Factor out item-form.

Factor out item-form.

--- src/lab_notebook/core.cljs
+++ src/lab_notebook/core.cljs
@@ -3,6 +3,43 @@
             [om.dom :as dom]))

 (defonce appstate (atom {}))
+
+(defn item-form [cursor component options]
+  (reify
+    om/IInitState
+    (init-state [this]
+      {:summary (get cursor :summary "")
+       :date-time (get cursor :date-time "")
+       :notes (get cursor :notes "")})
+    om/IRenderState
+    (render-state [this state]
+      (dom/form #js {:className "form-horizontal"}
+        (dom/input #js {:type "text"
+                        :className "form-control"
+                        :value (:summary state)
+                        :onChange (fn [e]
+                                    (om/set-state! component :summary
+                                      (-> e .-target .-value)))
+                        :placeholder "Summary"})
+        (dom/input #js {:type "text"
+                        :className "form-control"
+                        :value (:date-time state)
+                        :onChange (fn [e]
+                                    (om/set-state! component :date-time
+                                      (-> e .-target .-value)))
+                        :placeholder "Time"})
+        (dom/textarea #js {:className "form-control":placeholder "Notes"
+                           :value (:notes state)
+                           :onChange (fn [e]
+                                       (om/set-state! component :notes
+                                         (-> e .-target .-value)))
+                           :rows "5"})
+        (dom/button #js {:className "btn btn-primary"
+                         :onClick (fn [e]
+                                    (.preventDefault e)
+                                    (when-let [on-save (:on-save options)]
+                                      (on-save (:summary state) (:date-time state) (:notes state))))}
+          "Save")))))

 (defn item-view [cursor component]
   (reify
@@ -17,9 +54,7 @@
   (reify
     om/IInitState
     (init-state [this]
-      {:summary ""
-       :date-time ""
-       :notes ""})
+      {})
     om/IRenderState
     (render-state [this state]
       (dom/div nil
@@ -28,37 +63,14 @@
             (om/build item-view entry)))
         (dom/div nil
           (dom/h3 nil "New entry")
-          (dom/form #js {:className "form-horizontal"}
-            (dom/input #js {:type "text"
-                            :className "form-control"
-                            :value (:summary state)
-                            :onChange (fn [e]
-                                        (om/set-state! component :summary
-                                          (-> e .-target .-value)))
-                            :placeholder "Summary"})
-            (dom/input #js {:type "text"
-                            :className "form-control"
-                            :value (:date-time state)
-                            :onChange (fn [e]
-                                        (om/set-state! component :date-time
-                                          (-> e .-target .-value)))
-                            :placeholder "Time"})
-            (dom/textarea #js {:className "form-control":placeholder "Notes"
-                               :value (:notes state)
-                               :onChange (fn [e]
-                                           (om/set-state! component :notes
-                                             (-> e .-target .-value)))
-                               :rows "5"})
-            (dom/button #js {:className "btn btn-primary"
-                             :onClick (fn [e]
-                                        (.preventDefault e)
-                                        (om/transact! cursor :entries
-                                          (fn [entries]
-                                            ((fnil conj []) entries
-                                             {:summary (:summary state)
-                                              :date-time (:date-time state)
-                                              :notes (:notes state)}))))}
-              "Save")))))))
+          (om/build item-form {}
+            {:opts {:on-save (fn [summary date-time notes]
+                               (om/transact! cursor :entries
+                                 (fn [entries]
+                                   ((fnil conj []) entries
+                                    {:summary summary
+                                     :date-time date-time
+                                     :notes notes}))))}}))))))

 (defn app-container [cursor component]
   (reify


some style and content

some style and content

--- frontend/components/language_landing.cljs
+++ frontend/components/language_landing.cljs
@@ -25,7 +25,13 @@
                         :ss-1 "/assets/img/outer/languages/ruby-ss-1.png"
                         :ss-2 "/assets/img/outer/languages/ruby-ss-1.png"
                         :ss-3 "/assets/img/outer/languages/ruby-ss-1.png"
-                        :testimonial-author-1 "/assets/img/outer/stories/john.jpg"
+                        :feature-1-title "Built For Ruby"
+                        :feature-1 "CircleCI uses RVM to provide support for a wide variety of Ruby versions and gems. It is also trivial to add any packages or frameworks that are not installed on our machines by default, allowing you to effortlessly customize your test enviroment.  CircleCI also supports Test::Unit, RSpec, Cucumber, Spinach, Jasmine, Konacha, and just about any other testing framework you use for your Ruby project."
+                        :feature-2-title "Database Management"
+                        :feature-2 "Circle manages all your database requirements for your, such as running your rake commands for creating, loading, and migrating your database. We have pre-installed more than a dozen databases and queues, including PostgreSQL, MySQL, and MongoDB. You can also add custom database commands via your circle.yml."
+                        :feature-3-title "Inference That Just Works"
+                        :feature-3 "For the majority of Ruby projects no configuration is required; you just run your builds on CircleCI and it works! CircleCI will automatically infer your test commands if you're using Test::Unit, RSpec, Cucumber, Spinach, Jasmine, or Konacha."
+                        :docs-link "/docs/language-ruby-on-rails"
                         :testimonials [{:text "Nullam id dolor id nibh ultricies vehicula ut id elit. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Integer posuere erat a ante venenatis."
                                         :img "/assets/img/outer/stories/john.jpg"
                                         :author "Kevin Rose"
@@ -67,17 +73,17 @@
                      [:img {:src "/assets/img/outer/languages/gear-icon.png"}]
                      ]
                     [:div.feature-copy
-                     [:h4.feature-title "Testing Frameworks"
+                     [:h4.feature-title (:feature-1-title template)
                       ]
-                     [:p.feature-description "Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Maecenas faucibus mollis interdum. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Aenean lacinia bibendum nulla sed consectetur."]
+                     [:p.feature-description (:feature-1 template)]
                      ]

                     ]
                    [:div.feature
                     [:div.feature-copy
-                     [:h4.feature-title "Testing Frameworks"
+                     [:h4.feature-title (:feature-2-title template)
                       ]
-                     [:p.feature-description "Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Maecenas faucibus mollis interdum. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Aenean lacinia bibendum nulla sed consectetur."]
+                     [:p.feature-description (:feature-2 template)]
                      ]
                     [:div.feature-image
                      [:img {:src "/assets/img/outer/languages/book-icon.png"}]
@@ -88,14 +94,14 @@
                      [:img {:src "/assets/img/outer/languages/file-icon.png"}]
                      ]
                     [:div.feature-copy
-                     [:h4.feature-title "Testing Frameworks"
+                     [:h4.feature-title (:feature-3-title template)
                       ]
-                     [:p.feature-description "Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Maecenas faucibus mollis interdum. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Aenean lacinia bibendum nulla sed consectetur."]
+                     [:p.feature-description (:feature-3 template)]
                      ]

                     ]
                    [:div.button
-                    [:a {:href="#"} "Read documentation on " (:language template)]]
+                    [:a {:href (:docs-link template)} "Read documentation on " (:language template)]]
                    ]
                   ]
                  [:div.languages-testimonials {:class (arrow-class selected-testimonial)}
@@ -111,12 +117,8 @@
                     [:div.testimonial
                      [:p.testimonial-text (get-in template [:testimonials selected-testimonial :text])]

-                     [:div.testimonial-author "- " (get-in template [:testimonials selected-testimonial :author])]
+                     [:div.testimonial-author "—" (get-in template [:testimonials selected-testimonial :author])]
                      [:div.testimonial-author-title (get-in template [:testimonials selected-testimonial :title])]]
-                    ;;[:div.testimonial
-                    ;;[:div.testimonial-text (:testimonial-2 template)]]
-                    ;;[:div.testimonial
-                    ;;[:div.testimonial-text (:testimonial-3 template)]]
                     ]
                    ]
                   ]
@@ -128,17 +130,32 @@
                    [:div.languages-cta-steps
                     [:div.languages-cta-step
                      [:div.step-number "1"]
-                      "Start by signing up using GitHub"
+                     [:div
+                      "Start by signing up "
+                      [:br]
+                      "using GitHub"]
                      ]
-                     [:div.languages-cta-step
-                      [:div.step-number "2"]
-                      "Run one of your Ruby projects on Circle"]
-                     [:div.languages-cta-step
-                      [:div.step-number "3"]
-                      "That's it! If you hit any problems just us a message and we'll help you out."]
-                     ]
-                   [:a.languages-cta-button {:href="#"}
-                    "Sign Up With GitHub"]
+                    [:div.languages-cta-step
+                     [:div.step-number "2"]
+                     [:div
+                      "Run one of your Ruby projects on Circle"]]
+                    [:div.languages-cta-step
+                     [:div.step-number "3"]
+                     [:div
+                      [:strong "That's it!"]
+                      " Contact support if you run in to any issues. "]
+                     ]]
+                   [:div.cta-divider]
+                   [:div.center-text
+                    [:a.languages-cta-button
+                     ;come back to this
+                     ;{:href (auth-url)
+                     ;:on-click #(put! controls-ch [:track-external-link-clicked {:event "Auth GitHub"
+                     ;                                                           :properties {:source (:language template) "page"}
+                     ;                                                          :path (auth-url)}])}
+                     "Sign Up With GitHub"]
+                    [:div.language-cta-trial "14-day free trial"]
+                    ]
                    ]]

                  ])))))


Improve icons

Improve icons

--- frontend/components/language_landing.cljs
+++ frontend/components/language_landing.cljs
@@ -57,7 +57,7 @@
                          :icon (utils/cdn-path "/img/outer/languages/gear-icon.svg")}
                         {:feature "CircleCI intelligently determines the best way to run your tests using 'nosetests', 'tox', or Django. We also provide complete flexibility to override our inferred commands with your own custom commands via the circle.yml."
                          :title "Intelligent Test Running"
-                         :icon (utils/cdn-path "/img/outer/languages/file-icon.svg")}
+                         :icon (utils/cdn-path "/img/outer/languages/book-icon.svg")}
                         {:feature "CircleCI makes setting up Continuous Delivery for your Python application simple and easy. We offer first-class support for deployment to platforms like with Heroku, Elastic Beanstalk, and Google App Engine as well as using tools like Fabric, Ansible, Salt, and others."
                          :title "Easy Continuous Delivery"
                          :icon (utils/cdn-path "/img/outer/languages/cycle.svg")}]


Add tests for timeout and timeout with choice.

--- test/beicon/core_spec.cljs
+++ test/beicon/core_spec.cljs
@@ -96,6 +96,24 @@
       (t/is (s/observable? s))
       (drain! s #(t/is (= % [1 2 3])))
       (s/on-end s done))))
+
+(t/deftest observable-from-timeout
+  (t/async done
+    (let [s (s/timeout 1000 :timeout)]
+      (t/is (s/observable? s))
+      (drain! s #(do
+                   (t/is (= % [:timeout]))
+                   (done))))))
+
+(t/deftest observable-from-timeout-and-choice
+  (t/async done
+    (let [s (s/choice
+             (s/timeout 1000 :timeout)
+             (s/timeout 900 :value))]
+      (t/is (s/observable? s))
+      (drain! s #(do
+                   (t/is (= % [:value]))
+                   (done))))))

 (t/deftest observable-errors-from-binder
   (t/async done


Add an explicit test case for reading bgzipped VCF sequentially

--- test/cljam/io/vcf_test.clj
+++ test/cljam/io/vcf_test.clj
@@ -116,9 +116,11 @@
       (is (= (vcf/read-variants rdr) test-vcf-no-samples-variants-deep)))))

 (deftest read-variants-complex-test
-  (with-open [v (vcf/reader test-vcf-complex-file)
-              b (vcf/reader test-bcf-complex-file)]
+  (with-open [v (vcf/reader test-vcf-complex-file)    ;; uncompressed VCF
+              z (vcf/reader test-vcf-complex-gz-file) ;; bgzipped VCF
+              b (vcf/reader test-bcf-complex-file)]   ;; bgzipped BCF
     (is (= (vcf/read-variants v)
+           (vcf/read-variants z)
            (vcf/read-variants b)))))

 (deftest-remote bin-index-is-done-without-errors-with-a-large-file


log error if JWToken is expired

log error if JWToken is expired

--- src/open_company/lib/jwt.clj
+++ src/open_company/lib/jwt.clj
@@ -1,20 +1,28 @@
 (ns open-company.lib.jwt
-  (:require [clj-jwt.core :refer :all]
+  (:require [clj-jwt.core :as jwt]
+            [taoensso.timbre :as timbre]
+            [clj-time.core :as t]
+            [clj-time.coerce :as tc]
             [open-company.config :as config]))
+
+(defn expired?
+  [jwt-claims]
+  (t/after? (t/now) (tc/from-long (:expire jwt-claims))))

 (defn check-token
   "Verify a JSON Web Token"
   [token]
   (try
-    (do
-      (-> token
-        str->jwt
-        (verify config/passphrase))
-      true)
+    (let [jwt (-> token jwt/str->jwt)]
+      (when (expired? (:claims jwt))
+        (timbre/error "Request made with expired JWToken" (:claims jwt)))
+      (do
+        (-> token jwt/str->jwt (jwt/verify config/passphrase))
+        true))
     (catch Exception e
       false)))

 (defn decode
   "Decode a JSON Web Token"
   [token]
-  (str->jwt token))+  (jwt/str->jwt token))


db/docids.clj: use S3 instead of SimpleDB

--- src/org/altlaw/db/docids.clj
+++ src/org/altlaw/db/docids.clj
@@ -1,45 +1,23 @@
-(ns org.altlaw.db.docids
-  (:require [org.altlaw.util.simpledb :as db]))
+(ns org.altlaw.util.docids)

-;;; PRIVATE
+(def #^{:private true} *bucket* "altlaw.org")

-(def #^{:private true} *domain* "Docids")
+(defn- path [collection]
+  (str "v5/docids/" collection ".tsv.gz"))

-(defn- make-db-key [collection-name collection-key]
-  (let [s (str collection-name ":" collection-key)]
-    ;; Ensure the key fits within SimpleDB's 1024-byte limit
-    (if (< (count s) 1024)
-      s (subs s 0 1024))))
+(defn load-docids [collection]
+  (read-tsv-stream (get-object-stream *bucket* (path collection))))

-(def #^{:private true} *number-format* "%010d")
+(defn save-docids [collection])

-(def #^{:private true} *base-number-string*
-     (format *number-format* 10000))
-
-;;; PUBLIC
+(def get-docid-map (memoize (load-docids)))

 (defn get-docid [collection key]
-  (when-let [string (get (db/get-attrs *domain*
-                                     (make-db-key collection key))
-                       "docid")]
-    ;; Integer/parseInt ignores leading zeros
-    (Integer/parseInt string)))
+  (get @(get-docid-map collection) key))

-(defn put-docid [collection key docid]
-  (db/put-attrs *domain* (make-db-key collection key)
-                {:collection collection
-                 :key key
-                 ;; Add leading zeros for lexicographic ordering
-                 :docid (format *number-format* docid)}))
+(defn set-docid [collection keys docid]
+  (dosync (alter @(get-docid-map collection)
+                 merge (zipmap keys (repeat docid)))))

-(defn delete-docid [collection key]
-  (db/delete-item *domain* (make-db-key collection key)))
+(defn request-docid [collection keys])

-(defn max-docid []
-  (let [result (db/select-items
-                *domain*
-                (str "select docid from Docids where docid > "
-                     \' *base-number-string* \'
-                     " order by docid desc limit 1"))]
-    (Integer/parseInt (get (first (vals result)) "docid"))))
-


Cleaned up some RabbitMQ on Mesos related logic

--- src/clojure/funcatron/tron/brokers/rabbitmq.clj
+++ src/clojure/funcatron/tron/brokers/rabbitmq.clj
@@ -53,14 +53,29 @@
     (handle-rabbit-request handler broker ch metadata payload)
     ))

+(def ^:private delay-once (delay
+                            (Thread/sleep 2000)
+                            42))
+
 (defn- compute-mesos-rabbit-props
   "If we're running in Mesos, use DNS to look up the rabbit host and port"
   []
   (if (fu/in-mesos?)
-    (->
-      (fu/dns-lookup "_rabbit._rabbit-funcatron._tcp.marathon.mesos")
-      first
-      (select-keys [:host :port]))
+    (do
+      (loop [cnt 0]
+        (let [ret
+              (->
+                (fu/dns-lookup "_rabbit._rabbit-funcatron._tcp.marathon.mesos")
+                first
+                )]
+          ;; try 8 times to find the RabbitMQ server with some backoff
+          (if ret
+            {:hosts [(:host ret)] :port (:port ret)}
+            (if (< cnt 8)
+              (do (Thread/sleep (* 1000 (inc cnt)))
+                  (recur (inc cnt)))
+              nil))
+          )))
     {}))

 (defn- fix-props


[Fix #312] Local tests without mranderson

--- test/global_test_setup.clj
+++ test/global_test_setup.clj
@@ -1,7 +1,11 @@
 (ns global-test-setup
-  "This namespace's contents will be automatically loaded by `lein test` (or any test runner)."
-  (:require
-   [refactor-nrepl.inlined-deps.toolsnamespace.v1v1v0.clojure.tools.namespace.repl :refer [set-refresh-dirs]]))
+  "This namespace's contents will be automatically loaded by `lein test` (or any test runner).")
+
+(try
+  (require '[refactor-nrepl.inlined-deps.toolsnamespace.v1v1v0.clojure.tools.namespace.repl :refer [set-refresh-dirs]])
+  (catch Exception _
+    (require
+     '[clojure.tools.namespace.repl :refer [set-refresh-dirs]])))

 (when (System/getenv "CI") ; don't alter local environments (which may also use clojure.tools.namespace.repl)
   ;; Intentionally exclude the `lein-plugin/` source path:


Don't mark comments as new

Don't mark comments as new

--- iwaswhere-web/src/cljs/iwaswhere_web/ui/edit.cljs
+++ iwaswhere-web/src/cljs/iwaswhere_web/ui/edit.cljs
@@ -45,7 +45,7 @@
             update-temp-fn #(let [updated-entry (merge latest-entry (h/parse-entry (get-content %)))]
                              (put-fn [:entry/update-local updated-entry])
                              (reset! local-saved-entry updated-entry))
-            save-fn #(put-fn [:text-entry/update (if new-entry?
+            save-fn #(put-fn [:text-entry/update (if (and new-entry? (not (:comment-for entry)))
                                                    (update-in (h/clean-entry @local-saved-entry) [:tags] conj "#new")
                                                    (h/clean-entry @local-saved-entry))])


fix prep to check indentation even when stack is empty (caused all lines after first expression to be dedented)

--- src/parinfer/format/prep.cljc
+++ src/parinfer/format/prep.cljc
@@ -112,7 +112,11 @@
                   :backup []
                   :cursor-in-comment? false
                   :delim-trail {:start nil :end nil}
-                  :track-indent? (and (seq stack) (not (in-str? stack)))
+
+                  ;; different from process-line in parinfer.format.infer
+                  ;; (even if the stack is empty, we still have to track indentation)
+                  :track-indent? (not (in-str? stack))
+
                   :lines (conj lines "")
                   :line-no line-no
                   :removed-delims [])


fixing test description

fixing test description

--- test/restaurant_inspections_api/services_test.clj
+++ test/restaurant_inspections_api/services_test.clj
@@ -52,7 +52,7 @@
         (is (= (first (:violations json)) {:id 3, :count 1}))
         (is (= (:totalViolations json) 11))))
     ;; TODO: test given full results, gets fully correctly formatted object
-    (testing "Given empty results, returns"
+    (testing "Given empty results, returns object with all keys nil"
       (is (= (srv/format-data nil) {:basicViolations nil,
                                     :businessName nil,
                                     :countyName nil,


Added FreeBSD to native names in order for lien swank to wark on FreeBSD

--- src/leiningen/compile.clj
+++ src/leiningen/compile.clj
@@ -50,6 +50,7 @@
      {"Mac OS X" :macosx
       "Windows" :windows
       "Linux" :linux
+      "FreeBSD" :freebsd
       "SunOS" :solaris
       "amd64" :x86_64
       "x86_64" :x86_64


Update docstring

Update docstring

--- src/leiningen/new/sim.clj
+++ src/leiningen/new/sim.clj
@@ -5,7 +5,7 @@
 (def render (renderer "sim"))

 (defn sim
-  "FIXME: write documentation"
+  "Generate a sim project"
   [name]
   (let [sanitized-ns (sanitize-ns name)
         data {:raw-name name


Remove Spline

Remove Spline

--- src-cljs/frontend/components/insights/project.cljs
+++ src-cljs/frontend/components/insights/project.cljs
@@ -73,7 +73,6 @@
         (js/c3.generate (clj->js {:bindto el
                                   :padding {:top 10}
                                   :data {:x "date"
-                                         :type "spline"
                                          :columns [(concat ["date"] (map first build-times))
                                                    (concat ["Median Build Time"] (map last build-times))]}
                                   :legend {:hide true}


debugged spinner spinning forever when no failed tests

--- src-cljs/frontend/components/insights/project.cljs
+++ src-cljs/frontend/components/insights/project.cljs
@@ -229,7 +229,7 @@
             :target "_blank"}
         "test metadata documentation"]
        "."]
-      (and (not (nil? tests))
+      (and (nil? tests)
            (empty? tests))
       [:span "No failed tests to show."]


add two new possessive NP tests

add two new possessive NP tests

--- test/babel/test/en.cljc
+++ test/babel/test/en.cljc
@@ -138,3 +138,25 @@

 (deftest the-dogs-house
   (is (not (empty? (parse "the dogs' house")))))
+
+(deftest generate-with-possessive-1
+  (let [result
+        (generate {:synsem {:cat :noun
+                            :sem {:number :sing
+                                  :spec {:pred :of
+                                         :of {:pred :Juana}}
+                                  :pred :cane}}})]
+    (is (not (nil? result)))
+    (is (= "Juana's dog" (fo result)))))
+
+(deftest generate-with-possessive-2
+  (let [result
+        (generate {:synsem {:cat :noun
+                            :sem {:mod {:pred :rosso}
+                                  :number :sing
+                                  :spec {:pred :of
+                                         :of {:pred :Juana}}
+                                  :pred :cane}}})]
+    (is (not (nil? result)))
+    (is (= "Juana's red dog" (fo result)))))
+


prefix tests with 'generate-' where needed

--- test/babel/test/fr.cljc
+++ test/babel/test/fr.cljc
@@ -42,7 +42,7 @@
          true
          (over/over grammar arg1 arg2))))

-(deftest conditional
+(deftest generate-conditional
   (let [result (engine/generate {:synsem {:subcat '()
                                           :sem {:pred :sleep
                                                 :subj {:pred :I}
@@ -50,7 +50,7 @@
                                 small)]
     (is (= "je dormirais" (fo result)))))

-(deftest present-irregular
+(deftest generate-present-irregular
   (let [result (engine/generate {:synsem {:subcat '()
                                           :sem {:pred :be
                                                 :subj {:pred :I}
@@ -58,7 +58,7 @@
                                 small)]
     (is (= "je suis" (fo result)))))

-(deftest imperfect-irregular-être
+(deftest generate-imperfect-irregular-être
   (let [result (engine/generate {:synsem {:subcat '()
                                           :infl :imperfect
                                           :sem {:pred :be
@@ -67,7 +67,7 @@
                                 small)]
     (is (= "j'étais" (fo result)))))

-(deftest imperfect-irregular-avoir
+(deftest generate-imperfect-irregular-avoir
   (let [result (engine/generate {:synsem {:subcat '()
                                           :infl :imperfect
                                           :sem {:pred :have
@@ -165,7 +165,7 @@
                   :français "sommes"}}}}]
     (is (= (fo result) "nous sommes allées"))))

-(deftest passe-compose-1
+(deftest generate-passe-compose-1
   (let [result
         (forest/generate (unifyc
                           {:synsem {:subcat '()}}
@@ -181,7 +181,7 @@
     (and (is (not (nil? result)))
          (is (= (fo result) "nous sommes allées")))))

-(deftest passe-compose
+(deftest generate-passe-compose
   (let [result (engine/generate {:synsem {:sem {:pred :go
                                                 :subj {:pred :noi
                                                        :gender :fem}
@@ -191,7 +191,7 @@
     (is (not (nil? result)))
     (is (= (fo result) "nous sommes allées"))))

-(deftest reflexive
+(deftest generate-reflexive-present
   (let [rules {:s-present-phrasal
                (first (filter #(= (get % :rule) "s-present-phrasal")
                               (:grammar medium)))
@@ -206,12 +206,12 @@
     (is (= (fo (first result))
            "je m'amuse"))))

-(deftest have-fun-sentence
+(deftest generate-have-fun-sentence
   (let [result (engine/expression medium
                                   {:synsem {:sem {:pred :have-fun}}})]
     (is (= (get-in result [:synsem :sem :pred]) :have-fun))))

-(deftest vp-aux-reflexive
+(deftest generate-vp-aux-reflexive
   (let [result
         (engine/expression
          medium
@@ -219,7 +219,7 @@
                                      :pred :have-fun :tense :past}}})]
     (is (= (fo result) "elle l'est amusée"))))

-(deftest named-sentence
+(deftest generate-named-sentence
   (let [result (engine/expression medium
                                   {:synsem {:sem {:pred :be-called
                                                   :subj {:pred :lui}


add benchmark function

add benchmark function

--- test/babel/test/it.cljc
+++ test/babel/test/it.cljc
@@ -78,8 +78,6 @@
 (deftest forbid-mispelling
  (is (empty? (parse (fo "la donna difficila") np-grammar))))

-;;babel.test.it> (take 1000 (repeatedly #(let [generated (fo (generate :top)) parsed (parse generated medium)] (log/info (str "generated: " generated)) (log/info (str "semantics: " (or (strip-refs (get-in (first parsed) [:synsem :sem])) "NO PARSE FOUND FOR: " generated))))))
-
 ;; <roundtrip parsing tests>
 ;; these tests will not pass if you
 ;; don't have enough linguistic material
@@ -224,5 +222,18 @@
          "noi abbiamo bevuto la loro acqua bella"
          "Luisa e io abbiamo bevuto la loro acqua bella"])))

-;; benchmark:
-;;(take 1 (repeatedly #(time (get-in (first (parse "Luisa e io abbiamo bevuto la loro acqua bella" medium)) [:synsem :sem :pred]))))
+;; roundtrip parser testing
+(defn roundtrip-parsing [n]
+  (take n
+        (repeatedly #(let [generated
+                           (fo (generate {:synsem {:cat :verb
+                                                   :subcat '()}}))
+                           parsed (parse generated medium)]
+                       (log/info (str "generated: " generated))
+                       (log/info (str "semantics: "
+                                      (or (strip-refs (get-in (first parsed) [:synsem :sem]))
+                                          (str "NO PARSE FOUND FOR: " generated))))
+                       {:generated generated
+                        :pred (get-in (first parsed) [:synsem :sem :pred])
+                        :subj (get-in (first parsed) [:synsem :sem :subj :pred])}))))
+


correctly do that logic

correctly do that logic

Signed-off-by: Chris Granger <5654cde260ae99bc4d30054171b8bcd902efd19a@gmail.com>

--- lein-light-nrepl/src/lighttable/nrepl/eval.clj
+++ lein-light-nrepl/src/lighttable/nrepl/eval.clj
@@ -109,7 +109,8 @@
       )))

 (defn prep-code [{:keys [code meta]}]
-  (if-not (or meta (not (:start meta)))
+  (if (or (not meta)
+          (not (:start meta)))
     code
     (str (reduce str "" (repeat (:start meta 0) "\n"))
          code)))


List commercial audio books w/o audio

List commercial audio books w/o audio

--- src/mdr2/abacus/import.clj
+++ src/mdr2/abacus/import.clj
@@ -245,32 +245,32 @@
   (println "~~~~~~~~~~~~~~~~~~~~~")
   (println)
   (println "Ready:" (count (filter ready? all-productions)))
-  (println "-----")
+  (println "------")
   (println (string/join ", " (map :id (filter ready? all-productions))))
   (println)
   (println "Archived:" (count (filter archived? all-productions)))
-  (println "--------")
+  (println "---------")
   (println)
   (println "Recording with no wav and a struct.html:" (count (filter #(recording-no-wav-with-struct? %) all-productions)))
-  (println "---------------------------------------")
+  (println "----------------------------------------")
   (println (string/join ", " (map :id (filter #(recording-no-wav-with-struct? %) all-productions))))
   (println)
   (let [weird (filter #(and (not-any? struct-file? (get-all-files %)) (recording-no-wav? %)) all-productions)]
     (println "Recording with no wav and no struct.html:" (count weird))
-    (println "----------------------------------------")
+    (println "-----------------------------------------")
     (println (string/join ", " (map :id weird))))
   (println)
   (println "Recording with wav and an obi project:" (count (filter recording-with-obi? all-productions)))
-  (println "-------------------------------------")
+  (println "--------------------------------------")
   (println (string/join ", " (map :id (filter recording-with-obi? all-productions))))
   (println)
   (println "Recording with wav and no obi project:" (count (filter recording-with-wav-no-obi? all-productions)))
-  (println "-------------------------------------")
+  (println "--------------------------------------")
   (println (string/join ", " (map :id (filter recording-with-wav-no-obi? all-productions))))
   (println)
   (print "Ignoring the rest: ")
   (println (dissoc (frequencies (map :state all-productions)) "archived" "recording" "ready"))
-  (println "-----------------")
+  (println "------------------")
   (doseq [state ["repairing" "finishing" "recorded" "pre_ready"]]
     (println (str (string/capitalize state) ":") (string/join ", " (map :id (filter #(= (:state %) state) all-productions)))))
   (println )
@@ -278,32 +278,32 @@
   (println "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
   (println)
   (println "Ready:" (count (filter ready? all-commercial-productions)))
-  (println "-----")
+  (println "------")
   (println (string/join ", " (map :id (filter ready? all-commercial-productions))))
   (println)
   (println "Archived:" (count (filter archived? all-commercial-productions)))
-  (println "--------")
+  (println "---------")
   (println)
   (println "Recording with no wav and a struct.html:" (count (filter #(recording-no-wav-with-struct? %) all-commercial-productions)))
-  (println "---------------------------------------")
+  (println "----------------------------------------")
   (println (string/join ", " (map :id (filter #(recording-no-wav-with-struct? %) all-commercial-productions))))
   (println)
-  (let [weird (filter #(and (not-any? struct-file? (get-all-files %)) (recording-no-wav? %)) all-commercial-productions)]
-    (println "Recording with no wav and no struct.html:" (count weird))
-    (println "----------------------------------------")
+  (let [weird (filter #(and (recording-no-wav? %)) all-commercial-productions)]
+    (println "Recording with no wav:" (count weird))
+    (println "----------------------")
     (println (string/join ", " (map :id weird))))
   (println)
   (println "Recording with wav and an obi project:" (count (filter recording-with-obi? all-commercial-productions)))
-  (println "-------------------------------------")
+  (println "--------------------------------------")
   (println (string/join ", " (map :id (filter recording-with-obi? all-commercial-productions))))
   (println)
   (println "Recording with wav and no obi project:" (count (filter recording-with-wav-no-obi? all-commercial-productions)))
-  (println "-------------------------------------")
+  (println "--------------------------------------")
   (println (string/join ", " (map :id (filter recording-with-wav-no-obi? all-commercial-productions))))
   (println)
   (print "Ignoring the rest: ")
   (println (dissoc (frequencies (map :state all-commercial-productions)) "archived" "recording" "ready"))
-  (println "-----------------")
+  (println "------------------")
   (doseq [state ["structuring" "wipsing"]]
     (println (str (string/capitalize state) ":") (string/join ", " (map :id (filter #(= (:state %) state) all-commercial-productions)))))
   (println )


Flash strobe cues.

Flash strobe cues.


Add parameter for adjusting square pulse width.

Now that the issue with cue creation is fixed, this works.

--- src/afterglow/examples.clj
+++ src/afterglow/examples.clj
@@ -532,15 +532,15 @@
                          (fn [var-map] (dimmer-effect
                                         (oscillators/build-oscillated-param
                                          (oscillators/square :interval-ratio (build-ratio-param var-map)
-                                                             #_:width #_(params/bind-keyword-param (:width var-map)
+                                                             :width (params/bind-keyword-param (:width var-map)
                                                                                Number 0.5)))
                                         fixtures
                                         :effect-name effect-name))
                          :color color
                          :variables [{:key "beats" :min 1 :max 32 :type :integer :start :starting-beats :name "Beats"}
+                                     {:key "width" :min 0 :max 1 :start :starting-width :name "Width"}
                                      {:key "cycles" :min 1 :max 10 :type :integer :start :starting-cycles
-                                      :name "Cycles"}
-                                     {:key "width" :min 0 :max 1 :start :starting-width :name "Width"}]
+                                      :name "Cycles"}]
                          :end-keys end-keys))))

 (defn x-phase


slowing down the blues...

slowing down the blues...

--- test/examples/blues.clj
+++ test/examples/blues.clj
@@ -78,14 +78,14 @@
 (defn blue-ks1 []
   (play-seq 0 ks1
             (cycle (map sort (progression blues-chords :a 2 :ionian)))
-            (cycle [530 524 532 528])
+            (take 80 (map #(* 1.5 %) (cycle [530 524 532 528])))
             (now)
             0.5))

 (defn blue-ks1-demo []
   (play-seq 0 ks1-demo
             (cycle (map sort (progression blues-chords :a 2 :ionian)))
-            (take 20 (cycle [530 524 532 528]))
+            (take 80 (map #(* 1.5 %) (cycle [530 524 532 528])))
             (now)
             0.5))


GAWB-1821: cannot set root entity type when importing method into workspace

--- src/cljs/main/broadfcui/page/method_repo/method_config_importer.cljs
+++ src/cljs/main/broadfcui/page/method_repo/method_config_importer.cljs
@@ -74,11 +74,10 @@
         (fn [field]
           [:div {:style {:float "left" :marginRight "0.5em"}}
            (style/create-form-label (:label field))
-           (cond (= (:type field) "identity-select")
-             (style/create-identity-select {:ref (:key field)
-                                            :value (or (entity (:key field)) "")}
+           (if (= (:type field) "identity-select")
+             (style/create-identity-select
+               {:ref (:key field) :defaultValue (or (entity (:key field)) "")}
                (:options field))
-             :else
              [input/TextField {:defaultValue (entity (:key field))
                                :ref (:key field) :placeholder "Required"
                                :predicates [(input/nonempty "Fields")]}])])
@@ -182,7 +181,7 @@
           {:label "Configuration Name" :key "name"}
           {:label "Root Entity Type" :key "rootEntityType" :type "identity-select" :options root-entity-types}])

-       (:error @state) (style/create-server-error-message (:error @state))
+       (:error @state) (style/create-server-error-message (:error @state))`
        :else [comps/Spinner {:text "Creating template..."}]))
    :perform-copy
    (fn [{:keys [props state refs]}]


Implement on-click handler for dropdown items

--- src/reabledit/components.cljs
+++ src/reabledit/components.cljs
@@ -78,7 +78,11 @@
           (for [{:keys [key value]} options]
             ^{:key key}
             [:div.reabledit-dropdown-item
-             {:class (if (= key chosen-key) "selected")}
+             {:class (if (= key chosen-key) "selected")
+              :on-click (fn [e]
+                          (.stopPropagation e)
+                          (reset! cursor key)
+                          (disable-edit!))}
              [:span value]])]]))
     {:component-did-mount
      (fn [this]


Correct error computing y-grid interval for bottom half of grid with 0 in Y.

--- metlog-vault/src-client/metlog_client/tsplot.cljs
+++ metlog-vault/src-client/metlog_client/tsplot.cljs
@@ -163,7 +163,7 @@
   (if (range-contains-zero? y-range)
     (if (> (:max y-range) (.abs js/Math (:min y-range)))
       {:t (/ (:max y-range) (range-magnitude y-range)) :magnitude (:max y-range)}
-      {:t (/ (:max y-range) (range-magnitude y-range)) :magnitude (- (:min y-range))})
+      {:t (.abs js/Math (/ (:min y-range) (range-magnitude y-range))) :magnitude (- (:min y-range))})
     {:t 1.0 :magnitude (range-magnitude y-range) }))

 (defn find-y-grid-interval [ h y-range ]
@@ -189,9 +189,7 @@
     (draw-line ctx [ 0 y ] [ w y ])))

 (defn adjust-range-to-interval [ range interval ]
-  {:min (let [ value (:min range) ]
-          (* interval
-             (.floor js/Math (/ (+ value interval) interval))))
+  {:min (* interval (.floor js/Math (/ (+ (:min range) interval) interval)))
    :max (:max range)})

 (defn draw-y-grid [ ctx w h y-range ]


reset new-provider

reset new-provider

--- src/mediakeys/hotkeys.clj
+++ src/mediakeys/hotkeys.clj
@@ -14,7 +14,7 @@

 (def current-keys (atom DEFAULT_KEYS))

-(defn register-keys! [provider keys]
+(defn register-keys! [^Provider provider keys]
     (observable
         (fn [s]
             (doseq [[action hotkey] keys
@@ -37,5 +37,5 @@
                   result (register-keys! new-provider new-keys)]
                 (.reset @provider)
                 (.stop @provider)
-                (reset! provider)
+                (reset! provider new-provider)
                 result))))


Fix Bug with Movies List Response

Fix Bug with Movies List Response

--- src/movie_app/response.clj
+++ src/movie_app/response.clj
@@ -56,12 +56,13 @@
 (defn get-rated-movies []
   (for [movie (db/get-maps "movies")]
     (assoc movie :stars (gen-stars-per-movie (:_id movie))
-           :reviews (get-movie-reviews (:_id movie)))))
+           :reviews (get-movie-reviews (:_id movie))
+           )))

 ;;; Response endpoints that include movie and review information

 (defn get-movies-list []
-  (let [result get-rated-movies]
+  (let [result (get-rated-movies)]
     (result-nil? result)))

 (defn get-movie-entry [id-string]


Add buffer get number api wrapper

Add buffer get number api wrapper

--- src/neovim_client/nvim.clj
+++ src/neovim_client/nvim.clj
@@ -29,6 +29,7 @@
 (defvim buffer-get-line "buffer_get_line" buffer line-num)
 (defvim buffer-line-count "buffer_line_count" buffer)
 (defvim buffer-get-name "buffer_get_name" buffer)
+(defvim buffer-get-number "buffer_get_number" buffer)
 (defvim buffer-get-var "buffer_get_var" buffer var-name)
 (defvim buffer-set-line "buffer_set_line" buffer line-num line)
 (defvim vim-call-function "vim_call_function" f-name args)


can now choose only dictionaries

can now choose only dictionaries

--- src/ocr_evaluator/core.clj
+++ src/ocr_evaluator/core.clj
@@ -1,4 +1,3 @@
-
 (ns ocr-evaluator.core
   (:require [seesaw.core :refer :all]
             [seesaw.chooser :refer :all]
@@ -36,7 +35,7 @@
                         [:action
                          (fn [& args]
                            (value! gt-dir
-                                   (.getPath (choose-file))))])])
+                                   (.getPath (choose-file :selection-mode :dirs-only))))])])
               "Ordner mit OCR"
               (flow-panel
                :items
@@ -46,7 +45,7 @@
                         [:action
                          (fn [& args]
                            (value! ocr-dir
-                                   (.getPath (choose-file))))])])
+                                   (.getPath (choose-file :selection-mode :dirs-only))))])])
               "Zielordner für Ergebnisse"
               (flow-panel
                :items
@@ -57,7 +56,7 @@
                          (fn [& args]
                            (prn "hi")
                            (value! target-dir
-                                   (.getPath (choose-file))))])])
+                                   (.getPath (choose-file :selection-mode :dirs-only))))])])
               ""
               (button :text "Auszählung starten"
                       :listen
@@ -92,7 +91,7 @@
                         [:action
                          (fn [& args]
                            (value! param-dir
-                                   (.getPath (choose-file))))])])
+                                   (.getPath (choose-file :selection-mode :dirs-only))))])])
               "Eingabeordner"
               (flow-panel
                :items
@@ -102,7 +101,7 @@
                         [:action
                          (fn [& args]
                            (value! input-dir
-                                   (.getPath (choose-file))))])])
+                                   (.getPath (choose-file :selection-mode :dirs-only))))])])
               "Ausgabeordner"
               (flow-panel
                :items
@@ -112,7 +111,7 @@
                         [:action
                          (fn [& args]
                            (value! output-dir
-                                   (.getPath (choose-file))))])])
+                                   (.getPath (choose-file :selection-mode :dirs-only))))])])
               ""
               (button :text "Nachkorrektur starten"
                       :listen


More params for jGroups.

More params for jGroups.

--- src/onyx/queue/hornetq.clj
+++ src/onyx/queue/hornetq.clj
@@ -36,7 +36,9 @@
     (HornetQClient/createServerLocatorWithHA gdc)))

 (defmethod connect-to-locator :jgroups
-  [{:keys [hornetq.jgroups/file hornetq.jgroups/channel-name]}]
+  [{:keys [hornetq.jgroups/cluster-name hornetq.jgroups/refresh-timeout
+           hornetq.jgroups/discovery-timeout hornetq.jgroups/file
+           hornetq.jgroups/channel-name]}]
   (let [jgroups (JGroupsBroadcastGroupConfiguration. file channel-name)
         gdc (DiscoveryGroupConfiguration. cluster-name refresh-timeout discovery-timeout jgroups)]
     (HornetQClient/createServerLocatorWithHA gdc)))


integrated dial into mixer to control pan

--- src/overtone/gui/mixer.clj
+++ src/overtone/gui/mixer.clj
@@ -1,6 +1,7 @@
 (ns overtone.gui.mixer
   (:use [seesaw core border]
         overtone.studio.rig
+        overtone.gui.dial
         [overtone.libs event])
   (:require [seesaw.bind :as bind]))

@@ -16,8 +17,7 @@
   (let [v-slider (slider :value (* @(:volume ins) 100.0) :min 0 :max 100
                     :orientation :vertical)
         vsp (border-panel :center v-slider)
-        p-slider (slider :value (* @(:pan ins) 100) :min -100 :max 100
-                         :orientation :horizontal)
+        p-slider (dial :min -100 :max 100 :value (* @(:pan ins)))
         mute-state (atom false)
         mute-toggle #(if @mute-state
                        (do


reload samples correctly

reload samples correctly

--- src/overtone/sc/sample.clj
+++ src/overtone/sc/sample.clj
@@ -128,10 +128,11 @@
       files)))

 (defn- reload-all-samples []
-  (reset! cached-samples* {})
-  (reset! loaded-samples* {})
-  (doseq [smpl (vals @loaded-samples*)]
-    (apply load-sample* (:path smpl) (:args smpl))))
+  (let [previously-loaded-samples (vals @loaded-samples* )]
+    (reset! cached-samples* {})
+    (reset! loaded-samples* {})
+    (doseq [smpl previously-loaded-samples]
+      (apply load-sample* (:path smpl) (:args smpl)))))

 (on-deps :server-ready ::load-all-samples reload-all-samples)


Fix closing buffer scopes - it doesn't need to free the buffer.

--- src/overtone/viz/scope.clj
+++ src/overtone/viz/scope.clj
@@ -149,10 +149,7 @@
   [s]
   (log/info (str "Closing scope: \n" s))
   (let [{:keys [id bus-synth buf]} s]
-    (if bus-synth
-      (kill bus-synth))
-    (if buf
-      (buffer-free buf))
+    (when bus-synth (kill bus-synth))
     (dosync (alter scopes* dissoc id))))

 (defn- mk-scope


Test for merge-timelines

Test for merge-timelines

--- test/tick/core_test.clj
+++ test/tick/core_test.clj
@@ -41,6 +41,14 @@
   (is (every? good-friday? (good-fridays (-> "1900-01-01" LocalDate/parse))))
   (is (every? easter-monday? (easter-mondays (-> "1900-01-01" LocalDate/parse)))))

+(deftest merge-timelines-test
+  (let [merged
+        (merge-timelines
+         [(take 10 (periodic-seq (.plus (just-now) (seconds 10)) (minutes 1)))
+          (take 10 (periodic-seq (just-now) (minutes 1)))])]
+    (is (distinct? merged))
+    (is (= 20 (count merged)))))
+
 (deftest schedule-test
   (let [a (atom 0)
         f (fn [dt] (swap! a inc))


Begin generalizing error-reporting out from fakes.

--- src/midje/unprocessed.clj
+++ src/midje/unprocessed.clj
@@ -59,17 +59,23 @@
         (catch Throwable e#
           (captured-exception e#))))

+;; This is a macro to get line numbers to come out right. Feh.
+(defmacro reported-on-user-errors? [call-map local-fakes]
+  `(let [broken-fakes# (filter broken-fake? ~local-fakes)]
+     (report-broken-fakes broken-fakes#)
+     (not (empty? broken-fakes#))))
+
+
+
 (defn expect* [call-map local-fakes]
   "The core function in unprocessed Midje. Takes a map describing a call and a
    list of maps, each of which describes a secondary call the first call is supposed to
    make. See the documentation at http://github.com/marick/Midje."
-  (let [fakes (background-fakes-plus local-fakes)
-        broken-fakes (filter broken-fake? fakes)]
-    (if (empty? broken-fakes)
-      (with-altered-roots (binding-map fakes)
-        (let [code-under-test-result (capturing-exception
-                                      (eagerly
-                                       ((call-map :function-under-test))))]
-          (check-call-counts fakes)
-          (check-result code-under-test-result call-map)))
-      (report-broken-fakes broken-fakes))))
+  (let [fakes (background-fakes-plus local-fakes)]
+    (or (reported-on-user-errors? call-map local-fakes)
+        (with-altered-roots (binding-map fakes)
+          (let [code-under-test-result (capturing-exception
+                                        (eagerly
+                                         ((call-map :function-under-test))))]
+            (check-call-counts fakes)
+            (check-result code-under-test-result call-map))))))


Don't test user auth on unrelated test

Don't test user auth on unrelated test

--- test/uruk/core_test.clj
+++ test/uruk/core_test.clj
@@ -129,9 +129,10 @@
     (testing "session creation with URI content source using options"
       (is-default-session-options? (session->map
                                     (create-session
-                                     db (make-uri-content-source "xdbc://localhost:8383/"
-                                                                 {:preemptive-auth true})
-                                     {}))))
+                                     db (make-uri-content-source
+                                         "xdbc://localhost:8383/"
+                                         {:preemptive-auth false
+                                          :default-logger (Logger/getLogger "foobar")})))))
     (testing "session creation with hosted content source"
       (is-default-session-options? (session->map
                                     (create-session


Change PUT to POST

Change PUT to POST

Issue #3

--- src/movie_app/handler.clj
+++ src/movie_app/handler.clj
@@ -22,7 +22,7 @@
              (cc/GET "/movie/:id" [id] (response/get-movie-entry id))
              (cc/GET "/review" [] (response/get-review-list))
              (cc/GET "/review/:id" [id] (response/get-review-entry id))
-             (cc/PUT "/review/:id" {params :params} (response/update-review params))
+             (cc/POST "/review/:id" {params :params} (response/update-review params))
              (route/resources "/")
              (route/not-found "Not Found")))


Add torus neighbours function

Add torus neighbours function

--- src/petulant_life/life.clj
+++ src/petulant_life/life.clj
@@ -34,6 +34,23 @@
         :when (not= 0 dx dy)]
     [(+ dx x) (+ dy y)]))

+(defn mk-wrapping-add [wrap-at]
+  (fn [a b]
+    (let [sum (+ a b)]
+      (cond (> sum wrap-at) (- sum wrap-at)
+            (< sum 0)       (+ wrap-at sum)
+            :else           sum))))
+
+(defn mk-torus-neighbours [[width height]]
+  (let [add-height (mk-wrapping-add height)
+        add-width  (mk-wrapping-add width)]
+   (fn [[x y]]
+     (for [dx [-1 0 1]
+           dy [-1 0 1]
+           :when (not= 0 dx dy)]
+       [(add-width  dx x)
+        (add-height dy y)]))))
+
 (defn stepper
   "Returns a step function for Life-like cell automata.
   neighbours takes a location and return a sequential collection


Show all available data on line chart

Show all available data on line chart

--- src-cljs/frontend/components/insights/project.cljs
+++ src-cljs/frontend/components/insights/project.cljs
@@ -10,7 +10,7 @@
             cljsjs.c3)
   (:require-macros [frontend.utils :refer [html defrender]]))

-(def plot-info
+(def build-time-bar-chart-plot-info
   {:top 10
    :right 10
    :bottom 10
@@ -18,31 +18,17 @@
    :max-bars 100
    :positive-y% 0.6})

-(defn filter-chartable-builds [builds]
-  (some->> builds
-           (filter insights/build-chartable?)
-           (take (:max-bars plot-info))
-           reverse
-           (map insights/add-queued-time)))
-
-(defn decorate-project
-  "Add keys to project related to insights - :show-insights? :sort-category :chartable-builds ."
-  [plans {:keys [recent-builds] :as project}]
-  (let [chartable-builds (filter-chartable-builds recent-builds)]
-    (-> project
-        (assoc :chartable-builds chartable-builds))))
-
 (defn build-time-bar-chart [builds owner]
   (reify
     om/IDidMount
     (did-mount [_]
       (let [el (om/get-node owner)]
-        (insights/insert-skeleton plot-info el)
-        (insights/visualize-insights-bar! plot-info el builds owner)))
+        (insights/insert-skeleton build-time-bar-chart-plot-info el)
+        (insights/visualize-insights-bar! build-time-bar-chart-plot-info el builds owner)))
     om/IDidUpdate
     (did-update [_ prev-props prev-state]
       (let [el (om/get-node owner)]
-        (insights/visualize-insights-bar! plot-info el builds owner)))
+        (insights/visualize-insights-bar! build-time-bar-chart-plot-info el builds owner)))
     om/IRender
     (render [_]
       (html
@@ -95,7 +81,11 @@
                                                          (filter #(and (= (:reponame %) (:repo navigation-data))
                                                                        (= (:username %) (:org navigation-data))))
                                                          first)
-        chartable-builds (filter-chartable-builds (:recent-builds project))]
+        chartable-builds (some->> (:recent-builds project)
+                                  (filter insights/build-chartable?))
+        bar-chart-builds (->> chartable-builds
+                              (take (:max-bars build-time-bar-chart-plot-info))
+                              (map insights/add-queued-time))]
     (html
      (if (nil? chartable-builds)
        ;; Loading...
@@ -109,7 +99,6 @@
            [:dt "last build"]
            [:dd (om/build common/updating-duration
                           {:start (->> chartable-builds
-                                       reverse
                                        (filter :start_time)
                                        first
                                        :start_time)}
@@ -122,11 +111,11 @@
          [:div.card.insights-metadata
           [:dl
            [:dt "median queue"]
-           [:dd (datetime/as-duration (insights/median (map :queued_time_millis chartable-builds)))]]]
+           [:dd (datetime/as-duration (insights/median (map :queued_time_millis bar-chart-builds)))]]]
          [:div.card.insights-metadata
           [:dl
            [:dt "median build"]
-           [:dd (datetime/as-duration (insights/median (map :build_time_millis chartable-builds)))]]]
+           [:dd (datetime/as-duration (insights/median (map :build_time_millis bar-chart-builds)))]]]
          [:div.card.insights-metadata
           [:dl
            [:dt "parallelism"]
@@ -137,7 +126,7 @@
          [:div.card-header
           [:h3 "Build Timing"]]
          [:div.card-body
-          (om/build build-time-bar-chart chartable-builds)]]
+          (om/build build-time-bar-chart (reverse bar-chart-builds))]]
         [:div.card
          [:div.card-header
           [:h3 "Build Performance"]]


Convert CQL results metadata to Clojure data structures

--- src/clojure/clojurewerkz/cassaforte/conversion.clj
+++ src/clojure/clojurewerkz/cassaforte/conversion.clj
@@ -1,9 +1,36 @@
 (ns clojurewerkz.cassaforte.conversion
   (:use [clojure.walk :only [stringify-keys]]
-        [clojurewerkz.support.string :only [to-byte-buffer]])
-  (:import [org.apache.cassandra.thrift ConsistencyLevel KsDef CfDef CqlPreparedResult CqlResult CqlRow Column]
+        [clojurewerkz.support.string :only [to-byte-buffer from-byte-buffer]])
+  (:import [org.apache.cassandra.thrift ConsistencyLevel KsDef CfDef CqlPreparedResult CqlResult CqlRow Column CqlMetadata]
            java.util.List
            java.nio.ByteBuffer))
+
+;;
+;; Implementation
+;;
+
+(defn from-cql-column
+  [^Column column]
+  {:name      (String. ^bytes (.getName column) "UTF-8")
+   :value     (.getValue column)
+   :ttl       (.getTtl column)
+   :timestamp (.getTimestamp column)})
+
+(defn from-cql-row
+  [^CqlRow row]
+  {:key (String. ^bytes (.getKey row) "UTF-8")
+   :columns (map from-cql-column (.getColumns row))})
+
+(defn from-cql-type-map
+  [^java.util.Map$Entry m]
+  {:name (from-byte-buffer (.getKey m)) :value (.getValue m)})
+
+(defn from-cql-metadata
+  [^CqlMetadata md]
+  {:value-types (map from-cql-type-map (.getValue_types md))
+   :name-types  (map from-cql-type-map  (.getName_types md))
+   :default-value-type (.getDefault_value_type md)
+   :default-name-type  (.getDefault_name_type md)})

@@ -59,21 +86,9 @@
      :variable-names (.getVariable_names result)
      :variable-types (.getVariable_types result)}))

-(defn from-cql-column
-  [^Column column]
-  {:name      (String. ^bytes (.getName column) "UTF-8")
-   :value     (.getValue column)
-   :ttl       (.getTtl column)
-   :timestamp (.getTimestamp column)})
-
-(defn from-cql-row
-  [^CqlRow row]
-  {:key (String. ^bytes (.getKey row) "UTF-8")
-   :columns (map from-cql-column (.getColumns row))})
-
 (defn from-cql-result
   [^CqlResult result]
   {:num    (.getNum result)
-   :schema (.getSchema result)
+   :schema (from-cql-metadata (.getSchema result))
    :type   (.getType result)
-   :rows   (map from-cql-row (.getRows result))})+   :rows   (map from-cql-row (.getRows result))})


flip -1 and 1 for repness

flip -1 and 1 for repness

--- src/polismath/clusters.clj
+++ src/polismath/clusters.clj
@@ -93,10 +93,11 @@
                     (reduce
                       (fn [counts vote]
                         (case vote
-                          1       (assoc counts 0 (inc (first counts)))
-                          (0 -1)  (assoc counts 1 (inc (second counts)))
+                          -1       (assoc counts 0 (inc (first counts)))
+                          (0 1)  (assoc counts 1 (inc (second counts)))
                                   counts))
-                      [1 1] votes)]
+                      [1 1] ; start counting from 1 to prevent division by zero (smoothing)
+                      votes)]
               (/ up not-up)))]
     (let [in-cols  (columns (:matrix in-part))
           out-cols (columns (:matrix out-part))]


Adding correlation

Adding correlation

--- src/proxmox/generators.clj
+++ src/proxmox/generators.clj
@@ -1,6 +1,7 @@
 (ns proxmox.generators
   "proxomx generated valudes"
   (:use
+    [clojure.data :only (diff)]
     [puny.core :only (defgen)]
     [slingshot.slingshot :only  [throw+ try+]]
     [clojure.core.strint :only (<<)]
@@ -52,22 +53,23 @@
   (not (nil? (first (filter #(= % "open")
                             (map #(get-in % [:state :state]) (get-in host [:ports :ports])))))))

-(defn raw-scan [ip]
+(defn raw-scan
+  "runs raw scan, require nmap bin to be symlinked to /usr/local"
+  [ip]
   (let [nmap (Nmap4j. "/usr/local")]
     (doto nmap
       (.includeHosts ip)
       (.addFlags "-n -T5 -p U:1194,T:21,22,25,53,80,110,111")
       (.execute)
-      (.getResult)
-      )))
-
+      (.getResult))))

 (defn hosts-scan
   "Uses nmap so scan a list of hosts (192.168.10.1-50)"
   [hosts]
-  (map :addresses  (filter ports-open?
-                           (get-in (from-java (raw-scan hosts)) [:result :hosts])))
-  )
+  (map :addresses
+       (filter ports-open?  (get-in (from-java (raw-scan hosts)) [:result :hosts]))))
+
+

 (defn ip-to-long
   "Converts an ip address to long number"
@@ -153,14 +155,24 @@
         return nil "
         {:ips "ips"} {:rel-ip (ip-to-long ip)}))))

+
+; debugging fn's
 (defn list-used-ips
   "List used ips in human readable form (mainly for debugging)."
   []
    (map #( -> % (Long/parseLong) long-to-ip) (wcar (car/zrangebyscore "ips" 1 1))))

+(defn correlate
+  "compares stored ips to scan result"
+  []
+   (let [scanned (map (fn [[{:keys [addr]}]] addr) (hosts-scan "192.168.20.170-254"))]
+     (zipmap [:scanned :listed :common] (diff (into #{} scanned) (into #{} (list-used-ips))))
+    )
+  )

 (comment
-  (release-ip "192.168.5.130")
+  (clojure.pprint/pprint (correlate))
+  (release-ip "192.168.20.185")
   (gen-ip {})
   (wcar (car/del "ips"))
   (mark-used)


Minor doc updates as design develops

Minor doc updates as design develops

--- src/omhome/posts_meta.clj
+++ src/omhome/posts_meta.clj
@@ -29,9 +29,9 @@
   {:title ""
    :post-url "" ;; a custom url for the post
    :post-filepath "" ;; a path to the post data. The filename suffix determines the post format (.md, .html or .clj for hiccup).
-   :post nil ;; the post content, transformed from its underlying representation
+   :post nil ;; the post content, transformed from its underlying representation by gen-post
    :publish false ;; set to true to include the post in the generated output, indices etc
-   :date ""
+   :date nil ;; TODO: should be a datetime representation easily transformed into the html4 datetime type
    :category ""
    :tags []
    :author "Oliver Mooney"


Tidying up

Tidying up

--- src/pericles/handlers.clj
+++ src/pericles/handlers.clj
@@ -8,9 +8,9 @@
   "Middleware that logs each request."
   [handler]
   (fn [req]
-    (let [{:keys  [uri remote-addr]} req
-          current-time  (System/currentTimeMillis)
-          request-method  (str/upper-case  (:request-method req))]
+    (let [{:keys [uri remote-addr]} req
+          current-time (System/currentTimeMillis)
+          request-method (str/upper-case (:request-method req))]
       (log/debugf "Started %s [%s] by (%s)"
                   request-method
                   uri
@@ -18,10 +18,10 @@
       ;; Let evaluates to last form, so, for sake of next middleware, we need to make sure
       ;; it evaluates to result of calling handler function. Also, check if response
       ;; map is nil, since this route may have not been matched.
-      (if-let [response-map  (handler req)]
-        (let [status-code  (:status response-map)
-              status-name  (status/get-name status-code)
-              elapsed-time  (-  (System/currentTimeMillis) current-time)]
+      (if-let [response-map (handler req)]
+        (let [status-code (:status response-map)
+              status-name (status/get-name status-code)
+              elapsed-time (- (System/currentTimeMillis) current-time)]
           (log/debugf "Finished %s [%s => %d %s] in %dms by (%s)"
                       request-method
                       uri
@@ -39,8 +39,8 @@
     (try (handler req)
          (catch Throwable e
            (do
-             (log/error e  "Unhandled exception in handler!")
+             (log/error e "Unhandled exception in handler!")
              ;; We wrap exception and stack trace in response body. These will
              ;; get picked up by wrap-500 and it will make a nice HTML page.
              (resp/internal-server-error
-               (str/join  "\n" (conj  (map str  (.getStackTrace e))  (.toString e)))))))))
+               (str/join "\n" (conj (map str (.getStackTrace e)) (.toString e)))))))))


remove syntax errors, set up a go-loop just in case

--- src/bitsplit_cli/core.cljs
+++ src/bitsplit_cli/core.cljs
@@ -21,12 +21,8 @@

 (set! *print-fn* #(.log js/console %))

-(def )
-(def )
-
-(def system {:storage storage :client client})
-(def build-cmd (partial assoc system :command))
-(def exec-cmd (comp execute build-cmd))
+; (def build-cmd (partial assoc system :command))
+; (def exec-cmd (comp execute build-cmd))

 (defn- read-prompt [message]
     (let [return (chan 1)]
@@ -48,11 +44,13 @@
   {:percentages per
    :unspents unspents})

-
 (defn -main [& args]
   (let [log (open-log "logfile")
         storage (->File splits-location)
         client (new-client (str base-directory "seed") log)
-        unspent-results (handle-unspents! grab-percentages system)]))
+        system {:storage storage :client client}
+        unspent-results (handle-unspents! grab-percentages system)]
+    (go-loop [_ (<! unspent-results)]
+      (recur (<! unspent-results)))))

 (set! *main-cli-fn* -main)


Add API documentation for lambdacd.presentation.pipeline-structure

--- src/clj/lambdacd/presentation/pipeline_structure.clj
+++ src/clj/lambdacd/presentation/pipeline_structure.clj
@@ -136,24 +136,65 @@
   [part id include-alias?]
   (if (is-container-step? part)
     (container-step-representation part id include-alias?)
-    (simple-step-representation part id))
-  )
-
-(defn step-display-representation [part id]
+    (simple-step-representation part id)))
+
+(defn step-display-representation
+  "Takes a part of a pipeline and its step-id and returns a map-representation with data about this part of the pipeline:
+  ```clojure
+  > (step-display-representation `do-stuff `(1)])
+  {:name \"do-stuff\" :type :step :step-id '(1) :has-dependencies false}
+  ```"
+  [part id]
   (step-display-representation-internal part id false))

 (defn pipeline-display-representation
+  "Takes a pipeline-structure and returns a nested list of step representations (i.e. the result of `step-display-representation`):
+  ```clojure
+  > (pipeline-display-representation `((in-parallel
+                                         (in-cwd \"foo\"
+                                                 do-stuff)
+                                         (in-cwd \"bar\"
+                                                 do-other-stuff)))
+
+  [{:name \"in-parallel\"
+    :type :parallel
+    :step-id '(1)
+    :has-dependencies false
+    :children
+    [{:name \"in-cwd foo\"
+      :type :container
+      :step-id '(1 1)
+      :has-dependencies false
+      :children [{:name \"do-stuff\" :type :step :step-id '(1 1 1) :has-dependencies false}]}
+     {:name \"in-cwd bar\"
+      :type :container
+      :step-id '(2 1)
+      :has-dependencies false
+      :children [{:name \"do-other-stuff\" :type :step :step-id '(1 2 1) :has-dependencies true}]}]}]
+  ```"
   ([part]
    (seq-to-display-representations '() false part)))

-(defn flatten-pipeline-representation [reps]
+(defn flatten-pipeline-representation
+  "Takes a pipeline-representation as returned by `pipeline-display-representation` (which is hierarchical, containing
+  only representations for the root-steps which then contain the representation of their children) and returns a collection
+  of pipeline representations, this time containing all child steps as well."
+  [reps]
   (flatten
     (for [rep reps]
       (if (:children rep)
         (conj (flatten-pipeline-representation (:children rep)) rep)
         [rep]))))

-(defn step-display-representation-by-step-id [pipeline-def step-id]
+(defn step-display-representation-by-step-id
+  "Returns a information about step (as returned by `step-display-representation`) for a specific step (identified by a step-id) in a pipeline:
+  ```clojure
+  > (step-display-representation-by-step-id `(do-stuff
+                                                do-other-stuff
+                                                do-stuff-that-has-a-different-display-type) `(1))
+  {:name \"do-stuff\" :type :step :step-id '(1) :has-dependencies false}
+  ```"
+  [pipeline-def step-id]
   (->> (seq-to-display-representations '() true pipeline-def)
        (flatten-pipeline-representation)
        (filter #(= (:step-id %) step-id))


Fix a leftover unwrap to extract.

Fix a leftover unwrap to extract.

--- src/clojure/uncomplicate/clojurecl/internal/impl.clj
+++ src/clojure/uncomplicate/clojurecl/internal/impl.clj
@@ -80,7 +80,7 @@
   (wrap [this]
     this)
   Wrapper
-  (unwrap [this]
+  (extract [this]
     this))

 (extend-type cl_command_queue


remove unusable invoking of fixDefaultRequestArray

--- nginx-clojure-embed/src/clojure/nginx/clojure/embed.clj
+++ nginx-clojure-embed/src/clojure/nginx/clojure/embed.clj
@@ -30,8 +30,7 @@
   ([nginx-conf]
     (let [server (NginxEmbedServer/getServer)]
       (when *nginx-work-dir* (.setWorkDir server *nginx-work-dir*))
-      (.start server nginx-conf)
-      (when (.isStarted server) (nginx.clojure.clj.LazyRequestMap/fixDefaultRequestArray))))
+      (.start server nginx-conf)))
   )

 (defn stop-server []


We actually use the return value now, so they need to be correct.

If created, the calls return true. If they already existed and need
not be created, false is returned.

--- modules/messaging/src/test/clojure/test/immutant/messaging.clj
+++ modules/messaging/src/test/clojure/test/immutant/messaging.clj
@@ -22,8 +22,8 @@

 (def dummies { "jboss.messaging.default.jms.manager"
                (proxy [org.hornetq.jms.server.JMSServerManager][]
-                 (createQueue [& _] false)
-                 (createTopic [& _] false))
+                 (createQueue [& _] true)
+                 (createTopic [& _] true))
                "housekeeper" nil})

 (defn test-already-running [destination]


More examples

More examples

--- src/main/cljc/clojure_club/destructuring/core.cljc
+++ src/main/cljc/clojure_club/destructuring/core.cljc
@@ -1,3 +1,7 @@
 (ns clojure-club.destructuring.core)

 (def fib-seq (map first (iterate (fn [[a b]] [b (+ a b)]) [0N 1N])))
+
+;(defn mxn [fab m]
+;  (loop [[f & r] m]
+;    (recur r (map () r))))


remove unused code

remove unused code

--- src/app/symbol_solver/scope.clj
+++ src/app/symbol_solver/scope.clj
@@ -65,19 +65,6 @@
 (defn declare-symbol? [symbol-name symbols-declarator]
   (get (declared-symbols symbols-declarator) symbol-name))

-;(extend-protocol scope
-;  NameExpr
-;  (solveSymbol [this context nameToSolve]
-;    (when-not context
-;      (solveSymbol (.getParentNode this) nil nameToSolve))))
-
-;(extend-protocol scope
-;  AssignExpr
-;  (solveSymbol [this context nameToSolve]
-;    (if context
-;      (or (solveSymbol (.getTarget this) this nameToSolve) (solveSymbol (.getValue this) this nameToSolve))
-;      (solveSymbol (.getParentNode this) this nameToSolve))))
-
 (extend-protocol scope
   com.github.javaparser.ast.Node
   (solveSymbol [this context nameToSolve]
@@ -90,12 +77,6 @@
           decls (map (partial declare-symbol? nameToSolve) elementsToConsider)]
       (or (first decls) (solveSymbol (.getParentNode this) this nameToSolve)))))

-;(extend-protocol scope
-;  ExpressionStmt
-;  (solveSymbol [this context nameToSolve]
-;    (let [fromExpr (solveSymbol (.getExpression this) this nameToSolve)]
-;      (or fromExpr (solveSymbol (.getParentNode this) this nameToSolve)))))
-
 (defn solveClassInPackage [pakage nameToSolve]
   {:pre [typeSolver]}
   ; TODO first look into the package
@@ -106,11 +87,6 @@
   (let [id (.getId variableDeclarator)]
     (when (= nameToSolve (.getName id))
       id)))
-
-;(extend-protocol scope
-;  VariableDeclarationExpr
-;  (solveSymbol [this context nameToSolve]
-;    (first (filter (partial solveAmongVariableDeclarator nameToSolve) (.getVars this)))))

 (defn- solveAmongFieldDeclaration
   "Consider one single com.github.javaparser.ast.body.FieldDeclaration, which corresponds to possibly multiple fields"


Use sparkles for keypair-to-buf

Use sparkles for keypair-to-buf

--- src/caesium/crypto/box.clj
+++ src/caesium/crypto/box.clj
@@ -18,10 +18,10 @@

   This API matches libsodium's `crypto_box_keypair` and
   `crpyto_box_seed_keypair`."
-  ([^ByteBuffer pk ^ByteBuffer sk]
-   (.crypto_box_keypair sodium pk sk))
-  ([^ByteBuffer pk ^ByteBuffer sk ^ByteBuffer seed]
-   (.crypto_box_seed_keypair sodium pk sk seed)))
+  ([pk sk]
+   (b/✨ keypair pk sk))
+  ([pk sk seed]
+   (b/✨ seed-keypair pk sk seed)))

 (defn keypair!
   "Create a `crypto_box` keypair.


pass src dir into compile-java

pass src dir into compile-java

--- src/cake/tasks/compile.clj
+++ src/cake/tasks/compile.clj
@@ -5,14 +5,14 @@
         [cake.contrib.find-namespaces :only [find-clojure-sources-in-dir read-file-ns-decl]])
   (:import [org.apache.tools.ant.taskdefs Copy Javac Java]))

-(defn compile-java []
-  (let [start (System/currentTimeMillis)
-        src   (file "src" "jvm")]
+(defn compile-java [src]
+  (let [start (System/currentTimeMillis)]
     (when (.exists src)
       (ant Javac {:destdir     (file "classes")
                   :classpath   (classpath)
                   :srcdir      (path src)
                   :fork        true
+                  :verbose     (verbose?)
                   :debug       true
                   :debug-level "source,lines"
                   :failonerror true}))
@@ -65,7 +65,7 @@
 (deftask compile #{deps compile-native}
   "Compile all clojure and java source files. Use 'cake compile force' to recompile."
   (copy-native)
-  (compile-java)
+  (compile-java (file "src" "jvm"))
   (compile-clojure))

 ;; add actions to compile-native if you need to compile native libraries


New function render-repository-page

New function render-repository-page

--- src/arachnida/html_renderer.clj
+++ src/arachnida/html_renderer.clj
@@ -144,24 +144,44 @@
                              (for [s statistic]
                                   (render-value s :files_changed))]
                     ]]
-;               [:div {:class "panel panel-primary"}
-;                   [:div {:class "panel-heading"}
-;                       "Per repository statistic"]
-;                   [:table {:class "table table-condensed table-hover table-bordered" :rules "all"}
-;                       [:tr [:th "Repository"] [:th {:colspan "4"} "Statistic"]]
-;                       [:tr [:th " "]
-;                            [:th "Commits"]
-;                            [:th "Files"]
-;                            [:th "Insertions"]
-;                            [:th "Deletions"]]
-;                       (for [pr product-repo]
-;                           [:tr [:td (:reponame pr)]
-;                                [:td (:commits_count pr)]
-;                                [:td (:files_changed pr)]
-;                                [:td (:insertions pr)]
-;                                [:td (:deletions pr)]
-;                           ]
-;                       )]]
+                [:br][:br][:br][:br]
+                (render-html-footer mailto)
+            ] ; </div class="container">
+        ] ; </body>
+    ))
+
+(defn render-repository-page
+    [product-name repository-name statistic mailto]
+(println statistic)
+    (page/xhtml
+        (render-html-header)
+        [:body
+            [:div {:class "container"}
+                (render-navigation-bar-section)
+                [:h1 (str "Product: " product-name)]
+                [:h2 (str "Repository: " repository-name)]
+                [:br]
+                [:br]
+                [:div {:class "panel panel-primary"}
+                    [:div {:class "panel-heading"}
+                        "Statistic for repository"]
+                    [:table {:class "table table-condensed table-hover table-bordered" :rules "all"}
+                        [:tr [:th "Year"]
+                        (for [s statistic]
+                             [:th {:style "width:12ex;text-align:right"} (key s)])]
+                        [:tr [:th "Commits:"]
+                             (for [s statistic]
+                                  (render-value s :commits_count))]
+                        [:tr [:th "Insertions:"]
+                             (for [s statistic]
+                                  (render-value s :insertions))]
+                        [:tr [:th "Deletions:"]
+                             (for [s statistic]
+                                  (render-value s :deletions))]
+                        [:tr [:th "Changed files:"]
+                             (for [s statistic]
+                                  (render-value s :files_changed))]
+                    ]]
                 [:br][:br][:br][:br]
                 (render-html-footer mailto)
             ] ; </div class="container">


Move repl page.

Move repl page.

--- src/tryclojure/views/home.clj
+++ src/tryclojure/views/home.clj
@@ -39,7 +39,7 @@
 (defpage "/storytime" []
   (repl-html "story" "Storytime"))

-(defpage "/code" []
+(defpage "/repl" []
   (repl-html "isla" "Try Isla"))

 (defpage "/" []


fix typo

fix typo

--- src/babel/francais/grammar.cljc
+++ src/babel/francais/grammar.cljc
@@ -489,10 +489,10 @@
      :enrich enrich

      :pred2lex ;; map:<pred => subset of lexicon with that pred>
-     (map-subset-by-path lexicon-for-generation [:synsem :sem :pred])
+     (map-subset-by-path lexicon [:synsem :sem :pred])

      :cat2lex ;; map:<cat => subset of lexicon with that cat>
-     (map-subset-by-path lexicon-for-generation [:synsem :cat])
+     (map-subset-by-path lexicon [:synsem :cat])

      :grammar grammar
      ;; Will throw exception if more than 1 rule has the same :rule value:


temporarily comment out 'casa' without article

--- src/babel/italiano/lexicon.cljc
+++ src/babel/italiano/lexicon.cljc
@@ -550,12 +550,13 @@
                            :place true}}})

     ;; in the sense of "a casa": no article needed.
-    {:synsem {:cat :noun
-              :sem {:city false
-                    :place true
-                    :animate false
-                    :pred :casa}
-              :subcat '()}}]
+;    {:synsem {:cat :noun
+;              :sem {:city false
+;                    :place true
+;                    :animate false
+;                    :pred :casa}
+;              :subcat '()}}
+    ]

     "cattivo"
      (unify adjective


use morph/replace-over to generate candidate tokenizations

--- src/babel/italiano/workbook.clj
+++ src/babel/italiano/workbook.clj
@@ -60,8 +60,10 @@
 (defn analyze-tokens
   "given a string, generate a list of tokenization hypotheses."
   [string]
-  (list
-   (string/split string tokenizer)))
+  (map #(string/split % tokenizer)
+       (if true
+         (morph/replace-over [string])
+         [string])))

 (defn parse
   "parse a string in Italian into zero or more (hopefully more) phrase structure trees"


2.1.3  What Is Meant by Data?

2.1.3  What Is Meant by Data?

--- src/sicp/chapter2/1_3.clj
+++ src/sicp/chapter2/1_3.clj
@@ -3,3 +3,25 @@
 ;;;; 2.1  Introduction to Data Abstraction

 ;;; 2.1.3  What Is Meant by Data?
+
+(defn kons [x y]
+  (letfn [(dispatch [m]
+            (case m
+              0 x
+              1 y
+              (throw (IllegalArgumentException.
+                      (str "Argument not 0 or 1 -- CONS " m)))))]
+    dispatch))
+
+(defn car [z] (z 0))
+
+(defn cdr [z] (z 1))
+
+;; Exercise 2.4
+;; TODO
+
+;; Exercise 2.5
+;; TODO
+
+;; Exercise 2.6
+;; TODO


Server style fixes.

Server style fixes.

--- src/clj/fleetdb/server.clj
+++ src/clj/fleetdb/server.clj
@@ -70,7 +70,7 @@
       (.println System/err))))

 (def- protocol-handlers
-  {:binary binary-handler :text text-handler})
+  {:text text-handler :binary binary-handler })

 (defn run [db-path ephemeral port addr threads protocol]
   (let [inet          (InetAddress/getByName addr)
@@ -115,7 +115,7 @@
     (not (or (.has opt-set "f") (.has opt-set "e")))
       (println "You must specify either -e or -f <path>. Use -h for help.")
     :else
-      (let [db-path (.valueOf opt-set "f")
+      (let [db-path   (.valueOf opt-set "f")
             ephemeral (.has opt-set "e")
             port      (or (parse-int (.valueOf opt-set "p")) 3400)
             addr      (or (.valueOf opt-set "a") "127.0.0.1")


Make routes private

Make routes private

--- src/cljs/lens/history.cljs
+++ src/cljs/lens/history.cljs
@@ -9,9 +9,10 @@
            goog.history.Html5History
            goog.history.EventType))

-(def routes
-  ["/" {"" :index
-        ["w/" :id] :workbook}])
+(def ^:private routes
+  ["/"
+   {"" :index
+    ["w/" :id] :workbook}])

 (defn- create-history []
   (doto (Html5History.)
@@ -33,5 +34,5 @@
         (recur)))
     (bus/listen-on owner :route
       #(when-let [match (bidi/unmatch-pair routes %)]
-         (.setToken history match)))
+        (.setToken history match)))
     (.setEnabled history true)))


Usability: avoided always flashing the login form

It looked crude. Sending the user directly to Record is a better
solution, since they'll be sent to Login if they are not already logged
in.

--- src/cljs/memento/core.cljs
+++ src/cljs/memento/core.cljs
@@ -124,7 +124,7 @@
   (bidi/match-route routes s))

 (def history
-  (pushy/pushy set-page! bidi-matcher #_(partial bidi/match-route routes)))
+  (pushy/pushy set-page! bidi-matcher))

 ;;;;-------------------------
@@ -163,7 +163,7 @@
     (merge app-state {:ui-state {:is-busy?      false
                                  :wip-login?    false
                                  :show-thread?  false
-                                 :section       :login
+                                 :section       :record
                                  :current-query ""
                                  :results-page  0
                                  :memories      {:pages 0}
@@ -458,7 +458,10 @@
   (fn [app-state [_ section]]
     (if (= :remember section)
       (dispatch [:memories-load]))
-    (assoc-in app-state [:ui-state :section] section)))
+    ; Do not associate nil sections
+    (if (some? section)
+      (assoc-in app-state [:ui-state :section] section)
+      app-state)))

 (reg-event-db
   :state-message
@@ -739,8 +742,7 @@
           (list-memories @results true))
         [memory-load-trigger]
         ]
-       "panel-primary"]
-      )))
+       "panel-primary"])))

 (defn memory-list []
   (fn []
@@ -749,7 +751,6 @@
      [memory-thread]
      [memory-query]
      [memory-results]]))
-

 (defn login-form []
   (let [username  (subscribe [:credentials :username])
@@ -810,6 +811,7 @@
       )))

+
 (defn content-section []
   (let [section (subscribe [:ui-state :section])
         token   (subscribe [:credentials :token])]


:save-note handler should have indicated it was busy submitting

Also :load-memories-error should not have cleared the :is-busy? state.

--- src/cljs/memento/core.cljs
+++ src/cljs/memento/core.cljs
@@ -160,7 +160,7 @@
   (fn [app-state [_ result]]
     (dispatch [:set-message (str "Error remembering: " result) "alert-danger"])
     (clear-token-on-unauth result)
-    (assoc-in app-state [:ui-state :is-busy?] false)
+    app-state
     ))

@@ -184,7 +184,7 @@
                            :headers       {:authorization (str "Token " (get-in app-state [:credentials :token]))}
                            :handler       #(dispatch [:save-note-success note])
                            :error-handler #(dispatch [:save-note-error %])}))
-    app-state
+    (assoc-in app-state [:ui-state :is-busy?] true)
     ))

 (register-handler


Update form props

Update form props

--- src/cljs/re_form/core.cljs
+++ src/cljs/re_form/core.cljs
@@ -116,11 +116,12 @@

     :display-name (str (:form-name props))

-    ;; :component-will-receive-props
-    ;; (fn [_ new-props]
-    ;;   (println new-props)
-    ;;   (deinit (:form-name new-props))
-    ;;   (init props))
+    :component-will-receive-props
+    (fn [_ coll]
+      (let [new-props (second coll)]
+        (println new-props)
+        (deinit (:form-name new-props))
+        (init new-props)))

     :reagent-render
     (fn [{:keys [form-name value class] :as props} & body]


needless refactoring

needless refactoring

--- src/cljx/transom/core.cljx
+++ src/cljx/transom/core.cljx
@@ -67,12 +67,12 @@

 (def diff impl/diff)

-(defn prefixes?
+(defn ^:private prefixes?
   [path-1 path-2]
   (and (< (count path-1) (count path-2))
        (= path-1 (subvec path-2 0 (count path-1)))))

-(defn mappings-for
+(defn ^:private rebase-mappings
   [doc old new]
   (into {}
     (for [[new-path new-edit] new
@@ -84,23 +84,23 @@
             rebased-path (when rebased-key (assoc old-path key-index rebased-key))]
         [old-path rebased-path]))))

-(defn rebase-keys
+(defn rebase-paths
   [doc old new]
-  (let [mappings (mappings-for doc old new)
+  (let [mappings (rebase-mappings doc old new)
         rebased (set/rename-keys old mappings)]
     (dissoc rebased nil)))

 (defn compose
   ([doc old new]
-    (let [rebased (rebase-keys doc old new)]
+    (let [old' (rebase-paths doc old new)]
       (reduce
-        (fn [composed [new-path new-edit]]
-          (if (contains? composed new-path)
-            (assoc composed new-path (impl/compose (get-in doc new-path)
-                                                   (get composed new-path)
-                                                   new-edit))
-            (assoc composed new-path new-edit)))
-        rebased
+        (fn [old [new-path new-edit]]
+          (if-some [old-edit (get old new-path)]
+            (let [state (get-in doc new-path)
+                  composed-edit (impl/compose state old-edit new-edit)]
+              (assoc old new-path composed-edit))
+            (assoc old new-path new-edit)))
+        old'
         new)))
   ([doc old new & more]
     (reduce (partial compose doc) (compose doc old new) more)))
@@ -129,6 +129,6 @@
                     [(assoc ours path our-edit') (assoc theirs path their-edit')]))
                 [ours theirs]
                 shared)
-              ours'' (rebase-keys doc ours' (select-keys theirs' r))
-              theirs'' (rebase-keys doc theirs' (select-keys ours' l))]
+              ours'' (rebase-paths doc ours' (select-keys theirs' r))
+              theirs'' (rebase-paths doc theirs' (select-keys ours' l))]
           (recur (inc level) ours'' theirs''))))))


RP + CW | 25 | add debug logging for email sending functions

--- src/stonecutter/email.clj
+++ src/stonecutter/email.clj
@@ -31,26 +31,29 @@
    :body (confirmation-email-body (:base-url email-data) (:confirmation-id email-data))})

 (defn send! [template email-address email-data]
+  (log/debug (format "sending template '%s' to '%s'." template email-address))
   (let [{:keys [subject body]} ((template @template-to-renderer-map) email-data)]
     (@sender email-address subject body)))
-
-(defn initialise! [sender-fn template-to-renderer-config]
-  (reset! sender sender-fn)
-  (reset! template-to-renderer-map template-to-renderer-config))
-
-(defn reset-email-configuration! []
-  (reset! sender nil)
-  (reset! template-to-renderer-map nil))

 (defn bash-sender-factory [email-script-path]
   (if email-script-path
     (fn [email-address subject body]
+      (log/debug (format "sending email to '%s' using bash script: '%s'." email-address email-script-path))
       (shell/sh email-script-path
                 (str email-address)
                 (str subject)
                 (str body)))
     stdout-sender))

+(defn reset-email-configuration! []
+  (reset! sender nil)
+  (reset! template-to-renderer-map nil))
+
+(defn initialise! [sender-fn template-to-renderer-config]
+  (reset! sender sender-fn)
+  (reset! template-to-renderer-map template-to-renderer-config))
+
 (defn configure-email [path]
+  (log/debug (format "Initialising email sender to path: '%s'." path))
   (initialise! (bash-sender-factory path)
                {:confirmation confirmation-renderer}))


Moved reprojection functions from static over into forma.reproject. Generalized functions to work with rain dataset as well.

--- src/clj/forma/source/static.clj
+++ src/clj/forma/source/static.clj
@@ -35,7 +35,6 @@
                           (duck/read-lines old-file)))]
         (println line)))))

-
 ;; ### Sampling

 (defn sample-modis


partial implementation of Off the Grid

partial implementation of Off the Grid

--- src/clj/game/cards-upgrades.clj
+++ src/clj/game/cards-upgrades.clj
@@ -109,6 +109,11 @@
    {:events {:pre-trash {:req (req (= (:zone card) (:zone target)))
                          :effect (effect (trash-cost-bonus 3))}}}

+   "Off the Grid"
+   {:events {:successful-run {:req (req (= target :hq))
+                              :effect (req (trash state :corp card)
+                                           (system-msg state :corp (str "trashes Off the Grid")))}}}
+
    "Panic Button"
    {:init {:root "HQ"} :abilities [{:cost [:credit 1] :effect (effect (draw))
                                     :req (req (and run (= (first (:server run)) :hq)))}]}
@@ -171,4 +176,4 @@
    {:abilities [{:label "Add an icebreaker to the bottom of Stack"
                  :choices {:req #(has? % :subtype "Icebreaker")}
                  :msg (msg "add " (:title target) " to the bottom of Stack")
-                 :effect (effect (trash card) (move :runner target :deck))}]}})+                 :effect (effect (trash card) (move :runner target :deck))}]}})


Fix descriptions for trap triggers

Fix descriptions for trap triggers

--- src/cljc/robinson/describe.cljc
+++ src/cljc/robinson/describe.cljc
@@ -125,11 +125,21 @@
            :white-upper-right-2    "a pale ornate corner"
            :white-bottom-left-2    "a pale ornate corner"
            :white-bottom-right-2   "a pale ornate corner"
-           :crushing-wall-trigger  "TODO"
-           :wall-darts-trigger     "TODO"
-           :poisonous-gas-trigger  "TODO"
-           :spike-pit              "TODO"
-           :snakes-trigger         "TODO"))
+           :crushing-wall-trigger  (if (get cell :trap-found)
+                                     "a spiked wall trap trigger"
+                                     (describe-cell-type (assoc cell :type :floor)))
+           :wall-darts-trigger     (if (get cell :trap-found)
+                                     "a dart trap trigger"
+                                     (describe-cell-type (assoc cell :type :floor)))
+           :poisonous-gas-trigger  (if (get cell :trap-found)
+                                     "a poisonous gas trap trigger"
+                                     (describe-cell-type (assoc cell :type :floor)))
+           :spike-pit              (if (get cell :trap-found)
+                                     "a spike pit"
+                                     (describe-cell-type (assoc cell :type :floor)))
+           :snakes-trigger         (if (get cell :trap-found)
+                                     "a snake trap trigger"
+                                     (describe-cell-type (assoc cell :type :floor)))))
     "strange land"))

 (defn describe-npc


Fix: make sure we do not loose user data


Add a note about moving figwheel configuration

--- src/cljs/comic_reader/main.cljs
+++ src/cljs/comic_reader/main.cljs
@@ -10,6 +10,7 @@

 (enable-console-print!)

+;; TODO: Put figwheel setups into some kind of dev namespace
 (fw/start {
            ;; configure a websocket url if you are using your own server
            :websocket-url "ws://localhost:3449/figwheel-ws"


Work around anchor's not being clickable easily

--- src/cljs/comic_reader/main.cljs
+++ src/cljs/comic_reader/main.cljs
@@ -22,13 +22,13 @@
    "There's nothing to see here."
    [:a {:href "/#"}]])

-(defn id-btn-for-callback [on-click]
+(defn id-btn-for-callback [click-address]
   (fn [{:keys [id name]
         :as data}]
     ^{:key id}
     [:li
      [:a.large.button
-      {:on-click (partial on-click data)}
+      {:href (str "/#" (click-address data))}
       name]]))

 (defn site-list []
@@ -38,8 +38,8 @@
         [:div
          [:h1 "Manga Sites"]
          [:ul (map (id-btn-for-callback
-                    #(r/go-to (r/comics-path
-                               {:site (name (:id %))})))
+                    #(r/comics-path
+                      {:site (name (:id %))}))
                    site-list)]]))))

 (defn comic-list []
@@ -52,10 +52,10 @@
           [:div
            [:ul (map (id-btn-for-callback
                       (fn [item]
-                        (r/go-to (r/read-path {:site site
-                                               :comic (:id item)
-                                               :chapter 1
-                                               :page 1}))))
+                        (r/read-path {:site site
+                                      :comic (:id item)
+                                      :chapter 1
+                                      :page 1})))
                      comic-list)]])))))

 (defn img-component [site


🔥 Remove old fetch-congregation; no more access gis-db

Why:
- Refactoring towards event sourced territories
- It was tested that both implementations returned the same data, so the
  old one can now be removed
- Using `sequence` to always return a collection, instead of possibly
  returning `nil`, and it's faster than `vec` which requires copying

--- src/territory_bro/api.clj
+++ src/territory_bro/api.clj
@@ -4,7 +4,6 @@

 (ns territory-bro.api
   (:require [camel-snake-kebab.core :as csk]
-            [clojure.test :refer :all]
             [clojure.tools.logging :as log]
             [compojure.core :refer [defroutes GET POST ANY]]
             [liberator.core :refer [defresource]]
@@ -19,7 +18,6 @@
             [territory-bro.congregation-boundary :as congregation-boundary]
             [territory-bro.db :as db]
             [territory-bro.dispatcher :as dispatcher]
-            [territory-bro.gis-db :as gis-db]
             [territory-bro.gis-user :as gis-user]
             [territory-bro.jwt :as jwt]
             [territory-bro.permissions :as permissions]
@@ -188,35 +186,17 @@

 (defn- fetch-congregation [conn state user-id congregation]
   (let [cong-id (:congregation/id congregation)]
-    (db/use-tenant-schema conn (:congregation/schema-name congregation))
     {:id (:congregation/id congregation)
      :name (:congregation/name congregation)
      :permissions (->> (permissions/list-permissions state user-id [cong-id])
                        (map (fn [permission]
                               [permission true]))
                        (into {}))
-     :territories (gis-db/get-territories conn)
-     :congregation-boundaries (gis-db/get-congregation-boundaries conn)
-     :subregions (gis-db/get-subregions conn)
-     :card-minimap-viewports (gis-db/get-card-minimap-viewports conn)
-     :users (->> (user/get-users conn {:ids (congregation/get-users state cong-id)})
-                 (map (fn [user]
-                        (-> (:user/attributes user)
-                            (assoc :id (:user/id user))
-                            (assoc :sub (:user/subject user))))))}))
-
-(defn- fetch-congregation2 [conn state user-id congregation]
-  (let [cong-id (:congregation/id congregation)]
-    {:id (:congregation/id congregation)
-     :name (:congregation/name congregation)
-     :permissions (->> (permissions/list-permissions state user-id [cong-id])
-                       (map (fn [permission]
-                              [permission true]))
-                       (into {}))
-     :territories (vec (vals (get-in state [::territory/territories cong-id])))
-     :congregation-boundaries (vec (vals (get-in state [::congregation-boundary/congregation-boundaries cong-id])))
-     :subregions (vec (vals (get-in state [::subregion/subregions cong-id])))
-     :card-minimap-viewports (vec (vals (get-in state [::card-minimap-viewport/card-minimap-viewports cong-id])))
+     ;; TODO: extract query functions
+     :territories (sequence (vals (get-in state [::territory/territories cong-id])))
+     :congregation-boundaries (sequence (vals (get-in state [::congregation-boundary/congregation-boundaries cong-id])))
+     :subregions (sequence (vals (get-in state [::subregion/subregions cong-id])))
+     :card-minimap-viewports (sequence (vals (get-in state [::card-minimap-viewport/card-minimap-viewports cong-id])))
      :users (->> (user/get-users conn {:ids (congregation/get-users state cong-id)})
                  (map (fn [user]
                         (-> (:user/attributes user)
@@ -235,10 +215,7 @@
             congregation (congregation/get-my-congregation state cong-id user-id)]
         (when-not congregation
           (forbidden! "No congregation access"))
-        (ok (-> ((if (contains? (:query-params request) "new") ; TODO: remove old impl
-                   fetch-congregation2
-                   fetch-congregation)
-                 conn state user-id congregation)
+        (ok (-> (fetch-congregation conn state user-id congregation)
                 (format-for-api)
                 (validate-congregation)))))))

@@ -376,23 +353,3 @@
   (db/with-db [conn {:read-only? true}]
     (->> (user/get-users conn)
          (filter #(= "" (:name (:user/attributes %)))))))
-
-(deftest test-api-equivalence
-  (let [state (projections/cached-state)]
-    (db/with-db [conn {}]
-      (doseq [cong (congregation/get-unrestricted-congregations state)]
-        (testing (str (:congregation/id cong) " " (:congregation/name cong))
-          (is (= (-> (fetch-congregation conn state nil cong)
-                     (update :territories #(sort-by :territory/id %))
-                     (update :congregation-boundaries #(sort-by :region/id %))
-                     (update :subregions #(sort-by :region/id %))
-                     (update :card-minimap-viewports #(sort-by :region/id %))
-                     (format-for-api))
-                 (-> (fetch-congregation2 conn state nil cong)
-                     (update :territories #(sort-by :territory/id %))
-                     (update :congregation-boundaries #(sort-by :congregation-boundary/id %))
-                     (update :subregions #(sort-by :subregion/id %))
-                     (update :card-minimap-viewports #(sort-by :card-minimap-viewport/id %))
-                     (format-for-api)))))))))
-
-(test-api-equivalence)


Fix bug in file responses

Fix bug in file responses

--- src/compojure/response.clj
+++ src/compojure/response.clj
@@ -36,7 +36,7 @@
   (render [ref request] (render (deref ref) request))
   java.io.File
   (render [file _]
-    (-> (response/file-response file)
+    (-> (response/file-response (str file))
         (guess-content-type file)))
   clojure.lang.ISeq
   (render [coll _]