Drop the download menu item and add a editorial dropdown

The download is the landing page and the editorial dropdown is for the
different editorials for each format

--- src/catalog/web/layout.clj
+++ src/catalog/web/layout.clj
@@ -20,14 +20,6 @@
 (defn menu-item [href & body]
   [:li [:a {:href href} body]])

-(defn dropdown [items & body]
-  [:div.btn-group
-   [:button.btn.btn-default.dropdown-toggle {:type "button" :data-toggle "dropdown"}
-    body
-    [:span.caret]]
-   [:ul.dropdown-menu {:role "menu"}
-    (for [item items] item)]])
-
 (defn button-group [buttons]
   [:div.btn-group
    (for [button buttons] button)])
@@ -40,26 +32,16 @@
      (if user
        (list
         [:li [:a [:b (format "%s %s" (:first_name user) (:last_name user))]]]
-        [:li [:a {:href "/logout"} (glyphicon "log-out")]])
-       [:li [:a {:href "/login"} (glyphicon "log-in")]])]))
+        (menu-item "/logout" (glyphicon "log-out")))
+       (menu-item "/login" (glyphicon "log-in")))]))

-(defn dropdown-menu
-  "Display a dropdown menu"
-  [identity]
-  (let [menu [{:href "/archive" :label "Previous catalogs" :roles nil}
-              {:href "/upload" :label "Import from Vubis" :roles #{:catalog :it}}]
-        filtered (filter #(or
-                           ;; if no role is defined we allow access
-                           (nil? (:roles %))
-                           ;; otherwise we check if the role is authorized
-                           (friend/authorized? (:roles %) identity)) menu)]
-    (when (seq filtered)
-      [:li.dropdown
-       [:a.dropdown-toggle
-        {:href "#" :role "button" :data-toggle "dropdown" :aria-expanded false} "Actions" [:span.caret]]
-       [:ul.dropdown-menu {:role "menu"}
-        (for [{:keys [href label roles]} filtered]
-          [:li [:a {:href href} label]])]])))
+(defn- dropdown-menu [items]
+  [:li.dropdown
+   [:a.dropdown-toggle
+    {:href "#" :role "button" :data-toggle "dropdown" :aria-expanded false} "Editorials" [:span.caret]]
+   [:ul.dropdown-menu {:role "menu"}
+    (for [[link label] items]
+      (menu-item link label))]])

 (defn navbar
   "Display the navbar"
@@ -78,10 +60,11 @@
     [:div.collapse.navbar-collapse
      {:id "navbar-collapse-target"}
      [:ul.nav.navbar-nav
-      [:li.active [:a {:href "/"} "Download"]]
-      [:li [:a {:href "/editorial"} "Editorials"]]
-      [:li [:a {:href "/upload"} "Upload"]]]
      [:ul.nav.navbar-nav.navbar-right (loginbar identity)]]]])
+      (menu-item "/upload" "Upload")
+      (dropdown-menu [["/editorial/grossdruck" "Grossdruck"]
+                      ["/editorial/braille" "Braille"]
+                      ["/editorial/hörbuch" "Hörbuch"]])]]]])

 (defn common
   "Display a page using the bootstrap css"


Remove either monad transformer.

Remove either monad transformer.

--- src/cats/monad/either.cljc
+++ src/cats/monad/either.cljc
@@ -213,52 +213,7 @@

 (util/make-printable (type context))

-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Monad Transformer
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-(defn either-t
-  "The Either transformer constructor."
-  [inner]
-  (reify
-    p/Context
-    (-get-level [_] ctx/+level-transformer+)
-
-    p/Monad
-    (-mreturn [_ v]
-      (p/-mreturn inner (right v)))
-
-    (-mbind [_ mv f]
-      (p/-mbind inner
-                mv
-                (fn [either-v]
-                  (if (left? either-v)
-                    (p/-mreturn inner either-v)
-                    (f (p/-extract either-v))))))
-
-    p/MonadZero
-    (-mzero [_]
-      (p/-mreturn inner (left)))
-
-    p/MonadPlus
-    (-mplus [_ mv mv']
-      (p/-mbind inner
-                mv
-                (fn [either-v]
-                  (if (right? either-v)
-                    (p/-mreturn inner either-v)
-                    mv'))))
-
-    p/MonadTrans
-    (-lift [m mv]
-      (p/-mbind inner
-                mv
-                (fn [v]
-                  (p/-mreturn inner (right v)))))))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Utility functions
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; --- Utility functions

 (defn branch
   "Given an either value and two functions, if the either is a


switch to using Java 7 ProcessBuilder

switch to using Java 7 ProcessBuilder

--- src/clj/cljs/repl/node.clj
+++ src/clj/cljs/repl/node.clj
@@ -18,7 +18,8 @@
   (:import cljs.repl.IJavaScriptEnv
            java.net.Socket
            java.lang.StringBuilder
-           [java.io BufferedReader BufferedWriter]))
+           [java.io BufferedReader BufferedWriter]
+           [java.lang ProcessBuilder UNIXProcess ProcessBuilder$Redirect]))

 (defn socket [host port]
   (let [socket (Socket. host port)
@@ -48,25 +49,36 @@
                (.append sb (char c))
                (recur sb (.read in)))))))

-(defn node-eval [{{:keys [in out]} :socket :as repl-env} js]
-  (write out js)
-  {:status :success :value (read-response in)})
+(defn node-eval [repl-env js]
+  (let [{:keys [in out]} @(:socket repl-env)]
+    (write out js)
+    {:status :success
+     :value (read-response in)}))

 (defn load-javascript [repl-env ns url]
   (node-eval repl-env (slurp url)))

 (defn setup [repl-env]
-  (let [env (ana/empty-env)]
+  (println "Setting up Node.js REPL")
+  (let [bldr (ProcessBuilder. (into-array ["node"]))
+        _    (-> bldr
+               (.redirectInput (io/file (io/resource "cljs/repl/node_repl.js")))
+               (.redirectOutput ProcessBuilder$Redirect/INHERIT)
+               (.redirectError ProcessBuilder$Redirect/INHERIT))
+        proc (.start bldr)
+        env  (ana/empty-env)]
+    ;; TODO: temporary hack, should wait till we can read the start string
+    ;; from the process - David
+    (Thread/sleep 1000)
+    (reset! (:socket repl-env)
+      (socket (:host repl-env) (:port repl-env)))
     (repl/load-file repl-env "cljs/core.cljs")
     (swap! (:loaded-libs repl-env) conj "cljs.core")
     (repl/evaluate-form repl-env
       env "<cljs repl>"
-      '(ns cljs.user))
-    (repl/evaluate-form repl-env
-      env "<cljs repl>"
       '(set! *print-fn* (fn [x] (js/node_repl_print (pr-str x)))))))

-(defrecord NodeEnv [socket loaded-libs]
+(defrecord NodeEnv [host port socket loaded-libs]
   repl/IJavaScriptEnv
   (-setup [this]
     (setup this))
@@ -78,8 +90,15 @@
     (close-socket socket)))

 (defn repl-env* [{:keys [host port] :or {host "localhost" port 5001}}]
-  (NodeEnv. (socket host port) (atom {})))
+  (NodeEnv. host port (atom nil) (atom {})))

 (defn repl-env
   [& options]
   (repl-env* options))
+
+(comment
+
+  (def bldr (ProcessBuilder. (into-array ["node"])))
+
+
+  )


import more classes

import more classes

--- src/clj/ephemeris/core.clj
+++ src/clj/ephemeris/core.clj
@@ -1,2 +1,2 @@
 (ns ephemeris.core
-  (:import (swisseph SwissEph)))
+  (:import (swisseph SwissEph SweDate SweConst)))


refactor dashboard init

refactor dashboard init

--- src/clj/salava/user/db.clj
+++ src/clj/salava/user/db.clj
@@ -443,22 +443,25 @@

 (defn dashboard-info [ctx user-id]
-  (let [badges (->> (b/user-badges-all ctx user-id) (sort-by :mtime >))
+  (let [badges (->> (b/user-badges-all ctx user-id)
+                    (filter #(= "accepted" (:status %)))
+                    (sort-by :mtime >)
+                    (take 5))
         pending-badges (b/user-badges-pending ctx user-id)
         stats (b/badge-stats ctx user-id)
         events (so/get-all-events-add-viewed ctx user-id)
         user-info (user-information-with-registered-and-last-login ctx user-id)
         user-profile (-> (user-information-and-profile ctx user-id nil)
                          (dissoc :badges :pages :owner?))]
-  {:badges (->> badges (take 5))
-   :pending-badges (->> pending-badges (take 5))
+  {:badges badges
+   ;:pending-badges (->> pending-badges (take 5))
    :stats stats
    :endorsing (->> (end/endorsements-given ctx user-id) count)
    :endorsers (->> (end/endorsements-received ctx user-id) count)
    :pending-endorsements (->> (end/received-pending-endorsements ctx user-id) count)
    :connections {:badges (->> (so/get-connections-badge ctx user-id) count)}
-   :events (->> events (take 5))
-   :events_count (count events)
+   ;:events (->> events (take 5))
+   ;:events_count (count events)
    :pages_count (->> (p/user-pages-all ctx user-id) count)
    :files_count (->> (f/user-files-all ctx user-id) :files count)
    :gallery (g/gallery-stats ctx (:last_login user-info))


delete evidences

delete evidences

--- src/clj/salava/user/db.clj
+++ src/clj/salava/user/db.clj
@@ -346,9 +346,8 @@
 (defn remove-user-badges [db user-id]
   (let [user-badge-ids (select-user-badge-ids {:user_id user-id} (into {:row-fn :id} db))]
     (doseq [user-badge-id user-badge-ids]
-      (b/delete-badge-with-db! db user-badge-id))))
-
-
+      (b/delete-badge-with-db! db user-badge-id)
+      (b/delete-badge-evidences! db user-badge-id user-id))))

 (defn delete-user
   "Delete user and all user data"


1st working version of IRC bot

1st working version of IRC bot

--- src/clj_mrazik/irc_bot.clj
+++ src/clj_mrazik/irc_bot.clj
@@ -12,3 +12,63 @@

 (ns clj-mrazik.irc-bot)

+(require '[irclj.core :as irc])
+
+(def connection
+    (atom nil))
+
+(def bot-nick
+    (atom nil))
+
+(defn message-to-channel?
+    [message]
+    (.startsWith (:target message) "#"))
+
+(defn message-for-me?
+    [my-name message]
+    (or (.startsWith (:target message) my-name)        ; private message
+        (.startsWith (:text message) (str my-name ":")); direct message
+    ))
+
+(defn create-reply
+    [incoming-message]
+    (if (message-to-channel? incoming-message)
+        incoming-message
+        (assoc incoming-message :target (:nick incoming-message))))
+
+(defn prepare-reply-text
+    [incomming-message nick input-text]
+    (let [in-channel? (message-to-channel? incomming-message)
+          input       (if in-channel?
+                          (subs input-text (count @bot-nick))
+                          input-text)
+          prefix      (if in-channel? (str nick ": "))]
+        (str prefix "?")))
+
+(defn on-incoming-message
+    [connection incoming-message]
+    (let [{text    :text
+           target  :target
+           nick    :nick
+           host    :host
+           command :command} incoming-message]
+           (println "Received message from" nick "to" target ":" text "(" host command ")")
+           (if (message-for-me? @bot-nick incoming-message)
+               (irc/reply connection (create-reply incoming-message)
+                                     (prepare-reply-text incoming-message nick text)))))
+
+(defn start-irc-bot
+    [configuration]
+    (let [server  (:name configuration)
+          port    (:port configuration)
+          channel (:channel configuration)
+          nick    (:nick configuration)]
+        (println "Connecting to" server "on port" port)
+        (let [conn (irc/connect server port nick
+                                :callbacks {:privmsg on-incoming-message})]
+            (println "Connected, joining to channel" channel)
+            (reset! connection conn)
+            (reset! bot-nick nick)
+            (irc/join @connection channel)
+            (println "Connected..."))))
+


use default for catch error and ex-info to report problems

--- src/cljs/common/async.cljs
+++ src/cljs/common/async.cljs
@@ -47,7 +47,7 @@
     (loop [i n]
       (try
         (<? (f))
-        (catch js/Error e
+        (catch :default e
           (if (> i 0)
             (recur (dec i))
             e))))))
@@ -59,4 +59,4 @@
   (go
     (alt!
       c ([x] x)
-      (async/timeout msec) (js/Error. (str "Timeout " msec "ms")))))
+      (async/timeout msec) (ex-info (str "Timeout " msec "ms") {::timeout msec}))))


Removed now redundant button

Removed now redundant button

--- src/cljs/zetawar/data.cljs
+++ src/cljs/zetawar/data.cljs
@@ -18,7 +18,6 @@

     ;; Faction configuration
     :configure-faction-tip"Configure faction"
-    :configure-faction-title "Configure faction"
     :player-type-label "Player type"

     ;; New game settings


Add way to get lazy seq of container contents

The existing implementation in jclouds is broken, since it doesn't
recurse, nor does it give you a way to force recursion.

--- src/clojars/cloudfiles.clj
+++ src/clojars/cloudfiles.clj
@@ -1,7 +1,11 @@
 (ns clojars.cloudfiles
   (:require [clojure.java.io :as io]
             [clojure.string :as str]
-            [org.jclouds.blobstore2 :as jc]))
+            [org.jclouds.blobstore2 :as jc])
+  (:import [org.jclouds.blobstore
+            BlobStore
+            domain.PageSet
+            options.ListContainerOptions]))

 (defrecord Connection [bs container])

@@ -26,6 +30,42 @@
 (defn put-file [conn name file]
   (apply-conn jc/put-blob conn (jc/blob name :payload file)))

+;; borrowed from jclouds
+;; (https://github.com/jclouds/jclouds/blob/master/blobstore/src/main/clojure/org/jclouds/blobstore2.clj)
+;; and modified to properly allow recursion in container seq
+
+(defn- container-seq-chunk
+  [^BlobStore blobstore container options]
+  (apply jc/blobs blobstore container
+    (mapcat identity
+      (if (string? (:after-marker options))
+        options
+        (dissoc options :after-marker)))))
+
+(defn- container-seq-chunks [^BlobStore blobstore container options]
+  (when (:after-marker options) ;; When getNextMarker returns null, there's no more.
+    (let [chunk (container-seq-chunk blobstore container options)]
+      (lazy-seq (cons chunk
+                  (container-seq-chunks blobstore container
+                    (assoc options
+                      :after-marker (.getNextMarker ^PageSet chunk))))))))
+
+(defn container-seq
+  "Returns a lazy seq of all blobs in the given container."
+  ([^BlobStore blobstore container]
+     (container-seq blobstore container nil))
+  ([^BlobStore blobstore container options]
+     ;; :start has no special meaning, it is just a non-null (null indicates
+     ;; end), non-string (markers are strings).
+   (#'jc/concat-elements (container-seq-chunks blobstore container
+                           (assoc options :after-marker :start)))))
+
+;; end jclouds code
+
+(defn artifact-seq [conn]
+  (map (memfn getName) (apply-conn container-seq conn {:recursive true :with-details false})))
+
+
 ;; All deletions require purging from the CDN:
 ;; https://developer.rackspace.com/docs/cdn/v1/developer-guide/#purge-a-cached-asset
 (comment


Add indices type hinting to with-check-indices macro for

--- src/clojure/gpu/matrix.clj
+++ src/clojure/gpu/matrix.clj
@@ -58,36 +58,42 @@
                     (dec ndims) ", but got " dimension-number "instead!"))
         (aget shape dimension-number)))))

-(defn all?
+(defn- all?
   ([coll]
    (every? true? coll))
   ([f coll]
    (every? true? (mapv f coll))))

-(defn in-bound? [^long idx ^long len]
+(defn- make-index-type-hints [syms]
+  (vec
+    (mapcat (fn [sym]
+              `[~sym (long ~sym)])
+            syms)))
+
+(defn- in-bound? [^long idx ^long len]
   (and (>= idx 0) (< idx len)))

 (defmacro with-check-indices [ndims m & args]
-   (let [row (gensym "row_")
-         col (gensym "col_")
-         indexes (gensym "indexes_")
+   (let [row-sym (gensym "row_")
+         col-sym (gensym "col_")
+         indexes-sym (gensym "indexes_")
          check-clause
          (cond (= ndims 1)
-               `(and (>= ~row 0)
-                     (< ~row (first (mp/get-shape ~m))))
+               `(and (>= ~row-sym 0)
+                     (< ~row-sym (first (mp/get-shape ~m))))
                (= ndims 2)
                `(let [shape# (mp/get-shape ~m)]
-                 (and (>= ~row 0)
-                      (< ~row (first shape#))
-                      (>= ~col 0)
-                      (< ~col (second shape#))))
+                 (and (>= ~row-sym 0)
+                      (< ~row-sym (first shape#))
+                      (>= ~col-sym 0)
+                      (< ~col-sym (second shape#))))
                :else
                `(let [shape# (mp/get-shape ~m)]
                   (all? (map-indexed
                           (fn [dim# idx#]
                             (and (>= idx# 0)
                                  (< idx# (nth shape# dim#))))
-                          ~indexes))))
+                          ~indexes-sym))))
          body
          (cond (= ndims 2)
                (next (next args))
@@ -95,19 +101,30 @@
                (next args))
          all-indexes
          (cond (= ndims 1)
-               `[~(first args)]
+               `[~(first args)]
                (= ndims 2)
                `[~(first args) ~(second args)]
                :else
-               (first args))]
-    `(let ~(cond
-             (= ndims 1)
-             `[~row ~(first args)]
+               (first args))
+         type-hints
+         (make-index-type-hints
+           (cond (= ndims 1)
+                 (take 1 args)
+                 (= ndims 2)
+                 (take 2 args)
+                 :else
+                 []))
+         bindings
+         (-> (cond (= ndims 1)
+             `[~row-sym ~(first args)]
              (= ndims 2)
-             `[~row ~(first args)
-               ~col ~(second args)]
-             :else
-             `[~indexes ~(first args)])
+             `[~row-sym ~(first args)
+               ~col-sym ~(second args)]
+             :else
+             `[~indexes-sym ~(first args)])
+             (concat type-hints)
+             (vec))]
+    `(let ~bindings
        (if ~check-clause
          (do ~@body)
          (error
@@ -143,11 +160,11 @@

 (extend-protocol mp/PIndexedAccess
   NDArray
-  (get-1d [m ^long row]
+  (get-1d [m row]
     (with-check-shape
       1 [m m] row
       (.get m row)))
-  (get-2d [m ^long row ^long col]
+  (get-2d [m row col]
     (with-check-shape
       2 [m m] row col
       (.get m row col)))
@@ -158,11 +175,11 @@

 (extend-protocol mp/PIndexedSetting
   NDArray
-  (set-1d [m ^long row ^double v]
+  (set-1d [m row ^double v]
     (with-check-shape
       1 [m m] row
       (.set (.clone m) row v)))
-  (set-2d [m ^long row ^long col ^double v]
+  (set-2d [m row col ^double v]
     (with-check-shape
       2 [m m] row col
       (.set (.clone m) row col v)))
@@ -174,15 +191,15 @@

 (extend-protocol mp/PIndexedSettingMutable
   NDArray
-  (set-1d [m ^long row ^double v]
+  (set-1d! [m row ^double v]
     (with-check-shape
       1 [m m] row
       (.set m row v)))
-  (set-2d [m ^long row ^long col ^double v]
+  (set-2d! [m row col ^double v]
     (with-check-shape
       2 [m m] row col
       (.set m row col v)))
-  (set-nd [m indexes ^double v]
+  (set-nd! [m indexes ^double v]
     (with-check-shape
       (count indexes) [m m] indexes
       (.set m (long-array indexes) v))))


less clunky phrasing

less clunky phrasing

--- src/pc/views/blog/blue_ocean_made_of_ink.clj
+++ src/pc/views/blog/blue_ocean_made_of_ink.clj
@@ -21,7 +21,7 @@
      [:p "Elon Musk wrote that on "
          [:a {:href "http://www.teslamotors.com/blog/all-our-patent-are-belong-you"} "Telsa's blog"]
          " last year.
-         Tesla’s blue ocean was made of gasoline, Precursor’s is ink.
+         We're lucky enough to stand on the shores of a similar ocean.
          For every single designer or developer using an app to prototype their product, there's at least a thousand using pen and paper."]]

     [:article


[#1949] Auth "POST /visualisations"

[#1949] Auth "POST /visualisations"

--- backend/src/akvo/lumen/endpoint/visualisation.clj
+++ backend/src/akvo/lumen/endpoint/visualisation.clj
@@ -30,9 +30,13 @@
         :post {:parameters {:body map?}
                :handler (fn [{tenant :tenant
                               jwt-claims :jwt-claims
+                              auth-service :auth-service
                               body :body}]
-                          (let [vis-payload (w/keywordize-keys body)]
-                            (lib/ok (visualisation/create (p/connection tenant-manager tenant) vis-payload jwt-claims))))}}]
+                          (let [vis-payload (w/keywordize-keys body)
+                                ids (l.auth/ids ::visualisation.s/visualisation vis-payload)]
+                            (if (p/allow? auth-service ids)
+                              (lib/ok (visualisation/create (p/connection tenant-manager tenant) vis-payload jwt-claims))
+                              (lib/not-authorized {:ids ids}))))}}]
    ["/maps" ["" {:post {:parameters {:body map?}
                         :handler (fn [{tenant :tenant
                                        body :body}]


(PDB-5519) Convert distinct modifier to v2 format

hsql v1 allowed for `:modifiers` to specify the distinct query, v2
requires that you use `:select-distinct` instead.

--- src/puppetlabs/puppetdb/query_eng/engine.clj
+++ src/puppetlabs/puppetdb/query_eng/engine.clj
@@ -1552,19 +1552,22 @@
   i.e. {:select expr}."
   [{:keys [projected-fields call selection projections] :as _query}]
   ;; This is where we finally fully expand the projections.
-  (let [calls (mapv (comp hcore/raw :statement) call)
+  (let [calls (mapv :statement call)
         non-call-projections (if (and (empty? calls) (empty? projected-fields))
                                projections
-                               projected-fields)]
-    (assoc selection
-           :select (->> non-call-projections
-                        (remove (comp :unprojectable? second))
-                        ;; Currently this does not support deps for
-                        ;; projected functions i.e. :calls.
-                        (include-projection-dependencies projections)
-                        (mapv (fn [[name {:keys [field]}]]
-                                [field (quote-projections name)]))
-                        (into calls)))))
+                               projected-fields)
+        ;; map honeysql v1 distinct modifier to honeysqlv2 :select-distinct
+        select-distinct (some #{:distinct} (selection :modifiers))
+        select (if select-distinct :select-distinct :select)]
+    (assoc (dissoc selection :modifiers) ;; honeysql v2 rejects unrecognized keys
+           select (->> non-call-projections
+                       (remove (comp :unprojectable? second))
+                       ;; Currently this does not support deps for
+                       ;; projected functions i.e. :calls.
+                       (include-projection-dependencies projections)
+                       (mapv (fn [[name {:keys [field]}]]
+                               [field (quote-projections name)]))
+                       (into calls)))))

 (defn fn-binary-expression->hsql
   "Produce a predicate that compares the result of a function against a


Simplify FMI weather data fetching function

--- src/env_logger/grabber.clj
+++ src/env_logger/grabber.clj
@@ -91,17 +91,17 @@
                     (catch com.fasterxml.jackson.core.JsonParseException e
                       (log/error (str "FMI JSON weather data parsing failed: "
                                       (str e)))))]
-    (when json-resp
-      (when-not (or (zero? (count (get json-resp "t2m")))
-                    (zero? (count (get json-resp "TotalCloudCover")))
-                    (zero? (count (get json-resp "Pressure"))))
-        {:date (f/unparse (f/formatter :date-time-no-ms)
-                          (t/from-time-zone
-                           (e/from-long (get json-resp "latestObservationTime"))
-                           (t/time-zone-for-id (get-conf-value :timezone))))
-         :temperature ((last (get json-resp "t2m")) 1)
-         :cloudiness (int ((last (get json-resp "TotalCloudCover")) 1))
-         :pressure ((last (get json-resp "Pressure")) 1)}))))
+    (when (and json-resp
+               (not (or (zero? (count (get json-resp "t2m")))
+                        (zero? (count (get json-resp "TotalCloudCover")))
+                        (zero? (count (get json-resp "Pressure"))))))
+      {:date (f/unparse (f/formatter :date-time-no-ms)
+                        (t/from-time-zone
+                         (e/from-long (get json-resp "latestObservationTime"))
+                         (t/time-zone-for-id (get-conf-value :timezone))))
+       :temperature ((last (get json-resp "t2m")) 1)
+       :cloudiness (int ((last (get json-resp "TotalCloudCover")) 1))
+       :pressure ((last (get json-resp "Pressure")) 1)})))

 (defn get-latest-fmi-weather-data
   "Fetches the latest FMI weather data either using


Removing clojure.contrib.math dependency from examples.lawnmower.

--- src/examples/lawnmower.clj
+++ src/examples/lawnmower.clj
@@ -3,10 +3,7 @@
 ;; Lee Spector, lspector@hampshire.edu, 2010

 (ns examples.lawnmower
-  (:require [clojush]
-	    [clojure.contrib.math])
-  (:use [clojush]
-    [clojure.contrib.math]))
+  (:use [clojush]))

 ;;;;;;;;;;;;
 ;; Koza's lawnmower problem, described in Chapter 8 of Genetic Programming II:


Add a little cop-out label warning that the chart will suck, if there's little data. Really ought to be replaced with a placeholder image or just some plain text, but it was most convenient to add this logic to the graph-rendering code

--- src/foreclojure/graphs.clj
+++ src/foreclojure/graphs.clj
@@ -39,10 +39,13 @@
       (chart/add-pointer chart best (freqs best 0)
                          :text "best"
                          :angle :south))
-    (when curr
+    (when (and curr (not= curr best))
       (chart/add-pointer chart curr (freqs curr 0)
                          :text "this"
                          :angle :south))
+    (when-not (> (count freqs) 1)
+      (chart/add-text chart best (freqs best 0)
+                      "Very little golfing data - chart may suck"))
     chart))

 (defn serve-plot [plot]


cleaned up render-track-ball a bit

cleaned up render-track-ball a bit

--- src/frontend/renderer.cljs
+++ src/frontend/renderer.cljs
@@ -210,7 +210,7 @@
       (apply dom/span nil
         (om/build-all track-view (:music-info data))))))

-(defn render-track-bar [data display-bar-id]
+(defn render-track-bar [data display-bar-id progress-bar-id progress-ball-id ball-position]
   (dom/div nil
     (let [height 10
           top (/ height 2)
@@ -219,14 +219,11 @@
       (dom/div #js {:id display-bar-id
                     :style style}))

-    (dom/div #js {:id "progress-track-bar"
+    (dom/div #js {:id progress-bar-id
                   :className "track-bar"}
-      (let [sound (:current-sound data)
-            percent-completed (if (nil? sound)
-                                  0
-                                  (* 100 (/ (:current-sound-position data) (.-duration sound))))
+      (let [percent-completed (ball-position)
             style #js {:left (str percent-completed "%")}]
-          (dom/div #js {:id "progress-track-ball"
+          (dom/div #js {:id progress-ball-id
                         :className "bar-tracker"
                         :style style}
             (dom/div #js {:className "track-ball-display"}))))))
@@ -243,7 +240,13 @@
   (reify
     om/IRender
     (render [this]
-      (render-track-bar data "progress-track-bar-display"))
+      (render-track-bar data "progress-track-bar-display"
+                             "progress-track-bar"
+                             "progress-track-ball"
+                             #(if (nil? (:current-sound data))
+                                  0
+                                  (* 100 (/ (:current-sound-position data)
+                                            (.-duration (:current-sound data)))))))

     om/IDidMount
     (did-mount [this]


Fix formatting

Fix formatting

Signed-off-by: ivermac <cd640042a8f3b0ff08bacdf4feae34fdd495051d@gmail.com>

--- src/hatti/views/table.cljs
+++ src/hatti/views/table.cljs
@@ -394,7 +394,8 @@
     (.setItems dataview
                (clj->js
                 (cond-> data
-                  submission-review? replace-review-num-status-with-text-status))
+                  submission-review?
+                  replace-review-num-status-with-text-status))
                _id)
     (resizeColumns grid)
     [grid dataview]))


Remove tooltip of select all checkboxes

Remove tooltip of select all checkboxes

The tooltip span seem to block a user from selecting the select all checkbox

--- src/hatti/views/table.cljs
+++ src/hatti/views/table.cljs
@@ -118,10 +118,7 @@

 (def select-unselect-all-records-id "select-unselect-all-records")
 (def select-unselect-all-records-element
-  (str "
-            Select all on this page
-            <input type=\"checkbox\" id=\"" select-unselect-all-records-id "\">
-           "))
+  (str "<input type=\"checkbox\" id=\"" select-unselect-all-records-id "\">"))
 (def delete-record-class "delete-record")

 (defn actions-column


Update generator.clj

Update generator.clj

--- src/swagger_gen/examples/scala/generator.clj
+++ src/swagger_gen/examples/scala/generator.clj
@@ -22,4 +22,3 @@
           (merge additional-params
             (assoc spec :normalized-definitions
             (map expand-model (:normalized-definitions spec)))))))))
-


string -> source

string -> source

--- src/main/cljs/cljs/js.cljs
+++ src/main/cljs/cljs/js.cljs
@@ -21,8 +21,8 @@
 ;; -----------------------------------------------------------------------------
 ;; Analyze

-(defn analyze* [env string cb]
-  (let [rdr (rt/string-push-back-reader f)
+(defn analyze* [env source cb]
+  (let [rdr (rt/string-push-back-reader source)
         eof (js-obj)
         env (ana/empty-env)]
     (env/with-compiler-env env
@@ -34,11 +34,11 @@
             (recur))
           (cb))))))

-(defn analyze [env string cb]
+(defn analyze [env source cb]
   (binding [ana/*cljs-ns*    (or (:ns env) 'cljs.user)
             *ns*             (create-ns ana/*cljs-ns*)
             r/*data-readers* tags/*cljs-data-readers*]
-    (analyze* env string cb)))
+    (analyze* env source cb)))

 ;; -----------------------------------------------------------------------------
 ;; Emit


missed this rename from last commit

missed this rename from last commit

--- src/midje/internal_ideas/fakes.clj
+++ src/midje/internal_ideas/fakes.clj
@@ -198,10 +198,10 @@
              "  (provided (all-even? ..xs..) => true)")))
   (if-let [found (find-first (partial call-handled-by-fake? function-var actual-args) fakes)]
     found
-    (when-let [possible-fakes (find-first #(and (= function-var (:var %))
-                                                (usable-default-function? %))
-                                         fakes)]
-      (:value-at-time-of-faking possible-fakes))))
+    (when-let [fake-with-usable-default (find-first #(and (= function-var (:var %))
+                                                          (usable-default-function? %))
+                                                    fakes)]
+      (:value-at-time-of-faking fake-with-usable-default))))

 (defn- ^{:testable true } handle-mocked-call [function-var actual-args fakes]
   (macrolet [(counting-nested-calls [& forms]


Limit authorship accumulation during autosaves of stories.

--- src/oc/storage/resources/story.clj
+++ src/oc/storage/resources/story.clj
@@ -113,6 +113,28 @@
   {:pre [(db-common/conn? conn)]}
   (first (db-common/read-resources conn table-name :secure-uuid-org-uuid [[secure-uuid org-uuid]]))))

+(defn author-update
+  "
+  Add the specified editing author to the authors list with the following rules:
+
+  - if there is only the original author, the editor gets added
+  - if there is an existing editor(s), and the last editor is not the same as this editor, this editor gets added
+  - if there is an existing editor(s), and the last editor is the same as this editor, the last editor gets replaced
+  "
+  [authors author ts]
+  (let [last-editor (last authors)
+        this-editor (assoc author :updated-at ts)]
+    (cond
+      ;; if there is only the original author, the editor gets added
+      (< (count authors) 2)
+      (concat authors [this-editor])
+      ;; if there is an existing editor(s), and the last editor is not the same as this editor, this editor gets added
+      (not= (:user-id last-editor) (:user-id this-editor))
+      (concat authors [this-editor])
+      ;; if there is an existing editor(s), and the last editor is the same as this editor, the last editor gets replaced
+      :else
+      (concat (drop-last authors) [this-editor]))))
+
 (schema/defn ^:always-validate update-story! :- (schema/maybe common/Story)
   "
   Given the UUID of the story, an updated story property map, and a user (as the author), update the story and
@@ -128,7 +150,7 @@
     (let [authors (:author original-story)
           merged-story (merge original-story (ignore-props story))
           ts (db-common/current-timestamp)
-          updated-authors (conj authors (assoc (lib-schema/author-for-user user) :updated-at ts))
+          updated-authors (author-update authors (lib-schema/author-for-user user) ts)
           updated-story (assoc merged-story :author updated-authors)]
       (schema/validate common/Story updated-story)
       (db-common/update-resource conn table-name primary-key original-story updated-story ts))))


Add dependency info for shim JS file (or output-to, as appropriate)

--- src/adzerk/boot_cljs.clj
+++ src/adzerk/boot_cljs.clj
@@ -259,6 +259,7 @@
         (let [{:keys [warnings dep-order]}
               (pod/with-call-in (p)
                 (adzerk.boot-cljs.impl/compile-cljs ~sources ~cljs-opts))
+              dep-order      (concat dep-order [shim-path])
               dep-order-meta (-> fileset
                                  (inc-js-dep-meta incs)
                                  (add-compiled-js-dep-meta dep-order))]


Added liquors from Goodwine

Added liquors from Goodwine

--- src/priceous/provider/goodwine.clj
+++ src/priceous/provider/goodwine.clj
@@ -65,7 +65,7 @@
         [:.catalog-menu-table :li :a])
        (map #(vec [(html/text %)
                    (str (get-in % [:attrs :href]) "page=%s/")]))
-       (seq) (u/debug)
+       (cons ["Ликеры" "http://goodwine.com.ua/liqueurs/c4509/" ])
        ))

 ;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -92,6 +92,7 @@
            :page-limit     Integer/MAX_VALUE
            :done           false
            }
+
    ;; fetch strategy defines how we will fetch results
    :fetch-strategy :heavy
    :category true


Added function to retrieve all Environment resources. Fixes #38

--- src/prop_shop/data/environment.clj
+++ src/prop_shop/data/environment.clj
@@ -11,3 +11,10 @@
   (b/add-entity
     {:name name
      :type :environment}))
+
+
+(defn get-environments
+  "Retrieves all Environments."
+  {:added "0.1"}
+  []
+  (b/get-entities-by-type :environment))


Story ID: RPC-236 `not-every (= :ok)` => `some (= :error)` `if` => `when`

--- src/untangled_spec/stub.cljc
+++ src/untangled_spec/stub.cljc
@@ -69,9 +69,9 @@
     (if (not-empty atoms)
       (let [function @(first atoms)
             count-results (reduce validate-step-counts [] (:steps function))
-            errors? (not-every? #(= :ok %) count-results)]
-        (if errors?
-          (throw (ex-info (str "VERIFY ERROR: " (:function function) " was not called as many times as specified") {::verify-error true}))                    )
+            errors? (some #(= :error %) count-results)]
+        (when errors?
+          (throw (ex-info (str "VERIFY ERROR: " (:function function) " was not called as many times as specified") {::verify-error true})))
         (recur (rest atoms))))
     )
   )


+TODO

+TODO

--- src/babel/lexiconfn.cljc
+++ src/babel/lexiconfn.cljc
@@ -723,6 +723,7 @@
           vals))))

 ;; TODO: s/unifyc/unify/ for performance
+;; TODO: use (default) rather than this; it's simpler to understand and faster.
 (defn if-then [lexicon if-has unify-with]
   (map-function-on-map-vals
    lexicon


fix seed to work with groups

fix seed to work with groups

--- src/chat/server/seed.clj
+++ src/chat/server/seed.clj
@@ -10,7 +10,11 @@

 (defn seed! []
   (db/with-conn
-    (let [user-1 (db/create-user! {:id (db/uuid)
+    (let [group-1 (db/create-group! {:id (db/uuid)
+                                     :name "Lean Pixel"})
+          group-2 (db/create-group! {:id (db/uuid)
+                                     :name "Penyo Pal"})
+          user-1 (db/create-user! {:id (db/uuid)
                                    :email "raf@leanpixel.com"
                                    :password (get env :rafal-password "foobar")
                                    :avatar "https://s3.amazonaws.com/chat.leanpixel.com/avatars/4801271456_41230ac0b881cdf85c28_72.jpg"})
@@ -18,13 +22,20 @@
                                    :email "james@leanpixel.com"
                                    :password (get env :james-password "foobar")
                                    :avatar "https://s3.amazonaws.com/chat.leanpixel.com/avatars/4805955000_07dc272f0a7f9de7719e_192.jpg"})
+          _ (db/user-add-to-group! (user-1 :id) (group-1 :id))
+          _ (db/user-add-to-group! (user-1 :id) (group-2 :id))
+          _ (db/user-add-to-group! (user-2 :id) (group-1 :id))
+          _ (db/user-add-to-group! (user-2 :id) (group-2 :id))
           user-3 (db/create-user! {:id (db/uuid)
                                    :email "test@ycombinator.com"
                                    :password (get env :tester-password "")
                                    :avatar "https://s3.amazonaws.com/chat.leanpixel.com/ycombinator-logo.png"})

-          tag-1 (db/create-tag! {:id (db/uuid) :name "penyopal"})
-          tag-2 (db/create-tag! {:id (db/uuid) :name "watercooler"})
+          tag-1 (db/create-tag! {:id (db/uuid) :group-id (group-1 :id) :name "idonethis"})
+          tag-2 (db/create-tag! {:id (db/uuid) :group-id (group-1 :id) :name "watercooler"})
+
+          tag-3 (db/create-tag! {:id (db/uuid) :group-id (group-2 :id) :name "idonethis"})
+          tag-4 (db/create-tag! {:id (db/uuid) :group-id (group-2 :id) :name "watercooler"})

           _ (db/user-subscribe-to-tag! (user-1 :id) (tag-1 :id))
           _ (db/user-subscribe-to-tag! (user-2 :id) (tag-1 :id))


Attempt to fix CI :/

Attempt to fix CI :/

--- test/clojurewerkz/cassaforte/schema_test.clj
+++ test/clojurewerkz/cassaforte/schema_test.clj
@@ -26,7 +26,8 @@
                         (create-keyspace s "new_cql_keyspace"
                                          (with {:replication
                                                 {:class "SimpleStrategy"
-                                                 :replication_factor 1 }}))
+                                                 :replication_factor 1 }})
+                                         (if-not-exists))
                         (use-keyspace s "new_cql_keyspace")
                         (f)))


Reduce duplicate code in server response formatting

--- src/nhl_score_api/core.clj
+++ src/nhl_score_api/core.clj
@@ -51,18 +51,18 @@
     (->camelCaseString key)
     key))

+(defn- format-response [status body]
+  {:status status
+   :headers {"Access-Control-Allow-Origin" "*"
+             "Content-Type" "application/json; charset=utf-8"}
+   :body (json/write-str body :key-fn json-key-transformer)})
+
 (defn app [request]
   (println "Received request" request)
-  (let [headers {"Access-Control-Allow-Origin" "*"
-                 "Content-Type" "application/json; charset=utf-8"}]
-    (try
-      (let [success-response (get-response (:uri request) api/fetch-latest-scores cache/get-value cache/set-value)
-            response (or success-response {})]
-        {:status (if success-response 200 404)
-         :headers headers
-         :body (json/write-str response :key-fn json-key-transformer)})
-      (catch Exception e
-        (println "Caught exception" e)
-        {:status 500
-         :headers headers
-         :body (json/write-str {:error "Server error"})}))))
+  (try
+    (let [success-response (get-response (:uri request) api/fetch-latest-scores cache/get-value cache/set-value)
+          response (or success-response {})]
+      (format-response (if success-response 200 404) response))
+    (catch Exception e
+      (println "Caught exception" e)
+      (format-response 500 {:error "Server error"}))))


Use more keywords

Use more keywords

--- src/eventframework/app.clj
+++ src/eventframework/app.clj
@@ -37,10 +37,10 @@
     }
     (let [{type :type uuid :uuid} route-params]
       (put-command uuid {
-        :type type
+        :type (keyword type)
         :uuid uuid
         :remote-addr remote-addr
-        :payload form-params
+        :payload (zipmap (map keyword (keys form-params)) (vals form-params))
       })
       uuid)))


debug-log the last-good-commit

debug-log the last-good-commit

--- src/clj/runbld/build.clj
+++ src/clj/runbld/build.clj
@@ -6,6 +6,7 @@
             [runbld.util.data :refer [deep-merge-with deep-merge]]
             [runbld.util.date :as date]
             [runbld.scheduler :as scheduler]
+            [runbld.util.debug :as debug]
             [runbld.vcs.middleware :as vcs]
             [schema.core :as s]
             [slingshot.slingshot :refer [throw+]]))
@@ -106,6 +107,7 @@
                    (:job-name opts))
         vcs-repo (vcs/make-repo opts)]
     [(when-let [build (last-good-build job-name opts vcs-repo)]
+       (debug/log "Found last-good-commit:" (-> build :vcs :commit-id))
        ;; only actually check out as working copy if the command line
        ;; opt has been supplied
        (when check-out?


handler: add meta description

handler: add meta description

--- src/clj/type/handler.clj
+++ src/clj/type/handler.clj
@@ -18,6 +18,8 @@
     [:meta {:charset "utf-8"}]
     [:meta {:name "viewport"
             :content "width=device-width, initial-scale=1"}]
+    [:meta {:name "description"
+            :content "Mini game to learn to type fast."}]
     [:link {:rel "icon"
             :href "/favicon.ico"}]
     [:link {:href "https://fonts.googleapis.com/css?family=Cousine"


try to load fstype as package without add 'com.brainbot.' as prefix

--- src/com/brainbot/vfs.clj
+++ src/com/brainbot/vfs.clj
@@ -37,7 +37,7 @@
   (let [create-fs (@filesystem-registry fstype)]
     (cond
       (nil? create-fs)
-        (load-fs-package (symbol (str "com.brainbot." fstype)))
+        (load-fs-package (symbol fstype))
       (symbol? create-fs)
         (load-fs-package create-fs)
       :else


ZK client info log message now hints at issues

--- src/onyx/log/zookeeper.clj
+++ src/onyx/log/zookeeper.clj
@@ -89,7 +89,7 @@
   component/Lifecycle

   (start [component]
-    (taoensso.timbre/info "Starting ZooKeeper" (if (:zookeeper/server? config) "server" "client connection"))
+    (taoensso.timbre/info "Starting ZooKeeper" (if (:zookeeper/server? config) "server" "client connection. If Onyx hangs here it may indicates a difficulty connecting to ZooKeeper."))
     (let [onyx-id (:onyx/id config)
           server (when (:zookeeper/server? config) (TestingServer. (int (:zookeeper.server/port config))))
           conn (zk/connect (:zookeeper/address config))]


Changed r.m.params to use new Clojure 1.2 libraries

--- ring-core/src/ring/middleware/params.clj
+++ ring-core/src/ring/middleware/params.clj
@@ -1,7 +1,8 @@
 (ns ring.middleware.params
   "Parse form and query params."
-  (:require (clojure.contrib [str-utils :as str] [duck-streams :as duck])
-            (ring.util [codec :as codec])))
+  (:require [ring.util.codec :as codec]
+            [clojure.string :as string]
+            [clojure.contrib.io :as io]))

 (defn assoc-param
   "Associate a key with a value. If the key already exists in the map,
@@ -25,7 +26,7 @@
           (codec/url-decode (or val "") encoding))
          param-map))
     {}
-    (str/re-split #"&" param-string)))
+    (string/split param-string #"&")))

 (defn- assoc-query-params
   "Parse and assoc parameters from the query string with the request."
@@ -47,7 +48,7 @@
   [request encoding]
   (merge-with merge request
     (if-let [body (and (urlencoded-form? request) (:body request))]
-      (let [params (parse-params (duck/slurp* body) encoding)]
+      (let [params (parse-params (io/slurp* body) encoding)]
         {:form-params params, :params params})
       {:form-params {}, :params {}})))


Add `render` checks

Add `render` checks

--- test/io/perun_test.clj
+++ test/io/perun_test.clj
@@ -249,6 +249,10 @@
                         :msg "`atom-feed` should write atom.xml"))

         (p/render :renderer 'io.perun-test/render)
+        (testing "render"
+          (content-check :path "public/test/index.html"
+                         :content "<body>"
+                         :msg "`render` should modify a page"))

         (add-txt-file :path "test.js" :content js-content)
         (p/inject-scripts :scripts #{"test.js"})
@@ -378,6 +382,13 @@
                   :extensions [".htm"]
                   :out-dir "bar"
                   :meta {:set-by-render true})
+        (testing "render"
+          (content-check :path "bar/hammock/foo.htm"
+                         :content "<body>"
+                         :msg "`render` should modify a page")
+          (value-check :path "bar/hammock/foo.htm"
+                       :value-fn #(meta= %1 %2 :set-by-render true)
+                       :msg "`render` should set metadata"))

         (add-txt-file :path "test.js" :content js-content)
         (add-txt-file :path "baz.htm" :content "<body></body>")


Remove sleep hack.

Remove sleep hack.

--- test/onyx/test_job.clj
+++ test/onyx/test_job.clj
@@ -189,9 +189,6 @@
     (let [env-t (component/start (map->TestEnv config))]
       (try
         (add-peers env-t 10)
-        ;; TODO look into why this has issues
-        ; Not sure why this would affect anything
-        (Thread/sleep 10000)
         (is (= {:out [{:n 2} :done]
                 :inc_out [{:n 2} :done]}
                @(run-job env-t (add-debug-output-tasks


rename

rename

--- src/otp_api_proxy/core.clj
+++ src/otp_api_proxy/core.clj
@@ -377,7 +377,7 @@
                    plan->add-route-span
                    )))

-(defresource ws-otp-simplify [get-params]
+(defresource ws-otp-merge-by-route-sequence [get-params]
   :available-media-types ["application/json" "text/plain"]
   :handle-ok (pretty-json
                (-> (otp-request-live get-params)
@@ -423,8 +423,8 @@
   (context "/trip-planner/:otp-instance" [otp-instance]
      (ANY "/plan" request
        (ws-otp-with-args (:params request)))
-     (ANY "/plan-simplify" request
-       (ws-otp-simplify (:params request)))
+     (ANY "/plan-merge-by-route-sequence" request
+       (ws-otp-merge-by-route-sequence (:params request)))
      (ANY "/plan-cooked" []
        (ws-otp-cooked))
      (ANY "/pass-through" request


Adding a bit more logging to dependencies.

* this helps debug broken dependency handlers

--- src/overtone/libs/deps.clj
+++ src/overtone/libs/deps.clj
@@ -59,18 +59,21 @@

 (defn- satisfy*
   [{:keys [satisfied todo done]} new-deps]
-  ;(log/info (format "new-deps: %s" new-deps))
   (let [satisfied (set/union satisfied new-deps)
-        ;_ (log/info (format "satisfied: %s" satisfied))
         execute-tasks (fn [[final-done final-todo] [key deps task]]
-                        ;(log/info (format "Satisfied? = %s --- sat: %s deps: %s" (set/superset? satisfied deps) satisfied deps))
                         (if (set/superset? satisfied deps)
                           (do
-                            ;(log/info "Satisfying deps: " deps)
-                            (task)
+                            (log/info "Running dep handler: " key)
+                            (try
+                              (task)
+                              (catch Exception e
+                                (log/error (format "Exception in dependency handler: %s\n%s"
+                                                   key
+                                                   (with-out-str (.printStackTrace e))))))
                             [(conj final-done [key deps task]) final-todo])
                           [final-done (conj final-todo [key deps task])]))
         [t-done t-todo] (reduce execute-tasks [done []] todo)]
+    (log/info "deps-satisfied: " satisfied)
     {:satisfied satisfied
      :done t-done
      :todo t-todo}))
@@ -99,6 +102,7 @@
   "Specifies that a list of dependencies have been satisfied. Uses an agent so
   it's safe to call this from within a transaction."
   [& deps]
+  (log/info (format "satisfying deps: %s" deps))
   (send-off dep-state* satisfy* (set deps)))

 (defn reset-deps
@@ -133,19 +137,22 @@

 (defn wait-until-deps-satisfied
   "Makes the current thread sleep until specified deps have been satisfied.
-  Thread enters a sleep cycle sleeping for wait-time ms before each dep check.
+  Thread enters a sleep cycle sleeping for wait-time seconds before each dep check.
   If timeout is a positive value throws timeout exception if deps haven't been
-  satisfied by timeout ms. Default wait-time is 100ms and default timeout is
-  10000 ms"
-  ([deps] (wait-until-deps-satisfied deps 10000 100))
-  ([deps timeout] (wait-until-deps-satisfied deps timeout 100))
+  satisfied by timeout secs. The default wait-time is 0.1 seconds, and the
+  default timeout is 10 seconds."
+  ([deps] (wait-until-deps-satisfied deps 10 0.1))
+  ([deps timeout] (wait-until-deps-satisfied deps timeout 0.1))
   ([deps timeout wait-time]
+   (let [timeout (* 1000 timeout)
+         wait-time (* 1000 wait-time)]
      (if (<= timeout 0)
        (while (not (deps-satisfied? deps))
          (Thread/sleep wait-time))
        (loop [sleep-time 0]
          (when (> sleep-time timeout)
-           (throw (Exception. (str "The following deps took too long to be satisfied: " deps))))
+           (throw (Exception. (str "The following deps took too long (" timeout
+                                   " seconds) to be satisfied: " deps))))
          (when-not (deps-satisfied? deps)
            (Thread/sleep wait-time)
-           (recur (+ sleep-time wait-time)))))))
+           (recur (+ sleep-time wait-time))))))))


use 'path' and 'args' as returned by 'load-sample' in 'player' function.

--- src/overtone/sc/sample.clj
+++ src/overtone/sc/sample.clj
@@ -116,12 +116,12 @@

   "
   [path & args]
-  (let [s          (load-sample path args)
-        player     (fn [& pargs]
-                     (let [id (:id (get @loaded-samples* [path args]))]
-                       (if (empty? pargs)
-                         (mono-player id)
-                         (apply mono-player id pargs))))]
+  (let [{:keys [path args] :as s} (apply load-sample path args)
+        player (fn [& pargs]
+                 (let [id (:id (get @loaded-samples* [path args]))]
+                   (if (empty? pargs)
+                     (mono-player id)
+                     (apply mono-player id pargs))))]
     (callable-map (merge {:player player} s)
                   player)))


get sub-process stdout with :out. Thanks to MHOOO for pointing this out.

--- src/overtone/sc/server.clj
+++ src/overtone/sc/server.clj
@@ -110,7 +110,7 @@
   a better strategy to auto-connect."
   ([] (connect-jack-ports 2))
   ([n-channels]
-     (let [port-list (sh "jack_lsp")
+     (let [port-list (:out (sh "jack_lsp"))
            sc-ins         (re-seq #"SuperCollider.*:in_[0-9]*" port-list)
            sc-outs        (re-seq #"SuperCollider.*:out_[0-9]*" port-list)
            system-ins     (re-seq #"system:capture_[0-9]*" port-list)


refactor type inference

refactor type inference

--- src/main/clojure/cljs/analyzer.cljc
+++ src/main/clojure/cljs/analyzer.cljc
@@ -112,8 +112,7 @@
 #?(:cljs
    (def STRING_SYM 'string))

-#?(:cljs
-   (def BOOLEAN_SYM 'boolean))
+(def BOOLEAN_SYM 'boolean)

 #?(:cljs
    (def JS_STAR_SYM 'js*))
@@ -126,6 +125,10 @@

 #?(:cljs
    (def CLJS_CORE_SYM 'cljs.core))
+
+(def IGNORE_SYM 'ignore)
+
+(def ANY_SYM 'any)

 #?(:cljs
    (defn ^boolean cljs-seq? [x]
@@ -740,15 +743,66 @@
   #?(:cljs {:tag boolean})
   [env t]
   ;; don't use resolve-existing-var to avoid warnings
-  (when (and t (symbol? t))
-    (let [var (resolve-var env t)]
-      (or (:type var)
-          (-> var :info :type)
-          (:protocol-symbol var)
-          ;; need to hard code some cases because of
-          ;; forward declaration - David
-          ('#{cljs.core/PersistentHashMap
-              cljs.core/List} t)))))
+  (when (and (not (nil? t)) (symbol? t))
+    (let [var (resolve-var env t)
+          type (:type var)]
+      (if-not (nil? type)
+        type
+        (let [type (-> var :info :type)]
+          (if-not (nil? type)
+            type
+            (let [proto (:protocol-symbol var)]
+              (if-not (nil? proto)
+                proto
+                (get '#{cljs.core/PersistentHashMap cljs.core/List} t)))))))))
+
+(declare infer-tag)
+
+(def NOT_NATIVE '#{clj not-native})
+
+(def BOOLEAN_OR_SEQ '#{boolean seq})
+
+(defn infer-if [env e]
+  (let [{{:keys [op form]} :test} e
+        then-tag (infer-tag env (:then e))]
+    (if (and #?(:clj (= op :constant)
+                :cljs (keyword-identical? op :constant))
+             (not (nil? form))
+             (not (false? form)))
+      then-tag
+      (let [else-tag (infer-tag env (:else e))]
+        (cond
+          (or #?(:clj (= then-tag else-tag)
+                 :cljs (symbol-identical? then-tag else-tag))
+              #?(:clj (= else-tag IGNORE_SYM)
+                 :cljs (symbol-identical? else-tag IGNORE_SYM))) then-tag
+          #?(:clj (= then-tag IGNORE_SYM)
+             :cljs (symbol-identical? then-tag IGNORE_SYM)) else-tag
+          ;; TODO: temporary until we move not-native -> clj - David
+          (and (or (not (nil? (get NOT_NATIVE then-tag))) (type? env then-tag))
+               (or (not (nil? (get NOT_NATIVE else-tag))) (type? env else-tag)))
+          'clj
+          :else
+          (if (and (not (nil? (get BOOLEAN_OR_SEQ then-tag)))
+                   (not (nil? (get BOOLEAN_OR_SEQ else-tag))))
+            'seq
+            (let [then-tag (if #?(:clj (set? then-tag)
+                                  :cljs (cljs-set? then-tag))
+                             then-tag #{then-tag})
+                  else-tag (if #?(:clj (set? else-tag)
+                                  :cljs (cljs-set? else-tag))
+                             else-tag #{else-tag})]
+              (into then-tag else-tag))))))))
+
+(defn infer-invoke [env e]
+  (let [{info :info :as f} (:f e)
+        ret-tag (when-not (nil? (:fn-var info)) (:ret-tag info))]
+    (if-not (nil? ret-tag)
+      ret-tag
+      (let [ret-tag (infer-tag env (assoc (find-matching-method f (:args e)) :op :method))]
+        (if-not (nil? ret-tag)
+          ret-tag
+          ANY_SYM)))))

 (defn infer-tag
   "Given env, an analysis environment, and e, an AST node, return the inferred
@@ -757,47 +811,24 @@
   (if-let [tag (get-tag e)]
     tag
     (case (:op e)
-      :recur 'ignore
-      :throw 'ignore
-      :let (infer-tag env (:expr e))
-      :loop (infer-tag env (:expr e))
-      :do  (infer-tag env (:ret e))
-      :method (infer-tag env (:expr e))
-      :def (infer-tag env (:init e))
-      :invoke (let [{info :info :as f} (:f e)]
-                (or (and (:fn-var info) (:ret-tag info))
-                    (infer-tag env
-                      (assoc (find-matching-method f (:args e)) :op :method))
-                    'any))
-      :if (let [{{:keys [op form]} :test} e
-                then-tag (infer-tag env (:then e))]
-            (if (and (= op :constant)
-                     (not (#{nil false} form)))
-              then-tag
-              (let [else-tag (infer-tag env (:else e))]
-                (cond
-                  (or (= then-tag else-tag)
-                    (= else-tag 'ignore)) then-tag
-                  (= then-tag 'ignore) else-tag
-                  ;; TODO: temporary until we move not-native -> clj - David
-                  (and (or ('#{clj not-native} then-tag) (type? env then-tag))
-                    (or ('#{clj not-native} else-tag) (type? env else-tag)))
-                  'clj
-                  :else
-                  (if (every? '#{boolean seq} [then-tag else-tag])
-                    'seq
-                    (let [then-tag (if (set? then-tag) then-tag #{then-tag})
-                           else-tag (if (set? else-tag) else-tag #{else-tag})]
-                      (into then-tag else-tag)))))))
+      :recur    IGNORE_SYM
+      :throw    IGNORE_SYM
+      :let      (infer-tag env (:expr e))
+      :loop     (infer-tag env (:expr e))
+      :do       (infer-tag env (:ret e))
+      :method   (infer-tag env (:expr e))
+      :def      (infer-tag env (:init e))
+      :invoke   (infer-invoke env e)
+      :if       (infer-if env e)
       :constant (case (:form e)
-                  true 'boolean
-                  false 'boolean
-                  'any)
-      :var (if (:init e)
-             (infer-tag env (:init e))
-             (infer-tag env (:info e)))
-      :dot 'any
-      :js 'any
+                  true BOOLEAN_SYM
+                  false BOOLEAN_SYM
+                  ANY_SYM)
+      :var      (if (:init e)
+                  (infer-tag env (:init e))
+                  (infer-tag env (:info e)))
+      :dot      ANY_SYM
+      :js       ANY_SYM
       nil)))

 (defmulti parse (fn [op & rest] op))


update transformer

update transformer

--- src/graphql_clj/parser.clj
+++ src/graphql_clj/parser.clj
@@ -48,10 +48,11 @@
 (def transformation-test
   {:OperationDefinition (fn operation-definition [& args]
                           (println "operation-definition: " args)
-                          (let [definition (into {} args)
-                                type (:OperationType definition)
-                                selection-set (:selection-set definition)]
-                            (into [:operation-definition {:operation-type type}] selection-set)))
+                          (let [definition (into {} args)]
+                            [:operation-definition definition]))
+   :OperationType (fn operation-type [type]
+                    (println "operation-type: " type)
+                    [:operation-type type])
    :Definition (fn definition [definition]
                  (println "definition: " definition)
                  definition)
@@ -86,15 +87,20 @@
    parse-tree))

 (def execution-transform-map
+  "Deprecated"
   {:document (fn document [& args]
                (println "document: " args)
                (let [v (into {} args)]
                  {:data v}))
    :operation-definition (fn operation-definition [& args]
-                           (let [v (into {:parant :root} args)
+                           (println "operation-definition: " args)
+                           (let [props (first args)
+                                 v (into {:parant :root} args)
                                  name (or (:OperationType v))]
                              [name v]))
    })
+
+

 (defn execute
   [graph]


Execution for fragment

Execution for fragment

(execute (transformer (parse "query {user { ...userFields friends {name}}} fragment userFields on UserType {id name}")) (graphql-clj.type/create-type-meta-fn graphql-clj.type/demo-schema))

--- src/graphql_clj/parser.clj
+++ src/graphql_clj/parser.clj
@@ -165,9 +165,11 @@
 (defn collect-selection-fn
   [fragments]
   (fn [col selection]
-    (log/debug "collect-selection: " selection)
+    (log/debug "collect-selection-fn: " selection)
+    (log/debug "collect-selection-fn: col: " col)
     (let [selection-type (get-selection-type selection)
           response-key (get-selection-name selection)]
+      (log/debug "selection-type: " selection-type)
       (case selection-type
         :field (conj col selection)
         ;; (throw (ex-info "TODO: add suport for selection type :fragment-spread") {})
@@ -179,7 +181,8 @@
 (defn collect-fields
   "CollectFields(objectType, selectionSet, visitedFragments)"
   [object-type selection-set fragments]
-  (reduce (collect-selection-fn fragments) [] selection-set))
+  (log/debug "collect-fields: selection-set" selection-set)
+  (log/spy (reduce (collect-selection-fn fragments) [] selection-set)))

 (comment ; Type kind
   :SCALAR
@@ -271,7 +274,7 @@
 (declare execute-fields)

 (defn complete-value
-  [type-meta-fn field-type result sub-selection-set]
+  [type-meta-fn field-type result sub-selection-set fragments]
   (log/debug "*** complete-value: ")
   (log/debug "field-type: " field-type)
   (log/debug "result: " result)
@@ -285,11 +288,11 @@
     (cond
       (is-scalar-field-type? field-type) result
       (is-enum-field-type? field-type) result
-      (is-object-field-type? field-type) (log/spy (execute-fields type-meta-fn field-type result sub-selection-set))
-      (is-list-field-type? field-type) (log/spy (map #(execute-fields type-meta-fn (type-meta-fn (:innerType field-type)) % sub-selection-set) result))
+      (is-object-field-type? field-type) (log/spy (execute-fields type-meta-fn field-type result sub-selection-set fragments))
+      (is-list-field-type? field-type) (log/spy (map #(execute-fields type-meta-fn (type-meta-fn (:innerType field-type)) % sub-selection-set fragments) result))
       :else (throw (ex-info (format "Unhandled field type %s." field-type) {:field-type field-type})))))

-(defn get-field-entry [type-meta-fn parent-type parent-object field]
+(defn get-field-entry [type-meta-fn parent-type parent-object field fragments]
   (log/debug "*** get-field-entry: " field)
   (let [first-field-selection field
         response-key (get-selection-name first-field-selection)
@@ -298,20 +301,22 @@
     (log/debug "field-type" field-type)
     (if (not (nil? field-type))
       (let [resolved-object (resolve-field-on-object parent-object field-type field-entry)
-            field-selection-set (get-field-selection-set field)]
-        (log/debug "get-field-entry: field-selection-set: " field-selection-set)
+            field-selection-set (get-field-selection-set field)
+            fields (collect-fields field-type field-selection-set fragments)]
+        (log/debug "get-field-entry: fields: " fields)
+        (log/debug "get-field-entry: resolved-object: " resolved-object)
         (if (nil? resolved-object)
           [response-key nil] ; If resolvedObject is null, return
                              ; tuple(responseKey, null), indicating
                              ; that an entry exists in the result map
                              ; whose value is null.
           (let [;; sub-selection-set (merge-selection-sets field-selection-set)
-                response-value (complete-value type-meta-fn field-type resolved-object field-selection-set)]
+                response-value (complete-value type-meta-fn field-type resolved-object fields fragments)]
             [response-key (log/spy response-value)])))
       (log/debug "WARNING: field-type is nil!"))))

 (defn execute-fields
-  [type-meta-fn parent-type root-value fields]
+  [type-meta-fn parent-type root-value fields fragments]
   (log/debug "*** execute-fields")
   (log/debug "execute-fields: parent-type: " parent-type)
   (log/debug "execute-fields: root-value: " root-value)
@@ -320,7 +325,7 @@
                   (let [response-key (get-selection-name field)
                         ;; field-type (get-field-type-from-object-type parent-type field)
                         ;; resolved-object (resolve-field-on-object field-type root-value field)
-                        field-entry (get-field-entry type-meta-fn parent-type root-value field)]
+                        field-entry (get-field-entry type-meta-fn parent-type root-value field fragments)]
                     (log/spy field-entry)))
                 fields)))

@@ -330,7 +335,7 @@
         _ (println "fragments: " fragments)
         object-type (type-meta-fn :query)
         fields (collect-fields object-type selection-set fragments)]
-    (execute-fields type-meta-fn object-type :root fields)))
+    (execute-fields type-meta-fn object-type :root fields fragments)))

 (defn execute-definition
   [definition type-meta-fn]


Add WebFX as the main class for the jar manifest

That makes it into a standalone command-line "app-ifier" that can be
configured via command line arguments.

--- build.boot
+++ build.boot
@@ -11,7 +11,8 @@
       :url         "https://github.com/RadicalZephyr/webfx"
       :scm         {:url "https://github.com/RadicalZephyr/webfx"}
       :license     {"Eclipse Public License"
-                    "http://www.eclipse.org/legal/epl-v10.html"}})
+                    "http://www.eclipse.org/legal/epl-v10.html"}}
+ jar {:main 'radicalzephyr.WebFX})

 (deftask build
   "Build and install the project locally."


Start working on version 0.1.1

Start working on version 0.1.1

--- build.boot
+++ build.boot
@@ -11,7 +11,7 @@
 (require '[radicalzephyr.bootlaces :refer :all]
          '[radicalzephyr.boot-junit :refer [junit]])

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

 (bootlaces! +version+)


Fix typo in specs.alpha dependency exclusion

It caused problems downstream.

Cleaned up the require forms that refer to top-level tasks.

--- build.boot
+++ build.boot
@@ -49,10 +49,10 @@
  jar {:main        'frereth-cp.server
       :file        (str "frereth-cp-" version ".jar")})

-(require '[samestep.boot-refresh :refer [refresh]])
-(require '[tolitius.boot-check :as check])
-(require '[adzerk.boot-test :refer [test]])
-(require '[boot.pod :as pod])
+(require '[adzerk.boot-test :refer [test]]
+         '[boot.pod :as pod]
+         '[samestep.boot-refresh :refer [refresh]]
+         '[tolitius.boot-check :as check])

 (deftask build
   "Build the project locally as a JAR."


dependencies versions bumped up

dependencies versions bumped up

--- build.boot
+++ build.boot
@@ -3,28 +3,28 @@
  :resource-paths #{"resources"}
  :directories    #{"config"}
  :dependencies '[[org.clojure/clojure "1.9.0" :scope "provided"]
-                 [com.taoensso/carmine "2.16.0"]
+                 [com.taoensso/carmine "2.18.1"]
                  [org.mindrot/jbcrypt "0.4"]
                  [adzerk/bootlaces "0.1.13" :scope "test"]
                  [zilti/boot-midje "0.2.2-SNAPSHOT" :scope "test"]
-                 [com.h2database/h2 "1.4.196" :scope "test"]
-                 [mysql/mysql-connector-java "6.0.6" :scope "test"]
-                 [org.postgresql/postgresql "42.1.4" :scope "test"]
+                 [com.h2database/h2 "1.4.197" :scope "test"]
+                 [mysql/mysql-connector-java "8.0.11" :scope "test"]
+                 [org.postgresql/postgresql "42.2.4" :scope "test"]
                  [com.github.kstyrc/embedded-redis "0.6" :scope "test"]
-                 [ring/ring-defaults "0.3.1"]
-                 [midje "1.9.0" :scope "test"]
-                 [peridot "0.5.0" :scope "test"]
-                 [compojure "1.6.0" :scope "test"]
-                 [http-kit "2.2.0" :scope "test"]
+                 [ring/ring-defaults "0.3.2"]
+                 [ring/ring-anti-forgery "1.3.0"]
+                 [midje "1.9.2" :scope "test"]
+                 [peridot "0.5.1" :scope "test"]
+                 [compojure "1.6.1" :scope "test"]
+                 [http-kit "2.3.0" :scope "test"]
                  [cprop "0.1.11"]
                  [conman "0.7.4"]
-                 [mount "0.1.11"]
+                 [mount "0.1.12"]
                  [crypto-random "1.2.0"]
-                 [selmer "1.11.3"]
-                 [failjure "1.2.0"]
-                 [ring-anti-forgery "0.3.0"]
+                 [selmer "1.11.8"]
+                 [failjure "1.3.0"]
                  [ring-middleware-format "0.7.2"]
-                 [digest "1.4.6"]])
+                 [digest "1.4.8"]])

 (def +version+ "1.0.0-SNAPSHOT")


build.boot

build.boot

--- build.boot
+++ build.boot
@@ -3,6 +3,12 @@
   :version "0.1.0"
   :resource-paths #{"src" "resources"}
   :source-paths #{"src"}
+  :description "A toolkit for processing jar files"
+  :url "https://github.com/irresponsible/unscrew"
+  :scm {:url "https://github.com/irresponsible/unscrew.git"}
+  :developers {"James Laver" "james@seriesofpipes.com"}
+  :license {"MIT" "https://en.wikipedia.org/MIT_License"}
+  :repositories [["clojars" {:url "https://clojars.org/repo/"}]]
   :dependencies '[[org.clojure/clojure "1.8.0" :scope "provided"]
                   [byte-streams "0.2.1-alpha1"]
                   [me.raynes/fs     "1.4.6"    :scope "test"]
@@ -14,19 +20,19 @@
 (require '[adzerk.boot-test :as t])

 (task-options!
-  pom {:project (get-env :project)
-       :version (get-env :version)
-       :description "A toolkit for processing jar files"
-       :url "https://github.com/irresponsible/unscrew"
-       :scm {:url "https://github.com/irresponsible/unscrew.git"}
-       :developers {"James Laver" "james@seriesofpipes.com"}
-       :license {"MIT" "https://en.wikipedia.org/MIT_License"}}
+  pom {:url         (get-env :url)
+       :scm         (get-env :scm)
+       :project     (get-env :project)
+       :version     (get-env :version)
+       :license     (get-env :license)
+       :description (get-env :description)
+       :developers  (get-env :developers)}
   push {:tag            true
         :ensure-branch  "master"
         :ensure-release true
         :ensure-clean   true
         :gpg-sign       true
-        :repositories [["clojars" {:url "https://clojars.org/repo/"}]]}
+        :repositories (get-env :repositories)}
   target  {:dir #{"target"}})

 (deftask tests []


Fix travis self-hosted build #2

Fix travis self-hosted build #2

--- build.boot
+++ build.boot
@@ -135,7 +135,7 @@
             (proc "lumo"
                   "-c" (str "\"" (System/getProperty "fake.class.path") "\"")
                   "-k" "lumo_cache"
-                  "src/test/cljs/mikron/test_runner/node2.cljs")
+                  "src/test/cljs/mikron/test_runner/node.cljs")
             (boot-cljs-test/test-cljs :js-env        :node
                                       :namespaces    cljs-test-namespaces
                                       :optimizations opt


bump a couple deps

bump a couple deps

There are several more Java libraries with more recent versions, but I don't have time to test them at the moment.

--- build.boot
+++ build.boot
@@ -2,10 +2,10 @@
   :source-paths #{"src"}
   :dependencies '[; dev
                   [adzerk/bootlaces      "0.1.13" :scope "test"]
-                  [adzerk/boot-test      "1.0.4"  :scope "test"]
+                  [adzerk/boot-test      "1.1.2"  :scope "test"]
                   [str-to-argv           "0.1.0"  :scope "test"]
                   ; needed in order to run the "alda repl" command in dev
-                  [alda/core             "0.1.0"  :scope "test"]
+                  [alda/core             "0.1.1"  :scope "test"]
                   [alda/sound-engine-clj "0.1.0"  :scope "test"]
                   [alda/repl-clj         "0.1.0"  :scope "test"]


[#1845] Add instance details to import flow data ex

Relates to https://sentry.io/akvo-foundation/production/issues/830056719

--- backend/src/akvo/lumen/lib/import/flow.clj
+++ backend/src/akvo/lumen/lib/import/flow.clj
@@ -24,9 +24,14 @@
       (close [this])
       p/DatasetImporter
       (columns [this]
-        (cond
-          (<= version 2) (v2/dataset-columns (flow-common/form @survey formId))
-          (<= version 3) (v3/dataset-columns (flow-common/form @survey formId))))
+        (try
+          (cond
+            (<= version 2) (v2/dataset-columns (flow-common/form @survey formId))
+            (<= version 3) (v3/dataset-columns (flow-common/form @survey formId)))
+          (catch Throwable e
+            (if-let [ex-d (ex-data e)]
+              (throw (ex-info (:cause e) (assoc ex-d :instance instance)))
+              (throw e)))))
       (records [this]
         (try
           (cond


Adds styling to additional messages

Adds styling to additional messages

--- src/hphelper/live/view.clj
+++ src/hphelper/live/view.clj
@@ -119,7 +119,8 @@
                    )
                  ;; Extra Messages
                  (if-let [messages (:msgs u)]
-                   [:div
+                   [:div {:class "data"}
+                    [:h3 "Additional Messages"]
                     (map (fn [^String msg] [:div msg]) messages)
                     ]
                    )


Add new Interface for Meta Data.

Add new Interface for Meta Data.

--- src/konserve/filestore.clj
+++ src/konserve/filestore.clj
@@ -57,9 +57,9 @@

 (def version 1)

-(def compresson 1)
-
-(def encrypt 1)
+(def compressor 1)
+
+(def encryptor 1)

 (defprotocol BlobToChannel
   (blob->channel [input buffer-size]))
@@ -171,7 +171,7 @@
   (let [int-bb           (ByteBuffer/allocate 4)
         _                (.putInt int-bb meta)
         meta-array       (.array int-bb)
-        env-array        (byte-array [version compresson encrypt serializer])
+        env-array        (byte-array [version compressor encryptor serializer])
         return-buffer    (ByteBuffer/allocate 8)
         _                (.put return-buffer env-array)
         _                (.put return-buffer meta-array)


indentation of (get-string)

indentation of (get-string)

--- src/babel/espanol/morphology.clj
+++ src/babel/espanol/morphology.clj
@@ -49,150 +49,147 @@
                               vosotros :vosotros
                               ustedes :ustedes
                               }]]
-  (cond (string? word)
-        word
-        (seq? word)
-        (map (string/join " " #(get-string-1 %))
-             word)
-        true
-  (let [person (get-in word '(:agr :person))
-        number (get-in word '(:agr :number))
-        info (log/debug "get-string-1: input word: " word)
-        vosotros (if vosotros vosotros true)
-        ustedes (if ustedes ustedes false)
-        tú (if tú tú false)
-        usted (if usted usted false)]
-
-    (log/debug (str "get-string-1: word: " word))
-    (log/debug (str "get-string-1: word (stripped-refs): " (strip-refs word)))
-    (log/debug (str "word's a is a string? " (get-in word '(:a)) " => " (string? (get-in word '(:a)))))
-    (log/debug (str "word's b is a map? " (get-in word '(:b)) " => " (map? (get-in word '(:b)))))
-
-    (log/debug (str "word's a espanol is a string? " (get-in word '(:a :espanol)) " => " (string? (get-in word '(:a :espanol)))))
-
-    (cond
-
-     (= word :top) ".."
-
-     (ref? word)
-     (get-string-1 @word)
-
-     ;; TODO: this is a special case that should be handled below instead
-     ;; of forcing every input to go through this check.
-     (= word {:initial false})
-     ".."
-     (= word {:initial true})
-     ".."
-
-     (and (string? (get-in word '(:a)))
-          (string? (get-in word '(:b))))
-     (get-string (get-in word '(:a))
-                 (get-in word '(:b)))
-
-     (and (string? (get-in word '(:a)))
-          (map? (get-in word '(:b))))
-     (get-string (get-in word '(:a))
-                 (get-in word '(:b)))
-
-     (and (map? (get-in word '(:a)))
-          (map? (get-in word '(:b))))
-     (get-string
-      (get-in word '(:a))
-      (get-in word '(:b)))
-
-     ;; TODO: this rule is pre-empting all of the following rules
-     ;; that look in :a and :b. Either remove those following rules
-     ;; if they are redundant and not needed, or move this general rule
-     ;; below the following rules.
-     (and (not (= :none (get-in word '(:a) :none)))
-          (not (= :none (get-in word '(:b) :none))))
-     (get-string (get-in word '(:a))
-                 (get-in word '(:b)))
-
-     (and
-      (string? (get-in word '(:a :espanol)))
-      (string? (get-in word '(:b :espanol)))
-      (or (= :none (get-in word '(:b :agr :number) :none))
-          (= :top (get-in word '(:b :agr :number) :none)))
-      )
-     (str (string/trim (get-in word '(:a :espanol)))
-          " "
-          (string/trim (get-in word '(:b :espanol))))
-
-     (and
-      (string? (get-in word '(:a)))
-      (string? (get-in word '(:b :espanol)))
-      (or (= :none (get-in word '(:b :agr :number) :none))
-          (= :top (get-in word '(:b :agr :number) :none)))
-      )
-     (str (string/trim (get-in word '(:a)))
-          " "
-          (string/trim (get-in word '(:b :espanol))))
-
-     (and
-      (string? (get-in word '(:a :espanol)))
-      (get-in word '(:a :espanol))
-      (or (= :none (get-in word '(:b :agr :number) :none))
-          (= :top (get-in word '(:b :agr :number) :none)))
-      (= (get-in word '(:a :infl)) :top))
-     (string/trim (str (get-in word '(:a :espanol))
-                 " " (get-string-1 (get-in word '(:b)))))
-
-     (= true (get-in word [:exception]))
-     (get-in word [:espanol])
-
-     (and
-      (= (get-in word '(:infl)) :conditional)
-      (string? (get-in word '(:espanol))))
-     (verbs/conditional word
-                        {:usted usted
-                         :tú tú
-                         :vosotros vosotros
-                         :ustedes ustedes
-                         })
-     (and
-      (= (get-in word '(:infl)) :futuro)
-      (string? (get-in word '(:espanol))))
-     (verbs/future word
-                   {:usted usted
-                    :tú tú
-                    :vosotros vosotros
-                    :ustedes ustedes
-                    })
-     (and
-      (= (get-in word '(:infl)) :imperfetto)
-      (string? (get-in word '(:espanol))))
-     (verbs/imperfect word
-                      {:usted usted
-                       :tú tú
-                       :vosotros vosotros
-                       :ustedes ustedes
-                       })
-     (and
-      (= (get-in word '(:infl)) :present)
-      (string? (get-in word '(:espanol))))
-     (verbs/present word
+  (cond
+   (string? word)
+   word
+   (seq? word)
+   (map (string/join " " #(get-string-1 %))
+        word)
+   (= word :top) ".."
+   (ref? word)
+   (get-string-1 @word)
+   (map? word)
+   (let [person (get-in word '(:agr :person))
+         number (get-in word '(:agr :number))
+         info (log/debug "get-string-1: input word: " word)
+         vosotros (if vosotros vosotros true)
+         ustedes (if ustedes ustedes false)
+         tú (if tú tú false)
+         usted (if usted usted false)]
+     (log/debug (str "get-string-1: word: " word))
+     (log/debug (str "get-string-1: word (stripped-refs): " (strip-refs word)))
+     (log/debug (str "word's a is a string? " (get-in word '(:a)) " => " (string? (get-in word '(:a)))))
+     (log/debug (str "word's b is a map? " (get-in word '(:b)) " => " (map? (get-in word '(:b)))))
+
+     (log/debug (str "word's a espanol is a string? " (get-in word '(:a :espanol)) " => " (string? (get-in word '(:a :espanol)))))
+
+     (cond
+      ;; TODO: this is a special case that should be handled below instead
+      ;; of forcing every input to go through this check.
+      (= word {:initial false})
+      ".."
+      (= word {:initial true})
+      ".."
+
+      (and (string? (get-in word '(:a)))
+           (string? (get-in word '(:b))))
+      (get-string (get-in word '(:a))
+                  (get-in word '(:b)))
+
+      (and (string? (get-in word '(:a)))
+           (map? (get-in word '(:b))))
+      (get-string (get-in word '(:a))
+                  (get-in word '(:b)))
+
+      (and (map? (get-in word '(:a)))
+           (map? (get-in word '(:b))))
+      (get-string
+       (get-in word '(:a))
+       (get-in word '(:b)))
+
+      ;; TODO: this rule is pre-empting all of the following rules
+      ;; that look in :a and :b. Either remove those following rules
+      ;; if they are redundant and not needed, or move this general rule
+      ;; below the following rules.
+      (and (not (= :none (get-in word '(:a) :none)))
+           (not (= :none (get-in word '(:b) :none))))
+      (get-string (get-in word '(:a))
+                  (get-in word '(:b)))
+
+      (and
+       (string? (get-in word '(:a :espanol)))
+       (string? (get-in word '(:b :espanol)))
+       (or (= :none (get-in word '(:b :agr :number) :none))
+           (= :top (get-in word '(:b :agr :number) :none)))
+       )
+      (str (string/trim (get-in word '(:a :espanol)))
+           " "
+           (string/trim (get-in word '(:b :espanol))))
+
+      (and
+       (string? (get-in word '(:a)))
+       (string? (get-in word '(:b :espanol)))
+       (or (= :none (get-in word '(:b :agr :number) :none))
+           (= :top (get-in word '(:b :agr :number) :none)))
+       )
+      (str (string/trim (get-in word '(:a)))
+           " "
+           (string/trim (get-in word '(:b :espanol))))
+
+      (and
+       (string? (get-in word '(:a :espanol)))
+       (get-in word '(:a :espanol))
+       (or (= :none (get-in word '(:b :agr :number) :none))
+           (= :top (get-in word '(:b :agr :number) :none)))
+       (= (get-in word '(:a :infl)) :top))
+      (string/trim (str (get-in word '(:a :espanol))
+                        " " (get-string-1 (get-in word '(:b)))))
+
+      (= true (get-in word [:exception]))
+      (get-in word [:espanol])
+
+      (and
+       (= (get-in word '[:infl]) :conditional)
+       (string? (get-in word [:espanol])))
+      (verbs/conditional word
+                         {:usted usted
+                          :tú tú
+                          :vosotros vosotros
+                          :ustedes ustedes
+                          })
+      (and
+       (= (get-in word '(:infl)) :futuro)
+       (string? (get-in word '(:espanol))))
+      (verbs/future word
                     {:usted usted
                      :tú tú
                      :vosotros vosotros
                      :ustedes ustedes
                      })
-
-     (and
-      (= (get-in word '(:infl)) :preterito)
-      (string? (get-in word '(:espanol))))
-     (verbs/preterito word
-                      {:usted usted
-                       :tú tú
-                       :vosotros vosotros
-                       :ustedes ustedes
-                       })
+      (and
+       (= (get-in word '(:infl)) :imperfetto)
+       (string? (get-in word '(:espanol))))
+      (verbs/imperfect word
+                       {:usted usted
+                        :tú tú
+                        :vosotros vosotros
+                        :ustedes ustedes
+                        })
+      (and
+       (= (get-in word '(:infl)) :present)
+       (string? (get-in word '(:espanol))))
+      (verbs/present word
+                     {:usted usted
+                      :tú tú
+                      :vosotros vosotros
+                      :ustedes ustedes
+                      })
+
+      (and
+       (= (get-in word '(:infl)) :preterito)
+       (string? (get-in word '(:espanol))))
+      (verbs/preterito word
+                       {:usted usted
+                        :tú tú
+                        :vosotros vosotros
+                        :ustedes ustedes
+                        })

-     (string? (get-in word [:espanol]))
-     (get-in word [:espanol])
-
-     true
-     (throw (Exception. (str "get-string-1: don't know what to do with input argument: " word)))))))
+      (string? (get-in word [:espanol]))
+      (get-in word [:espanol])
+
+      true
+      (throw (Exception. (str "get-string-1: don't know what to do with input argument: " word)))))))

 (defn get-string [a & [ b ]]
   (cond (and (nil? b)


New taxonomy node -> html ul li conversion function - this time generates valid html - not integrated into main meta info generation yet (switched to previous pipeline in the interim) - tests also outdated

--- src/lonelyplanet/model.clj
+++ src/lonelyplanet/model.clj
@@ -74,11 +74,24 @@
                                                                     :attrs {:href (str link ".html")}
                                                                     :content link-text})]})))))

+(defn to-html-list-2
+  [loc]
+  (let [link-text (-> loc z/children first :content)
+        link (-> loc z/node (get-in [:attrs :geo_id]))
+        children (-> loc z/children)]
+    (-> (z/edit loc assoc :tag :ul :attrs {})
+        (z/edit assoc :content [])
+        (z/insert-child (x/map->Element {:tag     :li :attrs {:id link}
+                                         :content (concat [(x/map->Element {:tag     :a
+                                                                            :attrs   {:href (str link ".html")}
+                                                                            :content link-text})]
+                                                          children)})))))
+
 (defn transform-taxonomy-nodes
   "Transform a taxonomy zipper from the xml tag-based structure to an enlive-html tag-based structure suitable
   for rendering to HTML by enlive. Assumes it's operating from a root node tag, not the root <taxonomies> tag."
   [loc]
-  (if (= (-> loc z/node :tag) :node) (to-html-list loc) loc))
+  (if (= (-> loc z/node :tag) :node) (to-html-list-2 loc) loc))

 (defn prune-taxonomy-nodes
   "Remove nodes not in the set of :ul, :li or :a element types, or is a string."
@@ -121,7 +134,7 @@
         hierarchy (-> tax-zip z/next z/next (walk&transform-zipper transform-taxonomy-nodes)
                       z/root z/xml-zip z/next z/next (walk&transform-zipper prune-taxonomy-nodes)
                       z/root z/xml-zip z/next z/next z/node) ;; navigate to root :ul element
-        dest-metas (-> hierarchy gen-routes)
+        dest-metas (-> tax-zip leaves location-metas)
         destinations (-> destinations gen-parser :content)]
     {:destinations (for [destination destinations]
                      (let [destination-id (-> destination :attrs :atlas_id)]


renaming

renaming

--- src/clj/lambdacd/presentation/pipeline_state.clj
+++ src/clj/lambdacd/presentation/pipeline_state.clj
@@ -16,10 +16,10 @@
       has-waiting :waiting
       :else :unknown)))

-(defn- desc [a b]
+(defn- latest-first [a b]
   (compare b a))

-(defn- asc [a b]
+(defn- earliest-first [a b]
   (compare a b))

 (defn- not-waiting? [result]
@@ -33,10 +33,10 @@
        (first)))

 (defn- earliest-first-update [steps]
-  (first-with-key-ordered-by steps asc :first-updated-at))
+  (first-with-key-ordered-by steps earliest-first :first-updated-at))

 (defn- latest-most-recent-update [steps]
-  (first-with-key-ordered-by steps desc :most-recent-update-at))
+  (first-with-key-ordered-by steps latest-first :most-recent-update-at))

 (defn- history-entry [[k v]]
   (let [steps (vals v)]


Add tests for regressions checks.

Add tests for regressions checks.


Cheating/drunk mode works

Cheating/drunk mode works

--- src/cheating_countdown/core.cljs
+++ src/cheating_countdown/core.cljs
@@ -9,7 +9,8 @@
 (enable-console-print!)

 ;;Defining app state
-(def app-state (atom {:deadline nil }))
+(def app-state (atom {:deadline nil
+                      :drunk false }))

 ;;Date related helpers
 (defn date-gen
@@ -44,6 +45,33 @@
             seconds (rem seconds unit)]
         (recur (rest units) seconds (conj out unit-val))))))

+;;DOM related helpers
+
+(defn reset-dom-elements
+  [app]
+  (do
+    (-> (js/jQuery "#check-drunk") (.prop "checked" (:drunk app)))
+    (-> (js/jQuery "#datetimepicker") (.val (:deadline app)))))
+
+(defn is-checked []
+  (-> (js/jQuery "#check-drunk") (.prop "checked")))
+
+;;Undo related helpers
+
+(def app-history (atom [@app-state]))
+
+(add-watch app-state :history
+  (fn [_ _ _ n]
+    (when-not (= (last @app-history) n)
+      (swap! app-history conj n))))
+
+(defn undo
+  [event]
+  (when (> (count @app-history) 1)
+    (swap! app-history pop)
+    (reset! app-state (last @app-history))
+    (reset-dom-elements (last @app-history))))
+

 ;;Read deadline from URL
 (def deadline (.getParameterValue (Uri. (.-location js/window)) "date"))
@@ -82,7 +110,7 @@
       ;;Update remaining time in the app state every one second.
       (om/set-state! owner :interval
         (js/setInterval
-            #(om/set-state! owner :remaining (remaining (:deadline @app) false))
+            #(om/set-state! owner :remaining (remaining (:deadline @app) (:drunk @app)))
           1000)))

     om/IWillUnmount
@@ -125,19 +153,6 @@
     (render-state [this {:keys [deadline-chan]}]
       (form-display deadline-chan owner))))

-(def app-history (atom [@app-state]))
-
-(add-watch app-state :history
-  (fn [_ _ _ n]
-    (when-not (= (last @app-history) n)
-      (swap! app-history conj n))))
-
-(defn undo
-  [event]
-  (when (> (count @app-history) 1)
-    (swap! app-history pop)
-    (reset! app-state (last @app-history))))
-

 ;;Root component, composed of timer and form
 (defn countdown-timer
@@ -150,13 +165,19 @@
     om/IRenderState
     (render-state [this state]
       (dom/div nil
-               (dom/div nil (om/build count-view app {:init-state state}))
-               (dom/div nil (om/build datepicker-view app {:init-state state}))
-               (dom/div #js {:className "component spacer"}
-                        (dom/span #js {} "Counting down to: ")
-                        (dom/span #js {:id "deadline-display"}
-                            (when (not= nil (:deadline app)) (str (date-gen (:deadline app)))))
-                        (dom/span nil (dom/button #js {:onClick undo} "Undo")))))))
+         (dom/div nil (om/build count-view app {:init-state state}))
+         (dom/div nil (om/build datepicker-view app {:init-state state}))
+         (dom/div #js {:className "component spacer"}
+            (dom/span #js {} "Counting down to: ")
+            (dom/span #js {:id "deadline-display"}
+              (when (not= nil (:deadline app)) (str (date-gen (:deadline app)))))
+            (dom/span nil (dom/button #js {:onClick undo} "Undo"))
+            (dom/span nil
+              (dom/input #js {:type "checkbox"
+                              :id "check-drunk"
+                              :onClick
+                                (fn []
+                                  (om/update! app :drunk (is-checked))) } "Drunk")))))))

 (om/root countdown-timer app-state
   {:target (. js/document (getElementById "app"))})


Remove straggling reference to await-status! in dynamo tests

--- test/eulalie/dynamo_test.clj
+++ test/eulalie/dynamo_test.clj
@@ -37,9 +37,6 @@
               :else (do
                       (Thread/sleep 1000)
                       (recur)))))))
-
-(defn await-status!! [table status]
-  (<?! (await-status! table status)))

 (defn keys= [exp act ks]
   (= (select-keys exp ks) (select-keys act ks)))


Clean up comments and organize tests

Clean up comments and organize tests

--- test/expound/alpha_test.cljc
+++ test/expound/alpha_test.cljc
@@ -784,15 +784,9 @@
 (s/def :keys-spec/map-spec-3 (s/keys :req-un [:keys-spec/foo
                                               :keys-spec/child-2]))

-
-;; XXX New Tests
-;; Make sure that our changes work with s/keys
-
-
-(deftest keys-spec-2
-  (testing "More advanced key specs"
-    (is (= (pf
-            "-- Spec failed --------------------
+(deftest grouping-and-key-specs
+  (is (= (pf
+          "-- Spec failed --------------------

   {:foo 1.2, :bar ..., :baz ...}
         ^^^
@@ -821,12 +815,12 @@

 -------------------------
 Detected 3 errors\n")
-           (binding [s/*explain-out* (expound/custom-printer {:print-specs? false})]
-             (s/explain-str :keys-spec/map-spec-1 {:foo 1.2
-                                                   :bar 123
-                                                   :baz true}))))
-    (is (= (pf
-            "-- Spec failed --------------------
+         (binding [s/*explain-out* (expound/custom-printer {:print-specs? false})]
+           (s/explain-str :keys-spec/map-spec-1 {:foo 1.2
+                                                 :bar 123
+                                                 :baz true}))))
+  (is (= (pf
+          "-- Spec failed --------------------

   {:foo 1.2, :bar ..., :qux ...}
         ^^^
@@ -859,13 +853,13 @@

 -------------------------
 Detected 3 errors\n")
-           (binding [s/*explain-out* (expound/custom-printer {:print-specs? false})]
-             (s/explain-str :keys-spec/map-spec-2 {:foo 1.2
-                                                   :bar 123
-                                                   :qux false}))))
-
-    (is (=
-         "-- Spec failed --------------------
+         (binding [s/*explain-out* (expound/custom-printer {:print-specs? false})]
+           (s/explain-str :keys-spec/map-spec-2 {:foo 1.2
+                                                 :bar 123
+                                                 :qux false}))))
+
+  (is (=
+       "-- Spec failed --------------------

   {:foo 1.2, :child-2 ...}
         ^^^
@@ -911,11 +905,11 @@

 -------------------------
 Detected 4 errors\n"
-         (binding [s/*explain-out* (expound/custom-printer {:print-specs? false})]
-           (s/explain-str :keys-spec/map-spec-3 {:foo 1.2
-                                                 :child-2 {:bar 123
-                                                           :child-1 {:baz true
-                                                                     :qux false}}}))))))
+       (binding [s/*explain-out* (expound/custom-printer {:print-specs? false})]
+         (s/explain-str :keys-spec/map-spec-3 {:foo 1.2
+                                               :child-2 {:bar 123
+                                                         :child-1 {:baz true
+                                                                   :qux false}}})))))

 (s/def :multi-spec/value string?)
 (s/def :multi-spec/children vector?)
@@ -1059,7 +1053,6 @@
                :children [{:tag :group
                            :children [{:tag :group
                                        :props {:on-tap {}}}]}]})))))
-  ;; XXX New Test
   (testing "test that our new recursive spec grouping function works with
            alternative paths"
     (is (= (pf


Don't run new spec in CLJS

Don't run new spec in CLJS

--- test/expound/alpha_test.cljc
+++ test/expound/alpha_test.cljc
@@ -4203,52 +4203,53 @@
                               {}
                               {:print-specs? false}))))

-(deftype FakeDB [m]
-
-  clojure.lang.Seqable
-  (seq [_]
-    (seq m))
-
-  clojure.lang.IPersistentCollection
-
-  (count [_]
-    (count m))
-  (cons [_ o]
-    (throw (Exception. "FakeDB doesn't implement 'cons'")))
-  (empty [_]
-    (FakeDB. {}))
-  (equiv [_ o]
-    (=
-     m
-     (:m o)))
-
-  clojure.lang.Associative
-  (containsKey [_ k] (contains? m k))
-  (entryAt [_ k] (get m k))
-
-  clojure.lang.IPersistentMap
-  (assoc [this k v] (throw (Exception. "FakeDB doesn't implement 'assoc'")))
-  (assocEx [this k v] (throw (Exception. "FakeDB doesn't implement 'assocEx'")))
-  (without [this k] (throw (Exception. "FakeDB doesn't implement 'without'")))
-
-  clojure.lang.ILookup
-  (valAt [_ k]
-    (get m k))
-  (valAt [_ k not-found]
-    (get m k not-found)))
+#?(:clj
+   (deftype FakeDB [m]
+
+     clojure.lang.Seqable
+     (seq [_]
+       (seq m))
+
+     clojure.lang.IPersistentCollection
+
+     (count [_]
+       (count m))
+     (cons [_ o]
+       (throw (Exception. "FakeDB doesn't implement 'cons'")))
+     (empty [_]
+       (FakeDB. {}))
+     (equiv [_ o]
+       (=
+        m
+        (:m o)))
+
+     clojure.lang.Associative
+     (containsKey [_ k] (contains? m k))
+     (entryAt [_ k] (get m k))
+
+     clojure.lang.IPersistentMap
+     (assoc [this k v] (throw (Exception. "FakeDB doesn't implement 'assoc'")))
+     (assocEx [this k v] (throw (Exception. "FakeDB doesn't implement 'assocEx'")))
+     (without [this k] (throw (Exception. "FakeDB doesn't implement 'without'")))
+
+     clojure.lang.ILookup
+     (valAt [_ k]
+       (get m k))
+     (valAt [_ k not-found]
+       (get m k not-found))))

 (s/def ::db-val (s/or :i int? :s string?))

 ;; https://github.com/bhb/expound/issues/205
-(deftest unwalkable-values
-  ;; run bin/test-datomic for real test of datomic DB,
-  ;; but this at least simulates the failure. We should not
-  ;; try to walk arbitrary values
-  (let [db (FakeDB. {:a 1})]
-    (is (= true (map? db)))
-    (is (= "Success!\n"
-           (expound/expound-str some? db)))
-    (is (= "-- Spec failed --------------------
+#?(:clj (deftest unwalkable-values
+          ;; run bin/test-datomic for real test of datomic DB,
+          ;; but this at least simulates the failure. We should not
+          ;; try to walk arbitrary values
+          (let [db (FakeDB. {:a 1})]
+            (is (= true (map? db)))
+            (is (= "Success!\n"
+                   (expound/expound-str some? db)))
+            (is (= "-- Spec failed --------------------

   [{:a 1}]
    ^^^^^^
@@ -4262,5 +4263,5 @@
 -------------------------
 Detected 1 error
 "
-           (expound/expound-str (s/cat :db (s/keys
-                                            :req [::db-val])) [db])))))
+                   (expound/expound-str (s/cat :db (s/keys
+                                                    :req [::db-val])) [db]))))))


Add :moving-vertex to state and change it on click

--- src/constraint/core.cljs
+++ src/constraint/core.cljs
@@ -121,15 +121,13 @@

 (defn update-state [event world-state]
   (let [clicked-what (event->targetid event)
-        constrained-flip (partial flip-edge world-state)]
+        constrained-flip (partial flip-edge world-state)
+        is-edge? (re-matches #"edge.*" clicked-what)
+        is-vertex? (re-matches #"vertex.*" clicked-what)
+        ]
     (cond
-      (re-matches #"edge.*" clicked-what) (update-in world-state
-                                                     [:edges clicked-what]
-                                                     constrained-flip)
-
-      (re-matches #"vertex.*" clicked-what) (do
-                                               (.log js/console clicked-what)
-                                               world-state)
+      is-edge? (update-in world-state [:edges clicked-what] constrained-flip)
+      is-vertex? (update-in world-state [:moving-vertex] not)
       :else world-state)))

@@ -138,9 +136,10 @@
   (let [read-state (reader/read-string (<! (GET "./state.edn")))
         named-edges (update-in read-state [:edges]
                               (comp name-vertices-in-all-edges name-edges))
-        named-vertices (update-in named-edges [:vertices] name-vertices)]
+        named-vertices (update-in named-edges [:vertices] name-vertices)
+        state (conj named-vertices {:moving-vertex false})]
     (big-bang!
-      :initial-state named-vertices
+      :initial-state state
       :to-draw draw-world
       :on-click update-state))
   )