CMR-8762 updates geotools libraries in search-app

--- search-app/project.clj
+++ search-app/project.clj
@@ -39,9 +39,9 @@
                  [org.clojure/tools.reader "1.3.2"]
                  [org.eclipse.emf/org.eclipse.emf.ecore "2.23.0"]
                  [org.eclipse.emf/org.eclipse.emf.common "2.21.0"]
-                 [org.geotools/gt-shapefile "24.6"]
+                 [org.geotools/gt-shapefile "29-SNAPSHOT"]
                  [org.geotools/gt-geojsondatastore "24.6"]
-                 [org.geotools.xsd/gt-xsd-kml "24.6"]
+                 [org.geotools.xsd/gt-xsd-kml "27.1"]
                  [org.mozilla/rhino "1.7.12"]
                  [ring/ring-codec "1.1.3"]
                  [ring/ring-core "1.9.2"]
@@ -53,7 +53,8 @@
                  [metosin/ring-swagger "0.22.14"]
                  [prismatic/schema "1.1.9"]]
   :repositories [["osgeo" "https://download.osgeo.org/webdav/geotools"]
-                 ["geo" "https://repo.osgeo.org/repository/release"]]
+                 ["geo" "https://repo.osgeo.org/repository/release"]
+                 ["geo-snapshot" "https://repo.osgeo.org/repository/snapshot"]]
   :plugins [[lein-exec "0.3.7"]
             [test2junit "1.3.3"]]
   :repl-options {:init-ns user


CMR-2459 DRY up tests a little

CMR-2459 DRY up tests a little

--- system-int-test/test/cmr/system_int_test/search/collection_concept_retrieval_test.clj
+++ system-int-test/test/cmr/system_int_test/search/collection_concept_retrieval_test.clj
@@ -152,14 +152,17 @@
         result      (d/ingest-concept-with-metadata {:provider-id  "PROV1"
                                                      :concept-type :collection
                                                      :format       mime-type
-                                                     :metadata     json})]
+                                                     :metadata     json})
+        concept-id  (:concept-id result)
+        retrieve    (fn [revision-id]
+                      (search/retrieve-concept concept-id
+                                               revision-id
+                                               {:query-params {:token user1-token}
+                                                :accept       "application/vnd.nasa.cmr.umm+json"}))]
     (index/wait-until-indexed)

     (testing "without revision id"
-      (let [response     (search/retrieve-concept (:concept-id result)
-                                                  nil
-                                                  {:query-params {:token user1-token}
-                                                   :accept       "application/vnd.nasa.cmr.umm+json"})
+      (let [response     (retrieve nil)
             content-type (get-in response [:headers "Content-Type"])]
         (is (= 200 (:status response)))
         (is (= json (:body response)))
@@ -167,10 +170,7 @@
         (is (= "1.0" (mt/version-of content-type)))))

     (testing "with a revision id"
-      (let [response     (search/retrieve-concept (:concept-id result)
-                                                  1
-                                                  {:query-params {:token user1-token}
-                                                   :accept       "application/vnd.nasa.cmr.umm+json"})
+      (let [response     (retrieve 1)
             content-type (get-in response [:headers "Content-Type"])]
         (is (= 200 (:status response)))
         (is (= json (:body response)))


Only one file should be changed for easy-fix

--- src-clj/acha/achievement.clj
+++ src-clj/acha/achievement.clj
@@ -172,34 +172,36 @@
 (def easy-fix
   [:easy-fix
    (fn [{:keys [changed-files author time]}]
-     (when (some (fn [{diff :diff}]
-                   (or
-                     ; swap two nonadjacent lines
-                     (and
-                       (= 2 (count diff))
-                       ; one not blank lines
-                       (->> (for [d [0 1], m [:added :removed]]
-                              (and (= 1 (count (get-in diff [d m])))
-                                   (not (string/blank? (get-in diff [d m 0 0])))))
-                            (every? true?))
-                       ; content added in one edit == removed in another edit
-                       (= (get-in diff [0 :added 0 0])   (get-in diff [1 :removed 0 0]))
-                       (= (get-in diff [1 :added 0 0])   (get-in diff [0 :removed 0 0])))
-
-                     ; swap two adjacent lines
-                     (and
-                       (= 1 (count diff))
-                       ; one line
-                       (= 1 (count (get-in diff [0 :added])))
-                       (= 1 (count (get-in diff [0 :removed])))
-                       ; not blank line
-                       (not (string/blank? (get-in diff [0 :added 0 0])))
-                       ; the smae
-                       (= (get-in diff [0 :added 0 0])   (get-in diff [0 :removed 0 0]))
-                       ; adjacent
-                       (= 1 (Math/abs (- (get-in diff [0 :added 0 1])
-                                         (get-in diff [0 :removed 0 1])))))))
-                 changed-files)
+     (when (and
+             ; only one file was changed
+             (= (count changed-files) 1)
+             (let [diff (get-in changed-files [0 :diff])]
+               (or
+                 ; swap two nonadjacent lines
+                 (and
+                   (= 2 (count diff))
+                   ; one not blank lines
+                   (->> (for [d [0 1], m [:added :removed]]
+                          (and (= 1 (count (get-in diff [d m])))
+                               (not (string/blank? (get-in diff [d m 0 0])))))
+                        (every? true?))
+                   ; content added in one edit == removed in another edit
+                   (= (get-in diff [0 :added 0 0])   (get-in diff [1 :removed 0 0]))
+                   (= (get-in diff [1 :added 0 0])   (get-in diff [0 :removed 0 0])))
+
+                 ; swap two adjacent lines
+                 (and
+                   (= 1 (count diff))
+                   ; one line
+                   (= 1 (count (get-in diff [0 :added])))
+                   (= 1 (count (get-in diff [0 :removed])))
+                   ; not blank line
+                   (not (string/blank? (get-in diff [0 :added 0 0])))
+                   ; the smae
+                   (= (get-in diff [0 :added 0 0])   (get-in diff [0 :removed 0 0]))
+                   ; adjacent
+                   (= 1 (Math/abs (- (get-in diff [0 :added 0 1])
+                                     (get-in diff [0 :removed 0 1]))))))))
        {:username author
         :time time}))])


reconnect ws when server goes away

reconnect ws when server goes away

--- src-cljs/frontend/sente.cljs
+++ src-cljs/frontend/sente.cljs
@@ -12,14 +12,16 @@
   (if (-> sente-state :state deref :open?)
     (apply (:send-fn sente-state) message rest)
     (let [watch-id (utils/uuid)]
+      ;; TODO: handle this in the handle-message fn below
       (add-watch (:state sente-state) watch-id
                  (fn [key ref old new]
                    (when (:open? new)
                      (apply (:send-fn sente-state) message rest)
                      (remove-watch ref watch-id)))))))

-(defn subscribe-to-document [sente-state document-id]
-  (send-msg sente-state [:frontend/subscribe {:document-id document-id}]))
+(defn subscribe-to-document [sente-state document-id & {:keys [requested-color]}]
+  (send-msg sente-state [:frontend/subscribe {:document-id document-id
+                                              :requested-color requested-color}]))

 (defn fetch-subscribers [sente-state document-id]
   (send-msg sente-state [:frontend/fetch-subscribers {:document-id document-id}] 10000
@@ -73,19 +75,35 @@
   (put! (get-in @app-state [:comms :errors]) [:document-permission-error data])
   (utils/inspect data))

+(defmethod handle-message :chsk/state [app-state message data]
+  (let [state @app-state]
+    (utils/inspect data)
+    (when (and (:open? data)
+               (not (:first-open? data))
+               (:document/id state))
+      ;; TODO: This seems like a bad place for this. Can we share the same code that
+      ;;       we use for subscribing from the nav channel in the first place?
+      (subscribe-to-document
+       (:sente state) (:document/id state)
+       :requested-color (get-in state [:subscribers (:client-id state) :color])))))
+

 (defn do-something [app-state sente-state]
   (let [tap (async/chan (async/sliding-buffer 10))
         mult (:ch-recv-mult sente-state)]
     (async/tap mult tap)
     (go-loop []
-      (when-let [{[type data] :event} (<! tap)]
-        ;; other type is :chsk/state, sent when the ws is opened.
-        ;; might be a good thing to watch when we reconnect?
-        (when (= :chsk/recv type)
-          (utils/swallow-errors
-           (let [[message message-data] data]
-             (handle-message app-state message message-data))))
+      (when-let [{[type data] :event :as stuff} (<! tap)]
+        (case type
+          :chsk/recv (utils/swallow-errors
+                      (let [[message message-data] data]
+                        (handle-message app-state message message-data)))
+
+          ;; :chsk/state is sent when the ws is opened or closed
+          :chsk/state (utils/swallow-errors
+                       (handle-message app-state type data))
+
+          nil)
         (recur)))))

 (defn init [app-state]


get dada compiling on my netbook again - wierd !

--- dada-core/src/main/clojure/org/dada/core/RemoteSessionManager.clj
+++ dada-core/src/main/clojure/org/dada/core/RemoteSessionManager.clj
@@ -5,6 +5,9 @@
    [org.dada.core proxy]
    [org.dada.core remote]
    )
+  (:require
+   [org.dada.core
+    RemoteSession])
   (:import
    [java.lang.reflect
     Proxy]
@@ -39,7 +42,7 @@
    )
   (:gen-class
    :implements [org.dada.core.SessionManager]
-   :constructors {[String org.dada.core.remote.Remoter] []}
+   :constructors {[String Object] []}	;TODO - should be Remoter
    :methods []
    :init init
    :state state


ClojureScript dependencies.

ClojureScript dependencies.

--- project.clj
+++ project.clj
@@ -10,4 +10,24 @@
                  [mysql/mysql-connector-java "5.1.25"]
                  [ring/ring-core             "1.3.2"]
                  [com.relaynetwork/kinematic "1.3.8"]
-                 [http-kit                   "2.1.16"]])
+                 [http-kit                   "2.1.16"]
+
+                 ;; client side
+                 [org.clojure/clojurescript  "0.0-2760"]
+                 [org.omcljs/om              "0.8.8"]
+                 [om-utils                   "0.4.0"]
+                 [secretary                  "1.2.1"]
+                 [com.cognitect/transit-cljs "0.8.199"]]
+  :cljsbuild {:builds [{:id           "development"
+                        :source-paths ["src/task_tracker/app"]
+                        :compiler     {:output-to     "task_tracker.js"
+                                       :output-dir    "out"
+                                       :optimizations :none
+                                       :source-map    true}}
+                       {:id           "production"
+                        :source-paths ["src/task_tracker/app"]
+                        :compiler     {:output-to     "task_tracker_prod.js"
+                                       :optimizations :advanced
+                                       :pretty-print  false
+                                       :preamble      ["react/react.min.js"]
+                                       :externs       ["react/externs/react.js"]}}]})


(MAINT) Bump to 4.2.0-SNAPSHOT

(MAINT) Bump to 4.2.0-SNAPSHOT

--- project.clj
+++ project.clj
@@ -1,4 +1,4 @@
-(def pdb-version "4.1.1-SNAPSHOT")
+(def pdb-version "4.2.0-SNAPSHOT")

 (defn deploy-info
   "Generate deployment information from the URL supplied and the username and


Add transactional support to update dataset

--- backend/src/akvo/lumen/update.clj
+++ backend/src/akvo/lumen/update.clj
@@ -39,8 +39,8 @@
                                 :version (inc (:version dataset-version))
                                 :columns new-columns
                                 :transformations (vec transformations)})
-  (drop-table (:imported-table-name dataset-version))
-  (drop-table (:table-name dataset-version))
+  (drop-table conn {:table-name (:imported-table-name dataset-version)})
+  (drop-table conn {:table-name (:table-name dataset-version)})
   (update-successful-job-execution conn {:id job-execution-id}))

 (defn failed-update [conn job-execution-id reason]
@@ -135,10 +135,12 @@
   (let [job-execution-id (str (util/squuid))]
     (insert-dataset-update-job-execution tenant-conn {:id job-execution-id
                                                       :data-source-id data-source-id})
-    (future (do-update tenant-conn
-                       config
-                       dataset-id
-                       data-source-id
-                       job-execution-id
-                       data-source-spec))
+    (future
+      (jdbc/with-db-transaction [tx-conn tenant-conn]
+        (do-update tx-conn
+                   config
+                   dataset-id
+                   data-source-id
+                   job-execution-id
+                   data-source-spec)))
     (lib/ok {"updateId" job-execution-id})))


Fixed error in model creation

Fixed error in model creation

--- src/ardoq/swagger/common.clj
+++ src/ardoq/swagger/common.clj
@@ -30,7 +30,7 @@
 (defn find-or-create-model [client type]
   (if-let [model (first (filter #(= type (:name %)) (api/find-all (api/map->Model {}) client)))]
     model
-    (-> (api/map->Model (parse-string (slurp (io/resource (if (= type = "Swagger") "modelv1.json" "modelv2.json"))) true))
+    (-> (api/map->Model (parse-string (slurp (io/resource (if (= type "Swagger") "modelv1.json" "modelv2.json"))) true))
         (api/create client))))

 (defn find-existing-resource


refactor, add docstrings to schema

refactor, add docstrings to schema

--- src/braid/common/schema.cljc
+++ src/braid/common/schema.cljc
@@ -1,7 +1,9 @@
 (ns braid.common.schema
   (:require [schema.core :as s :include-macros true]))

+
 (def NewMessage
+  "A new message, before saved into thread - what the client sends"
   {:id s/Uuid
    :thread-id s/Uuid
    :user-id s/Uuid
@@ -12,27 +14,28 @@
 (def new-message-valid? (s/validator NewMessage))

 (def ThreadMessage
+  "A message saved into a thread"
   {:id s/Uuid
    :content s/Str
    :user-id s/Uuid
    :created-at s/Inst})

 (def MsgThread
+  "A thread (just calling it Thread apparently causes confusion (with java.lang.Thread)"
   {:id s/Uuid
    :messages [ThreadMessage]
    :tag-ids [s/Uuid]
    :mentioned-ids [s/Uuid]})

 ;; Notification rules schema
-(def AnyRule [(s/one (s/eq :any) "rule")
-              (s/one (s/cond-pre (s/eq :any) s/Uuid) "id")])
-(def MentionRule [(s/one (s/eq :mention) "rule")
-                  (s/one (s/cond-pre (s/eq :any) s/Uuid) "id")])
-(def TagRule [(s/one (s/eq :tag) "rule")
-              (s/one s/Uuid "id")])
 (def Rule
-  (s/conditional #(= :any (first %)) AnyRule
-                 #(= :mention (first %)) MentionRule
-                 #(= :tag (first %)) TagRule))
-(def Rules [Rule])
+  "One rule for user notification settings"
+  (s/conditional
+    #(or (= :any (first %)) (= :mention (first %)))
+    [(s/one (s/enum :any :mention) "rule")
+     (s/one (s/cond-pre (s/eq :any) s/Uuid) "id")]
+
+    #(= :tag (first %))
+    [(s/one (s/eq :tag) "rule") (s/one s/Uuid "id")]))
+(def Rules "User notification rules" [Rule])
 (def rules-valid? (s/validator Rules))


add schema for groups

add schema for groups

--- src/braid/common/schema.cljc
+++ src/braid/common/schema.cljc
@@ -28,7 +28,7 @@
    :mentioned-ids [s/Uuid]})

 ;; Notification rules schema
-(def Rule
+(def NotifyRule
   "One rule for user notification settings"
   (s/conditional
     #(or (= :any (first %)) (= :mention (first %)))
@@ -37,5 +37,17 @@

     #(= :tag (first %))
     [(s/one (s/eq :tag) "rule") (s/one s/Uuid "id")]))
-(def Rules "User notification rules" [Rule])
-(def rules-valid? (s/validator Rules))
+(def NotifyRules "User notification rules" [Rule])
+(def rules-valid? (s/validator NotifyRules))
+
+(def Extension
+  {:id s/Uuid
+   :type s/Keyword})
+
+(def Group
+  {:id s/Uuid
+   :name s/Str
+   :admins [s/Uuid]
+   :intro (s/maybe s/Str)
+   :avatar (s/maybe s/Str)
+   :extensions [Extension]})


Add anti-forgery meta tags to each page.

--- src/cadence/views/common.clj
+++ src/cadence/views/common.clj
@@ -1,6 +1,7 @@
 (ns cadence.views.common
   (:require [clojure.string :as string]
             [cemerick.friend :as friend]
+            [ring.util.anti-forgery :refer [anti-forgery-metas]]
             [cadence.model :as m]
             [noir.validation :as vali]
             [cadence.model.flash :as flash])
@@ -18,11 +19,11 @@
   (html5
     [:head
      [:title "Cadence"]
+     [:link {:rel "shortcut icon" :type "image/x-icon" :href "/favicon.ico"}]
+     (anti-forgery-metas)
      ; Meta Tag Necessary for Twitter Boostrap
      [:meta {:name "viewport"
              :content "width=device-width, initial-scale=1.0"}]
-     ; Get jQuery
-     [:link {:rel "shortcut icon" :type "image/x-icon" :href "/favicon.ico"}]
      (include-css "/css/bootstrap.min.css")
      (include-js (str "https://ajax.googleapis.com/ajax/libs/"
                       "jquery/1.7.2/jquery.min.js")


made user a string or nil for anonymously viewed pages like oss projects

--- src-cljs/frontend/analytics/segment.cljs
+++ src-cljs/frontend/analytics/segment.cljs
@@ -8,9 +8,7 @@
             [schema.core :as s]))

 (def SegmentProperties
-  ;; user and view should never be null, since they will always have values for
-  ;; a logged in user.
-  {:user s/Str
+  {:user (s/maybe s/Str)
    :view s/Keyword
    :org  (s/maybe s/Str)
    :repo (s/maybe s/Str)


(MAINT) Improve yaml parsing error handling

Add logging when the csr_attributes or custom_trusted_oid_mapping
file paths are non-nil but are invalid file paths. Allow any
exceptions thrown when parsing these files to bubble up.

--- src/clj/puppetlabs/puppetserver/certificate_authority.clj
+++ src/clj/puppetlabs/puppetserver/certificate_authority.clj
@@ -596,19 +596,18 @@
   "Parse the CSR attributes yaml file at the given path and create a list of
   certificate extensions from the `extensions_requests` section."
   [csr-attributes-file :- schema/Str]
-  (when (fs/file? csr-attributes-file)
-    (try
+  (when csr-attributes-file
+    (if (fs/file? csr-attributes-file)
       (let [csr-attrs (yaml/parse-string (slurp csr-attributes-file))
-            ext-req   (:extension_requests csr-attrs)]
+            ext-req (:extension_requests csr-attrs)]
         (map (fn [[oid value]]
                {:oid      (or (get puppet-short-names oid)
                               (name oid))
                 :critical false
                 :value    (str value)})
              ext-req))
-      (catch Exception e
-        (throw (Exception.
-                 (str "There was a problem parsing " csr-attributes-file) e))))))
+      (log/error (format "%s is not a valid file path. CSR Attributes will not be loaded."
+                         csr-attributes-file)))))

 (schema/defn create-master-extensions :- (schema/pred utils/extension-list?)
   "Create a list of extensions to be added to the master certificate."
@@ -1226,13 +1225,12 @@
   "Given a path to a custom OID mappings file, return a map of all oids to
   shortnames"
   [custom-oid-mapping-file :- (schema/maybe schema/Str)]
-  (when (fs/file? custom-oid-mapping-file)
-    (try
+  (when custom-oid-mapping-file
+    (if (fs/file? custom-oid-mapping-file)
       (let [oid-mappings (:oid_mapping (yaml/parse-string (slurp custom-oid-mapping-file)))]
         (into {} (for [[oid names] oid-mappings] [(name oid) (keyword (:shortname names))])))
-      (catch Exception e
-        (throw (Exception.
-                 (str "There was a problem parsing " custom-oid-mapping-file) e))))))
+      (log/error (format "%s is not a valid file path. Custom OID Mappings will not be loaded."
+                         custom-oid-mapping-file)))))

 (schema/defn ^:always-validate get-oid-mappings :- OIDMappings
   [custom-oid-mapping-file :- (schema/maybe schema/Str)]


Add a 'render fn for deftemplate --> strings.

This keeps liberator happier.

--- src/clj/aspire/templates.clj
+++ src/clj/aspire/templates.clj
@@ -1,6 +1,9 @@
 (ns aspire.templates
   (:require [net.cgrand.enlive-html :as en]
             [hiccup.core :as hc]))
+
+(defn render [template]
+  (reduce str template))

 (en/deftemplate index "public/index.html"
   [user-display-name]


add font encoding

add font encoding

--- src/clj/salava/badge/pdf.clj
+++ src/clj/salava/badge/pdf.clj
@@ -84,7 +84,7 @@
         user-data (ud/user-information ctx user-id)
         ul (if (blank? (:language user-data)) "en" (:language user-data))
         font-path  (first (mapcat #(get-in ctx [:config % :font] []) (get-plugins ctx)))
-        font  {:ttf-name (str site-url font-path)}
+        font  {:ttf-name (str site-url font-path) :encoding :unicode}
         stylesheet {:heading-name {:color [127 113 121]
                                    :family :times-roman
                                    :align :center}
@@ -97,7 +97,7 @@
                     :chunk {:size 11
                             :style :bold}}

-        pdf-settings  (if (empty? font-path) {:stylesheet stylesheet  :bottom-margin 0 :footer {:page-numbers true :align :right}} {:font font :stylesheet stylesheet  :bottom-margin 0 :footer {:page-numbers false :align :right}})
+        pdf-settings  (if (empty? font-path) {:stylesheet stylesheet  :bottom-margin 0 :footer {:page-numbers true :align :right}} {:font font :stylesheet stylesheet  :bottom-margin 0 :footer {:page-numbers false :align :right} :register-system-fonts? true})
         badge-template (pdf/template
                          (let [template #(cons [:paragraph]  [ (if (and (not (= "-" (:image_file %)))(ends-with? (:image_file %) "png"))
                                                                  [:image {:width 100 :height 100 :align :center} (str data-dir "/" (:image_file %))]


added headers

added headers

--- src/clj/salava/page/main.clj
+++ src/clj/salava/page/main.clj
@@ -115,6 +115,7 @@
          page (conj () (-> (select-page {:id page-id} (get-db ctx))
                            first
                            (assoc :blocks blocks)))
+         badges (map #(:id (filter (= "badge" :type %))) (:blocks (first page)))
         data-dir (get-in ctx [:config :core :data-dir])
         page-template (pdf/template
                         (let [template #(cons [:paragraph] [#_[:heading {:size :15 :align :center} $name] [:spacer 0]
@@ -153,7 +154,10 @@
                                                                  [:spacer 0]
                                                                 [:paragraph
                                                                  [:phrase (str (t :badge/Criteria)": ")] [:spacer 0]
-                                                                 [:anchor {:target (:criteria_url %) :style{:family :times-roman :color [66 100 162]}} (:criteria_url %)]]] " ")]]
+                                                                 [:anchor {:target (:criteria_url %) :style{:family :times-roman :color [66 100 162]}} (:criteria_url %)]
+                                                                 [:spacer]
+                                                                  (markdown->clj-pdf (:criteria_content %))
+                                                                 ]] " ")]]
                                                              ] " ")
                                                             (if (= "html" (:type %))
                                                               [:paragraph {:align :center}
@@ -167,6 +171,7 @@
                                                              [:chunk (str $first_name " " $last_name)]]]] content)))]

     (dump page)
+    (dump badges)
     (pdf/pdf (into [{:right-margin 50 :left-margin 50 }] (page-template page)) "out")

     ))


test runner without execute

test runner without execute

--- src/clj/shadow/cljs/node.clj
+++ src/clj/shadow/cljs/node.clj
@@ -70,14 +70,14 @@
             target (io/file public-dir js-name)

             out (->> provided-ns
-                  (map (fn [ns]
-                         (str "goog.require('" (comp/munge ns) "');")))
-                  (str/join "\n"))
+                     (map (fn [ns]
+                            (str "goog.require('" (comp/munge ns) "');")))
+                     (str/join "\n"))
             out (str prepend prepend-js out append-js)

             out (str (slurp (io/resource "shadow/cljs/node_bootstrap.txt"))
-                  "\n\n"
-                  out)
+                     "\n\n"
+                     out)
             goog-js (io/file public-dir cljs-runtime-path "goog" "base.js")
             deps-js (io/file public-dir cljs-runtime-path "deps.js")]
         (spit goog-js
@@ -164,30 +164,50 @@
   state)

 (defn setup-test-runner [state test-namespaces]
-  (let [test-runner-src {:name "test_runner.cljs"
-                         :js-name "test_runner.js"
-                         :type :cljs
-                         :provides #{'test-runner}
-                         :requires (into #{'cljs.core 'cljs.test} test-namespaces)
-                         :ns 'test-runner
-                         :input (atom [`(~'ns ~'test-runner
-                                          (:require [cljs.test]
-                                            ~@(mapv vector test-namespaces)))
-                                       `(cljs.test/run-tests (cljs.test/empty-env)
-                                          ~@(for [it test-namespaces]
-                                              `(quote ~it)))])
-                         :last-modified (System/currentTimeMillis)}]
+  (let [test-runner-src
+        {:name "test_runner.cljs"
+         :js-name "test_runner.js"
+         :type :cljs
+         :provides #{'test-runner}
+         :requires (into #{'cljs.core 'cljs.test} test-namespaces)
+         :ns 'test-runner
+         :input (atom [`(~'ns ~'test-runner
+                          (:require [cljs.test]
+                            ~@(mapv vector test-namespaces)))
+
+                       `(defmethod cljs.test/report [:cljs.test/default :end-run-tests] [m#]
+                          (if (cljs.test/successful? m#)
+                            (js/process.exit 0)
+                            (js/process.exit 1)
+                            ))
+
+                       `(cljs.test/run-tests
+                          (cljs.test/empty-env)
+                          ~@(for [it test-namespaces]
+                              `(quote ~it)))])
+         :last-modified (System/currentTimeMillis)}]

     (-> state
         (cljs/merge-resource test-runner-src)
         (cljs/reset-modules)
         (cljs/configure-module :test-runner ['test-runner] #{}))))

-(defn make-test-runner [state test-namespaces]
-  (-> state
-      (setup-test-runner test-namespaces)
-      (cljs/compile-modules)
-      (flush)))
+(defn find-all-test-namespaces [state]
+  (->> (get-in state [:sources])
+       (vals)
+       (remove :jar)
+       (filter cljs/has-tests?)
+       (map :ns)
+       (into [])))
+
+(defn make-test-runner
+  ([state]
+   (make-test-runner state (find-all-test-namespaces state)))
+  ([state test-namespaces]
+   (-> state
+       (setup-test-runner test-namespaces)
+       (cljs/compile-modules)
+       (flush))))

 (defn execute-affected-tests!
   [{:keys [logger] :as state} source-names]
@@ -208,16 +228,10 @@
           state))))

 (defn execute-all-tests! [state]
-  (let [test-namespaces (->> (get-in state [:sources])
-                             (vals)
-                             (remove :jar)
-                             (filter cljs/has-tests?)
-                             (map :ns)
-                             (into []))]
-    (-> state
-        (make-test-runner test-namespaces)
-        (execute! "node" :script))
-
-    ;; return unmodified state!
-    state
-    ))
+  (-> state
+      (make-test-runner)
+      (execute! "node" :script))
+
+  ;; return unmodified state!
+  state
+  )


Add some util constants

Add some util constants

--- src/cljs/cloj/math/vec2.cljs
+++ src/cljs/cloj/math/vec2.cljs
@@ -15,3 +15,20 @@
 (defn applyv [{fx :x fy :y} {x :x y :y}]
   (vec2 (fx x) (fy y)))

+
+(def left  (vec2 -1  0))
+(def right (vec2  1  0))
+(def up    (vec2  0 -1))
+(def down  (vec2  0  1))
+
+(def left-up    (vec2 -1 -1))
+(def left-down  (vec2 -1  1))
+(def right-up   (vec2  1 -1))
+(def right-down (vec2  1  1))
+
+(def up-left    left-up)
+(def down-left  left-down)
+(def up-right   right-up)
+(def down-right right-down)
+
+


Switch to doc.lmcloud.vse.cz

Switch to doc.lmcloud.vse.cz

--- src/cljs/db_quiz/config.cljs
+++ src/cljs/db_quiz/config.cljs
@@ -19,8 +19,8 @@
              :missed "#333333"
              :player-1 "#fc4349"
              :player-2 "#354d65"}
-   :data {:sparql {:endpoint-urls {:cs "http://xtest.lmcloud.vse.cz/virtuoso-dbquiz/sparql"
-                                   :en "http://xtest.lmcloud.vse.cz/virtuoso-dbquiz/sparql"}
+   :data {:sparql {:endpoint-urls {:cs "http://doc.lmcloud.vse.cz/virtuoso-dbquiz/sparql"
+                                   :en "http://doc.lmcloud.vse.cz/virtuoso-dbquiz/sparql"}
                    :query-files {:cs {:alphabetic "sparql/cs_dbpedia_az.mustache"
                                       :numeric "sparql/cs_dbpedia.mustache"}
                                  :en {:alphabetic ""


Move about page link to navbar

Move about page link to navbar

--- src/cljs/decktouch/core.cljs
+++ src/cljs/decktouch/core.cljs
@@ -62,7 +62,10 @@
 (defn navbar []
   [:nav.navbar.navbar-fixed-top.navbar-inverse.text-center
     [:a.navbar-brand {:href "#"}
-      "Decktouch"]])
+      "Decktouch"]
+    [:div#navbar.collapse.navbar-collapse
+      [:ul.nav.navbar-nav
+        [:li [:a {:href "#/about"} "go to about page"]]]]])

 (defn current-page []
   [:div


init! fn added to cljs core ns as an application initilizer

--- src/cljs/hellhound/core.cljs
+++ src/cljs/hellhound/core.cljs
@@ -1,6 +1,13 @@
 (ns hellhound.core
-  (:require [hellhound.connection :refer [send-fn!] ]))
+  (:require
+   [reagent.core         :as reagent]
+   [reframe.core         :as re-frame]
+   [re-frisk.core        :as re-frisk]
+   [hellhound.connection :refer [send-fn!] ]))

+
+(def debug?
+  ^boolean js/goog.DEBUG)

 (defn ->server
   "Send the given `data` to the server."
@@ -14,3 +21,25 @@
   "Dispatch the given event to server side application."
   [[name data]]
   (->server [:hellhound/message {:message-name name :data data}]))
+
+(defn mount-root
+  [view]
+  (re-frame/clear-subscription-cache!)
+  (reagent/render [view]
+                  (.getElementById js/document "app")))
+
+(defn setup-development
+  [dev-fn]
+  (enable-console-print!)
+  (re-frisk/enable-re-frisk!)
+  (println "DEV MODE")
+  (dev-fn))
+
+(defn init!
+  "Initialize the client side application."
+  [{:keys [router dev-setup main-view dispatch-events] :as options}]
+
+  (re-frame/dispatch-sync dispatch-events)
+  (when? (debug?)
+    (setup-development dev-setup))
+  (mount-root main-view))


Showing the graph only if the user has selected some "likes"

Otherwise the back end function for the graph would return an error 500,
which sigma cannot handle.

--- src/cljs/tropology/core.cljs
+++ src/cljs/tropology/core.cljs
@@ -123,7 +123,10 @@
 (re-frame/register-handler
   :set-show-graph
   (fn [app-state [_ show?]]
-    (assoc-in app-state [:ui-state :show-graph?] show?)
+    (if (and show? (empty? (get-in app-state [:article-data :like-list])))
+      (assoc-in app-state [:ui-state :errors] (cons "Cannot show graph for an empty list" (get-in app-state [:ui-state :errors])))
+      (assoc-in app-state [:ui-state :show-graph?] show?)
+      )
     ))

 (re-frame/register-handler
@@ -223,8 +226,8 @@
       (into [head
              (-> attrs
                  (assoc :style (->> (split style #"\;")
-                                          (map #(split % #"\:"))
-                                          (into {})))
+                                    (map #(split % #"\:"))
+                                    (into {})))
                  (dissoc :onclick))
              ]
             tail)


add syntax api to parse logger, and add breakdown of type counts per ns parse total

--- src/cljs_api_gen/catalog.clj
+++ src/cljs_api_gen/catalog.clj
@@ -66,10 +66,20 @@
   (let [ns-groups (group-by :ns parsed)
         pairs (sort-by first ns-groups)]
     (doseq [[ns- symbols] pairs]
-      (println "   " ns- ": parsed" (count symbols) "symbols"))))
+      (printf "    %-24s %4s = %s\n"
+        ns-
+        (count symbols)
+        (let [type-groups (group-by :type symbols)
+              pairs (sort-by first type-groups)]
+          (join " + "
+            (for [[type- symbols] pairs]
+              (let [total (count symbols)]
+                (str total " " (cond-> type- (> total 1) (str "s")))))))))))

 (defn print-summary
   [parsed]
+  (println " Syntax API:")
+  (print-summary* (:syntax parsed))
   (println " Library API:")
   (print-summary* (:library parsed))
   (println " Compiler API:")


Refactor

Refactor

--- src/hackernews/shared/scenes/detail_view/detail_view.cljs
+++ src/hackernews/shared/scenes/detail_view/detail_view.cljs
@@ -6,18 +6,18 @@
             [re-frame.core :refer [subscribe dispatch]]))

 (defn comment-row
-  [comment]
-  [rn/view {:style {:margin 10}}
-   [rn/text {:style {:padding 5
-                     :color "#f26522"}}
-    (str (:user comment) " " (:time_ago comment))]
-   [rn/html-view {:value (:content comment)
+  [{:keys [user time_ago content]}]
+  [rn/view {:style {:padding 15}}
+   [rn/text {:style {:color "#f26522"
+                     :margin-bottom 10}}
+    (str user " " time_ago)]
+   [rn/html-view {:value content
                   :stylesheet {:p {:font-size 18}}}]])

 (defn detail-view
   [{:keys [id]}]
   [rn/view
-   {:style {:padding-top 10}}
+   {:style {:margin-top 10}}
    [sr/story-row @(subscribe [:get-story id])]
    [l/list-view {::l/items @(subscribe [:story-flat-comments id])
                  ::l/render-row  comment-row}]])


Remove obsolete condition, already guarded by an assert.

--- src/decl_ui/reader_tags.cljs
+++ src/decl_ui/reader_tags.cljs
@@ -29,7 +29,7 @@
                          (-resolve [_ cells]
                            (let [callback (callbacks/compile cells callbacks form)]
                              (assert (some? callback) (str "Cannot bind to " form))
-                             (when callback (reaction (callback)))))))]
+                             (reaction (callback))))))]
     (assert (some? result) (str "Cannot bind to " form))
     result))


added distillery.view.html/DEBUG

added distillery.view.html/DEBUG

--- src/distillery/view/html.clj
+++ src/distillery/view/html.clj
@@ -1,6 +1,8 @@
 (ns distillery.view.html
+  (:require [clojure.pprint :refer (pprint)])
   (:require [clojure.java.io :refer (resource)])
-  (:require [net.cgrand.enlive-html :refer (html-resource transform content emit*)]))
+  (:require [net.cgrand.enlive-html :refer (html-resource transform content emit*)])
+  (:require [distillery.trace :refer :all]))

 (defn template
   "Loads a html template from the 'view' folder by its name without extension."
@@ -186,8 +188,19 @@
                  :attrs {:class "bar_beam"
                          :style (str "width:" iv "%; background-color: " c ";")}})]))))

+(defn DEBUG
+  [x]
+  (let [w (java.io.StringWriter.)]
+    (pprint x w)
+    (let [txt (.toString w)]
+      (trace-message "DEBUG: " txt)
+      {:tag :pre
+       :content [{:tag :strong :content "DEBUG\n" }
+                 {:tag :code
+                  :content [txt]}]})))
+
 (defn TODO
   [text]
-  ;(println (format "TODO: %s" text))
+  (trace-message "TODO: " text)
   {:tag :div :attrs {:class "todo"} :content text})


Adapt to upstream renames

Adapt to upstream renames

--- src/flense_demo/sidebar.cljs
+++ src/flense_demo/sidebar.cljs
@@ -9,11 +9,11 @@
             [xyzzy.core :as z]))

 (defn movement-keybinds [loc]
-  [["Down" (if (m/stringlike-loc? loc)
+  [["Down" (if (m/stringlike? loc)
              "Begin editing text inside this form"
              "Select this form's first child")
            (text/down loc)]
-   ["Up" (if (and (m/stringlike-loc? loc) (:editing? (z/node loc)))
+   ["Up" (if (and (m/stringlike? loc) (:editing? (z/node loc)))
            "Finish editing text inside this form"
            "Select this form's parent")
          (text/up loc)]
@@ -21,7 +21,7 @@
    ["Right" "Select the form to the right, or wrap around" (z/right-or-wrap loc)]])

 (defn structural-keybinds [loc]
-  [["Backspace" (if (or (not (m/atom-loc? loc)) (m/placeholder-loc? loc))
+  [["Backspace" (if (or (not (m/atom? loc)) (m/placeholder? loc))
                   "Delete this form"
                   "Delete the last character of this form")
                 true]
@@ -31,7 +31,7 @@
    ["Shift+9" "Wrap this form in a sequence" true]
    ["Open-bracket" "Wrap this form in a vector" true]
    ["Shift+Open-bracket" "Wrap this form in a map" true]
-   ["Shift+Single-quote" "Wrap this form in a string" (m/atom-loc? loc)]])
+   ["Shift+Single-quote" "Wrap this form in a string" (m/atom? loc)]])

 (defn semantic-keybinds [loc]
   [["Tab" "Expand template" (clojure/expand-template loc)]])


improve log message

improve log message

--- src/babel/francais/morphology/verbs.cljc
+++ src/babel/francais/morphology/verbs.cljc
@@ -909,7 +909,8 @@
      (get-in word [:français])

      :else
-     (let [message (str "get-string-1: imperfecto regular inflection: don't know what to do with input argument: " (strip-refs word))]
+     (let [message (str "get-string-1: imperfect regular inflection: "
+                        " don't know what to do with input argument: " (strip-refs word))]
        (if (= true suppress-incomplete-morphology-errors)
          (do (log/warn message)
              "(" (get-in word [:francais]) ")")


proper n value

proper n value

--- src/hackerrank/even_tree.clj
+++ src/hackerrank/even_tree.clj
@@ -15,7 +15,8 @@

 (defn even-tree
   ([]
-   (let [n (parseInt (read-line))]
+   (let [first-line-numbers (numbers (read-line))
+         n (nth first-line-numbers 0)]
      (println n)
      n))


Type checking for get-formatted-time

Type checking for get-formatted-time

--- src/emender_jenkins/job_data_fetcher.clj
+++ src/emender_jenkins/job_data_fetcher.clj
@@ -53,7 +53,7 @@

 (defn get-formatted-time
     "Returns formatted time."
-    [ms]
+    [^long ms]
     (let [sdf         (new java.text.SimpleDateFormat "yyyy-MM-dd HH:mm:ss")
           result-date (new java.util.Date ms)]
           (.format sdf result-date)))


impl-free now works correctly on cimpl and ncimpl

--- src/logic/basicfunctions.clj
+++ src/logic/basicfunctions.clj
@@ -38,12 +38,14 @@
 (defmacro cimpl
   "Converse logical implication (phi <- psi)"
   [phi psi]
-  (list 'impl psi phi))
+  (list 'or
+    (list 'not psi) phi))

 (defmacro ncimpl
   "Negated converse logical implication (!(phi <- psi))"
   [phi psi]
-  (list 'nimpl psi phi))
+  (list 'not
+    (list 'cimpl phi psi)))

 (defmacro xor
   "Logical exclusive or"


Receive just one arg

Receive just one arg

--- test/clojure/clojurewerkz/cassaforte/collections_test.clj
+++ test/clojure/clojurewerkz/cassaforte/collections_test.clj
@@ -10,7 +10,7 @@

 (let [s (th/make-test-session)]
   (use-fixtures :each (fn [f]
-                        (th/with-temporary-keyspace s f)))
+                        (th/with-temporary-keyspace f)))
   (deftest test-collection-conversion-on-load
     (let [t :users_collections]
       (create-table s t


test hook

test hook

--- src/main/cawala/api/read.clj
+++ src/main/cawala/api/read.clj
@@ -6,7 +6,7 @@
                      :person/relation :friend}
                  2  {:db/id 2 :person/name "Sally" :person/age 22
                      :person/relation :friend}
-                 3  {:db/id 3 :person/name "Allie" :person/age 72
+                 3  {:db/id 3 :person/name "Allie" :person/age 71
                      :person/relation :enemy}
                  4  {:db/id 4 :person/name "Zoe" :person/age 32
                      :person/relation :friend}


Indentation

Indentation

--- src/oxcart.clj
+++ src/oxcart.clj
@@ -95,7 +95,8 @@
          (do (let [ast (-> mform
                            (util/ast)
                            (assoc :raw-form form
-                                  :raw-op   (when (list? form) (first form))))]
+                                  :raw-op   (when (list? form)
+                                              (first form))))]
                ;; Add to the accumulator for the whole read program
                ;;
                ;; Builds a mapping of the form


Add temperature-as

Add temperature-as

--- src/test_utils/fracture_diagnostics.cljc
+++ src/test_utils/fracture_diagnostics.cljc
@@ -102,6 +102,13 @@
       [:bpm :m3-per-min] [(* magnitude factor) to]
       [:m3-per-min :bpm] [(/ magnitude factor) to])))

+(defn temperature-as [[magnitude from] to]
+  (let [f->c #(/ (- % 32) 1.8)
+        c->f #(+ (* % 1.8) 32)]
+    (condp = [from to]
+      [:F :C] [(f->c magnitude) to]
+      [:C :F] [(c->f magnitude) to])))
+
 (defn typical-vertical-depth []
   (tuc/draw-normal 8000 1216))

@@ -661,4 +668,4 @@
         measurement (generate-measurement-f unit)]
     [measurement (measurement-as-f measurement (first (remove (partial = unit) units)))]))

-(generate-pair #{:bbl-per-min :m3-per-min} rand-slurry-rate-unit typical-slurry-rate slurry-rate-as)
+(generate-pair #{:F :C} rand-temperature-unit typical-temperature temperature-as)


Fix #47 A stale mount point can cause issues

--- Clojure/src/ambly/repl/jsc.clj
+++ Clojure/src/ambly/repl/jsc.clj
@@ -200,11 +200,13 @@
         endpoint-port (:port endpoint)
         webdav-mount-point (str "/Volumes/Ambly-" endpoint-address)
         output-dir (io/file webdav-mount-point)
-        _ (.mkdirs output-dir)
         env (ana/empty-env)
         core (io/resource "cljs/core.cljs")]
     ((:print opts) "\nConnecting to" (bonjour-name->display-name bonjour-name) "...\n")
     (reset! (:webdav-mount-point repl-env) webdav-mount-point)
+    (when (.exists output-dir)
+      (shell/sh "umount" webdav-mount-point))
+    (.mkdirs output-dir)
     (shell/sh "mount_webdav" (str "http://" endpoint-address ":" endpoint-port) webdav-mount-point)
     (reset! (:socket repl-env)
       (socket endpoint-address (:port repl-env)))


Fill out lein-light-nrepl project.clj

Fill out lein-light-nrepl project.clj

--- lein-light-nrepl/project.clj
+++ lein-light-nrepl/project.clj
@@ -1,6 +1,6 @@
 (defproject lein-light-nrepl "0.0.18"
-  :description "FIXME: write description"
-  :url "http://example.com/FIXME"
+  :description "nrepl client for Light Table clj and cljs eval."
+  :url "https://github.com/LightTable/Clojure/tree/master/lein-light-nrepl"
   :license {:name "Eclipse Public License"
             :url "http://www.eclipse.org/legal/epl-v10.html"}
   :dependencies [[org.clojure/clojure "1.5.1"]


Start 2.5.8-SNAPSHOT

Start 2.5.8-SNAPSHOT

--- build.boot
+++ build.boot
@@ -18,7 +18,7 @@
 (task-options!
   sift {:include #{#"\.jar$"}}
   pom {:project 'nightcode
-       :version "2.5.7"
+       :version "2.5.8-SNAPSHOT"
        :description "An IDE for Clojure"
        :url "https://github.com/oakes/Nightcode"
        :license {"Public Domain" "http://unlicense.org/UNLICENSE"}


Disable recompile-dependents for development

--- build.boot
+++ build.boot
@@ -159,7 +159,8 @@
         (cljs :ids ["js/main"]
               :optimizations :none
               :compiler-options {:preloads '[zetawar.dev]
-                                 :parallel-build true})
+                                 :parallel-build true
+                                 :recompile-dependents false})
         (target)))

 (deftask run-tests


Update version to 0.3.0-SNAPSHOT

Update version to 0.3.0-SNAPSHOT

--- build.boot
+++ build.boot
@@ -1,5 +1,5 @@
 (def project 'rads/kafka.transit)
-(def version "0.2.0")
+(def version "0.3.0-SNAPSHOT")

 (set-env!
   :source-paths #{"src"}


Update boot

Update boot

--- build.boot
+++ build.boot
@@ -15,7 +15,7 @@
    [clj-http-fake "1.0.2" :scope "test"]
    [adzerk/boot-test "1.1.1" :scope "test"]
    [tolitius/boot-check "0.1.1" :scope "test"]
-   [boot/core "2.5.1" :scope "provided"]
+   [boot/core "2.5.5" :scope "provided"]
    [adzerk/bootlaces "0.1.13" :scope "test"]])

 (require


Update re-console

Update re-console

--- build.boot
+++ build.boot
@@ -22,7 +22,7 @@
                  [re-frame                    "0.5.0"]
                  [replumb/replumb             "0.2.2-SNAPSHOT"]
                  [cljsjs/highlight            "8.4-0"]
-                 [re-console                  "0.1.2"]
+                 [re-console                  "0.1.3-SNAPSHOT"]
                  [re-com                      "0.7.0-alpha2"]
                  [cljs-ajax                   "0.5.1"]
                  [hickory                     "0.5.4"]


tweak build.boot :filters :urls

tweak build.boot :filters :urls

--- build.boot
+++ build.boot
@@ -125,8 +125,8 @@
    :filters [{:ns 'migae.reloader   ; REQUIRED
               :name "reloader"      ; REQUIRED
               :display {:name "Clojure reload filter"} ; OPTIONAL
-              :urls [{:url "echo/*"}
-                     {:url "math/*"}]
+              :urls [{:url "/echo/*"}
+                     {:url "/math/*"}]
               :desc {:text "clojure reload filter"}}]
    :security [{:resource {:name "foo" :desc {:text "Foo resource security"}
                           :url "/foo/*"}


Add reflections as a dependency

Add reflections as a dependency

And update boot dep

--- build.boot
+++ build.boot
@@ -1,8 +1,10 @@
 (set-env!
  :source-paths #{"src"}
- :dependencies '[[org.clojure/clojure  "1.6.0"      :scope "provided"]
-                 [boot/core            "2.0.0-rc12" :scope "provided"]
-                 [junit                "4.12"       :scope "provided"]])
+ :dependencies '[[org.clojure/clojure  "1.6.0" :scope "provided"]
+                 [boot/core            "2.1.0" :scope "provided"]
+                 [junit                "4.12"  :scope "provided"]
+                 [org.reflections/reflections "0.9.10"
+                  :scope "provided"]])

 (require '[radicalzephyr.boot-junit :refer [junit]])


pass on more information when waiting for repo in example pipeline (e.g. to not just always use success status)

--- example/clj/todopipeline/steps.clj
+++ example/clj/todopipeline/steps.clj
@@ -4,10 +4,8 @@

 (ns todopipeline.steps
   (:require [lambdacd.steps.shell :as shell]
-            [lambdacd.internal.execution :as execution]
             [lambdacd.steps.git :as git]
-            [lambdacd.steps.manualtrigger :as manualtrigger]
-            [lambdacd.util :as util]))
+            [lambdacd.steps.manualtrigger :as manualtrigger]))

 ;; Let's define some constants
 (def backend-repo "git@github.com:flosell/todo-backend-compojure.git")
@@ -19,16 +17,14 @@
 (defn wait-for-frontend-repo [_ ctx]
   (let [wait-result (git/wait-for-git ctx frontend-repo "master")
         frontend-revision (:revision wait-result)]
-    {:frontend-revision frontend-revision
-     :backend-revision "HEAD"
-     :status :success}))
+    (assoc wait-result :frontend-revision frontend-revision
+                       :backend-revision "HEAD")))

 (defn wait-for-backend-repo [_ ctx]
   (let [wait-result (git/wait-for-git ctx backend-repo "master")
         backend-revision (:revision wait-result)]
-    {:backend-revision backend-revision
-     :frontend-revision "HEAD"
-     :status :success}))
+    (assoc wait-result :frontend-revision "HEAD"
+                       :backend-revision backend-revision)))

 ;; Define some nice syntactic sugar that lets us run arbitrary build-steps with a
 ;; repository checked out. The steps get executed with the folder where the repo


Have dynamically bound emission map use the "silent" one.

--- src/midje/ideas/formulas.clj
+++ src/midje/ideas/formulas.clj
@@ -10,6 +10,7 @@
         [clojure.walk :only [prewalk]])
   (:require [midje.emission.boundaries :as emission-boundary]
             [midje.emission.api :as emit]
+            [midje.emission.plugins.silence :as emission-silence]
             [midje.clojure-test-facade :as ctf]))

 ;; Formulas work by running up to *num-trials* trials per formula. If there is a failure,
@@ -44,19 +45,20 @@
         [opts-map [bindings & body]] (pop-opts-map more-args)]
     [docstring? opts-map bindings body]))

+
 ;; Formula Reporting -
 ;; one report for every batch of trials generated by a single formula run

 (def formula-reports (atom []))

 (def formula-emission-functions
-  {:pass (fn [])
-   :fail (fn [report-map]
-           (when-not (= :pass (:type report-map))
-             (ctf/note-fail))
-           (swap! formula-reports conj report-map))})
-
-
+  (merge emission-silence/emission-map
+         { :fail (fn [report-map]
+                   (when-not (= :pass (:type report-map))
+                     ;; TODO: This is temporary until Midje proper no longer
+                     ;; depends on clojure.test's counters.
+                     (ctf/note-fail))
+                   (swap! formula-reports conj report-map))}))

 (defmacro around-formula [& body]
   `(try
@@ -67,6 +69,9 @@
        (emit/fail failure#)
        (emit/pass))
      (reset! formula-reports []))))
+
+
+

 (defmacro formula
   "ALPHA/EXPERIMENTAL (subject to change) - Generative-style fact macro.


Add more producers

Add more producers

--- src/catalog/vubis.clj
+++ src/catalog/vubis.clj
@@ -138,8 +138,16 @@
    40 "BIT, München"
    50 "BSVÖ, Wien"
    103 "Paderborn"
+   104 "VzFB, Hannover"
+   106 "BBI, Wien"
+   108 "Stiftung für blinde und sehbehinderte Kinder und Jugendliche"
+   110 "SZB, St. Gallen"
    111 "RNIB, London"
-   120 "Braillists, Princeton"})
+   112 "Velen Integrationsspiel"
+   114 "IKS, Kassel"
+   120 "Braillists, Princeton"
+   121 "Bartkowski, München"
+   122 "Freunde blinder und sehbehinderter Kinder, Hamburg"})

 (def genre-code-to-genre
   "Mapping between genre-code and genre. Used for movies"


Better check for user visibility: entries can have :follow true or :unfollow false to be listed in replies.

--- src/oc/storage/db/common.clj
+++ src/oc/storage/db/common.clj
@@ -305,6 +305,8 @@
                          (r/add sort-value-base unread-cap-ms)
                          ;; The timestamp in seconds
                          sort-value-base)
+           ;; ***** Commented out since we want every entry no matter who commented *****
+           ;; ***** Uncomment this to show only entries with comments from others   *****
            ; :reply-authors (-> interactions-base
            ;                 (r/coerce-to :array)
            ;                 (r/map (r/fn [inter] (r/get-field inter [:author :user-id])))
@@ -319,6 +321,8 @@
        (r/filter query (r/fn [row]
         (r/and (r/gt (r/get-field row [:comments-count]) 0)
                ;; Filter out threads that have comments only from the current user
+               ;; ***** Commented out since we want every entry no matter who commented *****
+               ;; ***** Uncomment this to show only entries with comments from others   *****
                ; (-> (r/get-field row [:reply-authors])
                ;  (r/filter user-id)
                ;  (r/is-empty)
@@ -330,11 +334,18 @@
                             (r/le start (r/get-field row :sort-value))))
                ;; Filter on the user's visibility map:
                ;; - has :follow true
-               ;; - and has not :unfollor or :unfollow is false
-               (r/and (r/get-field row [:user-visibility (keyword user-id) :follow])
-                      (r/or (-> (r/get-field row [:user-visibility (keyword user-id)])
-                             (r/has-fields [:unfollow])
-                             r/not)
+               ;; - and has not :unfollow or :unfollow is false
+               ; (r/and (r/get-field row [:user-visibility (keyword user-id) :follow])
+               ;        (r/or (-> (r/get-field row [:user-visibility (keyword user-id)])
+               ;               (r/has-fields [:unfollow])
+               ;               r/not)
+               ;              (r/not (r/get-field row [:user-visibility (keyword user-id) :unfollow]))))
+               ;; Filter on user;s visibility map:
+               ;; - or has :follow true
+               ;; - or has :unfollow false
+               (r/or (r/get-field row [:user-visibility (keyword user-id) :follow])
+                     (r/and (-> (r/get-field row [:user-visibility (keyword user-id)])
+                             (r/has-fields [:unfollow]))
                             (r/not (r/get-field row [:user-visibility (keyword user-id) :unfollow])))))))
        ;; Sort
        (if-not count


Add parse-stream-strict.

Add parse-stream-strict.

--- src/cheshire/core.clj
+++ src/cheshire/core.clj
@@ -253,6 +253,26 @@
                      ^Reader rdr)
       key-fn nil array-coerce-fn))))

+(defn parse-stream-strict
+  "Returns the Clojure object corresponding to the given reader, reader must
+  implement BufferedReader. An optional key-fn argument can be either true (to
+  coerce keys to keywords),false to leave them as strings, or a function to
+  provide custom coercion.
+
+  The array-coerce-fn is an optional function taking the name of an array field,
+  and returning the collection to be used for array values.
+
+  Does not lazily parse top-level arrays."
+  ([rdr] (parse-stream-strict rdr nil nil))
+  ([rdr key-fn] (parse-stream-strict rdr key-fn nil))
+  ([^BufferedReader rdr key-fn array-coerce-fn]
+   (when rdr
+     (parse/parse-strict
+       (.createParser ^JsonFactory (or factory/*json-factory*
+                                       factory/json-factory)
+                      ^Reader rdr)
+       key-fn nil array-coerce-fn))))
+
 (defn parse-smile
   "Returns the Clojure object corresponding to the given SMILE-encoded bytes.
   An optional key-fn argument can be either true (to coerce keys to keywords),


CLJS-1179: strange load-file behavior

CLJS-1179: strange load-file behavior

cljs.repl/load-namespace:
  - sym can actually be a string as well, rename to ns

cljs.repl/load-file:
  - need to load dependencies before loading the compiled file

--- src/clj/cljs/repl.clj
+++ src/clj/cljs/repl.clj
@@ -167,23 +167,23 @@
   "Load a namespace and all of its dependencies into the evaluation environment.
   The environment is responsible for ensuring that each namespace is loaded once and
   only once."
-  ([repl-env sym] (load-namespace repl-env sym nil))
-  ([repl-env sym opts]
-   (let [sym      (if (and (seq? sym)
-                        (= (first sym) 'quote))
-                    (second sym)
-                    sym)
+  ([repl-env ns] (load-namespace repl-env ns nil))
+  ([repl-env ns opts]
+   (let [ns (if (and (seq? ns)
+                     (= (first ns) 'quote))
+               (second ns)
+               ns)
          ;; TODO: add pre-condition to source-on-disk, the
          ;; source must supply at least :url - David
-         sources  (cljsc/add-dependencies
-                    (merge (env->opts repl-env) opts)
-                    {:requires [(name sym)] :type :seed
-                     :url (:uri (cljsc/source-for-namespace
-                                  sym env/*compiler*))})
-         deps     (->> sources
-                    (remove (comp #{["goog"]} :provides))
-                    (remove (comp #{:seed} :type))
-                    (map #(select-keys % [:provides :url])))]
+         sources (cljsc/add-dependencies
+                   (merge (env->opts repl-env) opts)
+                   {:requires [(name ns)] :type :seed
+                    :url (:uri (cljsc/source-for-namespace
+                                 ns env/*compiler*))})
+         deps (->> sources
+                (remove (comp #{["goog"]} :provides))
+                (remove (comp #{:seed} :type))
+                (map #(select-keys % [:provides :url])))]
      (if (:output-dir opts)
        ;; REPLs that read from :output-dir just need to add deps,
        ;; environment will handle actual loading - David
@@ -478,8 +478,6 @@
         (let [env (assoc env :ns (ana/get-namespace ana/*cljs-ns*))]
           (evaluate-form repl-env env filename form))))))

-;; TODO: this should probably compile dependencies - David
-
 (defn load-file
   ([repl-env f] (load-file repl-env f *repl-opts*))
   ([repl-env f opts]
@@ -492,6 +490,8 @@
                        (assoc opts
                          :output-file
                          (cljsc/src-file->target-file src)))]
+        ;; need to load dependencies first
+        (load-dependencies repl-env (:requires compiled) opts)
         ;; make sure it's been analyzed, this is because if it's already compiled
         ;; cljs.compiler/compile-file won't do anything, good for builds,
         ;; but a bit annoying here


Parse port as integer

Parse port as integer

--- src/clj/ji/system.clj
+++ src/clj/ji/system.clj
@@ -9,7 +9,7 @@
 (defn system []
   {:game-envs (atom {})
    :client-chan (chan)
-   :port (:port env 8080)})
+   :port (Integer/parseInt (:port env "8080"))})

 (defn start [{:keys [game-envs client-chan] :as system}]
   (service/register-ws-app! game-envs client-chan)


Stop event propagation on history-reset. This removes the console warning.

--- src/cljs/svg/app.cljs
+++ src/cljs/svg/app.cljs
@@ -21,7 +21,9 @@
       [:div {:class "wrapper"}
        [:div {:class "form-group"}
         [:button {:class "btn btn-default"
-                  :onClick (fn [e] (reset! h []))} "History Reset"]
+                  :onClick (fn [e]
+                             (reset! h [])
+                             (.stopPropagation e))} "History Reset"]
         ]
        [:div {:class "form-group"}
         [:label {:for "history"} "History"]
@@ -36,8 +38,7 @@
                                (->> e
                                   (.-target)
                                   (.-value)
-                                  (from-history db h)
-                                  )))
+                                  (from-history db h))))
                  :onBlur (fn [e] (reset! active false))
                  }]]])))


Fix deprecation indicator.

Fix deprecation indicator.

--- src/afterglow/show.clj
+++ src/afterglow/show.clj
@@ -1129,7 +1129,7 @@
   address for each subsequent fixture; if not, the largest offset used by the
   fixture will be used to calculate a suitable offset."
   {:doc/format :markdown
-   :deprecated true}
+   :deprecated "0.1.2"}
   ([key fixture universe start-address count]
    (patch-fixture-group! key fixture universe start-address count (apply max (map :offset (:channels fixture)))))
   ([key fixture universe start-address count offset]


+(defn of) which passes allow an optional :show-notes to english.morphology/fo

--- src/babel/english.cljc
+++ src/babel/english.cljc
@@ -8,7 +8,7 @@
                                   small-lexicon small-plus-vp-pronoun
                                   small-plus-plus-np
                                   verbcoach]]
-   [babel.english.morphology :as morph :refer [fo]]
+   [babel.english.morphology :as morph]
    [babel.over :refer [over truncate]]
    [babel.parse :as parse]
    [clojure.repl :refer [doc]]
@@ -45,6 +45,11 @@
 (defn lookup [lexeme]
   ((:lookup medium) lexeme))

+(defn fo [expression
+          & {:keys [show-notes]
+             :or {show-notes true}}]
+  (morph/fo expression :show-notes show-notes))
+
 (defn generate
   [spec & {:keys [max-total-depth model truncate-children]
            :or {max-total-depth generate/max-total-depth


fix reference to inducer invoke-launchers

--- src/bract/core/dev.clj
+++ src/bract/core/dev.clj
@@ -131,7 +131,7 @@
   (echo/with-latency-capture "Launching application"
     (-> app-context
       (assoc (key kdef/ctx-launch?) true)
-      inducer/invoke-launcher
+      inducer/invoke-launchers
       record-context!))
   nil)


Nicer file selection/tab behavior

Nicer file selection/tab behavior

--- src/brevis/ui/core.clj
+++ src/brevis/ui/core.clj
@@ -94,7 +94,7 @@
   "The complete UI panel." (atom nil))

 (def chooser (javax.swing.JFileChooser.)) ; FileChooser hack to get system icons
-(def current-filename (atom nil))
+

 (defn get-editor
   "return the first editor window."
@@ -129,28 +129,42 @@
   "Check if a file is already open."
   [filename]
   (let [num-tabs (.getTabCount (:tabbed-panel @editor-window))
-        tab-names (map #(.getName (.getTabComponentAt (:tabbed-panel @editor-window) %)) (range num-tabs))]
-    (some #(= filename %) tab-names)))
+        tab-names (map #(.getToolTipTextAt (:tabbed-panel @editor-window) %) (range num-tabs))]
+    (some #(when (= filename (nth tab-names %)) %)
+          (range (count tab-names)))))

 (declare add-content-tab-from-filename)
 (defn open-file
   "Open a file and add  the tab if it isnt already open."
   [filename]
-  (when-not (is-open? filename);; could make tab active if it is already open
+  (if-let [tab-idx (is-open? filename)]
+    (.setSelectedIndex (:tabbed-panel @editor-window) tab-idx)
     (add-content-tab-from-filename filename @content-pane-params)))

 (defn a-open [e]
   (open-file (select-file)))

+(defn get-text-from-tab
+  "Return the text from a tab."
+  [tab-idx]
+  (let [component (.getTabComponentAt (:tabbed-panel @editor-window) tab-idx)]
+    (.getText (.getTextArea component))))
+
+(defn current-tab-index
+  "Return the index of the currently selected tab."
+  []
+  (.getSelectedIndex (:tabbed-panel @editor-window)))
+
 (defn a-save [e]
-  (spit @current-filename (.getText (:text-area (get-editor))))
-  #_(set-status "Wrote " filename "."))
+  (let [tab-idx (current-tab-index)]
+    (spit (.getName (.getTabComponentAt (:tabbed-panel @editor-window) tab-idx))
+          (get-text-from-tab tab-idx))))

 (defn a-save-as [e]
   (when-let [selected (select-file)]
-    #_(set-current-file selected)
-    (spit selected (.getText (:text-area (get-editor))))
-    #_(set-status "Wrote " filename ".")))
+    (let [tab-idx (.getSelectedIndex (:tabbed-panel @editor-window))]
+    (spit selected
+          (get-text-from-tab tab-idx)))))

 (defn a-exit  [e] (System/exit 0))
 (defn a-copy  [e] (.copy (:text-area (get-editor))))
@@ -199,7 +213,7 @@
 (defn a-eval-file
   "Evaluate a file."
   [e]
-  (eval-and-print (.getText (:text-area (get-editor))) false)
+  (eval-and-print (get-text-from-tab (current-tab-index)) false)
   #_(let [response-vals (nrepl/message (:client @repl) {:op "eval" :code (.getText (:text-area (get-editor)))})]
      (text! (:text-area @repl-output-window)
                           (with-out-str (doseq [resp response-vals]
@@ -251,6 +265,8 @@
     #_(println "Switching project:" proj)))

 (def ^{:private true} make-icon icon)
+
+

 (defn add-content-tab
   "Add a tab to the content pane."
@@ -289,8 +305,8 @@
                                :text filename #_(last (string/split @current-filename #"/")) #_@current-filename;; with text set to txt
                                :foreground :blue)
                       ;:filename @current-filename
-                      :tip @current-filename
-                      :icon (.getIcon chooser (file @current-filename))
+                      :tip filename
+                      :icon (.getIcon chooser (file filename))
                       :content (RTextScrollPane. textArea)})))

 (defn make-editor-window
@@ -595,10 +611,9 @@
     (reset! project-browser pb)
     (reset! repl-input-window ri)
     (reset! repl-output-window ro)
-    (reset! current-filename (:current-filename @current-profile))
     (make-ui)
     (load-file (str "src" File/separator "brevis" File/separator "ui" File/separator "keybinds.clj"))
-    (add-content-tab-from-filename @current-filename params)
+    #_(add-content-tab-from-filename @current-filename params)
     #_(when-not (empty? (:current-filename @current-profile))
        (.setText (:text-area ew) (slurp @current-filename)))))


Track full path for coll.

Track full path for coll.

--- src/cbfg/world/t2.cljs
+++ src/cbfg/world/t2.cljs
@@ -14,11 +14,11 @@
 (defn coll-handler [actx coll-state m]
   [coll-state nil])

-(defn make-coll [actx rev name kvs-mgr-ch]
+(defn make-coll [actx rev path kvs-mgr-ch]
   (let [coll-ch (achan actx)]
-    (state-loop actx [:coll name] coll-handler {})
+    (state-loop actx [:coll path rev] coll-handler {})
     {:rev rev
-     :name name
+     :path path
      :coll-ch coll-ch
      :kvs-mgr-ch kvs-mgr-ch}))

@@ -26,7 +26,8 @@

 (defn make-initial-server-state [actx]
   (let [kvs-mgr-ch (cbfg.kvs/make-kvs-mgr actx)
-        default-coll (make-coll actx 0 "default" kvs-mgr-ch)]
+        default-coll (make-coll actx 0 ["_lobby" "default" "default"]
+                                kvs-mgr-ch)]
     {:rev 0
      :realms {"_system" {:rev 0
                          :users {"admin" {:rev 0 :pswd "password"}}
@@ -95,7 +96,9 @@
                                              :colls])]
           (if (not (get (:key m) colls))
             (let [nrev (inc (:rev server-state))
-                  coll (make-coll actx nrev (:key m) (:kvs-mgr-ch server-state))]
+                  coll (make-coll actx nrev
+                                  [(:cur-realm m) (:cur-realm-collset m) (:key m)]
+                                  (:kvs-mgr-ch server-state))]
               ; TODO: audit log on success and failure.
               [(-> server-state
                    (assoc-in [:realms (:cur-realm m)


Implement Scavenge.

Implement Scavenge.

--- src/clj/game/cards.clj
+++ src/clj/game/cards.clj
@@ -154,7 +154,7 @@
    "Blue Sun: Powering the Future"
    {:abilities [{:msg (msg "add " (:title target) " to HQ and gain " (:cost target) " [Credits]")
                  :choices {:req #(:rezzed %)}
-                 :effect (effect (gain :credit (:cost target)) (move target :hand))}]}
+                 :effect (effect (gain :credit (:cost target)) (move (assoc target :rezzed false) :hand))}]}

    "Big Brother"
    {:req (req tagged) :effect (effect (gain :runner :tag 2))}
@@ -1566,6 +1566,24 @@
                  :prompt "Choose a program to install"
                  :choices (req (filter #(= (:type %) "Program") (:hand runner)))
                  :effect (effect (runner-install target))}]}
+
+   "Scavenge"
+   {:choices {:req #(= (:type %) "Program")}
+    :effect  (req (let [pr target]
+                       (trash state side pr)
+                       (resolve-ability state side
+                                        {:prompt  "Install a card from Grip or Heap?" :choices ["Grip" "Heap"]
+                                         :msg (msg "install a card from " target)
+
+                                         :effect  (req (let [fr target]
+                                                            (resolve-ability state side
+                                                              {:prompt "Choose a program to install"
+                                                               :choices (req (filter #(= (:type %) "Program")
+                                                                                ((if (= fr "Grip") :hand :discard ) runner)))
+                                                               :effect (effect (gain :credit (min (:cost target) (:cost pr)))
+                                                                               (runner-install target))
+                                                               } card nil)))
+                                         } card nil)))}

    "Scorched Earth"
    {:req (req tagged) :effect (effect (damage :meat 4))}


Fixed res route

Fixed res route

--- src/clj/ndt/server.clj
+++ src/clj/ndt/server.clj
@@ -38,7 +38,7 @@
   (context "/api" []
     (defroutes api-routes
       (POST "/login" {body :body} (authenticate body))))
-  (GET "*" _
+  (GET "/" _
     {:status 200
      :headers {"Content-Type" "text/html; charset=utf-8"}
      :body (io/input-stream (io/resource "public/index.html"))})


Add random-insertion flag to random-plush-genome-with-size

This brings the functions in random.clj back into a working state, but
there are other calls to random-plush-instruction-map that need to be
updated. Calls to random-plush-genome-with-size do not need to be
changed unless you want the flag to be set.

--- src/clojush/random.clj
+++ src/clojush/random.clj
@@ -75,11 +75,14 @@

 (defn random-plush-genome-with-size
   "Returns a random Plush genome containing the given number of points."
-  [genome-size atom-generators argmap]
-  (repeatedly genome-size
-              #(random-plush-instruction-map
+  ([genome-size atom-generators argmap]
+   (random-plush-genome-with-size genome-size atom-generators false argmap))
+  ([genome-size atom-generators random-insertion argmap]
+   (repeatedly genome-size
+               #(random-plush-instruction-map
                  atom-generators
-                 argmap)))
+                 random-insertion
+                 argmap))))

 (defn random-plush-genome
   "Returns a random Plush genome with size limited by max-genome-size."


green

green

--- src/cloogling/core.clj
+++ src/cloogling/core.clj
@@ -1,9 +1,11 @@
 (ns cloogling.core
   (:require [clojure.data.json :as json]))
+
+(defrecord entry [url])

 (defn get-entries
   "Get results from json data retrieved from engine"
   [x]
-  (-> x
+  (map (fn [x] (->entry (x "Url" ))) (-> x
       json/read-str
-      (get-in ["d" "results"])))
+      (get-in ["d" "results"]))))


Updated comments.

Updated comments.

--- src/cmr/common/xml.clj
+++ src/cmr/common/xml.clj
@@ -66,7 +66,7 @@
     (Boolean. s)))

 (defn datetimes-at-path
-  "Extracts a datetime from the given path in the XML structure."
+  "Extracts all the datetimes from the given path in the XML structure."
   [xml-struct path]
   (map p/string->datetime (strings-at-path xml-struct path)))


Focus management #38

Focus management #38

--- src/flatgui/focus.clj
+++ src/flatgui/focus.clj
@@ -7,32 +7,15 @@
 ; You must not remove this notice, or any other, from this software.

 (ns flatgui.focus
-    (:require [flatgui.base :as fg]
-      [flatgui.comlogic :as fgc]
-      [flatgui.inputchannels.awtbase :as inputbase]
-      [flatgui.inputchannels.mouse :as mouse]
-      [flatgui.inputchannels.keyboard :as keyboard])
-  (:import (java.awt.event KeyEvent)))
-
-(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 dir] {:mode :has-focus
-                                                                :focused-child permanent-owner-child
-                                                                :throw-mode dir})
-
-(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)))))
-
-;; For :parent-of-focused and :has-focus the latest focus movent direction (if any) is tracked in :throw-mode
-(defn focus-child-by-direction [child-id dir]
-  (assoc (focus-child child-id) :throw-mode dir))
+  (:require [flatgui.base :as fg]
+            [flatgui.comlogic :as fgc]
+            [flatgui.inputchannels.awtbase :as inputbase]
+            [flatgui.inputchannels.mouse :as mouse]
+            [flatgui.inputchannels.keyboard :as keyboard]
+            [flatgui.util.matrix :as m])
+  (:import (java.awt.event KeyEvent)
+           (java.util Comparator)))
+

 (defn accepts-focus? [component]
   (or
@@ -41,11 +24,59 @@
     ;; If the component has any child to which it can pass focus
     (some (fn [[_ c]] (accepts-focus? c)) (:children component))))

+(defn- get-accepting-children [child-map] (filter accepts-focus? (for [[_ v] child-map] v)))
+
+(def component-comparator
+  (reify Comparator
+    (compare [_this o1 o2]
+      (let [by-x (- (m/mx-x (:position-matrix o1)) (m/mx-x (:position-matrix o2)))]
+        (if (= by-x 0)
+          (- (m/mx-y (:position-matrix o1)) (m/mx-y (:position-matrix o2)))
+          by-x)))))
+
+(defn- sort-lines [lines] (map (fn [l] (sort component-comparator l)) lines))
+
+(defn- group-by-lines [accepting-children]
+  (let [cnt (count accepting-children)]
+    (loop [line-y1 []
+           line-y2 []
+           lines []
+           i 0]
+      (if (< i cnt)
+        (let [c (nth accepting-children i)
+              cy (m/mx-y (:position-matrix c))
+              line-index (if-let [matching (some
+                                             #(if (<= (nth line-y1 %) cy (nth line-y2 %)) %)
+                                             (range 0 (count lines)))]
+                           matching
+                           (count lines))
+              existing-line (< line-index (count lines))
+              line (if existing-line (nth lines line-index) #{})
+              cy2 (+ cy (m/y (:clip-size c)))]
+          (recur
+            (if existing-line line-y1 (assoc line-y1 line-index cy))
+            (assoc line-y2 line-index (if existing-line (max cy2 (nth line-y2 line-index)) cy2))
+            (assoc lines line-index (conj line c))
+            (inc i)))
+        (sort-lines lines)))))
+
+(fg/defevolverfn :focus-traversal-order
+  (let [accepting-children (get-accepting-children (get-property [:this] :children))]
+    (if (pos? (count accepting-children))
+      (let [lines (group-by-lines accepting-children)]
+        (mapcat (fn [i] (map :id (nth lines i))) (range 0 (count lines))))
+      [])))
+
+(defn get-child-ids-in-traversal-order [component]
+  (if-let [focus-traversal-order (:focus-traversal-order component)]
+    focus-traversal-order
+    (let [accepting-children (get-accepting-children (:children component))]
+      (mapv :id accepting-children))))
+
 (defn get-in-cycle
   ([component dir c-id]
-    (let [accepting-children (filter accepts-focus? (for [[_ v] (:children component)] v))
-          child-count (count accepting-children)
-          child-ids (mapv :id accepting-children)
+    (let [child-ids (get-child-ids-in-traversal-order component)
+          child-count (count child-ids)
           closed (:closed-focus-root component)
           cycle-keeper (fn [i]
                          (cond
@@ -62,6 +93,26 @@
                 :first (nth child-ids 0)
                 :last (nth child-ids (dec child-count))))))
   ([component dir] (get-in-cycle component dir nil)))
+
+(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 dir] {:mode :has-focus
+                                                                :focused-child permanent-owner-child
+                                                                :throw-mode dir})
+
+(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)))))
+
+;; For :parent-of-focused and :has-focus the latest focus movent direction (if any) is tracked in :throw-mode
+(defn focus-child-by-direction [child-id dir]
+  (assoc (focus-child child-id) :throw-mode dir))

 (fg/defevolverfn :focus-state
   (let [reason (fg/get-reason)


Add additional methods for number atomic types.

--- src/futura/atomic.clj
+++ src/futura/atomic.clj
@@ -38,7 +38,9 @@
   "A common abstraction for number atomic types."
   (get-and-add! [_ v] "Adds a delta and return the previous value.")
   (get-and-dec! [_] "Decrements the value and return the previous one.")
-  (get-and-inc! [_] "Increments the value and returns the previous one."))
+  (get-and-inc! [_] "Increments the value and returns the previous one.")
+  (dec-and-get! [_] "Decrements the value and return it.")
+  (inc-and-get! [_] "Increments the value and return it."))

 (deftype AtomicLong [^java.util.concurrent.atomic.AtomicLong av]
   IAtomicNumber
@@ -48,6 +50,11 @@
     (.getAndDecrement av))
   (get-and-inc! [_]
     (.getAndIncrement av))
+
+  (dec-and-get! [_]
+    (.decrementAndGet av))
+  (inc-and-get! [_]
+    (.incrementAndGet av))

   IAtomic
   (compare-and-set! [_ expected update]


Commit broken codes

Commit broken codes

--- src/googlica/core.clj
+++ src/googlica/core.clj
@@ -53,14 +53,47 @@
                                  (mapv (comp (partial mapv ->kebab-case-symbol) keys)))]
     `[~@required {:keys ~optional}]))

+(defn template->path-vector
+  ;;  "/b/{fooBar}/c/{bar} => ["/b/" foo-bar "/c/" bar ]"
+  [path-template arg-names]
+  (loop [result []
+         vars arg-names
+         template path-template]
+    (println {:result result})
+    (println {:vars vars})
+    (println {:template template})
+    (if-let [var (first vars)]
+      (let [placeholder-re (re-pattern (str "\\{" var "\\}"))
+            value-symbol (symbol (->kebab-case var))
+            [pre post] (s/split template placeholder-re)]
+        (recur
+         ;; result
+         (concat
+          result
+          [pre value-symbol])
+         ;; vars
+         (rest vars)
+         ;; template
+         post
+         ))
+      result)))
+
 ;; > (replace-path-vars "b/{bucket}/o/{object}")
 ;; => (str "b/" bucket "/o/" object)
-(defn replace-path-vars [path-template]
-  path-template)
+(defn generate-path [method]
+  (let [path-vector (template->path-vector
+                     (:path method)
+                     (->> method
+                          :parameters
+                          (filter (fn [[k v]](= "path" (:location v))))
+                          keys
+                          (map name)))]
+    `(str ~@path-vector)))
+

 (defn generate-request [base-url method]
   {:method (-> method :httpMethod s/lower-case keyword)
-   :url (str base-url (replace-path-vars (:path method)))})
+   :url (str base-url (generate-path method))})

 (defn generate-function-from-method
   [base-url method]


RDC - Add enumerations of rotation directions.

--- src/icfp2015/unit.clj
+++ src/icfp2015/unit.clj
@@ -8,8 +8,45 @@
         :pivot (f (:pivot unit)) })))

 (def translations
-  { :west [-1 0]
+  { :north [0 -2]
+    :west [-1 0]
     :east [1 0]
+    :south [0 2]
     :southwest [0 1]
-    :southeast [1 1] })
+    :southeast [1 1]
+})

+(defn rotate
+  "Rotate a unit around a pivot point"
+  [rotation, {:keys pi pj :as pivot}]
+  nil)
+
+(def rotations
+  [:counter-clockwise
+    { :origin [0 0]
+      :northwest :southwest
+      :northwest-offset :south
+      :north :southwest-offset
+      :west :southeast
+      :southwest :east
+      :southwest-offset :southeast-offset
+      :southeast :northeast
+      :south :northeast-offset
+      :southeast-offset :north
+      :east :northwest
+      :northeast :west
+      :northeast-offset :northwest-offset }
+  :clockwise
+    { :origin [0 0]
+      :northwest :east
+      :northwest-offset :northeast-offset
+      :north :southeast-offset
+      :west :southwest
+      :southwest :northwest
+      :southwest-offset :north
+      :southeast :west
+      :south :northwest-offset
+      :southeast-offset :southwest-offset
+      :east :southwest
+      :northeast :southeast
+      :northeast-offset :south }])


premutations

premutations

--- src/edge/webserver.clj
+++ src/edge/webserver.clj
@@ -9,6 +9,7 @@
    [clojure.java.io :as io]
    [clojure.tools.logging :refer :all]
    [com.stuartsierra.component :refer [Lifecycle using]]
+   [manifold.deferred :as d]
    [schema.core :as s]
    [cheshire.core :as json]
    [byte-streams :as b]
@@ -18,24 +19,52 @@
 (def URI "http://live-cdn.me-tail.net/cantor/api/wanda/garment-details/81e36a81-1921-4247-a8de-1ed7eb67840f?skus=nct_sandbox_dress_37_7cpxa7,nct_sandbox_trousers_2_5bahk2,nct_sandbox_jacket_4_btcjsf,nct_sandbox_coat_3_vxbetj,nct_sandbox_top_24_7k94td,nct_sandbox_skirt_15_04s5md,nct_sandbox_top_15_zwzenw")

 (defn get-garments [uri]
-  {:garments
+  {:garments/by-id
    (let [response (deref (http/get uri))]
      (if (= (:status response) 200)
-       (json/decode (b/to-string (:body response)) keyword)
+       (into {}
+             (for [garment (json/decode (b/to-string (:body response)) keyword)]
+               [(:id garment) garment]))
        (throw (Exception. "Oh no!!!"))))})
+
+(defn get-garments-async [uri]
+  (d/chain
+   (http/get uri)
+   (fn [response]
+     (if (= (:status response) 200)
+       {:garments/by-id
+        (into {}
+              (for [garment (json/decode (b/to-string (:body response)) keyword)]
+                [(:id garment) garment]
+                ))}
+       (throw (Exception. "Oh no!!!"))))))

 (defn readf [env k params]
   (infof "Reading k is %s" k)
+  (infof "env is %s" (dissoc env :state))
+  (infof "query is <%s>" (:query env))
+
   (let [st @(:state env)]
-    (if-let [[_ v] (find st k)]
-      {:value v}
-      {:value :not-found})))
+    (infof "state keys are %s" (keys st))
+    (infof "garments are %s"  (:garments/by-id st))
+    (case k
+      :garments/by-id
+      {:value (into {} ; just pick the garment properties we're being asked for
+                    (for [[id garment] (:garments/by-id st)]
+                      [id (select-keys garment (:query env))]
+                      ))}
+
+
+      (if-let [[_ v] (find st k)]
+        {:value v}
+        {:value :not-found}))))

 (defn mutatef [env k params]
   (infof "MUTATE! %s" k)
   {})

 (defn om-resource [parser app-state]
+  (infof "app-state is %s" @app-state)
   (resource
    {:methods
     {:post
@@ -52,11 +81,23 @@
 (defn create-api [parser app-state]
   ["/"
    [
+    ["hello" (yada "hello")]
     ["garments" (yada (get-garments URI))]
+
+    ;; You can't do this - yada doesn't know how to turn a promise
+    ;; into a resource (it can't infer much from a promise!)
+    ["garments-async-will-not-work" (yada (get-garments-async URI))]
+
+    ["garments-async" (yada
+                       (resource
+                        {:methods
+                         {:get {:produces "text/html" :response (get-garments-async URI)}}}))]
+
     ["api" (yada (om-resource parser app-state))]
     ["" (redirect "index.html")]
     ["favicon.ico" (yada nil)]
     ["" (yada (io/file "target/dev"))]
+    [true (yada nil)] ; 404 everything else
     ]])

 (s/defrecord Webserver [port :- (s/pred integer? "must be a port number!!")
@@ -65,14 +106,7 @@
                         api]
   Lifecycle
   (start [component]
-    (let [app-state (atom
-                     {:garments/by-id
-                      (let [response (deref (http/get URI))]
-                        (if (= (:status response) 200)
-                          (into {}
-                                (for [garment (json/decode (b/to-string (:body response)) keyword)]
-                                  [(:id garment) garment]))
-                          (throw (Exception. "Oh no!!!"))))})
+    (let [app-state (atom (get-garments URI))
           api (create-api (om/parser {:read readf :mutate mutatef}) app-state)]
       (assoc component
              :app-state app-state
@@ -87,3 +121,4 @@
   (using
    (map->Webserver {:port 3000})
    []))
+.


Add some more logging

Add some more logging

--- src/exploud/asgard.clj
+++ src/exploud/asgard.clj
@@ -107,7 +107,9 @@
   (at-at/after 1000 #(track-task region run-id workflow-id count) tp :desc (task-tracking-desc region run-id workflow-id)))

 (defn- track-task [region run-id workflow-id count]
+  (log/info "Generating task description")
   (let [desc (task-tracking-desc region run-id workflow-id)]
+    (log/info "Getting task")
     (if-let [task (task region run-id workflow-id)]
       (do
         (log/info "Storing information for" region run-id workflow-id)


format change percent

format change percent

--- src/notifier/core.clj
+++ src/notifier/core.clj
@@ -35,11 +35,12 @@
 (defn get-asx-prices []
   )

-(defn publish-event [level price percent]
-  (let[url (format  "https://maker.ifttt.com/trigger/BTC-AUD-%s/with/key/%s" level @ifttt-key)
+(defn publish-event [event & value]
+  (let[url (format  "https://maker.ifttt.com/trigger/%s/with/key/%s" event @ifttt-key)
+       body (into {} (for [i (range (count value))]
+                       [(->> i inc (str "value") keyword) value]))
        {:keys[status body]} @(http/post url {:headers {"Content-Type" "application/json"}
-                                            :body (json/write-str {:value1 (str price)
-                                                                   :value2 (str percent)})})]
+                                             :body (and value (json/write-str body))})]
     (println "published event:" url " result:" status ":" body)
     status))

@@ -61,7 +62,8 @@
         (doseq [c changes :let [last-price (@last-prices c)]]
           (if-let [change (and last-price (- price last-price))]
             (when (>= (Math/abs change) c)
-              (publish-event c price (-> change (* 100) (/ last-price)))
+              (publish-event (str "BTC-AUD-" c) (str price)
+                             (format "%+.1f%%" (-> change (* 100) (/ last-price))))
               (swap! last-prices assoc c price))
             (swap! last-prices assoc c price)))))))


Add alter column statement

Add alter column statement

--- src/clojure/clojurewerkz/cassaforte/new_query_api.clj
+++ src/clojure/clojurewerkz/cassaforte/new_query_api.clj
@@ -7,6 +7,7 @@
             Clause]
            [com.datastax.driver.core RegularStatement]
            [com.datastax.driver.core.schemabuilder SchemaBuilder SchemaBuilder$Direction
+
             SchemaBuilder$Caching SchemaBuilder$KeyCaching]
            )
   (:require [clojurewerkz.cassaforte.aliases :as alias]
@@ -512,7 +513,27 @@
                  (SchemaBuilder/createTable (name table-name)))
          (maybe-stringify))))

-(def alter-options
+;;
+;; Alter table
+;;
+
+(defn with-options
+  [options]
+  [:with-options options])
+
+(defn add-column
+  [column-name column-type]
+  [:add-column [column-name column-type]])
+
+(defn drop-column
+  [column-name]
+  [:drop-column column-name])
+
+(defn alter-column
+  [column-name column-type]
+  [:alter-column [column-name column-type]])
+
+(def ^:private alter-options
   {:default-ttl                 (fn [opts val] (.defaultTimeToLive opts val))
    :bloom-filter-fp-chance      (fn [opts val] (.bloomFilterFPChance opts val))
    :caching                     (fn [opts val] (.caching opts val))
@@ -528,12 +549,55 @@
    :compaction-options          (fn [opts val] (.compactionOptions opts val))
    :compression-options         (fn [opts val] (.compressionOptions opts val))})

+(defn resolve-alter-option
+  [option-name]
+  (if-let [res (get alter-options option-name)]
+    res
+    (throw (IllegalArgumentException. (str "Alter option "
+                                           " was not found, pick one of ("
+                                           (clojure.string/join "," (keys alter-options))
+                                           ")")))))
 (let [order
       {:with-options 1
        :add-column   2
        :alter-column 3
-       :drop-column  4
-       :with-options 5}])
+       :drop-column  4}
+      renderers
+      {:with-options (fn with-options-statement [query-builder options]
+                       (reduce
+                        (fn [query-builder [option-name option-vals]]
+                          ((resolve-alter-option option-name) option-vals))
+                        (.withOptions query-builder)
+                        options)
+                       query-builder)
+
+
+       :add-column   (fn add-column-statement [query-builder [column-name column-type]]
+                       (-> (.addColumn query-builder (name column-name))
+                           (resolve-primitive-type column-type)))
+
+       :alter-column (fn alter-column-statement [query-builder [column-name column-type]]
+                       (println (resolve-primitive-type column-type))
+                       (-> (.alterColumn query-builder (name column-name))
+                           (.type (resolve-primitive-type column-type))))
+
+       :drop-column  (fn drop-column-statement [query-builder column-name]
+                       (.dropColumn query-builder (name column-name)))
+
+
+
+       }]
+
+  (defn alter-table
+    [table-name & statements]
+    (->> statements
+         (sort-by #(get order (first %)))
+         (reduce (fn [builder [statement-name statement-args]]
+                   ((get renderers statement-name) builder statement-args))
+                 (SchemaBuilder/alterTable (name table-name)))
+         (maybe-stringify)))
+
+  )


sequentially plays songs in queue

sequentially plays songs in queue

--- src/frontend/core.cljs
+++ src/frontend/core.cljs
@@ -59,10 +59,17 @@
       (+ 1 (:num-of-queued-requests @app-state))
       :else (request-new-file))))

-(defn on-finish []
-  (println "Song has finished!"))
+

 (defn play-sound [sound-data]
+  (defn on-finish []
+    (println "Song has finished!")
+    (let [reader (new js/FileReader)
+          next-song-blob (nth (vals (:music-files @app-state))
+                              (:current-track @app-state) 1)]
+      (.readAsDataURL reader next-song-blob)
+      (set! (.-onloadend reader) #(play-sound (.-result reader)))))
+
   (if-not (nil? (:current-sound @app-state))
     (.destroySound js/soundManager (:current-sound-id @app-state)))
   (swap! app-state assoc :current-sound


fixed upload slots

fixed upload slots

--- src/frontend/core.cljs
+++ src/frontend/core.cljs
@@ -3,7 +3,7 @@
 (defonce room-id (.getAttribute (. js/document (getElementById "roomid")) "data"))
 (defonce socket (js/io))
 (defonce current-sound-id "current-song")
-(defonce default-upload-slots 1)
+(defonce default-upload-slots 2)
 (defonce default-download-slots 1)
 (defonce app-state (atom {:signed-in? false
                           :messages []
@@ -69,9 +69,8 @@
     (let [file (aget (.-files (.-target e)) 0)]
       (swap! app-state assoc :upload-queue (vec (cons file (:upload-queue @app-state))))
       (println "SHIT " (:num-of-uploads @app-state))
-      (if (= 1 (count (:upload-queue @app-state)))
         (if (> (:upload-slots @app-state) (:num-of-uploads @app-state))
-          (upload-file file))))))
+          (upload-file file)))))

 ; end stuff that should probably be cleaned up with react....


Proxy works even for new paths

Proxy works even for new paths

--- src/frontend/proxy.clj
+++ src/frontend/proxy.clj
@@ -66,8 +66,23 @@
           (let [local-response (handler req)]
             (when (not= 404 (:status local-response))
               local-response)))
-        (with-channel req channel
-          (request (proxy-request req options)
-                   (fn [response]
-                     (let [rewrite (if (:error response) rewrite-error rewrite-success)]
-                       (send! channel (rewrite response)))))))))
+        (letfn [(do-proxy-request [req channel]
+                  (request (proxy-request req options)
+                           (fn [response]
+                             (let [rewrite (if (:error response) rewrite-error rewrite-success)]
+                               (if (and (#{404 301} (:status response))
+                                        (not= "/dashboard" (:uri req)))
+
+                                 ;; If the backend returns a 404, try returning /dashboard instead,
+                                 ;; which is known to render the app page. This makes it easier to
+                                 ;; add new URLs in development, because we add see the new page on
+                                 ;; prod.circlehost without deploying the new route to the
+                                 ;; production backend. Just remember to deploy that route when
+                                 ;; shipping the feature, or the page will be unavailable in the
+                                 ;; production app.
+                                 (do-proxy-request (assoc req :uri "/dashboard") channel)
+
+                                 ;; Otherwise, proxy as normal.
+                                 (send! channel (rewrite response)))))))]
+          (with-channel req channel
+            (do-proxy-request req channel))))))


Extends navigation tests.

Extends navigation tests.

--- src/cljs/reagent_toolbox_docs/components/navigation.cljs
+++ src/cljs/reagent_toolbox_docs/components/navigation.cljs
@@ -17,12 +17,25 @@
          []
          (let [actions [{:label \"Alarm\" :raised true :icon \"access_alarm\"}
                         {:label \"Location\" :raised true :accent true :icon \"room\"}]
-               routes [{:href \"/navigation\" :label \"Inbox\" :icon \"inbox\"}
-                       {:href \"/naviation\" :active true :label \"Profile\" :icon \"person\"}]]
+               routes [{:href \"/navigation\"
+                        :label \"Favorite\"
+                        :icon \"favorite\"}
+                       {:href \"/navigation\"
+                        :active true
+                        :label \"History\"
+                        :icon \"history\"}]]
            (fn []
              [:div
               [reagent-toolbox.core/navigation {:type \"horizontal\" :actions actions}]
-              [reagent-toolbox.core/navigation {:type \"vertical\" :routes routes}]])))
+              [reagent-toolbox.core/navigation {:type \"vertical\"}
+               [reagent-toolbox.core/link {:href \"/navigation\"
+                                           :label \"Inbox\"
+                                           :icon \"inbox\"}]
+               [reagent-toolbox.core/link {:href \"/navigation\"
+                                           :active true
+                                           :label \"Profile\"
+                                           :icon \"person\"}]]
+              [reagent-toolbox.core/navigation {:routes routes}]])))

        [navigation-test]"]


update/rollback order form option #212

update/rollback order form option
#212

--- src/cljs/swarmpit/component/service/form_deployment.cljs
+++ src/cljs/swarmpit/component/service/form_deployment.cljs
@@ -79,6 +79,22 @@
        :onChange (fn [_ v]
                    (state/update-value [:update :delay] (parse-int v) form-value-cursor))})))

+(defn- form-update-order [value]
+  (form/comp
+    "ORDER"
+    (comp/select-field
+      {:value    value
+       :onChange (fn [_ _ v]
+                   (state/update-value [:update :order] v form-value-cursor))}
+      (comp/menu-item
+        {:key         "fuo1"
+         :value       "start-first"
+         :primaryText "start-first"})
+      (comp/menu-item
+        {:key         "fuo2"
+         :value       "stop-first"
+         :primaryText "stop-first"}))))
+
 (defn- form-update-failure-action [value]
   (form/comp
     "FAILURE ACTION"
@@ -87,15 +103,15 @@
        :onChange (fn [_ _ v]
                    (state/update-value [:update :failureAction] v form-value-cursor))}
       (comp/menu-item
-        {:key         "fdiu1"
+        {:key         "fufa1"
          :value       "pause"
          :primaryText "pause"})
       (comp/menu-item
-        {:key         "fdiu2"
+        {:key         "fufa2"
          :value       "continue"
          :primaryText "continue"})
       (comp/menu-item
-        {:key         "fdiu3"
+        {:key         "fufa3"
          :value       "rollback"
          :primaryText "rollback"}))))

@@ -123,6 +139,22 @@
        :onChange (fn [_ v]
                    (state/update-value [:rollback :delay] (parse-int v) form-value-cursor))})))

+(defn- form-rollback-order [value]
+  (form/comp
+    "ORDER"
+    (comp/select-field
+      {:value    value
+       :onChange (fn [_ _ v]
+                   (state/update-value [:rollback :order] v form-value-cursor))}
+      (comp/menu-item
+        {:key         "fro1"
+         :value       "stop-first"
+         :primaryText "stop-first"})
+      (comp/menu-item
+        {:key         "fro2"
+         :value       "start-first"
+         :primaryText "start-first"}))))
+
 (defn- form-rollback-failure-action [value]
   (form/comp
     "FAILURE ACTION"
@@ -131,11 +163,11 @@
        :onChange (fn [_ _ v]
                    (state/update-value [:rollback :failureAction] v form-value-cursor))}
       (comp/menu-item
-        {:key         "fdir1"
+        {:key         "frfa1"
          :value       "pause"
          :primaryText "pause"})
       (comp/menu-item
-        {:key         "fdir2"
+        {:key         "frfa2"
          :value       "continue"
          :primaryText "continue"}))))

@@ -168,6 +200,7 @@
        (html (form/subsection "Update Config"))
        (form-update-parallelism (:parallelism update))
        (form-update-delay (:delay update))
+       (form-update-order (:order update))
        (form-update-failure-action (:failureAction update))
        (when (= "rollback" (:failureAction update))
          (html
@@ -175,4 +208,5 @@
             (form/subsection "Rollback Config")
             (form-rollback-parallelism (:parallelism rollback))
             (form-rollback-delay (:delay rollback))
+            (form-rollback-order (:order rollback))
             (form-rollback-failure-action (:failureAction rollback))])))]))