sorts map and vector keyword entries in router-state-maintainer (#419)

--- waiter/src/waiter/state.clj
+++ waiter/src/waiter/state.clj
@@ -1185,170 +1185,171 @@
    Exposes the state of the router via a `query-state-fn` no-args function that is returned."
   [scheduler-state-chan router-chan router-id exit-chan service-id->service-description-fn deployment-error-config]
   (let [state-atom (atom {:all-available-service-ids #{}
-                          :service-id->healthy-instances {}
-                          :service-id->unhealthy-instances {}
-                          :service-id->my-instance->slots {} ; updated in update-router-state
-                          :service-id->expired-instances {}
-                          :service-id->starting-instances {}
-                          :service-id->failed-instances {}
-                          :service-id->instance-counts {}
-                          :service-id->deployment-error {}
-                          :service-id->instability-issue {}
                           :iteration 0
                           :routers []
+                          :service-id->deployment-error {}
+                          :service-id->expired-instances {}
+                          :service-id->failed-instances {}
+                          :service-id->healthy-instances {}
+                          :service-id->instability-issue {}
+                          :service-id->instance-counts {}
+                          :service-id->my-instance->slots {} ; updated in update-router-state
+                          :service-id->starting-instances {}
+                          :service-id->unhealthy-instances {}
                           :time (t/now)})
         router-state-push-chan (au/latest-chan)
-        query-chan (async/chan)]
-    {:router-state-push-mult (async/mult router-state-push-chan)
+        query-chan (async/chan)
+        go-chan
+        (async/go
+          (try
+            (loop [{:keys [iteration routers] :as current-state} @state-atom]
+              (reset! state-atom current-state)
+              (let [next-state
+                    (async/alt!
+                      exit-chan
+                      ([message]
+                        (log/warn "Stopping router-state-maintainer")
+                        (when (not= :exit message)
+                          (throw (ex-info "Stopping router-state maintainer" {:time (t/now), :reason message}))))
+
+                      scheduler-state-chan
+                      ([scheduler-messages]
+                        (cid/with-correlation-id
+                          (str "router-state-maintainer-" iteration)
+                          (loop [{:keys [service-id->healthy-instances service-id->unhealthy-instances service-id->my-instance->slots
+                                         service-id->expired-instances service-id->starting-instances service-id->failed-instances
+                                         service-id->instance-counts service-id->deployment-error service-id->instability-issue] :as loop-state} current-state
+                                 [[message-type message-data] & remaining] scheduler-messages]
+                            (log/trace "scheduler-state-chan received, type:" message-type)
+                            (let [loop-state'
+                                  (case message-type
+                                    :update-available-services
+                                    (let [{:keys [available-service-ids scheduler-sync-time]} message-data
+                                          all-available-service-ids' available-service-ids
+                                          services-without-instances (remove #(contains? service-id->my-instance->slots %) all-available-service-ids')
+                                          service-id->healthy-instances' (select-keys service-id->healthy-instances all-available-service-ids')
+                                          service-id->unhealthy-instances' (select-keys service-id->unhealthy-instances all-available-service-ids')
+                                          service-id->expired-instances' (select-keys service-id->expired-instances all-available-service-ids')
+                                          service-id->starting-instances' (select-keys service-id->starting-instances all-available-service-ids')
+                                          service-id->failed-instances' (select-keys service-id->failed-instances all-available-service-ids')
+                                          service-id->instance-counts' (select-keys service-id->instance-counts all-available-service-ids')
+                                          service-id->deployment-error' (select-keys service-id->deployment-error all-available-service-ids')
+                                          service-id->instability-issue' (select-keys service-id->instability-issue all-available-service-ids')]
+                                      (when (or (not= service-id->healthy-instances service-id->healthy-instances')
+                                                (not= service-id->unhealthy-instances service-id->unhealthy-instances')
+                                                (seq services-without-instances))
+                                        (log/info "update-available-services:"
+                                                  (count service-id->healthy-instances') "services with healthy instances and"
+                                                  (count services-without-instances) "services without instances:"
+                                                  (vec services-without-instances)))
+                                      (assoc loop-state
+                                        :all-available-service-ids all-available-service-ids'
+                                        :service-id->healthy-instances service-id->healthy-instances'
+                                        :service-id->unhealthy-instances service-id->unhealthy-instances'
+                                        :service-id->expired-instances service-id->expired-instances'
+                                        :service-id->starting-instances service-id->starting-instances'
+                                        :service-id->failed-instances service-id->failed-instances'
+                                        :service-id->instance-counts service-id->instance-counts'
+                                        :service-id->deployment-error service-id->deployment-error'
+                                        :service-id->instability-issue service-id->instability-issue'
+                                        :time scheduler-sync-time))
+
+                                    :update-service-instances
+                                    (let [{:keys [service-id healthy-instances unhealthy-instances failed-instances instance-counts scheduler-sync-time]} message-data
+                                          service-id->healthy-instances' (assoc service-id->healthy-instances service-id healthy-instances)
+                                          service-id->unhealthy-instances' (assoc service-id->unhealthy-instances service-id unhealthy-instances)
+                                          service-description (service-id->service-description-fn service-id)
+                                          grace-period-secs (t/seconds (int (get service-description "grace-period-secs")))
+                                          expiry-mins-int (int (get service-description "instance-expiry-mins"))
+                                          expiry-mins (t/minutes expiry-mins-int)
+                                          expired-instances (filter #(and (pos? expiry-mins-int)
+                                                                          (du/older-than? scheduler-sync-time expiry-mins %))
+                                                                    healthy-instances)
+                                          starting-instances (filter #(not (du/older-than? scheduler-sync-time grace-period-secs %)) unhealthy-instances)
+                                          service-id->expired-instances' (assoc service-id->expired-instances service-id expired-instances)
+                                          service-id->starting-instances' (assoc service-id->starting-instances service-id starting-instances)
+                                          service-id->failed-instances' (assoc service-id->failed-instances service-id failed-instances)
+                                          service-id->instance-counts' (assoc service-id->instance-counts service-id instance-counts)
+                                          deployment-error (get-deployment-error healthy-instances unhealthy-instances failed-instances deployment-error-config)
+                                          service-id->deployment-error' (if deployment-error
+                                                                          (assoc service-id->deployment-error service-id deployment-error)
+                                                                          (dissoc service-id->deployment-error service-id))
+                                          instability-issue (get-instability-issue failed-instances)
+                                          service-id->instability-issue' (if instability-issue
+                                                                           (assoc service-id->instability-issue service-id instability-issue)
+                                                                           (dissoc service-id->instability-issue service-id))]
+                                      (when (or (not= (get service-id->healthy-instances service-id) healthy-instances)
+                                                (not= (get service-id->unhealthy-instances service-id) unhealthy-instances))
+                                        (let [curr-instance-ids (set (map :id healthy-instances))
+                                              prev-instance-ids (set (map :id (get service-id->healthy-instances service-id)))
+                                              new-instance-ids (filterv (complement prev-instance-ids) curr-instance-ids)
+                                              rem-instance-ids (filterv (complement curr-instance-ids) prev-instance-ids)
+                                              unhealthy-instance-ids (mapv :id (get service-id->unhealthy-instances' service-id))]
+                                          (log/info "update-healthy-instances:" service-id "has"
+                                                    (count healthy-instances) "healthy instance(s) and"
+                                                    (count unhealthy-instance-ids) "unhealthy instance(s)."
+                                                    (if (seq new-instance-ids) (str "New healthy instances: " new-instance-ids ".") "")
+                                                    (if (seq rem-instance-ids) (str "Removed healthy instances: " rem-instance-ids ".") "")
+                                                    (if (seq unhealthy-instance-ids) (str "Unhealthy instances: " unhealthy-instance-ids ".") ""))))
+                                      (assoc loop-state
+                                        :service-id->deployment-error service-id->deployment-error'
+                                        :service-id->expired-instances service-id->expired-instances'
+                                        :service-id->failed-instances service-id->failed-instances'
+                                        :service-id->healthy-instances service-id->healthy-instances'
+                                        :service-id->instability-issue service-id->instability-issue'
+                                        :service-id->instance-counts service-id->instance-counts'
+                                        :service-id->starting-instances service-id->starting-instances'
+                                        :service-id->unhealthy-instances service-id->unhealthy-instances'
+                                        :time scheduler-sync-time))
+
+                                    ; default value
+                                    (do
+                                      (log/warn "scheduler-state-chan unknown message type=" message-type)
+                                      loop-state))]
+                              (if (nil? remaining)
+                                (let [new-state (update-router-state router-id current-state loop-state' service-id->service-description-fn)
+                                      relevant-keys [:service-id->deployment-error :service-id->expired-instances :service-id->failed-instances
+                                                     :service-id->healthy-instances :service-id->instability-issue :service-id->instance-counts
+                                                     :service-id->starting-instances :service-id->unhealthy-instances]]
+                                  (when (not= (select-keys current-state relevant-keys)
+                                              (select-keys new-state relevant-keys))
+                                    ; propagate along router-state-push-chan only when state changes
+                                    (async/put! router-state-push-chan new-state))
+                                  new-state)
+                                (recur loop-state' remaining))))))
+
+                      query-chan
+                      ([response-chan]
+                        (async/put! response-chan current-state)
+                        current-state)
+
+                      router-chan
+                      ([data]
+                        (cid/with-correlation-id
+                          (str "router-state-maintainer-" iteration)
+                          (let [router-id->endpoint-url data
+                                new-state
+                                (if (not= routers router-id->endpoint-url)
+                                  (let [candidate-state (assoc current-state :routers router-id->endpoint-url)
+                                        current-routers (-> current-state :routers keys vec sort)
+                                        new-routers (-> router-id->endpoint-url keys vec sort)]
+                                    (log/info "peer router info changed from" current-routers "to" new-routers)
+                                    (metrics/update-counter (metrics/waiter-counter "core" "number-of-routers") routers router-id->endpoint-url)
+                                    (update-router-state router-id current-state candidate-state service-id->service-description-fn))
+                                  current-state)]
+                            (async/put! router-state-push-chan new-state)
+                            new-state))))]
+                (if next-state
+                  (recur next-state)
+                  (log/info "Stopping router-state-maintainer as next state is nil"))))
+            (catch Exception e
+              (log/error e "Fatal error in router-state-maintainer!")
+              (System/exit 1))))]
+    {:go-chan go-chan
      :query-chan query-chan
      :query-state-fn (fn router-state-maintainer-query-state-fn []
                        (assoc @state-atom :router-id router-id))
-     :go-chan
-     (async/go
-       (try
-         (loop [{:keys [iteration routers] :as current-state} @state-atom]
-           (reset! state-atom current-state)
-           (let [next-state
-                 (async/alt!
-                   exit-chan
-                   ([message]
-                     (log/warn "Stopping router-state-maintainer")
-                     (when (not= :exit message)
-                       (throw (ex-info "Stopping router-state maintainer" {:time (t/now), :reason message}))))
-
-                   scheduler-state-chan
-                   ([scheduler-messages]
-                     (cid/with-correlation-id
-                       (str "router-state-maintainer-" iteration)
-                       (loop [{:keys [service-id->healthy-instances service-id->unhealthy-instances service-id->my-instance->slots
-                                      service-id->expired-instances service-id->starting-instances service-id->failed-instances
-                                      service-id->instance-counts service-id->deployment-error service-id->instability-issue] :as loop-state} current-state
-                              [[message-type message-data] & remaining] scheduler-messages]
-                         (log/trace "scheduler-state-chan received, type:" message-type)
-                         (let [loop-state'
-                               (case message-type
-                                 :update-available-services
-                                 (let [{:keys [available-service-ids scheduler-sync-time]} message-data
-                                       all-available-service-ids' available-service-ids
-                                       services-without-instances (remove #(contains? service-id->my-instance->slots %) all-available-service-ids')
-                                       service-id->healthy-instances' (select-keys service-id->healthy-instances all-available-service-ids')
-                                       service-id->unhealthy-instances' (select-keys service-id->unhealthy-instances all-available-service-ids')
-                                       service-id->expired-instances' (select-keys service-id->expired-instances all-available-service-ids')
-                                       service-id->starting-instances' (select-keys service-id->starting-instances all-available-service-ids')
-                                       service-id->failed-instances' (select-keys service-id->failed-instances all-available-service-ids')
-                                       service-id->instance-counts' (select-keys service-id->instance-counts all-available-service-ids')
-                                       service-id->deployment-error' (select-keys service-id->deployment-error all-available-service-ids')
-                                       service-id->instability-issue' (select-keys service-id->instability-issue all-available-service-ids')]
-                                   (when (or (not= service-id->healthy-instances service-id->healthy-instances')
-                                             (not= service-id->unhealthy-instances service-id->unhealthy-instances')
-                                             (seq services-without-instances))
-                                     (log/info "update-available-services:"
-                                               (count service-id->healthy-instances') "services with healthy instances and"
-                                               (count services-without-instances) "services without instances:"
-                                               (vec services-without-instances)))
-                                   (assoc loop-state
-                                     :all-available-service-ids all-available-service-ids'
-                                     :service-id->healthy-instances service-id->healthy-instances'
-                                     :service-id->unhealthy-instances service-id->unhealthy-instances'
-                                     :service-id->expired-instances service-id->expired-instances'
-                                     :service-id->starting-instances service-id->starting-instances'
-                                     :service-id->failed-instances service-id->failed-instances'
-                                     :service-id->instance-counts service-id->instance-counts'
-                                     :service-id->deployment-error service-id->deployment-error'
-                                     :service-id->instability-issue service-id->instability-issue'
-                                     :time scheduler-sync-time))
-
-                                 :update-service-instances
-                                 (let [{:keys [service-id healthy-instances unhealthy-instances failed-instances instance-counts scheduler-sync-time]} message-data
-                                       service-id->healthy-instances' (assoc service-id->healthy-instances service-id healthy-instances)
-                                       service-id->unhealthy-instances' (assoc service-id->unhealthy-instances service-id unhealthy-instances)
-                                       service-description (service-id->service-description-fn service-id)
-                                       grace-period-secs (t/seconds (int (get service-description "grace-period-secs")))
-                                       expiry-mins-int (int (get service-description "instance-expiry-mins"))
-                                       expiry-mins (t/minutes expiry-mins-int)
-                                       expired-instances (filter #(and (pos? expiry-mins-int)
-                                                                       (du/older-than? scheduler-sync-time expiry-mins %))
-                                                                 healthy-instances)
-                                       starting-instances (filter #(not (du/older-than? scheduler-sync-time grace-period-secs %)) unhealthy-instances)
-                                       service-id->expired-instances' (assoc service-id->expired-instances service-id expired-instances)
-                                       service-id->starting-instances' (assoc service-id->starting-instances service-id starting-instances)
-                                       service-id->failed-instances' (assoc service-id->failed-instances service-id failed-instances)
-                                       service-id->instance-counts' (assoc service-id->instance-counts service-id instance-counts)
-                                       deployment-error (get-deployment-error healthy-instances unhealthy-instances failed-instances deployment-error-config)
-                                       service-id->deployment-error' (if deployment-error
-                                                                       (assoc service-id->deployment-error service-id deployment-error)
-                                                                       (dissoc service-id->deployment-error service-id))
-                                       instability-issue (get-instability-issue failed-instances)
-                                       service-id->instability-issue' (if instability-issue
-                                                                        (assoc service-id->instability-issue service-id instability-issue)
-                                                                        (dissoc service-id->instability-issue service-id))]
-                                   (when (or (not= (get service-id->healthy-instances service-id) healthy-instances)
-                                             (not= (get service-id->unhealthy-instances service-id) unhealthy-instances))
-                                     (let [curr-instance-ids (set (map :id healthy-instances))
-                                           prev-instance-ids (set (map :id (get service-id->healthy-instances service-id)))
-                                           new-instance-ids (filterv (complement prev-instance-ids) curr-instance-ids)
-                                           rem-instance-ids (filterv (complement curr-instance-ids) prev-instance-ids)
-                                           unhealthy-instance-ids (mapv :id (get service-id->unhealthy-instances' service-id))]
-                                       (log/info "update-healthy-instances:" service-id "has"
-                                                 (count healthy-instances) "healthy instance(s) and"
-                                                 (count unhealthy-instance-ids) "unhealthy instance(s)."
-                                                 (if (seq new-instance-ids) (str "New healthy instances: " new-instance-ids ".") "")
-                                                 (if (seq rem-instance-ids) (str "Removed healthy instances: " rem-instance-ids ".") "")
-                                                 (if (seq unhealthy-instance-ids) (str "Unhealthy instances: " unhealthy-instance-ids ".") ""))))
-                                   (assoc loop-state
-                                     :service-id->healthy-instances service-id->healthy-instances'
-                                     :service-id->unhealthy-instances service-id->unhealthy-instances'
-                                     :service-id->expired-instances service-id->expired-instances'
-                                     :service-id->starting-instances service-id->starting-instances'
-                                     :service-id->failed-instances service-id->failed-instances'
-                                     :service-id->instance-counts service-id->instance-counts'
-                                     :service-id->deployment-error service-id->deployment-error'
-                                     :service-id->instability-issue service-id->instability-issue'
-                                     :time scheduler-sync-time))
-
-                                 ; default value
-                                 (do
-                                   (log/warn "scheduler-state-chan unknown message type=" message-type)
-                                   loop-state))]
-                           (if (nil? remaining)
-                             (let [new-state (update-router-state router-id current-state loop-state' service-id->service-description-fn)
-                                   relevant-keys [:service-id->healthy-instances :service-id->unhealthy-instances :service-id->expired-instances
-                                                  :service-id->starting-instances :service-id->failed-instances :service-id->instance-counts
-                                                  :service-id->deployment-error :service-id->instability-issue]]
-                               (when (not= (select-keys current-state relevant-keys)
-                                           (select-keys new-state relevant-keys))
-                                 ; propagate along router-state-push-chan only when state changes
-                                 (async/put! router-state-push-chan new-state))
-                               new-state)
-                             (recur loop-state' remaining))))))
-
-                   query-chan
-                   ([response-chan]
-                    (async/put! response-chan current-state)
-                    current-state)
-
-                   router-chan
-                   ([data]
-                     (cid/with-correlation-id
-                       (str "router-state-maintainer-" iteration)
-                       (let [router-id->endpoint-url data
-                             new-state
-                             (if (not= routers router-id->endpoint-url)
-                               (let [candidate-state (assoc current-state :routers router-id->endpoint-url)
-                                     current-routers (-> current-state :routers keys vec sort)
-                                     new-routers (-> router-id->endpoint-url keys vec sort)]
-                                 (log/info "peer router info changed from" current-routers "to" new-routers)
-                                 (metrics/update-counter (metrics/waiter-counter "core" "number-of-routers") routers router-id->endpoint-url)
-                                 (update-router-state router-id current-state candidate-state service-id->service-description-fn))
-                               current-state)]
-                         (async/put! router-state-push-chan new-state)
-                         new-state))))]
-             (if next-state
-               (recur next-state)
-               (log/info "Stopping router-state-maintainer as next state is nil"))))
-         (catch Exception e
-           (log/error e "Fatal error in router-state-maintainer!")
-           (System/exit 1))))}))
+     :router-state-push-mult (async/mult router-state-push-chan)}))

 ;; External state queries


Fixed a few misses in the formvalidation example.

--- clojure/sodium/src/sodium/s_widgets.clj
+++ clojure/sodium/src/sodium/s_widgets.clj
@@ -55,11 +55,13 @@
                   (.unlisten @l)
                   (proxy-super removeNotify)))]
     (reset! l (.listen (Operational/updates c-text)
-                       (handler [t] (if (SwingUtilities/isEventDispatchThread)
+                       (handler [t] (println (str "Operational/updates handler t=" t))
+                                (if (SwingUtilities/isEventDispatchThread)
                                       (.setText label t)
-                                      (SwingUtilities/invokeLater (fn [t] (.setText label ) t))))))
+                                      (SwingUtilities/invokeLater (fn [t] (println "invokeLater")(.setText label ) t))))))
     (Transaction/post (fn [] (SwingUtilities/invokeLater (fn []
-                                                         (.setText label (.sample c-text))))))
+                                                          (println "invokeLaterLater")
+                                                          (.setText label (.sample c-text))))))
     label))

 (defn s-text-field
@@ -318,23 +320,24 @@
      (fn []
        (let [max-emails 4
              gridbag (GridBagLayout.)
-             all-valid (Cell. true)
+             all-valid (atom (Cell. true))
              valids (atom {})
              x (atom {:row0 { :label (JLabel. "Name")
                              :component (s-text-field "" 30)}
                       :row1 { :label (JLabel. "No of email addresses")
                              :component (s-spinner 1)}})]
          (reset! valids (conj @valids {:valid0
-                                     (.map (:cell (:component (:row0 @x))) (apply1 [t]
-                                                                                (cond
-                                                        (= "" (s/trim t))
-                                                        "<-- enter something"
-                                                        (< 0 (.indexOf (s/trim t)))
-                                                        "<-- must contain space"
-                                                        :else "")))
+                                       (.map (:cell (:component (:row0 @x)))
+                                             (apply1 [t]
+                                                     (cond
+                                                      (= "" (s/trim t))
+                                                      "<-- enter something"
+                                                      (< (.indexOf (s/trim t) " ") 0)
+                                                      "<-- must contain space"
+                                                      :else "")))
                                      :valid1   (.map (:cell (:component (:row1 @x))) (apply1 [n]
-                                                                                (if (or (< n max-emails)
-                                                               (> n max-emails))
+                                                                                (if (or (< n 1)
+                                                                                (> n max-emails))
                                                          (str "<-- must be 1 to " max-emails)
                                                          "")))
                                      }))
@@ -350,87 +353,67 @@
                                   :component (s-text-field "" 30 enabled) }}))
              (reset! valids (conj @valids {k-valid
                                            (Cell/lift (apply2 [e n]
-                                                             (cond
-                                                              (>= row n)
-                                                              ""
-                                                              (= "" (s/trim e))
-                                                              "<-- enter something"
-                                                              (< 0 (.indexOf e "@"))
-                                                              "<-- must contain @"
-                                                              :else ""))
+                                                              (println (str "e: " e "n: " n))
+                                                              (cond
+                                                               (>= row n)
+                                                               ""
+                                                               (= "" (s/trim e))
+                                                               "<-- enter something"
+                                                               (< (.indexOf e "@") 0)
+                                                               "<-- must contain @"
+                                                               :else ""))
                                                      (:cell (:component (k-row @x)))
-                                                     (:cell (:component (:row2 @x))))
+                                                     (:cell (:component (:row1 @x))))
                                            } ))))
          (doto view
            (.setLayout gridbag)
-           (grid-bag-layout
+           (comment grid-bag-layout
+            :fill :BOTH
             :gridwidth 1 :gridheight 1
-            :fill :BOTH
             ))
          (dotimes [row (+ max-emails 2)]
            (let [k-row (keyword (str "row" row))
                  k-valid (keyword (str "valid" row))]
+             (println (str row "-> " k-row " -> " k-valid))
              (doto view
                (grid-bag-layout
-                :weightx 0
+                :fill :BOTH
+                :gridwidth 1 :gridheight 1
+                :weightx 0.0
                 :gridx 0 :gridy row
                 (:label (k-row @x))
                 :weightx 1.0
                 :gridx 1
                 (:jcomp (:component (k-row @x)))
-                :weightx 0
+                :weightx 0.0
                 :gridx 2
                 (s-label (k-valid @valids))))
-             (Cell/lift (apply2 [a b]
-                                (and a b))
-                        all-valid
-                        (.map (k-valid @valids) (apply1 [t] (= "" t))))))
+             (reset! all-valid (Cell/lift (apply2 [a b]
+                                                  (and a b))
+                                          @all-valid
+                                          (.map (k-valid @valids) (apply1 [t] (= "" t)))))))
          (doto view
            (grid-bag-layout
             :weightx 1.0
             :gridx 0 :gridy 6
             :gridwidth 3
             :fill :NONE
-            (:jbutton (s-button "OK" all-valid))))
+            (:jbutton (s-button "OK" @all-valid))))
          (pr @valids))))
     (doto view
       (.setSize 600 200)
       (.setVisible true))))

- (form-validation)
-
-
-
-(let [x (atom { :row0 { :foo :bar}})]
-
-  (dotimes [row 4]
-    (let [email (+ row 1)
-          enabled true
-          k-row (keyword (str "row" email))]
-      (reset! x (conj @x {k-row {:label (JLabel. (str "Email #" email))
-                                 :component '() } }))
-      (println (str "::: " (update-in @x [k-row :component] :bar )))))
-    (println @x))
-
-(def n 5)
-
-
-(if (or (< n 1) (> n 4))
-  (println "not ok")
-  (println "ok"))
-
-
-
-

 (defn -main
   [& args]
-  ;(form-validation)
-  (spinme)
-  (add)
-  (spinner)
-  (translate)
-  (redgreen)
-  (gamechat)
-  (frp-reverse)
-  (label))
+  (form-validation)
+  ;(spinme)
+  ;(add)
+  ;(spinner)
+  ;(translate)
+  ;(redgreen)
+  ;(gamechat)
+  ;(frp-reverse)
+                                        ;(label)
+  )


sort tracking keywords

sort tracking keywords

--- src-cljs/frontend/analytics/core.cljs
+++ src-cljs/frontend/analytics/core.cljs
@@ -68,9 +68,9 @@
     :invite-teammates-select-none-clicked
     :login-clicked
     :merge-clicked
+    :merge-failed
     :merge-impression
     :merge-success
-    :merge-failed
     :new-plan-clicked
     :no-plan-banner-impression
     :org-clicked


fixed a bug in the analytics/track defmethod argument declaration

--- src-cljs/frontend/analytics/core.cljs
+++ src-cljs/frontend/analytics/core.cljs
@@ -138,7 +138,7 @@
     (supplement-tracking-properties-from-owner properties owner)
     (supplement-tracking-properties-from-state properties current-state)))

-(s/defmethod track :default [{:keys [event-type :- SupportedEvents properties owner current-state]} :as event-data :- AnalyticsEvent]
+(s/defmethod track :default [{:keys [event-type :- SupportedEvents properties owner current-state] :as event-data :- AnalyticsEvent}]
     (segment/track-event event-type (supplement-tracking-properties {:properties properties
                                                                      :owner owner
                                                                      :current-state current-state})))


fix copy error

fix copy error

--- src-cljs/frontend/components/app.cljs
+++ src-cljs/frontend/components/app.cljs
@@ -149,7 +149,7 @@
                  [:article {:on-click #(.stopPropagation :overlay-info-toggled)}
                   [:h1 "What's this?"]
                   [:p "Precursor is a collaborative idea tool.
-                      Think of it as a notebook with infinite pages – use it to create rapid sketches, prototypes, notes, and everything in between.
+                      Think of it as a notebook with infinite pages – use it to create sketches, rapid prototypes, notes, and everything in between.
                       Collaborate by sharing your URL, and you'll instantly have multiple people working in the same document.
                       It's still a work in progress, so if you have feedback or a great idea for us sketch it up and ping "
                       [:a {:on-click #(cast! :chat-link-clicked)


pass chat submit learn path into chat

pass chat submit learn path into chat

--- src-cljs/frontend/components/app.cljs
+++ src-cljs/frontend/components/app.cljs
@@ -85,6 +85,7 @@

              (om/build chat/chat (select-in app [state/chat-opened-path
                                                  state/chat-mobile-opened-path
+                                                 state/chat-submit-learned-path
                                                  [:document/id]
                                                  [:sente-id]
                                                  [:client-id]


logging improvements

logging improvements

--- src/babel/forest.cljc
+++ src/babel/forest.cljc
@@ -85,9 +85,10 @@

   (if (and (not (= :fail spec))
            (not (empty? (strip-refs spec))))
-    (log/debug (str "lighting-bolt@" depth " spec: " (strip-refs spec))))
+    (log/debug (str "lighting-bolt@" depth " spec: " (strip-refs spec) "; parent: " (if parent
+                                                                                (:rule parent)))))
   (if (not parent)
-    (log/warn (str "no parent for lightning-bolt@" depth " with spec: " (strip-refs spec))))
+    (log/debug (str "no parent for lightning-bolt@" depth " with spec: " (strip-refs spec))))
   (let [maxdepth 3 ;; maximum depth of a lightning bolt: H1 -> H2 -> H3 where H3 must be a lexeme, not a phrase.
         debug (log/debug (str "lightning-bolt@" depth " grammar:" (string/join ", " (map #(get-in % [:rule]) grammar))))

@@ -105,7 +106,7 @@
         debug (if (not (empty? candidate-parents))
                 (log/debug (str "candidate-parents: " (string/join "," (map #(get-in % [:rule])
                                                                             candidate-parents))))
-                (log/warn (str "candidate-parents are empty!")))]
+                (log/debug (str "no candidate-parents for spec: " (strip-refs spec))))]
     ;; TODO: remove or parameterize this hard-coded value.
     (if (> depth 5)
       (throw (exception (str "DEPTH IS GREATER THAN 5; HOW DID YOU END UP IN THIS TERRIBLE SITUATION? LOOK AT THE STACK. I'M OUTTA HERE."))))


Reduce code duplication by using a partial function.

--- src/berry/parsing/context_handler.clj
+++ src/berry/parsing/context_handler.clj
@@ -7,18 +7,14 @@
             :current-column 1
             :offset 0})

-(defn ++
-  [{current-column :current-column
-    offset :offset
-    :as context}]
-  (merge context {
-                  :current-column (inc current-column)
-                  :offset (inc offset)}))
+(defn- apply-to
+  [transform {current-column :current-column
+              offset :offset
+              :as context}]
+  (assoc context
+         :current-column (transform current-column)
+         :offset (transform offset)))

-(defn --
-  [{current-column :current-column
-    offset :offset
-    :as context}]
-  (merge context {
-                  :current-column (dec current-column)
-                  :offset (dec offset)}))
+(def ++ (partial apply-to inc))
+
+(def -- (partial apply-to dec))


Add a `:meta` task option to `render`

Add a `:meta` task option to `render`

--- src/io/perun.clj
+++ src/io/perun.clj
@@ -411,30 +411,33 @@
    If permalink is not set, the original filename is used with file extension set to html."
   [o out-dir  OUTDIR   str  "the output directory (default: \"public\")"
    _ filterer FILTER   code "predicate to use for selecting entries (default: `:content`)"
-   r renderer RENDERER sym  "page renderer (fully qualified symbol which resolves to a function)"]
+   r renderer RENDERER sym  "page renderer (fully qualified symbol which resolves to a function)"
+   m meta     META     edn  "metadata to set on each entry"]
   (let [tmp     (boot/tmp-dir!)
         options (merge +render-defaults+ *opts*)]
     (boot/with-pre-wrap fileset
-      (let [files (filter (:filterer options) (perun/get-meta fileset))]
-        (pod/with-call-in @render-pod
+      (pod/with-call-in @render-pod
           (io.perun.render/update!))
-
-        (doseq [{:keys [path] :as file} files]
-          (let [render-data   {:meta    (perun/get-global-meta fileset)
-                               :entries (vec files)
-                               :entry   file}
-                html          (render-in-pod @render-pod renderer render-data)
-                page-filepath (perun/create-filepath
-                                (:out-dir options)
-                                ; If permalink ends in slash, append index.html as filename
-                                (or (some-> (:permalink file)
-                                            (string/replace #"/$" "/index.html")
-                                            perun/url-to-path)
-                                    (string/replace path #"(?i).[a-z]+$" ".html")))]
-            (perun/report-debug "render" "rendered page for path" path)
-            (perun/create-file tmp page-filepath html)))
+      (let [files (filter (:filterer options) (perun/get-meta fileset))
+            updated-files (doall
+                           (for [{:keys [path] :as file} files]
+                             (let [entry         (merge meta file)
+                                   render-data   {:meta    (perun/get-global-meta fileset)
+                                                  :entries (vec files)
+                                                  :entry   entry}
+                                   html          (render-in-pod @render-pod renderer render-data)
+                                   page-filepath (perun/create-filepath
+                                                  (:out-dir options)
+                                                  ; If permalink ends in slash, append index.html as filename
+                                                  (or (some-> (:permalink file)
+                                                              (string/replace #"/$" "/index.html")
+                                                              perun/url-to-path)
+                                                      (string/replace path #"(?i).[a-z]+$" ".html")))]
+                               (perun/report-debug "render" "rendered page for path" path)
+                               (perun/create-file tmp page-filepath html)
+                               entry)))]
         (perun/report-info "render" "rendered %s pages" (count files))
-        (commit fileset tmp)))))
+        (perun/merge-meta (commit fileset tmp) updated-files)))))

 (def ^:private +collection-defaults+
   {:out-dir "public"


Skip empty open graph values

Skip empty open graph values

--- src/bløggr/posts.clj
+++ src/bløggr/posts.clj
@@ -41,11 +41,12 @@
                     :locale "en_US"
                     :site_name "eikeland.se"
                     :description description
-                    :image (when img (str "http://blog.eikeland.se" img))
+                    :image (when img (str "https://blog.eikeland.se" img))
                     :url (post-absolute-url post)
                     :video (:video header)}
         graph (for [[k v] graph-data]
-                [:meta {:property (str "og:" (name k)) :content v}])]
+                (when v
+                  [:meta {:property (str "og:" (name k)) :content v}]))]

     (apply html/html graph)))


refactored particlesystem-forces do not use protocols

--- quil.info/particlesystem-forces.cljs
+++ quil.info/particlesystem-forces.cljs
@@ -24,123 +24,150 @@

 (ns nature-of-code.systems.particlesystem-forces.core
   "Particle-System produces Particles that experience Gravity
-	 Based on the Nature of Code by Daniel Shiffman http://natureofcode.com"
+  	 Based on the Nature of Code by Daniel Shiffman http://natureofcode.com"
   (:require [quil.core :as q :include-macros true]
             [quil.middleware :as m]
             [nature-of-code.math.vector :as mv]))

 (def params
-  {:size [600 400]
+  {:size [600 600]
    :background 255
    :frame-rate 30
-   :gravity [0.0 0.1]
+   :gravity [0.0 0.05]
    :lifespan 255
    :lifespan-dec-rate 2
-   :particle-r 16
-   :particle-color 127})
+   :circle-r 16
+   :square-l 16
+   :particle-color 127
+   :particle-outline-thickness 2})

-(defn size-x []
+(defmacro SIZE-X []
   (first (params :size)))

-(defn size-y []
+(defmacro SIZE-Y []
   (second (params :size)))

 ;;
-;; Abstractions
+;; particle
 ;;

-(defprotocol Movable_ ; hmm... calling it Movable results in failure
-  (move [this] "enter next motion state for the mobile object"))
+;; TODO clojure.spec verwenden ?)
+(defn gen-particle
+  [& {:keys [id shape mass location velocity acceleration lifespan]
+      :or {}}]
+  {:id id :shape shape :mass mass :location location :velocity velocity :acceleration acceleration :lifespan lifespan})

-(defprotocol Massiv
-  (apply-force [this force] "apply force to the massive object"))
+(defn apply-force-to-particle [{:keys [mass acceleration] :as particle} force]
+  (let [mf (mv/divide force (float mass))
+        next-acceleration (mv/add acceleration mf)]
+    (assoc particle :acceleration next-acceleration)))

-(defprotocol Expirable
-  (expired? [this] "returns true when lifespan is over"))
+(defn move-particle [{:keys [mass location velocity acceleration lifespan] :as particle}]
+  (let [next-location (mv/add location velocity)
+        next-velocity (mv/add velocity acceleration)
+        next-acceleration (mv/multiply acceleration 0)
+        next-lifespan (- lifespan (params :lifespan-dec-rate))]
+    (assoc particle :location next-location :velocity next-velocity :acceleration next-acceleration :lifespan next-lifespan)))

-(defprotocol Drawable
-  (draw [this] "draw the drawable object to an output-device"))
+(defn next-particle [particle force]
+  (-> particle
+      (apply-force-to-particle force)
+      (move-particle)))
+
+(defn is-expired-particle? [{:keys [lifespan] :as particle}]
+  (< lifespan 0))
+
+(defmulti draw-particle (fn [particle] (:shape particle)))
+
+(defmethod draw-particle :circle [{:keys [location lifespan] :as particle}]
+  (q/stroke 0 lifespan)
+  (q/stroke-weight (params :particle-outline-thickness))
+  (q/fill (params :particle-color) lifespan)
+  (q/ellipse (first location) (second location) (params :circle-r) (params :circle-r))
+  particle)
+
+(defmethod draw-particle :square [{:keys [location lifespan] :as particle}]
+  (q/stroke 0 lifespan)
+  (q/stroke-weight (params :particle-outline-thickness))
+  (q/fill (params :particle-color) lifespan)
+  (q/rect-mode :center)
+  (q/rect (first location) (second location) (params :square-l) (params :square-l))
+  (q/rect-mode :corner) ; TODO? get current rect-mode from graphic object
+  particle)
+
+(defmethod draw-particle :rotating-square [{:keys [location lifespan] :as particle}]
+  (q/stroke 0 lifespan)
+  (q/stroke-weight (params :particle-outline-thickness))
+  (q/fill (params :particle-color) lifespan)
+  (q/push-matrix)
+  (q/translate (first location) (second location))
+  (let [theta (q/map-range (first location) 0 (q/width) 0 (* Math/PI 2))]
+    (q/rotate theta))
+  (q/rect-mode :center)
+  (q/rect 0 0 (params :square-l) (params :square-l))
+  (q/rect-mode :corner) ; TODO? get current rect-mode from graphic object
+  (q/pop-matrix)
+  particle)

 ;;
-;; Particle
+;; particle-system
 ;;

-(defrecord Particle [id mass location velocity acceleration lifespan]
-  Movable_
-  (move [this]
-    (let [next-location (mv/add location velocity)
-          next-velocity (mv/add velocity acceleration)
-          next-acceleration (mv/multiply acceleration 0)
-          next-lifespan (- lifespan (params :lifespan-dec-rate))]
-      (assoc this :location next-location :velocity next-velocity :acceleration next-acceleration :lifespan next-lifespan)))
+;; TODO clojure.spec verwenden ?)
+(defn gen-particle-system
+  [& {:keys [origin gravity particles]
+      :or {}}]
+  {:origin origin :gravity gravity :particles particles})

-  Massiv
-  (apply-force [this force]
-    (let [mf (mv/divide force (float mass))
-          next-acceleration (mv/add acceleration mf)]
-      (assoc this :acceleration next-acceleration)))
+(defn next-particles [{:keys [gravity particles] :as particle-system}]
+  (let [next-particles (into [] (map (fn [particle] (next-particle particle gravity))
+                                     particles))]
+    (assoc particle-system :particles next-particles)))

-  Expirable
-  (expired? [this]
-    (< lifespan 0))
+(defn random-shape []
+  (rand-nth [:circle :square :rotating-square]))

-  Drawable
-  (draw [this]
-    (q/stroke 0 lifespan)
-    (q/stroke-weight 2)
-    (q/fill (params :particle-color) lifespan)
-    (q/ellipse (first location) (second location) (params :particle-r) (params :particle-r))
-    this))
+(defn add-new-particle [{:keys [origin particles] :as particle-system}]
+  (let [next-particles (conj particles
+                         (gen-particle
+                           :id (str "p" (count particles))
+                           :shape (random-shape)
+                           :mass 1.0
+                           :location origin
+                           :velocity [(q/random -1.0 1.0) (q/random -2.0 0.0)]
+                           :acceleration [0 0]
+                           :lifespan (params :lifespan)))]
+    (assoc particle-system :particles next-particles)))

-(defn gen-particle
-  [& {:keys [id mass location velocity acceleration lifespan]
-      :or {id "px" mass 0 location [0 0] velocity [0 0] acceleration [0 0] lifespan 0}}]
-  (Particle. id mass location velocity acceleration lifespan))
+(defn remove-expired-particles [{:keys [particles] :as particle-system}]
+  (let [next-particles (remove is-expired-particle? particles)]
+    (assoc particle-system :particles next-particles)))

-;;
-;; ParticleSystem
-;;
+(defn next-particle-system [particle-system]
+  (-> particle-system
+      (next-particles)
+      (add-new-particle)
+      (remove-expired-particles)))

-(defn move-particles [particles]
-  (map move particles))
-
-(defn add-particle [particles origin]
-  (conj
-    particles
-    (gen-particle :id (str "p" (count particles)) :mass 1.0 :location origin :velocity [(q/random -1.0 1.0) (q/random -2.0 0)] :lifespan (params :lifespan))))
-
-(defn remove-expired [particles]
-  (remove expired? particles))
-
-(defrecord ParticleSystem [origin particles]
-  Movable_
-  (move [this]
-    (let [ next-particles
-          (-> particles
-            (move-particles)
-            (add-particle origin)
-            (remove-expired))]
-      (assoc this :particles next-particles)))
-
-  Massiv
-  (apply-force [this force]
-    (let [next-particles (map #(apply-force % force) particles)]
-      (assoc this :particles next-particles)))
-
-  Drawable
-  (draw [this]
-    (dorun (map #(draw %) particles))
-     this))
+(defn draw-particle-system [{:keys [particles] :as particle-system}]
+  (dorun (map (fn [particle] (draw-particle particle)) particles))
+  particle-system)

 ;;
 ;; Sketch
-;;
+;;

-(def particle-system (atom (map->ParticleSystem {:origin [(/ (size-x) 2) (- (size-y) (* (size-y) 0.75))] :particles []})))
+(def particle-system (atom (gen-particle-system
+                             :origin [(/ (SIZE-X) 2) (- (SIZE-Y) (* (SIZE-Y) 0.75))]
+                             :gravity (params :gravity)
+                             :particles [])))

 (defn setup-sketch []
+  ;(js/console.log "setup-sketch")
   (q/frame-rate (params :frame-rate))
-  (q/smooth))
+  (q/smooth)
+  (q/rect-mode :corner))
+

 (defn draw-sketch []
   ; draw Background
@@ -148,16 +175,11 @@
   (q/fill 255)
   (q/rect 0 0 (q/width) (q/height))

-  ; draw Particles
-  (draw @particle-system)
+  ; draw particle-system
+  (draw-particle-system @particle-system)

   ; update ParticleSystem to next-state
-  (let [gravity (params :gravity)]
-    (swap!
-      particle-system
-      #(-> %
-         (apply-force gravity)
-         (move)))))
+  (swap! particle-system next-particle-system))

 ; This sketch uses functional-mode middleware.
 ; Check quil wiki for more info about middlewares and particularly


added path in scatter

added path in scatter

--- src/clj/forma/hadoop/jobs/scatter.clj
+++ src/clj/forma/hadoop/jobs/scatter.clj
@@ -297,6 +297,7 @@
 (comment
   "Run this:"
   (ultrarunner "/user/hadoop/checkpoint"
+               "s3n://formaresults/betabuckettemp"
                "s3n://formaresults/fullbetatemp"
                "s3n://formaresults/staticbuckettemp"
                "s3n://formaresults/finalbuckettemp"


avoid flicker during import

avoid flicker during import

--- src/cljs/clj_money/views/imports.cljs
+++ src/cljs/clj_money/views/imports.cljs
@@ -1,6 +1,7 @@
 (ns clj-money.views.imports
   (:require-macros [cljs.core.async.macros :refer [go]])
   (:require [reagent.core :as r]
+            [reagent.ratom :refer [make-reaction]]
             [secretary.core :as secretary :include-macros true]
             [cljs.core.async :refer [timeout
                                      <!]]
@@ -102,9 +103,7 @@
 (declare load-import)
 (defn- receive-import
   [{{:keys [errors finished]} :progress :as received} page-state]
-  (swap! page-state #(-> %
-                         -busy
-                         (assoc :active received)))
+  (swap! page-state #(assoc % :active received))
   (when (seq errors)
     (trace {:errors errors}))
   (when finished
@@ -116,10 +115,9 @@

 (defn- load-import
   [page-state]
-  (+busy page-state)
   (imports/get (get-in @page-state [:active :id])
                #(receive-import % page-state)
-               (handle-error page-state "Unable to load the import: %s")))
+               (notify/danger-fn "Unable to load the import: %s")))

 (defn- start-import
   [imp page-state]
@@ -174,18 +172,22 @@

 (defn- refresh-button
   [page-state]
-  (let [attr (if @auto-refresh
-               {:class "btn-danger"
-                :title "Click here to stop the auto-refresh."}
-               {:class "btn-success"
-                :title "Click here to auto-refresh the page."})]
-    [bs/busy-button {:html (assoc attr :on-click (fn []
-                                                   (swap! auto-refresh not)
-                                                   (when @auto-refresh
-                                                     (load-import page-state))))
-                     :icon (if @auto-refresh
-                             :stop
-                             :arrow-repeat)}]))
+  (let [busy? (busy page-state)
+        css-class (make-reaction #(if @auto-refresh "btn-danger" "btn-success"))
+        title (make-reaction #(if @auto-refresh
+                                "Click here to stop the auto-refresh."
+                                "Click here to auto-refresh the page."))
+        icon-image (make-reaction #(if @auto-refresh :stop :arrow-repeat))]
+    (fn []
+      ; TODO: either don't use busy-button, or change it to allow class, title, and icon to change
+      [bs/busy-button {:html {:class @css-class
+                              :title @title
+                              :on-click (fn []
+                                          (swap! auto-refresh not)
+                                          (when @auto-refresh
+                                            (load-import page-state)))}
+                       :icon @icon-image
+                       :busy? busy?}])))

 (defn- progress-card
   [page-state]


refactoring in search

refactoring in search

--- src/cljs/iwaswhere_web/ui/search.cljs
+++ src/cljs/iwaswhere_web/ui/search.cljs
@@ -29,6 +29,7 @@
          [:span.mention tag])])))

 (defn editor-state
+  "Create editor-state, either from deserialized state or from search string."
   [q]
   (if-let [editor-state (:editor-state q)]
     (draft/editor-state-from-raw (clj->js editor-state))
@@ -40,41 +41,33 @@
   (let [query-cfg (subscribe [:query-cfg])
         cfg (subscribe [:cfg])
         options (subscribe [:options])
-        state (r/atom {:query-id query-id
-                       :focused  true})
         initial-query (query-id (:queries @query-cfg))
         search-editor-state (editor-state initial-query)]
     (fn [query-id put-fn]
       (let [query (query-id (:queries @query-cfg))
+            show-pvt? (:show-pvt @cfg)
+            hashtags (:hashtags @options)
+            pvt-hashtags (:pvt-hashtags @options)
+            hashtags (if show-pvt? (concat hashtags pvt-hashtags) hashtags)
+            mentions-list (map (fn [m] {:name m}) (:mentions @options))
+            hashtags-list (map (fn [h] {:name h}) hashtags)
+
             search-send (fn [text editor-state]
                           (let [s (merge query
                                          (p/parse-search text)
                                          {:editor-state editor-state})]
                             (put-fn [:search/update s])))

-            show-pvt? (:show-pvt @cfg)
-            hashtags (:hashtags @options)
-            pvt-hashtags (:pvt-hashtags @options)
-            hashtags (if show-pvt? (concat hashtags pvt-hashtags) hashtags)
-            mentions (:mentions @options)
-
             story-select-handler
             (fn [ev]
               (let [v (-> ev .-nativeEvent .-target .-value)
                     story (js/parseInt v)
                     q (merge query {:story (when-not (js/isNaN story) story)})]
-                (put-fn [:search/update q])))
+                (put-fn [:search/update q])))]

-            ;mentions-list (map (fn [m] {:name (subs m 1)}) mentions)
-            ;hashtags-list (map (fn [m] {:name (subs m 1)}) hashtags)
-
-            mentions-list (map (fn [m] {:name m}) mentions)
-            hashtags-list (map (fn [h] {:name h}) hashtags)]
-
-        (when (not= (:query-id @state) query-id)
+        (when (not= initial-query query)
           (let [new-editor-state (editor-state query)]
-            (reset! search-editor-state @new-editor-state))
-          (swap! state assoc-in [:query-id] query-id))
+            (reset! search-editor-state @new-editor-state)))

         [:div.search
          [tags-view query]


routes-chan

routes-chan

--- src/cljs/omnext_routing_one/core.cljs
+++ src/cljs/omnext_routing_one/core.cljs
@@ -1,8 +1,12 @@
 (ns omnext-routing-one.core
+  (:require-macros
+    [cljs.core.async.macros :refer (go-loop)]
+    )
   (:require [goog.dom :as gdom]
             [om.next :as om :refer-macros [defui]]
             [om.dom :as dom]
             [clojure.string :as string]
+            [cljs.core.async :refer (<! put! chan)]
             ))

 (enable-console-print!)
@@ -205,6 +209,9 @@

 ;; Components

+
+(def routes-chan (chan))
+
 (defui RootView
   static om/IQueryParams
   (params [_]
@@ -226,6 +233,19 @@
     )

   Object
+  (componentDidMount [this]
+                     (go-loop [new-query (<! routes-chan)]
+                                             (println "new query"
+                                                      new-query)
+                                (om/set-query!
+                                  this
+                                  new-query
+                                  )
+
+                              (recur (<! routes-chan))
+                       )
+                     )
+
   (render [this]
           (let [unbound-query (om/query this)
                 unbound-params (om/params this)
@@ -332,40 +352,12 @@
     (let [parsed-url (parse-url-hash
           js/window.location.hash
           )
-          x (get-query-and-params-by-parsed-url
+          new-query (get-query-and-params-by-parsed-url
         tabs
         parsed-url
         )
-
-          y (some->>
-    (get-tab-by-parsed-url tabs parsed-url)
-    :component
-    )
-
-          the-query (with-meta
-           (om/get-query y)
-           nil)
-          _ (println "the-query" the-query)
           ]
-      (println "set query to" x)
-      #_(om/set-query!
-        reconciler
-        ;(select-keys x [:query])
-
-        )
-      (om/set-query!
-        reconciler
-        {:query
-         the-query
-         }
-        )
-
-      (println
-        "..."
-        (om/get-query
-          reconciler)
-        (om/query RootView)
-        )
+      (put! routes-chan new-query)
       )
     )
   )


Fix lazy-seq foldable implementation.

Fix lazy-seq foldable implementation.

--- src/cats/builtin.cljc
+++ src/cats/builtin.cljc
@@ -89,20 +89,14 @@

     p/Foldable
     (-foldr [ctx f z xs]
-      (lazy-seq
-       (let [x (first xs)
-             xs (rest xs)]
-         (if (nil? x)
-           z
-           (f x (p/-foldr ctx f z xs))))))
+      (let [x (first xs)]
+        (if (nil? x)
+          z
+          (let [xs (rest xs)]
+            (f x (p/-foldr ctx f z xs))))))

     (-foldl [ctx f z xs]
-      (lazy-seq
-       (let [x (first xs)
-             xs (rest xs)]
-         (if (nil? x)
-           z
-           (p/-foldl ctx f (f z x) xs)))))))
+      (reduce f z xs))))

 (extend-type #?(:clj  clojure.lang.LazySeq
                 :cljs cljs.core.LazySeq)


spelling

spelling

--- src/celestial/api.clj
+++ src/celestial/api.clj
@@ -60,7 +60,7 @@
          (if-not (p/system-exists? id)
            (bad-req {:msg (<< "No system found with given id ~{id}")})
            (success
-             {:msg "submited system creation" :id id
+             {:msg "submitted system creation" :id id
               :job (jobs/enqueue "reload"
               {:identity id :args [(assoc (p/get-system id) :system-id (Integer. id))]})})))

@@ -68,7 +68,7 @@
     {:nickname "destroySystem" :summary "System destruction job"
      :notes "Destroys a system, clearing it both from Celestial's model storage and hypervisor"}
          (success
-           {:msg "submited system destruction" :id id
+           {:msg "submitted system destruction" :id id
             :job (jobs/enqueue "destroy" {:identity id :args [id (p/get-system id)]})}))

   (POST- "/job/provision/:id" [^:int id]


adding PagingPredicate to "select"

adding PagingPredicate to "select"

--- src/chazel/chazel.clj
+++ src/chazel/chazel.clj
@@ -7,7 +7,7 @@
            [java.util.concurrent Callable]
            [com.hazelcast.core Hazelcast IMap EntryEvent ITopic Message MessageListener]
            [com.hazelcast.topic ReliableMessageListener]
-           [com.hazelcast.query SqlPredicate]
+           [com.hazelcast.query SqlPredicate PagingPredicate]
            [com.hazelcast.client HazelcastClient]
            [com.hazelcast.client.impl HazelcastClientProxy]
            [com.hazelcast.client.config ClientConfig]
@@ -245,15 +245,39 @@
   ([^IMap m index ordered?]
    (.addIndex m index ordered?)))

-(defn select [m where & {:keys [as]
-                         :or {as :set}}]
-  (let [pred (SqlPredicate. where)]
-    (case as
-      :set (into #{} (.values m pred))
-      :map (into {} (.entrySet m pred))
-      :native (.entrySet m pred)
-      (error (str "can't return a result of a distributed query as \"" as "\" (an unknown format you provided). "
-                  "query: \"" where "\", running on: \"" (.getName m) "\"")))))
+
+
+(defn- run-query [m pred where as]
+  (case as
+    :set (into #{} (.values m pred))
+    :map (into {} (.entrySet m pred))
+    :native (.entrySet m pred)
+    (error (str "can't return a result of a distributed query as \"" as "\" (an unknown format you provided). "
+                "query: \"" where "\", running on: \"" (.getName m) "\""))))
+
+(defprotocol Pageable
+  (next-page [_]))
+
+(deftype Pages [m pred where as]
+  Pageable
+  (next-page [_]
+             (.nextPage pred)
+             (run-query m pred where as)))
+
+;; TODO: QUERY_RESULT_SIZE_LIMIT
+(defn select [m where & {:keys [as comp-fn page-size]
+                         :or {as :set
+                              comp-fn (fn [e1 e2]
+                                        (compare (.getKey e1)
+                                                 (.getKey e2)))}}]
+  (let [sql-pred (SqlPredicate. where)
+        pred (if-not page-size
+               sql-pred
+               (PagingPredicate. sql-pred comp-fn page-size))
+        rset (run-query m pred where as)]
+    (if-not page-size
+      rset
+      {:pages (Pages. m pred where as) :results rset})))

 (defn add-entry-listener [m ml]
   (.addEntryListener m ml true))


CLJS-1035: REPLs should support watch recompilation

Add :watch "path/to/src/to/watch" support to all REPLs, create a watch.log file
at the root of :output-dir which users can tail.

--- src/clj/cljs/repl.clj
+++ src/clj/cljs/repl.clj
@@ -22,7 +22,7 @@
             [cljs.tagged-literals :as tags]
             [cljs.closure :as cljsc]
             [cljs.source-map :as sm])
-  (:import [java.io File PushbackReader]
+  (:import [java.io File PushbackReader FileWriter]
            [java.net URL]
            [javax.xml.bind DatatypeConverter]))

@@ -562,6 +562,12 @@
                 (:require [cljs.repl :refer-macros [doc]]))
              {:line 1 :column 1})
            identity opts)
+         (when-let [src (:watch opts)]
+           (future
+             (let [log-file (io/file (util/output-directory opts) "watch.log")]
+               (println "Watch compilation log available at:" (str log-file))
+               (binding [*out* (FileWriter. log-file)]
+                 (cljsc/watch src (dissoc opts :watch))))))
          (loop []
            ;; try to let things flush before printing prompt
            (Thread/sleep 10)


Use Langohr 3.0.0

Use Langohr 3.0.0

--- clojure/project.clj
+++ clojure/project.clj
@@ -4,4 +4,4 @@
   :license {:name "Eclipse Public License"
             :url "http://www.eclipse.org/legal/epl-v10.html"}
   :dependencies [[org.clojure/clojure     "1.6.0"]
-                 [com.novemberain/langohr "3.0.0-rc2"]])
+                 [com.novemberain/langohr "3.0.0"]])


Remove http:// on load

Remove http:// on load

--- src/nube/app.clj
+++ src/nube/app.clj
@@ -49,7 +49,7 @@
 (defn remove-app-env [app env] (redis! (car/hdel (str app ":envs") env)))
 (defn load-app-envs [app] (apply hash-map (redis! (car/hgetall (str app ":envs")))))

-(defn load-app-instances [app] (redis! (car/lrange (str "frontend:" app) 0 -1)))
+(defn load-app-instances [app] (mapv #(subs % 7) (redis! (car/lrange (str "frontend:" app) 0 -1))))
 (defn add-app-instance [app instance] (redis! (car/rpush (str "frontend:" app) (str "http://" instance))))
 (defn remove-app-instance [app instance] (redis! (car/lrem (str "frontend:" app) 0 (str "http://" instance))))

@@ -137,7 +137,6 @@
         (add-pending-app-instance app (str host ":" port))
         :ok
         (catch Exception e
-          (.printStackTrace e)
           (println "Deploy failed. Rolling back.")
           (try (kill-app-instance app host port)
                (Exception. "Deployment failed. Rolling back.")


`cljs.test/test-all-vars` shouldn't return anything

--- src/clj/cljs/test.clj
+++ src/clj/cljs/test.clj
@@ -265,9 +265,7 @@
                (fn [[_ v]] (:test v))
                (ana-api/ns-interns ns)))])
       (when (nil? env#)
-        (let [ret# (cljs.test/get-current-env)]
-          (cljs.test/clear-env!)
-          ret#)))))
+        (cljs.test/clear-env!)))))

 (defmacro test-ns
   "If the namespace defines a function named test-ns-hook, calls that.


Things should not be private, people should be able to shoot themselves in the foot if they want

--- src/clj_http/core.clj
+++ src/clj_http/core.clj
@@ -27,38 +27,38 @@
            (org.apache.http.impl.client DefaultHttpClient)
            (org.apache.http.util EntityUtils)))

-(defn- parse-headers [#^HttpResponse http-resp]
+(defn parse-headers [#^HttpResponse http-resp]
   (into {} (map (fn [#^Header h] [(.toLowerCase (.getName h)) (.getValue h)])
                 (iterator-seq (.headerIterator http-resp)))))

-(defn- set-client-param [#^HttpClient client key val]
+(defn set-client-param [#^HttpClient client key val]
   (when (not (nil? val))
     (-> client
         (.getParams)
         (.setParameter key val))))

-(defn- proxy-delete-with-body [url]
+(defn proxy-delete-with-body [url]
   (let [res (proxy [HttpEntityEnclosingRequestBase] []
               (getMethod [] "DELETE"))]
     (.setURI res (URI. url))
     res))

-(def ^{:private true} insecure-socket-factory
+(def insecure-socket-factory
   (doto (SSLSocketFactory. (reify TrustStrategy
                              (isTrusted [_ _ _] true)))
     (.setHostnameVerifier SSLSocketFactory/ALLOW_ALL_HOSTNAME_VERIFIER)))

-(def ^{:private true} insecure-scheme-registry
+(def insecure-scheme-registry
   (doto (SchemeRegistry.)
     (.register (Scheme. "http" 80 (PlainSocketFactory/getSocketFactory)))
     (.register (Scheme. "https" 443 insecure-socket-factory))))

-(def ^{:private true} regular-scheme-registry
+(def regular-scheme-registry
   (doto (SchemeRegistry.)
     (.register (Scheme. "http" 80 (PlainSocketFactory/getSocketFactory)))
     (.register (Scheme. "https" 443 (SSLSocketFactory/getSocketFactory)))))

-(defn- make-regular-conn-manager [& [insecure?]]
+(defn make-regular-conn-manager [& [insecure?]]
   (if insecure?
     (SingleClientConnManager. insecure-scheme-registry)
     (SingleClientConnManager.)))
@@ -73,7 +73,7 @@

 (def ^{:dynamic true} *connection-manager* nil)

-(defn- create-multipart-entity
+(defn create-multipart-entity
   "Takes a multipart map and creates a MultipartEntity with each key/val pair
    added as a part, determining part type by the val type."
   [multipart]


Allow alert-type to be specified

Allow alert-type to be specified

--- src/cljs/ji/main.cljs
+++ src/cljs/ji/main.cljs
@@ -54,10 +54,13 @@
     [:div#board]]])

 (defn show-alert!
-  [msg]
-  (dom/append!
-    (sel1 :#messages)
-    (node [:div.alert-box {:data-alert true} msg])))
+  ([msg] (show-alert! msg nil))
+  ([msg alert-type]
+   (dom/append!
+     (sel1 :#messages)
+     (node [:div {:class (str "alert-box " (when alert-type (name alert-type)))
+                  :data-alert true}
+            msg]))))

 (defn card-selector
   "todo: general partition/chunking buffer"
@@ -93,7 +96,6 @@
       (dom/append! el (card-ui/set-tmpl s)))))

 (defn go-game-summary [container {:keys [game] :as finish-msg}]
-  (println finish-msg)
   (go (let [modal (node [:div.reveal-modal.open
                          {:style "display:block; visibility:visible;"}
                          [:h2 "Game Complete"]
@@ -210,7 +212,7 @@
           (clear! (sel1 :#messages))
           (let [result (<! result-chan)]
             (if (msg/error? result)
-              (show-alert! (:message result)))))))
+              (show-alert! (:message result) :alert))))))

   (let [dict "abcdefghijklmnopqrstuvwxyz"
         dict "lj"


namespace changes from rewrite-clj -> rewrite-cljs

--- src/cljsfmt/core.cljs
+++ src/cljsfmt/core.cljs
@@ -3,6 +3,7 @@
             [rewrite-clj.parser :as p]
             [rewrite-clj.node :as n]
             [rewrite-clj.zip :as z]
+            [rewrite-clj.zip.base :as zb]
             [cljsfmt.indents.clojurescript :as ci]
             [cljsfmt.indents.fuzzy :as fi]))

@@ -13,7 +14,7 @@
       zloc)))

 (defn- transform [form zf & args]
-  (z/root (apply zf (z/edn form) args)))
+  (z/root (apply zf (zb/edn form) args)))

 (defn- surrounding? [zloc p?]
   (and (p? zloc) (or (nil? (zip/left zloc))


reindent

reindent

--- src-cljs/flatride/frontend.cljs
+++ src-cljs/flatride/frontend.cljs
@@ -9,8 +9,8 @@

 (defn map-config-obj []
   (js-obj "zoom" 12
-                "mapTypeId" gmaps.MapTypeId.ROADMAP
-                "center" (gmaps.LatLng. 45 45)))
+          "mapTypeId" gmaps.MapTypeId.ROADMAP
+          "center" (gmaps.LatLng. 45 45)))

 (defn init []
   (set! gmaps window/google.maps)


Rename organization path for consistency

--- src-cljs/frontend/api/path.cljs
+++ src-cljs/frontend/api/path.cljs
@@ -1,14 +1,14 @@
 (ns frontend.api.path
   (:require [goog.string :as gstring]))

-(defn base-project-url-path [vcs-type]
+(defn- base-project-url-path [vcs-type]
   (case vcs-type
     "bitbucket" (gstring/format
                   "/api/dangerzone/project/%s"
                   vcs-type)
     "github" "/api/v1/project"))

-(defn organization [vcs-type org-name]
+(defn- base-organization-url-path [vcs-type org-name]
   (gstring/format "/api/v1.1/%s/%s"
                   (or vcs-type "github")))

@@ -80,7 +80,7 @@

 (defn organization-invite [vcs-type org-name]
   (gstring/format "%s/invite"
-                  (organization vcs-type org-name)))
+                  (base-organization-url-path vcs-type org-name)))

 (defn build-retry [vcs-type org-name repo-name build-num]
   (gstring/format


refactor: prettify disqus inclusion

refactor: prettify disqus inclusion

--- src/blogiseq/core.clj
+++ src/blogiseq/core.clj
@@ -42,26 +42,26 @@
    (hiccup-page/include-js "//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.4.0/highlight.min.js")
    (hiccup-element/javascript-tag "hljs.initHighlightingOnLoad();")])

+(defn disqus-js [page-id]
+  (str "var disqus_config = function () {
+       // todo try if ommiting this will be annoying:
+       // this.page.url = 'http://www.franky-canonical-fqdn.com/';
+       this.page.identifier = '"page-id"';
+       };
+       (function() {  // DON'T EDIT BELOW THIS LINE
+       var d = document, s = d.createElement('script');
+
+       s.src = '//frankysblogiseq.disqus.com/embed.js';
+
+       s.setAttribute('data-timestamp', +new Date());
+       (d.head || d.body).appendChild(s);
+       })();"))
+
 (defn embed-disqus [page-id]
   [:div
-   (str
-     "

-
-     Please enable JavaScript to view the comments powered by Disqus.
-     ")])
+   [:div.disqus_thread]
+   (hiccup-element/javascript-tag (disqus-js page-id))
+   [:noscript "Please enable JavaScript to view the comments powered by Disqus."]])

 ;;;;;;;;;;;;;
 (defn site


get rid of fa

get rid of fa

--- src/blogiseq/site.clj
+++ src/blogiseq/site.clj
@@ -65,9 +65,7 @@
             :class "w3-right w3-xlarge w3-padding-large w3-hover-black w3-hide-large"
             :onclick "w3_close()"
             :href "javascript:void(0)"}
-        "close menu"
-        [:i {:class "fa fa-remove"}]
-        ]
+        "Close menu"]
        [:div (generate-menu-navi "resources/meta.edn")]]
       [:div {:id "myOverlay",
              :title "close side menu",
@@ -78,7 +76,7 @@
                                                   [:header {:class "w3-container"}
                                                    [:span {:onclick "w3_open()"
                                                            :class "w3-opennav w3-hide-large w3-xxlarge w3-hover-text-grey"}
-                                                    [:i {:class  "fa fa-bars"}]]]
+                                                    "MENU"]]
                                                   content]]
       ]]]])


Disable loading of import providers in prod

--- frontend/src/warehouse/prod.cljs
+++ frontend/src/warehouse/prod.cljs
@@ -1,6 +1,13 @@
 (ns warehouse.prod
   (:require
-   [warehouse.core]))
+   [warehouse.core]
+   [warehouse.component-import.events]
+   [re-frame.core :refer [reg-event-db]]))
+
+; disable loading of import providers
+(reg-event-db
+ :load-providers
+ identity)

 (warehouse.core/main)


Normalize the narrator

Normalize the narrator

i.e. we want 'John Boyer' instead of 'Boyer, John'

--- src/catalog/vubis.clj
+++ src/catalog/vubis.clj
@@ -4,6 +4,7 @@
              [coerce :as time.coerce]
              [format :as time.format]]
             [clojure
+             [string :as string]
              [xml :as xml]
              [zip :as zip]]
             [clojure.data.zip.xml :refer [attr= text xml-> xml1->]]
@@ -166,12 +167,19 @@
     (time.coerce/to-date
      (time.format/parse (time.format/formatters :year) year))))

+(defn normalize-name
+  "Change a name from 'name, surname' to 'surname name'"
+  [name]
+  (when name
+    (string/join " " (reverse (string/split name #",")))))
+
 (defn clean-raw-item
   "Return a proper production based on a raw item, i.e.
   translate the language tag into proper ISO 639-1 codes"
   [{:keys [genre-raw genre-code language format-raw producer-raw
            produced_commercially? source-date general-note
-           series-title-raw series-volume-raw braille-grade-raw] :as item
+           series-title-raw series-volume-raw
+           braille-grade-raw narrator] :as item
     :or {genre-raw "x01"}}]
   (-> item
       (assoc-some
@@ -187,6 +195,7 @@
                               (Integer/parseInt series-volume-raw))
        :braille-grade (braille-grade-raw-to-braille-grade braille-grade-raw)
        :source-date (get-year source-date)
+       :narrator (normalize-name narrator)
        :movie_country (when general-note (second (re-find #"^Originalversion: (.*)$" general-note))))
       (dissoc :genre-raw :genre-code :format-raw :producer-raw
               :series-title-raw :series-volume-raw)))


Remove redundant file

Remove redundant file

--- modules/bidi/src/modular/bidi/menu.clj
+++ modules/bidi/src/modular/bidi/menu.clj
@@ -1,8 +0,0 @@
-;; Copyright © 2014 JUXT LTD.
-
-(ns modular.bidi.menu
-  (:require
-   [com.stuartsierra.component :as component]
-   [modular.template :refer (TemplateModel)]
-   [bidi.bidi :refer (path-for)]
-   [hiccup.core :refer (html)]))


Added delete! and remove! functions

Added delete! and remove! functions

--- src/chazel/chazel.clj
+++ src/chazel/chazel.clj
@@ -116,6 +116,12 @@
 (defn put-all! [^IMap dest ^Map src]
   (.putAll dest src))

+(defn remove! [^IMap m k]
+  (.remove m k))
+
+(defn delete! [^IMap m k]
+  (.delete m k))
+
 (defn add-index
   ([^IMap m index]
    (add-index m index false))


Fix relu docs

Fix relu docs

--- src/cortex/layers.clj
+++ src/cortex/layers.clj
@@ -43,7 +43,7 @@
 (defn relu
   "Creates a rectified linear (ReLU) module of the given shape.

-   An optional lower bound may be provided, which otherwise defaults to 0.0"
+   An optional factor may be provided to scale negative values, which otherwise defaults to 0.0"
   ([shape & {:keys [negval]
             :or {negval 0.0 }}]
     (when-not (coll? shape)


exception fix

exception fix

--- src/crawler/crawl.clj
+++ src/crawler/crawl.clj
@@ -616,9 +616,11 @@
                                                                  (catch Exception e nil))

                                                          :xpath-texts (if (:body x)
-                                                                        (similarity/char-frequency-representation
-                                                                         (similarity/page-text-xpaths
-                                                                          (:body x)))
+                                                                        (try
+                                                                         (similarity/char-frequency-representation
+                                                                          (similarity/page-text-xpaths
+                                                                           (:body x)))
+                                                                         (catch Exception e {}))
                                                                         {})}))
                                              sampled-corpus)
                                   :new-visited links-list


Add ability to create tabs.

Add ability to create tabs.

--- nightweb-desktop/src/nightweb/core.clj
+++ nightweb-desktop/src/nightweb/core.clj
@@ -1,45 +1,8 @@
 (ns nightweb.core
-  (:use splendid.jfx
-        nightweb.page)
-  (:import javafx.scene.layout.VBox
-           javafx.scene.layout.HBox
-           javafx.scene.control.TabPane
-           javafx.scene.control.Tab
-           javafx.scene.web.WebView
-           javafx.scene.layout.Priority
-           javafx.scene.control.Button
-           javafx.scene.control.TextField
-           javafx.geometry.Insets
-           net.i2p.router.Router)
+  (:use nightweb.page
+        nightweb.browser)
+  (:import net.i2p.router.Router)
   (:gen-class))
-
-(defn start-browser
-  "Launch the JavaFX browser (non-blocking)."
-  []
-  (jfx (let [window (VBox.)
-             tab-view (VBox.)
-             nav-bar (HBox.)
-             back-btn (Button. "<-")
-             for-btn (Button. "->")
-             reload-btn (Button. "Reload")
-             url-field (TextField.)
-             tab-bar (TabPane.)
-             main-tab (Tab. "Main Page")
-             add-tab (Tab. "+")
-             web-view (WebView.)]
-         (.setPadding nav-bar (Insets. 4))
-         (.setSpacing nav-bar 2)
-         (add nav-bar [back-btn for-btn reload-btn url-field])
-         (HBox/setHgrow url-field Priority/ALWAYS)
-         (add tab-view [nav-bar web-view])
-         (.setClosable add-tab false)
-         (.setContent main-tab tab-view)
-         (.add (.getTabs tab-bar) main-tab)
-         (.add (.getTabs tab-bar) add-tab)
-         (.load (.getEngine web-view) "http://localhost:8080")
-         (VBox/setVgrow tab-bar Priority/ALWAYS)
-         (add window [tab-bar])
-         (show window))))

 (defn start-router
   "Launch the router (blocking)."


Fix apply-key so it's private

Fix apply-key so it's private

--- src/deepfns/core.cljc
+++ src/deepfns/core.cljc
@@ -23,7 +23,7 @@
     (when-not (every? nil? matches)
       (vals (remove nil? matches)))))

-(defn apply-key [handler]
+(defn- apply-key [handler]
   (fn [f ms k]
     [k (apply (partial handler f)
          (group-vals ms k))]))


remove debugging prints; small refactor

remove debugging prints; small refactor

--- src/braid/ui/views/sidebar.cljs
+++ src/braid/ui/views/sidebar.cljs
@@ -40,15 +40,16 @@
     (if (= old-i new-i)
       v
       (let [em (nth v old-i)]
-        (reduce (fn [v' [idx e]]
-                  (cond
-                    (= idx old-i) v'
-                    (= idx new-i) (if (< old-i new-i)
-                                    (conj v' e em)
-                                    (conj v' em e))
-                    :else (conj v' e)))
-                []
-                (map-indexed vector v))))))
+        (->> v
+             (map-indexed vector)
+             (reduce (fn [v' [idx e]]
+                       (cond
+                         (= idx old-i) v'
+                         (= idx new-i) (if (< old-i new-i)
+                                         (conj v' e em)
+                                         (conj v' em e))
+                         :else (conj v' e)))
+                     []))))))

 (defn badge-view [group-id]
   (let [cnt (subscribe [:group-unread-count group-id])]
@@ -74,8 +75,6 @@
                               old-idx (index-of current-groups (group :id))
                               new-idx (+ old-idx by)
                               new-groups (move-idx current-groups old-idx new-idx)]
-                          (println current-groups)
-                          (println new-groups)
                           (dispatch! :set-preference [:groups-order new-groups])))
         drag-state (r/atom {:grp nil
                             :elt-height 0


add clarity to log message when using Cortez Chip

--- src/clj/game/cards-hardware.clj
+++ src/clj/game/cards-hardware.clj
@@ -140,13 +140,12 @@
    "Cortez Chip"
    {:abilities [{:prompt "Choose a piece of ICE"
                  :choices {:req #(and (not (rezzed? %)) (ice? %))}
-                 :effect (req (let [ice target
-                                    serv (zone->name (second (:zone ice)))]
+                 :effect (req (let [ice target]
                                 (update! state side (assoc card :cortez-target ice))
                                 (trash state side (get-card state card) {:cause :ability-cost})
                                 (system-msg state side
-                                  (str "increases the cost to rez the ICE at position "
-                                    (ice-index state ice) " of " serv " by 2 [Credits] until the end of the turn"))))}]
+                                  (str "trashes Cortez Chip to increase the rez cost of " (card-str state ice)
+                                       " by 2 [Credits] until the end of the turn"))))}]
     :trash-effect {:effect (effect (register-events {:pre-rez {:req (req (= (:cid target) (:cid (:cortez-target card))))
                                                                :effect (effect (rez-cost-bonus 2))}
                                                      :runner-turn-ends {:effect (effect (unregister-events card))}


Add docstring

Add docstring

--- src/clj/lambdacd/state/core.clj
+++ src/clj/lambdacd/state/core.clj
@@ -10,8 +10,7 @@
        (sort)))

 (defn- get-step-results-from-legacy [component build-number]
-  (-> (legacy-pipeline-state/get-all component)
-      (get build-number)))
+  (get (legacy-pipeline-state/get-all component) build-number))

 ; -------------------------------------------------------------------------

@@ -28,7 +27,9 @@
       (protocols/consume-step-result-update component build-number step-id step-result)
       (legacy-pipeline-state/update component build-number step-id step-result))))

-(defn consume-pipeline-structure [ctx build-number pipeline-structure-representation]
+(defn consume-pipeline-structure
+  "Update the pipeline structure in the state"
+  [ctx build-number pipeline-structure-representation]
   (let [component (state-component ctx)]
     (if (satisfies? protocols/PipelineStructureConsumer component)
       (protocols/consume-pipeline-structure component build-number pipeline-structure-representation))))


Pretty print

Pretty print

--- src/cljs/learn_specter/app.cljs
+++ src/cljs/learn_specter/app.cljs
@@ -1,7 +1,8 @@
 (ns learn-specter.app
   (:require-macros [learn-specter.macros :refer [defedn]]
                    [reagent.ratom :refer [reaction]])
-  (:require [reagent.core :as reagent]
+  (:require [cljs.pprint :refer [pprint]]
+            [reagent.core :as reagent]
             [re-frame.core :refer [register-handler register-sub subscribe dispatch dispatch-sync]]
             [com.rpl.specter :as s]))

@@ -24,7 +25,7 @@
     (fn dataset-renderer
       []
       [:div
-       "First movie: " (:name @first-movie)])))
+       "First movie: " (with-out-str (pprint @first-movie))])))

 (defn init []
   (dispatch-sync [:initialize])


username and message are subscribed / dispatched

--- src/cljs/minimal_chat/core.cljs
+++ src/cljs/minimal_chat/core.cljs
@@ -6,33 +6,32 @@
             [reagent.core :as reagent]
             [reagent.session :as session]
             [secretary.core :as secretary :include-macros true]
+            [re-frame.core :as rf :refer [dispatch
+                                          dispatch-sync
+                                          register-handler
+                                          register-sub
+                                          subscribe]]
             [matchbox.async :as ma]
             [matchbox.core :as m])
-  (:require-macros [cljs.core.async.macros :refer [go go-loop]])
+  (:require-macros [reagent.ratom :refer [reaction]]
+                   [cljs.core.async.macros :refer [go go-loop]])
   (:import goog.History))
-
-;; -----------------------------
-;; Global Data

 ;; -- REPLACE with your own DB location ---------
 (def firebase-io-root "https://shining-torch-2145.firebaseIO.com")
 ;; ----------------------------------------------

-(defonce show-state? (reagent/atom true))
-(defonce username (reagent/atom "username"))
+(def initial-state
+  {:chat-room nil
+   :messages []
+   :username (str "Guest" (rand-int 100))})
+
 (defonce chat-room (reagent/atom nil))

 (defonce fb-messages (atom nil))
 (defonce messages (reagent/atom []))

-(defn random-four-characters []
-  (->> (repeatedly #(rand-nth ["a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s" "t" "u" "v" "w" "x" "y" "z"]))
-       (take 4)
-       (str/join)
-       (str/upper-case)))
-
-;; -----------------------------
-;; Firebase helpers
+;; -- Firebase helpers ------

 (defn bind-to-ratom [ratom ref & [korks]]
   (let [ch (ma/listen-to< ref korks :value)]
@@ -43,8 +42,13 @@
 (defn firebase-swap! [fb-ref f & args]
   (apply m/swap! fb-ref f args))

-;; ------------------
-;; logic
+;; -- Helpers ---------------
+
+(defn- random-four-characters []
+  (->> (repeatedly #(rand-nth ["a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s" "t" "u" "v" "w" "x" "y" "z"]))
+       (take 4)
+       (str/join)
+       (str/upper-case)))

 (defn join-room [id]
   (reset! chat-room id)
@@ -53,33 +57,56 @@
       (reset! fb-messages fb-item)
       (bind-to-ratom messages fb-item))))

-;; -------------------------
-;; Views
+;; -- Subscriptions ---------

-(defn ^:export toggle-showing-state! []
-  (swap! show-state? not))
+(register-sub
+  :username-input
+  (fn [db _]
+    (reaction (:username @db))))

-(defn text-input [value]
-  [:input {:type "text"
-           :value @value
-           :on-change #(reset! value (-> % .-target .-value))}])
+;; -- Event Handlers --------
+
+(register-handler
+  :initialize
+  (fn [db _]
+    (merge db initial-state)))
+
+(register-handler
+  :set-username-input
+  (fn [db [_ value]]
+    (assoc db :username value)))
+
+;; -- View Components -------
+
+(defn username-input []
+  (let [username (subscribe [:username-input])]
+    [:input {:type "text"
+             :value @username
+             :on-change #(dispatch [:set-username-input (-> % .-target .-value)])}]))
+
+(defn message-form []
+  (let [message  (reagent/atom "")
+        username (subscribe [:username-input])]
+    [:form {:on-submit (fn [e]
+                         (.preventDefault e)
+                         (firebase-swap! @fb-messages conj [@username @message]))}
+     [:input {:type "text"
+              :on-change #(reset! message (-> % .-target .-value))}]
+     [:button {:type "submit"} "Send"]]))
+
+;; -- Views -----------------

 (defn on-going-chat []
   [:div
-   [:label "Your username:"]
-   [text-input username]
+   [:label "Your username: "]
+   [username-input]

    [:div#messages
     (for [[message index] (map vector (take-last 30 @messages) (range))]
       ^{:key (str "message-" index)}
       [:div [:span.username (first message) ": "] [:span.message (second message)]])]

-   (let [users-message (reagent/atom "")]
-     [:form {:on-submit (fn [e]
-                          (.preventDefault e)
-                          (firebase-swap! @fb-messages conj [@username @users-message]))}
-      [text-input users-message]
-      [:button {:type "submit"} "Send"]])])
+   [message-form]])

 (defn join-room-view []
   (let [this-room (atom (random-four-characters))
@@ -108,17 +135,15 @@
       [on-going-chat]
       [join-room-view])

-    (when @show-state?
-      [:div [:br] [:br] [:br] "STATE!!!!"
-       [:div "Messages: " (pr-str @messages)]])]])
+    [:div [:br] [:br] [:br]
+     "STATE!!!!"
+     [:div "Messages: " (pr-str @messages)]]]])

 (defn current-page []
   [:div [(session/get :current-page)]])

 ;; -------------------------
 ;; Routes
-
-(secretary/set-config! :prefix "#")

 (secretary/defroute "/" []
   (reset! chat-room nil)
@@ -132,6 +157,7 @@
 ;; -------------------------
 ;; History
 ;; must be called after routes have been defined
+
 (defn hook-browser-navigation! []
   (doto (History.)
     (events/listen
@@ -142,7 +168,11 @@

 ;; -------------------------
 ;; Initialize app
+
 (defn init! []
   (hook-browser-navigation!)
+  (secretary/set-config! :prefix "#")
+  (dispatch-sync [:initialize])

+  ;; mount root
   (reagent/render-component [current-page] (.getElementById js/document "app")))


removed debug code

removed debug code

--- src/evalback/core.clj
+++ src/evalback/core.clj
@@ -143,14 +143,9 @@
         files (file-seq b)]
     (into {} (for [f files :when (.isFile f)] [(.getName f) (slurp f)]))))

-(defn debug-path []
-  (let [b (io/file "./webapps/evalB/WEB-INF/classes/")
-        files (file-seq b)
-        files (map (fn [f] (.getAbsolutePath f)) files)]
-        (clojure.string/join "\n" files)))

 (defn provide-examples []
-  (str "/*\n" (debug-path) "*/\n" "\nexample_list = "
+  (str "\nexample_list = "
     (json/write-str {"b" (mk-example-map "./webapps/evalB/WEB-INF/classes/public/examples/b")
                      "tla" (mk-example-map "./webapps/evalB/WEB-INF/classes/public/examples/tla") })))


Remove make-random-bytes function from keys ns (replaced with function son nonce ns).

--- src/clojure/buddy/core/keys.clj
+++ src/clojure/buddy/core/keys.clj
@@ -74,13 +74,3 @@
   [^String keydata]
   (with-open [reader (StringReader. keydata)]
     (read-pem->pubkey reader)))
-
-(defn make-random-bytes
-  "Generate a byte array of scpecified length with random
-  bytes taken from secure random number generator."
-  ([^Long numbytes]
-   (make-random-bytes numbytes (SecureRandom.)))
-  ([^Long numbytes ^SecureRandom sr]
-   (let [buffer (byte-array numbytes)]
-     (.nextBytes sr buffer)
-     buffer)))


Implement token caching for every role, for #11

--- src/googlica/auth.clj
+++ src/googlica/auth.clj
@@ -33,7 +33,19 @@
   "URL for requesting new OAuth2 tokens"
   "https://www.googleapis.com/oauth2/v4/token")

-;; TODO: Cache role:token so we don't have to get a new token for every request
+(def C
+  "Cache for role:token so we don't have to get a new token for every request"
+  (atom (cache/ttl-cache-factory {} :ttl 3500000))) ;; 3500 seconds
+
+(defmacro with-cache
+  "Given a key and an expression, will set the key in the cache to the result
+  of evaluating it if that key is expired."
+  [key body-expr]
+  `(let [new-cache# (if (cache/has? @C ~key)
+                      (cache/hit @C ~key)
+                      (cache/miss @C ~key ((fn [] ~body-expr))))]
+     (reset! C new-cache#)
+     (get new-cache# ~key)))

 (defn sign-jwt
   "Given a scope string, generates a new signed JWT claim"
@@ -46,22 +58,26 @@
                :iat (time/now)}]
     (jwt/sign claim privkey {:alg :rs256})))

-(defn get-new-oauth2-token [signed-jwt-claim]
-  (-> (http/request {:method :post
-                     :url access-request-url
-                     :form-params {:grant_type "urn:ietf:params:oauth:grant-type:jwt-bearer"
-                                   :assertion signed-jwt-claim}})
-      :body ;; TODO: handle http exceptions in here
-      (parse-string true)
-      :access_token))
+(defn get-oauth2-token
+  "Given a scope string, returns a cached OAuth2 token, or requests a new one
+  if the cached one (for that scope) is expired"
+  [scope]
+  (with-cache scope
+    (-> {:method :post
+         :url access-request-url
+         :form-params {:grant_type "urn:ietf:params:oauth:grant-type:jwt-bearer"
+                       :assertion (sign-jwt scope)}}
+        (http/request)
+        :body ;; TODO: handle http exceptions in here
+        (parse-string true)
+        :access_token)))

 ;;;; Requests utils

-;; TODO: cache roles
 (defn wrap-auth
   "Given a request map, enriches it with a new OAuth2 token."
   [req-map scope]
-  (assoc-in req-map [:headers "Authorization"] (str "Bearer " (-> scope
-                                                                  sign-jwt
-                                                                  get-new-oauth2-token))))
+  (assoc-in req-map
+            [:headers "Authorization"]
+            (str "Bearer " (get-oauth2-token scope))))


with-profiler prints profile even after aborting

Signed-off-by: Daniel Borchmann <25857343a15bf1edafebc2912e82ecf775c585c1@mailbox.tu-dresden.de>

--- src/conexp/contrib/profiler.clj
+++ src/conexp/contrib/profiler.clj
@@ -215,11 +215,14 @@
   [starting-options output-options & body]
   `(let [^Thread thread# (Thread. #(do ~@body))]
      (start-profiling :thread thread# ~@starting-options)
-     (time (do
-             (.start thread#)
-             (.join thread#)))
-     (show-profiling :thread thread# ~@output-options)
-     (stop-profiling :thread thread#)))
+     (try (time (do
+                  (.start thread#)
+                  (.join thread#)))
+          (catch Exception ex#
+            (.stop thread#))
+          (finally
+           (show-profiling :thread thread# ~@output-options)
+           (stop-profiling :thread thread#)))))

 ;;;


Trivial parallelization of «proper-premises»

Signed-off-by: Daniel Borchmann <25857343a15bf1edafebc2912e82ecf775c585c1@mailbox.tu-dresden.de>

--- src/conexp/fca/implications.clj
+++ src/conexp/fca/implications.clj
@@ -264,7 +264,9 @@
                                   (update-in arrow-map [m] conj g))
                            arrow-map))]
     (distinct
-     (mapcat #(proper-premises-for-attribute ctx %) down-arrow-map))))
+     (reduce concat
+             (pmap #(proper-premises-for-attribute ctx %)
+                   down-arrow-map)))))

 (defn proper-premise-implications
   "Returns all implications based on the proper premises of the