Fix bug #1, where ZooKeeper consumer creation could fail on start.

--- src/uswitch/bifrost/kafka.clj
+++ src/uswitch/bifrost/kafka.clj
@@ -2,7 +2,7 @@
   (:require [clj-kafka.zk :refer (topics)]
             [com.stuartsierra.component :refer (Lifecycle start stop system-map using)]
             [clojure.java.io :refer (file output-stream)]
-            [clojure.core.async :refer (chan <! >! go-loop timeout alts! close! put!)]
+            [clojure.core.async :refer (chan <! >! go-loop timeout alts! close! put! <!!)]
             [clojure.set :refer (difference intersection)]
             [clj-kafka.consumer.zk :refer (consumer messages shutdown)]
             [clojure.tools.logging :refer (info debug error)]
@@ -118,10 +118,27 @@
                         (timeout rotation-interval)))))
     message-ch))

+(defn safe-zookeeper-consumer
+  "Repeatedly tries to construct a ZooKeeper consumer. Will retry every
+  15s and log errors. Returns a channel that contains the obtained
+  consumer."
+  [consumer-properties]
+  (let [get-consumer (fn []
+                       (try (consumer consumer-properties)
+                            (catch Exception e
+                              (error e "Unable to create ZooKeeper consumer")
+                              nil)))]
+    (go-loop
+     []
+     (if-let [c (get-consumer)]
+       c
+       (do (<! (timeout (* 15 1000)))
+           (recur))))))
+
 (defrecord TopicBaldrConsumer [consumer-properties topic rotation-interval ch]
   Lifecycle
   (start [this]
-    (let [c (consumer consumer-properties)
+    (let [c (<!! (safe-zookeeper-consumer consumer-properties))
           run? (atom true)]
       (go-loop [msgs (messages c topic)
                 partition->message-ch {}]


Create zip file in a temp directory

Create zip file in a temp directory

Fixes the problem where a zip file can carry over between processing
runs of feeds for the same election and causing problems when trying to
recreate the zip file.

--- src/vip/data_processor/s3.clj
+++ src/vip/data_processor/s3.clj
@@ -53,8 +53,10 @@
   "Uploads the generated xml file to the specified S3 bucket."
   [ctx]
   (let [zip-name (str (zip-filename ctx) ".zip")
-        zip-file (File. zip-name)
-        zip (ZipFile. zip-name)
+        zip-dir (Files/createTempDirectory tmp-path-prefix
+                                           (into-array FileAttribute []))
+        zip-file (File. (.toFile zip-dir) zip-name)
+        zip (ZipFile. zip-file)
         zip-params (doto (ZipParameters.)
                      (.setCompressionLevel
                       Zip4jConstants/DEFLATE_LEVEL_NORMAL))


Debug print EDNs instead of JSONs

Debug print EDNs instead of JSONs

To be used as test fixtures.

--- src/devtools/core.cljs
+++ src/devtools/core.cljs
@@ -24,8 +24,8 @@
         (debug/log (debug/logger name) value)
         (debug/indent!)
         (let [api-response (api-call value)                 ; wrapped API call
-              api-response-filter (fn [key value] (if (= key "object") (str "REF -> " #_(str value)) value))]
-          (debug/log (debug/logger name) (str "=> " (json/serialize api-response api-response-filter)))
+              api-response-filter (fn [key value] (if (= key "object") "##REF##" value))]
+          (debug/log (debug/logger name) (str "=> " (js->clj (json/parse (json/serialize api-response api-response-filter)))))
           (debug/unindent!)
           api-response)))))


Stubbed process component to support health checks.

--- src/cmr/dev/env/manager/components/process.clj
+++ src/cmr/dev/env/manager/components/process.clj
@@ -111,3 +111,19 @@
   (map->ProcessRunner
     {:builder config-builder-fn
      :process-keyword process-keyword}))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;   Health-check Implementation   ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defn get-status
+  [this]
+  (let [process-response nil
+        http-response nil
+        ping-response nil]
+    {:process nil
+     :http nil
+     :ping nil}))
+
+(def healthful-behaviour
+  {:get-status get-status})


--- src/wiki_talk_parser/core.clj
+++ src/wiki_talk_parser/core.clj
@@ -40,8 +40,9 @@

 (defn process-page [page lang]
   (let [user-id (get-user-id (get-user-name page) lang)]
-    (doseq [contributor-id (get-contributor-ids page) :when (not (nil? contributor-id))]  ; filter out IP contributors
-      (println (str contributor-id "\t" user-id)))))  ; have to use "\t" as delimiter, ffs
+    (when-not (nil? user-id)  ; ignore "User_talk" pages of IP users or whatever wrong
+      (doseq [contributor-id (get-contributor-ids page) :when (not (nil? contributor-id))]  ; filter out IP contributors
+        (println (str contributor-id "\t" user-id))))))  ; have to use "\t" as delimiter, ffs

 (defn -main
   "Where everything starts happening."


fix imports, formatting, signatures

fix imports, formatting, signatures

--- src/yeller_clojure_client.clj
+++ src/yeller_clojure_client.clj
@@ -3,7 +3,8 @@
   (:import (com.yellerapp.client
              YellerHTTPClient
              YellerClient
-             YellerExtraDetail)))
+             YellerExtraDetail
+             YellerErrorHandler)))

 (defn default-io-error-handler [backend error]
   (.println *err* (str "Yeller: an io error ocurred whilst talking to yeller: " error)))
@@ -38,10 +39,10 @@
         client
         (reify
           YellerErrorHandler
-          (reportAuthError [backend e]
+          (reportAuthError [this backend e]
             ((:auth-error-handler options default-auth-error-handler)
                backend e))
-          (reportIOError [backend e]
+          (reportIOError [this backend e]
             ((:auth-io-handler options default-auth-error-handler)
                backend e)))))
     client))
@@ -82,11 +83,16 @@
            (:location extra)
            (:url extra))
      (let [detail (format-extra-detail extra)]
-       (.report client detail (stringify-keys (dissoc extra
-                                                      :environment
-                                                      :location
-                                                      :url))))
-     (.report client (stringify-keys (dissoc extra
-                                                    :environment
-                                                    :location
-                                                    :url))))))
+       (.report client
+                exception
+                detail
+                (stringify-keys (dissoc extra
+                                        :environment
+                                        :location
+                                        :url))))
+     (.report client
+              exception
+              (stringify-keys (dissoc extra
+                                      :environment
+                                      :location
+                                      :url))))))


Fix typo in meetup tests

Fix typo in meetup tests

Fixed an instance of the word 'map' which should have been 'may'

--- meetup/meetup_test.clj
+++ meetup/meetup_test.clj
@@ -57,7 +57,7 @@
 (deftest saturteenth-of-october-2013
   (is (= [2013 10 19] (meetup/meetup 10 2013 :saturday :teenth))))

-(deftest sunteenth-of-map-2013
+(deftest sunteenth-of-may-2013
   (is (= [2013 5 19] (meetup/meetup 5 2013 :sunday :teenth))))

 (deftest sunteenth-of-june-2013


More optimizations for c.c.a.parallel-cbo

i.e. introduced string-to-ints.

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

--- src/conexp/contrib/algorithms/parallel_cbo.clj
+++ src/conexp/contrib/algorithms/parallel_cbo.clj
@@ -50,8 +50,25 @@
      object-vector
      attribute-vector]))

-(defn- string-to-int [str]
-  (reduce #(+ (* 10 %1) (Character/digit ^Character %2 10)) 0 str))
+(defn- string-to-ints [vec str]
+  (loop [str         str,
+         current-int -1,
+         ints        (transient #{})]
+    (if (empty? str)
+      (if (neg? current-int)
+        (persistent! ints)
+        (persistent! (conj! ints (nth vec current-int))))
+      (let [next-char (first str)]
+        (if (= \space next-char)
+          (recur (rest str)
+                 -1
+                 (if (neg? current-int)
+                   ints
+                   (conj! ints (nth vec current-int))))
+          (recur (rest str)
+                 (let [next-int (int (Character/digit ^Character next-char 10))]
+                   (+ (* 10 (max 0 current-int)) next-int))
+                 ints))))))

 (defn context-intents
   "Computes the intents of context using parallel close-by-one (CbO)."
@@ -59,8 +76,7 @@
   (let [[ctx _ att-vec] (to-fcalgs-context context),
         output-file     (pcbo threads depth min-support ctx),
         intents         (line-seq (reader output-file)),
-        transform-back  #(set-of (nth att-vec (string-to-int x))
-                                 [x (split % #"\s+")])]
+        transform-back  #(string-to-ints att-vec %)]
     (if (= "" (first intents))
       (cons #{} (map transform-back (rest intents)))
       (map transform-back intents))))


CMR-1867 Simplifies test code.

CMR-1867 Simplifies test code.

--- umm-spec-lib/test/cmr/umm_spec/test/generate_and_parse.clj
+++ umm-spec-lib/test/cmr/umm_spec/test/generate_and_parse.clj
@@ -68,9 +68,7 @@
 (def example-records
   "A seq of example records for each of the example temporal extents above."
   (for [temporal temporal-extents]
-    (if temporal
-      (assoc example-base :TemporalExtents [temporal])
-      example-base)))
+    (assoc example-base :TemporalExtents [temporal])))

 (defn xml-round-trip
   "Returns record after being converted to XML and back to UMM through


Added D3.js to the footer of the site.

Added D3.js to the footer of the site.

--- src/profanity_power_index/site_generator.clj
+++ src/profanity_power_index/site_generator.clj
@@ -108,6 +108,9 @@
                 " and "
                 (link-to
                   "https://github.com/elastic/elasticsearch" "Elasticsearch. ")
+                " visualization built with "
+                (link-to
+                  "https://d3js.org/" "D3.js. ")
                 "Check out the code on "
                 (link-to
                   "https://www.github.com/timothyrenner/ProfanityPowerIndex"


make code a little lispier :heart_eyes_cat:

--- src/metabase/driver/query_processor.clj
+++ src/metabase/driver/query_processor.clj
@@ -170,7 +170,7 @@
   [results]
   {:pre [(map? results)
          (sequential? (:rows results))]}
-  (assoc results :rows (take max-result-rows (:rows results))))
+  (update-in results [:rows] (partial take max-result-rows)))

 ;; ### ADD-ROW-COUNT-AND-STATUS


how did that fix actually work :scream:?

--- src/metabase/driver/query_processor.clj
+++ src/metabase/driver/query_processor.clj
@@ -128,7 +128,6 @@
     query
     ;; If we're doing a "rows" aggregation with no breakout or fields clauses add one that will exclude Fields that are supposed to be hidden
     (do (swap! *internal-context* assoc :fields-is-implicit true)
-        (println "---------------------------------------- INTERNAL CONTEXT >>>> " @*internal-context*)
         (assoc query :fields (sel :many :id Field :table_id source_table, :active true, :preview_display true,
                                   :field_type [not= "sensitive"], (order :position :asc), (order :id :desc))))))

@@ -341,7 +340,6 @@
   [{{source-table :source_table, breakout-field-ids :breakout, field-field-ids :fields} :query} castified-field-names]
   {:post [(every? keyword? %)]}
   (try
-    (println "FIELDS-IS-IMPLICIT? >>>>" @*internal-context*)
     (-order-columns (sel :many :fields [Field :id :name :position] :table_id source-table)
                     breakout-field-ids
                     (when-not (:fields-is-implicit @*internal-context*) field-field-ids)


New model for callback functions. They should not modify state of response but return what is to be delivered (status, headers, ..) and action to execute (nil, :abort).

--- src/async/http/client/request.clj
+++ src/async/http/client/request.clj
@@ -240,7 +240,7 @@
     resp))

 (defn new-execute-request
-  "Executes provided requests.
+  "Executes provided request.
   Arguments:
   - req        - request to be executed
   - :status    - status callback
@@ -265,24 +265,34 @@
      (proxy [AsyncHandler] []
        (onStatusReceived
         [#^HttpResponseStatus e]
-        (convert-action (status resp (convert-status-to-map e))))
+        (let [[result action] (status resp (convert-status-to-map e))]
+          (deliver (:status resp) result)
+          (convert-action action)))
        (onHeadersReceived
         [#^HttpResponseHeaders e]
-        (convert-action (headers resp (convert-headers-to-map e))))
+        (let [[result action] (headers resp (convert-headers-to-map e))]
+          (deliver (:headers resp) result)
+         (convert-action action)))
        (onBodyPartReceived
         [#^HttpResponseBodyPart e]
         (when-let [bytes (.getBodyPartBytes e)]
           (let [length (alength bytes)
                 baos (ByteArrayOutputStream. length)]
             (.write baos bytes 0 alength)
-            (convert-action (part resp baos)))))
+            (let [[result action] (part resp baos)
+                  body (:body resp)]
+              (if-not (delivered? body)
+                (deliver body result))
+              (convert-action action)))))
        (onCompleted
         []
+        ;; TODO this is wrong, no call to completed
         (deliver (:done resp) true))
        (onThrowable
         [#^Throwable t]
         (do
           (print-cause-trace t)
+          ;; TODO this needs to deliver as well
           (error resp t)))))
     ^{:started (System/currentTimeMillis)}
     resp))


fix number of args

fix number of args

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

--- src/aurora/examples/todomvc2.cljs
+++ src/aurora/examples/todomvc2.cljs
@@ -190,7 +190,7 @@
              (when "ui/onChange" "toggle-all" 'value)
              (when "eve/compute" 'final "value == \"true\" ? \"completed\" : \"active\" ")
              (change ["todo-completed" 'todo 'complete?]
-                     ["current-toggle" 'todo 'final]))
+                     ["current-toggle" 'final]))

        (rule clear-completed-clicked
              (when "ui/onClick" "clear-completed")


Fixed a cyclic dependency with neo4j

Fixed a cyclic dependency with neo4j

--- src/webapp/framework/server/neo4j_helper.clj
+++ src/webapp/framework/server/neo4j_helper.clj
@@ -2,7 +2,6 @@

   [:require [clojure.string :as str]]
   [:use [korma.db]]
-  [:use [webapp.framework.server.systemfns]]
   [:use [webapp.framework.server.email-service]]
   [:use [webapp.framework.server.encrypt]]
   [:use [korma.core]]


Fix formatting

Fix formatting

--- src/braid/base/server/cqrs_fx.clj
+++ src/braid/base/server/cqrs_fx.clj
@@ -5,7 +5,7 @@
     [braid.core.server.sync-helpers :as helpers]
     [braid.core.server.db :as db]))

-(def run-txns! db/run-txns! )
+(def run-txns! db/run-txns!)

 (def chsk-send! socket/chsk-send!)


use run! macro for side-effect ratom

use run! macro for side-effect ratom

--- src/braid/ui/views/pages/tag.cljs
+++ src/braid/ui/views/pages/tag.cljs
@@ -1,6 +1,6 @@
 (ns braid.ui.views.pages.tag
   (:require [reagent.core :as r]
-            [reagent.ratom :include-macros true :refer-macros [reaction]]
+            [reagent.ratom :include-macros true :refer-macros [reaction run!]]
             [chat.client.store :as store]
             [chat.client.dispatcher :refer [dispatch!]]
             [chat.client.reagent-adapter :refer [subscribe]]
@@ -37,9 +37,8 @@
                                       (partial map :created-at)
                                       :messages))
                               reverse))
-        dummy (reaction (do (when-let [tag-id @page-id]
-                              (dispatch! :threads-for-tag {:tag-id tag-id}))
-                            nil))]
+        dummy (run! (when-let [tag-id @page-id]
+                      (dispatch! :threads-for-tag {:tag-id tag-id})))]
     (fn []
       (let [status (cond
                      @loading? :loading


index document size

index document size

fixes https://github.com/brainbot-com/es-nozzle/issues/12

--- src/brainbot/nozzle/esconnect.clj
+++ src/brainbot/nozzle/esconnect.clj
@@ -41,6 +41,7 @@
                     :store true,
                     :omit_norms true},
              :lastmodified {:type "date", :store "yes"},
+             :size {:type "long", :store "yes"},
              :content {:type "string", :store "yes"},
              :content_type {:type "string", :store "yes" :index "not_analyzed"},
              :extension {:type "string", :store "yes" :index "not_analyzed"},
@@ -260,7 +261,8 @@
               :tags (get-tags-from-path directory)
               :allow_token_document (simple-perms :allow)
               :deny_token_document (simple-perms :deny)
-              :lastmodified (mtime->lastmodified (get-in entry [:stat :mtime]))})))
+              :lastmodified (mtime->lastmodified (get-in entry [:stat :mtime]))
+              :size (get-in entry [:stat :size])})))


commented out some dependency stuff

commented out some dependency stuff

--- src/clj/forma/source/logistic.clj
+++ src/clj/forma/source/logistic.clj
@@ -1,23 +1,23 @@
 (ns forma.source.logistic
-  (:use [clojure-csv.core])
   (:require [incanter.core :as i]))

-(def mys-data (let [file "/Users/danhammer/Desktop/testmys/allmys.txt"]
-                (map
-                 (partial map #(Float/parseFloat %))
-                 (parse-csv
-                  (slurp file)))))
+;; (:use [clojure-csv.core])
+;; (def mys-data (let [file "/Users/danhammer/Desktop/testmys/allmys.txt"]
+;;                 (map
+;;                  (partial map #(Float/parseFloat %))
+;;                  (parse-csv
+;;                   (slurp file)))))

-(def mys-labels (take 1000000 (map last mys-data)))
-(def mys-features (take 1000000 (map butlast mys-data)))
+;; (def mys-labels (take 1000000 (map last mys-data)))
+;; (def mys-features (take 1000000 (map butlast mys-data)))

-(defn make-binary
-  [coll]
-  (map #(if (> % 0) 1 0) coll))
+;; (defn make-binary
+;;   [coll]
+;;   (map #(if (> % 0) 1 0) coll))

-(def y (make-binary mys-labels))
-(def X (map (partial cons 1) (take 235469 mys-features)))
-(def beta (repeat 23 0))
+;; (def y (make-binary mys-labels))
+;; (def X (map (partial cons 1) (take 235469 mys-features)))
+;; (def beta (repeat 23 0))

 (defn feature-vec
   [n]
@@ -105,10 +105,10 @@
 ;; (logistic-beta-vector (label-vec 100000) (feature-vec 100000) 0.00000001)

 ;; In the meantime, this is a problem ...
-;; (def X-rand (feature-vec 100000))
-;; (def y-rand (label-vec 100000))
-;; (time (total-log-likelihood beta y-rand X-rand))
-;; =>"Elapsed time: 3320.955 msecs"
+(def X-rand (feature-vec 100000))
+(def y-rand (label-vec 100000))
+(time (total-log-likelihood beta y-rand X-rand))
+=>"Elapsed time: 3320.955 msecs"

 ;; (def X-rand (feature-vec 100000))
 ;; (def y-rand (label-vec 100000))


(PDB-3323) Make report exists query use index

While this query was correct, it didn't use the index we have in place on this
column, making it very slow.

--- src/puppetlabs/puppetdb/scf/storage.clj
+++ src/puppetlabs/puppetdb/scf/storage.clj
@@ -1194,8 +1194,8 @@
                 report-hash (shash/report-identity-hash report)]
            (jdbc/with-db-transaction []
              (let [shash (sutils/munge-hash-for-storage report-hash)]
-               (when-not (-> "select 1 from reports where hash = ? limit 1"
-                             (query-to-vec shash)
+               (when-not (-> "select 1 from reports where encode(hash, 'hex'::text) = ? limit 1"
+                             (query-to-vec report-hash)
                              seq)
                  (let [certname-id (certname-id certname)
                        row-map {:hash shash


changed the country-tile map so that the keys are sets; wrote a function to get unique tiles, given a list of country codes.


Keep alive only for html

Keep alive only for html

--- src/clj/fortress/ring/writers.clj
+++ src/clj/fortress/ring/writers.clj
@@ -90,7 +90,7 @@
       (HttpHeaders/setContentLength response (.length body))
       (.write channel response)
       (-> (.writeAndFlush channel response-body)
-          (add-close-listener response)))))
+          (.addListener ChannelFutureListener/CLOSE)))))

 (extend-type nil
   ResponseWriter


prevent flipping Jinteki Biotech more than once per game

--- src/clj/game/cards-identities.clj
+++ src/clj/game/cards-identities.clj
@@ -271,7 +271,6 @@
                  :req (req (not (:biotech-used card)))
                  :label "Flip this identity"
                  :effect (req (let [flip (:biotech-target card)]
-                                (update! state side (assoc card :biotech-used true))
                                 (case flip
                                   "[The Brewery~brewery]"
                                   (do (system-msg state side "uses [The Brewery~brewery] to do 2 net damage")
@@ -289,7 +288,8 @@
                                         state side
                                         {:prompt "Choose a card that can be advanced"
                                          :choices {:req can-be-advanced?}
-                                         :effect (effect (add-prop target :advance-counter 4 {:placed true}))} card nil)))))}]}
+                                         :effect (effect (add-prop target :advance-counter 4 {:placed true}))} card nil)))
+                                (update! state side (assoc (get-card state card) :biotech-used true))))}]}

    "Kate \"Mac\" McCaffrey: Digital Tinker"
    {:effect (effect (gain :link 1))


fix Snatch&Grab tag to be unpreventable

fix Snatch&Grab tag to be unpreventable

--- src/clj/game/cards-operations.clj
+++ src/clj/game/cards-operations.clj
@@ -444,7 +444,8 @@
                                                 (if (= target "Yes")
                                                   {:msg (msg "take 1 tag to prevent " (:title c)
                                                              " from being trashed")
-                                                   :effect (effect (tag-runner :runner 1))}
+                                                   ; use gain tag instead of tag-runner since S&G tag is unpreventable
+                                                   :effect (effect (gain :runner :tag 1))}
                                                   {:effect (trash state side c) :msg (msg "trash " (:title c))})
                                                 card nil))}
                              card nil)))}}


Remove duplicate reference links

Remove duplicate reference links

--- src/cljs/asciinema_player/vt.cljs
+++ src/cljs/asciinema_player/vt.cljs
@@ -282,11 +282,3 @@
                 actions (remove nil? [exit-action transition-action entry-action])]
             [new-state actions])
           [current-state (if transition-action [transition-action] [])])))))
-
-;; References:
-;; http://en.wikipedia.org/wiki/ANSI_escape_code
-;; http://ttssh2.sourceforge.jp/manual/en/about/ctrlseq.html
-;; http://real-world-systems.com/docs/ANSIcode.html
-;; http://www.shaels.net/index.php/propterm/documents
-;; http://manpages.ubuntu.com/manpages/lucid/man7/urxvt.7.html
-;; http://vt100.net/docs/vt102-ug/chapter5.html


Always simulate actions based on p1

Always simulate actions based on p1

--- src/cljs/battle_console/game.cljs
+++ src/cljs/battle_console/game.cljs
@@ -256,8 +256,7 @@
                  (assoc :p2-focused-board (= player-code "p2"))
                  (assoc :action-focus player-code))
         jsgame (js/encodeURIComponent (.stringify js/JSON (clj->js game)))
-        url (str "http://rules.api.orionsbelt.eu/game/turn/" player-code "?context=" jsgame)]
-    (println game)
+        url (str "http://rules.api.orionsbelt.eu/game/turn/" "p1" "?context=" jsgame)]
     (state/set-state :processing-action action)
     (GET url {:handler action-added
               :error-handler error-loading-action})))


Fix order of "No action / Action before access"... again.

--- src/cljs/netrunner/gameboard.cljs
+++ src/cljs/netrunner/gameboard.cljs
@@ -862,11 +862,11 @@
                            (cond-button "Jack Out" (not (get-in cursor [:run :cannot-jack-out]))
                                         #(send-command "jack-out"))]
                           [:div.panel.blue-shade
-                           (cond-button "No more action" (not (:no-action run))
-                                        #(send-command "no-action"))
                            (when (zero? (:position run))
                              (cond-button "Action before access" (not (:no-action run))
-                                          #(send-command "corp-phase-43")))]))
+                                          #(send-command "corp-phase-43")))
+                           (cond-button "No more action" (not (:no-action run))
+                                        #(send-command "no-action"))]))
                       [:div.panel.blue-shade
                        (if (= (keyword active-player) side)
                          (when (and (zero? (:click me)) (not end-turn) (not runner-phase-12) (not corp-phase-12))


Add file upload feature to file block

Add file upload feature to file block

--- src/cljs/salava/page/ui/edit.cljs
+++ src/cljs/salava/page/ui/edit.cljs
@@ -1,5 +1,6 @@
 (ns salava.page.ui.edit
   (:require [reagent.core :refer [atom cursor create-class]]
+            [reagent-modals.modals :as m]
             [salava.core.ui.ajax-utils :as ajax]
             [cljs-uuid-utils.core :refer [make-random-uuid uuid-string]]
             [salava.core.ui.layout :as layout]
@@ -8,6 +9,7 @@
             [salava.core.i18n :as i18n :refer [t]]
             [salava.core.helper :refer [dump]]
             [salava.page.ui.helper :as ph]
+            [salava.file.ui.my :as file]
             [salava.file.icons :refer [file-icon]]))

 (defn random-key []
@@ -61,6 +63,23 @@
     (if file
       (update-block-value block-atom :files (conj (vec (:files @block-atom)) (assoc file :key (random-key)))))))

+(defn send-file [files-atom block-atom]
+  (let [file (-> (.querySelector js/document (str "#upload-file-" (:key @block-atom)))
+                 .-files
+                 (.item 0))
+        form-data (doto
+                    (js/FormData.)
+                    (.append "file" file (.-name file)))]
+    (m/modal! (file/upload-modal nil (t :file/Uploadingfile) (t :file/Uploadinprogress)))
+    (ajax/POST
+      "/obpv1/file/upload"
+      {:body    form-data
+       :handler (fn [{:keys [status message reason data]} response]
+                  (when (= status "success")
+                    (reset! files-atom (conj @files-atom data))
+                    (select-file block-atom @files-atom (:id data)))
+                  (m/modal! (file/upload-modal status message reason)))})))
+
 (defn remove-file [files-atom file]
   (reset! files-atom (vec (remove #(= % file) @files-atom))))

@@ -94,7 +113,7 @@
         format (get-in @block-atom [:format] "short")
         sort-by (get-in @block-atom [:sort] "name")
         tagged-badges (->> @badges
-                         (filter #(some (fn [t] (= t tag)) (:tags %))))]
+                           (filter #(some (fn [t] (= t tag)) (:tags %))))]
     [:div.form-group
      [:div.col-xs-8
       [:div.badge-select
@@ -124,27 +143,38 @@

 (defn edit-block-files [block-atom files]
   [:div
-   [:div.edit-block-files
-    (for [file (:files @block-atom)]
-      [:div.row
-       [:div.col-xs-6
-        [:i {:class (str "page-file-icon fa " (file-icon (:mime_type file)))}]
-        [:a {:href (str "/" (:path file))
-             :target "_blank"}
-         (:name file)]]
-       [:div.col-xs-6
-        [:span {:class "remove-file-icon"
-                :on-click #(remove-file (cursor block-atom [:files]) file)}
-         [:i {:class "fa fa-close"}]]]])]
+   (into
+     [:div.edit-block-files]
+     (for [file (:files @block-atom)]
+       [:div.row
+        [:div.col-xs-6
+         [:i {:class (str "page-file-icon fa " (file-icon (:mime_type file)))}]
+         [:a {:href (str "/" (:path file))
+              :target "_blank"}
+          (:name file)]]
+        [:div.col-xs-6
+         [:span {:class "remove-file-icon"
+                 :on-click #(remove-file (cursor block-atom [:files]) file)}
+          [:i {:class "fa fa-close"}]]]]))
    [:div.form-group
     [:div.col-xs-12
      [:div.file-select
       [:select {:class "form-control"
                 :value ""
                 :on-change #(select-file block-atom @files (js/parseInt (.-target.value %)))}
-       [:option {:value ""} (t "-" :page/none "-")]
+       [:option {:value ""} "- " (t :page/choosefile) " -"]
        (for [file @files]
-         [:option {:value (:id file) :key (:id file)} (:name file)])]]]]])
+         [:option {:value (:id file) :key (:id file)} (:name file)])]]]]
+   [:div.form-group
+    [:div.col-xs-12
+     [:button {:class "btn btn-primary"
+               :on-change #(.preventDefault %)}
+      (t :page/oruploadnewfile)]
+     [:input {:id        (str "upload-file-" (:key @block-atom))
+              :class     "page-file-upload"
+              :type      "file"
+              :name      "file"
+              :on-change #(send-file files block-atom)}]]]])

 (defn edit-block-text [block-atom]
   (let [content (:content @block-atom)]
@@ -273,6 +303,7 @@
 (defn content [state]
   (let [{:keys [id name]} (:page @state)]
     [:div {:id "page-edit"}
+     [m/modal-window]
      [ph/edit-page-header (t :page/Editpage ": " name)]
      [ph/edit-page-buttons id :content (fn [next-url] (save-page (:page @state) next-url))]
      [page-form state]]))


stats computation fixed

stats computation fixed

--- src/clueweb_disqus/read_stats.clj
+++ src/clueweb_disqus/read_stats.clj
@@ -4,6 +4,7 @@
   (:require [clj-time.core :as t]
             [clj-time.coerce :as c]
             [clojure.java.io :as io]
+            [clojure.set :as c-set]
             [clueweb-disqus.core :as core])
   (:use [clojure.pprint :only [pprint]]
         [incanter core stats charts io]))
@@ -35,15 +36,16 @@
                               (re-find #"all.downloaded" (.getAbsolutePath f)))
                              (re-find #".downloaded$" (.getAbsolutePath f))))
                           (file-seq (java.io.File. core/disqus-jobs-dir)))]
-    (reduce
-     (fn [acc f]
-       (+
-        acc
-        (with-open [rdr (io/reader f)]
-          (count
-           (line-seq rdr)))))
-     0
-     downloaded-files)))
+    (count
+     (doall
+      (reduce
+       (fn [acc f]
+         (c-set/union
+          acc
+          (with-open [rdr (io/reader f)]
+            (set (line-seq rdr)))))
+       (set [])
+       downloaded-files)))))

 (defn generate-samples
   []


CMR-179: Added constants for the number of threads to use with jetty. This is needed to know config options for peristent http.

--- src/cmr/common/api/web_server.clj
+++ src/cmr/common/api/web_server.clj
@@ -4,6 +4,20 @@
             [ring.adapter.jetty :as jetty]
             [cmr.common.log :refer (debug info warn error)])
   (:import org.eclipse.jetty.server.Server))
+
+(def MIN_THREADS
+  "The minimum number of threads for Jetty to use to process requests. The was originally set to the
+  ring jetty adapter default of 8."
+  8)
+
+(def MAX_THREADS
+  "The maximum number of threads for Jetty to use to process requests. This was originally set to
+  the ring jetty adapter default of 50.
+
+  VERY IMPORTANT NOTE: The value set here must correspond to the number of persistent HTTP
+  connections we use in the transmit library. Do not change this or refactor this code without
+  making sure that the transmit library uses the same amount."
+  50)

 (defrecord WebServer
   [
@@ -23,7 +37,10 @@
     [this system]
     (let [{:keys [port routes-fn]} this
           routes (routes-fn system)
-          server (jetty/run-jetty routes {:port port :join? false})]
+          server (jetty/run-jetty routes {:port port
+                                          :join? false
+                                          :min-threads MIN_THREADS
+                                          :max-threads MAX_THREADS})]
       (info "Jetty started on port" port)
       (assoc this :server server)))


Catch exceptions looking for hooks, not just loading them.

--- src/leiningen/core.clj
+++ src/leiningen/core.clj
@@ -77,13 +77,13 @@
        #'task-not-found))))

 (defn- load-hooks []
-  (doseq [n (sort (find-namespaces-on-classpath))
-          :when (re-find #"^leiningen\.hooks\." (name n))]
-    (try (require n)
-         (catch Exception e
-           (when-not (empty? (.list (File. "lib")))
-             (println "Warning: problem requiring hooks:" n (.getMessage e))
-             (println "...continuing without hooks completely loaded."))))))
+  (try (doseq [n (sort (find-namespaces-on-classpath))
+               :when (re-find #"^leiningen\.hooks\." (name n))]
+         (require n))
+       (catch Exception e
+         (when-not (empty? (.list (File. "lib")))
+           (println "Warning: problem requiring hooks:" (.getMessage e))
+           (println "...continuing without hooks completely loaded.")))))

 (defn ns->path [n]
   (str (.. (str n)


Move copy-out-loop into repl-client.

Move copy-out-loop into repl-client.

--- src/leiningen/repl.clj
+++ src/leiningen/repl.clj
@@ -52,7 +52,7 @@
              .start)
            (format "REPL started; server listening on %s:%s." ~host ~port)))))

-(defn- copy-out-loop [reader]
+(defn copy-out-loop [reader]
   (let [buffer (make-array Character/TYPE 1000)]
     (loop []
       (.write *out* buffer 0 (.read reader buffer))
@@ -61,16 +61,17 @@
       (recur))))

 (defn repl-client [reader writer]
-  (let [input (read-line)]
-    (when (and input (not= "" input))
-      (.write writer (str input "\n"))
-      (.flush writer)
-      (recur reader writer))))
+  (.start (Thread. #(copy-out-loop reader)))
+  (loop [reader reader, writer writer]
+    (let [input (read-line)]
+      (when (and input (not= "" input))
+        (.write writer (str input "\n"))
+        (.flush writer)
+        (recur reader writer)))))

 (defn- connect-to-server [socket handler]
   (let [reader (InputStreamReader. (.getInputStream socket))
         writer (OutputStreamWriter. (.getOutputStream socket))]
-    (.start (Thread. #(copy-out-loop reader)))
     (handler reader writer)))

 (defn poll-repl-connection


Adding new schema supporting per-commit project versions.

This should provide the base we decided we needed for correct querying.

Unfortunately, this code runs about 10x slower for initial import and
differential updates.

--- src/leiningen/voom.clj
+++ src/leiningen/voom.clj
@@ -1036,10 +1036,11 @@
 ;; ===== relation database tables =====

 (pldb/db-rel r-branch repo-path branch-name sha)
-(pldb/db-rel r-commit ^:index sha ctime parent-count parents)
+(pldb/db-rel r-commit ^:index sha ctime parent-count)
 (pldb/db-rel r-commit-parent ^:index sha ^:index parent-sha)
 (pldb/db-rel r-commit-path ^:index sha ^:index path)
-(pldb/db-rel r-proj ^:index sha ^:index path ^:index name version has-snaps?)
+(pldb/db-rel r-proj-path ^:index sha ^:index path ^:index blob-sha)
+(pldb/db-rel r-proj ^:index blob-sha ^:index name version has-snaps?)

 (defmacro q
   [db & args]
@@ -1161,12 +1162,20 @@
                       (count (:parents commit)) (:parents commit))
         (->/for [parent (:parents commit)]
           (pldb/db-fact r-commit-parent sha parent))
-        (->/for [[path file-sha] (:paths commit)]
-          (->/when-let [[_ dir] (re-matches #"(.*)(^|/)project.clj" path)]
-            (->/apply pldb/db-fact
-                      r-proj sha dir (proj-fact-tail gitdir file-sha))))
+        (->/for [[mode bsha stage path]
+                 , (->> (git {:gitdir gitdir}
+                             "ls-files" "--stage" (str sha)
+                             "--" "project.clj" "**/project.clj")
+                        :lines
+                        (map #(s/split % #"\s+" 4)))
+                   :let [blob-sha (sha/mk bsha)]]
+          (->/as pldb
+            (pldb/db-fact r-proj-path sha (.intern ^String path) blob-sha)
+            (->/when-not (first (q pldb [x] (r-proj blob-sha _ _ _) (l/== x true)))
+              (->/apply pldb/db-fact
+                        r-proj blob-sha (proj-fact-tail gitdir blob-sha)))))
         (->/for [dir-path (set (mapcat sub-paths (keys (:paths commit))))]
-          (pldb/db-fact r-commit-path sha dir-path)))))
+          (pldb/db-fact r-commit-path sha (.intern ^String dir-path))))))

 (defn build-shabam
   [{:keys [shabam pldb]} tips]
@@ -1214,7 +1223,7 @@
           (build-shabam (vals new-branches))
           (vary-meta assoc ::dirty true))))))

-(def voomdb-header "voom-db-4")
+(def voomdb-header "voom-db-5")

 (defn ^File git-db-file
   [gitdir]
@@ -1231,7 +1240,7 @@
       {:shabam shabam
        :pldb
        , (vdb/from-reldata
-          [r-branch r-commit r-commit-parent r-commit-path r-proj]
+          [r-branch r-commit r-commit-parent r-commit-path r-proj-path r-proj]
           reldata)}
       (do
         (println "Existing voomdb file for" (str gitdir)


Support ttf fonts with only cp437 coverage

--- src/robinson/ui/components/robinson.clj
+++ src/robinson/ui/components/robinson.clj
@@ -1314,7 +1314,9 @@
         [vx vy]                                     (rc/pos->xy viewport-pos)
         lantern-on                                  (when-let [lantern (ri/inventory-id->item game-state :lantern)]
                                                       (= (get lantern :state :off) :on))
-        font-type                                   (get (rfont/current-font game-state) :type :ttf)]
+        font                                        (rfont/current-font game-state)
+        font-type                                   (or (get font :charset) (get font :type :ttf))]
+    (log/info (rfont/current-font game-state))
     (zc/csx
 	  [:terminal {} [
 		[:group {:id :app} [


Add coerce-code function.

Add coerce-code function.

--- src/multihash/core.clj
+++ src/multihash/core.clj
@@ -6,6 +6,8 @@
   (:import
     java.security.MessageDigest))

+
+;; ## Hash Function Algorithms

 (def ^:const digest-algorithms
   "Map of content hashing algorithms to system names and byte encodings."
@@ -21,6 +23,48 @@
   "True if the given code number is assigned to the application-specfic range."
   [code]
   (< 0 code 0x10))
+
+
+(defn- lookup-algo
+  "Look up algorithm details by code number."
+  [code]
+  (some #(when (= code (:code (val %)))
+           (assoc (val %) :name (key %)))
+        digest-algorithms))
+
+
+(defn- code->name
+  "Return a keyword corresponding to the given algorithm code."
+  [code]
+  (if (app-code? code)
+    (keyword (str "app-" code))
+    (:name (lookup-algo code))))
+
+
+(defn coerce-code
+  "Coerces the argument to a numeric algorithm code."
+  [value]
+  (cond
+    (keyword? value)
+    (or (:code (digest-algorithms value))
+        (throw (IllegalArgumentException.
+                 (str "Keyword " value
+                      " does not name a supported digest algorithm."))))
+
+    (not (integer? value))
+    (throw (IllegalArgumentException.
+             (str "Code value " (pr-str value)
+                  " is not a keyword or integer.")))
+
+    (app-code? value)
+    value
+
+    :else
+    (if-let [algo (lookup-algo value)]
+      (:code value)
+      (throw (IllegalArgumentException.
+               (str "Code value " value
+                    " does not represent a valid digest algorithm."))))))

@@ -65,22 +109,6 @@
       (let [data' (byte-array width)]
         (System/arraycopy data 0 data' 0 (count data))
         data'))))
-
-
-(defn- lookup-algo
-  "Look up algorithm details by code number."
-  [code]
-  (some #(when (= code (:code (val %)))
-           (assoc (val %) :name (key %)))
-        digest-algorithms))
-
-
-(defn- code->name
-  "Return a keyword corresponding to the given algorithm code."
-  [code]
-  (if (app-code? code)
-    (keyword (str "app-" code))
-    (:name (lookup-algo code))))


test mmss fn

test mmss fn


Reorganize lifecycle method lookups

Reorganize lifecycle method lookups

--- src/om_tools/core.cljx
+++ src/om_tools/core.cljx
@@ -32,23 +32,39 @@
        (some #(and (vector? %) (= k (first %))) args))))

 #+clj
+(def ^:private component-protocols
+  {'display-name       `om/IDisplayName
+   'init-state         `om/IInitState
+   'should-update      `om/IShouldUpdate
+   'will-mount         `om/IWillMount
+   'did-mount          `om/IDidMount
+   'will-unmount       `om/IWillUnmount
+   'will-update        `om/IWillUpdate
+   'did-update         `om/IDidUpdate
+   'will-receive-props `om/IWillReceiveProps
+   'render             `om/IRender
+   'render-state       `om/IRenderState})
+
+#+clj
+(def ^:private mixin-methods
+  {'display-name       :getDisplayName
+   'init-state         :getInitialState
+   'should-update      :shouldComponentUpdate
+   'will-mount         :componentWillMount
+   'did-mount          :componentDidMount
+   'will-unmount       :componentWillUnmount
+   'will-update        :componentWillUpdate
+   'did-update         :componentDidUpdate
+   'will-receive-props :componentWillReceiveProps})
+
+#+clj
 (defn add-component-protocols [forms]
-  (let [protocols {'display-name       `om/IDisplayName
-                   'init-state         `om/IInitState
-                   'should-update      `om/IShouldUpdate
-                   'will-mount         `om/IWillMount
-                   'did-mount          `om/IDidMount
-                   'will-unmount       `om/IWillUnmount
-                   'will-update        `om/IWillUpdate
-                   'did-update         `om/IDidUpdate
-                   'will-receive-props `om/IWillReceiveProps
-                   'render             `om/IRender
-                   'render-state       `om/IRenderState}]
-    (mapcat (fn [form]
-              (if-let [protocol (when (seq? form) (protocols (first form)))]
-                [protocol form]
-                [form]))
-            forms)))
+  (mapcat
+   (fn [form]
+     (if-let [protocol (when (seq? form) (component-protocols (first form)))]
+       [protocol form]
+       [form]))
+   forms))

 #+clj
 (defn convenience-constructor [f ctor-sym]
@@ -62,18 +78,6 @@
                     ~(if ctor-sym
                        `(merge {:ctor ~ctor-sym} ~map-sym)
                        map-sym))))))
-
-#+clj
-(def mixin-methods
-  {'display-name       :getDisplayName
-   'init-state         :getInitialState
-   'should-update      :shouldComponentUpdate
-   'will-mount         :componentWillMount
-   'did-mount          :componentDidMount
-   'will-unmount       :componentWillUnmount
-   'will-update        :componentWillUpdate
-   'did-update         :componentDidUpdate
-   'will-receive-props :componentWillReceiveProps})

 #+clj
 (defn mixin-constructor [f mixins]


Reduce line count with doto.

Reduce line count with doto.

--- src/klangmeister/instruments.cljs
+++ src/klangmeister/instruments.cljs
@@ -4,10 +4,8 @@

 (defn volume [peak]
   (fn [at context]
-    (let [node (.createGain context)]
-      (doto (.-gain node)
-        (.setValueAtTime peak at))
-      node)))
+    (doto (.createGain context)
+      (-> .-gain (.setValueAtTime peak at)))))

 (defn percuss [attack decay]
   (fn [at context]


Fix issue with meta

Fix issue with meta

--- src/paredit/parser.clj
+++ src/paredit/parser.clj
@@ -345,7 +345,6 @@
                ;(p/unspaced open-string #"(?:\\.|[^\\\"])++(?!\")" :? eof)
                ;(p/unspaced open-regex #"(?:\\.|[^\\\"])++(?!\")" :? eof)
                [open-quote eof]
-               [open-meta :expr :? eof]
                [open-deprecated-meta :expr :? eof]
                [open-deref eof]
                [open-syntax-quote eof]
@@ -359,7 +358,9 @@
     :map [open-map :expr* "}"]
     :set [open-set :expr* "}"]
     :quote [open-quote :expr]
-    :meta [open-meta :expr :expr]
+    :open-meta "^"
+    :meta-prefix [:open-meta :expr]
+    :meta [:meta-prefix :expr]
     :deref [open-deref :expr]
     :syntax-quote [open-syntax-quote :expr]
     :var [open-var :expr]


Add tests to make sure 404 works when either the dataset or slice does not exist

--- test/cfpb/qu/handler_test.clj
+++ test/cfpb/qu/handler_test.clj
@@ -52,6 +52,12 @@
              => (contains {:status 200
                            :headers {"Content-Type" "application/xml;charset=UTF-8"}}))

+       (fact "it returns a 404 when the dataset does not exist"
+             (prerequisite (#'cfpb.qu.data/get-metadata "bad-dataset") => nil)
+
+             (app (request :get "/data/bad-dataset/what"))
+             => (contains {:status 404}))
+
        (fact "it returns a 404 when the slice does not exist"
              (prerequisite (#'cfpb.qu.data/get-metadata "good-dataset") => {:slices {}})


RANGE non-error case works

RANGE non-error case works

--- test/structural_typing/guts/mechanics/f_compiling_types.clj
+++ test/structural_typing/guts/mechanics/f_compiling_types.clj
@@ -4,7 +4,7 @@
             [structural-typing.guts.preds.annotated :refer [show-as]]
             [structural-typing.surface.oopsie :as oopsie]
             [structural-typing.guts.mechanics.canonicalizing-types :refer [canonicalize]]
-            [structural-typing.guts.paths.elements :refer [ALL]])
+            [structural-typing.guts.paths.elements :refer [ALL RANGE]])
   (:require [blancas.morph.monads :as e])
   (:use midje.sweet))

@@ -32,6 +32,67 @@
     (oopsie/explanations oopsies) => [":x should be `pos?`; it is `\"string\"`"]))

+(fact "handling ALL"
+  (let [type-checker (subject/compile-type (canonicalize {} [[:points ALL :x]]
+                                                         {[:points ALL :x] even?}))]
+    (oopsie/explanations (type-checker {:points [{:x 1} {:x 2} {:x 3} {:y 1}]}))
+    => (just "[:points 0 :x] should be `even?`; it is `1`"
+             "[:points 2 :x] should be `even?`; it is `3`"
+             "[:points 3 :x] must exist and be non-nil"
+             :in-any-order)))
+
+  (fact "a path with multiple values (RANGE)"
+    (fact "simple case"
+      (let [type-checker (subject/compile-type (canonicalize {}
+                                                             {[(RANGE 2 4)] even?}))]
+        (fact "a range avoids broken values"
+          (oopsie/explanations (type-checker [:wrong :wrong 2 4 :wrong])) => empty?)
+
+        (fact "... but allows processing of values within the range"
+          (oopsie/explanations (type-checker [:wrong :wrong 0 41 :wrong]))
+          => (just "[3] should be `even?`; it is `41`"))))
+
+    (fact "multiple ranges"
+      (let [type-checker (subject/compile-type (canonicalize {}
+                                                             {[(RANGE 2 4) (RANGE 1 2)] even?}))]
+        (fact "a range avoids broken values"
+          (oopsie/explanations (type-checker [:wrong :wrong [:wrong 2 :wrong] [:wrong 4] :wrong])) => empty?)
+
+        (fact "... but allows processing of values within the range"
+          (oopsie/explanations (type-checker [:wrong :wrong [:wrong 1 :wrong] [:wrong 3]]))
+          => (just "[2 1] should be `even?`; it is `1`"
+                   "[3 1] should be `even?`; it is `3`"))))
+
+    (fact "combination of RANGE and ALL"
+      (let [type-checker (subject/compile-type (canonicalize {}
+                                                             {[(RANGE 2 4) ALL] even?}))]
+        (fact "a range avoids broken values"
+          (oopsie/explanations (type-checker [:wrong :wrong [2 4 6] [4] :wrong])) => empty?)
+
+        (fact "... but allows processing of values within the range"
+          (oopsie/explanations (type-checker [:wrong :wrong [0 1 2] [2 3]]))
+          => (just "[2 1] should be `even?`; it is `1`"
+                   "[3 1] should be `even?`; it is `3`"))))
+
+    (fact "including other path elements"
+      (let [type-checker (subject/compile-type
+                          (canonicalize {}
+                                        {[:a (RANGE 1 3) :b (RANGE 1 5) pos?] even?}))]
+        (fact "a range avoids broken values"
+          (oopsie/explanations (type-checker {:a [:wrong
+                                                  {:b [1  2  2  2  2 1]}
+                                                  {:b [1 -1 -1 -1 -1 1]}
+                                                  :wrong]})) => empty?)
+
+        (fact "... but allows processing of values within the range"
+          (oopsie/explanations (type-checker {:a [:wrong
+                                                  {:b [1  2  2  2  3 1]}
+                                                  {:b [1 -1 -1  5 -1 1]}
+                                                  :wrong]}))
+          => (just "[:a 1 :b 4 pos?] should be `even?`; it is `3`"
+                   "[:a 2 :b 3 pos?] should be `even?`; it is `5`")))))
+
+
 (fact "compiling a whole type"
   (fact "Simple case"
     (oopsie/explanations ((subject/compile-type (canonicalize {} [:a])) {}))
@@ -55,46 +116,54 @@
       (oopsie/explanations (odd-and-exists {:a "hi"})) => (just "[:a :b] must exist and be non-nil")
       (oopsie/explanations (odd-and-exists {:a {:b 2}})) => (just "[:a :b] should be `odd?`; it is `2`")
       (oopsie/explanations (odd-and-exists {:a {:b 3}})) => empty?))
-
-  (fact "a path with multiple values (ALL)"
-    (let [type (subject/compile-type (canonicalize {} [[:points ALL :x]]
-                                                   {[:points ALL :x] even?}))]
-      (oopsie/explanations (type {:points [{:x 1} {:x 2} {:x 3} {:y 1}]}))
-      => (just "[:points 0 :x] should be `even?`; it is `1`"
-               "[:points 2 :x] should be `even?`; it is `3`"
-               "[:points 3 :x] must exist and be non-nil"
-               :in-any-order)))
-

   (fact "multiple paths in the type"
-    (let [type (subject/compile-type (canonicalize {} {:color string?
+    (let [type-checker (subject/compile-type (canonicalize {} {:color string?
                                                        :point {:x integer?
                                                                :y integer?}}))]
-      (oopsie/explanations (type {})) => empty? ; all optional
-      (oopsie/explanations (type {:color "green"})) => empty?
-      (oopsie/explanations (type {:color 1})) => (just ":color should be `string?`; it is `1`")
-      (oopsie/explanations (type {:color "green"
+      (oopsie/explanations (type-checker {})) => empty? ; all optional
+      (oopsie/explanations (type-checker {:color "green"})) => empty?
+      (oopsie/explanations (type-checker {:color 1})) => (just ":color should be `string?`; it is `1`")
+      (oopsie/explanations (type-checker {:color "green"
                            :point {:x "1"
                                    :y "2"}}))
       => (just "[:point :x] should be `integer?`; it is `\"1\"`"
                "[:point :y] should be `integer?`; it is `\"2\"`"
-               :in-any-order)))
+               :in-any-order))))

-  (fact "a path that can't be applied produces an error"
-    (let [type (subject/compile-type (canonicalize {} [[:x ALL :y]]))]
-      (type {:x 1}) => (just (contains {:leaf-value nil
-                                        :path [:x ALL :y]
-                                        :whole-value {:x 1}}))
-      (oopsie/explanations (type {:x 1})) => (just "[:x ALL :y] is not a path into `{:x 1}`")
-      (oopsie/explanations (type {:x :a})) => (just "[:x ALL :y] is not a path into `{:x :a}`")

+
+
+(fact "a path that can't be applied produces an error"
+  (fact "ALL"
+    (let [type-checker (subject/compile-type (canonicalize {} [[:x ALL :y]]))]
+      (type-checker {:x 1}) => (just (contains {:leaf-value nil
+                                                :path [:x ALL :y]
+                                                :whole-value {:x 1}}))
+      (oopsie/explanations (type-checker {:x 1})) => (just "[:x ALL :y] is not a path into `{:x 1}`")
+      (oopsie/explanations (type-checker {:x :a})) => (just "[:x ALL :y] is not a path into `{:x :a}`")
+
       (fact "these are fine, though"
-        (oopsie/explanations (type {:x [0]})) => (just "[:x 0 :y] must exist and be non-nil")
-        (type {:x []}) => empty?)
+        (oopsie/explanations (type-checker {:x [0]})) => (just "[:x 0 :y] must exist and be non-nil")
+        (type-checker {:x []}) => empty?)
+
+      (fact "A path containing an array complains if prefix doesn't exist"
+        (oopsie/explanations (type-checker {})) => (just #":x must exist"))
+
+      (fact "an unfortunate side effect of strings being collections"
+        (oopsie/explanations (type-checker {:x "string"}))
+        => (contains "[:x 0 :y] must exist and be non-nil"))))

-      (fact "A path containing an array complains if prefix doesn't exist"
-        (oopsie/explanations (type {})) => (just #":x must exist"))
+  (future-fact "RANGE"
+    (let [type-checker (subject/compile-type
+                        (canonicalize {}
+                                      {[:a (RANGE 1 4) :b (RANGE 1 5) pos?] even?}))]
+      (oopsie/explanations (type-checker {:a [:wrong :wrong
+                                              {:b [1  2  2  2  2 1]}
+                                              {:b [1 -1 -1 -1 -1 1]}
+                                              :wrong]})) => empty?)))

-      (fact "an unfortunate side effect of strings being collections"
-        (oopsie/explanations (type {:x "string"}))
-        => (contains "[:x 0 :y] must exist and be non-nil")))))
+
+
+
+


light refactoring, putting pieces in order

--- src/pronouns/pages.clj
+++ src/pronouns/pages.clj
@@ -31,15 +31,15 @@
   [subject reflexive]
   (render-sentence (wrap-pronoun (s/capitalize subject)) " threw the frisbee to " (wrap-pronoun reflexive) "."))

-
-(defn twitter-name [name]
-  [:a {:href (str "https://www.twitter.com/" name)} (str "@" name)])
-
-(defn contact-block []
-  [:div {:class "contact"}
-   [:p "Written by " (twitter-name "morganastra") " and " (twitter-name "thelseraphim") ". "
-   "Visit the project on " [:a {:href "https://github.com/witch-house/pronoun.is"} "github!"]]])
-
+(defn examples-block
+  [subject object possessive-determiner possessive-pronoun reflexive]
+  [:div {:class "examples"}
+   [:p [:h1 "Here are some usage examples for my pronouns:"]]
+   (subject-example subject)
+   (object-example object)
+   (posessive-determiner-example subject possessive-determiner)
+   (possessive-pronoun-example possessive-pronoun)
+   (reflexive-example subject reflexive)])

 (defn about-block []
   [:div {:class "about"}
@@ -51,17 +51,12 @@
    [:p "My name is Thel Seraphim, my " [:a {:href "http://pronoun.is/she"} "pronoun.is/she"] "."]
    [:p "My name is Morgan, my " [:a {:href "http://pronoun.is/ze/zir"} "pronoun.is/ze/zir"] "."]])

+(defn contact-block []
+  (let [twitter-name (fn [handle] [:a {:href (str "https://www.twitter.com/" handle)} (str "@" handle)])]
+  [:div {:class "contact"}
+   [:p "Written by " (twitter-name "morganastra") " and " (twitter-name "thelseraphim") ". "
+   "Visit the project on " [:a {:href "https://github.com/witch-house/pronoun.is"} "github!"]]]))

-
-(defn examples-block
-  [subject object possessive-determiner possessive-pronoun reflexive]
-  [:div {:class "examples"}
-   [:p [:h1 "Here are some usage examples for my pronouns:"]]
-   (subject-example subject)
-   (object-example object)
-   (posessive-determiner-example subject possessive-determiner)
-   (possessive-pronoun-example possessive-pronoun)
-   (reflexive-example subject reflexive)])

 (defn format-pronoun-examples
   [subject object possessive-determiner possessive-pronoun reflexive]


Tests test-process-select-product-page-existence, test-process-product-page-existence, test-process-add-new-product-page-existence, and test-process-add-new-chapter-page-existence

--- test/hurvinek/server_test.clj
+++ test/hurvinek/server_test.clj
@@ -75,3 +75,27 @@
         (is (callable? 'hurvinek.server/process-export-database))))

+(deftest test-process-select-product-page-existence
+    "Check that the hurvinek.server/process-select-product-page definition exists."
+    (testing "if the hurvinek.server/process-select-product-page definition exists."
+        (is (callable? 'hurvinek.server/process-select-product-page))))
+
+
+(deftest test-process-product-page-existence
+    "Check that the hurvinek.server/process-product-page definition exists."
+    (testing "if the hurvinek.server/process-product-page definition exists."
+        (is (callable? 'hurvinek.server/process-product-page))))
+
+
+(deftest test-process-add-new-product-page-existence
+    "Check that the hurvinek.server/process-add-new-product-page definition exists."
+    (testing "if the hurvinek.server/process-add-new-product-page definition exists."
+        (is (callable? 'hurvinek.server/process-add-new-product-page))))
+
+
+(deftest test-process-add-new-chapter-page-existence
+    "Check that the hurvinek.server/process-add-new-chapter-page definition exists."
+    (testing "if the hurvinek.server/process-add-new-chapter-page definition exists."
+        (is (callable? 'hurvinek.server/process-add-new-chapter-page))))
+
+


Whitespace

Whitespace

--- test/onyx/validation_test.clj
+++ test/onyx/validation_test.clj
@@ -9,15 +9,16 @@

 (def config (load-config))

-(def env-config (assoc (:env-config config)
-                       :onyx/id id
-                       :onyx.log/config {:appenders {:standard-out {:enabled? false}
-                                                     :spit {:enabled? false}}}))
+(def env-config
+  (assoc (:env-config config)
+         :onyx/id id
+         :onyx.log/config {:appenders {:standard-out {:enabled? false}
+                                       :spit {:enabled? false}}}))

 (def peer-config
   (assoc (:peer-config config)
-    :onyx/id id
-    :onyx.peer/job-scheduler :onyx.job-scheduler/balanced))
+         :onyx/id id
+         :onyx.peer/job-scheduler :onyx.job-scheduler/balanced))

 (def env (onyx.api/start-env env-config))


fixes typo in log level warn (#190)

fixes typo in log level warn (#190)

--- src/re_frame/core.cljc
+++ src/re_frame/core.cljc
@@ -160,6 +160,5 @@

 (defn register-sub
   [& args]
-  (console :warm  "re-frame:  \"register-sub\" is deprecated. Use \"reg-sub-raw\" (look for registration of " (str (first args)) ")")
+  (console :warn  "re-frame:  \"register-sub\" is deprecated. Use \"reg-sub-raw\" (look for registration of " (str (first args)) ")")
   (apply reg-sub-raw args))
-


Undo - correct bug in undo - use pos? and reuse undo? redo? in handlers

--- src/re_frame/undo.cljs
+++ src/re_frame/undo.cljs
@@ -36,11 +36,11 @@

 (defn undos?
   []
-  (>= (count @undo-list) 1))
+  (pos? (count @undo-list)))

 (defn redos?
   []
-  (> (count @redo-list) 0))
+  (pos? (count @redo-list)))

 ;; -- subscriptions  -----------------------------------------------------------------------------
@@ -66,9 +66,9 @@
   :undo                ;; usage:  (dispatch [:undo])
   (fn handler
     [_ _]
-    (when (> (count @undo-list) 0)
+    (when (undos?)
+      (reset! redo-list (cons @app-db @redo-list))
       (reset! app-db (last @undo-list))
-      (reset! redo-list (cons @app-db @redo-list))
       (reset! undo-list (pop @undo-list)))))

@@ -76,7 +76,7 @@
   :redo                ;; usage:  (dispatch [:redo])
   (fn handler
     [_ _]
-    (when (> (count @redo-list) 0)
+    (when (redos?)
       (reset! app-db (first @redo-list))
       (reset! redo-list (rest @redo-list))
       (reset! undo-list (conj @undo-list @app-db)))))


include content-sha in translation test

include content-sha in translation test

--- test/tranjlator/bing_test.clj
+++ test/tranjlator/bing_test.clj
@@ -13,13 +13,8 @@
                    :translator (->translator :de (chan 1))))
           translator (get-in system [:translator])]
       (a/>!! (:ctrl-chan translator)
-             {:content "Hello" :language "en"})
+             {:content "Hello" :language "en"
+              :content-sha "9b71d224bd62f3785d96d46ad3ea3d73319bfbc2890caadae2dff72519673ca72323c3d99ba5c11d7c7acc6e14b8c5da0c4663475c2e5c3adef46f73bcdec043"})
       (is (= "Hallo"
              (:content (a/<!! (:out-chan translator))))))))

-(deftest t-store-translations
-
-  (testing "check datomic for translation"
-    )
-
-  (testing ""))


common/pre-dump-event: force float coercion for event :ttl.

--- src/reimann/common.clj
+++ src/reimann/common.clj
@@ -46,6 +46,7 @@
   "Transforms an event (map) into a form suitable for protocol buffer encoding."
   [e]
   (let [e (if (:metric e) (assoc e :metric_f (float (:metric e))) e)
+        e (if (:ttl e)    (assoc e :ttl      (float (:ttl e)))    e)
         e (if (:time   e) (assoc e :time     (int   (:time e)))   e)]
     e))


Add directoy support to 'include'

Add directoy support to 'include'

--- src/riemann/config.clj
+++ src/riemann/config.clj
@@ -254,7 +254,8 @@
       (throw (logging/nice-syntax-error e file)))))

 (defn include
-  "Include another config file.
+  "Include another config file or directory. If the path points to a
+   directory, all files within it will be loaded recursively.

   ; Relative to the current config file, or cwd
   (include \"foo.clj\")
@@ -262,7 +263,12 @@
   ; Absolute path
   (include \"/foo/bar.clj\")"
   [path]
-  (let [path (config-file-path path)]
+  (let [path (config-file-path path)
+        file (file path)]
     (binding [*config-file* path
               *ns* (find-ns 'riemann.config)]
-      (load-file path))))
+      (if (.isDirectory file)
+        (doseq [f (file-seq file)]
+          (when (.isFile f)
+            (load-file (.toString f))))
+        (load-file path)))))


Adding port to macro

Adding port to macro

--- src/stub_http/core.clj
+++ src/stub_http/core.clj
@@ -67,6 +67,7 @@
     `(let ~bindings
        (let [server# (start! ~routes)
              ~'uri (:uri server#)
+             ~'port (:port server#)
              ~'server server#]
          (try
            ~@body


Adapt core ns for type constructors renaming.

--- src/suricatta/core.clj
+++ src/suricatta/core.clj
@@ -45,7 +45,7 @@
          ^Configuration conf (doto (DefaultConfiguration.)
                                (.set dialect)
                                (.set connection))]
-      (types/->context conf))))
+      (types/context conf))))

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; SQL Executor


Add sparseness factor for note-density of generated measures

--- src/tenor/entities.clj
+++ src/tenor/entities.clj
@@ -29,25 +29,32 @@
       (time-signature 0 sig))
     :else sig))

-(defn segment-beat [note-count note-value]
+(defn segment-beat [note-count note-value
+                    & {:keys [sparseness]
+                       :or {sparseness 1}}]
   (let [sixteenth-count (* (/ 16 note-value) note-count)
-        notes (range 1 (inc sixteenth-count))]
+        notes (range 1 (inc sixteenth-count))
+        distribution (cons true (repeat sparseness false))]
     (filter
-      (fn [x] (or (= 1 x) (rand-nth [true false])))
+      (fn [x] (or (= 1 x) (rand-nth distribution)))
       notes)))

 (defn segment-measure [measure
-                       & {:keys [running-count result note-value]
-                          :or {running-count 0 result '() note-value 16}}]
+                       & {:keys [running-count result note-value sparseness]
+                          :or {running-count 0 result '()
+                               note-value 16 sparseness 1}}]
   (if (empty? measure)
     result
     (let [result (concat result (map #(+ running-count %)
-                                     (segment-beat (first measure) note-value)))
+                                     (segment-beat (first measure)
+                                                   note-value
+                                                   :sparseness sparseness)))
           running-count (+ running-count (first measure))]
       (segment-measure (rest measure)
                        :running-count running-count
                        :result result
-                       :note-value note-value))))
+                       :note-value note-value
+                       :sparseness sparseness))))

 (defrecord Beat [note-count note-value]
   Entity


Fix bug where concurrent days were not meeting

This was because the intervals were considered to be less than each
other under comparison, rather than meeting. Ensure that intervals are
always bounded by points in time (rather than dates, months, etc.)

--- src/tick/interval.cljc
+++ src/tick/interval.cljc
@@ -45,10 +45,11 @@

 (defn interval
   [v1 v2]
-  (let [t1 (t/temporal-value v1)
-        t2 (t/temporal-value v2)]
-    (assert (t/< t1 t2))
-    (->Interval t1 t2)))
+  (let [t1 (t/beginning (t/temporal-value v1))
+        t2 (t/end (t/temporal-value v2))]
+    (if (t/< t1 t2)
+      (->Interval t1 t2)
+      (throw (ex-info "Interval must span between two times, the first must be before the second" {})))))

 ;; Adjustments


Update Puget code in vault.data.edn ns.

Update Puget code in vault.data.edn ns.

--- src/vault/data/edn.clj
+++ src/vault/data/edn.clj
@@ -26,7 +26,7 @@
     vault.blob.digest.HashID))

-;; CONSTANTS & CONFIGURATION
+;;;;; CONSTANTS & CONFIGURATION ;;;;;

 (def ^Charset blob-charset
   (Charset/forName "UTF-8"))
@@ -37,9 +37,13 @@
   "#vault/data\n")

-(def ^:const ^:private blob-width
-  "Width of text to use in serialized blobs."
-  100)
+(def ^:const ^:private render-opts
+  "Options to use to render EDN values with Puget."
+  {:width 100
+   :strict true
+   :map-delimiter ""
+   :map-coll-separator :line
+   :print-meta false})

 (def ^:const type-key
@@ -67,7 +71,7 @@

-;; TAGGED VALUES
+;;;;; TAGGED VALUES ;;;;;

 (def data-readers
   "Atom containing a map of tag readers supported by Vault."
@@ -112,13 +116,12 @@

-;; SERIALIZATION
+;;;;; SERIALIZATION ;;;;;

 (defn- print-value
   "Prints the canonical EDN representation for the given Clojure value."
   [value]
-  (binding [puget/*strict-mode* true]
-    (puget/pprint value {:width blob-width})))
+  (puget/pprint value render-opts))

 (defn- edn-str
@@ -126,8 +129,8 @@
   Clojure value."
   ^String
   [value]
-  (binding [puget/*colored-output* false]
-    (str/trim (with-out-str (print-value value)))))
+  (let [opts (assoc render-opts :print-color false)]
+    (puget/pprint-str value opts)))

 (defn edn-blob
@@ -174,7 +177,7 @@

-;; DESERIALIZATION
+;;;;; DESERIALIZATION ;;;;;

 (defn- counting-reader
   "Wraps the given input stream with a proxy which counts the bytes read


Create buffer-views from buffers

Create buffer-views from buffers

The buffers sent to WebGL are supposed to be views of glTF buffers so
that more than one can come from a single file.

--- src/main/cljs/ohpengull/core.cljs
+++ src/main/cljs/ohpengull/core.cljs
@@ -32,18 +32,28 @@
    }")

 (def input
-  {:accessors {"my-position-accessor" {:buffer-view "my-array-buffer-view"
+  {:accessors {"my-position-accessor" {:buffer-view "my-array-view"
                                        :components-per-vertex 3
                                        :type data-type/float}
-               "my-index-accessor" {:buffer-view "my-element-array-buffer-view"
+               "my-index-accessor" {:buffer-view "my-element-view"
                                     :count 3
                                     :type data-type/unsigned-short
                                     :offset 0}}
-   :buffer-views {"my-array-buffer-view" (ta/float32 [0.5 -0.5 0.0
-                                                      0.0 0.5 0.0
-                                                      -0.5 -0.5 0.0])
-                  "my-element-array-buffer-view" (ta/unsigned-int16 [0 1 2])}
-   :programs {"my-program" {:attributes nil                 ;TODO
+   :buffers {"my-array-buffer" {:uri [0.5 -0.5 0.0
+                                      0.0 0.5 0.0
+                                      -0.5 -0.5 0.0]
+                                :type ta/float32}
+             "my-element-buffer" {:uri [0 1 2]
+                                  :type ta/unsigned-int16}}
+   :buffer-views {"my-array-view" {:buffer "my-array-buffer"
+                                   :byteOffset 0
+                                   :byteLength 36
+                                   :target buffer-object/array-buffer}
+                  "my-element-view" {:buffer "my-element-buffer"
+                                     :byteOffset 0
+                                     :byteLength 6
+                                     :target buffer-object/element-array-buffer}}
+   :programs {"my-program" {:attributes ["vertex_position"]
                             :fragment-shader "my-fragment-shader"
                             :vertex-shader "my-vertex-shader"}}
    :shaders {"my-vertex-shader" {:type shader/vertex-shader
@@ -56,7 +66,8 @@
          (atom {:last-input {}
                 :programs {}
                 :shaders {}
-                :draws []}))
+                :buffers {}
+                :buffer-views {}}))

 (defn- load-shader! [gl {:keys [type uri]}]
   ;TODO dereference URI instead of using URI as source
@@ -73,36 +84,56 @@
 (defn- load-programs! [gl shaders descs]
   (map-vals descs #(load-program! gl shaders %)))

-(defn- make-draw-calls! [gl programs buffer-views accessors]
-  (let [program (get programs "my-program")
-        vertex-buffer (buffers/create-buffer gl (get buffer-views "my-array-buffer-view")
-                                             buffer-object/array-buffer
-                                             buffer-object/static-draw)
-        element-buffer (buffers/create-buffer gl (get buffer-views "my-element-array-buffer-view")
-                                              buffer-object/element-array-buffer
-                                              buffer-object/static-draw)]
-    [{:shader program
-      :draw-mode draw-mode/triangles
-      :count 3
-      :attributes [(assoc (get accessors "my-position-accessor")
-                     :buffer vertex-buffer
-                     :location (shaders/get-attrib-location gl program "vertex_position"))]
-      :element-array (assoc (get accessors "my-index-accessor")
-                       :buffer element-buffer)}]))
+(defn- load-buffer! [{:keys [uri type]}]
+  (type uri))
+
+(defn- load-buffers! [descs]
+  (map-vals descs #(load-buffer! %)))
+
+(defn- load-buffer-view! [gl buffers {:keys [buffer byteOffset byteLength target]}]
+  (let [view (js/DataView. (.-buffer (get buffers buffer)) byteOffset byteLength)]
+    (buffers/create-buffer gl view target buffer-object/static-draw)))
+
+(defn- load-buffer-views! [gl buffers descs]
+  (map-vals descs #(load-buffer-view! gl buffers %)))
+
+(defn- assoc-attribute [gl render-state program attribute-name accessor-name]
+  (let [accessor (get-in render-state [:last-input :accessors accessor-name])
+        buffer-view (get-in render-state [:buffer-views (:buffer-view accessor)])]
+    (assoc accessor
+      :buffer buffer-view
+      :location (shaders/get-attrib-location gl program attribute-name))))
+
+(defn- assoc-element-array [render-state accessor-name]
+  (let [accessor (get-in render-state [:last-input :accessors accessor-name])
+        buffer-view (get-in render-state [:buffer-views (:buffer-view accessor)])]
+    (assoc accessor
+      :buffer buffer-view)))

 (defn update-render-state! [old-state gl input]
   (if (= (:last-input old-state) input)
     old-state
     ; TODO: Unload removed shaders, programs, and buffers
     (let [shaders (load-shaders! gl (:shaders input))
-          programs (load-programs! gl shaders (:programs input))]
+          programs (load-programs! gl shaders (:programs input))
+          buffers (load-buffers! (:buffers input))
+          buffer-views (load-buffer-views! gl buffers (:buffer-views input))]
       {:last-input input
        :shaders shaders
        :programs programs
-       :draws (make-draw-calls! gl programs (:buffer-views input) (:accessors input))})))
+       :buffers buffers
+       :buffer-views buffer-views})))
+
+(defn- make-draw-calls [gl render-state]
+  (let [program (get-in render-state [:programs "my-program"])]
+    [{:shader program
+      :draw-mode draw-mode/triangles
+      :count 3
+      :attributes [(assoc-attribute gl render-state program "vertex_position" "my-position-accessor")]
+      :element-array (assoc-element-array render-state "my-index-accessor")}]))

 (let [gl (context/get-context (sel1 :#glcanvas))]
   (swap! render-state update-render-state! gl input)        ;TODO swap! function must not have side-effects
   (buffers/clear-color-buffer gl 0 0 0 1)
-  (doseq [draw-args (:draws @render-state)]
-    (mapply buffers/draw! gl draw-args)))
+  (doseq [draw-args (make-draw-calls gl @render-state)]
+    (mapply buffers/draw! gl draw-args)))


Can replay mouse movements too

Can replay mouse movements too

--- src/webapp/client/components/views.cljs
+++ src/webapp/client/components/views.cljs
@@ -84,7 +84,12 @@
     om/IRenderState
     (render-state
      [this state]
-     (dom/div #js {:id "mainel"  :onMouseMove
+     (dom/div #js {:style
+                            #js {
+                                 :position "relative"
+                                 }
+
+                   :id "mainel"  :onMouseMove
                    (fn[e] (on-mouse e app))}
               (str "(" (-> app :pointer :mouse-x) ", " (-> app :pointer :mouse-y)) ")"
               (dom/h2 nil "ConnectToUs.co")
@@ -97,7 +102,16 @@
               (om/build graph{
                                       :data    (:data    app)
                                       }
-              )
+                        )
+              (dom/div #js {
+                            :style
+                            #js {
+                                 :position "absolute"
+                                 :left (str (-> app :pointer :mouse-x) "px")
+                                 :top (str (-> app :pointer :mouse-y) "px")
+                                 }} "X"
+                       )
+
               ))
     ;---------------------------------------------------------


renamed gzipped to gzipped-size for consistency

--- src/asset_minifier/core.clj
+++ src/asset_minifier/core.clj
@@ -43,7 +43,7 @@
             compressed-length   (.length target)]
         {:original-szie uncompressed-length
          :compressed-size compressed-length
-         :gzipped (.length tmp)})))
+         :gzipped-size (.length tmp)})))

 (defn- minify-css-file [source target {:keys [linebreak] :or {linebreak -1}}]
   (with-open [rdr (reader source)


Starts to repair RR test.

Starts to repair RR test.

--- test/onyx/log/round_robin_multi_job_test.clj
+++ test/onyx/log/round_robin_multi_job_test.clj
@@ -1,96 +1,110 @@
 (ns onyx.log.round-robin-multi-job-test
-  (:require [clojure.core.async :refer [chan >!! <!! close!]]
-            [com.stuartsierra.component :as component]
-            [onyx.log.entry :refer [create-log-entry]]
-            [onyx.extensions :as extensions]
-            [onyx.api :as api]
+  (:require [clojure.core.async :refer [chan >!! <!! close! sliding-buffer]]
             [midje.sweet :refer :all]
-            [zookeeper :as zk]))
+            [onyx.peer.task-lifecycle-extensions :as l-ext]
+            [onyx.plugin.core-async :refer [take-segments!]]
+            [onyx.api]))

 (def onyx-id (java.util.UUID/randomUUID))

 (def config (read-string (slurp (clojure.java.io/resource "test-config.edn"))))

-(def scheduler :onyx.job-scheduler/round-robin)
-
 (def env-config
-  {:hornetq/mode :udp
-   :hornetq/server? true
-   :hornetq.server/type :embedded
-   :hornetq.udp/cluster-name (:cluster-name (:hornetq config))
-   :hornetq.udp/group-address (:group-address (:hornetq config))
-   :hornetq.udp/group-port (:group-port (:hornetq config))
-   :hornetq.udp/refresh-timeout (:refresh-timeout (:hornetq config))
-   :hornetq.udp/discovery-timeout (:discovery-timeout (:hornetq config))
-   :hornetq.embedded/config (:configs (:hornetq config))
-   :zookeeper/address (:address (:zookeeper config))
+  {:zookeeper/address (:address (:zookeeper config))
    :zookeeper/server? true
    :zookeeper.server/port (:spawn-port (:zookeeper config))
-   :onyx.peer/job-scheduler scheduler
    :onyx/id onyx-id})

 (def peer-config
-  {:hornetq/mode :udp
-   :hornetq.udp/cluster-name (:cluster-name (:hornetq config))
-   :hornetq.udp/group-address (:group-address (:hornetq config))
-   :hornetq.udp/group-port (:group-port (:hornetq config))
-   :hornetq.udp/refresh-timeout (:refresh-timeout (:hornetq config))
-   :hornetq.udp/discovery-timeout (:discovery-timeout (:hornetq config))
-   :zookeeper/address (:address (:zookeeper config))
+  {:zookeeper/address (:address (:zookeeper config))
    :onyx/id onyx-id
-   :onyx.peer/inbox-capacity (:inbox-capacity (:peer config))
-   :onyx.peer/outbox-capacity (:outbox-capacity (:peer config))
-   :onyx.peer/job-scheduler scheduler})
+   :onyx.peer/job-scheduler :onyx.job-scheduler/round-robin
+   :onyx.messaging/impl :http-kit-websockets})

 (def env (onyx.api/start-env env-config))

 (def catalog-1
   [{:onyx/name :a
-    :onyx/ident :hornetq/read-segments
+    :onyx/ident :core.async/read-from-chan
     :onyx/type :input
-    :onyx/medium :hornetq
-    :onyx/batch-size 20}
+    :onyx/medium :core.async
+    :onyx/batch-size 20
+    :onyx/max-peers 1
+    :onyx/doc "Reads segments from a core.async channel"}

    {:onyx/name :b
-    :onyx/fn :onyx.peer.single-peer-test/my-inc
+    :onyx/fn :onyx.log.round-robin-multi-job-test/my-inc
     :onyx/type :function
     :onyx/batch-size 20}

    {:onyx/name :c
-    :onyx/ident :hornetq/write-segments
+    :onyx/ident :core.async/write-to-chan
     :onyx/type :output
-    :onyx/medium :hornetq
-    :onyx/batch-size 20}])
+    :onyx/medium :core.async
+    :onyx/batch-size 20
+    :onyx/max-peers 1
+    :onyx/doc "Writes segments to a core.async channel"}])

 (def catalog-2
   [{:onyx/name :d
-    :onyx/ident :hornetq/read-segments
+    :onyx/ident :core.async/read-from-chan
     :onyx/type :input
-    :onyx/medium :hornetq
-    :onyx/batch-size 20}
+    :onyx/medium :core.async
+    :onyx/batch-size 20
+    :onyx/max-peers 1
+    :onyx/doc "Reads segments from a core.async channel"}

    {:onyx/name :e
-    :onyx/fn :onyx.peer.single-peer-test/my-inc
+    :onyx/fn :onyx.log.round-robin-multi-job-test/my-inc
     :onyx/type :function
     :onyx/batch-size 20}

    {:onyx/name :f
-    :onyx/ident :hornetq/write-segments
+    :onyx/ident :core.async/write-to-chan
     :onyx/type :output
-    :onyx/medium :hornetq
-    :onyx/batch-size 20}])
+    :onyx/medium :core.async
+    :onyx/batch-size 20
+    :onyx/max-peers 1
+    :onyx/doc "Writes segments to a core.async channel"}])
+
+(def n-messages 1000)
+
+(def a-chan (chan (inc n-messages)))
+
+(def c-chan (chan (sliding-buffer (inc n-messages))))
+
+(def d-chan (chan (inc n-messages)))
+
+(def f-chan (chan (sliding-buffer (inc n-messages))))
+
+(defmethod l-ext/inject-lifecycle-resources :a
+  [_ _] {:core.async/in-chan a-chan})
+
+(defmethod l-ext/inject-lifecycle-resources :c
+  [_ _] {:core.async/out-chan c-chan})
+
+(defmethod l-ext/inject-lifecycle-resources :d
+  [_ _] {:core.async/in-chan d-chan})
+
+(defmethod l-ext/inject-lifecycle-resources :f
+  [_ _] {:core.async/out-chan f-chan})
+
+(defn my-inc [segment]
+  (update-in segment [:n] inc))

 (def j1
-  (onyx.api/submit-job peer-config
-                       {:workflow [[:a :b] [:b :c]]
-                        :catalog catalog-1
-                        :task-scheduler :onyx.task-scheduler/round-robin}))
+  (onyx.api/submit-job
+   peer-config
+   {:workflow [[:a :b] [:b :c]]
+    :catalog catalog-1
+    :task-scheduler :onyx.task-scheduler/round-robin}))

 (def j2
-  (onyx.api/submit-job peer-config
-                       {:workflow [[:d :e] [:e :f]]
-                        :catalog catalog-2
-                        :task-scheduler :onyx.task-scheduler/round-robin}))
+  (onyx.api/submit-job
+   peer-config
+   {:workflow [[:d :e] [:e :f]]
+    :catalog catalog-2
+    :task-scheduler :onyx.task-scheduler/round-robin}))

 (def n-peers 36)


restrictions on birds and words

restrictions on birds and words

--- src/babel/encyclopedia.cljc
+++ src/babel/encyclopedia.cljc
@@ -146,7 +146,8 @@
                       :place false
                       :spec {:of {:human true}}}

-   {:pred :bird}     {:animate true}
+   {:pred :bird}     {:animate true
+                      :human false}

    {:pred :bread}    {:artifact true
                       :edible true}
@@ -212,6 +213,7 @@
                       :drinkable true}

    {:pred :word}     {:legible true
+                      :living false
                       :speakable true}

    ;; </preds>


Fix bug with nrepl hyperlink activation

Fix bug with nrepl hyperlink activation

--- ccw.core/src/clj/ccw/editors/clojure/nrepl_hyperlink_detector.clj
+++ ccw.core/src/clj/ccw/editors/clojure/nrepl_hyperlink_detector.clj
@@ -48,7 +48,7 @@
     (when-let [[offset length [_ host port]] (find-match-for-offset pattern line (- offset line-offset))]
       ;(println "nrepl hyperlink:" :offset (+ line-offset offset) :length length)
       [{:offset (+ line-offset offset) :length length
-        :open #(ccw.repl.REPLView/connect (format "nrepl://%s:%s") host port)}])))
+        :open #(ccw.repl.REPLView/connect (format "nrepl://%s:%s" host port))}])))

 (defn factory [ _ ]
   (proxy [AbstractHyperlinkDetector]


update nickname migration, add email uniqueness migration

--- src/chat/server/migrate.clj
+++ src/chat/server/migrate.clj
@@ -1,6 +1,15 @@
 (ns chat.server.migrate
   (:require [chat.server.db :as db]
             [datomic.api :as d]))
+
+(defn migrate-2016-01-01
+  "Change email uniqueness to /value"
+  []
+  (db/with-conn
+    (d/transact db/*conn*
+      [{:db/id :user/email
+        :db/unique :db.unique/value
+        :db.alter/_attribute :db.part/db}])))

 (defn migrate-2015-12-19
   "Add user nicknames"
@@ -10,7 +19,7 @@
       [{:db/ident :user/nickname
         :db/valueType :db.type/string
         :db/cardinality :db.cardinality/one
-        :db/unique :db.unique/identity
+        :db/unique :db.unique/value
         :db/id #db/id [:db.part/db]
         :db.install/_attribute :db.part/db}])))


pprint output

pprint output

--- src/clj/cljs/source_map.clj
+++ src/clj/cljs/source_map.clj
@@ -119,15 +119,16 @@
                        segs (encode-source lines segs source-idx names->idx name-idx)]
                    (recur (next sources) (inc source-idx) segs))
                  segs))]
-    (json/write-str
-     {"version" 3
-      "file" (:file opts)
-      "sources" (into [] (keys m))
-      "lineCount" (:lines opts)
-      "mappings" (->> segs
-                   (map #(string/join "," (apply str %)))
-                   (string/join ";"))
-      "names" (into [] (map (set/map-invert @names->idx) (range (count @names->idx))))})))
+    (with-out-str
+      (json/pprint
+       {"version" 3
+        "file" (:file opts)
+        "sources" (into [] (keys m))
+        "lineCount" (:lines opts)
+        "mappings" (->> segs
+                        (map #(string/join "," %))
+                        (string/join ";"))
+        "names" (into [] (map (set/map-invert @names->idx) (range (count @names->idx))))}))))

 (defn merge-source-maps
   ([cljs-map closure-map] (merge-source-maps cljs-map closure-map 0))


Make fn take a file object

Make fn take a file object

--- src/clj/nightcode/utils.clj
+++ src/clj/nightcode/utils.clj
@@ -37,12 +37,11 @@

 (defn delete-children-recursively!
   "Deletes the children of the given dir along with the dir itself."
-  [path]
-  (let [f (io/file path)]
-    (when (.isDirectory f)
-      (doseq [f2 (.listFiles f)]
-        (delete-children-recursively! f2)))
-    (io/delete-file f))
+  [f]
+  (when (.isDirectory f)
+    (doseq [f2 (.listFiles f)]
+      (delete-children-recursively! f2)))
+  (io/delete-file f)
   nil)

 (defn get-project-root-path
@@ -203,7 +202,7 @@
   :args (s/cat :project-set set? :path string?))

 (fdef delete-children-recursively!
-  :args (s/cat :path string?))
+  :args (s/cat :path file?))

 (fdef get-project-root-path
   :args (s/cat :pref-state map?)


add showcase to pdf

add showcase to pdf

--- src/clj/salava/page/pdf.clj
+++ src/clj/salava/page/pdf.clj
@@ -201,6 +201,42 @@
                                                                                (if (ends-with? (:image_file badge) "png") [:chunk [:image {:align :center :width 60 :height 60}(str data-dir "/" (:image_file badge))]] [:chunk [:image {:align :center :width 60 :height 60 :base64 true} (:qr_code (first b))]])
                                                                                ]])))]]]
                                                                   [[:cell [:line {:dotted true}]]]]))
+                                                         (when (= "showcase" (:type %))
+                                                           (if (= "long" (:format %))
+                                                             (into [:table {:border false :widths [1 3] :keep-together? false}]
+                                                                   (conj  (into [[[:cell {:colspan 2}]]] (for [badge (:badges %)
+                                                                                :let [b (pdf-generator-helper ctx user-id (list (:id badge)))
+                                                                                content (-> b first :content first)]]
+                                                                                (when-not (empty? b)
+                                                                                (conj [[:cell {:align :left} (if (and (not (= "-" (:image_file badge))) (ends-with? (:image_file badge) "png")) [:image {:align :center :width 75 :height 75}(str data-dir "/" (:image_file badge))] [:image {:align :center :width 75 :height 75 :base64 true} (:qr_code (first b))])]]
+                                                                                [:cell
+                                                                                [:paragraph.generic
+                                                                                [:heading (:name badge)]
+                                                                                [:chunk.bold (str (t :badge/Issuedby ul) ": ")] [:chunk (:issuer_content_name content)] "\n"
+                                                                                [:phrase
+                                                                                [:chunk.bold (str (t :badge/Issuedon ul)": ")] [:chunk (if (number? (:issued_on badge)) (date-from-unix-time (long (* 1000 (:issued_on badge))) "date") (:issued_on badge))] "\n"]
+                                                                                (:description badge)"\n"
+                                                                                [:spacer 0]
+                                                                                [:paragraph {:keep-together true}
+                                                                                [:phrase.bold (str (t :badge/Criteria ul)": ")]
+                                                                                [:anchor {:target (:criteria_url badge)} [:chunk.link (t :badge/Opencriteriapage ul)]] "\n"
+                                                                                #_[:paragraph {:style :italic} (:criteria_url badge) ]
+                                                                                (process-markdown (:criteria_content content) (:id badge) "Criteria")
+                                                                                ]
+                                                                                ][:spacer 0]]))))
+                                                                          [[:cell {:colspan 2}[:line {:dotted true}]]]))
+
+                                                             [:table {:no-split-cells? true :width 100 :border false}
+                                                              [[:cell
+                                                                [:table {:align :center :width-percent 100 :border false :num-cols 5}
+                                                                 (into [[:cell {:colspan 5}]] (for [badge (:badges %)
+                                                                                :let [b (pdf-generator-helper ctx user-id (list (:id badge)))
+                                                                                content (-> b first :content first)]]
+                                                                                (when-not (empty? b)
+                                                                                [:cell {:padding-right 10}[:anchor {:target (str site-url "/app/badge/info/" (:id badge))}
+                                                                                (if (ends-with? (:image_file badge) "png") [:chunk [:image {:align :center :width 60 :height 60}(str data-dir "/" (:image_file badge))]] [:chunk [:image {:align :center :width 60 :height 60 :base64 true} (:qr_code (first b))]])
+                                                                                ]])))]]]
+                                                              [[:cell [:line {:dotted true}]]]]))
                                                              [:spacer 3]])

                                content (-> (mapv template $blocks)


Function compute-schedule

Function compute-schedule

--- src/clj_mrazik/schedule.clj
+++ src/clj_mrazik/schedule.clj
@@ -15,3 +15,14 @@

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

+(defn compute-schedule
+    [bot-configuration]
+    (let [start     (:start bot-configuration)
+          end       (:end   bot-configuration)
+          frequency (:frequency bot-configuration)
+          duration  (:duration  bot-configuration)]
+          (loop [schedule [] time start]
+              (if (>= time end)
+                  schedule
+                  (recur (conj schedule (schedule-entry time duration)) (+ time frequency))))))
+


Annull game

Annull game

--- src/cljs/db_quiz/logic.cljs
+++ src/cljs/db_quiz/logic.cljs
@@ -142,6 +142,16 @@
   (assoc app-state :timer {:completion 0
                            :start (.getTime (js/Date.))}))

+(defn annull-game!
+  "Annull abandoned game."
+  []
+  (swap! app-state (comp #(assoc %
+                                 :answer nil
+                                 :current-field nil
+                                 :timer {:completion 0
+                                         :start 0}
+                                 :verdict nil))))
+
 (def unmatch-answer
   "Clear the answer match status."
   (partial match-answer nil))


More boring placeholders for player names

--- src/cljs/db_quiz/state.cljs
+++ src/cljs/db_quiz/state.cljs
@@ -20,8 +20,8 @@
                                 :places
                                 :films}
                    :share-url ""}
-         :players {:player-1 "Dmitrij"
-                   :player-2 "Paní M."}
+         :players {:player-1 "Player 1"
+                   :player-2 "Player 2"}
          :timer {:completion 0
                  :start 0}
          :verdict nil


Client db: Clarify key-value areas

Client db: Clarify key-value areas

Previously I had "scratch" areas that used key-value cells for storage.
The scratch areas were somehow thought for binding text input elements
to them, but that hadn't been defined clearly.

One possibility would be to define them clearly, but I might need areas
of key-value cells in other places. Avoid future duplication by turning
the whole thing into general-purpose key-value areas.

Two considerations:

 - Instead of making key-value areas separate entities I could have
   given each key-value cell an area key. I don't know how that would
   influence performance. Database guys would call it normalization or
   denormalization or something like that. Anyway, I decided to do it
   how I do it now, because conceptually key-value areas feel more like
   separate things to me.

 - I'm not sure whether putting key-value areas in the database is a
   good idea. (1), you can direcly store maps in DataScript. (2), it
   allows me to be sloppy and to not specify precisely what should be in
   the database. As to point 1, I don't know what is better. The other
   side of point 2 is that this way the IDs can be driven by the HTML
   template. This avoids duplication and saves work binding text input
   elements to the database. This might be vain, though, because later
   on I have to refer to them literally again.

Krch, questions, questions. If only there was someone to tell me what is
right and what is wrong.

--- src/cljs/theatralia/db.cljs
+++ src/cljs/theatralia/db.cljs
@@ -1,7 +1,23 @@
 (ns theatralia.db
   "Definitions of the schema of the DataScript DB in the client."
-  (:require [plumbing.core :as plumbing]
+  (:require [datascript :as d]
+            [plumbing.core :as plumbing :refer [safe-get]]
             [schema.core :as s]))
+
+;;;; Database helper functions
+
+(defn kv-area-as-map
+  "Retrieves the contents of the key-value store area identified by HANDLE from
+  DB and returns them as a key-value map."
+  [db handle]
+  (let [cell-maps (-> (d/pull db
+                              '[{:kv-area/cells [:kv-cell/key :kv-cell/val]}]
+                              [:kv-area/handle handle])
+                      (get :kv-area/cells))]
+    (plumbing/for-map [{k :kv-cell/key v :kv-cell/val} cell-maps]
+      k v)))
+
+;;;; Schema

 (def full-schema
   "Complete schema for the DB.
@@ -9,17 +25,18 @@
   DataScript only supports a subset of schema attributes, so we can't use this
   verbatim. Especially, it doesn't support custom value types specified with
   Prismatic schema. So this is mainly for documentation."
-  {:scratch/handle {:db/unique :db.unique/identity}
-   :scratch/kv-cells {:db/cardinality :db.cardinality/many
-                      :db/valueType   :db.type/ref}
+  {:kv-area/handle {:db/unique :db.unique/identity
+                    :db/valueType cljs.core/UUID}
+   :kv-area/cells {:db/cardinality :db.cardinality/many
+                   :db/valueType   :db.type/ref}

-   :kv-cell/key {:db/valueType :db.type/string}
+   :kv-cell/key {:db/valueType :db.type/keyword}
    :kv-cell/val {:db/valueType s/Any}

    :search/result
    {:db/cardinality :db.cardinality/many
     :db/valueType [(s/one s/Int "server entity ID")
-                   (s/one s/String "result title")
+                   (s/one s/Str "result title")
                    (s/one s/Num "score")]}

    :tag/s-id {:db/unique :db.unique/identity


tried to clean up large function in the repo routes

--- src/clojars/routes/repo.clj
+++ src/clojars/routes/repo.clj
@@ -43,6 +43,13 @@
       .mkdirs)
   (io/copy input sent-file))

+(defn try-save-to-file [sent-file input]
+  (try
+    (save-to-file sent-file input)
+    (catch java.io.IOException e
+      (.delete sent-file)
+      (throw e))))
+
 (defroutes routes
   (PUT ["/:group/:artifact/:file"
         :group #".+" :artifact #"[^/]+" :file #"maven-metadata\.xml[^/]*"]
@@ -72,19 +79,13 @@
                 (db/check-and-add-group account groupname)
                 (if (.endsWith filename ".pom")
                   (let [contents (slurp body)
-                        pom-info (merge (maven/pom-to-map
-                                         (StringReader. contents)) info)]
+                        pom-info (-> contents
+                                     StringReader.
+                                     maven/pom-to-map
+                                     (merge info))]
                     (db/add-jar account pom-info)
-                    (try
-                      (save-to-file file contents)
-                      (catch java.io.IOException e
-                        (.delete file)
-                        (throw e))))
-                  (try
-                    (save-to-file file body)
-                    (catch java.io.IOException e
-                      (.delete file)
-                      (throw e))))
+                    (try-save-to-file file contents))
+                  (try-save-to-file file body))
                 ;; Be consistent with scp only recording pom or jar
                 (when (some #(.endsWith filename %) [".pom" ".jar"])
                   (ev/record-deploy {:group-id groupname


Tweak hardocded resilience

Tweak hardocded resilience

--- src/clojush/meta_errors.clj
+++ src/clojush/meta_errors.clj
@@ -168,7 +168,7 @@
         0
         (if (> (/ (count (distinct hist))
                   (count hist))
-               4/5)
+               3/5)
           0
           1)))))