Fix regular expression to detect compilation dependency failures

--- build-support/clojure-compile.clj
+++ build-support/clojure-compile.clj
@@ -55,7 +55,7 @@
        true
        (catch clojure.lang.Compiler$CompilerException e
          (let [msg (.getMessage e)
-               cnfe-pattern #"^java\.lang\.ClassNotFoundException: ([a-zA-z0-9-_.]+) \(.*:\d+\)$"]
+               cnfe-pattern #"^java\.lang\.ClassNotFoundException: ([a-zA-z0-9-_.]+)(, compiling:| )\(.*:\d+\)$"]
            (let [matches (re-matches cnfe-pattern msg)]
              (if matches
                (let [not-found-ns (symbol (matches 1))]


Fix nonexistent import

Fix nonexistent import

--- src/todomvc/events.cljs
+++ src/todomvc/events.cljs
@@ -3,8 +3,7 @@
     [todomvc.db :refer [default-value todos->local-store]]
     [re-frame.core :refer [reg-event-db reg-event-fx inject-cofx path trim-v
                            after debug]]
-    [todomvc.rules :refer [q
-                           find-showing
+    [todomvc.rules :refer [find-showing
                            find-todo
                            find-todos
                            find-max-id


Refactor specs.

Refactor specs.

--- spec/freefrog/rest_spec.clj
+++ spec/freefrog/rest_spec.clj
@@ -39,45 +39,23 @@

 (def host-url "http://localhost:3000")

-(defn http-put-request
-  ([uri]
-   (http-put-request uri nil))
-  ([uri body]
-   (http-put-request uri body nil))
-  ([uri body options]
-   (http-client/put (str host-url uri)
-                    (merge {:throw-exceptions false
-                            :content-type "text/plain"
-                            :body body} options))))
-(defn http-post-request
-  ([uri]
-   (http-post-request uri nil))
-  ([uri body]
-   (http-post-request uri body nil))
-  ([uri body options]
-   (http-client/post (str "http://localhost:3000/" uri)
-                     (merge {:throw-exceptions false
-                             :content-type "text/plain"
-                             :body body} options))))
-
-(defn http-get-request
-  ([]
-   (http-get-request "" nil))
-  ([uri]
-   (http-get-request uri nil))
-  ([uri options]
-   (http-client/get (str "http://localhost:3000/" uri) (merge {:throw-exceptions false} options))))
+(def http-request-fns
+  {:get http-client/get
+   :put http-client/put
+   :post http-client/post})
+
+(defn http-request
+  ([method uri]
+   (http-request method uri nil))
+  ([method uri options]
+   (apply (get http-request-fns method)
+          [(str host-url uri)
+           (merge {:throw-exceptions false
+                   :content-type "text/plain"
+                   :body ""} options)])))

 (defn get-location [response]
   (get (:headers response) "Location"))
-
-(defn should-return-4xx [spec-context uri-fn request-content
-                         response-code response-content]
-  (context spec-context
-    (with response (http-post-request (uri-fn) request-content))
-    (it "should return a bad request"
-      (should= response-code (:status @response))
-      (should-contain response-content (:body @response)))))

 (def sample-gov-log {:body "Add role\nRename accountability."})

@@ -98,21 +76,23 @@
                     p/get-governance-log circle-not-found-thrower
                     p/put-governance-log circle-not-found-thrower]
         (it)))
+
     (context "requesting the governance endpoint"
-      (with response (http-get-request "/circles/1234/governance"))
+      (with response (http-request :get "/circles/1234/governance"))
       (it "should return a 404"
         (should= 404 (:status @response))
         (should= "Circle does not exist" (:body @response))))

     (context "posting to the governance endpoint"
-      (with response (http-post-request "/circles/1234/governance"))
+      (with response (http-request :post "/circles/1234/governance"))
       (it "should return a 400"
         (should= 400 (:status @response))
         (should-contain "Circle does not exist" (:body @response))))

     (context "putting to the agenda endpoint"
-      (with response (http-put-request "/circles/1234/governance/5678/agenda"
-                                       "New agenda"))
+      (with response (http-request :put
+                                   "/circles/1234/governance/5678/agenda"
+                                   {:body "New agenda"}))
       (it "should return a 400"
         (should= 400 (:status @response))
         (should-contain "Circle does not exist" (:body @response)))))
@@ -122,21 +102,22 @@
       (with-redefs [p/get-all-governance-logs (fn [id] sample-gov-log)
                     p/new-governance-log (fn [& args] 5678)]
         (it)))
+
     (context "requesting the governance endpoint"
-      (with response (http-get-request "/circles/1234/governance"))
+      (with response (http-request :get "/circles/1234/governance"))
       (it "should return the entire governance document"
         (should= 200 (:status @response))
         (should= (json/generate-string sample-gov-log) (:body @response))))

     (context "posting to the governance endpoint with an unsupported content-type"
-      (with response (http-post-request "/circles/1234/governance"
-                                        nil
-                                        {:content-type "application/json"}))
+      (with response (http-request :post
+                                   "/circles/1234/governance"
+                                   {:content-type "application/json"}))
       (it "should return a 415"
         (should= 415 (:status @response))))

     (context "posting to the governance endpoint"
-      (with response (http-post-request "/circles/1234/governance"))
+      (with response (http-request :post "/circles/1234/governance"))
       (it "should return a 201"
         (should= 201 (:status @response))
         (should= (str host-url "/circles/1234/governance/5678")
@@ -146,9 +127,11 @@
       (around [it]
         (with-redefs [p/get-governance-log govt-meeting-not-found-thrower]
           (it)))
+
       (context "putting to the agenda endpoint"
-        (with response (http-put-request "/circles/1234/governance/5678/agenda"
-                                         "New agenda"))
+        (with response (http-request :put
+                                     "/circles/1234/governance/5678/agenda"
+                                     {:body "New agenda"}))
         (it "should return a 400"
           (should= 400 (:status @response))
           (should-contain "Governance meeting does not exist" (:body @response)))))
@@ -160,21 +143,23 @@
             (it)))

         (context "putting to the agenda endpoint with an unsupported media type"
-          (with response (http-put-request "/circles/1234/governance/5678/agenda"
-                                           "New agenda"
-                                           {:content-type "application/json"}))
+          (with response (http-request :put
+                                       "/circles/1234/governance/5678/agenda"
+                                       {:body "New agenda"
+                                        :content-type "application/json"}))
           (it "should return a 415"
             (should= 415 (:status @response))))

         (context "putting to the agenda endpoint"
-          (with response (http-put-request "/circles/1234/governance/5678/agenda"
-                                           "New agenda"))
+          (with response (http-request :put
+                                       "/circles/1234/governance/5678/agenda"
+                                       {:body "New agenda"}))

           (it "should return a 201"
             (should= 201 (:status @response))))

         (context "getting the agenda endpoint"
-          (with response (http-get-request "/circles/1234/governance/5678/agenda"))
+          (with response (http-request :get "/circles/1234/governance/5678/agenda"))
           (it "should return an empty agenda"
             (should= 200 (:status @response))
             (should-contain "text/plain" (get-in @response
@@ -187,7 +172,7 @@
             (it)))

         (context "getting the governance resource"
-          (with response (http-get-request "/circles/1234/governance/5678"))
+          (with response (http-request :get "/circles/1234/governance/5678"))
           (it "should return a 200"
             (should= 200 (:status @response)))
           (it "should return that an open meeting exists"
@@ -195,20 +180,21 @@
                                            [:headers "Open-Meeting"]))))

         (context "putting to the governance resource"
-          (with response (http-put-request "/circles/1234/governance/5678"))
+          (with response (http-request :put "/circles/1234/governance/5678"))
           ;(xit "should persist a closed governance log")
           (it "should return a 204"
             (should= 204 (:status @response))))

         (context "putting to the agenda endpoint"
-          (with response (http-put-request "/circles/1234/governance/5678/agenda"
-                                           "New agenda"))
+          (with response (http-request :put
+                                       "/circles/1234/governance/5678/agenda"
+                                       {:body "New agenda"}))

           (it "should return a 204"
             (should= 204 (:status @response))))

         (context "getting the agenda endpoint"
-          (with response (http-get-request "/circles/1234/governance/5678/agenda"))
+          (with response (http-request :get "/circles/1234/governance/5678/agenda"))
           (it "should return an empty agenda"
             (should= 200 (:status @response))
             (should-contain "text/plain" (get-in @response
@@ -222,7 +208,7 @@
             (it)))

         (context "getting the governance resource"
-          (with response (http-get-request "/circles/1234/governance/5678"))
+          (with response (http-request :get "/circles/1234/governance/5678"))
           (it "should return a 200"
             (should= 200 (:status @response)))
           (it "should return the details of the governance resource"
@@ -230,20 +216,21 @@
                             (:body @response))))

         (context "putting to the governance resource"
-          (with response (http-put-request "/circles/1234/governance/5678"))
+          (with response (http-request :put "/circles/1234/governance/5678"))
           (it "should return a 204"
             (should= 204 (:status @response))))

         (context "putting to the agenda endpoint"
-          (with response (http-put-request "/circles/1234/governance/5678/agenda"
-                                           "New agenda"))
+          (with response (http-request :put
+                                       "/circles/1234/governance/5678/agenda"
+                                       {:body "New agenda"}))

           (it "should return a 400"
             (should= 400 (:status @response))
             (should-contain "Agenda is closed" (:body @response))))

         (context "getting the agenda endpoint"
-          (with response (http-get-request "/circles/1234/governance/5678/agenda"))
+          (with response (http-request :get "/circles/1234/governance/5678/agenda"))
           (it "should return 400"
             (should= 400 (:status @response))
             (should-contain "Agenda is closed" (:body @response))))))))


finished writing out basic API straw man

--- src/untangled/i18n.cljc
+++ src/untangled/i18n.cljc
@@ -4,16 +4,38 @@
 #?(:cljs (set! js/trc (fn [ctxt msg] msg)))
 #?(:cljs (set! js/trf (fn [fmt & args] fmt)))

-#?(:clj (defmacro tr
+#?(:cljs (defn format-date
+           "Format a date with an optional style. The default style is :short.
+
+           Style can be one of:
+
+           - :short E.g. 3/4/2015
+           - :medium E.g. Mar 4, 2015
+           - :long E.g. March 4, 2015
+           "
+           ([date style] (.toLocaleDateString date))
+           ([date] (.toLocaleDateString date))
+           ))
+#?(:cljs (defn format-number
+           "Format a number with locale-specific separators (grouping digits, and correct marker for decimal point)"
+           [number] number))
+#?(:cljs (defn format-currency
+           "Format a number as a currency (dropping digits that are insignificant in the current currency.)"
+           [number] (.toPrecision number 2)))
+#?(:cljs (defn format-rounded-currency
+           "Round and format a number as a currency, according to the current currency's rules."
+           [number] (.toPrecision (/ (.round (* 100 number)) 100.0) 2)))
+
+#?(:clj (defmacro tr
           "Translate the given literal string. The argument MUST be a literal string so that it can be properly extracted
           for use in gettext message files as the message key. This macro throws a detailed assertion error if you
           violate this restriction. See trf for generating translations that require formatting (e.g. construction from
           variables)."
-          [msg]
+          [msg]
           (assert (string? msg) (str "In call to tr(" msg "). Argument MUST be a literal string, not a symbol or expression. Use trf for formatting."))
           `(js/tr ~msg)))

-#?(:clj (defmacro trc
+#?(:clj (defmacro trc
           "Same as tr, but include a context message to the translator. This is recommended when asking for a
           translation to something vague.

@@ -33,7 +55,7 @@
           (assert (and (string? msg) (string? context)) (str "In call to trc(" context msg "). Arguments MUST be literal strings."))
           `(js/trc ~context ~msg)))

-#?(:clj (defmacro trf
+#?(:clj (defmacro trf
           "Translate a format string, then use it to format a message with the given arguments. The format MUST be a literal
           string for extraction by gettext. The arguments should be keyword/value pairs that will match the embedded
           items to format.


connect to snapshot repository

connect to snapshot repository

--- src/wb_es/web/setup.clj
+++ src/wb_es/web/setup.clj
@@ -39,9 +39,23 @@
                   (flush)
                   (Thread/sleep interval))))))))))

+(defn connect-snapshot-repository
+  ([repository-name]
+   (connect-snapshot-repository repository-name
+                                {"type" "s3"
+                                 "settings" {"bucket" "wormbase-elasticsearch-snapshots"
+                                             "region" "us-east-1"}}))
+  ([repository-name repository-settings]
+   (try
+     (http/get (format "%s/_snapshot/%s" es-base-url repository-name)
+               {:content-type "application/json"
+                :body (json/generate-string repository-settings)})
+     (catch Exception e
+       (throw (Exception. "Cannot connect to elasticsearch snapshot repository"))))))
+
 (defn get-snapshot-id
-  []
-  (let [response (http/get (format "%s/_cat/snapshots/s3_repository?format=json" es-base-url))
+  [repository-name]
+  (let [response (http/get (format "%s/_cat/snapshots/%s?format=json" es-base-url repository-name))
         all-snapshots (json/parse-string (:body response) true)
         id-pattern (re-pattern (format "snapshot_%s(_(\\d+))?" release-id))]
     (->> all-snapshots


[#78] Downgrade PG driver to be java 7 compatible

--- backend/project.clj
+++ backend/project.clj
@@ -21,7 +21,7 @@
                  [org.clojure/java.jdbc "0.4.2"]
                  [org.immutant/scheduling "2.1.2"]
                  [org.immutant/web "2.1.2"]
-                 [org.postgresql/postgresql "9.4.1208"]
+                 [org.postgresql/postgresql "9.4.1208.jre7"]
                  [org.slf4j/slf4j-nop "1.7.18"]
                  [pandect "0.5.4"]
                  [ring "1.4.0"]


[#1303] Update project release number

[#1303] Update project release number

--- backend/project.clj
+++ backend/project.clj
@@ -1,4 +1,4 @@
-(defproject org.akvo/lumen "0.22.1-SNAPSHOT"
+(defproject org.akvo/lumen "0.24.0-SNAPSHOT"
   :description "Akvo Lumen backend"
   :url "https://github.com/akvo/akvo-lumen"
   :license {:name "GNU Affero General Public License 3.0"


Update org.apache.httpcomponents/httpclient to "4.5.8"

--- backend/project.clj
+++ backend/project.clj
@@ -31,7 +31,7 @@
                  ;; explicit versions of commons deps used by tika-parsers and clj-http
                  [com.fasterxml.jackson.core/jackson-core "2.9.9"]
                  [org.apache.httpcomponents/httpcore "4.4.11"]
-                 [org.apache.httpcomponents/httpclient "4.5.5"]
+                 [org.apache.httpcomponents/httpclient "4.5.8"]
                  [org.apache.httpcomponents/httpmime "4.5.5"]
                  [org.clojure/clojure "1.9.0"]
                  [org.clojure/data.csv "0.1.4"]


Update backend dependencies.

Update backend dependencies.

--- backend/project.clj
+++ backend/project.clj
@@ -13,7 +13,7 @@
                  [org.clojure/tools.logging "0.3.1"]
                  [funcool/suricatta "1.3.1"]
                  [funcool/promesa "1.8.0"]
-                 [funcool/catacumba "2.0.0"]
+                 [funcool/catacumba "2.1.0"]
                  [funcool/cuerdas "2.0.3"]
                  [funcool/datoteka "1.0.0"]

@@ -23,11 +23,10 @@
                  [hiccup "1.0.5"]
                  [org.im4java/im4java "1.4.0"]

-                 [org.slf4j/slf4j-simple "1.7.23"]
+                 [org.slf4j/slf4j-simple "1.7.24"]
                  [com.layerware/hugsql-core "0.4.7"
                   :exclusions [org.clojure/tools.reader]]
                  [niwinz/migrante "0.1.0"]
-

                  [buddy/buddy-sign "1.4.0"]
                  [buddy/buddy-hashers "1.2.0"]


Mapped data-state transitions to attr map as well.

--- src-cljs/freactive/dom.cljs
+++ src-cljs/freactive/dom.cljs
@@ -292,17 +292,18 @@
 (defn get-data-state [element]
   (.getAttribute element "data-state"))

-(defn- enter-data-state! [element state old-state]
-  (when-let [enter-transition (get-transition element (keyword (str "on-" state)))]
-    (enter-transition element old-state)))
+(defn- enter-data-state! [element node-state state old-state]
+  )

 (defn set-data-state!
   ([element state]
     (let [cur-state (get-data-state element)
+          node-state (get-element-state element)
           state (when state (name state))]
       (when-not (identical? cur-state state)
         (do-set-data-state! element state)
-        (enter-data-state! element state cur-state)))))
+        (when-let [enter-transition (get-state-attr node-state (str "state/on-" state))]
+          (enter-transition element old-state state))))))

 (defn- bind-prop-attr! [set-fn element attr-name attr-value node-state]
   (if (satisfies? cljs.core/IDeref attr-value)
@@ -343,13 +344,16 @@
         (.removeAttribute element attr-name)))))

 (defn- bind-lifecycle-callback! [node node-state cb-name cb-value]
-  (if (identical? cb-name "disposed")
+  (when (identical? cb-name "disposed")
     (set! (.-disposed-callback node-state) cb-value)
-    (aset node-state (str "node-" cb-name) cb-value)))
+    ;; other callbacks automatically included in attr map
+    ))

 (def ^:private attr-ns-lookup
   #js
-  {:node bind-lifecycle-callback!})
+  {:node bind-lifecycle-callback!
+   :state (fn []) ;; automatically handled in attr map
+   })

 (defn register-attr-prefix! [prefix xml-ns-or-handler]
   (aset attr-ns-lookup prefix xml-ns-or-handler))
@@ -594,10 +598,13 @@
                                     (get-node-id new-elem) state)
         state))))

+(defn- get-state-attr [state attr-str]
+  (when-let [attrs (when state (.-attrs state))]
+    (aget attrs attr-str)))
+
 (defn- on-attached [state node]
-  (when state
-    (when-let [node-attached (aget state "node-on-attached")]
-      (node-attached node))))
+  (when-let [node-attached (get-state-attr state "node/on-attached")]
+    (node-attached node)))

 (defn- replace-node-completely [parent new-elem-spec cur-dom-node top-level]
   (let [new-elem
@@ -789,10 +796,9 @@
               (when-not (.-disposed state)
                 (let [new-elem (get-new-elem)
                       cur (.-cur-element state)
-                      cur-state (get-element-state cur)]
+                      node-state (get-element-state cur)]
                   (when-not (identical? (get-virtual-dom cur) (get-virtual-dom new-elem))
-                    (if-let [hide (when cur-state
-                                    (aget cur-state "node-on-detaching"))]
+                    (if-let [hide (get-state-attr node-state "node/on-detaching")]
                       (hide cur
                             (fn []
                               (if (.-disposed state)


Cleaning up.

Cleaning up.

--- src-cljs/freactive/dom.cljs
+++ src-cljs/freactive/dom.cljs
@@ -62,8 +62,6 @@
 ;; (deftype ElementState [id disposed element-spec child-states])

 (declare set-attr!)
-
-(declare get-transition)

 (defn- reset-element-spec! [state spec tag]
   (when-let [on-disposed (.-disposed-callback state)]
@@ -95,11 +93,6 @@

 (defprotocol IRemove
   (-remove! [x]))
-
-(defn- get-transition [x transition-name]
-  (let [spec (get-element-spec x)]
-    (when-not (string? spec)
-      (get (meta spec) transition-name))))

 (defn- dispose-node
   ([dom-node]
@@ -130,9 +123,7 @@

 (defn remove! [x]
   (if (dom-node? x)
-    (if-let [node-detaching (get-transition x :node-detaching)]
-      (node-detaching x (fn [] (remove-dom-node x)))
-      (remove-dom-node x))
+    (remove-dom-node x)
     (-remove! x)))

 ;; ## Polyfills


Allow multiple hosts for ES

Allow multiple hosts for ES

--- src/org/spootnik/cyanite/es_path.clj
+++ src/org/spootnik/cyanite/es_path.clj
@@ -178,8 +178,8 @@
 (defn es-native
   [{:keys [index host port cluster_name]
     :or {index "cyanite" host "localhost" port 9300 cluster_name "elasticsearch"}}]
-  (let [conn (esn/connect [[host port]]
-                         {"cluster.name" cluster_name})
+  (let [hosts (map #([% port]) (if (sequential? host) host [host]))
+        conn (esn/connect hosts {"cluster.name" cluster_name})
         existsfn (partial esnd/present? conn index ES_DEF_TYPE)
         updatefn (partial esnd/async-put conn index ES_DEF_TYPE)
         scrollfn (partial esnd/scroll-seq conn)


version bump 0.9.0-wip5

version bump 0.9.0-wip5

--- storm-kafka/project.clj
+++ storm-kafka/project.clj
@@ -1,4 +1,4 @@
-(defproject storm/storm-kafka "0.9.0-wip5-scala292-multischeme"
+(defproject storm/storm-kafka "0.9.0-wip5-scala292"
   :source-path "src/clj"
   :java-source-path "src/jvm"
   :javac-options {:debug "true" :fork "true"}


Add macros createMixin, createClass and defclass.

--- src/quiescent.clj
+++ src/quiescent.clj
@@ -21,3 +21,40 @@

 (defmacro set-prop! [o propname fn]
   `(let [newo# ~o] (set! (. newo# ~propname) ~fn) newo#))
+
+
+(defmacro createMixin [& proto+specs]
+  ;; TODO: Combine different signatures.
+  (let [[obj-specs proto+specs] (split-with (complement symbol?) proto+specs)
+        {obj-props false obj-meths true} (group-by (comp vector? second)
+                                                   obj-specs)
+        o (gensym)]
+    `(let [~o (~'js-obj)]
+       ~@(for [[pname & pbody] obj-props]
+           `(set! (. ~o ~(symbol (str \- (name pname))))
+                  (do ~@pbody)))
+       ~@(for [[mname margs & mbody] obj-meths]
+           `(set! (. ~o ~(symbol (str \- (name mname))))
+                  (fn ~(subvec margs 1)
+                    (this-as
+                      ~(first margs)
+                      ~@mbody))))
+       ~(if (empty? proto+specs)
+          o
+          `(specify! ~o ~@proto+specs)))))
+
+(defmacro createClass [& specs]
+  `(js/React.createClass (createMixin ~@specs)))
+
+(defmacro defclass [name docstr & specs]
+  (assert (symbol? name) "Must supply a symbol for name (as with def).")
+  (let [[docstr specs] (if (string? docstr)
+                      [docstr specs]
+                      ["" (cons docstr specs)])
+        specs (if (->> (split-with (complement symbol?) specs)
+                       (some #(= % 'displayName)))
+                (cons (list 'displayName name) specs)
+                specs)]
+    `(def ~name ~docstr (createClass ~@specs))))
+
+[]


Doc for `explain-with` was wrong.

Doc for `explain-with` was wrong.

--- src/structural_typing/guts/preds/annotating.clj
+++ src/structural_typing/guts/preds/annotating.clj
@@ -21,7 +21,10 @@
    `explainer` to be called with the [[oopsie]] that results from the
    failure.

-        (explain-with \"too small\" #(< (count %) 54))
+        (explain-with #(format \"Yo! %s has %s characters, which is WAY too long.\"
+                               (:leaf-value %)
+                               (count (:leaf-value %)))
+                      #(< (count %) 8)))
 "
   [explainer predicate]
   (-> predicate


[fix #3505] Fix account initialization events order

Signed-off-by: Dmitry Novotochinov <161568b2835bcbfce0822b25de9311ab2cbff690@gmail.com>

--- src/status_im/ui/screens/accounts/login/events.cljs
+++ src/status_im/ui/screens/accounts/login/events.cljs
@@ -123,11 +123,11 @@
   (fn [{{:keys [view-id] :as db} :db} [_ error address]]
     (if (nil? error)
       {:db         (cond-> (dissoc db :accounts/login)
-                     (= view-id :create-account)
-                     (assoc-in [:accounts/create :step] :enter-name))
+                           (= view-id :create-account)
+                           (assoc-in [:accounts/create :step] :enter-name))
        :dispatch-n (concat
                      [[:stop-debugging]
-                      [:initialize-account address]]
-                     (when (not= view-id :create-account)
-                       [[:navigate-to-clean :home]]))}
+                      [:initialize-account address
+                       (when (not= view-id :create-account)
+                         [[:navigate-to-clean :home]])]])}
       (log/debug "Error changing acount: " error))))


ClojureScript 0.0-2727

ClojureScript 0.0-2727

--- Clojure-Websockets/MainApp/project.clj
+++ Clojure-Websockets/MainApp/project.clj
@@ -17,7 +17,7 @@
                  [ring/ring-defaults "0.1.1"]
                  [clj-time "0.8.0"]
                  [pandect "0.4.1"]
-                 [org.clojure/clojurescript "0.0-2665"]
+                 [org.clojure/clojurescript "0.0-2727"]
                  [tailrecursion/cljs-priority-map "1.1.0"]
                  [org.clojure/data.priority-map "0.0.5"]
                  [reagent "0.5.0-alpha"]


changed params of state functions

changed params of state functions

--- src/braid/common/state.cljs
+++ src/braid/common/state.cljs
@@ -113,11 +113,11 @@
       (filter (fn [tag] @(get-user-subscribed-to-tag @state [nil (tag :id)]))))))

 (defn get-user-avatar-url
-  [state user-id]
+  [state [_ user-id]]
   (reaction (get-in @state [:users user-id :avatar])))

 (defn get-user-status
-  [state user-id]
+  [state [_ user-id]]
   (reaction (get-in @state [:users user-id :status])))

 (defn get-search-query


make help the default task

make help the default task

--- src/cake/tasks/defaults.clj
+++ src/cake/tasks/defaults.clj
@@ -6,25 +6,21 @@
             cake.tasks.dependencies
             cake.tasks.swank))

-(defn task-doc
-  "Print documentation for a task."
-  [task]
-  (println "-------------------------")
-  (println "cake" (name task) " ;" (:doc (@tasks task))))
-
 (def implicit-taskdocs
   [["repl"       "Start an interactive shell."]
    ["stop/reset" "Stop cake and project jvm processes."]])

 (deftask help
   "Print tasks with documentation (use -a for all tasks)."
+  (println "-------------------------------------------")
   (let [all?     (:a opts)
         taskdocs (for [[sym task] @tasks :when (or all? (seq (:doc task)))]
                    [(name sym) (str (first (:doc task)))])
         taskdocs (into implicit-taskdocs taskdocs)
         width  (apply max (map #(count (first %)) taskdocs))
         format (str "cake %-" width "s  ;; %s\n")]
-    (println (prn-str taskdocs))
     (doseq [[name doc] (sort-by first taskdocs)]
       (printf format name doc))
     (flush)))
+
+(deftask default => help)


Placeholder for sqls.stor.load-worksheet-state!

--- src/sqls/stor.clj
+++ src/sqls/stor.clj
@@ -35,16 +35,16 @@

 (defn add-connection!
   "Add connection to connection list.
-
+
   Parameters:
-
+
   - conn-data is a map with following keys:
-
+
     - name - name of the connection,
     - jdbc-conn-str - jdbc connection URI,
     - desc - description,
     - driver - JDBC connection driver name.
-
+
   Returns new connection list.
   "
   [conn-data]
@@ -68,7 +68,15 @@
     connections-without-deleted))

+(defn load-worksheet-state!
+  "Read current worksheet state.
+  Takes connection name. For now all connections are worksheets (1-1 relationship) in terms of state.
+  This obviously is needs to be designed - either we don't allow many worksheets of one conn,
+  or we have many states per conn. Either way it's to be chosen later.

+  Returns a map with worksheet state.

-
-
+  State file is called state.json and it's for now located in current directory.
+  "
+  [^String conn-name]
+  {})


[scamp] remove old 'init-cluster

[scamp] remove old 'init-cluster

--- modules/scamp/src/scamp/core.clj
+++ modules/scamp/src/scamp/core.clj
@@ -305,19 +305,6 @@
    networked-node :- NetworkedNodeSchema]
   (assoc-in world [:network (node->node-contact-address (:self networked-node))]
             networked-node))
-
-#_
-(s/defn init-cluster :- WorldSchema
-  [world :- WorldSchema
-   networked-node :- NetworkedNodeSchema]
-  (-> world
-      (add-new-node node-core)
-      (update-in [:network (:id node-core) :downstream]
-                 conj
-                 (:id node-core))
-      (update-in [:network (:id node-core) :upstream]
-                 conj
-                 (:id node-core))))

 (s/defn add-messages :- WorldSchema
   "Given 'world and new messages to add, return 'world with the new


Remove obsolete function call

Remove obsolete function call

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

--- clojure/sequence_generator.clj
+++ clojure/sequence_generator.clj
@@ -62,7 +62,7 @@
     #(or
        (nil? (% :channel))
        (-> % :channel :skip-frames zero?)
-       (not= 0 (mod (% :frame) (-> % :channel get-skip-frames inc))))
+       (not= 0 (mod (% :frame) (-> % :channel :skip-frames inc))))
     events))

 (defn process-use-autofocus [events use-autofocus autofocus-skip]


Fixed combined mutations bugs

Fixed combined mutations bugs

--- src/clj/asols/mutations.clj
+++ src/clj/asols/mutations.clj
@@ -19,7 +19,17 @@

 (defmethod mutate ::combined
   [net {:keys [mutations]}]
-  (reduce mutate net mutations))
+  (let [m-type #(case (:operation %)
+                 ::add-node :add-node
+                 ::del-node :del-node
+                 ::add-layer :layer
+                 :safe)
+        {add-node-ms :add-node del-node-ms :del-node
+         layer-ms :layer safe-ms :safe} (group-by m-type mutations)
+        sorted-del-node-ms (sort-by #(- (second (:deleted-node %))) del-node-ms)
+        sorted-layer-ms (sort-by #(- (:layer-pos %)) layer-ms)
+        correct-ms (concat safe-ms add-node-ms sorted-del-node-ms sorted-layer-ms)]
+    (reduce mutate net correct-ms)))

 (defn identity-mutations [_]
   [{:operation ::identity}])


at least try pulling `resources` up

at least try pulling `resources` up

--- src/clj/easynxc/handler.clj
+++ src/clj/easynxc/handler.clj
@@ -44,10 +44,10 @@
        :body (str (response :err))})))

 (defroutes routes
+  (resources "/")
   (GET "/songs/:url" [url] (song url))
   (GET "/" [] home-page)
-  (GET "*" [] loading-page)
-  (resources "/")
+  (GET "/*" [] loading-page)
   (not-found "Not Found"))

 (def app (wrap-middleware #'routes))


Add in-deck? function.

Add in-deck? function.

--- src/clj/game/core-flags.clj
+++ src/clj/game/core-flags.clj
@@ -103,6 +103,11 @@
   [card]
   (= (:zone card) [:hand]))

+(defn in-deck?
+  "Checks if the specified card is in the draw deck."
+  [card]
+  (= (:zone card) [:deck]))
+
 (defn is-type?
   "Checks if the card is of the specified type, where the type is a string."
   [card type]


refactored away unnecessary loops

refactored away unnecessary loops

--- src/clj/scraper/threads.clj
+++ src/clj/scraper/threads.clj
@@ -90,114 +90,89 @@
     nil
     (get reply-levels (dec indent-level))))

-(defn get-parent-ids
-  [indents reply-levels]
-  (when (first indents)
-    (let [indent        (first   indents)
-          indent-level  (first   indent)
-          reply-id      (second  indent)
-          new-levels    (assoc   reply-levels indent-level reply-id)]
-      (cons (get-parent-id indent-level reply-levels)
-            (get-parent-ids (rest indents) new-levels)))))
+(defn combine-users
+  [thread-data user bulb-users]
+  (let [users (:users thread-data)]
+    (-> users
+        (into (list user))
+        (into bulb-users)
+        (distinct))))

-(defn set-parent-id
-  [reply parent-id]
-  (-> reply
-      (assoc :parent-id parent-id)
-      (dissoc :indent)))
-
-(defn rm-nil-parent-id
-  [replies]
-  (let [first-reply     (first replies)
-        thread-replies  (rest  replies)]
-    (cons (dissoc first-reply :parent-id) thread-replies)))
-
-(defn set-parent-ids
-  [replies parents]
-  (when (first replies)
-    (let [reply     (first replies)
-          parent-id (first parents)]
-      (cons (set-parent-id reply parent-id)
-            (set-parent-ids (rest replies) (rest parents))))))
-
-(defn combine-users
-  [user bulbs]
-  (if (some? (:users bulbs))
-    (into (list user) (:users bulbs))
-    (list user)))
+(defn update-thread-data
+  [thread-data replies users]
+  (-> thread-data
+      (assoc :replies replies)
+      (assoc :users   users)))

 (defn rm-nil-bulb
   [reply]
-  (if (nil? (reply :bulbs))
+  (if (nil? (:bulbs reply))
     (dissoc reply :bulbs)
     reply))

+(defn rm-nil-parent-id
+  [reply]
+  (if (nil? (:parent-id reply))
+    (dissoc reply :parent-id)
+    reply))
+
+(defn rm-nil-keys
+  [reply]
+  (-> reply
+      (rm-nil-bulb)
+      (rm-nil-parent-id)))
+
 (defn get-data-helper
-  [rows]
-  (for [row rows
-    :let [cols         (utils/get-cols        row)
-          reply-url    (get-reply-url         cols)
-          reply-id     (get-reply-id          reply-url)
-          reply-title  (get-reply-title       cols)
-          post-time    (get-reply-post-time   cols)
-          bulbs        (bulbs/get-data        reply-url)
-          user-url     (utils/get-user-url    cols)
-          user-id      (utils/get-user-id     user-url)
-          username     (utils/get-username    cols)
-          reply        {
-            :id         reply-id
-            :indent     [(get-indent-level cols) reply-id]
-            :title      reply-title
-            :url        reply-url
-            :post-time  post-time
-            :user       user-id
-            :bulbs      (dissoc bulbs :users)
-          }
-          user         {
-            :id         user-id
-            :name       username
-            :url        user-url
-          }
-          users        (combine-users user bulbs)]]
-    [(rm-nil-bulb reply) users]))
-
-(defn collate-users
-  [tdata]
-  (distinct (reduce into '() (map second tdata))))
+  [rows reply-parents thread-data]
+  (when (first rows)
+    (let [row            (first                 rows)
+          cols           (utils/get-cols        row)
+          reply-url      (get-reply-url         cols)
+          reply-id       (get-reply-id          reply-url)
+          reply-title    (get-reply-title       cols)
+          post-time      (get-reply-post-time   cols)
+          bulbs          (bulbs/get-data        reply-url)
+          user-url       (utils/get-user-url    cols)
+          user-id        (utils/get-user-id     user-url)
+          username       (utils/get-username    cols)
+          indent-level   (get-indent-level      cols)
+          reply-parents  (assoc reply-parents indent-level reply-id)
+          parent-id      (get-parent-id indent-level reply-parents)
+          user           {:id         user-id
+                          :name       username
+                          :url        user-url}
+          bulb-users     (:users bulbs)
+          bulbs          (dissoc bulbs :users)
+          reply          {:id         reply-id
+                          :parent-id  parent-id
+                          :title      reply-title
+                          :url        reply-url
+                          :post-time  post-time
+                          :user-id    user-id
+                          :bulbs      bulbs}
+          replies        (into (:replies thread-data) (list (rm-nil-keys reply)))
+          users          (combine-users thread-data user bulb-users)
+          thread-data    (update-thread-data thread-data replies users)]
+      (merge thread-data (get-data-helper (rest rows) reply-parents thread-data)))))

 (defn get-data-by-url
   [url]
   (web/set-driver! {:browser           :firefox
                     :profile           bo-ffprofile})
-  (let [table      (get-replies-table  url)
-        rows       (utils/get-rows     table)
-        thread-id  (get-thread-id      url)
-        tdata      (get-data-helper    rows)
-        replies    (map first          tdata)
-        indents    (map #(get % :indent) replies)
-        parents    (get-parent-ids indents [])
-        users      (collate-users      tdata)
-        data       {
-                      :thread {
+  (let [table        (get-replies-table  url)
+        rows         (utils/get-rows     table)
+        thread-id    (get-thread-id      url)
+        thread-data  (get-data-helper rows [] {:replies '() :users '()})
+        replies      (reverse (:replies thread-data))
+        users        (:users   thread-data)
+        data         {:thread {
                         :id       thread-id
                         :replies  (map :id replies)
                       }
-                      :replies (rm-nil-parent-id (set-parent-ids replies parents))
-                      :users   users
-                    }]
+                      :replies replies
+                      :users   users}]
     (web/close)
     data))
-
-; (defn get-data-by-ids
-;   [subforum-id thread-id]
-;   (let [url    (get-thread-url     subforum-id thread-id)
-;         table  (get-replies-table  url)
-;         rows   (utils/get-rows     table)]
-;     {
-;       :thread   (get-thread-data   rows thread-id)
-;       :replies  (get-replies-data  rows)
-;       :users    (get-users-data    rows)
-;     }))

 (defn get-data
   ([url]


Added validation rule for data from Google Spreadsheet

--- src/cljs/db_quiz/model.cljs
+++ src/cljs/db_quiz/model.cljs
@@ -167,9 +167,10 @@
                  spreadsheet-id "/" worksheet-id "/public/full")
         transform-row (fn [{{label :$t} :gsx$label
                            {description :$t} :gsx$description}]
-                            {:label label
-                             :abbreviation (abbreviate label)
-                             :description description})
+                        (when (and label description)
+                          {:label label
+                           :abbreviation (abbreviate label)
+                           :description description}))
         raw-results-chan (wrap-load (http/jsonp url {:query-params {:alt "json-in-script"}})
                                 (chan 1 (map (comp (partial map transform-row) :entry :feed :body))))
         results-chan (chan)]
@@ -178,6 +179,8 @@
                     results-count (count results)]
                 (cond (< results-count number-of-fields)
                         (reagent-modals/modal! (modals/invalid-spreadsheet-rows results-count))
+                      (every? nil? results)
+                        (reagent-modals/modal! modals/invalid-spreadsheet-columns)
                       ; TODO: More validation rules
                       :else (>! results-chan (take number-of-fields (shuffle results))))))
           results-chan)
@@ -238,14 +241,15 @@
                                          :data {:selectors selectors
                                                 :limit number-of-fields
                                                 :offset offset}))]
-    (go (let [count-result (js/parseInt (:count (first (<! count-query-channel))) 10)
-              offset (count-to-offset count-result)
-              results (map despoilerify (<! (query-channel-fn offset)))
-              results-count (count results)]
-          (if (= results-count number-of-fields)
-            (do (swap! app-state #(assoc % :board (merge-board-with-data board results)))
-                (callback))
-            (reagent-modals/modal! (modals/invalid-number-of-results number-of-fields results-count)))))))
+    (go (if-let [count-result (:count (first (<! count-query-channel)))]
+          (let [offset (count-to-offset (js/parseInt count-result 10))
+                results (map despoilerify (<! (query-channel-fn offset)))
+                results-count (count results)]
+            (if (= results-count number-of-fields)
+              (do (swap! app-state #(assoc % :board (merge-board-with-data board results)))
+                  (callback))
+              (reagent-modals/modal! (modals/invalid-number-of-results number-of-fields results-count))))
+          (reagent-modals/modal! (modals/error-loading-data endpoint))))))

 (defmethod load-board-data :gdrive
   [board callback]


fixup controlled file input warning

fixup controlled file input warning

--- src/cljs/demtools/core.cljs
+++ src/cljs/demtools/core.cljs
@@ -76,7 +76,6 @@

 (defmethod read "packets"
   [{:keys [state ast] :as env} k {:keys [idx offset limit]}]
-  ;;  (println "read k" k (-> @state :packets count) (case k :packets/count "coun" "else"))
   (case k
     :packets/packet
     {:value (when idx (nth (get @state :packets) idx))}
@@ -241,6 +240,7 @@
 (defn file-upload [ui]
   (dom/input
    #js {:type "file"
+        :value ""
         :onChange #(let [f (-> % .-target .-files js/Array.from (nth 0))]
                      (om/update-query!
                       ui


point db to live humanmine and flymine, beta mousemine (best enrichment results this way)

--- src/cljs/gointermod/db.cljs
+++ src/cljs/gointermod/db.cljs
@@ -27,8 +27,10 @@
        :status {:status :na}
        :mine
        {:name "HumanMine"
-        :url "beta.humanmine.org/beta"
-        :service {:root "beta.humanmine.org/beta"}}}
+       :url "www.humanmine.org/humanmine"
+       :service {:root "www.humanmine.org/humanmine"}}}
+      ;  :url "beta.humanmine.org/beta"
+      ;  :service {:root "beta.humanmine.org/beta"}}}
     :fly
      {:id     :fly
       :common "Fly"
@@ -37,8 +39,10 @@
       :abbrev "D. melanogaster"
       :mine
        {:name "FlyMine"
-        :url "beta.flymine.org/beta"
-        :service {:root "beta.flymine.org/beta"}}}
+      ;  :url "beta.flymine.org/beta"
+      ;  :service {:root "beta.flymine.org/beta"}}}
+       :url "www.flymine.org/flymine"
+       :service {:root "www.flymine.org/flymine"}}}
     :mouse
      {:id     :mouse
       :common "Mouse"
@@ -47,8 +51,10 @@
       :status {:status :na}
       :mine
        {:name "MouseMine"
-        :url "www.mousemine.org/mousemine"
-        :service {:root "www.mousemine.org/mousemine"}}}
+      ;  :url "www.mousemine.org/mousemine"
+      ;  :service {:root "www.mousemine.org/mousemine"}}}
+       :url "beta.mousemine.org/mousemine"
+       :service {:root "beta.mousemine.org/mousemine"}}}
     :rat
      {:id     :rat
       :common "Rat"


Shows input field to edit a todo on double clicking the title, and hides on blur

--- src/cljs/todo_clj/core.cljs
+++ src/cljs/todo_clj/core.cljs
@@ -30,12 +30,27 @@
                       :response-format :json
                       :keywords? true}))

-(defn todo-view [todo]
+(defn display [show]
+  (if show
+    #js {}
+    #js {:display "none"}))
+
+(defn todo-view [todo owner]
   (reify
+    om/IInitState
+    (init-state [_]
+      {:editing false})
     om/IRenderState
-    (render-state [_ {:keys [delete update]}]
+    (render-state [_ {:keys [delete update editing]}]
       (dom/li #js {:key (str (:id todo) (rand)) :className "todo"}
-              (:title todo)
+              (dom/span #js {:style (display (not editing))
+                             :onDoubleClick #(om/set-state! owner :editing true)}
+                        (:title todo))
+              (dom/input #js {:ref "edit-todo"
+                              :value (:title todo)
+                              :autoFocus true
+                              :style (display editing)
+                              :onBlur #(om/set-state! owner :editing false)})
               (dom/input #js {:type "checkbox"
                               :checked (:completed todo)
                               :onClick #(update-todo todo {:completed (not (:completed todo))} (fn [updated-todo] (put! update updated-todo)))})


Updates todo when title changes

Updates todo when title changes

--- src/cljs/todo_clj/core.cljs
+++ src/cljs/todo_clj/core.cljs
@@ -35,6 +35,15 @@
     #js {}
     #js {:display "none"}))

+(defn save-todo [todo owner]
+  (let [title (:title todo)]
+    (update-todo todo {:title title}
+     #(om/set-state! owner :editing false))))
+
+(defn handle-edit-title [e todo]
+  (let [title (.. e -target -value)]
+    (om/transact! todo #(assoc % :title title))))
+
 (defn todo-view [todo owner]
   (reify
     om/IInitState
@@ -50,7 +59,8 @@
                               :value (:title todo)
                               :autoFocus true
                               :style (display editing)
-                              :onBlur #(om/set-state! owner :editing false)})
+                              :onBlur #(save-todo todo owner)
+                              :onChange #(handle-edit-title % todo)})
               (dom/input #js {:type "checkbox"
                               :checked (:completed todo)
                               :onClick #(update-todo todo {:completed (not (:completed todo))} (fn [updated-todo] (put! update updated-todo)))})


Removed useless comments

Removed useless comments

--- src/cljs/triboard/core.cljs
+++ src/cljs/triboard/core.cljs
@@ -105,7 +105,7 @@
     (mapcat #(available-moves-at board %))
     ))

-(defn with-available-moves ;; TODO - This should be optimized: much too slow (40-60 ms)
+(defn with-available-moves
   "Compute all available moves on the board.
    And group these positions by player then by position
    Example:
@@ -122,7 +122,7 @@
         (available-moves-xf board)
         #(update-in %1 [(:winner %2) (:move %2)] conj %2)
         {}
-        all-positions)) ;; TODO - To optimize, just consider the move of the current player?
+        all-positions))
     ))


Working on AI

Working on AI

--- src/cljs/triboard/core.cljs
+++ src/cljs/triboard/core.cljs
@@ -194,7 +194,10 @@
 (defn worst-immediate-loss
   "Return the next game move that would reduce the score the most for the provided player"
   [game player]
-  (best-immediate-move-with game (:player game) #(= player (:looser %))))
+  (let [move-filter #(= player (:looser %))
+        move (best-immediate-move-with game (:player game) move-filter)]
+    (transduce (map (comp count :taken)) + (second move))
+    ))

 ;; -----------------------------------------


Fix create-or-update-channel - sign /w user

--- src/clojure_fabric/user.clj
+++ src/clojure_fabric/user.clj
@@ -304,16 +304,14 @@
 (defn create-or-update-channel
   ([orderer envelope]
    (proto/broadcast-via-orderer orderer envelope))
-  ([channel-id orderer config-update signatures]
-   (let [payload (proto/make-payload :header (chaincode/make-header channel-id
-                                                                    orderer
-                                                                    {:channel-header-type :config-update})
-                                     :data (proto/make-config-update-envelope :config-update config-update
-                                                                              :signatures signatures))]
+  ([user channel-id orderer config-update signatures]
+   (let [payload (chaincode/make-payload channel-id orderer :config-update
+                                         (proto/make-config-update-envelope :config-update config-update
+                                                                            :signatures signatures))]
      (create-or-update-channel orderer
                                (proto/make-envelope :payload payload
                                                     :signature (crypto-suite/sign (.toByteArray ^Common$Payload (proto/clj->proto payload))
-                                                                                (:private-key orderer)
+                                                                                (:private-key user)
                                                                                {:algorithm (:key-algorithm (:crypto-suite orderer))}))))))

 (defn make-config-signature
@@ -334,9 +332,10 @@
                                       :signature))))

 (defn create-or-update-channel-from-nodes
-  [channel-id orderer nodes config-update]
+  [user channel-id orderer nodes config-update]
   ;; participants = orderers + peers
-  (create-or-update-channel channel-id
+  (create-or-update-channel user
+                            channel-id
                             orderer
                             config-update
                             (mapv (fn [node]
@@ -367,23 +366,6 @@
 ;;                                                   [(get @core/users  ["Org1MSP" "admin"]) (get @core/users  ["Org2MSP" "admin"])
 ;;                                                    (get @core/users  ["Orderer" "admin"])]
 ;;                                                   cu)
-
-(defn create-channel
-  ([channel-name orderer opts]
-   (create-channel core/*user* orderer))
-  ([user channel-name orderer opts]
-   #_
-   (if (known-user-node? user orderer :orderers)
-     (chaincode/send-chaincode-request :query-installed-chaincodes
-                                       system-channel-name
-                                       peer
-                                       user
-                                       {:channel-header-type :endorser-transaction})
-     (throw (Exception. "The target Peer does not know anything about the channel"))))
-  ;; get channel from orderer
-  ;; header - :config-update
-  ;;
-  )

 ;;; set_name
 ;;; Immutable


Fixed fi macro.

Fixed fi macro.

--- src/clojurefx/clojurefx.clj
+++ src/clojurefx/clojurefx.clj
@@ -16,14 +16,19 @@

 (defmacro fi
   [interface args & code]
-  (let [interface-type (.getMapping *ns* interface)
-
-        methods        (-> (.getMethods interface-type)
-                           seq)
-        method-sym     (.getName (first methods))]
-
-    (when-not (= (count methods) 1)
-      (throw (new Exception "can't take an interface with more then one method.")))
+  (debug "interface:" interface)
+  (let [iface-ref (reflect/type-reflect interface)
+        bogus (debug "iface-ref:" iface-ref)
+        methods (filter #(instance? clojure.reflect.Method %) (:members iface-ref))
+        bogus (debug "methods:" (pr-str methods))
+        method-sym (:name (first methods))]
+    (debug "method-sym:" method-sym)
+
+    (when-not (= (count methods) 1)
+      (throw (new Exception (str "can't take an interface with more then one method:" (pr-str methods)))))
+
+    (debug (pr-str `(proxy [~interface] []
+                      (~method-sym ~args ~@code))))

     `(proxy [~interface] []
        (~method-sym ~args
@@ -57,14 +62,14 @@
 (defn by-id [root id]
   (try
     (cond
-      (not (instance? clojure.lang.IFn root)) (do (debug "Raw input confirmed. Starting.")
+      (not (instance? clojure.lang.IFn root)) (do (trace "Raw input confirmed. Starting.")
                                                   (by-id (sgzipper root) id))
-      (zip/end? root) (do (debug "Search ended without result.")
+      (zip/end? root) (do (trace "Search ended without result.")
                           nil)
       (nil? (zip/node root)) (by-id (zip/next root) id)
       (= id (.getId (zip/node root))) (do (debug "Found item:" (zip/node root))
                                           (zip/node root))
-      :else (do (info "id of" (zip/node root) "does not match, proceeding to" (zip/node (zip/next root)))
+      :else (do (trace "id of" (zip/node root) "does not match, proceeding to" (zip/node (zip/next root)))
                 (by-id (zip/next root) id)))
     (catch Exception e (error e))))


Indentation

Indentation

--- src/tick/core.clj
+++ src/tick/core.clj
@@ -12,10 +12,8 @@
   (Clock/tickSeconds (ZoneId/systemDefault)))

 (defn now
-  ([]
-   (ZonedDateTime/now))
-  ([clock]
-   (ZonedDateTime/now clock)))
+  ([] (ZonedDateTime/now))
+  ([clock] (ZonedDateTime/now clock)))

 (defn just-now "Now, but truncated to the nearest second"
   ([] (.truncatedTo (now) (ChronoUnit/SECONDS)))
@@ -202,12 +200,12 @@
     :ok)

   (pause [_]
-    (when-let [fut (:scheduled-future @state)]
-      (.cancel fut false)
-      ;; TODO: Use (compare-and-set!) instead to avoid a race-condition
-      (swap! state (fn [s] (-> s (assoc :status :paused)
-                               (dissoc :scheduled-future))))
+    (let [st @state]
+      (when-let [fut (:scheduled-future st)]
+        (.cancel fut false))
+      (swap! state (fn [st] (-> st (assoc :status :paused) (dissoc :scheduled-future))))
       :ok))
+
   (resume [_]
     (let [st @state]
       (when (= :paused (:status st))
@@ -215,13 +213,14 @@
               executor (:executor st)
               clock (:clock st)]
           ;; TODO: Use (compare-and-set!) instead to avoid a race-condition
-          (swap! state (fn [s] (-> s (assoc :status :running
-                                            :scheduled-future (schedule-next
-                                                               clock
-                                                               (first timeline)
-                                                               executor
-                                                               #(callback state timeline clock trigger executor)))))))
+          (swap! state (fn [st] (-> st (assoc :status :running
+                                              :scheduled-future (schedule-next
+                                                                 clock
+                                                                 (first timeline)
+                                                                 executor
+                                                                 #(callback state timeline clock trigger executor)))))))
         :ok)))
+
   (stop [_]
     (when-let [fut (:scheduled-future @state)]
       (.cancel fut false))


CMR-2337: Add aggregations to the results for :query-specified queries for all concept types

--- search-app/src/cmr/search/results_handlers/query_specified_results_handler.clj
+++ search-app/src/cmr/search/results_handlers/query_specified_results_handler.clj
@@ -24,12 +24,12 @@
   (let [processor (get-elastic-result-item-processor query)]
     (processor context query elastic-result)))

-(defmethod elastic-results/elastic-results->query-results [:granule :query-specified]
-  [context query elastic-results]
-  (assoc (elastic-results/default-elastic-results->query-results context query elastic-results)
-         :aggregations (:aggregations elastic-results)))
+(doseq [concept-type [:collection :granule :tag]]

-(doseq [concept-type [:collection :granule :tag]]
+  (defmethod elastic-results/elastic-results->query-results [concept-type :query-specified]
+    [context query elastic-results]
+    (assoc (elastic-results/default-elastic-results->query-results context query elastic-results)
+           :aggregations (:aggregations elastic-results)))

   (defmethod elastic-search-index/concept-type+result-format->fields [concept-type :query-specified]
     [concept-type query]


CMR-8138: Refactor metrics-service for improved performance (#1530)

* Cache elasticsearch response
* set comprehensive false by default

--- search-app/src/cmr/search/services/community_usage_metrics/metrics_service.clj
+++ search-app/src/cmr/search/services/community_usage_metrics/metrics_service.clj
@@ -24,9 +24,9 @@
    hosts-col - the index of the Hosts in each CSV line"
   [csv-header]
   (let [csv-header (mapv str/trim csv-header)]
-   {:product-col (.indexOf csv-header "Product")
-    :version-col (.indexOf csv-header "Version")
-    :hosts-col (.indexOf csv-header "Hosts")}))
+    {:product-col (.indexOf csv-header "Product")
+     :version-col (.indexOf csv-header "Version")
+     :hosts-col (.indexOf csv-header "Hosts")}))

 (defn- read-csv-column
   "Read a column from the csv, if the column is exists. Otherwise, return nil."
@@ -41,8 +41,8 @@
   [context product-id]
   (when (seq product-id)
     (when-let [parsed-product-id (as-> (re-find #"(^.+):|(^.+)" product-id) matches
-                                       (remove nil? matches)
-                                       (last matches))]
+                                   (remove nil? matches)
+                                   (last matches))]
       (let [condition (gc/or (qm/string-condition :entry-title parsed-product-id false false)
                              (qm/string-condition :short-name parsed-product-id false false)
                              (qm/string-condition :short-name product-id false false))
@@ -54,59 +54,69 @@
             results (qe/execute-query context query)]
         (:short-name (first (:items results)))))))

-(defn- comprehensive-collection-short-name-search
-  "This function will check for a collection with the given product value against short-name and entry-title
-   and return its short-name.  Currently there are providers who are supplying non-short-name values
-   in short-name, which breaks usage metrics.  This is a short term solution to this problem,
-   the long term solution is correcting the EMS data which may take a long time to happen."
-  [context short-name]
-  (get-collection-by-product-id context short-name))
+(defn- cache-or-search
+  "Uses the `product` value to check the short-name-cache.  If there is a miss
+  it checks the current-metrics-cache.  If the `product` is unavailable in either,
+  elasticsearch is queried directly."
+  [context cache current-metrics product]
+  (if (.containsKey cache product)
+    (.get cache product) ;; return cache hit
+    (if (contains? current-metrics product)
+      (do ;; current-metrics hit
+        (.put cache product product)
+        product) ;; return product as short-name
+      (let [short-name (get-collection-by-product-id context product)] ;; query elastic
+        (.put cache product short-name)
+        short-name)))) ;; return queried short-name

-(defn- efficient-collection-short-name-search
-  "This function will check the current community-usage-metrics humanizer to see if this shortname exists,
-   if it does, then it will return that short-name, otherwise it will try looking up the short-name via
-   product-id."
-  [context short-name current-metrics]
-  (if (get current-metrics short-name)
-    short-name
-    (comprehensive-collection-short-name-search context short-name)))
+(defn- get-short-name
+  "Parse the short-name from the given csv-line and verify it exists in CMR.
+   If it doesn't exist in CMR, use the `product` value as-is.
+   Throws a service error if the product column is empty."
+  [context cache csv-line product-col current-metrics]
+  (let [product (read-csv-column csv-line product-col)
+        _ (when-not (seq product)
+            (errors/throw-service-error
+             :invalid-data
+             "Error parsing 'Product' CSV Data. Product may not be empty."))
+        short-name (cache-or-search context cache current-metrics product)]
+    (if (seq short-name)
+      short-name
+      (do
+        (warn (format (str "While constructing community metrics humanizer, "
+                           "could not find corresponding collection when searching for the term %s. "
+                           "Csv line entry: %s")
+                      product
+                      csv-line))
+        product))))
+
+(defn- get-access-count
+  "Parse access-count from given csv-line.  Throws service errors if the hosts column
+   is empty or contains an invalid integer."
+  [csv-line hosts-col]
+  (let [access-count (read-csv-column csv-line hosts-col)]
+    (if (seq access-count)
+      (try
+        (Integer/parseInt (str/replace access-count "," "")) ; Remove commas in large ints
+        (catch java.lang.NumberFormatException e
+          (errors/throw-service-error :invalid-data
+                                      (format (str "Error parsing 'Hosts' CSV Data. "
+                                                   "Hosts must be an integer. "
+                                                   "Csv line entry: [%s]")
+                                              csv-line))))
+      (errors/throw-service-error :invalid-data
+                                  (format (str "Error parsing 'Hosts' CSV Data. "
+                                               "Hosts may not be empty. "
+                                               "Csv line entry: [%s]")
+                                          csv-line)))))

 (defn- csv-entry->community-usage-metric
-  "Convert a line in the csv file to a community usage metric. Only storing short-name (product),
-   version (can be 'N/A' or a version number), and access-count (hosts)"
-  [context csv-line product-col version-col hosts-col comprehensive current-metrics]
+  "Convert a line in the csv file to a community usage metric. Only storing short-name (product)
+   and access-count (hosts)."
+  [context csv-line product-col hosts-col current-metrics cache]
   (when (seq (remove empty? csv-line)) ; Don't process empty lines
-    (let [short-name (read-csv-column csv-line product-col)]
-      (when-not (seq short-name)
-        (errors/throw-service-error :invalid-data
-          "Error parsing 'Product' CSV Data. Product may not be empty."))
-      (let [version (read-csv-column csv-line version-col)
-            searched-short-name (if (= "true" comprehensive)
-                                  (comprehensive-collection-short-name-search context short-name)
-                                  (efficient-collection-short-name-search context short-name current-metrics))]
-        {:short-name (if (seq searched-short-name)
-                       searched-short-name
-                       (do
-                         (warn (format (str "While constructing community metrics humanizer, "
-                                            "could not find corresponding collection when searching for the term %s. "
-                                            "Csv line entry: %s")
-                                       short-name
-                                       csv-line))
-                         short-name))
-         :version version
-         :access-count (let [access-count (read-csv-column csv-line hosts-col)]
-                         (if (seq access-count)
-                           (try
-                             (Integer/parseInt (str/replace access-count "," "")) ; Remove commas in large ints
-                             (catch java.lang.NumberFormatException e
-                               (errors/throw-service-error :invalid-data
-                                 (format (str "Error parsing 'Hosts' CSV Data for collection [%s], version "
-                                              "[%s]. Hosts must be an integer.")
-                                   short-name version))))
-                          (errors/throw-service-error :invalid-data
-                            (format (str "Error parsing 'Hosts' CSV Data for collection [%s], version "
-                                          "[%s]. Hosts may not be empty.")
-                              short-name version))))}))))
+    {:short-name (get-short-name context cache csv-line product-col current-metrics)
+     :access-count (get-access-count csv-line hosts-col)}))

 (defn- validate-and-read-csv
   "Validate the ingested community usage metrics csv and if valid, return the data lines read
@@ -130,28 +140,31 @@
     (errors/throw-service-error :invalid-data "You posted empty content")))

 (defn get-community-usage-metrics
-  "Retrieves the set of community usage metrics from metadata-db."
+  "Retrieves the current community usage metrics from metadata-db."
   [context]
   (:community-usage-metrics (json/decode (:metadata (humanizer-service/fetch-humanizer-concept context)) true)))

+(defn- community-usage-metrics-list->set
+  "Convert list of {:short-name :access-count} maps into a set of short-names."
+  [metrics-list]
+  (set (map :short-name  metrics-list)))
+
 (defn- community-usage-csv->community-usage-metrics
-  "Validate the community usage csv and convert to a list of community usage metrics to save"
-  [context community-usage-csv comprehensive]
-  (let [{:keys [csv-lines product-col version-col hosts-col]} (validate-and-read-csv community-usage-csv)
-        current-metrics (when (= "false" comprehensive)
-                          (get-community-usage-metrics context))]
-    (map #(csv-entry->community-usage-metric context % product-col version-col hosts-col comprehensive current-metrics)
+  "Validate the community usage csv and convert to a list of community usage metrics."
+  [context community-usage-csv current-metrics]
+  (let [{:keys [csv-lines product-col hosts-col]} (validate-and-read-csv community-usage-csv)
+        short-name-cache (new java.util.HashMap)]
+    (map #(csv-entry->community-usage-metric context % product-col hosts-col current-metrics short-name-cache)
          csv-lines)))

 (defn- aggregate-usage-metrics
-  "Combine access counts for entries with the same short-name and version number."
+  "Combine access-counts for entries with the same short-name."
   [metrics]
-  ;; name-version-groups is map of [short-name, version] [entries that match short-name/version]
-  (let [name-version-groups (group-by (juxt :short-name :version) metrics)] ; Group by short-name and version
-    ;; The first entry in each list has the short-name and version we want so just add up the access-counts
-    ;; in the rest and add that to the first entry to make the access-counts right
-    (map #(util/remove-nil-keys (assoc (first %) :access-count (reduce + (map :access-count %))))
-         (vals name-version-groups))))
+  (let [count-map (reduce (fn [m {:keys [short-name access-count]}]
+                            (update m short-name (fnil + 0) access-count))
+                          {}
+                          metrics)]
+    (map (fn [[k v]] {:short-name k :access-count v}) count-map)))

 (defn- validate-metrics
   "Validate metrics against the JSON schema validation"
@@ -174,7 +187,13 @@
   Returns the concept id and revision id of the saved humanizer."
   [context params community-usage-csv]
   (validate-update-community-usage-params params)
-  (let [metrics (community-usage-csv->community-usage-metrics context community-usage-csv (:comprehensive params))
-        metrics (seq (aggregate-usage-metrics metrics))] ; Combine access-counts for entries with the same version/short-name
-    (validate-metrics metrics)
-    (humanizer-service/update-humanizers-metadata context :community-usage-metrics metrics)))
+  (let [comprehensive (or (:comprehensive params) "false") ;; set default
+        current-metrics (if (= "false" comprehensive)
+                          (-> context
+                              (get-community-usage-metrics)
+                              (community-usage-metrics-list->set))
+                          #{})
+        metrics (community-usage-csv->community-usage-metrics context community-usage-csv current-metrics)
+        metrics-agg (aggregate-usage-metrics metrics)]
+    (validate-metrics metrics-agg)
+    (humanizer-service/update-humanizers-metadata context :community-usage-metrics metrics-agg)))


remove dump

remove dump

--- src/cljs/salava/social/ui/badge_message_modal.cljs
+++ src/cljs/salava/social/ui/badge_message_modal.cljs
@@ -21,7 +21,6 @@
                        (str (:new-messages message_count) " " (t :social/Newmessages ))
                        "")
         all-messages (str all-messages new-messages)]
-    (dump (str "test: "image_file))
     (fn []
       [:div {:id "badge-contents"}
        [:div.row


Using sorted map for cassandra results, zipped map makes absolutely no sense

--- src/clojure/clojurewerkz/cassaforte/conversion.clj
+++ src/clojure/clojurewerkz/cassaforte/conversion.clj
@@ -327,7 +327,7 @@
                                    (cb/deserialize key-format (:key %)))
                                  list))
              values (reverse (map #(to-plain-hash (or (:columns %) (:value %))) list))]
-         (zipmap names values))))
+         (apply sorted-map (interleave names values)))))

   ColumnOrSuperColumn
   (to-plain-hash


Retrieve a user's playlists

Retrieve a user's playlists

--- src/trak/api.cljs
+++ src/trak/api.cljs
@@ -35,3 +35,11 @@
             (fn [response] (pubsub/publish :actions {:action :api-call-result
                                                      :params {:call     :me
                                                               :response response}}))))
+(defn user-playlists [href auth]
+  (api-call (partial http/get)
+            (str href "/playlists")
+            {:with-credentials? false
+             :oauth-token       auth}
+            (fn [response] (pubsub/publish :actions {:action :api-call-result
+                                                     :params {:call     :user-playlists
+                                                              :response response}}))))


(TK-202) Move test helper closer to tests that use it

--- test/puppetlabs/trapperkeeper/services_test.clj
+++ test/puppetlabs/trapperkeeper/services_test.clj
@@ -51,6 +51,14 @@
 (defprotocol Service3
   (service3-fn [this]))

+(deftest test-services-not-required
+  (testing "services are not required to define lifecycle functions"
+    (let [service1 (service Service1
+                     []
+                     (service1-fn [this] "hi"))
+          app (bootstrap-services-with-empty-config [service1])]
+      (is (not (nil? app))))))
+
 (defn create-lifecycle-services
   [call-seq]

@@ -78,14 +86,6 @@
        (start [this context] (lc-fn context :start-service3))
        (stop [this context] (lc-fn context :stop-service3))
        (service3-fn [this] (lc-fn nil :service3-fn)))]))
-
-(deftest test-services-not-required
-  (testing "services are not required to define lifecycle functions"
-    (let [service1 (service Service1
-                     []
-                     (service1-fn [this] "hi"))
-          app (bootstrap-services-with-empty-config [service1])]
-      (is (not (nil? app))))))

 (deftest test-lifecycle-functions-ordered-correctly
   (testing "life cycle functions are called in the correct order"


Made make-context to automatically restrict the incidence relation

and removed all other code from conexp.fca.contexts which has done this.

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

--- src/conexp/fca/contexts.clj
+++ src/conexp/fca/contexts.clj
@@ -105,11 +105,7 @@
   (and (instance? conexp.fca.Context other)
        (= (objects this) (objects other))
        (= (attributes this) (attributes other))
-       (let [inz-this (incidence this)
-	     inz-other (incidence other)]
-	 (or (= (incidence this) (incidence other))
-	     (forall [pair (cross-product (objects this) (attributes this))]
-               (<=> (inz-this pair) (inz-other pair)))))))
+       (= (incidence this) (incidence other))))

 (defn Context-hashCode
   "Implements hashCode for contexts."
@@ -130,13 +126,20 @@
 (defmulti make-context
   "Standard constructor for contexts. Takes a sequence of objects,
   a sequence of attributes and either a set of pairs or function of
-  two elements being true iff its arguments are incident. Note that the
-  object and attribute sequences are converted to sets and therefore have to
-  not contain any douplicate elements."
+  two elements being true iff its arguments are incident. Note that
+  the object and attribute sequences are converted to sets and
+  therefore have to not contain any douplicate elements. The incidence
+  relation is auzomatically restricted to the cartesian product of the
+  object an the attribute set."
   (fn [& args] (map type-of args)))

 (defmethod make-context [::set ::set ::set] [objects attributes incidence]
-  (conexp.fca.Context. (set objects) (set attributes) (set incidence)))
+  (let [objs (set objects)
+	atts (set attributes)
+	inz  (set-of [g m] [[g m] incidence
+			    :when (and (contains? objs g)
+				       (contains? atts m))])]
+    (conexp.fca.Context. objs atts inz)))

 (defmethod make-context [::set ::set ::fn] [objects attributes incidence]
   (make-context objects attributes (set-of [x y] [x objects
@@ -189,19 +192,15 @@
   "Clarifies objects in context ctx."
   [ctx]
   (let [prime (memoize (partial object-derivation ctx))
-	new-objs (set (distinct-by-key (objects ctx) #(prime #{%})))
-	new-inz (set-of [g m] [[g m] (incidence ctx)
-			       :when (contains? new-objs g)])]
-    (make-context new-objs (attributes ctx) new-inz)))
+	new-objs (set (distinct-by-key (objects ctx) #(prime #{%})))]
+    (make-context new-objs (attributes ctx) (incidence ctx))))

 (defn clarify-attributes
   "Clarifies attributes in context ctx."
   [ctx]
   (let [prime (memoize (partial attribute-derivation ctx))
-	new-atts (set (distinct-by-key (attributes ctx) #(prime #{%})))
-	new-inz (set-of [g m] [[g m] (incidence ctx)
-			       :when (contains? new-atts m)])]
-    (make-context (objects ctx) new-atts new-inz)))
+	new-atts (set (distinct-by-key (attributes ctx) #(prime #{%})))]
+    (make-context (objects ctx) new-atts (incidence ctx))))

 (defn clarify-context
   "Clarifies context ctx."
@@ -270,12 +269,10 @@
 (defn reduce-clarified-context
   "Reduces context ctx assuming it is clarified."
   [ctx]
-  (let [inz (incidence ctx)
-	uda (up-down-arrows ctx)]
-    (let [new-obj (set (map first uda))
-	  new-att (set (map second uda))
-	  new-inz (set-of [g m] [g new-obj m new-att :when (inz [g m])])]
-    (make-context new-obj new-att (set new-inz)))))
+  (let [uda (up-down-arrows ctx)
+	new-obj (set (map first uda))
+	new-att (set (map second uda))]
+    (make-context new-obj new-att (incidence ctx))))

 (defn reduce-context
   "Reduces context ctx."
@@ -585,11 +582,6 @@
 				       (fn [g m]
 					 (not (contains? down-down [g m]))))]
     (for [[G-H N] (concepts compatible-ctx)]
-      (let [objs (difference (objects ctx) G-H)
-	    atts N
-	    inz  (set-of [g m] [[g m] (incidence ctx)
-				:when (and (contains? objs g)
-					   (contains? atts m))])]
-	(make-context objs atts inz)))))
+      (make-context (difference (objects ctx) G-H) N (incidence ctx)))))

 nil


cleanup

cleanup

--- test/babel/test/en.cljc
+++ test/babel/test/en.cljc
@@ -278,8 +278,7 @@
                                               :mod '()
                                               :number :sing
                                               :spec {:def :def
-                                                     :pred :definite}}
-                                       :tense :present}}})]
+                                                     :pred :definite}}}}})]
     (log/info (str "reflexive furniture expression:" (display-expression expr)))
     (is (= (fo expr)
            "the chair is in front of itself"))))


+TODO

+TODO

--- test/babel/test/la.cljc
+++ test/babel/test/la.cljc
@@ -119,7 +119,7 @@
           pose-question-to-user
           (source/morph (source/generate {:synsem {:sem semantics}}
                                          :model source-model)
-                        :show-notes false)
+                        :show-notes false) ;; TODO: use {:from-language :la}
           result
           (-> spec
               target/generate)]


Add test cases for fa2pac, pac2bwt, bwtgen, and bwt2sa

--- test/clj_bwa/t_core.clj
+++ test/clj_bwa/t_core.clj
@@ -36,6 +36,8 @@
                     "test-resources/test.fa.bwt"
                     "test-resources/test.fa.pac"
                     "test-resources/test.fa.sa"])
+(def test-pac-file "test-resources/test.fa.pac")
+(def test-bwt-file "test-resources/test.fa.bwt")
 (def test-sai-file "test-resources/test.sai")
 (def test-fq-file "test-resources/test.fq")

@@ -165,3 +167,46 @@
                    (str temp-dir "/test.fq")
                    (str temp-dir "/out.fastmap")
                    (bwa/fastmap-option))) => anything))
+
+;; fa2pac test
+;; -----------
+
+(with-state-changes [(before :facts (do (prepare-cache!)
+                                        (fs/copy test-fa-file (str temp-dir "/test.fa"))))
+                     (after :facts (clean-cache!))]
+  (fact "about fa2pac"
+    (with-out-file temp-out
+      (bwa/fa2pac (str temp-dir "/test.fa") (str temp-dir "/test1.fa") false) => anything
+      (bwa/fa2pac (str temp-dir "/test.fa") (str temp-dir "/test2.fa") true) => anything)))
+
+;; pac2bwt test
+;; ------------
+
+(with-state-changes [(before :facts (do (prepare-cache!)
+                                        (fs/copy test-pac-file (str temp-dir "/test.fa.pac"))))
+                     (after :facts (clean-cache!))]
+  (fact "about pac2bwt"
+    (with-out-file temp-out
+      (bwa/pac2bwt (str temp-dir "/test.fa.pac") (str temp-dir "/test1.fa.bwt") true) => anything
+      ;; FIXME: The following fact is failed
+      #_(bwa/pac2bwt (str temp-dir "/test.fa.pac") (str temp-dir "/test2.fa.bwt") false) => anything)))
+
+;; bwtgen
+;; ------
+
+(with-state-changes [(before :facts (do (prepare-cache!)
+                                        (fs/copy test-pac-file (str temp-dir "/test.fa.pac"))))
+                     (after :facts (clean-cache!))]
+  (fact "about bwtgen"
+    (with-out-file temp-out
+      (bwa/bwtgen (str temp-dir "/test.fa.pac") (str temp-dir "/test1.fa.bwt")) => anything)))
+
+;; bwt2sa
+;; ------
+
+(with-state-changes [(before :facts (do (prepare-cache!)
+                                        (fs/copy test-bwt-file (str temp-dir "/test.fa.bwt"))))
+                     (after :facts (clean-cache!))]
+  (fact "about bwt2sa"
+    (with-out-file temp-out
+      (bwa/bwt2sa (str temp-dir "/test.fa.bwt") (str temp-dir "/test.fa.sa") 32) => anything)))


Don't show projects card at all until org selected

--- src-cljs/frontend/components/pages/projects.cljs
+++ src-cljs/frontend/components/pages/projects.cljs
@@ -65,13 +65,13 @@
                        :selected-org (first (filter #(= selected-org-ident (organization-ident %)) (:organizations user)))
                        :on-org-click #(om/set-state! owner :selected-org-ident (organization-ident %))})]]
           [:.main
-           [:.card
-            [:.header
-             [:.title
-              (:name selected-org)
-              (case (:vcs_type selected-org)
-                "github" [:i.octicon.octicon-mark-github]
-                "bitbucket" [:i.fa.fa-bitbucket]
-                nil)]]
-            (when selected-org
-              (om/build table (:projects selected-org)))]]])))))
+           (when selected-org
+             [:.card
+              [:.header
+               [:.title
+                (:name selected-org)
+                (case (:vcs_type selected-org)
+                  "github" [:i.octicon.octicon-mark-github]
+                  "bitbucket" [:i.fa.fa-bitbucket]
+                  nil)]]
+              (om/build table (:projects selected-org))])]])))))


Updated JVMP Jetty9 dependency to 0.5.2

Updated JVMP Jetty9 dependency to 0.5.2

This commit updates the jvm-puppet project's dependency on
trapperkeeper-webservices-jetty9 to version 0.5.2.

--- configs/jvm-puppet/jvm-puppet.clj
+++ configs/jvm-puppet/jvm-puppet.clj
@@ -2,7 +2,7 @@
   :description "Release artifacts for jvm-puppet"
   :pedantic? :abort
   :dependencies [[puppetlabs/jvm-puppet "{{{jvm-puppet-version}}}"]
-                 [puppetlabs/trapperkeeper-webserver-jetty9 "0.5.1"]]
+                 [puppetlabs/trapperkeeper-webserver-jetty9 "0.5.2"]]

   :uberjar-name "jvm-puppet-release.jar"


Add tmp table defs

Add tmp table defs

--- test/clojure/clojurewerkz/cassaforte/test_helper.clj
+++ test/clojure/clojurewerkz/cassaforte/test_helper.clj
@@ -5,6 +5,12 @@
             [clojurewerkz.cassaforte.query.dsl :refer :all]))

 (def ^:dynamic *session*)
+
+(def table-definitions
+  {:tv_series {:series_title  :varchar
+               :episode_id    :int
+               :episode_title :text
+               :primary-key [:series_title :episode_id]}})
 (defn with-temporary-keyspace
   [f]

@@ -69,3 +75,11 @@
       (finally
         (client/disconnect! session)))
     ))
+
+(defmacro with-table
+  [table-name & body]
+  `(do
+     (create-table *session* ~table-name
+                   (column-definitions (get table-definitions ~table-name)))
+     ~@body
+     (drop-table *session*  ~table-name)))


abort discriminator-finding only on finding no non-empty token

--- src/calfpath/internal.cljc
+++ src/calfpath/internal.cljc
@@ -230,7 +230,7 @@
   (loop [token-count   1
          token-vectors routes-uri-tokens]
     (cond
-      (some empty?
+      (every? empty?
         token-vectors)   [nil 0]
       (->> token-vectors
         (map first)


data type checker test

data type checker test

--- test/neb/test/trunk.clj
+++ test/neb/test/trunk.clj
@@ -42,6 +42,8 @@
              (add-schema :test-schema2 compound-scheme 2) => anything)
        (fact "write cell with compound shceme"
              (new-cell @ttrunk 2 1 (int 2) compound-scheme-data) => anything)
+       (fact "Write cell with wrong data types"
+             (new-cell @ttrunk 3 1 (int 1) {:int-value "abc"}) => (throws IllegalArgumentException))
        (fact "read cell with compound scheme"
              (read-cell @ttrunk 2) => (contains compound-scheme-data))
        (fact "delete cell"


repo-exists? should use the .git directory, not the containing directory.

--- src/circle/backend/git.clj
+++ src/circle/backend/git.clj
@@ -36,7 +36,7 @@
 (defn repo-exists? [path]
   (let [git-dir (fs/join path ".git")]
     (->
-     (sh/shq [(stat ~path)])
+     (sh/shq [(stat ~git-dir)])
      (:exit)
      (= 0))))


Remove validation errors when no validators, remove soft-key and key from code, start validation in update-binding

--- src/cljs/re_form/core.cljs
+++ src/cljs/re_form/core.cljs
@@ -164,7 +164,8 @@
              body)])}))

 (defn- validate-and-update-errors [form-name path validators val]
-  (when-not (empty? validators)
+  (if (empty? validators)
+    (rf/dispatch [:re-form/validation-errors form-name {path nil}])
     (let [errors
           (reduce (fn [acc validator]
                     (if-let [res (validator val path)]
@@ -210,9 +211,9 @@
           (rf/dispatch [:re-form/input-removed form-name path]))

         update-binding
-        (fn [{new-soft-key :soft-key new-form :form-name new-path :path validators :validators :as new-state}]
-          (swap! state (fn [{soft-key :soft-key val :value err :errors path :path form :form-name :as curr-state}]
-                         (if (or (not= soft-key new-soft-key) (not= path new-path) (not= form new-form))
+        (fn [{new-form :form-name new-path :path validators :validators :as new-state}]
+          (swap! state (fn [{val :value err :errors path :path form :form-name :as curr-state}]
+                         (if (or (not= path new-path) (not= form new-form))
                            (do
                              (when (and form path)
                                (unbind-input form path))
@@ -223,12 +224,13 @@
                                ;; future validations
                                (add-watch new-val-subscr :binded-field run-validators)

-                               {:soft-key new-soft-key
-                                :form-name new-form
+                               {:form-name new-form
                                 :path new-path
                                 :value new-val-subscr
                                 :validators validators}))
-                           (assoc curr-state :validators validators)))))]
+                           (do
+                             (validate-and-update-errors new-form new-path validators @val)
+                             (assoc curr-state :validators validators))))))]

     (reagent/create-class
      {:display-name :binded-field
@@ -246,15 +248,14 @@
         (update-binding (second new-props)))

       :reagent-render
-      (fn [{:keys [key on-change form-name path on-blur error-paths] :as props}]
+      (fn [{:keys [on-change form-name path on-blur error-paths] :as props}]
         (let [flags @(rf/subscribe [:re-form/input-flags form-name path])
               is-form-submitting @(rf/subscribe [:re-form/is-form-submitting form-name])
               errors @(rf/subscribe [:re-form/input-errors form-name (into [path] error-paths)])]
           [:div.re-form-field {:class (->> flags
                                            (filter second)
                                            (map #(name (first %)))
-                                           (str/join " "))
-                               :key key}
+                                           (str/join " "))}
            [(:input props)
             (merge (dissoc props :form-name :path :input :validators)
                    {:value @(:value @state)


Now init also sets replumb's custom cljs.js/*eval-fn*

--- src/cljs/replumb/repl.cljs
+++ src/cljs/replumb/repl.cljs
@@ -391,6 +391,12 @@
                                   (conj init-fns fn)
                                   init-fns))))

+(defn add-init-eval-fn
+  "Given current and user options, returns a map containing a
+  valid :init-fns,conjoining with the one in current if necessary."
+  [opts user-opts]
+  (update-in opts [:init-fns] conj #(set! cljs.js/*eval-fn* (make-js-eval-fn user-opts))))
+
 (defn normalize-opts
   "Process the user options. Returns the map that can be fed to
   read-eval-call."
@@ -399,6 +405,7 @@
     ;; AR - note the order here, the last always overrides
     (-> vld-opts
         (add-default-opts vld-opts)
+        (add-init-eval-fn vld-opts)
         (add-load-fn vld-opts)
         (add-init-fns vld-opts))))


search instructions

search instructions

--- src/cljs/unfolds/core.cljs
+++ src/cljs/unfolds/core.cljs
@@ -141,6 +141,9 @@
       (let [opts {:current-item current-item ;;; XXX
                   :sync sync}]
         (dom/div #js {:id "search-view"}
+                 (dom/p nil "Currently only title's are searchable. It
+                 might take a few seconds before entries are
+                 indexed.")
           (str "Search: ")
           (dom/input #js {:value (:search state)
                           :type "text"


Add route signal transforms

Add route signal transforms

--- src/cljs_game/signals.cljs
+++ src/cljs_game/signals.cljs
@@ -79,6 +79,29 @@
                (propagate out-signal new-state))))
     out-signal))

+(defn ^:export route
+  "Given an input-signal, and sequence of predicates, returns a sequence of output-signals, each triggered when their predicate is true. Predicates are of arity 3, receving the target tag, old-state, and new-state from the input-signal, returning true if the signal should trigger the corresponding output-signal."
+  [input-signal & rest-args]
+  (let [routes (map (fn [pred]
+                      (when (fn? pred)
+                        {:signal (signal nil (str "route-" pred))
+                         :pred pred}))
+                    rest-args)]
+    (watch in-signal (:tag (:signal (first routes)))
+           (fn [target old-state new-state]
+             (map (fn [{signal :signal pred :pred}]
+                    (when (pred target old-state new-state)
+                      (propagate signal new-state)))
+                  routes)))
+    routes))
+
+(defn route*
+  [input-signal & rest-args]
+  (map (fn [pred]
+         (when (fn? pred)
+           (filter* pred input-signal)))
+       rest-args))
+
 ;; TODO, mechanism to removeEventListener? Grr Javascript wants the original func object
 ;;; Possibly, store the anon func as the tag in the outsignal? Otherwise make another field in signal :/
 (defn ^:export keyboard


Add Nemesis partitions back in :-)

Add Nemesis partitions back in :-)

--- src/copycat_jepsen/core.clj
+++ src/copycat_jepsen/core.clj
@@ -210,7 +210,7 @@
             :model   (model/cas-register)
             :checker   (checker/compose {:html timeline/html
                                          :linear checker/linearizable})
-            :nemesis  (nemesis/noop)
+            :nemesis  (nemesis/partition-random-halves)
             :ssh      {:private-key-path "/home/vagrant/.ssh/id_rsa"}
             :node-set node-set})))


Use btn-info for 'add word'-buttons

Use btn-info for 'add word'-buttons

--- src/cljs/cglossa/search_inputs/cwb/extended.cljs
+++ src/cljs/cglossa/search_inputs/cwb/extended.cljs
@@ -118,10 +118,10 @@
              [:span.glyphicon.glyphicon-minus]])
           (when last?
             [:div.add-search-word
-             [:button.btn.btn-default.btn-sm {:data-add-term-button ""
-                                  :title                "Add search word"
-                                  ;:on-click             #(on-add-term)
-                                  }
+             [:button.btn.btn-info.btn-sm {:data-add-term-button ""
+                                           :title                "Add search word"
+                                           ;:on-click             #(on-add-term)
+                                           }
               [:span.glyphicon.glyphicon-plus]]])]]]
        [:div.table-row
         (when first?


[#7821] Fix navigation on sending eth from chat

--- src/status_im/chat/commands/impl/transactions.cljs
+++ src/status_im/chat/commands/impl/transactions.cljs
@@ -304,8 +304,8 @@
           {:keys [symbol decimals]} (tokens/asset-for all-tokens chain symbol-param)
           {:keys [value error]}     (wallet.db/parse-amount amount decimals)
           next-view-id              (if (:wallet-set-up-passed? sender-account)
-                                      :wallet-send-transaction-modal
-                                      :wallet-onboarding-setup)]
+                                      :wallet-send-modal-stack
+                                      :wallet-send-modal-stack-with-onboarding)]
       (fx/merge cofx
                 {:db (-> db
                          (update-in [:wallet :send-transaction]


Add comment re. no parameters impl.

Add comment re. no parameters impl.

--- src/yada/core.clj
+++ src/yada/core.clj
@@ -181,7 +181,10 @@
          parameters (try
                       (res/parameters resource)
                       (catch AbstractMethodError e
-                        (throw (ex-info "No parameters implementation" {:resource resource}))))
+                        ;; This is while we're in transition and so many
+                        ;; resources don't have a parameters
+                        ;; function. TODO: Remove me
+                        (throw (ex-info "No parameters implementation" {:resource (type resource)}))))

          methods (methods/methods)


Feature/lambda etc (#19)

Feature/lambda etc (#19)

* reflow long lines

* basic support for lambda and custom resources

* namespace new stuff correctly

* update for latest features

* fix lambda specs

--- src/crucible/aws/lambda.clj
+++ src/crucible/aws/lambda.clj
@@ -8,37 +8,31 @@
 (defmethod ->key ::s3-key [_] "S3Key")
 (defmethod ->key ::s3-object-version [_] "S3ObjectVersion")

-(s/def ::subnet-ids ::v/value)
+(s/def ::subnet-id (v/spec-or-ref string?))

-(s/def ::security-group-ids ::v/value)
+(s/def ::security-group-ids (v/spec-or-ref string?))

 (s/def ::vpc-config (s/keys :req [::security-group-ids]
                             :opt [::subnet-ids]))

-(s/def ::timeout (s/or :compiled (s/and
-                                  pos-int?
-                                  #(<= % (* 5 60)))
-                       :runtime ::v/value))
+(s/def ::timeout (v/spec-or-ref (s/and pos-int? #(<= % (* 5 60)))))

 (s/def ::runtime #{"nodejs" "nodejs4.3" "java8" "python2.7"})

-(s/def ::role ::v/value)
+(s/def ::role (v/spec-or-ref string?))

-(s/def ::memory-size (s/or :compiled (s/and
-                                      #(-> % (mod 64) (= 0))
-                                      #(<= 128 % 1536))
-                           :runtime ::v/value))
+(s/def ::memory-size (v/spec-or-ref (s/and #(-> % (mod 64) (= 0)) #(<= 128 % 1536))))

-(s/def ::handler ::v/value)
+(s/def ::handler (v/spec-or-ref string?))

-(s/def ::function-name ::v/value)
+(s/def ::function-name (v/spec-or-ref string?))

-(s/def ::description ::v/value)
+(s/def ::description (v/spec-or-ref string?))

-(s/def ::s3-bucket ::v/value)
-(s/def ::s3-key ::v/value)
-(s/def ::s3-object-version ::v/value)
-(s/def ::zip-file ::v/value)
+(s/def ::s3-bucket (v/spec-or-ref string?))
+(s/def ::s3-key (v/spec-or-ref string?))
+(s/def ::s3-object-version (v/spec-or-ref string?))
+(s/def ::zip-file (v/spec-or-ref string?))

 (s/def ::code (s/keys ::opt [::s3-bucket
                              ::s3-key
@@ -57,18 +51,13 @@

 (def function (resource-factory "AWS::Lambda::Function" ::function))

-(s/def ::batch-size (s/or :compiled (s/and pos-int?
-                                           #(< % 10000))
-                          :runtime ::v/value))
+(s/def ::batch-size (v/spec-or-ref (s/and pos-int? #(< % 10000))))

-(s/def ::enabled (s/or :compiled boolean?
-                       :runtime ::v/value))
+(s/def ::enabled (v/spec-or-ref boolean?))

-(s/def ::event-source-arn (s/or :compiled string?
-                                :runtime ::v/value))
+(s/def ::event-source-arn (v/spec-or-ref string?))

-(s/def ::starting-postition (s/or :compiled #{"TRIM_HORIZON" "LATEST"}
-                                  :runtime ::v/value))
+(s/def ::starting-postition (v/spec-or-ref #{"TRIM_HORIZON" "LATEST"}))

 (s/def ::event-source-mapping (s/keys :req [::event-source-arn
                                             ::function-name


Redirect on POST of signup form

Redirect on POST of signup form

--- src/cylon/signup/signup.clj
+++ src/cylon/signup/signup.clj
@@ -1,6 +1,6 @@
 (ns cylon.signup.signup
   (:require
-   [cylon.signup.protocols :refer (render-signup-form send-email render-email-verified Emailer SignupFormRenderer WelcomeRenderer render-welcome)]
+   [cylon.signup.protocols :refer (render-signup-form send-email render-email-verified Emailer SignupFormRenderer)]
    [clojure.tools.logging :refer :all]
    [cylon.session :refer (session respond-with-new-session! assoc-session-data!)]
    [cylon.session.protocols :refer (SessionStore)]
@@ -12,7 +12,7 @@
    [hiccup.core :refer (html)]
    [ring.middleware.params :refer (params-request)]
    [ring.middleware.cookies :refer (cookies-response wrap-cookies)]
-   [ring.util.response :refer (response redirect)]
+   [ring.util.response :refer (response redirect redirect-after-post)]
    [cylon.user :refer (create-user! verify-email!)]
    [cylon.user.protocols :refer (UserStore)]
    [cylon.totp :as totp]
@@ -28,7 +28,8 @@
   {:fields [{:name s/Str
              :label s/Str
              (s/optional-key :placeholder) s/Str
-             (s/optional-key :password?) s/Bool}]})
+             (s/optional-key :password?) s/Bool}]
+   (s/optional-key :post-signup-redirect) s/Str})

 (defrecord SignupWithTotp [renderer session-store user-store password-verifier verification-code-store emailer fields]
   Lifecycle
@@ -39,13 +40,12 @@
                   :session-store (s/protocol SessionStore)
                   :password-verifier (s/protocol PasswordVerifier)
                   :verification-code-store (s/protocol TokenStore)
-                  :renderer (s/both (s/protocol SignupFormRenderer)
-                                    (s/protocol WelcomeRenderer))
+                  :renderer s/Any
                   (s/optional-key :emailer) (s/protocol Emailer)})
                 component))
   (stop [component] component)
   WebService
-  (request-handlers [this]
+  (request-handlers [component]
     {::GET-signup-form
      (fn [req]
        (let [resp (response (render-signup-form
@@ -57,6 +57,8 @@
            ;; We create an empty session. This is because the POST
            ;; handler requires that a session exists within which it can
            ;; store the identity on a successful login
+           ;; (revisit: the comment above is wrong, the POST handler can
+           ;; create the session)
            (respond-with-new-session! session-store req {} resp)
            resp)))

@@ -94,25 +96,25 @@
                                  (make-verification-link req code email)))))

          ;; Create a session that contains the secret-key
-         (let [data (merge {:cylon/subject-identifier uid
-                            :name name}
+         (let [data (merge {:cylon/subject-identifier uid :name name}
                            (when (satisfies? OneTimePasswordStore user-store)
-                             {:totp-secret totp-secret})
-                           )]
+                             {:totp-secret totp-secret}))]
            (assoc-session-data! session-store req data)
-           (response (render-welcome
-                      renderer req
-                      (merge
-                       {:session (session session-store req)}
-                       form
-                       data))))))
+
+           (respond-with-new-session!
+            session-store req
+            {:cylon/subject-identifier uid}
+            (if-let [loc (or (get form "post_signup_redirect")
+                             (:post-signup-redirect component))]
+              (redirect-after-post loc)
+              (response (format "Thank you, %s, for signing up" name)))))))

      ::verify-user-email
      (fn [req]
        (let [params (-> req params-request :params)
              body
              (if-let [[email code] [ (get params "email") (get params "code")]]
-               (if-let [store (get-token-by-id (:verification-code-store this) code)]
+               (if-let [store (get-token-by-id (:verification-code-store component) code)]
                  (if (= email (:email store))
                    (do (verify-email! user-store (:name store))
                        (format "Thanks, Your email '%s'  has been verified correctly " email))
@@ -125,13 +127,13 @@

      })

-  (routes [this]
+  (routes [_]
     ["/" {"signup" {:get ::GET-signup-form
                     :post ::POST-signup-form}
           "verify-email" {:get ::verify-user-email}
           }])

-  (uri-context [this] ""))
+  (uri-context [_] ""))

 (defn new-signup-with-totp [& {:as opts}]
   (component/using