Update datomic version.

Update datomic version.

--- build.boot
+++ build.boot
@@ -11,7 +11,7 @@
                   [adzerk/boot-reload "0.4.0" :scope "test"]
                   [pandeiro/boot-http "0.6.3" :scope "test"]
                   [allgress/boot-tasks "0.2.3" :scope "test"]
-                  [com.datomic/datomic-pro "0.9.5130" :scope "test" :exclusions [org.apache.httpcomponents/httpclient]]])
+                  [com.datomic/datomic-pro "0.9.5327" :scope "test" :exclusions [org.apache.httpcomponents/httpclient]]])

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


Prep v0.0.2 release

Prep v0.0.2 release

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

 (def default-version
   "Really just for running inside docker w/out git tags"
-  "0.0.1-???-dirty")
+  "0.0.2-???-dirty")
 (defn deduce-version-from-git
   "Avoid another decade of pointless, unnecessary and error-prone
   fiddling with version labels in source code.


Update boot-test to 1.2.0

Update boot-test to 1.2.0

--- build.boot
+++ build.boot
@@ -12,7 +12,7 @@
                   [com.stuartsierra/component "0.3.2"]
                   [org.clojure/clojurescript "1.9.518"          :scope "test"]
                   [adzerk/boot-cljs "1.7.228-2"                 :scope "test"]
-                  [adzerk/boot-test "1.1.2"                     :scope "test"]
+                  [adzerk/boot-test "1.2.0"                     :scope "test"]
                   [crisptrutski/boot-cljs-test "0.2.2"          :scope "test"]])

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


Renamed range-for* functions

Renamed range-for* functions

--- parser/parser.clj
+++ parser/parser.clj
@@ -37,20 +37,20 @@
      (match input
             (Pair _ offset) offset))

-(def range-for-symbol (start end)
+(def symbol-range (start end)
      (Range (offset-of start) (offset-of end)))

 (def parse-symbol (input)
      (match (read-while atom-character? input)
             (Pair next-input Empty) (ParseOut input)
-            (Pair next-input name)  (ParseNext next-input (Symbol name (range-for-symbol input next-input)))))
+            (Pair next-input name)  (ParseNext next-input (Symbol name (symbol-range input next-input)))))

-(def range-for-list (start end)
+(def list-range (start end)
      (Range (- (offset-of start) 1) (offset-of end)))

 (def parse-list (input parse-expressions)
      (match (parse-expressions input Empty)
-            (Pair next-input expressions) (ParseNext next-input (List expressions (range-for-list input next-input)))))
+            (Pair next-input expressions) (ParseNext next-input (List expressions (list-range input next-input)))))

 (def parse-expression (input parse-expressions)
      (match input


rm create-pages

rm create-pages

--- examples/lesson-carousel-starter-kit/src/carousel/core.cljs
+++ examples/lesson-carousel-starter-kit/src/carousel/core.cljs
@@ -24,54 +24,6 @@
 (defonce Vec3 (.. math -Vec3))

 (defonce ABSOLUTE (.. Size -ABSOLUTE))
-
-(defn create-pages [root-node simulation]
-  (let [url-base "http://demo.famo.us.s3.amazonaws.com/hub/apps/carousel/Museo_del_Prado_-_Goya_-_Caprichos_-_No._"
-        image-names ["01_-_Autorretrato._Francisco_Goya_y_Lucientes2C_pintor_thumb.jpg"
-                     "02_-_El_si_pronuncian_y_la_mano_alargan_al_primero_que_llega_thumb.jpg"
-                     "03_-_Que_viene_el_Coco_thumb.jpg"
-                     "04_-_El_de_la_rollona_thumb.jpg"
-                     "05_-_Tal_para_qual_thumb.jpg"
-                     "06_-_Nadie_se_conoce_thumb.jpg"
-                     "07_-_Ni_asi_la_distingue_thumb.jpg"
-                     "09_-_Tantalo_thumb.jpg"
-                     "10_-_El_amor_y_la_muerte_thumb.jpg"
-                     "11_-_Muchachos_al_avC3ADo_thumb.jpg"
-                     "12_-_A_caza_de_dientes_thumb.jpg"
-                     "13_-_Estan_calientes_thumb.jpg"]
-        pages (map (fn [image-name]
-                     (let [_image-url (str url-base image-name)
-                           image-url (str "url('" _image-url "')")
-                           image-node (.. root-node addChild)
-                           el (DOMElement. image-node)
-                           box (FamousBox. (clj->js {:mass 100 :size [100 100 100]}))
-                           anchor (Vec3. 1 0 0)
-                           spring (Spring. nil box (clj->js {:period 0.5 :dampingRatio 0.5 :anchor anchor}))
-                           quaternion (.. (Quaternion.) (fromEuler 0 (/ (.. js/Math -PI) -2) 0))
-                           rotational-spring (RotationalSpring. nil box (clj->js {:period 1 :dampingRatio 0.2 :anchor quaternion}))]
-                       (.. image-node
-                           (setSizeMode ABSOLUTE ABSOLUTE ABSOLUTE)
-                           (setAbsoluteSize 500 500 0)
-                           (setAlign 0.5 0.5)
-                           (setMountPoint 0.5 0.5)
-                           (setOrigin 0.5 0.5))
-                       (.. el
-                           (setProperty "backgroundImage" image-url)
-                           (setProperty "background-repeat" "no-repeat")
-                           (setProperty "background-size" "cover"))
-
-                       {:node              image-node
-                        :el                el
-                        :box               box
-                        :spring            spring
-                        :quaternion        quaternion
-                        :rotational-spring rotational-spring
-                        :anchor            anchor}))
-                   image-names)]
-    (doseq [{:keys [box spring rotational-spring]} pages]
-      (.. simulation (add box spring rotational-spring)))
-
-    pages))

 (defn make-tree []
   [:node {:id "root"}


comment out code

comment out code

--- examples/lesson-carousel-starter-kit/src/carousel/core.cljs
+++ examples/lesson-carousel-starter-kit/src/carousel/core.cljs
@@ -1,8 +1,8 @@
 (ns ^:figwheel-always carousel.core
-    (:require-macros [cljs.core.async.macros :refer [go]])
-    (:require [com.famous.Famous]
-              [carousel.util :refer [events->chan get-children]]
-              [cljs.core.async :refer [>! <! put! chan alts!]]))
+  (:require-macros [cljs.core.async.macros :refer [go]])
+  (:require [com.famous.Famous]
+            [carousel.util :refer [events->chan get-children]]
+            [cljs.core.async :refer [>! <! put! chan alts!]]))

 (enable-console-print!)

@@ -26,207 +26,210 @@
 (defonce ABSOLUTE (.. Size -ABSOLUTE))

 (defn decorate-arrow-node [arrow-node text]
-  (.. arrow-node
-      (setSizeMode 1 1)
-      (setAbsoluteSize 40 40))
-
-  (.. (DOMElement. arrow-node)
-      (setProperty "color" "white")
-      (setContent text)
-      (setProperty "fontSize" "40px")
-      (setProperty "lineHeight" "40px")
-      (setProperty "cursor" "pointer")
-      (setProperty "textHighlight" "none")
-      (setProperty "zIndex" "2")))
+      (.. arrow-node
+          (setSizeMode 1 1)
+          (setAbsoluteSize 40 40))
+
+      (.. (DOMElement. arrow-node)
+          (setProperty "color" "white")
+          (setContent text)
+          (setProperty "fontSize" "40px")
+          (setProperty "lineHeight" "40px")
+          (setProperty "cursor" "pointer")
+          (setProperty "textHighlight" "none")
+          (setProperty "zIndex" "2")))

 (defn decorate-dots [dots-node]
-  (let [dot-nodes (.. dots-node getChildren)
-        resize (clj->js {:onSizeChange (fn [^Float32Array size]
-                                         "NOTE: this call back is called only once because root-dot setSizeMode is ABSOLUTE (value of 1)"
-                                         (let [size (IndexedSeq. size 0)
-                                               dotWidth 10
-                                               numPages 5
-                                               spacing 5
-                                               totalDotSize (+ (* numPages dotWidth)
-                                                               (* spacing (dec numPages)))
-                                               start-x (/ (- (nth size 0) totalDotSize)
-                                                          2)]
-                                           (doseq [n (range (count dot-nodes))
-                                                   :let [dot-node (nth dot-nodes n)]]
-                                             (.. dot-node (setPosition (+ start-x
-                                                                          (* n
-                                                                             (+ dotWidth spacing)))
-                                                                       0
-                                                                       0)))))})]
-    (doseq [dot-node dot-nodes]
-      (.. (DOMElement. dot-node)
-          (setProperty "borderRadius" "5px")
-          (setProperty "border" "2px solid white")
-          (setProperty "boxSizing" "border-box")))
-
-    (.. dots-node (addComponent resize))))
+      (let [dot-nodes (.. dots-node getChildren)
+            resize (clj->js {:onSizeChange (fn [^Float32Array size]
+                                               "NOTE: this call back is called only once because root-dot setSizeMode is ABSOLUTE (value of 1)"
+                                               (let [size (IndexedSeq. size 0)
+                                                     dotWidth 10
+                                                     numPages 5
+                                                     spacing 5
+                                                     totalDotSize (+ (* numPages dotWidth)
+                                                                     (* spacing (dec numPages)))
+                                                     start-x (/ (- (nth size 0) totalDotSize)
+                                                                2)]
+                                                    (doseq [n (range (count dot-nodes))
+                                                            :let [dot-node (nth dot-nodes n)]]
+                                                           (.. dot-node (setPosition (+ start-x
+                                                                                (* n
+                                                                                (+ dotWidth spacing)))
+                                                                                0
+                                                                                0)))))})]
+           (doseq [dot-node dot-nodes]
+                  (.. (DOMElement. dot-node)
+                      (setProperty "borderRadius" "5px")
+                      (setProperty "border" "2px solid white")
+                      (setProperty "boxSizing" "border-box")))
+
+           (.. dots-node (addComponent resize))))

 (defn create-dots [root-node]
-  (let [root-dot (.. root-node addChild)]
-    (doseq [i (range 5)
-            :let [dot-node (.. root-dot addChild)]]
-      (.. dot-node
-          (setSizeMode ABSOLUTE ABSOLUTE)
-          (setAbsoluteSize 5 5)))
-    (.. root-dot
-        (setSizeMode ABSOLUTE ABSOLUTE)
-        (setAbsoluteSize 20 20)
-        (setPosition 0 -50 0)
-        (setAlign 0.5 1 0)
-        (setMountPoint .5, 1, 0))
-    root-dot))
+      (let [root-dot (.. root-node addChild)]
+           (doseq [i (range 5)
+                   :let [dot-node (.. root-dot addChild)]]
+                  (.. dot-node
+                      (setSizeMode ABSOLUTE ABSOLUTE)
+                      (setAbsoluteSize 5 5)))
+           (.. root-dot
+               (setSizeMode ABSOLUTE ABSOLUTE)
+               (setAbsoluteSize 20 20)
+               (setPosition 0 -50 0)
+               (setAlign 0.5 1 0)
+               (setMountPoint .5, 1, 0))
+           root-dot))

 (defn create-pages [root-node simulation]
-  (let [url-base "http://demo.famo.us.s3.amazonaws.com/hub/apps/carousel/Museo_del_Prado_-_Goya_-_Caprichos_-_No._"
-        image-names ["01_-_Autorretrato._Francisco_Goya_y_Lucientes2C_pintor_thumb.jpg"
-                     "02_-_El_si_pronuncian_y_la_mano_alargan_al_primero_que_llega_thumb.jpg"
-                     "03_-_Que_viene_el_Coco_thumb.jpg"
-                     "04_-_El_de_la_rollona_thumb.jpg"
-                     "05_-_Tal_para_qual_thumb.jpg"
-                     "06_-_Nadie_se_conoce_thumb.jpg"
-                     "07_-_Ni_asi_la_distingue_thumb.jpg"
-                     "09_-_Tantalo_thumb.jpg"
-                     "10_-_El_amor_y_la_muerte_thumb.jpg"
-                     "11_-_Muchachos_al_avC3ADo_thumb.jpg"
-                     "12_-_A_caza_de_dientes_thumb.jpg"
-                     "13_-_Estan_calientes_thumb.jpg"]
-        pages (map (fn [image-name]
-                     (let [_image-url (str url-base image-name)
-                           image-url (str "url('" _image-url "')")
-                           image-node (.. root-node addChild)
-                           el (DOMElement. image-node)
-                           box (FamousBox. (clj->js {:mass 100 :size [100 100 100]}))
-                           anchor (Vec3. 1 0 0)
-                           spring (Spring. nil box (clj->js {:period 0.5 :dampingRatio 0.5 :anchor anchor}))
-                           quaternion (.. (Quaternion.) (fromEuler 0 (/ (.. js/Math -PI) -2) 0))
-                           rotational-spring (RotationalSpring. nil box (clj->js {:period 1 :dampingRatio 0.2 :anchor quaternion}))]
-                       (.. image-node
-                           (setSizeMode ABSOLUTE ABSOLUTE ABSOLUTE)
-                           (setAbsoluteSize 500 500 0)
-                           (setAlign 0.5 0.5)
-                           (setMountPoint 0.5 0.5)
-                           (setOrigin 0.5 0.5))
-                       (.. el
-                           (setProperty "backgroundImage" image-url)
-                           (setProperty "background-repeat" "no-repeat")
-                           (setProperty "background-size" "cover"))
-
-                       {:node image-node
-                        :el el
-                        :box box
-                        :spring spring
-                        :quaternion quaternion
-                        :rotational-spring rotational-spring
-                        :anchor anchor}))
-                   image-names)]
-    (doseq [ {:keys [box spring rotational-spring]} pages]
-      (.. simulation (add box spring rotational-spring)))
-
-    pages))
+      (let [url-base "http://demo.famo.us.s3.amazonaws.com/hub/apps/carousel/Museo_del_Prado_-_Goya_-_Caprichos_-_No._"
+            image-names ["01_-_Autorretrato._Francisco_Goya_y_Lucientes2C_pintor_thumb.jpg"
+                         "02_-_El_si_pronuncian_y_la_mano_alargan_al_primero_que_llega_thumb.jpg"
+                         "03_-_Que_viene_el_Coco_thumb.jpg"
+                         "04_-_El_de_la_rollona_thumb.jpg"
+                         "05_-_Tal_para_qual_thumb.jpg"
+                         "06_-_Nadie_se_conoce_thumb.jpg"
+                         "07_-_Ni_asi_la_distingue_thumb.jpg"
+                         "09_-_Tantalo_thumb.jpg"
+                         "10_-_El_amor_y_la_muerte_thumb.jpg"
+                         "11_-_Muchachos_al_avC3ADo_thumb.jpg"
+                         "12_-_A_caza_de_dientes_thumb.jpg"
+                         "13_-_Estan_calientes_thumb.jpg"]
+            pages (map (fn [image-name]
+                           (let [_image-url (str url-base image-name)
+                                 image-url (str "url('" _image-url "')")
+                                 image-node (.. root-node addChild)
+                                 el (DOMElement. image-node)
+                                 box (FamousBox. (clj->js {:mass 100 :size [100 100 100]}))
+                                 anchor (Vec3. 1 0 0)
+                                 spring (Spring. nil box (clj->js {:period 0.5 :dampingRatio 0.5 :anchor anchor}))
+                                 quaternion (.. (Quaternion.) (fromEuler 0 (/ (.. js/Math -PI) -2) 0))
+                                 rotational-spring (RotationalSpring. nil box (clj->js {:period 1 :dampingRatio 0.2 :anchor quaternion}))]
+                                (.. image-node
+                                    (setSizeMode ABSOLUTE ABSOLUTE ABSOLUTE)
+                                    (setAbsoluteSize 500 500 0)
+                                    (setAlign 0.5 0.5)
+                                    (setMountPoint 0.5 0.5)
+                                    (setOrigin 0.5 0.5))
+                                (.. el
+                                    (setProperty "backgroundImage" image-url)
+                                    (setProperty "background-repeat" "no-repeat")
+                                    (setProperty "background-size" "cover"))
+
+                                {:node              image-node
+                                 :el                el
+                                 :box               box
+                                 :spring            spring
+                                 :quaternion        quaternion
+                                 :rotational-spring rotational-spring
+                                 :anchor            anchor}))
+                       image-names)]
+           (doseq [{:keys [box spring rotational-spring]} pages]
+                  (.. simulation (add box spring rotational-spring)))
+
+           pages))

 (defn make-tree []
-  [:node {:id "root"}
-   [ [:node {:id "back"
-             :align [0 0.5 0]
-             :position [40 0 0]
-             :mount-point [0 0.5 0]}]
-     [:node {:id "next"
-             :align [1 0.5 0]
-             :position [-40 0 0]
-             :mount-point [1 0.5 0]}]]])
+      [:node {:id "root"}
+       [[:node {:id          "back"
+                :align       [0 0.5 0]
+                :position    [40 0 0]
+                :mount-point [0 0.5 0]}]
+        [:node {:id          "next"
+                :align       [1 0.5 0]
+                :position    [-40 0 0]
+                :mount-point [1 0.5 0]}]]])

 (defn make-nodes [node-as-vec]
-  (let [attributes (nth node-as-vec 1)
-        node (Node.)
-        align (clj->js (:align attributes))
-        position (clj->js (:position attributes))
-        mount-point (clj->js (:mount-point attributes))
-        children (get-children node-as-vec)]
-    (.apply (.-setAlign node) node align)
-    (.apply (.-setPosition node) node position)
-    (.apply (.-setMountPoint node) node mount-point)
-    (println node-as-vec)
-    (if-not (empty? children)
-      (doseq [n (nth node-as-vec 2)
-              :let [a-child-node (make-nodes n)]]
-        (.. node (addChild a-child-node))))
-    node))
+      (let [attributes (nth node-as-vec 1)
+            node (Node.)
+            align (clj->js (:align attributes))
+            position (clj->js (:position attributes))
+            mount-point (clj->js (:mount-point attributes))
+            children (get-children node-as-vec)]
+           (.apply (.-setAlign node) node align)
+           (.apply (.-setPosition node) node position)
+           (.apply (.-setMountPoint node) node mount-point)
+           (println node-as-vec)
+           (if-not (empty? children)
+                   (doseq [n (nth node-as-vec 2)
+                           :let [a-child-node (make-nodes n)]]
+                          (.. node (addChild a-child-node))))
+           node))

 (defn Carousel []
-  (let [simulation (PhysicsEngine.)
-        context (.. FamousEngine (createScene "body"))
-        root-node (.. context addChild)
-
-        back-node (.. root-node addChild)
-        back-clicks (events->chan back-node "tap")
-
-        next-node (.. root-node addChild)
-        next-clicks (events->chan next-node "tap")
-
-        dots-node (create-dots root-node)
-        pages (create-pages root-node simulation)
-
-        current-index (atom 0)
-
-        back (decorate-arrow-node back-node "<")
-        next (decorate-arrow-node next-node ">")
-        dots (decorate-dots dots-node)
-        ]
-    (.. back-node
-        (setAlign 0 0.5 0)
-        (setPosition 40 0 0)
-        (setMountPoint 0 0.5 0))
-    (.. next-node
-        (setAlign 1 0.5 0)
-        (setPosition -40 0 0)
-        (setMountPoint 1 0.5 0))
-
-    (add-watch current-index :watcher (fn [key atom old-index new-index]
-                                        (let [old-page (nth pages old-index)
-                                              new-page (nth pages new-index)]
-                                          (.. (:anchor old-page) (set 1 0 0))
-                                          (.. (:quaternion old-page) (fromEuler 0 (/ (.. js/Math -PI) -2) 0))
-                                          (.. (:anchor new-page) (set 0 0 0))
-                                          (.. (:quaternion new-page) (set 1 0 0 0)))))
-
-    (go
-      (while true
-        (let [[v channel] (alts! [back-clicks next-clicks])]
-          (cond
-            (= channel back-clicks) (do
-                                      (println "back" @current-index)
-                                      (swap! current-index dec)
-                                      )
-            (= channel next-clicks) (do
-                                      (println "next" @current-index)
-                                      (swap! current-index inc)
-                                      )))))
-
-    (.. FamousEngine (requestUpdate (clj->js {:onUpdate (fn [time]
-                                                        (.. simulation (update time))
-                                                        (doseq [page pages
-                                                                :let [physics-transform (.. simulation (getTransform (:box page)))
-                                                                      p (.. physics-transform -position)
-                                                                      r (.. physics-transform -rotation)
-                                                                      node (:node page)]]
-                                                          (.. node
-                                                              (setPosition (* 0 1446) 0 0)
-                                                              (setRotation (nth r 0) (nth r 1) (nth r 2) (nth r 3))
-                                                              )
-                                                          )
-
-                                                        (this-as this
-                                                                 (.. FamousEngine (requestUpdateOnNextTick this)))
-                                                        )})))
-    )
-
-  )
+      (let [simulation (PhysicsEngine.)
+            context (.. FamousEngine (createScene "body"))
+            root-node (Node.)
+
+            back-node (.. root-node addChild)
+            ;back-clicks (events->chan back-node "tap")
+
+            next-node (.. root-node addChild)
+            ;next-clicks (events->chan next-node "tap")
+
+            ;dots-node (create-dots root-node)
+            ;pages (create-pages root-node simulation)
+
+            ;current-index (atom 0)
+
+            back (decorate-arrow-node back-node "<")
+            next (decorate-arrow-node next-node ">")
+            ;dots (decorate-dots dots-node)
+            ]
+
+            (.. context (addChild root-node))
+
+           (.. back-node
+               (setAlign 0 0.5 0)
+               (setPosition 40 0 0)
+               (setMountPoint 0 0.5 0))
+           (.. next-node
+               (setAlign 1 0.5 0)
+               (setPosition -40 0 0)
+               (setMountPoint 1 0.5 0))
+
+           ;(add-watch current-index :watcher (fn [key atom old-index new-index]
+           ;                                      (let [old-page (nth pages old-index)
+           ;                                            new-page (nth pages new-index)]
+           ;                                           (.. (:anchor old-page) (set 1 0 0))
+           ;                                           (.. (:quaternion old-page) (fromEuler 0 (/ (.. js/Math -PI) -2) 0))
+           ;                                           (.. (:anchor new-page) (set 0 0 0))
+           ;                                           (.. (:quaternion new-page) (set 1 0 0 0)))))
+
+           ;(go
+           ;  (while true
+           ;         (let [[v channel] (alts! [back-clicks next-clicks])]
+           ;              (cond
+           ;                (= channel back-clicks) (do
+           ;                                          (println "back" @current-index)
+           ;                                          (swap! current-index dec)
+           ;                                          )
+           ;                (= channel next-clicks) (do
+           ;                                          (println "next" @current-index)
+           ;                                          (swap! current-index inc)
+           ;                                          )))))
+
+           ;(.. FamousEngine (requestUpdate (clj->js {:onUpdate (fn [time]
+           ;                                                        (.. simulation (update time))
+           ;                                                        (doseq [page pages
+           ;                                                                :let [physics-transform (.. simulation (getTransform (:box page)))
+           ;                                                                      p (.. physics-transform -position)
+           ;                                                                      r (.. physics-transform -rotation)
+           ;                                                                      node (:node page)]]
+           ;                                                               (.. node
+           ;                                                                   (setPosition (* 0 1446) 0 0)
+           ;                                                                   (setRotation (nth r 0) (nth r 1) (nth r 2) (nth r 3))
+           ;                                                                   )
+           ;                                                               )
+           ;
+           ;                                                        (this-as this
+           ;                                                                 (.. FamousEngine (requestUpdateOnNextTick this)))
+           ;                                                        )})))
+           )
+
+      )

 (Carousel)
 (.. FamousEngine init)


km not m!!

km not m!!

--- src-cljs/flatride/frontend.cljs
+++ src-cljs/flatride/frontend.cljs
@@ -74,12 +74,12 @@
                                   (->> longest-slope slope-percent (gstring/format "%.2f%%"))
                                   " for a distance of "
                                   (->> longest-slope slope-total-distance (gstring/format "%.2f"))
-                                  "m"]))
+                                  "km"]))
     (dommy/append! ul (node [:li "The steepest slope is "
                                 (->> steepest-slope slope-percent (gstring/format "%.2f%%"))
                                 " for a distance of "
                                 (->> steepest-slope slope-total-distance (gstring/format "%.2f"))
-                                "m"]))))
+                                "km"]))))

 (defn get-routes []
   (let [from (dommy/value (sel1 :#input-from))


Some om cleanup

Some om cleanup

--- src-cljs/photon/ui/frontend.cljs
+++ src-cljs/photon/ui/frontend.cljs
@@ -18,7 +18,8 @@
                           :new-projection false}))

 (defn clj->str [c]
-  (let [res (clojure.string/replace (with-out-str (fipp/pprint c {:width 80})) #"}nil" "}")]
+  (let [res (clojure.string/replace
+             (with-out-str (fipp/pprint c {:width 80})) #"}nil" "}")]
     (.log js/console res)
     res))

@@ -45,16 +46,20 @@
           (dom/input
             #js {:type "text" :ref "name"
                  :value (:projection-name data)
-                 :onChange (fn [ev]
-                             (om/update! data :projection-name (.-value (.-target ev))))}))
+                 :onChange
+                 (fn [ev]
+                   (om/update! data :projection-name
+                               (.-value (.-target ev))))}))
         (dom/div
           nil
           "Stream name"
           (dom/input
             #js {:type "text" :ref "name"
                  :value (:stream-name data)
-                 :onChange (fn [ev]
-                             (om/update! data :stream-name (.-value (.-target ev))))}))
+                 :onChange
+                 (fn [ev]
+                   (om/update! data :stream-name
+                               (.-value (.-target ev))))}))
         (dom/div nil "Language")
         (apply dom/div
                #js {:className "radio"}
@@ -63,7 +68,8 @@
                        (dom/input
                          #js {:type "checkbox"
                               :checked (= % (:language data))
-                              :onChange (fn [ev] (om/update! data :language %))})
+                              :onChange
+                              (fn [ev] (om/update! data :language %))})
                        %)
                     ["clojure" "javascript"]))
         (dom/div nil "Initial value")
@@ -74,9 +80,11 @@
                       #js {:contentEditable "true"
                            :ref "initial-value-box"
                            :className "clojure"
-                           :onBlur (fn [ev]
-                                     (om/update! data :initial-value (.-textContent (.-target ev)))
-                                     (update-box owner "initial-value-box"))}
+                           :onBlur
+                           (fn [ev]
+                             (om/update! data :initial-value
+                                         (.-textContent (.-target ev)))
+                             (update-box owner "initial-value-box"))}
                       (:initial-value data))))
         (dom/div nil "Code: content of (fn [prev item] ... )")
         (dom/pre
@@ -86,27 +94,31 @@
                       #js {:contentEditable "true"
                            :ref "code-box"
                            :className "clojure"
-                           :onBlur (fn [ev]
-                                     (om/update! data :reduction (.-textContent (.-target ev)))
-                                     (update-box owner "code-box"))}
+                           :onBlur
+                           (fn [ev]
+                             (om/update! data :reduction
+                                         (.-textContent (.-target ev)))
+                             (update-box owner "code-box"))}
                       (:reduction data))))
         (dom/div
           nil
           (dom/button
-            #js {:onClick (fn [_]
-                            (go
-                              (let [res
-                                    (:body
-                                      (<! (client/post
-                                            "/projections"
-                                            {:json-params
-                                             {:projection-name (:projection-name data)
-                                              :stream-name (:stream-name data)
-                                              :initial-value (:initial-value data)
-                                              :language (:language data)
-                                              :reduction (:reduction data)}})))]
-                                (update-projections! data))))}
-            "Register projection"))))))
+              #js {:onClick
+                   (fn [_]
+                     (go
+                       (let [res
+                             (:body
+                              (<! (client/post
+                                   "/projections"
+                                   {:json-params
+                                    (select-keys data
+                                                 [:projection-name
+                                                  :stream-name
+                                                  :initial-value
+                                                  :reduction
+                                                  :language])})))]
+                         (update-projections! data))))}
+              "Register projection"))))))

 (defn widget-projections [data owner]
   (reify
@@ -126,7 +138,8 @@
         (dom/button
           #js {:onClick
                (fn [_]
-                 (om/update! data :new-projection (not (:new-projection data))))}
+                 (om/update! data :new-projection
+                             (not (:new-projection data))))}
           "+ New Projection")
         (if (:new-projection data)
           (do
@@ -137,10 +150,13 @@
                        nil
                        (dom/a
                          #js {:href "#"
-                              :onClick (fn [ev]
-                                         (if (= (:current-projection data) %)
-                                           (om/update! data :current-projection nil)
-                                           (om/update! data :current-projection %)))}
+                              :onClick
+                              (fn [ev]
+                                (if (= (:current-projection data) %)
+                                  (om/update! data
+                                              :current-projection nil)
+                                  (om/update! data
+                                              :current-projection %)))}
                          (:projection-name %))
                        (if (= (:current-projection data) %)
                          (dom/pre
@@ -157,7 +173,9 @@
     om/IDidMount
     (did-mount [this]
       (go (let [response (:body (<! (client/get "/streams")))]
-            (om/update-state! owner #(assoc % :streams (:streams response))))))
+            (om/update-state!
+             owner
+             #(assoc % :streams (:streams response))))))
     om/IRenderState
     (render-state [_ state]
       (dom/div
@@ -171,10 +189,48 @@
                        nil
                        (dom/a
                          #js {:href "#"
-                              :onClick (fn [ev] ((:handler data)
-                                                 {:stream (:stream %)}))}
+                              :onClick (fn [ev]
+                                         ((:handler data)
+                                          {:stream (:stream %)}))}
                          (:stream %)))
                     (:streams state)))))))
+
+(defn event-list-item [params]
+  (reify
+    om/IRender
+    (render [_]
+      (let [event (:event params)
+            data (:data params)
+            payload (:payload event)
+            id (str (:service-id event) ":" (:local-id event))]
+        (dom/li
+            nil
+          (let [current? (= (:current data) id)]
+            (dom/div
+                nil
+              (dom/a
+                  #js {:href "#"
+                       :onClick
+                       (fn [ev] (if current?
+                                  (om/update! data :current nil)
+                                  (om/update! data :current id)))}
+                  id)
+              (if current?
+                (dom/pre
+                 nil
+                 (dom/code
+                  #js {:className "clojure"}
+                  (clj->str event)))))))))))
+
+(defn event-list [params owner]
+  (reify
+    om/IRender
+    (render [_]
+      (apply dom/ul
+          nil
+          (map #(om/build event-list-item {:data (:data params)
+                                           :event %})
+               (:events params))))))

 (defn widget-stream [data owner]
   (reify
@@ -183,8 +239,12 @@
       {:events []})
     om/IDidMount
     (did-mount [this]
-      (go (let [response (:body (<! (client/get (str "/stream/" (:stream data)))))]
-            (om/update-state! owner #(assoc % :events (:results response))))))
+      (go (let [response
+                (:body (<! (client/get
+                            (str "/stream/" (:stream data)))))]
+            (om/update-state!
+             owner
+             #(assoc % :events (:results response))))))
     om/IDidUpdate
     (did-update [_ _ _]
       (dorun (map #(.highlightBlock js/hljs %) ($ "code"))))
@@ -196,32 +256,8 @@
         (dom/h2
           nil
           (str "Events: " (:stream data)))
-        (apply dom/ul
-               nil
-               (map (fn [event]
-                      (let [payload (:payload event)
-                            id (str (:service-id event) ":" (:local-id event))]
-                        (dom/li
-                          nil
-                          (let [current? (= (:current data) id)]
-                            (dom/div
-                              nil
-                              (dom/a
-                                #js {:href "#"
-                                     :onClick
-                                     (fn [ev] (if current?
-                                                (om/update! data :current nil)
-                                                (om/update! data :current id)))}
-                                id)
-                              (if current?
-                                (dom/pre
-                                  nil
-                                  (dom/code
-                                    #js {:className "clojure"}
-                                    (clj->str event)
-                                    #_(clj->str (js->clj (.parse js/JSON payload)
-                                                         :keywordize-keys true))))))))))
-                    (:events state)))))))
+        (om/build event-list {:data data
+                              :events (:events state)})))))

 (defn full-page [data owner]
   (reify


RS & AB | 6 | Add fact stubs

RS & AB | 6 | Add fact stubs

--- test/stonecutter/test/controller/user.clj
+++ test/stonecutter/test/controller/user.clj
@@ -234,3 +234,10 @@
                                                     :authorised-clients [...client-id-1... ...client-id-2...]}
                (c/retrieve-client ...client-id-1...) => {:name "CLIENT 1"}
                (c/retrieve-client ...client-id-2...) => {:name "CLIENT 2"})))
+
+(facts "about unsharing profile cards"
+       (fact "posting to /unshare-profile-card with the client-id in the form params should remove the client-id from the user's authorised clients and then redirect the user to the profile page")
+
+       (fact "posting to /unshare-profile-card with a client id that is not in the user's list of authorised clients")
+
+       )


Fix more tests

Fix more tests

--- test/yetibot/core/test/models/history.clj
+++ test/yetibot/core/test/models/history.clj
@@ -39,20 +39,22 @@

 (use-fixtures :once populate)

+(def extra-where {:is-yetibot false})
+
 (deftest test-count-entities
-  (count-entities chat-source))
+  (count-entities chat-source extra-where))

 (deftest test-head
-  (head chat-source 2))
+  (head chat-source 2 extra-where))

 (deftest test-tail
-  (tail chat-source 2))
+  (tail chat-source 2 extra-where))

 (deftest test-random
-  (random chat-source))
+  (random chat-source extra-where))

 (deftest test-grep
-  (grep chat-source "b.d+"))
+  (grep chat-source "b.d+" extra-where))

 (deftest test-cmd-only-items
   (cmd-only-items chat-source))


Scaling the map

Scaling the map

--- src/amindblowingworld/views.clj
+++ src/amindblowingworld/views.clj
@@ -34,7 +34,8 @@
 (defn biome-map [world]
   (let [ w (-> world .getDimension .getWidth)
          h (-> world .getDimension .getHeight)
-         img (BufferedImage. w h (BufferedImage/TYPE_INT_ARGB))
+         scale-factor 5
+         img (BufferedImage. (* scale-factor w) (* scale-factor h) (BufferedImage/TYPE_INT_ARGB))
          g (.createGraphics img)
          b (-> world .getBiome)]
     (doseq [y (range h)]
@@ -44,7 +45,9 @@
           (case (.name biome)
             "OCEAN" (.setColor g (Color. 0 0 255))
             (.setColor g (Color. 255 0 0)))
-            (.fillRect g x y 1 1))))
+          (let [pixel-x (* x scale-factor)
+                pixel-y (* y scale-factor)]
+            (.fillRect g pixel-x pixel-y scale-factor scale-factor)))))
     (.dispose g)
     img))


don't launch browser automatically with repl functions

--- src/app/clj/one/sample/repl.clj
+++ src/app/clj/one/sample/repl.clj
@@ -11,17 +11,13 @@
   "Start a browser-connected REPL and launch a browser to talk to it."
   []
   (dev/run-server)
-  (future (Thread/sleep 3000)
-          (browse/browse-url "http://localhost:8080/development"))
   (tools/cljs-repl))

 (defn dev-server
   "Start the development server and open the host application in the
   default browser."
   []
-  (dev/run-server)
-  (future (Thread/sleep 3000)
-          (browse/browse-url "http://localhost:8080")))
+  (dev/run-server))

 ;; This is a convenience function so that people can start a CLJS REPL
 ;; without having to type in (tools/cljs-repl)


~(defn model-reloaded): call (compile-lexicon) rather than (edn2lexicon), so we load the partitioned lexicon sources

--- src/babel/italiano/grammar.cljc
+++ src/babel/italiano/grammar.cljc
@@ -782,9 +782,8 @@
                                  0 depth)}))})))

 (defn model-reloaded []
-  (let [lexicon (babel.italiano.lexicon/edn2lexicon
-                 (clojure.java.io/resource "babel/italiano/lexicon.edn"))]
-    (model-plus-lexicon lexicon)))
+  (log/info (str "reloading model by compiling lexicon sources..."))
+  (model-plus-lexicon (compile-lexicon)))

 (defn model []
   (let [lexicon (read-lexicon "it")]


+TODO

+TODO

--- src/babel/italiano/lexicon.cljc
+++ src/babel/italiano/lexicon.cljc
@@ -29,6 +29,9 @@
             (merge-with concat a b))
           lexicons))

+;; TODO: rename this to (defn compile-lexicon) or similar:
+;; it does not convert an .edn file to a lexicon as its name suggests, but
+;; rather applies transformations to an existing lexicon.
 (defn edn2lexicon
   "Apply Italian-specific lexical rules to enhance input lexicon map into fully-specified lexical entries."
   [input-lexicon]


don't keep stale deps around

don't keep stale deps around

--- src/cake/tasks/dependencies.clj
+++ src/cake/tasks/dependencies.clj
@@ -2,7 +2,7 @@
   (:use cake cake.ant)
   (:import [org.apache.maven.artifact.ant DependenciesTask RemoteRepository WritePomTask Pom]
            [org.apache.maven.model Dependency License]
-           [org.apache.tools.ant.taskdefs Copy]))
+           [org.apache.tools.ant.taskdefs Copy Delete]))

 (def repositories
   {"central"           "http://repo1.maven.org/maven2"
@@ -33,6 +33,7 @@
     (add-dependencies (project :dependencies)))
   (let [dest (java.io.File. (:library-path project))]
     (.mkdirs dest)
+    (ant Delete {} (add-fileset {:dir dest :includes "*.jar"}))
     (ant Copy {:todir dest :flatten true}
       (.addFileset (get-reference "cake.dep.fileset")))))


Removing println

Removing println

--- src/cmr/search/results_handlers/reference_results_handler.clj
+++ src/cmr/search/results_handlers/reference_results_handler.clj
@@ -105,7 +105,6 @@
   [context query results]
   (let [{:keys [pretty? echo-compatible?]} query
         xml-fn (if pretty? x/indent-str x/emit-str)]
-    (println "echo-compatible?" echo-compatible?)
     (xml-fn (results->xml-element echo-compatible? results))))


Fix typos in information model

Fix typos in information model

--- src/onyx/information_model.cljc
+++ src/onyx/information_model.cljc
@@ -32,7 +32,7 @@
              :added "0.8.0"}

             :onyx/batch-timeout
-            {:doc "The number of milliseconds a peer will wait to read more segments before processing them all in a batch for this task. Segments will be processe when either `:onyx/batch-timeout` milliseconds passed, or `:onyx/batch-size` segments have been read - whichever comes first. This is a knob that is used to tune throughput and latency, and it goes hand-in-hand with `:onyx/batch-size`."
+            {:doc "The number of milliseconds a peer will wait to read more segments before processing them all in a batch for this task. Segments will be processed when either `:onyx/batch-timeout` milliseconds passed, or `:onyx/batch-size` segments have been read - whichever comes first. This is a knob that is used to tune throughput and latency, and it goes hand-in-hand with `:onyx/batch-size`."
              :type :integer
              :unit :milliseconds
              :tags [:latency :throughput]
@@ -176,7 +176,7 @@
              :added "0.8.0"}

             :onyx/bulk?
-            {:doc "Boolean value indicating whether the function in this catalog entry denoted by `:onyx/fn` should take a single segment, or the entire batch of segments that were read as a parameter. When set to `true`, this function's return value is ignored. The segments are identically propogated to the downstream tasks."
+            {:doc "Boolean value indicating whether the function in this catalog entry denoted by `:onyx/fn` should take a single segment, or the entire batch of segments that were read as a parameter. When set to `true`, this function's return value is ignored. The segments are identically propagated to the downstream tasks."
              :type :boolean
              :default false
              :tags [:function]
@@ -228,7 +228,7 @@
              :added "0.8.0"}

             :flow/predicate
-            {:doc "When denoted as a keyword, this must be a fully qualified, namespaced keyword pointing to a function on the classpath at runtime. This function takes at least 4 arguments - the Event map, the old segment before `:onyx/fn` was applied, the new segment after `:onyx/fn` was applied, and the sequence of new segments generated by the old semgent. If the old segment generated exactly one segment, and not a sequence of segments, the value of the last parameter will be a collection with only the new segment in it.
+            {:doc "When denoted as a keyword, this must be a fully qualified, namespaced keyword pointing to a function on the classpath at runtime. This function takes at least 4 arguments - the Event map, the old segment before `:onyx/fn` was applied, the new segment after `:onyx/fn` was applied, and the sequence of new segments generated by the old segment. If the old segment generated exactly one segment, and not a sequence of segments, the value of the last parameter will be a collection with only the new segment in it.

                   When denoted as a vector of keywords, the first value in the vector  may either be the keyword `:and`, `:or`, or `:not`, or be a keyword as described above. In the latter case, any subsequent values must be keywords that resolve to keys in the flow condition entries map. The values of these keys are resolved and passed as additional parameters to the function. In the former case, the result of the function (which may again be wrapped with a vector to nest logical operators or parameters), is applied with the designated logical operator. This yields predicate composition."
              :type [:keyword [:keyword]]
@@ -266,7 +266,7 @@
              :added "0.8.0"}

             :flow/action
-            {:doc "Names a side effect to perform in response to processing this segment. If set to `:retry`, this segment will be immediately, forcibly retried from the root input task from which it eminated. This segment will not be sent to any downstream tasks."
+            {:doc "Names a side effect to perform in response to processing this segment. If set to `:retry`, this segment will be immediately, forcibly retried from the root input task from which it emanated. This segment will not be sent to any downstream tasks."
              :type :keyword
              :choices [:retry]
              :optional? true
@@ -367,7 +367,7 @@
    :state-aggregation
    {:summary "Onyx provides the ability to perform stateful updates for segments calculated over windows. For example, a grouping task may accumulate incoming values for a number of keys over windows of 5 minutes."
     :link nil
-    :model {:aggregation/init {:doc "Fn (window) to initialise the state."
+    :model {:aggregation/init {:doc "Fn (window) to initialize the state."
                                :type :function
                                :optional? true
                                :added "0.8.0"}
@@ -510,7 +510,7 @@
                                          :optional? true
                                          :added "0.8.0"}

-            :lifecycle/after-batch {:doc "A function that takes two arguments - an event map, and the matching lifecycle map. Must return a map that is merged back into the original event map. This function is called immediately after a batch of segments has been procesed by the peer, but before the batch is acked."
+            :lifecycle/after-batch {:doc "A function that takes two arguments - an event map, and the matching lifecycle map. Must return a map that is merged back into the original event map. This function is called immediately after a batch of segments has been processed by the peer, but before the batch is acked."
                                     :type :function
                                     :optional? true
                                     :added "0.8.0"}
@@ -530,7 +530,7 @@
                                             :optional? true
                                             :added "0.8.0"}

-            :lifecycle/handle-exception {:doc "If an exception is thrown during any lifecycle execution except `after-task-stop`, one or more lifecycle handlers may be defined. If present, the exception will be caught and passed to this function,  which takes 4 arguments - an event map, the matching lifecycle map, the keyword lifecycle name from which the exception was thrown, and the exception object. This function must return `:kill`, `:restart` or `:defer` indicating whether the job should be killed, the task restarted, or the decision defered to the next lifecycle exception handler, if another is defined. If all handlers `:defer`, the default behavior is `:kill`."
+            :lifecycle/handle-exception {:doc "If an exception is thrown during any lifecycle execution except `after-task-stop`, one or more lifecycle handlers may be defined. If present, the exception will be caught and passed to this function,  which takes 4 arguments - an event map, the matching lifecycle map, the keyword lifecycle name from which the exception was thrown, and the exception object. This function must return `:kill`, `:restart` or `:defer` indicating whether the job should be killed, the task restarted, or the decision deferred to the next lifecycle exception handler, if another is defined. If all handlers `:defer`, the default behavior is `:kill`."
                                             :type :function
                                             :optional? true
                                             :added "0.8.3"}}}
@@ -643,7 +643,7 @@
              :added "0.8.0"}

             :onyx.windowing/min-value
-            {:doc "A default strict miminum value that `:window/window-key` can ever be. Note, this is generally best configured individually via :window/min-value in the task map."
+            {:doc "A default strict minimum value that `:window/window-key` can ever be. Note, this is generally best configured individually via :window/min-value in the task map."
              :type :integer
              :optional? true
              :default 0
@@ -681,7 +681,7 @@
              :added "0.8.3"}

             :onyx.task-scheduler.colocated/only-send-local?
-            {:doc "When this peer is running a task for a job with a colocated task scheduler and this value is true, this peer will only send messages to segments local to its machine. It is desirable to set this to false when you want tasks to be perfectly uniformly spread over the machines in your cluster, but do not want jobs to run entirely locally."
+            {:doc "When this peer is running a task for a job with a co-located task scheduler and this value is true, this peer will only send messages to segments local to its machine. It is desirable to set this to false when you want tasks to be perfectly uniformly spread over the machines in your cluster, but do not want jobs to run entirely locally."
              :optional? true
              :type :boolean
              :default true
@@ -790,7 +790,7 @@
              :added "0.8.0"}

             :onyx.messaging/allow-short-circuit?
-            {:doc "A boolean denoting whether to allow virtual peers to short circuit networked messaging when colocated with the other virtual peer. Short circuiting allows for direct transfer of messages to a virtual peer's internal buffers, which improves performance where possible. This configuration option is primarily for use in perfomance testing, as peers will not generally be able to short circuit messaging after scaling to many nodes."
+            {:doc "A boolean denoting whether to allow virtual peers to short circuit networked messaging when colocated with the other virtual peer. Short circuiting allows for direct transfer of messages to a virtual peer's internal buffers, which improves performance where possible. This configuration option is primarily for use in performance testing, as peers will not generally be able to short circuit messaging after scaling to many nodes."
              :optional? true
              :type :boolean
              :default true
@@ -804,7 +804,7 @@
              :added "0.8.0"}

             :onyx.messaging.aeron/subscriber-count
-            {:doc "The number of Aeron subscriber threads that receive messages for the peer-group.  As peer-groups are generally configured per-node (machine), this setting can bottleneck receive performance if many virtual peers are used per-node, or are receiving and/or de-serializing large volumes of data. A good guidline is is `num cores = num virtual peers + num subscribers`, assuming virtual peers are generally being fully utilised."
+            {:doc "The number of Aeron subscriber threads that receive messages for the peer-group.  As peer-groups are generally configured per-node (machine), this setting can bottleneck receive performance if many virtual peers are used per-node, or are receiving and/or de-serializing large volumes of data. A good guideline is is `num cores = num virtual peers + num subscribers`, assuming virtual peers are generally being fully utilized."
              :optional? true
              :type :integer
              :default 2
@@ -967,7 +967,7 @@
              :added "0.8.0"}

             :onyx.rocksdb.filter/peer-block-cache-size
-            {:doc "RocksDB block cache size in bytes. Larger caches reduce the chance that the peer will need to check for the prescence of a uniqueness key on disk. Defaults to 100MB."
+            {:doc "RocksDB block cache size in bytes. Larger caches reduce the chance that the peer will need to check for the presence of a uniqueness key on disk. Defaults to 100MB."
              :optional? true
              :type :integer
              :default 104857600


Provide cljs counterpart for uuid coercion.

--- src/onyx/static/validation.cljc
+++ src/onyx/static/validation.cljc
@@ -472,9 +472,11 @@

 (defn coerce-uuid [uuid]
   (try
-    (if (instance? java.util.UUID uuid)
+    (if (instance? #?(:clj java.util.UUID
+                      :cljs cljs.core/UUID) uuid)
         uuid
-        (java.util.UUID/fromString uuid))
+        #?(:clj (java.util.UUID/fromString uuid)
+           :cljs (uuid uuid)))
     (catch Throwable t
       (throw (ex-info (format "Argument must be a UUID or string UUID. Type was %s" (type uuid))
                       {:type (type uuid)


Prepare live demo with new focus manager

--- flatguisamples/src/flatgui/samples/forms/fdemowindow.clj
+++ flatguisamples/src/flatgui/samples/forms/fdemowindow.clj
@@ -42,211 +42,188 @@

 ;; Panel 1 for win 1

-(def panel-1
-  (fg/defcomponent
-    panel/panel
+(def title-1 "Focus 1 - ")
+
+(fg/defevolverfn window-text-evolver :text
+  (let [focus-state (get-property [:this] :focus-state)]
+    (str title-1 (:mode focus-state) "/" (:focused-child focus-state))))
+
+(def title-2 "Focus 2 - ")
+
+(fg/defevolverfn window-text-evolver-2 :text
+  (let [focus-state (get-property [:this] :focus-state)]
+    (str title-2 (:mode focus-state) "/" (:focused-child focus-state))))
+
+(def title-3 "Focus 3 - ")
+
+(fg/defevolverfn window-text-evolver-3 :text
+  (let [focus-state (get-property [:this] :focus-state)]
+    (str title-3 (:mode focus-state) "/" (:focused-child focus-state))))
+
+(def title-4 "Focus 4 - ")
+
+(fg/defevolverfn window-text-evolver-4 :text
+  (let [focus-state (get-property [:this] :focus-state)]
+    (str title-4 (:mode focus-state) "/" (:focused-child focus-state))))
+
+(def title-5 "Focus 5 - ")
+
+(fg/defevolverfn window-text-evolver-5 :text
+  (let [focus-state (get-property [:this] :focus-state)]
+    (str title-5 (:mode focus-state) "/" (:focused-child focus-state))))
+
+(def title-6 "Focus 6 - ")
+
+(fg/defevolverfn window-text-evolver-6 :text
+  (let [focus-state (get-property [:this] :focus-state)]
+    (str title-6 (:mode focus-state) "/" (:focused-child focus-state))))
+
+
+(def focus-window
+  (fg/defcomponent
+    window/window
     :hello
-    {:clip-size (m/defpoint 4 4)
-     :position-matrix (m/translation 1 2)}
-
-    (fg/defcomponent textfield/textfield :entry1
-      {:clip-size (m/defpoint 3.0 0.375)
-       :position-matrix (m/translation 0.25 0.75)
-       :evolvers {:model tf-model-evolver}})
-
-    (fg/defcomponent textfield/textfield :entry2
-      {:clip-size (m/defpoint 3.0 0.375)
-       :position-matrix (m/translation 0.25 1.25)
-       :evolvers {:model tf-model-evolver}})
-
-    (fg/defcomponent textfield/textfield :entry3
-      {:clip-size (m/defpoint 3.0 0.375)
-       :position-matrix (m/translation 0.25 1.75)
-       :evolvers {:model tf-model-evolver}})))
-
-
-(def title-1 "Focus 1 - ")
-
-(fg/defevolverfn window-text-evolver :text
-  (let [focus-state (get-property [:this] :focus-state)]
-    (str title-1 (:mode focus-state) "/" (:focused-child focus-state))))
-
-(def title-2 "Focus 2 - ")
-
-(fg/defevolverfn window-text-evolver-2 :text
-  (let [focus-state (get-property [:this] :focus-state)]
-    (str title-2 (:mode focus-state) "/" (:focused-child focus-state))))
-
-(def title-3 "Focus 3 - ")
-
-(fg/defevolverfn window-text-evolver-3 :text
-  (let [focus-state (get-property [:this] :focus-state)]
-    (str title-3 (:mode focus-state) "/" (:focused-child focus-state))))
-
-(def title-4 "Focus 4 - ")
-
-(fg/defevolverfn window-text-evolver-4 :text
-  (let [focus-state (get-property [:this] :focus-state)]
-    (str title-4 (:mode focus-state) "/" (:focused-child focus-state))))
-
-(def title-5 "Focus 5 - ")
-
-(fg/defevolverfn window-text-evolver-5 :text
-  (let [focus-state (get-property [:this] :focus-state)]
-    (str title-5 (:mode focus-state) "/" (:focused-child focus-state))))
-
-(def title-6 "Focus 6 - ")
-
-(fg/defevolverfn window-text-evolver-6 :text
-  (let [focus-state (get-property [:this] :focus-state)]
-    (str title-6 (:mode focus-state) "/" (:focused-child focus-state))))
-
-
-(def focus-window
-  (fg/defcomponent
-    window/window
-    :hello
-    {:clip-size (m/defpoint 7 7)
-     :position-matrix (m/translation 1 0.25)
+    {:clip-size (m/defpoint 4 4.5)
+     :position-matrix (m/translation 0.125 0.125)
      :text title-1
      :evolvers {:text window-text-evolver}}

     (fg/defcomponent textfield/textfield :entry1
-      {:clip-size (m/defpoint 3.0 0.375)
-       :position-matrix (m/translation 0.25 0.75)
+      {:clip-size (m/defpoint 1.0 0.375)
+       :position-matrix (m/translation 0.125 0.5)
        :evolvers {:model tf-model-evolver}})

     (fg/defcomponent textfield/textfield :entry2
-      {:clip-size (m/defpoint 3.0 0.375)
-       :position-matrix (m/translation 0.25 1.25)
+      {:clip-size (m/defpoint 1.0 0.375)
+       :position-matrix (m/translation 0.125 1.0)
        :evolvers {:model tf-model-evolver}})

     (fg/defcomponent textfield/textfield :entry3
-      {:clip-size (m/defpoint 3.0 0.375)
-       :position-matrix (m/translation 0.25 1.75)
+      {:clip-size (m/defpoint 1.0 0.375)
+       :position-matrix (m/translation 0.125 1.5)
        :evolvers {:model tf-model-evolver}})

     (fg/defcomponent panel/panel :panel1
-      {:clip-size (m/defpoint 3.0 3.0)
-       :position-matrix (m/translation 0.25 2.5)
+      {:clip-size (m/defpoint 1.0 2.375)
+       :position-matrix (m/translation 0.125 2.0)
        :look container-look})

     (fg/defcomponent panel/panel :panel2
-      {:clip-size (m/defpoint 3.0 3.0)
-       :position-matrix (m/translation 3.5 2.5)
+      {:clip-size (m/defpoint 2.625 2.375)
+       :position-matrix (m/translation 1.25 2.0)
        :look container-look}

          (fg/defcomponent panel/panel :panel2-1
-           {:clip-size (m/defpoint 2.75 1.0)
-            :position-matrix (m/translation 0.125 0.5)
+           {:clip-size (m/defpoint 2.375 0.875)
+            :position-matrix (m/translation 0.125 0.375)
             :look container-look}

            (fg/defcomponent textfield/textfield :entry1
-             {:clip-size (m/defpoint 1.125 0.375)
-              :position-matrix (m/translation 0.125 0.5)
+             {:clip-size (m/defpoint 1.0 0.375)
+              :position-matrix (m/translation 0.125 0.375)
               :evolvers {:model tf-model-evolver}})

            (fg/defcomponent textfield/textfield :entry2
-             {:clip-size (m/defpoint 1.125 0.375)
-              :position-matrix (m/translation 1.5 0.5)
+             {:clip-size (m/defpoint 1.0 0.375)
+              :position-matrix (m/translation 1.25 0.375)
               :evolvers {:model tf-model-evolver}}))

          (fg/defcomponent panel/panel :panel2-2
-           {:clip-size (m/defpoint 2.75 1.0)
-            :position-matrix (m/translation 0.125 1.625)
+           {:clip-size (m/defpoint 2.375 0.875)
+            :position-matrix (m/translation 0.125 1.375)
             :look container-look}

            (fg/defcomponent textfield/textfield :entry1
-             {:clip-size (m/defpoint 1.125 0.375)
-              :position-matrix (m/translation 0.125 0.5)
+             {:clip-size (m/defpoint 1.0 0.375)
+              :position-matrix (m/translation 0.125 0.375)
               :evolvers {:model tf-model-evolver}})

            (fg/defcomponent textfield/textfield :entry2
-             {:clip-size (m/defpoint 1.125 0.375)
-              :position-matrix (m/translation 1.5 0.5)
+             {:clip-size (m/defpoint 1.0 0.375)
+              :position-matrix (m/translation 1.25 0.375)
               :evolvers {:model tf-model-evolver}})))))

 (def focus-window-2
   (fg/defcomponent
     window/window
     :hello2
-    {:clip-size (m/defpoint 7 7)
-     :position-matrix (m/translation 9 0.25)
+    {:clip-size (m/defpoint 3.375 5)
+     :position-matrix (m/translation 4.25 0.125)
      :text title-2
      :evolvers {:text window-text-evolver-2}}

     (fg/defcomponent textfield/textfield :entry1
-      {:clip-size (m/defpoint 3.0 0.375)
-       :position-matrix (m/translation 0.25 0.75)
+      {:clip-size (m/defpoint 1.0 0.375)
+       :position-matrix (m/translation 0.125 0.5)
        :evolvers {:model tf-model-evolver}})

     (fg/defcomponent textfield/textfield :entry2
-      {:clip-size (m/defpoint 3.0 0.375)
-       :position-matrix (m/translation 0.25 1.25)
+      {:clip-size (m/defpoint 1.0 0.375)
+       :position-matrix (m/translation 0.125 1.0)
        :evolvers {:model tf-model-evolver}})

     (fg/defcomponent textfield/textfield :entry3
-      {:clip-size (m/defpoint 3.0 0.375)
-       :position-matrix (m/translation 0.25 1.75)
+      {:clip-size (m/defpoint 1.0 0.375)
+       :position-matrix (m/translation 0.125 1.5)
        :evolvers {:model tf-model-evolver}})

     (fg/defcomponent panel/panel :panel1
-      {:clip-size (m/defpoint 6.5 4.0)
-       :position-matrix (m/translation 0.25 2.5)
+      {:clip-size (m/defpoint 3.125 2.875)
+       :position-matrix (m/translation 0.125 2.0)
        :look container-look}

       (fg/defcomponent textfield/textfield :entry1-1
-        {:clip-size (m/defpoint 1.5 0.375)
-         :position-matrix (m/translation 0.125 0.5)
+        {:clip-size (m/defpoint 1.0 0.375)
+         :position-matrix (m/translation 0.125 0.375)
          :evolvers {:model tf-model-evolver}})

       (fg/defcomponent textfield/textfield :entry1-2
-        {:clip-size (m/defpoint 1.5 0.375)
-         :position-matrix (m/translation 1.75 0.5)
+        {:clip-size (m/defpoint 1.0 0.375)
+         :position-matrix (m/translation 1.25 0.375)
          :evolvers {:model tf-model-evolver}})

-           (fg/defcomponent panel/panel :panel1-1
-             {:clip-size (m/defpoint 6.25 2.75)
-              :position-matrix (m/translation 0.125 1.125)
-              :look container-look}
-
-             (fg/defcomponent panel/panel :panel1-1-1
-               {:clip-size (m/defpoint 3.0 2.25)
-                :position-matrix (m/translation 0.125 0.375)
-                :look container-look})
-
-             (fg/defcomponent panel/panel :panel1-1-2
-               {:clip-size (m/defpoint 2.875 2.25)
-                :position-matrix (m/translation 3.25 0.375)
-                :look container-look}
-
-               (fg/defcomponent panel/panel :panel1-1-2-1
-                 {:clip-size (m/defpoint 2.625 1.5)
-                  :position-matrix (m/translation 0.125 0.5)
-                  :look container-look}
-
-               (fg/defcomponent textfield/textfield :entry1-1-2-1
-                 {:clip-size (m/defpoint 1.5 0.375)
-                  :position-matrix (m/translation 0.125 0.5)
-                  :evolvers {:model tf-model-evolver}})))))))
+      (fg/defcomponent panel/panel :panel1-1
+        {:clip-size (m/defpoint 2.875 1.875)
+         :position-matrix (m/translation 0.125 0.875)
+         :look container-look}
+
+        (fg/defcomponent panel/panel :panel1-1-1
+          {:clip-size (m/defpoint 1.0 1.375)
+           :position-matrix (m/translation 0.125 0.375)
+           :look container-look})
+
+        (fg/defcomponent panel/panel :panel1-1-2
+          {:clip-size (m/defpoint 1.5 1.375)
+           :position-matrix (m/translation 1.25 0.375)
+           :look container-look}
+
+          (fg/defcomponent panel/panel :panel1-1-2-1
+            {:clip-size (m/defpoint 1.25 0.875)
+             :position-matrix (m/translation 0.125 0.375)
+             :look container-look}
+
+          (fg/defcomponent textfield/textfield :entry1-1-2-1
+            {:clip-size (m/defpoint 1.0 0.375)
+             :position-matrix (m/translation 0.125 0.375)
+             :evolvers {:model tf-model-evolver}})))))))

 (def focus-window-3
   (fg/defcomponent
     window/window
     :hello3
-    {:clip-size (m/defpoint 7 3.25)
-     :position-matrix (m/translation 1 7.5)
+    {:clip-size (m/defpoint 4 2.5)
+     :position-matrix (m/translation 0.125 5.25)
      :text title-3
      :evolvers {:text window-text-evolver-3}}

     (fg/defcomponent panel/panel :panel
-      {:clip-size (m/defpoint 6.75 2.5)
+      {:clip-size (m/defpoint 3.5 1.875)
        :position-matrix (m/translation 0.125 0.5)
        :look container-look}

       (fg/defcomponent panel/panel :panel1
-        {:clip-size (m/defpoint 3.0 0.875)
-         :position-matrix (m/translation 0.25 0.75)
+        {:clip-size (m/defpoint 3.25 0.875)
+         :position-matrix (m/translation 0.125 0.375)
          :look container-look}

         (fg/defcomponent textfield/textfield :entry1-1
@@ -255,26 +232,26 @@
                           :evolvers {:model tf-model-evolver}}))

       (fg/defcomponent textfield/textfield :entry1
-        {:clip-size (m/defpoint 1.5 0.375)
-         :position-matrix (m/translation 0.125 1.75)
+        {:clip-size (m/defpoint 1.0 0.375)
+         :position-matrix (m/translation 0.125 1.375)
          :evolvers {:model tf-model-evolver}})

       (fg/defcomponent textfield/textfield :entry2
-        {:clip-size (m/defpoint 1.5 0.375)
-         :position-matrix (m/translation 1.75 1.75)
+        {:clip-size (m/defpoint 1.0 0.375)
+         :position-matrix (m/translation 1.25 1.375)
          :evolvers {:model tf-model-evolver}})

       (fg/defcomponent textfield/textfield :entry3
-        {:clip-size (m/defpoint 1.5 0.375)
-         :position-matrix (m/translation 3.375 1.75)
+        {:clip-size (m/defpoint 1.0 0.375)
+         :position-matrix (m/translation 2.375 1.375)
          :evolvers {:model tf-model-evolver}}))))

 (def focus-window-4
   (fg/defcomponent
     window/window
     :hello4
-    {:clip-size (m/defpoint 7.0 2.0)
-     :position-matrix (m/translation 9 7.5)
+    {:clip-size (m/defpoint 3.375 2.0)
+     :position-matrix (m/translation 4.25 5.25)
      :text title-4
      :evolvers {:text window-text-evolver-4}}

@@ -297,8 +274,8 @@
   (fg/defcomponent
     window/window
     :hello5
-    {:clip-size (m/defpoint 4.25 1.625)
-     :position-matrix (m/translation 9 9.75)
+    {:clip-size (m/defpoint 4 1.5)
+     :position-matrix (m/translation 0.125 7.875)
      :text title-5
      :evolvers {:text window-text-evolver-5}}

@@ -316,8 +293,8 @@
   (fg/defcomponent
     window/window
     :hello6
-    {:clip-size (m/defpoint 4.25 1.625)
-     :position-matrix (m/translation 13.5 9.75)
+    {:clip-size (m/defpoint 3.375 1.0)
+     :position-matrix (m/translation 4.25 7.875)
      :text title-6
      :evolvers {:text window-text-evolver-6}}

@@ -331,7 +308,7 @@
   (fg/defcomponent
     panel/panel
     :main
-    {:clip-size (m/defpoint 40 25)
+    {:clip-size (m/defpoint 7.75 9.5)
      :background (awt/color 9 17 26)

      ;; TODO this should be a part defroot probably


Some cleanup of canonicalize tests.

Some cleanup of canonicalize tests.

--- test/structural_typing/mechanics/f_canonicalizing_types.clj
+++ test/structural_typing/mechanics/f_canonicalizing_types.clj
@@ -9,57 +9,103 @@
   (:use midje.sweet))

-;; Note: ..t.. is used as an irrelevant type-repo
-
-;;; Utilities
-
-
-
-
-
-
-;;; Decompressors
-
-;; Note: in tests below, I'll use `list` when I want to signify that a
-;; collection of values correspond to the multiple condensed descriptions that
-;; `named` accepts.
-
-(fact dc:validate-description-types
-  (fact "passes through many things unchanged"
-    (subject/dc:validate-starting-descriptions (list {} [] )) => (list {} [] ))
-
-  (fact "errors in canonicalize context"
-    (subject/canonicalize ..t.. :a) => (throws #"maps or vectors")))
-
-
-(fact dc-expand-type-signifiers
-  (fact "passes through many things unchanged"
-    (subject/dc:expand-type-signifiers ..repo.. []) => []
-    (let [unchanged [ (path/requires :x [:y :z]) {:a even?} ]]
-      (subject/dc:expand-type-signifiers ..repo.. unchanged) => unchanged))
-
-
-  (fact "deep-traverses to find `includes`"
-    (let [point {[:x] [even?], [:y] [odd?]}
-          type-map {:Point point}]
-
-      (subject/dc:expand-type-signifiers type-map (list {[:a :b] (path/includes :Point)} ))
-      => [{[:a :b] point}]
-
-      (subject/dc:expand-type-signifiers type-map (list (path/requires :x [:a (path/includes :Point)])))
-      => [ (path/requires :x [:a point]) ]
-
-
-      (subject/dc:expand-type-signifiers type-map [
-         (path/requires :x (list :a (path/includes :Point)))
-         (path/requires (list :a [:b :c] (path/includes :Point)))
-         ]) =>
-           [
-            (path/requires :x [:a point])
-            (path/requires [:a [:b :c] point])
-           ]))
-
-  (fact "affects canonicalization"
+(def ps list) ; "partial type descriptions" - just to make top-level grouping easier to follow
+
+(facts "Part 1: steps in canonicalization explained"
+  (fact dc:expand-type-signifiers
+    ;; only use of the type map ..repo.. used when it's irrelevant
+
+    (fact "passes through many things unchanged"
+      (subject/dc:expand-type-signifiers ..repo.. []) => []
+      (let [unchanged (ps (path/requires :x [:y :z])
+                          {:a even?})]
+        (subject/dc:expand-type-signifiers ..repo.. unchanged) => unchanged))
+
+    (fact "deep-traverses to find `includes`"
+      (let [point {[:x] [even?], [:y] [odd?]}
+            type-map {:Point point}]
+
+        (subject/dc:expand-type-signifiers type-map (ps {[:a :b]
+                                                         (path/includes :Point)} ))
+        => [{[:a :b] point}]
+
+        (subject/dc:expand-type-signifiers type-map
+                                           (ps (path/requires :x [:a (path/includes :Point)])))
+        => [ (path/requires :x [:a point]) ]
+
+
+        (subject/dc:expand-type-signifiers type-map
+                                           (ps (path/requires :x [:a (path/includes :Point)])
+                                               {[:a [:b :c]] (path/includes :Point)}))
+        => (ps (path/requires :x [:a point])
+               {[:a [:b :c]] point}))))
+
+  (fact dc:validate-starting-descriptions
+    (subject/dc:validate-starting-descriptions (ps {} [] )) => (ps {} [])
+    (subject/dc:validate-starting-descriptions (ps :a)) => (throws #"maps or vectors"))
+
+  (fact dc:spread-collections-of-required-paths
+    (fact "passes maps through unchanged"
+      (subject/dc:spread-collections-of-required-paths (ps {} {:a 1})) => (just {} {:a 1}))
+
+    (fact "splices vectors in"
+      (subject/dc:spread-collections-of-required-paths
+       (ps (path/requires [:l1a :l2a] [:l1b :l2b])
+             {:c even?}))
+      => (just [:l1a :l2a] [:l1b :l2b] {:c even?}))
+
+    (fact "converts a single key to a singleton path"
+      (subject/dc:spread-collections-of-required-paths (ps (path/requires :a :b)
+                                                           {:c even?}))
+      => (just [:a] [:b] {:c even?})))
+
+
+  (fact dc:split-paths-ending-in-maps
+    (fact "doesn't care about maps or most vectors"
+      (subject/dc:split-paths-ending-in-maps (ps {} [:a :b] )) => (just {} [:a :b] ))
+
+    (fact "paths ending in maps are split into a pure path and a map"
+      (subject/dc:split-paths-ending-in-maps (ps [:a {:b 1}] ))
+      => (just [:a]
+               {[:a] {:b 1}})))
+
+
+  (fact dc:required-paths->maps
+    (subject/dc:required-paths->maps []) => []
+    (fact "doesn't care about maps"
+      (subject/dc:required-paths->maps (ps {:a 1} )) => (just {:a 1}))
+
+    (fact "produces one map for each incoming vector"
+      (subject/dc:required-paths->maps (ps [:a] [:b :c])) => (just {[:a] [pred/required-key]}
+                                                                   {[:b :c] [pred/required-key]} ))
+
+    (fact "forking paths are not processed yet"
+      (subject/dc:required-paths->maps (ps [:a [:b :c] :d]))
+      => (just {[:a [:b :c] :d] [pred/required-key]})))
+
+
+  (fact dc:flatten-maps
+    (subject/dc:flatten-maps []) => []
+
+    (fact "only cares about maps"
+      (subject/dc:flatten-maps (ps [:a :b] [:a])) => (just [:a :b] [:a]))
+
+    (fact "flattens individual maps"
+      (subject/dc:flatten-maps (ps {:a {:b even?}})) => [ { [:a :b] [even?] } ]))
+
+
+
+
+
+
+
+)
+
+
+
+
+(facts "Part 2: examples of use in canonicalization"
+  (fact dc:expand-type-signifiers
     (let [type-map {:Type (subject/canonicalize ..t.. [:a] {:a odd? :b even?})}]
       (subject/canonicalize type-map (path/includes :Type)) => {[:a] [pred/required-key odd?]
                                                                 [:b] [even?]}
@@ -76,42 +122,19 @@
       => {[:a :a] [pred/required-key odd?]
           [:a :b] [even?]
           [:a :c] [pos?]
-          [:c] [pred/required-key]})))
-
-(fact dc:spread-collections-of-required-paths
-  (fact "passes maps through unchanged"
-    (subject/dc:spread-collections-of-required-paths (list {} {:a 1} )) => (just {} {:a 1}))
-
-  (fact "splicing-substitutes paths"
-    (subject/dc:spread-collections-of-required-paths (list (path/requires [:l1a :l2a] [:l1b :l2b]) ))
-    => (just [:l1a :l2a] [:l1b :l2b]))
-
-  (fact "converts a single key to a singleton path"
-    (subject/dc:spread-collections-of-required-paths (list (path/requires :a :b) ))
-    => (just [:a] [:b] ))
-
-  (fact "affects canonicalization"
-    (subject/canonicalize ..t.. [:a :b :c])
-    => (subject/canonicalize ..t.. [:a] [:b] [:c])))
-
-
-(fact dc:split-paths-ending-in-maps
-  (fact "doesn't care about maps or most vectors"
-    (subject/dc:split-paths-ending-in-maps (list {} [:a :b] )) => (just {} [:a :b] ))
-
-  (fact "paths ending in maps are split into a pure path and a map"
-    ;; note that vector has already been spread.
-    (subject/dc:split-paths-ending-in-maps (list [:a {:b 1}] ))
-    => (just [:a] {[:a] {:b 1}} ))
-
-  (fact "error cases in context of canonicalize"
-    (subject/canonicalize ..t.. (path/requires [{:a 1}]))
-    => (throws "A map cannot be the first element of a path: `[{:a 1}]`")
-
-    (subject/canonicalize ..t.. (path/requires [:a {:a even?} :a]))
-    => (throws #"Nothing may follow a map within a path"))
-
-  (fact "affects canonicalization"
+          [:c] [pred/required-key]}))
+
+  (fact dc:spread-collections-of-required-paths
+    (subject/canonicalize ..t.. (path/requires :a :b :c [:d :e]))
+    => (subject/canonicalize ..t.. (path/requires :a)
+                                   (path/requires [:b])
+                                   (path/requires :c)
+                                   (path/requires [:d :e])))
+
+  (fact dc:split-paths-ending-in-maps
+    (subject/canonicalize ..t.. (path/requires [:x {:a even?, :b even?}]))
+    => (subject/canonicalize ..t.. (path/requires [:x]) {:x {:a even?, :b even?}})
+
     (subject/canonicalize ..t.. (path/requires [:x {:a even?, :b even?} ]))
     => {[:x] [pred/required-key]
         [:x :a] [even?]
@@ -121,19 +144,16 @@
                                                     :d even?}] ))
     => {[:a] [pred/required-key]
         [:a :b :c] [even?]
-        [:a :d] [even?]}))
-
-
-(fact dc:flatten-maps
-  (subject/dc:flatten-maps []) => []
-
-  (fact "only cares about maps"
-    (subject/dc:flatten-maps (list [:a :b] [:a])) => (just [:a :b] [:a]))
-
-  (fact "flattens individual maps"
-    (subject/dc:flatten-maps [ {:a {:b even?}}]) => [ { [:a :b] [even?] } ])
-
-  (fact "affects canonicalization"
+        [:a :d] [even?]})
+
+  (fact dc:required-paths->maps
+    (subject/canonicalize ..t.. (path/requires :a [:b :d]) (path/requires :c))
+    => {[:a] [pred/required-key]
+        [:b :d] [pred/required-key]
+        [:c] [pred/required-key]})
+
+
+  (fact "dc:flatten-maps"
     (subject/canonicalize ..t.. {:a {:b even?}}) => {[:a :b] [even?]}

     (subject/canonicalize ..t.. {[:a :b] {[:c [:d1 :d2]] even?}})
@@ -143,112 +163,64 @@
     (fact "this is a pretty unlikely map to use, but it will work"
       (subject/canonicalize ..t..
                             {:points {ALL {:x integer?
-                                           :y integer?}}}) => {[:points ALL :x] [integer?]
-                                                               [:points ALL :y] [integer?]})))
-
-(fact dc:required-paths->maps
-  (fact "doesn't care about maps"
-    (subject/dc:required-paths->maps []) => []
-    (subject/dc:required-paths->maps (list {:a 1} )) => (just {:a 1}))
-
-  (fact "produces one map for each incoming vector"
-    (subject/dc:required-paths->maps (list [:a] [:b :c])) => (just {[:a] [pred/required-key]}
-                                                                {[:b :c] [pred/required-key]} ))
-
-  (fact "forking paths are left alone"
-    (subject/dc:required-paths->maps (list [:a [:b :c] :d]))
-    => (just {[:a [:b :c] :d] [pred/required-key]}))
-
-  (fact "affects canonicalization"
-    (fact "singleton paths"
-      (subject/canonicalize ..t.. [ :a :b ])
-      => {[:a] [pred/required-key] [:b] [pred/required-key]}
-      (subject/canonicalize ..t.. (path/requires :a :b))
-      => {[:a] [pred/required-key] [:b] [pred/required-key]}
-      (subject/canonicalize ..t.. (path/requires [:a] [:b] ))
-      => {[:a] [pred/required-key] [:b] [pred/required-key]})
-
-    (fact "multi-element vectors are paths"
-      (subject/canonicalize ..t.. (path/requires [:a :c]
-                                                 [:b :d])) => {[:a :c] [pred/required-key]
-                                                               [:b :d] [pred/required-key]})
-
-    (fact "nested and unnested elements can be combined"
-      (subject/canonicalize ..t.. (path/requires :a [:b :c] :d)) => {[:a] [pred/required-key]
-                                                                     [:b :c] [pred/required-key]
-                                                                     [:d] [pred/required-key]})))
-
-
-
-
-
-
-;;;; About type-map and path merging, which happens throughout
-
-(fact "multiple arguments are allowed"
-  (subject/canonicalize ..t.. {:a pred/required-key} {:b pred/required-key})
-  => {[:a] [pred/required-key]
-      [:b] [pred/required-key]})
-
-(fact "arguments with the same keys have their values merged"
-  (subject/canonicalize ..t.. {:a pred/required-key} {:a even?})
-  => {[:a] [pred/required-key even?]}
-  (subject/canonicalize ..t..
-                        {:a {:b pred/required-key}}
-                        {:a map?}
-                        {:a {:b even?}})
-  => {[:a] [map?]
-      [:a :b] [pred/required-key even?]})
-
-(fact "maps and vectors can be merged"
-  (subject/canonicalize ..t.. [ :a :b ] {:a even?})
-  => {[:a] [pred/required-key even?]
-      [:b] [pred/required-key]})
-
-(fact "note that forks allow the possibility of duplicate paths"
-  (subject/canonicalize ..t.. {[:a :b1] pos?
-                               [:a [:b1 :b2]] even?})
-  => (just {[:a :b1] (just [(exactly pos?) (exactly even?)] :in-any-order)
-            [:a :b2] [even?]})
-
-  (subject/canonicalize ..t.. {[:a :b] pos?
-                               [:a] {:b even?}})
-  => (just {[:a :b] (just [(exactly pos?) (exactly even?)] :in-any-order)}))
-
-
-;;; Some typical uses of a type-map
-(let [type-map (-> {}
-                   (assoc :Point (subject/canonicalize ..t.. [:x :y]
-                                                       {:x integer? :y integer?})
-                          :Colored (subject/canonicalize ..t.. [:color]
-                                                         {:color string?})
-                          :OptionalColored (subject/canonicalize ..t..
-                                                                 {:color string?})))]
-  (fact "merging types"
-    (fact "making a colored point by addition"
-      (subject/canonicalize type-map (path/includes :Point) [:color] {:color string?})
-      => {[:color] [pred/required-key string?]
-          [:x] [pred/required-key integer?]
-          [:y] [pred/required-key integer?]})
-
-    (fact "or you can just merge types"
-      (subject/canonicalize type-map (path/includes :Point) (path/includes :Colored))
-      => {[:color] [pred/required-key string?]
-          [:x] [pred/required-key integer?]
-          [:y] [pred/required-key integer?]})
-
-    (fact "note that merging an optional type doesn't make it required"
-      (subject/canonicalize type-map (path/includes :Point) (path/includes :OptionalColored))
-      => {[:color] [string?]
-          [:x] [pred/required-key integer?]
-          [:y] [pred/required-key integer?]}))
-
-  (fact "subtypes"
-    (fact "making a colored point by addition"
-      (subject/canonicalize type-map (path/includes :Point) [:color] {:color string?})
-      => {[:color] [pred/required-key string?]
-          [:x] [pred/required-key integer?]
-          [:y] [pred/required-key integer?]}
+                                           :y integer?}}})
+      => {[:points ALL :x] [integer?]
+          [:points ALL :y] [integer?]}))
+)
+
+
+
+(facts "About type-map and path merging"
+
+  (fact "multiple arguments are allowed"
+    (subject/canonicalize ..t.. {:a pred/required-key} {:b pred/required-key})
+    => {[:a] [pred/required-key]
+        [:b] [pred/required-key]})
+
+  (fact "arguments with the same keys have their values merged"
+    (subject/canonicalize ..t.. {:a pred/required-key} {:a even?})
+    => {[:a] [pred/required-key even?]}
+    (subject/canonicalize ..t..
+                          {:a {:b pred/required-key}}
+                          {:a map?}
+                          {:a {:b even?}})
+    => {[:a] [map?]
+        [:a :b] [pred/required-key even?]})
+
+  (fact "maps and vectors can be merged"
+    (subject/canonicalize ..t.. [ :a :b ] {:a even?})
+    => {[:a] [pred/required-key even?]
+        [:b] [pred/required-key]})
+
+  (fact "nested and unnested elements can be combined"
+    (subject/canonicalize ..t.. (path/requires :a [:b :c] :d)) => {[:a] [pred/required-key]
+                                                                   [:b :c] [pred/required-key]
+                                                                   [:d] [pred/required-key]})
+  (fact "note that forks allow the possibility of duplicate paths"
+    (subject/canonicalize ..t.. {[:a :b1] pos?
+                                 [:a [:b1 :b2]] even?})
+    => (just {[:a :b1] (just [(exactly pos?) (exactly even?)] :in-any-order)
+              [:a :b2] [even?]})
+
+    (subject/canonicalize ..t.. {[:a :b] pos?
+                                 [:a] {:b even?}})
+    => (just {[:a :b] (just [(exactly pos?) (exactly even?)] :in-any-order)})))
+
+
+(facts "Some typical uses of a type-map"
+  (let [type-map (-> {}
+                     (assoc :Point (subject/canonicalize ..t.. [:x :y]
+                                                         {:x integer? :y integer?})
+                            :Colored (subject/canonicalize ..t.. [:color]
+                                                           {:color string?})
+                            :OptionalColored (subject/canonicalize ..t..
+                                                                   {:color string?})))]
+    (fact "merging types"
+      (fact "making a colored point by addition"
+        (subject/canonicalize type-map (path/includes :Point) [:color] {:color string?})
+        => {[:color] [pred/required-key string?]
+            [:x] [pred/required-key integer?]
+            [:y] [pred/required-key integer?]})

       (fact "or you can just merge types"
         (subject/canonicalize type-map (path/includes :Point) (path/includes :Colored))
@@ -262,17 +234,36 @@
             [:x] [pred/required-key integer?]
             [:y] [pred/required-key integer?]}))

-    (fact "a line has a start and an end, which are points"
-      (subject/canonicalize type-map [:start :end]
-                            {:start (path/includes :Point)
-                             :end (path/includes :Point)})
-      => {[:start] [pred/required-key]
-          [:end] [pred/required-key]
-          [:start :x] [pred/required-key integer?]
-          [:start :y] [pred/required-key integer?]
-          [:end :x] [pred/required-key integer?]
-          [:end :y] [pred/required-key integer?]})
-
+    (fact "subtypes"
+      (fact "making a colored point by addition"
+        (subject/canonicalize type-map (path/includes :Point) [:color] {:color string?})
+        => {[:color] [pred/required-key string?]
+            [:x] [pred/required-key integer?]
+            [:y] [pred/required-key integer?]}
+
+        (fact "or you can just merge types"
+          (subject/canonicalize type-map (path/includes :Point) (path/includes :Colored))
+          => {[:color] [pred/required-key string?]
+              [:x] [pred/required-key integer?]
+              [:y] [pred/required-key integer?]})
+
+        (fact "note that merging an optional type doesn't make it required"
+          (subject/canonicalize type-map (path/includes :Point) (path/includes :OptionalColored))
+          => {[:color] [string?]
+              [:x] [pred/required-key integer?]
+              [:y] [pred/required-key integer?]}))
+
+      (fact "a line has a start and an end, which are points"
+        (subject/canonicalize type-map [:start :end]
+                              {:start (path/includes :Point)
+                               :end (path/includes :Point)})
+        => {[:start] [pred/required-key]
+            [:end] [pred/required-key]
+            [:start :x] [pred/required-key integer?]
+            [:start :y] [pred/required-key integer?]
+            [:end :x] [pred/required-key integer?]
+            [:end :y] [pred/required-key integer?]})
+
     (fact "a figure has a color and a set of points"
       (subject/canonicalize type-map [:points]
                             {[:points ALL] (path/includes :Point)}
@@ -289,29 +280,27 @@
       => {[:points] [pred/required-key]
           [:points ALL :color] [pred/required-key string?]
           [:points ALL :x] [pred/required-key integer?]
-          [:points ALL :y] [pred/required-key integer?]})))
-
-
-;;;; Let us not forget the simple cases
-
-(fact "simple maps just have their keys and values vectorized"
-  (subject/canonicalize ..t.. {:a even?}) => {[:a] [even?]}
-  (subject/canonicalize ..t.. {:a even?, :b even?})
-  => {[:a] [even?]
-      [:b] [even?]})
-
-(fact "simple vectors"
-  (subject/canonicalize ..t.. [:a :b]) => {[:a] [pred/required-key]
-                                           [:b] [pred/required-key]})
-
-
+          [:points ALL :y] [pred/required-key integer?]}))))
+
+
+(fact "let us not forget the simple cases"
+  (fact "simple maps just have their keys and values vectorized"
+    (subject/canonicalize ..t.. {:a even?}) => {[:a] [even?]}
+    (subject/canonicalize ..t.. {:a even?, :b even?})
+    => {[:a] [even?]
+        [:b] [even?]})
+
+  (fact "simple vectors"
+    (subject/canonicalize ..t.. [:a :b]) => {[:a] [pred/required-key]
+                                             [:b] [pred/required-key]}))
+
 ;;;; Canonicalize - random examples, probably redundant

 (fact "already vectorized keys and values are left alone if flat"
   (subject/canonicalize ..t.. {[:a] even?}) => {[:a] [even?]}
   (subject/canonicalize ..t.. {[:a] [even?]}) => {[:a] [even?]}
   (subject/canonicalize ..t.. {[:a :b] even?}) => {[:a :b] [even?]})
-
+
 (fact "forks are allowed in vectors"
   (subject/canonicalize ..t.. {[:a [:b1 :b2]] even?})
   => {[:a :b1] [even?]
@@ -322,44 +311,3 @@
       [:a :b1 :c :d2] [even?]
       [:a :b2 :c :d1] [even?]
       [:a :b2 :c :d2] [even?]})
-
-
-
-
-
-
-
-
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;
-
-;;; Canonicalization performs the following steps
-
-(fact
-  (let [Point {:x2x [pred/required-key integer?]
-               :x2y [pred/required-key integer?]}
-        type-map {:Point Point}]
-
-    (future-fact "first, expand type signifiers: no old types are irrelevant"
-      (dc:expand-type-signifiers type-map [[:a (path/includes :Point)]]) => [[:a Point]])
-    ;; Now there are no type signifiers
-
-    (future-fact "maps to condensed ppps"
-      (subject/dc2:condensed-maps->condensed-ppps [ {:a pred/required-key}
-                                                    {[:a :b] [pred/required-key even?]}
-                                                    {:a {:b even?}} ])
-      => (just (just [:a] #{pred/required-key})
-               (just [:a :b] #{pred/required-key even?})
-               (just [:a :b] #{even?})))
-
-    (fact "combining into a type description"
-      (let [result (ppp/->type-description [ (vector [:a :b] #{even?})
-                                             (vector [:a :b] #{odd?})
-                                             (vector [:a] #{pred/required-key})])]
-        (get result [:a :b]) => vector?
-        (get result [:a :b]) => (just [(exactly even?) (exactly odd?)] :in-any-order)
-        (get result [:a]) => vector?
-        (get result [:a]) => [pred/required-key]))))
-
-


refactor

refactor

--- src/clj/salava/metabadge/db.clj
+++ src/clj/salava/metabadge/db.clj
@@ -7,4 +7,4 @@
 (defn badge-id-by-assertion
   "in case of multiple hits return the most recent"
   [ctx assertion_url]
-  (some-> (select-user-badge-id-by-assertion-url {:assertion_url assertion_url} (u/get-db ctx)) #_(into {:result-set-fn first :row-fn :id} (u/get-db ctx)) first :id))
+  (some-> (select-user-badge-id-by-assertion-url {:assertion_url assertion_url} (u/get-db ctx)) first :id))


Send description in issue feedback and close frame after upload

--- src/cljc/robinson/feedback.cljc
+++ src/cljc/robinson/feedback.cljc
@@ -46,9 +46,11 @@
                                                   {:date date
                                                    :version version
                                                    :user-id user-id
+                                                   :description (ss/value description-input)
                                                    :world (if (ss/value upload-input)
                                                             (get state :world)
-                                                            nil)})))
+                                                            nil)})
+                                                (ss/hide! frame)))
   (->
     frame
     ss/pack!


Add blank render for a nil page-key

Add blank render for a nil page-key

This prevents the 404 page from flashing briefly before the initial
page-key value is set.

--- src/cljs/comic_reader/main.cljs
+++ src/cljs/comic_reader/main.cljs
@@ -60,6 +60,7 @@
     :site-list [site-list/site-list-container]
     :comic-list [comic-list/comic-page-container]
     :comic-viewer [:div [:h1 "Read a Comic!"]]
+    nil [:span ""]
     [base/four-oh-four]))

 (defn main-panel-container []


Fix for SeqProjectionSource.

Fix for SeqProjectionSource.

--- src/clojure/freactive/core.cljc
+++ src/clojure/freactive/core.cljc
@@ -1059,13 +1059,13 @@
      (deftype SeqProjectionSource [elements target enqueue]
        Object
        (refresh [this]
-         (dotimes [i (count elements)]
-           (target-insert target (nth elements i) nil)))
+         (doseq [elem elements]
+           (target-insert target elem nil)))

        IProjectionSource
        (-source-pull [this idx]
          (when (< idx (count elements))
-           (aget elements idx))))
+           (nth elements idx))))

      (defn seq-projection [elements]
        (reify IProjection


Swtiched to using identical? instead of = when triggering callbacks.

--- src/clojure/freactive/core.cljs
+++ src/clojure/freactive/core.cljs
@@ -73,7 +73,7 @@
   IReset
   (-reset! [a new-value]
     (let [old-value (.-state a)]
-        (when (not= old-value new-value)
+        (when-not (identical? old-value new-value)
           (let [validate (.-validator a)]
             (when-not (nil? validate)
               (assert (validate new-value) "Validator rejected reference state")))
@@ -180,7 +180,7 @@
                             *trace-capture* (when trace-captures
                                               (trace-captures)
                                               trace-captures)] (f))]
-      (when (not= old-val new-val)
+      (when-not (identical? old-val new-val)
         (set! state new-val)
         (-notify-watches this old-val new-val)
         new-val)))
@@ -279,7 +279,7 @@
     (add-watch-fn)
     (let [new-value ((.-getter cursor) @ref)
           old-value (.-state cursor)]
-      (when (not= old-value new-value)
+      (when-not (identical? old-value new-value)
         (set! (.-state cursor) new-value)
         (when-not (empty? (.-watches cursor))
           (-notify-watches cursor old-value new-value))


clean up greetings build.boot

clean up greetings build.boot

--- examples/greetings/build.boot
+++ examples/greetings/build.boot
@@ -83,15 +83,3 @@
         (builtin/sift :move {#"(.*clj$)" (str classes-dir "/$1")})
         (builtin/sift :move {#"(.*\.class$)" (str classes-dir "/$1")})
         ))
-
-        ;; (builtin/show :fileset true)
-        ;; (builtin/sift :to-asset #{#"(.*\.clj$)"}
-        ;;               :move {#"(.*\.clj$)" "WEB-INF/classes/$1"})
-        ;; (clj)
-        ;; (appstats)
-        ;; (filters :keep keep)
-        ;; (servlets :keep keep)
-        ;; (reloader :keep keep)
-        ;; (webxml)
-        ;;(appengine)
-        ;; ))


Fail the test

Fail the test

--- code/system-tests/test/system_tests/test_create_seating_plan.clj
+++ code/system-tests/test/system_tests/test_create_seating_plan.clj
@@ -6,5 +6,5 @@
   (testing "Selenium WebDriver"
     (taxi/set-driver! {:browser :phantomjs})
     (taxi/to "http://www.example.com/")
-    (is (.contains (taxi/text "body") "used for illustrative examples"))
+    (is (.contains (taxi/text "body") "used for illustrative examplez"))
     (taxi/quit)))


CMR-5037: date-at to date-at-str

CMR-5037: date-at to date-at-str

--- umm-spec-lib/src/cmr/umm_spec/xml_to_umm_mappings/dif10.clj
+++ umm-spec-lib/src/cmr/umm_spec/xml_to_umm_mappings/dif10.clj
@@ -143,7 +143,7 @@
                                :SingleDateTimes (dates-at-str temporal "Single_DateTime")
                                :PeriodicDateTimes (for [pdt (select temporal "Periodic_DateTime")]
                                                     {:Name (value-of pdt "Name")
-                                                     :StartDate (date-at pdt "Start_Date")
+                                                     :StartDate (date-at-str pdt "Start_Date")
                                                      :EndDate (parse-dif-end-date (value-of pdt "End_Date"))
                                                      :DurationUnit (value-of pdt "Duration_Unit")
                                                      :DurationValue (value-of pdt "Duration_Value")