Fix leave-cluster-test after PR#194

Fix leave-cluster-test after PR#194

--- test/onyx/log/leave_cluster_test.clj
+++ test/onyx/log/leave_cluster_test.clj
@@ -1,6 +1,7 @@
 (ns onyx.log.leave-cluster-test
   (:require [onyx.extensions :as extensions]
             [onyx.log.entry :refer [create-log-entry]]
+            [onyx.messaging.dummy-messenger :refer [dummy-messenger]]
             [onyx.system]
             [midje.sweet :refer :all]))

@@ -9,6 +10,7 @@
       rep-diff (partial extensions/replica-diff entry)
       rep-reactions (partial extensions/reactions entry)
       old-replica {:pairs {:a :b :b :c :c :a} :peers [:a :b :c]
+                   :messaging {:onyx.messaging/impl :dummy-messenger}
                    :job-scheduler :onyx.job-scheduler/greedy}
       new-replica (f old-replica)
       diff (rep-diff old-replica new-replica)]
@@ -23,6 +25,7 @@
       rep-diff (partial extensions/replica-diff entry)
       rep-reactions (partial extensions/reactions entry)
       old-replica {:pairs {:a :b :b :a} :peers [:a :b]
+                   :messaging {:onyx.messaging/impl :dummy-messenger}
                    :job-scheduler :onyx.job-scheduler/greedy}
       new-replica (f old-replica)
       diff (rep-diff old-replica new-replica)]
@@ -43,7 +46,8 @@
                                      :j2 :onyx.task-scheduler/balanced}
                    :tasks {:j1 [:t1] :j2 [:t2]}
                    :allocations {:j1 {:t1 [:a :b]}
-                                 :j2 {:t2 [:c :d]}}}
+                                 :j2 {:t2 [:c :d]}}
+                   :messaging {:onyx.messaging/impl :dummy-messenger}}
       new-replica (f old-replica)
       diff (rep-diff old-replica new-replica)]
   (fact (:allocations (f old-replica)) => {:j1 {:t1 [:a :b]} :j2 {:t2 [:c]}})
@@ -56,6 +60,7 @@
       rep-diff (partial extensions/replica-diff entry)
       rep-reactions (partial extensions/reactions entry)
       old-replica {:job-scheduler :onyx.job-scheduler/balanced
+                   :messaging {:onyx.messaging/impl :dummy-messenger}
                    :pairs {:a :b :b :c :c :a}
                    :peers [:a :b :c]
                    :jobs [:j1 :j2]


Next version of http-kit-events

Next version of http-kit-events

--- modules/http-kit-events/project.clj
+++ modules/http-kit-events/project.clj
@@ -1,9 +1,9 @@
 ;; Copyright © 2014 JUXT LTD.

-(defproject juxt.modular/http-kit-events "0.5.1"
+(defproject juxt.modular/http-kit-events "0.5.2-SNAPSHOT"
   :description "A modular extension that provides support for events over http-kit channels"
   :url "https://github.com/juxt/modular/tree/master/modules/http-kit-events"
   :license {:name "The MIT License"
             :url "http://opensource.org/licenses/MIT"}
-  :dependencies [[juxt.modular/http-kit "0.5.0"]
+  :dependencies [[juxt.modular/http-kit "0.5.1"]
                  ])


Sort before creating HTML files

Sort before creating HTML files

--- doclet/src/clojure/play_clj_doclet/html.clj
+++ doclet/src/clojure/play_clj_doclet/html.clj
@@ -105,6 +105,7 @@
             (create-embed-file (content group)))))
   (spit (io/file dir "index.edn")
         (->> parsed-files
+             sort
              (map (fn [[ns groups]]
                     (for [{:keys [name]} groups]
                       {:ns ns


Improve examples.

Improve examples.

--- src/african_polyphony_and_polyrhythm/talk.clj
+++ src/african_polyphony_and_polyrhythm/talk.clj
@@ -137,8 +137,7 @@
 ;;;;;;;;;;;;;;;;;;

 ; Natural numbers
-(comment
-  (range 0 8))
+(def natural-numbers (range 0 8))

 ; Raw frequencies
 (comment
@@ -146,7 +145,7 @@
        live/play)

   ; Inaudible
-  (->> (phrase (repeat 1/4) [0 1 2 3 4 5 6 7])
+  (->> (phrase (repeat 1/4) natural-numbers)
        live/play))

 ; Midi
@@ -156,7 +155,7 @@
        live/play)

   ; Inaudible
-  (->> (phrase (repeat 1/4) [0 1 2 3 4 5 6 7])
+  (->> (phrase (repeat 1/4) natural-numbers)
        (where :pitch midi->hz)
        live/play))

@@ -167,15 +166,12 @@
 (def central-african-scale (comp high pentatonic -))

 (comment
-  (major 0)
-  (major 2)
-  (minor 2)
-
-  (central-african-scale 0)
-  (central-african-scale 2)
+  (map major natural-numbers)
+  (map minor natural-numbers)
+  (map central-african-scale natural-numbers)

   ; Inaudible
-  (->> (phrase (repeat 1/4) [0 1 2 3 4 5 6 7])
+  (->> (phrase (repeat 1/4) natural-numbers)
        (where :pitch (comp midi->hz major))
        live/play))

@@ -185,11 +181,15 @@
 (def C #(+ 72 %))

 (comment
-  (->> (phrase (repeat 1/4) (range 0 8))
+  (map (comp A major) natural-numbers)
+  (map (comp A minor) natural-numbers)
+  (map (comp A central-african-scale) natural-numbers)
+
+  (->> (phrase (repeat 1/4) natural-numbers)
        (where :pitch (comp midi->hz A major))
        live/play)

-  (->> (phrase (repeat 1/4) (range 0 8))
+  (->> (phrase (repeat 1/4) natural-numbers)
        (where :pitch (comp midi->hz A central-african-scale))
        live/play))


Switch delete to default delete from hayt

--- src/clojure/clojurewerkz/cassaforte/query.clj
+++ src/clojure/clojurewerkz/cassaforte/query.clj
@@ -33,17 +33,7 @@
   (into {:update table
          :set-columns set-columns} clauses))

-(defn delete-query
-  "http://cassandra.apache.org/doc/cql3/CQL.html#deleteStmt
-
-Takes a table identifier and additional clause arguments:
-
-* columns (defaults to *)
-* using
-* where
-* table (optionaly using composition)"
-  [table & clauses]
-  (into {:delete table} clauses))
+(def delete-query verb/delete)

 (def truncate-query verb/truncate)
 (def drop-keyspace-query verb/drop-keyspace)


Updated heading comment.

Updated heading comment.


More refactorings and simplifications

More refactorings and simplifications

--- src/com/wsscode/pathom/connect/run_graph.cljc
+++ src/com/wsscode/pathom/connect/run_graph.cljc
@@ -287,35 +287,33 @@
         run-next
         (assoc ::run-next run-next)))))

-(defn extend-resolver-run-next
-  "Extend resolver run next, adding the current run-next from env to it. If the sym
-  nodes don't have a run-next, it will be set for the one informed by the env. In case
+(defn extend-node-run-next
+  "Extend node run next, adding the current run-next from env to it. If the node don't
+  have a run-next, it will be set for the one informed by the env. In case
   there is already something to run next the node, a wrap AND branch node will be
   inserted containing the previous node and the new one."
-  [{::keys [index-syms] :as out}
-   {::keys [run-next run-next-trail] :as env}]
-  (if run-next
-    (if-let [node-ids (seq (get index-syms (pc-sym env)))]
-      (reduce
-        (fn [out node-id]
-          (if (contains? run-next-trail node-id)
-            out
-            (let [node      (get-in out [::nodes node-id])
-                  new-out   (compute-root-and (assoc out ::root (::run-next node)) env {::node-id run-next})
-                  next-node (or (get-in new-out [::nodes run-next])
-                                (get-in out [::nodes run-next]))]
-              (-> out
-                  (assoc ::nodes (::nodes new-out))
-                  (assoc ::index-syms (::index-syms new-out))
-                  (assoc-in [::nodes node-id ::run-next] (::root new-out))
-                  (assoc-in [::nodes (::root new-out) ::after-node] node-id)
-                  (merge-node-provides node-id next-node)
-                  (propagate-provides node)
-                  (update ::extended-nodes p.misc/sconj node-id)))))
-        out
-        node-ids)
-      out)
-    out))
+  [out
+   {::keys [run-next run-next-trail] :as env}
+   node-id]
+  (if (or (not run-next)
+          (contains? run-next-trail node-id))
+    out
+    (let [node      (get-in out [::nodes node-id])
+          new-out   (compute-root-and
+                      (assoc out ::root (::run-next node))
+                      env
+                      {::node-id run-next})
+          next-node (or (get-in new-out [::nodes run-next])
+                        (get-in out [::nodes run-next]))]
+      (-> out
+          (assoc
+            ::nodes (::nodes new-out)
+            ::index-syms (::index-syms new-out))
+          (assoc-in [::nodes node-id ::run-next] (::root new-out))
+          (assoc-in [::nodes (::root new-out) ::after-node] node-id)
+          (merge-node-provides node-id next-node)
+          (propagate-provides node)
+          (update ::extended-nodes p.misc/sconj node-id)))))

 (defn include-node [out {::keys [node-id] :as node}]
   (let [sym (pc-sym node)]
@@ -401,9 +399,28 @@
          (not (dynamic-resolver? env resolver))
          (first (get index-syms resolver)))))

-(defn resolver-input-paths
+(defn compute-resolver-graph
+  [{::keys [unreachable-syms] :as out}
+   {::keys [run-next]
+    :as    env}
+   resolver]
+  (if (contains? unreachable-syms resolver)
+    out
+    (let [env (assoc env pc-sym resolver)]
+      (if-let [sym-node-id (get-resolver-extension-node-id out env)]
+        (-> (extend-node-run-next out env sym-node-id)
+            (update-in [::nodes sym-node-id ::requires] merge-io {(pc-attr env) {}})
+            (update-in [::nodes sym-node-id ::provides] merge-io {(pc-attr env) {}}))
+        (let [node (create-resolver-node out env)]
+          (-> out
+              (include-node node)
+              (cond-> (and run-next (not= run-next (::node-id node)))
+                      (assoc-in [::nodes run-next ::after-node] (::node-id node)))
+              (compute-root-or env node)))))))
+
+(defn compute-input-resolvers-graph
   [out
-   {::keys [available-data run-next]
+   {::keys [available-data]
     :as    env}
    inputs resolvers]
   (let [missing (into #{} (remove #(contains? available-data %)) inputs)
@@ -414,20 +431,7 @@
         (dissoc out ::root)
         ; resolvers loop
         (reduce
-          (fn [{::keys [unreachable-syms] :as out} resolver]
-            (if (contains? unreachable-syms resolver)
-              out
-              (let [env (assoc env pc-sym resolver)]
-                (if-let [sym-node-id (get-resolver-extension-node-id out env)]
-                  (-> (extend-resolver-run-next out env)
-                      (update-in [::nodes sym-node-id ::requires] merge-io {(pc-attr env) {}})
-                      (update-in [::nodes sym-node-id ::provides] merge-io {(pc-attr env) {}}))
-                  (let [node (create-resolver-node out env)]
-                    (-> out
-                        (include-node node)
-                        (cond-> (and run-next (not= run-next (::node-id node)))
-                                (assoc-in [::nodes run-next ::after-node] (::node-id node)))
-                        (compute-root-or env node)))))))
+          (fn [out resolver] (compute-resolver-graph out env resolver))
           <>
           resolvers)

@@ -456,7 +460,7 @@
                   (remove #(contains? entity (:key %)))
                   children))))))

-(defn compute-attribute-graph-item
+(defn compute-attribute-graph*
   [{::keys [root] :as out}
    {:com.wsscode.pathom.connect/keys [index-oir attribute]
     :as                              env}]
@@ -467,7 +471,7 @@
             (dissoc <> ::root)
             (reduce-kv
               (fn [out inputs resolvers]
-                (resolver-input-paths out env inputs resolvers))
+                (compute-input-resolvers-graph out env inputs resolvers))
               <>
               (get index-oir attribute)))]
       (if (::root new-out)
@@ -488,7 +492,7 @@
       out

       (contains? index-oir attr)
-      (compute-attribute-graph-item out env)
+      (compute-attribute-graph* out env)

       :else
       (add-unreachable-attr out attr))))


[#233] Return Form version

[#233] Return Form version

--- api/src/clojure/org/akvo/flow_api/datastore/survey.clj
+++ api/src/clojure/org/akvo/flow_api/datastore/survey.clj
@@ -75,6 +75,7 @@
           :question-groups (mapv (fn [question-group]
                                    (question-group-definition question-group))
                                  (.values (.getQuestionGroupMap form)))
+          :version (.getVersion form)
           :created-at (ds/created-at form)
           :modified-at (ds/modified-at form)}
        include-survey-id? (assoc :survey-id (str (.getSurveyGroupId form)))))))


CMR-3663 Fixes syntax error

CMR-3663 Fixes syntax error

--- access-control-app/src/cmr/access_control/data/access_control_index.clj
+++ access-control-app/src/cmr/access_control/data/access_control_index.clj
@@ -325,7 +325,7 @@
         provider-id (acls/acl->provider-id acl)
         target (:target (or (:system-identity acl)
                             (:provider-identity acl)
-                            (:single-instance-identity acl)))]
+                            (:single-instance-identity acl)))
         ;;Currently only group ids are supported when searching by target-id
         target-id (when (= "GROUP_MANAGEMENT"
                            (get-in acl [:single-instance-identity :target]))


SetActionOnFailure should be called for the StepConfig object

--- src/main/clj/com/climate/services/aws/emr.clj
+++ src/main/clj/com/climate/services/aws/emr.clj
@@ -231,16 +231,15 @@
   action-on-failure is a String or enum com.amazonaws.services.elasticmapreduce.model.ActionOnFailure.
   properties is a map of Java properties that are set when the step runs."
   (let [sc (StepConfig. name
-             (doto
-               (HadoopJarStepConfig.)
-               (.setJar jar-path)
-               (.setMainClass main-class)
-               (.setArgs (vec cli-args)) ;collection of strings
-               (.setProperties (kv-props properties))
-               (.setActionOnFailure (str (or action-on-failure
-                                             (and alive? ActionOnFailure/CANCEL_AND_WAIT)
-                                             ActionOnFailure/TERMINATE_JOB_FLOW)))))]
-    sc))
+                        (doto
+                          (HadoopJarStepConfig.)
+                          (.setJar jar-path)
+                          (.setMainClass main-class)
+                          (.setArgs (vec cli-args)) ;collection of strings
+                          (.setProperties (kv-props properties))))]
+    (.setActionOnFailure sc (str (or action-on-failure
+                                  (and alive? ActionOnFailure/CANCEL_AND_WAIT)
+                                  ActionOnFailure/TERMINATE_JOB_FLOW)))))

 (defn add-steps
   "Add a step to a running jobflow. Steps is a seq of StepConfig objects.


Component to add Datomic functions

Component to add Datomic functions

--- modules/datomic/src/modular/datomic.clj
+++ modules/datomic/src/modular/datomic.clj
@@ -62,14 +62,13 @@
 (defrecord DatomicSchema [res]
   component/Lifecycle
   (start [this]
-    (let [conn (get-in this [:connection])]
-      (with-open [rdr (java.io.PushbackReader. (io/reader res))]
-        @(d/transact conn
-                     (binding [clojure.tools.reader/*data-readers*
-                               {'db/id datomic.db/id-literal
-                                'db/fn datomic.function/construct
-                                'base64 datomic.codec/base-64-literal}]
-                       (clojure.tools.reader/read (indexing-push-back-reader rdr))))))
+    (with-open [rdr (java.io.PushbackReader. (io/reader res))]
+      @(d/transact (:connection this)
+                   (binding [clojure.tools.reader/*data-readers*
+                             {'db/id datomic.db/id-literal
+                              'db/fn datomic.function/construct
+                              'base64 datomic.codec/base-64-literal}]
+                     (clojure.tools.reader/read (indexing-push-back-reader rdr)))))
     this)
   (stop [this] this))

@@ -77,3 +76,24 @@
   (component/using
    (->DatomicSchema res)
    [:connection]))
+
+
+(defn create-functions [functions]
+  (vec
+   (for [[ident {:keys [doc params path]}] functions]
+     {:db/id (d/tempid :db.part/user)
+      :db/ident ident
+      :db/doc doc
+      :db/fn (d/function {:lang "clojure" :params params :code (slurp (io/resource path))})})))
+
+(defrecord DatomicFunctions [functions]
+  component/Lifecycle
+  (start [this]
+    @(d/transact (:connection this) (create-functions functions))
+    this)
+  (stop [this] this))
+
+(defn new-datomic-functions [functions]
+  (component/using
+   (->DatomicFunctions functions)
+   [:connection]))


[#1381] Fix line bug when using same x and y columns

--- backend/src/akvo/lumen/lib/aggregation/line.clj
+++ backend/src/akvo/lumen/lib/aggregation/line.clj
@@ -23,7 +23,7 @@
         max-points 2500
         aggregation-method (if (= (get query "metricAggregation") "mean") "avg" (get query "metricAggregation"))
         sql-text-with-aggregation "SELECT * FROM (SELECT * FROM (SELECT %1$s, %5$s(%2$s) FROM %3$s WHERE %4$s GROUP BY %1$s)z ORDER BY random() LIMIT %6$s)zz ORDER BY zz.%1$s"
-        sql-text-without-aggreagtion "SELECT * FROM (SELECT * FROM (SELECT %1$s, %2$s FROM %3$s WHERE %4$s)z ORDER BY random() LIMIT %6$s)zz ORDER BY zz.%1$s"
+        sql-text-without-aggreagtion "SELECT * FROM (SELECT * FROM (SELECT %1$s AS x, %2$s AS y FROM %3$s WHERE %4$s)z ORDER BY random() LIMIT %6$s)zz ORDER BY zz.x"
         sql-text (if aggregation-method sql-text-with-aggregation sql-text-without-aggreagtion)
         sql-response (run-query tenant-conn table-name sql-text column-x-name column-y-name filter-sql aggregation-method max-points)]
     (lib/ok


:sparkles: Removed some logs

:sparkles: Removed some logs

--- frontend/src/uxbox/main/ui/workspace/sidebar/options/frame_layouts.cljs
+++ frontend/src/uxbox/main/ui/workspace/sidebar/options/frame_layouts.cljs
@@ -32,7 +32,6 @@
       children]]))

 (mf/defc layout-options [{:keys [layout default-layout-params on-change on-remove]}]
-  (prn "(render) layout" layout)
   (let [state (mf/use-state {:show-advanced-options false
                              :changes {}})
         {:keys [type display params] :as layout} (d/deep-merge layout (:changes @state))
@@ -45,7 +44,6 @@

         emit-changes! (fn [update-fn]
                         (swap! state update :changes update-fn)
-                        (prn "(event) layout" (d/deep-merge layout (-> @state :changes update-fn)))
                         (when on-change (on-change (d/deep-merge layout (-> @state :changes update-fn)))))

         handle-toggle-visibility (fn [event]


simplify3d.clj: removed some debug code

simplify3d.clj: removed some debug code

--- clojure/org/gavrog/clojure/simplify3d.clj
+++ clojure/org/gavrog/clojure/simplify3d.clj
@@ -130,10 +130,5 @@
         (let [t (f ds)]
           (if (= t ds)
             (recur ds (rest pending))
-            (do
-              (println (class f))
-              ;;(println ds)
-              ;;(println t)
-              ;;(println (clean t))
-              (recur (clean t) operations))))
+            (recur (clean t) operations)))
         ds))))


fix typo

fix typo

--- test/babel/test/parse.cljc
+++ test/babel/test/parse.cljc
@@ -3,7 +3,7 @@
   (:refer-clojure :exclude [get-in])
   (:require [babel.francais.grammar :refer [small medium]]
             [babel.francais.lexicon :refer [lexicon]]
-            [babel.francais.morphology :refer [analyze fo]
+            [babel.francais.morphology :refer [analyze fo]]
             [babel.over :as over]
             [babel.parse :refer [parse tokenizer]]
             [clojure.string :as string]


Unregister clojure.test result after test

--- test/midje/emission/t_clojure_test_facade.clj
+++ test/midje/emission/t_clojure_test_facade.clj
@@ -40,3 +40,4 @@
                                       "1 failures, 0 errors."]))

 (ns-unmap *ns* 'a-clojure-test-fail) ; so as not to see failure when test rerun.
+(ns-unmap *ns* 'a-clojure-test-pass) ; so as not to see success when test rerun.


refined midje-doc

refined midje-doc

--- test/purnam_karma_testing/test_sweet_doc.cljs
+++ test/purnam_karma_testing/test_sweet_doc.cljs
@@ -4,14 +4,18 @@
                [purnam.test :only [init describe is it]]
                [purnam.test.sweet :only [fact facts]]))

+[[{:hide true}]]
 (init)

 [[:chapter {:title "testing clojure"}]]

 [[:section {:title "'pure' clojurescript hashmaps"}]]

-(facts [[{:doc "Basic Hashmaps"
-          :globals [o {:a 1 :b 2 :c 3}]}]]
+"Remember, these are tests in clojurescript!"
+
+(def o {:a 1 :b 2 :c 3})
+
+(facts [[{:doc "Basic Hashmaps"}]]
   (o :a)       => 1
   (o :a)       => #(not= 0 %)
   (get o :b)   => 2
@@ -21,29 +25,35 @@

 [[:section {:title "native javascript objects"}]]

+"We now look at doing tests on native javascript objects"
+
+(def o (obj :a 1 :b 2 :c 3))
+
 (facts [[{:doc "an example test description"
           :globals [ka "a"
                    kb "b"]
           :vars [o (obj :a 1 :b 2 :c 3)]}]]
-
- [[:subsection {:title "dot notation for native objects"}]]
+
+ "Here are some examples"
+
+ [[:subsubsection {:title "dot notation for native objects"}]]
  o.a => 1
  (+ o.a o.b o.c) => 6

- [[:subsection {:title "support for both native and cljs comparisons"}]]
+ [[:subsubsection {:title "support for both native and cljs comparisons"}]]
  o => (obj :a 1 :b 2 :c 3)
  [1 2 3 4] => [1 2 3 4]

- [[:subsection {:title "support for function comparison"}]]
+ [[:subsubsection {:title "support for function comparison"}]]
   2 => even?
   3 => (comp not even?)

-  [[:subsection {:title "globals can be accessed"}]]
+  [[:subsubsection {:title "globals can be accessed"}]]
   o.|ka| => 1
   (+ o.|ka| o.|kb|) => 3

-  [[:subsection {:title "vars can be rebound"}]]
+  [[:subsubsection {:title "vars can be rebound"}]]
   (! o (arr [1 2 3]
             [4 5 6]
             [7 8 9]))


Key invite modal users by type and handle

--- src-cljs/frontend/components/pages/team.cljs
+++ src-cljs/frontend/components/pages/team.cljs
@@ -69,31 +69,41 @@
                            :project project}))]]
     (assoc user ::follow-count (count (get followings user)))))

-(defn invitees [component-users-by-handle vcs-users]
+;; functions for invite-teammates-modal component state manipulation
+
+(defn- component-user-ident [{:keys [type handle] :as user} & keys]
+  [:org-members-by-type-and-handle [type handle]])
+
+(defn- conj-to-user-ident [user & keys]
+  (apply conj (component-user-ident user) keys))
+
+(defn- select! [owner user]
+  (om/set-state! owner (conj-to-user-ident user :selected?) true))
+
+(defn- deselect! [owner user]
+  (om/set-state! owner (conj-to-user-ident user :selected?) false))
+
+(defn- selected? [owner user]
+  (om/get-state owner (conj-to-user-ident user :selected?)))
+
+(defn- set-entered-email! [owner user value]
+  (om/set-state! owner (conj-to-user-ident user :entered-email) value))
+
+(defn- get-entered-email [owner user]
+  (om/get-state owner (conj-to-user-ident user :entered-email)))
+
+(defn- get-user-from-state [owner vcs-user]
+  (om/get-state owner (component-user-ident vcs-user)))
+
+(defn- invitees [component-state vcs-users]
   (keep (fn [{:keys [handle] :as vcs-user}]
-          (let [{:keys [selected?] :as component-user} (get component-users-by-handle handle)]
+          (let [user-ident (component-user-ident vcs-user)
+                {:keys [selected?] :as component-user} (get-in component-state user-ident)]
             (when selected?
               (-> vcs-user
                   (assoc :email (:entered-email component-user))
                   (select-keys [:provider_id :handle :email :name])))))
         vcs-users))
-
-;; functions for invite-teammates-modal component state manipulation
-
-(defn- select! [owner {:keys [handle] :as user}]
-  (om/set-state! owner [:org-members-by-handle handle :selected?] true))
-
-(defn- deselect! [owner {:keys [handle] :as user}]
-  (om/set-state! owner [:org-members-by-handle handle :selected?] false))
-
-(defn- selected? [owner {:keys [handle] :as user}]
-  (om/get-state owner [:org-members-by-handle handle :selected?]))
-
-(defn- set-entered-email! [owner {:keys [handle] :as user} value]
-  (om/set-state! owner [:org-members-by-handle handle :entered-email] value))
-
-(defn- get-entered-email [owner {:keys [handle] :as user}]
-  (om/get-state owner [:org-members-by-handle handle :entered-email]))

 (defn- invite-button-text [number-of-invites]
   (cond
@@ -108,26 +118,27 @@
       (let [new-selected-org (:selected-org new-props)
             new-vcs-users (:vcs-users new-selected-org)
             old-vcs-users (get-in (om/get-props owner) [:selected-org :vcs-users])
-            new-show-modal? (:show-modal? new-props)
-            component-users-by-handle (om/get-state owner :org-members-by-handle)]
+            new-show-modal? (:show-modal? new-props)]
         (when (and new-show-modal?
                    (not new-vcs-users))
           (api/get-org-members (:name new-selected-org) (:vcs_type new-selected-org) (om/get-shared owner [:comms :api])))
         (when (not= new-vcs-users old-vcs-users)
           (om/set-state! owner
-                         :org-members-by-handle
-                         (into {}
-                               (for [{:keys [handle user? email]
-                                      :as user} new-vcs-users
-                                     :when (not user?)]
-                                 (if-let [component-user (get component-users-by-handle handle)]
-                                   [handle component-user]
-                                   (let [trimmed-email (some-> email gstr/trim)]
-                                     [handle {:entered-email trimmed-email
-                                              :selected? (valid-email? trimmed-email)}]))))))))
+                         (reduce (fn [acc {:keys [user? email] :as user}]
+                                   (if user?
+                                     acc
+                                     (let [user-state (if-let [component-user (get-user-from-state owner user)]
+                                                        component-user
+                                                        (let [trimmed-email (some-> email gstr/trim)]
+                                                          {:entered-email trimmed-email
+                                                           :selected? (valid-email? trimmed-email)}))
+                                           user-ident (component-user-ident user)]
+                                       (assoc-in acc user-ident user-state))))
+                                 {}
+                                 new-vcs-users)))))

     om/IRenderState
-    (render-state [_ {:keys [org-members-by-handle]}]
+    (render-state [_ {:keys [org-members-by-type-and-handle] :as state}]
       (component
        (html
         [:div
@@ -137,10 +148,10 @@
                  count-users (count users)
                  count-selected (count (filter (fn [[_ user]]
                                                  (:selected? user))
-                                               org-members-by-handle))
+                                               org-members-by-type-and-handle))
                  count-with-email (count (filter (fn [[_ user]]
                                                    (-> user :entered-email valid-email?))
-                                                 org-members-by-handle))]
+                                                 org-members-by-type-and-handle))]
              (modal/modal-dialog {:title "Invite Teammates"
                                   :body
                                   (element :body
@@ -207,7 +218,7 @@
                                             (forms/managed-button
                                              [:button.btn.btn-primary {:data-success-text "Sent"
                                                                        :on-click #(do
-                                                                                (raise! owner [:invited-team-members {:invitees (invitees org-members-by-handle vcs-users)
+                                                                                (raise! owner [:invited-team-members {:invitees (invitees state vcs-users)
                                                                                :vcs_type (:vcs_type selected-org)
                                                                                :org-name (:name selected-org)}])
                                                                                (close-fn))


Force build and deployment

Force build and deployment

--- backend/specs/akvo/lumen/specs/visualisation/legend.clj
+++ backend/specs/akvo/lumen/specs/visualisation/legend.clj
@@ -21,4 +21,5 @@

 (s/def ::order (s/keys :opt-un [::order.s/mode ::order.s/list]))

+
 (s/def ::legend (s/keys :req-un [::order]))


implement real-time window shape persistence

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

--- plugins/DataBrowser/src/org/micromanager/browser/utils.clj
+++ plugins/DataBrowser/src/org/micromanager/browser/utils.clj
@@ -190,11 +190,25 @@
 (defn get-shape [components]
   (for [comp components]
     (condp instance? comp
-      java.awt.Window
+      Window
         [:window {:x (.getX comp) :y (.getY comp)
                   :w (.getWidth comp) :h (.getHeight comp)}]
-      javax.swing.JSplitPane
+      JSplitPane
         [:split-pane {:location (.getDividerLocation comp)}]
+      nil)))
+
+(defn watch-shape [components fun]
+  (doseq [comp components]
+    (condp instance? comp
+      Window
+        (.addComponentListener comp
+          (proxy [java.awt.event.ComponentAdapter] []
+            (componentMoved [_] (fun))
+            (componentResized [_] (fun))))
+      JSplitPane
+        (.addPropertyChangeListener comp JSplitPane/DIVIDER_LOCATION_PROPERTY
+          (proxy [java.beans.PropertyChangeListener] []
+            (propertyChange [_] (fun))))
       nil)))

 (defn set-shape [components shape-data]
@@ -218,14 +232,21 @@
   (write-value-to-prefs prefs name (get-shape components)))

 (defn restore-shape [prefs name components]
-  (set-shape components (read-value-from-prefs prefs name)))
-
+  (try
+    (set-shape components (read-value-from-prefs prefs name))
+    (catch Exception e)))
+
 (defn persist-window-shape [prefs name ^java.awt.Window window]
-  (let [components (widget-seq window)]
+  (let [components (widget-seq window)
+        shape-persister (agent nil)]
     (restore-shape prefs name components)
-    (.addWindowListener window
-      (proxy [java.awt.event.WindowAdapter] []
-        (windowClosing [_] (save-shape prefs name components))))))
+    (watch-shape components
+      #(send-off shape-persister
+        (fn [old-shape]
+          (let [shape (get-shape components)]
+            (when (not= old-shape shape)
+              (write-value-to-prefs prefs name shape))
+            shape))))))

 ;; file choosers


Added mostly functional asset reloading Currently causes the current room to fully reload, as if R was pressed

--- desktop/src-common/escape_game/core.clj
+++ desktop/src-common/escape_game/core.clj
@@ -40,7 +40,7 @@
                               :x (:x (:selected screen))
                               :y (- (:y (:selected screen)) 3)
                               :width 47 :height 58)]))
-    entities)       ; WATCH: must return only the entities list! (or NIL?)
+    entities)       ; WATCH: must return onuly the entities list! (or NIL?)

   :on-resize
   (fn [screen entities]
@@ -56,6 +56,21 @@
               nil)
           (= (:key screen) (key-code :r))
           (do (room->entities (:current-room screen) rooms))
+          (= (:key screen) (key-code :y))
+          (do (mapv (fn [name]
+                  (debug "RELOADING" name)
+                  (asset-manager! manager :unload name))
+                (asset-manager! manager :get-asset-names))
+            (let [newinv (map #(change-texture % (:image %)) (:inventory screen))]
+              (update! screen :inventory newinv))
+            (:switch-to-room (:current-room screen))
+            (let [newrooms (zipmap
+                             (keys (:rooms screen))
+                             (map (fn [vec]
+                                    (map #(change-texture % (:image %)) vec))
+                                  (vals (:rooms screen))))]
+              (update! screen :rooms newrooms)
+              ((:current-room screen) newrooms)))
           ;; (= (:key screen) (key-code :s))
           ;; (do (input! :get-text-input #(debug %) "Spawn item" "text" "hint")
           ;;     nil)


Update spyscope

Update spyscope

--- roles/clojure/files/profiles.clj
+++ roles/clojure/files/profiles.clj
@@ -6,7 +6,7 @@
                        [criterium "0.4.2"]
                        [org.clojure/tools.namespace "0.2.5"]
                        [slamhound "1.5.3"]
-                       [spyscope "0.1.4"]]
+                       [spyscope "0.1.5"]]

         :plugins [[cider/cider-nrepl "0.9.0-SNAPSHOT"]
                   [codox "0.6.6"]


Fix reconnect-overlay being under sidebar

--- src/braid/core/client/ui/styles/reconnect_overlay.cljs
+++ src/braid/core/client/ui/styles/reconnect_overlay.cljs
@@ -12,7 +12,7 @@
     :right 0
     :top 0
     :background "rgba(242,242,242,0.75)"
-    :z-index 5000}
+    :z-index 10000}

    [:>.info
     {:position "absolute"


[ISSUE #3432] Make sure public chat topic can be fully erased

--- src/status_im/ui/screens/add_new/new_public_chat/view.cljs
+++ src/status_im/ui/screens/add_new/new_public_chat/view.cljs
@@ -34,7 +34,7 @@
      :on-change-text    #(re-frame/dispatch [:set :public-group-topic %])
      :on-submit-editing #(when topic (re-frame/dispatch [:create-new-public-chat topic]))
      :value             topic
-     :validator         #(re-matches #"[a-z\-]+" %)
+     :validator         #(re-matches #"[a-z\-]*" %)
      :auto-capitalize   :none}]])

 (defn- public-chat-icon [topic]


reintroduce repository parsing

reintroduce repository parsing


TRDR-54: normalize newline using flag instead of reusing pushback buffer

--- src/main/clojure/clojure/tools/reader/reader_types.clj
+++ src/main/clojure/clojure/tools/reader/reader_types.clj
@@ -102,23 +102,25 @@
     (when (instance? Closeable rdr)
       (.close ^Closeable rdr))))

-(defn- normalize-newline [rdr ch]
-  (if (identical? \return ch)
-    (let [c (peek-char rdr)]
-      (when (or (identical? \formfeed c)
-                (identical? \newline c))
-        (read-char rdr))
-      \newline)
-    ch))
-
 (deftype IndexingPushbackReader
     [rdr ^:unsynchronized-mutable ^long line ^:unsynchronized-mutable ^long column
      ^:unsynchronized-mutable line-start? ^:unsynchronized-mutable prev
-     ^:unsynchronized-mutable ^long prev-column file-name]
+     ^:unsynchronized-mutable ^long prev-column file-name
+     ^:unsynchronized-mutable normalize?]
   Reader
   (read-char [reader]
     (when-let [ch (read-char rdr)]
-      (let [ch (normalize-newline rdr ch)]
+      (let [ch (if normalize?
+                 (do (set! normalize? false)
+                     (if (or (identical? \newline ch)
+                             (identical? \formfeed ch))
+                       (read-char rdr)
+                       ch))
+                 ch)
+            ch (if (identical? \return ch)
+                 (do (set! normalize? true)
+                     \newline)
+                 ch)]
         (set! prev line-start?)
         (set! line-start? (newline? ch))
         (when line-start?
@@ -155,9 +157,7 @@
 (extend-type java.io.PushbackReader
   Reader
   (read-char [rdr]
-    (let [c (.read ^java.io.PushbackReader rdr)]
-      (when (>= c 0)
-        (normalize-newline rdr (char c)))))
+    (char (.read ^java.io.PushbackReader rdr)))

   (peek-char [rdr]
     (when-let [c (read-char rdr)]
@@ -245,11 +245,22 @@
 (deftype SourceLoggingPushbackReader
     [rdr ^:unsynchronized-mutable ^long line ^:unsynchronized-mutable ^long column
      ^:unsynchronized-mutable line-start? ^:unsynchronized-mutable prev
-     ^:unsynchronized-mutable ^long prev-column file-name source-log-frames]
+     ^:unsynchronized-mutable ^long prev-column file-name source-log-frames
+     ^:unsynchronized-mutable normalize?]
   Reader
   (read-char [reader]
     (when-let [ch (read-char rdr)]
-      (let [ch (normalize-newline rdr ch)]
+      (let [ch (if normalize?
+                 (do (set! normalize? false)
+                     (if (or (identical? \newline ch)
+                             (identical? \formfeed ch))
+                       (read-char rdr)
+                       ch))
+                 ch)
+            ch (if (identical? \return ch)
+                 (do (set! normalize? true)
+                     \newline)
+                 ch)]
         (set! prev line-start?)
         (set! line-start? (newline? ch))
         (when line-start?
@@ -347,7 +358,7 @@
    (indexing-push-back-reader s-or-rdr buf-len nil))
   ([s-or-rdr buf-len file-name]
    (IndexingPushbackReader.
-    (to-pbr s-or-rdr buf-len) 1 1 true nil 0 file-name)))
+    (to-pbr s-or-rdr buf-len) 1 1 true nil 0 file-name false)))

 (defn ^Closeable source-logging-push-back-reader
   "Creates a SourceLoggingPushbackReader from a given string or PushbackReader"
@@ -366,7 +377,8 @@
     file-name
     (doto (make-var)
       (alter-var-root (constantly {:buffer (StringBuilder.)
-                                   :offset 0}))))))
+                                   :offset 0})))
+    false)))

 (defn read-line
   "Reads a line from the reader or from *in* if no reader is specified"


present tense: aspect should be :simple

present tense: aspect should be :simple

--- src/babel/espanol/writer.clj
+++ src/babel/espanol/writer.clj
@@ -185,7 +185,7 @@
                                                        (and (not (= (get-in spec [:synsem :sem :tense])
                                                                     :present))
                                                             (not (= (get-in spec [:synsem :sem :aspect])
-                                                                    :progressive)))
+                                                                    :simple)))
                                                        (and (= (get-in spec [:synsem :sem :tense])
                                                                :past)
                                                             (= (get-in spec [:synsem :sem :aspect])


whoops, plus icon lines weren't centered


Reindeer skeleton.

Reindeer skeleton.

--- ClojureScript/hello.cljs
+++ ClojureScript/hello.cljs
@@ -14,55 +14,12 @@
         ))

 (def my-code-url "https://github.com/pauldoo/scratch/blob/master/ClojureScript/hello.cljs")
+(def width-in-px 800)
+(def height-in-px 300)
 (def tick-step (/ 1 100))
 (def render-step (/ 1 25))
 (def gravity-strength 300)
 (def ground-strength 100)
-(def initial-game-state {
-    :nodes {
-        :t {
-            :pos [50 100]
-            :vel [0 0]
-        }
-        :u {
-            :pos [250 200]
-            :vel [0 0]
-        }
-        :v {
-            :pos [150 100]
-            :vel [0 0]
-        }
-    }
-    :springs [
-        {
-            :node-a :t
-            :node-b :u
-            :rest-length 224.0
-            :strength 2000
-        }
-        ;{
-        ;    :node-a :u
-        ;    :node-b :v
-        ;    :rest-length 141.0
-        ;    :strength 2000
-        ;}
-        {
-            :node-a :t
-            :node-b :v
-            :rest-length 100.0
-            :strength 2000
-        }
-    ]
-    :hinges [
-        {
-            :node-a :u
-            :node-b :t
-            :node-c :v
-            :rest-angle (/ Math/PI 2)
-            :strength 100000
-        }
-    ]
-    })

 (defn print-to-log [v]
     (.log js/console v))
@@ -74,12 +31,69 @@
 (def magnitude (comp Math/sqrt magnitude-squared))
 (def normalize (comp (partial apply vec*) (juxt identity (comp (partial / 1.0) magnitude))))
 (defn dot-product [v w] (apply + (map * v w)))
-(defn clamp [v lower upper] (Math/min (Math/max v lower) upper))
-(defn angle [v w] (Math/acos (clamp
-    (dot-product (normalize v) (normalize w))
-    -1.0 1.0 )))
+(defn cross-product [[a b] [c d]] (- (* a d) (* b c)))
+;(defn clamp [v lower upper] (Math/min (Math/max v lower) upper))
+(defn angle [v w] (Math/atan2 (cross-product v w) (dot-product v w)))
 (defn rot-cw [[x y]] [y (- x)])
 (defn rot-ccw [[x y]] [(- y) x])
+
+(defn make-node [x y] {:pos [x y] :vel [0 0]})
+(defn make-spring [a b] {:node-a a :node-b b})
+(defn make-hinge [a b c] {:node-a a :node-b b :node-c c})
+(defn make-state [nodes springs hinges] {
+    :nodes nodes
+    :springs (map
+        (fn [s] (assoc s
+            :rest-length (magnitude (vec- (:pos (nodes (:node-a s))) (:pos (nodes (:node-b s)))))
+            :strength 1000))
+        springs)
+    :hinges (map
+        (fn [h] (assoc h
+            :rest-angle (let [
+                a (vec- (:pos (nodes (:node-a h))) (:pos (nodes (:node-b h))))
+                c (vec- (:pos (nodes (:node-c h))) (:pos (nodes (:node-b h))))]
+                (angle a c))
+            :strength 20000))
+        hinges)
+})
+
+(def initial-game-state (make-state
+    {
+        :head (make-node 250 150)
+        :tail (make-node 50 150)
+        :h-l-k (make-node 270 75)
+        :h-l-f (make-node 270 0)
+        :h-t-k (make-node 230 75)
+        :h-t-f (make-node 230 0)
+        :t-l-k (make-node 70 75)
+        :t-l-f (make-node 70 0)
+        :t-t-k (make-node 30 75)
+        :t-t-f (make-node 30 0)
+    }
+    (map (partial apply make-spring) [
+        [:head :tail]
+        [:head :h-l-k]
+        [:h-l-k :h-l-f]
+        [:head :h-t-k]
+        [:h-t-k :h-t-f]
+        [:tail :t-l-k]
+        [:t-l-k :t-l-f]
+        [:tail :t-t-k]
+        [:t-t-k :t-t-f]
+    ])
+    (map (partial apply make-hinge) [
+        [:tail :head :h-l-k]
+        [:head :h-l-k :h-l-f]
+        [:tail :head :h-t-k]
+        [:head :h-t-k :h-t-f]
+        [:head :tail :t-l-k]
+        [:tail :t-l-k :t-l-f]
+        [:head :tail :t-t-k]
+        [:tail :t-t-k :t-t-f]
+    ])
+))
+
+;(print-to-log (pr-str initial-game-state))

 (defn calculate-force [node-a node-b rest-length strength]
     (let [a-b (vec- node-a node-b)
@@ -98,14 +112,23 @@
                 }))
             springs)))

+(defn real-mod [a b]
+    (mod (+ (mod a b) b) b))
+(defn pi-mod [a]
+    (-
+        (real-mod
+            (+ a Math/PI)
+            (* 2 Math/PI))
+        Math/PI))
+
 (defn calculate-hinge-force [a b c rest-angle strength]
     (let [
         b-to-a (vec- a b)
         b-to-c (vec- c b)
-        pressure (* (- rest-angle (angle b-to-a b-to-c)) strength)
+        pressure (* (pi-mod (- rest-angle (angle b-to-a b-to-c))) strength)
         result [
-            (vec* (rot-ccw b-to-a) (/ pressure (magnitude-squared b-to-a)))
-            (vec* (rot-cw b-to-c) (/ pressure (magnitude-squared b-to-c)))
+            (vec* (rot-cw b-to-a) (/ pressure (magnitude-squared b-to-a)))
+            (vec* (rot-ccw b-to-c) (/ pressure (magnitude-squared b-to-c)))
         ]]
             result))

@@ -197,10 +220,10 @@

 (defn rerender [canvas-element game-state]
     (let [
-        graphics (graphics/createGraphics 400 300)
+        graphics (graphics/createGraphics width-in-px height-in-px)
         {nodes :nodes springs :springs} game-state]
         (do
-            (apply draw-line graphics (apply concat (map world-to-screen [[0 0] [400 0]])))
+            (apply draw-line graphics (apply concat (map world-to-screen [[0 0] [width-in-px 0]])))
             (dorun (map
                 (fn [{a :node-a b :node-b}]
                     (let [


unify {:synsem :agr} with  {:synsem :subcat :1} within conjugation rules

--- src/babel/francais/morphology/verbs.cljc
+++ src/babel/francais/morphology/verbs.cljc
@@ -6,55 +6,69 @@
    [clojure.string :refer (trim)]
    #?(:clj [clojure.tools.logging :as log])
    #?(:cljs [babel.logjs :as log])
-   [dag_unify.core :refer (copy dissoc-paths fail? get-in ref? strip-refs unifyc)]))
+   [dag_unify.core :refer (copy dissoc-paths fail? get-in ref? strip-refs unify)]))

 ;; TODO: convert to (babel.morphology/conjugation) (see babel.latin.morphology for an example of how to use conjugation)
+
+(def agr
+  (let [agr (atom :top)]
+    {:synsem {:agr agr
+              :subcat {:1 {:agr agr}}}}))
+
 (def present-nonreflexive-er-verb
-  [
-   {:p [#"^([^' ]+)e$"         "$1er"]
-    :g [#"^([^' ]+)er$"        "$1e"]
-    :u {:synsem {:subcat {:1 {:agr {:number :sing
-                                    :person :1st}}}
-                 :infl :present}}}
-
-   {:p [#"^([^' ]+)es$"        "$1er"]
-    :g [#"^([^' ]+)er$"        "$1es"]
-    :u {:synsem {:subcat {:1 {:agr {:number :sing
-                                    :person :2nd}}}
-                 :infl :present}}}
-
-   {:p [#"^([^' ]+)e$"         "$1er"]
-    :g [#"^([^' ]+)er$"        "$1e"]
-    :u {:synsem {:subcat {:1 {:agr {:number :sing
-                                    :person :3rd}}}
-                 :infl :present}}}
-
-   {:p [#"^([^' ]+)([^e])ons$" "$1$2er"]
-    :g [#"^([^' ]+)([^g])er$"  "$1$2ons"]
-    :u {:synsem {:subcat {:1 {:agr {:number :plur
-                                    :person :1st}}}
-                 :infl :present}}}
-
-   {:p [#"^([^' ]+)(g)eons$"   "$1$2er"]
-    :g [#"^([^' ]+)(g)er$"     "$1$2eons"]
-    :u {:synsem {:subcat {:1 {:agr {:number :plur
-                                    :person :1st}}}
-                 :infl :present}}}
-
-   {:p [#"^([^' ]+)ez$"        "$1er"]
-    :g [#"^([^' ]+)er$"        "$1ez"]
-    :u {:synsem {:subcat {:1 {:agr {:number :plur
-                                    :person :2nd}}}
-                 :infl :present}}}
-
-   {:p [#"^([^' ]+)ent$"       "$1er"]
-    :g [#"^([^' ]+)er$"        "$1ent"]
-    :u {:synsem {:subcat {:1 {:agr {:number :plur
-                                    :person :3rd}}}
-                 :infl :present}}}
-   ])
+  (map
+   #(merge %
+           {:u (unify agr
+                      (:u %))})
+   [
+    {:p [#"^([^' ]+)e$"         "$1er"]
+     :g [#"^([^' ]+)er$"        "$1e"]
+     :u {:synsem {:subcat {:1 {:agr {:number :sing
+                                     :person :1st}}}
+                  :infl :present}}}
+
+    {:p [#"^([^' ]+)es$"        "$1er"]
+     :g [#"^([^' ]+)er$"        "$1es"]
+     :u {:synsem {:subcat {:1 {:agr {:number :sing
+                                     :person :2nd}}}
+                  :infl :present}}}
+
+    {:p [#"^([^' ]+)e$"         "$1er"]
+     :g [#"^([^' ]+)er$"        "$1e"]
+     :u {:synsem {:subcat {:1 {:agr {:number :sing
+                                     :person :3rd}}}
+                  :infl :present}}}
+
+    {:p [#"^([^' ]+)([^e])ons$" "$1$2er"]
+     :g [#"^([^' ]+)([^g])er$"  "$1$2ons"]
+     :u {:synsem {:subcat {:1 {:agr {:number :plur
+                                     :person :1st}}}
+                  :infl :present}}}
+
+    {:p [#"^([^' ]+)(g)eons$"   "$1$2er"]
+     :g [#"^([^' ]+)(g)er$"     "$1$2eons"]
+     :u {:synsem {:subcat {:1 {:agr {:number :plur
+                                     :person :1st}}}
+                  :infl :present}}}
+
+    {:p [#"^([^' ]+)ez$"        "$1er"]
+     :g [#"^([^' ]+)er$"        "$1ez"]
+     :u {:synsem {:subcat {:1 {:agr {:number :plur
+                                     :person :2nd}}}
+                  :infl :present}}}
+
+    {:p [#"^([^' ]+)ent$"       "$1er"]
+     :g [#"^([^' ]+)er$"        "$1ent"]
+     :u {:synsem {:subcat {:1 {:agr {:number :plur
+                                     :person :3rd}}}
+                  :infl :present}}}
+    ]))

 (def present-nonreflexive-ir-verb
+  (map
+   #(merge %
+           {:u (unify agr
+                      (:u %))})
   [
    {:p [#"^([^' ]+)is$"         "$1ir"]
     :g [#"^([^' ]+)ir$"         "$1is"]
@@ -91,9 +105,13 @@
     :u {:synsem {:subcat {:1 {:agr {:number :plur
                                     :person :3rd}}}
                  :infl :present}}}
-   ])
+   ]))

 (def present-nonreflexive-re-verb
+  (map
+   #(merge %
+           {:u (unify agr
+                      (:u %))})
   [
    {:p [#"^([^' ]+)$"          "$1re"]
     :g [#"^([^' ]+)re$"        "$1"]
@@ -131,50 +149,57 @@
     :u {:synsem {:subcat {:1 {:agr {:number :plur
                                     :person :3rd}}}
                  :infl :present}}}
-])
+]))

 (def present-reflexive-re-verb
-  [
-   {:p [#"^([^' ]+)s$"       "se $1dre"]
-    :g [#"^se ([^' ]+)dre$"  "$1s"]
-    :u {:synsem {:subcat {:1 {:agr {:number :sing
-                                    :person :1st}}}
-                 :infl :present}}}
-
-   {:p [#"^([^' ]+)s$"       "se $1dre"]
-    :g [#"^se ([^' ]+)dre$"  "$1s"]
-    :u {:synsem {:subcat {:1 {:agr {:number :sing
-                                    :person :2nd}}}
-                 :infl :present}}}
-
-   {:p [#"^([^' ]+)t$"       "se $1dre"]
-    :g [#"^se ([^' ]+)dre$"  "$1t"]
-    :u {:synsem {:subcat {:1 {:agr {:number :sing
-                                    :person :3rd}}}
-                 :infl :present}}}
-
-   ;; e.g. se plaindre => se plaindrons
-   {:p [#"^([^' ]+)gnons$"   "se $1ndre"]
-    :g [#"^se ([^' ]+)ndre$" "se $1gnons"]
-    :u {:synsem {:subcat {:1 {:agr {:number :plur
-                                    :person :1st}}}
-                 :infl :present}}}
-
-   {:p [#"^([^' ]+)gniez$"   "se $1ndre"]
-    :g [#"^se ([^' ]+)ndre$" "$1gnez"]
-    :u {:synsem {:subcat {:1 {:agr {:number :plur
-                                    :person :2nd}}}
-                 :infl :present}}}
-
-   {:p [#"^([^' ]+)gnent$"   "se $1ndre"]
-    :g [#"^se ([^' ]+)ndre$" "$1gnent"]
-    :u {:synsem {:subcat {:1 {:agr {:number :plur
-                                    :person :3rd}}}
-                 :infl :present}}}
-])
+  (map
+   #(merge %
+           {:u (unify agr
+                      (:u %))})
+   [
+    {:p [#"^([^' ]+)s$"       "se $1dre"]
+     :g [#"^se ([^' ]+)dre$"  "$1s"]
+     :u {:synsem {:subcat {:1 {:agr {:number :sing
+                                     :person :1st}}}
+                  :infl :present}}}
+
+    {:p [#"^([^' ]+)s$"       "se $1dre"]
+     :g [#"^se ([^' ]+)dre$"  "$1s"]
+     :u {:synsem {:subcat {:1 {:agr {:number :sing
+                                     :person :2nd}}}
+                  :infl :present}}}
+
+    {:p [#"^([^' ]+)t$"       "se $1dre"]
+     :g [#"^se ([^' ]+)dre$"  "$1t"]
+     :u {:synsem {:subcat {:1 {:agr {:number :sing
+                                     :person :3rd}}}
+                  :infl :present}}}
+
+    ;; e.g. se plaindre => se plaindrons
+    {:p [#"^([^' ]+)gnons$"   "se $1ndre"]
+     :g [#"^se ([^' ]+)ndre$" "se $1gnons"]
+     :u {:synsem {:subcat {:1 {:agr {:number :plur
+                                     :person :1st}}}
+                  :infl :present}}}
+
+    {:p [#"^([^' ]+)gniez$"   "se $1ndre"]
+     :g [#"^se ([^' ]+)ndre$" "$1gnez"]
+     :u {:synsem {:subcat {:1 {:agr {:number :plur
+                                     :person :2nd}}}
+                  :infl :present}}}
+
+    {:p [#"^([^' ]+)gnent$"   "se $1ndre"]
+     :g [#"^se ([^' ]+)ndre$" "$1gnent"]
+     :u {:synsem {:subcat {:1 {:agr {:number :plur
+                                     :person :3rd}}}
+                  :infl :present}}}]))

 (def present-reflexive
   ;; reflexive present -er and -ir type verbs
+  (map
+   #(merge %
+           {:u (unify agr
+                      (:u %))})
   [
    {:comment "present reflexive 1st person singular, stem begins with a vowel"
     :p [#"^([aeéiou]\S+)e$"    "s'$1er"]
@@ -258,9 +283,13 @@
     :g [#"^se ([^aeéiou]\S+)[ie]r$"     "$1ent"]
     :u {:synsem {:subcat {:1 {:agr {:number :plur
                                     :person :3rd}}}
-                 :infl :present}}}])
+                 :infl :present}}}]))

 (def past-reflexive
+  (map
+   #(merge %
+           {:u (unify agr
+                      (:u %))})
   [
    {:comment "past participle reflexive singular masculine -er where stem begins with a vowel"
     :p [#"^([aeéiou]\S+)é$"    "s'$1er"]
@@ -317,9 +346,13 @@
     :u {:synsem {:infl :past-p
                  :subcat {:1 {:agr {:number :plur
                                     :gender :fem}}}}}}
-   ])
+   ]))

 (def past-reflexive-re-verb
+  (map
+   #(merge %
+           {:u (unify agr
+                      (:u %))})
   [
    {:p [#"^([^' ]+)t$"       "se $1dre"]
     :g [#"^se ([^' ]+)dre$"  "$1t"]
@@ -357,427 +390,435 @@
     :u {:synsem {:subcat {:1 {:agr {:number :plur
                                     :person :3rd}}}
                  :infl :past-p}}}
-])
+]))

 (def past
-  [
-   {:comment "past participle non-reflexive singular -er; essere=true"
-    :p [#"^(\S+)é$"            "$1er"]
-    :g [#"^([^' ]+)er$"        "$1é"]
-    :u {:synsem {:infl :past-p
-                 :essere true
-                 :subcat {:1 {:agr {:number :sing}}}}}}
-
-   {:comment "past participle non-reflexive singular -er; essere=false"
-    :p [#"^(\S+)é$"            "$1er"]
-    :g [#"^([^' ]+)er$"        "$1é"]
-    :u {:synsem {:infl :past-p
-                 :essere false}}}
-
-   {:comment "past participle non-reflexive -re"
-    :p [#"^(\S+)u$"            "$1re"]
-    :g [#"^([^' ]+)re$"        "$1u"]
-    :u {:synsem {:infl :past-p}}}
-
-   {:comment "past participle non-reflexive -ir"
-    :p [#"^(\S+)i$"            "$1ir"]
-    :g [#"^([^' ]+)ir$"        "$1i"]
-    :u {:synsem {:infl :past-p}}}
-
-   {:comment "past participle non-reflexive plural; essere=true"
-    :p [#"^(\S+)és$"           "$1er"]
-    :g [#"^([^' ]+)er$"        "$1és"]
-    :u {:synsem {:infl :past-p
-                 :essere true
-                 :subcat {:1 {:agr {:gender :masc
-                                    :number :plur}}}}}}
-   ;; singular feminine
-   {:comment "past participle non-reflexive singular feminine; essere=true"
-    :p [#"^(\S+)ée$"           "$1er"]
-    :g [#"^([^' ]+)er$"        "$1ée"]
-    :u {:synsem {:infl :past-p
-                 :essere true
-                 :subcat {:1 {:agr {:number :sing
-                                    :gender :fem}}}}}}
-   ;; plural feminine
-   {:comment "past participle non-reflexive plural feminine; essere=true"
-    :p [#"^(\S+)ées$"          "$1er"]
-    :g [#"^([^' ]+)er$"        "$1ées"]
-    :u {:synsem {:infl :past-p
-                 :essere true
-                 :subcat {:1 {:agr {:number :plur
-                                    :gender :fem}}}}}}
-   ])
+  (map
+   #(merge %
+           {:u (unify agr
+                      (:u %))})
+   [{:comment "past participle non-reflexive plural; essere=true"
+     :p [#"^(\S+)és$"           "$1er"]
+     :g [#"^([^' ]+)er$"        "$1és"]
+     :u {:synsem {:infl :past-p
+                  :essere true
+                  :agr {:gender :masc
+                        :number :plur}
+                  :subcat {:1 {:agr {:gender :masc
+                                     :number :plur}}}}}}
+    ;; singular feminine
+    {:comment "past participle non-reflexive singular feminine; essere=true"
+     :p [#"^(\S+)ée$"           "$1er"]
+     :g [#"^([^' ]+)er$"        "$1ée"]
+     :u {:synsem {:infl :past-p
+                  :essere true
+                  :agr {:number :sing
+                        :gender :fem}
+                  :subcat {:1 {:agr {:number :sing
+                                     :gender :fem}}}}}}
+    ;; plural feminine
+    {:comment "past participle non-reflexive plural feminine; essere=true"
+     :p [#"^(\S+)ées$"          "$1er"]
+     :g [#"^([^' ]+)er$"        "$1ées"]
+     :u {:synsem {:infl :past-p
+                  :essere true
+                  :subcat {:1 {:agr {:number :plur
+                                     :gender :fem}}}}}}
+
+    {:comment "past participle non-reflexive singular -er; essere=false"
+     :p [#"^(\S+)é$"            "$1er"]
+     :g [#"^([^' ]+)er$"        "$1é"]
+     :u {:synsem {:infl :past-p
+                  :essere false}}}
+
+    {:comment "past participle non-reflexive -re"
+     :p [#"^(\S+)u$"            "$1re"]
+     :g [#"^([^' ]+)re$"        "$1u"]
+     :u {:synsem {:infl :past-p}}}
+
+    {:comment "past participle non-reflexive -ir"
+     :p [#"^(\S+)i$"            "$1ir"]
+     :g [#"^([^' ]+)ir$"        "$1i"]
+     :u {:synsem {:infl :past-p}}}
+    ]))

 (def conditional
-  [
-   {:p [#"^(\S+)ais$"       "$1"]
+  (map
+   #(merge %
+           {:u (unify agr
+                      (:u %))})
+  [{:p [#"^(\S+)ais$"       "$1"]
     :g [#"^(\S+)$"          "$1ais"]
     :u {:synsem {:infl :conditional
+                 :cat :verb
                  :subcat {:1 {:agr {:number :sing
                                     :person :1st}}}}}}
    {:p [#"^(\S+)ais$"       "s'$1"]
     :g [#"^s'(\S+)$"        "$1ais"]
     :u {:synsem {:infl :conditional
+                 :cat :verb
                  :subcat {:1 {:agr {:number :sing
                                     :person :1st}}}}}}
    {:p [#"^(\S+)ais$"       "se $1"]
     :g [#"^se (\S+)$"       "$1ais"]
     :u {:synsem {:infl :conditional
+                 :cat :verb
                  :subcat {:1 {:agr {:number :sing
                                     :person :1st}}}}}}
    {:p [#"^(\S+)ais$"       "$1"]
     :g [#"^(\S+)$"          "$1ais"]
     :u {:synsem {:infl :conditional
+                 :cat :verb
                  :subcat {:1 {:agr {:number :sing
                                     :person :2nd}}}}}}
    {:p [#"^(\S+)ais$"       "s'$1"]
     :g [#"^s'(\S+)$"        "$1ais"]
     :u {:synsem {:infl :conditional
+                 :cat :verb
                  :subcat {:1 {:agr {:number :sing
                                     :person :2nd}}}}}}
    {:p [#"^(\S+)ais$"       "se $1"]
     :g [#"^se (\S+)$"       "$1ais"]
     :u {:synsem {:infl :conditional
+                 :cat :verb
                  :subcat {:1 {:agr {:number :sing
                                     :person :2nd}}}}}}
    {:p [#"^(\S+)rais$"      "$1re"]
     :g [#"^(\S+)$"          "$1ais"]
     :u {:synsem {:infl :conditional
+                 :cat :verb
                  :subcat {:1 {:agr {:number :sing
                                     :person :1st}}}}}}
    {:p [#"^(\S+)rais$"      "s'$1re"]
     :g [#"^s'(\S+)$"        "$1ais"]
     :u {:synsem {:infl :conditional
+                 :cat :verb
                  :subcat {:1 {:agr {:number :sing
                                     :person :1st}}}}}}
    {:p [#"^(\S+)rais$"      "se $1re"]
     :g [#"^se (\S+)re$"     "$1rais"]
     :u {:synsem {:infl :conditional
+                 :cat :verb
                  :subcat {:1 {:agr {:number :sing
                                     :person :1st}}}}}}
    {:p [#"^(\S+)rais$"      "$1"]
     :g [#"^(\S+)re$"        "$1ais"]
     :u {:synsem {:infl :conditional
+                 :cat :verb
                  :subcat {:1 {:agr {:number :sing
                                     :person :2nd}}}}}}
    {:p [#"^(\S+)rais$"      "s'$1"]
     :g [#"^s'(\S+)re$"      "$1ais"]
     :u {:synsem {:infl :conditional
+                 :cat :verb
                  :subcat {:1 {:agr {:number :sing
                                     :person :2nd}}}}}}
    {:p [#"^(\S+)rais$"      "se $1"]
     :g [#"^se (\S+)$"       "$1ais"]
     :u {:synsem {:infl :conditional
+                 :cat :verb
                  :subcat {:1 {:agr {:number :sing
                                     :person :2nd}}}}}}
    {:p [#"^(\S+)ait$"       "$1"]
     :g [#"^(\S+)$"          "$1ait"]
     :u {:synsem {:infl :conditional
+                 :cat :verb
                  :subcat {:1 {:agr {:number :sing
                                     :person :3rd}}}}}}
    {:p [#"^(\S+)ait$"       "s'$1"]
     :g [#"^s'(\S+)$"        "$1ait"]
     :u {:synsem {:infl :conditional
+                 :cat :verb
                  :subcat {:1 {:agr {:number :sing
                                     :person :3rd}}}}}}
    {:p [#"^(\S+)ait$"       "se $1"]
     :g [#"^se (\S+)$"       "$1ait"]
     :u {:synsem {:infl :conditional
+                 :cat :verb
                  :subcat {:1 {:agr {:number :sing
                                     :person :3rd}}}}}}
    {:p [#"^(\S+)rait$"      "$1re"]
     :g [#"^(\S+)re$"        "$1rait"]
     :u {:synsem {:infl :conditional
+                 :cat :verb
                  :subcat {:1 {:agr {:number :sing
                                     :person :3rd}}}}}}
    {:p [#"^(\S+)rait$"      "s'$1re"]
     :g [#"^s'(\S+)$"        "$1rait"]
     :u {:synsem {:infl :conditional
+                 :cat :verb
                  :subcat {:1 {:agr {:number :sing
                                     :person :3rd}}}}}}
    {:p [#"^(\S+)rait$"      "se $1re"]
     :g [#"^se (\S+)$"       "$1ait"]
     :u {:synsem {:infl :conditional
+                 :cat :verb
                  :subcat {:1 {:agr {:number :sing
                                     :person :3rd}}}}}}
    {:p [#"^(\S+)ions$"      "$1"]
     :g [#"^(\S+)$"          "$1ions"]
     :u {:synsem {:infl :conditional
+                 :cat :verb
                  :subcat {:1 {:agr {:number :plur
                                     :person :1st}}}}}}
    {:p [#"^(\S+)ions$"      "s'$1"]
     :g [#"^s' (\S+)$"       "$1ions"]
     :u {:synsem {:infl :conditional
+                 :cat :verb
                  :subcat {:1 {:agr {:number :plur
                                     :person :1st}}}}}}
    {:p [#"^(\S+)ions$"      "se $1"]
     :g [#"^se (\S+)$"       "$1ions"]
     :u {:synsem {:infl :conditional
+                 :cat :verb
                  :subcat {:1 {:agr {:number :plur
                                     :person :1st}}}}}}
    {:p [#"^(\S+)rions$"     "$1re"]
     :g [#"^(\S+)re$"        "$1rions"]
     :u {:synsem {:infl :conditional
+                 :cat :verb
                  :subcat {:1 {:agr {:number :plur
                                     :person :1st}}}}}}
    {:p [#"^(\S+)rions$"     "s'$1re"]
     :g [#"^s'(\S+)$"        "$1ions"]
     :u {:synsem {:infl :conditional
+                 :cat :verb
                  :subcat {:1 {:agr {:number :plur
                                     :person :1st}}}}}}
    {:p [#"^(\S+)rions$"     "se $1re"]
     :g [#"^se (\S+)$"       "$1rions"]
     :u {:synsem {:infl :conditional
+                 :cat :verb
                  :subcat {:1 {:agr {:number :plur
                                     :person :1st}}}}}}
    {:p [#"^(\S+)iez$"       "$1"]
     :g [#"^(\S+)$"          "$1iez"]
     :u {:synsem {:infl :conditional
+                 :cat :verb
                  :subcat {:1 {:agr {:number :plur
                                     :person :2nd}}}}}}
    {:p [#"^(\S+)iez$"       "s'$1"]
     :g [#"^s'(\S+)$"        "$1iez"]
     :u {:synsem {:infl :conditional
+                 :cat :verb
                  :subcat {:1 {:agr {:number :plur
                                     :person :2nd}}}}}}
    {:p [#"^(\S+)iez$"       "se $1"]
     :g [#"^se (\S+)$"       "$1iez"]
     :u {:synsem {:infl :conditional
+                 :cat :verb
                  :subcat {:1 {:agr {:number :plur
                                     :person :2nd}}}}}}
    {:p [#"^(\S+)riez$"      "$1re"]
     :g [#"^(\S+)re$"        "$1riez"]
     :u {:synsem {:infl :conditional
+                 :cat :verb
                  :subcat {:1 {:agr {:number :plur
                                     :person :2nd}}}}}}
    {:p [#"^(\S+)riez$"      "s'$1re"]
     :g [#"^s'(\S+)re$"      "$1riez"]
     :u {:synsem {:infl :conditional
+                 :cat :verb
                  :subcat {:1 {:agr {:number :plur
                                     :person :2nd}}}}}}
    {:p [#"^(\S+)riez$"      "se $1re"]
     :g [#"^se (\S+)re$"     "$1riez"]
     :u {:synsem {:infl :conditional
+                 :cat :verb
                  :subcat {:1 {:agr {:number :plur
                                     :person :2nd}}}}}}
    {:p [#"^(\S+)aient$"     "$1"]
     :g [#"^(\S+)$"          "$1aient"]
     :u {:synsem {:infl :conditional
+                 :cat :verb
                  :subcat {:1 {:agr {:number :plur
                                     :person :3rd}}}}}}
    {:p [#"^(\S+)aient$"     "s'$1"]
     :g [#"^s'(\S+)$"        "$1aient"]
     :u {:synsem {:infl :conditional
+                 :cat :verb
                  :subcat {:1 {:agr {:number :plur
                                     :person :3rd}}}}}}
    {:p [#"^(\S+)aient$"     "se $1"]
     :g [#"^se (\S+)$"       "$1aient"]
     :u {:synsem {:infl :conditional
+                 :cat :verb
                  :subcat {:1 {:agr {:number :plur
                                     :person :3rd}}}}}}
    {:p [#"^(\S+)raient$"    "$1re"]
     :g [#"^(\S+)$"          "$1aient"]
     :u {:synsem {:infl :conditional
+                 :cat :verb
                  :subcat {:1 {:agr {:number :plur
                                     :person :3rd}}}}}}
    {:p [#"^(\S+)raient$"    "s'$1re"]
     :g [#"^s'(\S+)$"        "$1aient"]
     :u {:synsem {:infl :conditional
+                 :cat :verb
                  :subcat {:1 {:agr {:number :plur
                                     :person :3rd}}}}}}
    {:p [#"^(\S+)raient$"    "se $1re"]
     :g [#"^se (\S+)re$"     "$1raient"]
     :u {:synsem {:infl :conditional
+                 :cat :verb
                  :subcat {:1 {:agr {:number :plur
                                     :person :3rd}}}}}}
    ]
-  )
+  ))

 (def future
-  [
-   {:p [#"^(\S+)ai$"     "$1"]
-    :g [#"^(\S+)$"       "$1ai"]
-    :u {:synsem {:infl :future
-                 :subcat {:1 {:agr {:number :sing
-                                    :person :1st}}}}}}
-   {:p [#"^(\S+)ai$"     "s'$1"]
-    :g [#"^s'(\S+)$"     "$1ai"]
-    :u {:synsem {:infl :future
-                 :subcat {:1 {:agr {:number :sing
-                                    :person :1st}}}}}}
-   {:p [#"^(\S+)ai$"     "se $1"]
-    :g [#"^se (\S+)$"    "$1ai"]
-    :u {:synsem {:infl :future
-                 :subcat {:1 {:agr {:number :sing
-                                    :person :1st}}}}}}
-   {:p [#"^(\S+)as$"     "$1"]
-    :g [#"^(\S+)$"       "$1as"]
-    :u {:synsem {:infl :future
-                 :subcat {:1 {:agr {:number :sing
-                                    :person :2nd}}}}}}
-   {:p [#"^(\S+)as$"     "s'$1"]
-    :g [#"^s'(\S+)$"     "$1as"]
-    :u {:synsem {:infl :future
-                 :subcat {:1 {:agr {:number :sing
-                                    :person :2nd}}}}}}
-   {:p [#"^(\S+)as$"     "se $1"]
-    :g [#"^se (\S+)$"    "$1as"]
-    :u {:synsem {:infl :future
-                 :subcat {:1 {:agr {:number :sing
-                                    :person :2nd}}}}}}
-   {:p [#"^(\S+)rai$"    "$1re"]
-    :g [#"^(\S+)$"       "$1ai"]
-    :u {:synsem {:infl :future
-                 :subcat {:1 {:agr {:number :sing
-                                    :person :1st}}}}}}
-   {:p [#"^(\S+)rai$"    "s'$1re"]
-    :g [#"^s'(\S+)$"     "$1ai"]
-    :u {:synsem {:infl :future
-                 :subcat {:1 {:agr {:number :sing
-                                    :person :1st}}}}}}
-   {:p [#"^(\S+)rai$"    "se $1re"]
-    :g [#"^se (\S+)re$"  "$1rai"]
-    :u {:synsem {:infl :future
-                 :subcat {:1 {:agr {:number :sing
-                                    :person :1st}}}}}}
-   {:p [#"^(\S+)ras$"    "$1re"]
-    :g [#"^(\S+)re$"     "$1as"]
-    :u {:synsem {:infl :future
-                 :subcat {:1 {:agr {:number :sing
-                                    :person :2nd}}}}}}
-   {:p [#"^(\S+)ras$"    "s'$1re"]
-    :g [#"^s'(\S+)re$"   "$1as"]
-    :u {:synsem {:infl :future
-                 :subcat {:1 {:agr {:number :sing
-                                    :person :2nd}}}}}}
-   {:p [#"^(\S+)ras$"    "se $1re"]
-    :g [#"^se (\S+)$"    "$1as"]
-    :u {:synsem {:infl :future
-                 :subcat {:1 {:agr {:number :sing
-                                    :person :2nd}}}}}}
-   {:p [#"^(\S+)a$"      "$1"]
-    :g [#"^(\S+)$"       "$1a"]
-    :u {:synsem {:infl :future
-                 :subcat {:1 {:agr {:number :sing
-                                    :person :3rd}}}}}}
-   {:p [#"^(\S+)a$"      "s'$1"]
-    :g [#"^s'(\S+)$"     "$1a"]
-    :u {:synsem {:infl :future
-                 :subcat {:1 {:agr {:number :sing
-                                    :person :3rd}}}}}}
-   {:p [#"^(\S+)a$"      "se $1"]
-    :g [#"^se (\S+)$"    "$1a"]
-    :u {:synsem {:infl :future
-                 :subcat {:1 {:agr {:number :sing
-                                    :person :3rd}}}}}}
-   {:p [#"^(\S+)ra$"     "$1re"]
-    :g [#"^(\S+)re$"     "$1ra"]
-    :u {:synsem {:infl :future
-                 :subcat {:1 {:agr {:number :sing
-                                    :person :3rd}}}}}}
-   {:p [#"^(\S+)ra$"     "s'$1re"]
-    :g [#"^s'(\S+)$"     "$1ra"]
-    :u {:synsem {:infl :future
-                 :subcat {:1 {:agr {:number :sing
-                                    :person :3rd}}}}}}
-   {:p [#"^(\S+)ra$"     "se $1re"]
-    :g [#"^se (\S+)$"    "$1a"]
-    :u {:synsem {:infl :future
-                 :subcat {:1 {:agr {:number :sing
-                                    :person :3rd}}}}}}
-   {:p [#"^(\S+)ons$"    "$1"]
-    :g [#"^(\S+)$"       "$1ons"]
-    :u {:synsem {:infl :future
-                 :subcat {:1 {:agr {:number :plur
-                                    :person :1st}}}}}}
-   {:p [#"^(\S+)ons$"    "s'$1"]
-    :g [#"^s' (\S+)$"    "$1ons"]
-    :u {:synsem {:infl :future
-                 :subcat {:1 {:agr {:number :plur
-                                    :person :1st}}}}}}
-   {:p [#"^(\S+)ons$"    "se $1"]
-    :g [#"^se (\S+)$"    "$1ons"]
-    :u {:synsem {:infl :future
-                 :subcat {:1 {:agr {:number :plur
-                                    :person :1st}}}}}}
-   {:p [#"^(\S+)rons$"   "$1re"]
-    :g [#"^(\S+)re$"     "$1rons"]
-    :u {:synsem {:infl :future
-                 :subcat {:1 {:agr {:number :plur
-                                    :person :1st}}}}}}
-   {:p [#"^(\S+)rons$"   "s'$1re"]
-    :g [#"^s'(\S+)$"     "$1ons"]
-    :u {:synsem {:infl :future
-                 :subcat {:1 {:agr {:number :plur
-                                    :person :1st}}}}}}
-   {:p [#"^(\S+)rons$"   "se $1re"]
-    :g [#"^se (\S+)$"    "$1rons"]
-    :u {:synsem {:infl :future
-                 :subcat {:1 {:agr {:number :plur
-                                    :person :1st}}}}}}
-   {:p [#"^(\S+)ez$"     "$1"]
-    :g [#"^(\S+)$"       "$1ez"]
-    :u {:synsem {:infl :future
-                 :subcat {:1 {:agr {:number :plur
-                                    :person :2nd}}}}}}
-   {:p [#"^(\S+)ez$"     "s'$1"]
-    :g [#"^s'(\S+)$"     "$1ez"]
-    :u {:synsem {:infl :future
-                 :subcat {:1 {:agr {:number :plur
-                                    :person :2nd}}}}}}
-   {:p [#"^(\S+)ez$"     "se $1"]
-    :g [#"^se (\S+)$"    "$1ez"]
-    :u {:synsem {:infl :future
-                 :subcat {:1 {:agr {:number :plur
-                                    :person :2nd}}}}}}
-   {:p [#"^(\S+)rez$"    "$1re"]
-    :g [#"^(\S+)re$"     "$1rez"]
-    :u {:synsem {:infl :future
-                 :subcat {:1 {:agr {:number :plur
-                                    :person :2nd}}}}}}
-   {:p [#"^(\S+)rez$"    "s'$1re"]
-    :g [#"^s'(\S+)re$"   "$1rez"]
-    :u {:synsem {:infl :future
-                 :subcat {:1 {:agr {:number :plur
-                                    :person :2nd}}}}}}
-   {:p [#"^(\S+)rez$"    "se $1re"]
-    :g [#"^se (\S+)re$"  "$1rez"]
-    :u {:synsem {:infl :future
-                 :subcat {:1 {:agr {:number :plur
-                                    :person :2nd}}}}}}
-   {:p [#"^(\S+)ont$"    "$1"]
-    :g [#"^(\S+)$"       "$1ont"]
-    :u {:synsem {:infl :future
-                 :subcat {:1 {:agr {:number :plur
-                                    :person :3rd}}}}}}
-   {:p [#"^(\S+)ont$"    "s'$1"]
-    :g [#"^s'(\S+)$"     "$1ont"]
-    :u {:synsem {:infl :future
-                 :subcat {:1 {:agr {:number :plur
-                                    :person :3rd}}}}}}
-   {:p [#"^(\S+)ont$"    "se $1"]
-    :g [#"^se (\S+)$"    "$1ont"]
-    :u {:synsem {:infl :future
-                 :subcat {:1 {:agr {:number :plur
-                                    :person :3rd}}}}}}
-   {:p [#"^(\S+)ront$"   "$1re"]
-    :g [#"^(\S+)re$"     "$1ront"]
-    :u {:synsem {:infl :future
-                 :subcat {:1 {:agr {:number :plur
-                                    :person :3rd}}}}}}
-   {:p [#"^(\S+)ront$"   "s'$1re"]
-    :g [#"^s'(\S+)re$"   "$1ont"]
-    :u {:synsem {:infl :future
-                 :subcat {:1 {:agr {:number :plur
-                                    :person :3rd}}}}}}
-   {:p [#"^(\S+)ront$"   "se $1re"]
-    :g [#"^se (\S+)re$"  "$1ront"]
-    :u {:synsem {:infl :future
-                 :subcat {:1 {:agr {:number :plur
-                                    :person :3rd}}}}}}
-   ]
-  )
+  (map
+   #(merge %
+           {:u (unify agr
+                      (:u %)
+                      {:synsem {:cat :verb
+                                :infl :future}})})
+   [
+    {:p [#"^(\S+)ai$"     "$1"]
+     :g [#"^(\S+)$"       "$1ai"]
+     :u {:synsem {:subcat {:1 {:agr {:number :sing
+                                     :person :1st}}}}}}
+    {:p [#"^(\S+)ai$"     "s'$1"]
+     :g [#"^s'(\S+)$"     "$1ai"]
+     :u {:synsem {:subcat {:1 {:agr {:number :sing
+                                     :person :1st}}}}}}
+    {:p [#"^(\S+)ai$"     "se $1"]
+     :g [#"^se (\S+)$"    "$1ai"]
+     :u {:synsem {:subcat {:1 {:agr {:number :sing
+                                     :person :1st}}}}}}
+    {:p [#"^(\S+)as$"     "$1"]
+     :g [#"^(\S+)$"       "$1as"]
+     :u {:synsem {:subcat {:1 {:agr {:number :sing
+                                     :person :2nd}}}}}}
+    {:p [#"^(\S+)as$"     "s'$1"]
+     :g [#"^s'(\S+)$"     "$1as"]
+     :u {:synsem {:subcat {:1 {:agr {:number :sing
+                                     :person :2nd}}}}}}
+    {:p [#"^(\S+)as$"     "se $1"]
+     :g [#"^se (\S+)$"    "$1as"]
+     :u {:synsem {:subcat {:1 {:agr {:number :sing
+                                     :person :2nd}}}}}}
+    {:p [#"^(\S+)rai$"    "$1re"]
+     :g [#"^(\S+)$"       "$1ai"]
+     :u {:synsem {:subcat {:1 {:agr {:number :sing
+                                     :person :1st}}}}}}
+    {:p [#"^(\S+)rai$"    "s'$1re"]
+     :g [#"^s'(\S+)$"     "$1ai"]
+     :u {:synsem {:subcat {:1 {:agr {:number :sing
+                                     :person :1st}}}}}}
+    {:p [#"^(\S+)rai$"    "se $1re"]
+     :g [#"^se (\S+)re$"  "$1rai"]
+     :u {:synsem {:subcat {:1 {:agr {:number :sing
+                                     :person :1st}}}}}}
+    {:p [#"^(\S+)ras$"    "$1re"]
+     :g [#"^(\S+)re$"     "$1as"]
+     :u {:synsem {:subcat {:1 {:agr {:number :sing
+                                     :person :2nd}}}}}}
+    {:p [#"^(\S+)ras$"    "s'$1re"]
+     :g [#"^s'(\S+)re$"   "$1as"]
+     :u {:synsem {:subcat {:1 {:agr {:number :sing
+                                     :person :2nd}}}}}}
+    {:p [#"^(\S+)ras$"    "se $1re"]
+     :g [#"^se (\S+)$"    "$1as"]
+     :u {:synsem {:subcat {:1 {:agr {:number :sing
+                                     :person :2nd}}}}}}
+    {:p [#"^(\S+)a$"      "$1"]
+     :g [#"^(\S+)$"       "$1a"]
+     :u {:synsem {:subcat {:1 {:agr {:number :sing
+                                     :person :3rd}}}}}}
+    {:p [#"^(\S+)a$"      "s'$1"]
+     :g [#"^s'(\S+)$"     "$1a"]
+     :u {:synsem {:subcat {:1 {:agr {:number :sing
+                                     :person :3rd}}}}}}
+    {:p [#"^(\S+)a$"      "se $1"]
+     :g [#"^se (\S+)$"    "$1a"]
+     :u {:synsem {:subcat {:1 {:agr {:number :sing
+                                     :person :3rd}}}}}}
+    {:p [#"^(\S+)ra$"     "$1re"]
+     :g [#"^(\S+)re$"     "$1ra"]
+     :u {:synsem {:subcat {:1 {:agr {:number :sing
+                                     :person :3rd}}}}}}
+    {:p [#"^(\S+)ra$"     "s'$1re"]
+     :g [#"^s'(\S+)$"     "$1ra"]
+     :u {:synsem {:subcat {:1 {:agr {:number :sing
+                                     :person :3rd}}}}}}
+    {:p [#"^(\S+)ra$"     "se $1re"]
+     :g [#"^se (\S+)$"    "$1a"]
+     :u {:synsem {:subcat {:1 {:agr {:number :sing
+                                     :person :3rd}}}}}}
+    {:p [#"^(\S+)ons$"    "$1"]
+     :g [#"^(\S+)$"       "$1ons"]
+     :u {:synsem {:subcat {:1 {:agr {:number :plur
+                                     :person :1st}}}}}}
+    {:p [#"^(\S+)ons$"    "s'$1"]
+     :g [#"^s' (\S+)$"    "$1ons"]
+     :u {:synsem {:subcat {:1 {:agr {:number :plur
+                                     :person :1st}}}}}}
+    {:p [#"^(\S+)ons$"    "se $1"]
+     :g [#"^se (\S+)$"    "$1ons"]
+     :u {:synsem {:subcat {:1 {:agr {:number :plur
+                                     :person :1st}}}}}}
+    {:p [#"^(\S+)rons$"   "$1re"]
+     :g [#"^(\S+)re$"     "$1rons"]
+     :u {:synsem {:subcat {:1 {:agr {:number :plur
+                                     :person :1st}}}}}}
+    {:p [#"^(\S+)rons$"   "s'$1re"]
+     :g [#"^s'(\S+)$"     "$1ons"]
+     :u {:synsem {:subcat {:1 {:agr {:number :plur
+                                     :person :1st}}}}}}
+    {:p [#"^(\S+)rons$"   "se $1re"]
+     :g [#"^se (\S+)$"    "$1rons"]
+     :u {:synsem {:subcat {:1 {:agr {:number :plur
+                                     :person :1st}}}}}}
+    {:p [#"^(\S+)ez$"     "$1"]
+     :g [#"^(\S+)$"       "$1ez"]
+     :u {:synsem {:subcat {:1 {:agr {:number :plur
+                                     :person :2nd}}}}}}
+    {:p [#"^(\S+)ez$"     "s'$1"]
+     :g [#"^s'(\S+)$"     "$1ez"]
+     :u {:synsem {:subcat {:1 {:agr {:number :plur
+                                     :person :2nd}}}}}}
+    {:p [#"^(\S+)ez$"     "se $1"]
+     :g [#"^se (\S+)$"    "$1ez"]
+     :u {:synsem {:subcat {:1 {:agr {:number :plur
+                                     :person :2nd}}}}}}
+    {:p [#"^(\S+)rez$"    "$1re"]
+     :g [#"^(\S+)re$"     "$1rez"]
+     :u {:synsem {:subcat {:1 {:agr {:number :plur
+                                     :person :2nd}}}}}}
+    {:p [#"^(\S+)rez$"    "s'$1re"]
+     :g [#"^s'(\S+)re$"   "$1rez"]
+     :u {:synsem {:subcat {:1 {:agr {:number :plur
+                                     :person :2nd}}}}}}
+    {:p [#"^(\S+)rez$"    "se $1re"]
+     :g [#"^se (\S+)re$"  "$1rez"]
+     :u {:synsem {:subcat {:1 {:agr {:number :plur
+                                     :person :2nd}}}}}}
+    {:p [#"^(\S+)ont$"    "$1"]
+     :g [#"^(\S+)$"       "$1ont"]
+     :u {:synsem {:subcat {:1 {:agr {:number :plur
+                                     :person :3rd}}}}}}
+    {:p [#"^(\S+)ont$"    "s'$1"]
+     :g [#"^s'(\S+)$"     "$1ont"]
+     :u {:synsem {:subcat {:1 {:agr {:number :plur
+                                     :person :3rd}}}}}}
+    {:p [#"^(\S+)ont$"    "se $1"]
+     :g [#"^se (\S+)$"    "$1ont"]
+     :u {:synsem {:subcat {:1 {:agr {:number :plur
+                                     :person :3rd}}}}}}
+    {:p [#"^(\S+)ront$"   "$1re"]
+     :g [#"^(\S+)re$"     "$1ront"]
+     :u {:synsem {:subcat {:1 {:agr {:number :plur
+                                     :person :3rd}}}}}}
+    {:p [#"^(\S+)ront$"   "s'$1re"]
+     :g [#"^s'(\S+)re$"   "$1ont"]
+     :u {:synsem {:subcat {:1 {:agr {:number :plur
+                                     :person :3rd}}}}}}
+    {:p [#"^(\S+)ront$"   "se $1re"]
+     :g [#"^se (\S+)re$"  "$1ront"]
+     :u {:synsem {:subcat {:1 {:agr {:number :plur
+                                     :person :3rd}}}}}}
+    ]))

 (def regular-patterns-source
   (apply concat
@@ -802,16 +843,16 @@
          {:p (:p pattern)
           :comment (:comment pattern)
           :g (:g pattern)
-          :u (unifyc (:u pattern)
-                     (let [agr (atom :top)
-                           essere (atom :top)
-                           infl (atom :top)]
-                       {:synsem {:essere essere
-                                 :infl infl
-                                 :subcat {:1 {:agr agr}}}
-                        :essere essere
+          :u (unify (:u pattern)
+                    (let [agr (atom :top)
+                          essere (atom :top)
+                          infl (atom :top)]
+                      {:synsem {:essere essere
+                                :infl infl
+                                :subcat {:1 {:agr agr}}}
+                       :essere essere
                         :infl infl
-                        :agr agr}))})
+                       :agr agr}))})
        regular-patterns-source))

 (def irregular-patterns


fix typo

fix typo

--- src/metabase/driver/generic_sql/util.clj
+++ src/metabase/driver/generic_sql/util.clj
@@ -17,7 +17,7 @@
     (-> database
         database->connection-details
         connection-details->connection-spec
-        (assoc :make-pool? true))))     ; need to make a pool or the connection will be closed before we get a change to unCLOB-er the results during JSON serialization
+        (assoc :make-pool? true))))     ; need to make a pool or the connection will be closed before we get a chance to unCLOB-er the results during JSON serialization

 (def ^{:arglists '([database])}
   db->korma-db


Close restart ch instead of passing a value.

--- src/onyx/lifecycles/lifecycle_invoke.clj
+++ src/onyx/lifecycles/lifecycle_invoke.clj
@@ -1,5 +1,5 @@
 (ns ^:no-doc onyx.lifecycles.lifecycle-invoke
-  (:require [clojure.core.async :refer [>!!]]
+  (:require [clojure.core.async :refer [>!! close!]]
             [taoensso.timbre :refer [info error warn trace fatal] :as timbre]))

 (defn restartable-invocation [event phase handler-fn f & args]
@@ -11,7 +11,7 @@
               (throw t)

               (= action :restart)
-              (do (>!! (:onyx.core/restart-ch event) true)
+              (do (close! (:onyx.core/restart-ch event))
                   (throw (ex-info "Jumping out of task lifecycle for a clean restart."
                                   {:onyx.core/lifecycle-restart? true
                                    :original-exception t})))


rewrite om-i post blurb

rewrite om-i post blurb

--- src/pc/views/blog/optimizing_om_apps.clj
+++ src/pc/views/blog/optimizing_om_apps.clj
@@ -39,7 +39,7 @@

 (defn optimizing-om-apps []
   {:title "Optimizing Om Apps"
-   :blurb "We've released a new library for Om that we use to optimize Precursor."
+   :blurb "Our front end is built with Om and React. Both have excellent performance right out of the box, but we needed more insight."
    :author "Daniel"
    :body
    (list


Removed unnecessary TODO.

Removed unnecessary TODO.

--- test/cmr/search/test/services/parameter_validation.clj
+++ test/cmr/search/test/services/parameter_validation.clj
@@ -36,7 +36,6 @@
     (is (= {:granule_ur "Dummy"} (pv/validate-parameters :granule {:granule_ur "Dummy"})))
     (is (thrown? clojure.lang.ExceptionInfo (pv/validate-parameters :collection {:granule_ur "Dummy"}))))
   (testing "errors thrown when parameters are invalid."
-    ;; TODO Refactor this to use (is (thrown-with-msg?.
     (try
       (pv/validate-parameters :collection {:entry_title "fdad"
                                            :foo 1


tighten code

tighten code

--- src/clj/com/rpl/specter.cljc
+++ src/clj/com/rpl/specter.cljc
@@ -970,7 +970,7 @@
       (let [newi (next-fn vals i)]
         (if (= newi i)
           structure
-          (let [v (select-any (nthpath i) structure)]
+          (let [v (nth structure i)]
             (if (vector? structure)
               (let [shifted (if (< newi i)
                               (loop [j (dec i)


Cleanup

Cleanup

--- src/cljs/kindness/utils.cljs
+++ src/cljs/kindness/utils.cljs
@@ -52,8 +52,7 @@
 (defn set-element-style
   [element style]
   (doseq [[key value] style]
-    (style/setStyle element (name key) value)
-    ))
+    (style/setStyle element (name key) value)))

 (defn insert-image-assets!
   [images]


adding curves to the lines

adding curves to the lines

--- src/cljs/spaghetti/core.cljs
+++ src/cljs/spaghetti/core.cljs
@@ -74,10 +74,10 @@
 (defn calc-wire [{:keys [a b]} nodes]
   (let [node-a (get-in nodes [a])
         node-b (get-in nodes [b])
-        x1 (+ (:x node-a) 300)
-        y1 (+ (:y node-a) 165)
-        x2 (+ (:x node-b) 100)
-        y2 (+ (:y node-b) 65)]
+        x1     (+ (:x node-a) 300)
+        y1     (+ (:y node-a) 165)
+        x2     (+ (:x node-b) 100)
+        y2     (+ (:y node-b) 65)]
     {:x1 x1 :y1 y1 :x2 x2 :y2 y2}))

 (defcomponent wire [{:keys [wire nodes]} owner {:keys [app]}]
@@ -88,7 +88,9 @@
     (.connect (:node (get-in nodes [(:a wire)])) (:node (get-in nodes [(:b wire)]))))
   (render[_]
          (let [{:keys [x1 y1 x2 y2]} (calc-wire wire nodes)]
-           (html [:line {:onClick #(break-wire app wire) :x1 x1 :y1 y1 :x2 x2 :y2 y2 :stroke "#444" :stroke-width 1}]))))
+           (html [:path {:onClick #(break-wire app wire)
+                         :d (str "M" x1 "," y1 " Q" (/ (+ x1 x2) 2) "," (+ (max y1 y2) 40) " " x2 "," y2)
+                         :fill "none" :stroke "#444" :stroke-width 1}]))))

 (defcomponent wire-canvas [app owner]
   (render [_]


Port int parsing in main

Port int parsing in main

--- src/clojure_todo/handler.clj
+++ src/clojure_todo/handler.clj
@@ -138,4 +138,4 @@
   (run-jetty #'app {:port port :join? false}))

 (defn -main [port]
-  (start port))
+  (start (Integer/parseInt port)))


Update reitit JVM-settings (#4762)

Update reitit JVM-settings (#4762)

--- frameworks/Clojure/reitit/src/hello/handler.clj
+++ frameworks/Clojure/reitit/src/hello/handler.clj
@@ -13,10 +13,10 @@
   (fn [req]
     (let [exchange ^HttpServerExchange (:server-exchange req)]
       (if (.isInIoThread exchange)
-        (.dispatch exchange ^Runnable ^:once (fn []
-                                               (.startBlocking exchange)
-                                               (immutant/write-response exchange (handler req))
-                                               (.endExchange exchange)))
+        (.dispatch exchange ^Runnable (^:once fn* []
+                                        (.startBlocking exchange)
+                                        (immutant/write-response exchange (handler req))
+                                        (.endExchange exchange)))
         (handler req)))))

 (defn random []
@@ -25,7 +25,7 @@
 (def query-one (:query-one (p/compile {:row (p/rs->compiled-record)})))

 (defn random-world [ds]
-  (with-open [con (p/get-connection ds)]
+  (let [con (p/get-connection ds)]
     (query-one con ["SELECT id, randomnumber from WORLD where id=?" (random)])))

 (defn plain-text-handler [_]
@@ -46,16 +46,14 @@

 (defn -main [& _]
   (let [ds (hikari/make-datasource
-             {:read-only true
-              :maximum-pool-size 48
+             {:maximum-pool-size 256
               :pool-name "db-pool"
               :adapter "postgresql"
               :username "benchmarkdbuser"
               :password "benchmarkdbpass"
               :database-name "hello_world"
               :server-name "tfb-database"
-              :port-number 5432
-              :register-mbeans false})]
+              :port-number 5432})]
     (web/run
       (ring/ring-handler
         (ring/router
@@ -67,9 +65,9 @@
          :inject-router? false})
       {:port 8080
        :host "0.0.0.0"
+       :dispatch? false
        :io-threads (* 2 (.availableProcessors (Runtime/getRuntime)))
-       :dispatch? false
-       :worker-threads 48
+       :worker-threads (* 8 (.availableProcessors (Runtime/getRuntime)))
        :server {:always-set-keep-alive false}})))

 (comment


Fix a test to work with clojure versions pre 1.5.0-alpha4, see #4, thanks @xumingming


Z-index is part of layout data

Z-index is part of layout data

--- frontend/src/faceboard/views/boards/people.cljs
+++ frontend/src/faceboard/views/boards/people.cljs
@@ -124,7 +124,7 @@
                       (str
                         "translateX(" (:left layout) "px)"
                         "translateY(" (:top layout) "px)"
-                        "translateZ(" (if filtered? -500 -100) "px)"))
+                        "translateZ(" (:z layout) "px)"))
           zoom-transform (when layout
                            (str
                              "translateZ(" (if extended? 100 0) "px)"))]
@@ -339,21 +339,33 @@
   ISeqable
   (-seq [nl] (array-seq nl 0)))

-(defn retrieve-card-layout [card]
-  [(.getAttribute card "data-fbid")
-   {:left (.-offsetLeft card)
-    :top  (.-offsetTop card)}])
-
-(defn retrieve-cards-layout [cards]
-  (apply hash-map (mapcat #(retrieve-card-layout %) cards)))
+(defn is-person-filtered? [person filter-predicates]
+  (not (every? true? (map #(% person) filter-predicates))))
+
+(defn lookup-person [people id]
+  (first (filter #(= id (:id %)) people)))
+
+(defn retrieve-card-layout [people filter-predicates card]
+  (let [person-id (.getAttribute card "data-fbid")
+        person (lookup-person people person-id)]
+    [person-id
+     {:left (.-offsetLeft card)
+      :top  (.-offsetTop card)
+      :z    (if (is-person-filtered? person filter-predicates) -500 -100)}]))
+
+(defn retrieve-cards-layout [people filter-predicates cards]
+  (apply hash-map (mapcat #(retrieve-card-layout people filter-predicates %) cards)))

 (defn recompute-layout [data owner]
   (let [node (om/get-node owner "desk")
         cards (.-childNodes node)
+        active-filters (get-in data [:ui :filters :active])
+        filter-predicates (build-filter-predicates active-filters data)
+        people (get-in data [:content :people])
         old-layout (get-in data [:ui :people :layout])
-        layout (retrieve-cards-layout cards)]
+        layout (retrieve-cards-layout people filter-predicates cards)]
     (when-not (= (pr-str old-layout) (pr-str layout))
-      (perform! :people-layout layout))))
+      (.setTimeout js/window #(perform! :people-layout layout) 200))))

 (defcomponent people-scaffold-component [data owner _]
   (did-mount [_]
@@ -402,7 +414,7 @@
                   data {:person    person
                         :layout    (get layout person-id)
                         :extended? (contains? extended-set person-id)
-                        :filtered? (not (every? true? (map #(% person) filter-predicates)))
+                        :filtered? (is-person-filtered? person filter-predicates)
                         :anim      (:person anims)}]
               (om/build person-component data {:react-key person-id}))))))))


added TODO

added TODO


parse jira issues with link

parse jira issues with link

--- src/hu/ssh/github_changelog/conventional.clj
+++ src/hu/ssh/github_changelog/conventional.clj
@@ -27,7 +27,7 @@
   [config :- Config
    pull :- Pull]
   (let [base (str (:jira config) "/browse/")]
-    (collect-issues pull "([A-Z]+-\\d+)" (util/prepend base))))
+    (collect-issues pull "\\[?([A-Z]+-\\d+)\\]?" (util/prepend base))))

 (s/defn github-issues :- [Issue]
   [_config :- Config


[PDOK-1018] extends generator with date-time functions

--- src/main/clojure/pdok/featured/generator.clj
+++ src/main/clojure/pdok/featured/generator.clj
@@ -1,11 +1,13 @@
 (ns pdok.featured.generator
   (:require [cheshire.core :as json]
-            [clj-time.format :as tf]
-            [clj-time.local :refer [local-now]])
+            [clj-time [format :as tf]
+             [local :refer [local-now]]])
   (:import  [java.io PipedInputStream PipedOutputStream]))

 ;; 2015-02-26T15:48:26.578Z
 (def ^{:private true} date-time-formatter (tf/formatters :date-time) )
+
+(def ^{:private true} date-formatter (tf/formatters :date) )

 (defn random-word [length]
   (let [chars (map char (range 97 123))
@@ -15,27 +17,42 @@
 (defn random-geometry []
   {:type "gml" :gml "<gml:Surface srsName=\"urn:ogc:def:crs:EPSG::28992\"><gml:patches><gml:PolygonPatch><gml:exterior><gml:LinearRing>      <gml:posList srsDimension=\"2\" count=\"5\">000350.000 000650.000 000300.000 000650.000 000300.000 000600.000 000350.000 000600.000 000350.000 000650.000</gml:posList></gml:LinearRing></gml:exterior></gml:PolygonPatch></gml:patches></gml:Surface>"})

+(defn random-date []
+  (let [date (local-now)
+        date-string (tf/unparse date-formatter date)]
+    ["~#date", [date-string]]))
+
+(defn random-moment []
+  (let [moment (local-now)
+        date-time-string (tf/unparse date-time-formatter moment)]
+    ["~#moment", [date-time-string]]))
+
+(def attribute-generators [#(random-word 5) random-date random-moment])

 (defn random-new-feature
-  ([collection] (random-new-feature collection (repeatedly 2 #(random-word 5))))
-  ([collection other-fields] (random-new-feature collection (random-word 10) other-fields))
-  ([collection id other-fields]
+  ([collection]
+   (let [keys  (repeatedly 3 #(random-word 5))
+         attributes (map #(vector %1 %2) keys attribute-generators)]
+     (random-new-feature collection attributes)))
+  ([collection attributes] (random-new-feature collection (random-word 10) attributes))
+  ([collection id attributes]
    (let [validity (tf/unparse date-time-formatter (local-now))
          base {:_action "new"
               :_collection collection
               :_id id
               :_validity validity
                :_geometry (random-geometry)}
-         random-values (map #(vector % (random-word 5)) other-fields)
+         random-values (map (fn [[key gen]] (vector key (gen))) attributes)
          feature (reduce (fn [acc val] ( apply assoc acc val)) base random-values)]

      feature)))

 (defn random-json-features [out-stream dataset collection total]
-  (let [other-fields (repeatedly 2 #(random-word 5))
+  (let [other-fields (repeatedly 3 #(random-word 5))
+        attributes (map #(vector %1 %2) other-fields attribute-generators)
         package {:_meta {}
              :dataset dataset
-             :features (repeatedly total #(random-new-feature collection other-fields))}]
+             :features (repeatedly total #(random-new-feature collection attributes))}]
     (json/generate-stream package out-stream)))

 (defn- random-json-feature-stream* [out-stream dataset collection total]
@@ -49,6 +66,6 @@
   pipe-in))

 (defn generate-test-files []
-  (doseq [c [10]]
+  (doseq [c [10 100 1000 10000 100000]]
     (with-open [w (clojure.java.io/writer (str ".test-files/new-features-single-collection-" c ".json"))]
       (random-json-features w "testset" "collection1" c))))


CMR-6164 Adds try catch to subscription job searches.

--- ingest-app/src/cmr/ingest/services/jobs.clj
+++ ingest-app/src/cmr/ingest/services/jobs.clj
@@ -276,6 +276,17 @@
                 (some #{"read"} (get permissions (:concept-id granule-reference))))
               gran-refs))))

+(defn- search-gran-refs-by-collection-id
+  [context params1 params2 sub-id]
+  (try
+    (let [gran-refs1 (search/find-granule-references context params1)
+          gran-refs2 (search/find-granule-references context params2)]
+      (distinct (concat gran-refs1 gran-refs2)))
+    (catch Exception e
+      (error "Exception caught processing subscription" sub-id " searching with params "
+             (dissoc params1 :token) (dissoc params2 :token) "\n\n" (.getMessage e) "\n\n" e)
+      [])))
+
 (defn- process-subscriptions
   "Process each subscription in subscriptions into tuple for testing purposes and to use as
    the input when sending the subscription emails."
@@ -298,9 +309,7 @@
                               :collection-concept-id coll-id
                               :token (config/echo-system-token)}
                              query-params)
-              gran-refs1 (search/find-granule-references context params1)
-              gran-refs2 (search/find-granule-references context params2)
-              gran-refs (distinct (concat gran-refs1 gran-refs2))
+              gran-refs (search-gran-refs-by-collection-id context params1 params2 sub-id)
               subscriber-filtered-gran-refs (filter-gran-refs-by-subscriber-id context gran-refs subscriber-id)
               _ (send-update-subscription-notification-time context sub-id)]]
     [sub-id subscriber-filtered-gran-refs email-address subscription]))


CMR-810: Changed orbit-parameters to orbit_parameters in JSON output.

--- search-app/src/cmr/search/results_handlers/atom_json_results_handler.clj
+++ search-app/src/cmr/search/results_handlers/atom_json_results_handler.clj
@@ -72,7 +72,7 @@
                        :granule_count (when granule-counts-map (get granule-counts-map id 0))
                        :links (seq (map atom/atom-link->attribute-map atom-links))
                        :coordinate_system coordinate-system
-                       :orbit-parameters (when orbit-parameters
+                       :orbit_parameters (when orbit-parameters
                                            (fix-ocsd-values orbit-parameters))}
                       shape-result)]
     ;; remove entries with nil value