#99 readd comparison to default in benchmark

--- benchmarks/cheshire/test/benchmark.clj
+++ benchmarks/cheshire/test/benchmark.clj
@@ -26,7 +26,8 @@

 (def test-pretty-opts
   {:pretty {:indentation 4
-            :object-key-value-separator ": "}})
+            :indent-arrays? true
+            :object-field-value-separator ": "}})

 (def big-test-obj
   (-> "test/all_month.geojson.gz"
@@ -57,8 +58,6 @@

 (deftest t-bench-pretty
   (println "------- PrettyPrint Benchmarks ------")
-  (println "........without pretty printer")
-  (bench/bench (core/encode test-obj))
   (println "........default pretty printer")
   (bench/bench (core/encode test-obj {:pretty true}))
   (println "........custom pretty printer")


server - return known errors in 500s

server - return known errors in 500s

--- src/osmium/core.clj
+++ src/osmium/core.clj
@@ -41,7 +41,7 @@
    (POST "/login" {params :params}
      (let [user (user/login db (map-keys keyword params))]
        (if-let [error (:error user)]
-         (pr-str {:error error})
+         (web/error-page {:error error})
          (-> (response/redirect "/")
              (assoc-in [:session :user] user)))))
    (GET "/logout" _
@@ -51,14 +51,14 @@
    (POST "/signup" {params :params}
      (let [new-user (user/signup! db (map-keys keyword params))]
        (if-let [error (:error new-user)]
-         (pr-str error)
+         (web/error-page error)
          (-> (format "/user/%s" (:user/email new-user))
              response/redirect
              (assoc :session {:user new-user})))))
    (POST "/update-pass" {params :params}
      (let [new-user (user/update-password! db (map-keys keyword params))]
        (if-let [error (:error new-user)]
-         (pr-str error)
+         (web/error-page error)
          (response/redirect (format "/user/%s" (:user/email new-user))))))
    (GET "/book" {session :session}
      (if-not (web/logged-in? session)
@@ -69,7 +69,7 @@
        (response/status (response/response "Not authorized") 401)
        (let [new-book (book/new-book! db (map-keys (partial keyword "book") params))]
          (if-let [error (:error new-book)]
-           (pr-str error)
+           (web/error-page error)
            (response/redirect (format "/book/%s" (:db/id new-book)))))))
    (GET "/book/:id" {params :params session :session}
      (let [book (book/by-id db (Long. (:id params)))


Doc update. Missed a spot!

Doc update. Missed a spot!

--- src/algebolic/expression/core.clj
+++ src/algebolic/expression/core.clj
@@ -34,6 +34,7 @@
 ;; - the interpreter (interpreter.clj)
 ;; - the differentiator (differentiation.clj)
 ;; - possibly the computer algebra code (algebra.clj)
+;; - the Mathematica export code (mma.clj)
 (def function-symbols
   "The primitive set of functions that algebolic expressions can be built from."
   [{:name :plus :arity 2}


error check unneeded

error check unneeded

--- src/structural_typing/guts/type_descriptions/dc_type_maps.clj
+++ src/structural_typing/guts/type_descriptions/dc_type_maps.clj
@@ -25,7 +25,6 @@
       as-type-expander))

 (defn substitute [type-map forms]
-;  (when-not (sequential? forms) (boom! "Can't substitute type map into non-sequential %s" forms))
   (specter/transform (specter/walker type-expander?)
                      #(% type-map)
                      forms))


Add increasing applet id to untitled default string

--- src/quil/applet.clj
+++ src/quil/applet.clj
@@ -10,6 +10,8 @@

 (def ^{:private true}
   toupper (memfn toUpperCase))
+
+(defonce untitled-applet-id* (atom 0))

 (defn- fix-mname
   "Changes :method-name to :methodName."
@@ -61,7 +63,7 @@
                       JFrame/EXIT_ON_CLOSE
                       JFrame/DISPOSE_ON_CLOSE)]
        (reset! (:frame m)
-               (let [f (JFrame. (or (:title m) "Processing-core"))]
+               (let [f (JFrame. (or (:title m) (str "Quil " (swap! untitled-applet-id* inc))))]
                  (doto f
                    (.addWindowListener  (reify WindowListener
                                           (windowActivated [this e])


Border now have a default size of "none" which seems more correct than "auto". Certainly the demo page seems more sensible.

--- src/re_com/box.cljs
+++ src/re_com/box.cljs
@@ -447,7 +447,7 @@
    {:name :t-border   :required false                                :type "string"          :validate-fn string?           :description [:span "a CSS border style for the top border. Overrides " [:code ":border"]]}
    {:name :b-border   :required false                                :type "string"          :validate-fn string?           :description [:span "a CSS border style for the bottom. Overrides " [:code ":border"]]}
    {:name :radius     :required false                                :type "string"          :validate-fn string?           :description "a CSS radius style eg.\"2px\""}
-   {:name :size       :required false :default "auto"                :type "string"          :validate-fn string?           :description [:span "Equivalent to CSS style " [:span.bold "flex"] "." [:br]  "Examples: " [:code "initial"] ", " [:code "auto"] ", " [:code "none"]", " [:code "100px"] ", " [:code "2"] " or a generic triple of " [:code "grow/shrink/basis"]]}
+   {:name :size       :required false :default "none"                :type "string"          :validate-fn string?           :description [:span "Equivalent to CSS style " [:span.bold "flex"] "." [:br]  "Examples: " [:code "initial"] ", " [:code "auto"] ", " [:code "none"]", " [:code "100px"] ", " [:code "2"] " or a generic triple of " [:code "grow/shrink/basis"]]}
    {:name :width      :required false                                :type "string"          :validate-fn string?           :description "a CSS style describing the initial width"}
    {:name :height     :required false                                :type "string"          :validate-fn string?           :description "a CSS style describing the initial height"}
    {:name :min-width  :required false                                :type "string"          :validate-fn string?           :description "a CSS width style. The minimum width to which the box can shrink"}
@@ -468,7 +468,7 @@
     - border-style: none, hidden, dotted, dashed, solid, double, groove, ridge, inset, outset
     - color:        standard CSS color (e.g. grey #88ffee)"
   [& {:keys [size width height min-width min-height margin padding border l-border r-border t-border b-border radius child class style attr]
-      :or   {size "auto"}
+      :or   {size "none"}
       :as   args}]
   {:pre [(validate-args-macro border-args-desc args "border")]}
   (let [no-border      (every? nil? [border l-border r-border t-border b-border])


Remove 'clever' mapping of check fn over pan ugens. Also add checks for  balance2. Fixes #237.

--- src/overtone/sc/machinery/ugen/metadata/pan.clj
+++ src/overtone/sc/machinery/ugen/metadata/pan.clj
@@ -30,72 +30,71 @@
 ;; }

 (def specs
-  (map
-   #(assoc % :check (when-ar (first-input-ar)))
-   [
-
-    {:name "Pan2"
-     :args [{:name "in"
-             :doc "input signal"}
-
-            {:name "pos"
-             :default 0.0
-             :doc "pan position, -1 is left, +1 is right"}
-
-            {:name "level"
-             :default 1.0
-             :doc "a control rate level input"}]
-
-     :num-outs 2
-     :check (nth-input-stream? 0)
-     :doc "Two channel (stereo) equal power panner."}
-
-
-    {:name "LinPan2"
-     :extends "Pan2"
-     :doc "Two channel (stereo) linear panner. This one sounds more like
+  [
+   {:name "Pan2"
+    :args [{:name "in"
+            :doc "input signal"}
+
+           {:name "pos"
+            :default 0.0
+            :doc "pan position, -1 is left, +1 is right"}
+
+           {:name "level"
+            :default 1.0
+            :doc "a control rate level input"}]
+
+    :num-outs 2
+    :check (nth-input-stream? 0)
+    :doc "Two channel (stereo) equal power panner."}
+
+
+   {:name "LinPan2"
+    :extends "Pan2"
+    :doc "Two channel (stereo) linear panner. This one sounds more like
            the Rhodes tremolo than Pan2." }

-    {:name "Pan4",
-     :args [{:name "in",
-             :doc "input signal"}
-
-            {:name "xpos",
-             :default 0.0,
-             :doc "x pan position from -1 to +1 (left to right)"}
-
-            {:name "ypos",
-             :default 0.0,
-             :doc "y pan position from -1 to +1 (back to front)"}
-
-            {:name "level",
-             :default 1.0,
-             :doc "a control rate level input."}]
-
-     :num-outs 4
-     :check (nth-input-stream? 0)
-     :doc "Four channel equal power panner. Outputs are in order
+   {:name "Pan4",
+    :args [{:name "in",
+            :doc "input signal"}
+
+           {:name "xpos",
+            :default 0.0,
+            :doc "x pan position from -1 to +1 (left to right)"}
+
+           {:name "ypos",
+            :default 0.0,
+            :doc "y pan position from -1 to +1 (back to front)"}
+
+           {:name "level",
+            :default 1.0,
+            :doc "a control rate level input."}]
+
+    :num-outs 4
+    :check (nth-input-stream? 0)
+    :doc "Four channel equal power panner. Outputs are in order
            LeftFront, RightFront, LeftBack, RightBack." }

-    {:name "Balance2",
-     :args [{:name "left",
-             :doc "channel 1 of input stereo signal"}
-
-            {:name "right",
-             :doc "channel 2 of input stereo signal"}
-
-            {:name "pos",
-             :default 0.0,
-             :doc "pan position, -1 is left, +1 is right"}
-
-            {:name "level",
-             :default 1.0,
-             :doc "a control rate level input."}]
-
-     :num-outs 2
-     :doc "Equal power panning balances two channels; by panning, you
+   {:name "Balance2",
+    :args [{:name "left",
+            :doc "channel 1 of input stereo signal"}
+
+           {:name "right",
+            :doc "channel 2 of input stereo signal"}
+
+           {:name "pos",
+            :default 0.0,
+            :doc "pan position, -1 is left, +1 is right"}
+
+           {:name "level",
+            :default 1.0,
+            :doc "a control rate level input."}]
+    :rates #{:ar}
+    :check [(nth-input-ar 0)
+            (nth-input-ar 1)]
+    :num-outs 2
+    :doc "Equal power panning balances two channels; by panning, you
            are favouring one or other channel in the mix, and the other
            loses power. The middle pan position (pos=0.0) corresponds to
            the original stereo mix; full left (pos of -1) is essentially
@@ -103,22 +102,22 @@
            right. The output of Balance2 remains a stereo signal." }

-    {:name "Rotate2",
-     :args [{:name "x",
-             :doc "input signal"}
-
-            {:name "y",
-             :doc "input signal"}
-
-            {:name "pos",
-             :default 0.0,
-             :doc "angle to rotate around the circle from -1 to +1. -1
+   {:name "Rotate2",
+    :args [{:name "x",
+            :doc "input signal"}
+
+           {:name "y",
+            :doc "input signal"}
+
+           {:name "pos",
+            :default 0.0,
+            :doc "angle to rotate around the circle from -1 to +1. -1
                    is 180 degrees, -0.5 is left, 0 is forward, +0.5 is
                    right, +1 is behind." }]
-     :num-outs 2
-     :check [(nth-input-stream? 0)
-             (nth-input-stream? 1)]
-     :doc "Rotate2 can be used for rotating an ambisonic B-format sound
+    :num-outs 2
+    :check [(nth-input-stream? 0)
+            (nth-input-stream? 1)]
+    :doc "Rotate2 can be used for rotating an ambisonic B-format sound
            field around an axis.

            Rotate2 does an equal power rotation so it also works well on
@@ -135,68 +134,68 @@
            rotation around a circle." }

-    {:name "PanB",
-     :args [{:name "in",
-             :doc "input signal"}
-
-            {:name "azimuth",
-             :default 0.0,
-             :doc "in radians, -pi to +pi"}
-
-            {:name "elevation",
-             :default 0.0,
-             :doc "in radians, -0.5pi to +0.5pi"}
-
-            {:name "gain",
-             :default 1.0,
-             :doc "a control rate level input"}]
-
-     :num-outs 4
-     :check (nth-input-stream? 0)
-     :doc "Ambisonic B format panner. Output channels are in order
+   {:name "PanB",
+    :args [{:name "in",
+            :doc "input signal"}
+
+           {:name "azimuth",
+            :default 0.0,
+            :doc "in radians, -pi to +pi"}
+
+           {:name "elevation",
+            :default 0.0,
+            :doc "in radians, -0.5pi to +0.5pi"}
+
+           {:name "gain",
+            :default 1.0,
+            :doc "a control rate level input"}]
+
+    :num-outs 4
+    :check (nth-input-stream? 0)
+    :doc "Ambisonic B format panner. Output channels are in order
            W,X,Y,Z." }

-    {:name "PanB2",
-     :args [{:name "in",
-             :doc "input signal"}
-
-            {:name "azimuth",
-             :default 0.0,
-             :doc "position around the circle from -1 to +1. -1 is
+   {:name "PanB2",
+    :args [{:name "in",
+            :doc "input signal"}
+
+           {:name "azimuth",
+            :default 0.0,
+            :doc "position around the circle from -1 to +1. -1 is
                    behind, -0.5 is left, 0 is forward, +0.5 is right, +1
                    is behind." }

-            {:name "gain",
-             :default 1.0,
-             :doc "amplitude control"}]
-
-     :num-outs 3
-     :check (nth-input-stream? 0)
-     :doc "Encode a mono signal to two dimensional ambisonic B-format."}
-
-
-    {:name "BiPanB2",
-     :args [{:name "in-a",
-             :doc "input signal A"}
-
-            {:name "in-b",
-             :doc "input signal B"}
-
-            {:name "azimuth",
-             :doc "position around the circle from -1 to +1. -1 is
+           {:name "gain",
+            :default 1.0,
+            :doc "amplitude control"}]
+
+    :num-outs 3
+    :check (nth-input-stream? 0)
+    :doc "Encode a mono signal to two dimensional ambisonic B-format."}
+
+
+   {:name "BiPanB2",
+    :args [{:name "in-a",
+            :doc "input signal A"}
+
+           {:name "in-b",
+            :doc "input signal B"}
+
+           {:name "azimuth",
+            :doc "position around the circle from -1 to +1. -1 is
                    behind, -0.5 is left, 0 is forward, +0.5 is right, +1
                    is behind." }

-            {:name "gain",
-             :default 1.0,
-             :doc "amplitude control"}]
-
-     :num-outs 3
-     :check [(when-ar (first-n-inputs-ar 2))
-             (nth-input-stream? 0)
-             (nth-input-stream? 1)]
-     :doc "Encode a two channel signal to two dimensional ambisonic
+           {:name "gain",
+            :default 1.0,
+            :doc "amplitude control"}]
+
+    :num-outs 3
+    :check [(when-ar (first-n-inputs-ar 2))
+            (nth-input-stream? 0)
+            (nth-input-stream? 1)]
+    :doc "Encode a two channel signal to two dimensional ambisonic
            B-format.  This puts two channels at opposite poles of a 2D
            ambisonic field.  This is one way to map a stereo sound onto
            a soundfield.  It is equivalent to:
@@ -204,46 +203,46 @@
            PanB2(inA, azimuth, gain) + PanB2(inB, azimuth + 1, gain)"}

-    {:name "DecodeB2",
-     :args [{:name "numChannels"
-             :mode :num-outs,
-             :doc "number of output speakers. Typically 4 to 8."}
-
-            {:name "w",
-             :doc "B-format signal"}
-
-            {:name "x",
-             :doc "B-format signal"}
-
-            {:name "y",
-             :doc "B-format signal"}
-
-            {:name "orientation",
-             :default 0.5,
-             :doc "Should be zero if the front is a vertex of the
+   {:name "DecodeB2",
+    :args [{:name "numChannels"
+            :mode :num-outs,
+            :doc "number of output speakers. Typically 4 to 8."}
+
+           {:name "w",
+            :doc "B-format signal"}
+
+           {:name "x",
+            :doc "B-format signal"}
+
+           {:name "y",
+            :doc "B-format signal"}
+
+           {:name "orientation",
+            :default 0.5,
+            :doc "Should be zero if the front is a vertex of the
                    polygon. The first speaker will be directly in
                    front. Should be 0.5 if the front bisects a side of
                    the polygon. Then the first speaker will be the one
                    left of center. Default is 0.5." }]
-     :doc "2D Ambisonic B-format decoder. Decode a two dimensional
+    :doc "2D Ambisonic B-format decoder. Decode a two dimensional
            ambisonic B-format signal to a set of speakers in a regular
            polygon.  The outputs will be in clockwise order. The
            position of the first speaker is either center or left of
            center."
-     :check (when-ar (first-n-inputs-ar 3))}
-
-
-    {:name "PanAz",
-     :args [{:name "num-channels"
-             :mode :num-outs,
-             :doc "number of output channels"}
-
-            {:name "in",
-             :doc "input signal"}
-
-            {:name "pos",
-             :default 0.0,
-             :doc "pan position. Channels are evenly spaced over a
+    :check (when-ar (first-n-inputs-ar 3))}
+
+
+   {:name "PanAz",
+    :args [{:name "num-channels"
+            :mode :num-outs,
+            :doc "number of output channels"}
+
+           {:name "in",
+            :doc "input signal"}
+
+           {:name "pos",
+            :default 0.0,
+            :doc "pan position. Channels are evenly spaced over a
                    cyclic period of 2.0 with 0.0 equal to the position
                    directly in front, 2.0/numChans a clockwise shift
                    1/numChans of the way around the ring, 4.0/numChans
@@ -254,70 +253,70 @@
                    speaker depending on the setting of the orientation
                    arg, see below." }

-            {:name "level",
-             :default 1.0,
-             :doc "a control rate level input."}
-
-            {:name "width",
-             :default 2.0,
-             :doc "The width of the panning envelope. Nominally this is
+           {:name "level",
+            :default 1.0,
+            :doc "a control rate level input."}
+
+           {:name "width",
+            :default 2.0,
+            :doc "The width of the panning envelope. Nominally this is
                    2.0 which pans between pairs of adjacent
                    speakers. Width values greater than two will spread
                    the pan over greater numbers of speakers. Width
                    values less than one will leave silent gaps between
                    speakers." }

-            {:name "orientation",
-             :default 0.5,
-             :doc "Should be zero if the front is a vertex of the
+           {:name "orientation",
+            :default 0.5,
+            :doc "Should be zero if the front is a vertex of the
                    polygon. The first speaker will be directly in
                    front. Should be 0.5 if the front bisects a side of
                    the polygon. Then the first speaker will be the one
                    left of center. Default is 0.5." }]
-     :check (nth-input-stream? 1)
-     :doc "Multichannel equal power panner."}
-
-    {:name "XFade2",
-     :args [{:name "inA"
-             :doc "input signal A"}
-
-            {:name "inB"
-             :doc "input signal B"}
-
-            {:name "pan",
-             :default 0.0
-             :doc "Pan between the two input signals with -1 being inA
+    :check (nth-input-stream? 1)
+    :doc "Multichannel equal power panner."}
+
+   {:name "XFade2",
+    :args [{:name "inA"
+            :doc "input signal A"}
+
+           {:name "inB"
+            :doc "input signal B"}
+
+           {:name "pan",
+            :default 0.0
+            :doc "Pan between the two input signals with -1 being inA
                    only and 1 being inB only with values between being a
                    mix of the two." }

-            {:name "level",
-             :default 1.0
-             :doc "Output level - 0 being silent and 1 being original
+           {:name "level",
+            :default 1.0
+            :doc "Output level - 0 being silent and 1 being original
                    volume"}]

-     :check [(when-ar (first-n-inputs-ar 2))
-             (nth-input-stream? 0)
-             (nth-input-stream? 1)]
-     :rates #{:ar :kr}
-     :doc "Equal power two channel cross fade"}
-
-    {:name "LinXFade2",
-     :args [{:name "inA",
-             :doc "input signal A"}
-
-            {:name "inB",
-             :doc "input signal B"}
-
-            {:name "pan",
-             :default 0.0,
-             :doc "cross fade position from -1 to +1"}
-
-            {:name "level",
-             :default 1.0,
-             :doc "a control rate level input"}]
-
-     :rates #{:ar :kr}
-     :doc "Two channel linear crossfader."
-     :check [(when-ar (first-n-inputs-ar 2))
-             (nth-input-stream? 0)
-             (nth-input-stream? 1)]}]))
+    :check [(when-ar (first-n-inputs-ar 2))
+            (nth-input-stream? 0)
+            (nth-input-stream? 1)]
+    :rates #{:ar :kr}
+    :doc "Equal power two channel cross fade"}
+
+   {:name "LinXFade2",
+    :args [{:name "inA",
+            :doc "input signal A"}
+
+           {:name "inB",
+            :doc "input signal B"}
+
+           {:name "pan",
+            :default 0.0,
+            :doc "cross fade position from -1 to +1"}
+
+           {:name "level",
+            :default 1.0,
+            :doc "a control rate level input"}]
+
+    :rates #{:ar :kr}
+    :doc "Two channel linear crossfader."
+    :check [(when-ar (first-n-inputs-ar 2))
+            (nth-input-stream? 0)
+            (nth-input-stream? 1)]}])


Exotic numbers

Exotic numbers

--- test/bluebell/utils/setdispatch_test.clj
+++ test/bluebell/utils/setdispatch_test.clj
@@ -10,6 +10,7 @@
   (cond
     (double? x) :double
     (float? x) :float
+    (integer? x) :integer
     (number? x) :number
     (keyword? x) :keyword
     (string? x) :string
@@ -17,6 +18,7 @@
     (set? x) :set
     (coll? x) :coll))

+(subset-of ts :integer :number)
 (subset-of ts :double :number)
 (subset-of ts :float :number)
 (subset-of ts :map :coll)
@@ -26,6 +28,9 @@
 (subset-of ts :string :atom)
 (subset-of ts :coll :all)
 (subset-of ts :atom :all)
+
+(def exotic-number (difference :number
+                               (union :double :float :integer)))

 (def-dispatch my-plus ts get-feature)

@@ -83,6 +88,11 @@
    [:double b]]
   [:special-double-add a b])

+(def-set-method my-plus "Exotic addition"
+  [[exotic-number a]
+   [exotic-number b]]
+  [:exotic (+ a b)])
+

 (deftest test-it
   (is (= [:double-sum 7.9]
@@ -110,6 +120,8 @@
                   {:b 4})))
   (is (= [:triple-plus 6]
          (my-plus 1 2 3)))
+  (is (= [:exotic 5/7]
+         (my-plus 3/7 2/7)))
   (is (= (my-plus :a 3.4)
          [:special-double-add :a 3.4]))
   (is (thrown?


reorder

reorder

--- src/ads_txt_crawler/crawl.clj
+++ src/ads_txt_crawler/crawl.clj
@@ -6,19 +6,6 @@
 (defn print-record [domain record]
   (let [{:keys [exchange-domain account-id account-type tag-id]} record]
     (println (format "%s,%s,%s,%s,%s" domain exchange-domain account-id account-type tag-id))))
-
-(defn crawl
-  "Crawl a list of domains and process them with the output-fn.
-  The output-fn should accept a single parameter which is the return map from process/process-to-map
-
-  The domains list can be generated from a file from the domains/domains function.
-  Domains from other sources should be pre-processed with domains/clean-domain-name."
-  [domains output-fnc]
-  (doseq [d domains]
-    (let [data (p/process-to-map d)]
-      (if-let [err (:error data)]
-        (.println *err* (:message data))
-        (output-fnc data)))))

 (defn print-results
   "Print the results to stdout"
@@ -37,3 +24,17 @@
           records (:records data)]
       (doseq [record records]
         (data/save-record domain record dbname)))))
+
+(defn crawl
+  "Crawl a list of domains and process them with the output-fn.
+  The output-fn should accept a single parameter which is the return map from process/process-to-map
+
+  The domains list can be generated from a file from the domains/domains function.
+  Domains from other sources should be pre-processed with domains/clean-domain-name."
+  [domains output-fnc]
+  (doseq [d domains]
+    (let [data (p/process-to-map d)]
+      (if-let [err (:error data)]
+        (.println *err* (:message data))
+        (output-fnc data)))))
+


Add comment about fn-deprecated data

Add comment about fn-deprecated data

--- src/adzerk/boot_cljs/impl.clj
+++ src/adzerk/boot_cljs/impl.clj
@@ -98,6 +98,9 @@
                                           :file path
                                           :type warning-type
                                           :message s
+                                          ;; :fn-deprecated warning contains the whole
+                                          ;; analyze result as extra data, and :env value
+                                          ;; of that is unprintable.
                                           :extra (cond-> extra
                                                    (:fexpr extra) (update :fexpr dissoc :env))}]
                         (butil/warn "WARNING: %s %s\n" s (if (:line env)


Clean warning file path handing

Clean warning file path handing

--- src/adzerk/boot_cljs/impl.clj
+++ src/adzerk/boot_cljs/impl.clj
@@ -71,23 +71,20 @@
 (defn compile-cljs
   "Given a seq of directories containing CLJS source files and compiler options
   opts, compiles the CLJS to produce JS files."
-  [input-path {:keys [optimizations asset-path] :as opts}]
+  [input-path {:keys [optimizations] :as opts}]
   ;; So directories need to be passed to cljs compiler when compiling in dev
   ;; or there are stale namespace problems with tests. However, if compiling
   ;; with optimizations other than :none adding directories will break the
   ;; build and defeat tree shaking and :main option.
   (let [dirs (:directories pod/env)
-        ;; Includes also some tmp-dirs passed to this pod, but shouldn't matter
+        ; Includes also some tmp-dirs passed to this pod, but shouldn't matter
         source-paths (concat (:source-paths pod/env) (:resource-paths pod/env))
         warnings (atom [])
         handler (fn [warning-type env extra]
                   (when (warning-enabled? warning-type)
                     (when-let [s (ana/error-message warning-type extra)]
                       (let [path (if (= (-> env :ns :name) 'cljs.core)
-                                   ;; AR - figwheel does this as well
-                                   (-> asset-path
-                                       (str/replace #"/$" "")
-                                       (str "/cljs/core.cljs"))
+                                   "cljs/core.cljs"
                                    (util/find-original-path source-paths dirs ana/*cljs-file*))
                             warning-data {:line (:line env)
                                           :column (:column env)
@@ -96,7 +93,8 @@
                                           :type warning-type
                                           :message s
                                           :extra extra}]
-                        (butil/warn "WARNING: %s %s\n" s (when (:line env) (str "at line " (:line env) " " path)))
+                        (butil/warn "WARNING: %s %s\n" s (when (:line env)
+                                                           (str "at line " (:line env) " " path)))
                         (butil/dbug "%s\n" (butil/pp-str warning-data))
                         (swap! warnings conj warning-data)))))]
     (try


+her,+his,+my,+your

+her,+his,+my,+your

--- src/babel/english/lexicon.clj
+++ src/babel/english/lexicon.clj
@@ -643,7 +643,10 @@
              :sem {:pred :aiutare
                    :activity true
                    :obj {:human true}}}}
-
+   "her"
+   {:synsem {:cat :det
+             :sem {:pred :lei}
+             :def :possessive}}
    "herself"
    {:synsem {:cat :noun
              :pronoun true
@@ -667,6 +670,10 @@
              :sem {:human true
                    :pred :lui}
              :subcat '()}}
+   "his"
+   {:synsem {:cat :det
+             :sem {:pred :lui}
+             :def :possessive}}

    "hit" {:english {:past "hit"}
              :synsem {:cat :verb
@@ -939,6 +946,7 @@
              :sem {:pred :music}}}
    "my"
    {:synsem {:cat :det
+             :sem {:pred :I}
              :def :possessive}}
    "myself"
    {:synsem {:cat :noun
@@ -1532,6 +1540,11 @@
                    :pred :voi}
              :subcat '()}}

+   "your"
+   {:synsem {:cat :det
+             :sem {:pred :tu}
+             :def :possessive}}
+
    "yourself"
    [{:note "♀"
      :synsem {:cat :noun


Add docstring to defhook

Add docstring to defhook

--- src/braid/core/module_helpers.clj
+++ src/braid/core/module_helpers.clj
@@ -89,6 +89,14 @@
                  (deref (resolve '~v)))))))))

 (defmacro defhook
+  "Macro to generate a module extension point.
+  `:writer` will be a function name that should be in the
+  `:provides` section of the module.edn.
+  `:reader` will be deref-able and will give a collection of the
+  values passed to the writer.
+
+  By default, the values will be `conj`-ed into a vector, but this can
+  be customized with the `:initial-val` and `:add-fn` arguments."
   [& {:keys [reader writer initial-val add-fn]
       :or {initial-val [] add-fn conj}}]
   (assert (symbol? reader))


Fix error reporting for s3 upload

Fix error reporting for s3 upload

--- src/braid/core/client/s3.cljs
+++ src/braid/core/client/s3.cljs
@@ -13,7 +13,7 @@
     {:method :get
      :uri "/s3-policy"
      :on-error (fn [err]
-                 (errorf "Error getting s3 authorization: %s" (:error err)))
+                 (errorf "Error getting s3 authorization: %s" err))
      :on-complete
      (fn [{:keys [bucket auth]}]
        (let [file-name (.-name file)


Update instructions for trying it with curl.

--- src/clj/cljs/eval/browser.clj
+++ src/clj/cljs/eval/browser.clj
@@ -174,9 +174,9 @@
 (comment

   ;; Try it out
-
-  (require '[cljs.repl :as repl])
-  (require '[cljs.eval.browser :as eval-env])
+
+  (use 'cljs.repl)
+  (use 'cljs.eval.browser)
   (def repl-env (create-eval-env 9000))
   (repl repl-env)
   ;; curl -v -d "ready" http://127.0.0.1:9000


Safari stacktrace mapping support in browser REPL

--- src/clj/cljs/repl/browser.clj
+++ src/clj/cljs/repl/browser.clj
@@ -198,10 +198,83 @@
   (comp/with-core-cljs nil
     (fn [] (server/start repl-env))))

+;; =============================================================================
+;; Stracktrace parsing
+
+(defmulti parse-stacktrace (fn [repl-env st err opts] (:ua-product err)))
+
+;; -----------------------------------------------------------------------------
+;; Safari Stacktrace
+
+(defn safari-st-el->frame
+  "Parses a stack line into a frame representation, returning nil
+  if parse failed."
+  [st-el opts]
+  (let [[function flc] (if (re-find #"@" st-el)
+                         (string/split st-el #"@")
+                         [nil st-el])
+        xs (string/split flc #":")
+        [pre post]
+        (reduce
+          (fn [[pre post] [x i]]
+            (if (<= i 2)
+              [pre (conj post x)]
+              [(conj pre x) post]))
+          [[] []] (map vector xs (range (count xs) 0 -1)))
+        file (string/join ":" pre)
+        [line column] (map #(Long/parseLong %) post)]
+    (if (and file function line column)
+      {:file (if (re-find #"http://localhost:9000/" file)
+               (-> file
+                 (string/replace #"http://localhost:9000/" "")
+                 (string/replace (Pattern/compile (str "^" (util/output-directory opts) "/")) ""))
+               (if-let [asset-root (:asset-root opts)]
+                 (string/replace file asset-root "")
+                 (throw
+                   (ex-info (str "Could not relativize URL " file)
+                     {:type :parse-stacktrace
+                      :reason :relativize-url}))))
+       :function function
+       :line line
+       :column column}
+      (when-not (string/blank? function)
+        {:file nil
+         :function (string/trim function)
+         :line nil
+         :column nil}))))
+
+(comment
+  (safari-st-el->frame
+    "cljs$core$seq@http://localhost:9000/out/cljs/core.js:4259:17" {})
+  )
+
+(defmethod parse-stacktrace :safari
+  [repl-env st err opts]
+  (->> st
+    string/split-lines
+    (take-while #(not (.startsWith % "eval code")))
+    (remove string/blank?)
+    (map #(safari-st-el->frame % opts))
+    (remove nil?)
+    vec))
+
+(comment
+  (parse-stacktrace nil
+    "cljs$core$seq@http://localhost:9000/out/cljs/core.js:4259:17\ncljs$core$first@http://localhost:9000/out/cljs/core.js:4289:22\ncljs$core$ffirst@http://localhost:9000/out/cljs/core.js:5357:39\nhttp://localhost:9000/out/cljs/core.js:16972:92\nhttp://localhost:9000/out/cljs/core.js:16973:3\nhttp://localhost:9000/out/cljs/core.js:10982:133\nsval@http://localhost:9000/out/cljs/core.js:10983:3\ncljs$core$ISeqable$_seq$arity$1@http://localhost:9000/out/cljs/core.js:11074:14\ncljs$core$seq@http://localhost:9000/out/cljs/core.js:4240:44\ncljs$core$pr_sequential_writer@http://localhost:9000/out/cljs/core.js:28707:17\ncljs$core$IPrintWithWriter$_pr_writer$arity$3@http://localhost:9000/out/cljs/core.js:29386:38\ncljs$core$pr_writer_impl@http://localhost:9000/out/cljs/core.js:28912:57\ncljs$core$pr_writer@http://localhost:9000/out/cljs/core.js:29011:32\ncljs$core$pr_seq_writer@http://localhost:9000/out/cljs/core.js:29015:20\ncljs$core$pr_sb_with_opts@http://localhost:9000/out/cljs/core.js:29078:24\ncljs$core$pr_str_with_opts@http://localhost:9000/out/cljs/core.js:29092:48\ncljs$core$pr_str__delegate@http://localhost:9000/out/cljs/core.js:29130:34\ncljs$core$pr_str@http://localhost:9000/out/cljs/core.js:29139:39\n\neval code\neval@[native code]\nhttp://localhost:9000/out/clojure/browser/repl.js:23:271\nclojure$browser$repl$evaluate_javascript@http://localhost:9000/out/clojure/browser/repl.js:26:4\nhttp://localhost:9000/out/clojure/browser/repl.js:121:173\ndeliver@http://localhost:9000/out/goog/messaging/abstractchannel.js:142:21\nxpcDeliver@http://localhost:9000/out/goog/net/xpc/crosspagechannel.js:733:19\nmessageReceived_@http://localhost:9000/out/goog/net/xpc/nativemessagingtransport.js:321:23\nfireListener@http://localhost:9000/out/goog/events/events.js:741:25\nhandleBrowserEvent_@http://localhost:9000/out/goog/events/events.js:862:34\nhttp://localhost:9000/out/goog/events/events.js:276:42"
+    {:ua-product :safari}
+    nil)
+  )
+
+;; =============================================================================
+;; BrowserEnv
+
 (defrecord BrowserEnv []
   repl/IJavaScriptEnv
   (-setup [this opts]
     (setup this opts))
+  repl/IParseStacktrace
+  (-parse-stacktrace [this st err opts]
+    (parse-stacktrace this st err opts))
   (-evaluate [_ _ _ js] (browser-eval js))
   (-load [this provides url]
     (load-javascript this provides url))


unparallel

unparallel

--- src/clj/hdfs_cleaner/hdfs.clj
+++ src/clj/hdfs_cleaner/hdfs.clj
@@ -4,7 +4,7 @@
            (org.apache.hadoop.fs Path FileStatus)))

 (defn scan* [^Path path]
-  (pmap
+  (map
     (fn [^FileStatus file]
       (merge {:name (-> file (.getPath) (.getName))
               :path (-> file (.getPath) (.toString))


Need to wait for rendering somehow...

Need to wait for rendering somehow...

--- src/clj_simple_chart/core.clj
+++ src/clj_simple_chart/core.clj
@@ -76,8 +76,10 @@
         width (:width attrs)
         height (:height attrs)]
     (render-tag t)
+    (Platform/runLater (fn [] (.setPrefHeight @webview height)))
+    (Platform/runLater (fn [] (.setPrefWidth @webview width)))
     (Platform/runLater (fn [] (.sizeToScene @stage)))
-    (render-tag t)                                          ; TODO: Can this be simplified?
+    (Platform/runLater (fn [] (.show @stage)))
     (Platform/runLater
       (fn []
         (let [snap (SnapshotParameters.)]


Create a new component for displaying recurring expenses

--- src/cljs/my_money/events.cljs
+++ src/cljs/my_money/events.cljs
@@ -59,6 +59,9 @@
    [labelled-radio-button "expenses" "type"]
    [labelled-radio-button "incomes" "type"]])

+(defn amount->pretty-string [amount]
+  (str (/ amount 100) "€"))
+
 (defn bank-event-table [events]
   [:div.table-responsive
    [:table.table.table-striped
@@ -71,7 +74,7 @@
               ^{:key (:id event)}
               [:tr
                [:td (str (:transaction_date event))]
-               [:td (str (/ (:amount event) 100) "€")]
+               [:td (amount->pretty-string (:amount event))]
                [:td (str (:recipient event))]])]]])

 (defn- event-retrieval-handler [e]
@@ -94,6 +97,14 @@
   (let [month-filter (filters/month-filter month)]
     (filter month-filter events)))

+(defn recurring-expense-info [recurring-expenses]
+  [:div.list-group
+   (for [event recurring-expenses]
+     ^{:key (:id event)}
+     [:p.list-group-item (str (:recipient event)
+                              " "
+                              (amount->pretty-string(:amount event)))])])
+
 (defn events-page []
   (fn []
     (let [applied-filters (filters/combined-filter (:selected-filters @form-data))
@@ -112,4 +123,4 @@
          [bank-event-table filtered-events]]
         [:div.col-md-4
          [:h1 "Recurring expenses"]
-         [bank-event-table @recurring-expenses]]]])))
+         [recurring-expense-info @recurring-expenses]]]])))


Pass multijob test.

Pass multijob test.

--- test/onyx/coordinator/multi_job_test.clj
+++ test/onyx/coordinator/multi_job_test.clj
@@ -28,6 +28,10 @@

            sync-spy-a (chan 1)
            sync-spy-b (chan 1)
+
+           seal-spy-a (chan 1)
+           seal-spy-b (chan 1)
+
            ack-ch-spy (chan 2)
            offer-ch-spy (chan 10)
            status-spy (chan 2)
@@ -141,7 +145,11 @@
                                   :pulse-node (:node pulse-node-a)
                                   :payload-node (:node payload-node-a-2)
                                   :shutdown-node (:node shutdown-node-a)})
-
+
+         (extensions/on-change sync (:node/seal (:nodes payload-a)) #(>!! seal-spy-a %))
+         (extensions/touch-node sync (:node/exhaust (:nodes payload-a)))
+         (<!! seal-spy-a)
+
          (extensions/on-change sync (:node payload-node-a-2) #(>!! sync-spy-a %))
          (extensions/touch-node sync (:node/completion (:nodes payload-a))))

@@ -167,7 +175,11 @@
                                   :pulse-node (:node pulse-node-b)
                                   :payload-node (:node payload-node-b-2)
                                   :shutdown-node (:node shutdown-node-b)})
-
+
+         (extensions/on-change sync (:node/seal (:nodes payload-b)) #(>!! seal-spy-b %))
+         (extensions/touch-node sync (:node/exhaust (:nodes payload-b)))
+         (<!! seal-spy-b)
+
          (extensions/on-change sync (:node payload-node-b-2) #(>!! sync-spy-b %))
          (extensions/touch-node sync (:node/completion (:nodes payload-b)))

@@ -193,7 +205,11 @@
                                   :pulse-node (:node pulse-node-a)
                                   :shutdown-node (:node shutdown-node-a)
                                   :payload-node (:node payload-node-a-1)})
-
+
+         (extensions/on-change sync (:node/seal (:nodes payload-a)) #(>!! seal-spy-a %))
+         (extensions/touch-node sync (:node/exhaust (:nodes payload-a)))
+         (<!! seal-spy-a)
+
          (extensions/on-change sync (:node payload-node-a-1) #(>!! sync-spy-a %))
          (extensions/touch-node sync (:node/completion (:nodes payload-a)))

@@ -219,7 +235,11 @@
                                   :pulse-node (:node pulse-node-b)
                                   :shutdown-node (:node shutdown-node-b)
                                   :payload-node (:node payload-node-b-1)})
-
+
+         (extensions/on-change sync (:node/seal (:nodes payload-b)) #(>!! seal-spy-b %))
+         (extensions/touch-node sync (:node/exhaust (:nodes payload-b)))
+         (<!! seal-spy-b)
+
          (extensions/on-change sync (:node payload-node-b-1) #(>!! sync-spy-b %))
          (extensions/touch-node sync (:node/completion (:nodes payload-b)))

@@ -240,6 +260,15 @@

        (let [payload-a (extensions/read-node sync (:node payload-node-a-1))
              payload-b (extensions/read-node sync (:node payload-node-b-1))]
+
+         (extensions/on-change sync (:node/seal (:nodes payload-a)) #(>!! seal-spy-a %))
+         (extensions/touch-node sync (:node/exhaust (:nodes payload-a)))
+         (<!! seal-spy-a)
+
+         (extensions/on-change sync (:node/seal (:nodes payload-b)) #(>!! seal-spy-b %))
+         (extensions/touch-node sync (:node/exhaust (:nodes payload-b)))
+         (<!! seal-spy-b)
+
          (extensions/touch-node sync (:node/completion (:nodes payload-a)))
          (extensions/touch-node sync (:node/completion (:nodes payload-b)))


wrong key for :datomic/uri

wrong key for :datomic/uri

--- test/onyx/plugin/input_log_kill_test.clj
+++ test/onyx/plugin/input_log_kill_test.clj
@@ -75,7 +75,7 @@
 (deftest ^:ci datomic-input-log-kill-test
   (let [{:keys [env-config peer-config datomic-config]}
         (read-config (clojure.java.io/resource "config.edn") {:profile :test})
-        db-uri (str (:datomic/config datomic-config) (java.util.UUID/randomUUID))
+        db-uri (str (:datomic/uri datomic-config) (java.util.UUID/randomUUID))
         job (build-job db-uri 10 1000)
         {:keys [persist]} (core-async/get-core-async-channels job)
         job-id (atom nil)


partial implementation of An Offer You Can't Refuse

--- src/clj/game/cards-operations.clj
+++ src/clj/game/cards-operations.clj
@@ -11,6 +11,18 @@
    "Aggressive Negotiation"
    {:req (req (:scored-agenda corp-reg)) :prompt "Choose a card" :choices (req (:deck corp))
     :effect (effect (move target :hand) (shuffle! :deck))}
+
+   "An Offer You Cant Refuse"
+   {:prompt "Choose a server" :choices ["HQ" "R&D" "Archives"]
+    :effect (req (let [serv target]
+                   (resolve-ability
+                     state side
+                     {:optional
+                      {:prompt (msg "Make a run on " serv "?") :player :runner
+                       :yes-ability {:msg (msg "let the Runner make a run on " serv)}
+                       :no-ability {:effect (effect (as-agenda :corp (last (:discard corp)) 1))
+                                    :msg "add it to their score area and gain 1 agenda point"}}}
+                    card nil)))}

    "Anonymous Tip"
    {:effect (effect (draw 3))}


Change "agendas>2" to "agendas>1"

Change "agendas>2" to "agendas>1"

--- src/clj/game/cards-operations.clj
+++ src/clj/game/cards-operations.clj
@@ -2,7 +2,7 @@

 (def cards-operations
   {"24/7 News Cycle"
-   {:req (req (> (count (:scored corp)) 2))
+   {:req (req (> (count (:scored corp)) 1))
     :additional-cost [:forfeit]
     :prompt "Choose an agenda to trigger"
     :msg (msg "trigger the score ability on " (:title target))


Also fixes Strategic Innovations test error (if Hedge Fund not drawn).

--- src/clj/test/cards-identities.clj
+++ src/clj/test/cards-identities.clj
@@ -249,7 +249,7 @@
   "Strategic Innovations: Future Forward - Ability"
   (do-game
     (new-game
-      (make-deck "Strategic Innovations: Future Forward" [(qty "Hedge Fund" 2) (qty "Eli 1.0" 3) (qty "Crick" 3)])
+      (make-deck "Strategic Innovations: Future Forward" [(qty "Hedge Fund" 2) (qty "Eli 1.0" 2) (qty "Crick" 2)])
       (default-runner))
     (play-from-hand state :corp "Eli 1.0" "New remote")
     (play-from-hand state :corp "Hedge Fund")


added completions component

added completions component

(deleted by accident during the rebase)

--- src/cljs/cljs_repl_web/views.cljs
+++ src/cljs/cljs_repl_web/views.cljs
@@ -889,6 +889,8 @@
                         [console]
                         #(do (finish-tour tour)
                              (utils/scroll-to-top))]]
+                      [re-complete/completions console-key #(do (dispatch [:console-set-autocompleted-text console-key])
+                                                                (dispatch [:focus-console-editor console-key]))]
                       [welcome-modal-dialog]
                       [finished-tour-modal-dialog]]]
         (if (= :narrow @media-query)


Removed swears

Removed swears

Charlie came in and was looking the screen :)

--- src/cljs/my_project/appstate.cljs
+++ src/cljs/my_project/appstate.cljs
@@ -6,11 +6,7 @@
 (def app-state
   (atom
     {:update 0
-     :text "Little Shit Game"
-
-     :main-app { :name "Little Shit Game" }
-
+     :main-app { :name "Pogue" }
      :count {:count 0}
      :render-data gr/game-render-data
-
      }))


Clean some code

Clean some code

--- src/clojure/embla3d/new_world.clj
+++ src/clojure/embla3d/new_world.clj
@@ -2,6 +2,7 @@
   (:import (embla3d.engine.meshs MeshBuilder)
            [embla3d.engine World])
   (gen-class))
+
 ;;UTILS------------------------------------------------------------------
 (defn flat-map "flatten 'map'" [m]
   (flatten (conj (vals m))))
@@ -19,11 +20,10 @@
     (atom {:world world :thread thread})))

 ;;Since we completely destroy the old architecture we will migrate the basic method to this module
-;;TODO/README ONLY USE WORLD IT is A FACADE, no DIRECT USE OF MANAGEMENT/BUILDER TOOLS
-;; Material Fucntions---------------------------------------------
+;;README ONLY USE WORLD IT is A FACADE, no DIRECT USE OF MANAGEMENT/BUILDER TOOLS

 ;; Mesh Functions------------------------------------------------
-;;TODO create basic meshes
+
 (defn create-mesh!
   "Create an item in the `world` with the  specified id, position, mesh"
   [world & {:keys [vertices text-coord normals faces weight rgb texture-name]
@@ -66,7 +66,7 @@
             :or   {id       "can't read the doc..."
                    position [0 0 -2]
                    scale    1
-                   mesh     (create-mesh! world)}}]
+                   mesh     (create-mesh! world)}}]         ;;error here
   (.createItem world id (float-array position) scale mesh))

 (defn create-block!
@@ -86,7 +86,8 @@
 ;;TODO NEED CAMERA MANAGEMENT

 ;; Collision
-(defn create-boudingbox!
+
+(defn create-bouding-box!
   "Create a boundingbox in the `world` with the
   specified id, position, length, scale"
   [world & {:keys [id position length scale]
@@ -96,12 +97,14 @@
                    scale    1}}]

   (.createBoundingBox world id (float-array position) scale (float-array length)))
+(defn add-bounding-box!
+  "Add the specified 'bounding box' to the specified 'item'"
+  [item bounding-box]
+  (.setBoundingBox item bounding-box))
 (defn check-collision!
   "Check if 2 items are in collision in the `world` with the
   specified items"
   [world item1 item2]
   (.isInCollision world item1 item2))

-(defn test1 [world]
-  (.test world (float-array [1 2 3])))
 ;; Generic Generic------------------------------------------------


Fixed access, is now a list of maps instead of lists for vectors

--- src/hphelper/live/control.clj
+++ src/hphelper/live/control.clj
@@ -31,34 +31,28 @@
     [pass
      (-> pMap
          (assoc :password pass)
-         ;; Sets current access to starting access by default
-         (assoc :currentAccess (:accessRemaining pMap))
          )
      ]
     )
   )
-
 (defn- setup-indicies-history
   "Sets the initial indicies history to a list of the current indicies map"
   [{inds :indicies :as sMap}]
   (log/trace "setup-indicies-history.")
   (assoc sMap :indicies (list inds)))
-
 (defn- setup-current-access-totals
   "Sets up a map of player names to current access, and starts indicies history"
   [{players :hps :as sMap}]
   (log/trace "setup-current-access-totals. players:" (vals players))
-  (let [at (merge (map (fn [pMap]
+  (let [at (reduce merge {} (map (fn [pMap]
                          (log/trace "pMap:" pMap)
                          {(:name pMap) (:accessRemaining pMap)})
                        (vals players)))]
     (-> sMap
-        (assoc :current-access at)
-        (assoc :history-access (list at))
+        (assoc :access (list at))
         )
     )
   )
-
 (defn- player-all-setup
   "Adds a uuid password to all players in a scenMap, returns the map"
   [sMap]


gray -> dark gray

gray -> dark gray

--- qmon.clj
+++ qmon.clj
@@ -120,14 +120,15 @@
       scroll-pane  (JScrollPane. text-area)
       active       (atom true)
       toggle       (fn [x]
-                     (.setBackground text-area (if x (Color/GRAY ) (Color/WHITE)))
-                     (.setForeground text-area (if x (Color/WHITE) (Color/GRAY )))
-                     (.setText       button    (if x "Wake"       "Sleep"      ))
+                     (.setBackground text-area (if x (Color/DARK_GRAY ) (Color/WHITE)))
+                     (.setForeground text-area (if x (Color/WHITE) (Color/DARK_GRAY )))
+                     (.setText button (if x "Wake" "Sleep" ))
                      (if-not x (.setText text-area waitmsg))
                      (not x))]
   (do
     (doto text-area
       (.setFont (Font. "Monospaced" (Font/PLAIN) 12))
+      (.setForeground (Color/DARK_GRAY))
       (.setEditable false))
     (doto button
       (.addMouseListener (proxy [MouseAdapter] [] (mousePressed [e] (swap! active toggle)))))


Make the count-words test really test the output.

--- clstreams/test/clstreams/core_test.clj
+++ clstreams/test/clstreams/core_test.clj
@@ -2,14 +2,22 @@
   (:require [clojure.test :refer :all]
             [clstreams.core :refer :all])
   (:import [org.apache.kafka.test ProcessorTopologyTestDriver]
-           [org.apache.kafka.common.serialization StringSerializer StringDeserializer]
+           [org.apache.kafka.common.serialization Serdes]
            [org.apache.kafka.streams.kstream KStreamBuilder]))

-(def string-serializer (StringSerializer.))
-(def string-deserializer (StringDeserializer.))
+(def string-serializer (-> (Serdes/String) .serializer))
+(def string-deserializer (-> (Serdes/String) .deserializer))
+
+(def long-deserializer (-> (Serdes/Long) .deserializer))
+
+(defn key-value-map [key-value-objs]
+  (into {} (map #(vector (.key %) (.value %)) key-value-objs)))
+
+(defn collect-output [record-producing-fn]
+  (->> record-producing-fn repeatedly (take-while identity) key-value-map))

 (deftest test-copy-topology
-  (testing "It works"
+  (testing "Garbage in, garbage out..."
     (let [builder (KStreamBuilder.)
           _ (build-copy builder)
           driver (ProcessorTopologyTestDriver. count-words-props builder
@@ -22,7 +30,7 @@
         (is (= (.value record) "all streams lead to kafka"))))))

 (deftest test-word-count-topology
-  (testing "It works"
+  (testing "Complete table written to output topic"
     (let [builder (KStreamBuilder.)
           _ (build-count-words builder)
           driver (ProcessorTopologyTestDriver. count-words-props builder
@@ -33,6 +41,10 @@
                 string-serializer string-serializer)
       (.process driver "streams-file-input" "" "join kafka summit"
                 string-serializer string-serializer)
-      (let [record (.readOutput driver "streams-wordcount-output")]
-        (println (-> driver (.getKeyValueStore "Counts") .all iterator-seq))
-        (is (some? record))))))
+      (let [output (collect-output #(.readOutput driver "streams-wordcount-output"
+                                                 string-deserializer long-deserializer))]
+        (let [expected {"all" 1, "streams" 2, "lead" 1, "to" 1,
+                        "kafka" 3, "hello" 1, "join" 1, "summit" 1}]
+          (is (= output expected) "Output topic contents are correct")
+          (is (= (-> driver (.getKeyValueStore "Counts") .all iterator-seq key-value-map)
+                 expected) "Store contents are correct"))))))


Basic tests for file exporting functions

--- test/emender_jenkins/metadata_exporter_test.clj
+++ test/emender_jenkins/metadata_exporter_test.clj
@@ -69,3 +69,32 @@
         (is (callable? 'emender-jenkins.metadata-exporter/data->edn))))

+(deftest test-mix-columns-with-data-existence
+    "Check that the emender-jenkins.metadata-exporter/mix-columns-with-data definition exists."
+    (testing "if the emender-jenkins.metadata-exporter/mix-columns-with-data definition exists."
+        (is (callable? 'emender-jenkins.metadata-exporter/mix-columns-with-data))))
+
+
+(deftest test-flat-file-export-existence
+    "Check that the emender-jenkins.metadata-exporter/flat-file-export definition exists."
+    (testing "if the emender-jenkins.metadata-exporter/flat-file-export definition exists."
+        (is (callable? 'emender-jenkins.metadata-exporter/flat-file-export))))
+
+
+(deftest test-tree-file-export-existence
+    "Check that the emender-jenkins.metadata-exporter/tree-file-export definition exists."
+    (testing "if the emender-jenkins.metadata-exporter/tree-file-export definition exists."
+        (is (callable? 'emender-jenkins.metadata-exporter/tree-file-export))))
+
+
+(deftest test-export2xml-existence
+    "Check that the emender-jenkins.metadata-exporter/export2xml definition exists."
+    (testing "if the emender-jenkins.metadata-exporter/export2xml definition exists."
+        (is (callable? 'emender-jenkins.metadata-exporter/export2xml))))
+
+
+(deftest test-export-existence
+    "Check that the emender-jenkins.metadata-exporter/export definition exists."
+    (testing "if the emender-jenkins.metadata-exporter/export definition exists."
+        (is (callable? 'emender-jenkins.metadata-exporter/export))))
+


Remove Done! at the end or lein --to-dir will be messed up

--- src/leiningen/new/lambone.clj
+++ src/leiningen/new/lambone.clj
@@ -72,5 +72,4 @@
       (.exists (io/file name))
       (main/info "Could not create project because a directory named" name "already exists!")

-      :else (do (render-project options (set/union default-features user-features))
-                (main/info "Done!")))))
+      :else (do (render-project options (set/union default-features user-features))))))


Versionumero

Versionumero

--- mtg-pairings-server/project.clj
+++ mtg-pairings-server/project.clj
@@ -1,4 +1,4 @@
-(defproject mtg-pairings-server "2.0.1"
+(defproject mtg-pairings-server "2.1.0"
   :license {:name "MIT License"
             :url  "http://www.opensource.org/licenses/mit-license.php"}
   :dependencies [[org.clojure/clojure "1.9.0"]


Code review fixes

Code review fixes

--- src-cljs/frontend/components/build.cljs
+++ src-cljs/frontend/components/build.cljs
@@ -237,8 +237,18 @@
 ;; TODO this seems a little bit slow when calculating durations for really complex builds with
 ;; lots of containers. Is there a good way to avoid recalculating this when selecting container pills? (Perhaps caching the calculated value using IWillUpdate / IShouldUpdate?)
 (defn container-utilization-duration
-  [container]
-  (apply + (map action-duration-ms (:actions container))))
+  [actions]
+  (apply + (map action-duration-ms actions)))
+
+(defn container-duration-label [{:keys [actions]}]
+  (reify
+    om/IRender
+    (render [_]
+      (html
+        [:span.lower-pill-section
+         "("
+         (datetime/as-duration (container-utilization-duration actions))
+         ")"]))))

 (defn container-pill-v2 [{:keys [container current-container-id build-running?]} owner]
   (reify
@@ -255,7 +265,6 @@
       (html
        (let [container-id (container-model/id container)
              status (container-model/status container build-running?)
-             formatter datetime/as-duration
              duration-ms (container-utilization-duration container)]
         [:a.container-selector-v2
          {:on-click #(raise! owner [:container-selected {:container-id container-id}])
@@ -271,7 +280,9 @@
                                     :running "Status-Running"
                                     :waiting "Status-Queued"
                                     nil))]]
-         [:span.lower-pill-section "(" (formatter duration-ms) ")"]])))))
+         (om/build container-duration-label {:actions (:actions container)})])))))
+
+(def paging-width 10)

 (defn container-pills-v2 [data owner]
   (reify
@@ -280,18 +291,17 @@
       "Container Pills")
     om/IInitState
     (init-state [_]
-      {:container-index 0})
+      {:paging-offset 0})
     om/IRenderState
     (render-state [_ state]
       (let [container-data (:container-data data)
             build-running? (:build-running? data)
             build (:build data)
-            paging-width 10
             {:keys [containers current-container-id]} container-data
             container-count (count containers)
-            container-index (:container-index state)
-            previous-container-count (max 0 (- container-index 1))
-            subsequent-container-count (min paging-width (- container-count (+ container-index paging-width)))
+            paging-offset (:paging-offset state)
+            previous-container-count (max 0 (- paging-offset 1))
+            subsequent-container-count (min paging-width (- container-count (+ paging-offset paging-width)))

             hide-pills? (or (>= 1 (count containers))
                             (empty? (remove :filler-action (mapcat :actions containers))))
@@ -300,15 +310,15 @@
                  [:div.container-list-v2
                   (if (> previous-container-count 0)
                     [:a.container-selector-v2.page-container-pills
-                     {:on-click #(om/set-state! owner :container-index (- container-index paging-width))}
+                     {:on-click #(om/set-state! owner :paging-offset (- paging-offset paging-width))}
                      [:div.nav-caret
                       [:i.fa.fa-2x.fa-angle-left]]
                      [:div.pill-details ;; just for flexbox container
                       [:div "Previous " paging-width]
                       [:div (count containers) " total"]]])
                   (for [container (subvec containers
-                                          container-index
-                                          (min container-count (+ container-index paging-width)))]
+                                          paging-offset
+                                          (min container-count (+ paging-offset paging-width)))]
                     (om/build container-pill-v2
                               {:container container
                                :build-running? build-running?
@@ -316,7 +326,7 @@
                               {:react-key (:index container)}))
                   (if (> subsequent-container-count 0)
                     [:a.container-selector-v2.page-container-pills
-                     {:on-click #(om/set-state! owner :container-index (+ container-index paging-width))}
+                     {:on-click #(om/set-state! owner :paging-offset (+ paging-offset paging-width))}
                      [:div.pill-details ;; just for flexbox container
                       [:div "Next " subsequent-container-count]
                       [:div container-count " total"]]


make resources not download

make resources not download

--- server/src/kyoodos/handler.clj
+++ server/src/kyoodos/handler.clj
@@ -1,27 +1,25 @@
 (ns kyoodos.handler
   (:require [compojure.core :refer :all]
             [compojure.route :as route]
-            [ring.util.response :as rr]
             [ring.middleware.defaults :refer [wrap-defaults site-defaults]]
             [kyoodos.logic :as logic]))

 (defroutes app-routes
-  (GET "/" [] "Hello World")
-
+  (GET "/" [] "Hello world!")
   (GET "/users/:id{[0-9]+}" [id]
-    (rr/response (logic/get-user (read-string id))))
+    (logic/get-user (read-string id)))
   (POST "/users" request
-    (rr/response (logic/create-user request)))
+    (logic/create-user request))
   (PUT "/users/:id{[0-9]+}" request
-    (rr/response (logic/update-user request)))
+    (logic/update-user request))
   (DELETE "/users/:id{[0-9]+}" [id]
-    (rr/response (logic/delete-user id)))
+    (logic/delete-user id))

   (GET "/groups/:id{[0-9]+}" [id]
-    (rr/response (logic/get-group (read-string id))))
+    (logic/get-group (read-string id)))

   (GET "/kyoodos/:direction/:id{[0-9]+}" [direction id]
-    (rr/response (logic/get-kyoodos (read-string direction) (read-string id))))
+    (logic/get-kyoodos (read-string direction) (read-string id)))

   (route/not-found "Not Found"))


Add key-info printing for public-key blobs.

--- tool/vault/tool/data.clj
+++ tool/vault/tool/data.clj
@@ -2,9 +2,11 @@
   (:require
     [byte-streams]
     [clojure.java.io :as io]
+    [mvxcvi.crypto.pgp :as pgp]
     [puget.printer :as puget]
     [vault.blob.store :as store]
     [vault.data.edn :as edn]
+    [vault.data.key :as key]
     [vault.tool.blob :refer [enumerate-prefix]]))

@@ -34,6 +36,12 @@
       (println (str \u001b "[7m" \% \u001b "[0m")))))

+(defn- print-key-blob
+  "Prints a public-key blob info."
+  [blob]
+  (-> blob :data/values first pgp/key-info puget/cprint))
+
+
 (defn- print-edn-blob
   "Prints an EDN blob's values."
   [blob]
@@ -51,9 +59,10 @@
       (when-let [blob (store/get store id)]
         (println (str id))
         (let [content (:content blob)
+              key (key/parse-key blob)
               data (edn/parse-data blob)]
-          ; TODO: interpret PGP keys
-          (cond data               (print-edn-blob data)
+          (cond key                (print-key-blob key)
+                data               (print-edn-blob data)
                 (:binary opts)     (print-binary-blob content)
                 (textual? content) (print-text-blob content)
                 :else              (print-binary-blob content)))


engine: use an appropriate sentence, keep broken english for backward compat

--- src/warp/engine.clj
+++ src/warp/engine.clj
@@ -22,11 +22,13 @@

 (def progress-command?
   #{:init :command-start :command-deny :command-step :command-end
+    :command-denied
     :ack-timeout :timeout})

 (defn process-event
   [archive executions {:keys [opcode sequence] :as event}]

+  (info "received event:" (pr-str event))
   (when-not (progress-command? opcode)
     (throw (ex-info "invalid event received" {:event event})))


Extract variadic connect.

Extract variadic connect.

--- src/klangmeister/instruments.cljs
+++ src/klangmeister/instruments.cljs
@@ -2,6 +2,7 @@
   (:require [klangmeister.music :as music]))

 (defonce context (js/window.AudioContext.))
+

 (defn perc [at attack decay]
   (let [node (.createGain context)]
@@ -35,15 +36,19 @@
     (harmonic 4.1 0.25)
     (harmonic 5.2 0.2)))

+(defn connect [& [a b & nodes]]
+  (when b
+    (.connect a b)
+    (apply connect (cons b nodes))))
+
 (defn fuzz! [midi start dur]
   (let [freq (music/equal-temperament midi)
         start (+ start (.-currentTime context))
         stop (+ start dur)
-        envelope (doto (perc start 0.1 0.5)
-                   (.connect (.-destination context)))]
+        envelope (perc start 0.1 0.5)]
     (doto (.createOscillator context)
-      (.connect envelope)
       (-> .-frequency .-value (set! freq))
       (-> .-type  (set! "sawtooth"))
       (.start start)
-      (.stop (+ start 1.5)))))
+      (.stop (+ start 1.5))
+      (connect envelope (.-destination context)))))


Refactored function with destructuring, updated docstring and error message

--- src/metabase/pulse/render.clj
+++ src/metabase/pulse/render.clj
@@ -397,41 +397,40 @@
       :else                                                        :table)))

 (defn render-pulse-card
-  "Render a single CARD for a `Pulse`. DATA is the `:data` from QP results (I think)."
-  [card result]
+  "Render a single CARD for a `Pulse`. RESULT is the QP results."
+  [card {:keys [data error]}]
   (try
-    (when (:error result)
-      (throw (Exception. "Card has errors")))
-    (let [data (:data result)]
-      [:a {:href   (card-href card)
-           :target "_blank"
-           :style  (style section-style
-                          {:margin          :16px
-                           :margin-bottom   :16px
-                           :display         :block
-                           :text-decoration :none})}
-       (when *include-title*
-         [:table {:style (style {:margin-bottom :8px
-                                 :width         :100%})}
-          [:tbody
-           [:tr
-            [:td [:span {:style header-style}
-                  (-> card :name h)]]
-            [:td {:style (style {:text-align :right})}
-             (when *include-buttons*
-               [:img {:style (style {:width :16px})
-                      :width 16
-                      :src   (render-image-with-filename "frontend_client/app/img/external_link.png")}])]]]])
-       (case (detect-pulse-card-type card data)
-         :empty     (render:empty     card data)
-         :scalar    (render:scalar    card data)
-         :sparkline (render:sparkline card data)
-         :bar       (render:bar       card data)
-         :table     (render:table     card data)
-         [:div {:style (style font-style
-                              {:color       "#F9D45C"
-                               :font-weight 700})}
-          "We were unable to display this card." [:br] "Please view this card in Metabase."])])
+    (when error
+      (throw (Exception. (str "Card has errors: " error))))
+    [:a {:href   (card-href card)
+         :target "_blank"
+         :style  (style section-style
+                        {:margin          :16px
+                         :margin-bottom   :16px
+                         :display         :block
+                         :text-decoration :none})}
+     (when *include-title*
+       [:table {:style (style {:margin-bottom :8px
+                               :width         :100%})}
+        [:tbody
+         [:tr
+          [:td [:span {:style header-style}
+                (-> card :name h)]]
+          [:td {:style (style {:text-align :right})}
+           (when *include-buttons*
+             [:img {:style (style {:width :16px})
+                    :width 16
+                    :src   (render-image-with-filename "frontend_client/app/img/external_link.png")}])]]]])
+     (case (detect-pulse-card-type card data)
+       :empty     (render:empty     card data)
+       :scalar    (render:scalar    card data)
+       :sparkline (render:sparkline card data)
+       :bar       (render:bar       card data)
+       :table     (render:table     card data)
+       [:div {:style (style font-style
+                            {:color       "#F9D45C"
+                             :font-weight 700})}
+        "We were unable to display this card." [:br] "Please view this card in Metabase."])]
     (catch Throwable e
       (log/warn "Pulse card render error:" e)
       [:div {:style (style font-style


simplifies assertions in test-basic-health-check-port-index (#634)

--- waiter/integration/waiter/basic_test.clj
+++ waiter/integration/waiter/basic_test.clj
@@ -297,11 +297,11 @@

 (deftest ^:parallel ^:integration-fast test-basic-health-check-port-index
   (testing-using-waiter-url
-    (let [command (kitchen-cmd "-p $PORT1")
-          headers {:x-waiter-cmd command
-                   :x-waiter-health-check-port-index 1
+    (let [kitchen-command (kitchen-cmd "-p $PORT2")
+          headers {:x-waiter-cmd kitchen-command
+                   :x-waiter-health-check-port-index 2
                    :x-waiter-name (rand-name)
-                   :x-waiter-ports 2}
+                   :x-waiter-ports 3}
           {:keys [service-id] :as response} (make-request-with-debug-info headers #(make-shell-request waiter-url %))]
       (is (not (nil? service-id)))
       (when service-id
@@ -310,12 +310,11 @@
           (assert-response-status response 502)
           (is (str/includes? (-> response :body str) "Request to service backend failed"))
           (is (str/includes? (-> response :headers (get "server")) "waiter/"))
-          (let [service-settings (service-settings waiter-url service-id)
-                active-instances (get-in service-settings [:instances :active-instances])]
-            (is (= command (get-in service-settings [:service-description :cmd])))
-            (is (= 1 (get-in service-settings [:service-description :health-check-port-index])))
-            (is (seq active-instances))
-            (is (every? :healthy? active-instances))))))))
+          (let [{:keys [service-description]} (service-settings waiter-url service-id)
+                {:keys [cmd health-check-port-index ports]} service-description]
+            (is (= kitchen-command cmd))
+            (is (= 2 health-check-port-index))
+            (is (= 3 ports))))))))

 (defn- run-backend-proto-service-test
   "Helper method to run tests with various backend protocols"


try at using macro-do to generate series of macros

--- src/midje/checkers/collection.clj
+++ src/midje/checkers/collection.clj
@@ -10,9 +10,10 @@
         [clojure.math.combinatorics :only [permutations]]
         [midje.util.form-utils :only [regex? tack-on-to record? classic-map?]]
         [midje.util.object-utils :only [function-name named-function?]]
-	[midje.checkers util extended-equality chatty defining]
+      	[midje.checkers util extended-equality chatty defining]
         [midje.util.exceptions :only [user-error]]
-        [clojure.string :only [join]]))
+        [clojure.string :only [join]]
+        [utilize.macro :only (macro-do)]))

 (def looseness-modifiers #{:in-any-order :gaps-ok})

@@ -488,14 +489,19 @@
     (and (= (count actual) expected-count)
          (every? #(extended-= % expected) actual))))

-
 (defmacro- generate-n-of-checkers []
-  (let [int->checker-name { 1 "one", 2 "two", 3 "three", 4 "four", 5 "five",
-                            6 "six", 7 "seven", 8 "eight", 9 "nine", 10 "ten"}
-        defns (for [[int checker-name] int->checker-name]
-                (let [name (symbol (str checker-name "-of"))]
-                  `(defchecker ~name [expected-checker#]
-                     (n-of expected-checker# ~int))))]
-    `(do ~@defns)))
+  (macro-do [[int checker-name]]
+    `(defchecker ~(symbol (str checker-name "-of")) [expected-checker#]
+       (n-of expected-checker# ~int))
+    [1 "one"]
+    [2 "two"]
+    [3 "three"]
+    [4 "four"]
+    [5 "five"]
+    [6 "six"]
+    [7 "seven"]
+    [8 "eight"]
+    [9 "nine"]
+    [10 "ten"]))

 (generate-n-of-checkers)


Fixed encoding

Fixed encoding

--- src/video_server/freebase.clj
+++ src/video_server/freebase.clj
@@ -43,7 +43,7 @@
   [ftype title]
   (:result (get-json cache
                      (str "https://www.googleapis.com/freebase/v1/search?type=" ftype
-                          "&query=" (URLEncoder/encode title))
+                          "&query=" (URLEncoder/encode title "UTF-8"))
                      :auth authorize
                      :key-fn norm-keyword)))


Got red square on mouse press

Got red square on mouse press

--- src/cljs/clj_mini_apps/tic-tac-toe.cljs
+++ src/cljs/clj_mini_apps/tic-tac-toe.cljs
@@ -20,24 +20,27 @@
   (q/rect 370 79 9 441)
   (q/rect 79 220 441 9)
   (q/rect 79 370 441 9)
-  (q/rect-mode CENTER)
+  (q/rect-mode :center)
+  {:rects []})

 (defn draw
   [{:keys [:rects]}]
   (q/fill 255 0 0)
   (doseq [{:keys [x y w h]} rects]
-    (q/rect x y w h)))
+    (q/rect x y w h))
+  {:keys [x y w h]})

 (defn add-rect
-  [state {:keys [x y]}]
-  (log state)
-  (log mouse-x)
-  (update-in state [:rects]
-             conj {:x mouse-x :y mouse-y :w 10 :h 10}))
+  [state event]
+  (log (q/mouse-x))
+  (log (q/mouse-y))
+  (q/fill 255 0 0)
+  (q/rect (q/mouse-x) (q/mouse-y) 10 10))
+  ;(update-in state [:rects]
+   ;          conj {:x (q/mouse-x) :y (q/mouse-y) :w 10 :h 10}))

 (q/defsketch hello
-  :setup setup
-  :draw draw
   :host "canvas"
   :size [600 600]
+  :setup setup
   :mouse-pressed add-rect)


improve var name

improve var name

--- src/cljs/infinitelives/pixi/sprite.cljs
+++ src/cljs/infinitelives/pixi/sprite.cljs
@@ -140,12 +140,13 @@
     [(.-x bounds) (.-y bounds) (.-width bounds) (.-height bounds)]))

 (defn get-edges [sprite]
-  (let [[px py] (get-pivot-xy sprite)
+  (let [neg-pivot-x (- (get-pivot-x sprite))
+        neg-pivot-y (- (get-pivot-y sprite))
         [x y w h] (get-rects sprite)
         pos-x (get-x sprite)
         pos-y (get-y sprite)]
-    [(+ pos-x x (- px)) (+ pos-y y (- py))
-     (+ pos-x x w (- px)) (+ pos-y y h (- py))]))
+    [(+ pos-x x neg-pivot-x) (+ pos-y y neg-pivot-y)
+     (+ pos-x x w neg-pivot-x) (+ pos-y y h neg-pivot-y)]))

 (defn update-container-handle!
   [container xhandle yhandle]


fix plugin loading

fix plugin loading

--- src/clojure/zensols/cisql/directive.clj
+++ src/clojure/zensols/cisql/directive.clj
@@ -5,6 +5,7 @@
     zensols.cisql.directive
   (:require [clojure.tools.logging :as log]
             [clojure.string :as s]
+            [clojure.java.io :as io]
             [clojure.java.browse :as browse]
             [zensols.actioncli.log4j2 :as lu]
             [zensols.actioncli.parse :as parse]
@@ -372,12 +373,14 @@
           (ex/export-query-to-eval query last-query code))}
    {:name "plugin"
     :arg-count 1
-    :usage "<plugins directory>"
-    :desc "load all plugins from a directory"
+    :usage "<path>"
+    :desc "load from a file or all plugins from a directory"
     :help-section "plugins"
-    :fn (fn [opts [directory]]
-          (assert-no-query opts)
-          (merge-user-directives (plugin/load-plugins directory))
+    :fn (fn [opts [path]]
+          (assert-no-query opts)
+          (->> (io/file path)
+               plugin/load-plugins
+               merge-user-directives)
           (init-grammer)
           (->> @user-directives
                (map :name)


Refactor

Refactor

--- backend/src/akvo/lumen/component/handler.clj
+++ backend/src/akvo/lumen/component/handler.clj
@@ -1,6 +1,5 @@
 (ns akvo.lumen.component.handler
-  (:require [compojure.core :as compojure.core]
-            [compojure.response :as compojure.res]
+  (:require [compojure.response :as compojure.res]
             [integrant.core :as ig]
             [clojure.tools.logging :as log]
             [akvo.lumen.specs.components :refer [integrant-key]]
@@ -21,22 +20,13 @@
     (let [
           routes  (->> endpoints
                        (reduce-kv (fn [c k v]
-                                    (conj c [k v])
-                                    ) [] ))
-
-;;          _ (log/warn routes)
-
+                                    (conj c [k v])) [] ))
           handler (ring/ring-handler
                    (ring/router routes
-                                {:data {;; :coercion reitit.coercion.spec/coercion
-                                        ;;:muuntaja m/instance
-                                        :middleware middleware}
-                                 :conflicts (constantly nil)}))
-;;          _ (log/error :handler handler)
-]
+                                {:data {:middleware middleware}
+                                 :conflicts (constantly nil)}))]
       (assoc opts :handler handler))
     opts))
-

 (s/def ::endpoints (s/coll-of fn?
                               ;;:count 24
@@ -137,4 +127,3 @@
         (if (vector? res)
           (commons/variant->response res request)
           res)))))
-


Add transformation extract-multiple spec [skip ci]

--- backend/specs/akvo/lumen/specs/transformation.clj
+++ backend/specs/akvo/lumen/specs/transformation.clj
@@ -247,6 +247,40 @@
 	    ::transformation.engine/onError
             ::transformation.engine/op]))

+
+(create-ns 'akvo.lumen.specs.transformation.extract-multiple)
+(alias 'transformation.extract-multiple 'akvo.lumen.specs.transformation.extract-multiple)
+
+(create-ns 'akvo.lumen.specs.transformation.extract-multiple.column)
+(alias 'transformation.extract-multiple.column 'akvo.lumen.specs.transformation.extract-multiple.column)
+
+(s/def ::transformation.extract-multiple/selectedColumn :akvo.lumen.specs.import.column.multiple/header)
+(s/def ::transformation.extract-multiple/extractImage boolean?)
+(s/def ::transformation.extract-multiple.column/id int?)
+(s/def ::transformation.extract-multiple.column/name string?)
+(s/def ::transformation.extract-multiple.column/type #{"text"})
+(s/def ::transformation.extract-multiple.column/extract boolean?)
+(s/def ::transformation.extract-multiple.column/column
+  (s/keys :req-un [::transformation.extract-multiple.column/id
+                   ::transformation.extract-multiple.column/name
+                   ::transformation.extract-multiple.column/type
+                   ::transformation.extract-multiple.column/extract]))
+
+(s/def ::transformation.extract-multiple/columns (s/coll-of ::transformation.extract-multiple.column/column
+                                                            :kind vector? :distinct true))
+
+(s/def ::transformation.extract-multiple/args
+  (s/keys :req-un [::db.dsv.column/columnName
+                   ::transformation.extract-multiple/selectedColumn
+                   ::transformation.extract-multiple/extractImage]))
+
+(defmethod op-spec :core/extract-multiple  [_]
+  (s/keys
+   :req-un [::transformation.extract-multiple/args
+	    ::transformation.engine/onError
+            ::transformation.engine/op]))
+
+
 (lumen.s/sample ::transformation.engine/op-spec 10)

 (create-ns  'akvo.lumen.specs.dataset-version.transformation)


renamed cp and color in draw-marbles

renamed cp and color in draw-marbles

--- src/nonaga/draw/draw_marbles.cljs
+++ src/nonaga/draw/draw_marbles.cljs
@@ -13,12 +13,14 @@
   (let [marbles (color state)]
     (map (partial marble color) (map hex->svg marbles))))

-; Color and cp are badly named. Should be color-of-marbles-being-drawn and
-; current player.
 (defmethod draw-marbles ::marble-selectable
-  [component {[t cp] :event :as state} color]
-  (let [coords (color state)
+  [component {[t current-player] :event :as state} marble-color]
+  (let [coords (marble-color state)
         click  (partial start-marble-move component)]
-    (map (fn [hex svg] (marble color (if (= cp color) (click color hex)) svg))
+    (map (fn [hex svg]
+           (marble marble-color
+                   (if (= current-player marble-color)
+                     (click marble-color hex))
+                   svg))
          coords (map hex->svg coords))))


added keyword choice-checking to interop

--- src/onyx_java/utility/interop.clj
+++ src/onyx_java/utility/interop.clj
@@ -26,15 +26,19 @@
    :keyword (fn [x] (keyword x))
    :vector (fn [x] (vec x))})

+(defn check-choices [choices value]
+    (if (boolean (some #{:all} (flatten choices))) value
+        (if (some #{value} choices) value nil)))
+
 (defn cast-types [section m]
   (let [section* (keyword section)]
     (reduce-kv
      (fn [m* k v]
        (let [k* (keyword k)
              type (get-in model [section* :model k* :type])
-             choices (get-in model [section* :model k* :choices])
-             required (not (get-in model [section* :model k* :optional?]))
-             v* ((get casts type identity) v)]
+             choices (get-in model [section* :model k* :choices] [:all])
+             required (not (get-in model [section* :model k* :optional?] true))
+             v* (check-choices choices ((get casts type identity) v))]
          (assoc m* k* v*)))
      {}
      m)))


Update as-channel & send! docs.

Update as-channel & send! docs.

--- web/src/immutant/web/async.clj
+++ web/src/immutant/web/async.clj
@@ -42,7 +42,9 @@
   (send! [ch message] [ch message options]
   "Send a message to the channel, asynchronously.

-   `message` can either be a String or byte[].
+   `message` can either be a String or byte[]. If it is a String, it will be
+    encoded to the character set of the response for HTTP streams, and as UTF-8
+    for WebSockets.

    The following options are supported [default]:

@@ -122,8 +124,9 @@
   * :on-message - `(fn [ch message] ...)` - Called for each message
     from the client. `message` will be a `String` or `byte[]`

-  TODO: discuss: sessions, headers, ws vs http diffs (utf8, no headers)
-  provide usage example
+  When the ring handler is called during a WebSocket upgrade request,
+  any headers returned in the response map are ignored, but any changes to
+  the session are applied.

   Returns a ring response map, at least the :body of which *must* be
   returned in the response map from the calling ring handler."


Add children

Add children

--- src/atom_finder/atom_stats.clj
+++ src/atom_finder/atom_stats.clj
@@ -41,11 +41,18 @@
     (ren [a b] (if (= (->> a .getNodeData .toString) (->> b .getNodeData .toString)) 0.0 1.0))
     ))

-(defn ASTDiffNode [node]
-  (proxy [Node] [node]
-    (toString [] (.toString (proxy-super getNodeData)))))
+(defn ASTDiffNode
+  ([node] (ASTDiffNode node []))
+  ([node children]
+   (let [node-obj
+         (proxy [Node] [node]
+           (toString [] (.toString (proxy-super getNodeData))))]
+
+     (doseq [child children] (.addChild node-obj child))
+
+     node-obj)))

 apted = new APTED<>(new StringUnitCostModel())
 (def apted (APTED. ASTUnitCostModel))

-(.computeEditDistance apted (ASTDiffNode "abc") (ASTDiffNode "abc"))
+(.computeEditDistance apted (ASTDiffNode "a" [(ASTDiffNode "b") (ASTDiffNode "c")]) (ASTDiffNode "a" [(ASTDiffNode "b") (ASTDiffNode "d")]))


Remove unused code

Remove unused code

--- src/todomvc_reagent/core.cljs
+++ src/todomvc_reagent/core.cljs
@@ -35,12 +35,6 @@
   ([title done]
    (let [id (swap! session/counter inc)]
      (swap! session/todos assoc id {:id id :title title :done done}))))
-
-(defn init []
-  (add-todo "Taste JavaScript" true)
-  (add-todo "Buy a unicorn"))
-
-;;(init)

 ;; -------------------------
 ;; Views


+vp32

--- src/babel/english/grammar.cljc
+++ src/babel/english/grammar.cljc
@@ -386,6 +386,12 @@
                             :rule "vp-pronoun"
                             :synsem {:aux false
                                      :cat :verb}})
+
+                   (unify-check h32
+                           root-is-head
+                          {:rule "vp32"
+                           :synsem {:aux false
+                                    :cat :verb}})

                    (unify-check h10
                            {:head {:phrasal false


pred from avere to have

pred from avere to have

--- src/babel/francais/lexicon.clj
+++ src/babel/francais/lexicon.clj
@@ -83,7 +83,7 @@
                                :1plur "avons"
                                :2plur "avez"
                                :3plur "ont"}}}]
-     [(unify common {:synsem {:sem {:pred :avere
+     [(unify common {:synsem {:sem {:pred :have
                                     :subj {:human true}}}})
       (unify common verb-aux
              {:synsem {:subcat {:2 {:essere false}}}})])


Fix litedocx.unit package

Fix litedocx.unit package

--- src/bakyeono/litedocx/unit.clj
+++ src/bakyeono/litedocx/unit.clj
@@ -56,10 +56,10 @@
 (defn- conversion-medium
   "Takes a keyword of unit and returns its preffered conversion medium."
   [u]
-  (cond (metric-set u) [unit-per-m m-per-unit]
-        (inch-set u) [unit-per-inch inch-per-unit]))
+  (cond (metric-set u) [m-per-unit unit-per-m]
+        (inch-set u) [inch-per-unit unit-per-inch]))

-(defn conversion-rate
+(defn- conversion-rate
   "Returns conversion rate for 'from' unit -> 'to' unit. The parameters should
   be keywords."
   [from to]
@@ -78,12 +78,12 @@
   - value: <string> value with unit.
   - to: <string or keyword> target unit type.

+  Supported Unit Types:
+  - Length Units: inch, cm, km, m, mm, px, pt, dxa, emu
+
   Examples:
   - (convert \"10px\" \"mm\")
-  - (convert \"29.7 cm\" :dxa)
-
-  Supported Unit Types:
-  - Length Units: inch, cm, km, m, mm, px, pt, dxa, emu"
+  - (convert \"29.7 cm\" :dxa)"
   [value to]
   (let [[n unit] (parse-unit value)
         rate (conversion-rate unit (keyword to))]


added schema validation for identity read

--- src/cia/stores/es/identity.clj
+++ src/cia/stores/es/identity.clj
@@ -30,14 +30,18 @@
                         (:index state)
                         mapping
                         transformed)]
-    (update-in res [:capabilities] capabilities->capabilities-set)))
+    (-> res
+        (update-in [:capabilities] capabilities->capabilities-set)
+        (dissoc :id))))

-(defn handle-read-identity [state login]
+(s/defn handle-read-identity :- Identity
+  [state :- s/Any login :- s/Str]
   (-> (get-doc (:conn state)
                (:index state)
                mapping
                login)
-      (update-in [:capabilities] capabilities->capabilities-set)))
+      (update-in [:capabilities] capabilities->capabilities-set)
+      (dissoc :id)))

 (defn handle-delete-identity [state login]
   (delete-doc (:conn state)


Make gen-link->map more generic

Make gen-link->map more generic

It just assumes the name is in content, not the first item in content.
This will let extraction work on manga-here's format.

--- src/clj/comic_reader/sites.clj
+++ src/clj/comic_reader/sites.clj
@@ -4,7 +4,7 @@
             [clojure.string :as s]))

 (defn gen-link->map [process-name process-url]
-  (fn [{[name] :content
+  (fn [{name :content
         {url :href} :attrs}]
     {:name (process-name name)
      :url (process-url url)}))
@@ -20,7 +20,7 @@
   [(let [canonical-url "http://mangafox.me"
          manga-url (format "%s/manga/" canonical-url)
          manga-pattern (re-pattern (str manga-url "(.*?)/"))
-         link->map (gen-link->map identity identity)]
+         link->map (gen-link->map first identity)]
      {:id :manga-fox
       :name "Manga Fox"

@@ -61,7 +61,7 @@
    (let [canonical-url "http://www.mangareader.net"
          manga-pattern (re-pattern (str canonical-url
                                         "/(.*)(\\.html)?$"))
-         link->map (gen-link->map s/trim
+         link->map (gen-link->map (comp s/trim first)
                                   (partial str canonical-url))]
      {:id :manga-reader
       :name "Manga Reader"
@@ -99,8 +99,8 @@
    (let [canonical-url "http://www.mangahere.co"
          manga-url     (format "%s/manga" canonical-url)
          mangalist-url (format "%s/mangalist/" canonical-url)
-         manga-pattern (re-pattern (str manga-url "(.*?)/"))
-         link->map (gen-link->map identity identity)]
+         manga-pattern (re-pattern (str manga-url "/(.*?)/"))
+         link->map (gen-link->map second identity)]
      {:id :manga-here
       :name "Manga Here"
       :comic->url (fn [comic-id]


Fix bug in book/pick-book-move.

Fix bug in book/pick-book-move.

--- src/clojure/clj_chess/book.clj
+++ src/clojure/clj_chess/book.clj
@@ -406,7 +406,7 @@
   "Pick a random book move from the board position, based on their
   probabilities. Returns nil if no book move is found."
   [board & book-file-names]
-  (let [entries (find-book-entries board book-file-names)
+  (let [entries (apply find-book-entries board book-file-names)
         r (rand)]
     (first (first (filter #(> (second %) r)
                           (map (fn [e c] [(:move e) c])


Fix Android build issue

Fix Android build issue

--- src/clojure/nightcode/lein.clj
+++ src/clojure/nightcode/lein.clj
@@ -226,9 +226,10 @@
 (defn build-project-task
   [path project]
   (if (is-android-project? path)
-    (-> (leiningen.droid/transform-into-release project)
-        add-sdk-path
-        leiningen.droid/execute-release-routine)
+    (do (leiningen.droid.classpath/init-hooks)
+      (-> (leiningen.droid/transform-into-release project)
+          add-sdk-path
+          leiningen.droid/execute-release-routine))
     (leiningen.uberjar/uberjar project)))

 (defn test-project-task
@@ -266,7 +267,7 @@
   [process in out path]
   (stop-process process)
   (->> (do (println (utils/get-string :running))
-         (if (is-java-project? path)
+         (if (and (is-java-project? path) (not (is-android-project? path)))
            (start-process-directly process path run-project-task)
            (start-process-indirectly process path class-name "run")))
        (start-thread in out)))
@@ -275,7 +276,7 @@
   [process in out path]
   (stop-process process)
   (->> (do (println (utils/get-string :running_with_repl))
-         (if (is-java-project? path)
+         (if (and (is-java-project? path) (not (is-android-project? path)))
            (start-process-directly process path run-repl-project-task)
            (start-process-indirectly process path class-name "repl")))
        (start-thread in out)))
@@ -284,7 +285,7 @@
   [process in out path]
   (stop-process process)
   (->> (do (println (utils/get-string :building))
-         (if (is-java-project? path)
+         (if (and (is-java-project? path) (not (is-android-project? path)))
            (start-process-directly process path build-project-task)
            (start-process-indirectly process path class-name "build")))
        (start-thread in out)))
@@ -293,7 +294,7 @@
   [process in out path]
   (stop-process process)
   (->> (do (println (utils/get-string :testing))
-         (if (is-java-project? path)
+         (if (and (is-java-project? path) (not (is-android-project? path)))
            (start-process-directly process path test-project-task)
            (start-process-indirectly process path class-name "test")))
        (start-thread in out)))
@@ -302,7 +303,7 @@
   [process in out path]
   (stop-process process)
   (->> (do (println (utils/get-string :cleaning))
-         (if (is-java-project? path)
+         (if (and (is-java-project? path) (not (is-android-project? path)))
            (start-process-directly process path clean-project-task)
            (start-process-indirectly process path class-name "clean")))
        (start-thread in out)))


Adding two new endpoints for faster catalog rest integration tests to the control servlet.

--- src/cmr/dev_system/control.clj
+++ src/cmr/dev_system/control.clj
@@ -9,7 +9,13 @@
             [cmr.common.log :refer (debug info warn error)]
             [cmr.common.api.errors :as errors]
             [cmr.transmit.echo.acls :as echo-acls]
-            [cmr.search.data.elastic-search-index :as es]))
+            [cmr.search.data.elastic-search-index :as es]
+
+            ;; Services for reseting
+            [cmr.metadata-db.services.concept-service :as mdb-service]
+            [cmr.index-set.services.index-service :as index-set-service]
+            [cmr.indexer.services.index-service :as indexer-service]
+            [cmr.search.services.query-service :as search-service]))

 (defn app-context
   [system app]
@@ -35,6 +41,18 @@
               :search-cached-acls search-cached-acls
               :actual-acls actual-acls}))))

+(def service-reset-fns
+  "A map of services to reset functions."
+  {:metadata-db mdb-service/reset
+   :index-set index-set-service/reset
+   :indexer indexer-service/reset
+   :search search-service/clear-cache})
+
+(def service-clear-cache-fns
+  "A map of services to reset functions."
+  {:indexer indexer-service/clear-cache
+   :search search-service/clear-cache})
+

 (defn- build-routes [system]
   (routes
@@ -43,6 +61,18 @@
       {:status 200
        :body (json/generate-string (get-acl-state system) {:pretty true})
        :headers {"Content-Type" "application/json"}})
+
+    ;; Calls reset on all other systems internally
+    (POST "/reset" []
+      (doseq [[service-name reset-fn] service-reset-fns]
+        (reset-fn (app-context system service-name)))
+      {:status 200})
+
+    (POST "/clear-cache" []
+      (doseq [[service-name clear-cache-fn] service-clear-cache-fns]
+        (clear-cache-fn (app-context system service-name)))
+      {:status 200})
+
     (POST "/stop" []
       ((var-get (find-var 'cmr.dev-system.system/stop)) system)
       (System/exit 0))


Save server state only once per round

Save server state only once per round

--- src/rpi_challenger/controller.clj
+++ src/rpi_challenger/controller.clj
@@ -53,10 +53,7 @@
 (defn ^:dynamic record-response
   [participant response challenge]
   (dosync
-    (alter tournament t/record-strike participant (s/make-strike response challenge)))
-  ; TODO: load state on restart
-  ; TODO: save state less often
-  (io/object-to-file "rpi-challenger-state.clj" @tournament))
+    (alter tournament t/record-strike participant (s/make-strike response challenge))))

 (defn poll-participant
   [participant challenges]
@@ -81,6 +78,8 @@
   []
   (dosync (alter tournament t/finish-current-round))
   (.info logger "Starting a new round")
+  ; TODO: load state on restart
+  (io/object-to-file "rpi-challenger-state.clj" @tournament)
   ; TODO: parameterize the dir on command line or create an admin screen
   (c/load-challenge-functions (File. "../rpi-challenges/src/"))
   (dosync (alter tournament t/update-challenge-functions)))


Minor

Minor

--- src/discuss/communication.cljs
+++ src/discuss/communication.cljs
@@ -76,7 +76,7 @@
     (discuss.references.integration/process-references refs)))

 (defn init!
-  "Initialize initial data from API."
+  "Request initial data from API."
   []
   (let [url (:init config/api)]
     (lib/update-state-item! :layout :add? (fn [_] false))


Use proper content type for index.html and error.html

--- src/emender_jenkins/server.clj
+++ src/emender_jenkins/server.clj
@@ -19,8 +19,11 @@
 (require '[emender-jenkins.rest-api :as rest-api])

 (defn return-file
+    "Creates HTTP response containing content of specified file.
+     Special value nil / HTTP response 404 is returned in case of any I/O error."
     [file-name content-type]
-    (http-response/file-response file-name {:root "www"}))
+    (-> (http-response/file-response file-name {:root "www"})
+        (http-response/content-type content-type)))

 (defn render-front-page
     "Create front page."


Fixes toolbar clickable even when no selected task

--- src/front/ui/main/toolbar.cljs
+++ src/front/ui/main/toolbar.cljs
@@ -45,10 +45,11 @@
   (move-dialog/append @selected-task-atom))

 (defn- render-toolbar-action
-  [text css-class icon function]
+  [selected-task text css-class icon function]
   [:div
    {:class (str "item " css-class)
-    :on-click function}
+    :on-click (when selected-task
+                function)}
    [:div.icon
     {:title text}
     [:i
@@ -61,6 +62,7 @@
    (doall (for [item items]
             ^{:key (:text item)}
             [render-toolbar-action
+             true
              (:text item)
              (:css-class item)
              (:icon item)
@@ -75,6 +77,7 @@
    (doall (for [item items]
             ^{:key (:text item)}
             [render-toolbar-action
+             @selected-task-atom
              (:text item)
              (:css-class item)
              (:icon item)


actually use :custom-data

actually use :custom-data

--- src/yeller_clojure_client.clj
+++ src/yeller_clojure_client.clj
@@ -86,10 +86,7 @@
        (.report client
                 exception
                 detail
-                (stringify-keys (dissoc extra
-                                        :environment
-                                        :location
-                                        :url))))
+                (stringify-keys (:custom-data extra {}))))
      (.report client
               exception
               (stringify-keys (dissoc extra


Fix twitter url in twitterbuzz demo. refs #CLJS-9

--- samples/twitterbuzz/src/twitterbuzz/core.cljs
+++ samples/twitterbuzz/src/twitterbuzz/core.cljs
@@ -34,7 +34,7 @@
   [event f]
   (swap! state add-listener event f))

-(def twitter-uri (goog.Uri. "http://twitter.com/search.json"))
+(def twitter-uri (goog.Uri. "http://search.twitter.com/search.json"))

 (defn search-tag
   "Get the current tag value from the page."


(WIP) stub out register/poll for tweet retrieval, refs #48

--- samples/twitterbuzz/src/twitterbuzz/core.cljs
+++ samples/twitterbuzz/src/twitterbuzz/core.cljs
@@ -1,9 +1,5 @@
 (ns twitterbuzz.core
-  (:require [goog.net.Jsonp :as jsonp]
-            [goog.debug.Console :as console]))
-
-(def console (goog.debug.Console.))
-(defn log [msg] (.addLogRecord console msg))
+  (:require [goog.net.Jsonp :as jsonp]))

 (def twitter-uri (goog.Uri. "http://twitter.com/search.json"))

@@ -15,4 +11,19 @@
 (defn my-callback [json]
   (log json))

-(retrieve (.strobj {"q" "clojure"}) my-callback)+(retrieve (.strobj {"q" "clojure"}) my-callback)
+
+(defn register
+  "Register fn to be called with new tweets."
+  [fn])
+
+(defn poll
+  []
+  ;; polls twitter periodically using jsonp
+  ;; figures out if there are any new tweets
+  ;;   drop the n we already have?
+  ;;   use the latest known timestamp?
+  ;; if there are new tweets
+  ;;   keywordize the JSON keys
+  ;;   call every registered fn with the vector of maps of new tweets.
+  )


Remove (already commented-out) Immutant component

--- clstreams/src/clstreams/webapi/component.clj
+++ clstreams/src/clstreams/webapi/component.clj
@@ -24,20 +24,3 @@
 (defn new-aleph [app-factory config]
   (map->AlephWebServer {:app-factory app-factory :config config}))

-
-(comment defrecord ImmutantWebServer [app-factory config server]
-  component/Lifecycle
-
-  (start [component]
-    (log/info "Starting web server")
-    (let [handler (app-factory component)
-          server (apply web/run handler (mapcat seq config))]
-      (assoc component :server server)))
-
-  (stop [component]
-    (log/info "Stopping web server")
-    (web/stop server)
-    (assoc component :server nil)))
-
-(comment defn new-immutant [app-factory config]
-  (map->ImmutantWebServer {:app-factory app-factory :config config}))


Add challenge 383 bonus #1 katas

Add challenge 383 bonus #1 katas

--- clojure-katas/src/clojure_katas/challenge-383.clj
+++ clojure-katas/src/clojure_katas/challenge-383.clj
@@ -8,4 +8,22 @@
   (if (= (count str-a) (count str-b))
       (let [str-b-double (str str-b str-b)]
         (s/includes? str-b-double str-a))
-  false))
+      false))
+
+;; bonus #1
+(defn transpose-and-check-if-same [input-str modified-str times]
+  (if-not (zero? times)
+    (let [head (first modified-str)
+          rest (next modified-str)
+          new-modified-str (str (s/join rest) head)
+          new-times (- times 1)]
+      (if (= input-str modified-str)
+        (+ 1 (transpose-and-check-if-same input-str new-modified-str new-times))
+        (+ 0 (transpose-and-check-if-same input-str new-modified-str new-times))))
+    0))
+
+(defn repeats [input-str]
+  (let [length (count input-str)
+        head (first input-str)
+        rest (next input-str)]
+    (transpose-and-check-if-same input-str (str (s/join rest) head) length)))