Update dependencies.

Update dependencies.

--- project.clj
+++ project.clj
@@ -19,12 +19,12 @@
     [defun "0.3.0-RC1"] ; Erlang-esque pattern matching for Clojure functions https://github.com/killme2008/defun
     [org.clojure/core.incubator "0.1.4"] ; Functions proposed for inclusion in Clojure https://github.com/clojure/core.incubator
     [cheshire "5.7.1"] ; JSON de/encoding https://github.com/dakrone/cheshire
-    [org.flatland/ordered "1.5.4"] ; Ordered hash map https://github.com/flatland/ordered
+    [org.flatland/ordered "1.5.5"] ; Ordered hash map https://github.com/flatland/ordered
     [ring/ring-devel "1.6.1"] ; Web application library https://github.com/ring-clojure/ring
     [ring/ring-core "1.6.1"] ; Web application library https://github.com/ring-clojure/ring
     [http-kit "2.3.0-alpha2"] ; Web Server http://http-kit.org/
     [compojure "1.6.0"] ; Web routing https://github.com/weavejester/compojure
-    [liberator "0.15.0"] ; WebMachine (REST API server) port to Clojure https://github.com/clojure-liberator/liberator
+    [liberator "0.15.1"] ; WebMachine (REST API server) port to Clojure https://github.com/clojure-liberator/liberator
     [com.ashafa/clutch "0.4.0"] ; CouchDB client https://github.com/clojure-clutch/clutch
     [clojurewerkz/elastisch "3.0.0-beta2"] ; Client for ElasticSearch https://github.com/clojurewerkz/elastisch
     [environ "1.1.0"] ; Get environment settings from different sources https://github.com/weavejester/environ
@@ -47,7 +47,7 @@
         :hot-reload "false"
       }
       :dependencies [
-        [midje "1.9.0-alpha6"] ; Example-based testing https://github.com/marick/Midje
+        [midje "1.9.0-alpha8"] ; Example-based testing https://github.com/marick/Midje
         [ring-mock "0.1.5"] ; Test Ring requests https://github.com/weavejester/ring-mock
       ]
       :plugins [


jvm 1.7

jvm 1.7

--- project.clj
+++ project.clj
@@ -1,6 +1,7 @@
 (defproject secret-shame "0.1.0"
   :description "FIXME: write this!"
   :url "http://example.com/FIXME"
+  :javac-options     ["-target" "1.7" "-source" "1.7"]
   :dependencies [[org.clojure/clojure "1.6.0"]
                  [org.clojure/tools.reader "0.8.5"]
                  [org.clojure/clojurescript "0.0-2268"]


Bump Clojure 1.8 version

Bump Clojure 1.8 version

--- project.clj
+++ project.clj
@@ -28,7 +28,7 @@
              :1.5.1 {:dependencies [[org.clojure/clojure "1.5.1"]]}
              :1.6 {:dependencies [[org.clojure/clojure "1.6.0"]]}
              :1.7 {:dependencies [[org.clojure/clojure "1.7.0"]]}
-             :1.8 {:dependencies [[org.clojure/clojure "1.8.0-RC3"]]}
+             :1.8 {:dependencies [[org.clojure/clojure "1.8.0-RC5"]]}
              }

   :plugins [[lein-midje "3.2"]


v0.9.87

--- project.clj
+++ project.clj
@@ -1,4 +1,4 @@
-(defproject tupelo "0.9.86"
+(defproject tupelo "0.9.87"
   :description "Tupelo:  Clojure With A Spoonful of Honey"
   :url "http://github.com/cloojure/tupelo"
   :license {:name "Eclipse Public License"


Removed unused before-js-reload

Removed unused before-js-reload

--- project.clj
+++ project.clj
@@ -33,8 +33,7 @@
                                               :compiler {:source-map true
                                                          :main       "zest.dev"
                                                          :verbose true}
-                                              :figwheel {:on-jsload "zest.core/on-figwheel-reload"
-                                                         :before-js-reload "zest.core/before-figwheel-reload"}}}}
+                                              :figwheel {:on-jsload "zest.core/on-figwheel-reload"}}}}
                    :source-paths ["env/dev/cljs"]

                    :dependencies [[figwheel-sidecar "0.5.0-3"]]


Add tools.reader as a dep

Add tools.reader as a dep

--- project.clj
+++ project.clj
@@ -7,4 +7,5 @@
                  [org.clojure/clojure            "1.5.1"]
                  [org.clojure/tools.analyzer.jvm "0.1.0"]
                  [org.clojure/tools.emitter.jvm  "0.1.0"]
+                 [org.clojure/tools.reader       "0.8.4"]
                  ])


dev dependencies

dev dependencies

--- project.clj
+++ project.clj
@@ -7,9 +7,12 @@
                  [org.clojure/core.async "0.1.346.0-17112a-alpha"]
                  [org.zeromq/jeromq "0.3.4"]
                  [cheshire "5.4.0"]
-                 [figwheel "0.2.5"]
                  [org.omcljs/om "0.8.8"]
                  [sablono "0.3.4"]]
+
+  :profiles {:dev {:dependencies [[figwheel "0.2.5"]
+                                  [weasel "0.6.0"]]}}
+
   :main game.main

   :plugins [[lein-cljsbuild "1.0.5"]


latest amazonica

latest amazonica

--- project.clj
+++ project.clj
@@ -21,7 +21,7 @@
                  [org.clojure/data.json "0.2.2" ]
                  [com.taoensso/carmine "2.0.0"]
                  [org.clojure/core.memoize "0.5.2" :exclusions [org.clojure/core.cache]]
-                 [amazonica "0.1.29"]
+                 [amazonica "0.2.24"]
                  [narkisr/trammel "0.8.0-freez"]
                  [org.flatland/useful "0.10.3"]
                  [substantiation "0.1.3"]


Bump to version 0.0.7.

Bump to version 0.0.7.

--- project.clj
+++ project.clj
@@ -1,5 +1,5 @@
 (defproject
-  wlmmap "0.0.6"
+  wlmmap "0.0.7"
   :url "http://github.com/bzg/wlmmap"
   :license {:name "Eclipse Public License"
             :url "http://www.eclipse.org/legal/epl-v10.html"}


start working on 1.2.6

start working on 1.2.6

--- project.clj
+++ project.clj
@@ -1,4 +1,4 @@
-(defproject gorillalabs/sparkling "1.2.5"
+(defproject gorillalabs/sparkling "1.2.6-SNAPSHOT"
             :description "A Clojure Library for Apache Spark"
             :url "https://gorillalabs.github.io/sparkling/"
             :license {:name "Eclipse Public License"


Fix the pallet-rvm version number

Fix the pallet-rvm version number

--- project.clj
+++ project.clj
@@ -94,7 +94,7 @@
                  [org.cloudhoist/java "0.5.1"]
                  [org.cloudhoist/nginx "f48febc9e5e43148719a11c3aeca4e6b668993e"]
                  [lein-crate "0.1.0"]
-                 [pallet-rvm "0.2"]
+                 [pallet-rvm "0.2.0"]
                  [midje "1.2.0"]
                  [cdt "1.2.6.1-SNAPSHOT"]
                  [org.jruby.ext.posix/jnr-posix "1.1.8"]]


Version 0.2.0

Version 0.2.0

--- project.clj
+++ project.clj
@@ -1,4 +1,4 @@
-(defproject jcf-static/lein-template "0.2.0-SNAPSHOT"
+(defproject jcf-static/lein-template "0.2.0"
   :description "A Leiningen template I use for quickly creating a static site."
   :url "https://github.com/jcf/lein-template-static"
   :license {:name "The MIT License"


update project.clj info

update project.clj info

--- project.clj
+++ project.clj
@@ -1,6 +1,6 @@
 (defproject pw "0.1.0-SNAPSHOT"
-  :description "FIXME: write description"
-  :url "http://example.com/FIXME"
+  :description "A simple server for the unix password manager, pass"
+  :url "http://github.com/johnswanson/pass-server"
   :license {:name "Eclipse Public License"
             :url "http://www.eclipse.org/legal/epl-v10.html"}
   :plugins [[lein-environ "1.0.0"]


Version 0.1.14-SNAPSHOT

Version 0.1.14-SNAPSHOT

--- project.clj
+++ project.clj
@@ -1,4 +1,4 @@
-(defproject day8.re-frame/trace "0.1.13"
+(defproject day8.re-frame/trace "0.1.14-SNAPSHOT"
   :description "Tracing and developer tools for re-frame apps"
   :url         "https://github.com/Day8/re-frame-trace"
   :license     {:name "MIT"}


lein-release plugin: bumped version from 0.1.1 to 0.1.2-SNAPSHOT for next development cycle

--- project.clj
+++ project.clj
@@ -1,4 +1,4 @@
-(defproject se.haleby/fake-http "0.1.1"
+(defproject se.haleby/fake-http "0.1.2-SNAPSHOT"
   :description "A client library agonistic way to fake HTTP responses"
   :url "https://github.com/johanhaleby/fake-http"
   :license {:name         "MIT License"


Bump version

Bump version

--- project.clj
+++ project.clj
@@ -1,4 +1,4 @@
-(defproject sablono "0.4.1-SNAPSHOT"
+(defproject sablono "0.5.0-SNAPSHOT"
   :description "Lisp style templating for Facebook's React."
   :url "http://github.com/r0man/sablono"
   :author "r0man"


upgrade cljs again

upgrade cljs again

--- project.clj
+++ project.clj
@@ -10,7 +10,7 @@
                  [figwheel "0.2.5"]
                  [om "0.7.3"]
                  [org.clojure/clojure "1.6.0"]
-                 [org.clojure/clojurescript "0.0-3058"]
+                 [org.clojure/clojurescript "0.0-3115"]
                  [org.clojure/core.rrb-vector "0.0.11"]
                  [org.clojure/core.match "0.3.0-alpha4"]]


new snapshot version

new snapshot version

--- project.clj
+++ project.clj
@@ -1,4 +1,4 @@
-(defproject com.twitter/carbonite "1.4.0"
+(defproject com.twitter/carbonite "1.4.1-SNAPSHOT"
   :source-paths ["src/clj"]
   :java-source-paths ["src/jvm"]
   :javac-options ["-source" "1.6" "-target" "1.6"]


updated deps

updated deps

--- project.clj
+++ project.clj
@@ -5,7 +5,7 @@
             :url "https://www.apache.org/licenses/LICENSE-2.0.html"}
   :dependencies [[dda/dda-pallet "3.0.0"]
                  [dda/dda-serverspec-crate "1.3.4"]
-                 [dda/dda-user-crate "2.0.5"]
+                 [dda/dda-user-crate "2.0.6"]
                  [dda/dda-git-crate "2.2.2"]
                  [dda/dda-backup-crate "1.0.7"]]
   :source-paths ["main/src"]


Release version 0.11.0.0-alpha5.

Release version 0.11.0.0-alpha5.

--- project.clj
+++ project.clj
@@ -1,4 +1,4 @@
-(defproject onyx-cheat-sheet "0.11.0.0-SNAPSHOT"
+(defproject onyx-cheat-sheet "0.11.0.0-alpha5"
   :description "Cheat sheet for Onyx"
   :url "https://github.com/onyx-platform/onyx-cheat-sheet"
   :license {:name "Eclipse Public License"
@@ -16,7 +16,7 @@
                  [compojure "1.5.2"]
                  [enlive "1.1.6"]
                  ^{:voom {:repo "git@github.com:onyx-platform/onyx.git" :branch "master"}}
-                 [org.onyxplatform/onyx "0.11.0-alpha4"]
+                 [org.onyxplatform/onyx "0.11.0-alpha5"]
                  [prismatic/om-tools "0.4.0"]
                  [markdown-clj "0.9.94"]
                  [org.omcljs/om "0.9.0"]


Bump to 0.1.6-SNAPSHOT

Bump to 0.1.6-SNAPSHOT

--- project.clj
+++ project.clj
@@ -1,4 +1,4 @@
-(defproject measure "0.1.5"
+(defproject measure "0.1.6-SNAPSHOT"
   :description "Say things about your application with authority, using Coda Hale's Metrics."
   :url "http://measure.getkeepsafe.com"
   :scm {:name "git"


Release 0.14.0.

Release 0.14.0.

--- project.clj
+++ project.clj
@@ -6,7 +6,7 @@
 ;;   the terms of this license.
 ;;   You must not remove this notice, or any other, from this software.

-(defproject uncomplicate/clojurecl "0.14.0-SNAPSHOT"
+(defproject uncomplicate/clojurecl "0.14.0"
   :description "ClojureCL is a Clojure library for parallel computations with OpenCL."
   :url "https://github.com/uncomplicate/clojurecl"
   :scm {:name "git"


Add docstring to defsample macro

Add docstring to defsample macro

--- src/overtone/sc/sample.clj
+++ src/overtone/sc/sample.clj
@@ -220,5 +220,11 @@
 (derive ::sample :overtone.sc.buffer/file-buffer)
 (derive ::playable-sample ::sample)

-(defmacro defsample [s-name path & args]
+(defmacro defsample
+  "Define a s-name as a var in the current namespace referencing a
+   sample with the specified path and args.
+
+   Equivalent to:
+   (def s-name (sample path args...))"
+  [s-name path & args]
   `(def ~s-name (sample ~path ~@args)))


Free allocated id and throw exception if sample isn't loaded correctly.

--- src/overtone/sc/sample.clj
+++ src/overtone/sc/sample.clj
@@ -41,6 +41,11 @@
           n-frames (get arg-map :n-frames 0)]
       (with-server-sync  #(snd "/b_allocRead" id path start n-frames))
       (let [info   (buffer-info id)
+            _      (when (and (= 0 (:n-frames info))
+                              (= 0.0 (:rate info))
+                              (= 0 (:n-channels info)))
+                     (free-id :audio-buffer id)
+                     (throw (Exception. (str "Unable to load sample - file does not appear to be a valid audio file: " path))))
             sample (with-meta {:allocated-on-server (atom true)
                                :id id
                                :path path


make REPL init restore previous build sources

--- src/main/shadow/cljs/repl.clj
+++ src/main/shadow/cljs/repl.clj
@@ -147,7 +147,7 @@
     ))

 (defn prepare
-  [build-state]
+  [{:keys [build-sources] :as build-state}]
   {:pre [(build-api/build-state? build-state)]}
   (let [{:keys [repl-state] :as build-state}
         (setup build-state)
@@ -159,7 +159,8 @@
         (build-api/compile-sources repl-sources)
         ;; make sure sources exist on disk so the REPL can actually load them
         (output/flush-sources repl-sources)
-        (async/wait-for-pending-tasks!))))
+        (async/wait-for-pending-tasks!)
+        (assoc :build-sources build-sources))))

 (defn load-macros-and-set-ns-info
   "modifies the repl and analyzer state to reflect the updated ns changes done by require in the REPL"


Pass request ids directly to callback functions

--- src/lib/cljs/one/browser/remote.cljs
+++ src/lib/cljs/one/browser/remote.cljs
@@ -24,8 +24,8 @@
   (>= status 400))

 (defn- handle-response
-  [on-success on-error e]
-  (let [response {:id     (.-id e)
+  [on-success on-error id e]
+  (let [response {:id     id
                   :body   (. e/currentTarget (getResponseText))
                   :status (. e/currentTarget (getStatus))
                   :event  e}
@@ -44,7 +44,9 @@

   Other allowable keyword arguments are `:method`, `:content`, `:headers`,
   `:priority`, and `:retries`. `:method` defaults to \"GET\" and `:retries`
-  defaults to `0`."
+  defaults to `0`.
+
+  `priority` defaults to 100. The lower the number the higher the priority."
   [id url & {:keys [method content headers priority retries
                     on-success on-error]
              :or   {method   "GET"
@@ -57,11 +59,11 @@
            content
            (when headers (.-strobj headers))
            priority
-           (partial handle-response on-success on-error)
+           (partial handle-response on-success on-error id)
            retries)
     (catch js/Error e
       nil)))

 (defn url
   [path]
-  (str (.-origin (.-location js/document)) path))+  (str (.-origin (.-location js/document)) path))


(maint) Remove i18n tests for travis

(maint) Remove i18n tests for travis

This commit removes i18n middleware tests as they fail on travis because
the locales aren't installed. They also fail locally if the spanish
locale isn't installed. This is a temporary hack until we figure out a
more permnanent solution.

--- test/puppetlabs/puppetdb/middleware_test.clj
+++ test/puppetlabs/puppetdb/middleware_test.clj
@@ -1,7 +1,6 @@
 (ns puppetlabs.puppetdb.middleware-test
   (:import [java.io ByteArrayInputStream])
   (:require [puppetlabs.kitchensink.core :as kitchensink]
-            [puppetlabs.i18n.core :as i18n]
             [puppetlabs.puppetdb.http :as http]
             [ring.util.response :as rr]
             [cheshire.core :as json]
@@ -107,13 +106,7 @@
     (testing "should return an error response if unknown parameters are present"
       (let [{:keys [status body]} (wrapped-fn {:params {"foo" 1 "bar" 2 "wazzup" 3}})]
         (is (= http/status-bad-request status))
-        (is (= "Unsupported query parameter 'wazzup'" body))))
-    (testing "error responses with unknown parameters are translated"
-      (let [es (i18n/string-as-locale "es")]
-        (i18n/with-user-locale es
-          (let [{:keys [status body]} (wrapped-fn {:params {"foo" 1 "bar" 2 "wazzup" 3}})]
-            (is (= http/status-bad-request status))
-            (is (= "Parámetro no admitido 'wazzup'" body))))))))
+        (is (= "Unsupported query parameter 'wazzup'" body))))))

 (deftest verify-content-type-test
   (testing "with content-type of application/json"
@@ -146,22 +139,6 @@
         (let [wrapped-fn   (verify-content-type identity ["application/json"])]
           (is (= (wrapped-fn test-req) test-req)))))))

-(defmacro with-system-locale
-  "Evaluate body with the user locale set to locale.
-  TODO This code should be moved to the clj-i18n repo."
-  [locale & body]
-  `(let [locale# ~locale
-         default# (i18n/system-locale)]
-     (if (instance? java.util.Locale locale#)
-       (try
-         (. java.util.Locale setDefault locale#)
-         ~@body
-         (finally
-           (. java.util.Locale setDefault default#)))
-       (throw (IllegalArgumentException.
-               (str "Expected java.util.Locale but got "
-                    (.getName (.getClass locale#))))))))
-
 (deftest whitelist-middleware
   (testing "should log on reject"
     (let [wl (temp-file "whitelist-log-reject")]
@@ -170,18 +147,7 @@
         (is (= :authorized (authorizer-fn {:ssl-client-cn "foobar"})))
         (with-log-output logz
           (is (string? (authorizer-fn {:ssl-client-cn "badguy"})))
-          (is (= 1 (count (logs-matching #"^badguy rejected by certificate whitelist " @logz))))))))
-
-  (let [es (i18n/string-as-locale "es")]
-    (with-system-locale es
-      (testing "should log in Spanish on reject"
-        (let [wl (temp-file "whitelist-log-reject")]
-          (spit wl "foobar")
-          (let [authorizer-fn (build-whitelist-authorizer (fs/absolute-path wl))]
-            (is (= :authorized (authorizer-fn {:ssl-client-cn "foobar"})))
-            (with-log-output logz
-              (is (string? (authorizer-fn {:ssl-client-cn "badguy"})))
-              (is (= 1 (count (logs-matching #"^badguy fue rechazado por el certificado de la lista blanca " @logz)))))))))))
+          (is (= 1 (count (logs-matching #"^badguy rejected by certificate whitelist " @logz)))))))))

 (deftest test-fail-when-payload-too-large
   (testing "max-command-size-fail disabled should allow commands of any size"


Improve verbose printing

Improve verbose printing

--- src/clj/jest/jest.clj
+++ src/clj/jest/jest.clj
@@ -32,6 +32,27 @@
   (System/exit status))

+(defn line-break [n]
+  (str/join (repeat n "=")))
+
+
+(defn verbose-print-jest-source [source-code]
+  "Print helpful information based on the
+  input source code we're running"
+
+  (println "\n" "Raw input source code: \n")
+  (println (line-break 20))
+  (println source-code)
+  (println (line-break 20))
+
+  (println "\n" "Translated into Clojure: \n")
+  (println (line-break 20))
+  (print-jest source-code)
+  (println (line-break 20))
+
+  (println "\n" "Program Output: \n"))
+
+
 (defn -main [& args]
   (let [{:keys [options arguments errors summary]} (parse-opts args cli-options)]
     ;; Read the main file and parse it
@@ -42,7 +63,9 @@

     (let [source-file (first arguments)
           source-code (slurp source-file)]
-      (if (:verbose options) (do
-                               (println source-code)
-                               (print-jest source-code)) nil)
+
+      ;; Print some helpful output for testing/debugging
+      (cond (:verbose options) (verbose-print-jest-source source-code))
+
+      ;; Run all the things!
       (eval-jest source-code))))


cljs util#clj->js shouldn't rely on .-strobj implementation detail.

--- src/cljs/c2/util.cljs
+++ src/cljs/c2/util.cljs
@@ -8,12 +8,19 @@
    keywords into JavaScript strings."
   [x]
   (cond
-   (string? x) x
+   (string? x)  x
    (keyword? x) (name x)
-   (map? x) (.-strobj (reduce (fn [m [k v]]
-                                (assoc m (clj->js k) (clj->js v))) {} x))
-   (coll? x) (apply array (map clj->js x))
+   (map? x)     (reduce (fn [o [k v]]
+                          (let [key (clj->js k)]
+                            (when-not (string? key)
+                              (throw "Cannot convert; JavaScript map keys must be strings"))
+                            (aset o key (clj->js v))
+                            o))
+                        (js-obj) x)
+   (coll? x)    (apply array (map clj->js x))
    :else x))
+
+

 (defn ->coll
   "Convert something into a collection, if it's not already."


Fixed repness issue with bad repful agreement

--- src/polismath/clusters.clj
+++ src/polismath/clusters.clj
@@ -424,23 +424,30 @@
       (> (max rat rdt) current-best-z)))

-(defn- beats-best-agrr?
+(defn- beats-best-agr?
   "Like beats-best-by-test?, but only considers agrees. Additionally, doesn't focus solely on repness,
   but also on raw probability of agreement, so as to ensure that there is some representation of what
   people in the group agree on. Also, note that this takes the current-best, instead of just current-best-z."
-  [{:keys [ra rat pa pat] :as comment-conv-stats} current-best]
+  [{:keys [ra rat pa pat ns] :as comment-conv-stats} current-best]
   (cond
+   ; Explicitly don't let something that hasn't been voted on at all come into repness
+    (= ns 0)
+        false
+    ; If we have a current-best by repness estimate, use the more robust measurement
     (and current-best (> (:ra current-best) 1.0))
         ; XXX - a litte messy, since we're basicaly reimplimenting the repness sort function
         (> (* ra rat pa pat) (apply * (map current-best [:ra :rat :pa :pat])))
+    ; If we have current-best, but only by prob estimate, just shoot for something that is generally agreed upon
     current-best
         (> (* pa pat) (apply * (map current-best [:pa :pat])))
+    ; Otherwise, accept if either repness or probability look generally good
     :else
-        (or (> ra 1.0)
-            (> pa 0.5))))
-
-
-(defn passes-by-test?
+        (or (z-sig-90? pat)
+            (and (> ra 1.0)
+                 (> pa 0.5)))))
+
+
+(defn- passes-by-test?
   "Decide whether we should count a given comment-conv-stat hash-map as being representative."
   [{:keys [pat rat pdt rdt] :as comment-conv-stats}]
   (or (and (z-sig-90? rat) (z-sig-90? pat))
@@ -465,13 +472,15 @@
      :repful-for   repful-for}))

+(defn repness-metric
+  [{:keys [repness repness-test p-success p-test]}]
+  (* repness repness-test p-success p-test))
+
+
 (defn repness-sort
   [repdata]
   (sort-by
-    (fn [data] (- (* (:repness data)
-                     (:repness-test data)
-                     (:p-success data)
-                     (:p-test data))))
+    (comp - repness-metric)
     repdata))

@@ -519,7 +528,7 @@
                   (gr-assoc gr :best (finalize-cmt-stats tid comment-conv-stats))
                   gr)
                 ; Also keep track of best agree comment is, so we can throw that the front preferentially
-                (if (beats-best-agrr? comment-conv-stats (gr-get gr :best-agree))
+                (if (beats-best-agr? comment-conv-stats (gr-get gr :best-agree))
                   (gr-assoc gr :best-agree (assoc comment-conv-stats :tid tid))
                   gr))))
           result
@@ -529,20 +538,22 @@
     ; If no sufficient, use best; otherwise sort sufficient and take 5
     (map-vals
       (fn [{:keys [best best-agree sufficient]}]
-        (let [best-agree (if best-agree
-                           (finalize-cmt-stats (:tid best-agree) best-agree)
-                           best-agree)]
+        (let [best-agree (when best-agree
+                           (finalize-cmt-stats (:tid best-agree) best-agree))
+              best-head (cond
+                          best-agree [best-agree]
+                          best       [best]
+                          :else      [])]
+          (println best-agree)
+          ; If there weren't any matches of the criteria, just take the best match, and take the best agree if
+          ; possible, and if not just the best general
           (if (empty? sufficient)
-            ; If there weren't any matches of the criteria, just take the best match, and take the best agree if
-            ; possible, and if not just the best general
-            (if best-agree
-              [best-agree]
-              [best])
+            best-head
             (->> sufficient
                  ; Remove best agree if in list, since we'll be putting it in manually
                  (remove #(= best-agree %))
                  (repness-sort) ; sort by our complicated repness metric
-                 (concat [best-agree]) ; put best agree at front, regardless
+                 (concat (if best-agree [best-agree] [])) ; put best agree at front, if possible
                  (take 5) ; take the top 5
                  (agrees-before-disagrees))))))))


More cleanup of profiling code

More cleanup of profiling code

--- src/polismath/clusters.clj
+++ src/polismath/clusters.clj
@@ -95,7 +95,6 @@
   [data clusters]
   (as-> clusters clsts
     ; map every cluster to the newly centered cluster or to nil if there are no members in data
-    (p :safe-recenter-map (greedy
     (map
       (fn [clst]
         (let [rns (safe-rowname-subset data (:members clst))]
@@ -103,7 +102,6 @@
             nil
             (assoc clst :center (mean (matrix (get-matrix rns)))))))
       clsts)
-      ))
     ; Remove the nils, they break the math
     (remove nil? clsts)
     ; If nothing is left, make one great big cluster - so that things don't break in most-distal later
@@ -112,9 +110,7 @@
       [{:id (inc (apply max (map :id clusters)))
         :members (rownames data)
         :center (mean (matrix (get-matrix data)))}]
-      clsts)
-    ; XXX - for profiling
-    (greedy clsts)))
+      clsts)))

 (defn merge-clusters [clst1 clst2]
@@ -173,7 +169,6 @@
             (if (> (:dist outlier) 0)
               ; There is work to be done, so do it
               (recur
-              (p :usr/inner-clean
                 (->
                   ; first remove the most distal point from the cluster it was in;
                   (map
@@ -184,7 +179,7 @@
                   ; next add a new cluster containing only said point.
                   (conj {:id (inc (apply max (map :id clusters)))
                          :members [(:id outlier)]
-                         :center (get-row-by-name data (:id outlier))}))))
+                         :center (get-row-by-name data (:id outlier))})))
               ; Else just return recentered clusters
               clusters))
           ; Else just return recentered clusters


Documented repness code

Documented repness code

--- src/polismath/clusters.clj
+++ src/polismath/clusters.clj
@@ -278,7 +278,10 @@
          (apply concat))))

-(defn- count-votes [votes & [vote]]
+(defn- count-votes
+  [votes & [vote]]
+  "Utility function for counting the number of votes matching `vote`. Not specifying `vote` returns
+  length of vote vector."
   (let [filt-fn (if vote #(= vote %) identity)]
     (count (filter filt-fn votes))))

@@ -297,12 +300,16 @@
   ; This can cause PermGen space crashes.
   (defn- initial-comment-stats
     "Vote count stats for a given vote column. This vote column should represent the votes for a specific
-    comment and group. Group comparisons happen later."
+    comment and group. Comparisons _between_ groups happen later. See `(doc conv-repness)` for key details."
     [vote-col]
     (initial-comment-stats-graphimpl {:votes vote-col})))

-(defn- add-comparitive-stats [in-stats rest-stats]
+(defn- add-comparitive-stats
+  "Builds on results of initial-comment-stats by doing comparisons _between_ groups. Args are
+  in group stats (as returned by initial-comment-stats), and list of stats for rest of groups.
+  See `(doc conv-repness)` for key details."
+  [in-stats rest-stats]
   (assoc in-stats
     :ra (/ (:pa in-stats)
            (/ (+ 1 (pc/sum :na rest-stats))
@@ -317,12 +324,19 @@

 (defn conv-repness
-  ; output legend: n=#, p=prob, r=rep, t=test, a=agree, d=disagree, s=seen
+  "Computes representativeness (repness) for a given data set, group clustering and base clustering,
+  returned as a map `{:ids __ :stats __}`. The `:stats` key maps to a sequences of results, one for each
+  group cluster, each of which is a sequence where the positional index corresponds to a particular
+  comment, and each value is a hash-map of statistics for the given group/comment. The hash keys obey the
+  following legend:
+    n=#, p=prob, r=rep, t=test, a=agree, d=disagree, s=seen
+  The :ids key maps to a vector of group ids in the same order they appear in the :stats sequence."
   [data group-clusters base-clusters]
   {:ids (map :id group-clusters)
    :stats
      (->> group-clusters
-       ; Base clusters may not be necessary if we use the already compute bucket vote stats
+       ; XXX - Base clusters may not be necessary if we use the already compute bucket vote stats
+       ; A lazy-seq of
        (mapv (comp columns get-matrix (partial rowname-subset data) #(group-members % base-clusters)))
        (apply
          map
@@ -333,18 +347,24 @@

 (defn beats-best-by-test?
+  "Returns true if a given comment/group stat hash-map has a more representative z score than
+  current-best-z. Used for making sure we have at least _one_ representative comment for every group,
+  even if none are left over after the more thorough filters."
   [{:keys [pat rat rdt] :as comment-conv-stats} current-best-z]
   (or (nil? current-best-z)
       (> (max rat rdt) current-best-z)))

 (defn passes-by-test?
+  "Decide whether we should count a given comment-conv-stat hash-map as being representative."
   [{:keys [pat rat pdt rdt] :as comment-conv-stats}]
   (or (and (z-sig-90? rat) (z-sig-90? pat))
       (and (z-sig-90? rdt) (z-sig-90? pdt))))

 (defn finalize-cmt-stats
+  "Formats comment/repness stats to be consumable by clients. In particular, chooses between
+  agree/disagree as to which is more representative, and populates a more regular structure accordingly."
   [tid {:keys [na nd ns pa pd pat pdt ra rd rat rdt] :as comment-conv-stats}]
   (let [[n-success n-trials p-success p-test repness repness-test repful-for]
          (if (> rat rdt)
@@ -361,6 +381,9 @@

 (defn select-rep-comments
+  "Selects representative comments based on beats-best-by-test? and passes-by-test?. Always ensures
+  there is at least one representative comment for a given cluster. Takes the results of conv-repness
+  and returns a map of group cluster ids to representative comments and stats."
   [{:keys [ids stats] :as repness-stats}]
   ; Reduce statistics into a results hash mapping group ids to rep comments
   (->>


consider static

consider static

--- src/ganjika/core.clj
+++ src/ganjika/core.clj
@@ -16,7 +16,8 @@
    :is-void (-> m
                  .getReturnType
                  .getName
-                 (= "void"))})
+                 (= "void"))
+   :is-static (java.lang.reflect.Modifier/isStatic (.getModifiers m))})

 (defn- declare-fn
   "Given a method spec create an unevaluated function form, currying
@@ -24,19 +25,27 @@
   [spec instance no-currying]
   (let [method-name (symbol (:name spec))
         raw-method-name (symbol (str "." (:raw-name spec)))
+        static-method-name (symbol (str (.getName instance) "/" (:raw-name spec)))
         params (vec (map gensym (range (:args spec))))
         is-void (:is-void spec)]
-    (if no-currying
-      `(defn ~method-name [this# ~@params]
-         (let [return# (~raw-method-name this# ~@params)]
-           (if ~is-void
-             this#
-             return#)))
-      `(defn ~method-name [~@params]
-         (let [return# (~raw-method-name @~instance ~@params)]
-           (if ~is-void
-             @~instance
-             return#))))))
+    (cond
+     ;; define function for static method
+     (:is-static spec)
+     `(def ~method-name (fn ([~@params] (~static-method-name ~@params))))
+     ;; define non-curried function
+     no-currying
+     `(defn ~method-name [this# ~@params]
+        (let [return# (~raw-method-name this# ~@params)]
+          (if ~is-void
+            this#
+            return#)))
+     ;; define curried function
+     :else
+     `(defn ~method-name [~@params]
+        (let [return# (~raw-method-name @~instance ~@params)]
+          (if ~is-void
+            @~instance
+            return#))))))

 (defn- define-symbol
   "Creates and return a symbol that resolves to the provided object"
@@ -60,7 +69,7 @@
                           (class? target) [target (.newInstance target)]
                           :else [(class target) target])
         specs (map method-spec (.getDeclaredMethods clazz))
-        target-sym (if-not no-currying (define-symbol instance))
+        target-sym (if no-currying clazz (define-symbol instance))
         current-ns (.getName *ns*)]
     (when-not no-currying (assert (instance? clazz instance)))
     `(do
@@ -70,6 +79,10 @@
        (in-ns (quote ~current-ns)))))

 (comment
-  ;; multiple arity
+  ;;- multiple arity
+  ;;- currying must be disabled by default for static methods
+  ;; and field/static methods with the same name??? renaming?
+  ;;- and only public methods... or make them public????
+  ;;- better interop by coercing argument types
   (refer 'fus.noma.da :only ['mouse-move])
   (to-clj java.awt.Robot :using-ns 'fus.noma.da))


Fix error

Fix error

--- src/org/spootnik/cyanite/es_path.clj
+++ src/org/spootnik/cyanite/es_path.clj
@@ -107,7 +107,7 @@
                    :search_type "query_then_fetch"
                    :scroll "1m")
         paths-count (esrr/total-hits res)]
-    (if (and threshold (>  threshold))
+    (if (and threshold (> paths-count threshold))
       (throw (too-many-paths-ex :path-search paths-count))
       (map #(:_source %) (scroll res)))))


Remove private board author access for team admins.

--- src/oc/storage/api/access.clj
+++ src/oc/storage/api/access.clj
@@ -117,9 +117,6 @@

       ;; an org author of this non-private board
       (and (not= board-access :private) (org-authors user-id)) {:access-level :author}
-
-      ;; an admin of this org's team
-      ((set admin) (:team-id org)) {:access-level :author}

       ;; a named viewer of this board
       (and (= board-access :private) (board-viewers user-id)) {:access-level :viewer}


add a few more bodies that some modern astrologers would expect

--- src/clj/ephemeris_api/points.clj
+++ src/clj/ephemeris_api/points.clj
@@ -23,6 +23,12 @@
 (a :Neptune (. SweConst SE_NEPTUNE))
 (a :Pluto (. SweConst SE_PLUTO))
 (a :TrueNode (. SweConst SE_TRUE_NODE))
+(a :Chiron (. SweConst SE_CHIRON))
+(a :Pholus (. SweConst SE_PHOLUS))
+(a :Ceres (. SweConst SE_CERES))
+(a :Pallas (. SweConst SE_PALLAS))
+(a :Juno (. SweConst SE_JUNO))
+(a :Vesta (. SweConst SE_VESTA))

 (defn- datv [id v] (v (id (deref dat))))


Don't include blank string as kube node tags.

--- src/clj/shale/node_providers.clj
+++ src/clj/shale/node_providers.clj
@@ -112,7 +112,9 @@
                  :annotations
                  (:shale/node-tags "")
                  (clojure.string/split #";")
-                 (->> (into #{})))]
+                 (->> (map clojure.string/trim)
+                      (remove clojure.string/blank?)
+                      (into #{})))]
     {:url url
      :tags tags}))


changed game view style

changed game view style

--- src/cljs/dictionator/common.cljs
+++ src/cljs/dictionator/common.cljs
@@ -11,25 +11,42 @@
            (dom/p #js {:className "footer_p"}
                   "Made with ♥ CodeCouple")))

-;; Wrapper for the game part - for single page application
+
+
+(defui GamePlayer
+  static om/IQuery
+  (query [this]
+         [])
+  Object
+  (render [this]
+          (dom/li #js {:className "list-group-item"}
+                  (dom/span #js {:className "badge"}
+                            "1984")
+                  "Dajanka")))
+
+
+;; Wrapper for the game part
 (defui Game
   static om/IQuery
   (query [this]
          [:players :current-word])
   Object
   (render [this]
-          (dom/span #js {:className "glyphicon glyphicon-star points"}
-                    (dom/p #js {} 0))
           (dom/div #js {:className "row"}
-                   (dom/div #js {:className "col-md-12 text-center previous-word"}
-                            (dom/h3 #js {:className "prev"} "Previous word: ")
-                            (dom/p #js {} "Herisk")
-                            (dom/p #js {:className "last-letter"} "o"))
-                   (dom/div #js {:className "col-md-12 text-center"}
+                   (dom/div #js {:className "col-md-6 text-center"}
+                            (dom/div #js {:className "col-md-12 text-center previous-word"}
+                                     (dom/h3 #js {:className "prev"} "Previous word: ")
+                                     (dom/p #js {} "Herisk")
+                                     (dom/p #js {:className "last-letter"} "o"))
                             (dom/form #js {}
                                       (dom/input #js {:className "input-word"
                                                       :type "text"
-                                                      :placeholder ""}))))
+                                                      :placeholder ""})))
+                   (dom/div #js {:className "col-md-3 player-list"}
+                            (dom/ul #js {:className "list-group points"}
+                                    (dom/h3 #js {} "Points")
+                                    "Points")))
+
           footer))

 ;; Factory for game wrapper


just vertical scroll in autocomplete

just vertical scroll in autocomplete

--- src/cljs/material/component.cljs
+++ src/cljs/material/component.cljs
@@ -251,7 +251,8 @@
 (defn autocomplete [props]
   (auto-complete
     (merge props
-           {:listStyle {:maxHeight "230px"}})))
+           {:listStyle {:overflow-y  "scroll"
+                        :maxHeight "230px"}})))

 ;; Panel elements


function draw-kantor-lines added

function draw-kantor-lines added

--- src/cljs/wonderful_lib/core.cljs
+++ src/cljs/wonderful_lib/core.cljs
@@ -144,13 +144,11 @@
 (kantor-lines-2 [0 3] 4)

+(defn draw-kantor-lines [segments]
+  (doseq [[segment-start segment-end] segments]
+    (.beginPath context)
+    (.moveTo context segment-start 100)
+    (.lineTo context segment-end 100)
+    (.stroke context)))

-#_(defn draw [[frame-start frame-end] gaps]
-  (let [ln-3 (Math/log 3)
-        s-max (order frame-start)
-        highest-x s-max
-        s-target (order frame-end)
-        highest-step (/ s-max 3)
-        s1 highest-step
-        s2 (* 2 highest-step)]
-    ()))
+;(draw-kantor-lines (kantor-lines-2 [0 300] 3))


Removed unnecessary functions.

Removed unnecessary functions.

--- src/cmr/opendap/ous/variable.clj
+++ src/cmr/opendap/ous/variable.clj
@@ -210,26 +210,12 @@
      (geog/bounding-box->lookup-record
       lon-max lat-max bounding-box (:reversed? opts)))))

-(defn format-opendap-dim-lat
-  ([bounding-info]
-   (format-opendap-dim-lat bounding-info geog/default-lat-lon-stride))
-  ([bounding-info stride]
-   (if-let [opendap-bounds (:opendap bounding-info)]
-     (geog/format-opendap-dim-lat opendap-bounds stride)
-     "")))
-
-(defn format-opendap-dim-lon
-  ([bounding-info]
-   (format-opendap-dim-lon bounding-info geog/default-lat-lon-stride))
-  ([bounding-info stride]
-   (if-let [opendap-bounds (:opendap bounding-info)]
-     (geog/format-opendap-dim-lon opendap-bounds stride)
-    "")))
-
 (defn replace-defaults-lat-lon
   [bounding-info stride [k v]]
-  (cond (= k :Longitude) (format-opendap-dim-lon bounding-info stride)
-        (= k :Latitude) (format-opendap-dim-lat bounding-info stride)
+  (cond (= k :Longitude) (geog/format-opendap-dim-lon
+                          (:opendap bounding-info) stride)
+        (= k :Latitude) (geog/format-opendap-dim-lat
+                         (:opendap bounding-info) stride)
         :else (geog/format-opendap-dim 0 stride (dec v))))

 (defn format-opendap-dims


Typo on docs

Typo on docs

--- src/com/wsscode/pathom/core.cljc
+++ src/com/wsscode/pathom/core.cljc
@@ -298,7 +298,7 @@
     input))

 (defn transduce-children
-  "Recursivelly transduce children on the AST, you can use this to apply filter/transformations
+  "Recursively transduce children on the AST, you can use this to apply filter/transformations
   on a whole AST. Each iteration of the transducer will get a single AST node to process.

   ```


Add a :latest filter to the search engine

This patch adds a way that users can restrict searches to the latest
versions of documented artifacts to prevent duplication of results
across versions since this is _really_ hard to check for.

--- src/grimoire/api.clj
+++ src/grimoire/api.clj
@@ -452,6 +452,7 @@
   - Strings as a term match any Thing with an equal Name
   - Regexps as a Term match any Thing with a matching Name
   - Fns as a term match any Thing such that (f T) is truthy
+  - :latest is a speciao Version which matches only the latest one

   Examples:
   > [:def :any :any :any :any \"clojure.core\" \"concat\"]
@@ -541,6 +542,11 @@
                    ,,(let [ctor (forge pattern)]
                        (map #(ctor % el) results))

+                   (and (= el :latest)
+                        (= list-fn list-versions))
+                   ,,(for [r results]
+                       (first (e/result (list-fn cfg r))))
+
                    :else
                    ,,(for [r     results
                            ir    (e/result (list-fn cfg r))


Fixing inst bug on redefinition.

Fixing inst bug on redefinition.

* after a previous reworking the bus was incorrectly getting
changed when an instrument was redefined... fixed.

--- src/overtone/studio/mixer.clj
+++ src/overtone/studio/mixer.clj
@@ -111,7 +111,7 @@
   (dosync (ref-set instruments* {})))

 (defmacro pre-inst
-  [inst-bus & args]
+  [& args]
   (let [[sname params param-proxies ugen-form] (normalize-synth-args args)]
     `(let [~@param-proxies]
        (binding [*ugens* []
@@ -119,7 +119,7 @@
          (with-overloaded-ugens
            (let [form# ~@ugen-form
                  n-chans# (count form#)
-                 inst-bus# (audio-bus n-chans#)]
+                 inst-bus# (or (:bus (get @instruments* ~sname)) (audio-bus n-chans#))]
              (out inst-bus# form#)
              [~sname
               ~params
@@ -130,14 +130,15 @@

 (defmacro inst
   [sname & args]
-  `(let [[sname# params# ugens# constants# n-chans# inst-bus#] (pre-inst inst-bus# ~sname ~@args)
-         container-group# (or (:group (get @instruments* sname#))
+  `(let [[sname# params# ugens# constants# n-chans# inst-bus#] (pre-inst ~sname ~@args)
+         new-inst# (get @instruments* sname#)
+         container-group# (or (:group new-inst#)
                               (group :tail @inst-group*))
-         instance-group#  (or (:instance-group (get @instruments* sname#))
+         instance-group#  (or (:instance-group new-inst#)
                               (group :head container-group#))
-         fx-group#        (or (:fx-group (get @instruments* sname#))
+         fx-group#        (or (:fx-group new-inst#)
                               (group :tail container-group#))
-         imixer#    (or (:mixer (get @instruments* sname#))
+         imixer#    (or (:mixer new-inst#)
                         (inst-mixer :tgt container-group# :pos :tail :in-bus inst-bus#))
          sdef#      (synthdef sname# params# ugens# constants#)
          arg-names# (map :name params#)


return empty body from Twilio post

return empty body from Twilio post

--- src/pc/http/routes/twilio.clj
+++ src/pc/http/routes/twilio.clj
@@ -21,6 +21,7 @@
                                                                            :MessageStatus :MessageSid])))
       (log/infof "message to %s succeeded with %s"
                  (:To params) (:MessageStatus params)))
-    {:status 200}))
+    {:status 200
+     :body ""}))

 (def hooks-app (defpage/collect-routes))


Include name in defview anonymous function

--- src/re_view/core.clj
+++ src/re_view/core.clj
@@ -59,12 +59,12 @@

 (clojure.core/defn wrap-body
   "Wrap body in anonymous function form."
-  [body]
+  [name body]
   (cond (vector? (first body))
-        `(~'fn ~(first body) (~'re-view-hiccup.core/element (do ~@(rest body))))
+        `(~'fn ~name ~(first body) (~'re-view-hiccup.core/element (do ~@(rest body))))
         (list? (first body))
-        `(~'fn ~@(mapv (fn [body]
-                         `(~(first body) (~'re-view-hiccup.core/element (do ~@(rest body))))) body))
+        `(~'fn ~name ~@(mapv (fn [body]
+                               `(~(first body) (~'re-view-hiccup.core/element (do ~@(rest body))))) body))
         :else `(~'throw (~'js/Error ~(str "Invalid render function: " body)))))

 (defmacro defview
@@ -78,18 +78,21 @@
         methods (-> methods
                     (merge {:react/docstring docstring
                             :display-name    (display-name *ns* view-name)
-                            :life/render     (wrap-body body)})
+                            :life/render     (wrap-body view-name body)})
                     (group-methods))]
     `(def ~view-name ~docstring (~'re-view.core/view* ~methods))))

 (defmacro view
   "Returns anonymous view, given the same args as `defview`."
   [& args]
-  (let [[docstring methods body] (parse-view-args args)
+  (let [view-name (if (symbol? (first args))
+                    (first args)
+                    nil)
+        [docstring methods body] (parse-view-args (if view-name (rest args) args))
         methods (-> methods
                     (merge {:react/docstring docstring
-                            :display-name    (display-name *ns*)
-                            :life/render     (wrap-body body)})
+                            :display-name    (if view-name (display-name *ns* view-name) (display-name *ns*))
+                            :life/render     (wrap-body view-name body)})
                     (group-methods))]
     `(~'re-view.core/view* ~methods)))


CMR-2820: Added another test for multiple identity-type searches

--- access-control-app/int_test/cmr/access_control/int_test/acl_search_test.clj
+++ access-control-app/int_test/cmr/access_control/int_test/acl_search_test.clj
@@ -261,7 +261,10 @@
         "Identity type 'catalog_item'"
         ["catalog_item"] [acl-catalog-item]

-        "Mixed identity types"
+        "Multiple identity types"
+        ["provider" "single_instance"] [acl-provider acl-single-instance]
+
+        "All identity types"
         ["provider" "system" "single_instance" "catalog_item"] all-acls

         "Identity type searches are always case-insensitive"


Docstring fix

Docstring fix

--- src/shuriken/monkey_patch.clj
+++ src/shuriken/monkey_patch.clj
@@ -28,7 +28,7 @@
 (defmacro only
   "Ensures `body` is executed only once with respect to `name`.
   If `name` is a symbol or a keyword without a namespace, it will be
-  prefixed with `*ns*`.
+  prefixed with the value of `*ns*`.

   ```clojure
   (only 'foo (println \"bar\"))


Focus management #38

Focus management #38

--- src/flatgui/focus.clj
+++ src/flatgui/focus.clj
@@ -20,14 +20,19 @@
 (def having-focus-state {:mode :has-focus
                          :focused-child nil})

-(defn temporarily-taken-from-state [permanent-owner-child] {:mode :has-focus
-                                                            :focused-child permanent-owner-child})
+(defn temporarily-taken-from-state [permanent-owner-child dir] {:mode :has-focus
+                                                                :focused-child permanent-owner-child
+                                                                :throw-mode dir})

 (defn focus-child [child-id]
   (if (keyword? child-id)
     {:mode :parent-of-focused
      :focused-child child-id}
     (throw (IllegalArgumentException. (str "child-id must be a keyword but is: " child-id)))))
+
+;; For :parent-of-focused and :has-focus the latest focus movent direction (if any) is tracked in :throw-mode
+(defn focus-child-by-direction [child-id dir]
+  (assoc (focus-child child-id) :throw-mode dir))

 (defn accepts-focus? [component]
   (or
@@ -91,11 +96,12 @@
         :else old-focus-state)

       (fgc/parent-reason? reason)
-      (case (do (println "Parent event into " (:id component) " parent-mode " parent-mode " this-mode " this-mode) parent-mode)
+      (case parent-mode
         ;; If parent has focus temporarily, I take focus back (*2)
         ;; Otherwise my parent has focus permanently and my state is clean
         :has-focus (if (= parent-focused-child (:id component)) ; This condition means that parent has focus temporarily
-                     having-focus-state
+                     ;; Parent keeps latest throwing direction in :throw-mode in this case. Track it for further use
+                     (assoc having-focus-state :throw-mode (:throw-mode parent-focus-state))
                      clean-state)
         ;:has-focus clean-state
         :none clean-state
@@ -114,10 +120,17 @@
                                                                         (for [[_ c] (:children component)] c))))]
                                                    requesting-child-id
                                                    (if (not (:focusable component))
-                                                     (get-in-cycle component :first)))]
-                                 (focus-child child-id)
+                                                     (get-in-cycle
+                                                       component
+                                                       ;; In case latest focus movent direction is tracked
+                                                       ;; in :throw-mode - use it to determine firt or last
+                                                       (if (= :prev (:throw-mode parent-focus-state))
+                                                         :last
+                                                         :first))))]
+                                 (focus-child-by-direction child-id (:throw-mode parent-focus-state))
                                  having-focus-state)
-                               old-focus-state)
+                               ;; No change in state but track focus movent direction
+                               (assoc old-focus-state :throw-mode (:throw-mode parent-focus-state)))

                              ;; Another component next to me has focus, therefore my state is clean
                              clean-state)
@@ -132,23 +145,22 @@
       (let [child-id (nth reason 1)
             child-focus-state (get-property [:this child-id] :focus-state)
             child-mode (:mode child-focus-state)
-            child-throw-mode (:throw-mode child-focus-state)
-            _ (println "Child even into " (:id component) " child " child-id " mode " child-mode " thm " child-throw-mode)]
+            child-throw-mode (:throw-mode child-focus-state)]
         (case child-mode
           ;; Nothing to change in this case
           :none old-focus-state

           ;; If my child is the parent of focused component (or parent of parent ...)
           ;; then I'm :parent-of-focused as well
-          :parent-of-focused (focus-child child-id)
+          :parent-of-focused (focus-child-by-direction child-id child-throw-mode)

           ;; My child has focus itself - same thing
-          :has-focus (focus-child child-id)
+          :has-focus (focus-child-by-direction child-id child-throw-mode)

           :requests-focus (case this-mode
                             ;; I'm the parent of focused component (no matter which exactly) and my child requests
                             ;; focus - then I note that this child becomes the new focus owner. My :mode stays the same
-                            :parent-of-focused (focus-child child-id)
+                            :parent-of-focused (focus-child-by-direction child-id (:throw-mode old-focus-state))

                             ;; If I have focus and my child requests it - I give focus to it
                             :has-focus (focus-child child-id)
@@ -172,8 +184,9 @@
                                   (if (= prev-child this-focused-child)
                                     ;; My child throws focus, but there is no other component to take it.
                                     ;; So I take it temporarily and child will take back within the next step. (*2)
-                                    (temporarily-taken-from-state this-focused-child)
-                                    (focus-child prev-child))
+                                    ;; Latest movement direction is tracked to be used within the next step
+                                    (temporarily-taken-from-state this-focused-child :prev)
+                                    (focus-child-by-direction prev-child :prev))
                                   {:mode :throws-focus
                                    :throw-mode :prev
                                    :focused-child this-focused-child})
@@ -185,20 +198,25 @@
                                   (if (= next-child this-focused-child)
                                     ;; My child throws focus, but there is no other component to take it.
                                     ;; So I take it temporarily and child will take back within the next step. (*2)
-                                    (temporarily-taken-from-state this-focused-child)
-                                    (focus-child next-child))
+                                    ;; Latest movement direction is tracked to be used within the next step
+                                    (temporarily-taken-from-state this-focused-child :next)
+                                    (focus-child-by-direction next-child :next))
                                   {:mode :throws-focus
                                    :throw-mode :next
                                    :focused-child this-focused-child})

-                          ;; Just rethrow out in :prev direction
+                          ;; Rethrow up to nearest closed cycle root
                           :out-of-cycle-prev {:mode :throws-focus
-                                              :throw-mode :prev
+                                              :throw-mode (if (:closed-focus-root component)
+                                                            :prev
+                                                            :out-of-cycle-prev)
                                               :focused-child this-focused-child}

-                          ;; Just rethrow out in :next direction
+                          ;; Rethrow up to nearest closed cycle root
                           :out-of-cycle-next {:mode :throws-focus
-                                              :throw-mode :next
+                                              :throw-mode (if (:closed-focus-root component)
+                                                            :next
+                                                            :out-of-cycle-next)
                                               :focused-child this-focused-child})))

       :else ; Neither event type - ignore


Whitespace fix

Whitespace fix

--- src/mdr2/handler.clj
+++ src/mdr2/handler.clj
@@ -92,5 +92,3 @@
   (-> api-routes
       (wrap-defaults (assoc-in api-defaults [:params :multipart] true))
       stacktrace/wrap-stacktrace-log))
-
-


auth: Error indicators are now contained in an :error context symbol

--- src/freecoin/auth.clj
+++ src/freecoin/auth.clj
@@ -38,9 +38,9 @@
   (if-let [wallet (wallet/fetch wallet-store (:uid ctx))]
     {:wallet wallet}
     [ false
-     {:status :fatal
-      ::reason "wallet not found" }
+     {:error {:status :fatal
+              :reason "wallet not found"}}
      ]
-  ))
+    ))

 (defn has-api-key [ctx] true)


Add async/await syntax with alet/await macros.

--- src/promesa/core.cljc
+++ src/promesa/core.cljc
@@ -23,7 +23,7 @@
 ;; THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

 (ns promesa.core
-  (:refer-clojure :exclude [delay spread promise])
+  (:refer-clojure :exclude [delay spread promise await])
   (:require [cats.core :as m]
             [cats.context :as mc]
             [cats.protocols :as mp]
@@ -380,42 +380,21 @@
              (schedule t #(.complete p v))
              p))))

-(def ^{:no-doc true}
-  promise-context
-  (reify
-    mp/Context
-    (-get-level [_] mc/+level-default+)
-
-    mp/Functor
-    (-fmap [mn f mv]
-      (p/-map mv f))
-
-    mp/Bifunctor
-    (-bimap [_ err succ mv]
-      (-> mv
-          (p/-map succ)
-          (p/-catch err)))
-
-    mp/Monad
-    (-mreturn [_ v]
-      (promise v))
-
-    (-mbind [mn mv f]
-      (p/-bind mv f))
-
-    mp/Applicative
-    (-pure [_ v]
-      (promise v))
-
-    (-fapply [_ pf pv]
-      (then (all [pf pv])
-            (fn [[f v]]
-              (f v))))
-
-    mp/Semigroup
-    (-mappend [_ mv mv']
-      (p/-map (m/sequence [mv mv'])
-              (fn [[mvv mvv']]
-                (let [ctx (mp/-get-context mvv)]
-                  (mp/-mappend ctx mvv mvv')))))))
-
+(defn await
+  [& args]
+  (throw (ex-info "Should be only used in alet macro." {})))
+
+#?(:clj
+   (defmacro alet
+     [bindings & body]
+     (->> (reverse (partition 2 bindings))
+          (reduce (fn [acc [l r]]
+                    (if (and (coll? r) (symbol? (first r)))
+                      (let [mark (name (first r))]
+                        (if (= mark "await")
+                          `(bind ~(second r) (fn [~l] ~acc))
+                          `(let [~l ~r] ~acc)))
+                      `(let [~l ~r] ~acc)))
+                  `(promise (do ~@body))))))
+
+


fixed bad commit

fixed bad commit

--- src/re_demo/core.cljs
+++ src/re_demo/core.cljs
@@ -167,7 +167,7 @@

 (def id-store        (local-storage (atom nil) ::id-store))
 (def selected-tab-id (reagent/atom (if (or (nil? @id-store) (nil? (item-for-id @id-store tabs-definition)))
-                                     :date ;(:id date(first tabs-definition))
+                                     (:id date(first tabs-definition))
                                      @id-store)))  ;; id of the selected tab from local storage

 (defroute demo-page "/:tab" [tab] (let [id (keyword tab)]


Improve docs for swagger.clj

Improve docs for swagger.clj

--- src/ruuvi/swagger.clj
+++ src/ruuvi/swagger.clj
@@ -39,14 +39,17 @@
          (map first))))

 (s/defn tagging-configurer :- SwaggerObject
-  "Decorates a SwaggerObject with the tags and descriptions (groupings in Swagger UI)."
+  "Decorates a SwaggerObject with the tags and descriptions.
+
+   Routes with same tag are grouped as a one block in Swagger UI."
   [swagger-options :- SwaggerOptions
    swagger-object :- SwaggerObject
    routing-entries :- [RoutingEntry]]
   (assoc swagger-object :tags (routing-tags routing-entries)))

 (s/defn tagging-operation-decorator :- PathItem
-  "Decorates a PathItemObject with the tag (grouping in Swagger UI)."
+  "Decorates a PathItemObject (route) with a tag.
+   Routes with same tag are grouped to same block in the Swagger UI."
   [swagger-options :- SwaggerOptions
    swagger-object :- SwaggerObject
    routing-entry :- RoutingEntry
@@ -54,8 +57,8 @@
   (merge path-item-object {:tags [(routing-tag routing-entry)]})
   )

-(defn swagger-ui-response
-  "Reads and serves swagger-ui from ring-swagger-ui.jar"
+(defn- swagger-ui-response
+  "Reads and serves files for Swagger UI website from ring-swagger-ui.jar"
   [uri prefix swagger-path]
   (let [base "/swagger-ui"
         req-path (.replaceAll uri (str "^" prefix) "")]


navigation: added last command

navigation: added last command

--- src/todos/executor/exec_navigate.clj
+++ src/todos/executor/exec_navigate.clj
@@ -34,16 +34,21 @@
       (println "ID doesn't exist. There are only" (count ((current-todo :todos))) "ids")
       )))

+(defn cmd-last-
+  []
+  (swap! current-stack conj (last (((current-todolist) :todos)))))
+
 (def help
   {"navigation" {"cd .." "navigate to the parent todo"
                  "cd <str>" "navigate to todo with given name"
                  "nth <n>" "navigate to todo with position of n (1..)"
                  "first" "navigate to the first todolist"
+                 "last" "navigate to the last todolist"
                  }})

 (defn is-cmd?
   [cmd]
-  (or (= cmd "first") (= cmd "cd") (= cmd "nth")))
+  (or (= cmd "first") (= cmd "cd") (= cmd "nth") (= cmd "last")))

 (defn run-cmd
   [cmd & args]
@@ -59,4 +64,7 @@

     (= cmd "nth")
     (apply cmd-nth- args)
+
+    (= cmd "last")
+    (cmd-last-)
     ))


Use on-disk file mod times in generated jars.  Allows require to use jar-stored AOT compilations.

--- src/leiningen/jar.clj
+++ src/leiningen/jar.clj
@@ -45,7 +45,8 @@
     (when-not (skip-file? child)
       (let [path (reduce trim-leading-str (unix-path (str child))
                          [root resources classes src "/"])]
-        (.putNextEntry jar-os (JarEntry. path))
+        (.putNextEntry jar-os (doto (JarEntry. path)
+                                (.setTime (.lastModified child))))
         (copy child jar-os))))))

 (defmethod copy-to-jar :bytes [project jar-os spec]


Middle click tab close should not paste - close #1816

Fix inspired by https://github.com/atom/tabs/pull/53

--- src/lt/objs/tabs.cljs
+++ src/lt/objs/tabs.cljs
@@ -109,6 +109,10 @@
     (->name e)]
    (when (object/raise-reduce e :close-button+ false)
      (close-tab label))]
+  ;; Disable middle-click pasting in linux
+  :mouseup (fn [ev]
+             (when (or (= 1 (.-button ev)) (.-metaKey ev))
+               (dom/prevent ev)))
   :click (fn [ev]
            (if (or (= 1 (.-button ev)) (.-metaKey ev))
              (object/raise label :close)


update usage messaeg

update usage messaeg

--- src/revdiff/core.clj
+++ src/revdiff/core.clj
@@ -2,6 +2,7 @@
 ;; TODO maybe print log message / committer info (could use awt/swing popup)?
 ;; TODO pass all '--' options (e.g. --username) to svn?
 ;; TODO add command-line switch for case insensitivity!
+;; TODO make get-revpairs non-recursive?

 (ns revdiff.core
   (:gen-class)
@@ -69,6 +70,14 @@
           :when (seq (:attrs e))]
     (:revision (:attrs e)))))

+;; Return a sequence of revision pairs for potential comparison -- e.g. for the
+;; revlist (9 8 6 4 1), return (8 9 6 8 4 6 1 4).
+
+(defn get-revpairs [revlist object]
+  (when (seq (rest revlist))
+    (concat (list (first (rest revlist)) (first revlist))
+            (get-revpairs (rest revlist) object))))
+
 ;; Return a string containing the xml-formatted svn log for the requested
 ;; object.

@@ -100,14 +109,6 @@
                           filename (trim (first all-lines))]
                       (if (some matching-line-in? changes) filename)))))))

-;; Return a sequence of revision pairs for potential comparison -- e.g. for the
-;; revlist (9 8 6 4 1), return (8 9 6 8 4 6 1 4).
-
-(defn revpairs [revlist object]
-  (when (seq (rest revlist))
-    (concat (list (first (rest revlist)) (first revlist))
-            (revpairs (rest revlist) object))))
-
 ;; NEED NEW COMMENT HERE

 (defn svndiff [r1 r2 filename object]
@@ -130,6 +131,7 @@
   (println (str summary "\n"))
   (println "  object: svn URI or name of versioned object in working-copy")
   (println "  regexp: only show diffs where a changed line matches regexp\n")
+  (println "  See https://github.com/maddenp/revdiff for notes on options.\n")
   (System/exit code))

 ;; If object is a uri, the "-rn:m" revision-range format will not work if object
@@ -142,7 +144,6 @@
     (list (str path "@" r1) (str path "@" r2))
     (list (str "-r" r1 ":" r2) path)))

-
 ;; Entry point from command line.

 (defn -main [& args]
@@ -154,6 +155,6 @@
     (if (:help options) (usage summary 0))
     (if (not object)
       (usage summary 1)
-      (do
-        (diffrevpairs object filt (revpairs (get-revlist optsl object) object))
+      (let [revpairs (get-revpairs (get-revlist optsl object) object)]
+        (diffrevpairs object filt revpairs)
         (shutdown-agents)))))


remove inspect

remove inspect

--- src/pc/http/sente.clj
+++ src/pc/http/sente.clj
@@ -1075,7 +1075,7 @@

 (defmethod ws-handler :team/extend-trial [{:keys [client-id ?data ?reply-fn] :as req}]
   (let [team-uuid (-> ?data :team/uuid)]
-    (utils/inspect (check-team-access team-uuid req :admin))
+    (check-team-access team-uuid req :admin)
     (let [team (team-model/find-by-uuid (:db req) team-uuid)
           plan (:team/plan team)
           cust (get-in req [:ring-req :auth :cust])


Fix typo.

Fix typo.

--- src/pepa/web/poll.clj
+++ src/pepa/web/poll.clj
@@ -41,9 +41,9 @@
 (defn ^:private poll-handler* [req]
   (let [method (:request-method req)
         allowed-methods #{:get :post}
-        content-type (soome #(re-find % (:content-type req))
-                            [#"^application/transit\+json"
-                             #"^application/json"])]
+        content-type (some #(re-find % (:content-type req))
+                           [#"^application/transit\+json"
+                            #"^application/json"])]
     (cond
       (not content-type)
       {:status 406}


Add :x and :y to screen map when necessary

--- src/play_clj/core.clj
+++ src/play_clj/core.clj
@@ -61,13 +61,19 @@
   [screen screen-fn]
   (screen-fn))

+(defn ^:private add-coords
+  [{:keys [input-x input-y] :as screen}]
+  (if (and input-x input-y)
+    (merge screen (input->screen screen input-x input-y))
+    screen))
+
 (defn defscreen*
   [{:keys [screen entities
            on-show on-render on-hide on-pause on-resize on-resume on-timer]
     :as options}]
   (let [execute-fn! (fn [func & {:keys [] :as options}]
                       (when func
-                        (let [screen-map (merge @screen options)
+                        (let [screen-map (add-coords (merge @screen options))
                               old-entities @entities]
                           (some->> (with-meta
                                      #(normalize (func screen-map old-entities))


Remove assertion

Remove assertion

--- src/play_clj/core.clj
+++ src/play_clj/core.clj
@@ -508,8 +508,6 @@

     (set-screen! my-game main-screen text-screen)"
   [^Game game-object & screen-objects]
-  (assert (isa? (type game-object) Game)
-          "Attempted to set screen with an invalid game object.")
   (doseq [screen screen-objects]
     (assert (every? #(fn? (get screen %))
                     [:show :render :hide :pause :resize :resume])


Various cleanup and fixed to pca code

Various cleanup and fixed to pca code

--- src/polismath/pca.clj
+++ src/polismath/pca.clj
@@ -1,12 +1,14 @@
 (ns polismath.pca
   (:refer-clojure :exclude [* - + == /])
   (:use polismath.utils
+        [clojure.core.match :only (match)]
         clojure.core.matrix
         clojure.core.matrix.stats
         clojure.core.matrix.operators))

 (set-current-implementation :vectorz)
-
+(require '[clojure.tools.trace :as tr])
+(use 'alex-and-georges.debug-repl)

 (set! *unchecked-math* true)

@@ -35,7 +37,7 @@
   iters iterations and starting vector start-vector (defaulting to 100 and 111111 resp)."
   ; need to clean up some of these variables names to be more descriptive
   (let [iters (or iters 100)
-        n-cols (count (first data))
+        n-cols (dimension-count data 1)
         start-vector (or start-vector (repeatv n-cols 1))
         ; XXX - this add extra cols to the start vector if we have new comments... should test
         start-vector (matrix
@@ -62,36 +64,47 @@
   (matrix (mapv #(- % (proj-vec xs %)) data)))

-(defn centered-data [data]
-  (- data (mean data)))
-
-
 ; Will eventually also want to add last-pcs
 (defn powerit-pca [data n-comps & {:keys [iters start-vectors]}]
   "Find the first n-comps principal components of the data matrix; iters defaults to iters of
   power-iteration"
-  (let [cntrd-data (centered-data data)
+  (let [center (mean data)
+        cntrd-data (- data center)
         start-vectors (or start-vectors [])
         data-dim (min (row-count cntrd-data) (column-count cntrd-data))]
-    (loop [data' cntrd-data n-comps' (min n-comps data-dim) pcs [] start-vectors start-vectors]
-      (let [pc (power-iteration data' iters (first start-vectors)) ; may eventually want to return eigenvals...
-            pcs (conj pcs pc)]
-        (if (= n-comps' 1)
-          pcs ; return if done
-          (let [data' (factor-matrix data' pc)
-                n-comps' (dec n-comps')]
-            (recur data' n-comps' pcs (rest start-vectors))))))))
+    {:center center
+     :comps
+        (loop [data' cntrd-data n-comps' (min n-comps data-dim) pcs [] start-vectors start-vectors]
+          ; may eventually want to return eigenvals...
+          ;(debug-repl)
+          (let [start-vector (or (first start-vectors)
+                                 (matrix (for [x (range (dimension-count data' 1))] (rand))))
+                pc (power-iteration data' iters start-vector)
+                pcs (conj pcs pc)]
+            (if (= n-comps' 1)
+              pcs ; return if done
+              (let [data' (factor-matrix data' pc)
+                    n-comps' (dec n-comps')]
+                (recur data' n-comps' pcs (rest start-vectors))))))}))

-;(defn wrapped-pca [data n-comps & {:keys [iters start-vectors] :as kwargs}]
-  ;(let [[row-cnt col-cnt] (dim data)]
-    ;(case [(> row-cnt 1) (> col-cnt 1)]
-      ;[true true] (apply powerit-pca data n-comps kwargs)
+(defn wrapped-pca [data n-comps & {:keys [iters start-vectors] :as kwargs}]
+  ; gracefully handle all of the weird cases
+  (match (map (partial dimension-count data) [0 1])
+    [1 n-cols]
+      {:center (matrix (repeatv n-comps 0))
+       :comps  (into [(normalise (get-row data 0))]
+                 (repeat (dec n-comps) (repeatv n-cols 0)))}
+    [n-rows 1]
+      {:center (matrix [0])
+       :comps  (matrix [1])}
+    :else (apply powerit-pca data n-comps kwargs)))

-(defn pca-project [data pcs]
+(defn pca-project [data {:keys [comps center]}]
   "Apply the principal component projection specified by pcs to the data"
   ; Here we map each row of data to it's projection
-  (mmul data (transpose pcs)))
+  ; XXX - still need to verify this...
+  (mmul (- data center) (transpose comps)))


simplify simple-dict

simplify simple-dict

--- src/showkr/root.cljs
+++ src/showkr/root.cljs
@@ -9,11 +9,8 @@
             [showkr.browsing :refer [User]]))

 (defn simple-dict [db attr]
-  (let [eid (-> (db/transact! db [{:db/id -1 attr {}}])
-              :tempids
-              (get -1))
-        getter (fn []
-                 (attr (db/entity @db eid)))]
+  (let [eid (data/transact->eid! db {:db/id -1 attr {}})
+        getter #(attr (db/entity @db eid))]
     [getter
      (fn setter
        ([v] (db/transact! db [[:db/add eid attr v]]))
@@ -48,7 +45,7 @@
       (when-not hide-title
         (d/footer nil
           (d/p {:className "pull-right"}
-            (str "Stats: db size - " (count (pr-str db))))
+            (str "Stats: db - " (count (pr-str db)) "b"))
           (d/p nil
             "© 2012-2014 "
             (d/a {:href "http://solovyov.net"} "Alexander Solovyov")))))))


cleanup

cleanup

--- src/sormilla/gui.clj
+++ src/sormilla/gui.clj
@@ -45,7 +45,7 @@
     ; clear background
     (.setColor g background-color)
     (.fillRect g 0 0 w h)
-
+
     (when (= (:control-state telemetry) :emergency)
       (.setColor g (if (< (mod (System/currentTimeMillis) 400) 200) (Color. 128 16 16) (Color. 192 16 16)))
       (.fillRect g 0 0 w h))


Removed commented-out code to avoid confusion

--- src/tropology/db.clj
+++ src/tropology/db.clj
@@ -300,8 +300,6 @@
                      (fields :from-code :to-code)
                      (modifier "distinct")
                      (where {:type        (name rel)
-                             ; :from-code   [in (subselect sub)]
-                             ; :to-code     [in (subselect sub)]
                              :p1.incoming [< incoming-link-limit]
                              :p2.incoming [< incoming-link-limit]
                              :l1.type     (name rel)


leave reminder to try Rhino

leave reminder to try Rhino

--- src/uglify2/core.clj
+++ src/uglify2/core.clj
@@ -7,11 +7,13 @@
             [boot.util       :as util])
   (:import
    [java.io StringWriter]
-   [javax.script ScriptEngine ScriptEngineManager ScriptException ScriptEngineFactory]))
+   [javax.script ScriptEngine ScriptEngineManager ScriptException ScriptEngineFactory]
+   ;;[org.mozilla.javascript Context ImporterTopLevel ScriptableObject]
+   ))

 ;; see
 ;; https://github.com/mishoo/UglifyJS2/issues/122
-;; https://github.com/clojure/clojurescript/blob/c72e9c52156b3b348aa66857830c2ed1f0179e8c/src/main/clojure/cljs/repl/nashorn.clj#L29
+   ;; https://github.com/clojure/clojurescript/blob/c72e9c52156b3b348aa66857830c2ed1f0179e8c/src/main/clojure/cljs/repl/nashorn.clj#L29

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


Fix error when pressing undo and history empty

--- src/sojoban/core.cljs
+++ src/sojoban/core.cljs
@@ -112,7 +112,7 @@
          :won false))

 (defn undo [state-value]
-  (if (> (count (:history state-value)))
+  (if (> (count (:history state-value)) 0)
     (-> state-value
         (assoc :board (peek (:history state-value)))
         (update-in [:history] pop))


Implement make-completion-item for static fields of classes

--- src/de/kotka/vimclojure/util.clj
+++ src/de/kotka/vimclojure/util.clj
@@ -235,8 +235,11 @@
 (defn- type-of-completion
   [thing]
   (cond
-    (instance? clojure.lang.Namespace thing) "n"
+    (instance? clojure.lang.Namespace thing)   "n"
+    (instance? java.lang.reflect.Field thing)  "S"
+    (instance? java.lang.reflect.Method thing) "M"
     (class? thing)        "c"
+    (coll? thing)         (recur (first thing))
     (:macro (meta thing)) "m"
     :else                 (try
                             (let [value (var-get thing)]
@@ -269,13 +272,31 @@
             "info" ""))

 (defmethod make-completion-item "M"
-  [the-name the-method]
-  (let [rtype    (-> the-method .getReturnType .getSimpleName str)
-        arglist  (.getParameterTypes the-method)
-        menu     (str-cat (concat arglist [rtype]) " -> ")
-        info     (str the-name " :: " menu)]
+  [the-name the-methods]
+  (let [nam      (name (read-string the-name))
+        rtypes   (map #(-> % .getReturnType .getSimpleName) the-methods)
+        arglists (map (fn [m]
+                        (let [types (.getParameterTypes m)]
+                          (vec (map #(.getSimpleName %) types))))
+                      the-methods)
+        info     (apply str "  " the-name \newline \newline
+                        (map #(str "  " %1 " " nam
+                                   (str-wrap (str-cat %2 ", ") \( \))
+                                   \; \newline)
+                             rtypes arglists))]
     (hash-map "word" the-name
               "kind" "M"
+              "menu" (print-str arglists)
+              "info" info)))
+
+(defmethod make-completion-item "S"
+  [the-name [the-field]]
+  (let [nam  (name (read-string the-name))
+        menu (-> the-field .getType .getSimpleName)
+        info (str "  " the-name \newline \newline
+                  "  " menu " " the-name \newline)]
+    (hash-map "word" the-name
+              "kind" "S"
               "menu" menu
               "info" info)))


update doall -> do

update doall -> do

--- src/hivewing_core/hive_image.clj
+++ src/hivewing_core/hive_image.clj
@@ -240,7 +240,7 @@
       ; Generate the new keys
       (doseq [public-key public-keys]
         (let [location (io/file beekeeper-keys-path (str (hive-image-beekeeper-public-key-name (str bk-uuid) public-key) ".pub"))]
-          (doall
+          (do
             (logger/info "Storing PK in " (.getPath location))
             (.mkdirs (io/file (.getParent location)))
             ; add them to the file system


Refer to worker/default-sleep-time in default config

--- src/overseer/api.clj
+++ src/overseer/api.clj
@@ -4,7 +4,12 @@
             [clojure.set :as set]
             (overseer
               [core :as core]
-              [system :as system])))
+              [system :as system]
+              [worker :as worker])))
+
+(def default-config
+  {:datomic {:uri "datomic:free://localhost:4334/overseer"}
+   :sleep-time worker/default-sleep-time})

 (def start
   "Alias in order to start the system as a library"
@@ -38,7 +43,3 @@
   ([] (abort ""))
   ([msg]
     (throw (ex-info msg {:overseer/status :aborted}))))
-
-(def default-config
-  {:datomic {:uri "datomic:free://localhost:4334/overseer"}
-   :sleep-time 10000})


Make variable? a top-level function

Make variable? a top-level function

--- src/io/aviso/rook/dispatcher.clj
+++ src/io/aviso/rook/dispatcher.clj
@@ -131,28 +131,30 @@
       (rook-async/ring-handler->async-handler handler)
       handler)))

+(defn variable? [x]
+  (or (keyword? x) (symbol? x)))
+
 (defn compare-pathvecs [pathvec1 pathvec2]
-  (let [variable? (some-fn keyword? symbol?)]
-    (loop [pv1 (seq pathvec1)
-           pv2 (seq pathvec2)]
-      (cond
-        (nil? pv1) (if (nil? pv2) 0 -1)
-        (nil? pv2) 1
-        :else
-        (let [seg1 (first pv1)
-              seg2 (first pv2)]
-          (cond
-            (variable? seg1) (if (variable? seg2)
-                               (let [res (compare (name seg1) (name seg2))]
-                                 (if (zero? res)
-                                   (recur (next pv1) (next pv2))
-                                   res))
-                              -1)
-            (variable? seg2) 1
-            :else (let [res (compare seg1 seg2)]
-                    (if (zero? res)
-                      (recur (next pv1) (next pv2))
-                      res))))))))
+  (loop [pv1 (seq pathvec1)
+         pv2 (seq pathvec2)]
+    (cond
+      (nil? pv1) (if (nil? pv2) 0 -1)
+      (nil? pv2) 1
+      :else
+      (let [seg1 (first pv1)
+            seg2 (first pv2)]
+        (cond
+          (variable? seg1) (if (variable? seg2)
+                             (let [res (compare (name seg1) (name seg2))]
+                               (if (zero? res)
+                                 (recur (next pv1) (next pv2))
+                                 res))
+                             -1)
+          (variable? seg2) 1
+          :else (let [res (compare seg1 seg2)]
+                  (if (zero? res)
+                    (recur (next pv1) (next pv2))
+                    res)))))))

 (defn compare-route-specs [[method1 pathvec1] [method2 pathvec2]]
   (let [res (compare-pathvecs pathvec1 pathvec2)]


Support :schema in compile-dispatch-table

Also includes a tweak to argument extraction in the non-route-param
case.

--- src/io/aviso/rook/dispatcher.clj
+++ src/io/aviso/rook/dispatcher.clj
@@ -114,7 +114,7 @@
              (if (contains? route-params param)
                `(get (:route-params ~request-sym) ~(keyword param))
                `(internals/extract-argument-value
-                  (keyword (quote ~param))
+                  ~(keyword param)
                   ~request-sym
                   (-> ~request-sym :rook :arg-resolvers)))])
     arglist))
@@ -164,7 +164,8 @@
                                                 (-> handler#
                                                   ~add-resolvers
                                                   ~middleware))
-                                             middleware)]
+                                             middleware)
+                          schema           (:schema metadata)]
                       [[method pathvec]
                        `(let [route-params# ~(zipmap
                                                (map keyword route-params)
@@ -177,8 +178,11 @@
                                                    non-route-params)]
                                            (~verb-fn-sym ~@arglist)))]
                           ((~apply-middleware ~middleware ~sync? handler#)
-                           (assoc ~req
-                             :route-params route-params#)))]))
+                           (-> ~req
+                             (assoc :route-params route-params#)
+                             ~@(if schema
+                                 [`(assoc-in [:rook :metadata :schema]
+                                     ~schema)]))))]))
                   dt)
               :else nil))))))


Vary phrasing.

Vary phrasing.

--- src/klangmeister/ui/content.cljs
+++ src/klangmeister/ui/content.cljs
@@ -25,7 +25,7 @@
     (sine 442)) ; What happens if the two frequencies are closer together? Why?
   (gain 0.1))"]
    :envelope
-   ["The sound cuts off too abruptly. In order to shape it into a real note, we need what's called an envelope. The simplest example of an envelope is a percussive envelope. A percussive envelope is defined by an attack - how long it takes the note to get to maximum loundness, and a decay - how long it takes the note to die away. We use the envelope by connecting the sine waves to it."
+   ["The sound cuts off too abruptly. In order to shape it into a real note, we need what's called an envelope. The simplest example of an envelope is a percussive envelope. A percussive envelope is defined by an attack - how long it takes the note to get to maximum loundness, and a decay - how long it takes the note to die away. We use the envelope by adding it to our chain of connected synthesis nodes."
     "(connect->
   (add
     (sine 440)


+ hr for viewers

+ hr for viewers

--- src/text_stream/templates.clj
+++ src/text_stream/templates.clj
@@ -35,6 +35,7 @@
     [:title (str "Viewing " title)]]
    [:body
     [:h1 title]
+    [:hr]
     [:pre#stream
      [:span.cursor "|"]]
     (js-resource "utils.js")


xymon.clj: host->xymon: refactoring hostname transformation for xymon

--- src/riemann/xymon.clj
+++ src/riemann/xymon.clj
@@ -5,6 +5,12 @@
             [clojure.tools.logging :refer [error]]
             [clojure.math.numeric-tower :refer [ceil]])
   (:import java.net.Socket))
+
+
+(defn host->xymon
+  "Format an hostname for xymon. Basically, replace all dot chars by commas."
+  [host]
+  (s/replace host "." ","))

 (defn event->status
   "Formats an event as a Xymon status message:
@@ -25,7 +31,7 @@
   [{:keys [ttl host service state description]
     :or {host "" service "" description "" state "unknown"}}]
   (let [ttl-prefix (if ttl (str "+" (int (ceil (/ ttl 60)))) "")
-        host       (s/replace host "." ",")
+        host       (host->xymon host)
         service    (s/replace service #"(\.| )" "_")]
     (format "status%s %s.%s %s %s\n"
             ttl-prefix host service state description)))
@@ -39,7 +45,7 @@
   "
   [{:keys [host service]
     :or {host "" service ""}}]
-  (let [host (s/replace host "." ",")
+  (let [host (host->xymon host)
         service (s/replace service #"(\.| )" "_")]
     (format "enable %s.%s" host service)))


Test function test-assoc-in-if-not-nil-5

--- test/emender_jenkins/config_test.clj
+++ test/emender_jenkins/config_test.clj
@@ -137,3 +137,12 @@
             (assoc-in-if-not-nil {:first 1 :second 2} [:second] '(1 2 3)) {:first 1 :second '(1 2 3)}
             (assoc-in-if-not-nil {:first 1 :second 2} [:second] [1 2 3])  {:first 1 :second [1 2 3]})))

+(deftest test-assoc-in-if-not-nil-5
+    "Check the behaviour of function emender-jenkins.config/assoc-in-if-not-nil."
+    (testing "the behaviour of function emender-jenkins.config/assoc-in-if-not-nil."
+        (are [x y] (= x y)
+            (assoc-in-if-not-nil {:first {:left "L" :right "R"} :second {:left "L" :right "R"}} [:first :left] "***")   {:first {:left "***", :right "R"},   :second {:left "L",   :right "R"}}
+            (assoc-in-if-not-nil {:first {:left "L" :right "R"} :second {:left "L" :right "R"}} [:first :right] "***")  {:first {:left "L",   :right "***"}, :second {:left "L",   :right "R"}}
+            (assoc-in-if-not-nil {:first {:left "L" :right "R"} :second {:left "L" :right "R"}} [:second :left] "***")  {:first {:left "L",   :right "R"},   :second {:left "***", :right "R"}}
+            (assoc-in-if-not-nil {:first {:left "L" :right "R"} :second {:left "L" :right "R"}} [:second :right] "***") {:first {:left "L",   :right "R"},   :second {:left "L",   :right "***"}})))
+


Fixing paging regression (#4)

Fixing paging regression (#4)

Regression was likely caused by commit 4c24235, hadn’t noticed because
I didn’t have enough test data locally.

--- src/ui/relevance/display.cljs
+++ src/ui/relevance/display.cljs
@@ -277,7 +277,7 @@
            :last       true
            :ellipsis   true
            :maxButtons 20
-           :onSelect   #(dispatch [:app-state-item [:ui-state :url-page] (dec (aget %2 "eventKey"))])}])
+           :onSelect   #(dispatch [:app-state-item [:ui-state :url-page] (dec %1)])}])
        [:div {:class "card"}
         [:div {:class "content table-responsive table-full-width"}
          [:table {:class "table table-striped table-hover"}


Added round and limit to zoom steps (#7)

--- src/uxbox/data/workspace.cljs
+++ src/uxbox/data/workspace.cljs
@@ -16,6 +16,7 @@
             [uxbox.data.shapes :as uds]
             [uxbox.data.worker :as wrk]
             [uxbox.util.datetime :as dt]
+            [uxbox.util.math :as mth]
             [uxbox.util.geom.point :as gpt]))

 ;; --- Workspace Initialization
@@ -115,7 +116,7 @@
 (defrecord IncreaseZoom []
   rs/UpdateEvent
   (-apply-update [_ state]
-    (let [increase #(* % 1.05)]
+    (let [increase #(min (mth/precision (* % 1.05) 2) 3)]
       (update-in state [:workspace :zoom] (fnil increase 1)))))

 (defn increase-zoom
@@ -127,7 +128,7 @@
 (defrecord DecreaseZoom []
   rs/UpdateEvent
   (-apply-update [_ state]
-    (let [decrease #(* % 0.95)]
+    (let [decrease #(max (mth/precision (* % 0.95) 2) 0.15)]
       (update-in state [:workspace :zoom] (fnil decrease 1)))))

 (defn decrease-zoom


Improve exception message reporting.

Improve exception message reporting.

--- src/uxbox/util/exceptions.clj
+++ src/uxbox/util/exceptions.clj
@@ -28,10 +28,13 @@
       false)))

 (defn error
-  [& {:keys [type code] :or {type :unexpected} :as payload}]
+  [& {:keys [type code message] :or {type :unexpected} :as payload}]
   {:pre [(keyword? type) (keyword? code)]}
-  (let [payload (assoc payload :type type)]
-    (ex-info (pr-str code) payload)))
+  (let [message (if message
+                  (str message " / " (pr-str code) "")
+                  (pr-str code))
+        payload (assoc payload :type type)]
+    (ex-info message payload)))

 (defmacro raise
   [& args]


Error handling

Error handling

--- src/selmer/parser.clj
+++ src/selmer/parser.clj
@@ -197,9 +197,12 @@
 (defn skip-short-comment-tag [template rdr]
   (loop [ch1 (read-char rdr)
          ch2 (read-char rdr)]
-    (if (and (= *short-comment-second* ch1) (= *tag-close* ch2))
+    (cond
+      (nil? ch2)
+      (exception "short-form comment tag was not closed")
+      (and (= *short-comment-second* ch1) (= *tag-close* ch2))
       template
-      (recur ch2 (read-char rdr)))))
+      :else (recur ch2 (read-char rdr)))))

 ;; Compile-time parsing of tags. Accumulates a transient vector
 ;; before returning the persistent vector of INodes (TextNode, FunctionNode)


Get first db test working.

Get first db test working.

--- test/cavm/db_test.clj
+++ test/cavm/db_test.clj
@@ -1,5 +1,6 @@
-(ns cavm.query.db-test
+(ns cavm.db-test
   (:use cavm.h2)
+  (:use cavm.query.sources)
   (:use clojure.test))

 (def db (create-db "testing_db"))
@@ -10,9 +11,17 @@

 (use-fixtures :once db-fixture)

+(def eps 0.000001)
+
+(defn- nearly-equal [e a b]
+  (and (= (count a) (count b))
+       (reduce (fn [acc pair] (and acc (< (java.lang.Math/abs (apply - pair)) e)))
+               true
+               (map vector a b))))
+
 (deftest one-probe
   (testing "one probe"
     (let [out (read-symbols
-                genomic-source
-                '[{table fivebyten columns [3]}])]
-      (is (= [1.1 1.2 1.3 1.4] out)))))
+                [genomic-source]
+                '[{table fivebyten columns ["3"] samples ["1" "2"]}])]
+      (is (nearly-equal eps [-1.7 -1.2] (vec (first out)))))))


change hooks to be an atom-set, not a ref-map containing a set

--- src/subrosa/hooks.clj
+++ src/subrosa/hooks.clj
@@ -3,19 +3,16 @@
 (def get-hook
   (comp
    (memoize
-    (fn [hook]
-      (ref {:hook hook
-            :listeners #{}})))
+    (fn [hook] (atom #{})))
    (memfn toLowerCase)
    str))

 (defn add-hook [hook fn]
-  (dosync
-   (commute (get-hook hook) update-in [:listeners] conj fn)))
+  (swap! (get-hook hook) conj fn))

 (defn hooked? [hook]
-  (not (empty? (:listeners @(get-hook hook)))))
+  (not (empty? @(get-hook hook))))

 (defn run-hook [hook & args]
-  (doseq [listener (:listeners @(get-hook hook))]
+  (doseq [listener @(get-hook hook)]
     (apply listener hook args)))


(MAINT) fix whitespace

(MAINT) fix whitespace

--- test/puppetlabs/trapperkeeper/services/status/status_proxy_service_test.clj
+++ test/puppetlabs/trapperkeeper/services/status/status_proxy_service_test.clj
@@ -72,42 +72,42 @@
           (let [resp (http-client/get "http://localhost:8181/status-proxy/v1/services")
                 body (json/parse-string (slurp (:body resp)))]
             (is (= 200 (:status resp)))
-            (is (= {"bar" {"service_version" "0.1.0"
+            (is (= {"bar" {"service_version"        "0.1.0"
                            "service_status_version" 1
-                           "state" "running"
-                           "detail_level" "info"
-                           "status" "bar status 1 :info"}
-                    "foo" {"service_version" "1.1.0"
+                           "state"                  "running"
+                           "detail_level"           "info"
+                           "status"                 "bar status 1 :info"}
+                    "foo" {"service_version"        "1.1.0"
                            "service_status_version" 2
-                           "state" "running"
-                           "detail_level" "info"
-                           "status" "foo status 2 :info"}}
+                           "state"                  "running"
+                           "detail_level"           "info"
+                           "status"                 "foo status 2 :info"}}
                   body))))
         (testing "proxying url with query param"
           (let [resp (http-client/get "http://localhost:8181/status-proxy/v1/services?level=debug")
                 body (json/parse-string (slurp (:body resp)))]
             (is (= 200 (:status resp)))
-            (is (= {"bar" {"service_version" "0.1.0"
+            (is (= {"bar" {"service_version"        "0.1.0"
                            "service_status_version" 1
-                           "state" "running"
-                           "detail_level" "debug"
-                           "status" "bar status 1 :debug"}
-                    "foo" {"service_version" "1.1.0"
+                           "state"                  "running"
+                           "detail_level"           "debug"
+                           "status"                 "bar status 1 :debug"}
+                    "foo" {"service_version"        "1.1.0"
                            "service_status_version" 2
-                           "state" "running"
-                           "detail_level" "debug"
-                           "status" "foo status 2 :debug"}}
+                           "state"                  "running"
+                           "detail_level"           "debug"
+                           "status"                 "foo status 2 :debug"}}
                   body))))
         (testing "proxying specific service"
           (let [resp (http-client/get "http://localhost:8181/status-proxy/v1/services/foo")
                 body (json/parse-string (slurp (:body resp)))]
             (is (= 200 (:status resp)))
-            (is (= {"service_version" "1.1.0"
+            (is (= {"service_version"        "1.1.0"
                     "service_status_version" 2
-                    "state" "running"
-                    "detail_level" "info"
-                    "status" "foo status 2 :info"
-                    "service_name" "foo"}
+                    "state"                  "running"
+                    "detail_level"           "info"
+                    "status"                 "foo status 2 :info"
+                    "service_name"           "foo"}
                   body))))))))

 (defn count-ring-handler


Refactor - add `timetable-day-get-empty-and-non-empty-rows` function

along with:

- Using multimethod for `get-nr-rows-in-timetable-day`
- arity overloading for `timetable-row-empty?` and
  `timetable-row-not-empty?`

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

--- src/cljs/cljs_nusmods/timetable.cljs
+++ src/cljs/cljs_nusmods/timetable.cljs
@@ -430,11 +430,18 @@
   [day rowNum]
   (nth (timetable-get-day day) rowNum))

-(defn- get-nr-rows-in-timetable-day
-  "Returns the total number of rows in the given 0-indexed day in the Timetable,
-   where 0 = Monday, 1 = Tuesday, until 4 = Friday."
+; Returns the total number of rows for a given day in the Timetable.
+(defmulti get-nr-rows-in-timetable-day number? :default false)
+
+; Argument argument is a a 0-indexed integer representing the day, where
+; 0 = Monday, 1 = Tuesday, until 4 = Friday
+(defmethod get-nr-rows-in-timetable-day true [day]
   [day]
   (count (timetable-get-day day)))
+
+; Argument is a Timetable row returned by the `tiemtable-get-day-row` function
+(defmethod get-nr-rows-in-timetable-day false [ttDay]
+  (count ttDay))

 (def ^{:doc     "HTML string for the <td> elements in a <tr> on the Timetable
                  Builder page"
@@ -603,14 +610,16 @@
 (defn- timetable-row-empty?
   "Returns true if there is no lesson for a given day and row in `Timetable`.
    Returns false otherwise."
-  [day rowNum]
-  (empty? (timetable-get-day-row day rowNum)))
+  ([ttRow] (empty? ttRow))
+
+  ([day rowNum] (empty? (timetable-get-day-row day rowNum))))

 (defn- timetable-row-not-empty?
   "Returns true if there at least one lesson for a given day and row in
    `Timetable`. Returns false otherwise."
-  [day rowNum]
-  (not (timetable-row-empty? day rowNum)))
+  ([ttRow] (not (timetable-row-empty? ttRow)))
+
+  ([day rowNum] (not (timetable-row-empty? day rowNum))))

 (defn- timetable-row-get-lessons-satisfying-pred
   "Returns a sequence of vectors of `TimetableLessonInfo` object and the
@@ -622,6 +631,23 @@
     (filter (fn [[ttLessonInfo _]]
               (predFn ttLessonInfo))
             ttRow)))
+
+(defn- timetable-day-get-empty-and-non-empty-rows
+  "Returns a hash like this:
+   {
+     :emptyRows    -> vector of empty row indices for the day
+     :nonEmptyRows -> vector of non empty row indices for the day
+   }"
+  [day]
+  (let [ttDay (timetable-get-day day)]
+    (reduce (fn [dayPartition [rowIdx ttRow]]
+              (if (timetable-row-empty? ttRow)
+                  (update-in dayPartition [:emptyRows] #(conj %1 rowIdx))
+                  (update-in dayPartition [:nonEmptyRows] #(conj %1 rowIdx))))
+            {:emptyRows [], :nonEmptyRows []}
+            (map vector
+                 (range (get-nr-rows-in-timetable-day ttDay))
+                 ttDay))))

 (defn- create-lesson-div
   "Creates a <div> element for a new lesson using jQuery"
@@ -1333,50 +1359,45 @@
   (doseq [day affectedDaysSet]
     (let [nrRows          (get-nr-rows-in-timetable-day day)

-          {:keys [emptyRowsVec nonEmptyRowsVec]}
-          (reduce (fn [rPart rowIdx]
-                    (if (timetable-row-empty? day rowIdx)
-                        (update-in rPart [:emptyRowsVec] #(conj %1 rowIdx))
-                        (update-in rPart [:nonEmptyRowsVec] #(conj %1 rowIdx))))
-                  {:emptyRowsVec [], :nonEmptyRowsVec []}
-                  (range nrRows))
-
-          nrEmptyRows     (count emptyRowsVec)
+          {:keys [emptyRows nonEmptyRows]}
+          (timetable-day-get-empty-and-non-empty-rows day)
+
+          nrEmptyRows     (count emptyRows)
           nrNonEmptyRows  (- nrRows nrEmptyRows)
           $day            (nth HTML-Timetable day)
           $thElem         (.find $day "tr > th")]
-      (.log js/console (str "day = " day ", emptyRowsVec = "
-                            (.stringify js/JSON (clj->js emptyRowsVec))
-                            ", nonEmptyRowsVec = "
-                            (.stringify js/JSON (clj->js nonEmptyRowsVec))))
+      (.log js/console (str "day = " day ", emptyRows = "
+                            (.stringify js/JSON (clj->js emptyRows))
+                            ", nonEmptyRows = "
+                            (.stringify js/JSON (clj->js nonEmptyRows))))
       (set! Timetable
             (update-in Timetable [day]
                        (fn [ttDay]
                          (vec (map (fn [rowIdx] (nth ttDay rowIdx))
                                    (cond (>= nrNonEmptyRows 2)
-                                         nonEmptyRowsVec
+                                         nonEmptyRows

                                          (= nrNonEmptyRows 1)
-                                         [(first nonEmptyRowsVec)
-                                          (first emptyRowsVec)]
+                                         [(first nonEmptyRows)
+                                          (first emptyRows)]

                                          :else
-                                         (take 2 emptyRowsVec)))))))
+                                         (take 2 emptyRows)))))))
       ; shift <th> element to the new 0th row
-      (if (and (zero? (first emptyRowsVec)) (> nrNonEmptyRows 0))
-          (prepend (nth (children $day "tr") (first nonEmptyRowsVec)) $thElem))
+      (if (and (zero? (first emptyRows)) (> nrNonEmptyRows 0))
+          (prepend (nth (children $day "tr") (first nonEmptyRows)) $thElem))

       ; remove empty <tr> elements
       (let [rowsToRemove
-            (cond (>= nrNonEmptyRows 2) emptyRowsVec
-                  (=  nrNonEmptyRows 1) (rest emptyRowsVec)
-                  :else                 (drop 2 emptyRowsVec))]
+            (cond (>= nrNonEmptyRows 2) emptyRows
+                  (=  nrNonEmptyRows 1) (rest emptyRows)
+                  :else                 (drop 2 emptyRows))]
         (doseq [[idx rowIdx] (map vector (range (count rowsToRemove))
                                   rowsToRemove)]
           (.remove (nth (children $day "tr") (- rowIdx idx)))))

       (if (and (= nrNonEmptyRows 1)
-               (zero? (first emptyRowsVec)))
+               (zero? (first emptyRows)))
           (let [$trArray (children $day "tr")]
             (.log js/console "Am gonna swap this shit man")
             (.log js/console (str "$trArray = " $trArray ", 0th = " (nth $trArray 0) ", 1st = " (nth $trArray 1)))


fix bug in counting transitions

fix bug in counting transitions

--- src/cljs/triboard/ai/strategies.cljs
+++ src/cljs/triboard/ai/strategies.cljs
@@ -36,6 +36,6 @@
   [player]
   (reify minimax/AIStrategy
     (leaf-score [_ turn]
-      (get (transition/all-transitions (:board turn)) player))
+      (count (get (transition/all-transitions (:board turn)) player)))
     (maximizing? [_ turn] (= (:player turn) player))
     ))