Purge old data files

Purge old data files

--- src/saa/core.clj
+++ src/saa/core.clj
@@ -20,7 +20,6 @@
   ;; An option with a required argument
   [["-l" "--location PLACE" "Location"
     :default (:defaultlocation (config))
-;;    :parse-fn #(Integer/parseInt %)
     :validate [#(string? %) "Must be a string"]]
    ;; A non-idempotent option
    ["-m" "--measurement MEASUREMENT" "Measurement"
@@ -51,6 +50,25 @@
 (def firstcontent (comp first :content))
 (def secondcontent (comp second :content))

+(defn olderthan
+  "Is this file older than given time?"
+  [suspect age]
+  (> (- (.getTime (java.util.Date.))
+        (.lastModified suspect))
+     age))
+
+(defn cleanup
+  "Delete datafiles older than 30 minutes"
+  []
+  (let [dir (io/file ".")
+        files (.listFiles dir)
+        datafiles (filter #(re-find #"^weatherdata-.+xml$" (.getName %)) files) ]
+    (map (fn [x]
+           (when
+               (olderthan x 1800000)
+             (.delete x)))
+         datafiles)))
+
 (defn -main
   [& args]
   (let [climap (parse-opts args cli-options)
@@ -63,9 +81,7 @@
                      (:location cliopts))
         initfile (when (or ; fetch the XML if a cached copy doesn't exist or is over 15 mins old
                         (not (.exists (io/file filename)))
-                        (> (- (.getTime (java.util.Date.))
-                              (.lastModified (io/file filename)))
-                           900000))
+                        (olderthan (io/file filename) 900000))
                    (spit filename
                          (:body
                           (client/get datauri))))
@@ -77,6 +93,7 @@
          (tag= :result) (tag= :MeasurementTimeseries)
          (attr= :gml/id measurement) (tag= :point) (tag= :MeasurementTVP)]
         points (eduction (apply comp path) [ennuste])]
+    (cleanup)
     (cond
       (:help cliopts)
       (println (str "-l, --location PLACE [" (:defaultlocation (config)) "]\n-m --measurement [" (:defaultmeasurement (config)) "]\n\nPossible values for measurement are:\n" (clojure.string/join " " (sort measurements))))


Fix whitespace at end of line

Fix whitespace at end of line

--- src/desdemona/utils.clj
+++ src/desdemona/utils.clj
@@ -29,7 +29,7 @@

 (defn update-task
   "Finds the catalog entry with :onyx/name task-name
-  and applies f to it, returning the full catalog with the
+  and applies f to it, returning the full catalog with the
   transformed catalog entry"
   [catalog task-name f]
   (mapv (fn [entry]


delete renamed file

delete renamed file

--- src/leiningen/new/migae/reloadfilter.clj
+++ src/leiningen/new/migae/reloadfilter.clj
@@ -1,23 +0,0 @@
-(ns {{name}}.reload-filter
-  (:import (javax.servlet Filter FilterChain FilterConfig
-                          ServletRequest ServletResponse))
-  (:require [clojure.tools.logging :as log :only [debug info]])
-  (:gen-class :implements [javax.servlet.Filter]))
-
-(defn -init [^Filter this ^FilterConfig cfg])
-(defn -destroy [^Filter this])
-
-(defn -doFilter
-  [^Filter this
-   ^ServletRequest rqst
-   ^ServletResponse resp
-   ^FilterChain chain]
-  (do
-    (log/info "reloading...")
-    (require
-     {{#servlets}}
-     '{{appname}}.{{servlet}}-impl
-     {{/servlets}}
-     ;; :verbose
-     :reload)
-    (.doFilter chain rqst resp)))


Animated and moving player

Animated and moving player

--- src/game/main_game.cljs
+++ src/game/main_game.cljs
@@ -2,19 +2,63 @@

 (defn MainGame [game]
   (let [still-frame 0
+        anim-frame-rate 2
+        speed 1
+
         dialogue-style (clj->js {:font "20px Arial"
-                                 :fill "white"})]
+                                 :fill "white"})
+        UP (js/Phaser.Keyboard.)]
     (reify Object

       (create [this]
         (js/console.log "Entering Main Game!")
+
+        ;; Populate world
         (.. game -add (sprite 0 0 "floor"))
         (.. game -add (sprite 0 0 "dialogue-box"))
         (set! (.. this -dialogue) (.. game -add (text 0 0
                                                       "It begins here"
                                                       dialogue-style)))
-        (set! (.. this -player) (.. game -add (sprite 10 10 "player"))))
+        (set! (.. this -player) (.. game -add (sprite 10 10 "player")))
+
+        ;; Define animations
+        (.. this -player -animations (add "down" (clj->js [0 1 2]) anim-frame-rate true))
+        (.. this -player -animations (add "up" (clj->js [3 4 5]) anim-frame-rate true))
+        (.. this -player -animations (add "left" (clj->js [6 7 8]) anim-frame-rate true))
+        (.. this -player -animations (add "right" (clj->js [9 10 11]) anim-frame-rate true))
+
+        ;; Set up input
+        (set! (.. this -cursors)
+              (.. game -input -keyboard (createCursorKeys)))
+        )

       (update [this]
-        (if true
-          (set! (.. game -player -frame) still-frame))))))
+        (cond
+          (.. this -cursors -up -isDown)
+          (do
+            (let [y  (.. this -player -y)]
+              (set! (.. this -player -y)
+                    (- y speed)))
+            (.. this -player -animations (play "up")))
+          (.. this -cursors -down -isDown)
+          (do
+            (let [y  (.. this -player -y)]
+              (set! (.. this -player -y)
+                    (+ y speed)))
+            (.. this -player -animations (play "down")))
+
+          (.. this -cursors -left -isDown)
+          (do
+            (let [x  (.. this -player -x)]
+              (set! (.. this -player -x)
+                    (- x speed)))
+            (.. this -player -animations (play "left")))
+
+          (.. this -cursors -right -isDown)
+          (do
+            (let [x  (.. this -player -x)]
+              (set! (.. this -player -x)
+                    (+ x speed)))
+            (.. this -player -animations (play "right")))
+
+          :else (set! (.. this -player -frame) still-frame))))))


build-lookup-table function added to tabular.clj

--- src/grafter/tabular.clj
+++ src/grafter/tabular.clj
@@ -357,3 +357,31 @@
   (defn join [csv f & others]
     ;;(filter)
     (apply map vector csv others)))
+
+
+(defn build-lookup-table
+  "takes a CSV file, a vector of any number of integers corresponding
+  to key column numbers and a integer corresponding to the value column number and
+  returns a function, taking a row (a hash-map) as argument and returning the value wanted"
+  ([csv key-cols]
+
+    (let [key-names (map #(resolve-column-id csv % "this column id doesn't exist!") key-cols)
+          compl-key-cols (vec (clojure.set/difference (set (:column-names csv))
+                                                      (set (if (sequential? key-cols)
+                                                               key-names
+                                                               [key-names]))))]
+     (build-lookup-table csv key-cols compl-key-cols)))
+
+  ([csv key-cols value-col]
+
+    (let [arg->vector (fn [x] (if (sequential? x) x [x]))
+          keys (:rows (all-columns csv (arg->vector key-cols)))
+          val (:rows (all-columns csv (arg->vector value-col)))
+          table (zipmap keys val)]
+      (fn
+        [row]
+        (let [key-names (map #(resolve-column-id csv % "this column id doesn't exist!") (arg->vector key-cols))
+              lookup (zipmap key-names (map #(row %) key-names))
+              value-from-row (table lookup)]
+          value-from-row)))))
+


add timestamp at moment doc is created

add timestamp at moment doc is created

--- src/app/cljs/one/sample/model.cljs
+++ src/app/cljs/one/sample/model.cljs
@@ -32,11 +32,11 @@
         watch   (add-watch state :document-state-key
                          (fn [k r o n]
                            (swap! docs assoc (keyword (:id n)) n)))
+        now     #(. (js/Date.) (getTime))
         init    (swap! state assoc :who who :id (or id (uuid))
-                       :content (or content ""))
+                       :content (or content "") :ts (now))
         history (atom '())
-        cursor  (atom 0)
-        now     #(. (js/Date.) (getTime))]
+        cursor  (atom 0)]
     (fn document [command & args]
       (condp = command
         :set!          (let [[k v] args]


Example should use (into) instead of (concat)

Was testing this out and trying to add another middleware using `(insert-after)` and it blew up. `(concat)` returns a lazy sequence, and the next time calling `(subvec)` it blows up... Switching to `(into)` solved it since it preserves the vector type.

--- examples/progress_download.clj
+++ examples/progress_download.clj
@@ -27,7 +27,7 @@
   "Addes value into a vector at an specific index."
   (-> (subvec v 0 idx)
       (conj val)
-      (concat (subvec v idx))))
+      (into (subvec v idx))))

 (defn insert-after [v needle val]
   "Finds an item into a vector and adds val just after it.


PLATFORM-2817: re-enable integration tests

--- .midje.clj
+++ .midje.clj
@@ -1 +1 @@
-(change-defaults :fact-filter (complement :thumbnail-integration))
+;(change-defaults :fact-filter (complement :thumbnail-integration))


Add a goto! utility function to screen-based bidi routing support

--- src/main/workflo/macros/screen/bidi.cljs
+++ src/main/workflo/macros/screen/bidi.cljs
@@ -61,3 +61,8 @@
   (br/start-router! (routes)
                     {:on-navigate #(on-navigate env %)
                      :default-location {:handler default-screen}}))
+
+(defn goto!
+  [router screen params]
+  (let [location {:handler screen :route-params params}]
+    (br/set-location! router location)))


Fix clj tests

Fix clj tests

--- test/clojure/contrib/humanize_test.cljc
+++ test/clojure/contrib/humanize_test.cljc
@@ -8,9 +8,9 @@
             [clojure.contrib.inflect :refer [pluralize-noun]]
             #?(:clj [clojure.math.numeric-tower :refer [expt]])
             #?(:clj  [clj-time.core  :refer [now from-now seconds millis minutes
-                                             hours days weeks months years]]
+                                             hours days weeks months years plus]]
                :cljs [cljs-time.core :refer [now from-now seconds millis minutes
-                                             hours days weeks months years]])
+                                             hours days weeks months years plus]])
             #?(:clj  [clj-time.local  :refer [local-now]]
                :cljs [cljs-time.local :refer [local-now]])
             #?(:clj  [clj-time.coerce  :refer [to-date-time to-string]]
@@ -151,7 +151,7 @@

 (deftest datetime-test
   (let [past (fn [n unit] (datetime (now) :now-dt (-> n unit from-now)))
-        future (fn [n unit] (datetime (+ (-> n unit from-now) 300) ; fix delayed execution by adding some millis
+        future (fn [n unit] (datetime (plus (-> n unit from-now) (millis 300)) ; fix delayed execution by adding some millis
                                       :now-dt (now)))]
     (testing "date diff to text"
       (are [expected diff] (= expected diff)


Test external wait

Test external wait

--- test/com/wsscode/pathom/parser_test.clj
+++ test/com/wsscode/pathom/parser_test.clj
@@ -1,7 +1,7 @@
 (ns com.wsscode.pathom.parser-test
   (:require [clojure.test :refer [deftest is testing]]
             [clojure.core.async :as async :refer [go <! <!!]]
-            [com.wsscode.common.async-clj :refer [go-promise]]
+            [com.wsscode.common.async-clj :refer [let-chan go-promise]]
             [com.wsscode.pathom.parser :as pp]
             [com.wsscode.pathom.core :as p]
             [com.wsscode.pathom.connect :as pc]
@@ -59,6 +59,7 @@
 (defn r-ab-quick [_]
   {::pp/provides        #{:a :b}
    ::pp/response-stream (go
+                          (<! (async/timeout 10))
                           {::pp/provides       #{:a :b}
                            ::pp/response-value {:a 1 :b 2}})})

@@ -68,22 +69,26 @@
                           {::pp/provides       #{:a}
                            ::pp/response-value {}})})

+(defn r-b-dep [env]
+  (let-chan [b (p/entity-attr! env :b)]
+    (+ 10 b)))
+
 (defn r-async [_]
   (go :done))

 (def pparser (p/parallel-parser {}))
+
+(defn comparable-trace [trace]
+  (mapv #(dissoc % ::pt/timestamp ::pt/id) trace))
+
+(defn comparable-trace-set [trace]
+  (into #{} (map #(dissoc % ::pt/timestamp ::pt/id)) trace))

 (defn quick-reader
   ([reader] (quick-reader {} reader))
   ([env reader] (assoc env ::p/reader [p/map-reader reader])))

-(defn comparable-trace [trace]
-  (mapv #(dissoc % ::pt/timestamp ::pt/id) trace))
-
 (defonce trace (atom []))
-
-(comment
-  (comparable-trace @trace))

 (deftest test-parallel-parser
   (testing "returns blank channel on response"
@@ -107,33 +112,6 @@
             {:com.wsscode.pathom.core/path   []
              :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/value-return
              :key                            :a}
-            {:com.wsscode.pathom.core/path       []
-             :com.wsscode.pathom.trace/direction :com.wsscode.pathom.trace/leave
-             :com.wsscode.pathom.trace/event     :com.wsscode.pathom.parser/parse-loop}])))
-
-  (testing "async return"
-    (reset! trace [])
-    (is (= (<!! (pparser (quick-reader {::pt/trace* trace} {:a r-async})
-                  [:a]))
-           {:a :done}))
-    (is (= (comparable-trace @trace)
-           [{:com.wsscode.pathom.core/path       []
-             :com.wsscode.pathom.trace/direction :com.wsscode.pathom.trace/enter
-             :com.wsscode.pathom.trace/event     :com.wsscode.pathom.parser/parse-loop}
-            {:com.wsscode.pathom.core/path   []
-             :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/process-key
-             :key                            :a}
-            {:com.wsscode.pathom.core/path   []
-             :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/call-read
-             :key                            :a}
-            {:com.wsscode.pathom.core/path   []
-             :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/async-return
-             :key                            :a}
-            {:com.wsscode.pathom.core/path             []
-             :com.wsscode.pathom.parser/merge-result?  true
-             :com.wsscode.pathom.parser/provides       #{:a}
-             :com.wsscode.pathom.parser/response-value {:a :done}
-             :com.wsscode.pathom.trace/event           :com.wsscode.pathom.parser/process-pending}
             {:com.wsscode.pathom.core/path       []
              :com.wsscode.pathom.trace/direction :com.wsscode.pathom.trace/leave
              :com.wsscode.pathom.trace/event     :com.wsscode.pathom.parser/parse-loop}])))
@@ -169,6 +147,107 @@
              :com.wsscode.pathom.trace/direction :com.wsscode.pathom.trace/leave
              :com.wsscode.pathom.core/path       []}])))

+  (testing "async return"
+    (reset! trace [])
+    (is (= (<!! (pparser (quick-reader {::pt/trace* trace} {:a r-async})
+                  [:a]))
+           {:a :done}))
+    (is (= (comparable-trace @trace)
+           [{:com.wsscode.pathom.core/path       []
+             :com.wsscode.pathom.trace/direction :com.wsscode.pathom.trace/enter
+             :com.wsscode.pathom.trace/event     :com.wsscode.pathom.parser/parse-loop}
+            {:com.wsscode.pathom.core/path   []
+             :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/process-key
+             :key                            :a}
+            {:com.wsscode.pathom.core/path   []
+             :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/call-read
+             :key                            :a}
+            {:com.wsscode.pathom.core/path   []
+             :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/async-return
+             :key                            :a}
+            {:com.wsscode.pathom.core/path             []
+             :com.wsscode.pathom.parser/merge-result?  true
+             :com.wsscode.pathom.parser/provides       #{:a}
+             :com.wsscode.pathom.parser/response-value {:a :done}
+             :com.wsscode.pathom.trace/event           :com.wsscode.pathom.parser/process-pending}
+            {:com.wsscode.pathom.core/path       []
+             :com.wsscode.pathom.trace/direction :com.wsscode.pathom.trace/leave
+             :com.wsscode.pathom.trace/event     :com.wsscode.pathom.parser/parse-loop}])))
+
+  (testing "external wait"
+    (reset! trace [])
+    (is (= (<!! (pparser (quick-reader {::pt/trace* trace} {:b r-ab-quick :c r-b-dep})
+                  [:b :c]))
+           {:b 2 :c 12}))
+    (is (= (comparable-trace-set @trace)
+           #{{:com.wsscode.pathom.core/path             [:c]
+              :com.wsscode.pathom.parser/merge-result?  false
+              :com.wsscode.pathom.parser/provides       #{:b}
+              :com.wsscode.pathom.parser/response-value nil
+              :com.wsscode.pathom.trace/event           :com.wsscode.pathom.parser/process-pending}
+             {:com.wsscode.pathom.core/path       [:c]
+              :com.wsscode.pathom.trace/direction :com.wsscode.pathom.trace/enter
+              :com.wsscode.pathom.trace/event     :com.wsscode.pathom.parser/parse-loop}
+             {:com.wsscode.pathom.core/path       [:c]
+              :com.wsscode.pathom.trace/direction :com.wsscode.pathom.trace/leave
+              :com.wsscode.pathom.trace/event     :com.wsscode.pathom.parser/parse-loop}
+             {:com.wsscode.pathom.core/path   [:c]
+              :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/call-read
+              :key                            :b}
+             {:com.wsscode.pathom.core/path   [:c]
+              :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/external-wait-key
+              :key                            :b}
+             {:com.wsscode.pathom.core/path   [:c]
+              :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/process-key
+              :key                            :b}
+             {:com.wsscode.pathom.core/path   [:c]
+              :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/value-return
+              :key                            :b}
+             {:com.wsscode.pathom.core/path             []
+              :com.wsscode.pathom.parser/merge-result?  false
+              :com.wsscode.pathom.parser/provides       #{:a
+                                                          :b}
+              :com.wsscode.pathom.parser/response-value {:a 1
+                                                         :b 2}
+              :com.wsscode.pathom.trace/event           :com.wsscode.pathom.parser/process-pending}
+             {:com.wsscode.pathom.core/path             []
+              :com.wsscode.pathom.parser/merge-result?  true
+              :com.wsscode.pathom.parser/provides       #{:c}
+              :com.wsscode.pathom.parser/response-value {:c 12}
+              :com.wsscode.pathom.trace/event           :com.wsscode.pathom.parser/process-pending}
+             {:com.wsscode.pathom.core/path       []
+              :com.wsscode.pathom.parser/provides #{:a
+                                                    :b}
+              :com.wsscode.pathom.trace/event     :com.wsscode.pathom.parser/provided-return}
+             {:com.wsscode.pathom.core/path            []
+              :com.wsscode.pathom.parser/watcher-count 1
+              :com.wsscode.pathom.trace/event          :com.wsscode.pathom.parser/flush-watchers
+              :key                                     :b}
+             {:com.wsscode.pathom.core/path       []
+              :com.wsscode.pathom.trace/direction :com.wsscode.pathom.trace/enter
+              :com.wsscode.pathom.trace/event     :com.wsscode.pathom.parser/parse-loop}
+             {:com.wsscode.pathom.core/path       []
+              :com.wsscode.pathom.trace/direction :com.wsscode.pathom.trace/leave
+              :com.wsscode.pathom.trace/event     :com.wsscode.pathom.parser/parse-loop}
+             {:com.wsscode.pathom.core/path   []
+              :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/async-return
+              :key                            :c}
+             {:com.wsscode.pathom.core/path   []
+              :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/call-read
+              :key                            :b}
+             {:com.wsscode.pathom.core/path   []
+              :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/call-read
+              :key                            :c}
+             {:com.wsscode.pathom.core/path   []
+              :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/process-key
+              :key                            :b}
+             {:com.wsscode.pathom.core/path   []
+              :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/process-key
+              :key                            :c}
+             {:com.wsscode.pathom.core/path   []
+              :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/value-return
+              :key                            :b}})))
+
   (testing "max key iterations"
     (reset! trace [])
     (is (= (<!! (pparser (quick-reader {::pt/trace* trace} {:a r-provide-miss})


add plural forms of reflexive present verbs

--- src/babel/francais/morphology.cljc
+++ src/babel/francais/morphology.cljc
@@ -528,7 +528,8 @@

 (def replace-patterns
   [
-   ;; pronouns: e.g.: "t'" => "te"
+   ;; pronouns: e.g.: "t'" => "te". The apostrophe (')
+   ;; is already removed by the tokenizer.
    [#"^([jlmst])" "$1e" :top]
    [#"^(l)" "$1a" :top]

@@ -605,6 +606,21 @@
                                  :person :3rd}}}
               :infl :present}}]

+   [#"^([aeéiou]\S+)ons$" "s'$1er"
+    {:synsem {:subcat {:1 {:agr {:number :plur
+                                 :person :1st}}}
+              :infl :present}}]
+
+   [#"^([aeéiou]\S+)ez$" "s'$1er"
+    {:synsem {:subcat {:1 {:agr {:number :plur
+                                 :person :2nd}}}
+              :infl :present}}]
+
+   [#"^([aeéiou]\S+)ent$" "s'$1er"
+    {:synsem {:subcat {:1 {:agr {:number :plur
+                                 :person :3rd}}}
+              :infl :present}}]
+
    [#"^([^aeéiou]\S+)e$" "se $1er"
     {:synsem {:subcat {:1 {:agr {:number :sing
                                  :person :1st}}}
@@ -619,6 +635,22 @@
     {:synsem {:subcat {:1 {:agr {:number :sing
                                  :person :3rd}}}
               :infl :present}}]
+
+   [#"^([^aeéiou]\S+)ons$" "s'$1er"
+    {:synsem {:subcat {:1 {:agr {:number :plur
+                                 :person :1st}}}
+              :infl :present}}]
+
+   [#"^([^aeéiou]\S+)ez$" "s'$1er"
+    {:synsem {:subcat {:1 {:agr {:number :plur
+                                 :person :2nd}}}
+              :infl :present}}]
+
+   [#"^([^aeéiou]\S+)ent$" "s'$1er"
+    {:synsem {:subcat {:1 {:agr {:number :plur
+                                 :person :3rd}}}
+              :infl :present}}]
+
    ;; </reflexive present -er and -ir type verbs>

    ;; <present non-reflexive>


Clean up a misappropriate if-let usage

Clean up a misappropriate if-let usage

Signed-off-by: Gregory Haskins <640d9fe47775e6723f0355b7315e38f7d98d3539@gmail.com>

--- src/obcc/core.clj
+++ src/obcc/core.clj
@@ -101,7 +101,7 @@
                ""
                (str "Description: obcc " (:name subcommand) " - " (:desc subcommand))
                ""
-               (str "Usage: obcc " (:name subcommand) " [options] " (if-let [arguments (:arguments subcommand)] arguments ""))
+               (str "Usage: obcc " (:name subcommand) " [options] " (when-let [arguments (:arguments subcommand)] arguments))
                ""
                "Command Options:"
                options-summary


Style message embeds

Style message embeds

--- src/braid/client/mobile/style.cljs
+++ src/braid/client/mobile/style.cljs
@@ -12,6 +12,7 @@
             [braid.client.ui.styles.thread]
             [braid.client.ui.styles.body]
             [braid.client.ui.styles.message]
+            [braid.client.ui.styles.embed]
             [braid.client.ui.styles.mixins :as mixins]))

 (def styles
@@ -90,6 +91,7 @@
            [:.messages
             ;{:height "50vh"}
             {:flex-grow 1}
+           (braid.client.ui.styles.embed/embed pad)
             ]

            (braid.client.ui.styles.thread/new-message pad)


Add comments link to retrieve comments for entries (count is currently just an example).

--- src/oc/storage/representations/entry.clj
+++ src/oc/storage/representations/entry.clj
@@ -54,6 +54,11 @@
     (hateoas/link-map "comment" hateoas/POST comment-url {:content-type mt/comment-media-type
                                                           :accept mt/comment-media-type})))

+(defn- comments-link [org-uuid board-uuid topic-slug entry-uuid]
+  (let [comment-url (str config/interaction-server-url (url org-uuid board-uuid topic-slug entry-uuid) "/comments")]
+    (hateoas/link-map "comments" hateoas/GET comment-url {:accept mt/comment-collection-media-type}
+                                                          {:count 5}))) ; TODO comment count
+
 (defn- entry-collection-links
   [entry entry-count entry-uuid board-slug org-slug access-level]
   (let [topic-slug (name (:topic-slug entry))
@@ -80,10 +85,12 @@
                                    (delete-link org-slug board-slug entry entry-uuid)
                                    (create-link org-slug board-slug topic-slug)
                                    (archive-link org-slug board-slug topic-slug)
-                                   (comment-link org-uuid board-uuid topic-slug entry-uuid)])
+                                   (comment-link org-uuid board-uuid topic-slug entry-uuid)
+                                   (comments-link org-uuid board-uuid topic-slug entry-uuid)])

                     (= access-level :viewer)
-                    (conj links (comment-link org-slug board-slug topic-slug entry-uuid))
+                    (concat links [(comment-link org-slug board-slug topic-slug entry-uuid)
+                                   (comments-link org-uuid board-uuid topic-slug entry-uuid)])

                     :else links)]
     (assoc (select-keys entry representation-props) :links full-links)))


darken the auto-generated tags a bit

darken the auto-generated tags a bit

--- src/chat/client/views/helpers.cljs
+++ src/chat/client/views/helpers.cljs
@@ -10,7 +10,7 @@
                        (.substring 33 36)
                        (js/parseInt 16)
                        (/ 4096))]
-    (str "hsl(" (* 360 normalized) ",60%,60%)")))
+    (str "hsl(" (* 360 normalized) ",70%,35%)")))

 (defn format-message
   "Given the text of a message body, turn it into dom nodes, making urls into


make get-document-transactions return things that look more like transactions

--- src/pc/replay.clj
+++ src/pc/replay.clj
@@ -4,15 +4,6 @@
             [pc.datomic.schema :as schema]
             [pc.datomic.web-peer :as web-peer])
   (:import java.util.UUID))
-
-(defn get-document-transactions
-  "Gets the broadcasted transactions for a document"
-  [db doc]
-  (map #(d/entity db (first %))
-       (d/q '{:find [?t]
-              :in [$ ?doc-id]
-              :where [[?t :transaction/document ?doc-id]]}
-            db (:db/id doc))))

 (defn- ->datom
   [[e a v tx added]]
@@ -26,6 +17,24 @@
     (map ->datom)
     set))

+(defn get-document-transactions
+  "Returns a lazy sequence of transactions for a document in order of db/txInstant.
+   Has :tx-data and :db-after fields"
+  [db doc]
+  (map (fn [e]
+         (let [tx (d/entity db e)]
+           {:tx-data (tx-data tx)
+            :db-after (d/as-of db (:db/txInstant tx))}))
+       (map first
+            (sort-by second
+                     (d/q '{:find [?t ?tx]
+                            :in [$ ?doc-id]
+                            :where [[?t :transaction/document ?doc-id]
+                                    [?t :db/txInstant ?tx]]}
+                          db (:db/id doc))))))
+
+
+
 (defn replace-frontend-ids [db doc-id txes]
   (let [a (d/entid db :frontend/id)]
     (map (fn [tx]
@@ -36,13 +45,14 @@
              tx))
          txes)))

+
+
 (defn copy-transactions [db doc new-doc & {:keys [sleep-ms]
                                            :or {sleep-ms 1000}}]
   (let [conn (pcd/conn)
         tx-datas (->> (get-document-transactions db doc)
-                   (sort-by :db/txInstant)
                    (map (fn [t]
-                          (->> (tx-data t)
+                          (->> (:tx-data t)
                             (remove #(= (:e %) (:db/id t)))
                             (map #(if (= (:v %) (:db/id doc))
                                     (assoc % :v (:db/id new-doc))


actually use the session key

actually use the session key

--- src/pc/server.clj
+++ src/pc/server.clj
@@ -132,7 +132,7 @@
    (app sente-state)
    (sente/wrap-user-id)
    (wrap-anti-forgery)
-   (wrap-session {:store (cookie-store)
+   (wrap-session {:store (cookie-store {:key (profile/http-session-key)})
                   :cookie-attrs {:http-only true
                                  :expires (time-format/unparse (:rfc822 time-format/formatters) (time/from-now (time/years 1))) ;; expire one year after the server starts up
                                  :max-age (* 60 60 24 365)


add button role to fix iOS anchor bug

add button role to fix iOS anchor bug

--- frontend/components/build.cljs
+++ frontend/components/build.cljs
@@ -57,6 +57,7 @@
              status (container-model/status container build-running?)]
         [:a.container-selector
          {:on-click #(put! controls-ch [:container-selected {:container-id container-id}])
+          :role "button"
           :class (concat (container-model/status->classes status)
                          (when (= container-id current-container-id) ["active"]))}
          (str (:index container))


little cleanup

little cleanup

Signed-off-by: Chris Granger <5654cde260ae99bc4d30054171b8bcd902efd19a@gmail.com>

--- src/lt/objs/deploy.cljs
+++ src/lt/objs/deploy.cljs
@@ -22,17 +22,13 @@
 (def targz (load/node-module "tar.gz"))
 (def request (load/node-module "request"))
 (def tar (load/node-module "tar"))
-(def cur-path (.pwd shell))
 (def home-path (files/lt-home ""))
 (def get-proxy (.-App.getProxyForURL (js/require "nw.gui")))

 (def version-regex #"^\d+\.\d+\.\d+(-.*)?$")

-(defn in-lt [path]
-  (str home-path "/" path))
-
 (defn get-versions []
-  (let [vstr (:content (files/open-sync (in-lt "core/version.json")))]
+  (let [vstr (:content (files/open-sync (files/lt-home "core/version.json")))]
     (js->clj (.parse js/JSON vstr) :keywordize-keys true)))

 (defn proxy? []


Fix fix fix...

Fix fix fix...

--- src/clj_simple_chart/axis/core.clj
+++ src/clj_simple_chart/axis/core.clj
@@ -120,7 +120,7 @@
        (map (fn [d] [:g {:transform (translate 0 (center-point scale d))}
                      (opentype/text
                        (apply-axis-text-style-fn {:x         (- (* sign 6)
-                                                                (if (= :right direction)
+                                                                (if (= 1 sign)
                                                                   0
                                                                   axis-label-max-width))
                                                   :dy        ".32em"


Fix precondition for flat-list

Fix precondition for flat-list

The flat-list component handles the nil case but the precondition does
not.

This is currently causing transaction list failures when the list of
unsigned transactions is empty.

--- src/status_im/components/list/views.cljs
+++ src/status_im/components/list/views.cljs
@@ -86,7 +86,8 @@
   "A wrapper for FlatList.
    See https://facebook.github.io/react-native/docs/flatlist.html"
   [{:keys [data render-fn empty-component] :as props}]
-  {:pre [(sequential? data)]}
+  {:pre [(or (nil? data)
+             (sequential? data))]}
   (if (and (empty? data) empty-component)
     ;; TODO(jeluard) remove when native :ListEmptyComponent is supported
     empty-component


[#10005] Show only 1 line of ens name

[#10005] Show only 1 line of ens name

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

--- src/status_im/ui/screens/chat/utils.cljs
+++ src/status_im/ui/screens/chat/utils.cljs
@@ -14,7 +14,8 @@
 (defn format-author [alias style name]
   (let [additional-styles (style false)]
     (if name
-      [react/text {:style (merge {:color       colors/blue
+      [react/text {:number-of-lines 1
+                   :style (merge {:color       colors/blue
                                   :font-size   13
                                   :line-height 18
                                   :font-weight "500"} additional-styles)}


validators

validators


Add missing requies

Add missing requies

--- src/app/middleware.cljs
+++ src/app/middleware.cljs
@@ -1,4 +1,9 @@
-(ns app.middleware)
+(ns app.middleware
+  (:require [schema.core :as s :include-macros true]
+            [app.db :as db]
+            [re-frame.core :refer [after path
+                                   trim-v debug]]))
+

 ;; re-frame handler middleware


fix issue with card desactivation

fix issue with card desactivation

--- src/node/game/core.cljs
+++ src/node/game/core.cljs
@@ -65,7 +65,7 @@
     (let [dest (if (sequential? to) (vec to) [to])
           c (if (and (= side :corp) (= (first dest) :discard) (:rezzed card))
               (assoc card :seen true) card)
-          c (if (#{:discard :hand :deck :rfg} (first dest))
+          c (if (#{:servers :rig :scored} (first zone))
               (desactivate state side c) c)
           moved-card (assoc c :zone dest)]
       (if front


Allow requests from localhost:8080

Allow requests from localhost:8080

--- src/obb_api/service.clj
+++ src/obb_api/service.clj
@@ -58,6 +58,7 @@
               ::bootstrap/allowed-origins ["http://orionsbelt.eu"
                                            "http://orionsbelt-battlegrounds.github.io"
                                            "http://localhost:10555"
+                                           "http://localhost:8080"
                                            "http://localhost"]

               ;; Root for resource interceptor that is available by default.


Remove slack report for already bounced recipients, keep only alerts for new bounces.

--- src/oc/email/mailer.clj
+++ src/oc/email/mailer.clj
@@ -64,8 +64,7 @@
         :message {:subject subject
                   :body html-body}))
     (when error-msg
-      (timbre/warn error-msg)
-      (slack-lib/slack-report error-msg))))
+      (timbre/warn error-msg))))

 (defn- email-entry
   "Send emails to all to recipients in parallel."


Chance subject copy.

Chance subject copy.

--- src/oc/email/mailer.clj
+++ src/oc/email/mailer.clj
@@ -110,7 +110,7 @@
                   (assoc :source default-source)
                   (assoc :from default-from)
                   (assoc :reply-to default-reply-to)
-                  (assoc :subject (str "Carrot 🔔 Reminder about your " (:name (:org message)) " post")))]
+                  (assoc :subject (str "🔔 Reminder about your " (:name (:org message)) " post")))]
     (try
       (spit html-file (content/reminder-alert-html reminder)) ; create the email in a tmp file
       (inline-css html-file inline-file) ; inline the CSS


Added Reset Password button

Added Reset Password button

--- src/webapp/client/views/login_panel.cljs
+++ src/webapp/client/views/login_panel.cljs
@@ -22,6 +22,42 @@
 )

+
+
+
+
+
+
+
+
+(defn forgot-password-panel []
+  (el :form {:class "form-inline" :style "padding: 5px"}
+      [
+       (el :div {:class "form-group"} [
+        "<input  id='username-input' type='email' class='input-small form-control' placeholder='Email'>"
+        ])
+
+       (el :button {
+                     :id       "reset-password-button"
+                     :type     "button"
+                     :class    "btn btn-primary"
+                     :style    "margin-left: 10px;"
+                     :text     "Reset my password"
+                     :onclick  #(do-action "Reset password"
+                                           {
+                                            :username    (value-of "username-input")
+                                            })})
+
+        (el :button {
+                     :type "button"
+                     :class "btn btn-info"
+                     :style "margin-left: 10px;"
+                     :text "Cancel"
+                     :onclick #(do-action "show login signup panel")})
+
+      ]
+  )
+)

@@ -163,11 +199,29 @@
                                                 ($ :#top-right)
                                                 (signup-panel))
                            :onmouseover #(show-popover "signup-button"
-                                                       "Use this if you want to create an account"
+                                                       "
Use this if you want to create an account"
                                                        {:placement "left"})
                            :onmouseout #(hide-popovers)
                            })
+
+        (el :button
+                          {:id    "forgot-password-button"
+                           :style "margin: 5px; "
+                           :class "btn btn-default"
+                           :text "Forgot password?"
+                           :onclick #(swap-section
+                                                ($ :#top-right)
+                                                (forgot-password-panel))
+                           :onmouseover #(show-popover "forgot-password-button"
+                                                       "

Use this if you think you have created an
+                                                       account and you want to reset your password"
+                                                       {:placement "left"})
+                           :onmouseout #(hide-popovers)
+                           })
+
+
               ])
+
   )


Potential fix for #9

Potential fix for #9

--- src/fink_nottle/sqs/channeled.cljc
+++ src/fink_nottle/sqs/channeled.cljc
@@ -1,30 +1,30 @@
 (ns fink-nottle.sqs.channeled
   (:require [fink-nottle.sqs :as sqs]
             [fink-nottle.internal.util :as util]
-            [glossop.util :refer [onto-chan?]]
             [glossop.core #? (:clj :refer :cljs :refer-macros) [go-catching <?]]
-            #? (:clj
-                [clojure.core.async :as a :refer [>! alt!]]
-                :cljs
-                [cljs.core.async :as a :refer [>!]]))
+            #?@ (:clj
+                 [[clojure.core.async :as a :refer [>! alt!]]
+                  [clojure.core.async.impl.protocols :as async-protocols]]
+                 :cljs
+                 [[cljs.core.async :as a :refer [>!]]
+                  [cljs.core.async.impl.protocols :as async-protocols]]))
   #? (:cljs (:require-macros [cljs.core.async.macros :refer [alt!]])))

 (defn receive! [creds queue-url & [params {:keys [chan close?] :or {close? true}}]]
   (let [{:keys [maximum] :as params} (merge {:maximum 10 :wait-seconds 20} params)
         chan (or chan (a/chan maximum))]
     (go-catching
-      (loop []
-        (let [messages (try
-                         (<? (sqs/receive-message! creds queue-url params))
-                         (catch #? (:clj Exception :cljs js/Error) e
-                           (>! chan e)
-                           ::error))]
-          (if (and (not= messages ::error)
-                   (or (empty? messages)
-                       (<? (onto-chan? chan messages))))
-            (recur)
-            (when close?
-              (a/close! chan))))))
+      (try
+        (loop []
+          (let [messages (<? (sqs/receive-message! creds queue-url params))]
+            (when-not (empty? messages)
+              (<? (a/onto-chan chan messages false)))
+            (when-not (async-protocols/closed? chan)
+              (recur))))
+        (catch #? (:clj Exception :cljs js/Error) e
+          (>! chan e)))
+      (when close?
+        (a/close! chan)))
     chan))

 (defn identify-batch [messages]
@@ -43,7 +43,7 @@
         (when-let [exs (some->> failed vals (map failure->throwable) not-empty)]
           (<? (a/onto-chan error-chan exs false))))
       (catch #? (:clj Exception :cljs js/Error) e
-        (>! error-chan e)))))
+             (>! error-chan e)))))

 (defn- batch-cleanup! [issue-fn batch error-chan close?]
   (go-catching


fix (generate)'s handling a spec which is a sequence

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -45,17 +45,24 @@
 (defn generate [spec grammar lexicon index morph]
   (cond (or (vector? spec)
             (seq? spec))
-        (first (take 1
-                     (map (fn [each-spec]
-                            (log/info (str "generate: generating from spec: "
-                                           (strip-refs each-spec)))
-                            (let [expression
-                                  (generate each-spec grammar lexicon index morph)]
-                              (log/info (str "generate: expression generated for spec:"
-                                             (strip-refs each-spec) ":"
-                                             "'" (morph expression) "'"))
-                              expression))
-                          spec)))
+        (do
+          (log/debug (str "generating from " (count spec) " spec(s)"))
+          (let [expression
+                (first (take 1
+                             (mapcat (fn [each-spec]
+                                       (log/info (str "generate: generating from spec: "
+                                                      each-spec))
+                                       (let [expressions
+                                             (generate-all each-spec grammar lexicon index morph)]
+                                         expressions))
+                                     spec)))]
+            (if expression
+              (log/info (str "generate: generated "
+                             "'" (morph expression) "'"
+                             " from " (count spec) " spec(s)"))
+              (log/info (str "generate: no expression could be generated for any of the "
+                             " from " (count spec) " spec(s)")))
+            expression))

         (empty? grammar)
         (do


add log/debug

add log/debug

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -177,9 +177,11 @@
   (log/debug (str "generate2: spec: " spec))
   (let [depth 0
         max-depth max-total-depth]
-    (flatten
-     (mapfn #(add-bolt-at % % [] % model depth max-depth truncate-children)
-            (lightning-bolts model spec 0 max-total-depth)))))
+     (flatten
+      (mapfn #(do
+                (log/debug (str "top-level add-bolt-at: " ((:morph-ps model) %)))
+                (add-bolt-at % % [] % model depth max-depth truncate-children))
+             (lightning-bolts model spec 0 max-total-depth)))))

 (defn generate-n
   "Returns all possible expressions generated by the given language model, constrained by the given spec.


s/lazy-shuffle/shuffle/; remove unnecessary (let) variable

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -90,7 +90,6 @@
 such that only the head children are generated. This sequence is used by (generate (above))
 to generate expressions by adding complements using (add-all-comps)."
   (let [grammar (:grammar language-model)
-        index (:index language-model)
         depth (if depth depth 0)
         ;; this is the relative depth; that is, the depth from the top of the current lightning bolt.
         ;; total-depth, on the other hand, is the depth all the way to the top of the entire
@@ -108,8 +107,8 @@
                              (and (not (= :top pred)) (not (empty? pred-set))
                                   (not (= :top cat)) (not (empty? cat-set)))
                              (intersection-with-identity pred-set cat-set)
-                             true (get-lex parent :head index))]
-                       (over/overh parent (shuffle subset))))
+                             true (get-lex parent :head (:index language-model)))]
+                       (over/overh parent (lazy-shuffle subset))))
                    parents))
           phrasal ;; 2. generate list of all phrases where the head child of each parent is itself a phrase.
           (if (and (< total-depth max-total-depth)


use mapfn to switch between (map) and (pmap)

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -12,6 +12,7 @@
                                         strip-refs show-spec unify unifyc)]))
 ;; during generation, will not search deeper than this:
 (def ^:const max-total-depth 5)
+(def ^:const mapfn pmap)

 (declare add-complement)
 (declare lexemes-before-phrases)
@@ -94,7 +95,7 @@
       (log/debug (str "lightning-bolt(depth=" depth ", total-depth=" total-depth "): sem:" (strip-refs (get-in spec [:synsem :sem]))))
       (let [morph (if morph morph (fn [input] (get-in input [:rule] :default-morph-no-rule)))
             depth (if depth depth 0)
-            parents (filter #(not (fail? %)) (pmap (fn [rule] (unifyc spec rule)) grammar))]
+            parents (filter #(not (fail? %)) (mapfn (fn [rule] (unifyc spec rule)) grammar))]
         (let [lexical ;; 1. generate list of all phrases where the head child of each parent is a lexeme.
               (mapcat (fn [parent]
                         (if (= false (get-in parent [:head :phrasal] false))
@@ -148,7 +149,7 @@
                                   ",path=" path ",bolt=(" (show-bolt bolt path morph) ")=>"
                                   "'" (morph complement) "'"))
                   true)))
-            (pmap (fn [complement]
+            (mapfn (fn [complement]
                     (unify (copy bolt)
                            (path-to-map path
                                         (copy complement))))


improve logging

improve logging

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -179,27 +179,48 @@
   ;; Each head child may be a leaf or
   ;; otherwise has a child with the same two options (leaf or a head child),
   ;; up to the maximum depth.
-  (log/debug (str "lightning-bolts: depth=" depth (if use-candidate-parents
-                                                    (str "; using ucp: " (count use-candidate-parents)))))
+  (log/debug (str "lightning-bolts: depth="
+                  depth (if use-candidate-parents
+                          (str "; using ucp: "
+                               (count use-candidate-parents)))))
   (if (and (< depth max-depth)
            (not (= false (get-in spec [:phrasal] true))))
-    (let [candidate-parents (or use-candidate-parents
-                                (->>
-                                 (:grammar model)
-                                 (map (fn [rule]
-                                        (let [result (unify rule spec)]
-                                          (if
-                                            (not (= :fail result))
-                                            (log/debug (str "rule:" (:rule rule)
-                                                            " => "
-                                                            "OK")))
-                                          result)))
-                                 (filter #(not (= :fail %)))
-                                 (shufflefn)))]
-      (log/debug (str "candidate-parents emptiness at depth:" depth ":"
-                      (empty? candidate-parents)))
+    (let [candidate-parents
+          (or use-candidate-parents
+              (let [filtered
+                    (->>
+                     (:grammar model)
+                     (map (fn [rule]
+                            (let [result (unify rule spec)]
+                              (cond (= :fail result)
+                                    (log/debug (str "rule:" (:rule rule)
+                                                    " => "
+                                                    "FAIL between:"
+                                                    (:rule rule)
+                                                    " and: "
+                                                    (strip-refs spec)
+                                                    "; fail path:"
+                                                    (dag_unify.core/fail-path
+                                                     rule
+                                                     spec)))
+                                    true
+                                    (log/debug (str "rule:" (:rule rule)
+                                                    " => "
+                                                    "OK")))
+                              result)))
+                     (filter #(not (= :fail %)))
+                     (shufflefn))]
+                (if (empty? filtered)
+                  (log/debug (str "no rules found for spec:"
+                                  (dag_unify.core/strip-refs spec)
+                                  " at depth: " depth)))
+                filtered))]
       (if (not (empty? candidate-parents))
         (let [candidate-parent (first candidate-parents)]
+          (log/debug (str "creating bolts with: "
+                          (:rule candidate-parent)
+                          " and spec: " (dag_unify.core/strip-refs
+                                         (get-in candidate-parent [:head]))))
           (lazy-cat
            (->> (lightning-bolts model
                                  (get-in candidate-parent [:head])
@@ -208,11 +229,15 @@
                 (map (fn [head]
                        (assoc-in candidate-parent [:head] head))))
            (lightning-bolts model spec depth max-depth (rest candidate-parents))))
-        (do
-          (log/debug (str "no rules found at depth: " depth " for spec: "
-                          (dag_unify.core/strip-refs spec)))
-          candidate-parents)))
-    (shufflefn (get-lexemes model spec))))
+        []))
+    (let [lexemes
+          (shufflefn (get-lexemes model spec))]
+      (if (empty? lexemes)
+        (log/debug (str "lightning-bolts: no lexemes at depth: " depth
+                        " for spec: " (dag_unify.core/strip-refs spec)))
+        (log/debug (str "lightning-bolts: one or more lexemes at depth: " depth
+                        " for spec: " (dag_unify.core/strip-refs spec))))
+      lexemes)))

 (defn add-comps-to-bolt
   "bolt + paths => trees"


instrumenting/logging

instrumenting/logging

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -138,17 +138,18 @@
                 morph))))

 (defn generate-all [spec grammar lexicon index morph & [total-depth]]
-  (log/debug (str "generate-all: generating from spec: "
-                 (strip-refs spec)))
+  (log/debug (str "generate-all: generating from spec with cat "
+                  (get-in spec [:synsem :cat])))
   (if (= false (get-in spec [:phrasal] true))
-    nil
+    (exception (str "do not call generate-all with spec:[phrasal=true]"))
     ;; else, phrasal:
     (let [total-depth (if total-depth total-depth 0)
           add-complements-to-bolts
           (fn [bolts path]
             (log/debug (str "generate-all: "
-                            "add-complements-to-bolts@" path ": first bolt:"
-                            (show-bolt (first bolts) path morph)))
+                            "add-complements-to-bolts: "
+                            (show-bolt (first bolts) path morph)
+                            "@" path))
             (mapcat
              #(if (not (= :none (get-in % path :none)))
                 (lazy-seq (add-complement % path :top grammar lexicon index morph 0 (+ total-depth (count path))))
@@ -161,7 +162,7 @@
                                lexicon
                                spec 0 index morph total-depth)
                ;; TODO: allow more than a fixed maximum depth of generation (here, 4 levels from top of tree).
-               (add-complements-to-bolts [:head :head :head :comp] )
+               (add-complements-to-bolts [:head :head :head :comp])
                (add-complements-to-bolts [:head :head :comp])
                (add-complements-to-bolts [:head :comp])
                (add-complements-to-bolts [:comp])))]
@@ -182,7 +183,7 @@
                                  (first spec)
                                  spec)))]
           (log/error error-message)
-          (exception error-message)))
+          (if false (exception error-message))))
       (map (fn [expr]
              (truncate expr [[:head][:comp]]))
            expressions))))
@@ -210,11 +211,9 @@
 head of its parent. generate (above) 'decorates' each returned lightning bolt
 of this function with complements."
   (if (or (vector? spec) (seq? spec))
-    (mapcat (fn [each-spec]
-              (lightning-bolt grammar lexicon each-spec depth index morph total-depth))
-            spec)
+    (exception (str "don't call (lightning-bolt) with a vector of specs."))
     (do
-      (log/debug (str "lightning-bolt(depth=" depth "; total-depth=" total-depth "; cat=" (get-in spec [:synsem :cat]) "; spec=" (strip-refs spec) ")"))
+      (log/trace (str "lightning-bolt(depth=" depth "; total-depth=" total-depth "; cat=" (get-in spec [:synsem :cat]) "; spec=" (strip-refs spec) ")"))
       (let [morph (if morph morph (fn [input] (get-in input [:rule] :default-morph-no-rule)))
             depth (if depth depth 0)
             parents (candidate-parents grammar spec)]
@@ -225,14 +224,16 @@
                                 results (filter #(not (nil? %))
                                                 (over/overh parent (mapfn copy candidate-lexemes)))]
                             (log/debug (str "lightning-bolt: " (get-in parent [:rule])
-                                            ": first candidate head lexeme:'"
+                                            ": first candidate head lexeme:"
                                             (let [fo (morph (first candidate-lexemes))]
                                               (if (or (nil? fo)
                                                       (= '' (trim fo)))
-                                                (str "NOTHING: '" (get-in (first candidate-lexemes)
-                                                                          [:english :english]) "'")
-                                                (str fo)))
-                                            "'"))
+                                                (str
+                                                 "'"
+                                                 (get-in (first candidate-lexemes)
+                                                         [:english :english])
+                                                 "'")
+                                                (str fo)))))
                             results)))
                       parents)
               phrasal ;; 2. generate list of all phrases where the head child of each parent is itself a phrase.
@@ -245,6 +246,29 @@
           (if (lexemes-before-phrases total-depth)
             (concat lexical phrasal)
             (concat phrasal lexical)))))))
+
+(defn morph-with-recovery [morph-fn input]
+  (if (nil? input)
+    (exception (str "don't call morph-with-recovery with input=nil.")))
+  (let [result (morph-fn input)
+        result (if (or (nil? result)
+                       (= "" result))
+                 (get-in input [:english :english] "")
+                 (str "r1: " result))
+        result (if (or (nil? result)
+                       (= "" result))
+                 (get-in input [:english] "")
+                 (str "r2: " result))
+        result (if (or (nil? result)
+                       (= "" result))
+                 (get-in input [:rule] "")
+                 (str "r3: " result))
+        result (if (or (nil? result)
+                       (= "" result))
+                 (exception
+                  (str "r5: " input "/" (nil? input)))
+                 result)]
+    result))

 (defn add-complement [bolt path spec grammar lexicon cache morph depth total-depth]
   (log/debug (str "add-complement: " (show-bolt bolt path morph)))
@@ -272,20 +296,20 @@
                                              complement-candidate-lexemes)
         debug (log/debug
                (if (not (empty? filtered-lexical-complements))
-                 (str "add-complement: " (show-bolt bolt path morph) ":candidate first complement-lexemes:'"
+                 (str "add-complement: candidate first complement-lexemes:'"
                       (morph (first filtered-lexical-complements)) "'")))]
     (filter (fn [complement]
               (if (fail? complement)
                 (do
-                  (log/trace (str "add-complement(depth=" depth ",total-depth=" total-depth
+                  (log/debug (str "add-complement(depth=" depth ",total-depth=" total-depth
                                   ",path=" path ",bolt=(" (show-bolt bolt path morph) ") FAILED:"
-                                  "'" (morph complement) "'"))
+                                  "'" (morph-with-recovery morph complement) "'"))

                   false)
                 (do
-                  (log/trace (str "add-complement(depth=" depth ",total-depth=" total-depth
+                  (log/debug (str "add-complement(depth=" depth ",total-depth=" total-depth
                                   ",path=" path ",bolt=(" (show-bolt bolt path morph) ")=>"
-                                  "'" (morph complement) "'"))
+                                  "'" (morph-with-recovery morph complement) "'"))
                   true)))
             (mapfn (fn [complement]
                     (unify (copy bolt)
@@ -363,9 +387,11 @@
     false))

 (defn show-bolt [bolt path morph]
-  (if (not (empty? path))
-    (str (get-in bolt [:rule])
-         " '" (morph bolt) "' "
-         (let [rest-str (show-bolt (get-in bolt [:head]) (rest path) morph)]
-           (if (not (nil? rest-str))
-             (str " -> " rest-str))))))
+  (if (nil? bolt)
+    (exception (str "don't call show-bolt with bolt=null."))
+    (if (not (empty? path))
+      (str "[" (get-in bolt [:rule])
+           " '" (morph-with-recovery morph bolt) "' "
+           (let [rest-str (show-bolt (get-in bolt [:head]) (rest path) morph)]
+             (if (not (nil? rest-str))
+               (str " -> " rest-str  "]")))))) )


amount-of-money new format

amount-of-money new format

--- src/picsou/time/api.clj
+++ src/picsou/time/api.clj
@@ -41,11 +41,14 @@
                          {:normalized {:value (t/period->duration value)
                                        :unit "second"}}))

-      :temperature (merge {:type "value" :value value}
-                          (select-keys token [:unit]))
+      :temperature  (merge {:type "value" :value value}
+                           (select-keys token [:unit]))

-      :distance (merge {:type "value" :value value}
-                          (select-keys token [:unit]))
+      :distance     (merge {:type "value" :value value}
+                           (select-keys token [:unit]))
+
+      :amount-of-money  (merge {:type "value" :value value}
+                               (select-keys token [:unit]))

       :quantity (select-keys token [:value :unit :product])


remove warn-on-reflection

remove warn-on-reflection

--- src/cheshire/custom.clj
+++ src/cheshire/custom.clj
@@ -7,7 +7,7 @@
            (org.codehaus.jackson JsonFactory JsonGenerator JsonParser
                                  JsonParser$Feature)))

-(set! *warn-on-reflection* true)
+;;(set! *warn-on-reflection* true)

 (def ^{:private true :tag JsonFactory} factory
   (doto (JsonFactory.)


fixed GOS typo

fixed GOS typo


evolving typo in how we developed this site


just reorder a bit

just reorder a bit

--- src/prometheus/core.clj
+++ src/prometheus/core.clj
@@ -34,13 +34,6 @@

 (defn- ^Histogram$Child histogram-with-labels [^Histogram histogram label-array] (.labels histogram (into-array String label-array)))

-(defn- record-request-metric [counter histogram request-method response-status request-time response-path]
-  (let [status-class (str (int (/ response-status 100)) "XX")
-        method-label (string/upper-case (name request-method))
-        labels [method-label (str response-status) status-class response-path]]
-    (-> (histogram-with-labels histogram labels) (.observe request-time))
-    (-> (counter-with-labels counter labels) (.inc))))
-
 (defn- ^Counter make-counter [^CollectorRegistry registry namespace metric help label-names]
   (-> (Counter/build)
       (.namespace namespace)
@@ -66,21 +59,22 @@
       (.help help)
       (.register registry)))

-(defn set-gauge
-  "Set the value of a registered gauge."
-  [store namespace metric value & {:keys [labels] :or {labels []}}]
-  (-> (gauge-with-labels (get-in store [:metrics namespace metric]) labels)
-      (.set value)))
+(defn register-counter
+  "Registers a counter to the store and returns the new store."
+  [store namespace metric help label-names]
+  (assoc-in store [:metrics namespace metric] (make-counter (:registry store) namespace metric help label-names)))

 (defn register-gauge
   "Registers a gauge to the store and returns the new store."
   [store namespace metric help label-names]
   (assoc-in store [:metrics namespace metric] (make-gauge (:registry store) namespace metric help label-names)))

-(defn register-counter
-  "Registers a counter to the store and returns the new store."
-  [store namespace metric help label-names]
-  (assoc-in store [:metrics namespace metric] (make-counter (:registry store) namespace metric help label-names)))
+(defn register-histogram
+  "Registers a histogram to the store and returns the new store."
+  [store namespace metric help label-names buckets]
+  (assoc-in store
+            [:metrics namespace metric]
+            (make-histogram (:registry store) namespace metric help label-names buckets)))

 (defn increase-counter
   "Increase the value of a registered counter."
@@ -88,12 +82,11 @@
   (-> (counter-with-labels (get-in store [:metrics namespace metric]) labels)
       (.inc amount)))

-(defn register-histogram
-  "Registers a histogram to the store and returns the new store."
-  [store namespace metric help label-names buckets]
-  (assoc-in store
-            [:metrics namespace metric]
-            (make-histogram (:registry store) namespace metric help label-names buckets)))
+(defn set-gauge
+  "Set the value of a registered gauge."
+  [store namespace metric value & {:keys [labels] :or {labels []}}]
+  (-> (gauge-with-labels (get-in store [:metrics namespace metric]) labels)
+      (.set value)))

 (defn track-observation
   "Track the value of an observation for a registered histogram."
@@ -116,6 +109,13 @@
         (with-meta response (assoc response-meta :path route)))
       response)
     response))
+
+(defn- record-request-metric [counter histogram request-method response-status request-time response-path]
+  (let [status-class (str (int (/ response-status 100)) "XX")
+        method-label (string/upper-case (name request-method))
+        labels [method-label (str response-status) status-class response-path]]
+    (-> (histogram-with-labels histogram labels) (.observe request-time))
+    (-> (counter-with-labels counter labels) (.inc))))

 (defn instrument-handler
   "Ring middleware to record request metrics"


Add the two forms of printing; long and short [:17]

--- src/ttt/core.cljs
+++ src/ttt/core.cljs
@@ -327,10 +327,40 @@
          _ (unlock!)]
      res)))

+(defn open-state [pref-file]
+  (-> (:ticket-states pref-file) first keyword))
+(defn closed-state [pref-file]
+  (-> (:ticket-states pref-file) last keyword))
+
 (defn str-ticket
   "A basic single-line str for a ticket; suitable to print"
   [t]
-  (str (:id t) " [" (:type t) " :: " (:points t) " points] - " (:summary t)))
+  (let [pref-file (pref-file!)
+        status-map {(open-state pref-file) "_ "
+                    (closed-state pref-file) "X "}]
+    (str (get status-map (:current-state t) "> ") (:id t) " [" (:type t) " :: " (:points t) " points] - " (:summary t))))
+
+(defn str-ticket-long
+  "A full format ticket string; suitable to report on a single ticket"
+  [t]
+  (let [pref-file (pref-file!)
+        days-opened (-> (:states t) ((open-state pref-file)) (#(- (utc-millis) %)) (/ 86400000))
+        work?  (-> (:history t) last :at)
+        days-since (or (and work? (-> work? (#(- (utc-millis) %)) (/ 86400000)))
+                       days-opened)]
+    (if t
+      (str "Issue " (:id t) " - " (:summary t)
+           "\n------------------------"
+           "\n Description: " (:description t)
+           "\n Type: " (:type t)
+           "\n Status: " (:current-state t)
+           "\n Points: " (:points t)
+           "\n Reported by: " (:reported-by t) " - " days-opened " day(s) ago"
+           "\n Owned by: " (:owner t)
+           "\n Last activity: " days-since " day(s) ago"
+           "\n On branch: " (:branch t)
+           "\n Release: " (:release t))
+      "Could not locate that ticket")))

 ;; Git interactions
 ;; -----------------


CLJS-379: optimize tail call in linear-traversal-nth

--- src/cljs/cljs/core.cljs
+++ src/cljs/cljs/core.cljs
@@ -770,7 +770,7 @@
                          (first coll)
                          (throw (js/Error. "Index out of bounds")))
        (indexed? coll) (-nth coll n)
-       (seq coll)      (linear-traversal-nth (next coll) (dec n))
+       (seq coll)      (recur (next coll) (dec n))
        :else           (throw (js/Error. "Index out of bounds"))))
   ([coll n not-found]
      (cond
@@ -779,7 +779,7 @@
                          (first coll)
                          not-found)
        (indexed? coll) (-nth coll n not-found)
-       (seq coll)      (linear-traversal-nth (next coll) (dec n) not-found)
+       (seq coll)      (recur (next coll) (dec n) not-found)
        :else           not-found)))

 (defn nth


Added distinct?. per #34

Added distinct?. per #34

--- src/cljs/cljs/core.cljs
+++ src/cljs/cljs/core.cljs
@@ -519,6 +519,22 @@
   it will not perform a linear search for a value.  See also 'some'."
   [coll v]
   (boolean (-lookup coll v)))
+
+(defn distinct?
+  "Returns true if no two of the arguments are ="
+  ([x] true)
+  ([x y] (not (= x y)))
+  ([x y & more]
+     (if (not (= x y))
+     (loop [s #{x y} xs more]
+       (let [x (first xs)
+             etc (next xs)]
+         (if xs
+           (if (contains? s x)
+             false
+             (recur (conj s x) etc))
+           true)))
+     false)))

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Seq fns ;;;;;;;;;;;;;;;;

@@ -2572,6 +2588,8 @@
   (assert (not (contains? nil 42)))
   (assert (contains? "f" 0))
   (assert (not (contains? "f" 55)))
+  (assert (distinct? 1 2 3))
+  (assert (not (distinct? 1 2 3 1)))
   :ok
   )


додано відображення

додано відображення

--- src/uawa/core.clj
+++ src/uawa/core.clj
@@ -25,6 +25,19 @@
 ;; (якщо (менше? (дай-випадкове 3) 4) (друкуй "українська") (друкуй "ураиский русский))

-(вираз завершись ([] (System/exit 0)) ([статус] (System/exit статус)))
+(вираз вихід ([] (вихід 0)) ([статус] (System/exit статус)))

-(defmacro для "у циклі for" [set-expr body-expr] `(for ~set-expr body-expr))+(defmacro для "у циклі for" [set-expr body-expr] `(for ~set-expr body-expr))
+
+
+(defn використай [& args] (use args))
+
+(defmacro коли
+  "When, Evaluates test. If logical true, evaluates body in an implicit do."
+  [test & body] (when ~test ~body))
+
+(defn відобрази "map" [функція] (map функція))
+(defn відобрази "map" [функція список] (map функція список))
+(defn відобрази "map" [функція с1 с2] (map функція с1 с2))
+(defn відобрази "map" [функція с1 с2 с3] (map функція с1 с2 с3))
+(defn відобрази "map" [функція с1 с2 с3 &список] (map функція с1 с2 с3 &список))


Add *print-fn* var to allow for different print functions per environment.

--- src/cljs/cljs/core.cljs
+++ src/cljs/cljs/core.cljs
@@ -11,6 +11,14 @@
             [goog.string.StringBuffer :as gstringbuf]
             [goog.object :as gobject]
             [goog.array :as garray]))
+
+(def
+  ^{:doc "Each runtime environment provides a diffenent way to print output.
+  Whatever function *print-fn* is bound to will be passed any
+  Strings which should be printed."}
+  *print-fn*
+  (fn [_]
+    (throw (js/Error. "No *print-fn* fn set for evaluation environment"))))

 (defn truth_
   "Internal - do not use!"
@@ -2577,10 +2585,8 @@
             (interpose [sep] (map #(print-one % opts) coll)))
           [end]))

-; This should be different in different runtime environments. For example
-; when in the browser, could use console.debug instead of print.
 (defn string-print [x]
-  (js/print x)
+  (*print-fn* x)
   nil)

 (defn flush [] ;stub


CLJS-26: Renamed to extend-object\!

CLJS-26: Renamed to extend-object\!

--- src/cljs/cljs/core.cljs
+++ src/cljs/cljs/core.cljs
@@ -3266,7 +3266,7 @@
   "Given a multimethod, returns a map of preferred value -> set of other values"
   [multifn] (-prefers multifn))

-(defn extend-object
+(defn extend-object!
   "Takes a JavaScript object and a map of names to functions and
   attaches said functions as methods on the object.  Any references to
   JavaScript's implict this (via the this-as macro) will resolve to the


remove questionable code

remove questionable code

--- src/cljs/cljs/core.cljs
+++ src/cljs/cljs/core.cljs
@@ -151,10 +151,7 @@
 ;; INTERNAL - do not use
 (defn load-file [file]
   (when-not js/COMPILED
-    (let [file (if (identical? js/process.platform "win32")
-                 (.replace file "\\" "\\\\")
-                 file)]
-      (cljs.core/load-file* file))))
+    (cljs.core/load-file* file)))

 (if (and (exists? js/Symbol)
          (identical? (goog/typeOf js/Symbol) "function"))


fix bug in hash cache code, check that the result is a number.

--- src/cljs/cljs/core.cljs
+++ src/cljs/cljs/core.cljs
@@ -968,12 +968,14 @@
     (set! string-hash-cache-count (inc string-hash-cache-count))
     h))

+(declare number?)
+
 (defn check-string-hash-cache [k]
   (when (> string-hash-cache-count 255)
     (set! string-hash-cache (js-obj))
     (set! string-hash-cache-count 0))
   (let [h (aget string-hash-cache k)]
-    (if-not (nil? h)
+    (if (number? h)
       h
       (add-to-string-hash-cache k))))


using location page from pages module

using location page from pages module

--- src/cljs/ohds/core.cljs
+++ src/cljs/ohds/core.cljs
@@ -42,7 +42,7 @@
     (case (:page @app-state)
       :login [p/login-page do-login app-state]
       :bad-login [p/bad-login do-login app-state]
-      :location [location-page])]])
+      :location [p/location-page])]])

 (defn main []
   (println "In Main")


Fixed issue #31: Reading from ccs_description and package_description tables should not throw exception handled by the Ring.

--- src/clouseau/server.clj
+++ src/clouseau/server.clj
@@ -104,11 +104,15 @@

 (defn read-description
     [product package]
-    (let [result (jdbc/query (second product) (str "select description from packages where name='" package "';"))
-          desc   (:description (first result))]
-        (if (not desc)
-            nil
-            (.replaceAll desc "\n" "
"))))
+    (try
+        (let [result (jdbc/query (second product) (str "select description from packages where name='" package "';"))
+              desc   (:description (first result))]
+            (if (not desc)
+                nil
+                (.replaceAll desc "\n" "
")))
+        (catch Exception e
+            (println-and-flush "read-description(): error accessing database '" (:subname (second product)) "'!")
+            nil)))

 (defn read-package-descriptions
     [products package]
@@ -120,11 +124,15 @@

 (defn read-ccs-description
     [package]
-    (let [result (jdbc/query ccs-db (str "select description from packages where name='" package "';"))
-          desc   (:description (first result))]
-        (if (not desc)
-            nil
-            desc))) ; (.replaceAll desc "\n" "
"))))
+    (try
+        (let [result (jdbc/query ccs-db (str "select description from packages where name='" package "';"))
+              desc   (:description (first result))]
+            (if (not desc)
+                nil
+                desc)) ; (.replaceAll desc "\n" "
"))))
+        (catch Exception e
+            (println-and-flush "read-ccs-description(): Error accessing database 'css_descriptions.db'!")
+            nil)))

 (defn read-all-descriptions
     "Read all descriptions from a table 'ccs-db' stored in a file 'ccs_descriptions.db'."


Initial commit

Initial commit


almost have xml parsing back to a working state, via a very roundabout route :)

--- src/rapscallion/xml.clj
+++ src/rapscallion/xml.clj
@@ -1,7 +1,7 @@
 (ns rapscallion.xml
   (:require (clojure [xml :as xml])
             (clojure.java [io :as io]))
-  (:use (yoodls.pipe :only [pipe]))
+  (:use (yoodls [pipe :only [pipe]]))
   (:import [java.io Writer Reader StringReader]
            [java.util.concurrent LinkedBlockingQueue]
            [org.xml.sax Attributes InputSource]
@@ -127,7 +127,7 @@
   The event types and their associated data are:
     [:start-element tag attrs]
     [:end-element tag]
-    [:characters string]
+    [:text string]
     [:start-cdata]
     [:end-cdata]
     [:processing-instruction target data]
@@ -147,7 +147,7 @@

     ;; Text
     (characters [^chars ch ^long start ^long length]
-      (f [:characters (String. ch start length)]))
+      (f [:text (String. ch start length)]))

     ;; Keep track of which text came from a CDATA section
     (startCDATA []
@@ -178,7 +178,7 @@
 (extend-protocol AsInputSource
   String
   (input-source [s]
-    (let [^Reader r (if (.startsWith s "<")
+    (let [^Reader r (if (.startsWith s "<") ;; too "clever"? ... <shrug>
                       (StringReader. s)
                       (io/reader s))]
       (InputSource. r)))
@@ -224,15 +224,51 @@
          (apply concat))))

-(defn ignore [events & event-types]
-  (let [ignores (set event-types)]
-    (remove (fn [e] (ignores (v 0))) events)))
+(defn ignore
+  "Filters out events of the given types."
+  [events & event-types]
+  (let [ignored-types (set event-types)
+        ignorable? (fn [[type]] (ignored-types type))]
+    (remove ignorable? events)))
+
+
+(defn to-nodes
+  "Returns a 2-element vector containing:
+   1) A seq of sibling nodes extracted from the event stream, and
+   2) A seq of the unconsumed events.
+  "
+  [events]
+  (println events)
+  (loop [[[type :as evt] & events] events
+         xml []]
+    (case type
+      :start-element
+      (let [[_ tag attrs] evt
+            [children events] (to-nodes events)]
+        (recur events
+               (conj xml (Element. tag attrs children))))
+
+      :text
+      (recur events (conj xml (evt 1)))
+
+      (:end-element nil)
+      (do
+        (println "Returning: " xml)
+        [xml events])
+
+      )))
+
+

 (defn parse [in]
   (-> in
       event-seq
       merge-text
-      (ignore :start-cdata :end-cdata)
+      ;;(ignore :start-cdata :end-cdata)
+      ;;(ignore :start-prefix-mapping :end-prefix-mapping)
+      ;;(ignore :comment)
+      to-nodes
+      ffirst
       ))

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


Remove unnecessary logging

Remove unnecessary logging

--- src/replme/web/repl.clj
+++ src/replme/web/repl.clj
@@ -64,7 +64,6 @@
         ip (docker-ip client id)
         port 8081]
     (go-loop [msg (<! (timeout-stdout stdout))]
-      (log/info "MESSAGE" msg)
       (if (re-find nrepl-sentinel msg)
         (do
           (log/info (str "Connecting to docker nrepl at" ip ":" port))


added clustering module

added clustering module

--- src/crawler/cluster.clj
+++ src/crawler/cluster.clj
@@ -1,21 +1,57 @@
 (ns crawler.cluster
   "Clustering utilities for explorations by the crawler")

-(defn assign-where?
-  "At least 1 cluster member satisfies the membership test"
-  [clusters x membership-test]
-  (.indexOf
-   (map
-    (fn [a-cluster]
-      (membership-test a-cluster x))
-    clusters)
-   true))
+(defn merge?
+  [cluster1 cluster2 similar?]
+  (some
+   identity
+   (flatten
+    (map
+     (fn [x]
+       (map
+        (fn [y]
+          (if (similar? x y)
+            true))
+        cluster2))
+     cluster1))))

 (defn assign
-  "Returns a new set of clusters
-   after adding object x to them"
-  [clusters x membership-test]
-  (let [position (assign-where? clusters x membership-test)]
-    (if (<= 0 position)
-      (assoc clusters position (cons x (nth clusters position)))
-      (cons [x] clusters))))
+  [clusters x similar?]
+  (let [is
+        (filter
+         identity
+         (map
+          (fn [[i c]]
+            (if (merge? c x similar?)
+              i
+              nil))
+          (map vector
+               (range (count clusters))
+               clusters)))]
+    (if (empty? is)
+      -1 (first is))))
+
+(defn cluster
+  "Points: a set of points
+   similar? : are x and y similar?"
+  [points similar?]
+  (cond (-> points first vector?)
+        (let [merged (set
+                      (reduce
+                       (fn [acc x]
+                         (let [assign-to (assign acc x similar?)]
+                           (if (neg? assign-to)
+                             (into [] (cons x acc))
+                             (assoc (into [] acc) assign-to (into
+                                                             []
+                                                             (concat (nth acc assign-to)
+                                                                     x))))))
+                       []
+                       points))]
+          (if (= merged points)
+            merged
+            (recur merged similar?)))
+
+        :else
+        (recur (set (map (fn [x] [x]) points))
+               similar?)))


Animate expand triangle

Animate expand triangle

--- src/datafrisk/core.cljs
+++ src/datafrisk/core.cljs
@@ -8,9 +8,10 @@
                     :backgroundColor "transparent" :width "20px" :height "20px"}
             :onClick #(emit-fn (if expanded? :contract :expand) path)}
    [:svg {:viewBox "0 0 100 100"
-          :width "100%" :height "100%"}
-    [:polygon {:points (if expanded? "0,0 100,0 50,100"
-                                     "0,0 0,100 100,50") :stroke "black"}]]])
+          :width "100%" :height "100%"
+          :style {:transition "all 0.2s ease"
+                  :transform (when expanded? "rotate(90deg)")}}
+    [:polygon {:points "0,0 0,100 100,50" :stroke "black"}]]])

 (def styles
   {:shell {:backgroundColor "#FAFAFA"}


Can't put more than one arg in bulk header line.

--- src/riemann/elastic.clj
+++ src/riemann/elastic.clj
@@ -120,10 +120,7 @@
         (doseq [index (keys esets)]
           (let [raw (get esets index)
                 bulk-create-items
-                (interleave (map (fn [e]
-                                   {:create {:_type doc-type
-                                             :_id (get e "_id" nil)}})
-                                 raw)
+                (interleave (repeat {:create {:_type doc-type}})
                             raw)]
             (when (seq bulk-create-items)
               (let [res (eb/bulk-with-index index bulk-create-items)]


This works for enough values of "works", to be usable as an alternative until thrashcat is reliable enough.

--- src/defragment/core.clj
+++ src/defragment/core.clj
@@ -164,9 +164,8 @@
   Returns the string shell command to concatenate all the filenames,
   to the output dir, named properly with name and date."
   [cmd-path path {:keys [name date filenames]}]
-  (let [cmd (format "cat %s | %s > %s"
+  (let [cmd (format "ogg123 -q -d wav -f - %s | oggenc -Q - > %s"
                     (umisc/inter-str " " filenames)
-                    cmd-path
                     (format-show-save path name date))]
     (format "echo \"%s\"\n%s\n" cmd cmd)))

@@ -298,14 +297,19 @@
   Executes the cmd-path, feeding the filenames into it. Dumps the output to a specially-named
   file in path."
   [cmd-path path out-commands-file fileglob]
-  (spit out-commands-file (gen-command-line cmd-path path fileglob))
-  (let [{:keys [stdout stderr exit-code]} (bash out-commands-file {:verbose true})]
-    (log/debug {:doing stdout, :result stderr, :status @exit-code})
-    (when (not= 0 @exit-code)
-      ;; TODO: throw exception too?
-      (log/error {:doing stdout, :result stderr, :status @exit-code}))
-    ;; TODO: rm the old out-commands-file
-    ))
+  (let [cmd-line (gen-command-line cmd-path path fileglob)]
+    (log/info cmd-line)
+    (spit out-commands-file cmd-line))
+  (try
+    (let [{:keys [stdout stderr exit-code]} (bash out-commands-file {:verbose true})]
+      (log/debug {:doing stdout, :result stderr, :status @exit-code})
+      (when (not= 0 @exit-code)
+        ;; TODO: throw exception too?
+        (log/error {:doing stdout, :result stderr, :status @exit-code}))
+      ;; TODO: rm the old out-commands-file
+      )
+    (catch Exception e
+      (log/error e cmd-path path out-commands-file fileglob))))


Lock water color when outside field of view

--- src/robinson/render.clj
+++ src/robinson/render.clj
@@ -671,8 +671,12 @@
                               :corridor        ["#"]
                               :down-stairs     [">"]
                               :up-stairs       ["<"]
-                              :water           ["\u2248"  (rand-nth [:blue :dark-blue]) :black] ;; ≈
-                              :surf            ["~"  (rand-nth [:white :light-blue :blue-green]) :black]
+                              :water           ["\u2248" (if (= (cell :discovered) current-time)
+                                                           (rand-nth [:blue :dark-blue])
+                                                           :blue) :black] ;; ≈
+                              :surf            ["~" (if (= (cell :discovered) current-time)
+                                                      (rand-nth [:white :light-blue :blue-green])
+                                                      :light-blue) :black]
                               :sand            ["."  :beige      :black]
                               :dirt            ["."  :brown      :black]
                               :gravel          ["."  :gray       :black]


Add will to live flavor text in log

Add will to live flavor text in log

--- src/robinson/update.clj
+++ src/robinson/update.clj
@@ -909,6 +909,17 @@
                  (set (if (neg? (get-in state [:world :player :will-to-live]))
                         (conj status :dead)
                         status))))))
+
+(defn log-will-to-live-flavor
+  "Log a flavor message when will-to-live increases or decreases by a lot."
+  [state prev-will-to-live]
+  (let [dwtl (- prev-will-to-live (get-in state [:world :player :will-to-live]))]
+    (if (> (Math/abs dwtl) 1.5)
+      (if (neg? dwtl)
+        (append-log state (format "You feel %s." (rand-nth ["happy" "happier" "glad" "elated" "great" "good"])))
+        (append-log state (format "You feel %s." (rand-nth ["sad" "sadder" "down" "unhappy" "bummed" "bad"]))))
+      state)))
+

 (defn if-poisoned-get-hurt
   "Decrease player's hp if they are poisoned."
@@ -1443,7 +1454,8 @@
                         (new-state (get-in state [:world :current-state])))
             _ (assert (not (nil? new-state)))
             _ (info "player" (get-in state [:world :player]))
-            _ (info "new-state" new-state)]
+            _ (info "new-state" new-state)
+            wtl       (get-in state [:world :player :will-to-live])]
         (some-> state
             (assoc-in [:world :current-state] new-state)
             (tx/when-> advance-time
@@ -1460,7 +1472,9 @@
               ;; TODO: Add appropriate level
               (add-npcs-random 1)
               ;; update visibility
-              (update-visibility))
+              (update-visibility)
+              ;; add will-to-live flavor message
+              (log-will-to-live-flavor wtl))
             (update-quests)
             (arg-when-> [state] (contains? (-> state :world :player :status) :dead)
               ((fn [state]


Add unit tests for checking error conditions.

--- test/berry/parsing/scan_literal_test.clj
+++ test/berry/parsing/scan_literal_test.clj
@@ -7,27 +7,34 @@

 (deftest scan-literal-test

-  (testing "With a true literal."
+  (testing "When a true literal is analyzed."

            (let [true-literal (Token. "literal" "true" (Location. 1 1) (Location. 1 4))]

              (is (= true-literal
                     (scan-literal '("t" "r" "u" "e") context/begin)))))

-  (testing "With a false literal."
+  (testing "When a false literal is analyzed."

            (let [false-literal (Token. "literal" "false" (Location. 1 1) (Location. 1 5))]

              (is (= false-literal
                     (scan-literal '("f" "a" "l" "s" "e") context/begin)))))

-  (testing "With a null literal."
+  (testing "When a null literal is analyzed."

            (let [null-literal (Token. "literal" "null" (Location. 1 1) (Location. 1 4))]

              (is (= null-literal
                     (scan-literal '("n" "u" "l" "l") context/begin)))))

-
-
-  )
+  (testing "When an unexpected token is found in the sequence."
+
+           (is (thrown-with-msg? java.text.ParseException #"Unexpected token y at line 1, column 3."
+                                 (scan-literal '("t" "r" "y" "e") context/begin)))
+
+           (testing "When the input terminates unexpectedly."
+
+                    (is (thrown-with-msg? java.text.ParseException #"Unexpected end of input at line 1, column 4."
+
+                                          (scan-literal '("f" "a" "l" "s") context/begin))))))


rerender list on start of edit to hide previous edit fields

--- src/diary/ui/entry.cljs
+++ src/diary/ui/entry.cljs
@@ -23,8 +23,8 @@
     (doto e (.preventDefault) (.stopPropagation))))

 (defn edit [c {:keys [db/id diary.entry/text] :as props}]
-  (om/transact! c `[(entry/edit {:db/id ~id})])
-  (om/update-state! c merge {:need-focus true :edit-text text}))
+  (om/transact! c `[(entry/edit {:db/id ~id}) :entries/list])
+  (om/update-state! c merge { :edit-text text}))

 (defn change [c e]
   (om/update-state! c assoc
@@ -67,14 +67,7 @@
   (query [this]
          [:db/id :diary.entry/text :entry/editing])
   Object
-  (componentDidUpdate [this prev-props prev-state]
-    (when (and (:entry/editing (om/props this))
-               (om/get-state this :needs-focus))
-      (let [node (dom/node this "editField")
-            len  (.. node -value -length)]
-        (.focus node)
-        (.setSelectionRange node len len))
-      (om/update-state! this assoc :needs-focus nil)))
+
   (render [this]
           (let [props (om/props this)
                 {:keys [diary.entry/date entry/editing]} props


Test xsd:duration distance

Test xsd:duration distance

--- test/rdf_path_examples/distance_test.clj
+++ test/rdf_path_examples/distance_test.clj
@@ -45,7 +45,7 @@
       (are [a b distance] (== (distance-fn a b) distance)
            {"@value" 0} {"@value" 1} 0.1
            {"@value" -10} {"@value" 5} 1.5))
-    (testing "Distance between dates and date-times"
+    (testing "Distance between dates, date-times, and durations."
       (are [a b c d] (= (distance-fn a b) (distance-fn c d))
            ; A day difference
            {"@value" "2015-01-01"} {"@value" "2015-01-02"}
@@ -55,7 +55,10 @@
            {"@value" "2014-01-01"} {"@value" "2015-01-01"}
            ; A minutes difference
            {"@value" "2015-01-01T12:00:00.000Z"} {"@value" "2015-01-01T12:01:00.000Z"}
-           {"@value" "2015-01-01T12:01:00.000Z"} {"@value" "2015-01-01T12:02:00.000Z"}))
+           {"@value" "2015-01-01T12:01:00.000Z"} {"@value" "2015-01-01T12:02:00.000Z"}
+           ; A month difference
+           {"@value" "P5Y"} {"@value" "P4Y11M"}
+           {"@value" "P1M"} {"@value" "P2M"}))
     (testing "Malformed literals have maximum distance."
       (are [a b] (== (distance-fn a b) 1)
            {"@type" (xsd "date") "@value" "2016-04-31"} {"@type" (xsd "date") "@value" "2016-04-30"}


Correctly handle `:include-rss` and `:include-atom` on markdown file metadata

--- src/io/perun.clj
+++ src/io/perun.clj
@@ -4,7 +4,6 @@
             [boot.pod :as pod]
             [boot.util :as u]
             [clojure.java.io :as io]
-            [clojure.set :as set]
             [clojure.string :as string]
             [clojure.edn :as edn]
             [io.perun.core :as perun]))
@@ -114,6 +113,13 @@
       (perun/set-meta fileset updated-files)
       (commit fileset tmp))))

+(defn meta-by-ext
+  [fileset file-exts]
+  (->> fileset
+       boot/user-files
+       (boot/by-ext file-exts)
+       (keep perun/+meta-key+)))
+
 (defn content-pre-wrap
   "Wrapper for input parsing tasks. Calls `parse-form` on new or changed
   files with extensions in `file-exts`, adds `tracer` to `:io.perun/trace`
@@ -127,45 +133,39 @@
                                boot/user-files
                                (boot/by-ext file-exts)
                                add-filedata)
-            input-metadata (->>
-                            (if pod
-                              (pod/with-call-in @pod ~(parse-form changed-files))
-                              (eval (parse-form changed-files)))
-                            (trace tracer))
-            prev-fs-files (if @prev-fs
-                            (->> @prev-fs
-                                 boot/user-files
-                                 (boot/by-ext file-exts)
-                                 set)
-                            #{})
-            unchanged-metadata (->> changed-files
-                                    set
-                                    (set/difference prev-fs-files)
-                                    (filter #(boot/tmp-get fileset %))
-                                    (keep perun/+meta-key+))
-            output-metadata (doall
-                             (for [{:keys [path parsed filename] :as entry*} (concat input-metadata
-                                                                                unchanged-metadata)]
-                               (let [page-filepath (string/replace path #"(?i).[a-z]+$" ".html")
-                                     entry (-> entry*
-                                               (assoc :has-content true)
-                                               (assoc :original-path path)
-                                               (assoc :path page-filepath)
-                                               (assoc :filename (string/replace filename
-                                                                                #"(?i).[a-z]+$" ".html"))
-                                               (dissoc :parsed :extension :file-type
-                                                       :full-path :mime-type :original))]
-                                 (perun/create-file tmp page-filepath parsed)
-                                 entry)))
-            input-metadata* (map #(-> %
-                                      (dissoc :include-rss)
-                                      (dissoc :include-atom))
-                                 input-metadata)
-            final-metadata (perun/merge-meta* (perun/get-meta @prev-fs)
-                                              (concat input-metadata* output-metadata))
-            new-fs (-> fileset
+            changed-meta (->> (if pod
+                                (pod/with-call-in @pod ~(parse-form changed-files))
+                                (eval (parse-form changed-files)))
+                              (map #(let [{:keys [include-rss include-atom]} %]
+                                      (-> %
+                                          (assoc :include-rss* include-rss
+                                                 :include-atom* include-atom)
+                                          (dissoc :include-rss :include-atom))))
+                              (trace tracer))
+            input-fs (-> (if @prev-fs
+                           (perun/set-meta fileset (meta-by-ext @prev-fs file-exts))
+                           fileset)
+                         (perun/set-meta changed-meta))
+            input-meta (meta-by-ext input-fs file-exts)
+            output-meta (doall
+                         (for [{:keys [path parsed filename
+                                       include-rss* include-atom*] :as entry*} input-meta]
+                           (let [page-filepath (string/replace path #"(?i).[a-z]+$" ".html")
+                                 entry (-> entry*
+                                           (assoc :has-content true
+                                                  :original-path path
+                                                  :path page-filepath
+                                                  :filename (string/replace filename
+                                                                            #"(?i).[a-z]+$" ".html")
+                                                  :include-rss include-rss*
+                                                  :include-atom include-atom*)
+                                           (dissoc :parsed :extension :file-type :full-path
+                                                   :mime-type :original :include-rss* :include-atom*))]
+                             (perun/create-file tmp page-filepath parsed)
+                             entry)))
+            new-fs (-> input-fs
                        (commit tmp)
-                       (perun/set-meta final-metadata))]
+                       (perun/set-meta output-meta))]
         (reset! prev-fs new-fs)
         new-fs))))


Remove unused require, and fix a mac annoyance

--- src/io/perun.clj
+++ src/io/perun.clj
@@ -7,7 +7,6 @@
             [clojure.java.io :as io]
             [clojure.set :as set]
             [clojure.string :as string]
-            [clojure.edn :as edn]
             [io.perun.core :as perun]
             [io.perun.meta :as pm]))

@@ -122,6 +121,8 @@
    - width
    - height"
   []
+  ;; This prevents a Java icon appearing in the dock on a Mac, and stealing program focus
+  (System/setProperty "java.awt.headless" "true")
   (boot/with-pre-wrap fileset
     (let [pod (create-pod images-dimensions-deps)
           metas (trace :io.perun/images-dimensions


Simplify finding unchanged content files

--- src/io/perun.clj
+++ src/io/perun.clj
@@ -123,29 +123,25 @@
                                boot/user-files
                                (boot/by-ext file-exts)
                                add-filedata)
-            fs-files (->> fileset
-                          boot/user-files
-                          (boot/by-ext file-exts)
-                          set)
+            input-metadata (->>
+                            (if-let [pod (:pod options)]
+                              (pod/with-call-in @pod ~(parse-form changed-files))
+                              (eval (parse-form changed-files)))
+                            (trace tracer))
             prev-fs-files (if @prev-fs
                             (->> @prev-fs
                                  boot/user-files
                                  (boot/by-ext file-exts)
                                  set)
                             #{})
-            all-files (set/intersection fs-files prev-fs-files)
             unchanged-metadata (->> changed-files
                                     set
-                                    (set/difference all-files)
+                                    (set/difference prev-fs-files)
+                                    (filter #(boot/tmp-get fileset %))
                                     (keep perun/+meta-key+))
-            input-metadata (->>
-                            (if-let [pod (:pod options)]
-                              (pod/with-call-in @pod ~(parse-form changed-files))
-                              (eval (parse-form changed-files)))
-                            (trace tracer))
             output-metadata (doall
-                             (for [{:keys [path parsed filename] :as entry*} (concat unchanged-metadata
-                                                                                input-metadata)]
+                             (for [{:keys [path parsed filename] :as entry*} (concat input-metadata
+                                                                                unchanged-metadata)]
                                (let [page-filepath (string/replace path #"(?i).[a-z]+$" ".html")
                                      entry (-> entry*
                                                (assoc :has-content true)