remove unneeded parentheses

remove unneeded parentheses

--- src/babel/english/lexicon.clj
+++ src/babel/english/lexicon.clj
@@ -1089,13 +1089,12 @@
                           :pred :donna
                           :child false}}})

-   "work" [
-           {:synsem {:cat :verb
+   "work" [{:synsem {:cat :verb
                      :sem {:pred :work-human
                            :subj {:human true}}}
-            :english {:note "(human)"}}
+            :english {:note "human"}}

-           {:english {:note "(nonliving or machines)"} ;; TODO: add support in UI for :note.
+           {:english {:note "nonliving or machines"} ;; TODO: add support in UI for :note.
             :synsem {:cat :verb
                      :sem {:subj {:living false
                                   :human false ;; should not need to add human=false and animate=false: living=false should suffice.


fixed conducir

fixed conducir

--- src/babel/espanol/lexicon.clj
+++ src/babel/espanol/lexicon.clj
@@ -11,7 +11,7 @@
    [babel.pos :as pos :refer [pronoun-acc]]
    [dag_unify.core :refer [fail? get-in]]))

-(def lexicon-source
+(def lexicon-source
   {""
    [{:use-for-generation false
      :synsem {:cat :noun
@@ -74,7 +74,7 @@

    "abrazar" {:synsem {:cat :verb
                        :sem {:pred :hug}}}
-
+
    "acabar" {:synsem {:cat :verb
                       :sem {:pred :finish}}}

@@ -84,83 +84,83 @@
    "acertar" {:espanol {:boot-stem "aciert"}
               :synsem {:cat :verb
                        :sem {:pred :guess}}}
-
+
    "acompañar" {:synsem {:cat :verb
                          :sem {:pred :accompany}}}

    "advertir" {:espanol {:boot-stem "adviert"}
                :synsem {:cat :verb
                         :sem {:pred :warn}}}
-
+
    "almorzar" {:espanol {:boot-stem "almuerz"}
                :synsem {:cat :verb
                         :sem {:pred :have-lunch}}}
-
+
    "andar" {:espanol {:preterito-stem "anduv"}
                :synsem {:cat :verb
                         :sem {:pred :walk}}}
-
-
-
+
+
+
    "anunciar" {:synsem {:cat :verb
                         :sem {:pred :announce}}}

    "añadir" {:synsem {:cat :verb
                         :sem {:pred :add}}}
-
+
    "apagar" {:synsem {:cat :verb
                       :sem {:pred :turn-off}}}
-
+
    "apoyar" {:synsem {:cat :verb
                       :sem {:pred :support}}}

    "aprender" {:synsem {:cat :verb
                         :sem {:pred :learn}}}
-
+
    "aprobar" {:synsem {:cat :verb
                         :sem {:pred :approve}}}
-
+
    "aprovechar" [
                  {:synsem {:cat :verb
                            :sem {:pred :take-advantage-of}}}
                  {:synsem {:cat :verb
                            :sem {:pred :enjoy}}}]
-
+
    "asegurar" [{:synsem {:cat :verb
                          :sem {:pred :assure}}}
                {:synsem {:cat :verb
                          :sem {:pred :insure}}}]
-
+
    "aumentar" {:synsem {:cat :verb
                         :sem {:pred :increase}}}
-
+
    "ayudar" {:synsem {:cat :verb
                       :sem {:pred :aiutare
                             :obj {:human true}}}}
-
+
    "bailar" {:synsem {:cat :verb
                      :sem {:pred :dance}}}
-
+
    "bajar" {:synsem {:cat :verb
                      :sem {:pred :lower}}}
-
+
    "beber" {:synsem {:cat :verb
                      :sem {:pred :drink}}}
-
+
    "buscar" [{:synsem {:cat :verb
                        :sem {:pred :look-for}}}
              {:synsem {:cat :verb
                        :sem {:pred :look-up}}}]
-
+
    "caber" {:espanol {:present {:1sing "quepo"}
                       :preterito-stem "cup"}
             :synsem {:cat :verb
                      :sem {:pred :fit}}}
    "caer" {}
-
+
    "cambiar" {:synsem {:cat :verb
                        :sem {:pred :change}}}
-
+
    "cambiarse"
    (let [subject-semantics (atom {:human true})
          subject-agr (atom :top)]
@@ -175,8 +175,8 @@
                             :pronoun true
                             :reflexive true
                             :sem subject-semantics}}}})
-
-
+
+
    "caminar" {:synsem {:cat :verb
                         :sem {:pred :walk}}}
    "cancelar" {:synsem {:cat :verb
@@ -196,95 +196,95 @@
                             :pronoun true
                             :reflexive true
                             :sem subject-semantics}}}})
-
+
    "cenar" {:synsem {:cat :verb
                        :sem {:pred :have-dinner}}}
-
+
    "cerrar" {:espanol {:boot-stem "cierr"}
              :synsem {:cat :verb
                       :sem {:pred :close}}}
-
+
    "comentar" {:synsem {:cat :verb
                         :sem {:pred :comment}}}
-
+
    "comenzar" {:espanol {:boot-stem "comienz"}
              :synsem {:cat :verb
                       :sem {:pred :begin}}}
-
+
    "comer" {:synsem {:cat :verb
                      :sem {:pred :eat}}}

    "compartir" {:synsem {:cat :verb
                          :sem {:pred :share}}}
-
+
    "comprar" {:synsem {:cat :verb
                        :sem {:pred :comprare
                              :subj {:human true}
                              :obj {:buyable true}}}}
-
+
    "comprender" {:synsem {:cat :verb
                           :sem {:pred :understand-deeply}}}
-
+
    "confesar" {:espanol {:boot-stem "confies"}
              :synsem {:cat :verb
                       :sem {:pred :confess}}}
-
-   "conducir" [{:espanol {:present {:1sing "conduzco"}
-                          :preterito-stem "conduj"}
-                :synsem {:cat :verb
-                         :sem {:pred :lead}}}
-               {:espanol {:present {:1sing "conduzco"}
-                          :preterito-stem "conduj"}
-                :synsem {:cat :verb
-                         :sem {:pred :drive-c}}}]
+
+   "conducir" (let [common {:espanol {:present {:1sing "conduzco"}
+                                      :preterito-stem "conduj"}}]
+                [{:unify [common]
+                  :synsem {:cat :verb
+                           :sem {:pred :lead}}}
+                 {:unify [common]
+                  :synsem {:cat :verb
+                         :sem {:pred :drive-c}}}])
    "conocer" {}
-
+
    "consentir" {:espanol {:boot-stem "consient"}
                 :synsem {:cat :verb
                          :sem {:pred :consent}}}
-
+
    "conservar" [{:synsem {:cat :verb
                           :sem {:pred :conserve}}}
                 {:synsem {:cat :verb
                           :sem {:pred :preserve}}}]
-
+
    "considerar" {:synsem {:cat :verb
                           :sem {:pred :consider}}}
-
+
    "contar" {:espanol {:boot-stem "cuent"}
              :synsem {:cat :verb
                       :sem {:pred :count}}}
-
+
    "contestar" {:synsem {:cat :verb
                          :sem {:pred :answer}}}
-
+
    "convertir" {:espanol {:boot-stem "conviert"}
                 :synsem {:cat :verb
                          :sem {:pred :convert}}}
-
+
    "correr" {:synsem {:cat :verb
                       :sem {:pred :run}}}
-
+
    "corresponder" {:synsem {:cat :verb
                             :sem {:pred :correspond}}}
-
+
    "cortar" {:synsem {:cat :verb
                       :sem {:pred :cut}}}
-
+
    "crear" {:synsem {:cat :verb
                      :sem {:pred :create}}}
-
-   ;; TODO: clarify semantics of this in English
+
+   ;; TODO: clarify semantics of this in English
    ;;                     "cumplir" {:synsem {:cat :verb
    ;;                                         :sem {:pred :turn-years}}}
-
-
+
+
    "creer" {:synsem {:cat :verb
                           :sem {:pred :believe}}}
-
-
+
+
    "dañar" {}
-
+
    "dar" {:espanol  {:present {:1sing "doy"
                                :2plur "dais"}
                      :preterito {:1sing "di"
@@ -295,17 +295,17 @@
                                  :3plur "dieron"}}
           :synsem {:cat :verb
                    :sem {:pred :give}}}
-
+
    "deber" {:synsem {:cat :verb
                      :sem {:pred :have-to}}}
-
+
    "defender" {:espanol {:boot-stem "defiend"}
                 :synsem {:cat :verb
                          :sem {:pred :defend}}}

   "decidir" {:synsem {:cat :verb
                        :sem {:pred :decide}}}
-
+
   "decir" (let [common
                 {:espanol {:futuro-stem "dir"
                            :present {:1sing "digo"
@@ -319,22 +319,22 @@
                     {:synsem {:sem {:pred :say}}})
              (unify common
                     {:synsem {:sem {:pred :tell}}})])
-
+
    "dejar" {:synsem {:cat :verb
                      :sem {:pred :leave-behind}}}
-
-
+
+
    "deletrear" {}
-
+
    "desarrollar" {:synsem {:cat :verb
                            :sem {:pred :develop}}}
-
+
    "desear" {:synsem {:cat :verb
                       :sem {:pred :desire}}}
-
+
    "despertarse" {}
    "dibujar" {}
-
+
    "divertirse"
    (let [subject-semantics (atom {:human true})
          subject-agr (atom :top)]
@@ -350,7 +350,7 @@
                             :pronoun true
                             :reflexive true
                             :sem subject-semantics}}}})
-
+
    "dormir" {:espanol {:boot-stem "duerm"
                        :pret-stem "durm"}
              :synsem {:cat :verb
@@ -371,7 +371,7 @@
                             :pronoun true
                             :reflexive true
                             :sem subject-semantics}}}})
-
+
    "echar" {:synsem {:cat :verb
                      :sem {:pred :throw-out}}}
    "el"
@@ -380,7 +380,7 @@
                     :def :def
                     :gender :masc
                     :number :sing}})
-
+
    "él" [{:synsem {:cat cat-of-pronoun
                    :pronoun true
                    :case :nom
@@ -431,17 +431,17 @@
              :sem {:gender :fem
                    :pred :loro}
              :subcat '()}}
-
+
    "empezar" {:espanol {:boot-stem "empiez"}
               :synsem {:cat :verb
                        :sem {:pred :begin}}}
-
+
    "encender" {:espanol {:boot-stem "enciend"}
              :synsem {:cat :verb
                       :sem {:pred :light}}}
-
+
    "encontrar" {}
-
+
    "enojarse"
    (let [subject-semantics (atom {:human true})
          subject-agr (atom :top)]
@@ -456,68 +456,68 @@
                             :pronoun true
                             :reflexive true
                             :sem subject-semantics}}}})
-
+
    "enseñar" [{:note "e-"
                :synsem {:cat :verb
                         :sem {:pred :show}}}
               {:synsem {:cat :verb
                         :sem {:pred :teach}}}]
-
+
    "entender" {:espanol {:boot-stem "entiend"}
                :synsem {:cat :verb
                         :sem {:pred :understand-simply}}}
-
+
    "entrar" {:synsem {:cat :verb
                       :sem {:pred :enter}}}
-
+
    "enviar" {}
-
+
    "escapar" {:synsem {:cat :verb
                        :sem {:pred :escape}}}
-
+
    "escribir" {}
-
+
    "escuchar" {:synsem {:cat :verb
                         :sem {:pred :listen-to}}}
-
+
    "esperar" [{:synsem {:cat :verb
                         :sem {:pred :wait-for}}}
               {:synsem {:cat :verb
                         :sem {:pred :hope}}}]
-
+
    "estudiar" {:synsem {:cat :verb
                         :sem {:pred :study}}}
-
+
    "evitar" {:synsem {:cat :verb
                       :sem {:pred :avoid}}}
-
+
    "existir" {:synsem {:cat :verb
                        :sem {:pred :exist}}}
-
+
    "explicar" {}
-
+
    "expresar" {:synsem {:cat :verb
                         :sem {:pred :express}}}
-
+
    ;; TODO: fix up so that it does not need to be disabled.
 ;   "faltar" {:synsem {:cat :verb
 ;                      :sem {:pred :to-be-missing}}}
-
+
    "firmar" {}
-
+
    "formar" {:synsem {:cat :verb
                       :sem {:pred :form}}}
-
+
    "fregar" {:espanol {:boot-stem "frieg"}
              :synsem {:cat :verb
                       :sem {:pred :scrub}}}
-
+
    "fumar" {}
-
+
    "funcionar" {:synsem {:cat :verb
                          :sem {:subj {:human false}
                                :pred :work-nonhuman}}}
-
+
    "ganar" [{:synsem {:cat :verb
                       :sem {:pred :earn
                             :subj {:human true}
@@ -526,13 +526,13 @@
                       :sem {:pred :win
                             :subj {:human true}
                             :obj {:human false}}}}]
-
+
    ;; TODO: handle syntax/semantics mismatch between Italian/Espanol and English.
                                         ;                     "gustar" {:synsem {:cat :verb
                                         ;                                         :sem {:pred :??}}}
-
+
    "gastar" {}
-
+
    "hablar" [{:synsem {:cat :verb
                        :sem {:pred :speak
                              :subj {:human true}}}}
@@ -557,15 +557,15 @@
              {:synsem {:sem {:pred :do}}})
       (unify common
              {:synsem {:sem {:pred :make}}})])
-
+
    "herir" {}
-
+
    "hervir" {:espanol {:boot-stem "hierv"}
              :synsem {:cat :verb
                       :sem {:pred :boil}}}
-
+
    "intentar" {}
-
+
    "ir" {:espanol {:futuro-stem "ir"
                    :present {:1sing "voy"
                              :2sing "vas"
@@ -616,10 +616,10 @@
                     :number :plur}
               :sem {:human true
                     :pred :Juan-and-i}
-              :subcat '()}}]
-
+              :subcat '()}}]
+
    "jugar" {}
-
+
    "la"
    (unify determiner
           {:synsem {:cat :det
@@ -640,10 +640,10 @@
                             :pronoun true
                             :reflexive true
                             :sem subject-semantics}}}})
-
+
    "lavar" {}
    "leer" {}
-
+
    "levantarse"
    (let [subject-semantics (atom {:human true})
          subject-agr (atom :top)]
@@ -658,9 +658,9 @@
                             :pronoun true
                             :reflexive true
                             :sem subject-semantics}}}})
-
+
    "limpiar" {}
-
+
    "llamarse"
    (let [subject-semantics (atom :top)
          called-semantics (atom :top)
@@ -692,19 +692,19 @@

    "llegar" {:synsem {:cat :verb
                       :sem {:pred :arrive}}}
-
+
    "llenar" {}
-
+
    "llevar" (let [shared-part-of-llevar
                   {:synsem {:cat :verb}}]
               [(unify shared-part-of-llevar
                       {:synsem {:sem {:pred :carry}}})
                (unify shared-part-of-llevar
                       {:synsem {:sem {:pred :bring}}})])
-
+
    "llorar" {}
    "manejar" {}
-
+
    "me" {:synsem {:cat :noun
                   :pronoun true
                   :reflexive true
@@ -716,12 +716,12 @@
    "mentir" {:espanol {:boot-stem "mient"}
              :synsem {:cat :verb
                       :sem {:pred :lie}}}
-
+
    "mirar" {}
    "mostrar" {:note "m-"
               :synsem {:cat :verb
                        :sem {:pred :show}}}
-
+
    "mujer"
    (unify agreement-noun
           common-noun
@@ -731,19 +731,19 @@
                     :subcat {:1 {:cat :det
                                  :number :sing
                                  :def :def}}}})
-
+
    "nacer" {:espanol  {:present {:1sing "nazco"}}
             :synsem {:cat :verb
                       :sem {:pred :be-born}}}
-
-
+
+
    "nadar" {}
    "necesitar" {}
-
+
    "negar" {:espanol {:boot-stem "nieg"}
                 :synsem {:cat :verb
                          :sem {:pred :deny}}}
-
+
    "nos" {:synsem {:cat :noun
                    :pronoun true
                    :reflexive true
@@ -774,10 +774,10 @@
              :sem {:human true
                    :gender :masc
                    :pred :noi}
-             :subcat '()}}
+             :subcat '()}}

    ;; 2nd person plural informal 'vosotros/as' (ES-only)
-
+
    "oir" {}
    "olvidar" {}
    "organizar" {}
@@ -785,7 +785,7 @@
    "parar" {}
    "pedir" {}
    "peinarse" {}
-
+
    "os"
    {:synsem {:cat cat-of-pronoun
              :pronoun true
@@ -804,19 +804,19 @@
                     :subcat {:1 {:cat :det
                                  :number :sing
                                  :def :def}}}})
-
+
    "pensar" {:espanol {:boot-stem "piens"}
              :synsem {:cat :verb
                       :sem {:pred :think}}}
-
+
    "perder" {:espanol {:boot-stem "pierd"}
                 :synsem {:cat :verb
                          :sem {:pred :lose}}}
-
+
    "pintar" {:synsem {:cat :verb
-                      :sem {:pred :paint}}}
-
-   "poder"
+                      :sem {:pred :paint}}}
+
+   "poder"
    (let [shared-part-of-poder
          {:espanol {:boot-stem "pued"
                     :pret-stem "pud"}
@@ -827,7 +827,7 @@
              {:synsem {:sem {:pred :may}}})
       (unify shared-part-of-poder
              {:synsem {:sem {:pred :be-able-to}}})])
-
+
    "poner" {:espanol {:futuro-stem "pondr"
                       :present {:1sing "pongo"
                                 :2sing "pones"
@@ -839,12 +839,12 @@
             :synsem {:cat :verb
                      :sem {:subj {:animate true}
                            :pred :put}}}
-
+
    "ponerse de pie" {}
    "preguntar" {}
    "preocuparse" {}
    "prestar" {}
-
+
    "quedarse" (let [subject-semantics (atom {:animate true})
                     subject-agr (atom :top)]
                 {:synsem {:cat :verb
@@ -858,9 +858,9 @@
                                        :pronoun true
                                        :reflexive true
                                        :sem subject-semantics}}}})
-
+
    "quejarse" {}
-
+
    "querer" (let [shared-part-of-querer
                   {:synsem {:cat :verb}
                    :espanol {:boot-stem "quier"
@@ -870,18 +870,18 @@
                       {:synsem {:sem {:pred :want}}})
                (unify shared-part-of-querer
                       {:synsem {:sem {:pred :love}}})])
-
+
    "reparar" {}
    "responder" {}
    "romper"  {}
-
+
    "saber" {}
    "sacar" {}
-
+
    "salir" {:espanol {:present {:1sing "salgo"}}
             :synsem {:cat :verb
                       :sem {:pred :go-out}}}
-
+
    "se"
    [;; 3rd singular or plural: 'él,ellas,..etc'
     {:synsem {:cat :noun
@@ -902,11 +902,11 @@

    "seguir" {}
    "sentarse" {}
-
+
    "sentir" {}
    "sentirse" {}
    "soñar" {}
-
+
    "te" {:synsem {:cat :noun
                   :pronoun true
                   :reflexive true
@@ -914,7 +914,7 @@
                   :agr {:person :2nd
                         :number :sing}
                   :subcat '()}}
-
+
    "tener" {:espanol {:futuro {:1sing "tendré"
                                :2sing "tendras"
                                :3sing "tendrà"
@@ -943,11 +943,11 @@
             :synsem {:cat :verb
                      :sem {:subj {:animate true}
                            :pred :have}}}
-
-
+
+
    "terminar" {}
-
-
+
+
    "tirar" [{:synsem {:cat :verb
                       :sem {:pred :throw-out}}}
             {:synsem {:cat :verb
@@ -958,7 +958,7 @@
    "trabajar" {}
    "traducir" {}
    "traer" {}
-
+
    "tú" {:synsem {:cat :noun
                   :pronoun true
                   :case :nom
@@ -967,9 +967,9 @@
                   :sem {:human true
                         :pred :tu}
                   :subcat '()}}
-
+
    "usar" {}
-
+
    "ustedes"
    {:synsem {:cat cat-of-pronoun
              :pronoun true
@@ -979,11 +979,11 @@
              :sem {:human true
                    :pred :voi}
              :subcat '()}}
-
-
+
+
    "valer" {}
    "vender" {}
-
+
    "venir" {:espanol {:futuro-stem "vendr"
                       :present {:1sing "vengo"
                                 :2sing "vienes"
@@ -993,20 +993,20 @@
             :synsem {:cat :verb
                      :sem {:subj {:animate true}
                            :pred :come}}}
-
+
    "ver" {:espanol  {:present {:1sing "veo"
                                :2plur "veis"}
                      :preterito {:1sing "vi"
                                  :3sing "vio"}}
           :synsem {:cat :verb
                    :sem {:pred :see}}}
-
+
    "vestirse" {}
    "viajar" {}
    "vivir" {}
    "volar" {}
    "volver" {}
-
+
    "vosotras"
    {:synsem {:cat cat-of-pronoun
              :pronoun true
@@ -1030,7 +1030,7 @@
                    :gender :masc
                    :pred :voi}
              :subcat '()}}
-
+
    "yo"
    {:synsem {:cat :noun
              :pronoun true
@@ -1040,7 +1040,7 @@
              :sem {:human true
                    :pred :I}
              :subcat '()}}})
-
+
 ;; see TODOs in lexiconfn/compile-lex (should be more of a pipeline as opposed to a
 ;; argument-position-sensitive function.
 (def lexicon
@@ -1053,11 +1053,11 @@
                          :sem {:reflexive false
                                :obj :unspec}}}
                {:synsem {:sem {:obj :unspec}}})
-
+
       ;; make an intransitive version of every verb which has an
       ;; [:sem :obj] path.
       intransitivize
-
+
       ;; if verb does specify a [:sem :obj], then fill it in with subcat info.
       transitivize

@@ -1065,27 +1065,26 @@
       (if-then {:synsem {:cat :verb
                          :aux false}}
                {:synsem {:aux false}})
-
+
       (if-then {:synsem {:cat :verb
                          :subcat {:2 {:reflexive false}}}}
                {:synsem {:subcat {:2 {:reflexive false}}}})
-
+
       (if-then {:synsem {:cat :noun
                          :pronoun true
                          :null-pronoun false}}
                {:synsem {:null-pronoun false}})
-
+
       (if-then {:synsem {:cat :verb
                          :subcat {:3 '()}}}
                {:synsem {:subcat {:3 '()}}})
-
+
       ;; Cleanup functions can go here. Number them for ease of reading.
       ;; 1. this filters out any verbs without an inflection: infinitive verbs
-      ;; should have inflection ':infinitive',
+      ;; should have inflection ':infinitive',
       ;; rather than not having any inflection.
-      (map-function-on-map-vals
+      (map-function-on-map-vals
        (fn [k vals]
          (filter #(or (not (= :verb (get-in % [:synsem :cat])))
                       (not (= :none (get-in % [:synsem :infl] :none))))
                  vals)))))
-


+generation of present progressive in Italian

--- src/babel/italiano/writer.clj
+++ src/babel/italiano/writer.clj
@@ -102,7 +102,8 @@
                            :tense :past}}}

            ;; present progressive
-           ;; TODO
+           {:synsem {:sem {:aspect :progressive
+                           :tense :present}}}
            ])


test: more test to ensure safety of read and read-string

--- src/test/clojure/clojure/tools/reader_test.clj
+++ src/test/clojure/clojure/tools/reader_test.clj
@@ -1,6 +1,6 @@
 (ns clojure.tools.reader-test
   (:refer-clojure :exclude [read-string])
-  (:require [clojure.tools.reader :refer [read-string default-data-reader-fn]]
+  (:require [clojure.tools.reader :refer [read-string default-data-reader-fn unsafe-read-string]]
             [clojure.test :refer [deftest is]])
   (:import clojure.lang.BigInt))

@@ -295,7 +295,11 @@
   (is (= 14 ((eval (read-string "#(apply + % %1 %3 %&)")) 1 2 3 4 5))))

 (deftest read-eval
-  (is (= 3 (read-string "#=(+ 1 2)"))))
+  (is (= 3 (binding [*read-eval* true]
+             (unsafe-read-string "#=(+ 1 2)"))))
+  (is (thrown-with-msg? Exception #"#= only allowed when using the unsafe- variants of read and read-string"
+        (binding [*read-eval* true]
+          (read-string "#=(+ 1 2)")))))

 (deftest read-tagged
   (is (= #inst "2010-11-12T13:14:15.666"


Patching up some comments

Patching up some comments

--- src/baseline/client/main.cljs
+++ src/baseline/client/main.cljs
@@ -12,9 +12,9 @@
 ;Where process-search is the main action to take when processing the page/url

 ;; ### Browser REPL
-;; If you add a `repl` as a query-string arg, even on the live Barker,
+;; If you add a `repl` as a query-string arg, even on the live Baseline,
 ;; You can remotely interact with the site from the local REPL
-;; Visit: `http://127.0.0.1:8080/search?repl=yes#q=sat`
+;; Visit: `http://127.0.0.1:8080/test?repl=yes#q=something+else`
 (common/toggle-brepl query-args :repl)

 ;; ### Confirm we have remote-calling activated


fix executor do not accept nil argument

fix executor do not accept nil argument

--- src/graphql_clj/executor.clj
+++ src/graphql_clj/executor.clj
@@ -94,7 +94,8 @@
                                    (get vars (str (get-in argument [:value :name]))))
            :list-value (let [values (get-in argument [:value :values])]
                          (assert values "No values for list type argument!")
-                         (map :value values)))
+                         (map :value values))
+           :null-value nil)
          (get default-args (str (:name argument))))]))

 (defn args-fn [arguments default-arguments vars]


[#2396] Remove unused feature flag on invite verify link [skip ci]

--- backend/src/akvo/lumen/endpoint/invite.clj
+++ backend/src/akvo/lumen/endpoint/invite.clj
@@ -39,8 +39,7 @@
                             (let [auth-system (get query-params "auth")]
                               (user/verify-invite authorizer
                                                   (p/connection tenant-manager tenant)
-                                                  tenant id (str (location (:invite-redirect config) request)
-                                                                 "?auth=" auth-system))))}}])
+                                                  tenant id (location (:invite-redirect config) request))))}}])

 (defmethod ig/init-key :akvo.lumen.endpoint.invite/invite  [_ opts]
   (admin-routes opts))


Start using new context namespace from cats.monad.exception ns.

--- src/cats/monad/exception.cljc
+++ src/cats/monad/exception.cljc
@@ -53,15 +53,12 @@
   That is because when you will dereference the
   failure instance, it will reraise the containing
   exception."
-  #?(:clj
-     (:require [cats.protocols :as p]
-               [cats.core :refer [with-monad]]))
-
-  #?@(:cljs
-      [(:require [cats.protocols :as p])
-
-       (:require-macros [cats.monad.exception :refer [try-on]]
-                        [cats.core :refer [with-monad]])]))
+
+  (:require [cats.protocols :as p]
+            #?(:clj [cats.context :as ctx]
+               :cljs [cats.context :as ctx :include-macros true]))
+  #?(:cljs
+     (:require-macros [cats.monad.exception :refer (try-on)])))

 (defn throw-exception
   [message]
@@ -231,7 +228,7 @@
   exec-try-or-recover
   [func recoverfn]
   (let [result (exec-try-on func)]
-    (with-monad exception-monad
+    (ctx/with-context exception-monad
       (if (failure? result)
         (recoverfn (.-e result))
         result))))


passing int ids

passing int ids

--- src/celestial/api/systems.clj
+++ src/celestial/api/systems.clj
@@ -118,14 +118,14 @@
         (if-not (s/system-exists? id)
           (conflict {:message "System does not exists, use POST /host/system first"})
           (wrap-errors
-            (s/update-system id system)
+            (s/update-system (Integer/valueOf id) system)
             (success {:message "system updated" :id id}))))

   (DELETE- "/systems/:id" [^:int id] {:nickname "deleteSystem" :summary "Delete System"
                                           :errorResponses (errors {:bad-req "System does not exist"})}
          (try+
              (let [spec (s/get-system! id) int-id (Integer/valueOf id)]
-               (s/delete-system! id)
+               (s/delete-system! int-id)
                (success {:message "System deleted"}))
              (catch [:type :celestial.persistency/missing-system] e
                (bad-req {:message "System does not exist"}))))


adding user

adding user

--- src/celestial/api/systems.clj
+++ src/celestial/api/systems.clj
@@ -27,12 +27,13 @@

 (defmodel system
   :env :string
+  :type :string
+  :user :string
   :machine {:type "Machine"}
   :aws {:type "Aws" :description "An EC2 based system"}
   :physical {:type "Physical" :description "A physical machine"}
   :proxmox {:type "Proxmox" :description "A Proxmox based system"}
-  :vcenter {:type "Vcenter" :description "A vCenter based system"}
-  :type :string)
+  :vcenter {:type "Vcenter" :description "A vCenter based system"})

 (defmodel machine
   :cpus {:type :int :description "Not relevant in ec2"}
@@ -86,8 +87,9 @@
   (GET- "/systems/type/:type" [^:string type] {:nickname "getSystemsByType" :summary "Get systems by type"}
         (success {:ids (s/get-system-index :type type)}))

-  (POST- "/systems" [& ^:system spec] {:nickname "addSystem" :summary "Add system"
-                                           :errorResponses (errors {:bad-req "Missing system type"})}
+  (POST- "/systems" [& ^:system spec]
+    {:nickname "addSystem" :summary "Add system"
+     :errorResponses (errors {:bad-req "Missing system type"})}
          (wrap-errors
            (p/with-quota (s/add-system spec) spec
              (success {:msg "new system saved" :id id}))))


separate enumeration from instrument and test

Signed-off-by: Stuart Halloway <4dc50fc3bc007be011b5445f3f79298b9eeb51b7@cognitect.com>
Signed-off-by: Rich Hickey <2f3b32171da334ad5d7d0db393d0928eef4308ab@gmail.com>

--- src/clj/clojure/spec/test.clj
+++ src/clj/clojure/spec/test.clj
@@ -17,7 +17,44 @@
 (in-ns 'clojure.spec.test)
 (alias 'stc 'clojure.spec.test.check)

+(defn- throwable?
+  [x]
+  (instance? Throwable x))
+
+(defn ->sym
+  [x]
+  (@#'s/->sym x))
+
+(defn- ->var
+  [s-or-v]
+  (if (var? s-or-v)
+    s-or-v
+    (let [v (and (symbol? s-or-v) (resolve s-or-v))]
+      (if (var? v)
+        v
+        (throw (IllegalArgumentException. (str (pr-str s-or-v) " does not name a var")))))))
+
+(defn- collectionize
+  [x]
+  (if (symbol? x)
+    (list x)
+    x))
+
+(defn enumerate-namespace
+  "Given a symbol naming an ns, or a collection of such symbols,
+returns the set of all symbols naming vars in those nses."
+  [ns-sym-or-syms]
+  (into
+   #{}
+   (mapcat (fn [ns-sym]
+             (map
+              (fn [name-sym]
+                (symbol (name ns-sym) (name name-sym)))
+              (keys (ns-interns ns-sym)))))
+   (collectionize ns-sym-or-syms)))
+
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; instrument ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
 (def ^:private ^:dynamic *instrument-enabled*
   "if false, instrumented fns call straight through"
   true)
@@ -54,7 +91,6 @@
            (.applyTo ^clojure.lang.IFn f args)))
        (.applyTo ^clojure.lang.IFn f args)))))

-
 (defn- no-fn-spec
   [v spec]
   (ex-info (str "Fn at " v " is not spec'ed.")
@@ -63,15 +99,6 @@
 (def ^:private instrumented-vars
      "Map for instrumented vars to :raw/:wrapped fns"
      (atom {}))
-
-(defn- ->var
-  [s-or-v]
-  (if (var? s-or-v)
-    s-or-v
-    (let [v (and (symbol? s-or-v) (resolve s-or-v))]
-      (if (var? v)
-        v
-        (throw (IllegalArgumentException. (str (pr-str s-or-v) " does not name a var")))))))

 (defn- instrument-choose-fn
   "Helper for instrument."
@@ -84,14 +111,6 @@
   "Helper for instrument"
   [spec sym {overrides :spec}]
   (get overrides sym spec))
-
-(defn- collectionize
-  [x]
-  (if (symbol? x)
-    (list x)
-    x))
-
-(def ->sym @#'s/->sym)

 (defn- instrument-1
   [s opts]
@@ -123,40 +142,39 @@
   [opts]
   (reduce into #{} [(:stub opts) (keys (:replace opts)) (keys (:spec opts))]))

-(defn- sym-matcher
-  "Returns a fn that matches symbols that are either in syms,
-or whose namespace is in syms."
-  [syms]
-  (let [names (into #{} (map str) syms)]
-    (fn [s]
-      (or (contains? names (namespace s))
-          (contains? names (str s))))))
-
-(defn- validate-opts
-  [opts]
-  (assert (every? ident? (keys (:gen opts))) "instrument :gen expects ident keys"))
+(defn- fn-spec-name?
+  [s]
+  (symbol? s))
+
+(defn instrumentable-syms
+  "Given an opts map as per instrument, returns the set of syms
+that can be instrumented."
+  ([] (instrumentable-syms nil))
+  ([opts]
+     (assert (every? ident? (keys (:gen opts))) "instrument :gen expects ident keys")
+     (reduce into #{} [(filter fn-spec-name? (keys (s/registry)))
+                       (keys (:spec opts))
+                       (:stub opts)
+                       (keys (:replace opts))])))

 (defn instrument
-  "Instruments the vars matched by ns-or-names, a symbol or a
-collection of symbols. Instruments the current namespace if
-ns-or-names not specified. Idempotent.
-
-A var matches ns-or-names if ns-or-names includes either the var's
-fully qualified name or the var's namespace.
+  "Instruments the vars named by sym-or-syms, a symbol or collection
+of symbols, or all instrumentable vars if sym-or-syms is not
+specified.

 If a var has an :args fn-spec, sets the var's root binding to a
 fn that checks arg conformance (throwing an exception on failure)
 before delegating to the original fn.

 The opts map can be used to override registered specs, and/or to
-replace fn implementations entirely. Opts for symbols not matched
-by ns-or-names are ignored. This facilitates sharing a common
+replace fn implementations entirely. Opts for symbols not included
+in sym-or-syms are ignored. This facilitates sharing a common
 options map across many different calls to instrument.

 The opts map may have the following keys:

   :spec     a map from var-name symbols to override specs
-  :stub     a collection of var-name symbols to be replaced by stubs
+  :stub     a set of var-name symbols to be replaced by stubs
   :gen      a map from spec names to generator overrides
   :replace  a map from var-name symbols to replacement fns

@@ -176,63 +194,33 @@
 :spec can be used in combination with :stub or :replace.

 Returns a collection of syms naming the vars instrumented."
-  ([] (instrument (.name ^clojure.lang.Namespace *ns*)))
-  ([ns-or-names] (instrument ns-or-names nil))
-  ([ns-or-names opts]
-     (validate-opts opts)
-     (let [match? (sym-matcher (collectionize ns-or-names))]
-       (locking instrumented-vars
-         (into
-          []
-          (comp cat
-                (filter symbol?)
-                (filter match?)
-                (distinct)
-                (map #(instrument-1 % opts))
-                (remove nil?))
-          [(keys (s/registry)) (opt-syms opts)])))))
-
-(defn unstrument
-  "Undoes instrument on the vars matched by ns-or-names, specified
-as in instrument. Returns a collection of syms naming the vars
-unstrumented."
-  ([] (unstrument (.name ^clojure.lang.Namespace *ns*)))
-  ([ns-or-names]
-     (let [match? (sym-matcher (collectionize ns-or-names))]
-       (locking instrumented-vars
-         (into
-          []
-          (comp (map ->sym)
-                 (filter match?)
-                 (map unstrument-1)
-                 (remove nil?))
-           (keys @instrumented-vars))))))
-
-(defn instrument-all
-  "Like instrument, but works on all vars."
-  ([] (instrument-all nil))
-  ([opts]
-     (validate-opts opts)
+  ([] (instrument (instrumentable-syms)))
+  ([sym-or-syms] (instrument sym-or-syms nil))
+  ([sym-or-syms opts]
      (locking instrumented-vars
        (into
         []
-        (comp cat
-              (filter symbol?)
+        (comp (filter (instrumentable-syms opts))
               (distinct)
               (map #(instrument-1 % opts))
               (remove nil?))
-        [(keys (s/registry)) (opt-syms opts)]))))
-
-(defn unstrument-all
-  "Like unstrument, but works on all vars."
-  []
-  (locking instrumented-vars
-    (into
-     []
-     (comp (map ->sym)
-           (map unstrument-1)
-           (remove nil?))
-     (keys @instrumented-vars))))
+        (collectionize sym-or-syms)))))
+
+(defn unstrument
+  "Undoes instrument on the vars named by sym-or-syms, specified
+as in instrument. With no args, unstruments all instrumented vars.
+Returns a collection of syms naming the vars unstrumented."
+  ([] (unstrument (map ->sym (keys @instrumented-vars))))
+  ([sym-or-syms]
+     (locking instrumented-vars
+       (into
+        []
+        (comp (filter symbol?)
+              (map unstrument-1)
+              (remove nil?))
+        (collectionize sym-or-syms)))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; testing  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

 (defn- explain-test
   [args spec v role]
@@ -260,10 +248,6 @@
               (explain-test args (:fn specs) {:args cargs :ret cret} :fn))
             true))))))

-(defn- throwable?
-  [x]
-  (instance? Throwable x))
-
 (defn- check-fn
   [f specs {gen :gen opts ::stc/opts}]
   (let [{:keys [num-tests] :or {num-tests 100}} opts
@@ -308,34 +292,19 @@
   [{:keys [s f v spec]} {:keys [result-callback] :as opts}]
   (when v (unstrument s))
   (try
-   (cond
-    (nil? f)
-    {:type :no-fn :sym s :spec spec}
+   (let [f (or f (when v @v))]
+     (cond
+      (nil? f)
+      {:type :no-fn :sym s :spec spec}

-    (:args spec)
-    (let [tcret (check-fn f spec opts)]
-      (make-test-result s spec tcret))
+      (:args spec)
+      (let [tcret (check-fn f spec opts)]
+        (make-test-result s spec tcret))

-    :default
-    {:type :no-argspec :sym s :spec spec})
+      :default
+      {:type :no-argspec :sym s :spec spec}))
    (finally
     (when v (instrument s)))))
-
-;; duped from spec to avoid introducing public API
-(defn- collectionize
-  [x]
-  (if (symbol? x)
-    (list x)
-    x))
-
-(defn- sym-matcher
-  "Returns a fn that matches symbols that are either in syms,
-or whose namespace is in syms."
-  [syms]
-  (let [names (into #{} (map str) syms)]
-    (fn [s]
-      (or (contains? names (namespace s))
-          (contains? names (str s))))))

 (defn- sym->test-map
   [s]
@@ -344,38 +313,31 @@
      :v v
      :spec (when v (s/get-spec v))}))

-(defn- validate-opts
+(defn- validate-test-opts
   [opts]
   (assert (every? ident? (keys (:gen opts))) "test :gen expects ident keys"))
-
-(defn syms-to-test
-  "Returns a coll of registered syms matching ns-or-names (a symbol or
-collection of symbols).
-
-A symbol matches ns-or-names if ns-or-names includes either the symbol
-itself or the symbol's namespace symbol.
-
-If no ns-or-names specified, returns all registered syms."
-  ([] (sequence
-       (filter symbol?)
-       (keys (s/registry))))
-  ([ns-or-names]
-     (let [match? (sym-matcher (collectionize ns-or-names))]
-       (sequence
-        (comp (filter symbol?)
-              (filter match?))
-        (keys (s/registry))))))

 (defn test-fn
   "Runs generative tests for fn f using spec and opts. See
 'test' for options and return."
   ([f spec] (test-fn f spec nil))
   ([f spec opts]
-     (validate-opts opts)
+     (validate-test-opts opts)
      (test-1 {:f f :spec spec} opts)))

+(defn testable-syms
+  "Given an opts map as per test, returns the set of syms that
+can be tested."
+  ([] (testable-syms nil))
+  ([opts]
+     (validate-test-opts opts)
+     (reduce into #{} [(filter fn-spec-name? (keys (s/registry)))
+                       (keys (:spec opts))])))
+
 (defn test
-  "Checks specs for vars named by syms using test.check.
+  "Run generative tests for spec conformance on vars named by
+sym-or-syms, a symbol or collection of symbols. If sym-or-syms
+is not specified, test all testable vars.

 The opts map includes the following optional keys, where stc
 aliases clojure.spec.test.check:
@@ -411,10 +373,15 @@
 :no-gen     unable to generate :args
 :no-fn      unable to resolve fn to test
 "
-  ([syms] (test syms nil))
-  ([syms opts]
-     (validate-opts opts)
-     (pmap #(test-1 (sym->test-map %) opts) syms)))
+  ([] (test (testable-syms)))
+  ([sym-or-syms] (test sym-or-syms nil))
+  ([sym-or-syms opts]
+     (->> (collectionize sym-or-syms)
+          (filter (testable-syms opts))
+          (pmap
+           #(test-1 (sym->test-map %) opts)))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; test reporting  ;;;;;;;;;;;;;;;;;;;;;;;;

 (defn abbrev-result
   "Given a test result, returns an abbreviated version
@@ -425,20 +392,21 @@
     (update (dissoc x ::stc/ret) :spec s/describe)))

 (defn summarize-results
-  "Given a collection of test-results, e.g. from 'test',
-pretty prints the abbrev-result of each.
+  "Given a collection of test-results, e.g. from 'test', pretty
+prints the summary-result (default abbrev-result) of each.

 Returns a map with :total, the total number of results, plus a
 key with a count for each different :type of result."
-  [test-results]
-  (reduce
-   (fn [summary result]
-     (pp/pprint (abbrev-result result))
-     (-> summary
-         (update :total inc)
-         (update (:type result) (fnil inc 0))))
-   {:total 0}
-   test-results))
-
-
-
+  ([test-results] (summarize-results test-results abbrev-result))
+  ([test-results summary-result]
+     (reduce
+      (fn [summary result]
+        (pp/pprint (summary-result result))
+        (-> summary
+            (update :total inc)
+            (update (:type result) (fnil inc 0))))
+      {:total 0}
+       test-results)))
+
+
+


Remove Tag/shuffle even if no Operation is found

--- src/clj/game/cards-assets.clj
+++ src/clj/game/cards-assets.clj
@@ -286,13 +286,17 @@
     :abilities [{:label "Remove a tag to search R&D for an operation"
                  :prompt "Choose an operation to put on top of R&D"
                  :cost [:click 1]
-                 :choices (req (filter #(has? % :type "Operation") (:deck corp)))
+                 :choices (req (let [ops (filter #(has? % :type "Operation") (:deck corp))]
+                                 (if (empty? ops) ["No Operation in R&D"] ops)))
                  :req (req (> (get-in @state [:runner :tag]) 0))
-                 :effect (req (let [c (move state :corp target :play-area)]
-                                (shuffle! state :corp :deck)
-                                (move state :corp c :deck {:front true})
-                                (lose state :runner :tag 1)
-                                (system-msg state side (str "uses Lily Lockwell to put " (:title c) " on top of R&D"))))}]}
+                 :effect (req (if (not= target "No Operation found")
+                                (let [c (move state :corp target :play-area)]
+                                  (shuffle! state :corp :deck)
+                                  (move state :corp c :deck {:front true})
+                                  (system-msg state side (str "uses Lily Lockwell to put " (:title c) " on top of R&D")))
+                                (do (shuffle! state :corp :deck)
+                                    (system-msg state side (str "uses Lily Lockwell, but did not find an Operation in R&D"))))
+                                (lose state :runner :tag 1))}]}

    "Mark Yale"
    {:events {:agenda-counter-spent {:effect (effect (gain :credit 1))


Fix to liveness (was doing analysis in reverse)

--- src/clj/minijava/liveness.clj
+++ src/clj/minijava/liveness.clj
@@ -13,7 +13,7 @@

 ;; assumes that uses and defs have been defined for each GAS instruction
 ;; given a list of GAS instructions, return a hashmap defining live-in
-(defn live [program]
+(defn live-loop [program]
 (let [succs (flow program)]
   (loop [instrs   program
          live-in  {}
@@ -44,3 +44,6 @@
                             (not (= out new-out-set)))]
         ;;determine if any changes were made during the course of the inner loop
         (recur (rest instrs) new-ins new-outs isChanged))))))
+
+(defn live [program]
+  (live-loop (reverse program)))


render budget item amounts

render budget item amounts

--- src/clj_money/web/budgets.clj
+++ src/clj_money/web/budgets.clj
@@ -1,7 +1,7 @@
 (ns clj-money.web.budgets
   (:refer-clojure :exclude [update])
   (:require [clojure.tools.logging :as log]
-            [clojure.pprint :refer [pprint]]
+            [clojure.pprint :refer [pprint cl-format]]
             [environ.core :refer [env]]
             [clj-time.core :as t]
             [clj-time.format :as tf]
@@ -116,7 +116,7 @@

 (defn- period-heading
   [budget index]
-  [:th (budget-period-start-date budget index)])
+  [:th.text-right (budget-period-start-date budget index)])

 (defn- budget-header-row
   [budget]
@@ -124,12 +124,19 @@
    (html
      [:th "Account"]
      (map #(period-heading budget %) (range 0 (:period-count budget)))
-     [:th "Total"])])
-
-(defn- budget-data-row
+     [:th.text-right "Total"])])
+
+(defn- budget-period-cell
+  [period]
+  [:td.text-right (format-number (:amount period))])
+
+(defn- budget-item-row
   [budget item]
   [:tr
-   [:td (:account-id item)]])
+   (html
+     [:td (:account-id item)]
+     (map budget-period-cell (:periods item))
+     [:td (format-number (reduce + 0 (map :amount (:periods item))))])])

 (defn show
   "Renders the budet details"
@@ -142,7 +149,7 @@
       [:table.table.table-striped
        (html
        (budget-header-row budget)
-       (map #(budget-data-row budget %) (:items budget)))]
+       (map #(budget-item-row budget %) (:items budget)))]
       [:a.btn.btn-primary {:href (format "/budgets/%s/items/new" (:id budget))} "Add"]
       " "
       [:a.btn.btn-default {:href (format "/entities/%s/budgets" (:entity-id budget))} "Back"]]])))


WIP render budget report

WIP render budget report

--- src/clj_money/web/reports.clj
+++ src/clj_money/web/reports.clj
@@ -10,6 +10,7 @@
                                     format-date
                                     parse-date]]
             [clj-money.web.shared :refer :all]
+            [clj-money.models.budgets :as budgets]
             [clj-money.models.reports :as reports]))

 (defmulti render-report
@@ -57,6 +58,23 @@
                                           entity-id
                                           as-of))])

+(defn- budget-report-row
+  [record]
+  [:tr
+   [:td (:caption record)]])
+
+(defmethod render-report :budget
+  [{:keys [entity-id budget-id as-of] :as params}]
+  [:table.table.table-striped
+   (let [budget (if budget-id
+                  (budgets/find-by-id (env :db) budget-id)
+                  (first (budgets/select-by-entity-id (env :db) entity-id))) ; TODO find the current budget
+         as-of (or as-of
+                   (budgets/end-date budget))] ; TODO this is returning an incorrect value
+     (map budget-report-row (reports/budget (env :db)
+                                            budget
+                                            as-of)))])
+
 (defmulti render-filter
   (fn [params]
     (:type params)))
@@ -86,6 +104,16 @@
                                      :value (format-date (:as-of params))}]]
    [:input.btn.btn-primary {:type :submit :value "Show"}]])

+(defmethod render-filter :budget
+  [params]
+  [:form {:action "#" :method :get}
+   [:div.form-group
+    [:label.control-label {:for :as-of} "As of"]
+    [:input.form-control.date-field {:type :text
+                                     :name :as-of
+                                     :value (format-date (:as-of params))}]]
+   [:input.btn.btn-primary {:type :submit :value "Show"}]])
+
 (defn render
   [params]
   (let [params (-> params
@@ -106,7 +134,10 @@
                       :url (format "/entities/%s/reports/income-statement" (:entity-id params))}
                      {:id :balance-sheet
                       :caption "Balance Sheet"
-                      :url (format "/entities/%s/reports/balance-sheet" (:entity-id params))}]
+                      :url (format "/entities/%s/reports/balance-sheet" (:entity-id params))}
+                     {:id :budget
+                      :caption "Budget"
+                      :url (format "/entities/%s/reports/budget" (:entity-id params))}]
                     (:type params))]]
       [:div.row
        [:div.col-md-4.col-md-offset-1


Fix truncated start text

Fix truncated start text

--- src/cljc/robinson/render.cljc
+++ src/cljc/robinson/render.cljc
@@ -204,6 +204,10 @@
                             content))]
       characters))))

+(defn markup->length
+  [s]
+  (count (markup->chars 0 0 s)))
+
 (defn put-string
   ([^robinson.aterminal.ATerminal screen x y string]
      (put-string screen x y string :white :black #{}))
@@ -281,7 +285,7 @@

 (defn center-markup [s width]
   (let [n-ws-left (int (/ (- width (markup-length s)) 2))
-        n-ws-right (int (+ 0.5 (/ (- width (markup-length s)) 2)))]
+        n-ws-right (int (+ 1.6 (/ (- width (markup-length s)) 2)))]
    (apply str (concat (repeat n-ws-left " ") s (repeat n-ws-right " ")))))

 (defn left-justify-markup [s width]
@@ -1000,16 +1004,17 @@

 (defn render-start-text [state]
   (let [screen     (state :screen)
-        start-text (sg/start-text state)]
-    (render-list screen 16 4 53 6
+        start-text (sg/start-text state)
+        width      (reduce max (map markup->length (clojure.string/split-lines start-text)))]
+    (render-list screen 16 4 width 6
       (concat
         [{:s "" :fg :black :bg :white :style #{}}]
         (map
           (fn [line] {:s line :fg :black :bg :white :style #{:center}})
           (remove empty? (clojure.string/split-lines start-text)))
         [{:s "" :fg :black :bg :white :style #{}}
-         {:s "     Press <color fg=\"highlight\">any key</color> to continue and <color fg=\"highlight\">?</color> to view help." :fg :black :bg :white :style #{}}]))
-    (render-rect-double-border screen 16 4 53 6 :black :white)))
+         {:s "  Press <color fg=\"highlight\">any key</color> to continue and <color fg=\"highlight\">?</color> to view help." :fg :black :bg :white :style #{}}]))
+    (render-rect-double-border screen 15 4 (inc width) 6 :black :white)))

 (defn render-dead-text [state]
   (let [screen         (state :screen)
@@ -1027,7 +1032,7 @@
                            (> thirst max-thirst) "not drinking enough water"
                            (<= will-to-live 0)   "just giving up on life"
                            :else                 "mysterious causes"))]
-    (render-list screen 16 4 53 6
+    (render-list screen 16 4 55 6
       (concat
         [{:s "" :fg :black :bg :white :style #{}}]
         (map


Make snake traps hidden by default

Make snake traps hidden by default

--- src/cljc/robinson/render.cljc
+++ src/cljc/robinson/render.cljc
@@ -1458,7 +1458,7 @@
                                                            :snakes-trigger
                                                                              (if (get cell :trap-found)
                                                                                ["^"]
-                                                                               ["_"])
+                                                                               ["·"])

                                                            (do (log/info (format "unknown type: %s %s" (str (get cell :type)) (str cell)))
                                                            ["?"])))))


added repository routes

added repository routes

--- src/cljc/swarmpit/routes.cljc
+++ src/cljc/swarmpit/routes.cljc
@@ -11,22 +11,18 @@
        "/login"         {:post :login}
        "/slt"           {:get :slt}
        "/password"      {:post :password}
-       "/distribution/" {"public"     {:get {"/repositories" :public-repositories
-                                             "/tags"         :public-repository-tags
-                                             "/ports"        :public-repository-ports}}
+       "/repository/"   {:get {"tags"  :repository-tags
+                               "ports" :repository-ports}}
+       "/distribution/" {"public"     {:get {"/repositories" :public-repositories}}
                          "dockerhub"  {""  {:get  :dockerhub-users
                                             :post :dockerhub-user-create}
                                        "/" {:get    {[:id "/repositories"] :dockerhub-repositories
-                                                     [:id "/tags"]         :dockerhub-repository-tags
-                                                     [:id "/ports"]        :dockerhub-repository-ports
                                                      [:id]                 :dockerhub-user}
                                             :delete {[:id] :dockerhub-user-delete}
                                             :post   {[:id] :dockerhub-user-update}}}
                          "registries" {""  {:get  :registries
                                             :post :registry-create}
                                        "/" {:get    {[:id "/repositories"] :registry-repositories
-                                                     [:id "/tags"]         :registry-repository-tags
-                                                     [:id "/ports"]        :registry-repository-ports
                                                      [:id]                 :registry}
                                             :delete {[:id] :registry-delete}
                                             :post   {[:id] :registry-update}}}}


Allow merging of `:source` nodes for map task input.

--- src/clojure/parkour/graph.clj
+++ src/clojure/parkour/graph.clj
@@ -9,10 +9,7 @@
             [parkour.io.mux :as mux]
             [parkour.util
              :refer [ignore-errors returning var-str mpartial mcomp]])
-  (:import [java.io Writer]
-           [java.util Map List]
-           [clojure.lang ArityException IFn APersistentMap APersistentVector]
-           [org.apache.hadoop.mapreduce Job]
+  (:import [org.apache.hadoop.mapreduce Job]
            [org.apache.hadoop.mapreduce.lib.partition HashPartitioner]))

 (comment
@@ -84,7 +81,11 @@

 (def ^:private stage
   "The stage of a job graph node."
-  (comp :stage pr/arg0))
+  (fn [node & args]
+    (cond
+     (vector? node) ::vector
+     (map? node) (:stage node)
+     :else (throw (ex-info "Invalid `node`" {:node node})))))

 (let [id (atom 0)]
   (defn ^:private gen-id
@@ -111,20 +112,25 @@

 (def remote nil)
 (defmulti remote
-  "Create a new remote-execution task chained following the provided
-job graph `node` and implemented by function `f`, which should accept
-and return reducible collections of task tuples.  When producing a
-`:map`-stage node, may provide a combiner function `g`, will replace
-any existing job combiner function."
+  "Create a new remote-execution task chained following the provided job graph
+`node` and implemented by function `f`, which should accept and return reducible
+collections of task tuples.  When producing a `:map`-stage node, may provide a
+combiner function `g`, which will replace any existing job combiner function."
   {:arglists '([node f] [node f g])}
   stage)

 (defmethod remote :default
-  [node f]
+  [node & fs]
   (let [stage (:stage node)
-        msg (str "Cannot change remote-execution task from node of stage `"
-                 stage "`.")]
-    (throw (ex-info msg {:node node, :f f}))))
+        msg (str "Cannot chain remote-execution from stage `" stage "`.")]
+    (throw (ex-info msg {:node node}))))
+
+(defmethod remote ::vector
+  [nodes & fs]
+  (if-not (every? (comp #{:source} stage) nodes)
+    (throw (ex-info "Cannot merge non-`:source` nodes." {:nodes nodes}))
+    (assoc (source (mapv :source nodes))
+      :requires (into [] (mapcat :requires nodes)))))

 (defmethod remote :source
   ([node f] (assoc node :stage :map, :mapper (f-list f)))
@@ -134,16 +140,19 @@
   ([node f] (assoc node :mapper (cons f (:mapper node))))
   ([node f g] (assoc (remote node f) :combiner (f-list g))))

-(def partition nil)
-(defmulti partition
-  "Create new reduce-partition task chained following the provided job
-graph `node` and optionally implemented by function `f`, which should
-follow the interface described in `parkour.mapreduce/partition!`.
-Configures shuffle via `classes`, which should either be a vector of
-the two map-output key & value classes, or a config step specifying
-the shuffle."
-  {:arglists '([node classes] [node classes f])}
-  (comp type pr/arg0))
+(def ^:private partition* nil)
+(defmulti ^:private partition*
+  {:arglists '([node classes f])}
+  stage)
+
+(defn partition
+  "Create new reduce-partition task chained following the provided job graph
+`node` and optionally implemented by function `f`, which should follow the
+interface described in `parkour.mapreduce/partition!`.  Configures shuffle via
+`step`, which should either be a vector of the two map-output key & value
+classes, or a config step specifying the shuffle."
+  ([node step] (partition node step HashPartitioner))
+  ([node step f] (partition* node step f)))

 (defn shuffle
   "Base shuffle configuration; sets map output key & value types to
@@ -159,25 +168,21 @@
        (= 2 (count classes))
        (every? class? classes)))

-(defmethod partition Map
-  ([node classes]
-     (partition node classes HashPartitioner))
-  ([node classes f]
-     (-> (assoc node :stage :partition, :partitioner f)
-         (config (if-not (shuffle-classes? classes)
-                   classes
-                   (apply shuffle classes))))))
-
-(defmethod partition List
-  ([nodes classes]
-     (partition nodes classes HashPartitioner))
-  ([nodes classes f]
-     (if (= 1 (count nodes))
-       (partition (first nodes) classes f)
-       (-> {:stage :map,
-            :subnodes (vec (map-indexed #(assoc %2 :snid %1) nodes)),
-            :mapper parkour.hadoop.Mux$Mapper}
-           (partition classes f)))))
+(defmethod partition* ::vector
+  [nodes classes f]
+  (if (= 1 (count nodes))
+    (partition (first nodes) classes f)
+    (-> {:stage :map,
+         :subnodes (vec (map-indexed #(assoc %2 :snid %1) nodes)),
+         :mapper parkour.hadoop.Mux$Mapper}
+        (partition classes f))))
+
+(defmethod partition* :map
+  [node classes f]
+  (-> (assoc node :stage :partition, :partitioner f)
+      (config (if-not (shuffle-classes? classes)
+                classes
+                (apply shuffle classes)))))

 (defmethod remote :partition
   [node f] (assoc node :stage :reduce, :reducer (f-list f)))


array vector type

array vector type

--- src/clojure2d/math/vector.clj
+++ src/clojure2d/math/vector.clj
@@ -81,8 +81,12 @@
    :magsq (fn [v] (reduce #(+ (double %1) (* (double %2) (double %2))) v))
    :mag #(m/sqrt (magsq %))
    :dot #(reduce clojure.core/+ (map clojure.core/* %1 %2))
-   :add #(mapv clojure.core/+ %1 %2)
-   :sub #(mapv clojure.core/- %1 %2)
+   :add (fn
+          ([v] v)
+          ([v1 v2] (mapv clojure.core/+ v1 v2)))
+   :sub (fn
+          ([v] (mapv clojure.core/- v))
+          ([v1 v2] (mapv clojure.core/- v1 v2)))
    :mult (fn [v1 v] (map #(clojure.core/* (double %) ^double v) v1))
    :emult #(mapv clojure.core/* %1 %2)
    :div #(mult %1 (/ (double %2)))
@@ -107,6 +111,68 @@
    :econstrain (fn [v val1 val2] (mapv #(m/constrain ^double %1 ^double val1 ^double val2)) v)
    :is-zero? #(every? clojure.core/zero? %)
    :is-near-zero? #(every? near-zero? %)})
+
+(defn- aevery?
+  "Array version of every"
+  [^doubles array pred]
+  (let [s (alength array)]
+    (loop [idx (unchecked-long 0)]
+      (if (< idx s)
+        (if (pred (aget array idx))
+          (recur (inc idx))
+          false)
+        true))))
+
+
+;; Array Vector
+(deftype ArrayVec [^doubles array]
+  Object
+  (toString [_] (str (vec array)))
+  (equals [_ v]
+    (let [s (alength ^doubles array)]
+      (bool-and (== s (alength ^doubles v))
+                (loop [idx (unchecked-long 0)]
+                  (if (< idx s)
+                    (if (== (aget array idx) ^double (v idx))
+                      (recur (inc idx))
+                      false)
+                    true)))))
+  IFn
+  (invoke [_ n]
+    (aget array ^long n))
+  Counted
+  (count [_] (alength array))
+  VectorProto
+  (to-vec [_] (vec array))
+  (applyf [_ f] (ArrayVec. (amap array idx ret ^double (f (aget array idx)))))
+  (magsq [_] (areduce array idx ret (double 0.0) (+ ret (m/sq (aget array idx)))))
+  (mag [v1] (m/sqrt (magsq v1)))
+  (dot [_ v2] (areduce array idx ret (double 0.0) (+ ret (* (aget array idx) ^double (v2 idx)))))
+  (add [v] v)
+  (add [_ v2] (ArrayVec. (amap array idx ret (+ (aget array idx) ^double (v2 idx)))))
+  (sub [_] (ArrayVec. (amap array idx ret (- (aget array idx)))))
+  (sub [v1 v2] (ArrayVec. (amap array idx ret (- (aget array idx) ^double (v2 idx)))))
+  (mult [_ v] (ArrayVec. (amap array idx ret (* (aget array idx) ^double v))))
+  (emult [_ v2] (ArrayVec. (amap array idx ret (* (aget array idx) ^double (v2 idx)))))
+  (div [_ v] (ArrayVec. (amap array idx ret (/ (aget array idx) ^double v))))
+  (abs [_] (ArrayVec. (amap array idx ret (m/abs (aget array idx)))))
+  (mx [_] (areduce array idx ret (Double/MIN_VALUE) (max ret (aget array idx))))
+  (mn [_] (areduce array idx ret (Double/MAX_VALUE) (min ret (aget array idx))))
+  (emx [_ v2] (ArrayVec. (amap array idx ret (max (aget array idx) ^double (v2 idx)))))
+  (emn [_ v2] (ArrayVec. (amap array idx ret (min (aget array idx) ^double (v2 idx)))))
+  (sum [_] (areduce array idx ret (double 0.0) (+ ret (aget array idx))))
+  (reciprocal [_] (ArrayVec. (amap array idx ret (/ (aget array idx)))))
+  (interpolate [v1 v2 t]
+    (interpolate v1 v2 t m/lerp))
+  (interpolate [_ v2 t f]
+    (ArrayVec. (amap array idx ret ^double (f (aget array idx) (v2 idx) t))))
+  (einterpolate [v1 v2 v]
+    (einterpolate v1 v2 v m/lerp))
+  (einterpolate [_ v2 v f]
+    (ArrayVec. (amap array idx ret ^double (f (aget array idx) (v2 idx) (v idx)))))
+  (econstrain [_ val1 val2] (ArrayVec. (amap array idx ret ^double (m/constrain ^double (aget array idx) ^double val1 ^double val2))))
+  (is-zero? [_] (aevery? array #(zero? ^double %)))
+  (is-near-zero? [_] (aevery? array near-zero?)))

 ;; Create Vec2 and add all necessary protocols
 (deftype Vec2 [^double x ^double y]
@@ -135,7 +201,7 @@
   (mag [_] (m/hypot x y))
   (dot [_ v2]
     (let [^Vec2 v2 v2] (+ (* x (.x v2)) (* y (.y v2)))))
-  (add [_] (Vec2. x y))
+  (add [v] v)
   (add [_ v2]
     (let [^Vec2 v2 v2] (Vec2. (+ x (.x v2)) (+ y (.y v2)))))
   (sub [_] (Vec2. (- x) (- y)))
@@ -228,7 +294,7 @@
   (mag [_] (m/hypot x y z))
   (dot [_ v2]
     (let [^Vec3 v2 v2] (+ (* x (.x v2)) (* y (.y v2)) (* z (.z v2)))))
-  (add [_] (Vec3. x y z))
+  (add [v] v)
   (add [_ v2]
     (let [^Vec3 v2 v2] (Vec3. (+ x (.x v2)) (+ y (.y v2)) (+ z (.z v2)))))
   (sub [_] (Vec3. (- x) (- y) (- z)))
@@ -398,7 +464,7 @@
   (mag [v1] (m/sqrt (magsq v1)))
   (dot [_ v2]
     (let [^Vec4 v2 v2] (+ (* x (.x v2)) (* y (.y v2)) (* z (.z v2)) (* w (.w v2)))))
-  (add [_] (Vec4. x y z w))
+  (add [v] v)
   (add [_ v2]
     (let [^Vec4 v2 v2] (Vec4. (+ x (.x v2)) (+ y (.y v2)) (+ z (.z v2)) (+ w (.w v2)))))
   (sub [_] (Vec4. (- x) (- y) (- z) (- w)))
@@ -608,3 +674,8 @@
 (defn vec2
   "Make Vec2 vector"
   [x y] (Vec2. x y))
+
+(defn array-vec
+  "Make ArrayVec type"
+  [lst]
+  (ArrayVec. (double-array lst)))


CMR-1122: Re-enabled db-sychronize-channel

--- bootstrap-app/src/cmr/bootstrap/system.clj
+++ bootstrap-app/src/cmr/bootstrap/system.clj
@@ -65,8 +65,7 @@
              :collection-index-channel (chan 100)

              ;; Channel for asynchronously sending database synchronization requests
-             ;; Uncomment the following line before enabling db synchronization job
-             ;:db-synchronize-channel (chan)
+             :db-synchronize-channel (chan)

              :catalog-rest-user (mdb-config/catalog-rest-db-username)
              :db (oracle/create-db (mdb-config/db-spec "bootstrap-pool"))


In init-empty-state-test, check cb arg

In init-empty-state-test, check cb arg

--- planck-cljs/test/planck/core_test.cljs
+++ planck-cljs/test/planck/core_test.cljs
@@ -78,12 +78,14 @@
     (is (= "a\nb\n" (spit-slurp test-file "a\nb\n")))))

 (deftest init-empty-state-test
-  (is (= {:ns 'cljs.user, :value '(2 3 4)}
-        (cljs.js/eval-str (cljs.js/empty-state planck.core/init-empty-state)
-          "(map inc [1 2 3])"
-          nil
-          {:eval cljs.js/js-eval}
-          identity))))
+  (cljs.js/eval-str (cljs.js/empty-state planck.core/init-empty-state)
+    "(map inc [1 2 3])"
+    nil
+    {:eval cljs.js/js-eval}
+    (fn [{:keys [ns value error]}]
+      (is (nil? error))
+      (is (= 'cljs.user ns))
+      (is (= '(2 3 4) value)))))

 (deftest slurp-url-test
   (is (string/includes? (planck.core/slurp "http://planck-repl.org") "Planck")))


Clapping Music is a canon.

Clapping Music is a canon.

--- src/kolmogorov_music/talk.clj
+++ src/kolmogorov_music/talk.clj
@@ -114,14 +114,14 @@
 (defn clapping-music []
   (let [african-bell-pattern (rhythm [1/8 1/8 1/4 1/8 1/4 1/4 1/8 1/4])]
     (->> african-bell-pattern forever (all :part :clap1)
-         (with (->> african-bell-pattern (times 8) (then (rhythm [1/8])) forever (all :part :clap2))))))
+         (canon #(->> % (take 64) (then (rhythm [1/8])) forever (all :part :clap2))))))

 (comment
   (live/play (clapping-music))
   )

 (fact "Clapping Music is minimal."
-  (definitionally description-length clapping-music) => 218
+  (definitionally description-length clapping-music) => 228
   (result-length (->> (clapping-music) (take-while #(-> % :time (< 216))))) => 99151)

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;


more streamlining.

more streamlining.

--- src/metabase/driver/sync.clj
+++ src/metabase/driver/sync.clj
@@ -20,8 +20,7 @@
                              [table :refer [Table]])
             [metabase.util :as u]))

-(declare auto-assign-field-special-type-by-name!
-         mark-category-field-or-update-field-values!
+(declare mark-category-field-or-update-field-values!
          mark-json-field!
          mark-no-preview-display-field!
          mark-url-field!
@@ -29,7 +28,6 @@
          sync-database-active-tables!
          sync-database-with-tracking!
          sync-field!
-         sync-metabase-metadata-table!
          sync-table-active-fields-and-pks!
          sync-table-fks!
          sync-table-fields-metadata!
@@ -56,7 +54,6 @@
                    :or {full-sync? true}}]
   (binding [qp/*disable-qp-logging* true]
     (driver/sync-in-context driver @(:db table) (fn []
-                                                  ;; TODO: create/update/fetch table
                                                   (sync-database-active-tables! driver [table] :analyze? full-sync?)
                                                   (events/publish-event :table-sync {:table_id (:id table)})))))

@@ -64,102 +61,49 @@
 ;;; ## ---------------------------------------- IMPLEMENTATION ----------------------------------------

-(defn- mark-inactive-tables!
-  "Mark any `Tables` that are no longer active as such. These are ones that exist in the DB but didn't come back from `active-tables`."
-  [database active-tables existing-table->id]
-  (doseq [[{table :name, schema :schema, :as table} table-id] existing-table->id]
-    (when-not (contains? (set (map :name active-tables)) table)
-      (upd Table table-id :active false)
-      (log/info (u/format-color 'cyan "Marked table %s.%s%s as inactive." (:name database) (if schema (str schema \.) "") table))
-
-      ;; We need to mark driver Table's Fields as inactive so we don't expose them in UI such as FK selector (etc.)
-      (k/update Field
-                (k/where {:table_id table-id})
-                (k/set-fields {:active false})))))
-
-(defn- create-new-tables!
-  "Create new `Tables` as needed. These are ones that came back from `active-tables` but don't already exist in the DB."
-  [database active-tables existing-table->id]
-  (let [active-tables   (set (for [table active-tables]
-                               (-> (select-keys table [:name :schema])
-                                   (update :schema identity)))) ; convert tables that come back like {:name ...} to {:name ..., :schema nil}
-        existing-tables (set (keys existing-table->id))
-        new-tables      (->> (set/difference active-tables existing-tables)
-                             ;; exclude _metabase_metadata table which is not a real table
-                             (filter #(not= "_metabase_metadata" (s/lower-case (:name %)))))]
-    (when (seq new-tables)
-      (log/debug (u/format-color 'blue "Found new tables: %s" (vec (for [{table :name, schema :schema} new-tables]
-                                                                     (if schema
-                                                                       (str schema \. table)
-                                                                       table)))))
-      (doseq [{table :name, schema :schema} new-tables]
-        (ins Table :db_id (:id database), :active true, :schema schema, :name table)))))
-
-(defn- sync-metabase-metadata-table!
-  "Databases may include a table named `_metabase_metadata` (case-insentive) which includes descriptions or other metadata about the `Tables` and `Fields`
-   it contains. This table is *not* synced normally, i.e. a Metabase `Table` is not created for it. Instead, *this* function is called, which reads the data it
-   contains and updates the relevant Metabase objects.
-
-   The table should have the following schema:
-
-     column  | type    | example
-     --------+---------+-------------------------------------------------
-     keypath | varchar | \"products.created_at.description\"
-     value   | varchar | \"The date the product was added to our catalog.\"
-
-   `keypath` is of the form `table-name.key` or `table-name.field-name.key`, where `key` is the name of some property of `Table` or `Field`.
-
-   This functionality is currently only used by the Sample Dataset. In order to use this functionality, drivers must implement optional fn `:table-rows-seq`."
-  [driver database active-tables]
-  (doseq [{table-name :name} active-tables]
-    (when (= (s/lower-case table-name) "_metabase_metadata")
-      (doseq [{:keys [keypath value]} (driver/table-rows-seq driver database table-name)]
-        (let [[_ table-name field-name k] (re-matches #"^([^.]+)\.(?:([^.]+)\.)?([^.]+)$" keypath)]
-          (try (when (not= 1 (if field-name
-                               (k/update Field
-                                         (k/where {:name field-name, :table_id (k/subselect Table
-                                                                                (k/fields :id)
-                                                                                (k/where {:db_id (:id database), :name table-name}))})
-                                         (k/set-fields {(keyword k) value}))
-                               (k/update Table
-                                         (k/where {:name table-name, :db_id (:id database)})
-                                         (k/set-fields {(keyword k) value}))))
-                 (log/error (u/format-color "Error syncing _metabase_metadata: no matching keypath: %s" keypath)))
-               (catch Throwable e
-                 (log/error (u/format-color 'red "Error in _metabase_metadata: %s" (.getMessage e))))))))))
-
-(defn- sync-database-with-tracking! [driver database full-sync?]
-  (let [start-time (System/currentTimeMillis)
-        tracking-hash (str (java.util.UUID/randomUUID))]
-    (log/info (u/format-color 'magenta "Syncing %s database '%s'..." (name driver) (:name database)))
-    (events/publish-event :database-sync-begin {:database_id (:id database) :custom_id tracking-hash})
-
-    (let [database-schema    (driver/describe-database driver database)
-          active-tables      (:tables database-schema)
-          existing-table->id (into {} (for [{:keys [name schema id]} (sel :many :fields [Table :name :schema :id], :db_id (:id database), :active true)]
-                                        {{:name name, :schema schema} id}))]
-      ;; do some quick validations that our tables list is sensible
-      (when-not (and (set? active-tables)
-                     (every? map? active-tables)
-                     (every? :name active-tables))
-        (throw (Exception. "Invalid results returned by active-tables. Results should be a set of maps like {:name \"table_name\", :schema \"schema_name_or_nil\"}.")))
-
-      ;; now persist the tables, creating new ones as needed and inactivating old ones
-      (mark-inactive-tables! database active-tables existing-table->id)
-      (create-new-tables!    database active-tables existing-table->id)
-
-      ;; once the tables are persisted then we can do a detailed sync for each table
-      (let [tables (for [table (sel :many Table, :db_id (:id database) :active true)]
-                     ;; replace default delays with ones that reuse database (and don't require a DB call)
-                     (assoc table :db (delay database)))]
-        (sync-database-active-tables! driver tables :analyze? full-sync?))
-
-      ;; lastly, if we have a _metabase_metadata table go ahead and handle it
-      (sync-metabase-metadata-table! driver database active-tables))
-
-    (events/publish-event :database-sync-end {:database_id (:id database) :custom_id tracking-hash :running_time (- (System/currentTimeMillis) start-time)})
-    (log/info (u/format-color 'magenta "Finished syncing %s database '%s'. (%d ms)" (name driver) (:name database)
-                              (- (System/currentTimeMillis) start-time)))))
+(defn- save-database-tables-list!
+  "Create new Fields (and mark old ones as inactive) for TABLE, and update PK fields."
+  [database table-defs]
+  (let [active-tables             (set (->> (for [table-def table-defs]
+                                              (-> (select-keys table-def [:name :schema])
+                                                  (update :schema identity)))                                 ; make sure :schema is defined on every table
+                                            (filter #(not= "_metabase_metadata" (s/lower-case (:name %))))))  ; exclude _metabase_metadata table which is not a real table
+        existing-table-def->table (into {} (for [{:keys [name schema] :as table} (sel :many :fields [Table :name :schema :id :display_name], :db_id (:id database), :active true)]
+                                              {{:name name, :schema schema} table}))]
+    ;; first mark inactive Tables
+    (doseq [[table-def {:keys [id]}] existing-table-def->table]
+      (when-not (contains? active-tables table-def)
+        (upd Table id :active false)
+        (log/info (u/format-color 'cyan "Marked table %s.%s%s as inactive." (:name database) (if (:schema table-def) (str (:schema table-def) \.) "") (:name table-def)))
+
+        ;; We need to mark the Table's Fields as inactive as well
+        (k/update Field
+                  (k/where {:table_id id})
+                  (k/set-fields {:active false}))))
+
+    ;; a little logging so we are better informed
+    (let [new-tables (set/difference active-tables (set (keys existing-table-def->table)))]
+      (when (seq new-tables)
+        (log/debug (u/format-color 'blue "Found new tables: %s" (vec (for [{table :name, schema :schema} new-tables]
+                                                                       (if schema (str schema \. table)
+                                                                                table)))))))
+
+    ;; Create new Tables, update existing ones if needed
+    (doseq [table-def active-tables]
+      (let [existing-table (existing-table-def->table table-def)
+            display-name   (common/name->human-readable-name (:name table-def))]
+        (if-not existing-table
+          ;; Table doesn't exist, so create it.
+          (ins Table
+            :db_id        (:id database)
+            :schema       (:schema table-def)
+            :name         (:name table-def)
+            :display_name display-name
+            :active       true)
+          ;; Otherwise update the Table if needed
+          (when (nil? (:display_name existing-table))
+            (upd Field (:id existing-table)
+              :display_name display-name)))))))

 (def ^:private sync-progress-meter-string
@@ -194,12 +138,10 @@

 (defn- sync-database-active-table!
+  "Sync the given table, optionally skipping the more time & resource intensive part of the process by specifying `:analyze? false`."
   [driver table & {:keys [analyze?]
                    :or {analyze? true}}]
   (let [table-def (driver/describe-table driver table)]
-    ;; make sure table has :display_name
-    (u/try-apply update-table-display-name! table)
-
     ;; create all the Fields / PKs
     (u/try-apply sync-table-active-fields-and-pks! table table-def)

@@ -214,44 +156,91 @@

 (defn- sync-database-active-tables!
-  "Sync active tables by running each of the sync table steps.
-   Note that we want to completely finish each step for *all* tables before starting the next, since they depend on the results of the previous step.
-   (e.g., `sync-table-fks!` can't run until all tables have finished `sync-table-active-fields-and-pks!`, since creating `ForeignKeys` to `Fields` of *other*
-   Tables can't take place before they exist."
+  "Perform sync operations for the given list of tables.  We do 2 passes over the listed tables, the first which does
+   the bulk of the work and establishes fields & metadata, and a second pass to fill in foreign keys if supported."
   [driver active-tables & {:keys [analyze?]
                            :or {analyze? true}}]
-  (let [active-tables (sort-by :name active-tables)]
-    ;; Do a first pass which does the bulk of the work
-    (let [tables-count          (count active-tables)
-          finished-tables-count (atom 0)]
-      (doseq [table active-tables]
-        (sync-database-active-table! driver table :analyze? analyze?)
-
-        (swap! finished-tables-count inc)
-        (log/debug (u/format-color 'magenta "%s Synced table '%s'." (sync-progress-meter-string @finished-tables-count tables-count) (:name table)))))
-
-    ;; Second pass to sync FKs, which must take place after all other table info is in place
-    (when (contains? (driver/features driver) :foreign-keys)
-      (doseq [table active-tables]
-        (u/try-apply sync-table-fks! driver table)))))
+  ;; Do a first pass which does the bulk of the work
+  (let [tables-count          (count active-tables)
+        finished-tables-count (atom 0)]
+    (doseq [table active-tables]
+      (sync-database-active-table! driver table :analyze? analyze?)
+
+      (swap! finished-tables-count inc)
+      (log/debug (u/format-color 'magenta "%s Synced table '%s'." (sync-progress-meter-string @finished-tables-count tables-count) (:name table)))))
+
+  ;; Second pass to sync FKs, which must take place after all other table info is in place
+  (when (contains? (driver/features driver) :foreign-keys)
+    (doseq [table active-tables]
+      (u/try-apply sync-table-fks! driver table))))
+
+
+(defn- sync-metabase-metadata-table!
+  "Databases may include a table named `_metabase_metadata` (case-insentive) which includes descriptions or other metadata about the `Tables` and `Fields`
+   it contains. This table is *not* synced normally, i.e. a Metabase `Table` is not created for it. Instead, *this* function is called, which reads the data it
+   contains and updates the relevant Metabase objects.
+
+   The table should have the following schema:
+
+     column  | type    | example
+     --------+---------+-------------------------------------------------
+     keypath | varchar | \"products.created_at.description\"
+     value   | varchar | \"The date the product was added to our catalog.\"
+
+   `keypath` is of the form `table-name.key` or `table-name.field-name.key`, where `key` is the name of some property of `Table` or `Field`.
+
+   This functionality is currently only used by the Sample Dataset. In order to use this functionality, drivers must implement optional fn `:table-rows-seq`."
+  [driver database _metabase_metadata]
+  (doseq [{:keys [keypath value]} (driver/table-rows-seq driver database (:name _metabase_metadata))]
+    (let [[_ table-name field-name k] (re-matches #"^([^.]+)\.(?:([^.]+)\.)?([^.]+)$" keypath)]
+      (try (when (not= 1 (if field-name
+                           (k/update Field
+                                     (k/where {:name field-name, :table_id (k/subselect Table
+                                                                                (k/fields :id)
+                                                                                (k/where {:db_id (:id database), :name table-name}))})
+                                     (k/set-fields {(keyword k) value}))
+                           (k/update Table
+                                     (k/where {:name table-name, :db_id (:id database)})
+                                     (k/set-fields {(keyword k) value}))))
+             (log/error (u/format-color "Error syncing _metabase_metadata: no matching keypath: %s" keypath)))
+           (catch Throwable e
+             (log/error (u/format-color 'red "Error in _metabase_metadata: %s" (.getMessage e))))))))
+
+
+(defn- sync-database-with-tracking! [driver database full-sync?]
+  (let [start-time (System/currentTimeMillis)
+        tracking-hash (str (java.util.UUID/randomUUID))]
+    (log/info (u/format-color 'magenta "Syncing %s database '%s'..." (name driver) (:name database)))
+    (events/publish-event :database-sync-begin {:database_id (:id database) :custom_id tracking-hash})
+
+    (let [database-schema (driver/describe-database driver database)]
+      ;; do some quick validations that our tables list is sensible
+      (when-not (and (set? (:tables database-schema))
+                     (every? map? (:tables database-schema))
+                     (every? :name (:tables database-schema)))
+        (throw (Exception. "Invalid results returned by describe-database. `:tables` should be a set of maps like {:name \"table_name\", :schema \"schema_name_or_nil\"}.")))
+
+      ;; now persist the list of tables, creating new ones as needed and inactivating old ones
+      (save-database-tables-list! database (:tables database-schema))
+
+      ;; once the tables are persisted then we can do a detailed sync for each table
+      (let [tables (for [table (sel :many Table, :db_id (:id database), :active true (k/order :name :ASC))]
+                     ;; replace default delays with ones that reuse database (and don't require a DB call)
+                     (assoc table :db (delay database)))]
+        (sync-database-active-tables! driver tables :analyze? full-sync?))
+
+      ;; lastly, if we have a _metabase_metadata table go ahead and handle it
+      (when-let [_metabase_metadata (first (filter #(= (s/lower-case (:name %)) "_metabase_metadata") (:tables database-schema)))]
+        (sync-metabase-metadata-table! driver database _metabase_metadata)))
+
+    (events/publish-event :database-sync-end {:database_id (:id database) :custom_id tracking-hash :running_time (- (System/currentTimeMillis) start-time)})
+    (log/info (u/format-color 'magenta "Finished syncing %s database '%s'. (%d ms)" (name driver) (:name database)
+                              (- (System/currentTimeMillis) start-time)))))

 ;; ## sync-table steps.

-;; ### 1) update-table-display-name!
-
-(defn- update-table-display-name!
-  "Update the display_name of TABLE if it doesn't exist."
-  [table]
-  {:pre [(integer? (:id table))]}
-  (try
-    (when (nil? (:display_name table))
-      (upd Table (:id table) :display_name (common/name->human-readable-name (:name table))))
-    (catch Throwable e
-      (log/error (u/format-color 'red "Unable to update display_name for %s: %s" (:name table) (.getMessage e))))))
-
-
-;; ### 2) sync-table-active-fields-and-pks!
+;; ### 1) sync-table-active-fields-and-pks!

 (def ^{:arglists '([field-def])}
 infer-field-special-type
@@ -380,7 +369,7 @@
         (insert-or-update-active-field! field-def (existing-field-name->field (:name field-def)) table)))))

-;; ### 3) update-table-row-count!  (full sync ONLY)
+;; ### 2) update-table-row-count!  (full sync ONLY)

 (defn- update-table-row-count!
   "Update the row count of TABLE if it has changed."
@@ -394,7 +383,7 @@
       (log/error (u/format-color 'red "Unable to update row_count for '%s': %s" (:name table) (.getMessage e))))))

-;; ### 4) sync-table-fields-metadata!  (full sync ONLY)
+;; ### 3) sync-table-fields-metadata!  (full sync ONLY)

 (defn- sync-table-fields-metadata!
   "Call `sync-field!` for every active Field for TABLE."
@@ -406,7 +395,7 @@
       (u/try-apply sync-field! driver (assoc field :table (delay table))))))

-;; ### 5) sync-table-fks!
+;; ### 4) sync-table-fks!

 (defn- determine-fk-type
   "Determine whether a FK is `:1t1`, or `:Mt1`.


Fixed missing argument to make-repl call

--- src/de/kotka/gorilla/repl.clj
+++ src/de/kotka/gorilla/repl.clj
@@ -110,7 +110,7 @@
                          (throw (Exception. (str "No Repl of that id: " id))))
                        (alter *repls* dissoc id)
                        the-repl))
-                   (make-repl))
+                   (make-repl -1))
         line     (if (= line 0)
                    (the-repl :line)
                    line)]


Add very limited lp-state subsumption.  Seems this is as good as we are going to get without implementing complex projection algorithms, unfortunately.

--- src/edu/berkeley/ai/angelic/hybrid/continuous_lp_states.clj
+++ src/edu/berkeley/ai/angelic/hybrid/continuous_lp_states.clj
@@ -178,6 +178,13 @@

+(defn lp-state-subsumes?
+  "Return true if a known to subsume b, false otherwise.  May return false even if
+   a does subsume b, since testing is currently of a very limited form."
+  [a b]
+  (and (= (get-state-var-map a) (get-state-var-map b))
+       (lp/lp-subsumes? (get-incremental-lp a) (get-incremental-lp b)
+                        (- (get-reward-const a)  (get-reward-const b)))))

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


CMR-315: Added date attribute search test.

--- test/cmr/system_int_test/search/granule_psa_search_test.clj
+++ test/cmr/system_int_test/search/granule_psa_search_test.clj
@@ -286,7 +286,68 @@
            ;; only max range provided
            "time,bravo," nil 12 [gran1 gran2]))))

-
-
-
-
+(defn make-date
+  "Creates a datetime from a number added onto a base datetime"
+  [n]
+  (when n
+    (f/unparse (f/formatters :date)
+               (t/plus (t/date-time 2012 1 1 0 0 0)
+                       (t/days n)))))
+
+(deftest date-psas-search-test
+  (let [psa1 (dc/psa "alpha" :date)
+        psa2 (dc/psa "bravo" :date)
+        psa3 (dc/psa "charlie" :date)
+        coll1 (d/ingest "PROV1" (dc/collection {:product-specific-attributes [psa1 psa2]}))
+        gran1 (d/ingest "PROV1" (dg/granule coll1 {:product-specific-attributes
+                                                   [(dg/psa "alpha"
+                                                            [(make-date 10) (make-date 23)])
+                                                    (dg/psa "bravo"
+                                                            [(make-date 0)])]}))
+        gran2 (d/ingest "PROV1" (dg/granule coll1 {:product-specific-attributes
+                                                   [(dg/psa "bravo"
+                                                            [(make-date 10) (make-date 23)])]}))
+
+        coll2 (d/ingest "PROV1" (dc/collection {:product-specific-attributes [psa1 psa2 psa3]}))
+        gran3 (d/ingest "PROV1" (dg/granule coll2 {:product-specific-attributes
+                                                   [(dg/psa "alpha"
+                                                            [(make-date 14)])
+                                                    (dg/psa "bravo"
+                                                            [(make-date 13) (make-date 23)])]}))
+        gran4 (d/ingest "PROV1" (dg/granule coll2 {:product-specific-attributes
+                                                   [(dg/psa "charlie"
+                                                            [(make-date 14)])]}))]
+    (index/flush-elastic-index)
+
+    (testing "search by value"
+      (are [v n items]
+           (d/refs-match?
+             items (search/find-refs :granule {"attribute[]" (str v (make-date n))}))
+           "date,bravo," 23 [gran2, gran3]
+           "date,alpha," 11 []
+           "date,bravo," 0 [gran1]))
+
+    (testing "search by range"
+      (are [v min-n max-n items]
+           (let [min-v (make-date min-n)
+                 max-v (make-date max-n)
+                 full-value (str v min-v "," max-v)]
+             (d/refs-match? items (search/find-refs :granule {"attribute[]" full-value})))
+
+           ;; inside range
+           "date,alpha," 9 11 [gran1]
+           ;; beginning edge of range
+           "date,alpha," 10 11 [gran1]
+           ;; ending edge of range
+           "date,alpha," 9 10 [gran1]
+
+           ;; only min range provided
+           "date,bravo," 20 nil [gran2 gran3]
+
+           ;; only max range provided
+           "date,bravo," nil 12 [gran1 gran2]))))
+
+
+
+
+


Unmask snippets.transform/rotate test for ClojureScript.

--- test/cljx/snippets/transform.cljx
+++ test/cljx/snippets/transform.cljx
@@ -45,7 +45,6 @@
   (q/reset-matrix)
   (q/rect 0 0 50 100))

-#+clj
 (defsnippet rotate {:renderer :p3d}
   (q/camera 200 200 200 0 0 0 0 0 -1)
   (q/no-fill)


lein: add pomegranate

lein: add pomegranate

--- lein_profiles.clj
+++ lein_profiles.clj
@@ -2,3 +2,6 @@
                   [lein-ring "0.8.10"]
                   [lein-ancient "0.5.4"]
                   ]}}
+{:dev {:dependencies
+       [[com.cemerick/pomegranate "0.2.0"]]
+       }}


remove validator from validation namespace

--- src/navigator/validation.clj
+++ src/navigator/validation.clj
@@ -13,15 +13,6 @@
                     (s/optional-key :final-score)       s/Str
                     (s/optional-key :score-denominator) s/Int
                     (s/optional-key :score-type)        s/Keyword}})
-
-(defn validator
-  [entity-type data]
-  (let [validation (entity-type validations)]
-    (try
-      (s/validate
-       validation
-       data)
-      (catch Exception e (.getMessage e)))))

 (comment


fix for the menu item on-select issue.

fix for the menu item on-select issue.

--- src/om_bootstrap/button.cljs
+++ src/om_bootstrap/button.cljs
@@ -127,27 +127,37 @@
     (s/optional-key :title) s/Str
     (s/optional-key :on-select) (sm/=> s/Any s/Any)}))

+(defcomponentk menu-item*
+  "Generates an Om component of a menu item. Done this way so that
+  wrapping dropdowns will have access to the Om state."
+  [owner]
+  (render
+   [_]
+   (let [{:keys [opts children]} (om/get-props owner)
+         [bs props] (t/separate MenuItem opts {:href "#"})
+         classes {:dropdown-header (:header? bs)
+                  :divider (:divider? bs)}
+         handle-click (fn [e]
+                        (when-let [on-select (:on-select bs)]
+                          (.preventDefault e)
+                          (on-select (:key bs))))
+         children (if (:header? bs)
+                    children
+                    (d/a {:on-click handle-click
+                          :href (:href bs)
+                          :title (:title bs)
+                          :tab-index "-1"}
+                         children))
+         li-attrs {:role "presentation"
+                   :key (:key bs)
+                   :class (d/class-set classes)}]
+     (d/li (u/merge-props props li-attrs)
+           children))))
+
 (sm/defn menu-item :- t/Component
   [opts :- MenuItem & children]
-  (let [[bs props] (t/separate MenuItem opts {:href "#"})
-        classes {:dropdown-header (:header? bs)
-                 :divider (:divider? bs)}
-        handle-click (fn [e]
-                       (when-let [on-select (:on-select bs)]
-                         (.preventDefault e)
-                         (on-select (:key bs))))
-        children (if (:header? bs)
-                   children
-                   (d/a {:on-click handle-click
-                         :href (:href bs)
-                         :title (:title bs)
-                         :tab-index "-1"}
-                        children))
-        li-attrs {:role "presentation"
-                  :key (:key bs)
-                  :class (d/class-set classes)}]
-    (d/li (u/merge-props props li-attrs)
-          children)))
+  (->menu-item* {:opts opts
+                 :children children}))

 (def DropdownMenu
   (t/bootstrap


improve docstring

improve docstring

--- src/overtone/sc/dyn_vars.clj
+++ src/overtone/sc/dyn_vars.clj
@@ -46,9 +46,10 @@
      ~@body))

 (defmacro without-node-blocking
-  "Stops the current thread from being blocked if the node you're
-  attempting to modify hasn't completed loading. This may result in the
-  message being ignored by the server."
+  "Stops the current thread from being blocked if you send a
+   modification message to a server node that hasn't completed
+   loading. This may result in messages sent within the body of this
+   macro being ignored by the server."
   [& body]
   `(binding [*block-node-until-ready?* false]
      ~@body))


unify calls to sportsapi

unify calls to sportsapi

--- src/paulkrake/datacenter.clj
+++ src/paulkrake/datacenter.clj
@@ -53,31 +53,6 @@
   (->> (clojure.string/split ergebnis #":")
        (map to-num)))

-(defn spieltag [saison spieltag-nr]
-  (as-> (season-by-competition saison) x
-        (get x "id")
-        (matches-by-season x spieltag-nr)
-        (get x "round")
-        (first x)
-        (get x "match")
-        (map (fn [m] (let [home     (get-in m ["home" "name"])
-                          away     (get-in m ["away" "name"])
-                          finished (= "yes" (get m "finished"))
-                          hg       (if finished (as-> m y
-                                                      (get y "match_result")
-                                                      (filter #(and (= "home" (get % "place"))
-                                                                    (= "0" (get % "match_result_at"))) y)
-                                                      (map #(get % "match_result") y)
-                                                      (first y)))
-                          ag       (if finished (as-> m y
-                                                      (get y "match_result")
-                                                      (filter #(and (= "away" (get % "place"))
-                                                                    (= "0" (get % "match_result_at"))) y)
-                                                      (map #(get % "match_result") y)
-                                                      (first y)))]
-                      (vector home away hg ag)))
-             x)))
-
 (defn map-inverse [m]
   (as-> m x
         (map (fn [[k v]] [v k]) x)
@@ -95,18 +70,24 @@
                           home-id  (get-in m ["home" "id"])
                           away-id  (get-in m ["away" "id"])
                           match-id (get m "id")
-                          hg       (-> (team-stats-by-match match-id home-id)
-                                       (get kategorie))
-                          ag       (-> (team-stats-by-match match-id away-id)
-                                       (get kategorie))]
+                          hg       (as-> (team-stats-by-match match-id home-id) y
+                                     (get y kategorie)
+                                     (Double/valueOf y))
+                          ag       (as-> (team-stats-by-match match-id away-id) y
+                                     (get y kategorie)
+                                     (Double/valueOf y))]
                       (vector home away hg ag)))
              x)))

-(defn shots-on-goal [saison spieltag]
-  (data saison spieltag "shots"))
+(defn spieltag [saison spieltag-nr]
+  (data saison spieltag-nr "score"))

-(defn tore [saison spieltag]
-  (data saison spieltag "tore"))
+(defn score [saison spieltag-nr]
+  (data saison spieltag-nr "score"))

-(defn gegentore [saison spieltag]
-  (data saison spieltag "gegentore"))
+(defn shots-on-goal [saison spieltag-nr]
+  (data saison spieltag-nr "shots"))
+
+(defn passes-complete-percentage [saison spieltag-nr]
+  (data saison spieltag-nr "passes_complete_percentage"))
+


Add type hint for proxy-handler

Add type hint for proxy-handler

Fixes possible issues with GraalVM native-image.

--- ring-jetty-adapter/src/ring/adapter/jetty.clj
+++ ring-jetty-adapter/src/ring/adapter/jetty.clj
@@ -21,7 +21,7 @@

 (defn- ^AbstractHandler proxy-handler [handler]
   (proxy [AbstractHandler] []
-    (handle [_ ^Request base-request request response]
+    (handle [_ ^Request base-request ^HttpServletRequest request response]
       (when-not (= (.getDispatcherType request) DispatcherType/ERROR)
         (let [request-map  (servlet/build-request-map request)
               response-map (handler request-map)]


add 'target' to Field returned by 'sel' post-select macro.  'target' refers to the Field an 'fk' type points to.

--- src/metabase/models/field.clj
+++ src/metabase/models/field.clj
@@ -2,7 +2,8 @@
   (:require [korma.core :refer :all]
             [metabase.api.common :refer [check]]
             [metabase.db :refer :all]
-            (metabase.models [database :refer [Database]])
+            (metabase.models [database :refer [Database]]
+                             [foreign-key :refer [ForeignKey]])
             [metabase.util :as util]))

 (def special-types
@@ -73,10 +74,13 @@
 (defentity Field
   (table :metabase_field))

-(defmethod post-select Field [_ {:keys [table_id] :as field}]
+(defmethod post-select Field [_ {:keys [id special_type table_id] :as field}]
   (util/assoc* field
                :table     (delay (sel :one 'metabase.models.table/Table :id table_id))
                :db        (delay @(:db @(:table <>)))
+               :target    (delay (when (= "fk" special_type)
+                                   (let [dest-id (:destination_id (sel :one :fields [ForeignKey :destination_id] :origin_id id))]
+                                     (sel :one Field :id dest-id))))
                :can_read  (delay @(:can_read @(:table <>)))
                :can_write (delay @(:can_write @(:table <>)))))