hook up resend invoice dangerzone api

hook up resend invoice dangerzone api

--- src-cljs/frontend/controllers/controls.cljs
+++ src-cljs/frontend/controllers/controls.cljs
@@ -1219,14 +1219,20 @@
   [target message {:keys [invoice-id]} previous-state current-state]
   (let [uuid frontend.async/*uuid*
         api-ch (get-in current-state [:comms :api])
-        org-name (get-in current-state state/org-name-path)]
+        {org-name :name
+         vcs-type :vcs_type} (get-in current-state state/org-data-path)]
     (go
       (let [api-result (<! (ajax/managed-ajax
                               :post
-                              (gstring/format "/api/v1/organization/%s/invoice/resend" org-name)
+                              (gstring/format "/api/dangerzone/organization/%s/%s/invoice/resend"
+                                              vcs-type
+                                              org-name)
                               :params {:id invoice-id}))]
         ;; TODO Handle this message in the API channel
-        (put! api-ch [:resend-invoice (:status api-result) (assoc api-result :context {:org-name org-name})])
+        (put! api-ch [:resend-invoice
+                      (:status api-result)
+                      (assoc api-result :context {:org-name org-name
+                                                  :vcs-type vcs-type})])
         (release-button! uuid (:status api-result))))))

 (defmethod post-control-event! :cancel-plan-clicked


Fix failing test.

Fix failing test.

--- test/onyx/health_test.clj
+++ test/onyx/health_test.clj
@@ -126,7 +126,7 @@
                                                                  "allocation-version" 4
                                                                  "slot-id" 0
                                                                  "task-id" :my/inc
-                                                                 "group" (pr-str "eniensrats?")
+                                                                 "group" (pr-str "A stealthy fo")
                                                                  "window-id" window-id
                                                                  "peer-id" (first peers)
                                                                  "job-id" (str job-id)}})]


Documentation for new interpretation of missing arguments.

--- src/midje/doc.clj
+++ src/midje/doc.clj
@@ -27,7 +27,8 @@
                  midje-print-level
                  midje-print-levels
                  guide])
-(def for-repl  '[midje-repl])
+(def for-repl  '[midje-repl
+                 midje-repl-working-set])

 (def ^{:doc "
    Detailed help:
@@ -52,19 +53,23 @@
   To control verbosity of output, use print levels described by
   `(doc midje-print-levels)`.

+  The repl tools track the namespaces you're currently working
+  on in the \"working set\". See `(doc midje-repl-working-set)`.
+
   ----- Loading facts
   You load facts by namespace.
   (load-facts <ns> <ns>...)
   (load-facts 'midje.util.*)      ; Load all namespaces below midje.util.
+  (load-facts)                    ; Reload the working set namespaces.
   (load-facts <ns> :integration)  ; Apply filters to facts.

   ----- Checking facts, once loaded
-  (check-facts)                     ; in current namespace
+  (check-facts)                     ; in the working set
   (check-facts <ns> <ns>...)        ; in given namespaces
   (check-facts :all)                ; all defined facts
   (check-facts :all :integration)   ; all integration tests
-  (check-facts \"partial\")         ; in this namespace when
-                                    ; name contains \"partial\"
+  (check-facts \"partial\")         ; all files in the working set
+                                    ; whose name contains \"partial\"
   There are other filter arguments.

   ----- Rerunning facts
@@ -96,6 +101,51 @@
   -- (fact-namespace <ff>)
   -- (fact-description <ff>)         ; the doc string; might be nil
   "} midje-repl)
+
+;; working set
+(def ^{:doc "
+  The working set is a list of namespaces used as the
+  default argument to repl functions. For example:
+
+    ;; Load multiple namespaces' worth of facts:
+    (load-facts 'midje.util.*)
+
+    ;; Reload them:
+    (load-facts)
+
+    ;; Check them:
+    (check-facts)
+
+    ;; Forget them:
+    (forget-facts)
+
+    ;; In the above case, `forget-facts` doesn't
+    ;; clear the working set, so you can reload it:
+    (load-facts)
+
+  The working set changes whenever namespace-like arguments
+  are given to the repl functions. (\"Namespace-like\" arguments
+  are namespaces, symbols naming namespaces, `:all`, and
+  wildcarded namespaces like `midje.ideas.*`.
+
+  You can see the current working set with `(working-set)`.
+
+  Here is an example of the use of the working set:
+
+    ;; Suppose there are two test namespaces,
+    ;; `test.t1` and `test.t2`.
+    (load-facts :all)
+
+    ;; Check both sets of facts.
+    (check-facts)
+
+    ;; Check only one namespace
+    (check-facts 'test.t1)
+
+    ;; The working set is now only `test.t1`, so
+    ;; `(forget-facts)` would only facts facts
+    ;; in that namespace.
+  "} midje-repl-working-set)

 ;; print-levels
 (def ^{:doc "


+(def the-nice-small-grammar)

+(def the-nice-small-grammar)

--- src/babel/english/lab.cljc
+++ src/babel/english/lab.cljc
@@ -15,18 +15,64 @@
 (defn nursery
   "very fast and easy sentences."
   []
-  (let [
-        grammar
+  (let [grammar
+         (filter
+          #(= "sentence-nonphrasal-head" (u/get-in % [:rule]))
+          (:grammar model))
+        spec {:synsem {:cat :verb
+                       :subcat []}}]
+    (repeatedly
+     #(println
+       (morph (binding [babel.generate/println? false
+                        babel.generate/truncate? true
+                        babel.generate/grammar grammar]
+                (time (generate spec model)))
+              :show-notes false)))))
+
+(def the-nice-small-grammar
+   #{"sentence-phrasal-head"
+     "sentence-nonphrasal-head"
+     "transitive-vp-nonphrasal-head"
+     "transitive-vp-phrasal-head"
+     "noun-phrase"})
+
+(defn x-name-is-y
+  "sentences e.g. 'my name is Luisa'"
+  []
+  (let [grammar
         (filter
-            #(or (= "noun-phrase" (u/get-in % [:rule]))
-                 (= "sentence-phrasal-head" (u/get-in % [:rule]))
-                 (= "transitive-vp-nonphrasal-head" (u/get-in % [:rule])))
-            (:grammar model))
+         #(contains? the-nice-small-grammar
+                     (u/get-in % [:rule]))
+          (:grammar model))

         spec {:synsem {:cat :verb
                        :sem {:pred :be-called
-                             :subj {:pred :top}
+                             :subj {:pred :I}
                              :iobj {:pred :luisa}}
+                       :subcat []}}]
+    (repeatedly
+     #(println
+       (morph (binding [babel.generate/println? false
+                        babel.generate/truncate? true
+                        babel.generate/grammar grammar]
+                (time (generate spec model)))
+              :show-notes false)))))
+
+(defn antonia-had-read
+  "very specific semantics"
+  []
+  (let [grammar
+        (filter
+         #(contains? the-nice-small-grammar
+                     (u/get-in % [:rule]))
+          (:grammar model))
+
+        spec {:synsem {:cat :verb
+                       :sem {:pred :read
+                             :tense :past
+                             :aspect :pluperfect
+                             :subj {:pred :antonia}
+                             :obj :unspec}
                        :subcat []}}]
     (repeatedly
      #(println


WIP: display extensions list

WIP: display extensions list

--- src/chat/client/views/pages/extensions.cljs
+++ src/chat/client/views/pages/extensions.cljs
@@ -9,4 +9,9 @@
     om/IRender
     (render [_]
       (dom/div #js {:className "page extensions"}
-        (dom/h1 nil "Extensions")))))
+        (dom/h1 nil "Extensions")
+        (apply dom/div #js {:className "extensions-list"}
+          (map (fn [ext]
+                 (dom/div #js {:className "extension"}
+                   (str (ext :id) ": " (name (ext :type)))))
+               (get-in data [:groups (data :open-group-id) :extensions])))))))


db-conn fixes; rework create/update fns; queue fn

--- src/navigator.clj
+++ src/navigator.clj
@@ -70,187 +70,50 @@

 (defn get-perf-asmt
   "Get perf-asmt by shared key"
-  [conn id-sk]
-  (get-entity conn '[:find ?e
+  [db-conn id-sk]
+  (get-entity db-conn '[:find ?e
                      :in $ ?id-sk
                      :where [?e :perf-asmt/id-sk ?id-sk]]
               id-sk))

 (defn get-user2comp
   "Get user2comp by sis-user-id and comp"
-  [conn sis-user-id comp-eid]
-  (get-entity conn '[:find ?e
+  [db-conn sis-user-id comp-eid]
+  (get-entity db-conn '[:find ?e
                      :in $ ?sis-user-id ?comp-eid
                      :where [?e :user2comp/sis-user-id ?sis-user-id]
                             [?e :user2comp/comp ?comp-eid]]))

 ;; Creation/update functions

-;; TODO: schematode may have a thing that does this?
 (defn tx
   "transact with schematode constraints"
-  [conn txs]
-  (schematode/tx conn :enforce txs))
+  [db-conn txs]
+  (schematode/tx db-conn :enforce txs))

-#_(defn- transact-entity-fn
-  [valid-fields]
-  (fn [conn eid & {:as fields}]
-    (tx conn (merge {:db/id eid} (select-keys fields valid-fields)))))
+(defn filter-op-attrs*
+  [op entity entity-type]
+  (select-keys entity (conj (entity-type op) :db/id)))

-(defn- update-entity-fn
-  [updatable-fields transact-fn]
-  (fn [conn & {:keys [eid] :as entity}]
-    (apply transact-fn conn eid (select-keys entity updatable-fields))))
+(def filter-update-attrs
+  (partial filter-op-attrs* updatable-attrs))

+;; TODO: should we rename this?
+(def filter-create-attrs
+  (partial filter-op-attrs* valid-attrs))

+(defn tx-update-entity
+  [db-conn entity entity-type]
+  (tx db-conn [(filter-update-attrs entity entity-type)]))

+(defn tx-entity
+  [db-conn entity entity-type]
+  (tx db-conn [(filter-create-attrs entity entity-type)]))

-(defn update-competency2
-  [conn comp]
-  (tx conn [(select-keys entity (conj :db/id (:comp updatable-fields)))]))
+;; queue functions

-(defn filter-attrs
-  [entity entity-type]
-  (select-keys entity (conj :db/id (entity-type updatable-fields))))
-
-(defn update-competency3
-  [conn comp]
-  (tx conn [(filter-attrs comp :comp)]))
-
-(defn update-entity
-  [conn entity-type entity]
-  (tx conn [(filter-attrs entity entity-type)]))
-
-(defn create-competency2
-  "Create a new competency"
-  ;; TODO: where does id-sk come from?
-  [conn name version status & {:as optional-fields}]
-  (tx conn [(merge (select-keys optional-fields (:comp valid-fields))
-                   {:db/id (d/tempid :db.part/user)
-                    :comp/name name
-                    :comp/version version
-                    :comp/status status})]))
-
-
-(defn- transact-competency
-  [conn eid & {:as entity}]
-  (tx conn [(merge {:db/id eid} (select-keys entity (:comp valid-fields)))]))
-
-(defn update-competency
-  ;; TODO: refactor me?
-  "Consider using :comp/id-sk instead of the entity ID here, IF every :comp has a :comp/id-sk."
-  [conn entity]
-  ;;[(:db/id entity) (select-keys entity (:comp updatable-fields))]
-  (apply transact-competency conn (:db/id entity) (flatten (seq (select-keys entity (:comp updatable-fields))))))
-
-(defn create-competency
-  "Create a new competency"
-  ;; TODO: where does id-sk come from?
-  [conn name version status & {:as optional-fields}]
-  (apply transact-competency conn (d/tempid :db.part/user)
-         :comp/name name
-         :comp/version version
-         :comp/status status
-         (flatten (seq optional-fields))))
-
-(def transact-comp-tag
-  1
-  #_
-  (transact-entity-fn [:comp-tag/name
-                       :comp-tag/description
-                       :comp-tag/version
-                       :comp-tag/type
-                       :comp-tag/isrequestable
-                       :comp-tag/icon
-                       :comp-tag/status
-                       :comp-tag/isfinal
-                       :comp-tag/disp-ctxs
-                       :comp-tag/child-of]))
-
-(def update-comp-tag
-  ;; TODO: again, can we update name-version?
-  (update-entity-fn [:comp-tag/description
-                     :comp-tag/type
-                     :comp-tag/isrequestable
-                     :comp-tag/icon
-                     :comp-tag/status
-                     :comp-tag/isfinal] transact-comp-tag))
-
-(defn create-comp-tag
-  "Create a new competency tag"
-  [conn name version type status & {:as optional-fields}]
-  (apply transact-comp-tag conn (d/tempid :db.part/user)
-         :comp-tag/name name
-         :comp-tag/version version
-         :comp-tag/type type
-         :comp-tag/status status
-         (flatten (seq optional-fields))))
-
-(def update-comp-tag-disp-ctx
-  #_
-  (transact-entity-fn [:comp-tag-disp-ctx/name]))
-
-(defn create-comp-tag-disp-ctx
-  "Create a new competency tag display context"
-  [conn name]
-  (apply update-comp-tag-disp-ctx (d/tempid :db.part/user) :comp-tag-disp-ctx/name name))
-
-(def transact-perf-asmt
-  #_
-  (transact-entity-fn [:perf-asmt/id-sk
-                       :perf-asmt/name
-                       :perf-asmt/version
-                       :perf-asmt/type
-                       :perf-asmt/duration-rating-days
-                       :perf-asmt/comp]))
-
-(def update-perf-asmt
-  ;; TODO: can we update name version type?
-  (update-entity-fn [:perf-asmt/duration-rating-days] transact-perf-asmt))
-
-(defn create-perf-asmt
-  "Create a new perf assessment"
-  ;; TODO: where does id-sk come from?
-  ;; TODO: should name be required?
-  [conn version type & {:as optional-fields}]
-  (apply transact-perf-asmt (d/tempid :db.part/user)
-         :perf-asmt/version version
-         :perf-asm/type type
-         (flatten (seq optional-fields))))
-
-(def transact-user2comp
-  1
-  #_
-  (transact-entity-fn [:user2comp/sis-user-id
-                       :user2comp/comp
-                       :user2comp/start-date
-                       :user2comp/iscomplete
-                       :user2comp/isoverridden
-                       :user2comp/completion-date
-                       :user2comp/proposed-completion-date
-                       :user2comp/current-score
-                       :user2comp/final-score
-                       :user2comp/score-denominator
-                       :user2comp/score-type
-                       :user2comp/qualitative-notes]))
-
-(def update-user2comp
-  (update-entity-fn [:user2comp/start-date
-                     :user2comp/iscomplete
-                     :user2comp/isoverridden
-                     :user2comp/completion-date
-                     :user2comp/proposed-completion-date
-                     :user2comp/current-score
-                     :user2comp/final-score
-                     :user2comp/score-denominator
-                     :user2comp/score-type
-                     :user2comp/qualitative-notes]
-                    transact-user2comp))
-
-(defn create-user2comp
-  "Create a new user2comp"
-  [conn sis-user-id comp & {:as optional-fields}]
-  (apply transact-user2comp (d/tempid :db.part/user)
-         :user2comp/sis-user-id sis-user-id
-         :user2comp/comp comp
-         (flatten (seq optional-fields))))
+(defn task-in [db-conn message]
+  (tx-entity db-conn (merge {:db/id (d/tempid (get-partition :task))
+                          :task/id-sk (str (get-in message [:header :entity-id :task-id]))}
+                         (prefix-keys (get-in message [:payload :entity]) :task))
+             :task))


added a test for real example: method can be faked with cyclical return values

--- test/unit/reify_fake.cljc
+++ test/unit/reify_fake.cljc
@@ -84,7 +84,7 @@
     (let [cow (f/reify-fake p/AnimalProtocol
                             (speak :optional-fake [["you"] "moo to you!"
                                                    [f/any] (fn [this _]
-                                                              (p/speak this "you"))]))]
+                                                             (p/speak this "you"))]))]
       (is (= "moo to you!" (p/speak cow "Bob"))))))

 (u/-deftest
@@ -411,4 +411,17 @@
          (.charAt foo 100)

          (is (f/method-was-called p/save foo []))
-         (is (f/method-was-called "charAt" foo [100]))))))+         (is (f/method-was-called "charAt" foo [100]))))))
+
+(defprotocol WebService
+  (save [this data]))
+
+(u/-deftest
+  "real example: method can be faked with cyclical return values"
+  (f/with-fakes
+    (let [service (f/reify-fake WebService
+                                (save :fake [[:--data--]
+                                             (f/cyclically [503 200])]))]
+      (is (= 503 (save service :--data--)))
+      (is (= 200 (save service :--data--)))
+      (is (= 503 (save service :--data--))))))


CMR-276: Reset collection revision limit to 10.

--- src/cmr/metadata_db/services/concept_service.clj
+++ src/cmr/metadata_db/services/concept_service.clj
@@ -26,7 +26,7 @@
 (def num-revisions-to-keep-per-concept-type
   "Number of revisions to keep by concept-type. If a concept instance has more than the number
   of revisions here the oldest ones will be deleted."
-  {:collection 2
+  {:collection 10
    :granule 1})

 (def concept-truncation-batch-size


Implement Sensei

Implement Sensei

--- src/clj/game/cards-ice.clj
+++ src/clj/game/cards-ice.clj
@@ -7,7 +7,7 @@
 (def cards-ice
   {"Archangel"
    {:access {:optional
-             {:prompt "Pay 3 [Credits] to force Runner to encounter Archangel?"
+             {:prompt "Pay 3 [Credits] to force Runner to encounter Archangel?"
               :yes-ability {:cost [:credit 3]
                             :effect (req (system-msg state :corp "pays 3 [Credits] to force the Runner to encounter Archangel"))}}}
     :abilities [{:label "Trace 6 - Add 1 installed card to the Runner's Grip"
@@ -456,7 +456,7 @@
                  :trace {:base 3 :msg "give the Runner 1 tag" :effect (effect (tag-runner :runner 1))}}
                 {:label "End the run if a Current is active"
                  :req (req (or (not (empty? (runner :current)))
-                               (not (empty? (corp :current)))))
+                               (not (empty? (corp :current)))))
                  :effect (effect (end-run)) :msg "end the run"}]}

    "NEXT Bronze"
@@ -539,6 +539,10 @@
                  :trace {:base (req (or (:advance-counter card) 0)) :effect (effect (tag-runner :runner 1))
                          :msg "give the Runner 1 tag"}}]}

+   "Sensei"
+   {:abilities [{:label "Give each other ICE encountered \"End the run\" for the remainder of the run"
+                 :msg (msg "give each other ICE encountered \"[Subroutine] End the run\" after all its other subroutines for the remainder of the run")}]}
+
    "Shadow"
    {:advanceable :always
     :abilities [{:msg "gain 2 [Credits]" :effect (effect (gain :credit 2))}


fixed the message of active ability of Yagura

--- src/clj/game/cards-ice.clj
+++ src/clj/game/cards-ice.clj
@@ -985,9 +985,10 @@
    "Yagura"
    {:abilities [(do-net-damage 1)
                 {:msg "look at the top card of R&D"
-                 :optional {:prompt (msg "Add " (:title (first (:deck corp))) " to bottom of R&D?")
-                            :msg "add the top card of R&D to the bottom"
-                            :yes-ability {:effect (effect (move (first (:deck corp)) :deck))}}}]}
+                 :optional {:prompt (msg "Move " (:title (first (:deck corp))) " to the bottom of R&D?")
+
+                            :yes-ability {:effect (effect (move (first (:deck corp)) :deck)
+                                                          (do (system-msg state side "uses Yagura to move the top card of R&D to the bottom")))}}}]}

    "Zed 1.0"
    {:abilities [(do-brain-damage 1)]}})


fix Cell Portal

fix Cell Portal

--- src/clj/game/cards-ice.clj
+++ src/clj/game/cards-ice.clj
@@ -277,7 +277,10 @@

    "Cell Portal"
    {:abilities [{:msg "make the Runner approach the outermost ICE"
-                 :effect (req (swap! state assoc-in [:run :position] 0) (derez state side card))}]}
+                 :effect (req (let [srv (first (:server run))
+                                    n (count (get-in @state [:corp :servers srv :ices]))]
+                                (swap! state assoc-in [:run :position] n)
+                                (derez state side card)))}]}

    "Changeling"
    (morph-ice "Barrier" "Sentry" end-the-run)


Update Mac file name possibilities

Update Mac file name possibilities

--- src/cljs/app/analysis.cljs
+++ src/cljs/app/analysis.cljs
@@ -8,7 +8,7 @@
   (cond
     (boolean (re-find #"windows" url)) "Windows"
     (boolean (re-find #"linux" url)) "Linux"
-    (boolean (re-find #".dmg" url)) "Mac OS X"
+    (boolean (re-find #"mac|.dmg" url)) "Mac OS X"
     :else "Other"))

 (defn get-word-size


Fix form validation issue due to watch behavior

--- src/cljs/re_form/core.cljs
+++ src/cljs/re_form/core.cljs
@@ -1,5 +1,5 @@
 (ns re-form.core
-  (:require-macros [reagent.ratom :refer [reaction]]
+  (:require-macros [reagent.ratom :refer [reaction run!]]
                    [cljs.core.async.macros :refer [go]])
   (:require [reagent.core :as reagent]
             [re-frame.core :as rf]
@@ -35,7 +35,10 @@
 (rf/reg-sub-raw
  :re-form/form-value
  (fn [db [_ form-name]]
-   (reaction @(reagent/cursor db [:re-form form-name :value]))))
+   ;; Related to this issues:
+   ;; https://github.com/reagent-project/reagent/issues/244
+   ;; https://github.com/reagent-project/reagent/issues/116
+   (run! @(reagent/cursor db [:re-form form-name :value]))))

 (rf/reg-sub-raw
  :re-form/is-form-submitting


add api parameter to parse-ns defmulti

add api parameter to parse-ns defmulti

--- src/cljs_api_gen/parse.clj
+++ src/cljs_api_gen/parse.clj
@@ -48,49 +48,48 @@
     "tools.reader" *treader-tag*
     nil))

-(def normally-parsed-ns?
-  #{"cljs.pprint"
-    "cljs.reader"
-    "clojure.set"
-    "clojure.string"
-    "clojure.walk"
-    "clojure.zip"
-    "clojure.data"
-    "clojure.browser.dom"
-    "clojure.browser.event"
-    "clojure.browser.net"
-    "clojure.browser.repl"
-    "clojure.core.reducers"
-    "clojure.reflect"
-    "cljs.nodejs"
-    "cljs.nodejscli"
-    })
-
-(def custom-parsed-ns?
-  #{"cljs.core"
-    "cljs.test"
-    "cljs.repl"
-    "special"     ;; <-- pseudo-namespace for special forms
-    "specialrepl" ;; <-- pseudo-namespace for REPL special forms
-    "syntax"      ;; <-- pseudo-namespace for syntax forms
-    })
-
-(def cljs-lib-namespaces
-  (->> (into normally-parsed-ns? custom-parsed-ns?)
-       (remove #{"syntax"})))
-
-(def cljs-compiler-namespaces
-  #{"cljs.analyzer.api"
-    "cljs.build.api"
-    "cljs.compiler.api"
-    "cljs.repl"
-    "cljs.repl.browser"
-    "cljs.repl.nashorn"
-    "cljs.repl.node"
-    "cljs.repl.reflect"
-    "cljs.repl.rhino"
-    "cljs.repl.server"
-    })
+(def namespaces
+  "api -> namespaces, and namespace -> parse type"
+
+  {:syntax
+   {"syntax"                :custom} ;; <-- pseudo-namespace for syntax forms
+
+   :library
+   {"cljs.pprint"           :normal
+    "cljs.reader"           :normal
+    "clojure.set"           :normal
+    "clojure.string"        :normal
+    "clojure.walk"          :normal
+    "clojure.zip"           :normal
+    "clojure.data"          :normal
+    "clojure.browser.dom"   :normal
+    "clojure.browser.event" :normal
+    "clojure.browser.net"   :normal
+    "clojure.browser.repl"  :normal
+    "clojure.core.reducers" :normal
+    "clojure.reflect"       :normal
+    "cljs.nodejs"           :normal
+
+    "cljs.core"             :custom
+    "cljs.test"             :custom
+    "cljs.repl"             :custom
+    "special"               :custom ;; <-- pseudo-namespace for special forms
+    "specialrepl"           :custom ;; <-- pseudo-namespace for REPL special forms
+    }
+
+   :compiler
+   {"cljs.analyzer.api"     :normal
+    "cljs.build.api"        :normal
+    "cljs.compiler.api"     :normal
+    "cljs.repl"             :normal
+    "cljs.repl.browser"     :normal
+    "cljs.repl.node"        :normal
+    "cljs.repl.reflect"     :normal
+    "cljs.repl.rhino"       :normal
+    "cljs.repl.server"      :normal
+
+    "cljs.repl.nashorn"     :custom
+    }})

 ;;--------------------------------------------------------------------------------
 ;; Functions marked as macros
@@ -756,14 +755,12 @@
 ;;------------------------------------------------------------

 (defmulti parse-ns
-  (fn [ns-]
-    (cond
-      (custom-parsed-ns?   ns-) ns-
-      (normally-parsed-ns? ns-) :default-lib
-      (cljs-compiler-namespaces ns-) :default-compiler
-      :else nil)))
-
-(defmethod parse-ns "cljs.core" [ns-]
+  (fn [ns- api]
+    (if (= :custom (get-in namespaces [api ns-]))
+      [ns- api]
+      [:default api])))
+
+(defmethod parse-ns ["cljs.core" :library] [ns- api]
   ;; NOTE: Concatenation order is important here
   ;; so previously defined macros/functions are overwritten
   ;; by subsequent ones.
@@ -784,7 +781,7 @@
             (get-core-type-members type-names))))

 ;; pseudo-namespace since special forms don't have a namespace
-(defmethod parse-ns "special" [ns-]
+(defmethod parse-ns ["special" :library] [ns- api]
   (let [docs (->> (read-ns-forms "cljs.repl" :compiler)
                   (apply concat)
                   (keep #(parse-special-docs %))
@@ -802,7 +799,7 @@
     specials))

 ;; pseudo-namespace since repl special forms don't have a namespace
-(defmethod parse-ns "specialrepl" [ns-]
+(defmethod parse-ns ["specialrepl" :library] [ns- api]
   (let [forms (apply concat (read-ns-forms "cljs.repl" :compiler))
         docs (first (keep parse-repl-special-docs forms))
         specials (binding [*cur-ns* ns-
@@ -810,7 +807,7 @@
                    (first (keep #(parse-repl-specials % docs) forms)))]
     specials))

-(defmethod parse-ns "syntax" [ns-]
+(defmethod parse-ns ["syntax" :syntax] [ns- api]
   (binding [*cur-ns* ns-]
     (let [tagged-literals (parse-tagged-literals)
           syntax-items (parse-syntax-forms)
@@ -820,30 +817,33 @@
                syntax-items
                [destructure-item])))))

-(defmethod parse-ns "cljs.test" [ns-]
+(defmethod parse-ns ["cljs.test" :library] [ns- api]
   (parse-ns* ns- "clojurescript"
     (cond
       (>  *cljs-num* 3269) [:library]
-      (>= *cljs-num* 0)    [:library :compiler]
+      (>= *cljs-num* 0)    [:library :compiler] ;; macros mistakenly kept in compiler section before 3269
       :else nil)))

-(defmethod parse-ns "cljs.repl" [ns-]
+(defmethod parse-ns ["cljs.repl" :library] [ns- api]
   ;; the library file "repl.cljs" has (:require-macros cljs.repl)
   ;; so we must pull those in from the compiler and add in the
   ;; library functions.
-  (let [comp-syms (cond->> (parse-ns* ns- "clojurescript" [:compiler])
-
-                 ;; if parsing for library API, the macros are the only symbols we can use.
-                 (= "library" *cur-api*) (filter #(= "macro" (:type %))))
-
-        lib-syms (when (= "library" *cur-api*)
-                   (parse-ns* ns- "clojurescript" [:library]))]
-    (concat comp-syms lib-syms)))
-
-(defmethod parse-ns :default-lib [ns-]
+  (let [macros (->> (parse-ns* ns- "clojurescript" [:compiler])
+                    (filter #(= "macro" (:type %))))
+        lib (parse-ns* ns- "clojurescript" [:library])]
+    (concat macros lib)))
+
+(defmethod parse-ns ["cljs.repl.nashorn" :compiler] [ns- api]
+  (cond
+    (>= *cljs-num* 3255) nil ;; FIXME: parse defs from
+    ;; (util/compile-if (Class/forName "jdk.nashorn.api.scripting.NashornException")
+    ;;   (do ... ))
+    (>= *cljs-num* 0) (parse-ns* ns- "clojurescript" :compiler)))
+
+(defmethod parse-ns [:default :library] [ns- api]
   (parse-ns* ns- "clojurescript" :library))

-(defmethod parse-ns :default-compiler [ns-]
+(defmethod parse-ns [:default :compiler] [ns- api]
   (parse-ns* ns- "clojurescript" :compiler))

 ;;------------------------------------------------------------
@@ -883,19 +883,16 @@
         extras (map make ["catch" "finally"])]
     (concat parsed extras)))

+(defn parse-all*
+  [api]
+  (->> (get namespaces api)
+       (keys)
+       (mapcat #(parse-ns % api))
+       (doall)))
+
 (defn parse-all
   []
-  (let [syntax-parsed (parse-ns "syntax")
-        lib-parsed (binding [*cur-api* "library"]
-                     (->> cljs-lib-namespaces
-                          (mapcat parse-ns)
-                          doall
-                          add-catch-finally))
-        compiler-parsed (binding [*cur-api* "compiler"]
-                          (->> cljs-compiler-namespaces
-                               (mapcat parse-ns)
-                               doall))]
-    {:syntax syntax-parsed
-     :library lib-parsed
-     :compiler compiler-parsed}))
-
+  {:syntax   (parse-all* :syntax)
+   :library  (add-catch-finally (parse-all* :library))
+   :compiler (parse-all* :compiler)})
+


introduce :on, :off deltas (still experimental)

--- src/cljx/commos/delta.cljx
+++ src/cljx/commos/delta.cljx
@@ -120,6 +120,8 @@
   (results-skip-init add))

 ;; Adding deltas
+(declare add*)
+
 (defn- add-root-delta
   [val op new-val]
   (case op
@@ -127,7 +129,10 @@
     :in (into (or val #{}) (collect new-val))
     :ex (if (map? val)
           (apply dissoc val (collect new-val))
-          (difference val (collect new-val)))))
+          (difference val (collect new-val)))
+
+    :on (reduce add* val (positive-deltas new-val))
+    :off (reduce add* val (negative-deltas new-val))))

 (defn- add*
   [val [op korks-or-new-val new-val :as delta]]


tmpdir and upgrade cheshire

tmpdir and upgrade cheshire

--- src/co/nclk/linen/node.clj
+++ src/co/nclk/linen/node.clj
@@ -83,7 +83,9 @@
 (defn- invoke-local
   [checkpoint & [argv]]
   (binding [*log* (not (false? (:log checkpoint)))]
-    (let [tmpfile-name (tempfile-name)
+    (let [tmpfile-name (str (System/getProperty "java.io.tmpdir")
+                            "/"
+                            (tempfile-name))
           proxy? (not (nil? argv))
           argv (or argv
                    (remove clojure.string/blank?


Up truncation limit to 400k

Up truncation limit to 400k

--- src-cljs/frontend/models/action.cljs
+++ src-cljs/frontend/models/action.cljs
@@ -87,4 +87,4 @@
 (def max-output-size
   "Limits the number of chacaters we will try to display in the dom.
    The full output is availible for download."
-  (* 200 1000))
+  (* 400 1000))


can now delete items (but there must be a better way of doing this)

--- src/eatme/client/main.cljs
+++ src/eatme/client/main.cljs
@@ -7,6 +7,7 @@
             [shoreleave.pubsubs.publishable :as pcore]
             [domina :as d]
             [domina.events :as event]
+            [domina.css :as css]
             [eatme.client.render :as render])
   (:require-macros [shoreleave.remotes.macros :as srm]))

@@ -43,6 +44,8 @@

 (def item-added (pubsub/publishize (fn [e] {:item-name (d/value item-name-field)}) bus))

+(def item-deleted (pubsub/publishize (fn [e] {:item (event/target e)}) bus))
+
 (defn on-enter [e f]
   (when (= 13 (:keyCode e)) (item-added e)))

@@ -50,7 +53,12 @@
 (event/listen! item-name-field :keypress #(on-enter % item-added))

 (defn add-item-to-list [item]
-  (d/append! items-list (render/shopping-list-item item)))
+  (d/append! items-list (render/shopping-list-item item))
+  (event/listen! (css/sel items-list "button") :click #(item-deleted %)))
+
+(defn remove-item-from-list [item]
+  ;; (:item item) is actually the delete button that was clicked
+  (d/detach! (-> item :item .-parentNode .-parentNode)))

 (defn focus-item-input [& args]
   (.focus item-name-field))
@@ -66,3 +74,7 @@
 (pubsub/subscribe bus item-added focus-item-input)
 (pubsub/subscribe bus item-added clear-item-input)

+(pubsub/subscribe bus item-deleted log-to-console)
+(pubsub/subscribe bus item-deleted remove-item-from-list)
+
+(focus-item-input)


clarifies comment

clarifies comment

--- access-control-app/int_test/cmr/access_control/int_test/access_control_group_crud_test.clj
+++ access-control-app/int_test/cmr/access_control/int_test/access_control_group_crud_test.clj
@@ -166,8 +166,8 @@
         (is (= ["The following users do not exist [user4]"] errors))))))

 ;; This test currently records a false positive, the single instance acl is not granting permissions because group
-;; service uses echo-rest to determine permissions therefor adding an single instance ACL to cmr has no effect.  Also,
-;; the fixture system group acl in mock echo allows for any user to modify groups. A ticket is needed to have
+;; service uses echo-rest to determine permissions therefor adding an single instance ACL to cmr has no effect.
+;; The fixture system group acl in mock echo is what allows for any user to modify groups in this test. A ticket is needed to have
 ;; mock-echo use cmr for acls instead of echo-rest to more accurately depict how operations works with cmr-acl-read-enabled.
 (deftest create-group-with-managing-group-id-test
   (let [token-user1 (e/login (u/conn-context) "user1")


schemata changes

schemata changes

--- src/clj/migae/datastore/schemata.clj
+++ src/clj/migae/datastore/schemata.clj
@@ -1,21 +1,30 @@
 (ns migae.datastore.schemata
   (:require [clojure.tools.logging :as log :only [debug info]]
             ;; [clojure.tools.reader.edn :as edn]
-            [schema.core :as s])) ;; :include-macros true]
+            ;; [schema.core :as s]
+            )) ;; :include-macros true]

 (clojure.core/println "loading migae.datastore.schemata")

 ;;  keys:  :Schema/#version-number, e.g. :Persons/#1
 (defonce schemata (atom {}))

+(defn register-schema
+  [k schema]
+  ;; FIXME: validation
+  (if (and (vector? k)
+           (not (empty? k))
+           (every?
+            #(and (keyword? %) (not (nil? (namespace %))))
+           k))
+    (swap! schemata assoc k schema)
+    (throw (IllegalArgumentException. (str "First arg must be keyword")))))
+
+(defn dump-schemata
+  []
+  (log/debug "schemata: " @schemata))
+
 (defn schema
   [kw]
   (@schemata kw))

-(defn register-schema
-  [kw schema]
-  (log/debug "register-schema: " kw schema)
-  ;; FIXME: validation
-  (swap! schemata assoc kw schema))
-
-(defn dump [] (log/debug "schemata: " @schemata))


Use different cursor styles for draggable module

Cursor styles are based on:
https://developer.mozilla.org/en-US/docs/Web/CSS/cursor

Signed-off-by: Pang Yan Han <22594c345857f664c61cd411f607c4d40a9d4af9@gmail.com>

--- src/cljs/cljs_nusmods/timetable.cljs
+++ src/cljs/cljs_nusmods/timetable.cljs
@@ -484,6 +484,7 @@
        http://api.jqueryui.com/draggable/#event-start"
   [moduleCode lessonType selectedLessonGroup bgColorCssClass]
   (fn [evt ui]
+    (.css (aget ui "helper") "cursor" "grabbing")
     (let [ModulesMap         (aget js/window "ModulesMap")
           ; Get all lesson groups
           allLessonGroupsMap (get-in ModulesMap [moduleCode "lessons"
@@ -507,6 +508,7 @@
   "Returns a function used as the `stop` event handler for a draggable lesson."
   []
   (fn [evt ui]
+    (.css (aget ui "helper") "cursor" "grab")
     (let [affectedDaysSet
           (reduce (fn [daySet ttLessonInfo]
                     (conj daySet (:day ttLessonInfo)))
@@ -536,6 +538,7 @@
   [$divElemSeq moduleCode lessonType lessonLabel bgColorCssClass]
   ; And Drag event handler
   (doseq [$divElem $divElemSeq]
+    (.css $divElem "cursor" "grab")
     (.draggable $divElem
                 (js-obj "zIndex" 100
                         ; TODO: Replace this `revert` function with one


remove unused atom

remove unused atom

--- src/cljs/learndatalogtoday/core.cljs
+++ src/cljs/learndatalogtoday/core.cljs
@@ -17,9 +17,6 @@
 (let [converter (js/Markdown.Converter.)]
   (defn md [text]
     (.makeHtml converter text)))
-
-;; A map from id -> code-mirror instance
-(def editors (atom {}))

 (def state (atom {:current-tab nil}))


Make items of priorities more human readable

--- src/cljs/todogo_cljs/components.cljs
+++ src/cljs/todogo_cljs/components.cljs
@@ -75,14 +75,14 @@
              :placeholder (str "Add a todo in a list '" (:title todo-list) "'")
              :on-change   #(re-frame/dispatch-sync [:set-todo-title (-> % .-target .-value)])}]]])

-(def priorities [{:id 1 :label "IRRELEVANT"}
-                 {:id 2 :label "EXTRA_LOW"}
-                 {:id 3 :label "LOW"}
-                 {:id 4 :label "NORMAL"}
-                 {:id 5 :label "HIGH"}
-                 {:id 6 :label "URGENT"}
-                 {:id 7 :label "SUPER_URGENT"}
-                 {:id 8 :label "IMMEDIATE"}])
+(def priorities [{:id 1 :label "Irrelevant"}
+                 {:id 2 :label "Extra low"}
+                 {:id 3 :label "Low"}
+                 {:id 4 :label "Normal"}
+                 {:id 5 :label "High"}
+                 {:id 6 :label "Urgent"}
+                 {:id 7 :label "Super urgent"}
+                 {:id 8 :label "Immediate"}])

 (defn edit-todo-form [todo]
    [:form {:on-submit (fn [e] (do (update-todo todo)


Remove (create-input) and (create-input-raw) as they mostly emulate clojure.java.io/input-stream.

--- src/quil/core.clj
+++ src/quil/core.clj
@@ -1056,52 +1056,6 @@
   [w h format]
   (let [format (resolve-constant-key format image-formats)]
     (.createImage (current-applet) (int w) (int h) (int format))))
-
-(defn
-  ^{:requires-bindings true
-    :processing-name "createInput()"
-    :category "Input"
-    :subcategory "Files"
-    :added "1.0"}
-  create-input
-  "This is a method for advanced programmers to open a Java
-  InputStream. The method is useful if you want to use the facilities
-  provided by PApplet to easily open files from the data folder or
-  from a URL, but want an InputStream object so that you can use other
-  Java methods to take more control of how the stream is read.
-
-  If the requested item doesn't exist, null is returned.
-
-  If not online, this will also check to see if the user is asking for
-  a file whose name isn't properly capitalized. If capitalization is
-  different an error will be printed to the console. This helps
-  prevent issues that appear when a sketch is exported to the web,
-  where case sensitivity matters, as opposed to running from inside
-  the Processing Development Environment on Windows or Mac OS, where
-  case sensitivity is preserved but ignored.
-
-  The filename passed in can be:
-  - A URL, for instance (open-stream \"http://processing.org/\";
-  - A file in the sketch's data folder
-  - The full path to a file to be opened locally (when running as an
-    application)
-
-  If the file ends with .gz, the stream will automatically be gzip
-  decompressed. If you don't want the automatic decompression, use the
-  related function create-input-raw."
-  [filename]
-  (.createInput (current-applet) (str filename)))
-
-(defn
-  ^{:requires-bindings true
-    :processing-name "createInputRaw()"
-    :category "Input"
-    :subcategory "Files"
-    :added "1.0"}
-  create-input-raw
-  "Call create-input without automatic gzip decompression."
-  [filename]
-  (.createInputRaw (current-applet) filename))

 (defn
   ^{:requires-bindings true


Redirect / to index.html

Redirect / to index.html

--- api/src/geocommit/app_servlet.clj
+++ api/src/geocommit/app_servlet.clj
@@ -38,6 +38,9 @@
 	    (:request payload) (ds/slurp* (.getInputStream (:request payload)))
 	    (:body payload) (ds/slurp* (:body payload))))
 	  (app-hook (:payload (:params payload)))))
+  (GET "/" []
+       {:status 302
+       :headers {"Location" "index.html"}})
   (route/resources "/")
   (route/not-found "not a valid request"))


make clojure slightly more idiomatic

make clojure slightly more idiomatic

--- tls.clj
+++ tls.clj
@@ -2,7 +2,7 @@
   (not (seq? a)))

 (defn null? [a]
-  (or (= '() a)
+  (or (= [] a)
       (nil? a)))

 (defn lat? [l]
@@ -19,34 +19,34 @@

 (defn rember [a lat]
   (cond
-    (null? lat) '()
+    (null? lat) []
     (= (first lat) a) (rest lat)
     :else (cons (first lat)
                 (rember a (rest lat)))))

 (defn firsts [l]
   (cond
-    (null? l) '()
+    (null? l) []
     :else (cons (first (first l))
                 (firsts (rest l)))))

 (defn insertR [n o lat]
   (cond
-    (null? lat) '()
+    (null? lat) []
     (= (first lat) o) (cons o (cons n (rest lat)))
     :else (cons (first lat)
                 (insertR n o (rest lat)))))

 (defn insertL [n o lat]
   (cond
-    (null? lat) '()
+    (null? lat) []
     (= (first lat) o) (cons n lat)
     :else (cons (first lat)
                 (insertL n o (rest lat)))))

 (defn subst [n o lat]
   (cond
-    (null? lat) '()
+    (null? lat) []
     (= (first lat) o) (cons n (rest lat))
     :else (cons (first lat)
                 (subst n o (rest lat)))))
@@ -54,7 +54,7 @@
 ; end of LISPer, bonus practice
 (defn subst2 [n o1 o2 lat]
   (cond
-    (null? lat) '()
+    (null? lat) []
     (or (= (first lat) o1)
         (= (first lat) o2)) (cons n (rest lat))
     :else (cons (first lat)
@@ -62,14 +62,14 @@

 (defn multirember [a lat]
   (cond
-    (null? lat) '()
+    (null? lat) []
     (= (first lat) a) (multirember a (rest lat))
     :else (cons (first lat)
                 (multirember a (rest lat)))))

 (defn multiinsertR [n o lat]
   (cond
-    (null? lat) '()
+    (null? lat) []
     (= (first lat) o) (cons o (cons n
                                     (multiinsertR n o (rest lat))))
     :else (cons (first lat)
@@ -77,7 +77,7 @@

 (defn multisubst [n o lat]
   (cond
-    (null? lat) '()
+    (null? lat) []
     (= (first lat) o) (cons n
                             (multisubst n o (rest lat)))
     :else (cons (first lat)
@@ -149,14 +149,14 @@

 (defn no-nums [lat]
     (cond
-        (null? lat) '()
+        (null? lat) []
         (number? (first lat)) (no-nums (rest lat))
         :else (cons (first lat)
                     (no-nums (rest lat)))))

 (defn all-nums [lat]
     (cond
-        (null? lat) '()
+        (null? lat) []
         (not (number? (first lat))) (all-nums (rest lat))
         :else (cons (first lat)
                     (all-nums (rest lat)))))


core: filterv

core: filterv

--- core/data/core.clj
+++ core/data/core.clj
@@ -3467,6 +3467,15 @@
   ([f c1 c2 c3 & colls]
    (into [] (apply map f c1 c2 c3 colls))))

+(defn filterv
+  "Returns a vector of the items in coll for which
+  (pred item) returns true. pred must be free of side-effects."
+  {:added "1.0"}
+  [pred coll]
+  (reduce (fn [v o] (if (pred o) (conj v o) v))
+          []
+          coll))
+
 (defmacro cond->
   "Takes an expression and a set of test/form pairs. Threads expr (via ->)
   through each form for which the corresponding test


use at-at to schedule the scope updating

--- src/overtone/viz/scope.clj
+++ src/overtone/viz/scope.clj
@@ -8,17 +8,17 @@
            [javax.swing JFrame JPanel JSlider])
   (:use [clojure.stacktrace]
         [overtone.util lib]
-        [overtone.music time]
         [overtone.lib event deps]
         [overtone.sc defaults core synth ugen buffer node]
         [overtone.studio.util])
   (:require [clojure.set :as set]
-            [overtone.util.log :as log]))
+            [overtone.util.log :as log]
+            [overtone.at-at :as at-at]))

 (defonce SCOPE-BUF-SIZE 4096)
 (defonce FPS 10)
 (defonce scopes* (ref {}))
-(defonce scope-pool* (agent (make-pool)))
+(defonce scope-pool (at-at/mk-pool))
 (defonce scopes-running?* (ref false))
 (defonce WIDTH 600)
 (defonce HEIGHT 400)
@@ -26,14 +26,15 @@
 (defonce Y-PADDING 10)
 (defonce scope-group* (ref 0))

-(on-deps :studio-setup-completed ::create-scope-group #(dosync (ref-set scope-group* (group :tail ROOT-GROUP))
-                                                               (satisfy-deps :scope-group-created)))
+(on-deps :studio-setup-completed ::create-scope-group #(dosync
+                                                        (ref-set scope-group* (group :tail ROOT-GROUP))
+                                                        (satisfy-deps :scope-group-created)))

 (defn- update-scope-data [s]
   (let [{:keys [buf size width height panel y-arrays x-array panel]} s
-        frames (buffer-data buf)
-        step (int (/ (buffer-size buf) width))
-        y-scale (- height (* 2 Y-PADDING))
+        frames    (buffer-data buf)
+        step      (int (/ (buffer-size buf) width))
+        y-scale   (- height (* 2 Y-PADDING))
         [y-a y-b] @y-arrays]
     (if-not (empty? frames)
       (dotimes [x width]
@@ -89,15 +90,13 @@
          (.show)
          (.setAlwaysOnTop keep-on-top)))))

-(defn- start-scopes-runner
-  []
-  (periodic update-scopes (/ 1000 FPS) 0 @scope-pool*))
-
 (defn scopes-start
+  "Schedule the scope to be updated every (/ 1000 FPS) ms (unless the scopes are
+  already running in which case it does nothing."
   []
   (dosync
    (when-not @scopes-running?*
-     (start-scopes-runner)
+     (at-at/every (/ 1000 FPS) update-scopes scope-pool)
      (ref-set scopes-running?* true))))

 (defn- reset-data-arrays
@@ -120,10 +119,9 @@

 (defn scopes-stop
   []
-  (dosync
-   (stop-and-reset-pool! scope-pool*)
-   (empty-scope-data)
-   (ref-set scopes-running?* false)))
+  (at-at/stop-and-reset-pool! scope-pool)
+  (empty-scope-data)
+  (dosync (ref-set scopes-running?* false)))

 (defn- start-bus-synth
   [bus buf]


fixing the default rule to be a func again

--- src/spcr/core.clj
+++ src/spcr/core.clj
@@ -34,7 +34,7 @@

 (def default-rules { :default (fn [_] :true)
                     ;functions using other functions aren't allowed at the momment
-                    :high-daily-diff '(fn [{high :High low :Low}]
+                    :high-daily-diff (fn [{high :High low :Low}]
                                          (> (abs (- high low)) 3))})

 (defn get-matching-rules [record rules]


Added sorting by created_at to intercom get

--- src/polismath/intercom.clj
+++ src/polismath/intercom.clj
@@ -25,9 +25,11 @@
               (into {})))
         next-page (get-in return-data ["pages" "next"])
         users (get return-data "users")]
-    (if next-page
-      (into users (get-intercom-users next-page))
-      users)))
+    (sort-by
+      (fn [u] (int (get u "created_at")))
+      (if next-page
+        (into users (get-intercom-users next-page))
+        users))))

 (defn user-id


The function read-job-list should be variadic and accepts book name as a parameter

--- src/emender_service/db_interface.clj
+++ src/emender_service/db_interface.clj
@@ -43,13 +43,20 @@
             (println e))))

 (defn read-job-list
-    []
+    ([]
     (try
         (jdbc/query db-spec/emender-service-db
                     ["select id, job from results order by id,job"])
         (catch Exception e
             (println e)
             [])))
+    ([book-name]
+    (try
+        (jdbc/query db-spec/emender-service-db
+                    ["select id, job from results where job=? order by id,job" book-name])
+        (catch Exception e
+            (println e)
+            []))))

 (defn read-book-list
     []


fix typo in error message when DB is not setup

--- src/toucan/db.clj
+++ src/toucan/db.clj
@@ -91,7 +91,7 @@
   (or *db-connection*
       *transaction-connection*
       @default-db-connection
-      (throw (Exception. "DB is not set up. Make sure to bind call set-default-db-connection! or bind *db-connection*."))))
+      (throw (Exception. "DB is not set up. Make sure to call set-default-db-connection! or bind *db-connection*."))))

 (defn do-in-transaction
   "Execute F inside a DB transaction. Prefer macro form `transaction` to using this directly."


removes input coercion

removes input coercion

--- src/ring_curl/clj_http.clj
+++ src/ring_curl/clj_http.clj
@@ -8,7 +8,6 @@
    wrap-oauth
    wrap-user-info
    wrap-url
-   wrap-input-coercion
    wrap-accept
    wrap-accept-encoding
    wrap-content-type


first go at templating html in price functions

--- src-cljs/complico/prices.cljs
+++ src-cljs/complico/prices.cljs
@@ -18,7 +18,7 @@
                     (js/parseFloat)
                     (* 2.0)
                     (apply-price-formatting))]
-    (str currency new-price " / " currency "2.00")))
+    (dommy/html (node [:div (str currency new-price " / " currency "2.00")]))))

 (def conversion-functions [divide-by-two])


elevio Move side effecting form outside of let

--- src-cljs/frontend/elevio.cljs
+++ src-cljs/frontend/elevio.cljs
@@ -21,10 +21,10 @@
                                  (aget "ldUser")
                                  (aget "custom")
                                  (aget "free")))
-        user-info (aget js/window "elevSettings")
-        _ (-> user-info
-              (aget "traits")
-              (aset "free" is-free))]
+        user-info (aget js/window "elevSettings")]
+    (-> user-info
+        (aget "traits")
+        (aset "free" is-free))
     (set-elev! "account_id" account-id)
     (set-elev! "user" user-info)
     (set-elev! "pushin" "false")


Refactor content creation permissions creation

--- src/uruk/core.clj
+++ src/uruk/core.clj
@@ -619,6 +619,19 @@
     :resolve-entities
     :temporal-collection})

+(defn make-content-permissions
+  "Return an array of ContentPermissions decribing the given seq of
+  content capability keys."
+  [permissions]
+  (into-array ContentPermission
+              (reduce (fn [permissions-acc permission]
+                        (conj permissions-acc
+                              (ContentPermission.
+                               (content-capability (val (first permission)))
+                               (key (first permission)))))
+                      []
+                      permissions)))
+
 (defn content-creation-options
   "Creates a ContentCreateOptions object (to pass to a ContentFactory
   newContent call) out of the given options map. See
@@ -626,7 +639,7 @@
   [options]
   (let [cco (ContentCreateOptions.)]
     (when-not (every? valid-content-creation-options (keys options))
-      ;; TODO switch to spec
+      ;; TODO switch to spec?
       (throw (IllegalArgumentException. "Invalid content creation option. Keywords passed in `options` must be a subset of `valid-content-creation-options`.")))
     (let [xs [[:buffer-size #(.setBufferSize cco %)]
               [:collections #(.setCollections cco (into-array String %))]
@@ -636,25 +649,16 @@
               [:language    #(.setLanguage cco %)]
               [:locale      #(.setLocale cco %)]
               [:namespace   #(.setNamespace cco %)]
-              [:permissions #(.setPermissions
-                              cco
-                              (into-array ContentPermission
-                                          (reduce (fn [permissions permission]
-                                                    (conj permissions
-                                                          (ContentPermission.
-                                                           (content-capability (val (first permission)))
-                                                           (key (first permission)))))
-                                                  []
-                                                  %)))]
-              [:placement-keys #(.setPlaceKeys cco %)]
-              [:quality #(setQuality cco %)]
-              [:repair-level #(.setRepairLevel cco (doc-repair-level %))]
+              [:permissions #(.setPermissions cco (make-content-permissions %))]
+              [:placement-keys      #(.setPlaceKeys cco %)]
+              [:quality             #(.setQuality cco %)]
+              [:repair-level        #(.setRepairLevel cco (doc-repair-level %))]
               [:resolve-buffer-size #(.setResolveBufferSize cco %)]
-              [:resolve-entities #(.setResolveEntities cco %)]
+              [:resolve-entities    #(.setResolveEntities cco %)]
               [:temporal-collection #(.setTemporalCollection cco %)]]]
       (doseq [[k fn] xs]
         (when-let [x (k options)]
-          (f x))))
+          (fn x))))
     cco))

 (defn describe-content-creation-options
@@ -665,6 +669,7 @@
    :format ((clojure.set/map-invert doc-format) (.getFormat opts))
    :graph (.getGraph opts)
    :language (.getLanguage opts)
+   :locale (.getLocale opts)
    :namespace (.getNamespace opts)
    :permissions (mapv #(hash-map (.getRole %)
                                  (keyword (.toString (.getCapability %))))


create-default-session. Factor out session config.

Related to #12

--- src/uruk/core.clj
+++ src/uruk/core.clj
@@ -530,7 +530,7 @@
                               :preemptive-auth preemptive-auth})))

 (defn make-hosted-content-source
-  "Returna a ContentSource object according to the given `host` String
+  "Return a ContentSource object according to the given `host` String
   and integer `port`, and optionally a configuration map defining the
   `user` and `password`, `content-base`, `security-options`, and/or
   default Logger object and boolean flag for whether basic
@@ -582,7 +582,7 @@
   [{:keys [uri user password content-base]} & [content-source]]
   (let [cs (if (instance? ContentSource content-source)
              content-source
-             (ContentSourceFactory/newContentSource (URI. uri)))]
+             (make-uri-content-source (URI. uri)))]
     (cond
       (and (nil? content-base)
            (or (nil? user)
@@ -613,6 +613,24 @@
                  valid-session-config-options
                  " are recognized keywords.")))))

+(defn configure-session
+  ;; TODO docstring
+  [session {:keys [default-request-options logger user-object
+                   transaction-mode transaction-timeout]
+            :as config-options}]
+  (when (map? default-request-options)
+    (.setDefaultRequestOptions session (make-request-options default-request-options)))
+  (when (instance? Logger logger)
+    (.setLogger session logger))
+  ;; NB: the following is not the strictest test
+  (when (instance? Object user-object)
+    (.setUserObject session user-object))
+  (when (keyword? transaction-mode)
+    (.setTransactionMode session (->transaction-mode transaction-mode)))
+  (when (integer? transaction-timeout)
+    (.setTransactionTimeout session transaction-timeout))
+  session)
+
 (defn create-session
   "Create a Session for querying and transacting with. Parameter
   `db-info` describing database connection information must
@@ -635,6 +653,7 @@
   info URI."
   ([db-info]
    (create-session* db-info))
+
   ([db-info {:keys [default-request-options logger user-object
                     transaction-mode transaction-timeout]
              :as config-options}]
@@ -645,23 +664,22 @@
                     :logger logger :user-object user-object
                     :transaction-mode transaction-mode
                     :transaction-timeout transaction-timeout}))
+
   ([db-info content-source {:keys [default-request-options logger user-object
                                    transaction-mode transaction-timeout]
                             :as config-options}]
    (validate-session-config-options config-options)
-   (let [session (create-session* db-info content-source)]
-     (when (map? default-request-options)
-       (.setDefaultRequestOptions session (make-request-options default-request-options)))
-     (when (instance? Logger logger)
-       (.setLogger session logger))
-     ;; NB: the following is not the strictest test
-     (when (instance? Object user-object)
-       (.setUserObject session user-object))
-     (when (keyword? transaction-mode)
-       (.setTransactionMode session (->transaction-mode transaction-mode)))
-     (when (integer? transaction-timeout)
-       (.setTransactionTimeout session transaction-timeout))
-     session)))
+   (configure-session (create-session* db-info content-source) config-options)))
+
+(defn create-default-session
+  ;; TODO docstring
+  ([content-source]
+   (create-default-session content-source nil))
+  ([content-source {:keys [default-request-options logger user-object
+                           transaction-mode transaction-timeout]
+                    :as config-options}]
+   (validate-session-config-options config-options)
+   (configure-session (create-session* {} content-source) config-options)))

 ;; TODO require privilege
 ;; (defn session-cb-metadata


Ring middleware: Simplify tests of `wrap-json-body`

--- test/com/nomistech/clojure_the_language/c_800_libraries/s_800_web/ss_020_ring.clj
+++ test/com/nomistech/clojure_the_language/c_800_libraries/s_800_web/ss_020_ring.clj
@@ -94,27 +94,13 @@
 ;;;; ___________________________________________________________________________
 ;;;; ---- rmj/wrap-json-body ----

-(defn handler-of-interesting-request [request]
-  (let [user (get-in request [:body :user] "<no user specified>")]
-    (rur/response (str "Uploaded '" user "'."))))
-
-(def wrapped-handler-of-interesting-request
-  (-> handler-of-interesting-request
-      (rmj/wrap-json-body {:keywords? true
-                           :bigdecimals? true})))
-
-(fact "Handler with request whose body is Clojure data"
-  (handler-of-interesting-request {:body {:user "Fred"}})
-  => {:status 200
-      :headers {}
-      :body "Uploaded 'Fred'."})
-
-(fact "Wrapped handler with request whose body is JSON"
-  (wrapped-handler-of-interesting-request
-   (make-my-request))
-  => {:status 200
-      :headers {}
-      :body "Uploaded 'Fred'."})
+(fact ((-> identity-handler
+           (rmj/wrap-json-body {:keywords? true
+                                :bigdecimals? true}))
+       (make-my-request))
+  => {:headers      {"content-type" "application/json; charset=utf-8"}
+      :query-string "q1=a&q2=b"
+      :body         {:user "Fred"}})

 ;;;; ___________________________________________________________________________
 ;;;; ---- rmj/wrap-json-response ----


Fix find-nodes references in user ns.

Fix find-nodes references in user ns.

--- dev/user.clj
+++ dev/user.clj
@@ -163,12 +163,14 @@
     (try
       (let [root' (index/update-tree store update-case root
                                      (sort-by first (:changes update-case)))
-            old-nodes (viz/find-nodes store {}
-                                      (mdag/get-node store (::node/id (meta root)))
-                                      (constantly true))
-            new-nodes (viz/find-nodes store {}
-                                      (mdag/get-node store (::node/id (meta root')))
-                                      (constantly true))
+            old-nodes (graph/find-nodes
+                        store {}
+                        (mdag/get-node store (::node/id (meta root)))
+                        (constantly true))
+            new-nodes (graph/find-nodes
+                        store {}
+                        (mdag/get-node store (::node/id (meta root')))
+                        (constantly true))
             all-nodes (merge old-nodes new-nodes)
             shared-ids (set/intersection (set (keys old-nodes)) (set (keys new-nodes)))]
         (rhizome/view-graph


Playing with core.async in dev

Playing with core.async in dev

--- dev/user.clj
+++ dev/user.clj
@@ -5,6 +5,8 @@
             [polismath.conv-man :as conv-man]
             [polismath.math.conversation :as conv]
             [polismath.components.postgres :as postgres]
+            [clojure.core.matrix :as matrix]
+            [clojure.core.async :as async :refer [>! <! >!! <!! go go-loop thread]]
             [environ.core :as env]
             [taoensso.timbre :as log]))

@@ -51,4 +53,17 @@

   (runner/start!)

+
+  ;; Playing with core.async parallelism
+  (defn dowork [size]
+    (doseq [i (range size)]
+      (reduce + (range i))))
+
+  (let [kill-chan (async/promise-chan)
+        parallelism 4
+        work-size 30000]
+    (doseq [_ (range parallelism)]
+      (thread
+        (dowork work-size))))
+
   :end)


Sort test data to make diffs more useful: also the index

--- dev/user.clj
+++ dev/user.clj
@@ -43,7 +43,7 @@
     (io/make-parents file)
     (spit file (with-out-str (pprint data)))))

-(defn- normalized [data]
+(defn- normalize-maps [data]
   (clojure.walk/postwalk
     (fn [form] (if (map? form)
                  (into (sorted-map) form)
@@ -57,10 +57,11 @@
         restaurants (doall (map (fn [id] [id (updater/get-restaurant api id)])
                                 ids))]
     (delete-testdata)
-    (save-testdata "restaurants.edn" index)
+    (save-testdata "restaurants.edn"
+                   (normalize-maps index))
     (log/info "Saved restaurants")
     (doseq [[id restaurant] restaurants]
       (save-testdata (str "restaurant/" id ".edn")
-                     (normalized @restaurant))
+                     (normalize-maps @restaurant))
       (log/info "Saved restaurant" id))
     (log/info "Test data updated")))


CMR-5503: Fix humanizer test.

CMR-5503: Fix humanizer test.

--- system-int-test/test/cmr/system_int_test/search/humanizer/humanizer_test.clj
+++ system-int-test/test/cmr/system_int_test/search/humanizer/humanizer_test.clj
@@ -70,8 +70,11 @@

     (testing "Create humanizer with nil body"
       (is (= {:status 400,
+              ;; The input to validation is just "null" in this case which leads
+              ;; the validator to believe the json is malformed and throw the
+              ;; below error messages before it is even validated against the schema.
               :errors
-              ["#: expected type: JSONArray, found: Null"]}
+              ["Invalid JSON: Trailing characters are not permitted. at 3 [character 4 line 1]"]}
              (humanizer-util/update-humanizers admin-update-token nil))))

     (testing "Create humanizer with empty array"


CMR-114: Added a test to verify successful deletion of a concept from index and mdb.

--- test/cmr_system_int_test/concept_ingest_test.clj
+++ test/cmr_system_int_test/concept_ingest_test.clj
@@ -26,13 +26,15 @@
         ingest-rest-url (str "http://" host ":" port "/" ctx-part)]
     ingest-rest-url))

-(defn save-concept
-  "Make a put request to ingest a concept without JSON encoding the concept.  Returns a map with
-  status, revision-id, and a list of error messages"
-  [concept]
+(defn ingest-concept
+  "Make a concept create / delete request on ingest.  Returns a map with
+  status, concept-id, and revision-id"
+  [method concept]
+  (info method)
+  (info concept)
   (let [coerced-json-str (cheshire/generate-string concept)
         response (client/request
-                   {:method :put
+                   {:method (keyword method)
                     :url (construct-ingest-rest-url concept)
                     :body  coerced-json-str
                     :body-encoding "UTF-8"
@@ -43,9 +45,13 @@
                     :throw-exceptions true})
         status (:status response)
         body (cheshire/parse-string (:body response))
-        revision-id (get body "revision-id")
-        error-messages (get body "errors")]
-    {:status status :revision-id revision-id :error-messages error-messages :response response}))
+        concept-id (get body "concept-id")
+        revision-id (get body "revision-id")]
+    (info "ingest-concept fn response" response)
+    (info "test status" status)
+    (info "test concept-id " concept-id )
+    (info "test revision-id " revision-id )
+    {:status status :concept-id concept-id :revision-id revision-id :response response}))

 (def provider-suffix-num-atom (atom (rand-int 1000000)))

@@ -54,10 +60,10 @@
 ;;; add indexer app etc later to this list
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 (deftest concept-ingest-test
-  "Save a valid concept with no revision-id."
+  "Verrify successful ingest of concept."
   (swap! provider-suffix-num-atom inc)
   (try
-    (let [{:keys [status revision-id]} (save-concept (concept @provider-suffix-num-atom))]
+    (let [{:keys [status revision-id]} (ingest-concept "put" (concept @provider-suffix-num-atom))]
       (is (and (= status 200) (= revision-id 0))))
     (catch Exception e
       (error "Exception occurred while executing concept-ingest-test: " (.getMessage e))
@@ -71,7 +77,7 @@
     (let [N 4
           expected-revision-id (- N 1)
           last-revision-id (last (repeatedly N
-                                             #(let [ {:keys [revision-id]} (save-concept (concept @provider-suffix-num-atom))]
+                                             #(let [ {:keys [revision-id]} (ingest-concept "put" (concept @provider-suffix-num-atom))]
                                                 revision-id)))]
       (is (= expected-revision-id last-revision-id)))
     (catch Exception e
@@ -79,5 +85,21 @@
       (.printStackTrace e)
       (is false))))

+;; ingest a concept first and delete the very same concept.
+(deftest delete-concept-test
+  "Verify concept is deleted from mdb and index."
+  (swap! provider-suffix-num-atom inc)
+  (try
+    (let [{:keys [status revision-id]} (ingest-concept "put" (concept @provider-suffix-num-atom))
+          saved? (and (= status 200) (= revision-id 0))]
+      (if saved?
+        (let [{:keys [status]} (ingest-concept "delete" (concept @provider-suffix-num-atom))]
+          (is (= status 200)))
+        (is false)))
+    (catch Exception e
+      (error "Exception occurred while executing concept-ingest-test: " (.getMessage e))
+      (.printStackTrace e)
+      (is false))))

+


Remove remaining clojure.test items from item lifecycle tests.

--- test/fcms/unit/resources/item/item_lifecycle.clj
+++ test/fcms/unit/resources/item/item_lifecycle.clj
@@ -24,13 +24,6 @@

 (def timestamp org.joda.time.DateTime)

-(defn verify-new-resource [coll-slug resource]
-  (is (= (:collection resource) e))
-  (is (= (:version resource) 1))
-  (is (instance? String (:id resource)))
-  (is (instance? timestamp (:created-at resource)))
-  (is (= (:created-at resource) (:updated-at resource))))
-
 ;; ----- Tests -----

 (with-state-changes [(before :facts (empty-collection-e))
@@ -38,66 +31,88 @@

   (future-facts "about the validity of new items")

-  (facts "about item creation"
+  (facts "about successful item creation"

-      (fact "with a generated slug"
-        (let [item (create-item e ascii-name)]
-          (:name item) => ascii-name
-          (:slug item) => "test-this"
-          (verify-new-resource e item)))
+    (with-state-changes [(before :facts (create-item e i))
+                         (after :facts (delete-item e i))]

-      (fact "with a unicode name"
-        (let [item (create-item e unicode-name)]
-          (:name item) => unicode-name
-          (:slug item) => "1"
-          (verify-new-resource e item))
-        (let [item (create-item e mixed-name)]
-          (:name item) => mixed-name
-          (:slug item) => "test"
-          (verify-new-resource e item)))
+      (fact "resulting in a generated id"
+        (instance? String (:id (get-item e i))) => true)

-      (fact "with unicode properties"
-        (let [item (create-item e i {:description unicode-description})]
-          (:name item) => i
-          (:slug item) => i
-          (:description item) => unicode-description
-          (verify-new-resource e item)))
+      (fact "resulting in membership in the collection"
+        (:collection (get-item e i)) => e)

-      (fact "with a generated slug that is already used"
-        (let [item (create-item e ascii-name)]
-          (:name item) => ascii-name
-          (:slug item) => "test-this"
-          (verify-new-resource e item))
-        (let [item (create-item e ascii-name)]
-          (:name item) => ascii-name
-          (:slug item) => "test-this-1"
-          (verify-new-resource e item))
-        (let [item (create-item e ascii-name)]
-          (:name item) => ascii-name
-          (:slug item) => "test-this-2"
-          (verify-new-resource e item)))
+      (fact "resulting in an initial version"
+        (:version (get-item e i)) => 1)

-      (fact "with a provided slug"
-        (let [item (create-item e ascii-name {:slug slug})]
-          (:name item) => ascii-name
-          (:slug item) => slug
-          (verify-new-resource e item)))
+      (fact "resulting in good initial timestamps"
+        (instance? timestamp (:created-at (get-item e i))) => true
+        (:created-at (get-item e i)) => (:updated-at (get-item e i))))

-      (fact "with a provided slug that is already used"
-        (create-item e "first" {:slug slug})
-        (create-item e "second" {:slug slug}) => :slug-conflict)
+    (fact "with a generated slug"
+      (create-item e ascii-name)
+      (let [item-slug "test-this"
+            item (get-item e item-slug)]
+        (:name item) => ascii-name
+        (:slug item) => item-slug))

-      (fact "with a provided slug that is invalid"
-        (create-item e ascii-name {:slug "i I"}) => :invalid-slug)
+    (fact "with a unicode name"
+      (create-item e unicode-name)
+      (let [item-slug "1"
+            item (get-item e item-slug)]
+        (:name item) => unicode-name
+        (:slug item) => item-slug)
+      (create-item e mixed-name)
+      (let [item-slug "test"
+            item (get-item e item-slug)]
+        (:name item) => mixed-name
+        (:slug item) => "test"))

-      (fact "with a collection that doesn't exist"
-        (create-item "not-here" ascii-name) => :bad-collection)
+    (fact "with unicode properties"
+      (create-item e i {:description unicode-description})
+      (let [item (get-item e i)]
+        (:name item) => i
+        (:slug item) => i
+        (:description item) => unicode-description))

-      (fact "with a reserved property"
-        (doseq [prop resource/reserved-properties]
-          (create-item e i {prop "foo"}) => :property-conflict
-          (create-item e i {(name prop) "foo"}) => :property-conflict)))
+    (fact "with a generated slug that is already used"
+      (create-item e ascii-name)
+      (let [item-slug "test-this"
+            item (get-item e item-slug)]
+        (:name item) => ascii-name
+        (:slug item) => item-slug)
+      (create-item e ascii-name)
+      (let [item-slug "test-this-1"
+            item (get-item e item-slug)]
+        (:name item) => ascii-name
+        (:slug item) => item-slug)
+      (create-item e ascii-name)
+      (let [item-slug "test-this-2"
+            item (get-item e item-slug)]
+        (:name item) => ascii-name
+        (:slug item) => item-slug))

+    (fact "with a provided slug"
+      (let [item (create-item e ascii-name {:slug slug})]
+        (:name item) => ascii-name
+        (:slug item) => slug)))
+
+  (facts "about item creation failures"
+
+    (fact "with a provided slug that is already used"
+      (create-item e "first" {:slug slug})
+      (create-item e "second" {:slug slug}) => :slug-conflict)
+
+    (fact "with a provided slug that is invalid"
+      (create-item e ascii-name {:slug "i I"}) => :invalid-slug)
+
+    (fact "with a collection that doesn't exist"
+      (create-item "not-here" ascii-name) => :bad-collection)
+
+    (fact "with a reserved property"
+      (doseq [prop resource/reserved-properties]
+        (create-item e i {prop "foo"}) => :property-conflict
+        (create-item e i {(name prop) "foo"}) => :property-conflict)))

   (facts "about item retrieval"

@@ -111,6 +126,9 @@

     (with-state-changes [(before :facts (existing-item-i))
                      (after :facts (delete-item e i))]
+
+      (fact "when retrieving the item's id"
+        (instance? String (:id (get-item e i))) => true)

       (fact "when retrieving the item's collection"
         (:collection (get-item e i)) => e)


better formatting

better formatting

--- uni-linear-regression.clj
+++ uni-linear-regression.clj
@@ -34,7 +34,8 @@
 (defn st-dev [a-vector]
   (let [themean (mean a-vector)]
     (Math/pow (/ (reduce + (map #(Math/pow % 2)
-                             (map #(- % themean) a-vector)))
+                                (map #(- % themean)
+                                     a-vector)))
                  (- (count a-vector) 1)) 0.5)))

@@ -59,12 +60,16 @@

+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
 ;; ?!??!???!! (does the fitting and everything)
 (defn fit-straight-line [x-vec y-vec]
   (println x-vec)
   (println y-vec))
 ; adaptive learning rate?

+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


Put tests directory onto classpath

Put tests directory onto classpath

Fix #23

"test" directory can be in :source-paths because they do not end up in
resulting jars like :resource-paths do.

`(test-all)` now works after first doing a `(reset)` (or more specifically
doing a repl/refresh)

--- build.boot
+++ build.boot
@@ -32,8 +32,9 @@
 (def version (deduce-version-from-git))

 (set-env!
- :source-paths #{"sass" "src"}
- :test-paths #{"test"}
+ ;; It's okay for "test" to be used in source-paths as they don't go into
+ ;; resulting jar unless AOT'd.
+ :source-paths #{"sass" "src" "test"}
  :resource-paths #{"resources"}
  :asset-paths #{"assets"}
  :dependencies


update bot sim

update bot sim

--- build.boot
+++ build.boot
@@ -57,11 +57,14 @@

 (defn arena-2
   [player]
-  (let [w (gu/sanitize-player player)]
+  (let [w (gu/sanitize-player player)
+        a1 (assoc a :uuid "a1")
+        a2 (assoc a :uuid "a2")
+        a3 (assoc a :uuid "a3")]
     [[b b b b b b b b b b b b b b b b]
-     [b a o o a o o o o o o o o o o b]
+     [b a1 o o a2 o o o o o o o o o o b]
      [b o o p o f o o f o o p o o o b]
-     [b f o o o o o o f o a o o o o b]
+     [b f o o o o o o f o p o o o o b]
      [b f o o o o o o o o o o o o o b]
      [b p o o o o o o f o o f o o o b]
      [b b b b o f o o o o o o o o o b]
@@ -69,7 +72,7 @@
      [b f o o o o f o o f o o o b o b]
      [b f o o o o f o o f o b b b o b]
      [b f o o o o o o o o o o o o o b]
-     [b o o o o o f o o o f o f a o b]
+     [b o o o o o f o o o f o f a3 o b]
      [b f o o o o o o o o o o o o o b]
      [b f o o o o f o o o o f o o o b]
      [b w o o o o p o o o o o o o o b]
@@ -94,22 +97,22 @@
    f b f o b o

   Arena 2:
-   [[b b b b b b b b b b b b b b b b]
-    [b a o o a o o o o o o o o o o b]
-    [b o o p o f o o f o o p o o o b]
-    [b f o o o o o o f o a o o o o b]
-    [b f o o o o o o o o o o o o o b]
-    [b p o o o o o o f o o f o o o b]
-    [b b b b o f o o o o o o o o o b]
-    [b o o o p o o b o o o o f b o b]
-    [b f o o o o f o o f o o o b o b]
-    [b f o o o o f o o f o b b b o b]
-    [b f o o o o o o o o o o o o o b]
-    [b o o o o o f o o o f o f a o b]
-    [b f o o o o o o o o o o o o o b]
-    [b f o o o o f o o o o f o o o b]
-    [b B o o o o p o o o o o o o o b]
-    [b b b b b b b b b b b b b b b b]]"]
+    [[b b b b b b b b b b b b b b b b]
+     [b a o o a o o o o o o o o o o b]
+     [b o o p o f o o f o o p o o o b]
+     [b f o o o o o o f o p o o o o b]
+     [b f o o o o o o o o o o o o o b]
+     [b p o o o o o o f o o f o o o b]
+     [b b b b o f o o o o o o o o o b]
+     [b o o o p o o b o o o o f b o b]
+     [b f o o o o f o o f o o o b o b]
+     [b f o o o o f o o f o b b b o b]
+     [b f o o o o o o o o o o o o o b]
+     [b o o o o o f o o o f o f a o b]
+     [b f o o o o o o o o o o o o o b]
+     [b f o o o o f o o o o f o o o b]
+     [b B o o o o p o o o o o o o o b]
+     [b b b b b b b b b b b b b b b b]]"]
   (let [{:keys [code ratelimit-message]} (get-bot-code-simulator username repo token)
         arena-number (min 2 (or arena 1))
         player {:_id "1"


Bump version

Bump version

--- build.boot
+++ build.boot
@@ -11,7 +11,7 @@
          '[adzerk.boot-cljs   :refer [cljs]]
          '[pandeiro.boot-http :refer [serve]])

-(def +version+ "2.0.0")
+(def +version+ "2.1.0-SNAPSHOT")

 (task-options!
   pom {:project     'adzerk/boot-cljs


cleanup build.boot

cleanup build.boot

--- build.boot
+++ build.boot
@@ -16,23 +16,19 @@
 (load-data-readers!)

 (task-options!
- aot {:namespace   #{'osmium.core}}
- pom {:project     project
-      :version     version
-      :description "FIXME: write description"
-      :url         "http://example/FIXME"
-      :scm         {:url "https://github.com/bensu/osmium"}
-      :license     {"Eclipse Public License"
-                    "http://www.eclipse.org/legal/epl-v10.html"}}
- jar {:main        'osmium.core
-      :file        (str "osmium-" version "-standalone.jar")}
- push {:repo "clojars"})
+  pom {:project     project
+       :version     version
+       :description "FIXME: write description"
+       :url         "http://example/FIXME"
+       :scm         {:url "https://github.com/bensu/osmium"}
+       :license     {"Eclipse Public License"
+                     "http://www.eclipse.org/legal/epl-v10.html"}}
+  push {:repo "clojars"})

 (deftask build
   "Build the project locally as a JAR."
-  [d dir PATH #{str} "the set of directories to write to (target)."]
-  (let [dir (if (seq dir) dir #{"target"})]
-    (comp (aot) (pom) (uber) (jar) (target :dir dir))))
+  []
+  (comp (javac) (pom) (jar) (install)))

 (deftask run
   "Run the project."


Update dependencies.

Update dependencies.

--- build.boot
+++ build.boot
@@ -1,25 +1,25 @@
 (set-env!
  :source-paths   #{"src"}
  :resource-paths #{"html"}
- :dependencies '[[adzerk/boot-cljs      "1.7.48-5" :scope "test"]
+ :dependencies '[[adzerk/boot-cljs      "1.7.166-1" :scope "test"]
                  [adzerk/boot-cljs-repl "0.2.0" :scope "test"]
-                 [adzerk/boot-reload    "0.4.0"      :scope "test"]
+                 [adzerk/boot-reload    "0.4.1"      :scope "test"]

                  [org.clojure/core.async "0.1.346.0-17112a-alpha"]
-                 [prismatic/schema "1.0.1"]
+                 [prismatic/schema "1.0.3"]
                  [reagent "0.5.1"]
-                 [re-frame "0.4.1"]
+                 [re-frame "0.5.0"]
                  [re-com "0.6.2"]
-                 [org.clojure/tools.nrepl "0.2.10"]
+                 [org.clojure/tools.nrepl "0.2.11"]
                  [dragonmark/web "0.1.8"]
                  [markdown-clj "0.9.71"]
                  [cljsjs/jquery "1.9.1-0"]
                  [cljsjs/jquery-ui "1.11.3-1"]
                  [cljsjs/mousetrap "1.5.3-0"]
-                 [org.clojure/clojurescript "1.7.48" ]
+                 [org.clojure/clojurescript "1.7.145" ]
                  [boot-cljs-test/node-runner "0.1.0" :scope "test"]
                  [pandeiro/boot-http    "0.6.3"      :scope "test"]
-                 [org.clojure/test.check "0.8.1" :scope "test"]])
+                 [org.clojure/test.check "0.8.2" :scope "test"]])

 (require
  '[adzerk.boot-cljs      :refer [cljs]]
@@ -45,7 +45,7 @@
 (deftask dev []
   (set-env!
    :source-paths #{"src"})
-  (comp (serve :dir "target/")
+  (comp (serve :dir "target/" :port 3456)
         (watch)
         (speak)
         (reload :on-jsload 'app.core/main)


Fix post snippet

Fix post snippet

--- src/swartz/controllers.clj
+++ src/swartz/controllers.clj
@@ -41,7 +41,7 @@

 (html/defsnippet post-snippet "templates/post-snippet.html"
   [:.post]
-  [post]
+  [{:keys [post]}]
   [:a.title] (html/content (:title post))
   [:a.title] (fn [el]
                (let [url (:url post)]


Fix remove-browser event handler

Fix remove-browser event handler

Signed-off-by: Andrey Shovkoplyas <b713972e59b8e606e23253c4a13e948139fea4d1@gmail.com>

--- src/status_im/ui/screens/browser/events.cljs
+++ src/status_im/ui/screens/browser/events.cljs
@@ -70,4 +70,4 @@
   [re-frame/trim-v]
   (fn [{:keys [db]} [browser-id]]
     {:db (update-in db [:browser/browsers] dissoc browser-id)
-     :remove-browser browser-id}))
+     :data-store/remove-browser browser-id}))


Add log statement for stepper debugging.

--- src/uswitch/bifrost/s3.clj
+++ src/uswitch/bifrost/s3.clj
@@ -37,6 +37,7 @@
    topic partition
    first-offset last-offset
    file-path]
+  (info "Asked to step" {:state state :file-path file-path})
   (case state
     nil          {:goto :upload-file}
     :upload-file (try (info "Starting S3 upload for" {:topic topic


bug #5694 and #5709 - re-required request events

Signed-off-by: Goran Jovic <fc686822162e6f379ea05b6f92d78d206147085c@gmail.com>

--- src/status_im/ui/screens/events.cljs
+++ src/status_im/ui/screens/events.cljs
@@ -30,6 +30,7 @@
             [status-im.models.wallet :as models.wallet]
             status-im.ui.screens.wallet.collectibles.events
             status-im.ui.screens.wallet.send.events
+            status-im.ui.screens.wallet.request.events
             status-im.ui.screens.wallet.settings.events
             status-im.ui.screens.wallet.transactions.events
             status-im.ui.screens.wallet.choose-recipient.events


removes unused import

removes unused import

--- src-cljs/views/head_form.cljs
+++ src-cljs/views/head_form.cljs
@@ -1,7 +1,6 @@
 (ns doctopus.views.head-form
   (:require [cljs.core.async :refer [<!]]
             [cljs-http.client :as http]
-            [clojure.string :as s]
             [doctopus.util :refer [get-value http-ok? redirect-to in? maybe-conj]]
             [doctopus.validation :as validation]
             [doctopus.views.common :refer [button]]


Fix for multiple Team Sponsorships.

Fix for multiple Team Sponsorships.

--- src/clj/game/cards-assets.clj
+++ src/clj/game/cards-assets.clj
@@ -547,15 +547,22 @@
                  :msg "swap the positions of two ICE"}]}

    "Team Sponsorship"
+   (let [thelper (fn ts [n] {:prompt "Install a card from Archives or HQ?" :choices ["Archives" "HQ"]
+                             :msg (msg "install a card from " target)
+                             :effect (effect (resolve-ability
+                                               {:prompt "Choose a card to install"
+                                                :choices (req (filter #(not= (:type %) "Operation")
+                                                                      ((if (= target "HQ") :hand :discard) corp)))
+                                                :effect (req (corp-install state side target nil {:no-install-cost true})
+                                                             (when (pos? (dec n))
+                                                               (resolve-ability state side (ts (dec n)) card nil)))}
+                                               card targets))})]
    {:events {:agenda-scored
-             {:prompt "Install a card from Archives or HQ?" :choices ["Archives" "HQ"]
-              :msg (msg "install a card from " target)
-              :effect (effect (resolve-ability
-                               {:prompt "Choose a card to install"
-                                :choices (req (filter #(not= (:type %) "Operation")
-                                                      ((if (= target "HQ") :hand :discard) corp)))
-                                :effect (effect (corp-install target nil {:no-install-cost true}))}
-                               card targets))}}}
+             {:req (req (not (get-in @state [:per-turn (keyword (str "team-sponsorship-" (:cid target)))]))) ; only one TS responds per score
+              :effect (req (let [ts (->> (:corp @state) :servers seq flatten (mapcat :content)
+                                         (filter #(and (:rezzed %) (= (:title %) "Team Sponsorship"))) count)]
+                             (swap! state assoc-in [:per-turn (keyword (str "team-sponsorship-" (:cid target)))] true)
+                             (resolve-ability state side (thelper ts) card nil)))}}})

    "Tech Startup"
    {:abilities [{:label "Install an asset from R&D"


Simplified callback API.

Simplified callback API.

Work on issue #32.
Internal usage of execute-request follows now simplified form.

--- src/clj/http/async/client.clj
+++ src/clj/http/async/client.clj
@@ -144,9 +144,9 @@
       :realm    - realm name to authenticate in
     :timeout - request timeout in ms")]
               `(defn ~fn-name ~fn-doc [~'client #^String ~'url & {:as ~'options}]
-                 (apply execute-request ~'client
-                        (apply prepare-request ~method# ~'url (apply concat ~'options))
-                        (apply concat *default-callbacks*)))))
+                 (execute-request ~'client
+                                  (apply prepare-request ~method# ~'url
+                                         (apply concat ~'options))))))
           methods)))

 (gen-methods :get :post :put :delete :head :options)
@@ -159,25 +159,23 @@
                        and received body part as vector of bytes
   options - are optional and can contain :headers, :param, and :query (see prepare-request)."
   [client method #^String url body-part-callback & {:as options}]
-  (apply execute-request client
-         (apply prepare-request method url (apply concat options))
-         (apply concat (merge *default-callbacks* {:part body-part-callback}))))
+  (execute-request client
+                   (apply prepare-request method url (apply concat options))
+                   :part body-part-callback))

 (defn stream-seq
   "Creates potentially infinite lazy sequence of Http Stream."
   [client method #^String url & {:as options}]
   (let [que (LinkedBlockingQueue.)]
-    (apply execute-request client
-           (apply prepare-request method url (apply concat options))
-           (apply concat (merge
-                          *default-callbacks*
-                          {:part (fn [_ baos]
-                                   (.put que baos)
-                                   [que :continue])
-                           :completed (fn [_] (.put que ::done))
-                           :error (fn [_ t]
-                                    (.put que ::done)
-                                    t)})))))
+    (execute-request client
+                     (apply prepare-request method url (apply concat options))
+                     :part (fn [_ baos]
+                             (.put que baos)
+                             [que :continue])
+                     :completed (fn [_] (.put que ::done))
+                     :error (fn [_ t]
+                              (.put que ::done)
+                              t))))

 (defn failed?
   "Checks if request failed."


missing function: user-owns-badge-id added

--- src/clj/salava/badge/main.clj
+++ src/clj/salava/badge/main.clj
@@ -89,6 +89,21 @@
                     (into {:result-set-fn first}
                           (get-db ctx)))
                   (select-user-owns-signed-badge
+                    {:assertion_json (get-in assertion [:assertion_json])
+                     :user_id user-id}
+                    (into {:result-set-fn first}
+                          (get-db ctx)))))))
+
+(defn user-owns-badge-id
+  "Check if user owns badge and returns id"
+  [ctx assertion user-id]
+  (str (:id (if (= (get-in assertion [:verify :type]) "hosted")
+                  (select-user-owns-hosted-badge-id
+                    {:assertion_url (get-in assertion [:verify :url])
+                     :user_id user-id}
+                    (into {:result-set-fn first}
+                          (get-db ctx)))
+                  (select-user-owns-signed-badge-id
                     {:assertion_json (get-in assertion [:assertion_json])
                      :user_id user-id}
                     (into {:result-set-fn first}


small fix

small fix

--- src/clj/salava/gallery/db.clj
+++ src/clj/salava/gallery/db.clj
@@ -360,7 +360,7 @@

 (defn gallery-stats [ctx last-login]
   {:profiles {:all (gallery-profiles-count {} (into {:result-set-fn first :row-fn :profiles_count}(get-db ctx)))
-              :since_last_login}
+              :since_last_login nil}
    :pages (gallery-pages-count {} (into {:result-set-fn first :row-fn :pages_count}(get-db ctx)))
    :badges (gallery-badges-count {} (into {:result-set-fn first :row-fn :badges_count}(get-db ctx)))})


add test for Aggressive Secretary

add test for Aggressive Secretary

--- src/clj/test/cards-assets.clj
+++ src/clj/test/cards-assets.clj
@@ -11,6 +11,33 @@
       (take-credits state :corp 2)
       (take-credits state :runner)
       (is (= 6 (get-in @state [:corp :credit])))
+      )))
+
+(deftest aggressive-secretary
+  (do-game
+    (new-game
+      (default-corp [(qty "Aggressive Secretary" 1)])
+      (default-runner [(qty "Cache" 3)]))
+    (play-from-hand state :corp "Aggressive Secretary" "New remote")
+    (let [as (first (get-in @state [:corp :servers :remote1 :content]))]
+      (core/advance state :corp as)
+      (take-credits state :corp)
+      ;Run on AggSec with 3 programs
+      (play-from-hand state :runner "Cache")
+      (play-from-hand state :runner "Cache")
+      (play-from-hand state :runner "Cache")
+      (core/run state :runner :remote1)
+      (core/no-action state :corp nil)
+      (core/successful-run state :runner nil)
+      (prompt-choice :corp "Yes")
+      (is (= 3 (get-in @state [:corp :credit])))
+      (prompt-select :corp (get-in @state [:runner :rig :program 1]))
+      (prompt-choice :corp "Done")
+      ;There should be one Cache left
+      (is (= 3 (get-in @state [:corp :credit])))
+      (is (=
+            2
+            (count (get-in @state [:runner :rig :program]))))
       )))

 (deftest franchise-city


Show "no abilities" message if player has no abilities

--- src/cljc/robinson/render.cljc
+++ src/cljc/robinson/render.cljc
@@ -602,16 +602,21 @@
         abilities (rp/player-abilities state)
         height (+ 3 (count abilities))]
     (render-list screen 17 4 43 height
-      (concat
-        (map
-          (fn [ability]
-            {:s (format "<color fg=\"highlight\">%s</color> - %s" (get ability :hotkey) (get ability :name))
-             :fg :black
-             :bg :white
-             :style #{}})
-          abilities)
-        [{:s "" :fg :black :bg :white :style #{}}
+      (if (seq abilities)
+        (concat
+          (map
+            (fn [ability]
+              {:s (format "<color fg=\"highlight\">%s</color> - %s" (get ability :hotkey) (get ability :name))
+               :fg :black
+               :bg :white
+               :style #{}})
+            abilities)
+          [{:s "" :fg :black :bg :white :style #{}}
+           {:s "Select hotkey or press <color fg=\"highlight\">Esc</color> to exit." :fg :black :bg :white :style #{}}])
+        [{:s "No abilities." :fg :black :bg :white :style #{}}
+         {:s "" :fg :black :bg :white :style #{}}
          {:s "Select hotkey or press <color fg=\"highlight\">Esc</color> to exit." :fg :black :bg :white :style #{}}]))
+
     (render-rect-double-border screen 16 3 43 height :black :white)
     (put-string screen 33 3 "Abilities" :black :white)))


added error/unauthorized routes mapping #186

--- src/cljc/swarmpit/routes.cljc
+++ src/cljc/swarmpit/routes.cljc
@@ -70,6 +70,8 @@

 (def frontend ["" {"/"                        :index
                    "/login"                   :login
+                   "/error"                   :error
+                   "/unauthorized"            :unauthorized
                    "/password"                :password
                    "/services"                {""               :service-list
                                                "/create/wizard" {"/image"  :service-create-image


config BE routes #180

config BE routes
#180

--- src/cljc/swarmpit/routes.cljc
+++ src/cljc/swarmpit/routes.cljc
@@ -53,6 +53,10 @@
        "/secrets/"      {:get    {[:id] :secret}
                          :delete {[:id] :secret-delete}
                          :post   {[:id] :secret-update}}
+       "/configs"       {:get  :configs
+                         :post :config-create}
+       "/configs/"      {:get    {[:id] :config}
+                         :delete {[:id] :config-delete}}
        "/nodes"         {:get :nodes}
        "/placement"     {:get :placement}
        "/nodes/"        {:get {[:id] {""       :node


fixed youtube url

fixed youtube url

--- src/cljs/redditv/youtube.cljs
+++ src/cljs/redditv/youtube.cljs
@@ -3,8 +3,8 @@
   (:require [cljs.core.async :refer [put! chan <! >! timeout close!]]
             [redditv.player :as player]))

-(def regex-youtube-url #"^https?://www\.youtube\.com/.*?v=([a-zA-Z0-9]+)&?.*")
-(def regex-youtube-shortened-url #"^https?://youtu\.be/([a-zA-Z0-9]+)\??.*")
+(def regex-youtube-url #"^https?://www\.youtube\.com/.*?v=([a-zA-Z0-9_]+)&?.*")
+(def regex-youtube-shortened-url #"^https?://youtu\.be/([a-zA-Z0-9_]+)\??.*")

 (defn video-url->video-id [url]
   (cond


Fix color

Fix color

--- src/cljs/threed/renderer.cljs
+++ src/cljs/threed/renderer.cljs
@@ -93,11 +93,14 @@
                    )))

 (defn color->material [color]
-  ;; TODO generalize numbers
-  (color {:red 0
+  (if color
+    ;; TODO generalize numbers
+    (get {:red 0
           :green 6
           :water 12
-          :lava 18}))
+          :lava 18}
+         color)
+    0))

 (defn add-blocks [blocks]
   {:name :add-blocks :blocks blocks})


Added printing of total time and fixed "milliseconds" typo.

--- src/clojush/pushgp/report.clj
+++ src/clojush/pushgp/report.clj
@@ -170,7 +170,7 @@
         (println "Min copy number of one program:" (apply min (vals frequency-map)))
         (println "Median copy number:" (nth (sort (vals frequency-map)) (Math/floor (/ (count frequency-map) 2)))))
       (println "--- Timings ---")
-      (println "Current time:" (System/currentTimeMillis) "miliseconds")
+      (println "Current time:" (System/currentTimeMillis) "milliseconds")
       (when @global-print-timings
         (let [total-time (apply + (vals @global-timing-map))
               init (get @global-timing-map :initialization)
@@ -178,6 +178,7 @@
               fitness (get @global-timing-map :fitness)
               report-time (get @global-timing-map :report)
               other (get @global-timing-map :other)]
+          (printf "Total Time:      %8.1f seconds\n" (/ total-time 1000.0))
           (printf "Initialization:  %8.1f seconds, %4.1f%%\n" (/ init 1000.0) (* 100.0 (/ init total-time)))
           (printf "Reproduction:    %8.1f seconds, %4.1f%%\n" (/ reproduction 1000.0) (* 100.0 (/ reproduction total-time)))
           (printf "Fitness Testing: %8.1f seconds, %4.1f%%\n" (/ fitness 1000.0) (* 100.0 (/ fitness total-time)))


Fixing acl enforcement.

Fixing acl enforcement.

--- src/cmr/search/api/routes.clj
+++ src/cmr/search/api/routes.clj
@@ -274,14 +274,16 @@

       ;; Resets the application back to it's initial state.
        (POST "/reset" {:keys [request-context params headers]}
-         (acl/verify-ingest-management-permission request-context)
-        (query-svc/clear-cache (acl/add-authentication-to-context request-context params headers))
+         (acl/verify-ingest-management-permission
+          (acl/add-authentication-to-context request-context params headers))
+        (query-svc/clear-cache request-context)
         {:status 200})

       ;; Clears the cache.
       (POST "/clear-cache" {:keys [request-context params headers]}
-        (acl/verify-ingest-management-permission request-context)
-        (query-svc/clear-cache (acl/add-authentication-to-context request-context params headers))
+        (acl/verify-ingest-management-permission
+          (acl/add-authentication-to-context request-context params headers))
+        (query-svc/clear-cache request-context)
         {:status 200}))
     (route/not-found "Not Found")))


CMR-380: Added other functions for converting any shape into an MBR or LR.

--- src/cmr/spatial/serialize.clj
+++ src/cmr/spatial/serialize.clj
@@ -3,7 +3,8 @@
   (:require [cmr.common.services.errors :as errors]
             [cmr.spatial.ring :as r]
             [cmr.spatial.math :refer :all]
-            [cmr.spatial.polygon :as poly]))
+            [cmr.spatial.polygon :as poly]
+            [cmr.spatial.lr-binary-search :as lr]))

 ;; Some thoughts about how to store the elasticsearch data in a way that preserves space and accuracy.
@@ -53,19 +54,43 @@
   [v]
   (double (/ v multiplication-factor)))

-(defprotocol ShapeStoredOrdinatesConversion
+(defprotocol SerializeConversions
   (shape->stored-ords
     [shape]
-    "Converts a spatial shape into the ordinates to ordinates to store in the search index"))
+    "Converts a spatial shape into the ordinates to ordinates to store in the search index")
+  (shape->mbr
+    [shape]
+    "Converts a spatial shape into it's minimum bounding rectangle")
+  (shape->lr
+    [shape]
+    "Determins the largest interior rectangle of a shape"))

-(extend-protocol ShapeStoredOrdinatesConversion
+(extend-protocol SerializeConversions
+
   cmr.spatial.polygon.Polygon
+
   (shape->stored-ords
     [{:keys [rings]}]
     ;; only supports single ring polygons for now
     (when (> (count rings) 1)
       (errors/internal-error! "shape->stored-ords only supports polygons with a single ring. TODO add support"))
-    (map ordinate->stored (r/ring->ords (first rings)))))
+    (map ordinate->stored (r/ring->ords (first rings))))
+
+  (shape->mbr
+    [{:keys [mbr]}]
+    mbr)
+
+  (shape->lr
+    [{:keys [rings]}]
+    ;; TODO this does not yet take into account holes
+    (when (> (count rings) 1)
+      (errors/internal-error! "Finding LR of polygon with holes is not supported yet."))
+    (if-let [lr (lr/find-lr (first rings))]
+      lr
+      (errors/internal-error!
+        (format "Unable to find lr of ring [%s]. The current LR algorithm is limited and needs to be improved."
+                (pr-str (first rings)))))))
+

 (defmulti stored-ords->shape
   "Converts a type and stored ordinates into a spatial shape"


Assert the right key

Assert the right key

--- src/grimoire/api/fs/write.clj
+++ src/grimoire/api/fs/write.clj
@@ -20,7 +20,7 @@
   {:pre [(string? data)
          thing
          config
-         (-> config :datastore :doc)]}
+         (-> config :datastore :notes)]}
   (let [thing  (ensure-thing thing)
         _      (assert thing)
         handle (thing->notes-handle config thing)


PLD: remove leading spaces

PLD: remove leading spaces

--- src/hatti/views/dataview.cljs
+++ src/hatti/views/dataview.cljs
@@ -53,16 +53,16 @@
    [:span.tooltip
     [:span.tip-info.tooltip
      (cond
-       is-encrypted? " This tab is disabled because this form is encrypted."
+       is-encrypted? "This tab is disabled because this form is encrypted."
        not-within-pricing-limits?
-       " This tab is disabled because you are over the pricing limits."
+       "This tab is disabled because you are over the pricing limits."
        :else
        (condp = view
-         :map (str " The Map tab is disabled because this form "
+         :map (str "The Map tab is disabled because this form "
                    "has no location questions.")
-         :photos (str " The Photos tab is disabled because this form has no "
+         :photos (str "The Photos tab is disabled because this form has no "
                       "photo questions.")
-         :table (str " The table tab is disabled because you do not have "
+         :table (str "The table tab is disabled because you do not have "
                      "permissions to view it.")
          "This tab is disabled."))]
     [:span.tip-question "?"]]])