direct call to -run-queue from resume

direct call to -run-queue from resume

- this now happens in the :running state
  - just like a run-queue, but with an unconditional handling of the
    first item on the queue
- no need to trigger here

--- src/re_frame/router.cljs
+++ src/re_frame/router.cljs
@@ -126,8 +126,8 @@

   (-resume
     [this]
-    (-process-1st-event this)               ;; do the event which paused processing
-    (-fsm-trigger this :finish-resume nil)) ;; do the rest of the queued events
+    (-process-1st-event this) ;; do the event which paused processing
+    (-run-queue this))        ;; do the rest of the queued events

   (-fsm-trigger
     [this trigger arg]


stagger order of languages a bit

stagger order of languages a bit


switch headings with p

switch headings with p

--- frontend/components/pricing-b.cljs
+++ frontend/components/pricing-b.cljs
@@ -43,17 +43,17 @@
             [:div.pricing-calculator-controls
              [:div.controls-containers
               [:h2 "Containers"]
-              [:h5 "All of your containers are shared across your entire organization."]
+              [:p "All of your containers are shared across your entire organization."]
               [:div.containers-range
                [:figure.range-back]
                [:figure.range-highlight]
                [:figure.range-knob]]]
              [:div.controls-parallelism
               [:h2 "Parallelism"]
-              [:h5 "You can run X concurrent builds with X containers and X parallelism. (Adjustable per project.)"]
+              [:p "You can run X concurrent builds with X containers and X parallelism. (Adjustable per project.)"]
               [:div.parallelism-options
                [:button "1x"]
-               [:button "4x"]
+               [:button.active "4x"]
                [:button "8x"]
                [:button "12x"]
                [:button "16x"]]]]
@@ -94,7 +94,7 @@
                  Who cares if the tests pass yet again, you only want notifications when they fail.
                  Circle intelligently notifies you about the tests you care about, and does it over email, Hipchat, Campfire, FlowDock, IRC and webhooks."]]]
            [:article
-            [:h2 "How do containers work?"]
+            [:h3 "How do containers work?"]
             [:p "Every time you push to GitHub, we checkout your code and run your build inside of a container.
                  If you don't have enough free containers available, then your builds queue up until other builds finish."]
             [:p "Everyone gets their first container free and your team can run as many builds as you want with that container.
@@ -102,7 +102,7 @@
             [:p "Parallelism is an extrememly powerful feature and allows to dramitcally speed up your test suite.
                  CircleCI automatically splits your tests across multiple containers, finishing your build in a fraction of the time."]]
            [:article
-            [:h2 "How many containers do I need?"]
+            [:h3 "How many containers do I need?"]
             [:p "Most of our customers use about 2.5 containers per full-time developer.
                  Every team is different however and we're happy to set you up with a trial to help you figure out how many works best for you."]]]]
          (common/footer)]))))


reconnect es after 5 sec in error #165

reconnect es after 5 sec in error
#165

--- src/cljs/swarmpit/event/source.cljs
+++ src/cljs/swarmpit/event/source.cljs
@@ -39,8 +39,11 @@
   (print "Swarmpit event connection has been opened"))

 (defn- on-error!
-  [event]
-  (print "Swarmpit event connection failed. Reconnecting in 5 sec..."))
+  [event error-fx]
+  (when (= (.-readyState @es) 2)
+    (do
+      (print "Swarmpit event connection failed. Reconnecting in 5 sec...")
+      (js/setTimeout #(error-fx) 5000))))

 (defn close!
   []
@@ -56,5 +59,5 @@
                          event-source (js/EventSource. event-url)]
                      (.addEventListener event-source "message" on-message!)
                      (.addEventListener event-source "open" on-open!)
-                     (.addEventListener event-source "error" on-error!)
+                     (.addEventListener event-source "error" (fn [e] (on-error! e init!)))
                      (reset! es event-source)))}))


Removing unnecessary checks in collection matchers.

--- src/cmr/acl/collection_matchers.clj
+++ src/cmr/acl/collection_matchers.clj
@@ -10,11 +10,7 @@
 (defn coll-matches-collection-id?
   "Returns true if the collection matches the collection id"
   [coll collection-id]
-  (let [{:keys [data-set-id short-name version]} collection-id
-        {:keys [entry-title product access-value]} coll]
-    (or (= data-set-id entry-title)
-        (and (= short-name (:short-name product))
-             (= version (:version-id product))))))
+  (= (:data-set-id collection-id) (:entry-title coll)))

 (defn coll-matches-access-value-filter
   "Returns true if the collection matches the access-value filter"


Print dbreset status.

Print dbreset status.

--- spec/tests/eventacts/solid.clj
+++ spec/tests/eventacts/solid.clj
@@ -1,6 +1,5 @@
 (ns tests.eventacts.solid
   (:require [tests.test :refer :all]
-            [clojure.test :as t]
             [clojure.java.shell :refer [sh]]
             [speclj.core :as spec]
             [ombs.dbold :as db]
@@ -9,13 +8,14 @@
             [ombs.core :as core]
             [noir.validation :as vld]
             ))
+
 (def affirmation (vld/wrap-noir-validation dba/affirm))

 (spec/describe "======= Pay button on"

                (spec/before-all
                  (println "############################## RESET DB #######################################")
-                 (sh "bash" "-c" "./resetdb.sh test"))
+                 (println (sh "bash" "-c" "./scripts/resetdb.sh test")))

                (spec/context "solid event(without parts)"
                              (spec/it "is HIDDEN, when user NOT participate event"


cleanup

cleanup

--- src/clojure/zensols/nlparse/feature/lang.clj
+++ src/clojure/zensols/nlparse/feature/lang.clj
@@ -99,7 +99,6 @@
 (defn- dependency-tree-id
   "Get a hash code for the dependency parse tree of sentence **sent**."
   [panon]
-  (reset! x panon)
   (->> panon
        :sents
        (map :dependency-parse-tree)


Simplify example

Simplify example

:sync was a holdover from the core.async support

--- spec/validating.clj
+++ spec/validating.clj
@@ -4,9 +4,8 @@
     [io.aviso.rook.utils :as utils]))

 (defn create
-  {:sync   true
-   :schema {:name                     s/Str
+  {:schema {:name                     s/Str
             (s/optional-key :address) [s/Str]
             (s/optional-key :city)    s/Str}}
-  [^:request-key params]
+  [params]
   (utils/response 200 (-> params keys sort)))


add lexical index fn to prevent overgeneration (i.e. direct objects in non-reflexive contexts, e.g. "io lo parlo"

--- src/babel/italiano/lab.cljc
+++ src/babel/italiano/lab.cljc
@@ -424,6 +424,7 @@
                        (:grammar model))]
            (morph (binding [babel.generate/println? false
                             babel.generate/truncate? true
+                            babel.generate/index-fn (create-index-fn verb-set grammar)
                             babel.generate/grammar grammar]
                     (time (generate chosen-spec model))))))))))


+(defn target-generation)

+(defn target-generation)

--- src/babel/italiano/lab.cljc
+++ src/babel/italiano/lab.cljc
@@ -238,11 +238,26 @@
   (let [generated (generate spec model)]
     (u/get-in generated path ::none)))

+;; to be used within babel.reader/generate-question-and-correct-set:
+(defn target-generation [spec index-fn model]
+  (let [grammar
+        (let [generate-with-grammar-set (grammar/rule-matcher-reducer spec)]
+          (filter (fn [rule-structure]
+                    (contains? generate-with-grammar-set
+                               (u/get-in rule-structure [:rule])))
+                  (:grammar model)))]
+    (morph (binding [babel.generate/println? false
+                     babel.generate/truncate? false
+                     babel.generate/index-fn index-fn
+                     babel.generate/lexical-filter
+                     (fn [lexeme] (= false (u/get-in lexeme [:italiano :exception] false)))
+                     babel.generate/grammar grammar]
+             (time (generate spec model))))))
+
 ;; (take 10 (generate-for-verbcoach))
 (defn generate-for-verbcoach
   "generate sentences efficiently given specific constraints."
   [& [spec]]
-
   (let [example-verbs #{"arrabbiarsi" "chiamarsi" "dormire" "fermarsi" "parlare" "sedersi"}
         create-index-fn
         (fn []
@@ -276,7 +291,6 @@
                  (if (not (= :fail result))
                    result
                    spec))
-
                root-spec
                (let [unif
                      (unify spec
@@ -285,21 +299,8 @@
                  (if (not (= :fail unif))
                    unif
                    spec))
-
                chosen-spec (unify root-spec tense-spec)]
-           (let [generate-with-grammar-set
-                 (grammar/rule-matcher-reducer chosen-spec)
-
-                 grammar
-                 (filter (fn [rule-structure]
-                           (contains? generate-with-grammar-set
-                                      (u/get-in rule-structure [:rule])))
-                         (:grammar model))]
-             (morph (binding [babel.generate/println? false
-                              babel.generate/truncate? false
-                              babel.generate/index-fn (create-index-fn)
-                              babel.generate/lexical-filter
-                              (fn [lexeme] (= false (u/get-in lexeme [:italiano :exception] false)))
-                              babel.generate/grammar grammar]
-                      (time (generate chosen-spec model)))))))))))
-
+           (target-generation chosen-spec (create-index-fn) model)))))))
+
+
+


create table and initialize functions done

--- src/basilisk/db/rethink.clj
+++ src/basilisk/db/rethink.clj
@@ -11,6 +11,8 @@
 ;; Connection atom contains the connection object
 (def connection (atom nil))

+
+;; Public API
 (defn connect
   "Connect ro rethink cluster"
   []
@@ -22,17 +24,26 @@
                         :db   (db))]
     (swap! connection (fn [_] conn))))

+(defn initialize
+  "Initialize the database by creating it and its data structures."
+  []
+  (connect)
+  (r/run (r/db-create (db)) @connection))

 (defn create-table
   "Create a table with given name and specs"
   ([name]
-  (-> (r/table-create name)
-      (r/run @connection)))
+   ;; Query execution
+   (-> (r/db (db))
+       (r/table-create name)
+       (r/run @connection)))

   ([name spec-map]
   (let [index-name (get spec-map :index-name)
         index-fn   (get spec-map :index-fn (fn [row] (r/get-field row index-name)))]
-    (-> (r/table-create name)
+    ;; Query execution
+    (-> (r/db (db))
+        (r/table-create name)
         (when (not (nil? index-name))
           (r/index-create index-name index-fn))
         (r/run @connection)))))


Using empty-env function in rhino repl too

--- src/clj/cljs/repl/rhino.clj
+++ src/clj/cljs/repl/rhino.clj
@@ -93,7 +93,7 @@
           (swap! loaded-libs (partial apply conj) missing)))))

 (defn rhino-setup [repl-env]
-  (let [env {:context :statement :locals {} :ns (@comp/namespaces comp/*cljs-ns*)}
+  (let [env (comp/empty-env)
         scope (:scope repl-env)]
     (repl/load-file repl-env "cljs/core.cljs")
     (swap! loaded-libs conj "cljs.core")


Filter out nils

Filter out nils

--- src/clj/introspect/core.clj
+++ src/clj/introspect/core.clj
@@ -9,6 +9,7 @@
   [types]
   (str "("
        (->> types
+            (filter identity)
             (map #(.getName %))
             (clojure.string/join " -> "))
        ")"))
@@ -47,10 +48,10 @@
             (println call)
             (println (format-signature call))))
         (println "No calls found"))
-      ))
+      )))

-  (Interceptor/setCallback introspect-function)
-  )
+(Interceptor/setCallback introspect-function)
+

 (defonce introspected-namespaces (atom #{}))
 (defn introspect-namespace


dungeon game

dungeon game

--- src/clj/xl/dungeon_game.clj
+++ src/clj/xl/dungeon_game.clj
@@ -38,3 +38,54 @@
 "

 (ns xl.dungeon-game)
+(defn- dp [grid]
+  (let [m (count grid)
+        n (count (first grid))
+        cell (fn [row col] (nth (nth grid row) col))
+        ]
+    (reduce
+      (fn [state [row col]]
+        (let [neg-cell (- (cell row col))
+              val
+              (cond
+                (= col (dec n))
+                  (if (= row (dec m))
+                    (inc neg-cell)
+                    (+ neg-cell (state [(inc row) col]))
+                    )
+                (= row (dec m))
+                  (+ neg-cell (state [row (inc col)]))
+                :else
+                  (+ neg-cell (min (state [(inc row) col]) (state [row (inc col)])))
+                )
+              ]
+              (assoc state [row col] (max 1 val))
+          )
+        )
+      {}
+      (for [row (reverse (range m))
+            col (reverse (range n))]
+        [row col])
+      )
+    )
+  )
+
+(defn min-health [grid]
+  ((dp grid) [0 0])
+  )
+
+(defn- samples []
+  (let [grid
+        [
+         [-2 -3 3]
+         [-5 -10 1]
+         [10 30 -5]
+         ]
+        result (min-health grid)
+        ]
+    (println (str "result is: " result))
+    )
+  )
+
+(samples)
+


Use the correct path for migrators.

Use the correct path for migrators.

--- src/clj_codetip/handler.clj
+++ src/clj_codetip/handler.clj
@@ -90,7 +90,7 @@
     (joplin/migrate-db
      {:db {:type :jdbc
            :url (:connection-uri db-spec)}
-      :migrator "migrators/sql"})
+      :migrator "joplin/migrators/sql"})
     (db/schedule-unexpired-deletes db-spec now)
     (db/delete-expired-pastes! db-spec now)))


search local path for clojurescript namespaces

--- src/clojurescript/core.cljs
+++ src/clojurescript/core.cljs
@@ -198,7 +198,7 @@
   ([] (establish-load-path (js/process.cwd)))
   ([base]
    (aset js/module "paths" (node-module-paths base))
-   (set! *load-paths* (vec (node-module-paths-with-jars base)))))
+   (set! *load-paths* (into [base] (node-module-paths-with-jars base)))))

 ;; TODO not sure if process.cwd is a good default
 (establish-load-path)


Cleaned up for merge to master.

Cleaned up for merge to master.

--- src/clojush/examples/wc.clj
+++ src/clojush/examples/wc.clj
@@ -24,15 +24,6 @@
         clojush.instructions.tag
         clojure.math.numeric-tower
         [clojure.string :only [split trim]]))
-
-; Hand-coded solution for just character count
-#_(run-push '(exec_y (string_readchar file_EOF exec_when exec_pop) string_stackdepth output_charcount)
-          (->> (make-push-state)
-               (push-item nil :auxiliary)
-               (push-item nil :auxiliary)
-               (push-item nil :auxiliary)
-               (push-item "hello\nworld" :auxiliary)
-               (push-item "hello\nworld" :auxiliary)))

 ; Define new instructions
 (define-registered
@@ -118,7 +109,7 @@
         (stack-assoc top-int :auxiliary 4
                      (pop-item :integer state))))))

-; Make atom generators
+; Atom generators
 (def wc-atom-generators
   (list
     (fn [] (- (lrand-int 201) 100))
@@ -252,17 +243,10 @@
                                         (take n-test (shuffle input-set))))))
                           domains)))

-;;WC test data like this:
+;;Can make WC test data like this:
 ;(test-and-train-data-from-domains wc-data-domains)

-;(defn random-wc-inputs
-;  "Returns a list of n random inputs. Each will have size between 0 and 100."
-;  [n]
-;  (let [chars (map char (range 32 127))
-;        max-len 100]
-;    (repeatedly n
-;                (partial wc-input (lrand-int (inc max-len))))))
-
+; Helper functions for error function
 (defn wc-char-count
   "Takes a wc input and returns the char count output"
   [input]
@@ -296,7 +280,7 @@
   [data-domains]
   (let [[train-cases test-cases] (map wc-test-cases
                                       (test-and-train-data-from-domains data-domains))]
-    (when true ;; Change to True to print test cases
+    (when true ;; Change to false to not print test cases
       (doseq [[i [string ch wo li]] (map vector (range) train-cases)]
         (println (str "Train Case " i " | Chars: " ch " Words: " wo " Lines: " li))
         (prn string)


Downgraded Jetty from 6.1.26 to 6.1.25 in reponse to socket issue.

More information here:
https://groups.google.com/forum/#!topic/ring-clojure/z3n6jqO1fdo

--- ring-jetty-adapter/project.clj
+++ ring-jetty-adapter/project.clj
@@ -3,6 +3,6 @@
   :url "http://github.com/mmcgrana/ring"
   :dependencies [[ring/ring-core "0.3.11"]
                  [ring/ring-servlet "0.3.11"]
-                 [org.mortbay.jetty/jetty "6.1.26"]
-                 [org.mortbay.jetty/jetty-util "6.1.26"]]
+                 [org.mortbay.jetty/jetty "6.1.25"]
+                 [org.mortbay.jetty/jetty-util "6.1.25"]]
   :dev-dependencies [[clj-http "0.1.3"]])


removed rich char extractor

removed rich char extractor

--- src/crawler/rich_char_extractor.clj
+++ src/crawler/rich_char_extractor.clj
@@ -109,30 +109,3 @@
        :hrefs hrefs
        :texts texts})
     (:xpath-nav-info content))))
-
-(defn sample-quarter
-  [a-seq]
-  (let [size (count a-seq)]
-    (take (int (/ size 4)) a-seq)))
-
-(defn pagination?
-  "Even 1 pagination is good."
-  [{xpath :xpath hrefs :hrefs texts :texts} body]
-  (let [to-sample (sample-quarter hrefs)
-        page-sims (map
-                   #(similarity/tree-edit-distance-html
-                     body ())
-                   to-sample)]
-
-    (filter #(<= 0.8 %) page-sims)))
-
-(defn detect-pagination
-  "Pagination detection module.
-   First, we kick off from the least useful guys
-   and go to the most useful guys. Along the way,
-   bundle some shit up."
-  [normalized-decision-space body]
-  (let [tree1  (html/html-resource
-                (java.io.StringReader. body))
-        sorted (sort-by :score normalized-decision-space)]
-    (map #(pagination? % tree1) sorted)))


Tests test-send-configuration-xml-to-jenkins-existence, test-get-template-existence

--- test/clj_jenkins_api/jenkins_api_test.clj
+++ test/clj_jenkins_api/jenkins_api_test.clj
@@ -163,6 +163,20 @@
 (deftest test-log-operation-existence
     "Check that the clj-jenkins-api.jenkins-api/log-operation definition exists."
     (testing "if the clj-jenkins-api.jenkins-api/log-operation definition exists."
+        (is (callable? 'clj-jenkins-api.jenkins-api/update-template))))
+
+
+
+(deftest test-send-configuration-xml-to-jenkins-existence
+    "Check that the clj-jenkins-api.jenkins-api/send-configuration-xml-to-jenkins definition exists."
+    (testing "if the clj-jenkins-api.jenkins-api/send-configuration-xml-to-jenkins definition exists."
+        (is (callable? 'clj-jenkins-api.jenkins-api/update-template))))
+
+
+
+(deftest test-get-template-existence
+    "Check that the clj-jenkins-api.jenkins-api/get-template definition exists."
+    (testing "if the clj-jenkins-api.jenkins-api/get-template definition exists."
         (is (callable? 'clj-jenkins-api.jenkins-api/update-template))))


Restore code to configure back button

Restore code to configure back button

--- src/elfeed_cljsrn/android/core.cljs
+++ src/elfeed_cljsrn/android/core.cljs
@@ -10,6 +10,19 @@
 (def icon (r/adapt-react-class MaterialIcons))

 (def codePush (js/require "react-native-code-push"))
+
+(defn go-back! [navigation-state]
+  (if (zero? (:index navigation-state))
+    false
+    (do
+      (dispatch [:nav/pop nil])
+      true)))
+
+(defn listen-back-button! [navigation-state]
+  (.addEventListener (.-BackAndroid rn/ReactNative) "hardwareBackPress" #(go-back! @navigation-state)))
+
+(defn unlisten-back-button! [navigation-state]
+  (.removeEventListener (.-BackAndroid rn/ReactNative) "hardwareBackPress" #(go-back! @navigation-state)))

 (defn format-entry-date [date]
   (let [js-date (js/Date. date)]
@@ -292,7 +305,10 @@
 (defn app-root []
   (let [nav (subscribe [:nav/state])]
     (r/create-class
-     {:component-did-mount #(.sync codePush)
+     {:component-did-mount (fn []
+                             (listen-back-button! nav)
+                             (.sync codePush))
+      :component-will-unmount #(unlisten-back-button! nav)
       :display-name "AppRoot"
       :reagent-render
       (fn []


Add `:clojurize?` option to `info*`

Add `:clojurize?` option to `info*`

--- src/taoensso/carmine.clj
+++ src/taoensso/carmine.clj
@@ -244,12 +244,20 @@

 (defn info*
   "Like `info` but automatically coerces reply into a hash-map."
-  []
+  [& [clojureize?]]
   (->> (info)
-       (parse (fn [reply] (->> reply str/split-lines
-                              (map #(str/split % #":"))
-                              (filter #(= (count %) 2))
-                              (into {}))))))
+       (parse
+        (fn [reply]
+          (let [m (->> reply str/split-lines
+                       (map #(str/split % #":"))
+                       (filter #(= (count %) 2))
+                       (into {}))]
+            (if-not clojureize?
+              m
+              (reduce-kv (fn [m k v] (assoc m (keyword (str/replace k "_" "-")) v))
+                         {} (or m {}))))))))
+
+(comment (wcar {} (info* :clojurize)))

 (defn zinterstore*
   "Like `zinterstore` but automatically counts keys."


Housekeeping, API additions

Housekeeping, API additions

--- src/taoensso/faraday.clj
+++ src/taoensso/faraday.clj
@@ -8,6 +8,7 @@
             [taoensso.faraday.utils :as utils])
   (:import  [com.amazonaws.services.dynamodbv2.model
              AttributeValue
+             AttributeValueUpdate ;;+
              AttributeDefinition
              BatchGetItemRequest
              BatchGetItemResult
@@ -20,8 +21,9 @@
              DescribeTableResult
              DeleteTableRequest
              DeleteItemRequest
+             DeleteItemResult ;;+
              DeleteRequest
-             ExpectedAttributeValue
+             ExpectedAttributeValue ;;++
              GetItemRequest
              GetItemResult
              KeySchemaElement
@@ -31,12 +33,15 @@
              ProvisionedThroughput
              ProvisionedThroughputDescription
              PutItemRequest
+             PutItemResult ;;+
              PutRequest
              QueryRequest
-             QueryResult
+             QueryResult ;;++
              ResourceNotFoundException
              ScanRequest
              ScanResult
+             UpdateItemRequest ;;+
+             UpdateTableRequest ;;+
              WriteRequest]
             com.amazonaws.ClientConfiguration
             com.amazonaws.auth.BasicAWSCredentials
@@ -129,8 +134,7 @@
 (defn- str->num [^String s] (if (.contains s ".") (Double. s) (Long. s)))
 (defn- bb->ba   [^ByteBuffer bb] (.array bb))

-(defn- db-val->clj-val
-  "Returns the Clojure value of given AttributeValue object."
+(defn- db-val->clj-val "Returns the Clojure value of given AttributeValue object."
   [^AttributeValue x]
   (or (.getS x)
       (some->> (.getN  x) str->num)
@@ -147,8 +151,7 @@
                            (instance? Integer x)
                            (instance? Float   x)))

-(defn- clj-val->db-val
-  "Returns an AttributeValue object for given Clojure value."
+(defn- clj-val->db-val "Returns an AttributeValue object for given Clojure value."
   ^AttributeValue [x]
   (cond
    (string? x)
@@ -177,62 +180,70 @@

 ;;;; Coercion - objects

+(defprotocol AsMap (as-map [x]))
+
 (defn- db-map->clj-map [x] (when x (utils/fmap db-val->clj-val (into {} x))))

-(defprotocol AsMap (as-map [x]))
+(defmacro ^:private am-item-result [result get-form]
+  `(when-let [get-form# ~get-form]
+     (with-meta (db-map->clj-map get-form#)
+       {:consumed-capacity (.getConsumedCapacity ~result)})))
+
+(defmacro ^:private am-query|scan-result [result]
+  `(let [result# ~result]
+     {:items (map db-map->clj-map (.getItems result#))
+      :count (.getCount result#)
+      :consumed-capacity (.getConsumedCapacity result#)
+      :last-key (as-map (.getLastEvaluatedKey result#))}))

 (extend-protocol AsMap
-
-  java.util.ArrayList (as-map [alist] (into [] (map as-map alist)))
-  java.util.HashMap   (as-map [hmap] (utils/fmap as-map (into {} hmap)))
-  AttributeValue      (as-map [aval] (db-val->clj-val aval))
-  KeySchemaElement    (as-map [element] {:name (.getAttributeName element)})
-
-  ProvisionedThroughputDescription
-  (as-map [throughput] {:read  (.getReadCapacityUnits throughput)
-                        :write (.getWriteCapacityUnits throughput)
-                        :last-decrease (.getLastDecreaseDateTime throughput)
-                        :last-increase (.getLastIncreaseDateTime throughput)})
-
-  DescribeTableResult
-  (as-map [result] (let [table (.getTable result)]
-                     {:name          (.getTableName table)
-                      :creation-date (.getCreationDateTime table)
-                      :item-count    (.getItemCount table)
-                      :key-schema    (as-map (.getKeySchema table))
-                      :throughput    (as-map (.getProvisionedThroughput table))
-                      :status        (-> (.getTableStatus table)
-                                         (str/lower-case)
-                                         (keyword))}))
-
-  BatchWriteItemResult
-  (as-map [result] {:unprocessed-items (into {} (.getUnprocessedItems result))})
-
+  nil                 (as-map [_] nil)
+  java.util.ArrayList (as-map [a] (into [] (map as-map a)))
+  java.util.HashMap   (as-map [m] (utils/fmap as-map (into {} m)))
+  AttributeValue      (as-map [v] (db-val->clj-val v))
+  KeySchemaElement    (as-map [e] {:name (.getAttributeName e)})
+  GetItemResult       (as-map [r] (am-item-result r (.getItem r)))
+  PutItemResult       (as-map [r] (am-item-result r (.getAttributes r)))
+  DeleteItemResult    (as-map [r] (am-item-result r (.getAttributes r)))
+  QueryResult         (as-map [r] (am-query|scan-result r))
+  ScanResult          (as-map [r] (am-query|scan-result r))
   KeysAndAttributes
   (as-map [result]
     (merge
      (when-let [a (.getAttributesToGet result)] {:attrs (into [] a)})
-     (when-let [c (.getConsistentRead result)]  {:consistent c})
-     (when-let [k (.getKeys result)]            {:keys (utils/fmap as-map (into [] k))})))
+     (when-let [c (.getConsistentRead  result)] {:consistent c})
+     (when-let [k (.getKeys            result)] {:keys (utils/fmap as-map (into [] k))})))
+
+  ;; TODO CreateTableResult, ListTablesResult, UpdateItemResult, UpdateTableResult

   BatchGetItemResult
   (as-map [result]
-    {:responses        (utils/fmap as-map (into {} (.getResponses result)))
-     :unprocessed-keys (utils/fmap as-map (into {} (.getUnprocessedKeys result)))})
-
-  GetItemResult (as-map [result] (db-map->clj-map (.getItem result)))
-
-  QueryResult
-  (as-map [results] {:items    (map db-map->clj-map (.getItems results))
-                     :count    (.getCount results)
-                     :last-key (as-map (.getLastEvaluatedKey results))})
-
-  ScanResult
-  (as-map [results] {:items    (map db-map->clj-map (.getItems results))
-                     :count    (.getCount results)
-                     :last-key (as-map (.getLastEvaluatedKey results))})
-
-  nil (as-map [_] nil))
+    {:responses         (utils/fmap as-map (into {} (.getResponses result)))
+     :unprocessed-keys  (utils/fmap as-map (into {} (.getUnprocessedKeys result)))
+     :consumed-capacity (.getConsumedCapacity result)})
+  BatchWriteItemResult
+  (as-map [result] {:unprocessed-items (into {} (.getUnprocessedItems result))
+                    :consumed-capacity (.getConsumedCapacity result)})
+
+  DescribeTableResult
+  (as-map [result]
+    (let [table (.getTable result)]
+      {:name          (.getTableName table)
+       :creation-date (.getCreationDateTime table)
+       :item-count    (.getItemCount table)
+       :size-bytes    (.getTableSizeBytes table)
+       :key-schema    (as-map (.getKeySchema table))
+       :throughput    (as-map (.getProvisionedThroughput table))
+       ;; :indexes    (as-map (.getLocalSecondaryIndexes table)) ; TODO
+       :status        (-> (.getTableStatus table) (str/lower-case) (keyword))}))
+
+  ;; LocalSecondaryIndexDescription ; TODO
+
+  ProvisionedThroughputDescription
+  (as-map [throughput] {:read          (.getReadCapacityUnits    throughput)
+                        :write         (.getWriteCapacityUnits   throughput)
+                        :last-decrease (.getLastDecreaseDateTime throughput)
+                        :last-increase (.getLastIncreaseDateTime throughput)}))

 ;;;; API - tables

@@ -318,6 +329,8 @@
       .listTables
       .getTableNames
       seq))
+
+;;;; TODO Code walk-through below

 ;;;; API - items


RS & AB | #33 | Fix redundant breaking tests

--- test/objective8/unit/draft_diffs_test.clj
+++ test/objective8/unit/draft_diffs_test.clj
@@ -55,7 +55,7 @@
       (diffs/get-diffs-between-drafts {:content HICCUP_3} {:content HICCUP_2}) => {:previous-draft-diffs FORMATTED_PREVIOUS_DIFF_2_vs_3
                                                                                :current-draft-diffs FORMATTED_CURRENT_DIFF_2_vs_3})

-(fact "Difference between drafts 1 and 2 is returned"
+(future-fact "Difference between drafts 1 and 2 is returned"
       (diffs/get-diffs-between-drafts {:content HICCUP_2} {:content HICCUP_1}) => {:previous-draft-diffs FORMATTED_PREVIOUS_DIFF_1_vs_2
                                                                                :current-draft-diffs FORMATTED_CURRENT_DIFF_1_vs_2})

@@ -63,5 +63,5 @@
       (diffs/get-types-for-hiccup HICCUP_1) => ["p" "li" "li" "li" "p"])

 (fact "Insert diffs into drafts"
-      (diffs/insert-diffs-into-drafts '([:span nil "First paragraph."]) '(["p" {} "First paragraph."])) => '(["p" [:span nil "First paragraph."]])
+      (diffs/insert-diffs-into-drafts '([:span nil "First paragraph."]) '(["p" {} "First paragraph."])) => '(["p" {} [:span nil "First paragraph."]])
       )


Change renaming convention of "!" and "?"

Signed-off-by: Daniel Borchmann <25857343a15bf1edafebc2912e82ecf775c585c1@mailbox.tu-dresden.de>

--- src/conexp/contrib/java.clj
+++ src/conexp/contrib/java.clj
@@ -20,8 +20,8 @@
   (let [new-name (-> (str old-name)
                      (.replaceAll "-" "_")
                      (.replaceAll " " "_")
-                     (.replaceAll "!" "")
-                     (.replaceAll "\\?" "")
+                     (.replaceAll "!" "_f")   ;assume ! only at end
+                     (.replaceAll "\\?" "_p") ;assume ? only at end
                      (.replaceAll "<" "_lt_")
                      (.replaceAll ">" "_gt_")
                      (.replaceAll "=" "_eq_"))]


Use `sut` alias in `c-850-utils.s-100-utils-test`

--- test/com/nomistech/clojure_the_language/c_850_utils/s_100_utils_test.clj
+++ test/com/nomistech/clojure_the_language/c_850_utils/s_100_utils_test.clj
@@ -1,28 +1,28 @@
 (ns com.nomistech.clojure-the-language.c-850-utils.s-100-utils-test
-  (:require [com.nomistech.clojure-the-language.c-850-utils.s-100-utils :refer :all]
+  (:require [com.nomistech.clojure-the-language.c-850-utils.s-100-utils :as sut]
             [midje.sweet :refer :all]))

 ;;;; ___________________________________________________________________________
-;;;; ---- do1 ----
-
-(fact "`do1` works"
+;;;; ---- sut/do1 ----
+
+(fact "`sut/do1` works"

   (fact "Fails to compile when there are no forms"
-    (macroexpand-1 '(do1))
+    (macroexpand-1 '(sut/do1))
     => (throws clojure.lang.ArityException))

   (fact "Returns value of first form when there is one form"
-    (do1 :a)
+    (sut/do1 :a)
     => :a)

   (fact "Returns value of first form when there are two forms"
-    (do1
+    (sut/do1
         :a
       :b)
     => :a)

   (fact "Returns value of first form when there are three forms"
-    (do1
+    (sut/do1
         :a
       :b
       :c)
@@ -30,7 +30,7 @@

   (fact "Forms are evaluated in correct order"
     (let [side-effect-place (atom [])]
-      (do1
+      (sut/do1
           (swap! side-effect-place conj 1)
         (swap! side-effect-place conj 2)
         (swap! side-effect-place conj 3))
@@ -39,26 +39,26 @@
         @side-effect-place => [1 2 3]))))

 ;;;; ___________________________________________________________________________
-;;;; ---- do2 ----
-
-(fact "`do2` works"
+;;;; ---- sut/do2 ----
+
+(fact "`sut/do2` works"

   (fact "Fails to compile when there are no forms"
-    (macroexpand-1 '(do2))
+    (macroexpand-1 '(sut/do2))
     => (throws clojure.lang.ArityException))

   (fact "Fails to compile when there is one forms"
-    (macroexpand-1 '(do2 :a))
+    (macroexpand-1 '(sut/do2 :a))
     => (throws clojure.lang.ArityException))

   (fact "Returns value of second form when there are two forms"
-    (do2
+    (sut/do2
         :a
         :b)
     => :b)

   (fact "Returns value of second form when there are three forms"
-    (do2
+    (sut/do2
         :a
         :b
       :c)
@@ -66,7 +66,7 @@

   (fact "Forms are evaluated in correct order"
     (let [side-effect-place (atom [])]
-      (do2
+      (sut/do2
           (swap! side-effect-place conj 1)
           (swap! side-effect-place conj 2)
         (swap! side-effect-place conj 3))
@@ -75,119 +75,119 @@
         @side-effect-place => [1 2 3]))))

 ;;;; ___________________________________________________________________________
-;;;; ---- econd ----
-
-(fact "`econd` works"
+;;;; ---- sut/econd ----
+
+(fact "`sut/econd` works"
   (fact "no clauses"
-    (econd)
+    (sut/econd)
     => (throws RuntimeException))
   (fact "many clauses"
     (fact "last clause truthy"
-      (econd false 1
-             nil   2
-             :this-one 3)
+      (sut/econd false 1
+                 nil   2
+                 :this-one 3)
       => 3)
     (fact "non-last clause truthy"
-      (econd false 1
-             nil   2
-             :this-one 3
-             :not-this-one 4)
+      (sut/econd false 1
+                 nil   2
+                 :this-one 3
+                 :not-this-one 4)
       => 3)
     (fact "none truthy"
-      (econd false 1
-             nil   2
-             false 3
-             nil   4)
+      (sut/econd false 1
+                 nil   2
+                 false 3
+                 nil   4)
       => (throws RuntimeException))))

 ;;;; ___________________________________________________________________________
-;;;; ---- map-keys ----
-
-(fact "`map-keys`" works
-  (map-keys keyword
-            {"a" 1
-             "b" 2})
+;;;; ---- sut/map-keys ----
+
+(fact "`sut/map-keys`" works
+  (sut/map-keys keyword
+                {"a" 1
+                 "b" 2})
   => {:a 1
       :b 2})

 ;;;; ___________________________________________________________________________
-;;;; ---- map-vals ----
-
-(fact "`map-vals`" works
-  (map-vals inc
-            {:a 1
-             :b 2})
+;;;; ---- sut/map-vals ----
+
+(fact "`sut/map-vals`" works
+  (sut/map-vals inc
+                {:a 1
+                 :b 2})
   => {:a 2
       :b 3})

 ;;;; ___________________________________________________________________________
-;;;; ---- transitive-closure ----
-
-;; TODO: More substantial tests of `transitive-closure`, e.g. edge cases.
-
-(fact "`transitive-closure` works"
-  (transitive-closure (fn [x]
-                        (case x
-                          1 [1 2 3 4]
-                          2 [200 1]
-                          3 [300 1]
-                          4 [1]
-                          []))
-                      1)
+;;;; ---- sut/transitive-closure ----
+
+;; TODO: More substantial tests of `sut/transitive-closure`, e.g. edge cases.
+
+(fact "`sut/transitive-closure` works"
+  (sut/transitive-closure (fn [x]
+                            (case x
+                              1 [1 2 3 4]
+                              2 [200 1]
+                              3 [300 1]
+                              4 [1]
+                              []))
+                          1)
   => #{1 2 3 4 200 300})

 ;;;; ___________________________________________________________________________
-;;;; ---- transitive-closure-excluding-self ----
-
-;; TODO: More substantial tests of `transitive-closure-excluding-self`,
+;;;; ---- sut/transitive-closure-excluding-self ----
+
+;; TODO: More substantial tests of `sut/transitive-closure-excluding-self`,
 ;;       e.g. edge cases.

-(fact "`transitive-closure-excluding-self` works"
-  (transitive-closure-excluding-self (fn [x]
-                                       (case x
-                                         1 [1 2 3 4]
-                                         2 [200 1]
-                                         3 [300 1]
-                                         4 [1]
-                                         []))
-                                     1)
+(fact "`sut/transitive-closure-excluding-self` works"
+  (sut/transitive-closure-excluding-self (fn [x]
+                                           (case x
+                                             1 [1 2 3 4]
+                                             2 [200 1]
+                                             3 [300 1]
+                                             4 [1]
+                                             []))
+                                         1)
   => #{2 3 4 200 300})

 ;;;; ___________________________________________________________________________
-;;;; ---- invert-function invert-relation ----
-
-(fact "`invert-function` works"
-  (invert-function {:a 1
-                    :b 2
-                    :c 3
-                    :d 1}
-                   [:a :b :c :d :e])
+;;;; ---- sut/invert-function sut/invert-relation ----
+
+(fact "`sut/invert-function` works"
+  (sut/invert-function {:a 1
+                        :b 2
+                        :c 3
+                        :d 1}
+                       [:a :b :c :d :e])
   =>
   {1 [:a :d]
    2 [:b]
    3 [:c]})

-(fact "`invert-relation` works"
-  (invert-relation {:a [1 2]
-                    :b [2 3]
-                    :c []
-                    :d [2]}
-                   [:a :b :c :d :e])
+(fact "`sut/invert-relation` works"
+  (sut/invert-relation {:a [1 2]
+                        :b [2 3]
+                        :c []
+                        :d [2]}
+                       [:a :b :c :d :e])
   =>
   {1 [:a]
    2 [:a :b :d]
    3 [:b]})

 ;;;; ___________________________________________________________________________
-;;;; ---- with-extras ----
-
-(fact "`with-extras` works"
+;;;; ---- sut/with-extras ----
+
+(fact "`sut/with-extras` works"

   (fact "without an exception"
     (let [side-effect-place (atom [])]
       (fact "Value is correct"
-        (with-extras [:before (swap! side-effect-place conj 1)
-                      :after  (swap! side-effect-place conj 3)]
+        (sut/with-extras [:before (swap! side-effect-place conj 1)
+                          :after  (swap! side-effect-place conj 3)]
           (do (swap! side-effect-place conj 2)
               :a))
         => :a)
@@ -197,8 +197,8 @@
   (fact "with an exception"
     (let [side-effect-place (atom [])]
       (fact "throws"
-        (with-extras [:before (swap! side-effect-place conj 1)
-                      :after  (swap! side-effect-place conj 3)]
+        (sut/with-extras [:before (swap! side-effect-place conj 1)
+                          :after  (swap! side-effect-place conj 3)]
           (do (/ 0 0)
               (swap! side-effect-place conj 2)
               :a))
@@ -207,93 +207,93 @@
         @side-effect-place => [1 3]))))

 ;;;; ___________________________________________________________________________
-;;;; ---- member? ----
-
-(fact "`member?` works"
+;;;; ---- sut/member? ----
+
+(fact "`sut/member?` works"
   (fact "Returns truthy if the item is in the collection"
-    (member? :b [:a :b :c]) => truthy)
+    (sut/member? :b [:a :b :c]) => truthy)
   (fact "Returns falsey if the item is not in the collection"
-    (member? :d []) => falsey
-    (member? :d [:a :b :c]) => falsey))
-
-;;;; ___________________________________________________________________________
-;;;; ---- submap? ----
-
-(fact "`submap?` works"
-  (do
-    (fact (submap? {}     {}) => true)
-    (fact (submap? {:a 1} {}) => false))
-  (do
-    (fact (submap? {}               {:a 1 :b 2}) => true)
-    (fact (submap? {:a 1}           {:a 1 :b 2}) => true)
-    (fact (submap? {:a 1 :b 2}      {:a 1 :b 2}) => true))
-  (do
-    (fact (submap? {:a 1 :b 2 :c 3} {:a 1 :b 2}) => false)
-    (fact (submap? {:a 9}           {:a 1 :b 2}) => false)
-    (fact (submap? {:a 9 :b 2}      {:a 1 :b 2}) => false)))
-
-(fact "`submap?-v2` works"
-  (do
-    (fact (submap?-v2 {}     {}) => true)
-    (fact (submap?-v2 {:a 1} {}) => false))
-  (do
-    (fact (submap?-v2 {}               {:a 1 :b 2}) => true)
-    (fact (submap?-v2 {:a 1}           {:a 1 :b 2}) => true)
-    (fact (submap?-v2 {:a 1 :b 2}      {:a 1 :b 2}) => true))
-  (do
-    (fact (submap?-v2 {:a 1 :b 2 :c 3} {:a 1 :b 2}) => false)
-    (fact (submap?-v2 {:a 9}           {:a 1 :b 2}) => false)
-    (fact (submap?-v2 {:a 9 :b 2}      {:a 1 :b 2}) => false)))
-
-;;;; ___________________________________________________________________________
-;;;; ---- deep-merge ----
-
-(fact "`deep-merge` works"
+    (sut/member? :d []) => falsey
+    (sut/member? :d [:a :b :c]) => falsey))
+
+;;;; ___________________________________________________________________________
+;;;; ---- sut/submap? ----
+
+(fact "`sut/submap?` works"
+  (do
+    (fact (sut/submap? {}     {}) => true)
+    (fact (sut/submap? {:a 1} {}) => false))
+  (do
+    (fact (sut/submap? {}               {:a 1 :b 2}) => true)
+    (fact (sut/submap? {:a 1}           {:a 1 :b 2}) => true)
+    (fact (sut/submap? {:a 1 :b 2}      {:a 1 :b 2}) => true))
+  (do
+    (fact (sut/submap? {:a 1 :b 2 :c 3} {:a 1 :b 2}) => false)
+    (fact (sut/submap? {:a 9}           {:a 1 :b 2}) => false)
+    (fact (sut/submap? {:a 9 :b 2}      {:a 1 :b 2}) => false)))
+
+(fact "`sut/submap?-v2` works
+  (do
+    (fact (sut/submap?-v2 {}     {}) => true)
+    (fact (sut/submap?-v2 {:a 1} {}) => false))"
+  (do
+    (fact (sut/submap?-v2 {}               {:a 1 :b 2}) => true)
+    (fact (sut/submap?-v2 {:a 1}           {:a 1 :b 2}) => true)
+    (fact (sut/submap?-v2 {:a 1 :b 2}      {:a 1 :b 2}) => true))
+  (do
+    (fact (sut/submap?-v2 {:a 1 :b 2 :c 3} {:a 1 :b 2}) => false)
+    (fact (sut/submap?-v2 {:a 9}           {:a 1 :b 2}) => false)
+    (fact (sut/submap?-v2 {:a 9 :b 2}      {:a 1 :b 2}) => false)))
+
+;;;; ___________________________________________________________________________
+;;;; ---- sut/deep-merge ----
+
+(fact "`sut/deep-merge` works"

   (fact "non-conflicting merge"
-    (deep-merge {:a 1
-                 :b 2}
-                {:c 3})
+    (sut/deep-merge {:a 1
+                     :b 2}
+                    {:c 3})
     => {:a 1
         :b 2
         :c 3})

   (fact "replacing merge"
-    (deep-merge {:a 1
-                 :b {:bb 22}}
-                {:b 999})
+    (sut/deep-merge {:a 1
+                     :b {:bb 22}}
+                    {:b 999})
     => {:a 1
         :b 999})

   (fact "deep merge"
-    (deep-merge {:a 1
-                 :b {:bb 22}}
-                {:b {:ba 21
-                     :bb 999}})
+    (sut/deep-merge {:a 1
+                     :b {:bb 22}}
+                    {:b {:ba 21
+                         :bb 999}})
     => {:a 1
         :b {:ba 21
             :bb 999}})

   (fact "merge in an empty map"
-    (deep-merge {:a 1 :b {:bb 22}}
-                {:b {}})
+    (sut/deep-merge {:a 1 :b {:bb 22}}
+                    {:b {}})
     => {:a 1 :b {:bb 22}})

   (fact "merge in nil"
-    (deep-merge {:a 1 :b {:bb 22}}
-                {:b nil})
+    (sut/deep-merge {:a 1 :b {:bb 22}}
+                    {:b nil})
     => {:a 1 :b nil})

   (fact "merge multiple maps"
-    (deep-merge {:a 1 :b 2 :c 3}
-                {:a 11 :b 12}
-                {:a 101})
+    (sut/deep-merge {:a 1 :b 2 :c 3}
+                    {:a 11 :b 12}
+                    {:a 101})
     => {:a 101 :b 12 :c 3}))

 ;;;; ___________________________________________________________________________
-;;;; ---- select-keys-recursively ----
-
-(fact "`select-keys-recursively` works"
+;;;; ---- sut/select-keys-recursively ----
+
+(fact "`sut/select-keys-recursively` works"

   (let [m {:k-1 "v-1"
            :k-2 {:k-2-1 "v-2-1"
@@ -303,24 +303,24 @@
            :k-3 "v-3"}]

     (fact
-      (select-keys-recursively m [])
+      (sut/select-keys-recursively m [])
       => {})

     (fact
-      (select-keys-recursively m [[]])
+      (sut/select-keys-recursively m [[]])
       => (throws))

     (fact
-      (select-keys-recursively m [[:no-such-key]])
+      (sut/select-keys-recursively m [[:no-such-key]])
       => {})

     (fact
-      (select-keys-recursively m [[:k-1]])
+      (sut/select-keys-recursively m [[:k-1]])
       => {:k-1 "v-1"})

     (fact
-      (select-keys-recursively m [[:k-1]
-                                  [:k-2]])
+      (sut/select-keys-recursively m [[:k-1]
+                                      [:k-2]])
       => {:k-1 "v-1"
           :k-2 {:k-2-1 "v-2-1"
                 :k-2-2 {:k-2-2-1 "v-2-2-1"
@@ -328,42 +328,42 @@
                         :k-2-2-3 "v-2-2-3"}}})

     (fact
-      (select-keys-recursively m [[:k-1]
-                                  [:k-2 [:k-2-2
-                                         [:k-2-2-1]
-                                         [:k-2-2-3]]]])
+      (sut/select-keys-recursively m [[:k-1]
+                                      [:k-2 [:k-2-2
+                                             [:k-2-2-1]
+                                             [:k-2-2-3]]]])
       => {:k-1 "v-1"
           :k-2 {:k-2-2 {:k-2-2-1 "v-2-2-1"
                         :k-2-2-3 "v-2-2-3"}}})))

 ;;;; ___________________________________________________________________________
-;;;; ---- indexed ----
-
-(fact "`indexed` works"
-  (indexed [:a :b :c :d])
+;;;; ---- sut/indexed ----
+
+(fact "`sut/indexed` works"
+  (sut/indexed [:a :b :c :d])
   => [[0 :a]
       [1 :b]
       [2 :c]
       [3 :d]])

 ;;;; ___________________________________________________________________________
-;;;; ---- position ----
-;;;; ---- positions ----
-
-(fact "`position` and `positions` work"
-  (fact "`position` tests"
-    (position even? []) => nil
-    (position even? [12]) => 0
-    (position even? [11 13 14]) => 2
-    (position even? [11 13 14 14]) => 2)
-  (fact "`positions` tests"
-    (positions even? []) => []
-    (positions even? [12]) => [0]
-    (positions even? [11 13 14]) => [2]
-    (positions even? [11 13 14 14 15]) => [2 3]))
-
-;;;; ___________________________________________________________________________
-;;;; ---- unchunk ----
+;;;; ---- sut/position ----
+;;;; ---- sut/positions ----
+
+(fact "sut/`position` and sut/`positions` work"
+  (fact "`sut/position` tests"
+    (sut/position even? []) => nil
+    (sut/position even? [12]) => 0
+    (sut/position even? [11 13 14]) => 2
+    (sut/position even? [11 13 14 14]) => 2)
+  (fact "`sut/positions` tests"
+    (sut/positions even? []) => []
+    (sut/positions even? [12]) => [0]
+    (sut/positions even? [11 13 14]) => [2]
+    (sut/positions even? [11 13 14 14 15]) => [2 3]))
+
+;;;; ___________________________________________________________________________
+;;;; ---- sut/unchunk ----

 (defn fun-with-return-args-to-even?-and-identity [fun]
   (let [clj-even?     even?
@@ -381,7 +381,7 @@
        @identity?-acc])))

 (defmacro with-return-args-to-even?-and-identity
-  "Helper for testing `unchunk`.
+  "Helper for testing `sut/unchunk`.
   Execute `body` in a scope that redefines `even?` and `identity to make a note
   of their argument. After executing `body`, return a vector whose first element
   is a sequence of all the arguments passed to `even?` (in successive calls)
@@ -390,7 +390,7 @@
   [& body]
   `(fun-with-return-args-to-even?-and-identity (fn [] ~@body)))

-(fact "`unchunk` works"
+(fact "`sut/unchunk` works"
   (let [my-chunked-seq (range 10)]

     (fact "`my-chunked-seq` is indeed chunked"
@@ -398,39 +398,39 @@
       (fact (chunked-seq? (-> my-chunked-seq rest)) => true)
       (fact (chunked-seq? (-> my-chunked-seq rest rest)) => true))

-    (fact "`(unchunk my-chunked-seq)` is not chunked"
-      (fact (chunked-seq? (unchunk my-chunked-seq)) => false)
-      (fact (chunked-seq? (-> (unchunk my-chunked-seq) rest)) => false)
-      (fact (chunked-seq? (-> (unchunk my-chunked-seq) rest rest)) => false))
-
-    (fact "unchunking a sequence doesn't change its value"
+    (fact "`(sut/unchunk my-chunked-seq)` is not chunked"
+      (fact (chunked-seq? (sut/unchunk my-chunked-seq)) => false)
+      (fact (chunked-seq? (-> (sut/unchunk my-chunked-seq) rest)) => false)
+      (fact (chunked-seq? (-> (sut/unchunk my-chunked-seq) rest rest)) => false))
+
+    (fact "sut/unchunking a sequence doesn't change its value"
       (= my-chunked-seq
-         (unchunk my-chunked-seq))))
+         (sut/unchunk my-chunked-seq))))

   (fact "A more explicit exploration of the values that are realised"
-    (fact "Without `unchunk`, `map` consumes elements we don't ultimately need"
+    (fact "Without `sut/unchunk`, `map` consumes elements we don't ultimately need"
       (with-return-args-to-even?-and-identity
         (every? even?
                 (map identity [2 4 6 7 8 10])))
       =>
       [[2 4 6 7]
        [2 4 6 7 8 10]])
-    (fact "With `unchunk`, `map` only consumes elements we ultimately need"
+    (fact "With `sut/unchunk`, `map` only consumes elements we ultimately need"
       (with-return-args-to-even?-and-identity
         (every? even?
                 (map identity
-                     (unchunk [2 4 6 7 8 10]))))
+                     (sut/unchunk [2 4 6 7 8 10]))))
       =>
       [[2 4 6 7]
        [2 4 6 7]])))

 ;;;; ___________________________________________________________________________
-;;;; ---- last-index-of-char-in-string ----
-
-(fact "`last-index-of-char-in-string` works"
-  (fact (last-index-of-char-in-string \c "") => -1
-    (last-index-of-char-in-string \c "xyz") => -1
-    (last-index-of-char-in-string \c "c") => 0
-    (last-index-of-char-in-string \c "abc") => 2
-    (last-index-of-char-in-string \c "abcde") => 2
-    (last-index-of-char-in-string \c "abcce") => 3))
+;;;; ---- sut/last-index-of-char-in-string ----
+
+(fact "`sut/last-index-of-char-in-string` works"
+  (fact (sut/last-index-of-char-in-string \c "") => -1
+    (sut/last-index-of-char-in-string \c "xyz") => -1
+    (sut/last-index-of-char-in-string \c "c") => 0
+    (sut/last-index-of-char-in-string \c "abc") => 2
+    (sut/last-index-of-char-in-string \c "abcde") => 2
+    (sut/last-index-of-char-in-string \c "abcce") => 3))


More docstring formatting.

More docstring formatting.

--- src/clojure/parkour/mapreduce.clj
+++ src/clojure/parkour/mapreduce.clj
@@ -48,18 +48,17 @@
   [context] (src/reducer src/next-key src/keykeyvals context))

 (defn wrap-sink
-  "Return new tuple sink which wraps keys and values as the types
-`ckey` and `cval` respectively, which should be compatible with the
-key and value type of `sink`.  Where they are not compatible, the type
-of the `sink` will be used instead.  Returns a new tuple sink which
-wraps any sunk keys and values which are not already of the correct
-type then sinks them to `sink`."
+  "Return new tuple sink which wraps keys and values as the types `ckey` and
+`cval` respectively, which should be compatible with the key and value type of
+`sink`.  Where they are not compatible, the type of the `sink` will be used
+instead.  Returns a new tuple sink which wraps any sunk keys and values which
+are not already of the correct type then sinks them to `sink`."
   ([sink] (snk/wrap-sink nil nil sink))
   ([ckey cval sink] (snk/wrap-sink ckey cval sink)))

 (defn sink-as
-  "Return new tuple collection which has values sinked as `kind`,
-which may be one of `:keys`, `:vals`, or `:keyvals`."
+  "Return new tuple collection which has values sinked as `kind`, which may be
+one of `:keys`, `:vals`, or `:keyvals`."
   [kind sink] (vary-meta sink assoc ::snk/tuples-as kind))

 (defn sink
@@ -71,24 +70,23 @@
   (->> Job reflect/type-reflect :members (some #(= 'getInstance (:name %)))))

 (defmacro ^:private make-job
-  "Macro to create a new `Job` instance, using Hadoop version
-appropriate mechanism."
+  "Macro to create a new `Job` instance, using Hadoop version appropriate
+mechanism."
   [& args] `(~(if job-factory-method? `Job/getInstance `Job.) ~@args))

 (defn job
-  "Return new Hadoop `Job` instance, optionally initialized with
-configuration `conf`."
+  "Return new Hadoop `Job` instance, optionally initialized with configuration
+`conf`."
   {:tag `Job}
   ([] (make-job (conf/ig)))
   ([conf] (make-job (conf/clone conf))))

 (defn mapper!
-  "Allocate and return a new parkour mapper class for `job` as
-invoking `var`.  The `var` will be called during task-setup with the
-job Configuration and any provided `args` (which must be
-EDN-serializable).  It should return a function of one argument, which
-will be invoked with the task context, and should perform the desired
-content of the map task."
+  "Allocate and return a new parkour mapper class for `job` as invoking `var`.
+The `var` will be called during task-setup with the job Configuration and any
+provided `args` (which must be EDN-serializable).  It should return a function
+of one argument, which will be invoked with the task context, and should perform
+the desired content of the map task."
   [^Job job var & args]
   (let [i (conf/get-int job "parkour.mapper.next" 0)]
     (conf/assoc! job
@@ -108,29 +106,27 @@
     (Class/forName (format "parkour.hadoop.Reducers$_%d" i))))

 (defn reducer!
-  "Allocate and return a new parkour reducer class for `job` as
-invoking `var`.  The `var` will be called during task-setup with the
-job Configuration and any provided `args` (which must be
-EDN-serializable).  It should return a function of one argument, which
-will be invoked with the task context, and should perform the desired
-content of the reduce task."
+  "Allocate and return a new parkour reducer class for `job` as invoking `var`.
+The `var` will be called during task-setup with the job Configuration and any
+provided `args` (which must be EDN-serializable).  It should return a function
+of one argument, which will be invoked with the task context, and should perform
+the desired content of the reduce task."
   [^Job job var & args]
   (apply reducer!* :reduce job var args))

 (defn combiner!
-  "As per `reducer!`, but allocate and configure for the Hadoop
-combine step, which may impact e.g. output types."
+  "As per `reducer!`, but allocate and configure for the Hadoop combine step,
+which may impact e.g. output types."
   [^Job job var & args]
   (apply reducer!* :combine job var args))

 (defn partitioner!
-  "Allocate and return a new parkour partitioner class for `job` as
-invoking `var`.  The `var` will be called during task-setup with the
-job Configuration and any provided `args` (which must be
-EDN-serializable).  It should return a function of three arguments: a
-map-output key, a map-output value, and an integral reduce-task count.
-That function will called for each map-output tuple, and should return
-an integral value mod the reduce-task count.  Should be
+  "Allocate and return a new parkour partitioner class for `job` as invoking
+`var`.  The `var` will be called during task-setup with the job Configuration
+and any provided `args` (which must be EDN-serializable).  It should return a
+function of three arguments: a map-output key, a map-output value, and an
+integral reduce-task count.  That function will called for each map-output
+tuple, and should return an integral value mod the reduce-task count.  Should be
 primitive-hinted as OOLL."
   [^Job job var & args]
   (conf/assoc! job
@@ -154,7 +150,7 @@
   TaskAttemptID (taid [taid] taid))

 (defn tac
-  "Return a new TaskAttemptContext instance using provided
-configuration `conf` and task attempt ID `taid`."
+  "Return a new TaskAttemptContext instance using provided configuration `conf`
+and task attempt ID `taid`."
   {:tag `TaskAttemptContext}
   [conf id] (tac* (conf/ig conf) (taid id)))


Fixing integration test for legacy routes

--- test/vignette/http/legacy/integration_test.clj
+++ test/vignette/http/legacy/integration_test.clj
@@ -58,7 +58,7 @@
     (let [response (client/get (format "http://localhost:%d/bucket/images/thumb/a/ab/beach.jpg/200px-beach.jpg" default-port) {:as :byte-array :accept "image/webp"})]
       (:status response) => 200
       (get (:headers response) "Surrogate-Key") => "6f13d7df6b332e4945d90bd6785226b535f8b248"
-      (Integer/parseInt (get (:headers response) "Content-Length")) => (roughly 17950 50)
+      (Integer/parseInt (get (:headers response) "Content-Length")) => (roughly 16800 50)
       (get (:headers response) "Connection") => "close"
       (get (:headers response) "Content-Type") => "image/webp"
       (vec (:body response)) => (has-prefix riff-header)


Replace `ensure-path!` by `fs/ensure-dir!`

--- src/great_things_done/platform.cljs
+++ src/great_things_done/platform.cljs
@@ -11,12 +11,6 @@
         home-path (aget js/process.env home-env)
         args      (conj body "/" home-path)]
     (apply str args)))
-
-(defn- ensure-path!
-  "Ensures the path provided as argument is present on disk"
-  [path]
-  (when-not (fs/exists? path)
-    (fs/mkdir path)))

 (defn database-path
   "Return the database path according to the operating system"
@@ -45,19 +39,19 @@
 (defn ensure-database-path!
   "Ensure that `database-path` exists on disk"
   []
-  (ensure-path! (database-path)))
+  (fs/ensure-dir! (database-path)))

 (defn ensure-database-meta-projects-path!
   "Ensure that `database-meta-projects-path` exists on disk"
   []
-  (ensure-path! (database-meta-projects-path)))
+  (fs/ensure-dir! (database-meta-projects-path)))

 (defn ensure-database-projects-path!
   "Ensure that `database-projects-path` exists on disk"
   []
-  (ensure-path! (database-projects-path)))
+  (fs/ensure-dir! (database-projects-path)))

 (defn ensure-config-file!
   "Ensure that the config file exists"
   []
-  (ensure-path! (config-path)))
+  (fs/ensure-dir! (config-path)))


Prevent setting called :profiles

Prevent setting called :profiles

Second half of the fix for #4.

--- src/active/clojure/config.cljc
+++ src/active/clojure/config.cljc
@@ -454,6 +454,7 @@
   - `inherit?` says whether the setting values may be inherited from a surrounding section"
   [key description range & {:keys [inherit?]}]
   {:pre [(string? description)]}
+  (c/assert (not (identical? key :profiles)) "a setting can't be called :profiles")
   (make-setting key
                 description
                 range


Remove old file

Remove old file

--- src/airhead_cljs/core-old.cljs
+++ src/airhead_cljs/core-old.cljs
@@ -1,129 +0,0 @@
-(ns airhead-cljs.core
-  (:require-macros [cljs.core.async.macros :refer [go]])
-  (:require [reagent.core :as r :refer [atom]]
-            [ajax.core :refer [GET POST PUT DELETE]]))
-
-(defn get-json
-  ([url handler] (get-json url handler []))
-  ([url handler params] (GET url {:handler handler
-                                  :params params
-                                  :response-format :json})))
-
-;; -------------------------
-;; Views
-
-(defn track-span [track]
-  [:span (str (track "artist") " - " (track "title"))])
-
-
-(defn stream-section [url]
-  [:div
-   [:audio {:src url :controls "controls"}]])
-
-
-(defn current-track-section []
-  (let [current-track (atom {})
-        reset         #(reset! current-track (% "track"))
-        get-track     #(get-json "/api/queue/current" reset)]
-    (fn []
-      (js/setTimeout get-track 1000)
-      [:div
-       [:strong "Now playing: "]
-       [track-span @current-track]])))
-
-(defn dequeue-button [track]
-  [:input {:type "button" :value "Dequeue"
-           :on-click #(DELETE (str "/api/queue/"
-                                   (track "uuid")))}])
-
-(defn playlist-section []
-  (let [playlist     (atom [])
-        reset        #(reset! playlist (% "items"))
-        get-playlist #(get-json "/api/queue" reset)]
-    (fn []
-      (js/setTimeout get-playlist 1000)
-      [:div
-       [:h2 "Playlist"]
-       [:ul (for [track @playlist]
-              [:li
-               (dequeue-button track)
-               (track-span track)])]])))
-
-(defn enqueue-button [track]
-  [:input {:type "button" :value "Enqueue"
-           :on-click #(PUT (str "/api/queue/"
-                                (track "uuid")))}])
-
-(defn tracks-list [tracks]
-  [:ul (for [track @tracks]
-         [:li
-          [enqueue-button track]
-          [track-span track]])])
-
-(defn post-track [status]
-  ;; TODO: do not use element id
-  (let [form (.getElementById js/document
-                              "upload-form")
-        on-success (fn []
-                     (reset! status "Done!")
-                     (.reset form))
-        on-error #(reset! status "Something went wrong")]
-    (reset! status "Uploading...")
-    (POST "/api/tracks" {:enc-type "multipart/form-data"
-                         :body (js/FormData. form)
-                         :handler on-success
-                         :error-handler on-error})))
-
-(defn upload-section []
-  (let [upload-status (atom "")]
-    (fn []
-      [:div
-       [:h2 "Upload"]
-       [:form {:id "upload-form"}
-        [:input {:type "file"
-                 :name "track"}]
-        [:input {:type "button"
-                 :value "Upload"
-                 :on-click #(post-track upload-status)}]]
-       [:div @upload-status]])))
-
-(defn tracks-section []
-  (let [tracks (atom [])
-        reset-tracks #(reset! tracks (% "items"))
-        get-tracks   #(get-json "/api/tracks"
-                                reset-tracks
-                                {:q %})
-        query  (atom "")
-        reset-query (fn [e]
-                      (reset! query (-> e .-target .-value))
-                      (get-tracks @query))]
-    (get-tracks @query)
-    (fn []
-      [:div
-       [:h2 "Tracks"]
-       [:input {:type "text"
-                :value @query
-                :on-change reset-query}]
-       [tracks-list tracks]])))
-
-(defn home-page []
-  (let [info (atom {})]
-    (get-json "/api/info" #(reset! info %))
-    (fn []
-      [:div
-       [:h1 (@info "name")]
-       [:p  (@info "greet_message")]
-       [stream-section (@info "stream_url")]
-       [current-track-section]
-       [upload-section]
-       [playlist-section]
-       [tracks-section]])))
-
-;; -------------------------
-;; Initialize app
-
-(defn mount-root []
-  (r/render [home-page] (.getElementById js/document "app")))
-
-(defn init! []
-  (mount-root))


Add url to silence Leiningen

Add url to silence Leiningen

--- lein-template/project.clj
+++ lein-template/project.clj
@@ -3,6 +3,7 @@
 ;; We call this project modular to make the invocation: lein new modular appname
 (defproject modular/lein-template "0.6.13"
   :description "Leiningen template for a full-featured component based app using modular extensions."
+  :url "http://modularity.org/"
   :license {:name "The MIT License"
             :url "http://opensource.org/licenses/MIT"}
   :dependencies [[org.clojure/clojure "1.7.0-alpha4"]


Update words.clj

Update words.clj

--- src/iyye/subcon/knowledge/words.clj
+++ src/iyye/subcon/knowledge/words.clj
@@ -57,7 +57,7 @@
   "de-serialize t"
   (let [mykey #(keyword (str %1 %2))
         create-types #(clojure.string/split (t (mykey "Relation-Types-List" %1)) #"_")
-        create-data #(hash-map (keyword (t (mykey "Relation-Data-List1" %1)))
+        create-data #(hash-map (keyword (t (mykey "Relation-Data-List1" %1))) ; Only 2 now
                        (t (mykey "Relation-Data-List2" %1)))
         relations-list
         (loop [rel-vec []
@@ -87,10 +87,10 @@
         relation (->Iyye_Relation action-atom Predicate Types Function PredicateFunction [])]
     relation))

-(def time-start (persistence/current-time-to-string))
+(def time-start (persistence/local-time-to-string))
 (defn get-supertypes [atype]
   "gets types: self, type, immidiate parents"               ; FIXME Yumzia:0 get all parents
-  (if (not (:UNKNOWN atype))
+  (if-not (:UNKNOWN atype)
     (let [rels (:Relations atype)]
       (conj (for [supertype rels :when (:super (:Data supertype))]
               {:Name (:super (:Data supertype)) :Predicate (:Predicate supertype)})
@@ -164,7 +164,7 @@
         builtin (:Builtin (:atom type))]
       (do
         (dosync (alter noun-words #(assoc % uname type)))
-        (if (not builtin)
+        (if-not builtin
           (save-iyye-type-to-db type)
           (save-iyye-builtin-type-to-db type)))))


add new namespaces to leiningen template gen file

--- src/leiningen/new/lein_quick_om.clj
+++ src/leiningen/new/lein_quick_om.clj
@@ -14,6 +14,8 @@
              ["src/{{sanitized}}/core.cljs" (render "core.cljs" data)]
              ["src/{{sanitized}}/devbar.cljs" (render "devbar.cljs" data)]
              ["src/{{sanitized}}/state_viewer.cljs" (render "state_viewer.cljs" data)]
+             ["src/{{sanitized}}/ui.cljs" (render "ui.cljs" data)]
+             ["src/{{sanitized}}/example_components.cljs" (render "example_components.cljs" data)]
              ["project.clj" (render "project.clj" data)]
              ["Dockerfile" (render "Dockerfile" data)]
              ["Makefile" (render "Makefile" data)]


CMR-2201: Change to try to isolate test failure.

--- metadata-db-app/int_test/cmr/metadata_db/int_test/concepts/cleanup_test.clj
+++ metadata-db-app/int_test/cmr/metadata_db/int_test/concepts/cleanup_test.clj
@@ -112,7 +112,11 @@
     (is (= 204 (util/old-revision-concept-cleanup)))

     (is (every? #(revisions-removed? % (range 1 3)) granules))
-    (is (every? #(concept-revision-exists? % 3) [gran1 gran2 gran3 gran4]))
+    ; (is (every? #(concept-revision-exists? % 3) [gran1 gran2 gran3 gran4]))
+    (is (concept-revision-exists? gran1 3))
+    (is (concept-revision-exists? gran2 3))
+    (is (concept-revision-exists? gran3 3))
+    (is (concept-revision-exists? gran4 3))
     (is (concept-revision-exists? gran5 12))))

 (deftest old-service-revisions-are-cleaned-up


Remove scratch queries

Remove scratch queries

--- test/yetibot/core/test/models/history.clj
+++ test/yetibot/core/test/models/history.clj
@@ -15,38 +15,4 @@
      [?i :history/chat-source-room ?chat-source-room ?tx]
      [?i :history/body ?body ?tx]])

-;; command history / example of how to impl grep
-
 (defn is-command? [h] (re-find #"^\!" h))
-
-;; command only
-(q '[:find ?user-id ?body ?txInstant
-     ?chat-source-adapter ?chat-source-room
-     :where
-     [?tx :db/txInstant ?txInstant]
-     [?e :history/user-id ?user-id ?tx]
-     [?e :history/chat-source-adapter ?chat-source-adapter ?tx]
-     [?e :history/chat-source-room ?chat-source-room ?tx]
-     [?e :history/body ?body ?tx]
-     [(yetibot.core.test.models.history/is-command? ?body)] ])
-
-;; matches "history" only
-(q '[:find ?user-id ?body ?txInstant ?chat-source-adapter ?chat-source-room
-     :where
-     [?tx :db/txInstant ?txInstant]
-     [?e :history/user-id ?user-id ?tx]
-     [?e :history/chat-source-adapter ?chat-source-adapter ?tx]
-     [?e :history/chat-source-room ?chat-source-room ?tx]
-     [?e :history/body ?body ?tx]
-     [(re-find #"history" ?body)]])
-
-
-;; matches "history" only
-(q '[:find ?user-id ?body ?txInstant ?chat-source-adapter ?chat-source-room
-     :where
-     [?tx :db/txInstant ?txInstant]
-     [?e :history/user-id ?user-id ?tx]
-     [?e :history/chat-source-adapter ?chat-source-adapter ?tx]
-     [?e :history/chat-source-room ?chat-source-room ?tx]
-     [?e :history/body ?body ?tx]
-     [(re-find #"history" ?body)]])


Use retention instead of period in rollups

--- src/cyanite_remover/cli.clj
+++ src/cyanite_remover/cli.clj
@@ -16,8 +16,12 @@
   [rollups]
   (->> (str/split rollups #",")
        (map #(re-matches #"^((\d+):(\d+))$" %))
-       (map #(if % [(Integer/parseInt (nth % 2))
-                    (Integer/parseInt (nth % 3))] %))))
+       (map #(if %
+               (let [seconds-per-point (Integer/parseInt (nth % 2))
+                     retention (Integer/parseInt (nth % 3))
+                     period (/ retention seconds-per-point)]
+                 [seconds-per-point period])
+               %))))

 (defn- usage
   "Construct usage message."
@@ -25,9 +29,9 @@
   (->> ["A Cyanite data removal tool"
         ""
         "Usage: "
-        "  cyanite-remover [options] remove-metrics <tenant> <rollup:period,...> <path,...> <cassandra_host,...> <elasticsearch_url>"
+        "  cyanite-remover [options] remove-metrics <tenant> <rollup,...> <path,...> <cassandra_host,...> <elasticsearch_url>"
         "  cyanite-remover [options] remove-paths <tenant> <path,...> <elasticsearch_url>"
-        "  cyanite-remover [options] list-metrics <tenant> <rollup:period,...> <path,...> <cassandra_host,...> <elasticsearch_url>"
+        "  cyanite-remover [options] list-metrics <tenant> <rollup,...> <path,...> <cassandra_host,...> <elasticsearch_url>"
         "  cyanite-remover [options] list-paths <tenant> <path,...> <elasticsearch_url>"
         "  cyanite-remover help"
         ""


fix typo

fix typo

--- src/babel/english/grammar.cljc
+++ src/babel/english/grammar.cljc
@@ -187,9 +187,9 @@
                                       comp-type (atom :top)]
                                   {:rule "complementizer-phrase"
                                    :synsem {:cat :comp
-                                            :comp comp-type
+                                            :comp-type comp-type
                                             :sem semantics}
-                                   :head {:synsem {:comp comp-type
+                                   :head {:synsem {:comp-type comp-type
                                                    :sem semantics}}}))
                    (unify-check c10
                            {:rule "determiner-phrase"


+TODO

+TODO

--- src/babel/english/grammar.cljc
+++ src/babel/english/grammar.cljc
@@ -82,6 +82,8 @@
     :first :head
     :comment "c11"}))

+;; TODO: names like "c11-comp-subcat-1" have no human-discernible meaning:
+;; sound like construction droid names or something..
 (def c11-comp-subcat-1
   (let [subcat (atom :top)]
     (unifyc


-sem for {:cat :comp}

-sem for {:cat :comp}

--- src/babel/english/lexicon.cljc
+++ src/babel/english/lexicon.cljc
@@ -2001,7 +2001,6 @@
    "whether"
    {:synsem {:cat :comp
              :comp-type :if
-             :sem {:pred :that}
              :subcat {:1 {:cat :verb
                           :subcat '()}
                       :2 '()}}}


added creer decider desirer donner

added creer decider desirer donner

--- src/babel/francais/lexicon.clj
+++ src/babel/francais/lexicon.clj
@@ -81,7 +81,20 @@
                          :sem {:pred :walk}}}

      "effacer" {:synsem {:cat :verb
-                         :sem {:pred :erase}}}
+                         :sem {:pred :erase}}}
+
+     "créer" {:synsem {:cat :verb
+                         :sem {:pred :believe}}}
+
+     "décider" {:synsem {:cat :verb
+                         :sem {:pred :decide}}}
+
+     "désirer" {:synsem {:cat :verb
+                         :sem {:pred :desire}}}
+
+     "donner" {:synsem {:cat :verb
+                         :sem {:pred :give}}}
+
    "elle"
    [{:synsem {:cat :noun
              :pronoun true


added cambiarsi

added cambiarsi

--- src/babel/italiano/lexicon.clj
+++ src/babel/italiano/lexicon.clj
@@ -434,6 +434,21 @@
    "cambiare" {:synsem {:cat :verb
                         :sem {:pred :change}}}

+   "cambiarsi" (let [subject-semantics (ref {:animate true})
+                   subject-agr (ref :top)]
+               {:synsem {:cat :verb
+                         :essere true
+                         :sem {:pred :change-clothes
+                               :reflexive true
+                               :subj subject-semantics
+                               :obj subject-semantics}
+                         :subcat {:1 {:agr subject-agr
+                                      :sem subject-semantics}
+                                  :2 {:agr subject-agr
+                                      :pronoun true
+                                      :reflexive true
+                                      :sem subject-semantics}}}})
+
    "cancellare" {:synsem {:cat :verb
                           :sem {:pred :erase}}}


Add wpml/table function.

Add wpml/table function.

--- src/bakyeono/litedocx/wpml.clj
+++ src/bakyeono/litedocx/wpml.clj
@@ -152,9 +152,11 @@
    :body body})

 (defn make-resources
-  "Creates a vector of external resource information maps for DOCX pakcage.\n
-  Parameters:
-  - & specs: [content-type filename body] of the resource, ...\n
+  "Creates a vector of external resource information maps for DOCX pakcage.
+
+  Parameters:
+  - & specs: [content-type filename body] of the resource, ...
+
   Examples:
   - (make-resources [\"image/png\" \"embeded_image1.png\" FILE_BODY] ...)"
   [& specs]
@@ -172,9 +174,11 @@
            :PartName part-name}})

 (defn content-types-xml
-  "Creates xml data for [Content_Types].xml file in DOCX package.\n
-  Parameters:
-  - resources: <vector of {:content-type <string>, :part-name <string>}>}\n
+  "Creates xml data for [Content_Types].xml file in DOCX package.
+
+  Parameters:
+  - resources: <vector of {:content-type <string>, :part-name <string>}>}
+
   Note that resources should be created by make-resources."
   [resources]
   {:tag :Types
@@ -183,9 +187,11 @@
                   (map resource-type-override resources))})

 (defn doc-props-app-xml
-  "Creates xml data for docProps/app.xml file in DOCX pakcage.\n
-  Parameters:
-  - & properties: option, value, ...\n
+  "Creates xml data for docProps/app.xml file in DOCX pakcage.
+
+  Parameters:
+  - & properties: option, value, ...
+
   Examples:
   - (doc-props-app-xml :application \"Microsoft Office Word\" :app-version \"12.0000\")"
   [& {:as options
@@ -198,9 +204,11 @@
                    [:properties:Application :properties:AppVersion]))})

 (defn doc-props-core-xml
-  "Creates xml data for docProps/core.xml file in DOCX pakcage.\n
-  Parameters:
-  - & properties: option, value, ...\n
+  "Creates xml data for docProps/core.xml file in DOCX pakcage.
+
+  Parameters:
+  - & properties: option, value, ...
+
   Examples:
   - (doc-props-core-xml :creator \"Bak Yeon O\" :last-modified-by \"Bak Yeon O\")"
   [& {:as properties
@@ -214,7 +222,7 @@
                     :dc:description :cp:lastModifiedBy]))})

 (defn word-document-xml
-  "Creates xml data for word/document.xml file in DOCX pakcage.\n"
+  "Creates xml data for word/document.xml file in DOCX pakcage."
   []
   {:tag :w:document
    :attrs word-xmlns
@@ -279,13 +287,16 @@
 (defn paragraph-style
   "Creates a w:style tag of paragraph. Returns w:style tag for paragraph style with
   w:style tag for the font, as a vector containing both of them.
-  Needed for word-styles-xml.\n
+  Needed for word-styles-xml.
+
   Parameters:
   - name: <string> What others call this style. Also used as style-id. Must be unique.
-  - & options: option, value, ...\n
+  - & options: option, value, ...
+
   Examples:
   - (paragraph-style \"paragraph1\")
-  - (paragraph-style \"paragraph2\" :font \"Arial\" :font-color \"0000AA\" :align \"both\")\n
+  - (paragraph-style \"paragraph2\" :font \"Arial\" :font-color \"0000AA\" :align \"both\")
+
   See More: "
   [name
    & {:as options
@@ -340,7 +351,8 @@
   "Creates a vector of resource data map. Each map has :path and :byte-array
   keys and their values.
   Parameters:
-  - resources: <vector of {:path <string>, :body <byte-array>}>}\n
+  - resources: <vector of {:path <string>, :body <byte-array>}>}
+
   Note that resources should be created by make-resources."
   [resources]
   (flatten
@@ -357,12 +369,46 @@
            :Target target}})

 (defn word-rels-document-xml-rels
-  "Creates xml data for word/_rels/document.xml.rels file in DOCX package.\n
-  Parameters:
-  - resources: <vector of {:id <number>, :type <string>, :target <string>}>}\n
+  "Creates xml data for word/_rels/document.xml.rels file in DOCX package.
+
+  Parameters:
+  - resources: <vector of {:id <number>, :type <string>, :target <string>}>}
+
   Note that resources should be created by make-resources."
   [resources]
   {:tag :Relationships
    :attrs word-rels-document-xml-rels-xmlns
    :content (map rels resources)})

+(defn table
+  "Creates xml data of table.
+
+  Parameters:
+  - style: <string> style of table
+  - h-align: <string or keyword> horizontal alignment option in each cell.
+  - widths: <vector of numbers> widths of cells
+  - & body: content of the table
+
+  Examples:
+  (table \"table-style1\" :center [964 964 8072] ...)"
+  [style h-align widths & body]
+  {:tag :w:tbl
+   :content
+   (remove-nil
+     (into
+       [{:tag :w:tblPr
+         :content
+         [{:tag :w:tblStyle
+           :attrs {:w:val style}}
+          {:tag :w:tblW
+           :attrs {:w:w (reduce + widths)
+                   :w:type "dxa"}}
+          {:tag :w:jc
+           :attrs {:w:val (name h-align)}}]}
+        {:tag :w:tblGrid
+         :content
+         (for [w widths]
+           {:tag :w:gridCol
+            :attrs {:w:gridCol w}})}]
+       body))})
+


this is what happens when you insert a last minute assertion...

--- src/main/clojure/powderkeg/core.clj
+++ src/main/clojure/powderkeg/core.clj
@@ -24,13 +24,14 @@
   (some #(= msig (sig %)) (concat (.getMethods class) (.getConstructors class))))

 (defmacro ^:private compile-cond [& choices]
-	(let [x (Object.)
-	      expr
-	      (reduce (fn [_ [test expr]]
+  (let [x (Object.)
+        expr
+        (reduce (fn [_ [test expr]]
                   (when (eval test) (reduced expr)))
-         x (partition 2 choices))]
-	  (when (= x expr)
-	    (throw (ex-info "No valid choice." {:form &form})))))
+          x (partition 2 choices))]
+    (when (= x expr)
+      (throw (ex-info "No valid choice." {:form &form})))
+    expr))

 (defn- all-files
   "Returns a map of relative paths (as Strings) to Files for all files (not directories) below the argument."


Add a data-fn to sites for getting url of a comic

--- src/clj/comic_reader/sites.clj
+++ src/clj/comic_reader/sites.clj
@@ -22,6 +22,8 @@
      {:id :manga-fox
       :name "Manga Fox"

+      :comic->url (fn [comic-id]
+                    (str manga-url comic-id "/"))
       :comic-list-data {:url manga-url
                         :selector [:div.manga_list :ul :li :a]
                         :normalize link->map}
@@ -55,6 +57,9 @@
                                    (partial str canonical-url)))]
      {:id :manga-reader
       :name "Manga Reader"
+
+      :comic->url (fn [comic-id]
+                    (str canonical-url "/" comic-id))
       :comic-list-data {:url (str canonical-url "/alphabetical")
                         :selector [:div.series_alpha :ul :li :a]
                         :normalize link->map}


Accelerated Beta Test fix

Accelerated Beta Test fix

--- src/clj/game/cards-agendas.clj
+++ src/clj/game/cards-agendas.clj
@@ -3,7 +3,8 @@
 (def cards-agendas
   {"Accelerated Beta Test"
    (letfn [(abt [n i]
-             {:prompt "Select a piece of ICE from the top of the play area to install"
+             {:req (req (> i 0))
+              :prompt "Select a piece of ICE from the top of the play area to install"
               :choices {:req #(and (:side % "Corp") (= (:type %) "ICE") (= (:zone %) [:play-area]))}
               :effect (req (corp-install state side target nil {:no-install-cost true :install-state :rezzed-no-cost})
                            (trigger-event state side :rez target)
@@ -12,8 +13,7 @@
      {:optional {:prompt "Look at the top 3 cards of R&D?"
                  :yes-ability {:effect (req (let [n (count (filter #(= (:type %) "ICE") (take 3 (:deck corp))))]
                                               (resolve-ability state side
-                                                               {:req (req (> n 0))
-                                                                :msg (msg "install " n " ICE and trash " (- 3 n) " card" (when (< n 2) "s"))
+                                                               {:msg (msg "install " n " ICE and trash " (- 3 n) " card" (when (< n 2) "s"))
                                                                 :effect (req (doseq [c (take 3 (:deck corp))]
                                                                                (if (= (:type c) "ICE")
                                                                                (move state side c :play-area)


prevent closing of last window to keep menubar visible and gui-interaction possible - kind of a kludge...

--- src/clj_ns_browser/browser.clj
+++ src/clj_ns_browser/browser.clj
@@ -640,6 +640,11 @@
               (future
                 (clj-ns-browser.inspector/inspect-tree
                  val (str "Inspector for value of " fqn)))))))))
+    ;; If var is selected and its value is a collection, create inspector.
+    (b/bind
+      (b/property root :visible?)
+      (b/transform (fn [o]
+        (println "root visible?:" o))))
     ;;
     )) ; end of bind-all

@@ -744,6 +749,10 @@
     (swap! browser-root-frm-map (fn [a] (assoc @browser-root-frm-map (config root :id) root)))
     (config! root :transfer-handler (seesaw.dnd/default-transfer-handler
       :import [seesaw.dnd/string-flavor (fn [{:keys [data]}] (browser-with-fqn "" data root))]))
+    (listen root :component-hidden
+      (fn [e] (when (every? (fn [f] (not (config f :visible?))) @browser-root-frms)
+        (refresh-clj-ns-browser root)
+        (alert "Sorry... cannot close/hide last browser window."))))
     (refresh-clj-ns-browser root)
     root))


Removing fixed width for the tokenmgr views

--- src/com/okl/tokenmgr/views.clj
+++ src/com/okl/tokenmgr/views.clj
@@ -128,13 +128,13 @@
       ;; file import/export from web is needed.
       ;;(file-port-page)

-      [:div {:id "appdiv" :style "width:1200px;height:300px;"} ""]
+      [:div {:id "appdiv" :style "height:300px;"} ""]
       [:input {:type "submit" :class "AppAddNewRow" :value "Add New Row"}]
       [:input {:type "submit" :class "AppSubmitChanges" :value "Submit Changes"}]
       [:input {:type "submit" :class "AppResetChanges" :value "Reset Changes"}]
       [:script {:type "text/javascript"}
        (str "var appGrid = new AppSlickGrid('" app "', '"url-encoded-app "', '" (prefix) "', '" (delimiter) "');")]
-      [:div {:id "tokendiv" :style "width:1200px;height:300px;"} ""]
+      [:div {:id "tokendiv" :style "height:300px;"} ""]
       [:input {:type "submit" :class "TokenAddNewRow" :value "Add New Row"}]
       [:input {:type "submit" :class "TokenSubmitChanges" :value "Submit Changes"}]
       [:input {:type "submit" :class "TokenResetChanges" :value "Reset Changes"}]


Fix up sampled-piano to download samples if not previously cached.

--- src/overtone/inst/sampled_piano.clj
+++ src/overtone/inst/sampled_piano.clj
@@ -1,21 +1,35 @@
 (ns overtone.inst.sampled-piano
   (:use [overtone.core]))

-(defn- registered-samples []
-  (->> (registered-assets ::MISStereoPiano)
-       (filter #(.contains % "LOUD"))))
+(defn- registered-samples
+  "Fetch piano samples from the asset store (returns empty list if not
+  previously downloaded"
+  []
+  (filter #(.contains % "LOUD")
+          (registered-assets ::MISStereoPiano)))

-(defn- download-samples []
-  (->> (freesound-searchm [:id] "LOUD" :f "pack:MISStereoPiano")
-       (map freesound-path)))
+(defn- download-samples
+  "Download piano samples from freesound and store them in the asset
+  store."
+  []
+  (map freesound-path
+       (freesound-searchm [:id] "LOUD" :f "pack:MISStereoPiano")))
+
+(defn- get-samples
+  "Either fetch samples from the registered store or download them if
+  necessary"
+  []
+  (let [samples (registered-samples)]
+    (if (empty? samples)
+      (download-samples)
+      samples)))

 (defonce piano-samples
-  (doall (map load-sample (or (registered-samples)
-                              (download-samples)))))
+  (doall (map load-sample (get-samples))))

 (defn- note-index
-  "Returns a map of midi-note values [0-127] to buffer id's. Uses the provided
-  note-fn to determine the midi-note value of a buffer."
+  "Returns a map of midi-note values [0-127] to buffer ids. Uses the
+  provided note-fn to determine the midi-note value of a buffer."
   [buffers note-fn]
   (reduce (fn [index buf]
             (let [note (note-fn buf)


elevio Fix "paid users directed to Discuss" bug

Paid users were being directed to Discuss and free users had access to
support. This commit fixes the bug.


Add proper search support for kws, strings, regex, and numbers [:17]

--- src/ttt/search/core.cljs
+++ src/ttt/search/core.cljs
@@ -71,7 +71,7 @@
 ;; via a protocol, ISearchable, that defines a `search-compare`

 (defn ensure-kw [kw]
-  (if (and (= ":" (first kw)) (not (keyword? kw)))
+  (if (and (string? kw) (= ":" (first kw)) (not (keyword? kw)))
     (keyword kw)
     kw))

@@ -86,7 +86,11 @@

   js/RegExp
   (search-compare [this compare-to]
-    (re-find this (name compare-to))))
+    (re-find this (name compare-to)))
+
+  js/Number
+  (search-compare [this compare-to]
+    (= this compare-to)))

 (defn query-tickets [query-vec]
   (let [query-vec (normalize-query-vec query-vec)


Mention status scope on badge creation page

While tokens with greater scope will work, it's a bad idea to use them
so we don't include them in the list.  However this is confusing when
people know they have tokens and don't see them there.

--- src-cljs/frontend/components/project_settings.cljs
+++ src-cljs/frontend/components/project_settings.cljs
@@ -734,7 +734,7 @@
           [:div.token
            [:h4 "API Token"]
            (when-not (or oss (seq token))
-             [:p [:span.warning "Warning: "] "Private projects require an " [:a {:href "#api"} "API token"] "."])
+             [:p [:span.warning "Warning: "] "Private projects require an API token - " [:a {:href "#api"} "add one with status scope"] "."])
            [:div.styled-select
             [:select {:value token
                       :on-change #(utils/edit-input owner (conj state/project-data-path :status-badges :token) %)}


add npm dependencies to asciinema

add npm dependencies to asciinema

--- main/src/dda/pallet/dda_managed_ide/infra/basics.clj
+++ main/src/dda/pallet/dda_managed_ide/infra/basics.clj
@@ -54,7 +54,7 @@
      :scopes ["main"]
      :key-url "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x9D2E234C0F833EAD"})
   (actions/package-manager :update)
-  (actions/packages :aptitude ["asciinema" "nodejs" "phantomjs" "imagemagick" "gifsicle"])
+  (actions/packages :aptitude ["npm" "asciinema" "nodejs" "phantomjs" "imagemagick" "gifsicle"])
   (actions/exec-checked-script
     "install asciicast2gif"
     ("npm" "install" "--global" "asciicast2gif")))


version bump pallet-lein 0.8.0-alpha.1

version bump pallet-lein 0.8.0-alpha.1

--- dot/lein/profiles.clj
+++ dot/lein/profiles.clj
@@ -2,7 +2,7 @@
  {:plugins [[lein-vanity "0.1.0"]
             [jonase/eastwood "0.0.2"]
             [lein-ritz "0.7.0"]
-            [com.palletops/pallet-lein "0.6.0-beta.7"]]
+            [com.palletops/pallet-lein "0.8.0-alpha.1"]]
   :dependencies [[ritz/ritz-nrepl-middleware "0.7.0"]
                  [slamhound "1.3.3"]]
   :repl-options {:nrepl-middleware


add has-fn? inspired by Object#respond_to?

--- user.clj
+++ user.clj
@@ -13,6 +13,11 @@
 (defn split [f coll]
   "Like ruby's partition"
   [(filter f coll) (remove f coll)])
+
+(defn has-fn?
+  "Indicates if a namespace has a fn"
+  ([fun] (has-fn? fun *ns*))
+  ([fun nsp] (#(if (var? %) (fn? (deref %)) false) (ns-resolve nsp fun))))

 ; TODO: only display vars local to a namespace
 (defn ns-dynamic-vars


Improve parse-int function.

Improve parse-int function.

--- src/uxbox/util/data.cljs
+++ src/uxbox/util/data.cljs
@@ -94,7 +94,7 @@

 (defn parse-int
   ([v]
-   (js/parseInt v 10))
+   (parse-int v nil))
   ([v default]
    (let [v (js/parseInt v 10)]
      (if (or (not v) (nan? v))
@@ -103,7 +103,7 @@

 (defn parse-float
   ([v]
-   (js/parseFloat v))
+   (parse-float v nil))
   ([v default]
    (let [v (js/parseFloat v)]
      (if (or (not v) (nan? v))


s/DEBUG/TRACE/

s/DEBUG/TRACE/

--- src/babel/over.cljc
+++ src/babel/over.cljc
@@ -95,8 +95,8 @@
 (def ^:dynamic *check-infl* true)

 (defn head-pre-checks [parent child]
-  (log/debug (str "head-pre-checks PH: " (strip-refs (get-in parent [:head]))))
-  (log/debug (str "head-pre-checks H: " (dissoc (strip-refs child) :serialized)))
+  (log/trace (str "head-pre-checks PH: " (strip-refs (get-in parent [:head]))))
+  (log/trace (str "head-pre-checks H: " (dissoc (strip-refs child) :serialized)))
   (or
    (fail? (unifyc (get-in parent [:head :synsem :infl] :top)
                   (get-in child [:synsem :infl] :top)))


set {:comp {:synsem {:reflexive true}}} for vp-pronoun-nonphrasal

--- src/babel/italiano/grammar.clj
+++ src/babel/italiano/grammar.clj
@@ -338,12 +338,21 @@
                             :rule "vp-pronoun-phrasal"
                             :synsem {:cat :verb
                                      :infl {:not :past}}})
-                   ;; Note use of :reflexive below.
+
+                   ;; Note {:reflexive true} below: for now, we are trying to
+                   ;; only generate reflexive sentences (e.g. "io mi alzo") and not transitive
+                   ;; sentences with pronouns (e.g. "io lo vedo").
+                   ;; We have a problem with generating transitive sentences otherwise,
+                   ;; which is not always desired in a given educational context (if we want to concentrate
+                   ;; on intransitive verbs plus reflexives).
+                   ;; Later, when we do want to generate transitive sentences with pronouns, we might need
+                   ;; to split this rule into two: one for reflexives, one for transitives.
                    (unifyc c21
                            root-is-head
                            {:head {:phrasal false
                                    :synsem {:sem {:reflexive true}}}
                             :comp {:synsem {:cat :noun
+                                            :reflexive true
                                             :pronoun true}}
                             :rule "vp-pronoun-nonphrasal"
                             :synsem {:cat :verb


removed implied gets

removed implied gets

--- src/cia/stores/es/document.clj
+++ src/cia/stores/es/document.clj
@@ -24,16 +24,20 @@
                    doc
                    :id (:id doc)
                    :refresh true)
-  (get-doc conn index-name mapping (:id doc)))
+  doc)

 (defn update-doc
   "update a document on es return the updated document"
   [conn index-name mapping id doc]
-  (document/update-with-partial-doc conn index-name mapping id doc)
-  (get-doc conn
-           index-name
-           mapping
-           id))
+
+  (-> (document/update-with-partial-doc conn
+                                        index-name
+                                        mapping
+                                        id
+                                        doc
+                                        {:fields "_source"})
+      :get-result
+      :source))

 (defn delete-doc
   "delete a document on es and return nil if ok"


Fix: inadvertent override of timeout in :script-defaults

--- src/cider_ci/builder/tasks.clj
+++ src/cider_ci/builder/tasks.clj
@@ -51,14 +51,10 @@
     scripts
     (throw (IllegalStateException. (str ":scripts must a map " scripts)))))

-(def ^:private script-base-defaults
-  {:timeout (* 15 60)
-   })
-
 (defn- coerce-script-value [value]
   (cond
-    (map? value) (deep-merge script-base-defaults value)
-    (string? value) (deep-merge  script-base-defaults {:body value})
+    (map? value) value
+    (string? value) {:body value}
     :else (throw (IllegalStateException.
                    (str "don't know how to handle type " (type value))))))

@@ -116,6 +112,10 @@
                                                script-defaults)))
            context)))

+(def ^:private script-base-defaults
+  {:timeout (* 15 60)
+   })
+
 (defn build-tasks
   "Build the tasks for the given top-level specification."
   [job _spec]
@@ -124,7 +124,7 @@
                 spec
                 (conj (or (:task-defaults spec) {})
                       {:job_id (:id job)})
-                (or (:script-defaults spec) {}))]
+                (deep-merge script-base-defaults (or (:script-defaults spec) {})))]
     (doseq [raw-task tasks]
       (wrap-exception-create-job-issue
         job "Error during task creation"


set :agendapoints-runner for Domestic Sleepers and Project Beale

prevents Turntable from giving the Runner too many points if an overadvanced Beale or a 1-point Sleepers is ever swapped

--- src/clj/game/cards-agendas.clj
+++ src/clj/game/cards-agendas.clj
@@ -9,9 +9,7 @@
                                   (gain-agenda-point state agenda-owner (- (:agendapoints card))))
                                 ; refresh agendapoints to 1 before shuffle in case it was modified by e.g. The Board
                                 (move state :corp (dissoc (assoc card :agendapoints 1) :seen :rezzed) :deck {:front true})
-                                (shuffle! state :corp :deck)
-                                )
-                   }]
+                                (shuffle! state :corp :deck))}]
       :flags {:has-abilities-when-stolen true}}

    "Accelerated Beta Test"
@@ -120,7 +118,8 @@
                                :msg "create a new remote server, installing cards at no cost"}}})

    "Domestic Sleepers"
-   {:abilities [{:cost [:click 3] :msg "place 1 agenda counter on Domestic Sleepers"
+   {:agendapoints-runner (req (do 0))
+    :abilities [{:cost [:click 3] :msg "place 1 agenda counter on Domestic Sleepers"
                  :effect (req (when (zero? (:counter card))
                                 (gain-agenda-point state side 1))
                               (set-prop state side card :counter 1 :agendapoints 1))}]}
@@ -341,7 +340,8 @@
                  :effect (effect (move target :hand) (shuffle! :deck))}]}

    "Project Beale"
-   {:effect (effect (set-prop card :counter (quot (- (:advance-counter card) 3) 2)
+   {:agendapoints-runner (req (do 2))
+    :effect (effect (set-prop card :counter (quot (- (:advance-counter card) 3) 2)
                               :agendapoints (+ 2 (quot (- (:advance-counter card) 3) 2))))}

    "Project Vitruvius"


Remove unused function

Remove unused function

--- src/clj_gatling/simulation.clj
+++ src/clj_gatling/simulation.clj
@@ -40,15 +40,6 @@
             :start @start-promise
             :end (now)
             :result false} context])))))
-
-(defn- run-requests [requests timeout user-id result-channel]
-  (go-loop [r requests
-            context {}
-            results []]
-    (let [[result new-ctx] (<! (async-function-with-timeout (first r) timeout user-id context))]
-      (if (empty? (rest r))
-        (>! result-channel (conj results result))
-        (recur (rest r) new-ctx (conj results result))))))

 (defprotocol RunnerProtocol
   (continue-run? [runner handled-requests scenario-start])


Add debug logging to time requests submitted to ECHO

--- src/cmr/transmit/echo/rest.clj
+++ src/cmr/transmit/echo/rest.clj
@@ -28,10 +28,11 @@
    (let [conn (config/context->app-connection context :echo-rest)
          url (format "%s%s" (conn/root-url conn) url-path)
          params (merge (request-options conn) options)
-         ;; Uncoment to log requests
-         ; _ (debug "Making ECHO GET Request" url)
          response (client/get url params)
-         ; _ (debug "Completed ECHO GET Request" url)
+         start (System/currentTimeMillis)
+         response (client/get url params)
+         _ (debug (format "Completed ECHO GET Request to %s in [%d] ms" url (- (System/currentTimeMillis) start)))
+
          {:keys [status body headers]} response
          parsed (if (.startsWith ^String (get headers "Content-Type" "") "application/json")
                   (json/decode body true)


removed commented code

removed commented code

--- src/cellf/core.cljs
+++ src/cellf/core.cljs
@@ -90,7 +90,6 @@
     range
     vec
     (conj :empty)))
-  ;(conj (vec (range (dec (sq size)))) :empty))

 (defn make-cells [size win-state]


modal view

modal view

--- src/cellf/core.cljs
+++ src/cellf/core.cljs
@@ -217,10 +217,45 @@
                 :vid-ratio   (/ vw vh)
                 :vid-offset  (* 100 (/ (max 1 (.abs js/Math (- vw vh))) (max 1 (* vw 2))))
                 :canvas-node canvas
-                :ctx         (.getContext canvas "2d")})
+                :ctx         (.getContext canvas "2d")
+                :show-about  true})
               (js/setTimeout start! 500))))
           (aset "src" data)))
       (swap! app-state assoc :media-error? true)))))
+
+
+(defn modal [{:keys [stream media-error? show-about] :as app}]
+  (apply dom/div #js {
+    :className (str "modal" (when (or (not stream) media-error? show-about) " active"))}
+    (dom/h1 nil "Cellf")
+    (cond
+      media-error?
+        (dom/p nil
+          "Sorry, Cellf doesn't work without camera access."
+          (dom/button #js {:onClick get-camera!} "try again"))
+
+      (not stream)
+        (dom/p nil
+          (str
+            "Cellf is an interactive experiment that puts a twist on the classic "
+            "sliding puzzle game. Click OK to prompt for camera access.")
+          (dom/button #js {:onClick get-camera!} "ok"))
+
+      show-about
+        [
+          (dom/p nil
+            (str
+              "Simply click a square next to the empty space to move it. "
+              "When you shuffle them into the correct order, you win."))
+          (dom/p nil
+            (str
+              "You can also export a replay of your moves to an animated gif. "
+              "Cellf is ")
+            (dom/a #js {:href "https://github.com/dmotz/cellf"} "open source")
+            ". For more experiments like this, visit "
+            (dom/a #js {:href "http://oxism.com"} "oxism.com")
+            \.
+            (dom/button #js {:onClick #(om/update! app [:show-about] false)} "got it"))])))

 (om/root
@@ -249,6 +284,7 @@
       (render [_]
         (let [move-count (count moves)]
           (dom/div nil
+            (modal app)
             (dom/div #js {:id "sidebar" :style #js {:width capture-size}}
               (dom/h1 nil "cellf")
               (dom/p nil "find yourself.")