remove use of map-function-on-map-vals in favor of simpler (constrain-vals)

--- src/babel/italiano/lexicon.cljc
+++ src/babel/italiano/lexicon.cljc
@@ -2167,56 +2167,46 @@
                       :fail))
                   (fn [val]
                     (get universals (get-in val [:synsem :sem :pred]))))
-
-                 ;; make an intransitive version of every verb which has an
-                 ;; [:sem :obj] path.
+
+                 ;; TODO: refactor this; it's very monolithic currently:
                  intransitivize

                  ;; if verb does specify a [:sem :obj], then fill it in with subcat info.
+                 ;; TODO: refactor this; it's very monolithic currently:
                  transitivize

-                 ;; TODO: use lexiconfn/if-then where possible, like espanol/lexicon does.
-                 ;; reflexive pronouns
-                 (map-function-on-map-vals
-                  (let [agreement
-                        (let [case (atom :acc)
-                              cat (atom :noun)]
-                          {:synsem {:cat cat
-                                    :pronoun true
-                                    :subcat '()
-                                    :reflexive true
-                                    :case case}
-                           :italiano {:cat cat
-                                      :case case}})]
-                    (log/debug (str "reflexive pronoun check key: " key))
-                    (fn [k vals]
-                      (map (fn [val]
-                             (cond (and (= :noun (get-in val [:synsem :cat]))
-                                        (= true (get-in val [:synsem :reflexive]))
-                                        (= true (get-in val [:synsem :pronoun])))
-                                   (unify agreement val)
-                                   true val))
-                           vals))))
+                 (constrain-vals
+                  (fn [val]
+                    (and (= :noun (get-in val [:synsem :cat]))
+                         (= true (get-in val [:synsem :reflexive]))
+                         (= true (get-in val [:synsem :pronoun]))))
+                  (fn [val]
+                    (unify (let [case (atom :acc)
+                                 cat (atom :noun)]
+                             {:synsem {:cat cat
+                                       :pronoun true
+                                       :subcat '()
+                                       :reflexive true
+                                       :case case}
+                              :italiano {:cat cat
+                                         :case case}}))))

                  ;; If a verb is not specifically marked as reflexive, it
                  ;; is {:reflexive false}, to prevent generation of reflexive
                  ;; sentences using nonreflexive verbs.
-                 ;; TODO: move this to within intransitivize and transitivize:
+                 ;; TODO: consider moving this to within intransitivize and transitivize:
                  ;; that is, within babel.italiano.pos, mark certain parts of speech
                  ;; as reflexive=false to accomplish the same thing as we
                  ;; are doing here.
-                 (map-function-on-map-vals
-                  (fn [k vals]
-                    (map (fn [val]
-                           (cond (and (= (get-in val [:synsem :cat])
-                                         :verb)
-                                      (= (get-in val [:synsem :aux] false)
-                                         false)
-                                      (= :none (get-in val [:synsem :sem :reflexive] :none)))
-                                 (unify val {:synsem {:sem {:reflexive false}}})
-                                 true
-                                 val))
-                         vals)))
+                 (constrain-vals
+                  (fn [val]
+                    (and (= (get-in val [:synsem :cat])
+                            :verb)
+                         (= (get-in val [:synsem :aux] false)
+                            false)
+                         (= :none (get-in val [:synsem :sem :reflexive] :none))))
+                  (fn [val]
+                    (unify val {:synsem {:sem {:reflexive false}}})))

                  ;; if object is not specified, then set to :unspec.
                  ;; this prevents translations that may have actual objects - e.g. would allow translations like:


allow require forest :as forest

allow require forest :as forest

--- src/babel/italiano/workbook.clj
+++ src/babel/italiano/workbook.clj
@@ -2,7 +2,7 @@
   (:refer-clojure :exclude [get-in merge resolve find parents])
   (:require
    [babel.engine :as engine]
-   [babel.forest :refer [lightning-bolt]]
+   [babel.forest :as forest]
    [babel.italiano.grammar :refer [small medium np-grammar]]
    [babel.italiano.lexicon :refer :all]
    [babel.italiano.morphology :as morph :refer [fo]]


remove swap! from show-inventory, not quite ready

--- clojure/src/dnd/showScreen.cljs
+++ clojure/src/dnd/showScreen.cljs
@@ -148,23 +148,24 @@
     ;(.moveTo 0 (inc height) "got some text down below\n\n")
     (.moveTo 0 (+ 10 height))))

+;(.moveTo term 0 0
+;(.drawImage term "" #js {:shrink #js {:width 100 :height 150}}))
+
+
 (defn inventory-selected [term character error response]
-  (swap! character assoc :can-move true)
+  (assoc character :can-move true)
   (.moveTo term 0 (inc height)
            (if error
              "oh crap!"
              (str "you stare at " (.-selectedText response)))
            )
-   ;(.moveTo term 0 0
-      ;(.drawImage term "" #js {:shrink #js {:width 100 :height 150}}))
-  )
-
+  character)

 (defn show-inventory [term character]
-  (let [descriptions (->> @character :inventory (map :colorful-description))
+  (let [descriptions (->> character :inventory (map :colorful-description))
         inventory-selected (partial inventory-selected term character)]
     (when-not (empty? descriptions)
-      (swap! character assoc :can-move false)
+      (assoc character :can-move false)
       (.gridMenu term (clj->js descriptions) inventory-selected))
-    ))
+    character))


Remove unneeded comments

Remove unneeded comments

--- src/chrome_extensions/core.cljs
+++ src/chrome_extensions/core.cljs
@@ -1,10 +1,6 @@
 (ns chrome-extensions.core)

 (enable-console-print!)
-
-; (defn command-selector
-;   [command]
-;   (.log js/console command))

 (def constants {:commands {:tab-to-window "print-to-console"}})


removed some seesaw deps

removed some seesaw deps

--- src/temperaments/core.clj
+++ src/temperaments/core.clj
@@ -1,9 +1,9 @@
 (ns temperaments.core
   (:use seesaw.core
         seesaw.graphics
-        seesaw.color
-        seesaw.keystroke
-        seesaw.chooser
+        ;seesaw.color
+        ;seesaw.keystroke
+        ;seesaw.chooser
         clojure.math.numeric-tower)
   (:require [overtone.core :as o]
             [clojure.string :as s])


add util function to retrieve current identity

--- src/clj/dokkaa_builder/auth.clj
+++ src/clj/dokkaa_builder/auth.clj
@@ -1,5 +1,6 @@
 (ns dokkaa-builder.auth
-  (:require [cemerick.friend.credentials :as creds]))
+  (:require [cemerick.friend :as friend]
+   [cemerick.friend.credentials :as creds]))

 ;; these atoms are in-memory databases just for develoment
 (def users (atom {1 {:id 1
@@ -25,3 +26,6 @@
   (get-in
    (filterv #(= (:username (second %)) user-name) @users)
    [0 1]))
+
+(defn current-identity [m]
+  (:current (friend/identity m)))


Fixed merge conflict

Fixed merge conflict

--- src/clj/forma/trends/filter.clj
+++ src/clj/forma/trends/filter.clj
@@ -3,6 +3,37 @@
   (:require  [forma.matrix.utils :as u]
              [incanter.core :as i]
              [incanter.stats :as s]))
+
+;; Remove seasonal component by basic dummy decomposition
+
+(defn dummy-mat
+  "returns an incanter matrix of `n` cycling identity matrices of
+  dimension `freq`, used as the cofactor matrix for deseasonalizing a
+  time series.
+
+  Example:
+    (dummy-mat 23 (count (s/sample-normal 100)))
+    ;; 23: frequency of 16-day MODIS data
+    ;; 12: frequency of 32-day MODIS data"
+  [freq n]
+  (i/matrix (take n (cycle (i/identity-matrix freq)))))
+
+(defn deseasonalize
+  "accepts a timeseries `ts` with frequency `freq` and returns a
+  vector with the seasonal component removed; the returned vector is
+  only the trend component and the idiosyncratic disturbance of the
+  original time series.
+
+  Example:
+    (deseasonalize 23 (s/sample-uniform 200))"
+  [freq ts]
+  (let [x (dummy-mat freq (i/nrow ts))
+        xt (i/trans x)
+        xtx (i/mmult xt x)
+        coefs (i/mmult (i/solve xtx) xt ts)
+        fitted (i/mmult x coefs)]
+    (i/plus (i/minus ts fitted)
+            (s/mean ts))))

 ;; Remove seasonal component by harmonic decomposition

@@ -187,10 +218,6 @@
     (for [x (range start-index (inc end-index))]
       (subvec base-vec 0 x))))

-(defn deseasonalize
-  [series freq]
-  series)
-
 (defn make-clean
   "Interpolate over bad values and remove seasonal component using reliability."
   [freq good-set bad-set spectral-ts reli-ts]
@@ -220,4 +247,5 @@
 (defn shorten-ts
   "Shorten timeseries to length of match timeseries"
   [model-ts ts]
-  [(vec (take (count model-ts) ts))])+  [(vec (take (count model-ts) ts))])
+


Avoid combining statements inside reader conditionals in cljc rules ns

--- src/clj/precept/tuplerules.cljc
+++ src/clj/precept/tuplerules.cljc
@@ -8,10 +8,10 @@
                  [clara.rules :as cr]
                  [clara.macros :as cm]
                  [clara.rules.dsl :as dsl]
-                 [clara.rules.compiler :as com])
+                 [clara.rules.compiler :as com]))

-       :cljs
-       (:require-macros precept.tuplerules)))
+     #?(:cljs (:require [precept.spec.sub :as sub]))
+     #?(:cljs (:require-macros precept.tuplerules)))

 ;; This technique borrowed from Prismatic's schema library (via clara).
 #?(:clj
@@ -134,10 +134,10 @@
              definition  (if properties (rest body) body)
              {:keys [lhs rhs]} (dsl/split-lhs-rhs definition)
              sub-match `[::sub/request (~'= ~'?e ~'(:e this)) (~'= ~kw ~'(:v this))]
+             sub-map (first (drop-while #(not (map? %)) rhs))
              rw-lhs      (conj (macros/rewrite-lhs lhs) sub-match)
-             unwrite-rhs (drop-while #(not (map? %)) rw-lhs)
-             rw-rhs `(do (util/insert! [~'?e ::sub/response ~(first (rest rhs))]))]
-         (core/register-rule "subscription" rw-lhs rw-rhs)
+             rw-rhs `(do (util/insert! [~'?e ::sub/response ~sub-map]))
+             _ (core/register-rule "subscription" rw-lhs rw-rhs)]
          `(def ~(vary-meta name assoc :rule true :doc doc)
             (cond-> ~(dsl/parse-rule* rw-lhs rw-rhs {:group :report} {} (meta &form))
               ~name (assoc :name ~(str (clojure.core/name (ns-name *ns*)) "/" (clojure.core/name name)))


Trying to enclose the task in the card

Trying to enclose the task in the card

--- src/cljs/clojure_rest/core.cljs
+++ src/cljs/clojure_rest/core.cljs
@@ -38,12 +38,6 @@

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

-; TODO - Separate concerns!
-; Model at the end:
-; - A map id to card
-; - Collections for each status: each holding the list of IDs they have
-; - Use a reaction to provide for the filtered list of cards (filtered by text)
-
 (def app-state
   (r/atom
     {:cards {}
@@ -51,7 +45,7 @@
     }))

 (def card-list
-  "FRP style zoom on the card-list to render"
+  "FRP style zoom on the app state to render"
   (reaction
     (filter-by-title (:filter @app-state) (:cards @app-state))
   ))
@@ -61,11 +55,11 @@
   [filter]
   (swap! app-state #(assoc % :filter filter)))

-(defn add-task-to!
-  "Add a new task in the card"
-  [card-id task]
+(defn update-card!
+  "Update a card"
+  [card]
   (swap! app-state
-    #(update-in % [:cards card-id :tasks] conj (api/create-task! task false))
+    #(assoc-in % [:cards (:card-id card)] card)
   ))

 (defn remove-task-from!
@@ -92,7 +86,7 @@
   [:div.checklist
    [:ul
     (for [t tasks]
-      ^{:key (:task-id t)} [render-task card-id t])]
+      [render-task card-id t])]
   ])

 (defn card-side-color
@@ -104,15 +98,16 @@

 (defn render-add-list
   "Render the text field allowing to add new tasks to a card"
-  [card-id]
+  [card]
   [:input.checklist--add-task
    {:type "text"
     :placeholder "Type then hit Enter to add a task"
-    :on-key-press (fn [e]
-                    (when (= "Enter" (.-key e))
-                      (add-task-to! card-id (.. e -target -value))
-                      (set! (.. e -target -value) "")
-                  ))
+    :on-key-press
+    (fn [e]
+      (when (= "Enter" (.-key e))
+        (update-card! (api/add-task card (.. e -target -value)))
+        (set! (.. e -target -value) "")
+        ))
     }])

 (defn render-card
@@ -128,7 +123,7 @@
          [:div.card__details
           (:description card)
           [render-tasks (:card-id card) (:tasks card)]
-          [render-add-list (:card-id card)]
+          [render-add-list card]
          ])
        ])
     ))


Make btn-for-id-name a component generator

--- src/cljs/comic_reader/main.cljs
+++ src/cljs/comic_reader/main.cljs
@@ -30,28 +30,34 @@
    "There's nothing to see here."
    [:a {:href "/#"}]])

-(defn btn-for-id-name [site]
-  (let [{:keys [id name]} site]
-   ^{:key id}
-     [:li
-      [:input {:type "button"
-               :value name
-               :on-click #(.log js/console
-                                (str "You clicked the "
-                                     id
-                                     " button!"))}]]))
+(defn btn-for-id-name [on-click]
+  (fn [data]
+    (let [{:keys [id name]} data]
+      ^{:key id}
+      [:li
+       [:input {:type "button"
+                :value name
+                :on-click (partial on-click data)}]])))

 (defn site-list []
   (let [site-list (rf/subscribe [:site-list])]
     (fn []
       (when-let [site-list @site-list]
-        [:ul (map btn-for-id-name site-list)]))))
+        [:ul (map (btn-for-id-name
+                   #(.log js/console
+                          (str "You clicked the "
+                               (:id %)
+                               " button!"))) site-list)]))))

 (defn comic-list []
   (let [comics-list (rf/subscribe [:comic-list])]
     (fn []
       (when-let [comic-list @comic-list]
-        [:ul (map btn-for-id-name comic-list)]))))
+        [:ul (map (btn-for-id-name
+                   #(.log js/console
+                          (str "You clicked the "
+                               (:id %)
+                               " button!"))) comic-list)]))))

 (defn comic-reader []
   (let [page (rf/subscribe [:page])]


Unbind any current items when going home

--- src/cljs/hacker_agent/core.cljs
+++ src/cljs/hacker_agent/core.cljs
@@ -126,7 +126,8 @@

 (secretary/defroute "/" []
   (swap! app-state assoc
-         :render-view :main))
+         :render-view :main)
+  (base/unbind-item-sync! app-state [:current-item]))

 (secretary/defroute "/items/:id" [id]
   (swap! app-state assoc


finally get json working again

finally get json working again

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

--- plugins/DataBrowser/src/org/micromanager/browser/core.clj
+++ plugins/DataBrowser/src/org/micromanager/browser/core.clj
@@ -38,7 +38,7 @@
                    awt-event persist-window-shape close-window
                    create-alphanumeric-comparator
                    super-location? get-file-parent)]
-        [clojure.data.json :only (read-json write-json)]
+        [clojure.data.json :only (read-json json-str)]
         [org.micromanager.mm :only (load-mm gui)]))

 (def browser (atom nil))
@@ -465,7 +465,7 @@
   (let [data-path (get @collections collection-name)]
     (-> (File. data-path) .getParent (File.) .mkdirs)
     (with-open [pr (PrintWriter. data-path)]
-      (write-json settings pr))))
+      (.print pr (json-str settings)))))

 (defn load-data-and-settings [name]
   (or


Reformat code to make it more readable during a demo

--- src/cljs/htt_schedule/core.cljs
+++ src/cljs/htt_schedule/core.cljs
@@ -4,142 +4,156 @@

 (enable-console-print!)

+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Data structure for our application state
+
 (defonce app-state (atom {:text "ProgsCon Awesomenessness"
-                      :schedule []}))
+                          :schedule []}))
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Om Components

 (defn twitter-handle [cursor component]
   (reify
     om/IRender
     (render [this]
-      (dom/a #js {:href (str "https://twitter.com/" cursor)}
-             (str "@" cursor)))))
-
-;; Add twitter icon button
-;;
-;;
-;;
-
-
-#_(defn talk-detail [cursor component]
-  (reify
-    om/IRender
-    (render [this]
-      (dom/div #js {:className "panel panel-primary"}
-               (dom/div #js {:className "panel-heading"} (:title cursor))
-               (dom/div #js {:className "panel-body"}
-                        (dom/div nil (:description cursor))
-                        (dom/a #js {:href (str "https://twitter.com/" (:twitter-handle cursor))} (str "@" (:twitter-handle cursor))))))))
-
-
-;; Separate out the generation of the twitter handle, updating the cursor to just contain the twitter handle (saving us from extracting it in the twitter handler component)
-(defn talk-detail [cursor component]
-  (reify
-    om/IRender
-    (render [this]
-      (dom/div #js {:className "panel panel-primary"}
-               (dom/div #js {:className "panel-heading"} (:title cursor))
-               (dom/div #js {:className "panel-body"}
-                        (dom/div nil (:description cursor))
-                        #_(dom/div nil
-                                 (om/img #js {:src "https://twitter.com/logo.png"}))
-                        (om/build twitter-handle (:twitter-handle cursor)))))))
-
-#_(dom/div nil
-           (dom/div #js {:style {:color "blue"}} (:title cursor))
-           (dom/div nil (:description cursor))
-           (dom/a #js {:href (str "https://twitter.com/" (:twitter-handle cursor))} (:twitter-handle cursor)))
-
-
-
-;; Add a star button to each talk using bootstrap
-;; <button type="button" class="btn btn-default btn-lg">
-;;  Star
-;; </button>
-
-
-(defn schedule [cursor component]
+      (dom/a
+       #js {:href (str "https://twitter.com/" cursor)}
+       (str "@" cursor)))))
+
+(defn twitter-profile-picture [cursor component]
   (reify
     om/IRender
     (render [this]
       (dom/div nil
-             (for [talk (:schedule cursor)]
-               #_(dom/p nil "Please, Lets go loopy")
-               (om/build talk-detail talk))))))
-
-
-;; talk
-#_{:tile " "
- :description " "
- :twitter-handle ""}
-
-;; schedule
-#_[{:tile " "
-  :description " "
-  :twitter-handle ""}
- {:tile " "
-  :description " "
-  :twitter-handle ""}]
+        (dom/img
+         #js {:src "https://pbs.twimg.com/profile_images/857274701391028224/Ocn-IuEC_400x400.jpg"
+              :width  "50px"
+              :height "50px"})))))
+
+
+(defn talk-detail [cursor component]
+  (reify
+    om/IRender
+    (render [this
+]
+      (dom/div
+       #js {:className "panel panel-primary"}
+
+       (dom/div
+        #js {:className "panel-heading"} (:title cursor))
+
+       (dom/div
+        #js {:className "panel-body"}
+        (dom/div nil (:description cursor))
+
+        (om/build twitter-handle (:twitter-handle cursor))
+        (om/build twitter-profile-picture (:twitter-handle cursor)))))))
+
+
+;; Add a star button to each talk using bootstrap
+;; <button type="button" class="btn btn-default btn-lg">  Star </button>
+
+;; not rendering bootstrap properly
+#_(defn talk-detail-media [cursor component]
+  (reify
+    om/IRender
+    (render [this]
+
+      (dom/div
+       #js {:className "media media-right"}
+
+       (dom/div
+        #js {:className "media-heading"} (:title cursor))
+
+       (dom/a
+        #js {:className "media-body"
+             :href (str "https://twitter.com/" cursor "/profile.png")})
+
+        (dom/div nil (:description cursor))
+
+        (om/build twitter-handle (:twitter-handle cursor))))))
+
+
+(defn schedule [cursor component]
+  (reify
+    om/IRender
+    (render [this]
+      (dom/div nil
+        (for [talk (:schedule cursor)]
+          #_(dom/p nil "Please, Lets go loopy")
+          (om/build talk-detail talk))))))

 (defn add-session [cursor component]
   (reify
-    om/IInitState
+    om/IInitState                       ; component-local state (rather than just input fields)
     (init-state [this]
       {:title ""
        :description ""
        :twitter-handle ""})
     om/IRenderState
-    (render-state [this state]
+    (render-state [this state]          ; component will re-render when state changes
       (dom/div nil
         (dom/h3 nil "Add New Session")
-        (dom/form #js {:className "form-horizontal"}
-                  (dom/input #js {:type "text"
-                                  :className "form-control"
-                                  :value (:title state)
-                                  :onChange (fn [event]
-                                              (om/set-state! component :title
-                                                (-> event .-target .-value)))
-                                  :placeholder "Session Title"})
-                  (dom/textarea #js {:className "form-control"
-                                     :placeholder "Session description"
-                                     :value (:description state)
-                                     :onChange (fn [event]
-                                                 (om/set-state! component :description
-                                                   (-> event .-target .-value)))
-                                     :rows "5"})
-                  (dom/input #js {:type "text"
-                                  :className "form-control"
-                                  :value (:twitter-handle state)
-                                  :onChange (fn [event]
-                                              (om/set-state! component :twitter-handle
-                                                (-> event .-target .-value)))
-                                  :placeholder "Twitter handle"})
-                  (dom/button #js {:className "btn btn-primary"
-                                   :onClick (fn [e]
-                                              (.preventDefault e)
-                                              (om/transact! cursor :schedule
-                                                            (fn [new-talk]
-                                                              ((fnil conj []) new-talk
-                                                               {:title (:title state)
-                                                                :description (:description state)
-                                                                :twitter-handle (:twitter-handle state)}))))}
-                              "Add New Session"))
-               ))))
-
+
+        (dom/form
+         #js {:className "form-horizontal"}
+
+         (dom/input
+          #js {:type "text"
+               :className "form-control"
+               :value (:title state)
+               :onChange
+                 (fn [event]
+                   (om/set-state! component :title
+                     (-> event .-target .-value)))
+               :placeholder "Session Title"})
+
+         (dom/textarea
+          #js {:className "form-control"
+               :placeholder "Session description"
+               :value (:description state)
+               :onChange
+                 (fn [event]
+                   (om/set-state! component :description
+                     (-> event .-target .-value)))
+               :rows "5"})
+
+         (dom/input
+          #js {:type "text"
+               :className "form-control"
+               :value (:twitter-handle state)
+               :onChange
+                 (fn [event]
+                   (om/set-state! component :twitter-handle
+                     (-> event .-target .-value)))
+               :placeholder "Twitter handle"})
+
+         (dom/button
+          #js {:className "btn btn-primary"
+               :onClick
+                 (fn [e]
+                   (.preventDefault e)
+                   (om/transact! cursor :schedule
+                     (fn [new-talk]
+                       ((fnil conj []) new-talk
+                        {:title (:title state)
+                         :description (:description state)
+                         :twitter-handle (:twitter-handle state)}))))}
+          "Add New Session"))))))

 (defn root-component [app owner]
   (reify
     om/IRender
     (render [_]
-      (dom/div #js {:className "container"}  ;; creates javascript {className : "container"}
-               (dom/p #js {:className "jumbotron" :style #js {:fontSize "42px"} } (:text app))
-               (om/build schedule app)
-               (om/build add-session app)))))
-
-
-;; content header options
-;; jumbotron
+      (dom/div
+        #js {:className "container"}  ;; creates javascript {className : "container"}
+        (dom/p #js {:className "jumbotron" :style #js {:fontSize "42px"} } (:text app))
+        (om/build schedule app)
+        (om/build add-session app)))))

 (om/root


fix mixup

fix mixup

--- src/cljs/rksm/sommers/core.cljs
+++ src/cljs/rksm/sommers/core.cljs
@@ -6,7 +6,7 @@
 (if (:nrepl-websocket? config)
   (if-not (weasel-repl/alive?)
     (weasel-repl/connect
-     (str "ws://localhost:" (:nrepl-tcp-port config))
+     (str "ws://localhost:" (:nrepl-websocket-port config))
      :verbose true))
   (default-repl/connect
-    (str "http://localhost:" (:nrepl-websocket-port config) "/repl")))
+    (str "http://localhost:" (:nrepl-tcp-port config) "/repl")))


Whoops

Whoops

--- src/clojure/flambo/function.clj
+++ src/clojure/flambo/function.clj
@@ -63,7 +63,7 @@
          (check-not-nil! ~'this "Nil this func instance")
          (check-not-nil! ~'xs "Nil xs args")
          (let [fn-or-serfn# (.state ~'this)
-               _# (check-not-nil! "Nil fn-or-serfn state")
+               _# (check-not-nil! fn-or-serfn# "Nil fn-or-serfn state")
                f# (if (instance? array-of-bytes-type fn-or-serfn#)
                     (binding [sfn/*deserialize* kryo/deserialize]
                       (deserialize-fn fn-or-serfn#))
@@ -72,7 +72,7 @@
            (apply f# ~'xs)))
        (defn ~(vary-meta wrapper-name assoc :tag clazz)
          [f#]
-         (check-not-nil! "Nil func or serialize func wrapper")
+         (check-not-nil! f# "Nil func or serialize func wrapper")
          (new ~new-class-sym
               (if (serfn? f#)
                 (binding [sfn/*serialize* kryo/serialize]


Fixed bug with cursors in which swap! and reset! do not return the correct new value.

--- src/clojure/freactive/core.cljs
+++ src/clojure/freactive/core.cljs
@@ -256,8 +256,9 @@
 ;(defn- update-cursor-state [cursor ref]
 ;  )

-(defn- cursor-swap! [ref getter setter f]
-  (swap! ref (fn [cur] (setter cur (f (getter cur))))))
+(defn- cursor-swap! [cursor ref getter setter f]
+  (swap! ref (fn [cur] (setter cur (f (getter cur)))))
+  (-raw-deref cursor))

 (deftype ReactiveCursor [ref getter setter dirty state meta watches invalidation-watches lazy sully add-watch-fn]
   Object
@@ -329,14 +330,15 @@
   (-hash [this] (goog/getUid this))

   IReset
-  (-reset! [_ new-value]
-    (swap! ref (fn [cur] (setter cur new-value))))
+  (-reset! [this new-value]
+    (swap! ref (fn [cur] (setter cur new-value)))
+    (-raw-deref this))

   ISwap
-  (-swap! [_ f] (cursor-swap! ref getter setter f))
-  (-swap! [_ f x] (cursor-swap! ref getter setter #(f % x)))
-  (-swap! [_ f x y] (cursor-swap! ref getter setter #(f % x y)))
-  (-swap! [_ f x y more] (cursor-swap! ref getter setter #(apply f % x y more))))
+  (-swap! [this f] (cursor-swap! this ref getter setter f))
+  (-swap! [this f x] (cursor-swap! this ref getter setter #(f % x)))
+  (-swap! [this f x y] (cursor-swap! this ref getter setter #(f % x y)))
+  (-swap! [this f x y more] (cursor-swap! this ref getter setter #(apply f %  x y  more))))

 (defn cursor* [ref korks-or-getter setter lazy]
   (let [ks (cond
@@ -372,5 +374,4 @@

 (defn debug-rx* [the-rx capture-callback invalidation-callback]
   (add-invalidation-watch the-rx capture-callback invalidation-callback)
-  (add-invalidation-watch the-rx capture-callback invalidation-callback)
-  )
+  (add-invalidation-watch the-rx capture-callback invalidation-callback))


Handle a few more built-in writable types.

--- src/clojure/parkour/wrapper.clj
+++ src/clojure/parkour/wrapper.clj
@@ -4,8 +4,9 @@
             [parkour.util :refer [returning]])
   (:import [clojure.lang IPersistentVector]
            [org.apache.hadoop.io
-             NullWritable Text Writable IntWritable LongWritable
-             DoubleWritable FloatWritable]
+            , NullWritable Text Writable IntWritable LongWritable
+            , DoubleWritable FloatWritable VIntWritable VLongWritable
+            , BytesWritable BooleanWritable]
            [org.apache.hadoop.util ReflectionUtils]))

 (defprotocol Wrapper
@@ -77,13 +78,21 @@
   Text
   (unwrap [wobj] (.toString wobj))
   (rewrap [wobj obj]
-    (returning wobj (.set wobj ^String obj))))
+    (doto wobj (.set ^String obj)))
+
+  BytesWritable
+  (unwrap [wobj] (.get wobj))
+  (rewrap [wobj ^bytes obj]
+    (doto wobj (.set obj 0 (alength obj)))))

 (auto-wrapper
   IntWritable
   LongWritable
+  VIntWritable
+  VLongWritable
+  FloatWritable
   DoubleWritable
-  FloatWritable)
+  BooleanWritable)

 (def ^:no-doc ^:internal new-instance* nil)
 (defmulti ^:no-doc ^:internal new-instance*


refactor core/append to inject transform & enforce string IDs, update/simplify callsites, remove obsolete opts arg from material-null, bugfix filenames & meshname for area-light, ply-mesh, stl-mesh, shape-disk

--- src/thi/ng/luxor/core.clj
+++ src/thi/ng/luxor/core.clj
@@ -136,12 +136,36 @@
              (str (serialize-lxv scene* base-path)))
          lxs))))

+(defn- make-transform-matrix
+  [{:keys [scale rx ry rz axis theta translate] :or {rx 0 ry 0 rz 0} :as tx}]
+  (let [mat (if translate
+              (g/translate M44 (vec3 translate))
+              M44)
+        mat (if axis
+              (g/rotate-around-axis mat axis theta)
+              (if (some (complement zero?) [rx ry rz])
+                (-> mat
+                    (g/rotate-x (->radians rx))
+                    (g/rotate-y (->radians ry))
+                    (g/rotate-z (->radians rz)))
+                mat))
+        mat (if scale (g/scale mat scale) mat)]
+    (vals (g/transpose mat))))
+
+(defn- transform-common
+  [scene {:keys [matrix] :as tx}]
+  {:__transform (if matrix matrix (make-transform-matrix tx))})
+
 (defn- append
   ([scene group id opts]
      (append scene group id opts false))
-  ([scene group id opts singleton?]
+  ([scene group id {tx :__transform :as opts} singleton?]
      (-> (if singleton? (dissoc scene group) scene)
-         (assoc-in [group id] (or opts {})))))
+         (assoc-in
+          [group (name id)]
+          (merge
+           (when tx (transform-common scene tx))
+           (dissoc opts :__transform))))))

 (defn- append*
   [scene group xs]
@@ -170,18 +194,16 @@
    :__exterior exterior})

 (defn material-null
-  [scene id {:as opts}]
+  [scene id]
   {:pre [(kw-or-str? id)]}
   (append
-   scene :materials (name id)
-   (merge
-    (material-common opts)
-    {:type [:string "null"]})))
+   scene :materials id
+   {:type [:string "null"]}))

 (defn material-mix
   [scene id m1 m2 blend]
   (append
-   scene :materials (name id)
+   scene :materials id
    {:type [:string "mix"]
     :namedmaterial1 [:string (name m1)]
     :namedmaterial2 [:string (name m2)]
@@ -195,7 +217,7 @@
   [scene id alpha]
   (if (< alpha 1.0)
     (material-mix
-     scene (name id) "__hidden__" (material-id id alpha) alpha)
+     scene id "__hidden__" (material-id id alpha) alpha)
     scene))

 (defn material-matte
@@ -248,7 +270,7 @@
          (color? absorb) (optional color? absorb-hsb)
          (number? abs-scale) (number? abs-depth)]}
   (append
-   scene :volumes (name id)
+   scene :volumes id
    {:__type type
     :fresnel [:float (if (keyword ior) (presets/ior-presets ior) ior)]
     :absorption [:log-color [(if absorb-hsb (col/hsb->rgb absorb-hsb) absorb)
@@ -257,10 +279,10 @@
 (defn volume-integrator
   [scene id]
   {:pre [(conf/volume-integrators id)]}
-  (append-singleton scene :volume-integrator (name id) {}))
+  (append-singleton scene :volume-integrator id {}))

 (defn renderer-slg
-  [scene {:keys [cpu? gpu? ]}]
+  [scene {:keys [cpu? gpu?]}]
   (append-singleton
    scene :renderer "slg"
    {:config
@@ -470,29 +492,9 @@
               :default    (assoc opts :autofocus [:bool true]))]
     (append-singleton scene :camera type opts)))

-(defn- make-transform-matrix
-  [{:keys [scale rx ry rz axis theta translate] :or {rx 0 ry 0 rz 0} :as tx}]
-  (let [mat (if translate
-              (g/translate M44 (vec3 translate))
-              M44)
-        mat (if axis
-              (g/rotate-around-axis mat axis theta)
-              (if (some (complement zero?) [rx ry rz])
-                (-> mat
-                    (g/rotate-x (->radians rx))
-                    (g/rotate-y (->radians ry))
-                    (g/rotate-z (->radians rz)))
-                mat))
-        mat (if scale (g/scale mat scale) mat)]
-    (vals (g/transpose mat))))
-
-(defn- transform-common
-  [scene {:keys [matrix] :as tx}]
-  {:__transform (if matrix matrix (make-transform-matrix tx))})
-
 (defn light-group
   [scene id {:keys [gain] :or {gain 1.0}}]
-  (append scene :light-groups (name id) {:__gain gain}))
+  (append scene :light-groups id {:__gain gain}))

 (defn light-groups
   [scene groups]
@@ -519,18 +521,17 @@
                 (pl/plane-with-p (g/vec3 (or p [0 0 0])) (g/vec3 (or n [0 0 -1])))
                 (if (sequential? size)
                   {:width (first size) :height (second size)}
-                  {:size size})))
-        id (name id)]
+                  {:size size})))]
     (append
      scene :lights id
      (merge
-      (when tx (transform-common scene tx))
       (light-common scene opts)
-      {:__type :area-light
+      {:__transform tx
+       :__type :area-light
        :__shape [(conf/mesh-types mesh-type)
                  {:__mesh mesh
                   :__export-path export-path
-                  :__basename (str "light-" id)}]
+                  :__basename (str "light-" (name id))}]
        :nsamples [:int samples]}))))

 (defn spot-light
@@ -538,11 +539,11 @@
              :or {cone-angle 30 cone-delta 5 from [0 0 1] to [0 0 0]}
              :as opts}]
   (append
-   scene :lights (name id)
+   scene :lights id
    (merge
-    (when tx (transform-common scene tx))
     (light-common scene opts)
-    {:__type :spot-light
+    {:__transform tx
+     :__type :spot-light
      :from [:point-vec [from]]
      :to [:point-vec [to]]
      :coneangle [:float (->degrees cone-angle)]
@@ -565,43 +566,40 @@
   [scene id {:keys [z radius inner-radius phi tx material]
              :or {z 0 radius 1 inner-radius 0 phi 360}}]
   (append
-   scene :geometry (name id)
-   (merge
-    (when tx (transform-common scene tx))
-    {:__type :disk
-     :__material material
-     :name [:string id]
-     :height [:float z]
-     :radius [:float radius]
-     :innerradius [:float inner-radius]
-     :phimax [:float phi]})))
+   scene :geometry id
+   {:__transform tx
+    :__type :disk
+    :__material material
+    :name [:string (name id)]
+    :height [:float z]
+    :radius [:float radius]
+    :innerradius [:float inner-radius]
+    :phimax [:float phi]}))

 (defn ply-mesh
   [scene id {:keys [mesh path export-path tx material smooth]}]
   (append
-   scene :geometry (name id)
-   (merge
-    (when tx (transform-common scene tx))
-    {:__type :plymesh
-     :__material material
-     :__mesh mesh
-     :__export-path (or export-path path)
-     :name [:string id]
-     :filename [:string (or path (str (name id) ".ply"))]
-     :smooth [:bool smooth]})))
+   scene :geometry id
+   {:__transform tx
+    :__type :plymesh
+    :__material material
+    :__mesh mesh
+    :__export-path (or export-path path)
+    :name [:string (name id)]
+    :filename [:string (or path (str (name id) ".ply"))]
+    :smooth [:bool smooth]}))

 (defn stl-mesh
   [scene id {:keys [mesh path export-path tx material]}]
   (append
-   scene :geometry (name id)
-   (merge
-    (when tx (transform-common scene tx))
-    {:__type :stlmesh
-     :__material material
-     :__mesh mesh
-     :__export-path (or export-path path)
-     :name [:string id]
-     :filename [:string (or path (str (name id) ".stl"))]})))
+   scene :geometry id
+   {:__transform tx
+    :__type :stlmesh
+    :__material material
+    :__mesh mesh
+    :__export-path (or export-path path)
+    :name [:string (name id)]
+    :filename [:string (or path (str (name id) ".stl"))]}))

 (defn lux-scene
   []
@@ -614,4 +612,4 @@
       (accelerator-qbvh {})
       (film {})
       (light-group "default" {})
-      (material-null "__hidden__" {})))
+      (material-null "__hidden__")))


better looking invoices

better looking invoices

--- src-cljs/frontend/components/plan.cljs
+++ src-cljs/frontend/components/plan.cljs
@@ -13,6 +13,8 @@
             [frontend.utils :as utils]
             [goog.dom]
             [goog.dom.Range]
+            [goog.string :as gstring]
+            [goog.string.format]
             [om.core :as om]
             [om.dom :as dom]
             [taoensso.sente])
@@ -119,6 +121,11 @@
             (for [{:keys [cust instant added?]} (reverse history)]
               [:div (str cust (if added? " was marked active at " " was marked inactive at ") instant)])]))))))

+(defn format-stripe-cents [cents]
+  (let [pennies (mod cents 100)
+        dollars (/ (- cents pennies) 100)]
+    (gstring/format "$%d.%02d" dollars pennies)))
+
 (defn invoice-component [{:keys [invoice-id]} owner]
   (reify
     om/IInitState
@@ -137,23 +144,37 @@
                                   (om/get-state owner :listener-key)))
     om/IRender
     (render [_]
-      (let [invoice (utils/inspect (d/touch (d/entity @(om/get-shared owner :team-db) invoice-id)))]
-        (html
-         [:table
-          [:tbody
-           (for [[k v] invoice]
-             [:tr
-              [:td (str k)]
-              [:td (str v)]])]])))))
-
-(defn invoices [{:keys [plan team-uuid]} owner]
-  (reify
-    om/IRender
-    (render [_]
-      (html
-       [:div
-        (for [invoice (:plan/invoices plan)]
-          (om/build invoice-component {:invoice-id (:db/id invoice)} {:key :invoice-id}))]))))
+      (let [invoice (d/touch (d/entity @(om/get-shared owner :team-db) invoice-id))]
+        (html
+         [:div.invoice {:style {:margin-bottom "1em"}}
+          [:div.invoice-number "Invoice #" (:db/id invoice)]
+          [:div.invoice-date (datetime/medium-consistent-date (:invoice/date invoice))]
+          [:div.invoice-description (:invoice/description invoice)]
+          [:div.invoice-discount
+           (when (= :coupon/product-hunt (:discount/coupon invoice))
+             "Discount: 50% off for first 6 months")]
+          [:div.invoice-total
+           "Total: " (format-stripe-cents (:invoice/total invoice))]
+          [:div.invoice-status
+           "Status: "
+           (cond (:invoice/paid? invoice)
+                 "paid"
+
+                 (:invoice/next-payment-attempt invoice)
+                 (str "will charge on " (datetime/medium-consistent-date (:invoice/next-payment-attempt invoice)))
+                 :else "unpaid")]])))))
+
+(defn invoices [{:keys [plan team-uuid]} owner & {:keys [limit] :as opts}]
+  (reify
+    om/IRender
+    (render [_]
+      (let [sorted-invoices (reverse (sort-by :invoice/date (:plan/invoices plan)))]
+        (html
+         [:div
+          (for [invoice (if limit
+                          (take limit sorted-invoices)
+                          sorted-invoices)]
+            (om/build invoice-component {:invoice-id (:db/id invoice)} {:key :invoice-id}))])))))

 (defn paid-info [{:keys [plan team-uuid]} owner]
   (reify


update cider

update cider

--- .lein/profiles.clj
+++ .lein/profiles.clj
@@ -6,9 +6,9 @@
         }
  :woot {:plugins [[lein-ancient "0.6.7"]]}
  :cider-repl {:dependencies [[org.clojure/tools.nrepl "0.2.12"]]
-              :plugins [[cider/cider-nrepl "0.12.0"]]}
+              :plugins [[cider/cider-nrepl "0.13.0"]]}
  :repl {:dependencies [[org.clojure/tools.nrepl "0.2.12"]]
-        :plugins [[cider/cider-nrepl "0.12.0"]]}
+        :plugins [[cider/cider-nrepl "0.13.0"]]}
  :mavbozo {
            ;;:repl-options {:prompt (fn [ns] (str "[" *ns* "]" \newline "=> "))}
            :repl-options { ; for nREPL dev you really need to limit output
@@ -16,7 +16,7 @@
                           ;;:nrepl-middleware [cemerick.piggieback/wrap-cljs-repl]

                           }
-               :dependencies [[spyscope "0.1.6-SNAPSHOT"]
+               :dependencies [;;[spyscope "0.1.6-SNAPSHOT"]
                               [com.cemerick/piggieback "0.2.1"]
                           [org.clojure/tools.namespace "0.2.10"]
                           ;;[clojure-complete "0.2.3"]
@@ -24,7 +24,7 @@
                           ;;[io.aviso/pretty "0.1.8"]
                           ;;[im.chit/vinyasa "0.4.7"]
                           [figwheel-sidecar "0.5.3-1"]]
-           :plugins [[cider/cider-nrepl "0.12.0"]
+           :plugins [[cider/cider-nrepl "0.13.0"]
                      [jonase/eastwood "0.2.3"]
                      [lein-ns-dep-graph "0.1.0-SNAPSHOT"]]
            :injections [(require '[fipp.edn :refer (pprint) :rename {pprint fipp}])]


use Cambium instead of SLF4j MDC for basic MDC test

--- json-bundle/test/logback_bundle/json/basic_layout_test.clj
+++ json-bundle/test/logback_bundle/json/basic_layout_test.clj
@@ -10,19 +10,15 @@
 (ns logback-bundle.json.basic-layout-test
   (:require
     [clojure.test :refer :all]
-    [cambium.core :as log])
-  (:import
-    [org.slf4j MDC]))
+    [cambium.core :as log]))

 (deftest a-test
   (testing "Simple test"
-    (MDC/put "foo" "bar")
-    (MDC/put "baz" "qux")
-    (log/info "hello")))
+    (log/info {"foo" "bar"
+               "baz" "qux"} "hello")))

 (deftest e-test
   (testing "Exception"
-    (MDC/put "x" "y")
-    (log/error {} (RuntimeException. "Exception happened") "Testing exception")))
+    (log/error {"x" "y"} (RuntimeException. "Exception happened") "Testing exception")))


une proposition de solution à l'exercice ETL de exercism dans la track Clojure

--- exercism/clojure/etl/src/etl.clj
+++ exercism/clojure/etl/src/etl.clj
@@ -1,5 +1,8 @@
 (ns etl)

-(defn transform [source] ;; <- arglist goes here
-  ;; your code goes here
-)
+(defn keys-list-to-hash [value keys-list]
+  (map #(hash-map % value) keys-list))
+
+(defn transform [source]
+  (reduce merge {} (flatten (map #(etl/keys-list-to-hash % (map clojure.string/lower-case (get source %))) (keys source))))
+  )


Reimplement «frequent-closed-itemsets» in terms of «intents»

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

--- src/conexp/fca/implications.clj
+++ src/conexp/fca/implications.clj
@@ -404,11 +404,10 @@
   minimal support."
   [context minsupp]
   (let [mincount (* minsupp (count (objects context)))]
-    (all-closed-sets-in-family (fn [intent]
-                                 (>= (count (attribute-derivation context intent))
-                                     mincount))
-                               (attributes context)
-                               (partial context-attribute-closure context))))
+    (intents context
+             (fn [intent]
+               (>= (count (attribute-derivation context intent))
+                   mincount)))))

 (defn luxenburger-basis
   "Computes the luxenburger-basis for context with minimal support minsupp and minimal


network plugin preload FE

network plugin preload FE

#65

--- src/cljs/swarmpit/component/network/create.cljs
+++ src/cljs/swarmpit/component/network/create.cljs
@@ -13,6 +13,15 @@

 (def cursor [:page :network :form])

+(defonce network-plugins (atom []))
+
+(defn network-plugin-handler
+  []
+  (handler/get
+    (routes/path-for-backend :plugin-network)
+    {:on-success (fn [response]
+                   (reset! network-plugins response))}))
+
 (defn- form-name [value]
   (comp/form-comp
     "NAME"
@@ -24,17 +33,18 @@
        :onChange (fn [_ v]
                    (state/update-value [:networkName] v cursor))})))

-(defn- form-driver [value]
+(defn- form-driver [value plugins]
   (comp/form-comp
     "DRIVER"
     (comp/select-field
       {:value    value
        :onChange (fn [_ _ v]
                    (state/update-value [:driver] v cursor))}
-      (comp/menu-item
-        {:key         "fdi1"
-         :value       "overlay"
-         :primaryText "overlay"}))))
+      (->> plugins
+           (map #(comp/menu-item
+                   {:key         %
+                    :value       %
+                    :primaryText %}))))))

 (defn- form-internal [value]
   (comp/form-comp
@@ -100,7 +110,8 @@

 (rum/defc form < rum/reactive
                  init-state-mixin []
-  (let [{:keys [name
+  (let [plugins (rum/react network-plugins)
+        {:keys [name
                 driver
                 internal
                 ipam
@@ -126,7 +137,7 @@
          {:onValid   #(state/update-value [:isValid] true cursor)
           :onInvalid #(state/update-value [:isValid] false cursor)}
          (form-name name)
-         (form-driver driver)
+         (form-driver driver plugins)
          (form-internal internal))]
       [:div.form-view-group
        (comp/form-section "IP address management")


- remove multiple audio sources, as that was not really working

--- src/app/cljs/one/sample/animation.cljs
+++ src/app/cljs/one/sample/animation.cljs
@@ -910,10 +910,14 @@
      (fn [director]
        (log/info logger " Images loaded. Creating scene.")
        (doto director
-         (.addAudio "chime" ["sounds/22267__zeuss__the-chime.ogg" "sounds/22267__zeuss__the-chime.mp3"])
-         (.addAudio "doppp" ["sounds/8001__cfork__cf-fx-doppp-01.ogg" "sounds/8001__cfork__cf-fx-doppp-01.wav"])
-         (.addAudio "flopp" ["sounds/8006__cfork__cf-fx-flopp-03-dry.ogg" "sounds/8006__cfork__cf-fx-flopp-03-dry.wav"])
-         (.addAudio "munching" ["sounds/27877__inequation__munching.ogg" "sounds/27877__inequation__munching.wav"])
+         (.addAudio "chime" "sounds/22267__zeuss__the-chime.ogg" ;; "sounds/22267__zeuss__the-chime.mp3"
+                    )
+         (.addAudio "doppp" "sounds/8001__cfork__cf-fx-doppp-01.ogg" ;; "sounds/8001__cfork__cf-fx-doppp-01.wav"
+                    )
+         (.addAudio "flopp" "sounds/8006__cfork__cf-fx-flopp-03-dry.ogg" ;; "sounds/8006__cfork__cf-fx-flopp-03-dry.wav"
+                    )
+         (.addAudio "munching" "sounds/27877__inequation__munching.ogg" ;; "sounds/27877__inequation__munching.wav"
+                    )
          (.addAudio "song" "sounds/448614_Happiness_Alone.ogg"))
        (let [scene (. director (createScene))
              background (doto (CAAT/Actor.)


error handling in updater

error handling in updater

--- src/cljs/meo/electron/main/update.cljs
+++ src/cljs/meo/electron/main/update.cljs
@@ -35,7 +35,9 @@
                           (info "Update downloading" (str info))
                           (put-fn [:update/status {:status :update/downloading
                                                    :info   info}])))
-          error (fn [ev] (error "ERROR in auto-updater" ev))]
+          error (fn [ev]
+                  (error "in auto-updater" ev)
+                  (put-fn [:update/status {:status :update/not-available}]))]
       (info "Starting UPDATE Component")
       (aset autoUpdater "autoDownload" false)
       (aset autoUpdater "logger" electron-log)


Delete println.

Delete println.

--- src/cljs/mine_canary/console/core.cljs
+++ src/cljs/mine_canary/console/core.cljs
@@ -26,7 +26,6 @@
    [_]
     (consume (:consumer app)
       (fn [msg]
-        (println msg)
         (om/transact! app :alerts #(conj % msg)))))

   (render


Overrode old solution with new.

Overrode old solution with new.

--- src/main/cljc/clojure_club/sudoku/mbastian.cljc
+++ src/main/cljc/clojure_club/sudoku/mbastian.cljc
@@ -1,6 +1,5 @@
 (ns clojure-club.sudoku.mbastian)

-;Copied from https://github.com/markbastian/sudoku/blob/master/src/cljc/sudoku/rules.cljc
 (def valid-values (apply hash-set (range 1 10)))

 (defonce all-cells (for [i (range 9) j (range 9)] [i j]))
@@ -15,26 +14,27 @@
                           [a b])))]
            (zipmap all-cells (map #(disj (reduce into #{} (cells %)) %) all-cells))))

-(defn constraints [[board unsolved-cells]]
-  (letfn [(solved [cell] (apply hash-set (map #(valid-values (get-in board %)) (neighbors cell))))]
-    (->> unsolved-cells
-         (map (fn [c] [c (remove (solved c) valid-values)]))
-         (group-by (comp count second)))))
+(defn set-cell [board cell value]
+  (letfn [(safe-set [b c] (cond-> b (set? (get-in b c)) (update-in c disj value)))]
+    (-> (reduce safe-set board (neighbors cell)) (assoc-in cell value))))

-(defn lock-cells [[board unsolved-cells] [cell values]]
-  (map (fn [value] [(assoc-in board cell value) (disj unsolved-cells cell)]) values))
+(defn most-constrained [board]
+  (->> all-cells
+       (filter #(set? (get-in board %)))
+       (apply min-key #(count (get-in board %)))))

-(defn unknowns [board]
-  (apply hash-set (remove #(valid-values (get-in board %)) all-cells)))
+(defn initialize [problem]
+  (reduce
+    (fn [board cell]
+      (if-let [v (valid-values (get-in problem cell))]
+        (set-cell board cell v)
+        board))
+    (vec (repeat 9 (vec (repeat 9 valid-values))))
+    all-cells))

-(defn solve [initial-board]
-  (loop [[[board unsolved-cells :as f] & r] [[initial-board (unknowns initial-board)]]]
-    (if-not (empty? unsolved-cells)
-      (let [c (constraints f)]
-        (if (c 0)
-          (recur r)
-          (recur (into r (lock-cells f (first (some c (range 1 10))))))))
-      board)))
+(defn solve-step [board]
+  (let [best-cell (most-constrained board)]
+    (for [v (get-in board best-cell)] (set-cell board best-cell v))))

 (def hard
   '[[_ _ _ _ _ _ _ 1 2]
@@ -47,24 +47,14 @@
     [_ _ _ 6 2 _ _ _ _]
     [_ _ _ 1 _ _ _ _ _]])

-;(def hard
-;  '[[1 _ _ _ _ _ _ 1 2]
-;    [_ _ 8 _ 3 _ _ _ _]
-;    [_ _ _ _ _ _ _ 4 _]
-;    [1 2 _ 5 _ _ _ _ _]
-;    [_ _ _ _ _ 4 7 _ _]
-;    [_ 6 _ _ _ _ _ _ _]
-;    [5 _ 7 _ _ 9 3 _ _]
-;    [_ _ _ 6 2 _ _ _ _]
-;    [_ _ _ 1 _ _ _ _ _]])
+(defn solve [board]
+  (loop [[f & r] [(initialize board)]]
+    (cond
+      (every? #(every? integer? %) f) f
+      (nil? f) f
+      :default (recur (into r (solve-step f))))))

-(let [[[board unsolved-cells :as f] & r] [[hard (unknowns hard)]]]
-  (first (some (constraints f) (range)))
-  #_(if-not (empty? unsolved-cells)
-      (into r (lock-cells f (first (some (constraints f) (range)))))
-      board))
-
-(time (solve hard))
+;(solve hard)

 ;;;;;;;;;;;;;;;
 (defn valid-cell? [board cell]
@@ -78,4 +68,4 @@
 (defn valid-board? [board]
   (and
     (every? (partial get-in board) all-cells)
-    (empty? (bad-cells board))))+    (empty? (bad-cells board))))


Removing chrome tabs from the list of tabs displayed

We don't really care that much about time spend on an extension.

--- src/app/booklet/core.cljs
+++ src/app/booklet/core.cljs
@@ -183,7 +183,7 @@

 (defn div-timetrack []
   (let [url-times  (subscribe [:data :url-times])
-        url-values (reaction (vals @url-times))
+        url-values (reaction (filter-tabs (vals @url-times)))
         to-list    (reaction (sort-by #(* -1 (:time %)) @url-values))]
     (fn []
       [:div


Add namespace metadata to example test suite

--- src/examples/clojure/suite1.clj
+++ src/examples/clojure/suite1.clj
@@ -30,4 +30,6 @@
   addition subtraction)

 (defsuite all-tests []
-  numbers arithmetic)+  numbers arithmetic)
+
+(alter-meta! *ns* assoc :test all-tests)


only public issues are shown

only public issues are shown

--- src/gh_waiting_room/service.clj
+++ src/gh_waiting_room/service.clj
@@ -32,7 +32,8 @@

 (defn- issue-filter
   [issue]
-  (and (re-find issue-url-regex (str (:html_url issue)))
+  (and (not (get-in issue [:repository :private]))
+   (re-find issue-url-regex (str (:html_url issue)))
        (if gh-hide-labels
          (not (some
                (set gh-hide-labels)


require $GITHUB_AUTH and $GITHUB_USER, introduce optional $GITHUB_ISSUE_REGEX

--- src/gh_waiting_room/service.clj
+++ src/gh_waiting_room/service.clj
@@ -10,26 +10,33 @@

 (def db (atom {}))

-(defn- get-auth
-  []
-  (or (System/getenv "GITHUB_AUTH")
-      (throw (ex-info "Set $GITHUB_AUTH to fetch github issues" {}))))
+(def gh-auth
+  {:auth (or (System/getenv "GITHUB_AUTH")
+             (throw (ex-info "Set $GITHUB_AUTH to basic auth in order fetch github issues." {})))})
+
+(def gh-user
+  (or (System/getenv "GITHUB_USER")
+      (throw (ex-info "Set $GITHUB_USER to the user who owns the issues." {}))))
+
+(def issue-url-regex (re-pattern
+                      (or (System/getenv "GITHUB_ISSUE_REGEX")
+                          (str "github.com/" gh-user))))

 (defn- api-options
   []
-  {:filter "all" :all-pages true :auth (get-auth)})
+  (merge {:filter "all" :all-pages true} gh-auth))

 ;; TODO: make this customizable
 (defn- issue-filter
   [issue]
-  (and (re-find #"github.com/cldwalker" (str (:html_url issue)))
+  (and (re-find issue-url-regex (str (:html_url issue)))
        (= [] (:labels issue))))

 (defn- fetch-gh-issues
   []
   (swap! db assoc :issues (my-issues (api-options))))

-(defn ->issue [issue]
+(defn- ->issue [issue]
   {:name (str
           (or (re-find #"[^/]+/[^/]+(?=/issues/\d+)" (:html_url issue))
               (throw (ex-info "Failed to parse name from an issue" {:issue issue})))


envelope is a more accurate term, as it shapes input rather than generating it.

--- src/klangmeister/synthesis.cljs
+++ src/klangmeister/synthesis.cljs
@@ -20,8 +20,8 @@

 ; Envelopes

-(defn line
-  "Build a line out of [dx y] coordinates, starting at [0 0]."
+(defn envelope
+  "Build an envelope out of [dx y] coordinates, starting at [0 0]."
   [& corners]
   (fn [context at duration]
     (let [node (.createGain context)
@@ -36,7 +36,7 @@
       node)))

 (defn adshr [attack decay sustain hold release]
-  (line [attack 1.0] [decay sustain] [hold sustain] [release 0]))
+  (envelope [attack 1.0] [decay sustain] [hold sustain] [release 0]))

 (defn adsr [attack decay sustain release]
   (fn [context at duration]
@@ -46,7 +46,7 @@
       (ugen context at duration))))

 (defn percussive [attack decay]
-  (line [attack 1.0] [decay 0.0]))
+  (envelope [attack 1.0] [decay 0.0]))

 ; Combinators


being more defensive: don't try to write a history-file if no home-dir is defined

--- src/lambdacd/pipeline_state.clj
+++ src/lambdacd/pipeline_state.clj
@@ -17,8 +17,9 @@
   (spit file (json/write-str data)))

 (defn- write-state-to-disk [home-dir new-state]
-  (let [file (str home-dir "/" "history.json")]
-    (write-as-json file new-state)))
+  (if home-dir
+  (let [path (str home-dir "/" "history.json")]
+    (write-as-json path new-state))))

 (defn update [{step-id :step-id state :_pipeline-state build :build-number {:keys [home-dir]} :config } step-result]
   (if (not (nil? state)) ; convenience for tests: if no state exists we just do nothing


print exception stacktrace on DEBUG level.

--- src/leiningen/ancient/utils.clj
+++ src/leiningen/ancient/utils.clj
@@ -4,7 +4,9 @@
              [cli :as cli]
              [collect :as collect]
              [verbose :refer :all]]
-            [jansi-clj.core :as color]))
+            [jansi-clj.core :as color]
+            [clojure.string :as string])
+  (:import [java.io StringWriter PrintWriter]))

 ;; ## Reporting

@@ -35,12 +37,20 @@
            ~@body)))
      (catch Throwable t# t#)))

+(defn throwable->stacktrace
+  [^Throwable t]
+  (with-open [sw (StringWriter.)]
+    (with-open [pw (PrintWriter. sw)]
+      (.printStackTrace t pw)
+      (str sw))))
+
 (defmacro call-with-throwables
   "Run the given body but log all Throwables."
   [& body]
   `(let [v# (with-success [r# (do ~@body)] r#)]
      (when (throwable? v#)
-       (errorf "%s" (pr-str v#)))
+       (errorf "%s" (pr-str v#))
+       (debugf "%s" (throwable->stacktrace v#)))
      v#))

 (defn call-file


cleanup window appearance

cleanup window appearance

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

--- plugins/SlideExplorer2/src/slide_explorer/setup.clj
+++ plugins/SlideExplorer2/src/slide_explorer/setup.clj
@@ -13,7 +13,7 @@
     (.setLayout (FlowLayout. FlowLayout/CENTER))))

 (def cheat-sheet-text
-"Slide Explorer controls:
+" Slide Explorer controls:

   Mouse drag: Pan
   +/-: Zoom in/out
@@ -24,11 +24,11 @@
   Esc: Exit full screen mode
   1: Hide or show 1x view

-For live data sets:
+ For new data sets:

   Channels and z-stack settings are
-  borrowed from the multi-dimensional acquisition
-  window.
+  borrowed from the multi-dimensional
+  acquisition window.

   Ctrl/Cmd + Click: Add/remove positions
   Double-click: Navigate to location
@@ -51,7 +51,7 @@
       (.add (cheat-sheet)))
     (doto frame
       (.setResizable false)
-      (controls/show-window-center 400 450 gui-window))
+      (controls/show-window-center 400 500 gui-window))
     frame))

 (defn show-frame [gui-window]


fix type error

fix type error

--- src/blog_clj/redis_io.clj
+++ src/blog_clj/redis_io.clj
@@ -50,7 +50,7 @@
   related invert-index-set"
   [blog-id new-tags]
   (let [bkey (blog-key blog-id)
-        old-tags (wcar* (car/hget bkey :tags))
+        old-tags (set (wcar* (car/hget bkey :tags)))
         tags-to-add (difference new-tags old-tags)
         tags-to-delete (difference old-tags new-tags)]
     (wcar* (car/hmset bkey :tags new-tags)


Remove unused `require`s

Remove unused `require`s

--- src/braid/lib/upload.cljs
+++ src/braid/lib/upload.cljs
@@ -1,19 +1,18 @@
 (ns braid.lib.upload
   (:require
-    [clojure.string :as string]
-    [braid.lib.s3 :as s3]))
+   [clojure.string :as string]))

 (def regex (delay
              (re-pattern (str "https?://"
                               (-> (aget js/window "asset_domain")
                                   (string/replace "." "\\."))
-                                   "/"))))
+                              "/"))))

 (defn ->path [url]
   (string/replace
-    url
-    @regex
-    (str "//" (aget js/window "api_domain") "/upload/")))
+   url
+   @regex
+   (str "//" (aget js/window "api_domain") "/upload/")))

 (defn upload-path? [url]
   (string/includes? url (aget js/window "asset_domain")))


Add diff-product-rule to leibniz

Add diff-product-rule to leibniz

It's untested until I get all the diff rules typed in.

--- src/chapter3/leibniz.cljs
+++ src/chapter3/leibniz.cljs
@@ -35,6 +35,16 @@
   ['(d (diff-const-e1-rule f) (diff-const-e2-rule e2))
    (fn [d] 0)
    "diff-const-rule"])
+(defn diff-product-e3-rule [d x]
+  (and (not (atom? x))
+       (when-let [d2 (match-state '(* (? e1) (? e2)) x)]
+         (merge d d2))))
+(def diff-product-rule
+  ['(d (diff-product-e3-rule e3) (? v1))
+   (fn [d] (list '+
+                 (list '* (d 'e2) (list 'd (d 'e1) (d 'v1)))
+                 (list '* (d 'e1) (list 'd (d 'e2) (d 'v1)))))
+   "diff-product-rule"])
 ; other rules go here ...

 ; TODO: Clojure HAS to have a class/record facility to do this...


move om/root call out of init so it gets called when figwheel reloads

--- src/chat/client/core.cljs
+++ src/chat/client/core.cljs
@@ -12,6 +12,7 @@
 (defn init []
   (.addEventListener js/document "visibilitychange"
                 (fn [e] (store/set-window-visibility! (= "visible" (.-visibilityState js/document)))))
-  (om/root views/app-view store/app-state
+  (sync/start-router!))
+
+(om/root views/app-view store/app-state
            {:target (. js/document (getElementById "app"))})
-  (sync/start-router!))


CLJS-627: Add warnings on function arity problems

This patch adds three new warning types that may be thrown when
defining a function.

:multiple-variadic-overloads : Can't have more than 1 variadic overload
:variadic-max-arity : Can't have fixed arity with more params than
variadic
:overload-arity : Can't have 2 overloads with the same arity

--- src/clj/cljs/analyzer.clj
+++ src/clj/cljs/analyzer.clj
@@ -40,7 +40,10 @@
    :fn-deprecated true
    :protocol-deprecated true
    :undeclared-protocol-symbol true
-   :invalid-protocol-symbol true})
+   :invalid-protocol-symbol true
+   :multiple-variadic-overloads true
+   :variadic-max-arity true
+   :overload-arity true})

 (declare message namespaces)

@@ -97,6 +100,18 @@
 (defmethod default-warning-handler* :invalid-protocol-symbol
   [warning-type extra]
   (str "Symbol " (:protocol extra) " is not a protocol"))
+
+(defmethod default-warning-handler* :multiple-variadic-overloads
+  [warning-type extra]
+  (str (:name extra) ": Can't have more than 1 variadic overload"))
+
+(defmethod default-warning-handler* :variadic-max-arity
+  [warning-type extra]
+  (str (:name extra) ": Can't have fixed arity function with more params than variadic function"))
+
+(defmethod default-warning-handler* :overload-arity
+  [warning-type extra]
+  (str (:name extra) ": Can't have 2 overloads with same arity"))

 (defn ^:private default-warning-handler [warning-type env extra]
   (when (warning-type *cljs-warnings*)
@@ -562,10 +577,16 @@
                   ;; lets us optimize self calls
                   (no-warn (doall (map #(analyze-fn-method menv locals % type) meths)))
                   methods)]
-    ;;todo - at most one variadic, variadic takes max required args
-    (let [param-counts (map (comp count :params) methods)]
-      (when (not= (distinct param-counts) param-counts)
-        (throw (error env "Can't have 2 overloads with same arity"))))
+    (let [variadic-methods (filter :variadic methods)
+          variadic-params (count (:params (first variadic-methods)))
+          param-counts (map (comp count :params) methods)]
+      (when (and (:multiple-variadic-overloads *cljs-warnings*) (< 1 (count variadic-methods)))
+        (warning :multiple-variadic-overloads env {:name name-var}))
+      (when (and (:variadic-max-arity *cljs-warnings*)
+                 (not (or (zero? variadic-params) (= variadic-params (+ 1 max-fixed-arity)))))
+        (warning :variadic-max-arity env {:name name-var}))
+      (when (and (:overload-arity *cljs-warnings*) (not= (distinct param-counts) param-counts))
+        (warning :overload-arity env {:name name-var})))
     {:env env :op :fn :form form :name name-var :methods methods :variadic variadic
      :recur-frames *recur-frames* :loop-lets *loop-lets*
      :jsdoc [(when variadic "@param {...*} var_args")]


decomplect type hints & fns

decomplect type hints & fns

stop using :tag, fns now are always tagged 'function, and the type-hint
is instead attach to :ret-tag. Add type inference case for :throw, just
'ignore. We now have warnings if you try to add numbers and functions.

--- src/clj/cljs/analyzer.clj
+++ src/clj/cljs/analyzer.clj
@@ -417,13 +417,14 @@
     tag
     (case (:op e)
       :recur 'ignore
+      :throw 'ignore
       :let (infer-tag env (:expr e))
       :loop (infer-tag env (:expr e))
       :do  (infer-tag env (:ret e))
       :method (infer-tag env (:expr e))
       :def (infer-tag env (:init e))
       :invoke  (let [f (:f e)]
-                 (or (and (-> f :info :fn-var) (:tag f))
+                 (or (and (-> f :info :fn-var) (:ret-tag f))
                      (infer-tag env
                        (assoc (find-matching-method f (:args e)) :op :method))
                      'any))
@@ -611,10 +612,13 @@
                         (:methods init-expr))})))
       (merge {:env env :op :def :form form
               :name name :var var-expr :doc doc :init init-expr}
-             (when tag {:tag tag})
-             (when dynamic {:dynamic true})
-             (when export-as {:export export-as})
-             (when init-expr {:children [init-expr]})))))
+        (when tag
+          (if fn-var?
+            {:ret-tag tag}
+            {:tag tag}))
+        (when dynamic {:dynamic true})
+        (when export-as {:export export-as})
+        (when init-expr {:children [init-expr]})))))

 (defn- analyze-fn-method [env locals form type]
   (let [param-names (first form)
@@ -660,7 +664,7 @@
                       :info {:shadow (or (locals name)
                                        (get-in env [:js-globals name]))}}
                      (when-let [tag (-> name meta :tag)]
-                       {:tag tag})))
+                       {:ret-tag tag})))
         locals (if (and locals name) (assoc locals name name-var) locals)
         type (-> form meta ::type)
         fields (-> form meta ::fields)
@@ -711,6 +715,7 @@
       (when (and (:overload-arity *cljs-warnings*) (not= (distinct param-counts) param-counts))
         (warning :overload-arity env {:name name-var})))
     {:env env :op :fn :form form :name name-var :methods methods :variadic variadic
+     :tag 'function
      :recur-frames *recur-frames* :loop-lets *loop-lets*
      :jsdoc [(when variadic "@param {...*} var_args")]
      :max-fixed-arity max-fixed-arity
@@ -730,7 +735,7 @@
                   (let [be {:name   n
                             :line (get-line n env)
                             :column (get-col n env)
-                            :tag    (-> n meta :tag)
+                            :ret-tag (-> n meta :tag)
                             :local  true
                             :shadow (locals n)}]
                     [(assoc-in env [:locals n] be)


Hopefully everything's fixed...

Hopefully everything's fixed...

--- src/clj/cljweb/routes.clj
+++ src/clj/cljweb/routes.clj
@@ -22,6 +22,6 @@
       (read-nth-line "resources/public/questions.txt" random-int)))
   (POST "/time" req
     (let [q-time (get (:params req) :q-time)]
-      (spit "resources/public/times.txt" q-time :append true))
-    (response {:msg "Time written!"}))
+      (spit "resources/public/times.txt" q-time :append true)
+      q-time))
   (resources "/"))


kibit changes

kibit changes

--- src/clj/football/main.clj
+++ src/clj/football/main.clj
@@ -34,8 +34,8 @@

 (defn -main [& args]
   (let [options (:options (parse-opts args cli-options))
-        rankings(load-file (-> options :rankings)) ; it really behave better
-        players (load-file (-> options :player-list))
+        rankings(load-file (:rankings options)) ; it really behave better
+        players (load-file (:player-list options))
         players-rankings (filter #(contains? (set players) (:name %)) rankings)
         selections (engine/brute-force-selection players-rankings)]
     ;; use this information


change asciimath delimiters

change asciimath delimiters

--- src/clj/relembra/core.clj
+++ src/clj/relembra/core.clj
@@ -58,12 +58,12 @@
      :headers {"content-type" "text/html"}
      :body (html [:head [:title "relembra (WIP)"]
                   [:script {:type "text/x-mathjax-config"}
-                   "MathJax.Hub.Config({asciimath2jax: {delimiters: [['¿','¿']]}});"]
+                   "MathJax.Hub.Config({asciimath2jax: {delimiters: [['¡','¡']]}});"]
                   [:script {:type "text/javascript" :async true
                             :src "https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=AM_CHTML"}]]
                  [:body
                   [:h2 "Relembra (WIP)"]
-                  [:div (str "Hello, " user "!")]
+                  [:div (str "Olá, " user "!")]
                   [:div#app_container
                    [:script {:type "text/javascript" :src "js/main.js"}]
                    [:script {:type "text/javascript"} "relembra.core.main();"]]])}


Take advantage of bound variables in protocol implementations

--- src/cljs/fatlip/core.cljs
+++ src/cljs/fatlip/core.cljs
@@ -22,25 +22,25 @@
 (defrecord SparseGraph [layers succs preds ps qs rs]
   Reversible
   (rev [this]
-  (assoc this
-    :succs (:preds this)
-    :preds (:succs this)
-    :ps (:qs this)
-    :qs (:ps this)
-    :layers (vec (rseq (:layers this))))))
+    (assoc this
+      :succs preds
+      :preds succs
+      :ps qs
+      :qs ps
+      :layers (vec (rseq layers)))))

 (defrecord SparseLayer [id duration nodes])
 (defrecord OrderedGraph [layers succs preds ps qs minus-ps minus-qs]
   Reversible
   (rev [this]
-  (assoc this
-    :succs (:preds this)
-    :preds (:succs this)
-    :ps (:qs this)
-    :qs (:ps this)
-    :minus-ps (:minus-qs this)
-    :minus-qs (:minus-ps this)
-    :layers (vec (rseq (:layers this))))))
+    (assoc this
+      :succs preds
+      :preds succs
+      :ps qs
+      :qs ps
+      :minus-ps minus-qs
+      :minus-qs minus-ps
+      :layers (vec (rseq layers)))))

 (defrecord OrderedLayer [id duration items])
 (defrecord CountedAndMarkedGraph [layers succs preds crossings marked]) ; still has OrderedLayers


meh on defn-

meh on defn-

--- src/cljs/fatlip/core.cljs
+++ src/cljs/fatlip/core.cljs
@@ -22,7 +22,7 @@
   (map->Segment (assoc edge :layer-id layer-id)))

-(defn- add-edge [graph last-node node characters]
+(defn add-edge [graph last-node node characters]
   "Creates an edge and adds it to the graph as a whole and to each participating node"
   (let [weight (count characters)
         forward-edge (Edge. node characters weight)
@@ -40,7 +40,7 @@
         (update-in [:preds node] (fnil conj #{}) edge-2))))

-(defn- make-node [graph layer-id input]
+(defn make-node [graph layer-id input]
   "Utility function that was abstracted to avoid mutually recursing back to add-node
   when creating helper (p, q, and r) nodes. In particular, helper nodes don't require
   character group processing or bookkeeping metadata"
@@ -52,7 +52,7 @@
     [g node]))

-(defn- add-p-q-nodes [graph last-node node characters]
+(defn add-p-q-nodes [graph last-node node characters]
   "When an edge would span more than 2 layers, two helper nodes are created. P nodes
   are placed on the layer following last-node's layer, and q nodes are placed on the
   layer preceding node's layer. Edges are then drawn from last-node -> p node and from
@@ -70,7 +70,7 @@
     [g q-node]))

-(defn- add-r-node [graph last-node node characters]
+(defn add-r-node [graph last-node node characters]
   "R nodes are created to assist in drawing the graph, when an edge skips over a layer.
   In that case, the r node is placed in the intervening layer, and an edge is created
   from last-node to r node"
@@ -81,7 +81,7 @@
     [g r-node]))

-(defn- process-edge-characters [graph last-node node characters]
+(defn process-edge-characters [graph last-node node characters]
   "Create edges and possibly new helper nodes for a set of characters that
   remain together from last-node to node"
   (let [span (- (:layer-id node) (:layer-id last-node))
@@ -92,7 +92,7 @@
     (add-edge g last-n node characters)))

-(defn- process-characters
+(defn process-characters
   "Process each set of characters, where a set is defined as those characters
   present in the current node that also share their last node (ie. they define
   an edge in the graph)"
@@ -192,7 +192,7 @@
                [])))

-(defn- set-positions
+(defn set-positions
   "Step 2a of ESK. Positions in an ordered layer are used to calculate the order of the
   next layer. ESK's description of the position algorithm is almost willfully circuitous
   and obtuse, so here's a simplified description: An item's position in an ordered layer
@@ -214,7 +214,7 @@
         (recur (rest m-ps) c-p (assoc positions item (inc current-position)))))))

-(defn- get-measure
+(defn get-measure
   "Calculate the average weighted position of a node's predecessors"
   [node preds pred-positions]
   (if (empty? preds)
@@ -285,7 +285,7 @@
                [])))

-(defn- sorted-edge-order
+(defn sorted-edge-order
   "Sorts edges between two ordered layers first by their index in the source
   layer, and then by their index in the destination layer. Then, returns seq
   of [order edge] pairs of the edge targets in the destination layer, using
@@ -311,7 +311,7 @@
          (map #(-> [(get next-order-map (:dest %)) %])))))

-(defn- next-power-of-2
+(defn next-power-of-2
   "A helper for cross counting; the number of leaf nodes in the accumulator tree
   needs to be the first power of 2 greater than the number of nodes in one layer.
   This function sets all the bits to the right of the first bit set in a 32 bit
@@ -326,7 +326,7 @@
                (inc exp))))))

-(defn- single-edge-super-crossings
+(defn single-edge-super-crossings
   "Counts the number of crossings that result from adding an edge, in order,
   to the accumulator tree. If the index is even, meaning it's a right
   child of its parent, we increment its value. If the index is


Updating route during time travel seems to work

--- src/cljs/mathom/core.cljs
+++ src/cljs/mathom/core.cljs
@@ -57,8 +57,10 @@
 (defn set-app-state
   [state]
   (reset! appdb state)
-  ;(.route js/m (get-in state [::meta :route]))
-  (.redraw js/m))
+  (let [stored_route (get-in state [::meta :route])]
+    (if (= (.route js/m) stored_route)
+      (.redraw js/m)
+      (.route js/m stored_route))))

 (defn serialize-edn
   "Serialize given data structure into string"
@@ -189,7 +191,7 @@
             (clj->js {"/" index}))))

 (setup)
-(.route js/m "/")
+;(.route js/m "/")

 (setup-toolbar)


Add bucket for marked edges on a Layer

Add bucket for marked edges on a Layer

--- src/cljs/nchart/core.cljs
+++ src/cljs/nchart/core.cljs
@@ -23,7 +23,7 @@

 (defrecord Node [id layer-id characters])
 (defrecord Edge [dest characters])
-(defrecord Layer [id duration nodes])
+(defrecord Layer [id duration nodes marked])
 (defrecord SegmentContainer [segments])
 (defrecord Segment [edge])

@@ -143,7 +143,8 @@
         layer-id (count layers)
         layer (Layer. layer-id
                       (input-layer :duration)
-                      [])]
+                      []
+                      #{})]
     (loop [g (update-in graph [:layers] conj layer)
            input-groups (input-layer :groups)]
       (if (empty? input-groups)


display index-based slide

display index-based slide

--- src/cljs/slides/core.cljs
+++ src/cljs/slides/core.cljs
@@ -2,7 +2,7 @@
   (:require [om.core :as om :include-macros true]
             [om.dom :as dom :include-macros true]))

-(defonce app-state (atom {:slides []}))
+(defonce app-state (atom {:slides [] :index 0}))

 (defn slide [model owner]
   (reify
@@ -18,8 +18,8 @@
   (reify
     om/IRender
     (render [_]
-      (apply dom/div #js {:className "content"}
-         (om/build-all slide (:slides model))))))
+      (dom/div #js {:className "content"}
+        (om/build slide ((:slides model) (:index model)))))))

 (def slide-imgs
   [{:title "A Bird's Eye View of ClojureScript"
@@ -31,3 +31,5 @@
   (om/root app app-state {:target (. js/document (getElementById "app"))}))

 (swap! app-state assoc :slides slide-imgs)
+
+;;(swap! app-state assoc :index 0)


Fix native interface

Fix native interface

--- src/clojure_pf/native.clj
+++ src/clojure_pf/native.clj
@@ -7,9 +7,9 @@
   that is configured with the given interface, data link type
   and read buffer length."
   (let [fd (jna/invoke Integer
-                       clojure_pf_native/pf_open
+                       clojure_pf/pf_open
                        interface
-                       read-buffer-length
+                       read-length
                        data-link-type)]
     (when-not (= fd -1)
       fd)))
@@ -24,7 +24,7 @@
   Returns a data buffer on success."
   (let [data  (byte-array size)
         nr    (jna/invoke Integer
-                          clojure_pf_native/pf_read
+                          clojure_pf/pf_read
                           fd
                           data
                          (count data))]
@@ -35,7 +35,7 @@
   "Writes data to a socket/device.
   Returns the number of bytes written on success."
   (let [nw (jna/invoke Integer
-                       clojure_pf_native/pf_write
+                       clojure_pf/pf_write
                        data
                        (count data))]
     (when-not (= nw -1)
@@ -43,4 +43,4 @@

 (defn close [fd]
   "Closes a socket/device associated with the given file descriptor."
-  (jna/invoke Void clojure_pf_native/pf_close fd))
+  (jna/invoke Void clojure_pf/pf_close fd))


Capture output during r.m.stacktrace test.

--- ring-devel/test/ring/middleware/stacktrace_test.clj
+++ ring-devel/test/ring/middleware/stacktrace_test.clj
@@ -8,9 +8,10 @@
 (def js-req   {:headers {"accept" "text/javascript"}})

 (deftest wrap-stacktrace-smoke
-  (let [{:keys [status headers] :as response} (app html-req)]
-    (is (= 500 status))
-    (is (= {"Content-Type" "text/html"} headers)))
-  (let [{:keys [status headers]} (app js-req)]
-    (is (= 500 status))
-    (is (= {"Content-Type" "text/javascript"} headers))))
+  (binding [*err* (java.io.StringWriter.)]
+    (let [{:keys [status headers] :as response} (app html-req)]
+      (is (= 500 status))
+      (is (= {"Content-Type" "text/html"} headers)))
+    (let [{:keys [status headers]} (app js-req)]
+      (is (= 500 status))
+      (is (= {"Content-Type" "text/javascript"} headers)))))


Add some routes

Add some routes

--- src/comic_reader/core.clj
+++ src/comic_reader/core.clj
@@ -1,7 +1,15 @@
 (ns comic-reader.core
-  (:gen-class))
+  (:gen-class)
+  (:require [ring.util.response :as response]
+            [ring.middleware.params :refer [wrap-params]]
+            [compojure.core  :as c]
+            [compojure.route :as route]))

-(defn -main
-  "I don't do a whole lot ... yet."
-  [& args]
-  (println "Hello, World!"))
+(c/defroutes routes
+  (c/GET "/" [] "Hello World!")
+  (c/context "/api/v1" []
+    (c/GET "/comic/:name" [name]
+      (str "Hello comic" name)))
+  (route/resources "/"))
+
+(def app (wrap-params routes))


CMR-1746: Fixed a failing system integration test

--- system-int-test/src/cmr/system_int_test/data2/granule.clj
+++ system-int-test/src/cmr/system_int_test/data2/granule.clj
@@ -7,8 +7,11 @@
             [cmr.system-int-test.data2.collection :as dc]
             [cmr.common.date-time-parser :as p]
             [cmr.umm.spatial :as umm-s]
+            [cmr.common.util :as util]
             [cmr.spatial.orbits.swath-geometry :as swath])
-  (:import [cmr.umm.granule Orbit]))
+  (:import [cmr.umm.granule
+            Orbit
+            DataProviderTimestamps]))

 (defn psa
   "Creates product specific attribute ref"
@@ -100,12 +103,21 @@
                                   :start-coordinate-2 start-coordinate-2
                                   :end-coordinate-2 end-coordinate-2})))

+(defn data-provider-timestamps
+  [attribs]
+  (let [attribs (util/remove-nil-keys
+                  (select-keys attribs (util/record-fields DataProviderTimestamps)))
+        attribs (into {} (for [[k v] attribs] [k (p/parse-datetime v)]))
+        minimal-timestamps {:insert-time (d/make-datetime 10 false)
+                            :update-time (d/make-datetime 18 false)}]
+    (g/map->DataProviderTimestamps (merge minimal-timestamps attribs))))
+
 (defn granule
   "Creates a granule"
   ([collection]
    (granule collection {}))
   ([collection attribs]
-   (let [timestamps {:data-provider-timestamps (dc/data-provider-timestamps attribs)}
+   (let [timestamps {:data-provider-timestamps (data-provider-timestamps attribs)}
          {:keys [format-key entry-title entry-id] {:keys [short-name version-id]} :product} collection
          coll-ref (g/map->CollectionRef {:entry-title entry-title
                                          :entry-id entry-id


(SERVER-882) Refactor valid-static-file-path test to not use loop

--- test/unit/puppetlabs/services/master/master_core_test.clj
+++ test/unit/puppetlabs/services/master/master_core_test.clj
@@ -6,7 +6,8 @@
             [puppetlabs.comidi :as comidi]
             [puppetlabs.services.protocols.jruby-puppet :as jruby]
             [puppetlabs.trapperkeeper.testutils.logging :as logging]
-            [ring.util.response :as rr])
+            [ring.util.response :as rr]
+            [puppetlabs.kitchensink.core :as ks])
   (:import (java.util HashMap)))

 (use-fixtures :once schema-test/validate-schemas)
@@ -199,47 +200,28 @@
                        "bogus"}])})))))))

 (deftest valid-static-file-path-test
-  (let [expected-path-results {:valid #{"modules/foo/files/bar.txt"
-                                        "modules/foo/files/bar/"
-                                        "modules/foo/files/bar/baz.txt"
-                                        "environments/production/modules/foo/files/bar.txt"
-                                        "environments/production/modules/foo/files/..conf..d../..bar..txt.."
-                                        "environments/test/modules/foo/files/bar/baz.txt"
-                                        "environments/dev/modules/foo/files/path/to/file/something.txt"}
-                               :invalid #{"modules/foo/manifests/bar.pp"
-                                          "manifests/site.pp"
-                                          "environments/foo/bar/files"
-                                          "environments/../manifests/files/site.pp"
-                                          "environments/../modules/foo/lib/puppet/parser/functions/site.rb"
-                                          "environments/production/files/~/.bash_profile"
-                                          "environments/../modules/foo/files/site.pp"
-                                          "environments/production/modules/foo/files/../../../../../../site.pp"}}
-        paths ["modules/foo/files/bar.txt"
-               "modules/foo/files/bar/"
-               "modules/foo/files/bar/baz.txt"
-               "environments/production/modules/foo/files/bar.txt"
-               "environments/production/modules/foo/files/..conf..d../..bar..txt.."
-               "environments/test/modules/foo/files/bar/baz.txt"
-               "environments/dev/modules/foo/files/path/to/file/something.txt"
-               "modules/foo/manifests/bar.pp"
-               "manifests/site.pp"
-               "environments/foo/bar/files"
-               "environments/../manifests/files/site.pp"
-               "environments/../modules/foo/lib/puppet/parser/functions/site.rb"
-               "environments/production/files/~/.bash_profile"
-               "environments/../modules/foo/files/site.pp"
-               "environments/production/modules/foo/files/../../../../../../site.pp"]
-        actual-results (loop
-         [results {:valid #{}
-                   :invalid #{}}
-          remaining-paths paths]
-          (if-let [cur-path (first remaining-paths)]
-            (if (valid-static-file-path? cur-path)
-              (recur (assoc results :valid (conj (:valid results) cur-path)) (rest remaining-paths))
-              (recur (assoc results :invalid (conj (:invalid results) cur-path)) (rest remaining-paths)))
-            results))]
+  (let [valid-paths ["modules/foo/files/bar.txt"
+                     "modules/foo/files/bar/"
+                     "modules/foo/files/bar/baz.txt"
+                     "environments/production/modules/foo/files/bar.txt"
+                     "environments/production/modules/foo/files/..conf..d../..bar..txt.."
+                     "environments/test/modules/foo/files/bar/baz.txt"
+                     "environments/dev/modules/foo/files/path/to/file/something.txt"]
+        invalid-paths ["modules/foo/manifests/bar.pp"
+                       "manifests/site.pp"
+                       "environments/foo/bar/files"
+                       "environments/../manifests/files/site.pp"
+                       "environments/../modules/foo/lib/puppet/parser/functions/site.rb"
+                       "environments/production/files/~/.bash_profile"
+                       "environments/../modules/foo/files/site.pp"
+                       "environments/production/modules/foo/files/../../../../../../site.pp"]
+        check-valid-path (fn [path] {:path path :valid? (valid-static-file-path? path)})
+        valid-path-results (map check-valid-path valid-paths)
+        invalid-path-results (map check-valid-path invalid-paths)
+        get-validity (fn [{:keys [valid?]}] valid?)]
     (testing "Only files in 'modules/*/files/**' or 'environments/*/modules/*/files/**' are valid"
-      (is (= actual-results expected-path-results)))))
+      (is (every? get-validity valid-path-results) (ks/pprint-to-string valid-path-results))
+      (is (every? (complement get-validity) invalid-path-results) (ks/pprint-to-string invalid-path-results)))))

 (deftest file-bucket-file-content-type-test
   (testing (str "The 'Content-Type' header on incoming /file_bucket_file requests "


some type annotations

some type annotations

--- src/datascript/btset.cljc
+++ src/datascript/btset.cljc
@@ -44,7 +44,7 @@
                               first
                               inc))
 (def ^:const path-mask (dec (bit-shift-left 1 level-shift)))
-(def ^:const empty-path 0)
+(def ^:const ^long empty-path (long 0))

 (defn path-get ^long [^long path ^long level]
   (bit-and path-mask
@@ -607,7 +607,7 @@

 ;; iteration

-(defn -next-path [node path level]
+(defn -next-path ^long [node ^long path ^long level]
   (let [idx (path-get path level)]
     (if (pos? level)
       ;; inner node
@@ -631,12 +631,12 @@
 (defn next-path
   "Returns path representing next item after `path` in natural traversal order,
    or -1 if end of tree has been reached"
-  [^BTSet set path]
+  ^long [^BTSet set ^long path]
   (-next-path (.-root set) path (.-shift set)))

 (defn -rpath
   "Returns rightmost path possible starting from node and going deeper"
-  [node level]
+  ^long [node ^long level]
   (loop [node  node
          path  empty-path
          level level]
@@ -648,7 +648,7 @@
       ;; leaf
       (path-set path 0 (dec (shim/alength (.-keys ^Leaf node)))))))

-(defn -prev-path [node path level]
+(defn -prev-path ^long [node ^long path ^long level]
   (let [idx (path-get path level)]
     (if (pos? level)
       ;; inner node
@@ -675,7 +675,7 @@
 (defn prev-path
   "Returns path representing previous item before `path` in natural traversal order,
    or -1 if `path` was already beginning of a tree"
-  [^BTSet set path]
+  ^long [^BTSet set ^long path]
   (-prev-path (.-root set) path (.-shift set)))

@@ -690,7 +690,7 @@
           right  (inc (-rpath (.-root set) (.-shift set)))]
       (iter set left right))))

-(deftype Iter [set left right keys idx]
+(deftype Iter [set ^long left ^long right keys ^long idx]
   #?@(:cljs [
     ISeqable
     (-seq [this] (when keys this))
@@ -743,7 +743,7 @@
     (iterator [this] (clojure.lang.SeqIterator. this))
   ]))

-(defn iter [set left right]
+(defn iter [set ^long left ^long right]
   (Iter. set left right (keys-for set left) (path-get left 0)))

 (defn iter-first [^Iter iter]
@@ -821,7 +821,7 @@
                   (recur (inc left) keys (inc idx) new-acc)
                   new-acc)
                 (let [new-left (next-path set left)]
-                  (if (and (not= -1 new-left) (< new-left (.-right iter)))
+                  (if (and (not= -1 new-left) (< new-left right))
                     (recur new-left (keys-for set new-left) (path-get new-left 0) new-acc)
                     new-acc)))))))))

@@ -829,7 +829,7 @@

 (declare riter-first riter-next riter-rseq)

-(deftype ReverseIter [set left right keys idx]
+(deftype ReverseIter [set ^long left ^long right keys ^long idx]
   #?@(:cljs [
     ISeqable
     (-seq [this] (when keys this))
@@ -866,7 +866,7 @@
     (iterator [this] (clojure.lang.SeqIterator. this))
   ]))

-(defn riter [set left right]
+(defn riter [set ^long left ^long right]
   (ReverseIter. set left right (keys-for set right) (path-get right 0)))

 (defn riter-first [^ReverseIter riter]
@@ -901,7 +901,7 @@

 ;; distance

-(defn -distance [node left right level]
+(defn -distance [node ^long left ^long right ^long level]
   (let [idx-l (path-get left level)
         idx-r (path-get right level)]
     (if (pos? level)
@@ -915,7 +915,7 @@
             (* res avg-len))))
       (- idx-r idx-l))))

-(defn distance [^BTSet set path-l path-r]
+(defn distance [^BTSet set ^long path-l ^long path-r]
   (cond
     (== path-l path-r) 0
     (== (inc path-l) path-r) 1


Mild cleanup

Mild cleanup

--- src/foreclojure/users.clj
+++ src/foreclojure/users.clj
@@ -24,8 +24,8 @@
   (let [users (from-mongo
                (fetch :users
                       :only [:user :solved :contributor]))
-        sortfn  (comp count :solved)]
-    (reverse (sort-by sortfn users))))
+        sortfn  (comp - count :solved)]
+    (sort-by sortfn users)))

 (defn golfer? [user]
   (some user golfer-tags))
@@ -48,16 +48,16 @@
      [:th {:style "width: 40px;"} "Rank"]
      [:th "Username"]
      [:th "Problems Solved"]]]
-   (map-indexed #(vec [:tr (row-class %1)
-                       [:td (inc %1)]
-                       [:td
-                        (when (:contributor %2)
-                          [:span.contributor "* "])
-                        [:a#user-profile-link {:href (str "/user/" (:user %2))} (:user %2)]]
-                       [:td {:class "centered"} (count (:solved %2))]])
+   (map-indexed (fn [rownum {:keys [user contributor solved]}]
+                  [:tr (row-class rownum)
+                   [:td (inc rownum)]
+                   [:td
+                    (when contributor [:span.contributor "* "])
+                    [:a#user-profile-link {:href (str "/user/" user)} user]]
+                   [:td.centered (count solved)]])
                 (get-users))])

-;; TODO: this is snagged from problems.clj but can't be imported do to cyclic dependancy, must refactor this out.
+;; TODO: this is snagged from problems.clj but can't be imported due to cyclic dependency, must refactor this out.
 (defn get-problems
   ([]
      (from-mongo


Implement compile command.

Implement compile command.

--- src/leiningen/compile.clj
+++ src/leiningen/compile.clj
@@ -1,7 +1,13 @@
 (ns leiningen.compile
+  (:use [clojure.contrib.java-utils :only [file]]
+        [clojure.contrib.find-namespaces :only [find-namespaces-in-dir]])
   (:refer-clojure :exclude [compile]))

-;; accept either a list of namespaces or spider the project root for .clj files
-;; create classes/ directory
-
-(defn compile [project])+(defn compile
+  "Compile the namespaces specified in build.clj or all namespaces in src/
+  if none are provided."
+  [project]
+  (.mkdir (file (:root project) "classes"))
+  (doseq [n (or (:namespaces project)
+                (find-namespaces-in-dir (file (:root project) "src")))]
+    (compile n)))


add ::synth type key to synth map

add ::synth type key to synth map

--- src/overtone/sc/synth.clj
+++ src/overtone/sc/synth.clj
@@ -334,7 +334,8 @@
                               :sdef sdef#
                               :doc "User defined synth..."
                               :player player#
-                              :args arg-names#}
+                              :args arg-names#
+                              :type ::synth}
                              player#)]
      (load-synthdef sdef#)
      (event :new-synth :synth smap#)


add missing transaction/team attribute

add missing transaction/team attribute

--- src/pc/datomic/schema.clj
+++ src/pc/datomic/schema.clj
@@ -485,6 +485,10 @@
    (attribute :transaction/document
               :db.type/ref
               :db/doc "Annotates transaction with document it belongs to")
+
+   (attribute :transaction/team
+              :db.type/ref
+              :db/doc "Annotates transaction with team it belongs to")

    (attribute :migration
               :db.type/ref


Writing the tentacle test revealed the temp-fs implementation to be fucked. This is a comparatively quick-and-dirty fix; these two implementations share a *ton* of code, and should be compressed/refactored

--- src/doctopus/storage/impls/temp_fs.clj
+++ src/doctopus/storage/impls/temp_fs.clj
@@ -2,7 +2,8 @@
   (:require [clojure.string :as str]
             [doctopus.files :as files]
             [doctopus.storage.impls.fs-impl :refer [save-html-file] :as fs-impl]
-            [me.raynes.fs :as fs]))
+            [me.raynes.fs :as fs]
+            [bidi.ring :as bidi-ring]))

 ;; The root of the temp filesystem. Each Thing will store its stuff
 ;; within this directory
@@ -14,19 +15,22 @@
   (swap! temp-dir fs/temp-dir "doctopus-temp"))

 (defn save-fn
-  [key path-html-pairs]
-  (doseq [[path html] path-html-pairs] (save-html-file @temp-dir key path html)))
+  "Save a dir of html stuff by moving it in to the current temp root"
+  [key src-dir]
+  (binding [fs/*cwd* @temp-dir]
+    (let [target-dir (fs/file key)
+          result (fs/copy-dir src-dir target-dir)]
+      (and (fs/exists? result)
+           (fs/readable? result)))))

 (defn load-fn
-  "This is as Version 1 a way of doing this as I can think of:
-
-  1. We load html
-  2. We wrap that html in a function that returns itself, so we can Bidi"
+  "Returns the routes this serves"
   [key]
-  (binding [fs/*cwd* @temp-dir]
-    (let [dir (fs/file key)
-          rel-path-html-pairs (files/read-html dir)]
-      (into [] (map (fn [[rel-path html]] [rel-path (fn [_] html)]) rel-path-html-pairs)))))
+  (let [file-handle (binding [fs/*cwd* @temp-dir] (fs/file key))
+        file-name (str (.getPath file-handle) "/")]
+    (if (fs/exists? file-handle)
+      [key {"/" (bidi-ring/->Files {:dir file-name})}]
+      nil)))

 (defn remove-fn
   [key]


tree-query tag summary stuff

tree-query tag summary stuff

--- src/com/billpiel/mem_tracer/util/tree_query.clj
+++ src/com/billpiel/mem_tracer/util/tree_query.clj
@@ -11,7 +11,8 @@

 (defn children-zips [z] (if-let [d (z/down z)]
                           (lazy-cat [d]
-                                    (right-sib-zips d)) []))
+                                    (right-sib-zips d))
+                          []))

 (defn set-zip-children
   [z c]
@@ -33,29 +34,51 @@

 #_ (get-tags' {:id 1} {:a #(-> % :id #{1}) :b #(-> % :id #{1})})

-(defn get-children-tags*
+(defn merge-children-tag-summary
+  [& rest]
+  {:paths (->> rest
+               (mapcat :paths)
+               vec)
+   :set (->> rest
+             (map :set)
+             (apply clojure.set/union))})
+
+(defn insert-tag-into-children-tag-summary
+  [tag ch-tags]
+  {:paths (->> ch-tags
+               :paths
+               (mapv #(into [tag] %)))
+   :set (-> ch-tags
+            :set
+            (conj tag))})
+
+(defn get-children-tag-summary*
   [zipr pred-map]
   (let [this-tags (-> zipr
                       z/node
                       (get-tags' pred-map))]
-    (mapv #(into [this-tags] %)
-          (if-let [ch-zips (not-empty (children-zips zipr))]
-            (mapcat #(get-children-tags* % pred-map)
-                    ch-zips)
-            [[]]))))
+    (insert-tag-into-children-tag-summary this-tags
+                                          (if-let [ch-zips (-> zipr
+                                                               children-zips
+                                                               not-empty)]
+                                            (->> ch-zips
+                                                 (map #(get-children-tag-summary* %
+                                                                                pred-map))
+                                                 (apply merge-children-tag-summary))
+                                            (merge-children-tag-summary)))))

-(defn get-children-tags
+(defn get-children-tag-summary
   [zipr pred-map]
   (->> zipr
        children-zips
-       (mapcat #(get-children-tags* % pred-map))
-       vec))
+       (map #(get-children-tag-summary* %
+                                        pred-map))
+       merge-children-tag-summary))

 #_ (ppcp (get-children-tags z1
                             {:a #(-> % :id #{1 2 3 4}) :even #(-<> (do %)
                                                                    :id
                                                                    even?)}))
-

 (defn tag*
   [zipr pred-map & {:keys [parent-tags]}]


The list of participants is now sorted

The list of participants is now sorted

--- src/freecoin/handlers/participants.clj
+++ src/freecoin/handlers/participants.clj
@@ -99,6 +99,7 @@
   :authorized? #(auth/is-signed-in %)

   :handle-ok (fn [ctx]
-               (-> {:wallets (wallet/query wallet-store (request->wallet-query (:request ctx)))}
-                   participants-list/participants-list
-                   fv/render-page)))
+               (let [wallets (wallet/query wallet-store (request->wallet-query (:request ctx)))]
+                 (-> {:wallets (sort-by :name wallets)}
+                     participants-list/participants-list
+                     fv/render-page))))


Bump dependencies

Bump dependencies

* org.clojure/clojurescript
* sablono
* org.omcljs/om
* lein-cljsbuild
* lein-figwheel

--- src/leiningen/new/figwheel/project.clj
+++ src/leiningen/new/figwheel/project.clj
@@ -5,14 +5,14 @@
             :url "http://www.eclipse.org/legal/epl-v10.html"}

   :dependencies [[org.clojure/clojure "1.7.0"]
-                 [org.clojure/clojurescript "0.0-3297"]
+                 [org.clojure/clojurescript "1.7.122"]
                  [org.clojure/core.async "0.1.346.0-17112a-alpha"]{{#om?}}
-                 [sablono "0.3.4"]
-                 [org.omcljs/om "0.8.8"]{{/om?}}{{#reagent?}}
+                 [sablono "0.3.6"]
+                 [org.omcljs/om "0.9.0"]{{/om?}}{{#reagent?}}
                  [reagent "0.5.0"]{{/reagent?}}]

-  :plugins [[lein-cljsbuild "1.0.5"]
-            [lein-figwheel "0.3.5"]]
+  :plugins [[lein-cljsbuild "1.1.0"]
+            [lein-figwheel "0.3.8"]]

   :source-paths ["src"]