Add string functions to support printing of keywords and symbols

Refs #13, #19

--- src/cljs/cljs/core.cljs
+++ src/cljs/cljs/core.cljs
@@ -107,6 +107,39 @@
 (defn symbol? [x]
   (and (goog.isString x)
        (= (.charAt x 0) \uFDD1)))
+
+(defn str
+  "With no args, returns the empty string. With one arg x, returns
+  x.toString().  (str nil) returns the empty string. With more than
+  one arg, returns the concatenation of the str values of the args."
+  ([] "")
+  ([x] (if (nil? x) "" (. x (toString))))
+  ([x & ys] (reduce + (map str (cons x ys)))))
+
+(defn subs
+  "Returns the substring of s beginning at start inclusive, and ending
+  at end (defaults to length of string), exclusive."
+  ([s start] (.substring s start))
+  ([s start end] (.substring s start end)))
+
+(defn name [x]
+  "Returns the name String of a string, symbol or keyword."
+  (cond
+    (string? x) x
+    (or (keyword? x) (symbol? x))
+      (let [i (.lastIndexOf x "/")]
+        (if (< i 0)
+          (subs x 2)
+          (subs x (inc i))))
+    :else nil #_(throw (str "Doesn't support name: " x))))
+
+(defn namespace [x]
+  "Returns the namespace String of a symbol or keyword, or nil if not present."
+  (if (or (keyword? x) (symbol? x))
+    (let [i (.lastIndexOf x "/")]
+      (when (> i -1)
+        (subs x 2 i)))
+    :else nil #_(throw (str "Doesn't support namespace: " x))))

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Seq fns ;;;;;;;;;;;;;;;;

@@ -425,7 +458,7 @@
   (-equiv [o other] (identical? o other))

   goog.global.Date ; treat dates as values
-  (-equiv [o other] (identical? (.toString o ()) (.toString other ()))))
+  (-equiv [o other] (identical? (str o) (str other))))

 (defn = [x y]
   (-equiv x y))
@@ -1172,12 +1205,22 @@
           [end]))

 (extend-protocol IPrintable
-  goog.global.Number (-pr-seq [n opts] (list (.toString n 10)))
-  goog.global.String (-pr-seq [str opts]
-                        (if (get opts "readably")
-                          (list (goog.string.quote str))
-                          (list str)))
-  goog.global.Boolean (-pr-seq [bool opts] (list (.toString bool ())))
+  goog.global.Boolean (-pr-seq [bool opts] (list (str bool)))
+  goog.global.Number (-pr-seq [n opts] (list (str n)))
+  goog.global.String (-pr-seq [obj opts]
+                        (cond
+                          (keyword? obj)
+                            (list (str ":"
+                                       (when-let [nspc (namespace obj)]
+                                         (str nspc "/"))
+                                       (name obj)))
+                          (symbol? obj)
+                            (list (str (when-let [nspc (namespace obj)]
+                                         (str nspc "/"))
+                                       (name obj)))
+                          (get opts :readably)
+                            (list (goog.string.quote obj))
+                          :else (list obj)))
   goog.global.Array (-pr-seq [a opts]
                       (pr-sequential pr-seq "#<Array [" ", " "]>" opts a)))

@@ -1192,7 +1235,7 @@
     (nil? obj) (list "nil")
     (identical? undefined obj) (list "#<undefined>")
     (satisfies? IPrintable obj) (-pr-seq obj opts)
-    :else (list "#<" (.toString obj ()) ">")))
+    :else (list "#<" (str obj) ">")))

 (defn pr-str-with-opts
   "Prints a single object to a string, observing all the
@@ -1203,7 +1246,7 @@
       (when coll
         (.append sb (first coll))
         (recur (next coll))))
-    (.toString sb ())))
+    (str sb)))

 (defn pr-with-opts
   "Prints a single object using string-print, observing all
@@ -1224,7 +1267,7 @@
 (defn pr-str
   "pr to a string, returning it. Fundamental entrypoint to IPrintable."
   [obj]
-  (pr-str-with-opts obj {"readably" true}))
+  (pr-str-with-opts obj {:readably true}))

 (defn pr
   "Prints the object(s) using string-print.  Prints the
@@ -1232,17 +1275,17 @@
   By default, pr and prn print in a way that objects can be
   read by the reader"
   [obj]
-  (pr-with-opts obj {"readably" true}))
+  (pr-with-opts obj {:readably true}))

 (defn println
   "Prints the object(s) using string-print.
   print and println produce output for human consumption."
   [obj]
-  (pr-with-opts obj {"readably" false})
+  (pr-with-opts obj {:readably false})
   (newline))

 (defn prn
   "Same as pr followed by (newline)."
   [obj]
-  (pr-with-opts obj {"readably" true})
+  (pr-with-opts obj {:readably true})
   (newline))


Flesh out functional programming chapter

--- brave-true/clojure-noob/src/clojure_noob/fun-prog.clj
+++ brave-true/clojure-noob/src/clojure_noob/fun-prog.clj
@@ -2,22 +2,28 @@
   (:require [midje.sweet :refer :all]))

 (facts  "pure functions:"
-  (fact (get [:chumbawumba] 0)
+  (fact
+    (get [:chumbawumba] 0)
     => :chumbawumba)
-  (fact (reduce + [1 10 5])
+  (fact
+    (reduce + [1 10 5])
     => 16)
-  (fact (str "wax on " "wax off")
+  (fact
+    (str "wax on " "wax off")
     => "wax on wax off"))

 (facts "pure functions are refentially transparent"
-  (fact (+ 1 2)
+  (fact
+    (+ 1 2)
     => 3))

 (defn wisdom
+  "the string ', Daniel-san' is immutable"
   [words]
   (str words ", Daniel-san"))

-(fact (wisdom "Always bathe on Fridays")
+(fact
+  (wisdom "Always bathe on Fridays")
   => "Always bathe on Fridays, Daniel-san")

 ;; always gives a differen result so not referntially transperent
@@ -27,6 +33,7 @@
     "You get a raise!"
     "Better luck next year!"))

+;; separate referencialy transparent functions from side-effecting procedures
 (defn analysis
   "analysis is a function"
   [text]
@@ -37,8 +44,14 @@
   [filename]
   (analysis (slurp filename)))  ;; slurp is not a function

-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;(System/getProperty "user.dir")
+;;(analyze-file "project.clj")
+;;=> "Character count: 423"
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; living with immutable data structures
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

 (defn no-mutation
   [x]
@@ -51,27 +64,45 @@
   ;; outside of the let scope
   (println x))

-(no-mutation "Existential Angst Person")
-;; =>
+(fact "Kafka Human is in it's own scope"
+  (no-mutation "Existential Angst Person")
+  => nil)
 ;;Existential Angst Person
 ;;Kafka Human
 ;;Existential Angst Person

+
+;; recursive proplem solving:
 (defn sum
-  ([vals] (sum vals 0))
+  ([vals] (sum vals 0))  ;; --1-- default value for accumulator
   ([vals accumulating-total]
-    (if (empty? vals)
+    (if (empty? vals)    ;; --2-- empty vals is the base condition
       accumulating-total
       (sum (rest vals) (+ (first vals) accumulating-total)))))

-  (fact "test sum"
-    (sum []) => 0
-    (sum [1]) => 1
-    (sum [39 5 1]) => 45)
+(fact "evaluate sum"
+  (sum [39 5 1])   => 45   ;; single-arity - call 2-arity
+  (sum [39 5 1] 0) => 45
+  (sum [5 1] 39)   => 45
+  (sum [1] 44)     => 45
+  (sum [] 45)      => 45   ;; base case is reached, so return the accumulator
+  45               => 45 )
+
+;; should use 'recur' for more efficient looping
+(defn sum-r
+  ([vals]
+     (sum vals 0))
+  ([vals accumulating-total]
+     (if (empty? vals)
+       accumulating-total
+       (recur (rest vals) (+ (first vals) accumulating-total)))))
+
+(fact (sum-r [39 5 1]) => 45 )

-;;;;;;;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; function compostion instead of attribute mutation
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

 (require '[clojure.string :as s])

@@ -79,40 +110,59 @@
   [text]
   (s/replace (s/trim text) #"lol" "LOL"))

-(fact (clean "My boa constrictor is so sassy lol!  ")
+(fact
+  (clean "My boa constrictor is so sassy lol!  ")
   => "My boa constrictor is so sassy LOL!")

-(fact "pretty common style"
+;; use a chain of function calls instead of progressively mutating an object
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; cool things to do with functions
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(fact "chaining function is pretty common style so function called 'comp'"
   ((comp s/lower-case s/trim) " Unclean string ")
   => "unclean string")

+;; 'def' create a function
+(def my-lower-trim-1 (comp s/lower-case s/trim))
+(fact
+  (my-lower-trim-1  " Unclean string ")
+  => "unclean string")

+;; an implementation of 'comp' that composes two functions
 (defn two-comp
   [f g]
   (fn [& args]
     (f (apply g args))))

-(def my-lower-trim (two-comp s/lower-case s/trim))
+(def my-lower-trim-2 (two-comp s/lower-case s/trim))

-(fact (my-lower-trim " Unclean string  ")
+(fact
+  (my-lower-trim-2 " Unclean string  ")
   => "unclean string")

 (def sum-times2 (two-comp  #(* 2 %) +))

-(fact (sum-times2 1 2 3)
+(fact
+  (sum-times2 1 2 3)
   => 12)

 ;; define a new version of 'comp'
 (defn my-comp
   [f & funs]
-  (if (empty? funs) f
+  (if (empty? funs) f    ;; base case - returned composed function
       (recur (fn [& args]
                  (f (apply (first funs) args)))
                (rest funs))))

-(fact ((my-comp s/lower-case s/trim) " Unclean string ")
+(fact "works like two-comp"
+  ((my-comp s/lower-case s/trim) " Unclean string ")
   => "unclean string")
-(fact ((my-comp s/reverse s/lower-case s/trim) " Unclean string ")
+
+(fact "works like regular 'comp'"
+  ((my-comp s/reverse s/lower-case s/trim) " Unclean string ")
   => "gnirts naelcnu")

 (def sum-times2' (two-comp  #(* 2 %) +))
@@ -120,8 +170,10 @@
 (fact (sum-times2' 1 2 3)
   => 12)

+
 ;;;;;;;;;;;;;;;;;;;;
 ;; memoization
+;;;;;;;;;;;;;;;;;;;;

 (defn sleepy-identity
   "returns the given value after a 1 second 'calculation'"
@@ -129,10 +181,19 @@
   (Thread/sleep 1000)
   x)

-(sleepy-identity "Mr. Fantatstico")
+(sleepy-identity "Mr. Fantatstico")    ;; after one second

 (def memo-sleepy-identity
-  "does calculation once, then returns imediatly"
+  "memoize does calculation once, then returns immediatly"
   (memoize sleepy-identity))

-(memo-sleepy-identity "Mr. Fantatstico")
+(memo-sleepy-identity "Mr. Fantatstico")  ;; after one second
+(memo-sleepy-identity "Mr. Fantatstico")  ;; immediately
+
+
+;; Pretty cool!
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Peg Thing - in it's own project
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


Add missing help: valid-flux-policy-min-max-n-peers

--- src/onyx/static/helpful_job_errors.clj
+++ src/onyx/static/helpful_job_errors.clj
@@ -37,6 +37,9 @@

    :n-peers-with-min-or-max
    [":onyx/n-peers cannot be used with :onyx/min-peers or :onyx/max-peers."]
+
+   :valid-flux-policy-min-max-n-peers
+   ["When using a flux policy, a valid :onyx/min-peers and :onyx/max-peers, or :onyx/n-peers must be set."]

    :range-and-slide-incompatible
    ["Units specified for :window/range and :window/slide are incompatible with each other."]
@@ -416,6 +419,10 @@
   [entry error-data]
   [(str (semantic-error-msgs :sliding-window-needs-range-and-slide))])

+(defmethod predicate-error-msg 'valid-flux-policy-min-max-n-peers
+  [entry error-data]
+  [(str (semantic-error-msgs :valid-flux-policy-min-max-n-peers))])
+
 (defn missing-required-key* [job context error-data structure-type]
   (let [faulty-key (:missing-key error-data)
         path-len (count (:path error-data))


Added a failing test for ClojureFormat. Error changes the way the formatted source code is interpreted.

--- ccw.core/src/ccw/editors/antlrbased/ClojureFormat.clj
+++ ccw.core/src/ccw/editors/antlrbased/ClojureFormat.clj
@@ -127,4 +127,5 @@

 (deftest code-formatting
   (is (= "#\"something\"" (format-code "#\"something\"")))
-  (is (= "(resourcefully/put url {\"Content-Type\" \"multipart/form-data\" \"Encoding\" \"UTF-8\"} request)))" (format-code "(resourcefully/put url {\"Content-Type\" \"multipart/form-data\" \"Encoding\" \"UTF-8\"} request)))"))))
+  (is (= "(resourcefully/put url {\"Content-Type\" \"multipart/form-data\" \"Encoding\" \"UTF-8\"} request)))" (format-code "(resourcefully/put url {\"Content-Type\" \"multipart/form-data\" \"Encoding\" \"UTF-8\"} request)))")))
+  (is (= "#_(unread)" (format-code "#_(unread)"))))


Added payment link

Added payment link

--- scrape-n-mail/src/scrape_n_mail/core.cljs
+++ scrape-n-mail/src/scrape_n_mail/core.cljs
@@ -19,6 +19,7 @@
                          :signed-in? false
                          :sheet-data nil}))
 (defonce wellbeing-sheet "1bv6vgW-HMTz0uhKDkrJoTg387b-WK6IFkFd9y6N96hA")
+(defonce payment-link "https://www.paypal.me/pools/c/85ChNpjaRV")

 (def goog-datetime (fmt/formatter "MM/dd/YYYY HH:mm:ss"))


invalidate connection on IOException

invalidate connection on IOException


Harmonise crossover API.

Harmonise crossover API.

--- src/algebolic/expression/genetics.clj
+++ src/algebolic/expression/genetics.clj
@@ -119,5 +119,5 @@

 (defn ninety-ten-sl-crossover
   "A helper for making a size-limited 90:10 crossover, which you'll probably want to use."
-  [max-size]
-  (partial size-limited-crossover max-size ninety-ten-crossover))+  [max-size expr1 expr2]
+  (size-limited-crossover max-size ninety-ten-crossover expr1 expr2))


Add missing supervisor.

Add missing supervisor.

--- src/replikativ/crdt/ormap/realize.cljc
+++ src/replikativ/crdt/ormap/realize.cljc
@@ -33,7 +33,7 @@
         pub-ch (chan 10000)]
     (async/sub p :pub/downstream pub-ch)
     ;; stage is set up, now lets kick the update loop
-    (go-try
+    (go-try S
      ;; trigger an update for us if the crdt is already on stage
      ;; this ormap version is as far or ahead of the stage publications
      ;; (no gap in publication chain)


Make image extraction a bit better

Make image extraction a bit better

--- src/braid/server/api/link_extract.clj
+++ src/braid/server/api/link_extract.clj
@@ -13,12 +13,23 @@
   [host content]
   (let [url-re (re-pattern
                  (str "^http(?:s)?://(?:[^/])*" host ".*$"))]
-    (some-> content
-            (hs/select
-              (hs/and (hs/tag "img")
-                      (hs/attr "src" (partial re-matches url-re))))
+    (some-> (hs/select
+              (hs/descendant
+                (hs/and (hs/or (hs/tag "div") (hs/tag "section"))
+                        (hs/or (hs/id "main") (hs/id "body")))
+                (hs/and (hs/tag "img")
+                        (hs/or
+                          (hs/attr "src" #(string/starts-with? % "/"))
+                          (hs/attr "src" (partial re-matches url-re)))))
+              content)
             first
             (get-in [:attrs :src]))))
+
+(defn absolute-link
+  [url-base link]
+  (if (string/starts-with? link "/")
+    (str url-base link)
+    link))

 (defn extract'
   [url]
@@ -56,7 +67,7 @@
                                  content)
                                first
                                (get-in [:attrs :href])
-                               (->> (str url-base))))
+                               (->> (absolute-link url-base))))
                       "")
      :media {:type page-type}
      :type page-type
@@ -79,7 +90,8 @@
                [{:url url :colors [{:color [0 0 0]}]}]

                :else
-               (when-let [img (and content (find-img host content))]
+               (when-let [img (some->> content (find-img host)
+                                       (absolute-link url-base))]
                  [{:url img
                    :colors [{:color [0 0 0]}]}]))}))


accounts: recover password no longer appears as clear text #732

--- src/status_im/accounts/recover/screen.cljs
+++ src/status_im/accounts/recover/screen.cljs
@@ -56,14 +56,15 @@
                 (label :t/enter-valid-password))]
     [view
      [text-field
-      {:value          password
-       :error          error
-       :error-color    "#7099e6"
-       :label          (label :t/password)
-       :label-color    "#838c93de"
-       :line-color     "#0000001f"
-       :input-style    st/input-style
-       :on-change-text #(dispatch [:set-in [:recover :password] %])}]]))
+      {:value             password
+       :secure-text-entry true
+       :error             error
+       :error-color       "#7099e6"
+       :label             (label :t/password)
+       :label-color       "#838c93de"
+       :line-color        "#0000001f"
+       :input-style       st/input-style
+       :on-change-text    #(dispatch [:set-in [:recover :password] %])}]]))

 (defview recover []
   [{:keys [passphrase password passphrase-error password-error]} [:get :recover]]


popup menu position

popup menu position

--- src/status_im/components/context_menu.cljs
+++ src/status_im/components/context_menu.cljs
@@ -27,7 +27,7 @@
 (defn context-menu-options [custom-styles]
   {:customStyles {:optionsContainer
                   (merge {:elevation      2
-                          :margin-top     30
+                          :margin-top     0
                           :padding-top    8
                           :width          164
                           :padding-bottom 8}


endorsement tests

endorsement tests

--- test/clj/salava/badge/endorsement_test.clj
+++ test/clj/salava/badge/endorsement_test.clj
@@ -8,40 +8,71 @@
 (def user-2 (assoc user :id 4))
 (def user-3 (assoc user :id 5))

-(def badge 2)
-(def badge-2 7)
+(def user-badge {:id 2})
+(def user-badge-2 {:id 7})

 (t/deftest-ctx endorsement-test [ctx]
   (testing "Endorsements"
-      (testing "Endorse own badge"
-        (let [endorsement (e/endorse! ctx badge-2 (:id user-2) "i endorse this dude")]
-          (is (= (:status endorsement) "error"))))
-      (testing "Endorse badge"
-        (let [endorsement (e/endorse! ctx badge-2 (:id user) "i endorse this dude")
-              badge-endorsements (e/badge-endorsements ctx badge-2)]
-          (is (= (:status endorsement) "success"))
-          (is (= 1 (count badge-endorsements)))
+    (testing "Endorse own badge"
+      (let [endorsement (e/endorse! ctx (:id user-badge-2) (:id user-2) "i endorse this dude")]
+        (is (= (:status endorsement) "error"))))
+    (testing "Endorse badge"
+      (let [endorsement (e/endorse! ctx (:id user-badge-2) (:id user) "i endorse this dude")
+            badge-endorsements (e/user-badge-endorsements ctx (:id user-badge-2))]
+        (is (= (:status endorsement) "success"))
+        (is (= 1 (count badge-endorsements)))

-          (testing "Delete endorsement you do not own"
-            (let [connect (e/delete! ctx badge-2 (:id endorsement) (:id user-3))]
-              (is (= "error" (:status connect)))))
+        (testing "Delete endorsement you do not own"
+          (let [connect (e/delete! ctx (:id user-badge-2) (:id endorsement) (:id user-3))]
+            (is (= "error" (:status connect)))))

-          (testing "Delete own endorsement"
-            (let [connect (e/delete! ctx badge-2 (:id endorsement) (:id user))]
-              (is (= "success" (:status connect)))))
-          ))
+        (testing "Delete own endorsement"
+          (let [connect (e/delete! ctx (:id user-badge-2) (:id endorsement) (:id user))]
+            (is (= "success" (:status connect)))))
+        ))

-    (testing "Accept endorsment"
-      (let [endorsement (e/endorse! ctx badge-2 (:id user) "i endorse this dude")
-            connect (e/update-status! ctx (:id user-2) badge-2 (:id endorsement) "accepted")]
+    (testing "Accept endorsement"
+      (let [endorsement (e/endorse! ctx (:id user-badge-2) (:id user) "i endorse this dude")
+            connect (e/update-status! ctx (:id user-2) (:id user-badge-2) (:id endorsement) "accepted")]
         (is (= (:status endorsement) "success"))
         (is (= (:status connect) "success"))
-        (let [check (e/badge-endorsements ctx badge-2)]
+        (let [check (e/user-badge-endorsements ctx (:id user-badge-2))]
           (is (= 1 (count check)))
-          (is (= "pending" (->> check first :status))))))
+          (is (= "accepted" (->> check first :status))))
+        (testing "Delete own endorsement"
+          (let [connect (e/delete! ctx (:id user-badge-2) (:id endorsement) (:id user))]
+            (is (= "success" (:status connect)))))
+        ))

-    (testing "Reject endorsment")
-    (testing "Remove endorsement")))
+    (testing "Decline endorsement"
+      (let [endorsement (e/endorse! ctx (:id user-badge) (:id user-3) "This guy rocks")
+            badge-endorsements (e/user-badge-endorsements ctx (:id user-badge))]
+        (is (= (:status endorsement) "success"))
+        (is (= 1 (count badge-endorsements)))
+
+        (let [connect (e/update-status! ctx (:id user) (:id user-badge) (:id endorsement) "declined")
+              check (e/user-badge-endorsements ctx (:id user-badge))]
+          (is (= "success" (:status connect)))
+          (is (= nil (seq check))))
+        ))
+
+    (testing "Edit endorsement"
+      (let [endorsement (e/endorse! ctx (:id user-badge) (:id user-3) "This guy rocks")
+            _ (e/update-status! ctx (:id user) (:id user-badge) (:id endorsement) "accepted")
+            badge-endorsements (e/user-badge-endorsements ctx (:id user-badge))]
+        (is (= (:status endorsement) "success"))
+        (is (= 1 (count badge-endorsements)))
+        (is (= (->> badge-endorsements first :status) "accepted"))
+
+        (let [connect (e/edit! ctx (:id user-badge) (:id endorsement) "This guy sucks!" (:id user-3))
+              badge-endorsements (e/user-badge-endorsements ctx (:id user-badge))]
+          (is (= (:status connect) "success"))
+          (is (= (->> badge-endorsements first :status) "pending"))
+          #_(is (= (->> badge-endorsements first :content) "This guy sucks!"))
+          )
+
+        )
+      )))

 (migrator/reset-seeds (migrator/test-config))


maybe better placeholders

maybe better placeholders

--- src-cljs/frontend/components/canvas.cljs
+++ src-cljs/frontend/components/canvas.cljs
@@ -342,7 +342,7 @@
                       (dom/input #js {:type "text"
                                       :ref "id-input"
                                       :onClick #(.focus (om/get-node owner "id-input"))
-                                      :placeholder "Name this shape..."
+                                      :placeholder "Give this shape a unique id"
                                       :value (or (:layer/ui-id layer) "")
                                       ;; TODO: defaults for each layer when we create them
                                       :onChange #(cast! :layer-ui-id-edited {:value (.. % -target -value)})}))
@@ -351,6 +351,7 @@
                         (dom/div #js {:className "input-container"}
                           (dom/input #js {:type "text"
                                           :ref "target-input"
+                                          :placeholder "Link to another shape"
                                           :value (or (:layer/ui-target layer) "")
                                           :onClick #(.focus (om/get-node owner "target-input"))
                                           :onChange #(cast! :layer-ui-target-edited {:value (.. % -target -value)})})


gtag clj 2nd try

gtag clj 2nd try

--- src/clojurescript/nossal/app/app.cljs
+++ src/clojurescript/nossal/app/app.cljs
@@ -84,4 +84,4 @@

 (.addEventListener js/document "DOMContentLoaded" (fn [] (analytics-setup data-analytics)))
-; (analytics-setup data-analytics)
+(analytics-setup data-analytics)


Update user settings beta program layout and strings

--- src-cljs/frontend/components/account.cljs
+++ src-cljs/frontend/components/account.cljs
@@ -136,7 +136,6 @@
     (render [_]
       (html
        [:div
-        [:h3.subheading "Current Beta Features"]
         (card/collection
          (for [{:keys [name description]} available-betas]
           (card/titled {:title name} description)))]))))
@@ -206,6 +205,7 @@
                 We'll let you know when we release updates
                 so you'll be the first to see new
                 features!"]
+           [:p "You can see a list of the beta features that you have access to below."]
            [:p "We'd love to know what you think - " [:a {:href "mailto:beta@circleci.com"} "send us your feedback"] "!"]
            (button/button
             {:on-click #(do


vein buttons don't need veins wrapper anymore

--- src-cljs/frontend/components/overlay.cljs
+++ src-cljs/frontend/components/overlay.cljs
@@ -105,48 +105,47 @@
             doc (doc-model/find-by-id @db (:document/id app))]
         (html
           [:div.menu-view
-           [:div.veins
-            [:a.vein.make
-             {:on-click         #(cast! :overlay-info-toggled)
-              :on-touch-end #(do (cast! :overlay-info-toggled) (.preventDefault %))
-              :role "button"}
-             (common/icon :info)
-             [:span "About"]]
-            [:a.vein.make
-             {:href "/new"
-              :role "button"}
-             (common/icon :newdoc)
-             [:span "New Document"]]
-            [:a.vein.make
-             {:on-click         #(cast! :your-docs-opened)
-              :on-touch-end #(do (cast! :your-docs-opened) (.preventDefault %))
-              :role "button"}
-             (common/icon :clock)
-             [:span "Your Documents"]]
-            ;; TODO: should this use the permissions model? Would have to send some
-            ;;       info about the document
-            (if (auth/has-document-access? app (:document/id app))
-              [:a.vein.make
-               {:on-click         #(cast! :sharing-menu-opened)
-                :on-touch-end #(do (cast! :sharing-menu-opened) (.preventDefault %))
-                :role "button"}
-               (common/icon :sharing)
-               [:span "Sharing"]]
-
-              [:a.vein.make
-               {:on-click         #(cast! :document-permissions-opened)
-                :on-touch-end #(do (cast! :document-permissions-opened) (.preventDefault %))
-                :role "button"}
-               (common/icon :users)
-               [:span "Request Access"]])
-            [:a.vein.make
-             {:on-click         #(cast! :shortcuts-menu-opened)
-              :on-touch-end #(do (cast! :shortcuts-menu-opened) (.preventDefault %))
-              :class "mobile-hidden"
-              :role "button"}
-             (common/icon :command)
-             [:span "Shortcuts"]]
-             (om/build auth-link app {:opts {:source "start-overlay"}})]])))))
+           [:a.vein.make
+            {:on-click         #(cast! :overlay-info-toggled)
+             :on-touch-end #(do (cast! :overlay-info-toggled) (.preventDefault %))
+             :role "button"}
+            (common/icon :info)
+            [:span "About"]]
+           [:a.vein.make
+            {:href "/new"
+             :role "button"}
+            (common/icon :newdoc)
+            [:span "New Document"]]
+           [:a.vein.make
+            {:on-click         #(cast! :your-docs-opened)
+             :on-touch-end #(do (cast! :your-docs-opened) (.preventDefault %))
+             :role "button"}
+            (common/icon :clock)
+            [:span "Your Documents"]]
+           ;; TODO: should this use the permissions model? Would have to send some
+           ;;       info about the document
+           (if (auth/has-document-access? app (:document/id app))
+             [:a.vein.make
+              {:on-click         #(cast! :sharing-menu-opened)
+               :on-touch-end #(do (cast! :sharing-menu-opened) (.preventDefault %))
+               :role "button"}
+              (common/icon :sharing)
+              [:span "Sharing"]]
+
+             [:a.vein.make
+              {:on-click         #(cast! :document-permissions-opened)
+               :on-touch-end #(do (cast! :document-permissions-opened) (.preventDefault %))
+               :role "button"}
+              (common/icon :users)
+              [:span "Request Access"]])
+           [:a.vein.make
+            {:on-click         #(cast! :shortcuts-menu-opened)
+             :on-touch-end #(do (cast! :shortcuts-menu-opened) (.preventDefault %))
+             :class "mobile-hidden"
+             :role "button"}
+            (common/icon :command)
+            [:span "Shortcuts"]]
+           (om/build auth-link app {:opts {:source "start-overlay"}})])))))

 (defn private-sharing [app owner]


Fixed programmes fetching.

Fixed programmes fetching.

--- src-cljs/kixi/hecuba/tabs/programmes.cljs
+++ src-cljs/kixi/hecuba/tabs/programmes.cljs
@@ -100,6 +100,21 @@

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Data Fetchers
+(defn fetch-programmes [data]
+  (om/update! data [:programmes :fetching] :fetching)
+  (GET (str "/4/programmes/")
+       {:handler  (fn [x]
+                    (println "Fetching programmes.")
+                    (om/update! data [:programmes :data] (mapv slugify-programme x))
+                    (om/update! data [:programmes :fetching] (if (empty? x) :no-data :has-data))
+                    (om/update! data [:programmes :selected] nil))
+        :error-handler (fn [{:keys [status status-text]}]
+                         (om/update! data [:programmes :fetching] :error)
+                         (om/update! data [:programmes :error-status] status)
+                         (om/update! data [:programmes :error-text] status-text))
+        :headers {"Accept" "application/edn"}
+        :response-format :text}))
+
 (defn fetch-projects [programme-id data]
   (om/update! data [:projects :programme_id] programme-id)
   (om/update! data [:projects :fetching] :fetching)
@@ -149,6 +164,10 @@

       ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
       ;; Fetchers
+      (when-not programmes
+        (om/update! data [:programmes :selected] nil)
+        (fetch-programmes data))
+
       (when (and programmes
                  (not= programmes old-programmes))
         (println "Setting selected programme to: " programmes)
@@ -278,25 +297,6 @@

 (defn programmes-div [data owner]
   (reify
-    om/IDidUpdate
-    (did-update [_ prev-props prev-state]
-      (let [{:keys [programmes active-components]} data
-            programme_id (:programmes active-components)]
-        (when-not programme_id
-          (om/update! programmes :selected nil))
-
-        (if (not (seq (:data programmes)))
-          (GET (str "/4/programmes/")
-               {:handler  (fn [x]
-                            ;; (println "Fetching programmes.")
-                            (om/update! programmes :data (mapv slugify-programme x))
-                            (om/update! programmes :selected nil))
-                ;; TODO: Add Error Handler
-                :headers {"Accept" "application/edn"}
-                :response-format :text}))
-
-        ;; handle selection on programmes table (this should be nil if called)
-        (om/update! programmes :selected (:programmes active-components))))
     om/IRender
     (render [_]
       (html


Improve unknown field error message for resources

--- src/com/puppetlabs/puppetdb/query.clj
+++ src/com/puppetlabs/puppetdb/query.clj
@@ -245,7 +245,7 @@

          ;; ...else, failure
          :else (throw (IllegalArgumentException.
-                       (str path " is not a queryable object")))))
+                       (str path " is not a queryable object for resources")))))

 (defn compile-resource-equality-v1
   "Compile an = operator for a v1 resource query. `path` represents the field
@@ -261,7 +261,7 @@
   ;; ["node" "name"], rewrite it as "certname". But if they specify "certname",
   ;; fail because this is v1.
   (when (= path "certname")
-    (throw (IllegalArgumentException. "certname is not a queryable object")))
+    (throw (IllegalArgumentException. "certname is not a queryable object for resources")))
   (let [path (if (= path ["node" "name"]) "certname" path)]
     (compile-resource-equality-v2 path value)))


whitespace

whitespace

--- figwheel-repl/src/figwheel/server/jetty_websocket.clj
+++ figwheel-repl/src/figwheel/server/jetty_websocket.clj
@@ -76,7 +76,6 @@
             (when (.isCommitted res)
               (.setHandled request true)))
           (proxy-super handle target request req res))))))
-

 (defn set-log-level! [log-lvl]
   (let [level (or ({:all     StdErrLog/LEVEL_ALL


Use claypoole to run request futures.

Use claypoole to run request futures.

Past a certain number of requests, the fact that we were having one
request start up one thread each became a problem for the operating
system. So, now we use claypoole to cap things at 500 threads. This
gives dstt a much larger capacity for issuing requests than it had
previously.

There are still some boundaries that will cause it to error out,
however, so don't get too crazy.

--- src/frmr/dstt.clj
+++ src/frmr/dstt.clj
@@ -4,7 +4,8 @@
             [clojure.tools.cli :refer [parse-opts]]
             [clojure.java.io :as io]
             [clojure.string :refer [join split]]
-            [clojure.data.json :as json])
+            [clojure.data.json :as json]
+            [com.climate.claypoole :as cp])
   (:gen-class))

 ;;; Helper functions.
@@ -47,9 +48,13 @@
   specified amount of time. Then pass the elapsed time and the content of the request through the
   `handler` to get a vector of timing results - where each member of the vector represents one
   category timing."
-  [request-invoker pause handler]
-  (future
-    (Thread/sleep pause)
+  [test-start-time-ns request-invoker pause-ms handler pool]
+  (cp/future
+    pool
+    (let [current-time (System/nanoTime)
+          start-time-difference-ms (int (/ (- current-time test-start-time-ns) 1000000))
+          actual-pause-ms (max 0 (- pause-ms start-time-difference-ms))]
+      (Thread/sleep actual-pause-ms))
     (let [start (System/nanoTime)
           response (request-invoker)
           stop (System/nanoTime)
@@ -67,20 +72,23 @@
   surfaces a bit of timing information in the response, you might query that JSON and generate a
   vector from the information you find there in your handler."
   [request-invoker number-of-requests pause-between-requests handler]
-  (let [request-indicies (range number-of-requests)
-        request-delays (map #(* % pause-between-requests) request-indicies)
-        request-futures (map #(issue-timed-request request-invoker % handler) request-delays)
-        results (doall (map deref (doall request-futures)))
-        grouped-result-categories (partition (count results) (apply interleave results))
-        average-per-category (mapv #(apply-to-numbers % average) grouped-result-categories)
-        min-per-category (mapv #(apply-to-numbers % (fn [x] (apply min x))) grouped-result-categories)
-        max-per-category (mapv #(apply-to-numbers % (fn [x] (apply max x))) grouped-result-categories)
-        stddev-per-category (mapv #(apply-to-numbers % standard-deviation) grouped-result-categories)]
-    {"Averages" average-per-category
-     "Minimums" min-per-category
-     "Maximums" max-per-category
-     "StandardDeviations" stddev-per-category
-     "RawResults" results}))
+  (cp/with-shutdown! [network-pool (cp/threadpool (min 500 number-of-requests))
+                      cpu-pool (cp/threadpool (cp/ncpus))]
+    (let [request-indicies (range number-of-requests)
+          request-delays (map #(* % pause-between-requests) request-indicies)
+          test-start-time-ns (System/nanoTime)
+          request-futures (map #(issue-timed-request test-start-time-ns request-invoker % handler network-pool) request-delays)
+          results (doall (cp/pmap cpu-pool deref (doall request-futures)))
+          grouped-result-categories (partition (count results) (apply interleave results))
+          average-per-category (mapv #(apply-to-numbers % average) grouped-result-categories)
+          min-per-category (mapv #(apply-to-numbers % (fn [x] (apply min x))) grouped-result-categories)
+          max-per-category (mapv #(apply-to-numbers % (fn [x] (apply max x))) grouped-result-categories)
+          stddev-per-category (mapv #(apply-to-numbers % standard-deviation) grouped-result-categories)]
+      {"Averages" average-per-category
+       "Minimums" min-per-category
+       "Maximums" max-per-category
+       "StandardDeviations" stddev-per-category
+       "RawResults" results})))

 (defn- select-function-for-http-method
  [http-method]


cleanup

cleanup

--- statspop/src/statspop/math/matrix.cljs
+++ statspop/src/statspop/math/matrix.cljs
@@ -17,9 +17,6 @@
   IMatrixer
   (matrixify [this]
     (js/goog.math.Matrix. (clj->js this))))
-
-;; according to this http://stackoverflow.com/questions/11421805/clojurescript-protocol-usage I should be able to
-;; treat matrixify like a regular function here now.

 (defn multiply
   "multiply matrices"


Collapse mysql and postgres get-id-key-specs into :default.

--- clj_record/test/main.clj
+++ clj_record/test/main.clj
@@ -8,9 +8,7 @@
 (defmulti get-id-key-spec :subprotocol)
 (defmethod get-id-key-spec "derby" [db-spec name]
   [:id :int (str "GENERATED ALWAYS AS IDENTITY CONSTRAINT " name " PRIMARY KEY")])
-(defmethod get-id-key-spec "postgresql" [db-spec name]
-  [:id "SERIAL UNIQUE PRIMARY KEY"])
-(defmethod get-id-key-spec "mysql" [db-spec name]
+(defmethod get-id-key-spec :default [db-spec name]
   [:id "SERIAL UNIQUE PRIMARY KEY"])

 (defn drop-tables []


Connecting DataTable to T5P API

Connecting DataTable to T5P API


Fix session key deletion

Fix session key deletion

--- src/ansel/session.clj
+++ src/ansel/session.clj
@@ -25,7 +25,7 @@

   (delete-session [_ session-key]
     (let [session-data (read-string (when-slurp session-filename))
-          updated-data (dissoc session-data session-key session-data)]
+          updated-data (dissoc session-data (keyword session-key))]
       (spit session-filename updated-data)
       nil)))


more simplification and indentation removal

--- src/babel/forest.cljc
+++ src/babel/forest.cljc
@@ -53,25 +53,21 @@
                 morph))))

 (defn generate-all [spec grammar lexicon index morph & [total-depth]]
-  (filter #(not (fail? %))
-          (let [total-depth (if total-depth total-depth 0)]
-            (log/debug (str "generate-all: cat: " (get-in spec [:synsem :cat])))
-            (if (= :adjective (get-in spec [:synsem :cat]) )
-              (exception (str "got here; spec=" (strip-refs spec))))
-            (let [add-complements-to-bolts
-                  (fn [bolts path]
-                    (mapcat #(if (not (= :none (get-in % path :none)))
-                               (add-complement % path :top grammar lexicon index morph 0 (+ total-depth (count path)))
-                               [%])
-                            bolts))]
-              (-> (lightning-bolt (lazy-shuffle grammar)
-                                  lexicon
-                                  spec 0 index morph total-depth)
-                  ;; TODO: allow more than a fixed maximum depth of generation (here, 4 levels from top of tree).
-                  (add-complements-to-bolts [:head :head :head :comp] )
-                  (add-complements-to-bolts [:head :head :comp])
-                  (add-complements-to-bolts [:head :comp])
-                  (add-complements-to-bolts [:comp]))))))
+  (let [total-depth (if total-depth total-depth 0)
+        add-complements-to-bolts
+        (fn [bolts path]
+          (mapcat #(if (not (= :none (get-in % path :none)))
+                     (add-complement % path :top grammar lexicon index morph 0 (+ total-depth (count path)))
+                     [%])
+                  bolts))]
+    (-> (lightning-bolt (lazy-shuffle grammar)
+                        lexicon
+                        spec 0 index morph total-depth)
+        ;; TODO: allow more than a fixed maximum depth of generation (here, 4 levels from top of tree).
+        (add-complements-to-bolts [:head :head :head :comp] )
+        (add-complements-to-bolts [:head :head :comp])
+        (add-complements-to-bolts [:head :comp])
+        (add-complements-to-bolts [:comp]))))

 (defn lightning-bolt [grammar lexicon spec depth index morph total-depth]
   "Returns a lazy-sequence of all possible trees given a spec, where
@@ -109,51 +105,51 @@
 (defn add-complement [bolt path spec grammar lexicon cache morph depth total-depth]
   (let [input-spec spec
         from-bolt bolt ;; so we can show what (add-complement) did to the input bolt, for logging.
-        spec (unifyc spec (get-in bolt path))]
-    (let [immediate-parent (get-in bolt (butlast path))
-          start-time (current-time)
-          cached (if cache
-                   (get-lex immediate-parent :comp cache spec)
-                   (do (log/warn (str "no cache: will go through entire lexicon to find candidate complements."))
-                       (reduce concat (vals lexicon))))
-          complement-candidate-lexemes (if (not (= true
-                                                   (get-in bolt (concat path [:phrasal]))))
-                                         (if cached cached (flatten (vals lexicon))))
-          complement-pre-check (fn [child parent path-to-child]
-                                 (let [child-in-bolt (get-in bolt path-to-child)]
-                                   (and (not (fail?
-                                              (unifyc (get-in child [:synsem] :top)
-                                                      (get-in child-in-bolt [:synsem] :top)))))))
-          filtered-lexical-complements (filter (fn [lexeme]
-                                                 (complement-pre-check lexeme bolt path))
-                                               complement-candidate-lexemes)
-          shuffled-candidate-lexical-complements (lazy-shuffle filtered-lexical-complements)]
-      (filter (fn [complement]
-                (if (fail? complement)
-                  (do
-                    (log/debug (str "add-complement(depth=" depth ",total-depth=" total-depth
-                                    ",path=" path ",bolt=(" (show-bolt bolt path morph) ") FAILED:"
-                                    "'" (morph complement) "'"))
-
-                    false)
-                  (do
-                    (log/debug (str "add-complement(depth=" depth ",total-depth=" total-depth
-                                    ",path=" path ",bolt=(" (show-bolt bolt path morph) ")=>"
-                                    "'" (morph complement) "'"))
-                    true)))
-              (map (fn [complement]
-                     (unify (copy bolt)
-                            (path-to-map path
-                                         (copy complement))))
-                   (let [debug (log/debug (str "add-complement(depth=" depth ",total-depth=" total-depth
-                                               ",path=" path ",bolt=(" (show-bolt bolt path morph)
-                                               "): calling generate-all(" (strip-refs spec) ");"
-                                               "input-spec: " input-spec))
-                         phrasal-complements (if (< 10 total-depth)
-                                               (generate-all spec grammar lexicon cache morph (+ depth total-depth)))]
-                     (if (lexemes-before-phrases depth)
-                       (lazy-cat shuffled-candidate-lexical-complements phrasal-complements)
-                       (lazy-cat phrasal-complements shuffled-candidate-lexical-complements))))))))
+        spec (unifyc spec (get-in bolt path))
+        immediate-parent (get-in bolt (butlast path))
+        start-time (current-time)
+        cached (if cache
+                 (get-lex immediate-parent :comp cache spec)
+                 (do (log/warn (str "no cache: will go through entire lexicon to find candidate complements."))
+                     (reduce concat (vals lexicon))))
+        complement-candidate-lexemes (if (not (= true
+                                                 (get-in bolt (concat path [:phrasal]))))
+                                       (if cached cached (flatten (vals lexicon))))
+        complement-pre-check (fn [child parent path-to-child]
+                               (let [child-in-bolt (get-in bolt path-to-child)]
+                                 (and (not (fail?
+                                            (unifyc (get-in child [:synsem] :top)
+                                                    (get-in child-in-bolt [:synsem] :top)))))))
+        filtered-lexical-complements (filter (fn [lexeme]
+                                               (complement-pre-check lexeme bolt path))
+                                             complement-candidate-lexemes)
+        shuffled-candidate-lexical-complements (lazy-shuffle filtered-lexical-complements)]
+    (filter (fn [complement]
+              (if (fail? complement)
+                (do
+                  (log/debug (str "add-complement(depth=" depth ",total-depth=" total-depth
+                                  ",path=" path ",bolt=(" (show-bolt bolt path morph) ") FAILED:"
+                                  "'" (morph complement) "'"))
+
+                  false)
+                (do
+                  (log/debug (str "add-complement(depth=" depth ",total-depth=" total-depth
+                                  ",path=" path ",bolt=(" (show-bolt bolt path morph) ")=>"
+                                  "'" (morph complement) "'"))
+                  true)))
+            (map (fn [complement]
+                   (unify (copy bolt)
+                          (path-to-map path
+                                       (copy complement))))
+                 (let [debug (log/debug (str "add-complement(depth=" depth ",total-depth=" total-depth
+                                             ",path=" path ",bolt=(" (show-bolt bolt path morph)
+                                             "): calling generate-all(" (strip-refs spec) ");"
+                                             "input-spec: " input-spec))
+                       phrasal-complements (if (> 6 total-depth)
+                                             (generate-all spec grammar lexicon cache morph (+ depth total-depth)))]
+                   (if (lexemes-before-phrases depth)
+                     (lazy-cat shuffled-candidate-lexical-complements phrasal-complements)
+                     (lazy-cat phrasal-complements shuffled-candidate-lexical-complements)))))))

 (defn path-to-map [path val]
   (let [feat (first path)]


Optimize subscriptions

Optimize subscriptions

--- src/balance/subs.cljs
+++ src/balance/subs.cljs
@@ -4,18 +4,32 @@
     [balance.db    :refer [conn]]
     [posh.reagent  :refer [q pull]]))

-(reg-sub-raw
+;; -- Helpers ---------------------------------------
+
+(defn reg-query-sub [sub-name query]
+  (reg-sub-raw
+    sub-name
+    (fn [_ [_ & params]]
+      (let [pre-q (partial q query conn)]
+        (apply pre-q params)))))
+
+(defn reg-pull-sub [sub-name pattern]
+  (reg-sub-raw
+    sub-name
+    (fn [_ [_ id]]
+      (pull conn pattern id))))
+
+;; -- Subscriptions ---------------------------------
+
+(reg-query-sub
   :task-ids
-  (fn [_ _]
-    (q '[ :find  [?tid ...]
-          :where [?tid :task/title]] conn)))
+  '[ :find  [?tid ...]
+     :where [?tid :task/title]])

-(reg-sub-raw
+(reg-pull-sub
   :task-preview
-  (fn [_ [_ id]]
-    (pull conn '[:task/title :task/description]  id)))
+  '[:task/title :task/description])

-(reg-sub-raw
+(reg-pull-sub
   :task-details
-  (fn [_ [_ id]]
-    (pull conn '[*]  id)))
+  '[*])


Add test for IMb length in encode-spec

Add test for IMb length in encode-spec


nil or false is no tile

nil or false is no tile

--- src/cljs/infinitelives/pixi/tilemap.cljs
+++ src/cljs/infinitelives/pixi/tilemap.cljs
@@ -26,7 +26,7 @@
           (for [row (range (count tile-map))
                 col (range (count (first tile-map)))]
             (let [char (nth (tile-map row) col)]
-              (when (not= :space char)
+              (when char
                 (s/make-sprite (texture-map char)
                                :x (* tile-width col) :y (* tile-height row)
                                :xhandle 0 :yhandle 0))))))


add more information to dashboard

add more information to dashboard

--- src/cljs/salava/social/ui/dashboard.cljs
+++ src/cljs/salava/social/ui/dashboard.cljs
@@ -2,33 +2,21 @@
   (:require [salava.core.ui.layout :as layout]
             [salava.core.ui.ajax-utils :as ajax]
             [salava.social.ui.stream :as stream]
-            [reagent.core :refer [atom]]
+            [reagent.core :refer [atom cursor]]
             [salava.core.ui.modal :as mo]
             [salava.core.i18n :as i18n :refer [t translate-text]]
             [salava.core.time :refer [date-from-unix-time]]
             [reagent-modals.modals :as m]
             [salava.core.ui.helper :refer [path-for]]
-            [salava.badge.ui.my :as my]))
-
-(defn init-pending-badges [state]
+            [salava.badge.ui.my :as my]
+            [reagent.session :as session]
+            [salava.core.helper :refer [dump]]))
+
+(defn init-dashboard [state]
   (ajax/GET
-    (path-for "/obpv1/social/pending_badges" true)
+    (path-for (str "/obpv1/user/dashboard"))
     {:handler (fn [data]
-                (swap! state assoc :spinner false :pending-badges (:pending-badges data)))}))
-
-(defn init-badge-stats [state]
-  (ajax/GET
-    (path-for "/obpv1/badge/stats" true)
-    {:handler (fn [data]
-                (swap! state assoc :stats data)
-                )}))
-
-
-(defn init-data [state]
-  (stream/init-data state)
-  ;(init-pending-badges state)
-  (my/init-data state)
-  (init-badge-stats state))
+                (reset! state data))}))

 (defn follow-event-badge [event state]
   (let [{:keys [subject verb image_file message ctime event_id name object]}  event
@@ -50,15 +38,16 @@

 (defn message-event [event state]
   (let [{:keys [subject verb image_file message ctime event_id name object]}  event
-        reload-fn (fn [] (init-data state))]
+        ;reload-fn (fn [] (init-data state))
+        ]
     [:div {:class "media"}
      [:a {:href "#"
           :on-click #(do
                        ;(b/open-modal object true init-data state)
-                       (init-data state)
+                       ;(init-data state)
                        (mo/open-modal [:gallery :badges] {:badge-id object
                                                           :show-messages true
-                                                          :reload-fn reload-fn})
+                                                          :reload-fn nil})
                        (.preventDefault %) )
           :style {:text-decoration "none"}}
       [:div.media-left
@@ -72,131 +61,198 @@
 (defn welcome-block [state]
   [:div#welcome-block {:class "block"}
    [:div.welcome-block.block-content.row
-    [:div.content "Welcome back to open badge passport"]
-    ]])
-
-#_(defn notifications-block [state]
-    [:div#notifications-block {:class "block"}
-     [:div.notifications-block.block-content
-      [:div.heading_1 [:i.fa.fa-rss.icon]
-       [:span.title "notifications"]]
-      ]])
+    [:a {:data-toggle "collapse" :href "#hidden" :role "button" :aria-expanded "false" :aria-controls "hidden"}
+   [:div.content
+    [:div
+                                                                                [:i.fa.fa-chevron-down.icon]
+                                                                                "Welcome back to open badge passport"]]
+    [:div.collapse.hidden-content {:id "hidden" }
+     [:p "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."]
+     ]
+    ]]])

 (defn notifications-block [state]
   (let [events (:events @state)]
-    [:div#notifications-block {:class "block col-md-3" }
-     ;(prn @state)
-     [:div.notifications-block.block-content
-      [:div.heading_1 [:i.fa.fa-rss.icon]
-       [:a {:href "social/stream"} [:span.title "notifications"]] [:span.badge (count events)]]
-      (reduce (fn [r event]
-                (conj r [:div.notification-div.ax_default
-                         (cond
-                           (and (= "badge" (:type event)) (= "follow" (:verb event))) (follow-event-badge event state)
-                           (and (= "user" (:type event)) (= "follow" (:verb event))) (stream/follow-event-user event state)
-                           (and (= "badge" (:type event)) (= "publish" (:verb event))) (stream/publish-event-badge event state)
-                           (and (= "page" (:type event)) (= "publish" (:verb event))) (stream/publish-event-page event state)
-                           (= "advert" (:type event)) (stream/badge-advert-event event state)
-                           (= "message" (:verb event)) [message-event event state]
-                           :else "")
-                         ])
-                )[:div.content] (->> (take 5 events) (remove #(= (:verb %) "ticket"))))
-      ]]))
+    [:div {:class "box col-md-4" }
+     [:div#box_1
+      [:div.col-md-12.block
+       ;(prn @state)
+       [:div.notifications-block.row_1;.block-content
+        [:div.heading_1 [:i.fa.fa-rss.icon]
+         [:a {:href "social/stream"} [:span.title "notifications"]] [:span.badge (:events_count @state)]]
+        (reduce (fn [r event]
+                  (conj r [:div.notification-div.ax_default
+                           (cond
+                             (and (= "badge" (:type event)) (= "follow" (:verb event))) (follow-event-badge event state)
+                             (and (= "user" (:type event)) (= "follow" (:verb event))) (stream/follow-event-user event state)
+                             (and (= "badge" (:type event)) (= "publish" (:verb event))) (stream/publish-event-badge event state)
+                             (and (= "page" (:type event)) (= "publish" (:verb event))) (stream/publish-event-page event state)
+                             (= "advert" (:type event)) (stream/badge-advert-event event state)
+                             (= "message" (:verb event)) [message-event event state]
+                             :else "")
+                           ])
+                  )[:div.content] (->> events (remove #(= (:verb %) "ticket"))))
+        ]]]]))

 (defn badges-block [state]
-  [:div#badge-block {:class "block col-md-6"}
-   [:div.badge-block.block-content
-    [:div.heading_1
-     [:i.fa.fa-certificate.icon]
-      [:a {:href (path-for "/badge")} [:span.title "Badges"]]]
-     [:div.content
-      [:div.stats
-         [:div.total-badges
-          [:p.num (get-in @state [:stats :badge_count] 0)]
-          [:p.desc (t :badge/Badges)]]
-         [:div
-          [:p.num (->> (get-in @state [:stats :badge_views])
-                      (reduce #(+ %1 (:reg_count %2) (:anon_count %2)) 0))]
-          [:p.desc (t :badge/Badgeviews)]]]
-
-      [:div.pending
-       [:p.header (t :badge/Pendingbadges)]
-       (if (seq (:pending-badges @state))
-         (reduce (fn [r badge]
-                   (conj r [:a {:href (path-for "/badge")} [:img {:src (str "/" (:image_file badge)) :alt (:name badge) :title (:name badge)}]])
-                   ) [:div] (take 5 (:pending-badges @state)))
-         )]
-      [:div.badges
-       [:p.header (t :badge/Lastestearnedbadges)]
-       (reduce (fn [r badge]
-                   (conj r [:a {:href "#" :on-click #(do
-                                                       (.preventDefault %)
-                                                       (mo/open-modal [:badge :info] {:badge-id (:id badge )}))} [:img {:src (str "/" (:image_file badge)) :alt (:name badge) :title (:name badge)}]])
-                   ) [:div] (take 5 (:badges @state)))
+  (fn []
+    (let [badges (:badges @state )]
+      [:div {:class "box col-md-5 "}
+       [:div#box_2
+        [:div.col-md-12.block
+         [:div.badge-block;.block-content
+          [:div.heading_1
+           [:i.fa.fa-certificate.icon]
+           [:a {:href (path-for "/badge")} [:span.title "Badges"]]]
+          [:button.btn.button "Earn badges"]
+          [:div.content
+           [:div.stats
+            [:div.total-badges
+             [:p.num (get-in @state [:stats :badge_count] 0)]
+             [:p.desc (t :badge/Badges)]]
+            [:div
+             [:p.num (->> (get-in @state [:stats :badge_views])
+                          (reduce #(+ %1 (:reg_count %2) (:anon_count %2)) 0))]
+             [:p.desc (t :badge/Badgeviews)]]]
+
+           (when (seq (:pending-badges @state)) [:div.pending
+                                                 [:p.header (t :badge/Pendingbadges)]
+                                                 (if (seq (:pending-badges @state))
+                                                   (reduce (fn [r badge]
+                                                             (conj r [:a {:href (path-for "/badge")} [:img {:src (str "/" (:image_file badge)) :alt (:name badge) :title (:name badge)}]])
+                                                             ) [:div] (take 5 (:pending-badges @state)))
+                                                   )])
+           [:div.badges
+            [:p.header (t :badge/Lastestearnedbadges)]
+            (reduce (fn [r badge]
+                      (conj r [:a {:href "#" :on-click #(do
+                                                          (.preventDefault %)
+                                                          (mo/open-modal [:badge :info] {:badge-id (:id badge )}))} [:img {:src (str "/" (:image_file badge)) :alt (:name badge) :title (:name badge)}]])
+                      ) [:div] badges)
+            ]
+           [:div.badges
+            [:p.header (t :badge/Latestearnablebadges)]
+            ;[earnable-badges state]
+            ]
+           ]
+          ]]]])))
+
+(defn explore-block [state]
+  [:div.box.col-md-4
+
+   [:div#box_1 {:class "row_2"}
+    [:div.col-md-12.block
+     [:div.row_2;.block-content
+      [:div.heading_1
+       [:i.fa.fa-search.icon]
+       [:span.title "Explore"]]
+      [:div.content
+       [:div.info-block.badge-connection
+        [:a {:href (path-for "/gallery/badges")}
+         [:div.info
+         [:i.fa.fa-certificate.icon]
+         [:div.text
+          [:p.num (get-in @state [:gallery :badges])]
+          [:p.desc (t :badge/Badges)]]]]]
+              [:div.info-block.page
+        [:a {:href (path-for "/gallery/pages")}[:div.info
+         [:i.fa.fa-file.icon]
+         [:div.text
+          [:p.num (get-in @state [:gallery :pages])]
+          [:p.desc (t :page/Pages)]]]]]
+              [:div.info-block
+        [:a {:href (path-for "/gallery/profiles")}[:div.info
+         [:i.fa.fa-user.icon]
+         [:div.text
+          [:p.num (get-in @state [:gallery :profiles])]
+          [:p.desc (t :gallery/profiles)]]]]]
+
        ]
-      [:div.badges
-       [:p.header (t :badge/Latestearnablebadges)]
-       ;[earnable-badges state]
+      ]]]])
+
+(defn connections-block [state]
+  [:div.box.col-md-5
+   [:div#box_2
+    [:div.col-md-12.block
+     [:div.row_2
+      [:div
+       [:div.heading_1 [:i.fa.fa-group.icon]
+        [:span.title
+         "Connections"]]
+       [:div.content;.connections-block;.block-content
+        [:div.info-block.badge-connection
+         [:div.info
+          [:i.fa.fa-certificate.icon]
+          [:div.text
+           [:p.num (get-in @state [:connections :badges])]
+           [:p.desc (t :badge/Badges)]]]]
+        [:div.info-block.endorsement
+         [:div.info
+          [:i.fa.fa-thumbs-up.icon]
+          [:div.text
+           [:p.num (:endorsing @state)]
+           [:p.desc "Endorsing" #_(t :badge/Endorsing)]
+           ]
+          ]
+         ]
+        [:div.info-block.endorsement
+         [:div.info
+          [:i.fa.fa-thumbs-up.icon]
+          [:div.text
+           [:p.num (:endorsers @state)]
+           [:p.desc "Endorsers" #_(t :badge/Endorsing)]
+           ]
+          ]
+         ]
+        ]]]]]])
+
+(defn profile-block [state]
+  [:div.box.col-md-3
+   [:div.row_1 {:id "box_1"}
+    [:div.col-md-12.block
+     [:div.profile-block;.block-content
+      [:div.heading_1
+       [:i.fa.fa-user.icon]
+       [:span.title
+        "Profile"]]]]]])
+
+(defn help-block [state]
+  [:div {:class "box col-md-3"}
+   [:div#box_3
+    [:div.col-md-12.block
+     [:div.row_2.help;.getting-started.block-content
+      [:div.heading_1
+       [:i.fa.fa-info-circle.icon]
+       [:span.title.help
+        "Help"]]
+      [:div.content
+       [:a {:href (str (path-for "/user/profile/") (session/get-in [:user :id]))}[:p (t :badge/Iwanttoseeprofile)]]
+       [:a {:href (str (path-for "/user/edit/profile"))}[:p (t :badge/Iwanttoeditprofile)]]
+       [:a {:href (str (path-for "/badge"))}[:p (t :badge/Iwanttoseemysbadges)]]
+       (when (some #(= % :extra/application) (session/get :plugins))[:p (t :badge/Iwanttoearnnewbadges)])
+       [:a {:href (str (path-for "/gallery/badges"))} [:p (t :badge/Iwanttofindbadges)]]
+
        ]
       ]
-     ]])
-
-(defn explore-block [state]
-  [:div#explore-block {:class "block col-sm-3"}
-   [:div.explore-block.block-content
-    [:div.heading_1
-     [:i.fa.fa-search.icon]
-     [:span.title "Explore"]]
-    ]])
-
-(defn connections-block [state]
-  [:div#connections-block {:class "block col-sm-6"}
-   [:div.connections-block.block-content
-    [:div.heading_1 [:i.fa.fa-group.icon]
-     [:span.title
-      "Connections"]]
-    ]])
-
-(defn profile-block [state]
-  [:div#profile-block {:class "block col-sm-3"}
-   [:div.profile-block.block-content
-    [:div.heading_1
-     [:i.fa.fa-user.icon]
-     [:span.title
-      "Profile"]]]])
-
-(defn help-block [state]
-  [:div#getting-started {:class "block col-md-3"}
-   [:div.getting-started.block-content
-    [:div.heading_1
-     [:i.fa.fa-info-circle.icon]
-     [:span.title.help
-      "Help"]]
-    ]
-   ]
+     ]]]
   )

 (defn content [state]
-  #_[:div.grid-container
-     [:header.row [welcome-block state]]
-     [:main [notifications-block state] [badges-block state]
-      ]
-
-     ]
-
   [:div#dashboard-container
    [m/modal-window]
    [welcome-block state]
    [:div.row
     [notifications-block state]
     [badges-block state]
+    [profile-block state]
+    ]
+
+   [:div.row
+    ;[profile-block state]
+
+    [explore-block state]
+    [connections-block state]
     [help-block]
-
-    ]
-   [:div.row
-    [profile-block state]
-    [connections-block state]
-    [explore-block state]

     ]])
@@ -204,6 +260,6 @@

 (defn handler [site-navi]
   (let [state (atom {})]
-    (init-data state)
+    (init-dashboard state)
     (fn [] (layout/dashboard site-navi [content state]))))


Remove unused variable

Remove unused variable

--- src/braid/server/search/elasticsearch.clj
+++ src/braid/server/search/elasticsearch.clj
@@ -18,8 +18,7 @@
                   {:body (json/write-str {:query {:match {:content text}}})})
                :body
                json/read-str
-               (get "hits"))
-        more (- (get resp "total") (count (get resp "hits")))]
+               (get "hits"))]
     (->> (get resp "hits")
          (map #(Long. (get % "_id")))
          (d/pull-many (d/db db/conn) [{:message/thread [:thread/id]}])


Test test-create-bad-request-response-1

Test test-create-bad-request-response-1

--- test/emender_jenkins/rest_api_test.clj
+++ test/emender_jenkins/rest_api_test.clj
@@ -265,6 +265,13 @@
             {:status "error" :jobName "job-name" :command "command" :message nil}       (create-error-response "job-name" "command" nil)
             {:status "error" :jobName nil        :command nil       :message nil}       (create-error-response nil nil nil))))

+(deftest test-create-bad-request-response-1
+    "Check the function emender-jenkins.rest-api/create-bad-request-response."
+    (testing "the function emender-jenkins.rest-api/create-bad-request-response."
+        (are [x y] (= x y)
+            {:status "error" :command "command"} (create-bad-request-response "command")
+            {:status "error" :command nil      } (create-bad-request-response nil))))
+
 (deftest test-create-bad-request-response-2
     "Check the function emender-jenkins.rest-api/create-bad-request-response."
     (testing "the function emender-jenkins.rest-api/create-bad-request-response."


Add some comments to comic-list dev cards

--- test/cljs/comic_reader/ui/comic_list_test.cljs
+++ test/cljs/comic_reader/ui/comic_list_test.cljs
@@ -28,10 +28,12 @@
     [sut/comic-list-container]))

 (defcard-rg letter-filter
+  "Individual letter-filters"
   [:ul.sub-nav.no-bullet
    [sut/letter-filter "A" "B"]
    [sut/letter-filter "B" "B"]
    [sut/letter-filter "C" ""]])

 (defcard-rg alphabet-letter-filters
+  "The letter \"F\" should be highlighted below"
   [sut/alphabet-letter-filters "F"])


Replace less than sign in creator with ")"

--- src/catalog/vubis.clj
+++ src/catalog/vubis.clj
@@ -182,6 +182,9 @@
   (when-let [year (and s (re-find #"\d{4}" s))]
     (time.format/parse (time.format/formatters :year) year)))

+(defn- replace-less-than-sign [s]
+  (some-> s (string/replace #"<|>" {"<" "(" ">" ")"})))
+
 (defn remove-nonprintable-chars [s]
   (and s (string/replace s #"[¶¬]" "")))

@@ -247,7 +250,7 @@
                   :title (remove-nonprintable-chars title)
                   :subtitles (seq (map remove-nonprintable-chars subtitles))
                   :name-of-part (remove-nonprintable-chars name-of-part)
-                  :creator creator
+                  :creator (replace-less-than-sign creator)
                   :description description
                   :source-publisher source-publisher
                   :source source


not returning actions

not returning actions

--- src/celestial/api.clj
+++ src/celestial/api.clj
@@ -115,7 +115,7 @@

   (PUT- "/action/:id" [^:int id & ^:action action] {:nickname "updateActions" :summary "Update an actions set"}
         (p/update-action id action)
-        (success {:msg "updated actions" :action action}))
+        (success {:msg "updated actions"}))

   (GET- "/action/:id" [^:int id] {:nickname "getActions" :summary "Gets actions descriptor"}
         (success {:action (p/get-action id)}))


Improve consistency of property names

Improve consistency of property names

--- test/snergly/algorithms_properties.clj
+++ test/snergly/algorithms_properties.clj
@@ -193,7 +193,7 @@
   [alg-name & specs]

   (let [specs (cond
-                (empty? specs)     #{:perfect :all-changed :accurate-changes :each-changes :updates-link-2}
+                (empty? specs)     #{:perfect :all-changed :accurate-changes :each-update-changes :updates-link-2}
                 (= [:loose] specs) #{:perfect :all-changed :accurate-changes :each-incomplete-changes :incompletes-link-2}
                 :else              (set specs))]
     `(do
@@ -203,7 +203,7 @@
        (when (contains? ~specs :all-changed)
          (check-algorithm-all-cells-changed ~alg-name))

-       (when (contains? ~specs :each-changes)
+       (when (contains? ~specs :each-update-changes)
          (check-algorithm-each-update-changes ~alg-name))

        (when (contains? ~specs :each-incomplete-changes)
@@ -227,7 +227,7 @@
 (check-algorithm-properties "binary-tree")
 (check-algorithm-properties "sidewinder")
 (check-algorithm-properties "wilsons")
-;; The following two can't pass :each-changes because the last update might be a duplicate.
+;; The following can't pass :each-changes because the last update might be a duplicate.
 (check-algorithm-properties "aldous-broder" :loose)
 (check-algorithm-properties "hunt-and-kill" :loose)
 (check-algorithm-properties "recursive-backtracker" :loose)


Fixed clblast_test.

Fixed clblast_test.

--- test/uncomplicate/neanderthal/clblast_test.clj
+++ test/uncomplicate/neanderthal/clblast_test.clj
@@ -9,7 +9,8 @@
              [real-test :as real-test]
              [device-test :as device-test]
              [math-test :as math-test]]
-            [uncomplicate.neanderthal.internal.device.clblast :refer [clblast-float clblast-double]]))
+            [uncomplicate.neanderthal.internal.device.clblast :refer [clblast-float clblast-double]])
+  (:import clojure.lang.ExceptionInfo))

 (defn test-blas-clblast [factory]
   (real-test/test-imin factory)
@@ -24,8 +25,8 @@
 (with-default-1

   (facts "factory-by-type test"
-         (= opencl-float (factory-by-type :float)) => true
-         (= opencl-double (factory-by-type :double)) => true
+         (= clblast-float (factory-by-type :float)) => true
+         (= clblast-double (factory-by-type :double)) => true
          (factory-by-type :int) => (throws ExceptionInfo)
          (factory-by-type :long) => (throws ExceptionInfo))


* src/clj/cljs/core.clj: collect protocols and add to deftype and defrecord name symbol metadata

--- src/clj/cljs/core.clj
+++ src/clj/cljs/core.clj
@@ -440,15 +440,25 @@
              (drop-while seq? (next s)))
       ret)))

+(defn collect-protocols [impls env]
+  (->> impls
+      (filter symbol?)
+      (map #(:name (cljs.compiler/resolve-var (dissoc env :locals) %)))
+      (into #{})))
+
 (defmacro deftype [t fields & impls]
   (let [r (:name (cljs.compiler/resolve-var (dissoc &env :locals) t))
-        [fpps pmasks] (prepare-protocol-masks &env t impls)]
+        [fpps pmasks] (prepare-protocol-masks &env t impls)
+        protocols (collect-protocols impls &env)
+        t (vary-meta t assoc
+            :protocols protocols
+            :skip-protocol-flag fpps) ]
     (if (seq impls)
       `(do
          (deftype* ~t ~fields ~pmasks)
          (set! (.-cljs$lang$type ~t) true)
          (set! (.-cljs$lang$ctorPrSeq ~t) (fn [this#] (list ~(core/str r))))
-         (extend-type ~(with-meta t {:skip-protocol-flag fpps}) ~@(dt->et impls fields))
+         (extend-type ~t ~@(dt->et impls fields))
          ~t)
       `(do
          (deftype* ~t ~fields ~pmasks)
@@ -521,10 +531,14 @@
                                  (concat [~@(map #(list `vector (keyword %) %) base-fields)]
                                          ~'__extmap))))
                   ])
-          [fpps pmasks] (prepare-protocol-masks env tagname impls)]
+          [fpps pmasks] (prepare-protocol-masks env tagname impls)
+          protocols (collect-protocols impls env)
+          tagname (vary-meta tagname assoc
+                    :protocols protocols
+                    :skip-protocol-flag fpps)]
       `(do
          (~'defrecord* ~tagname ~hinted-fields ~pmasks)
-         (extend-type ~(with-meta tagname {:skip-protocol-flag fpps}) ~@(dt->et impls fields))))))
+         (extend-type ~tagname ~@(dt->et impls fields))))))

 (defn- build-positional-factory
   [rsym rname fields]


CLJS-1052: Cannot require ns from within the ns at the REPL for reloading purposes

Detect self requires, switch to the user ns if necessary and switch back

--- src/clj/cljs/repl.clj
+++ src/clj/cljs/repl.clj
@@ -461,6 +461,17 @@
 ;; form     - complete form entered at the repl
 ;; opts     - REPL options, essentially augmented cljs.closure/build options

+(defn self-require? [specs]
+  (some
+    (fn [quoted-spec-or-kw]
+      (and (not (keyword? quoted-spec-or-kw))
+           (let [spec (second quoted-spec-or-kw)
+                 ns (if (sequential? spec)
+                      (first spec)
+                      spec)]
+             (= ns ana/*cljs-ns*))))
+    specs))
+
 (def default-special-fns
   (let [load-file-fn
         (fn self
@@ -471,58 +482,65 @@
     {'in-ns
      (fn self
        ([repl-env env form]
-         (self repl-env env form nil))
+        (self repl-env env form nil))
        ([repl-env env [_ [quote ns-name] :as form] _]
          ;; guard against craziness like '5 which wreaks havoc
-         (when-not (and (= quote 'quote) (symbol? ns-name))
-           (throw (IllegalArgumentException. "Argument to in-ns must be a symbol.")))
-         (when-not (ana/get-namespace ns-name)
-           (swap! env/*compiler* assoc-in [::ana/namespaces ns-name] {:name ns-name})
-           (-evaluate repl-env "<cljs repl>" 1
-             (str "goog.provide('" (comp/munge ns-name) "');")))
-         (set! ana/*cljs-ns* ns-name)))
+        (when-not (and (= quote 'quote) (symbol? ns-name))
+          (throw (IllegalArgumentException. "Argument to in-ns must be a symbol.")))
+        (when-not (ana/get-namespace ns-name)
+          (swap! env/*compiler* assoc-in [::ana/namespaces ns-name] {:name ns-name})
+          (-evaluate repl-env "<cljs repl>" 1
+            (str "goog.provide('" (comp/munge ns-name) "');")))
+        (set! ana/*cljs-ns* ns-name)))
      'require
      (fn self
        ([repl-env env form]
-         (self repl-env env form nil))
+        (self repl-env env form nil))
        ([repl-env env [_ & specs :as form] opts]
-         (evaluate-form repl-env env "<cljs repl>"
-           (with-meta
-             `(~'ns ~ana/*cljs-ns*
-                (:require
-                  ~@(map
-                      (fn [quoted-spec-or-kw]
-                        (if (keyword? quoted-spec-or-kw)
-                          quoted-spec-or-kw
-                          (second quoted-spec-or-kw)))
-                      specs)))
-             {:merge true :line 1 :column 1})
-           identity opts)))
+        (let [is-self-require? (self-require? specs)
+              [target-ns restore-ns]
+              (if-not is-self-require?
+                [ana/*cljs-ns* nil]
+                ['cljs.user ana/*cljs-ns*])]
+          (evaluate-form repl-env env "<cljs repl>"
+            (with-meta
+              `(~'ns ~target-ns
+                 (:require
+                   ~@(map
+                       (fn [quoted-spec-or-kw]
+                         (if (keyword? quoted-spec-or-kw)
+                           quoted-spec-or-kw
+                           (second quoted-spec-or-kw)))
+                       specs)))
+              {:merge true :line 1 :column 1})
+            identity opts)
+          (when is-self-require?
+            (set! ana/*cljs-ns* restore-ns)))))
      'require-macros
      (fn self
        ([repl-env env form]
-         (self repl-env env form nil))
+        (self repl-env env form nil))
        ([repl-env env [_ & specs :as form] opts]
-         (evaluate-form repl-env env "<cljs repl>"
-           (with-meta
-             `(~'ns ~ana/*cljs-ns*
-                (:require-macros
-                  ~@(map
-                      (fn [quoted-spec-or-kw]
-                        (if (keyword? quoted-spec-or-kw)
-                          quoted-spec-or-kw
-                          (second quoted-spec-or-kw)))
-                      specs)))
-             {:merge true :line 1 :column 1})
-           identity opts)))
+        (evaluate-form repl-env env "<cljs repl>"
+          (with-meta
+            `(~'ns ~ana/*cljs-ns*
+               (:require-macros
+                 ~@(map
+                     (fn [quoted-spec-or-kw]
+                       (if (keyword? quoted-spec-or-kw)
+                         quoted-spec-or-kw
+                         (second quoted-spec-or-kw)))
+                     specs)))
+            {:merge true :line 1 :column 1})
+          identity opts)))
      'load-file load-file-fn
      'clojure.core/load-file load-file-fn
      'load-namespace
      (fn self
        ([repl-env env form]
-         (self env repl-env form nil))
+        (self env repl-env form nil))
        ([repl-env env [_ ns :as form] opts]
-         (load-namespace repl-env ns opts)))}))
+        (load-namespace repl-env ns opts)))}))

 (defn analyze-source
   "Given a source directory, analyzes all .cljs files. Used to populate


Tundra unit tests: switch from S3->disk data store

Disk store is a better fit here (fewer dependencies, etc.). Only used
S3 originally since the disk store didn't exist when these tests were
first written.

--- test/taoensso/carmine/tests/tundra.clj
+++ test/taoensso/carmine/tests/tundra.clj
@@ -1,18 +1,19 @@
 (ns taoensso.carmine.tests.tundra
-  (:require [clojure.test :refer :all]
-            [taoensso.carmine :as car  :refer (wcar)]
-            [taoensso.carmine.message-queue :as mq]
-            [taoensso.carmine.tundra        :as tundra]
-            [taoensso.carmine.tundra.s3     :as ts3])
-  (:import  [com.amazonaws.services.s3.model AmazonS3Exception]))
+  (:require
+   [clojure.test     :as test :refer [is deftest]]
+   [taoensso.carmine :as car  :refer [wcar]]
+   [taoensso.carmine.message-queue :as mq]
+   [taoensso.carmine.tundra        :as tundra]
+   [taoensso.carmine.tundra.disk   :as tdisk]))

-(comment (test/run-tests '[taoensso.carmine.tests.tundra]))
+(comment
+  (remove-ns      'taoensso.carmine.tests.tundra)
+  (test/run-tests 'taoensso.carmine.tests.tundra))

 (defmacro wcar* [& body] `(car/wcar {} ~@body))
 (def tkey (partial car/key :carmine :tundra :test))
 (def tqname "carmine-tundra-tests")
 (def mqname (format "tundra:%s" (name tqname))) ; Nb has prefix
-

 (defn clean-up! []
   (mq/clear-queues {} mqname)
@@ -21,31 +22,16 @@
            (apply car/srem @#'tundra/k-evictable ks)))
   (wcar* (car/srem @#'tundra/k-evictable (tkey :invalid-evictable))))

+(defn cleanup-fixture [f] (clean-up!) (f) (clean-up!))
+(test/use-fixtures :once cleanup-fixture)

-(defn cleanup-fixture
-  [f]
-  (clean-up!)
-  (f)
-  (clean-up!))
-
-(use-fixtures :once cleanup-fixture)
-
-
-(defonce s3-creds {:access-key (get (System/getenv) "AWS_S3_ACCESS_KEY")
-                   :secret-key (get (System/getenv) "AWS_S3_SECRET_KEY")})
-
-(def dstore (ts3/s3-datastore s3-creds "ensso-store/tundra"))
+(def dstore (tdisk/disk-datastore "./carmine-tundra-test-temp"))

 (defn- s->ba [^String s] (.getBytes s "UTF-8"))
 (defn- ba->s [^bytes ba] (String.  ba "UTF-8"))

-;;;; S3 DataStore
-
-(deftest s3-tests
-  (is (true? (and (:access-key s3-creds)
-                  (:secret-key s3-creds))))
-
-  (testing "Basic put and fetch case"
+(deftest datastore-tests
+  (test/testing "Basic put and fetch case"
     (tundra/put-key dstore (tkey :foo) (s->ba "hello world"))
     (is (= "hello world"
            (-> dstore
@@ -53,7 +39,7 @@
                first
                ba->s))))

-  (testing "Update val case"
+  (test/testing "Update val case"
     (tundra/put-key dstore (tkey :foo) (s->ba "hello world 1"))
     (tundra/put-key dstore (tkey :foo) (s->ba "hello world 2"))
     (is (= "hello world 2"
@@ -62,21 +48,20 @@
                first
                ba->s))))

-  (testing "Exception Case"
-    (is (thrown? AmazonS3Exception
-                 (first (tundra/fetch-keys dstore [(tkey :invalid)]))))))
-
+  (test/testing "Exception Case"
+    (is (instance? java.nio.file.NoSuchFileException
+                   (first (tundra/fetch-keys dstore [(tkey :invalid)]))))))

 (deftest tundra-api-test-1
   (let [tstore (tundra/tundra-store dstore)]
-    (testing "Bad cases"
+    (test/testing "Bad cases"
       (is (thrown? Exception (wcar* (tundra/dirty tstore (tkey :invalid)))))
       (is (= nil (wcar* (tundra/ensure-ks tstore (tkey :invalid)))))
       (is (thrown? Exception
                    (wcar* (car/sadd @#'tundra/k-evictable (tkey :invalid-evictable))
                           (tundra/ensure-ks tstore (tkey :invalid-evictable))))))

-    (testing "API never pollutes enclosing pipeline"
+    (test/testing "API never pollutes enclosing pipeline"
       (is (= ["OK" "PONG" 1]
              (wcar* (car/set (tkey 0) "0")
                     (car/ping)
@@ -102,7 +87,7 @@
                                      (tkey 0) (tkey 1) (tkey 2))
                        (catch Exception _ nil)))

-           (Thread/sleep 8000)          ; Wait for replication
+           (Thread/sleep 8000) ; Wait for replication
            (mq/stop tworker)
            (wcar* (car/del (tkey 0))
                   (car/set (tkey 2) [:clj-val-new])) ; Make some local modifications
@@ -117,41 +102,40 @@

 (deftest tundra-api-test-3
-  (is (= [-1 -1 -1]        ; nil eviction timeout (default) is respected!
+  (is (= [-1 -1 -1] ; nil eviction timeout (default) is respected!
          (let [tstore  (tundra/tundra-store dstore {:tqname tqname})
                tworker (tundra/worker tstore {} {:eoq-backoff-ms 100 :throttle-ms 100})]
            (wcar* (car/mset (tkey 0) "0" (tkey 1) "1" (tkey 2) "1") ; Clears timeouts
                   (tundra/dirty tstore (tkey 0) (tkey 1) (tkey 2)))
-           (Thread/sleep 8000)             ; Wait for replication
+           (Thread/sleep 8000) ; Wait for replication
            (mq/stop tworker)
            (wcar* (tundra/ensure-ks tstore (tkey 0) (tkey 1) (tkey 2))
                   (mapv #(car/ttl (tkey %)) [0 1 2]))))))

+(deftest tundra-api-test-4
+  (test/testing "nnil eviction timeout is applied & extended correctly"
+    (is ((fn [[t0 t1 t2]]
+           (and (= t0 -1)
+             (> t1  0)
+             (> t2  t1)))

-(deftest tundra-api-test-4
-  (testing "nnil eviction timeout is applied & extended correctly"
-    (is (= (fn [[t0 t1 t2]]
-             (and (= t0 -1)
-                  (> t1  0)
-                  (> t2  t1)))
+         (let [_       (clean-up!)
+               tstore  (tundra/tundra-store dstore {:redis-ttl-ms (* 1000 60 60 24)
+                                                    :tqname tqname})
+               tworker (tundra/worker tstore {} {:eoq-backoff-ms 100 :throttle-ms 100
+                                                 :auto-start false})]

-           (let [_       (clean-up!)
-                 tstore  (tundra/tundra-store dstore {:redis-ttl-ms (* 1000 60 60 24)
-                                                      :tqname tqname})
-                 tworker (tundra/worker tstore {} {:eoq-backoff-ms 100 :throttle-ms 100
-                                                   :auto-start false})]
+           (wcar* (car/set (tkey 0) "0") ; Clears timeout
+             (tundra/dirty tstore (tkey 0)))

-             (wcar* (car/set (tkey 0) "0") ; Clears timeout
-                    (tundra/dirty tstore (tkey 0)))
-
-             [(wcar* (car/pttl (tkey 0))) ; `dirty` doesn't set ttl immediately
-              (do (mq/start tworker)
-                  (Thread/sleep 5000) ; Wait for replication (> exp-backoff)
-                  (mq/stop tworker)
-                  (wcar* (car/pttl (tkey 0)))) ; Worker sets ttl after successful put
-              (do (Thread/sleep 1000)
-                  (wcar* (tundra/ensure-ks tstore (tkey 0))
-                         (car/pttl (tkey 0))))])))))
+           [(wcar* (car/pttl (tkey 0))) ; `dirty` doesn't set ttl immediately
+            (do (mq/start tworker)
+                (Thread/sleep 5000) ; Wait for replication (> exp-backoff)
+                (mq/stop tworker)
+                (wcar* (car/pttl (tkey 0)))) ; Worker sets ttl after successful put
+            (do (Thread/sleep 1000)
+                (wcar* (tundra/ensure-ks tstore (tkey 0))
+                       (car/pttl (tkey 0))))])))))

 (comment (clean-up!)
          (mq/queue-status {} mqname))


CLJS-1020: off by one error in REPL source map support

CLJS-1021: correct handling of plain JS files in REPL source map support

--- src/clj/cljs/repl.clj
+++ src/clj/cljs/repl.clj
@@ -151,45 +151,56 @@
      (load-namespace repl-env ns opts))))

 (defn read-source-map [f]
-  (sm/decode (json/read-str (slurp (io/file (str f ".map"))) :key-fn keyword)))
-
-(defn js-src->cljs-src [f]
+  (let [smf (io/file (str f ".map"))]
+    (when (.exists smf)
+      (sm/decode (json/read-str (slurp smf) :key-fn keyword)))))
+
+(defn ^File js-src->cljs-src [f]
   (let [f (io/file f)
         dir (.getParentFile f)
         name (.getName f)]
     (io/file dir (string/replace name ".js" ".cljs"))))

 (defn ns-info [f]
-  (ana/parse-ns (js-src->cljs-src f)))
+  (let [f' (js-src->cljs-src f)]
+    (when (.exists f')
+      (ana/parse-ns f'))))

 (defn mapped-line-and-column [source-map line column]
   (let [default [line column]]
     ;; source maps are 0 indexed for lines
     (if-let [columns (get source-map (dec line))]
       (vec
-        (map
-          ;; source maps are 0 indexed for columns
-          ;; multiple segments may exist at column
-          ;; just take first
-          (first
-            (if-let [mapping (get columns (dec column))]
-              mapping
-              (second (first columns))))
-          [:line :col]))
+        (map inc
+          (map
+           ;; source maps are 0 indexed for columns
+           ;; multiple segments may exist at column
+           ;; just take first
+           (first
+             (if-let [mapping (get columns (dec column))]
+               mapping
+               (second (first columns))))
+           [:line :col])))
       default)))

 (defn print-mapped-stacktrace [stacktrace]
   (let [read-source-map' (memoize read-source-map)
         ns-info' (memoize ns-info)]
     (doseq [{:keys [function file line column] :as frame} stacktrace]
-      (let [[sm {:keys [ns source-file]}] ((juxt read-source-map' ns-info') file)
-            [line' column'] (mapped-line-and-column sm line column)
-            name' (if function
+      (let [[sm {:keys [ns source-file] :as ns-info}] ((juxt read-source-map' ns-info') file)
+            [line' column'] (if ns-info
+                              (mapped-line-and-column sm line column)
+                              [line column])
+            name' (if (and ns-info function)
                     (symbol (name ns) (cljrepl/demunge function))
-                    ns)
-            source-file (string/replace (.getCanonicalFile ^File source-file)
-                          (str (System/getProperty "user.dir") File/separator) "")]
-        (println (str name' " (" source-file ":" line' ":" column' ")"))))))
+                    function)
+            file' (string/replace
+                    (.getCanonicalFile
+                      (if ns-info
+                        source-file
+                        (io/file file)))
+                    (str (System/getProperty "user.dir") File/separator) "")]
+        (println (str name' " (" file' ":" line' ":" column' ")"))))))

 (comment
   (cljsc/build "samples/hello/src"


Better printing of REPL return values. Refs #CLJS-45

--- src/clj/cljs/repl.clj
+++ src/clj/cljs/repl.clj
@@ -82,6 +82,9 @@

            (and (seq? form) ('#{load-file clojure.core/load-file} (first form)))
            (do (load-file repl-env (second form)) (newline) (recur))
+
+           (= form :namespaces)
+           (do (prn @comp/namespaces) (newline) (recur))

            :else
            (let [ret (evaluate-form repl-env
@@ -89,8 +92,11 @@
                                     (if (and (seq? form) (= 'ns (first form)))
                                       form
                                       (list 'cljs.core.pr-str form)))]
-             (try (prn (if (empty? ret) nil (read-string ret)))
-                  (catch Exception e (prn nil)))
+             (try (prn (read-string ret))
+                  (catch Exception e
+                    (if (string? ret)
+                      (println ret)
+                      (prn nil))))
              (recur)))))
       (-tear-down repl-env))))


Remove closed games from state-diff support structure.

--- src/clj/game/main.clj
+++ src/clj/game/main.clj
@@ -78,7 +78,8 @@
       (try
         (case action
           "start" (core/init-game msg)
-          "remove" (swap! game-states dissoc gameid)
+          "remove" (do (swap! game-states dissoc gameid)
+                       (swap! last-states dissoc gameid))
           "do" (handle-do user command state side args)
           "notification" (when state
                            (swap! state update-in [:log] #(conj % {:user "__system__" :text text}))))


Add API for calling Variational Bayesian learning

--- src/clj_stan/core.clj
+++ src/clj_stan/core.clj
@@ -30,7 +30,8 @@

 (defprotocol Model
   (sample [this data-map] [this data-map params])
-  (optimize [this data-map]))
+  (optimize [this data-map])
+  (variational [this data-map algorithm]))

 (defn tmp-dir
   []
@@ -62,6 +63,15 @@
     (let [t (tmp-dir)]
       (r-dump/r-dump (str t "/tmp-data.R") data-map)
       (execute executable "optimize"
+               "data" (str "file=" t "/tmp-data.R")
+               "output" (str "file=" t "/output.csv"))
+      (first (output/read-stan-output (str t "/output.csv")))))
+
+  (variational [this data-map algorithm]
+    (let [t (tmp-dir)]
+      (r-dump/r-dump (str t "/tmp-data.R") data-map)
+      (execute executable "variational"
+               (str "algorithm=" algorithm)
                "data" (str "file=" t "/tmp-data.R")
                "output" (str "file=" t "/output.csv"))
       (first (output/read-stan-output (str t "/output.csv"))))))


Destroy status component on disconn

Destroy status component on disconn

--- src/cljs/ji/main.cljs
+++ src/cljs/ji/main.cljs
@@ -160,6 +160,7 @@
               (do
                 (close! board-state)
                 (close! player-state)
+                (close! status-state)
                 (msg/error "Disconnected from server"))

               (= msg heartbeat-resp)


Cleanup

Cleanup

--- src/cloact/ratom.cljs
+++ src/cloact/ratom.cljs
@@ -15,13 +15,6 @@
 (defn- notify-deref-watcher! [derefable]
   (when-not (or (nil? *ratom-context*))
     (swap! *ratom-context* conj derefable)))
-
-;; Have atoms make a note when they're dereferenced.
-;; (extend-type Atom
-;;   IDeref
-;;   (-deref [this]
-;;     (notify-deref-watcher! this)
-;;     (.-state this)))

 (deftype RAtom [state meta validator watches]
   IEquiv


Optionally get server port from env

Optionally get server port from env

--- src/clj/salava/core/components/server.clj
+++ src/clj/salava/core/components/server.clj
@@ -8,9 +8,10 @@

   (start [this]
     (let [http-config   (get-in config [:config :core :http])
+          port          (or (System/getenv "SALAVA_PORT") (:port http-config))
           ring-handler  (get-in handler [:handler])
-          server        (http-kit/run-server ring-handler http-config)]
-      (println (str "http-kit application server started at " (:host http-config) ":" (:port http-config)))
+          server        (http-kit/run-server ring-handler (assoc http-config :port (Integer. port)))]
+      (println (str "http-kit application server started at " (:host http-config) ":" port))
       (assoc this :http-kit server)))

   (stop [this]


remove methohd that isn't used

remove methohd that isn't used

--- src/cljs/offcourse/models/collection.cljs
+++ src/cljs/offcourse/models/collection.cljs
@@ -45,6 +45,3 @@

 (defn collection-names [collection]
   (keys collection))
-
-(defn get-course-ids [collection]
-  (get-in collection [:collections collection-type collection-name collection-ids]))