Remove vestigial memoization of digest/sha-1

The new version of the digest library has switched from using a
multimethod (which is slower) to a protocol (which is faster).

--- src/com/puppetlabs/utils.clj
+++ src/com/puppetlabs/utils.clj
@@ -527,17 +527,14 @@

 ;; ## Hashing

-;; This method lookup is surprisingly expensive (on the order of 10x slower),
-;; so we pay the cost once, and define our own digest in terms of it.
-(let [digest-func (get-method digest/digest :default)]
-  (defn utf8-string->sha1
-    "Compute a SHA-1 hash for the UTF-8 encoded version of the supplied
-    string"
-    [s]
-    {:pre  [(string? s)]
-     :post [(string? %)]}
-    (let [bytes (.getBytes s "UTF-8")]
-      (digest-func "sha-1" [bytes]))))
+(defn utf8-string->sha1
+  "Compute a SHA-1 hash for the UTF-8 encoded version of the supplied
+  string"
+  [s]
+  {:pre  [(string? s)]
+   :post [(string? %)]}
+  (let [bytes (.getBytes s "UTF-8")]
+    (digest/sha-1 [bytes])))

 (defn bounded-memoize
   "Similar to memoize, but the cache will be reset if the number of entries


fix arity

fix arity

--- src/dato/lib/incoming_tx.clj
+++ src/dato/lib/incoming_tx.clj
@@ -35,7 +35,7 @@
 (defn have-guid? [[_ e _ _] guids]
   (instance? java.util.UUID (get guids e)))

-(defn have-ref-guid? [[_ _ _ v] tx guids]
+(defn have-ref-guid? [[_ _ _ v] guids]
   (instance? java.util.UUID (get guids v)))

 (defmulti valid-db-fn? (fn [tx] (first tx)))


Cleanup: less special-casing in sidebar code

--- src/flense_demo/sidebar.cljs
+++ src/flense_demo/sidebar.cljs
@@ -8,34 +8,49 @@
 (def special-keynames
   {:alt "⌥"
    :backspace "⌫"
+   :close-curly-bracket "}"
+   :close-parenthesis ")"
    :close-square-bracket "]"
    :ctrl "⌃"
+   :double-quote "\""
    :down "↓"
    :left "←"
    :meta "⌘"
+   :open-curly-bracket "{"
+   :open-parenthesis "("
    :open-square-bracket "["
    :right "→"
    :single-quote "'"
    :shift "⇧"
    :up "↑"})

-(def special-shift-combos
-  {#{:shift :close-square-bracket} "}"
-   #{:shift :nine} "("
-   #{:shift :open-square-bracket} "{"
-   #{:shift :single-quote} "\""
-   #{:shift :zero} ")"})
+(def shift-combo
+  {:close-square-bracket :close-curly-bracket
+   :nine :open-parenthesis
+   :open-square-bracket :open-curly-bracket
+   :single-quote :double-quote
+   :zero :close-parenthesis})
+
+(defn non-modifier-key [keyset]
+  (first (clojure.set/difference keyset #{:meta :ctrl :shift :alt})))
+
+(defn maybe-rewrite-shift-combo [keyset]
+  (let [non-mod (non-modifier-key keyset)
+        combo (shift-combo non-mod)]
+    (if (and (contains? keyset :shift) combo)
+      (-> keyset (disj :shift non-mod) (conj combo))
+      keyset)))

 (defn key->keyname [key]
   (or (special-keynames key)
       (clojure.string/capitalize (name key))))

 (defn keyset->keyname [keyset]
-  (or (special-shift-combos keyset)
-      (->> keyset
-           (sort-by #(case % :meta 0 :ctrl 1 :shift 2 :alt 3 4))
-           (map key->keyname)
-           clojure.string/join)))
+  (->> keyset
+       maybe-rewrite-shift-combo
+       (sort-by #(case % :meta 0 :ctrl 1 :shift 2 :alt 3 4))
+       (map key->keyname)
+       clojure.string/join))

 (defn movement-keybinds [loc]
   [[(cond


Problem added - "Intro to Trampoline"

Problem added - "Intro to Trampoline"

--- src/foreclojure/data_set.clj
+++ src/foreclojure/data_set.clj
@@ -786,9 +786,16 @@
 		   "(= (__ 40) 16)"
 		   "(= (__ 99) 60)"]})

-
-      (insert! :problems
-           {:_id 76
+      (insert! :problems
+          {:_id 76
+           :title "Intro to Trampoline"
+           :times-solved 0
+           :description "The trampoline function takes a function f and a variable number of parameters.  Trampoline calls f with any parameters that were supplied.  If f returns a function, trampoline calls that function with no arguments.  This is repeated, until the return value is not a function, and then trampoline returns that non-function value.  This is useful for implementing mutually recursive algorithms in a way that won't consume the stack."
+           :tags ["medium", "recursion"]
+           :tests ["(= __\n   (letfn\n     [(foo [x y] #(bar (conj x y) y))\n      (bar [x y] (if (> (last x) 10)\n                   x\n                   #(foo x (+ 2 y))))]\n     (trampoline foo [] 1)))"]})
+
+      (insert! :problems
+           {:_id 77
             :title "Power Set"
             :times-solved 0
             :description "A power set is the set of all subsets of a given set. Given a list, produce a set of sublists while preserving the order of elements."


Log sse output failures

Log sse output failures

--- src/gin/system/ring/jetty_async_adapter.clj
+++ src/gin/system/ring/jetty_async_adapter.clj
@@ -42,15 +42,22 @@
                                           (close! chunks))
                                         (onTimeout [c]
                                           (.complete c))))
-            (go (loop []
-                  (if-let [chunk (<! chunks)]
-                    (do (doto (.getWriter response)
-                          (.write chunk)
-                          (.flush))
-                        (when (.checkError (.getWriter response))
-                          (close! chunks))
-                        (recur))
-                    (.complete continuation))))
+            (go (try
+                  (loop []
+                    (if-let [chunk (<! chunks)]
+                      (do (doto (.getWriter response)
+                            (.write chunk)
+                            (.flush))
+                          (when (.checkError (.getWriter response))
+                            (close! chunks))
+                          (recur))
+                      (.complete continuation)))
+                  (catch Exception e
+                    (.printStackTrace e)
+                    (debug "Exception async out chan: " e)
+                    (close! chunks)
+                    (.complete continuation)
+                    (throw e))))
             ;; 4 minutes is google default
             (.setTimeout continuation (get options :response-timeout (* 4 60 1000)))
             ))))))


Removes debugging code

Removes debugging code

--- src/great_things_done/application_info.cljs
+++ src/great_things_done/application_info.cljs
@@ -18,7 +18,6 @@
   #(:id %1))

 (defmethod retrieve-current-app-data-osx "com.apple.mail" [info callback]
-  (js/console.log "Been there")
   (let [applescript (js/require "applescript")]
     (.execString applescript
                  osx-mail-applescript
@@ -30,7 +29,6 @@
 (defn- get-current-app-info-osx
   "Return info about the current frontmost application on OSX"
   []
-  (js/console.log "Been there2")
   (let [remote  (js/require "remote")
         nodobjc (js/require "nodobjc")]
     (.framework nodobjc "AppKit")


test hook

test hook

--- src/main/cawala/api/read.clj
+++ src/main/cawala/api/read.clj
@@ -6,7 +6,7 @@
                      :person/relation :friend}
                  2  {:db/id 2 :person/name "Sally" :person/age 22
                      :person/relation :friend}
-                 3  {:db/id 3 :person/name "Allie" :person/age 59
+                 3  {:db/id 3 :person/name "Allie" :person/age 58
                      :person/relation :enemy}
                  4  {:db/id 4 :person/name "Zoe" :person/age 32
                      :person/relation :friend}


CLJS-1303 WIP

CLJS-1303 WIP

add *ns* dynamic var

add cljs.core/munge, cljs.core/demunge

add cljs.core/find-ns, cljs.core/ns-map, cljs.core/ns-resolve

--- src/main/cljs/cljs/core.cljs
+++ src/main/cljs/cljs/core.cljs
@@ -25,6 +25,11 @@
   :closure-defines option."
     :jsdoc ["@define {string}"]}
   *target* "default")
+
+(def
+  ^{:dynamic true
+    :doc "Var bound to the current namespace. Only used for bootstrapping."}
+  *ns* nil)

 (defonce
   ^{:doc "Each runtime environment provides a different way to print output.
@@ -232,6 +237,62 @@
          (identical? (goog/typeOf js/Symbol) "function"))
   (def ITER_SYMBOL (.-iterator js/Symbol))
   (def ITER_SYMBOL "@@iterator"))
+
+(def ^{:jsdoc ["@enum {string"]}
+  CHAR_MAP
+  #js {"-"    "_"
+       ":"    "_COLON_"
+       "+"    "_PLUS_"
+       ">"    "_GT_"
+       "<"    "_LT_"
+       "="    "_EQ_"
+       "~"    "_TILDE_"
+       "!"    "_BANG_"
+       "@"    "_CIRCA_"
+       "#"    "_SHARP_"
+       "'"    "_SINGLEQUOTE_"
+       "\\\"" "_DOUBLEQUOTE_"
+       "%"    "_PERCENT_"
+       "^"    "_CARET_"
+       "&"    "_AMPERSAND_"
+       "*"    "_STAR_"
+       "|"    "_BAR_"
+       "{"    "_LBRACE_"
+       "}"    "_RBRACE_"
+       "["    "_LBRACK_"
+       "]"    "_RBRACK_"
+       "/"    "_SLASH_"
+       "\\\\" "_BSLASH_"
+       "?"    "_QMARK_"})
+
+(def ^{:jsdoc ["@enum {string}"]}
+  DEMUNGE_MAP
+  #js {"_"             "-"
+       "_COLON_"       ":"
+       "_PLUS_"        "+"
+       "_GT_"          ">"
+       "_LT_"          "<"
+       "_EQ_"          "="
+       "_TILDE_"       "~"
+       "_BANG_"        "!"
+       "_CIRCA_"       "@"
+       "_SHARP_"       "#"
+       "_SINGLEQUOTE_" "'"
+       "_DOUBLEQUOTE_" "\\\""
+       "_PERCENT_"     "%"
+       "_CARET_"       "^"
+       "_AMPERSAND_"   "&"
+       "_STAR_"        "*"
+       "_BAR_"         "|"
+       "_LBRACE_"      "{"
+       "_RBRACE_"      "}"
+       "_LBRACK_"      "["
+       "_RBRACK_"      "]"
+       "_SLASH_"       "/"
+       "_BSLASH_"      "\\\\"
+       "_QMARK_"       "?"})
+
+(def DEMUNGE_PATTERN nil)

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; arrays ;;;;;;;;;;;;;;;;

@@ -9704,3 +9765,105 @@
   [tag form]
   {:pre [(symbol? tag)]}
   (cljs.core.TaggedLiteral. tag form))
+
+(defn demunge-pattern []
+  (when-not DEMUNGE_PATTERN
+    (set! DEMUNGE_PATTERN
+      (let [ks (sort (fn [a b] (- (. b -length) (. a -length)))
+                 (js-keys DEMUNGE_MAP))]
+        (loop [ks ks ret ""]
+          (if (seq ks)
+            (recur
+              (next ks)
+              (str
+                (cond-> ret
+                  (not (identical? ret "")) (str "|"))
+                (first ks)))
+            (str ret "|\\$"))))))
+  DEMUNGE_PATTERN)
+
+(defn munge-str [name]
+  (loop [i 0 ret ""]
+    (if (< i (. name -length))
+      (recur (inc i)
+        (let [c (.charAt name i)]
+          (if-let [sub (goog.object/get CHAR_MAP c)]
+            (str ret sub)
+            (str ret c))))
+      ret)))
+
+(defn munge [name]
+  ((if (symbol? name) symbol str)
+    (munge-str (str name))))
+
+(defn demunge-str [munged-name]
+  (let [r (js/RegExp. (demunge-pattern) "g")]
+    (loop [ret "" last-match-end 0]
+      (if-let [match (.exec r munged-name)]
+        (let [[x] match]
+          (recur
+            (str ret
+              (.substring munged-name last-match-end
+                (- (. r -lastIndex) (. x -length)))
+              (if (= x "$") "/" (goog.object/get DEMUNGE_MAP x)))
+            (. r -lastIndex)))
+        ret))))
+
+(defn demunge [name]
+  ((if (symbol? name) symbol str)
+    (demunge-str (str name))))
+
+(deftype Namespace [obj name]
+  Object
+  (find [_ sym]
+    (goog.object/get obj (str sym)))
+  (getMappings [_]
+    (letfn [(step [ret k]
+              (let [sym (symbol (demunge k))]
+                (assoc ret sym
+                           (Var. (goog.object/get obj k)
+                             (symbol (str name) (str sym)) nil))))]
+      (reduce step {} (js-keys obj))))
+  IEquiv
+  (-equiv [_ other]
+    (if (instance? Namespace other)
+      (= name (.-name other))
+      false))
+  IHash
+  (-hash [_]
+    (hash name))
+  INamed
+  (-name [_] name)
+  (-namespace [_]
+    (throw (js/Error. "Cannot call -namespace on Namespace"))))
+
+(defn find-ns [ns]
+  (letfn [(find-ns* [ctxt xs]
+            (cond
+              (nil? ctxt) nil
+              (nil? xs) (Namespace. ctxt ns)
+              :else (recur (goog.object/get ctxt (first xs)) (next xs))))]
+    (if-not js/COMPILED
+      (let [segs (-> ns str (.split "."))]
+        (when (goog.object/get (. goog/dependencies_ -nameToPath) (str ns))
+          (condp identical? *target*
+            "nodejs" (find-ns* js/global segs)
+            "default" (find-ns* js/window segs)
+            (throw (js/Error. (str "find-ns not supported for target " *target*))))))
+      (throw
+        (js/Error.
+          "find-ns not supported when Closure optimization applied")))))
+
+(defn ns-name [ns-obj]
+  (.-name ns-obj))
+
+(defn ns-map [ns-obj]
+  (.getMappings ns-obj))
+
+(defn ns-resolve
+  ([ns sym] (ns-resolve ns nil sym))
+  ([ns env sym]
+   (when-not (contains? env sym)
+     (when-let [ns-obj (find-ns ns)]
+       (Var. #(.find ns-obj (str sym))
+         (symbol (str ns) (str sym)) nil)))))


normalize interop forms

normalize interop forms

--- src/main/cljs/cljs/core.cljs
+++ src/main/cljs/cljs/core.cljs
@@ -6078,7 +6078,7 @@
   Returns a new sorted map with supplied mappings, using the supplied comparator."
   ([comparator & keyvals]
      (loop [in (seq keyvals)
-            out (cljs.core.PersistentTreeMap. (fn->comparator comparator) nil 0 nil 0)]
+            out (PersistentTreeMap. (fn->comparator comparator) nil 0 nil 0)]
        (if in
          (recur (nnext in) (assoc out (first in) (second in)))
          out))))
@@ -6480,7 +6480,7 @@
   "Returns a new sorted set with supplied keys, using the supplied comparator."
   ([comparator & keys]
    (reduce -conj
-           (cljs.core.PersistentTreeSet. nil (sorted-map-by comparator) 0)
+           (PersistentTreeSet. nil (sorted-map-by comparator) 0)
            keys)))

 (defn replace


Identify that import-stylesheet returns nil.

--- src/main/clojure/cascade.clj
+++ src/main/clojure/cascade.clj
@@ -156,7 +156,7 @@
 (defn import-stylesheet
   "Imports a stylesheet into the rendered document. Like JavaScript libraries, the stylesheet will
    only be added a single time regardless of how many times it is imported. If the type is omitted,
-   it defaults to :context."
+   it defaults to :context. Returns nil."
   ([env path]
     (import-stylesheet env :context path))
   ([env type path]


(MAINT) Fix indentation

(MAINT) Fix indentation

--- src/clj/puppetlabs/services/jruby/jruby_puppet_service.clj
+++ src/clj/puppetlabs/services/jruby/jruby_puppet_service.clj
@@ -53,9 +53,10 @@
                                                     default-http-socket-timeout)))
           service-id        (tk-services/service-id this)
           agent-shutdown-fn (partial shutdown-on-error service-id)
-          pool-agent  (jruby-agents/pool-agent agent-shutdown-fn)
+          pool-agent        (jruby-agents/pool-agent agent-shutdown-fn)
           profiler          (get-profiler)
-          borrow-timeout (get-in-config [:jruby-puppet :borrow-timeout] default-borrow-timeout)]
+          borrow-timeout    (get-in-config [:jruby-puppet :borrow-timeout]
+                                           default-borrow-timeout)]
       (core/verify-config-found! config)
       (log/info "Initializing the JRuby service")
       (let [pool-context (core/create-pool-context config profiler)]


RR: default print-xls-report markup for testing

--- src/hatti/views/record.cljs
+++ src/hatti/views/record.cljs
@@ -41,7 +41,7 @@
 (defmethod print-xls-report-btn :default
   [cursor owner]
   (om/component
-   (html nil)))
+   (html [:div {:id "print-xls-report"}])))

 ;; A single row of a question / answer pair
 (def qa-elements


feature #3845 - added edcon to public chats and using keyboard avoiding view

Signed-off-by: Andrey Shovkoplyas <b713972e59b8e606e23253c4a13e948139fea4d1@gmail.com>

--- src/status_im/ui/screens/add_new/new_public_chat/view.cljs
+++ src/status_im/ui/screens/add_new/new_public_chat/view.cljs
@@ -51,12 +51,12 @@
      [list/item-icon {:icon      :icons/forward
                       :icon-opts {:color :gray}}]]]])

-(def default-public-chats ["status" "openbounty" "ethereum"])
+(def default-public-chats ["status" "openbounty" "edcon" "ethereum"])

 (views/defview new-public-chat []
   (views/letsubs [topic [:get :public-group-topic]
                   error [:get :public-group-topic-error]]
-    [react/view styles/group-container
+    [react/keyboard-avoiding-view styles/group-container
      [status-bar/status-bar]
      [toolbar/simple-toolbar
       (i18n/label :t/public-chat)]


add all and all1 functions

add all and all1 functions

all: ensures every element in the list validates against a
given function. Empty lists are ok;

all1: same as all but does not accept empty lists;

--- src/storaged/src/leela/storaged/network/actions/common.clj
+++ src/storaged/src/leela/storaged/network/actions/common.clj
@@ -26,8 +26,14 @@

 (def default-limit 100)

-(defn nil-or [pred]
-  #(or (nil? %) (pred %)))
+(defn all [p]
+  (fn [v] (and (coll? v) (reduce #(and %1 %2) true (map p v)))))
+
+(defn all1 [p]
+  (fn [v] (and (coll? v) (seq v) (reduce #(and %1 %2) (map p v)))))
+
+(defn nil-or [p]
+  #(or (nil? %) (p %)))

 (defn map-errors [test data]
   (letfn [(valid-fn [[key val]]


beefed up the overall story and added mroe examples

--- src/tutorial/untangled_tutorial/H_Server_Interactions.cljs
+++ src/tutorial/untangled_tutorial/H_Server_Interactions.cljs
@@ -1,8 +1,11 @@
 (ns untangled-tutorial.H-Server-Interactions
-  (:require-macros [cljs.test :refer [is]])
+  (:require-macros [cljs.test :refer [is]]
+                   [untangled-tutorial.tutmacros :refer [untangled-app]])
   (:require [om.next :as om :refer-macros [defui]]
             [om.dom :as dom]
-            [devcards.core :as dc :refer-macros [defcard defcard-doc]]))
+            [devcards.core :as dc :refer-macros [defcard defcard-doc]]
+            [untangled.client.mutations :as m]
+            [untangled.client.core :as uc]))

 ; TODO: Explain Om's HATEOS (keyword listing in :keys)
 ; see: https://github.com/omcljs/om/wiki/Quick-Start-%28om.next%29
@@ -10,6 +13,93 @@
 ; Remember that global-error-handler is a function of the network impl
 ; TODO: (advanced) cookies/headers (needs extension to U.Server see issue #13)

+(defui ^:once CategoryQuery
+  static om/IQuery
+  (query [this] [] [:db/id :category/name])
+  static om/Ident
+  (ident [this props] [:categories/by-id (:db/id props)]))
+
+(defui ^:once ItemQuery
+  static om/IQuery
+  (query [this] [] [:db/id {:item/category (om/get-query CategoryQuery)} :item/name])
+  static om/Ident
+  (ident [this props] [:items/by-id (:db/id props)]))
+
+(def sample-server-response
+  {:all-items [{:db/id 5 :item/name "item-42" :item/category {:db/id 1 :category/name "A"}}
+               {:db/id 6 :item/name "item-92" :item/category {:db/id 1 :category/name "A"}}
+               {:db/id 7 :item/name "item-32" :item/category {:db/id 1 :category/name "A"}}
+               {:db/id 8 :item/name "item-52" :item/category {:db/id 2 :category/name "B"}}]})
+
+(def component-query [{:all-items (om/get-query ItemQuery)}])
+
+(def hand-written-query [{:all-items [:db/id :item/name
+                                      {:item/category [:db/id :category/name]}]}])
+
+(defui ^:once ToolbarItem
+  static om/IQuery
+  (query [this] [] [:db/id :item/name])
+  static om/Ident
+  (ident [this props] [:items/by-id (:db/id props)])
+  Object
+  (render [this]
+    (let [{:keys [item/name]} (om/props this)]
+      (dom/li nil name))))
+
+(def ui-toolbar-item (om/factory ToolbarItem {:keyfn :db/id}))
+
+(defui ^:once ToolbarCategory
+  static om/IQuery
+  (query [this] [] [:db/id :category/name {:category/items (om/get-query ItemQuery)}])
+  static om/Ident
+  (ident [this props] [:categories/by-id (:db/id props)])
+  Object
+  (render [this]
+    (let [{:keys [category/name category/items]} (om/props this)]
+      (dom/li nil
+        name
+        (dom/ul nil
+          (map ui-toolbar-item items))))))
+
+(def ui-toolbar-category (om/factory ToolbarCategory {:keyfn :db/id}))
+
+(defui ^:once Toolbar
+  static om/IQuery
+  (query [this] [] [{:toolbar/categories (om/get-query ToolbarCategory)}])
+  Object
+  (render [this]
+    (let [{:keys [toolbar/categories]} (om/props this)]
+      (dom/div nil
+        (dom/button #js {:onClick #(om/transact! this '[(server-interaction/group-items)])} "Trigger Post Mutation")
+        (dom/button #js {:onClick #(om/transact! this '[(server-interaction/group-items-reset)])} "Reset")
+        (dom/ul nil
+          (map ui-toolbar-category categories))))))
+
+(defmethod m/mutate 'server-interaction/group-items-reset [{:keys [state]} k p]
+  {:action (fn [] (reset! state (om/tree->db component-query sample-server-response true)))})
+
+(defn add-to-category
+  "Returns a new db with the given item added into that item's category."
+  [db item]
+  (let [category-ident (:item/category item)
+        item-location (conj category-ident :category/items)]
+    (update-in db item-location (fnil conj []) (om/ident ItemQuery item))))
+
+(defn group-items
+  "Returns a new db with all of the items sorted by name and grouped into their categories."
+  [db]
+  (let [sorted-items (->> db :items/by-id vals (sort-by :item/name))
+        category-ids (-> db (:categories/by-id) keys)
+        clear-items (fn [db id] (assoc-in db [:categories/by-id id :category/items] []))
+        db (reduce clear-items db category-ids)
+        db (reduce add-to-category db sorted-items)
+        all-categories (->> db :categories/by-id vals (mapv #(om/ident CategoryQuery %)))]
+    (assoc db :toolbar/categories all-categories)))
+
+
+(defmethod m/mutate 'server-interaction/group-items [{:keys [state]} k p]
+  {:action (fn [] (swap! state group-items))})
+
 (defcard-doc
   "
   # Server interaction
@@ -23,13 +113,61 @@
   lead to out-of-order execution, and impossible-to-reason-about recovery from errors).
   - You may provide fallbacks that indicate error-handling mutations to run on failures

-  ## Reads
-
-  Remote reads in Untangled are explicit calls to the load functions in the `untangled.client.data-fetch` namespace, of
-  which there are two pairs:
+  ## General Theory of Operation
+
+  Untangled uses the primitives of Om Next, but one of the primary contributions it makes to that model is the
+  realization that the following use-cases are by far the most common:
+
+  - Reading data on initial app startup
+  - Triggering loads on user-based events (or perhaps timeouts)
+
+  In both cases, the implementation of the remoting in Om Next is very similar:
+
+  - Write something into your application state database the indicates you want to do some remote operation
+      - This triggers an internal parsing that you would normally have to interact with in order to decide
+        what to ask the server.
+      - Note that 'writing something to your app state' is a *mutation*.
+  - Morph the UI query into something your server would rather see (you don't want to write server queries for
+    every darn UI tree you can think of on the client side)
+  - Morph the response *back into UI shape*, and normalize it. Note this is a data transform aided by Om primitives.
+
+  So, the key realization is the *in practice Om reads requires some kind of **mutation** before a read can occur*! The
+  additional realization is the after the read run, and you've normalized data into the database, you often *want* to
+  morph the database into something special on your UI that the server need not understand.
+
+  So, Untangled provides the 'triggering' mutations, and gives you a way to hook into the result so that you can
+  do this post-transform when the remote read is complete.
+
+  ## The `untangled/load` Mutation
+
+  Untangled has a built-in mutation called `untangled/load`. This mutation *can* be used directly from `om/transact!` (and often is).
+
+  The `load` mutation does the following basic things:
+
+  - Places your query onto a built-in queue in your app state of things to load
+  - The mutation is marked `remote`, so it will cause the networking side of Om to trigger.
+  - The networking plumbing of Untangled looks in the queue when it sees a `load` mutation. It elides the `load` from the remote request itself, and
+    instead sends the desired query/queries, then properly merges the results.
+  - It may (optionally) place load markers in your app state so you can show in-progress indicators
+  - It may (optionally) run post-mutation transforms on the database (if you supply them)
+
+  The mutation can be used from application startup or anywhere you'd run a mutation (`transact!`). This covers almost
+  all of the possible remote data integration needs!
+
+  First, let's cover some helper functions that make using this mechanism a bit easier.
+
+  ## Load helpers
+
+  Untangled includes a few helper functions that can assist you in invoking the `untangled/load` mutation.

   1. `load-data` and `load-data-action`
   2. `load-field` and `load-field-action`
+
+  The former of each pair are methods the directly invoke a `transact!` to place load requests into a load queue.
+
+  The latter of each pair are low-level implementation method that can be used to *compose* remote reads with your
+  own mutations (e.g. you want to switch to a new area of the UI (local mutation), but also trigger a *remote read* to load the
+  content of that UI at the same time).

   ### Load Data vs. Load Field

@@ -39,9 +177,10 @@
   The only difference is that `load-data` must be passed a complete query while `load-field` uses the passed-in component
   to create its query.

-  So, `load-field` focuses the component's query to the specified field, associates the component's ident with the query,
+  `load-field` is really just a helper for a common use-case: loading a field of some specific thing on the screen. It
+   focuses the component's query to the specified field, associates the component's ident with the query,
   and asks the UI to re-render all components with the calling component's ident after the load is complete. Since `load-field`
-  requires a component to build the query sent to the server, it cannot be used with the reconciler. If you want to load data
+  requires a component to build the query sent to the server it cannot be used with the reconciler. If you want to load data
   from your server when the app initially loads, you must use `load-data` with the reconciler passed to the
   `:started-callback` function when creating a new untangled client application.

@@ -102,6 +241,7 @@
   **do not** call `om/transact!`, and are used to initialize a load inside of one of your custom client-side mutations.

   Let's look at an example of a standard load. Say you want to load a list of people from the server:
+
   ```
   (require [untangled.client.data-fetch :as df])

@@ -160,18 +300,62 @@
   the code to use the action-suffixed load instead. To learn more about the dangers of loads and lifecycle methods, see
   the [reference on loading data]().

-  ### How reads work : `untangled/load`
+  ### Using `untangled/load` Directly

   The helper functions described above simply trigger a built-in Untangled mutation called `untangled/load`, which you are
-  allowed (and sometimes encouraged) to use directly. It is the Untangled method of doing follow-on reads after a remote
-  mutation:
-
-  ```
-  (om/transact! this '[(app/do-some-thing) (untangled/load {:query [:a]})])
-  ```
-
-  The normal form of follow-on keywords (for re-rendering the UI) works fine, it will just never trigger remote
-  reads.
+  allowed (and sometimes encouraged) to use directly. The arguments to this mutation include:
+
+  - `query`: The specific query you'd like to send to the server
+  - `post-mutation`: A symbol indicating a mutation to run after the load completes
+  - `without`: A set of keywords that should be (recursively) removed from `query`
+  - `refresh`: A vector of keywords that should cause re-rendering after the load.
+  - `parallel`: True or false. If true, bypasses the sequential network queue
+  - `ident`: An ident. Used if you want the query to be morphed into an ident join. Used by
+  `load-field`.
+  - `field`: A keyworkd. Used if you want to focus the query to a specific single item. Used by
+  `load-field`.
+  - `marker`: True or false. If true, places a loading marker in place of the first top-level key in the query,
+    of in place of the given database object if `ident` and `field` are set (e.g. by `load-field`)
+
+  For most direct use-cases you'll probably skip using the `load-field` specific parameters. You can read
+  the source of `load-field` if you'd like to simulate it by hand.
+
+  The most common use for a direct call to the `untangled/load` mutation is obtaining a value from the server
+  after running some mutation that had a (potential) remote effect.
+
+  #### Getting a Remote Value after a Mutation
+
+  The most common direct use of `untangled/load` is doing remote follow-on reads after a mutation (which itself may
+  be remote).
+
+  Note the difference. The following follow-on read is *always* just a local re-render in Untangled (in stock Om,
+  the `:something` keyword can also trigger a remote read, though you'd have to write logic into the parser
+  to figure it out):
+
+  ```
+  (om/transact! this '[(app/do-some-thing) :something])
+  ```
+
+  If what you want instead is `do-some-thing` and the read `:something` from the server, you instead want:
+
+  ```
+  (om/transact! this '[(app/do-some-thing) (untangled/load {:query [:something] :refresh [:something})])
+  ```
+
+  This has both a clear benefit and cost with respect to stock Om:
+
+  - The benefits are:
+      - Non-opaque reasoning
+      - No need to write parser logic to figure out if you want to do remote reads
+  - The costs are:
+      - The UI is aware of what is remote, and what is local (in stock Om, the UI is completely unconcerned
+        about remoting.)
+
+  In practice, we've found that the idea that something involves a server is pretty clear-cut, so the ability
+  to completely abstract it away really isn't that necessary pragmatically, and the cost of writing
+  the behind-the-scenes logic related making a parser trigger remote reads is somewhat high.
+
+  #### A bit More About How it Works

   The `untangled/load` mutation does a very simple thing: It puts a state marker in a well-known location in your app state
   to indicate that you're wanting to load something (and returns `:remote true`). This causes the network
@@ -181,8 +365,8 @@
      - For each load, it places a state marker in the app state at the target destination for the query data
      - All loads that are present are combined together into a single Om query
   - It looks for other mutations
-  - It puts the 'other mutations' on the send queue
-  - It puts the derived query from the `untangled/load` onto the send queue
+  - It puts the 'other mutations' on the send queue (iff they are marked `:remote`)
+  - It puts the derived query/queries from the `untangled/load`s onto the send queue.

   A separate \"thread\" (core async go block) watches the send queue, and sends things one-at-a-time (e.g. each entry
   in the queue is processed in a sequence, ensuring you can reason about things sequentially). The one-at-a-time
@@ -218,13 +402,14 @@

   ### Data merge

-  When the server responds Untangled will merge the result into the application client database. It overrides the built-in Om
+  Untangled will automatically merge the result of loads into the application client database.
+  It overrides the built-in Om
   shallow merge. Untangled's data merge has a number of extension that are useful for
   simple application reasoning:

-  1. Merge is a deep merge, but with extra logic
-
-  Untangled merges your response via deep merge, meaning that existing data is not wiped out by default. Unfortunately,
+  #### Deep Merge
+
+  Untangled merges the response via a deep merge, meaning that existing data is not wiped out by default. Unfortunately,
   this causes a different problem. Let's say you have two UI components that ask for similar information:

   Component A asks for [:a]
@@ -246,17 +431,127 @@
       not asked for alone). This does indicate that your UI is possibly in a state inconsistent with the server, which
       is the reason for the \"avoid this case\" advice.

-  ### Normalization
-
-  Normalization is always *on* in Untangled. You are forced to use the default database format. If you've passed an
-  atom as initial state then initial state is assumed to be pre-normalized, but normalization will always be on. Loads
-  must use real composed queries from the UI for normalization to work (the om `get-query` function adds info to assit
+  #### Normalization
+
+  Normalization is always *on* in Untangled because your application will not work correctly if you don't normalize the
+  data in your database. Loads must use real composed queries from the UI for normalization to work (the om `get-query` function adds info to assit
   with normalization).

   Therefore, you almost *never* want to use a hand-written query that has not been placed on a `defui`. It is perfectly
   acceptable to define queries via `defui` to ensure normalization will work, and this will commonly be the case if your
   UI needs to ask for data in a structure different from what you want to run against the server.

+  For example, say we have some items in our database, and we're planning on showing them grouped by category. We *could*
+  write a server-side handler that could return them this way, but the grouping in the UI is really more of a UI
+  concern (we might also want them sorted by name, etc, etc.). It makes a lot more sense to define a single server-side
+  query that can return the items we want, and then define a UI-side transformation to run as a post-mutation that
+  forms them into the desired structure for the UI.
+
+  So, we need the data in our client database (normalized), but our UI might only have queries related to the grouped
+  view. Thus, we don't have a UI query that meets our server query needs.
+
+  In this situation we could write the following query-and-ident-only components:
+  "
+  (dc/mkdn-pprint-source ItemQuery)
+  (dc/mkdn-pprint-source CategoryQuery)
+  "
+
+  The proper way to now ask the server would be to do something like join this query into a top-level key:
+
+  "
+  (dc/mkdn-pprint-source component-query)
+  "
+
+  The resulting query, if you were to ask for it with `om/get-query` would look the same as this hand-written
+  query:
+
+  "
+  (dc/mkdn-pprint-source hand-written-query)
+  "
+  However, if you were to use the hand-written query then Om would not know how to normalize the server result
+  into your database because the Ident functions would not be known (the `get-query` function adds metadata to
+  the query to tell Om how to normalize the result`).
+
+  The following card demonstrates the difference of merging the following server response: "
+  (dc/mkdn-pprint-source sample-server-response))
+
+(defn merge-using-query [state-atom query data]
+  (let [db (om/tree->db query data true)]
+    (swap! state-atom assoc :resulting-database db)))
+
+(defcard query-response-demo
+  "This card shows the difference between using hand-written queries and queries pulled from
+  defui components (which need not have UI)."
+  (fn [state-atom _]
+    (dom/div nil
+      (dom/button #js {:onClick #(merge-using-query state-atom hand-written-query sample-server-response)} "Merge with Hand-Written Query")
+      (dom/button #js {:onClick #(merge-using-query state-atom component-query sample-server-response)} "Merge with Component Query")))
+  {}
+  {:inspect-data true})
+
+(defcard-doc
+  "
+  and now perhaps you can see the true power of Untangled's approach to data loading! One server query implementation
+  can now serve any of your needs for displaying these items.
+
+  #### Post Mutations
+
+  We've seen the power of using component to generate queries that are simple for the server (even though the UI might
+  want to display the result in a more complex way). Now, we'll finish the example by showing you how post mutations
+  can complete the story (and for Om users, complete your understanding of why a custom parser isn't necessary in Untangled).
+
+  In the prior section we talked about obtaining items that have categories. We wanted a simple server query so that
+  obtaining the items was the same no matter what kind of UI was going to use them (a display of items grouped by category,
+  for example).
+
+  ```text
+  Simple Query Result from Server
+              |
+     auto merge/normalize
+              |
+             \\|/
+      Items with Categories
+              |
+         post mutation
+              |
+             \\|/
+      Items by Category
+  ```
+
+  We all understand doing these kinds of transforms, so this technique gives some real concrete advantages overall:
+
+  - Simple query to the server (only have to write one query handler)
+      - Independent of the server's database structure (do items belong to categories, or just have them, etc).
+  - Simple layout in resulting UI database (normalized into tables and a graph)
+  - Straightforward data transform into what we want to show
+
+  So, let's add in the idea that the UI really wants to show a Toolbar that contains the items
+  grouped by category, but our sample load is as before.
+
+  The Untangled post-mutation can defined as:
+
+  ```clojure
+  (defmethod m/mutate 'server-interaction/group-items [{:keys [state]} k p]
+    {:action (fn [] (swap! state group-items))})
+  ```
+
+  Where the UI components and helper functions are:
+
+  "
+  (dc/mkdn-pprint-source ToolbarItem)
+  (dc/mkdn-pprint-source ToolbarCategory)
+  (dc/mkdn-pprint-source Toolbar)
+  (dc/mkdn-pprint-source add-to-category)
+  (dc/mkdn-pprint-source group-items))
+
+(defcard toolbar-with-items-by-category
+  "This card allows you to simulate the post-mutation defined above, and see the resulting UI and database change. The
+  Reset button will restore the db to the pre-mutation state, so you can A/B compare the before and after picture."
+  (untangled-app Toolbar)
+  (om/tree->db component-query sample-server-response true)
+  {:inspect-data true})
+
+(defcard-doc "
   ### Parameterized Reads

   You may add parameters to your remote reads using an optional argument to data fetch:


minor additions

minor additions


CMR-3207: Fixed comment

CMR-3207: Fixed comment

--- search-app/src/cmr/search/services/query_execution/facets/hierarchical_links_helper.clj
+++ search-app/src/cmr/search/services/query_execution/facets/hierarchical_links_helper.clj
@@ -24,8 +24,7 @@
   [query-params base-field]
   ;; Regex to find any query params for the base-field, and extract the index for each matching
   ;; param. e.g. with a base field of "foo" and param name of "foo[11][bar]", the regex will
-  ;; extract 11 as the index. It would not match "notfoo[11][bar]" because of the different base
-  ;; field.
+  ;; extract 11 as the index.
   (let [field-regex (re-pattern (format "%s\\[(\\d+)\\]\\[.*\\]" base-field))]
     (set (keep #(some-> (re-matches field-regex %) second Integer/parseInt)
                (keys query-params)))))


CMR-1168-3: Merged with master

CMR-1168-3: Merged with master

--- system-int-test/test/cmr/system_int_test/ingest/granule_validation_test.clj
+++ system-int-test/test/cmr/system_int_test/ingest/granule_validation_test.clj
@@ -83,6 +83,8 @@
           (let [concept (d/item->concept (dg/granule collection))]
             (assert-validation-success concept (d/item->concept collection :iso19115))
             (assert-validation-success concept (d/item->concept collection :dif))))
+
+

         (testing "invalid collection xml"
           (assert-validation-errors
@@ -209,61 +211,92 @@
                 [{:path ["CollectionRef"],
                   :errors ["Collection Reference should have at least Entry Title or Short Name and Version Id."]}]
                 (d/item->concept granule :iso-smap)
-                coll-concept))))))
-
-    (testing "with ingested collection"
-      (let [collection (d/ingest "PROV1" (dc/collection {}))]
-        (testing "successful validation of granule"
-          (let [granule-concept (d/item->concept (dg/granule collection))]
-            (assert-validation-success granule-concept)
-
-            (testing "with ingested parent collection"
-              (assert-validation-success granule-concept (d/item->concept collection)))))
-        (testing "invalid granule xml"
-          (assert-validation-errors
-            expected-errors
-            (-> collection
-                dg/granule
-                d/item->concept
-                (assoc :metadata invalid-granule-xml))))))))
-
-(defn polygon
-  "Creates a single ring polygon with the given ordinates. Points must be in counter clockwise order."
-  [& ords]
-  (poly/polygon [(apply umm-s/ords->ring ords)]))
-
-(defn assert-invalid
-  ([coll-attributes gran-attributes field-path errors]
-   (assert-invalid coll-attributes gran-attributes field-path errors :echo10))
-  ([coll-attributes gran-attributes field-path errors metadata-format]
-   (testing "through validation api"
-     (let [coll (dc/collection coll-attributes)
-           coll-concept (d/item->concept coll metadata-format)
-           granule (dg/granule coll gran-attributes)
-           gran-concept (d/item->concept granule)
-           response (ingest/validate-granule gran-concept coll-concept)]
-       (is (= {:status 400
-               :errors [{:path field-path
-                         :errors errors}]}
-              (select-keys response [:status :errors])))))
-
-   (testing "through ingest API"
-     (let [coll (d/ingest "PROV1" (dc/collection coll-attributes) metadata-format)
-           response (d/ingest "PROV1" (dg/granule coll gran-attributes) metadata-format)]
-       (is (= {:status 400
-               :errors [{:path field-path
-                         :errors errors}]}
-              (select-keys response [:status :errors])))))))
-
-(defn assert-valid
-  [coll-attributes gran-attributes]
-  (testing "through validation api"
-    (let [coll (dc/collection coll-attributes)
-          coll-concept (d/item->concept coll)
-          granule (dg/granule coll gran-attributes)
-          gran-concept (d/item->concept granule)
-          response (ingest/validate-granule gran-concept coll-concept)]
-      (is (= {:status 200}
+                coll-concept)))))
+
+      (testing "with ingested collection"
+        (let [collection (d/ingest "PROV1" (dc/collection {}))]
+          (testing "successful validation of granule"
+            (let [granule-concept (d/item->concept (dg/granule collection))]
+              (assert-validation-success granule-concept)
+
+              (testing "with ingested parent collection"
+                (assert-validation-success granule-concept (d/item->concept collection)))))
+          (testing "invalid granule xml"
+            (assert-validation-errors
+              expected-errors
+              (-> collection
+                  dg/granule
+                  d/item->concept
+                  (assoc :metadata invalid-granule-xml))))))))
+
+  (defn polygon
+    "Creates a single ring polygon with the given ordinates. Points must be in counter clockwise order."
+    [& ords]
+    (poly/polygon [(apply umm-s/ords->ring ords)]))
+
+  (defn assert-invalid
+    ([coll-attributes gran-attributes field-path errors]
+     (assert-invalid coll-attributes gran-attributes field-path errors :echo10))
+    ([coll-attributes gran-attributes field-path errors metadata-format]
+     (testing "through validation api"
+       (let [coll (dc/collection coll-attributes)
+             coll-concept (d/item->concept coll metadata-format)
+             granule (dg/granule coll gran-attributes)
+             gran-concept (d/item->concept granule)
+             response (ingest/validate-granule gran-concept coll-concept)]
+         (is (= {:status 400
+                 :errors [{:path field-path
+                           :errors errors}]}
+                (select-keys response [:status :errors])))))
+
+     (testing "through ingest API"
+       (let [coll (d/ingest "PROV1" (dc/collection coll-attributes) metadata-format)
+             response (d/ingest "PROV1" (dg/granule coll gran-attributes) metadata-format)]
+         (is (= {:status 400
+                 :errors [{:path field-path
+                           :errors errors}]}
+                (select-keys response [:status :errors])))))))
+
+  (defn assert-valid
+    [coll-attributes gran-attributes]
+    (testing "through validation api"
+      (let [coll (dc/collection coll-attributes)
+            coll-concept (d/item->concept coll)
+            granule (dg/granule coll gran-attributes)
+            gran-concept (d/item->concept granule)
+            response (ingest/validate-granule gran-concept coll-concept)]
+        (is (= {:status 200}
+               (select-keys response [:status :errors])))))
+
+    (testing "through ingest API"
+      (let [provider-id (get gran-attributes :provider-id "PROV1")
+            coll (d/ingest provider-id (dc/collection coll-attributes))
+            response (d/ingest provider-id (dg/granule coll gran-attributes))]
+        (is (= {:status 200} (select-keys response [:status :errors]))))))
+
+  (defn assert-invalid-spatial
+    ([coord-sys shapes errors]
+     (assert-invalid-spatial coord-sys shapes errors :echo10))
+    ([coord-sys shapes errors metadata-format]
+     (let [shapes (map (partial umm-s/set-coordinate-system coord-sys) shapes)]
+       (assert-invalid {:spatial-coverage (dc/spatial {:gsr coord-sys})}
+                       {:spatial-coverage (apply dg/spatial shapes)}
+                       ["SpatialCoverage" "Geometries" 0]
+                       errors
+                       metadata-format))))
+
+  (defn assert-valid-spatial
+    [coord-sys shapes]
+    (let [shapes (map (partial umm-s/set-coordinate-system coord-sys) shapes)]
+      (assert-valid {:spatial-coverage (dc/spatial {:gsr coord-sys})}
+                    {:spatial-coverage (apply dg/spatial shapes)})))
+
+  (defn assert-conflict
+    [gran-attributes errors]
+    (let [collection (d/ingest "PROV1" (dc/collection))
+          response (d/ingest "PROV1" (dg/granule collection gran-attributes))]
+      (is (= {:status 409
+              :errors errors}
              (select-keys response [:status :errors])))))

   (testing "through ingest API"


remove old code

remove old code


Fixes test failure for some vertical spatial domain values

--- umm-spec-lib/src/cmr/umm_spec/test/expected_conversion.clj
+++ umm-spec-lib/src/cmr/umm_spec/test/expected_conversion.clj
@@ -468,9 +468,7 @@
   [vsd]
   (let [fix-val (fn [x]
                   (when x
-                    (let [x-replaced (str/replace x #"[,=]" "")]
-                      (when-not (str/blank? x-replaced)
-                        x-replaced))))]
+                    (iso/sanitize-value x)))]
     (-> vsd
         (update-in [:Type] fix-val)
         (update-in [:Value] fix-val))))


Added comments.

Added comments.

--- umm-spec-lib/src/cmr/umm_spec/xml_to_umm_mappings/dif9.clj
+++ umm-spec-lib/src/cmr/umm_spec/xml_to_umm_mappings/dif9.clj
@@ -17,14 +17,17 @@
      :EastBoundingCoordinate (value-of el "Easternmost_Longitude")}))

 (defn- parse-instruments
+  "Returns the parsed instruments for the given xml doc."
   [doc]
   (su/parse-short-name-long-name doc "/DIF/Sensor_Name"))

 (defn- parse-just-platforms
+  "Returns the parsed platforms only (without instruments) for the given xml doc."
   [doc]
   (su/parse-short-name-long-name doc "/DIF/Source_Name"))

 (defn- parse-platforms
+  "Returns the parsed platforms with instruments added for the given xml doc."
   [doc]
   (let [platforms (parse-just-platforms doc)
         instruments (parse-instruments doc)]


Checkpoint

Checkpoint

Signed-off-by: Gregory Haskins <640d9fe47775e6723f0355b7315e38f7d98d3539@gmail.com>

--- src/obcc/build/interface.clj
+++ src/obcc/build/interface.clj
@@ -37,14 +37,13 @@
 ;; it to an AST.
 (defn compileintf [path intf]
   (println "Compile " intf)
-  (let [ipath (str path "/src/interfaces")
-        ast (->> (open ipath intf) slurp parse)]
-    [intf ast]))
+  (let [ipath (str path "/src/interfaces")]
+    (->> (open ipath intf) slurp parse)))

 ;; compile all applicable interfaces into a map of ASTs keyed by interface name
 (defn compileall [path config]
   (let [interfaces (getinterfaces config)]
-    (into {} (map #(compileintf path %) interfaces))))
+    (into {} (map #(vector % (compileintf path %)) interfaces))))

 ;;(defn generateproto [intf ast template]
 ;;  (loop [loc ast]


Fix arity of file-response and resource-response

--- ring-core/src/ring/util/response.clj
+++ ring-core/src/ring/util/response.clj
@@ -140,12 +140,14 @@
     :root            - take the filepath relative to this root path
     :index-files?    - look for index.* files in directories, defaults to true
     :allow-symlinks? - serve files through symbolic links, defaults to false"
-  [filepath & [opts]]
-  (if-let [file (find-file filepath opts)]
-    (let [data (file-data file)]
-      (-> (response (:content data))
-          (content-length (:content-length data))
-          (last-modified (:last-modified data))))))
+  ([filepath]
+   (file-response filepath {}))
+  ([filepath options]
+   (if-let [file (find-file filepath options)]
+     (let [data (file-data file)]
+       (-> (response (:content data))
+           (content-length (:content-length data))
+           (last-modified (:last-modified data)))))))

 ;; In Clojure 1.5.1, the as-file function does not correctly decode
 ;; UTF-8 byte sequences.
@@ -314,13 +316,17 @@
     :loader          - resolve the resource in this class loader
     :allow-symlinks? - allow symlinks in classpath directories,
                        defaults to false"
-  [path & [{:keys [root loader] :as opts}]]
-  (let [path      (-> (str "/" path)  (.replace "//" "/"))
-        root+path (-> (str root path) (.replaceAll "^/" ""))
-        load      #(if loader (io/resource % loader) (io/resource %))]
-    (if-not (directory-transversal? root+path)
-      (if-let [resource (load root+path)]
-        (let [response (url-response resource)]
-          (if (or (not (instance? File (:body response)))
-                  (safe-file-resource? response opts))
-            response))))))
+  ([path]
+   (resource-response path {}))
+  ([path options]
+   (let [path      (-> (str "/" path)  (.replace "//" "/"))
+         root+path (-> (str (:root options) path) (.replaceAll "^/" ""))
+         load      #(if-let [loader (:loader options)]
+                      (io/resource % loader)
+                      (io/resource %))]
+     (if-not (directory-transversal? root+path)
+       (if-let [resource (load root+path)]
+         (let [response (url-response resource)]
+           (if (or (not (instance? File (:body response)))
+                   (safe-file-resource? response options))
+             response)))))))


Implement proportions lock button on rect measurements element options sidebar.

With an additional cosmetic refactor.

--- src/uxbox/main/ui/workspace/sidebar/options/rect_measures.cljs
+++ src/uxbox/main/ui/workspace/sidebar/options/rect_measures.cljs
@@ -6,9 +6,7 @@
 ;; Copyright (c) 2015-2016 Juan de la Cruz <delacruzgarciajuan@gmail.com>

 (ns uxbox.main.ui.workspace.sidebar.options.rect-measures
-  (:require [sablono.core :as html :refer-macros [html]]
-            [rum.core :as rum]
-            [lentes.core :as l]
+  (:require [lentes.core :as l]
             [uxbox.util.i18n :refer (tr)]
             [uxbox.util.router :as r]
             [uxbox.util.rstore :as rs]
@@ -24,11 +22,11 @@
             [uxbox.util.dom :as dom]
             [uxbox.util.data :refer (parse-int parse-float read-string)]))

-(defn rect-measures-menu-render
-  [own menu shape]
+(mx/defc rect-measures-menu
+  {:mixins [mx/static]}
+  [menu {:keys [id] :as shape}]
   (letfn [(on-size-change [attr event]
-            (let [value (dom/event->value event)
-                  value (parse-int value 0)
+            (let [value (-> (dom/event->value event) (parse-int 0))
                   sid (:id shape)
                   props {attr value}]
               (rs/emit! (uds/update-size sid props))))
@@ -48,81 +46,83 @@
                   value (parse-int value nil)
                   sid (:id shape)
                   props {attr value}]
-              (rs/emit! (uds/update-radius-attrs sid props))))]
+              (rs/emit! (uds/update-radius-attrs sid props))))
+          (on-proportion-lock-change [event]
+            (if (:proportion-lock shape)
+              (rs/emit! (uds/unlock-proportions id))
+              (rs/emit! (uds/lock-proportions id))))]
     (let [size (geom/size shape)]
-      (html
-       [:div.element-set {:key (str (:id menu))}
-        [:div.element-set-title (:name menu)]
-        [:div.element-set-content
-         ;; SLIDEBAR FOR ROTATION AND OPACITY
-         [:span "Size"]
-         [:div.row-flex
-          [:input.input-text
-           {:placeholder "Width"
-            :type "number"
-            :min "0"
-            :value (:width size)
-            :on-change (partial on-size-change :width)}]
-          [:div.lock-size i/lock]
-          [:input.input-text
-           {:placeholder "Height"
-            :type "number"
-            :min "0"
-            :value (:height size)
-            :on-change (partial on-size-change :height)}]]
+      [:div.element-set {:key (str (:id menu))}
+       [:div.element-set-title (:name menu)]
+       [:div.element-set-content
+        ;; SLIDEBAR FOR ROTATION AND OPACITY
+        [:span "Size"]
+        [:div.row-flex
+         [:input.input-text
+          {:placeholder "Width"
+           :type "number"
+           :min "0"
+           :value (:width size)
+           :on-change (partial on-size-change :width)}]
+         [:div.lock-size
+          {:class (when (:proportion-lock shape) "selected")
+           :on-click on-proportion-lock-change}
+          i/lock]
+         [:input.input-text
+          {:placeholder "Height"
+           :type "number"
+           :min "0"
+           :value (:height size)
+           :on-change (partial on-size-change :height)}]]

-         [:span "Position"]
-         [:div.row-flex
-          [:input.input-text
-           {:placeholder "x"
-            :type "number"
-            :value (:x1 shape "")
-            :on-change (partial on-pos-change :x)}]
-          [:input.input-text
-           {:placeholder "y"
-            :type "number"
-            :value (:y1 shape "")
-            :on-change (partial on-pos-change :y)}]]
+        [:span "Position"]
+        [:div.row-flex
+         [:input.input-text
+          {:placeholder "x"
+           :type "number"
+           :value (:x1 shape "")
+           :on-change (partial on-pos-change :x)}]
+         [:input.input-text
+          {:placeholder "y"
+           :type "number"
+           :value (:y1 shape "")
+           :on-change (partial on-pos-change :y)}]]

-         [:span "Border radius"]
-         [:div.row-flex
-          [:input.input-text
-           {:placeholder "rx"
-            :type "number"
-            :value (:rx shape "")
-            :on-change (partial on-border-change :rx)}]
-          [:div.lock-size i/lock]
-          [:input.input-text
-           {:placeholder "ry"
-            :type "number"
-            :value (:ry shape "")
-            :on-change (partial on-border-change :ry)}]]
+        [:span "Border radius"]
+        [:div.row-flex
+         [:input.input-text
+          {:placeholder "rx"
+           :type "number"
+           :value (:rx shape "")
+           :on-change (partial on-border-change :rx)}]
+         [:div.lock-size i/lock]
+         [:input.input-text
+          {:placeholder "ry"
+           :type "number"
+           :value (:ry shape "")
+           :on-change (partial on-border-change :ry)}]]

-         [:span "Rotation"]
-         [:div.row-flex
-          [:input.slidebar
-           {:type "range"
-            :min 0
-            :max 360
-            :value (:rotation shape 0)
-            :on-change on-rotation-change}]]
+        [:span "Rotation"]
+        [:div.row-flex
+         [:input.slidebar
+          {:type "range"
+           :min 0
+           :max 360
+           :value (:rotation shape 0)
+           :on-change on-rotation-change}]]

-         [:div.row-flex
-          [:input.input-text
-           {:placeholder ""
-            :type "number"
-            :min 0
-            :max 360
-            :value (:rotation shape "0")
-            :on-change on-rotation-change
-            }]
-          [:input.input-text
-           {:style {:visibility "hidden"}}]
-          ]]]))))
+        [:div.row-flex
+         [:input.input-text
+          {:placeholder ""
+           :type "number"
+           :min 0
+           :max 360
+           :value (:rotation shape "0")
+           :on-change on-rotation-change
+           }]
+         [:input.input-text
+          {:style {:visibility "hidden"}}]
+         ]]])))

-(def rect-measures-menu
-  (mx/component
-   {:render rect-measures-menu-render
-    :name "rect-measures"
-    :mixins [mx/static]}))

+


#36 use str/blank? instead of seq

#36 use str/blank? instead of seq

--- src/org/zalando/stups/friboo/user.clj
+++ src/org/zalando/stups/friboo/user.clj
@@ -69,7 +69,7 @@
      (log/warn "ACCESS DENIED (unauthenticated) because token does not contain user information.")
      (api/throw-error 403 "no user information available"))
    (let [robot-team (get-service-team service-user-url token user-id)]
-     (when-not (seq robot-team)
+     (when (clojure.string/blank? robot-team)
        (log/warn "ACCESS DENIED (unauthorized) because user is not in any team.")
        (api/throw-error 403 "user has no teams"
                         {:user user-id}))


indentation

indentation

--- test/open_company/integration/section/section_manipulation.clj
+++ test/open_company/integration/section/section_manipulation.clj
@@ -322,34 +322,34 @@
                   placeholder (dissoc (common-res/section-by-name :highlights) :section-name :core)]
               (:status response) => 200
               (:sections body) => new-sections
-                                      ; verify placeholder flag and content in response
+              ;; verify placeholder flag and content in response
               (:placeholder resp-highlights) => true
               resp-highlights => (contains placeholder)
-                                      ; verify placeholder flag and content in DB
+              ;; verify placeholder flag and content in DB
               (:placeholder db-highlights) => true
               db-highlights => (contains placeholder)))

           (future-fact "that used to exist"
-                       (let [new-sections {:company [] :progress [] :financial []}
-                             response (mock/api-request :patch (company-rep/url r/slug) {:body {:sections new-sections}})
-                             body (mock/body-from-response response)
-                             db-company (company/get-company conn r/slug)]
-                         (:status response) => 200
-                         (:sections body) => new-sections
-                                      ; verify update is not in the response
-                         (:update body) => nil
-                                      ; verify update not in the DB
-                         (:update db-company) => nil)
-                       (let [new-sections {:company [] :progress ["update"] :financial []}
-                             response (mock/api-request :patch (company-rep/url r/slug) {:body {:sections new-sections}})
-                             body (mock/body-from-response response)
-                             db-company (company/get-company conn r/slug)]
-                         (:status response) => 200
-                         (:sections body) => new-sections
-                                      ; verify update is not in the response
-                         (:update body) => (contains r/text-section-1)
-                                      ; verify update not in the DB
-                         (:update db-company) => (contains r/text-section-1))))
+            (let [new-sections {:company [] :progress [] :financial []}
+                  response (mock/api-request :patch (company-rep/url r/slug) {:body {:sections new-sections}})
+                  body (mock/body-from-response response)
+                  db-company (company/get-company conn r/slug)]
+              (:status response) => 200
+              (:sections body) => new-sections
+              ;; verify update is not in the response
+              (:update body) => nil
+              ;; verify update not in the DB
+              (:update db-company) => nil)
+            (let [new-sections {:company [] :progress ["update"] :financial []}
+                  response (mock/api-request :patch (company-rep/url r/slug) {:body {:sections new-sections}})
+                  body (mock/body-from-response response)
+                  db-company (company/get-company conn r/slug)]
+              (:status response) => 200
+              (:sections body) => new-sections
+              ;; verify update is not in the response
+              (:update body) => (contains r/text-section-1)
+              ;; verify update not in the DB
+              (:update db-company) => (contains r/text-section-1))))

         (facts "with section content"

@@ -359,25 +359,25 @@
                 kudos-placeholder (common-res/section-by-name "kudos")]

             (future-fact "with minimal content"
-                         (let [kudos-content {:body "Fred is killing it"}
-                               response (mock/api-request :patch (company-rep/url r/slug) {:body {:sections new-sections
-                                                                                :kudos kudos-content}})
-                               body (mock/body-from-response response)
-                               db-company (company/get-company conn r/slug)]
-                           (:status response) => 200
-                           (:body response) => nil))
+              (let [kudos-content {:body "Fred is killing it"}
+                    response (mock/api-request :patch (company-rep/url r/slug) {:body {:sections new-sections
+                                                                                :kudos kudos-content}})
+                    body (mock/body-from-response response)
+                    db-company (company/get-company conn r/slug)]
+                (:status response) => 200
+                (:body response) => nil))

             (future-fact "with maximal content"
-                         (let [kudos-content {:title "Great Jobs!" :headline "Good stuff" :body "Fred is killing it"}
-                               response (mock/api-request :patch (company-rep/url r/slug) {:body {:sections new-sections
-                                                                                :kudos kudos-content}})
-                               body (mock/body-from-response response)
-                               db-company (company/get-company conn r/slug)]
-                           (:status response) => 200
-                           (:body response) => nil))
+              (let [kudos-content {:title "Great Jobs!" :headline "Good stuff" :body "Fred is killing it"}
+                    response (mock/api-request :patch (company-rep/url r/slug) {:body {:sections new-sections
+                                                                                :kudos kudos-content}})
+                    body (mock/body-from-response response)
+                    db-company (company/get-company conn r/slug)]
+                (:status response) => 200
+                (:body response) => nil))

             (future-fact "with too much content"
-
-                         (future-fact "extra properties aren't allowed")
-
-                         (future-fact "read/only properties are ignored")))))))))+
+              (future-fact "extra properties aren't allowed")
+
+              (future-fact "read/only properties are ignored")))))))))


Make function private

Make function private

--- src/play_clj/core_global.clj
+++ src/play_clj/core_global.clj
@@ -105,10 +105,6 @@
             false))]
     (proxy [GestureDetector] [listener])))

-(defn add-input!
+(defn- add-input!
   [^InputProcessor p]
   (.addProcessor ^InputMultiplexer (.getInputProcessor (Gdx/input)) p))
-
-(defn remove-input!
-  [^InputProcessor p]
-  (.removeProcessor ^InputMultiplexer (.getInputProcessor (Gdx/input)) p))


Make macros private

Make macros private

--- src/play_clj/g2d_physics.clj
+++ src/play_clj/g2d_physics.clj
@@ -27,15 +27,15 @@

 ; bodies

-(defmacro body-type
+(defmacro ^:private body-type
   [k]
-  `~(symbol (str u/main-package ".physics.box2d.BodyDef$BodyType/"
-                 (u/key->pascal k) "Body")))
+  `(symbol (str u/main-package ".physics.box2d.BodyDef$BodyType/"
+                (u/key->pascal ~k) "Body")))

 (defmacro body-def
   [k & options]
   `(let [^BodyDef object# (BodyDef.)]
-     (set! (. object# type) (body-type ~k))
+     (set! (. object# type) ~(body-type k))
      (u/fields! object# ~@options)))

 (defmacro body!
@@ -83,14 +83,14 @@

 ; joints

-(defmacro joint-init
+(defmacro ^:private joint-init
   [k]
-  `(~(symbol (str u/main-package ".physics.box2d.joints."
-                  (u/key->pascal k) "JointDef."))))
+  `(symbol (str u/main-package ".physics.box2d.joints."
+                (u/key->pascal ~k) "JointDef.")))

 (defmacro joint-def
   [k & options]
-  `(let [object# (joint-init ~k)]
+  `(let [object# (~(joint-init k))]
      (u/fields! object# ~@options)))

 (defn create-joint!*


Nil pruning as per https://github.com/MastodonC/kixi.hecuba/pull/638#discussion_r39143340

--- src/cljs/kixi/hecuba/tabs/hierarchy/tapestry.cljs
+++ src/cljs/kixi/hecuba/tabs/hierarchy/tapestry.cljs
@@ -99,10 +99,10 @@

 (defn set-new-heatmap-data!
   [cursor data lcb ucb gradations dates]
-  (let [lcb (if (nil? lcb) (.floor js/Math (apply min data)) lcb)
-        ucb (if (nil? ucb) (.ceil js/Math (apply max data)) ucb)
+  (let [lcb (if-not lcb (.floor js/Math (apply min data)) lcb)
+        ucb (if-not ucb (.ceil js/Math (apply max data)) ucb)
         midcb ((interpolate lcb ucb) 0.5)
-        gradations (if (nil? gradations) default-gradations gradations)
+        gradations (if-not gradations default-gradations gradations)
         adjusted-data (if @chart-fill-oor-cells? (map #(m/clamp % lcb ucb) data) data)]
     (om/update! cursor :dates dates)
     (om/update! cursor :data data)


Typo in timeseries.

Typo in timeseries.

--- src/clj/forma/hadoop/jobs/timeseries.clj
+++ src/clj/forma/hadoop/jobs/timeseries.clj
@@ -53,7 +53,7 @@
   (let [mk-tseries (form-tseries missing-val)
         series-src (<- [?name ?t-res ?location ?pix-idx ?timeseries]
                        (chunk-source _ ?chunk)
-                       (io/unpack-chunk-val ?chunk
+                       (schema/unpack-chunk-val ?chunk
                                             :> ?name ?t-res ?date ?location ?datachunk)
                        (mk-tseries ?t-res ?date ?datachunk
                                    :> ?pix-idx ?start ?end ?tseries)


Minor ui fix

Minor ui fix

--- src/cljs/salava/admin/ui/statistics.cljs
+++ src/cljs/salava/admin/ui/statistics.cljs
@@ -172,15 +172,16 @@
    [m/modal-window]
    [:div
     [:div.row
-     [:div.btn-toolbar.pull-right {:style {:margin-bottom "20px"}}
-      [:a.btn.btn-primary.btn-bulky
-       {:href "#"
-        :on-click #(if (= "text" @visible-content) (reset! visible-content "graphic") (reset! visible-content "text"))}
-       (if (= "graphic" @visible-content) (t :admin/Plaintext) (t :admin/Showgraphicalui))]
-      [:a.btn.btn-primary.btn-bulky
-       {:href "#"
-        :on-click #(export-stats state)}
-       (t :admin/ExportCSV)]]]
+     [:div.col-md-12
+      [:div.btn-toolbar.pull-right {:style {:margin-bottom "20px"}}
+       [:a.btn.btn-primary.btn-bulky
+        {:href "#"
+         :on-click #(if (= "text" @visible-content) (reset! visible-content "graphic") (reset! visible-content "text"))}
+        (if (= "graphic" @visible-content) (t :admin/Plaintext) (t :admin/Showgraphicalui))]
+       [:a.btn.btn-primary.btn-bulky
+        {:href "#"
+         :on-click #(export-stats state)}
+        (t :admin/ExportCSV)]]]]
     [:div.row
      [:div.col-md-12
       (if (= "text" @visible-content)


Document the keys of the notes.

Document the keys of the notes.

--- src/klangmeister/views.cljs
+++ src/klangmeister/views.cljs
@@ -27,13 +27,16 @@
       (row "bpm" "Make a transformation from beats to seconds." "((bpm 120) 3) => 1.5")
       (row "comp" "Join together several transformations." "((comp C major) 2) => 64")
       (row "def" "Define a name with a value. Use it before the `->>`." "(def key (comp C major))")
+      (row ":duration" "The duration of each note." "")
       (row "flat" "Transform a number of semitones down one." "(flat 72) => 71")
       (row ":instrument" "Specifies the synth to play. Currently :bell, :buzz or :fuzz." "")
       (row "major" "Transform a rank of a major scale into semitones." "(major 2) => 4")
       (row "minor" "Transform a rank of a minor scale into semitones." "(minor 2) => 3")
       (row "phrase" "Transform a sequence of durations and a sequence of pitches into a melody." "(phrase [1 1 2] [0 2 4])")
+      (row ":pitch" "The pitch of each note." "")
       (row "sharp" "Transform a number of semitones up one." "(sharp 70) => 71")
       (row "then" "Put one melody after another." "(->> bass (then guitar))")
+      (row ":time" "The time each note plays at." "")
       (row "where" "Transform an attribute of each note using the specified transformation." "(where :pitch inc notes)")
       (row "with" "Put two melodies together." "(with bass guitar)")]]))


Change the system vars to friendlier names.

--- dev/user.clj
+++ dev/user.clj
@@ -50,12 +50,12 @@
 (def los  (vlocal/create-local-object-storage itg/integration-path))
 (def lis  (create-image-storage los))

-(def S (create-system lis))
+(def system-local (create-system lis))

 (def s3os  (vs3/create-s3-object-storage storage-creds))
 (def s3s   (create-image-storage s3os "images" "images/thumb"))

-(def Ss (create-system s3s))
+(def system-s3 (create-system s3s))

 (comment
   (start S 8080)


Replace .size with count for clojure collections

--- test/integration/mongo_query_test.clj
+++ test/integration/mongo_query_test.clj
@@ -29,7 +29,7 @@

     (fact "get-datasets returns sequence of maps"
       (let [ds (data/get-datasets)]
-        (>= (.size ds) 1) => true
+        (>= (count ds) 1) => true
         (map :name ds) => (contains ["integration_test"] :gaps-ok)))

     (fact "get-metadata returns metadata for a dataset"
@@ -47,7 +47,7 @@
              result (data/get-find db coll query)]
         (> (:total result) limit ) => true
         (:size result) => limit
-        (.size (:data result)) => limit)))
+        (count (:data result)) => limit)))

   (facts "about get-aggregation"

@@ -60,7 +60,7 @@
         (map :state_abbr (:data result)) => ["NC" "NY" "PA"]
         (:total result) => 3
         (:size result) => 3
-        (.size (:data result)) => 3)))
+        (count (:data result)) => 3)))

   (facts "about execute"

@@ -85,7 +85,7 @@
             q (params->Query {:$limit limit} slicedef)
             result (query/execute db coll q)
             query_result (:result result)]
-        (.size (:data query_result)) => limit
+        (count (:data query_result)) => limit
         (:size query_result) => limit
         (> (:total query_result) limit) => true))

@@ -118,7 +118,7 @@
             query_result (:result result)]
         (:size query_result) => 3
         (:total query_result) => 3
-        (.size (:data query_result)) => 3
+        (count (:data query_result)) => 3
         (:data query_result) => [{:sum_tax_returns 15, :count_tax_returns 5, :min_tax_returns 1, :max_tax_returns 5, :state_abbr "NC"},
                                  {:sum_tax_returns 65, :count_tax_returns 5, :min_tax_returns 11, :max_tax_returns 15, :state_abbr "NY"},
                                  {:sum_tax_returns 40, :count_tax_returns 5, :min_tax_returns 6, :max_tax_returns 10, :state_abbr "PA"}])))


SeqFileTextToFiles.clj: fixed namespace name

--- src/org/altlaw/util/hadoop/SeqFileTextToFiles.clj
+++ src/org/altlaw/util/hadoop/SeqFileTextToFiles.clj
@@ -1,4 +1,4 @@
-(ns org.altlaw.jobs.util.hadoop.SeqFileTextToFiles
+(ns org.altlaw.util.hadoop.SeqFileTextToFiles
   (:gen-class)
   (:import (org.altlaw.util.hadoop LocalSetup)
            (org.apache.hadoop.io Text SequenceFile$Reader)


remove defs

remove defs

--- src/philly_show_checker/server/api/v1/session.clj
+++ src/philly_show_checker/server/api/v1/session.clj
@@ -12,8 +12,6 @@
   )

 (k-dsl/api-post
- (def request request)
- (def body body)
  (if (nil? (session-helpers/session-user-id))
    (if (attempt-login body)
      {:status "OK"


changed name to window-aggregator

changed name to window-aggregator


More debugging junk (WIP)

More debugging junk (WIP)

This version isn't fit for human consumption. But I desperately need to
move it to a different computer


[fix] event transfer hash turned into a function

that is silly

Signed-off-by: yenda <96f164ad4d9b2b0dacf8ebee2bb1eeb3aa69adf1@status.im>


Refactor.

Refactor.

--- src/datascript/core.cljs
+++ src/datascript/core.cljs
@@ -31,9 +31,7 @@
     (vec (vals (subseq index >= search-start <= search-stop))))))

 (defprotocol ISearch
-  (-search [data pattern callback]))
-
-(defprotocol Idb
+  (-search [data pattern callback])
   (add-record [data e a v]))

 (defrecord DB [eav aev ave]
@@ -53,8 +51,6 @@
       (slice-it ave [a nil nil] callback)            ;; _ a _
       (callback (filter #(= v (.-v %)) eav))         ;; _ _ v
       (callback eav)]))                              ;; _ _ _
-
-  Idb
   (add-record [_ e a v]
     (DB.
       (assoc eav [e a v] [e a v])


Updated ring-devel Hiccup dependency to 1.0.3

--- ring-devel/project.clj
+++ ring-devel/project.clj
@@ -4,7 +4,7 @@
   :license {:name "The MIT License"
             :url "http://opensource.org/licenses/MIT"}
   :dependencies [[ring/ring-core "1.2.0-beta1"]
-                 [hiccup "1.0.0"]
+                 [hiccup "1.0.3"]
                  [clj-stacktrace "0.2.5"]
                  [ns-tracker "0.2.1"]]
   :profiles


Fix last written? case

Fix last written? case

--- src/onyx/plugin/datomic.clj
+++ src/onyx/plugin/datomic.clj
@@ -494,7 +494,7 @@
                                    (d/transact-async conn (:tx (:message tx))))
                                  (mapcat :leaves (:tree (:onyx.core/results event))))
                            (into [] (comp (map deref))))
-     :onyx.core/written? true})
+     :datomic/written? true})

   (seal-resource
       [_ _]


Maybe peer links are being gc'd

Maybe peer links are being gc'd

--- src/onyx_benchmark/peer.clj
+++ src/onyx_benchmark/peer.clj
@@ -102,6 +102,7 @@
                      :onyx/id id
                      :onyx.messaging/bind-addr (slurp "http://169.254.169.254/latest/meta-data/local-ipv4")
                      :onyx.messaging/peer-ports (vec (range 40000 40200))
+                     :onyx.messaging/peer-link-gc-interval 99999999
                      ;:onyx.messaging.aeron/embedded-driver? false
                      :onyx.peer/join-failure-back-off 500
                      :onyx.peer/job-scheduler :onyx.job-scheduler/greedy


Indentation fix :unamused:

Indentation fix :unamused:


Move slurp / spit down

Move slurp / spit down

--- planck-cljs/src/planck/io.cljs
+++ planck-cljs/src/planck/io.cljs
@@ -67,17 +67,6 @@
   *err*
   (Writer. js/PLANCK_RAW_WRITE_STDERR js/PLANCK_RAW_FLUSH_STDERR))

-(defn slurp
-  "Slurps a file"
-  [filename]
-  (or (js/PLANCK_READ_FILE filename)
-    (throw (js/Error. filename))))
-
-(defn spit
-  "Spits a file"
-  [filename content]
-  (js/PLANCK_WRITE_FILE filename content)
-  nil)

 (defn- fission! [atom f & args]
   "Breaks an atom's value into two parts. The supplied function should
@@ -109,4 +98,16 @@
                                       residual))
                                   (subs s 0 n)]))))
     (when (reset! buffer (-read *in*))
-      (recur))))+      (recur))))
+
+(defn slurp
+  "Slurps a file"
+  [filename]
+  (or (js/PLANCK_READ_FILE filename)
+    (throw (js/Error. filename))))
+
+(defn spit
+  "Spits a file"
+  [filename content]
+  (js/PLANCK_WRITE_FILE filename content)
+  nil)


fixing namespace

fixing namespace

--- src/overtone/inst/synth.clj
+++ src/overtone/inst/synth.clj
@@ -1,5 +1,6 @@
 (ns overtone.inst.synth
-  (:use [overtone.sc gens envelope]
+  (:use [overtone.sc ugens envelope]
+        [overtone.sc.cgens mix]
         [overtone.sc.machinery.ugen.fn-gen]
         [overtone.music pitch]
         [overtone.studio mixer inst]))
@@ -18,14 +19,14 @@
     (* 0.1 env snd)))

 (definst tb303
-  [note {:default 60 :min 0 :max 120 :step 1}
-   wave {:default 1 :min 0 :max 2 :step 1}
-   r {:default 0.8 :min 0.01 :max 0.99 :step 0.01}
-   attack {:default 0.01 :min 0.001 :max 4 :step 0.001}
-   decay {:default 0.1 :min 0.001 :max 4 :step 0.001}
-   sustain {:default 0.6 :min 0.001 :max 0.99 :step 0.001}
-   release {:default 0.01 :min 0.001 :max 4 :step 0.001}
-   cutoff {:default 100 :min 1 :max 20000 :step 1}
+  [note       {:default 60 :min 0 :max 120 :step 1}
+   wave       {:default 1 :min 0 :max 2 :step 1}
+   r          {:default 0.8 :min 0.01 :max 0.99 :step 0.01}
+   attack     {:default 0.01 :min 0.001 :max 4 :step 0.001}
+   decay      {:default 0.1 :min 0.001 :max 4 :step 0.001}
+   sustain    {:default 0.6 :min 0.001 :max 0.99 :step 0.001}
+   release    {:default 0.01 :min 0.001 :max 4 :step 0.001}
+   cutoff     {:default 100 :min 1 :max 20000 :step 1}
    env-amount {:default 0.01 :min 0.001 :max 4 :step 0.001}]
   (let [freq       (midicps note)
         freqs      [freq (* 1.01 freq)]


fix typo on name

fix typo on name

--- src/pc/http/admin/outer.clj
+++ src/pc/http/admin/outer.clj
@@ -15,7 +15,7 @@
                                            "Please log in with Google"]
                                      "."]))))

-(defpage root "/health-check" [req]
+(defpage health-check "/health-check" [req]
   {:status 200 :body ":up"})

 (defpage google-auth "/auth/google" [req]


Make id field mandatory on update-page-metadata endpoint.

--- src/uxbox/frontend/pages.clj
+++ src/uxbox/frontend/pages.clj
@@ -61,8 +61,7 @@
 ;; --- Update Page Metadata

 (s/def ::update-page-metadata
-  (s/keys :req-un [::metadata ::project ::us/name]
-          :opt-un [::us/id]))
+  (s/keys :req-un [::us/id ::metadata ::project ::us/name]))

 (defn update-page-metadata
   [{user :identity params :route-params data :data}]


Add some sample data structures.

Add some sample data structures.

--- domain/src/domain/core.clj
+++ domain/src/domain/core.clj
@@ -5,6 +5,44 @@
             [ring.middleware.json :refer [wrap-json-body wrap-json-response]]
             [ring.util.response :refer [response]])
   (:gen-class))
+
+(def features
+  "A map that holds features and their possible values"
+  {:ethnicity [:asian :black :hispanic :white]
+   :location  [:prime :average]
+   :gender    [:male :female]
+   :age       [:young :mid :old]
+   :weather   [:sunny :rainny]})
+
+(def ads->features-example
+  "An example of a map that holds each ad and its preferred features"
+  {:ad1 {:ethnicity :asian
+         :weather   :sunny
+         :location  :prime
+         :url       "http://example.com/1.jpg"}
+   :ad2 {:age       :mid
+         :location  :average
+         :url       "http://example.com/2.jpg"}
+   :ad3 {:weather   :sunny
+         :url       "http://example.com/3.jpg"}
+   :ad4 {:gender    :male
+         :age       :old
+         :location :prime
+         :url       "http://example.com/4.jpg"}})
+
+(def result-features-example
+  "An example of a resulting map obtained from Tobiaz' UI and CV"
+  {:location  :prime
+   :ethnicity :asian
+   :weather   :sunny
+   :gender    :male})
+
+; Maybe we can add this information to the resulting response
+(def advertisers->ads
+  "A map that holds ads per advertiser"
+  {:advertiser1 #{:ad1 :ad2}
+   :advertiser2 #{:ad3}
+   :advertiser3 #{:ad4}})

 (defroutes app-routes
   (GET "/status" [] "OMG HI!")


turn down logging

turn down logging

--- src/babel/directory.cljc
+++ src/babel/directory.cljc
@@ -19,9 +19,9 @@
            (if (realized? en)
              en
              (deliver en
-                      (do (log/info (str "starting to load english model.."))
+                      (do (log/debug (str "starting to load english model.."))
                           (let [model (babel.english.grammar/small)]
-                            (log/info (str "finished loading english model."))
+                            (log/debug (str "finished loading english model."))
                             (conj model
                                   {:generate-fn (fn [spec]
                                                   (en/generate spec :model model))}))))))
@@ -48,7 +48,6 @@
                                                                                (= :verb (dag_unify.core/get-in v [:synsem :cat]))))
                                                                          (flatten (vals (:lexicon model)))))))))}))))))

-
      :fr (fn []
            (if (realized? fr)
              fr


check for (not (= :fail %)) rather than (not (fail? %))

--- src/babel/lexiconfn.cljc
+++ src/babel/lexiconfn.cljc
@@ -621,7 +621,7 @@
 (defn apply-default [original default]
   (let [result
         (unify original default)]
-    (if (not (fail? result))
+    (if (not (= :fail result))
       result
       original)))


do (group-by-two) during analysis, not rule compilation

--- src/babel/morphology.clj
+++ src/babel/morphology.clj
@@ -2,31 +2,26 @@
   (:require [clojure.tools.logging :as log]
             [clojure.string :as string]
             [dag_unify.core :refer [fail? strip-refs unify]]))
+
+(declare group-by-two)

 (defn analyze [surface-form lexicon replace-patterns]
   "Analyze a single surface form into a set of lexical forms."
   (concat (if (get lexicon surface-form)
             (get lexicon surface-form))
           (mapcat
-           (fn [replace-pattern]
-             (let [ ;; regular expression that matches the surface form
-                   from (nth (:p replace-pattern) 0)]
-               (log/debug (str "matching replace-pattern:" replace-pattern " against surface-form: " surface-form))
-               (if (re-matches from surface-form)
-                 (let [;; expression that is used by string/replace along with the first regexp and the surface form,
-                       ;; to create the lexical string
-                       to (nth (:p replace-pattern) 1)
-
-                       ;; unifies with the lexical entry to create the inflected form.
-                       unify-with (if (:u replace-pattern)
-                                    (:u replace-pattern)
-                                    :top) ;; default unify-with
-
-                       lex (string/replace surface-form from to)]
-                   (filter (fn [result] (not (= :fail result)))
-                           (map (fn [lexical-entry]
-                                  (unify unify-with lexical-entry))
-                                (get lexicon lex)))))))
+           (fn [{g :g agr :agr p :p u :u}]
+             (mapcat
+              (fn [[from to]]
+                (if (re-matches from surface-form)
+                  (let [;; unifies with the lexical entry to create the inflected form.
+                        unify-with (or u :top)
+                        lex (string/replace surface-form from to)]
+                    (filter (fn [result] (not (= :fail result)))
+                            (map (fn [lexical-entry]
+                                   (unify unify-with lexical-entry))
+                                 (get lexicon lex))))))
+              (group-by-two p)))
            replace-patterns)))

 (defn conjugate [infinitive unify-with replace-patterns]
@@ -52,24 +47,15 @@
                           (string/replace infinitive from to)))))
                   replace-patterns)))))

-(defn group-by-two [remaining]
-  (if (> (count remaining) 1)
-    (cons
-     [(nth remaining 0)
-      (nth remaining 1)]
-     (group-by-two (rest (rest remaining))))))
-
 (defn compile-patterns [unify-with patterns]
-  (mapcat (fn [{g :g agr :agr p :p u :u}]
-            (let [u (unify unify-with
-                              (or agr :top)
-                              (or u :top))]
-              (map (fn [pair]
-                     {:u u
-                      :g g
-                      :agr agr
-                      :p pair})
-                   (group-by-two p))))
+  (map (fn [{g :g agr :agr p :p u :u}]
+         (let [u (unify unify-with
+                        (or agr :top)
+                        (or u :top))]
+           {:u u
+            :g g
+            :agr agr
+            :p p}))
        patterns))

 (defn do-replace-on [infinitive patterns]
@@ -79,3 +65,10 @@
         (cons (string/replace infinitive from to)
               (do-replace-on infinitive (rest (rest patterns))))
         (do-replace-on infinitive (rest (rest patterns)))))))
+
+(defn group-by-two [remaining]
+  (if (not (empty? (rest remaining)))
+    (cons
+     [(nth remaining 0)
+      (nth remaining 1)]
+     (group-by-two (rest (rest remaining))))))


Removes utility functions from user.clj

Removes utility functions from user.clj

--- dev-system/dev/user.clj
+++ dev-system/dev/user.clj
@@ -78,47 +78,4 @@
   (future
     (tests/run-all-tests {:fail-fast? true :speak? true})))

-;;; Use these functions at the REPL for fun and profit. Soon you won't
-;;; want to do anything else.
-
-;; this is a function so that you can load the code while (reset)
-;; is running
-(defn get-db [] (-> system :apps :metadata-db :db))
-
-(defn get-ingest [] (-> system :apps :ingest))
-
-(defn get-providers
-  []
-  (cmr.metadata-db.data.providers/get-providers (get-db)))
-
-(defn get-provider
-  [id]
-  (cmr.metadata-db.data.providers/get-provider (get-db) id))
-
-(defn to-provider
-  [x]
-  (if (string? x)
-    (get-provider x)
-    x))
-
-(defn find-concepts
-  [provider params]
-  (cmr.metadata-db.data.concepts/find-concepts (get-db) [(to-provider provider)] params))
-
-(defn get-concept
-  [concept-id]
-  (let [{:keys [concept-type provider-id]} (concepts/parse-concept-id concept-id)]
-    (last (find-concepts provider-id {:concept-id concept-id
-                                      :concept-type concept-type}))))
-
-(defn save-granule
-  [granule]
-  (cmr.ingest.services.ingest-service/save-granule {:system (get-ingest)} granule))
-
-(defn find-concepts
-  [params]
-  (cmr.metadata-db.services.search-service/find-concepts
-   {:system (-> system :apps :metadata-db)}
-   params))
-
 (info "Custom dev-system user.clj loaded.")


CMR-2167: Fixed database setting

CMR-2167: Fixed database setting

--- dev-system/dev/user.clj
+++ dev-system/dev/user.clj
@@ -41,8 +41,8 @@
   ;; MAKE SURE YOU DISABLE SYMANTEC ANTIVIRUS BEFORE STARTING THE TESTS WITH EXTERNAL DB
   ;; Renable them when you're done

-  ; (system/set-dev-system-db-type! :in-memory)
-  (system/set-dev-system-db-type! :external)
+  (system/set-dev-system-db-type! :in-memory)
+  ; (system/set-dev-system-db-type! :external)

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


Fix the reference warning for buddy.core.bytes/bytes?

WARNING: bytes? already refers to: #'clojure.core/bytes? in namespace: buddy.core.bytes, being replaced by: #'buddy.core.bytes/bytes?

--- src/buddy/core/bytes.clj
+++ src/buddy/core/bytes.clj
@@ -15,7 +15,7 @@
 (ns buddy.core.bytes
   "A collection of functions for work with byte arrays
   and bytes."
-  (:refer-clojure :exclude [concat])
+  (:refer-clojure :exclude [bytes? concat])
   (:import java.nio.ByteBuffer
            java.util.Arrays))


add types for entities

add types for entities

--- src/ca_recipe/recipe.clj
+++ src/ca_recipe/recipe.clj
@@ -1,20 +1,24 @@
-(defrecord Recipe
-    [name
-     author
-     description
-     ingredients
-     steps
-     servings
+(ns ca-recipe.recipe
+  (:require [schema.core :as s]))
+
+(s/defrecord Ingredient
+    [name :- s/Str
+     quantity :- s/Int
+     unit :- s/Keywort
      ])

-(defrecord Ingredient
-    [name
-     quantity
-     unit
+(s/defrecord Recipe
+    [name :- s/Str
+     author :- s/Str
+     description :- s/Str
+     ingredients :- [Ingredient]
+     steps :- [s/Str]
+     servings :- s/Int
      ])

-(defrecord Person
-    [fname
-     lname])
+(s/defrecord Person
+    [fname :- s/Str
+     lname :- s/Str
+     ])


errors printout

errors printout

--- src/celestial/config.clj
+++ src/celestial/config.clj
@@ -75,8 +75,7 @@
   [c]
   (cond-> (-> c celestial-v second base-v second)
     (get-in c [:hypervisor :proxmox]) (-> proxmox-v second)
-    (get-in c [:hypervisor :aws])  (-> aws-v second)
-    ))
+    (get-in c [:hypervisor :aws])  (-> aws-v second)))

 (def config-paths
   ["/etc/celestial.edn" (<< "~(System/getProperty \"user.home\")/.celestial.edn")])
@@ -90,7 +89,7 @@
   (let [st (java.io.StringWriter.)]
     (binding [*out* st]
       (clojure.pprint/pprint m))
-    (error st)))
+    (error "Following configuration errors found:\n" st)))

 (defn read-and-validate []
   (let [c (conf/read-config path) ]


Support Clojure 1.9.0

Support Clojure 1.9.0

--- modules/reitit-core/src/reitit/trie.cljc
+++ modules/reitit-core/src/reitit/trie.cljc
@@ -296,9 +296,9 @@
          (let [fields (keys params)]
            (if (some qualified-keyword? fields)
              params
-             (let [name (gensym "PathParams")
-                   ctor (symbol (str "map->" name))]
-               (eval `(do (defrecord ~name ~(mapv symbol fields)) (~ctor {}))))))))))
+             (let [sym (gensym "PathParams")
+                   ctor (symbol (str "map->" sym))]
+               (eval `(do (defrecord ~sym ~(mapv (comp symbol name) fields)) (~ctor {}))))))))))

 (defn insert
   "Returns a trie with routes added to it."


another Windows path issue

another Windows path issue

--- src/clj/cljs/closure.clj
+++ src/clj/cljs/closure.clj
@@ -473,8 +473,8 @@

 (defn source-for-namespace
   [ns compiler-env]
-  (let [ns-str (str (comp/munge ns))
-        path (string/replace ns-str \. File/separatorChar)
+  (let [ns-str  (str (comp/munge ns))
+        path    (string/replace ns-str \. \/)
         relpath (str path ".cljs")]
     (if-let [cljs-res (io/resource relpath)]
       {:relative-path relpath :uri cljs-res}


added documentation for the static data sets.

--- src/clj/forma/static.clj
+++ src/clj/forma/static.clj
@@ -17,29 +17,51 @@

 (def chunk-size 24000)

-;; TODO: Comments.
 (def static-datasets
-  {:gadm {:ncols 36001
-          :nrows 13962
-          :xulcorner -180.000001
-          :yulcorner 83.635972
-          :cellsize 0.01
-          :nodata -9999}
-   :ecoid {:ncols 36000
-           :nrows 17352
-           :xulcorner -179.99996728576
-           :yulcorner 83.628027
-           :cellsize 0.01
-           :nodata -9999}
+  ^{:doc "These are the static datasets, described briefly below.  The inner
+   keys (e.g., :ncols) are a quick transformation on the ASCII header, where
+   the coordinates for the upper left corner are presented, rather than the
+   lower left corner.  The only value that changes, then, is the y-coord.
+
+   gadm   :: administrative boundaries, found [here](http://goo.gl/2N5CT),
+   and converted to a raster with the cell value given by ID_2, an integer
+   value corresponding to the most detailed administrative unit.
+
+   ecoid  :: ecoregions according to the World Wildlife Fund. The technical
+   paper can be found [here](http://goo.gl/yvssq). The polygons are converted
+   to a raster for sampling - much like the admin boundaries - where each cell
+   is assigned the value of the ecoregion id, the most detailed eco unit.
+
+   hansen :: forest cover loss hotspots data for training at 500m resolution,
+   found [here](http://goo.gl/HqvCW). Note that this has been projected into
+   WGS84 from Sinusoidal (463.3127m res).  The time period is 2000-2005.
+
+   vcf    :: vegetation continuous field index, derived from MODIS products for
+   the year 2000, found [here](http://goo.gl/KW8y1), and used to define the
+   extent of the sample area, given by the Forest Cover Loss Hotspots training
+   data set."}
+
+  {:gadm   {:ncols 36001
+            :nrows 13962
+            :xulcorner -180.000001
+            :yulcorner 83.635972
+            :cellsize 0.01
+            :nodata -9999}
+   :ecoid  {:ncols 36000
+            :nrows 17352
+            :xulcorner -179.99996728576
+            :yulcorner 83.628027
+            :cellsize 0.01
+            :nodata -9999}
    :hansen {:ncols 86223
             :nrows 19240
             :xulcorner -179.99998844516
             :yulcorner 40.164567
             :cellsize 0.0041752289295106
             :nodata -9999}
-   :vcf {:ncols 86223
-         :nrows 19240
-         :xulcorner -179.99998844516
-         :yulcorner 40.164567
-         :cellsize 0.0041752289295106
-         :nodata -9999}})
+   :vcf    {:ncols 86223
+            :nrows 19240
+            :xulcorner -179.99998844516
+            :yulcorner 40.164567
+            :cellsize 0.0041752289295106
+            :nodata -9999}})


starting work on the actual windowed grabs.

--- src/clj/forma/trends.clj
+++ src/clj/forma/trends.clj
@@ -168,3 +168,45 @@
     (<- [?tile-h ?tile-v ?window-col ?window-row ?window]
         (line-source ?tile-h ?tile-v ?line ?window-col ?line-vec)
         (line-agger ?line ?line-vec :> ?window-row ?window))))
+
+;; ### Walk the Windows
+;;
+;; Now that we have a way to generate windows, we need some functions
+;;to actually walk around.
+
+;; TODO: -- documentation on why we do this. Nearest neighbor analysis links.
+(defn walk-matrix
+  "Walks along the rows and columns of a matrix at the given window
+  size, returning all (window x window) snapshots."
+  [m window]
+  (mapcat (comp
+           (partial apply map vector)
+           (partial map (partial partition window 1)))
+          (partition window 1 m)))
+
+;; TODO: update walk-matrix above to return useful shit.
+(defmapcatop [walk-mat [window]]
+  {:doc "In progress! Not sure yet how walk-mat's return values work out, here."}
+  [m]
+  (walk-matrix m window))
+
+(defn get-windows
+  "IN PROGRESS. Currently, this job fails due to incorrect comparator
+  settings for the tuples."
+  [source edge splits]
+  (let [window-source (line-aggregator source edge splits)]
+    (?<- (stdout)
+         [?tile-h ?tile-v ?window-col ?window-row ?row1 ?row2 ?row3]
+         (window-source ?tile-h ?tile-v ?window-col ?window-row ?window)
+         (walk-mat [3] ?window :> ?row1 ?row2 ?row3))))
+
+;; I think that I might be able to tag pixels as "edges", based on a
+;; combination of pixel value and length of groups. If I can get all
+;; of the edge pixels aggregated together... that would be a big win!
+;;
+;; Can we extend this to deal with the whole world, by calculating the
+;; global pixel sample and line? One issue would be that edges
+;; sometimes wouldn't be met be anything on the other side.
+;;
+;; ACTUALLY -- this is a problem now, and if we solve it, we solve the
+;; whole mess.


Add missing csv library require

Add missing csv library require

--- src/clj_gatling/core.clj
+++ src/clj_gatling/core.clj
@@ -1,6 +1,7 @@
 (ns clj-gatling.core
   (:import (org.joda.time LocalDateTime))
-  (:require [clj-gatling.chart :as chart]
+  (:require [clojure-csv.core :as csv]
+            [clj-gatling.chart :as chart]
             [clj-gatling.report :as report]
             [clj-gatling.simulation :as simulation]))


This is still simplistic, fending off a restructure of this boxing stuff.

--- src/cljs/go/compiler.clj
+++ src/cljs/go/compiler.clj
@@ -160,7 +160,7 @@
   (not (or (set? from)
            (and (= 'string from) (= 'array to)) ;; strings are indexable
            ('#{clj-nil clj clj-or-nil} to)
-           ((hash-set to 'clj-nil) from))))
+           (contains? (hash-set to 'any 'clj-nil) from))))

 (declare emit-str)

@@ -795,7 +795,7 @@
        (emits f (when coerce? ".(CljsCoreIFn)") ".X_invoke_Arity" arity "(" (comma-sep args) ")"))

       ;; this is somewhat optimistic, the analyzer tags the expression based on the body of the fn, not the actual return type.
-      (when (and (not native?) (not= (:tag expr) (-> f :info :ret-tag)))
+      (when-not (= (:tag expr) (-> f :info :ret-tag))
         (emits (go-unbox-no-emit (:tag expr) nil))))))

 (defn normalize-goog-ctor [ctor]


cleanup

cleanup

--- src/cljs/ufo/client.cljs
+++ src/cljs/ufo/client.cljs
@@ -29,10 +29,6 @@
 (defui ColsSalaries
   static om/Ident (ident [this {:keys [id]}] [:rows/by-id id])
   static om/IQuery (query [this] '[:id :salary :abrev]))
-
-(defui TTable
-  static om/Ident (ident [this {:keys [tid]}] [:tables/by-tid tid])
-  static om/IQuery (query [this] '[:tid :sqlfn :tname]))

 (defui Th
   "1. {:keyfn ...} can only use keys specified by (om/props this)
@@ -137,6 +133,8 @@
                trows)]))))

 (defui Table
+  static om/Ident (ident [this {:keys [tid]}] [:tables/by-tid tid])
+  static om/IQuery (query [this] '[:tid :sqlfn :tname])
   Object
   (render
    [this]
@@ -157,7 +155,7 @@

 (defui RootView
   ;; the query-tree is static
-  static om/IQuery (query [this] `[{:list/tables ~(om/get-query TTable)}])
+  static om/IQuery (query [this] `[{:list/tables ~(om/get-query Table)}])
   Object
   #_(componentWillReceiveProps
      [this next-props]            (println "RootView" "WillReceiveProps"))