allow disabling source map generating for shadow-js

--- src/main/shadow/build/closure.clj
+++ src/main/shadow/build/closure.clj
@@ -1545,10 +1545,9 @@

         co-opts
         (merge
-          {:source-map true
-           ;; :whitespace or :simple work but some patterns really require the DCE done by :simple
-           ;; eg some conditional imports done by react&friends
-           :optimizations :simple
+          ;; :whitespace or :simple work but some patterns really require the DCE done by :simple
+          ;; eg some conditional imports done by react&friends
+          {:optimizations :simple
            :pretty-print false
            :pseudo-names false
            ;; es6+ is transformed by babel first
@@ -1556,7 +1555,12 @@
            ;; doesn't really impact much here anyways
            :language-in :ecmascript-next
            :language-out :ecmascript5}
-          (dissoc js-options :resolve))
+          (dissoc js-options :resolve)
+          ;; always enable source-map, just skip emitting them later if desired
+          {:source-map true})
+
+        generate-source-map?
+        (not (false? (:source-map js-options)))

         property-collector
         (PropertyCollector. cc)
@@ -1649,15 +1653,13 @@
                        (remove #(str/includes? js (str "(\"" % "\")")))
                        (into #{}))

-                  sw
-                  (StringWriter.)
-
-                  ;; for sourcesContent
-                  _ (.addSourceFile source-map source-file)
-                  _ (.appendTo source-map sw output-name)
-
                   sm-json
-                  (.toString sw)
+                  (when generate-source-map?
+                    (let [sw (StringWriter.)]
+                      ;; for sourcesContent
+                      (.addSourceFile source-map source-file)
+                      (.appendTo source-map sw output-name)
+                      (.toString sw)))

                   deps
                   (data/deps->syms state rc)
@@ -1666,14 +1668,16 @@
                   (into #{} (remove removed-requires) deps)

                   output
-                  {:resource-id resource-id
-                   :js js
-                   :source (.getCode source-file)
-                   :removed-requires removed-requires
-                   :actual-requires actual-requires
-                   :properties (into #{} (-> property-collector (.-properties) (.get name)))
-                   :compiled-at (System/currentTimeMillis)
-                   :source-map-json sm-json}]
+                  (-> {:resource-id resource-id
+                       :js js
+                       :source (.getCode source-file)
+                       :removed-requires removed-requires
+                       :actual-requires actual-requires
+                       :properties (into #{} (-> property-collector (.-properties) (.get name)))
+                       :compiled-at (System/currentTimeMillis)}
+                      (cond->
+                        generate-source-map?
+                        (assoc :source-map-json sm-json)))]

               (assoc-in state [:output resource-id] output)
               ))


add basic cache for goog converted files

--- src/main/shadow/build/closure.clj
+++ src/main/shadow/build/closure.clj
@@ -14,7 +14,8 @@
     [shadow.build.data :as data]
     [shadow.build.npm :as npm]
     [shadow.build.cache :as cache]
-    [shadow.core-ext :as core-ext])
+    [shadow.core-ext :as core-ext]
+    [shadow.build.resource :as rc])
   (:import (java.io StringWriter ByteArrayInputStream FileOutputStream File)
            (com.google.javascript.jscomp JSError SourceFile CompilerOptions CustomPassExecutionTime
                                          CommandLineRunner VariableMap SourceMapInput DiagnosticGroups
@@ -1724,6 +1725,12 @@

           (.addCustomPass CustomPassExecutionTime/BEFORE_CHECKS replace-require-pass)

+          ;; google SourceMapResolver is broken since it always resolves source map files relative
+          ;; from the input name not from its original path. since we always use the resource-name
+          ;; as the input it can never find anything. can't use the full path as input as that
+          ;; affects the generated alias
+          (.setResolveSourceMapAnnotations false)
+
           (.setWarningLevel DiagnosticGroups/NON_STANDARD_JSDOC CheckLevel/OFF)
           (.setWarningLevel DiagnosticGroups/MISPLACED_TYPE_ANNOTATION CheckLevel/OFF)
           ;; node_modules/@firebase/util/dist/cjs/src/constants.ts:26: ERROR - @define variable  assignment must be global
@@ -1976,9 +1983,9 @@
                  :live-js-deps live-js-deps))
       )))

-(defn convert-goog
+(defn convert-goog*
   "convert Closure Library code since it may contain a random mix of ClosureJS and Closure Modules"
-  [{:keys [js-options  mode] :as state} sources]
+  [{:keys [js-options mode] :as state} sources]
   (let [source-files
         (->> (for [{:keys [resource-name] :as src} sources]
                (let [source (data/get-source-code state src)]
@@ -2002,19 +2009,11 @@
         (data/make-closure-compiler)

         co-opts
-        (merge
-          ;; :whitespace or :simple work but some patterns really require the DCE done by :simple
-          ;; eg some conditional imports done by react&friends
-          {:pretty-print true
-           :pseudo-names false
-           ;; es6+ is transformed by babel first
-           ;; but closure got real picky and complains about some things being es6 that aren't
-           ;; doesn't really impact much here anyways
-           :language-in :ecmascript-next
-           :language-out :ecmascript5}
-          ;; (dissoc js-options :resolve)
-          ;; always enable source-map, just skip emitting them later if desired
-          {:source-map true})
+        {:pretty-print true
+         :pseudo-names false
+         :language-in :ecmascript-next
+         :language-out :ecmascript5
+         :source-map true}

         generate-source-map?
         (not (false? (:source-map js-options)))
@@ -2032,7 +2031,7 @@
         result
         (try
           (util/with-logged-time [state {:type ::goog-convert
-                                         :num-sources (count sources)}]
+                                         :num-files (count sources)}]
             (.compile cc default-externs source-files closure-opts))
           ;; catch internal closure errors
           (catch Exception e
@@ -2090,4 +2089,112 @@

           (->> (ShadowAccess/getJsRoot cc)
                (.children) ;; the inputs
-               )))))+               )))))
+
+(defn convert-goog
+  "convert and caches ClosureJS and ClosureModule sources"
+  [state sources]
+  (let [cache-index-file
+        (data/cache-file state "goog-js" "index.json.transit")
+
+        cache-index
+        (or (::shadow-js-cache state)
+            ;; read from disk
+            (and (.exists cache-index-file)
+                 (cache/read-cache cache-index-file))
+            ;; ensure that at least the directoy exists so we can write files into it later
+            (do (io/make-parents cache-index-file)
+                {}))
+
+        ;; FIXME: currently this doesn't accept any outside compiler options
+        cache-options
+        []
+
+        cache-files
+        (if (or (not= SHADOW-CACHE-KEY (:SHADOW-CACHE-KEY cache-index))
+                (not= cache-options (:CACHE-OPTIONS cache-index)))
+          ;; invalidate all cache when the timestamp of this file has changed
+          []
+          ;; compare each cache key
+          (->> (for [{:keys [resource-id cache-key] :as src} sources
+                     ;; FIXME: this should probably check if the file exists
+                     ;; never should delete individual cached files without also removing the index though
+                     :when (= cache-key (get cache-index resource-id))]
+                 src)
+               ;; need to preserve order for later
+               (into [])))
+
+        cache-files-set
+        (into #{} (map :resource-id) cache-files)
+
+        recompile-sources
+        (->> sources
+             (remove #(contains? cache-files-set (:resource-id %)))
+             (into []))
+
+        need-compile?
+        (boolean (seq recompile-sources))
+
+        ;; can't do a partial compile since goog is picky about missing names
+        ;; compile is fast so we can just recompile everything
+        state
+        (if-not need-compile?
+          state
+          (convert-goog* state sources))
+
+        cache-index-updated
+        (if-not need-compile?
+          cache-index
+          (util/with-logged-time [state {:type ::goog-cache-write
+                                         :num-files (count recompile-sources)}]
+            (reduce
+              (fn [idx {:keys [cache-key resource-id output-name] :as compiled-src}]
+                (let [output
+                      (data/get-output! state compiled-src)
+
+                      cache-file
+                      (data/cache-file state "goog-js" output-name)]
+
+                  (cache/write-file cache-file output)
+
+                  (assoc idx resource-id cache-key)))
+              (assoc cache-index
+                :SHADOW-CACHE-KEY SHADOW-CACHE-KEY
+                :CACHE-OPTIONS cache-options)
+              sources)))]
+
+    (when need-compile?
+      (cache/write-file cache-index-file cache-index-updated))
+
+    ;; full compile always so never need to restore cache when compiled
+    (if need-compile?
+      state
+      (util/with-logged-time [state {:type ::goog-cache-read
+                                     :num-files (count cache-files)}]
+        (reduce
+          (fn [state {:keys [resource-id output-name] :as cached-rc}]
+            (if (get-in state [:output resource-id])
+              state
+              (let [cache-file
+                    (data/cache-file state "goog-js" output-name)
+
+                    {:keys [actual-requires] :as cached-output}
+                    (-> (cache/read-cache cache-file)
+                        (assoc :cached true))]
+
+                (assoc-in state [:output resource-id] cached-output)
+                )))
+          state
+          cache-files)))))
+
+(defmethod build-log/event->str ::goog-cache-read
+  [{:keys [num-files]}]
+  (format "Closure JS Cache read: %d JS files" num-files))
+
+(defmethod build-log/event->str ::goog-cache-write
+  [{:keys [num-files]}]
+  (format "Closure JS Cache write: %d JS files" num-files))
+
+(defmethod build-log/event->str ::goog-convert
+  [{:keys [num-files]}]
+  (format "Closure JS convert: %d JS files" num-files))


Save theme pref

Save theme pref

--- src/net/sekao/nightcode/state.clj
+++ src/net/sekao/nightcode/state.clj
@@ -62,6 +62,8 @@
         (write-pref! :expansion-set new-expansions))
       (when (not= old-selection new-selection)
         (write-pref! :selection new-selection))
+      (when (not= old-theme new-theme)
+        (write-pref! :theme new-theme))
       (when (not= old-text-size new-text-size)
         (write-pref! :text-size new-text-size)))))


Changes done to refer to the proper entity. Will get refined in the future.

--- src/conceptnet_clj/core.clj
+++ src/conceptnet_clj/core.clj
@@ -69,7 +69,7 @@

 (defn actor-or-movie-name [db eid]
   (let [ent (d/entity db (e eid))]
-    (or (:movie/title ent) (:person/name ent))))
+    (or (:cnet/end ent) (:cnet/start ent))))

 (defn referring-to
   "Find all entities referring to an eid as a certain attribute."
@@ -88,7 +88,7 @@
   name is the actor's name"
   [db eid]
   (-> (d/entity db (e eid))
-      :person/name))
+      :cnet/start))

 (defn actor-search
   "Returns set with exact match, if found. Otherwise query will
@@ -96,12 +96,12 @@
   [db query]
   (if (str/blank? query)
     #{}
-    (if-let [eid (d/entid db [:person/name query])]
+    (if-let [eid (d/entid db [:cnet/start query])]
       [{:name query :actor-id eid}]
       (mapv #(zipmap [:actor-id :name] %)
             (q '[:find ?e ?name
                  :in $ ?search
-                 :where [(fulltext $ :person/name ?search) [[?e ?name]]]]
+                 :where [(fulltext $ :cnet/start ?search) [[?e ?name]]]]
                db (format-query query))))))

 (defn movie-actors
@@ -187,7 +187,7 @@
   (let [ename (partial actor-or-movie-name db)
         annotate-node (fn [node]
                         (let [ent (d/entity db node)]
-                          {:type (if (:person/name ent) "actor" "movie")
+                          {:type (if (:cnet/cnet ent) "actor" "movie")
                            :year (:movie/year ent)
                            :name (ename ent)
                            :entity ent}))]


Minor cosmetics in c.fca.contexts

Minor cosmetics in c.fca.contexts

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

--- src/conexp/fca/contexts.clj
+++ src/conexp/fca/contexts.clj
@@ -200,12 +200,12 @@
         m (count G),
         n (count M)]
     (assert (= (* m n) (count bits)))
-    (make-context G M
-                  (set-of [a b] [i (range (count G)),
-                                 j (range (count M)),
-                                 :when (= 1 (nth bits (+ (* n i) j)))
-                                 :let [a (nth G i),
-                                       b (nth M j)]]))))
+    (make-context-nc G M
+                     (set-of [a b] [i (range (count G)),
+                                    j (range (count M)),
+                                    :when (= 1 (nth bits (+ (* n i) j)))
+                                    :let [a (nth G i),
+                                          b (nth M j)]]))))

 (defn object-derivation
   "Computes set of attributes common to all objects in context."
@@ -294,7 +294,7 @@
 	inz (incidence ctx)
 	prime (memoize (partial attribute-derivation ctx))]
     (set-of [g m]
-	    [g obj
+	    [g obj,
 	     m att
 	     :when (and (not (inz [g m]))
 			(forall [n att]
@@ -344,10 +344,10 @@
 	     att (attributes ctx)
 	     uda (up-down-arrows ctx)]
 	 (and (forall [g obj]
-		(exists [ [h _] uda ]
+		(exists [[h _] uda]
 		  (= g h)))
 	      (forall [m att]
-		(exists [ [_ n] uda ]
+		(exists [[_ n] uda]
 		  (= m n)))))))

 (defn context-object-closure
@@ -381,7 +381,7 @@
   (for [objs (context-extents ctx)]
     [objs, (object-derivation ctx objs)]))

-;; Common Operations with Contexts
+;;; Common Operations with Contexts

 (defn dual-context
   "Dualizes context ctx, that is $(G,M,I)$ gets $(M,G,I^{-1})$."
@@ -515,7 +515,7 @@
 			(set-of [[g_2 2] [m_1 1]]
 				[g_2 (objects ctx-2)
 				 m_1 (attributes ctx-1)]))]
-    (make-context new-objs new-atts new-inz)))
+    (make-context-nc new-objs new-atts new-inz)))

 (defn context-product
   "Computes the context product of ctx-1 and ctx-2, that is


Adjusting reify clause

Adjusting reify clause

--- kabob-build/src/main/resources/edu/ucdenver/ccp/kabob/build/rules/temp/goa/goa.clj
+++ kabob-build/src/main/resources/edu/ucdenver/ccp/kabob/build/rules/temp/goa/goa.clj
@@ -45,7 +45,7 @@
          )
   :reify ([?/bp {:ln (:sha-1 ?/go ?/hr1)
                  :ns "kbio" :prefix "BP_"}]
-          [?/protein {:ln (:sha-1 ?/go ?/hr1 ?/bioentity)
+          [?/protein {:ln (:sha-1 ?/go ?/bioentity)
                     :ns "kbio" :prefix "P_"}]
           [?/hr1 {:ln (:restriction)
                  :ns "kbio" :prefix "R_"}])
@@ -109,7 +109,7 @@
                  :ns "kbio" :prefix "R_"}]
           [?/to1 {:ln (:restriction)
                  :ns "kbio" :prefix "R_"}]
-          [?/protein {:ln (:sha-1 ?/go ?/of1 ?/bioentity)
+          [?/protein {:ln (:sha-1 ?/go ?/bioentity)
                      :ns "kbio" :prefix "P_"}]
           [?/gocc {:ln (:sha-1 ?/go ?/to1)
                    :ns "kbio" :prefix "CC_"}]


delaney.clj: added print and comparison method and first test for DSymbol

--- clojure/org/gavrog/clojure/delaney.clj
+++ clojure/org/gavrog/clojure/delaney.clj
@@ -1,6 +1,8 @@
 (ns org.gavrog.clojure.delaney
-  (:use (org.gavrog.clojure [util :only [empty-queue pop-while]]))
-  (:import (org.gavrog.joss.dsyms.basic DelaneySymbol)))
+  (:use (clojure [test])
+        (org.gavrog.clojure [util :only [empty-queue pop-while]]))
+  (:import (org.gavrog.joss.dsyms.basic DelaneySymbol)
+           (java.io Writer)))

 (defprotocol IDSymbol
   (element? [_ D])
@@ -58,10 +60,39 @@
             (DSymbol. idcs
                       elms
                       (assoc s# i (dissoc (s# i) D ((s# i) D)))
-                      v#)))
+                      v#))
+  Object
+  (equals [self other]
+          (and (satisfies? IDSymbol other)
+               (= (indices self) (indices other))
+               (= (elements self) (elements other))
+               (= (ops self) (ops other))
+               (= (vs self) (vs other)))))

+(defmethod print-method DSymbol [ds ^Writer w]
+  (print-method (list (symbol "DSymbol.")
+                      (into #{} (indices ds))
+                      (into #{} (elements ds))
+                      (ops ds)
+                      (vs ds))
+                w))
+
+(deftest gluing
+  (is (= (dsglue (DSymbol. #{0 1 2} #{} {} {}) 0 1 2)
+         (DSymbol. #{0 1 2} #{1 2} {0 {1 2 2 1}} {}))))

 ;; General D-symbol functions
+
+(defn- ops [ds]
+  (into {} (for [i (indices ds)]
+             [i (into {} (for [D (elements ds)]
+                           [D (s ds i D)]))])))
+
+(defn- vs [ds]
+  (into {} (for [i (indices ds)
+                 :when (index? ds (inc i))]
+             [i (into {} (for [D (elements ds)]
+                           [D (v ds i (inc i) D)]))])))

 (defn size [ds] (count (elements ds)))


added filter example

added filter example

--- src/datasplash/examples.clj
+++ src/datasplash/examples.clj
@@ -1,7 +1,9 @@
 (ns datasplash.examples
   (:require [clojure.string :as str]
             [datasplash
-             [api :as ds]])
+             [api :as ds]
+             [bq :as bq]]
+            [clojure.edn :as edn])
   (:gen-class))

 ;;;;;;;;;;;;;;;
@@ -59,6 +61,52 @@
          (ds/distinct {:name "dedup"})
          (ds/write-text-file output {:name "DedupedShakespeare"}))))

+;;;;;;;;;;;;
+;; Filter ;;
+;;;;;;;;;;;;
+
+(ds/defoptions FilterOptions
+  {:input {:type String
+           :default "clouddataflow-readonly:samples.weather_stations"
+           :description "Table to read from, specified as <project_id>:<dataset_id>.<table_id>"}
+   :output {:type String
+            :default "filterRes.edn"
+            :description "Table to write to, specified as <project_id>:<dataset_id>.<table_id>. The dataset_id must already exist. If given a path, writes to edn."}
+   :monthFilter {:type Long
+                 :default 7
+                 :description "Numeric value of month to filter on"}})
+
+(defn run-filter
+  [str-args]
+  (let [p (ds/make-pipeline 'FilterOptions str-args)
+        {:keys [input output monthFilter]} (ds/get-pipeline-configuration p)
+        all-rows (->> p
+                      (bq/read-bq-table input)
+                      (ds/map (fn [row]
+                                (->>
+                                 (select-keys row [:year :month :day :mean_temp])
+                                 (map (fn [[k v]] (if (string? v) [k (edn/read-string v)] [k v])))
+                                 (into {})))
+                              {:name "Projection"}))
+        global-mean-temp (->> all-rows
+                              (ds/map :mean_temp)
+                              (ds/mean)
+                              (ds/view))
+        filtered-results (->> all-rows
+                              (ds/filter (fn [{:keys [month]}] (= month monthFilter)))
+                              (ds/filter (fn [{:keys [mean_temp]}]
+                                           (let [gtemp (:global-mean (ds/side-inputs))]
+                                             (< mean_temp gtemp)))
+                                         {:name "ParseAndFilter" :side-inputs {:global-mean global-mean-temp}}))]
+    (if (re-find #":[^\\]" output)
+      (bq/write-bq-table output {:schema [{:name "year" :type "INTEGER"}
+                                          {:name "month":type "INTEGER"}
+                                          {:name "day"  :type "INTEGER"}
+                                          {:name "mean_temp" :type "FLOAT"}]
+                                 :create-disposition :if-needed
+                                 :write-disposition :truncate}
+                         filtered-results)
+      (ds/write-edn-file output filtered-results))))

 ;;;;;;;;;;
 ;; Main ;;
@@ -69,5 +117,6 @@
   (compile 'datasplash.examples)
   (-> (case job
         "word-count" (run-word-count args)
-        "dedup" (run-dedup args))
+        "dedup" (run-dedup args)
+        "filter" (run-filter args))
       (ds/run-pipeline)))


Link to the custom JUnit docs

Link to the custom JUnit docs

--- src-cljs/frontend/components/build_head.cljs
+++ src-cljs/frontend/components/build_head.cljs
@@ -271,7 +271,7 @@
     [:li "For another inferred test runner that you'd like us to add metadata support for, "
      [:a {:on-click #(raise! owner [:intercom-dialog-raised])} "let us know"] "."]
     [:li "For a custom test command, configure your test runner to write a JUnit XML report to a directory in $CIRCLE_TEST_REPORTS - see "
-     [:a {:ref ""} "the docs"] " for more information."]]
+     [:a {:href "/docs/test-metadata#metadata-collection-in-custom-test-steps"} "the docs"] " for more information."]]
    "With test metadata, we can provide better insight into your build results and in some cases speed up your parallel builds by more efficiently splitting your tests between containers."])

 (defn build-tests-list [data owner]


show date in doc thumb

show date in doc thumb

--- src-cljs/frontend/components/doc_viewer.cljs
+++ src-cljs/frontend/components/doc_viewer.cljs
@@ -7,6 +7,7 @@
             [frontend.auth :as auth]
             [frontend.components.common :as common]
             [frontend.datascript :as ds]
+            [frontend.datetime :as datetime]
             [frontend.db :as fdb]
             [frontend.state :as state]
             [frontend.urls :as urls]
@@ -64,7 +65,10 @@
                [:span.recent-doc-title
                 (str (:document/name doc "Untitled")
                      (when (= "Untitled" (:document/name doc))
-                       (str " " (:db/id doc))))]]))))]))))
+                       (str " " (:db/id doc))))
+                (when (:last-updated-instant doc)
+                  [:span.recent-doc-timestamp
+                   (str " " (datetime/medium-consistent-date (:last-updated-instant doc)))])]]))))]))))

 (defn dummy-docs [current-doc-id doc-count]
   (repeat doc-count {:db/id current-doc-id


For now, filter on only symbol namespaces

Planck is incorrecly passing string names to
eval-str, which can cause them to be put
in as namespaces in the analysis cache

--- planck-cljs/src/planck/repl.cljs
+++ planck-cljs/src/planck/repl.cljs
@@ -99,7 +99,7 @@
 (defn- all-ns
   "Returns a sequence of all namespaces."
   []
-  (keys (::ana/namespaces @st)))
+  (filter symbol? (keys (::ana/namespaces @st))))

 (defn- drop-macros-suffix
   [ns-name]


[#3694] Ignore mixpanel/track http error when offline

Signed-off-by: Goran Jovic <fc686822162e6f379ea05b6f92d78d206147085c@gmail.com>

--- src/status_im/utils/mixpanel.cljs
+++ src/status_im/utils/mixpanel.cljs
@@ -29,7 +29,7 @@
                               props)})))

 (defn track [id label props]
-  (http/get (build-url id label props)))
+  (http/get (build-url id label props) nil identity))

 ;; Mixpanel events definition


Fixup 60517fd to provide API version (backwards-compatible)

--- src/taoensso/carmine/commands.clj
+++ src/taoensso/carmine/commands.clj
@@ -66,12 +66,12 @@
       (if-not varps
         `(defn ~(symbol fn-name)
            {:doc ~fn-docstring
-            :redis-api true}
+            :redis-api (or (:since ~refspec) true)}
            ~fn-params
            (protocol/send-request ~ps))
         `(defn ~(symbol fn-name)
            {:doc ~fn-docstring
-            :redis-api true}
+            :redis-api (or (:since ~refspec) true)}
            ~fn-params
            (protocol/send-request (into ~ps ~varps)))))))


Optimize multi-arity `return`

Optimize multi-arity `return`

--- src/taoensso/carmine/protocol.clj
+++ src/taoensso/carmine/protocol.clj
@@ -241,18 +241,23 @@
 (defmacro parse-nippy [thaw-opts & body]
   `(parse (with-meta identity {:thaw-opts ~thaw-opts}) ~@body))

-(defn return
+(def return
   "Takes values and returns them as part of next reply from Redis server.
   Unlike `echo`, does not actually send any data to Redis."
-  ([value & more] (encore/backport-run! return (cons value more)))
-  ([value]
-   (swap! (:req-queue *context*)
-     (fn [[_ q]]
-       [nil (conj q (with-meta [] ; Dummy request
-                      {:parser (parser-comp *parser* ; Nb keep context's parser
-                                 (with-meta identity {:dummy-reply value}))
-                       :expected-keyslot nil ; Irrelevant
-                       }))]))))
+  (let [return1
+        (fn [context value]
+          (swap! context
+            (fn [[_ q]]
+              [nil (conj q (with-meta [] ; Dummy request
+                             {:parser (parser-comp *parser* ; Nb keep context's parser
+                                        (with-meta identity {:dummy-reply value}))
+                              :expected-keyslot nil ; Irrelevant
+                              }))])))]
+    (fn
+      ([value] (return1 (:req-queue *context*) value))
+      ([value & more]
+       (encore/backport-run! (partial return1 (:req-queue *context*))
+         (cons value more))))))

 ;;;; Requests


add test for commodity api delete

add test for commodity api delete

--- test/clj_money/api/commodities_test.clj
+++ test/clj_money/api/commodities_test.clj
@@ -102,3 +102,27 @@
                                        (map :name)
                                        (into #{})))
             "The commodity is updated in the data store.")))))
+
+(deftest delete-a-commodity
+  (let [context (serialization/realize storage-spec commodities-context)
+        entity (find-entity context "Personal")
+        commodity (find-commodity context "USD")]
+    (testing "A user cannot delete a commodity from another user's entity"
+      (let [_ (is (thrown? ExceptionInfo
+                   (with-authentication (find-user context "jane@doe.com")
+                     (api/delete {:params {:id (:id commodity)}}))))
+            commodities (commodities/search storage-spec {:entity-id (:id entity)})]
+        (is (= #{"USD"} (->> commodities
+                             (map :symbol)
+                             (into #{})))
+            "The commodity is stil retrievable after attempt to delete")))
+    (testing "A user can delete a commodity from their entity"
+      (let [response (with-authentication (find-user context "john@doe.com")
+                       (api/delete {:params {:id (:id commodity)}}))
+            commodities (commodities/search storage-spec {:entity-id (:id entity)})]
+        (is (= 204 (:status response)) "The response is successful and empty")
+        (is (not ((->> commodities
+                       (map :symbol)
+                       (into #{}))
+                  "USD"))
+            "The commodity is not retrieved after delete")))))


Add CORS header. Add buildNumber attribute to BuildSummaries

--- src/lambdaui/dummy_data.clj
+++ src/lambdaui/dummy_data.clj
@@ -1,7 +1,8 @@
 (ns lambdaui.dummy-data
-  (:require [ring.util.response :refer [response]]))
+  (:require [ring.util.response :refer [response header]]))

 (def summaries {:summaries [{:buildId   1
+                             :buildNumber 1                 ; TODO differentiate between build Number (alias) and id?
                              :state     :running
                              :startTime "11pm"              ; TODO decide on format (ISO timestamp?)
                              :duration  "30 seconds"        ; TODO decide on format (maybe seconds?)
@@ -13,5 +14,5 @@

 (defn hello-response [] (response "haallo welt"))
-(defn build-summaries [] (response summaries))
+(defn build-summaries [] (header (response summaries) "Access-Control-Allow-Origin" "*"))


need to check the ref typing

need to check the ref typing

--- src/latte/kernel/typing.clj
+++ src/latte/kernel/typing.clj
@@ -137,7 +137,7 @@
                 ;; (println "sort2' = " sort2' " sort? " (stx/sort? sort2'))
                 (if (not (stx/sort? sort2'))
                   [:ko {:msg "Not a valid codomain type in product (not a sort)" :term B :type sort2}]
-                  [:ok sort2'])))))))))
+                  [:ok sort2])))))))))

 (example
  (type-of-term {} [] '(Π [x ✳] x)) => '[:ok ✳])
@@ -269,6 +269,9 @@
       (defenv/special? ddef)
       (throw (ex-info "Special should not occur at typing time (please report)"
                       {:special ddef :term (list* name args)}))
+      (defenv/notation? ddef)
+      (throw (ex-info "Notation should not occur at typing time (please report)"
+                      {:notation ddef :term (list* name args)}))
       (and (defenv/theorem? ddef)
            (= (:proof ddef) false))
       [:ko {:msg "Theorem has no proof." :thm-name (:name ddef)}]


file copy not working.

file copy not working.

--- src/leiningen/new/closp.clj
+++ src/leiningen/new/closp.clj
@@ -16,6 +16,7 @@

 (defn generate-project [name feature-params data]
+  ;(io/copy (io/reader (io/resource "leiningen/new/closp/img/loading.gif")) (io/file "./loading.gif"))
   (binding [*name* name
             *render* #((renderer "closp") % data)]
     (reset! features (-> feature-params))
@@ -65,12 +66,13 @@
                [(str "resources/public/css/screen.css") (*render* "resources/public/css/screen.css")]
                [(str "resources/public/css/home.css") (*render* "resources/public/css/home.css")]

+               ["resources/public/img/loading.gif" (render "resources/public/img/loading.gif")]
+
                ;"resources/public/img/browser_carousel_small.jpg"
                ;"resources/public/img/"
                ;"resources/public/img/"
                ;"resources/public/img/"

-               ["resources/public/img/browser_carousel_small.jpg" (io/resource "loading.gif")]
                ;[(str "resources/public/img/channel_carousel_small.jpg") (*render* "resources/public/img/channel_carousel_small.jpg")]
                ;[(str "resources/public/img/loading.jpg") (*render* "resources/public/img/loading.jpg")]
                ;[(str "resources/public/img/template_carousel_small.jpg") (*render* "resources/public/img/template_carousel_small.jpg")]


Added data-readers map to puget.data ns.

--- src/puget/data.clj
+++ src/puget/data.clj
@@ -153,3 +153,13 @@
   ^URI
   [^String uri]
   (URI. uri))
+
+
+
+;; DATA READERS
+
+(def data-readers
+  "Map of data readers supported by Puget. Merge project-specific readers into
+  this map."
+  {'bin read-bin
+   'uri read-uri})


random generate boxes

random generate boxes

--- desktop/src-common/clo_runner/core.clj
+++ desktop/src-common/clo_runner/core.clj
@@ -25,42 +25,38 @@
                                                 0)
                                             (assoc entity :x (- (:x entity) 30))
                                             (assoc entity :x 0))))
-(defn move-box [entity]
+
+
+(defn create-box []
+  (assoc (texture "box.jpg") :x 859 :y (rand-int 500) :width 59 :height 59))
+
+(defn move-box [entity]
    (assoc entity :x (- (:x entity) 3)))

 (defn move-boxes [boxes]
   (vec (map move-box boxes)))

 (defn moving [entities]
-      (let [backgr (first entities)
-            player (last entities)
-            boxes (move-boxes (vec (drop 1 (drop-last entities))))]
-
-     ;;   (->
-     ;;     (conj [] backgr)
-     ;;     (apply conj boxes)
-    ;;      (conj player))
-       (conj (apply conj (conj [] backgr) boxes) player)))
+  (let [backgr (first entities)
+        player (last entities)
+        boxes (try
+                (move-boxes (vec (drop 1 (drop-last entities))))
+                (catch NullPointerException e
+                  []))]
+    (conj (apply conj (conj [] backgr) boxes) player)))

 (defscreen main-screen
   :on-show
   (fn [screen entities]
     (update! screen :renderer (stage))
+    (add-timer! screen :spawn-enemy 0 2)
     (let [
-          ; load a sprite sheet from your resources dir
           sheet (texture "bird.png")
           birdy (texture! sheet :split (/ 506 3) (/ 918 5))

           background (texture "background.jpg")
-          background (assoc background :x 0 :y 0 :width 800 :height 600)
-
-          box (texture "box.jpg")
-          box-image (assoc box :x 100 :y 100 :width 59 :height 59)
-          box-image2 (assoc box :x 100 :y 400 :width 59 :height 59)
-          box-image3 (assoc box :x 250 :y 100 :width 59 :height 59)
-          box-image4 (assoc box :x 500 :y 300 :width 59 :height 59)
-
+          background (assoc background :x 0 :y 0 :width 800 :height 600)

           player-image (texture (aget birdy 0 0))
           ;;images (->
@@ -76,30 +72,24 @@
                 ;;   (conj (texture (aget birdy 1 3)))
                 ;;   (conj (texture (aget birdy 1 4))))
      ;;     player-image (assoc player-image :moving (animation 0.15 images))
-          player-image (assoc player-image :x 10 :y 10 :width 59 :height 59)]
-      ; return a new entities vector with player-image inside of it
-      [background box-image box-image2 box-image3 box-image4 player-image]))
-     ;;[background box-image player-image]))
-
+          player-image (assoc player-image :x 10 :y 10 :width 59 :height 59)]
+      [background player-image]))

   :on-render
   (fn [screen entities]
     (clear!)
-   ;; (merge (first entities) (animation->texture screen ((first entities) :moving)))
     (render! screen (moving entities)))
-
-
- ;;dodavanje na on-timer
-
-
+
+  :on-timer
+  (fn [screen entities]
+    :spawn-enemy (conj (conj (vec (drop-last entities)) (create-box)) (last entities)))

   :on-key-down
   (fn [screen entities]
     (->
       (drop-last entities)
       (vec)
-      (conj (move screen (last entities)))))
-)
+      (conj (move screen (last entities))))))

 (defgame clo-runner-game


oops - forgot to :use logging

oops - forgot to :use logging

--- dada-core/src/main/clojure/org/dada/core/dql.clj
+++ dada-core/src/main/clojure/org/dada/core/dql.clj
@@ -1,6 +1,7 @@
 (ns
  org.dada.core.dql
  (:use [org.dada.core])
+ (:use clojure.contrib.logging)
  (:use org.dada.core.PivotModel)
  (:import [clojure.lang
 	   ]


Use fast version of select peers when there are less peers than max.

--- src/onyx/peer/operation.clj
+++ src/onyx/peer/operation.clj
@@ -30,9 +30,11 @@
   "Stably select n peers using our id and the downstream task ids.
   If a peer is added or removed, the set can only change by one value at max"
   [id all-peers n]
-  (take n
-        (sort-by (fn [peer-id] (hash [id peer-id]))
-                 all-peers)))
+  (if (<= (count all-peers) n)
+    all-peers
+    (take n
+          (sort-by (fn [peer-id] (hash [id peer-id]))
+                   all-peers))))

 (defn peer-link
   [{:keys [onyx.core/state] :as event} peer-id]


Re-add required riemann metrics lifecyle require

--- src/onyx_benchmark/peer.clj
+++ src/onyx_benchmark/peer.clj
@@ -2,6 +2,7 @@
   (:require [clojure.core.async :refer [chan dropping-buffer <!!]]
             [onyx.lifecycle.metrics.metrics]
             [onyx.lifecycle.metrics.timbre]
+            [onyx.lifecycle.metrics.riemann]
             [onyx.peer.pipeline-extensions :as p-ext]
             [taoensso.timbre :refer  [info warn trace fatal error] :as timbre]
             [onyx.plugin.bench-plugin]


Bad null pointer fix.

Bad null pointer fix.

--- src/onyx_benchmark/peer.clj
+++ src/onyx_benchmark/peer.clj
@@ -56,11 +56,11 @@
                 start (System/currentTimeMillis)
                 _ (reset! retry-counter 0)
                 latencies (:latencies latency)
-                latency-00 (float (/ (get latencies 0.0 0) 1000000))
-                latency-05 (float (/ (get latencies 0.5 0) 1000000))
-                latency-095 (float (/ (get latencies 0.95 0) 1000000))
-                latency-099 (float (/ (get latencies 0.99 0) 1000000))
-                latency-0999 (float (/ (get latencies 0.999 0) 1000000))]
+                latency-00 (float (/ (or (get latencies 0.0) 0) 1000000))
+                latency-05 (float (/ (or (get latencies 0.5) 0) 1000000))
+                latency-095 (float (/ (or (get latencies 0.95) 0) 1000000))
+                latency-099 (float (/ (or (get latencies 0.99) 0) 1000000))
+                latency-0999 (float (/ (or (get latencies 0.999) 0) 1000000))]
             (info "-> " throughput ", retries: " retry-cnt ", latency " latency " <-")
             (info "-> " latency-00 latency-05 latency-095 latency-099 latency-0999)
             (r/send-event client {:service "onyx-retry" :state "ok" :metric retry-cnt :tags ["benchmark"]})


Bad commit.

Bad commit.

--- src/onyx_benchmark/peer.clj
+++ src/onyx_benchmark/peer.clj
@@ -1,4 +1,4 @@
-cd69211780584b9f5bfae11f87f5b7655b178e19 onyx-benchmark.peer
+(ns onyx-benchmark.peer
   (:require [clojure.core.async :refer [chan dropping-buffer <!!]]
             [clojure.data.fressian :as fressian]
             [riemann.client :as r]


Add missing ug -> ugen replacements in ugen repl helper fns.

--- src/overtone/repl/ugens.clj
+++ src/overtone/repl/ugens.clj
@@ -77,9 +77,9 @@
   specified terms. Prints out a list of summaries of each matching ugen.
   If only one matching ugen is found, prints out full docstring.

-  (find-ug foo)         ;=> finds all ugens containing the word foo
-  (find-ug foo \"bar\") ;=> finds all ugens containing the words foo AND bar
-  (find-ug #\"foo*\")   ;=> finds all ugens matching the regex foo*"
+  (find-ugen foo)         ;=> finds all ugens containing the word foo
+  (find-ugen foo \"bar\") ;=> finds all ugens containing the words foo AND bar
+  (find-ugen #\"foo*\")   ;=> finds all ugens matching the regex foo*"
   [& search-terms]
   (let [search-terms     (map #(if (symbol? %) (str %) %) search-terms)
         specs            (find-matching-ugen-specs search-terms)
@@ -90,32 +90,32 @@
      (println "Sorry, unable to find a matching ugen.")

      (= 1 (count specs))
-     (print-ug-docs specs)
+     (print-ugen-docs specs)

      :default
-     (print-ug-summaries specs longest-name-len))))
+     (print-ugen-summaries specs longest-name-len))))

 (defmacro find-ugen-doc
   "Find a ugen containing the specified terms which may be either strings or
   regexp patterns. Will search the ugen's docstrings for occurrances of all the
   specified terms. Prints out each ugens full docstring. Similar to find-doc.

-  (find-ug-doc foo)         ;=> finds all ugens containing the word foo
-  (find-ug-doc \"foo\" bar) ;=> finds all ugens containing the words foo
+  (find-ugen-doc foo)         ;=> finds all ugens containing the word foo
+  (find-ugen-doc \"foo\" bar) ;=> finds all ugens containing the words foo
                                     AND bar
-  (find-ug-doc #\"foo*\")   ;=> finds all ugens matching the regex foo*"
+  (find-ugen-doc #\"foo*\")   ;=> finds all ugens matching the regex foo*"
   [& search-terms]
   (let [search-terms (map #(if (symbol? %) (str %) %) search-terms)
         specs        (find-matching-ugen-specs search-terms)]
     (if (empty? specs)
       (println "Sorry, unable to find a matching ugen.")
-      (print-ug-docs specs))))
+      (print-ugen-docs specs))))

 (defmacro ugen-doc
   "Print documentation for ugen with name ug-name"
   [ug-name]
   `(if-let [spec# (fetch-ugen-spec '~ug-name)]
-     (print-ug-docs [spec#])
+     (print-ugen-docs [spec#])
      (println "Sorry, unable to find ugen with name")))

 (defmacro odoc


Fix disable-erroneous-popstate!

Fix disable-erroneous-popstate!

We were failing to pass along the event. The previous version of the
Closure library happened to not look at the event, but the new version
does, so we'd better provide it.

(Also, removing an arity of `set-current-token!` that isn't used.)

--- src-cljs/frontend/history.cljs
+++ src-cljs/frontend/history.cljs
@@ -34,8 +34,8 @@

 (defn set-current-token!
   "Lets us keep track of the history state, so that we don't dispatch twice on the same URL"
-  [history-imp & [token]]
-  (set! (.-_current_token history-imp) (or token (.getToken history-imp))))
+  [history-imp]
+  (set! (.-_current_token history-imp) (.getToken history-imp)))

 (defn setup-dispatcher! [history-imp]
   (events/listen history-imp goog.history.EventType.NAVIGATE
@@ -62,7 +62,7 @@
                    #(if (= (.getToken history-imp)
                            (.-_current_token history-imp))
                       (utils/mlog "Ignoring duplicate dispatch event to" (.getToken history-imp))
-                      (.onHistoryEvent_ history-imp)))))
+                      (.onHistoryEvent_ history-imp %)))))

 (defn route-fragment
   "Returns the route fragment if this is a route that we've don't dispatch


Recursive backtracker algorithm

Recursive backtracker algorithm

--- src/snergly/algorithms.cljc
+++ src/snergly/algorithms.cljc
@@ -13,7 +13,8 @@
     "sidewinder"
     "aldous-broder"
     "wilsons"
-    "hunt-and-kill"})
+    "hunt-and-kill"
+    "recursive-backtracker"})

 ;; necessary because (.indexOf) doesn't work properly in ClojureScript.
 (defn cljs-index-of [s val]
@@ -208,6 +209,34 @@
             (when result-chan (async/close! result-chan))
             new-grid)
           (recur new-grid next-coord))))))
+
+(defn recursive-backtracker-step [grid stack]
+  (let [grid (g/begin-step grid)
+        current-coord (first stack)
+        current-cell (g/grid-cell grid current-coord)
+        unvisited-neighbors (filter #(empty? (:links (g/grid-cell grid %)))
+                                    (g/cell-neighbors current-cell))]
+    (if (empty? unvisited-neighbors)
+      [grid (rest stack)]
+      (let [next-current (rand-nth unvisited-neighbors)]
+        [(g/link-cells grid current-cell next-current)
+         (conj stack next-current)]))))
+
+(s/defn maze-recursive-backtracker
+  ([grid :- g/Grid] (maze-recursive-backtracker grid nil))
+  ([grid :- g/Grid result-chan]
+    (go-loop [grid (assoc grid :algorithm-name "recursive-backtracker")
+              stack (list (g/random-coord grid))]
+             (when (and result-chan (g/changed? grid))
+               (println "reporting")
+               (async/>! result-chan grid))
+             (if (empty? stack)
+               (do
+                 (when result-chan (async/close! result-chan))
+                 grid)
+               (let [[new-grid new-stack] (recursive-backtracker-step grid stack)]
+                 (recur new-grid new-stack)
+                 )))))

 (s/defn find-distances :- g/Distances
   ([grid :- g/Grid start :- g/CellPosition] (find-distances grid start nil))
@@ -270,7 +299,8 @@
    "sidewinder" maze-sidewinder
    "aldous-broder" maze-aldous-broder
    "wilsons" maze-wilsons
-   "hunt-and-kill" maze-hunt-and-kill})
+   "hunt-and-kill" maze-hunt-and-kill
+   "recursive-backtracker" maze-recursive-backtracker})

 #?(:clj
    (defn synchronous-fn [func]


Demonstrate a mutation

Demonstrate a mutation

--- test-cljs/frontend/test_send.cljs
+++ test-cljs/frontend/test_send.cljs
@@ -345,7 +345,12 @@
                          aliasing/read))}))

 (def resolvers
-  {:root/user
+  {'do/something
+   (fn [context ast]
+     (let [do-something (get-in context [:apis :do-something])]
+       (do-something (:params ast))))
+
+   :root/user
    (fn [context ast]
      (resolve* (assoc context
                       :channel (chan)
@@ -417,17 +422,27 @@
                                             :species :pet-species/dog
                                             :description "pug"}]}
           data-chan (resolve {:channel (chan)
-                              :apis {:get-user (memoize
-                                                (fn [params]
-                                                  (p/do*
-                                                   (swap! api-calls conj [:get-user params])
-                                                   (get users params))))
-                                     :get-user-pets (memoize
-                                                     (fn [params]
-                                                       (p/do*
-                                                        (swap! api-calls conj [:get-user-pets params])
-                                                        (get user-pets params))))}}
-                             resolvers '[{(:root/user {:user/name "nipponfarm"})
+                              :apis {:get-user
+                                     (memoize
+                                      (fn [params]
+                                        (p/do*
+                                         (swap! api-calls conj [:get-user params])
+                                         (get users params))))
+
+                                     :get-user-pets
+                                     (memoize
+                                      (fn [params]
+                                        (p/do*
+                                         (swap! api-calls conj [:get-user-pets params])
+                                         (get user-pets params))))
+
+                                     :do-something
+                                     (fn [params]
+                                       (p/do*
+                                        (swap! api-calls conj [:do-something params])
+                                        "Did something."))}}
+                             resolvers '[(do/something {:very "important"})
+                                         {(:root/user {:user/name "nipponfarm"})
                                           [:user/name
                                            :user/favorite-color
                                            :user/favorite-number
@@ -443,7 +458,8 @@
       (take!
        (async/into #{} data-chan)
        (fn [v]
-         (is (= #{{:root/user {:user/name "nipponfarm"}}
+         (is (= #{{'do/something "Did something."}
+                  {:root/user {:user/name "nipponfarm"}}
                   {:root/user {:user/favorite-color :color/blue}}
                   {:root/user {:user/favorite-number 42}}
                   {:root/user {:user/vehicle {:vehicle/make "Toyota"
@@ -456,7 +472,8 @@
                   {:jamie {:user/name "jburnford"}}
                   {:jamie {:user/favorite-color :color/red}}}
                 v))
-         (is (= [[:get-user {:name "nipponfarm"}]
+         (is (= [[:do-something {:very "important"}]
+                 [:get-user {:name "nipponfarm"}]
                  [:get-user-pets {:name "nipponfarm"}]
                  [:get-user {:name "jburnford"}]]
                 @api-calls))


Remove ++expand-symbol-cljs-spec-bug++ fix

--- src/spec_tools/visitor.cljc
+++ src/spec_tools/visitor.cljc
@@ -43,14 +43,6 @@
 (defn- expand-spec-ns [x]
   (if-not (namespace x) (symbol "clojure.core" (name x)) x))

-(defn- ++expand-symbol-cljs-spec-bug++ [x]
-  (if (seq? x)
-    (let [[k & rest] x]
-      (cons k (if (= k 'cljs.spec.alpha/tuple)
-                (map expand-spec-ns rest)
-                rest)))
-    (expand-spec-ns x)))
-
 (defmulti visit
   "Walk a spec definition. Takes two arguments, the spec and the accept
   function, and returns the result of calling the accept function.
@@ -89,12 +81,12 @@

 (defmethod visit 'clojure.spec.alpha/every [spec accept]
   (let [[_ inner-spec] (extract-form spec)]
-    (accept 'clojure.spec.alpha/every spec [(visit (++expand-symbol-cljs-spec-bug++ inner-spec) accept)])))
+    (accept 'clojure.spec.alpha/every spec [(visit inner-spec accept)])))

 (defmethod visit 'clojure.spec.alpha/every-kv [spec accept]
   (let [[_ inner-spec1 inner-spec2] (extract-form spec)]
     (accept 'clojure.spec.alpha/every-kv spec (mapv
-                                          #(visit (++expand-symbol-cljs-spec-bug++ %) accept)
+                                          #(visit % accept)
                                           [inner-spec1 inner-spec2]))))

 (defmethod visit 'clojure.spec.alpha/coll-of [spec accept]
@@ -121,7 +113,7 @@

 (defmethod visit 'clojure.spec.alpha/? [spec accept]
   (let [[_ inner-spec] (extract-form spec)]
-    (accept 'clojure.spec.alpha/? spec [(visit (++expand-symbol-cljs-spec-bug++ inner-spec) accept)])))
+    (accept 'clojure.spec.alpha/? spec [(visit inner-spec accept)])))

 (defmethod visit 'clojure.spec.alpha/alt [spec accept]
   (let [[_ & {:as inner-spec-map}] (extract-form spec)]


* script/test: add identity benchmark

* script/test: add identity benchmark

--- benchmark/cljs/benchmark_runner.cljs
+++ benchmark/cljs/benchmark_runner.cljs
@@ -5,6 +5,8 @@
 (def println print)

 (set! *print-fn* js/print)
+
+(simple-benchmark [x 1] (identity x) 1000000)

 (println ";; array-reduce & ci-reduce")
 (def arr (let [arr (array)]


CLJS-357: large PersistentVector benchmarks

Benchmarks for the following:

* building a large vector without using transients (to get an idea of
  conj perf),

* conjing onto a large vector in a situation where this involves a
  push-tail operation,

* associng in non-tail position in a large vector,

* popping a large vector where this involves a pop-tail op.

--- benchmark/cljs/benchmark_runner.cljs
+++ benchmark/cljs/benchmark_runner.cljs
@@ -50,6 +50,13 @@
 (simple-benchmark [coll (seq [1 2 3])] (rest coll) 1000000)
 (simple-benchmark [coll (seq [1 2 3])] (-rest coll) 1000000)
 (simple-benchmark [coll (seq [1 2 3])] (next coll) 1000000)
+(println)
+
+(println ";;; large vector ops")
+(simple-benchmark [] (reduce conj [] (range 40000)) 100)
+(simple-benchmark [coll (reduce conj [] (range (+ 32768 32)))] (conj coll :foo) 1000000)
+(simple-benchmark [coll (reduce conj [] (range 40000))] (assoc coll 123 :foo) 1000000)
+(simple-benchmark [coll (reduce conj [] (range (+ 32768 33)))] (pop coll) 1000000)
 (println)

 (println ";;; transients")


* benchmark/cljs/benchmark_runner.cljs: add PHM benchmark - update existing key - not bad

--- benchmark/cljs/benchmark_runner.cljs
+++ benchmark/cljs/benchmark_runner.cljs
@@ -100,6 +100,12 @@
 (simple-benchmark [coll pmap] (get coll :f0) 1000000)
 (simple-benchmark [coll pmap] (-lookup coll :f0 nil) 1000000)
 (simple-benchmark [coll pmap] (assoc coll :g0 32) 1000000)
+(simple-benchmark [coll pmap]
+                  (loop [i 0 m coll]
+                    (if (< i 1000000)
+                      (recur (inc i) (assoc m :a 1))
+                      m))
+                  1)
 (simple-benchmark [coll cljs.core.PersistentHashMap/EMPTY] (assoc coll :f0 1) 1000000)
 (println)


setPosition on dot-nodes

setPosition on dot-nodes

--- examples/lesson-carousel-starter-kit/src/carousel/core.cljs
+++ examples/lesson-carousel-starter-kit/src/carousel/core.cljs
@@ -19,11 +19,17 @@
                (setProperty "zIndex" "2")))

 (defn decorate-dots [dots-node]
-  (doseq [dot-node (.. dots-node getChildren)]
-    (.. (DOMElement. dot-node)
-        (setProperty "borderRadius"  "5px")
-        (setProperty "border"  "2px solid white")
-        (setProperty "boxSizing"  "border-box"))))
+  (let [dot-nodes (.. dots-node getChildren)]
+    (doseq [dot-node dot-nodes]
+      (.. (DOMElement. dot-node)
+          (setProperty "borderRadius"  "5px")
+          (setProperty "border"  "2px solid white")
+          (setProperty "boxSizing"  "border-box")))
+
+    (doseq [n (range (count dot-nodes))
+            :let [dot-node (nth dot-nodes n)
+                  start-x 100]]
+      (.. dot-node (setPosition (+ start-x (* n 10)) 0 0 )))))

 (defn create-dots [root-node]
   (let [root-dot (.. root-node addChild)]


Remove test case. These test cases are for the original table UI and should be removed.

--- test/greenyet/view/table_test.clj
+++ test/greenyet/view/table_test.clj
@@ -36,14 +36,15 @@
                                 "<!-- BODY -->"
                                 []))))

-  (testing "shows only first host if all are green for the given environment and system"
-    (let [html (sut/render {(a-host-entry "last_host" 42) (a-status)
-                            (a-host-entry "first_host" 0) (a-status)
-                            (a-host-entry "second_host" 10) (a-status)}
-                           nil
-                           "<!-- BODY -->"
-                           [])]
-      (is (= 1
-             (count (re-seq #"class=\"host " html))))
-      (is (re-matches #".*first_host.*"
-                      html)))))
+  ; (testing "shows only first host if all are green for the given environment and system"
+  ;   (let [html (sut/render {(a-host-entry "last_host" 42) (a-status)
+  ;                           (a-host-entry "first_host" 0) (a-status)
+  ;                           (a-host-entry "second_host" 10) (a-status)}
+  ;                          nil
+  ;                          "<!-- BODY -->"
+  ;                          [])]
+  ;     (is (= 1
+  ;            (count (re-seq #"class=\"host " html))))
+  ;     (is (re-matches #".*first_host.*"
+  ;                     html))))
+)


Added tests for entity results reduction

--- test/prop_shop/data/base_test.clj
+++ test/prop_shop/data/base_test.clj
@@ -6,3 +6,109 @@
 (deftest test-database-connection
   (testing "Database Connection"
     (is (not (nil? conn)))))
+
+; Needed to fake out the reduce-entity method checks
+(deftype E [contents]
+    clojure.lang.IPersistentMap
+  (assoc [_ k v]
+    (E. (.assoc contents k v)))
+  (assocEx [_ k v]
+    (E. (.assocEx contents k v)))
+  (without [_ k]
+    (E. (.without contents k)))
+
+  java.lang.Iterable
+  (iterator [this]
+    (.iterator contents))
+
+  clojure.lang.Associative
+  (containsKey [_ k]
+    (.containsKey contents k))
+  (entryAt [_ k]
+    (.entryAt contents k))
+
+  clojure.lang.IPersistentCollection
+  (count [_]
+    (count contents))
+  (cons [_ o]
+    (E. (.cons contents o)))
+  (empty [_]
+    (empty contents))
+  (equiv [_ o]
+    (and (isa? (class o) E)
+         (.equiv contents o)))
+
+  clojure.lang.Seqable
+  (seq [_]
+    (seq contents))
+
+  clojure.lang.ILookup
+  (valAt [_ k]
+    (.valAt contents k))
+  (valAt [_ k not-found]
+    (.valAt contents k not-found))
+
+  datomic.Entity)
+
+(def mock-reduce-entity-data
+  "Provides a tree data structure to be used to test the reduce-entity method."
+  (E.
+    {:db/id 34
+     :name "Juan Valdez"
+     :age 34
+     :married? true
+     :children #{(E. {:db/id 44 :name "Dos Valdez"})
+                 (E. {:db/id 54 :name "Lil Valdez"})
+                 (E. {:db/id 64 :name "Exxon Valdez"})}
+     :lucky-numbers #{7 12 18 22 31 55}
+     :aliases #{"John" "Joowan" "Tabitha"}
+     :father (E. {:db/id 74 :name "Bob Valdez"})}))
+
+(comment
+  "As a reminder, this is what to test for:
+
+  {:field nil}          ;;If field is primitive it is included.  If field is reference it is not included.
+  {:field :ignore}      ;;Field is ignored.
+  {:field {}}           ;;If field is reference the entity is resolved with only primitive fields
+  {:field {:field ...}} ;;If field is reference the entity is with the embedded path-map instructions.
+  {:field :id}          ;;If field is reference only the id of the entity is included as a map key/value {:id 1234}.
+  {:* ...}              ;;Allows the use of the wild card to apply rule to any non-defined field.  For example,
+                        ;;{:field :id} is the same as {:field {:* :ignore}}")
+
+(deftest test-reduce-entity-empty-map
+  (testing "Testing reduce-entity with empty path-map"
+    (let [result (reduce-entity mock-reduce-entity-data {})]
+      (is (:id result))
+      (is (:name result))
+      (is (:age result))
+      (is (:married? result))
+      (is (nil? (:children result)))
+      (is (= 6 (count (:lucky-numbers result))))
+      (is (= 3 (count (:aliases result))))
+      (is (nil? (:father result))))))
+
+
+(deftest test-reduce-entity-ignores
+  (testing "Testing reduce-entity with empty path-map"
+    (let [result (reduce-entity mock-reduce-entity-data {:name :ignore :aliases :ignore})]
+      (is (:id result))
+      (is (nil? (:name result)))
+      (is (:age result))
+      (is (:married? result))
+      (is (nil? (:children result)))
+      (is (= 6 (count (:lucky-numbers result))))
+      (is (nil?  (:aliases result)))
+      (is (nil? (:father result))))))
+
+
+(deftest test-reduce-entity-wildcard-ignores
+  (testing "Testing reduce-entity with empty path-map"
+    (let [result (reduce-entity mock-reduce-entity-data {:* :ignore})]
+      (is (:id result))
+      (is (nil? (:name result)))
+      (is (nil? (:age result)))
+      (is (nil? (:married? result)))
+      (is (nil? (:children result)))
+      (is (nil? (:lucky-numbers result)))
+      (is (nil? (:aliases result)))
+      (is (nil? (:father result))))))


fixes on some util functions

fixes on some util functions

--- src/cljs/daveconservatoire/site/ui/util.cljs
+++ src/cljs/daveconservatoire/site/ui/util.cljs
@@ -2,6 +2,7 @@
   (:require [om.next :as om :include-macros true]
             [daveconservatoire.site.routes :as r :refer [routes]]
             [om.util :as om-u]
+            [goog.string :as gstr]
             [cljs.spec :as s]))

 (defn html-attr-merge [a b]
@@ -23,11 +24,14 @@
   :args (s/cat :attrs map?)
   :ret map?)

-(defn props->html [attrs props]
-  (->> (merge-with html-attr-merge attrs props)
-       (parse-route)
-       (into {} (filter (fn [[k _]] (not (namespace k)))))
-       (clj->js)))
+(defn props->html
+  ([props] (props->html {} props))
+  ([attrs props]
+   (->> (dissoc props :react-key)
+        (merge-with html-attr-merge attrs)
+        (parse-route)
+        (into {} (filter (fn [[k _]] (not (namespace k)))))
+        (clj->js))))

 (s/fdef props->html
   :args (s/cat :attrs map?
@@ -75,7 +79,7 @@

 (defn current-uri-slug? [handler slug]
   (= (r/current-handler) {::r/handler handler
-                          ::r/params  {::r/slug slug}}))
+                          ::r/params  {::r/slug (gstr/trim slug)}}))

 (s/fdef current-uri-slug?
   :args (s/cat :handler ::r/handler :slug ::r/slug)


Refined the granule indexes we will search when no collection identifier is provided.

--- src/cmr/search/data/elastic_search_index.clj
+++ src/cmr/search/data/elastic_search_index.clj
@@ -49,7 +49,7 @@
   [context query]
   (let [coll-concept-ids (ex/extract-collection-concept-ids query context)]
     (if (empty? coll-concept-ids)
-      "_all"
+      (format "%d_c*,%d_small_collections" index-set-id index-set-id)
       (s/join "," (collection-concept-ids->index-names context coll-concept-ids)))))

 (defn concept-type->index-info


More idiomatic usage in data.security.

More idiomatic usage in data.security.

--- src/vault/data/security.clj
+++ src/vault/data/security.clj
@@ -26,7 +26,7 @@
     (when-not blob
       (throw (IllegalStateException.
                (str "No public key blob stored for " id))))
-    (when-not (= :pgp/public-key (:data/type pubkey-blob))
+    (when (not= :pgp/public-key (:data/type pubkey-blob))
       (throw (IllegalStateException.
                (str "Blob " id " is not a PGP public key"))))
     (first (:data/values pubkey-blob))))
@@ -41,9 +41,10 @@
   (let [pubkey (load-pubkey store pubkey-id)
         privkey (privkeys (pgp/key-id pubkey))
         pgp-sig (pgp/sign data privkey)]
-    {:key pubkey-id
-     :signature pgp-sig
-     :vault.data/type :vault/signature}))
+    (assoc
+      (edn-data/typed-map :vault/signature)
+      :key pubkey-id
+      :signature pgp-sig)))

 (defn blob-signer


Only update data if file hash has changed.

--- src/cavm/h2.clj
+++ src/cavm/h2.clj
@@ -35,11 +35,10 @@
 (declare experiment_sources features probes scores experiments exp_samples)

 (defentity cohorts)
-(defentity sources
-  (many-to-many experiment_sources experiments))
+(defentity sources)

 (defentity experiments
-  (many-to-many experiment_sources sources)
+  (many-to-many sources :experiment_sources)
   (has-many exp_samples)
   (has-many probes))

@@ -205,11 +204,12 @@
 ; Probemap declarations
 ;

-(declare probemap_probes probemap_positions probemap_genes)
+(declare probmaps probemap_probes probemap_positions probemap_genes)
 (defentity probemap_sources)

 (defentity probemaps
-  (has-many probemap_probes))
+  (has-many probemap_probes)
+  (many-to-many sources :probemap_sources))

 (defentity probemap_probes
   (belongs-to probemaps)
@@ -249,9 +249,6 @@

 (def ^:private probemaps-defaults
   (into {} (map #(vector % nil) probemaps-columns)))
-
-(declare probemaps)
-(defentity probemap_sources)

 (def ^:private probemaps-meta
   {:table probemaps
@@ -516,7 +513,8 @@
     (unparse fmtr timestamp)))

 (defn- fmt-time [file-meta]
-  (assoc file-meta :time (format-timestamp (:time file-meta))))
+  (assoc file-meta :time
+         (. java.sql.Timestamp valueOf (format-timestamp (:time file-meta)))))

 (defn clean-sources []
   (delete sources
@@ -536,20 +534,37 @@
       (insert table
               (values {id-key id :sources_id fid})))))

+; work around h2 uppercase craziness
+; XXX review passing naming option to korma
+(defn- keys-lower [m]
+  (into {} (map #(vector (keyword (subs (clojure.string/lower-case (% 0)) 1)) (% 1)) m)))
+
+(defn- related-sources [table id]
+  (map keys-lower
+    (select table (join sources) (where {:id id}) (fields :sources.name :sources.hash :sources.time))))
+
 ; kdb/transaction will create a closure of our parameters,
 ; so we can't pass in the matrix seq w/o blowing the heap. We
 ; pass in a function to return the seq, instead.

-; XXX take feature data as well
-(defn load-exp [files metadata matrix-fn features]
-  (kdb/transaction
-    (let [matrix (matrix-fn)
-          exp (merge-m-ent experiments-meta metadata)]
-      (clear-by-exp exp)
-      (load-related-sources
-        experiment_sources :experiments_id exp (map fmt-time files))
-      (load-exp-samples exp (:samples (meta matrix)))
-      (load-exp-matrix exp matrix))))
+(defn load-exp
+  "Load matrix file and metadata. Skips the data load if file hashes are unchanged."
+  ([files metadata matrix-fn features]
+   (load-exp files metadata matrix-fn features false))
+
+  ([files metadata matrix-fn features force]
+   (kdb/transaction
+     (let [matrix (matrix-fn)
+           exp (merge-m-ent experiments-meta metadata)
+           files (map fmt-time files)]
+       (when (or force
+                 (not (= (set files) (set (related-sources experiments exp)))))
+         (println "loading data")
+         (clear-by-exp exp)
+         (load-related-sources
+           experiment_sources :experiments_id exp files)
+         (load-exp-samples exp (:samples (meta matrix)))
+         (load-exp-matrix exp matrix))))))

 ; XXX factor out common parts with merge, above?
 (defn del-exp [file]


Add TODO regarding lens library for core.config

--- src/yetibot/core/config.clj
+++ src/yetibot/core/config.clj
@@ -7,6 +7,10 @@
     [clojure.pprint :refer [pprint]]
     [clojure.edn :as edn]
     [clojure.string :refer [blank? split]]))
+
+
+;; TODO: is there a Clojure lens lib that could make accessing and getting
+;; updates from config easier and more idiomatic?

 (def config-path "config/config.edn")


spelling

spelling

--- examples/tutorial.clj
+++ examples/tutorial.clj
@@ -10,7 +10,7 @@
    :last-name "funke"
    :email "tobias.funke@gmail.com"})

-;; this is the raw way to define a lense
+;; this is the raw way to define a lens
 ;; you call lens/lens and give it a function
 ;; that takes a root value in this case a user
 ;; and returns a pair where the first value
@@ -49,7 +49,7 @@
 ;;     :email "tobias.funke@gmail.com"}

 ;; you can also define lenses using lens/getter-setter-lens
-;; wich makes a lens from a getter and a setter function
+;; which makes a lens from a getter and a setter function

 (def first-name2
   (lens/getter-setter-lens
@@ -60,7 +60,7 @@
 (= (lens/write user first-name  "Newname")
    (lens/write user first-name2 "Newname"))

-;; since using keywords to reference fields in maps is so commen
+;; since using keywords to reference fields in maps is so common
 ;; you can use them directly as lenses

 (= (lens/write user first-name  "Newname")
@@ -74,15 +74,15 @@
 ;; ========================================================
 ;; composition

-;; a critical feture of lenses are that they compose
+;; a critical future of lenses are that they compose
 ;; you can do this with the lens/comp-lenses
-;; this function takse a seq of lenses and combines them
+;; this function takes a seq of lenses and combines them

 (def user2
   {:first-name "tobias"
    :last-name "funke"
    :address {:city "bluethwill"
-             :address_line "sudden valy street 23"
+             :address_line "sudden vale street 23"
              :postcode "56321"}})

 (def user-city (lens/comp-lenses [:address :city]))
@@ -95,8 +95,8 @@
 (= (lens/view user2 [:address :postcode])
    "56321")

-;; so basicly you can use lenses just like you use
-;; the clojure *-in funcitons
+;; so basically you can use lenses just like you use
+;; the clojure *-in functions

 (= (get-in user2 [:address :city])
    (lens/view user2 [:address :city]))
@@ -113,12 +113,12 @@
 (def str->num (lens/iso-lens #(Integer/parseInt %) str))

 ;; iso-lens takes 2 functions one to convert it to a integer in this case
-;; and anather one to convert it back to a string
+;; and another one to convert it back to a string

 (lens/update user2 [:address :postcode str->num] inc)
 ;; {:last-name "funke",
 ;;  :first-name "tobias",
-;;  :address {:address_line "sudden valy street 23",
+;;  :address {:address_line "sudden vale street 23",
 ;;            :postcode "56322",
 ;;            :city "bluethwill"}}

@@ -128,7 +128,7 @@
 ;; extract

 ;; extract is a function that lets you transform a structure
-;; to a map of a diferent shape and later write back changes
+;; to a map of a different shape and later write back changes
 ;; that are done to the new map

 (def user-view
@@ -138,19 +138,19 @@
    :address_city [:address :city]})

 (= (lens/view user2 user-view)
-   {:address_line "sudden valy street 23",
+   {:address_line "sudden vale street 23",
     :last-name "funke",
     :first-name "tobias",
     :address_city "bluethwill"})

 (defn take-ower-town
-  "clame the town as you own"
+  "claim the town as you own"
   [user] ;; user in the user-view shape
   (assoc user :address_city (:first-name user)))

 (= (lens/update user2 user-view take-ower-town)
    {:last-name "funke", :first-name "tobias",
-    :address {:address_line "sudden valy street 23",
+    :address {:address_line "sudden vale street 23",
               :postcode "56321",
               :city "tobias"}})

@@ -378,7 +378,7 @@

 ;; first task! something simple
 ;; Lets change the name of all the authors to tobias funke in this xml document.
-;; This culd be accomplished by diggin down to the right elements and updating them
+;; This could be accomplished by digging down to the right elements and updating them
 ;; appropriately... but a lazier way would be to just walk all of the tree
 ;; and replace the contents of the elements with the author tag

@@ -387,18 +387,18 @@
 ;; and gives you a traversal of all nodes in the tree
 ;; EXAMPLE:

-;; sinse nodes in the
+;; since nodes in the

 (def xml-nodes (tree/pre-tree
                 [:content
-                 (travers/filtered map?) ; we dont want to list the strings
+                 (travers/filtered map?) ; we don't want to list the strings
                                          ; in the tree as nodes
                                          ; so we filter them here
                  ]))

 ;; xml nodes here is a lens/traversal that lets you view and modify
-;; nodes of the tree in a pre-walk fassion.
-;; (there is also a post-tree that lets you do it in a post-walk fassion)
+;; nodes of the tree in a pre-walk fashion.
+;; (there is also a post-tree that lets you do it in a post-walk fashion)

 ;; ok so lets shrink the nodes we are working with to only the nodes
 ;; with the tag author


(PDB-5161) engine/unsupported-fields: rely on parse-field

Rely on parse-field rather than is-dotted-projection?.

--- src/puppetlabs/puppetdb/query_eng/engine.clj
+++ src/puppetlabs/puppetdb/query_eng/engine.clj
@@ -2550,13 +2550,19 @@

 (declare push-down-context)

+(defn- valid-dotted-field?
+  [field allowed-json-extract?]
+  (let [[top & path] (parse/parse-field field)]
+    (and (seq path) (allowed-json-extract? (:name top)))))
+
 (defn unsupported-fields
   [field allowed-fields allowed-json-extracts]
-  (let [supported-calls (set (map #(vector "function" %) (keys pdb-fns->pg-fns)))]
-    (remove #(or (contains? (set allowed-fields) %)
-                 (contains? supported-calls (take 2 %))
-                 (and (is-dotted-projection? %)
-                      (contains? (set allowed-json-extracts) (first (str/split % #"\.")))))
+  (let [allowed-json-extract? (set allowed-json-extracts)
+        allowed-field? (set allowed-fields)
+        supported-call? (set (map #(vector "function" %) (keys pdb-fns->pg-fns)))]
+    (remove #(or (allowed-field? %)
+                 (supported-call? (take 2 %))
+                 (valid-dotted-field? % allowed-json-extract?))
             (ks/as-collection field))))

 (defn validate-query-operation-fields


Add circle logo

Add circle logo

--- src-cljs/frontend/components/enterprise.cljs
+++ src-cljs/frontend/components/enterprise.cljs
@@ -50,6 +50,8 @@
          [:section.container
           [:div.row
            [:article.enterprise-hero-title.center-block
+            [:div.text-center
+             [:img.hero-logo {:src (utils/cdn-path "/img/outer/enterprise/logo-circleci.svg")}]]
             [:h1
              [:div.text-center "Ship code at the speed of business."]
              [:br]


Correctly set show-modal?

Correctly set show-modal?

--- src-cljs/frontend/components/pages/team.cljs
+++ src-cljs/frontend/components/pages/team.cljs
@@ -80,90 +80,96 @@

 (defn invite-teammates-modal [{:keys [selected-org-ident app]} owner]
   (reify
-    om/IInitState
-    (init-state [_]
-      {:invite-teammates? true})
     om/IDidMount
     (did-mount [_]
       (api/get-org-members (om/get-shared owner [:comms :api]) (:name (get-in app selected-org-ident))))

     om/IRenderState
-    (render-state [_ {:keys []}]
-      (when (om/get-state owner :invite-teammates?)
+    (render-state [_ {:keys [show-modal?]}]
+      (html
         (let [invite-data (:invite-data app)
-            users (remove :circle_member (:github-users invite-data))
-            opts {:vcs_type (:vcs_type invite-data)
-                  :org-name (:org invite-data)}
-            count-users (count users)
-            count-with-email (count (filter #(utils/valid-email? (:email %)) users))
-            count-selected (count (filter #(:checked %) users))]
-        (html
-          (component
-            (modal/modal-dialog {:title "Invite Teammates"
-                                 :body
-                                 [:div
+              users (remove :circle_member (:github-users invite-data))
+              opts {:vcs_type (:vcs_type invite-data)
+                    :org-name (:org invite-data)}
+              count-users (count users)
+              count-with-email (count (filter #(utils/valid-email? (:email %)) users))
+              count-selected (count (filter #(:checked %) users))]
+          [:div
+           (when show-modal?
+             (modal/modal-dialog {:title "Invite Teammates"
+                                  :body
                                   [:div
-                                   "These are the people who are not using CircleCI yet:"
-                                   [:br]
-                                   [:span [:b count-with-email] " of " [:b count-users] " users have emails, " [:b count-selected] " are selected"]]
-                                  [:div.constraining-modal
-                                   (om/build table/table {:rows users
-                                                          :key-fn :login
-                                                          :columns [{:header "Username"
-                                                                     :cell-fn (fn [user-map]
-                                                                                [:span
-                                                                                [:img.invite-gravatar {:src (gh-utils/make-avatar-url user-map :size 50)}]
-                                                                                (str "  " (:login user-map))])}
-                                                                    {:header "Email"
-                                                                     :cell-fn (fn [user-map]
-                                                                                (let [{:keys [avatar_url email login index checked]} user-map
-                                                                                id-name (str login "-email")
-                                                                                error? (and (or checked (not (empty? email)))
-                                                                                (not (utils/valid-email? email)))]
-                                                                                (om/build form/text-field {:on-change (fn [event]
-                                                                                (utils/edit-input owner (conj (state/invite-github-user-path index) :email) event)
-                                                                                (when (and (not= checked true)
-                                                                                (not (empty? email)))
-                                                                                (utils/toggle-input owner (conj (state/invite-github-user-path index) :checked) nil)))
-                                                                                :value email
-                                                                                :size :medium
-                                                                                :validation-error (when (and (or checked (not (empty? email)))
+                                   [:div
+                                    "These are the people who are not using CircleCI yet:"
+                                    [:br]
+                                    [:span [:b count-with-email] " of " [:b count-users] " users have emails, " [:b count-selected] " are selected"]]
+                                   [:div.constraining-modal
+                                    (om/build table/table {:rows users
+                                                           :key-fn :login
+                                                           :columns [{:header "Username"
+                                                                      :cell-fn (fn [user-map]
+                                                                                [:span
+                                                                                [:img.invite-gravatar {:src (gh-utils/make-avatar-url user-map :size 50)}]
+                                                                                (str "  " (:login user-map))])}
+                                                                     {:header "Email"
+                                                                      :cell-fn (fn [user-map]
+                                                                                (let [{:keys [avatar_url email login index checked]} user-map
+                                                                                id-name (str login "-email")
+                                                                                error? (and (or checked (not (empty? email)))
+                                                                                (not (utils/valid-email? email)))]
+                                                                                (om/build form/text-field {:on-change (fn [event]
+                                                                                (utils/edit-input owner (conj (state/invite-github-user-path index) :email) event)
+                                                                                (when (and (not= checked true)
+                                                                                (not (empty? email)))
+                                                                                (utils/toggle-input owner (conj (state/invite-github-user-path index) :checked) nil)))
+                                                                                :value email
+                                                                                :size :medium
+                                                                                :validation-error (when (and (or checked (not (empty? email)))
                                                                                (not (utils/valid-email? email)))
                                                                                (str email "is not a valid email"))})))}
-                                                                    {:type :shrink
-                                                                     :cell-fn (fn [user-map]
-                                                                                (let [{:keys [email login index checked]} user-map
-                                                                                id-name (str login "-checkbox")
-                                                                                email-valid? (utils/valid-email? email)]
-                                                                                [:input {:type "checkbox"
-                                                                                :id id-name
-                                                                                :disabled (and (not (utils/valid-email? email))
+                                                                     {:type :shrink
+                                                                      :cell-fn (fn [user-map]
+                                                                                (let [{:keys [email login index checked]} user-map
+                                                                                id-name (str login "-checkbox")
+                                                                                email-valid? (utils/valid-email? email)]
+                                                                                [:input {:type "checkbox"
+                                                                                :id id-name
+                                                                                :disabled (and (not (utils/valid-email? email))
                                                                                (not (empty? email)))
-                                                                                :checked checked
-                                                                                :on-click #(utils/toggle-input owner (conj (state/invite-github-user-path index) :checked) %)}]))}]
-                                                          :striped? true
-                                                          :fixed-header? true})]]
-                                 :actions [(button/button {:on-click #(om/set-state! owner :invite-teammates? false)} "Cancel")
-                                           (forms/managed-button
-                                             [:button.btn.btn-success {:data-success-text "Sent"
-                                                                       :on-click #(.log js/console "Invitees: " (seq (invitees users)))
-                                                                       ;; :on-click #(raise! owner [:invited-github-users (merge {:invitees (invitees users)
-                                                                       ;;                                                         :vcs_type (:vcs_type opts)}
-                                                                       ;;                                                        (if (:project-name opts)
-                                                                       ;;                                                          {:project-name (:project-name opts)}
-                                                                       ;;                                                          {:org-name (:org-name opts)}))])
-                                                                       :disabled (or (empty? (invitees users))
-                                                                                (not (every? #(utils/valid-email? (:email %)) (invitees users))))}
-                                              "Send Invites "
-                                              [:i.fa.fa-envelope-o]])]
-                                 :close-fn #(om/set-state! owner :invite-teammates? false)}))))))))
+                                                                                :checked checked
+                                                                                :on-click #(utils/toggle-input owner (conj (state/invite-github-user-path index) :checked) %)}]))}]
+                                                           :striped? true
+                                                           :fixed-header? true})]]
+                                  :actions [(button/button {:on-click #(om/set-state! owner :show-modal? false)} "Cancel")
+                                            (forms/managed-button
+                                              [:button.btn.btn-success {:data-success-text "Sent"
+                                                                        :on-click #(.log js/console "Invitees: " (seq (invitees users)))
+                                                                        ;; :on-click #(raise! owner [:invited-github-users (merge {:invitees (invitees users)
+                                                                        ;;                                                         :vcs_type (:vcs_type opts)}
+                                                                        ;;                                                        (if (:project-name opts)
+                                                                        ;;                                                          {:project-name (:project-name opts)}
+                                                                        ;;                                                          {:org-name (:org-name opts)}))])
+                                                                        :disabled (or (empty? (invitees users))
+                                                                                (not (every? #(utils/valid-email? (:email %)) (invitees users))))}
+                                               "Send Invites "
+                                               [:i.fa.fa-envelope-o]])]
+                                  :close-fn #(om/set-state! owner :show-modal? false)}))
+           (button/button
+             {:disabled? (nil? users)
+              :primary? true
+              :on-click (fn []
+                          ;; TODO -ac Add tracking back in before merging
+                          #_((om/get-shared owner :track-event)
+                             {:event-type :invite-teammates-clicked
+                              :properties {:view :team}})
+                          (om/set-state! owner :show-modal? (not (:show-modal? (om/get-render-state owner)))))}
+              "Invite Teammates")])))))

 (defn- main-content [app owner]
   (reify
     om/IInitState
     (init-state [_]
-      {:selected-org-ident nil
-       :invite-teammates? false})
+      {:selected-org-ident nil})

     om/IWillMount
     (will-mount [_]
@@ -215,20 +221,14 @@
                                    "github" [:i.octicon.octicon-mark-github]
                                    "bitbucket" [:i.fa.fa-bitbucket]
                                    nil)])
-                   :action  (html
-                              [:div (when (:invite-teammates? (om/get-render-state owner))
+                   :action  (om/build invite-teammates-modal {:selected-org-ident selected-org-ident
+                                                              :app app})
+                   ;; TODO -ac Remvoethis cruft
+                   #_(html
+                              [:div (when (:show-modal? (om/get-render-state owner))
                                       (om/build invite-teammates-modal {:selected-org-ident selected-org-ident
                                                                         :app app}))
-                               (button/button
-                                 {:disabled? (nil? (:users selected-org))
-                                  :primary? true
-                                  :on-click (fn []
-                                              ;; TODO -ac Add tracking back in before merging
-                                              #_((om/get-shared owner :track-event)
-                                                 {:event-type :invite-teammates-clicked
-                                                  :properties {:view :team}})
-                                              (om/set-state! owner :invite-teammates? (not (:invite-teammates? (om/get-render-state owner)))))}
-                                 "Invite Teammates")])}
+                               ])}
                 (if-let [users (:users selected-org)]
                   (table (add-follow-counts users (:projects selected-org)))
                   (html [:div.loading-spinner common/spinner])))


Convert Java Exception to &error and Error to &assertion-violation.

--- src/active/clojure/condition.cljc
+++ src/active/clojure/condition.cljc
@@ -112,9 +112,10 @@
 (defn- condition-components
   "Extract components from condition."
   [cond]
+  {:pre [(condition? cond)]}
   (::components (ex-data cond)))

-(declare make-exception make-message-condition)
+(declare make-exception make-error make-assertion-violation make-message-condition)

 (defn make-condition
   "Make a condition from components.
@@ -138,8 +139,13 @@

    (instance? Throwable thing)
    (make-condition (mapcat condition-components
-                           [(make-exception thing)
-                            (make-message-condition (.getMessage ^Throwable thing))]))
+                           (filter identity
+                                   [(make-exception thing)
+                                    (make-message-condition (.getMessage ^Throwable thing))
+                                    (cond
+                                     (instance? Exception thing) (make-error)
+                                     (instance? Error thing) (make-assertion-violation)
+                                     :else nil)])))

    :else (clojure.core/assert (instance? Throwable thing) "not a throwable"))))


Fix bug in primitive progression, hwere constraints were ignored

--- src/angelic/hierarchy/angelic.clj
+++ src/angelic/hierarchy/angelic.clj
@@ -97,7 +97,7 @@
           (let [{:keys [precond-map effect-map reward]} this
                 restrict (state-set/constrain ss (util/map-vals (fn [x] #{x}) precond-map))]
             (when-not (state-set/empty? restrict)
-              [(state/set-vars ss (util/map-vals (fn [x] #{x}) effect-map)) reward])))]
+              [(state/set-vars restrict (util/map-vals (fn [x] #{x}) effect-map)) reward])))]
     {:precondition-context-set (fn [this ss] (util/keyset (:precond-map this)))
      :optimistic-set-and-reward- exact
      :pessimistic-set-and-reward- exact}))


move gender processing before :note-processing


make non 1 or 2 count case update-last faster for vectors, change updateextremes to be specific to persistentvector

--- src/clj/com/rpl/specter/impl.cljx
+++ src/clj/com/rpl/specter/impl.cljx
@@ -465,7 +465,7 @@
   (count v))

 (extend-protocol UpdateExtremes
-  #+clj clojure.lang.IPersistentVector #+cljs cljs.core/PersistentVector
+  #+clj clojure.lang.PersistentVector #+cljs cljs.core/PersistentVector
   (update-first [v afn]
     (let [val (nth v 0)]
       (assoc v 0 (afn val))
@@ -475,8 +475,9 @@
       (case c
         1 (let [[e] v] [(afn e)])
         2 (let [[e1 e2] v] [e1 (afn e2)])
-        (conj (pop v) (afn (peek v)))
-      )))
+        (let [i (dec c)]
+          (assoc v i (afn (nth v i)))
+          ))))
   #+clj Object #+cljs default
   (update-first [l val]
     (update-first-list l val))


Added trapping; switched from c/count instead of c/distinct-count

--- src/clj/forma/hadoop/jobs/cdm.clj
+++ src/clj/forma/hadoop/jobs/cdm.clj
@@ -96,7 +96,8 @@
         (min-period ?rp :> ?p)
         (r/modis->latlon ?sres ?modh ?modv ?s ?l :> ?lat ?lon)
         (latlon-valid? ?lat ?lon)
-        (latlon->tile ?lat ?lon zoom :> ?x ?y ?z))))
+        (latlon->tile ?lat ?lon zoom :> ?x ?y ?z)
+        (:trap (hfs-seqfile "s3n://formatemp/output/cdm-trapped")))))

 (defn spark-hits
   "Prep for generate counts by country, for spark graphs on GFW site.
@@ -113,7 +114,7 @@
   [src gadm-src nodata tres tres-out start thresh]
   (let [epoch (date/datetime->period tres-out "2000-01-01")
         start-period (date/datetime->period tres start)]
-    (<- [?iso ?s-res ?modh ?modv ?s ?l ?p]
+    (<- [?iso ?sres ?modh ?modv ?s ?l ?p]
         (src ?sres ?modh ?modv ?s ?l ?prob-series)
         (gadm-src ?sres ?modh ?modv ?s ?l _ ?gadm _ _ _)
         (gadm->iso ?gadm :> ?iso)
@@ -122,11 +123,12 @@
         (+ start-period ?first-hit-idx :> ?period)
         (date/convert-period-res tres tres-out ?period :> ?period-new-res)
         (- ?period-new-res epoch :> ?rp)
-        (min-period ?rp :> ?p))))
+        (min-period ?rp :> ?p)
+        (:trap (hfs-seqfile "s3n://formatemp/output/spark-trapped")))))

 (defn spark-graphify
   [src gadm-src nodata tres tres-out start thresh]
   (let [spark-src (spark-hits src gadm-src nodata tres tres-out start thresh)]
     (<- [?iso ?p ?ct]
         (spark-src ?iso _ _ _ _ _ ?p)
-        (c/distinct-count ?p :> ?ct))))
+        (c/count ?ct))))


Added tile 1010 to Peru

Added tile 1010 to Peru


use card->server in :choices

use card->server in :choices

--- src/clj/game/cards-operations.clj
+++ src/clj/game/cards-operations.clj
@@ -364,7 +364,7 @@
    (let [ice-index (fn [state i] (first (keep-indexed #(when (= (:cid %2) (:cid i)) %1)
                                                       (get-in @state (cons :corp (:zone i))))))
          sunhelp (fn sun [serv] {:prompt "Select two pieces of ICE to swap positions"
-                                 :choices {:req #(and (= serv (rest (butlast (:zone %))))
+                                 :choices {:req #(and (= serv (card->server state %))
                                                       (= (:type %) "ICE")) :max 2}
                                  :effect (req (if (= (count targets) 2)
                                                 (let [fndx (ice-index state (first targets))


Lag Time leaving play should trigger an ice strength update.

--- src/clj/game/cards-operations.clj
+++ src/clj/game/cards-operations.clj
@@ -131,7 +131,8 @@
             :unsuccessful {:msg "take 1 bad publicity" :effect (effect (gain :corp :bad-publicity 1))}}}

    "Lag Time"
-   {:events {:pre-ice-strength {:effect (effect (ice-strength-bonus 1))}}}
+   {:events {:pre-ice-strength {:effect (effect (ice-strength-bonus 1))}}
+    :leave-play {:effect (effect (update-all-ice))}}

    "Manhunt"
    {:events {:successful-run {:req (req (first-event state side :successful-run))


Show regular card images in card preview

not alt arts...

--- src/cljs/netrunner/gameboard.cljs
+++ src/cljs/netrunner/gameboard.cljs
@@ -158,14 +158,14 @@
     [:span {:class "fake-link" :id code} title]
     [:span item])))

-(defn get-alt-art [[title cards]]
-  (let [s (sort-by #(not= (:setname %) "Alternates") cards)]
+(defn get-non-alt-art [[title cards]]
+  (let [s (sort-by #(= (:setname %) "Alternates") cards)]
     {:title title :code (:code (first s))}))

 (defn prepare-cards []
  (->> (:cards @app-state)
       (group-by :title)
-      (map get-alt-art)
+      (map get-non-alt-art)
       (sort-by #(count (:title %1)))
       (reverse)))


added game count to the lobby options

added game count to the lobby options

--- src/cljs/netrunner/gamelobby.cljs
+++ src/cljs/netrunner/gamelobby.cljs
@@ -204,7 +204,7 @@
   (reify
     om/IInitState
     (init-state [this]
-      {:current-lobby "Casual"})
+      {:current-lobby "casual"})

     om/IRenderState
     (render-state [this state]
@@ -218,8 +218,8 @@
           [:div.float-right "Lobby: "
            [:select {:value (om/get-state owner :current-lobby)
                      :on-change #(om/set-state! owner :current-lobby (.. % -target -value))}
-            [:option "Casual"]
-            [:option "Competitive"]]]]
+            [:option {:value "casual"} (str "Casual (" (count (filter #(= "casual" (:lobby %)) games)) ")")]
+            [:option {:value "competitive"} (str "Competitive (" (count (filter #(= "competitive" (:lobby %)) games)) ")")]]]]
          (game-list cursor owner)]

         [:div.game-panel