Remove unecessary restriction to `Job`s.

--- src/clojure/parkour/mapreduce.clj
+++ src/clojure/parkour/mapreduce.clj
@@ -95,23 +95,23 @@
   (print-method (conf/diff job) w))

 (defn mapper!
-  "Allocate and return a new parkour mapper class for `job` as invoking `var`.
+  "Allocate and return a new parkour mapper class for `conf` as invoking `var`.
 The `var` will be called during task-setup with the job Configuration and any
 provided `args` (which must be EDN-serializable).  It should return a function
 of one argument, which will be invoked with the task context, and should perform
 the desired content of the map task."
-  [^Job job var & args]
-  (let [i (conf/get-int job "parkour.mapper.next" 0)]
-    (conf/assoc! job
+  [conf var & args]
+  (let [i (conf/get-int conf "parkour.mapper.next" 0)]
+    (conf/assoc! conf
       "parkour.mapper.next" (inc i)
       (format "parkour.mapper.%d.var" i) (pr-str var)
       (format "parkour.mapper.%d.args" i) (pr-str args))
     (Class/forName (format "parkour.hadoop.Mappers$_%d" i))))

 (defn ^:private reducer!*
-  [step ^Job job var & args]
-  (let [i (conf/get-int job "parkour.reducer.next" 0)]
-    (conf/assoc! job
+  [step conf var & args]
+  (let [i (conf/get-int conf "parkour.reducer.next" 0)]
+    (conf/assoc! conf
       "parkour.reducer.next" (inc i)
       (format "parkour.reducer.%d.step" i) (name step)
       (format "parkour.reducer.%d.var" i) (pr-str var)
@@ -119,30 +119,30 @@
     (Class/forName (format "parkour.hadoop.Reducers$_%d" i))))

 (defn reducer!
-  "Allocate and return a new parkour reducer class for `job` as invoking `var`.
+  "Allocate and return a new parkour reducer class for `conf` as invoking `var`.
 The `var` will be called during task-setup with the job Configuration and any
 provided `args` (which must be EDN-serializable).  It should return a function
 of one argument, which will be invoked with the task context, and should perform
 the desired content of the reduce task."
-  [^Job job var & args]
-  (apply reducer!* :reduce job var args))
+  [conf var & args]
+  (apply reducer!* :reduce conf var args))

 (defn combiner!
   "As per `reducer!`, but allocate and configure for the Hadoop combine step,
 which may impact e.g. output types."
-  [^Job job var & args]
-  (apply reducer!* :combine job var args))
+  [conf var & args]
+  (apply reducer!* :combine conf var args))

 (defn partitioner!
-  "Allocate and return a new parkour partitioner class for `job` as invoking
+  "Allocate and return a new parkour partitioner class for `conf` as invoking
 `var`.  The `var` will be called during task-setup with the job Configuration
 and any provided `args` (which must be EDN-serializable).  It should return a
 function of three arguments: a map-output key, a map-output value, and an
 integral reduce-task count.  That function will called for each map-output
 tuple, and should return an integral value mod the reduce-task count.  Should be
 primitive-hinted as OOLL."
-  [^Job job var & args]
-  (conf/assoc! job
+  [conf var & args]
+  (conf/assoc! conf
     "parkour.partitioner.var" (pr-str var)
     "parkour.partitioner.args" (pr-str args))
   parkour.hadoop.Partitioner)


clear api token from the post-api handler

--- frontend/controllers/api.cljs
+++ frontend/controllers/api.cljs
@@ -511,15 +511,11 @@
   [target message status {:keys [resp context]} state]
   (update-in state state/user-path assoc :heroku_api_key (:heroku_api_key resp)))

-(defmethod api-event [:create-api-token :failed]
-  [target message status {:keys [resp context]} state]
-  ;; XXX-ResponseText Don't drop the resp text on the floor here,
-  ;; should be shown to the user
-  state)
-
 (defmethod api-event [:create-api-token :success]
   [target message status {:keys [resp context]} state]
-  (update-in state state/user-tokens-path conj resp))
+  (-> state
+      (assoc-in state/new-user-token-path "")
+      (update-in state/user-tokens-path conj resp)))

 (defmethod api-event [:delete-api-token :failed]
   [target message status {:keys [resp context]} state]


allow unbalanced backticks

allow unbalanced backticks

--- src/chat/client/views/helpers.cljs
+++ src/chat/client/views/helpers.cljs
@@ -75,11 +75,15 @@
           block-type (volatile! nil)
           in-code (volatile! [])]
       (fn
-        ([] (xf))
-        ([result] (xf result))
+        ([]  (xf))
+        ([result] (if (= @state ::in-code)
+                    (let [prefix (if (= @block-type :block) "```" "`")]
+                      (reduce xf result (update-in @in-code [0] (partial str prefix))))
+                    (xf result)))
         ([result input]
          (if (string? input)
            (cond
+             ; TODO: handle starting code block with backtick not at beginning of word
              ; start multiline
              (and (= @state ::start) (.startsWith input "```"))
              (do (vreset! state ::in-code)


Encoding

Encoding

--- src/clj/algorithms_clj/huffman.clj
+++ src/clj/algorithms_clj/huffman.clj
@@ -61,9 +61,10 @@
   [huffman-tree values]
   (reduce #(get-bits huffman-tree %2 %1) [] values))

-#_(defn encode
-   [values]
-   (encode-with (make-tree values) values))
+(defn encode
+  "Encode a stream, using the stream frequences to build the huffman tree"
+  [values]
+  (encode-with (make-tree (frequencies values)) values))

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


remove TODO

remove TODO

--- src/clj/backtype/storm/cluster.clj
+++ src/clj/backtype/storm/cluster.clj
@@ -327,7 +327,6 @@
       (remove-storm! [this storm-id]
         (delete-node cluster-state (storm-task-root storm-id))
         (delete-node cluster-state (assignment-path storm-id))
-        ;; TODO: this might be a problem... originally this was the first thing
         (remove-storm-base! this storm-id))

       (report-task-error [this storm-id task-id error]


loading? removed

loading? removed

--- src/clj/om_next_leaflet/parser.clj
+++ src/clj/om_next_leaflet/parser.clj
@@ -27,10 +27,6 @@
                    (map (fn [{:keys [id line-name bounding-box geometry]}] [id line-name bounding-box geometry])))]
     {:value value}))

-(defmethod readf :loading?
-  [_ _ _]
-  {:value false})
-
 (defmulti mutatef om/dispatch)

 (defmethod mutatef 'app/update-title


Fix tenancy id key

Fix tenancy id key

--- src/clj/onyx_dashboard/tenancy.clj
+++ src/clj/onyx_dashboard/tenancy.clj
@@ -139,7 +139,7 @@
                  (stop-tracking! user-id)
                  (assoc user-id (component/start
                                   (new-track-tenancy-manager send-fn!
-                                                             (assoc peer-config :onyx/tenancyid deployment-id)
+                                                             (assoc peer-config :onyx/tenancy-id deployment-id)
                                                              user-id
                                                              tracking-id))))))
     (catch Throwable t


Fix numberpad duplicating numbers and keypresses

--- src/clj/robinson/swingterminal.clj
+++ src/clj/robinson/swingterminal.clj
@@ -151,35 +151,60 @@
           keyListener      (reify KeyListener
                              (keyPressed [this e]
                                ;(println "keyPressed keyCode" (.getKeyCode e) "escape" KeyEvent/VK_ESCAPE "escape?" (= (.getKeyCode e) KeyEvent/VK_ESCAPE))
-                               (when-let [k (cond
-                                              (= (.getKeyCode e) KeyEvent/VK_ENTER)      :enter
-                                              (= (.getKeyCode e) KeyEvent/VK_ESCAPE)     :escape
-                                              (= (.getKeyCode e) KeyEvent/VK_SPACE)      :space
-                                              (= (.getKeyCode e) KeyEvent/VK_BACK_SPACE) :backspace
-                                              (= (.getKeyCode e) KeyEvent/VK_NUMPAD1)    :numpad1
-                                              (= (.getKeyCode e) KeyEvent/VK_NUMPAD2)    :numpad2
-                                              (= (.getKeyCode e) KeyEvent/VK_NUMPAD3)    :numpad3
-                                              (= (.getKeyCode e) KeyEvent/VK_NUMPAD4)    :numpad4
-                                              (= (.getKeyCode e) KeyEvent/VK_NUMPAD5)    :numpad5
-                                              (= (.getKeyCode e) KeyEvent/VK_NUMPAD6)    :numpad6
-                                              (= (.getKeyCode e) KeyEvent/VK_NUMPAD7)    :numpad7
-                                              (= (.getKeyCode e) KeyEvent/VK_NUMPAD8)    :numpad8
-                                              (= (.getKeyCode e) KeyEvent/VK_NUMPAD9)    :numpad9
-                                              true (let [altDown (not= (bit-and (.getModifiersEx e) InputEvent/ALT_DOWN_MASK) 0)
-                                                         ctrlDown (not= (bit-and (.getModifiersEx e) InputEvent/CTRL_DOWN_MASK) 0)]
-                                                     ;(println "processing non-enter non-escape keypress")
-                                                     (when (and altDown ctrlDown (<= \A (.getKeyCode e) \Z))
-                                                       (.toLowerCase (char (.getKeyCode e))))))]
-
-                                 (on-key-fn k)))
+                               (let [numpad? (= (.getKeyLocation e) KeyEvent/KEY_LOCATION_NUMPAD)]
+                                 (when-let [k (cond
+                                                (= (.getKeyCode e) KeyEvent/VK_ENTER)      :enter
+                                                (= (.getKeyCode e) KeyEvent/VK_ESCAPE)     :escape
+                                                (= (.getKeyCode e) KeyEvent/VK_SPACE)      :space
+                                                (= (.getKeyCode e) KeyEvent/VK_BACK_SPACE) :backspace
+                                                (and numpad?
+                                                     (= (.getKeyCode e) KeyEvent/VK_NUMPAD1))    :numpad1
+                                                (and numpad?
+                                                     (= (.getKeyCode e) KeyEvent/VK_NUMPAD2))    :numpad2
+                                                (and numpad?
+                                                     (= (.getKeyCode e) KeyEvent/VK_NUMPAD3))    :numpad3
+                                                (and numpad?
+                                                     (= (.getKeyCode e) KeyEvent/VK_NUMPAD4))    :numpad4
+                                                (and numpad?
+                                                     (= (.getKeyCode e) KeyEvent/VK_NUMPAD5))    :numpad5
+                                                (and numpad?
+                                                     (= (.getKeyCode e) KeyEvent/VK_NUMPAD6))    :numpad6
+                                                (and numpad?
+                                                     (= (.getKeyCode e) KeyEvent/VK_NUMPAD7))    :numpad7
+                                                (and numpad?
+                                                     (= (.getKeyCode e) KeyEvent/VK_NUMPAD8))    :numpad8
+                                                (and numpad?
+                                                     (= (.getKeyCode e) KeyEvent/VK_NUMPAD9))    :numpad9
+                                                (contains? #{KeyEvent/VK_0
+                                                             KeyEvent/VK_1
+                                                             KeyEvent/VK_2
+                                                             KeyEvent/VK_3
+                                                             KeyEvent/VK_4
+                                                             KeyEvent/VK_5
+                                                             KeyEvent/VK_6
+                                                             KeyEvent/VK_7
+                                                             KeyEvent/VK_8
+                                                             KeyEvent/VK_9}
+                                                           (.getKeyCode e))
+                                                  (char (.getKeyCode e))
+                                                #_#_true (let [altDown (not= (bit-and (.getModifiersEx e) InputEvent/ALT_DOWN_MASK) 0)
+                                                           ctrlDown (not= (bit-and (.getModifiersEx e) InputEvent/CTRL_DOWN_MASK) 0)]
+                                                       ;(println "processing non-enter non-escape keypress")
+                                                       (when (and altDown ctrlDown (<= \A (.getKeyCode e) \Z))
+                                                         (.toLowerCase (char (.getKeyCode e))))))]
+
+                                   (info "KeyPressed" k e)
+                                   (on-key-fn k))))
                              (keyReleased [this keyEvent]
                                nil)
                              (keyTyped [this e]
                                (let [character (.getKeyChar e)
+                                     numpad?   (= (.getKeyLocation e) KeyEvent/KEY_LOCATION_NUMPAD)
                                      altDown   (not= (bit-and (.getModifiersEx e) InputEvent/ALT_DOWN_MASK) 0)
                                      ctrlDown  (not= (bit-and (.getModifiersEx e) InputEvent/CTRL_DOWN_MASK) 0)
                                      ignore    #{(char 10) (char 33) (char 27)}]
-                                 (when-not (contains? ignore character)
+                                 (when (and (re-matches #"[ -~]" (str character))
+                                            (not (re-matches #"[0-9]" (str character))))
                                    (if ctrlDown
                                        (on-key-fn (char (+ (int \a) -1 (int character))))
                                        (on-key-fn character))))))


Capture more AWS metadata exceptions

Capture more AWS metadata exceptions

--- src/clj/runbld/hosting/aws_ec2.clj
+++ src/clj/runbld/hosting/aws_ec2.clj
@@ -21,7 +21,10 @@
      (http/get (str "http://169.254.169.254/latest/meta-data" postfix)
                {:socket-timeout 500 :conn-timeout 500}))
     (catch org.apache.http.conn.ConnectTimeoutException _)
-    (catch java.net.ConnectException _))))
+    (catch java.net.ConnectException _)
+    ;; Non-AWS Windows
+    (catch java.net.SocketException _)
+    (catch java.net.UnknownHostException _))))

 (s/defn this-host? :- s/Bool
   "Is this host in AWS EC2?"


back and forward switch to queue, fix monad error in back

--- src/cljc/western_music/lib/ui.cljc
+++ src/cljc/western_music/lib/ui.cljc
@@ -175,12 +175,14 @@
 (def player-at-beginning? (comp zero? player-index))

 (defn player-back [{q :player/queue paused? :player/paused :as p}]
-  (cond-> p
+  (cond-> (m/return p)
+    true (m/fmap assoc :player/selected-tab :queue)
     (not (player-at-beginning? p)) (m/bind player-set-playing (q (dec (player-index p))) paused?)))

 (defn player-forward
   [{q :player/queue paused? :player/paused :as p}]
   (cond-> (m/return p)
+    true (m/fmap assoc :player/selected-tab :queue)
     (not (player-at-end? p)) (m/bind player-set-playing (q (inc (player-index p))) paused?)))

 (defn currently-playing? [player track-id]


Formatting

Formatting

--- src/cljs/learn_specter/routes.cljs
+++ src/cljs/learn_specter/routes.cljs
@@ -4,8 +4,8 @@
             [pushy.core :as pushy]))

 (def routes
-  ["" {""                    :index
-       ["/page/" [long :id]] :page}])
+  ["/" {""                   :index
+        ["page/" [long :id]] :page}])

 (defn- dispatch-route [match]
   (case (:handler match)


Convert a little more messaging logging (WIP)

This is failing the handshake test almost instantly: when I try to send
the child-> signal, the state is missing its ::outbound key.

--- src/clojure/frereth_cp/message.clj
+++ src/clojure/frereth_cp/message.clj
@@ -252,6 +252,7 @@
                                    ::specs/message-loop-name message-loop-name}))]
     (deliver accepted? true)
     (let [state' (callback state)]
+      (assert (::specs/outgoing state') "Callback threw away outgoing")
       ;; TODO: check whether we can do output now.
       ;; It's pointless to call this if we just have
       ;; to wait for the timer to expire.
@@ -560,7 +561,8 @@
                            ::log2/state]))
 (defn choose-next-scheduled-time
   [{{:keys [::specs/n-sec-per-block
-            ::specs/rtt-timeout]} ::specs/flow-control
+            ::specs/rtt-timeout]
+     :as flow-control} ::specs/flow-control
     {:keys [::specs/->child-buffer
             ::specs/gap-buffer]} ::specs/incoming
     {:keys [::specs/earliest-time
@@ -575,6 +577,11 @@
     log-state ::log2/state
     :as state}
    to-child-done?]
+  {:pre [state
+         outgoing
+         last-block-time
+         flow-control
+         n-sec-per-block]}
   ;;; This amounts to lines 286-305

   ;; I should be able to just completely bypass this if there's
@@ -745,6 +752,10 @@
      ::log2/state log-state}))

 (declare schedule-next-timeout!)
+(s/fdef action-trigger
+        :args (s/cat :io-handle ::specs/io-handle
+                     :state ::specs/state)
+        :ret any?)
 (defn action-trigger
   [{:keys [::actual-next
            ::delta_f
@@ -752,7 +763,8 @@
     :as timing-details}
    {:keys [::specs/message-loop-name]
     :as io-handle}
-   {log-state ::log2/state
+   {:keys [::specs/outgoing]
+    log-state ::log2/state
     :as state}
    ;; This is a variant that consists of a [tag callback] pair
    ;; It's tempting to destructure this here.
@@ -769,7 +781,8 @@
    ;; then destructure args later. But that makes
    ;; it less obviously a win.
    success]
-  (let [now (System/nanoTime)
+  {:pre [outgoing]}
+  (let [now (System/currentTimeMillis)
         prelog (utils/pre-log message-loop-name)  ; might be on a different thread
         fmt (str "Awakening event loop that was sleeping for ~g ms "
                  "after ~:d at ~:d\n"
@@ -802,7 +815,8 @@
                              ::scheduling-time scheduling-time
                              ::actual-next actual-next
                              ::now now
-                             ::success success}))
+                             ::success success
+                             ::trigger-details prelog}))
           (catch NumberFormatException ex
             (log2/exception log-state
                             ex
@@ -812,7 +826,8 @@
                              ::scheduling-time scheduling-time
                              ::actual-next actual-next
                              ::now now
-                             ::success success})))
+                             ::success success
+                             ::trigger-details prelog})))
         [tag
          log-state] (try [(first success) log-state]
                          (catch IllegalArgumentException ex
@@ -820,7 +835,8 @@
                             (log2/exception log-state
                                             ex
                                             ::action-trigger
-                                            "Should have been a variant")]))
+                                            "Should have been a variant"
+                                            {::trigger-details prelog})]))
         ;; TODO: Really should add something like a transaction ID to the state
         ;; to assist in tracing the action
         updater
@@ -828,23 +844,27 @@
         (case tag
           ::specs/child-> (let [[_ callback ack] success]
                             (partial trigger-from-child io-handle callback ack))
-          ::drained (do (throw (RuntimeException. "Start back here, after I've checked handshake test"))
-                        (log/warn prelog
-                                  ;; Actually, this seems like a strong argument for
-                                  ;; having a pair of streams. Child could still have
-                                  ;; bytes to send to the parent after the latter's
-                                  ;; stopped sending, or vice versa.
-                                  ;; I'm pretty sure the complexity I haven't finished
-                                  ;; translating stems from that case.
-                                  ;; TODO: Another piece to revisit once the basics
-                                  ;; work.
-                                  "Stream closed. Surely there's more to do")
-                        (constantly nil))
+          ::drained (fn [{log-state ::log2/state
+                          :as state}]
+                      ;; Actually, this seems like a strong argument for
+                      ;; having a pair of streams. Child could still have
+                      ;; bytes to send to the parent after the latter's
+                      ;; stopped sending, or vice versa.
+                      ;; I'm pretty sure the complexity I haven't finished
+                      ;; translating stems from that case.
+                      ;; TODO: Another piece to revisit once the basics
+                      ;; work.
+                      (update state
+                              ::log2/state
+                              #(log2/warn %
+                                          ::action-trigger
+                                          "Stream closed. Surely there's more to do"
+                                          {::trigger-details prelog})))
           ::parent-> (partial trigger-from-parent
                               io-handle
                               (second success))
           ::no-op identity
-          ;; This can throw off the timer, since we're basic the delay on
+          ;; This can throw off the timer, since we're basing the delay on
           ;; the delta from recent (which doesn't change) rather than now.
           ;; But we're basing the actual delay from now, which does change.
           ;; e.g. If the scheduled delay is 980 ms, and someone triggers a
@@ -852,102 +872,117 @@
           ;; still be 980 ms rather than the 940 that would have been
           ;; appropriate.
           ;; Q: What's the best way to avoid this?
+          ;; Updating recent seems obvious, but also dubious.
+          ;; Decrementing the delay seems like something the scheduler
+          ;; should handle.
           ::query-state (fn [state]
                           (if-let [dst (second success)]
-                            (deliver dst state)
-                            (log/warn prelog "state-query request missing required deferred"))
-                          state)
-          ::timed-out (do
-                        (log/debug prelog
-                                   (cl-format nil
-                                              "Timer for ~:d ms after ~:d timed out. Re-triggering Output"
-                                              delta_f
-                                              scheduling-time))
-                        (partial trigger-from-timer io-handle)))]
-    (when (not= tag ::drained)
-      (log/debug prelog "Processing event:" tag)
-      ;; At the end of the main ioloop in the refernce
-      ;; implementation, there's a block that closes the pipe
-      ;; to the child if we're done.
-      ;; I think the point is that we'll quit polling on
-      ;; that and start short-circuiting out of the blocks
-      ;; that might do the send, once we've hit EOF
-      ;; Q: What can I do here to
-      ;; produce the same effect?
-      ;; TODO: Worry about that once the basic idea works.
-
-      ;; If the child sent a big batch of data to go out
-      ;; all at once, don't waste time setting up a timeout
-      ;; scheduler. The poll in the original would have
-      ;; returned immediately anyway.
-      ;; Except that n-sec-per-block puts a hard limit on how
-      ;; fast we can send.
-      (let [start (System/nanoTime)
-            ;; TODO: Break these pieces into something
-            ;; like the interceptor-chain idea. They should
-            ;; return a value that includes a key for a
-            ;; seq of functions to run to perform the
-            ;; side-effects.
-            ;; I'd still have to call updater, get
-            ;; that updating seq, and update the state
-            ;; to recurse.
-
-            ;; I'd prefer to do these next two
-            ;; pieces in a single step.
-
-            ;; TODO: Read up on Executors. I could wind up
-            ;; with really nasty interactions now that I
-            ;; don't have an agent to keep this single-
-            ;; threaded.
-            ;; Actually, it should be safe as written.
-            ;; Just be sure to keep everything synchronized
-            ;; around takes from the i/o handle. (Not
-            ;; needing to do that manually is
-            ;; a great reason to not introduce a second
-            ;; one for bytes travelling the other direction)
-            state' (try (updater state)
-                        (catch ExceptionInfo ex
-                          (log/error ex
-                                     (str
-                                      prelog
-                                      "Running updater failed.\nDetails:\n"
-                                      (.getData ex))))
-                        (catch RuntimeException ex
-                          (log/error ex
-                                     prelog
-                                     "Running updater failed")
-                          ;; The eternal question in this scenario:
-                          ;; Fail fast, or hope we can keep limping
-                          ;; along?
-                          ;; TODO: Add prod vs. dev environment options
-                          ;; to give the caller control over what
-                          ;; should happen here.
-                          ;; (Note that, either way, it really should
-                          ;; include a callback to some
-                          ;; currently-undefined status updater
-                          (comment state)))
-            state' (update state'
-                           ::log2/state
-                           #(log2/flush-logs! (::log2/logger io-handle) %))
-            mid (System/nanoTime)
-            ;; This is taking a ludicrous amount of time.
-            ;; Q: How much should I blame on logging?
-            _ (schedule-next-timeout! io-handle state')
-            end (System/nanoTime)]
-        ;; FIXME: This needs to change to new logging system.
-        ;; Although, really, that's more trouble than it's worth.
-        ;; I'd have to fork the logs to send one half to schedule-next-timeout!
-        ;; and then flush this again.
-        ;; Better to fix my scheduling mismatch and just ditch my initial approach.
-        (log/debug prelog
-                   (cl-format nil
-                              (str
-                               "Handling ~a event took ~:d nanoseconds\n"
-                               "Scheduling next timeout took ~:d  nanoseconds")
-                              tag
-                              (- mid start)
-                              (- end mid)))
-        nil))))
+                            (do
+                              (deliver dst state)
+                              state)
+                            (update state
+                                    ::log2/state
+                                    #(log2/warn %
+                                                ::action-trigger
+                                                "state-query request missing required deferred"
+                                                {::trigger-details prelog}))))
+          ::timed-out (fn [state]
+                        (trigger-from-timer io-handle
+                                            (update state
+                                                    ::log2/state
+                                                    #(log2/debug %
+                                                                 "Re-triggering Output due to timeot"
+                                                                 (assoc timing-details
+                                                                        ::trigger-details prelog))))))
+        state (update state
+                        ::log2/state
+                        #(log2/debug %
+                                     ::action-trigger
+                                     "Processing event"
+                                     {::tag tag}))
+          ;; At the end of the main ioloop in the reference
+          ;; implementation, there's a block that closes the pipe
+          ;; to the child if we're done.
+          ;; I think the point is that we'll quit polling on
+          ;; that and start short-circuiting out of the blocks
+          ;; that might do the send, once we've hit EOF
+          ;; Q: What can I do here to
+          ;; produce the same effect?
+          ;; TODO: Worry about that once the basic idea works.
+
+          ;; If the child sent a big batch of data to go out
+          ;; all at once, don't waste time setting up a timeout
+          ;; scheduler. The poll in the original would have
+          ;; returned immediately anyway.
+          ;; Except that n-sec-per-block puts a hard limit on how
+          ;; fast we can send.
+          start (System/currentTimeMillis)
+          ;; TODO: Break these pieces into something
+          ;; like the interceptor-chain idea. They should
+          ;; return a value that includes a key for a
+          ;; seq of functions to run to perform the
+          ;; side-effects.
+          ;; I'd still have to call updater, get
+          ;; that updating seq, and update the state
+          ;; to recurse.
+
+          ;; I'd prefer to do these next two
+          ;; pieces in a single step.
+
+          ;; TODO: Read up on Executors. I could wind up
+          ;; with really nasty interactions now that I
+          ;; don't have an agent to keep this single-
+          ;; threaded.
+          ;; Actually, it should be safe as written.
+          ;; Just be sure to keep everything synchronized
+          ;; around takes from the i/o handle. (Not
+          ;; needing to do that manually is
+          ;; a great reason to not introduce a second
+          ;; one for bytes travelling the other direction)
+
+          state' (try (updater state)
+                      (catch ExceptionInfo ex
+                        (update state
+                                ::log2/state
+                                #(log2/exception %
+                                                 ex
+                                                 ::action-trigger
+                                                 "Running updater failed"
+                                                 {::details (.getData ex)})))
+                      (catch RuntimeException ex
+                        ;; The eternal question in this scenario:
+                        ;; Fail fast, or hope we can keep limping
+                        ;; along?
+                        ;; TODO: Add prod vs. dev environment options
+                        ;; to give the caller control over what
+                        ;; should happen here.
+                        ;; (Note that, either way, it really should
+                        ;; include a callback to some
+                        ;; currently-undefined status updater
+                        (comment state)
+                        (update state
+                                ::log2/state
+                                #(log2/exception %
+                                                 ex
+                                                 ::action-trigger
+                                                 "Running updater: low-level failure"))))
+        _ (assert (::specs/outgoing state') (str "After updating for " tag))
+        [my-logs forked-logs] (log2/fork (::log2/state state') ::schedule-next-timeout!)
+        mid (System/currentTimeMillis)
+        ;; This is taking a ludicrous amount of time.
+        ;; Q: How much should I blame on logging?
+        _ (schedule-next-timeout! io-handle (assoc state'
+                                                   ::log2/state
+                                                   forked-logs))
+        end (System/currentTimeMillis)]
+    (log2/flush-logs! (::log2/logger io-handle)
+                      (log2/debug  my-logs
+                                   ::action-trigger
+                                   "Handled a triggered action"
+                                   {::tag tag
+                                    ::handling-ms (- mid start)
+                                    ::rescheduling-ms (- end mid)})))
+  nil)

 (comment
   (let [delta_f ##Inf,
@@ -994,7 +1029,8 @@
 ;;; it takes me back to Square One in terms of
 ;;; handling the timer. But it's tempting.
 (defn schedule-next-timeout!
-  [{:keys [::specs/->parent
+  [{:keys [::log2/logger
+           ::specs/->parent
            ::specs/child-output-loop
            ::specs/child-input-loop
            ::specs/to-child
@@ -1006,18 +1042,23 @@
     {:keys [::specs/receive-eof
             ::specs/receive-total-bytes
             ::specs/receive-written]} ::specs/incoming
-    {:keys [::specs/send-eof-acked]} ::specs/outgoing
+    {:keys [::specs/send-eof-acked]
+     :as outgoing} ::specs/outgoing
     log-state ::log2/state
     :as state}]
-  {:pre [recent]}
+  {:pre [recent
+         outgoing]}
+  ;; This really keeps going with the "queue up side-effects" idea
   (let [{{:keys [::specs/next-action]
           :as flow-control} ::specs/flow-control} state
-        prelog (utils/pre-log message-loop-name)
-        now (System/nanoTime)]
-    (log/debug prelog
-               (cl-format nil
-                          "Top of scheduler at ~:d"
-                          now))
+        ;; Note that the caller called this shortly before.
+        ;; So calling it again this quickly seems like
+        ;; a waste of ~30-ish nanoseconds.
+        now (System/nanoTime)
+        log-state (log2/debug log-state
+                              ::schedule-next-timeout!
+                              "Top of scheduler"
+                              {::now now})]
     (if (not (strm/closed? stream))
       (let [{actual-next ::next-action-time
              log-state ::log2/state}
@@ -1041,15 +1082,18 @@
                                         ::specs/receive-written receive-written
                                         ::specs/receive-total-bytes receive-total-bytes
                                         ::specs/send-eof-acked send-eof-acked})}
-              (choose-next-scheduled-time state to-child-done?))
+              (choose-next-scheduled-time (assoc state
+                                                 ::log2/state
+                                                 log-state)
+                                          to-child-done?))
             {:keys [::delta_f
-                    ::next-action]}
+                    ::next-action
+                    ::log2/state]}
             (if actual-next
               ;; TODO: add an optional debugging step that stores state and the
               ;; calculated time so I can just look at exactly what I have
               ;; when everything goes sideways
-              (let [
-                    ;; It seems like it would make more sense to have the delay happen from
+              (let [;; It seems like it would make more sense to have the delay happen from
                     ;; "now" instead of "recent"
                     ;; Doing that throws lots of sand into the gears.
                     ;; Stick with this approach for now, because it *does*
@@ -1066,44 +1110,50 @@
                             0
                             (inc (utils/nanos->millis delta-nanos)))
                     ;; For printing
-                    delta_f (float delta)]
-                (log/debug prelog
-                           (cl-format nil
-                                      (str "Initially calculated scheduled delay: ~:d nanoseconds after ~:d vs. ~:d"
-                                           "\nSetting timer to trigger in ~:d ms (vs ~:d scheduled) on ~a")
-                                      (long scheduled-delay)
-                                      recent
-                                      now
-                                      delta_f
-                                      (float (utils/nanos->millis scheduled-delay))
-                                      stream))
+                    delta_f (float delta)
+                    log-state (log2/debug log-state
+                                          ::schedule-next-timeout!
+                                          "Setting timer to trigger after an initially calculated scheduled delay"
+                                          {::scheduled-delay scheduled-delay  ; Q: Convert to long?
+                                           ::specs/recent recent
+                                           ::now now
+                                           ::actual-delay delta_f
+                                           ::delay-in-millis (float (utils/nanos->millis scheduled-delay))
+                                           ::stream stream})]
                 {::delta_f delta_f
-                 ::next-action (strm/try-take! stream [::drained] delta_f [::timed-out])})
+                 ::next-action (strm/try-take! stream [::drained] delta_f [::timed-out])
+                 ::log2/state log-state})
               ;; The i/o portion of this loop is finished.
               ;; But we still need to wait on the caller to close the underlying stream.
               ;; If nothing else, it may still want/need to query state.
               {::delta_f ##Inf
-               ::next-action (strm/take! stream [::drained])})]
+               ::next-action (strm/take! stream [::drained])
+               ::log2/state log-state})
+            ;; Since this is recursive, forking logs seems like a bad idea
+            [my-logs forked-logs] (log2/fork log-state ::forked)]
         (dfrd/on-realized next-action
                           (partial action-trigger
                                    {::actual-next actual-next
                                     ::delta_f delta_f
                                     ::scheduling-time now}
                                    io-handle
-                                   state)
+                                   (assoc state ::log2/state forked-logs))
                           (fn [failure]
-                            (log/error failure
-                                       prelog
-                                       (cl-format nil
-                                                  "~a: Waiting on some I/O to happen in timeout ~:d ms after ~:d"
-                                                  delta_f
-                                                  now))
+                            (log2/flush-logs! logger
+                                              (log2/error forked-logs
+                                                          ::schedule-next-timeout!
+                                                          "Waiting on some I/O to happen in timeout"
+                                                          {::actual-delay delta_f
+                                                           ::now now}))
                             ;; We don't have any business doing this here, but the
                             ;; alternatives don't seem appealing.
                             ;; Well, we could recurse manually without a scheduled
                             ;; time.
                             (strm/close! stream))))
-      (log/warn prelog "I/O Handle closed"))
+      (log2/flush-logs! logger
+                        (log2/warn log-state
+                                   ::schedule-next-timeout!
+                                   "I/O Handle closed")))
     ;; Don't rely on the return value of a function called for side-effects
     nil))


Use a better way to reload namespaces

Use a better way to reload namespaces

--- src/clojure/nightcode/builders.clj
+++ src/clojure/nightcode/builders.clj
@@ -44,15 +44,11 @@
   [console path timestamp]
   (let [source-paths (-> (lein/read-project-clj path)
                          (lein/stale-clojure-sources timestamp))
-        contents (for [source-path source-paths]
-                   (slurp source-path))
-        names (for [source-path source-paths]
-                (.getName (io/file source-path)))]
-    (->> (format "(do %s\n\"%s\")"
-                 (clojure.string/join "\n" contents)
+        commands (map #(format "(load-file \"%s\")" %) source-paths)
+        names (map #(.getName (io/file %)) source-paths)]
+    (->> (format "(do %s \"%s\")"
+                 (clojure.string/join " " commands)
                  (clojure.string/join ", " names))
-         read-string
-         pr-str
          (.enterLine console)
          (binding [*read-eval* false]))))


Added TCP ping support.

Added TCP ping support.

--- src/cmr/dev/env/manager/health.clj
+++ src/cmr/dev/env/manager/health.clj
@@ -2,6 +2,7 @@
   (:require
     [cheshire.core :as json]
     [clj-http.client :as httpc]
+    [clojure.java.io :as io]
     [cmr.dev.env.manager.process.docker :as docker]
     [cmr.transmit.config :as transmit]
     [taoensso.timbre :as log]))
@@ -31,3 +32,23 @@
   ([_system _service-key health-check-url opts]
     (http-parse-response
       (httpc/get health-check-url opts))))
+
+(defn tcp-ping
+  [host port]
+  (let [socket (new java.net.Socket host port)
+        writer (io/writer socket)]
+    (.append writer \0)
+    (.flush writer)
+    (.close socket)))
+
+(defn tcp
+  ([port]
+    (tcp "127.0.0.1" port))
+  ([host port]
+    (try
+      (do
+        (tcp-ping host port)
+        {:status :ok})
+      (catch Exception ex
+        {:status :error
+         :details (.getMessage ex)}))))


Fix dis

Fix dis

--- src/doctopus/parsers/markdown.clj
+++ src/doctopus/parsers/markdown.clj
@@ -1,4 +1,4 @@
-(ns doctopus.markdown
+(ns doctopus.parsers.markdown
   (:require [markdown.core :as md]))

 (defn parse-mardown-file


(maint) Fix bug in CA HTTP routes

(maint) Fix bug in CA HTTP routes

Fix a problem with 404's improperly including a message about upgrading
due to a problem with the CA's comidi routes which was introduced during
resolution of merge conflicts when merging-in changes from stable.

--- src/clj/puppetlabs/services/ca/certificate_authority_core.clj
+++ src/clj/puppetlabs/services/ca/certificate_authority_core.clj
@@ -240,20 +240,22 @@

 (schema/defn ^:always-validate web-routes :- comidi/BidiRoute
   [ca-settings :- ca/CaSettings]
-  (comidi/context ["/" :environment]
-    (ANY ["/certificate_status/" :subject] [subject]
-         (certificate-status subject ca-settings))
-    (ANY ["/certificate_statuses/" :ignored-but-required] []
-         (certificate-statuses ca-settings))
-    (GET ["/certificate/" :subject] [subject]
-         (handle-get-certificate subject ca-settings))
-    (comidi/context ["/certificate_request/" :subject]
-      (GET [""] [subject]
-           (handle-get-certificate-request subject ca-settings))
-      (PUT [""] [subject :as {body :body}]
-           (handle-put-certificate-request! subject body ca-settings)))
-    (GET ["/certificate_revocation_list/" :ignored-node-name] []
-         (handle-get-certificate-revocation-list ca-settings))))
+  (comidi/routes
+    (comidi/context ["/" :environment]
+      (ANY ["/certificate_status/" :subject] [subject]
+        (certificate-status subject ca-settings))
+      (ANY ["/certificate_statuses/" :ignored-but-required] []
+        (certificate-statuses ca-settings))
+      (GET ["/certificate/" :subject] [subject]
+        (handle-get-certificate subject ca-settings))
+      (comidi/context ["/certificate_request/" :subject]
+        (GET [""] [subject]
+          (handle-get-certificate-request subject ca-settings))
+        (PUT [""] [subject :as {body :body}]
+          (handle-put-certificate-request! subject body ca-settings)))
+      (GET ["/certificate_revocation_list/" :ignored-node-name] []
+        (handle-get-certificate-revocation-list ca-settings)))
+    (comidi/not-found "Not Found")))

 (schema/defn ^:always-validate
   wrap-middleware :- IFn


Fixed redis stop function.

Fixed redis stop function.

--- src/dragon/data/sources/redis.clj
+++ src/dragon/data/sources/redis.clj
@@ -1,9 +1,11 @@
 (ns dragon.data.sources.redis
-  (:require [clojure.java.shell :as shell]
+  (:require [clojure.java.io :as io]
             [dragon.config :as config]
             [dragon.data.sources.core :as db-core]
+            [dragon.util :as util]
             [taoensso.carmine :as car :refer [wcar]]
-            [taoensso.timbre :as log]))
+            [taoensso.timbre :as log]
+            [trifl.fs :as fs]))

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;;   Constants & Utility Functions   ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -58,6 +60,7 @@
   [component]
   (let [id-file (:container-id-file (config/db-config component))]
     (->> (slurp id-file)
-         (shell/sh "docker" "stop" :in)
+         (util/shell! "docker" "stop")
          vec)
-    (shell/sh "rm" id-file)))
+    (when (fs/exists? (io/as-file id-file))
+      (util/shell! "rm" id-file))))


schema: added comment

schema: added comment

--- examples/_common/middleware/schema.cljs
+++ examples/_common/middleware/schema.cljs
@@ -4,7 +4,8 @@

 (defn add
   "Middleware will validate the model on every change using the specified schema.
-  Throws an exception if validation fails."
+  Throws an exception if validation fails.
+  Add it as close to spec as possible in order to not propagate the invalid model to other middlewares."
   [spec schema]
   (assoc spec :control
               (fn [model signal dispatch-signal dispatch-action]


Consolidated ajax format opts

Consolidated ajax format opts

--- frontend/utils/ajax.cljs
+++ frontend/utils/ajax.cljs
@@ -42,9 +42,12 @@

 (defn xml-response-format []
   {:read (fn read-xml [xhrio]
-           (set! js/window.testx (.getResponseXml xhrio))
            {:resp (.getResponseXml xhrio)})
    :description "XML"})
+
+(defn raw-response-format []
+  {:read (fn read-text [xhrio]
+           {:resp (.getResponseText xhrio)})})

 (defn scopes-from-response [api-resp]
   (if-let [scope-str (get-in api-resp [:response-headers "X-Circleci-Scopes"])]
@@ -60,35 +63,47 @@
       (assoc :resp (get-in default-response [:response :resp]))
       (assoc :status :failed)))

-;; TODO only implementing JSON/RAW format and not implementing prefixes for now since we don't anything else
-(defn ajax [method url message channel & {:keys [params keywords? context headers format]
-                                          :or {keywords? true format :json}}]
-  (let [uuid frontend.async/*uuid*
-        common-opts {:finally #(binding [frontend.async/*uuid* uuid]
-                                 (put! channel [message :finished context]))}
+(defn ajax-opts [method url {:keys [params keywords? context headers format csrf-token
+                                    handler error-handler finally]
+                             :or {keywords? true format :json csrf-token true}}]
+  (println "FORMAT" format)
+  (let [csrf-header (when (and csrf-token (re-find #"^/" url))
+                      {:X-CSRFToken (utils/csrf-token)})
+        common-opts {:handler handler
+                     :error-handler error-handler
+                     :finally finally}
         format-opts (case format
                       :json {:format (clj-ajax/json-request-format)
                              :response-format (json-response-format {:keywords? keywords? :url url :method method})
                              :keywords? keywords?
                              :params params
                              :headers (merge {:Accept "application/json"}
-                                             (when (re-find #"^/" url)
-                                               {:X-CSRFToken (utils/csrf-token)})
-                                             headers)
-                             :handler #(binding [frontend.async/*uuid* uuid]
-                                         (put! channel [message :success (assoc % :context context :scopes (scopes-from-response %))]))
-                             :error-handler #(binding [frontend.async/*uuid* uuid]
-                                       (put! channel [message :failed (normalize-error-response % {:url url :context context})]))}
-                      ;; TODO: use a custom reader or similar for raw to handle more like json
+                                             csrf-header
+                                             headers)}
+                      :xml {:format (xml-request-format)
+                            :response-format (xml-response-format)
+                            :params params
+                            :headers (merge {:Accept "application/xml"}
+                                            csrf-header
+                                            headers)}
                       :raw {:format :raw
-                            :response-format :raw
-                            :handler #(binding [frontend.async/*uuid* uuid]
-                                        (put! channel [message :success {:resp % :context context}]))
-                            :error-handler #(binding [frontend.async/*uuid* uuid]
-                                       (put! channel [message :failed {:resp % :url url :context context :status :failed}]))})
-        opts (merge common-opts format-opts)]
+                            :response-format (raw-response-format)})]
+    (-> (merge common-opts format-opts)
+        clj-ajax/transform-opts)))
+
+;; TODO prefixes not implemented
+(defn ajax [method url message channel & {:keys [params keywords? context headers format]
+                                          :or {keywords? true format :json}
+                                          :as opts}]
+  (let [uuid frontend.async/*uuid*]
     (put! channel [message :started context])
-    (-> (clj-ajax/transform-opts opts)
+    (-> (ajax-opts method url (merge opts
+                                     {:handler #(binding [frontend.async/*uuid* uuid]
+                                                  (put! channel [message :success (assoc % :context context :scopes (scopes-from-response %))]))
+                                      :error-handler #(binding [frontend.async/*uuid* uuid]
+                                                        (put! channel [message :failed (normalize-error-response % {:url url :context context})]))
+                                      :finally #(binding [frontend.async/*uuid* uuid]
+                                                  (put! channel [message :finished context]))}))
         (assoc :uri url :method method)
         clj-ajax/ajax-request)))


Add missing space in curl commands

Add missing space in curl commands

--- frontend/utils/docs.cljs
+++ frontend/utils/docs.cljs
@@ -18,7 +18,7 @@

 (defn api-curl [endpoint]
   (let [curl-args (if-not (= (:method endpoint) "GET")
-                    (str "-X " (:method endpoint))
+                    (str "-X " (:method endpoint) " ")
                     "")
         curl-params (if-let [params (:params endpoint)]
                       (->> params


more specific error message, which helps to newbies with fresh install

--- resources/leiningen/new/expo/env/dev/user.clj
+++ resources/leiningen/new/expo/env/dev/user.clj
@@ -67,13 +67,13 @@
            (first)
            (.getAddress)
            (.getHostAddress)))))
-
+
   (defn get-expo-ip []
     (if-let [expo-settings (get-expo-settings)]
       (case (get expo-settings "hostType")
         "lan" (get-lan-ip)
         "localhost" "localhost"
-        "tunnel" (throw (Exception. "Expo Setting tunnel doesn't work with figwheel.  Please set to LAN or Localhost.")))
+        "tunnel" (throw (Exception. "Expo Setting \"hostType\": \"tunnel\" doesn't work with figwheel. Check .expo/settings.json, please set value to \"lan\" or \"localhost\".")))
       "localhost"))                                         ;; default

   (defn write-env-dev


Fixed issue with AbstractHandler reify in Jetty adapter

--- ring-jetty-adapter/src/ring/adapter/jetty.clj
+++ ring-jetty-adapter/src/ring/adapter/jetty.clj
@@ -5,19 +5,18 @@
            (org.mortbay.jetty.bio SocketConnector)
            (org.mortbay.jetty.security SslSocketConnector)
            (javax.servlet.http HttpServletRequest HttpServletResponse))
-  (:use (ring.util servlet)
-        (clojure.contrib except)))
+  (:use ring.util.servlet))

-(defn- reify-handler
+(defn- proxy-handler
   "Returns an Jetty Handler implementation for the given Ring handler."
   [handler]
-  (reify AbstractHandler
-         (handle [this target ^Request request response dispatch]
-           (let [request-map  (build-request-map request)
-                 response-map (handler request-map)]
-             (when response-map
-               (update-servlet-response response response-map)
-               (.setHandled request true))))))
+  (proxy [AbstractHandler] []
+    (handle [target ^Request request response dispatch]
+      (let [request-map  (build-request-map request)
+            response-map (handler request-map)]
+        (when response-map
+          (update-servlet-response response response-map)
+          (.setHandled request true))))))

 (defn- add-ssl-connector!
   "Add an SslSocketConnector to a Jetty Server instance."
@@ -64,9 +63,8 @@
     (when-let [configurator (:configurator options)]
       (configurator s))
     (doto s
-      (.setHandler (reify-handler handler))
+      (.setHandler (proxy-handler handler))
       (.start))
     (when (:join? options true)
       (.join s))
     s))
-


Revert feature back to master

Revert feature back to master

--- src-cljs/frontend/models/feature.cljs
+++ src-cljs/frontend/models/feature.cljs
@@ -1,15 +1,7 @@
 (ns frontend.models.feature
   "Functions related to enabling and disabling features."
-  (:require [goog.net.cookies :as cookies]
-            [frontend.models.project :as project]
-            [frontend.utils :as util]
-            [frontend.utils.launchdarkly :as ld])
+  (:require [goog.net.cookies :as cookies])
   (:import goog.Uri))
-
-(defn enabled-for-project? [project feature]
-  (project/feature-enabled? project feature))
-
-;; export so we can set this using javascript in production

 (defn- feature-flag-value-true? [value]
   (= value "true"))
@@ -53,9 +45,6 @@
   value, otherwise look in a cookie for the feature. Returns false by
   default."
   [feature]
-  (let [feature-name (name feature)]
-   (if (set-in-query-string? feature-name)
-     (enabled-in-query-string? feature-name)
-     (if (ld/exists? feature-name)
-       (ld/feature-on? feature-name)
-       (enabled-in-cookie? feature-name)))))
+  (if (set-in-query-string? feature)
+    (enabled-in-query-string? feature)
+    (enabled-in-cookie? feature)))


Organize utils

Organize utils

--- desktop/src/nightweb_desktop/utils.clj
+++ desktop/src/nightweb_desktop/utils.clj
@@ -6,6 +6,8 @@
             [nightweb.io :as io]
             [ring.util.codec :as codec])
   (:import [java.util Locale]))
+
+; preferences

 (def prefs (.node (java.util.prefs.Preferences/userRoot) "nightweb"))

@@ -20,6 +22,12 @@

 (def update? (atom (read-pref :update)))
 (def remote? (atom (read-pref :remote)))
+
+(when (nil? @update?)
+  (write-pref :update true))
+
+; language
+
 (def lang-files {"en" "values/strings.xml"
                  "ja" "values-ja/strings.xml"})
 (def lang-strings (-> (get lang-files (.getLanguage (Locale/getDefault)))
@@ -28,9 +36,6 @@
                       .toString
                       xml/parse
                       :content))
-
-(when (nil? @update?)
-  (write-pref :update true))

 (defn get-string
   "Returns the localized string for the given keyword."
@@ -44,6 +49,8 @@
         (or "")
         (clojure.string/replace "\\" ""))
     res-name))
+
+; paths and encodings

 (defn get-relative-path
   "Gets the path of a child relative to its parent."


Generator cleans extra unused keys from record

--- src/hphelper/scengen/generator.clj
+++ src/hphelper/scengen/generator.clj
@@ -233,6 +233,22 @@
    (assoc-in scenRec [:hps]
              (concat '() hps (list character)))))

+(defn- copy-key
+  "Associates the key from source to the target"
+  [source k dest]
+  (assoc dest k (get source k)))
+
+(defn purge-unused
+  "Removes unused keys that are generally holdovers from elsewhere"
+  [scenRec]
+  ((apply comp
+          (map partial
+               (repeat copy-key)
+               (repeat scenRec)
+               [:zone :crisises :directives :societies :minions :news :indicies :hps]))
+   {}
+   ))
+
 (defn create-scenario
   "Creates a generated scenario"
   ([] (create-scenario {}))
@@ -255,6 +271,7 @@
        (update-in [:indicies] fuzzify-indicies)
        (update-in [:indicies] fuzzify-indicies)
        (update-in [:indicies] normalise-all-indicies)
+       ;(purge-unused)
        )))

-(:zone (create-scenario))
+(keys (create-scenario))


server doesn't really work when running client in dev mode b/c boot doesn't have permissions to fork processes

--- build.boot
+++ build.boot
@@ -4,7 +4,6 @@
                   ; dev
                   [adzerk/bootlaces "0.1.13" :scope "test"]
                   [adzerk/boot-test "1.0.4"  :scope "test"]
-                  [alda/server-clj  "0.0.1"  :scope "test"]
                   [str-to-argv      "0.1.0"  :score "test"]

                   ; silence slf4j logging dammit


Make run-sym task more robust

Make run-sym task more robust

--- build.boot
+++ build.boot
@@ -110,6 +110,14 @@
  '[clojure.string :as str]
  '[boot.util :as util])

+(defn- exists-but-no-ns? [sym]
+  (if (nil? sym)
+    false
+    (let [[ns just-sym] (get-ns sym)]
+      (if (nil? just-sym)
+        true
+        false))))
+
 (deftask run-sym
   "Run vars as a pre- and post- tasks."
   [b before SYM sym "The symbol to run inside a pre-wrap task"
@@ -121,13 +129,11 @@
                          (require ns))
                        (if-let [v (resolve s)]
                          (v)
-                         (util/warn "Could not find var '%s\n" s))))
-        [_ before-ns?] (when before (get-ns before))
-        [_ after-ns?]  (when after  (get-ns after))]
-    (if (or
-         (and before (not before-ns?))
-         (and after  (not after-ns?)))
-      (util/warn "Symbols should be fully namespace qualified\n"))
+                         (util/warn "Could not find var '%s\n" s))))]
+    (when (exists-but-no-ns? before)
+      (util/warn "Before symbol `%s` should be fully namespace qualified.\n" (prn-str before)))
+    (when (exists-but-no-ns? after)
+      (util/warn "After symbol `%s` should be fully namespace qualified.\n" (prn-str after)))
     (comp
      (if before
        (with-pass-thru _


Bump Clojure library versions

Bump Clojure library versions

--- build.boot
+++ build.boot
@@ -3,23 +3,23 @@
  :resource-paths  #{"resources"}
  :dependencies
  '[[org.clojure/clojure "1.8.0"]
-   [org.clojure/clojurescript "1.9.293"]
+   [org.clojure/clojurescript "1.9.562"]
    [org.clojure/core.async "0.2.395"]
-   [cljs-ajax "0.5.8"]
-   [reagent "0.6.0"]
-   [re-frame "0.9.1"]
+   [cljs-ajax "0.6.0"]
+   [reagent "0.6.2"]
+   [re-frame "0.9.3"]
    [day8.re-frame/http-fx "0.1.3"]
-   [cljsjs/fuse "2.5.0-0"]
-   [com.taoensso/timbre "4.8.0"]
+   [cljsjs/fuse "2.6.2-0"]
+   [com.taoensso/timbre "4.10.0"]

-   [adzerk/boot-cljs "1.7.228-2" :scope "test"]
-   [adzerk/boot-reload "0.5.0" :scope "test"]
-   [adzerk/boot-test "1.1.2" :scope "test"]
+   [adzerk/boot-cljs "2.0.0" :scope "test"]
+   [adzerk/boot-reload "0.5.1" :scope "test"]
+   [adzerk/boot-test "1.2.0" :scope "test"]
    [adzerk/boot-cljs-repl "0.3.3"]
    [com.cemerick/piggieback "0.2.1"  :scope "test"]
    [weasel "0.7.0"  :scope "test"]
    [org.clojure/tools.nrepl "0.2.12" :scope "test"]
-   [pandeiro/boot-http "0.7.6" :scope "test"]])
+   [pandeiro/boot-http "0.8.3" :scope "test"]])

 (require
  '[adzerk.boot-cljs :refer [cljs]]


Back to SNAPSHOT.

Back to SNAPSHOT.

--- build.boot
+++ build.boot
@@ -3,7 +3,7 @@
                   [clj.rb "0.2.1"]]
   :src-paths    ["src"])

-(def +version+ "0.1.0")
+(def +version+ "0.2.0-SNAPSHOT")

 (task-options!
   pom [:project 'boot-jruby


Version 0.5.13

Version 0.5.13

--- build.boot
+++ build.boot
@@ -12,7 +12,7 @@
          '[adzerk.bootlaces :refer [bootlaces! build-jar push-snapshot push-release]]
          '[metosin.boot-alt-test :refer [alt-test]])

-(def +version+ "0.5.13-SNAPSHOT")
+(def +version+ "0.5.13")
 (bootlaces! +version+)

 (task-options!


clean up build.boot

clean up build.boot

--- build.boot
+++ build.boot
@@ -1,10 +1,7 @@
 (set-env!
-  ;; using the sonatype repo is sometimes useful when testing Clojurescript
-  ;; versions that not yet propagated to Clojars
-  ;; :repositories #(conj % '["sonatype" {:url "http://oss.sonatype.org/content/repositories/releases"}])
   :dependencies '[[org.clojure/clojure       "1.6.0"     :scope "provided"]
-                  [boot/core                 "2.0.0-rc6" :scope "provided"]
-                  [adzerk/bootlaces          "0.1.9"     :scope "test"]
+                  [boot/core                 "2.0.0-rc9" :scope "provided"]
+                  [adzerk/bootlaces          "0.1.9"    :scope "test"]
                   [org.clojure/clojurescript "0.0-2814"  :scope "test"]])

 (require '[adzerk.bootlaces :refer :all])
@@ -19,4 +16,4 @@
        :description "Boot task to compile ClojureScript applications."
        :url         "https://github.com/adzerk/boot-cljs"
        :scm         {:url "https://github.com/adzerk/boot-cljs"}
-       :license     {"Eclipse Public License" "http://www.eclipse.org/legal/epl-v10.html"}})
+       :license     {"EPL" "http://www.eclipse.org/legal/epl-v10.html"}})


deftask uberjar

deftask uberjar

--- build.boot
+++ build.boot
@@ -71,3 +71,8 @@
    (testing-helper)
    (watch)
    (boot-test/test)))
+
+(deftask uberjar
+  []
+  (comp (uber) (aot) (pom) (jar) (sift) (target)))
+


Test dependency was breaking stuff

Test dependency was breaking stuff

--- build.boot
+++ build.boot
@@ -12,7 +12,7 @@

    [com.google.android/android "4.1.1.4" :scope "test"]
    [com.google.testing.compile/compile-testing "0.7" :scope "test"]
-   [adzerk/boot-test "1.1.1" :scope "test"]
+   [adzerk/boot-test "1.0.7" :scope "test"]
    [adzerk/bootlaces "0.1.13" :scope "test"]
    ])


Release v0.2.0

Release v0.2.0

--- build.boot
+++ build.boot
@@ -1,5 +1,5 @@
 (def project 'rads/kafka.transit)
-(def version "0.2.0-SNAPSHOT")
+(def version "0.2.0")

 (set-env!
   :source-paths #{"src"}


Ensure developers are defined

Ensure developers are defined

--- build.boot
+++ build.boot
@@ -6,6 +6,7 @@
   :description "Dynamic loading and lookup"
   :url "https://github.com/irresponsible/overload/"
   :scm {:url "https://github.com/irresponsible/overload"}
+  :developers {"James Laver" "james@seriesofpipes.com"}
   :license {"MIT" "https://en.wikipedia.org/MIT_License"}
   :dependencies '[[org.clojure/clojure      "1.8.0"  :scope "provided"]
                   [adzerk/boot-test         "1.1.0"  :scope "test"]


Use https:// web url for git scm links

Use https:// web url for git scm links

--- build.boot
+++ build.boot
@@ -5,7 +5,7 @@
   :source-paths #{"src"}
   :description "Dynamic loading and lookup"
   :url "https://github.com/irresponsible/overload/"
-  :scm {:url "https://github.com/irresponsible/overload.git"}
+  :scm {:url "https://github.com/irresponsible/overload"}
   :license {"MIT" "https://en.wikipedia.org/MIT_License"}
   :dependencies '[[org.clojure/clojure      "1.8.0"  :scope "provided"]
                   [adzerk/boot-test         "1.1.0"  :scope "test"]


Bump version in attempt to fix clojars

Bump version in attempt to fix clojars

--- build.boot
+++ build.boot
@@ -1,5 +1,5 @@
 (def project 'proud/boot-template)
-(def version "0.1.0")
+(def version "0.1.1")

 (set-env! :resource-paths #{"resources" "src"}
           ;; uncomment this if you write tests for your template:


Improve transformation API.

Improve transformation API.

--- src/algebolic/evolution/transform.clj
+++ src/algebolic/evolution/transform.clj
@@ -10,21 +10,32 @@

 ;; * Helpers *

-(defn apply-to-fraction
-  "Apply a transformation to a randomly selected fraction of the population."
-  [transform fraction population]
-  (map
-    #(if (< (rand) fraction) (transform %) %)
-    population))
-
 (defn apply-to-genotype
   [func individual]
   (assoc individual :genotype (func (:genotype individual))))

+(defn apply-to-fraction-of-genotypes
+  "Apply a transformation to a randomly selected fraction of the population. The transformation will
+  be applied to the genotype of the individual. The rest of the information in the individual will be
+  preserved."
+  [transform fraction population]
+  (map
+    #(if (< (rand) fraction) ((partial apply-to-genotype transform) %) %)
+    population))
+
+(defn apply-to-all-genotypes
+  "Apply a transformation to all of the population. The transformation will be applied to the genotype of
+  the individual. The rest of the information in the individual will be preserved."
+  [transform population]
+  (map (partial apply-to-genotype transform) population))
+
+
 ;; * Generic transformations *

-(defn- hill-descent-genotype
-  "See below."
+(defn hill-descent
+  "Takes a genotype and applies the given tweak function, returns the new individual if it
+  scores better on the score-function, otherwise returns the individual. The tweak function and
+  the score function should operate on the genotype of the individual."
   [tweak-function score-function genotype]
   (let [tweaked (tweak-function genotype)
         score (score-function genotype)
@@ -33,9 +44,3 @@
       tweaked
       genotype)))

-(defn hill-descent
-  "Takes an individual and applies the given tweak function, returns the new individual if it
-  scores better on the score-function, otherwise returns the individual. The tweak function and
-  the score function should operate on the genotype of the individual."
-  [tweak-function score-function individual]
-  (apply-to-genotype (partial hill-descent-genotype tweak-function score-function) individual))


Handle asset paths

Handle asset paths

--- frontend/utils/docs.cljs
+++ frontend/utils/docs.cljs
@@ -1,5 +1,6 @@
 (ns frontend.utils.docs
   (:require [clojure.string :as string]
+            [frontend.stefon :as stefon]
             [frontend.utils :as utils :include-macros true]
             [goog.string :as gstring]
             goog.string.format
@@ -13,9 +14,16 @@
          #js {"__html"  ((aget (aget js/window "HAML") template-name)
                          (clj->js (merge {"include_article" include-article} args)))}}])

+(defn replace-asset-paths [html]
+  (let [re (js/RegExp. "\"asset:/(.*?)\"" "g")]
+    (.replace html re (fn [s match]
+                        (stefon/asset-path match)))))
+
 (defn render-markdown [input]
   (when input
-    (js/marked input)))
+    (-> input
+        js/marked
+        replace-asset-paths)))

 (defn new-context []
   (let [context (js/Object.)]


bump deps

bump deps

--- src/leiningen/new/mies/project.clj
+++ src/leiningen/new/mies/project.clj
@@ -3,9 +3,9 @@
   :url "http://example.com/FIXME"

   :dependencies [[org.clojure/clojure "1.5.1"]
-                 [org.clojure/clojurescript "0.0-2080"]]
+                 [org.clojure/clojurescript "0.0-2127"]]

-  :plugins [[lein-cljsbuild "1.0.0"]]
+  :plugins [[lein-cljsbuild "1.0.1"]]

   :source-paths ["src"]


everyone needs to agree on where we're scrolling to

--- frontend/controllers/post_controls.cljs
+++ frontend/controllers/post_controls.cljs
@@ -104,8 +104,8 @@
                container-id)
     (let [parent (sel1 target "#container_parent")
           container (sel1 target (str "#container_" container-id))
-          new-scroll-left (.-x (goog.style.getContainerOffsetToScrollInto container parent))]
-      (goog.style.scrollIntoContainerView container parent))))
+          new-scroll-left (int (.-x (goog.style.getContainerOffsetToScrollInto container parent)))]
+      (aset parent "scrollLeft" new-scroll-left))))

 (defn container-id [container]
   (int (last (re-find #"container_(\d+)" (.-id container)))))


Tell users how much of the lgo is displayed

--- src-cljs/frontend/components/build_steps.cljs
+++ src-cljs/frontend/components/build_steps.cljs
@@ -93,7 +93,9 @@
       (let [truncated-notification
             (when (:truncated-client-side? action)
               [:span.truncated
-               "Your build output is too large to display in the browser."
+               (gstring/format
+                "Your build output is too large to display in the browser. Only the last %s characters are displayed."
+                action-model/max-output-size)
                [:br]
                (if (= "running" (:status action))
                  "You can download the output once this step is finished."


Limit rebalancer jobs to consider to max preemptions (#383)

--- scheduler/src/cook/mesos/rebalancer.clj
+++ scheduler/src/cook/mesos/rebalancer.clj
@@ -383,8 +383,9 @@
    category is :normal or :gpu, depending on which type of job we're working with"
   [db offer-cache pending-job-ents host->spare-resources {:keys [max-preemption category] :as params}]
   (let [timer (timers/start rebalance-duration)
-        jobs-to-make-room-for (filter (partial util/job-allowed-to-start? db)
-                                      pending-job-ents)
+        jobs-to-make-room-for (->> pending-job-ents
+                                   (filter (partial util/job-allowed-to-start? db))
+                                   (take max-preemption))
         init-state (init-state db (util/get-running-task-ents db) jobs-to-make-room-for host->spare-resources category)]
     (log/debug "Jobs to make room for:" jobs-to-make-room-for)
     (loop [state init-state


CMR-2564 adds comments to test

CMR-2564 adds comments to test

--- access-control-app/int_test/cmr/access_control/int_test/access_control_group_crud_test.clj
+++ access-control-app/int_test/cmr/access_control/int_test/access_control_group_crud_test.clj
@@ -200,7 +200,9 @@
         (is (= {:status 200 :body ["user2"]} (u/get-members token-user1 concept_id)))

         ;; Verify that user not in managing group does not have permission to add member to the group.
+        ;; Remove grant-all ECHO acl from fixture
         (e/ungrant (u/conn-context) {:id "guid4"})
+        ;; Clear it from cmr ACL cache
         (ac/clear-cache (u/conn-context))
         (is (= 401 (:status (u/add-members token-user3 concept_id ["user3"]))))))


don't propagate error page to users in production

--- src/clj/conference_rating/handler.clj
+++ src/clj/conference_rating/handler.clj
@@ -15,6 +15,7 @@
             [ring.middleware.okta :as okta]
             [schema.coerce :as coerce]
             [clojure.string :as string]
+            [onelog.core :as onelog]
             [conference-rating.schemas :as schemas]))

 (def home-page
@@ -119,13 +120,24 @@
       (println "clean request coming in: " clean-request)
       (handler clean-request))))

+(defn wrap-dont-show-error-page [handler]
+  (fn [request]
+    (try
+      (handler request)
+      (catch Exception e
+        (onelog/error (onelog/throwable e))
+        {:status 500 :body "An error occurred" }))))
+
 (defn app [db ssl-redirect-disabled]
   (let [handler (-> (create-routes db)
                     (prevent-open-redirect-through-relay-state)
                     (wrap-defaults (ring-settings ssl-redirect-disabled))
                     (json/wrap-json-response)
                     (json/wrap-json-body {:keywords? true}))]
-    (if (env :dev) (-> handler
-                       wrap-exceptions
-                       wrap-reload)
-                   handler)))
+    (if (env :dev)
+      (-> handler
+          wrap-exceptions
+          wrap-reload)
+      (-> handler
+          wrap-dont-show-error-page
+          ))))


Testing whether compiling tuples in buffer op is problem

--- src/clj/forma/hadoop/jobs/scatter.clj
+++ src/clj/forma/hadoop/jobs/scatter.clj
@@ -403,4 +403,31 @@
 ;; (run-local-info "/Users/robin/Downloads/eco-40103-small")

 ;; (local-beta-generator (forma-run-parameters "500-16"))
-;; (use 'forma.hadoop.jobs.scatter)+;; (use 'forma.hadoop.jobs.scatter)
+
+(defbufferop [eco-bufferop [r c m]]
+  [tuples]
+  (let [val-mat      (map second tuples)
+        neighbor-mat (map last tuples)
+        feature-mat  (map log/unpack-feature-vec val-mat neighbor-mat)]
+    [[(first feature-mat)]]))
+
+(defn buffer-generator
+  "query to return the beta vector associated with an ecoregion"
+  [{:keys [t-res est-start ridge-const convergence-thresh max-iterations]} src]
+  (let [first-idx (date/datetime->period t-res est-start)]
+    (<- [?beta]
+        (src ?hansen ?val ?neighbor-val)
+        (eco-bufferop [ridge-const convergence-thresh max-iterations]
+                                ?hansen ?val ?neighbor-val :> ?beta)
+        (:distinct false))))
+
+(defmain run-buffer-generator
+  [tmp-root in-path out-path]
+  (let [est-map (forma-run-parameters "500-16")]
+    (workflow [tmp-root]
+              genbetas
+              ([]
+                 (?- (hfs-seqfile out-path :sinkmode :replace)
+                     (buffer-generator est-map
+                                            (hfs-seqfile in-path)))))))


debugging

debugging

--- src/clj/rumahsewa141/routes/admin.clj
+++ src/clj/rumahsewa141/routes/admin.clj
@@ -84,9 +84,7 @@
                                         (get-content-fn)))))

 (defn admin-page-test []
-  (layout/render "member.html" {:username "dingdong"
-                                :admin true
-                                :section "overview"}))
+  (layout/render "member.html"))

 (defn settings-page [subsection req & [get-content-fn]]
   (admin-page "settings" get-content-fn req subsection))


Adding  few backend dependencies

Adding  few backend dependencies

--- zambuko-back/project.clj
+++ zambuko-back/project.clj
@@ -9,8 +9,12 @@
                  [com.taoensso/timbre "2.1.2"]
                  [com.postspectacular/rotor "0.1.0"]
                  [com.taoensso/tower "1.7.1"]
-                 [markdown-clj "0.9.28"]]
+                 [markdown-clj "0.9.28"]
+                 [org.jclouds/jclouds-allblobstore "1.6.0"]
+                 [org.hornetq/hornetq-core-client "2.3.3.Final"]
+                 [org.activiti/activiti-engine "5.13"]]
   :plugins [[lein-ring "0.8.5"]]
+  :repositories [["Alfresco Maven Repository" "https://maven.alfresco.com/nexus/content/groups/public/"]]
   :ring {:handler zambuko-back.handler/war-handler
          :init    zambuko-back.handler/init
          :destroy zambuko-back.handler/destroy}
@@ -20,4 +24,4 @@
                        :auto-reload?  false}}
    :dev {:dependencies [[ring-mock "0.1.5"]
                         [ring/ring-devel "1.1.8"]]}}
-  :min-lein-version "2.0.0")+  :min-lein-version "2.0.0")


Fix namespace `_` to `-`

Fix namespace `_` to `-`

--- src/day8/re_frame_10x/view/event.cljs
+++ src/day8/re_frame_10x/view/event.cljs
@@ -3,7 +3,7 @@
             [day8.re-frame-10x.view.components :as components]
             [day8.re-frame-10x.common-styles :as common]
             [mranderson047.garden.v1v3v3.garden.units :as units]
-            [mranderson047.reagent.v0v8v0_alpha2.reagent.core :as reagent]
+            [mranderson047.reagent.v0v8v0-alpha2.reagent.core :as reagent]
             [mranderson047.re-frame.v0v10v2.re-frame.core :as rf]
             [zprint.core :as zp]
             [goog.string]


+(try-hard-to)

+(try-hard-to)

--- src/babel/francais.cljc
+++ src/babel/francais.cljc
@@ -51,3 +51,17 @@

   ([input model]
    (parse/parse input model)))
+
+(defn try-hard-to [function]
+  (take
+   1
+   (repeatedly
+    #(println
+      (fo
+       (first
+        (take
+         1
+         (filter
+          (fn [expr] (not (nil? expr)))
+          (take 100
+                (repeatedly function))))))))))


add (def ^:dynamic) to morph-ps, index-fn and grammar

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -16,9 +16,11 @@
                         result))
 (def ^:dynamic truncate? false)
 (def ^:dynamic println? false)
+(def ^:dynamic default-fn (fn [x] [x]))
 (def ^:dynamic model)
-(def ^:dynamic index-fn nil)
-(def ^:dynamic lexicon)
+(def ^:dynamic morph-ps)
+(def ^:dynamic index-fn)
+(def ^:dynamic grammar)

 (declare assoc-children)
 (declare frontier)
@@ -32,13 +34,17 @@
   "Return one expression matching spec _spec_ given the model _model_."
   ([spec]
    (binding [model model
+             morph-ps morph-ps
+             grammar grammar
              index-fn index-fn]
      (first (gen spec))))

   ([spec model]
    (log/debug (str "(generate) with model named: " (:name model)
                    "; truncate? " truncate?))
-   (binding [model model
+   (binding [default-fn (:default-fn model)
+             grammar (:grammar model)
+             morph-ps (:morph-ps model)
              index-fn (if (:index-fn model)
                         (:index-fn model)
                         (do
@@ -56,7 +62,7 @@

 (defn grow
   "recursively generate trees given
-   input trees and model. continue recursively
+   input trees. continue recursively
    until no futher expansion is
    possible."
   [trees]
@@ -71,8 +77,8 @@
           child-spec (u/get-in tree f)
           child-lexemes #(get-lexemes child-spec)
           child-trees #(parent-with-head child-spec depth)]
-      (when println? (println (str "grow at:" ((:morph-ps model) tree))))
-      (log/debug (str "grow at:" ((:morph-ps model) tree)))
+      (when println? (println (str "grow at:" (morph-ps tree))))
+      (log/debug (str "grow at:" (morph-ps tree)))
       (lazy-cat
        (if (not (empty? f))
          (grow
@@ -116,12 +122,12 @@
     true []))

 (defn parent-with-head
-  "Return every possible tree of depth 1 from the given spec and model."
+  "Return every possible tree of depth 1 from the given spec."
   [spec depth]
   ;; get all rules that match input _spec_:
   (if (nil? spec) (throw (Exception. (str "nope: spec was nil."))))
   (let [matching-rules
-        (shuffle (->> (:grammar model)
+        (shuffle (->> grammar
                       (map #(unify % spec))
                       (filter #(not (= :fail %)))))]
     (->> matching-rules
@@ -135,7 +141,7 @@
     (let [parent-rule (first parent-rules)
           phrases-with-phrasal-head #(map (fn [child]
                                             (u/assoc-in parent-rule [:head] child))
-                                          (:grammar model))
+                                          grammar)
           phrases-with-lexical-heads #(map (fn [child]
                                              (u/assoc-in parent-rule [:head] child))
                                            (get-lexemes (unify
@@ -158,9 +164,9 @@
          (parent-with-head-1 spec depth (rest parent-rules)))))))

 (defn get-lexemes
-  "Get lexemes matching the spec. Use a model's index if available, where the index
-   is a function that we call with _spec_ to get a set of indices.
-   Otherwise use the model's entire lexeme."
+  "Get lexemes matching the spec. Use index, where the index
+   is a function that we call with _spec_ to get a set of lexemes
+   that matches the given _spec_."
   [spec]
   (->>
    (index-fn spec)
@@ -180,14 +186,12 @@
             (concat (butlast f) [::done?])
             true)
            (u/dissoc-paths (if truncate? [f] []))
-           ((or (:default-fn model) (fn [x] [x])))))
+           (default-fn)))
      (assoc-each-default tree (rest children) f))))

 (defn assoc-children [tree children f]
   (if (not (empty? children))
-    (let [child (first children)
-          default-fn (or (:default-fn model)
-                         (fn [x] [x]))]
+    (let [child (first children)]
       (lazy-cat
        (if (= true (u/get-in child [::done?]))
          (assoc-each-default tree (default-fn child) f)


(defn add-bolt-at): returning a lazy-seq vastly improves time-to-first-expression generation time

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -143,25 +143,26 @@
                   bolts-at))))))))

 (defn add-bolt-at [top-bolt bolt path bolt-at model depth max-depth]
-  (mapfn #(do-defaults % model)
-         (if (= false (get-in bolt-at [:phrasal]))
-           [(if (= bolt bolt-at)
-              bolt
-              (assoc-in bolt path bolt-at))]
-           (let [comp-paths (find-comp-paths bolt-at)
-                 comp-bolts (map #(comp-path-to-bolts bolt-at % model (+ 1 depth) max-depth)
-                                 comp-paths)]
-             (when (not (some empty? comp-bolts))
-               (mapfn #(if (= bolt bolt-at)
-                         %
-                         (assoc-in bolt path %))
-                      (add-comps bolt-at
-                                 model
-                                 comp-paths
-                                 comp-bolts
-                                 (+ 1 depth)
-                                 max-depth
-                                 top-bolt)))))))
+  (lazy-seq
+   (mapfn #(do-defaults % model)
+          (if (= false (get-in bolt-at [:phrasal]))
+            [(if (= bolt bolt-at)
+               bolt
+               (assoc-in bolt path bolt-at))]
+            (let [comp-paths (find-comp-paths bolt-at)
+                  comp-bolts (mapfn #(comp-path-to-bolts bolt-at % model (+ 1 depth) max-depth)
+                                    comp-paths)]
+              (when (not (some empty? comp-bolts))
+                (mapfn #(if (= bolt bolt-at)
+                          %
+                          (assoc-in bolt path %))
+                       (add-comps bolt-at
+                                  model
+                                  comp-paths
+                                  comp-bolts
+                                  (+ 1 depth)
+                                  max-depth
+                                  top-bolt))))))))
 (defn generate2
   "Return all expressions matching spec _spec_ given the model _model_."
   [spec model]


show syntax tree to help diagnose problems with generation, rather than just string: s/morph/morph-ps/

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -191,7 +191,7 @@
   (let [complements (gen (get-in bolt path) model 0 nil path)]
     (if (empty? complements)
       (log/warn (str "(improve grammar): no complements found for: "
-                     ((:morph model) bolt)
+                     ((:morph-ps model) bolt)
                      "; spec=" (show-spec
                                 (get-in bolt path))))
       (->>


fix semantics of if-then: should unify with 'then' part rather than just with 'if'

--- src/babel/lexiconfn.clj
+++ src/babel/lexiconfn.clj
@@ -911,9 +911,9 @@
                  (cond (not (fail? result))
                        (do
                          (log/debug (str val ": matches: if: " if-has " then " unify-with))
-                         (list result))
-                     true
-                     (list val))))
+                         (list (unifyc val unify-with)))
+                       true
+                       (list val))))
              vals))))

 (defn get-fail-path [map1 map2]


web/merge.clj: added doctype=case to records

--- src/org/altlaw/jobs/web/merge.clj
+++ src/org/altlaw/jobs/web/merge.clj
@@ -23,7 +23,7 @@
 (defn map-document [document]
   (let [links (all-links document)]
     (if-let [docid (some #(ids/get-docid "altcrawl" %) (all-links document))]
-      [[docid (assoc document :docid docid)]]
+      [[docid (assoc document :docid docid :doctype "case")]]
       (do (log/warn "Missing docid for " links)
           (h/counter "Missing docid")
           nil))))
@@ -33,7 +33,7 @@
     (let [download (decode-response-body download)
           html (Anonymizer/filter (pdf/pdf-to-html (str docid) (:response_body_bytes download)))
           text (PROHTMLToText/filter html)]
-      [[docid {:docid docid :html html :text text}]])
+      [[docid {:docid docid :html html :text text :doctype "case"}]])
     (do (log/warn "Missing docid for " (:request_uri download))
         (h/counter "Missing docid")
         nil)))


Add `not`, `and`, `or`, and `let` to quickref. Fixes #126.

--- src/clj/clojuredocs/pages/quickref/static.clj
+++ src/clj/clojuredocs/pages/quickref/static.clj
@@ -45,8 +45,10 @@
      :categories
      ({:title "Flow Control",
        :groups
-       ({:syms
-         (if
+       ({:syms (not and or), :title "Boolean"}
+        {:syms
+         (let
+             if
              if-not
            if-let
            when


Factor-out db/install-schema! into its own function

--- src/braid/server/db.clj
+++ src/braid/server/db.clj
@@ -5,17 +5,20 @@
             [braid.server.conf :refer [config]]
             [braid.server.schema :refer [schema]]))

-(defn init!
-  "set up schema"
-  [db-url]
-  (when (d/create-database db-url)
-    @(d/transact (d/connect db-url)
+(defn install-schema! [db-url]
+ (d/transact (d/connect db-url)
                  (concat
                    ; partition for our data
                    [{:db/ident :entities
                      :db/id #db/id [:db.part/db]
                      :db.install/_partition :db.part/db}]
-                   schema))))
+                   schema)))
+
+(defn init!
+  "set up schema"
+  [db-url]
+  (when (d/create-database db-url)
+    @(install-schema! db-url)))

 (defn connect [{:keys [db-url]}]
   (init! db-url)


braveclojure: finishing multimethods + protocols + records chapter(basics/fundamentals/clean/enough)

--- braveclojure-multimethods-protocols.clj
+++ braveclojure-multimethods-protocols.clj
@@ -74,3 +74,205 @@
 ;; one important thing as convention, is that the dispached-value should NOT contain any special dash
 ;; or other special chars

+;;;;;;;;;;;;
+;; Protocols
+;; are specially built for Type dispatching. The same thing can be achieved using multimethods as well.
+;; being built into the language -> language support
+;; whereas multimethods dispatch based on the returned func-dispatcher value, a protocol always
+;; dispatches based on the Type of the first argument.
+;; whereas a multimethod is one polymorphic operation, a protocol defines a collection of abstract
+;; polymorphic operations.
+;; Being a protocol it makes NO sense to provide implementation, in the exposed protocol.
+;; It makes sense, on the other side, to Types to implement this protocol -> therefore
+;; Types provide the implementation for the protocol polymorphic operations.
+;; So a protocol has a [name, optional-doc-string, methods-signatures-only]
+(defprotocol split-by-protocol
+  "optional doc-string for salute protocol"
+  (split [x] "optional method doc-string:: split by whitespace")
+  (split-by [x] [x splitter] "split by a given splitter"))
+
+;; a protocol cannot make use of the [rest] varargs. an exception is triggered if the case.
+;; therefore a protocol defines a fixed set of arguments. In the split-by signature
+;; this method is declared so that it can take 1 or 2 arguments respectively.
+
+;; as said it makes no sense for the protocol to implement itself. it is the responsibility
+;; of the Types to implement a protocol.
+;; the magnific side is that in clojure we can augment an existing compiled Type at runtime
+;; with additional polymorphic behavior. This cannot be done in Java not in 50 years from now...
+
+;; Protocols are NOT attached to a Type; we're coming from an OOP world, where each method must
+;; coexist in the context of a Type. Well this is Clojure world, and in Clojure the protocol's
+;; polymorphic behavior is attached on the namespaces. If there are 2 messages with the same
+;; name, for them to be used to augment a Type at runtime, they must exist in SEPARATED namespaces.
+;; this is the only restrictions. Since any declared method is bounded to the namespace
+;; where it was created:
+
+(in-ns 'other-ns)
+(class split-by-protocol) ; -> !!!RuntimeException: unable to resolve symbol
+(doc refer) ; -> [in-ns] does NOT load the 'clojure.core funcs!!! nor 'clojure.repl
+(require 'clojure.core)
+(require 'clojure.repl) ; -> now's better
+;; back to our protocols cake ;)
+(clojure.core/refer 'braveclojure)
+
+(for [each (all-ns)] each)
+
+(class split-by-protocol) ; -> persistent-array-map
+
+;; hence namespaces being first-class in clojure, the protocol's methods are bounded to the
+;; namespaces and NOT Types.
+;; "when we define protocls we define abstractions" i like this :)
+
+;; to make an existing Type extend a protocol there's the simple syntax sugar:
+(extend-type java.lang.String
+  split-by-protocol
+  (split [x] (clojure.string/split x #""))
+  (split-by
+     ([x] (split x))
+     ([x splitter] (clojure.string/split x splitter))))
+
+;; if a default implementation is desired, we can just extend the java.lang.Object Type...
+
+(split-by "cclaudiu")      ; ["c" "c" "l" "a" "u" "d" "i" "u"]
+(split-by "cclaudiu" #"a") ; ["ccl" "udiu"]
+
+;; NICeeeeeeeeeeeeeeeeeeeeee
+
+;; instead of using the [extend-type] macro all the time, we can just use the
+;; [extend-protocol] and list the Types we want our protocol to augment together
+;; with the implementations for the protocol, as in the [extend-type] scenario.
+
+(extend-protocol split-by-protocol
+  java.lang.String
+    (split
+       [x] (clojure.string/split x #""))
+    (split-by
+        ([x] (split x))       ;; delegate
+        ([x split-pattern] (clojure.string/split x split-pattern)))
+
+  java.lang.Object
+    (split [x] (clojure.string/split (.toString x) #""))
+    (split-by
+       ([x] (split x))
+       ([x split-pattern] (clojure.string/split (.toString x) split-pattern))))
+
+;; all in one: now we have a default Object protocol extended, and the specific String like.
+
+;; testing the default-object
+(split (Integer. 323)) ; ["3" "2" "3"]
+(split "some") ; ["s" "o" "m" "e"]
+(split-by "clojure-is-awesome" #"-") ; ["clojure" "is" "awesome"]
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Records
+;; in clojure are like custom-maps data-types. they(anaphora) associate keys with values
+;; and hence we can lookup for values by record-labels. The difference to maps comes
+;; in the form of "statically" defining fixed labels for values. While in maps the
+;; keys can vary, in records the labels are locked down upon record-creation.
+;; (think of class-fields)
+;; The other difference is that records can implement protocols.
+;; Vector-syntax is again used(as in the let-bindings or function-args, or loop-bindings
+;; or for-iterations) for enclosing the labels.
+;; Firsts things first we DEFINE the record using: [defrecord] macro:
+(defrecord Programmer [name company favourite-language])
+
+;; once we defined the Record, we MUST instantiate it somehow and "pair" the labels with values.
+;; one downside is that records are using formal label-positioning when binding values.
+;; this is because under-the-hood, records are java classes with no behavior:
+
+;; one way to instantiate a Record:
+(Programmer. "cclaudiu" "sap" "clojure")
+; #braveclojure.Programmer{:name "cclaudiu", :company "sap", :favourite-language "clojure"}
+
+;; --> Records can be instantiated as plain java Types using the "dot" special form
+
+;; another way is to use the ARROW notation:
+(->Programmer "cclaudiu" "sap" "clojure")
+; #braveclojure.Programmer{:name "cclaudiu", :company "sap", :favourite-language "clojure"}
+
+;; and the savior, providing named-labels support, when it comes to not enumerate the
+;; records-values and rely on the positional arguments is the:
+(map->Programmer {:company "sap" :name "cclaudiu" :favourite-language "clojure"})
+;; nice :)
+
+;; in the last 2 examples, when declaring the record definition automatically 2 factory funcs
+;; are created in the current-ns. the factory funcs are: ->Programmer and map->Programmer
+;; we can then reuse them to create instances of the declared record.
+
+;; records can be looked-up using 2 options:
+;; -> use map like lookups: record-labels as functions to lookup the record.
+;;       (the label-key is a function that looksup for itself in the provided record as argument)
+;; -> use java interop syntax
+(def cc (->Programmer "cclaudiu" "sap" "clojure"))
+(:name cc) ; "cclaudiu"
+
+;; (cc :name) ; -> ClassCastException:: Programmer record cannot be cast to IFn
+
+(.name cc) ; "cclaudiu"
+
+;; when testing for equality of records, clojure tests for values offcourse, and should have the
+;; same types.
+
+;; another powerfull thing in the records-abstraction is that any function that works on the
+;; core [map] works on the Records.
+(map-indexed vector cc)
+;; ([0 [:name "cclaudiu"]] [1 [:company "sap"]] [2 [:favourite-language "clojure"]])
+
+(sort-by first > (map-indexed vector cc))
+;; ([2 [:favourite-language "clojure"]] [1 [:company "sap"]] [0 [:name "cclaudiu"]])
+
+(sort-by first (comp - (comparator >)) (map-indexed vector cc))
+;; ([0 [:name "cclaudiu"]] [1 [:company "sap"]] [2 [:favourite-language "clojure"]])
+
+;; note: every predicate that takes 2 arguments is an function instance of the Comparator.
+;; normaly every predicate it translated under-the-hood into a comparator.
+;; that's why the last function inverses the sign using: comp - (comparator >)
+;; (comparator >) is returning a comparator func that returns
+;;   -> 1(for first > second)
+;;   -> -1(for first < second)
+;;   -> 0 (for equality)
+;; we are composing the comparator, that says: give me the record-data, mapped as
+;; a vector having the first item the index, sorted descendantly, but by
+;; composing the comparaotr func with a [minus] func we're reversing the order.
+
+;; [assoc] works also for records
+(assoc cc :address "titan")
+;; #braveclojure.Programmer{:name "cclaudiu", :company "sap", :favourite-language "clojure", :address "titan"}
+
+;; keep in mind that records are IMMUTABLE, as maps and other structures! so we should say like:
+(def cc-with-address (assoc cc :address "titan"))
+(class cc-with-address) ; -> braveclojure.Programmer
+
+;; the downside comes when dissoc iating stuff from records -> a new map-structure is returned instead
+;; of the record type:
+(class (dissoc cc :company)) ; -> PersistentArrayMap... NO MORE a Programmer Type!!
+
+
+;; records can be augmented with protocols, that is can implement protocols.
+;; and in the same context, while implementing the protocols you have access to the record's fields.
+(defprotocol rec-demo-protocol
+  "just to illustrate the power of records and protocols for abstracting things"
+  (print-everything [x] "will defintelly print everything"))
+
+(defrecord car-rec [brand car-type]
+  rec-demo-protocol
+    (print-everything
+       [that]
+       (println (format "car brand: %1s, car-type: %2s" (:brand that) (:car-type that)))))
+
+;; defrecord record-name [labels]
+;;    implemented-protocol (protocol-funcs-impl)
+
+(def bmw (->car-rec "bmw" "sport"))
+(print-everything bmw) ; -> will print:  car brand: bmw, car-type: sport
+(.print-everything bmw) ; -> same-thing, but as java interop syntactic sugar. print returns nil ;)
+
+;; we can augment any record at a later point using: [extend-type] or [extend-protocol] for more records
+
+;; one more thing to mention, is that records provide a faster lookup and performance than maps
+;; so when to use maps and when records? whenever we want to express the domain-logic into meaningfull
+;; terms that will have business value use records over maps.
+;; "your code will communicate its purpose better if you give a name to the concept you're trying to model"
+
+;; and this closes enough of clojure: multi-methods + protocols + records you want to know in the wild
+;; for further advanced reading: proxy, deftype will suite. but not my case for the moment ;)


Argument order fix in js->clj.

Argument order fix in js->clj.

This causes (js->clj nil) to return a type error instead of nil.

--- src/cljs/cljs/core.cljs
+++ src/cljs/cljs/core.cljs
@@ -7087,7 +7087,7 @@
   ([x] (js->clj x {:keywordize-keys false}))
   ([x & opts]
     (cond
-      (satisfies? x IEncodeClojure)
+      (satisfies? IEncodeClojure x)
       (-js->clj x (apply array-map opts))

       (seq opts)


Less fragile pattern

Less fragile pattern

--- src/cljs_rest/core.cljs
+++ src/cljs_rest/core.cljs
@@ -120,7 +120,10 @@
     m))

 (def link-pattern
-  #"(?i)<(.*?)>; rel=\"(.*?)\"")
+  "Matches a `link-value` according to https://tools.ietf.org/html/rfc5988#section-5,
+  capturing `URI-Reference` and a `rel` value for `link-param`, ignoring all other
+  `link-param` fields if present."
+  #"(?i)<(.*?)>(?:;\s*(?!rel)[^=]+=\".*?\")*;\s*rel=\"(.*?)\"(?:;\s*[^=]+=\".*?\")*")

 (defn parse-url-query-params [url]
   (let [uri (uri/parse url)


Remove stray logging line.

Remove stray logging line.

--- src/clojupyter/core.clj
+++ src/clojupyter/core.clj
@@ -291,7 +291,6 @@
                 (let [fullresult (nrepl-eval (get-in message [:content :code]) transport)
                       result (reformat-values fullresult)
                       output (:out fullresult)]
-                  (spit "/Users/rory/cache/clojupyter/log.log" fullresult)
 ;                      output (str s#)]
                   [output, result]))]
           (send-router-message shell-socket "execute_reply"


Fixed issue #17: Add support for text output format.

--- src/clouseau/server.clj
+++ src/clouseau/server.clj
@@ -287,6 +287,11 @@
         "[Package]\n" package
         "\n\n[CCS Description]\n" ccs-description
         "\n\n"))
+        (apply str
+            (for [p package-descriptions]
+                (str "[" (key p) "]\n"
+                         (val p) "\n\n")
+            ))))

 (defn html-renderer
     [products package package-descriptions ccs-description products-per-descriptions products-without-descriptions new-description user-name]