Piff examples

Piff examples

--- examples/tutorial.clj
+++ examples/tutorial.clj
@@ -10,12 +10,18 @@
    :last-name "funke"
    :email "tobias.funke@gmail.com"})

-;; this is the raw way to define a lens
-;; you call lens/lens and give it a function
-;; that takes a root value in this case a user
-;; and returns a pair where the first value
-;; is the field. And the second value is a function
-;; that takes a function of the name and returns a new user
+;; This is the raw way to define a lens:
+
+;; you call `lens/lens` with a function that takes a root structure
+;; (in this case a user) and returns a pair of elements:
+
+;; - the first element is the value you want to expose (in this case,
+;; the `:first-name` field of `user`)
+
+;; - the second element is a function that given an update function
+;; returns a new root structure (new user) where the value returned by
+;; the first element (current first name) has been replaced by the
+;; return value of the update function.

 (def first-name
   (lens/lens
@@ -27,41 +33,41 @@
 (require '[clojure.string :as string])
 (use 'clojure.pprint)

-;; you can get the field from the root value
-;; by calling view on it with the lens
+;; you can get the field from the root value by calling view on it
+;; with the lens:

 (pprint (lens/view user first-name))
 ;; => "tobias"

-;; you can also update the field with the update function
+;; you can also update the field with the update function:

 (pprint (lens/update user first-name string/capitalize))
 ;; => {:last-name "funke",
 ;;     :first-name "Tobias", <-- capitalized
 ;;     :email "tobias.funke@gmail.com"}

-;; you can also write to the field with lens/write
-;; this is the same as doing (update root lens (fn [_] new-value))
+;; you can also write to the field with `lens/write`: this is the same
+;; as doing `(update root lens (fn [_] new-value))`.

 (pprint (lens/write user first-name "Newname"))
 ;; => {:last-name "funke",
 ;;     :first-name "Newname",
 ;;     :email "tobias.funke@gmail.com"}

-;; you can also define lenses using lens/getter-setter-lens
-;; which makes a lens from a getter and a setter function
+;; you can also define lenses using `lens/getter-setter-lens`
+;; which makes a lens from a getter and a setter function:

 (def first-name2
   (lens/getter-setter-lens
    (fn [user] (:first-name user))
    (fn [user new-first-name] (assoc user :first-name new-first-name))))

-;; this will make you the same lens
+;; this will give you the same lens:
 (= (lens/write user first-name  "Newname")
    (lens/write user first-name2 "Newname"))

 ;; since using keywords to reference fields in maps is so common
-;; you can use them directly as lenses
+;; you can use them directly as lenses:

 (= (lens/write user first-name  "Newname")
    (lens/write user first-name2 "Newname")
@@ -72,31 +78,31 @@
    (lens/view user :first-name))

 ;; ========================================================
-;; composition
-
-;; a critical future of lenses are that they compose
-;; you can do this with the lens/comp-lenses
-;; this function takes a seq of lenses and combines them
+;; Composition
+
+;; A critical feature of lenses are that they compose.  You can do
+;; this using the `lens/comp-lenses` function that takes a seq of
+;; lenses and combines them:

 (def user2
   {:first-name "tobias"
    :last-name "funke"
-   :address {:city "bluethwill"
+   :address {:city "bluthville"
              :address_line "sudden vale street 23"
              :postcode "56321"}})

 (def user-city (lens/comp-lenses [:address :city]))

-(= (lens/view user2 user-city) "bluethwill")
-
-;; if you use a vector of lenses as a lens
-;; you will get the same result as calling lens/comp-lenses on the lenses
+(= (lens/view user2 user-city) "bluthville")
+
+;; If you use a vector of lenses as a lens you will get the same
+;; result as calling `lens/comp-lenses` on those lenses:

 (= (lens/view user2 [:address :postcode])
    "56321")

-;; so basically you can use lenses just like you use
-;; the clojure *-in functions
+;; so basically you can use lenses just like you use the clojure
+;; get-in/assoc-in/update-in functions:

 (= (get-in user2 [:address :city])
    (lens/view user2 [:address :city]))
@@ -107,29 +113,32 @@
 ;; =====================================================
 ;; iso-lens

-;; the postcode in the nested structure is a string atm
-;; but we can write a lens that lets us treat it as a number
+;; the `:postcode` in the nested structure is represented as a string
+;; but we can write a lens that lets us treat it as a number:

 (def str->num (lens/iso-lens #(Integer/parseInt %) str))

-;; iso-lens takes 2 functions one to convert it to a integer in this case
-;; and another one to convert it back to a string
+;; `iso-lens` takes two functions, the second one being the inverse of
+;; the first. In this case, the first converts the root value to a
+;; integer and the second converts it back to a string.

 (lens/update user2 [:address :postcode str->num] inc)
 ;; {:last-name "funke",
 ;;  :first-name "tobias",
 ;;  :address {:address_line "sudden vale street 23",
 ;;            :postcode "56322",
-;;            :city "bluethwill"}}
-
-;; the result after incrementing the postcode is still a string
+;;            :city "bluthville"}}
+
+;; the result after incrementing the postcode is still a string!
+
+

 ;; =====================================================
 ;; extract

-;; extract is a function that lets you transform a structure
-;; to a map of a different shape and later write back changes
-;; that are done to the new map
+;; `extract` is a function that lets you transform a structure to a
+;; map of a different shape and later write back changes that are done
+;; to the new map:

 (def user-view
   {:first-name   :first-name
@@ -138,26 +147,27 @@
    :address_city [:address :city]})

 (= (lens/view user2 user-view)
-   {:address_line "sudden vale street 23",
+   {:address_line "sudden valley street 23",
     :last-name "funke",
     :first-name "tobias",
-    :address_city "bluethwill"})
+    :address_city "bluthville"})

 (defn take-ower-town
-  "claim the town as you own"
+  "claim the town as your own"
   [user] ;; user in the user-view shape
   (assoc user :address_city (:first-name user)))

 (= (lens/update user2 user-view take-ower-town)
    {:last-name "funke", :first-name "tobias",
-    :address {:address_line "sudden vale street 23",
+    :address {:address_line "sudden valley street 23",
               :postcode "56321",
               :city "tobias"}})

 ;; =================================================
 ;; traversals

-;; traversals lets you dig into collections (or any thing that can be "traversed")
+;; traversals let you dig into collections (or any thing that can be
+;; "traversed")

 (def user3
   {:first-name "tobias"
@@ -169,11 +179,11 @@
     :first-name "tobias",
     :languages '("Clojure" "Ruby" "Elixir")})

-;; travers/mapped treats the items as seqs. so all results will be
-;; converted to lists
-;; but a traversal can create whatever structure it wants
-
-;; lets write a vector travers
+;; `travers/mapped` treats the items as seqs, so all results will be
+;; converted to lists, but a traversal can create whatever structure
+;; it wants.
+
+;; lets write a vector traversal:

 (def mapped-vec
   (lens/traversal
@@ -181,23 +191,20 @@
      [collection
       (fn [f] (mapv f collection))])))

-;; traversals are built a lot like lenses
-;; its a function that takes the structure
-;; in this case a collection
-;; it returns a pair that where the first item is
-;; all the items it "traverses" as a seq.
-;; and the second item is a function
-;; that builds a new value after applying the function
-;; to every item it traverses. IE a mapping
+;; Traversals are built a lot like lenses: they are functions that
+;; take a structure (in this case a collection) and return a pair
+;; where the first element is a seq of all the items it "traverses"
+;; and the second item is a function that builds a new value after
+;; applying the function to every item traversed. IE a mapping.
+
+;; this version keeps the languages in a vector:

 (= (lens/update user3 [:languages mapped-vec] string/capitalize)
    {:last-name "funke",
     :first-name "tobias",
     :languages ["Clojure" "Ruby" "Elixir"]})

-;; this version keeps the languages in a vector
-
-;; traversals can be composed with lenses in any way you want
+;; traversals can be composed with lenses in any way you want:

 (def deep-data
   {:a [{:b [{:c [1 2 3]}
@@ -217,9 +224,12 @@
         {:b [{:c [2 6]}
              {:c [6]}]}]})

-;; you can take a traversal and shrink the result your working with
+;; you can take a traversal and shrink the result you are working
+;; with:

 (def even-cs-lens [cs-lens (travers/shrink even?)])
+
+;; `even-cs-lens` will only access even values:

 (= (lens/write deep-data even-cs-lens 0)
    {:a [{:b [{:c [1 0 3]}
@@ -229,21 +239,22 @@
         {:b [{:c [1 3]}
              {:c [3]}]}]})

-;; this will only write to even values
-
-;; if you view a traversed lens you get all
-;; values it points to as a flattened seq
+
+;; if you view a traversed lens you get all values it points to as a
+;; flattened seq:

 (= (lens/view deep-data even-cs-lens)
    [2 4 8])

 ;; this returns all even values in the :c fields of the deep-data
+;; structure.

 ;; ===========================================
-
 ;; tree
-;; ok! lets work with some tree data
-;; courtesy of http://msdn.microsoft.com/en-us/library/ms762271(v=vs.85).aspx
+
+
+;; OK! lets work with some tree data!
+;; (courtesy of http://msdn.microsoft.com/en-us/library/ms762271(v=vs.85).aspx)

 (def xml-string
   "<?xml version=\"1.0\"?>
@@ -376,39 +387,42 @@

 (def xml-catalog (parse-xml-str xml-string))

-;; first task! something simple
-;; Lets change the name of all the authors to tobias funke in this xml document.
-;; This could be accomplished by digging down to the right elements and updating them
-;; appropriately... but a lazier way would be to just walk all of the tree
-;; and replace the contents of the elements with the author tag
-
-;; we can use tree/pre-tree to accomplish this
+;; First task! Something simple: let's change the name of all the
+;; authors to Tobias Funke in this xml document.
+
+;; This could be accomplished by digging down to the right elements
+;; and updating them appropriately... But a lazier way would be to
+;; just walk all of the tree and replace the contents of the elements
+;; with the author tag.
+
+;; We can use `tree/pre-tree` to accomplish this:
 ;; it is a function that takes a traversal of all sub nodes of a node
-;; and gives you a traversal of all nodes in the tree
+;; and gives you a traversal of all nodes in the tree.
+
 ;; EXAMPLE:
-
-;; since nodes in the

 (def xml-nodes (tree/pre-tree
                 [:content
-                 (travers/filtered map?) ; we don't want to list the strings
-                                         ; in the tree as nodes
-                                         ; so we filter them here
+                 (travers/filtered map?) ; we don't want to consider
+                                         ; the strings in the tree as
+                                         ; nodes so we filter them
+                                         ; here
                  ]))

-;; xml nodes here is a lens/traversal that lets you view and modify
-;; nodes of the tree in a pre-walk fashion.
-;; (there is also a post-tree that lets you do it in a post-walk fashion)
-
-;; ok so lets shrink the nodes we are working with to only the nodes
-;; with the tag author
+;; `xml-nodes` defined above using `tree/pre-tree` is a lens/traversal
+;; that lets you view and modify nodes of an XML tree in a pre-walk
+;; fashion. (There is also a corresponding `tree/post-tree` that lets
+;; you do it in a post-walk fashion)
+
+;; ok so let's shrink the nodes we are working with and consider only
+;; the nodes with the "author" tag:

 (def authors [xml-nodes (travers/shrink #(= (:tag %) :author))])

-;; and change the contents of these nodes to be "tobias funke"
+;; then change the content of these nodes to "Tobias Funke":

 (pprint
  (-> xml-catalog
-     (lens/write [authors :content] ["tobias funke"])))
-
-;; perfect all the authors are now tobias funke
+     (lens/write [authors :content] ["Tobias Funke"])))
+
+;; Perfect! All the authors are now Tobias Funke!


[#681] Remove unnecessary (after #699) expressions to ensure clje.user creation

--- test/clj/clojure/test_clojure/reader.cljc
+++ test/clj/clojure/test_clojure/reader.cljc
@@ -15,10 +15,6 @@
 ;;
 ;;  scgilardi (gmail)
 ;;  Created 22 October 2008
-
-;; Ensure there is a clje.user namespace
-(ns clje.user)
-(def x 1)

 (ns clojure.test-clojure.reader
   (:use clojure.test)


Cosmetics

Cosmetics

--- test/clojurewerkz/cassaforte/cql_test.clj
+++ test/clojurewerkz/cassaforte/cql_test.clj
@@ -345,8 +345,7 @@

   (is (= (set (range 11 20))
          (->> (select :tv_series
-                      (paginate :key :episode_id :per-page 10 :last-key 10 :where { :series_title "Futurama"})
-                      )
+                      (paginate :key :episode_id :per-page 10 :last-key 10 :where { :series_title "Futurama"}))
               (map :episode_id)
               set)))


Pass multi peer.

Pass multi peer.

--- test/onyx/coordinator/multi_peer_test.clj
+++ test/onyx/coordinator/multi_peer_test.clj
@@ -15,6 +15,9 @@
       (let [peer-node-a (extensions/create sync :peer)
             peer-node-b (extensions/create sync :peer)

+            pulse-node-a (extensions/create sync :pulse)
+            pulse-node-b (extensions/create sync :pulse)
+
             payload-node-a-1 (extensions/create sync :payload)
             payload-node-b-1 (extensions/create sync :payload)

@@ -47,10 +50,10 @@
         (tap (:ack-mult coordinator) ack-ch-spy)
         (tap (:offer-mult coordinator) offer-ch-spy)

-        (extensions/write-place sync peer-node-a payload-node-a-1)
+        (extensions/write-place sync peer-node-a {:pulse pulse-node-a :payload payload-node-a-1})
         (extensions/on-change sync payload-node-a-1 #(>!! sync-spy-a %))

-        (extensions/write-place sync peer-node-b payload-node-b-1)
+        (extensions/write-place sync peer-node-b {:pulse pulse-node-b :payload payload-node-b-1})
         (extensions/on-change sync payload-node-b-1 #(>!! sync-spy-b %))

         (>!! (:born-peer-ch-head coordinator) peer-node-a)
@@ -84,10 +87,10 @@
             (<!! status-spy)
             (<!! status-spy)

-            (extensions/write-place sync peer-node-a payload-node-a-2)
+            (extensions/write-place sync peer-node-a {:pulse pulse-node-a :payload payload-node-a-2})
             (extensions/on-change sync payload-node-a-2 #(>!! sync-spy-a %))

-            (extensions/write-place sync peer-node-b payload-node-b-2)
+            (extensions/write-place sync peer-node-b {:pulse pulse-node-b :payload payload-node-b-2})
             (extensions/on-change sync payload-node-b-2 #(>!! sync-spy-b %))

             (extensions/touch-place sync (:completion (:nodes payload-a)))
@@ -128,6 +131,7 @@
     (fn [coordinator sync log]
       (let [n 4
             peers (take n (repeatedly (fn [] (extensions/create sync :peer))))
+            pulses (take n (repeatedly (fn [] (extensions/create sync :pulse))))
             payloads (take n (repeatedly (fn [] (extensions/create sync :payload))))
             sync-spies (take n (repeatedly (fn [] (chan 1))))

@@ -155,8 +159,8 @@
         (tap (:offer-mult coordinator) offer-ch-spy)
         (tap (:ack-mult coordinator) ack-ch-spy)

-        (doseq [[peer payload sync-spy] (map vector peers payloads sync-spies)]
-          (extensions/write-place sync peer payload)
+        (doseq [[peer pulse payload sync-spy] (map vector peers pulses payloads sync-spies)]
+          (extensions/write-place sync peer {:pulse pulse :payload payload})
           (extensions/on-change sync payload #(>!! sync-spy %)))

         (doseq [peer peers]


Removed figwheel stuff from example

Removed figwheel stuff from example

--- examples/dropdown/src/core.cljs
+++ examples/dropdown/src/core.cljs
@@ -1,4 +1,4 @@
-(ns ^:figwheel-always examples.dropdown.core
+(ns examples.dropdown.core
   (:require [om.core :as om :include-macros true]
             [om-semantic.dropdown :as dd]
             [om-tools.dom :as dom :include-macros true]))


Add another approach to word-count example in clj

--- assignments/clojure/word-count/example.clj
+++ assignments/clojure/word-count/example.clj
@@ -9,3 +9,15 @@
        (group-by identity)
        (reduce (fn [acc [word occurrences]]
                  (assoc acc word (count occurrences))) {})))
+
+;; Another approach
+(ns phrase
+ (:require [clojure.string :refer [split lower-case]]))
+
+(defn- sanitize-and-split [phrase]
+  (-> (lower-case phrase)
+      (split #"\W+")))
+
+(defn word-count [phrase]
+  (-> (sanitize-and-split phrase)
+      (frequencies)))


Add /multiple-column details test endpoint

--- backend/test/akvo/lumen/endpoints_test.clj
+++ backend/test/akvo/lumen/endpoints_test.clj
@@ -39,7 +39,7 @@
 (defn put* [uri body & args]
   (apply with-body :post uri body args))

-(defn >get* [method uri & [query-params]]
+(defn >get* [method uri [query-params]]
   (cond->
       {:request-method method
        :server-port 3030,
@@ -192,6 +192,15 @@
           (is (= title* (-> (h (get* (api-url "/library")))
                             :body (json/parse-string keyword) :collections first :title)))
           ))
+
+      (testing "/multiple-column"
+        (is (=
+             {:hasImage false, :columns [{:id 1, :name "Alkalinity-m (mg/l)", :type "text"}]}
+             (-> (h (get*  (api-url "/multiple-column")
+                             {"query" (json/encode {:multipleType "caddisfly"
+                                                    :multipleId "85e9bea2-8538-4759-a46a-46459783c2d3"})}))
+                   body-kw))))
+
       (testing "/data-source/job-execution/:id/status/:status"
         (let [dataset-url "https://raw.githubusercontent.com/akvo/akvo-lumen/develop/client/e2e-test/sample-data-1.csv"
               import-id (-> (h (post*  (api-url "/datasets") {:source


delaney.clj: added test for D-symbol completeness

--- clojure/org/gavrog/clojure/delaney.clj
+++ clojure/org/gavrog/clojure/delaney.clj
@@ -93,6 +93,14 @@

 (defn connected? [ds]
   (> 2 (count (orbit-reps ds (indices ds)))))
+
+(defn complete? [ds]
+  (and (every? (comp not nil?)
+               (for [i (indices ds), D (elements ds)]
+                 (s ds i D)))
+       (every? (comp not nil?)
+               (for [i (indices ds), j (indices ds), D (elements ds)]
+                 (v ds i j D)))))

 (defn- protocol [ds indices traversal]
   (let [imap (zipmap indices (range (count indices)))


Can logout a user

Can logout a user

This just sets the user to  nil. We should probably reset the user in
the database as well at some point though

--- idecode/myappshare/mainapp.cljs
+++ idecode/myappshare/mainapp.cljs
@@ -301,7 +301,12 @@

                                    }
                      :onClick     #(do
-                                     (write-ui app [:mode] "login")
+                                     (if (:user @client-session-atom)
+                                       (do
+                                         (swap! client-session-atom assoc :user nil)
+                                         (write-ui app [:mode] "browse")
+                                         )
+                                       (write-ui app [:mode] "login"))
                                      )
                      :disabled  (if (= (read-ui app [:mode]) "login") "true" "")
                      }


(MAINT) Change LinkedBlockingDeque to RegisteredLinkedBlockingDeque

This commit changes one of the unit test references to
LinkedBlockingDeque to RegisteredLinkedBlockingDeque.  This is
necessary for compatibility with the change of the JRubyPuppet queue
structure to the new class type as part of a merge-up PR from stable.

--- test/integration/puppetlabs/services/jruby/class_info_test.clj
+++ test/integration/puppetlabs/services/jruby/class_info_test.clj
@@ -5,7 +5,7 @@
             [puppetlabs.services.jruby.jruby-puppet-internal :as jruby-internal]
             [me.raynes.fs :as fs]
             [cheshire.core :as cheshire])
-  (:import (java.util.concurrent LinkedBlockingDeque)))
+  (:import (com.puppetlabs.puppetserver RegisteredLinkedBlockingDeque)))

 (defn create-file
   [file content]
@@ -70,7 +70,7 @@

 (deftest ^:integration class-info-test
   (testing "class info properly enumerated for"
-    (let [pool (LinkedBlockingDeque. 1)
+    (let [pool (RegisteredLinkedBlockingDeque. 1)
           code-dir (ks/temp-dir)
           conf-dir (ks/temp-dir)
           config (jruby-testutils/jruby-puppet-config


put popNextImage on its own thread

put popNextImage on its own thread

git-svn-id: 03a8048b5ee8463be5048a3801110fb50f378627@10793 d0ab736e-dc22-4aeb-8dc9-08def0aa14fd

--- acqEngine/src/org/micromanager/acq_engine.clj
+++ acqEngine/src/org/micromanager/acq_engine.clj
@@ -382,6 +382,19 @@
     {:pix (.pix tagged-image)
      :tags (json-to-data (.tags tagged-image))}))

+(defn pop-burst-images
+  [n timeout-ms]
+  (let [queue (proxy [LinkedBlockingQueue] []
+                (take [] (let [item (proxy-super take)]
+                           (if (instance? Throwable item)
+                             (throw item)
+                             item))))]
+    (future
+      (dotimes [i n]
+        (try (.put queue (pop-burst-image timeout-ms))
+             (catch Throwable t (.put queue t)))))
+      queue))
+
 (defn make-multicamera-channel [raw-channel-index camera-channel num-camera-channels]
   (+ camera-channel (* num-camera-channels (or raw-channel-index 0))))

@@ -451,10 +464,11 @@
   (let [total (* (count burst-events)
                  (count camera-channel-names))
         camera-index-tag (str (. mmc getCameraDevice) "-CameraChannelIndex")
-        image-number-offset (if (first-trigger-missing?) -1 0)]
+        image-number-offset (if (first-trigger-missing?) -1 0)
+        image-queue (pop-burst-images total timeout-ms)]
     (doseq [_ (range total) :while (not (@state :stop))]
       (.put out-queue
-            (-> (pop-burst-image timeout-ms)
+            (-> (.take image-queue)
                 (tag-burst-image burst-events camera-channel-names camera-index-tag
                                  image-number-offset)
                 make-TaggedImage


fix bug in positions

fix bug in positions

git-svn-id: 03a8048b5ee8463be5048a3801110fb50f378627@7680 d0ab736e-dc22-4aeb-8dc9-08def0aa14fd

--- acqEngine/src/org/micromanager/acq_engine.clj
+++ acqEngine/src/org/micromanager/acq_engine.clj
@@ -449,7 +449,8 @@
       (flatten
         (list
           #(log event)
-          (for [[axis pos] (:axes (MultiStagePosition-to-map current-position)) :when pos]
+          (for [[axis pos] (:axes (MultiStagePosition-to-map (get-msp current-position)))
+                :when pos]
             #(apply set-stage-position axis pos))
           (for [[d p v] (get-in event [:channel :properties])]
             #(set-property [d p v]))
@@ -484,10 +485,11 @@
   (binding [state (.state this)]
     (def last-state state) ; for debugging
     (let [acq-seq (generate-acq-sequence settings @attached-runnables)]
+       (def acq-sequence acq-seq)
       (execute (mapcat #(make-event-fns % out-queue) acq-seq))
       (.put out-queue TaggedImageQueue/POISON)
       (cleanup)
-      (def acq-sequence acq-seq))))
+     )))

 ;; generic metadata


Une 2ème solution à l'exercice Acronym de Exercism dans la track Clojure

--- exercism/clojure/acronym/src/acronym.clj
+++ exercism/clojure/acronym/src/acronym.clj
@@ -4,10 +4,11 @@
 (defn acronym [phrase]
   (if (str/blank? phrase)
     ""
-    (str/join
-     (map #(subs %1 0 1)
-          (flatten
-           (map #(str/split %1 #"[a-z]+")
-                (map #(str/replace %1 #",|:" "")
-                     (map  #(str (str/upper-case (subs %1 0 1)) (subs %1 1))
-                           (str/split phrase #"\s|\-")))))))))
+    (->>
+     (str/split phrase #"\s|\-")
+     (map #(str (str/upper-case (subs %1 0 1)) (subs %1 1)))
+     (map #(str/replace %1 #",|:" ""))
+     (map #(str/split %1 #"[a-z]+"))
+     (flatten)
+     (map #(subs %1 0 1))
+     (str/join))))


Putting chain prefix back down to 2 words.

--- Spraff/src/spraff/core.clj
+++ Spraff/src/spraff/core.clj
@@ -21,7 +21,7 @@
 (def corpus-file "corpus.txt")
 (def word-pattern #"\S+")
 (def generated-sentence-length 10)
-(def prefix-length 3)
+(def prefix-length 2)

 (def table (ref {}))
 (def starters (ref []))


1) removed proxy-switch atom, spin :button-run; 2) refined proxy-settings loading/saving processes;

--- ext/chrome/src/cljs/owl/web/popup.cljs
+++ ext/chrome/src/cljs/owl/web/popup.cljs
@@ -11,7 +11,6 @@
                                                 :rules {}
                                                 :pacScript {}}
                                         :scope "regular"}))
-(defonce ^:export proxy-switch (atom false))
 (defonce ^:export proxy-types {:raw [:auto_detect
                                      :pac_script
                                      :direct
@@ -19,12 +18,24 @@
                                      :system]
                                :run ["pac_script"
                                      "fixed_servers"]})
+(defonce ^:export proxy-ui {:div (by-id "popup")
+                            :button-run (by-id "proxy_run")
+                            :input-uri (by-id "proxy_uri")})
+
 (declare on-proxy-error!)
+
+(defn save-proxy-settings [v]
+  (.setItem js/localStorage :proxy_settings
+            (.stringify js/JSON (clj->js v))))
+
+(defn load-proxy-settings []
+  (js->clj (.parse js/JSON (.getItem js/localStorage :proxy_settings))
+           :keywordize-keys true))

 (defn set-link! [id uri]
   (set-attr! (by-id id) :href (.getURL js/chrome.runtime uri)))

-(defn make-proxy-settings! [uri]
+(defn url-to-proxy-settings! [uri]
   (when-let [u (re-find #"(\w+)://([\w\.]+)(:(\d+))?(/(\w+\.\w+))?" uri)]
     (let [p {:url (first u)
              :scheme (nth u 1)
@@ -42,7 +53,7 @@
                                  {:scheme (:scheme p)
                                   :host (:host p)
                                   :port (js/parseInt (:port p))}}}))]
-      (reset! proxy-settings s))))
+      (reset! proxy-settings (assoc-in s [:scope] "regular")))))

 (defn proxy-settings-to-url [s]
   (when-let [p (:value s)]
@@ -50,58 +61,62 @@
       (case m
         "pac_script" (:url (:pacScript p))
         "fixed_servers" (let [u (:singleProxy (:rules p))]
-                         (str (:scheme u)
-                              (:host u)
+                         (str (:scheme u) "://"
+                              (:host u) ":"
                               (:port u)))
         nil))))

-(defn switch-proxy! []
+(defn set-ui-state! [switch]
+  (let [run (:button-run proxy-ui)
+        url-style (:input-uri proxy-ui)
+        style {:input-background-color (if switch "RoyalBlue" "")
+               :input-font-color (if switch "White" "")
+               :button-text (if switch "Stop" "Run ")}]
+    (set-value! run (:button-text style))
+    (set-style! url-style :background-color (:input-background-color style))
+    (set-style! url-style :color (:input-font-color style))))
+
+(defn set-ui-url! [url]
+  (set-value! (:input-uri proxy-ui) url))
+
+(defn restore-proxy-settings! []
   (let [g (clj->js {:incognito false})]
     (.get js/chrome.proxy.settings
           g (fn [d]
               (let [c (js->clj d :keywordize-keys true)
                     m (:mode (:value c))
-                    b (by-id "proxy_run")
-                    u (by-id "proxy_uri")]
-                (if (some #(= m %) (:run proxy-types))
-                  (do
-                    (reset! proxy-switch true)
-                    (set-value! u (proxy-settings-to-url c))
-                    (set-style! u :background-color "RoyalBlue")
-                    (set-style! u :color "White")
-                    (set-value! b "Stop"))
-                  (do
-                    (reset! proxy-switch false)
-                    (set-value! u (proxy-settings-to-url @proxy-settings))
-                    (set-style! u :background-color "")
-                    (set-style! u :color "")
-                    (set-value! b "Run "))))))))
+                    b (:button-run proxy-ui)
+                    u (:input-uri proxy-ui)
+                    running? (some #(= m %) (:run proxy-types))]
+                (set-ui-state! running?)
+                (set-ui-url! (proxy-settings-to-url
+                              (if running?
+                                c
+                                (load-proxy-settings)))))))))

 (defn apply-proxy-settings! [e]
-  (let [c (make-proxy-settings! (value (by-id "proxy_uri")))
+  (let [c (url-to-proxy-settings! (value (:input-uri proxy-ui)))
         d (clj->js c)]
     (.preventDefault e.evt)
     (.stopPropagation e.evt)
-    (.log js/console d)
-    ;;(.. js/chrome -proxy -onProxyError (addListener on-proxy-error!))
+    (.. js/chrome -proxy -onProxyError (addListener on-proxy-error!))
     (.set js/chrome.proxy.settings
           d (fn [s]
-              (.log js/console (clj->js s))))
+              (.log js/console d)
+              (save-proxy-settings c)))
     (.sendRequest js/chrome.extension {:type "clearError"})))

 (defn clear-proxy-settings! []
   (let [d (clj->js {:scope "regular"})]
-    (.clear js/chrome.proxy.settings d
-            (fn [] (.log js/console "#clear-proxy-settings")))))
+    (.clear js/chrome.proxy.settings
+            d (fn [] (.log js/console "#clear-proxy-settings")))))

 (defn on-proxy-run! [e]
-  (let [s @proxy-switch]
-    (if (true? s)
-      (do
-        (clear-proxy-settings!))
-      (do
-        (apply-proxy-settings! e)))
-    (switch-proxy!)))
+  (let [running? (= "Stop" (value (:button-run proxy-ui)))]
+    (if running?
+      (clear-proxy-settings!)
+      (apply-proxy-settings! e))
+    (set-ui-state! (not running?))))

 (defn on-proxy-error! [e]
   (let [d (js->clj e :keywordize-keys true)]
@@ -111,15 +126,11 @@

 (defn on-doc-ready []
   (when-let [ready-state (.-readyState js/document)]
-    (if (and (= "complete" ready-state)
-             (by-id "popup"))
-      (do
-          (.log js/console "#popup:on-doc-ready")
-          (set-link! "options_link" "resources/public/options.html")
-          (set-link! "echo_link" "resources/public/echo.html")
-          (switch-proxy!)
-          (ev/listen! (by-id "proxy_run") :click on-proxy-run!)
-        true)
-      false)))
+    (when (and (= "complete" ready-state)
+             (:div proxy-ui))
+      (set-link! "options_link" "resources/public/options.html")
+      (set-link! "echo_link" "resources/public/echo.html")
+      (restore-proxy-settings!)
+      (ev/listen! (:button-run proxy-ui) :click on-proxy-run!))))

 (set! (.-onreadystatechange js/document) on-doc-ready)


Fix unexpected exception on path edition.

--- frontend/src/uxbox/main/data/shapes.cljs
+++ frontend/src/uxbox/main/data/shapes.cljs
@@ -504,7 +504,7 @@
 (deftype UpdatePath [id index delta]
   ptk/UpdateEvent
   (update [_ state]
-    (update-in state [:shapes id :points index] gpt/add delta)))
+    (update-in state [:shapes id :segments index] gpt/add delta)))

 (defn update-path
   "Update a concrete point in the path shape."
@@ -516,7 +516,7 @@
   ptk/WatchEvent
   (watch [_ state s]
     (let [shape (get-in state [:shapes id])
-          point (get-in shape [:points index])
+          point (get-in shape [:segments index])
           point (gpt/add point canvas-coords)]
       (->> (uwrk/align-point point)
            (rx/map #(gpt/subtract % point))


normalize sequence conditionals

normalize sequence conditionals

--- sidecar/src/figwheel_sidecar/type_check.clj
+++ sidecar/src/figwheel_sidecar/type_check.clj
@@ -28,6 +28,9 @@
         (set? coll))
     (cons :SEQQ (map vector (range) (map seqify coll)))
     :else coll))
+
+(defn sequence-like? [x]
+  (and (not (map? x)) (coll? x)))

 (defn map?? [x]
   (and (or (seq? x) (vector? x))
@@ -175,8 +178,7 @@
 (defmethod apply-pred := [[_ pred] value] (pred value))
 (defmethod apply-pred :=> [[_ pred] value] (= (cond
                                                 (map? value) :MAPP
-                                                (seq? value) :SEQQ
-                                                (vector? value) :SEQQ
+                                                (sequence-like? value) :SEQQ
                                                 :else :_____BAD)
                                               pred))

@@ -211,7 +213,7 @@
 (declare type-checker)

 (defn fix-key [k parent-value]
-  (if (or (vector? parent-value) (seq? parent-value)) 0 k))
+  (if (sequence-like? parent-value) 0 k))

 (defn find-keyword-predicate [parent-type]
   (when-let [[pred-id _ [pt _ kt]] (first (*schema-rules* [:parent :?- parent-type]))]
@@ -269,8 +271,10 @@
                      (fn [[k v]]
                        (type-check-key-value parent-type k v (assoc state :parent-value value))))]
       (cond
-        (map? value)                      (concat (check-required-keys parent-type value state) (f value))
-        (or (vector? value) (seq? value) (set? value)) (f (map vector (range) value))
+        (map? value)
+        (concat (check-required-keys parent-type value state) (f value))
+        (sequence-like? value)
+        (f (map vector (range) value))
         :else (throw (Exception. (str "Expected compound type: " (class value)
                                       " is not a Map, Vector, or Sequence")))))))


Fix annoying one-pixel misalignment

Fix annoying one-pixel misalignment

--- src-cljs/frontend/components/dashboard.cljs
+++ src-cljs/frontend/components/dashboard.cljs
@@ -34,11 +34,11 @@
                                         [:a {:href (routes/v1-add-projects)} "Manage Projects page"] "?"]]
               :else
               [:div.dashboard
-               [:div.container-fluid
-                [:div.row
-                 [:div.col-xs-12
-                  (when (and plan (project-common/show-trial-notice? project plan))
-                    (om/build project-common/trial-notice current-project))]]]
+               (when (and plan (project-common/show-trial-notice? project plan))
+                 [:div.container-fluid
+                  [:div.row
+                   [:div.col-xs-12
+                    (om/build project-common/trial-notice current-project)]]])

                (when (plan-model/suspended? plan)
                  (om/build project-common/suspended-notice plan))


Cancelling the plan should lead to the new overview.

--- src-cljs/frontend/controllers/controls.cljs
+++ src-cljs/frontend/controllers/controls.cljs
@@ -985,8 +985,7 @@
          (put! errors-ch [:api-error api-result])
          (let [plan-api-result (<! (ajax/managed-ajax :get (gstring/format "/api/v1/organization/%s/plan" org-name)))]
            (put! api-ch [:org-plan (:status plan-api-result) (assoc plan-api-result :context {:org-name org-name})])
-           (put! nav-ch [:navigate! {:path (routes/v1-org-settings-subpage {:org org-name
-                                                                            :subpage "plan"})
+           (put! nav-ch [:navigate! {:path (routes/v1-org-settings {:org org-name})
                                      :replace-token? true}])))
        (release-button! uuid (:status api-result))))))


fundamental.clj: renamed (fundamental-edges) to (inner-edges)

--- clojure/org/gavrog/clojure/fundamental.clj
+++ clojure/org/gavrog/clojure/fundamental.clj
@@ -35,7 +35,8 @@
                              [[[D* r (other i j r)] [E* s n]]
                               [[E* s (other i j s)] [D* r n]]]))))]))

-(defn fundamental-edges [ds]
+(defn inner-edges [ds]
+  "Returns the list of inner edges for a fundamental domain."
   (loop [todo (initial-todo ds)
          [on-bnd opposite :as boundary] (initial-boundary ds)
          result []]


Don't use a redundant file-filter for compressible-files

The messages function already only returns files with the right file
extension (eg. the messages), so we need only filter by the one property
we care about: compressibility.

--- src/com/puppetlabs/puppetdb/command/dlo.clj
+++ src/com/puppetlabs/puppetdb/command/dlo.clj
@@ -143,12 +143,8 @@
   {:pre [(or (string? subdir)
              (instance? java.io.File subdir))]
    :post [(every? (partial instance? java.io.File) %)]}
-  (let [cutoff-time (.getMillis (ago threshold))
-        file-filter #(and
-                       (fs/file? %)
-                       (not= (fs/extension %) ".tgz")
-                       (< (fs/mod-time %) cutoff-time))]
-    (filter file-filter (messages subdir))))
+  (let [cutoff-time (.getMillis (ago threshold))]
+    (filter #(< (fs/mod-time %) cutoff-time) (messages subdir))))

 (defn already-archived?
   "Returns true if this `subdir` of the DLO has already been archived within the


update

update

--- src/main/clj/learnclojure/ch11/optimize.clj
+++ src/main/clj/learnclojure/ch11/optimize.clj
@@ -132,3 +132,25 @@
            data)))
 (time (array-histogram data))
 ;Elapsed time: 23.919621 msecs
+
+;aget和aset也要求数组类型是已知的来避免使用反射
+(let [arr (long-array 10)]
+  (aset arr 0 50)
+  (aget arr 0))
+
+;map和reduce也是可以用于数组的,但会引起对原始类型的自动封装
+;使用loop替代它们,但这样要自己跟踪管理数组的下标,容易出错
+;为此,clojure提供了两个宏amap和areduce用来操作数组同时避免自动封装
+
+(let [a (int-array (range 10))]
+  (vec
+    (amap a i res
+         (inc (aget a i)))))
+;[1 2 3 4 5 6 7 8 9 10]
+;amap的第一个参数时源数组,第二个参数是下标的名称,第三个是结果数组的名称,第四个是一个表达式,它的结果会设置为结果数组的下标i的值
+
+(let [a (int-array (range 10))]
+  (areduce a i sum 0
+        (+ sum (aget a i))))
+;前面两个参数和amap是一样的,第三个参数是累加器的名称,第四个是累加器的初始值,最后是一个表达式,它的值会成为下一次迭代的累加器的值和迭代结束之后的返回结果
+


PDOK-1672 geen errors wanneer geen features in timeline

--- src/main/clojure/pdok/featured/extracts.clj
+++ src/main/clojure/pdok/featured/extracts.clj
@@ -29,14 +29,16 @@

 (defn features-for-extract [dataset feature-type extract-type features templates-dir]
   "Returns the rendered representation of the collection of features for a given feature-type inclusive tiles-set"
-  (let [template (template templates-dir dataset feature-type extract-type)
-        partials (partials templates-dir dataset extract-type)]
-    (if (or (nil? template) (nil? partials))
-      [(str "Template or partials cannot be found for dataset: " dataset
+  (if (empty? features)
+    [nil nil]
+    (let [template (template templates-dir dataset feature-type extract-type)
+          partials (partials templates-dir dataset extract-type)]
+      (if (or (nil? template) (nil? partials))
+        [(str "Template or partials cannot be found for dataset: " dataset
                                                     " feature-type: " feature-type
                                                     " extract-type: " extract-type
                                                     " template-dir: " templates-dir) nil]
-      [nil (map #(vector (:_tiles %) (m/render template % partials) (:_valid_from %) (:_valid_to %)) features)])))
+        [nil (map #(vector (:_tiles %) (m/render template % partials) (:_valid_from %) (:_valid_to %)) features)]))))

 (defn create-extract-collection [db table]
@@ -83,7 +85,9 @@
                                                            features
                                                            "src/main/resources/pdok/featured/templates")]
     (if (nil? error)
-      {:status "ok" :count (add-extract-records config/data-db dataset feature-type extract-type extract-version features-for-extract)}
+      (if (nil? features-for-extract)
+        {:status "ok" :count 0}
+        {:status "ok" :count (add-extract-records config/data-db dataset feature-type extract-type extract-version features-for-extract)})
       {:status "error" :msg error :count 0})))

 (defn file-to-features [path dataset]


[Fix #84] Trim colon from build-id cli option (#85)

So that it won't matter if you specify :dev, ::dev or dev anymore.

--- src/main/shadow/cljs/devtools/cli_opts.cljc
+++ src/main/shadow/cljs/devtools/cli_opts.cljc
@@ -92,7 +92,7 @@
   (if (empty? arguments)
     (assoc result :errors [(str "Action \"" (name action) "\" requires one or more build ids")])
     ;; FIXME: validate build-ids
-    (assoc result :builds (into [] (map keyword) arguments))))
+    (assoc result :builds (into [] (map (comp keyword #(str/replace %1 ":" ""))) arguments))))

 (defn parse-arguments [{:keys [arguments] :as result}]
   (if (empty? arguments)


Tune material-ui comments

Tune material-ui comments

--- examples/material-ui/src/example/core.cljs
+++ examples/material-ui/src/example/core.cljs
@@ -78,13 +78,16 @@
    [:> Autocomplete {:options ["foo" "bar" "foobar"]
                      :style {:width 300}
                      ;; Note that the function parameter is a JS Object!
+                     ;; Autocomplete expects the renderInput value to be function
+                     ;; returning React elements, not a component!
+                     ;; So reactify-component won't work here.
                      :render-input (fn [^js params]
-                                     ;; Don't call js->clj because that would
-                                     ;; recursively convert all JS objects (e.g. React ref objects)
+                                     ;; Don't call js->clj because that would recursively
+                                     ;; convert all JS objects (e.g. React ref objects)
                                      ;; to Cljs maps, which breaks them, even when converted back to JS.
                                      ;; Best thing is to use r/create-element and
-                                     ;; pass the JS params to it. If necessary,
-                                     ;; use JS interop to modify params.
+                                     ;; pass the JS params to it.
+                                     ;; If necessary, use JS interop to modify params.
                                      (set! (.-variant params) "outlined")
                                      (set! (.-label params) "Autocomplete")
                                      (r/create-element mui/TextField params))}]])


Consider empty strings in bio as no values

--- frontend/src/faceboard/helpers/person.cljs
+++ frontend/src/faceboard/helpers/person.cljs
@@ -22,15 +22,15 @@
     (if (empty? sv) nil sv)))

 (defn name [person]
-  (let [source (or (get-in person [:bio :nickname]) (get-in person [:bio :name]))
-        name (str/trim (first-word (str source)))]
-    (sanitize name)))
+  (let [nickname (sanitize (get-in person [:bio :nickname]))
+        name (sanitize (get-in person [:bio :name]))]
+    (str/trim (first-word (or nickname name)))))

 (defn full-name [person]
-  (sanitize (or
-              (get-in person [:bio :full-name])
-              (get-in person [:bio :name])
-              (get-in person [:bio :nickname]))))
+  (or
+    (sanitize (get-in person [:bio :full-name]))
+    (sanitize (get-in person [:bio :name]))
+    (sanitize (get-in person [:bio :nickname]))))

 (defn photo-url [person]
   (or (get-in person [:bio :photo :url] nil) "/images/unknown.jpg"))


Another 404 URL fix for the simple example

--- examples/simple/src/simple/core.cljs
+++ examples/simple/src/simple/core.cljs
@@ -4,7 +4,7 @@
             [clojure.string :as str]))

 ;; A detailed walk-through of this source code is provided in the docs:
-;; https://github.com/day8/re-frame/blob/master/docs/CodeWalkthrough.md
+;; https://day8.github.io/re-frame/dominoes-live/

 ;; -- Domino 1 - Event Dispatch -----------------------------------------------


Don't show sign in & sign up if logged in already

--- src-cljs/frontend/components/header.cljs
+++ src-cljs/frontend/components/header.cljs
@@ -136,17 +136,21 @@
                [:li [:a {:href "/jobs"} "Jobs"]])
              [:li [:a {:href "http://blog.circleci.com"} "Blog"]]]

-            [:form.navbar-right.navbar-form
-             [:button#login.login-link.btn.btn-success {:href (auth-url)
-                                                        :on-click #(raise! owner [:track-external-link-clicked {:path (auth-url) :event "Auth GitHub" :properties {:source "header sign-up" :url js/window.location.pathname}}])
-                                                        :title "Sign up with Github"}
-              "Sign up"]]
-            [:ul.nav.navbar-nav.navbar-right
-             [:li
-              [:a#login.login-link {:href (auth-url)
-                                    :on-click #(raise! owner [:track-external-link-clicked {:path (auth-url) :event "Auth GitHub" :properties {:source "header sign-in" :url js/window.location.pathname}}])
-                                    :title "Sign in with Github"}
-               "Sign in"]]]]]])))))
+            (if logged-in?
+              [:ul.nav.navbar-nav.navbar-right
+               [:li [:a {:href "/"} "Back to app"]]]
+              (list
+                [:form.navbar-right.navbar-form
+                 [:button#login.login-link.btn.btn-success {:href (auth-url)
+                                                            :on-click #(raise! owner [:track-external-link-clicked {:path (auth-url) :event "Auth GitHub" :properties {:source "header sign-up" :url js/window.location.pathname}}])
+                                                            :title "Sign up with Github"}
+                  "Sign up"]]
+                [:ul.nav.navbar-nav.navbar-right
+                 [:li
+                  [:a#login.login-link {:href (auth-url)
+                                        :on-click #(raise! owner [:track-external-link-clicked {:path (auth-url) :event "Auth GitHub" :properties {:source "header sign-in" :url js/window.location.pathname}}])
+                                        :title "Sign in with Github"}
+                   "Sign in"]]]))]]])))))

 (defn inner-header [app owner]
   (reify


removed an unused variable in the header

--- src-cljs/frontend/components/header.cljs
+++ src-cljs/frontend/components/header.cljs
@@ -20,8 +20,6 @@
             [om.core :as om :include-macros true]
             [om.dom :as dom :include-macros true])
   (:require-macros [frontend.utils :refer [html]]))
-
-(def view "home")

 (defn show-follow-project-button? [app]
   (when-let [project (get-in app state/project-path)]


better mousetrap padding on link elements

--- cljs-cheatsheet/cljs_cheatsheet/tooltips.cljs
+++ cljs-cheatsheet/cljs_cheatsheet/tooltips.cljs
@@ -104,6 +104,8 @@
          :x2 (+ tooltip-left tooltip-width tooltip-mouseout-buffer)
          :y1 (- tooltip-top tooltip-mouseout-buffer)
          :y2 (+ tooltip-top tooltip-height tooltip-mouseout-buffer)}})))
+
+(def link-mousetrap-padding 2.5)

 ;; TODO: need to deal with tooltips tooltips at the bottom of the
 ;; page (flip up)
@@ -144,10 +146,10 @@
     ;; link element
     (reset! mousetrap-boxes {
       :link
-        {:x1 (- link-x 2)
-         :x2 (+ link-x link-width 2)
-         :y1 (dec link-y)
-         :y2 (+ link-y link-height 20)} ;; let them mouse down into the tooltip
+        {:x1 (- link-x link-mousetrap-padding)
+         :x2 (+ link-x link-width link-mousetrap-padding)
+         :y1 (- link-y link-mousetrap-padding)
+         :y2 (+ link-y link-height 15)} ;; let them mouse down into the tooltip

       :tooltip
         {:x1 tooltip-left


More options

More options

--- src/angelic/search/action_set/asplan.clj
+++ src/angelic/search/action_set/asplan.clj
@@ -178,7 +178,7 @@
           :naive (make-fire-action (->> effect-var action-var (state/get-var s)))
           :greedy (make-greedy-fire-action s effect-var)
           (:sloppy :extra-sloppy) (make-sloppy-fire-action s effect-var))
-     (-> (env/applicable? s) assert)))
+     #_ (-> (env/applicable? s) assert)))

@@ -202,11 +202,6 @@
           :when (and (= s cur-val) (not (contains? (backward-sets t) s)))]
       t)))

-
-(defn activation-actions  "Return a list of all activation actions for var v"
-  [child-map v]
-  (for [c (child-map v)]
-    (make-set-parent-var-action v c)))

 ;; TODO: generalize to modes other than greedy.
@@ -283,7 +278,7 @@
  ; that has every child of a parent-link in its ancestor-set.
 ; Or, more simply, variables should "die off".
 ;; TODO: generalize.  This is just special case for most logistics.
-(defn dead-end? [s ancestor-map child-map extra-edges]
+(defn uses-dead-vars? [s ancestor-map child-map extra-edges]
 ;  false #_
   (let [gpm      (:precond-map (state/get-var s (action-var sas/goal-var-name)))
         live-set (apply clojure.set/union #{sas/goal-var-name}
@@ -301,14 +296,37 @@
                           c)))))

-;; TODO: remove redundant dead-end check ?
-(defn possible-activation-actions
+(defn activation-actions  "Return a list of all activation actions for var v"
+  [child-map v]
+  (for [c (child-map v)]
+    (make-set-parent-var-action v c)))
+
+(defn add-actions [s v dtgs]
+  (cons (make-freeze-var-action v)
+        (for [as (vals (get-in dtgs [v (state/get-var s v)])), a as]
+          (make-add-action-action a))))
+
+(defn add-directed-actions [s v dtgs cvm acyclic-succ-fn]
+  (let [c-val (state/get-var s v)
+        dtg   (get-in dtgs [v c-val])
+        child (current-child s cvm v)
+        d-val (-> (state/get-var s (action-var child)) :precond-map (util/safe-get v))]
+    ;    (when greedy? #_ (util/assert-is (not (= c-val d-val)) "%s" (def *s* s)))
+    (if (= c-val d-val)
+      [(make-freeze-var-action v)]
+      (for [n-val (acyclic-succ-fn v c-val d-val), a (dtg n-val)]
+        (make-add-action-action a)))))
+
+
+
+(comment ; Dead-end check moved out to init.
+ (defn possible-activation-actions
    "Return a list of possible activation actions for var v possible in state s.
    To be possible parent, must be supported from below. "
    [s ancestor-map child-map v]
-;   (activation-actions child-map v) #_
+                                        ;   (activation-actions child-map v) #_
    (for [c (child-map v) :when (not (or (dead-end? s ancestor-map child-map [[ v c]])))]
-     (make-set-parent-var-action v c)))
+     (make-set-parent-var-action v c))))
 ;   (or (deadlocked? s child-map [[v c]]))

@@ -338,12 +356,12 @@
        Greedy means we forget about reserving preconditions when free and we can fire right now (less branching).
        Sloppy means we ignore if preconditions are free, but require no action on them.
        Extra-sloppy means anything goes -- if you can execute ignoring commitments, go for it."
-  ([sas-problem] (make-asplan-env sas-problem true true :greedy))
-  ([sas-problem check-deadlock? check-components? edge-rule]
-  (assert (contains? #{:naive :greedy :sloppy :extra-sloppy} edge-rule))
+  ([sas-problem & {:keys [directed? greedy? deadlock? dead-vars? components?] :as m
+                   :or   {directed? true greedy? true deadlock? true dead-vars? true components? false}}]
+     (assert (every? #{:directed? :greedy? :deadlock? :dead-vars? :components?} (keys m)))
      (def *add-count* (util/sref 0))
-;  (def *dead-count* (util/sref 0))
-     (let [causal-graph  (remove #(apply = %) (sas-analysis/standard-causal-graph sas-problem))
+     (let [edge-rule     (if greedy? :greedy :naive)
+           causal-graph  (remove #(apply = %) (sas-analysis/standard-causal-graph sas-problem))
            vars          (graphs/ancestor-set causal-graph [sas/goal-var-name])
            causal-graph  (filter (fn [[v1 v2]] (and (vars v1) (vars v2))) causal-graph)
            tsi           (graphs/topological-sort-indices causal-graph)
@@ -355,7 +373,7 @@
            simple-dtgs   (util/map-vals (fn [dtg] (for [[pval emap] dtg, [eval _] emap] [pval eval])) dtgs)
            acyclic-succ-fn (partial possibly-acyclic-successors (HashMap.) simple-dtgs)]
        (assert (graphs/dag? causal-graph))
-                                        ;    (clojure.inspector/inspect-tree child-var-map)
+
        (ASPlanEnv.
         sas-problem
         (expand-initial-state (env/initial-state sas-problem) child-var-map (goal-action dtgs))
@@ -366,46 +384,29 @@
          (for [a (:actions sas-problem)] (make-fire-action a)))

         (fn asplan-actions [s]
-          ;;       (println "\n" s)
-;          (println "\n" s #_(dead-end? s av-map child-var-map []))
-          (when-let [sources (and  (not (dead-end? s av-map child-var-map [])) ;; This is necessary to catch hanging edges, or need other checks.  i.e., look at top-down env.
-                                  (seq (source-vars s child-var-map check-deadlock? check-components? edge-rule)))]
+          (when-let [sources (and (or (not dead-vars?) (not (uses-dead-vars? s av-map child-var-map [])))
+                                  (seq (source-vars s child-var-map deadlock? components? edge-rule)))]
             (let [sources-by-type (group-by #(source-var-type s child-var-map %) sources)]
 ;              (println sources-by-type)
               (util/cond-let [sources]
                 (seq (sources-by-type :fire))
-                [(make-fire-action-type s edge-rule (first sources))]
+                [(make-fire-action-type s  edge-rule (first sources))]

                 (seq (sources-by-type :bottom-up-action))
-                (let [v     (apply min-key tsi sources)
-                      c-val (state/get-var s v)
-                      dtg   (get-in dtgs [v c-val])
-                      child (current-child s child-var-map v)
-                      d-val (-> (state/get-var s (action-var child)) :precond-map (util/safe-get v))]
-                  (when (= edge-rule :greedy)
-                    #_ (util/assert-is (not (= c-val d-val)) "%s" (def *s* s)))
-                  (if (= c-val d-val)
-                    [(make-freeze-var-action v)]
-                    (for [n-val (acyclic-succ-fn v c-val d-val), a (dtg n-val)]
-                      (make-add-action-action a))))
-
+                (if directed?
+                  (add-directed-actions s (apply min-key tsi sources) dtgs child-var-map acyclic-succ-fn)
+                  (add-actions s (apply min-key tsi sources) dtgs))
+
                 (seq (sources-by-type :bottom-up-activate))
-                (possible-activation-actions s av-map child-var-map (apply max-key tsi sources)) ;; TODO: smarter sort!
+                (activation-actions child-var-map (apply max-key tsi sources)) ;; TODO: smarter sort!

                 (seq (sources-by-type :top-down-activate))
-                (let [v (first sources)]
-                  (println "I!" v)
-                  (possible-activation-actions s av-map child-var-map (first sources))) ;; TODO: sort?
+                (do (println "I!") (activation-actions child-var-map (first sources)))

                 (seq (sources-by-type :top-down-action))
-                (let [v (first sources)]
-                  (println "A!" v) ;                         (state/get-var s x) (state/get-var s (parent-var x sas/goal-var-name))
-                  (cons (make-freeze-var-action v)
-                        (for [as (vals (get-in dtgs [v (state/get-var s v)])), a as]
-                          (make-add-action-action a))))
+                (do (println "A!") (add-actions s (first sources) dtgs))

-                :else (assert "Unknown source type!")))
-            #_ (do (util/sref-set! *dead-count* (inc (util/sref-get *dead-count*))) nil)))
+                :else (assert "Unknown source type!")))))
         (env/goal-map sas-problem)
         causal-graph dtgs av-map child-var-map tsi acyclic-succ-fn))))


working on imperfect verbs (currently 79/201 fail rate)

--- src/babel/italiano/morphology/verbs.cljc
+++ src/babel/italiano/morphology/verbs.cljc
@@ -26,7 +26,68 @@
                       (group-by-two (:p x)))))
           patterns))

-(def replace-patterns-future
+(def replace-patterns-imperfect-tense
+  (expand-replace-patterns
+   {:synsem {:infl :imperfect}}
+   [
+    {:agr {:synsem {:subcat {:1 {:agr {:number :sing
+                                       :person :1st}}}}}
+     :p [
+         #"(.*)avo$" "$1are"
+         #"(.*)avo$" "$1arsi"
+         #"(.*)ivo$" "$1ire"
+         #"(.*)ivo$" "$1irsi"
+         ]
+
+     }
+
+    {:agr {:synsem {:subcat {:1 {:agr {:number :sing
+                                       :person :2nd}}}}}
+     :p [
+         #"(.*)avi$" "$1are"
+         #"(.*)avi$" "$1arsi"
+         #"(.*)ivi$" "$1ire"
+         #"(.*)ivi$" "$1irsi"
+         ]
+     }
+
+    {:agr {:synsem {:subcat {:1 {:agr {:number :sing
+                                       :person :3rd}}}}}
+     :p [
+         #"(.*)ava$" "$1are"
+         #"(.*)ava$" "$1arsi"
+         ]
+     }
+
+    {:agr {:synsem {:subcat {:1 {:agr {:number :plur
+                                       :person :1st}}}}}
+     :p [
+         #"(.*)avamo$" "$1are"
+         #"(.*)avamo$" "$1arsi"
+         ]
+
+     }
+
+    {:agr {:synsem {:subcat {:1 {:agr {:number :plur
+                                       :person :2nd}}}}}
+     :p [
+         #"(.*)avate$" "$1are"
+         #"(.*)avate$" "$1arsi"
+         ]
+     }
+
+    {:agr {:synsem {:subcat {:1 {:agr {:number :plur
+                                       :person :3rd}}}}}
+     :p [
+         #"(.*)avano$" "$1are"
+         #"(.*)avano$" "$1arsi"
+         ]
+     }
+
+
+    ]))
+
+(def replace-patterns-future-tense
   (expand-replace-patterns
    {:synsem {:infl :future}}
    [{:agr {:synsem {:subcat {:1 {:agr {:number :sing
@@ -404,7 +465,8 @@
                     {:synsem {:cat :verb}})
           :g (:g each)})
        (concat
-        replace-patterns-future
+        replace-patterns-future-tense
+        replace-patterns-imperfect-tense
         replace-patterns-past-tense
         replace-patterns-present-tense)))


Remove nil results returned from user AI score functions

--- src/clj/zetawar/players/embedded_ai.cljs
+++ src/clj/zetawar/players/embedded_ai.cljs
@@ -59,27 +59,31 @@

 (declare ^:dynamic *actor-score-fn*)

-;; TODO: remove units with nil scores
+;; TODO: cleanup choose-* functions
 (defn choose-actor [db game ctx]
   (let [actor-score (memoize (*actor-score-fn* db game ctx))]
     (->> (game/actionable-actors db game)
-         (apply max-key actor-score))))
+         (keep (juxt identity actor-score))
+         (apply max-key second)
+         first)))

 (declare ^:dynamic *base-action-score-fn*)

-;; TODO: remove actions with nil scores
 (defn choose-base-action [db game ctx base]
   (let [base-action-score (memoize (*base-action-score-fn* db game ctx base))]
     (->> (game/base-actions db game base)
-         (apply max-key base-action-score))))
+         (keep (juxt identity base-action-score))
+         (apply max-key second)
+         first)))

 (declare ^:dynamic *unit-action-score-fn*)

-;; TODO: remove actions with nil scores
 (defn choose-unit-action [db game ctx unit]
   (let [unit-action-score (memoize (*unit-action-score-fn* db game ctx unit))]
     (->> (game/unit-actions db game unit)
-         (apply max-key unit-action-score))))
+         (keep (juxt identity unit-action-score))
+         (apply max-key second)
+         first)))

 (defn choose-action [player db game]
   (let [ctx (*action-ctx* db game)


add filter options to gallery profiles

add filter options to gallery profiles

--- src/cljs/salava/gallery/ui/profiles.cljs
+++ src/cljs/salava/gallery/ui/profiles.cljs
@@ -10,7 +10,8 @@
             [salava.user.ui.helper :refer [profile-picture]]
             [salava.core.i18n :refer [t]]
             [salava.core.ui.modal :as mo]
-            [salava.core.time :refer [date-from-unix-time]]))
+            [salava.core.time :refer [date-from-unix-time]]
+            [salava.core.helper :refer [dump]]))

 (defn ajax-stop [ajax-message-atom]
   (reset! ajax-message-atom nil))
@@ -161,27 +162,30 @@
       [profile-gallery-grid state])]])

 (defn init-data [state]
-  (let [country (session/get-in [:user :country] "all")]
+  (let [country (session/get-in [:user :country] "all")
+        filter-options (session/get :filter-options nil)
+        common-badges? (if filter-options (:common-badges filter-options) true)]
     (ajax/POST
       (path-for (str "/obpv1/gallery/profiles/"))
-      {:params {:country country
+      {:params {:country (session/get-in [:filter-options :country] country)
                 :name ""
-                :common_badges true
+                :common_badges common-badges?
                 :order_by "ctime"}
        :handler (fn [{:keys [users countries]} data]
                   (swap! state assoc :users users
                          :countries countries
-                         :country-selected country))})))
+                         :country-selected (session/get-in [:filter-options :country] country)))})))

 (defn handler [site-navi]
-  (let [state (atom {:users []
+  (let [ filter-options (session/get :filter-options nil)
+         state (atom {:users []
                      :countries []
                      :country-selected "all"
                      :name ""
                      :order_by "ctime"
                      :timer nil
                      :ajax-message nil
-                     :common-badges? true})]
+                     :common-badges? (if filter-options (:common-badges filter-options) true)})]
     (init-data state)
     (fn []
       (layout/default site-navi (content state)))))


Cleaned up bioavailability code.

Cleaned up bioavailability code.

--- src/clojush/examples/bioavailability.clj
+++ src/clojush/examples/bioavailability.clj
@@ -71,7 +71,7 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Define instructions and fitness cases

-;; I want x0 through x240 to be instructions that, when executed, push
+;; x0 through x240 are instructions that, when executed, push
 ;; the float from that column onto the float stack.
 (doseq [[numb symb] (map #(vector % (symbol (str "x" %))) (range 241))]
   (eval `(define-registered ~symb (fn [state#] (push-item (stack-ref :auxiliary ~numb state#) :float state#)))))
@@ -127,6 +127,17 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Main call

+;;;; The parameters used in the paper mentioned at the top are:
+;:population-size 500
+;:max-generations 100
+;:mutation-probability 0.09
+;:crossover-probability 0.81
+;;:replication-rate 0.1 ;implicit
+;:tournament-size 10
+;:node-selection-method :uniform
+;;:max-depth 17 ;tree GP param
+;;:max-dept-of-mutation-code 6 ;tree GP param
+
 (def argmap
   {:error-function (partial bioavailability-error-function :train)
    :atom-generators bioavailability-atom-generators
@@ -138,8 +149,7 @@
    :mutation-probability 0.09
    :crossover-probability 0.81
    :tournament-size 10
-   :node-selection-method :size-tournament
-   :node-selection-tournament-size 2
+   :node-selection-method :uniform
    :report-simplifications 0
    :final-report-simplifications 1000
    :use-rmse true


Some small optimizations for read-wiki

Some small optimizations for read-wiki

Signed-off-by: Daniel Borchmann <25857343a15bf1edafebc2912e82ecf775c585c1@mailbox.tu-dresden.de>

--- src/conexp/contrib/dl/util/read_wiki.clj
+++ src/conexp/contrib/dl/util/read_wiki.clj
@@ -78,8 +78,10 @@
    coll))

 (defn- prepare-for-conexp [hash-map]
-  (into {} (for [[k v] (symbolify hash-map)]
-             [k (set v)])))
+  (reduce! (fn [map [k v]]
+             (assoc! map k (set v)))
+           {}
+           (symbolify hash-map)))

 (defn- role-map->concept-map [role-map]
   (assert (= 1 (count role-map)))
@@ -147,11 +149,11 @@
                               (role-names (interpretation-language interpretation)))),
         base-set (collect (set individuals) relation),

-        name-int (into {} (for [name (concept-names (interpretation-language interpretation))]
-                            [name (intersection base-set (interpret interpretation name))])),
+        name-int (map-by-fn #(intersection base-set (interpret interpretation %))
+                            (concept-names (interpretation-language interpretation))),
         role-int (let [base-square (cross-product base-set base-set)]
-                   (into {} (for [role (role-names (interpretation-language interpretation))]
-                              [role (intersection base-square (interpret interpretation role))])))],
+                   (map-by-fn #(intersection base-square (interpret interpretation %))
+                              (role-names (interpretation-language interpretation))))]
     (make-interpretation (interpretation-language interpretation)
                          base-set
                          (merge name-int role-int))))


Wait up to 5 seconds until region is found to be moved

--- src/main/hbase_region_inspector/core.clj
+++ src/main/hbase_region_inspector/core.clj
@@ -218,7 +218,7 @@
        (hbase/admin-let
          [admin @zookeeper]
          (.move admin (.getBytes region) (.getBytes dest))
-         (loop [tries 10
+         (loop [tries 20
                 message (format "Moving %s from %s to %s" region src dest)]
            (util/info message)
            (when (> tries 0)


filter more network adapters

filter more network adapters

--- src/main/shadow/cljs/devtools/server.clj
+++ src/main/shadow/cljs/devtools/server.clj
@@ -160,6 +160,7 @@
         :let [display-name (.getDisplayName ni)]
         :when
         (and (not (str/includes? display-name "VirtualBox"))
+             (not (str/includes? display-name "vboxnet"))
              (not (str/includes? display-name "utun")))
         addr (enumeration-seq (.getInetAddresses ni))
         ;; probably don't need ipv6 for dev


Use partition-all to get the last partition if it contains fewer elements. Fix logs indentation.

--- src/oc/storage/resources/maintenance.clj
+++ src/oc/storage/resources/maintenance.clj
@@ -37,7 +37,7 @@
    and call the shared-limit-for-entry on all that are exceeding the shared limit."
   [conn :- lib-schema/Conn org-uuid :- lib-schema/UniqueID limit dry-run]
   (let [entries (list-all-entries-by-org! conn org-uuid)]
-    (timbre/info "  Entries count:" (count entries))
+    (timbre/info "    Entries count:" (count entries))
     (for [entry entries]
       (do
         (timbre/info "    Checking entry" (:uuid entry) "shared:" (count (:shared entry)))
@@ -47,7 +47,11 @@
 (defn shared-limit!
   "Given a batch size and offset load the orgs of that batch and run the shared limit,
   use :dry-run option to see the eventual output, to actually update you need to specify
-  :dry-run false."
+  :dry-run false.
+  :batch-length - how many org per batch
+  :batch-offset - the number of the batch: (tot-org / batch-length) * batch-offset
+  :dry-run - do not update, only print
+  :limit - number of shared to keep, default to 50"
   [conn {:keys [batch-length batch-offset limit dry-run]}]
   (let [batch-length (or batch-length 20)
         batch-offset (or batch-offset 0)
@@ -55,16 +59,16 @@
                   true
                   dry-run)
         limit (or limit 50)]
-    (timbre/info "Cut :shared lists for all entries to:" limit "(orgs from " (* batch-length batch-offset) "to" (* batch-length (inc batch-offset)) ")")
+    (timbre/info "Cut :shared lists for all entries to:" limit "(orgs from " (* batch-length batch-offset) "to" (dec (* batch-length (inc batch-offset))) ")")
     (when dry-run
       (timbre/info "---- Dry-run not updating ----"))
     (let [orgs (org-res/list-orgs conn)
           partition-length (min batch-length (count orgs))
-          batches (into [] (partition partition-length orgs))
+          batches (into [] (partition-all partition-length orgs))
           batch (into [] (get batches batch-offset))]
-      (timbre/info "Total orgs:" (count orgs) " batch: " (inc batch-offset) "/" (count batches))
-      (timbre/info "Current batch size:" (count batch))
+      (timbre/info "Total orgs:" (count orgs) " batch: " batch-offset "/" (count batches))
+      (timbre/info " Current batch size:" (count batch))
       (for [org batch]
         (do
-          (timbre/info "Checking:" (:slug org))
+          (timbre/info "  Checking:" (:slug org))
           (shared-limit-for-org! conn (:uuid org) limit dry-run))))))


Set page title on invite teammates page

Set page title on invite teammates page

Also remove a print statement accidentally left in

--- frontend/controllers/navigation.cljs
+++ frontend/controllers/navigation.cljs
@@ -231,12 +231,12 @@
   (let [api-ch (get-in current-state [:comms :api])
         org (:org args)]
     ; get the list of orgs
-    (print "getting orgs")
     (go (let [api-result (<! (ajax/managed-ajax :get "/api/v1/user/organizations"))]
       (put! api-ch [:organizations (:status api-result) api-result])))
     (when org
       (go (let [api-result (<! (ajax/managed-ajax :get (gstring/format "/api/v1/organization/%s/members" org)))]
-            (put! api-ch [:org-member-invite-users (:status api-result) api-result]))))))
+            (put! api-ch [:org-member-invite-users (:status api-result) api-result]))))
+    (set-page-title! "Invite teammates")))

 (defmethod navigated-to :project-settings
   [history-imp navigation-point {:keys [project-name subpage org repo] :as args} state]


:bug: Fix unexpected warning when export empty page.

--- frontend/src/uxbox/main/exports.cljs
+++ frontend/src/uxbox/main/exports.cljs
@@ -9,6 +9,7 @@
   (:require
    [cljsjs.react.dom.server]
    [rumext.alpha :as mf]
+   [uxbox.util.math :as mth]
    [uxbox.main.geom :as geom]
    [uxbox.main.ui.shapes.canvas :as canvas]
    [uxbox.main.ui.shapes.circle :as circle]
@@ -29,9 +30,11 @@
 (defn- calculate-dimensions
   [data]
   (let [shapes (vals (:shapes-by-id data))
-        shape (geom/shapes->rect-shape shapes)]
-    {:width (+ (:x shape) (:width shape) 100)
-     :height (+ (:y shape) (:height shape) 100)}))
+        shape (geom/shapes->rect-shape shapes)
+        width (+ (:x shape) (:width shape) 100)
+        height (+ (:y shape) (:height shape) 100)]
+    {:width (if (mth/nan? width) 100 width)
+     :height (if (mth/nan? height) 100 height)}))

 (mf/defc shape-wrapper
   [{:keys [shape] :as props}]
@@ -52,7 +55,7 @@
         shapes (map #(get shapes-by-id %) (:shapes data []))
         canvas (map #(get shapes-by-id %) (:canvas data []))
         dim (calculate-dimensions data)]
-    [:svg {:view-box (str "0 0 " (:width dim) " " (:height dim))
+    [:svg {:view-box (str "0 0 " (:width dim 0) " " (:height dim 0))
            :version "1.1"
            :xmlnsXlink "http://www.w3.org/1999/xlink"
            :xmlns "http://www.w3.org/2000/svg"}


Add Q-Spot 160.

Add Q-Spot 160.

--- src/afterglow/fixtures/chauvet.clj
+++ src/afterglow/fixtures/chauvet.clj
@@ -132,7 +132,7 @@
                              (chan/functions :control-functions 10
                                              0 nil
                                              8 "Blackout while moving Pan/Tilt"
-                                             28 "Blackout while moving Gobo Gheel"
+                                             28 "Blackout while moving Gobo Wheel"
                                              48 "Disable blackout while Pan/Tilt / moving Gobo Wheel"
                                              68 "Blackout while moving Color Wheel"
                                              88 "Disable blackout while Pan/Tilt / moving Color Wheel"
@@ -395,3 +395,109 @@
                                    (chan/color 6 :uv :label "UV" :hue (when mix-uv 270))]})
           :name "Chauvet SlimPAR Hex 3 IRC"
           :mode mode)))
+
+(defn q-spot-160
+  "Q Spot 160 moving yoke.
+
+  This fixture can be configured to use either 9 or 12 DMX channels.
+  If you do not specify a mode when patching it, `:12-channel` is
+  assumed; you can pass a value of `:9-channel` for `mode` if you are
+  using it that way."
+  {:doc/format :markdown}
+  ([]
+   (q-spot-160 :12-channel))
+  ([mode]
+   (let [build-color-wheel (fn [channel]
+                             (chan/functions :color channel
+                                             0 "Color Wheel Open"
+                                             (range 15 59 15) (chan/color-wheel-hue ["red" "yellow" "green"])
+                                             60 "Color Wheel pink"
+                                             (range 75 119 15) (chan/color-wheel-hue ["blue" "orange" "magenta"])
+                                             120 "Color Wheel Light Blue"
+                                             135 "Color Wheel Light Green"
+                                             150 {:type :color-clockwise
+                                                  :label "Color Wheel Clockwise (slow->fast)"
+                                                  :var-label "CW (slow->fast)"
+                                                  :range :variable}))
+         build-shutter (fn [channel]
+                         (chan/functions :shutter channel
+                                         0 "Shutter Closed"
+                                         32 "Shutter Open"
+                                         64 :strobe
+                                         96 "Shutter Open 2"
+                                         128 :pulse-strobe
+                                         160 "Shutter Open 3"
+                                         192 :random-strobe
+                                         224 "Shutter Open 4"))
+         gobo-names ["Splat" "Spot Sphere" "Fanned Squares" "Box" "Bar" "Blue Starburst" "Perforated Pink"]
+         build-gobo-entries (fn [shake? names]
+                              (map (fn [entry]
+                                     (let [label (str "Gobo " entry (when shake? " shake"))
+                                           type-key (keyword (sanitize-name label))]
+                                       (merge {:type type-key
+                                               :label label
+                                               :range (if shake? :variable :fixed)}
+                                              (when shake? {:var-label "Shake Speed"}))))
+                                   names))
+         build-gobo-wheel (fn [channel]
+                            (chan/functions :gobo channel
+                                            (range 0 79 10) (build-gobo-entries false (concat ["Open"] gobo-names))
+                                            (range 80 219 20) (build-gobo-entries true (reverse gobo-names))
+                                            220 {:type :gobo-scroll
+                                                 :label "Gobo Scroll"
+                                                 :var-label "Scroll Speed"
+                                                 :range :variable}))
+         build-gobo-rotation (fn [channel]
+                               (chan/functions :gobo-rotation channel
+                                               0 nil
+                                               3 {:type :gobo-rotation-clockwise
+                                                  :label "Gobo Rotation Clockwise (slow->fast)"
+                                                  :var-label "CW (slow->fast)"
+                                                  :range :variable}
+                              129 "gobo-rotation-stop"
+                              133 {:type :gobo-rotation-counterclockwise
+                                   :label "Gobo Rotation Counterlockwise (slow->fast)"
+                                   :var-label "CCW (slow->fast)"
+                                   :range :variable}))
+         build-control-channel (fn [channel]
+                                 (chan/functions :control channel
+                                             0 nil
+                                             20 "Blackout while moving Pan/Tilt"
+                                             40 "Disable Blackout while moving Pan/Tilt"
+                                             60 "Auto 1"
+                                             80 "Auto 2"
+                                             100 "Sound Active 1"
+                                             120 "Sound Active 2"
+                                             140 "Custom"
+                                             160 "Test"
+                                             180 nil
+                                             200 "Reset"
+                                             220 nil))]
+        (merge {:name "Q Spot 160"
+                :pan-center 128 :pan-half-circle 128 ; TODO: Fix these values
+                :tilt-center 128 :tilt-half-circle 128 ; TODO: Fix these values
+                :mode mode}
+               (case mode
+                 :12-channel
+                 {:channels [(chan/pan 1 2)
+                             (chan/tilt 3 4)
+                             (chan/fine-channel :pan-tilt-speed 5
+                                                :function-name "Pan / Tilt Speed"
+                                                :var-label "P/T fast->slow")
+                             (build-color-wheel 6)
+                             (build-gobo-wheel 7)
+                             (build-gobo-rotation 8)
+                             (chan/functions :prism 9 0 "Prism Out" 128 "Prism In")
+                             (chan/dimmer 10)
+                             (build-shutter 11)
+                             (build-control-channel 12)]}
+                 :9-channel
+                 {:channels [(chan/pan 1)
+                             (chan/tilt 2)
+                             (build-color-wheel 3)
+                             (build-gobo-wheel 4)
+                             (build-gobo-rotation 5)
+                             (chan/functions :prism 6 0 "Prism Out" 128 "Prism In")
+                             (chan/dimmer 7)
+                             (build-shutter 8)
+                             (build-control-channel 9)]})))))


~(defn fo) cleanup

~(defn fo) cleanup

--- src/babel/italiano/morphology.cljc
+++ src/babel/italiano/morphology.cljc
@@ -446,35 +446,7 @@
        :b (if (nil? b) :top b)})))

 (defn fo [input]
-  (cond
-
-   (= input :fail)
-   (str input)
-
-   (string? input)
-   input
-
-   (:italiano input)
-   ;; get-string should always return a string, but sometimes it (incorrectly) does not (FIXME)
-   (string/trim (str (get-string (get-in input [:italiano]))))
-
-   (and (map? input)
-        (get-in input [:a])
-        (get-in input [:b]))
-   (str (string/join " "
-                     (list (fo (get-in input [:a]))
-                           (get-in input [:punctuation :middle])
-                           (fo (get-in input [:b])))))
-
-   (or (seq? input)
-       (vector? input))
-   (str "(" (string/join " , "
-                         (remove #(= % "")
-                                 (map #(let [f (fo %)] (if (= f "") "" (str "" f ""))) input)))
-        ")")
-
-   true
-   ""))
+  (get-string (get-in input [:italiano])))

 (defonce ppa-tokens-to-surface
   (map (fn [pair]


don't use boot-stem, if any, to conjugate participle

--- src/babel/italiano/morphology.cljc
+++ src/babel/italiano/morphology.cljc
@@ -216,6 +216,12 @@
                    (get-in word [:boot-stem1])
                    true
                    (string/replace infinitive #"[iae]re$" ""))
+
+        ;; stem2 is stem without regard to :boot-stem1. It is
+        ;; used for gerunds, e.g.: fornire -> 'io fornisco'
+        ;; but 'io fornendo', not 'io forniscendo'.
+        stem2 (string/replace infinitive #"[iae]re$" "")
+
         last-stem-char-is-i (re-find #"i[iae]re$" infinitive)
         last-stem-char-is-e (re-find #"e[iae]re$" infinitive)
         is-care-or-gare? (re-find #"[cg]are$" infinitive)
@@ -226,6 +232,7 @@
      :ere-type ere-type
      :ire-type ire-type
      :stem stem
+     :stem2 stem2
      :last-stem-char-is-i last-stem-char-is-i
      :last-stem-char-is-e last-stem-char-is-e
      :is-care-or-gare? is-care-or-gare?
@@ -902,7 +909,7 @@
       (string? (get-in word [:italiano])))
      (let [stem-analysis (stem-analysis word)
            infinitive (:infinitive stem-analysis)
-           stem (:stem stem-analysis)]
+           stem (:stem2 stem-analysis)]
         (log/debug (str "conjugating present participle; analysis:" stem-analysis))
         (cond (= "are" (:are-type stem-analysis))
               (str stem "ando")


Fix missing login-state case on mobile-client

--- src/braid/client/mobile/views.cljs
+++ src/braid/client/mobile/views.cljs
@@ -111,5 +111,8 @@
          [auth-flow-view]

          :app
-         [main-view])])))
+         [main-view]

+         :init
+         [:div.status])])))
+


check new bot creation client-side too

check new bot creation client-side too

--- src/braid/ui/views/pages/bots.cljs
+++ src/braid/ui/views/pages/bots.cljs
@@ -1,9 +1,11 @@
 (ns braid.ui.views.pages.bots
   (:require [reagent.core :as r]
+            [reagent.ratom :refer-macros [reaction]]
             [chat.client.reagent-adapter :refer [subscribe]]
             [braid.ui.views.pills :refer [user-pill-view]]
             [chat.client.dispatcher :refer [dispatch!]]
-            [braid.ui.views.upload :refer [avatar-upload-view]]))
+            [braid.ui.views.upload :refer [avatar-upload-view]]
+            [chat.shared.util :refer [bot-name-re]]))

 (defn bot-view
   [bot]
@@ -52,7 +54,13 @@
         dragging? (r/atom false)
         error (r/atom nil)
         new-bot (r/atom {})
-        state (r/atom :initial)]
+        state (r/atom :initial)
+        bot-valid? (reaction (and
+                               (and (string? (@new-bot :name))
+                                 (re-matches bot-name-re (@new-bot :name)))
+                               (and (string? (@new-bot :webhook-url))
+                                 (re-matches #"\S+" (@new-bot :webhook-url)))
+                               (some? (@new-bot :avatar))))]
     (fn []
       (when @admin?
         [:div.add-bot
@@ -66,20 +74,21 @@
            [:form.new-bot-form
             {:action "/"
              :on-submit (fn [e] (.preventDefault e)
-                          (reset! error nil)
-                          (reset! state :creating)
-                          (swap! new-bot assoc :group-id @group-id)
-                          (dispatch! :new-bot
-                                     {:bot @new-bot
-                                      :on-complete
-                                      (fn [created]
-                                        (if created
-                                          (do (reset! new-bot created)
-                                              (reset! state :created))
-                                          (do
-                                            (reset! error "Failed to create bot")
-                                            (reset! state :initial))))})
-                          (reset! state :creating))}
+                          (when @bot-valid?
+                            (reset! error nil)
+                            (reset! state :creating)
+                            (swap! new-bot assoc :group-id @group-id)
+                            (dispatch! :new-bot
+                                       {:bot @new-bot
+                                        :on-complete
+                                        (fn [created]
+                                          (if created
+                                            (do (reset! new-bot created)
+                                                (reset! state :created))
+                                            (do
+                                              (reset! error "Failed to create bot")
+                                              (reset! state :initial))))})
+                            (reset! state :creating)))}
             (when-let [err @error]
               [:div.error err])
             [:label "Bot Name"
@@ -95,7 +104,7 @@
                [:img {:src avatar}])
              [avatar-upload-view {:on-upload (fn [url] (swap! new-bot assoc :avatar url))
                                   :dragging-change (partial reset! dragging?)}]]
-            [:input {:type "submit" :value "Add Bot"}]]
+            [:input {:type "submit" :value "Add Bot" :disabled (not @bot-valid?)}]]

            :created
            [:div


replaces routes current group helper with open group id deref

--- src/braid/ui/views/search_bar.cljs
+++ src/braid/ui/views/search_bar.cljs
@@ -23,9 +23,9 @@
                 (store/set-search-results! {})
                 (if (string/blank? query)
                   (do
-                    (routes/go-to! (routes/inbox-page-path {:group-id (routes/current-group)})))
+                    (routes/go-to! (routes/inbox-page-path {:group-id @open-group-id})))
                   (do
-                    (routes/go-to! (routes/search-page-path {:group-id (routes/current-group)
+                    (routes/go-to! (routes/search-page-path {:group-id @open-group-id
                                                              :query query}))
                     (dispatch! :search-history [query @open-group-id]))))))))
        :reagent-render


API consistency ftw

API consistency ftw

--- src/caesium/crypto/generichash.clj
+++ src/caesium/crypto/generichash.clj
@@ -29,7 +29,8 @@
   ([buf msg {:keys [key]
              :or {key (byte-array 0)}}]
    (.crypto_generichash
-    sodium buf (buflen buf) msg (buflen msg) key (buflen key))))
+    sodium buf (buflen buf) msg (buflen msg) key (buflen key))
+   buf))

 (defn hash
   "A friendlier API for generichash.
@@ -42,8 +43,7 @@
                 :or {size bytes}
                 :as opts}]
    (let [buf (byte-array size)]
-     (hash-to-buf! buf msg opts)
-     buf)))
+     (hash-to-buf! buf msg opts))))

 (defn blake2b-to-buf!
   ([buf msg]


motion file params now are changed

motion file params now are changed

--- src/cap_and_send/webcam/motion.clj
+++ src/cap_and_send/webcam/motion.clj
@@ -14,18 +14,28 @@
   newfile)

 (defn- alter-conf [file motion-dir device]
-  ())
+  (try
+    (let [out1 (sh "sed" "-i" "-e" (str "s#motion-dir#" motion-dir "#g") file)
+          out2 (sh "sed" "-i" "-e" (str "s#/dev/video0#" device "#g") file)]
+      (if-not (and (= (:exit out1) 0) (= (:exit out2) 0))
+        (println "ERROR sed did not alter motion config file: " out1 "\n" out2)))
+    (catch Throwable t
+      (println "ERROR could not alter motion config file " t))))

 (defn- do-motion-conf [config-dest motion-dir device] ""
+  (println "INFO making motion config file: " config-dest
+           "\n with params: motion-dir: " motion-dir "\n device: " device)
   (copy-conf-to-new config-dest)
-  (alter-conf config-dest motion-dir device))
+  (alter-conf config-dest motion-dir device)
+  config-dest)

 (defn- do-motion [motion-dir device] ""
   (println "INFO running motion with output dir: " motion-dir " and device: " device)
-  ;TODO actually use motion-dir and device
-  (let [in ["motion" "-n" "-c" "resources/motion.conf"]]
+  (let [conf-to-use "resources/motion-0.conf"
+        in ["motion" "-n" "-c" "resources/motion.conf"]]
     (try
       (println "INFO motion sh input: " in)
+      (do-motion-conf conf-to-use motion-dir device)
       (apply sh in)
       (catch Throwable t
         (println "ERROR motion error: " (:cause (Throwable->map t)))))))


remove :unified-mode option

remove :unified-mode option

--- resources/leiningen/new/tenzing/build.boot
+++ resources/leiningen/new/tenzing/build.boot
@@ -32,7 +32,6 @@

 (deftask development []
   (task-options! cljs {:optimizations :none
-                       :unified-mode true
                        :compiler-options {:asset-path "js/app.out"}
                        :source-map true}
                  reload {:on-jsload '{{name}}.app/init}{{{development-task-opts}}})


added POST & PUT content type

added POST & PUT content type

--- src/clj/swarmpit/docker/client.clj
+++ src/clj/swarmpit/docker/client.clj
@@ -85,12 +85,16 @@
   ([uri params headers] (execute "GET" uri params headers nil)))

 (defn- post
-  ([uri payload] (execute "POST" uri nil nil payload))
-  ([uri params payload] (execute "POST" uri params nil payload)))
+  ([uri payload] (post uri nil nil payload))
+  ([uri params payload] (post uri params nil payload))
+  ([uri params headers payload]
+   (execute "POST" uri params (merge headers {:Content-Type "application/json"}) payload)))

 (defn- put
-  ([uri payload] (execute "PUT" uri nil nil payload))
-  ([uri payload headers] (execute "PUT" uri nil headers payload)))
+  ([uri payload] (put uri nil nil payload))
+  ([uri headers payload] (put uri nil headers payload))
+  ([uri params headers payload]
+   (execute "PUT" uri params (merge headers {:Content-Type "application/json"}) payload)))

 (defn- delete
   ([uri] (execute "DELETE" uri nil nil nil))


fix image alignment

fix image alignment

--- src/cljs/salava/badge/ui/info.cljs
+++ src/cljs/salava/badge/ui/info.cljs
@@ -173,7 +173,7 @@
            (admintool id "badge")))

        (if (or verified_by_obf issued_by_obf)
-         (bh/issued-by-obf obf_url verified_by_obf issued_by_obf))
+         [:div.row (bh/issued-by-obf obf_url verified_by_obf issued_by_obf)])
        [:div {:class "row flip"}
         [:div {:id "pull-right" :class "col-md-3 badge-image"}
          [:div.row


refactored the timer code some more

refactored the timer code some more

--- src/clojure/com/gt/metime/main.clj
+++ src/clojure/com/gt/metime/main.clj
@@ -34,15 +34,16 @@
 (defrecord TimerContext [running offset base])

 (defn start-timer [event-chonometer event-button-view timer-context]
+  (config event-button-view :text "Start")
   (.stop event-chonometer)
-  (config event-button-view :text "Start")
-  (reset! timer-context (apply ->TimerContext [false (- (.getBase event-chonometer) (SystemClock/elapsedRealtime)) (.getBase event-chonometer)]))
+  (if (:running @timer-context) (reset! timer-context (apply ->TimerContext [false (- (.getBase event-chonometer) (SystemClock/elapsedRealtime)) (.getBase event-chonometer)])) ())
   (config event-button-view :on-click (fn [_] (stop-timer event-chonometer event-button-view timer-context))))

 (defn stop-timer [event-chonometer event-button-view timer-context]
-  (reset! timer-context (apply ->TimerContext [true (:offset @timer-context)  (+ (SystemClock/elapsedRealtime) (:offset @timer-context))]))
+  (config event-button-view :text "Stop")
+  (if (:running @timer-context) () (reset! timer-context (apply ->TimerContext [true (:offset @timer-context)  (+ (SystemClock/elapsedRealtime) (:offset @timer-context))])))
   (.setBase event-chonometer (:base @timer-context))
-  (config event-button-view :text "Stop")
+
   (.start event-chonometer)
   (config event-button-view :on-click (fn [_] (start-timer event-chonometer event-button-view timer-context))))

@@ -86,23 +87,9 @@
         (config date-text-view :text (stored-to-readable-date (str (:date task))))

         (.stop event-chonometer)
-
-        (if
-          (:running @timer-context)
-          ((fn []
-             (reset! timer-context (apply ->TimerContext [true (:offset @timer-context) (:base @timer-context)]))
-             (.setBase event-chonometer (:base @timer-context))
-             (.start event-chonometer)
-             (config event-button-view :text "Stop")
-
-             (config event-button-view :on-click (fn [_] (start-timer event-chonometer event-button-view timer-context)))
-             ))
-          ((fn []
-             (config event-chonometer :text (millis-to-format-time (* (:offset @timer-context) -1)))
-             (config event-button-view :text "Start")
-
-             (config event-button-view :on-click (fn [_] (stop-timer event-chonometer event-button-view timer-context)))
-             )))
+        (config event-chonometer :text (millis-to-format-time (* (:offset @timer-context) -1)))
+
+        ((if (:running @timer-context) stop-timer start-timer) event-chonometer event-button-view timer-context)

         (config event-text-view :text (str (:name task) " (Goal: " (millis-to-format-time (* 1000 60 (:duration task))) ") "))


instance caching feature

instance caching feature

--- src/clojure/zensols/dataset/db.clj
+++ src/clojure/zensols/dataset/db.clj
@@ -81,7 +81,10 @@
         call [[divide-by-preset]] for the first invocation of [[instances-load]]

   * **:url** the URL to the DB (defaults to `http://localhost:9200`)
-  * **mapping-type** map type name (see ES docs)
+  * **:mapping-type** map type name (see ES docs)
+  * **:cache-inst** an atom used to cache instances by ID; if given this
+    retrieves instances from the in memory map stored in the atom; otherwise it
+    goes to ElasticSearch each time

 Example
 -------
@@ -94,7 +97,8 @@
     (elasticsearch-connection \"tmp\" :create-instances-fn load-fn)))
 ```"
   [index-name &
-   {:keys [create-instances-fn population-use set-type url mapping-type-def]
+   {:keys [create-instances-fn population-use set-type url mapping-type-def
+           cache-inst]
     :or {create-instances-fn identity
          population-use 1.0
          set-type :train
@@ -104,6 +108,7 @@
          url "http://localhost:9200"}}]
   {:index-name index-name
    :ids-inst (atom nil)
+   :cache-inst cache-inst
    :default-set-type (atom set-type)
    :population-use (atom population-use)
    :instance-context (es/create-context
@@ -143,6 +148,7 @@
   `(let [conn# (connection)
          ~'index-name (:index-name conn#)
          ~'ids-inst (:ids-inst conn#)
+         ~'cache-inst (:cache-inst conn#)
          ~'instance-context (:instance-context conn#)
          ~'stats-context (:stats-context conn#)
          ~'population-use (:population-use conn#)
@@ -195,7 +201,14 @@
   ([id]
    (use-connection
      (with-context [instance-context]
-       (->> (es/document-by-id id))))))
+       (if cache-inst
+         (letfn [(sfn [data]
+                   (if-not (contains? data id)
+                     (assoc data id (es/document-by-id id))
+                     data))]
+           (swap! cache-inst sfn)
+           (get @cache-inst id))
+         (es/document-by-id id))))))

 (defn clear
   "Clear the in memory instance data.  If key `:wipe-persistent?` is `true` all


Minor refactoring.

Minor refactoring.

--- src/cmr/indexer/data/index_set.clj
+++ src/cmr/indexer/data/index_set.clj
@@ -297,17 +297,17 @@
      (get-concept-index-name context concept-id revision-id concept)))
   ([context concept-id revision-id concept]
    (let [concept-type (cs/concept-id->type concept-id)
-         indexes ((get-concept-type-index-names context) concept-type)]
+         indexes (get (get-concept-type-index-names context) concept-type)]
      (if (= :collection concept-type)
-       (indexes :collections)
+       (get indexes :collections)
        (let [coll-concept-id (:parent-collection-id (:extra-fields concept))]
-         (get indexes (keyword coll-concept-id) (:small_collections indexes)))))))
+         (get indexes (keyword coll-concept-id) (get indexes :small_collections)))))))

 (defn get-index-name-for-granule-delete
   "Return the concept index name for granule delete based on the input collection concept id"
   [context coll-concept-id]
-  (let [indexes ((get-concept-type-index-names context) :granule)]
-    (get indexes (keyword coll-concept-id) (:small_collections indexes))))
+  (let [indexes (get (get-concept-type-index-names context) :granule)]
+    (get indexes (keyword coll-concept-id) (get indexes :small_collections))))

 (defn get-concept-mapping-types
   "Fetch mapping types associated with concepts."


Add Insights Dashboard Feature Flag

Add Insights Dashboard Feature Flag

--- src-cljs/frontend/components/insights.cljs
+++ src-cljs/frontend/components/insights.cljs
@@ -13,6 +13,7 @@
             [frontend.models.project :as project-model]
             [frontend.models.repo :as repo-model]
             [frontend.models.user :as user-model]
+            [frontend.models.feature :as feature]
             [frontend.state :as state]
             [frontend.utils :as utils :refer-macros [inspect] :refer [unexterned-prop]]
             [frontend.utils.github :as gh-utils]
@@ -266,9 +267,11 @@
             (om/build svg {:class "badge-icon"
                            :src (-> latest-build build/status-icon common/icon-path)})]
            [:span.project-name
+            (if (feature/enabled? :insights-dashboard)
             [:a {:href (routes/v1-insights-dashboard {:org (:username project)
                                                       :repo (:reponame project)})}
-             (formatted-project-name project)]]
+             (formatted-project-name project)]
+             (formatted-project-name project))]
            [:div.github-icon
             [:a {:href (:vcs_url project)}
              [:i.octicon.octicon-mark-github]]]


use a transform for the progress bar

use a transform for the progress bar

--- src-cljs/frontend/components/progress.cljs
+++ src-cljs/frontend/components/progress.cljs
@@ -8,13 +8,18 @@

 (defn progress-bar [app owner]
   (reify
+    om/IDisplayName
+    (display-name [_] "Progress Bar")
     om/IRender
     (render [_]
       (let [progress (cursors/observe-progress owner)]
         (html
          [:div.progress-bar {:class (when (:active progress) "active")}
-          [:div.progress {:style {:width (if (:active progress)
-                                           (str (:percent progress) "%")
-                                           "100%")
+          [:div.progress {:style {:width "100%"
+                                  :transform (str "translate("
+                                                  (if (:active progress)
+                                                    (str (- (:percent progress) 100) "%")
+                                                    0)
+                                                  ")")
                                   :transition-duration (str (+ 16 (:expected-tick-duration progress 0))
                                                             "ms")}}]])))))


Utility functions

Utility functions

--- src/doctopus/doctopus/tentacle.clj
+++ src/doctopus/doctopus/tentacle.clj
@@ -15,11 +15,35 @@

 ;; TENTACLES
 (defprotocol TentacleMethods
-  (load-html [this])
+  (load-html [this] "Makes sure the HTML has been generated for this tentacle")
   (generate-html [this])
   (save-build-output [this dir])
   (get-html-entrypoint [this])
   (routes [this]))
+
+;; #### "Try, report, return"-ing
+;; I've found myself doing a lot of this:
+;; (if (do-a-thing-that-returns-something-or-nil)
+;;     (do (log the result) true)
+;;     (do (log the failure) nil))
+
+(defn report-success
+  [msg]
+  (log/info msg)
+  true)
+
+(defn report-error
+  [msg]
+  (log/error msg)
+  nil)
+
+(defn check-and-report
+  [result noun success-msg fail-msg]
+  (let [success-tpl "Success: %s for %s"
+        error-tpl   "Couldn't %s for %s"]
+    (if result
+      (report-success (format success-tpl noun success-msg))
+      (report-error (format error-tpl noun fail-msg)))))

 (defrecord Tentacle
     [name html-command html-args output-root source-location entry-point]