Deleted extra functions from earlier testing

--- src/clj/forma/hadoop/jobs/scatter.clj
+++ src/clj/forma/hadoop/jobs/scatter.clj
@@ -297,69 +297,6 @@
                                             (hfs-seqfile
                                             static-path)))))))

-;; (comment
-;;   "Run this:"
-;;   (ultrarunner "/user/hadoop/checkpoint"
-;;                "s3n://formaresults/ecobetatemp"
-;;                "s3n://formaresults/fullbetatemp"
-;;                "s3n://formaresults/staticbuckettemp"
-;;                "s3n://formaresults/finalbuckettemp"
-;;                "s3n://formaresults/finaloutput"
-;;                "eco"))
-
-
-
-(defbufferop eco-bufferop
-  "returns a vector of parameter coefficients.  note that this is
-  where the intercept is added (to the front of each stacked vector in
-  the feature matrix
-
-  TODO: The intercept is included in the feature vector for now, as a
-  kludge when we removed the hansen statistic.  When we include the
-  hansen stat, we will have to replace the feature-mat binding below
-  with a line that tacks on a 1 to each feature vector.
-  "
-  [tuples]
-  (let [val-mat      (map second tuples)
-        neighbor-mat (map last tuples)
-        feature-mat  (map log/unpack-feature-vec val-mat neighbor-mat)]
-    [[]]))
-
-(defn sink-eco
-  [{:keys [t-res est-start ridge-const convergence-thresh max-iterations]}
-   dynamic-src static-src ecoid]
-  (let [first-idx (date/datetime->period t-res est-start)]
-    (<- [?hansen ?val ?neighbor-val]
-        (dynamic-src ?s-res ?pd ?mod-h ?mod-v ?s ?l ?val ?neighbor-val)
-        (static-src ?s-res ?mod-h ?mod-v ?s ?l _ _ ?eco ?hansen)
-        (= ?pd first-idx)
-        (= ecoid ?eco)
-        (:distinct false))))
-
-(defmain prebeta
-  "do everything but actually estimate the beta vector - we want the data all in one file we can download"
-  [tmp-root static-path final-path out-path ecoid]
-  (let [est-map (forma-run-parameters "500-16")]
-    (workflow [tmp-root]
-              genbetas
-              ([]
-                 (?- (hfs-seqfile out-path :sinkmode :replace)
-                     (sink-eco est-map
-                               (hfs-seqfile final-path)
-                               (hfs-seqfile static-path)
-                               ecoid))))))
-
-(comment
-  "Run this:"
-   (ultrarunner "/user/hadoop/checkpoint"
-               "s3n://formaresults/ecobetatemp"
-               "s3n://formaresults/countrybetatemp"
-               "s3n://formaresults/staticbuckettemp"
-               "s3n://formaresults/finalbuckettemp"
-               "s3n://formaresults/finaloutput"
-               "eco"
-               "s3n://formaresults/ecobetapreapply"))
-
 (defn run-forma-estimate
   [beta-src dynamic-src static-src out-loc trap-path period]
   (?- (hfs-seqfile out-loc :sinkmode :replace)


User agent upgrade

User agent upgrade

Adjust user agent to new release.

--- src/clj/http/async/client/request.clj
+++ src/clj/http/async/client/request.clj
@@ -32,7 +32,7 @@
                     ByteArrayInputStream
                     ByteArrayOutputStream)))

-(def ^:dynamic *user-agent* "http.async.client/0.4.1-dev")
+(def ^:dynamic *user-agent* "http.async.client/0.4.1")

 (def ^:dynamic *CLIENT* nil)


highlight current page

highlight current page

--- src/cljs/omnext_routing_one/core.cljs
+++ src/cljs/omnext_routing_one/core.cljs
@@ -120,7 +120,7 @@

-(println (om/props this))
+(prn (om/props this))
 (when (> (:pages (:countries (om/props this))) 1)
   (apply dom/ul
    #js
@@ -369,7 +369,7 @@
   (println "readf" k params)
   (if-let [v (get @state k)]
     {:value
-     {:page (:page params)
+     {:page (or (cljs.reader/parse-int (:page params)) 1)
       :pages (.ceil js/Math
                     (/ (count v)
                        items-per-page


combined om roots into a single let to share channels

--- src/cljs/triangulator/components.cljs
+++ src/cljs/triangulator/components.cljs
@@ -188,21 +188,21 @@
                           (dom/h3 nil "Vertices")
                           (om/build triangle-detail (:triangle app) {:opts opts})))))))

-(om/root
- item-controller
- state/app-state
- {:target (. js/document (getElementById "definition-box"))
-  :opts
-  (let [{:keys [canvas width height]} (draw/surface "graphics-box")
-        click-chan (events/mouse-chan canvas :mouse-down :click)
-        mouse-move-chan (events/mouse-chan canvas :mouse-move :move)
-        draw-chan (draw/drawing-loop canvas width height)
-        events (async/merge [mouse-move-chan click-chan])]
-    {:event-chan events
-     :draw-chan draw-chan
-     :control-chan (chan)})})
-
-(om/root
- nav-box
- state/app-state
- {:target (. js/document (getElementById "definition-list"))})
+(let [{:keys [canvas width height]} (draw/surface "graphics-box")
+      click-chan (events/mouse-chan canvas :mouse-down :click)
+      mouse-move-chan (events/mouse-chan canvas :mouse-move :move)
+      draw-chan (draw/drawing-loop canvas width height)
+      events (async/merge [mouse-move-chan click-chan])]
+
+  (om/root
+   item-controller
+   state/app-state
+   {:target (. js/document (getElementById "definition-box"))
+    :opts {:event-chan events
+           :draw-chan draw-chan
+           :control-chan (chan)}})
+
+  (om/root
+   nav-box
+   state/app-state
+   {:target (. js/document (getElementById "definition-list"))}))


4clojure:: conway's game of life finished implementation

--- src/clojure_learning/game_of_life.clj
+++ src/clojure_learning/game_of_life.clj
@@ -1,6 +1,7 @@
 (ns clojure-learning.game-of-life)
 (require '[clojure.string :as str])

+;http://www.4clojure.com/problem/94
 ;Each cell interacts with its eight neighbours (horizontal, vertical, diagonal)
 ;1) Any live cell with fewer than two live neighbours dies, as if caused by under-population.
 ;2) Any live cell with two or three live neighbours lives on to the next generation.
@@ -13,26 +14,27 @@
            "     "
            "     "])

+;; function outer
 (defn replace-ws-with-char [strings replacer]
   (map #(str/replace % #"\s" replacer) strings))

 (def r (replace-ws-with-char life "0"))

+;; function outer
 (defn table->matrix [table]
   (map #(str/split % #"") table))

 (def matrix (table->matrix r))
 matrix

-;[row col]
-;[0 0]:: [0 1] [1 0] [1 1]
-;
 ;[1 1]:: [0 0] [0 1] [0 2]
 ;        [1 0]       [1 2]
 ;        [2 0] [2 1] [2 2]

-
+;; function inner
 (defn gen-neighbours-by-row [[row col] row-func]
+  "function that generates neighbours for given coordinate by applying the row-func
+   which can be any of: inc(neighbours-for-next-row), dec(neighbours-for-previous-row)"
   (letfn [(clean-alien-cels [cels-coordinates]
             (filter (fn [cell-coordinate]
                       (= 2 (count (remove neg? cell-coordinate))))
@@ -44,11 +46,15 @@
     (clean-alien-cels
       (gen-raw-neighbours-by-row [row col] row-func))))

+;; test
 (gen-neighbours-by-row [0 1] dec) ;; ()
 (gen-neighbours-by-row [0 1] inc) ;; ((1 0) (1 1) (1 2))
 (gen-neighbours-by-row [1 1] dec) ;; ((0 0) (0 1) (0 2))

+;; function inner
 (defn gen-neighbours-for [[row col :as cell-coordinates]]
+  "given a pair of coordinates on the table, generate all possible adjacent coordinates
+   that serve as neighbours for the given cell"
   (letfn [(clean-alien-cels [cels-coordinates]
                       (filter (fn [cell-coordinate]
                                 (= 2 (count (remove neg? cell-coordinate))))
@@ -72,12 +78,15 @@
       (map vec (gen-neighbours-by-row [row col] next-row-func))
     )))

+;; testing
 (gen-neighbours-for [0 1])
 ;; ((0 0)   ..   (0 2)
 ;;  (1 0) (1 1)  (1 2))

-matrix
+;; function outer
 (defn transpose-table->positions
+  "given a matrix of cells(0 1) this function will map each dump-cell with it's corresponding
+   coordinates on the table"
   [[head-row-with-cols & tail-rows] row-counter transposed-table-acc]
     (letfn [(generate-row-with-cols-tuple [row-counter cols-counter]
               (map vec
@@ -100,74 +109,120 @@
                      (structure-cells head-row-with-cols row-counter)
 )))))

-(take 3 (iterate inc 0))
-(transpose-table->positions [["0" "0" "0" "#" "0"] ["0" "0" "0" "0" "0"]] 0 [])
-
-(def transposed (transpose-table->positions [["0" "0" "0" "#" "0"] ["0" "0" "0" "0" "0"]] 1 []))
-transposed
-
-(get-in [[0 1 2 3] [4 5 6 7]] [0 2])
-(get-in [
-         [{:alive false :adj [[1 0] [1 1] [0 1]]}, {:alive false :adj [[0 0] [0 2] [1 0] [1 1] [1 2]]}]
-         [{:alive false :adj [[3 4] [5 6]]}, {:alive true :adj [[1 2] [1 4] [0 1]]}] ]
-        [1 0]) ;; this is the data-structure i expect!!!
-(if (:alive {:alive true}) (str "OK") (str "NOK")) ;; OK!
-
-(defn structure-cells-with-neighours
-  [[head-row-cols-with-positions & tail-rows] mapped-cells-with-neighbours]
-  (if (nil? head-row-cols-with-positions)
-    mapped-cells-with-neighbours
-    (recur tail-rows
-       (conj mapped-cells-with-neighbours
-             (vec (map (fn [cell-with-position]
-                                     {:alive (= "#" (first cell-with-position))
-                                      :neighbours-pos (gen-neighbours-for (second cell-with-position))})
-                             head-row-cols-with-positions))))
-))
-
-(defn map-cells-status-with-neighbours [matrix]
-  (let [starting-row 0
-        transposed-cells-with-positions (transpose-table->positions matrix starting-row [])]
-    (structure-cells-with-neighours transposed-cells-with-positions [])
-    ;; iterate
-))
-
-matrix
-(map-cells-status-with-neighbours matrix)
-
-;; once we mapped one cell "0" as::
-; { :alive false,
-;   :neighbours-pos ((3 3) (3 4) (3 5) (4 3) (4 5) (5 3) (5 4) (5 5))}
-
-;; next thing is to iterate each cell's neighbour and find in the
-;; transposed cells for each neighbour its liveness state
-
-(defn map-cells-with-alive-neighbours
-  [[head-mapped-cols-with-neighbours & tail-rows]
-   mapped-cells
-   cells-table-with-alive-neighbours]
-  (if (nil? head-mapped-cols-with-neighbours)
-    cells-table-with-alive-neighbours
-    (recur
-      tail-rows
-      mapped-cells
-      (conj cells-table-with-alive-neighbours
-            (map
-              (fn [cell-with-neighbours-positions]
-                (reduce
-                  (fn [alive-neighbours-acc neighbour-position]
-                    (let [neighbour (get-in mapped-cells neighbour-position)]
-                      (if (:alive neighbour)
-                        (conj alive-neighbours-acc neighbour-position)
-                        alive-neighbours-acc
-                        )))
-                  [] (:neighbours-pos cell-with-neighbours-positions))
-                )
-              head-mapped-cols-with-neighbours)
-      ))
-  ))
-
-(def neighs (map-cells-status-with-neighbours matrix))
-neighs
-(get-in neighs [4 4])
-(map-cells-with-alive-neighbours neighs neighs [])+;; test
+(def transposed->positions
+  (-> matrix
+    (transpose-table->positions 0 [])))
+transposed->positions
+;[... [["0" [4 0]] ["0" [4 1]] ["0" [4 2]] ["0" [4 3]] ["0" [4 4]]]]
+
+;; function inner
+(defn transpose-table-w-positions->map [table-cells-w-positions]
+  "function that will flatten and normalize the cells-with-positions to a map for
+   faster/easier-to-understand/constant-time lookups"
+  (let [flatten-cell->pos-pairs #(partition 3 (flatten %))]
+    (reduce
+      (fn [mapped-cells [cell-primitive-state & cell-position]]
+        (assoc mapped-cells (vec cell-position) cell-primitive-state))
+      {}
+      (flatten-cell->pos-pairs table-cells-w-positions))))
+
+;; test
+(def transposed->mapped-positions (transpose-table-w-positions->map transposed->positions))
+transposed->mapped-positions
+;{...[2 1] "#", [4 4] "0", [1 2] "0", ... }
+
+;; function inner
+(defn get-alive-neighbours [neighbours table-of-cells-w-positions]
+  "function that takes some neighbours and returns the ones for which cells are alive"
+  (let [map-of-cells-w-positions (transpose-table-w-positions->map table-of-cells-w-positions)
+        alive? #(= "#" %1)]
+  (reduce (fn [alive-neighbours-acc neighbour]
+            (if (alive? (get map-of-cells-w-positions neighbour))
+              (conj alive-neighbours-acc neighbour)
+              alive-neighbours-acc))
+    [] neighbours)))
+
+
+;; function outer-highest
+(defn one-generation->map-cells
+  "function that takes a table-of-cells and maps each cell to the INITIAL SEED given.
+   Each cell will have it's own view of the initial-seed hence might be updated simultaneously"
+  [table-of-cells-w-positions-view]
+  (letfn [(convert-cell [cell] (if (= "#" cell) {:alive true} {:alive false}))
+          (identify-cell-state [cell] (if (true? (:alive cell)) :alive :dead))
+
+          (cell-should-born? [cell identified-alive-neighbours]
+            (and (false? (:alive cell)) (= 3 (count identified-alive-neighbours))))
+
+          (cell-should-die? [cell identified-alive-neighbours]
+            (and (:alive cell) (or (> (count identified-alive-neighbours) 3) ;; overpopulation
+                                   (< (count identified-alive-neighbours) 2)))) ;; underpopulation
+
+          (cell-should-live? [cell identified-alive-neighbours]
+            (and (:alive cell) (or (<= (count identified-alive-neighbours) 3)
+                                   (>= (count identified-alive-neighbours) 2))))
+
+          (bless-cell [cell alive-neighbours]
+            (cond (cell-should-born? cell alive-neighbours)
+                  :alive
+                  (cell-should-die? cell alive-neighbours)
+                  :dead
+                  (cell-should-live? cell alive-neighbours)
+                  :alive
+                  :else (identify-cell-state cell)))]
+
+    (map (fn [row-cells-with-position]
+        (map (fn [cell-with-position]
+               (let [[cell-primitive-state cell-position] cell-with-position
+                     converted-cell (convert-cell cell-primitive-state)
+                     alive-neighbours (get-alive-neighbours
+                                                  (gen-neighbours-for cell-position) table-of-cells-w-positions-view)]
+                 (bless-cell converted-cell alive-neighbours)
+             ))
+             row-cells-with-position
+        ))
+        table-of-cells-w-positions-view
+)))
+
+;;test
+(def transposed
+  (-> matrix
+    (transpose-table->positions 0 [])))
+
+;; DONE! game of life!!!!
+(one-generation->map-cells transposed)
+;((:dead :dead :dead :dead :dead)
+; (:dead :dead :alive :dead :dead)
+; (:dead :dead :alive :dead :dead)
+; (:dead :dead :alive :dead :dead)
+; (:dead :dead :dead :dead :dead))
+
+;;;;;;;;;;;;;;;;;;;;;;;
+;; another test-case:: => try beating clojure at structuring the code into pipelined-chaining-computations
+(->
+  ["      "
+   " ##   "
+   " ##   "
+   "   ## "
+   "   ## "
+   "      "]
+  (replace-ws-with-char "0")
+  table->matrix
+  (transpose-table->positions 0 [])
+  one-generation->map-cells)
+
+;; comparing outputs::
+;["      "
+; " ##   "
+; " #    "
+; "    # "
+; "   ## "
+; "      "]
+;((:dead :dead :dead :dead :dead :dead)
+; (:dead :alive :alive :dead :dead :dead)
+; (:dead :alive :dead :dead :dead :dead)
+; (:dead :dead :dead :dead :alive :dead)
+; (:dead :dead :dead :alive :alive :dead)
+; (:dead :dead :dead :dead :dead :dead))
+;; WHOOOOOOHOOOOOO :)


remove unused clj-time from util

remove unused clj-time from util

--- src/com/billpiel/sayid/util/other.clj
+++ src/com/billpiel/sayid/util/other.clj
@@ -1,7 +1,5 @@
 (ns com.billpiel.sayid.util.other
-  (require [clj-time.core :as time]
-           [clj-time.coerce :as time-c]
-           [clojure.walk :as walk]
+  (require [clojure.walk :as walk]
            [clojure.tools.reader :as r]
            [clojure.tools.reader.reader-types :as rts]
            clojure.repl))
@@ -163,11 +161,6 @@
       (obj-pred-action-else string? :t-fn symbol)
       (obj-pred-action-else symbol? :t-fn #(ns-resolve ns-sym %))
       derefable?->))
-
-(defn diff-dates-in-msec
-  [a b]
-  (- (-> a time-c/from-date time-c/to-long)
-     (-> b time-c/from-date time-c/to-long)))

 (defn replace$
   [form]


remove lookups from unique-key pre-insert

--- src/er_cassandra/model/unique_key.clj
+++ src/er_cassandra/model/unique_key.clj
@@ -243,15 +243,16 @@
           new-record
           (:unique-key-tables model)))

-(defn without-unique-keys
-  "remove (the final part of) unique key columns from a record"
+(defn without-lookups
+  "remove (the final part of) lookup (including unique-key)
+   columns from a record"
   [^Model model record]
-  (let [unique-key-tables (:unique-key-tables model)]
+  (let [lookup-tables (concat (:unique-key-tables model) (:lookup-tables model))]
     (reduce (fn [r t]
               (let [key-col (last (:key t))]
                 (dissoc r key-col)))
             record
-            unique-key-tables)))
+            lookup-tables)))

 (defn update-unique-keys
   "attempts to acquire unique keys for an owner... returns
@@ -261,7 +262,7 @@
   (m/with-monad dm/either-deferred-monad
     (m/mlet [create-primary (r/insert session
                                       (get-in model [:primary-table :name])
-                                      (without-unique-keys model new-record))
+                                      (without-lookups model new-record))

              old-record (r/select-one session
                                       (get-in model [:primary-table :name])


Tidy up logging a bit

Tidy up logging a bit

--- src/leiningen/new/cljskel/project.clj
+++ src/leiningen/new/cljskel/project.clj
@@ -11,9 +11,11 @@
                  [org.clojure/data.zip "0.1.1"]
                  [org.clojure/tools.logging "0.2.6"]
                  [org.slf4j/slf4j-api "1.7.5"]
+                 [org.slf4j/jcl-over-slf4j "1.7.5"]
                  [org.slf4j/jul-to-slf4j "1.7.5"]
+                 [org.slf4j/log4j-over-slf4j "1.7.5"]
                  [ch.qos.logback/logback-classic "1.0.13"]
-                 [com.ovi.common.logging/logback-appender "0.0.45"]
+                 [com.ovi.common.logging/logback-appender "0.0.45" :exclusions [commons-logging/commons-logging]]
                  [com.yammer.metrics/metrics-logback "2.2.0"]
                  [com.ovi.common.metrics/metrics-graphite "2.1.21"]
                  [clj-http "0.7.6"]


input edit handling escape OK

input edit handling escape OK

--- cljs/tag/src/todo/core.cljs
+++ cljs/tag/src/todo/core.cljs
@@ -156,6 +156,7 @@

 			(= (.-key e) "Escape")
 			(do (println :ESCAPING!!!!!)
+				(set! (.-value edom) (md-get td :title))
 				(.remove (.-classList li-dom) "editing")))))

 (defn todo-start-editing [e]


Adding memory status, and fixing for case of no keywords.

--- Spraff/src/spraff/core.clj
+++ Spraff/src/spraff/core.clj
@@ -88,7 +88,7 @@
         (remove keyword? (map first
             (apply max-key #(count (filter true? (map second %)))
                 (take retries (repeatedly #(sentence-from-seed
-                    (rand-nth (:n-grams state))
+                    (rand-nth (seq (:n-grams state)))
                     (:backwardtable state)
                     (:forwardtable state)))))))
         (let [filtered-grams
@@ -228,6 +228,15 @@
     (if (.startsWith message "!burrito")
         (send-message irc channel
             (generate-burrito)))
+    (if (.startsWith message "!memory")
+        (send-message irc channel
+            (let [
+                r (Runtime/getRuntime)
+                free (.freeMemory r)
+                total (.totalMemory r)
+                to-mb (fn [b] (Math/round (double (/ b (* 1024 1024)))))
+                ]
+                (str "Total: " (to-mb total) " MiB" " - " "Free: " (to-mb free) " MiB"))))
 )

 (defn -main


move all cljs hacks to delayed init to fix some AOT issues

--- src/main/shadow/build/cljs_hacks.cljc
+++ src/main/shadow/build/cljs_hacks.cljc
@@ -543,9 +543,6 @@

     ast))

-(defmethod ana/parse '.
-  [_ env [_ target field & member+ :as form] _ opts]
-  (ana/disallowing-recur (shadow-analyze-dot env target field member+ form opts)))

 ;; its private in cljs.compiler ...
 (def es5>=
@@ -602,11 +599,6 @@
         (when-not (= :statement (:context env))
           (comp/emit-wrap env
             (comp/emits (comp/munge info))))))))
-
-(defmethod comp/emit* :var [expr] (shadow-emit-var expr))
-(defmethod comp/emit* :binding [expr] (shadow-emit-var expr))
-(defmethod comp/emit* :js-var [expr] (shadow-emit-var expr))
-(defmethod comp/emit* :local [expr] (shadow-emit-var expr))

 ;; noop
 (defn shadow-load-core [])
@@ -977,48 +969,6 @@
            (.replace \/ \$))
        "$"))

-(defmethod comp/emit* :invoke
-  [{f :fn :keys [invoke-type args env] :as expr}]
-  (comp/emit-wrap env
-    (case invoke-type
-      :opt-not
-      (comp/emits "(!(" (first args) "))")
-
-      :opt-count
-      (comp/emits "((" (first args) ").length)")
-
-      :protocol
-      (let [protocol-name (:protocol-name expr)
-            protocol-fn (:protocol-fn expr)
-            pimpl (str (munge (protocol-prefix protocol-name))
-                       (munge (name protocol-fn))
-                       "$arity$" (count args))]
-        (comp/emits (first args) "." pimpl "(" (comma-sep (cons "null" (rest args))) ")"))
-
-      :variadic-invoke
-      (let [mfa (:max-fixed-arity expr)]
-        (comp/emits f ".cljs$core$IFn$_invoke$arity$variadic(" (comma-sep (take mfa args))
-          (when-not (zero? mfa) ",")
-          "cljs.core.prim_seq.cljs$core$IFn$_invoke$arity$2(["
-          (comma-sep (drop mfa args)) "], 0))"))
-
-      :ifn
-      (comp/emits f ".cljs$core$IFn$_invoke$arity$" (count args) "(" (comma-sep args) ")")
-
-      :fn
-      (comp/emits f "(" (comma-sep args) ")")
-
-      :maybe-ifn
-      (let [fprop (str ".cljs$core$IFn$_invoke$arity$" (count args))]
-        (if ana/*fn-invoke-direct*
-          (comp/emits "(" f fprop " ? " f fprop "(" (comma-sep args) ") : "
-            f "(" (comma-sep args) "))")
-          (comp/emits "(" f fprop " ? " f fprop "(" (comma-sep args) ") : "
-            f ".call(" (comma-sep (cons "null" args)) "))")))
-
-      :dot-call
-      (comp/emits f ".call(" (comma-sep (cons "null" args)) ")"))))
-
 ;; fixes an issue where the cljs.core variant assumes that `resolve-var` will only return
 ;; a js/foo symbol if x is also js/something which isn't true in many cases for shadow-cljs
 ;; where npm deps especially resolve some/foo to js/module$something.foo
@@ -1045,6 +995,78 @@
           (vary-meta assoc :tag 'boolean)))
     `(some? ~x)))

+
+;; private is just annoying, get rid of that
+;; we need access to these below
+
+(alter-meta! #'cljs.core/to-property dissoc :private)
+(alter-meta! #'cljs.core/ifn-invoke-methods dissoc :private)
+(alter-meta! #'cljs.core/adapt-obj-params dissoc :private)
+
+
+;; multimethod in core, although I don't see how this is ever going to go past 2 impls?
+;; also added the metadata for easier externs inference
+;; switched .. to nested . since .. looses form meta
+
+(defn shadow-extend-prefix [tsym sym]
+  (let [prop-sym (core/to-property sym)]
+    (case (-> tsym meta :extend)
+      :instance
+      `(. ~tsym ~prop-sym)
+      ;; :default
+      `(. (. ~tsym ~'-prototype) ~prop-sym))))
+
+(defn shadow-add-obj-methods [type type-sym sigs]
+  (map (fn [[f & meths :as form]]
+         (let [[f meths] (if (vector? (first meths))
+                                [f [(rest form)]]
+                                [f meths])]
+           `(set! ~(with-meta
+                     (shadow-extend-prefix type-sym f)
+                     {:shadow/object-fn f})
+              ~(with-meta `(fn ~@(map #(core/adapt-obj-params type %) meths)) (meta form)))))
+    sigs))
+
+;; CLJS-3003
+(defn shadow-add-ifn-methods [type type-sym [f & meths :as form]]
+  (let [this-sym (with-meta 'self__ {:tag type})
+        argsym (gensym "args")
+
+        ;; we are emulating JS .call where the first argument will become this inside the fn
+        ;; but this is not actually what we want when emulating IFn since we need "this"
+        ;; so the first arg is always dropped instead and we dispatch to the actual protocol fns
+        call-fn
+        `(fn [unused#]
+           (core/this-as ~this-sym
+             (case (-> (core/js-arguments) (core/alength) (core/dec))
+               ~@(reduce
+                   (fn [form [args & body]]
+                     (let [arity (-> args (count) (dec))]
+                       (conj
+                         form
+                         arity
+                         (concat
+                           (list
+                             (symbol (str ".cljs$core$IFn$_invoke$arity$" arity))
+                             this-sym)
+                           (for [ar (range arity)]
+                             `(core/aget (core/js-arguments) ~(inc ar)))))))
+                   []
+                   meths)
+               (throw (js/Error. (str "Invalid arity: " (-> (core/js-arguments) (core/alength) (core/dec)))))
+               )))]
+
+    (concat
+      [`(set! ~(shadow-extend-prefix type-sym 'call) ~(with-meta call-fn (meta form)))
+       `(set! ~(shadow-extend-prefix type-sym 'apply)
+          ~(with-meta
+             `(fn ~[this-sym argsym]
+                (core/this-as ~this-sym
+                  (.apply (.-call ~this-sym) ~this-sym
+                    (.concat (core/array ~this-sym) (core/aclone ~argsym)))))
+             (meta form)))]
+      (core/ifn-invoke-methods type type-sym form))))
+
 (defn install-hacks! []
   ;; cljs.analyzer tweaks
   (replace-fn! #'ana/load-core shadow-load-core)
@@ -1060,82 +1082,62 @@

   (replace-fn! #'cljs.core/exists? shadow-exists?)

+  (replace-fn! #'cljs.core/extend-prefix shadow-extend-prefix)
+  (replace-fn! #'cljs.core/add-obj-methods shadow-add-obj-methods)
+  (replace-fn! #'cljs.core/add-ifn-methods shadow-add-ifn-methods)
+
+  (.addMethod comp/emit* :invoke
+    (fn [{f :fn :keys [invoke-type args env] :as expr}]
+      (comp/emit-wrap env
+        (case invoke-type
+          :opt-not
+          (comp/emits "(!(" (first args) "))")
+
+          :opt-count
+          (comp/emits "((" (first args) ").length)")
+
+          :protocol
+          (let [protocol-name (:protocol-name expr)
+                protocol-fn (:protocol-fn expr)
+                pimpl (str (munge (protocol-prefix protocol-name))
+                           (munge (name protocol-fn))
+                           "$arity$" (count args))]
+            (comp/emits (first args) "." pimpl "(" (comma-sep (cons "null" (rest args))) ")"))
+
+          :variadic-invoke
+          (let [mfa (:max-fixed-arity expr)]
+            (comp/emits f ".cljs$core$IFn$_invoke$arity$variadic(" (comma-sep (take mfa args))
+              (when-not (zero? mfa) ",")
+              "cljs.core.prim_seq.cljs$core$IFn$_invoke$arity$2(["
+              (comma-sep (drop mfa args)) "], 0))"))
+
+          :ifn
+          (comp/emits f ".cljs$core$IFn$_invoke$arity$" (count args) "(" (comma-sep args) ")")
+
+          :fn
+          (comp/emits f "(" (comma-sep args) ")")
+
+          :maybe-ifn
+          (let [fprop (str ".cljs$core$IFn$_invoke$arity$" (count args))]
+            (if ana/*fn-invoke-direct*
+              (comp/emits "(" f fprop " ? " f fprop "(" (comma-sep args) ") : "
+                f "(" (comma-sep args) "))")
+              (comp/emits "(" f fprop " ? " f fprop "(" (comma-sep args) ") : "
+                f ".call(" (comma-sep (cons "null" args)) "))")))
+
+          :dot-call
+          (comp/emits f ".call(" (comma-sep (cons "null" args)) ")")))))
+
+  (.addMethod comp/emit* :var (fn [expr] (shadow-emit-var expr)))
+  (.addMethod comp/emit* :binding (fn [expr] (shadow-emit-var expr)))
+  (.addMethod comp/emit* :js-var (fn [expr] (shadow-emit-var expr)))
+  (.addMethod comp/emit* :local (fn [expr] (shadow-emit-var expr)))
+  (.addMethod ana/parse '.
+    (fn
+      [_ env [_ target field & member+ :as form] _ opts]
+      (ana/disallowing-recur (shadow-analyze-dot env target field member+ form opts))))
+
   ;; remove these for now, not worth the trouble
   ;; (replace-fn! #'test/deftest @#'shadow-deftest)
   ;; (replace-fn! #'test/use-fixtures @#'shadow-use-fixtures)
   )
-
-
-(in-ns 'cljs.compiler)
-
-;; FIXME: patch this in CLJS. its the only externs inference call I can't work around
-;; cljs will blindly generate (set! (.. Thing -prototype -something) ...) for
-;; (deftype Thing []
-;;   Object
-;;   (something [...] ...))
-;; but doesn't keep any kind of meta that something is being defined on Object
-;; and that we should generate externs for it
-(in-ns 'cljs.core)
-
-;; multimethod in core, although I don't see how this is ever going to go past 2 impls?
-;; also added the metadata for easier externs inference
-;; switched .. to nested . since .. looses form meta
-(defn- extend-prefix [tsym sym]
-  (let [prop-sym (to-property sym)]
-    (core/case (core/-> tsym meta :extend)
-      :instance
-      `(. ~tsym ~prop-sym)
-      ;; :default
-      `(. (. ~tsym ~'-prototype) ~prop-sym))))
-
-(core/defn- add-obj-methods [type type-sym sigs]
-  (map (core/fn [[f & meths :as form]]
-         (core/let [[f meths] (if (vector? (first meths))
-                                [f [(rest form)]]
-                                [f meths])]
-           `(set! ~(with-meta
-                     (extend-prefix type-sym f)
-                     {:shadow/object-fn f})
-              ~(with-meta `(fn ~@(map #(adapt-obj-params type %) meths)) (meta form)))))
-    sigs))
-
-
-;; CLJS-3003
-(core/defn- add-ifn-methods [type type-sym [f & meths :as form]]
-  (core/let [this-sym (with-meta 'self__ {:tag type})
-             argsym (gensym "args")
-
-             ;; we are emulating JS .call where the first argument will become this inside the fn
-             ;; but this is not actually what we want when emulating IFn since we need "this"
-             ;; so the first arg is always dropped instead and we dispatch to the actual protocol fns
-             call-fn
-             `(fn [unused#]
-                (this-as ~this-sym
-                  (case (-> (js-arguments) (alength) (dec))
-                    ~@(reduce
-                        (core/fn [form [args & body]]
-                          (core/let [arity (core/-> args (count) (core/dec))]
-                            (conj
-                              form
-                              arity
-                              (concat
-                                (core/list
-                                  (symbol (core/str ".cljs$core$IFn$_invoke$arity$" arity))
-                                  this-sym)
-                                (core/for [ar (range arity)]
-                                  `(aget (js-arguments) ~(core/inc ar)))))))
-                        []
-                        meths)
-                    (throw (js/Error. (str "Invalid arity: " (-> (js-arguments) (alength) (dec)))))
-                    )))]
-
-    (concat
-      [`(set! ~(extend-prefix type-sym 'call) ~(with-meta call-fn (meta form)))
-       `(set! ~(extend-prefix type-sym 'apply)
-          ~(with-meta
-             `(fn ~[this-sym argsym]
-                (this-as ~this-sym
-                  (.apply (.-call ~this-sym) ~this-sym
-                    (.concat (array ~this-sym) (cljs.core/aclone ~argsym)))))
-             (meta form)))]
-      (ifn-invoke-methods type type-sym form))))


add with-timeout macro

add with-timeout macro

--- src/open_company/resources/common.clj
+++ src/open_company/resources/common.clj
@@ -2,6 +2,7 @@
   "Resources are any thing stored in the open company platform: companies, reports"
   (:require [clojure.string :as string]
             [clojure.set :as cset]
+            [clojure.core.async :as async]
             [schema.core :as s]
             [clojure.walk :refer (keywordize-keys)]
             [clj-time.format :as format]
@@ -143,6 +144,22 @@
     (select-keys [:avatar :image :user-id :name])
     (clojure.set/rename-keys {:avatar :image})))

+;; ----- Timeouts ----
+
+(def default-timeout 300)
+
+(defmacro with-timeout
+  "A basic macro to wrap things in a timeout.
+  Will throw an exception if the operation times out.
+  Note: This is a simplistic approach and piggiebacks on core.asyncs executor-pool.
+  Read this discussion for more info: https://gist.github.com/martinklepsch/0caf92b5e42eefa3a894"
+  [ms & body]
+  `(let [c# (async/thread-call #(do ~@body))]
+     (let [[v# ch#] (async/alts!! [c# (async/timeout ~ms)])]
+       (if-not (= ch# c#)
+         (throw (ex-info "Operation timed out" {}))
+         v#))))
+
 ;; ----- Resource CRUD funcitons -----

 (defn create-resource
@@ -152,9 +169,10 @@
           :created-at timestamp
           :updated-at timestamp})
         insert (pool/with-pool [conn pool/rethinkdb-pool]
-                 (-> (r/table table-name)
-                     (r/insert timed-resource)
-                     (r/run conn)))]
+                 (with-timeout default-timeout
+                   (-> (r/table table-name)
+                       (r/insert timed-resource)
+                       (r/run conn))))]
   (if (= 1 (:inserted insert))
     timed-resource
     (throw (RuntimeException. (str "RethinkDB insert failure: " insert))))))
@@ -177,22 +195,25 @@
   "
   ([table-name fields]
   (pool/with-pool [conn pool/rethinkdb-pool]
-    (-> (r/table table-name)
-      (r/with-fields fields)
-      (r/run conn))))
+    (with-timeout default-timeout
+      (-> (r/table table-name)
+          (r/with-fields fields)
+          (r/run conn)))))

   ([table-name index-name index-value]
   (pool/with-pool [conn pool/rethinkdb-pool]
-    (-> (r/table table-name)
-      (r/get-all [index-value] {:index index-name})
-      (r/run conn))))
+    (with-timeout default-timeout
+      (-> (r/table table-name)
+          (r/get-all [index-value] {:index index-name})
+          (r/run conn)))))

   ([table-name index-name index-value fields]
   (pool/with-pool [conn pool/rethinkdb-pool]
-    (-> (r/table table-name)
-      (r/get-all [index-value] {:index index-name})
-      (r/pluck fields)
-      (r/run conn)))))
+    (with-timeout default-timeout
+      (-> (r/table table-name)
+          (r/get-all [index-value] {:index index-name})
+          (r/pluck fields)
+          (r/run conn))))))

 (defn update-resource
   "Given a table name, the name of the primary key, and the original and updated resource,
@@ -206,10 +227,11 @@
           :created-at (:created-at original-resource)
           :updated-at timestamp})
         update (pool/with-pool [conn pool/rethinkdb-pool]
-                 (-> (r/table table-name)
-                     (r/get (original-resource primary-key-name))
-                     (r/replace timed-resource)
-                     (r/run conn)))]
+                 (with-timeout default-timeout
+                   (-> (r/table table-name)
+                       (r/get (original-resource primary-key-name))
+                       (r/replace timed-resource)
+                       (r/run conn))))]
   (if (or (= 1 (:replaced update)) (= 1 (:unchanged update)))
     timed-resource
     (throw (RuntimeException. (str "RethinkDB update failure: " update)))))))
@@ -218,20 +240,22 @@
   "Delete the specified resource and return `true`."
   ([table-name primary-key-value]
    (let [delete (pool/with-pool [conn pool/rethinkdb-pool]
-                  (-> (r/table table-name)
-                      (r/get primary-key-value)
-                      (r/delete)
-                      (r/run conn)))]
+                  (with-timeout default-timeout
+                    (-> (r/table table-name)
+                        (r/get primary-key-value)
+                        (r/delete)
+                        (r/run conn))))]
     (if (= 1 (:deleted delete))
       true
       (throw (RuntimeException. (str "RethinkDB delete failure: " delete))))))

   ([table-name key-name key-value]
    (let [delete (pool/with-pool [conn pool/rethinkdb-pool]
-                  (-> (r/table table-name)
-                      (r/get-all [key-value] {:index key-name})
-                      (r/delete)
-                      (r/run conn)))]
+                  (with-timeout default-timeout
+                    (-> (r/table table-name)
+                        (r/get-all [key-value] {:index key-name})
+                        (r/delete)
+                        (r/run conn))))]
      (if (zero? (:errors delete))
       true
       (throw (RuntimeException. (str "RethinkDB delete failure: " delete)))))))
@@ -242,9 +266,10 @@
   "Use with caution! Failure can result in partial deletes of just some resources. Returns `true` if successful."
   [table-name]
   (let [delete (pool/with-pool [conn pool/rethinkdb-pool]
-                 (-> (r/table table-name)
-                     (r/delete)
-                     (r/run conn)))]
+                 (with-timeout default-timeout
+                   (-> (r/table table-name)
+                       (r/delete)
+                       (r/run conn))))]
     (if (pos? (:errors delete))
       (throw (RuntimeException. (str "RethinkDB delete failure: " delete)))
       true)))


SearchResource.clj: handle no results in ATOM feed

--- src/org/altlaw/www/SearchResource.clj
+++ src/org/altlaw/www/SearchResource.clj
@@ -115,30 +115,32 @@
      Language/ENGLISH_US
      CharacterSet/UTF_8)))

-(defmethod render-results MediaType/APPLICATION_ATOM_XML [this variant data]
+(defn prepare-atom-fields [this data]
   (let [ref (.. this getRequest getOriginalRef)
         atom-ref (r/format-ref ref "atom")
         current-page (get-current-page ref)
         last-page (p/calc-last-page (:total_hits data) p/*page-size*)
         next-page (when (< current-page last-page) (inc current-page))
-        prev-page (when (> current-page 1) (dec current-page))
-        data (assoc data
-               :order (order-for-display (:sort data))
-               :timestamp (DateUtils/timestamp)
-               :current_page current-page
-               :page_size p/*page-size*
-               :html_results_url (tmpl/h ref)
-               :atom_results_url (tmpl/h atom-ref)
-               :atom_first_page_url (tmpl/h (r/page-ref atom-ref 1))
-               :atom_last_page_url (tmpl/h (r/page-ref atom-ref last-page))
-               :atom_prev_page_url (when prev-page (tmpl/h (r/page-ref atom-ref prev-page)))
-               :atom_next_page_url (when next-page (tmpl/h (r/page-ref atom-ref next-page)))
-               :atom_id (str "urn:uuid:" (java.util.UUID/randomUUID)))]
-    (StringRepresentation.
-     (tmpl/render "search/atom_results" data)
-     MediaType/APPLICATION_ATOM_XML
-     Language/ENGLISH_US
-     CharacterSet/UTF_8)))
+        prev-page (when (> current-page 1) (dec current-page))]
+    (assoc data
+      :order (order-for-display (:sort data))
+      :timestamp (DateUtils/timestamp)
+      :current_page current-page
+      :page_size p/*page-size*
+      :html_results_url (tmpl/h ref)
+      :atom_results_url (tmpl/h atom-ref)
+      :atom_first_page_url (tmpl/h (r/page-ref atom-ref 1))
+      :atom_last_page_url (tmpl/h (r/page-ref atom-ref last-page))
+      :atom_prev_page_url (when prev-page (tmpl/h (r/page-ref atom-ref prev-page)))
+      :atom_next_page_url (when next-page (tmpl/h (r/page-ref atom-ref next-page)))
+      :atom_id (str "urn:uuid:" (java.util.UUID/randomUUID)))))
+
+(defmethod render-results MediaType/APPLICATION_ATOM_XML [this variant data]
+  (StringRepresentation.
+   (tmpl/render "search/atom_results" (prepare-atom-fields this data))
+   MediaType/APPLICATION_ATOM_XML
+   Language/ENGLISH_US
+   CharacterSet/UTF_8))

 ;;; RENDERING EMPTY RESULT SET
@@ -149,6 +151,14 @@
 (defmethod render-no-results MediaType/TEXT_HTML [this variant prepared]
   (StringRepresentation.
    (tmpl/render "search/html_no_results" prepared)
+   MediaType/TEXT_HTML
+   Language/ENGLISH_US
+   CharacterSet/UTF_8))
+
+(defmethod render-no-results MediaType/APPLICATION_ATOM_XML [this variant prepared]
+  (StringRepresentation.
+   (tmpl/render "search/atom_results"
+                (prepare-atom-fields this prepared))
    MediaType/TEXT_HTML
    Language/ENGLISH_US
    CharacterSet/UTF_8))


Fix issue where process exists before output streams are flushed

--- boot/core/src/boot/main.clj
+++ boot/core/src/boot/main.clj
@@ -90,7 +90,8 @@
 (defn -main [pod-id worker-pod shutdown-hooks [arg0 & args :as args*]]
   (when (not= (boot.App/getVersion) (boot.App/getBootVersion))
     (let [url "https://github.com/boot-clj/boot#install"]
-      (throw (Exception. (str "Please download latest Boot binary: " url)))))
+      (util/exit-error
+        (println (format "Please download latest Boot binary: %s" url)))))

   (reset! pod/pod-id pod-id)
   (reset! pod/worker-pod worker-pod)


Trying out adagrad to some mixed results

--- examples/mnist/src/mnist/next.clj
+++ examples/mnist/src/mnist/next.clj
@@ -31,10 +31,10 @@
 (def hidden-layer-size 30)

-(def n-epochs 1)
-(def learning-rate 0.001)
-(def momentum 0.9)
-(def batch-size 100)
+(def n-epochs 10)
+(def learning-rate 0.01)
+(def momentum 0.1)
+(def batch-size 1)
 (def loss-fn (opt/mse-loss))

 (defn random-matrix
@@ -56,9 +56,11 @@
     (core/stack-module network-modules)))

-(defn create-sgd-optimizer
+(defn create-optimizer
   [network]
-  (opt/sgd-optimiser (core/parameter-count network) {:learn-rate learning-rate :momentum momentum}))
+  (opt/adadelta-optimiser (core/parameter-count network))
+  ;(opt/sgd-optimiser (core/parameter-count network) {:learn-rate learning-rate :momentum momentum} )
+  )

 (defn train-step
@@ -67,7 +69,7 @@
         temp-answer (core/output network)
         loss (cp/loss loss-fn temp-answer answer)
         loss-gradient (cp/loss-gradient loss-fn temp-answer answer)]
-    (core/backward network input loss-gradient)))
+    (core/backward (assoc network :loss loss) input loss-gradient)))

 (defn test-train-step
   []
@@ -79,7 +81,7 @@
                           (train-step input answer network loss-fn))
                         network
                         (map vector input-seq label-seq))
-        batch-scale (/ 1.0 (count input-seq))]
+        batch-scale (/ 10.0 (count input-seq))]
     (m/scale! (core/gradient network) batch-scale)
     (core/optimise optimizer network)))

@@ -87,14 +89,18 @@
 (defn train
   []
   (let [network (create-network)
-        optimizer (create-sgd-optimizer network)
+        optimizer (create-optimizer network)
         epoch-batches (repeatedly n-epochs
                        #(into [] (partition batch-size (shuffle (range (count training-data))))))
         [optimizer network] (reduce (fn [opt-network batch-index-seq]
                                       (reduce (fn [[optimizer network] batch-indexes]
                                                 (let [input-seq (mapv training-data batch-indexes)
-                                                      answer-seq (mapv training-labels batch-indexes)]
-                                                  (train-batch input-seq answer-seq network optimizer loss-fn)))
+                                                      answer-seq (mapv training-labels batch-indexes)
+                                                      [optimizer network] (train-batch input-seq
+                                                                                answer-seq
+                                                                                network optimizer loss-fn)]
+                                                  ;(println "loss after batch:" (:loss network))
+                                                  [optimizer network]))
                                               opt-network
                                               batch-index-seq))
                                     [optimizer network]
@@ -108,11 +114,11 @@
                               (m/emap #(Math/round (double %)) (core/output network))))
                           test-data)
         correct (count (filter #(m/equals (first %) (second %)) (map vector test-results test-labels)))]
-    (/ correct (count test-data))))
+    (double (/ correct (count test-data)))))

 (defn train-and-evaluate
   []
   (let [network (train)
         fraction-correct (evaluate network)]
-    (println (format "Network got %d correct" fraction-correct))))
+    (println (format "Network score: %g" fraction-correct))))


Formatted examples_test.clj by zprint

Formatted examples_test.clj by zprint

--- test/clj_flotr/examples_test.clj
+++ test/clj_flotr/examples_test.clj
@@ -15,26 +15,26 @@
             [clj-flotr.examples :refer :all]))

 (deftest test-line-charts-existence
-    (testing "Test if test-line-charts-function exists"
-        (is (function? test-line-charts))))
+  (testing "Test if test-line-charts-function exists"
+           (is (function? test-line-charts))))

 (deftest test-pie-charts-existence
-    (testing "Test if test-pie-charts-function exists"
-        (is (function? test-pie-charts))))
+  (testing "Test if test-pie-charts-function exists"
+           (is (function? test-pie-charts))))

 (deftest test-stacked-bars-existence
-    (testing "Test if test-stacked-bars-function exists"
-        (is (function? test-stacked-bars))))
+  (testing "Test if test-stacked-bars-function exists"
+           (is (function? test-stacked-bars))))

 (deftest test-line-charts-function
-    (testing "Test the line chart generation"
-        (test-line-charts)))
+  (testing "Test the line chart generation"
+           (test-line-charts)))

 (deftest test-pie-charts-function
-    (testing "Test the pie chart generation"
-        (test-pie-charts)))
+  (testing "Test the pie chart generation"
+           (test-pie-charts)))

 (deftest test-stacked-bars-function
-    (testing "Test the stacked bars generation"
-        (test-stacked-bars)))
+  (testing "Test the stacked bars generation"
+           (test-stacked-bars)))


Improve intermediate test output

Improve intermediate test output

--- test/comic_reader/sites_test.clj
+++ test/comic_reader/sites_test.clj
@@ -17,7 +17,7 @@
      (catch java.lang.RuntimeException re
        nil))

-   (str "Contents of `resources/sites/" site ".clj'"
+   (str "Contents of `resources/sites/" site ".clj' "
         "cannot be empty. It must contain exactly "
         "one map literal.")))

@@ -183,7 +183,7 @@
                              file#)))))

 (defn success-message [message]
-  (println (style (str "\u2713 " message)
+  (println (style (str "\t\u2713 " message)
                   :green))
   true)

@@ -303,6 +303,7 @@

 (defn testdef-form [site-name]
   `(deftest ~(symbol (str site-name "-test"))
+     (println (style ~(str "\n" site-name ":") :yellow))
      (binding [~'site-name ~site-name]
        (and
         (expect-opts-are-map site-name)
@@ -310,11 +311,6 @@
          ((scraper/get-sites) site-name)

          #(and
-           (test-regexes)
-           (test-enlive-selectors)
-           (test-normalize-functions)
-           (test-format-strings)
-
            (if (has-test-folder?)
              (and
               (test-image-page-extraction)
@@ -322,6 +318,11 @@
               (test-extract-comic-list))

              (error-must-have-test-data))
+
+           (test-regexes)
+           (test-enlive-selectors)
+           (test-normalize-functions)
+           (test-format-strings)

            (when (connected-to-network?)
              (test-scrape-urls))))


Fix trailing whitespace

Fix trailing whitespace

--- test/compojure/response_test.clj
+++ test/compojure/response_test.clj
@@ -54,7 +54,7 @@
       (is (nil? (get-in response [:headers "Content-Type"])))
       (is (string? (get-in response [:headers "Last-Modified"])))
       (is (.contains body-str "(ns ring.util.response"))))
-
+
   (testing "with map + metadata"
     (let [response (response/render ^{:has-metadata? true} {:body "foo"} {})]
       (is (= (:body response) "foo"))


upgrade example dependencies

upgrade example dependencies

--- example/project.clj
+++ example/project.clj
@@ -5,7 +5,7 @@
                  [org.slf4j/log4j-over-slf4j "1.6.1"]
                  [ch.qos.logback/logback-classic "0.9.28"]
 		 [compojure "0.6.4"]
-                 [org.signaut/ring.middleware.servlet-ext "0.2"]
+                 [org.signaut/ring.middleware.servlet-ext "0.3"]
 		 [ring/ring-core "0.3.11"]
 		 [ring/ring-servlet "0.3.11"]]
   :dev-dependencies [[swank-clojure "1.2.1"]


Show database changes when editing DB Defn

We just show the  @table-defn-changes  atom

--- idecode/myappshare/mainapp.cljs
+++ idecode/myappshare/mainapp.cljs
@@ -466,6 +466,7 @@
     (get-in @app-state [:ui :editing-database])
     (div nil
          (div nil "Editing database")
+         (pre nil (pr-str @table-defn-changes))
          (button {:style {:margin "10px"}
                  :className (str "btn-lg btn-default" )
                  :aria-hidden "true"


Try to initialize the blockly editor

Try to initialize the blockly editor

ok ok, so the code is in a bit of an unstable state right now....

--- idecode/myappshare/mainapp.cljs
+++ idecode/myappshare/mainapp.cljs
@@ -279,10 +279,6 @@
           (js/initBlockly)
           ))

-   :after-update
-   (js/refreshBlockly)
-
-
    }

@@ -354,6 +350,8 @@
          (textarea {:id "cm" :style {:width "600px" :height "800" :display "inline-block" }} "TEXT EDITOR")

        ))
+
+

@@ -576,7 +574,7 @@
                              :fontFamily "Ubuntu"    :fontSize "1em"       :marginTop "0.3em"
                              :opacity  (if (= (read-ui app [:mode]) "view")  "1.0" "0.4")
                              }
-                     :onClick     #(go (write-ui app [:mode] "edit"))
+                     :onClick     #(go (write-ui app [:mode] "edit") (js/refreshBlockly))
                      :disabled     (if (= (read-ui app [:mode]) "view") "" "true")
                      } "Edit")


[BUG #3083] Added extra delete options to current menu

--- src/status_im/chat/views/actions.cljs
+++ src/status_im/chat/views/actions.cljs
@@ -38,6 +38,15 @@
                  :height 19}
    :handler     #(re-frame/dispatch [:show-profile chat-id])})

+(defn item-delete [chat-id]
+  {:title      (i18n/label :t/delete-chat)
+   :icon       :search_gray_copy
+   :icon-style {:width  17
+                :height 17}
+   ;; TODO(jeluard) Refactor this or Jan will have an heart attack
+   :handler    #(do (re-frame/dispatch [:remove-chat chat-id])
+                    (re-frame/dispatch [:navigation-replace :home]))})
+
 (def item-search
   {:title      (i18n/label :t/search-chat)
    :subtitle   (i18n/label :t/not-implemented)
@@ -73,6 +82,7 @@

 (defn user-chat-items [chat-id]
   [(item-user chat-id)
+   (item-delete chat-id)
    item-search
    item-notifications])


fix #1605 protocol message parser catches all invalid payload as errors

--- src/status_im/protocol/listeners.cljs
+++ src/status_im/protocol/listeners.cljs
@@ -3,28 +3,37 @@
             [status-im.protocol.ack :as ack]
             [status-im.protocol.web3.utils :as u]
             [status-im.protocol.encryption :as e]
-            [taoensso.timbre :refer-macros [debug]]
+            [taoensso.timbre :as log]
             [status-im.utils.hex :as i]))

+(defn create-error [description]
+  (log/debug :parse-payload-error description)
+  {:error description})
+
 (defn- parse-payload [payload]
-  (debug :parse-payload)
+  (log/debug :parse-payload)
   (try
     ;; todo figure why we have to call to-utf8 twice
-    (let [read (comp r/read-string u/to-utf8 u/to-utf8)]
-      {:payload (read payload)})
+    (let [payload'   (u/to-utf8 payload)
+          payload''  (r/read-string payload')
+          payload''' (if (map? payload'')
+                       payload''
+                       (r/read-string (u/to-utf8 payload')))]
+      (if (map? payload''')
+        {:payload payload'''}
+        (create-error (str "Invalid payload type " (type payload''')))))
     (catch :default err
-      (debug :parse-payload-error err)
-      {:error err})))
+      (create-error err))))

 (defn- decrypt [key content]
   (try
     {:content (r/read-string (e/decrypt key content))}
     (catch :default err
-      (debug :decrypt-error err)
+      (log/debug :decrypt-error err)
       {:error err})))

 (defn- parse-content [key {:keys [content]} was-encrypted?]
-  (debug :parse-content
+  (log/debug :parse-content
          "Key exists:" (not (nil? key))
          "Content exists:" (not (nil? content)))
   (if (and (not was-encrypted?) key content)
@@ -36,9 +45,9 @@
   (fn [error js-message]
     ;; todo handle error
     (when error
-      (debug :listener-error error))
+      (log/debug :listener-error error))
     (when-not error
-      (debug :message-received (js->clj js-message))
+      (log/debug :message-received (js->clj js-message))
       (let [{:keys [sig payload recipientPublicKey] :as message}
             (js->clj js-message :keywordize-keys true)

@@ -56,7 +65,7 @@
                                                             (not= "" recipientPublicKey)
                                                             (not (nil? recipientPublicKey))))]
             (if error
-              (debug :failed-to-handle-message error)
+              (log/debug :failed-to-handle-message error)
               (let [payload'' (assoc payload' :content content)
                     message'  (assoc message :payload payload''
                                              :to recipientPublicKey


Removed entity type transfer rules after separating rules to own files

--- resources/rules/post_identifier_merge/ice_to_bio/entity_type_transfer_rules.clj
+++ resources/rules/post_identifier_merge/ice_to_bio/entity_type_transfer_rules.clj
@@ -1,139 +0,0 @@
-;; NEED A COUNT QUERY TO TEST FOR PRESENCE OF ANY OTHER GENE TYPE NAME!!!
-
-
-;; Assigning a sequence type to KABOB_DNA entities denoted by Entrez Gene
-;; identifiers based on the gene type field in the Entrez Gene gene_info file
-;; records
-;;
-;; Gene types and their definitions obtained from:
-;;     http://www.ncbi.nlm.nih.gov/books/NBK3841/#EntrezGene.Properties
-;; Possible gene types include:
-;; miscRNA - Names for the types of molecules encoded by genes follow the
-;;           conventions the collaborating sequence databases
-;;           (DDBJ/EMBL/GenBank); thus miscrna (misc_rna, miscellaneous RNA) is
-;;           assigned to any gene that encodes an RNA product not included in
-;;           the other specifics.
-;; ncRNA (non-coding RNA)
-;; other - applied to loci of known type, but a specific category has not yet
-;;         been applied in the Entrezgene data model (e.g., named fragile sites)
-;; protein-coding
-;; pseudo (pseudogene)
-;; rRNA (ribosomal RNA)
-;; scRNA (small cytoplasmic RNA)
-;; snRNA (small nuclear RNA)
-;; snoRNA (small nucleolar RNA)
-;; tRNA (transfer RNA)
-;; unknown - applied to probable genes for which the type is still under review.
-;;           This category is frequently used when the defining sequence has
-;;           uncertain coding propensity.
-
-
-;;protein-coding maps to SO:0001217 (so:protein_coding_gene)
-`{:name "i2b10-eg-proteincoding-gene-type-assertions"
-  :head ((?/egKabobDna rdfs/subClassOf obo/SO_0001217))
-  :body (;;(_/record kiao/hasTemplate iaoeg/EntrezGeneInfoFileDataSchema1)
-         ~@(kabob/rtv _/record
-                      iaoeg/EntrezGeneInfoFileData_geneIDDataField1 _/egIce
-                      iaoeg/EntrezGeneInfoFileData_typeOfGeneDataField1 "protein-coding")
-         (_/egIce obo/IAO_0000219 ?/egKabobDna))} ; denotes
-
-;; ;; ncRNA maps to SO:0000655 (so:ncRNA)
-;; `{:name "i2b11-eg-ncRNA-gene-type-assertion"
-;;   :head ((?/egKabobDna rdfs/subClassOf obo/S0_0000655))
-;;   :body (;;(_/record kiao/hasTemplate iaoeg/EntrezGeneInfoFileDataSchema1)
-;;          ~@(kabob/rtv _/record
-;;                       iaoeg/EntrezGeneInfoFileData_geneIDDataField1 _/egIce
-;;                       iaoeg/EntrezGeneInfoFileData_typeOfGeneDataField1 "ncRNA")
-;;          (_/egIce obo/IAO_0000219 ?/egKabobDna))}
-
-;; pseudo maps to SO:0000336 (so:pseudogene)
-`{:name "i2b12-eg-pseudo-gene-type-assertion"
-  :head ((?/egKabobDna rdfs/subClassOf obo/S0_0000336))
-  :body (;;(_/record kiao/hasTemplate iaoeg/EntrezGeneInfoFileDataSchema1)
-         ~@(kabob/rtv _/record
-                      iaoeg/EntrezGeneInfoFileData_geneIDDataField1 _/egIce
-                      iaoeg/EntrezGeneInfoFileData_typeOfGeneDataField1 "pseudo")
-         (_/egIce obo/IAO_0000219 ?/egKabobDna))} ; denotes
-
-;; rRNA maps to SO:0000252 (so:rRNA)
-;; `{:name "i2b13-eg-rrna-gene-type-assertion"
-;;   :head ((?/egKabobDna rdfs/subClassOf obo/S0_0000252))
-;;   :body (;;(_/record kiao/hasTemplate iaoeg/EntrezGeneInfoFileDataSchema1)
-;;          ~@(kabob/rtv _/record
-;;                       iaoeg/EntrezGeneInfoFileData_geneIDDataField1 _/egIce
-;;                       iaoeg/EntrezGeneInfoFileData_typeOfGeneDataField1 "rRNA")
-;;          (_/egIce obo/IAO_0000219 ?/egKabobDna))}
-
-;; scRNA maps to SO:0000013 (so:scRNA)
-;; `{:name "i2b14-eg-scrna-gene-type-assertion"
-;;   :head ((?/egKabobDna rdfs/subClassOf obo/S0_0000013))
-;;   :body (;;(_/record kiao/hasTemplate iaoeg/EntrezGeneInfoFileDataSchema1)
-;;          ~@(kabob/rtv _/record
-;;                       iaoeg/EntrezGeneInfoFileData_geneIDDataField1 _/egIce
-;;                       iaoeg/EntrezGeneInfoFileData_typeOfGeneDataField1 "scRNA")
-;;          (_/egIce obo/IAO_0000219 ?/egKabobDna))}
-
-;; ;; snRNA maps to SO:0000274 (so:snRNA)
-;; `{:name "i2b15-eg-snrna-gene-type-assertion"
-;;   :head ((?/egKabobDna rdfs/subClassOf obo/S0_0000274))
-;;   :body (;;(_/record kiao/hasTemplate iaoeg/EntrezGeneInfoFileDataSchema1)
-;;          ~@(kabob/rtv _/record
-;;                       iaoeg/EntrezGeneInfoFileData_geneIDDataField1 _/egIce
-;;                       iaoeg/EntrezGeneInfoFileData_typeOfGeneDataField1 "snRNA")
-;;          (_/egIce obo/IAO_0000219 ?/egKabobDna))}
-
-;; ;; snoRNA maps to SO:0000275 (so:snoRNA)
-;; `{:name "i2b16-eg-snoRNA-gene-type-assertion"
-;;   :head ((?/egKabobDna rdfs/subClassOf obo/S0_0000275))
-;;   :body (;;(_/record kiao/hasTemplate iaoeg/EntrezGeneInfoFileDataSchema1)
-;;          ~@(kabob/rtv _/record
-;;                       iaoeg/EntrezGeneInfoFileData_geneIDDataField1 _/egIce
-;;                       iaoeg/EntrezGeneInfoFileData_typeOfGeneDataField1 "snoRNA")
-;;          (_/egIce obo/IAO_0000219 ?/egKabobDna))}
-
-;; ;; tRNA maps to SO:0000253 (so:tRNA)
-;; `{:name "i2b17-eg-trna-gene-type-assertion"
-;;   :head ((?/egKabobDna rdfs/subClassOf obo/S0_0000253))
-;;   :body (;;(_/record kiao/hasTemplate iaoeg/EntrezGeneInfoFileDataSchema1)
-;;          ~@(kabob/rtv _/record
-;;                        iaoeg/EntrezGeneInfoFileData_geneIDDataField1 _/egIce
-;;                        iaoeg/EntrezGeneInfoFileData_typeOfGeneDataField1 "tRNA")
-;;          (_/egIce obo/IAO_0000219 ?/egKabobDna))}
-
-;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;;; BELOW STILL NEED CLASSIFICATION
-;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-
-;;;;;; unknown maps to kso:DNA_Sequence
-;;`{:name "i2b18-eg-id-unknown-gene-type-assertion"
-;; :head ((?/egKabobDna rdfs/subClassOf obo/))
-;; :body (;;(_/record kiao/hasTemplate iaoeg/EntrezGeneInfoFileDataSchema1)
-;;         ~@(kabob/rtv _/record
-;;                       iaoeg/EntrezGeneInfoFileData_geneIDDataField1 _/egIce
-;;                       iaoeg/EntrezGeneInfoFileData_typeOfGeneDataField1 "unknown")
-;;          (_/egIce obo/IAO_0000219 ?/egKabobDna))}
-;;
-;;;; other maps to kso:DNA_Sequence
-;;`{:name "i2b19-eg-id-other-gene-type-assertion"
-;;  :head ((?/egKabobDna rdfs/subClassOf obo/))
-;;  :body (;;(_/record kiao/hasTemplate iaoeg/EntrezGeneInfoFileDataSchema1)
-;;          ~@(kabob/rtv _/record
-;;                       iaoeg/EntrezGeneInfoFileData_geneIDDataField1 _/egIce
-;;                       iaoeg/EntrezGeneInfoFileData_typeOfGeneDataField1 "other")
-;;          (_/egIce obo/IAO_0000219 ?/egKabobDna))}
-
-;; miscRNA maps to SO: (so:)
-;;`{:name "i2b20-eg-id-miscrna-gene-type-assertion"
-;;  :head ((?/egKabobDna rdfs/subClassOf obo/))
-;;  :body (;;(_/record kiao/hasTemplate iaoeg/EntrezGeneInfoFileDataSchema1)
-;;          ~@(kabob/rtv _/record
-;;                       iaoeg/EntrezGeneInfoFileData_geneIDDataField1 _/egIce
-;;                       iaoeg/EntrezGeneInfoFileData_typeOfGeneDataField1 "miscRNA")
-;;          (_/egIce obo/IAO_0000219 ?/egKabobDna))}
-
-
-
-
-
-


cleanup drawings component and styles

cleanup drawings component and styles

--- frontend/components/drawings.cljs
+++ frontend/components/drawings.cljs
@@ -2,14 +2,7 @@
   (:require [cljs.core.async :as async :refer [>! <! alts! chan sliding-buffer close!]]
             [clojure.string :as str]
             [frontend.async :refer [put!]]
-            [frontend.components.common :as common]
-            [frontend.components.crumbs :as crumbs]
-            [frontend.components.shared :as shared]
-            [frontend.env :as env]
             [frontend.state :as state]
-            [frontend.stefon :as stefon]
-            [frontend.utils :as utils :include-macros true]
-            [frontend.utils.github :refer [auth-url]]
             [om.core :as om :include-macros true]
             [om.dom :as dom :include-macros true]
             [sablono.core :as html :refer-macros [html]])
@@ -39,54 +32,54 @@
                [:line {:x1 "350" :y1 "0" :x2 "350" :y2 "1000"}]
                [:g
                 [:text {:transform "matrix(1 0 0 1 125 505)"} "whoops"]
-                [:path {:d "M321.4,505l-2.7-2.7 M329.4,497l-8,8"}]]
+                [:polyline {:points "318.6,502.3 321.4,505 329.4,497"}]]
                [:g
                 [:text {:transform "matrix(1 0 0 1 125 480)"} "test-notifs"]
-                [:path {:d "M321.4,480l-2.7-2.7 M329.4,472l-8,8"}]]
+                [:polyline {:points "318.6,477.3 321.4,480 329.4,472"}]]
                [:g
                 [:text {:transform "matrix(1 0 0 1 125 455)"} "stability-fixes"]
-                [:path {:d "M321.4,455l-2.7-2.7 M329.4,447l-8,8"}]]
+                [:polyline {:points "318.6,452.3 321.4,455 329.4,447"}]]
                [:g
                 [:text {:transform "matrix(1 0 0 1 125 430)"} "simpler-gh-user"]
-                [:path {:d "M321.4,430l-2.7-2.7 M329.4,422l-8,8"}]]
+                [:polyline {:points "318.6,427.3 321.4,430 329.4,422"}]]
                [:g
                 [:text {:transform "matrix(1 0 0 1 125 330)"} "om-simple-settings"]
-                [:path {:d "M321.4,330l-2.7-2.7 M329.4,322l-8,8"}]]
+                [:polyline {:points "318.6,402.3 321.4,405 329.4,397"}]]
                [:g
                 [:text {:transform "matrix(1 0 0 1 125 405)"} "simple-sidebar-fixer"]
-                [:path {:d "M321.4,405l-2.7-2.7 M329.4,397l-8,8"}]]
+                [:polyline {:points "318.6,352.3 321.4,355 329.4,347"}]]
                [:g
                 [:text {:transform "matrix(1 0 0 1 125 380)"} "simple-sidebar"]
-                [:path.draw-times {:d "M328,380l-8-8 M328,372l-8,8"}]]
+                [:path {:d "M328,380l-8-8 M328,372l-8,8"}]]
                [:g
                 [:text {:transform "matrix(1 0 0 1 125 355)"} "simple-settings"]
-                [:path {:d "M321.4,355l-2.7-2.7 M329.4,347l-8,8"}]]
+                [:polyline {:points "318.6,327.3 321.4,330 329.4,322"}]]
                [:g
                 [:text {:transform "matrix(1 0 0 1 125 305)"} "new-invite-modal"]
-                [:path.draw-times {:d "M328,305l-8-8 M328,297l-8,8"}]]
+                [:path {:d "M328,305l-8-8 M328,297l-8,8"}]]
                [:g
                 [:text {:transform "matrix(1 0 0 1 125 280)"} "master"]
-                [:path {:d "M321.4,280l-2.7-2.7 M329.4,272l-8,8"}]]
+                [:polyline {:points "318.6,277.3 321.4,280 329.4,272"}]]
                [:g
                 [:text {:transform "matrix(1 0 0 1 125 255)"} "design-listing-rewrite"]
-                [:path {:d "M321.4,255l-2.7-2.7 M329.4,247l-8,8"}]]
+                [:polyline {:points "318.6,252.3 321.4,255 329.4,247"}]]
                [:g
                 [:text {:transform "matrix(1 0 0 1 125 230)"} "customer-story-styles"]
-                [:path {:d "M321.4,230l-2.7-2.7 M329.4,222l-8,8"}]]
+                [:polyline {:points "318.6,227.3 321.4,230 329.4,222"}]]
                [:g
                 [:text {:transform "matrix(1 0 0 1 125 205)"} "build-top-queue-fixes"]
-                [:path {:d "M321.4,205l-2.7-2.7 M329.4,197l-8,8"}]]
+                [:polyline {:points "318.6,202.3 321.4,205 329.4,197"}]]
                [:g
                 [:text {:transform "matrix(1 0 0 1 125 180)"} "build-switcher-styles"]
-                [:path.draw-times {:d "M328,180l-8-8 M328,172l-8,8"}]]
+                [:path {:d "M328,180l-8-8 M328,172l-8,8"}]]
                [:g
                 [:text {:transform "matrix(1 0 0 1 125 155)"} "brand-new-nav"]
-                [:path {:d "M321.4,155l-2.7-2.7 M329.4,147l-8,8"}]]
+                [:polyline {:points "318.6,152.3 321.4,155 329.4,147"}]]
                [:g
                 [:text {:transform "matrix(1 0 0 1 125 130)"} "aside-nav-v2"]
-                [:path {:d "M321.4,130l-2.7-2.7 M329.4,122l-8,8"}]]
+                [:polyline {:points "318.6,127.3 321.4,130 329.4,122"}]]
                [:line {:x1 "100" :y1 "100" :x2 "350" :y2 "100"}]
-               [:text.draw-select {:transform "matrix(1 0 0 1 145.3517 55)"} "Your Branch Activity"]])))))
+               [:text {:transform "matrix(1 0 0 1 145.3517 55)"} "Your Branch Activity"]])))))

 (defn draw-main [app owner]
   (reify
@@ -95,13 +88,13 @@
       (let [ab-tests (:ab-tests app)
             controls-ch (om/get-shared owner [:comms :controls])]
         (html [:g.draw-main
-               [:g.draw-th
+               [:g.draw-tr
                 [:line {:x1 "350" :y1 "100" :x2 "1600" :y2 "100"}]
-                [:text {:transform "matrix(1 0 0 1 400 55.0535)"} "Build"]
-                [:text {:transform "matrix(1 0 0 1 637.1372 55)"} "Author"]
-                [:text {:transform "matrix(1 0 0 1 896.2832 55)"} "Log"]
-                [:text {:transform "matrix(1 0 0 1 1331.788 55)"} "Length"]
-                [:text {:transform "matrix(1 0 0 1 1525.047 55)"} "Status"]]
+                [:text.draw-th {:transform "matrix(1 0 0 1 400 55.0535)"} "Build"]
+                [:text.draw-th {:transform "matrix(1 0 0 1 637.1372 55)"} "Author"]
+                [:text.draw-th {:transform "matrix(1 0 0 1 896.2832 55)"} "Log"]
+                [:text.draw-th {:transform "matrix(1 0 0 1 1331.788 55)"} "Length"]
+                [:text.draw-th {:transform "matrix(1 0 0 1 1525.047 55)"} "Status"]]
                [:g.draw-tr
                 [:circle {:cx "1574.5" :cy "125" :r "12.5"}]
                 [:line {:x1 "350" :y1 "150" :x2 "1600" :y2 "150"}]


Adds eqset? building on subset?

Adds eqset? building on subset?

--- src/the_little_clojurian/chapter7.clj
+++ src/the_little_clojurian/chapter7.clj
@@ -38,8 +38,8 @@
   (def subset?
     (fn [set1 set2]
       (cond (null? set1) true
-            (member? (car set1) set2) (subset? (cdr set1) set2)
-            :else false)))
+            :else (and (member? (car set1) set2)
+                       (subset? (cdr set1) set2)))))

   (is (= (subset? '() '()) true))
   (is (= (subset? '(1) '()) false))
@@ -48,3 +48,18 @@
   (is (= (subset? '(5 chicken wings) '(5 hamburgers 2 pieces fried chicken and light duckling wings)) true))
   (is (= (subset? '(4 pounds of horseradish) '(four pounds chicken and 5 ounces horseradish)) false)))

+(with-test
+  (def eqset?
+    (fn [set1 set2]
+      (and (subset? set1 set2)
+           (subset? set2 set1))))
+
+  (is (= (eqset? '() '()) true))
+  (is (= (eqset? '(1) '()) false))
+  (is (= (eqset? '(1) '(1)) true))
+  (is (= (eqset? '(1) '(2)) false))
+  (is (= (eqset? '(1 2) '(1 2)) true))
+  (is (= (eqset? '(1 2) '(2 1)) true))
+  (is (= (eqset? '(1 2 3 4) '(1 2 3 4)) true))
+  (is (= (eqset? '(1 2 3 4) '(4 3 2 1)) true))
+  (is (= (eqset? '(:foo :bar :baz) '(:baz :bar :foo)) true)))


Make startup of a VM simpler

Make startup of a VM simpler

By simplifying the parameters

--- src/webapp/framework/client/main.cljs
+++ src/webapp/framework/client/main.cljs
@@ -83,16 +83,18 @@

-(defn load-vm [cookie-name    cookie-session-id    view-window     dom-element]
+(defn load-vm [cookie-name    view-window     dom-element-name]
   (go
-    (let [create-session-response        (remote !create-session {
-                                                                   :init-state (with-out-str (prn @app-state))
+    (let [ dom-element                    (. js/document (getElementById  dom-element-name))
+           cookie-session-id              (cookie/get  cookie-name)
+           create-session-response        (remote !create-session {
+                                                                    :init-state                 (with-out-str (prn @app-state))

-                                                                   :browser    (str (-> @app-state :system :platform) ","
-                                                                                (-> @app-state :system :who-am-i))
+                                                                    :browser                    (str (-> @app-state :system :platform) ","
+                                                                                (-> @app-state :system :who-am-i))

-                                                                   :session-id-from-browser    cookie-session-id
-                                                                   })  ]
+                                                                    :session-id-from-browser     cookie-session-id
+                                                                    })  ]
       (log (str "cookie-session-id: " cookie-session-id))
       (log (str "create-session-response: " create-session-response))

@@ -112,6 +114,7 @@
       (cookie/set  cookie-name  (:session-id create-session-response))

       (om/root   view-window
+
                  app-state

                  {:target dom-element}))))
@@ -126,9 +129,8 @@
 (defn main []

   (load-vm  (get-cookie-name)
-            (cookie/get  (get-cookie-name))
             main-view
-            (. js/document (getElementById "main"))))
+            "main"))


extracted the duplication in the new fact table dissection facts

--- test/midje/midje_forms/t_dissecting.clj
+++ test/midje/midje_forms/t_dissecting.clj
@@ -62,67 +62,41 @@
 ;;  Fact tables

+(defn check-dissects-fact-table [msg [fact-form & table]]
+  (let [dissected (dissect-fact-table table)
+        expected-fact-form '(fact (+ ?a ?b) => ?result)
+        expected-binding-maps '[ {?a 1, ?b 2, ?result 3} ]
+        expected-map-order '[?a ?b ?result]]
+
+    (facts
+      (:fact-form dissected) => expected-fact-form
+      (:binding-maps dissected) => expected-binding-maps
+      (:map-order dissected) => expected-map-order)))

-(let [simple-fact-table (rest '(tabular
-                                (fact (+ ?a ?b) => ?result)
-                                ?a     ?b      ?result
-                                1      2       3))
-      dissected (dissect-fact-table simple-fact-table)
-      expected-fact-form '(fact (+ ?a ?b) => ?result)
-      expected-binding-maps '[ {?a 1, ?b 2, ?result 3} ]
-      expected-map-order '[?a ?b ?result]]
-
-  (facts
-    (:fact-form dissected) => expected-fact-form
-    (:binding-maps dissected) => expected-binding-maps
-    (:map-order dissected) => expected-map-order))
+(check-dissects-fact-table "basic table"
+  '(tabular
+     (fact (+ ?a ?b) => ?result)
+       ?a     ?b      ?result
+        1      2       3))

+(check-dissects-fact-table "ignores pipes"
+  '(tabular
+     (fact (+ ?a ?b) => ?result)
+       ?a | ?b | ?result
+       1  | 2  | 3))

-(let [fact-table-w-pipes (rest '(tabular
-                                (fact (+ ?a ?b) => ?result)
-                                ?a | ?b | ?result
-                                1  | 2  | 3))
-      dissected (dissect-fact-table fact-table-w-pipes)
-      expected-fact-form '(fact (+ ?a ?b) => ?result)
-      expected-binding-maps '[ {?a 1, ?b 2, ?result 3} ]
-      expected-map-order '[?a ?b ?result]]
-
-  (facts
-    (:fact-form dissected) => expected-fact-form
-    (:binding-maps dissected) => expected-binding-maps
-    (:map-order dissected) => expected-map-order))
+(check-dissects-fact-table "ignores symbol - where"
+  '(tabular
+     (fact (+ ?a ?b) => ?result)

+      where
+       ?a  ?b  ?result
+       1   2   3))

-(let [fact-table-w-kw-where (rest '(tabular
-                                (fact (+ ?a ?b) => ?result)
-
-                                :where
-                                ?a  ?b  ?result
-                                1   2   3))
-      dissected (dissect-fact-table fact-table-w-kw-where)
-      expected-fact-form '(fact (+ ?a ?b) => ?result)
-      expected-binding-maps '[ {?a 1, ?b 2, ?result 3} ]
-      expected-map-order '[?a ?b ?result]]
-
-  (facts
-    (:fact-form dissected) => expected-fact-form
-    (:binding-maps dissected) => expected-binding-maps
-    (:map-order dissected) => expected-map-order))
+(check-dissects-fact-table "ignores keyword - :where"
+  '(tabular
+     (fact (+ ?a ?b) => ?result)

-
-(let [fact-table-w-where (rest '(tabular
-                                (fact (+ ?a ?b) => ?result)
-
-                                where
-                                ?a  ?b  ?result
-                                1   2   3))
-      dissected (dissect-fact-table fact-table-w-where)
-      expected-fact-form '(fact (+ ?a ?b) => ?result)
-      expected-binding-maps '[ {?a 1, ?b 2, ?result 3} ]
-      expected-map-order '[?a ?b ?result]]
-
-  (facts
-    (:fact-form dissected) => expected-fact-form
-    (:binding-maps dissected) => expected-binding-maps
-    (:map-order dissected) => expected-map-order))
-
+      :where
+      ?a  ?b  ?result
+      1   2   3))


Handling - in clojure namespaces correctly now

--- jvm-runner/src/clojure/codewars/util.clj
+++ jvm-runner/src/clojure/codewars/util.clj
@@ -25,6 +25,7 @@
   (let [{:keys [:extension]} (get language-data language)]
     (-> class-name
         name
+        (clojure.string/replace "-" "_")
         ;; TODO: not platform independent...
         (clojure.string/replace "." "/")
         (str "." extension)


CMR-4528: Addressed the PR comment.

CMR-4528: Addressed the PR comment.

--- system-int-test/test/cmr/system_int_test/ingest/deleted_granules_index_test.clj
+++ system-int-test/test/cmr/system_int_test/ingest/deleted_granules_index_test.clj
@@ -117,13 +117,10 @@
         {:revision_date (t/minus- (t/now) (t/days 1))}
         [granule1-prov1 granule2-prov1 granule3-prov1-2 granule4-prov2]))

-    (testing "content-type in search header"
-      (are3 [params]
-        (is (= "application/json; charset=utf-8"
-               (get-in (search/find-deleted-granules params) [:headers :Content-Type])))
-
-        "deleted granule search header contains application/json content-type."
-        {:revision_date (t/minus- (t/now) (t/days 1))}))
+    (testing "Deleted granule search header contains application/json content-type"
+      (let [results (search/find-deleted-granules {:revision_date (t/minus- (t/now) (t/days 1))})]
+        (is (= "application/json; charset=utf-8"
+               (get-in results [:headers :content-type])))))

     (testing "Search for all after date for provider"
       (are3 [params granules]


Add a macro for testing data functions dependencies

--- test/comic_reader/sites/test_util.clj
+++ test/comic_reader/sites/test_util.clj
@@ -2,7 +2,8 @@
   (:require [clojure.test :refer :all]
             [comic-reader.sites :refer :all]
             [clj-http.client :as client]
-            [loom.graph :as graph]))
+            [loom.graph :as graph]
+            [loom.alg :as alg]))

 (defmacro test-data-functions-not-nil []
   `(are [selector] (is (not= (selector)
@@ -88,3 +89,33 @@
    [:manga-url :root-url]
    [:manga-url :manga-url-format]
    ))
+
+(def data-function?
+  #{:root-url
+    :manga-list-format
+    :manga-url-format
+    :manga-pattern-match-portion
+
+    :comic->url-format
+
+    :chapter-list-selector
+    :comic-list-selector
+    :image-selector
+    :page-list-selector
+
+    :chapter-number-pattern
+    :chapter-number-match-pattern
+
+    :link-name-normalize
+    :link-url-normalize
+
+    :page-normalize-format
+    :page-normalize-pattern})
+
+(defmacro ensure-dependencies-defined [fn-name]
+  `(are [selector] (is (not= (selector)
+                             nil))
+     ~@(->> (keyword fn-name)
+            (alg/topsort dependecy-dag)
+            (filter data-function?)
+            (map (comp symbol name)))))


Bugfix for map-keys and map-vals

Bugfix for map-keys and map-vals

These methods simply didn't work, but this wasn't noticed because tests
have not been added yet for the functions imported from think.recommend.

--- cortex/src/cortex/util.cljc
+++ cortex/src/cortex/util.cljc
@@ -113,20 +113,18 @@
 (defn map-keys
   "Applies f to each of the keys of a map, returning a new map."
   [f map]
-  (->> map
-    (reduce-kv (fn [m k v]
-                 (assoc m (f k) v))
-               {}
-               map)))
+  (reduce-kv (fn [m k v]
+               (assoc m (f k) v))
+             {}
+             map))

 (defn map-vals
   "Applies f to each of the values of a map, returning a new map."
   [f map]
-  (->> map
-    (reduce-kv (fn [m k v]
-                 (assoc m k (f v)))
-               {}
-               map)))
+  (reduce-kv (fn [m k v]
+               (assoc m k (f v)))
+             {}
+             map))

 ;;;; Arrays and matrices


clicking on insights go directly to build-timing

--- src-cljs/frontend/components/insights.cljs
+++ src-cljs/frontend/components/insights.cljs
@@ -46,6 +46,10 @@
   (or (#{"success" "failed"} outcome)
       (and (= "canceled" outcome)
            build_time_millis)))
+
+(defn build-timing-url [build]
+  (str (utils/uri-to-relative (unexterned-prop build "build_url"))
+       "#build-timing"))

 (defn visualize-insights-bar! [el builds owner]
   (let [[y-pos-max y-neg-max] (->> [:build_time_millis :queued_time_millis]
@@ -116,7 +120,7 @@
     ;; top bars enter and update
     (-> bars-join
         (.select ".top")
-        (.attr #js {"xlink:href" #(utils/uri-to-relative (unexterned-prop % "build_url"))
+        (.attr #js {"xlink:href" build-timing-url
                     "xlink:title" #(let [duration-str (datetime/as-duration (unexterned-prop % "build_time_millis"))]
                                      (gstring/format "%s in %s"
                                                      (gstring/toTitleCase (unexterned-prop % "outcome"))
@@ -131,7 +135,7 @@
     ;; bottom bar enter and update
     (-> bars-join
         (.select ".bottom")
-        (.attr #js {"xlink:href" #(utils/uri-to-relative (unexterned-prop % "build_url"))
+        (.attr #js {"xlink:href" build-timing-url
                     "xlink:title" #(let [duration-str (datetime/as-duration (unexterned-prop % "queued_time_millis"))]
                                      (gstring/format "Queue time %s" duration-str))})
         (.select "rect.bar")


dynamo; block in creating the migration table

--- joplin.dynamodb/src/joplin/dynamodb/database.clj
+++ joplin.dynamodb/src/joplin/dynamodb/database.clj
@@ -10,7 +10,8 @@
   [client]
   (far/ensure-table client :migrations
                     [:id :s]
-                    {:throughput {:read 1 :write 1}}))
+                    {:throughput {:read 1 :write 1}
+                     :block?     true}))

 ;; ============================================================================
 ;; Ragtime interface


First table of results

First table of results

--- src/angelic/scripts/experiments_11aaai.clj
+++ src/angelic/scripts/experiments_11aaai.clj
@@ -141,15 +141,24 @@
       (assoc e :ms (* 1000 (:last-total-seconds m)) :opt-count (:generated m)))))

+(defn inst-name [m] (str (:objects m) "-" (:rand m)))
 (defn dm-result-map [ds]
   (util/map-vals
    (fn [exps]
      (util/map-vals (fn [es] (assert (= (count es) 1)) ((juxt :secs :opt-count) (first es)))
-                    (group-by :objects exps)))
+                    (group-by inst-name exps)))
    (group-by :alg
-             (datasets/ds-summarize
-              (datasets/ds-derive #(/ (:ms %) 1000) (filter :ms ds) :secs)
-              [:objects :alg] [[:secs util/mean :secs] [:opt-count util/mean :opt-count]]))))
+             (datasets/ds-derive #(/ (:ms %) 1000) (filter :ms ds) :secs)
+
+             #_(datasets/ds-summarize
+                (datasets/ds-derive #(/ (:ms %) 1000) (filter :ms ds) :secs)
+                [:objects :alg] [[:secs util/mean :secs] [:opt-count util/mean :opt-count]]))))
+
+(defn dm-solution-lengths []
+  (into {}
+   (map (juxt inst-name #(count (first (:output %))))
+        (filter #(and (= (:alg %) :dash-a*) (:ms %)) *dm-results*))))
+

 (defn pad-right [x n]
   (let [xs (str x)
@@ -163,18 +172,20 @@

 (defn make-dm-table []
   (let [res (merge (dm-result-map *dm-results*) (dm-result-map (parsed-lama)))
+        lens (dm-solution-lengths)
         algs [:lama :aha* :sahtn :dash-a*]]
-    (print "num")
+    (print "num & len ")
     (doseq [alg algs] (print "&"  alg))
     (println)
-    (doseq [i (range 1 6)]
-      (print (pad-right i 8) "&" )
-      (doseq [alg algs]
-        (let [[secs evals] (get-in res [alg i])]
-          (if secs
-            (print (pad-right (format-n secs 2) 9) "&" (pad-right (format-n evals 0) 9) "&")
-            (print (pad-right "" 9) "&" (pad-right "" 9) "&"))))
-      (println))))
+    (doseq [i (range 1 6) r (range 1 4)]
+      (let [inst (inst-name {:objects i :rand r})]
+       (print (pad-right inst 8) "&" (pad-right (get lens inst) 8) "&")
+       (doseq [alg algs]
+         (let [[secs evals] (get-in res [alg inst])]
+           (if secs
+             (print (pad-right (format-n secs 2) 9) "&" (pad-right (format-n evals 0) 9) "&")
+             (print (pad-right "" 9) "&" (pad-right "" 9) "&"))))
+       (println)))))


Never render the opt in banner now

Never render the opt in banner now

--- src-cljs/frontend/components/app.cljs
+++ src-cljs/frontend/components/app.cljs
@@ -152,10 +152,6 @@
                  ;;     expanding all datastructures.
                  (om/build inspector/inspector app))

-               (when (and (#{:dashboard :account} (:navigation-point app))
-                          (feature/enabled? :ui-v2-opt-in-banner)
-                          (not (feature/enabled-in-cookie? :ui-v2)))
-                 (om/build opt-in/ui-v2-opt-in-banner app))
                (when (and (= :build (:navigation-point app))
                           (project/feature-enabled? project :osx))
              (om/build opt-in/ios-reminder-banner app))


Start refactoring document view for resizable sidebars.

--- src-cljs/pepa/workflows/document.cljs
+++ src-cljs/pepa/workflows/document.cljs
@@ -90,7 +90,7 @@
                          (.preventDefault e))}
         (om/build (:view opts) page {:opts opts})]))))

-(defn ^:private thumbnails [pages owner]
+(defn ^:private thumbnail-list [pages owner]
   (reify
     om/IRenderState
     (render-state [_ {:keys [events current-page]}]
@@ -109,6 +109,17 @@
                        :opts {:enable-rotate? true
                               :view page/thumbnail}})]))))

+(defn ^:private thumbnails [document owner]
+  (reify
+    om/IRenderState
+    (render-state [_ state]
+      (html
+       [:.thumbnails
+        (om/build thumbnail-pane-header document)
+        (om/build thumbnail-list (:pages document)
+                  ;; Just pass down the whole state
+                  {:state state})]))))
+
 (defn ^:private pages-pane-header [document]
   (om/component
    (html
@@ -119,7 +130,7 @@
        [:option "PDF"]
        [:option "Plain Text"]]]])))

-(defn ^:private pages [pages owner]
+(defn ^:private pages-list [pages owner]
   (reify
     om/IRenderState
     (render-state [_ {:keys [events current-page]}]
@@ -130,6 +141,16 @@
                        :init-state {:events events}
                        :state {:current-page current-page}
                        :opts {:view page/full}})]))))
+
+(defn ^:private pages [document owner]
+  (reify
+    om/IRenderState
+    (render-state [_ state]
+      (html
+       [:.full
+        (om/build pages-pane-header document)
+        (om/build pages-list (:pages document)
+                  {:state state})]))))

 (defn ^:private meta-pane [document owner]
   (om/component
@@ -179,8 +200,10 @@
     om/IInitState
     (init-state [_]
       {:page-number 1
-       :thumbnail-width 300
+       :thumbnail-width css/default-sidebar-width
        :sidebar-width css/default-sidebar-width
+       :thumbnail-widths (async/chan (async/sliding-buffer 1))
+       :sidebar-widths (async/chan (async/sliding-buffer 1))
        :sidebar/visible? true
        :pages (async/chan)
        :tag-changes (async/chan)})
@@ -188,15 +211,14 @@
     (will-mount [_]
       ;; Start handling tag change events etc.
       (go-loop []
-        (let [pages (om/get-state owner :pages)
-              tag-changes (om/get-state owner :tag-changes)
-              [event port] (alts! [pages tag-changes])]
+        (let [{:keys [pages tag-changes thumbnail-widths sidebar-widths]} (om/get-state owner)
+              [event port] (alts! [pages tag-changes thumbnail-widths sidebar-widths])]
           (when (and event port)
-            (cond
-              (= port pages)
+            (condp = port
+              pages
               (handle-page-click! @document owner event)

-              (= port tag-changes)
+              tag-changes
               (let [[op tag] event]
                 ;; Deref to get the 'actual' value (might be stale)
                 (-> @document
@@ -204,7 +226,13 @@
                                          :add data/add-tags
                                          :remove data/remove-tags)
                                [tag])
-                    (api/update-document!))))
+                    (api/update-document!)))
+
+              sidebar-widths
+              (println "sidebar" event)
+
+              thumbnail-widths
+              (println "thumbnail" event))
             (recur)))))
     om/IRenderState
     (render-state [_ state]
@@ -219,21 +247,17 @@
         (html
          [:.workflow.document
           [:.pane {:style {:width thumbnail-width}}
-           [:.thumbnails
-            (om/build thumbnail-pane-header document)
-            (om/build thumbnails (:pages document)
-                      {:init-state {:events page-events}
-                       :state {:current-page current-page}})]]
+           (om/build thumbnails document
+                     {:init-state {:events page-events}
+                      :state {:current-page current-page}})]
           [:.pane {:style {:width (str "calc("
                                        "100%"
                                        " - " thumbnail-width "px"
                                        " - " sidebar-width "px"
                                        ")")}}
-           [:.full
-            (om/build pages-pane-header document)
-            (om/build pages (:pages document)
-                      {:state {:current-page current-page
-                               :events page-events}})]]
+           (om/build pages document
+                     {:init-state {:events page-events}
+                      :state {:current-page current-page}})]
           [:.pane {:style {:width sidebar-width}}
            (om/build meta-pane document
                      {:init-state {:tags tag-changes}})]])))))


Don't show add tag button in read-only mode

Closes #184

--- src/braid/core/client/ui/views/thread.cljs
+++ src/braid/core/client/ui/views/thread.cljs
@@ -64,7 +64,8 @@
      (for [tag-id (thread :tag-ids)]
        ^{:key tag-id}
        [tag-mention-view tag-id]))
-   [add-tag-button-view thread]])
+   (when-not (:readonly thread)
+     [add-tag-button-view thread])])

 (defn messages-view [thread-id]
   ; Closing over thread-id, but the only time a thread's id changes is the new


old websocket component removed

old websocket component removed

--- src/clj/hellhound/components/websocket.clj
+++ src/clj/hellhound/components/websocket.clj
@@ -1,81 +0,0 @@
-(ns hellhound.components.websocket
-  "Websocket component is responsible for setting up a sente server
-  for client to connect to. In order to use this component all you
-  have to do is, either use `websocket-server` function with
-  `hellhound.system.defsystem` macro or use the `make-websocket` with a
-  traditional system map."
-  (:require
-   [taoensso.sente.packers.transit          :as packer]
-   [taoensso.sente                          :as sente]
-   [taoensso.sente.server-adapters.immutant :refer [get-sch-adapter]]
-   [hellhound.connection                    :refer [router-builder]]
-   [hellhound.components                    :as components]
-   [hellhound.components.protocols          :as protocols]))
-
-
-;; This component is responsible for establish a websocket server
-;; Base on Sente
-(defrecord WebSocketServer [web-server-adapter handler options adapter]
-  protocols/Lifecycle
-  (start [component]
-    (let [{:keys [ch-recv send-fn ajax-post-fn ajax-get-or-ws-handshake-fn connected-uids]}
-          (sente/make-channel-socket-server! adapter  options) ;;web-server-adapter
-          component (assoc component
-                           :ring-ajax-post                ajax-post-fn
-                           :ring-ajax-get-or-ws-handshake ajax-get-or-ws-handshake-fn
-                           :ch-chsk                       ch-recv
-                           :chsk-send!                    send-fn
-                           :adapter                       adapter
-                           :connected-uids                connected-uids)]
-
-      (assoc component
-             :router (sente/start-chsk-router!
-                      ch-recv (if (:wrap-component? options)
-                                (handler component)
-                                handler)))))
-  (stop [component]
-    (let [router (:router component)]
-      (if-not (nil? router)
-        (do
-          (router)
-          (assoc component :router nil))
-        component))))
-
-
-
-(defn new-channel-socket-server
-  ([web-server-adapter]
-   (new-channel-socket-server nil web-server-adapter {}))
-  ([event-msg-handler web-server-adapter]
-   (new-channel-socket-server event-msg-handler web-server-adapter {}))
-  ([event-msg-handler web-server-adapter options]
-   ;; TODO: Refactor this `let` statement
-   (let [opts (merge {:packer  (packer/->TransitPacker :json {} {})
-                      ;; TODO: Use something elegant instead of the epoch time for uids
-                      :user-id-fn  (fn [_] (str (quot (System/currentTimeMillis) 1000)))}
-                     options)]
-     (map->WebSocketServer {:web-server-adapter web-server-adapter
-                            :handler event-msg-handler
-                            :options opts
-                            :adapter (get-sch-adapter)}))))
-
-
-(defn new-websocket
-  "Creates a websocket component instance."
-  [{:as options :keys [router]}]
-  (new-channel-socket-server (router-builder router) (get-sch-adapter) options))
-
-
-
-(defn make-instance
-  "Create an instance from websocket component. This function is meant
-  to be used with `hellhound.system.defsystem` macro."
-  ([options]
-   (make-instance options {}))
-
-  ([options instance-opt]
-   (let [{:keys [requirements inputs]} instance-opt]
-     {:websocket (components/create-instance
-                  (new-websocket options)
-                  requirements
-                  inputs)})))


Reorganize symbols and change some section name.

--- src/cljs/cljs_repl_web/cljs_api/utils.cljs
+++ src/cljs/cljs_repl_web/cljs_api/utils.cljs
@@ -10,7 +10,7 @@
   {:sections [(Section. "Useful Macros" ""
                         [(Topic. "conditionals"
                                  '(if if-not if-let cond condp and or not when when-let
-                                   when-not case))
+                                      when-not case))
                          (Topic. "nesting, chaining, and interop"
                                  '(-> ->> doto .. .))
                          (Topic. "defining things"
@@ -33,29 +33,29 @@
                                  '("#(<ACTION> |% %2 %3 OR %&|)"))])
               (Section. "Useful Functions" ""
                         [(Topic. "math"
-                                 '(+ - * / quot rem mod inc dec max min))
+                                 '(+ - * / quot rem mod inc dec max min rand))
                          (Topic. "comparison"
                                  '(= == not= < > <= >=))
                          (Topic. "predicates"
                                  '(nil? identical? zero? pos? neg? even? odd? true? false?
-                                   distinct? empty? every? not-every? some not-any?))
-                         (Topic. "data processing"
-                                 '(map map-indexed mapcat reduce filter partition split-at
-                                   split-with))
-                         (Topic. "data create"
-                                 '(vector vec hash-map set for list list* repeat range iterate cycle))
+                                        distinct? empty? every? not-every? some not-any?))
+                         (Topic. "higher-order functions"
+                                 '(map map-indexed mapcat reduce filter partition-by
+                                       take-while keep remove merge-with mapcat iterate repeatedly))
+                         (Topic. "data creation"
+                                 '(vector vec hash-map set for list list* sorted-map
+                                          repeat range cycle))
                          (Topic. "data inspection"
-                                 '(first second last rest get get-in keys vals count nth contains? find
-                                   take take-while ))
+                                 '(first last rest next get get-in count keys
+                                         vals nth contains? find take ))
                          (Topic. "data manipulation"
-                                 '(seq into conj cons assoc assoc-in dissoc zipmap
-                                   merge merge-with select-keys update-in reverse))
-                         (Topic. "function creation"
+                                 '(seq into conj cons assoc flatten merge assoc-in
+                                       dissoc zipmap partition update-in reverse))
+                         (Topic. "functions as data"
                                  '(apply partial comp complement juxt))])
               (Section. "JavaScript Interop" ""
                         [(Topic. "method call" '("(.the-method target-object args...)"))
                          (Topic. "property access" '("(.-property target-object -property)"))
                          (Topic. "property setting" '("(set! (.-title js/document) \"Hi!\")"))
                          (Topic. "direct javascript" '("(js/alert \"Hello world!\")"))
-                         (Topic. "external library use" '("(.text (js/jQuery \"#title\") \"ClojureScript Rocks!\")"))])]
-})
+                         (Topic. "external library use" '("(.text (js/jQuery \"#title\") \"ClojureScript Rocks!\")"))])]})