Added subject to ios email

Added subject to ios email

--- src-cljs/frontend/components/mobile.cljs
+++ src-cljs/frontend/components/mobile.cljs
@@ -141,7 +141,7 @@
                                          [:br]
                                          [:br]
                                          "Currently in beta. Interested in joining? Please "
-                                         [:a {:href "mailto:sayhi@circleci.com"} "contact us."]]
+                                         [:a {:href "mailto:sayhi@circleci.com?subject=ios"} "contact us."]]
                      :subheadline "More testing, fewer bugs, better iOS apps."
                      :explanation "Each time you push new code to your repo on Github for your
                                   iOS app, CircleCI will automatically build and test your


Fixed ordering of options/req override.

Fixed ordering of options/req override.

--- src/cmr/http/kit/request.clj
+++ src/cmr/http/kit/request.clj
@@ -58,8 +58,8 @@

 (defn request
   [method url req options callback]
-  (httpc/request (-> options
-                     (merge req)
+  (httpc/request (-> req
+                     (merge options)
                      (assoc :url url :method method)
                      ((fn [x] (log/trace "Options to httpc:" x) x)))
                   callback))


Proto solution with clojure.

Proto solution with clojure.

--- src/ombs/db.clj
+++ src/ombs/db.clj
@@ -83,3 +83,11 @@
   (sql/select participants (sql/fields)
               (sql/with users (sql/where (= :name uname)) (sql/fields))
               (sql/with events (sql/fields [:name :event]))))
+
+(defn participated-list [uname]
+  ;need grouping by event params. Should get event params and vector of it's users.
+  ;Actually it's solved by sqlite.
+ (map
+  #(assoc % :participated? (= (:username %) uname))
+  (sql/select participation) ) )
+


Escape html from title and synopsis

Escape html from title and synopsis

--- src/storemi/models/story.clj
+++ src/storemi/models/story.clj
@@ -1,5 +1,6 @@
 (ns storemi.models.story
   (:require
+    [hiccup.util :refer [escape-html]]
     [clj-http.client :as client]
     [clojure.java.jdbc :as sql]
     [storemi.models.db :as db]
@@ -81,8 +82,8 @@
           {:username  username
            :data      (db/json-string data)
            :script    script
-           :title     title
-           :synopsis  synopsis})]
+           :title     (escape-html title)
+           :synopsis  (escape-html synopsis)})]
     (first response)))

 (defn parse-script [script]


Don't overwrite non-streaming mime type

Don't overwrite non-streaming mime type

--- src/zoo_event/web/routes.clj
+++ src/zoo_event/web/routes.clj
@@ -28,7 +28,9 @@
   [handler]
   (fn [req]
     (handler
-      (if (= (get-in req [:headers "upgrade"] "websocket"))
+      (if (and (= (get-in req [:headers "upgrade"]) "websocket")
+               (not (or (= (get-in req [:headers "accept"]) app-mime)
+                        (= (get-in req [:headers "accept"]) "application/json"))))
         (update-in req [:headers] assoc "accept" stream-mime)
         req))))


ontology autocomplete: handle out-of-order ajax [risk: low] (#1460)

only show autosuggest results that match current search value

--- src/cljs/main/broadfcui/components/autosuggest.cljs
+++ src/cljs/main/broadfcui/components/autosuggest.cljs
@@ -50,8 +50,15 @@
               :on-clear (when on-submit on-clear)
               :on-submit (when on-submit wrapped-on-submit))))
    :get-initial-state
+   ;; when the user rapidly enters characters in the autosuggest input field, we fire off multiple ajax
+   ;; requests (assuming the autosuggest is powered by a remote url). We can receive the results for those
+   ;; ajax requests out of order, which results in the UI showing suggestions that don't match the current
+   ;; input. We use the latest-input key to track which is the latest value input by the user, so we only
+   ;; show suggestions for that input.
    (fn [{:keys [props]}]
-     {:value (or (:value props) (:default-value props))})
+     {:value (or (:value props) (:default-value props))
+      :latest-input false
+      :ajax-result-map {}})
    :render
    (fn [{:keys [state props locals]}]
      (let [{:keys [data url service-prefix get-suggestions on-change caching? get-value suggestionsProps]} props
@@ -61,16 +68,26 @@
                              get-suggestions (fn [value]
                                                (get-suggestions (.-value value) #(swap! state assoc :suggestions %)))
                              url (fn [value]
+                                   ;; this is called in response to user keystrokes. Here, <value> represents the current user input.
+                                   (swap! state assoc :latest-input value)
                                    (ajax/call-orch
                                     (str url (.-value value))
                                     {:on-done (fn [{:keys [success? get-parsed-response]}]
-                                                (swap! state assoc :suggestions
-                                                       (if success?
-                                                         ; don't bother keywordizing, it's just going to be converted to js
-                                                         (filterv
-                                                          (fn [suggestion] (not (utils/seq-contains? (:remove-selected props) (get suggestion "id"))))
-                                                          (get-parsed-response false))
-                                                         [:error])))}
+                                                (let [result-map (:ajax-result-map @state)
+                                                      ajax-results (if success?
+                                                                     ; don't bother keywordizing, it's just going to be converted to js
+                                                                     (filterv
+                                                                      (fn [suggestion] (not (utils/seq-contains? (:remove-selected props) (get suggestion "id"))))
+                                                                       (get-parsed-response false))
+                                                                     [:error])
+                                                      updated-result-map (assoc result-map value ajax-results)]
+                                                  ;; this is called in response to an ajax request returning. Here, <value> represents the argument sent to the
+                                                  ;; ajax request, and we need to look to <(:latest-input @state)> to see the current user input.
+                                                  ;;
+                                                  ;; save results for this ajax request - which may not be current - to state
+                                                  (swap! state assoc :ajax-result-map updated-result-map)
+                                                  ;; extract results from state for the current input value
+                                                  (swap! state assoc :suggestions (get updated-result-map (:latest-input @state) []))))}
                                     (when service-prefix :service-prefix) service-prefix)
                                    [:loading])
                              :else (fn [value]


Reworded...

Reworded...

--- frontend/controllers/navigation.cljs
+++ frontend/controllers/navigation.cljs
@@ -5,7 +5,7 @@
             [frontend.utils.vcs-url :as vcs-url]
             [goog.string :as gstring]))

-;; --- Convenience methods ---
+;; --- Helper Methods ---

 (def from
   :navigation-point)


update version

update version

--- kafka-clj/project.clj
+++ kafka-clj/project.clj
@@ -1,4 +1,4 @@
-(defproject kafka-clj "2.4.3-SNAPSHOT"
+(defproject kafka-clj "2.4.3"
   :description "fast kafka library implemented in clojure"
   :url "https://github.com/gerritjvv/kafka-fast"
   :license {:name "Eclipse Public License"
@@ -29,7 +29,7 @@
                  [org.clojure/tools.trace "0.7.6"]
                  [org.xerial.snappy/snappy-java "1.1.1.6"]
                  [org.clojure/tools.logging "0.3.0"]
-                 [clj-tcp "0.4.3-SNAPSHOT"]
+                 [clj-tcp "0.4.3"]
                  [fmap-clojure "LATEST" :exclusions [org.clojure/tools.logging]]
                  [fun-utils "0.5.0" :exclusions [org.clojure/tools.logging]]
                  [clj-tuple "0.1.7"]


Rename `=-and-same-type` -> `==-and-same-type` because that's what it is.

--- test/clojure_the_language/clojure_numerics_test.clj
+++ test/clojure_the_language/clojure_numerics_test.clj
@@ -209,17 +209,17 @@
 (fact (== 2 2N 2M 2.0M 2.0) => true) ; true even for inexact things

 ;;;; ___________________________________________________________________________
-;;;; ---- `=-and-same-type` ----
-
-(defn =-and-same-type
-  "Returns true iff (= x y) is true and x and y are of the same type."
+;;;; ---- `==-and-same-type` ----
+
+(defn ==-and-same-type
+  "Returns true iff x and y are of the same type and (== x y) is true."
   [x y]
   (and (= (type x) (type y))
        (== x y)))

-(fact (=-and-same-type 2 2)   => true)
-(fact (=-and-same-type 2 2N)  => false)
-(fact (=-and-same-type 2N 2N) => true)
+(fact (==-and-same-type 2 2)   => true)
+(fact (==-and-same-type 2 2N)  => false)
+(fact (==-and-same-type 2N 2N) => true)

 ;;;; ___________________________________________________________________________
 ;;;; ---- Going from longs/Longs to bigger or smaller ----
@@ -236,7 +236,7 @@
   (fact "...auto-promote"
     (inc' Long/MAX_VALUE) => max-long-plus-1)
   (fact "...only change the type if necessary"
-    (=-and-same-type (inc' 1) 2) => true)
+    (==-and-same-type (inc' 1) 2) => true)
   (fact "...do not demote"
     (type (dec' (inc' Long/MAX_VALUE)))
     => clojure.lang.BigInt))


CMR-183: Simplified context construction

--- test/cmr/search/test/services/acls/granule_acls.clj
+++ test/cmr/search/test/services/acls/granule_acls.clj
@@ -61,13 +61,11 @@
 (defn context-with-cached-collections
   "Creates a context with the specified collections in the collections cache"
   [collections]
-  (let [coll-cache (-> (cache/create-cache)
-                       (cache/update-cache
-                         #(assoc
-                            %
-                            :collections {:by-concept-id
-                                         (into {} (for [{:keys [concept-id] :as coll} collections]
-                                                    [concept-id coll]))})))]
+  (let [coll-cache (cache/create-cache
+                     :default
+                     {:collections {:by-concept-id
+                                    (into {} (for [{:keys [concept-id] :as coll} collections]
+                                               [concept-id coll]))}})]
     {:system
      {:caches
       {coll-cache/cache-key coll-cache}}}))


(PE-4373) Added tests for OID ownership

(PE-4373) Added tests for OID ownership

--- test/puppetlabs/certificate_authority/core_test.clj
+++ test/puppetlabs/certificate_authority/core_test.clj
@@ -471,4 +471,15 @@
                ["1.3.6.1.4.1.34380.1.1.3" "my_ami_image"]
                ["1.3.6.1.4.1.34380.1.1.4" "342thbjkt82094y0uthhor289jnqthpc2290"]
                ["2.16.840.1.113730.1.13" "Puppet Ruby/OpenSSL Internal Certificate"]]]
-        (is (= (get-extension-value extensions oid) value))))))+        (is (= (get-extension-value extensions oid) value)))))
+
+  (testing "Testing OID subtree status"
+    (is (subtree-of? (:parent puppet-labs-exts)
+                     (:node-uid puppet-labs-exts)))
+    (is (subtree-of? (:reg-cert-ext puppet-labs-exts)
+                     (:node-image-name puppet-labs-exts)))
+    (is (not (subtree-of? (:node-image-name puppet-labs-exts)
+                          (:reg-cert-ext puppet-labs-exts))))
+    (is (not (subtree-of? (:parent puppet-labs-exts)
+                          (:parent puppet-labs-exts))))
+    (is (not (subtree-of? "1.2.3.4" (:node-preshared-key puppet-labs-exts))))))


Set logging context on testutils atom appender

--- test/puppetlabs/trapperkeeper/testutils/logging.clj
+++ test/puppetlabs/trapperkeeper/testutils/logging.clj
@@ -56,20 +56,22 @@
              (swap! output-atom conj entry))))))))

 (defn atom-appender
-  "Creates a log4j appender that writes log messages to the supplied atom"
+  "Creates a logback appender that writes log messages to the supplied atom"
   ([output-atom] (atom-appender output-atom false))
   ([output-atom debug]
-   (proxy [AppenderBase] []
-     (append [logging-event]
-       (let [throwable-info  (.getThrowableInformation logging-event)
-             ex              (if throwable-info (.getThrowable throwable-info))
-             entry           [(.getLoggerName logging-event)
-                              (.getLevel logging-event)
-                              ex
-                              (str (.getMessage logging-event))]]
-         (when debug (log-to-console entry))
-         (swap! output-atom conj entry)))
-     (close []))))
+   (let [appender (proxy [AppenderBase] []
+                    (append [logging-event]
+                       (let [throwable-info (.getThrowableInformation logging-event)
+                             ex (if throwable-info (.getThrowable throwable-info))
+                             entry [(.getLoggerName logging-event)
+                                    (.getLevel logging-event)
+                                    ex
+                                    (str (.getMessage logging-event))]]
+                         (when debug (log-to-console entry))
+                         (swap! output-atom conj entry)))
+                     (close []))]
+     (.setContext appender (pl-log/logging-context))
+     appender)))

 (defmacro with-log-output-atom
   "This is a utility macro, intended for use by other macros such as


[PDOK-1584] always local time

[PDOK-1584] always local time

--- src/main/clojure/pdok/featured/json_reader.clj
+++ src/main/clojure/pdok/featured/json_reader.clj
@@ -32,10 +32,10 @@
 (def ^{:private true} date-formatter (tf/formatter "yyyy-MM-dd"))

 (defn- parse-time
-  "Parses an ISO8601 date timestring to local date"
+  "Parses an ISO8601 date timestring to local date time"
   [datetimestring]
   (when-not (clojure.string/blank? datetimestring)
-    (tf/parse date-time-formatter datetimestring)))
+    (tc/to-local-date-time (tf/parse date-time-formatter datetimestring))))

 (defn- parse-date
   "Parses a date string to local date"


Update to ClojureScript 0.0-3255

Update to ClojureScript 0.0-3255

--- Clojure/project.clj
+++ Clojure/project.clj
@@ -4,7 +4,7 @@
   :license {:name "Eclipse Public License"
             :url "http://www.eclipse.org/legal/epl-v10.html"}
   :dependencies [[org.clojure/clojure "1.7.0-beta2"]
-                 [org.clojure/clojurescript "0.0-3246"]
+                 [org.clojure/clojurescript "0.0-3255"]
                  [com.github.rickyclarkson/jmdns "3.4.2-r353-1"]]
   :source-paths ["src"]
   :main ambly.repl.jsc)


cleanup

cleanup

--- src/babel/francais/morphology/nouns.cljc
+++ src/babel/francais/morphology/nouns.cljc
@@ -22,49 +22,3 @@
                         :cat cat}
              :synsem {:agr agr
                       :cat cat}})))
-
-(def plural-to-singular-noun-fem-1
-  {#"e$"
-   {:replace-with "a"
-    :unify-with {:synsem {:cat :noun
-                          :agr {:gender :fem
-                                :number :plur}}}}})
-
-(def plural-to-singular-noun-masc-1
-  {#"i$"
-   {:replace-with "o"
-    :unify-with {:synsem {:cat :noun
-                          :agr {:number :plur}}}}})
-
-(def plural-to-singular-noun-masc-2 ;; e.g. "cani" -> "cane"
-  {#"i$"
-   {:replace-with "e"
-    :unify-with {:synsem {:cat :noun
-                          :agr {:number :plur}}}}})
-
-
-(def plural-to-singular-adj-masc
-  {#"i$"
-   {:replace-with "o"
-    :unify-with {:synsem {:cat :adjective
-                          :agr {:gender :masc
-                                :number :plur}}}}})
-
-(def plural-to-singular-adj-fem-sing
-  {#"a$"
-   {:replace-with "o"
-    :unify-with {:synsem {:cat :adjective
-                          :agr {:gender :fem
-                                :number :sing}}}}})
-
-(def plural-to-singular-adj-fem-plur
-  {#"e$"
-   {:replace-with "o"
-    :unify-with {:synsem {:cat :adjective
-                          :agr {:gender :fem
-                                :number :plur}}}}})
-
-(def lexical-noun-to-singular
-  {:identity
-   {:unify-with {:synsem {:cat :noun
-                          :agr {:number :sing}}}}})


finish imperfect regular verb analysis

finish imperfect regular verb analysis


return () instead of -LRB- -RBR- (original text)

--- src/clojure/zensols/nlparse/stanford.clj
+++ src/clojure/zensols/nlparse/stanford.clj
@@ -194,7 +194,10 @@

 (defn- sents- [anon] (get- anon edu.stanford.nlp.ling.CoreAnnotations$SentencesAnnotation))

-(defn- text- [anon] (get- anon edu.stanford.nlp.ling.CoreAnnotations$TextAnnotation))
+;(defn- text- [anon] (get- anon edu.stanford.nlp.ling.CoreAnnotations$TextAnnotation))
+(defn- text- [anon]
+  (or (get- anon edu.stanford.nlp.ling.CoreAnnotations$OriginalTextAnnotation)
+      (get- anon edu.stanford.nlp.ling.CoreAnnotations$TextAnnotation)))

 (defn- pos-tag- [anon] (get- anon edu.stanford.nlp.ling.CoreAnnotations$PartOfSpeechAnnotation))


Only sort subscriptions by sub key, not whole sub vector

Fixes #119

--- src/day8/re_frame/trace/panels/subs.cljs
+++ src/day8/re_frame/trace/panels/subs.cljs
@@ -22,7 +22,7 @@
     [:div.subtrees {:style {:margin "20px 0"}}
      (doall
        (->> @subs/query->reaction
-            (sort)
+            (sort-by (fn [me] (ffirst (key me))))
             (map (fn [me]
                    (let [[query-v dyn-v :as inputs] (key me)]
                      ^{:key query-v}


Update timing panel to match mockup

Update timing panel to match mockup

--- src/day8/re_frame/trace/view/timing.cljs
+++ src/day8/re_frame/trace/view/timing.cljs
@@ -28,7 +28,7 @@
      :width            "63px"}]

    [".timing-elapsed-panel"
-    {:padding "12px"
+    {:padding "12px 12px 12px 0"
      :margin  common/gs-7s}]
    [".timing-part-panel"
     (merge (common/panel-style "3px")


Doc strings for all files in job-data-fetcher.clj module

--- src/emender_jenkins/job_data_fetcher.clj
+++ src/emender_jenkins/job_data_fetcher.clj
@@ -10,7 +10,8 @@
 ;      Pavel Tisnovsky
 ;

-(ns emender-jenkins.job-data-fetcher)
+(ns emender-jenkins.job-data-fetcher
+     "Module that contains the job fetching machinery that should be run in a separate thread.")

 (require '[emender-jenkins.results :as results])

@@ -19,34 +20,39 @@
 (def last-duration (atom nil))

 (defn minutes-to-seconds
-    "Converts minutes to seconds."
+    "Convert minutes to seconds."
     [minutes]
     (* minutes 60))

 (defn seconds-to-ms
-    "Converts seconds to milliseconds."
+    "Convert seconds to milliseconds."
     [seconds]
     (* seconds 1000))

 (defn compute-sleep-amount
+    "Convert sleep amount specified in minutes into millisesonds."
     [minutes]
     (-> minutes
         minutes-to-seconds
         seconds-to-ms))

 (defn fetch-data
-    "Dynamically creates file containing EDN data about books."
+    "Read job statuses and job results. Stores them in the data structure in result module."
     [configuration]
     (results/reload-all-results configuration))

 (defn try-to-fetch-data
+    "Fetch job statuses etc. from Jenkins."
     [configuration]
     (try
         (fetch-data configuration)
         (catch Exception e
             (println "*** Exception in fetcher:" (.getMessage e)))))

+;TODO put it into the proper module."
+
 (defn get-formatted-time
+    "Returns formatted time."
     [ms]
     (let [sdf         (new java.text.SimpleDateFormat "yyyy-MM-dd HH:mm:ss")
           result-date (new java.util.Date ms)]
@@ -78,6 +84,8 @@
         (run-fetcher-in-a-loop (-> configuration :fetcher :delay) configuration)))

 (defn run-fetcher-in-thread
+    "Run the fetcher (its loop) in a separate thread."
     [configuration]
+    ; he have to use lambda here because we need to pass parameter into the run-fetcher function
     (.start (Thread. #(run-fetcher configuration))))


factor out common stuff from jdbc into test-util

--- src/main/clj/org/bituf/fountain/jdbc.clj
+++ src/main/clj/org/bituf/fountain/jdbc.clj
@@ -19,36 +19,54 @@

 (defn make-sjtspec
   "Return a map with the following key associated to its respective value:
-    :org.bituf.fountain.jdbc.sjt - SimpleJdbcTemplate
+    :fountain.jdbc.sjt - SimpleJdbcTemplate
   See also:
     with-context
     clj-dbspec/*dbspec*"
   [& {:keys [^DataSource datasource]
-      :or   {datasource  nil}}]
+      :or   {datasource  nil}
+      :as opt}]
+  {:post [(mu/verify-cond (map? %))]
+   :pre  [(mu/verify-opt #{:datasource} opt)]}
   (let [ds  (or datasource (:datasource sp/*dbspec*)
               (mu/illegal-arg "No valid DataSource found/supplied"))
         sjt ^SimpleJdbcTemplate (SimpleJdbcTemplate. ^DataSource ds)]
      {:fountain.jdbc.sjt sjt}))

+(defn assoc-sjt
+  "Associate SimpleJdbcTemplate instance with the DB-Spec."
+  ([spec sjtspec] {:post [(mu/verify-cond (map? %))]
+                   :pre  [(mu/verify-arg (map? spec))
+                          (mu/verify-arg (map? sjtspec))
+                          (mu/verify-arg (contains? sjtspec :fountain.jdbc.sjt))]}
+    (sp/assoc-kvmap spec sjtspec))
+  ([spec] {:post [(mu/verify-cond (map? %))]
+           :pre  [(mu/verify-arg (map? spec))
+                  (mu/verify-arg (contains? spec :datasource))
+                  (mu/verify-arg (instance? DataSource (:datasource spec)))]}
+    (sp/assoc-kvmap spec (sp/with-dbspec spec
+                           (make-sjtspec)))))
+
+
 (defn wrap-sjt
   "Create SimpleJdbcTemplate instance and putting into clj-dbspec/*dbspec* as a
   key execute f."
-  [f] {:post [(fn? %)]
-       :pre  [(fn? f)]}
+  [f] {:post [(mu/verify-cond (fn? %))]
+       :pre  [(mu/verify-arg (fn? f))]}
   (fn [& args]
     (let [wf (sp/wrap-dbspec (make-sjtspec)
                f)]
       (apply wf args))))

-(defn- ^SimpleJdbcTemplate get-sjt
+(defn ^SimpleJdbcTemplate get-sjt
   "Get SimpleJdbcTemplate from context"
   ([context] (:fountain.jdbc.sjt context))
   ([] (get-sjt sp/*dbspec*)))

-(defn- ^SimpleJdbcInsert get-sji
+(defn ^SimpleJdbcInsert get-sji
   "Get SimpleJdbcInsert from context"
   ([context] (:fountain.jdbc.sji context))
   ([] (get-sji sp/*dbspec*)))
@@ -131,6 +149,7 @@
 (defn update
   "Execute update-query and return integer result (number of rows affected)."
   ([^String sql args]
+    (sp/verify-writable)
     (with-query-args [qargs args]
       (show-sql sql)
       (.update (get-sjt) sql qargs)))
@@ -144,6 +163,7 @@
   2. or a list of named param-value maps
   Return a lazy list of integers, each being the number of rows affected."
   [^String sql batch-args]
+  (sp/verify-writable)
   (let [args1        (first batch-args)
         is-map       (map? args1)
         is-seq       (or (coll? args1) (mu/array? args1))
@@ -220,6 +240,7 @@
   suitable if you want to retrieve generated column keys.
   See also: insert-give-id, insert-give-idmap"
   [^SimpleJdbcInsert sji row]
+  (sp/verify-writable)
   ;; sji.withTableName("tableName")
   ;; .execute(/* Map<String, Object> */ row); // int
   (try
@@ -231,6 +252,7 @@
 (defn insert-give-id
   "Insert row and return generated ID."
   [^SimpleJdbcInsert sji row]
+  (sp/verify-writable)
   ;; sji.withTableName("tableName")
   ;; .executeAndReturnKey(/* Map<String, Object> */ row); // Number
   (try
@@ -242,6 +264,7 @@
 (defn insert-give-idmap
   "Insert row and return generated ID map (for multiple columns)."
   [^SimpleJdbcInsert sji row]
+  (sp/verify-writable)
   ;; sji.withTableName("tableName")
   ;; .executeAndReturnKeyHolder(/* Map<String, Object> */ row)
   ;; .getKeys(); // Map<String, Object>
@@ -257,6 +280,7 @@
   "Insert rows in a batch and return a lazy list containing number of affected
   rows per insertion."
   [^SimpleJdbcInsert sji batch-rows]
+  (sp/verify-writable)
   ;; sji.withTableName("tableName")
   ;; .executeBatch(/* Map<String, Object>[] */ batchRows); // int[]
   (try


change home page to index page

change home page to index page

--- src/bookmarks/core.clj
+++ src/bookmarks/core.clj
@@ -6,12 +6,19 @@
    [ring.middleware.json :as ring-json]
    [ring.util.response	:as rr]
    [ring.middleware.defaults :refer [wrap-defaults site-defaults]]
-   [bookmarks.db.core :as db])
+   [compojure.response :refer [render]]
+   [clojure.java.io :as io])
   (:gen-class))

+(defn home
+  ""
+  [req]
+  (render (io/resource "index.html") req))
+
+
 (defroutes app-routes
-  (GET "/" [] "welcome to home page")
+  (GET "/" [] home)
   (route/resources "/static")
   (route/not-found "
Page not found
"))


Re-order search terms for users-subscribed-to-thread; much faster

Takes searching (which calls user-can-see-thread?, which calls this on
each) from 5.5 seconds to 38 milliseconds

--- src/braid/core/server/db/thread.clj
+++ src/braid/core/server/db/thread.clj
@@ -55,9 +55,9 @@
   (d/q '[:find [?user-id ...]
          :in $ ?thread-id
          :where
-         [?user :user/id ?user-id]
+         [?thread :thread/id ?thread-id]
          [?user :user/subscribed-thread ?thread]
-         [?thread :thread/id ?thread-id]]
+         [?user :user/id ?user-id]]
        (db/db)
        thread-id))


Fixed typo - template directory is '.cake' not 'cake'

--- src/cake/tasks/new.clj
+++ src/cake/tasks/new.clj
@@ -32,7 +32,7 @@
     (if (.exists root)
       (println "error:" project "already exists in this directory")
       (do
-        (log (str "Creating a new project based on ~/cake/templates/" template))
+        (log (str "Creating a new project based on ~/.cake/templates/" template))
         (ant Copy {:todir root} (add-fileset {:dir (str (file template-dir template))}))
         (rename-files root project)
         (scan-replace-contents (file-seq root) project)))))


Processing t1 expand/collapse UI events for now.

--- src/cbfg/world/t1.cljs
+++ src/cbfg/world/t1.cljs
@@ -174,6 +174,7 @@
                                      :sleep (js/parseInt (get-el-value "sleep"))})
                            (merge (map #(listen-el (gdom/getElement %) "click")
                                        (keys cbfg.world.lane/cmd-handlers))))
+              expand-ch (listen-el (gdom/getElement (str el-prefix "-html")) "click")
               prog (get-el-value "prog")
               prog-js (str "with (cbfg.world.t1) {" prog "}")
               prog-res (try (js/eval prog-js) (catch js/Object ex ex))]
@@ -187,7 +188,16 @@
                         (aput cmd-dispatch-loop client-req-ch msg))
                       (recur (inc num-dispatches))))
           (println :prog-res prog-res)
+          (go-loop [] ; Process expand/collapse UI events.
+            (let [actx-id (cbfg.vis/no-prefix (.-id (.-target (<! expand-ch))))]
+              (doseq [[actx actx-info] (:actxs @vis)]
+                (when (= actx-id (last actx))
+                  (swap! vis #(assoc-in % [:actxs actx :collapsed]
+                                        (not (:collapsed actx-info))))
+                  (>! delayed-event-ch [@vis nil true nil])))
+              (recur)))
           (<! prog-ch)
+          (close! expand-ch)
           (close! cmd-ch)
           (close! req-ch)
           (close! event-ch)


Add morpheus to dev script includes

Add morpheus to dev script includes

--- src/clj/clojuredocs/site/common.clj
+++ src/clj/clojuredocs/site/common.clj
@@ -93,6 +93,8 @@
       [:script
        "!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');"]]]
     (when (env/bool :cljs-dev)
+      [:script {:src "/js/morpheus.min.js"}])
+    (when (env/bool :cljs-dev)
       [:script {:src "http://fb.me/react-0.9.0.js"}])
     (when (env/bool :cljs-dev)
       [:script {:type "text/javascript" :src "/cljs/goog/base.js"}])


fix ref

fix ref

--- src/clj/just_married/api/labels.clj
+++ src/clj/just_married/api/labels.clj
@@ -92,7 +92,7 @@
 (defn labels-api
   [request]
   (with-basic-auth request
-    (let [labels-data     (db/labels!)
+    (let [labels-data     (get-labels!)
           labels-pdf-file (labels labels-data)]

       (-> (resp/file-response labels-pdf-file)


remove unneeded contract assertion

remove unneeded contract assertion

--- src/cljs/ohds/login/processing.cljs
+++ src/cljs/ohds/login/processing.cljs
@@ -13,9 +13,6 @@
   m/ChangeUsername
   (process-message
       [response app]
-    {:pre [(map? response)]
-     :post [(= (:username response)
-               (:username (:user app)))]}
     (assoc-state response app :user))

   m/ChangePassword


Add docstrings to codegen namespace.

Add docstrings to codegen namespace.

--- src/clojure/wintergreen/codegen.clj
+++ src/clojure/wintergreen/codegen.clj
@@ -1,77 +1,110 @@
 (ns wintergreen.codegen)

-(def indent-level (atom 0))
-(defn indent []  (swap! indent-level inc))
-(defn outdent [] (swap! indent-level #(max 0 (dec %))))
+(def indent-level "Current source-code indentation level." (atom 0))

-(defn print-indented-line [s]
+(defn indent "Increment current indentation level." []
+  (swap! indent-level inc))
+
+(defn outdent "Decrement current indentation level." []
+  (swap! indent-level #(max 0 (dec %))))
+
+(defn print-indented-line
+  "Print a string indented to the level defined in the var indent-level."
+  [s]
   (println (apply str (concat (repeat @indent-level "  ") s))))

-(defn print-statement [s]
+(defn print-statement
+  "Print a string indented to current indent-level with trailing semicolon."
+  [s]
   (if (not (empty? s)) (print-indented-line (str s ";"))))

 (declare to-js)

-(defn program-to-js [program]
-  (doseq [statement program]
-    (let [expr (to-js statement)]
-      (if expr
-        (println (str expr ";"))))))
+(defn write-program-js
+  "Top-level driver to write a program tree as JavaScript source
+  code. Writes code to *out*."
+  [program]
+  (binding [indent-level (atom 0)]
+    (doseq [statement program]
+      (let [expr (to-js statement)]
+        (if expr
+          (println (str expr ";")))))))

-(defn program-to-js-string [program]
+(defn program-to-js
+  "Converts a program tree to JavaScript source code, returned as a string."
+  [program]
   (binding [*out* (new java.io.StringWriter)]
-    (program-to-js program)
+    (write-program-js program)
     (.toString *out*)))

-(defmulti to-js (fn [x] (if (list? x) (first x) 'scalar)))
+(defmulti write-js
+  "Converts a program node to JavaScript source code. May return a
+  string or nil.

-(defmethod to-js 'proc [nodes]
+  In general, statement blocks are responsible for printing their code
+  to *out*, properly separating statements with semicolons and
+  newlines. Other tree nodes will return strings."
+  (fn [x] (if (list? x) (first x) 'scalar)))
+
+; Procedure.
+(defmethod write-js 'proc [nodes]
   (let [[_ name args & statements] nodes]
     (print-indented-line (format "var %s = function(%s) {"
                                  name
-                                 (apply str (interpose ", " (map to-js args)))))
+                                 (apply str (interpose ", " (map write-js args)))))
     (indent)
-    (dorun (map (comp print-statement to-js) statements))
+    (dorun (map (comp print-statement write-js) statements))
     (outdent)
     (print-indented-line "}")))

-(defmethod to-js 'arg [nodes] (str (nth nodes 2)))
+; Procedure argument.
+(defmethod write-js 'arg [nodes] (str (nth nodes 2)))

-(defmethod to-js 'return [nodes] (format "return %s" (to-js (second nodes))))
+; Return statement.
+(defmethod write-js 'return [nodes] (format "return %s" (write-js (second nodes))))

-(defmethod to-js 'call [nodes]
+; Procedure call.
+(defmethod write-js 'call [nodes]
   (let [[_ name & args] nodes]
-    (format "%s(%s)" name (apply str (interpose ", " (map to-js args))))))
+    (format "%s(%s)" name (apply str (interpose ", " (map write-js args))))))

-(defmethod to-js 'while [nodes]
+; While-loop.
+(defmethod write-js 'while [nodes]
   (let [[_ predicate & statements] nodes]
-    (print-indented-line (format "while (%s) {" (to-js predicate)))
+    (print-indented-line (format "while (%s) {" (write-js predicate)))
     (indent)
-    (dorun (map (comp print-statement to-js) statements))
+    (dorun (map (comp print-statement write-js) statements))
     (outdent)
     (print-indented-line "}")))

-(defmethod to-js 'decl [nodes]
+; Variable declaration.
+(defmethod write-js 'decl [nodes]
   (let [[_ type name & value] nodes]
     (if (empty? value)
       (format "var %s" name)
-      (format "var %s = %s" name (to-js (first value))))))
+      (format "var %s = %s" name (write-js (first value))))))

-(defmethod to-js 'assign [nodes]
+; Variable assignment.
+(defmethod write-js 'assign [nodes]
   (let [[_ varname value] nodes]
-    (format "%s = %s" varname (to-js value))))
+    (format "%s = %s" varname (write-js value))))

-(defmethod to-js 'binop [nodes]
+; Binary operation.
+(defmethod write-js 'binop [nodes]
   (let [[_ op a b] nodes]
-    (format "(%s %s %s)" (to-js a) op (to-js b))))
+    (format "(%s %s %s)" (write-js a) op (write-js b))))

-(defmethod to-js 'var [nodes] (str (second nodes)))
+; Variable.
+(defmethod write-js
+  'var [nodes] (str (second nodes)))

-(defmethod to-js 'scalar [s]
+; Single-value literal. May be a number or string.
+(defmethod write-js 'scalar [s]
   (if (string? s)
     (str "\"" s "\"")
     (str s)))

-(defmethod to-js 'putTestValue [nodes]
+; Built-in function to provide a test result value to the testing framework.
+(defmethod write-js 'putTestValue [nodes]
   (let [[_ name value] nodes]
-    (format "testValues.put(%s, %s)" (to-js name) (to-js value))))
+    (format "testValues.put(%s, %s)" (write-js name) (write-js value))))


Remove deprecated file

Remove deprecated file

--- src/clojure_fabric/hf_ca_client.clj
+++ src/clojure_fabric/hf_ca_client.clj
@@ -1,105 +0,0 @@
-(ns clojure-fabric.hf-ca-client
-  (:import [org.hyperledger.fabric_ca.sdk HFCAClient]))
-
-(defn
- get-crypto-suite
- [^org.hyperledger.fabric_ca.sdk.HFCAClient hfca-client]
- (. hfca-client getCryptoSuite))
-
-
-(defn
- enroll
- ([^org.hyperledger.fabric_ca.sdk.HFCAClient
-   hfca-client
-   ^java.lang.String
-   string0
-   ^java.lang.String
-   string1]
-  (. hfca-client enroll string0 string1))
- ([^org.hyperledger.fabric_ca.sdk.HFCAClient
-   hfca-client
-   ^java.lang.String
-   string0
-   ^java.lang.String
-   string1
-   ^org.hyperledger.fabric_ca.sdk.EnrollmentRequest
-   enrollment-request2]
-  (. hfca-client enroll string0 string1 enrollment-request2)))
-
-
-(defn
- create-new-instance
- ([^java.lang.String string0 ^java.util.Properties properties1]
-  (org.hyperledger.fabric_ca.sdk.HFCAClient/createNewInstance
-   string0
-   properties1))
- ([^java.lang.String
-   string0
-   ^java.lang.String
-   string1
-   ^java.util.Properties
-   properties2]
-  (org.hyperledger.fabric_ca.sdk.HFCAClient/createNewInstance
-   string0
-   string1
-   properties2)))
-
-
-(defn
- revoke
- [^org.hyperledger.fabric_ca.sdk.HFCAClient
-  hfca-client
-  ^org.hyperledger.fabric.sdk.User
-  user0
-  generic-arg1
-  ^java.lang.String
-  string2]
- (clojure.core/cond
-  (instance? java.lang.String generic-arg1)
-  (. hfca-client revoke user0 ^java.lang.String generic-arg1 string2)
-  (instance? org.hyperledger.fabric.sdk.Enrollment generic-arg1)
-  (.
-   hfca-client
-   revoke
-   user0
-   ^org.hyperledger.fabric.sdk.Enrollment
-   generic-arg1
-   string2)))
-
-
-(defn
- register
- [^org.hyperledger.fabric_ca.sdk.HFCAClient
-  hfca-client
-  ^org.hyperledger.fabric_ca.sdk.RegistrationRequest
-  registration-request0
-  ^org.hyperledger.fabric.sdk.User
-  user1]
- (. hfca-client register registration-request0 user1))
-
-
-(defn
- reenroll
- ([^org.hyperledger.fabric_ca.sdk.HFCAClient
-   hfca-client
-   ^org.hyperledger.fabric.sdk.User
-   user0]
-  (. hfca-client reenroll user0))
- ([^org.hyperledger.fabric_ca.sdk.HFCAClient
-   hfca-client
-   ^org.hyperledger.fabric.sdk.User
-   user0
-   ^org.hyperledger.fabric_ca.sdk.EnrollmentRequest
-   enrollment-request1]
-  (. hfca-client reenroll user0 enrollment-request1)))
-
-
-(defn
- set-crypto-suite
- [^org.hyperledger.fabric_ca.sdk.HFCAClient
-  hfca-client
-  ^org.hyperledger.fabric.sdk.security.CryptoSuite
-  crypto-suite0]
- (. hfca-client setCryptoSuite crypto-suite0))
-
-


add db fn for updating config

add db fn for updating config

--- src/chat/server/db.clj
+++ src/chat/server/db.clj
@@ -652,6 +652,11 @@
                       [:db/add [:extension/id extension-id]
                        :extension/refresh-token refresh-token]]))

+(defn update-extension-config
+  [extension-id config]
+  (d/transact *conn* [[:db/add [:extension/id extension-id]
+                       :extension/config (pr-str config)]]))
+
 (defn group-extensions
   [group-id]
   (->> (d/pull (d/db *conn*) [{:extension/_group extension-pull-pattern}]


CMR-981: Added a test.

CMR-981: Added a test.


Cleanup CQP results

Cleanup CQP results

--- src/cljs/cglossa/search_inputs/cwb/shared.cljs
+++ src/cljs/cglossa/search_inputs/cwb/shared.cljs
@@ -3,6 +3,19 @@
   (:require [clojure.string :as str]
             [cljs-http.client :as http]
             [cljs.core.async :refer [<!]]))
+
+(defn- cleanup-result [result]
+  (-> result
+      ;; Remove the beginning of the search result, which will be a position number in the
+      ;; case of a monolingual result or the first language of a multilingual result, or
+      ;; an arrow in the case of subsequent languages in a multilingual result.
+      (str/replace #"^\s*\d+:\s*" "")
+      (str/replace #"^-->.+?:\s*" "")
+      ;; When the match includes the first or last token of the s unit, the XML tag surrounding
+      ;; the s unit is included inside the match braces (this should probably be considered a bug
+      ;; in CQP). We need to fix that.
+      (str/replace #"\{\{(<s_id\s+.+?>)" "$1{{")
+      (str/replace #"(</s_id>)\}\}" "}}$1")))

 (defn- search! [queries corpus]
   (let [queries*    @queries
@@ -24,7 +37,7 @@
                                                 :queries   q}}))]
               (if success
                 (let [results (get-in response [:body :results])]
-                  (.log js/console (str results)))
+                  (.log js/console (str (map cleanup-result results))))
                 (.log js/console status))))))))

 (defn on-key-down [event wrapped-query corpus]


Add an ability to run async queries

Add an ability to run async queries

--- src/clojure/clojurewerkz/cassaforte/client.clj
+++ src/clojure/clojurewerkz/cassaforte/client.clj
@@ -193,6 +193,14 @@
              hayt/*param-stack*        (atom [])]
      (do ~body)))

+(def ^:dynamic *async* false)
+
+(defmacro async
+  "Prepare a single statement, return prepared statement"
+  [body]
+  `(binding [*async* true]
+     (do ~body)))
+
 (defmacro with-fetch-size
   "Temporarily alters fetch size."
   [^Integer n# & body]
@@ -223,20 +231,6 @@
   [^PreparedStatement statement values]
   (.bind statement (to-array values)))

-(defn ^ResultSetFuture execute-async
-  "Executes a pre-built query and returns a future.
-
-   Options
-     * prepared - whether the query should or should not be executed as prepared, always passed
-       explicitly, because `execute` is considered to be a low-level function."
-  ([^Session session query]
-     (execute-async session query {}))
-  ([^Session session query {:keys [prepared]}]
-     (comment
-       (let [^Statement statement (statement-for session query prepared)
-             ^ResultSetFuture fut (.executeAsync session statement)]
-         (future (conv/to-clj (.getUninterruptibly fut)))))))
-
 (defprotocol BuildStatement
   (build-statement [query]))

@@ -258,10 +252,21 @@
   (if hayt/*prepared-statement*
     (let [^String q (hayt/->raw query)]
       (.prepare session q))
-
     (let [^Statement built-statement (build-statement query)]
-      (-> (.execute session built-statement)
-          (conv/to-clj)))))
+      (if *async*
+        (let [async-result (.executeAsync session built-statement)]
+          (proxy [clojure.lang.IDeref
+                  clojure.lang.IBlockingDeref] []
+            (deref
+              ([]
+                 (conv/to-clj @async-result))
+              ([time-period time-unit]
+                 (conv/to-clj (deref async-result time-period time-unit))))
+            ))
+
+        (-> (.execute session built-statement)
+            (conv/to-clj))
+        ))))

 (defn ^String export-schema
   "Exports the schema as a string"


Cleanup scale.

Cleanup scale.

--- src/cljx/c2/scale.cljx
+++ src/cljx/c2/scale.cljx
@@ -31,8 +31,8 @@
         IInvertable
         (invert [this]
                 (assoc this
-                  :domain (:range this)
-                  :range (:domain this))))
+                  :domain range
+                  :range domain)))

 (declare log)


more threading in clojure

more threading in clojure

--- Clojure/cp/src/cp/threads.clj
+++ Clojure/cp/src/cp/threads.clj
@@ -231,31 +231,32 @@

 (comment
 	REFS:
-
-	)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+		synchronous, coordinated, STM
+		atomic, consistent, isolated.
+	)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+


save repo

save repo

--- cloc-webapp/src-cljs/dash/dash.cljs
+++ cloc-webapp/src-cljs/dash/dash.cljs
@@ -40,7 +40,7 @@
     (go (let [resp (<! (http/post register-repo-url {:oauth-token auth-token
                                                      :json-params {}}))]
            (if (= 200 (:status resp))
-             (let [registered-repo (:body resp)]
+             (let [registered-repo (:body resp)]
                (swap! app-state (fn [state] (assoc-in state [:repos current-index :registered] registered-repo)))
                (om/update! (registered-state-cur current-index) [0] :registered))

@@ -53,7 +53,18 @@
            (when (= 200 (:status resp))
               (swap! app-state (fn [state] (update-in state [:repos current-index] dissoc :registered)))
               (om/update! (registered-state-cur current-index) [0] :unregistered))))))
-
+
+(defn- save-repo [current-index auth-token repo-name body]
+  "save display language"
+  (let [save-repo-url (str/format "/api/user/%s/display_lang" repo-name)]
+    (go (let [resp (<! (http/patch save-repo-url {:oauth-token auth-token
+                                                  :json-params {:display_lang body}}))]
+           (when (= 200 (:status resp))
+              (swap! app-state (fn [state]
+                                 (if-let [registered (get-in [:repos current-index :registered] state)]
+                                   (assoc-in state [:repos current-index :registered] (assoc registered :lang body))
+                                   state))))))))
+
 ;; {:auth - :repo -}
 (defn repo-config-panel [state owner]
   (reify
@@ -65,10 +76,14 @@
         (case current-state
           :registered (dom/div nil
                         (dom/h2 nil (get current-repo "full_name"))
+                        (dom/input #js {:type "text" :ref "display-lang" :value (:lang current-repo)})
                         (dom/button
                           #js {:onClick #(when (= current-state :registered)
                                             (unregister-repo index (:auth state) (get current-repo "name")))}
-                          "unregister this repo"))
+                          "unregister this repo")
+                        (dom/button
+                          #js {:onClick #(save-repo index (:auth state) (get current-repo "name") (.-value (om/get-node owner "display-lang")))}
+                          "Save"))
           :registering (dom/h2
                           nil
                           "registering...")


onto anonymous functions in clojure

onto anonymous functions in clojure


re-added refine-action

re-added refine-action

--- src/crawler/corpus.clj
+++ src/crawler/corpus.clj
@@ -88,6 +88,37 @@
      (json/generate-stream
       (read-corpus-file a-corpus-file)
       wrtr)))
+
+(defn refine-action
+  "Args:
+    src-page: The body of the source web-page
+    dest-pages: A set of destination pages from the src-page at
+                the specified action (plz don't supply more)
+    action: The actiont taken (not the SRC-action!!!!)
+    dest-page-test: A routine that accepts the source page
+                    [url info] and the dest page [url info] data
+                    structures
+
+  Returns:
+    An {:only :avoid} data structure to augment the XPath"
+  [src-data dest-datas action src-url dest-page-test]
+  (let [muscle (map
+                first
+                (filter
+                 #(dest-page-test src-data %)
+                 dest-datas))
+
+        fat (map
+             first
+             (filter
+              #(not
+                (dest-page-test src-data %))
+              dest-datas))]
+    (dom/refine-xpath-accuracy action
+                               (-> src-data second :body)
+                               src-url
+                               muscle
+                               fat)))

 (defn detect-pagination
   "Employs the simpler digit-based algorithm.


:bug: Use canvas background in viewer

:bug: Use canvas background in viewer

--- frontend/src/uxbox/view/ui/viewer/canvas.cljs
+++ frontend/src/uxbox/view/ui/viewer/canvas.cljs
@@ -12,12 +12,13 @@
 ;; --- Background (Component)

 (mx/defc background
-  []
+  {:mixins [mx/static]}
+  [{:keys [background] :as metadata}]
   [:rect
    {:x 0 :y 0
     :width "100%"
     :height "100%"
-    :fill "white"}])
+    :fill (or background "#ffffff")}])

 ;; --- Canvas (Component)

@@ -25,12 +26,12 @@

 (mx/defc canvas
   {:mixins [mx/static]}
-  [{:keys [metadata] :as page}]
+  [{:keys [metadata id] :as page}]
   (let [{:keys [width height]} metadata]
-    [:div.view-canvas
+    [:div.view-canvas {:ref (str "canvas" id)}
      [:svg.page-layout {:width width
                         :height height}
-      (background)
+      (background metadata)
       (for [id (reverse (:shapes page))]
         (-> (shapes/shape id)
             (mx/with-key (str id))))]]))


Make assertions invokable as functions

Make assertions invokable as functions

--- src/main/clojure/com/stuartsierra/lazytest.clj
+++ src/main/clojure/com/stuartsierra/lazytest.clj
@@ -108,6 +108,8 @@
 ;;; Assertion types

 (deftype SimpleAssertion [pred] :as this
+  clojure.lang.IFn
+    (invoke [] (invoke-test this {}))
   TestInvokable
     (invoke-test [active]
       (try
@@ -118,6 +120,8 @@
           (TestThrown this nil t)))))

 (deftype ContextualAssertion [contexts pred] :as this
+  clojure.lang.IFn
+    (invoke [] (invoke-test this {}))
   TestInvokable
     (invoke-test [active]
       (let [merged (reduce open-context active contexts)


Reversed pmap in reader - doesn't seem to work.

--- src/depends/reader.clj
+++ src/depends/reader.clj
@@ -336,7 +336,7 @@
     (if (.isDirectory tfile-or-directory)
       (let [listing             (file-seq tfile-or-directory)  ; Note: this handles recursion into sub-archives / sub-sub-archives etc. for us
             class-files         (filter #(and (.canRead %) (.isFile %) (.endsWith (.getName %) ".class")) listing)
-            class-files-info    (pmap #(class-info % (.getPath %)) class-files)  ; pmap for embiggen of preformance
+            class-files-info    (map #(class-info % (.getPath %)) class-files)
             merged-info         (vec (map first class-files-info))
             merged-dependencies (reduce set/union (map second class-files-info))]
         [merged-info merged-dependencies])


Set color on each level

Set color on each level

--- src/devtools/core.cljs
+++ src/devtools/core.cljs
@@ -63,7 +63,7 @@

 ; TODO: convert to idiomatic clojure code
 (defn header-collection-template [value]
-  (let [arr (template "span" "" "[")]
+  (let [arr (template "span" "color:#000" "[")]
     (doseq [x (take MAX_COLLECTION_ELEMENTS value)]
       (.push arr (inlined-value-template x) (spacer x)))
     (.pop arr)
@@ -73,7 +73,7 @@
     arr))

 (defn header-map-template [value]
-  (let [arr (template "span" "" "{")
+  (let [arr (template "span" "color:#000" "{")
         v (seq value)]
     (doseq [[k v] (take MAX_MAP_ELEMENTS v)]
       (.push arr
@@ -86,7 +86,7 @@
     arr))

 (defn header-set-template [value]
-  (let [arr (template "span" "" "#{")]
+  (let [arr (template "span" "color:#000" "#{")]
     (doseq [x (take MAX_SET_ELEMENTS value)]
       (.push arr (inlined-value-template x) (spacer x)))
     (.pop arr)
@@ -96,7 +96,7 @@
     arr))

 (defn generic-template [value]
-  (template "span" "" ">" (reference value) "<"))
+  (template "span" "color:#000" (reference value)))

 (defn atomic-template [value]
   (cond


Add missing test case for s/coll-of on sets


Clean up issues with echo test (WIP)

Clean up issues with echo test (WIP)

The child portion still times out, but the rest of it passes.

--- test/frereth_cp/message/message_test.clj
+++ test/frereth_cp/message/message_test.clj
@@ -154,7 +154,7 @@
                                                            "Echo sent. Pretending other child triggers done")
                                            ;; This seems like a good time for the parent
                                            ;; to send EOF
-                                           {:keys [::specs/to-child]
+                                           {:keys [::specs/from-parent-trigger]
                                             :as io-handle} @io-handle-atom]
                                        ;; This part of the circular dependency
                                        ;; is absolutely not realistic.
@@ -163,7 +163,7 @@
                                        ;; It only makes sense in this test because
                                        ;; I'm totally mocking out any sort of real
                                        ;; interaction.
-                                       (.close to-child)
+                                       (strm/close! from-parent-trigger)
                                        (deliver response buf)
                                        logs)
                                      logs)]
@@ -175,7 +175,8 @@
             ;; logs parameter.
             ;; The bigger-picture problem is that the problem wasn't
             ;; immediately obvious
-            child-cb (fn [#_logs array-o-bytes]
+            ;; FIXME: Start back with the caller to fix that.
+            child-cb (fn [logs array-o-bytes]
                        (println "Top of child-cb")
                        ;; TODO: Add another similar test that throws an
                        ;; exception here, for the sake of hardening the
@@ -183,7 +184,8 @@
                        (let [logs (log2/info logs
                                              ::echo-child-cb
                                              "Incoming to child"
-                                             {::rcvd array-o-bytes})]
+                                             {::rcvd array-o-bytes
+                                              ::type (class array-o-bytes)})]
                          (is array-o-bytes "Falsey reached callback")
                          (println "Checked for truthy incoming")
                          (try
@@ -229,17 +231,17 @@
                                                                                ::echo-child-cb
                                                                                "Sent EOF after the message block")]
                                                         (log2/flush-logs! logger inner-logs))))
-                                                  logs)
-                                                (log2/warn logs :echo-child-cb "Empty incoming message. Highly suspicious"))]
-                                     (let [{:keys [::specs/from-child]
+                                                  logs))]
+                                     (log2/warn logs :echo-child-cb "Empty incoming message. Highly suspicious"))
+                                   (let [{:keys [::specs/from-child]
                                             :as io-handle} @io-handle-atom
                                            logs (log2/warn logs
                                                            ::echo-child-cb
-                                                           "Child received EOF. Mark done.")]
+                                                           "Child received what should be EOF. Mark done.")]
                                        (message/child-close! io-handle)
                                        (is (s/valid? ::specs/eof-flag array-o-bytes))
                                        (deliver child-finished array-o-bytes)
-                                       logs)))]
+                                       logs))]
                              (log2/flush-logs! logger logs))
                            (catch Exception ex
                              (println "child-cb Failed:" ex)


(TK-3) Make cond statements more readable

Make cond statements in the core implementation of the init and
start lifecycle functions to be more explicit about the code
path, thus making it more readable.

--- src/puppetlabs/trapperkeeper/services/webserver/jetty9_core.clj
+++ src/puppetlabs/trapperkeeper/services/webserver/jetty9_core.clj
@@ -609,18 +609,20 @@

 (schema/defn ^:always-validate init!
   [context config :- config/WebserverServiceRawConfig]
-  (let [old-config? (nil? (schema/check config/WebserverRawConfig config))]
+  (let [old-config (schema/check config/WebserverRawConfig config)
+        new-config (schema/check config/MultiWebserverRawConfig config)]
     (cond
-          old-config? (assoc context :jetty9-servers {:default (initialize-context)})
-          :else (assoc context :jetty9-servers (into {} (for [[server-id] config]
+          (nil? old-config) (assoc context :jetty9-servers {:default (initialize-context)})
+          (nil? new-config) (assoc context :jetty9-servers (into {} (for [[server-id] config]
                                                           [server-id (initialize-context)]))))))

 (schema/defn ^:always-validate start!
   [context config :- config/WebserverServiceRawConfig]
-  (let [old-config? (nil? (schema/check config/WebserverRawConfig config))]
+  (let [old-config (schema/check config/WebserverRawConfig config)
+        new-config (schema/check config/MultiWebserverRawConfig config)]
     (cond
-      old-config? (start-server-single-default context config)
-      :else (start-server-multiple context config))))
+      (nil? old-config) (start-server-single-default context config)
+      (nil? new-config) (start-server-multiple context config))))

 (schema/defn ^:always-validate add-context-handler-to!
   ([service-context server-id :- schema/Keyword


make code slightly clearer

make code slightly clearer

--- src/edge/pomodoro.cljs
+++ src/edge/pomodoro.cljs
@@ -5,24 +5,21 @@

 (defonce interval (atom 0))

-(def time-active (r/atom 0)) ;doesnt work as boolean? not sure why..
+(def time-active? (r/atom false))

-(def start-timer (r/atom 150000))
+(def work-timer (r/atom 150000))

 (def break-timer (r/atom 1500))

-(def start-time (r/atom 25))
+(def work-time (r/atom 25))

 (def break-time (r/atom 5))

 (def time-fn (atom dec))

-(def break-time? (r/atom 0))
+(def break-time? (r/atom false))

-(defn time-active? []
-  (if (= @time-active 0)
-    false
-    true))
+

 (defn seconds-to-time [secs]
   (let [d (js/Date. (* 10 secs))]
@@ -32,6 +29,7 @@
      :milliseconds (.getUTCMilliseconds d)}))

 (defn display-time [tm]
+"return str of mins secs and millisecs with padding"
   (let [pad (fn [n]
               (if (< n 10)
                 (str "0" n)
@@ -42,46 +40,48 @@
     (str mm ":" ss ":" ms)))

 (defn keep-time [func]
+"Starts appropriate timer (break or work) and checks if timer is 0"
   (if (zero? @break-timer)
     (do
-      (reset)
-
-      (start)))
-  (if (zero? @start-timer)
-    (do
-      (reset! break-time? 1)
-      (swap! break-timer func))
-    (do
-      (reset! break-time? 0)
-
-      (swap! start-timer func))))
+      (reset)
+      (start))
+    (if (zero? @work-timer)
+      (do
+        (reset! break-time? true)
+        (swap! break-timer func))
+      (do
+        (reset! break-time? false)
+        (swap! work-timer func)))))

 (defn pause []
-  (when (time-active?)
-    (reset! time-active 0)
+"if timer is running stop it"
+  (when @time-active?
+    (reset! time-active? true)
     (js/clearInterval @interval)))

 (defn start []
-  (reset! time-active 1)
+"if no timer is running, start it"
+  (reset! time-active? true)
   (reset! interval (js/setInterval #(keep-time @time-fn) 10)))

-(defn reset []
+(defn reset [] ;todo - reset only break timer when in break time
+"set the work and break timers and stop any running"
   (let [starting (fn [n] ;; cap input at 59 mins
                    (if (< n 60)
                      n
                      59))]
-    (reset! break-time? 0)
-    (reset! time-active 0)
+    (reset! break-time? false)
+    (reset! time-active? false)
     (js/clearInterval @interval)
-    (reset! start-timer (* 60 (* 100 (starting  @start-time))))
+    (reset! work-timer (* 60 (* 100 (starting  @work-time))))
     (reset! break-timer (* 60 (* 100 @break-time)))))

 (defn start-time-input []
   [:div.start-input
    "Set working timer (in minutes): "
    [:input {:type "text"
-            :value @start-time
-            :on-change #(reset! start-time (-> % .-target .-value))}]
+            :value @work-time
+            :on-change #(reset! work-time (-> % .-target .-value))}]
    [:button {:on-click (fn [ev] (reset))} "Set!"]])

 (defn break-time-input []
@@ -96,21 +96,21 @@

 (defn work-clock []
   [:div
-   [:h1 (when (time-active?)
-          (if (zero? @break-time?)
-            "Get to work!!"
-            "Break time!!")) ]
+   [:h1 (when @time-active?
+          (if @break-time?
+            "Break time!!"
+            "Get to work!!")) ]
    [start-time-input]
    [break-time-input]
-   [:h1.work-clock  {:class (if (zero? @break-time?)
+   [:h1.work-clock  {:class (if @break-time?
+                              "hide"
                               "show-work"
-                              "hide"
-                              )} (display-time (seconds-to-time @start-timer))]
-   [:h1.break-clock {:class (if (zero? @break-time?)
-                              "hide"
+                              )} (display-time (seconds-to-time @work-timer))]
+   [:h1.break-clock {:class (if @break-time?
                               (if (< @break-timer 3000)
                                 "show-break warning"
                                 "show-break")
+                              "hide"
                               )} (display-time (seconds-to-time @break-timer))]
    [:button {:on-click (fn [ev] (start))} "Start!"]
    [:button {:on-click (fn [ev] (pause))} "Pause!"]


Fix typos.

Fix typos.

--- examples/simple/src/simple/core.cljs
+++ examples/simple/src/simple/core.cljs
@@ -35,7 +35,7 @@

 (rf/reg-event-db                 ;; usage:  (dispatch [:timer a-js-Date])
   :timer                         ;; every second an event of this kind will be dispatched
-  (fn [db [_ new-time]]          ;; note how the 2nd parameter is desctructure to obtain the data value
+  (fn [db [_ new-time]]          ;; note how the 2nd parameter is destructured to obtain the data value
     (assoc db :time new-time)))  ;; compute and return the new application state

@@ -43,7 +43,7 @@

 (rf/reg-sub
   :time
-  (fn [db _]     ;; db is current app state. 2nd usused param is query vector
+  (fn [db _]     ;; db is current app state. 2nd unused param is query vector
     (-> db
         :time)))


Fix my fix 'only one instance'

Fix my fix 'only one instance'

--- examples/simple/src/simple/core.cljs
+++ examples/simple/src/simple/core.cljs
@@ -13,7 +13,7 @@
     (rf/dispatch [:timer now])))  ;; <-- dispatch used

 ;; Call the dispatching function every second.
-;; `defonce` is like `def` but it ensures only instance one is ever
+;; `defonce` is like `def` but it ensures only one instance is ever
 ;; created in the face of figwheel hot-reloading of this file.
 (defonce do-timer (js/setInterval dispatch-timer-event 1000))


only re-run changed query

only re-run changed query

--- iwaswhere-web/src/clj/iwaswhere_web/store.clj
+++ iwaswhere-web/src/clj/iwaswhere_web/store.clj
@@ -52,9 +52,12 @@
    :sente-uid, otherwise sends to all clients."
   [{:keys [current-state msg-payload msg-meta]}]
   (if-let [sente-uid (:sente-uid msg-payload)]
-    (let [queries (get-in current-state [:client-queries sente-uid :queries])
+    (let [query-id (:query-id msg-payload)
+          queries (get-in current-state [:client-queries sente-uid :queries])
+          queries (if query-id {query-id (query-id queries)} queries)
           msg-meta  (merge msg-meta {:sente-uid sente-uid})
-          get-results (run-query current-state (merge msg-meta {:sente-uid sente-uid}))
+          get-results (run-query current-state (merge msg-meta
+                                                      {:sente-uid sente-uid}))
           results (mapv get-results queries)]
       {:emit-msg results})
     {:send-to-self (mapv (fn [uid] [:state/publish-current {:sente-uid uid}])


Adds spec for function

Adds spec for function

--- src/expound/alpha.cljc
+++ src/expound/alpha.cljc
@@ -233,6 +233,15 @@
      (indent (pprint-str (s/form spec))))
     (pprint-str (s/form spec))))

+(s/def :spec/spec keyword?)
+(s/def :spec/specs (s/coll-of :spec/spec))
+(s/def :spec.problem/via (s/coll-of :spec/spec :kind vector?))
+(s/def :spec/problem (s/keys :req-un [:spec.problem/via]))
+(s/def :spec/problems (s/coll-of :spec/problem))
+
+(s/fdef specs
+        :args (s/cat :problems :spec/problems)
+        :ret :spec/specs)
 (defn specs
   "Given a collection of problems, returns the specs for those problems, with duplicates removed"
   [problems]


Add 2d camera.

Add 2d camera.

--- src/ezglib/render.cljs
+++ src/ezglib/render.cljs
@@ -11,6 +11,23 @@

 (defprotocol IGraph
   (-draw! [this camera]))
+
+;;;;; CAMERAS ;;;;;
+
+(deftype Camera2D [x y hw hh angle]
+  ICamera
+  (-matrix [_] (m/mult
+                (m/ortho (- x hw) (+ x hw) (- y hh) (+ y hh) -1000000 1000000)
+                (m/rotate-z angle))))
+
+(defn camera-2d
+  "Constructs a 2D camera."
+  ([x y hw hh]
+   (Camera2D. x y hw hh 0))
+  ([x y hw hh angle]
+   (Camera2D. x y hw hh angle)))
+
+;;;;; GRAPHS ;;;;;

 (defn graph
   "Creates a new 2d scene graph."


syncs duration changes

syncs duration changes

--- src/frontend/core.cljs
+++ src/frontend/core.cljs
@@ -35,7 +35,10 @@
     false))

 (defn on-drag-stop [event ui]
-  (println (.-position ui)))
+  (println (str "Drop position: " (.-position ui)))
+  (let [bar-width (.width (js/$ "#progress-track-bar"))]
+    (.emit socket "sync-to-server" #js {:type "position-change"
+                                        :data (/ (.-left (.-position ui)) bar-width)})))

 (.draggable (js/$ "#progress-track-ball") #js {:axis "x"
                                                :containment "#progress-track"
@@ -186,5 +189,9 @@
           (. current-sound pause)
         (= "resume" message-type)
           (. current-sound resume)
+        (= "position-change" message-type)
+          (let [duration (.-duration (:current-sound @app-state))
+                position (get message "data")]
+            (.setPosition js/soundManager (:current-sound-id @app-state) (* duration position)))
         :else
           (println "Don't know how to handle that message...")))))


remove user upload status on upload completion

--- src/frontend/core.cljs
+++ src/frontend/core.cljs
@@ -59,7 +59,9 @@

 (.on socket "file-upload-info"
   (fn [file-upload-info]
-    (swap! app-state assoc :current-uploads-info
-      (merge (:current-uploads-info @app-state)
-        {(.-id file-upload-info) file-upload-info}))
-    (println (:current-uploads-info @app-state))))
+    (if (= (.-totalsize file-upload-info) (.-bytesreceived file-upload-info))
+      (swap! app-state assoc :current-uploads-info
+        (dissoc (:current-uploads-info @app-state) (.-id file-upload-info)))
+      (swap! app-state assoc :current-uploads-info
+        (merge (:current-uploads-info @app-state)
+          {(.-id file-upload-info) file-upload-info})))))


Remove debugging from lazytest.group

Remove debugging from lazytest.group

--- src/main/clojure/lazytest/group.clj
+++ src/main/clojure/lazytest/group.clj
@@ -8,16 +8,7 @@
 	[lazytest.result :only (pass fail thrown result-group)])
   (:import (lazytest ExpectationFailed)))

-(comment
-  (defn- debug [& args]
-    (spit "log"
-	  (str (pr-str args) "\n")
-	  :append true)))
-
-(defmacro debug [& args] nil)
-
 (defn- apply-test-case [tc arguments]
-  (debug "apply-test-case" tc arguments)
   (let [this (vary-meta tc assoc :states arguments)]
     (try (apply (:f tc) arguments)
 	 (pass this)
@@ -25,7 +16,6 @@
 	 (catch Throwable e (thrown this e)))))

 (defn- run-test-case [tc]
-  (debug "run-test-case" tc)
   (try (let [states (map setup (:fixtures tc))
 	     result (apply-test-case tc states)]
 	 (dorun (map teardown (:fixtures tc)))
@@ -33,19 +23,13 @@
        (catch Throwable e (thrown tc e))))

 (defn- run-test-sequence [tc]
-  (debug "run-test-sequence" tc)
   (try
     (let [state-sequences (map (fn [fix]
-				 (debug "Mapping over fixture" fix)
 				 (if (:sequential (meta fix))
-				   (do (debug "sequential fixture" fix)
-				       (setup fix))
-				   (do (debug "singular fixture" fix)
-				       (repeatedly (fn [] (setup fix))))))
+				   (setup fix)
+				   (repeatedly (fn [] (setup fix)))))
 			       (:fixtures tc))
-	  _unused_ (debug "state-sequences" state-sequences)
 	  argument-lists (apply map list state-sequences)]
-      (debug "argument-lists" argument-lists)
       (map (partial apply-test-case tc) argument-lists))
     (catch Throwable e (list (thrown tc e)))))

@@ -54,7 +38,6 @@
   (get-tests [this] (list this))
   RunnableTest
   (run-tests [this]
-	     (debug "TestCase.run-tests" this)
 	     (if-let [skipped (skip-or-pending this)]
 	       (list skipped)
 	       (if (some #(:sequential (meta %)) fixtures)
@@ -77,7 +60,6 @@
   (get-tests [this] (list this))
   RunnableTest
   (run-tests [this]
-	     (debug "TestGroup.run-tests" this)
 	     (lazy-seq
 	      (list
 	       (or (skip-or-pending this)


Update task.clj

Update task.clj

--- src/iyye/bios/task.clj
+++ src/iyye/bios/task.clj
@@ -25,7 +25,7 @@
   (loop [cur (zip/vector-zip @tasks-tree)]
     (if (zip/end? cur)
       nil
-      (if (= (:name (zip/node cur)))
+      (if (= (:name (zip/node cur)) name)
         cur
         (recur (zip/next cur))))))

@@ -40,11 +40,12 @@

 (defn add-task [task]
   (if-let [name (:parent task)]
-    (if-let [cur (find-task name)]
-      (if cur
+    (let [cur (find-task name)]
+      (when cur
         (dosync (ref-set tasks-tree
-                         (-> cur (zip/append-child task) zip/root))))
-      (dosync (alter tasks-tree conj task)))
+                         (if (and (not (zip/end? (zip/next cur))) (-> cur zip/next zip/branch?))
+                           (-> cur zip/next (zip/replace (conj (-> cur zip/next zip/node) task)) zip/root)
+                           (-> cur zip/up (zip/append-child [task]) zip/root))))))
     (dosync (alter tasks-tree conj task))))

 (defn remove-task [task]


lose refer

lose refer

--- src/java_time/zone.clj
+++ src/java_time/zone.clj
@@ -1,5 +1,5 @@
 (ns java-time.zone
-  (:require [java-time.core :as jt.c :refer (value)]
+  (:require [java-time.core :as jt.c]
             [java-time.temporal :as jt.t]
             [java-time.util :as jt.u]
             [java-time.amount :as jt.a]
@@ -120,7 +120,7 @@
   ([y mo d h m s n] (offset-date-time y mo d h m s n (zone-offset)))
   ([y mo d h m s n o]
    (OffsetDateTime/of
-     (int (value y)) (int (value mo)) (int (value d))
+     (int (jt.c/value y)) (int (jt.c/value mo)) (int (jt.c/value d))
      (int h) (int m) (int s) (int n) (zone-offset o))))

 (deffactory offset-time
@@ -183,7 +183,7 @@
   ([y mo d h m s n] (zoned-date-time y mo d h m s n (zone-id)))
   ([y mo d h m s n o]
    (ZonedDateTime/of
-     (int (value y)) (int (value mo)) (int (value d))
+     (int (jt.c/value y)) (int (jt.c/value mo)) (int (jt.c/value d))
      (int h) (int m) (int s) (int n) (zone-id o))))

 (conversion! Clock ZonedDateTime


adds logging for close trigger on websockets (#609)

--- waiter/src/waiter/websocket.clj
+++ waiter/src/waiter/websocket.clj
@@ -232,7 +232,7 @@
                     (au/timed-offer! upload-chan send-data streaming-timeout-ms))
                 (recur (+ bytes-streamed bytes-read))
                 (do
-                  (log/error "unable to stream to " dest-name {:cid (cid/get-correlation-id), :bytes-streamed bytes-streamed})
+                  (log/error "unable to stream to" dest-name {:cid (cid/get-correlation-id), :bytes-streamed bytes-streamed})
                   (meters/mark! stream-back-pressure-meter)
                   (deliver reservation-status-promise stream-error-type)
                   (async/>! request-close-chan stream-error-type))))
@@ -312,6 +312,7 @@
                              error-code)

                            :else :unknown)]
+          (log/info (name source) "requesting close of websocket:" close-code close-message)
           (async/>! request-close-promise-chan [source close-code return-code-or-exception close-message]))))))

 (defn- close-client-session!
@@ -328,7 +329,7 @@
 (defn- successful?
   "Returns whether the status represents a successful status code."
   [status]
-  (= 1000 status))
+  (= StatusCode/NORMAL status))

 (defn process-response!
   "Processes a response resulting from a websocket request.
@@ -349,8 +350,8 @@
         stream-complete-rate
         (timers/start-stop-time!
           stream
-          (when-let [close-message (async/<! request-close-promise-chan)]
-            (let [[source close-code status-code-or-exception close-message] close-message]
+          (when-let [close-message-wrapper (async/<! request-close-promise-chan)]
+            (let [[source close-code status-code-or-exception close-message] close-message-wrapper]
               (log/info "websocket connections requested to be closed due to" source close-code close-message)
               (counters/dec! requests-streaming)
               ;; explicitly close the client connection if backend triggered the close


Format sparkline timestamps with relative dates if possible

--- src/metabase/pulse.clj
+++ src/metabase/pulse.clj
@@ -64,6 +64,7 @@
     :else (str (cl-format nil "~,1f" n))))

 (defn- format-timestamp
+  "Formats timestamps with human friendly absolute dates based on the column :unit"
   [timestamp col]
   (case (:unit col)
     :hour (f/unparse (f/formatter "h a - MMM YYYY") (c/from-long timestamp))
@@ -76,6 +77,39 @@
     :week-of-year (str timestamp)
     :month-of-year (str timestamp)
     (f/unparse (f/formatter "MMM d, YYYY") (c/from-long timestamp))))
+
+(defn- format-timestamp-relative
+  "Formats timestamps with relative names (today, yesterday, this *, last *) based on column :unit, if possible, otherwie returns nil"
+  [timestamp col]
+  (case (:unit col)
+    :day      (let [date    (c/from-long timestamp)
+                    d-start (t/date-midnight (t/year (t/now)) (t/month (t/now)) (t/day (t/now)))]
+                (cond (t/within? (t/interval d-start (t/plus d-start (t/days 1))) date) "Today"
+                      (t/within? (t/interval (t/minus d-start (t/days 1)) d-start) date) "Yesterday"))
+    :week     (let [date    (c/from-long timestamp)
+                    w-start (-> (new org.joda.time.LocalDate) .weekOfWeekyear .roundFloorCopy .toDateMidnight)]
+                (cond (t/within? (t/interval w-start (t/plus w-start (t/weeks 1))) date) "This week"
+                      (t/within? (t/interval (t/minus w-start (t/weeks 1)) w-start) date) "Last week"))
+    :month    (let [date    (c/from-long timestamp)
+                    m-start  (t/date-midnight (t/year (t/now)) (t/month (t/now)))]
+                (cond (t/within? (t/interval m-start (t/plus m-start (t/months 1))) date) "This month"
+                      (t/within? (t/interval (t/minus m-start (t/months 1)) m-start) date) "Last month"))
+    :quarter  (let [date    (c/from-long timestamp)
+                    q-start (t/date-midnight (t/year (t/now)) (+ 1 (* 3 (Math/floor (/ (- (t/month (t/now)) 1) 3)))))]
+                (cond (t/within? (t/interval q-start (t/plus q-start (t/months 3))) date) "This quarter"
+                      (t/within? (t/interval (t/minus q-start (t/months 3)) q-start) date) "Last quarter"))
+    :year     (let [date    (t/date-midnight timestamp)
+                    y-start (t/date-midnight (t/year (t/now)))]
+                (cond (t/within? (t/interval y-start (t/plus y-start (t/years 1))) date) "This year"
+                      (t/within? (t/interval (t/minus y-start (t/years 1)) y-start) date) "Last year"))
+    nil))
+
+(defn format-timestamp-pair
+  "Formats a pair of timestamps, using relative formatting for the first timestamps if possible and 'Previous :unit' for the second, otherwise absolute timestamps for both"
+  [[a b] col]
+  (if-let [a' (format-timestamp-relative a col)]
+    [a' (str "Previous " (-> col :unit name))]
+    [(format-timestamp a col) (format-timestamp b col)]))

 (defn- format-cell
   [value col]
@@ -227,18 +261,20 @@
         ys (map second rows)
         ymin (apply min ys)
         ymax (apply max ys)
-        yrange (- ymax ymin)
+        yrange (max 1 (- ymax ymin)) ; `(max 1 ...)` so we don't divide by zero
         ys' (map #(/ (- % ymin) yrange) ys)
-        values (take-last 2 rows)]
+        rows' (->> rows (take-last 2) (reverse))
+        values (map #(format-number (second %)) rows')
+        labels (format-timestamp-pair (map first rows') (first cols))]
   [:div
     [:img {:style "display: block; width: 100%;" :src (render-img (render-sparkline-to-png xs' ys' 524 130))}]
     [:table
       [:tr
-        [:td {:style (str "color: " color-brand "; font-size: 24px; font-weight: 700; padding-right: 16px;")} (-> values second second format-number)]
-        [:td {:style (str "color: " color-grey-3 "; font-size: 24px; font-weight: 700;")} (-> values first second format-number)]]
+        [:td {:style (str "color: " color-brand "; font-size: 24px; font-weight: 700; padding-right: 16px;")} (first values)]
+        [:td {:style (str "color: " color-grey-3 "; font-size: 24px; font-weight: 700;")} (second values)]]
       [:tr
-        [:td {:style (str "color: " color-brand "; font-size: 16px; font-weight: 700; padding-right: 16px;")} (-> values second first (format-timestamp (first cols)))]
-        [:td {:style (str "color: " color-grey-3 "; font-size: 16px;")}  (-> values first first (format-timestamp (first cols)))]]]]))
+        [:td {:style (str "color: " color-brand "; font-size: 16px; font-weight: 700; padding-right: 16px;")} (first labels)]
+        [:td {:style (str "color: " color-grey-3 "; font-size: 16px;")} (second labels)]]]]))

 (defn detect-pulse-card-type
   [card data]


type is optional

type is optional

--- web/celestial/models/system.clj
+++ web/celestial/models/system.clj
@@ -8,7 +8,7 @@
 (defn systems
   "system list range"
   [from to type]
-  {:pre [(> from -1) (p/type-exists! type)]}
+  {:pre [(> from -1) (if type (p/type-exists! type) true)]}
   (let [systems (if type (p/get-system-index :type type) (into [] (p/all-systems)))
         to* (min to (- (count systems) 1))]
     (if (and (contains? systems from) (contains? systems to*))


Add create, encode, decode stubs.

Add create, encode, decode stubs.

--- src/multihash/core.clj
+++ src/multihash/core.clj
@@ -175,9 +175,34 @@
     (Multihash. code digest m)))

-; TODO: constructor
-; TODO: encode
-; TODO: decode
+; TODO: unset ->Multihash
+
+
+(defn create
+  "Constructs a new Multihash identifier. Accepts either a numeric algorithm
+  code or a keyword name as the first argument. The digest may either by a byte
+  array or a hex string."
+  [algorithm digest]
+  (let [code (coerce-code algorithm)
+        digest (if (string? digest)
+                 (bytes->hex (hex->bytes digest))
+                 (bytes->hex digest))]
+    ; TODO: check length
+    (Multihash. code digest nil)))
+
+
+(defn encode
+  "Encodes a multihash into a binary representation."
+  [mhash]
+  ; TODO: encode
+  )
+
+
+(defn decode
+  "Decodes a hex string or byte array into a multihash value."
+  [encoded]
+  ; TODO: decode
+  )

 ; TODO: multimethod?


(PE-3489) Document preference of SSL functions from jvm-ca

This commit adds a section header comment and notes in the docstrings
of the SSL functions that mention the jvm-ca library should be preferred.

--- src/puppetlabs/kitchensink/core.clj
+++ src/puppetlabs/kitchensink/core.clj
@@ -725,9 +725,16 @@

 ;; ## SSL Certificate handling
+;;
+;; NOTE: Prefer functions provided by the jvm-certificate-authority library over these.
+;;
+;; These functions are only used by PuppetDB and they should likely move back into that
+;; project until they can be refactored away over functions from the jvm-ca library.

 (defn cn-for-dn
-  "Extracts the CN (common name) from an LDAP DN (distinguished name).
+  "Deprecated. Use functions from `jvm-certificate-authority`.
+
+  Extracts the CN (common name) from an LDAP DN (distinguished name).

   If more than one CN entry exists in the given DN, we return the most-specific
   one (the one that comes last, textually). If no CN is present in the DN, we
@@ -754,7 +761,9 @@
     (str)))

 (defn cn-for-cert
-  "Extract the CN from the DN of an x509 certificate. See `cn-for-dn` for details
+  "Deprecated. Use functions from `jvm-certificate-authority`.
+
+  Extract the CN from the DN of an x509 certificate. See `cn-for-dn` for details
   on how extraction is performed.

   If no CN exists in the certificate DN, nil is returned."


(PDB-3067) Improve existing command logging.

Change the message identifier in the command namespace's log/info
invocations to be a concatenation of the stockpile ID and the timestamp
the message was received at, in order to guarantee uniqueness across
restarts (as the stockpile ID may reset).

Change the overall structure of the logged message in the same form so
it's clear *what* is being logged.

--- src/puppetlabs/puppetdb/command.clj
+++ src/puppetlabs/puppetdb/command.clj
@@ -138,7 +138,8 @@
     (jdbc/with-transacted-connection' db :repeatable-read
       (scf-storage/maybe-activate-node! certname producer-timestamp)
       (scf-storage/replace-catalog! catalog received))
-    (log/infof "[%s] [%s] %s" id (command-names :replace-catalog) certname)))
+    (log/infof (i18n/trs "[%s-%d] '%s' command processed for %s")
+               id (tcoerce/to-long received) (command-names :replace-catalog) certname)))

 (defn replace-catalog [{:keys [payload received version] :as command} db]
   (let [validated-payload (upon-error-throw-fatality
@@ -150,13 +151,14 @@
 ;; Fact replacement

 (defn replace-facts*
-  [{:keys [payload id] :as command} db]
+  [{:keys [payload id received] :as command} db]
   (let [{:keys [certname values] :as fact-data} payload
         producer-timestamp (:producer_timestamp fact-data)]
     (jdbc/with-transacted-connection' db :repeatable-read
       (scf-storage/maybe-activate-node! certname producer-timestamp)
       (scf-storage/replace-facts! fact-data))
-    (log/infof "[%s] [%s] %s" id (command-names :replace-facts) certname)))
+    (log/infof (i18n/trs "[%s-%d] '%s' command processed for %s")
+               id (tcoerce/to-long received) (command-names :replace-facts) certname)))

 (defn replace-facts [{:keys [payload version received] :as command} db]
   (let [validated-payload (upon-error-throw-fatality
@@ -184,14 +186,15 @@
       deactivate-node-wire-v2->wire-3))

 (defn deactivate-node*
-  [{:keys [id payload]} db]
+  [{:keys [id received payload]} db]
   (let [certname (:certname payload)
         producer-timestamp (to-timestamp (:producer_timestamp payload (now)))]
     (jdbc/with-transacted-connection db
       (when-not (scf-storage/certname-exists? certname)
         (scf-storage/add-certname! certname))
       (scf-storage/deactivate-node! certname producer-timestamp))
-    (log/infof "[%s] [%s] %s" id (command-names :deactivate-node) certname)))
+    (log/infof (i18n/trs "[%s-%d] '%s' command processed for %s")
+               id (tcoerce/to-long received) (command-names :deactivate-node) certname)))

 (defn deactivate-node [{:keys [payload version] :as command} db]
   (-> command
@@ -210,8 +213,9 @@
     (jdbc/with-transacted-connection db
       (scf-storage/maybe-activate-node! certname producer-timestamp)
       (scf-storage/add-report! report received))
-    (log/infof "[%s] [%s] puppet v%s - %s"
+    (log/infof (i18n/trs "[%s-%d] '%s' puppet v%s command processed for %s")
                id
+               (tcoerce/to-long received)
                (command-names :store-report)
                puppet_version
                certname)))


Add reverse sorting, fix #24

Add reverse sorting, fix #24

--- frontend/src/cruncher/utils/lib.cljs
+++ frontend/src/cruncher/utils/lib.cljs
@@ -18,12 +18,13 @@
                                 :status    "ok"}
             :progress-running? false
             :player            {}
-            :evolution-number  0}))
+            :evolution-number  0
+            :sort-asc              true}))

 (declare get-pokemon-by-id)
 (declare evolution-sum)
-
-(defonce sort-direction-asc (atom true))
+(declare reconciler)
+
 ;;;; React compatibility
 (defonce counter (atom 0))

@@ -64,11 +65,14 @@
   [{:keys [state]} _ {:keys [player]}]
   {:action (fn [] (swap! state update-in [:player] (fn [] player)))})

-
 (defmethod mutate 'sort/pokemon
   [{:keys [state]} _ {:keys [key]}]
   {:action (fn [] (swap! state update-in [:pokemon] (fn [] (cond-> (sort-by (juxt key :individual_percentage :cp) (:pokemon @state))
-                                                      (swap! sort-direction-asc not) reverse))))})
+                                                                  (:sort-asc @state) reverse))))})
+
+(defmethod mutate 'sort/toggle-asc
+  [{:keys [state]} _ {:keys []}]
+  {:action (fn [] (swap! state update-in [:sort-asc] not))})

 (defmethod mutate 'change/view
   [{:keys [state]} _ {:keys [view]}]
@@ -239,7 +243,8 @@
 (defn sort-pokemon!
   "Sort complete list of pokemon by given key."
   [key]
-  (om/transact! reconciler `[(sort/pokemon {:key ~key})]))
+  (om/transact! reconciler `[(sort/pokemon {:key ~key})])
+  (om/transact! reconciler `[(sort/toggle-asc)]))

 (defn update-player!
   "Update the playerdata."