a quick'n'dirty optimization for finding words in board

--- src/wordup/logic/board.clj
+++ src/wordup/logic/board.clj
@@ -113,10 +113,15 @@
                             (innerloop board word (inc i) (neighboring-cells board cell-to-check) (conj used-cells cell-to-check))))))))]
     (innerloop board word 0 (set (keys (board-to-map board))) #{})))

+(defn prefilter-words
+  "quick filter words that can be made up of letters in board"
+  [board words]
+  (let [letters-on-board (set (flatten board))]
+    (filter #(clojure.set/subset? (set %) letters-on-board) words)))
+
 (defn all-words-in-board
   [board words]
-  ;(sort #(> (count %1) (count %2)) (filter #(contains-word? board %) @words)))
-  (set (filter #(contains-word? board %) @words)))
+  (set (filter #(contains-word? board %) (prefilter-words board @words))))

 (defn log-board!
   [board]


Add a store-delete prop

Add a store-delete prop

--- test/icecap/store/test_props.clj
+++ test/icecap/store/test_props.clj
@@ -1,6 +1,6 @@
 (ns icecap.store.test-props
   (:require [caesium.crypto.util :refer [array-eq]]
-            [icecap.store.api :refer [create! retrieve]]
+            [icecap.store.api :refer [create! delete! retrieve]]
             [icecap.crypto :refer [index-bytes]]
             [icecap.test-props :refer [n-bytes]]
             [clojure.core.async :refer [<!!]]
@@ -14,3 +14,11 @@
                 (do (<!! (create! store index blob))
                     (array-eq (<!! (retrieve store index))
                               blob))))
+
+(defn store-delete-prop
+  [store]
+  (prop/for-all [index (n-bytes index-bytes)
+                 blob gen/bytes]
+                (do (<!! (create! store index blob))
+                    (<!! (delete! store index))
+                    (nil? (<!! (retrieve store index))))))


Commit just for synch purposes

Commit just for synch purposes

--- src/fpinscala/datastructures.clj
+++ src/fpinscala/datastructures.clj
@@ -485,4 +485,15 @@
                 new-t
                 (go (branch t) branch (xconj new-t branch (f (:val t))))))]
     (go (:L t) :L (go (:R t) :R (xconj nil nil (f (:val t)))))))
-
+;fpins
+;given my structure of tree (via maps) and my xconj function, those don't
+;allow 1-1 translation - so, I've hit a ceiling/limitation :)
+;so I'l need different structure...
+
+(defn t-map-fpins [t f]
+  (match t
+         {:val v :L nil :R nil} (xconj nil nil (f v))
+         {:val v :L nil :R r} (t-map-fpins r f)
+         {:val v :L l :R nil} (t-map-fpins l f)
+         {:val v :L l :R r} ()))
+;-----------------------------------------------------------------------


tests for context propagation to instrumented Future objects

--- test/preflex/instrument_test.clj
+++ test/preflex/instrument_test.clj
@@ -14,7 +14,8 @@
     [preflex.instrument :as instru]
     [preflex.internal   :as in])
   (:import
-    [java.util.concurrent ExecutorService]))
+    [java.util.concurrent ExecutorService]
+    [preflex.instrument.concurrent FutureWrapper SharedContextFuture]))

 (defmacro with-active-thread-pool
@@ -45,7 +46,11 @@
                               :runnable-decorator  instru/shared-context-runnable-decorator
                               :future-decorator    instru/shared-context-future-decorator)
                             (dissoc :on-future-cancel :on-future-result)))]
-        (is (nil?
-              @(.submit ^ExecutorService instru-pool ^Runnable #(do 10))))
+        (let [^FutureWrapper fut (.submit ^ExecutorService instru-pool ^Runnable #(do 10))
+              ^SharedContextFuture scf (.getOrig fut)]
+          (is (instance? FutureWrapper fut))
+          (is (instance? SharedContextFuture scf))
+          (is (contains? @(.getContext scf) :submit-begin-ns))
+          (is (nil? @fut)))
         (is (= 10
               @(.submit ^ExecutorService instru-pool ^Callable #(do 10))))))))


remove commented out received? in whois test

--- test/subrosa/test/connection.clj
+++ test/subrosa/test/connection.clj
@@ -106,7 +106,6 @@
     (transmit s "USER dan 0 * :Dan Larkin")
     (transmit s "JOIN #foo")
     (transmit s "WHOIS dan")
-    ;;;    (transmit s "WHOIS") ; test that this doesn't throw sometime
     (is (received? s #"~dan .* \* :Dan Larkin"))
     (is (received? s #"#foo"))
     (is (received? s #":End of /WHOIS list"))))


Fixed lint error.

Fixed lint error.

--- src/hxgm30/language/gen/core.clj
+++ src/hxgm30/language/gen/core.clj
@@ -1,5 +1,6 @@
 (ns hxgm30.language.gen.core
   (:require
+    [clojure.string :as string]
     [hxgm30.common.util :as util]
     [hxgm30.language.gen.impl.markov :as markov]
     [hxgm30.language.gen.impl.syntagmata :as syntagmata])
@@ -114,7 +115,7 @@
     (derive-word words-data (rand-int 10)))
   ([words-data syllable-count]
     (let [total (reduce + 0.0 (map :weight words-data))]
-      (apply str
+      (string/join
         (flatten
           (map (fn [_] (rand-nth
                         (vec


fill in some basic mining tests

fill in some basic mining tests

--- test/block_chain/miner_test.clj
+++ test/block_chain/miner_test.clj
@@ -1,3 +1,43 @@
 (ns block-chain.miner-test
-  (:require  [clojure.test :refer :all]))
+  (:require  [clojure.test :refer :all]
+             [pandect.algo.sha256 :refer [sha256]]
+             [clojure.math.numeric-tower :as math]
+             [block-chain.miner :refer :all]
+             ))

+(def sample-block
+  {:header {:parent-hash "0"
+            :transactions-hash "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
+            :target "F000000000000000000000000000000000000000000000000000000000000000", :timestamp 1450057326
+            :nonce 0
+            }
+   :transactions []})
+
+(deftest hashes-block-by-hashing-header-values
+  (let [b {:header {:parent-hash "0"
+                    :transactions-hash "1"
+                    :target "2"
+                    :nonce 3}}]
+    (is (= (sha256 "0123") (block-hash b)))))
+
+(deftest determines-if-block-meets-specified-target
+  (let [b1 {:header {:hash "0F" :target "FF"}}
+        b2 {:header {:hash "FF" :target "0F"}}]
+    (is (meets-target? b1))
+    (is (not (meets-target? b2)))))
+
+(def max-sha2 (apply str (take 64 (repeat "F"))))
+
+(deftest returns-valid-block-with-same-nonce
+  (let [b {:header {:target max-sha2 :nonce 0}}
+        mined (mine b)]
+    (is (= b (update-in mined [:header] dissoc :hash)))))
+
+(def large-target (str (format "%x" (biginteger(math/expt 2 254)))))
+
+(deftest mines-block-by-updating-nonce-until-hash-is-valid
+  (let [b {:header {:target large-target :nonce 0}}
+        mined (mine b)]
+    (is (= 1 (get-in mined [:header :nonce])))))
+
+(run-tests)


add another example for reader monad to use the return value add more comment about thinking about monad and combinator in software design

--- src/monad/clojure/applications.clj
+++ src/monad/clojure/applications.clj
@@ -12,7 +12,7 @@
 ;;just like the reader monad in haskell
 (def reader-m {:return (fn [a]
                          (fn [_] a))
-               :>>=   (fn [m k]
+               :>>=    (fn [m k]
                          (fn [r]
                            ((k (m r)) r)))})

@@ -119,6 +119,22 @@
         [_ (connect-to-db-m)
          _ (connect-to-api-m)]
         (prn "Done.")))
+
+(defn connect-to-db-m-2 []
+  (do-m reader-m
+        [db-uri (asks :db-uri)]
+        (str "Connected to db at %s" db-uri)))
+
+(defn connect-to-api-m-2 []
+  (do-m reader-m
+        [api-key (asks :api-key)]
+        (str "Connected to api with key %s" api-key)))
+
+(defn run-app-m-2 []
+  (do-m reader-m
+        [dbinfo (connect-to-db-m-2)
+         apiinfo (connect-to-api-m-2)]
+        (str "dbinfo -> " dbinfo "apiinfo -> " apiinfo)))

 (macroexpand '(do-m reader-m
                     [_ (connect-to-db-m)
@@ -147,6 +163,10 @@
 ((run-app-m) {:db-uri  "user:passwd@host/dbname"
               :api-key "AF167"})

+;;从上面donotation这个宏的展开结果就可以看到 可以利用闭包性将参数传入最终的处理函数中 之前每一层的闭包参数都是_ 都忽略了 但是是可以放入参数的
+((run-app-m-2) {:db-uri  "user:passwd@host/dbname"
+                :api-key "AF167"})
+
 ;;感觉屌飞了 黑魔法啊 reader monad扔出来的就是一个单参函数接受传入的配置 并且可以用ask获取到传入的配置值
 ;;有了reader monad 就不需要把配置手动显式的传给每一个依赖配置的函数 可以让内部的业务代码更加整洁 当然团队内部平均水平肯定要都在一条线上

@@ -179,3 +199,8 @@
 ;;但是貌似defprotocol和reify的组合本身就可以这样弄 就是repo那里使用let绑定为mk-user-repo的位置 用reader monad会让代码描述性更强 repo就是单独传入的一个module一样的意思
 ;;如果不用reader monad那么用mk-user-repo函数生成的repo值还需要显示的被传入clone!函数 现在只要在最外层显式地写一次就好了
 ;;其实这样看来 上面传递env的那个例子也算是一种依赖注入 依赖就是env这个上下文中保存的信息
+
+;;monad还有一个高级应用就是用于面向combinator设计
+;;因为monad具有自相似性 局部与整体具有相同的结构与性质 函数式的组合子就是用小的遵守一定规则的小零件组成更大的但是仍然遵守同样规则的大零件 再组成更加复杂的大系统 但是所有东西从每一层看都是统一的 就像枫树叶的结构
+;;而传统的OO设计用来组合模块充斥着设计模式 最佳实践 都是一些看似严谨的工程实践经验组合 并没有严格的理论背景支撑 更像是文学 而不是理学 没有数学的美感 也没有自相似性这种神奇的性质
+;;上面的话有点中二 没有银弹 好玩就好


Fix error pipeline

Fix error pipeline

--- src/obb_api/handlers/play_game.clj
+++ src/obb_api/handlers/play_game.clj
@@ -24,8 +24,8 @@
   [args]
   (cond
     (nil? (args :game)) ["InvalidGame" 404]
+    (nil? (get-in args [:data])) ["EmptyJSON" 412]
     (not (valid-player? args)) ["InvalidPlayer" 401]
-    (nil? (get-in args [:data])) ["EmptyJSON" 412]
     (nil? (get-in args [:data :actions])) ["NoActions" 412]
     (= false ((args :processed) :success)) ["TurnFailed" 422]))


temp add endpoint to check sentry dsn

temp add endpoint to check sentry dsn

--- src/open_company/api/companies.clj
+++ src/open_company/api/companies.clj
@@ -4,7 +4,9 @@
             [liberator.core :refer (defresource by-method)]
             [open-company.api.common :as common]
             [open-company.resources.company :as company]
-            [open-company.representations.company :as company-rep]))
+            [open-company.representations.company :as company-rep]
+            [open-company.config :as c]
+            [cheshire.core :as json]))

 (defun add-ticker
   "Add the ticker symbol to the company properties if it's missing."
@@ -74,9 +76,20 @@
   :exists? (fn [_] {:companies (company/list-companies)})
   :handle-ok (fn [ctx] (company-rep/render-company-list (:companies ctx))))

+(defresource sentry []
+  :available-charsets [common/UTF8]
+  :available-media-types [company-rep/collection-media-type]
+  :handle-not-acceptable (common/only-accept 406 company-rep/collection-media-type)
+  :allowed-methods [:get]
+
+  ;; Get a list of companies
+  :exists? (fn [_] {:sentry c/dsn})
+  :handle-ok (fn [ctx] (json/generate-string {:collection (array-map :sentry (:sentry ctx))} {:pretty true})))
+
 ;; ----- Routes -----

 (defroutes company-routes
   (ANY "/v1/companies/:ticker" [ticker] (company ticker))
   (GET "/v1/companies/" [] (company-list))
-  (GET "/v1/companies" [] (company-list)))+  (GET "/v1/companies" [] (company-list))
+  (GET "/v1/sentry" [] (sentry)))


Clean up mutable assoc for hash collision node

--- src/main/cljs/lean_map/core.cljs
+++ src/main/cljs/lean_map/core.cljs
@@ -281,9 +281,8 @@
     (assert (== hash collision-hash))
     (let [idx (hash-collision-node-find-index arr cnt key)]
       (if ^boolean hedit
-        (if ^boolean (can-edit edit hedit)
-         (.mutable-inode-assoc inode idx key val added-leaf?)
-         (.mutable-inode-assoc (HashCollisionNode. hedit hash cnt (aclone arr)) idx key val added-leaf?))
+        (let [new-node (if ^boolean (can-edit edit hedit) inode (HashCollisionNode. hedit hash cnt (aclone arr)))]
+          (.mutable-inode-assoc new-node idx key val added-leaf?))
         (.persistent-inode-assoc inode idx hedit key val added-leaf?))))

   (has-nodes? [_]


remove docset debug printing

remove docset debug printing

--- src/main/cljs_api_gen/docset.clj
+++ src/main/cljs_api_gen/docset.clj
@@ -154,8 +154,6 @@
           pairs (->> (:api result)
                      (mapcat get-api-ns-pairs)
                      (set))]
-      (doseq [p pairs]
-        (println "pair:" (pr-str p)))
       (apply j/insert! sqlite-db :searchIndex
         (for [[api-type ns-] pairs]
           (let [ns-display (get-ns-display-name ns- api-type)


add cljsdoc info to ns data in result

add cljsdoc info to ns data in result

--- src/main/cljs_api_gen/result.clj
+++ src/main/cljs_api_gen/result.clj
@@ -302,15 +302,29 @@
   ([item curr-tag cljsdoc]
    (let [doc-version (last (filter #(or (nil? %) (cljs-cmp <= % curr-tag))
                                    (:versions cljsdoc)))
-         doc (get-in cljsdoc [:docs doc-version])]
-     (cond-> item
-       ;; don't overwrite signature if it's null
-       doc              (merge (select-keys doc [:examples :related :description :moved :usage :tags :known-as]))
-       (:display doc)   (merge (select-keys doc [:display]))
-       (:signature doc) (merge (select-keys doc [:signature]))))))
+         doc (get-in cljsdoc [:docs doc-version])
+         data (prune-map (select-keys doc
+                [:examples
+                 :known-as
+                 :display
+                 :caption
+                 :caption-library
+                 :caption-compiler
+                 :description
+                 :description-library
+                 :description-compiler
+                 :signature
+                 :usage
+                 :related
+                 :moved
+                 :tags
+                 ]))]
+     (merge item data))))

 (defn add-cljsdoc-to-result
   [result]
   (let [tag (-> result :release :cljs-tag)
-        update-symbols (fn [symbols] (mapmap #(add-cljsdoc % tag) symbols))]
-    (update-in result [:symbols] update-symbols)))
+        update (fn [symbols] (mapmap #(add-cljsdoc % tag) symbols))]
+    (-> result
+        (update-in [:symbols] update)
+        (update-in [:namespaces] update))))


Added some tests for the null values in paths.

--- test/lambda_blog/utils_test.clj
+++ test/lambda_blog/utils_test.clj
@@ -3,6 +3,10 @@
             [lambda-blog.utils :refer [path]]))

 (deftest path-renders-properly
+  (is (= (path "foo" nil "bar")
+         "./foo/bar"))
+  (is (= (path nil nil)
+         "."))
   (is (= (path "foo" "bar")
          "./foo/bar"))
   (is (= (path "" "foo")


chopping to clojure 1.7-alpha5 issue: unmacroexpanded should work

--- test/midje/util/t_one_seven.clj
+++ test/midje/util/t_one_seven.clj
@@ -14,49 +14,55 @@
   (binding [*mocked-function-produces-next-element* (fn [n] (swap! counter inc) (inc n))]
     (eagerly (take 5 (function-under-test-produces-a-lazy-list)))))

-(midje.checking.facts/creation-time-check
- (midje.data.compendium/record-fact-existence!
-  (clojure.core/with-meta
-   (clojure.core/fn
-    []
-    (midje.parsing.util.wrapping/midje-wrapped
-     (midje.data.prerequisite-state/with-installed-fakes
-      (midje.parsing.1-to-explicit-form.parse-background/background-fakes)
-      (reset! counter 1)
-      (mock-use)
-      (midje.parsing.util.wrapping/midje-wrapped
-       (midje.checking.checkables/check-one
-        (clojure.core/merge
-         {:description (midje.data.nested-facts/descriptions),
-          :expected-result-form '5,
-          :check-expectation :expect-match,
-          :midje.parsing.lexical-maps/a-midje-checkable-map? true,
-          :function-under-test (clojure.core/fn [] @counter),
-          :expected-result 5,
-          :position
-          (midje.parsing.util.file-position/line-number-known nil),
-          :namespace clojure.core/*ns*}
-         {:arrow '=>, :call-form '@counter}
-         (midje.clojure.core/hash-map-duplicates-ok
-          :position
-          (midje.parsing.util.file-position/line-number-known 18)))
-        [])))))
-   (clojure.core/merge
-    {:midje/guid "9a01710b2962f9945f24630a0579bba82671d1ef",
-     :midje/name "eagerly forces evaluation",
-     :midje/description "eagerly forces evaluation",
-     :midje/source
-     '(fact
-       "eagerly forces evaluation"
-       (reset! counter 1)
-       (mock-use)
-       @counter
-       =>
-       5),
-     :midje/namespace 'midje.util.t-one-seven,
-     :midje/file "midje/util/t_one_seven.clj",
-     :midje/line 17}
-    {:midje/top-level-fact? true}))))
+(fact "eagerly forces evaluation"
+  (reset! counter 1)
+  (mock-use)
+  @counter => 5
+)
+
+;; (midje.checking.facts/creation-time-check
+;;  (midje.data.compendium/record-fact-existence!
+;;   (clojure.core/with-meta
+;;    (clojure.core/fn
+;;     []
+;;     (midje.parsing.util.wrapping/midje-wrapped
+;;      (midje.data.prerequisite-state/with-installed-fakes
+;;       (midje.parsing.1-to-explicit-form.parse-background/background-fakes)
+;;       (reset! counter 1)
+;;       (mock-use)
+;;       (midje.parsing.util.wrapping/midje-wrapped
+;;        (midje.checking.checkables/check-one
+;;         (clojure.core/merge
+;;          {:description (midje.data.nested-facts/descriptions),
+;;           :expected-result-form '5,
+;;           :check-expectation :expect-match,
+;;           :midje.parsing.lexical-maps/a-midje-checkable-map? true,
+;;           :function-under-test (clojure.core/fn [] @counter),
+;;           :expected-result 5,
+;;           :position
+;;           (midje.parsing.util.file-position/line-number-known nil),
+;;           :namespace clojure.core/*ns*}
+;;          {:arrow '=>, :call-form '@counter}
+;;          (midje.clojure.core/hash-map-duplicates-ok
+;;           :position
+;;           (midje.parsing.util.file-position/line-number-known 18)))
+;;         [])))))
+;;    (clojure.core/merge
+;;     {:midje/guid "9a01710b2962f9945f24630a0579bba82671d1ef",
+;;      :midje/name "eagerly forces evaluation",
+;;      :midje/description "eagerly forces evaluation",
+;;      :midje/source
+;;      '(fact
+;;        "eagerly forces evaluation"
+;;        (reset! counter 1)
+;;        (mock-use)
+;;        @counter
+;;        =>
+;;        5),
+;;      :midje/namespace 'midje.util.t-one-seven,
+;;      :midje/file "midje/util/t_one_seven.clj",
+;;      :midje/line 17}
+;;     {:midje/top-level-fact? true}))))

 ;; After justification, more facts.


fixing tests

fixing tests

--- test/celestial/test/vc.clj
+++ test/celestial/test/vc.clj
@@ -6,22 +6,21 @@
     [celestial.model :refer (vconstruct)]
     [celestial.persistency :as p]
     [celestial.fixtures.data :refer (redis-vc-spec)]
-    [celestial.fixtures.core :refer (with-conf with-m?)]
+    [celestial.fixtures.core :refer (with-conf with-defaults with-m?)]
     [celestial.persistency.systems :as s])
   (:use midje.sweet)
   (:import clojure.lang.ExceptionInfo))

-(with-conf
-  (do
-    (fact "basic construction"
+(with-defaults
+   (fact "basic construction"
       (let [vm (vconstruct redis-vc-spec)]
-        (:allocation vm ) => {:datacenter "playground" :hostsystem "192.168.5.5" :pool "dummy" :disk-format :sparse}
+        (:allocation vm ) => {:datacenter "playground" :hostsystem "192.168.5.6" :pool "dummy" :disk-format :sparse}
         (:hostname vm)   => "red1"
         (:machine vm) => {:cpus 1 :memory 512
                           :password "foobar" :user "ronen" :sudo true
                           :gateway "192.168.5.1" :ip "192.168.5.91" :netmask "255.255.255.0"
                           :domain "local" :names ["8.8.8.8"] :search "local"
-                          :template "ubuntu-13.04_puppet-3.2"}))
+                          :template "ubuntu-13.04_puppet-3.3.2"}))

     (fact "missing datacenter"
           (vconstruct (assoc-in redis-vc-spec [:vcenter :datacenter] nil)) =>
@@ -62,8 +61,5 @@
         (s/validate-system (assoc-in redis-vc-spec [:machine :names] "bla")) =>
           (throws ExceptionInfo (with-m? {:machine {:names '("must be a vector")}}))
         (provided (p/user-exists? "admin")  => true)
-        (provided (p/type-exists? "redis")  => true))
-    ))
+        (provided (p/type-exists? "redis")  => true)))

-
-


Update manual snippet `pixels-update-pixels` to work with p5js. Issue #255.

--- test/cljs/quil/manual.cljs
+++ test/cljs/quil/manual.cljs
@@ -148,6 +148,7 @@
                      j (range 30)]
                (q/set-pixel (+ 40 i) (+ 40 j) (q/color 0 (* 7 i) (* 7 j)))))
            (q/no-loop)))
+
   (q/sketch
    :host "pixels-update-pixels"
    :size [500 500]
@@ -157,9 +158,19 @@
              (q/with-graphics gr
                (q/background 55))

-             (let [px (q/pixels gr)]
+             (let [px (q/pixels gr)
+                   c  (q/color 255)
+                   r  (q/red c)
+                   g  (q/green c)
+                   b  (q/blue c)
+                   a  (q/alpha c)]
                (dotimes [i 100]
-                 (aset px (* i i) (q/color 255))))
+                 (let [d (q/display-density)
+                       p (* 4 i i d d)]
+                   (aset px p r)
+                   (aset px (+ 1 p) g)
+                   (aset px (+ 2 p) b)
+                   (aset px (+ 3 p) a))))
              (q/update-pixels gr)

              (q/image gr 10 10))


Fixed unit test failed

Fixed unit test failed

--- test/control/test/core.clj
+++ test/control/test/core.clj
@@ -14,8 +14,8 @@

 (defn- arg-count [f] (let [m (first (.getDeclaredMethods (class f))) p (.getParameterTypes m)] (alength p)))
 (deftest test-gen-log
-  (is (= "localhost:ssh: test" (gen-log "localhost" "ssh" "test")))
-  (is (= "a.domain.com:scp: hello world" (gen-log "a.domain.com" "scp" "hello world"))))
+  (is (= "\033[1;31mlocalhost:\033[1;32mssh: \033[0mtest" (gen-log "localhost" "ssh" "test")))
+  (is (= "\033[1;31ma.domain.com:\033[1;32mscp: \033[0mhello world" (gen-log "a.domain.com" "scp" "hello world"))))

 (deftest test-ssh-client
   (is (= "apple@localhost" (ssh-client "localhost" "apple")))
@@ -25,8 +25,8 @@
 (deftest test-task
   (is (= 0 (count @tasks)))
   (deftask :test "test task"
-		[]
-		(+ 1 2))
+	[]
+	(+ 1 2))
   (is (= 1 (count @tasks)))
   (is (= 0 (count @clusters)))
   (is (function? (:test @tasks)))
@@ -37,10 +37,10 @@
 (deftest test-cluster
   (is (= 0 (count @clusters)))
   (defcluster :mycluster
-		   :clients [{:host "a.domain.com" :user "apple"}]
-		   :addresses ["a.com" "b.com"]
-		   :user "dennis"
-		   )
+	:clients [{:host "a.domain.com" :user "apple"}]
+	:addresses ["a.com" "b.com"]
+	:user "dennis"
+	)
   (is (= 0 (count @tasks)))
   (is (= 1 (count @clusters)))
   (let [m (:mycluster @clusters)]
@@ -52,14 +52,14 @@

 (defmacro with-private-fns [[ns fns] & tests]
   "Refers private fns from ns and runs tests in context."
-    `(let ~(reduce #(conj %1 %2 `(ns-resolve '~ns '~%2)) [] fns)
-         ~@tests))
+  `(let ~(reduce #(conj %1 %2 `(ns-resolve '~ns '~%2)) [] fns)
+	 ~@tests))

 (with-private-fns [control.core [perform spawn await-process]]
   (deftest test-perform
 	(deftask :test "test-task"
-		  [a b]
-		  (+ a b))
+	  [a b]
+	  (+ a b))
 	(let [t (:test @tasks)]
 	  (is (= 10 (perform 1 2 t :test '(3 4))))))
   (deftest test-spawn
@@ -69,7 +69,7 @@
 		(is (= 0 status))
 		(is (= "hello" (:stdout execp)))
 		(is (blank? (:stderr execp)))
-	))))
+		))))

 (deftest test-scp
   (binding [exec (fn [h u c] c)]


Add tests.

Add tests.

--- test/beicon/core_spec.cljs
+++ test/beicon/core_spec.cljs
@@ -30,6 +30,12 @@

 ;; event stream

+(defn log
+  [e ob]
+  (s/tap (fn [v]
+           (println "[log]:" e ":" v)
+           v) ob))
+
 (t/deftest observable-from-vector
   (t/async done
     (let [coll [1 2 3]
@@ -37,6 +43,29 @@
       (t/is (s/observable? s))
       (drain! s #(t/is (= % coll)))
       (s/on-end s done))))
+
+(t/deftest observable-from-vector-with-take
+  (t/async done
+    (let [coll [1 2 3 4 5 6]
+          s (->> (s/from-coll coll)
+                 (s/take 2))]
+      (t/is (s/observable? s))
+      (drain! s #(t/is (= % [1 2])))
+      (s/on-end s done))))
+
+(t/deftest observable-from-atom
+  (t/async done
+    (let [a (atom 0)
+          s (->> (s/from-atom a)
+                 (s/take 4))]
+      (t/is (s/observable? s))
+      (drain! s #(do
+                   (t/is (= % [1 2 3 4]))
+                   (done)))
+      (swap! a inc)
+      (swap! a inc)
+      (swap! a inc)
+      (swap! a inc))))

 (t/deftest observable-from-set
   (t/async done
@@ -94,45 +123,18 @@
       (drain! s #(t/is (= % [1])))
       (s/on-end s done))))

-(t/deftest observable-never
-  (t/async done
-    (let [n (s/never)]
-      (s/on-end n done))))
-
-;; (t/deftest observable-interval
+;; (t/deftest observable-never
 ;;   (t/async done
-;;     (let [i (s/interval 10)
-;;           sample (s/take 4 i)]
-;;       (drain! sample #(t/is (apply = %)))
-;;       (s/on-end sample done))))
-
-;; (t/deftest observable-later
+;;     (let [n (s/never)]
+;;       (s/on-end n done))))
+
+;; (t/deftest observable-on-value
 ;;   (t/async done
-;;     (let [s (s/later 10 42)]
-;;       (drain! s #(t/is (= % [42])))
-;;       (s/on-end s done))))
-
-;; (t/deftest observable-sequentially
-;;   (t/async done
-;;     (let [s (s/sequentially 10 [1 2 3])
-;;           sample (s/take 6 s)]
-;;       (drain! sample #(t/is (= % [1 2 3])))
-;;       (s/on-end sample done))))
-
-;; (t/deftest observable-repeatedly
-;;   (t/async done
-;;     (let [s (s/repeatedly 10 [1 2 3])
-;;           sample (s/take 6 s)]
-;;       (drain! sample #(t/is (= % [1 2 3 1 2 3])))
-;;       (s/on-end sample done))))
-
-(t/deftest observable-on-value
-  (t/async done
-    (let [s (s/from-coll [1 2 3])
-          vacc (volatile! [])]
-      (s/on-value s #(vswap! vacc conj %))
-      (s/on-end s #(do (t/is (= @vacc [1 2 3]))
-                       (done))))))
+;;     (let [s (s/from-coll [1 2 3])
+;;           vacc (volatile! [])]
+;;       (s/on-value s #(vswap! vacc conj %))
+;;       (s/on-end s #(do (t/is (= @vacc [1 2 3]))
+;;                        (done))))))

 (t/deftest observable-concat
   (t/async done
@@ -185,13 +187,6 @@
       (s/end! s)
       (s/end! sv))))

-;; ;; - bufferWithTime
-;; ;; - bufferWithCount
-;; ;; - bufferWithTimeOrCount
-;; ;; - toProperty
-
-;; ;; bus
-
 (t/deftest bus-push
   (t/async done
     (let [b (s/bus)]
@@ -203,97 +198,12 @@
       (s/end! b)
       (s/on-end b done))))

-
-;; TODO:
-;; (t/deftest bus-erro
-;;   (t/async done
-;;     (let [b (s/bus)]
-;;       (t/is (s/bus? b))
-;;       (drain! b #(t/is (= % [1]))
-;;                 #(t/is (= % :oh-no)))
-;;       (s/push! b 1)
-;;       (s/error! b (ex-info "oh noes" {})
-;;       (s/on-error b done))))
-
-;; (t/deftest bus-plug
-;;   (t/async done
-;;     (let [b (s/bus)]
-;;       (t/is (s/bus? b))
-;;       (s/plug! b (s/from-coll [1 2 3]))
-;;       (s/plug! b (s/from-coll [:four :five]))
-;;       (drain! b #(t/is (= %
-;;                           [1 2 3 :four :five])))
-;;       (s/end! b)
-;;       (s/on-end b done))))
-
 (t/deftest filter-with-predicate
   (t/async done
     (let [s (s/from-coll [1 2 3 4 5])
           fs (s/filter #{3 5} s)]
       (drain! fs #(t/is (= % [3 5])))
       (s/on-end fs done))))
-
-;; ;; ::todo decomplect
-;; ;; - filter (pred, property)
-;; ;; - map
-;; ;; - mapError
-;; ;; - errors
-;; ;; - skipErrors
-;; ;; - mapEnd
-;; ;; - skipDuplicates
-;; ;; - take
-;; ;; - takeUntil
-;; ;; - takeWhile
-;; ;; - first
-;; ;; - last
-;; ;; - skip
-;; ;; - delay
-;; ;; - throttle
-;; ;; - debounce
-;; ;; - debounceImmediate
-;; ;; - bufferingThrottle
-;; ;; - doAction
-;; ;; - doError
-;; ;; - not
-;; ;; - flatMap
-;; ;; - flatMapLatest
-;; ;; - flatMapFirst
-;; ;; - flatMapError
-;; ;; - flatMapWithConcurrencyLimit
-;; ;; - flatMapConcat
-;; ;; - scan
-;; ;; - fold/reduce
-;; ;; - diff
-;; ;; - zip
-;; ;; - slidingWindow
-;; ;; - log
-;; ;; - doLog
-;; ;; - combine
-;; ;; - withStateMachine
-;; ;; - decode
-;; ;; - awaiting
-;; ;; - endOnError
-;; ;; - withHandler
-;; ;; - name
-;; ;; - withDescription
-
-;; ;; TODO
-
-;; ;; - combineAsArray
-;; ;; - combineWith
-;; ;; - combineTemplate
-;; ;; - mergeAll
-;; ;; - zipAsArray
-;; ;; - zipWith
-;; ;; - onValues
-
-
-;; ;; TODO: error handling
-;; ;; - onError, ...
-;; ;; - retry
-
-;; ;; TODO: join
-;; ;; - when

 (t/deftest event-stream-as-functor
  (t/async done
@@ -329,8 +239,6 @@
                                   [3 :3]])))
       (s/on-end sample done))))

-;; ;; interop
-
 (t/deftest pipe-to-atom
   (t/async done
     (let [st (s/from-coll [1 2 3])


Formatting

Formatting

--- test/icecap/codec_test.clj
+++ test/icecap/codec_test.clj
@@ -7,4 +7,4 @@
   (testing "safebase64 passes KATs, round-trips"
     (are [raw enc] (and (= (safebase64-encode raw) enc)
                         (Arrays/equals (safebase64-decode enc) raw))
-         (.getBytes "The quick brown fox") "VGhlIHF1aWNrIGJyb3duIGZveA")))
+      (.getBytes "The quick brown fox") "VGhlIHF1aWNrIGJyb3duIGZveA")))


refactor(ccw.api.repl): removed println

refactor(ccw.api.repl): removed println

--- ccw.core/src/clj/ccw/api/repl.clj
+++ ccw.core/src/clj/ccw/api/repl.clj
@@ -15,7 +15,6 @@
                      user sent expression should be honored (defaults to false)"
   ([repl expr] (send repl expr false true false))
   ([repl expr add-to-history print-to-log repeat-last-eval]
-    (println "repl:" repl "expr:" expr)
     (when (and repl expr)
       (.evalExpression repl expr
         (boolean add-to-history)


improved formatting just a tiny bit

improved formatting just a tiny bit

These double spaces around the number always bugged me...

--- core/src/gorillalabs/tesla.clj
+++ core/src/gorillalabs/tesla.clj
@@ -15,7 +15,7 @@
 (defn wait! [conf]
   (if-let [wait-time (config/config conf [:wait-ms-on-stop])]
     (try
-      (log/info "<- Waiting " wait-time " milliseconds.")
+      (log/info "<- Waiting" wait-time "milliseconds.")
       (Thread/sleep wait-time)
       (catch Exception e (log/error e)))))


Clarify that these are nonced ctexts

Clarify that these are nonced ctexts

--- src/caesium/magicnonce/secretbox.clj
+++ src/caesium/magicnonce/secretbox.clj
@@ -126,20 +126,20 @@

 (defn decrypt-to-buf!
   "Decrypts any secretbox message with a prefix nonce into the given buffer."
-  [out key ctext])
+  [out key nonced-ctext])

 (defn decrypt
   "Decrypts any secretbox message with a prefix nonce."
-  [key ctext])
+  [key nonced-ctext]

 (defn open-to-buf!
   "Like [[decrypt-to-buf!]], but with different argument order;
   analogous to [[caesium.crypto.secretbox/secretbox-open-easy-to-buf!]]."
-  [out ctext key]
+  [out nonced-ctext key]
   (decrypt-to-buf! out key ctext))

 (defn open
   "Like [[decrypt]], but with different argument order; analogous to
   [[caesium.crypto.secretbox/secretbox-open-easy]]."
-  [ctext key]
+  [nonced-ctext key]
   (decrypt key ctext))


restore validation rules

restore validation rules

--- src/clj_money/models/commodities.clj
+++ src/clj_money/models/commodities.clj
@@ -90,6 +90,7 @@

 (def create
   (create-fn {:before-save before-save
+              :rules-fn validation-rules
               :coercion-rules coercion-rules
               :spec ::new-commodity
               :create create-commodity


[REFACTOR] Add `document-location-hash-reset!` function

Signed-off-by: Pang Yan Han <22594c345857f664c61cd411f607c4d40a9d4af9@gmail.com>

--- src/cljs/cljs_nusmods/timetable.cljs
+++ src/cljs/cljs_nusmods/timetable.cljs
@@ -415,6 +415,11 @@
                      (re-pattern (str moduleCode "_" lessonType "=[^&]+"))
                      (str moduleCode "_" lessonType "=" newLessonGroup))]
     (set-document-location-hash! newUrlHash)))
+
+(defn- document-location-hash-reset!
+  "Resets `document.location.hash` to the empty string"
+  []
+  (set-document-location-hash! ""))

 (def ^{:doc "Vector of <tBody> objects representing the days of the timetable
              in the Timetable Builder page"
@@ -1557,4 +1562,4 @@
   (reset-ModulesSelected!)
   (reset-ModulesSelectedOrder!)
   (select2-box-update-modules)
-  (set-document-location-hash! ""))
+  (document-location-hash-reset!))


workaround for safari where POST /contributions beats GET /contributions

safari was trying to stream contributions before sse stream had been started

--- src/github_contributions/service.clj
+++ src/github_contributions/service.clj
@@ -24,19 +24,30 @@
     (swap! subscribers assoc id sse-context)
     (log/error :msg "No id passed to /contributions. Ignored.")))

-(defn update-contributions [request]
+(defn- get-sse-context
+  "If sse-context doesn't exist yet, sleep and try again. This was needed for safari and
+opening a user url in a new tab."
+  [id]
+  (if-let [sse-context (get @subscribers id)]
+    sse-context
+    (do
+      (log/info :msg "Waiting 500ms for sse-context to start.")
+      (Thread/sleep 500)
+      (get @subscribers id))))
+
+(defn stream-contributions-page [request]
   (if-let [id (get-in request [:form-params "id"])]
-    (if-let [sse-context (get @subscribers id)]
+    (if-let [sse-context (get-sse-context id)]
       (stream-contributions sse/send-event sse-context (get-in! request [:form-params "user"]))
       (log/error :msg (str "No sse context for id " id)))
-    (log/error :msg "No id passed to update contributions. Ignored.")))
+    (log/error :msg "No id passed to stream contributions. Ignored.")))

 (defroutes routes
   [[["/"
      ;; Set default interceptors for /about and any other paths under /
      ^:interceptors [(body-params/body-params) bootstrap/html-body]
      ["/contributions" {:get [::contributions (sse/start-event-stream contributions-page)]
-                        :post update-contributions}]
+                        :post stream-contributions-page}]
      ["/*user" {:get home-page}]]]])

 ;; You can use this fn or a per-request fn via io.pedestal.service.http.route/url-for


fix string-only test call.

fix string-only test call.

--- src/leiningen/ancient/utils/test.clj
+++ src/leiningen/ancient/utils/test.clj
@@ -23,6 +23,7 @@
   (let [task (or (get-in project [:aliases "test-ancient"])
                  (get-in project [:aliases "test"])
                  "test")
+        task (if (sequential? task) task [task])
         r (run-test-task! project task)]
     (when-not r
       (main/info "Tests failed (use ':no-tests' if you want to suppress testing)."))


Rewrite von concept probability.

Rewrite von concept probability.

New implementation uses an incremental approach to
compute the powers of the probabilities and the binomial
coefficient.

The fast computation can no be triggered by a
binding,

(binding [*fast-computation* true] body)

which executes the whole computation in double instead of
fractions.

--- src/main/clojure/conexp/fca/misc.clj
+++ src/main/clojure/conexp/fca/misc.clj
@@ -9,12 +9,13 @@
 (ns conexp.fca.misc
   "More on FCA."
   (:require [conexp.base :refer :all]
+            [clojure.core.reducers :as r]
             [conexp.fca
              [contexts :refer :all]
              [exploration :refer :all]
-             [implications :refer :all]]
-            [conexp.math
-             [util :refer [binomial-coefficient]]]))
+             [implications :refer :all]]))
+
+(def ^:dynamic *fast-computation* nil)

 ;;; Compatible Subcontexts

@@ -248,40 +249,29 @@
   which is: $\\sum_{k=0}^n {n\\choose k} p_B^k(1-p_B)^{n-k}\\prod_{m\\in
   M\\setminus B}(1-p_m^k).$"
   [context concept]
-  (let [n (count (objects context))
+  (let [nr_of_objects (count (objects context))
+        n  (if *fast-computation* (double nr_of_objects) nr_of_objects)
         M (attributes context)
         B (second concept) ; intent of concept
-        P_M_B (map #(/ (count (attribute-derivation context #{%})) n ) (difference M B))
-        p_B (reduce * (pmap #(/ (count (attribute-derivation context #{%})) n) B))
-        k_barrier (/ (Math/log 1E-16) (Math/log (apply max P_M_B)))]
-    (reduce + (pmap (fn [k]
-                       (* (binomial-coefficient n k)
-                          (expt p_B k)
-                          (expt (- 1 p_B) (- n k))
-                          (reduce * (map #(- 1 (expt % k)) P_M_B)))) (range 1 (inc n))))))
-
-(defn faster-concept-probability
-  "In case some of the powers are evaluated in double precision
-  arithmetic we might get loose of some of the last factors. When
-  $p_m^k$ is smallen than the Wilinson Epsilon we might gain no effect
-  by subtracting it form 1. Therefore we compute some `kbarrier' value
-  for the greatest $p_m$. For k bigger than that we omit the last
-  factor.  Be aware, if you have *many* attributes in the context this
-  might lead to errors."
-  [context concept]
-  (let [n (count (objects context))
-        M (attributes context)
-        B (second concept) ; intent of concept
-        P_M_B (pmap #(/ (count (attribute-derivation context #{%})) n ) (difference M B))
-        p_B (reduce * (pmap #(/ (count (attribute-derivation context #{%})) n) B))
-        k_barrier (int (/ (Math/log 1E-16) (Math/log (apply max P_M_B))))]
-    (+
-     (reduce + (pmap (fn [k]
-                       (* (binomial-coefficient n k)
-                          (expt p_B k)
-                          (expt (- 1 p_B) (- n k))
-                          (reduce * (map #(- 1 (Math/pow % k)) P_M_B)))) (range 1 k_barrier)))
-     (reduce + (pmap (fn [k]
-                       (* (binomial-coefficient n k)
-                          (expt p_B k)
-                          (expt (- 1 p_B) (- n k)))) (range (inc k_barrier) (inc n)))))))
+        P_M_B (mapv #(/ (count (attribute-derivation context #{%})) n ) (difference M B))
+        p_B (r/fold * (map #(/ (count (attribute-derivation context #{%})) n) B))
+        one_minus_p_B_n (expt (- 1 p_B) n)]
+    (loop [
+           k 1  ;; since for k=0 the last term is 0, we can start with 1
+           result 0
+           binomial n ;; since k=0 the start binomial is n
+           p_B_k  p_B
+           one_minus_p_B_k  (/ one_minus_p_B_n (- 1 p_B))
+           P_M_B_k P_M_B ]
+      (if (or (== k n) (== p_B_k 0)) ;; either done or underflowed probability (double)
+        result
+        (let [new_res
+              (* binomial p_B_k one_minus_p_B_k
+                 (r/fold * (map #(- 1 %) P_M_B_k)))]
+          (recur
+           (inc k)
+           (+ new_res result)
+           (* binomial (/ (- n k) (inc k)))
+           (* p_B_k p_B)
+           (/ one_minus_p_B_k (- 1 p_B))
+           (mapv (partial *) P_M_B_k P_M_B)))))))


clean up (transform) a little

clean up (transform) a little

--- src/main/java/org/dada/demo/core.clj
+++ src/main/java/org/dada/demo/core.clj
@@ -146,19 +146,15 @@
     )))

 ;; (transform input-model src-class property-map input-names view output-class)
-(defn transform [model model-class property-map expanded-properties view view-class]
-  (if (= (map (fn [x] (nth x 1)) expanded-properties) (keys property-map))
+(defn transform [model model-class property-map sel-getters tgt-names view view-class]
+  (if (= tgt-names (keys property-map))
     ;; we are selecting all the fields in their original order - no
     ;; need for a transformation...
     ;; N.B. if just order has changed, could we just reorder metadata ?
-    (do
-      (connect model view)
-      view)
+    (connect model view)
     ;; we need some sort of transformation...
-    (let [getters (map (fn [x] (nth x 2)) expanded-properties)
-	  transformer (make-transformer getters view view-class)]
-      (connect model transformer)
-      )))
+    (connect model (make-transformer sel-getters view view-class))
+    ))

 ;; properties is a vector of property descriptions of the form:
 ;; [input-name output-type output-name]
@@ -204,6 +200,7 @@
 	fields (make-fields src-class src-map props) ; selection ([type name ...])
    	tgt-types (map (fn [field] (nth field 0)) fields)
    	tgt-names (map (fn [field] (nth field 1)) fields)
+   	sel-getters (map (fn [field] (nth field 2)) fields)
 	tgt-props (map (fn [field] [(nth field 0) (nth field 1)]) fields) ; ([type name]..)
 	class-factory (new ClassFactory)
   	tgt-class (apply make-class class-factory tgt-class-name tgt-props)
@@ -213,7 +210,7 @@
    	tgt-version-getter (tgt-getter-map version-name)
 	tgt-metadata (new GetterMetadata tgt-class tgt-types tgt-names tgt-getters)
 	view (VersionedModelView. tgt-model-name tgt-metadata tgt-key-getter tgt-version-getter)
-	transformer (transform src-model src-class src-map fields view tgt-class)]
+	transformer (transform src-model src-class src-map sel-getters tgt-names view tgt-class)]
     view)
   )


Fix routes_test with the new reality

Fix routes_test with the new reality

--- test/vignette/http/routes_test.clj
+++ test/vignette/http/routes_test.clj
@@ -121,7 +121,7 @@
     (provided
      (u/get-or-generate-thumbnail ..system.. route-params) => nil
      (ir/error-image route-params) => ..thumb..
-     (ir/create-image-response ..thumb..) => {})
+     (ir/create-image-response ..thumb.. route-params) => {})

     ((app-routes ..system..) (request :get "/lotr/3/35/ropes.jpg/revision/latest/thumbnail/width/10/height/10")) => (contains {:status 500})
     (provided


Introducing various optimizations

Introducing various optimizations

--- jvm-runner/project.clj
+++ jvm-runner/project.clj
@@ -11,6 +11,7 @@
   :source-paths      ["src/clojure"]
   :java-source-paths ["src/java"]
   :env {:timeout "2000"}
-  :profiles {:uberjar {:aot :all}
-             :env {:timeout "2000"}}
+  :profiles {:uberjar {:aot :all
+                       :omit-source true
+                       :javac-options ["-g:none"]}}
   :main codewars.core)


Updated Hiccup to 1.0.0-RC3

Updated Hiccup to 1.0.0-RC3

--- ring-devel/project.clj
+++ ring-devel/project.clj
@@ -2,6 +2,6 @@
   :description "Ring development and debugging libraries."
   :url "http://github.com/mmcgrana/ring"
   :dependencies [[ring/ring-core "1.1.0-RC1"]
-                 [hiccup "1.0.0-RC2"]
+                 [hiccup "1.0.0-RC3"]
                  [clj-stacktrace "0.2.4"]
                  [ns-tracker "0.1.1"]])


Fixed bug when there are no drifters to attack

--- desktop/src-common/ds3/enemy.clj
+++ desktop/src-common/ds3/enemy.clj
@@ -127,10 +127,13 @@
                           drifters (shuffle (filter #(= (:movement-state %) :drifting) enemies))
                           non-drifters (filter #(not= (:movement-state %) :drifting) enemies)
                           entity (first drifters)
-                          attacker (assoc entity :movement-state (state-machine (:movement-state entity)) :current-time 0
-                                     :spline (splines/calibrate-spline (:x entity) (:y entity) (:row entity)))]
+                          attacker (cond entity
+                                         (assoc entity :movement-state (state-machine (:movement-state entity)) :current-time 0
+                                           :spline (splines/calibrate-spline (:x entity) (:y entity) (:row entity)))
+                                         :else nil)]
                       ;(prn :entities (count entities) :enemies (count enemies) :non-enemies (count non-enemies) :drifters (count drifters) :non-drifters (count non-drifters))
-                      (conj (conj (conj (rest drifters) attacker) non-drifters) non-enemies)))
+                      (cond (nil? attacker) entities
+                            :else (conj (conj (conj (rest drifters) attacker) non-drifters) non-enemies))))
           :else entities)))

 (defn update-home [entity screen]


caseless

caseless

--- web/celestial/routes/system.clj
+++ web/celestial/routes/system.clj
@@ -2,6 +2,7 @@
   "System routes"
  (:use compojure.core)
  (:require
+    [clojure.core.strint :refer  (<<)]
     [celestial.routes.common :refer [per-page base]]
     [celestial.model :refer [figure-virt]]
     [celestial.models.system :as sys]
@@ -40,13 +41,9 @@
 (defn- system
   "renders a system"
   [id]
-  (let [system (sys/system id)]
-    (case (figure-virt system)
-      :proxmox
-        (layout/render "proxmox.html" (into base {:system (update-in system [:machine :os] name)}))
-      :aws  (layout/render "aws.html" (into base {:system system}))
-      )
-    ))
+  (let [system (sys/system id)
+        props (into base {:system system })]
+     (layout/render (<<  "~(-> system figure-virt name).html") props)))

 (defroutes system-routes
   (GET "/view/systems" [from to] (systems (Integer/parseInt from) (Integer/parseInt to)))


perplexity experiments

perplexity experiments


track when the signup buttons are hovered over

--- frontend/components/landing.cljs
+++ frontend/components/landing.cljs
@@ -242,7 +242,8 @@
                          :ref "prolog-cta"
                          :on-click #(raise! owner [:track-external-link-clicked {:event "Auth GitHub"
                                                                                :properties {:source "prolog-cta"}
-                                                                                :path (auth-url)}])}
+                                                                                :path (auth-url)}])
+                         :on-mouse-enter #(raise! owner [:prolog-cta-hovered])}
          "Sign Up Free"]
         [:div.home-cover]
         [:div.home-top-shelf]
@@ -464,7 +465,8 @@
                          :role "button"
                          :on-click #(raise! owner [:track-external-link-clicked {:event "Auth GitHub"
                                                                                :properties {:source "epilog-cta"}
-                                                                                :path (auth-url)}])}
+                                                                                :path (auth-url)}])
+                         :on-mouse-enter #(raise! owner [:epilog-cta-hovered])}
          "Sign Up Free"]
         [:div.home-cover]
         [:div.home-top-shelf]


Remove #56 workarounds, add second, ffirst, nfirst, fnext

--- lib/shin/cljs/cljs/core.cljs
+++ lib/shin/cljs/cljs/core.cljs
@@ -41,11 +41,7 @@
   ([coll k v & kvs]
    (let [ret (assoc coll k v)]
      (if kvs
-       ; TODO: use recur instead when #56 is fixed
-       ; (recur ret (first kvs) (second kvs) (nnext kvs))
-       (let [args (into-array kvs)]
-         (.unshift args ret)
-         (.apply assoc nil args))
+       (recur ret (first kvs) (second kvs) (nnext kvs))
        ret))))

 (defn dissoc
@@ -385,6 +381,31 @@
       (if (nil? s)
         nil
         (-first s)))))
+
+(defn second
+  "Same as (first (next x))"
+  [coll]
+  (first (next coll)))
+
+(defn ffirst
+  "Same as (first (first x))"
+  [coll]
+  (first (first coll)))
+
+(defn nfirst
+  "Same as (next (first x))"
+  [coll]
+  (next (first coll)))
+
+(defn fnext
+  "Same as (first (next x))"
+  [coll]
+  (first (next coll)))
+
+(defn nnext
+  "Same as (next (next x))"
+  [coll]
+  (next (next coll)))

 (defn last
   "Return the last item in coll, in linear time"


Typo in PersistentHashSet.-equiv

Typo in PersistentHashSet.-equiv

--- lib/shin/cljs/cljs/core.cljs
+++ lib/shin/cljs/cljs/core.cljs
@@ -2088,7 +2088,7 @@
     (if (and (instance? PersistentHashSet other)
              (== (count coll) (count other)))
       (let [keys (hamt/keys h)
-            len   (length keys)]
+            len   (alength keys)]
         (loop [i 0]
           (if (< i len)
             (let [k (aget keys i)]


Changed localizations and added a new key.

--- app/src/weather/localization.cljc
+++ app/src/weather/localization.cljc
@@ -2,11 +2,12 @@

 (def dictionary {:title "Weather with Clojure from Wunderground!"
                  :submit "Show me the weather!"
+                 :current-weather "Here is the current weather:"
                  :data-arrived "Here is the weather data you wanted:"
-                 :fog "Fog!"
-                 :rain "Rain!"
-                 :snow "Snow!"
-                 :hail "Hail!"
+                 :fog "There was some fog to be seen!"
+                 :rain "It rained!"
+                 :snow "It snowed!"
+                 :hail "There was some hail!"
                  :highest "Highest temp (celsius): "
                  :lowest "Lowest temp (celsius): "
                  :bad-request "Bad request! Maybe you are trying to look too


font size fix

font size fix

--- src/mobile_patient/screen/chats.cljs
+++ src/mobile_patient/screen/chats.cljs
@@ -65,7 +65,7 @@
                     :margin-top 20
                     :margin-bottom 20
                     :color color/pink
-                    :font-size font-size
+                    :font-size 14
                     :font-weight :bold}}
         text])


jobs/pre/altcrawl.clj: removed obsolete job

Replaced by multiple jobs under jobs/web/

--- src/org/altlaw/jobs/pre/altcrawl.clj
+++ src/org/altlaw/jobs/pre/altcrawl.clj
@@ -1,205 +0,0 @@
-(ns org.altlaw.jobs.pre.altcrawl
-  (:require [org.altlaw.util.hadoop :as h]
-            [org.altlaw.util.files :as files]
-            [org.altlaw.util.tsv :as tsv]
-            [org.altlaw.util.jruby :as ruby]
-            [org.altlaw.util.context :as context]
-            [org.altlaw.util.log :as log]
-            [org.altlaw.util.merge-fields :as merge]
-            [org.altlaw.db.docids :as ids]
-            [org.altlaw.extract.pdf :as pdf]
-            [clojure.contrib.walk :as walk]
-            [clojure.contrib.singleton :as sing]
-            [clojure.set :as set])
-  (:use clojure.contrib.json.read
-        org.altlaw.util.log)
-  (:import (org.altlaw.extract PROHTMLToText)
-           (org.apache.commons.codec.binary Base64)
-           (javax.script ScriptContext ScriptEngine ScriptEngineManager)
-           (java.io StringReader)))
-
-(h/setup-mapreduce)
-
-(def scraper-handler
-     (sing/per-thread-singleton
-      (fn []
-        (ruby/eval-jruby "require 'org/altlaw/extract/scrape/scraper_handler'")
-        (ruby/eval-jruby "ScraperHandler.new"))))
-
-(defn- decode-response-body [download]
-  (assoc download :response_body_bytes
-         (Base64/decodeBase64
-          (.getBytes (:response_body_base64 download) "UTF-8"))))
-
-
-;; DIAGRAM OF CONTROL FLOW
-;;
-;; status-code-dispatch
-;;  |                |
-;;  |               warn
-;;  |
-;; mime-type-dispatch----------------------
-;;  |                   |                 |
-;;  |                   |                 |
-;; handle-html         pdf-docid-dispatch        warn
-;;  |       |           |      |
-;;  |      warn         |     warn
-;;  |                   |
-;; scraper-dispatch    convert-pdf
-;;  |
-;; (for each case found)
-;;  |
-;;  |
-;; handle-scraped
-;;  |
-
-
-
-
-;; Step 3 (for HTML): Run scrapers
-
-(defn get-primary-url [record]
-  (when-let [links (get record :links)]
-    (get links "application/pdf")))
-
-(defn get-all-urls [record]
-  (when-let [links (get record :links)]
-    (vals links)))
-
-(defn handle-scraper-record [record]
-  (h/counter "Scraper output records" "Total")
-  (let [data (ruby/convert-jruby record)]
-    (if (contains? data :exception)
-      (do (h/counter "Scraper output records" "Errors")
-          [:scraper-error data])
-      (if-let [docid (some #(ids/get-docid "altcrawl" %) (get-all-urls data))]
-        (do (h/counter "Scraper output records" "With docid")
-            [docid data])
-        (do (h/counter "Scraper output records" "Docid requested")
-            [:docid-request (ids/make-docid-request "altcrawl" (get-all-urls data))])))))
-
-(defn run-scrapers [download]
-  (filter identity
-          (map handle-scraper-record
-               (ruby/eval-jruby "$handler.parse(Download.from_map($dmap))"
-                                {:dmap (walk/stringify-keys download)
-                                 :handler (scraper-handler)}))))
-
-
-;;; Step 4 (for PDFs): convert to HTML
-
-(defn convert-pdf [docid download]
-  (debug "converting PDF to HTML for " (:request_uri download))
-  (let [html (pdf/pdf-to-html (str docid) (:response_body_bytes download))
-        text (PROHTMLToText/filter html)]
-    [[docid {:html html, :text text}]]))
-
-;;; Step 3 (for PDFs): dispatch on presence of Docid
-
-(defn pdf-docid-dispatch [download]
-  (if-let [docid (ids/get-docid "altcrawl" (:request_uri download))]
-    (do (debug "pdf-docid-dispatch got docid " docid " for " (:request_uri download))
-        (h/counter "PDF files" "with docid")
-        (convert-pdf docid download))
-    (do (warn "pdf-docid-dispatch found no docid for " (:request_uri download))
-        (h/counter "PDF files" "no docid")
-        nil)))
-
-
-;;; Step 2: dispatch on MIME type of the download
-
-(defmulti mime-type-dispatch
-  (fn [download]
-    (files/guess-mime-type-by-content (:response_body_bytes download))))
-
-(defmethod mime-type-dispatch "application/pdf" [download]
-  (h/counter "MIME types" "PDF")
-  (debug "mime-type-dispatch got PDF from " (:request_uri download))
-  (pdf-docid-dispatch download))
-
-(defmethod mime-type-dispatch "text/html" [download]
-  (h/counter "MIME types" "HTML")
-  (debug "mime-type-dispatch got HTML from " (:request_uri download))
-  (run-scrapers download))
-
-(defmethod mime-type-dispatch :default [download]
-  (h/counter "MIME types" "unknown")
-  (warn "mime-type-dispatch found no handler for " (:request_uri download)))
-
-
-;;; Step 1: dispatch on Status code of the download
-
-(defn status-code-dispatch [download]
-  (h/counter "Status codes" (str (:response_status_code download)))
-  (if (= 200 (:response_status_code download))
-    (mime-type-dispatch download)
-    (warn "status-code-dispatch saw "
-          (:response_status_code download)
-          " from " (:request_uri download))))
-
-
-(defn my-map [key download]
-  (status-code-dispatch (decode-response-body download)))
-
-
-
-;;; REDUCER IMPLEMENTATION
-
-(defn merge-docs [docid documents]
-  (let [doc (merge/merge-fields documents)]
-    (if (and (:html doc) (:text doc))
-      [[docid doc]]
-      (do (h/counter "No html/text")
-          (log/warn "No html/text; skipping " docid)))))
-
-(defn assign-docids [requests]
-  (doseq [r requests]
-    (ids/handle-docid-request r))
-  (ids/save-docids "altcrawl")
-  (ids/save-next-docid)
-  nil)
-
-(defn my-reduce [key documents]
-  (cond
-    (= key :docid-request) (assign-docids documents)
-    (= key :exception) nil
-    (integer? key) (merge-docs key documents)))
-
-
-
-;;; MAPPER METHODS
-
-(defn mapper-configure [this job]
-  (context/use-hadoop-jobconf job))
-
-(def mapper-map (partial h/json-map my-map))
-
-
-
-;;; REDUCER METHODS
-
-(defn reducer-configure [this job]
-  (context/use-hadoop-jobconf job))
-
-(def reducer-reduce (partial h/standard-reduce my-reduce))
-
-
-
-
-;;; TOOL METHODS
-
-(defn tool-run [this args]
-  (let [job (h/default-jobconf this)
-        outpath (Path. (h/job-path :pre :altcrawl))
-        hdfs (FileSystem/get job)]
-    (.setJobName job "pre.altcrawl")
-    (FileInputFormat/setInputPaths job (str (h/job-path :seqfiles :altcrawl) "/*.jsr"))
-    (FileOutputFormat/setOutputPath job outpath)
-    (.setInputFormat job TextInputFormat)
-    (.delete hdfs outpath true)
-    (.setMapperClass job (Class/forName "org.altlaw.jobs.pre.altcrawl_mapper"))
-    (.setReducerClass job (Class/forName "org.altlaw.jobs.pre.altcrawl_reducer"))
-    (.setMapOutputKeyClass job Text)
-    (DistributedCache/addCacheFile (URI. (h/docid-path :seqfiles :ohm1)) job)
-    (JobClient/runJob job))
-  0)


add `mbql->native` and `execute-query` implementations to bigquery driver.

--- src/metabase/driver/bigquery.clj
+++ src/metabase/driver/bigquery.clj
@@ -154,9 +154,9 @@
    :fields (set (table-schema->metabase-field-info (.getSchema (get-table database table-name))))})

-(defn- ^QueryResponse execute-query
+(defn- ^QueryResponse execute-bigquery
   ([{{:keys [project-id]} :details, :as database} query-string]
-   (execute-query (database->client database) project-id query-string))
+   (execute-bigquery (database->client database) project-id query-string))

   ([^Bigquery client, ^String project-id, ^String query-string]
    {:pre [client (seq project-id) (seq query-string)]}
@@ -222,7 +222,7 @@
   ;; automatically retry the query if it times out or otherwise fails. This is on top of the auto-retry added by `execute` so operations going through `process-native*` may be
   ;; retried up to 3 times.
   (u/auto-retry 1
-    (post-process-native (execute-query database query-string))))
+    (post-process-native (execute-bigquery database query-string))))

 (defn- process-native [{database :database, {native-query :query} :native}]
   (process-native* database native-query))
@@ -345,6 +345,21 @@
         sql        (korma-form->sql korma-form)]
     (sqlqp/log-korma-form korma-form sql)
     (post-process-mbql dataset-id table-name (process-native* database sql))))
+
+(defn- mbql->native [{{{:keys [dataset-id]} :details, :as database} :database, {{table-name :name} :source-table} :query, :as query}]
+  {:pre [(map? database) (seq dataset-id) (seq table-name)]}
+  (let [korma-form (korma-form query (entity dataset-id table-name))
+        sql        (korma-form->sql korma-form)]
+    (sqlqp/log-korma-form korma-form sql)
+    {:query      sql
+     :table-name table-name
+     :mbql?      true}))
+
+(defn- execute-query [{{{:keys [dataset-id]} :details, :as database} :database, {sql :query, :keys [table-name mbql?]} :native}]
+  (let [results (process-native* database sql)]
+    (if mbql?
+      (post-process-mbql dataset-id table-name results)
+      results)))

 ;; This provides an implementation of `prepare-value` that prevents korma from converting forms to prepared statement parameters (`?`)
 ;; TODO - Move this into `metabase.driver.generic-sql` and document it as an alternate implementation for `prepare-value` (?)
@@ -443,8 +458,8 @@
                                                :display-name "Auth Code"
                                                :placeholder  "4/HSk-KtxkSzTt61j5zcbee2Rmm5JHkRFbL5gD5lgkXek"
                                                :required     true}])
+          :execute-query         (u/drop-first-arg execute-query)
           :field-values-lazy-seq (u/drop-first-arg field-values-lazy-seq)
-          :process-native        (u/drop-first-arg process-native)
-          :process-mbql          (u/drop-first-arg process-mbql)}))
+          :mbql->native          (u/drop-first-arg mbql->native)}))

 (driver/register-driver! :bigquery (BigQueryDriver.))


Less compiler improvements

Less compiler improvements

No longer recompiling on every reset, but checks staleness

--- modules/less/src/modular/less.clj
+++ modules/less/src/modular/less.clj
@@ -7,24 +7,64 @@
    [clj-less.less :refer (run-compiler)]
    [clojure.java.io :as io]
    [modular.bidi :refer (WebService)]
-   [ring.util.response :refer (file-response)]))
+   [ring.util.response :refer (file-response content-type)]))

-(defrecord LessCompiler []
+(defn source->target [path]
+  (when-let [[_ s] (re-matches #"(.*)\.less" path)]
+    (str s ".css")))
+
+(defn stale? [source-dir target]
+  (>
+   (apply max (conj (map #(.lastModified %) (.listFiles (io/file source-dir))) 1))
+   (.lastModified (io/file target))))
+
+(defrecord LessCompiler [uri-context source-dir source-path target-dir target-path]
   Lifecycle
   (start [this]
-    (run-compiler this)
-    this)
-  (stop [this] this))
+    (let [target-path (or target-path (source->target source-path))
+          target (io/file target-dir target-path)]
+      (when (stale? source-dir target)
+        (run-compiler (assoc this
+                             :source-path (str source-path)
+                             :target-path (str target)
+                             )))
+      (assoc this :target target :target-path target-path)))
+
+  (stop [this] this)
+
+  WebService
+  (request-handlers [_] {})
+
+  (routes [this]
+    ["/" [[(:target-path this)
+           (fn [_]
+             (-> (:target this)
+               str file-response
+               (content-type "text/css")))]]])
+
+  (uri-context [_] uri-context))
+
+(def default-src-dir "src/less")

 (defn new-less-compiler [& {:as opts}]
   (->> opts
-       (merge {:engine :nashorn
-               :loader #(slurp (str "resources/less/" %))})
-       (s/validate {:engine (s/enum :javascript :rhino :nashorn)
-                    :loader (s/=> s/Str s/Str)
-                    :source-path s/Str
-                    :target-path s/Str})
-       map->LessCompiler))
+    (merge
+     {:engine :nashorn
+      :source-dir default-src-dir
+      :loader #(slurp (str (io/file (or (:source-dir opts) default-src-dir) %)))
+      :target-dir "target/css"
+      :uri-context "/css"})
+    (s/validate
+     {:engine (s/enum :javascript :rhino :nashorn)
+      :loader (s/=> s/Str s/Str)
+      :source-dir s/Str
+      :source-path s/Str
+      :target-dir s/Str
+      ;; target-path, if missing, will be a result of concatenating the
+      ;; target-dir with the source-path (with a css suffix)
+      (s/optional-key :target-path) s/Str
+      :uri-context s/Str})
+    map->LessCompiler))

 (defrecord CustomBootstrapLessCompiler [version resource-dir target-path]
   Lifecycle
@@ -47,9 +87,7 @@
                          (let [res-path (format "META-INF/resources/webjars/bootstrap/%s/%s" version bootstrap-path)]
                            (io/resource res-path))
                          x)))))]
-      (if (>
-           (apply max (conj (map #(.lastModified %) (.listFiles (io/file resource-dir))) 1))
-           (.lastModified (io/file target-path)))
+      (if (stale? resource-dir target-path)
         (do
           (println "Compiling bootstrap less files")
           (run-compiler this))
@@ -59,9 +97,9 @@

   WebService
   (request-handlers [_]
-    {::css (fn [_] (file-response target-path))})
+    {::bootstrap-css (fn [_] (file-response target-path))})
   (routes [_]
-    ["/" {"css/bootstrap.css" ::css}])
+    ["/" {"css/bootstrap.css" ::bootstrap-css}])
   (uri-context [_]
     "/custom-bootstrap"))


Use more basic thread handoff from MIDI events.

Apparently core.async uses too many tricks to be efficient with threads,
which was defeating my purpose in trying to take MIDI event processing
away from the MIDI extension threads which have classloader issues. Use
a basic BlockingQueue and my own dedicated thread to be darn sure. This
change makes it so I can start a show for the first time using the Stop
button on the Ableton Push, and everything finally works. Whew!

--- src/afterglow/midi.clj
+++ src/afterglow/midi.clj
@@ -1,12 +1,12 @@
 (ns afterglow.midi
   "Handles MIDI communication, including syncing a show metronome to MIDI clock pulses."
   (:require [afterglow.rhythm :refer :all]
-            [clojure.core.async :refer [chan go <! >!! thread]]
             [amalloy.ring-buffer :refer [ring-buffer]]
             [overtone.at-at :refer [now]]
             [overtone.midi :as midi]
             [taoensso.timbre :refer [info error]])
-  (:import [java.util.regex Pattern]))
+  (:import [java.util.regex Pattern]
+           [java.util.concurrent LinkedBlockingQueue]))

 (def ^:private max-clock-intervals
   "How many MIDI clock pulses should be kept around for averaging?"
@@ -60,11 +60,18 @@
   (doseq [handler (vals (get-in @control-mappings [(:name (:device msg)) (:channel msg) (:note msg)]))]
     (handler msg)))

-(defonce ^:private ^{:doc "The channel used to hand MIDI events from
+(defonce ^:private ^{:doc "The queue used to hand MIDI events from
   the extension thread to our world, since there seem to be
   classloader compatibility issues, and the Java3d classes are not
   available to threads that are directly dispatching MIDI events."}
-  channel
+  midi-queue
+  (LinkedBlockingQueue.))
+
+(defonce ^:private ^{:doc "The thread used to hand MIDI events from
+  the extension thread to our world, since there seem to be
+  classloader compatibility issues, and the Java3d classes are not
+  available to threads that are directly dispatching MIDI events."}
+  midi-transfer-thread
   (atom nil))

 (defn- delegated-message-handler
@@ -74,8 +81,8 @@
   variable mappings, etc.) and dispatches to the appropriate specific
   handler."
   []
-  (go
-    (loop [msg (<! @channel)]
+  (let [running (atom true)]
+    (loop [msg (.take midi-queue)]
       (when msg
         ;; First call the global message handlers
         (doseq [handler @global-handlers]
@@ -93,11 +100,14 @@
             (:timing-clock :start :stop) (clock-message-handler msg)
             :control-change (cc-message-handler msg)
             nil)
+
+          (catch InterruptedException t
+            (info "MIDI event handler thread interrupted, shutting down.")
+            (reset! running false)
+            (reset! midi-transfer-thread nil))
           (catch Throwable t
             (error t "Problem running MIDI event handler")))
-        (recur (<! @channel))))
-    ;; The channel has been closed.
-    (reset! channel nil)))
+        (when running (recur (.take midi-queue)))))))

 (defn- incoming-message-handler
   "Attached to all midi input devices we manage. Puts the message on a
@@ -105,7 +115,7 @@
   which have access to all the classes that Afterglow needs."
   [msg]
   (try
-    (thread (>!! @channel msg))
+    (.add midi-queue msg)
     (catch Throwable t
       (error t "Problem trasferring MIDI event to core.async channel"))))

@@ -158,21 +168,20 @@
             (not (mmj-descriptions (:name device))))))
     identity))

-(defn- create-channel
-  "Creates the core.async channel used to deliver MIDI events when needed."
-  [old-channel]
-  (or old-channel
-      (let [c (chan 32)]
-        (info "Created MIDI dispatch channel.")
-        (future (delegated-message-handler))
-        c)))
+(defn- start-handoff-thread
+  "Creates the thread used to deliver MIDI events when needed."
+  [old-thread]
+  (or old-thread
+      (doto (Thread. delegated-message-handler)
+        (.setDaemon true)
+        (.start))))

 ;; TODO: This and open-outputs will have to change once hot-plugging works.
 (defn open-inputs-if-needed!
   "Make sure the MIDI input ports are open and ready to distribute events.
   Returns the opened inputs."
   []
-  (swap! channel create-channel)
+  (swap! midi-transfer-thread start-handoff-thread)
   (let [port-filter (create-midi-port-filter)
         result (swap! midi-inputs #(if (empty? %)
                                      (map connect-midi-in


Deleted unnecessary imports from operations.clj

--- src/app/operations.clj
+++ src/app/operations.clj
@@ -1,19 +1,8 @@
 (ns app.operations
   (:use [app.javaparser]))

-(import com.github.javaparser.JavaParser)
-(import com.github.javaparser.ast.CompilationUnit)
-(import com.github.javaparser.ast.Node)
 (import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration)
-(import com.github.javaparser.ast.body.EnumDeclaration)
-(import com.github.javaparser.ast.body.EnumConstantDeclaration)
 (import com.github.javaparser.ast.body.ConstructorDeclaration)
-(import com.github.javaparser.ast.body.FieldDeclaration)
-(import com.github.javaparser.ast.body.MethodDeclaration)
-(import com.github.javaparser.ast.body.ModifierSet)
-(import com.github.javaparser.ast.body.TypeDeclaration)
-(import com.github.javaparser.ast.body.VariableDeclaratorId)
-(import com.github.javaparser.ast.visitor.DumpVisitor)

 (defrecord Operation [query params headers])


allow for 'model' param

allow for 'model' param

--- src/babel/english.cljc
+++ src/babel/english.cljc
@@ -80,8 +80,8 @@
    (parse/parse (preprocess input) model)))

-(defn sentences [ & [spec]]
-  (let [model (medium)
+(defn sentences [ & [spec model]]
+  (let [model (if model model (medium))
         spec (if spec
                (unifyc spec {:modified false})
                {:modified false


fix classifer for tests

fix classifer for tests

--- dummy-connector/config/project.clj
+++ dummy-connector/config/project.clj
@@ -29,7 +29,7 @@

   :profiles
   {:test
-   {:dependencies [[com.sixsq.slipstream/SlipStreamCljResourcesTests-jar]
+   {:dependencies [[com.sixsq.slipstream/SlipStreamCljResourcesTests-jar :classifier "tests"]
                    [com.sixsq.slipstream/SlipStreamDbTesting-jar]
                    [peridot]
                    [commons-logging]


indenting

indenting

--- src/celestial/jobs.clj
+++ src/celestial/jobs.clj
@@ -64,8 +64,10 @@
                     (save-status spec' :success))
                 (do (apply f args)
                     (save-status spec' :success)))
-              (catch Throwable e (error e)
-                (save-status spec' :error)))))))))
+              (catch Throwable e
+                (error e)
+                (save-status spec' :error)
+                ))))))))

 (defn jobs []
   {:reload [wf/reload 2] :destroy [wf/destroy 2] :provision [wf/puppetize 2]


missing checksum commit

missing checksum commit

--- src/cellophane/dom.clj
+++ src/cellophane/dom.clj
@@ -1,6 +1,22 @@
 (ns cellophane.dom
   (:refer-clojure :exclude [map meta time use])
-  (:require [cellophane.protocols :as p]))
+  (:require [cellophane.protocols :as p])
+  (:import [java.util.zip Adler32]))
+
+;; ===================================================================
+;; Checksums (data-react-checksum)
+
+;; Not equal to React's optimized version of adler32. See
+;; https://github.com/facebook/react/blob/3b96650/src/shared/utils/adler32.js
+(defn checksum [markup]
+  (let [chk (Adler32.)
+        bytes (.getBytes markup)]
+    (.update chk bytes 0 (count bytes))
+    (.getValue chk)))
+
+
+;; ===================================================================
+;; DOM render

 (def tags
   '[a


Reindent for readability.

Reindent for readability.

--- src/cavm/h2.clj
+++ src/cavm/h2.clj
@@ -21,53 +21,60 @@
 (def score-size (* float-size bin-size))

 ; Note H2 has one int type: signed, 4 byte. Max is approximately 2 billion.
-(def probes-table ["CREATE TABLE IF NOT EXISTS `probes` (
-                   `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
-                   `eid` INT NOT NULL,
-                   FOREIGN KEY (eid) REFERENCES `experiments` (`id`),
-                   `name` VARCHAR(255))"
-                   "ALTER TABLE `probes` ADD CONSTRAINT IF NOT EXISTS `eid_name` UNIQUE(`eid`, `name`)"
-                   "CREATE INDEX IF NOT EXISTS probe_name ON probes (eid, name)"])
-
-(def scores-table [(format "CREATE TABLE IF NOT EXISTS `scores` (
-                  `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
-                  `expScores` VARBINARY(%d) NOT NULL)" score-size)])
-
-(def join-table ["CREATE TABLE IF NOT EXISTS `joins` (
-                 `pid` INT,
-                 `i` INT,
-                 `sid` INT)"
-                 "CREATE INDEX IF NOT EXISTS index_pid ON joins (`pid`, `i`)"])
-
-(def cohorts-table ["CREATE TABLE IF NOT EXISTS `cohorts` (
-                   `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
-                   `name` VARCHAR(2000) NOT NULL UNIQUE)"
-                   "CREATE INDEX IF NOT EXISTS index_name ON cohorts (`name`)"])
-
-(def samples-table ["CREATE TABLE IF NOT EXISTS `samples` (
-                    `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
-                    `cid` INT NOT NULL,
-                    FOREIGN KEY (cid) REFERENCES `cohorts` (`id`),
-                    `sample` VARCHAR(1000) NOT NULL)"
-                    "CREATE INDEX IF NOT EXISTS index_cid ON samples (`cid`)"])
+(def probes-table
+  ["CREATE TABLE IF NOT EXISTS `probes` (
+   `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
+   `eid` INT NOT NULL,
+   FOREIGN KEY (eid) REFERENCES `experiments` (`id`),
+   `name` VARCHAR(255))"
+   "ALTER TABLE `probes` ADD CONSTRAINT IF NOT EXISTS `eid_name` UNIQUE(`eid`, `name`)"
+   "CREATE INDEX IF NOT EXISTS probe_name ON probes (eid, name)"])
+
+(def scores-table
+  [(format "CREATE TABLE IF NOT EXISTS `scores` (
+           `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
+           `expScores` VARBINARY(%d) NOT NULL)" score-size)])
+
+(def join-table
+  ["CREATE TABLE IF NOT EXISTS `joins` (
+   `pid` INT,
+   `i` INT,
+   `sid` INT)"
+   "CREATE INDEX IF NOT EXISTS index_pid ON joins (`pid`, `i`)"])
+
+(def cohorts-table
+  ["CREATE TABLE IF NOT EXISTS `cohorts` (
+   `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
+   `name` VARCHAR(2000) NOT NULL UNIQUE)"
+   "CREATE INDEX IF NOT EXISTS index_name ON cohorts (`name`)"])
+
+(def samples-table
+  ["CREATE TABLE IF NOT EXISTS `samples` (
+   `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
+   `cid` INT NOT NULL,
+   FOREIGN KEY (cid) REFERENCES `cohorts` (`id`),
+   `sample` VARCHAR(1000) NOT NULL)"
+   "CREATE INDEX IF NOT EXISTS index_cid ON samples (`cid`)"])

 ; XXX What should max file name length be?
-(def experiments-table ["CREATE TABLE IF NOT EXISTS `experiments` (
-                       `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
-                       `file` VARCHAR(2000) NOT NULL UNIQUE,
-                       `time` TIMESTAMP NOT NULL,
-                       `hash` VARCHAR(40) NOT NULL,
-                       `cid` INT NOT NULL,
-                        `loaded` BOOLEAN NOT NULL,
-                       FOREIGN KEY (cid) REFERENCES `cohorts` (`id`))"])
-
-(def exp-samples-table ["CREATE TABLE IF NOT EXISTS `exp_samples` (
-                        `eid` INT NOT NULL,
-                        FOREIGN KEY (eid) REFERENCES `experiments` (`id`),
-                        `sid` INT NOT NULL,
-                        FOREIGN KEY (sid) REFERENCES `samples` (`id`),
-                        `i` INT NOT NULL,
-                        PRIMARY KEY(`eid`, `sid`))"])
+(def experiments-table
+  ["CREATE TABLE IF NOT EXISTS `experiments` (
+   `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
+   `file` VARCHAR(2000) NOT NULL UNIQUE,
+   `time` TIMESTAMP NOT NULL,
+   `hash` VARCHAR(40) NOT NULL,
+   `cid` INT NOT NULL,
+   `loaded` BOOLEAN NOT NULL,
+   FOREIGN KEY (cid) REFERENCES `cohorts` (`id`))"])
+
+(def exp-samples-table
+  ["CREATE TABLE IF NOT EXISTS `exp_samples` (
+   `eid` INT NOT NULL,
+   FOREIGN KEY (eid) REFERENCES `experiments` (`id`),
+   `sid` INT NOT NULL,
+   FOREIGN KEY (sid) REFERENCES `samples` (`id`),
+   `i` INT NOT NULL,
+   PRIMARY KEY(`eid`, `sid`))"])

 ; XXX What should max file name length be?
 (def probemap-table


checking status

checking status

--- src/freenas/remote.clj
+++ src/freenas/remote.clj
@@ -11,11 +11,15 @@

 (ns freenas.remote
   (:require
+    [slingshot.slingshot :refer  [throw+]]
+    [taoensso.timbre :as timbre]
     [celestial.common :refer (import-logging)]
     [cheshire.core :refer :all]
     [celestial.model :refer (hypervisor)]
     [clojure.core.strint :refer (<<)]
     [org.httpkit.client :as client]))
+
+(timbre/refer-timbre)

 (defn freenas [ks])

@@ -28,6 +32,16 @@
   [(hypervisor :freenas :username) (hypervisor :freenas :password)]
   )

-(defn call [verb api args]
-   (-> @(verb (<< "~(root)~{api}") (merge args {:basic-auth (auth) :insecure? true})) :body parse-string))
+(defn defaults []
+  {:basic-auth (auth) :insecure? true :headers {"Content-Type" "application/json"}})

+(defn call
+  ([verb api] (call verb api nil))
+  ([verb api params]
+   (let [args* (merge (defaults) {:body (generate-string params)} {})
+         {:keys [body status] :as res} @(verb (<< "~(root)~{api}") args*)]
+     (when-not (= 201 status)
+       (info status)
+       (throw+ (assoc res :type ::call-failed)))
+     (-> body parse-string))))
+


commented the temp scan

commented the temp scan

--- src/hbase_clj/core.clj
+++ src/hbase_clj/core.clj
@@ -70,7 +70,7 @@
     (let [{:keys [id-type families]} *schema*

           res (atom {})]
-      (doseq [r (.getScanner *table* scanner)]
+      #_(doseq [r (.getScanner *table* scanner)]
         (doseq [^KeyValue kv (.list r)]
           (let [id (decode id-type (.getRow kv))


added a main method that calls the ring jetty adapter thingy

--- src/todo_repl_webapp/handler.clj
+++ src/todo_repl_webapp/handler.clj
@@ -3,7 +3,8 @@
         hiccup.core)
   (:require [compojure.handler :as handler]
             [compojure.route :as route]
-            [hiccup.form :as form]))
+            [hiccup.form :as form]
+            [ring.adapter.jetty :as jetty]))

 (defn home-page [& x]
   (html [:head [:title "todo-repl"]]
@@ -23,3 +24,6 @@

 (def app
   (handler/site app-routes))
+
+(defn -main [port]
+  (jetty/run-jetty app-routes {:port (Integer. port) :join? false}))


Story ID: RPC-206 filenames should have underscores instead of hyphens

--- src/leiningen/i18n.clj
+++ src/leiningen/i18n.clj
@@ -143,24 +143,23 @@
 (defn deploy-translations
   "This subtask converts translated .po files into locale-specific .cljs files for runtime string translation."
   [project]
-  (let [trans-ns (translation-namespace project)
+  (let [replace-hyphen #(str/replace % #"-" "_")
+        trans-ns (translation-namespace project)
         output-dir (cljs-output-dir trans-ns)
         po-files (find-po-files msgs-dir-path)
         default-lc (default-locale project)
         locales (map clojure-ize-locale po-files)
         locales-inc-default (conj locales default-lc)
-        default-lc-translation-path (str output-dir "/" default-lc ".cljs")
+        default-lc-translation-path (str output-dir "/" (replace-hyphen default-lc) ".cljs")
         default-lc-translations (u/wrap-with-swap :namespace trans-ns :locale default-lc :translation {})
         locales-code-string (gen-locales-ns project locales)
         locales-path (str output-dir "/locales.cljs")
         default-locale-code-string (gen-default-locale-ns trans-ns default-lc)
-        default-locale-path (str output-dir "/default-locale.cljs")]
+        default-locale-path (str output-dir "/default_locale.cljs")]
     (sh "mkdir" "-p" output-dir)
     (u/write-cljs-translation-file default-locale-path default-locale-code-string)
     (if (some #{default-lc} locales)
       (u/write-cljs-translation-file locales-path locales-code-string)
-      ; else, write an empty .po file for the default locale
-      ; as well as locales code that now includes the default locale
       (let [locales-code-string (gen-locales-ns project locales-inc-default)]
         (u/write-cljs-translation-file locales-path locales-code-string)
         (u/write-cljs-translation-file default-lc-translation-path default-lc-translations)))
@@ -171,10 +170,9 @@
             translation-map (u/map-translations (po-path po))
             cljs-translations (u/wrap-with-swap
                                 :namespace trans-ns :locale locale :translation translation-map)
-            cljs-trans-path (str output-dir "/" locale ".cljs")]
+            cljs-trans-path (str output-dir "/" (replace-hyphen locale) ".cljs")]
         (u/write-cljs-translation-file cljs-trans-path cljs-translations)))

-    ; if we have a .po file for the default locale already, go ahead and write the locales code to disk...
     (lmain/warn "Deployed translations for the following locales:" locales)

     (if-let [modules-map (lookup-modules project locales-inc-default)]


slight improvement of wording in reflexive pronoun example.

--- src/pronouns/pages.clj
+++ src/pronouns/pages.clj
@@ -34,7 +34,7 @@
 (defn reflexive-example
   [subject reflexive]
   (wrap-para
-   [:span#sentence (wrap-pronoun subject) " threw it to " (wrap-pronoun reflexive)]))
+   [:span#sentence (wrap-pronoun subject) " threw the frisbee to " (wrap-pronoun reflexive)]))

 (defn twitter-name [name]


Don't call on-dispose in non-reactive deref for now

--- src/reagent/ratom.cljs
+++ src/reagent/ratom.cljs
@@ -438,10 +438,7 @@
             (set! state newstate)
             (when (and (some? watches)
                        (not= oldstate newstate))
-              (-notify-watches this oldstate newstate))))
-        (when (and (some? on-dispose)
-                   (nil? watches))
-          (on-dispose state)))
+              (-notify-watches this oldstate newstate)))))
       (do
         (notify-deref-watcher! this)
         (when-not (== dirtyness clean)


Start switch to three-state dirty status

--- src/reagent/ratom.cljs
+++ src/reagent/ratom.cljs
@@ -197,6 +197,10 @@
   (-handle-change [k sender oldval newval])
   (-peek-at [this]))

+(def clean 0)
+(def maybe-dirty 1)
+(def is-dirty 2)
+
 (deftype Reaction [f ^:mutable state ^:mutable dirty? ^:mutable active?
                    ^:mutable watching ^:mutable watches
                    auto-run on-set on-dispose]
@@ -224,7 +228,7 @@
     (let [oldval state]
       (set! state newval)
       (when on-set
-        (set! dirty? true)
+        (set! dirty? is-dirty)
         (on-set oldval newval))
       (-notify-watches a oldval newval)
       newval))
@@ -242,7 +246,7 @@
   IComputedImpl
   (-handle-change [this sender oldval newval]
     (when (and active? (not (identical? oldval newval)))
-      (set! dirty? true)
+      (set! dirty? is-dirty)
       ((or auto-run run) this)))

   (-update-watching [this derefed]
@@ -255,7 +259,7 @@
     (set! watching derefed))

   (-peek-at [this]
-    (if-not dirty?
+    (if (== dirty? clean)
       state
       (binding [*ratom-context* nil]
         (-deref this))))
@@ -270,7 +274,7 @@
       (when-not active?
         (when debug (swap! -running inc))
         (set! active? true))
-      (set! dirty? false)
+      (set! dirty? clean)
       (set! state res)
       (-notify-watches this oldstate state)
       res))
@@ -280,11 +284,11 @@
     (if (or auto-run (some? *ratom-context*))
       (do
         (notify-deref-watcher! this)
-        (if dirty?
+        (if-not (== dirty? clean)
           (run this)
           state))
       (do
-        (when dirty?
+        (when-not (== dirty? clean)
           (let [oldstate state]
             (set! state (f))
             (when-not (identical? oldstate state)
@@ -297,7 +301,7 @@
       (remove-watch w this))
     (set! watching nil)
     (set! state nil)
-    (set! dirty? true)
+    (set! dirty? is-dirty)
     (when active?
       (when debug (swap! -running dec))
       (set! active? false))
@@ -319,7 +323,7 @@
 (defn make-reaction [f & {:keys [auto-run on-set on-dispose derefed]}]
   (let [runner (if (= auto-run true) run auto-run)
         active (not (nil? derefed))
-        dirty (not active)
+        dirty (if (not active) is-dirty clean)
         reaction (Reaction. f nil dirty active
                             nil nil
                             runner on-set on-dispose)]


tidy up

tidy up

--- src/overtone/helpers/old_contrib.clj
+++ src/overtone/helpers/old_contrib.clj
@@ -1,32 +1,34 @@
-(ns
-    ^{:doc "Temporary namespace for functions and macros we depend on from the old Clojure 1.2 contrib. This namespace should be removed when these have been relocated to the new contrib structure."}
+(ns ^{:doc "Temporary namespace for functions and macros we depend on
+            from the old Clojure 1.2 contrib. This namespace should be
+            removed when these have been relocated to the new contrib
+            structure." }
   overtone.helpers.old-contrib)

 ;; name-with-attributes by Konrad Hinsen:
 ;;http://code.google.com/p/clojure-contrib/source/browse/trunk/src/clojure/contrib/def.clj?r=889
 (defn name-with-attributes
   "To be used in macro definitions.
-   Handles optional docstrings and attribute maps for a name to be defined
-   in a list of macro arguments. If the first macro argument is a string,
-   it is added as a docstring to name and removed from the macro argument
-   list. If afterwards the first macro argument is a map, its entries are
-   added to the name's metadata map and the map is removed from the
-   macro argument list. The return value is a vector containing the name
-   with its extended metadata map and the list of unprocessed macro
-   arguments."
+   Handles optional docstrings and attribute maps for a name to be
+   defined in a list of macro arguments. If the first macro argument is
+   a string, it is added as a docstring to name and removed from the
+   macro argument list. If afterwards the first macro argument is a map,
+   its entries are added to the name's metadata map and the map is
+   removed from the macro argument list. The return value is a vector
+   containing the name with its extended metadata map and the list of
+   unprocessed macro arguments."
   [name macro-args]
   (let [[docstring macro-args] (if (string? (first macro-args))
-                 [(first macro-args) (next macro-args)]
-                 [nil macro-args])
-    [attr macro-args]      (if (map? (first macro-args))
-                 [(first macro-args) (next macro-args)]
-                 [{} macro-args])
-    attr                   (if docstring
-                 (assoc attr :doc docstring)
-                 attr)
-    attr                   (if (meta name)
-                 (conj (meta name) attr)
-                 attr)]
+                                 [(first macro-args) (next macro-args)]
+                                 [nil macro-args])
+        [attr macro-args]      (if (map? (first macro-args))
+                                 [(first macro-args) (next macro-args)]
+                                 [{} macro-args])
+        attr                   (if docstring
+                                 (assoc attr :doc docstring)
+                                 attr)
+        attr                   (if (meta name)
+                                 (conj (meta name) attr)
+                                 attr)]
     [(with-meta name attr) macro-args]))

 ;;from str-utils2


Corrected bootstrap user name.

Corrected bootstrap user name.

--- bootstrap-app/src/cmr/bootstrap/config.clj
+++ bootstrap-app/src/cmr/bootstrap/config.clj
@@ -6,7 +6,7 @@

 (defconfig bootstrap-username
   "Defines the bootstrap database username."
-  {:default "cmr"})
+  {:default "CMR_BOOTSTRAP"})

 (defconfig bootstrap-password
   "Defines the bootstrap database password."


Fixing self-introduced bug when moving rows

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

--- src/conexp/contrib/gui/editors/context_editor/table_control.clj
+++ src/conexp/contrib/gui/editors/context_editor/table_control.clj
@@ -405,8 +405,8 @@
    new-view."
   [otable old-view new-view]
   (assert (keyword-isa? otable table-control))
-  (let [^JTable control (get-control otable)
-        col-model (.getColumnModel control) ]
+  (let [^JTable control (get-control otable),
+        col-model (.getColumnModel control)]
     (.moveColumn col-model old-view new-view)))

 (defn-swing set-column-index-permutator
@@ -414,7 +414,7 @@
   rearranges the columns accordingly."
   [otable col-idx]
   (assert (keyword-isa? otable table-control))
-  (let [ col-count (get-column-count otable) ]
+  (let [col-count (get-column-count otable)]
     (doseq [col (range col-count)]
       (let [at-view (get-index-column otable (col-idx col))]
         (move-column otable at-view col)))))
@@ -438,26 +438,26 @@
    new-view."
   [otable old-view new-view]
   (assert (keyword-isa? otable table-control))
-  (let [ view-to-index (get-row-index-permutator otable)
-         row-count (get-row-count otable)
-         col-indices (range (get-column-count otable))]
+  (let [view-to-index (get-row-index-permutator otable),
+        row-count     (get-row-count otable),
+        col-indices   (range (get-column-count otable))]
     (if (and (>= new-view 0)
-         (< new-view row-count)
-          (not= old-view new-view))
+             (< new-view row-count)
+             (not= old-view new-view))
       (if (< old-view new-view)
-        (let [ new-view-to-index-map
-               (apply conj (for [r (range row-count)]
-                             (cond (< r old-view) {r (view-to-index r)}
-                               (= r old-view) {new-view (view-to-index old-view)}
-                               (<= r new-view) {(- r 1) (view-to-index r)}
-                               :otherwise {r (view-to-index r)}))),
+        (let [new-view-to-index-map
+              (apply conj (for [r (range row-count)]
+                            (cond (< r old-view) {r (view-to-index r)}
+                                  (= r old-view) {new-view (view-to-index old-view)}
+                                  (<= r new-view) {(- r 1) (view-to-index r)}
+                                  :otherwise {r (view-to-index r)}))),

-               new-index-to-view-map
-               (apply conj (for [r (range row-count)]
-                             (cond (< r old-view) {(view-to-index r) r}
-                               (= r old-view) {(view-to-index old-view) new-view}
-                               (<= r new-view) {(view-to-index r) (- r 1)}
-                               :otherwise {(view-to-index r) r}))),
+              new-index-to-view-map
+              (apply conj (for [r (range row-count)]
+                            (cond (< r old-view) {(view-to-index r) r}
+                                  (= r old-view) {(view-to-index old-view) new-view}
+                                  (<= r new-view) {(view-to-index r) (- r 1)}
+                                  :otherwise {(view-to-index r) r}))),

               new-view-to-index  (fn [x]
                                    (if (and (>= x 0) (< x row-count))
@@ -469,6 +469,7 @@
               grab-list          (range old-view (+ 1 new-view)),
               put-list           (apply conj [new-view] (range old-view new-view)),
               old-table-change-hook (get-hook-function otable "table-changed")]
+          (set-hook otable "table-changed" (fn [_ _ _ _] nil))
           (dorun (for [put-data
                         (doall (zip put-list
                            (for [r grab-list]


RR: test fields are not repeated

RR: test fields are not repeated

--- test/hatti/views/table_test.cljs
+++ test/hatti/views/table_test.cljs
@@ -59,6 +59,10 @@
       (is (some #(= "_submission_time" (:name %)) fields))
       (is (some #(= "_submission_time" (:name %)) more-fields)))

+    (testing "fields are not repeated"
+      (let [all-fields (tv/all-fields fat-form)]
+        (is (= (count all-fields) (count (group-by #(:name %) all-fields))))))
+
     (testing "group and note fields are removed"
       (is (not (->> more-fields (map :type) (contains? #{"note" "group"})))))))


Fix tests.

Fix tests.

--- test/uxbox/tests/geom_types.cljs
+++ test/uxbox/tests/geom_types.cljs
@@ -1,8 +1,8 @@
 (ns uxbox.tests.geom-types
   (:require [cljs.test :as t :include-macros true]
             [cljs.pprint :refer (pprint)]
-            [uxbox.common.geom.point :as gpt]
-            [uxbox.common.geom.matrix :as gmt]))
+            [uxbox.util.geom.point :as gpt]
+            [uxbox.util.geom.matrix :as gmt]))

 (t/deftest point-constructors-test
   (let [p (gpt/point 1 2)]


Fix skip

Fix skip

--- src/rester/core.clj
+++ src/rester/core.clj
@@ -269,7 +269,7 @@

 (defn exec-tests [tests opts]
   (let [opts (atom opts)
-        skip-tag (:skip opts)
+        skip-tag (opts "skip")
         name-to-test (into {} (for [t tests] [(:test t) t]))
         test-agents (vec (map agent tests))
         exec-test (fn [test]


fixes

fixes

--- src/rester/core.clj
+++ src/rester/core.clj
@@ -95,7 +95,7 @@
                           :insecure? true})
          (catch ExceptionInfo e
            (.getData e)))
-        (assoc :elapsed (/ (- (System/nanoTime) start) 1000))
+        (assoc :elapsed (/ (- (System/nanoTime) start) 1000000.0))
        (#(update % :body coerce-payload (get-in % [:headers "Content-Type"]))))))

 (defn extract-data [{:keys [status body headers] :as resp} extractions]
@@ -163,7 +163,8 @@
   (let [test (if (:error test) test (prepare-test test @opts))]
     (if (:error test) test
         (let [resp (mk-request test)
-              delta (verify-response resp test)]
+              delta (verify-response resp test)
+              test (assoc test :time (:elapsed resp))]
           (if delta
             (assoc test :failure delta :resp resp)
             (do
@@ -227,7 +228,7 @@
       (print (if (:success test) "\u001B[32m [v] " "\u001B[31m [x] "))
       (println (:test test) "\t" (or result :success) "\u001B[0m"))))

-(defn junit-report [dest-file {:keys [suites]}]
+(defn junit-report [dest-file src-file {:keys [suites]}]
   (make-parents dest-file)
   (with-open [out (writer dest-file)]
     (indent (sexp-as-element
@@ -235,7 +236,7 @@
               (for [{:keys [name tests total failure error skipped]} suites]
                 [:testsuite {:name name :errors error :tests total :failures failure}
                  (for [test tests]
-                   [:testcase {:name (:test test) :time 0}
+                   [:testcase {:name (:test test) :classname src-file :time (:time test)}
                     (condp test nil
                       :error :>> #(vector :error {:message %})
                       :failure :>> #(vector :failure {:message %} (:resp test))
@@ -253,10 +254,11 @@
   (try
     (let [opts (apply hash-map (map-indexed #(if (even? %1) (subs %2 1) %2) (rest args)))
           _ (println "running with arguments:" opts)
+          tests-file (first args)
           xml-report (or (opts "report")
-                         (str "target/" (str/replace (first args) #"\.csv" "-results.xml")))
-          results (-> args first tests-from (exec-tests opts) summarise-results)]
-      ((juxt #(junit-report xml-report %) print-test-results) results)
+                         (str "target/" (str/replace tests-file #"\.csv" "-results.xml")))
+          results (-> tests-file tests-from (exec-tests opts) summarise-results)]
+      ((juxt #(junit-report xml-report tests-file %) print-test-results) results)
       (System/exit (- (results :total 0) (results :success 0))))
     (finally
       (shutdown-agents))))


whitespace cleanup

whitespace cleanup

--- src/selmer/tags.clj
+++ src/selmer/tags.clj
@@ -130,7 +130,6 @@
       (render-if-any false (rest params) if-tags else-tags render)
       (= ["not" "any"] (take 2 params))
       (render-if-any true (drop 2 params) if-tags else-tags render)
-
       (< (count params) 3)
       (if-default-handler params if-tags else-tags render)
       :else


remove Allen

remove Allen

--- frontend/components/about.cljs
+++ frontend/components/about.cljs
@@ -20,16 +20,6 @@
     :visible true
     :bio ["You might not know it by looking at him, but Paul is a wicked card shark. When he's not making his poker buddies cry, he seeks out mogul-laced ski trails to hurl himself down, and within the first five minutes of meeting him he'll probably tell you the story about how he mostly landed a backflip on his skis. Lest his ego get too big, though, we can always remind him of the time he failed at a YCombinator startup, and he'll go bury his emotions in the sweet sweet taste of artisan chocolate--or any chocolate, really.",
           "Paul's been interviewed by the Wall Street Journal, and one of his proudest achievements was giving a Google Tech Talk on compilers and programming languages. He wrote phc, an open source PHP compiler, while doing his PhD on compilers and static analysis in Dublin. After moving to the Bay Area, Paul worked on the Firefox Javascript engine, started Circle, and then wrote stefon, an asset pipeline for Clojure. Because it pains Paul to see so much time wasted due to inadequate developer tools, he approaches continuous integration from the perspective of developer productivity. He loves to focus on building the Circle product, but, as he'll tell you while he's walloping you at table tennis, he also has to take care of the business side of things, too."]}
-   {:name "Allen Rohner"
-    :img-path (stefon/asset-path "/img/outer/about/allen.png")
-    :visible true
-    :role "Founder"
-    :github "arohner"
-    :twitter "arohner"
-    :email "allen@circleci.com"
-    :bio ["Allen loves Ultimate Frisbee: he's played in the snow, on the beach, on Thanksgiving Day, New Year's Eve, and New Year's Day, and he regularly plays in 110 degree August heat. His future plans include the tacocopter, the burrito bomber, and the mosquito laser. When Allen's not coding, he spends his time making his own pizza dough and brewing his own beer. He'd make his own whiskey, too, if he wanted to wait 10 years for a drink.",
-          "Back in the day, Allen started work on his own self-hosting, native code lisp, and then the clouds parted and he discovered Clojure. Since then, he's become a Clojure contributor, and has commits in clojure.core, contrib, lein, ring, compojure, noir, and about a dozen more libraries. He finished SICP, and wrote Scriptjure, a Clojure to Javascript compiler, 2 years before ClojureScript. Other devs used his work as a basis for Stevedore, which he's happy to say is used in production every day at Circle. In addition to co-founding Circle as a means to bring Continuous Deployment to the masses, he looks forward to building tools that help debug test failures by anticipating common problems. He currently deploys six times a day, and more on weekends."]}
-   {:name "David Lowe"
     :visible true
     :role "Backend Developer"
     :github "dlowe"


More reasonable support claim.

More reasonable support claim.

--- frontend/components/plans.cljs
+++ frontend/components/plans.cljs
@@ -89,7 +89,7 @@
    {:headline "Unlimited build time",
     :detail "Great testing means using Circle as much as possible. You don't want to weigh good testing against possible charges or monthly fees. So we have no limit, no per-hour cost, no overages. Just simple, predictable pricing."},
    {:headline "Phenomenal support",
-    :detail "We respond to support requests immediately, every day (yes, on weekends and holidays). Most requests are responded to within the hour, 99% are responded to in 12 hours. We're also available for live chat support."},
+    :detail "We respond to support requests quickly -- most requests during working hours are answered within the hour. We also offer live support chat."},
    {:headline "Custom NDA",
     :detail "Naturally we never look at your code. We also have a great security policy, which gives us no rights whatsoever to your code. However, if you would prefer that we sign your custom NDA, we'd be happy to.",
     :enterprise true},