Problem 0054.

Problem 0054.

--- src/project_euler/problem_0054.clj
+++ src/project_euler/problem_0054.clj
@@ -145,12 +145,14 @@
             ])

 (defn h-rank [hand]
-  (some identity (map (fn [f r] (when-let [vals (f hand)] [r vals])) ranks (iterate dec (count ranks)))))
+  (some identity (map (fn [f r] (when-let [vals (f hand)] [r (vec vals)])) ranks (iterate dec (count ranks)))))

 (defn solution []
   (->> (slurp "resources/p054_poker.txt")
        (clojure.string/split-lines)
-       (map (fn [line] (partition 2 (clojure.string/split line #" "))))
+       (map (fn [line] (partition 5 (clojure.string/split line #" "))))
        (map (fn [[h1 h2]] [(h-rank h1) (h-rank h2)]))
-       (take 5)
+       (map (fn [[r1 r2]] (compare r1 r2)))
+       (filter #{1})
+       (count)
        ))


Reword error message

Reword error message

--- src/refactor_nrepl/ns/clean_ns.clj
+++ src/refactor_nrepl/ns/clean_ns.clj
@@ -21,7 +21,7 @@
   (dorun (map
           #(when (= % :exclude)
              (throw (IllegalArgumentException.
-                     "Can't remove :use clause with :exclude clause!")))
+                     "Can't run clean-ns on :use clause containing :exclude!")))
           (tree-seq sequential? identity use-form)))
   use-form)


convert PORT to integer

convert PORT to integer

--- src/ruuvi_server/configuration.clj
+++ src/ruuvi_server/configuration.clj
@@ -39,7 +39,7 @@
     (merge conf
            {:database (heroku-database-config)
             :server (merge (conf :server)
-                           {:port (System/getenv "PORT")}
+                           {:port (Integer/valueOf(System/getenv "PORT"))}
                            )})
     conf)
   )


show updated Quicksand strength immediately

--- src/clj/game/cards-ice.clj
+++ src/clj/game/cards-ice.clj
@@ -526,7 +526,8 @@
    "Quicksand"
    {:abilities [{:req (req (and this-server (= (dec (:position run)) (ice-index state card))))
                  :label "Add 1 power counter"
-                 :effect (effect (add-prop card :counter 1))}
+                 :effect (effect (add-prop card :counter 1)
+                                 (update-all-ice))}
                  end-the-run]
     :strength-bonus (req (or (:counter card) 0))}


Make all download action safe

Make all download action safe

--- src/clj/subman/helpers.clj
+++ src/clj/subman/helpers.clj
@@ -5,33 +5,6 @@
             [net.cgrand.enlive-html :as html]
             [clj-http.client :as client]
             [subman.const :as const]))
-
-(defn remove-first-0
-  "Remove first 0 from string"
-  [query]
-  (clojure.string/replace query #"^(0+)" ""))
-
-(defn get-from-line
-  "Get parsed html from line"
-  [line]
-  (html/html-resource (StringReader. line)))
-
-(defn download
-  [url]
-  (:body (client/get url {:socket-timeout const/conection-timeout
-                          :conn-timeout const/conection-timeout})))
-
-(defn fetch
-  "Fetch url content"
-  [url]
-  (get-from-line (download url)))
-
-(defn nil-to-blank
-  "Replace nil with blank string"
-  [item]
-  (if (nil? item)
-    ""
-    item))

 (defn make-safe
   "Make fnc call safe"
@@ -48,6 +21,33 @@
     `(defsafe ~name ~@(rest body))
     `(def ~name (make-safe (fn ~@body)
                            nil))))
+
+(defn remove-first-0
+  "Remove first 0 from string"
+  [query]
+  (clojure.string/replace query #"^(0+)" ""))
+
+(defn get-from-line
+  "Get parsed html from line"
+  [line]
+  (html/html-resource (StringReader. line)))
+
+(defsafe download
+  [url]
+  (:body (client/get url {:socket-timeout const/conection-timeout
+                          :conn-timeout const/conection-timeout})))
+
+(defsafe fetch
+  "Fetch url content"
+  [url]
+  (get-from-line (download url)))
+
+(defn nil-to-blank
+  "Replace nil with blank string"
+  [item]
+  (if (nil? item)
+    ""
+    item))

 (defn get-season-episode-part
   [text]


Fixing typo

Fixing typo

--- src/cljs/memento/core.cljs
+++ src/cljs/memento/core.cljs
@@ -563,7 +563,7 @@
                    {:placement :top
                     :overlay   tooltip}
                    [:span {:class    "btn btn-danger btn-xs icon-margin-left"
-                           :on-click #(when (js/confirm "Are you sure yu want to remove the thought/")
+                           :on-click #(when (js/confirm "Are you sure you want to remove the thought/")
                                         (dispatch [:cluster-remove-thought (:id cluster) (:id memory)]))}
                     [:i {:class "fa fa-minus"}]]])]
     [:span


Minor fix for notebook rendering.

Minor fix for notebook rendering.

--- src/cljs/website/core.cljs
+++ src/cljs/website/core.cljs
@@ -140,17 +140,22 @@
 (secretary/defroute "/experiments" []
   (session/put! :page :experiments))

+(defn notebook-handler [data]
+  (.log js/console (.parse js/JSON data))
+  (js/setTimeout
+    (fn[] (.appendChild
+      (.getElementById js/document "notebook")
+        (.render (.parse js/nb (.parse js/JSON data)))
+      )
+    ) 150
+  )
+)
+
 (secretary/defroute "/notebook/:id" [id]
   (session/put! :page :notebook)
-  (.getJSON js/jQuery (str (js/atob id)) (fn [data]
-    (js/setTimeout
-      (fn[] (.appendChild
-        (.getElementById js/document "notebook")
-          (.render (.parse js/nb data))
-        )
-      ) 150
-    )
-  ))
+  (GET (js/atob id) {
+    :handler notebook-handler
+  })
 )

 (secretary/defroute "/games" []


History fix.

History fix.

--- src/cljs/website/core.cljs
+++ src/cljs/website/core.cljs
@@ -112,10 +112,12 @@
     [:div.row
     [:div#game.col-md-12]]])

+(defonce notebook-data (r/atom nil))
+
 (defn notebook-page []
   [:div.container
     [:div.row
-    [:div#notebook.col-md-12]]])
+    [:div#notebook.col-md-12 {:dangerouslySetInnerHTML #js{:__html @notebook-data}}]]])

 (def pages
   {:home #'home-page
@@ -151,18 +153,18 @@
   })

 (defn nicescroll [id]
-  (ready (fn []
-    (.niceScroll (js/jQuery id) nicescroll-config))))
+  (ready #(.niceScroll (js/jQuery id) nicescroll-config)))

 (defn notebook-handler [data]
   (ready (fn []
-    (.appendChild
-      (js/document.getElementById "notebook")
-      (-> data js/JSON.parse js/nb.parse .render))
-    (js/Prism.highlightAll)
-    (nicescroll "#app > .container"))))
+    (swap! notebook-data
+      #(-> data js/JSON.parse js/nb.parse .render .-innerHTML))
+    (js/setTimeout (fn []
+      (js/Prism.highlightAll)
+      (nicescroll "#app > .container")) 100))))

 (secretary/defroute "/notebook/:id" [id]
+  (swap! notebook-data (constantly nil))
   (session/put! :page :notebook)
   (GET (js/atob id) { :handler notebook-handler }))


Fixing bug when parsing diff. Granule spatial representation must always be set.

--- src/cmr/umm/dif/collection/spatial_coverage.clj
+++ src/cmr/umm/dif/collection/spatial_coverage.clj
@@ -33,7 +33,7 @@
         spatial-coverage-elems (cx/elements-at-path xml-struct [:Spatial_Coverage])]
     (when (or gsr (seq spatial-coverage-elems))
       (c/map->SpatialCoverage
-        {:granule-spatial-representation gsr
+        {:granule-spatial-representation (or gsr :no-spatial)
          :spatial-representation (when (seq spatial-coverage-elems) :cartesian)
          :geometries (seq (map spatial-coverage-elem->br spatial-coverage-elems))}))))


remove! ask for permission to delete

remove! ask for permission to delete

--- src/todos/executor/exec_remove.clj
+++ src/todos/executor/exec_remove.clj
@@ -10,8 +10,12 @@
     (println "You cant remove root")
     (let [current-todo (current-todolist)
           current-name ((current-todo :name))]
-      (println current-name)
-      )))
+      (if (= "yes" (inp/user-str-input
+                     (format "Ary you sure to delete \"%s\"? (yes/no) " current-name)
+                     ))
+        (println "Here we want to delete")
+        (println "canceled.")
+        ))))

 (defn remove-
   [joined-args]


Refactor sub

Refactor sub

--- src/braid/client/subs.cljs
+++ src/braid/client/subs.cljs
@@ -292,8 +292,7 @@
 (reg-sub
   :open-group-tags
   (fn [state _]
-    (into ()
-          (comp
-            (filter (fn [tag] (= (get-in state [:open-group-id]) (tag :group-id)))))
-          (vals (get-in state [:tags])))))
-
+    (->> (state :tags)
+         vals
+         (filter (fn [tag] (= (get-in state [:open-group-id]) (tag :group-id)))))))
+


Improve padding implementation.

Improve padding implementation.

--- src/buddy/core/padding.clj
+++ src/buddy/core/padding.clj
@@ -14,6 +14,7 @@

 (ns buddy.core.padding
   "Block padding algorithms."
+  (:refer-clojure :exclude [count])
   (:require [buddy.core.bytes :as bytes])
   (:import org.bouncycastle.crypto.paddings.ZeroBytePadding
            org.bouncycastle.crypto.paddings.X923Padding
@@ -37,35 +38,42 @@

 (defn pad!
   "Add padding using one of supported padding algorithms."
-  ([^bytes input ^long offset] (pad input offset :zerobyte))
+  ([^bytes input ^long offset] (pad! input offset :pkcs7))
   ([^bytes input ^long offset ^Keyword alg]
    (let [engine (padding-engine alg)]
      (.init engine (java.security.SecureRandom.))
      (.addPadding engine input offset))))

-(defn pad
-  "Add padding using one of supported padding algorithms.
-  This is a side effect free version of pad! function."
-  ([^bytes input ^long offset] (pad input offset :zerobyte))
-  ([^bytes input ^long offset ^Keyword alg]
-   (let [^bytes input (bytes/copy input)]
-     (pad! input offset alg)
-     input)))
+(defn unpad!
+  "Remove padding from given byte array and fill
+  the unpadded bytes with 0"
+  ([^bytes input] (unpad! input :pkcs7))
+  ([^bytes input ^Keyword alg]
+   (let [engine (padding-engine alg)
+         padsize (.padCount engine input)
+         offset (- (clojure.core/count input) padsize)]
+     (bytes/fill input 0 :offset offset))))
+
+(defn count
+  "Get the padding size found on given byte array."
+  ([^bytes input] (count input :pkcs7))
+  ([^bytes input ^Keyword alg]
+   (let [engine (padding-engine alg)]
+     (.padCount engine input))))

 (defn padded?
   "Check if given byte array has padding using specified
-  padding algorithm. If no one is specified, :zerobyte
+  padding algorithm. If no one is specified, :pkcs7
   will be used."
-  ([^bytes input] (padded? input :zerobyte))
+  ([^bytes input] (padded? input :pkcs7))
   ([^bytes input ^Keyword alg]
-   (let [engine (padding-engine alg)]
-     (pos? (.padCount engine input)))))
+   (pos? (count input alg))))

-(defn unpad
-  "Remove padding from given byte array and return a new
-  byte array without padding."
-  ([^bytes input] (unpad input :zerobyte))
-  ([^bytes input ^Keyword alg]
-   (let [engine (padding-engine alg)
-         num (.padCount engine input)]
-     (bytes/slice input 0 (- (count input) num)))))
+;; (defn pad
+;;   "Add padding using one of supported padding algorithms.
+;;   This is a side effect free version of pad! function."
+;;   ([^bytes input ^long offset] (pad input offset :pkcs7))
+;;   ([^bytes input ^long offset ^Keyword alg]
+;;    (let [^bytes input (bytes/copy input)]
+;;      (pad! input offset alg)
+;;      input)))


removed debug logging.

removed debug logging.

--- ssclj/jar/src/com/sixsq/slipstream/ssclj/util/namespace_utils.clj
+++ ssclj/jar/src/com/sixsq/slipstream/ssclj/util/namespace_utils.clj
@@ -6,21 +6,12 @@
     [clojure.java.classpath :as cp]
     [clojure.tools.namespace.find :as nsf]))

-(defn show
-  [msg o]
-  (println "OBJECT --->>> " msg)
-  (clojure.pprint/pprint o)
-  (println "<<<--- OBJECT")
-  o)
-
 (defn filter-namespaces
   "Returns symbols for all of the namespaces that match the given filter
    function."
   [f]
   (->> (cp/classpath)
-       ;(show "CLASS-PATH")
        (nsf/find-namespaces)
-       ;(show "NAME-SPACES")
        (filter f)))

 (defn load-namespace


refactor validation for flat entities

refactor validation for flat entities

--- src/gangway/validation.clj
+++ src/gangway/validation.clj
@@ -1,39 +1,34 @@
 (ns gangway.validation
   (:require [clojure.data.json :as json]
+            [clojure.pprint :refer [pprint]]
             [hatch]
             [schema.core :as s]
-            [navigator.validation :as nav-val]
             [oarlock.validation :as oar-val]))

 (defn construct-data
-  "Constructs a namespaced map out of an incoming json message"
-  [msg]
-  (let [entity-type (get-in msg [:header :entity-type])]
-    (if (get-in msg [:header :entity-id])
-      (let [id-key (keyword (str entity-type "-id"))
-            id-sk-key (keyword (str entity-type "/id-sk"))
-            id (str (get-in msg [:header :entity-id id-key]))]
-        (merge {id-sk-key id}
-               (hatch/slam-all (get-in msg [:payload :entity]) (keyword entity-type))))
-      (hatch/slam-all (get-in msg [:payload :entity]) (keyword entity-type)))))
+  "Combines route-params with incoming json message"
+  [msg rp]
+  (pprint msg)
+  (merge msg {:id-sk (:id-sk rp)
+              :id-sk-origin (keyword (:id-sk-origin rp))}))

 (defn validator
-  [entity-type validation-map data]
+  [validation-map entity-type data]
   (let [validation (entity-type validation-map)]
     (if validation
       (try
         (s/validate
          validation
          data)
-        (catch Exception e (.getMessage e)))
-      data)))
+        {:valid true :data data}
+        (catch Exception e {:valid false :error (.getMessage e)}))
+      {:valid true :data data})))

 (def validation-maps
   {:assert
    {:task           oar-val/validations
     :perf-asmt      oar-val/validations
-    :user2perf-asmt oar-val/validations
-    :user2comp      nav-val/validations}})
+    :user2perf-asmt oar-val/validations}})

 (defn valid-json?
   "Evaluates given message string to determine if it's valid JSON.
@@ -50,13 +45,19 @@
 (defn valid?
   "Runs a validation function to check if a message is valid.
   Returns true or false."
-  [msg]
-  (let [op (keyword (:operation msg))
-        entity-type (keyword (:entity-type msg))
+  [msg rp op]
+  (let [entity-type (keyword (:entity-type rp))
         validation-map (get-in validation-maps [op entity-type])]
-    (if (nil? validation-map)
-      true
-      ;;We need some new validation here
-      #_(if (nil? (first (validation-fn (construct-data msg))))
-        true
-        false))))
+    (if (valid-json? msg)
+      (let [parsed-msg (json/read-str msg :key-fn keyword)
+            data (construct-data parsed-msg rp)]
+        (if (nil? validation-map)
+          true
+          (validator validation-map entity-type data))))))
+
+(comment
+
+  (def msg {:name "flarp" :version "v2" :description "this is a description"})
+  (def rp {:id-sk "392" :id-sk-origin "showevidence" :entity-type "task" :qid "showevidence"})
+
+  )


Put the starting page in the session on initialisation to fix the crash (which doesn't happen with figwheel).

--- src/klangmeister/core.cljs
+++ src/klangmeister/core.cljs
@@ -65,6 +65,7 @@
 (defn mount-root []
   (let [handle! (framework/handler-for state-atom)]
     (handle! (action/->Refresh (macro/text "src/klangmeister/live.cljs.txt") :main))
+    (session/put! :current-page #'home-page)
     (reagent/render
       [current-page]
       js/document.body)))


debbuging

debbuging

--- src/celestial/puppet_standalone.clj
+++ src/celestial/puppet_standalone.clj
@@ -44,6 +44,7 @@
    (task copy-yaml
      (let [{:keys [type module]} args path (<< "/tmp/~(type :hostname).yml") f (file path) ]
        (spit f (yaml/generate-string (select-keys type [:classes])))
+       (debug "copy from " path remote)
        (copy path (<< "/tmp/~(module :name)/"))
        (.delete f)))


fixing exit code error detection

fixing exit code error detection

--- src/celestial/puppet_standalone.clj
+++ src/celestial/puppet_standalone.clj
@@ -54,7 +54,7 @@

    (task run-puppet
       (let [{:keys [module type]} args]
-        (run (str (<< "cd /tmp/~(:name module)") " && " (as-root remote (<< "./scripts/run.sh ~(args-of type)"))))))
+        (run (str (<< "cd /tmp/~(:name module)") " && " (as-root remote (<< "./scripts/run.sh ~(args-of type) --detailed-exitcodes || [ $? -eq 2 ]"))))))

    (task cleanup
       (let [{:keys [module]} args]


few extra options and comments

few extra options and comments

--- src/clj/just_married/api/labels.clj
+++ src/clj/just_married/api/labels.clj
@@ -11,12 +11,18 @@

 (def ^:private default-n-cols 3)
 (def ^:private file-name "labels.pdf")
+(def ^:private default-font "Helvetica")

 (defn labels-sql
   []
   (-> (h/select :group_name :country :address)
       (h/from :guests-group)
-      (h/where [:= :invitation_sent false])
+      (h/where [:and
+                [:= :invitation_sent false]
+                ;; could add this if we don't need labels for manually handed over anyway
+                ;; [:not= :address nil]
+                ;; [:not= :country nil]
+                ])
       (sql/format)))

 (defn get-labels!
@@ -31,6 +37,9 @@
    :bottom-margin          2
    :size                   :a4
    :font                   {:size     12
+                            :family   default-font
+                            ;;TODO: change the font in this way if you want to
+                            ;; :ttf-name "resources/public/fonts/OpenSans-Regular.ttf"
                             :encoding :unicode}
    :register-system-fonts? true})


Use multimethod for asciicast initialization

--- src/cljs/asciinema_player/core.cljs
+++ src/cljs/asciinema_player/core.cljs
@@ -277,31 +277,34 @@
   {:lines (vt/compact-lines lines)
    :cursor cursor})

-(defn initialize-asciicast-v0 [state asciicast]
+(defmulti initialize-asciicast (fn [dispatch state asciicast]
+                                 (if (vector? asciicast)
+                                   0
+                                   (:version asciicast))))
+
+(defmethod initialize-asciicast 0 [dispatch state asciicast]
   (let [frame-0-lines (-> asciicast first last :lines)
         width (->> frame-0-lines vals first (map #(count (first %))) (reduce +))
         height (count frame-0-lines)]
     (assoc state
+           :loading false
            :width (or (:width state) width)
            :height (or (:height state) height)
            :frame-fn acc->frame
            :duration (reduce #(+ %1 (first %2)) 0 asciicast)
            :frames (build-v0-frames asciicast))))

-(defn initialize-asciicast-v1 [state asciicast]
+(defmethod initialize-asciicast 1 [dispatch state asciicast]
   (assoc state
+         :loading false
          :width (or (:width state) (:width asciicast))
          :height (or (:height state) (:height asciicast))
          :frame-fn vt->frame
          :duration (reduce #(+ %1 (first %2)) 0 (:stdout asciicast))
          :frames (build-v1-frames asciicast)))

-(defn initialize-asciicast
-  "Prepares fetched asciicast for playback."
-  [state asciicast]
-  (cond (vector? asciicast) (initialize-asciicast-v0 state asciicast)
-        (= 1 (:version asciicast)) (initialize-asciicast-v1 state asciicast)
-        :else (throw (str "unsupported asciicast version: " (:version asciicast)))))
+(defmethod initialize-asciicast :default [dispatch state asciicast]
+  (throw (str "unsupported asciicast version: " (:version asciicast))))

 (defn handle-asciicast-response
   "Merges asciicast frames into player state, hides loading indicator and starts the
@@ -311,9 +314,7 @@
   (let [asciicast (-> json
                       js/JSON.parse
                       (util/faster-js->clj :keywordize-keys true))]
-    (-> state
-        (assoc :loading false)
-        (initialize-asciicast asciicast))))
+    (initialize-asciicast dispatch state asciicast)))

 (defn handle-bad-response [state dispatch resp]
   (print "error fetching asciicast file:")


More alt

More alt

--- src/cljs/browser_rotation/core.cljs
+++ src/cljs/browser_rotation/core.cljs
@@ -75,7 +75,7 @@
                               :id n
                               :on-change #(select! i) }]
                      [:label {:for n}
-                      [:img { :src (value browser) :width 30 :height 30 } ]]])) @browsers)])
+                      [:img { :src (value browser) :width 30 :height 30 :alt (k browser)} ]]])) @browsers)])

 (defn browser-rotation []
   (let [days ["Monday" "Tuesday" "Wednesday" "Thursday" "Friday"]]


Added missing fingering message

Added missing fingering message

Signed-off-by: Christian Romney <78cb0763aa1664e7dd86fd558ae466f67ab17826@pointslope.com>

--- src/cljs/trumpet/ui/components.cljs
+++ src/cljs/trumpet/ui/components.cljs
@@ -115,7 +115,11 @@
   "Renders the row in the scale table that displays instrument fingerings."
   [state note-seq]
   [:tr
-   (doall (map-indexed (partial finger-cell state) note-seq))])
+   (let [current-instrument (:instrument @state)]
+     (if (get instrument/fingering current-instrument)
+       (doall (map-indexed (partial finger-cell state) note-seq))
+       [:td.text-center {:colSpan 8}
+        (str "Fingering chart not yet available for " current-instrument)]))])

 (defn scale-table
   "Renders a table containing the notes and fingerings for the currently selected


Ensure that reloaded clj files are reloaded in the specified order.

--- src/lib/clj/one/reload.clj
+++ src/lib/clj/one/reload.clj
@@ -82,10 +82,10 @@
 ;; Implement ISources for multiple directores. The pred function is
 ;; used to filter the returned files.

-(defrecord Directories [dirs pred]
+(defrecord Directories [dirs pred order]
   ISources
   (files [this]
-    (filter-all-descendants dirs pred)))
+    (sort-by order (filter-all-descendants dirs pred))))

 ;; Implement ISources and Compilable for multiple ClojureScript source
 ;; directories. The directores may contain non-ClojureScript files,
@@ -134,7 +134,6 @@
   Compilable
   (-compile [this opts]
     (let [fs (files this)]
-      (reload-clj-seq fs)
       (let [d (io/file dir)]
         (flatten (map #(-compile % (assoc opts :output-file (js-file-name d %)))
                       fs))))))
@@ -236,8 +235,13 @@
 ;; Sugar
 ;; =====

-(defn clj-files-in [dirs & files]
-  (let [clj (->Directories dirs (by-file-name (vec files)))]
+(defn name-order [names]
+  (fn [file] (get (into {} (map-indexed (fn [i x] [x i]) names))
+                 (.getName file)
+                 0)))
+
+(defn clj-files-in [dirs & fs]
+  (let [clj (->Directories dirs (by-file-name (vec fs)) (name-order fs))]
     (->ClojureReloadable [clj])))

 (defn shared
@@ -255,7 +259,7 @@
        (->ClojureScriptReloadable opts sources pkgs))))

 (defn dir-trigger [dir reloadable]
-  (let [dir-source (->Directories [dir] (constantly true))]
+  (let [dir-source (->Directories [dir] (constantly true) identity)]
     (->DirDependency dir-source [reloadable])))

 ;; Examples
@@ -268,7 +272,8 @@
                                               "templates.clj"
                                               "api.clj"
                                               "application.clj"
-                                              "snippets.clj"])))
+                                              "snippets.clj"])
+                               identity))
   (files clj-dirs)

   (def clj-r (->ClojureReloadable [clj-dirs]))


CMR-387: Add nil for orbit parameter in call to spatial.

--- test/cmr/system_int_test/search/collection_search_format_test.clj
+++ test/cmr/system_int_test/search/collection_search_format_test.clj
@@ -254,6 +254,7 @@
                                         :related-urls [ru3]
                                         :spatial-coverage
                                         (dc/spatial :cartesian
+                                                    nil
                                                     :cartesian
                                                     (poly/polygon [(umm-s/ords->ring -70 20, 70 20, 70 30, -70 30, -70 20)]))}))]


Make sure there is an empty page before the back cover

--- src/catalog/layout/fop.clj
+++ src/catalog/layout/fop.clj
@@ -521,6 +521,8 @@
                         :force-page-count "no-force"
                         :font-family "StoneSans, Arial"}
      [:fo:flow {:flow-name "xsl-region-body"}
+      ;; add an empty page before the back cover
+      [:fo:block {:break-before "page" :break-after "page"} " "]
       [:fo:wrapper {:role "artifact"}
        [:fo:block-container {:absolute-position "fixed" :width "210mm" :height "297mm"
                              :left "0mm" :top "0mm" :background-color "transparent"}


Test fix :wrench:

Test fix :wrench:

--- test/metabase/cmd/load_from_h2_test.clj
+++ test/metabase/cmd/load_from_h2_test.clj
@@ -13,7 +13,8 @@

 (defn- all-entity-names []
   (set (for [ns       (ns-find/find-namespaces (classpath/classpath))
-             :when    (re-find #"^metabase\.models\." (name ns))
+             :when    (or (re-find #"^metabase\.models\." (name ns))
+                          (= (name ns) "metabase.db.migrations"))
              :when    (not (re-find #"test" (name ns)))
              [_ varr] (do (require ns)
                           (ns-interns ns))
@@ -22,5 +23,5 @@
          (:name entity))))

 (expect
-  (migrated-entity-names)
-  (all-entity-names))
+  (all-entity-names)
+  (migrated-entity-names))


fix shadowing

fix shadowing

--- test/riemann/jvm_profiler/core_test.clj
+++ test/riemann/jvm_profiler/core_test.clj
@@ -1,8 +1,8 @@
 (ns riemann.jvm-profiler.core-test
-  (:require [riemann.jvm-profiler :as profiler])
-  (:use [clojure.test]))
+  (:use [clojure.test :exclude (report)]
+        [riemann.jvm-profiler]))

 (deftest format-prefix-test
   (testing "format-prefix"
-    (is (= (profiler/format-prefix "") "")
-    (is (= (profiler/format-prefix "myapp") "myapp ")))))
+    (is (= (format-prefix "") "")
+    (is (= (format-prefix "myapp") "myapp ")))))


Remove debug prints

Remove debug prints

--- src/onyx/plugin/kafka.clj
+++ src/onyx/plugin/kafka.clj
@@ -110,7 +110,6 @@
                 (let [message ^KafkaMessage (first ms)
                       next-offset ^int (.offset message)
                       dm (deserializer-fn (.value message))]
-                  (clojure.pprint/pprint ["RX" dm])
                   (>!! ch (assoc (t/input (java.util.UUID/randomUUID)
                                           dm)
                                  :offset next-offset))
@@ -202,7 +201,6 @@

   (ack-segment [_ _ segment-id]
     (when-let [offset (:offset (get @pending-messages segment-id))]
-      (clojure.pprint/pprint ["ACK" (get @pending-messages segment-id)])
       (swap! pending-commits conj offset))
     (swap! pending-messages dissoc segment-id))


Profile exports raw format again

Profile exports raw format again

--- src/com/wsscode/pathom/profile.cljc
+++ src/com/wsscode/pathom/profile.cljc
@@ -4,8 +4,6 @@
     #?(:cljs [cljs.core.async :refer [<! chan put!]])
                     [com.wsscode.pathom.core :as p]
                     [com.wsscode.pathom.async :as pa]))
-
-(declare profile->flame-graph)

 (defn- append-at [cur v]
   (cond
@@ -29,7 +27,7 @@
    (fn [reader]
      (fn [{::keys [profile*] ::p/keys [path] :as env}]
        (if (= ::profile (p/key-dispatch env))
-         (profile->flame-graph @profile*)
+         @profile*
          (let [start-time (current-time-ms)
                res        (reader env)]
            (swap! profile* update-in path append-at


added pagination. need more work on the framework

--- src/crawler/rich_char_extractor.clj
+++ src/crawler/rich_char_extractor.clj
@@ -1,6 +1,8 @@
 (ns crawler.rich-char-extractor
   "Character based extraction as opposed to token based extraction"
-  (require [crawler.dom :as dom]))
+  (require [crawler.dom :as dom]
+           [crawler.tree-edit-distance :as ted]
+           [net.cgrand.enlive-html :as html]))

 (defn leaf?
   [src-num target-num]
@@ -104,3 +106,26 @@
        :score (/ score (:total-nav-info content))
        :hrefs hrefs})
     (:xpath-nav-info content))))
+
+(defn pagination?
+  "Even 1 pagination is good."
+  [{xpath :xpath hrefs :hrefs texts :texts} src-tree]
+  (let [to-sample (sample-quarter hrefs)
+        page-sims (map
+                   #(ted/tree-edit-distance
+                     src-tree (ted/load-tree %))
+                   to-sample)]
+
+    (seq
+     (filter #(<= 0.8 %) page-sims))))
+
+(defn detect-pagination
+  "Pagination detection module.
+   First, we kick off from the least useful guys
+   and go to the most useful guys. Along the way,
+   bundle some shit up."
+  [normalized-decision-space body]
+  (let [tree1  (html/html-resource
+                (java.io.StringReader. body))
+        sorted (sort-by :score normalized-decision-space)]
+    (filter #(pagination? % tree1) sorted)))


implement get_permissions

implement get_permissions

--- src/fscrawler_tika_convert/core.clj
+++ src/fscrawler_tika_convert/core.clj
@@ -153,13 +153,64 @@
   (lb/ack ch delivery-tag))

+
+(defn get-permissions-for-entry
+  [fs directory {relpath :relpath, {type :type} :stat, error :error :as entry}]
+  (if (and (= type "file") (not error))
+    (assoc entry "permissions" (vfs/get-permissions fs (vfs/join fs [directory relpath])))
+    entry))
+
+
+(defn get-permissions
+  [fs directory entries]
+  (map (partial get-permissions-for-entry fs directory)
+       entries))
+
+(defn entry-is-type?
+  [type entry]
+  (= (get-in entry [:stat :type]) type))
+
+(def entry-is-directory? (partial entry-is-type? "directory"))
+(def entry-is-file? (partial entry-is-type? "file"))
+
+(defn entry-is-directory?
+  [entry]
+  (= (get-in entry [:stat :type]) "directory"))
+
+
+(defn handle-msg-get_permissions
+  [fs ch {:keys [delivery-tag exchange routing-key] :as meta} ^bytes payload]
+  (let [body (json/read-json (String. payload "UTF-8"))
+        directory (:directory body)
+        entries-with-permissions (get-permissions fs directory (:entries body))]
+
+    (let [listdir-cmd (routing-key-string-with-command routing-key "listdir")]
+      (doseq [entry (filter (fn [entry]
+                              (and (entry-is-directory? entry)
+                                   (not (:error entry))))
+                            entries-with-permissions)]
+        (let [subdirectory-path (vfs/join fs [directory (:relpath entry)])]
+          (println "publish listdir" subdirectory-path listdir-cmd)
+          (lb/publish ch exchange listdir-cmd
+                      (json/write-str {:path subdirectory-path})))))
+
+
+    (lb/publish ch exchange (routing-key-string-with-command routing-key "update_directory")
+                (json/write-str (assoc body :entries entries-with-permissions)))
+
+    (lb/ack ch delivery-tag)))
+
+
 (defn handle-msg-listdir
-  [fs ch {:keys [content-type delivery-tag type] :as meta} ^bytes payload]
-  (println (format "[consumer] Received a message: %s, delivery tag: %d, content type: %s, type: %s"
-                   (String. payload "UTF-8")
-                   delivery-tag
-                   content-type
-                   type))
+  [fs ch {:keys [delivery-tag exchange routing-key] :as meta} ^bytes payload]
+  (let [body (json/read-json (String. payload "UTF-8"))
+        path (:path body)
+        entries (vfs/cmd-listdir fs path)]
+    (println "handle-msg-listdir" path)
+    (lb/publish ch
+                exchange
+                (routing-key-string-with-command routing-key "get_permissions")
+                (json/write-str {:directory path :entries entries})))
   (lb/ack ch delivery-tag))

@@ -241,7 +292,8 @@

 (def command->msg-handler
-  {"listdir" handle-msg-listdir})
+  {"listdir" handle-msg-listdir
+   "get_permissions" handle-msg-get_permissions})


Update words.clj

Update words.clj

--- src/iyye/subcon/knowledge/words.clj
+++ src/iyye/subcon/knowledge/words.clj
@@ -1,5 +1,5 @@
 ; Iyye - AI agent
-; Copyright (C) 2016-2018  Sasha Yumzya
+; Copyright (C) 2016-2019  Sasha Yumzya

 ; This program is free software: you can redistribute it and/or modify
 ; it under the terms of the GNU Affero General Public License as
@@ -181,7 +181,7 @@
         verbs (get-iyye-verbs name)]
     (if (:UNKNOWN (first types))
       (if (:UNKNOWN (first verbs))
-        types
+        (list (first types))
         verbs)
       (if (:UNKNOWN (first verbs))
         types
@@ -197,20 +197,25 @@
         (save-iyye-builtin-type-to-db type)))))

 (defn check-select-params [action params]
-  "true if params matches action, false other ways"
+  "params tree if params matches action, false other ways"
   (let [act-params (:Types action)
+        relation-check (if (= "relation" (first act-params))
+                         (check-select-params (first (filter :Predicate (first params))) (rest params)) true)
         check-params-count
         (fn [p1 p2]
           (if (= "*" (last p2))
             (>= (count p1) (count p2))
             (= (count p1) (count p2))))
-        expand-params (fn [p] (map #(map (fn [stype] (assoc stype :Param %)) (get-supertypes %))
-                                   p))]
-    (when (check-params-count params act-params)
+        expand-params (fn [p] (map #(map (fn [stype] (assoc stype :Param %)) (get-supertypes %)) p))]
+    (when (and relation-check (check-params-count params act-params))
       (let [params-types (for [cur params] (expand-params cur))
-            act-params2 (take (count params-types) act-params)
+            params-len (count params-types)
+            act-params2 (take params-len act-params)
+            act-params3 (reduce conj (if (and (= "*" (last act-params2)) (> params-len (count act-params)))
+                                       (repeat (- params-len (count act-params)) "*")
+                                       (list)) (reverse (take params-len act-params)))
             ;   vec-params (vec (map #(:Name (:name %)) params))
-            pairs (map #(vector %1 (flatten  %2)) act-params2 params-types)
+            pairs (map #(vector %1 (flatten %2)) act-params3 params-types)
             check-pair (fn [t check]
                          (case t
                              :UNKNOWN (= :UNKNOWN check)
@@ -234,33 +239,32 @@
 ; (when (check-params relation params)
 ;  ((:Function relation) params)) )

-(defn action-function [action params-list pred]
-  (if (and (= (:type (:name (first params-list)))  "relation")
-           (= (:Result action) "predicate"))
-    ((:Function action) (conj params-list pred))
-    ((:Function action) params-list)))
-
-(defn run-action [cmd params IO]
+(defn run-action [cmd params]
   (let [actions-list (get-iyye-verbs cmd)
         params-list (if (map? (first params))               ; map? is a check for non-string but resolved type
                       params (map get-iyye-words params))
-        pred (->Iyye_ModalPredicate :YUMZIA :INSTRUCTION (persistence/local-time-to-string) :ALWAYS)]
+        pred (->Iyye_ModalPredicate :YUMZIA :INSTRUCTION (persistence/local-time-to-string) :ALWAYS)
+        append-param-list (fn [action plist]
+                            (if (and (= (:Result action) "relation") (= (:Type (:name (first (filter :Predicate (first plist))))) "relation"))
+                              (cons (list pred) plist)
+                              plist))]
     (case (count actions-list)
       0 (->Iyye_Error (str "failed to parse: no matching action to " cmd) pr-str)
       1 (let [action (first actions-list)
-              plist (check-select-params action params-list)]
+              plist (check-select-params action (append-param-list action params-list))]
           (if plist
-            (action-function action plist pred)
+            ((:Function action) plist)
             (->Iyye_Error (pr-str "Params invalid for " cmd " : " params) pr-str)))
       (let [matching-actions
-            (for [action actions-list :when (check-select-params action params-list)] action)]
+            (for [action actions-list :when (check-select-params action (append-param-list action params-list))] action)]
         (case (count matching-actions)
           0 (->Iyye_Error (pr-str "Cant find " cmd " " params) pr-str)
-          1 (action-function (first matching-actions) (check-select-params (first matching-actions) params-list) pred)
+          1 ((:Function (first matching-actions)) (check-select-params (first matching-actions)
+                                                                       (append-param-list (first matching-actions) params-list)))
           (->Iyye_Error (pr-str "Too many actions " cmd " " params) pr-str)))))) ; FIXME probabilities

 (defn action [cmd params IO]
   "Params are either text or objects from previous evaluations"
   (when (not @dbg-IO) (dosync (ref-set dbg-IO IO)))         ; set debug
   ; (print-io-str @dbg-IO (str "cmd: " cmd "::" (pr-str params)) )
-  (run-action cmd params IO))
+  (run-action cmd params))


optimize analyze-symbol

optimize analyze-symbol

--- src/main/clojure/cljs/analyzer.cljc
+++ src/main/clojure/cljs/analyzer.cljc
@@ -2129,22 +2129,28 @@
 (defn analyze-symbol
   "Finds the var associated with sym"
   [env sym]
-  (if (:quoted? env)
+  (if ^boolean (:quoted? env)
     {:op :constant :env env :form sym :tag 'cljs.core/Symbol}
     (let [{:keys [line column]} (meta sym)
-          env (cond-> env
-                line (assoc :line line)
-                column (assoc :column column))
-          ret {:env env :form sym}
-          lb (-> env :locals sym)]
-      (if lb
+          env  (if-not (nil? line)
+                 (assoc env :line line)
+                 env)
+          env  (if-not (nil? column)
+                 (assoc env :column column)
+                 env)
+          ret  {:env env :form sym}
+          lcls (:locals env)
+          lb   (get lcls sym)]
+      (if-not (nil? lb)
         (assoc ret :op :var :info lb)
-        (if-not (:def-var env)
-          (assoc ret :op :var :info
-            (if-not (contains? (meta sym) ::analyzed)
-              (resolve-existing-var env sym)
-              (resolve-var env sym)))
-          (assoc ret :op :var :info (resolve-var env sym)))))))
+        (if-not (true? (:def-var env))
+          (let [sym-meta (meta sym)
+                info     (if-not (contains? sym-meta ::analyzed)
+                           (resolve-existing-var env sym)
+                           (resolve-var env sym))]
+            (assoc ret :op :var :info info))
+          (let [info (resolve-var env sym)]
+            (assoc ret :op :var :info info)))))))

 (defn excluded?
   #?(:cljs {:tag boolean})


CoGroupedRDD signature change for 2.x

CoGroupedRDD signature change for 2.x

--- src/main/clojure/powderkeg/core.clj
+++ src/main/clojure/powderkeg/core.clj
@@ -400,8 +400,12 @@
   (let [rdd (ensure-scala-pair-rdd rdd)
         rdds (map ensure-scala-pair-rdd rdds)
         partitioner (org.apache.spark.Partitioner/defaultPartitioner
-                      rdd (scala-seq rdds))]
-    (by-key (org.apache.spark.rdd.CoGroupedRDD. ^scala.reflect.ClassTag (scala-seq (cons rdd rdds)) partitioner)
+                     rdd (scala-seq rdds))
+        evidence scala.reflect.ClassTag]
+    (by-key (org.apache.spark.rdd.CoGroupedRDD.
+             ^scala.reflect.ClassTag (scala-seq (cons rdd rdds))
+             partitioner
+             evidence)
       (map (fn [groups]
              (clj/into [] (map #(scala.collection.JavaConversions/asJavaList %)) groups))))))


CMR-3208 Fix build

CMR-3208 Fix build

--- umm-spec-lib/src/cmr/umm_spec/test/expected_conversion.clj
+++ umm-spec-lib/src/cmr/umm_spec/test/expected_conversion.clj
@@ -8,6 +8,8 @@
             [cmr.common.util :as util :refer [update-in-each]]
             [cmr.umm-spec.util :as su]
             [cmr.umm-spec.json-schema :as js]
+            ;; Required for loading service models for testing
+            [cmr.umm-spec.models.service]
             [cmr.umm-spec.test.expected-conversion-util :as conversion-util]
             [cmr.umm-spec.test.echo10-expected-conversion :as echo10]
             [cmr.umm-spec.test.dif9-expected-conversion :as dif9]


Updated fullscreen title to have better margin values

--- src/clj/redditv/styles.clj
+++ src/clj/redditv/styles.clj
@@ -225,6 +225,8 @@
     ;;:text-overflow "ellipsis"
     :padding-left (px 20)
     :padding-right (px 20)
+    :margin-left (px 10)
+    :margin-right (px 10)
     :font-size (px 20)
     :overflow "hidden"
     :text-align "center"


Renaming Write -> Record

Renaming Write -> Record

Three sections will be Record / Remember / Reflect

--- src/cljs/memento/core.cljs
+++ src/cljs/memento/core.cljs
@@ -269,7 +269,7 @@
              [navbar-item "Login" :login]
              [navbar-item "Sign up" :signup]]
             [:ul {:class "nav navbar-nav"}
-             [navbar-item "Write" :write]
+             [navbar-item "Record" :write]
              [navbar-item "Remember" :remember]])
           ]]
         ]]


Redirecting to record after signup (#37)

This has been broken for a while, only noticed after manual tests.

--- src/cljs/memento/core.cljs
+++ src/cljs/memento/core.cljs
@@ -14,7 +14,11 @@
             [markdown.transformers :as transformers]
             [pushy.core :as pushy]
             [ajax.core :refer [GET POST PUT DELETE]]
-            [clojure.string :as string])
+            [clojure.string :as string]
+            [taoensso.timbre :as timbre
+             :refer-macros [log trace debug info warn error fatal report
+                            logf tracef debugf infof warnf errorf fatalf reportf
+                            spy get-env]])
   (:require-macros [reagent.ratom :refer [reaction]]
                    [memento.misc.cljs-macros :refer [adapt-bootstrap]])
   (:import goog.History))
@@ -116,11 +120,13 @@

 (defn set-page! [match]
   (let [{:keys [handler route-params]} match]
+    (trace "Setting" match)
     (if (fn? handler)
       (handler route-params)
       (dispatch [:state-ui-section handler]))))

 (defn bidi-matcher [s]
+  (trace "Matching" s (bidi/match-route routes s))
   (bidi/match-route routes s))

 (def history
@@ -176,13 +182,13 @@
 (reg-event-db
   :auth-request
   (fn [app-state [_ signup?]]
-    (let [url       (if signup? "signup" "login")
-          ;; Should probalby centralize password validation, so we can use the same function
+    (let [url    (if signup? "signup" "login")
+          ;; Should probably centralize password validation, so we can use the same function
           ;; both here and when the UI is being updated
-          is-valid? (or (not signup?)
-                        (= (get-in app-state [:credentials :password])
-                           (get-in app-state [:credentials :password2])))]
-      (if is-valid?
+          valid? (or (not signup?)
+                     (= (get-in app-state [:credentials :password])
+                        (get-in app-state [:credentials :password2])))]
+      (if valid?
         (POST (str "/api/auth/" url) {:params        (:credentials app-state)
                                       :handler       #(dispatch [:auth-set-token (:token %)])
                                       :error-handler #(dispatch [:auth-request-error %])}))
@@ -196,9 +202,12 @@
     (if (not-empty token)
       (dispatch [:state-message ""]))
     (cookies/set! :token token)
-    (if (empty? token)
-      (set-page! "/login")
-      (set-page! (bidi-matcher (-> js/window .-location .-pathname))))
+    (trace "Got token" token app-state)
+    (trace "Current state" (bidi-matcher (-> js/window .-location .-pathname)))
+    (cond
+      (empty? token) (dispatch [:state-ui-section :login])
+      (= :signup (get-in app-state [:ui-state :section])) (dispatch [:state-ui-section :record])
+      :else (set-page! (bidi-matcher (-> js/window .-location .-pathname))))
     (-> app-state
         (assoc-in [:credentials :token] token)
         (assoc-in [:ui-state :wip-login?] false)
@@ -456,6 +465,7 @@
 (reg-event-db
   :state-ui-section
   (fn [app-state [_ section]]
+    (trace :state-ui-section section)
     (if (= :remember section)
       (dispatch [:memories-load]))
     ; Do not associate nil sections
@@ -762,8 +772,7 @@
         signup?   (reaction (= :signup @section))
         u-class   (reaction (if (and @signup? (empty? @username)) " has-error"))
         pw-class  (reaction (if (and @signup? (> 5 (count @password))) " has-error"))
-        pw2-class (reaction (if (not= @password @confirm) " has-error"))
-        ]
+        pw2-class (reaction (if (not= @password @confirm) " has-error"))]
     (fn []
       [:div {:class "modal"}
        [:div {:class "modal-dialog"}


Disable, don't hide, undo/redo buttons

Disable, don't hide, undo/redo buttons

--- src/cljs/pizarra/core.cljs
+++ src/cljs/pizarra/core.cljs
@@ -137,12 +137,13 @@
     om/IRender
     (render [_]
       (dom/div nil
-               (when (undo/undo-is-possible)
-                 (dom/button #js {:onClick (fn [_] (undo/do-undo app-state))}
-                             "Undo"))
-               (when (undo/redo-is-possible)
-                 (dom/button #js {:onClick (fn [_] (undo/do-redo app-state))}
-                             "Redo"))))))
+               (dom/button #js {:onClick (fn [_] (undo/do-undo app-state))
+                                :disabled (not (undo/undo-is-possible))}
+                           "Undo")
+
+               (dom/button #js {:onClick (fn [_] (undo/do-redo app-state))
+                                :disabled (not (undo/redo-is-possible))}
+                           "Redo")))))

 (undo/init-history app-state)


minor improvements

minor improvements

--- src/cljs/worktv/views.cljs
+++ src/cljs/worktv/views.cljs
@@ -122,9 +122,9 @@
         :else [:img {:src @urls :style {:max-width "400px" :max-height "400px"}}]))))

 (defn image-form [form]
-  (with-let [search-fn (u/throtled b/search-images 1000)]
+  (with-let [search-fn (u/throtled b/search-images 500)]
     [:div
-     [:form.form-horizontal
+     [:form
       [c/input {:type "text" :label "Title" :model [form :title]
                 :placeholder "Optional title" :wrapper-class "col-sm-10" :label-class "col-sm-2"}]
       [c/input {:type "text" :label "URL" :model [form :url] :placeholder "Image URL or search text"


Add unit-terrain-stats function

Add unit-terrain-stats function

--- src/cljs/zetawar/game.cljs
+++ src/cljs/zetawar/game.cljs
@@ -291,6 +291,19 @@

 (defn unit-ex [message unit]
   (ex-info message (select-keys unit [:unit/q :unit/r])))
+
+(defn unit-terrain-stats [db unit terrain]
+  (only (d/q '[:find ?mc ?at ?ar
+               :in $ ?u ?t
+               :where
+               [?u  :unit/type ?ut]
+               [?t  :terrain/type ?tt]
+               [?tt :terrain-type/effects ?e]
+               [?e  :terrain-effect/unit-type ?ut]
+               [?e  :terrain-effect/attack-bonus ?at]
+               [?e  :terrain-effect/armor-bonus ?ar]
+               [?e  :terrain-effect/movement-cost ?mc]]
+             db (e unit) (e terrain))))

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;; Unit States


Added repairable-friend-in-range-of-selected? track

--- src/cljs/zetawar/subs.cljs
+++ src/cljs/zetawar/subs.cljs
@@ -480,6 +480,11 @@
   (when-let [[selected-q selected-r] @(selected-hex conn)]
     @(in-range-of-friend-at? conn selected-q selected-r q r)))

+(deftrack repairable-friend-in-range-of-selected? [conn q r]
+  (when-let [[selected-q selected-r] @(selected-hex conn)]
+    (and @(in-range-of-friend-at? conn selected-q selected-r q r)
+         @(can-be-repaired? conn q r))))
+
 (deftrack selected-can-attack-targeted? [conn]
   (when-let [[q r] @(targeted-hex conn)]
     (and @(selected-can-attack? conn)


add emit code to special forms

add emit code to special forms

--- src/cljs_api_gen/parse.clj
+++ src/cljs_api_gen/parse.clj
@@ -495,6 +495,33 @@
     (let [[_quote doc-map] (nth form 2)]
       (transform-special-doc doc-map))))

+(defn special-parse->emit-op
+  "The names between the parse/emit methods are not always the same:
+   (defmethod parse 'op ...)
+   (defmethod emit* :op ...)"
+  [name]
+  (get '{"js*"   :js
+         "."     :dot
+         "var"   :var-special
+         "fn*"   :fn
+         "lefn*" :letfn
+         "loop*" :loop
+         "let*"  :let}
+    name
+    (keyword name))) ;; <-- default just converts to a keyword
+
+(defn parse-special-emit [form]
+  (when (and (list? form)
+             (= (take 2 form) '(defmethod emit*)))
+    (let [op (nth form 2)]
+      [op form])))
+
+(defn parse-special-emits
+  "Parse cljs special form emission code of the form:
+  (defmethod emit* :<op>)"
+  [forms]
+  (into {} (keep parse-special-emit forms)))
+
 (defn parse-special*
   "Parse cljs special forms of the form:
   (defmethod parse 'symbol ...)"
@@ -506,15 +533,21 @@
       {:name (str name-)})))

 (defn parse-special
-  [form doc-map]
+  [form doc-map emit-map]
   (when-let [special (parse-special* form)]
     (let [location (parse-location form)
           extras {:type "special form"}
           docs (get doc-map (symbol (:name special)))
+          emit (get emit-map (special-parse->emit-op (:name special)))
+          emit-src (when emit
+                     (-> (:source (parse-location emit))
+                         (assoc :title "Emitting code")))
           final (-> special
                     (merge location docs)
                     (assoc :type "special form")
-                    (assoc-in [:source :title] "Parser code"))]
+                    (assoc-in [:source :title] "Parser code"))
+          final (cond-> final
+                  emit-src (assoc :extra-sources [emit-src]))]
       final)))

 ;;--------------------------------------------------------------------------------
@@ -583,13 +616,15 @@
   (let [docs (->> (read-all-ns-forms "cljs.repl" :compiler)
                   (keep #(parse-special-docs %))
                   first)
+        emits (->> (read-all-ns-forms "cljs.compiler" :compiler)
+                   parse-special-emits)
         ns-with-specials (cond
                            (cljs-cmp >= "0.0-1424") "cljs.analyzer"
                            :else                    "cljs.compiler")
         specials (binding [*cur-ns* ns-
                            *cur-repo* "clojurescript"]
                    (->> (read-all-ns-forms ns-with-specials :compiler)
-                        (keep #(parse-special % docs))
+                        (keep #(parse-special % docs emits))
                         doall))]
     specials))


Whitespace fix

Whitespace fix

--- src/mdr2/abacus/import.clj
+++ src/mdr2/abacus/import.clj
@@ -37,6 +37,7 @@
    (map #(merge (prod/default-meta-data) %))))

 (defn import!
-  "Import all productions from file `f` and insert them in the data base"
+  "Import all productions from file `f` and insert them in the data
+  base"
   [f]
   (apply jdbc/insert! db :production (productions f)))


Convert speed to km/h

Convert speed to km/h

--- src/strava_activity_graphs/core.clj
+++ src/strava_activity_graphs/core.clj
@@ -11,7 +11,7 @@
        "https://www.strava.com/api/v3/activities"
        {:query-params
         {:access_token token
-         :per_page 200}})
+         :per_page     200}})
       :body)))

 (defn- to-millis [str-date]
@@ -30,6 +30,8 @@
     (set-alpha 0.8)
     view))

+(def m-per-h->km-per-h (partial * 3.6))
+
 (defn -main
   [& args]

@@ -38,42 +40,37 @@
     (println "Strava API token provided"))
   (let
     [token (first args)
-     activities (strava-json-activities token)
+     activities (->> (strava-json-activities token)
+                     (map #(update-in % ["average_speed"] m-per-h->km-per-h))
+                     (map #(update-in % ["start_date_local"] to-millis)))
      to-millis (fn [dates] (map #(to-millis %) dates))]

     (with-data
       (to-dataset activities)
       #_(view $data)
       (ts-plot
-        (to-millis ($ :start_date_local))
+        ($ :start_date_local)
         ($ :average_speed)
         :group-by ($ :type)
         :title "Average speed over time"
         :x-label "time"
-        :y-label "average speed (m/s)")
+        :y-label "average speed (km/h)")
       (ts-plot
-        (to-millis ($ :start_date_local))
-        ($ :average_speed)
-        :group-by ($ :type)
-        :title "Average speed over time"
-        :x-label "time"
-        :y-label "average speed (m/s)")
-      (ts-plot
-        (to-millis ($ :start_date_local))
+        ($ :start_date_local)
         ($ :kudos_count)
         :group-by ($ :type)
         :title "Activity kudos over time"
         :x-label "time"
         :y-label "kudos")
       (ts-plot
-        (to-millis ($ :start_date_local))
+        ($ :start_date_local)
         ($ :pr_count)
         :group-by ($ :type)
         :title "Personal records over time"
         :x-label "time"
         :y-label "personal records")
       (ts-plot
-        (to-millis ($ :start_date_local))
+        ($ :start_date_local)
         ($ :elapsed_time)
         :group-by ($ :type)
         :title "Activity duration over time"


Fix desktop signin text input field

Fix desktop signin text input field


Cosmetic changes on persistente namespace.

--- src/uxbox/persistence.clj
+++ src/uxbox/persistence.clj
@@ -2,6 +2,8 @@
   (:require [mount.core :as mount :refer (defstate)]
             [hikari-cp.core :as hikari]
             [uxbox.config :as cfg]))
+
+(def ^:dynamic *ctx*)

 (def ^:const +defaults+
   {:connection-timeout 30000
@@ -16,7 +18,7 @@
    :server-name "localhost"
    :port-number 5432})

-(defn create-datasource
+(defn- create-datasource
   []
   (let [dbconf (:database cfg/config)
         dbconf (merge +defaults+ dbconf)]


Don't clobber value of leave-open when it's 0. Allow both 0 and 1 for true and false in addition to true and false directly.

--- src/overtone/sc/buffer.clj
+++ src/overtone/sc/buffer.clj
@@ -156,7 +156,11 @@

     (snd "/b_write" (:id buf) path header samples
          n-frames start-frame
-         (if leave-open 1 0))
+         (if (or (= 0 leave-open)
+                 (false? leave-open)
+                 (nil? leave-open))
+           0
+           1))
     :done))

 (defmulti buffer-id type)


simplify

simplify

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

--- acqEngine/src/org/micromanager/acq_engine.clj
+++ acqEngine/src/org/micromanager/acq_engine.clj
@@ -180,7 +180,7 @@
                    (when (and x y) (core setXYPosition stage-dev x y))))

 (defn set-property
-  ([prop] (core setProperty (prop 0) (prop 1) (prop 2))))
+  ([prop] (apply* core setProperty prop)))

 (defn send-device-action [dev action]
   (send-off (device-agents dev) (fn [_] (action))))


make sure display settings get initialized

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

--- acqEngine/src/org/micromanager/acq_engine.clj
+++ acqEngine/src/org/micromanager/acq_engine.clj
@@ -440,7 +440,8 @@
                  :slices nil, :numFrames 0, :keep-shutter-open-channels false,
                  :zReference 0.0, :frames (), :save false}
             summary-metadata (make-summary-metadata summary)
-	          cache (MMImageCache. (TaggedImageStorageRam. summary-metadata))
+	          cache (doto (MMImageCache. (TaggedImageStorageRam. summary-metadata))
+	                  (.setSummaryMetadata summary-metadata))
 	          display (doto (VirtualAcquisitionDisplay. "" true false)
 	                        (.setCache cache) .initialize)]
 	          (reset! current-album {:cache cache :display display


Use :gen-class for yetibot.core.init

Use :gen-class for yetibot.core.init

--- src/yetibot/core/init.clj
+++ src/yetibot/core/init.clj
@@ -10,7 +10,8 @@
     [yetibot.core.logo :refer [logo]]
     [yetibot.core.adapters.campfire :as cf]
     [yetibot.core.adapters.irc :as irc]
-    [yetibot.core.adapters.slack :as slack]))
+    [yetibot.core.adapters.slack :as slack])
+  (:gen-class))

 (defn welcome-message []
   (println logo))


(maint) PR feedback - add CommonOptions for webrouting

Introduce a CommonOptions schema, use it for add-websocket-handler! and
add-ring-hander!

--- src/puppetlabs/trapperkeeper/services/webrouting/webrouting_service_core.clj
+++ src/puppetlabs/trapperkeeper/services/webrouting/webrouting_service_core.clj
@@ -20,6 +20,9 @@

 (def RouteOption
   {(schema/optional-key :route-id) schema/Keyword})
+
+(def CommonOptions
+  (dissoc (merge jetty9-core/CommonOptions RouteOption) :server-id))

 (def ContextHandlerOptions
   (dissoc (merge jetty9-core/ContextHandlerOptions RouteOption) :server-id))
@@ -110,7 +113,7 @@
 (schema/defn ^:always-validate add-ring-handler!
   [context webserver-service
    svc :- (schema/protocol tk-services/Service)
-   handler options :- RouteOption]
+   handler options :- CommonOptions]
   (let [{:keys [path opts]} (compute-common-elements context svc options)
         add-ring-handler    (:add-ring-handler webserver-service)]
     (add-ring-handler handler path opts)))
@@ -126,7 +129,7 @@
 (schema/defn ^:always-validate add-websocket-handler!
   [context webserver-service
    svc :- (schema/protocol tk-services/Service)
-   handlers options :- RouteOption]
+   handlers options :- CommonOptions]
   (let [{:keys [path opts]}   (compute-common-elements context svc options)
         add-websocket-handler (:add-websocket-handler webserver-service)]
     (add-websocket-handler handlers path opts)))


great arg spec

great arg spec

--- src/bluebell/utils/ebo.clj
+++ src/bluebell/utils/ebo.clj
@@ -345,8 +345,8 @@
                     (filter (complement pred) samples))))))))

 (defn arg-spec-samples [arg-spec]
-  (reduce into [(:pos arg-spec)
-                (:neg arg-spec)]))
+  (reduce into [] [(:pos arg-spec)
+                   (:neg arg-spec)]))

 (defn pred [pred-fn]
   "Easy construction of an arg-spec. This should only be used for very common values, because it just uses a default set of sample values"


Changed code so that the driver is only loaded for the first connection with the magic of memoization.

--- src/blutwurst/database.clj
+++ src/blutwurst/database.clj
@@ -6,17 +6,25 @@
   (:import (java.sql DriverManager JDBCType)
            (java.lang Class)))

-(def ^:private jdbc-drivers (-> "drivers.txt" io/resource slurp edn/read-string))
+(def ^:private
+     jdbc-drivers (-> "drivers.txt"
+                       io/resource
+                       slurp
+                       edn/read-string))

-(defn- find-class-for-spec [spec]
- (trace "Found spec: " spec)
- (trace "Driver list: " jdbc-drivers)
+(defn- find-class-for-spec [connection-string]
+     (trace "Looking up driver class for connection string " connection-string)
+     (trace "Driver list: " jdbc-drivers)

- (let [connection-string (:connection-string spec)
-       driver-entries (filter #(cstring/starts-with? connection-string (first %)) jdbc-drivers)]
-  (trace "Found drivers: " (pr-str (seq driver-entries)))
-  (:classname (second (first driver-entries)))
-  ))
+     (let [driver-entries (filter #(cstring/starts-with? connection-string (first %)) jdbc-drivers)]
+       (trace "Found drivers: " (pr-str (seq driver-entries)))
+       (:classname (second (first driver-entries)))
+      ))
+
+(defn- load-driver-for-connection-string-inner [connection-string]
+  (.newInstance (Class/forName (find-class-for-spec connection-string))))
+
+(def ^:private load-driver-for-connection-string (memoize load-driver-for-connection-string-inner))

 (defmacro with-jdbc-meta-data
  "Accepts a specification object and a function accepting a single argument (metadata).
@@ -25,10 +33,9 @@
  [spec fun]
  (let [connection-name (gensym)
        meta-data-name (gensym)
-       result-name (gensym)
-       d (gensym)]
+       result-name (gensym)]
    `(do
-       (.newInstance (Class/forName (find-class-for-spec ~spec)))
+       (load-driver-for-connection-string (:connection-string ~spec))

        (let [~connection-name (DriverManager/getConnection (:connection-string ~spec))
              ~meta-data-name (.getMetaData ~connection-name)


result adding a vector value to a vector found through a vector of keyword keys key - forgot to save

--- src/clj/ephemeris/core.clj
+++ src/clj/ephemeris/core.clj
@@ -71,7 +71,9 @@
 (defn- result [a k v]
   (do
     (if (vector? k)
-      (reset! a (assoc-in @a k (conj (get-in @a k) v)))
+      (reset! a (assoc-in @a k (if (vector? v)
+                                   (vec (flatten (conj (get-in @a k) v)))
+                                   (conj (get-in @a k) v))))
       (swap! a assoc k v))
     v))


Replace "FIRST BLK" with "100" to geocode.

--- src/clj/hbg_crime/core.clj
+++ src/clj/hbg_crime/core.clj
@@ -69,7 +69,7 @@
 (defn geocode-report
   [report]
   (let [res (first-zip-match (geo/geocode-address
-                              (str (:address report) ", Harrisburg, PA")))
+                              (str (str/replace (:address report) "FIRST BLK" "100") ", Harrisburg, PA")))
         loc (get-in res [:geometry :location])]
     (-> report
         (merge loc)


Refreshing thread properly on thought edit/delete

https://app.asana.com/0/17212341701456/161867801429592

--- src/cljs/memento/core.cljs
+++ src/cljs/memento/core.cljs
@@ -293,7 +293,7 @@
       (if (= :remember (get-in app-state [:ui-state :section])) ; Just in case we allow editing from elsewhere...
         (dispatch [:memories-load]))
       (if thread
-        (dispatch [:thread-load (:root-id (first thread))]))
+        (dispatch [:thread-load (:id (first thread))]))
       (-> app-state
           (assoc-in [:ui-state :is-busy?] false)
           (assoc-in [:note :edit-memory] nil)
@@ -313,7 +313,6 @@
   :memory-forget
   (fn [app-state [_ root-id]]
     (let [url (str "/api/memory/" root-id "/thought")]
-      (.log js/console url)
       (DELETE url {:headers       {:authorization (str "Token " (get-in app-state [:credentials :token]))}
                    :handler       #(dispatch [:memory-forget-success %])
                    :error-handler #(dispatch [:memory-forget-error %])}))
@@ -322,17 +321,22 @@
 (register-handler
   :memory-forget-success
   (fn [app-state [_ msg]]
-    (.log js/console (get-in app-state [:ui-state :section]))
-    (dispatch [:state-message (str "Thought forgotten") "alert-success"])
-    (if (= :remember (get-in app-state [:ui-state :section])) ; Just in case we allow editing from elsewhere...
-      (dispatch [:memories-load]))
-    (-> app-state
-        (assoc-in [:ui-state :is-busy?] false)
-        (assoc-in [:note :edit-memory] nil)
-        (assoc-in [:note :edit-note] "")
-        (assoc-in [:note :focus] nil)
-        (assoc :search-state nil)
-        )))
+    (let [thread     (get-in app-state [:note :thread])
+          in-thread? (and thread
+                          (get-in app-state [:ui-state :show-thread?]))]
+      (dispatch [:state-message (str "Thought forgotten") "alert-success"])
+      (if (= :remember (get-in app-state [:ui-state :section])) ; Just in case we allow editing from elsewhere...
+        (dispatch [:memories-load]))
+      (if in-thread?
+        (dispatch [:thread-load (:id (first thread))]))
+      (-> app-state
+          (assoc-in [:ui-state :is-busy?] false)
+          (assoc-in [:note :edit-memory] nil)
+          (assoc-in [:note :edit-note] "")
+          (assoc-in [:note :focus] nil)
+          (assoc :search-state nil)
+          )))
+  )

 (register-handler
   :memory-forget-error
@@ -460,7 +464,6 @@
 (register-handler
   :state-show-thread
   (fn [app-state [_ show?]]
-    (if (not show?) (dispatch [:state-browser-token :remember]))
     (assoc-in app-state [:ui-state :show-thread?] show?)))


load plugin data to local storage on startup

--- src/cljs/swarmpit/app.cljs
+++ src/cljs/swarmpit/app.cljs
@@ -1,7 +1,9 @@
 (ns swarmpit.app
   (:require [swarmpit.router :as router]
             [swarmpit.component.layout :as layout]
-            [swarmpit.component.message :as message]))
+            [swarmpit.component.message :as message]
+            [swarmpit.component.network.create :as network]
+            [swarmpit.component.volume.create :as volume]))

 ;; Starting router

@@ -13,4 +15,9 @@

 ;; Mounting message

-(message/mount!)+(message/mount!)
+
+;; Fetch plugins data
+
+(network/network-plugin-handler)
+(volume/volume-plugin-handler)


fetch and store localstorage

fetch and store localstorage

--- src/cljs/unfolds/core.cljs
+++ src/cljs/unfolds/core.cljs
@@ -15,8 +15,26 @@
             [secretary.core :as secretary])
   (:import goog.History))

-;; Link format: [[foo|blitz]]
-
+;; From http://adambard.com/blog/a-simple-clojurescript-app/
+
+(defn keywordify [m]
+  (cond
+   (map? m) (into {} (for [[k v] m] [(keyword k) (keywordify v)]))
+   (coll? m) (vec (map keywordify m))
+   :else m))
+
+(defn fetch [k default]
+  (let [item (.getItem js/localStorage k)]
+    (if  (and item (not= item "null")) ;; "null" is true, fuck you js.
+      (-> (.getItem js/localStorage k)
+          (or (js-obj))
+          (js/JSON.parse)
+          (js->clj)
+          (keywordify))
+      default)))
+
+(defn store [k obj]
+  (.setItem js/localStorage k (js/JSON.stringify (clj->js obj))))

 (def base-url (atom ""))

@@ -42,7 +60,21 @@
                    (secretary/dispatch! (.-token event))))
   (.setEnabled history true))

-(defonce app-state (atom {:search ""
+(def default-init-state
+  {:search ""
+   :word-map {}
+   :visible [] ;; XXX: Bad name, visible items.
+   :hidden {:view false
+            :add true
+            :search true
+            :menu false}
+   :current-item 0
+   :items []})
+
+(defonce app-state
+  (atom (fetch "unfolds" default-init-state)))
+
+#_(defonce app-state (atom {:search ""
                           :word-map {"Ogden" [0]
                                      "Foo" [1]} ;; populate this, oh
                           :visible [] ;; XXX: Bad name, visible items.
@@ -232,6 +264,8 @@
           (if value (method app value) (method app)))))))

 (defn app-view [app owner]
+  ;; Can this be here?
+  (store "unfolds" app) ;; too much?
   (reify
     om/IInitState
     (init-state [_]
@@ -244,7 +278,7 @@
     (render-state [this {:keys [chan] :as state}]
       (dom/div nil
                ;; TODO: Make these into four separate components
-
+
                ;; Menu bar
                (dom/div #js {:style (hidden (-> app :hidden :menu))}
                         (dom/p nil (dom/h1 nil "Unfolds")


Added compatible-armor-types-for-repair? and related functions

--- src/cljs/zetawar/subs.cljs
+++ src/cljs/zetawar/subs.cljs
@@ -249,6 +249,7 @@
                                     :unit-type/description
                                     :unit-type/can-capture
                                     :unit-type/can-repair
+                                    :unit-type/armor-type
                                     :unit-type/min-range
                                     :unit-type/max-range
                                     :unit-type/image]}]
@@ -422,6 +423,14 @@
                       :app/targeted-r])
       not-empty))

+(deftrack selected-and-targeted-hex [conn]
+  (-> @(app conn)
+      (select-values [:app/selected-q
+                      :app/selected-r
+                      :app/targeted-q
+                      :app/targeted-r])
+      not-empty))
+
 (deftrack selected-unit [conn]
   (when-let [[q r] @(selected-hex conn)]
     @(unit-at conn q r)))
@@ -445,6 +454,11 @@
 (deftrack selected-can-repair-other? [conn]
   (when-let [[q r] @(selected-hex conn)]
     @(can-repair-other? conn q r)))
+
+(deftrack compatible-armor-types-for-repair? [conn]
+  (when-let [[selected-q selected-r targeted-q targeted-r] @(selected-and-targeted-hex conn)]
+    (game/compatible-armor-types-for-repair? @conn @(game conn) @(unit-at conn selected-q selected-r)
+                                                                @(unit-at conn targeted-q targeted-r))))

 (deftrack selected-can-capture? [conn]
   (when-let [[q r] @(selected-hex conn)]
@@ -494,7 +508,8 @@
   (when-let [[targeted-q targeted-r] @(targeted-hex conn)]
     (and @(selected-can-repair-other? conn)
          @(friend-in-range-of-selected? conn targeted-q targeted-r)
-         @(can-be-repaired? conn targeted-q targeted-r))))
+         @(can-be-repaired? conn targeted-q targeted-r)
+         @(compatible-armor-types-for-repair? conn))))

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;; Unit picker


fix bug introduced 5 minutes ago with reporting

--- src/clojure/fudje/core.clj
+++ src/clojure/fudje/core.clj
@@ -17,15 +17,12 @@
          [expected# supplied#] (if (fudje.util/poly-checker? probably-supplied#)
                                  [probably-supplied# probably-expected#]
                                  [probably-expected# probably-supplied#]) ;; make sure we got the order right
-         clean-form# (list '~'compatible expected# supplied#)
          [only-expected# only-value# both#] (data/diff expected# supplied#)
          failure# (boolean (cond-> only-expected#
                                    (coll? only-expected#) seq))]
      (if only-expected#
-       (test/do-report {:type :fail, :message ~msg :expected clean-form#, :actual (list
-                                                                               '~'found only-value#
-                                                                               '~'instead-of only-expected#)})
-       (test/do-report {:type :pass, :message ~msg :expected clean-form#, :actual both#}))
+       (test/do-report {:type :fail, :message ~msg :expected expected#, :actual supplied#})
+       (test/do-report {:type :pass, :message ~msg :expected expected#, :actual both#}))
      (not failure#)))

 ;================================================================================================================


fix amp analytics

fix amp analytics

--- src/clojure/nossal/web.clj
+++ src/clojure/nossal/web.clj
@@ -65,7 +65,7 @@
      (concat
        [{:async true :charset "utf-8" :src "https://cdn.ampproject.org/v0.js"}]
        (if (= "true" (env :production))
-         {:async true :custom-element "amp-analytics" :charset "utf-8" :src "https://cdn.ampproject.org/v0/amp-analytics-0.1.js"})
+         [{:async true :custom-element "amp-analytics" :charset "utf-8" :src "https://cdn.ampproject.org/v0/amp-analytics-0.1.js"}])
        scripts)
      (concat
        [{:attr {:amp-boilerplate true} :content (slurp (io/resource "amp-css.css"))}]


Implemented the simulate function.

Implemented the simulate function.

--- src/clojure_robby/core.clj
+++ src/clojure_robby/core.clj
@@ -11,6 +11,9 @@
 (def simul-steps 100) ; Steps to allow the robot to make in a simulation.
 (def tiles [\w \p \g]) ; Tiles that populate the map: wall, path, and gold.
 (def actions [\u \d \l \r \p]) ; Actions the robot can take: up, down, left, right, pick up.
+(def dir-vects ['(1 0) '(-1 0) '(-1 0) '(0 1) '(0 0)]) ; Direction vectors, corresponding to the actions.
+(def action-penalty 5) ; How many points robot loses when hitting the wall or picking up when it shouldn't.
+(def gold-value 10) ; How many points picking up gold is worth.

 ; DNA functions
@@ -35,14 +38,51 @@
     (if (or (= x 0) (= y 0) (= x last-coord) (= y last-coord))
       \w
       (if (< (rand-int 100) gold-prob) \g \p)))
-  (map (fn [y] (map (fn [x] (gen-tile x y)) (range map-size))) (range map-size)))
+  (def map-coords (vec (range map-size)))
+  (mapv (fn [y] (mapv (fn [x] (gen-tile x y)) map-coords)) map-coords))

-(defn on-index [themap x y]
+(defn get-tile [the-map pos]
   "Given a map and coordinates, evaluates to what is on the map at the position."
-  (nth (nth themap y) x))
+  (let [[x y] (vec pos)]
+    (nth (nth the-map y) x)))

-;(defn simulate [dna onmap]
- ; "Simulates the DNA on a map. Evaluates to the score the robot achieved in simul-steps."
+(defn set-tile [the-map pos tile]
+  "Returns a copy of the map where the tile on pos has been replaced."
+  (let [[x y] (vec pos)]
+    (def new-row (assoc (nth the-map y) x tile))
+    (assoc the-map y new-row)))
+
+(defn get-tile-index [t]
+  "Returns the numeric index of a tile."
+  (+ 1 (.indexOf tiles t)))
+
+(defn add-vec [v1 v2]
+  "Adds 2 vectors"
+  (map + v1 v2))
+
+(defn simulate [dna the-map]
+  "Simulates the DNA on a map. Evaluates to the score the robot achieved in simul-steps."
+  (defn make-step [[current-map pos score]]
+    "Makes a single step on the map, according to the DNA sequence."
+    (defn nearby-tiles-idx []
+      "Returns the tile indices of nearby tiles in a vector."
+      (def nearby-tiles (map (fn[v] (get-tile the-map (add-vec pos v))) dir-vects))
+      (map get-tile-index nearby-tiles))
+    (def action (nth dna (- (reduce * (nearby-tiles-idx)) 1)))
+    (case action
+      (\l \r \u \d)
+      (do
+        (def new-pos (add-vec pos (nth dir-vects (get-tile-index action))))
+        (if (not= \w (get-tile current-map new-pos))
+          [current-map new-pos score]
+          [current-map pos (- score action-penalty)]))
+      \p
+      (do
+        (if (= \g (get-tile current-map pos))
+          [(set-tile current-map pos \p) pos (+ score gold-value)]
+          [current-map pos (- score action-penalty)]))))
+  (def final-state (nth (iterate make-step [the-map '(1 1) 0]) simul-steps))
+  (nth final-state 2))

 (defn -main


More minor optimizations.

More minor optimizations.

--- src/clojure_robby/core.clj
+++ src/clojure_robby/core.clj
@@ -11,6 +11,8 @@
 (def simul-steps 100) ; Steps to allow the robot to make in a simulation.
 (def tiles [\w \p \g]) ; Tiles that populate the map: wall, path, and gold.
 (def actions [\u \d \l \r \x \p]) ; Actions the robot can take: up, down, left, right, pick up.
+
+(def multipliers (map (fn [n] (** (count tiles) n)) (range (count actions)))) ; Used to calculate genes to use.
 (def dir-vects ['(0 -1) '(0 1) '(-1 0) '(1 0) '(0 0)]) ; Direction vectors, corresponding to the 4 actions.

 (def mutation-prob 5) ; Probability in 100 that a gene will mutate.
@@ -74,12 +76,11 @@

 (defn simulate [dna the-map]
   "Simulates the DNA on a map. Evaluates to the score the robot achieved in simul-steps."
-  (let [multipliers (map (fn [n] (** (count tiles) n)) (range (count actions)))
-        make-step
+  (let [make-step
         (fn [[current-map pos score]]
           "Makes a single step on the map, according to the DNA sequence."
-          (let [situation (map (fn[v] (get-tile current-map (add-vec pos v))) dir-vects)
-                action-idx (reduce + (map * (map get-tile-index situation) multipliers))
+          (let [situation (map (fn[v] (get-tile-index (get-tile current-map (add-vec pos v)))) dir-vects)
+                action-idx (reduce + (map * situation multipliers))
                 action (nth dna action-idx)
                 step-to
                   (fn [the-pos]
@@ -98,7 +99,8 @@
               (if (= \g (get-tile current-map pos))
                 [(set-tile current-map pos \p) pos (+ score gold-value)]
                 [current-map pos (- score action-penalty)]))))
-        [_ final-pos final-score] (nth (iterate make-step [the-map '(1 1) 0]) simul-steps)]
+        iteration (iterate make-step [the-map '(1 1) 0])
+        [_ final-pos final-score] (nth iteration simul-steps)]
     final-score))


Fixed arg metadata.

Fixed arg metadata.

--- src/cmr/opendap/config.clj
+++ src/cmr/opendap/config.clj
@@ -59,14 +59,14 @@
         :else [service]))

 (defn service->base-url
-  [^Keyword service]
+  [service]
   (format "%s://%s:%s"
           (or (:protocol service) "https")
           (:host service)
           (or (:port service) "443")))

 (defn service->url
-  [^Keyword service]
+  [service]
   (format "%s%s"
           (service->base-url service)
           (or (get-in service [:relative :root :url])
@@ -74,7 +74,7 @@
               "/")))

 (defn service->base-public-url
-  [^Keyword service]
+  [service]
   (let [protocol (or (get-in service [:public :protocol]) "https")
         host (get-in service [:public :host])]
     (if (= "https" protocol)
@@ -82,7 +82,7 @@
       (format "%s://%s:%s" protocol host (get-in service [:public :port])))))

 (defn service->public-url
-  [^Keyword service]
+  [service]
   (format "%s%s"
           (service->base-public-url service)
           (or (get-in service [:relative :root :url])


analysing heart rate percentiles

analysing heart rate percentiles

--- misc-inrepl-analysis/etenema.clj
+++ misc-inrepl-analysis/etenema.clj
@@ -9,6 +9,14 @@
 (def pasi_p (get-profile "SannaK"))
 (def pasiex (with-collection "exercise" (find {:user "SannaK" :sport "Juoksu"}) (sort {:creationDate 1}) (batch-size 5000)))

+(def maratonit (with-collection "exercise" (find {"$and" [{:sport "Juoksu"} {:avghr {"$gte" 100}} {:distance {"$gte" 42000}} {:distance {"$lte" 42200}}]}) (sort {:creationDate 1}) (batch-size 5000)))
+
+(def kympit (with-collection "exercise" (find {"$and" [{:sport "Juoksu"} {:avghr {"$gte" 100}} {:distance 10000} ]}) (sort {:creationDate 1}) (batch-size 5000)))
+
+
+(defn get-res[ex]
+  (let [profile (get-profile (:user ex))]
+    (get-hres-percentage ex profile)))

 (defn get-bpmdist-raw2 [exercise profile]
   (let [{:keys [duration distance avghr]} exercise


Added support for active scene in scene ns

  - This was donw to simplify scene commands for the active scene

--- src/retro_fever/scene.cljs
+++ src/retro_fever/scene.cljs
@@ -3,6 +3,25 @@
   (:require [clojure.walk :as walk]
             [retro-fever.sprite :as sprite]
             [retro-fever.util :as util]))
+
+(def active-scene (atom {:game-state nil :scene-lens nil}))
+
+(defn set-active!
+  ([game-state]
+   (set-active! game-state nil))
+  ([game-state scene-lens]
+   (swap! active-scene assoc :game-state game-state
+          :scene-lens (if (or (nil? scene-lens) (vector? scene-lens))
+                        scene-lens (vector scene-lens)))))
+
+(defn get-active []
+  @active-scene)
+
+(defn update-scene! [fn]
+  (let [{:keys [game-state scene-lens]} @active-scene]
+    (if (vector? scene-lens)
+      (swap! game-state update-in scene-lens fn)
+      (swap! game-state fn))))

 (defprotocol INode
   (add-child-id [this id])
@@ -28,14 +47,17 @@
   (remove-child-id [this id]
     (update-in this [:children] disj id)))

+(defn create-id []
+  (keyword (gensym "se-")))
+
 (defrecord Scene []
   IScene
   (add [this element]
-    (add this (keyword (gensym "se-")) element))
+    (add this (create-id) element))
   (add [this id element]
     (add-to this :se-root id element))
   (add-to [this destination-id element]
-    (add-to this destination-id (keyword (gensym "se-")) element))
+    (add-to this destination-id (create-id) element))
   (add-to [this destination-id id element]
     (-> this
         (assoc id (with-meta element {:se-id id :parent destination-id}))
@@ -62,6 +84,24 @@
   (get-elements-at [this node-id]
     (get-elements this (get-children-ids (get-element this node-id)))))

+(defn add!
+  ([element]
+   (update-scene! #(add % element)))
+  ([id element]
+     (update-scene! #(add % id element))))
+
+(defn add-to!
+  ([destination-id element]
+   (update-scene! #(add-to % destination-id element)))
+  ([destination-id id element]
+   (update-scene! #(add-to % destination-id id element))))
+
+(defn remove! [id]
+  (update-scene! #(remove % id)))
+
+(defn move-to! [id destination-id]
+  (update-scene! #(move-to % id destination-id)))
+
 (defn get-id [element]
   (:se-id (meta element)))

@@ -77,7 +117,7 @@
   ([order update-fn]
    (assoc (group update-fn) :order order)))

-(defn scene []
+(defn new []
   (assoc (Scene.) :se-root (with-meta (group)  {:se-id :se-root})))

 (derive sprite/StaticImage ::sprite)


Add shutdown function to close a sesame repository safely.

--- src/grafter/rdf/sesame.clj
+++ src/grafter/rdf/sesame.clj
@@ -426,3 +426,7 @@
                  ?s ?p ?o .
                }
             }"))))
+
+(defn shutdown [repo]
+  "Cleanly shutsdown the repository."
+  (.shutDown repo))


wip: complete-value

wip: complete-value

--- src/graphql_clj/parser.clj
+++ src/graphql_clj/parser.clj
@@ -99,13 +99,17 @@
 (defn get-selection-object-name
   [selection]
   {:post [(not (nil? %))]}
-  (println selection)
-  (:name (second (second selection))))
+  (println "get-selection-object-name: " selection)
+  (let [name (:name (second (second selection)))]
+    (println "get-selection-object-name: name: " name)
+    name))

 (defn get-selection-name
   [selection]
   (println "get-selection-name: " selection)
-  (:name (second (second selection))))
+  (let [name (:name (second (second selection)))]
+    (println "get-selection-name: name: " name)
+    name))

 (defn get-selection-type [selection]
   (first (second selection)))
@@ -122,11 +126,39 @@
   [object-type selection-set visited-fragments]
   (reduce collect-selection [] selection-set))

+(comment ; Type kind
+  :SCALAR
+  :OBJECT
+  :INTERFACE
+  :UNION
+  :ENUM
+  :INPUT_OBJECT
+  :LIST
+  :NOT_NULL)
+
+(def type-map
+  {:UserType {:name "User"
+              :kind :OBJECT
+              :fields {:id {:type :GraphQLString}
+                       :name {:type :GraphQLString}}
+              :args {}
+              :resolve-fn (fn [object] {:id "test"})}})
+
+(def schema
+  {:query {:name "Query"
+           :kind :OBJECT
+           :fields {:user {:type :UserType}}
+           :args {:id :GraphQLString}}})
+
 (defn type-system-lookup
   [object-type object-name]
   (case object-type
     :root (case object-name
-            "user" {:type "user"
+            "user" {:name "User"
+                    :kind :OBJECT
+                    :fields {:id {:type :GraphQLString}
+                             :name {:type :GraphQLString}}
+                    :args {}
                     :resolve-fn (fn [object] {:id "test"})}
             (throw (ex-info (format "Unknown object name: %s." object-name) {})))
     (throw (ex-info (format "Unknown object type: %s." object-type) {}))))
@@ -134,9 +166,11 @@
 (defn get-field-type-from-object-type
   "FIXME"
   [object-type field-selection]
+  (println (format "get-field-type-from-object-type: object-type: %s, field-selection: %s." object-type field-selection))
   (let [object-name (get-selection-object-name field-selection)
-        type-info (type-system-lookup object-type object-name)]
-    (:type type-info)))
+        _ (println "object-name: " object-name)
+        type-meta (type-system-lookup object-type object-name)]
+    type-meta))

 (defn resolve-field-on-object
   "FIXME"
@@ -147,23 +181,62 @@
     (resolve-fn object)))

 (defn merge-selection-sets
-  [fields]
-  (reduce (fn [col field]
-            (println "field: " field)
-            (let [field-selection-set (:selection-set field)]
-              (if field-selection-set
-                (conj col field-selection-set))))
-          [] fields))
+  [selections]
+  (let [sets (reduce (fn [col selection]
+                       (println "merge-selection-sets: selection: " selection)
+                       (let [field (second (second selection))
+                             field-selection-set (:selection-set field)]
+                         (if field-selection-set
+                           (into col field-selection-set)
+                           col)))
+                     [] selections)]
+    (println "merge-selection-sets: sets: " sets)
+    sets))
+
+(defn is-enum-field-type?
+  [field-type-meta]
+  (= :ENUM (:kind field-type-meta)))
+
+(defn is-scalar-field-type?
+  [field-type-meta]
+  (= :SCALAR (:kind field-type-meta)))
+
+(defn is-object-field-type?
+  [field-type-meta]
+  (= :OBJECT (:kind field-type-meta)))
+
+(defn is-interface-field-type?
+  [field-type-meta]
+  (= :INTERFACE (:kind field-type-meta)))
+
+(defn is-union-field-type?
+  [field-type-meta]
+  (= :UNION (:kind field-type-meta)))

 (defn complete-value
-  [field-type resolved-object sub-selection-set]
-  (println "complete-value"))
+  [field-type result sub-selection-set]
+  (println "complete-value: ")
+  (println "field-type: " field-type)
+  (println "result: " result)
+  (println "sub-selection-set: " sub-selection-set)
+  ;;; TODO
+  ;; (if (and (not nullable?)
+  ;;          (nil? resolved-object))
+  ;;   (throw ""))
+  ;; FIXME
+  (if result
+    (cond
+      (is-scalar-field-type? field-type) result
+      (is-enum-field-type? field-type) result
+      (is-object-field-type? field-type) (evaluate-selection-set field-type result sub-selection-set nil))))

 (defn get-field-entry [object-type object fields]
+  (println "get-field-entry: " fields)
   (let [first-field-selection (first fields)
         response-key (get-selection-name first-field-selection)
         field-type (get-field-type-from-object-type object-type first-field-selection)
         field-entry first-field-selection]
+    (println "field-type" field-type)
     (if (not (nil? field-type))
       (let [resolved-object (resolve-field-on-object object-type object field-entry)]
         (if (nil? resolved-object)


api documentation

api documentation

--- src/io/aviso/rook/core.clj
+++ src/io/aviso/rook/core.clj
@@ -262,11 +262,17 @@
                :rook (merge (or (:rook request) {})
                       {:default-arg-resolvers (concat (:default-arg-resolvers (:rook request))  arg-resolvers)})))))

-(defn- get-compiled-paths-uncached [namespace]
+(defn get-available-paths [namespace]
   (->> (ns-paths namespace)
        (map (fn [[[request-method path] function-key]]
               (when-let [fun (ns-function namespace function-key)]
-                [[request-method (clout/route-compile path)] fun])))
+                [[request-method path] fun])))
+       (remove nil?)))
+
+(defn- get-compiled-paths-uncached [namespace]
+  (->> (get-available-paths namespace)
+       (map (fn [[[request-method path] fun]]
+              [[request-method (clout/route-compile path)] fun]))
        (remove nil?)))

 (def get-compiled-paths (memo/memo get-compiled-paths-uncached))


Adds stateful-fn, useful for testing fns that throw

--- test/circle/test_utils.clj
+++ test/circle/test_utils.clj
@@ -12,6 +12,7 @@
   (:require [circle.backend.ec2 :as ec2])
   (:require [circle.backend.ssh :as ssh])
   (:require [circle.sh :as sh])
+  (:use [circle.util.except :only (throwf)])
   (:use [midje.sweet])
   (:import java.io.StringReader))

@@ -286,3 +287,27 @@
                                 ;;(redis/with-redis ) this isn't enough, we need to switch redis and resque at the same time.
                                 (mongo/with-mongo (test-db-connection)
                                   ?form)))))
+
+(defn stateful-fn*
+  "Takes a seq of no argument fns. Returns a new fn that calls each fn in turn."
+  [fns]
+  (let [state (atom fns)]
+    (fn []
+      (if (not (zero? (count @state)))
+        (let [f (first @state)]
+          (try
+            (apply f [])
+            (finally
+             (swap! state rest))))
+        (throwf "no more values")))))
+
+(defmacro thunk-args
+  "Takes a seq of unevaluated exprs. Returns a seq of no argument fns, that call each of the exprs in turn"
+  [exprs]
+  (into [] (map (fn [v]
+                  `(fn []
+                     ~v)) exprs)))
+
+(defmacro stateful-fn
+  [& args]
+  `(stateful-fn* (thunk-args ~args)))


Here it is. Here's the bug.

Here it is. Here's the bug.

--- src/divergence/entity.cljs
+++ src/divergence/entity.cljs
@@ -197,7 +197,7 @@
   (entity [(c/named :bg)
            (c/entity-type :bg)
            (c/sprite [texture])
-           ;(c/tiling-sprite texture)
+           (c/tiling-sprite texture)
            (c/on-stage stage)
            c/has-actions
            (c/unique c/player-input)


#54: add threeten dependency requirement API comment

--- src/java_time/interval.clj
+++ src/java_time/interval.clj
@@ -61,7 +61,9 @@
     => #<Interval 1970-01-01T00:01:40Z/1970-01-01T00:16:40Z>

     (j/interval (j/instant 100000) (j/duration 15 :minutes))
-    => #<Interval 1970-01-01T00:01:40Z/1970-01-01T00:16:40Z>"
+    => #<Interval 1970-01-01T00:01:40Z/1970-01-01T00:16:40Z>
+
+    Requires the optional `threeten-extra` dependency."
     ([^String o] (Interval/parse o))
     ([a b]
      (cond (and (jt.t/instant? a) (jt.t/instant? b))


unused requires

unused requires

--- src/java_time/interval.clj
+++ src/java_time/interval.clj
@@ -1,7 +1,6 @@
 (ns java-time.interval
   (:refer-clojure :exclude [contains?])
-  (:require [clojure.string :as string]
-            [java-time.util :as jt.u]
+  (:require [java-time.util :as jt.u]
             [java-time.core :as jt.c]
             [java-time.temporal :as jt.t]
             [java-time.amount :as jt.a])


Fix a monad test; as monad state must be a map since some time.

--- test/active/clojure/monad_test.cljc
+++ test/active/clojure/monad_test.cljc
@@ -272,10 +272,10 @@
                                                    (return [x y]))))))

 (deftest frse-state
-  (is (= ['foo 'bar]
-         (run-free-reader-state-exception (null-monad-command-config 'nil 'foo)
+  (is (= [{:x 'foo} {:x 'bar}]
+         (run-free-reader-state-exception (null-monad-command-config 'nil {:x 'foo})
                                           (monadic [x (get-state)]
-                                                   (put-state! 'bar)
+                                                   (put-state! {:x 'bar})
                                                    (return x))))))

 (deftest null-config


Added more tests into utils-test module

Added more tests into utils-test module

--- test/emender_jenkins/utils_test.clj
+++ test/emender_jenkins/utils_test.clj
@@ -177,6 +177,33 @@
     (testing "the function emender-jenkins.utils/third."
         (are [x y] (= x y)
             nil (third nil))))
+
+(deftest test-fourth-1
+    "Check the function emender-jenkins/fourth."
+    (testing "the function emender-jenkins/fourth."
+        (are [x y] (= x y)
+            4 (fourth [1 2 3 4 5])
+            4 (fourth '(1 2 3 4))
+            4 (fourth '(1 2 3 4 5)))))
+
+(deftest test-fourth-2
+    "Check the function emender-jenkins/fourth."
+    (testing "the function emender-jenkins/fourth."
+        (are [x y] (= x y)
+            nil (fourth [])
+            nil (fourth '())
+            nil (fourth [1])
+            nil (fourth '(1))
+            nil (fourth [1 2])
+            nil (fourth '(1 2))
+            nil (fourth [1 2 3])
+            nil (fourth '(1 2 3)))))
+
+(deftest test-fourth-not-NPE
+    "Check the function emender-jenkins/fourth."
+    (testing "the function emender-jenkins/fourth."
+        (are [x y] (= x y)
+            nil (fourth nil))))

 (deftest test-substring-1
     "Check the function emender-jenkins.utils/substring."


Fix lost imports.

Fix lost imports.

--- src/konserve/filestore.clj
+++ src/konserve/filestore.clj
@@ -9,7 +9,10 @@
             [clojure.string :as str]
             [konserve.protocols :refer [PEDNAsyncKeyValueStore -exists? -get-in -update-in
                                         PBinaryAsyncKeyValueStore -bget -bassoc
-                                        -serialize -deserialize]]))
+                                        -serialize -deserialize]])
+  (:import [java.io
+            DataInputStream DataOutputStream
+            FileInputStream FileOutputStream]))

 ;; TODO safe filename encoding
 (defn dumb-encode [s]


Add the first entry iterator.

Add the first entry iterator.

--- src/lab_notebook/core.cljs
+++ src/lab_notebook/core.cljs
@@ -11,8 +11,11 @@
       (apply dom/div nil
         (dom/h1 nil "Lab notebook")
         nil
-        (for [x (range 10)]
-          (str x " "))))))
+        (for [entry (:entries cursor)]
+          (dom/div nil
+            (dom/div nil (:summary entry))
+            (dom/div nil (:date-time entry))
+            (dom/div nil (:notes entry))))))))

 (om/root app-container appstate
   {:target (. js/document (getElementById "app"))})


Add first Om render.

Add first Om render.

--- src/lab_notebook/core.cljs
+++ src/lab_notebook/core.cljs
@@ -1,3 +1,15 @@
-(ns lab-notebook.core)
+(ns lab-notebook.core
+  (:require [om.core :as om]
+            [om.dom :as dom]))

 (defonce appstate (atom {}))
+
+(defn app-container [cursor component]
+  (reify
+    om/IRender
+    (render [this]
+      (dom/div nil "Hello!"))))
+
+(om/root app-container appstate
+  {:target (. js/document (getElementById "app"))})
+


namespace based pathing

namespace based pathing

--- test/selmer/benchmark.clj
+++ test/selmer/benchmark.clj
@@ -13,13 +13,13 @@
 (deftest ^:benchmark bench-for-typical []
   (println "BENCH: bench-for-typical")
   (criterium/quick-bench
-   (render-file "test/templates/nested-for.html"
+   (render-file "templates/nested-for.html"
                 nested-for-context)))

 (deftest ^:benchmark bench-for-huge []
   (println "BENCH: bench-for-huge")
   (criterium/quick-bench
-   (render-file "test/templates/nested-for.html"
+   (render-file "templates/nested-for.html"
                 big-for-context)))

 (deftest ^:benchmark bench-assoc-in []


Should be returning the result of the function, not the function itself

--- src/lister/persistence.clj
+++ src/lister/persistence.clj
@@ -60,7 +60,7 @@
 (defn create-creds
   []
   (if (= (master-account-id) (:account-id (im/instance-identity)))
-    create-standard-credentials
+    (create-standard-credentials)
     ((mem/ttl create-assumed-credentials :ttl/threshold (* 30 60 1000)))))

 (defn upsert-application


Fix non-debug connection bug

Fix non-debug connection bug

--- src/neovim_client/nvim.clj
+++ src/neovim_client/nvim.clj
@@ -129,7 +129,7 @@

 (defn new
   "Connect to msgpack-rpc channel via standard io or TCP socket."
-  ([] (new* System/in System/out) false)
+  ([] (new* System/in System/out false))
   ([host port]
    (log/info "plugin host connecting to nvim at " host ":" port)
    (let [socket (java.net.Socket. host port)]


Fixed sample player bug.

Fixed sample player bug.

--- src/overtone/sc/sample.clj
+++ src/overtone/sc/sample.clj
@@ -53,7 +53,6 @@

 (defn- load-all-samples []
   (doseq [[[path args] buf] @loaded-samples*]
-    ;(println "loading sample: " path args)
     (apply load-sample* path args)))

 (on-event :connected :sample-loader load-all-samples)
@@ -76,9 +75,11 @@
   "
   [path & args]
   (let [s          (load-sample path)
-        player     (fn [& pargs] (node "mono-player"
-                                       (:id (get @loaded-samples* [path args]))
-                                        pargs))]
+        player     (fn [& pargs]
+                     (let [id (:id (get @loaded-samples* [path args]))]
+                       (if (empty? pargs)
+                         (mono-player id)
+                         (apply mono-player id pargs))))]
     (callable-map (merge {:player player} s)
                   player)))


fixed minor bug

fixed minor bug

--- src/pe_core_utils/core.clj
+++ src/pe_core_utils/core.clj
@@ -99,4 +99,4 @@
 (defn ->jsonkeys
   "Replaces all the keyword-based keys in m with JSON string keys."
   [m]
-  (replace-keys (keys m) m keyword->jsonkey))
+  (replace-keys m (keys m) keyword->jsonkey))


Actually add fancy new hotness

Actually add fancy new hotness

--- test/icecap/e2e/common.clj
+++ test/icecap/e2e/common.clj
@@ -3,7 +3,9 @@
   (:require [icecap.core :as core]
             [clojure.test :refer :all]
             [aleph.http :as http]
-            [taoensso.timbre :refer [info spy]]))
+            [taoensso.timbre :refer [info spy]]
+            [byte-streams :as bs]
+            [clojure.tools.reader.edn :as edn]))

 (def icecap-server)

@@ -38,3 +40,10 @@
   [cap-url]
   (info "Revoking cap" cap-url)
   (http/delete cap-url {:throw-exceptions false}))
+
+(defn get-body
+  "Given a request, extracts its body."
+  [req]
+  (-> (:body req)
+      (bs/to-string)
+      (edn/read-string)))