use a sliding buffer so events dont pile up

--- src/buyme_aggregation_backend/sources.clj
+++ src/buyme_aggregation_backend/sources.clj
@@ -1,6 +1,6 @@
 (ns buyme-aggregation-backend.sources
   (:require [buyme-aggregation-backend.db :as db]
-            [clojure.core.async :refer [chan go-loop <! alt!]]
+            [clojure.core.async :refer [chan go-loop <! alt! sliding-buffer]]
             [chime :refer [chime-ch]]
             [clj-time.core :as t]
             [clj-time.periodic :refer [periodic-seq]]
@@ -12,9 +12,12 @@
 (defn get-source-settings []
   (db/get-all-sources))

-(defn start-source []
+
+(defn start-source [source]
+  (info "starting source" source)
   (let [command-ch (chan)
-        fetch-timer-ch (chime-ch (rest (periodic-seq (t/now) (-> 5 t/seconds))))]
+        fetch-timer-ch (chime-ch (rest (periodic-seq (t/now) (-> 5 t/seconds)))
+                                 {:ch (chan (sliding-buffer 1))})]
     (go-loop
       [state :stopped]
       (let [new-state


fix typo

fix typo

--- src/cljs/gointermod/enrichment/views.cljs
+++ src/cljs/gointermod/enrichment/views.cljs
@@ -28,7 +28,7 @@
       "Error loading results. The server says: \""
       [:pre (:error result)]"\""
       (cond (re-find #"I didn't get any values for \[list\]" (:error result))
-        [:p "This may be because InterMine to be upgraded on the organisms's server"]
+        [:p "This error may have occurred because InterMine needs to be upgraded on the organisms's server"]
         )
    ])


revised problems/tozier/winkler01

revised problems/tozier/winkler01

--- src/clojush/problems/tozier/winkler01.clj
+++ src/clojush/problems/tozier/winkler01.clj
@@ -26,6 +26,12 @@
                (get counts "1" 0))
             (count-digits num)))))

+(defn kill-trailing-zeroes
+  "Returns an integer with all trailing zeroes stripped off"
+  [num]
+    (read-string (clojure.string/replace (str num) #"(0+)$" ""))
+  )
+
 (defn winkler-error-function
   "Returns the error function for Tozier's 01 problem."
   [number-test-cases]
@@ -37,9 +43,14 @@
             (push-item input :integer
               (make-push-state))))
              result-output (top-item :integer final-state)]
+          (when false (println  ;; change to true to print every result (which is awful)
+            (if (and (number? result-output) (pos? result-output))
+            (* input result-output)
+            "N/A")))
           (if (and (number? result-output) (pos? result-output))
-            (proportion-not-01 (* input result-output))
-            1000))))))
+            (proportion-not-01 (kill-trailing-zeroes (* input result-output)))
+            100)
+          )))))

 ; Atom generators
@@ -55,13 +66,13 @@

 ; Define the argmap
 (def argmap
-  {:error-function (winkler-error-function 100)
+  {:error-function (winkler-error-function 133)
    :atom-generators winkler-atom-generators
    :max-points 1000
    :max-genome-size-in-initial-program 500
    :evalpush-limit 2000
    :population-size 1000
-   :max-generations 300
+   :max-generations 500
    :parent-selection :lexicase
    :final-report-simplifications 1000
    })


some fixes of settings

some fixes of settings

--- src/clojush/problems/tozier/winkler01.clj
+++ src/clojush/problems/tozier/winkler01.clj
@@ -117,20 +117,23 @@
 ; Atom generators
 (def winkler-atom-generators
   (concat (take 100 (repeat 'in1))
-          (take 100 (repeat (fn [] (lrand-int 65536)))) ;Integer ERC [0,65536]
+          (take 50 (repeat (fn [] (lrand-int 65536)))) ;Integer ERC [0,65536]
           (registered-for-stacks [:integer :code :boolean :exec :vector_integer])))

 ; Define the argmap
 (def argmap
-  {:error-function (winkler-error-function-02 33) ;; change the error function to follow along...
+  {:error-function (winkler-error-function-02 44) ;; change the error function to follow along...
    :atom-generators winkler-atom-generators
    :max-points 1000
-   :max-genome-size-in-initial-program 300
+   :print-csv-logs true
+   :csv-columns [:generation :location :parent-uuids :genetic-operators :push-program-size :push-program :total-error :test-case-errors]
+   :csv-log-filename "log.csv"
+   :max-genome-size-in-initial-program 500
    :evalpush-limit 1000
    :population-size 1000
-   :max-generations 500
-   :parent-selection :tournament
+   :max-generations 1000
+   :parent-selection :lexicase
    :final-report-simplifications 1000
    })


Added FIXME for migrating formats correctly.

--- src/cmr/bootstrap/data/bulk_migration.clj
+++ src/cmr/bootstrap/data/bulk_migration.clj
@@ -137,6 +137,8 @@
   ([system provider-id  collection-id]
    (let [dataset-table (catalog-rest-dataset-table system provider-id)
          collection-table (metadata-db-concept-table system provider-id :collection)
+         ;; FIXME: Format is incorrect when copied over. Catalog REST has a constant like "ECHO10"
+         ;; but we expect application/echo10+xml
          stmt (format (str "INSERT INTO %s (id, concept_id, native_id, metadata, format, short_name, "
                            "version_id, entry_title, delete_time, revision_date) SELECT %s_seq.NEXTVAL,"
                            "echo_collection_id, dataset_id, compressed_xml, xml_mime_type, short_name,"


Less sleeping in GC test

Less sleeping in GC test

--- test/com/climate/claypoole_test.clj
+++ test/com/climate/claypoole_test.clj
@@ -575,10 +575,11 @@
   not guarantee that as a contract."
   [pmap-fn]
   (let [a (atom nil)
-        p (promise)
+        started (promise)
+        finish (promise)
         task-runner (future
                       (dorun
-                        (pmap-fn 3 deref
+                        (pmap-fn 1 deref
                                  (list
                                    ;; Have one task make a note when GC'd
                                    (delay
@@ -586,18 +587,20 @@
                                        #(reset! a :finalized)))
                                    (delay 1)
                                    (delay 2)
-                                   (delay 3)
-                                   p))))]
+                                   (delay (deliver started :started))
+                                   finish))))]
     ;; Let the tasks run
-    (Thread/sleep 100)
+    @started
     ;; Trigger GC
     (System/gc)
     ;; Wait for GC to run
-    (Thread/sleep 100)
+    (doseq [i (range 100)
+            :while (not @a)]
+      (Thread/sleep 1))
     ;; Verify that the task was GC'd
     (is (= @a :finalized))
     ;; Complete the map
-    (deliver p :done)
+    (deliver finish :done)
     @task-runner))

 (defn check-shuts-off


add test case for map-key

add test case for map-key

--- test/com/rpl/specter/core_test.cljc
+++ test/com/rpl/specter/core_test.cljc
@@ -1530,6 +1530,7 @@
 (deftest map-key-test
   (is (= {:b nil :c 3} (setval (s/map-key :a) :b {:c 3})))
   (is (= {:b 2} (setval (s/map-key :a) :b {:a 2})))
+  (is (= {:b 2} (setval (s/map-key :a) :b {:a 2 :b 1})))
   )

 #?(:clj


Three tests for the simple 'third' function

--- test/emender_jenkins/utils_test.clj
+++ test/emender_jenkins/utils_test.clj
@@ -126,3 +126,25 @@
             (catch Exception e
                 (is (nil? (get-exception-message e)))))))

+(deftest test-third-1
+    "Check the function clouseau.utils/third."
+    (testing "the function clouseau.utils/third."
+        (are [x y] (= x y)
+            3 (third [1 2 3])
+            3 (third [1 2 3 4 5])
+            3 (third '(1 2 3))
+            3 (third '(1 2 3 4 5)))))
+
+(deftest test-third-2
+    "Check the function clouseau.utils/third."
+    (testing "the function clouseau.utils/third."
+        (are [x y] (= x y)
+            nil (third [1 2])
+            nil (third '(1 2)))))
+
+(deftest test-third-not-NPE
+    "Check the function clouseau.utils/third."
+    (testing "the function clouseau.utils/third."
+        (are [x y] (= x y)
+            nil (third nil))))
+


Trying to understand 6.11 and how to convert it... :S

--- src/fpinscala/purely_functional_state.clj
+++ src/fpinscala/purely_functional_state.clj
@@ -298,4 +298,19 @@
   {:val val :next-state next-state})
 ;In addition, Clojure does not provide case classes and companion objects as Scala
 ;does so existing unit, map, map2, flat-map and sequnce does the job as
-;there is no instance you could invoke method on+;there is no instance you could invoke method on
+
+(defn flat-map-s
+  "flatMap for exercise 6.8 from FPINS but generalized to state"
+  [f g]
+  #(from-state (f %) :let [v s]
+             ((g v) s)))
+
+(defn map-via-flat-map-s
+  "map in terms of flatMap for exercise 6.9 of FPINS"
+  [s f]
+  (flat-map-s s (fn [x] (unit (f x)))))
+
+(defn map2-via-flat-map-s
+  [s1 s2 f]
+  (flat-map-s s1 (fn [a] (map-via-flat-map-s s2 #(f a %)))))


Doc string fix.

Doc string fix.

--- src/midje/internal_ideas/fact_context.clj
+++ src/midje/internal_ideas/fact_context.clj
@@ -1,5 +1,4 @@
-(ns ^{:doc "A way to keep track of the pertinent context of the current nested fact.
-            Currently, that is only the fact's description/doc-string"}
+(ns ^{:doc "A way to keep track of the pertinent context of the current nested fact."}
   midje.internal-ideas.fact-context
   (:use [clojure.string :only [join]]))


moving to amazonica api

moving to amazonica api

--- src/aws/volumes.clj
+++ src/aws/volumes.clj
@@ -13,8 +13,7 @@
   (:require
     [celestial.common :refer (import-logging )]
     [celestial.provider :refer (wait-for)]
-    [aws.sdk.ebs :as ebs]
-    [aws.sdk.ec2 :as ec2]
+    [amazonica.aws.ec2 :as ec2]
     [celestial.persistency.systems :as s]
     [aws.common :refer (with-ctx instance-desc creds image-id)]
     ))
@@ -22,13 +21,20 @@
 (import-logging)

 (defn image-desc [endpoint ami & ks]
-  (-> (ec2/describe-images (assoc (creds) :endpoint endpoint) (ec2/image-id-filter ami))
-      first (apply ks)))
+  (->
+    (ec2/describe-images (assoc (creds) :endpoint endpoint)
+       :image-ids [ami]) :images first (apply ks)
+      ))

 (defn wait-for-attach [endpoint instance-id timeout]
   (wait-for {:timeout timeout}
     #(= "attached" (instance-desc endpoint instance-id :block-device-mappings 0 :ebs :status))
     {:type ::aws:ebs-attach-failed :message "Failed to wait for ebs root device attach"}))
+
+(defn volume-desc [endpoint volume-id & ks]
+  (->
+   (with-ctx ec2/describe-volumes {:volume-ids [volume-id]}))
+    :volumes first (get-in ks))

 (defn handle-volumes
    "attached and waits for ebs volumes"
@@ -37,11 +43,14 @@
     (wait-for-attach endpoint instance-id [10 :minute]))
   (let [zone (instance-desc endpoint instance-id :placement :availability-zone)]
     (doseq [{:keys [device size]} (aws :volumes)]
-      (let [{:keys [volumeId]} (with-ctx ebs/create-volume size zone)]
-        (wait-for {:timeout [10 :minute]} #(= "available" (with-ctx ebs/state volumeId))
+      (let [{:keys [volume-id]} (with-ctx ec2/create-volume {:size size :availability-zone zone})]
+        (wait-for {:timeout [10 :minute]}
+           #(= "available" (volume-desc endpoint volume-id :state))
            {:type ::aws:ebs-volume-availability :message "Failed to wait for ebs volume to become available"})
-        (with-ctx ebs/attach-volume volumeId instance-id device)
-        (wait-for {:timeout [10 :minute]} #(= "attached" (with-ctx ebs/attachment-status volumeId))
+        (with-ctx ec2/attach-volume
+          {:volume-id volume-id :instance-id instance-id :device device})
+        (wait-for {:timeout [10 :minute]}
+           #(= "attached" (volume-desc endpoint volume-id :attachments 0 :state))
            {:type ::aws:ebs-volume-attach-failed :message "Failed to wait for ebs volume device attach"})))))

 (defn clear?
@@ -58,16 +67,9 @@
   (doseq [{:keys [ebs device-name]} (-> (instance-desc endpoint instance-id) :block-device-mappings rest)]
     (when (clear? device-name system-id)
       (trace "deleting volume" ebs)
-      (with-ctx ebs/detach-volume (ebs :volume-id))
+      (with-ctx ec2/detach-volume {:volume-id (ebs :volume-id)})
       (wait-for {:timeout [10 :minute]}
-        #(= "available" (with-ctx ebs/state  (ebs :volume-id)))
+        #(= "available" (with-ctx (volume-desc endpoint (ebs :volume-id) :state)))
         {:type ::aws:ebs-volume-availability
          :message "Failed to wait for ebs volume to become available"})
-      (with-ctx ebs/delete-volume (ebs :volume-id)))))
-
-(comment
-  (clojure.pprint/pprint
-    (celestial.model/set-env :dev
-                             (-> (instance-desc "ec2.eu-west-1.amazonaws.com" "i-a5a88de9") :block-device-mappings rest)
-                             ))
-  )
+      (with-ctx ec2/delete-volume {:volume-id (ebs :volume-id)}))))


-(defn moreover-comp)

-(defn moreover-comp)

--- src/babel/over.cljc
+++ src/babel/over.cljc
@@ -236,45 +236,6 @@
                                 (fail-path-between parent {:head child}))))))
           :fail)))))

-;; Might be useful to set the following variable to true,
-;; if doing grammar development and it would be unexpected
-;; to have a failing result from calling (moreover-comp)
-;; with certain arguments.
-(def ^:dynamic *throw-exception-if-failed-to-add-complement* false)
-
-(defn moreover-comp [parent child lexfn-sem-impl]
-  (log/trace (str "moreover-comp type parent: " (type parent)))
-  (log/trace (str "moreover-comp type comp:" (type child)))
-  (log/trace (str "moreover-comp: child cat: " (get-in child [:synsem :cat])))
-  (log/trace (str "moreover-comp: parent comp cat: " (get-in parent [:comp :synsem :cat])))
-
-  (let [result
-        (unifyc parent
-                {:comp child}
-                {:comp {:synsem {:sem (lexfn-sem-impl (get-in child '(:synsem :sem) :top))}}})]
-    (if (not (fail? result))
-      (do (log/trace "unification was successful.")
-          (merge {:comp-filled true}
-                 result))
-      ;; else: fail:
-      (do
-        (log/trace (str "moreover-comp: fail: " result))
-        (if (= false pre-check)
-          (log/warn (str "moreover-comp: pre-checked missed: fail-path-between:"
-                         (fail-path-between parent {:comp child}))))
-        (log/trace (str "moreover-comp: fail: child: " (get-in child [:rule] (get-in child [:synsem :sem :pred] :no-pred))))
-        (if (and
-             *throw-exception-if-failed-to-add-complement*
-             (get-in child '(:head)))
-          (throw
-           (exception
-            (let [fail-path (fail-path parent {:comp child})]
-              (str "failed to add complement: " (:rule child) "  to: phrase: " (:rule parent)
-                   ". Failed path was: " fail-path)))))
-        (log/trace (str "moreover-comp: complement synsem: " (strip-refs (get-in child '(:synsem) :top))))
-        (log/trace (str "moreover-comp:  parent value: " (strip-refs (get-in parent (fail-path result)))))
-        :fail))))
-
 (defn overh
   "add given head as the head child of the phrase: parent."
   [parent head]
@@ -331,7 +292,7 @@

 ;; Haskell-looking signature:
 ;; (parent:map) X (child:{set,seq,fs}) => list:map
-;; TODO: verify that the above commentn about the signature
+;; TODO: verify that the above comment about the signature
 ;; is still true.
 (defn overc [parent comp]
   "add given child as the comp child of the phrase: parent."
@@ -377,7 +338,9 @@
    true
    (let [check-result (comp-pre-checks parent comp)
          result (if check-result :fail
-                    (moreover-comp parent comp null-sem-impl))
+                      (unifyc parent
+                              {:comp comp}
+                              {:comp {:synsem {:sem (null-sem-impl (get-in comp '(:synsem :sem) :top))}}}))
          is-fail? (fail? result)]
      (if (not is-fail?)
        (do


Remove side effect in log statement

Remove side effect in log statement

--- src/onyx/peer/task_lifecycle.clj
+++ src/onyx/peer/task_lifecycle.clj
@@ -151,7 +151,6 @@
   (run! pub/poll-heartbeats! (m/publishers (get-messenger state)))
   (advance state))

-
 ;; In the future this shouldn't be neccesary
 (defn strip-coordinator [src-peer-id]
   (if (vector? src-peer-id)
@@ -161,15 +160,15 @@
 (defn notify-dead-peers! [state timed-out-peer-ids]
   (let [replica (get-replica state)
         {:keys [id outbox-ch]} (get-event state)]
-    (info "Should be killing " (vec timed-out-peer-ids)
-          (run! (fn [peer-id]
-                  (let [entry {:fn :leave-cluster
-                               :peer-parent id
-                               :args {:id peer-id
-                                      :group-id (get-in replica [:groups-reverse-index peer-id])}}]
-                    (info "Peer timed out with no heartbeats. Emitting leave cluster." entry)
-                    (>!! outbox-ch entry)))
-                timed-out-peer-ids))
+    (info "Should be killing " (vec timed-out-peer-ids))
+    (run! (fn [peer-id]
+            (let [entry {:fn :leave-cluster
+                         :peer-parent id
+                         :args {:id peer-id
+                                :group-id (get-in replica [:groups-reverse-index peer-id])}}]
+              (info "Peer timed out with no heartbeats. Emitting leave cluster." entry)
+              (>!! outbox-ch entry)))
+          timed-out-peer-ids)
     ;; FIXME, needs to jump into a mode here where we wait it out for a new replica
     (Thread/sleep 1000)
     (info "Replica is" replica)))


Close lifecycle chans before waiting for completion

--- src/onyx/peer/task_lifecycle.clj
+++ src/onyx/peer/task_lifecycle.clj
@@ -371,6 +371,8 @@
       (l-ext/close-lifecycle-resources* event)

       (close! (:seal-ch component))
+      (close! (:release-messages-ch component))
+      (close! (:forward-completion-ch component))

       ;; Ensure task operations are finished before closing peer connections
       (<!! (:task-lifecycle-ch component))


Cleanup unused event destructuring

Cleanup unused event destructuring

--- src/onyx/peer/task_lifecycle.clj
+++ src/onyx/peer/task_lifecycle.clj
@@ -200,8 +200,8 @@
         :else
         event))

-(defn ack-barriers [{:keys [task-map messenger id pipeline barriers] :as event}]
-  (if (and (= :output (:onyx/type task-map))
+(defn ack-barriers [{:keys [task-type messenger] :as event}]
+  (if (and (= :output task-type)
            (m/all-barriers-seen? messenger))
      (assoc event :messenger (m/ack-barrier messenger))
     event))
@@ -210,15 +210,16 @@
   (let [entry (entry/create-log-entry :exhaust-input {:job job-id :task task-id})]
     (>!! (:outbox-ch event) entry)))

-(defn receive-acks [{:keys [task-map messenger id pipeline barriers opts] :as event}]
-  (if (= :input (:onyx/type task-map))
-    (let [new-messenger (m/receive-acks messenger)]
+(defn receive-acks [{:keys [task-type] :as event}]
+  (if (= :input task-type)
+    (let [messenger (:messenger event)
+          new-messenger (m/receive-acks messenger)]
       (if-let [ack-barrier (m/all-acks-seen? new-messenger)]
         ;; TODO: Should checkpoint offsets here
-        (let [completed? (get-in barriers [(:replica-version ack-barrier) (:epoch ack-barrier) :completed?])]
+        (let [completed? (get-in (:barriers event) [(:replica-version ack-barrier) (:epoch ack-barrier) :completed?])]
           (when completed?
             (complete-job event)
-            (Thread/sleep (arg-or-default :onyx.peer/drained-back-off opts)))
+            (Thread/sleep (arg-or-default :onyx.peer/drained-back-off (:peer-opts event))))
           (assoc event :messenger (m/flush-acks messenger)))
         event))
     event))
@@ -296,8 +297,7 @@
         (throw e)))))

 (defrecord TaskInformation
-    [id log job-id task-id
-     workflow catalog task flow-conditions windows filtered-windows triggers lifecycles task-map]
+  [id log job-id task-id workflow catalog task flow-conditions windows filtered-windows triggers lifecycles task-map]
   component/Lifecycle
   (start [component]
     (let [catalog (extensions/read-chunk log :catalog job-id)


Take the count first.

Take the count first.

--- src/onyx/queue/hornetq_utils.clj
+++ src/onyx/queue/hornetq_utils.clj
@@ -20,7 +20,7 @@

     (let [producer (.createProducer session queue-name)]
       (.start session)
-      (doseq [n (range messages)]
+      (doseq [n (range (count messages))]
         (when (zero? (mod n echo))
           (info (format "[HQ Util] Wrote %s segments" n)))
         (let [message (.createMessage session true)]


Apply changes suggested by @frenchy64

Apply changes suggested by @frenchy64

--- src/puppetlabs/trapperkeeper/internal.clj
+++ src/puppetlabs/trapperkeeper/internal.clj
@@ -455,18 +455,19 @@
   [app-context :- (schema/atom a/TrapperkeeperAppContext)]
   (log/info (i18n/trs "Beginning shutdown sequence"))
   (let [{:keys [ordered-services shutdown-channel lifecycle-worker]} @app-context
-        result-chan (async/promise-chan (map #(filter (partial not= :ok) %)))
+        errors-chan (async/promise-chan)
         shutdown-fn (fn [] (let [results
                                  (doall
-                                  (map (fn [[service-id s]]
-                                         (try
-                                           (run-lifecycle-fn! app-context s/stop "stop" service-id s)
-                                           :ok
-                                           (catch Exception e
-                                             (log/error e (i18n/trs "Encountered error during shutdown sequence"))
-                                             e)))
-                                       (reverse ordered-services)))]
-                             (async/put! result-chan results)))]
+                                  (keep
+                                   (fn [[service-id s]]
+                                     (try
+                                       (run-lifecycle-fn! app-context s/stop "stop" service-id s)
+                                       nil
+                                       (catch Exception e
+                                         (log/error e (i18n/trs "Encountered error during shutdown sequence"))
+                                         e)))
+                                   (reverse ordered-services)))]
+                             (async/put! errors-chan results)))]
     (log/trace (i18n/trs "Putting shutdown message on shutdown channel."))
     (async/>!! shutdown-channel {:type :shutdown
                                  :task-function shutdown-fn})
@@ -475,7 +476,8 @@
     (if (not (nil? (async/<!! lifecycle-worker)))
       (do
         (log/info (i18n/trs "Finished shutdown sequence"))
-        (async/<!! result-chan))
+        ;; deliver errors from stopped services if any
+        (async/<!! errors-chan))
       ;; else, the read from the channel returned a nil because it was closed,
       ;; indicating that there was already a shutdown in progress, and thus the
       ;; redundant shutdown request was ignored
@@ -618,13 +620,13 @@
       (a/stop [this]
         (a/stop this false))
       (a/stop [this throw?]
-        (if-let [errors (not-empty (shutdown! app-context))]
-          (let [msg (i18n/trs "Error during app shutdown!")
-                e (ex-info msg {:errors errors})]
-            (log/error e msg)
-            (when throw?
-              (throw e)))
-          this))
+        (let [errors (shutdown! app-context)]
+          (if (and throw? (seq errors))
+            (let [msg (i18n/trs "Error during app shutdown!")
+                  e (ex-info msg {:errors errors})]
+              (log/error e msg)
+              (throw e))
+            this)))
       (a/restart [this]
         (try
           (run-lifecycle-fns app-context s/stop "stop" (reverse ordered-services))


Routes Query Parameters for Start and End Dates

--- src/restaurant_inspections_api/routes.clj
+++ src/restaurant_inspections_api/routes.clj
@@ -7,23 +7,22 @@
            (GET "/" [] (srv/home))
            (GET "/get/:id" [id] (srv/get-details id))
            (GET "/list-counties" [] (srv/get-dist-counties))
-           (GET ["/location/:start-date/:end-date/:zips"
-                 :zips #"[^/]+"]
-                [start-date end-date zips]
-                (srv/location start-date end-date zips))
-           (GET ["/name/:start-date/:end-date/:name"
+           (GET ["/location/:zips" :zips #"[^/]+"]
+                [startDate endDate zips]
+                (srv/location startDate endDate zips))
+           (GET ["/name/:name"
                  :name #"[^/]+"]
-                [id start-date end-date name]
-                (srv/get-name start-date end-date name))
-           (GET ["/name/:start-date/:end-date/:name/:zips"
+                [startDate endDate name]
+                (srv/get-name startDate endDate name))
+           (GET ["/name/:name/:zips"
                  :name #"[^/]+"
                  :zips #"[^/]+"]
-                [id start-date end-date name zips]
-                (srv/get-name start-date end-date name zips))
-           (GET "/district/:start-date/:end-date/:id"
-                [start-date end-date id]
-                (srv/district id start-date end-date))
-           (GET "/county/:start-date/:end-date/:id"
-                [start-date end-date id]
-                (srv/county id start-date end-date)))
+                [startDate endDate name zips]
+                (srv/get-name startDate endDate name zips))
+           (GET "/district/:id"
+                [startDate endDate id]
+                (srv/district id startDate endDate))
+           (GET "/county/:id"
+                [startDate endDate id]
+                (srv/county id startDate endDate)))


bold username in android

bold username in android

--- src/status_im/components/drawer/view.cljs
+++ src/status_im/components/drawer/view.cljs
@@ -54,7 +54,7 @@
      [text-input
       {:placeholder    placeholder
        :style          (st/name-input-text (s/valid? ::v/name (or new-name current-name)))
-       :font           (if platform/ios? :medium :default)
+       :font           :medium
        :default-value  (or new-name current-name)
        :on-change-text #(rf/dispatch [:set-in [:profile-edit :name] %])
        :on-end-editing #(do


gh-25: refactoring unique keyfn to a helper fn

--- src/untangled_spec/reporters/browser.cljs
+++ src/untangled_spec/reporters/browser.cljs
@@ -12,6 +12,10 @@
     [untangled-spec.reporters.impl.browser :as impl]
     [untangled-spec.reporters.impl.diff :as diff]
     [pushy.core :as pushy]))
+
+(defn unique-key-fn [ns-str]
+  (let [c (atom 0)]
+    #(str ns-str "_" (swap! c inc))))

 (defui ^:once Foldable
   Object
@@ -31,8 +35,7 @@
             (str title)))
         (dom/div #js {:className (when folded? "hidden")}
           value)))))
-(def ui-foldable (om/factory Foldable {:keyfn (let [c (atom 0)]
-                                                #(str "foldable-" (swap! c inc)))}))
+(def ui-foldable (om/factory Foldable {:keyfn (unique-key-fn "foldable")}))

 (defui ^:once ResultLine
   Object
@@ -50,8 +53,7 @@
                                    (if folded? (str value) title))
                           :value (if stack stack (if-not folded? (html-edn value)))
                           :classes (if stack "stack")})})))))))
-(def ui-result-line (om/factory ResultLine {:keyfn (let [c (atom 0)]
-                                                     #(str "result-line-" (swap! c inc)))}))
+(def ui-result-line (om/factory ResultLine {:keyfn (unique-key-fn "result-line")}))

 (defui ^:once HumanDiffLines
   Object
@@ -70,8 +72,7 @@
           (dom/tr #js {:className "actual"}
             (dom/td nil "got: ")
             (dom/td nil (html-edn got))))))))
-(def ui-human-diff-lines (om/factory HumanDiffLines {:keyfn (let [c (atom 0)]
-                                                              #(swap! c inc))}))
+(def ui-human-diff-lines (om/factory HumanDiffLines {:keyfn (unique-key-fn "human-diff-lines")}))

 (defui ^:once HumanDiff
   Object
@@ -93,8 +94,7 @@
         (dom/td nil)
         (dom/tr #js {:className "human-diff"}
           (dom/td nil "DIFFS:"))))))
-(def ui-human-diff (om/factory HumanDiff {:keyfn (let [c (atom 0)]
-                                                   #(str "human-diff-" (swap! c inc)))}))
+(def ui-human-diff (om/factory HumanDiff {:keyfn (unique-key-fn "human-diff")}))

 (defui ^:once TestResult
   Object


Can handle text IDs now

Can handle text IDs now

So that any data type can be used for a database realtime table

--- src/webapp/framework/server/systemfns.clj
+++ src/webapp/framework/server/systemfns.clj
@@ -1119,6 +1119,17 @@
       (Integer. find-num)
       s)))

+(defn get-id-type [ column-type ]
+  (do
+    (println (str "*******COLTYPE:" column-type ":"))
+    (cond
+    (= column-type "integer")                     "INTEGER"
+    (= column-type"character")                    "TEXT"
+    (= column-type"character varying")            "TEXT"
+
+    :else                                         "integer"
+    )
+  ))

@@ -1130,7 +1141,9 @@
 (defn process-log-entry [ realtime-log-entry ]

   (let [
-        id               (parse-id  (get realtime-log-entry :record_id))
+        id-type          (get-id-type (get realtime-log-entry :record_id_type))
+        id               (cond (= id-type "INTEGER")  (parse-id  (get realtime-log-entry :record_id))
+                               (= id-type "TEXT")     (get realtime-log-entry :record_id))
         db-table         (get realtime-log-entry :record_table_name)
         ]
     ;(println (str "**** Processing realtime record change: "))


Run fence unit test automatically.

Run fence unit test automatically.

--- src/cbfg/fence.cljs
+++ src/cbfg/fence.cljs
@@ -1,7 +1,8 @@
 (ns cbfg.fence
-  (:require-macros [cbfg.ago :refer [achan achan-buf aclose aalts
+  (:require-macros [cljs.core.async.macros :refer [go]]
+                   [cbfg.ago :refer [achan achan-buf aclose aalts
                                      ago ago-loop aput atake atimeout]])
-  (:require [cljs.core.async :refer [onto-chan]]))
+  (:require [cljs.core.async :refer [chan onto-chan <! sliding-buffer]]))

 ;; Explaining out-of-order replies and fencing with a diagram.  Client
 ;; sends a bunch of requests (r0...r4), where r2 is fenced (F).  "pX"
@@ -96,16 +97,13 @@
                    in-msgs]
   (let [in (achan-buf actx in-ch-size)
         out (achan-buf actx out-ch-size)
-        fdp (make-fenced-pump actx in out max-inflight)
-        gch (ago-loop test-out actx [acc nil]
+        fdp (make-fenced-pump actx in out max-inflight)]
+    (onto-chan in in-msgs)
+    (ago-loop test-out actx [acc nil]
               (let [result (atake test-out out)]
                 (if result
-                  (do (println "Output result: " result)
-                      (recur (conj acc result)))
-                  (do (println "Output channel closed")
-                      (reverse acc)))))]
-    (onto-chan in in-msgs)
-    gch))
+                  (recur (conj acc result))
+                  (reverse acc))))))

 (defn test [actx]
   (let [reqs [{:rq #(test-add-two % 1 200)}
@@ -135,3 +133,8 @@
                   (atake test test-helper-out)
                   res)
                 '(6 3 12 40 41 42 43 44 6 7 8 0 1 11 11 9 32)]]))))
+
+(let [last-id (atom 0)
+      gen-id #(swap! last-id inc)]
+  (go (println (<! (test [{:gen-id gen-id
+                           :event-ch (chan (sliding-buffer 1))}])))))


Fix creation of argument completer.

Fix creation of argument completer.

--- src/cli4clj/cli.clj
+++ src/cli4clj/cli.clj
@@ -69,20 +69,19 @@
       (let [fn-args (get-in cmds [k :fn-args])
             completion-hint (get-in cmds [k :completion-hint])]
         (if (or (not (nil? fn-args))
-                  (not (nil? completion-hint)))
+                (not (nil? completion-hint)))
           (conj v
                 (ArgumentCompleter.
                   [(StringsCompleter. (conj (vec (map name (cmd-aliases k))) (name k)))
                    (proxy [Completer] []
                      (complete [buffer cursor candidates]
                        (if (not (nil? fn-args))
-                         (.add candidates (str "Arguments: "
-                                               fn-args
-                                               (if (not (nil? completion-hint))
-                                                 "\n"))))
+                         (.add candidates (str "Arguments: " fn-args)))
                        (if (not (nil? completion-hint))
                          (.add candidates (str completion-hint)))
-                       (.add candidates "")
+                       (if (or (not (nil? fn-args))
+                               (not (nil? completion-hint)))
+                         (.add candidates ""))
                        0))]))
           v)))
     []


Use customized skip-whitespace to make GraalVM happy.

--- src/cli4clj/cli.clj
+++ src/cli4clj/cli.clj
@@ -73,6 +73,30 @@
             (intern cli-fns-ns (symbol (name cmd-name)) (:fn cmd-def))))))
     (refer cli-fns-ns)))

+(defn skip-whitespace
+;;; The code for this function was largely taken from
+;;; https://github.com/clojure/clojure/blob/b182982007df934394f0bc68b3a238ca9f200dd1/src/clj/clojure/main.clj#L120
+;;; which is copyrighted as:
+;;; ;; Copyright (c) Rich Hickey All rights reserved. The use and
+;;; ;; distribution terms for this software are covered by the Eclipse Public
+;;; ;; License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) which can be found
+;;; ;; in the file epl-v10.html at the root of this distribution. By using this
+;;; ;; software in any fashion, you are agreeing to be bound by the terms of
+;;; ;; this license. You must not remove this notice, or any other, from this
+;;; ;; software.
+;;; ;; Originally contributed by Stephen C. Gilardi
+;;;
+;;; Changes aim at "making graalvm happy" and include::
+;;; - Add type hints.
+;;; - Remove "readLine" case.
+  [#^PushbackReader s]
+  (loop [c (.read s)]
+	(cond
+	  (= c (int \newline)) :line-start
+	  (= c -1) :stream-end
+	  (or (Character/isWhitespace (char c)) (= c (int \,))) (recur (.read s))
+	  :else (do (.unread s c) :body))))
+
 (defn create-repl-read-fn
   "This function creates a function that is intended to be used as repl read function.
    The created read function is largely based on the existing repl read function:
@@ -89,7 +113,7 @@
     (fn [request-prompt request-exit]
       (try
         (or ({:line-start request-prompt :stream-end request-exit}
-             (main/skip-whitespace *in*))
+              (skip-whitespace *in*))
             (loop [v []]
               (let [input (try
                             (read {:read-cond :allow} *in*)
@@ -105,7 +129,7 @@
                   (do
                     (main/skip-if-eol *in*)
                     input)
-                  (if (= :line-start (main/skip-whitespace *in*))
+                  (if (= :line-start (skip-whitespace *in*))
                     (if (and (symbol? input)
                              (some #(= (keyword input) %) quit-commands))
                       request-exit


added invariant anchor tag detection. dangerous to use

--- src/crawler/dom.clj
+++ src/crawler/dom.clj
@@ -300,17 +300,36 @@
 on the page that we are interested in.
 The returned item is the record nodes"
   [xpaths page-src]
-  (map
-   #(xpath->records % (html->xml-doc page-src))
-   (:xpaths
-    (let [xml-doc (html->xml-doc page-src)]
-      (reduce
-       (fn [acc v]
-         (let [v-records (xpath->records v xml-doc)]
-           (if (some #(same-node-set? v-records %)
-                     (:record-sets acc))
-             acc
-             (merge-with concat acc {:xpaths [v] :record-sets [v-records]}))))
-       {:xpaths      []
-        :record-sets []}
-       xpaths)))))
+  (first ;;; big assumption here.!!!! FIX
+   (map
+    #(xpath->records % (html->xml-doc page-src))
+    (:xpaths
+     (let [xml-doc (html->xml-doc page-src)]
+       (reduce
+        (fn [acc v]
+          (let [v-records (xpath->records v xml-doc)]
+            (if (some #(same-node-set? v-records %)
+                      (:record-sets acc))
+              acc
+              (merge-with concat acc {:xpaths [v] :record-sets [v-records]}))))
+        {:xpaths      []
+         :record-sets []}
+        xpaths))))))
+
+;; Node-set operations.
+(defn node-set-anchor-invariants
+  "In a collection of node objects, the local DOM
+can have invariant anchor-tags (in text and not targets).
+We check just the text representation of the subtree and nuke it. Say
+share, save, hide links in a reddit record.
+A node in a node-set is an org.w3c.<blah blah>.Node object"
+  [node-set]
+  (let [node-anchors (map #($x:text+ ".//a" %) node-set)]
+    (reduce
+     (fn [acc xs]
+       (if (empty? acc)
+         xs
+         (filter
+          #(some #{%} acc)
+          xs)))
+     node-anchors)))


add configurable and final source dump

add configurable and final source dump

--- src/crison/core.clj
+++ src/crison/core.clj
@@ -29,6 +29,13 @@
       (wc/get-screenshot driver :file s-file)))
   ([] (screenshot nil)))

+(defn source
+  ([name]
+   (let [nm (if name (str "-" name) "")
+         s-file (str *output-dir* "/" (date) "_" (.getName *crison-file*) "-source" nm ".txt")]
+      (spit s-file (wc/page-source driver))))
+  ([] (source nil)))
+
 (defn title [] (wc/title driver))

 (defn title? [x] (is (= x (title)) x))
@@ -42,7 +49,10 @@

 (defmulti decode (fn[x] (ffirst x)))

-(defmethod decode :url! [x] (go (:url! x)) (screenshot (:screenshot x)))
+(defmethod decode :url! [x]
+  (go (:url! x))
+  (screenshot (:screenshot x))
+  (source (:source x)))

 (defmethod decode :click! [x]
   (let [e (:click! x)]
@@ -50,11 +60,11 @@
       (-> driver (wc/find-element {:id e}) wc/click)
       (-> driver (wc/find-element e) wc/click))
     (Thread/sleep 2000)
-    (screenshot (:screenshot x))))
+    (screenshot (:screenshot x))
+    (source (:source x))))

 (defn compute-fill [{:keys [fill-submit!] :as x}]
   (let [head (butlast fill-submit!)]
-    (println "head : " head)
     (doseq [e head]
       (let [txt-val (:text! e)
             field (dissoc e :text!)]
@@ -84,7 +94,8 @@
     (doseq [f fs]
       (binding [*crison-file* f]
         (doseq [t (read-string (slurp f))] (decode t))
-        (screenshot)))))
+        (screenshot)
+        (source)))))

 (defn drive [input-d output-d]
   (binding [*input-dir* input-d


Removing some log statements

Removing some log statements

--- src-cljs/app/main.cljs
+++ src-cljs/app/main.cljs
@@ -116,7 +116,6 @@
     (val ($ "#hour") (pad hour))
     (val ($ "#minute") (pad (.getMinutes datetime)))
     (val ($ "#meridian") meridian)
-    (println (.toString datetime))
     (.datepicker ($ "#datepicker") "update" datetime)))

 (add-watch selected-time :_ on-selected-time-change)
@@ -151,7 +150,6 @@
         new-time (doto selected-date
                     (.setMinutes (.getMinutes datetime))
                     (.setHours (.getHours datetime)))]
-    (println (.toString new-time))
     (reset! selected-time (.getTime new-time))
     (show-closest-snapshot!)))

@@ -216,7 +214,7 @@

 (defn init-snapshot-list []
   (->> (.-SNAPSHOT_LIST js/window) ; server injected to this in a <script>
-       ; (js->clj)
+       ; (js->clj) ; TODO - Modify server to just send EDN and revert back to using native clojure types
        ; (clojure.walk/keywordize-keys)
        (reset! snapshot-list)))


operations: running kibit and cleaning

operations: running kibit and cleaning

--- src/app/operations.clj
+++ src/app/operations.clj
@@ -20,15 +20,15 @@
   (getQName x))

 (defn resultToStrings [resultRow]
-  (into [] (map toString resultRow)))
+  (vec (map toString resultRow)))

 (defn resultsToStrings [results]
   (map resultToStrings results))

 (defn getN [l ind]
-  (if (= ind 0)
+  (if (zero? ind)
     (first l)
-    (getN (rest l) (- ind 1))))
+    (getN (rest l) (dec ind))))

 (def columnSeparator " | ")

@@ -47,10 +47,10 @@
       (conj
         acc
         (columnLength (first headersStrings) resultsStrings ind))
-      (+ 1 ind))))
+      (inc ind))))

 (defn columnLengths [headersStrings, resultsStrings]
-  (into [] (columnLengthsHelper headersStrings resultsStrings [] 0)))
+  (vec (columnLengthsHelper headersStrings resultsStrings [] 0)))

 (defn padStr [s len]
   (if (>= (.length s) len)
@@ -60,15 +60,14 @@
 (defn rowStr [lengths values]
   (let
     [paddedValues (map (fn [l v] (padStr v l)) lengths values)]
-    (apply str
-      (interpose columnSeparator paddedValues))))
+    (clojure.string/join columnSeparator paddedValues)))

 (defn sum [v]
   (apply + v))

 (defn separatorStr [lengths]
   (let [sumLenRows (sum lengths)
-        sumLenSeparators (* (- (.length lengths) 1) (.length columnSeparator))
+        sumLenSeparators (* (dec (.length lengths)) (.length columnSeparator))
         n (+ sumLenRows sumLenSeparators)]
     (clojure.string/join (repeat n "-"))))

@@ -76,11 +75,10 @@
   (let [resultsStrings (resultsToStrings results),
         headersStrings (resultToStrings headers),
         colLengths (columnLengths headersStrings resultsStrings)]
-    (do
       (println (rowStr colLengths headersStrings))
       (println (separatorStr colLengths))
       (doall (for [r resultsStrings]
-        (println (rowStr colLengths r)))))))
+        (println (rowStr colLengths r))))))

 (defn printOperation [operation cus threshold]
   (let [headers (.headers operation),
@@ -112,7 +110,7 @@
     (subs s 1)
     (= :onEnd cutOn)
     (try
-      (subs s 0 (- (.length s) 1))
+      (subs s 0 (dec (.length s)))
       (catch Exception e (throw (Exception. "Caspita..."))))
     :else
     (throw (Exception. "cutOn should be :onStart or :onEnd"))))
@@ -145,7 +143,7 @@

 (defn printParam [printer p]
   (let
-    [fmtStr (str "%-" (- (:len p) 1) "s")]
+    [fmtStr (str "%-" (dec (:len p)) "s")]
     (print (format fmtStr (:name p)) " | ")))

 (defn printSeparator [printer params]


allow paragraph-style printing (if :as-numbered-list = false)

--- src/babel/english.cljc
+++ src/babel/english.cljc
@@ -97,8 +97,10 @@
   ([input model]
    (parse/parse (preprocess input) model)))

-(defn sentences [ & [count spec model]]
-  (let [count (or (Integer. count) 100)
+(defn sentences [ & [count as-numbered-list spec model]]
+  (let [as-numbered-list (or (nil? as-numbered-list)
+                             (= as-numbered-list "true"))
+        count (or (Integer. count) 100)
         model (or model (medium))
         spec (or (and spec
                       (unifyc spec {:modified false}))
@@ -118,5 +120,13 @@
                         (str (string/capitalize (nth fo 0))
                              (string/join "" (rest (vec fo)))
                              "."))]
-                  (println (str (+ 1 num) ". " to-print)))))
+                  (cond
+                    as-numbered-list
+                    (println (str (+ 1 num) "." to-print))
+
+                    (= 0 (mod num 7))
+                    (print (str "\n\t" to-print " "))
+
+                    true
+                    (print (str to-print " "))))))
             (range 0 count)))))


Mark Yale.

Mark Yale.

--- src/clj/game/cards.clj
+++ src/clj/game/cards.clj
@@ -1185,10 +1185,6 @@
    "Lucky Find"
    {:effect (effect (gain :credit 9))}

-   "MaxX: Maximum Punk Rock"
-   {:events {:runner-turn-begins {:msg "trash the top 2 cards from Stack and draw 1 card"
-                                  :effect (effect (mill 2) (draw))}}}
-
    "Magnum Opus"
    {:abilities [{:cost [:click 1] :effect (effect (gain :credit 2)) :msg "gain 2 [Credits]"}]}

@@ -1198,6 +1194,24 @@
    "Manhunt"
    {:events {:successful-run {:once :per-turn :trace {:base 2 :msg "give the Runner 1 tag"
                                                       :effect (effect (gain :runner :tag 1))}}}}
+
+   "Mark Yale"
+   {:events {:agenda-counter-spent {:effect (effect (gain :credit 1))
+                                    :msg "gain 1 [Credits]"}}
+    :abilities [{:label "Trash to gain 2 [Credits]"
+                 :msg "gain 2 [Credits]"
+                 :effect (effect (gain :credit 2) (trash card))}
+                {:label "Spend an agenda counter to gain 2 [Credits]"
+                 :effect (req (resolve-ability
+                                state side
+                                {:prompt "Select an agenda with a counter"
+                                 :choices {:req #(and (= (:type %) "Agenda")
+                                                      (:counter %))}
+                                 :effect (req (add-prop state side target :counter -1)
+                                              (gain state :corp :credit 2)
+                                              (trigger-event state side :agenda-counter-spent card))
+                                 :msg (msg "spend an agenda token on " (:title target) " and gain 2 [Credits]")}
+                                card nil))}]}

    "Marked Accounts"
    {:abilities [{:cost [:click 1] :msg "store 3 [Credits]"
@@ -1212,6 +1226,10 @@
    {:choices {:max 3 :req #(and (has? % :type "Program") (= (:zone %) [:hand]))}
     :msg (msg "install " (join ", " (map :title targets)))
     :effect (req (doseq [c targets] (runner-install state side c)))}
+
+   "MaxX: Maximum Punk Rock"
+   {:events {:runner-turn-begins {:msg "trash the top 2 cards from Stack and draw 1 card"
+                                  :effect (effect (mill 2) (draw))}}}

    "Medical Research Fundraiser"
    {:effect (effect (gain :credit 8) (gain :runner :credit 3))}


Cleanup

Cleanup

--- src/cljs/app/core.cljs
+++ src/cljs/app/core.cljs
@@ -12,37 +12,43 @@
 (def downloads (reagent/atom {}))

 ;; URL analysis
-(defn get-os [url]
+(defn get-os
+  [url]
   (cond
     (boolean (re-find #"windows" url)) "Windows"
     (boolean (re-find #"linux" url)) "Linux"
     (boolean (re-find #".dmg" url)) "Mac OS X"
     :else "Other"))

-(defn get-word-size [url]
+(defn get-word-size
+  [url]
   (cond
     (boolean (re-find #"x86_64" url)) "64-bit"
     (boolean (re-find #"x64" url)) "64-bit"
     (boolean (re-find #"x86" url)) "32-bit"
     :else ""))

-(defn get-file-type [url]
+(defn get-file-type
+  [url]
   (cond
     (boolean (re-find #".zip" url)) "Portable"
     (boolean (re-find #".tar.gz" url)) "Portable"
     (boolean (re-find #".dmg" url)) "Disk Image"
     :else "Installer"))

-(defn analyze-download-url [asset-info]
+(defn analyze-download-url
+  [asset-info]
   (let [{url :browser_download_url} asset-info]
     {:os (get-os url) :word-size (get-word-size url)
      :file-type (get-file-type url) :url url}))

-(defn build-download-map [asset-info-vector]
+(defn build-download-map
+  [asset-info-vector]
   (group-by :os (map analyze-download-url asset-info-vector)))

 ;; Get JSON download data
-(defn download-json [json-url]
+(defn download-json
+  [json-url]
   (go
     (let [{{asset-info-vector :assets} :body}
           (<! (http/get json-url {:with-credentials? false}))]


remove unused requires

remove unused requires

--- src/cljs/app/core.cljs
+++ src/cljs/app/core.cljs
@@ -6,8 +6,6 @@
    [cljs.core.async :as async
     :refer [<! chan close! alts! timeout put!]]
    [goog.dom :as dom]
-   [goog.events :as events]
-   [goog.string :as gstring]
    [reagent.core :as reagent
     :refer [atom]]
    [api.jokes :as jokes]


fix comment

fix comment

--- src/clygments/core.clj
+++ src/clygments/core.clj
@@ -104,6 +104,6 @@
                                               py-opts]))]

      (when (and res (.__nonzero__ res))
-       ;; This won't work with non-text formatters, such as gif, but it's
+       ;; This won't work with non-text formatters such as :gif, but it's
        ;; ok since they're not supported on Jython (#2)
        (.asString res)))))


Fix unnecessary 'and' in macro expand of routes

--- src/compojure/core.clj
+++ src/compojure/core.clj
@@ -100,7 +100,7 @@
         (if (and (symbol? x) (= :<< y))
           (recur (drop 3 args) (conj syms x))
           (recur (next args) syms)))
-      syms)))
+      (seq syms))))

 (defmacro ^:no-doc let-request [[bindings request] & body]
   (warn-on-*-bindings! bindings)


Pass state and chanel as arguments to components

--- src/gol/client.cljs
+++ src/gol/client.cljs
@@ -34,60 +34,43 @@
   [count width height]
   (set (take count (distinct (repeatedly (fn [] [(rand-int width) (rand-int height)]))))))

-(def state (atom (let [count 500 width 30 height 30]
-                   {:gen          (rand-gen count width height)
-                    :count        count
-                    :timeout      500
-                    :timeout-min  200
-                    :timeout-max  2000
-                    :timeout-step 100
-                    :width        width
-                    :height       height
-                    :limit        false
-                    :pause        false})))
-
-(def c (chan))
-
 (defn cell
-  [x y cell]
+  [c x y cell]
   [:b.cell
    {:on-click (fn [] (put! c {:msg :toggle :loc [x y]}))}
    (when cell [:i])])

 (defn row
-  [x row]
-  (into [:li] (map-indexed (partial cell x) row)))
+  [c x row]
+  (into [:li] (map-indexed (partial cell c x) row)))

-(def main-component
-  (with-meta
-    (fn [] (into [:ul.cell-area] (let [s @state
-                                       w (:width s)
-                                       h (:height s)
-                                       gen (:gen s)]
-                                   (map-indexed row (populate (empty-board w h) (filter-on-board w h gen))))))
-    {:display-name        "main_component"
-     :component-did-mount (fn []
-                            (go (while true
-                                  (<! (timeout (:timeout @state)))
-                                  (let [s @state
-                                        w (:width s)
-                                        h (:height s)
-                                        l (:limit s)]
-                                    (when (not (:pause s))
-                                      (let [ns (swap! state update-in [:gen] (if l (comp set (partial filter-on-board w h) step) step))]
-                                        (when (empty? (:gen ns))
-                                          (put! c {:msg :pause}))))))))}))
+(defn main-component
+  [state c]
+  (go (while true
+        (<! (timeout (:timeout @state)))
+        (let [s @state
+              w (:width s)
+              h (:height s)
+              l (:limit s)]
+          (when (not (:pause s))
+            (let [ns (swap! state update-in [:gen] (if l (comp set (partial filter-on-board w h) step) step))]
+              (when (empty? (:gen ns))
+                (put! c {:msg :pause})))))))
+  (fn [state c] (into [:ul.cell-area] (let [s @state
+                              w (:width s)
+                              h (:height s)
+                              gen (:gen s)]
+                          (map-indexed (partial row c) (populate (empty-board w h) (filter-on-board w h gen)))))))

-(r/render-component [main-component] (js/document.getElementById "app"))
-
-(def control-component
-  (fn []
+(defn control-component
+  [state c]
+  (fn [state c]
     [:div
      [:div
-      [:input {:value (:count @state)
-               :type :number
-               :min 1
-               :max (* (:width @state) (:height @state))
+      [:input {:value     (:count @state)
+               :type      :number
+               :min       1
+               :max       (* (:width @state) (:height @state))
                :on-change (fn [this] (put! c {:msg :count :count (aget this "target" "value")}))}]]
      [:div
       [:button {:on-click (fn [] (put! c {:msg :pause}))} (if (:pause @state) "Play" "Pause")]
@@ -118,7 +101,22 @@
                                  (filter-on-board w h gen)))]
       [:div "Universe: " (count (:gen @state))]]]))

-(r/render-component [control-component] (js/document.getElementById "control"))
+(def state (atom (let [count 500 width 30 height 30]
+                   {:gen          (rand-gen count width height)
+                    :count        count
+                    :timeout      500
+                    :timeout-min  200
+                    :timeout-max  2000
+                    :timeout-step 100
+                    :width        width
+                    :height       height
+                    :limit        false
+                    :pause        false})))
+
+(def c (chan))
+
+(r/render-component [main-component state c] (js/document.getElementById "app"))
+(r/render-component [control-component state c] (js/document.getElementById "control"))

 (go (while true
       (let [{v :msg :as msg} (<! c)]


Let `pattern` take the token stream, rather than just a single token.  For upcoming changes to how many tokens small patterns can consume.

--- src/isla/parser.clj
+++ src/isla/parser.clj
@@ -38,32 +38,34 @@

 ;; atoms

-(defn -nl [token] (pattern token :nl :nl))
+(defn -nl [tokens] (pattern tokens :nl :nl))

-(defn -is [token]
-  (pattern token #"is" :is (fn [x] [:is])))
+(defn -is [tokens]
+  (pattern tokens #"is" :is (fn [x] [:is])))

 ;; values

-(defn -value [token]
-  (def nodes (alternatives token [-string -integer -identifier]))
-  (if (> (count nodes) 0)
-    (nnode :value [(first nodes)])
+;;;;;;;; might need attention - doesn't get back left-tokens
+(defn -value [tokens]
+  (def alts (alternatives tokens [-string -integer -identifier]))
+  (if (> (count alts) 0)
+    (let [{node :node left-tokens :left-tokens} (first alts)]
+      {:node (nnode :value [node]) :left-tokens left-tokens})
     nil))

-(defn -assignee [token] (pattern token #"[A-Za-z]+" :assignee))
+(defn -assignee [tokens] (pattern tokens #"[A-Za-z]+" :assignee))

-(defn -identifier [token] (pattern token #"(?!^is$)[A-Za-z]+" :identifier))
+(defn -identifier [tokens] (pattern tokens #"(?!^is$)[A-Za-z]+" :identifier))

-(defn -integer [token]
-  (pattern token #"[0-9]+" :integer (fn [x] [(Integer/parseInt token)])))
+(defn -integer [tokens]
+  (pattern tokens #"[0-9]+" :integer (fn [x] [(Integer/parseInt (first tokens))])))

-(defn -string [token]
-  (pattern token #"'[A-Za-z0-9 ]+'" :string (fn [x] [(str/replace token "'" "")])))
+(defn -string [tokens]
+  (pattern tokens #"'[A-Za-z0-9 ]+'" :string (fn [x] [(str/replace (first tokens) "'" "")])))

 ;; helpers

-(defmulti is-type (fn [matcher token] (class matcher)))
+(defmulti is-type (fn [matcher tokens] (class matcher)))

 (defmethod is-type clojure.lang.Keyword [symbol token]
   (= symbol token))
@@ -85,26 +87,25 @@
   (if (> (count alts) 0)
     (let [{expr :expr left-tokens :left-tokens} (first alts)]
       {:expr (nnode :expression [expr]) :left-tokens left-tokens}) ;; return alternative
-    nil)) ;; no alternative match - return
+    nil)) ;; no alternatives match - return

 (defn pattern-sequence [tokens patterns collected]
   (let [pattern (first patterns)
-        token (first tokens)]
+        token (first tokens)] ;;;;;;;;;;;;;;;;; need to fix - sub patterns shd manage own toks
     (if (nil? pattern)
       {:nodes collected :left-tokens tokens} ;; pattern matched - return
-      (if (nil? token)
+      (if (nil? token) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ditto
         nil ;; pattern match failure - not enough tokens
-        (if-let [node (pattern token)] ;; matched token
-          (pattern-sequence (rest tokens) (rest patterns) (conj collected node)) ;; round again
+        (if-let [{node :node left-tokens :left-tokens} (pattern tokens)] ;; matched token
+          (pattern-sequence left-tokens (rest patterns) (conj collected node)) ;; round again
           nil))))) ;; pattern match failure token match failure - return

-;; only one token, for now
-(defn pattern [input matcher tag & args]
-  (if (is-type matcher input)
+(defn pattern [tokens matcher tag & args]
+  (if (is-type matcher (first tokens))
     (let [output (if (not= nil args)
-                   ((first args) input)
-                   [input])]
-      (nnode tag output))
+                   ((first args) (first tokens))
+                   [(first tokens)])]
+      {:node (nnode tag output) :left-tokens (rest tokens)})
     nil))

 (defn nnode [tag data]


Use clojure.string/join instead of repeating \n

--- src/app/interactive.clj
+++ src/app/interactive.clj
@@ -13,19 +13,20 @@
 ; ============================================

 (def commands-grammar
-  (str
-   "<COMMAND> = HELP | EXIT | LOAD | LIST | MC | MCP | F | ST   \n"
-   "HELP = 'help' | 'h'                                         \n"
-   "EXIT = 'exit' | 'quit' | 'q'                                \n"
-   "LOAD = 'load' <WS> STR                                      \n"
-   "LIST = 'list'                                               \n"
-   "MC  = ('mc'|'many-constructors') <WS> 'th' <WS> NUM         \n"
-   "MCP = ('mcp'|'many-costructor-params') <WS> 'th' <WS> NUM   \n"
-   "F = ('f'|'finalizers')                                      \n"
-   "ST = ('st'|'singletons')                                    \n"
-   "WS  = #'[\t ]+'                                             \n"
-   "NUM = #'[0-9]+'                                             \n"
-   "STR = #'\"[^\"]*\"'                                         \n"))
+  (clojure.string/join
+   "\n"
+   ["<COMMAND> = HELP | EXIT | LOAD | LIST | MC | MCP | F | ST"
+    "HELP = 'help' | 'h'"
+    "EXIT = 'exit' | 'quit' | 'q'"
+    "LOAD = 'load' <WS> STR"
+    "LIST = 'list'"
+    "MC  = ('mc'|'many-constructors') <WS> 'th' <WS> NUM"
+    "MCP = ('mcp'|'many-costructor-params') <WS> 'th' <WS> NUM"
+    "F = ('f'|'finalizers')"
+    "ST = ('st'|'singletons')"
+    "WS  = #'[\t ]+'"
+    "NUM = #'[0-9]+'"
+    "STR = #'\"[^\"]*\"'"]))

 (def command-parser
   (insta/parser commands-grammar))
@@ -34,15 +35,16 @@
   "No classes loaded. Use <load> first")

 (def help-message
-  (str
-   "h/help                             : print this help message \n"
-   "q/quit/exit                        : close the shell \n"
-   "list                               : list classes loaded \n"
-   "load DIR                           : load classes from DIR \n"
-   "mc/many-constructors th NUM        : list classes with NUM or more constructors \n"
-   "mcp/many-constructor-params th NUM : list constructors with NUM or more parameters \n"
-   "f/finalizers                       : list classes that use finalizers \n"
-   "st/singletons                      : list singletons"))
+  (clojure.string/join
+   "\n"
+   ["h/help                             : print this help message"
+    "q/quit/exit                        : close the shell"
+    "list                               : list classes loaded"
+    "load DIR                           : load classes from DIR"
+    "mc/many-constructors th NUM        : list classes with NUM or more constructors"
+    "mcp/many-constructor-params th NUM : list constructors with NUM or more parameters"
+    "f/finalizers                       : list classes that use finalizers"
+    "st/singletons                      : list singletons"]))

 (declare interactive)


Change 'at' to 'apply-at'

Change 'at' to 'apply-at'

--- src/overtone_workspace/ambi_rand.clj
+++ src/overtone_workspace/ambi_rand.clj
@@ -1,8 +1,5 @@
 (ns overtone-workspace.ambi-rand
   (:use [overtone.live]))
-
-;; https://twitter.com/kn1kn1/status/624227547660726272
-;; loop{use_bpm 70;sample:ambi_piano,sustain:0.25,rate:pitch_to_ratio([-5,-2,0,3].choose)*[1,2,4].choose*[1,-1].choose,start:rand;sleep 0.25}

 (def ambi-piano-b (load-sample "resources/ambi_piano.wav"))
 (def ambi-choir-b (load-sample "resources/ambi_choir.wav"))
@@ -13,7 +10,7 @@
 (def ambi-lunar-land-b (load-sample "resources/ambi_lunar_land.wav"))
 (def ambi-soft-buzz-b (load-sample "resources/ambi_soft_buzz.wav"))
 (def ambi-swoosh-b (load-sample "resources/ambi_swoosh.wav"))
-(definst ambi [buff ambi-choir-b frames 0 start 0 rate 1.0 dur 0.25 amp 10]
+(definst ambi [buff ambi-choir-b frames 0 start 0 rate 1.0 dur 0.25 amp 1]
   (let [
         trig (env-gen:kr (lin 0 dur 0))
         src (play-buf 1 buff rate trig (* frames start) 0 FREE)
@@ -41,12 +38,16 @@
                      ambi-soft-buzz-b
                      ambi-swoosh-b
                      ])]
-    (at (metro beat) (ambi buf (num-frames buf) start rate (/ dur (choose [1 2 3 4]))))
-    (apply-by (metro (+ beat 1/4)) #'ambi-player [metro (+ beat 1/4)])))
+    (at (metro beat) (ambi buf (num-frames buf) start rate (/ dur (choose [1 2 3 4]))))))
+
+(defn ambi-loop [metro beat]
+  (apply-at (metro beat) #'ambi-player [metro beat])
+  (apply-by (metro (+ beat 1/4)) #'ambi-loop [metro (+ beat 1/4)]))

 (comment
   (do
     (def metro (metronome 128))
-    (ambi-player metro (metro)))
+    ;;(ambi-player metro (metro)))
+    (ambi-loop metro (metro)))
   (stop)
   )


Print subroutines from revealed ice. New option to resolve a subroutine from a Grail.

--- src/clj/game/cards.clj
+++ src/clj/game/cards.clj
@@ -2858,7 +2858,8 @@
                 {:msg "draw 1 card" :effect (effect (draw))}]}

    "Excalibur"
-   {:abilities [{:msg "prevent the Runner from making another run" :effect (effect (prevent-run))}]}
+   {:abilities [{:label "The Runner cannot make another run this turn"
+                 :msg "prevent the Runner from making another run" :effect (effect (prevent-run))}]}

    "Fenris"
    {:effect (effect (gain :bad-publicity 1) (system-msg "takes 1 bad publicity"))
@@ -2877,7 +2878,16 @@
                  :effect (effect (damage :meat 2 {:unpreventable true :card card}) (end-run))}]}

    "Galahad"
-   {:abilities [{:msg "end the run" :effect (effect (end-run))}]}
+   {:abilities [{:label "End the run" :msg "end the run" :effect (effect (end-run))}
+                {:label "Reveal up to 2 Grail ICE from HQ"
+                 :choices {:max 2 :req #(and (:side % "Corp") (= (:zone %) [:hand]) (has? % :subtype "Grail"))}
+                 :msg (msg "reveal "
+                           (join ", " (map #(str (:title %) " ("
+                                                 (:label (first (:abilities (card-def %)))) ")") targets)))}
+                {:label "Resolve up to 2 Grail ICE subroutines from HQ"
+                 :choices {:max 2 :req #(and (:side % "Corp") (= (:zone %) [:hand]) (has? % :subtype "Grail"))}
+                 :effect (req (doseq [ice targets]
+                                (resolve-ability state side (first (:abilities (card-def ice))) card nil)))}]}

    "Gemini"
    {:abilities [{:label "Trace 2"
@@ -2983,7 +2993,16 @@
    "Lancelot"
    {:abilities [{:prompt "Choose a program to trash" :msg (msg "trash " (:title target))
                  :label "Trash a program" :choices (req (get-in runner [:rig :program]))
-                 :effect (effect (trash target))}]}
+                 :effect (effect (trash target))}
+                {:label "Reveal up to 2 Grail ICE from HQ"
+                 :choices {:max 2 :req #(and (:side % "Corp") (= (:zone %) [:hand]) (has? % :subtype "Grail"))}
+                 :msg (msg "reveal "
+                           (join ", " (map #(str (:title %) " ("
+                                                 (:label (first (:abilities (card-def %)))) ")") targets)))}
+                {:label "Resolve up to 2 Grail ICE subroutines from HQ"
+                 :choices {:max 2 :req #(and (:side % "Corp") (= (:zone %) [:hand]) (has? % :subtype "Grail"))}
+                 :effect (req (doseq [ice targets]
+                                (resolve-ability state side (first (:abilities (card-def ice))) card nil)))}]}

    "Little Engine"
    {:abilities [{:msg "end the run" :effect (effect (end-run))}
@@ -3019,7 +3038,16 @@
                  :trace {:base 2 :msg "give the Runner 1 tag" :effect (effect (gain :runner :tag 1))}}]}

    "Merlin"
-   {:abilities [{:msg "do 2 net damage" :effect (effect (damage :net 2 {:card card}))}]}
+   {:abilities [{:label "Do 2 net damage" :msg "do 2 net damage" :effect (effect (damage :net 2 {:card card}))}
+                {:label "Reveal up to 2 Grail ICE from HQ"
+                 :choices {:max 2 :req #(and (:side % "Corp") (= (:zone %) [:hand]) (has? % :subtype "Grail"))}
+                 :msg (msg "reveal "
+                           (join ", " (map #(str (:title %) " ("
+                                                 (:label (first (:abilities (card-def %)))) ")") targets)))}
+                {:label "Resolve up to 2 Grail ICE subroutines from HQ"
+                 :choices {:max 2 :req #(and (:side % "Corp") (= (:zone %) [:hand]) (has? % :subtype "Grail"))}
+                 :effect (req (doseq [ice targets]
+                                (resolve-ability state side (first (:abilities (card-def ice))) card nil)))}]}

    "Meru Mati"
    {:abilities [{:msg "end the run" :effect (effect (end-run))}]


Scaffolding out the file parsing structure

--- src/doctopus/files.clj
+++ src/doctopus/files.clj
@@ -1,5 +1,54 @@
 (ns doctopus.files
-  (:require []))
+  (:require [me.raynes.fs :as fs]
+            [clojure.string :as str]))

 ;; THIS IS TOTALLY DATABASS
 ;; (pprint (fs/walk vector "/Users/rossdonaldson/Code/doctopus/src/"))
+
+(defn markdown-type
+  "returns true only for type files. Expects a Java.Util.FileHandle"
+  [file-handle]
+  (if (re-find #"(?i)md|markdown|mdown$" (.getPath file-handle))
+    true
+    false
+    )
+  )
+
+
+(defn filtered-the-docs
+  "Vector Triple of (path, directories, files), and function that filters relevant doc-types"
+  [[path directories files] doc-type-fn]
+    (if-let [matched-files (filter doc-type-fn files)]
+      [path matched-files]
+      nil
+    )
+  )
+
+
+(declare truncate-str)
+(defn assemble-the-results
+  "More stuff"
+  [doc-root path matched-files]
+  (let [str-path (.getPath path)
+        str-rel-path (truncate-str doc-root str-path)
+        ]
+    (for [matched-file matched-files]
+      [doc-root str-rel-path matched-file])
+  )
+
+
+(defn truncate-str
+  "Removes non-relatice path data from a string"
+  [fq-path rel-path]
+  (str/replace fq-path rel-path ""))
+
+
+(defn walk-the-docs
+  "Walk the docs"
+  [doc-root]
+  (let [docs-all (fs/walk vector doc-root) ;; Triple of directory path, directory name, file name
+        filtered-docs (filter-the-docs docs-all)
+        assembled-result (assemble-the-results filtered-docs)
+        ]
+    assembled-result
+  )


Add depth to ABACUS export file

Add depth to ABACUS export file

Fixes #43

--- src/mdr2/abacus.clj
+++ src/mdr2/abacus.clj
@@ -176,12 +176,13 @@
   "Export the state of a production as a csv-like structure, ready to
   be consumed by ABACUS"
   [{:keys [product_number total_time state audio_format multimedia_type
-           date id produced_date volumes] :as production}]
+           date id produced_date volumes depth] :as production}]
   (->> [(create-row 2 product_number)
         (create-row 239 (quot (or total_time 0) (* 1000 60))) ; in minutes
         (create-row 106 (string/capitalize state))
         (create-row 280 audio_format)
         (create-row 271 volumes) ; Number of CDs
+        (create-row 279 depth)
         (create-row 281 multimedia_type)
         (create-row 256 (and produced_date
                              (format date-format produced_date))) ; Date of production end


Update http-kit

Update http-kit

This will suppress the exception that occurs when you stop figwheel.

--- sidecar/project.clj
+++ sidecar/project.clj
@@ -12,7 +12,7 @@
     :exclusions [org.apache.ant/ant]]
    [org.clojure/core.async "0.2.374"]
    [com.stuartsierra/component "0.3.0"]
-   [http-kit "2.1.18"]
+   [http-kit "2.1.19"]
    [ring-cors "0.1.7"]
    [compojure "1.4.0"]
    [clj-stacktrace "0.2.8"]


Remove unused def

Remove unused def

--- src/exploud/asgard.clj
+++ src/exploud/asgard.clj
@@ -201,9 +201,6 @@
   "The URL describing the Asgard to use for a given environment."
   [environment]
   ((keyword environment) asgards-by-environment (:poke asgards-by-environment)))
-
-(def asgard-url
-  (:poke asgards-by-environment))

 (defn- application-url
   "Gives us a region-based URL we can use to get information about an


Removes redundant code path

Removes redundant code path

--- src/expound/paths.cljc
+++ src/expound/paths.cljc
@@ -184,7 +184,8 @@
     (= form val)
     (conj paths path)

-    (sequential? form)
+    (or (sequential? form)
+        (set? form))
     (reduce
      (fn [ps [x i]]
        (paths-to-value x val (conj path i) ps))
@@ -199,13 +200,6 @@
                  paths
                  form)

-    ;; TODO - collapse with above (sequential)
-    (set? form) (reduce
-                 (fn [ps [x i]]
-                   (paths-to-value x val (conj path i) ps))
-                 paths
-                 (map vector (seq form) (range)))
-
     :else paths))

 (defn in-with-kps [form val in in']


Fix regression where item delete was incorrectly returning a body.

--- src/fcms/api/items.clj
+++ src/fcms/api/items.clj
@@ -89,7 +89,7 @@
   :conflict? (fn [_] false)
   :put! (fn [ctx] (update-item coll-slug item-slug (:data ctx)))
   :new? (by-method {:post true :put false})
-  :respond-with-entity? (fn [_] true)
+  :respond-with-entity? (by-method {:put true :delete false})
   :handle-not-implemented (fn [ctx] (when (:bad-collection ctx) common/missing-collection-response))
   :handle-created (fn [ctx] (item-location-response coll-slug (:item ctx))))


prints proper base64

prints proper base64

--- src/frontend/core.cljs
+++ src/frontend/core.cljs
@@ -91,7 +91,14 @@
         (swap! app-state assoc :current-file-download
           (new js/Blob #js [(:current-file-download @app-state) blob-chunk]))))
     (.on stream "end"
-      #(println (:current-file-download @app-state)))))
+      (fn []
+        (println (.-size (:current-file-download @app-state)))
+        (let [reader (new js/FileReader)
+              blob   (:current-file-download @app-state)]
+          (.readAsDataURL reader blob)
+          (set! (.-onloadend reader)
+            (fn []
+              (println (.-result reader)))))))))

 (.change (js/$ "#file_upload_input")
   (fn [e]


creation of path was using io/file, which on windows converts to single backslash for js code creating escape chars instead of file separators. forward slash always works in js.

--- src/adzerk/boot_cljs/middleware.clj
+++ src/adzerk/boot_cljs/middleware.clj
@@ -154,7 +154,7 @@
           rooted-path #(util/rooted-relative docroot (core/tmppath %))
           scripts     (-> (:incs files)
                           (->> (mapv rooted-path))
-                          (conj (io/file output-dir "goog" "base.js"))
+                          (conj (str output-dir "/goog/base.js"))
                           (conj (util/get-name output-to)))]
       (->> (write-body (file->goog (str "boot/cljs/" base-name)))
            (format shim-js shim-name (apply str (map write-src scripts)))


Making popup overflow: hidden to remove scrollbars

The horizontal and vertical scrollbars on Chrome at least are rather ugly

--- src/adzerk/boot_reload/display.cljs
+++ src/adzerk/boot_reload/display.cljs
@@ -53,7 +53,7 @@
            :pad       [:padding "12px"]
            :container [:color "black"
                        :max-height "320px"
-                       :overflow "scroll"
+                       :overflow "hidden"
                        :transition (str transition-duration "ms")
                        :font-family "sans-serif"
                        :position "fixed"


fix core conflict

fix core conflict

--- Assets/game/core.clj
+++ Assets/game/core.clj
@@ -156,19 +156,7 @@
   (let [citywfc (make-city city-size city-size)
         city (.gameObject citywfc)]
     (timeline [
-<<<<<<< 772cd6bd0eab429fcc8af87a05da3f93bcaa37ec
-      (wait 0.1)
-      #(do
-        (prune-city-center city)
-        (destroy (the city-sample))
-        (local-scale! city (v3 city-scale))
-        (position! city
-          (v3 (* city-size -4 city-scale) 0
-              (* city-size -4 city-scale)))
-        (cmpt- city (type citywfc)) nil)]))
- ;(gif/setup 800 480 24)
-=======
-               (wait 0.01)
+               (wait 0.1)
                #(do
                  (prune-city-center city)
                  (destroy (the city-sample))
@@ -180,7 +168,6 @@
  (clone! :ui/recording-canvas)
  (if @data/recording?
   (set! (.alpha (cmpt (object-tagged "skatecam") UnityEngine.CanvasGroup)) 1.0))
->>>>>>> working gif capture
  (make-player
    (v3 (* park-size park-scale)
        (* 6 park-scale)


temporary hack to make NUX Bootstrapped experience work

--- src-cljs/frontend/controllers/api.cljs
+++ src-cljs/frontend/controllers/api.cljs
@@ -1155,4 +1155,13 @@

 (defmethod post-api-event! [:follow-projects :failed]
   [_ _ status {:keys [context]} previous-state current-state comms]
-  (forms/release-button! (:uuid context) status))
+  (let [api-ch (:api comms)]
+    (forms/release-button! (:uuid context) status)
+    ;; Below is a hack because of the fact that with the current flow we have
+    ;; no way of knowing whether or not a user is an admin on projects when we
+    ;; show them the NUX Bootstrap experience on the dashboard page. So, it is possible
+    ;; that we receive a 403 as one project is unable to be followed although others were
+    ;; followed. So, do a fetch to get the builds and projects in case the user was followed
+    ;; to some but not all projects.
+    (api/get-dashboard-builds {} api-ch)
+    (api/get-projects api-ch)))


Use pprint for edn output

Use pprint for edn output

--- src/bltool/data/edn.clj
+++ src/bltool/data/edn.clj
@@ -1,10 +1,12 @@
 (ns bltool.data.edn
   (:require [bltool.data.default :refer :all])
   (:require [bltool.flags :refer :all])
-  (:require [clojure.edn :as edn]))
+  (:require [clojure.edn :as edn])
+  (:require [clojure.pprint :as pprint]))

 (defmethod read-games "edn" [_ source]
   (edn/read (java.io.PushbackReader. source)))

 (defmethod write-games "edn" [_ games sink]
-  (.write sink (str (vec games))))
+  (pprint/pprint (vec games) sink)
+  (.write sink "\n"))


cjl - Whoops

cjl - Whoops

--- src/icfp2015/board.clj
+++ src/icfp2015/board.clj
@@ -45,7 +45,7 @@
 ; [ [:move :west] [:move :east] [:move :southwest] [:move :southeast]
 ;   [:rotate :clockwise] [:rotate :counterclockwise] ]
 (defn transition-board
-  "Given a board and command, returns a new (possibly invalid board)"
+  "Given a board and command, returns a new (possibly invalid) board"
   [board [command direction]]
   (if (= command :move)
     (let [unit-fn (apply translate (translations direction))]


Remove unused require

Remove unused require

--- src/cljs/asciinema_player/view.cljs
+++ src/cljs/asciinema_player/view.cljs
@@ -1,6 +1,5 @@
 (ns asciinema-player.view
   (:require [clojure.string :as string]
-            [cljs.core.async :refer [>!]]
             [asciinema-player.util :as util]
             [asciinema-player.fullscreen :as fullscreen]))


Removed time part in the deck timespamp to save space

--- src/cljs/netrunner/deckbuilder.cljs
+++ src/cljs/netrunner/deckbuilder.cljs
@@ -492,7 +492,7 @@
      [:img {:src (image-url (:identity deck))}]
      [:div.float-right (deck-status-span deck)]
      [:h4 (:name deck)]
-     [:div.float-right (-> (:date deck) js/Date. js/moment (.format "MMM Do YYYY - HH:mm"))]
+     [:div.float-right (-> (:date deck) js/Date. js/moment (.format "MMM Do YYYY"))]
      [:p (get-in deck [:identity :title])]]))

 (defn deck-builder [{:keys [decks decks-loaded] :as cursor} owner]


add endorse badge link to modal

add endorse badge link to modal

--- src/cljs/salava/badge/ui/modal.cljs
+++ src/cljs/salava/badge/ui/modal.cljs
@@ -206,8 +206,12 @@
         [:div.description description]

-        ;check-badge
-        (check-badge id)]]
+        ;;Check-badge
+        (check-badge id)
+
+        ;;Endorse-badge
+        [endr/endorse-badge]
+        ]]

       (when-not (empty? alignment)
         [:div.row


Added string_setchar instruction

Added string_setchar instruction

--- src/clojush/instructions/string.clj
+++ src/clojush/instructions/string.clj
@@ -345,6 +345,26 @@
                    :string
                    (pop-item :char (pop-item :string state))))
       state)))
+
+  (define-registered
+  string_setchar ; Returns a function that sets char at index in string
+  ^{:stack-types [:string :char :integer]}
+  (fn [state]
+    (if (or (empty? (:string state))
+            (empty? (:char state))
+            (empty? (:integer state)))
+      state
+      (let [s (top-item :string state)
+            item (top-item :char state)
+            index (if (empty? s)
+                    0
+                    (mod (top-item :integer state) (count s)))
+            result (if (empty? s)
+                     s
+                     (apply str (assoc (vec s) index item)))]
+        (push-item result
+                   :string
+                   (pop-item :char (pop-item :integer (pop-item :string state))))))))

 (define-registered
   exec_string_iterate ; Returns a function that iterates over a string using the code on the exec stack.


start tree-walking

start tree-walking

--- src/clojee/core.clj
+++ src/clojee/core.clj
@@ -1,10 +1,4 @@
 (ns clojee.core)
-
-(defn foo
-  "I don't do a whole lot."
-  [x]
-  (println x "Hello, World!"))
-

 ; syntax
 ;   (let* [a v1 b v2 c v3] form)
@@ -70,3 +64,55 @@
         (make-bindings bindings)
         form))

+
+(def eg1
+  [(make-def 'id (make-fn '(x) 'x))
+   (make-def '. (make-fn '(f g x) '(f (g x))))
+   (make-def 'd (make-fn '(x) '(x x)))
+   (make-def 't (make-fn '(f x) '(. f f x)))])
+
+
+(defn my-resolve
+  [sym env]
+  ((env :specials) sym))
+
+(defn f-symbol
+  [node log env]
+  (cons {:symbol node,
+         :type "symbol",
+         :resolution (my-resolve node env)}
+        log))
+
+(defn f-list
+  [node log env]
+  (loop [log-n (cons {:type "list" :length (count node)} log); :env env} log)
+         node-n node]
+        (if (empty? node-n)
+            log-n
+            (recur (f-node (first node-n) log-n env)
+                   (rest node-n)))))
+
+(defn f-node
+  [node log env]
+  (if (symbol? node)
+      (f-symbol node log env)
+      (f-list node log env)))
+
+
+(def specials
+  {'if "yes!"
+   'def "yes!"
+   'fn* "yes!"
+   'let* "yes!"
+   'loop* "yes!"
+   'do "yes!"
+   'set! "yes!"})
+
+(def root-env {:specials specials})
+
+(defn run-eg
+  ([] (run-eg '() root-env))
+  ([log env]
+   (doseq [x (f-node (second eg1) log env)]
+     (prn x))))
+


Brydon - bugfix for configuring jetty port

--- src/checkin/handler.clj
+++ src/checkin/handler.clj
@@ -46,6 +46,5 @@
         (auth/authentication-middleware))))

 (defn -main [& args]
-  (run-jetty app {:port (or (-> (System/getenv "PORT")
-                                (Integer/parseInt))
-                            3000)}))
+  (run-jetty app {:port (Integer/parseInt (or (System/getenv "PORT")
+                                              "3000"))}))


retry ES related http requests

retry ES related http requests

--- src/clj/runbld/opts.clj
+++ src/clj/runbld/opts.clj
@@ -11,6 +11,7 @@
             [runbld.store :as store]
             [runbld.util.data :refer [deep-merge-with deep-merge]]
             [runbld.util.date :as date]
+            [runbld.util.http :refer [wrap-retries]]
             [runbld.io :as io]
             [runbld.version :as version]))

@@ -153,7 +154,9 @@
                            log-index
                            max-index-bytes] :as opts}]
   (let [conn (store/make-connection
-              (select-keys opts [:url :http-opts]))
+              (assoc (select-keys opts [:url :http-opts])
+                     :additional-middleware
+                     [wrap-retries]))
         build-index-write (store/set-up-index
                            conn build-index
                            StoredBuildIndexSettings


Fix the non leaf blocks fetching

Fix the non leaf blocks fetching

--- src/cljam/io/bigwig.clj
+++ src/cljam/io/bigwig.clj
@@ -321,7 +321,7 @@
                                          start-base (lsb/read-uint r)
                                          end-chrom-ix (lsb/read-uint r)
                                          end-base (lsb/read-uint r)
-                                         offset (lsb/read-uint r)]
+                                         offset (lsb/read-long r)]
                                      {:start-chrom-ix start-chrom-ix
                                       :start-base start-base
                                       :end-chrom-ix end-chrom-ix
@@ -335,7 +335,7 @@
                                  (cir-tree-overlaps? id start end
                                                      start-chrom-ix start-base
                                                      end-chrom-ix end-base)))
-                       (map (fn [{:keys [offset]}] (recur offset)))))))))]
+                       (mapcat (fn [{:keys [offset]}] (make-blocks offset)))))))))]
     (make-blocks root-offset)))

 (defn- fetch-overlapping-blocks-group


corrected fill's docstring

corrected fill's docstring

corrected fill's docstring example to clojure

--- src/cljc/quil/core.cljc
+++ src/cljc/quil/core.cljc
@@ -1557,7 +1557,7 @@
     :subcategory "Setting"
     :added "1.0"}
   fill
-  "Sets the color used to fill shapes. For example, if you run fill(204, 102, 0),
+  "Sets the color used to fill shapes. For example, if you run (fill 204 102 0),
   all subsequent shapes will be filled with orange.  This function casts all input as a float.
   If nil is passed it removes any fill color; equivalent to (no-fill)."
   ([gray]


Supply missing arguments to some fn calls

--- src/cljs/cljs/core.cljs
+++ src/cljs/cljs/core.cljs
@@ -2342,7 +2342,7 @@
      (< 1 (- cnt (tail-off coll)))
       (PersistentVector. meta (dec cnt) shift root (.slice tail 0 -1))
       :else (let [new-tail (array-for coll (- cnt 2))
-                  nr (pop-tail shift root)
+                  nr (pop-tail coll shift root)
                   new-root (if (nil? nr) cljs.core.PersistentVector/EMPTY_NODE nr)
                   cnt-1 (dec cnt)]
               (if (and (< 5 shift) (nil? (aget new-root 1)))
@@ -3166,7 +3166,7 @@

             (nil? n)
             (if (<= cnt 8)
-              (pack-array-node inode idx)
+              (pack-array-node inode nil idx)
               (ArrayNode. nil (dec cnt) (clone-and-set arr idx n)))

             :else
@@ -4381,7 +4381,7 @@

   ISorted
   (-sorted-seq [coll ascending?]
-    (map key (-sorted-seq-from tree-map ascending?)))
+    (map key (-sorted-seq tree-map ascending?)))

   (-sorted-seq-from [coll k ascending?]
     (map key (-sorted-seq-from tree-map k ascending?)))


fix first/rest with nil, vec

fix first/rest with nil, vec

--- src/cljs/cljs/core.cljs
+++ src/cljs/cljs/core.cljs
@@ -102,15 +102,15 @@
   "Returns the first item in the collection. Calls seq on its
   argument. If coll is nil, returns nil."
   [coll]
-  (when coll
-    (-first (seq coll))))
+  (when-let [s (seq coll)]
+    (-first s)))

 (defn rest
   "Returns a possibly empty seq of the items after the first. Calls seq on its
   argument."
   [coll]
-  (when coll
-    (-rest (seq coll))))
+  (when-let [s (seq coll)]
+    (-rest s)))

 (defn next
   "Returns a seq of the items after the first. Calls seq on its
@@ -415,7 +415,7 @@
 (set! cljs.core.Vector.EMPTY (Vector. nil (array)))

 (defn vec [coll]
-  (reduce conj Vector.EMPTY coll)) ; using [] here causes infinite recursion
+  (reduce conj cljs.core.Vector.EMPTY coll)) ; using [] here causes infinite recursion

 (defn vector [& args] (vec args))


Add ObjMap, simplify HashMap, fix count, add partition. Refs #10

--- src/cljs/cljs/core.cljs
+++ src/cljs/cljs/core.cljs
@@ -96,6 +96,11 @@

 (defn js-obj []
   (js* "return {}"))
+
+(defn js-keys [obj]
+  (let [keys (array)]
+    (goog.object/forEach obj (fn [_ key _] (.push keys key)))
+    keys))

 (defn js-delete [obj key]
   (js* "delete ~{obj}[~{key}]"))
@@ -453,8 +458,8 @@
     (if (satisfies? ICounted coll)
       (-count coll)
       (loop [s (seq coll) n 0]
-	(if (first s)
-	  (recur (rest s) (inc n))
+	(if s
+	  (recur (next s) (inc n))
 	  n)))
     0))

@@ -1067,6 +1072,7 @@
 (defn vector [& args] (vec args))

 (extend-protocol IHash
+  goog.global.String (-hash [o] (goog.string/hashCode o))
   goog.global.Number (-hash [o] o))

 (defn hash [o]
@@ -1091,17 +1097,14 @@
           i
           (recur (+ i incr)))))))

-; Keys is an array of all keys of this map, in no particular order.
-; Any string key is stored along with its value in strobj. If a string key is
-; assoc'ed when that same key already exists in strobj, the old value is
-; overwritten.
-; Any non-string key is hashed and the result used as a property name of
-; hashobj. Each values in hashobj is actually a bucket in order to handle hash
-; collisions. A bucket is an array of alternating keys (not their hashes) and
-; vals.
-(deftype HashMap [meta keys strobj hashobj]
+; The keys field is an array of all keys of this map, in no particular
+; order. Any string, keyword, or symbol key is used as a property name
+; to store the value in strobj.  If a key is assoc'ed when that same
+; key already exists in strobj, the old value is overwritten. If a
+; non-string key is assoc'ed, return a HashMap object instead.
+(deftype ObjMap [meta keys strobj]
   IWithMeta
-  (-with-meta [coll meta] (HashMap. meta keys strobj hashobj))
+  (-with-meta [coll meta] (ObjMap. meta keys strobj))

   IMeta
   (-meta [coll] meta)
@@ -1120,15 +1123,8 @@

   ISeqable
   (-seq [coll]
-    (when (> (.length keys) 0)
-      (let [hash-map-seq
-             (fn hash-map-seq [i]
-               (lazy-seq
-                 (when (< i (.length keys))
-                   (cons
-                     (vector (aget keys i) (-lookup coll (aget keys i)))
-                     (hash-map-seq (inc i))))))]
-        (hash-map-seq 0))))
+    (when (pos? (.length keys))
+      (map #(vector % (aget strobj %)) keys)))

   ICounted
   (-count [coll] (.length keys))
@@ -1136,17 +1132,9 @@
   ILookup
   (-lookup [coll k] (-lookup coll k nil))
   (-lookup [coll k not-found]
-    (if (goog/isString k)
-      (if (.hasOwnProperty strobj k)
-        (aget strobj k)
-        not-found)
-      ; non-string key
-      (let [h (hash k)
-            bucket (aget hashobj h)
-            i (when bucket (scan-array 2 k bucket))]
-        (if i
-          (aget bucket (inc i))
-          not-found))))
+    (if (and (goog/isString k) (.hasOwnProperty strobj k))
+      (aget strobj k)
+      not-found))

   IAssociative
   (-assoc [coll k v]
@@ -1155,64 +1143,112 @@
             overwrite? (.hasOwnProperty new-strobj k)]
         (aset new-strobj k v)
         (if overwrite?
-          (HashMap. meta keys new-strobj hashobj)
+          (ObjMap. meta keys new-strobj)     ; overwrite
           (let [new-keys (array-clone keys)] ; append
             (.push new-keys k)
-            (HashMap. meta new-keys new-strobj hashobj))))
-      ; non-string key
-      (let [h (hash k)
-            bucket (aget hashobj h)]
-        (if bucket
-          (let [new-bucket (array-clone bucket)
-                new-hashobj (goog.object/clone hashobj)]
-            (aset new-hashobj h new-bucket)
-            (if-let [i (scan-array 2 k new-bucket)]
-              (do
-                (aset new-bucket (inc i) v) ; found key, replace
-                (HashMap. meta keys strobj new-hashobj))
-              (let [new-keys (array-clone keys)] ; did not find key, append
-                (.push new-keys k)
-                (.push new-bucket k v)
-                (HashMap. meta new-keys strobj new-hashobj))))
-          (let [new-keys (array-clone keys)
-                new-hashobj (goog.object/clone hashobj)]
-            (.push new-keys k)
-            (aset new-hashobj h (array k v))
-            (HashMap. meta new-keys strobj new-hashobj))))))
-
+            (ObjMap. meta new-keys new-strobj))))
+      ; non-string key. game over.
+      (with-meta (into (hash-map k v) (seq coll)) meta)))
+
   IMap
   (-dissoc [coll k]
-    (if (goog.isString k)
-      (if (not (.hasOwnProperty strobj k))
-        coll ; key not found, return coll unchanged
-        (let [new-keys (array-clone keys)
-              new-strobj (goog.object/clone strobj)
-              new-count (dec (.length keys))]
-          (.splice new-keys (scan-array 1 k new-keys) 1)
-          (js-delete new-strobj k)
-          (HashMap. meta new-keys new-strobj hashobj)))
-      ; non-string key
-      (let [h (hash k)
-            bucket (aget hashobj h)
-            i (when bucket (scan-array 2 k bucket))]
-        (if (not i)
-          coll ; key not found, return coll unchanged
-          (let [new-keys (array-clone keys)
-                new-hashobj (goog.object/clone hashobj)]
-            (if (> 3 (.length bucket))
-              (js-delete new-hashobj h)
-              (let [new-bucket (array-clone bucket)]
-                (.splice new-bucket i 2)
-                (aset new-hashobj h new-bucket)))
-            (.splice new-keys (scan-array 1 k new-keys) 1)
-            (HashMap. meta new-keys strobj new-hashobj))))))
+    (if (and (goog/isString k) (.hasOwnProperty strobj k))
+      (let [new-keys (array-clone keys)
+            new-strobj (goog.object/clone strobj)]
+        (.splice new-keys (scan-array 1 k new-keys) 1)
+        (js-delete new-strobj k)
+        (HashMap. meta new-keys new-strobj hashobj))
+      coll)) ; key not found, return coll unchanged

   IPrintable
   (-pr-seq [coll opts]
     (let [pr-pair (fn [keyval] (pr-sequential pr-seq "" " " "" opts keyval))]
       (pr-sequential pr-pair "{" ", " "}" opts coll))))

-(set! cljs.core.HashMap/EMPTY (HashMap. nil (array) (js-obj) (js-obj)))
+; The keys field is an array of all keys of this map, in no particular
+; order. Each key is hashed and the result used as a property name of
+; hashobj. Each values in hashobj is actually a bucket in order to handle hash
+; collisions. A bucket is an array of alternating keys (not their hashes) and
+; vals.
+(deftype HashMap [meta count hashobj]
+  IWithMeta
+  (-with-meta [coll meta] (HashMap. meta count hashobj))
+
+  IMeta
+  (-meta [coll] meta)
+
+  ICollection
+  (-conj [coll entry] (-assoc coll (-nth entry 0) (-nth entry 1)))
+
+; IEmptyableCollection
+; (iempty [coll] coll)
+
+  IEquiv
+  (-equiv [coll other] (equiv-map coll other))
+
+  IHash
+  (-hash [coll] (hash-coll coll))
+
+  ISeqable
+  (-seq [coll]
+    (when (pos? count)
+      (let [hashes (js-keys hashobj)]
+        (mapcat #(map vec (partition 2 (aget hashobj %)))
+                hashes))))
+
+  ICounted
+  (-count [coll] count)
+
+  ILookup
+  (-lookup [coll k] (-lookup coll k nil))
+  (-lookup [coll k not-found]
+    (let [h (hash k)
+          bucket (aget hashobj h)
+          i (when bucket (scan-array 2 k bucket))]
+      (if i
+        (aget bucket (inc i))
+        not-found)))
+
+  IAssociative
+  (-assoc [coll k v]
+    (let [h (hash k)
+          bucket (aget hashobj h)]
+      (if bucket
+        (let [new-bucket (array-clone bucket)
+              new-hashobj (goog.object/clone hashobj)]
+          (aset new-hashobj h new-bucket)
+          (if-let [i (scan-array 2 k new-bucket)]
+            (do ; found key, replace
+              (aset new-bucket (inc i) v)
+              (HashMap. meta count new-hashobj))
+            (do ; did not find key, append
+              (.push new-bucket k v)
+              (HashMap. meta (inc count) new-hashobj))))
+        (let [new-hashobj (goog.object/clone hashobj)] ; did not find bucket
+          (aset new-hashobj h (array k v))
+          (HashMap. meta (inc count) new-hashobj)))))
+
+  IMap
+  (-dissoc [coll k]
+    (let [h (hash k)
+          bucket (aget hashobj h)
+          i (when bucket (scan-array 2 k bucket))]
+      (if (not i)
+        coll ; key not found, return coll unchanged
+        (let [new-hashobj (goog.object/clone hashobj)]
+          (if (> 3 (.length bucket))
+            (js-delete new-hashobj h)
+            (let [new-bucket (array-clone bucket)]
+              (.splice new-bucket i 2)
+              (aset new-hashobj h new-bucket)))
+          (HashMap. meta (dec count) new-hashobj)))))
+
+  IPrintable
+  (-pr-seq [coll opts]
+    (let [pr-pair (fn [keyval] (pr-sequential pr-seq "" " " "" opts keyval))]
+      (pr-sequential pr-pair "{" ", " "}" opts coll))))
+
+(set! cljs.core.HashMap/EMPTY (HashMap. nil 0 (js-obj)))

 (defn hash-map
   "keyval => key val
@@ -1220,7 +1256,7 @@
   [& keyvals]
   (loop [in (seq keyvals), out cljs.core.HashMap/EMPTY]
     (if in
-      (recur (nnext in) (-assoc out (first in) (second in)))
+      (recur (nnext in) (assoc out (first in) (second in)))
       out)))

 (defn conj
@@ -1476,6 +1512,28 @@
   [to from]
   (reduce -conj to from))

+(defn partition
+  "Returns a lazy sequence of lists of n items each, at offsets step
+  apart. If step is not supplied, defaults to n, i.e. the partitions
+  do not overlap. If a pad collection is supplied, use its elements as
+  necessary to complete last partition upto n items. In case there are
+  not enough padding elements, return a partition with less than n items."
+  ([n coll]
+     (partition n n coll))
+  ([n step coll]
+     (lazy-seq
+       (when-let [s (seq coll)]
+         (let [p (take n s)]
+           (when (= n (count p))
+             (cons p (partition n step (drop step s))))))))
+  ([n step pad coll]
+     (lazy-seq
+       (when-let [s (seq coll)]
+         (let [p (take n s)]
+           (if (= n (count p))
+             (cons p (partition n step pad (drop step s)))
+             (list (take n (concat p pad)))))))))
+
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Printing ;;;;;;;;;;;;;;;;

 (defn pr-sequential [print-one begin sep end opts coll]
@@ -1603,6 +1661,8 @@
   (assert (= (list 3 2 1) [3 2 1]))
   (assert (= [3 2 1] (seq (array 3 2 1))))
   (assert (= {"x" "y"} (meta ^{"x" "y"} [])))
+  (assert (= (hash-map :foo 5)
+             (assoc (cljs.core.ObjMap. (array) (js-obj)) :foo 5)))

   (assert (= "[1 {:a 2, :b 42} #<Array [3, 4]>]"
              (pr-str [1 {:a 2 :b 42} (array 3 4)])))


* src/cljs/cljs/core.cljs: optimize type_satisfies

--- src/cljs/cljs/core.cljs
+++ src/cljs/cljs/core.cljs
@@ -39,16 +39,15 @@
   [x]
   (js* "(~{x} != null && ~{x} !== false)"))

+(set! *unchecked-if* true)
 (defn ^boolean type_satisfies_
   "Internal - do not use!"
   [p x]
   (cond
-   ;; check that x isn't a CLJS ctor
-   (and (coercive-not= x nil)
-        ^boolean (.-cljs$lang$type x)) false
    (aget p (goog.typeOf x)) true
    (aget p "_") true
    :else false))
+(set! *unchecked-if* false)

 (defn is_proto_
   [x]
@@ -5580,12 +5579,12 @@
                        (meta obj))
               (concat ["^"] (pr-seq (meta obj) opts) [" "]))
             (cond
-             (satisfies? IPrintable obj) (-pr-seq obj opts)
-
              ;; handle CLJS ctors
              (and (coercive-not= obj nil)
                   ^boolean (.-cljs$lang$type obj))
              (.cljs$lang$ctorPrSeq obj obj)
+
+             (satisfies? IPrintable obj) (-pr-seq obj opts)

              :else (list "#<" (str obj) ">")))))


Fix a couple ObjMap bugs found by gclosure compiler.

--- src/cljs/cljs/core.cljs
+++ src/cljs/cljs/core.cljs
@@ -1159,7 +1159,7 @@
             new-strobj (goog.object/clone strobj)]
         (.splice new-keys (scan-array 1 k new-keys) 1)
         (js-delete new-strobj k)
-        (HashMap. meta new-keys new-strobj hashobj))
+        (ObjMap. meta new-keys new-strobj))
       coll)) ; key not found, return coll unchanged

   IPrintable
@@ -1672,8 +1672,9 @@
   (assert (= (list 3 2 1) [3 2 1]))
   (assert (= [3 2 1] (seq (array 3 2 1))))
   (assert (= {"x" "y"} (meta ^{"x" "y"} [])))
+  (assert (= {:a :b} (dissoc {:a :b :c :d} :c)))
   (assert (= (hash-map :foo 5)
-             (assoc (cljs.core.ObjMap. (array) (js-obj)) :foo 5)))
+             (assoc (cljs.core.ObjMap. nil (array) (js-obj)) :foo 5)))

   (assert (= "[1 {:a 2, :b 42} #<Array [3, 4]>]"
              (pr-str [1 {:a 2 :b 42} (array 3 4)])))


Whitespace.

Whitespace.

--- src/clu/server/core.clj
+++ src/clu/server/core.clj
@@ -1,10 +1,10 @@
 (ns clu.server.core
   (:require [clojure.tools.logging :as log]
-            [org.httpkit.server :as http]
-            [org.httpkit.timer :as timer]
-            [clojure.data.json :as json]
-            [clu.server.sounds :as sounds]
-            [clu.server.scheduled :as scheduled]))
+            [org.httpkit.server    :as http]
+            [org.httpkit.timer     :as timer]
+            [clojure.data.json     :as json]
+            [clu.server.sounds     :as sounds]
+            [clu.server.scheduled  :as scheduled]))

 (defn send-msg
   [channel {:keys [msg data] :as params}]


CMR-5276 Forces bytes to be returned as longs

--- src/cmr/sizing/core.clj
+++ src/cmr/sizing/core.clj
@@ -24,12 +24,15 @@
 (defn- format-estimate
   "Formats estimate to two significant digits, while avoiding scientific notation for really
    small numbers"
-  [estimate]
-  (if (double? estimate)
+  [estimate type]
+  (if (and (double? estimate)
+           (not= type :bytes))
     (->> estimate
-        (format "%.2f")
-        read-string)
-    estimate))
+         (format "%.2f")
+         read-string)
+    (-> estimate
+        Math/ceil
+        long)))

 ;; XXX This function is nearly identical to one of the same name in
 ;;     cmr.ous.common -- we should put this somewhere both can use,
@@ -70,9 +73,9 @@
                                  (:request-id params)
                                  estimate
                                  elapsed))
-               (results/create [{:bytes (format-estimate estimate)
-                                 :mb (format-estimate (/ estimate (Math/pow 2 20)))
-                                 :gb (format-estimate (/ estimate (Math/pow 2 30)))}]
+               (results/create [{:bytes (format-estimate estimate :bytes)
+                                 :mb (format-estimate (/ estimate (Math/pow 2 20)) :mb)
+                                 :gb (format-estimate (/ estimate (Math/pow 2 30)) :gb)}]
                                :request-id (:request-id params)
                                :elapsed elapsed
                                :warnings warns)))))))))