fixed #42

fixed #42

--- src/frontend/core.cljs
+++ src/frontend/core.cljs
@@ -248,15 +248,17 @@
              "track-order:" track-order
              "current-track-id:" current-track-id
              "current-sound-id:" current-sound-id)
-    ; TODO: should probably convert room-music-info to clojure object before manipulating
     (let [track-order (js->clj track-order)
-          sorted-music-info (.sort room-music-info (fn [a b]
-                                                     (- (first (indices #(= %1 (.-id a)) track-order))
-                                                        (first (indices #(= %1 (.-id b)) track-order)))))]
-
+          room-music-info (js->clj room-music-info)
+          sorted-music-info (sort (fn [a b]
+                                    (compare (first (indices #(= %1 (get a "id")) track-order))
+                                             (first (indices #(= %1 (get b "id")) track-order))))
+                                  room-music-info)]
+      (println "SORTED")
+      (println sorted-music-info)
       (swap! app-state assoc :track-order track-order)
       (swap! app-state assoc :music-info (vec (map #(clj->js %1)
-                                                (js->clj sorted-music-info)))))
+                                                   sorted-music-info))))

     (swap! app-state assoc :current-track-id current-track-id)
     (swap! app-state assoc :current-sound-id current-sound-id)


Removing doall as per sw1nn's comment.

Removing doall as per sw1nn's comment.

--- src/kixi/hecuba/data/measurements.clj
+++ src/kixi/hecuba/data/measurements.clj
@@ -164,15 +164,15 @@
    size of the batches and inserts them into the database."
   [store sensor page measurements]
   (db/with-session [session (:hecuba-session store)]
-    (doall (reduce (fn [{:keys [min-date max-date]} batch]
-                     (let [dates (time/min-max-dates batch)
-                           new-min (:min-date dates)
-                           new-max (:max-date dates)]
-                       (insert-batch session batch)
-                       {:min-date (if (t/before? new-min min-date) new-min min-date)
-                        :max-date (if (t/after? new-max max-date) new-max max-date)}))
-                   {:min-date (tc/from-date (:timestamp (first measurements)))
-                    :max-date (tc/from-date (:timestamp (first measurements)))} (partition-all page measurements)))))
+    (reduce (fn [{:keys [min-date max-date]} batch]
+              (let [dates (time/min-max-dates batch)
+                    new-min (:min-date dates)
+                    new-max (:max-date dates)]
+                (insert-batch session batch)
+                {:min-date (if (t/before? new-min min-date) new-min min-date)
+                 :max-date (if (t/after? new-max max-date) new-max max-date)}))
+            {:min-date (tc/from-date (:timestamp (first measurements)))
+             :max-date (tc/from-date (:timestamp (first measurements)))} (partition-all page measurements))))

 (defn parse-double [txt]
   (Double/parseDouble txt))


Unify buffer creation between convolver and noise.

--- src/klangmeister/sound/synthesis.cljs
+++ src/klangmeister/sound/synthesis.cljs
@@ -110,7 +110,7 @@
         buffer (.createBuffer context 1 frame-count sample-rate)
         data (.getChannelData buffer 0)]
     (doseq [i (range sample-rate)]
-      (aset data i (generate-bit!)))
+      (aset data i (generate-bit! i)))
     buffer))

 (defn noise
@@ -123,7 +123,7 @@
         (.start at)))))

 (def white-noise
-  (let [white #(-> (js/Math.random) (* 2.0) (- 1.0))]
+  (let [white (fn [_] (-> (js/Math.random) (* 2.0) (- 1.0)))]
     (noise white)))

 (defn constant
@@ -186,19 +186,12 @@
         (doto (.createDelay context maximum)
           (-> .-delayTime (plug time context at duration)))))))

-; FIXME: Unify with noise.
 (defn convolver
   [generate-bit!]
   (fn [context at duration]
-    (let [sample-rate 44100
-          frame-count (* sample-rate (+ duration 1.0)) ; Give a bit of extra for the release.
-          buffer (.createBuffer context 1 frame-count sample-rate)
-          data (.getChannelData buffer 0)]
-      (doseq [i (range sample-rate)]
-        (aset data i (generate-bit! i)))
-      (section
-        (doto (.createConvolver context)
-          (-> .-buffer (set! buffer)))))))
+    (section
+      (doto (.createConvolver context)
+        (-> .-buffer (set! (buffer generate-bit! context (+ duration 1.0))))))))

 (def wet
   (let [duration 5


Set DB consistency to quorum

Set DB consistency to quorum

--- src/lcmap/clownfish/configuration.clj
+++ src/lcmap/clownfish/configuration.clj
@@ -25,7 +25,8 @@
    :db     {:keyspace (:db-keyspace env)
             :cluster {:contact-points (tokenize (:db-url env))
                       :credentials {:user (:db-user env)
-                                    :password (:db-pass env)}}}
+                                    :password (:db-pass env)}
+                      :query-options {:consistency :quorum}}}
    :server {:exchange (:exchange env) :queue (:queue env)}
    :chip-specs-url (:chip-specs-url env)})


Fixed FressianReader user handler bug

Fixed FressianReader user handler bug

--- src/longshi/fressian/byte_stream.cljs
+++ src/longshi/fressian/byte_stream.cljs
@@ -261,5 +261,5 @@

 (defn byte-input-stream
   ([stream] (byte-input-stream stream #js {}))
-  ([stream user-handlers] (byte-input-stream stream #js {} true))
+  ([stream user-handlers] (byte-input-stream stream user-handlers true))
   ([stream user-handlers use-checksum] (->ByteInputStream stream 0 0 user-handlers fh/core-read-handlers #js [] #js [] use-checksum)))


Add 'ensure-deps-repos for 'freshen and 'box-add commands.

The 'box-add metadata was brought into line with project.clj
originating metadata, being nested one level down under the key :voom.

--- src/leiningen/voom.clj
+++ src/leiningen/voom.clj
@@ -274,6 +274,15 @@

 ;; === build-deps ===
+
+(defn ensure-deps-repos
+  "Ensures that any repos, mentioned in dependency metadata, are
+   cloned locally."
+  [deps]
+  (doseq [dep deps
+          :let [dep-meta-repo (-> dep meta :voom :repo)]
+          :when dep-meta-repo]
+    (ensure-repo dep-meta-repo)))

 (defn resolve-artifact
   "Build and install given artifact using git. Return value is
@@ -584,7 +593,7 @@
   (newline))

 (defn fresh-version [[prj ver :as dep]]
-  (let [voom-meta (:voom (meta dep))
+  (let [voom-meta (-> dep meta :voom)
         ver-spec (or (:version voom-meta)
                      (re-find #"^[^.]+." ver))
         groups (->> (newest-voom-ver-by-spec prj (merge voom-meta {:version ver-spec
@@ -637,6 +646,7 @@

   Example: lein voom freshen"
   [project]
+  (ensure-deps-repos (:dependencies project))
   (p-repos (fn [p] (fetch-all [p]) (tag-repo-projects p)))
   (let [prj-file-name (str (:root project) "/project.clj")
         old-deps (:dependencies project)
@@ -760,27 +770,29 @@
       (if (seq rdeps)
         (if (map? fdep)
           (let [[ndep & rdeps] rdeps]
-            (recur (conj deps (with-meta ndep fdep)) rdeps))
+            (recur (conj deps (with-meta ndep {:voom fdep})) rdeps))
           (recur (conj deps fdep) rdeps))
         (conj deps fdep))
       deps)))

 (defn box-add
   [proj & adeps]
-  (p-repos (fn [p] (tag-repo-projects p)))
-  (doseq [:let [deps (fold-args-as-meta (map edn/read-string adeps))]
-          dep deps
-          :let [full-projs (if (.contains (str dep) "/")
-                             [dep]
-                             (resolve-short-proj (pr-str dep) (all-projects)))
-                full-projs (map symbol full-projs)
-                repo-infos (mapcat #(newest-voom-ver-by-spec % (meta dep)) full-projs)]]
-    (case (count repo-infos)
-      0 (throw (ex-info "Could not find matching projects" {:dep dep}))
-      1 (box-repo-add (first repo-infos))
-      (do
-        (print "Multiple projects / locations match" (str \" dep \"\:))
-        (print-repo-infos repo-infos)))))
+  (let [deps (fold-args-as-meta (map edn/read-string adeps))]
+    (ensure-deps-repos deps)
+    (p-repos (fn [p] (tag-repo-projects p)))
+    (doseq [dep deps
+            :let [full-projs (if (.contains (str dep) "/")
+                               [dep]
+                               (resolve-short-proj (pr-str dep) (all-projects)))
+                  full-projs (map symbol full-projs)
+                  repo-infos (mapcat #(newest-voom-ver-by-spec % (-> dep meta :voom))
+                                     full-projs)]]
+      (case (count repo-infos)
+        0 (throw (ex-info "Could not find matching projects" {:dep dep}))
+        1 (box-repo-add (first repo-infos))
+        (do
+          (print "Multiple projects / locations match" (str \" dep \"\:))
+          (print-repo-infos repo-infos))))))

 (defn box-init
   [proj target & args]


Use print-table for multiple match messages

--- src/leiningen/voom.clj
+++ src/leiningen/voom.clj
@@ -1,7 +1,7 @@
 (ns leiningen.voom
   (:require [clojure.java.shell :as shell]
             [clojure.string :as s]
-            [clojure.pprint :refer [pprint]]
+            [clojure.pprint :refer [pprint print-table]]
             [clojure.java.io :as io]
             [leiningen.core.project :as project]
             [leiningen.core.main :as lmain]
@@ -464,6 +464,18 @@
                  :branch found-branch}))
             (partition 2 1 (concat commits [:end]))))))

+(defn print-repo-infos
+  [repo-infos]
+  (->> repo-infos
+       (map (fn [info]
+              (-> info
+                  (dissoc :gitdir)
+                  (assoc :repo (-> (remotes (:gitdir info)) :origin :fetch))
+                  (update-in [:sha] #(subs (str % "--------") 0 7)))))
+       (sort-by :ctime)
+       (print-table [:repo :proj :ver :branch :path :ctime :sha]))
+  (newline))
+
 (defn fresh-version [[prj ver :as dep]]
   (let [voom-meta (:voom (meta dep))
         ver-spec (or (:version voom-meta)
@@ -476,12 +488,9 @@
      0 (do (println "No matching version found for" prj (pr-str ver-spec))
            dep)
      1 (assoc dep 1 (key (first groups)))
-     (do (println "\nMultiple bump resolutions for:"
-                  prj (pr-str ver-spec) (pr-str voom-meta))
-         (doseq [[voom-ver group] groups]
-           (prn voom-ver (map #(assoc (select-keys % [:branch :path :ctime])
-                                 :repo (-> (remotes (:gitdir %)) :origin :fetch))
-                              group)))
+     (do (print "\nMultiple bump resolutions for:"
+                prj (pr-str ver-spec) (pr-str voom-meta))
+         (print-repo-infos (map #(first (val %)) groups))
          dep))))

 (defn rewrite-project-file [input-str replacement-map]
@@ -599,9 +608,8 @@
           repo-infos (mapcat #(newest-voom-ver-by-spec % "" {}) full-projs)]
       (if (< 1 (count repo-infos))
         (do
-          (println "Multiple projects / locations match" (str \" dep \"\:))
-          (doseq [r repo-infos]
-            (prn r)))
+          (print "Multiple projects / locations match" (str \" dep \"\:))
+          (print-repo-infos repo-infos))
         (box-repo-add (first repo-infos))))))

 ;; === lein entrypoint ===


Return of the spec-tests for cljs

Return of the spec-tests for cljs

--- test/cljs/reitit/doo_runner.cljs
+++ test/cljs/reitit/doo_runner.cljs
@@ -5,7 +5,7 @@
             reitit.impl-test
             reitit.middleware-test
             reitit.ring-test
-            #_reitit.spec-test
+            reitit.spec-test
             reitit.exception-test
             reitit.frontend.core-test
             reitit.frontend.history-test
@@ -18,7 +18,7 @@
            'reitit.impl-test
            'reitit.middleware-test
            'reitit.ring-test
-           #_'reitit.spec-test
+           'reitit.spec-test
            'reitit.exception-test
            'reitit.frontend.core-test
            'reitit.frontend.history-test


Disable test for Bundle import race condition (#1183)

Disable the race condition test which is more a probe of the race condition that can be used to address it later.

--- test/ctia/bundle/routes_test.clj
+++ test/ctia/bundle/routes_test.clj
@@ -1126,7 +1126,7 @@
          (is (= 200 (:status bundle-get-res)))
          (is (seq (-> bundle-get-res :parsed-body :casebooks))))))))

-(deftest race-condition-test
+(deftest ^:disabled race-condition-test
   (helpers/with-properties
     ["ctia.store.es.default.refresh" "false"
      "ctia.store.es.default.refresh_interval" "1s"
@@ -1156,10 +1156,10 @@
                            :confidence "High"}]}
              import (fn [new-bundle]
                       (POST app
-                          "ctia/bundle/import"
-                        :body new-bundle
-                        :headers {"Authorization" "45c1f5e3f05d0"}))
+                            "ctia/bundle/import"
+                            :body new-bundle
+                            :headers {"Authorization" "45c1f5e3f05d0"}))
              res (->> (pmap import (repeat 10 new-bundle))
                       (mapcat (comp :results :parsed-body)))]
          (testing "there is a race condition for checking external ids"
-             (is (< 1 (count (filter #(= "created" (:result %)) res))))))))))
+           (is (< 1 (count (filter #(= "created" (:result %)) res))))))))))


Temporarily hiding useless cards

Temporarily hiding useless cards

--- src-cljs/photon/ui/frontend.cljs
+++ src-cljs/photon/ui/frontend.cljs
@@ -391,7 +391,7 @@
                 (dom/span
                   #js {:className "data"}
                     "CPU Load: " (:cpu-load (:stats params)) "%"))))
-        (dom/div
+        #_#_#_(dom/div
           #js {:className "col-sm-12 col-md-6 col-lg-4"}
           (dom/div
             #js {:className "widget-box"}


cjl - Fix translation test

cjl - Fix translation test

--- test/icfp2015/unit_test.clj
+++ test/icfp2015/unit_test.clj
@@ -18,17 +18,17 @@
             expected-unit { :members #{ [1 0] [2 1] } :pivot [1 1] }]
         (is (= expected-unit actual-unit))))

-    (testing "translate southwest"
-      (let [unit { :members #{ [0 0] [1 1] } :pivot [0 1] }
+    (testing "translate even row southwest"
+      (let [unit { :members #{ [0 1] [0 2] } :pivot [0 1] }
             f    (apply translate southwest)
             actual-unit (f unit)
-            expected-unit { :members #{ [0 1] [1 2] } :pivot [0 2] }]
+            expected-unit { :members #{ [1 0] [1 1] } :pivot [1 0] }]
         (is (= expected-unit actual-unit))))

-    (testing "translate southeast"
-      (let [unit { :members #{ [0 0] [1 1] } :pivot [0 1] }
+    (testing "translate even row southeast"
+      (let [unit { :members #{ [0 0] [0 1] } :pivot [0 1] }
             f    (apply translate southeast)
             actual-unit (f unit)
-            expected-unit { :members #{ [1 1] [2 2] } :pivot [1 2] }]
+            expected-unit { :members #{ [1 0] [1 1] } :pivot [1 2] }]
         (is (= expected-unit actual-unit))))))


[#1062] Update backend deps

[#1062] Update backend deps

Did not update org.akvo.* dependencies.

--- backend/project.clj
+++ backend/project.clj
@@ -4,34 +4,33 @@
   :license {:name "GNU Affero General Public License 3.0"
             :url  "https://www.gnu.org/licenses/agpl-3.0.html"}
   :min-lein-version "2.0.0"
-  :dependencies [[cheshire "5.7.0"]
-                 [clj-http "3.4.1"]
-                 [clj-time "0.13.0"]
-                 [org.apache.tika/tika-core "1.14"]
-                 [org.apache.tika/tika-parsers "1.14"]
+  :dependencies [[cheshire "5.8.0"]
+                 [clj-http "3.7.0"]
+                 [clj-time "0.14.0"]
                  [com.layerware/hugsql "0.4.7"]
                  [com.stuartsierra/component "0.3.2"]
-                 [compojure "1.5.2" :exclusions [medley]]
+                 [commons-io/commons-io "2.5"]
+                 [compojure "1.6.0" :exclusions [medley]]
+                 [duct "0.8.2"]
+                 [duct/hikaricp-component "0.1.1"]
+                 [environ "1.1.0"]
                  [funcool/cuerdas "2.0.3"]
-                 [duct "0.8.2"]
-                 [duct/hikaricp-component "0.1.0"]
-                 [environ "1.1.0"]
                  [meta-merge "1.0.0"]
                  [org.akvo/commons "0.4.4-SNAPSHOT" :exclusions [org.postgresql/postgresql org.clojure/java.jdbc]]
                  [org.akvo/resumed "0.1.0-SNAPSHOT"]
-                 [commons-io/commons-io "2.5"]
-                 [org.apache.tika/tika-core "1.14"]
+                 [org.apache.tika/tika-core "1.16"]
+                 [org.apache.tika/tika-parsers "1.16"]
                  [org.clojure/clojure "1.8.0"]
-                 [org.clojure/data.csv "0.1.3"]
-                 [org.immutant/web "2.1.6"]
-                 [org.postgresql/postgresql "42.0.0"]
-                 [org.slf4j/slf4j-nop "1.7.24"]
+                 [org.clojure/data.csv "0.1.4"]
+                 [org.immutant/web "2.1.9"]
+                 [org.postgresql/postgresql "42.1.4"]
+                 [org.slf4j/slf4j-nop "1.7.25"]
                  [ragtime/ragtime.jdbc "0.6.4"]
                  [raven-clj "1.5.0"]
-                 [ring "1.5.1"]
-                 [ring/ring-defaults "0.2.3"]
+                 [ring "1.6.2"]
+                 [ring/ring-defaults "0.3.1"]
                  [ring/ring-json "0.4.0"]
-                 [selmer "1.10.8"]]
+                 [selmer "1.11.1"]]
   :uberjar-name "akvo-lumen.jar"
   :repl-options {:timeout 120000}
   ;; :pedantic? :abort
@@ -57,8 +56,8 @@
    :project/dev   {:dependencies   [[duct/generate "0.8.2"]
                                     [reloaded.repl "0.2.3"]
                                     [org.clojure/tools.namespace "0.2.11"]
-                                    [org.clojure/tools.nrepl "0.2.12"]
-                                    [eftest "0.1.3"]
+                                    [org.clojure/tools.nrepl "0.2.13"]
+                                    [eftest "0.3.1"]
                                     [com.gearswithingears/shrubbery "0.4.1"]
                                     [kerodon "0.8.0"]]
                    :plugins        [[jonase/eastwood "0.2.3"]]


update resolve-var hacks in prep for next cljs release

https://github.com/clojure/clojurescript/commit/6cbd40f865132b8b13c6b902b715aed43e64f0b1

--- src/main/shadow/build/cljs_hacks.cljc
+++ src/main/shadow/build/cljs_hacks.cljc
@@ -54,7 +54,8 @@
               (is-shadow-shim? ns))
       (shadow-js-access-property current-ns prop))

-    {:name qname
+    {:op :js-var
+     :name qname
      :tag 'js
      :ret-tag 'js
      :ns 'js}))
@@ -71,7 +72,8 @@

 (defn resolve-cljs-var [ns sym]
   (merge (ana/gets @env/*compiler* ::ana/namespaces ns :defs sym)
-    {:name (symbol (str ns) (str sym))
+    {:op :var
+     :name (symbol (str ns) (str sym))
      :ns ns}))

 (defn resolve-ns-var [ns sym current-ns]
@@ -85,7 +87,8 @@
     (resolve-js-var ns sym current-ns)

     (contains? (:goog-names @env/*compiler*) ns)
-    {:name (symbol (str ns) (str sym))
+    {:op :js-var
+     :name (symbol (str ns) (str sym))
      :ns ns}

     :else
@@ -103,10 +106,21 @@

 (defn resolve-invokeable-ns [alias current-ns env]
   (let [ns (ana/resolve-ns-alias env alias)]
-    {:name (symbol "js" (str ns))
+    {:op :js-var
+     :name (symbol "js" (str ns))
      :tag 'js
      :ret-tag 'js
      :ns 'js}))
+
+;; core.async calls `macroexpand-1` manually with an ill-formed
+;; :locals map. Normally :locals maps symbols maps, but
+;; core.async adds entries mapping symbols to symbols. We work
+;; around that specific case here. This is called defensively
+;; every time we lookup the :locals map.
+(defn handle-symbol-local [sym lb]
+  (if (symbol? lb)
+    {:name sym}
+    lb))

 (def known-safe-js-globals
   "symbols known to be closureJS compliant namespaces"
@@ -125,38 +139,46 @@
          sym-ns-str (namespace sym)]

      (if (= "js" sym-ns-str)
-       (do (when (contains? locals (-> sym name symbol))
-             (ana/warning :js-shadowed-by-local env {:name sym}))
-
+       ;; js/... vars
+       (let [symn (-> sym name symbol)
+             shadowed-by-local (handle-symbol-local symn (get locals symn))]
+         (cond
+           (some? shadowed-by-local)
+           (do (ana/warning :js-shadowed-by-local env {:name sym})
+               (assoc shadowed-by-local :op :local))
+
+           :else
            ;; always record all fully qualified js/foo.bar calls
            ;; except for the code emitted by cljs.core/exists?
            ;; (exists? some.foo/bar)
            ;; checks js/some, js/some.foo, js/some.foo.bar
-           (when-not (-> sym meta ::ana/no-resolve)
-             (let [[global & props]
-                   (str/split (name sym) #"\.")]
-
-               ;; do not record access to
-               ;; js/goog.string.format
-               ;; js/cljs.core.assoc
-               ;; just in case someone does that, we won't need externs for those
-               (when-not (contains? known-safe-js-globals global)
-                 (shadow-js-access-global current-ns global)
-                 (when (seq props)
-                   (doseq [prop props]
-                     (shadow-js-access-property current-ns prop))))))
-
-           {:name sym
-            :ns 'js
-            :tag 'js
-            :ret-tag 'js})
-
+           (do (when-not (-> sym meta ::ana/no-resolve)
+                 (let [[global & props]
+                       (str/split (name sym) #"\.")]
+
+                   ;; do not record access to
+                   ;; js/goog.string.format
+                   ;; js/cljs.core.assoc
+                   ;; just in case someone does that, we won't need externs for those
+                   (when-not (contains? known-safe-js-globals global)
+                     (shadow-js-access-global current-ns global)
+                     (when (seq props)
+                       (doseq [prop props]
+                         (shadow-js-access-property current-ns prop))))))
+
+               {:op :js-var
+                :name sym
+                :ns 'js
+                :tag 'js
+                :ret-tag 'js})))
+
+       ;; none js/... vars
        (let [s (str sym)
-             lb (get locals sym)
+             lb (handle-symbol-local sym (get locals sym))
              current-ns-info (ana/gets @env/*compiler* ::ana/namespaces current-ns)]

          (cond
-           (some? lb) lb
+           (some? lb) (assoc lb :op :local)

            (some? sym-ns-str)
            (let [ns sym-ns-str
@@ -177,16 +199,20 @@
            (let [idx (.indexOf s ".")
                  prefix (symbol (subs s 0 idx))
                  suffix (subs s (inc idx))]
-             (if-some [lb (get locals prefix)]
-               {:name (symbol (str (:name lb)) suffix)}
+             (if-some [lb (handle-symbol-local prefix (get locals prefix))]
+               {:op :local
+                :name (symbol (str (:name lb)) suffix)}
                (if-some [full-ns (ana/gets current-ns-info :imports prefix)]
-                 {:name (symbol (str full-ns) suffix)}
+                 {:op :local
+                  :name (symbol (str full-ns) suffix)}
                  (if-some [info (ana/gets current-ns-info :defs prefix)]
                    (merge info
-                     {:name (symbol (str current-ns) (str sym))
+                     {:op :local
+                      :name (symbol (str current-ns) (str sym))
                       :ns current-ns})
                    (merge (ana/gets @env/*compiler* ::ana/namespaces prefix :defs (symbol suffix))
-                     {:name (if (= "" prefix) (symbol suffix) (symbol (str prefix) suffix))
+                     {:op :local
+                      :name (if (= "" prefix) (symbol suffix) (symbol (str prefix) suffix))
                       :ns prefix})))))

            (some? (ana/gets current-ns-info :uses sym))
@@ -211,7 +237,8 @@
            ;; not sure if correct fix
            ;; cljs.core/Object is used by parse-type so using that here
            (= 'Object sym)
-           '{:name cljs.core/Object
+           '{:op :var
+             :name cljs.core/Object
              :ns cljs.core}

            (ana/core-name? env sym)
@@ -227,6 +254,14 @@
                  (confirm env current-ns sym))
                (resolve-cljs-var current-ns sym)
                )))))))
+
+(defn shadow-resolve-var-checked
+  ([env sym]
+   {:post [(contains? % :op)]}
+   (shadow-resolve-var env sym nil))
+  ([env sym confirm]
+   {:post [(contains? % :op)]}
+   (shadow-resolve-var env sym confirm)))

 (defn infer-externs-dot
   [{:keys [form form-meta method field target-tag env prop tag] :as ast}
@@ -527,14 +562,14 @@
   [x]
   (if (core/symbol? x)
     (core/let [resolved (:name (cljs.analyzer/resolve-var &env x))
-               y     (core/cond-> resolved
-                       (= "js" (namespace resolved)) name)
-               segs  (string/split (core/str (string/replace (core/str y) "/" ".")) #"\.")
-               n     (count segs)
-               syms  (map
-                       #(vary-meta (symbol "js" (string/join "." %))
-                          assoc :cljs.analyzer/no-resolve true)
-                       (reverse (take n (iterate butlast segs))))
-               js    (string/join " && " (repeat n "(typeof ~{} !== 'undefined')"))]
+               y (core/cond-> resolved
+                   (= "js" (namespace resolved)) name)
+               segs (string/split (core/str (string/replace (core/str y) "/" ".")) #"\.")
+               n (count segs)
+               syms (map
+                      #(vary-meta (symbol "js" (string/join "." %))
+                         assoc :cljs.analyzer/no-resolve true)
+                      (reverse (take n (iterate butlast segs))))
+               js (string/join " && " (repeat n "(typeof ~{} !== 'undefined')"))]
       (bool-expr (concat (core/list 'js* js) syms)))
     `(some? ~x)))


update benchmark script

update benchmark script

--- bench/transit/bench.cljs
+++ bench/transit/bench.cljs
@@ -13,7 +13,7 @@
 ;; limitations under the License.

 (ns transit.test
-  (:require [transit.core :as t]
+  (:require [com.cognitect.transit-cljs :as t]
             [cljs.reader :as r]))

 (enable-console-print!)


Make kibit happy.

Make kibit happy.

--- src/open_company/util/sample_data.clj
+++ src/open_company/util/sample_data.clj
@@ -105,8 +105,8 @@
       (let [arg (first arguments)
             edn-file #".*\.edn$"
             filenames (if (re-matches edn-file arg)
-                        [arg]
-                        (filter #(re-matches edn-file %) (map #(.toString %) (file-seq (clojure.java.io/file arg)))))]
+                        [arg] ; they specified just 1 file
+                        (filter #(re-matches edn-file %) (map str (file-seq (clojure.java.io/file arg)))))] ; a dir
         ;; Import each file
         (doseq [filename filenames]
           (let [data (read-string (slurp filename))]


Fully unload namespaces. Commit to preserving :state var.

--- src/prod/clj/com/potetm/tire_iron.clj
+++ src/prod/clj/com/potetm/tire_iron.clj
@@ -90,30 +90,29 @@
            "  throw new Error(\"Cannot resolve symbol: " sym "\");\n"
            "}\n"))))

-(defn set-ti-state-from-sym-script [state-sym]
-  (let [state-sym (comp/munge state-sym)]
-    (when-not (str/blank? (str state-sym))
-      (str "if (" (object-path-exists? state-sym) ") {\n"
-           "  goog.tire_iron_state_ = " state-sym ";\n"
-           "} else {\n"
-           "  throw new Error(\"Cannot resolve :state symbol: " state-sym "\");\n"
-           "}\n"))))
-
-(defn set-sym-from-ti-state-script [state-sym]
-  (let [state-sym (comp/munge state-sym)]
-    (when-not (str/blank? (str state-sym))
-      (str "if (" (parts-exist? (butlast (object-path-parts state-sym))) ") {\n"
-           "  " state-sym " = goog.tire_iron_state_;\n"
-           "} else {\n"
-           "  throw new Error(\"Cannot resolve :state symbol: " state-sym "\");\n"
-           "}\n"))))
-
-(defn compile-unload-ns [ns]
+(defn compile-unload-ns [state-sym ns]
+  ;; We DO need to guarantee some location won't be cleared. Otherwise we might
+  ;; blow away and rebuild their REPL connection.
   (let [ns (comp/munge ns)
         loaded-libs (comp/munge 'cljs.core/*loaded-libs*)]
     (str "(function(){\n"
-         "var ns, ns_string, path, key, value;\n"
+         "var ns, ns_string, path, key, state_path_parts, on_state_path;\n"
          "ns_string = \"" ns "\";\n"
+         "state_path_parts = ["
+         (str/join ","
+                   (map #(str "\"" % "\"")
+                        (object-path-parts (comp/munge state-sym))))
+         "];\n"
+         "on_state_path = function(k) {\n"
+         "  var i, full_name;\n"
+         "  full_name = ns_string + '.' + k;\n"
+         "  for (i = 0; i < state_path_parts.length; i++) {\n"
+         "    if (state_path_parts[i] === full_name) {\n"
+         "      return true;"
+         "    }\n"
+         "  }\n"
+         "  return false;\n"
+         "}\n;"
          "path = goog.dependencies_.nameToPath[ns_string];\n"
          "goog.object.remove(goog.dependencies_.visited, path);\n"
          "goog.object.remove(goog.dependencies_.written, path);\n"
@@ -122,39 +121,17 @@
          "  ns = " ns ";\n"
          "  for (key in ns) {\n"
          "    if (!ns.hasOwnProperty(key)) { continue; }\n"
-         "    value = ns[key];"
-         ;; defmulti declares a defonce to hold its state. As noted below,
-         ;; we purposely set defonce'd members to null so they aren't redefined.
-         ;; Not redefining a multi causes defmethod failures on reload.
-         ;;
-         ;; Luckily, there is a handy `cljs.core/remove-all-methods` function to clear
-         ;; a multimethod's state. The trick then is to figure out which members
-         ;; are multimethods. The check below seems reliable.
-         "    if (typeof value !== 'undefined' && \n
-                         value !== null && \n
-                    typeof value.constructor !== 'undefined' && \n
-                           value.constructor !== null && \n
-                      value.constructor.cljs$lang$ctorStr === 'cljs.core/MultiFn') {\n"
-         "      cljs.core.remove_all_methods.call(null, value);\n"
+         "    if (!on_state_path(key)) {\n"
          "      delete ns[key];\n"
-         "    } else {\n"
-         ;; setting to null is critical to allow defonce to work as expected.
-         ;; defonce checks typeof var == "undefined"
-         ;; we need to allow certain vars to _not_ be redefined in order to
-         ;; maintain only one repl connection.
-         ;;
-         ;; I'm not certain, but it seemed like multiple connections usually
-         ;; resulted in stackoverflows in goog.require.
-         "      ns[key] = null;\n"
          "    }\n"
          "  }\n
          }\n"
          loaded-libs " = cljs.core.disj.call(null, " loaded-libs ", ns_string);\n"
          "})();")))

-(defn unload-nss-script [nss]
+(defn unload-nss-script [state-sym nss]
   (str/join "\n"
-            (map compile-unload-ns
+            (map (partial compile-unload-ns state-sym)
                  nss)))

 (defn load-nss-sync [nss]
@@ -195,11 +172,9 @@
     (eval-script repl-env
                  (str "(function() {\n"
                       (call-sym-script before)
-                      (set-ti-state-from-sym-script state)
-                      (unload-nss-script unload-nss)
+                      (unload-nss-script state unload-nss)
                       "var d = " (load-nss-html-async load-nss) ";\n"
                       "d.addCallback(function(ret) {\n"
-                      (set-sym-from-ti-state-script state)
                       (call-sym-script after)
                       "  });\n"
                       "})();"))))
@@ -210,10 +185,8 @@
   (-refresh [this {:keys [repl-env before after state unload-nss load-nss]}]
     (eval-script repl-env
                  (str (call-sym-script before)
-                      (set-ti-state-from-sym-script state)
-                      (unload-nss-script unload-nss)
+                      (unload-nss-script state unload-nss)
                       (load-nss-sync load-nss)
-                      (set-sym-from-ti-state-script state)
                       (call-sym-script after)))))

 (defn refresh* [{:keys [refresher
@@ -255,19 +228,6 @@
   (swap! tracker assoc ::track/load nil ::track/unload nil)
   (println :ok))

-(defn recover-state [repl-env analyzer-env repl-opts state]
-  (eval-form repl-env
-             analyzer-env
-             repl-opts
-             `(set! ~state (.-tire_iron_state_ js/goog))))
-
-(defn print-state [repl-env analyzer-env repl-opts]
-  (println
-    (eval-form repl-env
-               analyzer-env
-               repl-opts
-               `(.-tire_iron_state_ js/goog))))
-
 (defn maybe-quoted->symbol [symbol-or-list]
   (if (list? symbol-or-list)
     (second symbol-or-list)
@@ -304,18 +264,13 @@

    Refresh happens in the following order:
      1. :before is called
-     2. :state is copied to a private location on the client
-     3. refresh happens
-     4. :state is copied back to the original location
-     5. :after is called
+     2. refresh happens
+     3. :after is called

    Returns a map of the following fns for use in the cljs repl.

    'refresh: refreshes :source-dirs. Accepts the same args as `special-fns`.
-             Any passed args will override the values passed to `special-fns`.
-   'print-tis: prints the last state tire iron stored during refresh
-   'recover-tis: replaces :state var with the last state tire iron stored during refresh.
-                 Accepts an optional symbol pointing to an arbitrary target var."
+             Any passed args will override the values passed to `special-fns`."
   [& {:keys [source-dirs
              before
              after
@@ -364,20 +319,6 @@
                              :analyzer-env analyzer-env
                              :repl-opts repl-opts}))))

-     'print-tis
-     (wrap (fn [repl-env analyzer-env _ repl-opts]
-             (print-state repl-env
-                          analyzer-env
-                          repl-opts)))
-
-     'recover-tis
-     (wrap (fn [repl-env analyzer-env [_ state-sym] repl-opts]
-             (recover-state repl-env
-                            analyzer-env
-                            repl-opts
-                            (or state-sym
-                                state))))
-
      'print-disabled
      (wrap (fn [& _]
              (prn :disabled-unload @disable-unload)


Provide ns in the dotted form

Provide ns in the dotted form

--- lambdalf-lib/src/main/clojure/alfresco.clj
+++ lambdalf-lib/src/main/clojure/alfresco.clj
@@ -15,7 +15,13 @@
            :prefix "ci-"
            :methods [[setNamespaces [java.util.List] void]])

+(defn load-ns
+  "loads a given ns provided its dotted String representation"
+  [^String ns]
+  (let [s (.replaceAll ns "\\." "/")]
+    (load (str "/" s))))
+
 (defn ci-setNamespaces
   "Bootstraps the given namespaces"
   [this ns-list]
-  (apply load ns-list))
+  (apply load-ns ns-list))


CM - select by attribute rather than id in objectives-create template

--- src/d_cent/responses.clj
+++ src/d_cent/responses.clj
@@ -1,19 +1,19 @@
-(ns d-cent.responses
+(ns d-cent.responses
   (:require [net.cgrand.enlive-html :as html]
             [d-cent.translation :refer [translation-config]]))

 ;BASE TEMPLATE
-(html/deftemplate base "templates/base.html"
+(html/deftemplate base "templates/base.html"
                   [{:keys [translation
-                           locale
+                           locale
                            doc-title
                            doc-description
                            global-navigation
                            content]}]
                   [:html] (html/set-attr :lang locale)
                   ; TODO find a way to select description without an ID
-                  ; [:meta (html/attr= :name "description")] (html/set-attr :content "Some text")
+                  ; [:head (html/attr= :name "description")] (html/set-attr :content "some text")
                   [:title] (html/content doc-title)
                   [:#clj-description] (html/set-attr :content doc-description)
                   [:#clj-global-navigation] (html/content global-navigation)
@@ -29,7 +29,7 @@
                                                                                [:#clj-user-profile-link] (html/content (translation :navigation-global/profile-text))
                                                                                [:#clj-user-profile-link] (html/set-attr :title (translation :navigation-global/profile-title)))

-(html/defsnippet global-navigation-signed-out "templates/navigation-global-signed-out.html" [[:.global-navigation]]
+(html/defsnippet global-navigation-signed-out "templates/navigation-global-signed-out.html" [[:.global-navigation]]
                                                                                [{:keys [translation]}]
                                                                                [:#clj-sign-in-link] (html/content (translation :navigation-global/sign-in-text))
                                                                                [:#clj-sign-in-link] (html/set-attr :title (translation :navigation-global/sign-in-title)))
@@ -50,15 +50,14 @@
 (html/defsnippet objective-create-page "templates/objectives-create.html" [[:#clj-objective-create]]
                                                                           [{:keys [translation]}]
                                                                           [:h1] (html/content (translation :objective-create/page-title))
-                                                                          ;TODO look at attr= to remove classes here
-                                                                          [:.clj-obj-title-label] (html/content (translation :objective-create/title-label))
-                                                                          [:.clj-obj-title-title] (html/set-attr :title (translation :objective-create/title-title))
-                                                                          [:.clj-obj-goals-label] (html/content (translation :objective-create/goals-label))
-                                                                          [:.clj-obj-goals-title] (html/set-attr :title (translation :objective-create/goals-title))
-                                                                          [:.clj-obj-description-label] (html/content (translation :objective-create/description-label))
-                                                                          [:.clj-obj-description-title] (html/set-attr :title (translation :objective-create/description-title))
-                                                                          [:.clj-obj-end-date-label] (html/content (translation :objective-create/end-date-label))
-                                                                          [:.clj-obj-end-date-title] (html/set-attr :title (translation :objective-create/end-date-title))
+                                                                          [(html/attr= :for "objective-title")] (html/content (translation :objective-create/title-label))
+                                                                          [(html/attr= :name "title")] (html/set-attr :title (translation :objective-create/title-title))
+                                                                          [(html/attr= :for "objective-goals")] (html/content (translation :objective-create/goals-label))
+                                                                          [(html/attr= :name "goals")] (html/set-attr :title (translation :objective-create/goals-title))
+                                                                          [(html/attr= :for "objective-description")] (html/content (translation :objective-create/description-label))
+                                                                          [(html/attr= :name "description")] (html/set-attr :title (translation :objective-create/description-title))
+                                                                          [(html/attr= :for "objective-end-date")] (html/content (translation :objective-create/end-date-label))
+                                                                          [(html/attr= :name "end-date")] (html/set-attr :title (translation :objective-create/end-date-title))
                                                                           [:.button] (html/content (translation :objective-create/submit)))

 (html/defsnippet objectives-new-link-page "templates/objectives-new-link.html" [[:#clj-objectives-new-link]]
@@ -82,8 +81,8 @@
 (html/defsnippet users-email "templates/users-email.html" [[:#clj-users-email]]
                                                            [{:keys [translation]}]
                                                            [:h1] (html/content (translation :users-email/page-title))
-                                                           [:.clj-users-email-label] (html/content (translation :users-email/email-label))
-                                                           [:.clj-users-email-title] (html/set-attr :title (translation :users-email/email-title))
+                                                           [(html/attr= :for "email-address")] (html/content (translation :users-email/email-label))
+                                                           [(html/attr= :name "email-address")] (html/set-attr :title (translation :users-email/email-title))
                                                            [:button] (html/content (translation :users-email/button)))

 (defn render-template [template & args]
@@ -108,4 +107,3 @@
         (if-let [status-code (:status-code args)]
           (simple-response page status-code)
           (simple-response page))))
-


A null commit to see if we can get TravisCI working

--- src/dragonmark/core.cljx
+++ src/dragonmark/core.cljx
@@ -454,7 +454,6 @@
         guid-closed (atom (fn [x]))
         send-message (atom (fn [guid message ack-chan]))

-
         write-func
         (fn [item]
           (cond


Fix alias

Fix alias

--- src/expound/printer.cljc
+++ src/expound/printer.cljc
@@ -6,7 +6,7 @@
             [clojure.set :as set]
             [expound.util :as util]
             [expound.ansi :as ansi]
-            #?(:clj [clojure.main :as clojure.main]))
+            #?(:clj [clojure.main :as main]))
   (:refer-clojure :exclude [format]))

 (def indent-level 2)
@@ -140,8 +140,8 @@
            (if (re-matches #"^fn__\d+\@.*$" f-n)
              anon-fn-str
              (str
-              (clojure.main/demunge ns-n) "/"
-              (clojure.main/demunge f-n))))
+              (main/demunge ns-n) "/"
+              (main/demunge f-n))))
          :cljs
          (let [fn-parts (string/split (second (re-find
                                                #"object\[([^\( \]]+).*(\n|\])?"


pick-n-in-nn working

pick-n-in-nn working

--- src/unspun/screens/number_needed.cljs
+++ src/unspun/screens/number_needed.cljs
@@ -28,22 +28,18 @@
     ))

 (defn picked-before? [a-set a-choice]
-  (a-choice a-set))
+  (a-set a-choice))

-(defn pick-one [nn picked n]
-  (loop [picked-set picked]
-    [selection (inc (rand-int (dec nn)))]
-    (if (picked-before? picked-set selection)
-      (recur )
-      )))
-
-(defn highlighted
-  "Pick `anyway-count -1` icons at random from nn to highlight"
-  ([scenar nn]
-   (let [anyway-count (anyway (:relative-risk scenar) (:baseline-risk scenar))]
-     (reduce (partial pick-one nn) #{} (range 0 anyway-count))
-     anyway-count)))
-
+(defn pick-n-in-nn [nn n]
+  (loop [picked-set #{}
+         n-left n]
+    (if (zero? n-left)
+      picked-set
+      (let
+        [selection (inc (rand-int (dec nn)))]
+        (if (picked-before? picked-set selection)
+          (recur picked-set n-left)
+          (recur (conj picked-set selection) (dec n-left)))))))

 (rum/defc page < rum/reactive []
   (let [scenar ((rum/react stories) (rum/react story-index))


RR: generate styles for mouse hover/click states

--- src/hatti/map/utils.cljs
+++ src/hatti/map/utils.cljs
@@ -288,41 +288,89 @@

 (defn add-mapboxgl-layer
   "Add map layer."
-  [map]
-  (let [layer (clj->js {:id "points"
-                        :type "circle"
+  [map layer-id layer-type]
+  (let [layer (clj->js {:id layer-id
+                        :type layer-type
                         :source "xform_id_string"
-                        :source-layer "oloitoktok_bike_trip_geom"
-                        :paint {:circle-radius 6 :circle-color "red"}})]
+                        :source-layer "oloitoktok_bike_trip_geom"})]
     (.addLayer map layer)))
+
+(defn generate-stops
+  [selected-id selected-color]
+  [[0 "#f30"]
+   [selected-id "#ad2300"]])
+
+(defn get-styles
+  [& [selected-id]]
+  {:point {:normal [["circle-color" (clj->js
+                                     {:property "id"
+                                      :type "categorical"
+                                      :stops [[0 "#f30"]]})]
+                    ["circle-radius" 6]]
+           :hover [["circle-color" (clj->js
+                                    {:property "id"
+                                     :type "categorical"
+                                     :stops (generate-stops
+                                             selected-id "#631400")})]]
+           :clicked ["circle-color" (clj->js
+                                     {:property "id"
+                                      :type "categorical"
+                                      :stops (generate-stops
+                                              selected-id "#ad2300")})]}})
+
+(defn get-style-properties
+  [layer-type style-type & [selected-id]]
+  (-> (get-styles selected-id) layer-type style-type))
+
+(defn set-mapboxgl-paint-property
+  "Sets maps paint properties given layer-id and list of properties to set.
+  properties should be a list of properties that contains the propery name
+  and value in a vector. e.g. [[property1 value1] [property2 value2]"
+  [map layer-id properties]
+  (doseq [[p v] properties] (.setPaintProperty map layer-id p v)))

 (defn register-mapboxgl-mouse-events
   "Register map mouse events."
   [map event-chan]
   (.on map "mousemove"
        (fn [e]
-         (let [features
+         (let [layer-id "points"
+               features
                (.queryRenderedFeatures
-                map (.-point e) (clj->js {:layers ["points"]}))]
+                map (.-point e) (clj->js {:layers [layer-id]}))
+               no-of-features (.-length features)]
            (set! (.-cursor (.-style (.getCanvas map)))
-                 (if (pos? (.-length features)) "pointer" "")))))
-
+                 (if (pos? (.-length features)) "pointer" ""))
+           (if (= no-of-features 1)
+             (set-mapboxgl-paint-property
+              map layer-id (get-style-properties :point :hover
+                                                 (-> (first features)
+                                                     (aget "properties")
+                                                     (aget "id"))))))))
   (.on map "click"
        (fn [e]
-         (let [features
+         (let [layer-id "points"
+               features
                (.queryRenderedFeatures
-                map (.-point e) (clj->js {:layers ["points"]}))
+                map (.-point e) (clj->js {:layers [layer-id]}))
                no-of-features (.-length features)]
            (when (pos? no-of-features)
              (when (= no-of-features 1)
                (put! event-chan {:mapped-submission-to-id
                                  (-> (first features)
                                      (aget "properties")
-                                     (aget "id"))})))))))
+                                     (aget "id"))})
+               (set-mapboxgl-paint-property
+                map layer-id (get-style-properties :point :selected
+                                                   (-> (first features)
+                                                       (aget "properties")
+                                                       (aget "id"))))))))))

 (defn map-on-load
   "Functions that are called after map is loaded in DOM."
   [map event-chan]
   (add-mapboxgl-source map)
-  (add-mapboxgl-layer map)
-  (register-mapboxgl-mouse-events map event-chan))
+  (add-mapboxgl-layer map "points" "circle")
+  (register-mapboxgl-mouse-events map event-chan)
+  (set-mapboxgl-paint-property
+   map "points" (get-style-properties :point :normal)))


RR: get view-by data from map-page key

RR: get view-by data from map-page key

--- src/hatti/views/map.cljs
+++ src/hatti/views/map.cljs
@@ -32,8 +32,9 @@
              markers (vals (get-id-marker-map))]
          (when view-by
            (let [{:keys [full-name] :as field} (:field view-by)
-                 ids (map #(get % _id) (:data @app-state))
-                 raw-answers (map #(get % full-name) (:data @app-state))
+                 ids (map #(get % _id) (-> @app-state :map-page :data))
+                 raw-answers (map #(get % full-name)
+                                  (-> @app-state :map-page :data))
                  vb-info (vb/viewby-info field raw-answers ids)]
              (om/update! app-state [:map-page :view-by] vb-info)
              (vb/view-by! vb-info markers)))


Updated memory settings.

Updated memory settings.

--- src/clj/forma/hadoop/cluster.clj
+++ src/clj/forma/hadoop/cluster.clj
@@ -82,11 +82,16 @@
 (defn forma-cluster
   "Generates a FORMA cluster with the supplied number of nodes. We
   pick that reduce capacity based on the recommended 1.2 times the
-  number of tasks times number of nodes."
+  number of tasks times number of nodes.
+
+RECOMMENDED SETTINGS:
+mappers 4, reducers 3 for c1.large
+mappers 35, reducers 27 for m2.4xlarge
+mappers 22, reducers 16 for cc1.4xlarge"
   [nodecount]
   (let [lib-path (str fw-path "/usr/lib")
-        mappers 35
-        reducers 27]
+        mappers 22
+        reducers 16]
     (cluster-spec :private
                   {
                    :jobtracker (node-group [:jobtracker :namenode])


remove core

remove core

--- src/clj/gen_class_issue/core.clj
+++ src/clj/gen_class_issue/core.clj
@@ -1,6 +0,0 @@
-(ns gen-class-issue.core)
-
-(defn foo
-  "I don't do a whole lot."
-  [x]
-  (println x "Hello, World!"))


Add authorization to specific routes

Add authorization to specific routes

--- src/clj/mdr2/routes/services.clj
+++ src/clj/mdr2/routes/services.clj
@@ -8,7 +8,7 @@
     [reitit.ring.middleware.muuntaja :as muuntaja]
     [reitit.ring.middleware.multipart :as multipart]
     [reitit.ring.middleware.parameters :as parameters]
-    [mdr2.middleware :refer [wrap-restricted]]
+    [mdr2.middleware :refer [wrap-restricted wrap-authorized]]
     [mdr2.middleware.formats :as formats]
     [ring.util.http-response :refer :all]
     [clojure.string :refer [blank?]]
@@ -99,8 +99,9 @@
                               (map prod/remove-null-values)
                               ok)))}
       :post {:summary "Create a production"
-             :middleware [wrap-restricted]
-             :swagger {:security [{:apiAuth []}]}
+             :middleware [wrap-restricted wrap-authorized]
+             :swagger {:security [{:apiAuth []}]}
+             :authorized #{:it}
              :parameters {:body prod.spec/production}
              :handler (fn [{{p :body} :parameters}]
                         (try
@@ -122,8 +123,9 @@

       :delete {:summary "Delete a production"
                :description "Mark a production as deleted"
-               :middleware [wrap-restricted]
+               :middleware [wrap-restricted wrap-authorized]
                :swagger {:security [{:apiAuth []}]}
+               :authorized #{:it}
                :parameters {:path {:id int?}}
                :handler (fn [{{{:keys [id]} :path} :parameters}]
                           (if-let [p (prod/get-production id)]
@@ -135,8 +137,9 @@
                             (not-found)))}

       :patch {:summary "Patch a production, e.g. update the library_signature"
-              :middleware [wrap-restricted]
+              :middleware [wrap-restricted wrap-authorized]
               :swagger {:security [{:apiAuth []}]}
+              :authorized #{:catalog :it}
               :parameters {:path {:id int?}
                            :body {:library_signature ::prod.spec/library_signature}}
               :handler (fn [{{{:keys [id]} :path {:keys [library_signature]} :body} :parameters}]
@@ -152,8 +155,9 @@

     ["/:id/repair"
      {:post {:summary "Repair a production"
-             :middleware [wrap-restricted]
-             :swagger {:security [{:apiAuth []}]}
+             :middleware [wrap-restricted wrap-authorized]
+             :swagger {:security [{:apiAuth []}]}
+             :authorized #{:admin :studio :it}
              :parameters {:path {:id int?}}
              :handler (fn [{{{:keys [id]} :path} :parameters}]
                         (let [p (prod/get-production id)]
@@ -179,8 +183,9 @@
                          (not-found)))}

       :post {:summary "Upload the DTBook XML structure for a production"
-             :middleware [wrap-restricted]
-             :swagger {:security [{:apiAuth []}]}
+             :middleware [wrap-restricted wrap-authorized]
+             :swagger {:security [{:apiAuth []}]}
+             :authorized #{:etext :it}
              :parameters {:path {:id int?}
                           :multipart {:file multipart/temp-file-part}}
              :handler (fn [{{{:keys [file]} :multipart {:keys [id]} :path} :parameters}]
@@ -275,8 +280,9 @@

     ["/upload"
      {:post {:summary "Upload XML from a Vubis export"
-             :middleware [wrap-restricted]
-             :swagger {:security [{:apiAuth []}]}
+             :middleware [wrap-restricted wrap-authorized]
+             :swagger {:security [{:apiAuth []}]}
+             :authorized #{:etext :it}
              :parameters {:multipart {:file multipart/temp-file-part}}
              :handler (fn [{{{:keys [file]} :multipart} :parameters}]
                         (let [tempfile (:tempfile file)


refine logic for calculated balance sheet  values

--- src/clj_money/models/reports.clj
+++ src/clj_money/models/reports.clj
@@ -172,30 +172,41 @@
                       :value (+ (:equity summary) (:liability summary))
                       :style :summary}])))

+(defn- append-equity-pseudo-account
+  [account-groups caption value]
+  (update-in account-groups
+               [2]
+               (fn [entry]
+                 (-> entry
+                     (update-in [:accounts] #(conj %
+                                                   {:name caption
+                                                    :balance value
+                                                    :children-balance 0}))
+                     (update-in [:value] #(+ % value))))))
+
 (defn- append-retained-earnings
   [account-groups]
   (let [summary (->> account-groups
                      (map (juxt :type :value))
                      (into {}))
-        retained (- (:income summary) (:expense summary))]
-    (update-in account-groups
-               [2]
-               (fn [entry]
-                 (-> entry
-                     (update-in [:accounts] #(conj %
-                                                   {:name "Retained Earnings"
-                                                    :balance retained
-                                                    :children-balance 0}))
-                     (update-in [:value] #(+ % retained)))))))
+        value (- (:income summary) (:expense summary))
+        caption (if (< value 0)
+                  "Retained Losses"
+                  "Retained Earnings")]
+    (append-equity-pseudo-account account-groups
+                                  caption
+                                  value)))

 (defn- append-unrealized-gains
   [account-groups storage-spec entity-id as-of]
   account-groups
-  #_(let [unrealized-gains (lots/unrealized-gains storage-spec entity-id as-of)
-        unrealized-caption (if (< unrealized-gains 0)
-                             "Unrealized Losses"
-                             "Unrealized Gains")]
-    account-groups))
+  (let [value (lots/unrealized-gains storage-spec entity-id as-of)
+        caption (if (< value 0)
+                  "Unrealized Losses"
+                  "Unrealized Gains")]
+    (append-equity-pseudo-account account-groups
+                                  caption
+                                  value)))

 (defn- append-calculated-values
   [storage-spec entity-id as-of account-groups]


Add a link to the locale detection idea

Add a link to the locale detection idea

--- src/cljs/hyphen_keeper/i18n.cljs
+++ src/cljs/hyphen_keeper/i18n.cljs
@@ -1,5 +1,7 @@
 (ns hyphen-keeper.i18n)

+;; the idea for this comes from
+;; http://www.mattzabriskie.com/blog/detecting-locale
 (defn lang-attribute []
   (.. js/document -documentElement (getAttribute "lang")))


Add app state for trello card

Add app state for trello card

--- src/cljs/new_website/routes.cljs
+++ src/cljs/new_website/routes.cljs
@@ -13,7 +13,8 @@

 (defonce app-state
   (atom
-   {:navigation {:view :welcome}}))
+   {:navigation {:view :welcome}
+    :trello-card {:name "" :description ""}}))

 ;; -------------------------
 ;; Routes


Clean up

Clean up

--- src/cljs/whatishistory/core.cljs
+++ src/cljs/whatishistory/core.cljs
@@ -63,8 +63,6 @@
         b (get @app-atom :email-confirm)
         email-provided (not (nil? a))
         email-confirmed (= a b)]
-    (js/console.log "provided: " email-provided)
-    (js/console.log "confirmed: " email-confirmed)
     (if-not (or (not email-provided) (not email-confirmed))
       true
       (condp = do-alert


Deprecate neko.application namespace

Deprecate neko.application namespace

--- src/clojure/neko/application.clj
+++ src/clojure/neko/application.clj
@@ -10,11 +10,10 @@
 ; this software.

 (ns neko.application
-  "Contains tools to create and manipulate Application instances."
-  (:require neko.context neko.init)
-  (:use [neko.-utils :only [simple-name]]
-        [neko.resource :only [package-name]]
-        [neko.threading :only [init-threading]])
+  "Contains tools to create and manipulate Application instances. This
+  namespace is deprecated and exists only for backward compatibility
+  purposes."
+  (:require neko.init)
   (:import android.app.Application
            android.content.Context))

@@ -24,18 +23,8 @@
   Application class from Java. Default `:on-create` moved to
   `init-application`.")))

-(def ^{:doc "Represents if initialization was already performed."
-       :private true}
-  initialized? (atom false))
-
 (defn init-application
-  "Performs necessary preparations for Neko and REPL development."
-  [context & {:keys [extends prefix on-create nrepl-port]
-              :or {extends android.app.Application
-                   prefix (str (simple-name name) "-")}}]
-  (when-not @initialized?
-    (alter-var-root #'neko.context/context (constantly context))
-    (alter-var-root #'package-name (constantly (.getPackageName context)))
-    (neko.init/init context :port (or nrepl-port 9999))
-    (init-threading)
-    (reset! initialized? true)))
+  "DEPRECATED: Performs necessary preparations for Neko and REPL
+  development. You should call `neko.init/init` instead."
+  [context]
+  (neko.init/init context))


Don't blacklist import

Don't blacklist import

--- src/clojure/nightmod/sandbox.clj
+++ src/clojure/nightmod/sandbox.clj
@@ -16,8 +16,7 @@
      *read-eval* set! eval catch
      addMethod forName
      load load-file load-string load-reader
-     ns-resolve ns-publics ns-unmap ns-map ns-interns the-ns in-ns
-     require import
+     ns-resolve ns-publics ns-unmap ns-map ns-interns the-ns in-ns require
      System/out System/in System/err
      defscreen* defgame* defgame set-screen! setScreen set-screen-wrapper!
      app! app on-gl


Fix pulse table rendering due to dividing BigDecimals

Resolves #1714

--- src/metabase/pulse.clj
+++ src/metabase/pulse.clj
@@ -242,7 +242,7 @@
                                                :max-height       :10px
                                                :height           :10px
                                                :border-radius    :2px
-                                               :width            (str (float (* 100 (/ (bar-column row) max-value))) "%")})}
+                                               :width            (str (float (* 100 (/ (double (bar-column row)) max-value))) "%")})} ; cast to double to avoid "Non-terminating decimal expansion" errors
                           " "]])])
                    rows)]]))


Fix menu select problem

Fix menu select problem

--- src-cljs/frontend/components/app.cljs
+++ src-cljs/frontend/components/app.cljs
@@ -54,13 +54,13 @@
        :hovered-tool-line nil})
     om/IRender
     (render [_]
-      (let [{:keys [cast!]} (om/get-shared owner)
-            show-grid? (get-in app state/show-grid-path)
-            night-mode? (get-in app state/night-mode-path)
-            hovered-tool? (:hovered-tool (om/get-state owner))
+      (let [{:keys [cast!]}      (om/get-shared owner)
+            show-grid?           (get-in app state/show-grid-path)
+            night-mode?          (get-in app state/night-mode-path)
+            hovered-tool?        (:hovered-tool (om/get-state owner))
             hovered-tool-select? (:hovered-tool-select (om/get-state owner))
-            hovered-tool-shape? (:hovered-tool-shape (om/get-state owner))
-            hovered-tool-line? (:hovered-tool-line (om/get-state owner))]
+            hovered-tool-shape?  (:hovered-tool-shape (om/get-state owner))
+            hovered-tool-line?   (:hovered-tool-line (om/get-state owner))]
         (html [:div#app {:class (str/join " " (concat (when show-grid? ["show-grid"])
                                                       (when night-mode? ["night-mode"])))}
                [:aside.app-aside {:class (when night-mode? ["night-mode"])}
@@ -77,21 +77,21 @@
                      [:object
                       (common/icon :tool-text)
                       [:span "Text"]]]
-                    [:button {:on-mouse-up #(cast! :tool-selected-select [:select])
+                    [:button {:on-mouse-up #(cast! :tool-selected [:select])
                               :on-mouse-enter #(om/set-state! owner :hovered-tool-select true)
                               :on-mouse-leave #(om/set-state! owner :hovered-tool-select false)
                               :class (when hovered-tool-select? "hover")}
                      [:object
                       (common/icon :cursor)
                       [:span "Select"]]]
-                    [:button {:on-mouse-up #(cast! :tool-selected-shape [:shape])
+                    [:button {:on-mouse-up #(cast! :tool-selected [:shape])
                               :on-mouse-enter #(om/set-state! owner :hovered-tool-shape true)
                               :on-mouse-leave #(om/set-state! owner :hovered-tool-shape false)
                               :class (when hovered-tool-shape? "hover")}
                      [:object
                       (common/icon :tool-square)
                       [:span "Shape"]]]
-                    [:button {:on-mouse-up #(cast! :tool-selected-line [:line])
+                    [:button {:on-mouse-up #(cast! :tool-selected [:line])
                               :on-mouse-enter #(om/set-state! owner :hovered-tool-line true)
                               :on-mouse-leave #(om/set-state! owner :hovered-tool-line false)
                               :class (when hovered-tool-line? "hover")}


dependencies

dependencies


clojure.core/format is a great fit here

clojure.core/format is a great fit here

--- metrics-clojure-core/src/metrics/utils.clj
+++ metrics-clojure-core/src/metrics/utils.clj
@@ -23,9 +23,10 @@

 (defn all-metrics []
   (letfn [(parse-name [^MetricName metric-name]
-            (str (.getGroup metric-name)
-                 "." (.getType metric-name)
-                 "." (.getName metric-name)))
+            (format "%s.%s.%s"
+                    (.getGroup metric-name)
+                    (.getType metric-name)
+                    (.getName metric-name)))
           (parse-entry [[metric-name metric]]
             [(parse-name metric-name)
              metric])]


get entities back out of datomic during tests

--- test/navigator_test.clj
+++ test/navigator_test.clj
@@ -15,40 +15,44 @@
                          [{:db/id (d/tempid :db.part/user)
                            :comp/id-sk "i am a shared key"
                            :comp/name "COMP there it is"}]))))
-  (testing "create-competency"
-    (is (n-tl/ensure-tx (navigator/tx-entity
-                         (:db-conn nt-config/system)
-                         {:db/id (d/tempid :db.part/user)
-                          :comp/name "I will keep typing"
-                          :comp/version "v1"
-                          :comp/status :comp.status/active
-                          :comp/id-sk "yeep"}
-                         :comp))))
-  (testing "create duplicate competency"
-    (is (n-tl/should-throw @(navigator/tx-entity
-                             (:db-conn nt-config/system)
-                             {:db/id (d/tempid :db.part/user)
-                              :comp/name "I will keep typing"
-                              :comp/version "v1"
-                              :comp/status :comp.status/active
-                              :comp/id-sk "jeep"})))))
+  (let [comp {:comp/name "I will keep typing"
+              :comp/version "v1"
+              :comp/status :comp.status/active
+              :comp/id-sk "yeep"}]
+    (testing "create competency"
+      (is (n-tl/ensure-tx (navigator/tx-entity
+                           (:db-conn nt-config/system)
+                           (merge {:db/id (d/tempid :db.part/user)}
+                                  comp)
+                           :comp))))
+    (testing "get comp"
+      (is (= (sort comp)
+             (sort (into {} (navigator/get-competency (:db-conn nt-config/system) "yeep"))))))
+    (testing "create duplicate competency"
+      (is (n-tl/should-throw @(navigator/tx-entity
+                               (:db-conn nt-config/system)
+                               (merge {:db/id (d/tempid :db.part/user)}
+                                      (assoc comp :comp/id-sk "jeep"))))))))

 (deftest update-comps
-  (is (n-tl/ensure-tx (navigator/tx-entity
-                       (:db-conn nt-config/system)
-                       {:db/id (d/tempid :db.part/user)
-                        :comp/name "can I update?"
-                        :comp/version "v1"
-                        :comp/status :comp.status/active
-                        :comp/id-sk "yeep"}
-                       :comp)))
-  (is (n-tl/ensure-tx (navigator/tx-update-entity
-                       (:db-conn nt-config/system)
-                       {:comp/name "can I update?"
-                        :comp/version "v1"
-                        :comp/status :comp.status/active
-                        :db/id [:comp/id-sk "yeep"]}
-                       :comp))))
+  (let [comp {:comp/name "can I update?"
+              :comp/version "v1"
+              :comp/status :comp.status/active
+              :comp/id-sk "yeep"}
+        comp-archived (assoc comp :comp/status :comp.status/archived)]
+    (testing "update competency"
+      (is (n-tl/ensure-tx (navigator/tx-entity
+                           (:db-conn nt-config/system)
+                           (merge {:db/id (d/tempid :db.part/user)}
+                                  comp)
+                           :comp)))
+      (is (n-tl/ensure-tx (navigator/tx-update-entity
+                           (:db-conn nt-config/system)
+                           (merge {:db/id [:comp/id-sk "yeep"]}
+                                  comp-archived)
+                           :comp)))
+      (is (= (sort comp-archived)
+             (sort (into {} (navigator/get-competency (:db-conn nt-config/system) "yeep"))))))))

 (comment
   (map #(keys (deref %))


Add log level to server output.

Add log level to server output.

--- src/oc/storage/app.clj
+++ src/oc/storage/app.clj
@@ -61,6 +61,7 @@
     "AWS SNS notification topic ARN: " c/aws-sns-storage-topic-arn "\n"
     "Hot-reload: " c/hot-reload "\n"
     "Trace: " c/liberator-trace "\n"
+    "Log level: " c/log-level "\n"
     "Sentry: " c/dsn "\n\n"
     (when c/intro? "Ready to serve...\n"))))


no need to test puppet its already test under workflows

--- test/celestial/integration/puppet.clj
+++ test/celestial/integration/puppet.clj
@@ -1,27 +0,0 @@
-(ns celestial.integration.puppet
-  "Requires both kvm redis and a celetial instance to reply to puppet ext queries"
-  (:require
-    [celestial.persistency.systems :as s]
-    [celestial.persistency.types :as t]
-    [celestial.fixtures.core :refer (with-defaults) :as f]
-    [celestial.fixtures.populate :refer (add-users)]
-    [celestial.fixtures.data :as d]
-    [celestial.workflows :refer (reload provision destroy)]
-    [celestial.redis :refer (clear-all)]
-    [celestial.config :refer (path)])
-  (:use midje.sweet))
-
-(defn run-cycle [spec type]
-  (clear-all)
-  (add-users)
-  (t/add-type type)
-  (let [id (s/add-system spec)]
-    (try
-      (reload (assoc spec :system-id id))
-      (provision type (s/get-system id))
-      (finally
-        (destroy (assoc (s/get-system id) :system-id id))))))
-
-(with-defaults
-  (fact "provisioning a kvm instance" :integration :puppet :kvm
-        (run-cycle d/redis-kvm-spec d/redis-type)))


Use of deleted is optional

Use of deleted is optional

--- org-mode/src/com/gfredericks/org_sync.clj
+++ org-mode/src/com/gfredericks/org_sync.clj
@@ -63,11 +63,15 @@
     new-file))

 (defn merge
-  "First arg is a map of :live, :archive, :deleted, each being
-  a parsed org file.
+  "First arg is a map of :live, :archive, and optionally :deleted,
+  each being a parsed org file.

   Returns an updated version of the first arg, but where the values
   can be nil if the contents haven't changed.
+
+  If the :deleted key is present, then entries in :live that are
+  missing from new-entries will be moved to deleted, otherwise they
+  are maintained in :live.

   new-entries is a list of org entries, and opts is a map
   containing:
@@ -121,7 +125,9 @@
                                                         (filter #(< 1 (val %)))
                                                         (first))})))
     (let [[retained-entries new-deleted-entries]
-          ((juxt filter remove) (comp new-entries-by-id id-fn) all-entries)
+          (if deleted
+            ((juxt filter remove) (comp new-entries-by-id id-fn) all-entries)
+            [all-entries []])

           retained-entries-by-id (->> retained-entries
                                       (map (juxt id-fn identity))
@@ -143,12 +149,15 @@
                                          (filter archive?)
                                          (sort-by sort-key)
                                          (wrap-in-archive-file-prelude time-zone category))]
-      {:live    (nil-if-equivalent new-live-file-contents live)
-       :archive (nil-if-equivalent new-archive-file-contents archive)
-       :deleted (when (seq new-deleted-entries)
-                  (wrap-in-archive-file-prelude time-zone category
-                                                (concat (::org/sections deleted)
-                                                        new-deleted-entries)))})))
+      (cond->
+          {:live    (nil-if-equivalent new-live-file-contents live)
+           :archive (nil-if-equivalent new-archive-file-contents archive)}
+        deleted
+        (assoc :deleted
+                 (when (seq new-deleted-entries)
+                   (wrap-in-archive-file-prelude time-zone category
+                                                 (concat (::org/sections deleted)
+                                                         new-deleted-entries))))))))

 (defmacro ^:private with-atomic-write
   [[binding filename] & body]
@@ -166,9 +175,10 @@
                      (log/info "Writing to %s" f)
                      (with-atomic-write [w f]
                        (org/write-file w content)))
-        {:keys [live archive deleted]} (merge {:live    (read-file live-file)
-                                               :archive (read-file archive-file)
-                                               :deleted (read-file deleted-file)}
+        {:keys [live archive deleted]} (merge (cond-> {:live    (read-file live-file)
+                                                       :archive (read-file archive-file)}
+                                                deleted-file
+                                                (assoc :deleted (read-file deleted-file)))
                                               new-entries merge-opts)]
     (when live (write-file live-file live))
     (when archive (write-file archive-file archive))


Replace nanoTime id with a sequential number generator

--- src/photon/streams.clj
+++ src/photon/streams.clj
@@ -282,6 +282,8 @@
        true)
      false)))

+(def order-id-nano (atom 0))
+
 (defn as-process-event! [{:keys [stats db global-channel] :as stream}
                          ev]
   ;; Think about the order of store+send to taps
@@ -292,7 +294,8 @@
         new-msg (assoc! msg :event-time new-timestamp)
         new-msg (assoc! new-msg :order-id
                         (+ (* 1000 new-timestamp)
-                           (rem (System/nanoTime) 1000)))
+                           (swap! order-id-nano #(if (< % 999) (inc %) 0))
+                           #_(rem (System/nanoTime) 1000)))
         new-msg (persistent! new-msg)]
     (swap! stats update :incoming inc)
     (update-streams! stream (:stream-name new-msg))


Allow send messages over GET requests.

Allow send messages over GET requests.

That will enable cross domain request,
and the ability to upgrade to server-sent-events
or websocket connections.

--- src/postal/client.cljs
+++ src/postal/client.cljs
@@ -2,6 +2,7 @@
   (:require [cognitect.transit :as t]
             [promesa.core :as p]
             [cats.core :as m]
+            [goog.crypt.base64 :as b64]
             [httpurr.client :as http]
             [httpurr.status :as http-status]
             [httpurr.client.xhr :as xhr]))
@@ -52,20 +53,23 @@
         (p/resolved message)))
     (p/rejected (ex-info "Unexpected" response))))

+(defn- prepare-request
+  [client data]
+  (let [req {:headers (merge +default-headers+ (:headers client))
+             :method (:method client)
+             :url (:url client)}]
+    (if (= :method :get)
+      (merge req {:query-string (str "d=" (b64/encodeString data true))})
+      (merge req {:body data}))))
+
 (defn send!
   [client {:keys [type dest data headers] :as opts}]
   {:pre [(or (map? data)
              (nil? data))
          (keyword? dest)
          (client? client)]}
-  (let [hds (merge +default-headers+
-                   (:headers client))
-        req {:url (:url client)
-             :method (:method client)
-             :body (encode {:data data
-                            :dest dest
-                            :type type})
-             :headers hds}]
+  (let [data (encode {:data data :dest dest :type type})
+        req (prepare-request client data)]
     (-> (http/send! xhr/client req)
         (p/then process-response))))


silence all the async printing

silence all the async printing

--- src/clj/infinitelives/utils/async.clj
+++ src/clj/infinitelives/utils/async.clj
@@ -54,12 +54,13 @@
             :default form))))
     body))

-(defmacro go-while [test & body]
-  `(go
-     ~(thread-test-around-sync-points test body)))
-
 (defmacro continue-while [test & body]
   `(try
      ~(thread-test-around-sync-points test body)
      (catch js/Error e
-       (js/console.log "continue-while exit triggered by: " e))))
+       ;;(js/console.log "continue-while exit triggered by: " e)
+       )))
+
+(defmacro go-while [test & body]
+  `(go
+     (continue-while ~test ~@body)))


add comment for next refactor step

add comment for next refactor step

--- src/clj_money/models/transactions.clj
+++ src/clj_money/models/transactions.clj
@@ -768,11 +768,13 @@
     (let [validated (validate storage ::existing-transaction transaction)]
       (if (validation/has-error? validated)
         validated
+
+        ; TODO: rewrite this using an "update-context" map that holds all necessary information
+
         (let [existing (find-existing-transaction storage validated)
               dereferenced-base-items (remove-dereferenced-items storage validated existing)
               dereferenced-account-base-items (dereferenced-account-base-items storage validated existing)
               current-base-items (process-updated-transaction-items storage validated existing)
-

               ; process all item updates
               _ (->> current-base-items


Use 'navigator.language' 'cos M$

Use 'navigator.language' 'cos M$

--- src/cljs-shared/sbsk/shared/time.cljs
+++ src/cljs-shared/sbsk/shared/time.cljs
@@ -6,7 +6,7 @@
   (.format (.locale (js/moment
                      time
                      "YYYYMMDD'T'HHmmss'Z'")
-                    (aget (.-languages js/navigator) 0)) "L"))
+                    (.-language js/navigator)) "L"))

 (defn as-moment-month-year
   [time]
@@ -19,4 +19,4 @@
   (.calendar (.locale (js/moment
                        time
                        "YYYYMMDD'T'HHmmss'Z'")
-                      (aget (.-languages js/navigator) 0))))
+                      (.-language js/navigator))))


Destory old popover before displaying new one.

--- src/cljs/editor/quil_site/editor.cljs
+++ src/cljs/editor/quil_site/editor.cljs
@@ -55,6 +55,7 @@
     (.popover (j/$ "#share") "show")))

 (defn share []
+  (.popover (j/$ "#share") "destroy")
   (j/ajax
    {:url "/sketches/create"
     :method "POST"


Add a viewport declaration; improve mobile view

--- src/pronouns/pages.clj
+++ src/pronouns/pages.clj
@@ -75,6 +75,7 @@
    [:html
     [:head
      [:title title]
+     [:meta {:name "viewport" :content "width=device-width"}]
      [:link {:rel "stylesheet" :href "/pronouns.css"}]]
     [:body
      (title-block title)
@@ -103,6 +104,7 @@
      [:html
       [:head
        [:title title]
+       [:meta {:name "viewport" :content "width=device-width"}]
        [:link {:rel "stylesheet" :href "/pronouns.css"}]]
       [:body
        (title-block title)


Updated docstring for tests in module server

--- test/zg/server_test.clj
+++ test/zg/server_test.clj
@@ -217,14 +217,14 @@
 ;

 (deftest test-get-user-name-not-NPE
-    "Check the function get-user-name."
-    (testing "the function get-user-name."
+    "Check the function zg.server/get-user-name."
+    (testing "the function zg.server/get-user-name."
         (are [x y] (= x (get-user-name y))
             nil nil)))

 (deftest test-get-user-name
-    "Check the function get-user-name."
-    (testing "the function get-user-name."
+    "Check the function zg.server/get-user-name."
+    (testing "the function zg.server/get-user-name."
         (are [x y] (= x (get-user-name y))
             "new user" {:params  {"user-name" "new user"}}
             "new user" {:params  {"user-name" "new user"}
@@ -232,8 +232,8 @@
             "old user" {:cookies {"user-name" {:value "old user"}}})))

 (deftest test-get-title
-    "Check the function get-title."
-    (testing "the function get-title."
+    "Check the function zg.server/get-title."
+    (testing "the function zg.server/get-title."
         (are [x y] (= x (get-title y))
             "ZG" {:configuration {:display {:app-name "ZG"}}}
             nil  {:configuration {:display {:app-name nil}}}
@@ -244,8 +244,8 @@
             nil  nil)))

 (deftest test-get-emender-page
-    "Check the function get-emender-page."
-    (testing "the function get-emender-page."
+    "Check the function zg.server/get-emender-page."
+    (testing "the function zg.server/get-emender-page."
         (are [x y] (= x (get-emender-page y))
             "http://www.emender.org" {:configuration {:display {:emender-page "http://www.emender.org"}}}
             nil  {:configuration {:display {:emender-page nil}}}
@@ -256,8 +256,8 @@
             nil  nil)))

 (deftest test-get-url-prefix
-    "Check the function get-url-prefix."
-    (testing "the function get-url-prefix."
+    "Check the function zg.server/get-url-prefix."
+    (testing "the function zg.server/get-url-prefix."
         (are [x y] (= x (get-url-prefix y))
             "http://localhost" {:configuration {:server {:url-prefix "http://localhost"}}}
             nil  {:configuration {:server {:url-prefix nil}}}


Add :session-cookie-attrs to session docstring

--- ring-core/src/ring/middleware/session.clj
+++ ring-core/src/ring/middleware/session.clj
@@ -90,10 +90,12 @@
                   path attribute. Defaults to \"/\".

   :cookie-name  - The name of the cookie that holds the session key. Defaults to
-                  \"ring-session\"
+                  \"ring-session\".

   :cookie-attrs - A map of attributes to associate with the session cookie.
-                  Defaults to {:http-only true}."
+                  Defaults to {:http-only true}. This may be overridden on a
+                  per-response basis by adding :session-cookie-attrs to the
+                  response."
   ([handler]
      (wrap-session handler {}))
   ([handler options]


Small changes for September call

Small changes for September call

--- scrape-n-mail/src/scrape_n_mail/core.cljs
+++ scrape-n-mail/src/scrape_n_mail/core.cljs
@@ -142,6 +142,7 @@
           (.load js/gapi "client:auth2" #(init-client config-keys)) )
         #_(println keys-resp) )))

+; TODO - make this generic so it only adds the fields that are specified
 (defn prefilled-link [{name-altar ::held-name-altar
                        name-public ::held-name-public
                        pronunciation ::procunciation-hints
@@ -165,6 +166,55 @@
     [:a {:href custom-url} name-altar]
   ))

+
+(defn name-email-link [{submitter-name ::submitter-name
+                        submitter-email ::submitter-email}]
+  (let [url-root
+        "https://docs.google.com/forms/d/e/1FAIpQLSc_FFrH7a_ClDmpAq36vA7gdUd1njmoEK0wfhRNaYcjfLox0w/viewform?usp=pp_url"]
+        (join \& [ url-root
+                  (str "entry.552838120=" submitter-name)
+                  (str "entry.681476151=" submitter-email)])
+  ))
+
+
+(defn email-text [submitter-email name-records]
+  (let [personal-link (name-email-link (first name-records))]
+    [
+      [:hr]
+      [:p submitter-email]
+      [:br]
+      [:p "Dear " (::submitter-name (first name-records)) ","]
+
+      [:p "Our call for names for Wellbeing for August 2018 is out: "
+          "http://newdharma.transformativechange.org/2018/08/wellbeing-september-2018/"]
+
+      [:p "Currently, the community is holding the following names on the altar "
+          "in support of their wellbeing at your request. You can click "
+          "directly on each name you would like to remain and get a pre-filled form. "
+          "Please check each submission before clicking the submit button, and let Dav know "
+          "if there is anything incorrect." ]
+
+      (into [:ul {:id "content"}]
+        ; We currently assume all visible data is "current"
+        ; (filter #(s/includes? (aget % 0) "2017"))
+        ; Each line is a list, this joins them in to one string
+        (map #(vector :li (prefilled-link %)) name-records))
+
+      [:p "New names may be submitted at " [:a {:href personal-link} "your presonal link"]
+      ". If the above links don't work, you can copy-paste the form link into your browser:"]
+
+      [:p personal-link]
+
+      [:p [:em "As explained in the group email, it is traditional to offer Dana "
+               "along with the submission of names. Here's "
+               [:a {:href payment-link} "the link."]]]
+
+      [:p "If we do not hear from you, we will remove the above names from the altar. J'ai mitra!"]
+
+      ; Note that the \ is an escape character!
+      [:p "/|\\"]
+    ]))
+
 (rum/defc scrape-it < rum/reactive []
   (let [curr-data (rum/react app-data)]
     [:div
@@ -180,41 +230,7 @@

         (when-let [records (:sheet-data curr-data)]
           (for [[submitter-email name-records] (group-by ::submitter-email records)]
-            [
-              [:hr]
-              [:p submitter-email]
-               [:br]
-               [:p "Dear " (::submitter-name (first name-records)) ","]
-
-               [:p "Our call for names for Wellbeing for August 2018 is out: http://center.transformativechange.org/?p=1883"]
-
-               [:p "Currently, the community is holding the following names on the altar "
-                   "in support of their wellbeing at your request. You can click "
-                   "directly on each name you would like to remain and get a pre-filled form. "
-                   "Please check each submission before clicking the submit button, and let Dav know "
-                   "if there is anything incorrect."
-
-                (into [:ul {:id "content"}]
-                  ; We currently assume all visible data is "current"
-                  ; (filter #(s/includes? (aget % 0) "2017"))
-                  ; Each line is a list, this joins them in to one string
-                  (map #(vector :li (prefilled-link %)) name-records))
-
-                "New names may be submitted at "
-                [:a {:href blank-form} "this link"]
-                ". If the above links don't work, you can copy-paste the form link into your browser:"]
-
-               [:p blank-form]
-
-               [:p [:em "As explained in the group email, it is traditional to offer Dana "
-                        "along with the submission of names. Here's "
-                        [:a {:href payment-link} "the link."]]]
-
-               [:p "If we do not hear from you, we will remove these names from the altar. J'ai mitra!"]
-
-               ; Note that the \ is an escape character!
-               [:p "/|\\"]
-                ]))
+            (email-text submitter-email name-records) ))
      ]))

 (rum/mount (scrape-it)


update to latest

update to latest

--- src/hundred_pushups/android/core.cljs
+++ src/hundred_pushups/android/core.cljs
@@ -1,5 +1,5 @@
 (ns hundred-pushups.android.core
- (:require [reagent.core :as r :refer [atom]]
+  (:require [reagent.core :as r :refer [atom]]
             [clojure.pprint :as pp]
             [re-frame.core :refer [subscribe dispatch dispatch-sync]]
             [hundred-pushups.events]
@@ -75,8 +75,8 @@
        [touchable-highlight {:style {:background-color "#999" :padding 10 :border-radius 5 :margin 10}
                              :on-press #(do
                                           (dispatch [:append-test
-                                                     {:exr.pushup/reps (js/parseInt (:pushup-reps-text @ui-state))
-                                                      :exr.plank/reps (js/parseInt (:plank-reps-text @ui-state))
+                                                     {:exr/pushup-reps (js/parseInt (:pushup-reps-text @ui-state))
+                                                      :exr/plank-reps (js/parseInt (:plank-reps-text @ui-state))
                                                       }
                                                      ])
                                           (dispatch [:ui-state/clear [[:plank-reps-text]
@@ -102,10 +102,8 @@
       (for [x (range (:exr/sets schedule))]
         [view {:key x}
          [text {:style {:font-size 18 :font-weight "600" :margin-top 10}} (str "Set" x)]
-         [text {} (str (:exr.pushup/reps circuit) " pushups")]
-         [text {} (str "Hold plank for "(:exr.plank/reps circuit) " breaths")]
-         ]
-        )
+         [text {} (str (:exr/pushup-reps circuit) " pushups")]
+         [text {} (str "Hold plank for "(:exr/plank-reps circuit) " breaths")]])
       [touchable-highlight {:style {:background-color "#999" :padding 10 :border-radius 5 :margin-top 20}
                             :on-press #(do
                                          (dispatch [:complete-day schedule])


Fixing typo in index.clj. Closes #243

Fixing typo in index.clj. Closes #243

--- src/io/cyanite/index.clj
+++ src/io/cyanite/index.clj
@@ -30,7 +30,7 @@
     {:path         path
      :text         (last (split path #"\."))
      :id           path
-     :allowChilren (if (some (partial < length) lengths) 1 0)
+     :allowChildren (if (some (partial < length) lengths) 1 0)
      :expandable   (if (some (partial < length) lengths) 1 0)
      :leaf         (if (boolean (lengths length)) 1 0)}))


Added some indices for events table.

Added some indices for events table.

--- src/lobos/migrations.clj
+++ src/lobos/migrations.clj
@@ -28,6 +28,8 @@
                      (timestamp :event_time :not-null)
                      ))
       (create (index :events :ix_events_event_time [:event_time]))
+      (create (index :events :ix_events_created_on [:created_on]))
+      (create (index :events :ix_events_trackers_id [:tracker_id]))
       )

   (down [] (drop (table :events))))


try pr-string in the console first since clojure errors might come through differently

Signed-off-by: Chris Granger <5654cde260ae99bc4d30054171b8bcd902efd19a@gmail.com>

--- src/lt/objs/console.cljs
+++ src/lt/objs/console.cljs
@@ -129,7 +129,10 @@
   (statusbar/console-class "error")
   (log (str (if (.-stack e)
               (.-stack e)
-              (str e)))
+              (let [pr-e (pr-str e)]
+                (if (not= pr-e "[object Object]")
+                  pr-e
+                  (str e)))))
        "error"))

 (defn clear []


core: rational?

core: rational?

--- data/core.clj
+++ data/core.clj
@@ -1747,3 +1747,9 @@
   {:added "1.0"}
   [n]
   (instance? Double n))
+
+(defn rational?
+  "Returns true if n is a rational number"
+  {:added "1.0"}
+  [n]
+  (or (integer? n) (ratio? n)))


fix advanced compilation bug

fix advanced compilation bug

--- src/main/om_css/dom.cljc
+++ src/main/om_css/dom.cljc
@@ -120,8 +120,8 @@
       (if #?(:clj (and (map? props)
                        (not (record? props)))
              :cljs (or (and (cljs.core/object? props)
-                            (not (.-$$typeof props))
-                            (not= (goog/typeOf (.-$$typeof props)) "symbol"))
+                            (not (aget props "$$typeof"))
+                            (not= (goog/typeOf (aget props "$$typeof")) "symbol"))
                        (map? props)))
         [props (rest params)]
         [nil params])


Now that freeing nodes is bound to allocation - the trick of assuming the osc sends would be asynchronously fired (and therefore collected in an at bundle) no longer works. It was also an issue in a concurrent context as the allocator would have freed node ids at a totally different time to the server freeing them. Use at-at to schedule a thunk to do the work instead.

--- src/overtone/sc/synth.clj
+++ src/overtone/sc/synth.clj
@@ -7,7 +7,8 @@
   overtone.sc.synth
   (:require
     [overtone.log :as log]
-    [clojure.contrib.generic.arithmetic :as ga])
+    [clojure.contrib.generic.arithmetic :as ga]
+    [at-at])
   (:use
     [overtone util event time-utils]
     [overtone.sc.ugen defaults]
@@ -547,7 +548,7 @@
              (list 'out 0 body))]
     `(let [s# (synth "audition-synth" ~b2)
            note# (s#)]
-       (at (+ (now) ~demo-time) (node-free note#))
+       (at-at/at (+ (now) ~demo-time) #(node-free note#))
        note#)))

 (defn active-synths


Fix page history

Fix page history

--- demo/sitetools/core.cljs
+++ demo/sitetools/core.cljs
@@ -90,8 +90,8 @@
                     (History.)))
         (evt/listen hevt/NAVIGATE #(dispatch [:set-page (.-token %)]))
         (.setEnabled true))
-      (when (and page (not html5) (empty? (.getToken history)))
-        (dispatch [:set-page page])))))
+      (when (and page (not html5) (-> history .getToken empty?))
+        (.setToken history page)))))

 (defn to-relative [f]
   (string/replace f #"^/" ""))


interceptor context map contains post body in :params

--- src/minuette/service.clj
+++ src/minuette/service.clj
@@ -3,7 +3,7 @@
             [io.pedestal.service.http.route :as route]
             [io.pedestal.service.http.route.definition :refer [defroutes]]
             [io.pedestal.service.http.body-params :as body-params]
-            [ring.util.response :as ring-response]
+            [ring.util.response :as ring-resp]
             [io.pedestal.service.http.servlet :as ps]
             [io.pedestal.service.log :as log]
             ;; the impl dependencies will go away
@@ -16,15 +16,20 @@
             [io.pedestal.service.http.route.definition :refer [defroutes]]
             [io.pedestal.service.http.sse :refer :all]
             [ring.util.mime-type :as ring-mime]
-            [ring.middleware.session.cookie :as cookie])
-    (:require [io.pedestal.service.http :as bootstrap]
-              [io.pedestal.service.http.route :as route]
-              [io.pedestal.service.http.body-params :as body-params]
-              [io.pedestal.service.http.route.definition :refer [defroutes]]
-              [io.pedestal.service.log :as log]
-              [ring.util.response :as ring-resp]
-              [minuette.quartzite.scheduler :as scheduler]
+            [ring.middleware.session.cookie :as cookie]
+
+            [minuette.quartzite.scheduler :as scheduler]
     ))
+
+
+;; -------------------------------------------------------------------------------
+;; for xhr/request from pedestal app, request body was edn encoded, hence under :end-params key.
+;; destrcture [{reqbody :edn-params :as request}], request context map still :as request.
+;;
+
+; An interceptor is one instance of an Interceptor record or a map with
+; :enter, :leave, :pause, :resume, and :error keys.
+

 (defn about-page
   [request]
@@ -44,14 +49,15 @@
 (definterceptor session-interceptor
   (middlewares/session {:store (cookie/cookie-store)}))

+
 ;;==================================================================================
-;
+; retrieve schedule
 ;;==================================================================================
 (defn get-schedule
   "get things by type, ret from peer a list of thing in a new line sep string"
-  [req]
-  ; path segment in req contains request params, /api/:thing, /api/lecture
-  (let [schedid (get-in req [:path-params :schedid])
+  [req]     ; get req, no post data body.
+  ; path segment in req can be parameterized in nested map.
+  (let [schedid (get-in req [:path-params :schedid]) ; nested map under :path-params
         schedule (scheduler/get-schedule schedid)
         result {:status 200 :schedule schedule}
         jsonresp (bootstrap/json-response result)] ; conver to keyword for query
@@ -71,13 +77,13 @@
 ;;==================================================================================
 (defn add-schedule
   "add a schedule upon post request, request contains post data"
-  [{reqbody :edn-params :as request}]  ; reqbody is json post data
+  [{postbody :edn-params :as request}]   ; xhr/request post data is edn encoded, not usable here.
   (let [;resp (bootstrap/json-print {:result msg-data})
-        details (:params request)
+        details (or postbody (:params request))  ; curl post body in :params
         added-schedule (scheduler/add-schedule details)
         result {:status 200 :schedule added-schedule}
         jsonresp (bootstrap/json-response result)
-        ]
+       ]
     ; INFO  minuette.service - {:line 52, "service add-schedule " {"detail" "123", "min" "3", "weekdays" "[1,2]"}
     (log/info "add-schedule request " request)
     jsonresp))
@@ -91,11 +97,11 @@
 ; [[["/order"  ^:interceptors [verify-request] ^:constraints {:user-id #"[0-9]+"}
 ;    {:get list-orders :post create-order}
 ;    ["/:id"  ^:constraints {:user-id #"[0-9]+"} ^:interceptors [verify-order-ownership load-order-from-db]
-;    {:get view-order :put update-order}]]]]
+;    {:get view-order :post [:make-an-order o/create-order]}]]]]
 ;;==================================================================================
 (defroutes routes
   [[["/" {:get home-page}
-     ; set common interceptors to be executed for all routes
+     ; set intermediate interceptors to be executed for before dest-interceptor.
      ^:interceptors [(body-params/body-params) bootstrap/html-body session-interceptor]
      ["/about" {:get about-page}]
      ["/api/schedule/:schedid" {:get get-schedule}]


Fixed errors with parsing discography

Fixed errors with parsing discography

--- src/metallumapi/scrape/bands.clj
+++ src/metallumapi/scrape/bands.clj
@@ -73,18 +73,19 @@
                                        *discography*)]
               (map (fn [row]
                      (let [[n t y r] (map :content (html/select row [:td]))
-                           rating (first (:content (second r)))]
+                           rating (first (:content (second r)))
+                           rating-link (:href (:attrs (second r)))]
                        {:album {:name (first (:content (first n)))
                                 :link (:href (:attrs (first n)))}
                         :type (first t)
                         :year (first y)
-                        :rating (if rating
-                                  {:link (:href (:attrs (second r)))}
-                                  (let [rating-match (re-matcher #"(\d+)\s(\((\d+)%\))" rating)
-                                        [_ number _ percentage] (re-find rating-match)]
-                                    {:reviews number
-                                     :avg-rating (str percentage "%")
-                                     :link (:href (:attrs (second r)))}))}))
+                        :rating (if rating-link
+                                  (let [[_ number _ percentage] (re-matches #"(\d+)\s(\((\d+)%\))"
+                                                                             (if rating rating "") )]
+                                     (if number
+                                       {:reviews number
+                                        :avg-rating (str percentage "%")
+                                        :link rating-link})))}))
                    content)))]
     {:complete (fn [] (disco "all"))
      :main (fn [] (disco "main"))