More logical lein profile structure

More logical lein profile structure

--- project.clj
+++ project.clj
@@ -6,47 +6,9 @@
   ["out-client" "out-server" "out-test" "deploy/index.js" "resources/js/supper.compiled.js"
    "supper.compiled.test.js" "target"]

-  :cljsbuild
-  {:builds [{:id "test"
-             :source-paths ["src" "test"]
-             :compiler
-             {:output-to "supper.compiled.test.js"
-              :output-dir "out-test"
-              :optimizations :advanced}}
+  :profiles {:default [:cljs-shared]

-            {:id "server"
-             :source-paths ["src"]
-             :compiler
-             {:main "supper.core-server"
-              :target :nodejs
-              :output-to "deploy/index.js"
-              :output-dir "out-server"
-              :preamble ["include.js"]
-              :optimizations :simple
-              :language-in :ecmascript5
-              :language-out :ecmascript5}}
-
-            {:id "client"
-             :source-paths ["src"]
-             :compiler
-             {:main "supper.core-client"
-              :output-to "resources/js/supper.compiled.js"
-              :output-dir "out-client"
-              :optimizations :advanced
-              :pretty-print false}}]
-
-   :test-commands {"unit-tests" ["phantomjs" :runner
-                                 "test/es5-shim.js" ;Polyfills to account for dated webkit in PhantomJS
-                                 "test/es5-sham.js"
-                                 "test/console-polyfill.js"
-                                 "supper.compiled.test.js"]}}
-
-  ;Android specific config
-  :global-vars {*warn-on-reflection* true}
-  :source-paths ["src-droid/clojure"]
-  :java-source-paths ["src-droid/java"]
-  :javac-options ["-target" "1.6" "-source" "1.6" "-Xlint:-options"]
-  :profiles {:cljs-shared
+             :cljs-shared
              {:dependencies [[org.clojure/clojure "1.6.0"]
                              [org.clojure/clojurescript "0.0-3058"]
                              [org.clojure/core.async "0.1.346.0-17112a-alpha"]
@@ -59,24 +21,82 @@
                              ]

               :plugins [[lein-cljsbuild "1.0.5"]
-                        [com.cemerick/clojurescript.test "0.3.3"]]}
+                        [com.cemerick/clojurescript.test "0.3.3"]]
+
+              :cljsbuild
+              {:builds [{:id "test"
+                         :source-paths ["src-cljs" "test"]
+                         :compiler
+                         {:output-to "supper.compiled.test.js"
+                          :output-dir "out-test"
+                          :optimizations :advanced}}
+
+                        {:id "server"
+                         :source-paths ["src-cljs"]
+                         :compiler
+                         {:main "supper.core-server"
+                          :target :nodejs
+                          :output-to "deploy/index.js"
+                          :output-dir "out-server"
+                          :preamble ["include.js"]
+                          :optimizations :simple
+                          :language-in :ecmascript5
+                          :language-out :ecmascript5}}
+
+                        {:id "client"
+                         :source-paths ["src-cljs"]
+                         :compiler
+                         {:main "supper.core-client"
+                          :output-to "resources/js/supper.compiled.js"
+                          :output-dir "out-client"
+                          :optimizations :advanced
+                          :pretty-print false}}]
+
+               :test-commands {"unit-tests" ["phantomjs" :runner
+                                             "test/es5-shim.js" ;Polyfills to account for dated webkit in PhantomJS
+                                             "test/es5-sham.js"
+                                             "test/console-polyfill.js"
+                                             "supper.compiled.test.js"]}}}
+
+             :android-shared
+             [:android-common
+              {:global-vars {*warn-on-reflection* true}
+               :source-paths ["src-droid/clojure"]
+               :java-source-paths ["src-droid/java"]
+               :javac-options ["-target" "1.6" "-source" "1.6" "-Xlint:-options"]
+
+               :dependencies [[org.clojure-android/clojure "1.7.0-alpha6" :use-resources true]
+                              [neko/neko "3.2.0"]]
+               :plugins [[lein-droid "0.4.0-alpha1"]]
+               :android {;; Specify the path to the Android SDK directory.
+                         ;; :sdk-path "/home/user/path/to/android-sdk/"
+
+                         ;; Try increasing this value if dexer fails with
+                         ;; OutOfMemoryException. Set the value according to your
+                         ;; available RAM.
+                         :dex-opts ["-JXmx4096M"]
+
+                         ;; If previous option didn't work, uncomment this as well.
+                         ;; :force-dex-optimize true
+
+                         :assets-paths ["resources"]
+                         :target-version "22"
+                         :aot-exclude-ns ["clojure.parallel" "clojure.core.reducers"
+                                          "cljs-tooling.complete" "cljs-tooling.info"
+                                          "cljs-tooling.util.analysis" "cljs-tooling.util.misc"
+                                          "cider.nrepl" "cider-nrepl.plugin"]}}]

              :android-dev
-             [:android-common
-              {:dependencies [[org.clojure-android/clojure "1.7.0-alpha6" :use-resources true]
-                              [org.clojure-android/tools.nrepl "0.2.6-lollipop"]
-                              [neko/neko "3.2.0"]]
-               :plugins [[lein-droid "0.4.0-alpha1"]]
+             [:android-shared
+              {:dependencies [[org.clojure-android/tools.nrepl "0.2.6-lollipop"]]
                :target-path "target/debug"
                :android {:aot :all-with-unused
-                         :assets-paths ["resources"]
                          :rename-manifest-package "com.sparrho.supperdemo.debug"
                          :manifest-options {:app-name "SupperDemo - debug"}}}]

              :android-release
-             [:android-common
+             [:android-shared
               {:target-path "target/release"
-               :plugins [[lein-droid "0.4.0-alpha1"]]
                :android
                { ;; Specify the path to your private keystore
                 ;; and the the alias of the key you want to
@@ -84,24 +104,6 @@
                 ;; :keystore-path "/home/user/.android/private.keystore"
                 ;; :key-alias "mykeyalias"

-                :assets-paths ["resources"]
                 :ignore-log-priority [:debug :verbose]
                 :aot :all
-                :build-type :release}}]}
-
-  :android {;; Specify the path to the Android SDK directory.
-            ;; :sdk-path "/home/user/path/to/android-sdk/"
-
-            ;; Try increasing this value if dexer fails with
-            ;; OutOfMemoryException. Set the value according to your
-            ;; available RAM.
-            :dex-opts ["-JXmx4096M"]
-
-            ;; If previous option didn't work, uncomment this as well.
-            ;; :force-dex-optimize true
-
-            :target-version "22"
-            :aot-exclude-ns ["clojure.parallel" "clojure.core.reducers"
-                             "cljs-tooling.complete" "cljs-tooling.info"
-                             "cljs-tooling.util.analysis" "cljs-tooling.util.misc"
-                             "cider.nrepl" "cider-nrepl.plugin"]})
+                :build-type :release}}]})


(maint) Target master at 6.1.0

(maint) Target master at 6.1.0

--- project.clj
+++ project.clj
@@ -1,4 +1,4 @@
-(def ps-version "6.0.2-SNAPSHOT")
+(def ps-version "6.1.0-SNAPSHOT")

 (defn deploy-info
   [url]


New dependency: clj-calendar

New dependency: clj-calendar

--- project.clj
+++ project.clj
@@ -33,6 +33,7 @@
                                                       com.sun.jmx/jmxri]]
                    [org.slf4j/slf4j-log4j12 "1.6.6"]
                    [org.clojars.tisnik/clj-jenkins-api "0.10.0-SNAPSHOT"]
+                   [org.clojars.tisnik/clj-calendar "0.3.0-SNAPSHOT"]
                    [org.clojars.tisnik/clj-fileutils "0.2.0-SNAPSHOT"]]
     :dev-dependencies [[lein-ring "0.8.10"]]
     :plugins [[lein-ring "0.8.10"]


Dependencies: log4j and slf4j-log4j12

Dependencies: log4j and slf4j-log4j12

--- project.clj
+++ project.clj
@@ -27,6 +27,11 @@
                    [clojure-ini "0.0.1"]
                    [irclj "0.5.0-alpha4"]
                    [org.clojure/tools.logging "0.3.1"]
+                   [log4j/log4j "1.2.17" :exclusions [javax.mail/mail
+                                                      javax.jms/jms
+                                                      com.sun.jmdk/jmxtools
+                                                      com.sun.jmx/jmxri]]
+                   [org.slf4j/slf4j-log4j12 "1.6.6"]
                    [org.clojars.tisnik/clj-jenkins-api "0.10.0-SNAPSHOT"]
                    [org.clojars.tisnik/clj-fileutils "0.2.0-SNAPSHOT"]]
     :dev-dependencies [[lein-ring "0.8.10"]]


add exclusions for things that don't need them

--- project.clj
+++ project.clj
@@ -12,10 +12,11 @@
                  [org.apache.httpcomponents/httpmime "4.2.5"]
                  [commons-codec "1.7"]
                  [commons-io "2.4"]
-                 [slingshot "0.10.3"]
+                 [slingshot "0.10.3" :exclusions [org.clojure/clojure]]
                  [cheshire "5.1.1"]
-                 [crouton "0.1.1"]
-                 [org.clojure/tools.reader "0.7.3"]]
+                 [crouton "0.1.1" :exclusions [org.clojure/clojure]]
+                 [org.clojure/tools.reader "0.7.3"
+                  :exclusions [org.clojure/clojure]]]
   :profiles {:dev {:dependencies [[org.clojure/clojure "1.5.1"]
                                   [ring/ring-jetty-adapter "1.1.8"]
                                   [ring/ring-devel "1.1.8"]]}


updated deps

updated deps

--- project.clj
+++ project.clj
@@ -1,11 +1,11 @@
-(defproject dda/dda-managed-ide "1.0.3-SNAPSHOT"
+(defproject dda/dda-managed-ide "2.0.0-SNAPSHOT"
   :description "module to install and configure ide based on ubuntu vm."
   :url "https://www.domaindrivenarchitecture.org"
   :license {:name "Apache License, Version 2.0"
             :url "https://www.apache.org/licenses/LICENSE-2.0.html"}
   :dependencies [[dda/dda-config-commons "1.4.0"]
                  [dda/dda-pallet "2.2.0"]
-                 [dda/dda-managed-vm "2.0.0"]]
+                 [dda/dda-managed-vm "2.1.1"]]
   :source-paths ["main/src"]
   :resource-paths ["main/resources"]
   :repositories [["snapshots" :clojars]


Version 2.1.10

Version 2.1.10

--- project.clj
+++ project.clj
@@ -1,4 +1,4 @@
-(defproject grafter/grafter "2.1.10-SNAPSHOT"
+(defproject grafter/grafter "2.1.10"
   :description "Tools for the hard graft of linked data processing"
   :url "http://grafter.org/"
   :license {:name "Eclipse Public License - v1.0"


Release version 0.10.0.0-alpha5.

Release version 0.10.0.0-alpha5.

--- project.clj
+++ project.clj
@@ -1,4 +1,4 @@
-(defproject org.onyxplatform/onyx-datomic "0.10.0.0-SNAPSHOT"
+(defproject org.onyxplatform/onyx-datomic "0.10.0.0-alpha5"
   :description "Onyx plugin for Datomic"
   :url "https://github.com/onyx-platform/onyx-datomic"
   :license {:name "Eclipse Public License"
@@ -13,7 +13,7 @@
                              :sign-releases false}}
   :dependencies [[org.clojure/clojure "1.8.0"]
                  ^{:voom {:repo "git@github.com:onyx-platform/onyx.git" :branch "master"}}
-                 [org.onyxplatform/onyx "0.10.0-alpha4"]]
+                 [org.onyxplatform/onyx "0.10.0-alpha5"]]
   :test-selectors {:default (complement :ci)
                    :ci :ci
                    :all (constantly true)}


next dev cycle

next dev cycle

--- project.clj
+++ project.clj
@@ -1,4 +1,4 @@
-(defproject mapp "1.0.1"
+(defproject mapp "1.0.2-SNAPSHOT"
   :description "Starcity's Member Application"
   :url "http://apply.joinstarcity.com"
   :license {:name "Eclipse Public License"
@@ -46,7 +46,7 @@
                  [com.taoensso/timbre "4.10.0"]
                  [prismatic/plumbing "0.5.3"]
                  [starcity/ribbon "0.1.0"]
-                 [starcity/toolbelt "0.1.4" :exclusions [com.datomic/datomic-free]]
+                 [starcity/toolbelt "0.1.5" :exclusions [com.datomic/datomic-free]]
                  [me.raynes/fs "1.4.6"]]

   :plugins [[lein-cljsbuild "1.1.4"]


Version 0.4.6

Version 0.4.6

--- project.clj
+++ project.clj
@@ -1,4 +1,4 @@
-(defproject yetibot.core "0.4.6-SNAPSHOT"
+(defproject yetibot.core "0.4.6"
   :description "Core yetibot utilities, extracted for shared use among yetibot
                 and its various plugins"
   :url "https://github.com/devth/yetibot.core"


Version 4.4.1-SNAPSHOT

Version 4.4.1-SNAPSHOT

--- project.clj
+++ project.clj
@@ -1,6 +1,6 @@
 (def jetty-version "9.4.48.v20220622")

-(defproject puppetlabs/trapperkeeper-webserver-jetty9 "4.4.0"
+(defproject puppetlabs/trapperkeeper-webserver-jetty9 "4.4.1-SNAPSHOT"
   :description "A jetty9-based webserver implementation for use with the puppetlabs/trapperkeeper service framework."
   :url "https://github.com/puppetlabs/trapperkeeper-webserver-jetty9"
   :license {:name "Apache License, Version 2.0"


Set version to 1.2.0.

Set version to 1.2.0.

--- project.clj
+++ project.clj
@@ -1,4 +1,4 @@
-(defproject funcool/bide "1.1.0"
+(defproject funcool/bide "1.2.0"
   :description "Simple routing for ClojureScript"
   :url "https://github.com/funcool/bide"
   :license {:name "BSD (2-Clause)"


reorder & group deps list

reorder & group deps list

--- project.clj
+++ project.clj
@@ -4,8 +4,13 @@
   :license {:name "Eclipse Public License"
             :url  "http://www.eclipse.org/legal/epl-v10.html"}
   :dependencies [[org.clojure/clojure "1.10.1"]
+                 [org.clojure/math.combinatorics "0.1.6"]
+                 [org.clojure/tools.logging "1.1.0"]
+
                  [cheshire "5.10.0"]
                  [clj-stacktrace "0.2.8"]
+                 [clj-time "0.15.2"]
+                 [com.taoensso/nippy "2.14.0"]
                  [org.apache.beam/beam-sdks-java-core "2.26.0"]
                  [org.apache.beam/beam-sdks-java-io-elasticsearch "2.26.0"]
                  [org.apache.beam/beam-sdks-java-io-kafka "2.26.0"]
@@ -13,10 +18,6 @@
                  [org.apache.beam/beam-runners-google-cloud-dataflow-java "2.26.0"]
                  [org.apache.beam/beam-runners-core-java "2.26.0"]
                  [org.apache.kafka/kafka-clients "2.5.0"]
-                 [com.taoensso/nippy "2.14.0"]
-                 [org.clojure/math.combinatorics "0.1.6"]
-                 [org.clojure/tools.logging "1.1.0"]
-                 [clj-time "0.15.2"]
                  [superstring "3.0.0"]]
   :source-paths ["src/clj"]
   :pedantic? false


lein-release plugin: preparing 0.53 release

--- project.clj
+++ project.clj
@@ -1,4 +1,4 @@
-(defproject tyranitar "0.53-SNAPSHOT"
+(defproject tyranitar "0.53"
   :description "Tyranitar service"
   :url "http://wikis.in.nokia.com/NokiaMusicArchitecture/Tyranitar"


Update some dependencies

Update some dependencies

--- project.clj
+++ project.clj
@@ -1,14 +1,13 @@
 (defproject rest.tasks "0.1"
   :description "Proof of concept for REST/Backbone web stack"
-  :dependencies
+  :dependencies
     [[org.clojure/clojure "1.5.1"]
      [liberator "0.9.0"]
-     [compojure "1.1.3"]
+     [compojure "1.1.5"]
      [korma "0.3.0-RC5"]
      [lobos "1.0.0-beta1"]
      [postgresql "9.1-901.jdbc4"]
      [hiccup "1.0.4"]]
-
-  :plugins [[lein-ring "0.8.3"]]
-  :ring {:handler rest.tasks.routes/tasks-routes}
+  :plugins [[lein-ring "0.8.7"]]
+  :ring {:handler rest.core/app}
   :eval-in-leiningen true)


(maint) Merge up 10eb504 to main

(maint) Merge up 10eb504 to main

Generated by CI

* commit '10eb50471b77ab71b357831b9df66e750941dbd5':
  Set clj-parent=4.8.0
  Set clj-parent=4.7.3
  Set clj-parent=4.7.2

--- project.clj
+++ project.clj
@@ -27,7 +27,7 @@

   :min-lein-version "2.9.1"

-  :parent-project {:coords [puppetlabs/clj-parent "4.7.1"]
+  :parent-project {:coords [puppetlabs/clj-parent "4.8.0"]
                    :inherit [:managed-dependencies]}

   :dependencies [[org.clojure/clojure]


Upgrade to 0.9.7-alpha19.

Upgrade to 0.9.7-alpha19.

--- project.clj
+++ project.clj
@@ -1,10 +1,10 @@
-(defproject workshop "0.9.7-alpha18"
+(defproject workshop "0.9.7-alpha19"
   :license {:name "Eclipse Public License"
             :url "http://www.eclipse.org/legal/epl-v10.html"}
   :dependencies [[org.clojure/clojure "1.8.0"]
                  [org.clojure/core.async "0.2.374"]
                  ^{:voom {:repo "git@github.com:onyx-platform/onyx.git" :branch "master"}}
-                 [org.onyxplatform/onyx "0.9.7-alpha18"]
+                 [org.onyxplatform/onyx "0.9.7-alpha19"]
                  [org.slf4j/slf4j-api "1.7.12"]
                  [org.slf4j/slf4j-nop "1.7.12"]]
   :profiles {:dev {:dependencies [[org.clojure/tools.namespace "0.2.10"]


Slowed down process orchestration slide

Slowed down process orchestration slide

--- src-cljs/qcon/main.cljs
+++ src-cljs/qcon/main.cljs
@@ -381,7 +381,7 @@
             ydelta (/ (- (second to-pos) (second from-pos)) 18)]

         (go-loop [i 0]
-          (<! (timeout 30))
+          (<! (timeout 100))
           (om/set-state!
            slide :message
            [(+ (first from-pos) (* i xdelta))


cjl - Begin get-games

cjl - Begin get-games

--- src/icfp2015/problem.clj
+++ src/icfp2015/problem.clj
@@ -31,4 +31,15 @@
 (defn get-games
   "Returns (count (:sourceSeeds problem)) games given a problem."
   [problem]
-  nil)
+  (let [n (:sourceLength problem)
+        units (fn [seed] (->> seed
+                              (source-sequence)
+                              (take n)
+                              (map #(nth (:units problem) (mod % n)))))
+        coord-to-vec (fn [{:keys [x y]}] [x y])
+        make-game (fn [seed]
+                    { :width (:width problem)
+                      :height (:height problem)
+                      :filled (set (map coord-to-vec (:filled problem)))
+                      :units (units seed) })]
+    (map make-game (:sourceSeeds problem))))


Spruce up cache docs a bit

Spruce up cache docs a bit

--- modules/cache/src/main/clojure/immutant/cache.clj
+++ modules/cache/src/main/clojure/immutant/cache.clj
@@ -173,14 +173,27 @@
            (clojure.lang.MapEntry. k (cc/lookup this k))))))

 (defn cache
-  "The entry point to determine whether clustered or local"
+  "Returns an implementation of Mutable and
+   core.cache/CacheProtocol. A cache name is the only required
+   argument. When two arguments are passed, the second may be either a
+   symbol indicating replication mode or a seed, i.e. either the
+   second or the third of the 3-argument signature.
+
+   Replication mode should be one of:
+     :local, :invalidated, :distributed, or :replicated
+
+   Although the entries in the passed base hash map will be added to
+   the cache, entries already in the cache will NOT be deleted"
   ([name] (cache name nil nil))
   ([name v] (if (keyword? v) (cache name v nil) (cache name nil v)))
   ([name mode base]
      (cc/seed (InfinispanCache. (raw-cache name mode)) base)))

 (defn memo
-  "Wrap a function in an infinispan-backed memoization cache"
+  "Memoize a function by associating its arguments with return values
+   stored in a possibly-clustered Infinispan-backed cache. Other than
+   the function to be memoized, arguments are the same as for the
+   cache function."
   ([f name] (memo f name nil nil))
   ([f name v] (if (keyword? v) (memo f name v nil) (memo f name nil v)))
   ([f name mode seed]


apply vector => vec

apply vector => vec

--- src/java_time/graph.cljc
+++ src/java_time/graph.cljc
@@ -321,7 +321,7 @@
   (condp = (count (:path path))
     0 (vector path (fn [x] x))
     1 (vector path (->> path :fns first))
-    (let [fns (->> path :fns (apply vector))]
+    (let [fns (->> path :fns vec)]
       (vector path (fn [v] (reduce (fn [v f] (f v)) v fns))))))

 (defn conversion-fn


no-op-transformer

no-op-transformer

--- modules/reitit-spec/src/reitit/coercion/spec.cljc
+++ modules/reitit-spec/src/reitit/coercion/spec.cljc
@@ -27,8 +27,8 @@
      :encoders stt/json-type-encoders
      :default-encoder stt/any->any}))

-(def just-validate-transformer
-  (st/type-transformer {}))
+(def no-op-transformer
+  st/no-op-transformer)

 (defprotocol IntoSpec
   (into-spec [this name]))
@@ -64,10 +64,10 @@

 (def default-options
   {:coerce-response? coerce-response?
-   :transformers {:body {:default just-validate-transformer
+   :transformers {:body {:default no-op-transformer
                          :formats {"application/json" json-transformer}}
                   :string {:default string-transformer}
-                  :response {:default just-validate-transformer}}})
+                  :response {:default no-op-transformer}}})

 (defn create [{:keys [transformers coerce-response?] :as opts}]
   ^{:type ::coercion/coercion}


Making helpers private

Making helpers private

--- clojure/bob/bob.clj
+++ clojure/bob/bob.clj
@@ -1,13 +1,13 @@
 (ns bob (:require [clojure.string :as str]))

-(defn is-silent [phrase]
+(defn- is-silent [phrase]
     (str/blank? phrase)
 )
-(defn is-shouting [phrase]
+(defn- is-shouting [phrase]
     (= phrase (str/upper-case phrase))
 )

-(defn is-question [phrase]
+(defn- is-question [phrase]
     (= \? (last phrase))
 )


0.0-2371-25 -- bump version after reverting

--- build.boot
+++ build.boot
@@ -7,7 +7,7 @@

 (require '[tailrecursion.boot-useful :refer :all])

-(def +version+ "0.0-2371-23")
+(def +version+ "0.0-2371-25")

 (useful! +version+)


Add kebab->camel utility for camel-casing strings

--- src/main/workflo/macros/util/string.cljc
+++ src/main/workflo/macros/util/string.cljc
@@ -1,5 +1,7 @@
 (ns workflo.macros.util.string
-  (:require [clojure.string :as str]))
+  (:require #?(:cljs [cljs.spec :as s]
+               :clj  [clojure.spec :as s])
+            [clojure.string :as string]))

 (defn camel->kebab
   "Converts from camel case (e.g. Foo or FooBar) to kebab case
@@ -7,5 +9,18 @@
   [s]
   (->> s
        (re-seq #"[A-Z][a-z0-9_-]*")
-       (str/join "-")
-       (str/lower-case)))
+       (string/join "-")
+       (string/lower-case)))
+
+(s/fdef kebab->camel
+  :args (s/cat :s string?)
+  :ret  string?)
+
+(defn kebab->camel
+  "Converts from kebab case (e.g. foo-bar) to camel case (e.g.
+   fooBar)."
+  [s]
+  (let [words (re-seq #"\w+" s)]
+    (apply str
+           (cons (first words)
+                 (map string/capitalize (rest words))))))


Use decode-body more.

Use decode-body more.

--- src/kixi/hecuba/amon.clj
+++ src/kixi/hecuba/amon.clj
@@ -100,6 +100,7 @@
     [:pre (with-out-str
             (pprint item))]]))

+;; TODO move to webutil - how to handle call to ->shallow-kebab-map?
 (defmulti decode-body :content-type :default "application/json")

 (defmethod decode-body "application/json" [{body :body}] (some-> body read-json-body ->shallow-kebab-map))
@@ -265,8 +266,7 @@

   :post!
   (fn [{request :request}]
-    (let [body          (-> request :body)
-          entity        (-> body read-json-body ->shallow-kebab-map)
+    (let [entity        (decode-body request)
           project-id    (-> entity :project-id)
           property-code (-> entity :property-code)]
       (when (and project-id property-code)
@@ -327,11 +327,11 @@
                {::items items}))))

   :malformed?
-  (fn [{{body :body
-        {entity-id :entity-id} :route-params
-        method :request-method} :request}]
+  (fn [{{{entity-id :entity-id} :route-params
+        method :request-method
+        :as request} :request}]
     (case method
-      :post (let [body (-> body read-json-body ->shallow-kebab-map)]
+      :post (let [body (decode-body request)]
               ;; We need to assert a few things
               (if
                   (or
@@ -530,9 +530,9 @@
   :known-content-type? #{"application/json"}
   :authorized? (authorized? querier :measurement)

-  :post! (fn [{{body :body {:keys [device-id]} :route-params} :request}]
+  :post! (fn [{{{:keys [device-id]} :route-params :as request} :request}]
            (let [topic (get-in queue ["measurements"])]
-             (doseq [measurement (-> body read-json-body ->shallow-kebab-map :measurements)]
+             (doseq [measurement (:measurements (decode-body request))]
                (let [t        (db-timestamp (get measurement "timestamp"))
                      m2       {:device-id device-id
                                :type (get measurement "type")
@@ -623,8 +623,8 @@
   :allowed-methods #{:get :post}
   :available-media-types #{"application/edn" "text/html"}
   :authorized? (authorized? querier :datasets)
-  :post! (fn [{{body :body {:keys [entity-id]} :route-params} :request}]
-           (let [{:keys [members name]} (-> body read-edn-body ->shallow-kebab-map)
+  :post! (fn [{{{:keys [entity-id]} :route-params :as request} :request}]
+           (let [{:keys [members name]} (decode-body request)
                  members-str            (string/join \, members)
                  ds                     {:entity_id entity-id
                                          :name name
@@ -671,8 +671,8 @@
                                                     :name name}))]
       {::item item}
       #_(throw (ex-info (format "Cannot find item of id %s")))))
-  :post! (fn [{{body :body {:keys [entity-id name]} :route-params} :request}]
-           (let [{:keys [members name]} (-> body read-edn-body ->shallow-kebab-map)
+  :post! (fn [{{{:keys [entity-id name]} :route-params :as request} :request}]
+           (let [{:keys [members name]} (decode-body request)
                  ds {:entity_id entity-id
                      :name name
                      :members (string/join \, members)}]


implement test mode

implement test mode

--- src/s7p/core.clj
+++ src/s7p/core.clj
@@ -63,11 +63,8 @@
                :price (+ 1 second-price)
                :isClick (click? result response)})))

-(defn worker [c]
-  (thread
-    (loop []
-      (when-let [{:keys [req result]} (<!! c)]
-        (let [xf (comp
+(defn work [req result]
+  (let [xf (comp
                   (map (fn [dsp] [dsp (http/post (:url dsp) (json-request-option req))]))
                   (map validate)
                   ;; TODO: log validated responses
@@ -75,6 +72,19 @@
                   (map (fn [[_ res]] (:valid res))))]
           (some->> (sequence xf @dsps)
                    (pick-winner-and-second-price (:floorPrice req))
-                   (winnotice req result)
-                   )
-          (recur))))))
+                   (winnotice req result))))
+
+(defn test [req]
+  (let [xf (comp
+            (map (fn [dsp] [dsp (http/post (:url dsp) (json-request-option req))]))
+            (map validate))]
+          (sequence xf @dsps)))
+
+(defn worker [c]
+  (thread
+    (loop []
+      (when-let [{:keys [req result]} (<!! c)]
+        (if (= 1 (:test req))
+          (test req)
+          (work req result))
+        (recur)))))


New map style.

New map style.

--- src/clojure/kamituel/ngm_toc/ui/map.cljs
+++ src/clojure/kamituel/ngm_toc/ui/map.cljs
@@ -30,6 +30,23 @@
     ;; width.
     (coordinates-pixel-offset map lat-lng {:x (/ width 4) :y 0})))

+(def map-style
+  "Adapted from: https://snazzymaps.com/style/151/ultra-light-with-labels"
+  [{:featureType "water" :elementType "geometry" :stylers [{:color "#D3DEEA"} {:lightness 17}]}
+   {:featureType "landscape" :elementType "geometry" :stylers [{:color "#f5f5f5"} {:lightness 20}]}
+   {:featureType "road.highway" :elementType "geometry.fill" :stylers [{:color "#ffffff"} {:lightness 17}]}
+   {:featureType "road.highway" :elementType "geometry.stroke" :stylers [{:color "#ffffff"} {:lightness 29} {:weight 0.2}]}
+   {:featureType "road.arterial" :elementType "geometry" :stylers [{:color "#ffffff"} {:lightness 18}]}
+   {:featureType "road.local" :elementType "geometry" :stylers [{:color "#ffffff"} {:lightness 16}]}
+   {:featureType "poi" :elementType "geometry" :stylers [{:color "#f5f5f5"} {:lightness 21}]}
+   {:featureType "poi.park" :elementType "geometry" :stylers [{:color "#dedede"} {:lightness 21}]}
+   {:elementType "labels.text.stroke" :stylers [{:visibility "on"} {:color "#ffffff"} {:lightness 16}]}
+   {:elementType "labels.text.fill" :stylers [{:saturation 36} {:color "#333333"} {:lightness 40}]}
+   {:elementType "labels.icon" :stylers [{:visibility "off"}]}
+   {:featureType "transit" :elementType "geometry" :stylers [{:color "#f2f2f2"} {:lightness 19}]}
+   {:featureType "administrative" :elementType "geometry.fill" :stylers [{:color "#fefefe"} {:lightness 20}]}
+   {:featureType "administrative" :elementType "geometry.stroke" :stylers [{:color "#dddddd"} {:lightness 17} {:weight 1.2}]}])
+
 (defn default-map-options
   "It has to be a function to force it to evaluate only once Google Maps API is loaded."
   []
@@ -45,12 +62,13 @@
    :panControl false
    :rotateControl false
    :scaleControl true
-   :streetViewControl false})
+   :streetViewControl false
+   :styles map-style})

 (defn marker-icon
   [mode]
   {:path "M-20,0a20,20 0 1,0 40,0a20,20 0 1,0 -40,0"
-   :fillColor (if (= :peeked mode) "#FF0000" "#000000") ; Red or black.
+   :fillColor (if (= :peeked mode) "#FF0000" "#FFCE00") ; Red or NGM color.
    :fillOpacity (if (= :not-peeked mode) 0.3 1)
    :strokeWeight 10
    :strokeOpacity 0 ; Larger stroke makes it easy to point an icon on a map.


Fix bugs in deb packaging

Fix bugs in deb packaging

md5 files for debs now have the correct timestamp for snapshot versions,
and the package depends on jre-headless virtual packages, not the full
JRE.

--- tasks/leiningen/fatdeb.clj
+++ tasks/leiningen/fatdeb.clj
@@ -34,10 +34,11 @@
   (cleanup project)
   (sh "rm" (str (:root project) "/target/*.deb")))

+(def build-date (Date.))
 (defn get-version
   [project]
   (let [df   (SimpleDateFormat. "yyyyMMdd-HHmmss")]
-    (replace (:version project) #"SNAPSHOT" (.format df (Date.)))))
+    (replace (:version project) #"SNAPSHOT" (.format df build-date))))

 (defn control
   "Control file"
@@ -49,7 +50,7 @@
               :section "base"
               :priority "optional"
               :architecture "all"
-              :depends (join ", " ["bash" "default-jre | java2-runtime"])
+              :depends (join ", " ["bash" "default-jre-headless | java2-runtime-headless"])
               :maintainer (:email (:maintainer project))
               :description (:description project)})))


Add browser-eval-env function.

Add browser-eval-env function.

--- src/lib/clj/one/test.clj
+++ src/lib/clj/one/test.clj
@@ -140,6 +140,14 @@
   [form]
   `(cljs-eval ~(test-namespace) ~form))

+(defn browser-eval-env
+  "Create and set up a browser evaluation environment. Open a browser
+  to connect to this client."
+  [& options]
+  (let [eval-env (apply browser/repl-env options)]
+    (-setup eval-env)
+    eval-env))
+
 (def ^:dynamic *eval-ns* 'cljs.user)

 (defn bep-setup


Fix ctor.

Fix ctor.

--- src/onyx/monitoring/no_op_monitoring.clj
+++ src/onyx/monitoring/no_op_monitoring.clj
@@ -7,4 +7,4 @@

 (defmethod extensions/monitoring-agent :no-op
   [monitoring-config]
-  (map->NoOpMonitoringAgent))+  (->NoOpMonitoringAgent))


Update deps.

Update deps.

--- lein/.lein/profiles.clj
+++ lein/.lein/profiles.clj
@@ -1,9 +1,10 @@
 {:user {
-        :plugins [[cider/cider-nrepl "0.12.0-SNAPSHOT"]
+        :plugins [[cider/cider-nrepl "0.12.0"]
                   [lein-ancient "0.6.8"]
                   [lein-bikeshed "0.3.0"]
-                  [lein-kibit "0.1.2"]]
-
+                  [jonase/eastwood "0.2.3"]
+                  [lein-kibit "0.1.2"]
+                  [lein-pprint "1.1.1"]]
         :dependencies [[org.clojure/clojure "1.7.0"]
                        [org.clojure/tools.reader "1.0.0-alpha3"]
                        [com.cemerick/url "0.1.1"]


Minor performance improvements on jwe related to key extraction on cbc mode.

--- src/buddy/sign/jwe.clj
+++ src/buddy/sign/jwe.clj
@@ -232,7 +232,7 @@
 (defn extract-encryption-key
   [secret algorithm]
   {:pre [(bytes/bytes? secret)]}
-  (condp = algorithm
+  (case algorithm
     :a128cbc-hs256 (bytes/slice secret 16 32)
     :a192cbc-hs384 (bytes/slice secret 24 48)
     :a256cbc-hs512 (bytes/slice secret 32 64)))
@@ -240,7 +240,7 @@
 (defn extract-authentication-key
   [secret algorithm]
   {:pre [(bytes/bytes? secret)]}
-  (condp = algorithm
+  (case algorithm
     :a128cbc-hs256 (bytes/slice secret 0 16)
     :a192cbc-hs384 (bytes/slice secret 0 24)
     :a256cbc-hs512 (bytes/slice secret 0 32)))


remove standalone.config from lobos.migrations

--- src/lobos/migrations.clj
+++ src/lobos/migrations.clj
@@ -4,7 +4,6 @@
   (:use (lobos [migration :only [defmigration]] connectivity core schema))
   (:use lobos.helpers)
   (:use [clojure.tools.logging :only (info warn error)])
-  (:use ruuvi-server.standalone.config)
   (:use ruuvi-server.database)
   )

@@ -70,8 +69,8 @@
   (down [] (drop (table :event_extension_values))))

 (defn do-migration [direction db-config]
-  (println "Execute" (name direction))
-  (open-global (create-connection-pool *database-config*))
+  (info "Execute" (name direction))
+  (open-global (create-connection-pool db-config))
   (if (= :rollback direction)
     (do
       (info "rollbacking")


Address user confusion around plugin.json vs plugin.edn #1677 #1141

Also addressed whitespace in validate

--- src/lt/objs/plugins.cljs
+++ src/lt/objs/plugins.cljs
@@ -84,12 +84,12 @@
 ;; Plugin reading
 ;;*********************************************************

-(defn validate [plugin]
+(defn validate [plugin filename]
   (let [valid? (every? plugin [:name :author :behaviors :desc])]
     (if-not valid?
       (do
-        (console/error (str "Invalid plugin.json file: " (:dir plugin) "/plugin.json \nPlugins
-                            must include values for name, version, author, behaviors, and desc."))
+        (console/error (str "Invalid " filename " file: " (:dir plugin) "/" filename "\nPlugins "
+                            "must include values for name, version, author, behaviors, and desc."))
         nil)
       plugin)))

@@ -97,14 +97,14 @@
   (when-let [content (files/open-sync (files/join dir "plugin.edn"))]
     (-> (EOF-read (:content content))
         (assoc :dir dir)
-        (validate))))
+        (validate "plugin.edn"))))

 (defn plugin-json [dir]
   (when-let [content (files/open-sync (files/join dir "plugin.json"))]
     (-> (js/JSON.parse (:content content))
         (js->clj :keywordize-keys true)
         (assoc :dir dir)
-        (validate))))
+        (validate "plugin.json"))))

 (defn plugin-info [dir]
   (or (plugin-json dir) (plugin-edn dir)))
@@ -322,7 +322,7 @@
         p (popup/popup! {:header "Submit a plugin to the central repository"
                          :body [:div
                                 [:p "You can submit a github url to add a plugin to the central repository.
-                                 All plugin repos must have at least one tag in version format, e.g. 0.1.2 and must have a plugin.json
+                                 All plugin repos must have at least one tag in version format, e.g. 0.1.2 and must have a plugin.json or plugin.edn
                                  with name, version, desc, and behaviors keys. To refresh the available versions, just resubmit the plugin."]
                                 [:label "Github URL for plugin: "]
                                 input


Fixes read-config function.

Fixes read-config function.

--- src/cadence/config.clj
+++ src/cadence/config.clj
@@ -7,11 +7,11 @@
   (load-file (.getPath (io/resource "config.clj"))))

 (defn read-config [config-var]
-  (or (System/getenv config-var) ""
-     (find config-from-file
-             (keyword (string/replace
-                        (string/lower-case config-var)
-                        "_" "-")))))
+  (or (System/getenv config-var)
+      (get config-from-file
+            (keyword (string/replace
+                       (string/lower-case config-var)
+                       "_" "-")))))

 (def storage {:uri (read-config "MONGOHQ_URL")
               :db-name (read-config "MONGO_DB_NAME")


Renamed to fwd-to-lane.

Renamed to fwd-to-lane.

--- src/cbfg/world/t2.cljs
+++ src/cbfg/world/t2.cljs
@@ -76,12 +76,12 @@
       [lane-state nil])
     nil))

-(defn rq-handle-lane [actx m] ; Forward to lane-state-ch to handle the request.
-  (act rq-handle-lane actx
+(defn rq-fwd-to-lane [actx m] ; Forward to lane-state-ch to handle the request.
+  (act rq-fwd-to-lane actx
        (let [lane-state-ch (:lane-state-ch m)
-             res-ch (achan rq-handle-lane)]
-         (if (aput rq-handle-lane lane-state-ch (assoc m :res-ch res-ch))
-           (atake rq-handle-lane res-ch)
+             res-ch (achan rq-fwd-to-lane)]
+         (if (aput rq-fwd-to-lane lane-state-ch (assoc m :res-ch res-ch))
+           (atake rq-fwd-to-lane res-ch)
            (assoc m :status :failed
                   :status-info [(:op m) :closed :dispatch-lane])))))

@@ -89,7 +89,7 @@

 (def rq-handlers
   {"authenticate" rq-authenticate
-   "realms-list" rq-handle-lane
+   "realms-list" rq-fwd-to-lane
    "add" cbfg.world.base/example-add
    "sub" cbfg.world.base/example-add
    "count" cbfg.world.base/example-count


Move typical volume units; correct conversion

--- src/test_utils/fracture_diagnostics.cljc
+++ src/test_utils/fracture_diagnostics.cljc
@@ -58,8 +58,8 @@
                    [:kg-per-m3 :lb-per-cu-ft] #(/ % (factors [:lb-per-cu-ft :kg-per-m3]))
                    [:ft-lb :J]                #(* % (factors [:ft-lb :J]))
                    [:J :ft-lb]                #(/ % (factors [:ft-lb :J]))
-                   [:lbf :W]                  #(* % (factors [:lbf :W]))
-                   [:W :lbf]                  #(/ % (factors [:lbf :W]))
+                   [:lbf :N]                  #(* % (factors [:lbf :N]))
+                   [:N :lbf]                  #(/ % (factors [:lbf :N]))
                    [:ft :m]                   #(/ % (factors [:m :ft]))
                    [:m :ft]                   #(* % (factors [:m :ft]))
                    [:kg :lb]                  #(* % (factors [:kg :lb]))
@@ -511,9 +511,10 @@
   ([] (let [volume-unit (rand-volume-unit)]
         [(typical-pumped-volume volume-unit) volume-unit]))
   ([volume-unit]
-   (condp = volume-unit
-     :bbl (tuc/draw-normal 6986.70 1992.30)
-     :m3 (tuc/draw-normal 813.47 286.89))))
+   (let [volume-magnitude (condp = volume-unit
+                            :bbl (tuc/draw-normal 6986.70 1992.30)
+                            :m3  (tuc/draw-normal 813.47 286.89))]
+     [volume-magnitude volume-unit])))

 (defn typical-proppant-mass
   ([] (let [mass-unit (rand-mass-unit)]


shaping up cogroup

shaping up cogroup

--- pigpen-core/src/main/clojure/pigpen/cascading.clj
+++ pigpen-core/src/main/clojure/pigpen/cascading.clj
@@ -1,7 +1,7 @@
 (ns pigpen.cascading
   (:import (cascading.tap.hadoop Hfs)
            (cascading.scheme.hadoop TextLine)
-           (cascading.pipe Pipe Each)
+           (cascading.pipe Pipe Each CoGroup)
            (cascading.flow.hadoop HadoopFlowConnector)
            (pigpen.cascading PigPenFunction)
            (cascading.tuple Fields)
@@ -82,11 +82,10 @@
   ;(let [pig-field (format-field field)
   ;      pig-schema (str " AS " alias)]
   ;  [nil (str pig-field pig-schema)])
-  (println "flowdef" flowdef)
-  ;(update-in flowdef [:pipes pipe :fields] (fn [fields] (assoc fields field alias))))
-  (println "updated" (update-in flowdef [:pipes pipe] #(Each. % (Identity.))))
-  (println "x" x)
-  (println "pipe" (get-in flowdef [:pipes pipe]))
+  ;(println "flowdef" flowdef)
+  ;(println "updated" (update-in flowdef [:pipes pipe] #(Each. % (Identity.))))
+  ;(println "x" x)
+  ;(println "pipe" (get-in flowdef [:pipes pipe]))
   (update-in flowdef [:pipes pipe] #(Each. % (Identity.))))

 (defmethod command->flowdef :group
@@ -106,7 +105,9 @@
   (println "keys" keys)
   (println "ancestors" ancestors)
   (println "join-types" join-types)
-  (update-in flowdef [:pipes] (partial merge {id (Pipe. (str id))})))
+  (update-in flowdef [:pipes] (partial merge {id (CoGroup. (str id)
+                                                           (into-array Pipe (map (:pipes flowdef) ancestors))
+                                                           (into-array (map #(Fields. (into-array (map str %))) keys)))})))

 (defmethod command->flowdef :projection-flat
            [{:keys [code alias pipe]} flowdef]
@@ -116,21 +117,21 @@
 (defmethod command->flowdef :generate
            [{:keys [id ancestors projections opts]} flowdef]
   {:pre [id ancestors (not-empty projections)]}
-  (let [new-flowdef (cond (contains? (:sources flowdef) (first ancestors)) (let [pipe (Pipe. (str id))]
-                                                                             (-> flowdef
-                                                                                (update-in [:pipe-to-source] (partial merge {id (first ancestors)}))
-                                                                                (update-in [:pipes] (partial merge {id pipe}))))
-                          (contains? (:pipes flowdef) (first ancestors)) (let [pipe ((:pipes flowdef) (first ancestors))]
-                                                                           (-> flowdef
-                                                                               ;(update-in [:pipe-to-pipe] (partial merge {(first ancestors) id}))
-                                                                               (update-in [:pipes] (partial merge {id (Pipe. (str id) pipe)}))
-                                                                               ))
-                          :else (do
-                                  (println "flowdef" flowdef)
-                                  (println "id" id)
-                                  (println "ancestors" ancestors)
-                                  (throw (Exception. "not implemented")))
-                          )]
+  (let [new-flowdef (reduce (fn [def ancestor]
+                              (cond (contains? (:sources def) ancestor) (let [pipe (Pipe. (str id))]
+                                                                          (-> def
+                                                                              (update-in [:pipe-to-source] (partial merge {id ancestor}))
+                                                                              (update-in [:pipes] (partial merge {id pipe}))))
+                                    (contains? (:pipes def) ancestor) (let [pipe ((:pipes def) ancestor)]
+                                                                        (-> def
+                                                                            (update-in [:pipes] (partial merge {id (Pipe. (str id) pipe)}))))
+                                    :else (do
+                                            (println "flowdef" flowdef)
+                                            (println "id" id)
+                                            (println "ancestors" ancestors)
+                                            (throw (Exception. "not implemented")))))
+                            flowdef ancestors
+                            )]
     (reduce (fn [def cmd] (command->flowdef (assoc cmd :pipe id) def)) new-flowdef projections)))

 (defmethod command->flowdef :default


Fix a bug in r.m.stacktrace that coused it to omit the stack elements in the response.

--- ring-devel/src/ring/middleware/stacktrace.clj
+++ ring-devel/src/ring/middleware/stacktrace.clj
@@ -22,18 +22,19 @@
       [:td.method (h (java-method-str elem))]]))

 (defn- html-ex-view [e]
-  (html
-    (doctype :xhtml-transitional)
-    [:html {:xmlns "http://www.w3.org/1999/xhtml"}
-      [:head
-        [:meta {:http-equiv "Content-Type" :content "text/html;charset=utf-8"}]
-        [:title "Ring: Stacktrace"]
-        [:style {:type "text/css"} css]
-        [:body
-          [:div#content
-            [:h3.info (h (str e))]
-            [:table.trace [:tbody
-              (map elem-partial (:trace-elems e))]]]]]]))
+  (let [e-parsed (parse-exception e)]
+    (html
+      (doctype :xhtml-transitional)
+      [:html {:xmlns "http://www.w3.org/1999/xhtml"}
+        [:head
+          [:meta {:http-equiv "Content-Type" :content "text/html;charset=utf-8"}]
+          [:title "Ring: Stacktrace"]
+          [:style {:type "text/css"} css]
+          [:body
+            [:div#content
+              [:h3.info (h (str e))]
+              [:table.trace [:tbody
+                (map elem-partial (:trace-elems e-parsed))]]]]]])))

 (defn- html-ex-response [e]
   (-> (response (html-ex-view e))


fix length

fix length

--- src/ci3/agent/core.clj
+++ src/ci3/agent/core.clj
@@ -100,7 +100,7 @@
 (def base-url (or (environ/env :ci3-config-base-url) "http://cleo-ci.health-samurai.io/"))

 (defn err-msg [err]
-  (when (> (count err) 500) (subs err 0 500) err))
+  (if (> (count err) 2000) (subs err 0 2000) err))
 (defn notify [st build & text]
   (telegram/notify (str st " build " (get-in build [:repository]) " \n"
                         (get-in build [:commit :message]) " \n"
@@ -130,7 +130,7 @@
                 (if st
                   (let [res (do-step st env)]
                     (if-not (= 0 (:exit res))
-                      (error build res)
+                      (error build st)
                       (recur res sts)))
                   (do
                     (println "==========================================\nDONE in "


revert to callback streaming

revert to callback streaming

--- src/clj/ceres/core.clj
+++ src/clj/ceres/core.clj
@@ -13,7 +13,7 @@
             [gezwitscher.core :refer [start-filter-stream gezwitscher]]
             [clojure.java.io :as io]
             [clojure.core.async :refer [close! put! timeout sub chan <!! >!! <! >! go go-loop] :as async]
-            [taoensso.timbre :as timbre]))
+            [taoensso.timbre :refer [info debug error warn] :as timbre]))

 (timbre/refer-timbre)

@@ -90,6 +90,7 @@
                       (remove nil?)
                       (mapv format-article))
         data (extract-tweet-data tweet)]
+    (debug (str "Storing tweet " (:id tweet)))
     (swap! state update-in [:app :recent-articles] (fn [old new] (vec (take 250 (into new old)))) articles)
     (when (not(empty? articles))
       (doall (map #(put! % {:topic :new-article :data articles}) (-> @state :app :out-chans))))
@@ -131,8 +132,8 @@
                  (io/resource "public/index.html"))))

-(defn -main [& args]
-  (initialize server-state (first args))
+(defn -main [config-path & args]
+  (initialize server-state config-path)
   (timbre/set-config! [:appenders :spit :enabled?] true)
   (timbre/set-config! [:shared-appender-config :spit-filename] (:logfile @server-state))
   (info "Starting twitter collector...")
@@ -141,7 +142,8 @@
   (info @server-state)
   (when (:http-server? @server-state)
     (run-server (site #'all-routes) {:port (:port @server-state) :join? false}))
-  (start-stream server-state)
+  (let [{{:keys [follow track credentials]} :app} @server-state]
+    (start-filter-stream follow track (partial stream-handler server-state) credentials))
   (when (:backup? @server-state)
     (start-executor (:backup-folder @server-state))))

@@ -149,6 +151,11 @@
 (comment

   (initialize server-state "opt/server-config-1.edn")
+
+  (let [{{:keys [follow track credentials]} :app} @server-state]
+    (start-filter-stream follow track (partial stream-handler server-state) credentials))
+
+  (stop-stream)

   (def g (start-stream server-state))


Cloud breakers now count installed breakers hosted on cards (Dinosaurus, London Library).

--- src/clj/game/cards.clj
+++ src/clj/game/cards.clj
@@ -658,8 +658,7 @@
    {:abilities [{:req (req (empty? (:hosted card))) :cost [:click 1]
                  :prompt "Choose a non-AI icebreaker to install on Dinosaurus"
                  :choices (req (filter #(and (has? % :subtype "Icebreaker")
-                                             (not (has? % :subtype "AI"))
-                                             (<= (:cost %) (:credit runner)))
+                                             (not (has? % :subtype "AI")))
                                        (:hand runner)))
                  :msg (msg "host " (:title target))
                  :effect (effect (gain :memory (:memoryunits target))
@@ -2476,9 +2475,6 @@
                     (move target :hand) (shuffle! :deck))
     :choices (req (filter #(has? % :subtype "Icebreaker") (:deck runner)))}

-   "Spike"
-   {:abilities [{:msg "break up to 3 barrier subroutines" :effect (effect (trash card {:cause :ability-cost}))}]}
-
    "Spinal Modem"
    {:effect (effect (gain :memory 1)) :leave-play (effect (lose :memory 1)) :recurring 2
     :events {:successful-trace {:req (req run) :effect (effect (damage :brain 1 {:card card}))}}}
@@ -2626,7 +2622,10 @@
    {:effect (effect (run :rd) (access-bonus 2))}

    "The Personal Touch"
-   {:hosting {:req #(and (has? % :subtype "Icebreaker") (:installed %))}}
+   {:hosting {:req #(and (has? % :subtype "Icebreaker") (:installed %))}
+    :effect (effect (update-breaker-strength (:host card)))
+    :events {:pre-breaker-strength {:req (req (= (:cid target) (:cid (:host card))))
+                                    :effect (effect (breaker-strength-bonus 1))}}}

    "The Supplier"
    {:abilities [{:label "Host a resource or piece of hardware" :cost [:click 1]
@@ -2921,11 +2920,11 @@
                 {:cost [:credit 1] :msg "add 1 strength" :effect (effect (pump card 1))}]}

    "Crowbar"
-   {:abilities [{:msg "break up to 3 code gate subroutines" :effect (effect (trash card))}]
+   {:abilities [{:msg "break up to 3 code gate subroutines" :effect (effect (trash card {:cause :ability-cost}))}]
     :events (let [cloud {:req (req (has? target :subtype "Icebreaker"))
                          :effect (effect (update-breaker-strength card))}]
               {:runner-install cloud :trash cloud :card-moved cloud})
-    :strength-bonus (req (count (filter #(has? % :subtype "Icebreaker") (get-in runner [:rig :program]))))}
+    :strength-bonus (req (count (filter #(has? % :subtype "Icebreaker") (all-installed state :runner))))}

    "Crypsis"
    {:abilities [{:cost [:credit 1] :msg "break ICE subroutine"}
@@ -3070,10 +3069,18 @@
                 {:cost [:credit 1] :msg "add 2 strength" :effect (effect (pump card 2))}]}

    "Shiv"
-   {:abilities [{:msg "break up to 3 sentry subroutines" :effect (effect (trash card {:cause :ability-cost}))}]}
+   {:abilities [{:msg "break up to 3 sentry subroutines" :effect (effect (trash card {:cause :ability-cost}))}]
+    :events (let [cloud {:req (req (has? target :subtype "Icebreaker"))
+                         :effect (effect (update-breaker-strength card))}]
+              {:runner-install cloud :trash cloud :card-moved cloud})
+    :strength-bonus (req (count (filter #(has? % :subtype "Icebreaker") (all-installed state :runner))))}

    "Spike"
-   {:abilities [{:msg "break up to 3 barrier subroutines" :effect (effect (trash card {:cause :ability-cost}))}]}
+   {:abilities [{:msg "break up to 3 barrier subroutines" :effect (effect (trash card {:cause :ability-cost}))}]
+    :events (let [cloud {:req (req (has? target :subtype "Icebreaker"))
+                         :effect (effect (update-breaker-strength card))}]
+              {:runner-install cloud :trash cloud :card-moved cloud})
+    :strength-bonus (req (count (filter #(has? % :subtype "Icebreaker") (all-installed state :runner))))}

    "Study Guide"
    {:abilities [{:cost [:credit 1] :msg "break 1 code gate subroutine"}


Remove cruft

Remove cruft

--- src/clj/inky/entry.clj
+++ src/clj/inky/entry.clj
@@ -369,10 +369,6 @@

 (def $four-oh-four
-  #_($layout
-      {:content
-       [:div
-        [:h1 {:style "font-size: 100px; text-align: center; margin-top: 150px;"} "404"]]})
   (hp/html5
     [:head
      [:title "404 | inky.cc"]


Fix some bugs in the VM, add comments

Fix some bugs in the VM, add comments

--- src/cljx/revue/vm.cljx
+++ src/cljx/revue/vm.cljx
@@ -165,18 +165,20 @@
 (defmethod print-method Env [env writer]
   (.write writer (str "#" (print-str (class env)) "{:frames " (frames env) "}")))

-(defn env-value [vm-state {:keys [frame slot]}]
+(defn env-value
   "Return the value at position `[frame slot]` in `vm-state`'s
   environment.  This is similar to `(get-in env [frame slot])` but
   throws if the index is out of bounds (which can only result from a
   compiler error)."
+  [vm-state {:keys [frame slot]}]
   (let [env (:env vm-state)
         frame-vector (nth env frame)]
     (nth frame-vector slot)))

-(defn set-local-var-from-stack [{:keys [env stack] :as vm-state} {:keys [frame slot]}]
+(defn set-local-var-from-stack
   "Set the value at position `[frame slot]` in `vm-state`'s
   environment to `new-value`."
+  [{:keys [env stack] :as vm-state} {:keys [frame slot]}]
   (assoc vm-state
     :env (assoc-in (:env vm-state) [frame slot] (peek stack))
     :stack (pop (:stack vm-state))))
@@ -185,28 +187,34 @@
 ;;; The Global Environment
 ;;; ======================

-(defn make-global-env []
+(defn make-global-env
   "Create a hash table that serves as the global environment."
+  []
   {})

 ;;; The VM State
 ;;; ============

-(defn make-return-address [{:keys [function pc env]}]
+(defn make-return-address
+  "Create a new return address that jumps to step `pc` in `function`."
+  [{:keys [function pc env]}]
   {:type :return-address
    :function function
    :pc pc
    :env env})

-(defn make-fn [{:keys [code env name args]}]
+(defn make-fn
+  "Create a new bytecode-interpreted function."
+  [{:keys [code env name args]}]
   {:type :bytecode-function
    :code code
    :env env
    :name name
    :args args})

-(defn initial-state [f]
+(defn initial-state
   "Create a new state for a VM, initially executing function `f`"
+  [f]
   {:type :vm-state
    :function f
    :code (:code f)
@@ -231,8 +239,9 @@
 ;;; VM Instructions
 ;;; ===============

-(defn make-prim [symbol n-args opcode always? side-effect?]
+(defn make-prim
   "Create a new primitive instruction."
+  [symbol n-args opcode always? side-effect?]
   {:type :primitive-instruction
    :symbol symbol
    :n-args n-args
@@ -366,7 +375,16 @@
   (-opcode [this]
     'CALLJ))

-(defn move-args-from-stack-to-env [n-args vm-state & n-rest-args]
+(defn move-args-from-stack-to-env
+  "If `n-rest-args` is falsy, pop `n-args` arguments from the stack
+  and put them in a newly created environment frame.  If `n-rest-args`
+  is truthy it must be an integer, in that case `n-args` +
+  `n-rest-args` arguments are popped from the stack; the first
+  `n-args` are put in individual slots in the newly created
+  environment frame, the last `n-rest-args` are collected into a
+  vector and put in the (`n-args` + 1)st slot in the new environment
+  frame."
+  [n-args vm-state & n-rest-args]
   (let [stack (:stack vm-state)
         tmp-frame (vec (take n-args stack))
         tmp-stack (drop n-args stack)
@@ -436,11 +454,11 @@
   VmInst
   (-step [this vm-state]
     (assoc vm-state :stack
-           (make-fn :code (assemble '((args 1)
-                                      (lvar 1 0 stack)
-                                      (set-cc)
-                                      (lvar 0 0 fun)
-                                      (return)))
+           (make-fn :code (assemble '((ARGS 1)
+                                      (LVAR 1 0 stack)
+                                      (SET-CC)
+                                      (LVAR 0 0 fun)
+                                      (RETURN)))
                     :env (->Env [(:stack vm-state)])
                     :name '%cc
                     :args '[fun])))
@@ -468,14 +486,23 @@
     'OP))

-(defn step [vm-state]
+(defn step
   "Run a single step of the VM starting in `vm-state`.  If the VM is
   stopped, i.e., `(:stopped? vm-state)` is true, then return the state
   unchanged."
+  [vm-state]
   (if (:stopped? vm-state)
     vm-state
     (let [instr (nth (:code vm-state) (:pc vm-state))]
-      (-step instr (update-in vm-state :pc inc)))))
+      (-step instr (assoc vm-state
+                     :pc (inc (:pc vm-state))
+                     :instr instr)))))
+
+
+;;; The Assembler
+;;; =============
+
+(defn assemble [])

 ;;; The VM Proper
 ;;; =============


Properly report extra error data

Properly report extra error data

The ex-data and extra bits weren't making it to the :extra attribute of
the sentry report.

--- src/clojars/errors.clj
+++ src/clojars/errors.clj
@@ -8,19 +8,25 @@
   (:import java.util.UUID))

-(defn raven-event-info [message e extra]
+(defn raven-extra-data [e extra]
+  (-> (ex-data e)
+    (merge extra)
+    (dissoc :message)))
+
+(defn raven-event-info [id message e extra]
   (cond-> {}
           message (assoc :message message)
           e (interfaces/stacktrace e ["clojars"])
-          extra (merge extra)))
+          (or e extra) (assoc :extra (raven-extra-data e extra))
+          id (assoc-in [:extra :error-id] id)))

 (defn raven-error-report
-  ([dsn message e extra]
-   (raven-clj/capture dsn (raven-event-info message e extra)))
-  ([dsn message e]
-   (raven-clj/capture dsn (raven-event-info message e nil)))
-  ([dsn message]
-   (raven-clj/capture dsn (raven-event-info message nil nil))))
+  ([dsn id message e extra]
+   (raven-clj/capture dsn (raven-event-info id message e extra)))
+  ([dsn id message e]
+   (raven-error-report dsn id message e nil))
+  ([dsn id message]
+   (raven-error-report dsn id message nil nil)))

 (defprotocol ErrorReporter
   (-report-error [reporter e extra id]))
@@ -29,13 +35,15 @@
    ErrorReporter
    (-report-error [_ e extra id]
      (raven-error-report (:dsn raven-config)
+                         id
                          (or (:message extra) "RavenErrorReporter capture")
                          e
-                         (merge extra {:extra {:error-id id}})))
+                         extra))

    Thread$UncaughtExceptionHandler
    (uncaughtException [this thread throwable]
      (raven-error-report (:dsn raven-config)
+                         nil
                          ("UncaughtExceptionHandler capture")
                          throwable)))


Added function to allow updating specific XML elements at a given path.

--- src/cmr/common/xml.clj
+++ src/cmr/common/xml.clj
@@ -15,6 +15,25 @@
             (mapcat #(children-by-tag % tag) elements))
           [element]
           path))
+
+(defn update-elements-at-path
+  "Calls updater-fn with each element at the specified path. Replaces the element with the result of
+  calling the function. This has not been optimized for speed. Works by recursively replacing elements
+  that are the parents of the updated nodes. Calls updater-fn with the element and any supplied args."
+  [element path updater-fn & args]
+  (if (= 0 (count path))
+    (apply updater-fn (cons element args))
+    (let [tag (first path)
+          rest-of-path (rest path)]
+      (update-in
+        element [:content]
+        (fn [children]
+          (map (fn [child]
+                 (if (= tag (:tag child))
+                   (apply update-elements-at-path
+                          (concat [child rest-of-path updater-fn] args))
+                   child))
+               children))))))

 (defn element-at-path
   "Returns a single element from within an XML structure at the given path."


make initial val a map not vector

make initial val a map not vector

--- kafka-clj/src/kafka_clj/client.clj
+++ kafka-clj/src/kafka_clj/client.clj
@@ -340,7 +340,7 @@
                                           new-meta-producers (reduce (fn [m {:keys [host port]}]
                                                                        (if-not (get metadata-producer-map {:host host :port port})
                                                                          (assoc m {:host host :port port} (metadata-request-producer host port conf))
-                                                                         m)) [] (map deref producers))]
+                                                                         m)) {} (map deref producers))]
                                       (dosync (alter metadata-producers-ref (fn [coll] (apply conj coll (vals new-meta-producers)))))))

         ;try each metadata-producer-ref entry in search of metadata


flushed out initial implementation for all /api/org/* endpoints.

--- src/metabase/api/org.clj
+++ src/metabase/api/org.clj
@@ -2,76 +2,116 @@
   (:require [compojure.core :refer [defroutes GET PUT POST DELETE]]
             [metabase.api.common :refer :all]
             [metabase.db :refer :all]
-            [metabase.models.org :refer [Org]]))
-
-(def org-list
-  (GET "/" request
-       ;; TODO - implementation
-       {:status 200
-        :body {}}))
-
-(def org-post
-  (POST "/" [:as {body :body}]
-        ;; TODO - implementation
-        {:status 200
-         :body {}}))
-
-(def org-get
-  (GET "/:org-id" [org-id]
-       ;; TODO - implementation
-       {:status 200
-        :body {}}))
-
-(defendpoint GET "/slug/:org-slug" [org-slug]
-  (or-404-> (sel :one Org :slug org-slug)))
-
-(def org-update
-  (PUT "/:org-id" [org-id :as {body :body}]
-       ;; TODO - implementation
-       {:status 200
-        :body {}}))
-
-(def org-members-list
-  (GET "/:org-id/members" [org-id]
-       ;; TODO - implementation
-       {:status 200
-        :body {}}))
-
-(def org-members-create
-  (POST "/:org-id/members" [org-id :as {body :body}]
-       ;; TODO - implementation
-       {:status 200
-        :body {}}))
-
-(def org-members-adduser
-  (GET "/:org-id/members/:user-id" [org-id user-id]
-       ;; TODO - implementation
-       {:status 200
-        :body {}}))
-
-(def org-members-updateuser
-  (PUT "/:org-id/members/:user-id" [org-id user-id :as {body :body}]
-       ;; TODO - implementation
-       {:status 200
-        :body {}}))
-
-(def org-members-removeuser
-  (DELETE "/:org-id/members/:user-id" [org-id user-id]
-       ;; TODO - implementation
-       {:status 200
-        :body {}}))
+            [metabase.models.hydrate :refer :all]
+            (metabase.models [org :refer [Org]]
+                             [user :refer [User]]
+                             [org-perm :refer [OrgPerm]])))

-(define-routes routes
-  ;; TODO - this feels bleh.  is it better to put the actual route data here
-  ;;        and just have the endpoints be plain functions?
-  ;;        best way to automate building this list?
-  org-list
-  org-post
-  org-get
-  org-update
-  org-members-list
-  org-members-create
-  org-members-adduser
-  org-members-updateuser
-  org-members-removeuser)
+(defendpoint GET "/" []
+  ;; TODO - permissions check
+  (sel :many Org))
+
+
+(defendpoint POST "/" [:as {body :body}]
+  ;; TODO - implementation
+  {:status 200
+   :body {}})
+
+
+(defendpoint GET "/:id" [id]
+  ;; TODO - permissions check
+  (or-404-> (sel :one Org :id id)))
+
+
+(defendpoint GET "/slug/:slug" [slug]
+  ;; TODO: permissions check
+  (or-404-> (sel :one Org :slug slug)))
+
+
+(defendpoint PUT "/:id" [id :as {body :body}]
+  ;; TODO - permissions check
+  ;; TODO - validations (email address must be unique)
+  (let-or-404 [org (sel :one Org :id id)]
+    ;; TODO - how can we pass a useful error message in the 500 response on error?
+    (upd Org id
+      ;; TODO - find a way to make this cleaner.  we don't want to modify the value if it doesn't exist
+      :name (get body :name (:name org))
+      :description (get body :description (:description org))
+      :logo_url (get body :logo_url (:logo_url org)))
+    (sel :one Org :id id)))
+
+
+(defn grant-org-perm
+  "Grants permission for given User on Org.  Creates record if needed, otherwise updates existing record."
+  [user-id org-id is-admin]
+  (let [perm (sel :one OrgPerm :user_id user-id :organization_id org-id)]
+    (if-not perm
+      (ins OrgPerm
+        :user_id user-id
+        :organization_id org-id
+        :admin is-admin)
+      (upd OrgPerm (:id perm)
+        :admin is-admin))))
+
+
+(defendpoint GET "/:id/members" [id]
+  ;; TODO - permissions check
+  (with-or-404 (sel :one Org :id id)
+    (-> (sel :many OrgPerm :organization_id id)
+      ;; TODO - we need a way to remove :organization_id and user_id from this output
+      (hydrate :user :organization))))
+
+
+(defendpoint POST "/:id/members" [id :as {body :body}]
+  ;; TODO - permissions check
+  ; find user with existing email - if exists then grant perm
+  (let-or-404 [org (sel :one Org :id id)]
+    (let [user (sel :one User :email (:email body))]
+      (if-not user
+        (let [new-user-id (ins User
+                            :email (:email body)
+                            :first_name (:first_name body)
+                            :last_name (:last_name body)
+                            :password (str (java.util.UUID/randomUUID))
+                            :date_joined (new java.util.Date)
+                            :is_staff true
+                            :is_active true
+                            :is_superuser false)]
+          (grant-org-perm (:id new-user-id) (:id org) (:admin body))
+          ;; TODO - send signup email
+          (-> (sel :one OrgPerm :user_id (:id new-user-id) :organization_id (:id org))
+            (hydrate :user :organization)))
+        (do
+          (grant-org-perm (:id user) (:id org) (:admin body))
+          (-> (sel :one OrgPerm :user_id (:id user) :organization_id (:id org))
+              (hydrate :user :organization)))))))
+
+
+(defendpoint POST "/:id/members/:user-id" [id user-id :as {body :body}]
+  ;; TODO - permissions check
+  (let-or-404 [org (sel :one Org :id id)]
+    (let-or-404 [user (sel :one User :id user-id)]
+      (grant-org-perm user-id id (or (:admin body) false))
+      {:success true})))
+
+
+(defendpoint PUT "/:id/members/:user-id" [id user-id :as {body :body}]
+  ;; TODO - permissions check
+  ;; HMMM, same body as endpoint above in this case.  how can we unify the impl of 2 endpoints?
+  (let-or-404 [org (sel :one Org :id id)]
+    (let-or-404 [user (sel :one User :id user-id)]
+      (grant-org-perm user-id id (or (:admin body) false))
+      {:success true})))
+
+
+(defendpoint DELETE "/:id/members/:user-id" [id user-id :as {body :body}]
+  ;; TODO - permissions check
+  ;; HMMM, same body as endpoint above in this case.  how can we unify the impl of 2 endpoints?
+  (let-or-404 [org (sel :one Org :id id)]
+    (let-or-404 [user (sel :one User :id user-id)]
+      (del OrgPerm :user_id user-id :organization_id id)
+      {:success true})))
+
+
+(define-routes)


fix problem with position name; fix typo in check-for-serious-error

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

--- acqEngine/src/org/micromanager/acq_engine.clj
+++ acqEngine/src/org/micromanager/acq_engine.clj
@@ -81,7 +81,7 @@

 (defn check-for-serious-error []
   (when (.. MMStudioMainFrame seriousErrorReported_ get)
-    (swap! state :stop true)))
+    (swap! state assoc :stop true)))

 ;; time

@@ -119,6 +119,7 @@
   (merge
     (map-config (core getSystemStateCache))
     (:metadata event)
+    (println "pos-ndex" (:position-index event))
     (let [[x y] (let [xy-stage (state :default-xy-stage)]
                   (when-not (empty? xy-stage)
                     (get-in state [:last-stage-positions xy-stage])))]
@@ -138,7 +139,9 @@
        "PixelSizeUm" (state :pixel-size-um)
        "PixelType" (state :pixel-type)
        "PositionIndex" (:position-index event)
-       "PositionName" (if-let [pos (:position-index event)] (if-args #(.getLabel %) (get-msp pos)))
+       "PositionName" (when-lets [pos (:position-index event)
+                                  msp (get-msp pos)]
+                                 (.getLabel msp))
        "Slice" (:slice-index event)
        "SliceIndex" (:slice-index event)
        "SlicePosition" (:slice event)


print just json

print just json

--- src/athena_cmd/core.clj
+++ src/athena_cmd/core.clj
@@ -37,8 +37,6 @@
 (defn -main
   [& args]

-  (println "executing query")
-
   (let [query (slurp (nth args 0))
         rs (.executeQuery stmt query)
         m (.getMetaData rs)]


Add some tests

Add some tests

--- test/caesium/crypto/generichash_test.clj
+++ test/caesium/crypto/generichash_test.clj
@@ -3,14 +3,32 @@
             [caesium.crypto.util :refer [unhexify array-eq]]
             [clojure.test :refer :all]))

+(def empty-string-digest (unhexify "786a02f742015903c6c6fd852552d272912f4740e15847618a86e217f71f5419d25e1031afee585313896444934eb04b903a685b1448b755d56f701afe9be2ce"))
+
+(def blake2b-empty-args-variations
+  "All of the different ways you could spell that you want the digest
+  of the empty string: with or without key, salt, and
+  personalization.
+
+  When given to the blake2b function, all of these should return the
+  empty string digest."
+  (for [key-expr [[] [:key (byte-array 0)]]
+        salt-expr [[] [:salt (byte-array 16)]]
+        personal-expr [[] [:personal (byte-array 16)]]]
+    (flatten (conj [(byte-array 0)] key-expr salt-expr personal-expr))))
+
 (deftest blake2b-kat-test
   (testing "blake2b works directly"
     (are [args expected] (array-eq (apply blake2b args)
                                    expected)
-        [(byte-array [])] (unhexify "786a02f742015903c6c6fd852552d272912f4740e15847618a86e217f71f5419d25e1031afee585313896444934eb04b903a685b1448b755d56f701afe9be2ce")
+        [(byte-array [])] empty-string-digest
         [(byte-array [90])] (unhexify "4884256d056fb76f83f10ab85c127682d447d126d99dee526883488f57951fffb576a16d8a7fd391420e23b7c0cf14b413878de095dc3d84bcaecba0bc657c77")
         [(.getBytes "The quick brown fox jumps over the lazy dog")
          :key (.getBytes "This is a super secret key. Ssshh!")
          :salt (.getBytes "0123456789abcdef")
          :personal (.getBytes "fedcba9876543210")]
-        (unhexify "9479874d504f0447d43d72a969c989c34032172276ac50077e0027277c3c8d867bee9ee314c8506e4e4a9b3030b989d3eb7b4c1826c8e0d56e6aa71b1d4cf388")
+        (unhexify "9479874d504f0447d43d72a969c989c34032172276ac50077e0027277c3c8d867bee9ee314c8506e4e4a9b3030b989d3eb7b4c1826c8e0d56e6aa71b1d4cf388")))
+  (testing "blake2b defaults are accurate"
+    (let [results (map #(apply blake2b %) blake2b-empty-args-variations)
+          empty-string-digest? (partial array-eq empty-string-digest)]
+      (is (every? empty-string-digest? results)))))


✅ Test that the new and old congregation queries are equivalent

--- test/territory_bro/congregation_test.clj
+++ test/territory_bro/congregation_test.clj
@@ -175,3 +175,26 @@
               "unrelated congregation"))))

     (testing "superadmin can access all congregations"))) ; TODO
+
+(comment
+  (congregation/update-cache! db/database)
+  (:state @congregation/cache)
+
+  (is (= (set (congregation/get-unrestricted-congregations db/database))
+         (set (->> (vals (:state @congregation/cache))
+                   (map #(dissoc % :congregation/user-permissions))))))
+
+  (doseq [{:keys [congregation user]} (set (->> (jdbc/query db/database ["select * from congregation_access"])
+                                                (doall)))]
+    (is (= (congregation/get-my-congregation db/database congregation user)
+           (-> (congregation/get-my-congregation2 (:state @congregation/cache) congregation user)
+               (dissoc :congregation/user-permissions)))))
+
+  (is (= (set (->> (jdbc/query db/database ["select * from congregation_access"])
+                   (doall)))
+         (set (->> (vals (:state @congregation/cache))
+                   (mapcat (fn [cong]
+                             (map (fn [[user perms]]
+                                    {:congregation (:congregation/id cong)
+                                     :user user})
+                                  (:congregation/user-permissions cong)))))))))


Fix version parsin

Fix version parsin

--- src/uio/main.clj
+++ src/uio/main.clj
@@ -62,7 +62,7 @@
         (errln "Version:" (str "["
                                (try (->> (uio/from "res:///META-INF/leiningen/uio/uio/project.clj")
                                          slurp
-                                         (re-find #"^\(defproject (.+)\"")
+                                         (re-find #"^\(defproject (.+\")")
                                          second)
                                     (catch Throwable _ "unknown"))
                                "]"))


cleanup

cleanup

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -106,19 +106,18 @@
 (defn comp-path-to-bolts
   "return a lazy sequence of bolts for all possible complements that can be added to the end of the _path_ within _bolt_."
   [bolt path model depth max-depth]
-  (when (and (not (nil? bolt)))
-    (let [spec (get-in bolt path)
-          lexemes (get-lexemes model spec)
-          bolts-at (if (< depth max-depth)
-                     (lightning-bolts
-                      model
-                      (get-in bolt path)
-                      depth max-depth))
-          lexemes-before-phrases
-          (lexemes-before-phrases depth max-depth)]
-      (if lexemes-before-phrases
-        (lazy-cat lexemes bolts-at)
-        (lazy-cat bolts-at lexemes)))))
+  (let [spec (get-in bolt path)
+        lexemes (get-lexemes model spec)
+        bolts-at (if (< depth max-depth)
+                   (lightning-bolts
+                    model
+                    (get-in bolt path)
+                    depth max-depth))
+        lexemes-before-phrases
+        (lexemes-before-phrases depth max-depth)]
+    (if lexemes-before-phrases
+      (lazy-cat lexemes bolts-at)
+      (lazy-cat bolts-at lexemes))))

 (defn add-comps
   "given a bolt, return the lazy sequence of all bolts derived from this bolt after adding,


s/map/pmap/

s/map/pmap/

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -85,16 +85,15 @@
             depth (if depth depth 0)
             parents (filter #(not (fail? %)) (map (fn [rule] (unifyc spec rule)) grammar))]
         (let [lexical ;; 1. generate list of all phrases where the head child of each parent is a lexeme.
-              (mapcat (fn [parent]
-                        (if (= false (get-in parent [:head :phrasal] false))
-                          (let [candidate-lexemes (get-lex parent :head index spec)]
-                            (if (some fail? candidate-lexemes)
-                              (exception (str "some candidate lexeme was fail?=true!")))
-                            (over/overh parent
-                                        (map copy (lazy-shuffle candidate-lexemes))))))
-                      parents)
+              (reduce concat
+                      (map (fn [parent]
+                             (if (= false (get-in parent [:head :phrasal] false))
+                               (let [candidate-lexemes (get-lex parent :head index spec)]
+                                 (over/overh parent
+                                             (map copy (lazy-shuffle candidate-lexemes))))))
+                           parents))
               phrasal ;; 2. generate list of all phrases where the head child of each parent is itself a phrase.
-              (if (< depth maxdepth)
+              (if (< depth max-total-depth)
                 (mapcat (fn [parent]
                           (over/overh parent (lightning-bolt grammar lexicon (get-in parent [:head])
                                                              (+ 1 depth) index morph (+ 1 total-depth))))
@@ -138,7 +137,7 @@
                                   ",path=" path ",bolt=(" (show-bolt bolt path morph) ")=>"
                                   "'" (morph complement) "'"))
                   true)))
-            (map (fn [complement]
+            (pmap (fn [complement]
                    (unify (copy bolt)
                           (path-to-map path
                                        (copy complement))))


re-add (filter non-fails) that was removed in commit 183ab5ac95d7fd1b8507bb5a8acb2ba732d63256

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -193,50 +193,51 @@
                                        (and (not-fail? (unify (strip-refs (get-in lexeme [:synsem] :top))
                                                               bolt-child-synsem))))
                                      complement-candidate-lexemes))]
-    (mapfn (fn [complement]
-             (let [unified
-                   (unify (copy bolt)
-                          (assoc-in {} path
-                                    (copy complement)))]
-               (if truncate-children
-                 (truncate unified [path] language-model)
-                 unified)))
-           (let [phrasal-complements (if (and (> max-total-depth total-depth)
-                                              (= true (get-in spec [:phrasal] true)))
-                                       (generate-all spec language-model (+ (count path) total-depth)
-                                                     :max-total-depth max-total-depth))
-                 lexemes-before-phrases (lexemes-before-phrases total-depth max-total-depth)]
-             (cond (and lexemes-before-phrases
-                        (empty? lexical-complements)
-                        (= false (get-in spec [:phrasal] true)))
-                   (log/warn (str "failed to generate any lexical complements with spec: "
+    (filter #(not-fail? %)
+            (mapfn (fn [complement]
+                     (let [unified
+                           (unify (copy bolt)
+                                  (assoc-in {} path
+                                            (copy complement)))]
+                       (if truncate-children
+                         (truncate unified [path] language-model)
+                         unified)))
+                   (let [phrasal-complements (if (and (> max-total-depth total-depth)
+                                                      (= true (get-in spec [:phrasal] true)))
+                                               (generate-all spec language-model (+ (count path) total-depth)
+                                                             :max-total-depth max-total-depth))
+                         lexemes-before-phrases (lexemes-before-phrases total-depth max-total-depth)]
+                     (cond (and lexemes-before-phrases
+                                (empty? lexical-complements)
+                                (= false (get-in spec [:phrasal] true)))
+                           (log/warn (str "failed to generate any lexical complements with spec: "
                                   (strip-refs spec)))
-
-                   (and lexemes-before-phrases
-                        (= true (get-in spec [:phrasal] false))
-                        (empty? phrasal-complements))
-                   (log/warn (str "failed to generate any phrasal complements with spec: "
-                                  (strip-refs spec)))
-
-                   (and (empty? lexical-complements)
-                        (empty? phrasal-complements))
-
-                   (let [message (str "add-complement-to-bolt: could generate neither phrasal "
-                                      "nor lexical complements for "
+
+                           (and lexemes-before-phrases
+                                (= true (get-in spec [:phrasal] false))
+                                (empty? phrasal-complements))
+                           (log/warn (str "failed to generate any phrasal complements with spec: "
+                                          (strip-refs spec)))
+
+                           (and (empty? lexical-complements)
+                                (empty? phrasal-complements))
+
+                           (let [message (str "add-complement-to-bolt: could generate neither phrasal "
+                                              "nor lexical complements for "
                                       "bolt:" (show-bolt bolt language-model) "; immediate parent: "
                                       (get-in bolt (concat (butlast path) [:rule]) :norule) " "
                                       "while trying to create a complement: "
                                       (spec-info spec)
                                       )]
-                     (log/warn message)
-                     (if error-if-no-complements (exception message)))
-
-                   lexemes-before-phrases
-                   (take max-generated-complements
-                         (lazy-cat lexical-complements phrasal-complements))
-                   true
-                   (take max-generated-complements
-                         (lazy-cat phrasal-complements lexical-complements)))))))
+                             (log/warn message)
+                             (if error-if-no-complements (exception message)))
+
+                           lexemes-before-phrases
+                           (take max-generated-complements
+                                 (lazy-cat lexical-complements phrasal-complements))
+                           true
+                           (take max-generated-complements
+                                 (lazy-cat phrasal-complements lexical-complements))))))))

 (defn bolt-depth [bolt]
   (if-let [head (get-in bolt [:head] nil)]


proposed-per-bolt -> per-path generation (as opposed to per-path -> per-bolt)

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -101,41 +101,52 @@
         expressions
         (->
          (lightning-bolts language-model spec 0 total-depth :max-total-depth max-total-depth)
-         (add-all-comps (take max-total-depth (repeatedly (fn [] :head)))
-                        language-model total-depth))]
+         (add-all-comps-to-bolts spec language-model total-depth))]
     (map (fn [expr]
-           (if truncate-children
-             (truncate expr [[:head][:comp]])
-             ;; else, don't truncate for efficiency (i.e. don't remove :head and :comp).
+           (if (and false truncate-children)
+             (truncate expr [[:head][:comp]]) ;; remove :head and :comp for efficiency
+             ;; else, don't remove.
              expr))
          expressions)))

-(defn add-all-comps [bolts path language-model total-depth]
-  (if (not (empty? path))
-    (add-all-comps
-     (add-complements-to-bolts bolts (concat path [:comp])
-                               language-model total-depth
-                               :max-total-depth max-total-depth)
-     (rest path) language-model total-depth)
-    (add-complements-to-bolts bolts [:comp]
-                              language-model total-depth)))
-
-(defn add-complements-to-bolts [bolts path language-model total-depth
-                                & {:keys [max-total-depth]
-                                   :or {max-total-depth max-total-depth}}]
+(declare find-comp-paths-in)
+(declare add-all-comps-to-bolts-with-paths)
+
+(defn add-all-comps-to-bolts [bolts spec language-model total-depth]
+  (log/debug (str "add-all-comps-to-bolts with (empty? bolts): " (empty? bolts)
+                  "; spec: " (strip-refs spec)))
   (lazy-mapcat
    (fn [bolt]
-     (if (not (= :none (get-in bolt path :none)))
-       (add-complement-to-bolt bolt path :top language-model 0 (+ total-depth (count path))
-                       :max-total-depth max-total-depth)
-       (do
-         (log/warn (str "bolt has no path: " (string/join " " path)))
-         [bolt])))
+     (add-all-comps-to-bolts-with-paths [bolt] spec language-model total-depth
+                                        (find-comp-paths-in bolt [:head])))
    bolts))

+(defn add-all-comps-to-bolts-with-paths [bolts spec language-model total-depth comp-paths]
+  (log/debug (str "add-all-comps-to-bolts-with-paths with (empty? bolts): " (empty? bolts) "; spec: " spec))
+  (if (not (empty? comp-paths))
+    (let [path (first comp-paths)]
+      (add-all-comps-to-bolts-with-paths
+       (lazy-mapcat
+        (fn [bolt]
+          (log/debug (str "adding path: " (string/join " " path) " to bolt: " ((:morph language-model) bolt)))
+          (add-complement-to-bolt bolt path spec
+                                  language-model 0 total-depth
+                                  :max-total-depth max-total-depth))
+        bolts)
+       spec
+       language-model
+       total-depth
+       (rest comp-paths)))
+    bolts))
+
+(defn find-comp-paths-in [bolt path]
+  (if (not (= (get-in bolt path :none) :none))
+    (cons (vec (concat (butlast path) [:comp]))
+          (find-comp-paths-in bolt (concat path [:head])))))
+
 (defn add-complement-to-bolt [bolt path spec language-model depth total-depth
-                      & {:keys [max-total-depth]
-                         :or {max-total-depth max-total-depth}}]
+                              & {:keys [max-total-depth]
+                                 :or {max-total-depth max-total-depth}}]
   (log/debug (str "add-complement-to-bolt: start: " (show-bolt bolt path language-model) "@"
                   (string/join " " path)))
   (let [index (:index language-model)
@@ -301,6 +312,8 @@
 (defn morph-with-recovery [morph-fn input]
   (if (nil? input)
     (exception (str "don't call morph-with-recovery with input=nil.")))
+  (if (nil? morph-fn)
+    (exception (str "don't call morph-with-recovery with morph-fn=nil.")))
   (let [result (morph-fn input)
         result (if (or (nil? result)
                        (= "" result))
@@ -338,15 +351,18 @@
       false)))

 (defn show-bolt [bolt path language-model]
-  (let [morph (:morph language-model)]
-    (if (nil? bolt)
-      (exception (str "don't call show-bolt with bolt=null."))
-      (if (not (empty? path))
-        (str "[" (get-in bolt [:rule])
-             " '" (morph-with-recovery morph bolt) "'"
-             (let [head-bolt (get-in bolt [:head])]
-               (if (not (nil? head-bolt))
-                 (let [rest-str (show-bolt (get-in bolt [:head]) (rest path) language-model)]
-                 (if (not (nil? rest-str))
-                   (str " -> " rest-str)))))
-             "]")))))
+  (if (nil? bolt)
+    (exception (str "don't call show-bolt with bolt=null."))
+    (let [morph (:morph language-model)]
+      (if (nil? morph)
+        (exception (str "don't call show-bolt with morph=null."))
+        (if (not (empty? path))
+          (str "[" (get-in bolt [:rule])
+               " '" (morph-with-recovery morph bolt) "'"
+               (let [head-bolt (get-in bolt [:head])]
+                 (if (not (nil? head-bolt))
+                   (let [rest-str (show-bolt (get-in bolt [:head]) (rest path) language-model)]
+                     (if (not (nil? rest-str))
+                       (str " -> " rest-str)))))
+               "]"))))))
+


comments

comments

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -75,8 +75,9 @@
   (let [spec (get-in bolt path)
         lexemes (shufflefn (get-lexemes model spec))
         bolts-at (if (< depth max-depth)
-                   ((if true nugents
-                        lightning-bolts)
+                   ((if false
+                      nugents ;; nugents is slow
+                      lightning-bolts) ;; lightning-bolts is fast
                     model
                     (get-in bolt path)
                     depth max-depth))


Keep from dropping sessions when the flash is not set.

--- ring-core/src/ring/middleware/flash.clj
+++ ring-core/src/ring/middleware/flash.clj
@@ -15,5 +15,6 @@
                      :flash flash)
           response (handler request)
           session  (if-let [flash (response :flash)]
-                     (assoc (response :session) :_flash flash))]
+                     (assoc (response :session) :_flash flash)
+                     session)]
       (assoc response :session session))))


TRDR-40 for edn namespace

TRDR-40 for edn namespace

--- src/main/cljs/cljs/tools/reader/edn.cljs
+++ src/main/cljs/cljs/tools/reader/edn.cljs
@@ -205,15 +205,17 @@
 (defn- read-map
   [rdr _ opts]
   (let [the-map (read-delimited \} rdr opts)
+        map-count (count the-map)
         ks (take-nth 2 the-map)
-        key-set (set ks)
-        l (to-array the-map)]
-    (when (== 1 (bit-and (alength l) 1))
+        key-set (set ks)]
+    (when (odd? map-count)
       (reader-error rdr "Map literal must contain an even number of forms"))
     (when-not (= (count key-set) (count ks))
       (reader-error rdr (duplicate-keys-error
                          "Map literal contains duplicate key" ks)))
-    (apply hash-map l)))
+    (if (<= map-count (* 2 (.-HASHMAP-THRESHOLD PersistentArrayMap)))
+      (.fromArray PersistentArrayMap (to-array the-map) true true)
+      (.fromArray PersistentHashMap (to-array the-map) true))))

 (defn- read-number
   [reader initch opts]


Fix some comment indentation

Fix some comment indentation

--- src/cascade/request.clj
+++ src/cascade/request.clj
@@ -27,11 +27,11 @@
   "Internal handler for asset requests. Returns the response from the handler, or nil if
 no handler matches the name.
 asset-factories
-Maps keywords for the asset domain (eg., :file or :classpath) to the factory function (which takes a path)
+  Maps keywords for the asset domain (eg., :file or :classpath) to the factory function (which takes a path)
 domain
-Keyword used to locate factory function
+  Keyword used to locate factory function
 path
-String path passed to the handler."
+  String path passed to the handler."
   [asset-factories domain path]
   (let [factory (domain asset-factories)
         asset (and factory (factory path))
@@ -94,7 +94,7 @@

 (defn initialize
   "Initializes asset handling for Cascade. This sets an application version (a value incorporated into URLs, which
-should change with each new deployment. Named arguments:
+  should change with each new deployment. Named arguments:
 :html-routes
   Routes that produce full-page rendered HTML markup. The provided handlers should render the request to a seq
   of DOM nodes.


Reimplement `reference-if-able` logic in Clojure.

`--reference-if-able` is a pretty new Git feature (introduced in 2.11.0.)
Instead of relying on that, we can check whether the directory containing the
repository exists on disk ourselves.

--- src/clj/runbld/main.clj
+++ src/clj/runbld/main.clj
@@ -1,6 +1,7 @@
 (ns runbld.main
   (:gen-class)
   (:require [clj-git.core :as git]
+            [clojure.java.io :as jio]
             [clojure.pprint :refer [pprint]]
             [environ.core :as environ]
             [runbld.build :as build]
@@ -58,8 +59,9 @@
          branch (-> raw-opts :scm :branch)
          depth (-> raw-opts :scm :depth)]
      (when clone?
-       (let [clone-args (->> [(when reference
-                                ["--reference-if-able" reference])
+       (let [clone-args (->> [(when (and reference
+                                         (.exists (jio/as-file reference)))
+                                ["--reference" reference])
                               (when branch ["--branch" (str branch)])
                               (when depth ["--depth" (str depth)])]
                              (filter identity)


* src/cljs/cljs/core.cljs: we have < compiler macro, remove lt-

--- src/cljs/cljs/core.cljs
+++ src/cljs/cljs/core.cljs
@@ -237,9 +237,6 @@
   "Returns a number one greater than num."
   [x] (js* "(~{x} + 1)"))

-(defn- lt- [x y]
-  (js* "(~{x} < ~{y})"))
-
 (defn- ci-reduce
   "Accepts any collection which satisfies the ICount and IIndexed protocols and
 reduces them without incurring seq initialization"
@@ -247,17 +244,17 @@
      (if (= 0 (-count cicoll))
        (f)
        (loop [val (-nth cicoll 0), n 1]
-         (if (lt- n (-count cicoll))
+         (if (< n (-count cicoll))
            (recur (f val (-nth cicoll n)) (inc n))
            val))))
   ([cicoll f val]
      (loop [val val, n 0]
-         (if (lt- n (-count cicoll))
+         (if (< n (-count cicoll))
            (recur (f val (-nth cicoll n)) (inc n))
            val)))
   ([cicoll f val idx]
      (loop [val val, n idx]
-         (if (lt- n (-count cicoll))
+         (if (< n (-count cicoll))
            (recur (f val (-nth cicoll n)) (inc n))
            val))))

@@ -266,7 +263,7 @@
   (-seq [this] this)
   ISeq
   (-first [_] (aget a i))
-  (-rest [_] (if (lt- (inc i) (.length a))
+  (-rest [_] (if (< (inc i) (.length a))
                (IndexedSeq. a (inc i))
                (list)))
   ICounted
@@ -302,9 +299,9 @@
   IIndexed
   (-nth
     ([array n]
-       (if (lt- n (.length array)) (aget array n)))
+       (if (< n (.length array)) (aget array n)))
     ([array n not-found]
-       (if (lt- n (.length array)) (aget array n)
+       (if (< n (.length array)) (aget array n)
            not-found)))

   ILookup


fix re-pattern

fix re-pattern

--- src/cljs/cljs/core.cljs
+++ src/cljs/cljs/core.cljs
@@ -2370,7 +2370,9 @@
 (defn re-pattern
   "Returns an instance of RegExp which has compiled the provided string."
   [s]
-  (doto (js/RegExp. s) (.compile ())))
+  (let [re (js/RegExp. s)]
+    (. re (compile))
+    re))

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Printing ;;;;;;;;;;;;;;;;


CLJS-1073: :dynamic typo for *target*

CLJS-1073: :dynamic typo for *target*

--- src/cljs/cljs/core.cljs
+++ src/cljs/cljs/core.cljs
@@ -17,7 +17,7 @@

 (def *unchecked-if* false)

-(def ^{:dyanmic true
+(def ^{:dynamic true
        :jsdoc ["@define {string}"]}
   *target* "default")


CLJS-777: multimethods are not IFn

CLJS-777: multimethods are not IFn

--- src/cljs/cljs/core.cljs
+++ src/cljs/cljs/core.cljs
@@ -7620,6 +7620,8 @@

 (deftype MultiFn [name dispatch-fn default-dispatch-val hierarchy
                   method-table prefer-table method-cache cached-hierarchy]
+  IFn
+
   IMultiFn
   (-reset [mf]
     (swap! method-table (fn [mf] {}))


Basic support for text/plain output.

Basic support for text/plain output.

--- src/clouseau/server.clj
+++ src/clouseau/server.clj
@@ -280,6 +280,10 @@
         [:div {:class "label label-warning"} (str "Description for the package '" package "' has been updated, thank you!")]
         [:br]
         [:br]])
+
+(defn text-renderer
+    [products package package-descriptions ccs-description products-per-descriptions products-without-descriptions new-description user-name]
+    "TBD")

 (defn html-renderer
     [products package package-descriptions ccs-description products-per-descriptions products-without-descriptions new-description user-name]
@@ -423,10 +427,23 @@
             (-> (http-response/response html-output)
                 (http-response/content-type "text/html")))))

+(defn generate-txt-normal-response
+    [products package package-descriptions ccs-description
+     products-per-description products-without-descriptions new-description user-name]
+     (let [text-output (text-renderer products package package-descriptions ccs-description products-per-description products-without-descriptions new-description user-name)]
+        (store-changes user-name package new-description)
+            (-> (http-response/response text-output)
+                (http-response/content-type "text/plain"))))
+
 (defn generate-error-response
     [package user-name message]
     (-> (http-response/response (render-error-page package user-name message))
         (http-response/content-type "text/html")))
+
+(defn generate-txt-error-response
+    [package user-name message]
+    (-> (http-response/response (str "Sorry, error occured in Clouseau:" message))
+        (http-response/content-type "text/plain")))

 (defn package-error
     "Returns sequence of products for whom the database can't be read