factored out smaller Quiescent/React components

--- cljx/plongeur-cljs/src/plongeur/view.cljs
+++ cljx/plongeur-cljs/src/plongeur/view.cljs
@@ -6,27 +6,30 @@
             [plongeur.sigma :as s])
   (:require-macros [cljs.core.async.macros :refer [go]]))

+;; MDL machinery
+
 (defn upgrade-mdl-components
   "Material Design Lite component upgrade handler."
   []
   (js/setInterval #(.upgradeDom js/componentHandler) 100))

+;; React components

 (let [sigma-state (atom {})]
-  (defcomponent Card
+  (defcomponent Sigma
     :keyfn (fn [[id _]] id)

     :on-mount (fn [node [id _] {:keys [sigma-ctx]}]
                 (prn "on-mount" @sigma-state)
+
                 (swap! sigma-state assoc id {:ch (chan 10)})
-
-                ;TODO explore

                 ;(go (>! update-sigma [id cmd-chans]))
                 )

     :on-unmount (fn [_ [id _] {:keys [sigma-ctx]}]
                   (prn "on-unmount" @sigma-state)
+
                   (swap! sigma-state
                          (fn [m]
                            (-> id m :ch close!)
@@ -34,91 +37,79 @@

                   ;(go (>! remove-sigma id))
                   )
+    [[id props] cmd-chans]
+    (html [:div {:id         (s/graph-id id)
+                 :class-name "graph"}])))

-    [[id props] {:keys [drop-graph] :as cmd-chans}]
-    (html [:div {:class-name "mdl-cell mdl-cell--6-col-desktop mdl-cell--6-col-tablet mdl-cell--6-col-phone"}
-           [:div {:class-name "mdl-card mdl-shadow--2dp"}
+(defcomponent Card
+  "Component surrounding the visualization containers."
+  [[id props] {:keys [drop-graph] :as cmd-chans}]
+  (html [:div {:class-name "mdl-cell mdl-cell--6-col-desktop mdl-cell--6-col-tablet mdl-cell--6-col-phone"}
+         [:div {:class-name "mdl-card mdl-shadow--2dp"}

-            [:div {:class-name "mdl-card__supporting-text"}
+          [:div {:class-name "mdl-card__supporting-text"}
+           (Sigma [id props] cmd-chans)]

-             ;; Factor out in a React component as minimal as possible.
-             ;; make the sigma state atom scope wrap this component.
-             [:div {:id         (s/graph-id id)
-                    :class-name "graph"}]]
+          [:div {:class-name "mdl-card__title"}
+           [:button {:on-click   #(go (>! drop-graph id))
+                     :class-name "mdl-button mdl-js-button mdl-js-ripple-effect"} "delete " id]]]]))

-            [:div {:class-name "mdl-card__title"}
-             [:button {:on-click   #(go (>! drop-graph id))
-                       :class-name "mdl-button mdl-js-button mdl-js-ripple-effect"} "delete " id]]
+(defcomponent Header
+  [state cmd-chans]
+  (html [:header {:class-name "mdl-layout__header"}
+         [:div {:class-name "mdl-layout__header-row"}
+          [:div {:class-name "mdl-layout-spacer"}]

-            ]])))
+          ]]))

-;; TODO
-;; TODO factor out layout components: header, drawer, content, etc...
-;; TODO
+(defcomponent Drawer
+  [state {:keys [add-graph] :as cmd-chans}]
+  (html [:div {:class-name "mdl-layout__drawer"}
+         [:header {} "Plongeur"]
+         [:nav {:class-name "mdl-navigation"}
+          [:a {:class-name "mdl-navigation__link mdl-navigation__link--current"
+               :href "index.html"}
+           [:i {:class-name "material-icons"
+                :role       "presentation"} "dashboard"] "Dashboard"]
+          [:a {:class-name "mdl-navigation__link"
+               :href "config.html"}
+           [:i {:class-name "material-icons"
+                :role       "presentation"} "settings"] "Settings"]
+          [:a {:class-name "mdl-navigation__link"
+               :href "config.html"}
+           [:i {:class-name "material-icons"
+                :role       "presentation"} "reorder"] "Logs"]
+          [:button {:on-click   #(go (>! add-graph :click))
+                    :hidden     (>= (m/graph-count state) 4)
+                    :class-name "mdl-button mdl-js-button mdl-button--fab mdl-button--colored"}
+           [:i {:class-name "material-icons"} "add"]]
+
+          [:div {:class-name "mdl-layout-spacer"}]
+
+          [:a {:class-name "mdl-navigation__link"
+               :href "https://github.com/tmoerman/plongeur"
+               :target "_blank"}
+           [:i {:class-name "material-icons"
+                :role       "presentation"} "link"] "Github"]
+
+          ]]))
+
+(defcomponent Grid
+  [state cmd-chans]
+  (html [:main {:class-name "mdl-layout__content"}
+         [:div {:class-name "mdl-grid mdl-grid--no-spacing"}
+          [:div {:class-name "mdl-grid mdl-cell mdl-cell--9-col-desktop mdl-cell--12-col-tablet mdl-cell--4-col-phone mdl-cell--top"}
+           (for [graph-state (m/graphs state)]
+             (Card graph-state cmd-chans))]]]))

 (defcomponent Root
-  [state {:keys [add-graph debug] :as cmd-chans}]
-
-  (html [:div {:id "plongeur-main"} ;; extra wrapper for MDL React bug
-
+  [state cmd-chans]
+  (html [:div {:id "plongeur-main"}
          [:div {:id         "layout"
                 :class-name "mdl-layout mdl-js-layout mdl-layout--fixed-drawer mdl-layout--fixed-header is-small-screen"}
-
-          ;; HEADER
-
-          [:header {:class-name "mdl-layout__header"}
-           [:div {:class-name "mdl-layout__header-row"}
-            [:div {:class-name "mdl-layout-spacer"}]
-
-
-            ]]
-
-          ;; DRAWER
-
-          [:div {:class-name "mdl-layout__drawer"}
-           [:header {} "Plongeur"]
-           [:nav {:class-name "mdl-navigation"}
-            [:a {:class-name "mdl-navigation__link mdl-navigation__link--current"
-                 :href "index.html"}
-             [:i {:class-name "material-icons"
-                  :role       "presentation"} "dashboard"] "Dashboard"]
-            [:a {:class-name "mdl-navigation__link"
-                 :href "config.html"}
-             [:i {:class-name "material-icons"
-                  :role       "presentation"} "settings"] "Settings"]
-            [:a {:class-name "mdl-navigation__link"
-                 :href "config.html"}
-             [:i {:class-name "material-icons"
-                  :role       "presentation"} "reorder"] "Logs"]
-            [:button {:on-click   #(go (>! add-graph :click))
-                      :hidden     (>= (m/graph-count state) 4)
-                      :class-name "mdl-button mdl-js-button mdl-button--fab mdl-button--colored"}
-             [:i {:class-name "material-icons"} "add"]]
-
-            [:div {:class-name "mdl-layout-spacer"}]
-
-            [:a {:class-name "mdl-navigation__link"
-                 :href "https://github.com/tmoerman/plongeur"
-                 :target "_blank"}
-             [:i {:class-name "material-icons"
-                  :role       "presentation"} "link"] "Github"]
-
-
-            ]]
-
-          ;; CONTENT
-
-          [:main {:class-name "mdl-layout__content"}
-           [:div {:class-name "mdl-grid mdl-grid--no-spacing"}
-
-            [:div {:class-name "mdl-grid mdl-cell mdl-cell--9-col-desktop mdl-cell--12-col-tablet mdl-cell--4-col-phone mdl-cell--top"}
-
-             (for [graph-state (m/graphs state)]
-               (Card graph-state cmd-chans))
-
-             ]]]
-
-          ]]))
+          (Header state cmd-chans)
+          (Drawer state cmd-chans)
+          (Grid   state cmd-chans)]]))

 (defn view
   "Returns a stream of view trees, represented as a core.async channel."


Finished first Clojure version of Azulenoid generator.

--- clojure/org/gavrog/clojure/azulenoids.clj
+++ clojure/org/gavrog/clojure/azulenoids.clj
@@ -1,7 +1,9 @@
 (ns org.gavrog.clojure.azulenoids
   (:import (org.gavrog.jane.numbers Whole)
            (org.gavrog.joss.dsyms.basic DSymbol DynamicDSymbol)
-           (org.gavrog.joss.dsyms.generators CombineTiles DefineBranching2d)))
+           (org.gavrog.joss.dsyms.generators CombineTiles DefineBranching2d))
+  (:require clojure.set)
+  (:gen-class))

 (defn iterate-cycle [coll x]
   (reductions (fn [x f] (f x)) x (cycle coll)))
@@ -82,12 +84,21 @@
   (lazy-mapcat (fn [ds] (map (partial apply-to-template ds) boundary-mappings))
                octa-syms))

-(defn azul-syms []
+(def azul-syms
   (letfn [(step [acc ds]
                 (let [[seen _] acc
-                      ds* (-> ds .dual .minimal)
-                      key (.invariant ds*)]
+                      key (.invariant ds)]
                   (if (seen key)
                     [seen false]
-                    [(conj seen key) (.canonical ds*)])))]
-         (reductions step [#{} false] (azul-syms-raw))))
+                    [(conj seen key) ds])))]
+         (filter identity
+                 (map second
+                      (reductions step [#{} false] (azul-syms-raw))))))
+
+(defn -main []
+  (do
+    (doall (map (fn [ds] (println (str ds))) azul-syms))
+    (println "#Generated:")
+    (println "#   " (count octa-sets) "octagonal D-sets.")
+    (println "#   " (count octa-syms) "octagonal D-symbols.")
+    (println "#   " (count azul-syms) "azulenoid D-symbols.")))


selfdual2d.clj: first attempt at pruning the D-set generation tree.

--- clojure/org/gavrog/clojure/selfdual2d.clj
+++ clojure/org/gavrog/clojure/selfdual2d.clj
@@ -28,12 +28,25 @@
         t (/ (double (- (. System (nanoTime)) start-time)) 1000000000.0)]
     (println (format-summary n t))))

+(defn- orbits-okay? [ds]
+  (>= 4 (count (for [i (indices ds)
+                     j (indices ds) :when (> j i)
+                     D (orbit-reps ds [i j])
+                     :when (< (or (r ds i j D) 3) (if (> j (inc i)) 2 3))]
+                 [i j D]))))
+
+;; All self-dual, 2d Delaney sets that have non-negative curvature after
+;; setting m to the minimal feasible value on each (i,j)-orbit when face and
+;; edge degrees in a derived tiling are both to be at least three.
+(defn d-sets [max-size]
+  (for [dset (results (dsets 2 max-size) (comp orbits-okay? first))
+        :when (and (self-dual? dset) (proto-euclidean? dset))]
+    dset))

 ;; All convex, self-dual, 2d euclidean tilings.
 (defn d-syms [max-size]
   (let [good? (andp self-dual? minimal? euclidean? convex?)]
-    (for [dset (results (dsets 2 max-size))
-          :when (and (self-dual? dset) (proto-euclidean? dset))
+    (for [dset (d-sets max-size)
           dsym (results (branchings dset))
           :when (good? dsym)]
     (canonical dsym))))


add Yhteiset tiedostot -link

add Yhteiset tiedostot -link

--- src/publisher/core.clj
+++ src/publisher/core.clj
@@ -17,6 +17,10 @@

 (def styles "
 <style>
+
+  body {
+    font-size: 20px;
+  }

   .intro-jumbotron {
       background-image: url(siru_ja_muksu2.jpg);
@@ -300,6 +304,8 @@
 "]
              [:div {:style "margin-top: 20px"}
               (like-button site-url)]]
+            [:a {:style "text-decoration: underline" :href "/yhteiset"}
+             "Yhteiset tiedostot"]
             [:h2 "Koulut"]
             koulut
             [:h2 "Päiväkodit"]
@@ -312,33 +318,44 @@
 (defn add-ip! [ip]
   (swap! ips-atom (fn [ips]
                     (take 10 (conj ips {:ip ip
-                                        :time (date-to-map (Date.))})))))
+                                        :time (Date.)})))))

 (defn report-ips [ips]
   (hiccup/html
    [:ul
     (map (fn [ip]
-           [:li  (date-time-string (:time ip)) [:br]
-            [:strong (:ip ip)]])
+           [:li (date-time-string (date-to-map (:time ip))) [:br]
+            [:strong (pr-str (:ip ip))]])
          ips)]))

 (defn app []
   (compojure/routes (compojure/GET "/" []
                                    (front-page))

-                    (compojure/GET "/ip" request
-                                   (add-ip! (:remote-addr request))
+                    (compojure/GET "/ip/add" request
+                                   (add-ip! (or (get-in request [:headers "x-forwarded-for"])
+                                                (:remote-addr request)))
+                                   "thanks!")
+
+                    (compojure/GET "/ip/report" request
                                    (report-ips @ips-atom))
+
+                    (compojure/GET "/ip/edn" request
+                                   (pr-str @ips-atom))

                     (compojure/GET ["/get/:folder/:file" :folder #"[^/]+" :file #"[^/]+"]  [folder file]
                                    (do (timbre/info (str "load file " (URLDecoder/decode folder) "/" (URLDecoder/decode file)))
                                        (response/file-response (str files-directory "/" (URLDecoder/decode folder) "/" (URLDecoder/decode file)))))

                     (compojure/GET ["/:folder" :folder #"[^/]+"]  [folder]
-                                     (show-folder folder))
+                                   (show-folder folder))

                     (compojure/GET ["/:folder/:file" :folder #"[^/]+" :file #"[^/]+"] [folder file]
-                                     (show-file folder file))))
+                                   (show-file folder file))))

 (def handler (-> (app)
                  (file/wrap-file "resources")))
+
+(comment
+  * * * * * curl http://kuntotiedot.sirpakauppinen.fi/ip/add
+  ) ;; TODO: remove-me


Remove trailing null characters from strings in fields.

--- src/mavlink/mavlink_xml.clj
+++ src/mavlink/mavlink_xml.clj
@@ -176,7 +176,12 @@
                                 (transient [])
                                 range-length))]
               (assoc! message  name-key (if (= type-key :char)
-                                          (new String ^"[B" (into-array Byte/TYPE new-array))
+                                          (loop [idx (dec (count new-array))]
+                                            (if (neg? idx)
+                                              (new String "")
+                                              (if (= (get new-array idx) \o000)
+                                                (recur (dec idx))
+                                                (new String ^"[B" (into-array Byte/TYPE (subvec new-array 0 (inc idx)))))))
                                           new-array)))))
           (fn decode-it [buffer message]
             (assoc! message name-key (let [v (if (and bitmask


fix incorrect datatype

fix incorrect datatype

--- src/main/shadow/build/api.clj
+++ src/main/shadow/build/api.clj
@@ -344,7 +344,7 @@
   {:pre [(coll? source-ids)]}

   (let [modified (set source-ids)
-        all-deps-to-reset (find-resources-affected-by state source-ids)]
+        all-deps-to-reset (find-resources-affected-by state modified)]

     (reduce
       (fn [state resource-id]


Bug fix

Bug fix

Stopped server from starting

--- src/webapp/framework/server/systemfns.clj
+++ src/webapp/framework/server/systemfns.clj
@@ -2115,7 +2115,7 @@
 (defn get-user-for-session-id   [session-id]
   (if session-id
     (let [user-id  (:fk_appshare_user_id (sql-1 "select fk_appshare_user_id from appshare_web_sessions where session_id = ?" [session-id]))
-          user     (if (user-id (sql-1 "select id, user_name, from appshare_users where id = ?" [user-id])))]
+          user     (if user-id (sql-1 "select id, user_name, from appshare_users where id = ?" [user-id]))]
       user)))


cqlsh migration helper

cqlsh migration helper

--- src/er_cassandra/drift/migration_helpers.clj
+++ src/er_cassandra/drift/migration_helpers.clj
@@ -1,6 +1,8 @@
 (ns er-cassandra.drift.migration-helpers
   (:require [drift.config :as config]
-            [er-cassandra.session]))
+            [er-cassandra.session]
+            [clojure.java.shell :refer [sh]]
+            [environ.core :refer [env]]))

 (defn session
   "get the alia session"
@@ -16,3 +18,8 @@
   []
   (println "pausing to let cassandra catch up")
   (Thread/sleep 5000))
+
+(defn cqlsh
+  [cqlsh-cmd]
+  (let [cqlsh (env :cqlsh "cqlsh")]
+    (sh cqlsh :in cqlsh-cmd)))


Don't fetch *current-user* just to check superuser :racing_car:

--- src/metabase/api/common.clj
+++ src/metabase/api/common.clj
@@ -65,7 +65,7 @@
 (defn check-superuser
   "Check that `*current-user*` is a superuser or throw a 403."
   []
-  (check-403 (:is_superuser @*current-user*)))
+  (check-403 (db/exists? 'User, :id *current-user-id*, :is_superuser true)))

 ;;; #### checkp- functions: as in "check param". These functions expect that you pass a symbol so they can throw exceptions w/ relevant error messages.


CMR-7656: results feature in query was returned as a chunk, so I had to transform it into a set to use contains? on it for correct condition checking

--- search-app/src/cmr/search/results_handlers/umm_json_results_handler.clj
+++ search-app/src/cmr/search/results_handlers/umm_json_results_handler.clj
@@ -63,9 +63,9 @@
   [context query results]
   (let [granule-counts-map (:granule-counts-map results)
         items (:items results)
-        results (assoc results :items (if (nil? (get-in query [:result-features :granule-counts]))
-                                items
-                                (add-granule-count-to-items items granule-counts-map)))]
+        results (assoc results :items (if (contains? (set (:result-features query)) :granule-counts)
+                                        (add-granule-count-to-items items granule-counts-map)
+                                        items))]
     (json/generate-string (select-keys results [:hits :took :items]))))

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -103,8 +103,7 @@
   [context query results]
   (let [granule-counts-map (:granule-counts-map results)
         items (:items results)
-
-        results (assoc results :items (if (nil? (get-in query [:result-features :granule-counts]))
-                                items
-                                (add-granule-count-to-items items granule-counts-map)))]
+        results (assoc results :items (if (contains? (set (:result-features query)) :granule-counts)
+                                        (add-granule-count-to-items items granule-counts-map)
+                                        items))]
     (json/generate-string (select-keys results [:hits :took :items]))))


trying to make the animations work better in safari

--- support/src/figwheel/client/heads_up.cljs
+++ support/src/figwheel/client/heads_up.cljs
@@ -9,7 +9,8 @@
 (declare clear)
 ;; heads up display

-(def clojure-symbol-svg "<?xml version='1.0' encoding='UTF-8' ?>
+(def clojure-symbol-svg
+  "<?xml version='1.0' encoding='UTF-8' ?>
 <!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'>
 <svg width='49px' height='49px' viewBox='0 0 100 99' version='1.1' xmlns='http://www.w3.org/2000/svg' style='position:absolute; top:9px; left: 10px;'>
 <circle fill='rgba(255,255,255,0.5)' cx='49.75' cy='49.5' r='48.5'/>
@@ -118,14 +119,15 @@
 (defn display-heads-up [style msg]
   (go
    (let [c (ensure-container)]
-     (set-content! c msg)
      (set-style! c (merge {
                           :paddingTop "10px"
                           :paddingBottom "10px"
                           :width "100%"
-                          :height "auto"
-                          :opacity "1.0" }
-                         style))
+                           #_:minHeight #_"68px"
+                           :height "auto"
+                           :opacity "1.0" }
+                          style))
+     (set-content! c msg)
      (<! (timeout 400)))))

 (defn heading [s]
@@ -191,3 +193,4 @@
    (<! (display-loaded-start))
    (<! (timeout 400))
    (<! (clear))))
+


wildcard hostname

wildcard hostname

--- test/celestial/integration/es/systems.clj
+++ test/celestial/integration/es/systems.clj
@@ -44,9 +44,10 @@
        (total (sys/systems-for "admin" {:bool {:must {:term {:machine.cpus "4" }}}} 0 5)) => 2)

    (fact "find by hostname" :integration :elasticsearch
-       (total (sys/systems-for "admin" {:bool {:must {:term {:machine.hostname "red1" }}}} 0 5)) => 2
-       (total (sys/systems-for "admin" {:bool {:must [{:term {:machine.hostname "foo-1" }}]}} 0 5)) => 1
-
+      (total (sys/systems-for "admin" {:bool {:must {:term {:machine.hostname "red1" }}}} 0 5)) => 2
+      (total (sys/systems-for "admin" {:bool {:must [{:term {:machine.hostname "foo-1" }}]}} 0 5)) => 1
+
+      (total (sys/systems-for "admin" {:bool {:must {:wildcard {:machine.hostname "r*" }}}} 0 5)) => 2
          )

    (fact "find proxmox systems for non su user" :integration :elasticsearch


k-fold-cross-validation is random so only test things that won't change.

--- project/analyze-data/test/analyze_data/evaluate_model_test.clj
+++ project/analyze-data/test/analyze_data/evaluate_model_test.clj
@@ -42,7 +42,6 @@
       "trains and evaluates a model"))

 (deftest k-fold-cross-validation-test
-  (is (= {"one" {"one" 1, "two" 2}
-          "two" {"one" 1, "two" 0}}
-         (test-ns/k-fold-cross-validation 2 :knn (:dataset knn-model)))
+  (is (= ["one" "two"]
+         (keys (test-ns/k-fold-cross-validation 2 :knn (:dataset knn-model))))
       "trains and evaluates k-fold"))


Better naming and comments.

Better naming and comments.

--- src/re_frame/subs.cljs
+++ src/re_frame/subs.cljs
@@ -33,13 +33,16 @@

 (defn cache-and-return
   "cache the reaction r"
-  [v dynv r]
-  (let [cache-key [v dynv]]
+  [query-v dynv r]
+  (let [cache-key [query-v dynv]]
     ;; when this reaction is nolonger being used, remove it from the cache
     (ratom/add-on-dispose! r #(do (swap! query->reaction dissoc cache-key)
                                   (warn "Removing subscription: " cache-key)))

-    ;; cache this reaction, so it can be used for identical subscriptions
+    (.log js/console "Dispatch site: ")
+    (.log js/console (:dispatch-site (meta query-v)))
+
+    ;; cache this reaction, so it can be used to deduplicate other, identical subscriptions
     (swap! query->reaction assoc cache-key r)

     r))  ;; return the actual reaction
@@ -55,16 +58,16 @@

 (defn subscribe
   "Returns a Reagent/reaction which contains a computation"
-  ([v]
-   (if-let [cached (cache-lookup v)]
-     (do (warn "Using cached subscription: " v)
+  ([query-v]
+   (if-let [cached (cache-lookup query-v)]
+     (do (warn "Using cached subscription: " query-v)
          cached)
-     (let [query-id   (first-in-vector v)
+     (let [query-id   (first-in-vector query-v)
            handler-fn (get @qid->fn query-id)]
-       (warn "Subscription crerated: " v)
+       (warn "Subscription crerated: " query-v)
        (if-not handler-fn
          (error "re-frame: no subscription handler registered for: \"" query-id "\". Returning a nil subscription."))
-       (cache-and-return v [] (handler-fn app-db v)))))
+       (cache-and-return query-v [] (handler-fn app-db query-v)))))

   ([v dynv]
     (if-let [cached (cache-lookup v dynv)]


Add riemann.common/deprecated

Add riemann.common/deprecated

A macro which logs a deprecation notice when invoked.

--- src/riemann/common.clj
+++ src/riemann/common.clj
@@ -12,6 +12,7 @@
             [clojure.java.io :as io])
   (:use [clojure.string :only [split]]
         [riemann.time :only [unix-time]]
+        clojure.tools.logging
         riemann.codec
         gloss.core
         clojure.math.numeric-tower))
@@ -19,6 +20,14 @@
 (defprotocol Match
   (match [pred object]
     "Does predicate describe object?"))
+
+; Deprecation
+(defmacro deprecated
+  "Wraps body in an implicit (do), and logs a deprecation notice when invoked."
+  [comment & body]
+  `(do
+     (info ~(str "Deprecated: " comment))
+     ~@body))

 ; Times
 (defn time-at
@@ -32,6 +41,7 @@
   (clj-time.format/unparse (clj-time.format/formatters :date-time)
                            (clj-time.coerce/from-long (long (* 1000 unix)))))

+; Events
 (defn post-load-event
   "After events are loaded, we assign default times if none exist."
   [e]


change naming strategy as discussed on irc

--- src/riemann/plugin.clj
+++ src/riemann/plugin.clj
@@ -14,9 +14,10 @@
   containing at least two keys:

   - `plugin`: the plugin name
-  - `require`: a vector of require statements to hand over to
-               `clojure.core/require`
+  - `require`: the namespace to load

+  The namespace will be made available using the plugin name's symbol
+  value.
 "
   (:require [clojure.java.classpath :as cp]
             [clojure.java.io        :refer [resource]]
@@ -29,15 +30,15 @@
     (read-string src)))

 (defn load-from-meta
-  "Given a metadata description map, follow requirements"
+  "Given a metadata description map, require plugin's namespace"
   [{:keys [plugin require]}]
-  (when (seq require)
-    (info "loading plugin:" plugin)
-    (apply clojure.core/require require)))
+  (let [to-symbol (comp symbol name)]
+    (when require
+      (info "loading plugin:" plugin)
+      (clojure.core/require [(to-symbol require) :as (to-symbol plugin)]))))

 (defn load-from-resource
-  "Given a path to a java resource, load metadata and apply
-   given requirements."
+  "Given a path to a java resource, load metadata and require plugin"
   [src]
   (-> src
       resource
@@ -55,8 +56,8 @@
       (load-from-resource desc-file))))

 (defn load-plugin
-  "Given a plugin name, look for its metadata description file, execute
-   given requirements."
+  "Given a plugin name, look for its metadata description file, and
+   require plugin's namespace"
   [plugin]
   (load-from-resource (format "riemann_plugin/%s/meta.edn" (name plugin))))


getting rid of deps

getting rid of deps

--- sidecar/src/figwheel_sidecar/type_check.clj
+++ sidecar/src/figwheel_sidecar/type_check.clj
@@ -2,11 +2,7 @@
   (:require
    [clj-fuzzy.metrics :as metrics]
    [clojure.walk :as walk]
-   [alandipert.intension :refer [make-db]]
-   [datascript.core      :refer [q]]
-   [clojure.core.logic :as l]
-   [clojure.core.match :refer [match]]
-   [clojure.test :as t :refer [deftest is run-tests]]))
+   [clojure.core.logic :as l]))

 (def ^:dynamic *schema-rules* nil)


carry-schema: add space in exception message

--- contrib/schema/src/carry_schema/core.cljs
+++ contrib/schema/src/carry_schema/core.cljs
@@ -15,6 +15,6 @@
                 (when-let [problems (s/check schema new-model)]
                   ; using console log for better printing in Chrome console (in particular with binaryage/cljs-devtools)
                   (.log js/console "VALIDATION PROBLEMS:" problems)
-                  (throw (js/Error. (str "Model validation failed. Problems:" (pr-str problems)))))
+                  (throw (js/Error. (str "Model validation failed. Problems: " (pr-str problems)))))

                 new-model)))))


lint fix

lint fix

--- src/metabase/driver/mysql.clj
+++ src/metabase/driver/mysql.clj
@@ -86,7 +86,8 @@
 (extend MySQLDriver
   ISqlDriverDatabaseSpecific  {:connection-details->connection-spec connection-details->connection-spec
                                :database->connection-details        database->connection-details
-                               :unix-timestamp->timestamp           unix-timestamp->timestamp}
+                               :unix-timestamp->timestamp           unix-timestamp->timestamp
+                               :timezone->set-timezone-sql          timezone->set-timezone-sql}
   IDriver                     GenericSQLIDriverMixin
   ISyncDriverTableFKs         GenericSQLISyncDriverTableFKsMixin
   ISyncDriverFieldAvgLength   GenericSQLISyncDriverFieldAvgLengthMixin


tuning telemetry

tuning telemetry

--- src/sormilla/drone.clj
+++ src/sormilla/drone.clj
@@ -59,8 +59,8 @@
 (defn speed [s key1 key2 keys]
   (* s (key-dir [(key1 keys false) (key2 keys false)])))

-(def yaw-speed 0.25)
-(def alt-speed 0.35)
+(def yaw-speed 0.55)
+(def alt-speed 0.55)

 (def yaw (partial speed yaw-speed :left :right))
 (def alt (partial speed alt-speed :down :up))
@@ -91,10 +91,10 @@
       (comm/send-commands! [command]))))

 (defn telemetry []
-  #_(navdata/get-nav-data)
-  (swap! world assoc :telemetry {:pitch            0.3
+  (swap! world assoc :telemetry (navdata/get-nav-data))
+  #_(swap! world assoc :telemetry {:pitch            0.1
                                  :yaw              0.0
-                                 :roll             0.4
+                                 :roll            -0.4
                                  :alt           1358.0
                                  :vel-x            0.0
                                  :vel-y            0.0
@@ -104,8 +104,8 @@

 (def service (reify system/Service
                (start! [this config]
-                 (task/schedule :upstream 60 #'upstream)
-                 (task/schedule :telemetry 100 #'telemetry)
+                 (task/schedule :upstream 45 #'upstream)
+                 (task/schedule :telemetry 60 #'telemetry)
                  config)
                (stop! [this config]
                  (task/cancel :upstream)


CMR-6296 fixes intermittent umm test failure

--- umm-spec-lib/src/cmr/umm_spec/test/echo10_expected_conversion.clj
+++ umm-spec-lib/src/cmr/umm_spec/test/echo10_expected_conversion.clj
@@ -42,7 +42,7 @@
    In ECHO 10 there is only 1 price (fees) but there can be many data formats. The first fee
    applies to all data formats."
   [file-dist-infos]
-  (when-let [file-dist-infos (mapcat conversion-util/expand-file-dist-infos file-dist-infos)]
+  (when-let [file-dist-infos (seq (mapcat conversion-util/expand-file-dist-infos file-dist-infos))]
    (let [price (find-first-available-distribution-price file-dist-infos)]
     (for [file-dist-info file-dist-infos]
       (-> file-dist-info
@@ -55,10 +55,13 @@
   "Creates expected ArchiveAndDistributionInformation for echo10."
   [archive-dist-info]
   (when (seq (get archive-dist-info :FileDistributionInformation))
-    (-> archive-dist-info
-        (assoc :FileArchiveInformation nil)
-        (update :FileDistributionInformation expected-file-dist-info)
-        umm-c/map->ArchiveAndDistributionInformationType)))
+    (let [archive-dist-info
+          (-> archive-dist-info
+              (assoc :FileArchiveInformation nil)
+              (update :FileDistributionInformation expected-file-dist-info)
+              util/remove-nil-keys)]
+     (when (seq (util/remove-nil-keys archive-dist-info))
+       (umm-c/map->ArchiveAndDistributionInformationType archive-dist-info)))))

 (defn- get-url-type-by-type
  "Get the url-type based on type. Return default there is no applicable


only handle error on the ERROR state

only handle error on the ERROR state

--- src/oc/storage/api/videos.clj
+++ src/oc/storage/api/videos.clj
@@ -21,7 +21,7 @@
         video-changed (:video-processed entry)]
     (timbre/debug (:state_string video) video entry)
     (when entry
-      (let [error (some #(= (:state_string video) %) ["EMPTY", "ERROR"])
+      (let [error (= (:state_string video) "ERROR")
             updated-result (if-not error
                              (entry-res/update-video-data conn video entry)
                              (entry-res/error-video-data conn entry))


docstring in wrong place

docstring in wrong place

--- src/such/shorthand.clj
+++ src/such/shorthand.clj
@@ -73,6 +73,7 @@
   [pred coll]
   (first (filter pred coll)))

-(defn without-nils [coll]
+(defn without-nils
   "A lazy sequence of non-nil values of `coll`."
+  [coll]
   (keep identity coll))


Tweak impls of `render` method following the change of trace format

--- src/pinpointer/formatter.cljc
+++ src/pinpointer/formatter.cljc
@@ -76,6 +76,15 @@
 ;; Method implementations of `render`
 ;;

+(defmethod render `s/and [frame _ printer x]
+  (visit/visit (pop-trace printer) x))
+
+(defmethod render `s/or [frame _ printer x]
+  (visit/visit (pop-trace printer) x))
+
+(defmethod render `s/nilable [frame _ printer x]
+  (visit/visit (pop-trace printer) x))
+
 (defn- pretty-coll [printer open xs sep close f]
   (let [xform (comp (map-indexed #(f printer %1 %2))
                     (interpose sep))
@@ -97,8 +106,10 @@
                      (visit/visit (cond-> printer (= i n) pop-trace) x)))]
      (pretty-coll printer open x sep close each-fn))))

-(defmethod render `s/tuple [frame _ printer x]
-  (render-coll frame printer x))
+(defmethod render `s/tuple [{:keys [steps] :as frame} _ printer x]
+  (if (empty? steps)
+    (visit/visit (pop-trace printer) x)
+    (render-coll frame printer x)))

 (defn- render-every [{[n] :steps :as frame} printer x]
   (if (map? x)
@@ -132,10 +143,15 @@
   (render-every-kv frame printer x))

 (defmethod render `s/keys [{[key] :steps :as frame} _ printer x]
-  (render-coll frame printer x
-    (fn [i [k v]]
-      (let [vprinter (cond-> printer (= k key) pop-trace)]
-        [:span (visit/visit printer k) " " (visit/visit vprinter v)]))))
+  (if (nil? key)
+    (visit/visit (pop-trace printer) x)
+    (render-coll frame printer x
+      (fn [i [k v]]
+        (let [vprinter (cond-> printer (= k key) pop-trace)]
+          [:span (visit/visit printer k) " " (visit/visit vprinter v)])))))
+
+(defmethod render `s/merge [frame _ printer x]
+  (visit/visit (pop-trace printer) x))

 (defmethod render `s/cat [frame _ printer x]
   (render-coll frame printer x))
@@ -154,3 +170,9 @@

 (defmethod render `s/+ [frame _ printer x]
   (render-coll frame printer x))
+
+(defmethod render `s/multi-spec [frame _ printer x]
+  (visit/visit (pop-trace printer) x))
+
+(defmethod render `s/nonconforming [frame _ printer x]
+  (visit/visit (pop-trace printer) x))


additional core_commands tests

additional core_commands tests


still new positive tests

still new positive tests

--- src/paredit/core_commands.clj
+++ src/paredit/core_commands.clj
@@ -558,7 +558,7 @@
                  "(a\n|]" "(a\n  |]"
                  " #(a\n|]" " #(a\n    |]"
                  }]
-      #"C-j"     :paredit-newline
+      [#"C-j"     :paredit-newline
                 {"(ab|cd)" "(ab\n  |cd)"
                  "(ab|     cd)" "(ab\n  |cd)"
                  "   a|" "   a\n   |"


typo fixes

typo fixes

Signed-off-by: Bronsa <0a61acb1b71741ad3e278bf687ec45e201a8835f@gmail.com>
Imported from #CLJ-1164

--- src/main/clojure/clojure/tools/reader/default_data_readers.clj
+++ src/main/clojure/clojure/tools/reader/default_data_readers.clj
@@ -138,7 +138,7 @@

 (defn validated
   "Return a function which constructs and instant by calling constructor
-after first validting that those arguments are in range and otherwise
+after first validating that those arguments are in range and otherwise
 plausible. The resulting function will throw an exception if called
 with invalid arguments."
   [new-instance]
@@ -238,7 +238,7 @@
 ;;; reader integration

 (defn- construct-calendar
-  "Construct a java.util.Calendar, which preserves, preserving the timezone
+  "Construct a java.util.Calendar, preserving the timezone
 offset, but truncating the subsecond fraction to milliseconds."
   ^GregorianCalendar
   [years months days hours minutes seconds nanoseconds
@@ -252,7 +252,7 @@

 (defn- construct-date
   "Construct a java.util.Date, which expresses the original instant as
-milliseconds since the epoch, GMT."
+milliseconds since the epoch, UTC."
   [years months days hours minutes seconds nanoseconds
    offset-sign offset-hours offset-minutes]
   (.getTime (construct-calendar years months days


Test taking 50000

Test taking 50000

--- src/wlmmap/handler.clj
+++ src/wlmmap/handler.clj
@@ -40,7 +40,7 @@
 (defn- generate-markers
   "return a string with the javascript code to generate addressPoints."
   [params]
-  (let [mons (take 2000 (wcar* (car/smembers "frfrim")))
+  (let [mons (take 50000 (wcar* (car/smembers "frfrim")))
         all (remove #(nil? %)
                     (for [m mons]
                       (let [res (read-string (wcar* (car/get m)))
@@ -61,9 +61,10 @@
                             arl (format "%s" lng art art)
                             src (format "Source: %s" reg id)]
                         (when (and lat lon nam)
-                          (format "[%s,%s,\"%s\"]" lat lon (str "
" nam "
"
-                                                                ilk "
" (if art (str arl "
") "")
-                                                                src "
"))))))]
+                          (format "[%s,%s,\"%s\"]" lat lon nam
+                                  (str "
" nam "
"
+                                       ilk "
" (if art (str arl "
") "")
+                                       src "
"))))))]
     (str "var addressPoints = [" (str/join "," all) "];")))

 (defn- index [params]
@@ -115,11 +116,12 @@
     for (var i = 0; i < addressPoints.length; i++) {
         var a = addressPoints[i];
         var title = a[2];
+        var popup = a[3];
         var marker = L.marker(new L.LatLng(a[0], a[1]), {
             icon: L.mapbox.marker.icon({'marker-symbol': 'post', 'marker-color': '0044FF'}),
             title: title
         });
-        marker.bindPopup(title,{minWidth:270});
+        marker.bindPopup(popup,{minWidth:270});
         markers.addLayer(marker);
     }


use analytics/track instead of mixpanel/track

--- src-cljs/frontend/controllers/controls.cljs
+++ src-cljs/frontend/controllers/controls.cljs
@@ -664,9 +664,9 @@
 (defmethod post-control-event! :aside-menu-toggled
   [browser-state message _ previous-state current-state]
   (if (get-in current-state state/aside-menu-opened-path)
-    (do (mixpanel/track "Aside menu opened")
+    (do (analytics/track "Aside menu opened")
         (favicon/set-normal!))
-    (mixpanel/track "Aside menu closed")))
+    (analytics/track "Aside menu closed")))

 (defmethod control-event :overlay-info-toggled
   [browser-state message _ state]


(PDB-5161) engine: use parse-field instead of string operations

Replace various remaining uses of string operations like splitting a
field on #"\." with parse-field.

--- src/puppetlabs/puppetdb/query_eng/engine.clj
+++ src/puppetlabs/puppetdb/query_eng/engine.clj
@@ -2061,7 +2061,9 @@
                      "Argument \"{0}\" is incompatible with numeric field \"{1}\"."
                      value (name field))))))

-              [[(:or ">" ">=" "<" "<=")  (field :guard #(not (str/includes? %  "."))) _]]
+              [[(:or ">" ">=" "<" "<=")
+                (field :guard #(= (count (parse/parse-field %)) 1))
+                _]]
               (let [col-type (get-in query-context [:projections field :type])]
                 (when-not (or (vec? field)
                               (contains? #{:numeric :timestamp :jsonb-scalar}
@@ -2374,8 +2376,9 @@
                                         :value value}))

             [["=" column-name value]]
-            (let [colname (first (str/split column-name #"\."))
-                  cinfo (get-in query-rec [:projections colname])]
+            ;; FIXME: pass parsed representation down
+            (let [[top & path] (parse/parse-field column-name)
+                  cinfo (get-in query-rec [:projections (:name top)])]
               (case (:type cinfo)
                :timestamp
                (map->BinaryExpression {:operator :=
@@ -2392,7 +2395,7 @@
                                        :value (facts/factpath-to-string value)})

                :queryable-json
-               (if (string/includes? column-name "[")
+               (if (some #(= ::parse/indexed-field-part (:kind %)) path)
                  (map->JsonbPathBinaryExpression {:field column-name
                                                   :column-data cinfo
                                                   :value value
@@ -2450,8 +2453,9 @@
                                                                    (map str value))})))

             [[(op :guard #{">" "<" ">=" "<="}) column-name value]]
-            (let [colname (first (str/split column-name #"\."))
-                  {:keys [type] :as cinfo} (get-in query-rec [:projections colname])]
+            ;; FIXME: pass parsed representation down
+            (let [[top & path] (parse/parse-field column-name)
+                  {:keys [type] :as cinfo} (get-in query-rec [:projections (:name top)])]
               (cond
                 (= :timestamp type)
                 (map->BinaryExpression {:operator (keyword op)
@@ -2506,8 +2510,9 @@
                 (map->NullExpression {:column cinfo :null? value})))

             [["~" column-name value]]
-            (let [colname (first (str/split column-name #"\."))
-                  cinfo (get-in query-rec [:projections colname])]
+            ;; FIXME: pass parsed representation down
+            (let [[top] (parse/parse-field column-name)
+                  cinfo (get-in query-rec [:projections (:name top)])]
               (case (:type cinfo)
                 :array
                 (map->ArrayRegexExpression {:column cinfo :value value})


(PDB-3723) Fix jsonb factset queries

(PDB-3723) Fix jsonb factset queries

[rlb@puppet.com: squashed; adjust message and indentation]

--- src/puppetlabs/puppetdb/query_eng/engine.clj
+++ src/puppetlabs/puppetdb/query_eng/engine.clj
@@ -1144,9 +1144,9 @@

                :relationships certname-relations

-               :alias "package_inventory"
+               :alias "package_inventory
                :subquery? false
-               :source-table "packages"}))
+               :source-table packages"}))

 (def factsets-query
   "Query for the top level facts query"
@@ -1158,16 +1158,24 @@
                     :field :timestamp}
        "facts" {:type :queryable-json
                 :queryable? true
-                :field (hcore/raw "(stable||volatile)")}
+                :field {:select [(h/row-to-json :facts_data)]
+                        :from [[{:select [[(hcore/raw "json_agg(json_build_object('name', t.name, 'value', t.value))")
+                                           :data]
+                                          [(hsql-hash-as-href "fs.certname" :factsets :facts)
+                                           :href]]
+                                 :from [[{:select [[:key :name] :value :certname]
+                                          :from [(hcore/raw "jsonb_each(fs.volatile || fs.stable)")]}
+                                         :t]]}
+                                :facts_data]]}}
        "certname" {:type :string
                    :queryable? true
-                   :field :factsets.certname}
+                   :field :fs.certname}
        "hash" {:type :string
                :queryable? true
-               :field (hsql-hash-as-str :factsets.hash)}
+               :field (hsql-hash-as-str :fs.hash)}
        "producer_timestamp" {:type :timestamp
                              :queryable? true
-                             :field :factsets.producer_timestamp}
+                             :field :fs.producer_timestamp}
        "producer" {:type :string
                    :queryable? true
                    :field :producers.name}
@@ -1175,11 +1183,11 @@
                       :queryable? true
                       :field :environments.environment}}

-      :selection {:from [:factsets]
+      :selection {:from [[:factsets :fs]]
                   :left-join [:environments
-                              [:= :factsets.environment_id :environments.id]
+                              [:= :fs.environment_id :environments.id]
                               :producers
-                              [:= :producers.id :factsets.producer_id]]}
+                              [:= :producers.id :fs.producer_id]]}

       :relationships (merge certname-relations
                             {"environments" {:local-columns ["environment"]
@@ -2016,7 +2024,7 @@

             [[(op :guard #{">" "<" ">=" "<="}) column-name value]]
             (let [colname (first (str/split column-name #"\."))
-                  cinfo (get-in query-rec [:projections colname])]
+                  {:keys [type] :as cinfo} (get-in query-rec [:projections colname])]
               (cond
                 (= :timestamp type)
                 (map->BinaryExpression {:operator (keyword op)
@@ -2033,7 +2041,7 @@
                                         :column cinfo
                                         :value (su/munge-jsonb-for-storage value)})

-                :queryable-json
+                (= :queryable-json type)
                 (map->JsonbPathBinaryExpression {:field column-name
                                                  :column-data cinfo
                                                  :value (su/munge-jsonb-for-storage value)


Check axis spec :major / :minor instead of :visible when drawing grid.

--- src/thi/ng/geom/viz/core.cljc
+++ src/thi/ng/geom/viz/core.cljc
@@ -77,7 +77,7 @@
 ;; | `:range`       | vec of range bounds  | Y          | nil                                    | Lower & upper bound of projected coordinates                             |
 ;; | `:pos`         | number               | Y          | nil                                    | Draw position of the axis (ypos for X-axis, xpos for Y-axis)             |
 ;; | `:major`       | seq of domain values | N          | nil                                    | Seq of domain positions at which to draw labeled tick marks              |
-;; | `:minor`       | seq of domain values | N          | nil                                    | Seq of domain positions at which                                         |
+;; | `:minor`       | seq of domain values | N          | nil                                    | Seq of domain positions at which to draw minor tick marks                |
 ;; | `:major-size`  | number               | N          | 10                                     | Length of major tick marks                                               |
 ;; | `:minor-size`  | number               | N          | 5                                      | Length of minor tick marks                                               |
 ;; | `:label`       | function             | N          | =(default-svg-label (value-format 2))= | Function to format & emit tick labels                                    |
@@ -122,7 +122,9 @@
 ;; *** Axis grid definition (:grid)
 ;;
 ;; *Note:* If no `:grid` spec is given in the main spec, no background
-;; *grid will be displayed...
+;; *grid will be displayed. If the axis is not `:visible`, the grid
+;; *will still be displayed as long as either `:major` or `:minor`
+;; *ticks are defined in the axis spec.
 ;;
 ;; | *Key*      | *Value* | *Required* | *Default*       | *Description*                                            |
 ;; |------------+---------+------------+-----------------+----------------------------------------------------------|
@@ -782,9 +784,9 @@
         scale-y (:scale y-axis)]
     (svg/group
      (merge {:stroke "#ccc" :stroke-dasharray "1 1"} attribs)
-     (if (:visible x-axis)
+     (if (or (:major x-axis) (:minor x-axis))
        (map #(let [x (scale-x %)] (svg/line (vec2 x y1) (vec2 x y2))) (select-ticks x-axis minor-x)))
-     (if (:visible y-axis)
+     (if (or (:major y-axis) (:minor y-axis))
        (map #(let [y (scale-y %)] (svg/line (vec2 x1 y) (vec2 x2 y))) (select-ticks y-axis minor-y))))))

 (defn svg-plot2d-cartesian
@@ -848,11 +850,11 @@
         great?  (> (m/abs-diff x1 x2) m/PI)]
     (svg/group
      (merge {:stroke "#ccc" :stroke-dasharray "1 1"} attribs)
-     (if (:visible x-axis)
+     (if (or (:major x-axis) (:minor x-axis))
        (map
         #(let [x (scale-x %)] (svg/line (project [x y1]) (project [x y2])))
         (select-ticks x-axis minor-x)))
-     (if (:visible y-axis)
+     (if (or (:major y-axis) (:minor y-axis))
        (map
         #(let [y (scale-y %)]
            (if circle


test/core: fix incorrect comparison in tests

--- test/app/test/core.clj
+++ test/app/test/core.clj
@@ -74,10 +74,10 @@
   (is (insta/failure? (command-parser "a not valid command"))))

 (deftest testParsingQ
-  (is (= [:EXIT 'q']) (command-parser "q")))
+  (is (= '([:EXIT "q"]) (command-parser "q"))))

 (deftest testParsingQuit
-  (is (= [:EXIT 'quit']) (command-parser "quit")))
+  (is (= '([:EXIT "quit"]) (command-parser "quit"))))

 (deftest testParsingExit
-  (is (= [:EXIT 'exit']) (command-parser "exit")))
+  (is (= '([:EXIT "exit"]) (command-parser "exit"))))


Fix satisfied status for requirements, components and work items

--- src/web/components/nodes.cljs
+++ src/web/components/nodes.cljs
@@ -29,6 +29,15 @@
     (let [route (node->route (om/props this))]
       (routing/activate-route! route)))

+  (satisfied? [this]
+    (let [{:keys [kind mapped-here mapped-to]} (om/props this)]
+      (case kind
+        "requirement" (not (empty? mapped-to))
+        "component" (and (not (empty? mapped-here))
+                         (not (empty? mapped-to)))
+        "work-item" (not (empty? mapped-here))
+        "tag" true)))
+
   (render [this]
     (let [{:keys [name title kind description children
                   mapped-to mapped-here ui/expanded]} (om/props this)
@@ -37,8 +46,7 @@
                     (str "node"
                          (when-not parent
                            " node-root")
-                         (if (or (some #{kind} ["work-item" "tag"])
-                                 (not (empty? mapped-to)))
+                         (if (.satisfied? this)
                            " node-satisfied"
                            " node-unsatisfied"))}
         (dom/h2 #js {:className "node-header"}


arg rename

arg rename

--- src/overtone/core/synth.clj
+++ src/overtone/core/synth.clj
@@ -157,8 +157,8 @@
 ; (defsynth foo [freq [440 :ar]] ...)
 ; Should probably do this with a recursive function that can pull
 ; out argument pairs or triples, and get rid of the vector
-(defn- parse-params [params]
-  (for [[p-name p-val] params]
+(defn- parse-params [param-map]
+  (for [[p-name p-val] param-map]
     (let [[p-val p-rate] (if (vector? p-val)
                            p-val
                            [p-val DEFAULT-RATE])]


Add tests for special characters in mentions.

--- test/linkification.clj
+++ test/linkification.clj
@@ -55,4 +55,13 @@
       "how are you @foo"))
   (is (=
       (linkify "nice to see @foo again")
-      "nice to see @foo again")))
+      "nice to see @foo again"))
+  (is (=
+      (linkify "@?")
+      "@?"))
+  (is (=
+      (linkify "@foo: test")
+      "@foo: test"))
+  (is (=
+      (linkify "@foo.bar test")
+      "@foo.bar test")))


Add retrieve image endpoint.

Add retrieve image endpoint.

--- src/uxbox/frontend/images.clj
+++ src/uxbox/frontend/images.clj
@@ -87,7 +87,22 @@
     (-> (sv/query params)
         (p/then #(http/ok (rsp %))))))

-;; --- Create image
+;; --- Retrieve Image
+
+(s/def ::retrieve-image
+  (s/keys :req-un [::us/id]))
+
+(defn retrieve-image
+  [{user :identity params :route-params}]
+  (let [params (us/conform ::retrieve-image params)
+        params (assoc params :user user :type :retrieve-image)]
+    (->> (sv/query params)
+         (p/map populate-thumbnails)
+         (p/map populate-urls)
+         (p/map rsp)
+         (p/map http/ok))))
+
+;; --- Create Image

 (s/def ::create-image
   (s/keys :req-un [::file ::width ::height ::mimetype]


stackdriver plugin fixes: - fix handling of single events - do not post when there are no data points

--- src/riemann/stackdriver.clj
+++ src/riemann/stackdriver.clj
@@ -13,17 +13,17 @@
   (let [service ((:name opts) event)]
      (str/replace service #"\s+" ".")))

-(defn generate-datapoint
+(defn generate-datapoints
   "Accepts riemann event/events and converts it into equivalent stackdriver datapoint."
   [opts event-or-events]
-  (let [events (if (sequential? event-or-events) event-or-events (list event-or-events))]
-    (map (fn [event]
-      {:name (metric-name opts event)
-       :value (:metric event)
-       :collected_at (long (:time event))})
-    events)))
+  (->> (if (sequential? event-or-events) event-or-events (list event-or-events))
+       (remove (comp nil? :metric))
+       (map (fn [event]
+              {:name (metric-name opts event)
+               :value (:metric event)
+               :collected_at (long (:time event))}))))

-(defn post-datapoint
+(defn post-datapoints
   "Post the riemann metrics datapoints."
   [api-key uri data]
   (let [http-options {:body data
@@ -37,9 +37,10 @@
   (let [ts (atom 0)
         opts (merge {:api-key "stackdriver-api-key"
                      :name :service} opts)]
-    (fn [event]
-      (let [post-data {:timestamp (swap! ts #(max (inc %) (long (riemann.time/unix-time))))
-                       :proto_version 1
-                       :data (generate-datapoint opts (remove (comp nil? :metric) event))}
-            json-data (generate-string post-data)]
-        (post-datapoint (:api-key opts) gateway-url json-data)))))
+    (fn [event-or-events]
+      (when-let [data (not-empty (generate-datapoints opts event-or-events))]
+        (->>  {:timestamp (swap! ts #(max (inc %) (long (riemann.time/unix-time))))
+               :proto_version 1
+               :data data}
+              (generate-string)
+              (post-datapoints (:api-key opts) gateway-url))))))


load-urls returns the collection that was loaded

--- src/cljs/infinitelives/utils/resources.cljs
+++ src/cljs/infinitelives/utils/resources.cljs
@@ -1,6 +1,7 @@
 (ns infinitelives.utils.resources
   (:require [infinitelives.utils.string :as string]
-            [cljs.core.async :refer [chan put! <! timeout close!]])
+            [infinitelives.utils.console :refer [log]]
+            [cljs.core.async :refer [chan put! <! timeout close! take!]])
   (:require-macros [cljs.core.async.macros :refer [go]]))

@@ -29,13 +30,17 @@
   "loads each url in the passed in list. Updates the progress as it goes with
   a percentage. Once complete, displays all the images fullsize."
   [urls progress-fn]
-  (let [finished (chan)                         ;; make our channel to
-        num-urls (count urls)                   ;; how many urls
-        images (doall                           ;; start loading all the urls
-                (map #(put! finished (load %)) urls))]
+  (let [finished (chan)       ;; make our channel to
+        num-urls (count urls) ;; how many urls
+        ]
+    (doall ;; start loading all the urls
+     (map #(take!
+            (load %)
+            (fn [res] (put! finished res))) urls))
     (go
-      (loop [i 1]
-        (let [[url obj] (<! finished)] ;; a new image has finished loading
+      (loop [i 1 coll {}]
+        (let [[url obj] (<! finished)
+              new-coll (assoc coll url obj)] ;; a new image has finished loading
           ;; setup a pixi texture keyed by the tail of its filename
           (register! url obj)

@@ -43,5 +48,6 @@
           (when progress-fn (progress-fn i num-urls url obj))

           ;; more images?
-          (when (< i num-urls)
-            (recur (inc i))))))))
+          (if (< i num-urls)
+            (recur (inc i) new-coll)
+            new-coll))))))


Preparing for async operations

Preparing for async operations

--- src/clojure/clojurewerkz/cassaforte/cql.clj
+++ src/clojure/clojurewerkz/cassaforte/cql.clj
@@ -1,18 +1,28 @@
 (ns clojurewerkz.cassaforte.cql
-  (:import [com.datastax.driver.core Session])
+  (:import [com.datastax.driver.core Session Query
+            ResultSet ResultSetFuture]
+           [com.google.common.util.concurrent Futures FutureCallback])
   (:require
    [qbits.hayt.cql :as cql]
+   [qbits.alia.codec :as codec]
    [clojurewerkz.cassaforte.query :as query]
    [clojurewerkz.cassaforte.client :as client]
    [clojurewerkz.cassaforte.debug-utils :as debug-utils]))

 (def ^:dynamic *debug* false)
+(def ^:dynamic *async* false)

 (defmacro with-debug
   "Executes query with debug output"
   [& body]
   `(binding [*debug* true]
      (debug-utils/catch-exceptions ~@body)))
+
+(defmacro async
+  "Executes query with debug output"
+  [& body]
+  `(binding [*async* true]
+     ~@body))

 ;; connect! can be replaced by client/set-session!

@@ -39,13 +49,23 @@
   "Executes built query"
   ([query]
      (execute client/*default-session* query))
-  ([session query]
+  ([session query & {:keys [success failure]}]
      (client/with-session session
-       (into []  ;; alia prefers not to return vectors
-             (if cql/*prepared-statement*
-               (client/execute (client/prepare (first query))
-                               :values (second query))
-               (client/execute query))))))
+       (let [^Query statement (if cql/*prepared-statement*
+                                (client/query->statement (client/prepare (first query))
+                                                         (second query))
+                                (client/query->statement query nil))
+             ^ResultSetFuture future (.executeAsync session statement)]
+         (into []  ;; alia prefers not to return vectors
+               (if *async*
+                 (Futures/addCallback
+                  future
+                  (reify FutureCallback
+                    (onSuccess [_ result]
+                      (success (codec/result-set->maps (.get future) true)))
+                    (onFailure [_ result]
+                      (failure result))))
+                 (codec/result-set->maps  (.getUninterruptibly future) true)))))))

 (defn ^:private execute-
   [query-params builder]


nicer exception when no matching device, and search both name and filter

--- src/midi.clj
+++ src/midi.clj
@@ -1,6 +1,7 @@
 (ns midi
   (:import (javax.sound.midi MidiSystem
-                             ShortMessage))
+                             ShortMessage
+                             MidiUnavailableException))
   (:refer-clojure :exclude [send]))

 (defn note-on
@@ -25,7 +26,9 @@
   [re]
   (let [infos (MidiSystem/getMidiDeviceInfo)]
     (map #(MidiSystem/getMidiDevice %)
-         (filter #(re-find (re-pattern re) (.getName %))
+         (filter (or
+                  #(re-find (re-pattern re) (.getName %))
+                  #(re-find (re-pattern re) (.getDescription %)))
                  infos))))

 (defn get-receiver
@@ -37,10 +40,13 @@
   (let [devices (find-devices re)
         devices (filter #(not (= 0 (.getMaxReceivers %))) devices)
         device (first devices)]
-    (do
-      (when (not (.isOpen device))
-        (.open device))
-      (.getReceiver device))))
+    (when (not device)
+      (throw (MidiUnavailableException.
+              (str "No MIDI receiver matching /" re "/"))))
+    (when (not (.isOpen device))
+      (.open device))
+    (.getReceiver device)))
+

 (defn send
   "Send a message to a receiver"


add benchmark case for multi-arity keypath

--- scripts/benchmarks.clj
+++ scripts/benchmarks.clj
@@ -72,6 +72,7 @@
       p (comp-paths :a :b :c)]
   (run-benchmark "get value in nested map" 2500000
     (select-any [:a :b :c] data)
+    (select-any (keypath :a :b :c) data)
     (select-one [:a :b :c] data)
     (select-first [:a :b :c] data)
     (select-one! [:a :b :c] data)


for debugging

for debugging

--- test/babel/test/it.clj
+++ test/babel/test/it.clj
@@ -2,6 +2,7 @@
   (:refer-clojure :exclude [get-in])
   (:require [babel.engine :as engine]
             [babel.italiano :as it :refer [lexicon]]
+            [babel.italiano.lexicon :refer [lexicon-source]]
             [babel.italiano.morphology :refer [fo]]
             [babel.writer :as writer]
             [clojure.string :as string]


chore: println cleanup

chore: println cleanup

--- src/main/clojure/pdok/featured/timeline.clj
+++ src/main/clojure/pdok/featured/timeline.clj
@@ -107,7 +107,7 @@
 (defn- execute-query-result-on-channel [timeline query rc]
   (try (j/with-db-connection [c (:db timeline)]
          (let [statement (j/prepare-statement (doto (j/get-connection c) (.setAutoCommit false)) query :fetch-size 10000)]
-           (j/query c [statement] :row-fn (partial feature-on-channel rc)) )
+           (j/query c [statement] :row-fn (partial feature-on-channel rc)) )
          (close! rc))
        (catch java.sql.SQLException e
           (log/with-logs ['pdok.featured.timeline :error :error] (j/print-sql-exception-chain e)))))
@@ -315,10 +315,8 @@
   (proj/init [this]
     (init db) this)
   (proj/new-feature [_ feature]
-    (let [_ (println "---> " (:version feature))
-          [dataset collection id] (feature-key feature)
+    (let [[dataset collection id] (feature-key feature)
           [root-col root-id] (root-fn dataset collection id)
-          _ (println "root-col: " root-col  " ,root-id: " root-id)
           path (path-fn dataset collection id)
           batched-new (with-batch new-current-batch new-current-batch-size (partial new-current db) flush-fn)
           cache-batched-new (with-cache feature-cache batched-new cache-store-key cache-value)
@@ -328,8 +326,7 @@
           batched-history (with-batch new-history-batch new-history-batch-size (partial new-history db) flush-fn)
           cached-get-current (use-cache feature-cache cache-use-key)]
       (if-let [current (cached-get-current dataset root-col root-id)]
-        (let [_ (println "current: " (:version feature))
-              new-current (merge current path feature)]
+        (let [new-current (merge current path feature)]
           (if (= (:action feature) :close)
             (cache-batched-update (sync-valid-to new-current feature))
             (if (t/before? (:_valid_from current) (:validity feature))


TODO islands ref

TODO islands ref

--- src/tenbytenbot/tactics.clj
+++ src/tenbytenbot/tactics.clj
@@ -44,6 +44,7 @@

 (defn number-of-islands [board]
+  "TODO http://prismoskills.appspot.com/lessons/Arrays/Count_blobs_in_matrix.jsp"
   0)


using cljs.compiler munge

using cljs.compiler munge

For proper namespace matching on the client; I could do a much better
job of handling namespaces in general

--- support/src/figwheel/core.clj
+++ support/src/figwheel/core.clj
@@ -1,6 +1,7 @@
 (ns figwheel.core
   (:require
    [compojure.route :as route]
+   [cljs.compiler]
    [compojure.core :refer [routes GET]]
    [org.httpkit.server :refer [run-server with-channel on-close on-receive send! open?]]
    [watchtower.core :as wt :refer [watcher compile-watcher watcher* ignore-dotfiles file-filter extensions]]
@@ -122,7 +123,7 @@

 (defn make-sendable-file [st path]
   { :file (make-server-relative-path st path)
-    :namespace (string/join "." (string/split path #"\/")) })
+    :namespace (cljs.compiler/munge path)})

 ;; watchtower file change detection
 (defn compile-js-filewatcher [{:keys [js-dirs] :as server-state}]


Rendering on gha version has smaller size

--- test/clj_chrome_devtools/automation_test.clj
+++ test/clj_chrome_devtools/automation_test.clj
@@ -32,4 +32,4 @@
   (a/print-pdf @a/current-automation "example.pdf")
   (let [pdf (slurp "example.pdf")]
     (is (str/starts-with? pdf "%PDF-1.4")) ; file exists and starts with proper PDF header
-    (is (> (count pdf) 50000)))) ; file should be little over 50k
+    (is (> (count pdf) 30000)))) ; file should be little over 30k


Basic test coverage for create-index, drop-index

--- test/clojurewerkz/cassaforte/schema_test.clj
+++ test/clojurewerkz/cassaforte/schema_test.clj
@@ -73,6 +73,17 @@
            (= 2 (count columns)) ;; Cassandra versions
            (= 3 (count columns))))))

+  (deftest test-create-table-with-indices
+    (create-table s :people
+                  (column-definitions {:name        :varchar
+                                       :title       :varchar
+                                       :birth_date  :timestamp
+                                       :primary-key [:name]}))
+    (create-index s :people :title
+                  (index-name :people_title))
+    (drop-index   s :people_title)
+    (drop-table s :people))
+
   (deftest test-create-alter-table-add-column
     (create-table s :userstmp
                   (column-definitions {:name        :varchar


Change logs back to local time.

Change logs back to local time.

The recent Timbre update changed the default log time zone to UTC, which
makes sense for server-side software, but not for a local tool like
Afterglow. Explicitly restore local time zone when configuring logging.

--- src/afterglow/core.clj
+++ src/afterglow/core.clj
@@ -59,7 +59,9 @@

     :middleware [] ; (fns [data]) -> ?data, applied left->right

-    :timestamp-opts timbre/default-timestamp-opts ; {:pattern _ :locale _ :timezone _}
+    :timestamp-opts {:pattern "yyyy-MMM-dd HH:mm:ss"
+                     :locale :jvm-default
+                     :timezone (java.util.TimeZone/getDefault)}

     :output-fn timbre/default-output-fn ; (fn [data]) -> string
     })


Update user settings email preferences card heading

--- src-cljs/frontend/components/account.cljs
+++ src-cljs/frontend/components/account.cljs
@@ -344,7 +344,7 @@
         (html
          [:div.card
           [:div.header
-           [:h2 "Email preferences"]
+           [:h2 "Email Preferences by Organization"]
            [:div
             [:label "Choose an organization"]
             [:select.form-control


put private docs in feature link on home

--- src-cljs/frontend/components/landing.cljs
+++ src-cljs/frontend/components/landing.cljs
@@ -311,7 +311,7 @@
               Communicate and create new ideas with your teammates in one secure place."]]
             [:a.feature-link {:href "/pricing" :role "button" :title "Start your trial"}
              [:span.content-copy
-              "Start your trial"]]]
+              "Try private docs."]]]
            [:div.feature-media artwork-team]]])))))

 (defn the-what [app owner]


Refactor fingerprint code

Refactor fingerprint code

--- src/afrey/boot_asset_fingerprint/impl.clj
+++ src/afrey/boot_asset_fingerprint/impl.clj
@@ -24,7 +24,7 @@
       (str relative-root separator path))))

 (defn fingerprint-asset [asset-path {:keys [input-root file-hashes]}]
-  (let [full-path (asset-full-path (str asset-path) input-root)
+  (let [full-path   (asset-full-path (str asset-path) input-root)
         fingerprint (get file-hashes full-path)]
     (if fingerprint
       (str asset-path "?v=" fingerprint)
@@ -60,4 +60,6 @@
   [{:keys [input-path output-path] :as opts}]
   (let [out (io/file output-path)]
     (io/make-parents out)
-    (spit out (str/replace (slurp input-path) #"\$\{(.+?)\}" (lookup-fn opts)))))
+    (as-> (slurp input-path) $
+      (str/replace $ #"\$\{(.+?)\}" (lookup-fn opts))
+      (spit out $))))


working on nested forms

working on nested forms

--- src/cards/untangled/components/forms.cljs
+++ src/cards/untangled/components/forms.cljs
@@ -43,7 +43,7 @@
         (field-with-label this form :person/registered-to-vote? "Registered?")
         (when (f/checked? form :person/registered-to-vote?)
           (dom/div nil "Good on you!"))
-        (dom/button #js {:onClick #(f/reset-from-entity! this form Person id)} "Load person: ")
+        (dom/button #js {:onClick #(f/reset-from-entity! this form Person id true)} "Load person: ")
         (dom/input #js {:value (or id "") :onChange #(m/set-integer! this :ui/person-id :event %)})
         (dom/br nil)
         (dom/button #js {:onClick #(f/commit-to-entity! this form Person)} "Save to entity!")


further edge cases for :exec-string-iterate

--- test/push/instructions/base/string_test.clj
+++ test/push/instructions/base/string_test.clj
@@ -65,6 +65,16 @@
                                                               "re he was able"
                                                               :exec-string-iterate
                                                               :integer-add))}
+    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+    {:exec   '(:integer-add :foo)
+     :string '("ere he was able")}
+                            :exec-string-iterate
+                                                  {:char   '(\e)
+                                                   :string '()
+                                                   :exec   '((:integer-add
+                                                              "re he was able"
+                                                              :exec-string-iterate
+                                                              :integer-add) :foo)}
     ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
     {:exec   '((2 :integer-add (7)))
      :string '("ere he was able")}
@@ -88,7 +98,14 @@
                             :exec-string-iterate
                                                   {:char   '()
                                                    :string '()
-                                                   :exec   '(:integer-add)})
+                                                   :exec   '(:integer-add)}
+    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+    {:exec   '(:integer-add :foo)
+     :string '("")}
+                            :exec-string-iterate
+                                                  {:char   '()
+                                                   :string '()
+                                                   :exec   '(:integer-add :foo)})


Basic pedestal component added

Basic pedestal component added

--- src/clj/hellhound/components/pedestal.clj
+++ src/clj/hellhound/components/pedestal.clj
@@ -4,9 +4,44 @@
   `Pedestal` component is responsible for creating a pedestal service
   by reading the configuration and service map from environment config
   file or from the given input."
-  (:require [hellhound.components.protocols :as protocols]))
+  (:require
+   [io.pedestal.http               :as http]
+   [hellhound.core                 :as hellhound]
+   [hellhound.components.protocols :as protocols]))

-(defrecord Pedestal []
+(declare map->Pedestal)
+
+;; Functions -----------------------------------------------
+(defn test?
+  []
+  (hellhound/test?))
+
+
+(defn new-pedestal
+  "Creates a new pedestal record."
+  [service-map service]
+  (map->Pedestal {:service-map service-map
+                  :serive      service}))
+
+(defn make-pedestal-component
+  "Create new pedestal record to with the key name of `:pedestal`
+  to be injected into `hellhound`'s system map"
+  [system-map service-map service]
+  (update-in system-map [:components :pedestal]
+             (new-pedestal service-map sercice)))
+
+;; Record --------------------------------------------------
+(defrecord Pedestal [service-map service]
   protocols/Lifecycle
-  (start [this])
-  (stop [this]))
+  (start [this]
+    (if service
+      this
+      (cond-> service-map
+        true                      http/create-server
+        (not (test? service-map)) http/start
+        true                      ((partial assoc this :service)))))
+
+  (stop [this]
+    (when (and service (not (test? service-map))))
+    (http/stop service)
+    (assoc this :service nil)))


Add utf-8 char marker to CSV files

Add utf-8 char marker to CSV files

--- src/clj/org/openforis/ceo/db/projects.clj
+++ src/clj/org/openforis/ceo/db/projects.clj
@@ -1009,7 +1009,7 @@
                    "Content-Disposition" (str "attachment; filename="
                                               (prepare-file-name (:name project-info) "plot")
                                               ".csv")}
-         :body (str/join "\n" (conj data-rows headers-out))})
+         :body (str/join "\n" (conj data-rows (str "\uFEFF" headers-out)))})
       (data-response "Project not found."))))

 (defn- get-ext-sample-headers
@@ -1081,5 +1081,5 @@
                    "Content-Disposition" (str "attachment; filename="
                                               (prepare-file-name (:name project-info) "sample")
                                               ".csv")}
-         :body (str/join "\n" (conj data-rows headers-out))})
+         :body (str/join "\n" (conj data-rows (str "\uFEFF" headers-out)))})
       (data-response "Project not found."))))


optimized the heapify operation to ignore the last level of leaves...

--- src/clojure_learning/algorithms/heaps.clj
+++ src/clojure_learning/algorithms/heaps.clj
@@ -66,7 +66,7 @@
   "heapify takes a vector and transforms it into a heapified data-structure
    the operations performs in O(nlogn) just like any sorting operation
    Note:: there's no better sorting operation that performs faster than
-          worst case running time of O(nlogn)"
+          worst case running time of O(nlogn) VIA value-comparison!!!"
  (let [heapified-arr (into-array xs)
        last-idx (dec (alength heapified-arr))
        reverse-indexing #(take (inc %) (iterate dec %))]
@@ -317,20 +317,102 @@
 ;; "Elapsed time: 92,053.150033 msecs" for heap-sort

 ;; an example of heap-sort
+(defn heap-sort-by-heapify [xs]
+  (let [heapified (ArrayList.)
+        sorted (ArrayList.)]
+    (doseq [x (heapify xs)] (.add heapified x))
+    (loop []
+      (let [extracted-min (heap-extract-min heapified)]
+        (when (number? extracted-min)
+          (do
+            (.add sorted extracted-min)
+            (recur)))))
+    sorted
+    ))
 (time
-  (def s
-    (let [heapified (reduce
-                      (fn [acc x] (.add acc x) acc) (ArrayList.) (heapify nums))
-          sorted (ArrayList.)] ;; mutable auto-shrinkable list
-      (loop []
-        (let [extracted-min (heap-extract-min heapified)]
-          (when (number? extracted-min)
-            (do
-              (.add sorted extracted-min)
-              (recur)))))
-  sorted
-)))
+  (def s (heap-sort-by-heapify nums)))
 s

+(let [xs (ArrayList.)]
+  (.addAll xs (java.util.Arrays/asList (to-array [1 2 3])))
+  xs)
 (type (java.util.Arrays/asList (to-array [1 2])))
-(type (reduce (fn [lst x] (.add lst x) lst) (ArrayList.) (to-array [1 2 3])))+(type (reduce (fn [lst x] (.add lst x) lst) (ArrayList.) (to-array [1 2 3])))
+
+;; ANALYSING the running times.....
+(time
+  (def a (reduce (fn [acc x] (.add acc x) acc) (ArrayList.) (range 0 100000))))
+;; producing a new ArrayList with 100K items requires:: "Elapsed time: 142.279817 msecs"
+;; kind of a lot when the core "sort" requires only:: "Elapsed time: 50.9928 msecs"
+;; => therefore only building the array-list requires with a factor of 3 x times than
+;; to sort it.
+;; i've used ArrayList in my heap-insert/heap-extract implementations relying on
+;; dynamic shrinking the array-list while removing items from it, however behind
+;; the scenes, the entire array is copied with System.arraycopy...which is NOT
+;; wise at all...
+
+;; own thoughts...on how to improve the performance
+;; to optimize the heapify operation, i should discard ALL the ((2^height - 1) level) items
+;; bubbling-up, because those are leafs and shouldn't by heap-ordered!
+;; therefore:: based on the .length of the array, i should find the
+;; correspondent:: 2^x factor. i'm interested in finding the "x" here...
+;; where the x stands for the height, if i know the height, i know which items
+;; should be discarded based on the total items
+;; applying Math here, i'm interested in finding the (log2 x) by applying the
+;; (log10 x) / (log10 2) -> gives the logarithm in base 2
+(/ (Math/log10 8) (Math/log10 2)) ;; => (log2 x) -> where x = 3
+(/ (Math/log10 11) (Math/log10 2)) ;; => (log2 x) -> where x = 3.4594316186372978
+;; -> so flooring the number and i got the height
+;; if the items in an array size is: 11 -> then we can apply the math formula,
+;; and get the height, then applying the power of 2 using that computed height
+;; i know the range of the items that SHOULD BE included in the heap operation.
+
+(defn heapify [xs]
+  "heapify takes a vector and transforms it into a heapified data-structure
+   the operations performs in O(nlogn) just like any sorting operation
+   Note:: there's no better sorting operation that performs faster than
+          worst case running time of O(nlogn) VIA value-comparison!!!"
+ (let [heapified-arr (into-array xs)
+       height (int (/ (Math/log10 (alength heapified-arr)) (Math/log10 2)))
+       rev-idxs (reverse (range 0 (Math/pow 2 height)))]
+
+   ;; optimized to heapify ONLY the nodes which have children:: bubble-up
+   (loop [[idx & first-idxs] rev-idxs]
+     (cond (nil? idx) heapified-arr
+       :else
+         (let [node-val (aget heapified-arr idx)
+               [left-idx left-val] (left-child-of heapified-arr idx)
+               [right-idx right-val] (right-child-of heapified-arr idx)]
+           ;; curr-node higher than both left & right children?
+           (if (and ((comp not nil?) left-val)
+                    ((comp not nil?) right-val)
+                    (> node-val left-val) (> node-val right-val))
+             ;; compare the children nodes
+             (if (> right-val left-val)
+               (do ;; swap left
+                 (aset heapified-arr idx left-val)
+                 (aset heapified-arr left-idx node-val)
+                 (recur (cons left-idx first-idxs))) ;; bubble-down(remember swaped indx)
+               (do ;; swap right
+                 (aset heapified-arr idx right-val)
+                 (aset heapified-arr right-idx node-val)
+                 (recur (cons right-idx first-idxs)))) ;; bubble-down(remember swaped indx)
+             ;; curr-node higher only than right-child
+             (if (and ((comp not nil?) right-val)
+                      (> node-val right-val)) ;; swap right
+               (do
+                 (aset heapified-arr idx right-val)
+                 (aset heapified-arr right-idx node-val)
+                 (recur (cons right-idx first-idxs))) ;; bubble-down(remember swaped indx)
+               ;; curr-node higher only than left-child
+               (if (and ((comp not nil?) left-val)
+                        (> node-val left-val))
+                 (do
+                   (aset heapified-arr idx left-val)
+                   (aset heapified-arr left-idx node-val)
+                   (recur (cons left-idx first-idxs))) ;; bubble-down(remember swaped indx)
+                 ;; no attention required
+                 (recur first-idxs)
+))))))))
+(heapify [3 4 1 2 6 9 5 7 8]) ;; [1, 2, 3, 4, 6, 9, 5, 7, 8] => OK
+(heapify [12 8 7 6 5 11 4 2 3 1 10]) ;; [1, 2, 4, 3, 5, 11, 7, 6, 12, 8, 10] => OK


[scamp] rewrap comments on message types

--- modules/scamp/src/scamp/core.clj
+++ modules/scamp/src/scamp/core.clj
@@ -100,22 +100,27 @@
    ;; first [re]contact: [re]subscribe a new node
    :new-subscription

-   ;; new node joining cluster, recipient will probabilistically add this new node to :downstream, else forward it again
+   ;; new node joining cluster, recipient will probabilistically add
+   ;; this new node to :downstream, else forward it again
    :forwarded-subscription

    ;; inform newly :downstream node that you are now in its :upstream
    :new-upstream-node

-   ;; I added this to make it possible to instruct a node to unsubscribe.
+   ;; I added this to make it possible to instruct a node to
+   ;; unsubscribe.
    :node-unsubscription

-   ;; instruct an upstream node and a downstream node to connect directly, without me in the middle
+   ;; instruct an upstream node and a downstream node to connect
+   ;; directly, without me in the middle
    :node-replacement

-   ;; alternative to :node-replacement, used when upstream/downstream don't get a replacement
+   ;; alternative to :node-replacement, used when upstream/downstream
+   ;; don't get a replacement
    :node-removal

-   ;; just for saying "Hi" and "please don't assume you've been partitioned from the rest of the cluster"
+   ;; just for saying "Hi" and "please don't assume you've been
+   ;; partitioned from the rest of the cluster"
    :heartbeat

    ;; more stuff that isn't here yet...


CMR-3571 Adds testing blocks

CMR-3571 Adds testing blocks

--- access-control-app/int_test/cmr/access_control/int_test/acl_crud_test.clj
+++ access-control-app/int_test/cmr/access_control/int_test/acl_crud_test.clj
@@ -68,26 +68,28 @@
 ;; and collection_identifier when granule_applicable is true.

 (deftest create-catalog-item-identity-acl-test
-  (is (= 1 (:revision_id
-             (ac/create-acl (u/conn-context)
-                            {:group_permissions [{:user_type "guest"
-                                                  :permissions ["read"]}]
-                             :catalog_item_identity {:name "Catalog Item Identity 1"
-                                                     :provider_id "PROV1"
-                                                     :collection_identifier {:access_value {:include_undefined_value true}}
-                                                     :collection_applicable true
-                                                     :granule_applicable false}}
-                            {:token (transmit-config/echo-system-token)}))))
-  (is (= 1 (:revision_id
-             (ac/create-acl (u/conn-context)
-                            {:group_permissions [{:user_type "guest"
-                                                  :permissions ["read"]}]
-                             :catalog_item_identity {:name "Catalog Item Identity 2"
-                                                     :provider_id "PROV1"
-                                                     :collection_identifier {:access_value {:include_undefined_value true}}
-                                                     :collection_applicable false
-                                                     :granule_applicable true}}
-                            {:token (transmit-config/echo-system-token)})))))
+  (testing "with collection_identifier, collection_applicable true, and granule_applicable false"
+    (is (= 1 (:revision_id
+               (ac/create-acl (u/conn-context)
+                              {:group_permissions [{:user_type "guest"
+                                                    :permissions ["read"]}]
+                               :catalog_item_identity {:name "Catalog Item Identity 1"
+                                                       :provider_id "PROV1"
+                                                       :collection_identifier {:access_value {:include_undefined_value true}}
+                                                       :collection_applicable true
+                                                       :granule_applicable false}}
+                              {:token (transmit-config/echo-system-token)})))))
+  (testing "with collection_identifier, collection_applicable false, and granule_applicable true"
+    (is (= 1 (:revision_id
+               (ac/create-acl (u/conn-context)
+                              {:group_permissions [{:user_type "guest"
+                                                    :permissions ["read"]}]
+                               :catalog_item_identity {:name "Catalog Item Identity 2"
+                                                       :provider_id "PROV1"
+                                                       :collection_identifier {:access_value {:include_undefined_value true}}
+                                                       :collection_applicable false
+                                                       :granule_applicable true}}
+                              {:token (transmit-config/echo-system-token)}))))))

 (deftest create-single-instance-acl-permission-test
   (let [token (e/login (u/conn-context) "user1")


119 + wow solution

119 + wow solution

--- stuf/src/sandbox/4clojure.clj
+++ stuf/src/sandbox/4clojure.clj
@@ -838,13 +838,39 @@
   (lazy-seq (when (seq xs) (cons (pred fst) (my-map pred rst)))))

-;;119
-(defn f [xo]
+;;119 Win at Tic-Tac-Toe
+(defn f [trn xo]
   (let [m* (fn [n m] (map #(* % n) m))
+        l+ (fn [p l] (map #(map + p %) l))
         seed [[0 1] [1 0] [1 1] [-1 1]]
-        mult [-3 -2 1 2 3]
-        delta (map (fn [l] (map #(m* % l) mult)) seed)]
-    (for [x (range 3) y (range 3)] (map #(get-in xo (map + [x y] %)) delta))))
+        mult [-2 -1 1 2 ]
+        delta (map (fn [l] (map #(m* % l) mult)) seed)
+        lines (fn [p] (map #(l+ p %) delta))
+        check-ln (fn [ln] (filter identity (map #(get-in xo %) ln)))
+        check (fn [p] (->> (lines p)
+                           (map check-ln)
+                           (map #(cons trn %))
+                           (filter #(= 3 (count %)))
+                           (map set)
+                           (map count)
+                           (some #{1})))]
+    (set (for [x (range 3) y (range 3) :when (and (= :e (get-in xo [x y])) (check [x y]))] [x y]))))
+;; wow solution
+;;#(
+;;  reduce conj #{}
+;;  (for [x (range 3) y (range 3)
+;;       :when (and
+;;               (= :e (get-in %2 [x y]))
+;;               ((fn [[[a b c] [d e f] [g h i] :as x]]
+;;                  (some {[% % %] %}
+;;                        (list* [a d g]
+;;                               [b e h]
+;;                               [c f i]
+;;                               [a e i]
+;;                               [c e g]
+;;                               x)))
+;;                (assoc-in %2 [x y] %)))] [x y]))
+


82 seq function

82 seq function

--- stuf/src/sandbox/4clojure.clj
+++ stuf/src/sandbox/4clojure.clj
@@ -372,3 +372,10 @@
       (= d -1) (= (filter (set s1) s2) (seq s1))
       (= d 1) (recur s2 s1)
       :else false)))
+
+(defn g [xs]
+  (->>
+   (for [s1 xs s2 xs] [s1 s2])
+   (filter #(apply f %))
+   (reduce #(update-in %1 [(first %2)] conj (second %2)) {})))
+


Simplify condp dispatch for checking annotations

--- test/caesium/binding_test.clj
+++ test/caesium/binding_test.clj
@@ -90,10 +90,11 @@
            Integer/TYPE)
          (.getGenericReturnType method)))
   (doseq [{:keys [type annotations]} params]
-    (is (= (condp (fn [x y] (x y)) type
-             #{ByteArray ByteBuffer} #{Pinned}
-             #{Long/TYPE}  #{LongLong}
-             #{LongLongByReference} #{})
+    (is (= (condp = type
+             ByteArray #{Pinned}
+             ByteBuffer #{Pinned}
+             Long/TYPE  #{LongLong}
+             LongLongByReference #{})
            annotations))))

 (defn check-const-method


CMR-1239: DRY concept constraint tests

CMR-1239: DRY concept constraint tests

--- metadata-db-app/test/cmr/metadata_db/test/services/concept_constraints.clj
+++ metadata-db-app/test/cmr/metadata_db/test/services/concept_constraints.clj
@@ -45,142 +45,80 @@
   [constraint test-concept & existing-concepts]
   (is (nil? (apply run-constraint constraint test-concept existing-concepts))))

-(deftest entry-title-unique-constraint-test
-  (let [test-concept (make-concept :collection "PROV1" "C1-PROV1" 5 {:entry-title "ET1"})
-        is-valid (partial assert-valid (cc/unique-field-constraint :entry-title))
-        not-valid #(apply assert-invalid %1 (cc/unique-field-constraint :entry-title) test-concept %2)]
+(defn- unique-constraint-test
+  "Runs the given unique constraint test. Takes the following parameters:
+  concept-type - :collection or :granule
+  constraint-fn - uniqueness constraint function being tested
+  field - name of the field which must be unique (e.g. :entry-title, :entry-id, or :granule-ur)"
+  [concept-type constraint-fn field]
+  (let [extra-fields {field "unique-field1"}
+        test-concept (make-concept concept-type "PROV1" "C1-PROV1" 5 extra-fields)
+        is-valid (partial assert-valid constraint-fn)
+        not-valid #(apply assert-invalid %1 constraint-fn test-concept %2)]

     (testing "valid cases"
       (testing "with empty database"
         (is-valid test-concept))
-      (testing "another collection with entry title that is deleted is valid"
-        (let [other-tombstone (make-tombstone :collection "PROV1" "C2-PROV1" 2 {:entry-title "ET1"})]
+      (testing (format "another collection with %s that is deleted is valid" field)
+        (let [other-tombstone (make-tombstone concept-type "PROV1" "C2-PROV1" 2 extra-fields)]
           (is-valid test-concept other-tombstone)))
-      (testing "another provider with the same entry title is valid "
-        (let [other-concept (make-concept :collection "PROV2" "C1-PROV1" 5 {:entry-title "ET1"})]
+      (testing (format "another provider with the same %s is valid " field)
+        (let [other-concept (make-concept concept-type "PROV2" "C1-PROV1" 5 extra-fields)]
           (is-valid test-concept other-concept)))
       (testing "same concept id but earlier revision id is valid"
-        (let [other-concept (make-concept :collection "PROV1" "C1-PROV1" 4 {:entry-title "ET1"})]
+        (let [other-concept (make-concept concept-type "PROV1" "C1-PROV1" 4 extra-fields)]
           (is-valid test-concept other-concept)))
-      (testing "different entry titles are valid"
-        (let [other-concept (make-concept :collection "PROV1" "C1-PROV1" 5 {:entry-title "ET2"})]
+      (testing (format "different values for %s are valid" field)
+        (let [other-concept (make-concept concept-type "PROV1" "C1-PROV1" 5 {field "unique-field2"})]
           (is-valid test-concept other-concept)))
       (testing "multiple valid concepts are still valid"
         (is-valid test-concept
-                  (make-concept :collection "PROV1" "C2-PROV1" 1 {:entry-title "ET1"})
-                  (make-tombstone :collection "PROV1" "C2-PROV1" 2 {:entry-title "ET1"})
-                  (make-concept :collection "PROV2" "C1-PROV1" 5 {:entry-title "ET1"})
-                  (make-concept :collection "PROV1" "C1-PROV1" 4 {:entry-title "ET1"})
-                  (make-concept :collection "PROV1" "C1-PROV1" 5 {:entry-title "ET2"}))))
+                  (make-concept concept-type "PROV1" "C2-PROV1" 1 extra-fields)
+                  (make-tombstone concept-type "PROV1" "C2-PROV1" 2 extra-fields)
+                  (make-concept concept-type "PROV2" "C1-PROV1" 5 extra-fields)
+                  (make-concept concept-type "PROV1" "C1-PROV1" 4 extra-fields)
+                  (make-concept concept-type "PROV1" "C1-PROV1" 5 {field "unique-field2"}))))

     (testing "invalid cases"
-      (testing "same entry title"
-        (let [other-concept (make-concept :collection "PROV1" "C2-PROV1" 1 {:entry-title "ET1"})]
+      (testing (format "same %s" field)
+        (let [other-concept (make-concept concept-type "PROV1" "C2-PROV1" 1 extra-fields)]
           (not-valid
-            (msg/duplicate-field-msg :entry-title [other-concept])
+            (msg/duplicate-field-msg field [other-concept])
             [other-concept])))
       (testing "cannot find saved concept throws internal error"
-        (let [db (mem-db/create-db)]
+        (let [db (mem-db/create-db)
+              error-regex (java.util.regex.Pattern/compile
+                            (format "Unable to find saved concept for provider.*PROV1.*and %s .*unique-field1"
+                                    (name field)))]
           (is (thrown-with-msg?
                 java.lang.Exception
-                #"Unable to find saved concept for provider \[PROV1\] and entry-title \[ET1\]"
-                ((cc/unique-field-constraint :entry-title) db test-concept))))))))
+                error-regex
+                (constraint-fn db test-concept))))))))

-(deftest entry-id-unique-constraint-test
-  (let [test-concept (make-concept :collection "PROV1" "C1-PROV1" 5 {:entry-id "EID-1"})
-        is-valid (partial assert-valid (cc/unique-field-constraint :entry-id))
-        not-valid #(apply assert-invalid %1 (cc/unique-field-constraint :entry-id) test-concept %2)]
+(deftest unique-constraint-tests
+  (unique-constraint-test :collection (cc/unique-field-constraint :entry-title) :entry-title)
+  (unique-constraint-test :collection (cc/unique-field-constraint :entry-id) :entry-id)
+  (unique-constraint-test :granule (cc/unique-field-constraint :granule-ur) :granule-ur)
+  (unique-constraint-test :granule cc/granule-ur-unique-constraint :granule-ur)

-    (testing "valid cases"
-      (testing "with empty database"
-        (is-valid test-concept))
-      (testing "another collection with entry id that is deleted is valid"
-        (let [other-tombstone (make-tombstone :collection "PROV1" "C2-PROV1" 2 {:entry-id "EID-1"})]
-          (is-valid test-concept other-tombstone)))
-      (testing "another provider with the same entry id is valid "
-        (let [other-concept (make-concept :collection "PROV2" "C1-PROV1" 5 {:entry-id "EID-1"})]
-          (is-valid test-concept other-concept)))
-      (testing "same concept id but earlier revision id is valid"
-        (let [other-concept (make-concept :collection "PROV1" "C1-PROV1" 4 {:entry-id "EID-1"})]
-          (is-valid test-concept other-concept)))
-      (testing "different entry ids are valid"
-        (let [other-concept (make-concept :collection "PROV1" "C1-PROV1" 5 {:entry-id "EID-2"})]
-          (is-valid test-concept other-concept)))
-      (testing "multiple valid concepts are still valid"
-        (is-valid test-concept
-                  (make-concept :collection "PROV1" "C2-PROV1" 1 {:entry-id "EID-1"})
-                  (make-tombstone :collection "PROV1" "C2-PROV1" 2 {:entry-id "EID-1"})
-                  (make-concept :collection "PROV2" "C1-PROV1" 5 {:entry-id "EID-1"})
-                  (make-concept :collection "PROV1" "C1-PROV1" 4 {:entry-id "EID-1"})
-                  (make-concept :collection "PROV1" "C1-PROV1" 5 {:entry-id "EID-2"}))))
-
-    (testing "invalid cases"
-      (testing "same entry id"
-        (let [other-concept (make-concept :collection "PROV1" "C2-PROV1" 1 {:entry-id "EID-1"})]
-          (not-valid
-            (msg/duplicate-field-msg :entry-id [other-concept])
-            [other-concept])))
-      (testing "cannot find saved concept throws internal error"
-        (let [db (mem-db/create-db)]
-          (is (thrown-with-msg?
-                java.lang.Exception
-                #"Unable to find saved concept for provider \[PROV1\] and entry-id \[EID-1\]"
-                ((cc/unique-field-constraint :entry-id) db test-concept)))))
-
-      (testing "invalid field throws internal error"
-        (let [db (mem-db/create-db)]
-          (is (thrown-with-msg?
-                java.lang.Exception
-                #"Unable to find saved concept for provider \[PROV1\] and invalid-field \[null\]"
-                ((cc/unique-field-constraint :invalid-field) db test-concept))))))))
+  (testing "invalid field throws internal error"
+    (let [db (mem-db/create-db)
+          test-concept (make-concept :collection "PROV1" "C1-PROV1" 5 {:entry-title "ET1"})]
+      (is (thrown-with-msg?
+            java.lang.Exception
+            #"Unable to find saved concept for provider \[PROV1\] and invalid-field \[null\]"
+            ((cc/unique-field-constraint :invalid-field) db test-concept))))))

 (deftest granule-ur-unique-constraint-test
-  (let [test-concept (make-concept :granule "PROV1" "C1-PROV1" 5 {:granule-ur "G_UR-1"})
-        is-valid (partial assert-valid cc/granule-ur-unique-constraint)
-        not-valid #(apply assert-invalid %1 cc/granule-ur-unique-constraint test-concept %2)]
-
-    (testing "valid cases"
-      (testing "with empty database"
-        (is-valid test-concept))
-      (testing "another granule with granule-ur that is deleted is valid"
-        (let [other-tombstone (make-tombstone :granule "PROV1" "C2-PROV1" 2 {:granule-ur "G_UR-1"})]
-          (is-valid test-concept other-tombstone)))
-      (testing "another provider with the same granule-ur is valid "
-        (let [other-concept (make-concept :granule "PROV2" "C1-PROV1" 5 {:granule-ur "G_UR-1"})]
-          (is-valid test-concept other-concept)))
-      (testing "same concept id but earlier revision id is valid"
-        (let [other-concept (make-concept :granule "PROV1" "C1-PROV1" 4 {:granule-ur "G_UR-1"})]
-          (is-valid test-concept other-concept)))
-      (testing "different granule-urs are valid"
-        (let [other-concept (make-concept :granule "PROV1" "C1-PROV1" 5 {:granule-ur "G_UR-2"})]
-          (is-valid test-concept other-concept)))
-      (testing "multiple valid concepts are still valid"
-        (is-valid test-concept
-                  (make-concept :granule "PROV1" "C2-PROV1" 1 {:granule-ur "G_UR-1"})
-                  (make-tombstone :granule "PROV1" "C2-PROV1" 2 {:granule-ur "G_UR-1"})
-                  (make-concept :granule "PROV2" "C1-PROV1" 5 {:granule-ur "G_UR-1"})
-                  (make-concept :granule "PROV1" "C1-PROV1" 4 {:granule-ur "G_UR-1"})
-                  (make-concept :granule "PROV1" "C1-PROV1" 5 {:granule-ur "G_UR-2"}))))
-
-    (testing "invalid cases"
-      (testing "same granule-ur"
-        (let [other-concept (make-concept :granule "PROV1" "C2-PROV1" 1 {:granule-ur "G_UR-1"})]
-          (not-valid
-            (msg/duplicate-field-msg :granule-ur [other-concept])
-            [other-concept])))
-      (testing "native-id is checked for uniqueness when granule-ur is null"
-        (let [other-concept (make-concept :granule "PROV1" "C2-PROV1" 1 "G_UR-1" {})]
-          (not-valid
-            (msg/duplicate-field-msg :granule-ur
-                                     [(assoc-in other-concept [:extra-fields :granule-ur]
-                                                (get-in test-concept [:extra-fields :granule-ur]))])
-            [other-concept])))
-      (testing "cannot find saved concept throws internal error"
-        (let [db (mem-db/create-db)]
-          (is (thrown-with-msg?
-                java.lang.Exception
-                #"Unable to find saved concept for provider \[PROV1\] and granule-ur \[G_UR-1\]"
-                (cc/granule-ur-unique-constraint db test-concept))))))))
+  (testing "native-id is checked for uniqueness when granule-ur is null"
+    (let [test-concept (make-concept :granule "PROV1" "C1-PROV1" 5 {:granule-ur "G_UR-1"})
+          not-valid #(apply assert-invalid %1 cc/granule-ur-unique-constraint test-concept %2)
+          other-concept (make-concept :granule "PROV1" "C2-PROV1" 1 "G_UR-1" {})]
+      (not-valid
+        (msg/duplicate-field-msg :granule-ur
+                                 [(assoc-in other-concept [:extra-fields :granule-ur]
+                                            (get-in test-concept [:extra-fields :granule-ur]))])
+        [other-concept]))))

 (comment


version bump slamhound

version bump slamhound

--- dot/lein/profiles.clj
+++ dot/lein/profiles.clj
@@ -5,7 +5,7 @@
             [com.palletops/pallet-lein "0.8.0-alpha.1"]]
   :dependencies [;[ritz/ritz-nrepl-middleware "0.7.0"]
                  [org.clojure/tools.trace "0.7.6"]
-                 [slamhound "1.3.3"]]
+                 [slamhound "1.5.0"]]
   ;; :repl-options {:nrepl-middleware
   ;;                [ritz.nrepl.middleware.javadoc/wrap-javadoc
   ;;                 ritz.nrepl.middleware.simple-complete/wrap-simple-complete]}