fixed bug when cancelling uploads

fixed bug when cancelling uploads

--- src/frontend/uploads.cljs
+++ src/frontend/uploads.cljs
@@ -76,15 +76,19 @@
       (let [uploads (:uploads new-state)
             uploads-order (vec (remove deleted-upload-ids (:uploads-order new-state)))
             inactive-uploads (inactive-uploads uploads-order uploads)]
-        (if (empty? inactive-uploads)
-          (swap! app-state/app-state
-                 merge
-                 {:uploads-order uploads-order})
-          (swap! app-state/app-state
-                 merge
-                 {:uploads-order uploads-order
-                  :uploads (merge uploads {(first inactive-uploads)
-                                           (start-upload (uploads (first inactive-uploads)))})}))))))
+        (cond
+          (empty? inactive-uploads)
+            (swap! app-state/app-state
+                   merge
+                   {:uploads-order uploads-order})
+          (> (count (active-uploads uploads-order uploads))
+             (:upload-slots new-state))
+            (swap! app-state/app-state
+                   merge
+                   {:uploads-order uploads-order
+                    :uploads (assoc uploads
+                                    (first inactive-uploads)
+                                    (start-upload (uploads (first inactive-uploads))))}))))))

 (add-watch app-state/app-state :upload-removed upload-removed-watch-fn!)


Remove dead import

Remove dead import

--- src/fugue/midi_input.cljs
+++ src/fugue/midi_input.cljs
@@ -5,8 +5,7 @@
             [cljs.core.async :as async]
             [fugue.components :refer [slider picker]]
             [fugue.midi :as midi]
-            [fugue.keyboard :as kb]
-            [fugue.chords :as chords]))
+            [fugue.keyboard :as kb]))

 (defn midi-selector [midi-ins on-change]
   [:select {:on-change #(on-change (get midi-ins (.. % -target -value)))}


image-nodes

image-nodes

--- examples/lesson-carousel-starter-kit/src/carousel/core.cljs
+++ examples/lesson-carousel-starter-kit/src/carousel/core.cljs
@@ -101,6 +101,32 @@
                                            :textHighlight "none"
                                            :zIndex "2"
                                            :content ">"}]]}]
+
+      (let [url-base "http://demo.famo.us.s3.amazonaws.com/hub/apps/carousel/Museo_del_Prado_-_Goya_-_Caprichos_-_No._"
+            image-names ["01_-_Autorretrato._Francisco_Goya_y_Lucientes2C_pintor_thumb.jpg"
+                         "02_-_El_si_pronuncian_y_la_mano_alargan_al_primero_que_llega_thumb.jpg"
+                         "03_-_Que_viene_el_Coco_thumb.jpg"
+                         "04_-_El_de_la_rollona_thumb.jpg"
+                         "05_-_Tal_para_qual_thumb.jpg"
+                         "06_-_Nadie_se_conoce_thumb.jpg"
+                         "07_-_Ni_asi_la_distingue_thumb.jpg"
+                         "09_-_Tantalo_thumb.jpg"
+                         "10_-_El_amor_y_la_muerte_thumb.jpg"
+                         "11_-_Muchachos_al_avC3ADo_thumb.jpg"
+                         "12_-_A_caza_de_dientes_thumb.jpg"
+                         "13_-_Estan_calientes_thumb.jpg"]]
+        (for [image-name image-names
+              :let [url-base "http://demo.famo.us.s3.amazonaws.com/hub/apps/carousel/Museo_del_Prado_-_Goya_-_Caprichos_-_No._"
+                    image-url (str url-base image-name)
+                    url (str "url('" image-url "')")]]
+          [:node {:size-mode [ABSOLUTE ABSOLUTE ABSOLUTE]
+                  :absolute-size [500 500 0]
+                  :align [0.5 0.5]
+                  :mount-point [0.5 0.5]
+                  :origin [0.5 0.5]
+                  :components [ [:DOMElement {:backgroundImage url
+                                              :background-repeat "no-repeat"
+                                              :background-size "cover"}]]}]))
       [:node {:id "dots"
               :size-mode [ABSOLUTE ABSOLUTE]
               :absolute-size [20 20]
@@ -123,14 +149,15 @@
         position (clj->js (:position attributes))
         components (:components attributes)
         mount-point (clj->js (:mount-point attributes))
-
+        origin (clj->js (:origin attributes))
         children (get-children node-as-vec)]
     (.apply (.-setSizeMode node) node size-mode)
     (.apply (.-setAbsoluteSize node) node absolute-size)
     (.apply (.-setAlign node) node align)
     (.apply (.-setPosition node) node position)
     (.apply (.-setMountPoint node) node mount-point)
-    (println components)
+    (.apply (.-setOrigin node) node origin)
+
     (if-not (empty? components)
       (doseq [component components
               :let [dom-element (DOMElement. node)


Removes double assert

Removes double assert

--- src/expound/spec.cljs
+++ src/expound/spec.cljs
@@ -265,7 +265,6 @@

 (defmethod problem-group-str :problem/missing-key [_type val path problems]
   (assert (apply = (map :val problems)) (str "All values should be the same, but they are " problems))
-  (assert (apply = (map :val problems)) (str "All values should be the same, but they are " (map :val problems)))
   (gstring/format
    "%s

@@ -281,7 +280,6 @@

 (defmethod problem-group-str :problem/not-in-set [_type val path problems]
   (assert (apply = (map :val problems)) (str "All values should be the same, but they are " problems))
-  (assert (apply = (map :val problems)) (str "All values should be the same, but they are " (map :val problems)))
   (s/assert ::singleton problems)
   (gstring/format
    "%s
@@ -324,9 +322,7 @@
      (relevant-specs problems))))

 (defmethod problem-group-str :problem/unknown [_type val path problems]
-  ;; TODO - remove double assert
   (assert (apply = (map :val problems)) (str "All values should be the same, but they are " problems))
-  (assert (apply = (map :val problems)) (str "All values should be the same, but they are " (map :val problems)))
   (gstring/format
    "%s


cjl - Put back the dumb ai

cjl - Put back the dumb ai

--- src/icfp2015/core.clj
+++ src/icfp2015/core.clj
@@ -2,7 +2,7 @@
   (:require [clojure.data.json :as json]
             [clojure.tools.cli :refer [parse-opts]]
             [icfp2015.problem :refer [get-games]]
-            [icfp2015.ai :refer [slightly-smarter-ai]]
+            [icfp2015.ai :refer [dumb-ai]]
             [icfp2015.gameplay :refer [get-commands]])
   (:gen-class))

@@ -24,7 +24,7 @@
 (defn solve-game [game]
   { :problemId (:problemId game)
     :seed (:seed game)
-    :solution (apply str (map command-to-letter (get-commands slightly-smarter-ai game))) })
+    :solution (apply str (map command-to-letter (get-commands dumb-ai game))) })

 (def cli-options
   [["-f" "--file FILE" "Input filename"


resolving conflict

resolving conflict

--- src/io/aviso/rook.clj
+++ src/io/aviso/rook.clj
@@ -84,11 +84,13 @@
   [namespace]
   (when-not (find-ns namespace)
     (require namespace))
-  (concat
-    (remove nil?
-            (map function-entry
-                 (filter symbol-for-function? (map second (ns-publics namespace)))))
-    default-mappings))
+  (->> namespace
+   ns-publics
+   (map second)
+   (filter symbol-for-function?)
+   (map function-entry)
+   (remove nil?)
+   (concat default-mappings)))

 (defn- get-function-meta
   "Get meta for route-mapping and namespace."
@@ -234,4 +236,14 @@
                    rook-handler
                    (apply compojure/routes (concat handlers [rook-handler])))
          handler' (namespace-middleware handler namespace-name)]
-     (compojure/context path [] handler'))))+     (compojure/context path [] handler'))))
+
+  ([namespace]
+   (namespace-middleware rook-handler namespace))
+  ([path namespace & handlers]
+   (let [handler (if (empty? handlers)
+                   rook-handler
+                   (apply compojure/routes (concat handlers [rook-handler])))
+         handler' (namespace-middleware handler namespace)]
+     (compojure/context path [] handler'))))
+


Fix not returning state

Fix not returning state

--- src/braid/client/state/helpers.cljs
+++ src/braid/client/state/helpers.cljs
@@ -117,8 +117,9 @@
   (assoc-in state [:users user-id :avatar] avatar))

 (defn update-user-status [state user-id status]
-  (when (get-in state [:users user-id])
-    (assoc-in state [:users user-id :status] status)))
+  (if (get-in state [:users user-id])
+    (assoc-in state [:users user-id :status] status)
+    state))

 (defn remove-user-from-group [state user-id group-id]
   ; TODO: also remove user from collection if group-ids is now empty? shouldn't make a difference


showing the latest 5 tweets about bacon as an unordered list

--- src/cljs/baconator/client/main.cljs
+++ src/cljs/baconator/client/main.cljs
@@ -20,7 +20,7 @@
     (reset! vis-marker marker)
     (.addTo marker world-map)))

-;; Twitter users
+;; Utils

 (defn log [& args]
   (.log js/console (apply pr-str args)))
@@ -31,16 +31,21 @@
 (defn get-element [id]
   (dom/getElement (name id)))

+;; Twitter users
+
 (defn create-li-tweet [name msg]
   (let [li (dom/createElement "li")]
-    (doto li (dom/setTextContent (str name ":" msg)))))
+    (doto li (dom/setTextContent (str name ": " msg)))))

 (defn show-tweet [name msg]
   (let [node (get-element :tweetlist)
-        item (create-li-tweet name msg)]
-    (log-obj node)
-    (log-obj item)
-    (dom/insertChildAt node item 0)))
+        item (create-li-tweet name msg)
+        childs (prim-seq (dom/getChildren node))
+        new-childs (conj (take 4 childs) item)]
+    (log (count new-childs))
+    (dom/removeChildren node)
+    (doseq [child new-childs]
+      (dom/appendChild node child))))

 ;; Get bacon lovers


CLJS-283: fix protocol & protocol method names in reducers/Cat

--- src/cljs/clojure/core/reducers.cljs
+++ src/cljs/clojure/core/reducers.cljs
@@ -180,11 +180,11 @@

 ;;do not construct this directly, use cat
 (deftype Cat [cnt left right]
-  clojure.lang.Counted
-  (count [_] cnt)
-
-  clojure.lang.Seqable
-  (seq [_] (concat (seq left) (seq right)))
+  cljs.core/ICounted
+  (-count [_] cnt)
+
+  cljs.core/ISeqable
+  (-seq [_] (concat (seq left) (seq right)))

   cljs.core/IReduce
   (-reduce [this f1] (-reduce this f1 (f1)))


removed commet

removed commet

--- src/cljs/lisp_interpreter/core.cljs
+++ src/cljs/lisp_interpreter/core.cljs
@@ -117,7 +117,7 @@

 (defn eval-sequence
   [exps env]
-  (cond (empty? (rest exps)) (my-eval (first exps) env) ;; this needs to be sequencable -- I could pass in a list instead
+  (cond (empty? (rest exps)) (my-eval (first exps) env)
         :else (do (my-eval (first exps) env)
                   (eval-sequence (rest exps) env))))


construct websocket url from location host

--- src/cljs/sparky_elephants/core.cljs
+++ src/cljs/sparky_elephants/core.cljs
@@ -43,13 +43,14 @@

 (defn set-user
   [user-id]
-  (let [user-id (not-empty user-id)]
+  (let [user-id (not-empty user-id)
+        host (-> js/window.location .-host)]
     (go
       (reset! user-id-value user-id)
       (swap! mailbox-chan (fn [old-chan] (when old-chan (close! old-chan)) nil))
       (reset! message-history-value nil)
       (when user-id
-        (when-let [ch (<! (open-ws (str "ws://localhost:10000/mailbox/" user-id "?client-uuid=" client-uuid)))]
+        (when-let [ch (<! (open-ws (str "ws://" host "/mailbox/" user-id "?client-uuid=" client-uuid)))]
           (reset! mailbox-chan ch)
           (log-channel ch message-history-value))))))

@@ -66,7 +67,8 @@
   [:div
    [:div.row
     [:div.col-md-2 [:label "Message"]]
-    [:div.col-md-5 [:input {:field :text :id :msg}]]]])
+    [:div.col-md-5 [:input {:field :text
+                            :id :msg}]]]])

 (defn message-form
   []


Implement sign

Implement sign

--- src/clojure_fabric/crypto_suite.clj
+++ src/clojure_fabric/crypto_suite.clj
@@ -21,7 +21,8 @@
   (:require [clojure.data.codec.base64 :as b64]
             [clojure-fabric.utils :as utils]
             [clojure.java.io :as io])
-  (:import [org.bouncycastle.crypto.generators ECKeyPairGenerator]
+  (:import [java.math BigInteger]
+   [org.bouncycastle.crypto.generators ECKeyPairGenerator]
            [org.bouncycastle.jce ECNamedCurveTable]
            [org.bouncycastle.jce.spec ECNamedCurveParameterSpec ECNamedCurveSpec]
            [org.bouncycastle.jce.provider BouncyCastleProvider]
@@ -31,12 +32,14 @@
            [org.bouncycastle.util.encoders Hex]
            [org.bouncycastle.asn1.pkcs PrivateKeyInfo]
            [org.bouncycastle.asn1.x509 SubjectPublicKeyInfo]
+           [org.bouncycastle.asn1 ASN1Integer DERSequenceGenerator]
            [org.bouncycastle.cert X509CertificateHolder]
            [org.bouncycastle.openssl.jcajce JcaPEMKeyConverter]
            [org.bouncycastle.openssl PEMParser]
            [org.bouncycastle.cert.jcajce JcaX509CertificateConverter]
-
-           [java.io FileInputStream StringReader FileReader File]
+           [org.bouncycastle.crypto.signers ECDSASigner]
+           [org.bouncycastle.crypto.params ECDomainParameters ECPrivateKeyParameters]
+           [java.io FileInputStream StringReader FileReader File ByteArrayOutputStream]
            [java.util Arrays]
            [javax.crypto Cipher SecretKeyFactory]
            [javax.crypto.spec SecretKeySpec]
@@ -107,8 +110,7 @@
 ;;;

 (defprotocol IBCECKey
-  (algorithm [this])
-  (curve-spec [this])
+;;  (key->value [this])
   (curve-params [this])
   (%derive-key [this opts]))

@@ -138,16 +140,14 @@
 ;;;
 (extend-type BCECPrivateKey
   IBCECKey
-  (algorithm [this] (-> this .getAlgorithm keyword))
-  (curve-spec [this] (keyword (.getName ^ECNamedCurveSpec (.getParams this))))
+;;  (key->value [this] (.getD this))
   (curve-params [this] (-> this .getParameters %curve-params))
   (%derive-key [this opts]
     (derive-bcec-key (curve-params this))))

 (extend-type BCECPublicKey
   IBCECKey
-  (algorithm [this] (-> this .getAlgorithm keyword))
-  (curve-spec [this] (keyword (.getName ^ECNamedCurveSpec (.getParams this))))
+;;  (key->value [this] (.getQ this))
   (curve-params [this] (-> this .getParameters %curve-params))
   (%derive-key [this opts]
     (derive-bcec-key (curve-params this))))
@@ -273,6 +273,15 @@
   [k cipher-text {:keys [algorithm] :as opts}]
   (%encrypt-or-decrypt k cipher-text (assoc opts :cipher-mode :decrypt)))

+(defn- prevent-malleability
+  [signature ^BigInteger curve-n]
+  ;; Copy from Fabric SDK Java
+  (let [cmp-val ^BigInteger (.divide curve-n (biginteger 2))
+        s-val (aget signature 1)]
+    (when (= (.compareTo ^BigInteger s-val cmp-val) 1)
+      (aset signature 1 s-val))
+    signature))
+
 ;;;sign
 (defn sign
   "Sign the data.
@@ -282,13 +291,27 @@
         opts (function) hashing function to use
   Returns
         Result(Object):Signature object"
-  [^bytes digest priv-key {:keys [algorithm hash-algorithm]
-                           :or {algorithm :ecdsa hash-algorithm :sha256}}]
-  (let [hashed (hash digest :algorithm hash-algorithm)
-        signer (Signature/getInstance (name algorithm))]
-    (.initSign signer priv-key)
-    (.update signer hashed)
-    (.sign signer)))
+  [^bytes digest priv-key {:keys [algorithm curve hash-algorithm]
+                           :or {algorithm :ecdsa curve :secp256r1 hash-algorithm :sha256}}]
+  (let [signer (ECDSASigner.)
+        priv-params (-> curve name ECNamedCurveTable/getParameterSpec)
+        curve-n (.getN priv-params) ]
+    (->> (ECDomainParameters. (.getCurve priv-params) (.getG priv-params) curve-n)
+         (ECPrivateKeyParameters. (.getS ^BCECPrivateKey priv-key))
+         (.init signer true))
+    (let [out-stream (ByteArrayOutputStream.)
+          der-seq (DERSequenceGenerator. out-stream)
+          signature (prevent-malleability (.generateSignature signer
+                                                              (hash digest :algorithm hash-algorithm))
+                                          curve-n)]
+      (try
+        (.addObject der-seq (ASN1Integer. ^BigInteger (aget signature 0)))
+        (.addObject der-seq (ASN1Integer. ^BigInteger (aget signature 1)))
+        (catch Exception e
+          (println "FIXME: log error?" e))
+        (finally (.close der-seq)))
+
+      (.toByteArray out-stream))))

 ;;; verify
 (defn verify


Remove spec tests.

Remove spec tests.

--- spec/buddy/auth/accessrules_spec.clj
+++ spec/buddy/auth/accessrules_spec.clj
@@ -1,167 +0,0 @@
-(ns buddy.auth.accessrules-spec
-  (:require [speclj.core :refer :all]
-            [ring.util.response :as ring]
-            [buddy.auth.accessrules :refer [compile-rule-handler restrict wrap-access-rules
-                                            success error]]))
-
-(defn ok [v] (success v))
-(defn fail [v] (error v))
-
-(defn ok2 [v] true)
-(defn fail2 [v] false)
-
-(describe "Compile one rule (handler or composition of them)"
-  (it "compile access rules 1"
-    (let [rule (compile-rule-handler ok)
-          result (rule 1)]
-      (should= (success 1) result)))
-
-  (it "compile access rules 2"
-    (let [rule (compile-rule-handler {:or [ok fail]})
-          result (rule 1)]
-      (should= (success 1) result)))
-
-  (it "compile access rules 3"
-    (let [rule (compile-rule-handler {:and [ok fail]})
-          result (rule 1)]
-      (should= (error 1) result)))
-
-  (it "compile access rules 4"
-    (let [rule (compile-rule-handler {:or [fail fail {:and [ok ok]}]})
-          result (rule 1)]
-      (should= (success 1) result)))
-
-  (it "compile access rules 5"
-    (let [rule (compile-rule-handler {:and [ok ok]})
-          result (rule 1)]
-      (should= (success 1) result)))
-
-  (it "compile access rules 6"
-    (let [rule (compile-rule-handler {:and [ok2 ok2]})
-          result (rule 1)]
-      (should= true result)))
-
-  (it "compile access rules 7"
-    (let [rule (compile-rule-handler {:or [fail2 ok2]})
-          result (rule 1)]
-      (should= true result)))
-)
-
-(defn test-handler
-  [req]
-  (ring/response req))
-
-(describe "Restrict one handler with ok"
-  (it "restrict handler 1"
-    (let [handler (restrict test-handler {:handler {:or [ok fail]}})
-          rsp     (handler "test")]
-      (should= "test" (:body rsp))))
-
-  (it "restrict handler with failure 1"
-    (let [handler (restrict test-handler {:handler {:or [fail fail]}})]
-      (should-throw (handler 1))))
-
-  (it "restrict handler with failure 2"
-    (let [handler (restrict test-handler {:handler {:or [fail fail]}})
-          rsp (handler "Failure message")]
-      (should= "Failure message" (:body rsp))
-      (should= 400 (:status rsp))))
-
-  (it "restrict handlerw with failure and explicit on-error handler"
-    (let [handler (restrict test-handler
-                            {:handler {:or [fail fail]}
-                             :on-error (fn [req val] (ring/response (str "onfail-" val)))})
-          rsp     (handler "test")]
-      (should= "onfail-test" (:body rsp))))
-
-  (it "restrict handlerw with failure and redirect"
-    (let [handler (restrict test-handler
-                            {:handler {:or [fail fail]}
-                             :redirect "/foobar"})
-          rsp     (handler "test")]
-      (should= 302 (:status rsp))
-      (should= "/foobar" (get-in rsp [:headers "Location"]))))
-)
-
-
-
-(def params1
-  {:rules [{:pattern #"^/path1$"
-            :handler {:or [ok fail]}}
-           {:pattern #"^/path2$"
-            :handler ok}
-           {:pattern #"^/path3$"
-            :handler {:and [fail ok]}}]})
-
-(def params2
-  {:rules [{:uri "/path1"
-            :handler {:or [ok fail]}}
-           {:uri "/path2"
-            :handler ok}
-           {:uris ["/path3" "/path0"]
-            :handler {:and [fail ok]}}]})
-
-(defn on-error
-  [req val]
-  (-> (ring/response val)
-      (ring/status 400)))
-
-
-(def handler1
-  (wrap-access-rules test-handler
-                     (assoc params1 :policy :reject)))
-
-(def handler2
-  (wrap-access-rules test-handler
-                     (assoc params1
-                       :policy :reject
-                       :on-error on-error)))
-
-(def handler3
-  (wrap-access-rules test-handler
-                     (assoc params2 :policy :reject)))
-
-(describe "Wrap access rules using pattern"
-  (it "check access rules 1"
-    (let [rsp (handler1 {:uri "/path1"})]
-      (should= {:uri "/path1"} (:body rsp))))
-
-  (it "check access rules 2"
-    (let [rsp (handler1 {:uri "/path2"})]
-      (should= {:uri "/path2"} (:body rsp))))
-
-  (it "check access rules 3"
-    (should-throw (handler1 {:uri "/path3"})))
-
-  (it "check access rules 4"
-    (should-throw (handler1 {:uri "/path4"})))
-
-  (it "check access rules 5"
-    (let [rsp (handler2 {:uri "/path3"})]
-      (should= 400 (:status rsp))
-      (should= {:uri "/path3"} (:body rsp))))
-
-  (it "check access rules 6"
-    (let [rsp (handler2 {:uri "/path4"})]
-      (should= 400 (:status rsp))
-      (should= nil (:body rsp))))
-)
-
-(describe "Wrap access rules using clout"
-  (it "check access rules 1"
-    (let [rsp (handler3 {:uri "/path1"})]
-      (should= {:uri "/path1"} (:body rsp))))
-
-  (it "check access rules 2"
-    (let [rsp (handler3 {:uri "/path2"})]
-      (should= {:uri "/path2"} (:body rsp))))
-
-  (it "check access rules 3"
-    (should-throw (handler3 {:uri "/path3"})))
-
-  (it "check access rules 4"
-    (should-throw (handler3 {:uri "/path4"})))
-)
-
-(run-specs)
-


Sideline nrepl as an external setting

Sideline nrepl as an external setting

--- cmma-clj/src/cmma/nrepl.clj
+++ cmma-clj/src/cmma/nrepl.clj
@@ -29,7 +29,7 @@
    {:port (port*)
     :bind (bind)})
   ([project]
-   (let [{:keys [nrepl-options]} project]
+   (let [nrepl-options (get-in project [:external :nrepl-options])]
      (merge
        (dissoc nrepl-options :reply)
        {:port (port* nrepl-options :port)
@@ -51,7 +51,7 @@
 (defn -main [& args]
   (let [prj (cmma.project/project (first args)) ;; `project` is nil-safe; defaults to "project.edn"
         nrepl (server (repl-settings prj))]
-    (if (get-in prj [:nrepl-options :reply])
+    (if (get-in prj [:external :nrepl-options :reply])
       (reply/-main)
       (do (println "Server running; Hit a key to shutdown:")
           (read-line)))


Snap selection to the complete sentence

Snap selection to the complete sentence

--- src/discuss/components/tooltip.cljs
+++ src/discuss/components/tooltip.cljs
@@ -41,7 +41,7 @@
   (let [offset 5]
     (+ (- top theight offset) js/window.scrollY)))

-(defn calc-position
+(defn- calc-position
   "Create a new tooltip at given selection. Creates a rectangle around the selection,
    which has position-properties and which are useful for positioning of the tooltip."
   [tooltip-width tooltip-height]
@@ -67,7 +67,29 @@
      (move-to-selection (calc-position tooltip.offsetWidth tooltip.offsetHeight)))))

-;;;; Include listener for tooltips
+;; -----------------------------------------------------------------------------
+;; Selection corrections
+
+(defn- snap-selection
+  "Selection optimizations. Snaps to a specific pattern. Currently selects the
+  whole sentence, where the selected parts are part of."
+  []
+  (let [sel (js/document.getSelection)]
+    (when (-> sel str count pos?)
+      (.modify sel "move"   "backward" "sentence")
+      (.modify sel "extend" "forward"  "sentence")
+      (.modify sel "extend" "backward" "character")
+      sel)))
+
+(defn- save-selected-text
+  "Get the user's selection and save it."
+  []
+  (let [selection (snap-selection)]
+    (if-not (nil? selection)
+      (do (move-to-selection)
+          (lib/save-selection! (str selection)))
+      (hide))))
+
 (defn- listen
   "Helper function for mouse-click events."
   [el type]
@@ -75,17 +97,7 @@
     (events/listen el type (fn [e] (put! out e)))
     out))

-(defn- save-selected-text
-  "Get the users selection and save it."
-  []
-  (let [selection (str (.getSelection js/window))]
-    (if (and (pos? (count selection))
-             (not= selection (lib/get-selection)))
-      (do (move-to-selection)
-          (lib/save-selection! selection))
-      (hide))))
-
-(defn track-user-selection
+(defn- track-user-selection
   "Listen to clicks on the websites' text to store it in the app-state."
   []
   (when-let [discuss-text-dom (gdom/getElement (lib/prefix-name "text"))]
@@ -113,7 +125,7 @@

                  [:span
                   (vlib/safe-space) " " (vlib/safe-space)
-                  [:span.pointer {:onClick #((lib/show-overlay) (hide))}
+                  [:span.pointer {:onClick #(do (lib/show-overlay) (hide))}
                    (vlib/fa-icon "fa-comments")
                    (translate :common :show-discuss :space)]]])))
 (def tooltip (om/factory Tooltip))


Move numel-id to box-id

Move numel-id to box-id

--- src/leiningen/new/cljskel/setup.clj
+++ src/leiningen/new/cljskel/setup.clj
@@ -27,7 +27,7 @@
 (defn start
   []
   (setup/configure-logging)
-  (setup/start-graphite-reporting {:graphite-prefix (str (env :environment-name) (env :service-name) (env :numel-id setup/hostname))})
+  (setup/start-graphite-reporting {:graphite-prefix (str (env :environment-name) (env :service-name) (env :box-id setup/hostname))})
   (reset! server (start-server)))

 (defn stop


status display improved

status display improved

--- src/leiningen/git.clj
+++ src/leiningen/git.clj
@@ -7,6 +7,17 @@
             [leiningen.namespaces :as ns]))

 (def output-length 120)
+
+(defn remove-change-status-from [path]
+  (-> path
+      (str/replace #"M\s" "")
+      (str/replace #"A\s" "")
+      (str/replace #"D\s" "")
+      (str/replace #"R\s" "")
+      (str/replace #"C\s" "")
+      (str/replace #"U\s" "")
+      (str/replace #"\?\?\s" "")
+      (str/replace #"\s" "")))

 (defn log-git-status [status & args]
   (pp/print-table status)
@@ -75,20 +86,13 @@
                    (u/ask-user u/yes-or-no)))
       (push! project))))

-(defn get-details-status [project status-result projects-desc]
-  (let [status-lines (-> status-result
-                         (u/output-of)
-                         (str/replace #"M\s" "")
-                         (str/replace #"A\s" "")
-                         (str/replace #"D\s" "")
-                         (str/replace #"R\s" "")
-                         (str/replace #"C\s" "")
-                         (str/replace #"U\s" "")
-                         (str/replace #"\?\?\s" "")
-                         (str/split-lines))
-        changed-files (map #(str/replace % #"\s" "") status-lines)
-        synchronized-resources (->> changed-files
-                                    (filter #(ns/sync-resources? projects-desc %))
+(defn get-details-status [status-result projects-desc]
+  (let [synchronized-resources (->> status-result
+                                    (u/output-of)
+                                    (str/split-lines)
+                                    (filter #(ns/sync-resources?
+                                              projects-desc
+                                              (remove-change-status-from %)))
                                     (str/join " "))]
     {:synchronized-resources (if (empty? synchronized-resources)
                                :no-change synchronized-resources)}))
@@ -100,7 +104,7 @@
       (merge {:project                project
               :unpushed-commit-change (if (empty? unpushed-changes)
                                         :no-change unpushed-changes)}
-             (get-details-status project status-result projects-desc))
+             (get-details-status status-result projects-desc))
       {:project project :status (status-failed)})))

 (defn overview-status [project]


Add deprecation warning for js->clj

Add deprecation warning for js->clj

--- src/lt/util/cljs.cljs
+++ src/lt/util/cljs.cljs
@@ -51,8 +51,8 @@
 (defn ->dottedkw [& args]
   (keyword (string/join "." (map name (filter identity args)))))

-;; TODO: Remove once remove these references from Clojure, Python and JS plugins
 (defn js->clj [& args]
+  (js/lt.objs.console.error "lt.util.cljs/js->clj is deprecated and will be removed in 0.9.0. Use js->clj instead")
   (apply cljs.core/js->clj args))

 (defn str-contains? [str x]


Improve parse-int util function.

Improve parse-int util function.

It now accept a default value in case of parsing
return NaN.

--- frontend/uxbox/util/data.cljs
+++ frontend/uxbox/util/data.cljs
@@ -42,5 +42,10 @@
   (r/read-string v))

 (defn parse-int
-  [v]
-  (js/parseInt v 10))
+  ([v]
+   (js/parseInt v 10))
+  ([v default]
+   (let [v (js/parseInt v 10)]
+     (if (or (not v) (nan? v))
+       default
+       v))))


Add live-sequencer from checkouts/overtone/src/overtone/examples/getting_started/pragpub-article.clj and src/overtone_workshop/timing.clj

--- src/overtone_workspace/grunbles.clj
+++ src/overtone_workspace/grunbles.clj
@@ -6,8 +6,18 @@
 ;; Inspired by an example in an early chapter of the SuperCollider book

 ;; (def kick (sample "resources/kick.wav"))
-;; (kick :start 0 :end 0.1)
+;; (kick)

+(stop)
+
+(odoc line)
+(odoc asr)
+(odoc buf-rd)
+(odoc phasor)
+(odoc bpz2)
+(odoc latch)
+(odoc buf-rate-scale)
+(odoc buf-dur)

 (definst grumble [freq 440 freq-mul 1 speed 10 attack 10 release 50]
   (let [snd (mix (map #(* (lf-cub (* % freq-mul freq))
@@ -60,13 +70,13 @@
 (defn laserplayer [beat]
   (let [dur (/ 60.0 (metro :bpm))]      ; 15bars
     (at (metro beat)
-        (laserbeam :pan (- (rand 2.0) 1.0) :freq (+ (rand-int 1000) 12000) :dur 0.25))
+        (laserbeam :pan (- (rand 2.0) 1.0) :freq (+ (rand-int 1000) 100) :dur 0.25))
     (at (metro (+ beat 0.25))
-        (laserbeam :pan (- (rand 2.0) 1.0) :freq (+ (rand-int 1000) 12000) :dur 0.25))
+        (laserbeam :pan (- (rand 2.0) 1.0) :freq (+ (rand-int 1000) 100) :dur 0.25))
     (at (metro (+ beat 0.5))
-        (laserbeam :pan (- (rand 2.0) 1.0) :freq (+ (rand-int 1000) 12000) :dur 0.25))
+        (laserbeam :pan (- (rand 2.0) 1.0) :freq (+ (rand-int 1000) 100) :dur 0.25))
     (at (metro (+ beat 0.75))
-        (laserbeam :pan (- (rand 2.0) 1.0) :freq (+ (rand-int 1000) 12000) :dur 0.25))
+        (laserbeam :pan (- (rand 2.0) 1.0) :freq (+ (rand-int 1000) 100) :dur 0.25))
     (apply-by (metro (inc beat)) #'laserplayer (inc beat) [])
     ))

@@ -74,7 +84,7 @@

 ;; (stop)

-(def latchbell-arg (atom {:rate 9 :amp 0.2 :max 2.5}))
+(def latchbell-arg (atom {:rate 100 :amp 0.4 :max 5}))

 (defn latchbellplayer [beat]
   (let [dur (/ 60.0 (metro :bpm))]
@@ -88,13 +98,80 @@
         (latchbell :rate (:rate @latchbell-arg) :amp (:amp @latchbell-arg) :time-scale-max (:max @latchbell-arg)))
     (apply-by (metro (inc beat)) #'latchbellplayer (inc beat) [])
     ))
-
 ;; (init-latchbell-mod (:rate @latchbell-arg))
 ;; (latchbellplayer (metro))
 ;; (stop)
+
+(comment
+  (inst-fx! latchbell fx-echo)
+  (inst-fx! latchbell fx-distortion2)
+  (clear-fx latchbell)
+
+  (inst-fx! grumble fx-bitcrusher)
+  (clear-fx grumble)
+
+  (inst-fx! laserbeam fx-freeverb)
+  (clear-fx laserbeam))
+

 ;; (def dirty-kick (freesound 777))
 ;; (dirty-kick)
 ;; (def kick (sample (freesound-path 2086)))
 ;; (kick)
 ;; (def close-hihat (sample-player (sample (freesound-path 802))))
+
+
+(def _ 0)
+(def beats {laserbeam [1 _ _ _ _ _ _ 1 _ _ 1 _ _ _ _ 1]
+            latchbell [1 _ 1 _ 1 _ 1 _ 1 _ 1 _ 1 _ _ 1]})
+
+(def *beats (atom beats))
+
+; (defn live-sequencer [nome beat live-patterns scale idx]
+;   (doseq [[sound pattern] @live-patterns]
+;      (when (= 1 (nth pattern (mod idx (count pattern))))
+;        (at (nome beat) (sound))))
+;   (let [next-beat (+ scale beat)]
+;     (apply-by (nome next-beat) live-sequencer [nome next-beat live-patterns scale (inc idx)])))
+
+(defn flatten1
+  "Takes a map and returns a seq of all the key val pairs:
+      (flatten1 {:a 1 :b 2 :c 3}) ;=> (:b 2 :c 3 :a 1)"
+  [m]
+  (reduce (fn [r [arg val]] (cons arg (cons val r))) [] m))
+
+
+(defn live-sequencer [nome beat live-patterns scale idx]
+  (doseq [[sound pattern] @live-patterns
+          :let [v (nth pattern (mod idx (count pattern)))
+                v (cond
+                    (= 1 v)
+                    []
+
+                    (map? v)
+                    (flatten1 v)
+
+                    :else
+                    nil)]
+          :when v]
+    (at (nome beat) (apply sound v)))
+  (let [next-beat (+ scale beat)]
+    (apply-by (nome next-beat) live-sequencer [nome next-beat live-patterns scale (inc idx)])))
+
+(def a {:rate 100 :amp 0.5 :time-scale-max 10})
+(def a {:rate 2 :amp 0.05 :time-scale-max 5})
+(def b {:pan -1 :freq 1000})
+(def c {:freq 25000 :amp 0.2})
+(def d {:amp 3.0 :dur 0.25})
+
+(metro :bpm 110)
+(volume 0.5)
+(comment
+  (live-sequencer metro (metro) *beats 1/4 0)
+
+  (swap! *beats assoc laserbeam [d _ _ _ b _ _ d _ _ d _ b _ _ d])
+  (swap! *beats assoc latchbell [a _ a _ a _ a _ a _ a _ a _ a _])
+  (swap! *beats assoc laserbeam [d c c c b c c d c c d c b c c d])
+
+  (reset! *beats beats)
+  (stop))


Fix sorting snippets so that the most recent shows up at the top

--- src/app/components/snippet_list.cljs
+++ src/app/components/snippet_list.cljs
@@ -21,7 +21,7 @@
             (dom/button #js {:className "snippet-list-title-button"
                              :onClick #(when create-fn (create-fn))}
               "+ Create")))
-        (for [sn (sort-snippets (reverse snippets))]
+        (for [sn (sort-snippets snippets)]
           (snippet (om/computed sn {:toggle-fn toggle-fn
                                     :edit-fn edit-fn
                                     :delete-fn delete-fn


fix race condition when loading build target fns

--- src/main/shadow/build.clj
+++ src/main/shadow/build.clj
@@ -150,6 +150,8 @@
           (deep-merge mode-opts))
         (dissoc :release :dev))))

+(defonce target-require-lock (Object.))
+
 (defn get-target-fn [target build-id]

   (let [target-fn-sym
@@ -168,19 +170,20 @@

         target-ns (-> target-fn-sym namespace symbol)]

-    (when-not (find-ns target-ns)
-      (try
-        (require target-ns)
-        (catch Exception e
-          (throw (ex-info (format "failed to require :target %s for build %s" target build-id)
-                   {:tag ::get-target-fn :target target} e)))))
-
-    (let [fn (ns-resolve target-ns target-fn-sym)]
-      (when-not fn
-        (throw (ex-info (str "target-fn " target-fn-sym " not found") {:target target})))
-
-      fn
-      )))
+    (locking target-require-lock
+      (when-not (find-ns target-ns)
+        (try
+          (require target-ns)
+          (catch Exception e
+            (throw (ex-info (format "failed to require :target %s for build %s" target build-id)
+                     {:tag ::get-target-fn :target target} e)))))
+
+      (let [fn (ns-resolve target-ns target-fn-sym)]
+        (when-not fn
+          (throw (ex-info (str "target-fn " target-fn-sym " not found") {:target target})))
+
+        fn
+        ))))

 (defn configure
   [build-state mode {:keys [build-id target] :as config}]


fix  and

fix  and

--- src/misaki/config.clj
+++ src/misaki/config.clj
@@ -47,32 +47,20 @@

 ;; ## Config Data Wrapper

-(defn render-map [m & {:keys [ignore] :or {ignore #{}}}]
+(defn render-map [init target & {:keys [ignore] :or {ignore #{}}}]
   (reduce (fn [res [k v]]
             (if (contains? ignore k) res
               (assoc res k (if (string? v) (render v res) v)))
-            ) m m))
+            ) init target))

 ; =load-config
 (defn load-config
   "Load and read config file"
   []
-  (let [config (read-string (slurp (str *base-dir* *config-file*)))
-        ;res (render-map config :ignore #{:post-filename-format})
-        ]
-    (reduce
-      (fn [res [k v]]
-        (if (= k :post-filename-format)
-          res
-          (assoc res k (if (string? v) (render v res) v))
-          )
-        )
-      (apply hash-map config)
-      (partition 2 config)
-      )
-    ;res
-    ))
-  ;(read-string (slurp (str *base-dir* *config-file*))))
+  (let [config (read-string (slurp (str *base-dir* *config-file*)))]
+    (render-map (apply hash-map config)
+                (partition 2 config)
+                :ignore #{:post-filename-format})))

 ; =with-config
 (defmacro with-config
@@ -88,23 +76,15 @@
         *post*         (:post-dir config#)
         *layout-dir*   (str *base-dir* (:layout-dir config#))
         *post-dir*     (str *base-dir* (:post-dir config#))
-        ;*layout-dir*   (str *base-dir* (:template-dir config#) (:layout-dir config#))
-        ;*post-dir*     (str *base-dir* (:template-dir config#) (:post-dir config#))
         *tag-out-dir*  (:tag-out-dir config#)
         *tag-layout*   (str *base-dir* (:tag-layout config#))
-        ;*tag-layout*   (str *base-dir*
-        ;                    (:template-dir config#)
-        ;                    (:layout-dir config#)
-        ;                    (:tag-layout config#)
-        ;                    ".clj"
-        ;                    )
         *lang*         (get config# :lang "en")
         *site*         (get config# :site {})
         *compile-with-post* (:compile-with-post config#)
         *post-filename-regexp* (get config# :post-filename-regexp
                                  #"(\d{4})[-_](\d{1,2})[-_](\d{1,2})[-_](.+)$")
         *post-filename-format* (get config# :post-filename-format
-                                 "%year/%month/%file")
+                                 "{{year}}/{{month}}/{{filename}}")
         *cljs-compile-options* (assoc (dissoc cljs# :output-dir)
                                       :src-dir template#
                                       :output-to (str public# (:output-to cljs#)))]


Adjust collision-

Adjust collision-

Since it is a square it is not working good for this runner shape,
we will use a central square as collision point and see how to
get pixel detection (maybe moving to a canvas)

--- src/mrunner/core.cljs
+++ src/mrunner/core.cljs
@@ -120,8 +120,8 @@

 (defn detect-collision [{:keys [obstacles pos-x pos-y down] :as state}]
   (let [obstacle (first obstacles)]
-    (square-intersect? (+ pos-x runner-offset) (+ pos-y floor-y)
-                       (:width runner) (if down 47 (:height runner))
+    (square-intersect? (+ pos-x runner-offset 30) (+ pos-y floor-y)
+                       (- (:width runner) 60) (if down 47 (:height runner))
                        (:pos-x obstacle) (:pos-y obstacle)
                        (:width obstacle) (:height obstacle))))


Remove unused code.

Remove unused code.

--- src/octet/buffer.cljx
+++ src/octet/buffer.cljx
@@ -228,10 +228,3 @@
   [size & _]
   (let [bf (js/ArrayBuffer. size)]
     (js/DataView. bf)))
-
-;; #+cljs
-;; (defmethod allocate [:heap :node]
-;;   [size & _]
-;;   (let [bf (js/require "buffer")
-;;         bf (.-Buffer bf)]
-;;     (bf. size)))


minor spelling correction

minor spelling correction

--- src/overtone/util.clj
+++ src/overtone/util.clj
@@ -151,7 +151,7 @@
    where 1 2 and 3 are ordered params and
    4 and 5 are named params (associated with :d and :f respectively).

-   If the expected args is the lis [:a :b :c :d :f] then the resulting map
+   If the expected args is the list [:a :b :c :d :f] then the resulting map
    will look as follows: {:a 1 :b 2 :c 3 :d 5 :f 5}. If the defaults contains
    extra keys, these will be merged in with any clashes being overridden with
    the result map, so if the default map is {:a 99 :h 2} the final output will


Remove plugin fn.

Remove plugin fn.

--- src/onyx_starter/core.clj
+++ src/onyx_starter/core.clj
@@ -161,18 +161,9 @@

 (onyx.api/submit-job conn {:catalog catalog :workflow workflow})

-;; A little utility to read from the channel until :done
-(defn take-segments! [ch]
-  (loop [x []]
-    (let [segment (<!! ch)]
-      (let [stack (conj x segment)]
-        (if-not (= segment :done)
-          (recur stack)
-          stack)))))
+(def loud-results (onyx.plugin.core-async/take-segments! loud-output-chan))

-(def loud-results (take-segments! loud-output-chan))
-
-(def question-results (take-segments! question-output-chan))
+(def question-results (onyx.plugin.core-async/take-segments! question-output-chan))

 (clojure.pprint/pprint loud-results)


Allow changing shape position via assoc

Allow changing shape position via assoc

--- src/play_clj/entities.clj
+++ src/play_clj/entities.clj
@@ -5,6 +5,7 @@
             TextureRegion]
            [com.badlogic.gdx.graphics.g3d Environment ModelBatch ModelInstance]
            [com.badlogic.gdx.graphics.glutils ShapeRenderer]
+           [com.badlogic.gdx.math Matrix4]
            [com.badlogic.gdx.scenes.scene2d Actor]))

 (defprotocol Entity
@@ -59,9 +60,14 @@
     (.render renderer object attributes)))

 (defrecord ShapeEntity [object] Entity
-  (draw-entity! [{:keys [^ShapeRenderer object type draw!]}
+  (draw-entity! [{:keys [^ShapeRenderer object type draw! x y z]}
                  {:keys [^Camera camera]}
                  _]
+    (let [^Matrix4 m (.getTransformMatrix object)
+          x (float (or x 0))
+          y (float (or y 0))
+          z (float (or z 0))]
+      (.setTranslation m x y z))
     (when camera
       (.setProjectionMatrix object (. camera combined)))
     (.begin object type)


Disable circuit breaker recovery-test because it's not stable

--- scheduler/test/clj_http_async_pool/circuit_breaker_test.clj
+++ scheduler/test/clj_http_async_pool/circuit_breaker_test.clj
@@ -97,7 +97,7 @@
           (dotest 2 1000)))
       (async/close! service))))

-(deftest recovery-test
+#_(deftest recovery-test
   (testing "circuit breaker recovers after reset-timeout-ms"
     (let [reset-timeout-ms (multiply-duration 200)
           recovery-time-ms (+ reset-timeout-ms (/ reset-timeout-ms 10))


Added capitalize function

Added capitalize function

--- lib/compojure/str_utils/str_utils.clj
+++ lib/compojure/str_utils/str_utils.clj
@@ -52,3 +52,9 @@
   "Concatenate a sequence of strings into lines of a single string."
   [coll]
   (str-join "\n" coll))
+
+(defn capitalize
+  "Uppercase the first letter of a string, and lowercase the rest."
+  [s]
+  (str (.toUpperCase (.substring s 0 1))
+       (.toLowerCase (.substring s 1))))


CMR-662: Updated method signature to address pull request comments.

--- src/cmr/search/services/parameters/parameter_validation.clj
+++ src/cmr/search/services/parameters/parameter_validation.clj
@@ -379,7 +379,7 @@
            :errors))

 (defn unrecognized-aql-params-validation
-  [_ params]
+  [concept-type params]
   (map #(str "Parameter [" (csk/->snake_case_string % )"] was not recognized.")
        (set/difference (set (keys params))
                        (set [:page-size :page-num :sort-key :result-format :pretty :options]))))
@@ -430,8 +430,8 @@
   "Validates the query parameters passed in with an AQL search.
   Throws exceptions to send to the user. Returns parameters if validation
   was successful so it can be chained with other calls."
-  [params]
-  (let [errors (mapcat #(% {} params) aql-parameter-validations)]
+  [concept-type params]
+  (let [errors (mapcat #(% concept-type params) aql-parameter-validations)]
     (when (seq errors)
       (err/throw-service-errors :invalid-data errors)))
   params)


Improve phrasing

Improve phrasing

--- src/braid/client/register/views.cljs
+++ src/braid/client/register/views.cljs
@@ -288,7 +288,8 @@
            (when (and (show-status? :name) (not (valid? :name)))
              [:div.error-message (first (messages :name))])
            [:div.explanation
-            [:p "Your group's name will show up in menus and headings. It doesn't need to be formal."]]]]
+            [:p "Your group's name will show up in menus and headings."]
+            [:p "It doesn't need to be formal and can always be changed later."]]]]

          [:div.option.group-url
           {:class (when (show-status? :url)


avoid double-commenting

avoid double-commenting

--- src/chat/server/extensions/asana.clj
+++ src/chat/server/extensions/asana.clj
@@ -1,6 +1,7 @@
 (ns chat.server.extensions.asana
   (:require [clojure.edn :as edn]
             [clojure.data.json :as json]
+            [clojure.string :as string]
             [org.httpkit.client :as http :refer [url-encode]]
             [taoensso.carmine :as car]
             [taoensso.timbre :as timbre]
@@ -196,26 +197,30 @@
                 (db/extension-subscribe (extension :id) thread-id))
               (sync/broadcast-thread thread-id ()))
           (timbre/warnf "No such task %s" resource))))
-    ; TODO: handle changed issue to add a new message to the thread
+
     (timbre/debugf "%s new comments" (count new-comments))
     (let [issue->thread (->> (get-in extension [:config :thread->issue] {})
-                             (into {} (map (fn [[t i]] [i t]))))]
+                             (into {} (map (fn [[t i]] [i t]))))
+          comment-prefix (apply str (take-while (partial not= \%) comment-format-str))]
       (doseq [{:strs [resource parent] :as story} new-comments]
         (if-let [thread-id (issue->thread parent)]
           (let [story-data (-> (fetch-asana-info (extension :id) (str "/stories/" resource))
                                (get "data"))]
-            (timbre/debugf "new comment %s" story story-data)
-            (db/with-conn
-              (db/create-message! {:thread-id thread-id
-                                   :id (db/uuid)
-                                   :content (format issue-comment-format
-                                              (get-in story-data ["created_by" "name"])
-                                              (story-data "text"))
-                                   :user-id (extension :user-id)
-                                   :created-at (java.util.Date.)
-                                   :mentioned-user-ids ()
-                                   :mentioned-tag-ids ()}))
-            (sync/broadcast-thread thread-id ()))
+            (when-not (or (string/blank? (story-data "text"))
+                          (.startsWith (story-data "text") comment-prefix))
+              (timbre/debugf "new comment %s" story story-data)
+              ; TODO: check to make sure comment wasn't one we sent
+              (db/with-conn
+                (db/create-message! {:thread-id thread-id
+                                     :id (db/uuid)
+                                     :content (format issue-comment-format
+                                                (get-in story-data ["created_by" "name"])
+                                                (story-data "text"))
+                                     :user-id (extension :user-id)
+                                     :created-at (java.util.Date.)
+                                     :mentioned-user-ids ()
+                                     :mentioned-tag-ids ()}))
+              (sync/broadcast-thread thread-id ())))
           (timbre/warnf "No existing thread for resource %s" resource))))))

 (defmethod handle-webhook :asana


ensure ClosedByInterruptException is wrapped in an InterruptedException

--- src/clj/backtype/storm/zookeeper.clj
+++ src/clj/backtype/storm/zookeeper.clj
@@ -51,7 +51,10 @@
              (if (or (exception-cause? InterruptedException error)
                      (exception-cause? java.nio.channels.ClosedByInterruptException error))
                (do (log-warn-error error "Zookeeper exception " msg)
-                   (throw error))
+                   (let [to-throw (InterruptedException.)]
+                     (.initCause to-throw error)
+                     (throw to-throw)
+                     ))
                (do (log-error error "Unrecoverable Zookeeper error " msg)
                    (halt-process! 1 "Unrecoverable Zookeeper error")))
              ))))


Sign out button

Sign out button

--- src/cljs/todogo_cljs/components.cljs
+++ src/cljs/todogo_cljs/components.cljs
@@ -26,7 +26,14 @@
              :class menu-class}
        [:ul {:class "nav navbar-nav"}
         [:li
-         [:a {:href "#/about"} "About"]]]]]]))
+         [:a {:href "#/about"} "About"]]]
+       [:ul {:class "nav navbar-nav navbar-right"}
+        [:li
+         (if (.getItem (.-localStorage js/window) "token")
+           [:a {:on-click (fn [] (do (.removeItem (.-localStorage js/window) "token")
+                                     (nav! "/sign-in")))}
+            "Sign out"]
+           )]]]]]))

 (def footer


fix unnamed doclinks to use qualified name when appropriate

--- src/cljs_api_gen/docfile/doclink.clj
+++ src/cljs_api_gen/docfile/doclink.clj
@@ -96,14 +96,18 @@
   ;;    |   |                |
   #"(?<!])\[doc:([^\]]+)\](?![\(\[])")

-(defn get-short-display-name
+(defn get-display-name
   [docname]
-  (let [{:keys [display-as name ns]} (docname->item docname)]
-    (or display-as name ns)))
+  (let [{:keys [display-as full-name name ns type]} (docname->item docname)]
+    (cond
+      display-as display-as
+      (= type "namespace") ns
+      (= ns "cljs.core") name
+      :else full-name)))

 (defn insert-doclink-name
   [[whole-match docname]]
-  (let [name- (get-short-display-name docname)]
+  (let [name- (get-display-name docname)]
     (if (string/includes? name- "`")
       (str "[``" name- "``]" whole-match)
       (str "[`" name- "`]" whole-match))))


Cleanup

Cleanup

--- src/cljs/gtfve/components/maps-canvas/google.cljs
+++ src/cljs/gtfve/components/maps-canvas/google.cljs
@@ -24,7 +24,7 @@

 (defn search-stop-marker [data owner]
   (reify
-    om/IDisplayName (display-name [_] "Stop Marker")
+    om/IDisplayName (display-name [_] "Search Stop Marker")
     om/IInitState
     (init-state [_]
       {:feature-options #js {:id (:stop/id data)


Fix group rendering.

Fix group rendering.

Bug introduced in previous refactor of shapes rendering.

--- src/uxbox/main/ui/shapes/group.cljs
+++ src/uxbox/main/ui/shapes/group.cljs
@@ -45,9 +45,10 @@
         on-mouse-down #(common/on-mouse-down % shape selected)
         on-mouse-up #(common/on-mouse-up % shape)]
     (html
-     [:g.shape {:class (when selected? "selected")
-                :on-mouse-down on-mouse-down
-                :on-mouse-up on-mouse-up}
+     [:g.shape.group-shape
+      {:class (when selected? "selected")
+       :on-mouse-down on-mouse-down
+       :on-mouse-up on-mouse-up}
       (group-shape shape render-component)])))

 (def group-component
@@ -68,12 +69,13 @@
         shapes-by-id (get @st/state :shapes-by-id)
         xf (comp
             (map #(get shapes-by-id %))
-            (remove :hidden)
-            (map factory))]
+            (remove :hidden))]
     (html
      [:g attrs
-      (for [item (reverse (into [] xf items))]
-        (rum/with-key item (str (:id item))))])))
+      (for [item (reverse (into [] xf items))
+            :let [key (str (:id item))]]
+        (-> (factory item)
+            (rum/with-key key)))])))

 (def group-shape
   (mx/component


reduce send-buff window

reduce send-buff window

--- src/pc/http/sente.clj
+++ src/pc/http/sente.clj
@@ -893,7 +893,8 @@
   (let [{:keys [ch-recv send-fn ajax-post-fn connected-uids
                 ajax-get-or-ws-handshake-fn] :as fns} (sente/make-channel-socket!
                                                        sente-web-server-adapter
-                                                       {:user-id-fn #'user-id-fn})]
+                                                       {:user-id-fn #'user-id-fn
+                                                        :send-buf-ms-ws 5})]
     (reset! sente-state fns)
     (setup-ws-handlers fns)
     (track-document-subs)


Randomize initial position of movers.

Randomize initial position of movers.

--- src/videotest/basic_mover/flock.clj
+++ src/videotest/basic_mover/flock.clj
@@ -29,7 +29,7 @@

 (defn init-vehicles [width height n]
   (vec
-   (take n (repeatedly #(random-vehicle width height)))))
+   (take n (repeatedly #(random-vehicle {:width width :height height})))))

 (defn flock [all vehicle]
   (let [sep-factor   1.5


Added type column. Keep timestamp as datetime object.

--- src/com/lemondronor/orbital_detector/createdb.clj
+++ src/com/lemondronor/orbital_detector/createdb.clj
@@ -1,6 +1,7 @@
 (ns com.lemondronor.orbital-detector.createdb
   ""
-  (:require [clojure.java.jdbc :as jdbc]
+  (:require [clj-time.coerce :as timecoerce]
+            [clojure.java.jdbc :as jdbc]
             [com.lemondronor.orbital-detector.planeplotter :as orbdet]))

 (set! *warn-on-reflection* true)
@@ -16,7 +17,7 @@
 (defn create-tables [db]
   (jdbc/db-do-commands
    db
-   "CREATE TABLE IF NOT EXISTS reports (timestamp integer, icao text, registration text, altitude integer, lat real, lon real, speed real, heading real)"))
+   "CREATE TABLE IF NOT EXISTS reports (timestamp integer, icao text, registration text, type text, altitude integer, lat real, lon real, speed real, heading real)"))

    ;; (println (jdbc/create-table-ddl
    ;;  :reports
@@ -36,7 +37,7 @@
       (jdbc/insert!
        t-con
        :reports
-       {:timestamp (long (/ (:timestamp r) 1000))
+       {:timestamp (long (/ (timecoerce/to-long (:timestamp r)) 1000))
         :icao (:icao r)
         :registration (:registration r)
         :altitude (:altitude r)


Fixes memory leak and input issue.

Fixes memory leak and input issue.

The input issue is caused by the fact that the previous screen is
still rendered, even after .setScreen is called. Executing on
the gl thread fixes this.

The documentation says that old screens need to be disposed manually.
This instantly freed up a lot of memory when running my game.

--- src/play_clj/core.clj
+++ src/play_clj/core.clj
@@ -515,20 +515,24 @@
   (let [run-fn! (fn [k & args]
                   (doseq [screen screen-objects]
                     (apply (get screen k) args)))]
-    (.setScreen game-object
-      (reify Screen
-        (show [this]
-          (input! :set-input-processor (InputMultiplexer.))
-          (run-fn! :show)
-          (doseq [{:keys [screen]} screen-objects]
-            (doseq [[_ listener] (:input-listeners @screen)]
-              (add-input! listener))))
-        (render [this d] (run-fn! :render d))
-        (hide [this] (run-fn! :hide))
-        (pause [this] (run-fn! :pause))
-        (resize [this w h] (run-fn! :resize w h))
-        (resume [this] (run-fn! :resume))
-        (dispose [this])))))
+    (when-let [old-screen (.getScreen game-object)]
+      (.dispose old-screen))
+    (on-gl
+     (.setScreen game-object
+                 (reify Screen
+                   (show [this]
+                     (input! :set-input-processor (InputMultiplexer.))
+                     (run-fn! :show)
+
+                     (doseq [{:keys [screen]} screen-objects]
+                       (doseq [[_ listener] (:input-listeners @screen)]
+                         (add-input! listener))))
+                   (render [this d] (run-fn! :render d))
+                   (hide [this] (run-fn! :hide))
+                   (pause [this] (run-fn! :pause))
+                   (resize [this w h] (run-fn! :resize w h))
+                   (resume [this] (run-fn! :resume))
+                   (dispose [this]))))))

 (defn set-screen-wrapper!
   "Sets a function that wraps around all screen functions, allowing you to


updating welcome for basics

updating welcome for basics

--- src/ppl/views/welcome.clj
+++ src/ppl/views/welcome.clj
@@ -1,5 +1,5 @@
 (ns ppl.views.welcome
-  (:require [ppl.views.common :as common]
+  (:require [ppl.templates :as common]
             [noir.content.getting-started])
   (:use [noir.core :only [defpage]]
         [hiccup.core :only [html]])
@@ -11,4 +11,4 @@

 (defpage "/mustache" []
   (render-file "templates/layout"
-             {:name "Donald"}))+             {:name "Donald"}))


Changed dev db back to in-memory db.

Changed dev db back to in-memory db.

--- dev-system/dev/user.clj
+++ dev-system/dev/user.clj
@@ -69,8 +69,8 @@
   ;; MAKE SURE YOU DISABLE SYMANTEC ANTIVIRUS BEFORE STARTING THE TESTS WITH EXTERNAL DB
   ;; Renable them when you're done

-  ; (system/set-dev-system-db-type! :in-memory)
-  (system/set-dev-system-db-type! :external)
+  (system/set-dev-system-db-type! :in-memory)
+  ; (system/set-dev-system-db-type! :external)

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


allow victory

allow victory

--- src/quoridor/core.clj
+++ src/quoridor/core.clj
@@ -85,21 +85,46 @@
                     move)
          (not (contains? (set [current-position other-position]) move)))))

+(defn- black-won?
+  [state]
+  (= (Character/digit (second (state :black)) 10) 8))
+
+(defn- white-won?
+  [state]
+  (= (Character/digit (second (state :white)) 10) 1))
+
+(defn- game-over?
+  [state]
+  (or (black-won? state) (white-won? state)))
+
+(defn- winner
+  [state]
+  (cond
+    (black-won? state) "black"
+    (white-won? state) "white"
+    :else nil))
+
+(defn- print-game-over
+  [state]
+  (println (str "Congrats " (winner state) ", you won!")))
+
 (defn -main
   [& args]
   (loop [current (first black-white)
          next (rest black-white)
          state { :black "e1" :white "e8" :current current }]
     (println (board/render state))
-    (println (str current "'s move: "))
-    (let [move (s/trim (read-line))]
-      (cond
-        (= move "q") (println "Thanks for playing!")
-        (allowed-move? state move) (let [next-player (first next)]
-                                     (recur next-player
-                                            (rest next)
-                                            (-> state
-                                             (assoc (keyword current) move)
-                                             (assoc :current next-player))))
-        :else (do (println (str "Sorry, " move " is not a valid move"))
-                  (recur current next state))))))
+    (if (game-over? state)
+      (print-game-over state)
+      (do (println (str current "'s move: "))
+          (let [move (s/trim (read-line))]
+            (cond
+              (= move "q") (println "Thanks for playing!")
+              (allowed-move? state move) (let [next-player (first next)]
+                                           (recur next-player
+                                                  (rest next)
+                                                  (-> state
+                                                      (assoc (keyword current) move)
+                                                      (assoc :current next-player))))
+              :else (do (println (str "Sorry, " move " is not a valid move"))
+                        (recur current next state))))))))


Add docs for track, track! and dispose!

Add docs for track, track! and dispose!

--- src/reagent/core.cljs
+++ src/reagent/core.cljs
@@ -221,16 +221,31 @@
   ([x & rest] (apply ratom/atom x rest)))

 (defn track
+  "Takes a function and optional arguments, and returns a derefable
+  containing the output of that function. If the function derefs
+  Reagent atoms (or track, etc), the value will be updated whenever
+  the atom changes.
+
+  In other words, @(track foo bar) will produce the same result
+  as (foo bar), but foo will only be called again when the atoms it
+  depends on changes, and will only trigger updates of components when
+  its result changes.
+
+  track is lazy, i.e the function is only evaluated on deref."
   [f & args]
   {:pre [(ifn? f)]}
   (ratom/make-track f args))

 (defn track!
+  "An eager version of track. The function passed is called
+  immediately, and continues to be called when needed, until stopped
+  with dispose!."
   [f & args]
   {:pre [(ifn? f)]}
   (ratom/make-track! f args))

 (defn dispose!
+  "Stop the result of track! from updating."
   [x]
   (ratom/dispose! x))


remove outdated comment

remove outdated comment

--- src/re_com/typeahead.cljs
+++ src/re_com/typeahead.cljs
@@ -41,7 +41,6 @@
 ;; TODO
 ;; ability to focus & blur the input-text would be nice... this is also missing from input-text
 ;; the typeahead should blur the input-text after a selection is chosen
-;; fix passing an initial model value

 (declare debounce display-suggestion)
 (defn- make-typeahead-state


Move comment and readjust format.

Move comment and readjust format.

--- src/re_frame/loggers.cljc
+++ src/re_frame/loggers.cljc
@@ -9,26 +9,28 @@
                            (first args)
                            (str/join " " args)))))

-;; "loggers" holds the current set of logging functions.
-;; By default, re-frame uses the functions provided by js/console.
-;; Use set-loggers! to change these defaults.

 ;; XXX should loggers be put in the registrar ??
-(def ^:private loggers (atom #?(:cljs {:log       (js/console.log.bind   js/console)
-                                       :warn      (js/console.warn.bind  js/console)
-                                       :error     (js/console.error.bind js/console)
-                                       :group     (if (.-group js/console)         ;; console.group does not exist  < IE 11
-                                                    (js/console.group.bind js/console)
-                                                    (js/console.log.bind   js/console))
-                                       :groupEnd  (if (.-groupEnd js/console)        ;; console.groupEnd does not exist  < IE 11
-                                                    (js/console.groupEnd.bind js/console)
-                                                    #())})
-                             ;; clojure versions
-                             #?(:clj {:log      (partial log :info)
-                                      :warn     (partial log :warn)
-                                      :error    (partial log :error)
-                                      :group    (partial log :info)
-                                      :groupEnd  #()})))
+(def ^:private loggers
+  "Holds the current set of logging functions.
+   By default, re-frame uses the functions provided by js/console.
+   Use `set-loggers!` to change these defaults
+  "
+  (atom #?(:cljs {:log       (js/console.log.bind   js/console)
+                  :warn      (js/console.warn.bind  js/console)
+                  :error     (js/console.error.bind js/console)
+                  :group     (if (.-group js/console)         ;; console.group does not exist  < IE 11
+                               (js/console.group.bind js/console)
+                               (js/console.log.bind   js/console))
+                  :groupEnd  (if (.-groupEnd js/console)        ;; console.groupEnd does not exist  < IE 11
+                               (js/console.groupEnd.bind js/console)
+                               #())})
+        ;; clojure versions
+        #?(:clj {:log      (partial log :info)
+                 :warn     (partial log :warn)
+                 :error    (partial log :error)
+                 :group    (partial log :info)
+                 :groupEnd  #()})))

 (defn console
   [level & args]


add comment

add comment

--- src/kalar_plugins/templates/page.clj
+++ src/kalar_plugins/templates/page.clj
@@ -79,6 +79,7 @@
           )))))

 (defn- gen-paginate-page [dir]
+  "dir is the directory where posts are put."
   (letfn [(create-paginate [total paginate-url-pattern]
             (cons "index.html"
                   (map #(str/replace paginate-url-pattern #":num" (str %)) (range 2 (+ 1 total)))))]


Fix measurements slicing for GET.

Fix measurements slicing for GET.

--- src/kixi/hecuba/api/measurements.clj
+++ src/kixi/hecuba/api/measurements.clj
@@ -67,8 +67,20 @@
                    (when (t/before? next-start end)
                      (all-measurements store sensor_id (merge opts {:start next-start :end end}))))))))

+(defn retrieve-measurements
+  "Iterate over a sequence of months and concatanate measurements retrieved from the database."
+  [querier start-date end-date device-id reading-type]
+  (let [range  (time-range start-date end-date (t/months 1))
+        months (map #(util/get-month-partition-key (tc/to-date %)) range)
+        where  [[= :device_id device-id]
+                [= :type reading-type]
+                [>= :timestamp (tc/to-date start-date)]
+                [<= :timestamp (tc/to-date end-date)]]]
+    (mapcat (fn [month] (hecuba/items querier :measurement (conj where [= :month month]))) months)))
+
 (defn measurements-slice-handle-ok [store store-new ctx]
   (let [request                (:request ctx)
+        querier                (:querier store)
         {:keys [route-params
                 query-string]} request
         {:keys [device_id
@@ -76,7 +88,7 @@
         decoded-params         (util/decode-query-params query-string)
         start-date             (util/to-db-format (string/replace (get decoded-params "startDate") "%20" " "))
         end-date               (util/to-db-format (string/replace (get decoded-params "endDate") "%20" " "))
-        measurements           nil ;; TODO
+        measurements           (retrieve-measurements querier start-date end-date device_id reading-type)
         ]
     {:measurements (->> measurements
                         (map (fn [m]
@@ -84,10 +96,6 @@
                                    util/parse-value
                                    (update-in [:timestamp] util/db-to-iso)
                                    (dissoc :month :metadata :device_id)))))}))
-
-
-
-

 (defn- min-date [dt1 dt2]
   (let [dt1' (tc/to-date-time dt1)


Sorted the page of the tag in alphabetical order.

	modified:   src/misaki/compiler/orgmode/core.clj

--- src/misaki/compiler/orgmode/core.clj
+++ src/misaki/compiler/orgmode/core.clj
@@ -135,9 +135,10 @@
   "Get tagged posts data from (:post-dir *config*) directory."
   [tag-name]
   {:pre [(string? tag-name)]}
-  (filter
-   #(post-info-contains-tag? % tag-name)
-   (get-post-data :all? true)))
+  (sort-alphabetically :title
+   (filter
+    #(post-info-contains-tag? % tag-name)
+    (get-post-data :all? true))))

 (defn make-arichves
   "Make post list for archive pages."


changed change-track to use redis-lua

changed change-track to use redis-lua

--- src/server/rooms.cljs
+++ src/server/rooms.cljs
@@ -416,7 +416,7 @@
 (defn change-track [room track-num sound-id callback]
   (println "Chainging track in room " room
            "to" track-num "with sound-id" sound-id)
-  (.eval redis-client "local room_id = ARGV[1] local track_num = ARGV[2] local sound_id = ARGV[3] redis.call('set', 'room:' .. room_id .. ':started?', 'false') redis.call('del', 'room:' .. room_id .. ':sync-start') local num_tracks = redis.call('hlen', 'room:' .. room_id .. ':music-info') if (tonumber(track_num) < 0) or (tonumber(track_num) >= tonumber(num_tracks)) then return nil end redis.call('del', 'room:' .. room_id .. ':track-complete') local track_id = redis.call('hget', 'room:' .. room_id .. ':track-order', track_num) redis.call('set', 'room:' .. room_id .. ':current-track', track_num) redis.call('set', 'room:' .. room_id .. ':current-sound', sound_id) redis.call('set', 'room:' .. room_id .. ':waiting-to-start?', 'true') return track_id "
+  ((.scriptWrap redis-lua "changeTrack")
     0 room track-num sound-id
     (fn [err reply]
       (if-not (nil? reply)


a whole new world

a whole new world

--- ros/angelic_planning/src/ros/world.clj
+++ ros/angelic_planning/src/ros/world.clj
@@ -404,12 +404,16 @@
 	     :height 0.6}

     "bottle" {:xyz [16.3 26.1 0.85] :rpy [0 0 0] :def (get-odwalla)
-	     :type :movable :on "table" :goal nil ;["table" (make-xy-region [17.7 18.0] [26.0 26.2])]
+	     :type :movable :on "table" :goal ["table" (make-xy-region [17.7 18.0] [26.0 26.2])]
 	      :height 0.2}
     "bottle2" {:xyz [16.3 27.0 0.85] :rpy [0 0 0] :def (get-odwalla)
 	     :type :movable :on "table" :goal ["endtable"] #_["table" (make-xy-region [16.21 16.8] [26.2 26.5])] :height 0.2}
     "bottle3" {:xyz [12.4 26.1 0.70] :rpy [0 0 0] :def (get-odwalla)
 	     :type :movable :on "endtable" :goal ["table" ] :height 0.2}
+
+    "bottle4" {:xyz [18.8 26.5 0.85] :rpy [0 0 0] :def (get-odwalla)
+	     :type :movable :on "table" :goal ["table" (make-xy-region [16.21 17.0] [26.1 27.0])]
+	      :height 0.2}
     }
       d3-res d2-res d2-pad))


Fixed args for valid-fire? test

Fixed args for valid-fire? test

--- test/clj/forma/source/fire_test.clj
+++ test/clj/forma/source/fire_test.clj
@@ -40,7 +40,8 @@
   (let [expected-length 12]
     (valid-fire?
      (str "latitude,longitude,brightness,scan,track,acq_date"
-          ",acq_time,satellite,confidence,version,bright_t31,frp"))
+          ",acq_time,satellite,confidence,version,bright_t31,frp")
+     expected-length)
     => false
     (valid-fire? "-16.701,137.752,338.2,1.7,1.3,2012-11-04, 01:25,T,89,5.0       ,298.1,63" expected-length) => true
     (valid-fire? "0.585,100.415,331.3,1.2,1.1,2012-09-18, 06:40,A,84,5.0A,75,5.0       ,302.4,26.3" expected-length) => false))


rename test

rename test

--- test/com/rpl/specter/core_test.cljc
+++ test/com/rpl/specter/core_test.cljc
@@ -1544,7 +1544,7 @@

 ;; this function necessary to trigger the bug from happening
 (defn inc2 [v] (inc v))
-(deftest dynamic-function-arg
+(deftest dynamic-function-arg-test
   (is (= {[2] 4} (let [a 1] (transform (s/keypath [(inc2 a)]) inc {[2] 3}))))
   )


Print newline after error

Print newline after error

--- boot/aether/src/boot/aether.clj
+++ boot/aether/src/boot/aether.clj
@@ -46,7 +46,7 @@
         (->k size))

       (:corrupted :failed)
-      (when err (util/fail (.getMessage err)))
+      (when err (util/fail "%s\n" (.getMessage err)))

       nil)))


Add clj->vim transformation for nil

Add clj->vim transformation for nil

--- src/main/clojure/vimclojure/util.clj
+++ src/main/clojure/vimclojure/util.clj
@@ -232,6 +232,10 @@
   [thing]
   (str thing))

+(defmethod clj->vim nil
+  [_]
+  0)
+
 (defn safe-var-get
   [the-var]
   (when (.isBound the-var)


Simplify row macro.

Simplify row macro.


simplification, router not needed by name


Pass cofx as first parameter when deleting bootnodes

Signed-off-by: Andrea Maria Piana <39e16ece3c2d27e1889178b15ddb376e524032f8@gmail.com>

--- src/status_im/events.cljs
+++ src/status_im/events.cljs
@@ -551,8 +551,8 @@

 (handlers/register-handler-fx
  :bootnodes.ui/delete-pressed
- (fn [_ [_ id]]
-   (bootnodes/show-delete-bootnode-confirmation _ id)))
+ (fn [cofx [_ id]]
+   (bootnodes/show-delete-bootnode-confirmation cofx id)))

 (handlers/register-handler-fx
  :bootnodes.ui/delete-confirmed


code cleanup

code cleanup

--- paredit.clj/src/paredit/core.clj
+++ paredit.clj/src/paredit/core.clj
@@ -450,32 +450,26 @@
                      (assoc-in [:offset] replace-offset)
                      (assoc-in [:length] (count to-raise-text))
                      (update-in [:modifs] conj {:offset replace-offset :length replace-length :text to-raise-text}))
-;                _ (println "new-t:" (pr-str new-t))
              shifted-loc (l/paredit-col-shift {:parse-tree parse-tree
                                                :buffer buffer}
                                               (-> new-t :modifs (nth 0))
                                               to-raise-offset
                                               replace-offset)
-;             _ (println "shifted-loc:" (str "'" (loc-text shifted-loc) "'"))
              shifted-parse-tree (z/root shifted-loc)
              shifted-text (node-text shifted-parse-tree)
              diff (t/text-diff text shifted-text)
-;             _ (println "diff:" (pr-str diff))
              shifted-buffer (edit-buffer buffer (:offset diff) (:length diff) (:text diff))
              shifted-parse-tree (buffer-parse-tree shifted-buffer 0)
              ddiff (nth (:modifs (l/col-shift {:parse-tree parse-tree
                                  :buffer buffer}
                                 diff)) 0)
-;             _ (println "ddiff:" (pr-str ddiff))
-;             _ (println "text:" (str "'" text "'"))
              final-text (if-not ddiff
                           shifted-text
                           (-> text
                             (t/str-replace (:offset ddiff) (:length ddiff) (:text ddiff))
                             (t/str-replace (:offset diff) (:length diff) (:text diff))))
-;             _ (println "final text:" (str "'" final-text "'"))
              ]
-            {:text final-text #_shifted-text
+            {:text final-text
              :offset replace-offset
              :length (+ (:length new-t) (- (count shifted-text)
                                            (count (:text new-t))))


Remove unneeded core.async from project.

--- spectacles/project.clj
+++ spectacles/project.clj
@@ -4,15 +4,11 @@
   :license {:name "Apache License 2.0"
             :url "http://www.apache.org/licenses/LICENSE-2.0"}
   :dependencies [[org.clojure/clojure "1.6.0"]
-                 [org.clojure/core.async "0.2.374"]
                  [quil "2.3.0"]
                  [clj-time "0.11.0"]]
-
-
   :resource-paths [
                    ;; Wordmaps / WordCram
                    "resources/wordcram/library/WordCram.jar"
                    "resources/wordcram/library/cue.language.jar"
                    "resources/wordcram/library/jsoup-1.7.2.jar"
-                   ]
-  )
+                   ])


Adde clj-time as a dependency. I need to process time series so eventually you need a good librairy for that specific task 	modified:   loganalyzer/project.clj


in (defn json-value-converter), convert postgres arrays to clojure vectors

--- src/babel/reader.clj
+++ src/babel/reader.clj
@@ -462,6 +462,12 @@

     (string? v)
     (keyword v)
+
+    (= (type v)
+       org.postgresql.jdbc.PgArray)
+    (vec (.getArray v))
+
+
     :else v))


Fix concat implementation.

Fix concat implementation.

--- src/beicon/core.cljc
+++ src/beicon/core.cljc
@@ -565,9 +565,9 @@
   sequences, as long as the previous observable
   sequence terminated successfully."
   [& more]
-  #?(:cljs (let [more (reverse (cljs.core/filter identity more))]
+  #?(:cljs (let [more (cljs.core/filter identity more)]
              (cljs.core/reduce #(.concat %1 %2) more))
-     :clj  (let [more (reverse (clojure.core/filter identity more))]
+     :clj  (let [more (clojure.core/filter identity more)]
              (clojure.core/reduce (fn [^Observable a ^Observable b]
                                     (Observable/concat a b))
                                   more))))


functions for handling commands as strings

--- src/text_stream/edits.clj
+++ src/text_stream/edits.clj
@@ -1,11 +1,5 @@
 (ns text-stream.edits
   (:gen-class))
-
-(defn perform
-  "Performs the `edits` (in the manner defined by the `consolidate` function)
-  on the provided `source-map`."
-  [edits source-map]
-  ((consolidate edits) source-map))

 (defn consolidate
   "Takes a seq of edits and composes them into a single function. Applies from
@@ -13,6 +7,12 @@
   with `cons`."
   [edits]
   (apply comp edits))
+
+(defn perform
+  "Performs the `edits` (in the manner defined by the `consolidate` function)
+  on the provided `source-map`."
+  [edits source-map]
+  ((consolidate edits) source-map))

 (defn cursor
   "Produces an edit function which moves the cursor to index `position-index`
@@ -26,7 +26,6 @@
   the current cursor position."
   [text-insertion]
   (fn [source-map]
-    (println "insert into:" source-map)
     (let [old-text (:text source-map)
           cursor (:pos source-map)
           new-text (str
@@ -41,7 +40,6 @@
   the text from the current cursor position (backwards)."
   [deletion-count]
   (fn [source-map]
-    (println "delete from" source-map)
     (let [old-text (:text source-map)
           cursor (:pos source-map)
           new-position (- cursor deletion-count)
@@ -60,5 +58,49 @@

 (defn initial-text
   [text]
-  ((insert-text text)
+  ((insert text)
    {:pos 0 :text ""}))
+
+(def commands
+  "Note: all commands happen to be 6 characters.
+  We'll exploit this later."
+  {"inited" initial-text
+   "insert" insert
+   "delete" delete
+   "cursor" cursor})
+
+(def cmd-len "Length of commands." 6)
+
+(def cmd-validators
+  "Functions which convert a string to fit type expected by command,
+  or, if not possible, return `nil`."
+  (let [parse-int #(try (Integer/parseInt %)
+                       (catch NumberFormatException _ nil))]
+    {;; inited requires a different function, as it is only valid as the
+     ;; first message in a stream
+     initial-text (fn [_ _] nil)
+     insert (fn [in _] (and (string? in) in))
+     delete (fn [in source-map]
+              (if-let [n (parse-int in)]
+                (and (<= (:pos source-map) n) n)))
+     cursor (fn [in source-map]
+              (if-let [n (parse-int in)]
+                (and (<= (count (:text source-map))) n)))}))
+
+(defn valid-command?
+  "Is this a valid command? Returns the command string."
+  [text]
+  (and (>= (count text) (inc cmd-len))
+       (let [cmd (subs text 0 cmd-len)]
+         (and
+          (contains? commands cmd)
+          cmd))))
+
+(defn process-text-command
+  [text source-map]
+  (if-let [cmd (valid-command? text)]
+    (let [func (get commands cmd)
+          text-input (subs text cmd-len)]
+      (if-let [valid-input ((get cmd-validators func)
+                            text-input source-map)]
+        ((func valid-input) source-map)))))


add with-context!

add with-context!

--- src/cake/project.clj
+++ src/cake/project.clj
@@ -53,9 +53,18 @@
   (if-let [context (get-in *opts* [:context 0])]
     (symbol context)))

+(defn project-with-context [context]
+  (merge-in project-root
+            (assoc (context *context*)
+              :context context)))
+
 (defmacro with-context [context & forms]
   `(let [context# (symbol (name (or ~context (:context *project*))))]
-     (binding [*project* (merge-in project-root
-                                   (assoc (context# *context*)
-                                     :context context#))]
+     (binding [*project* (project-with-context context#)]
        ~@forms)))
+
+(defmacro with-context! [context & forms]
+  `(let [context# (symbol (name (or ~context (:context *project*))))]
+     (alter-var-root #'*project* (fn [_#] (project-with-context context#)))
+     (do ~@forms)
+     (alter-var-root #'*project* project-root)))


made board functions pure

made board functions pure

--- src/client/core.cljs
+++ src/client/core.cljs
@@ -56,32 +56,41 @@

 (defn read-board
   "Get the current value from the given board position."
-  [x y]
-  (get-in @state [:board y x]))
+  [x y board]
+  (get-in board [y x]))

 (defn coord-inside?
   [x y]
   (and (<= 0 x 9) (<= 0 y 21)))

-(defn write-to-board!
-  "Writes a given value to the x,y position on the board."
-  [ x y value ]
+(defn write-to-board
+  "Returns a new board with a value written to the given position."
+  [x y value board]
   (if (coord-inside? x y)
-    (swap! state assoc-in [:board y x] value)))
+    (assoc-in board [y x] value)
+    board))

-(defn write-coord-to-board!
-  [[cx cy] x y]
-    (write-to-board! (+ cx x) (+ cy y) 1))
+(defn write-coord-to-board
+  "Returns a new board with a value written to the given relative coordinate and position."
+  [[cx cy] x y value board]
+    (write-to-board (+ cx x) (+ cy y) value board))

-(defn write-piece-to-board!
-  "Writes a given piece to the board."
-  [piece x y]
-  (doall (map #(write-coord-to-board! % x y) piece)))
+(defn write-coords-to-board
+  "Returns a new board with a value written to the given relative coordinates and position."
+  [coords x y value board]
+  (if (zero? (count coords))
+    board
+    (let [coord (first coords)
+          rest-coords (rest coords)
+          new-board (write-coord-to-board coord x y value board)]
+      (recur rest-coords x y value new-board))))

-(defn clear-board!
-  "Clears the board."
-  []
-  (swap! state assoc :board empty-board))
+(defn write-piece-to-board
+  "Returns a new board with a the given piece written to the coordinate on the board."
+  [piece-key x y board]
+  (let [value piece-key
+        coords (piece-key pieces)]
+    (write-coords-to-board coords x y value board)))

 (defn rotate-piece
   "Create a new piece by rotating the given piece clockwise."
@@ -90,21 +99,21 @@

 (defn coord-empty?
   "Determines if the given coordinate on the board is empty."
-  [x y]
-  (zero? (read-board x y)))
+  [x y board]
+  (zero? (read-board x y board)))

 (defn coord-fits?
   "Determines if the given relative coordinate fits at the position on the board."
-  [[cx cy] x y]
+  [[cx cy] x y board]
   (let [abs-x (+ x cx)
         abs-y (+ y cy)]
     (and (coord-inside? abs-x abs-y)
-         (coord-empty? abs-x abs-y))))
+         (coord-empty? abs-x abs-y board))))

 (defn piece-fits?
   "Determines if the given piece will collide with anything in the current board."
-  [piece x y]
-  (every? #(coord-fits? % x y) piece))
+  [piece x y board]
+  (every? #(coord-fits? % x y board) piece))

 ; ------------------------------------------------------------
 ; DRAWING FUNCTIONS
@@ -118,19 +127,22 @@
     (aset canvas "height" (* sq-size 22))))

 (defn draw-cell
-  [ctx x y]
-  (let [color (get-cell-color (read-board x y))
+  "Draw the given cell of the given board."
+  [ctx x y board]
+  (let [color (get-cell-color (read-board x y board))
         left (* sq-size x)
         top  (* sq-size y)]
-
     (aset ctx "fillStyle" color)
     (.fillRect ctx left top sq-size sq-size)))

-(defn draw-board []
+(defn draw-board
+  "Draw the given board to the canvas."
+  [board]
   (let [canvas (.getElementById js/document "canvas")
         ctx    (.getContext canvas "2d")]
-    (doall (for [x (range 10) y (range 22)]
-      (draw-cell ctx x y)))))
+    (doseq [x (range 10) y (range 22)]
+      (draw-cell ctx x y board))
+    nil))

 (defn auto-refresh
   "Automatically refresh the page whenever a cljs file is compiled."
@@ -142,7 +154,7 @@
 (defn init []
   (connect-repl)
   (size-canvas)
-  (draw-board)
+  (draw-board (:board @state))

   (auto-refresh)
   )


throw error on nil io input

throw error on nil io input

--- src/clj_money/io.clj
+++ src/clj_money/io.clj
@@ -6,6 +6,9 @@

 (defn read-bytes
   [input]
+  (when (nil? input)
+    (throw (IllegalArgumentException. "input is required")))
+
   (with-open [out (ByteArrayOutputStream.)]
     (io/copy input out)
     (.toByteArray out)))


Tidy up -main.

Tidy up -main.

--- src/clojars/core.clj
+++ src/clojars/core.clj
@@ -1,21 +1,22 @@
 (ns clojars.core
-  (:use ring.adapter.jetty
+  (:use [ring.adapter.jetty :only [run-jetty]]
         [clojars.web :only [clojars-app]])
-  (:require clojars.scp)
+  (:require [clojars.scp])
   (:import com.martiansoftware.nailgun.NGServer
            java.net.InetAddress)
   (:gen-class))

-(defn -main [& [http-port ng-port]]
-  (if (not (and http-port ng-port))
-    (do (.println System/err "Usage: clojars.core http-port nailgun-port")
-        (.println System/err "   eg: clojars.core 8080 8701"))
-    (do
-      (println "clojars-web: starting jetty on port" http-port)
-      (run-jetty clojars-app {:port (Integer/parseInt http-port) :join? false})
-      (println "clojars-web: starting nailgun on 127.0.0.1 port " ng-port)
-      (.run (NGServer. (InetAddress/getByName "127.0.0.1")
-                       (Integer/parseInt ng-port))))))
+(defn -main
+  ([]
+     (.println System/err "Usage: clojars.core http-port nailgun-port")
+     (.println System/err "   eg: clojars.core 8080 8701")
+     (System/exit 1))
+  ([http-port ng-port]
+     (println "clojars-web: starting jetty on port" http-port)
+     (run-jetty clojars-app {:port (Integer/parseInt http-port) :join? false})
+     (println "clojars-web: starting nailgun on 127.0.0.1 port " ng-port)
+     (.run (NGServer. (InetAddress/getByName "127.0.0.1")
+                      (Integer/parseInt ng-port)))))

 ; (defonce server (run-jetty #'clojars-app {:port 8080 :join? false}))


Typo fix: added a missing 'do'.

Typo fix: added a missing 'do'.

--- src/clojars/core.clj
+++ src/clojars/core.clj
@@ -8,8 +8,8 @@

 (defn -main [& [http-port ng-port]]
   (if (not (and http-port ng-port))
-    (.println System/err "Usage: clojars.core http-port nailgun-port")
-    (.println System/err "   eg: clojars.core 8080 8701")
+    (do (.println System/err "Usage: clojars.core http-port nailgun-port")
+        (.println System/err "   eg: clojars.core 8080 8701"))
     (do
       (println "clojars-web: starting jetty on port" http-port)
       (run-server {:port (Integer/parseInt http-port)}


Updated Image for rb site

Updated Image for rb site

--- src/redbrick_20/components/data.cljs
+++ src/redbrick_20/components/data.cljs
@@ -3,11 +3,16 @@

 (def supporting-deails (reagent/atom {
     :title "Time To Have a Birthday Party!"
-    :text "This year marks our 20th birthday. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
-    tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris
-    nisi ut aliquip ex ea commodo consequat.
-    Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
-    occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
+    :text " Hear ye! Hear ye! Let the calls of \"RESIIIGN\" toll through the lands, for
+            today is a day of celebration! The twentieth anniversary of the honourable
+            Redbrick society has arrived! Over the past twenty years, DCU's Networking
+            Society has been through a lot, and now is the time to remember, and to
+            party! Meet the Redbrick heroes and villains from over the years, and
+            party with the current networking stock; share horror stories, and make
+            fun of the admins who broke everything with the best of them. So dust off
+            your networking goggles, and get ready to see regrettable drunk pictures
+            from the past 20 years! See you on the 9th April 2016, to eat, drink, be
+            merry, and party like it's 1996!."
   }))

 (def event-details (reagent/atom {
@@ -28,7 +33,7 @@
     society, they were allowed to setup a temporary home for the server in the Computer Applications facility, going online in the
     postgrad area on March 5th, 1996 as dcuns.compapp.dcu.ie. Later, the society received its own subnet and subdomain of dcu.ie
     from the Computer Services Department."
-    :supporting-image "http://www.pixempire.com/images/preview/power-on-computer-icon.jpg"
+    :supporting-image "http://wiki.redbrick.dcu.ie/mw/images/9/91/Rbwiki_RedbrickLogo_tiny_logo.gif"
   }
   {
     :year 1997
@@ -74,8 +79,7 @@
   }
   {
     :year 2002
-    :supporting-data "This entire wiki section just seems like bloat nothing of real society relevance happens or at least that
-                      is what I've gathered from this."
+    :supporting-data "Redbrick gets a new logo."
     :supporting-image "http://wiki.redbrick.dcu.ie/mw/images/2/29/Rbwiki_RedbrickLogo_logo2-rb.gif"
   }
   {
@@ -164,9 +168,10 @@
   }
   {
     :year 2015
-    :supporting-data "Redbrick Returns to FOSDEM there was cheers, tears and far far too many beer's.
-                      The admins realized Redbrick isnt as reziliant as once thought. Rob didnt resgin!
-                      TechWeek is held in the mezz, We got Speakers from AOL, Intercom, Google, Amazon and our lovely Associates :)"
+    :supporting-data "Redbrick returns to FOSDEM! There were cheers, tears and far far too many beers.
+                      The admins realised that Redbrick isn't as resilient as once thought. Rob didn't resign!
+                      TechWeek is held in the mezz; we got speakers from AOL, Intercom, Google, Amazon, and
+                      our lovely associates :)"
     :supporting-image "https://pbs.twimg.com/profile_images/378800000547772739/6069389b75cc1ae0d2ab8a0ebac9bec8_400x400.png"
   }
   ])


Can remove the null protection.

Can remove the null protection.

It turns out the only reason that the descriptions were null was a bug
in CoreMIDI4J; other libraries crash when encountering such devices too.
So I moved the fix to CoreMIDI4J.

--- src/afterglow/midi.clj
+++ src/afterglow/midi.clj
@@ -761,8 +761,8 @@
     (let [pattern (if (= (class name-filter) Pattern)
                     name-filter
                     (Pattern/compile (Pattern/quote (str name-filter)) Pattern/CASE_INSENSITIVE))]
-      (filter #(or (re-find pattern (or (:name %1) ""))
-                   (re-find pattern (or (:description %1) "")))
+      (filter #(or (re-find pattern (:name %1))
+                   (re-find pattern (:description %1)))
               devices))))

 (defn current-clock-sources


fix bug in access key logic

fix bug in access key logic

--- src/wombats/datomic/db_functions.clj
+++ src/wombats/datomic/db_functions.clj
@@ -175,40 +175,45 @@
                                          :in $ ?access-key-key
                                          :where [?access-key :access-key/key ?access-key-key]]
                                        db access-key-key)))
-                 valid-access-key? (and
-                                    ;; Access key exists
-                                    access-key
-                                    ;; Access key has not reached max uses
-                                    (< (:access-key/number-of-uses access-key)
-                                       (:access-key/max-number-of-uses access-key))
-                                    ;; Access key has not expired
-                                    (< (.getTime (new java.util.Date))
-                                       (.getTime (:access-key/expiration-date access-key))))
+                 valid-access-key (and
+                                   ;; Access key exists
+                                   access-key
+                                   ;; Access key has not reached max uses
+                                   (< (:access-key/number-of-uses access-key)
+                                      (:access-key/max-number-of-uses access-key))
+                                   ;; Access key has not expired
+                                   (< (.getTime (new java.util.Date))
+                                      (.getTime (:access-key/expiration-date access-key))))
                  current-user (ffirst
                                (d/q '[:find ?user
                                       :in $ ?github-id
                                       :where [?user :user/github-id ?github-id]]
                                     db github-id))
                  current-user-id (get current-user :user/id)
-                 user-update (cond-> {:user/github-access-token github-access-token
-                                      :user/access-token user-access-token
-                                      :user/github-username github-username
-                                      :user/github-id github-id
-                                      :user/avatar-url avatar-url}
-                               (and access-key
-                                    (nil? (:user/access-key current-user)))
-                               (assoc :user/access-key (:db/id access-key)))]
+                 user-update {:db/id (d/tempid :db.part/user)
+                              :user/id (.toString (java.util.UUID/randomUUID))
+                              :user/roles [:user.roles/user]
+                              :user/github-access-token github-access-token
+                              :user/access-token user-access-token
+                              :user/github-username github-username
+                              :user/github-id github-id
+                              :user/avatar-url avatar-url}
+                 should-add-access-key (boolean (and valid-access-key
+                                                     (nil? (:user/access-key current-user))))]
+
              (cond-> []
-               (nil? current-user-id)
-               (conj (merge user-update
-                            {:db/id (d/tempid :db.part/user)
-                             :user/id (.toString (java.util.UUID/randomUUID))
-                             :user/roles [:user.roles/user]}))
+               (and (nil? current-user-id)
+                    should-add-access-key)
+               (conj (assoc user-update :user/access-key (:db/id access-key)))
+
+               (and (nil? current-user-id)
+                    (not should-add-access-key))
+               (conj user-update)

                (some? current-user-id)
                (conj (merge user-update {:user/id current-user-id}))

-               valid-access-key?
+               should-add-access-key
                (conj {:access-key/key (:access-key/key access-key)
                       :access-key/number-of-uses (inc (:access-key/number-of-uses access-key))})))}))


Prevent app thread from being flooded during output piping

--- src/net/sekao/nightcode/builders.clj
+++ src/net/sekao/nightcode/builders.clj
@@ -28,6 +28,7 @@
                       (-> engine
                           (.executeScript "window")
                           (.call "append" (into-array [s])))))
+                  (Thread/sleep 100) ; prevent application thread from being flooded
                   (recur))))))))))

 (defn create-pipes []


Fix npe

Fix npe

--- src/net/sekao/nightcode/projects.clj
+++ src/net/sekao/nightcode/projects.clj
@@ -175,14 +175,14 @@
 (fdef update-project-buttons!
   :args (s/cat :state map? :scene spec/scene?))
 (defn update-project-buttons! [state ^Scene scene]
-  (let [rename-button (.lookup scene "#rename")
-        remove-button (.lookup scene "#remove")
-        path (:selection state)
-        file (io/file path)]
-    (.setDisable rename-button (not (.isFile file)))
-    (.setDisable remove-button
-      (and (not (contains? (:project-set state) path))
-        (not (.isFile file))))))
+  (when-let [path (:selection state)]
+    (let [rename-button (.lookup scene "#rename")
+          remove-button (.lookup scene "#remove")
+          file (io/file path)]
+      (.setDisable rename-button (not (.isFile file)))
+      (.setDisable remove-button
+        (and (not (contains? (:project-set state) path))
+          (not (.isFile file)))))))

 (fdef move-project-tree-selection!
   :args (s/cat :scene spec/scene? :diff integer?))


backout js/Date extension to IEquiv, this is an interop liability.


Update invite-teammates related tests

Update invite-teammates related tests

--- test-cljs/frontend/controllers/test_controls.cljs
+++ test-cljs/frontend/controllers/test_controls.cljs
@@ -209,10 +209,17 @@
   (let [calls (atom [])
         project-name "proj"
         vcs-type "github"
-        invitees ["me@foo.com", "you@bar.co"]
+        invitees [{:handle "me"
+                   :email "me@foo.com"
+                   :provider_id 666
+                   :name "Me"}
+                  {:handle "you"
+                   :email "you@bar.co"
+                   :provider_id 667
+                   :name "You"}]
         control-data {:project-name project-name
                       :org-name "org"
-                      :invitees ["me@foo.com", "you@bar.co"]}
+                      :invitees invitees}
         api-ch "api-ch"
         current-state {:comms {:api api-ch}}]
     (testing "the post-control-event invite-github-users calls button-ajax with the correct parameters"
@@ -227,18 +234,25 @@
           (is (= (nth args 2) :invite-team-members))
           (is (= (nth args 3) api-ch))
           (is (= (->> (nth args 4) (apply hash-map) :context) {:project project-name
-                                                              :first_green_build true}))
+                                                               :first_green_build true}))
           (is (= (->> (nth args 4) (apply hash-map) :params) invitees)))))))

 (deftest post-control-event-invited-team-members-invites-users-for-bb-projects
   (let [calls (atom [])
         project-name "proj"
         vcs-type "bitbucket"
-        invitees ["me@foo.com", "you@bar.co"]
+        invitees [{:handle "me"
+                   :email "me@foo.com"
+                   :provider_id 666
+                   :name "Me"}
+                  {:handle "you"
+                   :email "you@bar.co"
+                   :provider_id 667
+                   :name "You"}]
         control-data {:project-name project-name
                       :vcs-type vcs-type
                       :org-name "org"
-                      :invitees ["me@foo.com", "you@bar.co"]}
+                      :invitees invitees}
         api-ch "api-ch"
         current-state {:comms {:api api-ch}}]
     (testing "the post-control-event invite-github-users does nothing for bitbucket projects"


More index tests

More index tests


Fix regex

Fix regex

Former-commit-id: 8c648d597aec593ab1fe82ea059d3f1ed86f328c

--- planck-cljs/src/planck/core.cljs
+++ planck-cljs/src/planck/core.cljs
@@ -87,7 +87,7 @@
   (let [namespace-candidates (map str
                                (keys (:cljs.analyzer/namespaces @planck.core/st)))
         top-form? (re-find #"^\s*\(\s*[^()\s]*$" buffer)
-        typed-ns (second (re-find #"(\b[a-zA-Z-.]+)\/[a-zA-Z-]+$" buffer))
+        typed-ns (second (re-find #"(\b[a-zA-Z-.]+)/[a-zA-Z-]+$" buffer))
         all-candidates (set (if typed-ns
                               (completion-candidates-for-ns (symbol typed-ns) false)
                               (concat namespace-candidates


remove (parse) from here; add later possibly  - for now, just use language-specific workbooks

--- src/babel/workbook.clj
+++ src/babel/workbook.clj
@@ -45,16 +45,6 @@
    [dag_unify.core :refer [get-in remove-false strip-refs unify]]
    [hiccup.core :refer [html]]
 ))
-
-;; TODO: move (parse) and (expr) to separate namespace: 'workbook/useful-user-functions' or something.
-;; TODO: add other languages (English and Spanish)
-(defn parse [string]
-  (concat
-   (eng/parse string)
-;   (esg/parse string)
-;   (fr/parse string)
-;   (it/parse string)))
-   ))

 (defn expr [id]
   (reader/id2expression (Integer. id)))