Many changes to dolly.clone, esp. making fns work on multiple files at once

--- src/dolly/clone.clj
+++ src/dolly/clone.clj
@@ -18,47 +18,66 @@
     pathname))

-(defn copy-ns-file
-  "Copies the .clj source file (found relative to source-path) for the
-namespace named by the symbol ns-sym to a file for the same namespace,
-but relative to dest-path.
+(defn distinct-parent-dirs
+  "Given a collection 's' of java.io.File objects, return a lazy
+sequence of the parent directories of those files as returned by
+method .getParentFile, with at most one occurrence of each parent
+directory."
+  [s]
+  (distinct
+   (map (fn [^File f] (.getParentFile f)) s)))
+
+
+(defn copy-ns-files
+  "Copies the .clj source files (found relative to 'source-path') for
+the namespaces named by the symbols in collection 'ns-syms' to a file
+for the same namespace, but relative to 'dest-path'.
+
+Map 'opts' can be used to supply options.  If key :dry-run? is present
+and has a logical true value, then no modifications will be made to
+any files.  If key :print? is present and has a logical true value,
+messages will be printed to *out* describing what is being done (or
+if :dry-run? is true, then what would have been done).

 WARNING: This function can overwrite any source file that was already
 at the destination!  Make sure you have a backup or version control."
-  [source-path ns-sym dest-path opts]
-  (let [ns-fname (#'move/ns-file-name ns-sym)
-        old-file (io/file source-path ns-fname)
-        new-file (io/file dest-path ns-fname)]
-    (when (:print? opts)
-      (println (format "mkdir %s"
-                       (abbreviate-path (str (.getParentFile new-file))
-                                        dest-path (:dest-path-abbrev opts)))))
-    (when-not (:dry-run? opts)
-      (.mkdirs (.getParentFile new-file)))
-    (when (:print? opts)
-      (println (format "copy %s %s"
-                       (abbreviate-path (str old-file) source-path
-                                        (:source-path-abbrev opts))
-                       (abbreviate-path (str new-file) dest-path
-                                        (:dest-path-abbrev opts)))))
-    (when-not (:dry-run? opts)
-      (io/copy old-file new-file))))
-
-
-(defn namespace-to-copy? [ns root-ns]
+  [source-path dest-path ns-syms opts]
+  (let [ns-fnames (map #'move/ns-file-name ns-syms)
+        old-new-file-pairs (map (fn [ns-fname]
+                                  [ (io/file source-path ns-fname)
+                                    (io/file dest-path ns-fname) ])
+                                ns-fnames)
+        new-dirs (distinct-parent-dirs (map second old-new-file-pairs))]
+    (doseq [new-dir new-dirs]
+      (when (:print? opts)
+        (println (format "mkdir %s"
+                         (abbreviate-path (str new-dir)
+                                          dest-path (:dest-path-abbrev opts)))))
+      (when-not (:dry-run? opts)
+        (.mkdirs ^File new-dir)))
+    (doseq [[old-file new-file] old-new-file-pairs]
+      (when (:print? opts)
+        (println (format "copy %s %s"
+                         (abbreviate-path (str old-file) source-path
+                                          (:source-path-abbrev opts))
+                         (abbreviate-path (str new-file) dest-path
+                                          (:dest-path-abbrev opts)))))
+      (when-not (:dry-run? opts)
+        (io/copy old-file new-file)))))
+
+
+(defn namespace-extends? [ns root-ns]
   (or (= ns root-ns)
-      (let [^String ns-str (str ns)
-            ^String root-ns-str (str root-ns ".")]
-        (.startsWith ns-str root-ns-str))))
+      (.startsWith (str ns) (str root-ns "."))))

 (defn copy-namespaces-unmodified
   "Scan through all files in directory source-path or one of its
 subdirectories.  For every .clj source file that contains an ns
 declaration with a namespace that is exactly ns-sym, or begins with
-ns-sym followed by a dot, copy them unmodified to a file that is
-rooted at the directory dest-path, and has the same relative path name
-after dest-path that the original does after source-path.
+ns-sym followed by a dot, copy it unmodified to a file that is rooted
+at the directory dest-path, and has the same relative path name after
+dest-path that the original does after source-path.

 The namespaces will first be checked that they correspond with the
 file names in which they occur.  If they do not, an error is returned
@@ -67,159 +86,151 @@
 For example, if source-path is /source/path and it contains a file
 /source/path/one/two.clj, it will be an error if the namespace inside
 is anything other than 'one.two'."
-  [source-path ns-sym dest-path opts]
+  [source-path dest-path ns-sym opts]
   (let [ns-info (ns/namespaces-in-dirs {:paths [source-path]})]
     (if (:err ns-info)
       ns-info
-      (do
+      (let [all-nss (map second (:clojure.tools.namespace.file/filemap ns-info))
+            to-copy? #(namespace-extends? % ns-sym)
+            do-copy (filter to-copy? all-nss)
+            dont-copy (remove to-copy? all-nss)]
         (when (:print? opts)
           (println (format "Copy Clojure source files in namespace %s unmodified\n  from source path S='%s'\n  to dest path D='%s'"
                            ns-sym source-path dest-path)))
-        (doseq [[file ns] (:clojure.tools.namespace.file/filemap ns-info)]
-          (if (namespace-to-copy? ns ns-sym)
-            (copy-ns-file source-path ns dest-path
-                          (merge opts {:source-path-abbrev "S"
-                                       :dest-path-abbrev "D"}))
-            (when (:print? opts)
-              (println (format "Don't copy namespace %s from S since it is not a 'sub-namespace' of %s"
-                               ns ns-sym)))))))))
+        (copy-ns-files source-path dest-path do-copy
+                       (merge opts {:source-path-abbrev "S"
+                                    :dest-path-abbrev "D"}))
+        (when (and (:print? opts) (seq dont-copy))
+          (println (format "Don't copy following namespaces from S since they are not a 'sub-namespace' of %s"
+                           ns-sym))
+          (doseq [ns dont-copy]
+            (println (format "  %s" ns))))))))

 (comment
 (require '[dolly.clone :as c])
 (def tns-path "/Users/jafinger/clj/dolly/copy-deps/tools.namespace/src/main/clojure")
 (def staging-path "/Users/jafinger/clj/dolly/staging")
-(def o1 (c/copy-namespaces-unmodified tns-path 'clojure.tools.namespace staging-path {:dry-run? true :print? true}))
+(def o1 (c/copy-namespaces-unmodified tns-path staging-path 'clojure.tools.namespace {:dry-run? true :print? true}))
 ;;(print (apply str (:dry-run-msgs o1)))
-(def o2 (c/copy-namespaces-unmodified tns-path 'clojure.tools.namespace.dir staging-path {:dry-run? true :print? true}))
+(def o2 (c/copy-namespaces-unmodified tns-path staging-path 'clojure.tools.namespace.dir {:dry-run? true :print? true}))
 ;;(print (apply str (:dry-run-msgs o2)))
 )

-;;(defn copy-namespaces
-;;  "Copy all .clj source files (found relative to source-path) for the
-;;namespaces that have names beginning with old-sym.  Copy them to new
-;;file with namespaces that begin with new-sym.  Replace all occurrences
-;;of the old name with the new name in all Clojure source files found in
-;;dirs.
-;;
-;;This is a purely textual transformation.  It does not work on
-;;namespaces require'd or use'd from a prefix list.
-;;
-;;WARNING: This function modifies your source files!  Make sure you have
-;;a backup or version control."
-;;  [source-path old-sym dest-path new-sym dirs]
-;;  (let [ns-info (ns/namespaces-in-dirs {:paths [source-path]})]
-;;    (if (:err ns-info)
-;;      ns-info
-;;      (do
-;;        (doseq [[file ns] (:clojure.tools.namespace.file/filemap ns-info)]
-;;          (when (namespace-to-copy? ns old-sym)
-;;            (copy-ns-file file ns old-sym new-sym source-path)))
-;;        (doseq [file (#'move/clojure-source-files dirs)]
-;;          (#'move/update-file file #'move/replace-ns-symbol
-;;                              old-sym new-sym))))))
-
-
-(defn move-ns-file
-  "Copied and modified from the version in tools.namespace.  This
-  version adds support for doing a 'dry run' that only describes what
-  it would do, without changing anything.  It also adds a dest-path
-  argument that can be used to move files to a completely different
-  'root' path in a project, in addition to changing the namespace.
-
-  Moves the .clj source file (found relative to source-path) for the
-  namespace named old-sym to a file for a namespace named new-sym,
-  relative to dest-path.
-
-  WARNING: This function moves and deletes your source files!  Make
-  sure you have a backup or version control."
-  [old-sym new-sym source-path dest-path opts]
-  (let [old-file (io/file source-path (#'move/ns-file-name old-sym))
-        new-file (io/file dest-path (#'move/ns-file-name new-sym))]
-    (when (:print? opts)
-      (println (format "mkdir %s"
-                       (abbreviate-path (str (.getParentFile new-file))
-                                        dest-path (:dest-path-abbrev opts)))))
-    (when-not (:dry-run? opts)
-      (.mkdirs (.getParentFile new-file)))
-    (when (:print? opts)
-      (println (format "copy %s %s"
-                       (abbreviate-path (str old-file)
-                                        source-path (:source-path-abbrev opts))
-                       (abbreviate-path (str new-file)
-                                        dest-path (:dest-path-abbrev opts)))))
-    (when-not (:dry-run? opts)
-      (io/copy old-file new-file))
-    (when (:print? opts)
-      (println (format "delete %s"
-                       (abbreviate-path (str old-file)
-                                        source-path (:source-path-abbrev opts)))))
-    (when-not (:dry-run? opts)
-      (.delete old-file))
-    (when (:print? opts)
-      (println (format "delete old dir %s if empty"
-                       (abbreviate-path (str (.getParentFile old-file))
-                                        source-path (:source-path-abbrev opts)))))
-    (when-not (:dry-run? opts)
-      (loop [dir (.getParentFile old-file)]
-        (when (empty? (.listFiles dir))
-          (.delete dir)
-          (recur (.getParentFile dir)))))))
-
-
-(defn replace-ns-symbol
-  "Copied and modified from the version in tools.namespace.  This
-  version adds support for doing a 'dry run' that only describes what
-  it would do, without changing anything.
-
-  Given Clojure source as a string, replaces all occurrences of the
-  namespace name old-sym with new-sym and returns a map containing:
-
-    :new-source - modified source as a string
-
-    :num-symbols - number of 'symbols' found in input string source
-
-    :symbols - map of strings to integers, where the keys are
-      'symbols' found in the input string source, and the values are
-      the number of times that string was found in the input.  Can be
-      useful for debugging the 'symbol' matching code.
-
-    :num-replacements - number of times old-sym was found and replaced"
-  [opts source old-sym new-sym]
-  (let [old-name (name old-sym)
-        new-name (name new-sym)
+(defn move-ns-files
+  "Modified version of tools.namespace's move-ns-file.
+
+Moves the .clj source files (found relative to 'source-path') for the
+namespaces named as the symbols that are keys in map 'sym-map' to
+files for the namespaces named as the values in 'sym-map', relative to
+'dest-path'.
+
+Map 'opts' can be used to supply options.  If key :dry-run? is present
+and has a logical true value, then no modifications will be made to
+any files.  If key :print? is present and has a logical true value,
+messages will be printed to *out* describing what is being done (or
+if :dry-run? is true, then what would have been done).
+
+WARNING: This function moves and deletes your source files!  Make sure
+you have a backup or version control."
+  [source-path dest-path sym-map opts]
+  (let [inf
+        (into {}
+              (for [[old-sym new-sym] sym-map]
+                [old-sym {:new-sym new-sym
+                          :old-file (io/file source-path
+                                             (#'move/ns-file-name old-sym))
+                          :new-file (io/file dest-path
+                                             (#'move/ns-file-name new-sym))}]))
+        new-dirs (distinct-parent-dirs (map #(:new-file (val %)) inf))
+        old-dirs (distinct-parent-dirs (map #(:old-file (val %)) inf))]
+    (doseq [new-dir new-dirs]
+      (when (:print? opts)
+        (println (format "mkdir %s"
+                         (abbreviate-path (str new-dir)
+                                          dest-path (:dest-path-abbrev opts)))))
+      (when-not (:dry-run? opts)
+        (.mkdirs ^File new-dir)))
+    (doseq [[old-sym {:keys [old-file new-file]}] inf]
+      (when (:print? opts)
+        (println (format "copy %s %s"
+                         (abbreviate-path (str old-file) source-path
+                                          (:source-path-abbrev opts))
+                         (abbreviate-path (str new-file) dest-path
+                                          (:dest-path-abbrev opts))))
+        (println (format "delete %s"
+                         (abbreviate-path (str old-file) source-path
+                                          (:source-path-abbrev opts)))))
+      (when-not (:dry-run? opts)
+        (io/copy old-file new-file)
+        (.delete ^File old-file)))
+    (doseq [old-dir old-dirs]
+      (when (:print? opts)
+        (println (format "delete old dir %s if empty"
+                         (abbreviate-path (str old-dir) source-path
+                                          (:source-path-abbrev opts)))))
+      (when-not (:dry-run? opts)
+        (loop [^File dir old-dir]
+          (when (empty? (.listFiles dir))
+            (.delete dir)
+            (recur (.getParentFile dir))))))))
+
+
+(defn replace-ns-symbols
+  "Modified version of tools.namespace's replace-ns-symbol.
+
+Given Clojure source as a string 'source', replaces all occurrences of
+the namespace names that are keys of sym-map with the corresponding
+values of those keys.  Returns a map containing:
+
+  :new-source - modified source as a string
+
+  :num-symbols - number of 'symbols' found in input string source
+
+  :symbols - map of strings to integers, where the keys are 'symbols'
+    found in the input string source, and the values are the number of
+    times that string was found in the input.  Can be useful for
+    debugging the 'symbol' matching code.
+
+  :symbols-replaced - map where the keys are string-ified versions of
+    the keys in sym-map that were found in the string 'source', and
+    the values are the number of times that string was found and
+    replaced."
+  [opts source sym-map]
+  (let [string-map (into {} (for [[k v] sym-map] [(str k) (str v)]))
         num-symbols (atom 0)
         symbols-found (atom {})
-        num-replacements (atom 0)
+        symbols-replaced (atom {})
         ;; A lossless parser would be better, but this is adequate
         new-source (str/replace source @#'move/symbol-regex
                                 (fn [match]
                                   (swap! num-symbols inc)
                                   (swap! symbols-found
                                          update-in [match] (fnil inc 0))
-                                  (if (= match old-name)
+                                  (if (contains? string-map match)
                                     (do
-                                      (swap! num-replacements inc)
-                                      new-name)
+                                      (swap! symbols-replaced
+                                             update-in [match] (fnil inc 0))
+                                      (get string-map match))
                                     match)))]
     {:new-source new-source
      :num-symbols @num-symbols
      :symbols @symbols-found
-     :num-replacements @num-replacements}))
+     :symbols-replaced @symbols-replaced}))

 (defn update-file
-  "Copied and modified from the version in tools.namespace.  This
-  version adds support for doing a 'dry run' that only describes what
-  it would do, without modifying any files.
-
-  Reads file as a string, calls f on opts, the string, plus any args.
-
-  If opts has a logical false value for the key :dry-run? (or no such
-  key), update-file then writes the value of f's :new-source key (f's
-  return value being a map containing this key) as the new contents of
-  file.  Avoids writing file if the content is unchanged."
+  "Modified version of tools.namespace's update-file.
+
+Reads file as a string, calls f on opts, the string, plus any args.
+update-file returns the same value that f returned.
+
+If map 'opts' has a logical true value for the key :dry-run?, no files
+are modified.  If it is not present or has a logical false value,
+update-file writes the value of f's :new-source key (f's return value
+being a map containing this key) as the new contents of file.  Avoids
+writing file if the content is unchanged."
   [file opts f & args]
   (let [old (slurp file)
         m (apply f opts old args)
@@ -230,41 +241,109 @@
     m))

+(defn move-namespaces
+  "Modified version of tools.namespace's move-ns.
+
+Moves the .clj source files (found relative to 'source-path') for the
+namespaces named as the symbols that are keys in 'sym-map' to files
+for the namespaces named as the values in 'sym-map', relative to
+'dest-path'.
+
+It also replaces all occurrences of the old namespaces with the
+corresponding new namespaces in all Clojure source files found in
+'dirs'.  This is a purely textual transformation.  It does not work on
+namespaces require'd or use'd from a prefix list.
+
+Map 'opts' can be used to supply options.  If key :dry-run? is present
+and has a logical true value, then no modifications will be made to
+any files.  If key :print? is present and has a logical true value,
+messages will be printed to *out* describing what is being done (or
+if :dry-run? is true, then what would have been done).
+
+WARNING: This function modifies and deletes your source files!  Make
+sure you have a backup or version control."
+  [source-path dest-path sym-map dirs opts]
+  (move-ns-files source-path dest-path sym-map opts)
+  (doseq [file (#'move/clojure-source-files dirs)]
+    (let [m (update-file file opts replace-ns-symbols sym-map)]
+      (when (:print? opts)
+        (println (format "File %s" (str file)))
+        (if (empty? (:symbols-replaced m))
+          (println (format "  No symbols replaced"))
+          (doseq [sym (sort (keys (:symbols-replaced m)))]
+            (println (format "  %3d instances of %s replaced"
+                             (-> m :symbols-replaced (get sym)) sym))))))))
+
+
+(defn move-namespaces-and-rename
+  "Scan through all files in directory 'source-path' or one of its
+subdirectories.  For every .clj source file that contains an ns
+declaration with a namespace that is exactly 'source-ns-sym', or
+begins with 'source-ns-sym' followed by a dot, move it to a file that
+is rooted at the directory 'dest-path', and has its namespace changed
+so that the prefix that was 'source-ns-sym' is replaced with
+'dest-ns-sym'.
+
+It also replaces all occurrences of the source namespaces with the
+corresponding destination namespaces in all Clojure source files found
+in 'dirs'.  This is a purely textual transformation.  It does not work
+on namespaces require'd or use'd from a prefix list.
+
+The source namespaces will first be checked that they correspond with
+the file names in which they occur.  If they do not, an error is
+returned and no files are copied.
+
+For example, if 'source-path' is /source/path and it contains a file
+/source/path/one/two.clj, it will be an error if the namespace inside
+is anything other than 'one.two'.
+
+Map 'opts' can be used to supply options.  If key :dry-run? is present
+and has a logical true value, then no modifications will be made to
+any files.  If key :print? is present and has a logical true value,
+messages will be printed to *out* describing what is being done (or
+if :dry-run? is true, then what would have been done).
+
+WARNING: This function moves and deletes your source files!  Make sure
+you have a backup or version control."
+  [source-path dest-path source-ns-sym dest-ns-sym dirs opts]
+  (let [ns-info (ns/namespaces-in-dirs {:paths [source-path]})]
+    (if (:err ns-info)
+      ns-info
+      (let [all-nss (map second (:clojure.tools.namespace.file/filemap ns-info))
+            to-move? #(namespace-extends? % source-ns-sym)
+            do-move (filter to-move? all-nss)
+            dont-move (remove to-move? all-nss)
+            source-ns-sym-len (count (str source-ns-sym))
+            sym-map (into {}
+                          (for [ns do-move]
+                            [ns (symbol (str
+                                         dest-ns-sym
+                                         (subs (str ns) source-ns-sym-len)))]))]
+        (when (:print? opts)
+          (println (format "Move Clojure source files in namespace %s\n  from source path S='%s'\n  to dest path D='%s'\n  with new 'root' namespace %s"
+                           source-ns-sym source-path dest-path dest-ns-sym)))
+        (move-namespaces source-path dest-path sym-map dirs opts)
+        (when (and (:print? opts) (seq dont-move))
+          (println (format "Don't move following namespaces from S since they are not a 'sub-namespace' of %s"
+                           source-ns-sym))
+          (doseq [ns dont-move]
+            (println (format "  %s" ns))))))))
+
+
 (comment
 (use 'clojure.pprint)
 (require '[dolly.clone :as c])
 (def tns-path "/Users/jafinger/clj/dolly/copy-deps/tools.namespace/src/main/clojure")
 (def staging-path "/Users/jafinger/clj/dolly/staging")
-(def o1 (c/update-file (str tns-path "/clojure/tools/namespace.clj") {:dry-run? true} c/replace-ns-symbol 'clojure.tools.namespace 'eastwood.copieddeps.tns.clojure.tools.namespace))
+(def dolly-src-path ["/Users/jafinger/clj/dolly/src" tns-path])
+(def o1 (c/update-file (str tns-path "/clojure/tools/namespace.clj") {:dry-run? true} c/replace-ns-symbols '{clojure.tools.namespace eastwood.copieddeps.tns.clojure.tools.namespace}))
 (def m1 (into (sorted-map) (:symbols o1)))
 (pprint m1)
+
+(def sym-map '{clojure.tools.namespace eastwood.copieddeps.tns.clojure.tools.namespace, clojure.tools.namespace.dependency eastwood.copieddeps.tns.clojure.tools.namespace.dependency, clojure.tools.namespace.dir eastwood.copieddeps.tns.clojure.tools.namespace.dir, clojure.tools.namespace.file eastwood.copieddeps.tns.clojure.tools.namespace.file, clojure.tools.namespace.find eastwood.copieddeps.tns.clojure.tools.namespace.find, clojure.tools.namespace.move eastwood.copieddeps.tns.clojure.tools.namespace.move, clojure.tools.namespace.parse eastwood.copieddeps.tns.clojure.tools.namespace.parse, clojure.tools.namespace.reload eastwood.copieddeps.tns.clojure.tools.namespace.reload, clojure.tools.namespace.repl eastwood.copieddeps.tns.clojure.tools.namespace.repl, clojure.tools.namespace.track eastwood.copieddeps.tns.clojure.tools.namespace.track})
+(c/move-namespaces tns-path staging-path sym-map dolly-src-path {:dry-run? true :print? true})
+
+(c/move-namespaces-and-rename tns-path staging-path 'clojure.tools.namespace 'eastwood.copieddeps.tns.clojure.tools.namespace dolly-src-path {:dry-run? true :print? true})
+
+(c/move-namespaces-and-rename tns-path staging-path 'clojure.tools.namespace.track 'eastwood.copieddeps.tns.clojure.tools.namespace.track dolly-src-path {:dry-run? true :print? true})
 )
-
-
-(defn move-ns
-  "Copied and modified from the version in tools.namespace.  This
-  version adds support for doing a 'dry run' that only describes what
-  it would do, without changing anything.  It also adds a dest-path
-  argument that can be used to move files to a completely different
-  'root' path in a project, in addition to changing the namespace.
-
-  Moves the .clj source file (found relative to source-path) for the
-  namespace named old-sym to a .clj source file (relative to
-  dest-path) for the namespace named new-sym.  It also replaces all
-  occurrences of the old name with the new name in all Clojure source
-  files found in dirs.
-
-  This is a purely textual transformation.  It does not work on
-  namespaces require'd or use'd from a prefix list.
-
-  WARNING: This function modifies and deletes your source files!  Make
-  sure you have a backup or version control."
-  [old-sym new-sym source-path dest-path dirs opts]
-  ;; TBD: Add dry run option
-  (move-ns-file old-sym new-sym source-path dest-path opts)
-  (doseq [file (#'move/clojure-source-files dirs)]
-    (update-file opts file replace-ns-symbol old-sym new-sym)))
-
-
-
-;; TBD: Add function that repeats move-ns for multiple namespaces.


Disambiguate the bacon

Disambiguate the bacon

--- src/kevin/routes/home.clj
+++ src/kevin/routes/home.clj
@@ -11,7 +11,7 @@
 (defn home []
   (cache! :home
     (views/main-template
-      :body (views/form "Kevin Bacon" nil nil))))
+      :body (views/form "Kevin Bacon (I)" nil nil))))

 (defn- cache-key [search hard-mode]
   (conj (mapv :actor-id (first search)) hard-mode))


adding :lexicon optional param to relevant functions

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -32,10 +32,12 @@
 (declare spec-info)

 (defn generate [spec language-model
-                & {:keys [max-total-depth truncate-children]
+                & {:keys [max-total-depth truncate-children lexicon]
                    :or {max-total-depth max-total-depth
+                        lexicon nil
                         truncate-children true}}]
   (let [language-model (if (future? language-model) @language-model language-model)
+        lexicon (if lexicon lexicon (:lexicon language-model))
         morph (:morph language-model)]
     (log/info (str "generate: generating from spec: "
                    (strip-refs spec) " with max-total-depth: " max-total-depth ";truncate: " truncate-children))
@@ -215,6 +217,8 @@
    (merge
     (if-let [cat (get-in spec [:synsem :cat])]
       {:cat cat})
+    (if-let [essere (get-in spec [:synsem :essere])]
+      {:essere essere})
     (if-let [pred (get-in spec [:synsem :sem :pred])]
       {:pred pred})
     (if-let [agr (get-in spec [:synsem :agr])]
@@ -257,7 +261,7 @@
                                          (log/debug (str " with lexemes:" (string/join ";" (sort (map morph subset)))))
                                          (log/debug (str " with spec:" (spec-info spec)))
                                          (if (not (empty? subset))
-                                           (over/overh parent (shuffle subset))
+                                           (over/overh parent (map copy (shuffle subset)))
                                            []))))))
                        parents)
           phrasal ;; 2. generate list of all phrases where the head child of each parent is itself a phrase.


+(defn filter-by)

+(defn filter-by)

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -106,10 +106,14 @@
      (rest val-at-paths)
      model)))

+(defn filter-by [bolt-and-comps]
+  (and (not (empty? (get bolt-and-comps [:head :comp])))
+       (not (empty? (get bolt-and-comps [:comp])))))
+
 (defn nugents [model spec & [max-depth]]
   (log/debug (str "nugents:" (strip-refs spec)))
   (let [max-depth (or max-depth babel.generate/max-total-depth)
-        bolts-and-comps (bolts-with-comps spec model 0 max-depth)
+        bolts-and-comps (filter filter-by (bolts-with-comps spec model 0 max-depth))
         debug (str "nugents: bolts-and-comps:" (type bolts-and-comps))
         all-of-them
         (mapcat (fn [each-bolt-and-comps]


pass along :paths

pass along :paths

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -72,7 +72,7 @@
                        :comps (zipmap paths each-path-through-trellis)})
                     (apply combo/cartesian-product comps))))

-     (map (fn [{bolt :bolt comps :comps}]
+     (map (fn [{bolt :bolt comps :comps paths :paths}]
             ;; TODO: further flatten this into the overall ->> pipeline
             (reduce (fn [a b]
                       (let [result


not doing shuffling helps speed up a bit

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -159,8 +159,8 @@
                         phrasal-complements (if (> max-total-depth total-depth)
                                               (generate-all spec grammar lexicon cache morph (+ depth total-depth)))]
                     (if (lexemes-before-phrases total-depth)
-                      (lazy-cat shuffled-candidate-lexical-complements phrasal-complements)
-                      (lazy-cat phrasal-complements shuffled-candidate-lexical-complements)))))))
+                      (lazy-cat filtered-lexical-complements phrasal-complements)
+                      (lazy-cat phrasal-complements filtered-lexical-complements)))))))

 (defn path-to-map [path val]
   (let [feat (first path)]


cleanup local messaging code

cleanup local messaging code

--- src/clj/backtype/storm/messaging/local.clj
+++ src/clj/backtype/storm/messaging/local.clj
@@ -21,7 +21,7 @@
     (if (= flags 1)
       (.poll queue)
       (.take queue)))
-  (^void send [this ^int taskId ^"[B" payload]
+  (^void send [this ^int taskId ^bytes payload]
     (let [send-queue (add-queue! queues-map lock storm-id port)]
       (.put send-queue (TaskMessage. taskId payload))
       ))
@@ -29,8 +29,8 @@
     ))

-(deftype LocalContext [^{:volatile-mutable true} queues-map
-                       ^{:volatile-mutable true} lock]
+(deftype LocalContext [^{:unsynchronized-mutable true} queues-map
+                       ^{:unsynchronized-mutable true} lock]
   IContext
   (^void prepare [this ^Map storm-conf]
     (set! queues-map (atom {}))


Remove unused code.

Remove unused code.

--- src/cljs/hatnik/web/client/components.cljs
+++ src/cljs/hatnik/web/client/components.cljs
@@ -3,9 +3,6 @@
             [om.dom :as dom :include-macros true]
             [hatnik.web.client.app-state :as state])
   (:use [jayq.core :only [$]]))
-
-(defn test-action []
-  (js/alert "Hoooo!"))

 (defn accordion-panel [& {:keys [body-id header button body]}]


Maybe I should have written a testing framework first

--- src/korhal/micro/state.clj
+++ src/korhal/micro/state.clj
@@ -33,6 +33,6 @@

 (defn micro-tag-new-unit! [unit]
   (let [unit-type (get-unit-type unit)]
-    (case unit-type
+    (condp = unit-type
       (get-unit-type (:scv unit-type-kws)) nil
       (micro-tag-unit! unit {:role :defend}))))


Add 'Add operation' button.

Add 'Add operation' button.

--- src/cljs/hatnik/web/client/form/github_pull_request.cljs
+++ src/cljs/hatnik/web/client/form/github_pull_request.cljs
@@ -58,9 +58,14 @@
   (reify
     om/IRender
     (render [this]
-      (dom/div #js {:className "form-group"}
-               (dom/label nil "Operations list")
-               (om/build pull-request-operation {})))))
+      (dom/div nil
+               (dom/div nil
+                        (dom/button
+                         #js {:className "btn btn-primary pull-right"}
+                         "Add operation"))
+               (dom/div #js {:className "form-group"}
+                        (dom/label nil "Operations list")
+                        (om/build pull-request-operation {}))))))

 (defn github-pull-request-component [data owner]
   (reify


Refactored leiningen.ring.jar requires

Refactored leiningen.ring.jar requires

--- src/leiningen/ring/jar.clj
+++ src/leiningen/ring/jar.clj
@@ -1,8 +1,8 @@
 (ns leiningen.ring.jar
-  (:require [leiningen.jar :as jar]
-            [clojure.string :as str])
   (:use [leiningen.ring.util :only (compile-form ensure-handler-set!)]
-        [leiningen.ring.server :only (add-server-dep)]))
+        [leiningen.ring.server :only (add-server-dep)])
+  (:require [clojure.string :as str]
+            leiningen.jar))

 (defn default-main-namespace [project]
   (let [handler-sym (get-in project [:ring :handler])]
@@ -34,4 +34,4 @@
   (ensure-handler-set! project)
   (let [project (-> project add-server-dep add-main-class)]
     (compile-main project)
-    (jar/jar project)))
+    (leiningen.jar/jar project)))


remove unused clojure.string

remove unused clojure.string

--- pedestal-app/app/src/semtag_web/behavior.clj
+++ pedestal-app/app/src/semtag_web/behavior.clj
@@ -1,6 +1,5 @@
 (ns ^:shared semtag-web.behavior
-    (:require [clojure.string :as string]
-              [io.pedestal.app :as app]
+    (:require [io.pedestal.app :as app]
               [io.pedestal.app.messages :as msg]))

 (defn set-value [old-value message]


Add an extra test for async-seq

Add an extra test for async-seq

--- test/momentum/test/core/async.clj
+++ test/momentum/test/core/async.clj
@@ -5,6 +5,9 @@
   (:import
    [momentum.async
     TimeoutException]))
+
+;; TODO:
+;; * async-seq fn throws, what happens?

 (defn- deferred-inc
   [i]
@@ -360,6 +363,13 @@
           Exception #"BOOM"
           @(doasync seq)))))

+(deftest async-seq-throwing-in-fn
+  (let [res (atom nil)]
+    (is (thrown-with-msg? Exception #"BOOM"
+          @(doasync (async-seq (throw (Exception. "BOOM")))
+             (fn [v] (reset! res v)))))
+    (is (nil? @res))))
+
 ;; ==== batch

 (deftest batching-regular-seqs


Fix min peers test

Fix min peers test

--- test/onyx/peer/min_peers_test.clj
+++ test/onyx/peer/min_peers_test.clj
@@ -64,7 +64,7 @@
 (>!! in-chan :done)
 (close! in-chan)

-(def v-peers (onyx.api/start-peers 3 peer-config))
+(def v-peers (onyx.api/start-peers 3 peer-group))

 (onyx.api/submit-job
  peer-config


[#1656] WIP public dashboard filter workaround

--- backend/src/akvo/lumen/lib/public.clj
+++ backend/src/akvo/lumen/lib/public.clj
@@ -18,7 +18,7 @@

 (defn dashboard-response-data [tenant-conn id windshaft-url]
   (when-let [dashboard (dashboard/fetch tenant-conn id)]
-    (assoc (aggregation/aggregate-dashboard-viss dashboard tenant-conn windshaft-url)
+    (assoc (aggregation/aggregate-dashboard-viss dashboard tenant-conn windshaft-url {})
            :dashboards {id dashboard})))

 (defn response-data [tenant-conn share windshaft-url]
@@ -26,7 +26,7 @@
     (assoc (dashboard-response-data tenant-conn dashboard-id windshaft-url)
            :dashboardId dashboard-id)
     (let [visualisation-id (:visualisation-id share)]
-      (assoc (aggregation/visualisation-response-data tenant-conn visualisation-id windshaft-url)
+      (assoc (aggregation/visualisation-response-data tenant-conn visualisation-id windshaft-url {})
              :visualisationId visualisation-id))))

 (defn share


split out a function for getting an observable of the current key configuration

--- src/mediakeys/hotkeys.clj
+++ src/mediakeys/hotkeys.clj
@@ -4,10 +4,6 @@

 (import [com.tulskiy.keymaster.common Provider HotKeyListener])
 (import [javax.swing KeyStroke])
-
-; (defn ^HotKeyListener action-listener [action]
-;    (proxy [HotKeyListener] []
-;             (onHotKey [event] (action event))))

 (defn make-keystroke [keystroke]
     (KeyStroke/getKeyStroke keystroke))
@@ -28,13 +24,19 @@

 (def provider (atom (Provider/getCurrentProvider false)))

+(defn key-config! [key-changes]
+    (map key-changes
+        (fn [key-update]
+            (swap! current-keys #(merge % key-update)))))
+
 (defn keypress-events! [key-changes]
-    (mapcat key-changes
-        (fn [key-update]
-            (let [new-keys (swap! current-keys #(merge % key-update))
-                  new-provider (Provider/getCurrentProvider false)
-                  result (register-keys! new-provider new-keys)]
-                (.reset @provider)
-                (.stop @provider)
-                (reset! provider new-provider)
-                result))))
+    (-> key-changes
+        key-config!
+        (mapcat (fn [all-keys]
+            (let [new-provider (Provider/getCurrentProvider false)
+                  result register-keys! new-provider all-keys]
+                  (doto @provider
+                      (.reset)
+                      (.stop))
+                  (reset! provider new-provider)
+                  result)))))


Add initial implementation for ES6 DataView

--- src/bytebuf/buffer.cljx
+++ src/bytebuf/buffer.cljx
@@ -135,6 +135,47 @@
   (write-bytes [buff pos size data]
     (.setBytes buff pos data 0 size)))

+#+cljs
+(extend-type js/DataView
+  IBufferShort
+  (read-short [buff pos]
+    (.getInt16 buff pos))
+  (write-short [buff pos value]
+    (.setInt16 buff pos value))
+
+  IBufferInt
+  (read-int [buff pos]
+    (.getInt32 buff pos))
+  (write-int [buff pos value]
+    (.setInt32 buff pos value))
+
+  IBufferFloat
+  (read-float [buff pos]
+    (.getFloat32 buff pos))
+  (write-float [buff pos value]
+    (.setFloat32 buff pos value))
+
+  IBufferDouble
+  (read-double [buff pos]
+    (.getFloat64 buff pos))
+  (write-double [buff pos value]
+    (.setFloat64 buff pos value))
+
+  IBufferByte
+  (read-byte [buff pos]
+    (.getInt8 buff pos))
+  (write-byte [buff pos value]
+    (.setInt8 buff pos value)))
+
+  ;; IBufferBytes
+  ;; (read-bytes [buff pos size]
+  ;;   (let [offset (.-byteOffset buff)
+  ;;         buffer (.-buffer buff)]
+  ;;     (js/Int8Array. buffer (+ offset pos) size)))
+  ;; (write-bytes [buff pos size data]
+  ;;   (doseq [i (range (.-length data))]
+  ;;     (.setInt8 buff (+ pos i) (aget data i)))))
+
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Public Api
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


Apparently adding :tbody fixes it?

Apparently adding :tbody fixes it?

--- src/lolitemsets/core.cljs
+++ src/lolitemsets/core.cljs
@@ -218,21 +218,21 @@

 (defn current-build [recommended num-items]
   (let [build (concat recommended (repeat (- num-items (count recommended)) nil))]
-    (into [:div]
-          (for [i build]
-            [item-image i]))))
+    [:div (for [[idx i] (map vector (range) build)]
+            [:span {:key idx} [item-image i]])]))

 (defn build-stats [recommended champ champ-level props num-items]
   [:div.panel.panel-primary
    [:div.panel-heading "Current build"]
    [:div.panel-body [current-build recommended num-items]]
    [:table.table
-    [:tr [:th "Stat"] [:th "Value"]]
-    [:div
-     (map (fn [idx stat]
-            ^{:key idx}
-            [stat-row recommended props champ champ-level stat])
-          (range) stats)]]])
+    [:tbody
+     [:tr [:th "Stat"] [:th "Value"]]
+     [:div
+      (map (fn [idx stat]
+             ^{:key idx}
+             [stat-row recommended props champ champ-level stat])
+           (range) stats)]]]])

 (defn item-block [id block]
   (let [items (mapv #(get @items (int (:id %))) (:items block))]


fix shadow.test counters

fix shadow.test counters

--- src/main/shadow/test.cljs
+++ src/main/shadow/test.cljs
@@ -14,16 +14,21 @@
   (let [summary
         (volatile!
           {:test 0 :pass 0 :fail 0 :error 0
-           :type :summary})]
+           :type :summary})

-    (-> [(fn []
-           (vswap!
-             summary
-             (partial merge-with +)
-             (:report-counters (ct/get-and-clear-env!))))]
-        (into (mapcat #(test-ns-block env %)) namespaces)
+        merge-counters
+        (fn []
+          (vswap!
+            summary
+            (partial merge-with +)
+            (:report-counters (ct/get-and-clear-env!))))]
+
+    (-> [(fn [] (ct/set-env! env))]
+        (into (->> namespaces
+                   (mapcat (fn [ns]
+                             (-> (test-ns-block env ns)
+                                 (conj merge-counters))))))
         (conj (fn []
-                (ct/set-env! env)
                 (ct/do-report @summary)
                 (ct/report (assoc @summary :type :end-run-tests))
                 (ct/clear-env!))))))


Parameterize query server to take the monitoring component.

--- src/onyx/http_query.clj
+++ src/onyx/http_query.clj
@@ -460,7 +460,7 @@
 (defn app [replica peer-config state-store-group]
   {:handler (wrap-params (fn [request] (handler replica peer-config state-store-group request)))})

-(defrecord QueryServer [state-store-group replica server peer-config]
+(defrecord QueryServer [state-store-group replica server peer-config monitoring]
   component/Lifecycle
   (start [this]
     (let [ip (arg-or-default :onyx.query.server/ip peer-config)


allow user to turn stereo mode off

allow user to turn stereo mode off

--- src/mars_ogler/routes.clj
+++ src/mars_ogler/routes.clj
@@ -115,7 +115,9 @@
                          :visit-recent visit-recent
                          :cams (->> (:cams parsed-params)
                                  (map name)
-                                 (str/join " ")))
+                                 (str/join " "))
+                         :stereo (or (:stereo parsed-params)
+                                     :off))
                   set-expires)}))
   (route/resources "/")
   (route/not-found "You have wandered into a maze of twisty passages, all alike"))


fixed type constructor argument count warnings

--- src/cljs/cljs/core.cljs
+++ src/cljs/cljs/core.cljs
@@ -3084,7 +3084,7 @@
   (-seq [coll]
     (let [rear (seq rear)]
       (if (or front rear)
-        (PersistentQueueSeq. nil front (seq rear) nil nil)
+        (PersistentQueueSeq. nil front (seq rear) nil)
         cljs.core.List/EMPTY)))

   ICounted
@@ -4852,10 +4852,12 @@
           (RedNode. (.-key app) (.-val app)
                     (RedNode. (.-key left) (.-val left)
                               (.-left left)
-                              (.-left app))
+                              (.-left app)
+                              nil)
                     (RedNode. (.-key right) (.-val right)
                               (.-right app)
-                              (.-right right))
+                              (.-right right)
+                              nil)
                     nil)
           (RedNode. (.-key left) (.-val left)
                     (.-left left)
@@ -5030,7 +5032,7 @@
         (if (coercive-not= t nil)
           (let [c (comp k (.-key t))]
             (cond
-              (zero? c)  (PersistentTreeMapSeq. nil (conj stack t) ascending? -1)
+              (zero? c)  (PersistentTreeMapSeq. nil (conj stack t) ascending? -1 nil)
               ascending? (if (neg? c)
                            (recur (conj stack t) (.-left t))
                            (recur stack          (.-right t)))
@@ -5038,7 +5040,7 @@
                            (recur (conj stack t) (.-right t))
                            (recur stack          (.-left t)))))
           (if (coercive-= stack nil)
-            (PersistentTreeMapSeq. nil stack ascending? -1))))))
+            (PersistentTreeMapSeq. nil stack ascending? -1 nil))))))

   (-entry-key [coll entry] (key entry))


oh, just some whitespace

oh, just some whitespace

--- src/cljs/moon/core.cljs
+++ src/cljs/moon/core.cljs
@@ -56,6 +56,7 @@
                                                   :running-workout false
                                                   :total-duration total-duration
                                                   :remaining total-duration})))))
+
 (defmethod event-handlers :start-workout [event]
   (start-workout (get-in @app-state [:config :flux]) (:workout @app-state)))


fixed dragging to dock after program is opened

--- src/cljs/smgui/gui.cljs
+++ src/cljs/smgui/gui.cljs
@@ -5,7 +5,7 @@

 (def open-channel (chan))

-(-> nwgui .-App (.on "open" #(smgui.search/search-for %)))
+(-> nwgui .-App (.on "open" #(put! smgui.core/flux-channel {:cmd :add-search :path %})))

 (defn open-external [url]
   (-> nwgui .-Shell (.openExternal url)))


bugfix

bugfix

--- src/cljs/zole/core.cljs
+++ src/cljs/zole/core.cljs
@@ -214,6 +214,7 @@
   (cond
     (= msg ["ok" "login"]) (swap! state assoc :loggedin true)
     (= msg ["ok" "join"]) (table-joined state)
+    (= msg ["ok" "save"]) (swap! state assoc-in [:play-page :saved] nil)
     (= (first msg) "cards") (swap! state assoc-in [:play-page :cards] (second msg))
     (= (first msg) "players") (swap! state assoc-in [:play-page :players] (second msg))
     (= (first msg) "prompt") (swap! state assoc-in [:play-page :prompt] (second msg))


Amphibious monsters

Amphibious monsters

--- src/robinson/update.clj
+++ src/robinson/update.clj
@@ -1762,6 +1762,7 @@
           npc-pos-vec            [(npc-pos :x) (npc-pos :y)]
           threshold              (get npc :range-threshold)
           npc-can-move-in-water  (mg/can-move-in-water? (get npc :race))
+          npc-can-move-on-land   (mg/can-move-on-land? (get npc :race))

           player                 (-> state :world :player)
           player-pos-vec         [(-> player :pos :x) (-> player :pos :y)]
@@ -1790,8 +1791,15 @@
                                                      :short-grass}
                                                    (get-type x y))))

-          traversable?           (if npc-can-move-in-water
+          traversable?           (cond
+                                   (and npc-can-move-in-water
+                                        npc-can-move-on-land)
+                                   (fn [xy]
+                                     (or (water-traversable? xy)
+                                         (land-traversable? xy)))
+                                   npc-can-move-in-water
                                      water-traversable?
+                                   npc-can-move-on-land
                                      land-traversable?)
           path                   (try
                                    (debug "a* params" [width height] traversable? npc-pos-vec [(target :x) (target :y)])
@@ -1829,6 +1837,7 @@
           [npc-x npc-y]          [(npc-pos :x) (npc-pos :y)]
           threshold              (get npc :range-threshold)
           npc-can-move-in-water  (mg/can-move-in-water? (get npc :race))
+          npc-can-move-on-land   (mg/can-move-on-land? (get npc :race))

           player                 (-> state :world :player)
           player-pos-vec         [(-> player :pos :x) (-> player :pos :y)]
@@ -1856,8 +1865,15 @@
                                                      :short-grass}
                                                    (get-type x y)))

-          traversable?           (if npc-can-move-in-water
+          traversable?           (cond
+                                   (and npc-can-move-in-water
+                                        npc-can-move-on-land)
+                                   (fn [xy]
+                                     (or (water-traversable? xy)
+                                         (land-traversable? xy)))
+                                   npc-can-move-in-water
                                      water-traversable?
+                                   npc-can-move-on-land
                                      land-traversable?)
           ;; TODO: calc new-pos based on adj-navigable space (8-dir) that is farthest away from player
           ;_                      (debug "path to target" path)


Fix inbox url.

Fix inbox url.

--- src/oc/storage/representations/activity.clj
+++ src/oc/storage/representations/activity.clj
@@ -12,7 +12,7 @@
 (defn- inbox-url

   ([collection-type {slug :slug :as org}]
-  (str "/orgs" slug "/" collection-type))
+  (str "/orgs/" slug "/" collection-type))

   ([collection-type {slug :slug :as org} {start :start following :following}]
   (let [following-concat (if start "?" "&")]


Improve readability

Improve readability

--- src/onyx/log/commands/peer_replica_view.clj
+++ src/onyx/log/commands/peer_replica_view.clj
@@ -16,18 +16,22 @@
   (let [out-peers (egress-peers task-id)]
     (cond (empty? out-peers)
           (fn [_] nil)
+
           (and (planning/grouping-task? task-map) (#{:continue :kill} (:onyx/flux-policy task-map)))
           (fn [hash-group]
             (nth out-peers
                  (mod hash-group
                       (count out-peers))))
+
           (and (planning/grouping-task? task-map) (= :recover (:onyx/flux-policy task-map)))
           (let [n-peers (or (:onyx/n-peers task-map)
                             (:onyx/max-peers task-map))]
             (fn [hash-group]
               (slot-id->peer-id (mod hash-group n-peers))))
+
           (planning/grouping-task? task-map)
           (throw (ex-info "Unhandled grouping-task flux-policy." task-map))
+
           :else
           (fn [_]
             (rand-nth out-peers)))))


extract nomalize-synth-args from pre-synth as a standard fn to reduce macro complexity

--- src/overtone/sc/synth.clj
+++ src/overtone/sc/synth.clj
@@ -231,9 +231,10 @@
   []
   (str "anon-" (next-id :anonymous-synth)))

-; TODO: Figure out how to generate the let-bindings rather than having them
-; hard coded here.
-(defmacro pre-synth [& args]
+(defn- normalize-synth-args
+  "Pull out and normalize the synth name, parameters, control proxies and the ugen form
+   from the supplied arglist resorting to defaults if necessary."
+  [args]
   (let [[sname args] (cond
                        (or (string? (first args))
                            (symbol? (first args))) [(str (first args)) (rest args)]
@@ -243,6 +244,13 @@
                              [[] args])
         params (vec (map #(if (symbol? %) (str %) %) params))
         param-proxies (control-proxies params)]
+    [sname params param-proxies ugen-form]))
+
+; TODO: Figure out how to generate the let-bindings rather than having them
+; hard coded here.
+(defmacro pre-synth
+  [& args]
+  (let [[sname params param-proxies ugen-form] (normalize-synth-args args)]
     `(let [~@param-proxies]
        (binding [*ugens* []
                  *constants* #{}]


Ensure that the synth param list is a vector

--- src/overtone/sc/synth.clj
+++ src/overtone/sc/synth.clj
@@ -180,7 +180,13 @@
   "throws an error if list l does not contain an even number of elements"
   [l]
   (when-not (even? (count l))
-    (throw (IllegalArgumentException. "A synth requires either an even number of arguments in the form [control default]* i.e. [freq 440 vol 0.5] or a list of maps"))))
+    (throw (IllegalArgumentException. (str "A synth requires either an even number of arguments in the form [control default]* i.e. [freq 440 vol 0.5] or a list of maps. You passed " (count l) " args:" l)))))
+
+(defn- ensure-vec!
+  "throws an error if list l is not a vector"
+  [l]
+  (when-not (vector? l)
+    (throw (IllegalArgumentException. (str "Your synth argument list is not a vector. Instead I found " (type l) ": " l)))))

 (defn- mapify-params
   "converts a list of param name val pairs to a param map. If the val of a param
@@ -219,6 +225,7 @@
       (dorun (map ensure-param-keys! params))
       (vec (map stringify-names params)))
     (do
+      (ensure-vec! params)
       (ensure-paired-params! params)
       (vec (mapify-params params)))))


Remove `:expr` key - make generic and use `:node`.

--- src/isla/parser.clj
+++ src/isla/parser.clj
@@ -14,9 +14,9 @@
   (nnode :root [(-block tokens [])]))

 (defn -block [tokens collected]
-  (if-let [{expr :expr left-tokens :left-tokens}
+  (if-let [{node :node left-tokens :left-tokens}
            (-expression tokens [])]
-    (-block left-tokens (conj collected expr)) ;; add expr, continue collecting more
+    (-block left-tokens (conj collected node)) ;; add expr, continue collecting more
     (nnode :block collected))) ;; no more exprs, return block

 ;; expressions
@@ -27,13 +27,13 @@
 (defn -assignment [tokens]
   (if-let [{nodes :nodes left-tokens :left-tokens}
            (pattern-sequence tokens [-assignee -is -value -nl] [])]
-    {:expr (nnode :assignment (take 3 nodes)) :left-tokens left-tokens}
+    {:node (nnode :assignment (take 3 nodes)) :left-tokens left-tokens}
     nil))

 (defn -invocation [tokens]
   (if-let [{nodes :nodes left-tokens :left-tokens}
            (pattern-sequence tokens [-identifier -value -nl] [])]
-    {:expr (nnode :invocation (take 2 nodes)) :left-tokens left-tokens}
+    {:node (nnode :invocation (take 2 nodes)) :left-tokens left-tokens}
     nil))

 ;; atoms
@@ -86,8 +86,8 @@
 (defn pattern-sequence-selector [tokens pattern-sequences]
   (def alts (alternatives tokens pattern-sequences))
   (if (> (count alts) 0)
-    (let [{expr :expr left-tokens :left-tokens} (first alts)]
-      {:expr (nnode :expression [expr]) :left-tokens left-tokens}) ;; return alternative
+    (let [{node :node left-tokens :left-tokens} (first alts)]
+      {:node (nnode :expression [node]) :left-tokens left-tokens}) ;; return alternative
     nil)) ;; no alternatives match - return

 (defn pattern-sequence [tokens patterns collected]


small fix for patiend app

small fix for patiend app

--- app_patient/patient/events.cljs
+++ app_patient/patient/events.cljs
@@ -157,14 +157,13 @@

 (reg-event-fx
  :set-user-data
- (fn [cofx [_ user-data]]
+ (fn [{:keys [db]} [_ user-data]]
    ;;(print "user-data" user-data)
    (let [user-ref (get-in user-data [:ref :id])
          where-to-go :get-medication-statements]
-     {:db (-> (:db cofx)
-              (assoc :user user-data))
-      :dispatch [:get-patient-data user-ref where-to-go]
-      :current-screen :main})))
+     {:db (merge db {:user user-data
+                     :current-screen :main})
+      :dispatch [:get-patient-data user-ref where-to-go]})))


update docstring for defkey

update docstring for defkey

--- src/keypin/core.clj
+++ src/keypin/core.clj
@@ -148,9 +148,11 @@

 (defmacro defkey
-  "Define one ore more keys as vars using argument vectors. See `make-key` for details - only the first argument
-  `the-key` is mandatory in each argument vector, rest are optional. First argument to defkey can optionally be an
-  option-map that applies to all argument vectors.
+  "Define one or more keys as vars using argument vectors. Every argument vector must have one of the following formats:
+  [key]
+  [key validator description]
+  [key validator description options]
+  See `make-key` for details. First argument to `defkey` can optionally be a base option-map for all argument vectors.
   Examples:
   (defkey
     ip   [:ip-address]


ensure buffer is active when attempting to read buffer data

--- src/overtone/sc/buffer.clj
+++ src/overtone/sc/buffer.clj
@@ -465,6 +465,7 @@
   [buf]
   (when-not (internal-server?)
     (throw (Exception. (str "Only able to fetch buffer data directly from an internal server. Try #'buffer-read instead."))))
+  (ensure-buffer-active! buf)
   (let [buf-id (buffer-id buf)
         snd-buf (scsynth-get-buffer-data @sc-world* buf-id)]
     snd-buf))


Improve Prophet synth design:

Improve Prophet synth design:

* add amp and output params
* add normaliser
* auto free synth on completion

--- src/overtone/synth/sts.clj
+++ src/overtone/synth/sts.clj
@@ -1,4 +1,4 @@
-(ns overtone.synths.sts
+(ns overtone.synth.sts
   (:use [overtone.core]))

 ;; Synths translated from the excellent book
@@ -24,16 +24,19 @@
    frequency) and its LFO has a little bit of randomisation thrown into
    its frequency component for that extra bit of variety."

-  [freq 440 cutoff-freq 12000 rq 0.3 out-bus 0 attack 1 decay 2]
+  [amp 1 freq 440 cutoff-freq 12000 rq 0.3  attack 1 decay 2 out-bus 0 ]

   (let [snd (pan2 (mix [(pulse freq (* 0.1 (/ (+ 1.2 (sin-osc:kr 1)) )))
                         (pulse freq (* 0.8 (/ (+ 1.2 (sin-osc:kr 0.3) 0.7) 2)))
                         (pulse freq (* 0.8 (/ (+ 1.2 (lf-tri:kr 0.4 )) 2)))
                         (pulse freq (* 0.8 (/ (+ 1.2 (lf-tri:kr 0.4 0.19)) 2)))
-                        (* 0.5 (pulse (/ freq 2) (* 0.8 (/ (+ 1.2 (lf-tri:kr (+ 2 (lf-noise2:kr 0.2 )) )) 2)))) ]))
-        env (env-gen (perc attack decay))
+                        (* 0.5 (pulse (/ freq 2) (* 0.8 (/ (+ 1.2 (lf-tri:kr (+ 2 (lf-noise2:kr 0.2))))
+                                                           2))))]))
+        snd (normalizer snd)
+        env (env-gen (perc attack decay) :action FREE)
         snd (rlpf (* env snd snd) cutoff-freq rq)]

-    (out out-bus snd)))
+    (out out-bus (* amp snd))))

-;;(prophet :freq (midi->hz (note :E2)))
+;;(prophet :freq (midi->hz (note :E2)) :amp 3 :decay 5)
+;;(prophet :freq (midi->hz (note :C3)) :amp 3 :decay 5)


Add false and pwd subtasks to server task

--- src/pallet/task/server.clj
+++ src/pallet/task/server.clj
@@ -29,6 +29,9 @@
      (= cmd "kill") (do (shutdown-agents)
                         (System/exit 0))
      (= cmd "pid") (println (pid))
+     (= cmd "false") (throw (ex-info "errr" {:exit-code 1}))
+     (= cmd "pwd") (println (System/getProperty "grench.cwd"))
+
      :else (do
              (when cmd
                (println "Unknown command" cmd \newline))


CMR-354: Added +browsable and +browse_only tests.

--- test/cmr/system_int_test/search/granule_sorting_search_test.clj
+++ test/cmr/system_int_test/search/granule_sorting_search_test.clj
@@ -282,5 +282,7 @@

          "browse_only" [g2 g1]
          "-browse_only" [g1 g2]
+         "+browse_only" [g2 g1]
          "browsable" [g2 g1]
-         "-browsable" [g1 g2])))
+         "-browsable" [g1 g2]
+         "+browsable" [g2 g1])))


core: Clarify the partition-by docstring (#28)

--- src/datasplash/core.clj
+++ src/datasplash/core.clj
@@ -733,7 +733,8 @@
 (defn dpartition-by
   {:doc (with-opts-docstr
           "Partitions the content of pcoll according to the PartitionFn.
-See https://cloud.google.com/dataflow/java-sdk/JavaDoc/com/google/cloud/dataflow/sdk/transforms/Partition"
+See https://cloud.google.com/dataflow/java-sdk/JavaDoc/com/google/cloud/dataflow/sdk/transforms/Partition.
+The partition function is given two arguments: the current element and the number of partitions."
           named-schema)
    :added "0.1.0"}
   ([f num options ^PCollection pcoll]


modified workload for inner joins, work in progress

--- src/datasplash/core.clj
+++ src/datasplash/core.clj
@@ -914,8 +914,24 @@
          new-coll-tuple))
      empty-kpct (map-indexed (fn [idx v] [idx v]) pcolls))))

+(defn greedy-read-cogbkresult
+  [raw-values tag]
+  (loop [^java.util.Iterator it (.iterator (.getAll raw-values tag))
+         acc (list)]
+    (if (.hasNext it)
+      (recur it (conj acc (.next it)))
+      acc)))
+
+(defn greedy-emit-cogbkresult
+  [raw-values tag ^DoFn$ProcessContext context]
+  (loop [^java.util.Iterator it (.iterator (.getAll raw-values tag))]
+    (when (.hasNext it)
+      (let [v (.next it)]
+        (.output context (make-kv nil (list v)))
+        (recur it)))))
+
 (defn cogroup-transform
-  ([options]
+  ([specs {:keys [join-nil?] :as options}]
    (let [opts (assoc options :label :raw-cogroup)]
      (ptransform
       :cogroup
@@ -925,52 +941,66 @@
                               (map #(.getTupleTag %))
                               (sort-by #(.getId %)))
             rel (apply-transform pcolltuple (CoGroupByKey/create) base-schema opts)
-            final-rel (pardo (fn [^DoFn$ProcessContext c]
-                               (let [^KV kv (.element c)
-                                     k (.getKey kv)
-                                     ^CoGbkResult raw-values (.getValue kv)
-                                     values (mapv
+            final-rel (pardo
+                       (fn [^DoFn$ProcessContext c]
+                         (let [^KV kv (.element c)
+                               k (.getKey kv)
+                               ^CoGbkResult raw-values (.getValue kv)
+                               required-list (->> specs
+                                                  (map-indexed
+                                                   (fn [idx {:keys [type]}]
+                                                     (when (= type :required) idx)))
+                                                  (remove nil?))
+                               required-count (count required-list)]
+                           ;; skip if a required part of the group is empty
+                           (when-not (some identity
+                                           (map (fn [tag {:keys [type]}]
+                                                  (if (= type :required)
+                                                    (not (.hasNext (.iterator (.getAll raw-values tag))))
+                                                    false))
+                                                ordered-tags specs))
+                             (if (and (not join-nil?) (nil? k))
+                               (cond
+                                 (= required-count 0) (doseq [tag ordered-tags]
+                                                        (greedy-emit-cogbkresult raw-values tag c))
+                                 (= required-count 1) (greedy-emit-cogbkresult raw-values
+                                                                               (nth ordered-tags
+                                                                                (first required-list))
+                                                                               c)
+                                 :else nil)
+                               (let [values (mapv
                                              (fn [tag]
-                                               (loop [^java.util.Iterator it (.iterator (.getAll raw-values tag))
-                                                      acc (list)]
-                                                 (if (.hasNext it)
-                                                   (recur it (conj acc (.next it)))
-                                                   acc)))
+                                               (greedy-read-cogbkresult raw-values tag))
                                              ordered-tags)]
-                                 (.output c (make-kv k values))))
-                             (assoc opts
-                                    :without-coercion-to-clj true
-                                    :coder (make-kv-coder (.getKeyCoder (.getCoder rel))
-                                                          (make-nippy-coder)))
-                             rel)]
+                                 (.output c (make-kv k values)))))))
+                       (assoc opts
+                              :without-coercion-to-clj true
+                              :coder (make-kv-coder (.getKeyCoder (.getCoder rel))
+                                                    (make-nippy-coder)))
+                       rel)]
         final-rel)))))

 (defn cogroup
-  [options pcolls]
+  [specs options pcolls]
   (let [opts (assoc options :label :cogroup)
         pcolltuple (make-keyed-pcollection-tuple pcolls)]
-    (apply-transform pcolltuple (cogroup-transform opts) base-schema opts)))
+    (apply-transform pcolltuple (cogroup-transform specs opts) base-schema opts)))

 (defn cogroup-by
   ([options specs reduce-fn]
    (let [safe-opts (dissoc options :name)
-         operations (for [[idx [pcoll f type]] (map-indexed vector specs)]
-                      [(with-keys f (assoc safe-opts :name (str "group-by-" idx))
-                         pcoll) type])
-         required-idx (remove nil? (map-indexed (fn [idx [_ b]] (when b idx)) operations))
-         pcolls (map first operations)
-         grouped-coll (cogroup safe-opts pcolls)
-         filtered-coll (if (empty? required-idx)
-                         grouped-coll
-                         (dfilter (fn [^KV kv]
-                                    (let [all-vals (.getValue kv)
-                                          idx-vals (into [] all-vals)]
-                                      (every? #(not (empty? (get idx-vals %))) required-idx)))
-                                  (assoc safe-opts :without-coercion-to-clj true)
-                                  grouped-coll))]
+         pcolls (for [[idx [pcoll f {:keys [drop-nil?]}]] (map-indexed vector specs)]
+                  (let [op (with-keys f (assoc safe-opts :name (str "group-by-" idx)) pcoll)]
+                    (if drop-nil?
+                      (dfilter (fn [^KV kv] (not (nil? (.getKey kv))))
+                               {:name (str "drop-nil-" idx)
+                                :without-coercion-to-clj true}
+                               op)
+                      op)))
+         grouped-coll (cogroup (map #(drop 2 %) specs) safe-opts pcolls)]
      (if reduce-fn
-       (dmap reduce-fn safe-opts filtered-coll)
-       filtered-coll)))
+       (dmap reduce-fn safe-opts grouped-coll)
+       grouped-coll)))
   ([options specs] (cogroup-by options specs nil)))

 (defn join-by


Pin current version to demo at muenchhausen

--- src/discuss/config.cljs
+++ src/discuss/config.cljs
@@ -2,8 +2,8 @@
   (:require [clojure.string :as str]))

 (goog-define version "0.2.1")
-(goog-define remote-host "http://localhost:4284/")
-(goog-define remote-search "http://muenchhausen.cn.uni-duesseldorf.de:9201/")
+(goog-define remote-host "http://muenchhausen.cn.uni-duesseldorf.de:4284/")
+(goog-define remote-search "http://muenchhausen.cn.uni-duesseldorf.de:9200/")

 (def project "discuss")


Unescape html characters in the title

Unescape html characters in the title

--- src/reddio_frontend/screens/listings/listings.cljs
+++ src/reddio_frontend/screens/listings/listings.cljs
@@ -1,5 +1,6 @@
 (ns reddio-frontend.screens.listings.listings
   (:require [clojure.string :as string]
+            [goog.string :as gstring]
             [reagent.core :as r]
             [re-frame.core :as rf]
             [reddio-frontend.utilities.core :as u]
@@ -49,7 +50,7 @@
       [:div.post-title
        {:on-click
         #(when playable (rf/dispatch [:play-post post posts]))}
-       (:title post)]
+       (gstring/unescapeEntities (:title post))]
       [:div.post-metadata
        [:span (:score post) " points"]
        [:span.divider]


regex refinement re: model matching

regex refinement re: model matching

--- src/blx/sortable/core.clj
+++ src/blx/sortable/core.clj
@@ -61,11 +61,12 @@
 (defn model-regex
   [model]
   (-> (or model "")
+      str/lower-case
       ; [_ -] chars are equivalent and optional
       (str/replace #"[\s_-]+" "[\\\\s_-]*")
       ; common model prefixes are optional
-      str/lower-case
-      (str/replace #"(dsc|dslr|dmc|pen|slt|is)" "(?:$1)?")))
+      (str/replace #"(dsc|dslr|dmc|pen|slt|is)" "(?:$1)?")
+      re-pattern))

 (p/defnp product-regex
   "Generates a case-insensitive regex pattern that represents the product."
@@ -73,6 +74,9 @@
   ; Roughly: word{0,3} family? word? model
   (re-pattern
     (str (family-regex (:family product))
+         ; Require some kind of separator before model to keep it distinct,
+         ; eg. don't accept "PowerShot SX220 HS" for "Ixus 220 HS".
+         #"[\s_-]"
          (model-regex (:model product))
          ; Don't match if model is directly followed by a number,
          ; eg. don't accept "EOS 100" for "EOS 10".
@@ -100,7 +104,7 @@
 (defn prepare-product [product]
   (assoc product
          :regex (product-regex product)
-         :model-regex (re-pattern (model-regex (:model product)))))
+         :model-regex (model-regex (:model product))))

 (p/defnp group-products
   "Returns a map of (lowercase first word of manufacturer) to products."


Remove unnecesary file corresponding to catacumba.ratpack ns.

--- src/catacumba/ratpack.clj
+++ src/catacumba/ratpack.clj
@@ -1,24 +0,0 @@
-(ns catacumba.ratpack
-  "Functions and helpers for work in a clojure
-  way with ratpack types."
-  (:refer-clojure :exclude [next])
-  (:require [catacumba.impl.ratpack :as impl]
-            [catacumba.utils :as utils])
-  (:import ratpack.handling.Context
-           ratpack.handling.Chain
-           ratpack.handling.Handler
-           ratpack.handling.Handlers
-           ratpack.registry.Registry
-           ratpack.registry.Registries
-           ratpack.http.Request
-           ratpack.http.Response
-           ratpack.http.Headers
-           ratpack.http.TypedData
-           ratpack.http.MutableHeaders
-           ratpack.func.Action
-           ratpack.func.Function
-           io.netty.buffer.Unpooled
-           io.netty.buffer.ByteBuf
-           java.io.InputStream
-           java.util.Map))
-


register view and dump data into gui

register view and dump data into gui

--- dada-swt/src/main/clojure/org/dada/swt/gui.clj
+++ dada-swt/src/main/clojure/org/dada/swt/gui.clj
@@ -1,5 +1,6 @@
 (ns org.dada.swt.gui
     (:import
+     (java.io Serializable)
      (org.eclipse.swt SWT)
      (org.eclipse.swt.widgets Display Shell Table TableColumn TableItem Listener)
      (org.eclipse.swt.layout GridData GridLayout)
@@ -26,13 +27,14 @@
     (.setText column text)
     column))

-(defn begin []
+(defn begin [metadata data]
   (let [#^Display display (Display.)
 	#^Shell shell (Shell. display)
 	flags (reduce bit-or [(SWT/MULTI) (SWT/BORDER) (SWT/FULL_SELECTION)])
 	#^Table table (Table. shell flags)
-	;; plug in metadata here...
-	titles [" ", "C", "!", "Description", "Resource", "In Folder", "Location"]
+
+	;; add metadata
+	titles (map str (.getAttributeKeys metadata))
 	columns (doall (map #(make-column table %) titles))]

     (.setLayout shell (GridLayout.))
@@ -40,16 +42,14 @@
     (.setHeaderVisible table true)
     (.setLayoutData table (GridData. (SWT/FILL) (SWT/FILL) true true))

-    (dotimes [i 128]
-	(let [#^TableItem item (TableItem. table (SWT/NONE))]
-	  (.setText item 0 "x")
-	  (.setText item 1 "y")
-	  (.setText item 2 "!")
-	  (.setText item 3 "this stuff behaves the way I expect")
-	  (.setText item 4 "almost everywhere")
-	  (.setText item 5 "some.folder")
-	  (.setText item 6 (str "line " i " in nowhere"))
-	  ))
+    ;; add data
+    (doall		   ;TODO - use a fn that implies a side-effect
+     (map
+      (fn [datum]
+	  (let [#^TableItem item (TableItem. table (SWT/NONE))]
+	    (.setText item 0 (str datum))
+	    ))
+      data))

     (doall (map	#(.pack %) columns))

@@ -61,7 +61,7 @@
     (.addListener
      table
      (SWT/DefaultSelection)
-     (proxy [Listener] [] (handleEvent [evt] (println "DefaultSelection" (.getSelection table)))))
+     (proxy [Listener] [] (handleEvent [evt] (println "DefaultSelection" (map #(.getText %) (.getSelection table))))))

     ;; insert item at index
     ;;	TableItem item = new TableItem (table, SWT.NONE, 1);
@@ -74,11 +74,65 @@
     (.open shell)
     (swt-loop display shell)))

-(begin)
-
 ;; Executing code from a non-UI thread

 ;; Applications that wish to call UI code from a non-UI thread must provide a Runnable that calls the UI code. The methods syncExec(Runnable) and asyncExec(Runnable) in the Display class are used to execute these runnables in the UI thread during the event loop.

 ;;     * syncExec(Runnable) should be used when the application code in the non-UI thread depends on the return value from the UI code or otherwise needs to ensure that the runnable is run to completion before returning to the thread. SWT will block the calling thread until the runnable has been run from the application's UI thread. For example, a background thread that is computing something based on a window's current size would want to synchronously run the code to get the window's size and then continue with its computations.
 ;;     * asyncExec(Runnable) should be used when the application needs to perform some UI operations, but is not dependent upon the operations being completed before continuing. For example, a background thread that updates a progress indicator or redraws a window could request the update asynchronously and continue with its processing. In this case, there is no guaranteed relationship between the timing of the background thread and the execution of the runnable.
+
+
+(import org.apache.activemq.ActiveMQConnectionFactory)
+(import javax.jms.ConnectionFactory)
+(import javax.jms.Connection)
+(import javax.jms.Session)
+(import org.dada.jms.RemotingFactory)
+(import org.dada.core.MetaModel)
+(import org.dada.core.View)
+(import java.rmi.server.UID)
+(import java.util.concurrent.ExecutorService)
+(import java.util.concurrent.Executors)
+
+
+(def server-name "Cetacea.MetaModel")
+(def url "tcp://localhost:61616")
+(def connection-factory (ActiveMQConnectionFactory. url))
+(def connection (.createConnection connection-factory))
+(.start connection)
+(def session (.createSession connection false (Session/AUTO_ACKNOWLEDGE)))
+
+;; create proxy to server-side metamodel
+
+(def clientside-metamodel-proxy
+     (.createSynchronousClient
+      (RemotingFactory. session MetaModel, 10000)
+      (.createQueue session server-name)
+      true))
+
+;; create proxy for ourselves to send to server
+
+(def client-destination (.createQueue session (str "Client" (UID.))))
+(def client-view (proxy [View] [] (update [insertions alterations deletions]
+					  (println ("VIEW:" insertions alterations deletions)))))
+
+(def view-remoting-factory (RemotingFactory. session View 10000))
+
+(def clientside-view-server
+     (.createServer
+      view-remoting-factory
+      client-view
+      client-destination
+      (Executors/newFixedThreadPool 20)))
+
+(def serverside-view-proxy
+     (.createSynchronousClient
+      view-remoting-factory
+      client-destination
+      true))
+
+;; register our interest in the metamodel
+(def registration (.registerView clientside-metamodel-proxy server-name serverside-view-proxy))
+
+(begin (.getMetadata registration) (.getData registration))
+
+


more matchers

more matchers

--- src/matcha.clj
+++ src/matcha.clj
@@ -3,7 +3,7 @@
     :exclude
     [empty? every?
      = some not <= >= < >
-     instance? string? map? seq? char? vector? nil? keyword? symbol? ratio? decimal? float? isa? rational? coll? set? list?])
+     instance? string? map? seq? char? vector? nil? keyword? symbol? ratio? decimal? float? isa? rational? coll? set? list? fn?])
   (:require [clojure.string :as string]
             [clojure.core :as core]))
 ;; Matcher
@@ -23,10 +23,7 @@
 ;;
 ;;  TODO: matchers list
 ;;  - all the matchers using `on` should have good error messages with bad types
-;;  - fn?
 ;;  - re-matches
-;; -- ** Matcher combinators
-;; , and-also
 (defn describe-list [call xs]
   (str "(" call " " (clojure.string/join " " xs) ")"))

@@ -376,6 +373,16 @@
   {:match core/set?
    :description "a set"})

+(def
+  ^{:doc
+    "passes if the value is a function
+
+    (matcha/run-match matcha/fn? #()) ; => passes
+    (matcha/run-match matcha/fn? 5) ; => fails"}
+  fn?
+  {:match core/fn?
+   :description "a function"})
+
 (defn assert-good-matcher [{:keys [match description describe-mismatch] :as matcher}]
   (assert (not (nil? matcher)) "Matcher should not be nil")
   (assert match


use-macros -- simplify parsing, use :require-macros-like get-expander logic

--- src/clj/cljs/compiler.clj
+++ src/clj/cljs/compiler.clj
@@ -780,17 +780,12 @@
                                                (:use :use-macros)
                                                (do (assert (and expr (= :only kw))
                                                            "Only (:use [lib.ns :only [names]]*) form of :use / :use-macros is supported")
-                                                   (if (= :use k)
-                                                     (map vector expr (repeat lib))
-                                                     (do (require lib)
-                                                         (->> lib ns-publics
-                                                              (filter (comp :macro meta val))
-                                                              (filter (comp (set expr) key))))))))
+                                                   (map vector expr (repeat lib)))))
                                            libs))))
                 {} (remove (fn [[r]] (= r :refer-clojure)) args))]
     (set! *cljs-ns* name)
     (require 'cljs.core)
-    (doseq [nsym (vals requires-macros)]
+    (doseq [nsym (concat (vals requires-macros) (vals uses-macros))]
       (clojure.core/require nsym))
     (swap! namespaces #(-> %
                            (assoc-in [name :name] name)
@@ -876,8 +871,8 @@
                            :else
                            (-> env :ns :requires-macros (get (symbol nstr))))]
               (.findInternedVar ^clojure.lang.Namespace ns (symbol (name sym))))
-            (if-let [mvar (-> env :ns :uses-macros sym)]
-              mvar
+            (if-let [nsym (-> env :ns :uses-macros sym)]
+              (.findInternedVar ^clojure.lang.Namespace (find-ns nsym) sym)
               (.findInternedVar ^clojure.lang.Namespace (find-ns 'cljs.core) sym))))]
     (when (and mvar (.isMacro ^clojure.lang.Var mvar))
       @mvar)))


* src/clj/cljs/compiler.clj: support type hints on fns

--- src/clj/cljs/compiler.clj
+++ src/clj/cljs/compiler.clj
@@ -97,8 +97,10 @@
              ns (if (= "clojure.core" ns) "cljs.core" ns)
              full-ns (resolve-ns-alias env ns)]
          (confirm-var-exists env full-ns (symbol (name sym)))
-         {:name (symbol (str full-ns "." (munge (name sym))))
-          :ns full-ns})
+         (merge
+          (get-in @namespaces [full-ns :defs sym])
+          {:name (symbol (str full-ns "." (munge (name sym))))
+           :ns full-ns}))

        (.contains s ".")
        (let [idx (.indexOf s ".")
@@ -109,19 +111,26 @@
            {:name (munge (symbol (str (:name lb) suffix)))}
            (do
              (confirm-var-exists env prefix (symbol suffix))
-             {:name (munge sym) :ns prefix})))
+             (merge
+              (get-in @namespaces [prefix :defs sym])
+              {:name (munge sym) :ns prefix}))))

        (get-in @namespaces [(-> env :ns :name) :uses sym])
-       {:name (symbol (str (get-in @namespaces [(-> env :ns :name) :uses sym]) "." (munge (name sym))))
-        :ns (-> env :ns :name)}
+       (let [full-ns (get-in @namespaces [(-> env :ns :name) :uses sym])]
+         (merge
+          (get-in @namespaces [full-ns :defs sym])
+          {:name (symbol (str full-ns "." (munge (name sym))))
+           :ns (-> env :ns :name)}))

        :else
        (let [full-ns (if (core-name? env sym)
                        'cljs.core
                        (-> env :ns :name))]
          (confirm-var-exists env full-ns sym)
-         {:name (munge (symbol (str full-ns "." (munge (name sym)))))
-          :ns full-ns})))))
+         (merge
+          (get-in @namespaces [full-ns :defs sym])
+          {:name (munge (symbol (str full-ns "." (munge (name sym)))))
+           :ns full-ns}))))))

 (defn resolve-var [env sym]
   (if (= (namespace sym) "js")
@@ -716,11 +725,13 @@

 (defmethod parse 'def
   [op env form name]
-  (let [pfn (fn ([_ sym] {:sym sym})
+  (let [pfn (fn
+              ([_ sym] {:sym sym})
               ([_ sym init] {:sym sym :init init})
               ([_ sym doc init] {:sym sym :doc doc :init init}))
         args (apply pfn form)
-        sym (:sym args)]
+        sym (:sym args)
+        tag (-> sym meta :tag)]
     (assert (not (namespace sym)) "Can't def ns-qualified name")
     (let [env (let [ns-name (-> env :ns :name)]
                 (if (or (and (not= ns-name 'cljs.core)
@@ -743,13 +754,13 @@
       (swap! namespaces update-in [(-> env :ns :name) :defs sym]
              (fn [m]
                (let [m (assoc (or m {}) :name name)]
-                 (if-let [line (:line env)]
-                   (-> m
-                       (assoc :file *cljs-file*)
-                       (assoc :line line))
-                   m))))
+                 (merge m
+                   (when tag {:tag tag})
+                   (when-let [line (:line env)]
+                     {:file *cljs-file* :line line})))))
       (merge {:env env :op :def :form form
               :name name :doc doc :init init-expr}
+             (when tag {:tag tag})
              (when init-expr {:children [init-expr]})
              (when export-as {:export export-as})))))

@@ -1065,7 +1076,8 @@
    (let [enve (assoc env :context :expr)
          fexpr (analyze enve f)
          argexprs (vec (map #(analyze enve %) args))]
-     {:env env :op :invoke :f fexpr :args argexprs :children (conj argexprs fexpr)})))
+     {:env env :op :invoke :f fexpr :args argexprs
+      :children (conj argexprs fexpr) :tag (-> fexpr :info :tag)})))

 (defn analyze-symbol
   "Finds the var associated with sym"


Forgot the file extension

Forgot the file extension

--- src/frontend/stefon.clj
+++ src/frontend/stefon.clj
@@ -112,7 +112,7 @@
            "docs/time-seconds.md"
            "docs/troubleshooting-browsers.md"
            "docs/troubleshooting-clojure.md"
-           "docs/troubleshooting-guide"
+           "docs/troubleshooting-guide.md"
            "docs/troubleshooting-haskell.md"
            "docs/troubleshooting-nodejs.md"
            "docs/troubleshooting-php.md"


Make sure unwritten pages are sorted correctly.

--- src/od117_walker/core.clj
+++ src/od117_walker/core.clj
@@ -91,7 +91,7 @@
                                     :author (extract-author next-para)}))
             (recur (rest to-check)
                    (conj visited next)
-                   out))))
+                   (assoc out next {})))))
       out)))

 ;; Colours used for different author's bubbles.


Add examples of UI widgets with no style

--- src/play_clj/ui.clj
+++ src/play_clj/ui.clj
@@ -189,6 +189,7 @@
   "Returns an entity based on [CheckBox](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/scenes/scene2d/ui/CheckBox.html).

     (check-box \"I'm a check box\" (style :check-box off on font color))
+    (check-box \"I'm a check box\" (style :check-box nil nil (bitmap-font) (color :white)))
     (check-box \"I'm a check box\" (skin \"uiskin.json\"))"
   [text arg & options]
   `(let [entity# (check-box* ~text ~arg)]
@@ -240,6 +241,7 @@
   "Returns an entity based on [Dialog](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/scenes/scene2d/ui/Dialog.html).

     (dialog \"I'm a dialog\" (style :window font font-color background))
+    (dialog \"I'm a dialog\" (style :window (bitmap-font) (color :white) nil))
     (dialog \"I'm a dialog\" (skin \"uiskin.json\"))"
   [text arg & options]
   `(let [entity# (dialog* ~text ~arg)]
@@ -323,6 +325,7 @@
   "Returns an entity based on [ImageButton](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/scenes/scene2d/ui/ImageButton.html).

     (image-button (style :image-button up dn check img-up img-dn img-check))
+    (image-button (style :image-button nil nil nil nil nil nil))
     (image-button (skin \"uiskin.json\"))"
   [arg & options]
   `(let [entity# (image-button* ~arg)]
@@ -350,6 +353,8 @@

     (image-text-button \"I'm an image text button\"
                        (style :image-text-button up down checked font))
+    (image-text-button \"I'm an image text button\"
+                       (style :image-text-button nil nil nil (bitmap-font)))
     (image-text-button \"I'm an image text button\" (skin \"uiskin.json\"))"
   [text arg & options]
   `(let [entity# (image-text-button* ~text ~arg)]
@@ -379,7 +384,7 @@
   "Returns an entity based on [Label](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/scenes/scene2d/ui/Label.html).

     (label \"I'm a label\" (color :white))
-    (label \"I'm a label\" (style :label (g2d/bitmap-font) (color :white)))
+    (label \"I'm a label\" (style :label (bitmap-font) (color :white)))
     (label \"I'm a label\" (skin \"uiskin.json\"))"
   [text arg & options]
   `(let [entity# (label* ~text ~arg)]
@@ -406,6 +411,7 @@
   "Returns an entity based on [ScrollPane](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/scenes/scene2d/ui/ScrollPane.html).

     (scroll-pane table-entity (style :scroll-pane back h h-knob v v-knob))
+    (scroll-pane table-entity (style :scroll-pane nil nil nil nil nil))
     (scroll-pane table-entity (skin \"uiskin.json\"))"
   [child arg & options]
   `(let [entity# (scroll-pane* ~child ~arg)]
@@ -432,6 +438,10 @@
   "Returns an entity based on [SelectBox](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/scenes/scene2d/ui/SelectBox.html).

     (select-box (style :select-box font color back scroll-style list-style)
+                :set-items (into-array [\"Item 1\" \"Item 2\" \"Item 3\"]))
+    (select-box (style :select-box (bitmap-font) (color :white) nil
+                       (style :scroll-pane nil nil nil nil nil)
+                       (style :list (bitmap-font) (color :white) (color :black) nil))
                 :set-items (into-array [\"Item 1\" \"Item 2\" \"Item 3\"]))
     (select-box (skin \"uiskin.json\")
                 :set-items (into-array [\"Item 1\" \"Item 2\" \"Item 3\"]))"
@@ -463,6 +473,7 @@
   "Returns an entity based on [Slider](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/scenes/scene2d/ui/Slider.html).

     (slider {:min 0 :max 10 :step 1 :vertical? false} (style :slider back knob))
+    (slider {:min 0 :max 10 :step 1 :vertical? false} (style :slider nil nil))
     (slider {:min 0 :max 10 :step 1 :vertical? false} (skin \"uiskin.json\"))"
   [attrs arg & options]
   `(let [entity# (slider* ~attrs ~arg)]
@@ -539,6 +550,7 @@
   "Returns an entity based on [TextButton](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/scenes/scene2d/ui/TextButton.html).

     (text-button \"I'm a text button\" (style :text-button up dn checked font))
+    (text-button \"I'm a text button\" (style :text-button nil nil nil (bitmap-font)))
     (text-button \"I'm a text button\" (skin \"uiskin.json\"))"
   [text arg & options]
   `(let [entity# (text-button* ~text ~arg)]
@@ -564,7 +576,8 @@
 (defmacro text-field
   "Returns an entity based on [TextField](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/scenes/scene2d/ui/TextField.html).

-    (text-field \"I'm a text field\" (style :text-field font col cur sel back))
+    (text-field \"I'm a text field\" (style :text-field font color cur sel back))
+    (text-field \"I'm a text field\" (style :text-field (bitmap-font) (color :white) nil nil nil))
     (text-field \"I'm a text field\" (skin \"uiskin.json\"))"
   [text arg & options]
   `(let [entity# (text-field* ~text ~arg)]
@@ -591,6 +604,7 @@
   "Returns an entity based on [Tree](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/scenes/scene2d/ui/Tree.html).

     (tree [entity-1 entity-2] (style :tree plus minus selection))
+    (tree [entity-1 entity-2] (style :tree nil nil nil))
     (tree [entity-1 entity-2] (skin \"uiskin.json\"))"
   [children arg & options]
   `(let [entity# (tree* ~children ~arg)]
@@ -641,7 +655,8 @@
 (defmacro window
   "Returns an entity based on [Window](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/scenes/scene2d/ui/Window.html).

-    (window [entity-1 entity-2] \"I'm a window\" (style :window title font col))
+    (window [entity-1 entity-2] \"I'm a window\" (style :window font color background))
+    (window [entity-1 entity-2] \"I'm a window\" (style :window (bitmap-font) (color :white) nil))
     (window [entity-1 entity-2] \"I'm a window\" (skin \"uiskin.json\"))"
   [children title arg & options]
   `(let [entity# (window* ~children ~title ~arg)]


Add ISS image

Add ISS image

--- src/orbitingnews/core.clj
+++ src/orbitingnews/core.clj
@@ -5,7 +5,7 @@
             [compojure.route :as route]))

 (defroutes app-routes
-  (GET "/" [] "Hello HTTP!"))
+  (GET "/" [] "Houston we have a problem
"))

 (defn -main
   "I don't do a whole lot."


resize of large images

resize of large images

--- src/harnocode/core.cljs
+++ src/harnocode/core.cljs
@@ -278,7 +278,7 @@
       )
     ))

-(defonce max-image-dimension 300)
+(defonce max-image-dimension 224)

 (defn on-image-load [event]
   (let [image (.-target event)
@@ -312,7 +312,7 @@
   )

 (defn handle-files [event]
-  {:pre [(not (nil? (.-files (.-target event))))]}
+  {:pre [(> (alength (.-files (.-target event))) 0)]}
   (let [f (nth (to-clj-array (.-files (.-target event))) 0)
         reader (js/FileReader.)]
     (set! (.-onloadend reader) on-reader-load)


Add resulting code validation.

Add resulting code validation.

Essentially, we compare AST of the input source code and AST of the
source code after harnification.

--- src/harnocode/core.cljs
+++ src/harnocode/core.cljs
@@ -142,6 +142,16 @@
         unused               (arrange-unused ts-unused 160)
         result (concat arranged unused)]
     (string/join "\n" result)))              ; img must be resized by now, no need in w
+
+(defn validate [code img w]
+  (let [ast-before (js->clj (js/esprima.parse code))
+        harnocode  (harnify code img w)
+        ast-after  (js->clj (js/esprima.parse harnocode))
+        _ (println "-----")
+        msg        (if (= ast-before ast-after)
+                    "OK"
+                    (str "Differs: " (js/escodegen.generate ast-after)) "\nFAIL")]
+    (println msg)))

 ;; TODO: add unused tokens

@@ -203,6 +213,7 @@
       img @img
       width (count (first img))
       harnocode (harnify code img width)]
+  (validate code img width)
   (show-harnocode! harnocode))


simplify the function in insert-endpoint!

get-in and assoc-in are your friends.

--- src/puppetlabs/cthun/connection_states.clj
+++ src/puppetlabs/cthun/connection_states.clj
@@ -51,23 +51,17 @@
   [host type]
   (str "cth://" host "/" type "/" (str (java.util.UUID/randomUUID))))

-; TODO(ploubser): This seems ever so janky. I'm willing to bet money that there
-; is a more lispy way of doing this.
 (defn- insert-endpoint!
   "Create a map from an endpoint string and websocket object"
   [endpoint ws]
   (let [points (str/split (subs endpoint 6) #"/")
         host (get points 0)
         type (get points 1)
-        uid (get points 2)]
-    (swap! endpoint-map (fn [e-map]
-                          (if-let [found-host (get @endpoint-map host)]
-                            (if-let [found-type (get found-host type)]
-                              (if-let [found-uid (get found-type uid)]
-                                (throw (Exception. (str "Endpoint already exists: " endpoint)))
-                                (assoc-in e-map [host type] (conj (get (get e-map host) type) {uid ws})))
-                              (assoc-in e-map [host] (conj (get e-map host) {type {uid ws}})))
-                            (merge e-map {host {type {uid ws}}}))))))
+        uid  (get points 2)]
+    (swap! endpoint-map (fn [map]
+                          (if-let [existing (get-in map [host type uid])]
+                            (throw (Exception. (str "Endpoint already exists: " endpoint)))
+                            (assoc-in map [host type uid] ws))))))

 (s/defn ^:always-validate
   new-socket :- ConnectionMap


* src/quil/applet.clj: fix bug where frame wasn't being set

--- src/quil/applet.clj
+++ src/quil/applet.clj
@@ -78,7 +78,8 @@
                    (.pack))
                  (when (= mode :opengl)
                    (.setResizable f false))
-                 (.show f))))))
+                 (.show f)
+                 f)))))

 (def ^{:private true}
   renderer-modes {:p2d    P2D


Indexing error

Indexing error

--- src/re_db/core.cljs
+++ src/re_db/core.cljs
@@ -79,7 +79,7 @@
   "Returns id, resolving lookup refs (vectors of the form `[attribute value]`) to ids. Lookup refs are only supported for indexed attributes.
   Arity 3 is for known lookup refs, and does not check for uniqueness."
   ([db-snap attr val]
-   (log-read [:attr-val] conj [nil attr val])
+   (log-read [:_av] conj [nil attr val])
    (first (get-in* db-snap [:ave attr val])))
   ([db-snap id]
    (if ^:boolean (vector? id)
@@ -92,7 +92,9 @@
 (defn contains?
   "Returns true if entity with given id exists in db."
   [db-snap id]
-  (contains?* (get* db-snap :eav) (resolve-id db-snap id)))
+  (let [id (resolve-id db-snap id)]
+    (when id (log-read [:e__] conj [id]))
+    (true? (contains?* (get* db-snap :eav) id))))

 (defn- listen-path!
   [db path f]
@@ -106,24 +108,33 @@

 (declare get entity)

+(defn p-nil?
+  "Return true if value is nil or '_"
+  [x]
+  (or (nil? x) (= '_ x)))
+
 (defn pattern->idx
   "Returns type of listener pattern."
-  [pattern]
-  (let [[id attr val] (mapv #(if (= % '_) nil %) pattern)]
-    (cond (and id attr) :entity-attr
-          (and attr val) :attr-val
-          id :id
-          attr :attr
-          :else nil)))
+  [[e a v :as x]]
+  (let [pattern (keyword (str (if (p-nil? e) "_" "e")
+                              (if (p-nil? a) "_" "a")
+                              (if (p-nil? v) "_" "v")))]
+    (when-not (#{:e__ :ea_ :_av :_a_} pattern)
+      (println {:pattern pattern :x x})
+      (throw (js/Error. (str "Unsupported pattern: " " " pattern "e: " e "a: " a "v: " v))))
+    pattern))
+
+;; spec
+

 (defn- pattern->listener-path
   "Returns path to listener set for the given access pattern."
   [[id attr val :as pattern]]
   (case (pattern->idx pattern)
-    :entity-attr [:listeners :entity-attr id attr]
-    :attr-val [:listeners :attr-val attr val]
-    :id [:listeners :entity id]
-    :attr [:listeners :attr attr]
+    :e__ [:listeners :e__ id]
+    :ea_ [:listeners :ea_ id attr]
+    :_av [:listeners :_av attr val]
+    :_a_ [:listeners :_a_ attr]
     nil [:listeners :tx-log]))

 (declare listen! unlisten!)
@@ -155,10 +166,10 @@

 (defn listen!
   "Add pattern listeners. Supported patterns:
-   [id attr _]  => :entity-attr
-   [_ attr val] => :attr-val
-   [id _ _]     => :entity
-   [_ attr _]   => :attr"
+   [id attr _]  => :ea_
+   [_ attr val] => :_av
+   [id _ _]     => :e__
+   [_ attr _]   => :_a_"
   [db & patterns]
   (let [f (last patterns)]
     (doseq [pattern (seq (drop-last patterns))]
@@ -171,7 +182,7 @@
   "Returns entity for resolved id."
   [db-snap id]
   (when-let [id (resolve-id db-snap id)]
-    (log-read [:id] conj [id])
+    (log-read [:e__] conj [id])
     (some-> (get-in* db-snap [:eav id])
             (assoc id-attr id))))

@@ -179,23 +190,23 @@
   "Get attribute in entity with given id."
   ([db-snap id attr]
    (when-let [id (resolve-id db-snap id)]
-     (log-read [:entity-attr id] fnil-conj-set [id attr])
+     (log-read [:ea_ id] fnil-conj-set [id attr])
      (get-in* db-snap [:eav id attr])))
   ([db-snap id attr not-found]
    (when-let [id (resolve-id db-snap id)]
-     (log-read [:entity-attr id] fnil-conj-set [id attr])
+     (log-read [:ea_ id] fnil-conj-set [id attr])
      (get-in* db-snap [:eav id attr] not-found))))

 (defn get-in
   "Get-in the entity with given id."
   ([db-snap id ks]
    (when-let [id (resolve-id db-snap id)]
-     (log-read [:entity-attr id] fnil-conj-set [id (first ks)])
+     (log-read [:ea_ id] fnil-conj-set [id (first ks)])
      (-> (get-in* db-snap [:eav id])
          (get-in* ks))))
   ([db-snap id ks not-found]
    (when-let [id (resolve-id db-snap id)]
-     (log-read [:entity-attr id] fnil-conj-set [id (first ks)])
+     (log-read [:ea_ id] fnil-conj-set [id (first ks)])
      (-> (get-in* db-snap [:eav id])
          (get-in* ks not-found)))))

@@ -203,7 +214,7 @@
   "Select keys from entity of id"
   [db-snap id ks]
   (when-let [id (resolve-id db-snap id)]
-    (log-read [:entity-attr id] into (mapv #(do [id %]) ks))
+    (log-read [:ea_ id] into (mapv #(do [id %]) ks))
     (-> (get-in* db-snap [:eav id])
         (assoc id-attr id)
         (select-keys* ks))))
@@ -321,12 +332,14 @@
     (fn [db-snap attr val]
       (let [schema (get-schema db-snap attr)
             prev-val (get* prev-m attr)]
-        (if (many? schema)
-          (update-index db-snap id attr
-                        (set/difference val prev-val)
-                        (set/difference prev-val val)
-                        schema)
-          (update-index db-snap id attr val prev-val schema))))
+        (cond (many? schema)
+              (update-index db-snap id attr
+                            (set/difference val prev-val)
+                            (set/difference prev-val val)
+                            schema)
+              (not= val prev-val)
+              (update-index db-snap id attr val prev-val schema)
+              :else db-snap)))
     db-snap m))

 (defn add-map-datoms [datoms id m prev-m db-snap]
@@ -383,21 +396,21 @@
         (swap! seen-ids conj (datom 0))

         ;; entity-attr listeners
-        (doseq [f (get-in* listeners [:entity-attr id a])]
+        (doseq [f (get-in* listeners [:ea_ id a])]
           (f datom))

         ;; attr-val listeners
         (doseq [v (cond-> (or v prev-v)
                           (not (many? a)) (list))]
-          (doseq [f (get-in* listeners [:attr-val a v])]
+          (doseq [f (get-in* listeners [:_av a v])]
             (f datom)))

         ;; attr listeners
-        (doseq [f (get-in* listeners [:attr a])]
+        (doseq [f (get-in* listeners [:_a_ a])]
           (f datom)))

       (doseq [id @seen-ids]
-        (doseq [f (get-in* listeners [:entity id])]
+        (doseq [f (get-in* listeners [:e__ id])]
           (f id)))

       ;; tx-log listeners
@@ -469,12 +482,12 @@
                           (reduce-kv (fn [s id entity] (if ^:boolean (q entity) (conj s id) s)) #{} (get* db-snap :eav))

                           (keyword? q)
-                          (do (log-read [:attr] conj [nil q nil])
+                          (do (log-read [:_a_] conj [nil q nil])
                               (reduce-kv (fn [s id entity] (if ^:boolean (contains?* entity q) (conj s id) s)) #{} (get* db-snap :eav)))

                           :else
                           (let [[attr val] q]
-                            (log-read [:attr-val] conj [nil attr val])
+                            (log-read [:_av] conj [nil attr val])
                             (if (index? db-snap attr)
                               (get-in* db-snap [:ave attr val])
                               (do (when ^:boolean (true? *debug*) (println (str "Not an indexed attribute: " attr)))
@@ -489,14 +502,14 @@
   (str (uuid-utils/make-random-uuid)))

 (def blank-access-log
-  {:id          #{}
-   :attr        #{}
-   :attr-val    #{}
-   :entity-attr {}})
+  {:e__ #{}
+   :_a_ #{}
+   :_av #{}
+   :ea_ {}})

 (defn access-log-patterns
   "Returns vector of access log patterns, pruning overlapping patterns"
-  [{ids :id attr-vals :attr-val entity-attrs :entity-attr attrs :attr }]
+  [{ids :e__ attr-vals :_av entity-attrs :ea_ attrs :_a_}]
   (apply set/union
          ids
          attr-vals


allow for a long first http request line

--- src/io/cyanite/http.clj
+++ src/io/cyanite/http.clj
@@ -130,7 +130,7 @@
   (proxy [ChannelInitializer] []
     (initChannel [channel]
       (let [pipeline (.pipeline channel)]
-        (.addLast pipeline "codec"      (HttpServerCodec.))
+        (.addLast pipeline "codec"      (HttpServerCodec. 1048576 8192 8192))
         (.addLast pipeline "aggregator" (HttpObjectAggregator. 1048576))
         (.addLast pipeline "handler"    (netty-handler handler))))))