Sketch out Snowbank fixture definition.

Sketch out Snowbank fixture definition.

--- src/afterglow/fixtures/blizzard.clj
+++ src/afterglow/fixtures/blizzard.clj
@@ -27,11 +27,10 @@
        names))

 (defn torrent-f3
-  "[Torrent F3](http://www.blizzardlighting.com/index.php?option=com_k2&view=item&id=174:torrent-f3™&Itemid=71)
-  moving head effects spotlight. The default patching orientation is sitting on its feet
-  with the LCD and control panel right side up and facing the
-  audience. In this orientation, at a pan of 0, the beam is straight
-  into the audience.
+  "Torrent F3 moving head effects spotlight. The default patching
+  orientation is sitting on its feet with the LCD and control panel
+  right side up and facing the audience. In this orientation, at a pan
+  of 0, the beam is straight into the audience.

   The origin of the light is, as for all moving heads, at the
   intersection of the pan and tilt axes. That is the point that you
@@ -145,7 +144,7 @@

 (defn blade-rgbw
   "[Blade
-  RGBW](http://www.blizzardlighting.com/index.php?option=com_k2&view=item&layout=item&id=177&Itemid=157)
+  RGBW](http://www.blizzardlighting.com/products/moving-head-lights/item/163-blade-rgbw)
   moving head. The default patching orientation is sitting on its feet
   with the LCD and control panel right side up and facing the
   audience. In this orientation, at a pan of 0, the beam is straight
@@ -301,7 +300,7 @@

 (defn weather-system
   "[Weather
-  System](http://www.blizzardlighting.com/index.php?option=com_k2&view=item&layout=item&id=173&Itemid=152)
+  System](http://www.blizzardlighting.com/products/all-in-one-lighting-systems/item/209-weather-system)
   8-fixture LED bar. Even though this fixture does not move, it is
   important to patch it at the correct orientation, so Afterglow can
   properly reason about the spatial relationships between the eight
@@ -345,8 +344,46 @@
           :name "Blizzard Weather System"
           :mode mode)))

+(defn- snowbank-head
+  "Creates a head definition for one head of the Snowbank."
+  [index]
+  ;; TODO: Actually implement! The snowbank has two rows of heads, that scan in opposite orders, and
+  ;;       project forward different amounts. But it has not been worth mapping them for our own fixture,
+  ;;       because it has too many failed LED channels. So we only use it in 7-channel mode as a blinder
+  ;;       generally aimed at the ceiling. For now, just cheating and pretending the heads are arranged
+  ;;       the same as for a Weather System
+  (ws-head index))
+
+(defn snowbank
+  "[Snow
+  Bank](http://www.blizzardlighting.com/products/led-effects/item/212-snowbank)
+  RGB Blinder / LED Pixel Effect."
+  ([]
+   (snowbank :26-channel))
+  ([mode]
+   (assoc (case mode
+            :7-channel {:channels [(chan/dimmer 1) (chan/color 2 :red) (chan/color 3 :green) (chan/color 4 :blue)
+                                   (chan/functions :control 5
+                                                   0 nil 8 "Red" 16 "Yellow" 24 "Green" 32 "Cyan" 40 "Blue"
+                                                   48 "Purple" 56 "White" (range 64 232 8) "Program"
+                                                   232 :sound-active)
+                                   (chan/functions :speed 6 0 nil 64 :speed)
+                                   (chan/functions :strobe 7 0 nil
+                                                   11 {:type :strobe
+                                                       :label "Strobe (?->?Hz)"
+                                                       :range :variable})]}
+            :26-channel {:channels [(chan/dimmer 1)
+                                    (chan/functions :strobe 26
+                                                    0 nil
+                                                    11 {:type :strobe
+                                                        :label "Strobe (?->?Hz)"
+                                                        :range :variable})]
+                         :heads (map snowbank-head (range 8))})
+          :name "Blizzard Snowbank"
+          :mode mode)))
+
 (defn snowball
-  "[Snowball](http://www.blizzardlighting.com/index.php?option=com_k2&view=item&layout=item&id=100&Itemid=96)
+  "[Snowball](http://www.blizzardlighting.com/products/led-effects/item/210-snowball)
   multi-beam moonflower effect light."
   []
   {:name "Blizzard Snowball"


wrappers for qname-* protocol functions

wrappers for qname-* protocol functions

--- src/main/clojure/clojure/data/xml/name.cljc
+++ src/main/clojure/clojure/data/xml/name.cljc
@@ -22,10 +22,20 @@

 (export-api
  #?@(:clj  [jvm/parse-qname jvm/make-qname]
-     :cljs [jsn/parse-qname jsn/make-qname])
-
- ;; protocol functions can be redefined by extend-*
- protocols/qname-uri protocols/qname-local)
+     :cljs [jsn/parse-qname jsn/make-qname]))
+
+;; protocol functions can be redefined by extend-*, so we wrap
+;; protocols/qname-uri protocols/qname-local within regular fns
+
+(defn qname-uri
+  "Get the namespace uri for this qname"
+  [v]
+  (protocols/qname-uri v))
+
+(defn qname-local
+  "Get the name for this qname"
+  [v]
+  (protocols/qname-local v))

 (defn qname
   ([name] (make-qname "" name ""))


Enhance zookeeper client resiliency (#1284)

* Enhance zookeeper client resiliency

* spelling change

--- ssclj/jar/src/com/sixsq/slipstream/ssclj/util/zookeeper.clj
+++ ssclj/jar/src/com/sixsq/slipstream/ssclj/util/zookeeper.clj
@@ -2,7 +2,8 @@
   (:require
     [environ.core :as env]
     [clojure.tools.logging :as log]
-    [zookeeper :as zk]))
+    [zookeeper :as zk])
+  (:import (org.apache.zookeeper KeeperException$SessionExpiredException)))

 (def ^:dynamic *client*)

@@ -16,7 +17,7 @@
   []
   (let [zk-endpoints (or (env/env :zk-endpoints) "localhost:2181")]
     (log/info "creating zookeeper client:" zk-endpoints)
-    (zk/connect zk-endpoints :timeout-msec 60000)))
+    (zk/connect zk-endpoints)))

 (defn close-client! []
   (when *client*
@@ -26,44 +27,55 @@
 (defn string-to-byte [value]
   (.getBytes (str value) "UTF-8"))

-(defn create-all [path & options]
-  (apply zk/create-all *client* path options))
+(defmacro retry-zk-client [zk-func path & options]
+  `(try
+     (when (or (nil? *client*)
+               (instance? clojure.lang.Var$Unbound *client*))
+       (set-client! (create-client)))
+     (~zk-func *client* ~path ~@options)
+     (catch KeeperException$SessionExpiredException e#
+       (log/warn "zookeeper session expired exception occurred!")
+       (close-client!)
+       (set-client! (create-client))
+       (~zk-func *client* ~path ~options))))

-(defn create [path & options]
-  (apply zk/create *client* path options))
+(defmacro create-all [path & options]
+  `(retry-zk-client zk/create-all ~path ~@options))

-(defn get-znode [path & options]
-  (let [result (apply zk/data *client* path options)
-        data (:data result)
-        value (when (-> data nil? not) (String. data))]
-    (assoc result :data value)))
+(defmacro create [path & options]
+  `(retry-zk-client zk/create ~path ~@options))

-(defn get-data [path & options]
-  (-> (apply get-znode path options)
-      :data))
+(defmacro get-znode [path & options]
+  `(let [result# (retry-zk-client zk/data ~path ~@options)
+         data# (:data result#)
+         value# (when (-> data# nil? not) (String. data#))]
+     (assoc result# :data value#)))

-(defn get-stat [path & options]
-  (-> (apply get-znode path options)
-      :stat))
+(defmacro get-data [path & options]
+  `(-> (get-znode ~path ~@options)
+       :data))
+
+(defmacro get-stat [path & options]
+  `(-> (retry-zk-client get-znode ~path ~@options)
+       :stat))

 (defn get-version
   [path]
   (-> (get-znode path) :stat :version))

-(defn set-data [path value & options]
-  (let [version (get-version path)
-        data (string-to-byte value)]
-    (apply zk/set-data *client* path data version options)))
+(defmacro set-data [path value & options]
+  `(let [version# (get-version ~path)
+         data# (string-to-byte ~value)]
+     (retry-zk-client zk/set-data ~path data# version# ~@options)))

-(defn exists [path & options]
-  (apply zk/exists *client* path options))
+(defmacro exists [path & options]
+  `(retry-zk-client zk/exists ~path ~@options))

-(defn children [path & options]
-  (apply zk/children *client* path options))
+(defmacro children [path & options]
+  `(retry-zk-client zk/children ~path ~@options))

-(defn delete-all [path & options]
-  (apply zk/delete-all *client* path options))
+(defmacro delete-all [path & options]
+  `(retry-zk-client zk/delete-all ~path ~@options))

-(defn delete [path & options]
-  (apply zk/delete *client* path options))
-
+(defmacro delete [path & options]
+  `(retry-zk-client zk/delete ~path ~@options))


Add 'add language' button

Add 'add language' button

--- src/cljs/cglossa/search_inputs.cljs
+++ src/cljs/cglossa/search_inputs.cljs
@@ -43,7 +43,9 @@
    "Search"])

 (defn- language-add-button []
-  [:span "ADD LANGUAGE"])
+  [:button.btn {:style {:marginLeft 20}
+                :on-click #()}
+   "Add language"])

 (defn- add-phrase-button []
   [:button.btn.add-phrase-btn {:on-click #()} "Or..."])


refactoring

refactoring

--- src/cljs/salava/badge/ui/modal.cljs
+++ src/cljs/salava/badge/ui/modal.cljs
@@ -18,8 +18,7 @@
             [salava.social.ui.badge-message-modal :refer [badge-message-link]]
             [salava.admin.ui.reporttool :refer [reporttool1]]
             [salava.badge.ui.verify :refer [check-badge]]
-            [salava.core.ui.tag :as tag]
-            [clojure.string :refer [blank?]]))
+            [salava.core.ui.tag :as tag]))

 (defn init-badge-connection [state badge-id]


Add type hint on prime?

Add type hint on prime?

--- src/clojure/com/hypirion/primes.clj
+++ src/clojure/com/hypirion/primes.clj
@@ -2,7 +2,7 @@
   (:import [com.hypirion.primes Primes])
   (:refer-clojure :exclude [take get]))

-(defn prime? [n]
+(defn prime? [^long n]
   (Primes/isPrime n))

 (defn take [n]


Implement schema- and value generators for :multi

--- src/test/cljc/mikron/schema_generators.cljc
+++ src/test/cljc/mikron/schema_generators.cljc
@@ -53,7 +53,9 @@
                inner-generator))

 (defmethod compound-schema-generator :multi [_ inner-generator]
-  inner-generator)
+  (tc.gen/fmap (fn [schema]
+                 [:multi {} any? {true schema}])
+               inner-generator))

 (defmethod compound-schema-generator :coll [schema-name inner-generator]
   (tc.gen/fmap (fn [schema]
@@ -106,8 +108,10 @@
 (defmethod schema-size :wrapped [[_ _ _ _ schema']]
   (schema-size schema'))

-(defmethod schema-size :multi [[_ _ _ schema']]
-  (schema-size schema'))
+(defmethod schema-size :multi [[_ _ _ schemas']]
+  (let [schema-sizes (map schema-size (vals schemas'))]
+    (/ (reduce + schema-sizes)
+       (count schema-sizes))))

 (defmethod schema-size :coll [[_ _ schema']]
   (* coll-schema-size-multiplier (schema-size schema')))
@@ -207,8 +211,8 @@
 (defmethod value-generator :wrapped [[_ _ _ post schema']]
   (tc.gen/fmap post (value-generator schema')))

-(defmethod value-generator :multi [_]
-  (tc.gen/return "Not value-generator implemented for :multi"))
+(defmethod value-generator :multi [[_ _ _ schemas']]
+  (tc.gen/one-of (map value-generator (vals schemas'))))

 (defmethod value-generator :list [[_ _ schema']]
   (tc.gen/list (value-generator schema')))


feat(ccw.bundle): add expect-bundle fn to help user plugins add expectations on ccw version

fixes #806

--- ccw.core/src/clj/ccw/bundle.clj
+++ ccw.core/src/clj/ccw/bundle.clj
@@ -31,10 +31,18 @@
  (defn available? [bundle]
   (and bundle (start-states (.getState bundle))))

- (defn bundle
+ (defn bundle
    "Return the bundle object associated with the bundle-symbolic-name (a String)"
    [bundle-symbolic-name]
    (Platform/getBundle bundle-symbolic-name))
+
+ (defn bundle-version
+   "Return the Version object for the bundle"
+   [bundle]
+   (.getVersion bundle))
+
+ (defn string->version "Create a version from a String"
+   [s] (Version. s))

  (defn version
    "Create a version object from a map with keys
@@ -62,7 +70,17 @@
    "Return truethiness if version1 is > than version2"
    [v1 v2]
    (pos? (compareTo v1 v2)))
-
+
+(defn expect-bundle
+  "Expect that bundle represented by `bundle-symbolic-name` exists and its version is at minimum equal to `bundle-version-string`"
+  [bundle-symbolic-name bundle-version-string]
+  (let [expected-version (string->version bundle-version-string)
+        actual-version   (.getVersion (bundle bundle-symbolic-name))]
+    (when (< actual-version expected-version)
+      (throw (ex-info (format "user plugin %s can only work with a Counterclockwise version at least equal to %s (%s found)."
+                        *ns* expected-version actual-version) {})))))
+
+
  (defn load-and-get-bundle [bundle-symbolic-name]
    ;; TODO: not good??, maybe we will not catch the right bundle (the same the OSGi framework would use ...)
    (try


Remove loading-flag from login

Remove loading-flag from login

--- src/discuss/communication/auth.cljs
+++ src/discuss/communication/auth.cljs
@@ -21,8 +21,7 @@
 (defn- wrong-login
   "Callback function for invalid credentials."
   [_]
-  (lib/error! (t :errors :login))
-  (lib/loading? false))
+  (lib/error! (t :errors :login)))

 (defn ajax-login
   "Get cleaned data and send ajax request."


Fix broken unit test.

Fix broken unit test.

--- test/one/test/dispatch.clj
+++ test/one/test/dispatch.clj
@@ -33,9 +33,9 @@
 ;; ============

 (deftest create-reaction
-  (is (= [:max-count :event-pred :reactor]
+  (is (= #{:max-count :event-pred :reactor}
          (js (let [reaction (react-to #{:do-something} (constantly true))]
-               (keys reaction))))))
+               (set (keys reaction)))))))

 (deftest reaction-catches-event
   (is (= [[:do-something nil]]


Black out old sample show when replacing it.

--- src/afterglow/examples.clj
+++ src/afterglow/examples.clj
@@ -289,7 +289,9 @@
   (set-default-show! (swap! sample-show (fn [s]
                                           (when s
                                             (show/unregister-show s)
-                                            (with-show s (show/stop!)))
+                                            (with-show s
+                                              (show/stop!)
+                                              (show/blackout-show)))
                                           (show/show :universes (distinct [universe extra-universe])
                                                      :description "Sample Show"))))


Add event observer tests to existing handler tests

--- test/rill/handler_test.clj
+++ test/rill/handler_test.clj
@@ -1,7 +1,7 @@
 (ns rill.handler-test
   (:require [rill.handler :as handler :refer [try-command]]
             [rill.aggregate :refer [handle-command aggregate-ids handle-event]]
-            [rill.message :as message :refer [defcommand defevent primary-aggregate-id]]
+            [rill.message :as message :refer [defcommand defevent primary-aggregate-id observers]]
             [clojure.test :refer [deftest testing is]]
             [rill.uuid :refer [new-id]]
             [rill.event-store :refer [retrieve-events]]
@@ -51,3 +51,59 @@
                 (retrieve-events store my-aggregate-id)))
       (is (= [::HandlerTestEvent]
              (map message/type (retrieve-events store my-aggregate-id)))))))
+
+(defevent FooEvent
+  :id s/Uuid)
+
+(defevent BarEvent
+  :id s/Uuid)
+
+(defevent BazEvent
+  :id s/Uuid)
+
+(defmethod handle-event ::FooEvent
+  [agg event]
+  agg)
+
+(defmethod handle-event ::BarEvent
+  [agg event]
+  agg)
+
+(defmethod handle-event ::BazEvent
+  [agg event]
+  agg)
+
+(defcommand FooCommand
+  :id s/Uuid)
+
+(defcommand BarCommand
+  :id s/Uuid)
+
+(defmethod handle-command ::FooCommand
+  [agg cmd]
+  [:ok [(foo-event (:id cmd))]])
+
+(defmethod handle-command ::BarCommand
+  [agg cmd]
+  [:ok [(bar-event (:id cmd))]])
+
+(defmethod observers ::FooEvent
+  [_]
+  [[:foo-observer (fn [observer event primary & rest-aggregates]
+                    [(bar-event (new-id))])]])
+
+(defmethod observers ::BarEvent
+  [_]
+  [[:bar-observer (fn [observer event primary & rest-aggregates]
+                    [(baz-event (new-id))])]])
+
+(deftest test-observers
+  (testing "Events triggered by command"
+    (let [[_ _ _ triggered-events] (try-command (given []) (bar-command (new-id)))]
+      ;; BarCommand -> BarEvent -> BarEventObserver -> BazEvent
+      (is (= [::BazEvent] (map message/type triggered-events)))))
+
+  (testing "Events triggered by other triggered events"
+    (let [[_ _ _ triggered-events] (try-command (given []) (foo-command (new-id)))]
+      ;; FooCommand -> FooEvent -> FooEventObserver -> BarEvent -> BarEventObserver -> BazEvent
+      (is (= [::BarEvent ::BazEvent] (map message/type triggered-events))))))


Adding proto repl sayid as a development time dependency in dev system.

--- dev-system/project.clj
+++ dev-system/project.clj
@@ -73,7 +73,8 @@
                         ;; Must be listed here as metadata db depends on it.
                         [drift "1.5.3"]
                         [proto-repl-charts "0.3.1"]
-                        [proto-repl "0.3.1"]]
+                        [proto-repl "0.3.1"]
+                        [proto-repl-sayid "0.1.3"]]
          ;; Use the following to enable JMX profiling with visualvm
          ;:jvm-opts ^:replace ["-server"
          ;                     "-Dcom.sun.management.jmxremote"


fix call to convert

fix call to convert

--- src/fscrawler_tika_convert/core.clj
+++ src/fscrawler_tika_convert/core.clj
@@ -27,7 +27,13 @@
 (defn convert
   "convert file and call wash on text property"
   [filename]
-  (update-in (convert filename) [:text] wash))
+  (update-in (tika/parse filename) [:text] wash))
+
+(defn break-channel
+  [ch delay]
+  (future
+    (Thread/sleep delay)
+    (lq/bind ch "no-such-queu-453456546345", "amq.fanout")))

 (defn handle-message
@@ -40,10 +46,12 @@
         ;; converted (tika/parse fp)
         ]
         ;;
-    (future (let [converted (convert fp)]
+    (future (
+             (println "starting...")
+             (let [converted (convert fp)]
               (println "before ack" (Thread/currentThread) (:delivery-tag metadata))
               (lb/ack ch (:delivery-tag metadata))
-              (println "done" fp " ****" )))
+              (println "done" fp " ****" ))))

     (println "scheduled" fp " ****" )))

@@ -61,7 +69,8 @@
                      (println "hello")
                      (println "headers" headers)
                      ;; (println (format "[consumer] Received %s" (String. payload "UTF-8")))
-                     (lb/ack ch delivery-tag))]
+                     (lb/ack ch delivery-tag)
+                     )]
     ;; (lq/declare ch queue-name :exclusive false :auto-delete true)
     ;; (lq/bind    ch queue-name "nextbot")
     (lb/qos ch (+ number-of-cores 4))
@@ -71,6 +80,7 @@
     ;;                  (fn [consumer_tag reason]
     ;;                    (println "shutdown" consumer_tag reason))

+    ;; (break-channel ch 2000)
     (lcons/blocking-subscribe ch queue-name handle-message :auto-ack false)))


Update Woman in the Red Dress to use new :no-effect of optional prompts.

--- src/clj/game/cards-resources.clj
+++ src/clj/game/cards-resources.clj
@@ -583,7 +583,7 @@
              {:msg (msg "reveal " (:title (first (:deck corp))) " on the top of R&D")
               :optional {:prompt (msg "Draw " (:title (first (:deck corp))) "?")
                          :msg (msg "draw " (:title (first (:deck corp))))
-                         :no-msg "doesn't draw with Woman in the Red Dress"
+                         :no-effect {:effect (effect (system-msg "doesn't draw with Woman in the Red Dress"))}
                          :player :corp :effect (effect (draw))}}}}

    "Wyldside"


A brief description added to message dispatcher on connection ns

--- src/clj/hellhound/connection.clj
+++ src/clj/hellhound/connection.clj
@@ -1,13 +1,17 @@
 (ns hellhound.connection
+  "This namespace is responsible for dispatching reveived data
+  from the client to the correct message handler in the server side
+  application. In order to define a message router checkout the
+  `hellhound.messaging.core` namespace. This namespace is an internal
+  namespace which used by the `websocket` component."
   (:require [hellhound.system :refer [get-system]]
             [hellhound.logger.core :as logger]))

 (defmulti router
-  "Multimethod to handle Sente `event-msg`s"
-  :id ; Dispatch on event-id
-  )
+  "Multimethod to handle Sente `event-msg`s. Dispatch messages by `:id`"
+  :id)

 (defmethod router
    :default ; Default/fallback case (no other matching handler)
@@ -24,15 +28,22 @@

 (defmethod router :hellhound/event
-  [{:as ev-msg :keys [?data ?reply-fn event event-router send-fn]}]
+  [{:as ev-msg :keys [?data ?reply-fn event message-router uid
+                      client-id send-fn]}]
   (logger/warn "TODO: Handle hellhound event")

-  (let [event-name    (:event-name ?data)
-        event-handler (get event-router event-name)]
+  (let [message-name    (:message-name ?data)
+        message-handler (get event-router event-name)]
     (if (nil? event-handler)
       ;; TODO: Should we send any error code or something similar?
       (logger/warn "Can't find an event handler for '%s' event" event-name)
-      (event-handler (:data ?data) ev-msg))))
+      ;; Calls the message handler function provided by the message router
+      ;; with the following arguments:
+      ;; First argument is the `data` which sent by the client, second argument
+      ;; is a `function` to send data back to the same client and finally the
+      ;; third argument is the `ev-msg` itself which contains complete
+      ;; on the received message information.
+      (message-handler (:data ?data) #(send-fn uid %) ev-msg))))

 (defn event-router [{:as ev-msg :keys [id ?data event]}]
   (router ev-msg))


added version number

added version number

--- src/clj/reply/initialization.clj
+++ src/clj/reply/initialization.clj
@@ -1,6 +1,8 @@
 (ns reply.initialization
   (:require [clojure.pprint]
             [clojure.repl]))
+
+(def ^:dynamic *reply-version* "2.0.0-SNAPSHOT")

 (defmacro repl-defn [sym & args]
   (let [no-meta-source (binding [*print-meta* true]
@@ -90,7 +92,7 @@
   "Assumes cd-client will be on the classpath when this is evaluated."
   []
   `(do
-    (println "Welcome to REPL-y!")
+    (println "REPL-y" *reply-version*)
     (println "Clojure" (clojure-version))

     (use '[clojure.repl :only ~'[source apropos dir]])


optional-key is red herring; maybe is what we want in schemas

--- src/cljc/coffee_table/model.cljc
+++ src/cljc/coffee_table/model.cljc
@@ -9,31 +9,31 @@
   (s/enum 0 1 2 3 4 5))

 ;;; No idea how implement this, will come back to later
- #_ (s/defschema Address
-      "Location information"
-      {:address1 s/Str
-       (s/optional-key :address2) s/Str
-       :city s/Str
-       :region s/Str
-       :country s/Str})
+(s/defschema Address
+  "Location information"
+  {:address1 s/Str
+   (s/optional-key :address2) s/Str
+   :city s/Str
+   :region s/Str
+   :country s/Str})

 (s/defschema Visit
   "Schema for coffee table visits"
   {(s/optional-key :id) s/Int
    :cafe_name s/Str
    :visit_date LocalDate
-   #_ (s/optional-key :address) #_ Address
-   (s/optional-key :machine) (s/maybe s/Str)
-   (s/optional-key :grinder) (s/maybe s/Str)
-   (s/optional-key :roast) (s/maybe s/Str)
+   #_ :address #_ Address
+   :machine (s/maybe s/Str)
+   :grinder (s/maybe s/Str)
+   :roast (s/maybe s/Str)
    :beverage_ordered s/Str
    :beverage_rating Rating
-   (s/optional-key :beverage_notes) (s/maybe s/Str)
-   (s/optional-key :service_rating) (s/maybe Rating)
-   (s/optional-key :service_notes) (s/maybe s/Str)
-   (s/optional-key :ambience_rating) (s/maybe Rating)
-   (s/optional-key :ambience_notes) (s/maybe s/Str)
-   (s/optional-key :other_notes) (s/maybe s/Str)})
+   :beverage_notes (s/maybe s/Str)
+   :service_rating (s/maybe Rating)
+   :service_notes (s/maybe s/Str)
+   :ambience_rating (s/maybe Rating)
+   :ambience_notes (s/maybe s/Str)
+   :other_notes (s/maybe s/Str)})

 (s/defn make-visit :- Visit
   "Create a visit object with default values"
@@ -45,7 +45,8 @@
           :visit_date date-visited
           :beverage_ordered beverage-ordered
           :beverage_rating beverage-rating}
-         {:machine nil
+         {#_ :address #_ nil
+          :machine nil
           :grinder nil
           :roast nil
           :beverage_notes nil


Added more namespace to the namespace completions (#223)

--- src/cljs/snapshot/lumo/repl.cljs
+++ src/cljs/snapshot/lumo/repl.cljs
@@ -1297,7 +1297,11 @@
       cognitect.transit
       lazy-map.core
       com.cognitect.transit
-      com.cognitect.transit]))
+      com.cognitect.transit
+      lumo.io
+      lumo.core
+      lumo.classpath
+      lumo.build.api]))

 (defn- namespace-completions []
   (transduce (comp


Don't log when a try-defn fn can't be created [IMMUTANT-124]

--- namespaces/common/src/main/clojure/immutant/try.clj
+++ namespaces/common/src/main/clojure/immutant/try.clj
@@ -45,9 +45,7 @@
   (let [fname (str *ns* "/" name)]      ; capture the ns-qualified name
     (if (worked? attempt)
       `(defn ~name ~@rest)
-      `(defn ~name [& args#]
-         (log/warn (str "The function, " ~fname ", is limited when run outside of Immutant"))
-         nil))))
+      `(defn ~name [& args#]))))

 (defmacro try-def
   "Does exactly what def does assuming eval'ing attempt doesn't throw


Autofocus searchfield on /

Autofocus searchfield on /

--- src/beebster_clj/views.clj
+++ src/beebster_clj/views.clj
@@ -42,7 +42,7 @@
     [:form {:method "post" :role "form" :action "/results"}
      [:div.tfield
       [:p "Enter Search term:"]
-      [:input.form-control {:type "text" :name "searchvalue" }]]
+      [:input.form-control {:type "text" :name "searchvalue" :autofocus "autofocus"}]]
      [:div.sbut
       [:input {:type "submit" :value "Search" :class "searchbutton"}]]]]))


Make the top comment more prominent in the datomic_helpers_sample.clj

--- datomic_helpers_sample.clj
+++ datomic_helpers_sample.clj
@@ -1,4 +1,7 @@
 ;;;; -*- Mode: clojure; indent-tabs-mode: nil; coding: utf-8; show-trailing-whitespace: t -*-
+;;;;
+;;;; =========================================================================================
+;;;;
 ;;;; Demonstrates how to use DATOMIC-HELPERS to define schema and some data
 ;;;; for two well known Datomic sample databases:
 ;;;;
@@ -7,6 +10,8 @@
 ;;;;    <datomic-root>/samples/seattle/seattle-schema.edn  and seattle-data0.edn
 ;;;; 2. The MusicBrainz sample, see original schema at
 ;;;;    https://github.com/Datomic/mbrainz-sample/blob/master/schema.edn
+;;;;
+;;;; =========================================================================================

 (ns datomic-helpers-sample
   (:require [datomic.api :as d])


only define uuid? in util for clj

only define uuid? in util for clj

cljs already has cljs.core/uuid?

--- src/braid/common/util.cljc
+++ src/braid/common/util.cljc
@@ -38,7 +38,8 @@
 (def bot-name-re
   #"(?:\w|\d){1,30}")

-(defn uuid?
-  [u]
-  #?(:clj (instance? java.util.UUID u)
-     :cljs (cljs.core/uuid? u)))
+; cljs already has cljs.core/uuid?
+#?(:clj
+   (defn uuid?
+     [u]
+     (instance? java.util.UUID u)))


remove debug info

remove debug info

--- src/ceres_collector/db.clj
+++ src/ceres_collector/db.clj
@@ -165,7 +165,6 @@
   (let [raw-html (if (= url :not-available)
                    nil
                    (slurp url))]
-    (debug "Storing raw html")
     (mc/insert-and-return
      @db
      "htmls"
@@ -274,6 +273,5 @@

   (def suids (map :_id (mc/find-maps @db "users" {:screen_name {$in news-accounts}})))

-  (mc/count @db "htmls" {:ts {$gt (t/date-time 2015 2 19)}})

   )


skip trasact! for speed

skip trasact! for speed

--- src/chat/client/store.cljs
+++ src/chat/client/store.cljs
@@ -182,8 +182,8 @@
 (defn set-new-message!
   [thread-id content]
   (if (get-in @app-state [:threads thread-id])
-    (transact! [:threads thread-id :new-message] (constantly content))
-    (transact! [:new-thread-msg thread-id] (constantly content))))
+    (swap! app-state assoc-in [:threads thread-id :new-message] content)
+    (swap! app-state assoc-in [:new-thread-msg thread-id] content)))

 (defn add-message! [message]
   (maybe-create-thread! (message :thread-id))


making progress!

making progress!

--- src/clj/cljs/sourcemap.clj
+++ src/clj/cljs/sourcemap.clj
@@ -2,16 +2,63 @@
   (:require [clojure.java.io :as io]
             [clojure.string :as string]
             [clojure.data.json :as json]
+            [clojure.pprint :as pp]
             [cljs.sourcemap.base64-vlq :as base64-vlq]))

-(defn decode [seg mapping]
+(defn seg->map [seg source-map]
   (let [[gcol source line col name] seg]
-   {:gcol gcol
-    :source (nth (:sources mapping) source)
-    :line line
-    :col col
-    :name (when name
-            (nth (:names mapping) name))}))
+   {:gcol   gcol
+    :source (nth (:sources source-map) source)
+    :line   line
+    :col    col
+    :name   (when name
+              (nth (:names source-map) name))}))
+
+(defn seg-combine [seg relseg]
+  (let [[gcol source line col name] seg
+        [rgcol rsource rline rcol rname] relseg]
+    [(+ gcol rgcol)
+     (+ (or source 0) rsource)
+     (+ (or line 0) rline)
+     (+ (or col 0) rcol)
+     (+ (or name 0) rname)]))
+
+(defn decode
+  ([source-map]
+     (decode (:mappings source-map) source-map))
+  ([mappings source-map]
+     (let [relseg-init [0 0 0 0 0]
+           update-result (fn [result seg gline]
+                           (let [segmap (seg->map seg source-map)]
+                             (update-in result [(:source segmap)]
+                               (fnil (fn [m]
+                                       (update-in m [(:line segmap)]
+                                         (fnil (fn [m]
+                                                 (assoc m (:col segmap)
+                                                   {:gline gline
+                                                    :gcol (:gcol segmap)
+                                                    :name (:name segmap)}))
+                                               (sorted-map))))
+                                     (sorted-map)))))
+           lines (seq (string/split mappings #";"))]
+       (loop [i 0 lines lines relseg relseg-init result {}]
+         (if lines
+           (let [line (first lines)
+                 [result relseg] (let [segs (seq (string/split line #","))]
+                                   (loop [segs segs relseg relseg result result]
+                                     (if segs
+                                       (let [seg (first segs)
+                                             nrelseg (seg-combine (base64-vlq/decode seg) relseg)]
+                                         (recur (next segs) nrelseg (update-result result nrelseg i)))
+                                       [result relseg])))]
+             (recur (inc i) (next lines) (assoc relseg 0 0) result))
+           result)))))
+
+(defn encode [xs]
+  )
+
+(defn gen-merged-map [cljs-map closure-map]
+  )

 (comment
   ;; INSTRUCTIONS:
@@ -35,9 +82,18 @@
       (string/split #";")
       first
       (string/split #",")
-      second
+      count)
+
+  (first (decode raw-source-map))
+
+  (-> raw-source-map
+      :mappings
+      (string/split #";")
+      first
+      (string/split #",")
+      (nth 30)
       base64-vlq/decode
-      (decode raw-source-map))
+      (seg->map raw-source-map))

   (first (string/split (:mappings raw-source-map) #";"))


Make create-history private

Make create-history private

--- src/cljs/lens/history.cljs
+++ src/cljs/lens/history.cljs
@@ -13,7 +13,7 @@
   ["/" {"" :index
         ["w/" :id] :workbook}])

-(defn create-history []
+(defn- create-history []
   (doto (Html5History.)
     (.setUseFragment false)
     (.setPathPrefix "")))


Using separate thought-edit-box paths for editing and adding notes

https://app.asana.com/0/17212341701456/46481344812604

--- src/cljs/memento/core.cljs
+++ src/cljs/memento/core.cljs
@@ -217,7 +217,7 @@
   :memory-edit-set
   (fn [app-state [_ thought]]
     (if (empty? thought)
-      (dispatch [:state-current-note nil]))
+      (dispatch [:state-note :edit-note nil]))
     (assoc-in app-state [:note :edit-memory] thought)
     ))

@@ -225,7 +225,7 @@
 (register-handler
   :memory-edit-save
   (fn [app-state _]
-    (let [note   (get-in app-state [:note :current-note])
+    (let [note   (get-in app-state [:note :edit-note])
           memory (get-in app-state [:note :edit-memory])
           url    (str "/api/memory/" (:id memory) "/thought")]
       (PUT url {:params        {:thought note :refine_id (get-in app-state [:note :focus :id])}
@@ -246,7 +246,7 @@
     (-> app-state
         (assoc-in [:ui-state :is-busy?] false)
         (assoc-in [:note :edit-memory] nil)
-        (assoc-in [:note :current-note] "")
+        (assoc-in [:note :edit-note] "")
         (assoc-in [:note :focus] nil)
         )))

@@ -356,9 +356,9 @@
       )))

 (register-handler
-  :state-current-note
-  (fn [app-state [_ note]]
-    (assoc-in app-state [:note :current-note] note)))
+  :state-note
+  (fn [app-state [_ note-id note]]
+    (assoc-in app-state [:note note-id] note)))

 (register-handler
   :state-current-query
@@ -430,7 +430,6 @@

 (defn focused-thought []
   (let [focus (subscribe [:note :focus])]
-
     (if @focus
       [:div {:class "col-sm-10 col-sm-offset-1"}
        [:div {:class "panel panel-default"}
@@ -442,8 +441,8 @@
     ))

-(defn thought-edit-box []
-  (let [note (subscribe [:note :current-note])]
+(defn thought-edit-box [note-id]
+  (let [note (subscribe [:note note-id])]
     (fn []
       [:div {:class "form-group"}
        [focused-thought]
@@ -454,7 +453,7 @@
                      :placeholder "I was thinking..."
                      :rows        12
                      :style       {:font-size "18px"}
-                     :on-change   #(dispatch-sync [:state-current-note (-> % .-target .-value)])
+                     :on-change   #(dispatch-sync [:state-note note-id (-> % .-target .-value)])
                      :value       @note
                      }]]
         ]]))
@@ -466,12 +465,12 @@
     (fn []
       [:fielset
        [:div {:class "form-horizontal"}
-        [thought-edit-box]
+        [thought-edit-box :current-note]
         [:div {:class "form-group"}
          [:div {:class "col-sm-12"}
           [:button {:type     "reset"
                     :class    "btn btn-default"
-                    :on-click #(dispatch [:state-current-note ""])} "Clear"]
+                    :on-click #(dispatch [:state-note :current-note ""])} "Clear"]
           [:button {:type     "submit"
                     :disabled (or @is-busy? (empty? @note))
                     :class    "btn btn-primary"
@@ -539,7 +538,7 @@
        (if (= :open (:status memory))
          [:a {:class    "btn btn-primary btn-xs"
               :on-click #(do
-                          (dispatch [:state-current-note (:thought memory)])
+                          (dispatch [:state-note :edit-note (:thought memory)])
                           (dispatch [:memory-edit-set memory]))}
           "Edit" [:i {:class "fa fa-pencil fa-space"}]])
        [:a {:class    "btn btn-primary btn-xs"
@@ -560,7 +559,7 @@

 (defn edit-memory []
   (let [edit-memory (subscribe [:note :edit-memory])
-        note        (subscribe [:note :current-note])
+        note        (subscribe [:note :edit-note])
         is-busy?    (subscribe [:ui-state :is-busy?])
         ;; On the next one, we can't use not-empty because (= nil (not-empty nil)), and :show expects true/false,
         ;; not a truth-ish value.
@@ -569,7 +568,7 @@
       [Modal {:show @show? :onHide #(dispatch [:memory-edit-set nil])}
        [ModalBody
         [:div {:class "col-sm-12 thought"}
-         [thought-edit-box]]]
+         [thought-edit-box :edit-note]]]
        [ModalFooter
         [:button {:type     "reset"
                   :class    "btn btn-default"


Add proper redirect for /

Add proper redirect for /

--- src/cljs/nesouri/core.cljs
+++ src/cljs/nesouri/core.cljs
@@ -27,6 +27,9 @@
       options {:target (. js/document (getElementById "app"))
                :state {:player-chan player-chan}}]

+  (sec/defroute index-page "/" []
+    (sec/dispatch! "/search"))
+
   (sec/defroute search-page "/search" []
     (om/root search-view app-state options))

@@ -48,5 +51,5 @@

 (let [current-hash (.. js/window -location -hash)]
   (if (empty? current-hash)
-    (sec/dispatch! "/search")
+    (sec/dispatch! "/")
     (sec/dispatch! (.substring current-hash 1))))


Tweak some docstrings.

Tweak some docstrings.

--- src/clojure/parkour/fs.clj
+++ src/clojure/parkour/fs.clj
@@ -118,7 +118,7 @@
             (into {})))))

 (defn path-open
-  "Open an input stream on `p`."
+  "Open an input stream on `p`, or default `fs` if not provided."
   ([p] (path-open (path-fs p) p))
   ([fs p] (.open ^FileSystem fs (path p))))

@@ -139,7 +139,7 @@
   "/tmp")

 (defn ^:private run-id
-  "A likely-unique user and time-based string."
+  "A likely-unique user- and time-based string."
   []
   (let [user (System/getProperty "user.name")
         time (System/currentTimeMillis)


Disable intermittently failing test

Disable intermittently failing test

--- test/eulalie/test/sns.cljc
+++ test/eulalie/test/sns.cljc
@@ -65,19 +65,20 @@
                        <?
                        (subs 0 4))))))))

-(deftest ^:integration ^:aws set-platform-application-attributes
-  (test.common/with-aws
-    (fn [creds]
-      (go-catching
-        (let [arn (<? (create-gcm-application! creds))]
-          (<? (sns! creds
-                    :set-platform-application-attributes
-                    {:platform-application-arn arn
-                     :attrs {:success-feedback-sample-rate 50}}))
-          (is (:success-feedback-sample-rate
-               (<? (sns! creds
-                         :get-platform-application-attributes
-                         {:platform-application-arn arn})))))))))
+;; This is failing on Travis, but not locally - investigate.
+;; (deftest ^:integration ^:aws set-platform-application-attributes
+;;   (test.common/with-aws
+;;     (fn [creds]
+;;       (go-catching
+;;         (let [arn (<? (create-gcm-application! creds))]
+;;           (<? (sns! creds
+;;                     :set-platform-application-attributes
+;;                     {:platform-application-arn arn
+;;                      :attrs {:success-feedback-sample-rate 50}}))
+;;           (is (:success-feedback-sample-rate
+;;                (<? (sns! creds
+;;                          :get-platform-application-attributes
+;;                          {:platform-application-arn arn})))))))))

 (deftest ^:integration ^:aws delete-platform-application+
   (test.common/with-aws


add missing test for dynamic store

add missing test for dynamic store

--- test/keypin/store_test.clj
+++ test/keypin/store_test.clj
@@ -49,8 +49,12 @@
       (is (thrown? TimeoutException
             (contains? fixed-store :foo)) "timed out waiting to update stale data")))
   (testing "Actualy dynamically fetched config"
-    ;; TODO
-    ))
+    (let [ds (ks/make-dynamic-store (fn [_] {:foo 10}) {:foo 20})]
+      (is (= 20 (get ds :foo)))
+      (Thread/sleep 1100)  ; wait for 1s refresh window to elapse
+      (get ds :foo)        ; trigger re-fetch
+      (Thread/sleep 100)   ; wait for fetch to happen
+      (is (= 10 (get ds :foo))))))

 (defmacro nanos


Add cname extension to copy impl.

Add cname extension to copy impl.

--- src/incise/parsers/impl/copy.clj
+++ src/incise/parsers/impl/copy.clj
@@ -12,4 +12,4 @@
     (copy input-file output-file)
     output-file))

-(pc/register [:copy] parse)
+(pc/register [:copy :cname] parse)


Redeploy module when deploy is called while already deployed

--- src/containium/modules.clj
+++ src/containium/modules.clj
@@ -132,11 +132,13 @@
                            (assoc % :state :undeployed))))))

+(declare handle-redeploy)
+
 (defn- handle-deploy
   [{:keys [name state] :as module} manager file promise]
   (case state
     :deploying (invalid-state module promise "already deploying.")
-    :deployed (invalid-state module promise "already deployed.")
+    :deployed (handle-redeploy module manager promise)
     :redeploying (invalid-state module promise "currently redeploying.")
     :swapping (invalid-state module promise "currently swapping.")
     :undeploying (invalid-state module promise "currently undeploying.")


(maint) correct typo in docstring

(maint) correct typo in docstring

--- src/puppetlabs/cthun/validation.clj
+++ src/puppetlabs/cthun/validation.clj
@@ -47,7 +47,7 @@
   {(s/required-key :query) [s/Str]})

 (def DestinationReport
-  "Defined the data field for a destination report body"
+  "Defines the data field for a destination report body"
   {:message MessageId
    :destination [Endpoint]})


en fixed 12am/12pm: 12 is ambiguous am/pm

--- src/duckling/time/pred.clj
+++ src/duckling/time/pred.clj
@@ -118,7 +118,7 @@
              (next (iterate #(t/minus % :day 7) anchor))])))

 (defn hour [h twelve-hour-clock?]
-  (fn& :hour [t _] (let [step (if (and twelve-hour-clock? (<= h 11))
+  (fn& :hour [t _] (let [step (if (and twelve-hour-clock? (<= h 12))
                           12
                           24)
                    diff (mod (- h (t/hour t)) step)


Tesco API has a bad cert, ignoring it

Tesco API has a bad cert, ignoring it

--- src/eatme/item_library.clj
+++ src/eatme/item_library.clj
@@ -27,7 +27,8 @@
      (:body (client/get tesco-api {:query-params (merge {:command (to-command command)
                                                          :sessionkey (:SessionKey @session)
                                                          :page 1} (app) params)
-                                   :as :json}))))
+                                   :as :json
+                                   :insecure? true}))))

 (defn login
   ([] (login user))


setting up dev project

setting up dev project

--- example/project.clj
+++ example/project.clj
@@ -27,12 +27,19 @@
                          :compiler { :output-to "resources/public/js/compiled/example.js"
                                      :output-dir "resources/public/js/compiled/out"
                                      :source-map true
+                                    :optimizations :none}}
+                       { :id "dev"
+                         :source-paths ["src" "../support/src"]
+                         :compiler { :output-to "resources/public/js/compiled/example.js"
+                                     :output-dir "resources/public/js/compiled/out"
+                                     :source-map true
                                      :optimizations :none}}]}

   :figwheel {
              :http-server-root "public" ;; default and assumes "resources"
              :server-port 3449 ;; default
              :css-dirs ["resources/public/css"]
+             :open-file-command "emacsclient"
              ;; if you want to embed a server in figwheel do it like so:
              #_:ring-handler #_example.server/handler
              })


:sparkles: Set enable as true by default on profiler component.

--- frontend/src/uxbox/util/perf.cljs
+++ frontend/src/uxbox/util/perf.cljs
@@ -57,7 +57,7 @@
   [props]
   (let [children (unchecked-get props "children")
         label    (unchecked-get props "label")
-        enabled? (unchecked-get props "enabled")
+        enabled? (or (unchecked-get props "enabled") true)
         on-render (mf/use-memo
                    (mf/deps label)
                    #(on-render-factory label))]


Problem title added to tweet text if it will fit

--- src/foreclojure/social.clj
+++ src/foreclojure/social.clj
@@ -36,6 +36,12 @@
        (or anchor-text "Twitter")
        "</a>"))

+(defn get-problem-title [id]
+  (:title
+   (fetch-one :problems
+	      :only [:title]
+	      :where {:_id id})))
+
 (defn gist!
   "Create a new gist containing a user's solution to a problem and
   return its url."
@@ -43,9 +49,7 @@
   (let [[user-name possessive] (if user-name
                                  [user-name "'s"]
                                  ["anonymous" nil])
-
-        {name :title} (fetch-one :problems
-                                 :where {:_id problem-num})
+	name (get-problem-title problem-num)
         filename (str user-name "-4clojure-solution" problem-num ".clj")
         text (str ";; " user-name possessive " solution to " name "\n"
                   ";; https://4clojure.com/problem/" problem-num
@@ -58,8 +62,12 @@
       (catch Throwable _))))

 (defn tweet-solution [id gist-url & [link-text]]
-  (let [status-msg (str "Check out how I solved problem #"
-                        id " on #4clojure " (clojure-hashtag) gist-url)]
+  (let [status-msg (str "Check out how I solved "
+                        (let [title (get-problem-title id)]
+			  (if (> (count title) 35)
+			    (str "problem " id)
+			    (str "\"" title "\"")))
+			" on #4clojure " (clojure-hashtag) gist-url)]
     (tweet-link id status-msg link-text)))

 (def-page share-page []


(PE-4308) Docstrings and schemas

(PE-4308) Docstrings and schemas

--- src/clj/puppetlabs/puppetserver/certificate_authority.clj
+++ src/clj/puppetlabs/puppetserver/certificate_authority.clj
@@ -56,15 +56,25 @@
    status endpoint for signing and revoking certificates."
   (schema/enum :signed :revoked))

+(def CertificateState
+  "The list of states a certificate may be in."
+  (schema/enum "requested" "signed" "revoked"))
+
 (def CertStatus
   "Various information about the state of a certificate or
    certificate request that is provided by the certificate
    status endpoint."
   {:name          schema/Str
-   :state         (schema/enum "requested" "signed" "revoked")
+   :state         CertificateState
    :dns_alt_names [schema/Str]
    :fingerprint   schema/Str
    :fingerprints  {schema/Keyword schema/Str}})
+
+(def Certificate
+  (schema/pred utils/certificate?))
+
+(def CertificateRequest
+  (schema/pred utils/certificate-request?))

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;; Definitions
@@ -171,14 +181,14 @@
     (str/join "\n" missing-files))))

 ; TODO - PE-5529 - these should be moved to jvm-c-a.
-(schema/defn get-subject :- String
-  [cert :- (schema/pred utils/certificate?)]
+(schema/defn get-subject :- schema/Str
+  [cert :- Certificate]
   (-> cert
       (.getSubjectX500Principal)
       (.getName)))

-(schema/defn get-csr-subject :- String
-  [csr :- (schema/pred utils/certificate-request?)]
+(schema/defn get-csr-subject :- schema/Str
+  [csr :- CertificateRequest]
   (-> csr
       (.getSubject)
       (.toString)
@@ -261,7 +271,7 @@
     * $NB = The 'not before' field of the cert, as a date/timestamp in UTC.
     * $NA = The 'not after' field of the cert, as a date/timestamp in UTC.
     * $S  = The distinguished name of the cert's subject."
-  [cert :- (schema/pred utils/certificate?)
+  [cert :- Certificate
    inventory-file :- schema/Str]
   (let [serial-number (->> cert
                            (.getSerialNumber)
@@ -479,7 +489,7 @@
    master-certname :- schema/Str
    ca-private-key :- (schema/pred utils/private-key?)
    ca-public-key :- (schema/pred utils/public-key?)
-   ca-cert :- (schema/pred utils/certificate?)
+   ca-cert :- Certificate
    keylength :- schema/Int
    serial-file :- schema/Str
    inventory-file :- schema/Str
@@ -659,14 +669,12 @@
         (whitelist-matches? autosign subject))
       false)))

-(defn create-agent-extensions
+(schema/defn create-agent-extensions :- (schema/pred utils/extension-list?)
   "Given a certificate signing request, generate a list of extensions that
   should be signed onto the certificate. This includes a base set of standard
   extensions in addition to any valid extensions found on the signing request."
-  [csr capub]
-  {:pre [(utils/certificate-request? csr)
-         (utils/public-key? capub)]
-   :post [(utils/extension-list? %)]}
+  [csr :- CertificateRequest
+   capub :- (schema/pred utils/public-key?)]
   (let [subj-pub-key (utils/get-public-key csr)
         csr-ext-list (utils/get-extensions csr)
         base-ext-list [(utils/netscape-comment
@@ -688,7 +696,7 @@
   "Given a subject name, their certificate request, and the CA settings
   from Puppet, auto-sign the request and write the certificate to disk."
   [subject :- schema/Str
-   csr :- (schema/pred utils/certificate-request?)
+   csr :- CertificateRequest
    {:keys [cacert capub cakey signeddir ca-ttl serial cert-inventory]} :- CaSettings]
   (let [validity    (cert-validity-dates ca-ttl)
         signed-cert (utils/sign-certificate (get-subject (utils/pem->cert cacert))
@@ -701,7 +709,7 @@
                                             (create-agent-extensions
                                              csr
                                              (utils/pem->public-key capub)))]
-    (log/debug (str "Signed certificate request for " subject))
+    (log/debug "Signed certificate request for" subject)
     (write-cert-to-inventory! signed-cert cert-inventory)
     (utils/cert->pem! signed-cert (path-to-cert signeddir subject))))

@@ -709,7 +717,7 @@
   save-certificate-request!
   "Write the subject's certificate request to disk under the CSR directory."
   [subject :- schema/Str
-   csr :- (schema/pred utils/certificate-request?)
+   csr :- CertificateRequest
    csrdir :- schema/Str]
   (utils/obj->pem! csr (path-to-cert-request csrdir subject)))

@@ -719,7 +727,7 @@
    The exception map will look like:
    {:type    :duplicate-cert
     :message <specific error message>}"
-  [csr :- (schema/pred utils/certificate-request?)
+  [csr :- CertificateRequest
    {:keys [allow-duplicate-certs cacrl csrdir signeddir]} :- CaSettings]
   (let [subject (get-csr-subject csr)
         cert (path-to-cert signeddir subject)
@@ -751,7 +759,7 @@
 (schema/defn validate-csr-signature!
   "Throws an exception when the CSR's signature is invalid.
   See `signature-valid?` for more detail."
-  [certificate-request :- (schema/pred utils/certificate-request?)]
+  [certificate-request :- CertificateRequest]
   (when-not (utils/signature-valid? certificate-request)
     (sling/throw+
       {:type    :invalid-signature
@@ -770,8 +778,8 @@
                        "` to sign this request.")}))))

 (schema/defn validate-csr!
-  "Perform all policy checks against the provided certificate signing request. "
-  [csr      :- (schema/pred utils/certificate-request?)
+  "Perform all policy checks against the provided certificate signing request."
+  [csr      :- CertificateRequest
    subject  :- schema/Str
    settings :- CaSettings]
   ; These validations must happen in this order
@@ -849,33 +857,38 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;; certificate_status endpoint

-;; TODO docs
-(defn certificate-state
-  [cert-or-csr cacrl]
+(schema/defn certificate-state :- CertificateState
+  "Determine the state a certificate is in."
+  [cert-or-csr :- (schema/either Certificate CertificateRequest)
+   cacrl :- schema/Str]
   (if (utils/certificate-request? cert-or-csr)
     "requested"
     (if (utils/revoked? (utils/pem->crl cacrl) cert-or-csr)
       "revoked"
       "signed")))

-;; TODO docs
-(defn dns-alt-names
-  [cert-or-csr]
+(schema/defn dns-alt-names :- [schema/Str]
+  "Get the list of DNS alt names on the provided certificate or CSR.
+   Each name will be prepended with 'DNS:'."
+  [cert-or-csr :- (schema/either Certificate CertificateRequest)]
   (mapv (partial str "DNS:")
         (utils/get-subject-dns-alt-names cert-or-csr)))

-;; TODO docs
-(defn fingerprint
-  [cert-or-csr algorithm]
+(schema/defn fingerprint :- schema/Str
+  "Calculate the hash of the certificate or CSR using the given
+   algorithm, which must be one of SHA-1, SHA-256, or SHA-512."
+  [cert-or-csr :- (schema/either Certificate CertificateRequest)
+   algorithm :- schema/Str]
   (->> (utils/fingerprint cert-or-csr algorithm)
        (partition 2)
        (map (partial apply str))
        (str/join ":")
        (str/upper-case)))

-;; TODO docs
-(schema/defn ^:always-validate
-  get-certificate-status :- CertStatus
+(schema/defn ^:always-validate get-certificate-status :- CertStatus
+  "Get the status of the subject's certificate or certificate request.
+   The status includes the state of the certificate (signed, revoked, requested),
+   DNS alt names, and several different fingerprint hashes of the certificate."
   [{:keys [csrdir signeddir cacrl]} :- CaSettings
    subject :- schema/Str]
   (let [cert-or-csr         (if (fs/exists? (path-to-cert signeddir subject))
@@ -891,9 +904,8 @@
                      :SHA512  (fingerprint cert-or-csr "SHA-512")
                      :default default-fingerprint}}))

-;; TODO docs
-(schema/defn ^:always-validate
-  get-certificate-statuses :- [CertStatus]
+(schema/defn ^:always-validate get-certificate-statuses :- [CertStatus]
+  "Get the status of all certificates and certificate requests."
   [{:keys [csrdir signeddir] :as settings} :- CaSettings]
   (let [path->subject #(let [name (.getName %)]
                          (.substring name 0 (- (count name) 4)))
@@ -903,8 +915,8 @@
                                    (fs/find-files signeddir pem-pattern)))]
     (map (partial get-certificate-status settings) all-subjects)))

-;; TODO docs
 (schema/defn sign-existing-csr!
+  "Sign the subject's certificate request."
   [{:keys [csrdir] :as settings} :- CaSettings
    subject :- schema/Str]
   (let [csr-path (path-to-cert-request csrdir subject)]
@@ -916,8 +928,9 @@
         (fs/delete csr-path)
         (log/debugf "Removed certificate request for %s at '%s'" subject csr-path)))))

-;; TODO docs
 (schema/defn revoke-existing-cert!
+  "Revoke the subject's certificate. Note this does not destroy the certificate.
+   The certificate will remain in the signed directory despite being revoked."
   [{:keys [signeddir cacrl cakey capub]} :- CaSettings
    subject :- schema/Str]
   (let [cert-path (path-to-cert signeddir subject)]
@@ -931,9 +944,8 @@
         (utils/crl->pem! new-crl cacrl)
         (log/debugf "Revoked %s certificate with serial %d" subject serial)))))

-; TODO docs
-(schema/defn ^:always-validate
-  set-certificate-status!
+(schema/defn ^:always-validate set-certificate-status!
+  "Sign or revoke the certificate for the given subject."
   [settings :- CaSettings
    subject :- schema/Str
    desired-state :- DesiredCertState]
@@ -941,18 +953,16 @@
     (sign-existing-csr! settings subject)
     (revoke-existing-cert! settings subject)))

-(schema/defn ^:always-validate
-  certificate-exists? :- schema/Bool
+(schema/defn ^:always-validate certificate-exists? :- schema/Bool
   "Do we have a CSR or certificate for the given subject?"
   [{:keys [csrdir signeddir]} :- CaSettings
    subject :- schema/Str]
   (or (fs/exists? (path-to-cert signeddir subject))
       (fs/exists? (path-to-cert-request csrdir subject))))

-;; TODO docs
-(schema/defn ^:always-validate
-  delete-certificate!
-  "Delete the certificate and/or CSR for the given subject."
+(schema/defn ^:always-validate delete-certificate!
+  "Delete the certificate and/or CSR for the given subject.
+   Note this does not revoke the certificate."
   [{:keys [csrdir signeddir]} :- CaSettings
    subject :- schema/Str]
   (let [cert (path-to-cert signeddir subject)


Fit lines in 80 char columns

Fit lines in 80 char columns

Signed-off-by: Njagi Mwaniki <b6a4ba60ad861b9c9afb6daea7294be4be68f44c@urbanslug.com>

--- src/hatti/views/table.cljs
+++ src/hatti/views/table.cljs
@@ -259,156 +259,156 @@
     (resizeColumns grid)
     [grid dataview]))

-;; EVENT LOOPS
-(defn handle-table-events
-  "Event loop for the table view. Processes a tap of share/event-chan,
+    ;; EVENT LOOPS
+    (defn handle-table-events
+      "Event loop for the table view. Processes a tap of share/event-chan,
    and updates app-state/dataview/grid as needed."
-  [app-state grid dataview]
-  (let [event-chan (shared/event-tap)]
-    (go
-      (while true
-        (let [{:keys [submission-to-rank
-                      submission-clicked
-                      submission-unclicked
-                      filter-by
-                      new-columns
-                      re-render]} (<! event-chan)
-              update-data! (partial om/update! app-state
-                                    [:table-page :submission-clicked :data])
-              get-submission-data (fn [field value]
-                                    (first
-                                     (filter #(= value (get % field))
-                                             (get-in @app-state [:data]))))]
-          (when submission-to-rank
-            (let [rank submission-to-rank
-                  submission (get-submission-data _rank rank)]
-              (update-data! submission)))
-          (when submission-clicked
-            (update-data! submission-clicked))
-          (when submission-unclicked
-            (update-data! nil))
-          (when new-columns
-            (.setColumns grid new-columns)
-            (resizeColumns grid)
-            (.render grid))
-          (when filter-by
-            (.setFilterArgs dataview (clj->js {:query filter-by}))
-            (.refresh dataview))
-          (when (= re-render :table)
-            ;; need tiny wait (~16ms requestAnimationFrame delay) to re-render
-            ;; table
-            (go (<! (timeout 20))
-                (.resizeCanvas grid)
-                (.invalidateAllRows grid)
+      [app-state grid dataview]
+      (let [event-chan (shared/event-tap)]
+        (go
+          (while true
+            (let [{:keys [submission-to-rank
+                          submission-clicked
+                          submission-unclicked
+                          filter-by
+                          new-columns
+                          re-render]} (<! event-chan)
+                  update-data! (partial om/update! app-state
+                                        [:table-page :submission-clicked :data])
+                  get-submission-data (fn [field value]
+                                        (first
+                                         (filter #(= value (get % field))
+                                                 (get-in @app-state [:data]))))]
+              (when submission-to-rank
+                (let [rank submission-to-rank
+                      submission (get-submission-data _rank rank)]
+                  (update-data! submission)))
+              (when submission-clicked
+                (update-data! submission-clicked))
+              (when submission-unclicked
+                (update-data! nil))
+              (when new-columns
+                (.setColumns grid new-columns)
                 (resizeColumns grid)
-                (.render grid)
-                (init-sg-pager grid dataview))))))))
-
-(defn- render-options
-  [options owner colset!]
-  (let [choose-display-key (fn [k] (om/set-state! owner :name-or-label k)
-                             (colset! k))]
-    (for [[k v] options]
-      [:li [:a {:on-click (click-fn #(choose-display-key k)) :href "#"} v]])))
-
-;; OM COMPONENTS
-(defmethod label-changer :default
-  [{{:keys [hide-actions-column?]} :table-page :as cursor} owner]
-  (reify
-    om/IInitState
-    (init-state [_] {:name-or-label :label})
-    om/IRenderState
-    (render-state [_ {:keys [name-or-label language]}]
-      (let [options {:label [:strong "Label"]
-                     :name  [:strong "Name"]}
-            {:keys [flat-form]} (om/get-shared owner)
-            new-language (:current (om/observe owner (shared/language-cursor)))
-            colset! #(put! shared/event-chan
-                           {:new-columns
-                            (flat-form->sg-columns
-                             flat-form
-                             :get-label? (= :label %)
-                             :hide-actions-column? hide-actions-column?
-                             :language new-language)})]
-        (when (not= new-language language)
-          (om/set-state! owner :language new-language)
-          (colset! name-or-label))
-        (html
-         [:div.label-changer
-          [:span.label-changer-label "Show:"]
-          [:div#header-display-dropdown.drop-hover
-           [:span (options name-or-label) [:i.fa.fa-angle-down]]
-           [:ul.submenu.no-dot (render-options options owner colset!)]]])))))
-
-(defn delayed-search
-  "Delayed search fires a query-event on event-chan if the value of the input
+                (.render grid))
+              (when filter-by
+                (.setFilterArgs dataview (clj->js {:query filter-by}))
+                (.refresh dataview))
+              (when (= re-render :table)
+                ;; need tiny wait (~16ms requestAnimationFrame delay) to re-render
+                ;; table
+                (go (<! (timeout 20))
+                    (.resizeCanvas grid)
+                    (.invalidateAllRows grid)
+                    (resizeColumns grid)
+                    (.render grid)
+                    (init-sg-pager grid dataview))))))))
+
+    (defn- render-options
+      [options owner colset!]
+      (let [choose-display-key (fn [k] (om/set-state! owner :name-or-label k)
+                                 (colset! k))]
+        (for [[k v] options]
+          [:li [:a {:on-click (click-fn #(choose-display-key k)) :href "#"} v]])))
+
+    ;; OM COMPONENTS
+    (defmethod label-changer :default
+      [{{:keys [hide-actions-column?]} :table-page :as cursor} owner]
+      (reify
+        om/IInitState
+        (init-state [_] {:name-or-label :label})
+        om/IRenderState
+        (render-state [_ {:keys [name-or-label language]}]
+          (let [options {:label [:strong "Label"]
+                         :name  [:strong "Name"]}
+                {:keys [flat-form]} (om/get-shared owner)
+                new-language (:current (om/observe owner (shared/language-cursor)))
+                colset! #(put! shared/event-chan
+                               {:new-columns
+                                (flat-form->sg-columns
+                                 flat-form
+                                 :get-label? (= :label %)
+                                 :hide-actions-column? hide-actions-column?
+                                 :language new-language)})]
+            (when (not= new-language language)
+              (om/set-state! owner :language new-language)
+              (colset! name-or-label))
+            (html
+             [:div.label-changer
+              [:span.label-changer-label "Show:"]
+              [:div#header-display-dropdown.drop-hover
+               [:span (options name-or-label) [:i.fa.fa-angle-down]]
+               [:ul.submenu.no-dot (render-options options owner colset!)]]])))))
+
+    (defn delayed-search
+      "Delayed search fires a query-event on event-chan if the value of the input
    doesn't change within 150 ms (ie, user is still typing).
    Call on-change or on-key-up, with (.-target event) as first argument."
-  [input query-event-key]
-  (let [query (.-value input)]
-    ;; Wait 150 ms for input value to stabilize. Empirically felt good, plus
-    ;; 200 ms wait is when people start noticing change in interfaces
-    (go (<! (timeout 150))
-        (when (= query (.-value input))
-          (put! shared/event-chan {query-event-key query})))))
-
-(defmethod table-search :default
-  [_ owner]
-  (om/component
-   (html
-    [:div.table-search
-     [:i.fa.fa-search]
-     [:input {:type "text"
-              :placeholder "Search"
-              :on-change #(delayed-search (.-target %) :filter-by)}]])))
-
-(defmethod table-header :default
-  [cursor owner]
-  (om/component
-   (html
-    [:div.topbar
-     [:div {:id pager-id}]
-     (om/build label-changer cursor)
-     (om/build table-search cursor)
-     [:div {:style {:clear "both"}}]])))
-
-(defn- init-grid!
-  "Initializes grid + dataview, and stores them in owner's state."
-  [data owner slick-grid-event-handlers]
-  (when (seq data)
-    (let [{:keys [flat-form is-filtered-dataview?]} (om/get-shared owner)
-          current-language (:current
-                            (om/observe owner (shared/language-cursor)))
-          [grid dataview] (sg-init data
-                                   flat-form
-                                   current-language
-                                   is-filtered-dataview?
-                                   owner
-                                   slick-grid-event-handlers)]
-      (om/set-state! owner :grid grid)
-      (om/set-state! owner :dataview dataview)
-      [grid dataview])))
-
-(defn get-table-view-height
-  []
-  (- (-> "body"
-         js/document.querySelector
-         .-clientHeight)
-     (-> ".tab-page"
-         js/document.querySelector
-         .getBoundingClientRect
-         .-top)))
-
-(defn set-window-resize-handler
-  [owner]
-  (let [resize-handler (fn [event]
-                         (om/set-state! owner
-                                        :table-view-height
-                                        (get-table-view-height)))]
-    (.addEventListener js/window
-                       "resize"
-                       resize-handler)
-    (om/set-state! owner :resize-handler resize-handler)))
+      [input query-event-key]
+      (let [query (.-value input)]
+        ;; Wait 150 ms for input value to stabilize. Empirically felt good, plus
+        ;; 200 ms wait is when people start noticing change in interfaces
+        (go (<! (timeout 150))
+            (when (= query (.-value input))
+              (put! shared/event-chan {query-event-key query})))))
+
+    (defmethod table-search :default
+      [_ owner]
+      (om/component
+       (html
+        [:div.table-search
+         [:i.fa.fa-search]
+         [:input {:type "text"
+                  :placeholder "Search"
+                  :on-change #(delayed-search (.-target %) :filter-by)}]])))
+
+    (defmethod table-header :default
+      [cursor owner]
+      (om/component
+       (html
+        [:div.topbar
+         [:div {:id pager-id}]
+         (om/build label-changer cursor)
+         (om/build table-search cursor)
+         [:div {:style {:clear "both"}}]])))
+
+    (defn- init-grid!
+      "Initializes grid + dataview, and stores them in owner's state."
+      [data owner slick-grid-event-handlers]
+      (when (seq data)
+        (let [{:keys [flat-form is-filtered-dataview?]} (om/get-shared owner)
+              current-language (:current
+                                (om/observe owner (shared/language-cursor)))
+              [grid dataview] (sg-init data
+                                       flat-form
+                                       current-language
+                                       is-filtered-dataview?
+                                       owner
+                                       slick-grid-event-handlers)]
+          (om/set-state! owner :grid grid)
+          (om/set-state! owner :dataview dataview)
+          [grid dataview])))
+
+    (defn get-table-view-height
+      []
+      (- (-> "body"
+             js/document.querySelector
+             .-clientHeight)
+         (-> ".tab-page"
+             js/document.querySelector
+             .getBoundingClientRect
+             .-top)))
+
+    (defn set-window-resize-handler
+      [owner]
+      (let [resize-handler (fn [event]
+                             (om/set-state! owner
+                                            :table-view-height
+                                            (get-table-view-height)))]
+        (.addEventListener js/window
+                           "resize"
+                           resize-handler)
+        (om/set-state! owner :resize-handler resize-handler)))

 (defmethod table-page :default
   [{{:keys [active]} :views :as cursor}
@@ -481,6 +481,7 @@
         (.removeEventListener js/window
                               "resize"
                               (om/get-state owner :resize-handler)))
+
       om/IWillReceiveProps
       (will-receive-props [_ next-props]
         "Reset SlickGrid data if the table data has changed."


add/revise captions for dart and cljs

add/revise captions for dart and cljs

--- src/solar_system_of_js/actions.cljs
+++ src/solar_system_of_js/actions.cljs
@@ -167,7 +167,7 @@

    ;; slide in the JS logo
    {:caption
-    "This is JavaScript, the default choice for modern web development, of course."
+    "This is JavaScript, the one and only programming language that today's browsers understand."
     [:js-face :x]   {:a :_ :b 0 :duration 1}
     [:title :alpha] {:a :_ :b 0 :duration 0.4}}

@@ -252,7 +252,10 @@
    ;; show module sys
    {:caption
     (str "And for proper dependency loading, we need extra module tools like"
-         " [Browserify](http://browserify.org/) or [RequireJS](http://requirejs.org/).")
+         " [Browserify](http://browserify.org/),"
+         " [webpack](http://webpack.github.io/),"
+         " [SystemJS](https://github.com/systemjs/systemjs),"
+         " [RequireJS](http://requirejs.org/), etc.")

     [:linter :highlight] false
     [:modulesys :highlight] true
@@ -329,7 +332,7 @@

    ;; fade out staticsphere details
    {:caption
-    "This is our simplified two-layer view of JS. We now leave the JS language for new worlds."
+    "There are also languages that are completely separate from JS, but still compile to it."
     [:static :typescript :alpha]  {:a :_ :b 0 :duration 1}
     [:static :flow :alpha]        {:a :_ :b 0 :duration 1}
     [:static :closure :alpha]     {:a :_ :b 0 :duration 1}
@@ -341,21 +344,23 @@

    ;; show coffeescript
    {:caption
-    "(to be continued...)"
+    "[CoffeeScript](http://coffeescript.org/) is separate from JS but remains close.  Its simpler syntax and idioms have influenced features in ES6."
     :enable-orbits? true
     [:radar :orbit] :coffeescript
     [:coffeescript :highlight] true
     [:coffeescript :alpha] {:a :_ :b 1 :duration 1}}

    ;; show dart
-   {
+   {:caption
+    "[Dart](https://www.dartlang.org/) is larger. It embraces OOP with optional typing, a large core library, and development tools."
     [:coffeescript :highlight] false
     [:dart :highlight] true
     [:radar :orbit] :dart
     [:dart :alpha] {:a :_ :b 1 :duration 1}}

    ;; show clojurescript
-   {
+   {:caption
+    "[ClojureScript](http://clojurescript.org) eschews traditional OO in favor of immutability, plain data, and a more expressive syntax."
     [:dart :highlight] false
     [:clojurescript :highlight] true
     [:clojurescript :angle] (- (/ PI 10))
@@ -365,6 +370,10 @@
     [:cam :y]               {:a :_ :b 0 :duration 1}
     [:cam :x]               {:a :_ :b 300 :duration 1}
     [:cam :zoom]            {:a :_ :b 0.15 :duration 1}}
+
+   ;; TODO: read about elm
+   ;; TODO: read about purescript
+
 ]))

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


Put generated files in target. Closes #22.

--- src/leiningen/protobuf.clj
+++ src/leiningen/protobuf.clj
@@ -20,6 +20,14 @@
   (java.net.URL.
    (format "http://protobuf.googlecode.com/files/protobuf-%s.zip"  version)))

+;; In lein 1 there was a :target-dir key that defaulted to "." and wasn't really
+;; used much. In lein 2, things that are generated by plugins and such are
+;; supposed to go in :target-path. This will default to 'target'. We don't want
+;; to wait for this, so we'll simulate it here.
+(defn target [project]
+  (doto (io/file (or (:target-path project) "target"))
+    .mkdirs))
+
 (defn- proto-dependencies
   "look for lines starting with import in proto-file"
   [proto-file]
@@ -33,6 +41,7 @@
     (when-not (empty? files)
       (let [proto (peek files)
             files (pop files)]
+        ;; TODO Somehow check for :proto-path too?
         (if (or (.exists (io/file "proto" proto))
                 (.exists (io/file target "proto" proto)))
           (recur files)
@@ -69,7 +78,7 @@
 (defn fetch
   "Fetch protocol-buffer source and unzip it."
   [project]
-  (let [target (:target-dir project)]
+  (let [target (target project)]
     (when-not (.exists (io/file target srcdir))
       (let [zipped (io/file target zipfile)]
         (println "Downloading" zipfile)
@@ -84,7 +93,7 @@
   (when (installed?)
     (let [password (read-pass)
           proc (sh/proc "sudo" "-S" "make" "uninstall"
-                        :dir (io/file (:target-dir project) srcdir))]
+                        :dir (io/file (target project) srcdir))]
       (sh/feed-from-string proc (str password "\n"))
       (sh/stream-to-out proc :out))))

@@ -93,7 +102,7 @@
   [project]
   (when-not (installed?)
     (fetch project)
-    (let [source (io/file (:target-dir project) srcdir)]
+    (let [source (io/file (target project) srcdir)]
       (when-not (.exists (io/file source "src" "protoc"))
         (fs/chmod "+x" (io/file source "configure"))
         (fs/chmod "+x" (io/file source "install-sh"))
@@ -115,18 +124,20 @@
 (defn protoc
   "Create .java and .class files from the provided .proto files."
   ([project protos]
-     (protoc project protos (io/file (:target-dir project) "protosrc")))
+     (protoc project protos (io/file (target project) "protosrc")))
   ([project protos dest]
-     (let [target (:target-dir project)
+     (let [target (target project)
+           dest (.getAbsoluteFile dest)
            dest-path (.getPath dest)
-           proto-path (or (:proto-path project) "proto")]
+           proto-path (.getAbsoluteFile (io/file (or (:proto-path project) "proto")))]
        (when (or (> (modtime proto-path) (modtime dest))
                  (> (modtime proto-path) (modtime "classes")))
          (.mkdirs dest)
-         (.mkdir (io/file target "proto"))
+         (.mkdirs proto-path)
          (doseq [proto protos]
            (extract-dependencies (io/file proto-path proto) target)
-           (let [args ["protoc" proto (str "--java_out=" dest-path) "-I." (str "-I" target proto-path)]]
+           (let [args ["protoc" proto (str "--java_out=" dest-path) "-I."
+                       (str "-I" proto-path)]]
              (println " > " (join " " args))
              (let [protoc-result (apply sh/proc (concat args [:dir proto-path]))]
                (if (not (= (sh/exit-code protoc-result) 0))
@@ -138,7 +149,7 @@
   "Compile com.google.protobuf.*"
   [project]
   (let [proto-files (io/file "proto/google/protobuf")
-        target (:target-dir project)]
+        target (target project)]
     (.mkdirs proto-files)
     (io/copy (io/file target srcdir "src/google/protobuf/descriptor.proto")
              (io/file proto-files "descriptor.proto"))


cleanup

cleanup

--- solutions/day07/solution.clj
+++ solutions/day07/solution.clj
@@ -35,12 +35,11 @@
     (loop [[switch & more] switches
            circuit init-circuit]
       (if switch
-        (if (circuit (:target switch))
-          (recur more circuit)
-          (let [inputs ((:inputs switch) circuit)]
-            (if (every? (complement nil?) inputs)
-              (recur more (assoc circuit (:target switch) (apply (:fn switch) inputs)))
-              (recur (conj (vec more) switch) circuit))))
+        (let [inputs ((:inputs switch) circuit)]
+          (if (not-any? nil? inputs)
+            (recur more (assoc circuit (:target switch) (apply (:fn switch) inputs)))
+            ; inputs for this switch aren't set, so put it at the end of the list and keep going
+            (recur (conj (vec more) switch) circuit)))
         circuit))))

 (defn part1
@@ -49,7 +48,9 @@

 (defn part2
   [switches init-circuit]
-  ((switches->circuit switches init-circuit) "a"))
+  (let [set-switches (set (keys init-circuit))
+        switches (filter #(not (set-switches (:target %))) switches)]
+    ((switches->circuit switches init-circuit) "a")))

 (println "part 1:" (part1 switches))
 (println "part 2:" (part2 switches {"b" (part1 switches)}))


uses thrown-with-msg? instead of thrown? in unit tests (#1099)

--- waiter/test/waiter/service_description_test.clj
+++ waiter/test/waiter/service_description_test.clj
@@ -2358,22 +2358,24 @@
       (is (nil? (validate builder
                           (assoc basic-service-description "namespace" "*")
                           validation-settings)))
-      (is (thrown? Exception #"Cannot use run-as-requester with a specific namespace"
-                   (validate builder
-                             (assoc basic-service-description
-                               "namespace" "some-user")
-                             validation-settings))))
+      (is (thrown-with-msg?
+            Exception #"Service namespace must either be omitted or match the run-as-user"
+            (validate builder
+                      (assoc basic-service-description
+                        "namespace" "some-user")
+                      validation-settings))))

     (testing "validate-service-description-namespace-some-user"
       (is (nil? (validate builder some-user-service-description validation-settings)))
       (is (nil? (validate builder
                           (assoc some-user-service-description "namespace" "some-user")
                           validation-settings)))
-      (is (thrown? Exception #"Service namespace must either be omitted or match the run-as-user"
-                   (validate builder
-                             (assoc basic-service-description
-                               "namespace" "some-other-user")
-                             validation-settings))))))
+      (is (thrown-with-msg?
+            Exception #"Service namespace must either be omitted or match the run-as-user"
+            (validate builder
+                      (assoc basic-service-description
+                        "namespace" "some-other-user")
+                      validation-settings))))))

 (deftest test-retrieve-most-recently-modified-token
   (testing "all tokens have last-update-time"


More memory improvements across the board.


Make the logger cljs-devtools friendly

Make the logger cljs-devtools friendly

--- env/dev/cljs/clchess/dev.cljs
+++ env/dev/cljs/clchess/dev.cljs
@@ -5,22 +5,77 @@
             [re-frisk.core :refer [enable-re-frisk!]]
             [devtools.core :as devtools]))

+
+(defn console-appender-devtools
+  "Returns a simple js/console appender for ClojureScript.
+
+  For accurate line numbers in Chrome, add these Blackbox[1] patterns:
+    `/taoensso/timbre/appenders/core\\.js$`
+    `/taoensso/timbre\\.js$`
+    `/cljs/core\\.js$`
+
+  [1] Ref. https://goo.gl/ZejSvR"
+
+  ;; TODO Any way of using something like `Function.prototype.bind`
+  ;; (Ref. https://goo.gl/IZzkQB) to get accurate line numbers in all
+  ;; browsers w/o the need for Blackboxing?
+
+  [& [opts]]
+  {:enabled?   true
+   :async?     false
+   :min-level  nil
+   :rate-limit nil
+   :output-fn  :inherit
+   :fn
+   (if (exists? js/console)
+     (let [;; Don't cache this; some libs dynamically replace js/console
+           level->logger
+           (fn [level]
+             (or
+               (case level
+                 :trace  js/console.trace
+                 :debug  js/console.debug
+                 :info   js/console.info
+                 :warn   js/console.warn
+                 :error  js/console.error
+                 :fatal  js/console.error
+                 :report js/console.info)
+               js/console.log))]
+
+       (fn [data]
+         (when-let [logger (level->logger (:level data))]
+           (let [output
+                 ((:output-fn data)
+                  (assoc data
+                         :msg_  ""
+                         :?err nil))
+                 ;; (<output> <raw-error> <raw-arg1> <raw-arg2> ...):
+                 args (->> (:vargs data) ;; (cons (:?err data))
+                           (cons output))]
+
+             (.apply logger js/console (into-array args))))))
+
+     (fn [data] nil))})
+
 (defn setup-dev-environment
   []
   (log/debug "Setup dev enviroment")
-  (log/merge-config! {:ns-whitelist [#_"clchess.core"
-                                     "clchess.board"
-                                     "clchess.events"
-                                     "clchess.subs"
-                                     #_"clchess.theme"
-                                     "clchess.db"
-                                     #_"clchess.views"
-                                     #_"clchess.widgets"
-                                     "clchess.events-common"
-                                     #_"clchess.board"
-                                     #_"scid.*"
-                                     #_"clchess.node_subs"
-                                     "clchess.ctrl"]})
+  (log/set-config! {:ns-whitelist [#_"clchess.core"
+                                   "clchess.board"
+                                   "clchess.events"
+                                   "clchess.subs"
+                                   #_"clchess.theme"
+                                   "clchess.dev"
+                                   "clchess.db"
+                                   #_"clchess.views"
+                                   #_"clchess.widgets"
+                                   "clchess.events-common"
+                                   #_"clchess.board"
+                                   #_"scid.*"
+                                   #_"clchess.node_subs"
+                                   "clchess.ctrl"]
+                    :appenders
+                    {:console-appender-devtools (console-appender-devtools)}})
   (log/set-level! :debug)
   (figwheel/watch-and-reload
    :websocket-url "ws://localhost:3449/figwheel-ws"


Exclude our names as org slugs to avoid email from conflict.

--- src/oc/storage/resources/org.clj
+++ src/oc/storage/resources/org.clj
@@ -40,6 +40,8 @@

 ;; ----- Organization Slug -----

+;; Excluded slugs due to existing and potential URL routing conflicts
+;; the person names are excluded because right now we're sending update emails as from: "slug@opencompany.com"
 (def reserved-slugs #{"about" "android" "api" "app" "careers" "companies"
                       "company" "contact" "create-company" "crowd" "developer"
                       "developers" "download" "email-confirmation" "faq" "forum" "forums"
@@ -48,7 +50,7 @@
                       "news" "newsletter" "press" "privacy" "profile" "register" "reset"
                       "section" "sections" "signin" "signout" "signup" "stakeholder"
                       "stakeholder-update" "subscription-completed" "terms" "topic" "topics"
-                      "update" "updates"})
+                      "update" "updates" "stuart" "sean" "iacopo"})

 (declare list-orgs)
 (defn taken-slugs


Comment for future.

Comment for future.

--- src/onyx/messaging/netty_tcp.clj
+++ src/onyx/messaging/netty_tcp.clj
@@ -227,6 +227,7 @@
             (.channel channel)
             (.handler (client-channel-initializer (new-client-handler))))
         ch-fut ^ChannelFuture (.awaitUninterruptibly (.connect b host port)
+                                                     ;; TODO, add connection timeout
                                                      ;(:onyx.messaging.netty/connect-timeout-millis defaults)
                                                      ;TimeUnit/MILLISECONDS
                                                      )


Check upstream for heartbeats and eviction after polling subscriber during recovery.

--- src/onyx/peer/task_lifecycle.clj
+++ src/onyx/peer/task_lifecycle.clj
@@ -146,14 +146,16 @@

 (defn check-upstream-heartbeats [state liveness-timeout-ns]
   (let [curr-time (System/nanoTime)]
-    (->> (sub/status-pubs (m/subscriber (get-messenger state)))
-         (filter (fn [[peer-id spub]]
-                   (< (+ (status-pub/get-heartbeat spub)
-                         liveness-timeout-ns)
-                      curr-time)))
-         (map key)
-         (reduce evict-peer! state)
-         (advance))))
+    (->> state
+         (get-messenger)
+         (m/subscriber)
+         (sub/status-pubs)
+         (sequence (comp (filter (fn [[peer-id spub]]
+                                   (< (+ (status-pub/get-heartbeat spub)
+                                         liveness-timeout-ns)
+                                      curr-time)))
+                         (map key)))
+         (reduce evict-peer! state))))

 (defn offer-heartbeats [state]
   (advance (heartbeat! state)))
@@ -336,8 +338,8 @@
         input-pipeline (get-input-pipeline state)]
     (when-not recovered?
       (let [event (get-event state)
-            stored (res/recover-input event recover-coordinates)
-            _ (info (:onyx.core/log-prefix event) "Recover pipeline checkpoint:" stored)]
+            stored (res/recover-input event recover-coordinates)]
+        (info (:onyx.core/log-prefix event) "Recover pipeline checkpoint:" stored)
         (p/recover! input-pipeline (t/replica-version state) stored)))
     (if (p/synced? input-pipeline (t/epoch state))
       (-> state
@@ -367,8 +369,8 @@
       (let [event (get-event state)
             ;; output recovery is only supported with onyx/n-peers set
             ;; as we can't currently scale slot recovery up and down
-            stored (res/recover-output event recover-coordinates)
-            _ (info (:onyx.core/log-prefix event) "Recover output pipeline checkpoint:" stored)]
+            stored (res/recover-output event recover-coordinates)]
+        (info (:onyx.core/log-prefix event) "Recover output pipeline checkpoint:" stored)
         (p/recover! pipeline (t/replica-version state) stored)))
     (if (p/synced? pipeline (t/epoch state))
       (-> state
@@ -377,10 +379,19 @@
       ;; ensure we don't try to recover output again before synced
       (set-context! state (assoc context :recovered? true)))))

+(defn event->pub-liveness [event]
+  (ms->ns (arg-or-default :onyx.peer/publisher-liveness-timeout-ms
+                          (:onyx.core/peer-opts event))))
+
+(defn poll-recover-check-upstream [state]
+  (let [timeout (event->pub-liveness (get-event state))]
+    (check-upstream-heartbeats state timeout)))
+
 (defn poll-recover-input-function [state]
   (let [messenger (get-messenger state)
-        subscriber (m/subscriber messenger)
-        _ (sub/poll! subscriber)]
+        subscriber (m/subscriber messenger)]
+    (sub/poll! subscriber)
+    (poll-recover-check-upstream state)
     (if (and (sub/blocked? subscriber)
              (sub/recovered? subscriber))
       (-> state
@@ -395,8 +406,9 @@
       state)))

 (defn poll-recover-output [state]
-  (let [subscriber (m/subscriber (get-messenger state))
-        _ (sub/poll! subscriber)]
+  (let [subscriber (m/subscriber (get-messenger state))]
+    (sub/poll! subscriber)
+    (poll-recover-check-upstream state)
     (if (and (sub/blocked? subscriber)
              (sub/recovered? subscriber))
       (-> state
@@ -488,10 +500,6 @@
                transform/apply-fn-single)]
     (fn [state]
       (transform/apply-fn a-fn f state))))
-
-(defn event->pub-liveness [event]
-  (ms->ns (arg-or-default :onyx.peer/publisher-liveness-timeout-ms
-                          (:onyx.core/peer-opts event))))

 (def state-fn-builders
   {:recover [{:lifecycle :lifecycle/poll-recover
@@ -518,7 +526,7 @@
               {:lifecycle :lifecycle/check-publisher-heartbeats
                :builder (fn [event]
                           (let [timeout (event->pub-liveness event)]
-                            (fn [state] (check-upstream-heartbeats state timeout))))}
+                            (fn [state] (advance (check-upstream-heartbeats state timeout)))))}
               {:lifecycle :lifecycle/seal-barriers?
                :builder (fn [_] input-function-seal-barriers?)}
               {:lifecycle :lifecycle/seal-barriers?
@@ -547,7 +555,7 @@
                    {:lifecycle :lifecycle/check-publisher-heartbeats
                     :builder (fn [event]
                                (let [timeout (event->pub-liveness event)]
-                                 (fn [state] (check-upstream-heartbeats state timeout))))}
+                                 (fn [state] (advance (check-upstream-heartbeats state timeout)))))}
                    {:lifecycle :lifecycle/after-read-batch
                     :builder (fn [event] (build-lifecycle-invoke-fn event :lifecycle/after-read-batch))}
                    {:lifecycle :lifecycle/apply-fn


:var is defined to be clojure.lang.Var not Symbol

--- src/oxcart/passes/tree_shake.clj
+++ src/oxcart/passes/tree_shake.clj
@@ -20,7 +20,7 @@

 (defn reach-set
-  "λ AST → #{Symbol}
+  "λ AST → #{Var}

   Computes the var reach set of an AST"
   [source]


Improve pprint-ns

Improve pprint-ns

When referring many symbols in a prefixed libspec all symbols were
printed on the same line.

--- src/refactor_nrepl/ns/pprint.clj
+++ src/refactor_nrepl/ns/pprint.clj
@@ -14,7 +14,7 @@
                   (if (= idx (dec (count libspecs)))
                     (printf "%s]\n" libspec)
                     (if (sequential? libspec)
-                      (println libspec)
+                      (pprint libspec)
                       (if (= idx 0)
                         (printf " %s " libspec)
                         (if (sequential? (nth libspecs (inc idx)))


RS & AB | #0 | wrap-ssl-redirect in a slightly different way

--- src/objective8/core.clj
+++ src/objective8/core.clj
@@ -102,10 +102,9 @@
       (wrap-xss-protection true {:mode :block})
       (wrap-frame-options :sameorigin)

-      ((if (config/get-var "ENABLE_HTTPS_ONLY")
+      (#(if (config/get-var "ENABLE_HTTPS_ONLY")
          wrap-ssl-redirect
-         identity
-         ))))
+         %))))

 (defonce server (atom nil))
 (defonce scheduler (atom nil))


Add LOC and SHA achievements.

Add LOC and SHA achievements.

--- src-clj/acha/achievement.clj
+++ src-clj/acha/achievement.clj
@@ -113,7 +113,48 @@
          {:username author
           :time time})))])

-; TODO date achievement
+; sha achievements
+(defn make-sha-scanner [achievement-id sha-predicate]
+  [achievement-id
+   (fn [{:keys [id author time]}]
+     (when (sha-predicate id)
+       {:username author
+        :time time}))])
+
+(def lucky
+  (make-sha-scanner
+    :lucky
+    #(.contains % "777")))
+
+(def mark-of-the-beast
+  (make-sha-scanner
+    :mark-of-the-beast
+    #(.contains sha "666")))
+
+; LOC achievements
+(defn make-loc-scanner [achievement-id loc-predicate]
+  [achievement-id
+   (fn [{:keys [loc author time]}]
+     (when (loc-predicate loc)
+       {:username author
+        :time time}))])
+
+(def world-balance
+  (make-loc-scanner
+    :world-balance
+    (fn [loc] (= (:added loc) (:deleted loc)))))
+
+(def eraser
+  (make-loc-scanner
+    :eraser
+    (fn [loc] (nil? (:added loc)))))
+
+(def massive
+  (make-loc-scanner
+    :massive
+    (fn [loc] (>= (:added loc) 1000))))
+
+; TODO date achievements
 (def professional-pride
   [:professional-pride
    (fn [commit-info]
@@ -136,14 +177,6 @@
      nil)])

 ; TODO diff achievements
-(def eraser
-  [:eraser
-   (fn [commit-info]
-     nil)])
-(def massive
-  [:massive
-   (fn [commit-info]
-     nil)])
 (def easy-fix
   [:easy-fix
    (fn [commit-info]
@@ -152,24 +185,7 @@
   [:mover
    (fn [commit-info]
      nil)])
-(def world-balance
-  [:world-balance
-   (fn [commit-info]
-     nil)])
-
-; TODO sha achievements
-(def lucky
-  [:lucky
-   (fn [commit-info]
-     nil)])
-(def mark-of-the-beast
-  [:mark-of-the-beast
-   (fn [commit-info]
-     nil)])
-(def commit-get
-  [:commit-get
-   (fn [timeline]
-     nil)])
+

 ; TODO commit-info achievements
 (def borat
@@ -288,6 +304,10 @@
      nil)])
 (def goodboy
   [:goodboy
+   (fn [timeline]
+     nil)])
+(def commit-get
+  [:commit-get
    (fn [timeline]
      nil)])


Make frames/skip-duplicates totally lazy

--- src/asciinema/player/frames.cljs
+++ src/asciinema/player/frames.cljs
@@ -70,8 +70,9 @@
 (defn skip-duplicates
   "Returns frames with subsequent duplicate frames removed."
   [frames]
-  (let [[_ v1 :as f1] (first frames)]
-    (cons f1 (skip-duplicates* v1 (next frames)))))
+  (lazy-seq
+   (let [[_ v1 :as f1] (first frames)]
+     (cons f1 (skip-duplicates* v1 (next frames))))))

 (defn at-hz
   "Returns frames at requested frame rate (hz)."


Require commons from lemur.core.test

Require commons from lemur.core.test

--- src/test/clj/lemur/core_test.clj
+++ src/test/clj/lemur/core_test.clj
@@ -17,6 +17,7 @@
     lemur.core
     [lemur.command-line :only [quit]]
     [lemur.evaluating-map :only [evaluating-map]]
+    [lemur.common :only [eoval]]
     midje.sweet
     clojure.test
     lemur.test)


Fix "Stream closed" issue with pod pools (fixes #270)

--- boot/pod/src/boot/pod.clj
+++ boot/pod/src/boot/pod.clj
@@ -239,7 +239,9 @@

 (defn require-in
   [pod ns]
-  (doto pod (.require (into-array String [(str ns)]))))
+  (doto pod
+    (with-eval-in
+      (require '~(symbol (str ns))))))

 (defn canonical-coord
   [[id & more :as coord]]


(PE-3864) delete unused import and require

--- src/clj/puppetlabs/master/certificate_authority.clj
+++ src/clj/puppetlabs/master/certificate_authority.clj
@@ -1,8 +1,7 @@
 (ns puppetlabs.master.certificate-authority
   (:import [org.apache.commons.io IOUtils]
            [java.util Date]
-           [java.io InputStream ByteArrayOutputStream ByteArrayInputStream]
-           [com.puppetlabs.certificate_authority])
+           [java.io InputStream ByteArrayOutputStream ByteArrayInputStream])
   (:require [me.raynes.fs :as fs]
             [schema.core :as schema]
             [clojure.string :as str]
@@ -14,8 +13,7 @@
             [clj-time.coerce :as time-coerce]
             [slingshot.slingshot :as sling]
             [puppetlabs.kitchensink.core :as ks]
-            [puppetlabs.certificate-authority.core :as utils]
-            [clojure.string :as string]))
+            [puppetlabs.certificate-authority.core :as utils]))

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;; Schemas
@@ -623,7 +621,7 @@
       (let [bad-extension-oids (map :oid bad-extensions)]
         (sling/throw+ {:type    :disallowed-extension
                        :message (str "CSR has request extensions that are not permitted: "
-                                     (string/join ", " bad-extension-oids))})))))
+                                     (str/join ", " bad-extension-oids))})))))

 (schema/defn validate-csr-subject!
   "Validate the CSR subject name.  The subject name must:


add bindings completable-future test

add bindings completable-future test

--- test/com/climate/claypoole_test.clj
+++ test/com/climate/claypoole_test.clj
@@ -25,6 +25,7 @@
      ExecutorService
      LinkedBlockingQueue]))

+(def ^:dynamic *test-context* nil)

 (defn callable
   "Just a cast."
@@ -785,6 +786,14 @@
                 (range 10))]
         (is (= @f (range 10)))
         (is (true? @a)))))
+  (testing "bindings completable-future test"
+    (cp/with-shutdown! [pool 3]
+      (binding [*test-context* ::bound-value]
+        (let [f (cp/completable-future
+                  pool
+                  ;; Body can contain multiple elements.
+                  *test-context*)]
+          (is (= @f ::bound-value))))))
   (testing "completable-future threadpool args"
     (is (thrown? IllegalArgumentException (cp/completable-future 3 (inc 1))))
     (is (thrown? IllegalArgumentException (cp/completable-future nil (inc 1))))


add detail to response spy middleware

add detail to response spy middleware

--- src/clj/clj_money/web/server.clj
+++ src/clj/clj_money/web/server.clj
@@ -248,6 +248,7 @@
   [handler]
   (fn [request]
     (let [response (handler request)]
+      (log/debug "response to " (:uri request))
       (log/spy response)
       response)))


show both card titles when Mr. Li draws 2 copies of same card

--- src/clj/game/cards-resources.clj
+++ src/clj/game/cards-resources.clj
@@ -347,7 +347,7 @@
                                          (:title (first (:deck runner)))) ["OK"] {}))}}}
    "Mr. Li"
    {:abilities [{:cost [:click 1] :prompt "Card to keep?"
-                 :choices (req (take 2 (:deck runner))) :msg "choose 1 card to draw"
+                 :choices (req (take 2 (:deck runner))) :not-distinct true :msg "choose 1 card to draw"
                  :effect (req (move state side target :hand)
                               (if (= target (first (:deck runner)))
                                 (move state side (second (:deck runner)) :deck)


Reproduce nashorn error... take two...

Reproduce nashorn error... take two...

--- src/clj_simple_chart/hornexp.clj
+++ src/clj_simple_chart/hornexp.clj
@@ -14,4 +14,14 @@
 (def font-bytes (FileUtils/readFileToByteArray (File. "./resources/fonts/Roboto-Black.ttf")))
 (.eval engine (str "var base64 = '" (String. (base64/encode-bytes font-bytes)) "';"))
 (.eval engine "var ab = b64.decode(base64);")
-(.eval engine "var font = opentype.parse(ab);") ;;; doesn't work
+;(.eval engine "var font = opentype.parse(ab);") ;;; doesn't work
+
+(.eval engine "
+function uint32(x) {
+  var buffer = new ArrayBuffer(8);
+  var dataview = new DataView(buffer);
+  dataview.setUint32(0, x);
+  return dataview.getUint32(0, false);
+}
+print(uint32(0x5F0F3CF5) === uint32(0x5F0F3CF5));
+")


Renamed variables to something more sensible.

These variable names were taken from the original Node.js prototype and were
based upon incorrectly annotated UMM-Var data (which had also been flipped, X
for Y). This change brings the variable names in line with what the UMM-Var
dimensions should be.

--- src/cmr/opendap/ous/variable.clj
+++ src/cmr/opendap/ous/variable.clj
@@ -55,10 +55,10 @@
 (def default-lat-lo -90.0)
 (def default-lat-hi 90.0)

-(def default-x-lo 0.0)
-(def default-x-hi 360.0)
-(def default-y-lo 0.0)
-(def default-y-hi 180.0)
+(def default-lon-abs-lo 0.0)
+(def default-lon-abs-hi 360.0)
+(def default-lat-abs-lo 0.0)
+(def default-lat-abs-hi 180.0)

 (def default-stride 1)

@@ -261,8 +261,8 @@
   ;;     for now, we're just gonna pretend ... by changing the order
   ;;     below :-(
   ;; XXX This is being tracked in CMR-4958
-  [(or (:Size (first (filter #(= "YDim" (:Name %)) dim))) default-x-hi)
-   (or (:Size (first (filter #(= "XDim" (:Name %)) dim))) default-y-hi)])
+  [(or (:Size (first (filter #(= "YDim" (:Name %)) dim))) default-lon-abs-hi)
+   (or (:Size (first (filter #(= "XDim" (:Name %)) dim))) default-lat-abs-hi)])

 (defn extract-dimensions
   [entry]
@@ -303,7 +303,7 @@

 (defn create-opendap-bounds
   ([bounding-box]
-   (create-opendap-bounds {:x default-x-hi :y default-y-hi} bounding-box))
+   (create-opendap-bounds {:x default-lon-abs-hi :y default-lat-abs-hi} bounding-box))
   ([{x-dim :x y-dim :y} [lon-lo lat-lo lon-hi lat-hi :as bounding-box]]
    (if bounding-box
      (let [x-lo (lon-lo-phase-shift x-dim lon-lo)