Got the code fragment hover code working by splitting the mega-component into simpler ones (but there is still a weird rendering issue affecting performance)

--- src/day8/re_frame_10x/view/event.cljs
+++ src/day8/re_frame_10x/view/event.cljs
@@ -11,69 +11,6 @@
                    [day8.re-frame-10x.utils.re-com :refer [handler-fn]]))

 (def code-border (str "1px solid " common/white-background-border-color))
-
-
-(def current-code
-  (reagent/atom
-    (list
-      {:title ":event/handler",
-       :id    1,
-       :code  [{:id           0
-                :form         'dissoc
-                :result       dissoc
-                :indent-level 1}
-               {:id           1
-                :form         'todos
-                :result       {3 {:id 3, :title "abc", :done false},
-                               4 {:id 4, :title "abc", :done true},
-                               5 {:id 5, :title "def", :done true},
-                               6 {:id 6, :title "abc", :done false},
-                               7 {:id 7, :title "add", :done false}}
-                :indent-level 1}
-               {:id           2
-                :form         'todos
-                :result       {3 {:id 3, :title "abc", :done false},
-                               4 {:id 4, :title "abc", :done true},
-                               5 {:id 5, :title "def", :done true},
-                               6 {:id 6, :title "abc", :done false},
-                               7 {:id 7, :title "add", :done false}}
-                :indent-level 4}
-               {:id           3
-                :form         '(vals todos)
-                :result       '({:id 3, :title "abc", :done false},
-                                 {:id 4, :title "abc", :done true},
-                                 {:id 5, :title "def", :done true},
-                                 {:id 6, :title "abc", :done false},
-                                 {:id 7, :title "add", :done false})
-                :indent-level 3}
-               {:id           4
-                :form         '(filter :done)
-                :result       '({:id 4 :title "abc" :done true}
-                                 {:id 5 :title "def" :done true})
-                :indent-level 2}
-               {:id           5
-                :form         '(map :id)
-                :result       '(4 5)
-                :indent-level 1}
-               {:id           6
-                :form         '(reduce dissoc todos)
-                :result       {3 {:id 3, :title "abc", :done false},
-                               6 {:id 6, :title "abc", :done false},
-                               7 {:id 7, :title "add", :done false}}
-                :indent-level 1}
-               {:id           7
-                :form         '(->> (vals todos)
-                                    (filter :done)
-                                    (map :id)
-                                    (reduce dissoc todos))
-                :result       {3 {:id 3, :title "abc", :done false},
-                               6 {:id 6, :title "abc", :done false},
-                               7 {:id 7, :title "add", :done false}}
-                :indent-level 1}]
-       :form  '(->> (vals todos)
-                    (filter :done)
-                    (map :id)
-                    (reduce dissoc todos))})))

 (def event-styles
@@ -98,8 +35,31 @@
    ])

+;; Terminology:
+;; Form: a single Clojure form (may have nested children)
+;; Result: the result of execution of a single form
+;; Fragment: the combination of a form and result
+;; Listing: a block of traced Clojure code, e.g. an event handler function
+
+
+(defn no-event-instructions
+  []
+  [rc/v-box
+   :children [#_[:span.bm-heading-text.light-heading event-str]
+              [rc/p {:style {:font-style "italic"}} "Code trace is not currently available for this event"]
+              [:br]
+              [rc/p "This panel can show the actual code of the event along with all of it's intermediate values."]
+              [rc/p "To get to this magic going, you need to make a few adjustments to your project:"]
+              [:ol
+               [:li [rc/p "Add " [:span.bold "[day8.re-frame/debux \"0.5.0-SNAPSHOT\"]"] " to the :dev :dependencies section in project.clj"]]
+               [:li [rc/p "Add " [:span.bold "\"debux.cs.core.trace_enabled_QMARK_\" true"] " to the :closure-defines section in project.clj"]]
+               [:li [rc/p "Add " [:span.bold "[debux.cs.core :refer-macros [fn-traced]]"] " to the :require section of the event code file(s)"]]
+               [:li [rc/p "Replace " [:span.bold "fn"] " with " [:span.bold "fn-traced"] " in the events to be traced in this panel"]]]]])
+
+
 (defn code-header
   [code-execution-id line]
+  (println ">>>>>> code-header:" (:id line))
   (let [open?-path [@(rf/subscribe [:epochs/current-epoch-id]) code-execution-id (:id line)]
         open?      (get-in @(rf/subscribe [:code/code-open?]) open?-path)]
     [rc/h-box
@@ -123,7 +83,8 @@

 (defn code-block
-  [code-execution-id line i] ;; TODO: can remove i and use () instead but left here for now in case DC removes that in the :code/current-code sub
+  [code-execution-id line]
+  ;(println ">>>>>> code-block:" (:id line))
   [rc/box
    :style {:background-color "rgba(100, 255, 100, 0.08)"
            :border           code-border
@@ -131,106 +92,84 @@
            :overflow-x       "auto"
            :overflow-y       "hidden"
            :padding          "0px 3px"}
-   :child [components/simple-render (:result line) [@(rf/subscribe [:epochs/current-epoch-id]) code-execution-id i]]])
+   :child [components/simple-render (:result line) [@(rf/subscribe [:epochs/current-epoch-id]) code-execution-id (:id line)]]])

-(defn event-panel-instructions
-  []
-  (let [current-event @(rf/subscribe [:epochs/current-event])
-        event-str     (if (some? current-event)
-                        (subs (prn-str current-event) 0 400)
-                        "No event")]
-    [rc/v-box
-     :children [[:span.bm-heading-text.light-heading event-str]
-                [rc/p {:style {:font-style "italic"}} "Code trace is not currently available for this event"]
-                [:br]
-                [rc/p "This panel can show the actual code of the event along with all of it's intermediate values."]
-                [rc/p "To get to this magic going, you need to make a few adjustments to your project:"]
-                [:ol
-                 [:li [rc/p "Add " [:span.bold "[day8.re-frame/debux \"0.5.0-SNAPSHOT\"]"] " to the :dev :dependencies section in project.clj"]]
-                 [:li [rc/p "Add " [:span.bold "\"debux.cs.core.trace_enabled_QMARK_\" true"] " to the :closure-defines section in project.clj"]]
-                 [:li [rc/p "Add " [:span.bold "[debux.cs.core :refer-macros [fn-traced]]"] " to the :require section of the event code file(s)"]]
-                 [:li [rc/p "Replace " [:span.bold "fn"] " with " [:span.bold "fn-traced"] " in the events to be traced in this panel"]]]]]))
+(defn event-expression
+  [form]
+  (let [highlighted-form @(rf/subscribe [:code/highlighted-form])
+        form-str         (zp/zprint-str form)
+        search-str       highlighted-form
+        start            (str/index-of form-str search-str)
+        length           (if (some? search-str)
+                           (count (pr-str search-str))
+                           0)
+        before           (subs form-str 0 start)
+        end-index        (+ start length)
+        highlight        (subs form-str start end-index)
+        after            (subs form-str end-index)]
+    ;(println ">> event-expression:" (pr-str (subs (pr-str highlighted-form) 0 30)))
+    ; DC: We get lots of React errors if we don't force a creation of a new element when the highlight changes. Not really sure why...
+    ^{:key (pr-str highlighted-form)}
+    [rc/box
+     :style {:max-height (str (* 10 17) "px") ;; Add scrollbar after 10 lines
+             ;:overflow-x "auto"
+             :overflow-y "auto" ;; TODO: Need to overwrite some CSS in the components/highlight React component to get the horizontal scrollbar working properly
+             ;:border     "1px solid #e3e9ed"
+             ;:background-color "white"
+             }
+
+     :child (if (some? highlighted-form)
+              [components/highlight {:language "clojure"}
+               (list ^{:key "before"} before
+                     ^{:key "hl"} [:span.code-listing--highlighted highlight]
+                     ^{:key "after"} after)]
+              [components/highlight {:language "clojure"}
+               form-str])
+     #_#_:child [:pre form-str]
+     ]))

-;; Terminology:
-;; Form: a single Clojure form (may have nested children)
-;; Result: the result of execution of a single form
-;; Fragment: the combination of a form and result
-;; Listing: a block of traced Clojure code, e.g. an event handler function
+(defn event-fragments
+  [fragments code-exec-id]
+  ;(println ">> event-fragments - count:" (count fragments))
+  (let [code-open? @(rf/subscribe [:code/code-open?])]
+    [rc/v-box
+     :size     "1"
+     :style    {:overflow-y "auto"}
+     :children (doall
+                 (for [frag fragments]
+                   (let [id (:id frag)]
+                     ^{:key id}
+                     [rc/v-box
+                      :class    "code-fragment"
+                      :style    {:margin-left (str (* 9 (dec (:indent-level frag))) "px")
+                                 :margin-top  (when (pos? id) "-1px")}
+                      :attr     {:on-mouse-enter (handler-fn #_(println "OVER:" (:id frag)) (rf/dispatch [:code/hover-form (:form frag)]))
+                                 :on-mouse-leave (handler-fn #_(println " OUT:" (:id frag)) (rf/dispatch [:code/exit-hover-form (:form frag)]))}
+                      :children [[code-header code-exec-id frag]
+                                 (when (get-in code-open? [@(rf/subscribe [:epochs/current-epoch-id]) code-exec-id id])
+                                   [code-block code-exec-id frag id])]])))]))

-(defn event-code []
-  (let [code-traces      @(rf/subscribe [:code/current-code]) ;; TODO: Try @current-code to see indents, then delete when real indents implemented
-        code-open?       @(rf/subscribe [:code/code-open?])
-        highlighted-form @(rf/subscribe [:code/highlighted-form])
+
+(defn event-code
+  []
+  (let [code-traces      @(rf/subscribe [:code/current-code])
+        code-execution   (first code-traces) ;; Ignore multiple code executions for now
+        highlighted-form (rf/subscribe [:code/highlighted-form])
         debug?           @(rf/subscribe [:settings/debug?])]
-    (if (empty? code-traces)
-      [event-panel-instructions]
+    ;(println "EVENT-CODE")
+    (if-not code-execution
+      [no-event-instructions]
       [rc/v-box
        :size "1 1 auto"
        :class "code-panel"
-       :children
-       [#_(when debug? [:pre "Hover " (pr-str highlighted-form) "\n"])
-        (doall
-          (for [code-execution code-traces]
-            ^{:key (:id code-execution)}
-            [rc/v-box
-             :size "1 1 auto"
-             :gap common/gs-19s
-             :children
-             (let [form       (:form code-execution)
-                   form-str   (zp/zprint-str form)
-                   search-str highlighted-form
-                   start      (str/index-of form-str search-str)
-                   length     (if (some? search-str)
-                                (count (pr-str search-str))
-                                0)
-                   before     (subs form-str 0 start)
-                   end-index  (+ start length)
-                   highlight  (subs form-str start end-index)
-                   after      (subs form-str end-index)]
-               [
-                ;; We get lots of React errors if we don't force a creation of a new element
-                ;; when the highlight changes. Not really sure why...
-                ^{:key (pr-str highlighted-form)}
-                [rc/box
-                 :style {:max-height (str (* 10 17) "px") ;; Add scrollbar after 10 lines
-                         ;:overflow-x "auto"
-                         :overflow-y "auto" ;; TODO: Need to overwrite some CSS in the components/highlight React component to get the horizontal scrollbar working properly
-                         }
-                 :child (if (some? highlighted-form)
-                          [components/highlight {:language "clojure"}
-                           (list ^{:key "before"} before
-                                 ^{:key "hl"} [:span.code-listing--highlighted highlight]
-                                 ^{:key "after"} after)]
-                          [components/highlight {:language "clojure"}
-                           form-str])]
-                [rc/v-box
-                 :size     "1"
-                 :style    {:overflow-y "auto"}
-                 :children (doall
-                             (->> (:code code-execution)
-                                  ;; Remove traced function values, these are usually not very interesting in and of themselves.
-                                  (remove (fn [line] (fn? (:result line))))
-                                  (map-indexed ;; TODO: Can remove map-indexed because we insert :id in the :code/current-code sub (but DC may change that so left it here for now)
-                                    (fn [i line]
-                                      (list
-                                        ;; See https://github.com/reagent-project/reagent/issues/350 for why we use random-uuid here
-                                        ^{:key (random-uuid)}
-                                        [rc/v-box
-                                         :class "code-fragment"
-                                         :style {:margin-left (str (* 9 (dec (:indent-level line))) "px")
-                                                 :margin-top  (when (pos? i) "-1px")}
-                                         ;; on-mouse enter/leave fires fewer events (only on enter/leave of outer form)
-                                         ;; but the events don't seem to be reliably sent in order.
-                                         ;; Instead we use pointer-events: none on the children of the code fragments
-                                         ;; to prevent lots of redundant events.
-                                         :attr {:on-mouse-enter (handler-fn (rf/dispatch [:code/hover-form (:form line)]))
-                                                :on-mouse-leave  (handler-fn (rf/dispatch [:code/exit-hover-form (:form line)]))}
-                                         :children [[code-header (:id code-execution) line]
-                                                    ;; TODO: disable history expansion, or at least storing of it in ls.
-                                                    (when (get-in code-open? [@(rf/subscribe [:epochs/current-epoch-id]) (:id code-execution) (:id line)])
-                                                      [code-block (:id code-execution) line i])]])))))]])]))]])))
+       :children [(when debug? [:pre "Hover " (pr-str @highlighted-form) "\n"])
+                  [event-expression (:form code-execution)]
+                  [rc/gap-f :size common/gs-19s]
+                  [event-fragments (->> (:code code-execution)
+                                        (remove (fn [line] (fn? (:result line)))))
+                   (:id code-execution)]]])))

 (defn render []


added proximal

added proximal

--- src/distributions/core.clj
+++ src/distributions/core.clj
@@ -31,14 +31,18 @@
         p-double (double-array p)]
     (new EnumeratedIntegerDistribution x-int p-double)))
 (defn exponential
-  [mean]
-  (new ExponentialDistribution mean))
+  [rate]
+  (new ExponentialDistribution (/ 1 rate)))
 (defn f-distribution
   [df1 df2]
   (new FDistribution df1 df2))
 (defn gamma
   [shape rate]
   (new GammaDistribution shape (/ 1 rate)))
+(defrecord GeneralizedDoubleParetoDistribution [shape scale])
+(defn gdp
+  [shape scale]
+  (GeneralizedDoubleParetoDistribution. shape scale))
 (defn geometric
   [p]
   (new GeometricDistribution p))
@@ -49,11 +53,11 @@
   [population-size number-successes sample-size]
   (new HypergeometricDistribution population-size number-successes sample-size))
 (defn laplace
-  [location scale]
-  (new LaplaceDistribution location scale))
+  [location rate]
+  (new LaplaceDistribution location (/ 1 rate)))
 (defn double-exponential
-  [location scale]
-  (laplace location scale))
+  [location rate]
+  (laplace location rate))
 (defn levy
   [location scale]
   (new LevyDistribution location scale))
@@ -79,7 +83,7 @@
      (mvnormal mean variance))))
 (defn normal
   [mean variance]
-  (new NormalDistribution mean (Math/sqrt variance)))
+  (new NormalDistribution mean (sqrt variance)))
 (defn pareto
   [scale shape]
   (new ParetoDistribution scale shape))
@@ -122,8 +126,12 @@
   (P
     ([d] (fn [x] (.probability d x)))
     ([d x] (.probability d x)))
-  )
-
+  GeneralizedDoubleParetoDistribution
+  (P
+    ([d] (fn [x] 0))
+    ([d x] 0)
+    )
+  )
 (defprotocol density-function
   (pdf [d] [d x])
   (log-pdf [d] [d x]))
@@ -140,7 +148,7 @@
     ([d x] (/ (pdf (new TDistribution (:df d)) (/ (- x (:location d)) (:scale d))) (:scale d)))
     ([d] (fn [x] (pdf d x))))
   (log-pdf
-    ([d x] (- (log-pdf (new TDistribution (:df d)) (/ (- x (:location d)) (:scale d))) (Math/log (:scale d)) ))
+    ([d x] (- (log-pdf (new TDistribution (:df d)) (/ (- x (:location d)) (:scale d))) (log (:scale d)) ))
     ([d] (fn [x] (log-pdf d x))))
   MultivariateNormalDistribution
   (log-pdf
@@ -156,8 +164,18 @@
        ))
     ([d] (fn [x] (log-pdf d x))))
   (pdf
-    ([d x] (Math/exp (log-pdf d x)))
-    ([d] (fn [x] (pdf d x))))
+    ([d x] (exp (log-pdf d x)))
+    ([d] (fn [x] (pdf d x))))
+  GeneralizedDoubleParetoDistribution
+  (pdf
+    ([d x] (exp (log-pdf d x)))
+    ([d] (fn [x] (pdf d x))))
+  (log-pdf
+    ([d x]
+     (let [shape (:shape d)
+           scale (:scale d)]
+       (- (log 0.5) (log scale) (* (inc shape) (log (inc (/ (abs x) (* shape scale)) ))))))
+    ([d] (fn [x] (log-pdf d x))))
   )

 (defprotocol mass-function
@@ -243,6 +261,15 @@

 (def probit (cdf (normal 0 1)))

+(defprotocol location-scale
+  (rate [d])
+  (location [d]))
+(extend-protocol location-scale
+  RealDistribution
+  (rate [d] (/ 1 (.getScale d)))
+  (location [d] (.getLocation d))
+  )
+
 (defprotocol second-central-moment
   (variance [d]))
 (extend-protocol second-central-moment
@@ -256,6 +283,32 @@
   RealDistribution
   (variance [d] (.getNumericalVariance d))
   )
+
+(defn inv [x] (/ 1 x))
+
+(defprotocol proximal
+  (prox [d] [d h x]))
+(extend-protocol proximal
+  NormalDistribution
+  (prox
+    ([d] (fn [h x] (* x (/ (inv h) (+ (inv h) (inv (variance d)))))))
+    ([d h x] ((prox d) h x)))
+  LaplaceDistribution
+  (prox
+    ([d] (fn [h x] (* (signum x) (max 0.0 (- (abs x) (* h (rate d)))))))
+    ([d h x] ((prox d) h x)))
+  GeneralizedDoubleParetoDistribution
+  (prox
+    ([d]
+     (let [shape (:shape d)
+           scale (:scale d)]
+       (fn [h x]
+         (let [g (* h (inc shape))
+               a (* shape scale)
+               d (max 0 (- (* a (abs x)) g))]
+           (* 0.5 (signum x) (+ (abs x) (negate a) (sqrt (+ (* 4 d) (square (- a (abs x)))))))))))
+    ([d h x]
+     ((prox d) h x))))

 (defprotocol random
   (sample [d] [d n]))
@@ -284,6 +337,16 @@
            D (diagonal-matrix (map (fn [x] (sqrt (max x 0))) S))]
        (add mean-vector (mmul U D z))))
     ([d n] (take n (repeatedly #(sample d)))))
+  GeneralizedDoubleParetoDistribution
+  (sample
+    ([d]
+     (let [shape (:shape d)
+           scale (:scale d)
+           eta (* shape scale)
+           lambda (sample (gamma shape eta))
+           tau (sample (exponential (/ (square lambda) 2)))]
+       (sample (normal 0 tau))))
+    ([d n] (take n (repeatedly #(sample d)))))
   )

 (defn expectation
@@ -320,3 +383,5 @@
          grid (map (icdf d) (range delta 1 delta))
          f_i (map f grid)]
      (/ (reduce + 0 f_i) n))))
+
+


GAWB-1435: tsv entity download now POST and accepts columns as form data (#615)

* tsv entity download now POST and accepts columns as form data

* Use ref instead of element ID

* using semantic submit input instead of ref

* include FCtoken in tsv download post

--- src/cljs/org/broadinstitute/firecloud_ui/page/workspace/data/tab.cljs
+++ src/cljs/org/broadinstitute/firecloud_ui/page/workspace/data/tab.cljs
@@ -187,21 +187,29 @@
                             [:div {:style {:display "flex" :alignItems "center" :marginBottom "1em"}}
                              (map layout (vals built-in))
                              (when-let [selected-entity-type (some-> (:selected-entity-type @state) name)]
-                               [:a {:style {:textDecoration "none" :margin "7px .3em 0 0"}
-                                    :href (str (config/api-url-root) "/cookie-authed/workspaces/"
-                                               (:namespace workspace-id) "/"
-                                               (:name workspace-id) "/entities/" selected-entity-type "/tsv"
-                                               "?attributeNames="
-                                               (->> (persistence/try-restore
-                                                     {:key (str (common/workspace-id->string workspace-id) ":data:" selected-entity-type)
-                                                      :initial (constantly {})})
-                                                    :column-meta
-                                                    (filter :visible?)
-                                                    (map :header)
-                                                    (clojure.string/join ",")))
-                                    :onClick #(u/set-access-token-cookie (u/get-access-token))
-                                    :target "_blank"}
-                                (str "Download '" (clojure.string/replace selected-entity-type ":" "") "' data")])
+                               [:form {:target "_blank"
+                                       :method "POST"
+                                       :action (str (config/api-url-root) "/cookie-authed/workspaces/"
+                                                    (:namespace workspace-id) "/"
+                                                    (:name workspace-id) "/entities/" selected-entity-type "/tsv")}
+                                [:input {:type "hidden"
+                                         :name "FCtoken"
+                                         :value (u/get-access-token)}]
+                                [:input {:type "hidden"
+                                         :name "attributeNames"
+                                         :value (->> (persistence/try-restore
+                                                      {:key (str (common/workspace-id->string
+                                                                  workspace-id) ":data:" selected-entity-type)
+                                                       :initial (constantly {})})
+                                                     :column-meta
+                                                     (filter :visible?)
+                                                     (map :header)
+                                                     (clojure.string/join ","))}]
+                                [:input {:style {:border "none" :backgroundColor "transparent" :cursor "pointer"
+                                                 :color (:button-primary style/colors) :fontSize "inherit" :fontFamily "inherit"
+                                                 :padding 0 :marginLeft "1em"}
+                                         :type "submit"
+                                         :value (str "Download '" selected-entity-type "' data")}]])
                              [:div {:style {:flexGrow 1}}]
                              [:div {:style {:paddingRight ".5em"}}
                               [comps/Button {:text "Import Data..."


Removing demo code

Removing demo code

--- src/scad_demo/core.clj
+++ src/scad_demo/core.clj
@@ -1,11 +0,0 @@
-(ns scad-demo.core
-  (:use [scad-clj.scad])
-  (:use [scad-clj.model]))
-
-(def primitives
-  (union
-   (union)
-   (->> (sphere 50))))
-
-(spit "post-demo.scad"
-      (write-scad primitives))


don't allow mentioning non-member contacts in public chat (#13227)

--- src/status_im/chat/models/mentions.cljs
+++ src/status_im/chat/models/mentions.cljs
@@ -247,7 +247,10 @@
       (merge mentionable-users
              (mentionable-contacts-from-identites all-contacts public-key (keys community-members)))

-      :else (merge mentionable-users mentionable-contacts))))
+      (= chat-type constants/public-chat-type)
+      (merge mentionable-users (select-keys mentionable-contacts (keys mentionable-users)))
+
+      :else mentionable-users)))

 (def ending-chars "[\\s\\.,;:]")
 (def ending-chars-regex (re-pattern ending-chars))


Disallow BookKeeper loopback unless running a local quorum

--- src/onyx/state/bookkeeper.clj
+++ src/onyx/state/bookkeeper.clj
@@ -27,6 +27,8 @@
           _ (zk/create (:conn log) ledgers-available-path :persistent? true)
           base-journal-dir (arg-or-default :onyx.bookkeeper/base-journal-dir env-config)
           base-ledger-dir (arg-or-default :onyx.bookkeeper/base-ledger-dir env-config)
+          ;; allow loopback? only if running a local quorum
+          allow-loopback? (boolean (arg-or-default :onyx.bookkeeper/local-quorum? env-config))
           server-id (str onyx-id "_" port)
           journal-dir (str base-journal-dir "/" server-id)
           ledger-dir (str base-ledger-dir "/" server-id)
@@ -36,7 +38,7 @@
                         (.setBookiePort port)
                         (.setJournalDirName journal-dir)
                         (.setLedgerDirNames (into-array String [ledger-dir]))
-                        (.setAllowLoopback true))
+                        (.setAllowLoopback allow-loopback?))
           server (BookieServer. server-conf)
           _ (info "Starting BookKeeper server on port" port)
           _ (.start server)]


Minor alerts demo tweaking

Minor alerts demo tweaking

--- src/re_demo/alerts.cljs
+++ src/re_demo/alerts.cljs
@@ -21,12 +21,13 @@
        :children [[v-box
                    :gap      "10px"
                    :style    {:font-size "small"}
-                   :children [[component-title"[alert-box ... ]"]
+                   :children [[component-title "[alert-box ... ]"]
                               [label :label "A component which renders a single alert-box."]
                               [args-table   alert-box-args-desc]]]
                   [v-box
-                   :gap "10px"
-                   :children [[component-title  "Demo"]
+                   :width    "500px"
+                   :gap      "10px"
+                   :children [[component-title "Demo"]
                               (if @show-alert
                                 [alert-box
                                  :id         1
@@ -36,10 +37,7 @@
                                  :closeable? true
                                  :on-close   #(reset! show-alert false)]
                                 [:p {:style {:text-align "center" :margin "30px"}} "[You closed me]"])
-
-                              [:br]
-                              [:br]
-                              [:br]
+                              [gap :size "50px"]
                               [:p "Further Variations ..."]
                               (when @show-alert1
                                 [:div
@@ -52,14 +50,15 @@
                                 [:div
                                  [alert-box
                                   :alert-type "warning"
-                                  :body       "Alert with :body but no :heading (:padding set to 4px)"
-                                  :padding    "4px"
+                                  :body       "Alert with :body but no :heading (:padding set to 6px)."
+                                  :padding    "6px"
                                   :closeable? true
                                   :on-close   #(reset! show-alert2 false)]])
                               [alert-box
                                :alert-type "danger"
                                :heading    ":alert-type is \"danger\""
-                               :body       [:span "This is the :body of an danger-styled alert with :closeable? omitted (defaults to false). " [:a {:href "http://google.com" :target "_blank"} "Link to Google"]]]]]]])))
+                               :body       [:span "This is the :body of an danger-styled alert with :closeable? omitted (defaults to false). "
+                                            [:a {:href "http://google.com" :target "_blank"} "Link to Google"] "."]]]]]])))

 (defn add-alert
@@ -71,9 +70,9 @@
 (defn alert-list-demo
   []
   (let [alerts       (reagent/atom [])]
-    (add-alert alerts 0 "danger"  {:heading "Woa! something bad happened" :body "Next time you should take more care!  Next time you should take more care! Next time you should take more care!"})
-    (add-alert alerts 1 "info"    {:heading "News Flash!" :body "The rain in Spain often falls on the mountatins too"})
-    (add-alert alerts 2 "info"    {:heading "Here's some info" :body "The rain in Spain falls mainly on the plain"})
+    (add-alert alerts 0 "danger"  {:heading "Woa! something bad happened" :body "Next time you should take more care! Next time you should take more care! Next time you should take more care!"})
+    (add-alert alerts 1 "info"    {:heading "News Flash!" :body "The rain in Spain often falls on the mountatins too."})
+    (add-alert alerts 2 "info"    {:heading "Here's some info" :body "The rain in Spain falls mainly on the plain."})
     (add-alert alerts 3 "warning" {:heading "\"Oh bother\", said Pooh. And then ..." :body "\"Some people care too much. I think it's called love.\""})

     (fn []
@@ -86,8 +85,9 @@
                               [label :label "A component which renders a list of alert-boxes vertically."]
                               [args-table   alert-list-args-desc]]]
                   [v-box
-                   :gap "10px"
-                   :children [[component-title  "Demo"]
+                   :width    "500px"
+                   :gap      "10px"
+                   :children [[component-title "Demo"]
                               [:p "Press the 'Add alert' button to add some more."]
                               [:p ":max-height is set to 300px and a custom 'dotted' :border-style is set in this case."]
                               [alert-list


devtools now also understands component actions without tagging them

--- src/frontend/devtools.cljs
+++ src/frontend/devtools.cljs
@@ -65,7 +65,7 @@
               ; Notification signal is needed, for instance, to hit persistence middleware to save new component model.
               (-> (dispatch ::replay)
                   :component
-                  (component-control ::on-did-replay #(:component (dispatch [::component %])))))
+                  (component-control ::on-did-replay #(:component (dispatch %)))))

             (handle-component-signal
               [model]
@@ -165,6 +165,7 @@
                  (update m :action-events #(filter :enabled? %))
                  (update m :signal-events #(remove (partial -orphaned-signal? m) %)))

+           ; component action coming from specific signal
            [::component signal-id a]
            (as-> model m
                  (update m :component component-reconcile a)
@@ -172,12 +173,12 @@
                  (update m :next-action-id inc))

            ; for bare component actions (e.g. when dispatching from REPL) create an "unknown signal" event
-           [::component a]
-           (let [[signal-id _ :as unknown-signal-event] (-signal-event (:next-signal-id model) :-unknown-signal)]
+           :else
+           (let [[signal-id _ :as unknown-signal-event] (-signal-event (:next-signal-id model) ::unknown-signal)]
              (-> model
                  (update :signal-events concat [unknown-signal-event])
                  (update :next-signal-id inc)
-                 (reconcile [::component signal-id a]))))))
+                 (reconcile [::component signal-id action]))))))

 ;;;;;;;;;;;;;;;;;;;;;;;; View model
 (defn -wrap-view-model


fix the typo

fix the typo

--- src/riemann/elastic.clj
+++ src/riemann/elastic.clj
@@ -104,7 +104,7 @@
   range component of the index name.  Acceptable values
   are :hour, :day, :week, :month and :year.

-  Events will be massages to conform to Kubana expections.  This means
+  Events will be massages to conform to Kibana expections.  This means
   that the `@timestamp` field will be set if not found, based on the
   `time` field of the event.  The `ttl` field will be removed, as it's
   internal to Riemann.  Lastly, any fields starting with an `_` will


Work on common typing

Work on common typing

--- src/robinson/common.clj
+++ src/robinson/common.clj
@@ -10,11 +10,12 @@
 (t/ann ^:no-check taoensso.timbre/refer-timbre [-> t/Any])
 (timbre/refer-timbre)

-(t/ann uniform-int (t/Fn [Integer -> Integer]
-                         [Integer Integer -> Integer]))
+(t/ann ^:no-check clojure.data.generators/uniform [Long Long -> Long])
+(t/ann uniform-int (t/IFn [Long -> Long]
+                          [Long Long -> Long]))
 (defn uniform-int
- ([hi] (uniform-int 0 hi))
- ([lo hi] {:pre [(< lo hi)]} (int (dg/uniform lo hi))))
+ ([hi] {:pre [(pos? hi)]} (uniform-int 0 hi))
+ ([lo hi] {:pre [(< lo hi)]} (dg/uniform lo hi)))

 (defmacro log-time
   "Log the time it takes to execute body."
@@ -24,6 +25,7 @@
        (println ~msg)
        result#)))

+(t/ann log-io (t/All [x y ...] [String [y ... y -> x] -> [y ... y -> x]]))
 (defn log-io
   "Log function inputs and outputs by wrapping an function f."
   [msg f]
@@ -68,9 +70,10 @@
     [arg [sym] condition form else-form]
     (arg-if- 'clojure.core/-> arg sym condition form else-form)))

+(t/ann vec-match? [(t/Vec t/Any) (t/Vec t/Any) -> Boolean])
 (defn vec-match?
   [test-expr expr]
-  (let [arg-match? (fn [[test-term term]]
+  (let [arg-match? (t/fn [[test-term term] :- (t/I (t/Vec t/Any) (t/ExactCount 2))] :- Boolean
     (cond
       (fn? test-term)  (test-term term)
       (= :* test-term) true
@@ -83,47 +86,53 @@
   `(condp vec-match? ~match
      ~@body))

+(t/ann noun->indefinite-article (t/Pred String))
 (defn noun->indefinite-article [noun] (if (contains? #{\a \e \i \o \u} (first noun))
                                         "an"
                                         "a"))
 (t/defalias Pos (t/HMap :mandatory {:x Integer :y Integer}))

-(t/ann pos->xy (t/Fn [Pos -> (t/Vec Number)]))
+(t/ann pos->xy (t/IFn [Pos -> (t/Vec Number)]))
 (defn pos->xy
   [{x :x y :y}]
   [x y])

-(t/ann xy->pos (t/Fn [Number Number -> Pos]))
+(t/ann xy->pos (t/IFn [Number Number -> Pos]))
 (defn xy->pos
   [x y]
   {:x x :y y})

-(t/ann chebyshev-distance (t/Fn [Pos Pos -> Number]))
+(t/ann chebyshev-distance (t/IFn [Pos Pos -> Number]))
 (defn chebyshev-distance
   "Chebyshev/chessboard distance between 2 points"
   [p1 p2]
   (max (Math/abs (- (:x p1) (:x p2)))
        (Math/abs (- (:y p1) (:y p2)))))

-(t/ann distance-sq (t/Fn [Pos Pos -> Number]))
+(t/ann distance-sq (t/IFn [Pos Pos -> Number]))
 (defn distance-sq
   [p1 p2]
   (let [sq (fn [x] (* x x))]
   (+ (sq (- (:x p1) (:x p2)))
      (sq (- (:y p1) (:y p2))))))

-(t/ann distance (t/Fn [Pos Pos -> Number]))
+(t/ann distance (t/IFn [Pos Pos -> Number]))
 (defn distance
   "Euclidean distance between 2 points"
   [p1 p2]
   (Math/sqrt (distance-sq p1 p2)))

-(t/ann farther-than? (t/Fn [Pos Pos Number -> Boolean]))
+(t/ann farther-than? [Pos Pos Number -> Boolean])
 (defn farther-than?
   "Are the two points farther in distance than l?"
   [p1 p2 l]
   (> (distance-sq p1 p2) (* l l)))

+(t/ann fill-missing (t/All [x y z] (t/IFn [(t/Pred x)
+                                           (t/IFn [x y -> z])
+                                           (t/Seq y)
+                                           (t/Seq x) -> (t/Seq z)])))
+
 (defn fill-missing
   "For each item in coll for which (pred item) returns true, replace that
    element with the result of (f item vcoll-item) where vcoll-item
@@ -160,6 +169,8 @@
                             (cons (f x y) (if (empty? xs) [] (fill-missing pred f ys xs)))
                             (cons x (if (empty? xs) [] (fill-missing pred f vcoll xs)))))))

+(t/ann fn-in (t/All[x]
+               [[t/Any x -> t/Any] (t/Map t/Any t/Any) (t/Vec t/Any) -> x]))
 (defn fn-in
   "Applies a function to a value in a nested associative structure and an input value.
    ks sequence of keys and v is the second arguement to f. The nested value will be
@@ -167,14 +178,20 @@
   [f m ks v]
   (update-in m ks (fn [coll] (f coll v))))

+(t/ann concat-in (t/All [x]
+                   (t/IFn [x (t/Vec t/Any) t/Any -> x])))
 (defn concat-in
   [m ks v]
   (fn-in concat m ks v))

+(t/ann conj-in (t/All [x]
+                 (t/IFn [x (t/Vec t/Any) t/Any -> x])))
 (defn conj-in
   [m ks v]
   (fn-in conj m ks v))

+(t/ann map-in (t/All [x]
+                [x (t/Vec t/Any) [t/Any -> t/Any] -> x]))
 (defn map-in
   [m ks f]
   (fn-in (fn [coll _] (if (vector? coll)
@@ -182,6 +199,9 @@
                         (map f coll)))
          m ks nil))

+(t/ann reduce-in (t/All [x]
+                   (t/IFn [x (t/Vec t/Any) (t/IFn [t/Any -> t/Any]) -> x]
+                         [x (t/Vec t/Any) (t/IFn [t/Any -> t/Any]) t/Any -> x])))
 (defn reduce-in
   "Reduce a value inside an associative datastructure. `more` can be either
   a reducing function, a reducting function and an initial value."
@@ -190,30 +210,32 @@
   ([m ks f v]
    (update-in m ks (fn [coll] (reduce f v coll)))))

+(t/ann filter-in (t/All [x]
+                   (t/IFn [x (t/Vec t/Any) (t/IFn [t/Any -> t/Any]) -> x])))
 (defn filter-in
   [m ks f]
   (fn-in (fn [coll _] (if (vector? coll)
                         (vec (filter f coll))
                         (filter f coll))) m ks nil))

+(t/ann remove-in (t/All [x]
+                   [x (t/Vec t/Any) [t/Any -> t/Any] -> x]))
 (defn remove-in
   [m ks f]
   (fn-in (fn [coll _] (if (vector? coll)
                         (vec (remove f coll))
                         (remove f coll))) m ks nil))

+(t/ann some-in (t/All [x]
+                 (t/IFn [x (t/Vec t/Any) (t/IFn [t/Any -> t/Any]) -> x])))
 (defn some-in
   [m ks f]
   (fn-in (fn [coll _] (if (vector? coll)
                         (vec (some f coll))
                         (some f coll))) m ks nil))

-(defn remove-in
-  [m ks f]
-  (fn-in (fn [coll _] (if (vector? coll)
-                        (vec (remove f coll))
-                        (remove f coll))) m ks nil))
-
+(t/ann update-in-matching (t/All [a b]
+                            (t/IFn [a (t/Vec t/Any) (t/IFn [b -> Boolean]) (t/IFn [b -> t/Any]) -> a])))
 (defn update-in-matching
   [m ks p f]
   (if (fn? p)
@@ -305,7 +327,7 @@
                                :npcs (t/Vec Npc)}))
 (t/defalias State (HMap :mandatory {:world World :screen t/Any}))

-(t/ann append-log (t/Fn [State String -> State]
+(t/ann append-log (t/IFn [State String -> State]
                         [State String t/Kw -> State]))
 (defn append-log
   "Append a message to the in-game log. The last five log messages are retained."
@@ -320,17 +342,17 @@
                                     :time (-> state :world :time)
                                     :color color}]))))))

-(t/ann ui-hint (t/Fn [State String -> State]))
+(t/ann ui-hint (t/IFn [State String -> State]))
 (defn ui-hint
   [state msg]
   (assoc-in state [:world :ui-hint] msg))

-(t/ann clear-ui-hint (t/Fn [State String -> State]))
+(t/ann clear-ui-hint (t/IFn [State String -> State]))
 (defn clear-ui-hint
   [state]
   (ui-hint state nil))

-(t/ann wrap-line (t/Fn [Integer String -> (t/Vec String)]))
+(t/ann wrap-line (t/IFn [Integer String -> (t/Vec String)]))
 (defn wrap-line [size text]
   (loop [left size line [] lines []
          words (clojure.string/split text #"\s+")]


PCP-24 Check if we have a connection before closing it

Here we check more carefully for our not-connected sentinel in
`:websocket-connection` so we can avoid calling
(gniazdo.core/close client) on something that is not a connection.

--- src/puppetlabs/pcp/client.clj
+++ src/puppetlabs/pcp/client.clj
@@ -47,7 +47,8 @@
           :handlers Handlers
           :should-stop Object ;; promise that when delivered means should stop
           :websocket-client Object
-          :websocket-connection Object}))
+          :websocket-connection Object ;; atom of a promise that will be a connection or true
+          }))

 ;; connection state checkers
 (s/defn ^:always-validate state :- (s/pred ws-state?)
@@ -118,7 +119,7 @@
   "Send a message across the websocket session"
   [client :- Client message :- message/Message]
   (let [{:keys [identity websocket-connection]} client]
-    (if-not (realized? @websocket-connection)
+    (if-not (and (realized? @websocket-connection) (not (= true @@websocket-connection)))
       (throw+ {:type ::not-connected})
       (ws/send-msg @@websocket-connection
                    (message/encode (assoc message :sender identity))))
@@ -194,7 +195,7 @@
         client (merge params {:identity (make-identity cert type)
                               :state (atom :connecting :validator ws-state?)
                               :websocket-client (make-websocket-client params)
-                              :websocket-connection (atom (future "To be a connection later"))
+                              :websocket-connection (atom (future true))
                               :handlers handlers
                               :should-stop (promise)})
         {:keys [websocket-connection]} client]
@@ -214,11 +215,12 @@
   "Close the connection"
   [client :- Client]
   (let [{:keys [should-stop websocket-client websocket-connection]} client]
+    ;; NOTE:  This true value is also the sentinel for make-connection
     (deliver should-stop true)
     (when (contains? #{:opening :open} (state client))
       (log/debug "Closing")
       (reset! (:state client) :closing)
       (.stop websocket-client))
-    (when (realized? @websocket-connection)
-      (ws/close @@websocket-connection))
-    true))
+    (if (and (realized? @websocket-connection) (not (= true @@websocket-connection)))
+      (ws/close @@websocket-connection)))
+  true)


Exercise 3.28, 3.29

Exercise 3.28, 3.29

--- src/sicp/chapter3_3.clj
+++ src/sicp/chapter3_3.clj
@@ -1057,6 +1057,79 @@
           (recur (rest keys) (node-subtree subtable))))))
   :ok)

+;; Exercise 3.27
+;; TODO
+
 ;;; 3.3.4  A Simulator for Digital Circuits

+(declare get-signal set-signal! add-action!
+         after-delay inverter-delay and-gate-delay or-gate-delay
+         make-wire)
+
+(defn logical-not [s]
+  (case s
+    0 1
+    1 0
+    (throw (IllegalArgumentException. (str "Invalid signal " s)))))
+
+(defn inverter [input output]
+  (letfn [(invert-input []
+            (let [new-value (logical-not (get-signal input))]
+              (after-delay inverter-delay
+                           #(set-signal! output new-value))))]
+    (add-action! input invert-input)
+    :ok))
+
+(defn logical-and [s1 s2]
+  (case [s1 s2]
+    [0 0] 0
+    [0 1] 0
+    [1 0] 0
+    [1 1] 1
+    (throw (IllegalArgumentException. (str "Invalid signal "
+                                           {:s1 s1 :s2 s2})))))
+
+(defn and-gate [a1 a2 output]
+  (letfn [(and-action-procedure []
+            (let [new-value (logical-and (get-signal a1)
+                                         (get-signal a2))]
+              (after-delay and-gate-delay
+                           #(set-signal! output new-value))))]
+    (add-action! a1 and-action-procedure)
+    (add-action! a2 and-action-procedure)
+    :ok))
+
+;; Exercise 3.28
+(defn logical-or [s1 s2]
+  (case [s1 s2]
+    [0 0] 0
+    [0 1] 1
+    [1 0] 1
+    [1 1] 1
+    (throw (IllegalArgumentException. (str "Invalid signal "
+                                           {:s1 s1 :s2 s2})))))
+
+(defn or-gate [a1 a2 output]
+  (letfn [(or-action-procedure []
+            (let [new-value (logical-or (get-signal a1)
+                                        (get-signal a2))]
+              (after-delay or-gate-delay
+                           #(set-signal! output new-value))))]
+    (add-action! a1 or-action-procedure)
+    (add-action! a2 or-action-procedure)
+    :ok))
+
+;; Exercise 3.29
+(defn or-gate' [a1 a2 output]
+  (let [b1 (make-wire)
+        b2 (make-wire)
+        c (make-wire)]
+    (inverter a1 b1)
+    (inverter a2 b2)
+    (and-gate b1 b2 c)
+    (inverter c output)
+    :ok))
+
+;; the delay time of or-gate' = 2 * inverter-delay + and-gate-delay
+
 ;;; 3.3.5  Propagation of Constraints


bump cljs to 1.7.228

bump cljs to 1.7.228

--- src/leiningen/new/aemette/project.clj
+++ src/leiningen/new/aemette/project.clj
@@ -2,7 +2,7 @@
   :description "FIXME: write this!"
   :url "http://example.com/FIXME"
   :dependencies [[org.clojure/clojure "1.7.0"]
-                 [org.clojure/clojurescript "1.7.170"]
+                 [org.clojure/clojurescript "1.7.228"]
                  [org.omcljs/om {{#om-legacy}}"0.9.0"{{/om-legacy}}{{^om-legacy}}"1.0.0-alpha28"{{/om-legacy}}]
                  [org.clojure/core.async "0.2.374"]
                  [secretary "1.2.3"]]


Add types for skipped and pending tests

Add types for skipped and pending tests

--- src/main/clojure/lazytest/results.clj
+++ src/main/clojure/lazytest/results.clj
@@ -1,10 +1,16 @@
 (ns lazytest.results
-  (:use [lazytest.plan :only (example?)]))
+  "Any object encapsulating results of a single test must implement
+  the TestResult protocol.  The record types defined here should be
+  created with the constructor functions pass, fail, throw, skip, and
+  pending."
+  (:use [lazytest.arguments :only (nil-or)]
+	[lazytest.plan :only (example?)]))

 (defprotocol TestResult
   (success? [r] "True if this result and all its children passed.")
   (pending? [r] "True if this is the result of an empty test.")
   (error? [r] "True if this is the result of a thrown exception.")
+  (skipped? [r] "True if this is the result of a skipped test.")
   (container? [r] "True if this is a container for other results."))

 (defrecord TestResultContainer [source children]
@@ -12,6 +18,7 @@
     (success? [this] (every? success? children))
     (pending? [this] (if (seq children) false true))
     (error? [this] false)
+    (skipped? [this] false)
     (container? [this] true))

 (defrecord TestPassed [source states]
@@ -19,6 +26,7 @@
     (success? [this] true)
     (pending? [this] false)
     (error? [this] false)
+    (skipped? [this] false)
     (container? [this] false))

 (defrecord TestFailed [source states]
@@ -26,6 +34,7 @@
     (success? [this] false)
     (pending? [this] false)
     (error? [this] false)
+    (skipped? [this] false)
     (container? [this] false))

 (defrecord TestThrown [source states throwable]
@@ -33,6 +42,23 @@
     (success? [this] false)
     (pending? [this] false)
     (error? [this] true)
+    (skipped? [this] false)
+    (container? [this] false))
+
+(defrecord TestSkipped [source reason]
+  TestResult
+    (success? [this] true)
+    (pending? [this] false)
+    (error? [this] false)
+    (skipped? [this] true)
+    (container? [this] false))
+
+(defrecord TestPending [source reason]
+  TestResult
+    (success? [this] true)
+    (pending? [this] true)
+    (error? [this] false)
+    (skipped? [this] false)
     (container? [this] false))

 (defn pass [source states]
@@ -47,3 +73,17 @@
   {:pre [(example? source)
 	 (instance? Throwable throwable)]}
   (TestThrown. source states throwable))
+
+(defn skip
+  ([source] (skip source nil))
+  ([source reason]
+     {:pre [(example? source)
+	    (nil-or string? reason)]}
+     (TestSkipped. source reason)))
+
+(defn pending
+  ([source] (pending source nil))
+  ([source reason]
+     {:pre [(example? source)
+	    (nil-or string? reason)]}
+     (TestPending. source reason)))


Correct configuration of  static middleware

--- src/rmfu/core.clj
+++ src/rmfu/core.clj
@@ -108,7 +108,6 @@
             (GET "/reset-password-redirect/:email" [] reset-password-redirect)
             (PUT "/reset-password-from-form" [] reset-password-from-form!)
             (GET "/verify-email/:email" [] verify-email)
-            (wrap-file "/" "resources/public")              ;; server static files from this directory
             (route/not-found (not-found "Resource not found")))

 (defroutes app-routes
@@ -121,10 +120,11 @@
           (wrap-cors :access-control-allow-origin [#".+"]
                      :access-control-allow-methods [:get :put :post :delete])
           params-middleware/wrap-params
-          (json-middleware/wrap-json-body {:keywords? true})))
+          (json-middleware/wrap-json-body {:keywords? true})
+          (wrap-file "resources/public")))              ;; server static files from this directory

 (defn -main [port]
   (jetty/run-jetty app {:port (Integer. port)}))

 (defn -dev [port]
-  (jetty/run-jetty (wrap-reload #'app) {:port (Integer. port)}))+  (jetty/run-jetty (wrap-reload #'app) {:port (Integer. port)}))


Added child route generation to route generation - added child generation function, recursively descending through converted taxonomy gathering eldest children - moved gen-route to a fn combining parent and child routes (dropping the overlap in loc id)

--- src/lonelyplanet/model.clj
+++ src/lonelyplanet/model.clj
@@ -89,21 +89,30 @@
     loc
     (z/remove loc)))

-(defn gen-route
+(defn gen-route-parent
   "Generate a route to the top destination from the current destination"
   [loc acc]
-  (aprint (str "At node " (-> loc z/node :tag) " " (-> loc z/node :attrs :id)))
   (let [parent (-> loc z/up z/up)
         loc-id (-> loc z/node :attrs :id)]
-    (aprint (str "Node parent: " (if parent (str (-> parent z/node :tag) " " (-> parent z/node :attrs :id)) nil)))
     (if parent (recur parent (cons loc-id acc)) (cons loc-id acc))))
+
+(defn gen-route-child
+  "Generate a route to the bottom destination from the current destination, taking the left-most child if any"
+  [loc acc]
+  (let [loc-id (-> loc z/node :attrs :id)
+        child-test (-> loc z/down z/right)]
+    (if child-test (recur (z/down child-test) (cons loc-id acc)) (cons loc-id acc))))
+
+(defn gen-route [loc]
+  "Merge the parent route and the child route"
+  (concat (gen-route-parent loc []) (rest (reverse (gen-route-child loc [])))))

 (defn gen-meta
   "Generate destination meta-info for the view"
   [loc]
   (let [loc-id (-> loc z/node :attrs :id)
         loc-name (-> loc z/down z/down z/node)]
-    [(Integer. ^String loc-id) {:route     (gen-route loc [])
+    [(Integer. ^String loc-id) {:route     (gen-route loc)
                                 :place-id  loc-id
                                 :placename loc-name}]))


Fix missing arg in exception handling

Fix missing arg in exception handling

--- src/lt/objs/langs/clj.cljs
+++ src/lt/objs/langs/clj.cljs
@@ -317,7 +317,7 @@
                   :triggers #{:editor.eval.clj.exception}
                   :reaction (fn [obj res passed?]
                               (when-not passed?
-                                (notifos/done-working))
+                                (notifos/done-working ""))
                               (let [meta (:meta res)
                                     loc {:line (dec (:end-line meta)) :ch (:end-column meta 0)
                                          :start-line (dec (:line meta 1))}]
@@ -329,7 +329,7 @@
                   :triggers #{:editor.eval.cljs.exception}
                   :reaction (fn [obj res passed?]
                               (when-not passed?
-                                (notifos/done-working))
+                                (notifos/done-working ""))
                               (let [meta (:meta res)
                                     loc {:line (dec (:end-line meta)) :ch (:end-column meta)
                                          :start-line (dec (:line meta))}


let-bind intermediate expression

let-bind intermediate expression

--- src/midje/data/prerequisite_state.clj
+++ src/midje/data/prerequisite_state.clj
@@ -115,8 +115,9 @@
             (map var->faker-fn fn-fake-vars))))

 (defn- data-fakes-binding-map [data-fakes]
-  (apply merge-with metaconstant/merge-metaconstants (for [{:keys [var contained]} data-fakes]
-                                                       {var (Metaconstant. (pile/object-name var) contained nil)})))
+  (let [metaconstant-vars (for [{:keys [var contained]} data-fakes]
+                            {var (Metaconstant. (pile/object-name var) contained nil)})]
+    (apply merge-with metaconstant/merge-metaconstants metaconstant-vars)))

 (defn binding-map [fakes]
   (let [[data-fakes fn-fakes] (seq/bifurcate :data-fake fakes)]


Fix unordered series data

Fix unordered series data

--- maps/src/maps/core.cljs
+++ maps/src/maps/core.cljs
@@ -116,4 +116,4 @@
 (reagent/render-component [page]
                           (. js/document (getElementById "app")))

-(evolution! 0.851 points, speed)+(defonce foo (evolution! 0.851 points, speed))


Fixes ISO vertical spatial domain issue.

--- umm-spec-lib/src/cmr/umm_spec/xml_to_umm_mappings/iso19115_2/spatial.clj
+++ umm-spec-lib/src/cmr/umm_spec/xml_to_umm_mappings/iso19115_2/spatial.clj
@@ -86,6 +86,8 @@
     {:SpatialCoverageType (get extent-info "SpatialCoverageType")
      :GranuleSpatialRepresentation (get extent-info "SpatialGranuleSpatialRepresentation")
      :HorizontalSpatialDomain {:Geometry (parse-geometry doc)}
-     :VerticalSpatialDomains (when-let [vsd-type (get extent-info "VerticalSpatialDomainType")]
-                               [{:Type vsd-type
-                                 :Value (get extent-info "VerticalSpatialDomainValue")}])}))
+     :VerticalSpatialDomains (let [vsd-type  (get extent-info "VerticalSpatialDomainType")
+                                   vsd-value (get extent-info "VerticalSpatialDomainValue")]
+                               (when (or vsd-type vsd-value)
+                                 [{:Type vsd-type
+                                   :Value vsd-value}]))}))


now that git works again, add it to the demo-pipeline by default

--- src/todopipeline/pipeline.clj
+++ src/todopipeline/pipeline.clj
@@ -28,8 +28,8 @@
      (either
        lambdacd.manualtrigger/wait-for-manual-trigger
        wait-for-greeting
-       ;wait-for-frontend-repo
-       ;wait-for-backend-repo
+       wait-for-frontend-repo
+       wait-for-backend-repo
        )
      ;; you could also wait for a repository to change. to try, point the step to a repo you control,
     ;; uncomment this, run and see the magic happen (the first build will immediately run since there is no known state)


Modify example to fit new tests

Modify example to fit new tests

- Fixes #21

--- meetup/example.clj
+++ meetup/example.clj
@@ -1,23 +1,21 @@
 (ns meetup
   (:import (java.util Calendar)))

-(def day-offsets {:sunday    1
-                  :monday    2
-                  :tuesday   3
-                  :wednesday 4
-                  :thursday  5
-                  :friday    6
-                  :saturday  7})
+(def day-offsets
+  {:sunday    1
+   :monday    2
+   :tuesday   3
+   :wednesday 4
+   :thursday  5
+   :friday    6
+   :saturday  7})

-(def ordinals {:first  1
-               :second 2
-               :third  3
-               :fourth 4})
-
-(defn- abs [n]
-  (cond
-    (neg? n) (* -1 n)
-    :else    n))
+(def days-of-month
+  {:first 1
+   :second 8
+   :third 15
+   :fourth 22
+   :teenth 13})

 (defn- ^Calendar to-date
   [year month day]
@@ -39,7 +37,7 @@

 (defn- days-to-move
   [weekday offset-and-direction]
-  (let [offset    (abs offset-and-direction)
+  (let [offset    (Math/abs offset-and-direction)
         direction (/ offset-and-direction offset)]
     (* (mod (* -1 direction (- weekday offset)) 7) direction)))

@@ -55,28 +53,17 @@
   (let [date (to-date year month 1)]
     (.getActualMaximum date Calendar/DAY_OF_MONTH)))

-; generate the "*teenth" functions
-(doseq [[day-name offset] day-offsets]
-  (let [fname (symbol
-                (clojure.string/replace
-                  (name day-name) #"day" "teenth"))]
-    (intern *ns* fname
-            (fn [month year]
-              (date-parts (offset-date year month 13 offset))))))
+(defn- offset-for
+  [schedule day-of-week]
+  (if (= :last schedule)
+    (* -1 day-of-week)
+    day-of-week))

-; generate the ordinal day functions
-(doseq [[ordinal week-number] ordinals]
-  (doseq [[day-name offset] day-offsets]
-    (let [fname (symbol (str (name ordinal) "-" (name day-name)))
-          day-of-month (inc (* (dec week-number) 7))]
-      (intern *ns* fname
-              (fn [month year]
-                (date-parts (offset-date year month day-of-month offset)))))))
-
-; generate the "last*" functions
-(doseq [[day-name offset] day-offsets]
-  (let [fname (symbol (str "last-" (name day-name)))]
-    (intern *ns* fname
-            (fn [month year]
-              (let [last-day (last-day-of-month year month)]
-                (date-parts (offset-date year month last-day (* -1 offset))))))))
+(defn meetup
+  [month year day-name schedule]
+  (let [day-of-month (if (= :last schedule)
+                       (last-day-of-month year month)
+                       (get days-of-month schedule))
+        day-of-week (get day-offsets day-name)
+        offset (offset-for schedule day-of-week)]
+    (date-parts (offset-date year month day-of-month offset))))


Add corresponding tests

Add corresponding tests

--- test/clojure/clojurewerkz/cassaforte/new_query_api_test.clj
+++ test/clojure/clojurewerkz/cassaforte/new_query_api_test.clj
@@ -79,11 +79,16 @@
                  (limit (int 42)))))

+  (is (= "SELECT writetime(a),ttl(a) FROM foo ALLOW FILTERING;"
+         (select :foo
+          (columns (write-time :a)
+                   (ttl :a))
+          (allow-filtering))))

   )

-;; "SELECT writetime(a),ttl(a) FROM foo ALLOW FILTERING;";
+;;
 ;; select().writeTime("a").ttl("a").from("foo").allowFiltering();


CMR-306: Added test for string range attribute searches.

--- test/cmr/system_int_test/search/granule_psa_search_test.clj
+++ test/cmr/system_int_test/search/granule_psa_search_test.clj
@@ -25,7 +25,10 @@
        "string,,a" (am/invalid-name-msg "")
        "string,,a,b" (am/invalid-name-msg "")
        "string,alpha," (am/invalid-value-msg :string "")
-       "string,alpha" (am/invalid-num-parts-msg))
+       "string,alpha" (am/invalid-num-parts-msg)
+       "string,alpha,," (am/one-of-min-max-msg)
+       "string,alpha,b,a" "")
+

   (is (= {:status 422 :errors [(am/attributes-must-be-sequence-msg)]}
          (search/get-search-failure-data
@@ -38,21 +41,40 @@
         psa3 (dc/psa "charlie" :string)

         coll1 (d/ingest "PROV1" (dc/collection {:product-specific-attributes [psa1 psa2]}))
-        gran1 (d/ingest "PROV1" (dg/granule coll1 {:product-specific-attributes [(dg/psa "alpha" ["a" "b"])
-                                                                                (dg/psa "bravo" ["c" "b"])]}))
-        gran2 (d/ingest "PROV1" (dg/granule coll1 {:product-specific-attributes [(dg/psa "bravo" ["a"])]}))
+        gran1 (d/ingest "PROV1" (dg/granule coll1 {:product-specific-attributes [(dg/psa "alpha" ["ab" "bc"])
+                                                                                (dg/psa "bravo" ["cd" "bf"])]}))
+        gran2 (d/ingest "PROV1" (dg/granule coll1 {:product-specific-attributes [(dg/psa "bravo" ["ab"])]}))

         coll2 (d/ingest "PROV1" (dc/collection {:product-specific-attributes [psa2 psa3]}))
-        gran3 (d/ingest "PROV1" (dg/granule coll2 {:product-specific-attributes [(dg/psa "bravo" ["a" "b"])]}))
-        gran4 (d/ingest "PROV1" (dg/granule coll2 {:product-specific-attributes [(dg/psa "charlie" ["a"])]}))]
+        gran3 (d/ingest "PROV1" (dg/granule coll2 {:product-specific-attributes [(dg/psa "bravo" ["aa" "bf"])]}))
+        gran4 (d/ingest "PROV1" (dg/granule coll2 {:product-specific-attributes [(dg/psa "charlie" ["az"])]}))]
     (index/flush-elastic-index)

     (testing "search by value"
       (are [v items]
            (d/refs-match? items (search/find-refs :granule {"attribute[]" v}))
-           "string,alpha,a" [gran1]
+           "string,alpha,ab" [gran1]
            "string,alpha,c" []
-           "string,bravo,b" [gran1 gran3]))))
+           "string,bravo,bf" [gran1 gran3]))
+
+    (testing "search by range"
+      (are [v items]
+           (d/refs-match? items (search/find-refs :granule {"attribute[]" v}))
+
+           ;; inside range
+           "string,alpha,aa,ac" [gran1]
+           ;; beginning edge of range
+           "string,alpha,ab,ac" [gran1]
+           ;; ending edge of range
+           "string,alpha,aa,ab" [gran1]
+
+           ;; only min range provided
+           "string,bravo,bc," [gran1 gran3]
+
+           ;; only max range provided
+           "string,bravo,,bc" [gran2 gran3]))))

+
+


Add FIXME comment.

Add FIXME comment.

--- src/uxbox/data/workspace.cljs
+++ src/uxbox/data/workspace.cljs
@@ -137,6 +137,8 @@
           (update-in $ [:pages-by-id pid :shapes] conj sid)
           (assoc-in $ [:shapes-by-id sid] shape))))))

+
+;; FIXME: delete shape that is part of group.
 (defn delete-shape
   "Remove the shape using its id."
   [id]


Add leaf node coloring.

Add leaf node coloring.

Will use this to add decay and possible fish seek behavior.

--- src/videotest/coral/coral.clj
+++ src/videotest/coral/coral.clj
@@ -58,21 +58,39 @@
   ([coral [col row :as coords]]
      (occupied-coral-under true coral coords))
   ([odd-col-lower coral [col row]]
-     (let [row-under (inc row)
+     (let [row-plus (inc row)
            under-coords (if (or
                              (and odd-col-lower (even? col))
                              (and (not odd-col-lower) (odd? col)))
                           [[(dec col) row]
-                           [     col  row-under]
+                           [     col  row-plus]
                            [(inc col) row]]
-                          [[(dec col) row-under]
-                           [     col  row-under]
-                           [(inc col) row-under]])
-           ]
+                          [[(dec col) row-plus]
+                           [     col  row-plus]
+                           [(inc col) row-plus]])]
        (filter #(is-occupied? coral %) under-coords))))

-(defn is-row-under-occupied? [coral [col row]]
+(defn occupied-coral-above
+  ([coral [col row :as coords]]
+     (occupied-coral-above true coral coords))
+  ([odd-col-lower coral [col row]]
+     (let [row-minus (dec row)
+           other-coords (if (or
+                             (and odd-col-lower (even? col))
+                             (and (not odd-col-lower) (odd? col)))
+                          [[(dec col) row-minus]
+                           [     col  row-minus]
+                           [(inc col) row-minus]]
+                          [[(dec col) row]
+                           [     col  row-minus]
+                           [(inc col) row]])]
+       (filter #(is-occupied? coral %) other-coords))))
+
+#_(defn is-row-under-occupied? [coral [col row]]
   (seq (occupied-coral-under coral [col row])))
+
+(defn is-leaf? [odd-col-lower coral [col row :as coords]]
+  (not (seq (occupied-coral-above odd-col-lower coral coords))))

 (def BOTTOM-ATTACH-PCT 0.1)

@@ -166,13 +184,17 @@
       (update-rot-cycle)
       (rotate-coral-side)))

-(defn draw-polyp [odd-col-lower
+(defn draw-polyp [coral
                   {:keys [cell-w cell-half-w
                           hex-w hex-half-w
-                          hex-y-offset] :as coral-size}
+                          hex-y-offset
+                          odd-col-lower] :as coral-size}
                   [[col row :as coords]
                    {:keys [color-rgba] :as polyp}]]
   #_(apply q/fill color-rgba)
+  (if (is-leaf? odd-col-lower coral coords)
+    (q/fill 50 255 0 155)
+    (q/no-fill))
   (apply q/stroke color-rgba)
   (hex/draw-hex-cell odd-col-lower
                      cell-w cell-half-w
@@ -190,6 +212,6 @@
                     (float rot-cycle))]
     (q/with-translation [(- x-offset) 0]
       (dorun
-       (map (partial draw-polyp odd-col-lower coral-size)
+       (map (partial draw-polyp coral coral-size)
             coral))))
   (q/pop-style))


expose _source to catalyst integration but make all [] nil

--- src/wb_es/web/integration.clj
+++ src/wb_es/web/integration.clj
@@ -16,21 +16,21 @@

 (defn- get-obj [doc]
   (let [search-obj (pack-search-obj doc)
-        doc-source (:_source doc)]
-    {:name search-obj
-     :description (:description doc-source)
-     :taxonomy (->> (get-in doc-source [:species :name])
-                    (pack-species))
-     :gene (->> (:gene doc-source)
-                (not-empty))
-     :phenotype (->> (:phenotype doc-source)
-                     (not-empty))
-     :genotype (->> (:genotype doc-source)
-                    (not-empty))
-     :strain (->> (:strain doc-source)
-                  (not-empty))
-     :author (->> (:author doc-source)
-                  (not-empty))}))
+        doc-source (:_source doc)
+
+        non-empty-doc-source
+        (reduce (fn [result [k v]]
+                  (let [non-empty-v
+                        (if (sequential? v)
+                          (not-empty v)
+                          v)]
+                    (assoc result k non-empty-v)))
+                {}
+                doc-source)]
+    (assoc non-empty-doc-source
+           :name search-obj
+           :taxonomy (->> (get-in doc-source [:species :name])
+                          (pack-species)))))

 (defn wrap-params [handler]
   (fn [request]


Adds a-pair?

Adds a-pair?

--- src/the_little_clojurian/chapter7.clj
+++ src/the_little_clojurian/chapter7.clj
@@ -132,3 +132,20 @@
   (is (= (intersect-all '((b) (b))) '(b)))
   (is (= (intersect-all '((a 1) (a 2) (a 3))) '(a)))
   (is (= (intersect-all '((a b c) (a b c d) (a b c d e))) '(a b c))))
+
+(with-test
+  (def a-pair?
+    (fn [x]
+      (cond (atom? x) false
+            (empty? x) false
+            (null? (cdr x)) false
+            (null? (cdr (cdr x))) true
+            :else false)))
+
+  (is (= (a-pair? '()) false))
+  (is (= (a-pair? '(:foo :bar)) true))
+  (is (= (a-pair? '(:foo)) false))
+  (is (= (a-pair? :foo)) false)
+  (is (= (a-pair? '(:foo (:bar))) true))
+  (is (= (a-pair? '(:foo :bar :baz)) false))
+  (is (= (a-pair? '((:foo) (:bar))) true)))


Add database checklist description

Add database checklist description

--- src/metabase/api/setup.clj
+++ src/metabase/api/setup.clj
@@ -104,7 +104,7 @@
         num-users          (db/select-one-count 'User)]
     [{:title       "Add a database"
       :group       "Get connected"
-      :description "TODO - Write something good here"
+      :description "Connect to your data so your whole team can start to explore."
       :link        "/admin/databases/create"
       :completed   has-dbs?
       :triggered   :always}


waveform independent of window size

waveform independent of window size

--- src/vijualizer/core.clj
+++ src/vijualizer/core.clj
@@ -26,9 +26,11 @@
 (defn init-line []
   "Initializes Minim and an InputLine"
   (let [frame-size 1024
+        sample-rate 44100
         minim (Minim. MinimDummyInput)
-        input (.getLineIn minim Minim/MONO, frame-size)]
-    {:frame-size frame-size
+        input (.getLineIn minim Minim/MONO frame-size sample-rate)]
+    {:sample-rate sample-rate
+     :frame-size frame-size
      :minim minim
      :input input}))

@@ -58,7 +60,7 @@

 (defn update-state [state args]
-  (let [fft (FFT. (:frame-size args) 44100.0)]
+  (let [fft (FFT. (:frame-size args) (:sample-rate args))]
     (.logAverages fft 45 15)
     (a/go (while (not (:stop @state))
             (.forward fft (.-mix (:input args)))
@@ -112,18 +114,29 @@

 ;;; waveform

+#_(defn cache-ys [a]
+  (defn get-y [i] (-> (:input a) .-mix (.get i)))
+  (doall (map get-y (range (:frame-size a)))))
+
+
 (defn draw-waveform [a]
-  (q/background 1.0)
-  (defn scale [y] (-> y (* 200) (+ 200)))
-  (defn get-y [i] (-> (:input a) .-mix (.get i)))
-  (doseq [i (-> (:frame-size a) dec range)]
-    (q/line i (scale (get-y i))
-            (inc i) (scale (get-y (inc i))))))
+  (q/background 0.5)
+  (q/text (str [(q/width) (q/height)]) 0 0 500 500)
+  (let [get-y (fn [i] (-> (:input a) .-mix (.get i)))
+        hh (/ (q/height) 2)
+        scale-x (fn [x] (-> x (/ (:frame-size a))
+                            (* (q/width))))
+        scale-y (fn [y] (-> y (* hh) (+ hh)))]
+    (doseq [i (-> (:frame-size a) dec range)
+            :let [j (inc i)]]
+      (q/line (scale-x i) (scale-y (get-y i))
+              (scale-x j) (scale-y (get-y j))))))

 (defn plot-waveform [a]
   (q/sketch
-   :size [1024 400]
+   :size [500 500]
+;   :size :fullscreen
    :setup quil-setup
    :update identity
    :draw (fn [_] (draw-waveform a))


Moves rename-document

Moves rename-document

--- src/wordsmith/core.cljs
+++ src/wordsmith/core.cljs
@@ -93,16 +93,16 @@

 ;; The main app

-(defn rename-document [app new-title]
-  (p/rename-document (:last-title @app) new-title)
-  (save-document app))
-
 (defn save-document [app]
   (om/update! app :last-saved (js/Date.))
   (om/update! app :last-title (:title @app))
   (p/set-document (:title @app) (:input @app))
   (om/update! app :titles (p/get-all-titles)))

+(defn rename-document [app new-title]
+  (p/rename-document (:last-title @app) new-title)
+  (save-document app))
+
 (defn remove-document [app title]
   (p/remove-document title)
   (om/update! app :titles (p/get-all-titles)))


Functions to read changes, changes statistic and changes made by selected user


Add test for #77 - collection renders without input files

--- test/io/perun_test.clj
+++ test/io/perun_test.clj
@@ -122,7 +122,9 @@
   (str "<body>" (:content (:entry data)) "</body>"))

 (deftesttask markdown-test []
-  (comp (add-txt-file :path "2017-01-01-test.md" :content md-content)
+  (comp (p/collection :renderer 'io.perun-test/render) ;; test #77, collection works without input files
+
+        (add-txt-file :path "2017-01-01-test.md" :content md-content)
         (boot/with-pre-wrap fileset
           (pm/set-global-meta fileset {:base-url "http://example.com/"
                                        :site-title "Test Title"


update scope:

update scope:

* Can now scope control-busses
* Prints name of thing to scope if it exists
* Cleans up resources on close

--- src/overtone/gui/scope.clj
+++ src/overtone/gui/scope.clj
@@ -10,7 +10,7 @@
   (:use [clojure.stacktrace]
         [overtone.helpers lib]
         [overtone.libs event deps]
-        [overtone.sc defaults server synth ugens buffer node foundation-groups]
+        [overtone.sc defaults server synth ugens buffer node foundation-groups bus]
         [overtone.sc.cgens buf-io]
         [overtone.studio core util])
   (:require [clojure.set :as set]
@@ -53,9 +53,12 @@
   will cause the crash to happen sooner. Need to remove this limitation
   when scsynth-jna is fixed."
   [s]
+
   (let [{:keys [buf size width height panel y-arrays x-array panel]} s
-        frames    (if @(:update? s) (buffer-data buf) @(:frames s))
-        step      (/ (buffer-size buf) width)
+        frames    (if (buffer-live? buf)
+                    (buffer-data buf)
+                    [])
+        step      (/ (:size buf) width)
         y-scale   (- height (* 2 Y-PADDING))
         [y-a y-b] @y-arrays]

@@ -65,15 +68,13 @@
               (int (* y-scale
                       (aget ^floats frames (unchecked-multiply x step))))))
       (reset! y-arrays [y-b y-a])
-      (.repaint panel))
-
-    (when (and (not (:bus-synth s))
-               @(:update? s))
-      (reset! (:frames s) frames)
-      (reset! (:update? s) false))))
+      (.repaint panel))))

 (defn- update-scopes []
-  (dorun (map update-scope-data (vals @scopes*))))
+  (try
+    (dorun (map update-scope-data (vals @scopes*)))
+    (catch Exception e
+      (println "Exception when updating scopes:" (with-out-str (.printStackTrace e))))))

 (defn- paint-scope [^Graphics g id]
   (if-let [scope (get @scopes* id)]
@@ -125,7 +126,7 @@
   (ensure-internal-server!)
   (dosync
    (when-not @scopes-running?*
-     (at-at/every (/ 1000 FPS) update-scopes scope-pool :desc "Scope refresh fn")
+     (at-at/every (/ 1000 FPS) #'update-scopes scope-pool :desc "Scope refresh fn")
      (ref-set scopes-running?* true))))

 (defn- reset-data-arrays
@@ -155,14 +156,16 @@
   (dosync (ref-set scopes-running?* false)))

 (defn- start-bus-synth
-  [bus buf]
-  (bus->buf :target @scope-group* bus buf))
+  [bus buf control-rate?]
+  (if control-rate?
+    (control-bus->buf :target @scope-group* bus buf)
+    (bus->buf :target @scope-group* bus buf)))

 (defn- scope-bus
   "Set a bus to view in the scope."
-  [s]
-  (let [buf (buffer SCOPE-BUF-SIZE)
-        bus-synth (start-bus-synth (:num s) buf)]
+  [s control-rate?]
+  (let [buf       (buffer SCOPE-BUF-SIZE)
+        bus-synth (start-bus-synth (:thing s) buf control-rate?)]
     (assoc s
       :size SCOPE-BUF-SIZE
       :bus-synth bus-synth
@@ -193,7 +196,7 @@
 (defn- scope-bus-freq
   [s]
   (let [buf (buffer SCOPE-BUF-SIZE)
-        bus-synth (start-bus-freq-synth (:num s) buf)]
+        bus-synth (start-bus-freq-synth (:thing s) buf)]
     (assoc s
       :size SCOPE-BUF-SIZE
       :bus-synth bus-synth
@@ -202,10 +205,10 @@
 (defn- scope-buf
   "Set a buffer to view in the scope."
   [s]
-  (let [info (buffer-info (:num s))]
+  (let [buf (:thing s)]
     (assoc s
-      :size (:size info)
-      :buf  info)))
+      :size (:size buf)
+      :buf  buf)))

 (defn scope-close
   "Close a given scope. Copes with the case where the server has crashed
@@ -224,84 +227,104 @@
     (dosync (alter scopes* dissoc id))))

 (defn- mk-scope
-  [num kind keep-on-top width height]
-  (let [id    (uuid)
-        name  (str kind ": " num)
-        panel (scope-panel id width height)
-        slider (JSlider. JSlider/VERTICAL 0 99 50)
-        frame (scope-frame panel slider name keep-on-top width height)
-        x-array (int-array width)
-        y-a     (int-array width)
-        y-b     (int-array width)
-        scope {:id id
-               :name name
-               :size 0
-               :num num
-               :panel panel
-               :slider slider
-               :kind kind
-               :color (Color. 0 130 226)
-               :background (Color. 50 50 50)
-               :frame frame
-               :width width
-               :height height
-               :x-array x-array
-               :y-arrays (atom [y-a y-b])
-               :update? (atom true)
-               :frames (atom [])}
-
-        _ (reset-data-arrays scope)]
+  [thing kind keep-on-top width height]
+  (let [thing-id (to-sc-id thing)
+        scope-id (uuid)
+        name     (str kind ": " thing-id " " (if-let [n (:name thing)]
+                                               (str "[" n "]")
+                                               ""))
+        panel    (scope-panel scope-id width height)
+        slider   (JSlider. JSlider/VERTICAL 0 99 50)
+        frame    (scope-frame panel slider name keep-on-top width height)
+        x-array  (int-array width)
+        y-a      (int-array width)
+        y-b      (int-array width)
+        scope    {:id         scope-id
+                  :name       name
+                  :size       0
+                  :thing      thing
+                  :panel      panel
+                  :slider     slider
+                  :kind       kind
+                  :color      (Color. 0 130 226)
+                  :background (Color. 50 50 50)
+                  :frame      frame
+                  :width      width
+                  :height     height
+                  :x-array    x-array
+                  :y-arrays   (atom [y-a y-b])}
+
+        _        (reset-data-arrays scope)]
     (.addWindowListener frame
-      (reify WindowListener
-        (windowActivated [this e])
-        (windowClosing [this e]
-                       (scope-close (get @scopes* id)))
-        (windowDeactivated [this e])
-        (windowDeiconified [this e])
-        (windowIconified [this e])
-        (windowOpened [this e])
-        (windowClosed [this e])))
+                        (reify WindowListener
+                          (windowActivated [this e])
+                          (windowClosing [this e]
+                            (scope-close (get @scopes* scope-id)))
+                          (windowDeactivated [this e])
+                          (windowDeiconified [this e])
+                          (windowIconified [this e])
+                          (windowOpened [this e])
+                          (windowClosed [this e])))
     (comment .addComponentListener frame
-      (reify ComponentListener
-        (componentHidden [this e])
-        (componentMoved  [this e])
-        (componentResized [this e]
-          (let [w (.getWidth frame)
-                h (.getHeight frame)
-                xs (int-array w)
-                ya (int-array w)
-                yb (int-array w)]
-            (dosync
-              (let [s (get (ensure scopes*) id)
-                    s (assoc s
-                             :width w
-                             :height h
-                             :x-array xs
-                             :y-arrays (atom [ya yb]))]
-                (alter scopes* assoc id s)))))
-        (componentShown [this e])))
+             (reify ComponentListener
+               (componentHidden [this e])
+               (componentMoved  [this e])
+               (componentResized [this e]
+                 (let [w (.getWidth frame)
+                       h (.getHeight frame)
+                       xs (int-array w)
+                       ya (int-array w)
+                       yb (int-array w)]
+                   (dosync
+                    (let [s (get (ensure scopes*) scope-id)
+                          s (assoc s
+                              :width w
+                              :height h
+                              :x-array xs
+                              :y-arrays (atom [ya yb]))]
+                      (alter scopes* assoc scope-id s)))))
+               (componentShown [this e])))

     (case kind
-          :bus (scope-bus scope)
-          :bus-freq (scope-bus-freq scope)
-          :buf (scope-buf scope))))
+      :control-bus (scope-bus scope true)
+      :bus (scope-bus scope false)
+      :audio-bus (scope-bus scope false)
+      :bus-freq (scope-bus-freq scope)
+      :buf (scope-buf scope))))

 (defn scope
-  "Create a scope for either a bus or a buffer. Defaults to scoping bus 0.
+  "Create a scope for either a bus or a buffer. Defaults to scoping audio-bus 0.
    Example use:
-   (scope :bus 1)
+
+   (scope a-control-bus)
+   (scope a-buffer)
+   (scope an-audio-bus)
+   (scope :audio-bus 1)
+   (scope :control-bus 10)
    (scope :buf 10)"
-  ([&{:keys [bus buf keep-on-top]
-      :or {bus 0
-           buf -1
-           keep-on-top false}}]
+  ([]        (scope :audio-bus 0))
+  ([thing]   (cond
+              (audio-bus? thing)   (scope :audio-bus thing)
+              (control-bus? thing) (scope :control-bus thing)
+              (buffer? thing)      (scope :buf thing)
+              :else                (scope :audio-bus thing)))
+  ([kind id] (scope kind id false))
+  ([kind id keep-on-top?]
      (ensure-internal-server!)
-     (let [buf (if (buffer? buf) (:id buf) buf)
-           kind (if (= -1 buf) :bus :buf)
-           num  (if (= -1 buf) bus buf)
-           s (mk-scope num kind keep-on-top WIDTH HEIGHT)]
+     (let [s  (mk-scope id kind keep-on-top? WIDTH HEIGHT)]
        (dosync (alter scopes* assoc (:id s) s))
        (scopes-start))))
+
+(defn pscope
+  "Creates a 'permanent' scope, where the window is always kept
+  on top of other OS windows. See scope."
+  ([]        (scope :audio-bus 0 true))
+  ([thing]   (cond
+              (audio-bus? thing)   (scope :audio-bus thing true)
+              (control-bus? thing) (scope :control-bus thing true)
+              (buffer? thing)      (scope :buf thing true)
+              :else                (scope :audio-bus thing true)))
+  ([kind id] (scope kind id true)))

 (defn spectrogram
   "Create frequency scope for a bus.  Defaults to bus 0.
@@ -314,14 +337,6 @@
      (let [s (mk-scope bus :bus-freq keep-on-top WIDTH HEIGHT)]
        (dosync (alter scopes* assoc (:id s) s))
        (scopes-start))))
-
-(defn pscope
-  "Creates a 'permanent' scope, where the window is always kept
-  on top of other OS windows. See scope."
-  ([& args]
-     (ensure-internal-server!)
-     (apply scope (concat args [:keep-on-top true]))))
-

 (defn- reset-scopes
   "Restart scopes if they have already been running"


Fix incorrect return keyword.

Fix incorrect return keyword.

--- src/overtone/sc/sample.clj
+++ src/overtone/sc/sample.clj
@@ -141,7 +141,7 @@
         args (:args smpl)
         buf  (get @loaded-samples* [path args])]
     (free-loaded-sample [[path args] buf])
-    :overtone/remove-handler))
+    :sample-freed))

 (defn sample-player
   [smpl & pargs]


OSD message about keys.

OSD message about keys.

--- src/brevis/osd.clj
+++ src/brevis/osd.clj
@@ -46,6 +46,7 @@
   #_(osd :msg-type :penumbra :fn (fn [[dt t] state] (str (int (/ 1 dt)) " fps " (double (get-current-simulation-rate)) " sim/s")) :start-t 0 :stop-t -1)
   (osd :msg-type :penumbra :fn (fn [[dt t] state] (str (float (get-time)) " sim time")) :start-t 0 :stop-t -1)
   (osd :msg-type :penumbra :fn (fn [[dt t] state] (str (float (get-wall-time)) " wall time")) :start-t 0 :stop-t -1)
+  (osd :msg-type :penumbra :fn (fn [[dt t] state] "Keys: Esc - quit / w - forward / s - backward / a - left / d - right / c - up / leftshift - down ") :start-t 0 :stop-t 10)
   #_(osd :msg-type :brevis :fn #(str (int (count @*objects*)) " objs") :start-t 0 :stop-t 5))

 (defn update-display-text


add new insert-paren anims

add new insert-paren anims

--- src/parinfer/vcr_data.cljs
+++ src/parinfer/vcr_data.cljs
@@ -1601,94 +1601,92 @@
 (def wrap
   '{:timescale 2
     :changes
-    [{:change
+    [{:selections ({:anchor {:line 0, :ch 0}, :head {:line 0, :ch 0}}),
+      :dt 0}
+     {:change
+      {:from {:line 0, :ch 0},
+       :to {:line 0, :ch 0},
+       :text ("(foo 1 2 3 4 5 6)"),
+       :origin "paste"},
+      :dt 543}
+     {:selections ({:anchor {:line 0, :ch 5}, :head {:line 0, :ch 5}}),
+      :dt 924}
+     {:change
       {:from {:line 0, :ch 5},
        :to {:line 0, :ch 5},
-       :text ("1"),
-       :origin "+input"},
-      :dt 0}
-     {:change
-      {:from {:line 0, :ch 6},
-       :to {:line 0, :ch 6},
+       :text ("["),
+       :origin "+input"},
+      :dt 595}
+     {:selections ({:anchor {:line 0, :ch 19}, :head {:line 0, :ch 19}}),
+      :dt 856}
+     {:change
+      {:from {:line 0, :ch 19},
+       :to {:line 0, :ch 19},
+       :text ("" ""),
+       :origin "+input"},
+      :dt 572}
+     {:change
+      {:from {:line 1, :ch 0},
+       :to {:line 1, :ch 0},
+       :text ("("),
+       :origin "+input"},
+      :dt 311}
+     {:change
+      {:from {:line 1, :ch 1},
+       :to {:line 1, :ch 1},
+       :text ("b"),
+       :origin "+input"},
+      :dt 207}
+     {:change
+      {:from {:line 1, :ch 2},
+       :to {:line 1, :ch 2},
+       :text ("a"),
+       :origin "+input"},
+      :dt 169}
+     {:change
+      {:from {:line 1, :ch 3},
+       :to {:line 1, :ch 3},
+       :text ("r"),
+       :origin "+input"},
+      :dt 112}
+     {:change
+      {:from {:line 1, :ch 4},
+       :to {:line 1, :ch 4},
        :text (" "),
        :origin "+input"},
-      :dt 97}
-     {:change
-      {:from {:line 0, :ch 7},
-       :to {:line 0, :ch 7},
-       :text ("2"),
-       :origin "+input"},
-      :dt 103}
-     {:change
-      {:from {:line 0, :ch 8},
-       :to {:line 0, :ch 8},
+      :dt 79}
+     {:change
+      {:from {:line 1, :ch 5},
+       :to {:line 1, :ch 5},
+       :text ("a"),
+       :origin "+input"},
+      :dt 244}
+     {:change
+      {:from {:line 1, :ch 6},
+       :to {:line 1, :ch 6},
        :text (" "),
        :origin "+input"},
-      :dt 120}
-     {:change
-      {:from {:line 0, :ch 9},
-       :to {:line 0, :ch 9},
-       :text ("3"),
-       :origin "+input"},
-      :dt 201}
-     {:change
-      {:from {:line 0, :ch 10},
-       :to {:line 0, :ch 10},
+      :dt 83}
+     {:change
+      {:from {:line 1, :ch 7},
+       :to {:line 1, :ch 7},
+       :text ("b"),
+       :origin "+input"},
+      :dt 227}
+     {:change
+      {:from {:line 1, :ch 8},
+       :to {:line 1, :ch 8},
        :text (" "),
        :origin "+input"},
-      :dt 143}
-     {:change
-      {:from {:line 0, :ch 11},
-       :to {:line 0, :ch 11},
-       :text ("4"),
-       :origin "+input"},
-      :dt 168}
-     {:change
-      {:from {:line 0, :ch 12},
-       :to {:line 0, :ch 12},
-       :text (" "),
-       :origin "+input"},
-      :dt 136}
-     {:change
-      {:from {:line 0, :ch 13},
-       :to {:line 0, :ch 13},
-       :text ("5"),
-       :origin "+input"},
-      :dt 425}
-     {:change
-      {:from {:line 0, :ch 14},
-       :to {:line 0, :ch 14},
-       :text (" "),
-       :origin "+input"},
-      :dt 290}
-     {:change
-      {:from {:line 0, :ch 15},
-       :to {:line 0, :ch 15},
-       :text ("6"),
-       :origin "+input"},
-      :dt 157}
-     {:selections ({:anchor {:line 0, :ch 5}, :head {:line 0, :ch 5}}),
-      :dt 1063}
-     {:change
-      {:from {:line 0, :ch 5},
-       :to {:line 0, :ch 5},
-       :text ("("),
-       :origin "+input"},
-      :dt 1260}
-     {:change
-      {:from {:line 0, :ch 6},
-       :to {:line 0, :ch 6},
-       :text ("+"),
-       :origin "+input"},
-      :dt 831}
-     {:change
-      {:from {:line 0, :ch 7},
-       :to {:line 0, :ch 7},
-       :text (" "),
-       :origin "+input"},
-      :dt 161}],
-    :init-value "(foo )",
-    :last-time 1444255657876,
+      :dt 181}
+     {:change
+      {:from {:line 1, :ch 9},
+       :to {:line 1, :ch 9},
+       :text ("c"),
+       :origin "+input"},
+      :dt 130}],
+    :init-value "",
+    :last-time 1444574204081,
     :recording? false})

 (def splice
@@ -1709,22 +1707,35 @@
     :recording? false})

 (def barf
-  '{:changes
- [{:selections ({:anchor {:line 0, :ch 20}, :head {:line 0, :ch 20}}),
-   :dt 0}
-  {:selections ({:anchor {:line 0, :ch 20}, :head {:line 0, :ch 19}}),
-   :dt 165}
-  {:selections ({:anchor {:line 0, :ch 11}, :head {:line 0, :ch 11}}),
-   :dt 2231}
-  {:change
-   {:from {:line 0, :ch 11},
-    :to {:line 0, :ch 11},
-    :text (")"),
-    :origin "+input"},
-   :dt 1230}],
- :init-value "(foo (+ 1 2 3 4 5 6))",
- :last-time 1444256380089,
- :recording? false})
+  '{:timescale 2
+    :changes
+    [{:selections ({:anchor {:line 0, :ch 0}, :head {:line 0, :ch 0}}),
+      :dt 0}
+     {:change
+      {:from {:line 0, :ch 0},
+       :to {:line 0, :ch 0},
+       :text ("(foo [1 2 3 4 5 6])" "(bar a b c)"),
+       :origin "paste"},
+      :dt 1438}
+     {:selections ({:anchor {:line 0, :ch 11}, :head {:line 0, :ch 11}}),
+      :dt 1384}
+     {:change
+      {:from {:line 0, :ch 11},
+       :to {:line 0, :ch 11},
+       :text ("]"),
+       :origin "+input"},
+      :dt 588}
+     {:selections ({:anchor {:line 1, :ch 8}, :head {:line 1, :ch 8}}),
+      :dt 1033}
+     {:change
+      {:from {:line 1, :ch 8},
+       :to {:line 1, :ch 8},
+       :text (")"),
+       :origin "+input"},
+      :dt 889}],
+    :init-value "",
+    :last-time 1444574335406,
+    :recording? false})

 (def slurp-
   '{:changes


add function name test

add function name test


Functions process-whitelist, process-blacklist, store-word, and store-words should use proper dictionary specifier

--- src/zg/server.clj
+++ src/zg/server.clj
@@ -68,34 +68,42 @@
                 (http-response/content-type "text/html")))))

 (defn process-front-page
+    "Function that prepares data for the front page."
     [request title]
     (let [params         (:params request)]
         (finish-processing request nil nil title :whitelist)))

 (defn process-whitelist
+    "Function that prepares data for the whitelist front page."
     [request title]
     (let [params         (:params request)
           word           (get params "word")
-          search-results (if (not (empty? word)) (db-interface/read-words-for-pattern word))]
+          search-results (if (not (empty? word))
+                             (db-interface/read-words-for-pattern word :whitelist))]
         (finish-processing request search-results nil title :whitelist)))

 (defn process-blacklist
+    "Function that prepares data for the blacklist front page."
     [request title]
     (let [params         (:params request)
           word           (get params "word")
-          search-results (if (not (empty? word)) (db-interface/read-words-for-pattern word))]
+          search-results (if (not (empty? word))
+                             (db-interface/read-words-for-pattern word :blacklist))]
         (finish-processing request search-results nil title :blacklist)))

 (defn store-word
-    [word description user-name]
-    (println "About to store following word:" word " with description: " description)
-    (db-interface/add-new-word-into-dictionary word description user-name))
+    "Store one word into the dictionary."
+    [word description user-name dictionary-type]
+    (println "About to store following word:" word " with description: " description
+             " into dictionary: " (str dictionary-type))
+    (db-interface/add-new-word-into-dictionary word description (or user-name "(*unknown*)") dictionary-type))

 (defn store-words
-    [words user-name]
+    "Store sequence of words into the dictionary."
+    [words user-name dictionary-type]
     (println "About to store following words:" words)
     (doseq [word words]
-        (db-interface/add-new-word-into-dictionary word user-name)))
+        (db-interface/add-new-word-into-dictionary word user-name dictionary-type)))

 (defn add-word-message
     [word proper-word]


Change some testnames to more consistent names.

--- test/buddy/test_buddy_core.clj
+++ test/buddy/test_buddy_core.clj
@@ -13,7 +13,7 @@
             [clojure.java.io :as io])
   (:import buddy.Arrays))

-(deftest codecs-test
+(deftest buddy-core-codecs
   (testing "Hex encode/decode 01"
     (let [some-bytes  (str->bytes "FooBar")
           encoded     (bytes->hex some-bytes)
@@ -28,7 +28,7 @@
           decoded (hex->bytes encoded)]
       (is (Arrays/equals decoded mybytes)))))

-(deftest password-hashers-tests
+(deftest buddy-hashers
   (testing "Test low level api for encrypt/verify pbkdf2"
     (let [plain-password      "my-test-password"
           encrypted-password  (pbkdf2/make-password plain-password)]
@@ -54,7 +54,7 @@
           encrypted-password  (scrypt/make-password plain-password)]
       (is (scrypt/check-password plain-password encrypted-password)))))

-(deftest core-hash-tests
+(deftest buddy-core-hash
   (testing "SHA3 support test"
     (let [plain-text "FooBar"
           hashed     (-> (hash/sha3-256 plain-text)
@@ -65,7 +65,7 @@
           valid-hash "7aa01e35e65701c9a9d8f71c4cbf056acddc9be17fdff06b4c7af1b0b34ddc29"]
       (is (= (bytes->hex (hash/sha256 (io/input-stream path))) valid-hash)))))

-(deftest poly1305-tests
+(deftest core-mac-poly1305
   (let [iv        (byte-array 16) ;; 16 bytes array filled with 0
         plaintext "text"
         secretkey "secret"]
@@ -95,6 +95,5 @@
     (let [iv2 (make-random-bytes 16)
           signature (poly/poly1305-serpent plaintext secretkey iv2)]
       (is (poly/poly1305-serpent-verify plaintext signature secretkey iv2))
-      (is (not (poly/poly1305-serpent-verify plaintext signature secretkey iv)))))
-))
+      (is (not (poly/poly1305-serpent-verify plaintext signature secretkey iv)))))))


Fixed small bug in final dropdown demo

Fixed small bug in final dropdown demo

--- src/re_demo/dropdowns.cljs
+++ src/re_demo/dropdowns.cljs
@@ -311,7 +311,7 @@
                                :width     "300px"
                                :on-change #(do
                                             (reset! selected-country-id %)
-                                            (reset! filtered-cities (filter-choices-by-keyword cities :country-id @selected-country-id))
+                                            (reset! filtered-cities (vec (filter-choices-by-keyword cities :country-id @selected-country-id)))
                                             (reset! selected-city-id nil))]
                               [:div
                                [:strong "Selected country: "]


Realize lazy seq to prevent "zip file closed" exception

--- boot/core/src/boot/main.clj
+++ boot/core/src/boot/main.clj
@@ -42,7 +42,7 @@
     (pod/with-eval-worker
       (require '[clojure.tools.namespace.find :as nsf])
       (with-open [jf (java.util.jar.JarFile. ~(.getPath (io/file jar)))]
-        (nsf/find-ns-decls-in-jarfile jf)))))
+        (into [] (nsf/find-ns-decls-in-jarfile jf))))))

 (defn- export-tasks?
   [[_ name docstring? attr-map?]]


Fix #101

Fix #101

Fix #'cats.core/mapseq documentation

Returns a seq not a vector.

Remove unnecessary quote in #'cats.core/mapseq

There's no need to quote the empty list.
Reference: http://clojure.org/cheatsheet
Create	() list list*

- Remove not-empty precondition.
- Similar to #'cats.core/foldm, if the given collection is empty,
  return the empty list wrapped the current monadic context.
- Update docstrings:
  - Add examples using ctx/with-context and the empty list.
  - Clean up require form
  - Use ;; => #<Monad [value]> convention

--- src/cats/core.cljc
+++ src/cats/core.cljc
@@ -539,32 +539,42 @@

 (defn sequence
   "Given a non-empty collection of monadic values, collect
-  their values in a vector returned in the monadic context.
-
-      (sequence [(maybe/just 2) (maybe/just 3)])
-      ;; => <Just [[2, 3]]>
-
-      (sequence [(maybe/nothing) (maybe/just 3)])
-      ;; => <Nothing>
+  their values in a seq returned in the monadic context.
+
+      (require '[cats.context :as ctx]
+               '[cats.monad.maybe :as maybe]
+               '[cats.core :as m])
+
+      (m/sequence [(maybe/just 2) (maybe/just 3)])
+      ;; => #<Just [[2, 3]]>
+
+      (m/sequence [(maybe/nothing) (maybe/just 3)])
+      ;; => #<Nothing>
+
+      (ctx/with-context maybe/context
+        (m/sequence []))
+      ;; => #<Just [()]>
   "
   [mvs]
-  {:pre [(not-empty mvs)]}
-  (let [ctx (ctx/get-current (first mvs))]
-    (ctx/with-context ctx
-      (reduce (fn [mvs mv]
-                (mlet [v mv
-                       vs mvs]
-                  (return (cons v vs))))
-              (return '())
-              (reverse mvs)))))
+  (if (empty? mvs)
+    (return (ctx/get-current) ())
+    (let [ctx (ctx/get-current (first mvs))]
+      (ctx/with-context ctx
+        (reduce (fn [mvs mv]
+                  (mlet [v mv
+                         vs mvs]
+                    (return (cons v vs))))
+                (return ())
+                (reverse mvs))))))

 (defn mapseq
   "Given a function `mf` that takes a value and puts it into a
   monadic context, and a collection, map `mf` over the collection,
   calling `sequence` on the results.

-      (require '[cats.monad.maybe :as maybe])
-      (require '[cats.core :as m])
+      (require '[cats.context :as ctx]
+               '[cats.monad.maybe :as maybe]
+               '[cats.core :as m])

       (m/mapseq maybe/just [2 3])
       ;=> <Just [[2 3]]>
@@ -574,7 +584,11 @@
                     (maybe/just v)
                     (maybe/nothing)))
                 [1 2])
-      ;=> <Nothing>
+      ;; => #<Nothing>
+
+      (ctx/with-context maybe/context
+        (mapseq #(maybe/just (* % 2)) []))
+      ;; => #<Just [()]>
   "
   [mf coll]
   (sequence (map mf coll)))


New test: test-new-file-4

New test: test-new-file-4

--- test/clj_fileutils/fileutils_test.clj
+++ test/clj_fileutils/fileutils_test.clj
@@ -101,3 +101,10 @@
             "/abc/def"     (.toString (new-file "" "abc/def"))
             "/abc/def/xyz" (.toString (new-file "" "abc/def/xyz")))))

+(deftest test-new-file-4
+    "Check the function clj-fileutils.fileutils/new-file."
+    (testing "Check the function clj-fileutils.fileutils/new-file."
+        (are [x y] (= x y)
+            "abc/def"         (.toString (new-file "abc" "def"))
+            "abc/abc.def"     (.toString (new-file "abc" "abc.def")))))
+


test for PUT /api/meta/db/:id/members/:user-id

--- test/metabase/api/org_test.clj
+++ test/metabase/api/org_test.clj
@@ -133,7 +133,7 @@
   (exists? OrgPerm :organization_id org-id :user_id user-id))

 (defn create-org-perm [org-id user-id]
-  ((user->client :crowberto) :post 200 (format "org/%d/members/%d" org-id user-id)))
+  ((user->client :crowberto) :post 200 (format "org/%d/members/%d" org-id user-id) {:admin false}))

 ;; ## POST /api/org/:id/members/:user-id
 ;; Check that we can create an OrgPerm between existing User + Org
@@ -159,3 +159,18 @@
          (org-perm-exists?))
      (do ((user->client :crowberto) :delete 204 (format "org/%d/members/%d" org-id user-id))
          (org-perm-exists?))]))
+
+;; ## PUT /api/org/:id/members/:user-id
+;; Check that we can edit an exisiting OrgPerm (i.e., toggle 'admin' status)
+(expect
+    [nil
+     false
+     true]
+  (let [{org-id :id} (create-org (random-name))
+        {user-id :id} (create-user)
+        is-admin? (fn [] (sel :one :field [OrgPerm :admin] :user_id user-id :organization_id org-id))]
+    [(is-admin?)
+     (do (create-org-perm org-id user-id)
+         (is-admin?))
+     (do ((user->client :crowberto) :put 200 (format "org/%d/members/%d" org-id user-id) {:admin true})
+         (is-admin?))]))


test fix

test fix

--- test/metabase/api/meta/field_test.clj
+++ test/metabase/api/meta/field_test.clj
@@ -68,7 +68,7 @@
        :preview_display true
        :created_at $
        :base_type "FloatField"})
-  (let [result ((user->client :rasta) :put 200 (format "meta/field/:id" (field->id :venues :latitude)) {:special_type :latitude})]
+  (let [result ((user->client :rasta) :put 200 (format "meta/field/%d" (field->id :venues :latitude)) {:special_type :latitude})]
     ;; this is sketchy. But return the Field back to its unmodified state so it won't affect other unit tests
     (upd Field (field->id :venues :latitude) :special_type nil)
     ;; return the modified Field


Corrected require statement

Corrected require statement

--- src/cine/utils.clj
+++ src/cine/utils.clj
@@ -1,5 +1,5 @@
 (ns cine.utils
-  (:require [clojure.string :str])
+  (:require [clojure.string :as str])
   (:gen-class))

 (defn month-to-num [^String month]