Protocol for ConnectionManager. Fix reconnection logic.

--- src/onyx/messaging/netty_tcp.clj
+++ src/onyx/messaging/netty_tcp.clj
@@ -1,5 +1,6 @@
 (ns ^:no-doc onyx.messaging.netty-tcp
-    (:require [clojure.core.async :refer [chan >!! >! <!! alts!! timeout close! thread go-loop dropping-buffer]]
+    (:require [clojure.core.async :refer [chan >!! >! <!! alts!! timeout close!
+                                          thread go-loop sliding-buffer dropping-buffer]]
               [com.stuartsierra.component :as component]
               [taoensso.timbre :as timbre]
               [onyx.messaging.protocol-netty :as protocol]
@@ -66,14 +67,10 @@
           worker-thread-factory (DefaultThreadFactory. worker-event-thread-pool-name true)
           worker-group (if (epoll?)
                          (EpollEventLoopGroup. thread-count worker-thread-factory)
-                         (NioEventLoopGroup. thread-count worker-thread-factory))
-
-          pending-buffer-size (or (:onyx.messaging.netty/pending-buffer-size opts)
-                                  (:onyx.messaging.netty/pending-buffer-size defaults))]
+                         (NioEventLoopGroup. thread-count worker-thread-factory))]
       (timbre/info "Starting Netty Peer Group")
       (assoc component
              :shared-event-executor shared-event-executor
-             :pending-buffer-size pending-buffer-size
              :client-group client-group
              :worker-group worker-group
              :boss-group boss-group)))
@@ -170,17 +167,12 @@
 (defn start-netty-server
   [boss-group worker-group host port messenger inbound-ch release-ch retry-ch]
   (let [bootstrap (ServerBootstrap.)
-        channel (if (epoll?)
-                  EpollServerSocketChannel
-                  NioServerSocketChannel)
+        channel (if (epoll?) EpollServerSocketChannel NioServerSocketChannel)
         channel-group (DefaultChannelGroup. (str "tcp-server " host ":" port)
-                        (ImmediateEventExecutor/INSTANCE))
-        initializer (channel-initializer-done
-                     (gen-tcp-handler channel-group
-                                      (create-server-handler messenger
-                                                             inbound-ch
-                                                             release-ch
-                                                             retry-ch)))]
+                                            (ImmediateEventExecutor/INSTANCE))
+        initializer (->> (create-server-handler messenger inbound-ch release-ch retry-ch)
+                         (gen-tcp-handler channel-group)
+                         (channel-initializer-done))]
     (doto bootstrap
       (.group boss-group worker-group)
       (.channel channel)
@@ -198,7 +190,7 @@
           assigned-port (.. ch localAddress getPort)]
       (timbre/info "Netty server" host assigned-port "online")
       (fn killer []
-        (.. channel-group close awaitUninterruptibly)
+        (.close channel-group)
         (timbre/info "TCP server" host port "shut down")))))

 (defn new-client-handler []
@@ -222,8 +214,7 @@
              (timbre/fatal e))))))

 (defn established? [channel]
-  (and (not (nil? channel))
-       (.isActive channel)))
+  (and channel (.isActive channel)))

 (defn create-client [client-group host port]
   (let [channel (if (epoll?)
@@ -258,13 +249,16 @@
           retry-ch (chan (dropping-buffer (:onyx.messaging/retry-ch-buffer-size defaults)))
           bind-addr (bind-addr config)
           external-addr (external-addr config)
-          ports (allowable-ports config)]
+          ports (allowable-ports config)
+          pending-buffer-size (or (:onyx.messaging.netty/pending-buffer-size config)
+                                  (:onyx.messaging.netty/pending-buffer-size defaults))]
       (assoc component
              :bind-addr bind-addr
              :external-addr external-addr
              :boss-group boss-group
              :client-group client-group
              :worker-group worker-group
+             :pending-buffer-size pending-buffer-size
              :ports ports
              :resources (atom nil)
              :release-ch release-ch
@@ -308,14 +302,8 @@
     (reset! (:resources messenger)
             {:shutdown-fn shutdown-fn})))

-(defmethod extensions/initialize-peer-link NettyTcpSockets
-  [messenger _ site]
-  {:state :initializing
-   :site site
-   :pending-ch (chan (:pending-buffer-size messenger))})
-
 (defn flush-pending
-  "Flush all pending bufs. Useful when the channel is established"
+  "Flush all pending bufs. Run after when the channel is established."
   [^Channel channel pending-ch]
   (close! pending-ch)
   (loop []
@@ -324,24 +312,93 @@
       (recur)))
   (.flush channel))

+(defprotocol ConnectionManager
+  (connect [_])
+  (write [connection buf])
+  (reset-connection [_ previous-link-val])
+  (enqueue-pending [_ buf])
+  (close [_]))
+
+(defn add-failed-check
+  "Check if the future failed. link-val is used as a staleness check
+  for the connection as it should not be reset if it has already been reset."
+  [f connection link-val buf]
+  (.addListener f (reify GenericFutureListener
+                    (operationComplete [_ _]
+                      (when-not (.isSuccess f)
+                        (timbre/error "Message failed to send: " (.cause f))
+                        (reset-connection connection link-val))))))
+
+(defn make-pending-chan [messenger]
+  (chan (sliding-buffer (:pending-buffer-size messenger))))
+
+(defrecord Connection [messenger site link]
+  ConnectionManager
+  (reset-connection [connection previous-link-val]
+    (when (compare-and-set! link
+                            previous-link-val
+                            {:state :reset
+                             :pending-ch (make-pending-chan messenger)})
+      (connect connection)))
+
+  (enqueue-pending [connection buf]
+    (let [link-val @link
+          channel ^Channel (:channel link-val)]
+      (case (:state link-val)
+        :initializing (>!! (:pending-ch link-val) buf)
+        :connecting (>!! (:pending-ch link-val) buf)
+        :reset (connect connection)
+        :failed (connect connection)
+        ;; may have finished connecting in the time between
+        ;; so we should check if it's established now before trying to reconnect
+        :connected (if (established? channel)
+                     (.writeAndFlush channel buf (.voidPromise channel))
+                     (reset-connection connection link-val)))))
+
+  (write [connection buf]
+    (let [link-val @link
+          channel ^Channel (:channel link-val)]
+      (if (and channel (.isActive channel))
+        (let [fut (.writeAndFlush channel ^ByteBuf buf)]
+          (add-failed-check fut connection link-val ^ByteBuf buf))
+        (enqueue-pending connection buf))))
+
+  (close [_]
+    (some-> @link :channel .close)
+    (some-> @link :pending-ch close!))
+
+  (connect [_]
+    ; Ensures only a single thread will connect by only allowing the connection that performed
+    ; the CAS to go ahead and connect.
+    ; The spawned future will be the one to set the channel in the peer-link.
+    ; All sending threads will continue on adding to the pending-ch until the
+    ; connection has been established
+    (let [link-val @link
+          state (:state link-val)
+          connecting-link-val (assoc link-val :state :connecting)]
+      (when (#{:initializing :reset :failed} state)
+        (when (compare-and-set! link link-val connecting-link-val)
+          (future
+            (if-let [channel (create-client (:client-group messenger) (:netty/external-addr site) (:netty/port site))]
+              (let [pending-ch (:pending-ch connecting-link-val)
+                    connected-link-val (assoc connecting-link-val
+                                              :channel channel
+                                              :state :connected
+                                              :pending-ch nil)
+                    was-set? (compare-and-set! link connecting-link-val connected-link-val)]
+                (assert was-set?)
+                (flush-pending channel pending-ch))
+              (reset! link {:state :failed
+                            :pending-ch (make-pending-chan messenger)}))))))))
+
 (defmethod extensions/connect-to-peer NettyTcpSockets
-  ; Ensures only a single thread will connect by CAS.
-  ; The spawned future will be the one to set the channel in the peer-link.
-  ; All sending threads will continue on adding to the pending-ch until the
-  ; connection has been established
-  [messenger _ link {:keys [netty/external-addr netty/port]}]
-  (let [link-val @link
-        pending-ch (:pending-ch link-val)
-        new-link-val (assoc link-val :state :connecting)
-        state (:state link-val)
-        connect-here? (and (#{:initializing :failed} state)
-                           (compare-and-set! link link-val new-link-val))]
-    (when connect-here?
-      (future
-        (if-let [channel (create-client (:client-group messenger) external-addr port)]
-          (do (reset! link (assoc new-link-val :channel channel :state :connected))
-              (flush-pending channel pending-ch))
-          (reset! link {:site (:site link-val)}))))))
+  [messenger _ link site]
+  (doto
+    (->Connection messenger
+                  site
+                  (atom {:state :initializing
+                         :pending-ch (make-pending-chan messenger)}))
+    connect))

 (defmethod extensions/receive-messages NettyTcpSockets
   [messenger {:keys [onyx.core/task-map] :as event}]
@@ -355,53 +412,29 @@
           segments)
         segments))))

-(defn enqueue-pending [messenger event peer-link buf]
-  (let [link-val @peer-link
-        channel ^Channel (:channel link-val)]
-    (case (:state link-val)
-      :initializing (>!! (:pending-ch link-val) buf)
-      :connecting (>!! (:pending-ch link-val) buf)
-      ;; may have finished connecting in the time between
-      ;; so we should check if it's established now before trying to reconnect
-      :connected (if (established? channel)
-                   (.writeAndFlush channel buf (.voidPromise channel))
-                   (let [site (:site link-val)
-                         peer-link-new (extensions/initialize-peer-link messenger event site)
-                         link-val (reset! peer-link peer-link-new)]
-                     (>!! (:pending-ch link-val) buf)
-                     (extensions/connect-to-peer messenger event peer-link site))))))
-
-(defn add-failed-check [f messenger event peer-link buf]
-  (.addListener f (reify GenericFutureListener
-                    (operationComplete [_ _]
-                      (when-not (.isSuccess f)
-                        (timbre/error "Message failed to send: " (.cause f))
-                        ; Not sure if re-queing here is a great idea
-                        (enqueue-pending messenger event peer-link buf))))))
-
-(defn write [messenger event peer-link ^ByteBuf buf]
-  (let [channel ^Channel (:channel @peer-link)]
-    (if (established? channel)
-      (let [fut (.writeAndFlush channel buf)]
-        (add-failed-check fut messenger event peer-link buf))
-      (enqueue-pending messenger event peer-link buf))))
+; (defn reset-connection-enqueue [messenger event peer-link buf]
+;   (let [site (:site link-val)
+;         peer-link-new (extensions/initialize-peer-link messenger event site)
+;         link-val (reset! peer-link peer-link-new)]
+;     (>!! (:pending-ch link-val) buf)
+;     (extensions/connect-to-peer messenger event peer-link site)))

 (defmethod extensions/send-messages NettyTcpSockets
   [messenger event peer-link messages]
-  (write messenger event peer-link (protocol/build-messages-msg-buf (:compress-f messenger) messages)))
+  (write peer-link (protocol/build-messages-msg-buf (:compress-f messenger) messages)))

 (defmethod extensions/internal-ack-message NettyTcpSockets
   [messenger event peer-link message-id completion-id ack-val]
-  (write messenger event peer-link (protocol/build-ack-msg-buf message-id completion-id ack-val)))
+  (write peer-link (protocol/build-ack-msg-buf message-id completion-id ack-val)))

 (defmethod extensions/internal-complete-message NettyTcpSockets
   [messenger event id peer-link]
-  (write messenger event peer-link (protocol/build-completion-msg-buf id)))
+  (write peer-link (protocol/build-completion-msg-buf id)))

 (defmethod extensions/internal-retry-message NettyTcpSockets
-  [messenger event id ^Channel peer-link]
-  (write messenger event peer-link (protocol/build-retry-msg-buf id)))
+  [messenger event id peer-link]
+  (write peer-link (protocol/build-retry-msg-buf id)))

 (defmethod extensions/close-peer-connection NettyTcpSockets
-  [messenger event ^Channel peer-link]
-  (some-> @peer-link :channel .close))
+  [messenger event peer-link]
+  (close peer-link))


Use defaults for max-pending

Use defaults for max-pending

--- src/onyx/plugin/bench_plugin.clj
+++ src/onyx/plugin/bench_plugin.clj
@@ -1,6 +1,7 @@
 (ns onyx.plugin.bench-plugin
   (:require [clojure.core.async :refer [chan >!! <!! close! alts!! timeout]]
             [clojure.data.fressian :as fressian]
+            [onyx.static.default-vals :refer [defaults]]
             [onyx.peer.pipeline-extensions :as p-ext]))

 (def hundred-bytes


Normalize short kind forms (e.g. "r") to long forms ("requirement")

--- src/custard/parser.clj
+++ src/custard/parser.clj
@@ -31,6 +31,25 @@
   (update-in tree name-segments recursive-merge data))

 ;;;; Node tree
+
+(defn normalize-kind [node]
+  (letfn [(normalize [kind]
+            (let [aliases {"project" ["project"]
+                           "requirement" ["requirement" "req" "r"]
+                           "component" ["component" "comp" "c"]
+                           "work-item" ["work-item" "work" "w"]
+                           "tag" ["tag" "t"]}
+                  res (or (->> aliases
+                               (filter #(some #{kind} (second %)))
+                               ffirst)
+                          kind)]
+              res))]
+    (-> (if (contains? node "kind")
+          (update node "kind" normalize)
+          node)
+        (update :children (fn [children]
+                            (mapv #(normalize-kind %)
+                                  children))))))

 (defn inject-name [node parent-segments]
   (let [segments (if (nil? (:name node))
@@ -67,6 +86,7 @@
                     (build-node name-segment data)))]
     (let [tree (reduce build-step root data)]
       (-> tree
+          (normalize-kind)
           (inject-name [])
           (inject-parent nil)))))


Extended the search compare to regular expression; RegExp needs to be ISeq though

--- src/ttt/search/core.cljs
+++ src/ttt/search/core.cljs
@@ -75,13 +75,18 @@
     (keyword kw)
     kw))

-(extend-type js/String
-  s-protocols/ISearchable
+(extend-protocol s-protocols/ISearchable
+
+  js/String
   (search-compare [this compare-to]
     (if (keyword? this) ;; CLJS interns keywords as strings...
       (or (= this compare-to)
           (re-find (js/RegExp. (name this)) compare-to))
-      (re-find (js/RegExp. this) (name compare-to)))))
+      (re-find (js/RegExp. this) (name compare-to))))
+
+  js/RegExp
+  (search-compare [this compare-to]
+    (re-find this (name compare-to))))

 (defn query-tickets [query-vec]
   (let [query-vec (normalize-query-vec query-vec)


Fix for menu on website

Fix for menu on website

--- src/demogorgon/web.clj
+++ src/demogorgon/web.clj
@@ -50,7 +50,8 @@
       [:div.navbar-header
        [:button.navbar-toggle {"type" "button"
                                "data-toggle" "collapse"
-                               "data-target" ".nav-collapse"}
+                               "data-target" ".navbar-collapse"}
+        [:span.sr-only "Toggle navigation"]
         [:span.icon-bar ""]
         [:span.icon-bar ""]
         [:span.icon-bar ""]]
@@ -275,7 +276,6 @@
   (route/resources "/")
   (route/not-found (page-not-found)))

-(+ 1 1)
 (defn start-web []
   (run-jetty #'main-routes {:port 8080 :join? false}))


list to vector

list to vector

--- src/cljs/early_vote_site/constants.cljs
+++ src/cljs/early_vote_site/constants.cljs
@@ -1,7 +1,7 @@
 (ns early-vote-site.constants)

 (def states
-  (list{:fips-code "01" :state-name "Alabama"},
+  [{:fips-code "01" :state-name "Alabama"},
    {:fips-code "02" :state-name "Alaska"}
    {:fips-code "04" :state-name "Arizona"}
    {:fips-code "05" :state-name "Arkansas"},
@@ -51,4 +51,4 @@
    {:fips-code "53" :state-name "Washington"},
    {:fips-code "54" :state-name "West Virginia"},
    {:fips-code "55" :state-name "Wisconsin"},
-   {:fips-code "56" :state-name "Wyoming"}))
+   {:fips-code "56" :state-name "Wyoming"}])


non working extend type

non working extend type

--- src/cljs/infinitelives/pixi/sprite.cljs
+++ src/cljs/infinitelives/pixi/sprite.cljs
@@ -152,6 +152,14 @@
     (set-pivot! container (* xhandle width) (* yhandle height))
     container))

+;; (defprotocol Container
+;;   (update-handle [container & handles]))
+
+;; (extend-type js/PIXI.Container
+;;   Container
+;;   (update-handle
+;;     ([container & handles] (apply update-container-handles container handles))))
+
 (defn make-container
   [children & {:keys [x y xhandle yhandle scale alpha
                       rotation tint visible


Fix theme change bug

Fix theme change bug

--- src/cljs/koeeoadi/components/theme.cljs
+++ src/cljs/koeeoadi/components/theme.cljs
@@ -28,22 +28,22 @@
   (let [input (util/target-value e)]
     (om/update-state! comp assoc :name-temp input)))

+
 (defn select-theme [comp e]
-  (let [{theme-map    :theme/map
-         active-color :palette-widget/active-color} (om/props comp)
-        theme-name (util/target-value e)]
-    (om/transact! comp `[(state/merge
+  (let [{theme-map    :theme/map} (om/props comp)
+        theme-name   (util/target-value e)
+        active-color (first (get-in theme-map [theme-name :colors/list]))]
+    (om/transact! comp `[(theme/change
                            ~(assoc (get theme-map theme-name)
                               :theme/name
                               theme-name

-                              :mutate/name
-                              'theme/select
+                              :palette-widget/active-color active-color

                               :palette-widget/face-classes-by-color-type
                               (util/faces-to-colorize
                                 (get-in theme-map [theme-name :faces/list])
-                                (:color-id active-color))))
+                                (last active-color))))
                          :theme/map])))

 (defn new-theme [comp]


Added and example of only using some stacks to the tutorial.

--- src/clojush/problems/demos/tutorial.clj
+++ src/clojush/problems/demos/tutorial.clj
@@ -89,3 +89,31 @@
 ;   })

 ;(pushgp argmap)
+
+;;;;;;;;;;;;
+;; Here is the odd problem again, except this time only using instructions from
+;; specific stacks -- namely the integer, boolean, code, and exec stacks. This
+;; method is useful if you want to use instructions from some stacks but not others.
+
+;(def argmap
+;  {:use-single-thread true
+;   :error-function (fn [program]
+;                     (doall
+;                       (for [input (range 10)]
+;                         (let [state (run-push program
+;                                               (push-item input :input
+;                                                          (push-item input :integer
+;                                                                     (make-push-state))))
+;                               top-bool (top-item :boolean state)]
+;                           (if (not (= top-bool :no-stack-item))
+;                             (if (= top-bool (odd? input)) 0 1)
+;                             1000)))))
+;   :atom-generators (concat (registered-for-stacks [:integer :boolean :code :exec])
+;                            (list (fn [] (lrand-int 100))
+;                                  'in1))
+;   :parent-selection :tournament
+;   :genetic-operator-probabilities {:alternation 0.5
+;                                    :uniform-mutation 0.5}
+;   })
+
+;(pushgp argmap)


Temporarily hardcode double bias for young in possibly-just-young-or-old.

--- src/clojush/pushgp/parent_selection.clj
+++ src/clojush/pushgp/parent_selection.clj
@@ -50,7 +50,7 @@
   [pop {:keys [lexicase-youth-segregation]}]
   (if lexicase-youth-segregation
     (let [age-limit (lrand-nth (distinct (map :age pop)))
-          criterion (lrand-nth [<= >=])]
+          criterion (lrand-nth [<= <= >=])]
       (filter (fn [ind] (criterion (:age ind) age-limit))
               pop))
     pop))
@@ -266,3 +266,4 @@
                                                                (inc sel-count)))))
     selected))

+


Simplify specs, now mutations are just a query expr

--- src/com/wsscode/pathom/specs/query.cljc
+++ src/com/wsscode/pathom/specs/query.cljc
@@ -19,7 +19,7 @@
    (fn gen-ident-key [_] gen/keyword)

    ::gen-ident-value
-   (fn gen-ident-value [_] gen/any-printable)
+   (fn gen-ident-value [_] gen/simple-type-printable)

    ::gen-ident
    (fn gen-ident [{::keys [gen-ident-key gen-ident-value] :as env}]
@@ -83,12 +83,13 @@
        (list q p)))

    ::gen-query-expr
-   (fn gen-query-expr [{::keys [gen-property gen-join gen-ident gen-param-expr gen-special-property]
+   (fn gen-query-expr [{::keys [gen-property gen-join gen-ident gen-param-expr gen-special-property gen-mutation]
                         :as    env}]
      (gen/frequency [[20 (gen-property env)]
                      [6 (gen-join env)]
                      [1 (gen-ident env)]
                      [2 (gen-param-expr env)]
+                     [1 (gen-mutation env)]
                      [1 (gen-special-property env)]]))

    ::gen-query
@@ -113,18 +114,7 @@
    ::gen-mutation
    (fn gen-mutation [{::keys [gen-mutation-expr gen-mutation-join] :as env}]
      (gen/frequency [[5 (gen-mutation-expr env)]
-                     [1 (gen-mutation-join env)]]))
-
-   ::gen-mutation-tx
-   (fn gen-mutation-tx [{::keys [gen-mutation gen-property] :as env}]
-     (gen/fmap vec
-       (s/gen (s/cat :mutations (s/+ (s/with-gen ::mutation #(gen-mutation env)))
-                     :reads (s/* (s/with-gen ::property #(gen-property env)))))))
-
-   ::gen-transaction
-   (fn gen-transaction [{::keys [gen-query gen-mutation-tx] :as env}]
-     (gen/frequency [[5 (gen-query env)]
-                     [1 (gen-mutation-tx env)]]))})
+                     [1 (gen-mutation-join env)]]))})

 (defn default-gen [name]
   #((get generators name) generators))
@@ -172,10 +162,25 @@
     (s/and list? (s/cat :expr ::join-key-param-key :params ::params))
     (default-gen ::gen-join-key-param-expr)))

+(s/def ::mutation-key (s/with-gen symbol? (default-gen ::gen-mutation-key)))
+
+(s/def ::mutation-expr
+  (s/with-gen
+    (s/and list? (s/cat :mutate-key ::mutation-key :params (s/? ::params)))
+    (default-gen ::gen-mutation-expr)))
+
+(s/def ::mutation-join
+  (s/map-of ::mutation-expr ::query :count 1 :conform-keys true))
+
+(s/def ::mutation
+  (s/or :mutation ::mutation-expr
+        :mutation-join ::mutation-join))
+
 (s/def ::query-expr
   (s/or :prop ::property
         :join ::join
         :ident ::ident
+        :mutation ::mutation
         :param-exp ::param-expr
         :special ::special-property))

@@ -202,31 +207,6 @@
 (s/def ::query
   (s/coll-of ::query-expr :kind vector? :gen (default-gen ::gen-query)))

-(s/def ::mutation-key (s/with-gen symbol? (default-gen ::gen-mutation-key)))
-
-(s/def ::mutation-expr
-  (s/with-gen
-    (s/and list? (s/cat :mutate-key ::mutation-key :params (s/? ::params)))
-    (default-gen ::gen-mutation-expr)))
-
-(s/def ::mutation-join
-  (s/map-of ::mutation-expr ::query :count 1 :conform-keys true))
-
-(s/def ::mutation
-  (s/or :mutation ::mutation-expr
-        :mutation-join ::mutation-join))
-
-(s/def ::mutation-tx
-  (s/with-gen
-    (s/and vector? (s/cat :mutations (s/+ ::mutation) :reads (s/* ::property)))
-    (default-gen ::gen-mutation-tx)))
-
-(s/def ::transaction
-  (s/with-gen
-    (s/or :query ::query
-          :mutation ::mutation-tx)
-    (default-gen ::gen-transaction)))
-
 (comment
   (time
     (clojure.test.check/quick-check 30
@@ -236,16 +216,7 @@
         (fp/query->ast query))))

   (gen/sample (make-gen {::gen-params
-                         (fn [_] (gen/map (gen/return :param) gen/string-ascii))
-
-                         ::gen-property
-                         (fn [_] (gen/return :prop))
-
-                         ::gen-union-key
-                         (fn [_] (gen/elements [:a :b :c]))
-
-                         ::gen-ident
-                         (fn [_] (gen/return [:by-id 42]))}
+                         (fn [_] (gen/return {:param "value"}))}
                 ::gen-query)
     10)


use zero? instead of (= 0 ...)

use zero? instead of (= 0 ...)

--- src/greybear/model.clj
+++ src/greybear/model.clj
@@ -112,7 +112,7 @@
                             (limit 1)))]
     (when move
       (let [[x y] (map parse-int (split (:move move) #"-"))]
-        {:player (if (= 0 (mod (:ordinal move) 2))
+        {:player (if (zero? (mod (:ordinal move) 2))
                    WHITE
                    BLACK)
          :x x


remove async load guards

remove async load guards

--- src/java_time/core.clj
+++ src/java_time/core.clj
@@ -3,130 +3,127 @@
   (:import [java.time.temporal ValueRange]
            [java.time.chrono Chronology]))

-;; enable parallel loading
-(locking *ns*
-  (when-not (resolve 'as*)
-    (defprotocol Amount
-      (zero? [a]
-        "True if the amount is zero")
-      (negative? [a]
-        "True if the amount is negative")
-      (negate [a]
-        "Negates a temporal amount:
-
-          (negate (negate x)) == x")
-      (abs [a]
-        "Returns the absolute value of a temporal amount:
-
-          (abs (negate x)) == (abs x)"))
-
-    (defprotocol Supporting
-      (supports? [o p]
-        "True if the `o` entity supports the `p` property"))
-
-    (defprotocol HasChronology
-      (^java.time.chrono.Chronology chronology [o]
-        "The `Chronology` of the entity"))
-
-    (defprotocol HasFields
-      (fields [o]
-        "Fields present in this temporal entity")
-      (field* [o k]
-        "Internal use"))
-
-    (defprotocol HasUnits
-      (units [o]
-        "Units present in this temporal entity.")
-      (unit* [o k]
-        "Internal use"))
-
-    (defprotocol HasProperties
-      (properties [o]
-        "Map of properties present in this temporal entity")
-      (property [o k]
-        "Property of this temporal entity under key `k`"))
-
-    (defprotocol As
-      (as* [o k]
-        "Value of property/unit identified by key/object `k` of the temporal
-        entity `o`"))
-
-    (defprotocol ReadableProperty
-      (value [p]
-        "Value of the property"))
-
-    (defprotocol ReadableRangeProperty
-      (range [p]
-        "Range of values for this property")
-      (min-value [p]
-        "Minimum value of this property")
-      (largest-min-value [p]
-        "Largest minimum value of this property")
-      (smallest-max-value [p]
-        "Smallest maximum value of this property, e.g. 28th of February for months")
-      (max-value [p]
-        "Maximum value of this property, e.g. 29th of February for months"))
-
-    (defprotocol WritableProperty
-      (with-value [p v]
-        "Underlying temporal entity with the value of this property set to `v`"))
-
-    (defprotocol WritableRangeProperty
-      (with-min-value [p]
-        "Underlying temporal entity with the value set to the minimum available for
-        this property")
-      (with-largest-min-value [p]
-        "Underlying temporal entity with the value set to the largest minimum
-        available for this property")
-      (with-smallest-max-value [p]
-        "Underlying temporal entity with the value set to the smallest maximum
-        available for this property")
-      (with-max-value [p]
-        "Underlying temporal entity with the value set to the maximum
-        available for this property"))
-
-    (defprotocol KnowsTimeBetween
-      (time-between [o e u]
-        "Time between temporal entities `o` and `e` in unit `u`.
-
-        ```
-        (j/time-between (j/local-date 2015) (j/local-date 2016) :days)
-        => 365
-
-        (j/time-between :days (j/local-date 2015) (j/local-date 2016))
-        => 365
-        ```"))
-
-    (defprotocol KnowsIfLeap
-      (leap? [o]
-        "True if the year of this entity is a leap year."))
-
-    (defprotocol Truncatable
-      (truncate-to [o u]
-        "Truncates this entity to the specified time unit. Only works for units that
-        divide into the length of standard day without remainder (up to `:days`)."))
-
-    (defprotocol HasZone
-      (with-zone [o z]
-        "Returns this temporal entity with the specified `ZoneId`"))
-
-    (defprotocol Plusable
-      "Internal"
-      (seq-plus [o os]))
-
-    (defprotocol Minusable
-      "Internal"
-      (seq-minus [o os]))
-
-    (defprotocol Multipliable
-      (multiply-by [o v]
-        "Entity `o` multiplied by the value `v`"))
-
-    (defprotocol Ordered
-      (single-before? [a b]
-        "Internal use")
-      (single-after? [a b]
-        "Internal use"))))
+(defprotocol Amount
+  (zero? [a]
+    "True if the amount is zero")
+  (negative? [a]
+    "True if the amount is negative")
+  (negate [a]
+    "Negates a temporal amount:
+
+      (negate (negate x)) == x")
+  (abs [a]
+    "Returns the absolute value of a temporal amount:
+
+      (abs (negate x)) == (abs x)"))
+
+(defprotocol Supporting
+  (supports? [o p]
+    "True if the `o` entity supports the `p` property"))
+
+(defprotocol HasChronology
+  (^java.time.chrono.Chronology chronology [o]
+    "The `Chronology` of the entity"))
+
+(defprotocol HasFields
+  (fields [o]
+    "Fields present in this temporal entity")
+  (field* [o k]
+    "Internal use"))
+
+(defprotocol HasUnits
+  (units [o]
+    "Units present in this temporal entity.")
+  (unit* [o k]
+    "Internal use"))
+
+(defprotocol HasProperties
+  (properties [o]
+    "Map of properties present in this temporal entity")
+  (property [o k]
+    "Property of this temporal entity under key `k`"))
+
+(defprotocol As
+  (as* [o k]
+    "Value of property/unit identified by key/object `k` of the temporal
+    entity `o`"))
+
+(defprotocol ReadableProperty
+  (value [p]
+    "Value of the property"))
+
+(defprotocol ReadableRangeProperty
+  (range [p]
+    "Range of values for this property")
+  (min-value [p]
+    "Minimum value of this property")
+  (largest-min-value [p]
+    "Largest minimum value of this property")
+  (smallest-max-value [p]
+    "Smallest maximum value of this property, e.g. 28th of February for months")
+  (max-value [p]
+    "Maximum value of this property, e.g. 29th of February for months"))
+
+(defprotocol WritableProperty
+  (with-value [p v]
+    "Underlying temporal entity with the value of this property set to `v`"))
+
+(defprotocol WritableRangeProperty
+  (with-min-value [p]
+    "Underlying temporal entity with the value set to the minimum available for
+    this property")
+  (with-largest-min-value [p]
+    "Underlying temporal entity with the value set to the largest minimum
+    available for this property")
+  (with-smallest-max-value [p]
+    "Underlying temporal entity with the value set to the smallest maximum
+    available for this property")
+  (with-max-value [p]
+    "Underlying temporal entity with the value set to the maximum
+    available for this property"))
+
+(defprotocol KnowsTimeBetween
+  (time-between [o e u]
+    "Time between temporal entities `o` and `e` in unit `u`.
+
+    ```
+    (j/time-between (j/local-date 2015) (j/local-date 2016) :days)
+    => 365
+
+    (j/time-between :days (j/local-date 2015) (j/local-date 2016))
+    => 365
+    ```"))
+
+(defprotocol KnowsIfLeap
+  (leap? [o]
+    "True if the year of this entity is a leap year."))
+
+(defprotocol Truncatable
+  (truncate-to [o u]
+    "Truncates this entity to the specified time unit. Only works for units that
+    divide into the length of standard day without remainder (up to `:days`)."))
+
+(defprotocol HasZone
+  (with-zone [o z]
+    "Returns this temporal entity with the specified `ZoneId`"))
+
+(defprotocol Plusable
+  "Internal"
+  (seq-plus [o os]))
+
+(defprotocol Minusable
+  "Internal"
+  (seq-minus [o os]))
+
+(defprotocol Multipliable
+  (multiply-by [o v]
+    "Entity `o` multiplied by the value `v`"))
+
+(defprotocol Ordered
+  (single-before? [a b]
+    "Internal use")
+  (single-after? [a b]
+    "Internal use"))

 (defn as
   "Values of property/unit identified by keys/objects `ks` of the temporal


Fix #38. "box remove" did not sync tags when fetching.

--- src/leiningen/voom.clj
+++ src/leiningen/voom.clj
@@ -201,7 +201,7 @@

 (defn dirty-repo?
   [gitdir]
-  (git {:gitdir gitdir} "fetch" "--all")
+  (git {:gitdir gitdir} "fetch" "--all" "--tags")
   (let [g {:gitdir gitdir}
         dirty (:lines (git g "status" "--short"))
         stashes (:lines (git g "stash" "list"))


Reorder project info table columns to put repo and path together.

--- src/leiningen/voom.clj
+++ src/leiningen/voom.clj
@@ -555,7 +555,7 @@
                   (assoc :repo (-> (remotes (:gitdir info)) :origin :fetch))
                   (update-in [:sha] #(subs (str % "--------") 0 7)))))
        (sort-by :ctime)
-       (print-table [:repo :proj :version :branch :path :ctime :sha]))
+       (print-table [:repo :path :proj :version :branch :ctime :sha]))
   (newline))

 (defn fresh-version [[prj ver :as dep]]


Move 'q macro earlier so we can use it for constructing shabam db.

--- src/leiningen/voom.clj
+++ src/leiningen/voom.clj
@@ -1041,6 +1041,20 @@
 (pldb/db-rel r-commit-path ^:index sha ^:index path)
 (pldb/db-rel r-proj ^:index sha ^:index path ^:index name version has-snaps?)

+(defmacro q
+  [db & args]
+  (let [[count [rfresh & body]] (if (-> args first number?)
+                                  ((juxt first rest) args)
+                                  [nil args])
+        run-mode (if count
+                   '[l/run count]
+                   '[l/run*])
+        body (walk/postwalk #(get '{_ (l/lvar)} % %)
+                            body)]
+    `(pldb/with-db ~db
+       (~@run-mode ~rfresh
+                   ~@body))))
+
 (defn sub-paths
   "Turns path 'foo/bar/baz/quux' into:
   ['' 'foo' 'foo/bar' 'foo/bar/baz' 'foo/bar/baz/quux']"
@@ -1223,19 +1237,6 @@
   [_]
   (time (p-repos (fn [p] (updated-git-db p)))))

-(defmacro q
-  [db & args]
-  (let [[count [rfresh & body]] (if (-> args first number?)
-                                  ((juxt first rest) args)
-                                  [nil args])
-        run-mode (if count
-                   '[l/run count]
-                   '[l/run*])
-        body (walk/postwalk #(get '{_ (l/lvar)} % %)
-                            body)]
-    `(pldb/with-db ~db
-       (~@run-mode ~rfresh
-                   ~@body))))

 (def subtasks [#'build-deps #'deploy #'find-box #'freshen #'install


Re-enumerate symbols according to proper order in 'newest-voom-ver-by-spec.

--- src/leiningen/voom.clj
+++ src/leiningen/voom.clj
@@ -1221,12 +1221,12 @@
   proj dir change -> commit where a change happened in a subtree rooted with a project.clj
   - mark all project directory changes with project.clj version info
   - a. narrow proj dir changes by proj name spec
-  - a2. narrow all proj dir changes by *this* proj dir
-  - b. for each branch (matching spec) narrow proj dir changes by branch reachability
-  - c. narrow proj dir changes further by version range (spec)
-  - d. find max sem ver
-  - e. narrow proj dir changes further by max sem ver
-  - f. narrow proj dir changes to candidates by finding proj dir changes
+  - b. narrow all proj dir changes by *this* proj dir
+  - c. for each branch (matching spec) narrow proj dir changes by branch reachability
+  - d. narrow proj dir changes further by version range (spec)
+  - e. find max sem ver
+  - f. narrow proj dir changes further by max sem ver
+  - g. narrow proj dir changes to candidates by finding proj dir changes
        with no childer proj dir changes in this set
 "
   [proj-name {:keys [sha version repo branch path allow-snaps]
@@ -1252,34 +1252,34 @@
         :when (or (= found-path path) (nil? path))
         [found-branch branch-sha] (q pldb [ref sha] (r-branch _ ref sha))
         :when (or (= found-branch branch) (nil? branch))
-        :let [candidates-a2 (filter #(= (:path %) found-path) candidates-a)
-              sha-candidates-a (group-by :sha candidates-a2)
-              shas-b (sha-ancestors shabam branch-sha (map :sha candidates-a2))
-              shas-b (if (contains? sha-candidates-a branch-sha)
-                       (conj shas-b branch-sha)
-                       shas-b)
+        :let [candidates-b (filter #(= (:path %) found-path) candidates-a)
+              sha-candidates-a (group-by :sha candidates-b)
+              shas-c (sha-ancestors shabam branch-sha (map :sha candidates-b))
+              shas-c (if (contains? sha-candidates-a branch-sha)
+                       (conj shas-c branch-sha)
+                       shas-c)
               gvs (GenericVersionScheme.)
               version-constraint (when version
                                    (.parseVersionConstraint gvs version))
-              candidates-c (if version
+              candidates-d (if version
                         (keep #(let [[candidate] (get sha-candidates-a %)]
                                  (when (.containsVersion
                                         version-constraint
                                         (.parseVersion gvs (:version candidate)))
                                    candidate))
-                              shas-b)
-                        (map (comp first sha-candidates-a) shas-b))
-              [_ max-ver-d] (apply compare-max
+                              shas-c)
+                        (map (comp first sha-candidates-a) shas-c))
+              [_ max-ver-e] (apply compare-max
                                    (map #(vector (when % (.parseVersion gvs %)) %)
-                                        (distinct (map :version candidates-c))))
-              candidates-e (filter #(= max-ver-d (:version %)) candidates-c)
-              shas-e (map :sha candidates-e)
-              candidates-f (remove #(seq (sha-successors shabam (:sha %) shas-e))
-                                   candidates-e)]
-        {:keys [sha ctime]} candidates-f]
+                                        (distinct (map :version candidates-d))))
+              candidates-f (filter #(= max-ver-e (:version %)) candidates-d)
+              shas-f (map :sha candidates-f)
+              candidates-g (remove #(seq (sha-successors shabam (:sha %) shas-f))
+                                   candidates-f)]
+        {:keys [sha ctime]} candidates-g]
     {:sha sha
      :ctime ctime
-     :version max-ver-d
+     :version max-ver-e
      :path found-path
      :proj proj-name
      :gitdir gitdir


Return full git command context for 'ensure-repo.

--- src/leiningen/voom.clj
+++ src/leiningen/voom.clj
@@ -176,13 +176,13 @@
   [^String repo]
   (let [repo-dir (->> repo .getBytes ^bytes b64/encode String. (io/file voom-repos))]
     (if (.exists repo-dir)
-      (:bool (git {:gitdir repo-dir} "fetch"))
+      (git {:gitdir repo-dir} "fetch")
       (let [clone-repo (if (and (github-ssh-repo? repo) (https-credentials))
                          (let [https-repo (https-url-for (https-credentials) (github-ssh-path repo))]
                            (println (format "Using %s instead of %s to clone" https-repo repo))
                            https-repo)
                          repo)]
-        (:bool (git {} "clone" clone-repo repo-dir))))))
+        (git {} "clone" clone-repo repo-dir)))))

 (defn ancestor?
   [gitdir old new]


Added comments into html_renderer.clj

Added comments into html_renderer.clj

--- src/zg/html_renderer.clj
+++ src/zg/html_renderer.clj
@@ -177,6 +177,7 @@
   ))

 (defn render-front-page-for-whitelist
+  "Render front page for whitelisted words."
   [word url-prefix emender-page mode]
   [:div {:class "container-fluid"}
    [:div {:class "row"}
@@ -209,6 +210,7 @@
    [:br]])

 (defn render-front-page-for-blacklist
+  "Render front page for blacklisted words."
   [word url-prefix emender-page mode]
   [:div {:class "container-fluid"}
    [:div {:class "row"}
@@ -262,6 +264,7 @@
    [:br]])

 (defn render-front-page-for-atomic-typos
+  "Render front page for atomic typos (words)."
   [word url-prefix emender-page mode]
   [:div {:class "container-fluid"}
    [:div {:class "row"}
@@ -301,6 +304,7 @@
    [:br]])

 (defn render-front-page-for-glossary
+  "Render front page for glossary."
   [word url-prefix emender-page mode sources]
   [:div {:class "container-fluid"}
    [:div {:class "row"}
@@ -364,21 +368,24 @@
    [:br]])

 (defn yes-no
+  "Transformation from 0/1 to 'yes' and 'no' strings."
   [key-name search-results]
   (condp = (get search-results key-name)
     1 "yes"
     0 "no"
-      "N/A"))
+      "N/A")) ; fallback

 (defn yes-no-with-caution
+  "Transformation from 0/1/2 to 'yes', 'no', and 'with caution' strings."
   [key-name search-results]
   (condp = (get search-results key-name)
     1 "yes"
     0 "no"
     2 "with caution"
-      "N/A"))
+      "N/A")) ; fallback

 (defn get-source
+  "Try to retrieve the source from search results."
   [sources-map key-name search-results]
   (let [source (get search-results key-name)]
     (if source
@@ -386,6 +393,7 @@
       "N/A")))

 (defn get-class
+  "Try to retrieve class from search results."
   [classes-map key-name search-results]
   (let [class (get search-results key-name)]
     (if class
@@ -393,10 +401,12 @@
       "N/A")))

 (defn handle-null
+  "Handle null/nil in nice way."
   [key-name search-results]
   (or (get search-results key-name) "N/A"))

 (defn get-correct-or-preferred-forms
+  "Get the correct or preffered forms."
   [search-result]
   (str (:incorrect_forms search-result) (:correct_forms search-result)))

@@ -476,6 +486,7 @@
   ))

 (defn dictionary-name
+  "Retrieve dictionary type according to the attribute taken from database."
   [dictionary-type]
   (condp = dictionary-type
     "w" "whitelist"


(SERVER-2914) Internally prefer versioned-project to project-name-and-ref

--- src/clj/puppetlabs/services/master/file_serving.clj
+++ src/clj/puppetlabs/services/master/file_serving.clj
@@ -102,11 +102,11 @@
 (defn get-project-root
   "Lookup a project by name and return the path where its project files are
   located as a string."
-  [projects-dir project-name-and-ref]
-  (let [boltdir-path (str projects-dir "/" project-name-and-ref "/Boltdir")]
+  [projects-dir versioned-project]
+  (let [boltdir-path (str projects-dir "/" versioned-project "/Boltdir")]
     (if (fs/exists? boltdir-path)
       boltdir-path
-      (str projects-dir "/" project-name-and-ref))))
+      (str projects-dir "/" versioned-project))))

 (defn list-dirs-in-paths
   "Given a list of directories, return a list of all the subdirectories
@@ -180,9 +180,9 @@
   "Find a file in a project using the parameters from a `file_content` request.
   Returns the path as as string. If the module name is the same as the project
   name then files are served from the project directly."
-  [bolt-projects-dir project-name-and-ref mount module path]
-  (when (is-bolt-project? (str bolt-projects-dir "/" project-name-and-ref))
-    (let [project-root (get-project-root bolt-projects-dir project-name-and-ref)
+  [bolt-projects-dir versioned-project mount module path]
+  (when (is-bolt-project? (str bolt-projects-dir "/" versioned-project))
+    (let [project-root (get-project-root bolt-projects-dir versioned-project)
           project-config (read-bolt-project-config project-root)
           project-name (get project-config :name)
           modulepath (get-project-modulepath project-config)
@@ -227,8 +227,8 @@
 (defn find-project-plugin-file
   "Given a relative path as received by the plugins mount, search all lib dirs
   and return the path to the file if it's found in any of them."
-  [bolt-projects-dir project-name-and-ref mount relative-path]
-  (let [project-root (get-project-root bolt-projects-dir project-name-and-ref)
+  [bolt-projects-dir versioned-project mount relative-path]
+  (let [project-root (get-project-root bolt-projects-dir versioned-project)
         project-config (read-bolt-project-config project-root)
         project-as-module? (project-configured-as-module? project-config)
         modulepath (get-project-modulepath project-config)
@@ -238,9 +238,9 @@
 (defn get-plugins-metadata
   "Return the metadata for pluginsync. This scans the lib directories of all
   modules and returns a list of files smashed together."
-  [bolt-projects-dir project-name-and-ref mount checksum-type ignores ignore-source-permissions]
-  (when (is-bolt-project? (str bolt-projects-dir "/" project-name-and-ref))
-    (let [project-root (get-project-root bolt-projects-dir project-name-and-ref)
+  [bolt-projects-dir versioned-project mount checksum-type ignores ignore-source-permissions]
+  (when (is-bolt-project? (str bolt-projects-dir "/" versioned-project))
+    (let [project-root (get-project-root bolt-projects-dir versioned-project)
           project-config (read-bolt-project-config project-root)
           project-as-module? (project-configured-as-module? project-config)
           modulepath (get-project-modulepath project-config)


form exposable ports

form exposable ports

--- src/cljs/swarmpit/component/service/form_ports.cljs
+++ src/cljs/swarmpit/component/service/form_ports.cljs
@@ -1,12 +1,39 @@
 (ns swarmpit.component.service.form-ports
-  (:require [material.icon :as icon]
-            [material.component :as comp]
+  (:require [material.component :as comp]
             [swarmpit.component.state :as state]
+            [swarmpit.component.handler :as handler]
+            [swarmpit.routes :as routes]
             [rum.core :as rum]))

 (enable-console-print!)

 (def cursor [:page :service :wizard :ports])
+
+(defonce exposable-ports (atom []))
+
+(defn public-ports-handler
+  [repository]
+  (handler/get
+    (routes/path-for-backend :public-repository-ports)
+    {:params     {:repository repository}
+     :on-success (fn [response]
+                   (reset! exposable-ports response))}))
+
+(defn dockerhub-ports-handler
+  [distribution repository]
+  (handler/get
+    (routes/path-for-backend :dockerhub-repository-ports {:id distribution})
+    {:params     {:repository repository}
+     :on-success (fn [response]
+                   (reset! exposable-ports response))}))
+
+(defn registry-ports-handler
+  [distribution repository]
+  (handler/get
+    (routes/path-for-backend :registry-repository-ports {:id distribution})
+    {:params     {:repository repository}
+     :on-success (fn [response]
+                   (reset! exposable-ports response))}))

 (def headers [{:name  "Container port"
                :width "100px"}
@@ -86,7 +113,9 @@
                    :hostPort      0} cursor))

 (rum/defc form-create < rum/reactive []
-  (let [ports (state/react cursor)]
+  (let [exposable-ports (rum/react exposable-ports)
+        ports (concat exposable-ports
+                      (state/react cursor))]
     [:div
      (comp/form-add-btn "Publish port" add-item)
      (if (not (empty? ports))


Doubled max points

Doubled max points

--- src/clojush/problems/regression/bioavailability.clj
+++ src/clojush/problems/regression/bioavailability.clj
@@ -138,7 +138,7 @@
 (def argmap
   {:error-function (partial bioavailability-error-function :train)
    :atom-generators bioavailability-atom-generators
-   :max-points 1000
+   :max-points 2000
    :max-genome-size-in-initial-program 500
    :evalpush-limit 500
    :population-size 500


Update lexicon.clj

Update lexicon.clj

--- src/babel/espanol/lexicon.clj
+++ src/babel/espanol/lexicon.clj
@@ -100,6 +100,11 @@
                         :boot-stem2 "confes"}
              :synsem {:cat :verb
                       :sem {:pred :confess}}}
+
+   "consentir" {:espanol {:boot-stem1 "consient"
+                        :boot-stem2 "consent"}
+             :synsem {:cat :verb
+                      :sem {:pred :consent}}}

    "conservar" [{:synsem {:cat :verb
                           :sem {:pred :conserve}}}


Only mount graphics once, when loading

Only mount graphics once, when loading

--- src/blue_salamander/core.cljs
+++ src/blue_salamander/core.cljs
@@ -72,16 +72,16 @@

 (if initial-load?
   (do
+    (gfx/mount-graphics app-state)
     (k/start-keypress-tracking)
     (start-ticking)
     (set! initial-load? false)))

-(gfx/mount-graphics app-state)
+

 (defn on-js-reload []
   ;; optionally touch your app-state to force rerendering depending on
   ;; your application
   ;;(swap! app-state update-in [:__figwheel_counter] inc)
   #_(swap! app-state assoc :blockdata (maze/build-block-maze 10 1))
-  (set! queued-swap-fn #(assoc % :blockdata (maze/build-block-maze 5 3)))
   )


CLJS-1078: Nashorn REPL should use persistent code cache

Use code cache by default. Can be disabled with :code-cache false.

Add plain repl-env* constructor.

--- src/clj/cljs/repl/nashorn.clj
+++ src/clj/cljs/repl/nashorn.clj
@@ -15,7 +15,7 @@
             [cljs.repl :as repl]
             [cljs.compiler :as comp]
             [cljs.closure :as closure])
-  (:import [javax.script ScriptEngine ScriptEngineManager ScriptException]
+  (:import [javax.script ScriptEngine ScriptEngineManager ScriptException ScriptEngineFactory]
            [jdk.nashorn.api.scripting NashornException]))

 ;; Nashorn Clojurescript repl binding.
@@ -63,14 +63,21 @@

 ;; Implementation

-(defn create-engine []
-  (if-let [engine (.getEngineByName (ScriptEngineManager.) "nashorn")]
-    (let [context (.getContext engine)]
-      (.setWriter context *out*)
-      (.setErrorWriter context *err*)
-      engine)
-    (throw (IllegalArgumentException.
-            "Cannot find the Nashorn script engine, use a JDK version 8 or higher."))))
+(defn create-engine
+  ([] (create-engine nil))
+  ([{:keys [code-cache] :or {code-cache true}}]
+   (let [args (when code-cache ["-pcc"])
+         factories (.getEngineFactories (ScriptEngineManager.))
+         factory (get (zipmap (map #(.getEngineName %) factories) factories) "Oracle Nashorn")]
+     (if-let [engine (if-not (empty? args)
+                       (.getScriptEngine ^ScriptEngineFactory factory (into-array args))
+                       (.getScriptEngine ^ScriptEngineFactory factory))]
+       (let [context (.getContext engine)]
+         (.setWriter context *out*)
+         (.setErrorWriter context *err*)
+         engine)
+       (throw (IllegalArgumentException.
+                "Cannot find the Nashorn script engine, use a JDK version 8 or higher."))))))

 (defn eval-str [^ScriptEngine engine ^String s]
   (.eval engine s))
@@ -197,6 +204,12 @@
     (when-let [frames (read-string frames-str)]
       (vec (map #(update-in %1 [:file] (fn [s] (strip-file-name s output-dir))) frames)))))

+(defn repl-env* [{:keys [debug] :as opts}]
+  (let [engine (create-engine opts)]
+    (merge
+      (NashornEnv. engine debug)
+      opts)))
+
 (defn repl-env
   "Create a Nashorn repl-env for use with the repl/repl* method in Clojurescript and as the
    :repl-env argument to piggieback/cljs-repl. Besides the usual repl options (e.g. :source-map),
@@ -205,8 +218,5 @@
    :output-dir  the directory of the compiled files, e.g. \"resources/public/my-app\" (mandatory).
    :output-to   load this file initially into Nashorn, relative to output-dir.
                 Use a minimal bootstrapped cljs.core environment if not specified."
-  [& {:keys [debug] :as opts}]
-  (let [engine (create-engine)]
-    (merge
-      (NashornEnv. engine debug)
-      opts)))
+  [& {:as opts}]
+  (repl-env* opts))


log scan error

log scan error

--- src/clj/hdfs_cleaner/hdfs.clj
+++ src/clj/hdfs_cleaner/hdfs.clj
@@ -1,5 +1,6 @@
 (ns hdfs-cleaner.hdfs
-  (:require [cluster-connector.utils.for-debug :refer [$ spy]])
+  (:require [cluster-connector.utils.for-debug :refer [$ spy]]
+            [taoensso.timbre :as log])
   (:import (com.factual.hdfs_cleaner HDFS)
            (org.apache.hadoop.fs Path FileStatus)))

@@ -18,6 +19,7 @@
                           (reduce + (map :size sub-files))
                           (.getLen file))})
                (catch Exception e
+                 (log/error e "Scan failed for dir:" (-> file (.getPath) (.toString)))
                  {:has-error true}))))
     (.listStatus HDFS/dfs path)))


Let dumb users know they shouldn't press the magic button twice!

--- src/clj/mokkameister/brew.clj
+++ src/clj/mokkameister/brew.clj
@@ -1,11 +1,13 @@
 (ns mokkameister.brew
   (:require [clojure.core.async :refer [<! go timeout]]
+            [clj-time.core :as t]
+            [clj-time.coerce :as tc]
             [mokkameister
              [pusher :as pusher]
              [slack :as slack]
              [system :refer [system]]
              [train :refer [rand-train]]]
-            [mokkameister.db.persistence :refer [brew-stats persist-brew!]]))
+            [mokkameister.db.persistence :refer [brew-stats persist-brew! find-last-regular-coffee]]))

 (def ^:private channel "#penthouse")

@@ -49,9 +51,26 @@
   `(go (<! (timeout ~time-ms))
        ~@body))

-(defn start-brewing! [in-brew]
+(defn- currently-brewing? []
+  (when-let [last-brew (first (find-last-regular-coffee))]
+    (-> (:created last-brew)
+        (tc/from-sql-time)
+        (t/interval (t/now))
+        (t/in-minutes)
+        (< 2))))
+
+(defn- notify-already-brewing! []
+  (let [msg "Ro dykk ned! Kaffien kokar allereie!!1"]
+    (slack/notify msg :channel channel)))
+
+(defn- persist-and-notify-new-brew! [in-brew]
   (let [brew     (persist-brew! in-brew)
         delay-ms (* (:brew-time brew) 60 1000)]
     (notify-start! brew)
     (pusher/push! "coffee" "brewing" "start")
     (delayed! delay-ms (finish-brewing! brew))))
+
+(defn start-brewing! [in-brew]
+  (if (currently-brewing?)
+    (notify-already-brewing!)
+    (persist-and-notify-new-brew! in-brew)))


make *unchecked-if* backwards compatible so it doesn't break before 1.8.28

--- src/clj/shadow/cljs/build.clj
+++ src/clj/shadow/cljs/build.clj
@@ -689,7 +689,9 @@
   [{:keys [static-fns] :as state} {:keys [name input cljc] :as rc}]

   (binding [ana/*cljs-static-fns* static-fns
-            ana/*unchecked-if* false]
+            ;; initialize with default value
+            ;; must set binding to it is thread bound, since the analyzer may set! it
+            ana/*unchecked-if* ana/*unchecked-if*]
     (let [source @input]
       (with-logged-time
         [(:logger state) (format "Compile CLJS: \"%s\"" name)]


actually need load-core, need to figure out why

--- src/clj/shadow/cljs/build.clj
+++ src/clj/shadow/cljs/build.clj
@@ -499,10 +499,7 @@
               ana/*cljs-ns* ns
               ana/*cljs-file* name]

-      (with-redefs [ana/load-core ;; no-op this, not exactly sure that the point is anyways
-                    (fn [])
-
-                    ana/parse
+      (with-redefs [ana/parse
                     (fn shadow-parse [op env form name opts]
                       (condp = op
                         ;; the default ana/parse 'ns has way too many side effects we don't need or want
@@ -1134,6 +1131,7 @@
   "compile a list of sources by name"
   [state source-names]
   (with-compiler-env state
+    (ana/load-core)
     (reduce
       (fn [state source-name]
         (let [src (get-in state [:sources source-name])


update routes registry

update routes registry

--- src/cljc/salava/registry.cljc
+++ src/cljc/salava/registry.cljc
@@ -17,5 +17,6 @@
                 [salava.registerlink.ui.routes]
                 [salava.metabadge.ui.routes]
                 [salava.connections.ui.routes]
+                [salava.profile.ui.routes]
 ])))


fixed obvious bug

fixed obvious bug

--- src/cljs/chess_game/core.cljs
+++ src/cljs/chess_game/core.cljs
@@ -7,24 +7,24 @@
 (defonce app-state (atom {:text "hello world"}))

 ;; (defn contacts-view [data owner]
-;;   (reify
-;;     om/IInitState
-;;     (init-state [_]
-;;       {:vect [[1 1 1]
+;;    (reify
+;;      om/IInitState
+;;      (init-state [_]
+;;        {:vect [[1 1 1]
 ;;               [1 1 1]
-;;               [2 3 4]]})
-;;     om/IRenderState
-;;     (render-state [_ state]
-;;                   (apply dom/div nil
-;;                          (for [row (:vect state)]
-;;                            (dom/p nil (str row)))))))
+;;                [2 3 4]]})
+;;      om/IRenderState
+;;      (render-state [_ state]
+;;                    (apply dom/div nil
+;;                           (for [row (:vect state)]
+;;                             (dom/p nil (str row)))))))

 ;; (defn foo [data owner]
-;;   (reify
-;;     om/IRender
-;;     (render [this]
-;;             (dom/div nil
-;;               (dom/p nil "yo")))))
+;;    (reify
+;;      om/IRender
+;;      (render [this]
+;;              (dom/div nil
+;;                (dom/p nil "yo")))))

 (defn x-cord
   [pair]
@@ -82,6 +82,10 @@
                              {:state {:pawn (if (= x 1) true)}
                               :opts {:pos [x y]}}))))))))

+(defn start-game
+  []
+  (js/console.log "start game"))
+
 (defn main []
   (om/root
     (fn [app owner]
@@ -93,11 +97,9 @@
         (render [_]
                 (dom/div nil
                          (dom/p nil(:text app))
-                         (om/build contacts-view nil)
                          (om/build chess-board nil)
                          (dom/button #js {:onClick #(start-game)}
-                                     "Start Game")
-                         (om/build foo nil)))))
+                                     "Start Game")))))
     app-state
     {:target (. js/document (getElementById "app"))}))


Fix konserve name.

Fix konserve name.

--- src/cljx/geschichte/sync.cljx
+++ src/cljx/geschichte/sync.cljx
@@ -1,7 +1,7 @@
 (ns geschichte.sync
     "Synching related pub-sub protocols."
     (:require [geschichte.meta :refer [update isolate-branch]]
-              [konserve.protocols :refer [IAsyncKeyValueStore -assoc-in -get-in -update-in]]
+              [konserve.protocols :refer [IEDNAsyncKeyValueStore -assoc-in -get-in -update-in]]
               [geschichte.platform-log :refer [debug info warn error]]
               [clojure.set :as set]
               [hasch.core :refer [uuid uuid?]]


i18n translation bug fixed, :dict was missing

--- src/hell_hound/i18n/core.cljc
+++ src/hell_hound/i18n/core.cljc
@@ -46,7 +46,6 @@

 (def ^:private locale  (atom nil))
 (def ^:private options (atom nil))
-(def ^:private translate (partial tr @options @locale))

 (defn- check-for-valid-values
   []
@@ -65,7 +64,7 @@
   "Translate the given string according to the current locale."
   [& args]
   (check-for-valid-values)
-  (apply translate args))
+  (tr @options [@locale] (first (vec args))))

@@ -74,4 +73,4 @@
   be call at the begining of your application."
   [dictionary lang]
   (set-locale! lang)
-  (reset! options dictionary))
+  (reset! options {:dict dictionary}))


Enable warnings for reflections and unboxed math

These are good defaults to have so you know when to add type annotations.

--- src/leiningen/new/chestnut/dev/user.clj
+++ src/leiningen/new/chestnut/dev/user.clj
@@ -4,6 +4,12 @@
             [figwheel-sidecar.repl-api :as figwheel]{{#less?}}
             [clojure.java.shell]{{/less?}}{{#sass?}}
             [clojure.java.shell]{{/sass?}}))
+
+;; Let Clojure warn you when it needs to reflect on types, or when it does math
+;; on unboxed numbers. In both cases you should add type annotations to prevent
+;; degraded performance.
+(set! *warn-on-reflection* true)
+(set! *unchecked-math* :warn-on-boxed)

 {{#less?}}
 (defn start-less []


Only inject the <script> block if there is either immediate or onready initialization logic

--- src/main/clojure/cascade/dispatcher.clj
+++ src/main/clojure/cascade/dispatcher.clj
@@ -46,25 +46,31 @@
         ; The linebreak is to keep some braindead browsers from getting confused.
         :script { :type "text/javascript" :src path } [ linebreak ]))))

+(defn inject-script-block
+  [env dom-nodes immediate onready]
+  (extend-dom dom-nodes [:html :body] :bottom
+    (template
+      ; this could be done more efficiently
+      :script {:type "text/javascript"} [
+        (for [line immediate]
+          [line linebreak])
+        (when-not (empty? onready)
+          (import-jquery env)
+          (interpose "\n"
+            (concat [ "jQuery(function() {" ]
+              onready
+              [ "});"])))
+      ])))
+
 (defn add-script-block-for-initialization
   [env dom-nodes]
   (let [aggregation (-> env :cascade :resource-aggregation)
         immediate (@aggregation :immediate)
         onready (@aggregation :onready)]
-    (extend-dom dom-nodes [:html :body] :bottom
-      (template
-        ; this could be done more efficiently
-        :script {:type "text/javascript"} [
-          (for [line immediate]
-            [line linebreak])
-          (when-not (empty? onready)
-            (import-jquery env)
-            (interpose "\n"
-              (concat [ "jQuery(function() {" ]
-                onready
-                [ "});"])))
-        ]))))
-
+    (if (and (empty? immediate) (empty? onready))
+      dom-nodes
+      (inject-script-block env dom-nodes immediate onready))))
+
 (defn add-links-for-stylesheets
   [env dom-nodes]
     (let [aggregation (-> env :cascade :resource-aggregation)


oolong.cljc: Exclude Lifecycle/start/stop from cljs

--- src/irresponsible/oolong.cljc
+++ src/irresponsible/oolong.cljc
@@ -44,9 +44,11 @@

 ;; For convenience, we alias a few things from `component`
+;; Note that clojurescript seems to take objection to doing this for Lifecycle
+;; and its methods, so it's clj-only to make the cljs error more obvious.

-(def Lifecycle "The Lifecycle protocol for components" cpt/Lifecycle)
-(def start "Starts a component" cpt/start)
-(def stop "Stops a component" cpt/stop)
+#?(:clj (def Lifecycle "The Lifecycle protocol for components" cpt/Lifecycle))
+#?(:clj (def start "Starts a component" cpt/start))
+#?(:clj (def stop "Stops a component" cpt/stop))
 (def start-system "Starts a system" cpt/start-system)
 (def stop-system "Stops a system" cpt/stop-system)


Pass resource paths to dx

Pass resource paths to dx

--- src/leiningen/droid/build.clj
+++ src/leiningen/droid/build.clj
@@ -26,7 +26,7 @@
   "Creates a DEX file from the compiled .class files."
   [{{:keys [sdk-path out-dex-path external-classes-paths
             force-dex-optimize]} :android,
-    compile-path :compile-path :as project}]
+    compile-path :compile-path resource-paths :resource-paths :as project}]
   (info "Creating DEX....")
   (ensure-paths sdk-path)
   (let [dx-bin (sdk-binary sdk-path :dx)
@@ -34,12 +34,15 @@
                       "--no-optimize" [])
         annotations (str sdk-path "/tools/support/annotations.jar")
         deps (resolve-dependencies :dependencies project)
-        external-paths (or external-classes-paths [])]
+        external-paths (or external-classes-paths [])
+        existing-resource-paths (filter #(.exists (java.io.File. %))
+                                        resource-paths)]
     (with-process [proc (map str
                              (flatten [dx-bin "--dex" no-optimize
                                        "--output" out-dex-path
                                        compile-path annotations deps
-                                       external-paths]))]
+                                       external-paths
+                                       existing-resource-paths]))]
       (.addShutdownHook (Runtime/getRuntime) (Thread. #(.destroy proc))))))

 (defn crunch-resources


Eliminate removed GCL namespace

Eliminate removed GCL namespace

--- planck-cljs/src/planck/bundle.cljs
+++ planck-cljs/src/planck/bundle.cljs
@@ -156,5 +156,4 @@
    [goog.structs.StringSet]
    [goog.structs.TreeNode]
    [goog.structs.Trie]
-   [goog.structs.weak]
    [goog.text.LoremIpsum]))


update some dependencies

update some dependencies

--- sidecar/project.clj
+++ sidecar/project.clj
@@ -12,17 +12,17 @@
     :exclusions [org.apache.ant/ant]]
    [org.clojure/core.async "0.4.474"
     :exclusions [org.clojure/tools.reader]]
-   [com.stuartsierra/component "0.3.2"]
+   [com.stuartsierra/component "1.0.0"]
    [suspendable "0.1.1"
     :exclusions [org.clojure/clojure com.stuartsierra/component]]
-   [http-kit "2.3.0"]
-   [ring-cors "0.1.12"
+   [http-kit "2.3.0"] ;; tested and works with 2.4.0-alpha-6
+   [ring-cors "0.1.13"
     :exclusions [ring/ring-core org.clojure/clojure]]
-   [ring/ring-core "1.6.3"
+   [ring/ring-core "1.6.3" ;; tested and works with 1.8.3
     :exclusions
     [org.clojure/tools.reader
      org.clojure/clojure]]
-   [co.deps/ring-etag-middleware "0.2.0"]
+   [co.deps/ring-etag-middleware "0.2.1"]
    [clj-stacktrace "0.2.8"]
    [figwheel "0.5.20-SNAPSHOT"
       :exclusions [org.clojure/tools.reader]]


fix location of es-nozzle.ini in dev.clj

--- src/brainbot/nozzle/dev.clj
+++ src/brainbot/nozzle/dev.clj
@@ -5,6 +5,6 @@

 (def iniconfig
   (inihelper/read-ini-with-defaults
-   (format "%s/doc/nozzle.ini" (System/getProperty "user.dir"))))
+   (format "%s/doc/es-nozzle.ini" (System/getProperty "user.dir"))))

 (def system (sys/make-system iniconfig []))


WIP commit, add more patterns

WIP commit, add more patterns

--- src/oxcart/pattern.clj
+++ src/oxcart/pattern.clj
@@ -56,6 +56,16 @@
   (-> ast :op (= :fn)))

+(defn fn->name
+  "λ AST → (Option Symbol)
+
+  If the argument AST is a fn, attempts to return the internal name of
+  the fn defaulting to a freshly generated symbol."
+  [ast]
+  (when (fn? ast)
+    (-> ast :internal-name)))
+
+
 (defn fn-method?
   "λ AST → Boolean

@@ -87,6 +97,26 @@
   Indicates whether the argument form is a binding node."
   [ast]
   (-> ast :op (= :binding)))
+
+
+(defn binding->symbol
+  "λ AST → (Option Symbol)
+
+  If the argument form was a binding, returns the bound local
+  symbol."
+  [ast]
+  (when (binding? ast)
+    (-> ast :name)))
+
+
+(defn binding->value
+  "λ AST → (Option AST)
+
+  If the argument form was a binding, returns the bound value as an
+  AST node."
+  [ast]
+  (when (binding? ast)
+    (-> ast :init)))

 (defn local?
@@ -105,26 +135,6 @@
   [ast]
   (when (local? ast)
     (:name ast)))
-
-
-(defn binding->symbol
-  "λ AST → (Option Symbol)
-
-  If the argument form was a binding, returns the bound local
-  symbol."
-  [ast]
-  (when (binding? ast)
-    (-> ast :name)))
-
-
-(defn binding->value
-  "λ AST → (Option AST)
-
-  If the argument form was a binding, returns the bound value as an
-  AST node."
-  [ast]
-  (when (binding? ast)
-    (-> ast :init)))

 (defn invoke?


stringify the avatar

stringify the avatar

--- src/pc/models/cust.clj
+++ src/pc/models/cust.clj
@@ -6,7 +6,8 @@
             [datomic.api :refer [db q] :as d]
             [pc.datomic :as pcd]
             [pc.datomic.schema :as schema]
-            [pc.models.flag :as flag-model]))
+            [pc.models.flag :as flag-model]
+            [pc.utils :as utils]))

 ;; We'll pretend we have a type here
@@ -90,13 +91,16 @@
     (flag-model/add-flag cust :flags/private-docs)))

 (defn read-api [cust]
-  (select-keys cust
-               (concat
-                (schema/browser-setting-idents)
-                [:cust/email :cust/uuid :cust/name :flags :google-account/avatar])))
+  (-> cust
+    (select-keys (concat
+                  (schema/browser-setting-idents)
+                  [:cust/email :cust/uuid :cust/name :flags :google-account/avatar]))
+    (utils/update-when-in [:google-account/avatar] str)))

 (defn public-read-api [cust]
-  (select-keys cust [:cust/uuid :cust/name :cust/color-name :google-account/avatar]))
+  (-> cust
+    (select-keys [:cust/uuid :cust/name :cust/color-name :google-account/avatar])
+    (utils/update-when-in [:google-account/avatar] str)))

 (defn public-read-api-per-uuids
   "Returns hashmap of uuid to cust-map, e.g. {#uuid '123' {:cust/uuid '123' :cust/name 'd'}}"


Simplify history-watcher and undo-handler

--- src/pot/core/hand.cljs
+++ src/pot/core/hand.cljs
@@ -16,9 +16,9 @@
           hval @history
           cursor (:cursor hval)
           last-board (:board (get-in hval [:snapshots (dec cursor)]))]
-      (when-not (or (= old-board new-board) (= old-board last-board))
+      (when-not (= old-board new-board)
         (swap! history assoc-in [:snapshots cursor] old)
-        (swap! history update-in [:cursor] inc)))))
+        (swap! history update-in [:cursor] (if (= new-board last-board) dec inc))))))

 (defn storage-watcher
   [storage key]
@@ -51,16 +51,7 @@

 (defn undo-handler
   [_ state history]
-  (let [hval @history sval @state
-        cursor (:cursor hval)
-        last-board (get-in hval [:snapshots (dec cursor) :board])
-        game-over (:game-over sval)
-        board (:board sval)]
-    (when last-board
-      (remove-watch state :history-watcher)
-      (when game-over
-        (swap! state assoc :game-over false))
-      (swap! state assoc :board last-board)
-      (add-watch state :history-watcher (history-watcher state history))
-      (swap! history assoc-in [:snapshots cursor] sval)
-      (swap! history update-in [:cursor] dec))))
+  (let [history-value @history
+        last-snapshot (get-in history-value [:snapshots (dec (:cursor history-value))])]
+    (when last-snapshot
+      (reset! state last-snapshot))))


Make better normalize-attributes

Make better normalize-attributes

--- src/pump/template.cljs
+++ src/pump/template.cljs
@@ -40,12 +40,9 @@
    :for :htmlFor})

 (defn normalize-attributes
-  [tag-type attrs]
+  [attrs]
   (into {} (map
-            (fn [[k v]] [(if (= tag-type :vanilla)
-                           (dash-to-camel-name (attr-mapping k k))
-                           k)
-                         v])
+            (fn [[k v]] [(dash-to-camel-name (attr-mapping k k)) v])
             attrs)))

 (defn exclude-empty
@@ -62,7 +59,10 @@
                         :className (if class (string/replace class #"\." " "))}
         map-attrs      (first content)]
     (if (map? map-attrs)
-      [tag-type tag (merge tag-attrs (normalize-attributes tag-type map-attrs)) (next content)]
+      [tag-type tag (merge tag-attrs (if (= tag-type :vanilla)
+                                       (normalize-attributes map-attrs)
+                                       map-attrs))
+       (next content)]
       [tag-type tag tag-attrs content])))

 (defn elem-factory


Display tag instead of SHA on version page

--- src/foreclojure/version.clj
+++ src/foreclojure/version.clj
@@ -1,15 +1,15 @@
 (ns foreclojure.version
   (:use [foreclojure.template :only [def-page]]
         [foreclojure.config   :only [repo-url]]
-        [foreclojure.git      :only [sha]]
+        [foreclojure.git      :only [sha tag]]
         [compojure.core       :only [defroutes GET]]))

 (def-page version []
   {:title "About/version"
    :content
-   (if sha
-     [:p "SHA: "
-      [:a {:href (str repo-url "/tree/" sha)} sha]]
+   (if tag
+     [:p
+      [:a {:href (str repo-url "/tree/" sha)} tag]]
      [:p "No git repository found"])})

 (defroutes version-routes


Simplify format-duration further.

Simplify format-duration further.

--- src-cljs/frontend/datetime.cljs
+++ src-cljs/frontend/datetime.cljs
@@ -163,15 +163,16 @@
    :months ["month" "months"]
    :years ["year" "years"]})

-(defn format-duration [duration-ms {:keys [seconds minutes hours days months years]}]
+(defn format-duration [duration-ms units]
   (let [ago (max (.floor js/Math (/ duration-ms 1000)) 0)
-        [divisor [singular plural]] (cond
-                                      (< ago minute) [1 seconds]
-                                      (< ago hour) [minute minutes]
-                                      (< ago day) [hour hours]
-                                      (< ago month) [day days]
-                                      (< ago year) [month months]
-                                      :else [year years])
+        [divisor unit] (cond
+                         (< ago minute) [1 :seconds]
+                         (< ago hour) [minute :minutes]
+                         (< ago day) [hour :hours]
+                         (< ago month) [day :days]
+                         (< ago year) [month :months]
+                         :else [year :years])
+        [singular plural] (units unit)
         time-count (.round js/Math (/ ago divisor))]
     (str time-count " "  (if (= 1 time-count) singular plural))))


no important

no important

--- src/Miscellaneous/warehouse.clj
+++ src/Miscellaneous/warehouse.clj
@@ -131,7 +131,7 @@
         func #(into pivot %)]
     (map func word-seg)))

-;(unwind {:a 1 :b 2 :word-seg [{:word 4 :nature 5} {:word 6 :nature 7}]})
+(unwind {:a 1 :b 2 :word-seg [{:word 4 :nature 5} {:word 6 :nature 7}]})

 (defn word-seg
   [collections target-key & kws]


reverted middleware order

reverted middleware order

--- src/re_frame/core.cljs
+++ src/re_frame/core.cljs
@@ -11,7 +11,7 @@
 (def dispatch         handlers/dispatch)
 (def dispatch-sync    handlers/dispatch-sync)

-(def register-sub subs/register)
+(def register-sub  subs/register)
 (def subscribe     subs/subscribe)

@@ -32,4 +32,4 @@
   ([id handler]
     (register-handler id pure handler))
   ([id middleware handler]
-    (register-handler id (comp middleware pure) handler)))
+    (register-handler id (comp pure middleware) handler)))


config: lexicographically sort files before including them

A common use of the include directory functionality is to
load files in order, allowing symbols referenced early
in the inclusion process in subsequently loaded files.

With a lexicographical sort, the canonical use-case
of using a numbered naming scheme for include files
is now possible.

--- src/riemann/config.clj
+++ src/riemann/config.clj
@@ -182,19 +182,19 @@
   (kafka-consumer {:consumer.config {:bootstrap.servers \"localhost:9092\"
                                      :group.id \"riemann\"}
                    :topics [\"riemann\"]})
-
+
   Options:
-
+
   For a full list of :consumer.config options see the kafka consumer docs.
   NOTE: The :enable.auto.commit option is ignored and defaults to true.

-  :consumer.config      Consumer configuration
+  :consumer.config      Consumer configuration
     :bootstrap.servers  Bootstrap configuration, default is \"localhost:9092\"
     :group.id           Consumer group id, default is \"riemann\"
   :topics               Topics to consume from, default is [\"riemann\"]
-  :key.deserializer     Key deserializer function, defaults to the
+  :key.deserializer     Key deserializer function, defaults to the
                         keyword-deserializer.
-  :value.deserializer   Value deserializer function, defaults to
+  :value.deserializer   Value deserializer function, defaults to
                         json-deserializer.
   :poll.timeout.ms      Polling timeout, default is 100."

@@ -437,6 +437,7 @@
              file-seq
              (filter config-file?)
              (map str)
+             (sort)
              (map include)
              dorun)
         (load-file path)))))


Clean up config/config-file?

Clean up config/config-file?

--- src/riemann/config.clj
+++ src/riemann/config.clj
@@ -317,8 +317,9 @@
       (throw (logging/nice-syntax-error e file)))))

-(defn- is-config-file?
-  [file]
+(defn- config-file?
+  "Is the given File a configuration file?"
+  [^File file]
   (let [filename (.getName file)]
     (and (.isFile file)
          (or (.matches filename ".*\\.clj$")
@@ -341,6 +342,6 @@
               *ns* (find-ns 'riemann.config)]
       (if (.isDirectory file)
         (doseq [f (file-seq file)]
-          (when (is-config-file? f)
+          (when (config-file? f)
             (load-file (.toString f))))
         (load-file path)))))


Try processing body again

Try processing body again

--- src/sandbox/master.clj
+++ src/sandbox/master.clj
@@ -13,19 +13,22 @@
 (defn message-handler [req]
   (info req)
   (with-channel req req-channel
-    (go (let [code (get-in req [:params :code])]
-          (when code
+    (go (let [code (get-in req [:body :code])]
+          (if code
             (let [result-channel (docker/eval-on-worker code)
                   result (<! result-channel)
                   reply (str code "\n" "=> " result)]
-              (send! req-channel reply)))))))
+              (send! req-channel {:status 200
+                                  :headers {"Content-Type" "application/json"}
+                                  :body reply}))
+            (send! req-channel {:status 400}))))))

 (defroutes app-routes
   (POST "/clojure" [] message-handler))

 (def app (-> app-routes
              (wrap-json-response)
-             (wrap-json-params)))
+             (wrap-json-body)))

 (defn -main []
   (docker/build-container!)


fix bogus output when test library has no tests

--- src/main/clojure/clojure/test/generative/runner.clj
+++ src/main/clojure/clojure/test/generative/runner.clj
@@ -130,25 +130,26 @@
 (defn run-generative-tests
   "Run generative tests."
   [nses nthreads msec]
-  (let [test-msec (quot msec (count (->> (apply find-vars-in-namespaces nses)
-                                         (filter gentest?)
-                                         seq)))]
-    (doseq [ns nses]
-      (when-let [fs (->> (find-vars-in-namespaces ns)
-                         (filter gentest?)
-                         seq)]
-        (event/report :test/group
-                      :name ns
-                      :tags #{:begin}
-                      :test/threads nthreads
-                      :test/count (count fs))
-        (try
-         (run-batch
-          fs
-          nthreads
-          test-msec)
-         (finally
-          (event/report :test/group :tags #{:end} :test/threads nthreads :test/count (count fs))))))))
+  (let [c (count (->> (apply find-vars-in-namespaces nses)
+                      (filter gentest?)))]
+    (when-not (zero? c)
+      (let [test-msec (quot msec c)]
+        (doseq [ns nses]
+          (when-let [fs (->> (find-vars-in-namespaces ns)
+                             (filter gentest?)
+                             seq)]
+            (event/report :test/group
+                          :name ns
+                          :tags #{:begin}
+                          :test/threads nthreads
+                          :test/count (count fs))
+            (try
+             (run-batch
+              fs
+              nthreads
+              test-msec)
+             (finally
+              (event/report :test/group :tags #{:end} :test/threads nthreads :test/count (count fs))))))))))

 (defn has-clojure-test-tests?
   [ns]
@@ -169,7 +170,8 @@
             @event-counts))
         ct-results (run-with-counts 'clojure.test
                      #(binding [ctest/report cta/report-adapter]
-                        (apply ctest/run-tests (filter has-clojure-test-tests? nses))))
+                        (when-let [ctnses (seq (filter has-clojure-test-tests? nses))]
+                          (apply ctest/run-tests ctnses))))
         ctg-results (run-with-counts 'clojure.test.generative
                       #(run-generative-tests nses threads msec))]
     (io/await)


added se changer

added se changer

--- src/babel/francais/lexicon.cljc
+++ src/babel/francais/lexicon.cljc
@@ -637,7 +637,23 @@
                                          :pronoun true
                                          :reflexive true
                                          :sem subject-semantics}}}})
-
+
+   "se changer" (let [subject-semantics (atom {:human true})
+                      subject-agr (atom :top)]
+                  {
+                   :synsem {:cat :verb
+                            :essere true
+                            :sem {:pred :change-clothes
+                                  :reflexive true
+                                  :subj subject-semantics
+                                  :obj subject-semantics}
+                            :subcat {:1 {:agr subject-agr
+                                         :sem subject-semantics}
+                                     :2 {:agr subject-agr
+                                         :pronoun true
+                                         :reflexive true
+                                         :sem subject-semantics}}}})
+
    ;; not supported in grammar yet.
    ;;                                     :3 {:cat :adverb
    ;;                                         :sem {:pred :bad}}}}})


strip :pet from nouns (along with other semantic keys)

--- src/babel/italiano/grammar.cljc
+++ src/babel/italiano/grammar.cljc
@@ -491,6 +491,7 @@
                                                      (= % :buyable)         (= % :clothing) (= % :consumable)
                                                      (= % :drinkable)       (= % :edible)   (= % :furniture)
                                                      (= % :human)           (= % :legible)  (= % :part-of-human-body)
+                                                     (= % :pet)
                                                      (= % :physical-object) (= % :place)    (= % :speakable))))
                            filtered-v)]
                   (if (not (empty? remove-semantic-features))


enforce mutual exclusivity between pronoun and propernoun: pronoun=true/false <=> propernoun=false/true

--- src/babel/italiano/lexicon.cljc
+++ src/babel/italiano/lexicon.cljc
@@ -93,11 +93,13 @@
 (defn infer-cat [lexicon]
   (-> lexicon
       (if-has
+       [:synsem :pronoun] true
+       {:synsem {:cat :noun
+                 :propernoun false}})
+      (if-has
        [:synsem :propernoun] true
-       {:synsem {:cat :noun}})
-      (if-has
-       [:synsem :propernoun] true
-       {:synsem {:cat :noun}})))
+       {:synsem {:cat :noun
+                 :pronoun false}})))

 (defn infer-subcat [lexicon]
   (-> lexicon


reflexive=false rule should only apply to non-aux verbs

--- src/babel/italiano/lexicon.cljc
+++ src/babel/italiano/lexicon.cljc
@@ -234,6 +234,7 @@

       (default ;; reflexive defaults to false.
        {:synsem {:cat :verb
+                 :aux false
                  :sem {:reflexive false}}})

       (default ;; noun agreement


move can-pay? requirement of Tori Hanzō

move can-pay? requirement of Tori Hanzō

prevents an unrecoverable state where Runner gets a wait prompt but Corp can't afford to use Tori

--- src/clj/game/cards-upgrades.clj
+++ src/clj/game/cards-upgrades.clj
@@ -389,13 +389,12 @@
    {:events
     {:pre-resolve-damage
      {:once :per-run
-      :req (req (and this-server (= target :net) (> (last targets) 0)))
+      :req (req (and this-server (= target :net) (> (last targets) 0) (can-pay? state :corp nil [:credit 2])))
       :effect (req (swap! state assoc-in [:damage :damage-replace] true)
                    (damage-defer state side :net (last targets))
                    (show-wait-prompt state :runner "Corp to use Tori Hanzō")
                    (resolve-ability state side
-                     {:optional {:req (req (can-pay? state :corp nil [:credit 2]))
-                                 :prompt (str "Pay 2 [Credits] to do 1 brain damage with Tori Hanzō?") :player :corp
+                     {:optional {:prompt (str "Pay 2 [Credits] to do 1 brain damage with Tori Hanzō?") :player :corp
                                  :yes-ability {:msg "do 1 brain damage instead of net damage"
                                                :effect (req (swap! state update-in [:damage] dissoc :damage-replace)
                                                             (clear-wait-prompt state :runner)


refactor

refactor

--- src/clj/salava/metabadge/db.clj
+++ src/clj/salava/metabadge/db.clj
@@ -8,18 +8,6 @@

 (defqueries "sql/metabadge/queries.sql")

-(defn- revoked? [asr]
-  (or (= (:status asr) 410) (get-in asr [:body :revoked])))
-
-(defn- assertion [assertion-url]
-  (http/http-req {:socket-timeout 10000
-                  :conn-timeout   10000
-                  :method :get
-                  :url assertion-url
-                  :throw-exceptions false
-                  :as :json
-                  :accept :json}))
-
 (defn- fetch-json-data [url]
   (try
     (http/http-get url {:as :json :accept :json})
@@ -28,96 +16,60 @@
       {})))

 (defn user-badge-by-assertion
-  ;"in case of multiple hits return the most recent"
   [ctx assertion_url]
   (some-> (select-user-badge-by-assertion-url {:assertion_url assertion_url} (u/get-db ctx))))

 (defn metabadge?!
   "checks if badge is a metabadge, db is updated with information"
-  [db-conn factory-url user_badge]
+  [ctx factory-url user_badge]
   (let [url (str factory-url "/v1/assertion/is_metabadge/?url=" (u/url-encode (:assertion_url user_badge)))
         data (fetch-json-data url)]
-    (when-not (every? nil? (-> data (dissoc :last_modified) vals))
-      (if (nil? (:metabadge data))
-        (jdbc/execute! db-conn
-                       ["INSERT IGNORE INTO user_badge_metabadge (user_badge_id, meta_badge_req, last_modified) VALUES (?,?,?)"
-                        (:id user_badge) (:required_badge data) (:last_modified data)])
-        (doseq [m (:metabadge data)]
-          (jdbc/execute! db-conn
-                         ["INSERT IGNORE INTO user_badge_metabadge (user_badge_id, meta_badge, meta_badge_req, last_modified) VALUES (?,?,?,?)"
-                          (:id user_badge) m (:required_badge data) (:last_modified data)]))))
+    (jdbc/with-db-transaction  [db-conn (:connection (u/get-db ctx))]
+      (delete-user-badge-metabadge! {:user_badge_id (:id user_badge)} {:connection db-conn})
+      (when-not (every? nil? (-> data (dissoc :last_modified) vals))
+        (if (nil? (:metabadge data))
+          (insert-user-badge-metabadge! {:user_badge_id (:id user_badge) :meta_badge "NULL" :meta_badge_req (:required_badge data) :last_modified (:last_modified data)} {:connection db-conn})
+          (doseq [metabadge-id (:metabadge data)]
+            (insert-user-badge-metabadge! {:user_badge_id (:id user_badge) :meta_badge metabadge-id :meta_badge_req (:required_badge data) :last_modified (:last_modified data)} {:connection db-conn})))))
     (if (empty? data) false true)))

-#_(defn save-required-badges! [ctx db-conn metabadge user_badge user_metabadge_id]
-    (log/info "saving required badges" (:id metabadge) "," user_metabadge_id)
-    (doseq [badge (:required-badges metabadge)
-            :let [required-badge-content (when-not (:received badge) (fetch-json-data (:url badge)))
-                  user-badge (when (:received badge) (user-badge-by-assertion ctx (:url badge)))
-                  {:keys [name description image criteria]} required-badge-content]]
-      (if-not (:received badge)
-        (jdbc/execute! db-conn
-                       ["INSERT IGNORE INTO factory_metabadge_required (metabadge_id, required_badge_id, name, description, criteria, image_file, ctime, mtime) VALUES (?,?,?,?,?,?,?,?)"
-                        (:id metabadge) (:id badge) name description (u/md->html criteria) (u/file-from-url ctx image) (u/now) (u/now)])
-        (doseq [ub user-badge]
-          (jdbc/execute! db-conn
-                         ["INSERT IGNORE INTO user_metabadge_required_received (metabadge_id, user_metabadge_id, user_required_badge_id, user_id, last_modified) VALUES (?,?,?,?,?)"
-                          (:id metabadge) user_metabadge_id (:id ub) (:user_id user_badge) (:last_modified user_badge)])))))
+(defn badge-url [s]
+  (if (clojure.string/blank? s) nil (->> (clojure.string/split s #"&event=") first)))

-;;TODO Fix
-(defn get-metabadge! [ctx db-conn factory-url user_badge]
+(defn get-metabadge! [ctx factory-url user_badge]
   (let [url (str factory-url "/v1/assertion/metabadge/?url=" (u/url-encode (:assertion_url user_badge)))
         metabadges (:metabadge (fetch-json-data url))]
     (try
       (when-not (empty? metabadges)
         (doseq [metabadge metabadges
-                :let [metabadge-badge-content (when-not (-> metabadge :badge :received) (fetch-json-data (-> metabadge :badge :url)))
-                      user_metabadge (when (-> metabadge :badge :received) (user-badge-by-assertion ctx (-> metabadge :badge :url)))
+                :let [metabadge-badge-content (if-not (-> metabadge :badge :received)
+                                                (fetch-json-data (-> metabadge :badge :url))
+                                                (some->> (:badge (fetch-json-data (-> metabadge :badge :url)))
+                                                         (badge-url)
+                                                         (fetch-json-data)))
                       {:keys [description criteria image]} metabadge-badge-content]]
+          (when-not (empty? metabadge-badge-content)
+            (jdbc/with-db-transaction  [db-conn (:connection (u/get-db ctx))]
+              (delete-factory-metabadge! {:id (:id metabadge)} {:connection db-conn})
+              (insert-factory-metabadge! {:id (:id metabadge) :name (:name metabadge) :description description :criteria (u/md->html criteria) :image_file (u/file-from-url ctx image) :min_required (:min_required metabadge)} {:connection db-conn}))
+            (doseq [badge (:required_badges metabadge)
+                    :let [required-badge-content (if-not (:received badge)
+                                                   (fetch-json-data (:url badge))
+                                                   (some->> (:badge (fetch-json-data (:url badge)))
+                                                            (badge-url)
+                                                            (fetch-json-data)))
+                          {:keys [name description image criteria]} required-badge-content]]
+              (when-not (empty? required-badge-content)
+                (jdbc/with-db-transaction  [db-conn (:connection (u/get-db ctx))]
+                  (delete-factory-metabadge-required-badge! {:metabadge_id (:id metabadge) :required_badge_id (:id badge)} {:connection db-conn})
+                  (insert-factory-metabadge-required-badge! {:metabadge_id (:id metabadge) :required_badge_id (:id badge) :name name :description description :criteria (u/md->html criteria) :image_file (u/file-from-url ctx image)} {:connection db-conn})
+                  ))))))
+    (catch Exception e
+      (log/error (.getMessage e))))))

-          (if-not (-> metabadge :badge :received)
-            (jdbc/execute! db-conn
-                           ["INSERT IGNORE INTO factory_metabadge (id, name, description, criteria, image_file, min_required, ctime, mtime ) VALUES (?,?,?,?,?,?,?,?)"
-                            (:id metabadge) (:name metabadge) description (u/md->html criteria) (u/file-from-url ctx image) (:min_required metabadge) (u/now) (u/now)])
+(defn all-badges [ctx factory-url]
+  (select-all-badges {:obf_url (str factory-url "%")} (u/get-db ctx)))

-            (doseq [um user_metabadge]
-              (jdbc/execute! db-conn
-                             ["INSERT IGNORE INTO user_metabadge_received (metabadge_id, user_badge_id, user_id, name, min_required, last_modified) VALUES (?,?,?,?,?,?)"
-                              (:id metabadge) (:id um) (:user_id user_badge) (:name metabadge) (:min_required metabadge) (:last_modified user_badge) ])))
+(defn all-metabadges [ctx]
+  (select-all-metabadges {} (u/get-db ctx)))

-
-          (doseq [badge (:required_badges metabadge)
-                  :let [required-badge-content (when-not (:received badge) (fetch-json-data (:url badge)))
-                        user-badge (when (:received badge) (user-badge-by-assertion ctx (:url badge)))
-                        {:keys [name description image criteria]} required-badge-content]]
-            (if-not (:received badge)
-              (jdbc/execute! db-conn
-                             ["INSERT IGNORE INTO factory_metabadge_required (metabadge_id, required_badge_id, name, description, criteria, image_file, ctime, mtime) VALUES (?,?,?,?,?,?,?,?)"
-                              (:id metabadge) (:id badge) name description (u/md->html criteria) (u/file-from-url ctx image) (u/now) (u/now)])
-              (doseq [ub user-badge]
-                (if (empty? user_metabadge)
-                  (jdbc/execute! db-conn
-                                 ["INSERT IGNORE INTO user_metabadge_required_received (metabadge_id, user_required_badge_id, user_id, last_modified) VALUES (?,?,?,?)"
-                                  (:id metabadge) (:id ub) (:user_id user_badge) (:last_modified user_badge)])
-                  (doseq [um user_metabadge]
-                    (jdbc/execute! db-conn
-                                   ["INSERT IGNORE INTO user_metabadge_required_received (metabadge_id, user_metabadge_id, user_required_badge_id, user_id, last_modified) VALUES (?,?,?,?,?)"
-                                    (:id metabadge) (:id um) (:id ub) (:user_id user_badge) (:last_modified user_badge)]))
-                  )
-
-                )))))
-      (catch Exception e
-        (log/error (.getMessage e))))))
-
-(defn clean-metabadge-tables
-  "delete entries in user_badge_metabadge, user_metabadge_received and user_metabadge_required_received"
-  [ctx db-conn user-badge-id]
-  (jdbc/with-db-transaction [t-con db-conn]
-    (jdbc/execute! db-conn
-                   ["DELETE FROM user_badge_metabadge WHERE user_badge_id = ?"
-                     user-badge-id])
-    (jdbc/execute! db-conn
-                   ["DELETE FROM user_metabadge_received WHERE user_badge_id = ?"
-                     user-badge-id])
-    (jdbc/execute! db-conn
-                   ["DELETE FROM user_metabadge_required_received WHERE user_required_badge_id = ?"
-                     user-badge-id])))


whitespace changes

whitespace changes

--- src/clj_money/models/prices.clj
+++ src/clj_money/models/prices.clj
@@ -106,6 +106,9 @@
    (most-recent storage-spec commodity-id (t/today)))
   ([storage-spec commodity-id as-of]
    (with-storage [s storage-spec]
-     (-> (select-prices-by-commodity-id s commodity-id (tc/to-long as-of) {:limit 1})
+     (-> (select-prices-by-commodity-id s
+                                        commodity-id
+                                        (tc/to-long as-of)
+                                        {:limit 1})
          first
          after-read))))


Include secretary and new namespaces in main

--- src/cljs/comic_reader/main.cljs
+++ src/cljs/comic_reader/main.cljs
@@ -1,6 +1,12 @@
 (ns comic-reader.main
   (:require [figwheel.client :as fw]
+            [comic-reader.session :as session]
+            [comic-reader.pages.sites :as sites]
+            [comic-reader.pages.comics :as comics]
+            [comic-reader.pages.reader :as reader]
             [reagent.core :as reagent :refer [atom]]
+            [secretary.core :as secretary
+             :include-macros true :refer [defroute]]
             [ajax.core :refer [GET POST]]))

 (enable-console-print!)


cleanup

cleanup

--- src/sormilla/video.clj
+++ src/sormilla/video.clj
@@ -100,7 +100,7 @@
                             (thread* (read-frame-task socket frame-ch))
                             (thread* (decode-frame-task frame-ch image-ch))
                             (thread* (update-image-task image-ch))])]
-      (println "video: cleanup..." (= ch cancel-ch))
+      (println "video: cleanup...")
       (async/close! frame-ch)
       (async/close! image-ch)
       (try (.close ^Socket socket) (catch Exception _))


Added support for background-knowledge to stem-base

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

--- src/conexp/fca/implications.clj
+++ src/conexp/fca/implications.clj
@@ -142,22 +142,26 @@
     (partial close-under-implications implications)))

 (defn stem-base
-  "Returns stem base of given context."
-  [ctx]
-  (let [double-prime (partial context-attribute-closure ctx)
-	attributes   (attributes ctx)]
-    (loop [implications #{}
-	   last         #{}]
-      (let [conclusion-from-last (double-prime last)
-	    implications (if (not= last conclusion-from-last)
-			   (conj implications
-				 (make-implication last conclusion-from-last))
-			   implications)
-	    clop (clop-by-implications* implications)
-	    next (next-closed-set attributes clop last)]
-	(if next
-	  (recur implications next)
-	  implications)))))
+  "Returns stem base of given context. Uses background-knowledge as
+  starting set of implications, which will also be subtracted from the
+  final result."
+  ([ctx]
+     (stem-base ctx #{}))
+  ([ctx background-knowledge]
+     (let [double-prime (partial context-attribute-closure ctx),
+           attributes   (attributes ctx)]
+       (loop [implications background-knowledge,
+              last         #{}]
+         (let [conclusion-from-last (double-prime last),
+               implications (if (not= last conclusion-from-last)
+                              (conj implications
+                                    (make-implication last conclusion-from-last))
+                              implications),
+               clop (clop-by-implications* implications),
+               next (next-closed-set attributes clop last)]
+           (if next
+             (recur implications next)
+             (difference implications background-knowledge)))))))

 ;;;


Add secured route to admin page and a login page

--- src/todo_repl_webapp/handler.clj
+++ src/todo_repl_webapp/handler.clj
@@ -17,6 +17,9 @@
     (let [eval-result (e/evaluate evalInput)]
       (println "/eval " evalInput " evals to: " eval-result)
       (views/display eval-result)))
+  (GET "/admin" request (friend/authorize #{::admin}
+                                          "Admin page"))
+  (GET "/login" [] "This is a login page")
   (route/resources "/")
   (route/not-found "Not Found"))


fix bind* to use new fn names

fix bind* to use new fn names

--- src/gamma_driver/impl/bind.cljs
+++ src/gamma_driver/impl/bind.cljs
@@ -19,8 +19,8 @@

 (defmethod bind* :attribute [fns driver program element input]
-  (let [{:keys [attribute-input array-buffer]} fns]
-    (attribute-input
+  (let [{:keys [bind-attribute array-buffer]} fns]
+    (bind-attribute
      driver
      program
      element
@@ -40,8 +40,8 @@
                       (count data)))))))))

 (defmethod bind* :uniform [fns driver program element input]
-  (let [{:keys [uniform-input]} fns]
-    (uniform-input
+  (let [{:keys [bind-uniform]} fns]
+    (bind-uniform
      driver
      program
      element
@@ -65,8 +65,8 @@

 (defmethod bind* :texture-uniform [fns driver program variable input]
-  (let [{:keys [texture-uniform-input texture]} fns]
-    (texture-uniform-input
+  (let [{:keys [bind-texture-uniform texture]} fns]
+    (bind-texture-uniform
      driver
      program
      variable