session id modal no longer dismissable on backdrop click

--- src/prais2/main.cljs
+++ src/prais2/main.cljs
@@ -67,7 +67,7 @@
                    (data/table1 core/app data event-bus)
                    (data/option-menu event-bus)])]))

-(defn close-start-modal []
+(defn close-start-modal [event]
   (prn "closing")
   (let [new-session-id (.val ($ "#session-id"))]
     (when new-session-id
@@ -111,7 +111,7 @@
 (def bs-open-popover
   {:did-mount (fn [state]
                 (if (nil? @logger/session-id)
-                  (ready (.modal ($ "#start-modal") (clj->js {:show true}))))
+                  (ready (.modal ($ "#start-modal") (clj->js {:show true :backdrop :static}))))
                 state)})
 ;;;
 ;; pager


Update client app to use sorts instead of items

--- src/scavenger/client/main.cljs
+++ src/scavenger/client/main.cljs
@@ -33,55 +33,55 @@
 ; Reader for state
 (defmulti read om/dispatch)

-(defmethod read :items
+(defmethod read :sorts
   [{:keys [state query]} key params]
   {:value (d/q '[:find [(pull ?e [*]) ...]
-                 :where [?e :item/name]]
+                 :where [?e :sort/name]]
                (d/db state) query)})

 ; Mutator for state
 (defmulti mutate om/dispatch)

-; Add a single item
+; Add a single sort
 ; Persists to the backend API first, before adding the complete
-; item from the API response to the locale state cache.
+; sort from the API response to the locale state cache.
 ; TODO: Add to local state cache immediately, updating with response
 ; data and reverting local transaction if persisting fails
-(defmethod mutate 'items/add
+(defmethod mutate 'sorts/add
   [{:keys [state]} _ entity]
-  {:value {:keys [:items]}
+  {:value {:keys [:sorts]}
    :action (fn []
              (edn-xhr {:method "POST"
-                       :path "/items"
+                       :path "/sorts"
                        :data entity
                        :on-complete
                        (fn [data]
                          (d/transact! state [data]))}))})

-; Scavenger items list
-(defui ItemsList
+; Scavenger sorts list
+(defui SortsList
   Object
   (render [this]
-    (let [items (om/props this)]
+    (let [sorts (om/props this)]
       (apply dom/ul nil
         (map
-          (fn [item]
-            (dom/li nil (:item/name item)))
-          items)))))
+          (fn [sort]
+            (dom/li nil (:sort/name sort)))
+          sorts)))))

-(def items-list (om/factory ItemsList))
+(def sorts-list (om/factory SortsList))

 (def google-map (js/React.createFactory js/GoogleMapReact))

-; Keep state property for name text in AddItem component instance up to date
+; Keep state property for name text in AddSort component instance up to date
 (defn update-state [component event]
   (om/update-state! component assoc
     :name-text (.. event -target -value)))

-(defui AddItem
+(defui AddSort
   static om/IQuery
   (query [this]
-    [:items])
+    [:sorts])
   Object
   (render [this]
     (dom/div nil
@@ -92,26 +92,23 @@
              (fn [e]
                (let [value (om/get-state this :name-text)]
                  (om/transact! this
-                    `[(items/add {:item/name ~value})])))}
-        "Add item!"))))
+                    `[(sorts/add {:sort/name ~value})])))}
+        "Add sort!"))))

-(def add-item (om/factory AddItem))
+(def add-sort (om/factory AddSort))

 ; Main application component
 (defui App
   static om/IQuery
   (query [this]
-    [:items])
+    [:sorts])
   Object
   (render [this]
-    (let [{:keys [items]} (om/props this)]
+    (let [{:keys [sorts]} (om/props this)]
       (dom/div nil
-        (dom/h1 nil "Scavenger items")
-        (items-list items)
-        (add-item)
-        (dom/div (clj->js {:style {:width "500px" :height "500px"}})
-          (google-map (clj->js {:center {:lat 59.974289 :lng 10.728749}
-                                :zoom 13})))))))
+        (dom/h1 nil "Scavenger sorts")
+        (sorts-list sorts)
+        (add-sort)

 (def app (om/factory App))

@@ -121,9 +118,9 @@
     {:state conn
      :parser (om/parser {:read read :mutate mutate})}))

-; Load all items from API
+; Load all sorts from API
 (edn-xhr {:method "GET"
-          :path "/items"
+          :path "/sorts"
           :on-complete (fn [data]
                          (d/transact! conn data))})


Move time-left definition to please the compiler.

--- src/tetris/core.cljs
+++ src/tetris/core.cljs
@@ -208,6 +208,12 @@
   []
   (.getTime (js/Date.)))

+(defn time-left
+  "Given a timestamp and a time interval, returns a remaining interval
+   since then."
+  [ts interval]
+  (max 0 (- interval (- (current-timestamp) ts))))
+
 (defn process-time
   "Adds current :now timestamp in milliseconds to a given state map."
   [state]
@@ -316,12 +322,6 @@
                        :debug {:fps max-fps
                                :frames-counter 0
                                :last-fps-update (current-timestamp)}}))
-
-(defn time-left
-  "Given a timestamp and a time interval, returns a remaining interval
-   since then."
-  [ts interval]
-  (max 0 (- interval (- (current-timestamp) ts))))

 (add-watch game-state
            :time-flow


add extra check for map-values in msg-persist

--- kafka-clj/src/kafka_clj/msg_persist.clj
+++ kafka-clj/src/kafka_clj/msg_persist.clj
@@ -26,8 +26,10 @@

 (defn map-values [^Map m]
   (when m
-    (let [^Collection vals' (.values m)]
-      (_map-values-seq (.iterator vals')))))
+    (try
+      (let [^Collection vals' (.values m)]
+        (_map-values-seq (.iterator vals')))
+      (catch Exception _ '()))))

 (defn- format-val [m-vals]
   "Fix bug in DBMap that all keys return null when used as keywords"


add module entry key for package.json

add module entry key for package.json

increasingly packages only provide module and no main or browser.

--- src/main/shadow/build/npm.clj
+++ src/main/shadow/build/npm.clj
@@ -848,7 +848,7 @@
      :js-options {:extensions [#_".mjs" ".js" ".json"]
                   :target :browser
                   :use-browser-overrides true
-                  :entry-keys [#_#_"module" "jsnext:main" "browser" "main"]}
+                  :entry-keys ["browser" "main" "module"]}
      }))

 (defn stop [npm])


comment async code

comment async code

--- src/thinking/async.cljc
+++ src/thinking/async.cljc
@@ -22,10 +22,11 @@
   [channel topic]
   (unsub-all channel topic))

-(defn notify [channel]
-  (go-loop []
-    (println channel ": " (<! channel))
-    (recur)))
+(comment
+  (defn notify [channel]
+    (go-loop []
+      (println channel ": " (<! channel))
+      (recur))))

 (defn publish [topic data]
   (go (>! publisher (assoc {:topic topic} data))))


Fix the test.

Fix the test.

--- test/circle/backend/build/test_run_build.clj
+++ test/circle/backend/build/test_run_build.clj
@@ -12,7 +12,8 @@
   (:require [somnium.congomongo :as mongo])
   (:require [circle.backend.ec2 :as ec2])
   (:use [circle.util.predicates :only (ref?)])
-  (:use [circle.util.retry :only (wait-for)]))
+  (:use [circle.util.retry :only (wait-for)])
+  (:require [clj-time.core :as time]))

 (test-ns-setup)

@@ -98,6 +99,7 @@
     (-> @build :instance-id (ec2/instance) :state :name) => "running"
     (-> @build :instance-ids (first)) => string?
     (nodes/cleanup-nodes build) => anything
-    (wait-for {:sleep 1000 :tries 60}
+    (wait-for {:sleep (time/secs 1)
+               :timeout (time/secs 60)}
               #(not= (-> @build :instance-ids (first) (ec2/instance) :state :name) "running")) => anything
     (-> @build :instance-ids (first) (ec2/instance) :state :name) =not=> "running"))


fix for file input

fix for file input

--- src/cljs/re_form/widgets/file_upload_impl.cljs
+++ src/cljs/re_form/widgets/file_upload_impl.cljs
@@ -34,10 +34,10 @@
            [:input {:style {:display "none"}
                     :ref #(swap! state assoc :input-ref %)
                     :type "file"
-                    :on-change #(my-onchange % upload-fn on-change) :value nil}]
+                    :on-change #(my-onchange % upload-fn on-change)}]

            (if uploading?
-             (str "Uploading " #_(str/join ", " (map #(.-name %) (array-seq files))) "...")
+             (str "Uploading " (str/join ", " (map #(.-name %) (array-seq files))) "...")
              (if value
                [:pre (.stringify js/JSON (clj->js (:value @state)))]
                [:a {:href "javascript:void(0);" :on-click open-file-dialog} "Select file to upload..."]))]))})))


Fix the test to not depend on the current process's env

--- test/circle/workers/test_github.clj
+++ test/circle/workers/test_github.clj
@@ -20,4 +20,5 @@

 (fact "authorization-url works"
   (-> "http://localhost:3000/hooks/repos" authorization-url) =>
-  "https://github.com/login/oauth/authorize?client_id=586bf699b48f69a09d8c&scope=repo&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fhooks%2Frepos")+  "https://github.com/login/oauth/authorize?client_id=586bf699b48f69a09d8c&scope=repo&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fhooks%2Frepos"
+  (provided (circle.env/env) => :test))


perpetual running consumer and dispatch action for creating snapshot

--- src/wb_es/bulk/core.clj
+++ src/wb_es/bulk/core.clj
@@ -311,18 +311,30 @@
       (go
        (loop []
          (debug "Stats" (scheduler-stats))
-         (if-let [job-ref (scheduler-take! 60000 nil)]
+         (if-let [job-ref (scheduler-take!)]
            ;; normal batches won't be nil
            ;; only get nil when no more jobs are added to the queue for a period of time
            (do
              (try
-               (let [job (deref job-ref)]
+               (let [job (deref job-ref)
+                     job-meta (meta job)]
                  (try
-                   (run-index-batch db release-id job)
+                   (debug "Starting" (:action job-meta))
+                   (case (:action job-meta)
+                     "snapshot" (let [index-id (:index job-meta)
+                                      repository-name (:repository job-meta)
+                                      snapshot-id (get-next-snapshot-id repository-name release-id)]
+                                  (save-snapshot index-id repository-name snapshot-id)
+                                  (debug "Snapshot created" job-meta))
+                     (do
+                       (run-index-batch db release-id job)
+                       (debug "Indexed" job-meta)))
+
                    (scheduler-complete! job-ref)
-                   (debug "Indexed" (or (meta job) :no_metadata))
+
                    (catch Exception e
-                     (warn "Failed to index and scheduled to retry" (or (meta job) :no_metadata))
+                     (error e)
+                     (warn "Failed and scheduled to retry" job-meta)
                      (scheduler-retry! job-ref) ; retried items are added at the end of the queue
                      )))
                (catch java.io.IOException e
@@ -330,11 +342,6 @@
                  (scheduler-complete! job-ref)))
              (recur))

-           (if (= (:in-progress (scheduler-stats))
-                  0)
-             (do
-               (info "Done!" (scheduler-stats))
-               (mount/stop)))
            ))))

     )
@@ -357,9 +364,11 @@
       (let [db (d/db datomic-conn)]
         (do
           (run db)
-          (schedule-jobs-all db)))
-      (connect-snapshot-repository repository-name)
-      (let [snapshot-id (get-next-snapshot-id repository-name release-id)]
-        (save-snapshot index-id repository-name snapshot-id))
+          (schedule-jobs-all db)
+          (connect-snapshot-repository repository-name)
+          (scheduler-put! (with-meta {} {:action "snapshot"
+                                         :index index-id
+                                         :repository repository-name}))))
+
       ))
   )


Refactored large method

Refactored large method

--- src/video_server/discovery.clj
+++ src/video_server/discovery.clj
@@ -12,23 +12,39 @@
   (:require [clojure.tools.logging :as log])
   (:import (java.net DatagramPacket DatagramSocket InetAddress)))

-(defn- listen-for-clients
+(defn receive-request
+  "Blocks waiting for a client to broadcast a discovery message."
+  [socket]
+  (let [buffer (byte-array 15000)
+        packet (DatagramPacket. buffer (count buffer))]
+    (.receive socket packet)
+    (log/trace "received request from" (.getAddress packet))
+    packet))
+
+(defn request-message
+  "Returns the message from the request packet."
+  [packet]
+  (-> (.getData packet) (String.) .trim))
+
+(defn send-response
+  "Sends the response back to the requester."
+  [socket request url hostname]
+  (let [response (str url "|" hostname)
+        data (.getBytes response)
+        packet (DatagramPacket. data (count data) (.getAddress request) (.getPort request))]
+    (log/trace "sending" response)
+    (.send socket packet)))
+
+(defn listen-for-clients
   "Listens for client requests and responds with information to
   identify this server."
   [url port hostname]
-  (let [socket (doto (DatagramSocket. port) (.setBroadcast true))
-        buffer (byte-array 15000)]
+  (let [socket (doto (DatagramSocket. port) (.setBroadcast true))]
     (while true
-      (try (let [packet (DatagramPacket. buffer (count buffer))]
-             (.receive socket packet)
-             (let [message (-> (.getData packet) (String.) .trim)]
-               (log/trace "received message" message "from" (.getAddress packet))
-               (when (= message "DISCOVER_VIDEO_SERVER_REQUEST")
-                 (let [response (str url "|" hostname)
-                       data (.getBytes response)
-                       send-packet (DatagramPacket. data (count data) (.getAddress packet) (.getPort packet))]
-                   (log/trace "sending" response)
-                   (.send socket send-packet)))))
+      (try (let [request (receive-request socket)
+                 message (request-message request)]
+             (when (= message "DISCOVER_VIDEO_SERVER_REQUEST")
+               (send-response socket request url hostname)))
            (catch Exception e (log/error e))))))

 (defn start-discovery


adds a 404 route for unknown API calls

adds a 404 route for unknown API calls

--- src/nevergreen/api/routes.clj
+++ src/nevergreen/api/routes.clj
@@ -36,7 +36,9 @@

              (GET "/ping" [] {:status 204})

-             (GET "/version" [] {:headers {"Content-Type" "text/plain"} :body (version)})))
+             (GET "/version" [] {:headers {"Content-Type" "text/plain"} :body (version)})
+
+             (GET "*" [] {:status 404})))

 (defn wrap-api-middleware [routes]
   (-> routes


remove more thread sleeps

remove more thread sleeps

--- test/clj/lambdacd/internal/execution_test.clj
+++ test/clj/lambdacd/internal/execution_test.clj
@@ -316,7 +316,7 @@
           pipeline `((some-control-flow-thats-called some-step-that-fails-if-retriggered some-step-to-retrigger) some-successful-step)
           context (some-ctx-with :initial-pipeline-state initial-state)]
       (retrigger pipeline context 0 [2 1] 1)
-      (Thread/sleep 200)
+      (wait-for (step-success? context 1 [2]))
       (is (= {0 {[1] { :status :success }
                  [1 1] {:status :success :out "I am nested"}
                  [2 1] {:status :unknown :out "this will be retriggered"}}


rewrite present-tense rule

rewrite present-tense rule

--- src/babel/italiano/morphology/verbs.cljc
+++ src/babel/italiano/morphology/verbs.cljc
@@ -319,200 +319,83 @@
    ])

 (def replace-patterns-present-tense
-  [
-   {:p [#"^([^' ]+)o$"         "$1are"]
-    :u {:synsem {:subcat {:1 {:agr {:number :sing
-                                    :person :1st}}}
-                 :infl :present}}}
-   {:p [#"^([^' ]+)o$"         "$1ere"]
-    :u {:synsem {:subcat {:1 {:agr {:number :sing
-                                    :person :1st}}}
-                 :infl :present}}}
-   {:p [#"^([^' ]+)isco$"      "$1ire"]
-    :u {:synsem {:subcat {:1 {:agr {:number :sing
-                                    :person :1st}}}
-                 :infl :present}}}
-   {:p [#"^([^' ]+)o$"         "$1ire"]
-    :u {:synsem {:subcat {:1 {:agr {:number :sing
-                                    :person :1st}}}
-                 :infl :present}}}
-   {:p [#"^([^' ]+)o$"         "$1arsi"] ;; alzo -> alzarsi
-    :u {:synsem {:subcat {:1 {:agr {:number :sing
-                                    :person :1st}}}
-                 :infl :present}}}
-   {:p [#"^([^' ]+)o$"         "$1irsi"] ;; diverto -> divertirso
-    :u {:synsem {:subcat {:1 {:agr {:number :sing
-                                    :person :1st}}}
-                 :infl :present}}}
-   {:p [#"^([^' ]+)ico$"       "$1ire"] ;; dico -> dire
-    :u {:synsem {:subcat {:1 {:agr {:number :sing
-                                    :person :1st}}}
-                 :infl :present}}}
-   ;; 2nd sing
-   {:p [#"^([^' ]+)i$"         "$1are"] ;; lavi -> lavare
-    :u {:synsem {:subcat {:1 {:agr {:number :sing
-                                    :person :2nd}}}
-                 :infl :present}}}
-   {:p [#"^([^' ]+)i$"         "$1iare"] ;; studi -> studiare
-    :u {:synsem {:subcat {:1 {:agr {:number :sing
-                                    :person :2nd}}}
-                 :infl :present}}}
-   {:p [#"^([^' ]+)i$"         "$1arsi"] ;; lavi -> lavarsi
-    :u {:synsem {:subcat {:1 {:agr {:number :sing
-                                    :person :2nd}}}
-                 :infl :present}}}
-   {:p [#"^([^' ]+)cci$"       "$1cciare"] ;; abbracci -> abbracciare
-    :u {:synsem {:subcat {:1 {:agr {:number :sing
-                                    :person :2nd}}}
-                 :infl :present}}}
-   {:p [#"^([^' ]+)i$"         "$1ere"]
-    :u {:synsem {:subcat {:1 {:agr {:number :sing
-                                    :person :2nd}}}
-                 :infl :present}}}
-   {:p [#"^([^' ]+)i$"         "$1ire"] ;; senti -> sentire
-    :u {:synsem {:subcat {:1 {:agr {:number :sing
-                                    :person :2nd}}}
-                 :infl :present}}}
-   {:p [#"^([^' ]+c)hi$"       "$1are"] ;; cerchi -> cercare
-    :u {:synsem {:subcat {:1 {:agr {:number :sing
-                                    :person :2nd}}}
-                 :infl :present}}}
-
-   {:p [#"^([^' ]+)i$"         "$1iarsi"] ;; arrabi -> arrabiarsi
-    :u {:synsem {:subcat {:1 {:agr {:number :sing
-                                    :person :2nd}}}
-                 :infl :present}}}
-   {:p [#"^([^' ]+)sci$"       "$1re"] ;; finisci -> finire
-    :u {:synsem {:subcat {:1 {:agr {:number :sing
-                                    :person :2nd}}}
-                 :infl :present}}}
-   {:p [#"^([^' ]+)i$"         "$1irsi"] ;; diverti -> divertirsi
-    :u {:synsem {:subcat {:1 {:agr {:number :sing
-                                    :person :2nd}}}
-                 :infl :present}}}
-   {:p [#"^([^' ]+)ici$"       "$1ire"] ;; dici -> dire
-    :u {:synsem {:subcat {:1 {:agr {:number :sing
-                                    :person :2nd}}}
-                 :infl :present}}}
-   {:p [#"^([^' ]+)hi$"        "$1are"] ;; pieghi -> piegare
-    :u {:synsem {:subcat {:1 {:agr {:number :sing
-                                    :person :2nd}}}
-                 :infl :present}}}
-
-   {:p [#"^([^' ]+)a$"         "$1are"]
-    :u {:synsem {:subcat {:1 {:agr {:number :sing
-                                    :person :3rd}}}
-                 :infl :present}}}
-   {:p [#"^([^' ]+)e$"         "$1ere"]
-    :u {:synsem {:subcat {:1 {:agr {:number :sing
-                                    :person :3rd}}}
-                 :infl :present}}}
-   {:p [#"^([^' ]+)e$"         "$1ire"]
-    :u {:synsem {:subcat {:1 {:agr {:number :sing
-                                    :person :3rd}}}
-                 :infl :present}}}
-   {:p [#"^([^' ]+)a$"         "$1arsi"] ;; prepara -> preperarsi
-    :u {:synsem {:subcat {:1 {:agr {:number :sing
-                                    :person :3rd}}}
-                 :infl :present}}}
-   {:p [#"^([^' ]+)sce$"       "$1re"] ;; finisce -> finire
-    :u {:synsem {:subcat {:1 {:agr {:number :sing
-                                    :person :3rd}}}
-                 :infl :present}}}
-   {:p [#"^([^' ]+)te$"        "$1tirsi"] ;; diverte -> divertirsi
-    :u {:synsem {:subcat {:1 {:agr {:number :sing
-                                    :person :3rd}}}
-                 :infl :present}}}
-   {:p [#"^([^' ]+)ice$"      "$1ire"] ;; dice -> dire
-    :u {:synsem {:subcat {:1 {:agr {:number :sing
-                                    :person :3rd}}}
-                 :infl :present}}}
-
-   {:p [#"^([^' ]+)iamo$"      "$1are"]  ;; parliamo -> parlare
-    :u {:synsem {:subcat {:1 {:agr {:number :plur
-                                    :person :1st}}}
-                 :infl :present}}}
-
-   {:p [#"^([^' ]+)iamo$"      "$1iare"] ;; mangiamo -> mangiare
-    :u {:synsem {:subcat {:1 {:agr {:number :plur
-                                    :person :1st}}}
-                 :infl :present}}}
-   {:p [#"^([^' ]+)iamo$"      "$1ere"]
-    :u {:synsem {:subcat {:1 {:agr {:number :plur
-                                    :person :1st}}}
-                 :infl :present}}}
-   {:p [#"^([^' ]+)iamo$"      "$1ire"]
-    :u {:synsem {:subcat {:1 {:agr {:number :plur
-                                    :person :1st}}}
-                 :infl :present}}}
-   {:p [#"^([^' ]+c)hiamo$"    "$1are"] ;; sprechiamo -> sprecare
-    :u {:synsem {:subcat {:1 {:agr {:number :plur
-                                    :person :1st}}}
-                 :infl :present}}}
-   {:p [#"^([^' ]+)iamo$"      "$1iarsi"] ;; arrabiamo -> arrabiarsi
-    :u {:synsem {:subcat {:1 {:agr {:number :plur
-                                    :person :1st}}}
-                 :infl :present}}}
-   {:p [#"^([^' ]+)iamo$"      "$1arsi"] ;; chiamiamo -> chiamarsi
-    :u {:synsem {:subcat {:1 {:agr {:number :plur
-                                    :person :1st}}}
-                 :infl :present}}}
-   {:p [#"^([^' ]+)iamo$"      "$1irsi"] ;; divertiamo -> divertirsi
-    :u {:synsem {:subcat {:1 {:agr {:number :plur
-                                    :person :1st}}}
-                 :infl :present}}}
-   {:p [#"^([^' ]+)ciamo$"     "$1re"] ;; diciamo -> dire
-    :u {:synsem {:subcat {:1 {:agr {:number :plur
-                                    :person :1st}}}
-                 :infl :present}}}
-   {:p [#"^([^' ]+)hiamo$"     "$1are"] ;; pieghiamo -> piegare
-    :u {:synsem {:subcat {:1 {:agr {:number :plur
-                                    :person :1st}}}
-                 :infl :present}}}
-   ;; 2nd plur
-   {:p [#"^([^' ]+)([aei])te$" "$1$2re"] ;; parlate -> parlare; leggere -> leggere
-    :u {:synsem {:subcat {:1 {:agr {:number :plur
-                                    :person :2nd}}}
-                 :infl :present}}}
-   {:p [#"^([^' ]+)([aei])te$" "$1$2rsi"] ;; chiamate -> chiamarsi
-    :u {:synsem {:subcat {:1 {:agr {:number :plur
-                                    :person :2nd}}}
-                 :infl :present}}}
-
-   {:p [#"^([^' ]+)ano$"       "$1are"]
-    :u {:synsem {:subcat {:1 {:agr {:number :plur
-                                    :person :3rd}}}
-                 :infl :present}}}
-   {:p [#"^([^' ]+)ono$"       "$1ere"]
-    :u {:synsem {:subcat {:1 {:agr {:number :plur
-                                    :person :3rd}}}
-                 :infl :present}}}
-   {:p [#"^([^' ]+)ono$"       "$1ire"]
-    :u {:synsem {:subcat {:1 {:agr {:number :plur
-                                    :person :3rd}}}
-                 :infl :present}}}
-
-   {:p [#"^([^' ]+)ano$"       "$1arsi"] ;; alzano -> alzarsi
-    :u {:synsem {:subcat {:1 {:agr {:number :plur
-                                    :person :3rd}}}
-                 :infl :present}}}
-   {:p [#"^([^' ]+)scono$"     "$1re"] ;; finiscono -> finire
-    :u {:synsem {:subcat {:1 {:agr {:number :plur
-                                    :person :3rd}}}
-                 :infl :present}}}
-   {:p [#"^([^' ]+)ono$"       "$1irsi"] ;; divertono -> divertirsi
-    :u {:synsem {:subcat {:1 {:agr {:number :plur
-                                    :person :1st}}}
-                 :infl :present}}}
-   {:p [#"^([^' ]+)cono$"      "$1re"] ;; dicono -> dire
-    :u {:synsem {:subcat {:1 {:agr {:number :plur
-                                    :person :3rd}}}
-                 :infl :present}}}
-   {:p [#"^([^' ]+)ono$"       "$1irsi"] ;; vestono -> vestirsi
-    :u {:synsem {:subcat {:1 {:agr {:number :plur
-                                    :person :3rd}}}
-                 :infl :present}}}
-   ])
+  (expand-replace-patterns
+   {:synsem {:infl :present}}
+   [{:agr {:synsem {:subcat {:1 {:agr {:number :sing
+                                       :person :1st}}}}}
+     :p [
+         #"^([^' ]+)o$"         "$1are"
+         #"^([^' ]+)o$"         "$1ere"
+         #"^([^' ]+)isco$"      "$1ire"
+         #"^([^' ]+)o$"         "$1ire"
+         #"^([^' ]+)o$"         "$1arsi" ;; alzo -> alzarsi
+         #"^([^' ]+)o$"         "$1irsi" ;; diverto -> divertirso
+         #"^([^' ]+)ico$"       "$1ire" ;; dico -> dire
+         ]}
+    {:agr {:synsem {:subcat {:1 {:agr {:number :sing
+                                       :person :2nd}}}}}
+     :p [
+         #"^([^' ]+)i$"         "$1are" ;; lavi -> lavare
+         #"^([^' ]+)i$"         "$1iare" ;; studi -> studiare
+         #"^([^' ]+)i$"         "$1arsi" ;; lavi -> lavarsi
+         #"^([^' ]+)cci$"       "$1cciare" ;; abbracci -> abbracciare
+         #"^([^' ]+)i$"         "$1ere"
+         #"^([^' ]+)i$"         "$1ire" ;; senti -> sentire
+         #"^([^' ]+c)hi$"       "$1are" ;; cerchi -> cercare
+         #"^([^' ]+)i$"         "$1iarsi" ;; arrabi -> arrabiarsi
+         #"^([^' ]+)sci$"       "$1re" ;; finisci -> finire
+         #"^([^' ]+)i$"         "$1irsi" ;; diverti -> divertirsi
+         #"^([^' ]+)ici$"       "$1ire" ;; dici -> dire
+         #"^([^' ]+)hi$"        "$1are" ;; pieghi -> piegare
+         ]}
+
+    {:agr {:synsem {:subcat {:1 {:agr {:number :sing
+                                       :person :3rd}}}}}
+
+     :p [
+         #"^([^' ]+)a$"         "$1are"
+         #"^([^' ]+)e$"         "$1ere"
+         #"^([^' ]+)e$"         "$1ire"
+         #"^([^' ]+)a$"         "$1arsi" ;; prepara -> preperarsi
+         #"^([^' ]+)sce$"       "$1re" ;; finisce -> finire
+         #"^([^' ]+)te$"        "$1tirsi" ;; diverte -> divertirsi
+         #"^([^' ]+)ice$"       "$1ire" ;; dice -> dire
+         ]}
+
+    {:agr {:synsem {:subcat {:1 {:agr {:number :plur
+                                       :person :1st}}}}}
+     :p [
+         #"^([^' ]+)iamo$"      "$1are"  ;; parliamo -> parlare
+         #"^([^' ]+)iamo$"      "$1iare" ;; mangiamo -> mangiare
+         #"^([^' ]+)iamo$"      "$1ere"
+         #"^([^' ]+)iamo$"      "$1ire"
+         #"^([^' ]+c)hiamo$"    "$1are" ;; sprechiamo -> sprecare
+         #"^([^' ]+)iamo$"      "$1iarsi" ;; arrabiamo -> arrabiarsi
+         #"^([^' ]+)iamo$"      "$1arsi" ;; chiamiamo -> chiamarsi
+         #"^([^' ]+)iamo$"      "$1irsi" ;; divertiamo -> divertirsi
+         #"^([^' ]+)ciamo$"     "$1re" ;; diciamo -> dire
+         #"^([^' ]+)hiamo$"     "$1are" ;; pieghiamo -> piegare
+         ]}
+
+    {:agr {:synsem {:subcat {:1 {:agr {:number :plur
+                                       :person :2nd}}}}}
+     :p [
+         #"^([^' ]+)([aei])te$" "$1$2re" ;; parlate -> parlare
+         #"^([^' ]+)([aei])te$" "$1$2rsi" ;; chiamate -> chiamarsi
+         ]}
+
+    {:agr {:synsem {:subcat {:1 {:agr {:number :plur
+                                       :person :3rd}}}}}
+     :p [
+         #"^([^' ]+)ano$"       "$1are"
+         #"^([^' ]+)ono$"       "$1ere"
+         #"^([^' ]+)ono$"       "$1ire"
+         #"^([^' ]+)ano$"       "$1arsi" ;; alzano -> alzarsi
+         #"^([^' ]+)scono$"     "$1re" ;; finiscono -> finire
+         #"^([^' ]+)ono$"       "$1irsi" ;; divertono -> divertirsi
+         #"^([^' ]+)cono$"      "$1re" ;; dicono -> dire
+         #"^([^' ]+)ono$"       "$1irsi" ;; vestono -> vestirsi
+         ]}]))

 (def replace-patterns
   (map (fn [each]   ;; unify with {:synsem {:cat :verb}} for all rules.


println the results of a test DRPC execution

--- test/marceline/topology/wordcount_metrics.clj
+++ test/marceline/topology/wordcount_metrics.clj
@@ -102,7 +102,7 @@
                        spout
                        local-drpc)))
     (Thread/sleep 10000)
-    (.execute local-drpc "words" "cat dog the man jumped")
+    (println "DRPC query: " (.execute local-drpc "words" "cat dog the man jumped"))
     (.shutdown cluster)
     (System/exit 0)))


Nomalization: allow single task; allow array for traits

--- src/cider_ci/builder/jobs/normalizer.clj
+++ src/cider_ci/builder/jobs/normalizer.clj
@@ -12,6 +12,9 @@
     ))

+(defn seqable? [x]
+  (instance? clojure.lang.Seqable x))
+
 (defn- normalize-to-key-name-map [d]
   (cond (map? d)
         (->> d
@@ -22,8 +25,7 @@
                            (assoc :key (or (:key v) k))
                            (assoc :name (or (:name v) k)))]))
              (into {}))
-
-        (instance?  clojure.lang.Seqable d)
+        (seqable? d)
         (->> d
              (map-indexed (fn [i v] [(or (:key v) (:name v) (str i)) v]))
              (into {}))
@@ -34,22 +36,43 @@

 ;### Debug ####################################################################

-(defn- normalize-body-tasks-to-script-tasks [tasks-map]
-  (->> tasks-map
-       (map (fn [[k v]]
-              [k (cond (:scripts v) v
-                       (:body v) (-> v
-                                     (assoc :scripts {:main {:body (:body v)}})
-                                     (dissoc :body))
-                       :else  v)]))
+(defn- normalize-string-value-to-body-map [v]
+  (if (string? v)
+    {:body v}
+    v))
+
+;### normalize task ###########################################################
+
+(defn seq-to-strin-bool-map [sq]
+  (->> sq
+       (map (fn [s] [(str s) true]))
        (into {})))

-;### Debug ####################################################################
+(defn- normalize-traits-in-task [task-map]
+  (if-let [traits (:traits task-map)]
+    (cond (map? traits) task-map
+          (seqable? traits) (assoc task-map :traits (seq-to-strin-bool-map traits))
+          :else (throw (IllegalStateException. "Traits must be a map or a seqable.")))
+    (assoc task-map :traits {})))

-(defn- normalize-string-value-to-body-map [v]
-  (if (instance? String v)
-    {:body v}
-    v))
+(defn- normalize-task-with-body-to-scripts-task [task-map]
+  (cond (:scripts task-map) task-map
+        (:body task-map) (-> task-map
+                             (assoc :scripts {:main {:body (:body task-map)}})
+                             (dissoc :body))
+        :else  task-map))
+
+
+(defn- normalize-task [task]
+  (-> task
+      normalize-string-value-to-body-map
+      normalize-task-with-body-to-scripts-task
+      normalize-traits-in-task
+      ))
+
+
+
+;### normalize tasks ##########################################################

 (defn- normalize-seq-with-string-value-to-body-map [d]
   (cond (map? d)
@@ -57,21 +80,57 @@
              (map (fn [[k v]] [k (normalize-string-value-to-body-map v)]))
              (into {}))

-        (instance?  clojure.lang.Seqable d)
+        (seqable? d)
         (->> d
              (map (fn [v] (normalize-string-value-to-body-map v))))

         :else (throw (IllegalStateException.
                        (str (type d) "  must a map or Seqable!")))))

+
+(defn- normalize-tasks [tasks]
+  (->> tasks
+       normalize-seq-with-string-value-to-body-map
+       normalize-to-key-name-map
+       (map (fn [[k task]]
+              [k (normalize-task task)]))
+       (into {})
+       ))
+
+(defn- normalize-task-to-tasks [context-spec]
+  (cond
+    (:task context-spec) (-> context-spec
+                             (dissoc :task)
+                             (assoc :tasks [(:task context-spec)]))
+    (:tasks context-spec) context-spec
+    :else (assoc context-spec :tasks {})))
+
+(defn- normalize-tasks-in-context [context-spec]
+  (when (and (:task context-spec)
+             (:tasks context-spec))
+    (throw (IllegalStateException. "The keys 'task' and 'tasks' are exclusive.")))
+  (-> context-spec
+      normalize-task-to-tasks
+      (#(assoc % :tasks (normalize-tasks (:tasks %))))))
+
+
+;### task-defaults ############################################################
+
+(defn- normalize-task-defaults [task-defaults]
+  (normalize-task task-defaults))
+
+(defn- normalize-task-defaults-in-context [ctx]
+  (if-let [task-defaults (:task-defaults ctx)]
+    (assoc ctx :task-defaults (normalize-task-defaults task-defaults))
+    ctx
+    ))
+
 ;### Debug ####################################################################

 (defn- normalize-context [context-spec]
   (-> context-spec
-      (#(if (:tasks %) % (assoc % :tasks [])))
-      (#(assoc % :tasks (normalize-seq-with-string-value-to-body-map (:tasks %))))
-      (#(assoc % :tasks (normalize-to-key-name-map (:tasks %))))
-      (#(assoc % :tasks (normalize-body-tasks-to-script-tasks (:tasks %))))
+      normalize-tasks-in-context
+      normalize-task-defaults-in-context
       (#(if-let[subcontexts (:subcontexts %)]
           (assoc % :subcontexts
                  (->> subcontexts
@@ -86,7 +145,7 @@
 ;### Debug ####################################################################

-(def CONTEXT-KEYS [:tasks :task-defaults :script-defaults :subcontexts])
+(def CONTEXT-KEYS [:task :tasks :task-defaults :script-defaults :subcontexts])

 (defn- normalize-to-top-level-context [spec]
   (if (:context spec)
@@ -104,7 +163,7 @@
       (#(assoc % :context (-> % :context normalize-context)))
       ))

-(apply dissoc {:x 5} [:x])
+;(apply dissoc {:x 5} [:x])

 ;### Debug ####################################################################
 ;(logging-config/set-logger! :level :debug)


CMR-2468: Removed thread-last macro per Chris' suggestion.

--- indexer-app/src/cmr/indexer/services/index_service.clj
+++ indexer-app/src/cmr/indexer/services/index_service.clj
@@ -484,10 +484,9 @@
                            revision-id
                            all-revisions-index?)]
     (if (= concept-type :collection)
-      (->> {:collection-concept-id concept-id}
-           (search/find-granule-hits context)
-           (format "%s. Removing %d granules"
-                   log-string))
+      (format "%s. Removing %d granules."
+              log-string
+              (search/find-granule-hits context {:collection-concept-id concept-id}))
       log-string)))

 (defmulti delete-concept


Close modal when its background is clicked

--- src/cljs/my_money/components/common.cljs
+++ src/cljs/my_money/components/common.cljs
@@ -1,6 +1,9 @@
 (ns my-money.components.common
   (:require [reagent.core :as r]
             [reagent.session :as session]))
+
+(defn- close-modal []
+  (session/remove! :modal))

 (defn modal [header body footer]
   [:div
@@ -8,8 +11,8 @@
     [:div.modal-content
      [:div.modal-header [:span.modal-title.h5 header]
                         [:button.close {:type "button"
-                                        :on-click #(session/remove! :modal)}
+                                        :on-click close-modal}
                                        "×"]]
      [:div.modal-body body]
      [:div.modal-footer footer]]]
-   [:div.modal-backdrop.fade.in]])
+   [:div.modal-backdrop.fade.in {:on-click close-modal}]])


fix edit button in profile block

fix edit button in profile block

--- src/cljs/salava/social/ui/dashboard.cljs
+++ src/cljs/salava/social/ui/dashboard.cljs
@@ -374,7 +374,10 @@
          [:span.small.icon]
          #_[:i.fa.fa-angle-right.icon.small]]
         [:div.content
-         (when-not (not-activated?) [:a.btn.button {:href (path-for "/user/edit/profile")} (t :page/Edit)])
+         (when-not (not-activated?) [:a.btn.button {:href (path-for (str "/profile/" (session/get-in [:user :id])))
+                                                    :on-click #(do
+                                                                (.preventDefault %)
+                                                                (session/put! :edit-mode true))} (t :page/Edit)])

          [:div
           [:div.media


Made novelty distances faster when using Hamming distance.

--- src/clojush/pushgp/selection/novelty.clj
+++ src/clojush/pushgp/selection/novelty.clj
@@ -16,24 +16,26 @@
    Note that there is no limit on behavior differences, which will only be limited
    by their max bounds based on things like maximum integer size."
   [behavior1 behavior2 {:keys [novelty-distance-metric] :as argmap}]
-  (let [behavior-differences (map (fn [b1 b2]
-                                    (cond
-                                      ; Handles equal behaviors, including if both are :no-stack-item
-                                      (= b1 b2) 0
-                                      ; If one has :no-stack-item and the other does not, give max difference
-                                      (or (= b1 :no-stack-item)
-                                          (= b2 :no-stack-item)) max-number-magnitude
-                                      :else (case (recognize-literal b1)
-                                              :string (levenshtein-distance b1 b2)
-                                              (:integer :float) (math/abs (-' b1 b2))
-                                              (:boolean :char) (if (= b1 b2) 0 1)
-                                              (throw (Exception. (str "Unrecognized behavior type in novelty distance for: " b1))))))
-                                  behavior1
-                                  behavior2)]
-    (case novelty-distance-metric
-      :hamming (apply +' (map #(if (zero? %) 0 1) behavior-differences))
-      :manhattan (apply +' behavior-differences)
-      :euclidean (math/sqrt (apply +' (map #(*' % %) behavior-differences))))))
+  (if (= novelty-distance-metric :hamming) ; This is hear, instead of below, for speed reasons
+    (apply + (map #(if (= %1 %2) 0 1)
+                  behavior1 behavior2))
+    (let [behavior-differences (map (fn [b1 b2]
+                                      (cond
+                                        ; Handles equal behaviors, including if both are :no-stack-item
+                                        (= b1 b2) 0
+                                        ; If one has :no-stack-item and the other does not, give max difference
+                                        (or (= b1 :no-stack-item)
+                                            (= b2 :no-stack-item)) max-number-magnitude
+                                        :else (case (recognize-literal b1)
+                                                :string (levenshtein-distance b1 b2)
+                                                (:integer :float) (math/abs (-' b1 b2))
+                                                (:boolean :char) (if (= b1 b2) 0 1)
+                                                (throw (Exception. (str "Unrecognized behavior type in novelty distance for: " b1))))))
+                                    behavior1
+                                    behavior2)]
+      (case novelty-distance-metric
+        :manhattan (apply +' behavior-differences)
+        :euclidean (math/sqrt (apply +' (map #(*' % %) behavior-differences)))))))

 (defn calculate-behavior-distance-map
   "Calculates a map storing the distances between any two behaviors, of the form:
@@ -108,13 +110,8 @@
                   % assign-novelty-to-individual behavior-sparseness argmap)
                 pop-agents)))
   (when-not use-single-thread (apply await pop-agents)) ;; SYNCHRONIZE
-  ;; (println "^^^^^^^^^^ Novelty Archive below ^^^^^^^^^^^^^")
-  ;; (doseq [ind pop-agents]
-  ;;   (println (:novelty (deref ind))))
-  ;; (doseq [a novelty-archive]
-  ;;   (println (:uuid a)))
-  ;; (println "vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv")
-  (println "Done calculating novelty."))
+  (println "Done calculating novelty.")
+  (println "\nNovelty Numbers:" (sort > (map #(float (:novelty (deref %))) pop-agents))))

 (defn novelty-tournament-selection
   "Returns an individual that does the best out of a tournament based on novelty."


Use html5 history

Use html5 history

--- demo/sitetools/core.cljs
+++ demo/sitetools/core.cljs
@@ -51,6 +51,9 @@

 (defonce history nil)

+(defn as-relative [f]
+  (clojure.string/replace f #"^/" ""))
+
 (defn demo-handler [state [id v1 v2 :as event]]
   (case id
     :content (do
@@ -63,7 +66,7 @@
                         :main-content v1
                         :title title)))
     :set-page (do (secretary/dispatch! v1)
-                  (assoc state :page v1))
+                  (assoc state :page-name v1))
     :goto-page (do
                  (when r/is-client
                    (.setToken history v1 false)
@@ -72,7 +75,7 @@
     state))

 (defn dispatch [event]
-  ;; (dbg event)
+  (dbg event)
   (rswap! config demo-handler event)
   nil)

@@ -81,9 +84,22 @@

 (defn init-history []
   (when-not history
-    (doto (set! history (History.))
-      (evt/listen hevt/NAVIGATE #(dispatch [:set-page (.-token %)]))
-      (.setEnabled true))))
+    (let [page (:page-name @config)
+          html5 (let [proto js/location.protocol]
+                  (and page
+                       (.isSupported Html5History)
+                       (#{"http:" "https:"} proto)))]
+      (doto (set! history
+                  (if html5
+                    (doto (Html5History.)
+                      (.setUseFragment false)
+                      (.setPathPrefix js/location.origin)
+                      (.setEnabled true))
+                    (History.)))
+        (evt/listen hevt/NAVIGATE #(dispatch [:set-page (str (.-token %))]))
+        (.setEnabled true))
+      (when html5
+        (.setToken history page)))))

 ;; (defn register-page
@@ -286,8 +302,6 @@
   (write-file (path-join dir (:css-file @config))
               (read-css)))

-(defn as-relative [f]
-  (clojure.string/replace f #"^/" ""))

 ;;; Main entry points

@@ -295,7 +309,7 @@
   (log "Generating site")
   (swap! config merge (js->clj opts :keywordize-keys true))
   (let [dir (:site-dir @config)
-        timestamp (str "?" (.' js/Date now))]
+        timestamp (str "?" js/Date.now)]
     (doseq [f (:pages @config)]
       (write-file (path-join dir (dbg (as-relative f)))
                   (gen-page f timestamp)))
@@ -309,13 +323,7 @@
                  (js->clj js/pageConfig :keywordize-keys true))
           page-name (:page-name conf)]
       (swap! config merge conf)
-      (when (nil? history)
-        ;; (when page-name
-        ;;   (set-start-page page-name))
-        (init-history)
-        ;; (setup-history page-name)
-        ;; (set! (.-title js/document) (get-title))
-        )
+      (init-history)
       (r/render-component (body)
                           (.' js/document getElementById
                               (:main-div @config))))))


Remove compile-assertion declaration

Remove compile-assertion declaration

--- src/main/clojure/com/stuartsierra/lazytest.clj
+++ src/main/clojure/com/stuartsierra/lazytest.clj
@@ -45,7 +45,7 @@

 ;;; DATATYPES

-(declare run-test-case compile-assertion)
+(declare run-test-case)

 ;; Context sets up state for TestCases that depend on it.  parents is
 ;; a vector of parent Contexts.  before and after are functions.


remove unneeded comment

remove unneeded comment

--- test/cljam/t_common.clj
+++ test/cljam/t_common.clj
@@ -10,7 +10,6 @@
   {:resources [{:id "large.bam"
                 :url "ftp://ftp.broadinstitute.org/old/NA12878.BI.illumina.dup.sort.bam"
                 :sha1 "523780c7f39dfe97939124e92c8d34d0759c841f"
-                ;:sha1 "e3d87d947e8b5cc0b88fef042b2e5438ab9120b8"
                 :auth {:user "gsapubftp-anonymous", :password "cljam-test"}
                 }
                ]})


Remove unused option to render-file

Remove unused option to render-file

--- src/main/hbase_region_inspector/core.clj
+++ src/main/hbase_region_inspector/core.clj
@@ -239,7 +239,6 @@
 (defroutes app-routes
   (GET "/" []
        (render-file "public/index.html" {:zookeeper @zookeeper
-                                         :read-only @read-only?
                                          :updated-at (:updated-at @cached)}))
        ;; (content-type (resource-response "index.html" {:root "public"})
        ;;               "text/html"))


Fix bytes conversion failure in tests.

Fix bytes conversion failure in tests.

--- test/blocks/core_test.clj
+++ test/blocks/core_test.clj
@@ -64,9 +64,8 @@
         "load returns literal block for lazy block")
     (is (identical? literal-readme (block/load! literal-readme))
         "load returns literal block unchanged")
-    (is (bytes= @literal-readme
-                (with-open [content (block/open lazy-readme)]
-                  (bytes/to-byte-array content)))
+    (is (bytes= (.open @literal-readme)
+                (block/open lazy-readme))
         "literal block content should match lazy block")))


177 (in progress)

177 (in progress)

--- stuf/src/sandbox/4clojure.clj
+++ stuf/src/sandbox/4clojure.clj
@@ -1497,3 +1497,12 @@

 ;;173 Intro to Destructuring 2
 ;f a
+
+;;177
+(def lp [\( \[ \{])
+(def rp [\) \] \}])
+(defn f [[fst & rst] stack]
+  (let [stk (first stack)]
+    (cond
+      (nil? fst) stack
+      ((set lp) fst) (f rst (cons fst stack)))))


Remove test for function that's no longer on the public api.

--- test/grafter/tabular_test.clj
+++ test/grafter/tabular_test.clj
@@ -113,15 +113,6 @@
            "a" 0
            :not-found "z"
            :not-found :z))))
-
-(deftest invalid-column-keys-tests
-  (testing "invalid-column-keys"
-    (let [dataset (test-dataset 5 5)]
-      (testing "Returns the keys not in the dataset"
-        (is (= ["x" "z" 5 :f] (invalid-column-keys ["a" "b" "x" "z" "c" "d" "e" 0 1 2 3 4 5 :a :b :c :d :e :f] dataset)))
-
-        (testing "Preserves the order of invalid keys"
-          (is (= ["z" "x"] (invalid-column-keys ["a" "b" "z" "x" "c" "d" "e"] dataset))))))))

 (deftest columns-tests
   (let [expected-dataset (test-dataset 5 2)


Reorder assertions.

Reorder assertions.

--- test/onyx/hornetq/vm_test.clj
+++ test/onyx/hornetq/vm_test.clj
@@ -89,13 +89,13 @@

 @p

+(doseq [v-peer v-peers]
+  ((:shutdown-fn v-peer)))
+
+(onyx.api/shutdown conn)
+
 (let [results @output
       expected (set (map (fn [x] {:n (inc x)}) (range n-messages)))]
   (fact (set (butlast results)) => expected)
   (fact (last results) => :done))

-(doseq [v-peer v-peers]
-  ((:shutdown-fn v-peer)))
-
-(onyx.api/shutdown conn)
-


Add tests for new "on-changes" middleware

--- test/re-frame/middleware.cljs
+++ test/re-frame/middleware.cljs
@@ -29,3 +29,13 @@
                    handler) db [nil])]
       (is (= (:a new-db)
              false)))))
+
+
+(deftest on-changes
+         (let [set-a     (fn [db v] (assoc db :a v))      ;; handler
+               mid-ware  (middleware/on-changes + [:c] [:a] [:b])   ;; middleware
+               wrapped   (mid-ware set-a)]                ;; wrapped middleware
+             (is (= (wrapped {:a 0 :b 2} 0)               ;; no change in 'a'
+                    {:a 0 :b 2}))
+             (is (= ({:a 4 :b 2} 0)                       ;; 'a' changed to 0
+                    {:c 2 :a 0 :b 2}))))                  ;; 'c' is a + b


remove debug statement

remove debug statement

--- test/shelver/handler_test.clj
+++ test/shelver/handler_test.clj
@@ -40,7 +40,7 @@
     (are [base target]
       (let [target-with-base (str "http://targethost.edu" target)
             target-encoded (base64-encode target)]
-        (dbg (= (format "%s&next=%s" base target-encoded) (add-redirect-next base target-with-base))))
+        (= (format "%s&next=%s" base target-encoded) (add-redirect-next base target-with-base)))

       "http://host.com/path?q1" "/target"
       "http://host.com/path?q1=v1" "/target"


Add new corner case

Add new corner case


wrap test metrics in try catch (#886)

wrap test metrics in try catch (#886)

--- waiter/test/waiter/test_helpers.clj
+++ waiter/test/waiter/test_helpers.clj
@@ -124,16 +124,20 @@

 (defn- post-json
   [url json]
-  (let [conn (doto (.openConnection (URL. url))
-               (.setDoOutput true)
-               (.setDoInput true)
-               (.setRequestMethod "POST")
-               (.setRequestProperty "content-type" "application/json")
-               (.setUseCaches false)
-               (.connect))]
-    (with-open [writer (io/writer (.getOutputStream conn))]
-      (.write writer json))
-    (.getResponseCode conn)))
+  (try
+    (let [conn (doto (.openConnection (URL. url))
+                 (.setDoOutput true)
+                 (.setDoInput true)
+                 (.setRequestMethod "POST")
+                 (.setRequestProperty "content-type" "application/json")
+                 (.setUseCaches false)
+                 (.connect))]
+      (with-open [writer (io/writer (.getOutputStream conn))]
+        (.write writer json))
+      (.getResponseCode conn))
+    (catch Throwable e
+      (log/error "Failed to post test metrics json " e url json)
+      (throw e))))

 (defn blue [message] (str ANSI-BLUE message ANSI-RESET))
 (defn magenta [message] (str ANSI-MAGENTA message ANSI-RESET))
@@ -182,32 +186,35 @@
         (println \tab (blue "FINISH:") test-name (cyan (format-duration elapsed-millis))
                  (assoc @*report-counters* :running (count @running-tests)))
         (when test-metrics-url
-          (let [{:keys [full-name name namespace]} (test-name-info (:var m))
-                num-fails (or (@test-name->num-fails-atom full-name) 0)
-                num-errors (or (@test-name->num-errors-atom full-name) 0)
-                num-passes (or (@test-name->num-passes-atom full-name) 0)
-                test-skipped? (= 0 (+ num-fails num-errors num-passes))
-                test-failed? (> (+ num-fails num-errors) 0)
-                result (if test-failed? "failed" (if test-skipped? "skipped" "passed"))
-                es-index (str "waiter-tests-" (du/date-to-str (t/now) (f/formatters :basic-date)))]
-            ;TODO: can check for outstanding commits: (println (jgit/git-status git-repo))
-            (post-json (str test-metrics-url "/" es-index "/test-result")
-                       (json/write-str {:build-id test-metrics-build-id
-                                        :expected-to-fail test-metrics-expected-to-fail
-                                        :git-branch current-git-branch
-                                        :git-branch-under-test test-metrics-branch-under-test
-                                        :git-commit-hash current-git-commit
-                                        :git-commit-hash-under-test test-metrics-commit-hash-under-test
-                                        :host hostname
-                                        :project "waiter"
-                                        :result result
-                                        :run-description test-metrics-run-description
-                                        :run-id test-metrics-run-id
-                                        :runtime-milliseconds elapsed-millis
-                                        :test-name name
-                                        :test-namespace namespace
-                                        :timestamp (du/date-to-str (t/now))
-                                        :user username})))))
+          (try
+            (let [{:keys [full-name name namespace]} (test-name-info (:var m))
+                  num-fails (or (@test-name->num-fails-atom full-name) 0)
+                  num-errors (or (@test-name->num-errors-atom full-name) 0)
+                  num-passes (or (@test-name->num-passes-atom full-name) 0)
+                  test-skipped? (= 0 (+ num-fails num-errors num-passes))
+                  test-failed? (> (+ num-fails num-errors) 0)
+                  result (if test-failed? "failed" (if test-skipped? "skipped" "passed"))
+                  es-index (str "waiter-tests-" (du/date-to-str (t/now) (f/formatters :basic-date)))]
+              ;TODO: can check for outstanding commits: (println (jgit/git-status git-repo))
+              (post-json (str test-metrics-url "/" es-index "/test-result")
+                         (json/write-str {:build-id test-metrics-build-id
+                                          :expected-to-fail test-metrics-expected-to-fail
+                                          :git-branch current-git-branch
+                                          :git-branch-under-test test-metrics-branch-under-test
+                                          :git-commit-hash current-git-commit
+                                          :git-commit-hash-under-test test-metrics-commit-hash-under-test
+                                          :host hostname
+                                          :project "waiter"
+                                          :result result
+                                          :run-description test-metrics-run-description
+                                          :run-id test-metrics-run-id
+                                          :runtime-milliseconds elapsed-millis
+                                          :test-name name
+                                          :test-namespace namespace
+                                          :timestamp (du/date-to-str (t/now))
+                                          :user username})))
+            (catch Throwable e
+              (log/error "Failed to post test metrics " e test-metrics-url)))))
       (log-running-tests)))

   (defmethod report :summary [m]


core: refactor hex-format

core: refactor hex-format

--- src/cfg/core.cljs
+++ src/cfg/core.cljs
@@ -83,10 +83,10 @@

 (def canvas (om/factory Canvas))

+
 (defn hex-format
   [n]
-  (.toString n 16))
-
+  (str "0x" (string/upper-case (.toString n 16))))

 (defui BasicBlock
@@ -103,7 +103,7 @@
       (dom/tbody
        (for [insn (:insns (om/props this))]
          (dom/tr {:key (str (:addr insn)) :class "insn"}
-                 (dom/td {:class "addr"} (str "0x" (string/upper-case (hex-format (:addr insn)))))
+                 (dom/td {:class "addr"} (hex-format (:addr insn)))
                  (dom/td {:class "bytes"} (string/upper-case (:bytes insn)))
                  (dom/td {:class "mnem"} (:mnem insn))
                  (dom/td {:class "operands"} (:operands insn))


missing require in db test ns

missing require in db test ns

--- test/clojento/magento/t_db.clj
+++ test/clojento/magento/t_db.clj
@@ -5,7 +5,9 @@
             [clj-time.core :as t]
             [clojure.java.io :as io]
             [clojure.tools.logging :as log]
-            [com.stuartsierra.component :as component]))
+            [com.stuartsierra.component :as component]
+            [ragtime.jdbc]
+            [ragtime.repl]))

 (log/debug "loading clojento.magento.t_db namespace")


Update test for checking how failed media uploads are displayed

--- test/hatti/ona/forms_test.cljs
+++ test/hatti/ona/forms_test.cljs
@@ -163,10 +163,12 @@
                     :small_download_url "THUMB.jpg"}
             image3 {:filename "foo/bar.jpg"
                     :download_url "IMAGE.jpg"}
-            txt-link (forms/format-answer q-img image2 :compact? true)]
+            txt-link (forms/format-answer q-img image2 :compact? true)
+            tooltip-error-msg (forms/format-answer q-img image1)]
         (is (= (forms/format-answer q-img nil) forms/no-answer))
         (is (= (forms/format-answer q-img "") forms/no-answer))
-        (is (= (forms/format-answer q-img image1) "bar.jpg"))
+        (is (re-find #"This media file was not uploaded successfully."
+                     tooltip-error-msg))
         (is (= (forms/format-answer q-img image2)
                [:a {:href "IMAGE.jpg" :target "_blank"}
                 [:img {:width "80px" :src "THUMB.jpg"}]]))


First version of sahucs broken, earlier stuff seems broken too.

--- src/exp/sahdd.clj
+++ src/exp/sahdd.clj
@@ -5,7 +5,8 @@
             [exp.hierarchy :as hierarchy])
   (:import  [java.util HashMap]))

-;; TODO: note other implementations are incorrect, since they don't handle reward decreases of partial nodes properly. ?
+;; TODO: note other sahucs implementations are incorrect, since they don't handle reward decreases of partial nodes properly. ?
+;; For the same reason, sahucs-fancy-dijkstra is doubly-incorrect ?

 ; Here, there is no real Seq character.  No real choices.
 ; Note: hard (impossible?) to unify down and up.
@@ -85,7 +86,9 @@
                 (let [next-min-reward (max min-reward (queue-best-reward queue))]
                   (queues/pq-replace! partial-queue best (make-queue-priority best-reward))
                   (let [{:keys [result-pairs max-reward]} (expand-fn best next-min-reward)]
-                    (queues/pq-replace! partial-queue best (make-queue-priority max-reward))
+                    (if (= max-reward Double/NEGATIVE_INFINITY)
+                        (queues/pq-remove! partial-queue best)
+                      (queues/pq-replace! partial-queue best (make-queue-priority max-reward)))
                     (doseq [[ni nr] result-pairs]
  ;                    (println "NEW" max-reward (class ni) nr (:name ni))
                       (assert (not (= :re-added (queues/pq-add! new-queue ni (make-queue-priority nr))))))
@@ -160,15 +163,19 @@
           (next-partial-solution [min-reward]
             (if (< @index-atom (count @result-vec-atom))
                 (let [[_ rew :as result] (nth @result-vec-atom @index-atom)]
+                 ;; TODO: remove
+                  (util/assert-is (<= (count @result-vec-atom) 1) "%s" [@result-vec-atom])
                   (if (>= rew min-reward)
                       (do (swap! index-atom inc)
                           (PartialResult [result]
-                                         (max (get @result-vec-atom @index-atom Double/NEGATIVE_INFINITY)
+                                         (max (second (get @result-vec-atom @index-atom [nil Double/NEGATIVE_INFINITY]))
                                               @next-reward-atom)))
                     (PartialResult nil rew)))
               (if (viable? @next-reward-atom min-reward)
                   (let [{:keys [result-pairs max-reward]} (next-partial-solution search-problem min-reward)]
                     (reset! next-reward-atom max-reward)
+                    ;; TODO: remove!
+                    (doseq [x1 @result-vec-atom x2 result-pairs] (assert (not (= (first x1) (first x2)))))
                     (swap!  result-vec-atom into result-pairs)
                     (recur min-reward))
                 (PartialResult nil @next-reward-atom)))))))))
@@ -221,12 +228,10 @@
   (expand-node        [se new-threshold]
     "Returns PartialResult of SearchNodes."))

-
-
-(deftype GoalNode [goal-state]
-  SearchNode
-  (extract-goal-state []           goal-state)
-  (expand-node        [min-reward] (throw (UnsupportedOperationException.))))
+(defn make-goal-node [goal-state]
+  (reify SearchNode
+       (extract-goal-state [] goal-state)
+       (expand-node        [min-reward] (throw (UnsupportedOperationException.)))))

 ;; Named node is simple non-terminal node whose equality semantics are given by name.
 (deftype NamedNode [name root-sa expand-fn] :as this
@@ -272,7 +277,7 @@
             (make-recursive-expander
              (delay (make-exhaustive-search
                      (make-abstracted-incremental-dijkstra-sa-search state reward f))) r)))
-     (GoalNode state))
+     (make-goal-node state))
    reward])

@@ -288,8 +293,78 @@

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Inverted Node ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

-
-;; TODO: how to switch between these as we go?!
+;; Can we do it as "state-to-go", not "finished state" ?
+; i.e., state, reward, remaining-actions, parent-cache.
+; when r-a is empty, update.  Can add factoring later if we need it ?
+
+;; Note: can we cache results across calls?
+;; We need same initial state, at least.
+;;  Different goal is possible, but might as well integrate this above as well.
+
+; Note: right now, reward in parent-pair is being ignored.
+
+;; TODO: remove expensive tests.
+(defn- add-monotonic! [result-pair-atom [new-result new-reward :as new-result-pair]]
+  (assert (every? #(not (= (first %) new-result)) @result-pair-atom))
+  (when (seq @result-pair-atom) (assert (<= new-reward (second (last @result-pair-atom)))))
+  (swap! result-pair-atom conj new-result-pair))
+
+(defprotocol InvertedItem (notify-upward [item outcome-pair]))
+
+(deftype InvertedCache [result-pairs-atom parent-pairs-atom]
+  InvertedItem
+    (notify-upward [outcome-pair]
+      (add-monotonic! result-pairs-atom outcome-pair)
+      (mapcat #(notify-upward (first %) outcome-pair) @parent-pairs-atom)))
+
+(declare make-inverted-node notify-upward-node)
+
+(defn connect-downward-cache [state action [new-parent new-reward :as new-parent-pair]]
+  (let [context (env/precondition-context action state)
+        ic      (get-cached-search [::INV (env/extract-context state context) (env/action-name action)]
+                  (InvertedCache (atom []) (atom [])))
+        {:keys [result-pairs-atom parent-pairs-atom]} ic
+        first-visit?  (empty? @parent-pairs-atom)]
+    (add-monotonic! parent-pairs-atom new-parent-pair)
+    (if first-visit?  ; first time: create and return sub-nodes.
+        (let [state (env/get-logger state context)]
+          (if (env/primitive? action)
+              (when-let [[ss sr] (and (env/applicable? action state) (env/successor action state))]
+                [(make-inverted-node (vary-meta ss assoc :opt [action]) (+ new-reward sr) nil ic)])
+            (for [ref (hierarchy/immediate-refinements action state)]
+              (make-inverted-node state new-reward ref ic))))
+      (map #(notify-upward-node new-parent %) @result-pairs-atom))))
+
+
+;; TODO: partial expansions for goals ?
+(deftype InvertedNode   [name state reward remaining-actions parent-cache] :as this
+  Object
+   (equals   [y] (= name (:name y)))
+   (hashCode []  (hash name))
+  SearchNode
+   (extract-goal-state [] nil)
+   (expand-node        [min-reward]
+     (if-let [[f & r] remaining-actions]
+         (connect-downward-cache state f [this reward])
+       (notify-upward parent-cache [state reward])))
+  InvertedItem
+   (notify-upward [outcome-pair]
+     (let [[outcome-state outcome-rew] (generalize-outcome-pair outcome-pair state reward)]
+       [(make-inverted-node outcome-state outcome-rew (next remaining-actions) parent-cache)])))
+
+(defn make-inverted-node [state reward remaining-actions parent-cache]
+  [(InvertedNode [state remaining-actions parent-cache] state reward remaining-actions parent-cache) reward])
+
+(defn make-inverted-root-node [state action]
+  (connect-downward-cache state action
+    [(reify InvertedItem
+      (notify-upward [outcome-pair] [(update-in outcome-pair 0 make-goal-node)]))
+     0]))
+
+(defn make-inverted-sa-search [state action]
+  (make-incremental-dijkstra-search [(make-inverted-root-node state action)]))
+
+

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Top-level  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -326,6 +401,7 @@
   (hierarchical-search henv (if-cycle-fn :transparent :recursive-exhaustive)
     (comp make-exhaustive-search make-incremental-dijkstra-sa-search)))

+
 (defn sahucs-flat [henv]
   (hierarchical-search henv (constantly :transparent)
     make-incremental-dijkstra-sa-search))
@@ -337,6 +413,10 @@
 (defn sahucs-dijkstra [henv]
   (hierarchical-search henv (if-cycle-fn :transparent :recursive)
     make-incremental-dijkstra-sa-search))
+
+(defn sahucs-inverted [henv]
+  (hierarchical-search henv :dummy
+    make-inverted-sa-search))


Update core_test.clj

Update core_test.clj

--- test/swagger_gen/core_test.clj
+++ test/swagger_gen/core_test.clj
@@ -20,4 +20,3 @@
   (testing "should extract all paths into a flattened list"
     (let [extracted (->> (parse-swagger petstore-yaml) :paths)]
       (is (= (count extracted) 4)))))
-


procfiles/profed.clj: fixed map output structure

--- src/org/altlaw/jobs/procfiles/profed.clj
+++ src/org/altlaw/jobs/procfiles/profed.clj
@@ -23,17 +23,17 @@
               meta (PROMetadataReader.)]
           (.setFilename meta filename)
           (.parse meta (StringReader. raw-html))
-          {:docid docid
-           :doctype "case"
-           :files [filename]
-           :name (.getTitle meta)
-           :dockets (vec (.getDockets meta))
-           :citations (vec (.getCitations meta))
-           :court (.getCourtId meta)
-           :date (.getDate meta)
-           :html body-html
-           :text body-text
-           :size (count body-text)}))
+          [[docid {:docid docid
+                   :doctype "case"
+                   :files [filename]
+                   :name (.getTitle meta)
+                   :dockets (vec (.getDockets meta))
+                   :citations (vec (.getCitations meta))
+                   :court (.getCourtId meta)
+                   :date (.getDate meta)
+                   :html body-html
+                   :text body-text
+                   :size (count body-text)}]]))
       (do (h/counter "Files with no docid")
           (log/warn "No docid for file " filename)))))


remove dev task from the example

remove dev task from the example

--- example/build.boot
+++ example/build.boot
@@ -35,13 +35,3 @@
         (rss :title "Hashobject" :description "Hashobject blog" :link "http://blog.hashobject.com")
         (atom-feed  :title "Hashobject" :subtitle "Hashobject blog" :link "http://blog.hashobject.com")
         (notify)))
-
-(deftask dev
-  "Dev process"
-  []
-  (comp
-    (watch)
-    (repl :server true)
-    (pom)
-    (jar)
-    (install)))


parser/parse now only called once

parser/parse now only called once

--- src/aeolian/composer.clj
+++ src/aeolian/composer.clj
@@ -30,12 +30,12 @@
 	(n/pick-note-for-line-length line-length))

 (defn adjust-for-complexity [metric]
-	(let [complexity (:complexity (parser/parse metric))]
+	(let [complexity (:complexity metric)]
 		(if (> complexity 1)
 			(abc/inline (t/tempo-for complexity)))))

 (defn adjust-for-indentation [metric]
-	(let [indentation-error (:indentation? (parser/parse metric))]
+	(let [indentation-error (:indentation? metric)]
 		(if (not (nil? indentation-error))
 			(midi/volume-boost))))

@@ -52,12 +52,13 @@
 (defn metric-to-note [metric]
 	(log/debug (str "Processing metric " metric))
 	(let [
-		current-source-file (:source-file (parser/parse metric))
-		current-author 		(:author (parser/parse metric))
-		raw-note 			(str (build-note (:line-length (parser/parse metric))) " ")
+		metric-components (parser/parse metric)
+		current-source-file (:source-file metric-components)
+		current-author 		(:author metric-components)
+		raw-note 			(str (build-note (:line-length metric-components)) " ")
 		final-note-bits (cons (adjust-for-author-change current-author)
 							(cons (adjust-for-file-change current-source-file)
-								(cons (adjust-for-complexity metric) (list raw-note))))
+								(cons (adjust-for-complexity metric-components) (list raw-note))))
 		final-note (apply str (interpose " " (filter #(not (nil? %)) final-note-bits)))
 		]
 		(update-source-file current-source-file)


Version 0.3.4

Version 0.3.4

--- metlog-vault/project.clj
+++ metlog-vault/project.clj
@@ -1,4 +1,4 @@
-(defproject metlog-vault "0.3.4-SNAPSHOT"
+(defproject metlog-vault "0.3.4"
   :description "Repository for long term storage of series data."

   :license {:name "Eclipse Public License"


Minor fix on ruler ctrl mode.

Minor fix on ruler ctrl mode.

--- src/uxbox/ui/workspace/canvas/ruler.cljs
+++ src/uxbox/ui/workspace/canvas/ruler.cljs
@@ -67,8 +67,8 @@
   (letfn [(on-value [[[x y :as pos] ctrl?]]
             (if ctrl?
               (let [[sx sy] (:pos1 @local)
-                    dx (- x sx)
-                    dy (- y sy)]
+                    dx (mth/abs (- x sx))
+                    dy (mth/abs (- y sy))]
                 (cond
                   (> dx dy) (swap! local assoc :pos2 [x sy])
                   (> dy dx) (swap! local assoc :pos2 [sx y])


Version 0.6.1

Version 0.6.1

--- metlog-vault/project.clj
+++ metlog-vault/project.clj
@@ -1,4 +1,4 @@
-(defproject metlog-vault "0.6.1-SNAPSHOT"
+(defproject metlog-vault "0.6.1"
   :description "Repository for storing and displaying time series data reported by metlog-agent.."

   :license {:name "Eclipse Public License"


Add Party to v5 validations

Add Party to v5 validations

--- src/vip/data_processor/validation/v5.clj
+++ src/vip/data_processor/validation/v5.clj
@@ -13,7 +13,8 @@
             [vip.data-processor.validation.v5.locality :as locality]
             [vip.data-processor.validation.v5.internationalized-text :as intl-text]
             [vip.data-processor.validation.v5.district-type :as district-type]
-            [vip.data-processor.validation.v5.office :as office]))
+            [vip.data-processor.validation.v5.office :as office]
+            [vip.data-processor.validation.v5.party :as party]))

 (def validations
   [candidate/validate-no-missing-ballot-names
@@ -46,4 +47,5 @@
    district-type/validate
    office/validate-no-missing-names
    office/validate-no-missing-term-types
-   office/validate-term-types])
+   office/validate-term-types
+   party/validate-colors])


`cljs.closure/add-implicit-options` add the implicit options for :optimizations :advanced

--- src/clj/cljs/closure.clj
+++ src/clj/cljs/closure.clj
@@ -1353,7 +1353,12 @@
       (= optimizations :none)
       (assoc
         :cache-analysis (:cache-analysis opts true)
-        :source-map (:source-map opts true)))))
+        :source-map (:source-map opts true))
+
+      (= optimizations :advanced)
+      (cond->
+        (not (false? (:static-fns opts))) (assoc :static-fns true)
+        (not (false? (:optimize-constants opts))) (assoc :optimize-constants true)))))

 (defn build
   "Given a source which can be compiled, produce runnable JavaScript."


Words

Words

--- src/clj/runbld/build.clj
+++ src/clj/runbld/build.clj
@@ -146,18 +146,17 @@
     (let [b (find-build opts (-> opts :build :last-success :id))
           commit (-> b :vcs :commit-short)]
       ((:logger opts)
-       "using last successful commit"
-       commit
-       "from"
-       (-> b :build :job-name) (-> b :id)
-       (-> b :process :time-start)
-       (date/human-duration
-        (date/iso-diff-secs
-         (date/from-iso
-          ;; notify on time-end because it makes more
-          ;; logical sense to report on the last
-          ;; completed build's end time, I think
-          (-> b :process :time-end))
-         (date/now)))
+       "Using last successful commit" commit
+       "from the job" (-> b :build :job-name)
+       "with the build id" (-> b :id)
+       "that was started at" (-> b :process :time-start)
+       "and finished" (date/human-duration
+                       (date/iso-diff-secs
+                        (date/from-iso
+                         ;; notify on time-end because it makes more
+                         ;; logical sense to report on the last
+                         ;; completed build's end time, I think
+                         (-> b :process :time-end))
+                        (date/now)))
        "ago")))
   opts)


Improvements on the lovins implementation

--- src/clj_fuzzy/lovins.clj
+++ src/clj_fuzzy/lovins.clj
@@ -97,11 +97,11 @@
     #"ity$" :A         #"ium$" :A         #"ive$" :A         #"ize$" :F
     #"oid$" :A         #"one$" :R         #"ous$" :A

-    #"ae$" :A          #"al$" :BB          #"ar$" :X          #"as$" :B
+    #"ae$" :A          #"al$" :BB         #"ar$" :X          #"as$" :B
     #"ed$" :E          #"en$" :F          #"es$" :E          #"ia$" :A
     #"ic$" :A          #"is$" :A          #"ly$" :B          #"on$" :S
     #"or$" :T          #"um$" :U          #"us$" :V          #"yl$" :R
-    #"s'" :A           $"'s$" :A
+    #"s'"  :A          #"'s$" :A

     #"a$" :A           #"e$" :A           #"i$" :A           #"o$" :A
     #"s$" :W           #"y$" :B))
@@ -113,18 +113,18 @@
    :C (fn [stem] (> (count stem) 3))
    :D (fn [stem] (> (count stem) 4))
    :E (fn [stem] (not (re-test? #"e$" stem)))
-   :F (fn [stem] (and (conditions :B stem) (conditions :E stem)))
-   :G (fn [stem] (and (conditions :B stem) (re-test? #"f$" stem)))
+   :F (fn [stem] (and ((conditions :B) stem) (conditions :E stem)))
+   :G (fn [stem] (and ((conditions :B) stem) (re-test? #"f$" stem)))
    :H (fn [stem] (re-test? #"(t|ll)$" stem))
    :I (fn [stem] (not (re-test? #"[oe]$" stem)))
    :J (fn [stem] (not (re-test? #"[ae]$" stem)))
-   :K (fn [stem] (and (conditions :B stem) (re-test? #"(l|i|(u\we))$")))
+   :K (fn [stem] (and ((conditions :B) stem) (re-test? #"(l|i|(u\we))$" stem)))
    :L (fn [stem] (not (re-test? #"(u|x|([^o]s))$" stem)))
    :M (fn [stem] (not (re-test? #"[acem]$" stem)))
-   :N (fn [stem] (if (re-test? #"s\w{2}$") (conditions :C stem) (conditions :B stem)))
+   :N (fn [stem] (if (re-test? #"s\w{2}$" stem) ((conditions :C) stem) ((conditions :B) stem)))
    :O (fn [stem] (re-test? #"[li]$" stem))
    :P (fn [stem] (not (re-test? #"c$" stem)))
-   :Q (fn [stem] (and (conditions :B stem) (not (re-test? #"[ln]$" stem))))
+   :Q (fn [stem] (and ((conditions :B) stem) (not (re-test? #"[ln]$" stem))))
    :R (fn [stem] (re-test? #"[nr]$" stem))
    :S (fn [stem] (re-test? #"(dr|[^t]t)$" stem))
    :T (fn [stem] (re-test? #"(s|[^o]t)$" stem))
@@ -135,17 +135,17 @@
    :Y (fn [stem] (re-test? #"in$" stem))
    :Z (fn [stem] (not (re-test? #"f$" stem)))
    :AA (fn [stem] (re-test? #"([dflt]|ph|th|er|or|es)$" stem))
-   :BB (fn [stem] (and (conditions :B stem) (not (re-test? #"(met|ryst)" stem))))
+   :BB (fn [stem] (and ((conditions :B) stem) (not (re-test? #"(met|ryst)" stem))))
    :CC (fn [stem] (re-test? #"l$" stem))})

 ;; Transformations
 (defn- dedouble
   "Drop double occurences of certain letters in the given [stem]."
   [stem]
-  (clojure.string/replace stem #"([bdglmnprst])[bdglmnprst]" "$1"))
+  (clojure.string/replace stem #"([bdglmnprst])\1{1,}" "$1"))

 (def ^:private transformations
-  '(#"ief$" "iev"
+  '(#"iev$" "ief"
     #"uct$" "uc"
     #"umpt$" "um"
     #"rpt$" "rb"
@@ -191,3 +191,29 @@
   [word]
   (-> (clojure.string/lower-case word)
       (clean)))
+
+(defn- drop-suffix
+  "Drop the longest suffix we can find in the given [word]."
+  [word]
+  (if-let [[match condition] (some #(when (re-test? (first %) word) %) (partition 2 endings))]
+    (let [stem (clojure.string/replace word match "")]
+      (if (and ((conditions condition) stem)
+               (> (count stem) 1))
+        stem
+        word))
+    word))
+
+(defn apply-transformations
+  "Apply the algorithm's transformations to the given [stem]."
+  [stem]
+  (if-let [[match replacement] (some #(when (re-test? (first %) stem) %) (partition 2 transformations))]
+    (clojure.string/replace stem match replacement)
+    stem))
+
+(defn stem
+  "Stem the given [word] according to the algorithm"
+  [word]
+  (-> (prep-word word)
+      (drop-suffix)
+      (dedouble)
+      (apply-transformations)))


readability changes

readability changes

--- src/clj_money/import.clj
+++ src/clj_money/import.clj
@@ -1,7 +1,9 @@
 (ns clj-money.import
   (:refer-clojure :exclude [update])
   (:require [clojure.pprint :refer [pprint]]
-            [clj-money.util :refer [pprint-and-return-l]]
+            [clj-money.util :refer [pprint-and-return
+                                    pprint-and-return-l]]
+            [clj-money.validation :as validation]
             [clj-money.models.users :as users]
             [clj-money.models.entities :as entities]
             [clj-money.models.accounts :as accounts]
@@ -21,7 +23,7 @@
         parent-id (get-in context [:accounts original-parent-id])
         to-create (cond-> account
                     true
-                    (assoc :entity-id (:entity-id context))
+                    (assoc :entity-id (-> context :entity :id))

                     true
                     (dissoc :id)
@@ -29,18 +31,34 @@
                     parent-id
                     (assoc :parent-id parent-id))
         result (accounts/create (:storage context) to-create)]
+    (when-not (:id result)
+      (throw (ex-info (str
+                        "Unable to create the account "
+                        (validation/error-messages result))
+                      {:result result})))
     (update-in context [:accounts] #(assoc % original-id (:id result)))))
+
+(defn- resolve-account-references
+  [context items]
+  (map (fn [item]
+         (update-in item [:account-id] #(-> context :accounts (get %))))
+       items))
+
+(defn- prepare-transaction
+  [context transaction]
+  (-> transaction
+      (update-in [:items] #(resolve-account-references context %))
+      (assoc :entity-id (-> context :entity :id))))

 (defn- import-transaction
   [context transaction]
-  (let [to-create (-> transaction
-                      (update-in [:items] (fn [items]
-                                            (map (fn [item]
-                                                   (update-in item [:account-id] #(-> context :accounts (get %))))
-                                                 items)))
-                      (assoc :entity-id (:entity-id context)))]
-    (transactions/create (:storage context) to-create)
-    context)) ; Update anything in the context? don't want to include all transactions, as that can be many
+  (->> transaction
+       (prepare-transaction context)
+       (transactions/create (:storage context)))
+  ; Update anything in the context?
+  ; don't want to include all transactions,
+  ; as that can be many
+  context)

 (defn import-data
   "Reads the contents from the specified input and saves
@@ -49,9 +67,11 @@
   is created"
   [storage-spec user entity-name input source-type]
   (with-transacted-storage [s storage-spec]
-    (let [entity (entities/find-or-create s user  entity-name)
-          context (atom {:storage s
+    (let [context (atom {:storage s
                          :accounts {}
-                         :entity-id (:id entity)})]
-      (read-source source-type input (->Callback (fn [account] (swap! context #(import-account % account)))
-                                                 (fn [transaction] (swap! context #(import-transaction % transaction))))))))
+                         :entity (entities/find-or-create s user entity-name)})
+          callback (->Callback (fn [account]
+                                 (swap! context #(import-account % account)))
+                               (fn [transaction]
+                                 (swap! context #(import-transaction % transaction))))]
+      (read-source source-type input callback))))


refine import

refine import

--- src/clj_money/import.clj
+++ src/clj_money/import.clj
@@ -23,6 +23,18 @@
   (fn [source-type _ _]
     source-type))

+(defn- import-price
+  [{:keys [storage entity] :as context} price]
+  (let [commodity (->> {:exchange (name (:exchange price))
+                        :symbol (:symbol price)
+                        :entity-id (:id entity)}
+                       (commodities/search storage)
+                       first)]
+    (prices/create storage (-> price
+                               (assoc :commodity-id (:id commodity))
+                               (dissoc :exchange :symbol))))
+  context)
+
 (defn- find-commodity
   [context {:keys [exchange symbol]}]
   (->> context
@@ -167,23 +179,21 @@
   (import-budget context budget))

 (defmethod process-record :price
-  [{:keys [storage entity] :as context} price _]
-  (let [commodity (->> {:exchange (name (:exchange price))
-                        :symbol (:symbol price)
-                        :entity-id (:id entity)}
-                       (commodities/search storage)
-                       first)]
-    (prices/create storage (-> price
-                               (assoc :commodity-id (:id commodity))
-                               (dissoc :exchange :symbol)))))
+  [context price _]
+  (import-price context price))

 (defmethod process-record :commodity
   [{:keys [entity storage] :as context} commodity _]
   (let [to-create (assoc commodity :entity-id (:id entity))
         created (commodities/create storage to-create)]
-    (-> context
-        (update-in [:commodities] #((fnil conj []) % created))
-        (inc-and-update-progress :commodity))))
+    (update-in context [:commodities] #((fnil conj []) % created))))
+
+(def ^:private reportable-record-types
+  #{:commodity :price :account :transaction :budget})
+
+(defn- report-progress?
+  [record-type]
+  (reportable-record-types record-type))

 (defn process-callback
   "Top-level callback processing
@@ -199,8 +209,8 @@
                     record
                     (process-record record record-type)

-                    true
-                    (inc-and-update-progress % record-type))))
+                    (report-progress? record-type)
+                    (inc-and-update-progress record-type))))

 (defn import-data
   "Reads the contents from the specified input and saves


Ensure Kenny is in front

Ensure Kenny is in front

--- src/cljs/kenny/core.cljs
+++ src/cljs/kenny/core.cljs
@@ -84,7 +84,7 @@
   #js {:bottom (get-in app [:hero :position :bottom])
        :left (get-in app [:hero :position :left])
        :display (if (get-in app [:design-game]) "none" "block")
-       :z-index 10})
+       :zIndex 10})

 (defn hero-feet-coords [position]
   (let [bottom (position :bottom)


Add option for random meta-error.

Add option for random meta-error.

--- src/clojush/evaluate.clj
+++ src/clojush/evaluate.clj
@@ -30,7 +30,8 @@
      :size (minimize size of program)
      :compressibility (minimize ammount a program compresses compared to itself)
      :total-error (minimize total error)
-     :unsolved-cases (maximize number of cases with zero error)"
+     :unsolved-cases (maximize number of cases with zero error)
+     :random (a random floating-point value)"
   [ind {:keys [meta-error-categories error-threshold] :as argmap}]
   (let [meta-error-fn (fn [cat]
                         (cond
@@ -39,6 +40,7 @@
 ;                          (= cat :compressibility) 555 ;;TMH fix later
                           (= cat :total-error) (:total-error ind)
                           (= cat :unsolved-cases) (count (filter #(> % error-threshold) (:errors ind)))
+                          (= cat :random) (lrand)
                           :else (throw (Exception. (str "Unrecognized meta category: " cat)))))]
     (doall (map meta-error-fn meta-error-categories))))

@@ -122,3 +124,4 @@
                            )
             me (calculate-meta-errors new-ind argmap)]
         (assoc new-ind :meta-errors me)))))
+


nothing

nothing

--- src/codeitlater/core.clj
+++ src/codeitlater/core.clj
@@ -23,3 +23,4 @@

 (defn -main []
   (println (read-comments-inline (make-pattern testMark) "aaa//test")))
+


Исправления

Исправления

--- radiolamp-6P3S/src/r6p3s/cpt/select_time_interval.cljs
+++ radiolamp-6P3S/src/r6p3s/cpt/select_time_interval.cljs
@@ -1,6 +1,6 @@
 (ns r6p3s.cpt.select-time-interval
-  (:require-macros [cljs.core.async.macros :refer [go]])
-  (:require [cljs.core.async :refer [put! chan <!]]
+  #_(:require-macros [cljs.core.async.macros :refer [go]])
+  (:require ;;[cljs.core.async :refer [put! chan <!]]
             [om.core :as om :include-macros true]
             [om.dom :as dom :include-macros true]
             [r6p3s.core :as c]
@@ -48,7 +48,7 @@

-(defn component [app own {:keys [placeholder on-selected-fn] :as opts}]
+(defn component [app own {:keys [on-selected-fn] :as opts}]
   (reify
     om/IRender
     (render [_]


Fix bug

Fix bug

--- src/leiningen/highlight/rendering_rules/html.clj
+++ src/leiningen/highlight/rendering_rules/html.clj
@@ -10,7 +10,7 @@
 (defn- var-link [var content]
   (let [m (meta var)]
     [:a {:href (format "/ns/%s#%s" (str (:ns m)) (:name m))}
-     content]))
+     (str content)]))

 (defn- symbol-attr [x]
   {:data-symbol x})


Revert "use the proper md5 format"

Revert "use the proper md5 format"

This reverts commit 4ced5d5ba3c372abc0bb6aac6ee33e46b631fa57.

--- src/pc/assets.clj
+++ src/pc/assets.clj
@@ -185,7 +185,7 @@
                                    :key key
                                    :input-stream (java.io.ByteArrayInputStream. gzipped-bytes)
                                    :metadata {:content-type (mime-type-of file)
-                                              :content-md5 (md5/hex->base64 tag)
+                                              :content-md5 tag
                                               :content-encoding "gzip"
                                               :content-length (count gzipped-bytes)
                                               :cache-control "max-age=3155692"})]
@@ -220,7 +220,7 @@
                                             :input-stream (java.io.ByteArrayInputStream. gzipped-bytes)
                                             :metadata {:content-type (mime-type-of file-path)
                                                        :content-length (count gzipped-bytes)
-                                                       :content-md5 (md5/hex->base64 (byte-array->md5 gzipped-bytes))
+                                                       :content-md5 (byte-array->md5 gzipped-bytes)
                                                        :content-encoding "gzip"
                                                        :cache-control "max-age=3155692"})
                              (assoc acc path {:s3-key key :s3-bucket cdn-bucket})))


make sure that document-ids are numbers

make sure that document-ids are numbers

--- src/pc/server.clj
+++ src/pc/server.clj
@@ -57,7 +57,7 @@
           {:status 200
            :headers {"Content-Type" "image/svg+xml"}
            :body (render-layers layers)}))
-   (GET "/document/:document-id" [document-id :as req]
+   (GET ["/document/:document-id" :document-id #"[0-9]+"] [document-id :as req]
         (content/app (merge {:CSRFToken ring.middleware.anti-forgery/*anti-forgery-token*
                              :google-client-id (google-client-id)}
                             (when-let [cust (-> req :auth :cust)]


Replace get-iplayer with get_iplayer

Replace get-iplayer with get_iplayer

--- src/beebster_clj/core.clj
+++ src/beebster_clj/core.clj
@@ -16,7 +16,7 @@

 (def iplayer-info
-  ["get-iplayer" "-i"])
+  ["get_iplayer" "-i"])

 ;; keeping downloaded programmes longer than 30 days on your harddisk is not
@@ -81,7 +81,7 @@
          dir  (get config/config :download-folder)]
      (list term
            dir
-           "-e"  (apply str "get-iplayer" " --modes=" mode "1" " -g " index))))
+           "-e"  (apply str "get_iplayer" " --modes=" mode "1" " -g " index))))

 (defn get-url


Remove extraneous `str` call

Remove extraneous `str` call

--- src/braid/lib/upload.cljs
+++ src/braid/lib/upload.cljs
@@ -13,7 +13,7 @@
   (some-> url
           (string/replace
             @regex
-            (str "/api/upload/"))))
+            "/api/upload/")))

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


* src/clj/cljs/compiler.clj: CLJS-238: analysis should follow dependencies

--- src/clj/cljs/compiler.clj
+++ src/clj/cljs/compiler.clj
@@ -1097,6 +1097,18 @@
         :else {:env env :op :set! :form form :target targetexpr :val valexpr
                :children [targetexpr valexpr]})))))

+(defn ns->relpath [s]
+  (str (string/replace (munge s) \. \/) ".cljs"))
+
+(declare analyze-file)
+
+(defn analyze-deps [deps]
+  (doseq [dep deps]
+    (when-not (:defs (@namespaces dep))
+      (let [relpath (ns->relpath dep)]
+        (when (io/resource relpath)
+          (analyze-file relpath))))))
+
 (defmethod parse 'ns
   [_ env [_ name & args :as form] _]
   (let [docstring (if (string? (first args)) (first args) nil)
@@ -1109,12 +1121,14 @@
                       (into s xs))
                     s))
                 #{} args)
+        deps (atom #{})
         {uses :use requires :require uses-macros :use-macros requires-macros :require-macros :as params}
         (reduce (fn [m [k & libs]]
                   (assert (#{:use :use-macros :require :require-macros} k)
                           "Only :refer-clojure, :require, :require-macros, :use and :use-macros libspecs supported")
                   (assoc m k (into {}
                                    (mapcat (fn [[lib kw expr]]
+                                             (swap! deps conj lib)
                                              (case k
                                                (:require :require-macros)
                                                (do (assert (and expr (= :as kw))
@@ -1126,6 +1140,8 @@
                                                    (map vector expr (repeat lib)))))
                                            libs))))
                 {} (remove (fn [[r]] (= r :refer-clojure)) args))]
+    (when (seq @deps)
+      (analyze-deps @deps))
     (set! *cljs-ns* name)
     (require 'cljs.core)
     (doseq [nsym (concat (vals requires-macros) (vals uses-macros))]


Conveying this to delegate fns. Refs. CLJS-40

--- src/clj/cljs/compiler.clj
+++ src/clj/cljs/compiler.clj
@@ -341,12 +341,12 @@
         (print arglist)
         (dotimes [_ (- (count params) 2)] (print ")"))
         (println ");")
-        (println (str "return " delegate-name ".call(" (string/join ", " (cons "null" params)) ");")))
+        (println (str "return " delegate-name ".call(" (string/join ", " (cons "this" params)) ");")))
       (do
         (print (str "var " (last params) " = "))
         (print "cljs.core.seq(" arglist ");")
         (println ";")
-        (println (str "return " delegate-name ".call(" (string/join ", " (cons "null" params)) ");"))))
+        (println (str "return " delegate-name ".call(" (string/join ", " (cons "this" params)) ");"))))
     (print "})")))

 (defn emit-fn-method


CLJS-1130: :foreign-libs regression under Closure optimized builds

:foreign-libs support regressed, we never want to emit a goog.require
for a foreign lib in any other optimization setting other than :none

make the comment string clear on this point to avoid future simple
errors like this one.

--- src/clj/cljs/compiler.clj
+++ src/clj/cljs/compiler.clj
@@ -848,14 +848,18 @@
         (emitln "if(!COMPILED) " loaded-libs " = cljs.core.set();"))
       (doseq [lib (remove (set (vals seen)) (distinct (vals libs)))]
         (cond
-          (and (= :nodejs (get-in @env/*compiler* [:options :target]))
-               (ana/foreign-dep? lib))
-          ;; under node.js we load foreign libs globally
-          (let [{:keys [js-dependency-index options]} @env/*compiler*
-                ijs-url (get-in js-dependency-index [(name lib) :url])]
-            (emitln "cljs.core.load_file(\""
-              (str (io/file (util/output-directory options) (util/get-name ijs-url)))
-              "\");"))
+          (ana/foreign-dep? lib)
+          (let [{:keys [target optimizations]} (get @env/*compiler* :options)]
+            ;; we only load foreign libraries under optimizations :none
+            (when (= :none optimizations)
+              (if (= :nodejs target)
+                ;; under node.js we load foreign libs globally
+                (let [{:keys [js-dependency-index options]} @env/*compiler*
+                      ijs-url (get-in js-dependency-index [(name lib) :url])]
+                  (emitln "cljs.core.load_file(\""
+                    (str (io/file (util/output-directory options) (util/get-name ijs-url)))
+                    "\");"))
+                (emitln "goog.require('" (munge lib) "');"))))

           (-> libs meta :reload)
           (emitln "goog.require('" (munge lib) "', 'reload');")


remove unused schema var

remove unused schema var

--- src/clj/datasplash/bq.clj
+++ src/clj/datasplash/bq.clj
@@ -228,9 +228,7 @@
     (ptransform
      :write-bq-table-from-clj
      [^PCollection pcoll]
-     (let [schema (:schema options)
-           base-coll pcoll]
-       (write-bq-table-raw to safe-opts base-coll)))))
+     (write-bq-table-raw to safe-opts pcoll))))

 (defn write-bq-table
   ([to options ^PCollection pcoll]


bug fix

bug fix

--- src/clj/tictag/server.clj
+++ src/clj/tictag/server.clj
@@ -57,9 +57,9 @@
   (assert long-time)
   (db/add-tags db long-time tags (utils/local-time-from-long long-time)))

-(defn tag-ping-by-id [db {:keys [id tags]}]
+(defn tag-ping-by-id [db {:keys [id] :as args}]
   (let [long-time (db/pending-timestamp db id)]
-    (tag-ping-by-long-time db long-time tags)))
+    (tag-ping-by-long-time db (assoc args :long-time long-time))))

 (defn tag-last-ping [db {:keys [tags]}]
   (let [[last-ping] (db/get-pings


Fix cross counting; wasn't merging virtual edges with graph edges

--- src/cljs/fatlip/core.cljs
+++ src/cljs/fatlip/core.cljs
@@ -342,7 +342,7 @@
                    (map (fn [[seg-c characters]]
                           [seg-c (Edge. seg-c seg-c characters)]))
                    (into {})
-                   graph-edges)]
+                   (merge graph-edges))]
     (->> ordered
          (mapcat (fn [item]
                    (sort-by #(get next-order-map (:dest %))


working on functions in clojure

working on functions in clojure

--- src/clojure_noon/core.clj
+++ src/clojure_noon/core.clj
@@ -141,5 +141,62 @@
 ;; and use a vector everywhere else

 ;; sets are collections of unique values
-# {"jay sivakumaran" 22 :bananas}
-
+#{"jay sivakumaran" 22 :bananas}
+
+(hash-set 1 1 2 2 ) ;stores #{1 2} only stores each value once
+
+(conj #{:a :b} :b) ;conj in this case doesn't add anything to the hash-set since :b already exists within it
+
+(set [3 3 3 4 4 5]) ; creating a set using the set function and a vector
+
+;; contains? vs keyword vs get
+(contains? #{:a :b} :a) ;returns true
+(contains? #{:a :b} :3) ;returns false
+(contains? #{nil}) nil ;returns true
+
+;using a keyword
+(:a #{:a :b}) ; returns :a
+
+;using get
+(get #{:a :b} :a) ;returns :a
+(get #{:a nil} nil) ;returns nil
+(get #{:a :b} "jay sivakumaran") ;returns nil
+
+;contains? is better than get when testing specifically for membership
+
+;basic clojure philosophy - it's better to have 99 functions operate on one data structure than 9 functions on 9 data structures
+
+;now it's time to learn about functions - calling functions - defining functions - anonymous functions - returning functions
+
+;calling functions
+(+ 1 2 3 4) ;returns 10
+(* 1 2 3 4) ;returns 24
+(first [1 2 3 4]) ;returns 1
+
+;all clojure operations have the same structure - opening parenthesis, operator, operands, closing parenthesis
+(or + -) ;or returns the first truthy value so it returns plus which is the function of plus
+((or + -) 1 2 3) ;returns 6 - because the first expression returns the plus operator which then operates on the other operands (the numbers)
+((and (= 1 1) +) 1 2 3) ;returns 6 because and retuns the first falsey value or the last truthy value hence the + is returned
+
+;the following are not valid function calls
+(1 2 3 4) ;because numbers aren't functions you\ll get a java exception
+("test" 1 2 3) ; because string is not a valid operand
+
+;higher order functions can take functions as an argument or return a function
+(inc 1.1) ; returns 2.1
+(map inc [0 1 2 3]) ;this is map the function not the data structure
+
+;; function calls - macro calls - special forms (definitions and if expressions)
+(if good-mood
+  (tweet walking-on-sunshine-lyrics)
+  (tweet mopey-country-song-lyrics))
+
+;; clojure can't evaluate both the if clause and the else clause as it normally would with functions because if shoud be one or the other hence why it is a special form - good thing about clojure is that there aren't very many special forms
+
+;;defining  functions - defn + function name + a docstring describing the function (optional) + parameters listed in brackets + function body
+(defn too-enthusiastic
+  "Return a cheer that might be a bit too enthusiastic"
+  [name]
+  (str "OH MY. God. " name " YOU are most definitely like the best"))
+
+(too-enthusiastic "Link")


Moar.

Moar.

--- src/clojurecraft/core.clj
+++ src/clojurecraft/core.clj
@@ -23,6 +23,7 @@
      0x0E :playerdigging
      0x0F :playerblockplacement
      0x10 :holdingchange
+     0x11 :usebed
 })
 (def packet-ids (apply assoc {} (mapcat reverse packet-types)))

@@ -167,6 +168,15 @@
       (-write-byte conn (:holdingchange packet-ids))

       (-write-short conn slot))
+
+(defn write-packet-usebed [conn {eid :eid inbed :inbed x :x y :y z :z}]
+      (-write-byte conn (:usebed packet-ids))
+
+      (-write-int conn eid)
+      (-write-byte conn inbed)
+      (-write-int conn x)
+      (-write-byte conn y)
+      (-write-int conn z))

 ; Writing Wrappers -----------------------------------------------------------------
@@ -187,6 +197,7 @@
         (= packet-type :playerdigging)        (write-packet-playerdigging conn payload)
         (= packet-type :playerblockplacement) (write-packet-playerblockplacement conn payload)
         (= packet-type :holdingchange)        (write-packet-holdingchange conn payload)
+        (= packet-type :usebed)               (write-packet-usebed conn payload)
         )
       (flushc conn))

@@ -307,6 +318,14 @@
 (defn read-packet-holdingchange [conn]
       (-> {}
           (assoc :slot (-read-short conn))))
+
+(defn read-packet-usebed [conn]
+      (-> {}
+          (assoc :eid (-read-int conn))
+          (assoc :inbed (-read-byte conn))
+          (assoc :x (-read-int conn))
+          (assoc :y (-read-byte conn))
+          (assoc :z (-read-int conn))))

 ; Reading Wrappers -----------------------------------------------------------------
@@ -330,6 +349,7 @@
             (= packet-type :playerdigging)        (read-packet-playerdigging conn)
             (= packet-type :playerblockplacement) (read-packet-playerblockplacement conn)
             (= packet-type :holdingchange)        (read-packet-holdingchange conn)
+            (= packet-type :usebed)               (read-packet-usebed conn)
             :else (str "UNKNOWN PACKET TYPE: " packet-id)
             ))
         (println "\n\n\n")))


mark some unused args

mark some unused args

--- src/seri/core.clj
+++ src/seri/core.clj
@@ -29,7 +29,6 @@

   (gen-string-builder #(. %1 (toString))) yields the equivalent of
   `clojure.core.str`"
-
   [normalize-single-string]
   (fn ^String str**
     (^String [] "")
@@ -43,7 +42,6 @@

 (def escape-html (gen-string-builder toHtmlEscapedStr))

-
 ;;; ;;;;;;;;
 (defprotocol Serializable
   "The default implementation of Seri's serialization interface."
@@ -55,8 +53,8 @@
   nil (ser [_ _] "")
   String (ser [s _] s)
   Character (ser [c _] (str c))
-  Number (ser [n w] (safe n))           ; optimization
-  Named (ser [o w] (str o)))
+  Number (ser [n _] (safe n))           ; optimization
+  Named (ser [o _] (str o)))

 (defn extend-seri [typ fn]
   (extend typ Serializable {:ser fn}))