Fix and simplify round robin multi job test

--- test/onyx/log/round_robin_multi_job_test.clj
+++ test/onyx/log/round_robin_multi_job_test.clj
@@ -2,6 +2,7 @@
   (:require [clojure.core.async :refer [chan >!! <!! close! sliding-buffer]]
             [midje.sweet :refer :all]
             [onyx.peer.task-lifecycle-extensions :as l-ext]
+            [onyx.log.helper :refer [playback-log]]
             [onyx.plugin.core-async :refer [take-segments!]]
             [onyx.extensions :as extensions]
             [onyx.api]))
@@ -18,6 +19,8 @@
          :onyx.peer/job-scheduler :onyx.job-scheduler/round-robin))

 (def env (onyx.api/start-env env-config))
+
+(def peer-group (onyx.api/start-peer-group peer-config))

 (def catalog-1
   [{:onyx/name :a
@@ -86,10 +89,10 @@

 (def j1
   (onyx.api/submit-job
-   peer-config
-   {:workflow [[:a :b] [:b :c]]
-    :catalog catalog-1
-    :task-scheduler :onyx.task-scheduler/round-robin}))
+    peer-config
+    {:workflow [[:a :b] [:b :c]]
+     :catalog catalog-1
+     :task-scheduler :onyx.task-scheduler/round-robin}))

 (def j2
   (onyx.api/submit-job
@@ -100,55 +103,42 @@

 (def n-peers 36)

-(def v-peers (onyx.api/start-peers n-peers peer-config))
+(def v-peers (onyx.api/start-peers n-peers peer-group))

-(def ch (chan n-peers))
+(def ch (chan 10000))
+
+(defn get-counts [replica]
+  (let [task-a (nth (get-in replica [:tasks j1]) 0)
+        task-b (nth (get-in replica [:tasks j1]) 1)
+        task-c (nth (get-in replica [:tasks j1]) 2)
+        task-d (nth (get-in replica [:tasks j2]) 0)
+        task-e (nth (get-in replica [:tasks j2]) 1)
+        task-f (nth (get-in replica [:tasks j2]) 2)
+        task-a-count (count (get (get (:allocations replica) j1) task-a))
+        task-b-count (count (get (get (:allocations replica) j1) task-b))
+        task-c-count (count (get (get (:allocations replica) j1) task-c))
+        task-d-count (count (get (get (:allocations replica) j2) task-d))
+        task-e-count (count (get (get (:allocations replica) j2) task-e))
+        task-f-count (count (get (get (:allocations replica) j2) task-f))]
+    [task-a-count task-b-count task-c-count task-d-count task-e-count task-f-count]))

 (def replica-1
-  (loop [replica (extensions/subscribe-to-log (:log env) ch)]
-    (let [position (<!! ch)
-          entry (extensions/read-log-entry (:log env) position)
-          new-replica (extensions/apply-log-entry entry replica)
-          task-a (nth (get-in new-replica [:tasks j1]) 0)
-          task-b (nth (get-in new-replica [:tasks j1]) 1)
-          task-c (nth (get-in new-replica [:tasks j1]) 2)
-          task-d (nth (get-in new-replica [:tasks j2]) 0)
-          task-e (nth (get-in new-replica [:tasks j2]) 1)
-          task-f (nth (get-in new-replica [:tasks j2]) 2)]
-      (if-not (and (= (count (get (get (:allocations new-replica) j1) task-a)) 6)
-                   (= (count (get (get (:allocations new-replica) j1) task-b)) 6)
-                   (= (count (get (get (:allocations new-replica) j1) task-c)) 6)
-                   (= (count (get (get (:allocations new-replica) j2) task-d)) 6)
-                   (= (count (get (get (:allocations new-replica) j2) task-e)) 6)
-                   (= (count (get (get (:allocations new-replica) j2) task-f)) 6))
-        (recur new-replica)
-        new-replica))))
+  (playback-log (:log env) (extensions/subscribe-to-log (:log env) ch) ch 2000))
+
+(fact "Peers balanced after before killed in multi-job test"
+      (get-counts replica-1) => [6 6 6 6 6 6])

 (onyx.api/kill-job peer-config j1)

 (def replica-2
-  (loop [replica replica-1]
-    (let [position (<!! ch)
-          entry (extensions/read-log-entry (:log env) position)
-          new-replica (extensions/apply-log-entry entry replica)
-          task-a (nth (get-in new-replica [:tasks j1]) 0)
-          task-b (nth (get-in new-replica [:tasks j1]) 1)
-          task-c (nth (get-in new-replica [:tasks j1]) 2)
-          task-d (nth (get-in new-replica [:tasks j2]) 0)
-          task-e (nth (get-in new-replica [:tasks j2]) 1)
-          task-f (nth (get-in new-replica [:tasks j2]) 2)]
-      (if-not (and (= (count (get (get (:allocations new-replica) j1) task-a)) 0)
-                   (= (count (get (get (:allocations new-replica) j1) task-b)) 0)
-                   (= (count (get (get (:allocations new-replica) j1) task-c)) 0)
-                   (= (count (get (get (:allocations new-replica) j2) task-d)) 12)
-                   (= (count (get (get (:allocations new-replica) j2) task-e)) 12)
-                   (= (count (get (get (:allocations new-replica) j2) task-f)) 12))
-        (recur new-replica)
-        new-replica))))
+  (playback-log (:log env) replica-1 ch 2000))
+
+(fact "Peers balanced after job killed in multi-job test"
+      (get-counts replica-2) => [0 0 0 12 12 12])

 (doseq [v-peer v-peers]
   (onyx.api/shutdown-peer v-peer))

 (onyx.api/shutdown-env env)
-(fact "Peers balanced after job killed in multi-job test" true => true)

+(onyx.api/shutdown-peer-group peer-group)


CMR-2894 Clarifying a comment

CMR-2894 Clarifying a comment

--- access-control-app/src/cmr/access_control/services/event_handler.clj
+++ access-control-app/src/cmr/access_control/services/event_handler.clj
@@ -31,7 +31,7 @@
   ;; app itself. We need to ensure that the groups are unindexed here too, or else they will
   ;; still come up in search results, etc..
   (index/delete-provider-groups context provider-id)
-  ;; ACLs are unindexed here, but we will tombstone
+  ;; ACLs are also purged from metadata db in the same way.
   (index/delete-provider-acls context provider-id))

 (defn subscribe-to-events


Optionally run the app with aleph

Optionally run the app with aleph

--- examples/http-swagger/src/example/server.clj
+++ examples/http-swagger/src/example/server.clj
@@ -146,6 +146,7 @@

 (defn start []
   (jetty/run-jetty #'app {:port 3000, :join? false, :async true})
+  ;(aleph/start-server (aleph/wrap-ring-async-handler #'app) {:port 3000})
   (println "server running in port 3000"))

 (comment


:cyclone:

:cyclone:

New york's actual coordinates

--- src/main/clj/agency/irl/instagrammer/core.clj
+++ src/main/clj/agency/irl/instagrammer/core.clj
@@ -74,6 +74,7 @@
 (defn got-new-media
   "Does something with new media from instagram"
   [body params]
+  (println "***")
   (println body)
   ; (println params)
   (update-clients! "got update"))
@@ -118,10 +119,11 @@

     (unsubscribe/all-sync)

-    (let [geo-sub-1 (subscribe/geo :lng 74.0059 :lat -40.7127 :radius 5000)
-          geo-sub-2 (subscribe/geo :lng -40.7127 :lat 74.0059 :radius 5000)
-          tag-sub-1 (subscribe/tag :tag "picoftheday")
-          tag-sub-1 (subscribe/tag :tag "yolo")]))
+    (let [;geo-sub-1 (subscribe/geo :lng 74.0059 :lat -40.7127 :radius 5000)
+          nyc-geo-sub (subscribe/geo :lat 40.748817 :lng -73.985428 :radius 5000)
+          ; tag-sub-1 (subscribe/tag :tag "picoftheday")
+          ; tag-sub-1 (subscribe/tag :tag "yolo")
+          ]))

 ; ; Bind client info


[#2307] Fix tests

[#2307] Fix tests

--- backend/test/akvo/lumen/component/keycloak_test.clj
+++ backend/test/akvo/lumen/component/keycloak_test.clj
@@ -3,6 +3,8 @@
   (:require
    [akvo.lumen.component.keycloak :as keycloak]
    [akvo.lumen.test-utils :as tu]
+   [clj-time.coerce :as tc]
+   [clj-time.core :as t]
    [akvo.lumen.protocols :as p]
    [clojure.test :refer :all]
    [integrant.core :as ig]))
@@ -22,11 +24,11 @@
 (deftest keycloak-test
   (testing "Jerome (admin) permissions to t1"
     (is (= #{"t1/admin"}
-           (p/allowed-paths *keycloak* "jerome@t1.lumen.localhost"))))
+           (p/allowed-paths *keycloak* {:email "jerome@t1.lumen.localhost" :iat (tc/to-date (t/now))}))))

   (testing "Salim (member) permissions to t1"
     (is (= #{"t1"}
-           (p/allowed-paths *keycloak* "salim@t1.lumen.localhost"))))
+           (p/allowed-paths *keycloak* {:email "salim@t1.lumen.localhost" :iat (tc/to-date (t/now))}))))

   (testing "Non existing user"
-    (is (= nil (p/allowed-paths *keycloak* "nobody@t1.lumen.localhost")))))
+    (is (= nil (p/allowed-paths *keycloak* {:email "nobody@t1.lumen.localhost" :iat (tc/to-date (t/now))} )))))


cleanup requires

cleanup requires

--- src/babel/forest.cljc
+++ src/babel/forest.cljc
@@ -1,8 +1,7 @@
 (ns babel.forest
   (:refer-clojure :exclude [get-in deref resolve find parents])
   (:require
-   [babel.cache :refer (build-lex-sch-cache get-comp-phrases-of get-head-phrases-of get-lex
-                                            get-parent-phrases-for-spec)]
+   [babel.cache :refer [check-index get-head-phrases-of get-lex]]
    [babel.over :as over]
    [babel.stringutils :refer [show-as-tree]]
    #?(:clj [clojure.tools.logging :as log])


Add information for env-config to information model

--- doc/information_model.clj
+++ doc/information_model.clj
@@ -540,8 +540,8 @@
           :onyx.messaging/peer-port
           {:doc "Port that peers should use to communicate."
            :optional? false
-           :type :vector
-           :default []}
+           :type :integer
+           :default nil}

           :onyx.messaging/allow-short-circuit?
           {:doc "A boolean denoting whether to allow virtual peers to short circuit networked messaging when colocated with the other virtual peer. Short circuiting allows for direct transfer of messages to a virtual peer's internal buffers, which improves performance where possible. This configuration option is primarily for use in perfomance testing, as peers will not generally be able to short circuit messaging after scaling to many nodes."
@@ -579,4 +579,54 @@
            :optional? true
            :type :keyword
            :default :high-restart-latency
-           :choices [:high-restart-latency :low-restart-latency]}}}}
+           :choices [:high-restart-latency :low-restart-latency]}}}
+:env-config
+ {:summary "All options available to configure the node environment."
+  :link nil
+  :model {:zookeeper/server?
+          {:doc "Bool to denote whether to startup a local, in-memory ZooKeeper for TEST PURPORSES ONLY."
+           :type :boolean
+           :optional? true}
+
+          :zookeeper.server/port
+          {:doc "Port to use for the local in-memory ZooKeeper"
+           :type :integer
+           :required-when ["The `:zookeeper/server?` is `true`."]}
+
+          :onyx.bookkeeper/server?
+          {:doc "Bool to denote whether to startup a BookKeeper instance on this node, for use in persisting Onyx state information."
+           :type :boolean
+           :default false
+           :optional? true}
+
+          :onyx.bookkeeper/local-quorum?
+          {:doc "Bool to denote whether to startup a full quorum of BookKeeper instances on this node for testing purposes."
+           :default false
+           :type :boolean
+           :required-when ["The `:onyx.bookkeeper/server?` is `true` and `:onyx.bookkeeper/local-quorum?` is `true`"]
+           :optional? true}
+
+          :onyx.bookkeeper/local-quorum-ports
+          {:doc "Ports to use for the local BookKeeper quorum."
+           :type :vector
+           :default [3196 3197 3198]
+           :required-when ["The `:onyx.bookkeeper/server?` is `true` and `:onyx.bookkeeper/local-quorum?` is `true`"]
+           :optional? true}
+
+          :onyx.bookkeeper/port
+          {:doc "Port to startup this node's BookKeeper instance on."
+           :type :integer
+           :default 3196
+           :required-when ["The `:onyx.bookkeeper/server?` is `true` and `:onyx.bookkeeper/local-quorum?` is `false`"]}
+
+          :onyx.bookkeeper/base-journal-dir
+          {:doc "Directory to store BookKeeper's journal in. It is recommended that this is altered to somewhere fast, preferably on a different disk to the BookKeeper ledger."
+           :type :string
+           :default "/tmp/bookkeeper_journal"
+           :optional? true}
+
+          :onyx.bookkeeper/base-ledger-dir
+          {:doc "Directory to store BookKeeper's ledger in. It is recommended that this is altered to somewhere fast, preferably on a different disk to the BookKeeper journal"
+           :type :string
+           :default "/tmp/bookkeeper_ledger"
+           :optional? true}}}}


added extra line break

added extra line break

--- src/c_graph/core.cljs
+++ src/c_graph/core.cljs
@@ -84,7 +84,7 @@
      [:div (map span children)]
      [:br]
      [:form {:on-submit submit-form}
-      [:input {:type "text" :id "zi"}][:br]
+      [:input {:type "text" :id "zi"}][:br][:br]
       [:input {:type "submit"}]]
      ]))


Fixing get

Fixing get

--- src/celestial/api.clj
+++ src/celestial/api.clj
@@ -121,11 +121,15 @@
            (success {:msg "added new task" :id id})))

   (PUT- "/task/:id" [^:int id & ^:task task] {:nickname "updateTask" :summary "Update a task"}
-        (p/update-task task)
+        (p/update-task id task)
         (success {:msg "updated task" :task task}))

-  (GET- "/task" [^:int id] {:nickname "getTask" :summary "Get a task"}
-        (success {:task (p/get-task id)})))
+  (GET- "/task/:id" [^:int id] {:nickname "getTask" :summary "Get a task"}
+        (success {:task (p/get-task id)}))
+
+  (DELETE- "/task/:id" [^:int id] {:nickname "deleteTask" :summary "Deletes a task"}
+           (p/delete-task id)
+           (success {:msg "delete task" :id id})))

 (defroutes- users {:path "/user" :description "User managment"}
   (GET- "/user/:name" [^:string name] {:nickname "getUser" :summary "Get User"}


adding notes and action job

adding notes and action job

--- src/celestial/api.clj
+++ src/celestial/api.clj
@@ -37,18 +37,26 @@

 (defmodel object)

-(defmodel capistrano :name :string :src :string :args :string)
+(defmodel capistrano :args {:type "List" :items {"$ref" "String"}})

-(defmodel task :capistrano {:type "Capistrano" :description "For capistrano based tasks"})
+(defmodel ccontainer :capistrano {:type "Capistrano"} )
+
+(defmodel actions :action-a {:type "Ccontainer"})
+
+(defmodel action :operates-on :string :src :string :actions {:type "Actions"})

 (defroutes- jobs {:path "/job" :description "Operations on async job scheduling"}

-  (POST- "/job/stage/:id" [^:int id] {:nickname "stageSystem" :summary "Complete end to end staging job"}
+  (POST- "/job/stage/:id" [^:int id]
+    {:nickname "stageSystem" :summary "Complete end to end staging job"
+     :notes "Combined system creation and provisioning, seperate actions are available also."}
          (jobs/enqueue "stage" {:identity id :args [(p/get-system id)]})
          (success {:msg "submitted staging" :id id}))

-  (POST- "/job/create/:id" [^:int id] {:nickname "createSystem" :summary "System creation job"
-                                       :errorResponses (errors {:bad-req "Missing system"})}
+  (POST- "/job/create/:id" [^:int id]
+     {:nickname "createSystem" :summary "System creation job"
+      :errorResponses (errors {:bad-req "Missing system"})
+      :notes "Creates a new system on remote hypervisor (usually followed by provisioning)."}
          (if-not (p/system-exists? id)
            (bad-req {:msg (<< "No system found with given id ~{id}")})
            (success
@@ -56,18 +64,29 @@
               :job (jobs/enqueue "reload"
               {:identity id :args [(assoc (p/get-system id) :system-id (Integer. id))]})})))

-  (POST- "/job/destroy/:id" [^:int id] {:nickname "destroySystem" :summary "System destruction job"}
+  (POST- "/job/destroy/:id" [^:int id]
+    {:nickname "destroySystem" :summary "System destruction job"
+     :notes "Destroys a system, clearing it both from Celestial's model storage and hypervisor"}
          (success
            {:msg "submited system destruction" :id id
             :job (jobs/enqueue "destroy" {:identity id :args [(p/get-system id)]})}))

-  (POST- "/job/provision/:id" [^:int id] {:nickname "provisionSystem" :summary "Provisioning job"}
+  (POST- "/job/provision/:id" [^:int id]
+    {:nickname "provisionSystem" :summary "Provisioning job"
+     :notes "Starts a provisioning workflow on a remote system using the provisioner configured in system type"}
          (let [system (p/get-system id) type (p/get-type (:type system))
                job (jobs/enqueue "provision" {:identity id :args [type system]})]
            (success
              {:msg "submitted provisioning" :id id :system system :type type :job job})))

-  (POST- "/job/:action/:id" [^:string actions ^:int id] {:nickname "runAction" :summary "Run an adhoc remote action (like deployment, service restart etc) "}
+  (POST- "/job/:action/:id" [^:string action ^:int id]
+     {:nickname "runAction" :summary "Run remote action"
+      :notes "Runs adhoc remote opertions on system (like deployment, service restart etc)
+             using matching remoting capable tool like Capisrano/Supernal/Fabric"}
+       (let [system (p/get-system id) type (p/find-action-for action (:type system))
+               job (jobs/enqueue "provision" {:identity id :args [type system]})]
+           (success
+             {:msg "submitted action" :id id :system system :action action :job job}))
          )

   (GET- "/job/:queue/:uuid/status" [^:string queue ^:string uuid]
@@ -83,22 +102,20 @@
   (update-in user [:password] (fn [v] (creds/hash-bcrypt v))))

 (defroutes- actions {:path "/actions" :description "Adhoc actions managment"}
-  (POST- "/action" [& ^:task task] {:nickname "addActions" :summary "Adds an actions set"}
-         (let [id (p/add-task task)]
+  (POST- "/action" [& ^:action action] {:nickname "addActions" :summary "Adds an actions set"}
+         (let [id (p/add-action action)]
            (success {:msg "added actions" :id id})))

-  (PUT- "/action/:id" [^:int id & ^:task task] {:nickname "updateActions" :summary "Update an actions set"}
-        (p/update-task id task)
-        (success {:msg "updated actions" :task task}))
+  (PUT- "/action/:id" [^:int id & ^:action action] {:nickname "updateActions" :summary "Update an actions set"}
+        (p/update-action id action)
+        (success {:msg "updated actions" :action action}))

   (GET- "/action/:id" [^:int id] {:nickname "getActions" :summary "Gets actions descriptor"}
-        (success {:task (p/get-task id)}))
+        (success {:action (p/get-action id)}))

   (DELETE- "/action/:id" [^:int id] {:nickname "deleteActions" :summary "Deletes an action set"}
-           (p/delete-task id)
+           (p/delete-action id)
            (success {:msg "deleted actions" :id id})))
-
-

 (defroutes app-routes
   hosts types actions jobs (friend/wrap-authorize users admin) (friend/wrap-authorize quotas admin) (route/not-found "Not Found"))


CLJS-484 Throw exception instead of trying to throw string in defmulti compiler macro

--- src/clj/cljs/core.clj
+++ src/clj/cljs/core.clj
@@ -1152,7 +1152,7 @@
                       (conj (meta mm-name) m)
                       m)]
     (when (= (count options) 1)
-      (throw "The syntax for defmulti has changed. Example: (defmulti name dispatch-fn :default dispatch-value)"))
+      (throw (Exception. "The syntax for defmulti has changed. Example: (defmulti name dispatch-fn :default dispatch-value)")))
     (let [options   (apply hash-map options)
           default   (core/get options :default :default)]
       (check-valid-options options :default :hierarchy)


Costs for accessing.

Costs for accessing.

--- src/clj/game/core.clj
+++ src/clj/game/core.clj
@@ -872,6 +872,16 @@
          (swap! state update-in [:runner :register :made-run] #(conj % (first s)))
          (trigger-event state :runner :run s)))))

+(defn access-cost-bonus [state side costs]
+  (swap! state update-in [:bonus :access-cost] #(merge-costs (concat % costs))))
+
+(defn access-cost [state side card]
+  (-> (if-let [costfun (:access-cost-bonus (card-def card))]
+        (costfun state side card nil)
+        nil)
+      (concat (get-in @state [:bonus :access-cost]))
+      merge-costs flatten vec))
+
 (defn steal-cost-bonus [state side costs]
   (swap! state update-in [:bonus :steal-cost] #(merge-costs (concat % costs))))

@@ -899,44 +909,49 @@
   (doseq [c cards]
     (swap! state update-in [:bonus] dissoc :trash)
     (swap! state update-in [:bonus] dissoc :steal-cost)
-    (let [cdef (card-def c)
-          c (assoc c :seen true)]
-      (when-let [name (:title c)]
-        (if (= (:type c) "Agenda")
-          (do (trigger-event state side :pre-steal-cost c)
-              (if (not (get-in @state [:runner :register :cannot-steal]))
-                (let [cost (steal-cost state side c)]
-                  (if (pos? (count cost))
-                    (optional-ability state :runner c (str "Pay " (costs-to-symbol cost) " to steal " name "?")
-                                      {:yes-ability {:cost cost
-                                                     :effect (effect (system-msg (str "pays " (costs-to-symbol cost)
-                                                                                " to steal " (:title c)))
-                                                                     (resolve-steal c))}
-                                       :no-ability {:effect (effect (resolve-steal-events c))}} nil)
-                    (resolve-ability state :runner
-                                     {:prompt (str "You access " (:title c)) :choices ["Steal"]
-                                      :effect (req (resolve-steal state :runner c))} c nil)))
-                (do (resolve-steal-events state side c)
-                    (prompt! state :runner c (str "You accessed but cannot steal " (:title c)) ["OK"] {}))))
-        (do (when-let [access-effect (:access cdef)]
-              (resolve-ability state (to-keyword (:side c)) access-effect c nil))
-            (trigger-event state side :access c)
-            (trigger-event state side :pre-trash c)
-            (when (not= (:zone c) [:discard])
-              (if-let [trash-cost (trash-cost state side c)]
-                (let [card (assoc c :seen true)]
-                  (if (and (get-in @state [:runner :register :force-trash])
-                           (can-pay? state :runner :credit trash-cost))
-                    (resolve-ability state :runner {:cost [:credit trash-cost]
-                                                    :effect (effect (trash card)
-                                                            (system-msg (str "is forced to pay " trash-cost
-                                                                             " [Credits] to trash " (:title card))))} card nil)
-                    (optional-ability state :runner card (str "Pay " trash-cost "[Credits] to trash " name "?")
-                                      {:yes-ability {:cost [:credit trash-cost]
-                                                     :effect (effect (trash card)
-                                                                     (system-msg (str "pays " trash-cost " [Credits] to trash "
-                                                                                (:title card))))}} nil)))
-                (prompt! state :runner c (str "You accessed " (:title c)) ["OK"] {})))))))))
+    (swap! state update-in [:bonus] dissoc :access-cost)
+    (trigger-event state side :pre-access-card c)
+    (let [acost (access-cost state side c)]
+      (if (or (empty? acost) (pay state side c acost))
+        (let [cdef (card-def c)
+              c (assoc c :seen true)]
+          (when-let [name (:title c)]
+            (if (= (:type c) "Agenda")
+              (do (trigger-event state side :pre-steal-cost c)
+                  (if (not (get-in @state [:runner :register :cannot-steal]))
+                    (let [cost (steal-cost state side c)]
+                      (if (pos? (count cost))
+                        (optional-ability state :runner c (str "Pay " (costs-to-symbol cost) " to steal " name "?")
+                                          {:yes-ability {:cost cost
+                                                         :effect (effect (system-msg (str "pays " (costs-to-symbol cost)
+                                                                                " to steal " (:title c)))
+                                                                         (resolve-steal c))}
+                                           :no-ability {:effect (effect (resolve-steal-events c))}} nil)
+                        (resolve-ability state :runner
+                                         {:prompt (str "You access " (:title c)) :choices ["Steal"]
+                                          :effect (req (resolve-steal state :runner c))} c nil)))
+                    (do (resolve-steal-events state side c)
+                        (prompt! state :runner c (str "You accessed but cannot steal " (:title c)) ["OK"] {}))))
+              (do (when-let [access-effect (:access cdef)]
+                    (resolve-ability state (to-keyword (:side c)) access-effect c nil))
+                  (trigger-event state side :access c)
+                  (trigger-event state side :pre-trash c)
+                  (when (not= (:zone c) [:discard])
+                    (if-let [trash-cost (trash-cost state side c)]
+                      (let [card (assoc c :seen true)]
+                        (if (and (get-in @state [:runner :register :force-trash])
+                                 (can-pay? state :runner :credit trash-cost))
+                          (resolve-ability state :runner {:cost [:credit trash-cost]
+                                                          :effect (effect (trash card)
+                                                                          (system-msg (str "is forced to pay " trash-cost
+                                                                                " [Credits] to trash " (:title card))))} card nil)
+                          (optional-ability state :runner card (str "Pay " trash-cost "[Credits] to trash " name "?")
+                                            {:yes-ability {:cost [:credit trash-cost]
+                                                           :effect (effect (trash card)
+                                                                           (system-msg (str "pays " trash-cost " [Credits] to trash "
+                                                                                (:title card))))}} nil)))
+                      (prompt! state :runner c (str "You accessed " (:title c)) ["OK"] {})))))))
+        (prompt! state :runner nil "You can't pay the cost to access this card" ["OK"] {})))))

 (defn max-access [state side n]
   (swap! state assoc-in [:run :max-access] n))


Initial implementation of history

Initial implementation of history

--- src/cljs/svg/app.cljs
+++ src/cljs/svg/app.cljs
@@ -2,6 +2,39 @@
   (:require [reagent.core :as r :refer [atom]]))

 (defonce app-db (atom {:x 300 :y 100 :radius 10 :fill nil :clicks 0}))
+
+(defonce history (atom {:states []}))
+
+(defn from-history
+  [db h v]
+  (let [i (js/parseInt v)
+        state (get @h i)]
+    (when state
+      (reset! db state))))
+
+(defn history-component [db]
+  (let [h (r/cursor history [:states])
+        active (atom nil)]
+    (fn [db]
+      (when-not @active
+        (swap! h #(conj % @db)))
+      [:div {:class "form-group"}
+       [:label {:for "history"} "History"]
+       [:input {:type "range"
+                :class "form-control"
+                :name "history"
+                :min 0
+                :max (count @h)
+                :onChange (fn [e]
+                            (when (> (count @h) 0)
+                              (reset! active true)
+                              (->> e
+                                 (.-target)
+                                 (.-value)
+                                 (from-history db h)
+                                 )))
+                :onBlur (fn [e] (reset! active false))
+                }]])))

 (defn click-count-component
   [clicks]
@@ -58,6 +91,7 @@
     (fn []
       [:div {:id "wrapper"}
        [:div {:id "controls" :class "col-md-3"}
+        [history-component app-db]
         [click-count-component clicks]
         [range-component x 300 700 "CX"]
         [range-component y 100 500 "CY"]


removing extraneous comments

removing extraneous comments

--- src/clrdlhu/core.cljs
+++ src/clrdlhu/core.cljs
@@ -306,46 +306,14 @@
     (println "Sorry, there is no room for" (:name @object)
              "on" (:name @support))))

-(defn put [o s]
-  (put-on (block_map o) (block_map s))
-  (draw))
-
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

-;; (do (reset-world)
-;;     (println "------------------------->>")
-;;     (print (put-on w7 b3))
-;;     (println "------------------------->>")
-;;     (print (put-on b2 b4))
-;;     (println "------------------------->>")
-;;     (print (put-on w5 b2)))
-
-;; (pprint w7)
-;; (pprint "suckit")
-;; (pprint (assoc w7 :position '(999 999)))
-;; (print (* 8 8))
-
-;; (println (top-location @hh))
-;; (println (top-location @(second *blocks*)))
-;; (println (get-space @(second *blocks*)  @(nth *blocks* 3)))
-;; (println @(block_map "tt"))
-
-;; (println  (m/run* [q]
-;;             (membero q [1 2 3])
-;;             (membero q [2 3 4])))
-
-;;(print (put-on (block_map "b1") (block_map "b2")))
-
-;; (println "------------------------->>")
-;; (print (put-on (block_map "b2") (block_map "w7")))
-;; (println "------------------------->>")
-;; (print (put-on (block_map "b1") (block_map "b2")))
-;; (println "------------------------->>")
-;; (print (put-on (block_map "b2") (block_map "b6")))
-;; (println "------------------------->>")
-
-(println (:name @(:supported-by @(block_map "b1"))))
-
+(def black "#000000")
+(def yellow "#FFDB7F")
+(def red "#E88E7F")
+(def purple "#DA98FF")
+(def blue "#88BAE8")
+(def green "#7FFFA5")

 (def canvas (.getElementById js/document "canvas"))
 (def context (.getContext canvas "2d"))
@@ -356,26 +324,17 @@
 (def world (atom {}))

 (defn resized []
-  (set! (.-width canvas) (* @width cell-size)) ;;(.-innerWidth js/window))
-  (set! (.-height canvas) (* @height cell-size)) ;;(.-innerHeight js/window))
-  ;; (reset! width (/ (.-width canvas) cell-size))
-  ;; (reset! height (/ (.-height canvas) cell-size))
-  )
+  (set! (.-width canvas) (* @width cell-size))
+  (set! (.-height canvas) (* @height cell-size)))

 (defn fill_sq [x y w h];; colour]
   (set! (.-fillStyle context) red)
   (set! (.-strokeStyle context) yellow)
-  ;; (.fillRect context
-  ;;            (* x cell-size)
-  ;;            (* y cell-size)
-  ;;            (* w cell-size)
-  ;;            (* h cell-size))
   (.strokeRect context
                (* x cell-size)
                (* y cell-size)
                (* w cell-size)
-               (* h cell-size))
-  )
+               (* h cell-size)))

 (defn fill_tri [x y w h];; colour]
   (set! (.-fillStyle context) red)
@@ -391,7 +350,7 @@
     (.lineTo context tx ty)
     (.stroke context)))

-(defn fill_circ [x y w h];; colour]
+(defn fill_circ [x y w];; colour]
   (set! (.-fillStyle context) red)
   (set! (.-strokeStyle context) yellow)
   (let [r (/ (* cell-size w) 2)
@@ -409,13 +368,6 @@
 (defn deg->rad [d]
   (* Math/PI (/ d 360)))

-(def black "#000000")
-(def yellow "#FFDB7F")
-(def red "#E88E7F")
-(def purple "#DA98FF")
-(def blue "#88BAE8")
-(def green "#7FFFA5")
-
 (set! (.-onresize js/window) resized)

 (resized)
@@ -428,33 +380,26 @@
              (* cell-size @width)
              (* cell-size @height)))

-;;(blank)
-
 (defn draw []
   (blank)
   (doseq [[k v] block_map]
-    (cond
-      (= (:type @v) ::brick)(fill_sq (first (:position @v))
-                                     (- @height (last (:position @v)))
-                                     (:width @v)
-                                     (- (:height @v)))
-      (= (:type @v) ::wedge)(fill_tri (first (:position @v))
-                                      (- @height (last (:position @v)))
-                                      (:width @v)
-                                      (- (:height @v)))
-      (= (:type @v) ::ball)(fill_circ (first (:position @v))
-                                      (- @height (last (:position @v)))
-                                      (:width @v)
-                                      (- (:height @v)))
-      :else
-      (println "table"))
+    (let [x (first (:position @v))
+          y (- @height (last (:position @v)))
+          w (:width @v)
+          h (- (:height @v))]
+      (cond
+        (= (:type @v) ::brick)(fill_sq x y w h)
+        (= (:type @v) ::wedge)(fill_tri x y w h)
+        (= (:type @v) ::ball)(fill_circ x y w)
+        :else
+        (println "draw table")))
     (fill_txt (first (:position @v))
               (- @height (last (:position @v)))
               (:name @v))))

 (draw)

-
-(println (- 6))
-
-(println Math/PI)
+(defn put [o s]
+  (put-on (block_map o) (block_map s))
+  (draw))
+


light refactoring

light refactoring

--- src/crawler/crawl.clj
+++ src/crawler/crawl.clj
@@ -44,29 +44,35 @@
   (if (and (not (zero? limit))
            (or (seq (-> queues :content))
                (seq (-> queues :pagination))))
-    (let [content-q  (-> queues :content)         ; holds the content queues
-          paging-q   (-> queues :pagination)      ; holds the pagination queues
+    (let [content-q   (-> queues :content)         ; holds the content queues
+          paging-q    (-> queues :pagination)      ; holds the pagination queues

-          queue-kw   (cond
-                      (empty? content-q)
-                      :pagination
+          queue-kw    (cond
+                       (empty? content-q)
+                       :pagination

-                      (empty? paging-q)
-                      :content
+                       (empty? paging-q)
+                       :content

-                      :else
-                      (if (even? (int (/ (count visited) 10)))
-                        :pagination :content))
-          queue      (queues queue-kw)
-
-          url        (-> queue first :url)
-          body       (-> url client/get :body)
-          paginated? (-> queue first :pagination?)
-          extracted  (extractor/extract-above-average-richest
-                      body (first queue) (clojure.set/union visited queue))
-          decision   (:decision extracted)
-          xpaths     (map first decision)
-          score      (:score extracted)]
+                       :else
+                       (if (even? (int (/ (count visited) 10)))
+                         :pagination :content))
+
+          queue       (queues queue-kw)
+
+          url         (-> queue first :url)
+          body        (-> url client/get :body)
+          new-visited (conj visited url)
+          paginated?  (-> queue first :pagination?)
+
+          ;; extract from whatever needs extracting
+          extracted   (extractor/extract-above-average-richest
+                       body
+                       (first queue)
+                       (clojure.set/union visited queue))
+          decision    (:decision extracted)
+          xpaths      (map first decision)
+          score       (:score extracted)]
       (do
         (println :total-score (/ sum-score num-decisions))
         (println :cur-page-score score)
@@ -75,7 +81,7 @@
                       (/ sum-score num-decisions))
                    score))

-          (let [; the decision made by the pagination component
+          (let [;; the decision made by the pagination component
                 paging-dec   (extractor/weak-pagination-detector
                               body
                               (first queue)
@@ -83,7 +89,8 @@
                                                  (map #(-> % :url) content-q)
                                                  (map #(-> % :url) paging-q)
                                                  [url]))
-
+
+                ;; add to content-q if anything needs adding/removing
                 content-q'   (concat (if (= :content queue-kw)
                                        (rest content-q) content-q)
                                      (distinct-by-key
@@ -105,6 +112,7 @@
                                         decision))
                                       :url))

+                ;; add to paging-q if anything needs adding/removing
                 paging-q'    (concat (if (= :pagination queue-kw)
                                        (rest paging-q) paging-q)
                                      (distinct-by-key
@@ -124,7 +132,8 @@
                                                links))
                                             paging-dec))
                                       :url))
-                new-visited  (conj visited url)
+
+
                 new-num-dec  (inc num-decisions)
                 new-scr      (+ score sum-score)
                 new-lim      (dec limit)]
@@ -142,7 +151,6 @@
                                  :pagination (rest paging-q)}
                                 {:content (rest content-q)
                                  :pagination paging-q})
-                  new-visited (conj visited url)
                   new-num-dec num-decisions
                   new-scr     sum-score
                   new-lim     (dec limit)]


Only announce region that is defined

Only announce region that is defined

--- src/demogorgon/nh.clj
+++ src/demogorgon/nh.clj
@@ -13,6 +13,7 @@

 (def logger (Logger/getLogger "demogorgon.nh"))
 (def scummers (ref {}))
+(def announce-region "eu")

 (def db {:classname "org.sqlite.JDBC"
                     :subprotocol "sqlite"
@@ -276,7 +277,8 @@
                                              (:name data)
                                              (:endtime data)))
             final-tweet (str tweet-prefix ", " url)]
-        (announce irc out)
+        (if (= (:region data) announce-region)
+          (announce irc out))
         (try
          (twitter/tweet final-tweet)
          (catch Exception e
@@ -411,7 +413,8 @@

 (defn handle-livelog-line [irc file line]
   (let [data (assoc (parse-line line) :region (region-from-fn file))]
-    (if (not (is-scum (:player data)))
+    (if (and (not (is-scum (:player data)))
+             (= (:region data) announce-region))
       (let [out (make-livelog-out data)]
         (if out
           (announce irc out))))))


Small doc fixes.

Small doc fixes.

--- cortex/src/cortex/graph.clj
+++ cortex/src/cortex/graph.clj
@@ -504,7 +504,8 @@
 means the the format of the stream map and the node->output-map must be
 entries of the form of at least {:buffer data} instead of linking key directly
 to data.  This allows a uniform system both when doing auto-differentiation and
-when simply doing execution."
+when simply doing execution because when doing back propagation the entries must
+link to both {:buffer :gradient}."
   [graph node stream-map node-id->output-map]
   (->> (get-node-arguments node)
        (map (fn [{:keys [key type] :as argument}]
@@ -538,11 +539,13 @@
             (get p->c-map parent-node-id))))

 (defn remove-node
+  "Remove a node, its buffers and all children from the graph."
   [graph node-id]
   (recur-remove-node (parent->child-map graph) graph node-id))

 (defn parameter-count
+  "Return the number of trainable and non-trainable parameters."
   [graph]
   (->> (get graph :buffers)
        vals
@@ -551,6 +554,7 @@

 (defn graph->nodes
+  "Return a list of all nodes in the graph in dfs order."
   [graph]
   (->> (dfs-seq graph)
        (map #(get-node graph %))))


Begin ordering refactor

Begin ordering refactor

Ordering should use the previous iteration of ordering rather than
feeding in the original sparse graph each time.

--- src/fatlip/order.cljs
+++ src/fatlip/order.cljs
@@ -379,24 +379,25 @@
     [(+ sup-crossings sub-crossings) marked]))

-(defn SparseGraph->OrderedGraph
+(defn OrderedGraph->OrderedGraph
   "Performs one layer-by-layer sweep of the graph using ESK's algorithm"
-  [sparse-graph first-layer]
-  (let [{:keys [ps qs rs preds succs characters layers]} sparse-graph
+  [ordered-graph]
+  (let [{:keys [ps qs rs preds succs characters layers]} ordered-graph
+        first-layer (first layers)
         [ordered-layers minus-ps minus-qs]
-        (reduce (fn [[layers minus-ps minus-qs prev-layer] sparse-layer]
+        (reduce (fn [[layers minus-ps minus-qs prev-layer] layer]
                   (let [minus-p (replace-ps (:items prev-layer) ps succs)
                         positions (set-positions minus-p)
                         [qs non-qs] (map set
                                          ((juxt filter remove)
                                           #(contains? qs %)
-                                          (:nodes sparse-layer)))
+                                          (remove vector? (:items layer))))
                         measures (set-measures non-qs preds positions)
                         minus-q (merge-layer minus-p positions
                                              non-qs measures)
                         items (add-qs minus-q qs)
-                        ordered-layer (OrderedLayer. (:id sparse-layer)
-                                                     (:duration sparse-layer)
+                        ordered-layer (OrderedLayer. (:id layer)
+                                                     (:duration layer)
                                                      items)]
                     [(conj layers ordered-layer)
                      (conj minus-ps minus-p)
@@ -456,6 +457,26 @@
     (assoc co-graph :characters sorted)))

+(defn SparseGraph->OrderedGraph
+  [sparse-graph]
+  (let [{:keys [ps qs rs preds succs characters layers]} sparse-graph
+        ordered-layers (map (fn [layer]
+                              (map->OrderedLayer
+                               (-> layer
+                                   (dissoc :nodes)
+                                   (assoc :items (:nodes layer)))))
+                            layers)]
+    (map->OrderedGraph {:layers ordered-layers
+                        :minus-ps []
+                        :minus-qs []
+                        :succs succs
+                        :preds preds
+                        :ps ps
+                        :qs qs
+                        :rs rs
+                        :characters characters})))
+
+
 (defn SparseGraph->ordered-graphs
   "Implements the 2-layer crossing minimization algorithm on a sparse graph
   found in 'An Efficient Implementation of Sugiyama’s Algorithm for Layered
@@ -476,34 +497,23 @@
   allows the counting and marking to be parallelized, whereas the ordering is
   inherently serial."
   [sparse-graph & {:keys [max-sweeps] :or {max-sweeps 20}}]
-  (let [layers (:layers sparse-graph)
-        last-layer-idx (dec (count layers))
-        first-sparse-layer (first layers)
-        ;; seed the first layer with initial ordered layer
-        first-ordered-layer (map->OrderedLayer
-                             (-> first-sparse-layer
-                                 (dissoc :nodes)
-                                 (assoc :items (:nodes first-sparse-layer))))
-        rev-sparse-graph (rev sparse-graph)]
+  (let [last-layer-idx (dec (count (:layers sparse-graph)))]
     (->>
-     (cycle [sparse-graph rev-sparse-graph])
-     (reduce (fn [[orderings ordering-set first-layer :as reduced-info]
-                  input-graph]
-               (let [graph (SparseGraph->OrderedGraph input-graph
-                                                      first-layer)
-                     layers (:layers graph)]
-                 ;; If we see a graph that we've seen before, this is the
-                 ;; beginning of a cycle, and we can stop processing
-                 (if (or (contains? ordering-set graph)
-                         (= max-sweeps (inc (count reduced-info))))
-                   (reduced [orderings])
-                   ;; The last layer of the current ordering is the first
-                   ;; layer of the next
-                   [(conj orderings graph)
-                    (conj ordering-set graph)
-                    (layers last-layer-idx)])))
-             [[] #{} first-ordered-layer])
-     first
+     (loop [orderings []
+            ordering-set #{}
+            input-graph (SparseGraph->OrderedGraph sparse-graph)]
+       (let [graph (OrderedGraph->OrderedGraph input-graph)
+             layers (:layers graph)]
+         ;; If we see a graph that we've seen before, this is the
+         ;; beginning of a cycle, and we can stop processing
+         (if (or (contains? ordering-set graph)
+                 (= max-sweeps (inc (count orderings))))
+           orderings
+           ;; The last layer of the current ordering is the first
+           ;; layer of the next
+           (recur (conj orderings graph)
+                  (conj ordering-set graph)
+                  (rev graph)))))
      ;; This is sort of ugly, but once we order the nodes, we still have to
      ;; come up with a good subnode ordering. Conceptually, this belongs in
      ;; SparseGraph->OrderedGraph, but it's also conceptually cromulent to have


fix elapsed time display

fix elapsed time display

--- cljs/sledge/core.cljs
+++ cljs/sledge/core.cljs
@@ -167,7 +167,7 @@
                (dom/button #js {:onClick #(dequeue-track index)}
                            "-")))))

-(defn minimised-queue-view [app owner]
+(defn audio-el [app owner]
   (reify
     om/IDidMount
     (did-mount [this]
@@ -176,6 +176,12 @@
         ;; http://stackoverflow.com/questions/11291651/why-dont-audio-and-video-events-bubble
         (.addEventListener el "ended" player-next true)
         (.addEventListener el "timeupdate" player-playing true)))
+    om/IRender
+    (render [this]
+      (html [:audio {:ref "player"}]))))
+
+(defn minimised-queue-view [app owner]
+  (reify
     om/IRender
     (render [this]
       (let [queue (om/observe owner (player-queue))]
@@ -338,7 +344,8 @@
          (if (:viewing-queue? state)
            (om/build queue-view state)
            (om/build minimised-queue-view state))]
-        [:audio {:ref "player"}]]))))
+        (om/build audio-el state)
+        ]))))

 (defn init []
   (add-watch app-state :transport sync-transport)


Focus management #38

Focus management #38

--- src/flatgui/focus.clj
+++ src/flatgui/focus.clj
@@ -17,13 +17,17 @@
 (def clean-state {:mode :none
                   :focused-child nil})

+(def having-focus-state {:mode :has-focus
+                         :focused-child nil})
+
+(defn temporarily-taken-from-state [permanent-owner-child] {:mode :has-focus
+                                                            :focused-child permanent-owner-child})
+
 (defn focus-child [child-id]
   (if (keyword? child-id)
     {:mode :parent-of-focused
      :focused-child child-id}
     (throw (IllegalArgumentException. (str "child-id must be a keyword but is: " child-id)))))
-
-

 (defn accepts-focus? [component]
   (or
@@ -54,7 +58,6 @@
                 :last (nth child-ids (dec child-count))))))
   ([component dir] (get-in-cycle component dir nil)))

-
 (fg/defevolverfn :focus-state
   (let [reason (fg/get-reason)
         this-focused-child (:focused-child old-focus-state)
@@ -84,13 +87,17 @@
         {:mode :requests-focus
          :focused-child this-focused-child}
         (and (:closed-focus-root component) (#{:none :throws-focus :requests-focus} this-mode))
-        {:mode :has-focus
-         :focused-child nil}
+        having-focus-state
         :else old-focus-state)

       (fgc/parent-reason? reason)
-      (case parent-mode
-        :has-focus clean-state
+      (case (do (println "Parent event into " (:id component) " parent-mode " parent-mode " this-mode " this-mode) parent-mode)
+        ;; If parent has focus temporarily, I take focus back (*2)
+        ;; Otherwise my parent has focus permanently and my state is clean
+        :has-focus (if (= parent-focused-child (:id component)) ; This condition means that parent has focus temporarily
+                     having-focus-state
+                     clean-state)
+        ;:has-focus clean-state
         :none clean-state
         :parent-of-focused (if (= parent-focused-child (:id component))
                              ;; If my parent is :parent-of-focused and I am :parent-of-focused,
@@ -109,8 +116,7 @@
                                                    (if (not (:focusable component))
                                                      (get-in-cycle component :first)))]
                                  (focus-child child-id)
-                                 {:mode :has-focus
-                                  :focused-child nil})
+                                 having-focus-state)
                                old-focus-state)

                              ;; Another component next to me has focus, therefore my state is clean
@@ -126,7 +132,8 @@
       (let [child-id (nth reason 1)
             child-focus-state (get-property [:this child-id] :focus-state)
             child-mode (:mode child-focus-state)
-            child-throw-mode (:throw-mode child-focus-state)]
+            child-throw-mode (:throw-mode child-focus-state)
+            _ (println "Child even into " (:id component) " child " child-id " mode " child-mode " thm " child-throw-mode)]
         (case child-mode
           ;; Nothing to change in this case
           :none old-focus-state
@@ -155,14 +162,18 @@
                             ;; changed about this
                             :requests-focus old-focus-state

-                            ;; My child request focus and I thow focus - then I let this child get focus
+                            ;; My child request focus and I throw focus - then I let this child get focus
                             :throws-focus (focus-child child-id))
           :throws-focus (case child-throw-mode
                           ;; My child throws focus in :prev direction. Give focus to previous child.
                           ;; But if I'm not a closed root then there may be no previous child,
                           ;; get-in-cycle returns nil in this case. Rethrow it out in this case
                           :prev (if-let [prev-child (get-in-cycle component :prev this-focused-child)]
-                                  (focus-child prev-child)
+                                  (if (= prev-child this-focused-child)
+                                    ;; My child throws focus, but there is no other component to take it.
+                                    ;; So I take it temporarily and child will take back within the next step. (*2)
+                                    (temporarily-taken-from-state this-focused-child)
+                                    (focus-child prev-child))
                                   {:mode :throws-focus
                                    :throw-mode :prev
                                    :focused-child this-focused-child})
@@ -171,7 +182,11 @@
                           ;; But if I'm not a closed root then there may be no next child,
                           ;; get-in-cycle returns nil in this case. Rethrow it out in this case
                           :next (if-let [next-child (get-in-cycle component :next this-focused-child)]
-                                  (focus-child next-child)
+                                  (if (= next-child this-focused-child)
+                                    ;; My child throws focus, but there is no other component to take it.
+                                    ;; So I take it temporarily and child will take back within the next step. (*2)
+                                    (temporarily-taken-from-state this-focused-child)
+                                    (focus-child next-child))
                                   {:mode :throws-focus
                                    :throw-mode :next
                                    :focused-child this-focused-child})


Bind _

Bind _

--- src/fleet/builder.clj
+++ src/fleet/builder.clj
@@ -23,5 +23,5 @@
   [args ast]
   (str
     "(fn [runtime " (su/join " " args) "] "
-    "(let [{:keys [raw raw? screen]} runtime] "
+    "(let [{:keys [raw raw? screen _]} runtime] "
     (consume ast) "))"))


Only show icons on PRs

Only show icons on PRs

The compare view when creating a PR also has commit links, but isn't an
actual PR view. Fixes #1.

--- src/gitique/core.cljs
+++ src/gitique/core.cljs
@@ -22,8 +22,9 @@
 (add-watch state :pr-change (fn [_ _ old new]
                               (let [new-pr (:current-pr new)
                                     new-count (:commit-count new)]
-                                (when (or (not= (:current-pr old) new-pr)
-                                          (and (pos? new-count) (not= (:commit-count old) new-count)))
+                                (when (and new-pr
+                                           (or (not= (:current-pr old) new-pr)
+                                               (and (pos? new-count) (not= (:commit-count old) new-count))))
                                   (add-icons!)
                                   (maybe-show-new (:repo new-pr) (:pr new-pr))))))


write files

write files

--- src/gitmirth/core.clj
+++ src/gitmirth/core.clj
@@ -5,7 +5,8 @@
              [pprint :as pp]
              [zip :as zip]]
             [clojure.data.xml :as xml]
-            [clojure.data.zip.xml :as zx]))
+            [clojure.data.zip.xml :as zx]
+            [clojure.java.io :as io]))

 (defn to-zip
   "Takes a string of xml and returns an xml zipper"
@@ -41,7 +42,12 @@
 (defn process-channel
   "Take a channel zip and write to the filesystem"
   [chanzip]
-  (zx/xml-> chanzip :name zip/down zip/node))
+  (let [channel-name (first (zx/xml-> chanzip :name zip/node))
+        channel-xml (xml/indent-str (zip/node chanzip))
+        base-dir "blarfnarg" ;; (java.util.UUID/randomUUID)
+        file-path (str base-dir "/" channel-name)]
+    (io/make-parents file-path)
+    (spit file-path channel-xml)))

 (defn makeitso
   "App logic"


replacing with cljs version

replacing with cljs version

--- dmmproj/src/dmmproj/core.clj
+++ dmmproj/src/dmmproj/core.clj
@@ -1,6 +0,0 @@
-(ns dmmproj.core)
-
-(defn foo
-  "I don't do a whole lot."
-  [x]
-  (println x "Hello, World!"))


RDC - rotate-cell function works correctly.

--- src/icfp2015/cell.clj
+++ src/icfp2015/cell.clj
@@ -11,8 +11,8 @@
 (defn cube->offset
   "Convert cube coordinate place to offset coordinate plane"
   [[x y z]]
-  (let [row z
-        col (+ x (/ (- z (bit-and z 1)) 2))]
+  (let [col (+ x (/ (- z (bit-and z 1)) 2))
+        row z]
     [row col]))

 (def offsets
@@ -25,14 +25,16 @@
   "Returns a function that rotates a cell around a pivot point"
   [pivot direction]
   (fn [cell]
-    (mapv + cell
-      (let [cell (offset->cube cell)
-            pivot (offset->cube pivot)
-            [x y z] (mapv - cell pivot)]
-      (cube->offset
+    (let [rotator (fn [[x y z]]
         (case direction
-          :counterclockwise (mapv - [z x y])
-          :clockwise (mapv - [y z x])))))))
+          :counterclockwise (mapv - [y z x])
+          :clockwise (mapv - [z x y])))]
+      (->> [cell pivot]
+        (mapv offset->cube)
+        (apply mapv -)
+        (rotator)
+        (cube->offset)
+        (mapv + pivot)))))

 (defn translate-dir [direction]
   (fn [cell]


Update ioframes.clj

Update ioframes.clj

--- src/iyye/ioframes.clj
+++ src/iyye/ioframes.clj
@@ -17,7 +17,8 @@
 (ns iyye.ioframes
   (:require
     [clojure.tools.logging :as log]
-    [iyye.persistence :as persistence]))
+    [iyye.persistence :as persistence]
+    [iyye.resource :as resource]))

 (defrecord InputSources [start-function input-listeners-list])
 (defn create-InputSources [start-function input-listeners-list] (InputSources. start-function input-listeners-list))
@@ -26,15 +27,14 @@
 (defrecord IO [name start-function inputs-list outputs-list])

 (defn create-IO [name start-fumction inputs-list outputs-list] (IO. name start-fumction inputs-list outputs-list))
-; list of IOs

 (defn process-input [IO input]
   (log/info (str "in: " (:name IO) input))
   (for [func (map :input-listeners-list IO)
         :when func] (func input))
-  (persistence/write-io-to-db IO :input input))
+  (persistence/write-io-to-db @resource/num-days IO :input input))

 (defn process-output [IO output]
   (log/info (str "out:" (:name IO) output))
   ((first (:outputs-list (:outputs-list IO))) output)
-  (persistence/write-io-to-db IO :output output))
+  (persistence/write-io-to-db @resource/num-days IO :output output))


Update ioframes.clj

Update ioframes.clj

--- src/iyye/ioframes.clj
+++ src/iyye/ioframes.clj
@@ -16,7 +16,8 @@

 (ns iyye.ioframes
   (:require
-    [clojure.tools.logging :as log]))
+    [clojure.tools.logging :as log]
+    [iyye.persistence :as persistence]))

 (defrecord InputSources [start-function input-listeners-list])
 (defn create-InputSources [start-function input-listeners-list] (InputSources. start-function input-listeners-list))
@@ -30,4 +31,5 @@
 (defn process-input [IO input]
   (log/info (str (:name IO) input))
   (for [func (map :input-listeners-list IO)
-        :when func] (func input)))
+        :when func] (func input))
+  (persistence/write-io-to-db IO input))


Added better timeout handling.

Added better timeout handling.

--- src/kademlia/core.clj
+++ src/kademlia/core.clj
@@ -8,6 +8,7 @@
 (def port 1665)
 (def bind-timeout 5000) ;; milliseconds

+(defn timeout [] (throw (new Exception "timeout!!!")))
 (defn uuid []
   (java.util.UUID/randomUUID))

@@ -39,10 +40,9 @@
 (defn bind-socket
   "Returns a deferred socket, all messages coming into the socket will be consumed by
    recv-handler. If port is 0 we will bind to an open port."
-  ([] (let [socket (deref (udp/socket {:port 0}) bind-timeout :timeout)]
-        (s/consume (partial #'recv-handler socket) socket)
-        socket) )
+  ([] (bind-socket 0))
   ([port] (let [socket (deref (udp/socket {:port port}) bind-timeout :timeout)]
+            (when (= :timeout socket) (timeout))
             (s/consume (partial #'recv-handler socket) socket)
             socket)))


Fix inline-exception warning properly

Fix inline-exception warning properly

--- src/lt/objs/eval.cljs
+++ src/lt/objs/eval.cljs
@@ -433,7 +433,8 @@
                 :triggers #{:click :double-click :clear!}
                 :tags #{:inline :inline.exception}
                 :init (fn [this info]
-                        (if (-> info :loc :line)
+                        (if-not (-> info :loc :line)
+                          (notifos/set-msg! (str (:ex info)) {:class "error"})
                           (let [content (->inline-exception this info)]
                             (object/merge! this (assoc info
                                                   :widget (ed/line-widget (ed/->cm-ed (:ed info))


Improve logs

Improve logs

--- jar-placement-lib/src/sixsq/slipstream/placement/core.clj
+++ jar-placement-lib/src/sixsq/slipstream/placement/core.clj
@@ -7,7 +7,6 @@
     [sixsq.slipstream.client.api.cimi :as cimi]
     [clojure.string :as string]))

-(def service-offer-currency-key :schema-org:priceCurrency)
 (def no-price -1)

 (defn string-or-nil?
@@ -33,8 +32,7 @@

 (defn- display-service-offer
   [service-offer]
-  (str "ServiceOffer "
-       (get-in service-offer [:connector :href]) "/"
+  (str (get-in service-offer [:connector :href]) "/"
        (instance-type service-offer)))

 (defn smallest-service-offer
@@ -45,7 +43,7 @@

 (defn- EUR-or-unpriced?
   [service-offer]
-  (let [price-currency (service-offer-currency-key service-offer)]
+  (let [price-currency (:schema-org:priceCurrency service-offer)]
     (or (nil? price-currency) (= "EUR" price-currency))))

 (defn- service-offer-for-connector
@@ -91,15 +89,14 @@
                        :values   [1]}])
     no-price))

-;; TODO hard-coded currency to EUR
-;; TODO hard-coded timecode
+;; TODO hard-coded currency to EUR and timecode to "HUR"
 (defn- price-connector
   [service-offers connector-name]
   (if-let [service-offer (service-offer-for-connector service-offers connector-name)]
-    (do
-      (log/info "Entity to price with " (display-service-offer service-offer))
+    (let [price (compute-price service-offer "HUR")]
+      (log/info "Priced " (display-service-offer service-offer) ":" price "EUR/h")
       {:name          connector-name
-       :price         (compute-price service-offer "HUR")
+       :price         price
        :currency      "EUR"
        :cpu           (cpu service-offer)
        :ram           (ram service-offer)
@@ -115,9 +112,7 @@
                           :else (< a b))) priced-coll))
 (defn- add-indexes
   [coll]
-  (map-indexed (fn [i e]
-                 (log/info "e = " e)
-                 (assoc e :index i)) coll))
+  (map-indexed (fn [i e] (assoc e :index i)) coll))

 (defn price-component
   [user-connectors service-offers component]
@@ -154,7 +149,7 @@
         connectors-clause   (str/join " or " connectors-clauses)
         cimi-filter         (cimi-and policy connectors-clause)
         cimi-filter         (cimi-and cimi-filter (clause-cpu-ram-disk component))]
-    (log/debug "the cimi-filter = " cimi-filter)
+    (log/debug "cimi-filter = " cimi-filter)
     cimi-filter))

 (defn- service-offers-by-component-policy
@@ -163,15 +158,14 @@

 (defn- place-rank-component
   [user-connectors component]
-  (log/info "component is: " component)
+  (log/info "Placing and ranking component " component)
+  (log/info "user-connectors = " user-connectors)
   (let [filtered-service-offers (service-offers-by-component-policy user-connectors component)]
-    (log/info "filtered-service-offers = " (map :id filtered-service-offers))
-    (log/info "user-connectors = " user-connectors)
+    (log/info "filtered-service-offers = " (map display-service-offer filtered-service-offers))
     (price-component user-connectors filtered-service-offers component)))

 (defn place-and-rank
   [request]
-  (log/info "Calling place-and-rank")
   (let [components (:components request)
         user-connectors (:user-connectors request)]
     {:components (map (partial place-rank-component user-connectors) components)}))


working solution

working solution

I've implemented this from scratch before you pushed our code to Github.

--- clojure/adventofcode/src/adventofcode/days/day4.clj
+++ clojure/adventofcode/src/adventofcode/days/day4.clj
@@ -1,34 +1,36 @@
-(ns adventofcode.days.day4
-  (:gen-class)
-  (:require [clojure.string :as str])
-  (:require [clojure.java.io :as io]))
+(ns advent.4.core
+  (:require [clojure.string :as s]
+            [clojure.java.io :as io]))

-(defn rooms []
-  (line-seq (io/reader "././files/day4_input.txt")))
+(defn room-name [room]
+  (subs 0 (- (count room) 11)))
+
+(defn sector-id [room]
+  (let [length (count room)]
+    (subs room (- length 10) (- length 7))))

 (defn checksum [room]
   (let [length (count room)]
     (subs room (- length 6) (- length 1))))

-(defn compare-item [[k1 v1][k2 v2]]
-  (or (> v1 v2)
-      (if (= v1 v2)
-        (<= (compare k1 k2) 0)
-        false)))
+(defn calc-checksum [room-name]
+  (->> (s/replace room-name "-" "")
+       (frequencies)
+       (sort-by val)
+       (reverse)
+       (partition-by val)
+       (map #(map first %))
+       (map sort)
+       (flatten)
+       (take 5)
+       (s/join)))

-(defn check-real-room [room]
-  (->> (sort compare-item
-             (-> room
-                 (subs 0 (- (count room) 10))
-                 (str/replace "-" "")
-                 (frequencies)))
-       (take 5)
-       (keys)))
+(defn sector-value [room]
+  (if (= (checksum room) (calc-checksum (room-name room)))
+    (Integer. (sector-id room))
+    0))

-(defn solution [room]
-    (if (= (set (check-real-room room)) (set (checksum room)))
-      (Integer. (subs room (- (count room) 10) (- (count room) 7)))
-      0))
+(defn rooms [path]
+  (line-seq (io/reader path)))

-(transduce (map #(do (println (check-real-room %1) (checksum %1) (solution %1)) (solution %1))) + (rooms))
-(reduce + (map solution (rooms)))
+(reduce + (map sector-value (rooms "././files/day4_input.txt")))


better handler for auth errors

better handler for auth errors

--- src/pc/http/sente.clj
+++ src/pc/http/sente.clj
@@ -1185,16 +1185,12 @@
                             :db (pcd/default-db)
                             :receive-instant (java.util.Date.))))
        (catch :status t
-         ;; XXX: fix this
-         (let [send-fn (:send-fn @sente-state)]
-           (log/error t)
-           ;; TODO: should this use the send-fn? We can do that too, I guess, inside of the defmethod.
-           ;; TODO: rip out sente and write a sensible library
-           (send-fn (:client-id req) [:frontend/error {:status-code (:status t)
-                                                       :error-msg (:error-msg t)
-                                                       :error-key (:error-key t)
-                                                       :event (:event req)
-                                                       :event-data (:?data req)}])))
+         (log/error t)
+         (send-msg req (:client-id req) [:frontend/error {:status-code (:status t)
+                                                          :error-msg (:error-msg t)
+                                                          :error-key (:error-key t)
+                                                          :event (:event req)
+                                                          :event-data (:?data req)}]))
        (catch Object e
          (log/error e)


docstring wording

docstring wording

--- src/test/clojure/clojure/test/check/test.cljc
+++ src/test/clojure/clojure/test/check/test.cljc
@@ -522,7 +522,7 @@

 (deftest f-map-respected-during-shrinking
   (testing
-    "Generators created fmap should have that function applied
+    "Generators created with fmap should have that function applied
     during shrinking"
     (is (= [50]
            (let [result (tc/quick-check 100


More likely to scroll

More likely to scroll

--- src/playmary/one.cljs
+++ src/playmary/one.cljs
@@ -235,7 +235,7 @@
          (or (= (prev-t :type) "touchmove")
              (and (= (prev-t :type) "touchstart")
                   (= (prev-t :age) 0)
-                  (> (distance (cur-t :position) (prev-t :position)) 10))))))
+                  (> (distance (cur-t :position) (prev-t :position)) 5))))))

 (defmulti handle-touch (fn [t touches out-c] (:type t)))


a whole new world

a whole new world

--- ros/angelic_planning/src/ros/robot_actions.clj
+++ ros/angelic_planning/src/ros/robot_actions.clj
@@ -1056,7 +1056,7 @@
 		:when goal]
 	    obj-name)]
     (if (empty? remaining-objects)
-        [[(make-arm-tuck-action right?)]]
+        [[(make-arm-tuck-action true)]]
       (for [obj remaining-objects]
 	[(make-move-to-goal-hla (:right? a) obj)
 	 (make-enforce-goal-action obj)


Update pod.clj

Update pod.clj

--- boot/pod/src/boot/pod.clj
+++ boot/pod/src/boot/pod.clj
@@ -2,6 +2,7 @@
   (:require
     [clojure.set                  :as set]
     [clojure.string               :as string]
+    [clojure.walk                 :as walk]
     [boot.util                    :as util]
     [boot.file                    :as file]
     [boot.xform                   :as xf]
@@ -465,7 +466,7 @@
   ([expr]
      (let [{:keys [meta? expr]} (read-string expr)]
        (binding [*print-meta* meta?]
-         (pr-str (clojure.walk/prewalk identity (eval expr))))))
+         (pr-str (walk/prewalk identity (eval expr))))))
   ([pod expr]
      (let [arg (pr-str {:meta? *print-meta* :expr expr})
            ret (with-invoke-in pod (boot.pod/eval-in* arg))]


Clean up example template a little bit.

Clean up example template a little bit.

--- src/pubhouse/play.clj
+++ src/pubhouse/play.clj
@@ -26,18 +26,18 @@

 (defn play-template
   [site content]
-  (hiccup/html
-   [:html
-    [:head
-     [:title (get-in site [:current-page :title])]
-     [:link {:rel "stylesheet" :src "style.css"}]]
-    [:body
-     (top-nav (get-in site [:current-page :url]) (dissoc site :current-page))
-     [:h1 (get-in site [:current-page :title])]
-     content
-     [:div.development
-      [:pre {:style "font-family: Courier;line-height: 1.5em;"}
-       (with-out-str (clojure.pprint/pprint site))]]]]))
+  (let [{:keys [url title content]} (:current-page site)]
+    (hiccup/html
+     [:html
+      [:head
+       [:title title]
+       [:link {:rel "stylesheet" :src "style.css"}]]
+      [:body
+       (top-nav url (dissoc site :current-page))
+       [:h1 title]
+       content
+       [:div.development
+        [:pre (with-out-str (clojure.pprint/pprint site))]]]])))

 (defn read-info
   "Reads the lines preceding the info block separator '===' in as a
@@ -58,8 +58,7 @@
 (defn play
   []
   (compile-site (fn [site reader writer]
-                  (.write writer
-                          (play-template site (read-content reader))))
+                  (.write writer (play-template site (read-content reader))))
                 {:site-root "example/content"
                  :info read-info
                  :build-root "example-build"


fix transformation of json with namespaced keywords (#1749)

--- db-binding/src/com/sixsq/slipstream/db/es/utils.clj
+++ db-binding/src/com/sixsq/slipstream/db/es/utils.clj
@@ -36,11 +36,32 @@

 (def ^:const max-result-window 200000)

+;;
+;; FIXME: This is a copy of code in the Clojure API client.  Collect into a utility.
+;;
+
+(defn kw->str
+  "Converts a keyword to the equivalent string without the leading colon and
+   **preserving** any namespace."
+  [kw]
+  (subs (str kw) 1))
+
+(defn key-fn
+  "Converts a keyword to the equivalent string without the leading colon and
+   **preserving** any namespace."
+  [k]
+  (if (keyword? k)
+    (kw->str k)
+    (str k)))
+
+(defn str->json [s]
+  (json/read-str s :key-fn keyword))
+
 (defn json->edn [json]
-  (when json (json/read-str json :key-fn keyword)))
+  (when json (str->json json)))

 (defn edn->json [edn]
-  (json/write-str edn))
+  (json/write-str edn :key-fn key-fn))

 (def ^:const doc-type "_doc")


allow custom command for installing npm packages from deps.cljs

fixes #404

--- src/main/shadow/cljs/devtools/server/npm_deps.clj
+++ src/main/shadow/cljs/devtools/server/npm_deps.clj
@@ -92,7 +92,23 @@
       (let [yarn-lock (io/file "yarn.lock")]
         (when (.exists yarn-lock)
           :yarn))
+
       :npm))
+
+(defn fill-packages-placeholder [install-cmd packages]
+  (let [full-cmd
+        (reduce
+          (fn [x y]
+            (if (= y :packages)
+              (into x packages)
+              (conj x y)))
+          []
+          install-cmd)]
+
+    ;; if no :packages was replaced just append the packages
+    (if (not= full-cmd install-cmd)
+      full-cmd
+      (into install-cmd packages))))

 (defn install-deps [config deps]
   (let [args
@@ -100,15 +116,17 @@
           (str id "@" version))

         install-cmd
-        (case (guess-node-package-manager config)
-          :yarn
-          ["yarn" "add"]
-          :npm
-          ["npm" "install" "--save"])
+        (or (get-in config [:node-modules :install-cmd])
+            (case (guess-node-package-manager config)
+              :yarn
+              ["yarn" "add"]
+              :npm
+              ["npm" "install" "--save"]))

         full-cmd
-        (into install-cmd args)
-
+        (fill-packages-placeholder install-cmd args)
+
+        ;; FIXME: replace this on windows to properly locate npm/yarn binaries instead
         full-cmd
         (if (str/includes? (System/getProperty "os.name") "Windows")
           (into ["cmd" "/C"] full-cmd)
@@ -128,6 +146,13 @@
     (.start (Thread. (bound-fn [] (util/pipe proc (.getErrorStream proc) *err*))))

     (.waitFor proc)))
+
+(comment
+  (install-deps
+    {:node-modules
+     {:install-cmd ["hello" :packages "world"]}}
+    [{:id "hello"
+      :version "1.2.3"}]))

 (defn get-deps-from-classpath []
   (let [deps


:sparkles: Improve grid performance (now using svg patterns).

--- frontend/src/uxbox/main/ui/workspace/grid.cljs
+++ frontend/src/uxbox/main/ui/workspace/grid.cljs
@@ -8,35 +8,36 @@
 (ns uxbox.main.ui.workspace.grid
   (:require
    [cuerdas.core :as str]
+   [lentes.core :as l]
    [rumext.alpha :as mf]
+   [uxbox.main.refs :as refs]
    [uxbox.main.constants :as c]))

 ;; --- Grid (Component)

-(defn- horizontal-line
-  [width acc value]
-  (let [pos value]
-    (conj acc (str/format "M %s %s L %s %s" 0 pos width pos))))
-
-(defn- vertical-line
-  [height acc value]
-  (let [pos value]
-    (conj acc (str/format "M %s %s L %s %s" pos 0 pos height))))
-
-(defn- make-grid-path
-  [metadata]
-  (let [x-ticks (range 0 c/viewport-width (:grid-x-axis metadata 10))
-        y-ticks (range 0 c/viewport-height (:grid-y-axis metadata 10))]
-    (as-> [] $
-      (reduce (partial vertical-line c/viewport-height) $ x-ticks)
-      (reduce (partial horizontal-line c/viewport-width) $ y-ticks)
-      (str/join " " $))))
+(def options-iref
+  (-> (l/key :options)
+      (l/derive refs/workspace-data)))

 (mf/defc grid
-  [{:keys [page] :as props}]
-  (let [metadata (:metadata page)
-        color (:grid-color metadata "#cccccc")
-        path (mf/use-memo {:deps #js [metadata]
-                           :fn #(make-grid-path metadata)})]
-    [:g.grid {:style {:pointer-events "none"}}
-     [:path {:d path :stroke color :opacity "0.3"}]]))
+  {:wrap [mf/wrap-memo]}
+  [props]
+  (prn "grid$render")
+  (let [options (mf/deref options-iref)
+        width (:grid-x options 10)
+        height (:grid-y options 10)
+        color (:grid-color options "#cccccc")]
+    [:g.grid
+     [:defs
+      [:pattern {:id "grid-pattern"
+                 :x "0" :y "0"
+                 :width width :height height
+                 :patternUnits "userSpaceOnUse"}
+       [:path {:d (str/format "M 0 %s L %s %s L %s 0" height width height width)
+               :fill "transparent"
+               :stroke color}]]]
+     [:rect {:style {:pointer-events "none"}
+             :x 0 :y 0
+             :width "100%"
+             :height "100%"
+             :fill "url(#grid-pattern)"}]]))


Remove unnecessary imports

Remove unnecessary imports

--- desktop/src/nightmod/core/desktop_launcher.clj
+++ desktop/src/nightmod/core/desktop_launcher.clj
@@ -13,9 +13,7 @@
            [java.awt.event ComponentAdapter WindowAdapter]
            [javax.swing JLayeredPane]
            [com.badlogic.gdx.backends.lwjgl LwjglApplication]
-           [org.lwjgl.input Keyboard]
-           [org.pushingpixels.substance.api SubstanceLookAndFeel]
-           [org.pushingpixels.substance.api.skin GraphiteSkin])
+           [org.lwjgl.input Keyboard])
   (:gen-class))

 ; allow s/select to work with Canvas


Adding raw osx-ga plans.

Adding raw osx-ga plans.

--- src-cljs/frontend/components/org_settings.cljs
+++ src-cljs/frontend/components/org_settings.cljs
@@ -301,12 +301,19 @@
             [:dt question]
             [:dd answer]))]]))))

-(defn osx-plan-ga [{:keys [plan-type plan price current-plan]} owner]
+(defn osx-plan-ga [{:keys [title price container-count daily-build-count max-minutes support-level team-size]} owner]
   (reify
     om/IRender
     (render [_]
       (html
-        [:h1 "An osx plan"]))))
+        [:div.card
+         [:div title]
+         [:div "$" price "/mo"]
+         [:div container-count " OS X containers"]
+         [:div "Recommended for teams that do " daily-build-count " builds/day"]
+         [:div max-minutes " max minutes/month"]
+         [:div support-level]
+         [:div "Recommended for " team-size " team members"]]))))

 (defn osx-plan [{:keys [plan-type plan price current-plan]} owner]
   (reify
@@ -341,6 +348,38 @@
                 :data-failed-text plan-img
                 :on-click new-plan-fn}
                plan-img])))))))
+(def osx-plans
+  {:ga [{:title "SEED"
+         :price 39
+         :container-count "2"
+         :daily-build-count "1-2"
+         :max-minutes "500"
+         :support-level "Community support"
+         :team-size "1-2"}
+
+        {:title "STARTUP"
+         :price 129
+         :container-count "5"
+         :daily-build-count "2-5"
+         :max-minutes "1,800"
+         :support-level "Engineer support"
+         :team-size "unlimited"}
+
+        {:title "GROWTH"
+         :price 249
+         :container-count "5"
+         :daily-build-count "4-10"
+         :max-minutes "5,000"
+         :support-level "Engineer support"
+         :team-size "unlimited"}
+
+        {:title "MOBILE FOCUSED"
+         :price 449
+         :container-count "10"
+         :daily-build-count "more than 10"
+         :max-minutes "25,000"
+         :support-level "Priority support & Account manager"
+         :team-size "unlimited"}]})

 (defn osx-plans-list-ga [plan owner]
   (reify
@@ -353,7 +392,7 @@
             [:legend (str "iOS Plans")]
             [:p "Your selection selection below only applies to iOS service and will not affect Linux Containers."]]
            [:div.plan-selection
-            (om/build osx-plan-ga {:plan plan :price 0 :plan-type "" :current-plan current-plan})]])))))
+            (om/build-all osx-plan-ga (:ga osx-plans))]])))))

 (defn osx-plans-list [plan owner]
   (reify


add-containers is not the name of the subpage.

--- src-cljs/frontend/components/org_settings.cljs
+++ src-cljs/frontend/components/org_settings.cljs
@@ -909,7 +909,7 @@
               ;; make sure to link to the add-containers page of the plan's org,
               ;; in case of piggiebacking.
               [:a {:href (routes/v1-org-settings-subpage {:org (:org_name plan)
-                                                          :subpage "add-containers"})}
+                                                          :subpage "containers"})}
                "add more"]
               " at $" container-cost " per container for more parallelism and shorter queue times."))])
         (when  (pm/freemium? plan)


State.

State.

--- test/com/nomistech/clojure_the_language/c_400_state_and_concurrency/s_010_intro.clj
+++ test/com/nomistech/clojure_the_language/c_400_state_and_concurrency/s_010_intro.clj
@@ -2,7 +2,7 @@
   (:require [midje.sweet :refer :all]))

 ;;;; ___________________________________________________________________________
-;;;; State management and concurrency and without locks
+;;;; State and Concurrency

 ;;;; Clojure is an impure functional language
 ;;;; - It supports side effects


Remove the no-op form returned by validates now that we check for a return value before including anything in the generated init-model expansion.

--- clj_record/validation.clj
+++ clj_record/validation.clj
@@ -23,4 +23,4 @@
           validations (or (@metadata :validations) [])]
       (ref-set metadata
         (assoc @metadata :validations (conj validations [(keyword (name attribute-name)) message (eval function)])))))
-  '(identity 1)) ; XXX: Have to return a no-op form since we don't need any defs.
+  nil)


lein: add ultra to color tests

lein: add ultra to color tests

Signed-off-by: Laurent Senta <93e2db26c7714cc3fb230d05f2fbedc450bb1db9@gmail.com>

--- lein.symlink/profiles.clj
+++ lein.symlink/profiles.clj
@@ -1,22 +1,21 @@
 {:user {
-         :dependencies [
-                        [cljfmt "0.1.10"]
-                        [jonase/eastwood "0.2.1" :exclusions [org.clojure/clojure]]
-                        ]
-        :test-refresh {:notify-command ["terminal-notifier" "-title" "Tests" "-message"]}
-         :plugins [
-                    [lein-midje "3.1.3"]
-                    [lein-ancient "0.5.5"]
-                    [lein-kibit "0.0.8"]
-                    [jonase/eastwood "0.2.1" :exclusions [org.clojure/clojure]]
-                    [lein-bikeshed "0.1.8"]
-                    [slamhound "1.5.5"]
-                    [lein-ubersource "0.1.1"]
-                    [com.jakemccrary/lein-test-refresh "0.11.0"]
-                    ]
-        :android {
-                  :sdk-path "/Users/lsenta/dev/android-sdk-macosx"
-                  }
-         :aliases {
-                    "slamhound" ["run" "-m" "slam.hound"]
-                  }}}
+        :dependencies [
+                       [cljfmt "0.1.10"]
+                       [jonase/eastwood "0.2.1" :exclusions [org.clojure/clojure]]
+                       ]
+        :test-refresh {:notify-command ["reattach-to-user-namespace" "terminal-notifier" "-title" "Tests" "-message"]}
+        :plugins [
+                  [lein-midje "3.1.3"]
+                  [lein-ancient "0.5.5"]
+                  [lein-kibit "0.0.8"]
+                  [jonase/eastwood "0.2.1" :exclusions [org.clojure/clojure]]
+                  [lein-bikeshed "0.1.8"]
+                  [slamhound "1.5.5"]
+                  [lein-ubersource "0.1.1"]
+                  [com.jakemccrary/lein-test-refresh "0.13.0"]
+                  [pjstadig/humane-test-output "0.7.1"]
+                  [venantius/ultra "0.4.0"]
+                  ]
+        :ultra {:color-scheme :solarized_dark}
+        :android {:sdk-path "/Users/lsenta/dev/android-sdk-macosx"}
+        :aliases {"slamhound" ["run" "-m" "slam.hound"]}}}


small formatting change

small formatting change

--- test/config/migrations/20111130220559_initial.clj
+++ test/config/migrations/20111130220559_initial.clj
@@ -51,8 +51,7 @@
             [:id "BIGSERIAL" "PRIMARY KEY"]
             [:domain "TEXT" "NOT NULL UNIQUE"]
             [:owner "int" "NOT NULL REFERENCES login(id) ON DELETE CASCADE"]
-            [:blogid "int" "REFERENCES blog(id) ON DELETE SET NULL"])
-        )
+            [:blogid "int" "REFERENCES blog(id) ON DELETE SET NULL"]))
     (println "config.migrations.20111130220559-initial up done"))

 (defn down
@@ -66,6 +65,5 @@
         (sql/drop-table :s3reference)
         (sql/drop-table :post)
         (sql/drop-table :blog)
-        (sql/drop-table :login)
-        )
+        (sql/drop-table :login))
     (println "config.migrations.20111130220559-initial down done"))


Fix day 2 commenting-out to make docstring accurate

--- advent-of-code-day-2/src/advent_of_code_day_2/core.clj
+++ advent-of-code-day-2/src/advent_of_code_day_2/core.clj
@@ -31,7 +31,7 @@
   (->> (slurp *in*)
        (string/split-lines)
        (map parse-dimensions)
-       #_(map wrapping-area)
-       (map ribbon-length)
+       (map wrapping-area)
+       #_(map ribbon-length)
        (reduce +)
        (println)))


Pend this, too, for the time being

Pend this, too, for the time being

--- integration-tests/apps/caching/counter/test/counter/test/locking.clj
+++ integration-tests/apps/caching/counter/test/counter/test/locking.clj
@@ -28,13 +28,15 @@
                         (msg/unlisten listener))))

 (deftest correct-counting-with-pessimistic-locking
-  (csh/put (:pessimistic caches) :count 0)
-  (is (= 0 (:count (:pessimistic caches))))
-  (dotimes [_ 10] (msg/publish "/queue/work" {:name :pessimistic :key :count}))
-  (log/info "JC: published 10 messages")
-  (is (every? (partial = :pessimistic) (take 10 (msg/message-seq "/queue/done" :timeout 60000))))
-  (log/info "JC: pessimistic done" (:count (:pessimistic caches)))
-  (is (= 10 (:count (:pessimistic caches)))))
+  (println "PENDING: fix prior to release")
+  ;; (csh/put (:pessimistic caches) :count 0)
+  ;; (is (= 0 (:count (:pessimistic caches))))
+  ;; (dotimes [_ 10] (msg/publish "/queue/work" {:name :pessimistic :key :count}))
+  ;; (log/info "JC: published 10 messages")
+  ;; (is (every? (partial = :pessimistic) (take 10 (msg/message-seq "/queue/done" :timeout 60000))))
+  ;; (log/info "JC: pessimistic done" (:count (:pessimistic caches)))
+  ;; (is (= 10 (:count (:pessimistic caches))))
+  )

 (deftest correct-counting-with-optimistic-locking
   (println "PENDING: fix prior to release")


Reset fileset should merge changes on top of source files (fixes #330)

--- boot/core/src/boot/core.clj
+++ boot/core/src/boot/core.clj
@@ -662,13 +662,13 @@
   returning a new immutable fileset. When called with no args returns a new
   fileset containing only the latest project files."
   [& [fileset]]
-  (sync-user-dirs!)
-  (-> (if-not fileset
-        (new-fileset)
-        (rm fileset (user-files fileset)))
-      (add-user-asset (first (user-asset-dirs)))
-      (add-user-source (first (user-source-dirs)))
-      (add-user-resource (first (user-resource-dirs)))))
+  (let [fileset (when fileset (rm fileset (user-files fileset)))]
+    (sync-user-dirs!)
+    (-> (new-fileset)
+        (add-user-asset (first (user-asset-dirs)))
+        (add-user-source (first (user-source-dirs)))
+        (add-user-resource (first (user-resource-dirs)))
+        (update-in [:tree] merge (:tree fileset)))))

 (defn reset-build!
   "Resets mutable build state to default values. This includes such things as


Fix issue with cli task option parsing

Fix issue with cli task option parsing

--- boot/core/src/boot/core.clj
+++ boot/core/src/boot/core.clj
@@ -261,10 +261,11 @@
         (when-not (and op (:boot.core/task (meta op)))
           (throw (IllegalArgumentException. (format "No such task (%s)" op-str))))
         (let [spec   (:argspec (meta op))
-              parsed (cli/parse-opts args spec :in-order true)]
+              parsed (cli/parse-opts args spec :in-order true)
+              opts   (->> parsed :options (mapcat identity))]
           (when (seq (:errors parsed))
             (throw (IllegalArgumentException. (string/join "\n" (:errors parsed)))))
-          (recur (conj ret (apply (var-get op) args)) (:arguments parsed)))))))
+          (recur (conj ret (apply (var-get op) opts)) (:arguments parsed)))))))

 (def ^:dynamic *warnings* nil)


Update docstring

Update docstring

--- src/clojure/clojurewerkz/cassaforte/client.clj
+++ src/clojure/clojurewerkz/cassaforte/client.clj
@@ -118,7 +118,8 @@
 ;;

 (defmacro prepared
-  "Executes a prepared statement"
+  "Same as cassaforte.policies/forcing-prepared-statements. Kept for backwards
+   compatibility."
   [& body]
   `(binding [hayt/*prepared-statement* true
              hayt/*param-stack*        (atom [])]


Print frontend host/port information

Print frontend host/port information

--- src/clojure/funcatron/tron/modes/tron_mode.clj
+++ src/clojure/funcatron/tron/modes/tron_mode.clj
@@ -372,7 +372,7 @@
      }))

 (defmethod dispatch-tron-message "awake"
-  [{:keys [from type] :as msg} _ {:keys [::network] :as state}]
+  [{:keys [from type host_info] :as msg} _ {:keys [::network] :as state}]
   (info (str "awake from " msg))
   (clean-network state)
   (swap! network assoc from
@@ -387,6 +387,9 @@
     (do
       (send-route-map from state)
       (remove-other-instances-of-this-frontend msg state)
+      (when-let [{:keys [host port]} host_info]
+        (when (and (not-empty host) (not-empty port))
+          (info (str "Frontend at http://" host ":" port))))
       )

     (= "runner" type)


parallel build enabled

parallel build enabled

--- examples/todomvc/project.clj
+++ examples/todomvc/project.clj
@@ -1,7 +1,7 @@
 (defproject
   todomvc "0.1.0-SNAPSHOT"
   :dependencies [[org.clojure/clojure "1.8.0"]
-                 [org.clojure/clojurescript "1.7.170"]
+                 [org.clojure/clojurescript "1.7.228"]

                  [reagent "0.5.1" :exclusions [cljsjs/react]]
                  [cljsjs/react-with-addons "0.13.3-0"]
@@ -30,7 +30,8 @@
                                        :output-to            "resources/public/js/compiled/frontend.js"
                                        :output-dir           "resources/public/js/compiled/out"
                                        :source-map-timestamp true
-                                       :compiler-stats       true}
+                                       :compiler-stats       true
+                                       :parallel-build true}
                         :figwheel     {:on-jsload     "app.core/on-jsload"
                                        :before-jsload "app.core/before-jsload"}}

@@ -40,7 +41,8 @@
                                        :output-to      "resources/public/js/compiled/frontend.js"
                                        :optimizations  :advanced
                                        :pretty-print   false
-                                       :compiler-stats true}}
+                                       :compiler-stats true
+                                       :parallel-build true}}

                        #_{:id           "test"
                           :source-paths ["src/frontend" "test"]


(maint) Set environment_timeout to 0 in tasks tests

Previously environment_timeout was set to unlimited in the tasks tests.
Due to a puppet bug, we still saw new environments as they were created.
Once that bug was fixed, new environments would not be seen with it set
to unlimited because they would not be created until after puppet had
started up. Now we set it to 0 to ensure new environments are seen. We
also no longer need to generate environment.conf, so that call is
removed from the fixture creation.

--- test/integration/puppetlabs/services/jruby/tasks_test.clj
+++ test/integration/puppetlabs/services/jruby/tasks_test.clj
@@ -22,7 +22,7 @@
      :master-conf-dir (.getAbsolutePath conf-dir)})))

 (def puppet-conf-file-contents
-  "[main]\nenvironment_timeout=unlimited\nbasemodulepath=$codedir/modules\n")
+  "[main]\nenvironment_timeout=0\nbasemodulepath=$codedir/modules\n")

 (def ^:dynamic *code-dir* nil)
 (def ^:dynamic *jruby-service* nil)
@@ -93,7 +93,6 @@

 (defn create-env
   [env-dir tasks]
-  (testutils/create-env-conf env-dir "")
   (gen-empty-tasks env-dir tasks))

 (defn env-dir


[tests] Enable all the tests.

[tests] Enable all the tests.

--- test/cortex/test.cljs
+++ test/cortex/test.cljs
@@ -3,12 +3,16 @@
             [cortex.wiring-test]
             [cortex.function-test]
             [cortex.network-test]
-            [cortex.normaliser-test]))
+            [cortex.normaliser-test]
+            [cortex.optimise-test]
+            [cortex.util-test]))

 (enable-console-print!)

 (doo-tests 'cortex.wiring-test
            'cortex.function-test
+           'cortex.util-test
            'cortex.network-test
-           'cortex.normaliser-test)
+           'cortex.normaliser-test
+           'cortex.optimise-test)


run a bunch of basic passes

run a bunch of basic passes

--- src/main/clojure/clojure/tools/analyzer/js.clj
+++ src/main/clojure/clojure/tools/analyzer/js.clj
@@ -18,7 +18,12 @@
              [ast :refer [prewalk]]
              [env :as env :refer [*env*]]]
             [clojure.tools.analyzer.passes
-             [cleanup :refer [cleanup]]]
+             [source-info :refer [source-info]]
+             [cleanup :refer [cleanup]]
+             [elide-meta :refer [elide-meta elides]]
+             [warn-earmuff :refer [warn-earmuff]]
+             [add-binding-atom :refer [add-binding-atom]]
+             [uniquify :refer [uniquify-locals]]]
             [clojure.tools.analyzer.js.utils
              :refer [desugar-ns-specs validate-ns-specs ns-resource source-path res-path]]
             [clojure.java.io :as io]
@@ -61,6 +66,7 @@
    :locals     {}
    :ns         *ns*})

+;; TODO handle js-ns/foo
 (defn desugar-host-expr [[op & expr :as form]]
   (if (symbol? op)
     (let [opname (name op)]
@@ -262,7 +268,17 @@
        {:meta metadata}))))

 (defn run-passes [ast]
-  (-> ast))
+  (binding [elides (into #{:line :column :end-line :end-column :file :source} elides)]
+    (-> ast
+
+      uniquify-locals
+      add-binding-atom
+
+      (prewalk (fn [ast]
+                 (-> ast
+                   warn-earmuff
+                   source-info
+                   elide-meta))))))

 (defn analyze
   ([form] (analyze form (empty-env) {}))


make uri matching a little less strict

make uri matching a little less strict

--- src/adzerk/boot_reload/reload.cljs
+++ src/adzerk/boot_reload/reload.cljs
@@ -7,13 +7,17 @@

 (def ^:private page-uri (goog.Uri. (.. js/window -location -href)))

+(defn- substring? [s subs]
+  (pos? (.lastIndexOf s subs)))
+
 (defn- reload-page! []
   (.reload (.-location js/window)))

 (defn- changed-href? [href-or-uri changed]
   (when href-or-uri
-    (let [uri (goog.Uri. href-or-uri)]
-      (when (contains? changed (.getPath (.resolve page-uri uri)))
+    (let [uri  (goog.Uri. href-or-uri)
+          path (.getPath (.resolve page-uri uri))]
+      (when (not-empty (filter #(substring? % path) changed))
         uri))))

 (defn- ends-with? [s pat]
@@ -33,9 +37,8 @@
         (when-let [href-uri (changed-href? (.-src image) changed)]
           (set! (.-src image) (.toString (.makeUnique href-uri))))))))

-(defn- reload-js [changed
-                  {:keys [on-jsload]
-                   :or {on-jsload identity}}]
+(defn- reload-js [changed {:keys [on-jsload]
+                           :or {on-jsload identity}}]
   (let [js-files (filter #(ends-with? % ".js") changed)]
     (if (seq js-files)
       (-> #(-> % guri/parse .makeUnique jsloader/load)


fix typo (really this time)

fix typo (really this time)

--- src/babel/italiano/morphology.cljc
+++ src/babel/italiano/morphology.cljc
@@ -1323,7 +1323,7 @@
                                                                     true
                                                                     (dissoc (copy lexeme) :serialized))]
                                                    (if (not (= :none (get-in lexeme path :none)))
-                                                     (do (log/debug (str (first lexeme-kv) " generating lexeme exceptional surface form: " (surface-form-fn lexeme)
+                                                     (do (log/debug (str (first lexeme-kv) " generating lexeme exceptional surface form: " (surface-form-fn lexeme)))
                                                          (list {(surface-form-fn lexeme)
                                                                 (merge
                                                                  lexeme


avoid unnecessary copy

avoid unnecessary copy

--- src/babel/italiano/morphology.cljc
+++ src/babel/italiano/morphology.cljc
@@ -1427,7 +1427,9 @@
                                                                     (= lexeme :top)
                                                                     :top
                                                                     true
-                                                                    (dissoc (copy lexeme) :serialized))]
+                                                                    lexeme)]
+                                                                    ;; not copying this time
+;;                                                                    (dissoc (copy lexeme) :serialized))]
                                                    (if (not (= :none (get-in lexeme path :none)))
                                                      (do (log/debug (str (first lexeme-kv) " generating lexeme exceptional surface form: " (surface-form-fn lexeme)))
                                                          (list {(surface-form-fn lexeme)


handle noun exceptions

handle noun exceptions

--- src/babel/italiano/morphology.cljc
+++ src/babel/italiano/morphology.cljc
@@ -1648,6 +1648,13 @@
                              (fn [val]
                                {:italiano {:agr {:gender :fem
                                                  :number :plur}}})}
+                            ;; nouns
+                            {:path [:italiano :plur]
+                             :merge-fn
+                             (fn [val]
+                               {:synsem {:cat :noun}
+                                :italiano {:agr {:number :plur}}})}
+
                             ])]
         (concat result (exception-generator (rest lexicon)))))))


Enable `save` snippet for cljs as it is supported by p5js. Issue #255.

--- src/cljc/quil/snippets/output.cljc
+++ src/cljc/quil/snippets/output.cljc
@@ -16,14 +16,13 @@
      (q/box 100)
      (q/end-raw)))

-#?(:clj
-   (defsnippet save
-     "save"
-     {:renderer :p3d}
+(defsnippet save
+  "save"
+  {:renderer :p3d}

-     (q/camera 150 150 150 0 0 0 0 0 1)
-     (q/box 100)
-     (q/save "generated/box.png")))
+  (q/camera 150 150 150 0 0 0 0 0 1)
+  (q/box 100)
+  (q/save "generated/box.png"))

 #?(:clj
    (defsnippet save-frame


playing with types

playing with types

--- src/cljs/triboard/logic/board.cljs
+++ src/cljs/triboard/logic/board.cljs
@@ -2,6 +2,7 @@
   (:require
     [cljs.spec :as s :include-macros true]
     [cljs.spec.test :as stest :include-macros true]
+    [cljs.spec.impl.gen :as gen]
     [triboard.logic.constants :as cst]
     ))

@@ -37,12 +38,18 @@
 ;; Public Types
 ;; -----------------------------------------

-(s/def ::board (s/coll-of cst/cell?))
+(s/def ::board (s/coll-of (s/coll-of cst/cell? :count 11) :count 16))
 (s/def ::coord (s/tuple integer? integer?))

 (s/fdef new-board :ret ::board)
-(s/fdef to-iterable :args ::board :ret (s/coll-of (s/tuple ::coord cst/cell?)))
-(s/fdef empty-cells :args ::board :ret (s/coll-of cst/cell?))
+
+(s/fdef to-iterable
+  :args (s/cat :board ::board)
+  :ret (s/coll-of (s/tuple ::coord cst/cell?)))
+
+(s/fdef empty-cells
+  :args (s/cat :board ::board)
+  :ret (s/coll-of ::coord))

 (defn board?
   "A board is a vector of vector of cells"
@@ -65,7 +72,6 @@
 (defn new-board
   "Creates a new board with initial positions of each players"
   []
-  {:post [(board? %)]}
   (reduce
     (fn [r [color point]] (assoc-in r point color))
     empty-board (init-positions)))
@@ -85,3 +91,8 @@
   (eduction
     (filter #(= (get-cell-at board %) :empty))
     cst/all-positions))
+
+;; (s/check-asserts true)
+
+;; You can test this function by using
+;; (empty-cells (first (gen/sample (s/gen ::board) 1)))


Added function for extracting processing level.

--- src/cmr/opendap/ous/collection.clj
+++ src/cmr/opendap/ous/collection.clj
@@ -43,3 +43,7 @@
 (defn extract-service-ids
   [entry]
   (sort (get-in entry [:associations :services])))
+
+(defn extract-processing-level
+  [entry]
+  (get-in entry [:umm :ProcessingLevel :Id]))


fix(frontend): adapt colorpalette to rumext changes

--- frontend/src/uxbox/main/ui/workspace/colorpalette.cljs
+++ frontend/src/uxbox/main/ui/workspace/colorpalette.cljs
@@ -83,7 +83,7 @@
            [:option {:key (str (:id collection))
                      :value (pr-str (:id collection))}
             (:name collection)])]
-        #_[:div.color-palette-buttons
+        [:div.color-palette-buttons
            [:div.btn-palette.edit.current i/pencil]
            [:div.btn-palette.create i/close]]]

@@ -104,9 +104,9 @@

        ;; FIXME Scroll on click does not work
        [:span.right-arrow
-        (if (< offset invisible)
-          {:on-click #(.scrollBy (dom/get-element "color-palette-inside") offset 0)}
-          {})
+        {:on-click (fn [event]
+                     (when (< offset invisible)
+                       (.scrollBy (dom/get-element "color-palette-inside") offset 0)))}
         i/arrow-slide]

        [:span.close-palette {:on-click close}