Upgrade to latest CLJS compiler

Upgrade to latest CLJS compiler

--- project.clj
+++ project.clj
@@ -5,13 +5,13 @@
             :url "http://www.apache.org/licenses/LICENSE-2.0"}

   :dependencies [[org.clojure/clojure "1.8.0"]
-                 [org.clojure/clojurescript "1.9.473"]
+                 [org.clojure/clojurescript "1.9.660"]
                  [org.clojure/core.async "0.2.374"]
                  [reagent "0.6.2"]
                  [devcards "0.2.2" :exclusions [cljsjs/react]]
                  [org.clojure/test.check "0.9.0"]
                  [org.clojure/core.match "0.3.0-alpha4"]
-                 [prismatic/schema "1.1.3"]]
+                 [prismatic/schema "1.1.6"]]

   :plugins [[lein-cljsbuild "1.1.5"]
             [lein-figwheel "0.5.9"]


project cruft

project cruft

--- project.clj
+++ project.clj
@@ -15,6 +15,4 @@
                                                     :optimizations :simple
                                                     :output-dir "out"
                                                     :libs ["lib"]
-                                                    ;; :foreign-libs [{:file "lib/pear.grid.js"
-                                                    ;;                 :provides ["pear"]}]
                                                     }}}}}})


Version 1.1.4-SNAPSHOT

Version 1.1.4-SNAPSHOT

--- project.clj
+++ project.clj
@@ -1,4 +1,4 @@
-(defproject puppetlabs/http-client "1.1.3"
+(defproject puppetlabs/http-client "1.1.4-SNAPSHOT"
   :description "HTTP client wrapper"
   :license {:name "Apache License, Version 2.0"
             :url "http://www.apache.org/licenses/LICENSE-2.0.html"}


heroku compatibility

heroku compatibility

--- project.clj
+++ project.clj
@@ -80,7 +80,7 @@
               :cljsbuild
               {:builds
                {:server
-                {:compiler {:optimizations :simple
+                {:compiler {:optimizations :none
                             :pretty-print false}}
                 :app
                 {:compiler {:output-dir "target/app/out"


(PCP-528) Fix unit and integration lein profiles

[skip ci]

--- project.clj
+++ project.clj
@@ -1,6 +1,7 @@
 (def tk-version "1.4.0")
 (def ks-version "1.3.0")
 (def i18n-version "0.4.1")
+(def http-async-client-version "0.6.1")

 (defproject puppetlabs/pcp-broker "0.7.3-SNAPSHOT"
   :description "PCP fabric messaging broker"
@@ -93,7 +94,7 @@
                                   ;; - it actually brings in netty 3.9.2.Final, but we
                                   ;; want some fixes to websocket handling that are in later .x releases
                                   [io.netty/netty "3.9.9.Final"]
-                                  [http.async.client "0.6.1" :exclusions [org.clojure/clojure]]
+                                  [http.async.client ~http-async-client-version :exclusions [org.clojure/clojure]]
                                   [puppetlabs/trapperkeeper ~tk-version :classifier "test" :scope "test"]
                                   [puppetlabs/kitchensink ~ks-version :classifier "test" :scope "test"]
                                   [puppetlabs/ssl-utils "0.8.1"]
@@ -101,8 +102,13 @@
                                   ;; Transitive dependency for lein-cloverage and puppetlabs/kitchensink
                                   [org.clojure/tools.cli "0.3.0"]]
                    :plugins [[lein-cloverage "1.0.6" :excludes [org.clojure/clojure org.clojure/tools.cli]]]}
-             :integration {:test-paths ^:replace ["test/integration" "test/utils" "test-resources"]}
-             :unit {:test-paths ^:replace ["test/unit" "test/utils" "test-resources"]}
+             :unit {:source-paths ["test/utils" "test-resources"]
+                    :dependencies [[http.async.client ~http-async-client-version :exclusions [org.clojure/clojure]]]
+                    :test-paths ^:replace ["test/unit"]}
+             :integration [:unit
+                           {:dependencies [[puppetlabs/trapperkeeper ~tk-version :classifier "test" :scope "test"]
+                                           [puppetlabs/kitchensink ~ks-version :classifier "test" :scope "test"]]
+                            :test-paths ^:replace ["test/integration"]}]
              :cljfmt {:plugins [[lein-cljfmt "0.3.0"]
                                 [lein-parent "0.2.1"]]
                       :parent-project {:path "../pl-clojure-style/project.clj"
@@ -117,6 +123,8 @@
             ;; runs trapperkeeper with schema validations enabled
             "tkv" ["trampoline" "run" "-m" "user" "--config" "test-resources/conf.d"]
             "certs" ["trampoline" "run" "-m" "puppetlabs.pcp.testutils.certs" "--config" "test-resources/conf.d" "--"]
+            ;; cljfmt requires pl-clojure-style's root dir as per above profile;
+            ;; run with 'check' then 'fix' with args (refer to the project docs)
             "cljfmt" ["with-profile" "+cljfmt" "cljfmt"]
             "coverage" ["cloverage" "-e" "puppetlabs.puppetdb.*" "-e" "user"]}


regexp-quote is not required

regexp-quote is not required

--- project.clj
+++ project.clj
@@ -29,7 +29,6 @@

   :node-dependencies [[source-map-support "0.2.8"]   ;; optional
                       [crc                "3.3.0"]   ;; response verification, opt.
-                      [regexp-quote       "0.0.0"]   ;; signing
                       [portfinder         "0.4.0"]   ;; test
                       [timekeeper         "0.0.5"]   ;; test
                       [xml2js             "0.4.9"]]  ;; sns/sqs


Update dependencies.

Update dependencies.

--- project.clj
+++ project.clj
@@ -24,10 +24,8 @@
                  [manifold "0.1.5"]
                  [com.stuartsierra/component "0.3.1"]
                  [commons-io/commons-io "2.5"]
-                 [buddy/buddy-sign "1.1.0"
-                  :exclusions [com.fasterxml.jackson.core/jackson-core]]
-
-                 [funcool/cuerdas "0.8.0"]
+                 [buddy/buddy-sign "1.2.0"]
+                 [funcool/cuerdas "1.0.1"]
                  [funcool/promesa "1.5.0"]
                  [danlentz/clj-uuid "0.1.6"]
                  [environ "1.1.0"]


Add cheshire for json http responses

Add cheshire for json http responses

--- project.clj
+++ project.clj
@@ -35,7 +35,8 @@
                  [clj-tuple "0.2.2"]
                  [clj-fuzzy "0.3.1" :exclusions [org.clojure/clojurescript]]
                  [ring "1.4.0"]
-                 [ring-jetty-component "0.3.0"]]
+                 [ring-jetty-component "0.3.0"]
+                 [cheshire "5.5.0"]]
   :jvm-opts ["-Xmx4g" "-XX:-OmitStackTraceInFastThrow"]
   :profiles {:dev {:dependencies [[org.clojure/tools.nrepl "0.2.11"]
                                   [table "0.5.0"]


Rename namespace in lazytest_asserts.clj

And add empty "describe" block.

--- src/asserts/lazytest_asserts.clj
+++ src/asserts/lazytest_asserts.clj
@@ -1,4 +1,4 @@
-(ns com.stuartsierra.lazytest-test
+(ns com.stuartsierra.lazytest-asserts
   (:use com.stuartsierra.lazytest
         com.stuartsierra.lazytest.report))

@@ -107,3 +107,7 @@
   (let [result (once-contexts)]
     (assert (success? result))
     (assert (= @*log* [:open-c1 :open-c2 :close-c2 :close-c1]))))
+
+
+;; empty describe to block run-spec
+(describe *ns* )


Preserve order of :aot namespaces list.

Preserve order of :aot namespaces list.

--- src/leiningen/compile.clj
+++ src/leiningen/compile.clj
@@ -20,11 +20,9 @@
   their class files are present and up-to-date."
   [project]
   (let [nses (or (:aot project) (:namespaces project))
-        nses (set (cond
-                   (coll? nses) nses
-
-                   (= :all nses)
-                   (find-namespaces-in-dir (file (:source-path project)))))]
+        nses (if (= :all nses)
+               (find-namespaces-in-dir (file (:source-path project)))
+               nses)]
     (if (:main project)
       (conj nses (:main project))
       nses)))


Added support for multiple statement execution.

--- src/cljsh/core.cljs
+++ src/cljsh/core.cljs
@@ -12,9 +12,11 @@
   (.readFileSync fs filename "utf-8"))

 (defn -main [& args]
-  (replumb/read-eval-call {:target :nodejs}
+  (replumb/read-eval-call {:target :nodejs
+                           :context :statement ;; Will eval multiple exprs with this.
+                           }
                           (fn [result]
                             (when-not (:success? result)
-                              (println "it didn't work :(")))
+                              (println result)))
                           (node-read-file-sync (first args))))
 (set! *main-cli-fn* -main)


Removed references to old environment

Removed references to old environment

--- src/aurora/compiler/datalog.cljs
+++ src/aurora/compiler/datalog.cljs
@@ -44,6 +44,9 @@
   (Knowledge. (to-be kn) #{} #{}))

 ;; creating queries
+
+(defn op? [op clause]
+  (and (seq? clause) (= op (first clause))))

 (defn vars [clause]
   (condp op? clause
@@ -133,9 +136,6 @@
             elem (get fact set-key :inq-not-found)]
         (assoc fact name-key elem)))))

-(defn op? [op clause]
-  (and (seq? clause) (= op (first clause))))
-
 (defn gen* [clauses]
   (reduce
    (fn [query clause]
@@ -153,8 +153,8 @@
    clauses))

 (defn asserts+retracts* [clauses]
-  (let [assert-fs (map #(map-q (second %)) (filter assert? clauses))
-        retract-fs (map #(map-q (second %)) (filter retract? clauses))
+  (let [assert-fs (into [] (map #(map-q (second %)) (filter #(op? '+ %) clauses)))
+        retract-fs (into [] (map #(map-q (second %)) (filter #(op? '- %) clauses)))
         gen (gen* clauses)]
     (fn [kn]
       (let [facts (gen kn)
@@ -196,9 +196,9 @@

 (comment

-  ((project '[a b]) (Knowledge. #{[1 2] [3 4 5] [6 7]} #{} #{}))
-
-  ((join (project '[a b _]) (project '[_ a b])) (Knowledge. #{[1 2 3] [2 3 4] [2 4 6] [4 6 8]} #{} #{}))
+  ((project '[a b] to-be) (Knowledge. #{[1 2] [3 4 5] [6 7]} #{} #{}))
+
+  ((join (project '[a b _] to-be) (project '[_ a b] to-be)) (Knowledge. #{[1 2 3] [2 3 4] [2 4 6] [4 6 8]} #{} #{}))

   ((filter-q (project '[a b] to-be) (fnk [a b] (= a b))) (Knowledge. #{[1 2] [3 4] [6 6]} #{} #{}))


add extra note for kicks

add extra note for kicks

--- examples/extemp_piano.clj
+++ examples/extemp_piano.clj
@@ -35,7 +35,7 @@
 (def instrument sampled-piano)
 (def metro (metronome 20))

-(def beat-offsets [0 0.1 1/3  0.7 0.9])
+(def beat-offsets [0 0.1 0.2 1/3  0.7 0.9])
 (def chord-prog
   [#{[2 :minor7] [7 :minor7] [10 :major7]}
    #{[0 :minor7] [8 :major7]}])


language: when developing a language the language was lost

--- src/civs/logic/tribe_choices.clj
+++ src/civs/logic/tribe_choices.clj
@@ -160,11 +160,14 @@
     (fn [game tribe]
       (possibility-of-evolving-into-tribe tribe))
     (fn [game group]
-      {
-        :game (develop-a-language game (:id group))
-        :tribe (evolve-in-tribe group)
-        :params {}
-        })))
+      (let [game (develop-a-language game (:id group))
+            group (get-group game (:id group))
+            group (evolve-in-tribe group)]
+        {
+          :game game
+          :tribe group
+          :params {}
+          }))))

 (def evolution-in-chiefdom
   (PossibleEvent.


Tidy up dataset spec namespaces

Tidy up dataset spec namespaces

--- backend/specs/akvo/lumen/specs/dataset.clj
+++ backend/specs/akvo/lumen/specs/dataset.clj
@@ -1,15 +1,12 @@
 (ns akvo.lumen.specs.dataset
-  (:require [akvo.lumen.specs :as lumen.s :refer (sample)]
-            [akvo.lumen.specs.transformation]
-            [akvo.lumen.lib.dataset.utils :as dataset.utils]
-            [clojure.spec.alpha :as s]
-            [clojure.spec.gen.alpha :as gen]))
+  (:require [akvo.lumen.lib.dataset.utils :as dataset.utils]
+            [clojure.spec.alpha :as s]))

-(alias 'db.dsv 'akvo.lumen.specs.db.dataset-version)
+(alias 'db.dsv.s 'akvo.lumen.specs.db.dataset-version)

 (s/fdef dataset.utils/find-column
-  :args (s/alt :by-name (s/cat :columns ::db.dsv/columns
+  :args (s/alt :by-name (s/cat :columns ::db.dsv.s/columns
                                :v (s/nilable string?))
-               :by-filter (s/cat :columns ::db.dsv/columns
+               :by-filter (s/cat :columns ::db.dsv.s/columns
                                  :v (s/nilable string?)
                                  :filter-by keyword?)))


Reload server whenever restart function is run.

--- src/incise/core.clj
+++ src/incise/core.clj
@@ -74,7 +74,8 @@
       (serve))))

 (defn restart
-  "Define a server and set up a watcher AT THE SAME TIME!"
+  "Stop a server if it is already started and start a new one."
   [& args]
   (stop-server)
+  (require :reload 'incise.server)
   (apply defserver args))


Add a table alias function to Source, allowing us to mock alias generation.

--- src/datomish/query/source.cljc
+++ src/datomish/query/source.cljc
@@ -36,20 +36,27 @@
    attribute-transform
    constant-transform

+   ;; `table-alias` is a function from table to alias, e.g., :datoms => :datoms1234.
+   table-alias
+
    ;; Not currently used.
    make-constraints    ; ?fn [source alias] => [where-clauses]
    ])
+
+(defn gensym-table-alias [table]
+  (gensym (name table)))

 (defn datoms-source [db]
   (->Source :datoms
             [:e :a :v :tx :added]
             transforms/attribute-transform-string
             transforms/constant-transform-default
+            gensym-table-alias
             nil))

 (defn source->from [source]
   (let [table (:table source)]
-    [table (gensym (name table))]))
+    [table ((:table-alias source) table)]))

 (defn source->constraints [source alias]
   (when-let [f (:make-constraints source)]


Rename fn which processes ajax-responses

--- src/discuss/communication.cljs
+++ src/discuss/communication.cljs
@@ -3,7 +3,6 @@
   (:require [ajax.core :refer [GET POST]]
             [clojure.walk :refer [keywordize-keys]]
             [discuss.config :as config]
-            [discuss.debug :as debug]
             [discuss.utils.common :as lib]))

 ;;; Auxiliary functions
@@ -47,7 +46,7 @@
     (ajax-get url)
     (lib/change-view! view))

-(defn success-handler
+(defn process-response
   "Generic success handler, which sets error handling and returns a cljs-compatible response."
   [response]
   (let [res (lib/json->clj response)
@@ -62,7 +61,7 @@
 (defn process-url-handler
   "React on response after sending a new statement. Reset atom and call newly received url."
   [response]
-  (let [res (success-handler response)
+  (let [res (process-response response)
         url (:url res)]
     (lib/hide-add-form!)
     (lib/update-state-item! :layout :add-type (fn [_] nil))


Leiningen caches dependencies

Leiningen caches dependencies

Since the clojure container is run with LEIN_ROOT, by default it
downloads jars to /root/.m2/repository.  Making the user-space default
location explicit lets them pile up like you'd expect.

This took me an astoundingly long time to figure out, and it _still_
doesn't work for plugins!  Aaaah!!

--- dotfiles/lein/profiles.clj
+++ dotfiles/lein/profiles.clj
@@ -1,3 +1,4 @@
-{:user {:plugins [[cider/cider-nrepl "0.8.2"]
+{:user {:local-repo "/home/dev/.m2/repository"
+        :plugins [[cider/cider-nrepl "0.8.2"]
                   [jonase/eastwood "0.2.1"]
                   [lein-cljfmt "0.1.7"]]}}


Better error reporting for AlphaBot.

Better error reporting for AlphaBot.

--- Alphabot/src/alphabot/core.clj
+++ Alphabot/src/alphabot/core.clj
@@ -25,20 +25,63 @@
         (mapcat get-all-plaintext-lines (:content o))
         (re-seq #".+" o)))

-(defn get-results [xmldoc]
+(defn extract-nested-errors [xmldoc parent-tag child-tag]
+    (filter
+        (fn [t] (= (:tag t) child-tag))
+        (mapcat
+            (fn [t] (:content t))
+            (filter
+                (fn [t] (= (:tag t) parent-tag))
+                (:content xmldoc)))))
+
+(defn extract-didyoumeans [xmldoc]
+    (mapcat
+        (fn [t] (let [[l & ls] (:content t)]
+            (concat
+                [(str "Did you mean: " l)]
+                ls)))
+        (extract-nested-errors xmldoc :didyoumeans :didyoumean)))
+
+(defn extract-tips [xmldoc]
+    (map
+        (fn [t] (str "Tip: " (:text (:attrs t))))
+        (extract-nested-errors xmldoc :tips :tip)))
+
+(defn extract-top-level-errors [xmldoc parent-tag attrs]
     (mapcat
         (fn [t]
-            (let [[l & ls] (get-all-plaintext-lines t)]
-                (concat
-                    [(str (:title (:attrs t)) ": " l)]
-                    ls)))
-        (take 2
-            (filter
-                (fn [t] (and
-                        (= (:tag t) :pod)
-                        (not (empty? (get-all-plaintext-lines t)))
-                        ))
-                (:content xmldoc)))))
+            (map (fn [a] (a (:attrs t))) attrs))
+        (filter (fn [t] (= (:tag t) parent-tag))
+            (:content xmldoc))))
+
+(defn extract-languagemsg [xmldoc]
+    (extract-top-level-errors xmldoc :languagemsg [:other :english]))
+
+(defn extract-futuretopic [xmldoc]
+    (extract-top-level-errors xmldoc :futuretopic [:topic :msg]))
+
+(defn get-results [xmldoc query]
+    (if (= (:success (:attrs xmldoc)) "true")
+        (mapcat
+            (fn [t]
+                (let [[l & ls] (get-all-plaintext-lines t)]
+                    (concat
+                        [(str (:title (:attrs t)) ": " l)]
+                        ls)))
+            (take 2
+                (filter
+                    (fn [t] (and
+                            (= (:tag t) :pod)
+                            (not (empty? (get-all-plaintext-lines t)))
+                            ))
+                    (:content xmldoc))))
+        (concat
+            [(str "Something went wrong, try the website for a better debug: http://www.wolframalpha.com/input/?i=" (url-encode query))]
+            (extract-languagemsg xmldoc)
+            (extract-futuretopic xmldoc)
+            (extract-tips xmldoc)
+            (extract-didyoumeans xmldoc)
+)))

 (defn make-query-url [query appid]
     (str "http://api.wolframalpha.com/v2/query?input=" (url-encode query) "&appid=" (url-encode appid)))
@@ -47,7 +90,7 @@
     (let [
         query-url (make-query-url query appid)
         response-xml (clojure.xml/parse query-url)
-        result (get-results response-xml)
+        result (get-results response-xml query)
         ]
         (println query)
         (println query-url)


optimize sequence of structurepaths to not add additional overhead by coercing to structurevalspath

--- src/clj/com/rpl/specter/impl.clj
+++ src/clj/com/rpl/specter/impl.clj
@@ -88,11 +88,11 @@
         selector (:select* pimpl)
         updater (:update* pimpl)]
     (->TransformFunctions
-      StructureValsPathExecutor
-      (fn [vals structure next-fn]
-        (selector this structure (fn [structure] (next-fn vals structure))))
-      (fn [vals structure next-fn]
-        (updater this structure (fn [structure] (next-fn vals structure))))
+      StructurePathExecutor
+      (fn [structure next-fn]
+        (selector this structure next-fn))
+      (fn [structure next-fn]
+        (updater this structure next-fn))
     )))

 (defn obj-extends? [prot obj]
@@ -117,39 +117,70 @@
       )))

+(defn extype [^TransformFunctions f]
+  (let [^ExecutorFunctions exs (.executors f)]
+    (.type exs)
+    ))
+
+(defn- combine-same-types [[^TransformFunctions f & _ :as all]]
+  (let [^ExecutorFunctions exs (.executors f)
+
+        t (.type exs)
+
+        combiner
+        (if (= t :svalspath)
+          (fn [curr next]
+            (fn [vals structure next-fn]
+                    (curr vals structure
+                          (fn [vals-next structure-next]
+                            (next vals-next structure-next next-fn)
+                            ))))
+          (fn [curr next]
+            (fn [structure next-fn]
+              (curr structure (fn [structure] (next structure next-fn)))))
+          )]
+
+    (reduce (fn [^TransformFunctions curr ^TransformFunctions next]
+              (->TransformFunctions
+                exs
+                (combiner (.selector curr) (.selector next))
+                (combiner (.updater curr) (.updater next))
+                ))
+             all)))
+
+(defn coerce-structure-vals [^TransformFunctions tfns]
+  (condp = (extype tfns)
+    :svalspath
+    tfns
+
+    :spath
+    (let [selector (.selector tfns)
+          updater (.updater tfns)]
+      (->TransformFunctions
+        StructureValsPathExecutor
+        (fn [vals structure next-fn]
+          (selector structure (fn [structure] (next-fn vals structure))))
+        (fn [vals structure next-fn]
+          (updater structure (fn [structure] (next-fn vals structure))))
+        ))))
+
 (extend-protocol StructureValsPathComposer
   Object
   (comp-paths* [sp]
     (coerce-path sp))
   java.util.List
   (comp-paths* [structure-paths]
-    ;;TODO: need to get smart here
-    ;;   - select/update become stupid and just run execute-select / execute-update
-    ;; - coerce-path doesn't go all the way to structurevalspath interface but actually keeps things as is
-    ;;     (except for collector)
-    ;; - compose together consecutive structurepaths and consecutive structurevalspath
-    ;; - if only one structurepath remaining, return that
-    ;;    - otherwise coerce structurepath to structurevalspath and finish combining
-    (reduce (fn [^TransformFunctions sp-curr ^TransformFunctions sp]
-              (let [curr-selector (.selector sp-curr)
-                    selector (.selector sp)
-                    curr-updater (.updater sp-curr)
-                    updater (.updater sp)]
-                (->TransformFunctions
-                  StructureValsPathExecutor
-                  (fn [vals structure next-fn]
-                    (curr-selector vals structure
-                              (fn [vals-next structure-next]
-                                (selector vals-next structure-next next-fn)
-                                )))
-                  (fn [vals structure next-fn]
-                    (curr-updater vals structure
-                              (fn [vals-next structure-next]
-                                (updater vals-next structure-next next-fn)
-                                )))
-                  )))
-          (map coerce-path structure-paths))
-    ))
+    (let [combined (->> structure-paths
+                        (map coerce-path)
+                        (partition-by extype)
+                        (map combine-same-types)
+                        )]
+      (if (= 1 (count combined))
+        (first combined)
+        (->> combined
+             (map coerce-structure-vals)
+             combine-same-types)
+        ))))

 ;; cell implementation idea taken from prismatic schema library
 (definterface PMutableCell


implement Paige Piper

implement Paige Piper

--- src/clj/game/cards-resources.clj
+++ src/clj/game/cards-resources.clj
@@ -294,6 +294,26 @@
                                                            :effect (effect (gain :credit 1))} card nil)))))
     :leave-play (req (remove-watch state :order-of-sol))}

+   "Paige Piper"
+   (let [pphelper (fn [card cards]
+                    (let [num (count cards)]
+                      {:req (req (> num 0))
+                       :prompt (str "Trash how many copies of " (:title card) "?")
+                       :choices {:number (req num)}
+                       :effect (req (doseq [c (take (int target) cards)]
+                                      (trash state side c))
+                                    (when (> (int target) 0)
+                                      (shuffle! state :runner :deck)
+                                      (system-msg state side (str "trashes " (int target)
+                                                                  " cop" (if (> (int target) 1) "ies" "y")
+                                                                  " of " (:title card)))))}))]
+    {:events {:runner-install {:req (req (first-event state side :runner-install))
+                               :effect (effect (resolve-ability
+                                                (pphelper target (->> (:deck runner)
+                                                                      (filter #(has? % :title (:title target)))
+                                                                      (vec)))
+                                                card nil))}}})
+
    "Paparazzi"
    {:effect (req (swap! state update-in [:runner :tagged] inc))
     :events {:pre-damage {:req (req (= target :meat)) :msg "prevent all meat damage"
@@ -548,3 +568,4 @@
                                 (remove-watch state (keyword (str "zona-sul-shipping" (:cid card))))
                                 (trash ref :runner card)
                                 (system-msg ref side "trash Zona Sul Shipping for being tagged")))))}})
+


fix Rolodex typo

fix Rolodex typo

--- src/clj/game/cards-resources.clj
+++ src/clj/game/cards-resources.clj
@@ -510,7 +510,7 @@
    "Rolodex"
    {:effect (req (prompt! state side card
                           (str "Drag cards from the play area back onto your Stack") ["OK"] {})
-                 (doseq [c (take 5 (:deck runner))] (move state side c :play-area)))
+                 (doseq [c (take 5 (:deck runner))] (move state side c :play-area)))}

    "Sacrificial Clone"
    {:prevent {:damage [:meat :net :brain]}


Fixed typo in namespace name

Fixed typo in namespace name

--- src/emender_service/config.clj
+++ src/emender_service/config.clj
@@ -10,7 +10,7 @@
 ;      Pavel Tisnovsky
 ;

-(ns emeder-service.config)
+(ns emender-service.config)

 (require '[clojure.pprint :as pprint])


fix compilation problem in openjdk7

fix compilation problem in openjdk7

--- src/clj/hsm/controllers/main.clj
+++ src/clj/hsm/controllers/main.clj
@@ -2,7 +2,9 @@
 	(:require
 		[hsm.ring 		:refer [html-resp]]
 		[hsm.views 		:refer :all]
-		[hsm.utils 		:refer [host-of id-of]]))
+		[hsm.utils 		:refer [host-of id-of cutoff]]
+		[hsm.helpers  :refer [pl->lang]]
+		[hsm.actions 	:refer [list-top-proj]]))

 (defn homepage
 	[[db event-chan] request]
@@ -24,8 +26,8 @@
 (defn platform
 	[[db event-chan] request]
 	(let [host (host-of request)
-				pl   (hsm.helpers/pl->lang (id-of request :platform))
-				top-projects (hsm.actions/list-top-proj db pl 10)]
+				pl   (pl->lang (id-of request :platform))
+				top-projects (list-top-proj db pl 10)]
 		(html-resp
 			(layout host
 				[:div
@@ -56,8 +58,6 @@
 										(for [x top-projects]
 											[:li
 												[:a {:href (str "/p/"(:full_name x))} (:full_name x)
-												[:p {:style "color:gray"} (hsm.utils/cutoff (:description x) 50)]]
+												[:p {:style "color:gray"} (cutoff (:description x) 50)]]
 												]
-											)]
-
-								]]]]]))))
+											)]]]]]]))))


Ball now starts towards certain degrees.

--- src/cljs/clj_mini_apps/pong.cljs
+++ src/cljs/clj_mini_apps/pong.cljs
@@ -33,12 +33,16 @@
     (q/rect 1040 250 paddle-width paddle-height)
     (q/ellipse 550 250 ball-size ball-size))

-  {:player {:x 59 :y 250}
-   :cpu    {:x 1040 :y 250}
-   :ball   {:x 550 :y 250
-            :dx (+ 1 (rand-nth (range 3)))
-            :dy (+ 1 (rand-nth (range 3)))}
-   :is-running? false})
+  (let [deg (rand-nth (concat (range 135 225)
+                              (range 0 45)
+                              (range 315 359)))]
+    (log (str deg \- (apply str (take 4 (str (q/radians deg))))))
+    {:player {:x 59 :y 250}
+     :cpu    {:x 1040 :y 250}
+     :ball   {:x 550 :y 250
+              :dx (- (* 4 (q/cos (q/radians deg))))
+              :dy    (* 4 (q/sin (q/radians deg)))}
+     :is-running? false}))

 (defn move-player-paddle
   [state direction]


fix import link

fix import link

--- src/cljs/salava/badge/ui/my.cljs
+++ src/cljs/salava/badge/ui/my.cljs
@@ -80,7 +80,7 @@
     (into [:div#grid {:class "row wrap-grid"}
            (when-not (private?)
              [:div#import-badge {:key   "new-badge"}
-            [:a.add-element-link {:href  "#" :on-click #(js-navigate-to "badge/import")}
+            [:a.add-element-link {:href  (path-for "/badge/import") }
              [:div {:class "media grid-container"}
               [:div.media-content
                [:div.media-body


Trace caching

Trace caching

--- src/com/wsscode/pathom/core.cljc
+++ src/com/wsscode/pathom/core.cljc
@@ -14,7 +14,8 @@
     [com.wsscode.pathom.specs.query :as spec.query]
     [clojure.set :as set]
     [clojure.walk :as walk]
-    #?(:cljs [goog.object :as gobj]))
+    #?(:cljs [goog.object :as gobj])
+    [com.wsscode.pathom.trace :as pt])
   #?(:clj
      (:import (clojure.lang IAtom IDeref))))

@@ -781,22 +782,25 @@
 (defmacro cached [env key body]
   `(if-let [cache# (get ~env ::request-cache)]
      (if-let [hit# (get @cache# ~key)]
-       (casync/throw-err hit#)
-       (casync/if-cljs
-         (com.wsscode.common.async-cljs/let-chan [hit# (try
-                                                         ~body
-                                                         (catch #?(:clj Throwable :cljs :default) e#
-                                                           (swap! cache# assoc ~key e#)
-                                                           (throw e#)))]
-           (swap! cache# assoc ~key hit#)
-           hit#)
-         (com.wsscode.common.async-clj/let-chan [hit# (try
-                                                        ~body
-                                                        (catch #?(:clj Throwable :cljs :default) e#
-                                                          (swap! cache# assoc ~key e#)
-                                                          (throw e#)))]
-           (swap! cache# assoc ~key hit#)
-           hit#)))
+       (do (pt/trace ~env {::pt/event ::cache-hit ::cache-key ~key})
+           (casync/throw-err hit#))
+       (do
+         (pt/trace ~env {::pt/event ::cache-miss ::cache-key ~key})
+         (casync/if-cljs
+           (com.wsscode.common.async-cljs/let-chan [hit# (try
+                                                           ~body
+                                                           (catch #?(:clj Throwable :cljs :default) e#
+                                                             (swap! cache# assoc ~key e#)
+                                                             (throw e#)))]
+             (swap! cache# assoc ~key hit#)
+             hit#)
+           (com.wsscode.common.async-clj/let-chan [hit# (try
+                                                          ~body
+                                                          (catch #?(:clj Throwable :cljs :default) e#
+                                                            (swap! cache# assoc ~key e#)
+                                                            (throw e#)))]
+             (swap! cache# assoc ~key hit#)
+             hit#))))
      ~body))

 (defn cache-hit [{::keys [request-cache]} key value]


Fix js-obj-reader on seqs and add error-message helper

--- src/com/wsscode/pathom/core.cljc
+++ src/com/wsscode/pathom/core.cljc
@@ -78,9 +78,8 @@

 (s/def ::plugin (s/keys :opt [::wrap-read ::wrap-parser]))

-#_
-(s/def ::plugins
-  (s/with-gen (s/coll-of ::plugin :kind vector?) #(s/gen #{[]})))
+#_(s/def ::plugins
+    (s/with-gen (s/coll-of ::plugin :kind vector?) #(s/gen #{[]})))

 (s/def ::parent-join-key (s/or :prop ::spec.query/property
                                :ident ::spec.query/ident
@@ -488,7 +487,7 @@
        (if (gobj/containsKey entity js-key)
          (let [v (gobj/get entity js-key)]
            (if (js/Array.isArray v)
-             (join-seq env v)
+             (join-seq env (array-seq v))
              (if (and query (= (type v) js/Object))
                (join (assoc env entity-key v))
                (js-value-transform (:key ast) v))))
@@ -515,6 +514,10 @@
        (f (parser env tx))))})

 ; Exception
+
+(defn error-message [err]
+  #?(:clj  (.getMessage err)
+     :cljs (.-message err)))

 (defn error-str [err]
   #?(:clj


implement keyboard/raise

implement keyboard/raise

--- src/lt/objs/keyboard.cljs
+++ src/lt/objs/keyboard.cljs
@@ -159,3 +159,10 @@
                   :type :user
                   :reaction (fn [this timeout]
                               (set! chord-timeout timeout)))
+
+(defn raise [obj k & args]
+  (loop [reactions (-> @obj :listeners k)]
+    (when (seq reactions)
+      (set! *capture* true)
+      (object/raise* obj [(first reactions)] args k)
+      (when-not *capture* (recur (rest reactions))))))


consistent capitalization

consistent capitalization

--- frontend/components/project_settings.cljs
+++ frontend/components/project_settings.cljs
@@ -349,7 +349,7 @@
            " These " [:em "are"] " works-in-progress, though, and there may be some sharp edges. Be careful!"]
           [:ul
            (describe-flag {:flag :junit
-                           :title "JUnit Support"
+                           :title "JUnit support"
                            :blurb [:p
                                    "We've been experimenting with better ways to display and manage "
                                    "test result data, especially for large test suites. This adds flags "
@@ -357,7 +357,7 @@
                                    "JUnit-compatabile test runners. It only works for a handful of test "
                                    "runners for now, and the data is only available through our API, though!"]})
            (describe-flag {:flag :set-github-status
-                           :title "GitHub Status Updates"
+                           :title "GitHub Status updates"
                            :blurb [:p
                                    "By default, we update the status of every pushed commit with "
                                    "GitHub's status API. If you'd like to turn this off (if, for example, "
@@ -370,11 +370,11 @@
                                    "builds to use it and let others see your builds, both through the "
                                    "web UI and the API."]})
            (describe-flag {:flag :build-fork-prs
-                           :title "Project Fork Pull Requests"
+                           :title "Project fork pull requests"
                            :blurb [:p
                                    "CircleCI will automatically update the commit status shown on GitHub's "
-                                   "pull request page. Builds will count against the parent repository's plan "
-                                   "and will be able to access the parent's project and environment settings."
+                                   "pull request page. Builds will will be run using the parent repository's plan "
+                                   "and will be able to access the parent project's environment settings."
                                    :p
                                    "If you have SSH keys or AWS credentials stored in your project settings and "
                                    "untrusted forks can make pull requests against your repo, then this option "


strip leading slash before setting token

--- frontend/controllers/post_navigation.cljs
+++ frontend/controllers/post_navigation.cljs
@@ -20,7 +20,10 @@

 (defmethod post-navigated-to! :navigate!
   [history-imp to path previous-state current-state]
-  (.setToken history-imp path))
+  (let [path (if (= \/ (first path))
+               (subs path 1)
+               path)]
+    (.setToken history-imp path)))

 (defmethod post-navigated-to! :dashboard
   [history-imp to args previous-state current-state]


adding naive rpm and speed to data model

--- sr-client/app/src/sr_client/behavior.clj
+++ sr-client/app/src/sr_client/behavior.clj
@@ -27,6 +27,18 @@
 (defn inc-transform [old_value _]
   ((fnil inc 0) old_value))

+(def max-rpm 15000)
+
+(defn get-speed [old_value {:keys [gear rpm]}]
+  (if (nil? old_value)
+    5
+    (+ old_value (* old_value 0.05 (- 1 (/ rpm max-rpm))))))
+
+(defn get-rpm [old_value {:keys [gear time]}]
+  (if (nil? old_value)
+    100
+    (+ old_value (* max-rpm 0.05))))
+
 (defn init-main [_]
   [[:transform-enable [:main :my-car :gear]
     :shift-gear [{msg/topic [:my-car :gear]}]]
@@ -42,12 +54,16 @@
    :emit [{:init init-main}
           [#{[:my-car :gear]
              [:time]
+             [:rpm]
+             [:speed]
              [:other-players :*]
              [:total-count]
              [:total-gears]} (app/default-emitter [:main])]
           [#{[:pedestal :debug :*]} (app/default-emitter [])]]
    :effect #{[#{[:my-car]} publish-player :single-val]}
    :derive #{[{[:my-car] :me [:other-players] :others} [:players] merge-players :map]
+             [{[:my-car :gear] :gear [:rpm] :rpm} [:speed] get-speed :map]
+             [{[:my-car :gear] :gear [:time] :time} [:rpm] get-rpm :map]
              [#{[:players :*]} [:total-count] total-count :vals]
              [#{[:players :* :gear]} [:total-gears] sum-all :vals]}
    :debug true})


add icon for chat sound

add icon for chat sound


Use aggregate reactions instead of plain reactions list in render-entry-list.

--- src/oc/storage/representations/entry.clj
+++ src/oc/storage/representations/entry.clj
@@ -8,7 +8,8 @@
             [oc.storage.representations.org :as org-rep]
             [oc.storage.urls.board :as board-url]
             [oc.storage.representations.content :as content]
-            [oc.storage.lib.sort :as sort]))
+            [oc.storage.lib.sort :as sort]
+            [oc.storage.resources.reaction :as reaction-res]))

 (def org-prop-mapping {:uuid :org-uuid
                        :name :org-name
@@ -250,7 +251,7 @@
                     :links full-links
                     :items (map #(entry-and-links org board %
                                     (or (filter :body (:interactions %)) [])  ; comments only
-                                    (or (filter :reaction (:interactions %)) []) ; reactions only
+                                    (reaction-res/aggregate-reactions (or (filter :reaction (:interactions %)) [])) ; reactions only
                                     access-level user-id)
                              entries)}}
       {:pretty config/pretty?})))


Remove commented code.

Remove commented code.

--- frontend/src/uxbox/main/ui/workspace.cljs
+++ frontend/src/uxbox/main/ui/workspace.cljs
@@ -53,8 +53,7 @@
     (scroll-to-page-center)

     (st/emit! (udp/watch-page-changes pageid)
-              (udu/watch-page-changes pageid)
-              #_(udh/watch-page-changes pageid))
+              (udu/watch-page-changes pageid))

     (assoc own ::sub sub)))

@@ -72,8 +71,7 @@
       (st/emit! (dw/initialize projectid pageid)
                 ::udp/stop-page-watcher
                 (udp/watch-page-changes pageid)
-                (udu/watch-page-changes pageid)
-                #_(udh/watch-page-changes pageid)))
+                (udu/watch-page-changes pageid))
     state))

 (defn- on-scroll


Cleanup code.

Cleanup code.

--- src/org/spootnik/cyanite/store_cache.clj
+++ src/org/spootnik/cyanite/store_cache.clj
@@ -100,7 +100,7 @@
           (deref flusher))))))

 (defn store-chan
-  [tenant period rollup time path data ttl chan]
+  [chan tenant period rollup time path data ttl]
   (>!! chan {:tenant tenant
              :period period
              :rollup rollup
@@ -117,11 +117,7 @@
         cache-get (fn [key pkeys] (get @(get-data pkeys) key))
         cache-key (fn [tenant period rollup time path] (hash path))
         schan (store/channel-for store)
-        ;;fn-store (partial store-chan schan)
-        fn-store (fn [tenant period rollup time path data ttl]
-                   (store-chan tenant period rollup time path data ttl schan))
-        ]
-
+        fn-store (partial store-chan schan)]
     (reify
       StoreCache
       (put! [this tenant period rollup time path data ttl]
@@ -129,11 +125,7 @@
               pkeys (set-keys! mkeys tenant period rollup time path ttl
                                cache-get fn-agg fn-store cache-key)
               adata (get-data @pkeys)]
-          (swap! adata #(assoc % ckey (conj (get % ckey) data)))
-          ;;(-show-keys this)
-          ;;(-show-cache this)
-          ;;(-show-meta this)
-          ))
+          (swap! adata #(assoc % ckey (conj (get % ckey) data)))))
       (flush! [this]
         (run-flusher! mkeys))
       (-show-keys [this] (debug "MKeys:" mkeys))


Changes schema to properly reflect uid map change

--- src/hphelper/shared/schema.clj
+++ src/hphelper/shared/schema.clj
@@ -97,7 +97,7 @@
   ;; Cbay items up for sale. Includes time left in the string for now
   {:cbay [s/Str]
    ;; A list of all the player characters
-   :hps {s/Int playerCharacter}
+   :hps {s/Str playerCharacter}
    ;; A list of all the secret society missions
    :societies [scenSocietySingle]
    ;; Name of the zone


make connection info blocks clickable

make connection info blocks clickable

--- src/cljs/salava/extra/socialuser/ui/connections.cljs
+++ src/cljs/salava/extra/socialuser/ui/connections.cljs
@@ -7,7 +7,8 @@
             [salava.user.ui.helper :refer [profile-picture]]
             [salava.core.i18n :refer [t]]
             [reagent-modals.modals :as m]
-            [salava.core.ui.layout :as layout]))
+            [salava.core.ui.layout :as layout]
+            [reagent.session :as session]))

 (defn init-data [state]
@@ -15,7 +16,8 @@
     (path-for (str "/obpv1/socialuser/connections" ))
     {:handler (fn [data]
                 (swap! state assoc :followers-users (:followers-users data)
-                       :following-users (:following-users data)))}))
+                       :following-users (:following-users data)
+                       :visible-area (session/get! :visible-area nil)))}))

@@ -157,18 +159,22 @@
     (fn []
       [:div
        [:div.info-block
-        ;[:a {:href (path-for "/connections/user")}
+        [:a {:href (path-for "/connections/user") :on-click #(do
+                                                               (.preventDefault %)
+                                                               (session/put! :visible-area :accepted) )}
          [:div.info
           ;[:i.fa.fa-user.icon]
           [:div.text
            [:p.num (->> (:following-users @state) count)]
            [:p.desc (t :social/Followedusers)]
            ]]
-         ;]
+         ]
         ]

        [:div.info-block
-        ;[:a {:href (path-for "/connections/user")}
+        [:a {:href (path-for "/connections/user")  :on-click #(do
+                                                                (.preventDefault %)
+                                                                (session/put! :visible-area :pending) )}
          [:div.info
           (when (pos? (count (:pending @state))) [:span.badge (count (:pending @state))])
           ;[:i.fa.fa-user.icon]
@@ -176,8 +182,8 @@
            [:p.num (->> (:followers-users @state) count)]
            [:p.desc (t :social/Followersusers)]
            ]
-          ;]
-        ]]])))
+          ]
+         ]]])))

 (defn handler [site-navi]
   (let [state (atom {:visible-area  nil


Fix typo.

Fix typo.

--- src/onyx/logger.clj
+++ src/onyx/logger.clj
@@ -122,7 +122,7 @@
     component)

   (stop [component]
-    (info "Stopping Virtual Peer")
+    (info "Stopping Logger")

     component))


Reindent and rough in actions div

Reindent and rough in actions div

--- src-cljs/frontend/components/pages/workflow.cljs
+++ src-cljs/frontend/components/pages/workflow.cljs
@@ -42,19 +42,19 @@
         (card/basic
          (element :content
            (html
-            [:div
-             #_[:.status (status/badge (status-class status) (name status))]
-             [:.status {:class (name status)}
-              [:span.status-icon {:class (name status)}
+             [:div
+              #_[:.status (status/badge (status-class status) (name status))]
+              [:div.status {:class (name status)}
+               [:span.status-icon {:class (name status)}
                (case (status-class status)
                  :status-class/failed (icon/status-failed)
                  :status-class/stopped (icon/status-canceled)
                  :status-class/succeeded (icon/status-passed)
                  :status-class/running (icon/status-running)
                  :status-class/waiting (icon/status-queued))]
-              [:.status-string (name status)]]
-             [:div.metadata
-              [:div.metadata-row.timing
+               [:.status-string (name status)]]
+              [:div.metadata
+               [:div.metadata-row.timing
                [:span.metadata-item.recent-time.start-time
                 [:i.material-icons "today"]
                 [:span.started-at {:title (str "Started: " (datetime/full-datetime started-at))}
@@ -64,13 +64,15 @@
                 [:span.duration {:title (str "Duration: " (datetime/as-duration (- stopped-at started-at)))}
                  (build-legacy common/updating-duration {:start started-at
                                                          :stop stopped-at})]]]
-              [:div.metadata-row.pull-revision
-               [:span.metadata-item.pull-requests {:title "Pull Requests"}
-                (icon/git-pull-request)
-                [:a "#1234"]]
-               [:span.metadata-item.revision
-                [:i.octicon.octicon-git-commit]
-                [:a "1234345"]]]]])))))))
+               [:div.metadata-row.pull-revision
+                [:span.metadata-item.pull-requests {:title "Pull Requests"}
+                 (icon/git-pull-request)
+                 [:a "#1234"]]
+                [:span.metadata-item.revision
+                 [:i.octicon.octicon-git-commit]
+                 [:a "1234345"]]]]
+              [:div.actions
+               ]])))))))

 (def run (om-next/factory Run {:keyfn :run/id}))


prevent exception when sorting fails

prevent exception when sorting fails

git-svn-id: 03a8048b5ee8463be5048a3801110fb50f378627@7130 d0ab736e-dc22-4aeb-8dc9-08def0aa14fd

--- plugins/DataBrowser/src/org/micromanager/browser/core.clj
+++ plugins/DataBrowser/src/org/micromanager/browser/core.clj
@@ -474,10 +474,12 @@
           (.setPreferredWidth (* total-width (:width col))))))
     ;(println "sorted-column" sorted-column :model-column)
     (when sorted-column
+    (try
       (.. table getRowSorter
           (setSortKeys (list (RowSorter$SortKey.
                                (.indexOf tags (sorted-column :model-column))
-                               (nth (SortOrder/values) (sorted-column :order)))))))
+                               (nth (SortOrder/values) (sorted-column :order))))))
+      (catch Exception e nil)))
     (-> @settings-window :columns :table
                          .getModel .fireTableDataChanged))
   (update-browser-status))


filter out fails before calling do-defaults

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -317,6 +317,9 @@
                          truncate-children)
                   (truncate unified [path] language-model)
                   unified))))
+
+     (filter #(not-fail? %))
+
      (mapfn (fn [tree]
               (do-defaults tree language-model))))))


more improvements for (defn add-complement-to-bolt)

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -197,14 +197,16 @@
                 (flatten (vals lexicon)))))

         complement-pre-check (fn [child child-in-bolt]
+                               (log/trace (str "child-in-bolt: " (strip-refs child-in-bolt)))
+                               (log/trace (str "child: " (strip-refs child)))
                                (not (fail?
-                                     (unifyc child
-                                             child-in-bolt))))
+                                     (unify child
+                                            child-in-bolt))))

         filtered-lexical-complements (lazy-shuffle
                                       (filter (fn [lexeme]
-                                                (complement-pre-check (get-in lexeme [:synsem] :top)
-                                                                      (get-in bolt (concat path [:synsem]) :top)))
+                                                (complement-pre-check (strip-refs (get-in lexeme [:synsem] :top))
+                                                                      (strip-refs (get-in bolt (concat path [:synsem]) :top))))
                                               complement-candidate-lexemes))]
     (filter #(not (fail? %))
             (mapfn (fn [complement]


change initial state of atom

change initial state of atom

--- src/background_on/web.clj
+++ src/background_on/web.clj
@@ -7,7 +7,7 @@
             [background-on.nyt :as nyt])
   (:gen-class))

-(def snapshot-json-atom (atom ""))
+(def snapshot-json-atom (atom "[]"))

 (defroutes app-routes
   (GET "/snapshot" [] @snapshot-json-atom)


cleanup header ns

cleanup header ns

--- src/cljs/swarmpit/component/header.cljs
+++ src/cljs/swarmpit/component/header.cljs
@@ -58,8 +58,7 @@
          {:key       "appbar-user-menu-logged-info"
           :className "Swarmpit-appbar-user-menu-logged-info"
           :disabled  true}
-         (rum/with-key
-           (user-info) "appbar-user-menu-sign-info"))
+         (user-info))
        (comp/divider
          {:key "appbar-user-menu-divider"})
        (comp/menu-item


Add hansen value to results

Add hansen value to results

--- src/clj/forma/hadoop/jobs/postprocess.clj
+++ src/clj/forma/hadoop/jobs/postprocess.clj
@@ -217,8 +217,9 @@

 (defn forma->david
   "Prep data for David."
-  [nodata src]
-  (<- [?lat ?lon ?clean-probs ?gadm2 ?ecoid]
+  [nodata src static-src]
+  (<- [?lat ?lon ?clean-probs ?gadm2 ?ecoid ?hansen]
       (src ?s-res ?mod-h ?mod-v ?sample ?line ?start-final ?merged-series ?gadm2 ?ecoid)
+      (static-src ?s-res ?mod-h ?mod-v ?sample ?line _ _ _ ?hansen _)
       (r/modis->latlon ?s-res ?mod-h ?mod-v ?sample ?line :> ?lat ?lon)
       (o/clean-probs ?merged-series nodata :> ?clean-probs)))


Require clojure.string/join into side-panel

--- src/cljs/gtfve/components/side_panel.cljs
+++ src/cljs/gtfve/components/side_panel.cljs
@@ -1,5 +1,6 @@
 (ns gtfve.components.side-panel
-  (:require [om.core :as om]
+  (:require [clojure.string :refer [join]]
+            [om.core :as om]
             [sablono.core :as html :refer-macros [html]]
             [gtfve.async :refer [raise!]]
             [gtfve.state :as state]))
@@ -35,10 +36,10 @@
                [:div.tab-content
                 ;; stops
                 [:div.wrapper
-                 [:div {:className (clojure.string/join " "
-                                                        ["tab-pane" "fade" "side"
-                                                         (when (= tab :stops)
-                                                           "active in")])}
+                 [:div {:className (join " "
+                                         ["tab-pane" "fade" "side"
+                                          (when (= tab :stops)
+                                            "active in")])}
                   [:form.form-horizontal
                    [:fieldset
                     [:div.form-group
@@ -56,14 +57,14 @@
                      [:th "Lat/Lng"]]]
                    [:tbody]]]]
                 ;; routes
-                [:div {:className (clojure.string/join " "
-                                                       ["tab-pane" "fade" "side"
-                                                        (when (= tab :routes)
-                                                          "active in")])}
+                [:div {:className (join " "
+                                        ["tab-pane" "fade" "side"
+                                         (when (= tab :routes)
+                                           "active in")])}
                  [:p "Routes panel"]]
                 ;; trips
-                [:div {:className (clojure.string/join " "
-                                                       ["tab-pane" "fade" "side"
-                                                        (when (= tab :trips)
-                                                          "active in")])}
+                [:div {:className (join " "
+                                        ["tab-pane" "fade" "side"
+                                         (when (= tab :trips)
+                                           "active in")])}
                  [:p "Trips panel"]]]])))))


Make number of points in tailsping depend on sketch size.

--- src/cljs/quil_site/examples/tailspin.cljs
+++ src/cljs/quil_site/examples/tailspin.cljs
@@ -5,12 +5,15 @@

 (defn setup []
   (q/frame-rate 30)
-  (let [max-r (/ (q/width) 2)]
+  (let [max-r (/ (q/width) 2)
+        n (int (q/map-range (q/width)
+                            200 500
+                            20 50))]
    {:dots (into [] (for [r (map #(* max-r %)
-                                (range 0 1 0.05))]
+                                (range 0 1 (/ n)))]
                      [r 0]))}))

-(def speed 0.0005)
+(def speed 0.0003)
 (def speed 0.001) ; hack to make it faster on in small size ;DELETE

 (defn move [dot]


hpass privacy policy

hpass privacy policy

--- src/cljs/salava/extra/hpass/ui/block.cljs
+++ src/cljs/salava/extra/hpass/ui/block.cljs
@@ -6,7 +6,7 @@
    [:div.green-banner]
    [:div.login_top
     [:h1
-    "Welcome to myHPass"]
+     "Welcome to myHPass"]
     [:hr]]]
   )

@@ -20,25 +20,184 @@
    [:br]
    [:br]
    [:div.footer]
-  ])
+   ])

 (defn ^:export footer []
   [:footer.footer
    [:div.footer-container
-       [:p.text-muted
-      "Copyright © 2018 Humanitarian Leadership Academy | "
+    [:p.text-muted
+     "Copyright © 2018 Humanitarian Leadership Academy | "
      [:a {:class "bottom-link" :href "mailto:info@hpass.org" }
       "info@hpass.org"]
-       " | "
+     " | "
      [:a {:class "bottom-link" :href "/terms" }
       "Privacy Policy and Terms of Use"]

-    ]]])
+     ]]])

 (defn ^:export terms []
-  [:div {:style {:padding "10px"}}
+  [:div {:style {:padding "30px"}}
    [:div
-    [:p {:style {:text-align "center"}} "Read our privacy policy from "  [:a {:href "https://hpass.org/privacy-policy/"} [:b "here"]]]]])
+    [:h1 {:style {:text-align "center"}} [:b "PRIVACY POLICY"]]
+    [:p "This Privacy Policy covers the information practices of the HPass platform (my.hpass.org) and the website which is used to access the HPass platform (hpass.org) (Site). The data controller of this website is the Humanitarian Leadership Academy (Academy), a charity registered in England and Wales (1161600) and a company limited by guarantee in England and Wales (9395495). The Academy’s registered office is at 1 St John’s Lane, London, EC1M 4AR"]
+    [:p "The Academy believes strongly in protecting your privacy and the confidentiality of your Personal Information. We acknowledge that you may have privacy and security concerns with respect to the information we collect, use, and disclose to third parties for the purpose of allowing us to offer and provide our products and services to you. In order to comply with privacy legislation, we have developed this Privacy Policy. Personal information is any combination of information, in the possession of or likely to come into the possession of the Academy, that can be used to identify, contact, or locate a discrete individual (“Personal Information”) and will be treated in accordance with this Privacy Policy. This includes any expression of opinion about such individual. Any information which cannot be used to identify a discrete individual (such as aggregated statistical information) is not Personal Information."]]
+   [:div
+    [:h2 [:b "PURPOSE FOR COLLECTION, USE AND DISCLOSURE OF PERSONAL INFORMATION"]]
+    [:p "The Academy processes your Personal Information for the legitimate interest of fulfilling the mission and vision of the Academy as a humanitarian, not-for-profit organization. In furtherance of this legitimate interest, the Academy collects, uses and discloses your Personal Information (including individuals associated with you, all of whom are referred to as “you” in this Privacy Policy) in its normal course of operating the Site for the following purposes:"]
+    [:ul
+     [:li [:p "Establishing and maintaining our communications with you;"]]
+     [:li [:p "Publishing humanitarian credentials;"]]
+     [:li [:p "Development and delivery of learning and credentialing services;"]]
+     [:li [:p "Responding to your inquiries about badging opportunities, humanitarian aid opportunities, and other award and learning services;"]]
+     [:li [:p "Enabling your communications with other users of the Site; including learning providers, badge providers, aid organizations, and other individuals with similar interests;"]]
+     [:li [:p "Connecting you with others who share the same interests and commitment to humanitarian aid; Meeting legal, security, and regulatory requirements;"]]
+     [:li [:p "Protecting against fraud, suspicious or other illegal activities; and"]]
+     [:li [:p "Compiling statistics for analysis of our sites and our business."]]]]
+   [:div
+    [:h2 [:b "WHAT INFORMATION WE COLLECT"]]
+    [:p "The information gathered by the Academy from this Site falls into two categories: (1) information voluntarily supplied by visitors to our Site and (2) tracking information gathered as visitors navigate through our Site."]
+    [:div
+     [:h3 [:b "INFORMATION VOLUNTARILY PROVIDED BY YOU"]]
+     [:p "When using this Site, you may choose to provide us with information to help us serve your needs. The Personal Information that we collect will depend on how you choose to use this Site."]
+     [:ul
+      [:li [:p "Where you request information:"]
+       [:p "If you request a brochure or further information from us, we require you to submit your name, e-mail address, the name of your organization, and the country in which you are based so we may send you the material you have requested, and to enable us to identify if you have an existing relationship with the Academy."]]
+      [:li
+       [:p "Where you register with us and/or request services:"]
+       [:p "If you register with the Site, or request a service available on the Site (via another organization or a learning/badging provider), we may ask you for your name, e-mail address, country, telephone number and the reason for your communication, as well as information about your position and organization and such other information as is reasonably necessary so that we can facilitate the service. On the data submission form, we shall indicate by way of an asterisk, which information is optional and which information is mandatory. This information can include:"]
+       [:ol {:style {:list-style-type "circle"}}
+        [:li [:p "Information you provide on applications or other forms, which may include your name, address, email address, age, medical and health information, employment and educational information, and any awards or credentials you may possess;"]]
+        [:li [:p "Information we acquire from and/or transfer to other persons (such as learning providers, industry associations, credentialing providers, humanitarian aid organizations, and your employer) to verify your identity and the accuracy of the information you have provided;"]]
+        [:li [:p "Information about you received from the Academy affiliates, other intermediaries, third party providers and others which are necessary for the provision of the HPass platform; and"]]
+        [:li [:p "Information we receive from background verification companies."]]]
+       [:p "Any Personal Information that you send us will be used for the purpose indicated on the Site or in this Privacy Policy.Following an inquiry into receiving services from us, if you decide to proceed, we will collect Personal Information necessary to proceed with a transaction, such as your name, address, post code, contact telephone number, e-mail address, and other Personal Information as relevant to the service or credential. We will use your Personal Information to administer your account, coordinate services, etc. and generally manage your relationship with us. We shall pass your personal data to other users of the Site (including humanitarian aid agencies, learning service providers, and credentialing providers) as is necessary to enable the services and activities to which you have indicated an interest. Please see the Disclosure of Your Information section below for information on the categories of recipients of your personal data."]
+       ]
+      [:li [:p "Where you submit content:"]
+       [:p "Finally, when you submit content regarding any of the information that you view on our Site, we will ask for your name and e-mail address, so that, if you choose, we can update you by e-mail when others also comment on the content, and also so that we can manage the content in line with our HPass Platform Terms and Conditions. You should be aware that the information you provide to the social network features of the Site will be made publically available to the Academy employees and other users of the Site. "]]]]
+    [:div
+     [:h3 [:b "WEBSITE NAVIGATIONAL INFORMATION"]]
+     [:p "As you navigate the Site, we may also collect information through the use of commonly-used information-gathering tools, such as cookies and web beacons (collectively “Website Navigational Information”). Website Navigational Information includes standard information from your web browser (such as browser type and browser language), your Internet Protocol (“IP”) address, and the actions you take on the Site (such as the web pages viewed and the links clicked)."]
+     [:p {:style {:font-size "20px"}} "Cookies"]
+     [:p "Like many companies, we may use cookies on this Site. Cookies are pieces of information shared between your web browser and a website. Use of cookies enables a faster and easier experience for the user. A cookie cannot read data off your computer’s hard drive."]
+     [:p "There are different kinds of cookies with different functions:"]
+     [:ul {:style {:list-style-type "lower-roman"}}
+      [:li [:p "Session cookies: these are only stored on your computer during your web session. They are automatically deleted when the browser is closed. They usually store an anonymous session ID allowing you to browse a website without having to log in to each page. They do not collect any information from your computer."]]
+      [:li [:p "Persistent cookies: a persistent cookie is one stored as a file on your computer, and it remains there when you close your web browser. The cookie can be read by the website that created it when you visit that website again."]]
+      [:li [:p "First-party cookies: the function of this type of cookie is to retain your preferences for a particular website for the entity that owns that website. They are stored and sent between the Academy’s servers and your computer’s hard drive. They are not used for anything other than for personalization as set by you. These cookies may be either Session or Persistent cookies."]]
+      [:li [:p "Third-party cookies: the function of this type of cookie is to retain your interaction with a particular website for an entity that does not own that website. They are stored and sent between the Third-party’s server and your computer’s hard drive. These cookies are usually Persistent cookies."]]
+      ]
+     [:p "Except as described in this Privacy Policy, we do not use third-party cookies on our Sites, although we do use third party provided web beacons (please see the section on Web Beacons below)."]
+     [:p "This Site does use Google Analytics, a web analytics service provided by Google, Inc. (“Google”). Google Analytics uses cookies to help the website analyze how users use the site. The information generated by the cookie about your use of the website (including your IP address) will be transmitted to and stored by Google on servers in the United States. Google will use this information for the purpose of evaluating your use of the website, compiling reports on website activity, and providing other services relating to website activity and internet usage for the Academy and its affiliates. Google may also transfer this information to third parties where required to do so by law, or where such third parties process the information on Google’s behalf. Google will not associate your IP address with any other data held by Google. You may refuse the use of cookies by selecting the appropriate settings on your browser, however please note that if you do this you may not be able to use the full functionality of this website. By using this website,
+      you consent to the processing of data about you by Google in the manner and for the purposes set out above."]
+     [:p "The major browsers have attempted to implement the draft “Do Not Track” (“DNT”) standard of the World Wide Web Consortium (“W3C”) in their latest releases. As this standard has not been finalized, the Academy’s Sites are not compatible with DNT."]
+     [:p "For information on all of these categories of cookies, and for more information generally on cookies please refer to" [:a {:href "https://www.aboutcookies.org/"} " aboutcookies.org."]]
+     [:p "We use cookies for the following purposes:"]
+     [:ul
+      [:li [:p [:b "Where strictly necessary"]]
+       [:p "These cookies are essential in order to enable you to move around the Site and use its features, such as accessing secure areas of the Site. Without these cookies, services you have asked for, such as obtaining a quote or logging into your account, cannot be provided. These cookies do not gather information about you that could be used for marketing or remembering where you have been on the internet."]]
+      [:li [:p [:b "Performance"]]
+       [:p "These cookies collect information about how visitors use a Site, for instance which pages visitors go to most often, and if they get error messages from web pages. They also allow us to record and count the number of visitors to the Site, all of which enables us to see how visitors use the Site in order to improve the way that our Site works. These cookies do not collect information that identifies a person, as all information these cookies collect is anonymous and is used to improve how our Site works."]]
+      [:li [:p [:b "Functionality"]]
+       [:p "These cookies allow our Site to remember choices you make (such as your user name, language or the region you are in) and provide enhanced features. For instance, a Site may be able to remember your log in details, so that you do not have to repeatedly sign in to your account when using a particular device to access our Site. These cookies can also be used to remember changes you have made to text size, font and other parts of web pages that you can customize. They may also be used to provide services you have requested such as viewing a video or commenting on an article. The information these cookies collect is usually anonymized. They do not gather any information about you that could be used for advertising or remember where you have been on the internet."]]
+      ]
+     [:p "Please consult your web browser’s ‘Help’ documentation or visit" [:a {:href "https://www.aboutcookies.org/"} " aboutcookies.org"] " for more information about how to turn cookies on and off for your browser."]
+     [:p {:style {:font-size "20px"}}  "Web Beacons"]
+     [:p "The Site may also use web beacons (including web beacons supplied or provided by third parties) alone or in conjunction with cookies to compile information about users’ usage of the Site and interaction with e-mails from the Academy. Web beacons are clear electronic images that can recognize certain types of information on your computer, such as cookies, when you viewed a particular Site tied to the web beacon, and a description of a Site tied to the web beacon. We use web beacons to operate and improve the Sites and e-mail communications. We may use information from web beacons in combination with other data we have about our clients to provide you with information about the Academy and our services. We will conduct this review on an anonymous basis."]
+     [:p {:style {:font-size "20px"}} "IP Addresses"]
+     [:p "When you visit our Sites, the Academy collects your Internet Protocol (“IP”) addresses to track and aggregate non-Personal Information. For example, the Academy uses IP addresses to monitor the regions from which users navigate the Sites. IP addresses will be stored in such a way so that you cannot be identified from the IP address."]
+
+     ]
+    [:div
+     [:h2 [:b "DISCLOSURE OF INFORMATION TO OTHERS"]]
+     [:p "We do not disclose any Personal Information about you to any third parties except as stated in this Privacy Policy, as otherwise permitted by law, or authorized by you."]
+     [:p "Note that as HPass has social networking features, and is intended to publish your capabilities for the purpose of helping many different parties coordinate efficient and effective humanitarian aid, most participants on the HPass platform will have your Personal Information disclosed to them as a feature of HPass."]
+     [:p "Third parties to whom we disclose information are required by law and contractual undertakings to keep your Personal Information confidential and secure, and to use and disclose it for purposes that a reasonable person would consider appropriate in the circumstances, in compliance with all applicable legislation, which purposes are as follows:"]
+     [:ul
+      [:li [:p "To provide the functionality of the Site;"]]
+      [:li [:p "To notify you or allow other users of the Site to notify you of products, services, or aid opportunities offered by other users of the Site or our affiliated companies;"]]
+      [:li [:p "To update information with credentialing and learning providers;"]]
+      [:li [:p "To allow you to communicate with other users in the community of interest supported by HPass; and"]]
+      [:li [:p "To process transactions through data processing service providers."]]]
+     [:p "If these third parties wish to use your Personal Information for any other purpose, they will have a legal obligation to notify you of this and, where required, to obtain your consent. Contact us at " [:a {:href "mailto:info@hpass.org"} "info@hpass.org"] " for more information on these third parties."]
+     [:h3 [:b "AFFILIATE SHARING"]]
+     [:p "In the normal course of maintaining HPass, Personal Information may be shared within the Academy and its affiliates for all the purposes above, as well as: research and statistical purposes, system administration, and crime prevention or detection. When you supply us with information containing third party Personal Information (names, addresses, or other information relating to living individuals), we will hold and use that Personal Information to provide the functionality of the HPass platform for you on the understanding that the individuals to whom the Personal Information relates have been informed of the reason(s) for obtaining the Personal Information, the fact that it may be disclosed to third parties such as the Academy, and have consented to such disclosure and use."]
+     [:h3 [:b "SERVICE PROVIDERS"]]
+     [:p "Because a number of the service providers we use are located in the United States, including certain the Academy affiliates, your Personal Information may be processed and stored inside the United States, and the U.S. government, courts, or law enforcement or regulatory agencies may be able to obtain disclosure of your Personal Information under US laws."]
+     [:p "The Academy’s service suppliers adhere to the same protections regarding the collection, use, and retention of data as we do."]
+     [:h3 [:b "BUSINESS TRANSACTIONS"]]
+     [:p "As we continue to develop our mission, we might sell or buy assets. In such transactions, user information, including Personal Information, generally is one of the transferred assets. Also, if either the Academy itself or substantially all of the Academy assets were acquired, your Personal Information may be one of the transferred assets. Therefore, we may disclose and/or transfer your Personal Information to a third party in these circumstances"]
+     [:h3 [:b "OTHER LEGALLY REQUIRED DISCLOSURES"]]
+     [:p "The Academy preserves the right to disclose without your prior permission any Personal Information about you or your use of this Site if the Academy has a good faith belief that such action is necessary to: (a) protect and defend the rights, property or safety of the Academy, employees, other users of this Site, or the public; (b) enforce the terms and conditions that apply to use of this Site; (c) as required by a legally valid request from a competent governmental authority; or (d) respond to claims that any content violates the rights of third-parties. We may also disclose Personal Information as we deem necessary to satisfy any applicable law, regulation, legal process, or governmental request."]
+     [:p "In this Privacy Policy, the purposes identified above and in “Collection, Use and Disclosure of Personal Information” will be referred to as the “Identified Purposes.”"]
+     ]
+    [:div
+     [:h2 [:b "CALIFORNIA’S “SHINE THE LIGHT” LAW"]]
+     [:p "California Civil Code Section 1798.83 requires any operator of a website to permit its California-resident customers to request and obtain from the operator a list of what Personal Information the operator disclosed to third parties for direct marketing purposes, for the preceding calendar year; and the addresses and names of such third parties. the Academy does not share any Personal Information collected from this site with third parties for their direct marketing purposes."]
+     ]
+    [:div
+     [:h2 [:b "CONSENT"]]
+     [:p "Your knowledge of and consent to the Academy’s collection, use and disclosure of your Personal Information is critical. We rely on the following actions by you as indications of your consent to our existing and future Personal Information practices:"]
+     [:ul
+      [:li [:p "Your voluntary provision of Personal Information to us directly;"]]
+      [:li [:p "Your express consent or acknowledgement contained within a written, verbal or electronic application or claims process; and"]]
+      [:li [:p "Your verbal consent solicited by the Academy (or our agent) for a specified purpose."]]
+      ]
+     [:p "Where the Academy relies on consent for the fair and lawful processing of Personal Information, the opportunity to consent will be provided when the Personal Information in question is collected. Your consent may be given through your authorized representative such as a legal guardian, agent or holder of a power of attorney."]
+     [:p "Subject to certain legal or contractual restrictions and reasonable notice, you may withdraw this consent at any time. the Academy will inform you of the consequences of withdrawing your consent."
+      [:b " In some cases, refusing to provide certain Personal Information or withdrawing consent"] " for the Academy to collect, use or disclose your Personal Information"
+      [:b " could mean that we cannot obtain insurance coverage or other requested products, services or information for you."]]
+     [:p [:b "If you wish to withdraw your consent please refer to the Questions or to Withdraw Consent section below."]]
+     [:p [:b "However"] ", there are a number of instances where the Academy does not require your consent to engage in the processing or disclosure of Personal Information. The Academy may not solicit your consent for the processing or transfer of Personal information for the those purposes which have a statutory basis, such as:"]
+     [:ul
+      [:li [:p "The transfer or processing is necessary for the performance of a contract between you and the Academy (or one of its affiliates);"]]
+      [:li [:p "The transfer or processing is necessary for the performance of a contract, concluded in your interest, between the Academy (or one of its affiliates) and a third party;"]]
+      [:li [:p "The transfer or processing is necessary, or legally required, on important public interest grounds, for the establishment, exercise, or defense of legal claims, or to protect your vital interests; or"]]
+      [:li [:p "The transfer or processing is required, or permitted without consent, by applicable law."]]
+      ]
+     ]
+    [:div
+     [:h2 [:b "LIMITING COLLECTION AND RETENTION OF PERSONAL INFORMATION"]]
+     [:p "The Academy will collect, use, or disclose Personal Information that is necessary for the Identified Purposes or as permitted by law. If we require Personal Information for any other purpose, you will be notified of the new purpose, and subject to your consent (where appropriate), that new purpose will become an Identified Purpose."]
+     [:p "The Academy will collect Personal Information by fair and lawful means. We will normally retain Personal Information as long as necessary for the fulfillment of the Identified Purposes. However, some Personal Information may be retained for longer periods as required by law, contract, or auditing requirements."]
+
+     ]
+    [:div
+     [:h2 [:b "SAFEGUARDS"]]
+     [:p "We have in place physical, electronic and procedural safeguards appropriate to the sensitivity of the information we maintain. Safeguards will vary depending on the sensitivity, format, location, amount, distribution and storage of the Personal Information. They include physical, technical, and managerial measures to keep Personal Information protected from unauthorized access. Among such safeguards are the encryption of communications via SSL, encryption of information while it is in storage, firewalls, access controls, separation of duties, and similar security protocols. However, due to the nature of the Internet and related technology, we cannot absolutely guarantee the security of Personal Information, and the Academy expressly disclaims any such obligation."]
+     ]
+    [:div
+     [:h2 [:b "EXTERNAL LINKS"]]
+     [:p "The Academy Sites may include links to other websites whose privacy policies we do not control. Once you leave our servers (you can tell where you are by checking the URL in the location bar on your web browser), use of any Personal Information you provide is governed by the privacy policy of the operator of the website you are visiting. That policy may differ from ours. If you can’t find the privacy policy of any of these websites via a link from the website’s homepage, you should contact the website directly for more information."]
+     ]
+    [:div
+     [:h2 [:b "ACCURACY, ACCOUNTABILITY, OPENNESS AND CUSTOMER ACCESS"]]
+     [:p "Our knowing about changes to some of your Personal Information (e.g. email address) may be key to effectively communicating with you at your request.
+      If any of your details change you can update us by e-mailing us at "[:a {:href "mailto:info@hpass.org"} "info@hpass.org."]
+      [:b " Please keep us informed of changes to your Personal Information."]]
+     [:p "You have the right to access your Personal Information and request rectification of any Personal Information in the file that may be obsolete, incomplete or incorrect.
+      If you have any questions about this Privacy Policy or want to access your Personal Information, you can obtain our Personal Information Question/Request form by writing or calling our Chief Privacy Officer at the following address or visiting the
+      Site at: " [:a {:href "https://www.humanitarianleadershipacademy.org/privacy-cookie-policy/"} "www.humanitarianleadershipacademy.org/privacy-cookie-policy."]]
+     [:div
+      [:p "The Company Secretary"]
+      [:p "Humanitarian Leadership Academy"]
+      [:p "1 St John’s Lane"]
+      [:p "London"]
+      [:p "EC1M 4AR."]
+      ]
+     [:p "or email at compliance@humanitarian.academy"]
+     ]
+    [:p "The Academy is responsible for all Personal Information under its control and has designated a privacy officer who is accountable to Management for the Academy’s compliance with this Privacy Policy."]
+    [:div
+     [:h2 [:b "QUESTIONS OR TO WITHDRAW CONSENT"]]
+     [:p "You may exercise your right to withdraw your consent to applicable uses or disclosures of your Personal Information (which may limit or terminate the products and services that the Academy provides to you) by writing or sending an email to us at the above address. We will need to validate the identity of anyone making such a request to ensure that we do not provide your information to anyone who does not have the right to such information."]
+     [:p "Normally we will respond to access requests within 30 days."]
+     [:p "Should you feel that your Personal Information has not been handled in accordance with this Policy after inquiring with us, you may contact the UK’s Information Commissioner’s Office with your complaint."]
+     ]
+    [:div
+     [:h2 [:b "CHANGES TO THIS PRIVACY POLICY"]]
+     [:p "If there is any material change to your rights under this Privacy Policy, the Academy will provide you with notice of such change 30 days prior to the changes going into effect. As part of this notice, the Academy may post a notice of the change on the site in a clear and conspicuous manner for the 30 day notice period. the Academy may also communicate the change via email or postal mail if this is the way that March normally corresponds with you. Please note that your continued use of the Site or Services once this 30 day period are over indicates your agreement to the changes which were the subject of the notice."]
+     ]
+    ]])

 (defn ^:export accept-terms-string []
   "I have read and i agree to the privacy policy")


Transactions can be grouped by week

Transactions can be grouped by week

--- src/swanson/models/db.clj
+++ src/swanson/models/db.clj
@@ -80,3 +80,15 @@
 (defn mk-transaction-id
   [date amount description]
   (sha256 (apply str date amount description)))
+
+(def week-grouping-query
+  "SELECT date_trunc('week', t.date) AS Week , SUM(t.amount) AS total
+  FROM transactions t
+  WHERE t.date > now() - interval '1 year'
+  AND t.amount < 0.00
+  GROUP BY Week
+  ORDER BY Week")
+
+(defn get-transactions-by-week []
+  (with-db sql/with-query-results rows [week-grouping-query]
+      (doall rows)))


more tweaks to basic tcp server code

more tweaks to basic tcp server code

--- src/block_chain/net.clj
+++ src/block_chain/net.clj
@@ -3,45 +3,35 @@
             [clojure.core.async :as async])
   (:import  [java.net ServerSocket]))

-(defn gets
-  "Read a line of textual data from the given socket"
-  [reader]
-  (.readLine reader))
-
 (defn write-response
   "Send the given string message out over the given socket"
   [socket msg]
   (let [writer (io/writer socket)]
-      (.write writer msg)
-      (.flush writer)))
+    (.write writer msg)
+    (.flush writer)))

-(defn read-lines [reader]
-  (loop [lines []
+(defn read-lines [socket]
+  (let [reader (io/reader socket)]
+    (loop [lines []
          next-line (.readLine reader)]
-    (if (empty? next-line)
-      lines
-      (recur (conj lines next-line)
-             (.readLine reader)))))
+      (if (empty? next-line)
+        lines
+        (recur (conj lines next-line)
+               (.readLine reader))))))

 (defn echo-handler [lines]
   (println "handling lines: " lines)
-  (clojure.string/join "\n" lines))
+  (str (clojure.string/join "\n" lines) "\n"))

-(import '[java.net ServerSocket])
-(require '[clojure.java.io :as io])
+(defn serve-loop [server-sock handler]
+  (future
+    (while true
+      (with-open [socket (.accept server-sock)]
+        (write-response socket
+                        (handler (read-lines socket)))))))
+
 (defn start-server [port handler]
-  (let [server-sock (ServerSocket. port)]
+  (let [server (ServerSocket. port)]
     (println "server waiting for will wait for next request")
-    {:server server-sock
-     :run-loop (future
-      (while true
-        (with-open [socket (.accept server-sock)
-                    reader (io/reader socket)
-                    writer (io/writer socket)]
-          (println "got connection: " socket)
-          (let [lines (read-lines reader)]
-            (println "read lines: " lines)
-            (.write writer
-                    (handler lines))))))
-     }))
+    {:server server :run-loop (serve-loop server handler)}))


Fixed get-index from search.

Fixed get-index from search.

--- src/beebster_clj/core.clj
+++ src/beebster_clj/core.clj
@@ -4,7 +4,7 @@
         [net.cgrand.enlive-html :as html]
         [clojure.java.shell :only [sh]]
         [compojure.core]
-        [clojure.string :only [split-lines]]))
+        [clojure.string :as str :only [split-lines ]]))

 (def iplayer-command
@@ -13,7 +13,8 @@
 (defn iplayer-search
   "run external command with given args list."
   [search-title]
-  (split-lines (:out (apply sh (flatten (conj (list search-title) iplayer-command))))))
+  (split-lines (:out (apply sh (flatten
+                                (conj (list search-title) iplayer-command))))))

 (def iplayer-info
   '("get_iplayer" "-i"))
@@ -24,23 +25,17 @@
   (split-lines (:out (apply sh (flatten (conj (list index) iplayer-info))))))

 (defn get-thumb-from-search
-  "find thumbnail-url in string."
-  [str]
-  (re-find #"http.*jpg" str))
+  "return list of thumbnail for searchterm."
+  [s]
+  (remove nil? (map #(re-find #"http.*jpg" %) s)))

+(defn get-title-and-episode
+  "return list of titles from search-iplayer string."
+  [s]
+  (map #(re-find #"[A-Z0-9].*" %)
+       (remove nil? (map #(re-find #"jpg.*" %) (map #(str/replace % #"-" "") s)))))

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+(defn get-index-from-search
+  "return list of indexes from search-iplayer string."
+  [s]
+  (remove #(= "" %) (map #(re-find #"^[0-9]*" %) s)))


Use sparkles for secretbox-easy-to-buf!

Use sparkles for secretbox-easy-to-buf!

Remove other API

--- src/caesium/crypto/secretbox.clj
+++ src/caesium/crypto/secretbox.clj
@@ -8,22 +8,14 @@
 (b/defconsts [keybytes noncebytes macbytes primitive])

 (defn secretbox-easy-to-buf!
-  "Encrypt with `crypto_secretbox_easy` into the given byte array.
+  "Encrypt with `crypto_secretbox_easy` into the given byte buffer.

-  You only want this to manage the output byte array yourself. Otherwise,
+  All arguments must be `java.nio.ByteBuffer`.
+
+  You only want this to manage the output byte buffer yourself. Otherwise,
   you want [[secretbox-easy]]."
-  [^bytes out ^bytes msg ^bytes nonce ^bytes key]
-  (let [mlen (buflen msg)]
-    (.crypto_secretbox_easy b/sodium out msg mlen nonce key)))
-
-(defn secretbox-easy-to-byte-buf!
-  "Like [[secretbox-easy-to-buf!]], but with a ByteBuffer output.
-
-  Like [[secretbox-easy-to-buf!]], this is only useful if you want to manage
-  the output byte buffer yourself. Otherwise, you want [[secretbox-easy]]."
-  [^java.nio.ByteBuffer out ^bytes msg ^bytes nonce ^bytes key]
-  (let [mlen (buflen msg)]
-    (.crypto_secretbox_easy b/sodium out msg mlen nonce key)))
+  [c m n k]
+  (b/✨ easy m n k))

 (defn secretbox-easy
   "Encrypt with `crypto_secretbox_easy`.


create_before_destroy on template_files too

causes 'cycle' issues described here https://github.com/hashicorp/terraform/issues/2359

--- src/terraboot/cluster.clj
+++ src/terraboot/cluster.clj
@@ -266,6 +266,7 @@
                                :internal-lb-dns (cluster-output-of "aws_elb" "InternalMasterLoadBalancer" "dns_name")
                                :fallback-dns (vpc/fallback-dns vpc/vpc-cidr-block)
                                :number-of-masters min-number-of-masters}
+                        :lifecycle { :create_before_destroy true }
                         })

              (asg "MasterServerGroup"
@@ -326,7 +327,8 @@
                                :exhibitor-s3-bucket (cluster-unique "exhibitor-s3-bucket")
                                :internal-lb-dns (cluster-output-of "aws_elb" "InternalMasterLoadBalancer" "dns_name")
                                :fallback-dns (vpc/fallback-dns vpc/vpc-cidr-block)
-                               :number-of-masters min-number-of-masters}})
+                               :number-of-masters min-number-of-masters}
+                        :lifecycle { :create_before_destroy true }})

              (asg "PublicSlaveServerGroup"
                   cluster-unique
@@ -369,6 +371,7 @@
                                :internal-lb-dns (cluster-output-of "aws_elb" "InternalMasterLoadBalancer" "dns_name")
                                :fallback-dns (vpc/fallback-dns vpc/vpc-cidr-block)
                                :number-of-masters min-number-of-masters}
+                        :lifecycle { :create_before_destroy true }
                         })

              (asg "SlaveServerGroup"


Expose scalarmult

Expose scalarmult

--- src/caesium/binding.clj
+++ src/caesium/binding.clj
@@ -132,7 +132,15 @@

     ^int ^{size_t {}} crypto_scalarmult_bytes []
     ^int ^{size_t {}} crypto_scalarmult_scalarbytes []
-    ^String crypto_scalarmult_primitive []})
+    ^String crypto_scalarmult_primitive []
+
+    ^int crypto_scalarmult_base
+    [^bytes ^{Pinned {}} q
+     ^bytes ^{Pinned {}} n]
+    ^int crypto_scalarmult
+    [^bytes ^{Pinned {}} q
+     ^bytes ^{Pinned {}} n
+     ^bytes ^{Pinned {}} p]})

 (defmacro ^:private defsodium
   []


Fix regression for empty text node

Fix regression for empty text node

--- src/lt/plugins/kukui/core.cljs
+++ src/lt/plugins/kukui/core.cljs
@@ -62,7 +62,7 @@
 (def text-regex (re-pattern (str "\\s*" tags-delimiter "\\s*")))

 (defn ->text-value [text]
-  (-> text (s/split text-regex) first))
+  (-> text (s/split text-regex) first (or "")))

 (defn add-node-with-tags [nodes node tags]
   (conj nodes (assoc node :text (->text-value (:text node)) :tags (set tags))))


A convenience macro to scale contexts

A convenience macro to scale contexts

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

--- src/conexp/fca/many_valued_contexts.clj
+++ src/conexp/fca/many_valued_contexts.clj
@@ -215,4 +215,37 @@

 ;;;

+(defmacro scale-context
+  "Scales the given (many-valued) context ctx with the given
+  scales. These are of the form
+
+    [att_1 att_2 ...] short_scale,
+
+  where att_i is an attribute of the given context and short_scale
+  determines a call to a known scala, without the attributes. For
+  example, you may use this macro with
+
+    (scale-context ctx
+                   [a b c] (nominal-scale)
+                   [d]     (dichotomic-scale))
+
+  Note that attributes always have to be given in a sequence, even if
+  there is only one."
+  [ctx & scales]
+  (let [scales (partition 2 scales),
+        given-atts (mapcat first scales)]
+    (when (not= given-atts (distinct given-atts))
+      (illegal-argument "Doubly given attribute."))
+    `(do
+       (when-not (= (attributes ~ctx) ~(set given-atts))
+         (illegal-argument "Given scalas to scale-context do not "
+                           "yield the attribute set of the given context."))
+       (scale-mv-context ~ctx
+                         ~(into {}
+                                (for [[atts scale] scales,
+                                      att atts]
+                                  `['~att ~(list* (first scale) `(attributes ~ctx) (rest scale))]))))))
+
+;;;
+
 nil


skip non migrated actions

skip non migrated actions

--- src/celestial/persistency/actions.clj
+++ src/celestial/persistency/actions.clj
@@ -31,10 +31,13 @@

 (defn add-provided [action]
   "appends action expected arguments derived from args strings"
-   (reduce
-     (fn [m e]
-       (assoc-in m [(figure-rem m) e :provided]
-         (remove #{"target" "hostname"} (c/args-of (join " " ((remoter m) e :args)))))) action (keys (remoter action))))
+   (if (:args (remoter action))
+     action ; not migrated yet
+     (reduce
+      (fn [m e]
+        (assoc-in m [(figure-rem m) e :provided]
+          (remove #{"target" "hostname"}
+            (c/args-of (join " " ((remoter m) e :args)))))) action (keys (remoter action)))))

 (def with-provided (partial c/with-transform add-provided))


Fix UV cue.

Fix UV cue.

--- src/afterglow/shows/sallie.clj
+++ src/afterglow/shows/sallie.clj
@@ -234,7 +234,7 @@
                                     :color :cyan))

     (ct/set-cue! (:cue-grid *show*) 7 7
-                 (cues/function-cue :hex-uv :uv (show/fixtures-named "snowball")
+                 (cues/function-cue :hex-uv :uv (show/fixtures-named "hex")
                                     :level 255
                                     :color :blue))


Upgrade Sente.

Upgrade Sente.

--- src/clj/onyx_dashboard/http/sente.clj
+++ src/clj/onyx_dashboard/http/sente.clj
@@ -1,6 +1,7 @@
 (ns onyx-dashboard.http.sente
   (:require [clojure.core.async :refer [close!]]
             [com.stuartsierra.component :as component]
+            [taoensso.sente.server-adapters.http-kit]
             [taoensso.sente.packers.transit :as sente-transit]
             [taoensso.sente :refer [make-channel-socket!]]))

@@ -16,7 +17,9 @@
   component/Lifecycle
   (start [component]
     (println "Starting Sente")
-    (let [x (make-channel-socket! {:user-id-fn user-id-fn :packer packer})]
+    (let [x (make-channel-socket!
+             taoensso.sente.server-adapters.http-kit/http-kit-adapter
+             {:user-id-fn user-id-fn :packer packer})]
       (assoc component
         :ring-ajax-post (:ajax-post-fn x)
         :ring-ajax-get-or-ws-handshake (:ajax-get-or-ws-handshake-fn x)


material form cleanup

material form cleanup

--- src/cljs/material/component/form.cljs
+++ src/cljs/material/component/form.cljs
@@ -3,8 +3,7 @@
   (:require [material.component :as cmp]
             [material.icon :as icon]
             [sablono.core :refer-macros [html]]
-            [swarmpit.time :as time]
-            [swarmpit.routes :as routes]))
+            [swarmpit.time :as time]))

 (defn item
   [name value]
@@ -80,5 +79,5 @@
    (subsection name nil))
   ([name button]
    (html [:div.Swarmpit-form-section
-          [:div (cmp/typography {:variant "subheading"} name)]
+          [:div (cmp/typography {:variant "subtitle1"} name)]
           [:div button]])))


using component handler instead of controller handler for rpc

--- src/cljs/swarmpit/component/menu.cljs
+++ src/cljs/swarmpit/component/menu.cljs
@@ -2,6 +2,7 @@
   (:require [material.component :as comp]
             [material.icon :as icon]
             [sablono.core :refer-macros [html]]
+            [swarmpit.component.handler :as handler]
             [swarmpit.component.state :as state]
             [swarmpit.storage :as storage]
             [swarmpit.routes :as routes]
@@ -164,20 +165,16 @@
          (take 7)
          (apply str))))

-(def get-version
+(def retrieve-version
   {:will-mount
    (fn [state]
-     (swarmpit.controller/get
+     (handler/get
        (routes/path-for-backend :version)
-       (fn [version]
-         (state/update-value
-           [:version]
-           (parse-version version)
-           cursor)))
+       {:on-success #(state/update-value [:version] (parse-version %) cursor)})
      state)})

 (rum/defc drawer < rum/reactive
-                   get-version [page-domain]
+                   retrieve-version [page-domain]
   (let [{:keys [opened version]} (state/react cursor)
         drawer-container-style (if opened
                                  drawer-container-opened-style


Restore removed functions from previous commit.

--- src/clojure/catacumba/serializers.clj
+++ src/clojure/catacumba/serializers.clj
@@ -59,6 +59,14 @@
 ;; Public Api
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

+(defn str->bytes
+  [data]
+  (.getBytes data "UTF-8"))
+
+(defn bytes->str
+  [data]
+  (String. data "UTF-8"))
+
 (defmulti -encode
   (fn [data opts] (::type opts)))


Make proper use of defrecord implicit field bindings

--- src/main/clojure/cascade/dom.clj
+++ src/main/clojure/cascade/dom.clj
@@ -105,13 +105,11 @@
   (stream [node strategy out]
     ; I'm hoping the need to qualify clojure.core/name is a bug in the 1.2 defrecord code that can be
     ; removed when we switch up to 1.3.
-    (let [name-keyword (:name node)
-          element-name (clojure.core/name name-keyword)
-          attr-quote (strategy :attribute-quote)
-          content (:content node)]
+    (let [element-name (clojure.core/name name)
+          attr-quote (strategy :attribute-quote)]
       (write out "<" element-name)
       ; Write out normal attributes
-      (doseq [[attr-name attr-value] (:attributes node)]
+      (doseq [[attr-name attr-value] attributes]
         (if-not (nil? attr-value)
           (write out
             " " (clojure.core/name attr-name) "=" attr-quote (to-attr-string attr-value) attr-quote)))
@@ -129,13 +127,13 @@

   NodeStreaming
   (stream [node strategy out]
-    (write out (:text node))))
+    (write out text)))

 (defrecord Comment [text]

   NodeStreaming
   (stream [node strategy out]
-    (write out "<!--" (:text node) "-->")))
+    (write out "<!--" text "-->")))

 ; Most outside code will use these standard constructor functions, rather than using the records' constructors.


fix another cut-and-paste typo

fix another cut-and-paste typo

--- src/babel/francais/morphology/verbs.cljc
+++ src/babel/francais/morphology/verbs.cljc
@@ -1231,8 +1231,8 @@
      :unify-with {:synsem {:cat :verb
                            :agr {:person :3rd
                                  :number :sing}
-                           :infl :imperfect}
-                  :français {:imperfect {:stem true}}}}
+                           :infl :future}
+                  :français {:future {:stem true}}}}
     {:prefix :future-stem :suffix "ons"
      :unify-with {:synsem {:cat :verb
                            :agr {:person :1st


Make recipient in the savings recipients list removable

--- src/cljs/my_money/components/config.cljs
+++ src/cljs/my_money/components/config.cljs
@@ -37,7 +37,10 @@
    (into [:ul.list-group]
      (for [recipient (:selected-recipients @data)]
        ^{:key (str "active_" recipient)}
-       [:li.list-group-item recipient]))])
+       [:li.list-group-item recipient
+        [:button.btn.close
+         {:on-click #(swap! data update :selected-recipients disj recipient)}
+         "×"]]))])

 (defn- fields [data]
   [:div


checks

checks

--- src/clojure/zensols/actioncli/log4j2.clj
+++ src/clojure/zensols/actioncli/log4j2.clj
@@ -24,9 +24,11 @@
 (defn configure
   "Congigure the Log4j2 system with an XML resource."
   [xml-resource]
-  (let [resource (io/resource xml-resource)
-        stream (.openStream resource)]
-    (with-open [in (io/input-stream (io/file xml-resource))]
+  (let [res (io/resource xml-resource)]
+    (if (nil? res)
+      (throw (ex-info (format "No such resource: %s" xml-resource)
+                      {:xml-resource xml-resource})))
+    (with-open [in (io/input-stream res)]
       (LogUtil/config in))))

 (defn log-level-set-option