Split request generation logic into public, toplevel fns

--- src/taoensso/faraday.clj
+++ src/taoensso/faraday.clj
@@ -389,11 +389,16 @@
                  chunk))))]
     (step nil)))

+(defn describe-table-request
+  "Implementation detail"
+  [table]
+  (doto (DescribeTableRequest.) (.setTableName (name table))))
+
 (defn describe-table
   "Returns a map describing a table, or nil if the table doesn't exist."
   [client-opts table]
   (try (as-map (.describeTable (db-client client-opts)
-                (doto (DescribeTableRequest.) (.setTableName (name table)))))
+                ^DescribeTableRequest (describe-table-request table)))
        (catch ResourceNotFoundException _ nil)))

 (defn table-status-watch
@@ -506,6 +511,23 @@
           (.setProvisionedThroughput (provisioned-throughput throughput))))
       indexes)))

+(defn create-table-request
+  "Implementation detail"
+  [table-name hash-keydef
+   & [{:keys [range-keydef throughput lsindexes gsindexes block?]
+       :or   {throughput {:read 1 :write 1}} :as opts}]]
+  (let [lsindexes (or lsindexes (:indexes opts))]
+    (doto-cond [_ (CreateTableRequest.)]
+      :always (.setTableName (name table-name))
+      :always (.setKeySchema (key-schema hash-keydef range-keydef))
+      :always (.setProvisionedThroughput (provisioned-throughput throughput))
+      :always (.setAttributeDefinitions
+               (keydefs hash-keydef range-keydef lsindexes gsindexes))
+      lsindexes (.setLocalSecondaryIndexes
+                 (local-2nd-indexes hash-keydef lsindexes))
+      gsindexes (.setGlobalSecondaryIndexes
+                 (global-2nd-indexes gsindexes)))))
+
 (defn create-table
   "Creates a table with options:
     hash-keydef   - [<name> <#{:s :n :ss :ns :b :bs}>].
@@ -519,21 +541,12 @@
     :block?       - Block for table to actually be active?"
   [client-opts table-name hash-keydef
    & [{:keys [range-keydef throughput lsindexes gsindexes block?]
-       :or   {throughput {:read 1 :write 1}} :as opts}]]
+       :as opts}]]
   (let [lsindexes (or lsindexes (:indexes opts)) ; DEPRECATED
         result
         (as-map
          (.createTable (db-client client-opts)
-           (doto-cond [_ (CreateTableRequest.)]
-             :always (.setTableName (name table-name))
-             :always (.setKeySchema (key-schema hash-keydef range-keydef))
-             :always (.setProvisionedThroughput (provisioned-throughput throughput))
-             :always (.setAttributeDefinitions
-                      (keydefs hash-keydef range-keydef lsindexes gsindexes))
-             lsindexes (.setLocalSecondaryIndexes
-                        (local-2nd-indexes hash-keydef lsindexes))
-             gsindexes (.setGlobalSecondaryIndexes
-                        (global-2nd-indexes gsindexes)))))]
+           (create-table-request table-name hash-keydef opts)))]
     (if-not block? result @(table-status-watch client-opts table-name :creating))))

 (comment (time (create-table mc "delete-me7" [:id :s] {:block? true})))
@@ -559,6 +572,13 @@
          (throughput-steps [3 3] [27 27])
          (throughput-steps [17 8] [3 22])
          (throughput-steps [1 1] [300 300]))
+
+(defn update-table-request
+  "Implementation detail"
+  [table throughput]
+  (doto (UpdateTableRequest.)
+    (.setTableName (name table))
+    (.setProvisionedThroughput (provisioned-throughput throughput))))

 (defn update-table
   "Updates a table. Allows automatic multi-step adjustments to conform to
@@ -588,10 +608,7 @@
           (letfn [(run1 [[r' w']]
                     (as-map
                      (.updateTable (db-client client-opts)
-                       (doto (UpdateTableRequest.)
-                         (.setTableName (name table))
-                         (.setProvisionedThroughput (provisioned-throughput
-                                                     {:read r' :write w'})))))
+                       (update-table-request table {:read r' :write w'})))
                     ;; Returns _new_ descr when ready:
                     @(table-status-watch client-opts table :updating))]

@@ -604,26 +621,36 @@
   (let [p (update-table client-opts :faraday.tests.main {:read 1 :write 1})]
     @p))

+(defn delete-table-request
+  "Implementation detail"
+  [table]
+  (DeleteTableRequest. (name table)))
+
 (defn delete-table "Deletes a table, go figure."
   [client-opts table]
-  (as-map (.deleteTable (db-client client-opts) (DeleteTableRequest. (name table)))))
+  (as-map (.deleteTable (db-client client-opts) ^DeleteTableRequest (delete-table-request table))))

 ;;;; API - items
+
+(defn get-item-request
+  "Implementation detail"
+  [table prim-kvs & [{:keys [attrs consistent? return-cc?]}]]
+  (doto-cond [g (GetItemRequest.)]
+    :always     (.setTableName       (name table))
+    :always     (.setKey             (clj-item->db-item prim-kvs))
+    consistent? (.setConsistentRead  g)
+    attrs       (.setAttributesToGet (mapv name g))
+    return-cc?  (.setReturnConsumedCapacity (utils/enum :total))))

 (defn get-item
   "Retrieves an item from a table by its primary key with options:
     prim-kvs     - {<hash-key> <val>} or {<hash-key> <val> <range-key> <val>}.
     :attrs       - Attrs to return, [<attr> ...].
     :consistent? - Use strongly (rather than eventually) consistent reads?"
-  [client-opts table prim-kvs & [{:keys [attrs consistent? return-cc?]}]]
+  [client-opts table prim-kvs & [opts]]
   (as-map
    (.getItem (db-client client-opts)
-    (doto-cond [g (GetItemRequest.)]
-      :always     (.setTableName       (name table))
-      :always     (.setKey             (clj-item->db-item prim-kvs))
-      consistent? (.setConsistentRead  g)
-      attrs       (.setAttributesToGet (mapv name g))
-      return-cc?  (.setReturnConsumedCapacity (utils/enum :total))))))
+    (get-item-request table prim-kvs opts))))

 (defn- expected-values
   "{<attr> <cond> ...} -> {<attr> ExpectedAttributeValue ...}"
@@ -635,6 +662,16 @@
         (ExpectedAttributeValue. (clj-val->db-val %)))
      expected-map)))

+(defn put-item-request
+  [table item & [{:keys [return expected return-cc?]
+                  :or   {return :none}}]]
+  (doto-cond [g (PutItemRequest.)]
+    :always  (.setTableName    (name table))
+    :always  (.setItem         (clj-item->db-item item))
+    expected (.setExpected     (expected-values g))
+    return   (.setReturnValues (utils/enum g))
+    return-cc? (.setReturnConsumedCapacity (utils/enum :total))))
+
 (defn put-item
   "Adds an item (Clojure map) to a table with options:
     :return   - e/o #{:none :all-old :updated-old :all-new :updated-new}.
@@ -643,15 +680,10 @@
                   {<attr> <expected-value> ...}
                   {<attr> false ...} ; Attribute must not exist"
   [client-opts table item & [{:keys [return expected return-cc?]
-                              :or   {return :none}}]]
+                              :as   opts}]]
   (as-map
    (.putItem (db-client client-opts)
-     (doto-cond [g (PutItemRequest.)]
-       :always  (.setTableName    (name table))
-       :always  (.setItem         (clj-item->db-item item))
-       expected (.setExpected     (expected-values g))
-       return   (.setReturnValues (utils/enum g))
-       return-cc? (.setReturnConsumedCapacity (utils/enum :total))))))
+     (put-item-request table item opts))))

 (defn- attribute-updates
   "{<attr> [<action> <value>] ...} -> {<attr> AttributeValueUpdate ...}"
@@ -661,6 +693,16 @@
      (fn [[action val]] (AttributeValueUpdate. (when val (clj-val->db-val val))
                                               (utils/enum action)))
      update-map)))
+(defn update-item-request
+  [table prim-kvs update-map & [{:keys [return expected return-cc?]
+                                 :or   {return :none}}]]
+  (doto-cond [g (UpdateItemRequest.)]
+    :always  (.setTableName        (name table))
+    :always  (.setKey              (clj-item->db-item prim-kvs))
+    :always  (.setAttributeUpdates (attribute-updates update-map))
+    expected (.setExpected         (expected-values g))
+    return   (.setReturnValues     (utils/enum g))
+    return-cc? (.setReturnConsumedCapacity (utils/enum :total))))

 (defn update-item
   "Updates an item in a table by its primary key with options:
@@ -669,30 +711,30 @@
     :return    - e/o #{:none :all-old :updated-old :all-new :updated-new}.
     :expected  - {<attr> <#{<expected-value> false}> ...}."
   [client-opts table prim-kvs update-map & [{:keys [return expected return-cc?]
-                                             :or   {return :none}}]]
+                                             :as   opts}]]
   (as-map
    (.updateItem (db-client client-opts)
-     (doto-cond [g (UpdateItemRequest.)]
-       :always  (.setTableName        (name table))
-       :always  (.setKey              (clj-item->db-item prim-kvs))
-       :always  (.setAttributeUpdates (attribute-updates update-map))
-       expected (.setExpected         (expected-values g))
-       return   (.setReturnValues     (utils/enum g))
-       return-cc? (.setReturnConsumedCapacity (utils/enum :total))))))
+     (update-item-request table prim-kvs update-map opts))))
+
+(defn delete-item-request
+  "Implementation detail"
+  [table prim-kvs & [{:keys [return expected return-cc?]
+                      :or   {return :none}}]]
+  (doto-cond [g (DeleteItemRequest.)]
+    :always  (.setTableName    (name table))
+    :always  (.setKey          (clj-item->db-item prim-kvs))
+    expected (.setExpected     (expected-values g))
+    return   (.setReturnValues (utils/enum g))
+    return-cc? (.setReturnConsumedCapacity (utils/enum :total))))

 (defn delete-item
   "Deletes an item from a table by its primary key.
   See `put-item` for option docs."
   [client-opts table prim-kvs & [{:keys [return expected return-cc?]
-                                  :or   {return :none}}]]
+                                  :as opts}]]
   (as-map
    (.deleteItem (db-client client-opts)
-     (doto-cond [g (DeleteItemRequest.)]
-       :always  (.setTableName    (name table))
-       :always  (.setKey          (clj-item->db-item prim-kvs))
-       expected (.setExpected     (expected-values g))
-       return   (.setReturnValues (utils/enum g))
-       return-cc? (.setReturnConsumedCapacity (utils/enum :total))))))
+     (delete-item-request table prim-kvs opts))))

 ;;;; API - batch ops

@@ -749,6 +791,13 @@
           (recur (merge-with merge-results last-result (more-f more))
                  (inc idx)))))))

+(defn batch-get-item-request
+  "Implementation detail"
+  [return-cc? raw-req]
+  (doto-cond [g (BatchGetItemRequest.)]
+    :always    (.setRequestItems raw-req)
+    return-cc? (.setReturnConsumedCapacity (utils/enum :total))))
+
 (defn batch-get-item
   "Retrieves a batch of items in a single request.
   Limits apply, Ref. http://goo.gl/Bj9TC.
@@ -768,9 +817,7 @@
   (letfn [(run1 [raw-req]
             (as-map
              (.batchGetItem (db-client client-opts)
-               (doto-cond [g (BatchGetItemRequest.)] ; {table-str KeysAndAttributes}
-                 :always    (.setRequestItems raw-req)
-                 return-cc? (.setReturnConsumedCapacity (utils/enum :total))))))]
+               ^BatchGetItemRequest (batch-get-item-request return-cc? raw-req))))]
     (merge-more run1 span-reqs (run1 (batch-request-items requests)))))

 (comment
@@ -784,6 +831,13 @@
   (case action
     :put    (doto (WriteRequest.) (.setPutRequest    (doto (PutRequest.)    (.setItem item))))
     :delete (doto (WriteRequest.) (.setDeleteRequest (doto (DeleteRequest.) (.setKey  item))))))
+
+(defn batch-write-item-request
+  "Implementation detail"
+  [return-cc? raw-req]
+  (doto-cond [g (BatchWriteItemRequest.)]
+    :always    (.setRequestItems raw-req)
+    return-cc? (.setReturnConsumedCapacity (utils/enum :total))))

 (defn batch-write-item
   "Executes a batch of Puts and/or Deletes in a single request.
@@ -802,9 +856,7 @@
   (letfn [(run1 [raw-req]
             (as-map
              (.batchWriteItem (db-client client-opts)
-               (doto-cond [g (BatchWriteItemRequest.)]
-                 :always    (.setRequestItems raw-req)
-                 return-cc? (.setReturnConsumedCapacity (utils/enum :total))))))]
+               ^BatchWriteItemRequest (batch-write-item-request return-cc? raw-req))))]
     (merge-more run1 span-reqs
       (run1
        (utils/name-map
@@ -834,6 +886,27 @@
            (.setComparisonOperator (enum-op operator))
            (.setAttributeValueList (mapv clj-val->db-val vals)))))
      conditions)))
+
+(defn query-request
+  "Implementation detail"
+  [table prim-key-conds
+   & [{:keys [last-prim-kvs query-filter span-reqs return index order limit consistent?
+              return-cc?] :as opts
+       :or {order :asc}}]]
+  (doto-cond [g (QueryRequest.)]
+    :always (.setTableName        (name table))
+    :always (.setKeyConditions    (query|scan-conditions prim-key-conds))
+    :always (.setScanIndexForward (case order :asc true :desc false))
+    last-prim-kvs   (.setExclusiveStartKey
+                     (clj-item->db-item last-prim-kvs))
+    query-filter    (.setQueryFilter (query|scan-conditions query-filter))
+    limit           (.setLimit     (int g))
+    index           (.setIndexName      g)
+    consistent?     (.setConsistentRead g)
+    (coll?* return) (.setAttributesToGet (mapv name return))
+    return-cc? (.setReturnConsumedCapacity (utils/enum :total))
+    (and return (not (coll?* return)))
+    (.setSelect (utils/enum return))))

 (defn query
   "Retrieves items from a table (indexed) with options:
@@ -867,26 +940,29 @@
   [client-opts table prim-key-conds
    & [{:keys [last-prim-kvs query-filter span-reqs return index order limit consistent?
               return-cc?] :as opts
-       :or   {span-reqs {:max 5}
-              order     :asc}}]]
+       :or   {span-reqs {:max 5}}}]]
   (letfn [(run1 [last-prim-kvs]
             (as-map
              (.query (db-client client-opts)
-               (doto-cond [g (QueryRequest.)]
-                 :always (.setTableName        (name table))
-                 :always (.setKeyConditions    (query|scan-conditions prim-key-conds))
-                 :always (.setScanIndexForward (case order :asc true :desc false))
-                 last-prim-kvs   (.setExclusiveStartKey
-                                  (clj-item->db-item last-prim-kvs))
-                 query-filter    (.setQueryFilter (query|scan-conditions query-filter))
-                 limit           (.setLimit     (int g))
-                 index           (.setIndexName      g)
-                 consistent?     (.setConsistentRead g)
-                 (coll?* return) (.setAttributesToGet (mapv name return))
-                 return-cc? (.setReturnConsumedCapacity (utils/enum :total))
-                 (and return (not (coll?* return)))
-                 (.setSelect (utils/enum return))))))]
+              (query-request table prim-key-conds opts))))]
     (merge-more run1 span-reqs (run1 last-prim-kvs))))
+
+(defn scan-request
+  [table
+   & [{:keys [attr-conds last-prim-kvs span-reqs return limit total-segments
+              segment return-cc?] :as opts}]]
+  (doto-cond [g (ScanRequest.)]
+    :always (.setTableName (name table))
+    attr-conds      (.setScanFilter        (query|scan-conditions g))
+    last-prim-kvs   (.setExclusiveStartKey
+                     (clj-item->db-item last-prim-kvs))
+    limit           (.setLimit             (int g))
+    total-segments  (.setTotalSegments     (int g))
+    segment         (.setSegment           (int g))
+    (coll?* return) (.setAttributesToGet (mapv name return))
+    return-cc? (.setReturnConsumedCapacity (utils/enum :total))
+    (and return (not (coll?* return)))
+    (.setSelect (utils/enum return))))

 (defn scan
   "Retrieves items from a table (unindexed) with options:
@@ -923,18 +999,7 @@
   (letfn [(run1 [last-prim-kvs]
             (as-map
              (.scan (db-client client-opts)
-               (doto-cond [g (ScanRequest.)]
-                 :always (.setTableName (name table))
-                 attr-conds      (.setScanFilter        (query|scan-conditions g))
-                 last-prim-kvs   (.setExclusiveStartKey
-                                  (clj-item->db-item last-prim-kvs))
-                 limit           (.setLimit             (int g))
-                 total-segments  (.setTotalSegments     (int g))
-                 segment         (.setSegment           (int g))
-                 (coll?* return) (.setAttributesToGet (mapv name return))
-                 return-cc? (.setReturnConsumedCapacity (utils/enum :total))
-                 (and return (not (coll?* return)))
-                 (.setSelect (utils/enum return))))))]
+               (scan-request table opts))))]
     (merge-more run1 span-reqs (run1 last-prim-kvs))))

 (defn scan-parallel


add keyspace to alia-session

add keyspace to alia-session

--- src/er_cassandra/session/alia.clj
+++ src/er_cassandra/session/alia.clj
@@ -15,7 +15,7 @@
   `(binding [debug true]
      ~@forms))

-(defrecord AliaSession [alia-session]
+(defrecord AliaSession [keyspace alia-session]
   Session
   (execute [_ statement]
     (aliam/execute
@@ -34,4 +34,4 @@
   (let [cluster (alia/cluster {:contact-points contact-points})
         alia-session (alia/connect cluster)]
     (alia/execute alia-session (str "USE " keyspace ";"))
-    (->AliaSession alia-session)))
+    (->AliaSession keyspace alia-session)))


Use io! macro in transactional-operation and with-db-transaction.

--- src/fhofherr/clj_db_util/core.clj
+++ src/fhofherr/clj_db_util/core.clj
@@ -144,7 +144,7 @@
   `(fn [~tx-state-bnd]
      {:post [(sequential? ~'%) (transaction-state? (second ~'%))]}
      (try
-       ~@body
+       (io! ~@body)
        (catch Exception ex#
          (*exception-during-transaction* ~tx-state-bnd ex#)))))

@@ -166,10 +166,11 @@

 (defn with-db-transaction
   [db tx-op]
-  (jdbc/with-db-transaction
-    [t-con (db-spec db)]
-    (let [tx-state (map->TransactionState {:t-con t-con})
-          [tx-result final-tx-state] (tx-op tx-state)]
-      (if (rollback-only? final-tx-state)
-        [tx-result err-transaction-rolled-back]
-        [tx-result nil]))))+  (io!
+   (jdbc/with-db-transaction
+     [t-con (db-spec db)]
+     (let [tx-state (map->TransactionState {:t-con t-con})
+           [tx-result final-tx-state] (tx-op tx-state)]
+       (if (rollback-only? final-tx-state)
+         [tx-result err-transaction-rolled-back]
+         [tx-result nil])))))


debugger: added Sweep All button

debugger: added Sweep All button

--- examples/_common/middleware/devtools.cljs
+++ examples/_common/middleware/devtools.cljs
@@ -41,10 +41,10 @@
   (assoc app-initial-model ::debugger
                            {:initial-model              app-initial-model

-                            :signal-events              (list)
+                            :signal-events              nil
                             :next-signal-id             0

-                            :action-events              (list)
+                            :action-events              nil
                             :next-action-id             0

                             :persist?                   false
@@ -119,6 +119,9 @@

            ::on-sweep
            (dispatch-action ::sweep)
+
+           ::on-sweep-all
+           (dispatch-action ::sweep-all)

            ::on-reset
            (do
@@ -186,6 +189,11 @@
            (as-> model m
                  (update-in m [::debugger :action-events] #(filter :enabled? %))
                  (update-in m [::debugger :signal-events] #(remove (partial -orphaned-signal? m) %)))
+
+           ::sweep-all
+           (-> model
+               (assoc-in [::debugger :signal-events] nil)
+               (assoc-in [::debugger :action-events] nil))

            ::toggle-visibility
            (update-in model [::debugger :visible?] not)
@@ -242,6 +250,7 @@
                                   :on-change #(dispatch ::on-toggle-persist)}]
    [:label {:for "persist-toggle"} "Persist session"]
    [-menu-button "Sweep" #(dispatch ::on-sweep) "Removes disabled actions and \"orphaned\" signals from history"]
+   [-menu-button "Sweep All" #(dispatch ::on-sweep-all) "Clears debugger history without affecting app model"]
    [-menu-button "Reset" #(dispatch ::on-reset) "Removes all actions and signals resetting the model to initial state"]
    [-menu-button
     (str "Hide (" toggle-visibility-shortcut ")")


small refactoring

small refactoring

--- src/heroku_releases_copy/core.clj
+++ src/heroku_releases_copy/core.clj
@@ -79,17 +79,18 @@
 (defn app-releases [app]
   (get-heroku-data (str "/apps/" app "/releases") heroku-options))

+; TODO -- how to unify these two functions?
+
 (defn get-latest-release [app]
-  (let [releases (app-releases app)]
-    (last (sort-by :version < releases))))
+  (let [release (last (sort-by :version < (app-releases app)))]
+    (get-in release [:slug :id])))

 (defn get-specific-release [app version]
-  (let [releases (app-releases app)]
-    (filter #(= version (:version %)) releases)))
+  (let [release (filter #(= version (:version %)) (app-releases app))]
+    (get-in release [:slug :id])))

-(defn copy-release [slug target configuration-data]
-  (let [deployment-data (post-heroku-data (str "/apps/" target "/releases") {"slug" slug})]
-    (merge configuration-data deployment-data)))
+(defn copy-release [slug target]
+  (post-heroku-data (str "/apps/" target "/releases") {"slug" slug}))

 (defn run-copy []
   (let [configuration-data (get-configuration-from-mongo (:app parameters))
@@ -99,10 +100,11 @@
                   (get-specific-release (:app parameters) (:version parameters)))
         merge-data (partial merge configuration-data)
         heroku-copier (comp save-to-mongo merge-data copy-release)] ; AOP on the cheap!
-    (dorun (map #(heroku-copier (get-in release [:slug :id]) %) targets))))
+    (dorun (map #(heroku-copier release %) targets))))

 ;-- Enable lein run
 (defn -main [] (run-copy))

+


Resolves TODOs

Resolves TODOs

--- src/hundred_pushups/ios/core.cljs
+++ src/hundred_pushups/ios/core.cljs
@@ -36,7 +36,6 @@
     ]
    [touchable-highlight {:style {:background-color "#999" :padding 10 :border-radius 5 :margin 10}
                          :on-press #(do
-                                      ;; TODO - change this to :complete-stage
                                       (dispatch [:complete-stage :learn-pushup-form])
                                       (dispatch [:db/save]))}
     [text {:style {:color "white" :text-align "center" :font-weight "bold"}} "OK, I've got it."]]])
@@ -46,7 +45,6 @@
   (let [ui-state (subscribe [:ui-state/get])]
     (fn []
       [view {}
-       [text {:style {}} @ui-state] ;; TODO - remove
        [text {:style {:text-align "center"}} "Do as many good pushups as you can."]
        [text {:style {:text-align "center"}} "Stop when it takes more than five seconds to do a rep or when you can't do any more reps."]
        [text {} "Reps:"]
@@ -66,7 +64,6 @@
   (let [ui-state (subscribe [:ui-state/get])]
     (fn []
       [view {}
-       [text {:style {}} @ui-state] ;; TODO - remove
        [text {:style {:text-align "center"}} "Hold a plank for as many breaths as you can (not seconds!)"]
        [text {:style {:text-align "center"}} "Stop when your form starts to get bad (e.g. sagging body)"]
        [text {} "Plank breadths:"]


Make topic config specific to topic.

Make topic config specific to topic.

--- src/kixi/eventlog/application.clj
+++ src/kixi/eventlog/application.clj
@@ -21,9 +21,9 @@
 (defn new-system
   ([] (let [zookeeper-connect  (or (System/getenv "ZK_CONNECT") "localhost:2181")
             topic              (or (System/getenv "TOPIC") "events")
-            num-partitions     (Integer/parseInt (or (System/getenv "TOPIC_NUM_PARTITIONS") "3"))
-            replication-factor (Integer/parseInt (or (System/getenv "TOPIC_REPLICATION_FACTOR") "3"))
-            max-message-size   (or (System/getenv "TOPIC_MAX_MESSAGE_SIZE") "1000000")] ;; annoying inconsistency Int vs String.
+            num-partitions     (Integer/parseInt (or (System/getenv (str (.toUpperCase topic) "_TOPIC_NUM_PARTITIONS")) "3"))
+            replication-factor (Integer/parseInt (or (System/getenv (str (.toUpperCase topic) "_TOPIC_REPLICATION_FACTOR")) "3"))
+            max-message-size   (or (System/getenv (str (.toUpperCase topic) "_TOPIC_MAX_MESSAGE_SIZE")) "1000000")] ;; annoying inconsistency Int vs String.
        (-> (map->EventLogApi
             {:web-server   (web/new-server)
              :repl-server  (Object.) ; dummy - replaced when invoked via controller.main


update docs

update docs

--- kafka-clj/test/kafka_clj/integration_v2_counts.clj
+++ kafka-clj/test/kafka_clj/integration_v2_counts.clj
@@ -21,7 +21,14 @@
 (defn- setup-test-data [topic n]
   (send-test-messages @client-ref topic n))

+(defn- read-messages [node]
+  (loop [msgs []]
+    (if-let [msg (read-msg! node 500)]
+      (recur (conj msgs msg))
+      msgs)))
+
 (defonce test-topic (uniq-name))
+(defonce msg-count 100000)

 (with-state-changes
   [ (before :facts (do (reset! state-ref (startup-resources test-topic))
@@ -34,12 +41,13 @@
                                            :conf {}}
                                           [test-topic]))
                        (Thread/sleep 1000)
-                       (setup-test-data test-topic 100000)))
+                       (setup-test-data test-topic msg-count)))
     (after :facts (do
                     (close @client-ref)
                     (shutdown-node! @node-ref)
                     (shutdown-resources @state-ref)))]

   (fact "Test message counts" :it
-
+        (let [msgs (read-messages @node-ref)]
+          (count msgs) => msg-count)
         ))


set mute on video els

set mute on video els

--- src/cellf/core.cljs
+++ src/cellf/core.cljs
@@ -225,9 +225,10 @@
                 :className (str "cell" (when adj (str " adjacent-" adj)))
                 :style     (get-cell-style app idx)
                 :onClick   #(when adj (move! app n))}
-           (dom/video #js {:autoPlay "autoplay"
-                           :style    (get-bg-transform app n)
-                           :ref      "vid"})
+           (dom/video #js {:autoPlay    true
+                           :muted       true
+                           :style       (get-bg-transform app n)
+                           :ref         "vid"})
            (dom/label nil (inc n))))))))


Being more careful about loading gapi

Being more careful about loading gapi

--- scrape-n-mail/src/scrape_n_mail/core.cljs
+++ scrape-n-mail/src/scrape_n_mail/core.cljs
@@ -12,7 +12,8 @@

 ;; define your app data so that it doesn't get over-written on reload

-(defonce app-data (atom {:signed-in? false
+(defonce app-data (atom {:initialized false
+                         :signed-in? false
                          :sheet-data nil}))
 (defonce wellbeing-sheet "1bv6vgW-HMTz0uhKDkrJoTg387b-WK6IFkFd9y6N96hA")

@@ -37,17 +38,24 @@
 ; This gets sent as a callback into the .load call for the gapi below in the "go" block
 (defn init-client [gapi_config]
   (-> (.init js/gapi.client gapi_config)
-      (.then (let [is-signed-in (.. js/gapi.auth2 getAuthInstance -isSignedIn)]
+      ; I don't actually care about the response, but I need to do something with it maybe?
+      (.then #(let [response %
+                    is-signed-in (.. js/gapi.auth2 getAuthInstance -isSignedIn)]
                ; Set up a listener per Google's tutorial
                (.listen is-signed-in update-after-auth)
                ; Also set the initial value
                ; Unfortunrately, this often doesn't work if we were already signed in...
                ; I'm missing something
-               (update-after-auth (.get is-signed-in)) ))))
+               (update-after-auth (.get is-signed-in))
+               (swap! app-data assoc :initialized true) )
+             ; This is an error reason
+             #(println %)
+             )))

 ; In retrospect, this was not really useful (these keys aren't secret).
 ; We're also hurting performance a little, but it's not relevant to our
 ; use-case so I'm leaving it alone.
+; (defonce _ ; doesn't seem to fix the reload problem with sheets not being defined.
 (go (let [keys-resp (<! (http/get "keys.json"))]
       (if (:success keys-resp)
         (let [config-keys
@@ -65,10 +73,11 @@
   [:div
     [:h2 "Wellness Scraper"]
     [:p "First, we will authenticate you to Google, then get some data from the Wellenss spreadsheet"]
-    (if-not (:signed-in? (rum/react app-data))
-      [:button {:id "authorize-button" :on-click #(.. js/gapi.auth2 getAuthInstance signIn)} "Authorize"]
-      [:button {:id "sign-out-button" :on-click #(.. js/gapi.auth2 getAuthInstance signOut)} "Sign Out"]
-      )
+    (if (:initialized (rum/react app-data))
+      (if-not (:signed-in? @app-data)
+        [:button {:id "authorize-button" :on-click #(.. js/gapi.auth2 getAuthInstance signIn)} "Authorize"]
+        [:button {:id "sign-out-button" :on-click #(.. js/gapi.auth2 getAuthInstance signOut)} "Sign Out"]
+        ) )
     ; Since I already react to app-data above, I don't seem to need to again...
     [:pre {:id "content"}
      (->> (:sheet-data @app-data)


Drop chars up to # in comments.

Drop chars up to # in comments.

--- src/cgdata/core.clj
+++ src/cgdata/core.clj
@@ -421,7 +421,7 @@
   [lines]
   (when-let [header (first (filter not-blank? (take 20 lines)))]
     (when (comment? header)
-      header)))
+      (subs header (inc (.indexOf header "#"))))))

 (def position-columns #{:chrom :chromStart :chromEnd :strand})


don't filter clojure-future-spec because of the clojure.future ns

--- src/main/shadow/cljs/npm/cli.cljs
+++ src/main/shadow/cljs/npm/cli.cljs
@@ -156,9 +156,6 @@
      ;; breaks cache when ending up with older version
      com.cognitect/transit-clj
      com.cognitect/transit-java
-
-     ;; spec for 1.8, never required
-     clojure-future-spec/clojure-future-spec
      })

 (defn drop-unwanted-deps [dependencies]


Add chapter and comic name and url normalize fns to data-function?

--- test/comic_reader/sites/test_util.clj
+++ test/comic_reader/sites/test_util.clj
@@ -80,8 +80,11 @@
     :chapter-number-pattern
     :chapter-number-match-pattern

-    :link-name-normalize
-    :link-url-normalize
+    :chapter-link-name-normalize
+    :chapter-link-url-normalize
+
+    :comic-link-name-normalize
+    :comic-link-url-normalize

     :page-normalize-format
     :page-normalize-pattern})


[#11398] Error at attempt to sign typed message in simpledapp.eth

Signed-off-by: andrey <b713972e59b8e606e23253c4a13e948139fea4d1@gmail.com>

--- src/status_im/browser/core.cljs
+++ src/status_im/browser/core.cljs
@@ -323,14 +323,14 @@

 (defn normalize-sign-message-params
   "NOTE (andrey) we need this function, because params may be mixed up"
-  [params]
+  [params typed?]
   (let [[first-param second-param] params]
     (when (and (string? first-param) (string? second-param))
       (cond
         (ethereum/address? first-param)
-        [first-param (normalize-message second-param)]
+        [first-param (if typed? second-param (normalize-message second-param))]
         (ethereum/address? second-param)
-        [second-param (normalize-message first-param)]))))
+        [second-param (if typed? second-param (normalize-message first-param))]))))

 (fx/defn send-to-bridge
   [cofx message]
@@ -339,20 +339,21 @@
 (fx/defn web3-send-async
   [cofx {:keys [method params id] :as payload} message-id]
   (let [message?      (constants/web3-sign-message? method)
-        dapps-address (get-in cofx [:db :multiaccount :dapps-address])]
+        dapps-address (get-in cofx [:db :multiaccount :dapps-address])
+        typed? (not= constants/web3-personal-sign method)]
     (if (or message? (= constants/web3-send-transaction method))
       (let [[address data] (cond (and (= method constants/web3-keycard-sign-typed-data)
                                       (not (vector? params)))
                                  ;; We don't use signer argument for keycard sign-typed-data
                                  ["0x0" params]
-                                 message? (normalize-sign-message-params params)
+                                 message? (normalize-sign-message-params params typed?)
                                  :else [nil nil])]
         (when (or (not message?) (and address data))
           (signing/sign cofx (merge
                               (if message?
                                 {:message {:address address
                                            :data data
-                                           :typed? (not= constants/web3-personal-sign method)
+                                           :typed? typed?
                                            :pinless? (= method constants/web3-keycard-sign-typed-data)
                                            :from dapps-address}}
                                 {:tx-obj  (update (first params) :from #(or % dapps-address))})


mod spec

mod spec

--- src/synthesis_crawlers/core.clj
+++ src/synthesis_crawlers/core.clj
@@ -27,9 +27,7 @@

 (s/def ::attr-extractor (s/map-of keyword? string?))
 (s/def ::container-extractor string?)
-(s/def ::empty-container #(and (string? %) (= (count %) 0)))
-(s/def ::empty-attr-extractor (s/map-of keyword? nil?))
-;(s/def ::incomplete-attr-extractor (s/map-of keyword? ))
+(s/def ::complete-attr-extractor (s/map-of keyword? string?))
 (s/def ::text string?)
 (s/def ::extractors (s/map-of ::container-extractor ::attr-extractor))
 (s/fdef extract


Improve onyx/fn doc.

Improve onyx/fn doc.

--- src/onyx/information_model.cljc
+++ src/onyx/information_model.cljc
@@ -329,7 +329,7 @@
                    :added "0.8.0"}

                   :onyx/fn
-                  {:doc "A function to transform a segment into another segment. A fully qualified, namespaced keyword that points to a function on the classpath. This function takes at least one argument - an incoming segment, and returns either a segment or a vector of segments. This function may not return `nil`. This function can be parameterized further through a variety of techniques."
+                  {:doc "A function to transform a segment into another segment. A fully qualified, namespaced keyword that points to a function on the classpath. This function takes at least one argument - an incoming segment, and returns either a segment or a vector of segments. This function may not return `nil`. This function can be parameterized further through a variety of techniques. The function is called to transform the segments before being processed by windows, being sent downstream, or being written to an output medium."
                    :type :keyword
                    :tags [:function]
                    :required-when ["`:onyx/type` is set to `:function`"]


Increase default publication creation timeout

--- src/onyx/information_model.cljc
+++ src/onyx/information_model.cljc
@@ -1101,7 +1101,7 @@
             {:doc "Timeout after a number of ms on attempting to create an Aeron publication"
              :optional? true
              :type :integer
-             :default 1000
+             :default 5000
              :added "0.8.0"}

             :onyx.messaging.aeron/embedded-media-driver-threading


Document :window/type :global use of window/window-key.

--- src/onyx/information_model.cljc
+++ src/onyx/information_model.cljc
@@ -540,6 +540,7 @@
             :window/window-key
             {:doc "The key of the incoming segments to window over. This key can represent any totally ordered domain, for example `:event-time`."
              :type :any
+             :optional-when ["`:window/type` is set to `:global`, and `:window/storage-strategy` includes `:ordered-log`."]
              :required-when ["`:window/type` is set to `:fixed`"
                              "`:window/type` is set to `:sliding`"
                              "`:window/type` is set to `:session`"]


Remove unnecessary <pid> from get-iplayer cmd.

--- src/beebster_clj/core.clj
+++ src/beebster_clj/core.clj
@@ -9,7 +9,8 @@

 (def iplayer-command
-  ["get_iplayer" "--nocopyright" "--limitmatches" "50" "--listformat" "<index> <pid> <thumbnail> <name> <episode>"])
+  ["get_iplayer" "--nocopyright" "--limitmatches" "50" "--listformat" "<index> <thumbnail> <name> <episode>"])
+;;

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


shape.core cleaning

shape.core cleaning

--- src/brevis/shape/core.clj
+++ src/brevis/shape/core.clj
@@ -1,60 +1,25 @@
 (ns brevis.shape.core
   (:import [java.awt.image BufferedImage]
            [java.awt Color])
-  (:use ;[penumbra opengl compute]
-        ;[penumbra.opengl core]
-        [brevis vector])
-  #_(:require #_[penumbra.data :as data]))
+  (:use [brevis vector]))

 (defn compute-normal
   "Compute the normal for some vertices of an arbitrary polygon."
   [vertices]
   (loop [vidx (range (count vertices))
-         normal (vec3 0 0 0)]
+         ^Vector3f normal (vec3 0 0 0)]
     (if (empty? vidx)
       (div normal (length normal))
       ;(mul (div normal (length normal)) -1.0)
       (recur (rest vidx)
-             (let [curr (nth vertices (first vidx))
-                   next (nth vertices (mod (first vidx) (count vertices)))]
+             (let [^Vector3f curr (nth vertices (first vidx))
+                   ^Vector3f next (nth vertices (mod (first vidx) (count vertices)))]
                (vec3 (+ (.x normal) (* (- (.y curr) (.y next))
                                        (+ (.z curr) (.z next))))
                      (+ (.y normal) (* (- (.z curr) (.z next))
                                        (+ (.x curr) (.x next))))
                      (+ (.z normal) (* (- (.x curr) (.x next))
                                        (+ (.y curr) (.y next))))))))))
-
-#_(defn- define-quads-display-list
-   "Create a quads display list."
-   [polys]
-   (create-display-list
-      (draw-quads
-        (loop [rem polys]
-          (apply normal (compute-normal (first rem)))
-          (doseq [v (first rem)]
-            (apply vertex v))))))
-
-#_(defn- define-triangles-display-list
-   "Create a tris display list."
-   [polys]
-   (create-display-list
-      (draw-triangles
-        (loop [rem polys]
-          (apply normal (compute-normal (first rem)))
-          (doseq [v (first rem)]
-            (apply vertex v))))))
-
-#_(defn define-display-list
-   "Penumbra suffers from slowdowns if you do per-vertex shapes on the fly. Compute a display list beforehand and save some CPU."
-   [poly-type polys]
-   (cond
-     (= :quads poly-type) (define-quads-display-list polys)
-     (= :triangles poly-type) (define-triangles-display-list polys)))
-
-#_(defn resize-shape
-  "Change the dimension of an object's shape."
-  [obj new-dim]
-  (assoc-in obj [:shape :dim] new-dim))

 (defn get-shape
   "Return the shape of an object."
@@ -67,29 +32,6 @@
   (.resize (.getShape obj) new-dim)
   obj)

-#_(defn textured-quad []
-   (push-matrix
-     (material :front-and-back)
-     (translate -0.5 -0.5 0.5)
-     (normal 0 0 -1)
-     (draw-quads
-       (texture 1 1) (vertex 1 1 0)
-       (texture 0 1) (vertex 0 1 0)
-       (texture 0 0) (vertex 0 0 0)
-       (texture 1 0) (vertex 1 0 0))))
-
-(defn xor [a b] (or (and a (not b)) (and (not a) b)))
-
-(defn init-checkers []
-  (def #^:dynamic *checkers*
-	  (let [tex (BufferedImage. 128 128 BufferedImage/TYPE_INT_ARGB)]
-     (for [x (range 128) y (range 128)]
-       (.setRGB tex x y
-         (.getRGB (if (xor (even? (bit-shift-right x 4)) (even? (bit-shift-right y 4)))
-                    (Color. 0.9 0.9 0.9 1.0)
-                    (Color. 0.8 0.8 0.8 1.0)))))
-     tex)))
-
 (defn get-mesh
   "Return a shape's mesh."
   [shp]


Minor cosmetic changes.

Minor cosmetic changes.

--- src/buddy/core/crypto.clj
+++ src/buddy/core/crypto.clj
@@ -351,9 +351,8 @@
     (try
       (calculate-authtag! cipher output offset)
       (catch InvalidCipherTextException e
-        (let [message (str "Couldn't generate gcm authentication tag: "
-                           (.getMessage e))]
-          (throw (ex-info message {:type :encryption :cause :authtag})))))
+        (as-> (str "Couldn't generate gcm authentication tag: " (.getMessage e)) $
+          (throw (ex-info $ {:type :encryption :cause :authtag})))))
     output))

 (defn decrypt-gcm
@@ -372,9 +371,8 @@
     (try
       (calculate-authtag! cipher output offset)
       (catch InvalidCipherTextException e
-        (let [message (str "Couldn't validate gcm authentication tag: "
-                           (.getMessage e))]
-          (throw (ex-info message {:type :validation :cause :authtag})))))
+        (as-> (str "Couldn't validate gcm authentication tag: " (.getMessage e)) $
+          (throw (ex-info $ {:type :validation :cause :authtag})))))
     output))

 (defn- aad->bytes


Capitalise default ugen docstrings

Capitalise default ugen docstrings

--- src/overtone/sc/ugen/defaults.clj
+++ src/overtone/sc/ugen/defaults.clj
@@ -31,13 +31,13 @@

 (def DEFAULT-ARG-DOCS
   {"bufnum" "A buffer or buffer index value."
-   "freq" "frequency in hz (cycles per second)"
-   "freq1" "frequency in hz (cycles per second)"
-   "freq2" "frequency in hz (cycles per second)"
-   "freq3" "frequency in hz (cycles per second)"
-   "phase" "the start point within a cycle"
-   "loop" "a boolean switch to turn on looping"
-   "in" "the input signal"
+   "freq" "Frequency in hz (cycles per second)"
+   "freq1" "Frequency in hz (cycles per second)"
+   "freq2" "Frequency in hz (cycles per second)"
+   "freq3" "Frequency in hz (cycles per second)"
+   "phase" "The start point within a cycle"
+   "loop" "A boolean switch to turn on looping"
+   "in" "The input signal"
    })

 (def DOC-WIDTH 45)


fix the link to close the overlay

fix the link to close the overlay

--- src-cljs/frontend/components/overlay.cljs
+++ src-cljs/frontend/components/overlay.cljs
@@ -152,7 +152,7 @@
                               :role "button"}
             "Sign Up"]]
           [:div.menu-footer
-           [:a.menu-footer-link {:href "#"}
+           [:a.menu-footer-link {:on-click #(cast! :overlay-closed)}
             "No thanks."]]])))))

 (def overlay-components


devtools: log edn and raw model object

devtools: log edn and raw model object

--- contrib/devtools/src/carry_devtools/core.cljs
+++ contrib/devtools/src/carry_devtools/core.cljs
@@ -202,7 +202,9 @@
                  (dispatch-action ::replay))

                [::on-log-action-result id]
-               (-> (-find-action @model id) :result pr-str println)
+               (let [result (:result (-find-action @model id))]
+                 (.log js/console "EDN:" (pr-str result))
+                 (.log js/console "Raw:" result))

                ::on-toggle-replay-mode
                (dispatch-action ::toggle-replay-mode)


trying new accessor for mapbox

trying new accessor for mapbox

--- src/pasmo_gigi/geo/ui/core.cljs
+++ src/pasmo_gigi/geo/ui/core.cljs
@@ -11,7 +11,7 @@
             [mapbox.L :as L])
   (:require-macros [cljs.core.async.macros :refer [go]]))

-(.log js/console "access token: " (-> js/L .-mapbox))
+(.log js/console "access token: " (.-mapbox js/L))

 (let [mapbox (.-mapbox js/L)]
   (set! (-> mapbox .-accessToken) "pk.eyJ1IjoidXJpczc3IiwiYSI6InRuYTZRa3MifQ._Bo-JRcA7QVGocCJvdSoJg"))


Revert the addition of liberator ring-response to not-found messages; it's causing responses to be sent with charset ISO-8859-1 instead of UTF-8. Need to investigate that further and then re-add ring-response

--- src/cfpb/qu/resources.clj
+++ src/cfpb/qu/resources.clj
@@ -69,7 +69,7 @@
                       (let [dataset (get-in request [:params :dataset])
                             message (str "No such dataset: " dataset)]
                         (case (:media-type representation)
-                          "text/html" (ring-response (not-found message))
+                          "text/html"  (not-found message)
                           message)))
   :handle-ok (fn [{:keys [request dataset metadata representation]}]
                (let [resource (-> (hal/new-resource (:uri request))
@@ -112,7 +112,7 @@
   :handle-not-found (fn [{:keys [dataset concept request representation]}]
                       (let [message (str "No such concept " concept " in dataset " dataset)]
                         (case (:media-type representation)
-                          "text/html" (ring-response (not-found message))
+                          "text/html" (not-found message)
                           message)))
   :handle-ok (fn [{:keys [dataset concept cdata request representation]}]
                (let [resource (-> (hal/new-resource (:uri request))
@@ -175,7 +175,7 @@
                             slice (get-in request [:params :slice])
                             message (str "No such slice: " dataset "/" slice)]
                         (case (:media-type representation)
-                          "text/html" (ring-response (not-found message))
+                          "text/html" (not-found message)
                           message)))
   :handle-ok (fn [{:keys [dataset metadata slice request representation]}]


Tweak dragenter

Tweak dragenter

--- src/chessground/drag.cljs
+++ src/chessground/drag.cljs
@@ -107,8 +107,9 @@
       (set! (-> dragging-div .-style .-top) (str (- (:top rect) (/ h 2)) "px"))
       (set! (-> dragging-div .-style .-display) "block")
       (reset! dragging-div-pos rect))
-    (let [dx (- (:left rect) (:left @dragging-div-pos))
-          dy (- (:top rect) (:top @dragging-div-pos))]
+    (let [pos @dragging-div-pos
+          dx (- (:left rect) (:left pos))
+          dy (- (:top rect) (:top pos))]
       (aset (.-style dragging-div)
             common/transform-prop (str "translate3d(" dx "px, " dy "px, 0)")))))


deactivate tokenizer

deactivate tokenizer

--- src/clj/ceres/curator.clj
+++ src/clj/ceres/curator.clj
@@ -25,7 +25,7 @@
 (defrecord Reaction [tweet reactions])

-(def tokenize (make-tokenizer "/home/konny/data/open-nlp/de-token.bin"))
+#_(def tokenize (make-tokenizer "/home/konny/data/open-nlp/de-token.bin"))

 (def stopwords
   (into #{}


Generalized the dot form classification

Generalized the dot form classification

--- src/clj/cljs/compiler.clj
+++ src/clj/cljs/compiler.clj
@@ -852,31 +852,28 @@
      (-> sym name (.substring 1) munge)
      (-> sym name munge))))

-(defn- classify-sub
-  [e]
-  (cond (property-symbol? e) ::property
-        (symbol? e)          ::symbol
-        (seq? e)             ::list
-        (nil? e)             ()
-        :default             ::unknown))
-
-(defmulti build-dot-form #(map classify-sub %))
-
-;; (.-p (...))
+(defn- classify-dot-form
+  [[target member args]]
+  [(cond (nil? target) ::error
+         :default      ::expr)
+   (cond (property-symbol? member) ::property
+         (symbol? member)          ::symbol
+         (seq? member)             ::list
+         :default                  ::error)
+   (cond (nil? args) ()
+         :default    ::expr)])
+
+(defmulti build-dot-form #(classify-dot-form %))
+
+
+;; (. o -p)
 ;; (. (...) -p)
-(defmethod build-dot-form [::list ::property ()]
+(defmethod build-dot-form [::expr ::property ()]
   [[target prop _]]
   {:dot-action ::access :target target :field (clean-symbol prop)})

-;; (.-p o)
-;; (. o -p)
-(defmethod build-dot-form [::symbol ::property ()]
-  [[target prop _]]
-  {:dot-action ::access :target target :field (clean-symbol prop)})
-
-;; (.-p o <args>)
 ;; (. o -p <args>)
-(defmethod build-dot-form [::symbol ::property ::list]
+(defmethod build-dot-form [::expr ::property ::list]
   [[target prop args]]
   (throw (Error. (str "Cannot provide arguments " args " on property access " prop))))

@@ -888,37 +885,27 @@
     {:dot-action ::call :target target :method (munge meth) :args args}
     {:dot-action ::call :target target :method (munge (first meth)) :args args}))

-;; (.m o 1 2)
 ;; (. o m 1 2)
-(defmethod build-dot-form [::symbol ::symbol ::list]
+(defmethod build-dot-form [::expr ::symbol ::expr]
   [[target meth args]]
   (build-method-call target meth args))

-;; (.m o)
 ;; (. o m)
-(defmethod build-dot-form [::symbol ::symbol ()]
+(defmethod build-dot-form [::expr ::symbol ()]
   [[target meth args]]
   (build-method-call target meth args))

 ;; (. o (m))
 ;; (. o (m 1 2))
-(defmethod build-dot-form [::symbol ::list ()]
-  [[target [meth & args] _]]
-  (build-method-call target meth args))
-
 ;; (. (. ...))
-(defmethod build-dot-form [::list ::list ()]
+;; (. (f _) m 1 2)
+(defmethod build-dot-form [::expr ::list ()]
   [[target meth _]]
   (build-method-call target meth ()))

-;; (.m (f _) 1 2)
-(defmethod build-dot-form [::list ::symbol ::list]
-  [[target meth args]]
-  (build-method-call target meth args))
-
 (defmethod build-dot-form :default
   [dot-form]
-  (throw (Error. (str "Unknown dot form of " dot-form " with cassification " (vec (map classify-sub dot-form))))))
+  (throw (Error. (str "Unknown dot form of " (list* '. dot-form) " with classification " (classify-dot-form dot-form)))))

 (defmethod parse '.
   [_ env [_ target & [field & member+]] _]


Drop unnecessary intermediate data from pileup results

--- src/cljam/algo/pileup.clj
+++ src/cljam/algo/pileup.clj
@@ -103,7 +103,7 @@
      (when-not deletion? indel)
      (when deletion? indel)
      (.qname aln)
-     aln)))
+     (dissoc aln :seqs-at-ref :quals-at-ref))))

 (defn- resolve-bases
   [[ref-pos alns]]


Reload friendly selected-district

Reload friendly selected-district

--- src/cljs/geoforms/db.cljs
+++ src/cljs/geoforms/db.cljs
@@ -128,7 +128,7 @@

 (def supported-ideas (atom #{}))

-(def selected-district (atom nil))
+(defonce selected-district (atom nil))

 (defn logout! []
   (ma/unlink! supported-ideas)


nil is default for transparent-color parameter

--- src/clojure/gift/core.clj
+++ src/clojure/gift/core.clj
@@ -19,7 +19,7 @@
   :quality            - quality of color quantization (should be > 0)
   :width              - width of resulting gif (if not provided the size of first frame is used)
   :height             - height of resulting gif (if not provided the size of first frame is used)
-  :transparent-color  - vector [r g b a] which defines color that will be transparent in resulting gif (default is [0 0 0 255])
+  :transparent-color  - vector [r g b a] which defines color that will be transparent in resulting gif. nil defines no transparent color (which is default)

 "
   [output-path images
@@ -32,13 +32,14 @@
       :or {delay 200
            iterations 0
            quality 10
-           transparent-color [0 0 0 255]}}]
+           transparent-color nil}}]
   (let [encoder (doto (gift.AnimatedGifEncoder.)
                   (.start output-path)
                   (.setRepeat iterations)
                   (.setQuality quality) ;; less is better
                   (.setDelay delay) ;; milliseconds
-                  (.setTransparent (when transparent-color
+                  (.setTransparent (if (nil? transparent-color)
+                                     transparent-color
                                      (apply #(java.awt.Color. %1 %2 %3 %4) transparent-color))))]
     (when (and width height)
       (.setSize encoder width height))


Add more examples

Add more examples

--- src/clojure/mcj/ch_xx.clj
+++ src/clojure/mcj/ch_xx.clj
@@ -1,6 +1,5 @@
 (ns mcj.ch_xx
-  (require [clojure.core.match :as m]
-           [defun :as f]))
+  (require [clojure.core.match :as m]))

 ;; Pattern matching using the defun macro
 (defn xor [x y]
@@ -13,8 +12,104 @@
 (xor (= 2 3) (= 3 3)) ; true
 ;(xor 0 0) ;; IllegalArgumentException: No matching clause

-(f/defun fibo
-  ([0] 0N)
-  ([1] 1N)
-  ([n] (+ (fibo (- n 1))
-          (fibo (- n 2)))))
+;; Using delays
+(def delayed-1
+  (delay
+   (Thread/sleep 3000)
+   (println "3 seconds later ..")
+   1))
+
+(realized? delayed-1) ;; false
+
+;; after 3 seconds later
+(realized? delayed-1) ;; true
+
+;; Using futures and promises
+(defn wait-3-seconds []
+  (Thread/sleep 3000)
+  (println)
+  (println "3 seconds later..."))
+
+(.start (Thread. wait-3-seconds))
+
+(defn val-as-future [n secs]
+  (future
+    (Thread/sleep (* secs 1000))
+    (println ("\n" (str secs " seconds later...")))
+    n))
+
+(def future-1 (val-as-future 1 3))
+
+(realized? future-1) ;; true
+(future-done? future-1) ;; true
+
+(def future-10 (val-as-future 10 10))
+
+;; cancel the future
+(future-cancel future-10)
+
+(future-cancelled? future-10) ;; true
+
+;; @future-10 ;; will raise error
+
+(def p (promise))
+
+(deliver p 100) ;; #promise[{:status :ready, :val 100} 0x4cb2764d]
+
+@p ;; 100
+
+(deliver p 200)
+
+@p ;; 100
+
+(defn lock-for-2-seconds []
+  (let [lock (Object. )
+        task-1 (fn []
+                 (future
+                   (locking lock
+                     (Thread/sleep 2000) ;; wait for 2 seconds
+                     (println "Task 1 completed"))))
+        task-2 (fn []
+                 (future
+                   (locking lock
+                     (Thread/sleep 1000) ;; wait for 1 second
+                     (println "Task 2 completed"))))]
+    (task-1)
+    (task-2)))
+
+(lock-for-2-seconds)
+
+;; Using vars
+
+(def ^:dynamic *thread-local-state* [1 2 3])
+
+(binding [*thread-local-state* [10 20]]
+  (map #(* % %) *thread-local-state*)) ;; (100 400)
+
+(map #(* % %) *thread-local-state*) ;; (1 4 9)
+
+(with-bindings {#'*thread-local-state* [10 20]}
+  (map #(* % %) *thread-local-state*)) ;; (100 400)
+
+(with-bindings {(var *thread-local-state*) [10 20]}
+  (map #(* % %) *thread-local-state*)) ;; (100 400)
+
+(def ^:dynamic *unbound-var*) ;; #'mcj.ch_xx/*unbound-var*
+
+(thread-bound? (var *unbound-var*)) ;; false
+
+(binding [*unbound-var* 1]
+  (thread-bound? (var *unbound-var*))) ;; true
+
+;; Mutable variables using the with-local-vars form
+(defn factorial [n]
+  (with-local-vars [i n acc 1]
+    (while (> @i 0)
+      (var-set acc (* @acc @i))
+      (var-set i (dec @i)))
+    (var-get acc)))
+
+(factorial 5) ;; 120
+(factorial 20) ;; 2432902008176640000
+
+;; Using refs: (TBC)


(stest/check `find-northpole) cannot generate good enough. I need to learn how to generate from sets or maps

--- src/adventofcode1/four.clj
+++ src/adventofcode1/four.clj
@@ -112,6 +112,8 @@
 (s/fdef find-northpole
         ;; need a better way to generate valid room names
         ;; ExceptionInfo Couldn't satisfy such-that predicate after 100 tries.  clojure.core/ex-info (core.clj:4725)
+        ;; :args (s/cat :names (s/coll-of (s/and string? valid-room-name?)))
+        ;; maybe I should look at https://github.com/gfredericks/test.chuck
         :args (s/cat :names (s/coll-of (s/and string? valid-room-name?)))
         :ret  (s/or :not-found nil :found (s/tuple integer? string?)))


Fix scene active/end handling.

Fix scene active/end handling.

--- src/afterglow/effects.clj
+++ src/afterglow/effects.clj
@@ -128,9 +128,12 @@
   constituent effects try to assign to the same target, the later ones
   will have a chance to override or blend with the earlier ones."
   [scene-name & effects]
-  (Effect. scene-name
-           (fn [show snapshot]
-             (reduce (fn [result current] (or (still-active? current show snapshot) result)) false effects))
-           (fn [show snapshot] (mapcat #(generate % show snapshot) effects))
-           (fn [show snapshot]
-             (reduce (fn [result current] (and (end current show snapshot) result)) true effects))))
+  (let [active (atom effects)]
+    (Effect. scene-name
+             (fn [show snapshot]
+               (swap! active (fn [fx] (filterv #(still-active? % show snapshot) fx)))
+               (seq @active))
+             (fn [show snapshot] (mapcat #(generate % show snapshot) @active))
+             (fn [show snapshot]
+               (swap! active (fn [fx] () (filterv #(not (end % show snapshot)) fx)))
+               (empty? @active)))))


Add initalization msg with datemo version

--- src/datemo/init.clj
+++ src/datemo/init.clj
@@ -6,6 +6,7 @@
 (require '[clojure.pprint :refer [pprint]])

 (defn init []
+  (println (apply str "Initializing datemo version: " (:datemo-version env)))
   (if (= "true" (env :testing))
     (db/init-db true)
     (db/init-db)))


CMR-5231: Change atom header.

CMR-5231: Change atom header.

--- search-app/src/cmr/search/results_handlers/atom_results_handler.clj
+++ search-app/src/cmr/search/results_handlers/atom_results_handler.clj
@@ -287,7 +287,7 @@
    :xmlns:dc "http://purl.org/dc/terms/"
    :xmlns:georss "http://www.georss.org/georss/10"
    :xmlns:time "http://a9.com/-/opensearch/extensions/time/1.0/"
-   :xmlns:echo "http://www.echo.nasa.gov/esip" ;; TODO change or delete this dead link
+   :xmlns:echo "https://cmr.earthdata.nasa.gov/legacy-services"
    :xmlns:gml "http://www.opengis.net/gml"
    :xmlns:esipdiscovery "http://commons.esipfed.org/ns/discovery/1.2/"
    :xmlns:os "http://a9.com/-/spec/opensearch/1.1/"


update code format.

update code format.

--- src/dbms/oracle.clj
+++ src/dbms/oracle.clj
@@ -4,7 +4,8 @@

 (def db-spec
   (oracle {:subname "@//192.168.1.83:1521/testdb"
-           :user "xxx" :password "xxx"
+           :user "xxx"
+           :password "xxx"
            :naming {:keys str/lower-case :fields str/upper-case}}))

 (defdb korma-db db-spec)


less logging

less logging

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -63,6 +63,9 @@
 (declare add-all-comps)
 (declare candidate-parents)
 (declare lazy-shuffle)
+(declare find-comp-paths-in)
+(declare add-all-comps-to-bolts)
+(declare add-all-comps-to-bolts-with-paths)

 (defn generate-all [spec language-model total-depth
                     & {:keys [max-total-depth truncate-children]
@@ -73,47 +76,47 @@
   (log/debug (str "generate-all: generating from spec with spec "
                   (strip-refs spec) "; max total depth: " max-total-depth))

-  (let [total-depth (if total-depth total-depth 0)
-        expressions
-        (->
-         (lightning-bolts language-model spec 0 total-depth :max-total-depth max-total-depth)
-         (add-all-comps-to-bolts spec language-model total-depth))]
-    (map (fn [expr]
-           (if (and false truncate-children)
-             (truncate expr [[:head][:comp]]) ;; remove :head and :comp for efficiency
-             ;; else, don't remove.
-             expr))
-         expressions)))
-
-(declare find-comp-paths-in)
-(declare add-all-comps-to-bolts-with-paths)
+  (let [total-depth (if total-depth total-depth 0)]
+    (->
+     (lightning-bolts language-model spec 0 total-depth :max-total-depth max-total-depth)
+     (add-all-comps-to-bolts spec language-model total-depth)
+     (truncate-expressions [[:head][:comp]])
+     )))

 (defn add-all-comps-to-bolts [bolts spec language-model total-depth]
   (log/debug (str "add-all-comps-to-bolts with (empty? bolts): " (empty? bolts)
                   "; spec: " (strip-refs spec)))
-  (lazy-mapcat
-   (fn [bolt]
-     (add-all-comps-to-bolts-with-paths [bolt] spec language-model total-depth
-                                        (find-comp-paths-in bolt [:head])))
-   bolts))
+  (cond
+    (= spec :fail)
+    nil
+    true
+    (lazy-mapcat
+     (fn [bolt]
+       (add-all-comps-to-bolts-with-paths [bolt] spec language-model total-depth
+                                          (find-comp-paths-in bolt [:head])))
+     bolts)))

 (defn add-all-comps-to-bolts-with-paths [bolts spec language-model total-depth comp-paths]
-  (log/debug (str "add-all-comps-to-bolts-with-paths with (empty? bolts): " (empty? bolts) "; spec: " spec))
-  (if (not (empty? comp-paths))
-    (let [path (first comp-paths)]
-      (add-all-comps-to-bolts-with-paths
-       (lazy-mapcat
-        (fn [bolt]
-          (log/debug (str "adding path: " (string/join " " path) " to bolt: " ((:morph language-model) bolt)))
-          (add-complement-to-bolt bolt path spec
-                                  language-model 0 total-depth
-                                  :max-total-depth max-total-depth))
-        bolts)
-       spec
-       language-model
-       total-depth
-       (rest comp-paths)))
-    bolts))
+  (log/trace (str "add-all-comps-to-bolts-with-paths with (empty? bolts): "
+                  (empty? bolts) "; spec: " (strip-refs spec)))
+  (cond (= spec :fail)
+        nil
+        true
+        (if (not (empty? comp-paths))
+          (let [path (first comp-paths)]
+            (add-all-comps-to-bolts-with-paths
+             (lazy-mapcat
+              (fn [bolt]
+                (log/debug (str "+comps: " ((:morph language-model) bolt) "@" "[" (string/join " " path) "]"))
+                (add-complement-to-bolt bolt path spec
+                                        language-model 0 total-depth
+                                        :max-total-depth max-total-depth))
+              bolts)
+             spec
+             language-model
+             total-depth
+             (rest comp-paths)))
+          bolts)))

 (defn find-comp-paths-in [bolt path]
   (if (not (= (get-in bolt path :none) :none))
@@ -123,7 +126,7 @@
 (defn add-complement-to-bolt [bolt path spec language-model depth total-depth
                               & {:keys [max-total-depth]
                                  :or {max-total-depth max-total-depth}}]
-  (log/debug (str "add-complement-to-bolt: start: " (show-bolt bolt path language-model) "@"
+  (log/trace (str "add-complement-to-bolt: start: " (show-bolt bolt path language-model) "@"
                   (string/join " " path)))
   (let [index (:index language-model)
         lexicon (:lexicon language-model)


*len_ps should not be annotated LongLong

--- src/caesium/binding.clj
+++ src/caesium/binding.clj
@@ -136,19 +136,19 @@
       ^bytes ^{Pinned {}} seed]]
     [^int crypto_sign
      [^bytes ^{Pinned {}} sm
-      ^jnr.ffi.byref.LongLongByReference ^{LongLong {}} smlen_p
+      ^jnr.ffi.byref.LongLongByReference smlen_p
       ^bytes ^{Pinned {}} m
       ^long ^{LongLong {}} mlen
       ^bytes ^{Pinned {}} sk]]
     [^int crypto_sign_open
      [^bytes ^{Pinned {}} m
-      ^jnr.ffi.byref.LongLongByReference ^{LongLong {}} mlen_p
+      ^jnr.ffi.byref.LongLongByReference mlen_p
       ^bytes ^{Pinned {}} sm
       ^long ^{LongLong {}} smlen
       ^bytes ^{Pinned {}} pk]]
     [^int crypto_sign_detached
      [^bytes ^{Pinned {}} sig
-      ^jnr.ffi.byref.LongLongByReference ^{LongLong {}} siglen_p
+      ^jnr.ffi.byref.LongLongByReference siglen_p
       ^bytes ^{Pinned {}} m
       ^long ^{LongLong {}} mlen
       ^bytes ^{Pinned {}} sk]]


This should be quite near stream as seq.

--- src/async/http/client.clj
+++ src/async/http/client.clj
@@ -125,7 +125,9 @@
                     (when-not (empty? bytes)
                       (let [v (apply str (map char bytes))]
                         ;;(println "putting: " v)
-                        (.put que v))))
+                        (.put que v)
+                        (if-not (contains? @state :body )
+                          (dosync (alter state assoc :body s-seq))
            done-seq (fn [state]
                       ;;(println "putting: " ::done)
                       (.put que ::done))


factor out subject-verb-agreement

factor out subject-verb-agreement

--- src/babel/english/pos.clj
+++ src/babel/english/pos.clj
@@ -2,10 +2,10 @@
   (:refer-clojure :exclude [get-in]))

 (require '[babel.english.morphology :refer (fo)])
-(require '[babel.lexiconfn :as lexiconfn :refer (map-function-on-map-vals)])
+(require '[babel.lexiconfn :as lexiconfn :refer (map-function-on-map-vals unify)])
 (require '[babel.pos :as pos])
 (require '[clojure.tools.logging :as log])
-(require '[dag-unify.core :as unify :refer (dissoc-paths get-in serialize unifyc)])
+(require '[dag-unify.core :as unify :refer (dissoc-paths get-in serialize)])

 (def adjective pos/adjective)
 (def animal pos/common-noun)
@@ -17,16 +17,19 @@
     {:english {:agr agr}
      :synsem {:agr agr}}))

+(def subject-verb-agreement
+  (let [infl (ref :top)
+        agr (ref :top)]
+    {:english {:agr agr
+               :infl infl}
+     :synsem {:infl infl
+              :subcat {:1 {:agr agr}}}}))
+
 ;; A generalization of intransitive and transitive:
 ;; they both have a subject, thus "subjective".
 (def verb-subjective
-  (unifyc pos/verb-subjective
-          (let [infl (ref :top)
-                agr (ref :top)]
-            {:english {:agr agr
-                       :infl infl}
-             :synsem {:infl infl
-                      :subcat {:1 {:agr agr}}}})))
+  (unify pos/verb-subjective
+         subject-verb-agreement))

 (def transitive
   (unifyc verb-subjective


fix issuer name not showing

fix issuer name not showing

--- src/cljs/salava/badge/ui/endorsement.cljs
+++ src/cljs/salava/badge/ui/endorsement.cljs
@@ -338,7 +338,7 @@
          [:div#endorsebadge

           (reduce (fn [r endorsement]
-                    (let [{:keys [id user_badge_id image_file name content issuer_name first_name last_name profile_picture endorser_id status]} endorsement]
+                    (let [{:keys [id user_badge_id image_file name content issuer_name first_name last_name profile_picture issuer_id issuer_name status]} endorsement]
                       (conj r [:div.panel.panel-default.endorsement
                                [:div.panel-heading {:id (str "heading" id)}
                                 [:div.panel-title
@@ -346,9 +346,9 @@
                                  [:div.row.flip.settings-endorsement
                                   [:div.col-md-9
                                    [:a {:href "#"
-                                        :on-click #(mo/open-modal [:user :profile] {:user-id endorser_id})}
+                                        :on-click #(mo/open-modal [:user :profile] {:user-id issuer_id})}
                                     [:img.small-image {:src (profile-picture profile_picture)}]
-                                    (str first_name " " last_name " ")] ]]]
+                                    issuer_name] ]]]

                                 [:div [:button {:type "button"
                                                 :aria-label "OK"


private support; better naming

private support; better naming

--- src/clojure/zensols/actioncli/dynamic.clj
+++ src/clojure/zensols/actioncli/dynamic.clj
@@ -22,7 +22,7 @@
 (defn dyn-init-var
   "Create a variable binding if it isn't already defined.

-  You probably want to use [[def-noclob]] and [[def-atom]] over this.
+  You probably want to use [[defnc-]] and [[defa-]] over this.

 Usage:
 ```clojure
@@ -44,25 +44,47 @@
        (let [new-var (intern *ns* var-sym)]
          (alter-var-root new-var (constantly init-val)))))))

-(defmacro def-noclob
-  "Create a variable binding out of **var** that doesn't already exist.  The
-  variable is initialized to **init-value**, otherwise it is bound to `nil`.
+(defmacro defnc
+  "Create a variable binding out of **sym** that doesn't already exist
+  (no clobbering).  The variable is initialized to **init-value**.

-  See [[def-atom]] and [[undef]]."
-  ([var]
-   `(dyn-init-var *ns* (quote ~var)))
-  ([var init-value]
-   `(dyn-init-var *ns* (quote ~var) (quote ~init-value))))
+  See [[defa]], [[defnc-]] and [[undef]]."
+  ([sym init-value]
+   `(let [msym# (quote ~sym)]
+      (dyn-init-var *ns* msym# (quote ~init-value)))))

-(defmacro def-atom
-  "Just like [[def-noclob]] but the initialization value is an atom created
+(defmacro defa
+  "Just like [[defnc]] but the initialization value is an atom created
   with **init-value** or `nil` if not given.

-  See [[def-noclob]] and [[undef]]."
-  ([var]
-   `(dyn-init-var *ns* (quote ~var) (atom nil)))
-  ([var init-value]
-   `(dyn-init-var *ns* (quote ~var) (atom (quote ~init-value)))))
+  See [[defnc]], [[defa-]] and [[undef]]."
+  ([sym]
+   `(let [msym# (quote ~sym)]
+      (dyn-init-var *ns* msym# (atom nil))))
+  ([sym init-value]
+   `(let [msym# (quote ~sym)]
+      (dyn-init-var *ns* msym# (atom (quote ~init-value))))))
+
+(defmacro defnc-
+  "Create a private variable binding out of **sym** that doesn't already exist
+  (no clobbering).  The variable is initialized to **init-value**.
+
+  See [[defa-]] and [[undef]]."
+  ([sym init-value]
+   `(let [msym# (with-meta (quote ~sym) {:private true})]
+      (dyn-init-var *ns* msym# (quote ~init-value)))))
+
+(defmacro defa-
+  "Just like [[defnc-]] but the initialization value is an atom created
+  with **init-value** or `nil` if not given.
+
+  See [[defnc-]] and [[undef]]."
+  ([sym]
+   `(let [msym# (with-meta (quote ~sym) {:private true})]
+      (dyn-init-var *ns* msym# (atom nil))))
+  ([sym init-value]
+   `(let [msym# (with-meta (quote ~sym) {:private true})]
+      (dyn-init-var *ns* msym# (atom (quote ~init-value))))))

 (defmacro undef
   "Unbind a variable in the current namespace.  Just like:


CMR-724: Added special case handling for this bad polygon.

--- src/cmr/indexer/data/concepts/spatial.clj
+++ src/cmr/indexer/data/concepts/spatial.clj
@@ -4,6 +4,7 @@

             ;; Must be required for derived calculations
             [cmr.spatial.geodetic-ring :as gr]
+            [cmr.spatial.ring-relations :as rr]
             [cmr.spatial.polygon :as p]
             [cmr.spatial.mbr :as mbr]
             [cmr.spatial.lr-binary-search :as lr]
@@ -23,13 +24,21 @@
      (with-prefix :south) (:south mbr)
      (with-prefix :crosses-antimeridian) (mbr/crosses-antimeridian? mbr)}))

+(def special-cases
+  "Created for CMR-724. It has mappings of specific spatial areas which cause problems to an equivalent
+  representation."
+  {(p/polygon :geodetic [(rr/ords->ring :geodetic
+                                        -179.9999 0.0, -179.9999 -89.9999, 0.0 -89.9999, 0.0 0.0,
+                                        0.0 89.9999, -179.9999 89.9999, -179.9999 0.0)])
+   mbr/whole-world})

 (defn shapes->elastic-doc
   "Converts a spatial shapes into the nested elastic attributes"
   [shapes coordinate-system]
-  (let [shapes (map d/calculate-derived
-                    (map (partial umm-s/set-coordinate-system coordinate-system)
-                         shapes))
+  (let [shapes (->> shapes
+                    (map (partial umm-s/set-coordinate-system coordinate-system))
+                    (map #(get special-cases % %))
+                    (map d/calculate-derived))
         ords-info-map (srl/shapes->ords-info-map shapes)
         lrs (map srl/shape->lr shapes)
         ;; union mbrs to get one covering the whole area


update miner to pull actual parent hash

update miner to pull actual parent hash

--- src/block_chain/miner.clj
+++ src/block_chain/miner.clj
@@ -22,11 +22,11 @@

 (defn latest-block-hash
   "Look up the hash of the latest block in the chain.
-   Useful for getting parent hash for new blocks. Eventually
-   this will need to grab the latest one off the chain but for now
-   we'll just zero it out."
+   Useful for getting parent hash for new blocks."
   []
-  (hex-string 0))
+  (if-let [parent (last @bc/block-chain)]
+    (get-in parent [:header :hash])
+    (hex-string 0)))

 (defn next-target
   "Calculate the appropriate next target based on the time frequency
@@ -57,7 +57,7 @@
       (recur (update-in block [:header :nonce] inc)))))

 (defn coinbase []
-  {:inputs [] :outputs [:amount 10 :address wallet/public-pem]})
+  {:inputs [] :outputs [:amount 25 :address wallet/public-pem]})

 (defn gather-transactions
   "Gather pending transactions from the network and add our own coinbase
@@ -66,25 +66,26 @@
   []
   [(coinbase)])

-(defn find-next-block
-  []
-  (mine (generate-block (gather-transactions))))
+(defn find-next-block [] (mine (generate-block (gather-transactions))))

 (def mine? (atom true))
+(defn stop-miner! [] (reset! mine? false))
 (defn run-miner! []
   (reset! mine? true)
   (async/go
     (while @mine?
-      (bc/add-block! (find-next-block)))))
-
-(defn stop-miner! [] (reset! mine? false))
+      (let [b (find-next-block)]
+        (println "****** Found a Block ******")
+        (println b)
+        (println "***************************")
+        (bc/add-block! b)))))

 ;; wallet -- using blockchain to find
 ;; balance / transaction outputs
 ;; wallet:
 ;; -- (available-utxos pub-key)
 ;; -- (available-balance pub-key)
-;; wallet:
+;; wallet:
 ;; (pay-to-address pub-key amount)
 ;; -- find utxo totaling this amount
 ;; -- generate new transaction transferring to that address


Show that dam number in the label of the upload dialog

--- src/cljc/mdr2/i18n.cljc
+++ src/cljc/mdr2/i18n.cljc
@@ -63,7 +63,7 @@
                     :depth "Depth"
                     ;;
                     :transitions-state "Transition state to '%1'"
-                    :upload-structure "Upload structure for '%1'"
+                    :upload-structure "Upload structure for '%1' (DAM %2)"
                     :upload-vubis "Upload Vubis export file"
                     ;;
                     :details "Details"
@@ -145,7 +145,7 @@
                     :modified-at "Letzte Änderung"
                     ;;
                     :transitions-state "Status auf '%1' setzen"
-                    :upload-structure "Struktur Datei für '%1' hochladen"
+                    :upload-structure "Struktur Datei für '%1' (DAM %2) hochladen"
                     :upload-vubis "Vubis Export Datei hochladen"
                     ;;
                     :details "Details"


Replace js math functions with Clojure Math/

--- src/cljs38/polygon.cljs
+++ src/cljs38/polygon.cljs
@@ -10,8 +10,8 @@
 (defn coordinates [number-of-edges radius]
   (letfn [
     (edge-coordinates [index]
-      [(* radius (.cos js/Math (/(* index 2 (aget js/Math "PI")) number-of-edges)))
-      (* radius (.sin js/Math (/(* index 2 (aget js/Math "PI")) number-of-edges)))])
+      [(* radius (Math/cos (/(* index 2 Math/PI) number-of-edges)))
+       (* radius (Math/sin (/(* index 2 Math/PI) number-of-edges)))])

     (next-edge [edges-left, edges]
       (if (> edges-left 0)


update match-listings docstring

update match-listings docstring

--- src/blx/sortable/core.clj
+++ src/blx/sortable/core.clj
@@ -166,12 +166,14 @@
     :matcher-maker (comp memoize make-title-matcher)}])

 (p/defnp match-listings
-  "Matches listings to products using listing-matcher. Returns a vector of
-  Result maps. The order of the results is nondeterministic because Tesser
-  is used to parallelize the matching across all cores."
-  [prepare-fn listing-matcher listings]
+  "Matches listings to products using listing-matcher. Returns the map
+       {:n-listings total-number-of-listings
+        :results    [{:product_name ... :listings [...]} ...]}
+  The order of the results is nondeterministic because Tesser is used
+  to parallelize the matching across all cores."
+  [parse-fn listing-matcher listings]
   (let [chunk-size 2048]
-    (->> (t/map prepare-fn)
+    (->> (t/map parse-fn)
          (t/fuse {:n-listings (t/count)
                   :results (->> (t/group-by (comp :product_name listing-matcher))
                                 (t/post-combine


Remove access keys and aws credentials to move to IAM role usage.

--- src/rsvp_backend/db/invitee.clj
+++ src/rsvp_backend/db/invitee.clj
@@ -4,9 +4,7 @@
             [taoensso.faraday :as ddb]))

 (def client-opts
-  {:access-key (util/get-config :aws :dynamodb :access-key)
-   :secret-key (util/get-config :aws :dynamodb :secret-key)
-   :endpoint   (util/get-config :aws :dynamodb :endpoint)})
+  {:endpoint   (util/get-config :aws :dynamodb :endpoint)})

 (def db-name (util/get-config :aws :dynamodb :db-name))


Add category-page html

Add category-page html

--- src/beebster_clj/views.clj
+++ src/beebster_clj/views.clj
@@ -52,7 +52,7 @@
      [:div.form-group
       [:input.form-control {:type "text" :name "searchvalue"}]]
      [:div.form-group
-      [:input.form-control {:type "submit" :value "Search"}]]]]))
+      [:input {:type "submit" :value "Search" :class "btn btn-default"}]]]]))

 (defn about-page
   []
@@ -65,3 +65,10 @@
    [:a {:href "http://www.infradead.org/get_iplayer/html/get_iplayer.html"}
     "get-iplayer"]))

+(defn category-page
+  [category]
+  (html
+   (base-template "Categories")
+   (header '(("/" "Index") ("/about" "About")))
+   [:h2.header (str category)]))
+


Don't reap cache on startup.

Don't reap cache on startup.

--- src/blocks/store/cache.clj
+++ src/blocks/store/cache.clj
@@ -40,7 +40,7 @@
              "Cache not initialized, no :state available"))))

-(defn reap-space!
+(defn reap!
   "Given a target amount of space to free and a cache store, deletes blocks from
   the cache to free up the desired amount of space. Returns a vector of the
   deleted entries."
@@ -69,7 +69,7 @@
                (or (nil? max-block-size)
                    (<= (:size block) max-block-size)))
       ; Free up enough space for the new block.
-      (reap-space! store (:size block))
+      (reap! store (:size block))
       ; Store the block and update cache state.
       (when-let [cached (block/put! cache block)]
         (swap! (:state store)
@@ -103,11 +103,6 @@
           (log/infof "Cache has %d bytes in %d blocks"
                      (:total-size initial-state)
                      (count (:priorities initial-state)))
-          (when (< size-limit (:total-size initial-state))
-            (log/infof "Reaping cache down to size limit of %d bytes" size-limit)
-            (let [deleted (reap-space! this 0)]
-              (log/infof "Deleted %d blocks to free %d bytes of space"
-                         (count deleted) (reduce + 0 (map :size deleted)))))
           this))))


Convert store behavior tests to test.carly harness.

--- src/blocks/store/tests.clj
+++ src/blocks/store/tests.clj
@@ -16,7 +16,8 @@
     [multihash.core :as multihash]
     [multihash.digest :as digest]
     [puget.color.ansi :as ansi]
-    [puget.printer :as puget])
+    [puget.printer :as puget]
+    [test.carly.core :as carly :refer [defop]])
   (:import
     blocks.data.Block
     blocks.data.PersistentBytes
@@ -52,89 +53,6 @@

-;; ## Operation Multimethods
-
-(defmulti ^:private apply-op
-  "Apply the operation to the store, returning a result value."
-  (fn dispatch
-    [store [op-key args]]
-    op-key))
-
-
-(defmethod apply-op :default
-  [store [op-key args]]
-  ; Try to resolve the key as a method in the blocks.core namespace.
-  (if-let [method (ns-resolve 'blocks.core (symbol (name op-key)))]
-    (method store args)
-    (throw (ex-info (str "No apply function available for operation " (pr-str op-key))
-                    {:op-key op-key}))))
-
-
-(defmulti ^:private update-model
-  "Apply an update to the model based on the operation."
-  (fn dispatch
-    [model [op-key args]]
-    op-key))
-
-
-(defmethod update-model :default
-  [model _]
-  ; By default, ops have no effect on model state.
-  model)
-
-
-(defmulti ^:private check-op
-  "Make assertions about an operation given the operation type, the model
-  state, and the args/response being tested."
-  ; TODO: should this include `is` or return a boolean?
-  (fn dispatch
-    [model [op-key args result]]
-    op-key))
-
-
-(defmethod check-op :default
-  [_ _]
-  ; By default, checks make no assertions.
-  true)
-
-
-(defmacro ^:private defop
-  "Defines a new specification for a store operation test."
-  [op-key & forms]
-  (let [form-map (into {} (map (juxt first rest)) forms)]
-    `(do
-       (defn- ~(symbol (str "gen-" (name op-key) "-op"))
-         ~(str "Constructs a " (name op-key) " operation spec generator.")
-         ~@(if-let [gen-form (get form-map 'gen-args)]
-             (if (= 1 (count gen-form))
-               [['blocks]
-                `(gen/tuple
-                   (gen/return ~op-key)
-                   ~(list (first gen-form) 'blocks))]
-               [(first gen-form)
-                `(gen/tuple
-                   (gen/return ~op-key)
-                   (do ~@(rest gen-form)))])
-             [['blocks]
-              `(gen/return [~op-key])]))
-       ~(when-let [apply-form (get form-map 'apply)]
-          `(defmethod apply-op ~op-key
-             [store# [op-key# args#]]
-             (let [~(first apply-form) [store# args#]]
-               ~@(rest apply-form))))
-       ~(when-let [check-form (get form-map 'check)]
-          `(defmethod check-op ~op-key
-             [model# [op-key# args# result#]]
-             (let [~(first check-form) [model# args# result#]]
-               ~@(rest check-form))))
-       ~(when-let [update-form (get form-map 'update)]
-          `(defmethod update-model ~op-key
-             [model# [op-key# args#]]
-             (let [~(first update-form) [model# args#]]
-               ~@(rest update-form)))))))
-
-
-
 ;; ## Operation Generators

 (defn- choose-id
@@ -149,52 +67,49 @@
   (gen/elements (vals blocks)))

-(defop :wait
-
-  (gen-args
-    [_]
-    (gen/choose 1 100))
-
-  (apply
-    [store duration]
-    (Thread/sleep duration)))
-
-
-(defop :stat
-
-  (gen-args choose-id)
-
-  (check
-    [model id result]
+(defop StatBlock
+  [id]
+
+  (gen-args
+    [ctx]
+    [(choose-id ctx)])
+
+  (apply-op
+    [this store]
+    (block/stat store id))
+
+  (check
+    [this model result]
     (if-let [block (get model id)]
-      (and (map? result)
-           (= (:id block) (:id result))
-           (= (:size block) (:size result))
-           (some? (:stored-at result)))
-      (nil? result))))
-
-
-(defop :list
-
-  (gen-args
-    [blocks]
-    (gen/fmap
-      (fn select
-        [[opts selection]]
-        (select-keys opts selection))
-      (gen/tuple
-        (gen/hash-map
-          :algorithm (gen/elements (keys digest/functions))
-          :after (gen/fmap hex/encode (gen/not-empty gen/bytes)) ; TODO: pick prefixes
-          :limit (gen/large-integer* {:min 1, :max (inc (count blocks))}))
-        (gen/set (gen/elements #{:algorithm :after :limit})))))
-
-  (apply
-    [store query]
+      (do (is (map? result))
+          (is (= (:id block) (:id result)))
+          (is (= (:size block) (:size result)))
+          (is (some? (:stored-at result))))
+      (is (nil? result)))))
+
+
+(defop ListBlocks
+  [query]
+
+  (gen-args
+    [blocks]
+    [(gen/fmap
+       (fn select
+         [[opts selection]]
+         (select-keys opts selection))
+       (gen/tuple
+         (gen/hash-map
+           :algorithm (gen/elements (keys digest/functions))
+           :after (gen/fmap hex/encode (gen/not-empty gen/bytes)) ; TODO: pick prefixes
+           :limit (gen/large-integer* {:min 1, :max (inc (count blocks))}))
+         (gen/set (gen/elements #{:algorithm :after :limit}))))])
+
+  (apply-op
+    [this store]
     (doall (block/list store query)))

   (check
-    [model query result]
+    [this model result]
     (let [expected-ids (cond->> (keys model)
                          (:after query)
                            (filter #(pos? (compare (multihash/hex %) (:after query))))
@@ -204,138 +119,186 @@
                            (sort)
                          (:limit query)
                            (take (:limit query)))]
-      (and (is (sequential? result))
-           (is (= (count result) (count expected-ids)))
-           (is (every? #(check-op model (cons :stat %))
-                       (map vector expected-ids result)))))))
-
-
-(defop :get
-
-  (gen-args choose-id)
-
-  (check
-    [model id result]
+      (is (sequential? result))
+      (is (= (count result) (count expected-ids)))
+      (doseq [[id stat] (zipmap expected-ids result)]
+        (if-let [block (get model id)]
+          (do (is (map? stat))
+              (is (= (:id block) (:id stat)))
+              (is (= (:size block) (:size stat)))
+              (is (some? (:stored-at stat))))
+          (is (nil? stat)))))))
+
+
+(defop GetBlock
+  [id]
+
+  (gen-args
+    [blocks]
+    [(choose-id blocks)])
+
+  (apply-op
+    [this store]
+    (block/get store id))
+
+  (check
+    [this model result]
     (if-let [block (get model id)]
-      (do
-        (is (some? (:id result)))
-        (is (integer? (:size result)))
-        (is (= id (:id result)))
-        (is (= (:size block) (:size result))))
-      (nil? result))))
-
-
-(defop :put!
-
-  (gen-args choose-block)
-
-  (check
-    [model block result]
-    (= block result))
-
-  (update
-    [model block]
+      (do (is (some? (:id result)))
+          (is (integer? (:size result)))
+          (is (= id (:id result)))
+          (is (= (:size block) (:size result))))
+      (is (nil? result)))))
+
+
+(defop PutBlock
+  [block]
+
+  (gen-args
+    [blocks]
+    [(choose-block blocks)])
+
+  (apply-op
+    [this store]
+    (block/put! store block))
+
+  (check
+    [this model result]
+    (is (= block result)))
+
+  (update-model
+    [this model]
     (assoc model (:id block) block)))

-(defop :delete!
-
-  (gen-args choose-id)
-
-  (check
-    [model id result]
+(defop DeleteBlock
+  [id]
+
+  (gen-args
+    [blocks]
+    [(choose-id blocks)])
+
+  (apply-op
+    [this store]
+    (block/delete! store id))
+
+  (check
+    [this model result]
     (if (contains? model id)
-      (true? result)
-      (false? result)))
-
-  (update
-    [model id]
+      (is (true? result))
+      (is (false? result))))
+
+  (update-model
+    [this model]
     (dissoc model id)))

-(defop :get-batch
-
-  (gen-args
-    [blocks]
-    (gen/set (choose-id blocks)))
-
-  (check
-    [model ids result]
-    (and (is (coll? result))
-         (is (= (set (keep model ids))
-                (set result))))))
-
-
-(defop :put-batch!
-
-  (gen-args
-    [blocks]
-    (gen/set (choose-block blocks)))
-
-  (check
-    [model blocks result]
-    (and (coll? result)
-         (= (set blocks) (set result))))
-
-  (update
-    [model blocks]
+(defop GetBlockBatch
+  [ids]
+
+  (gen-args
+    [blocks]
+    [(gen/set (choose-id blocks))])
+
+  (apply-op
+    [this store]
+    (block/get-batch store ids))
+
+  (check
+    [this model result]
+    (is (coll? result))
+    (is (= (set (keep model ids))
+           (set result)))))
+
+
+(defop PutBlockBatch
+  [blocks]
+
+  (gen-args
+    [blocks]
+    [(gen/set (choose-block blocks))])
+
+  (apply-op
+    [this store]
+    (block/put-batch! store blocks))
+
+  (check
+    [this model result]
+    (is (coll? result))
+    (is (= (set blocks) (set result))))
+
+  (update-model
+    [this model]
     (into model (map (juxt :id identity) blocks))))

-(defop :delete-batch!
-
-  (gen-args
-    [blocks]
-    (gen/set (choose-id blocks)))
-
-  (check
-    [model ids result]
-    (and (set? result)
-         (= result (set (filter (set ids) (keys model))))))
-
-  (update
-    [model ids]
+(defop DeleteBlockBatch
+  [ids]
+
+  (gen-args
+    [blocks]
+    [(gen/set (choose-id blocks))])
+
+  (apply-op
+    [this store]
+    (block/delete-batch! store ids))
+
+  (check
+    [this model result]
+    (is (set? result))
+    (is (= result (set (filter (set ids) (keys model))))))
+
+  (update-model
+    [this model]
     (apply dissoc model ids)))

-(defop :erase!!
-
-  (apply
-    [store _]
+(defop EraseStore
+  []
+
+  (apply-op
+    [this store]
     (block/erase!! store))

-  (update
-    [model _]
+  (update-model
+    [this model]
     (empty model)))

-(defop :scan
-
-  (gen-args
-    [_]
-    (gen/elements
-      [nil
-       (fn scan-pred
-         [stat]
-         (< (:size stat) 256))]))
-
-  (check
-    [model p result]
+(defop ScanStore
+  [p]
+
+  (gen-args
+    [blocks]
+    [(gen/elements [nil (fn scan-pred
+                          [stat]
+                          (< (:size stat) 256))])])
+
+  (apply-op
+    [this store]
+    ; TODO: bloom filter prints... poorly.
+    (block/scan store p))
+
+  (check
+    [this model result]
     (let [blocks (cond->> (vals model) p (filter p))]
-      (and (= (count blocks) (:count result))
-           (= (reduce + (map :size blocks)) (:size result))
-           (map? (:sizes result))
-           (every? integer? (keys (:sizes result)))
-           (= (count blocks) (reduce + (vals (:sizes result))))
-           (every? (partial sum/probably-contains? result) (map :id blocks))))))
-
-
-(defop :open
-
-  (gen-args choose-id)
-
-  (apply
-    [store id]
+      (is (= (count blocks) (:count result)))
+      (is (= (reduce + (map :size blocks)) (:size result)))
+      (is (map? (:sizes result)))
+      (is (every? integer? (keys (:sizes result))))
+      (is (= (count blocks) (reduce + (vals (:sizes result)))))
+      (is (every? (partial sum/probably-contains? result) (map :id blocks))))))
+
+
+(defop OpenBlock
+  [id]
+
+  (gen-args
+    [blocks]
+    [(choose-id blocks)])
+
+  (apply-op
+    [this store]
     (when-let [block (block/get store id)]
       (let [baos (java.io.ByteArrayOutputStream.)]
         (with-open [content (block/open block)]
@@ -343,13 +306,14 @@
         (.toByteArray baos))))

   (check
-    [model id result]
+    [this model result]
     (if-let [block (get model id)]
-      (bytes= (.toBuffer ^PersistentBytes @block) result)
-      (nil? result))))
-
-
-(defop :open-range
+      (is (bytes= (.toBuffer ^PersistentBytes @block) result))
+      (is (nil? result)))))
+
+
+(defop OpenBlockRange
+  [id start end]

   (gen-args
     [blocks]
@@ -358,13 +322,16 @@
       (fn [block]
         (gen/fmap
           (fn [positions]
-            (vec (cons (:id block) (sort positions))))
+            (let [[start end] (sort positions)]
+              {:id (:id block)
+               :start start
+               :end end}))
           (gen/vector-distinct
             (gen/large-integer* {:min 0, :max (:size block)})
             {:num-elements 2})))))

-  (apply
-    [store [id start end]]
+  (apply-op
+    [this store]
     (when-let [block (block/get store id)]
       (let [baos (java.io.ByteArrayOutputStream.)]
         (with-open [content (block/open block start end)]
@@ -372,78 +339,51 @@
         (.toByteArray baos))))

   (check
-    [model [id start end] result]
+    [this model result]
     (if-let [block (get model id)]
       (let [baos (java.io.ByteArrayOutputStream.)
             length (- end start)
             subarray (byte-array length)]
         (block/write! block baos)
         (System/arraycopy (.toByteArray baos) start subarray 0 length)
-        (bytes= subarray result))
-      (nil? result))))
-
-
-(defn- op-generators
-  [blocks]
-  [(gen-list-op blocks)
-   (gen-scan-op blocks)
-   (gen-stat-op blocks)
-   (gen-get-op blocks)
-   (gen-get-batch-op blocks)
-   (gen-open-op blocks)
-   (gen-open-range-op blocks)
-   (gen-put!-op blocks)
-   (gen-put-batch!-op blocks)
-   (gen-delete!-op blocks)
-   (gen-delete-batch!-op blocks)
-   (gen-erase!!-op blocks)])
-
-
-(defn- gen-op-seq
-  "Generates non-empty sequences of store operations for linear testing."
-  [blocks]
-  (->> (op-generators blocks)
-       (gen/one-of)
-       (gen/list)
-       (gen/not-empty)))
-
-
-(defn- gen-op-seq*
-  "Generates non-empty sequences of store operations for multithread testing,
-  including timing wait ops."
-  [blocks]
-  (->> (op-generators blocks)
-       (cons (gen-wait-op nil))
-       (gen/one-of)
-       (gen/list)
-       (gen/not-empty)))
+        (is (bytes= subarray result)))
+      (is (nil? result)))))
+
+
+(def ^:private op-generators
+  (juxt gen->StatBlock
+        gen->ListBlocks
+        ;gen->ScanStore
+        gen->GetBlock
+        gen->OpenBlock
+        gen->OpenBlockRange
+        gen->PutBlock
+        gen->DeleteBlock
+        gen->GetBlockBatch
+        gen->PutBlockBatch
+        gen->DeleteBlockBatch
+        gen->EraseStore))

 ;; ## Operation Testing

-(defn- apply-ops!
-  "Apply a sequence of operations to a store, returning a list of op vectors
-  with appended results."
-  [store ops]
-  (reduce
-    (fn [results op]
-      (conj results (conj op (apply-op store op))))
-    []
-    ops))
-
-
-(defn- valid-ops?
-  "Determines whether the given sequence of operations produced valid results
-  when applied to the store. Returns true if the store behavior is valid."
-  [ops]
-  (loop [model {}
-         ops ops]
-    (if-let [op (first ops)]
-      (if (check-op model op)
-        (recur (update-model model op) (rest ops))
-        false)
-      true)))
+(defn- start-store
+  [constructor]
+  (let [store (component/start (constructor))]
+    (when-not (empty? (block/list store))
+      (throw (IllegalStateException.
+               (str "Cannot run integration test on " (pr-str store)
+                    " as it already contains blocks!"))))
+    (is (zero? (:count (block/scan store))))
+    store))
+
+
+(defn- stop-store
+  [store]
+  (block/erase!! store)
+  (is (empty? (block/list store)) "ends empty")
+  (component/stop store))

 (defn check-store
@@ -461,53 +401,19 @@
                   :or {blocks 20, max-size 1024, iterations 100}}]
   {:pre [(fn? constructor)]}
   (let [test-blocks (generate-blocks! blocks max-size)]
-    (check/quick-check iterations
-      (prop/for-all [ops (gen-op-seq test-blocks)]
-        (let [store (constructor)]
-          (component/start store)
-          (try
-            (when-not (empty? (block/list store))
-              (throw (IllegalStateException.
-                       (str "Cannot run integration test on " (pr-str store)
-                            " as it already contains blocks!"))))
-            (is (zero? (:count (block/scan store))))
-            ; TODO: multithread test
-            (let [results (apply-ops! store ops)
-                  validity (valid-ops? results)]
-              (block/erase!! store)
-              (is (empty? (block/list store)) "ends empty")
-              validity)
-            (finally
-              (try
-                (component/stop store)
-                (catch Exception ex
-                  (println "Error stopping store:" ex))))))))))
-
-
-(defn check-store!
-  "Runs tests as for `check-store` but interprets the results for
-  `clojure.test`. Throws an exception if the tests do not succeed."
-  [& args]
-  (let [info (apply check-store args)]
-    (cond
-      (true? (:result info))
-        true
-
-      (or (false? (:result info))
-          (instance? Throwable (:result info)))
-        (do
-          (puget/pprint
-            info
-            {:print-color true
-             :print-handlers #(get {Multihash (puget/tagged-handler 'data/hash multihash/base58)
-                                    Block (puget/tagged-handler 'data/block (partial into {}))}
-                                   %
-                                   (puget/common-handlers %))})
-          (if (false? (:result info))
-            (throw (ex-info (format "Tests failed after %d iterations" (:num-tests info))
-                            {:info info}))
-            (throw (:result info))))
-
-      :else
-        (throw (ex-info (str "Unknown info format: " (pr-str info))
-                        {:info info})))))
+    (carly/check-system "integration testing" iterations
+      #(start-store constructor)
+      op-generators
+      :on-stop stop-store
+      :context-gen (gen/fmap
+                     (partial apply generate-blocks!)
+                     (gen/tuple
+                       (gen/choose 1 100)
+                       (gen/choose 16 4096)))
+      :repetitions 10
+      :report
+      {:puget {:print-handlers #(get {Multihash (puget/tagged-handler 'data/hash multihash/base58)
+                                      Block (puget/tagged-handler 'data/block (partial into {}))
+                                      (class (byte-array 0)) (puget/tagged-handler 'data/bytes alphabase.hex/encode)}
+                                     %
+                                     (puget/common-handlers %))}})))


finish clojure version

finish clojure version

--- Shortest-Unsorted-Continuous-Subarray/SUCS.clj
+++ Shortest-Unsorted-Continuous-Subarray/SUCS.clj
@@ -7,3 +7,13 @@
 (def test5 '())
 (def test6 '(3 2 1))

+(defn find-unsorted-subarray [nums]
+  (let [newNums (sort < nums)
+        result (atom 0)]
+    (doseq [[n o]
+            (map list newNums nums)
+            :when (not= n o)]
+      (swap! result inc))
+    @result))
+
+(find-unsorted-subarray test3)


datomic.query.EntityMap implements the interfaces:

  interface clojure.lang.IPersistentCollection
  interface datomic.query.EMapImpl
  interface clojure.lang.Associative
  interface clojure.lang.Seqable
  interface clojure.lang.ILookup
  interface datomic.Entity
  interface clojure.lang.IType

so added a clojure.lang.Associative clause in the IPersistentCollection route to generate a json-map.

--- src/cheshire/generate.clj
+++ src/cheshire/generate.clj
@@ -75,7 +75,9 @@
                             clojure.lang.IPersistentList
                             (generate-array jg obj date-format ex)
                             clojure.lang.ISeq
-                            (generate-array jg obj date-format ex))
+                            (generate-array jg obj date-format ex)
+                            clojure.lang.Associative
+                            (generate-map jg obj date-format ex))
     Map (generate-map jg obj date-format ex)
     List (generate-array jg obj date-format ex)
     Set (generate jg (seq obj) date-format ex)