Speed up seq by only tracking node indexes

--- src/main/cljs/lean_map/core.cljs
+++ src/main/cljs/lean_map/core.cljs
@@ -92,10 +92,9 @@

   (inode-seq [inode]
     (let [nodes (make-array 7)
-          cursors-lengths (make-array 14)]
+          cursors-lengths #js [0 0 0 0 0 0 0]]
       (aset nodes 0 inode)
-      (aset cursors-lengths 0 0)
-      (aset cursors-lengths 1 (.node-arity inode))
+      (aset cursors-lengths 0 (.node-arity inode))
       (if (zero? datamap)
         (create-inode-seq arr 0 nodes cursors-lengths 0 (.data-arity inode))
         (NodeSeq. nil arr 0 nodes cursors-lengths 0 (.data-arity inode) nil))))
@@ -144,7 +143,7 @@
     (bit-count datamap))

   (get-node [_ i]
-    (aget arr (- (alength arr) 1 i)))
+    (aget arr (- (alength arr) i)))

   (get-array [_]
     arr)
@@ -535,21 +534,19 @@
           cursors-lengths (aclone cursors-lengths)]
       (loop [lvl lvl]
         (when (>= lvl 0)
-          (let [node-idx (aget cursors-lengths (* lvl 2))
-                node-len (aget cursors-lengths (inc (* lvl 2)))]
-            (if (< node-idx node-len)
+          (let [node-idx (aget cursors-lengths lvl)]
+            (if (zero? node-idx)
+              (recur (dec lvl))
               (let [node (.get-node (aget nodes lvl) node-idx)
                     has-nodes ^boolean (.has-nodes? node)
                     new-lvl (if has-nodes (inc lvl) lvl)]
-                (aset cursors-lengths (* lvl 2) (inc node-idx))
+                (aset cursors-lengths lvl (dec node-idx))
                 (when has-nodes
                   (aset nodes new-lvl node)
-                  (aset cursors-lengths (* new-lvl 2) 0)
-                  (aset cursors-lengths (inc (* new-lvl 2)) (.node-arity node)))
+                  (aset cursors-lengths new-lvl (.node-arity node)))
                 (if ^boolean (.has-data? node)
                   (NodeSeq. nil (.get-array node) new-lvl nodes cursors-lengths 0 (.data-arity node) nil)
-                  (recur (inc lvl))))
-              (recur (dec lvl)))))))))
+                  (recur (inc lvl)))))))))))

 (extend-protocol IPrintWithWriter
   NodeSeq


Equality Optimization

Equality Optimization

- Check equality on BitmapIndexNode and HashCollisionNode instead of on the PersistentHashMap sequence

--- src/main/cljs/lean_map/core.cljs
+++ src/main/cljs/lean_map/core.cljs
@@ -227,7 +227,19 @@
               (.copy-and-set-node inode wedit bit sub-node-new))
             inode))
         :else
-        inode))))
+        inode)))
+
+  IEquiv
+  (-equiv [inode other]
+    (if (identical? inode other)
+      true
+      (when (instance? BitmapIndexedNode other)
+        (when (and (== datamap (.-datamap other)) (== nodemap (.-nodemap other)))
+          (let [len (alength arr)]
+            (loop [i 0 eq true]
+              (if (and eq (< i len))
+                (recur (inc i) (= (aget arr i) (aget (.-arr other)i)))
+                eq))))))))

 (set! (.-EMPTY BitmapIndexedNode) (BitmapIndexedNode. nil 0 0 (make-array 0)))

@@ -302,7 +314,19 @@
     (inode-kv-reduce arr cnt 0 f init))

   (single-kv? [_]
-    false))
+    false)
+
+  IEquiv
+  (-equiv [inode other]
+    (if (identical? inode other)
+      true
+      (when (instance? HashCollisionNode other)
+        (when (== cnt (.-cnt other))
+          (let [len (alength arr)]
+            (loop [i 0 eq true]
+              (if (and eq (< i len))
+                (recur (inc i) (= (aget arr i) (aget (.-arr other)i)))
+                eq))))))))

 (deftype PersistentHashMap [meta cnt root ^:mutable __hash]
   Object
@@ -353,7 +377,12 @@
   (-empty [coll] (-with-meta (.-EMPTY PersistentHashMap) meta))

   IEquiv
-  (-equiv [coll other] (equiv-map coll other))
+  (-equiv [coll other]
+    (if (identical? coll other)
+      true
+      (if (instance? PersistentHashMap other)
+       (-equiv root (.-root other))
+       (equiv-map coll other))))

   IHash
   (-hash [coll] (caching-hash coll hash-unordered-coll __hash))


[PDOK-1592] lock on UUIDGenerator

[PDOK-1592] lock on UUIDGenerator

--- src/main/clojure/pdok/random.clj
+++ src/main/clojure/pdok/random.clj
@@ -3,4 +3,4 @@

 (def ^:private UUIDGenerator (Generators/timeBasedGenerator))

-(defn ordered-UUID [] (.generate UUIDGenerator))
+(defn ordered-UUID [] (locking UUIDGenerator (.generate UUIDGenerator)))


Bugfix: merge-vecs doesn't perserve form order

Fixes #18

--- src/oxcart/passes.clj
+++ src/oxcart/passes.clj
@@ -68,9 +68,9 @@
   [forms]
   (reduce
    (fn [acc e]
-     (if (vector? e)
-       (concat acc e)
-       (conj acc e)))
+     (concat acc
+             (if (vector? e)
+               e [e])))
    nil forms))


[l.d.utils] Fix :gen-path bug

[l.d.utils] Fix :gen-path bug

--- src/leiningen/droid/utils.clj
+++ src/leiningen/droid/utils.clj
@@ -152,7 +152,7 @@
           support-repo (file sdk-path "extras" "android" "m2repository")
           ps-repo (file sdk-path "extras" "google" "m2repository")]
       (-> project
-          (update-in [:java-source-paths] conj (:gen-path android-params))
+          (update-in [:java-source-paths] conj (str (:gen-path android-params)))
           (update-in [:repositories] concat
                      [["android-support" {:url (str "file://" support-repo)}]
                       ["android-play-services" {:url (str "file://" ps-repo)}]])


(chore) remove unnecessary imports

(chore) remove unnecessary imports

--- src/papaline/core.clj
+++ src/papaline/core.clj
@@ -8,8 +8,7 @@
            [java.util.concurrent ExecutorService TimeUnit TimeoutException Callable
                                  ThreadPoolExecutor LinkedBlockingQueue RejectedExecutionHandler
                                  ThreadPoolExecutor$DiscardOldestPolicy ThreadFactory Future CompletableFuture CompletionException]
-           (java.util.function BiFunction)
-           (java.util Objects List)))
+           (java.util.function BiFunction)))

 (defrecord Stage [buffer-factory stage-fn]
   clojure.lang.IFn
@@ -291,12 +290,12 @@

   (run-pipeline-wait [this & args]
                      (let [future (this {:args args})]
-                       (:args (.get future))))
+                       (:args (.get ^Future future))))

   (run-pipeline-timeout [this timeout-interval timeout-val & args]
                         (let [future (this {:args args})]
                           (try
-                            (:args (.get future timeout-interval TimeUnit/MILLISECONDS))
+                            (:args (.get ^Future future timeout-interval TimeUnit/MILLISECONDS))
                             (catch TimeoutException e
                               timeout-val))))
   (stop! [this]))


better proportions for blogpost title

better proportions for blogpost title

--- src/pc/views/blog.clj
+++ src/pc/views/blog.clj
@@ -82,7 +82,7 @@
      (blog-head)
      [:div.blogpost-title
       [:article
-       [:h1 (:title post)]]]
+       [:h2 (:title post)]]]
      (:body post)]))

 (defn render-page [slug]


Create an add-page function for adding page-info into the site map.

--- src/pubhouse/core.clj
+++ src/pubhouse/core.clj
@@ -49,16 +49,15 @@
   [url]
   (str "/" (-> url (clojure.string/replace "index.html" "") (strip-extensions))))

+(defn add-page
+  [site inf]
+  (assoc-in site (site-nav (:url inf)) (update-in inf [:url] canonical-url)))
+
 (defn mapping->site
   "Convert a sequence of [path url] pairs to a map structure representing
   the directory layout of the site."
   [mapping]
-  (reduce (fn [site [path inf]]
-            (assoc-in site
-                      (site-nav (:url inf))
-                      (update-in inf [:url] canonical-url)))
-          {}
-          mapping))
+  (reduce #(add-page %1 (last %2)) {} mapping))

 (defn html-file
   "Given the path to the build directory and url relative to the site root,


fix error formation

fix error formation

--- cloc-webapp/src-cljs/dash/dash.cljs
+++ cloc-webapp/src-cljs/dash/dash.cljs
@@ -1,6 +1,8 @@
 (ns cloc-webapp.dash
   (:require-macros [cljs.core.async.macros :refer [go alt!]])
   (:require [goog.json :as json]
+            [goog.string :as str]
+            [goog.string.format]
             [om.core :as om :include-macros true]
             [om.dom :as dom :include-macros true]
             [cljs-http.client :as http])
@@ -27,7 +29,7 @@
         (map-indexed repo-button state)))))

 ;; {:auth - :repo -}
-(defn repo-config-panel [state onwer]
+(defn repo-config-panel [state owner]
   (reify
     om/IInitState
     (init-state [_]
@@ -35,23 +37,24 @@
                                     (:registered current-repo)
                                     [:registered]
                                     [:unregistered])})]
-        (merge {:mutable mutable
-                :state-cursor (:state (om/root-cursor mutable))} state)))
+        (merge state {:mutable mutable
+                      :state-cursor (:state (om/root-cursor mutable))})))

     om/IRenderState
     (render-state [this state]
-      (let [cursor (:state-cursor state)
-            current-state (nth (om/observe owner (:state-cursor state)) 0)
+      (let [cursor (om/ref-cursor (:state-cursor state))
+            current-state (nth (om/observe owner cursor) 0)
             auth-token (:auth state)
-            register-repo-url (format "/api/user/%s/register" (get-in state [:repo :name]))
+            register-repo-url (str/format "/api/user/%s/register" (get-in state [:repo "name"]))
             register-fn (fn []
-                          (when (= current-state :unregistered)
+                          (when (= current-state :unregistered)
+                            (om/update! cursor [0] :registering)
+
                             (go (let [resp (<! (http/post register-repo-url {:oauth-token auth-token
                                                                              :json-params {}}))]
                                    (if (= 200 (:status resp))
-                                     ;; refresh repo state
-                                     ;; TODO
-                                     (om/update! cursor [0] :registered))))))]
+                                     (prn resp)
+                                     (om/update! cursor [0] :unregistered))))))]

         (case current-state
           :registered (dom/h2 nil (get (:repo state) "full_name"))
@@ -74,7 +77,7 @@
       (let [current-index (nth (om/observe owner (current-index-cur)) 0)
             repos (:repos state)]
         (if (< current-index (count repos))
-          (om/build repo-config-panel {:repo (nth repos current-index)
+          (om/build repo-config-panel {:repo (nth repos current-index)
                                        :auth (:auth state)})
           (dom/h2 nil "Add your repos"))))))

@@ -86,11 +89,12 @@
        :auth (.get (Cookies. js/document) "session_id")})

     om/IRenderState
-    (render-state [this state]
+    (render-state [this state]
       (let [repos (vec (get-in state [:me "repos"]))]
+        (prn repos)
         (dom/div nil
           (om/build repo-list-view repos)
-          (om/build repo-detail-view {:repos (:me state)
+          (om/build repo-detail-view {:repos repos
                                       :auth (:auth state)}))))))

 (om/root widget app-state {:target (.getElementById js/document "content")})


Stability improvements

Stability improvements

Made all layers deal in vectors. Added check-frame to throw an exception if a layer makes an invalid change to the frame.

--- src/sparkle/layer.clj
+++ src/sparkle/layer.clj
@@ -4,47 +4,30 @@

 (defn static-color [color]
   (fn [env frame]
-    (map (constantly color) frame)))
+    (mapv (constantly color) frame)))

 (defn scale-brightness [factor]
   (fn [env frame]
-    (map (fn [pixel]
+    (mapv (fn [pixel]
            (fmap #(* factor %) pixel))
-         frame)))
+          frame)))

 (defn brightness-gradient [start-factor end-factor]
   (fn [env frame]
     (let [step (/ (- end-factor start-factor)
                   (dec (count frame)))
           factors (iterate #(+ % step) start-factor)]
-      (map (fn [pixel factor]
+      (mapv (fn [pixel factor]
              (fmap #(* factor %) pixel))
-           frame factors))))
+            frame factors))))

 (defn pulse-brightness [{:keys [time] :as env} frame]
   (let [scaled-time (* 2 Math/PI (/ time 1000))
         brightness-factor (+ 1/2
                              (/ (Math/sin scaled-time) 2))]
-    (map (fn [pixel]
+    (mapv (fn [pixel]
            (fmap #(* % brightness-factor) pixel))
-         frame)))
-
-(defn swimming-static-color
-  ([color length interval]
-   (swimming-static-color color length interval 0))
-
-  ([color length interval initial-offset]
-   (fn [{:keys [time] :as env} frame]
-     (let [frame (vec frame)
-           size (count frame)
-           last (dec size)
-           offset (+ initial-offset
-                     (int (Math/floor (* (inc size)
-                                         (/ (mod time interval) interval)))))
-           start (constrain 0 last (- offset length))]
-       (vec (concat (subvec frame 0 start)
-                    (take (- offset start) (repeat color))
-                    (subvec frame (min last offset))))))))
+          frame)))

 (defn stepping-static-color [color interval]
   (fn
@@ -58,6 +41,14 @@
           :state {:offset new-offset :last-time time}})
        {:frame (assoc frame offset color)
         :state  state}))))
+
+(defn check-frame
+  "Verify that a layer didn't make an invalid change to the frame."
+  [old-frame new-frame layer]
+  (when (not= (count old-frame) (count new-frame))
+    (throw (Exception. (str "Error after " layer
+                            ". New frame is a different size (" (count new-frame)
+                            ") than the previous frame (" (count old-frame) ").")))))

 ;; Layers are either functions or {:layer-fn :state} maps. Layers
 ;; which wish to use state must have an arity-2 version that can be
@@ -73,12 +64,16 @@
  (if (map? layer)
    (let [{:keys [layer-fn state]} layer
          {new-frame :frame next-state :state} (layer-fn env state frame)]
+     (check-frame frame new-frame layer)
      [new-frame (assoc layer :state next-state)])
    (let [layer-result (layer env frame)]
      (if (map? layer-result)
        (let [{new-frame :frame next-state :state} layer-result]
+         (check-frame frame new-frame layer)
          [new-frame {:layer-fn layer :state next-state}])
-       [layer-result layer]))))
+       (do
+         (check-frame frame layer-result layer)
+         [layer-result layer])))))

 (defn apply-layers
   "Applies each layer in layers to the frame with env. Returns the


moving some doc strings around

moving some doc strings around

--- src/name/choi/joshua/fnparse.clj
+++ src/name/choi/joshua/fnparse.clj
@@ -1,11 +1,13 @@
 (ns name.choi.joshua.fnparse
-  (:use clojure.contrib.monads clojure.contrib.except clojure.contrib.error-kit))
+  [:use clojure.contrib.monads clojure.contrib.except
+        clojure.contrib.error-kit])

 ; A rule is a delay object that contains a function that:
 ; - Takes a collection of tokens.
-; - If the token sequence is valid, it returns a (0) vector containing the (1) consumed
-;   symbols' products and (2) a state data object, usually a map. The state contains the (3)
-;   sequence of remaining tokens, usually with the key *remainder-accessor*.
+; - If the token sequence is valid, it returns a (0) vector containing the (1)
+;   consumed symbols' products and (2) a state data object, usually a map. The
+;   state contains the (3) sequence of remaining tokens, usually with the key
+;   *remainder-accessor*.
 ; - If the given token sequence is invalid, then the rule Fails, meaning that it either
 ;   simply returns nil.

@@ -22,23 +24,25 @@
 (def parser-m (state-t maybe-m))

 (def
-  #^{:doc "The function, symbol, or other callable object that is used to access the
-     remainder inside a state object. In other words, (*remainder-accessor* a-state) has to
-     return the remainder inside a-state. By default, the remainder-accessor is :remainder
-     (meaning that FnParse's default states are maps containing :remainder). But the
-     accessor is rebindable, so that you can use different kinds of state objects in your
-     parsing application. Myself, I usually put a struct-map accessor for :remainder in
-     here."}
+  #^{:doc "The function, symbol, or other callable object that is used to access
+     the remainder inside a state object. In other words,
+     (*remainder-accessor* a-state) has to return the remainder inside a-state.
+     By default, the remainder-accessor is :remainder (meaning that FnParse's
+     default states are maps containing :remainder). But the accessor is
+     rebindable, so that you can use different kinds of state objects in your
+     parsing application. Myself, I usually put a struct-map accessor for
+     :remainder in here."}
   *remainder-accessor*
   :remainder)
 (def
-  #^{:doc "The function, symbol, or other callable object that is used to change the
-     remainder inside a state object. In other words,
-     (*remainder-setter* a-state new-remainder) has to return the remainder inside a-state.
-     By default, the remainder-accessor is #(assoc %1 :remainder %2), which means that
-     FnParse's default states are maps containing :remainder. But the accessor is rebindable,
-     so that you can use different kinds of state objects in your parsing application.
-     Myself, I usually leave this variable alone."}
+  #^{:doc "The function, symbol, or other callable object that is used to change
+     the remainder inside a state object. In other words,
+     (*remainder-setter* a-state new-remainder) has to return the remainder
+     inside a-state. By default, the remainder-accessor is
+     #(assoc %1 :remainder %2), which means that FnParse's default states are
+     maps containing :remainder. But the accessor is rebindable, so that you can
+     use different kinds of state objects in your parsing application. Myself, I
+     usually leave this variable alone."}
   *remainder-setter*
   #(assoc %1 :remainder %2))

@@ -47,7 +51,8 @@
   `(domonad parser-m ~steps ~@product-expr))

 (def
-  #^{:doc "A rule that consumes no tokens. Its product is the entire current state.
+  #^{:doc "A rule that consumes no tokens. Its product is the entire current
+     state.
      [Equivalent to the result of fetch-state from clojure.contrib.monads.]"}
   get-state (fetch-state))
 (defn get-info


Modified the portal top page URL.

Modified the portal top page URL.

--- src/tames/handler.clj
+++ src/tames/handler.clj
@@ -52,8 +52,7 @@
     ;(println "[forgery]  :"
     (-> (response/redirect next_url)
         ;(assoc-in [:session :identity] (keyword username))
-        (assoc-in [:session :identity] username)
-        )))
+        (assoc-in [:session :identity] username))))

 (defn logout
   [req]
@@ -88,10 +87,11 @@
   (GET "/logout" req
     (logout req))

-  ;; Portal Top Page
-  (GET "/tames.html" []
-    (println "[GET] /tames.html")
-    (response/file-response "core/tames.html"))
+  ;; Portal Top
+  (GET "/tames" []
+    (println "[GET] /tames")
+    (-> (response/file-response "core/tames.html")
+        (response/header "Content-Type" (content-types "html"))))

   ;; REST API for CRUD
   (GET "/api/:class-id" [class-id]


Extract text-methods and spec them

Extract text-methods and spec them

--- src/discuss/texts/references.cljs
+++ src/discuss/texts/references.cljs
@@ -5,23 +5,46 @@
             [discuss.translations :refer [translate] :rename {translate t}]
             [discuss.texts.lib :as textlib]))

+(defn- undercut-text
+  "Create string which represents an undercut."
+  [nickname premise attacks]
+  (format "Laut %s kann man die Aussage, dass \"%s\", nicht damit begründen, dass \"%s\", weil %s."
+          nickname
+          (textlib/highlight-conclusion (:conclusion attacks))
+          (textlib/highlight-premise (:premise attacks))
+          (textlib/highlight-undercut premise)))
+
+(defn- argument-text
+  "Given a conclusion and premise, construct a string representing an argument."
+  [nickname conclusion premise]
+  (format "%s %s %s, %s %s."
+          nickname
+          (t :common :argue/that)
+          (textlib/highlight-conclusion conclusion)
+          (t :common :because)
+          (textlib/highlight-premise premise)))
+
 (defn reference-usage-intro
   "Construct reference usage intro. If attacks are provided, the target attack is
   an argument itself, which makes the whole attack an undercut."
   [nickname conclusion premise attacks]
   (if (seq attacks)
-    (format "Laut %s kann man die Aussage, dass \"%s\", nicht damit begründen, dass \"%s\", weil %s."
-            nickname
-            (textlib/highlight-conclusion (:conclusion attacks))
-            (textlib/highlight-premise (:premise attacks))
-            (textlib/highlight-undercut premise))
-    (format "%s %s %s, %s %s."
-            nickname
-            (t :common :argue/that)
-            (textlib/highlight-conclusion conclusion)
-            (t :common :because)
-            (textlib/highlight-premise premise))))
+    (undercut-text nickname premise attacks)
+    (argument-text nickname conclusion premise)))
+
+(s/def ::nickname string?)
+(s/def ::conclusion string?)
+(s/def ::premise string?)
+(s/def ::attacks (s/or :empty nil? :undercut map?))

 (s/fdef reference-usage-intro
-  :args (s/cat :nickname string? :conclusion string? :premise string? :attacks (s/or :empty nil? :undercut map?))
+  :args (s/cat :nickname ::nickname :conclusion ::conclusion :premise ::premise :attacks ::attacks)
   :ret string?)
+
+(s/fdef argument-text
+  :args (s/cat :nickname ::nickname :conclusion ::conclusion :premise ::premise)
+  :ret string?)
+
+(s/fdef undercut-text
+  :args (s/cat :nickname ::nickname :conclusion ::conclusion :premise ::premise :attacks ::attacks)
+  :ret string?)


Add gen-class

Add gen-class

--- src/gcp_pubsub_adapter/system.clj
+++ src/gcp_pubsub_adapter/system.clj
@@ -5,7 +5,8 @@
             [gcp-pubsub-adapter.infra.repository.lemming-repository :refer [lemming-repository-component]]
             [gcp-pubsub-adapter.domain.usecase.lemming-usecase :refer [lemming-usecase-component]]
             [gcp-pubsub-adapter.app.handler :refer [handler-component]]
-            [gcp-pubsub-adapter.app.endpoint :refer [end-point-component]]))
+            [gcp-pubsub-adapter.app.endpoint :refer [end-point-component]])
+  (:gen-class))

 (defn gcp-pubsub-adapter-system
   [{:keys [gcp-pubsub-adapter-project-id


Add more info

Add more info

--- src/obb_demo/views/player.cljs
+++ src/obb_demo/views/player.cljs
@@ -203,4 +203,8 @@
         [:p "This is a demo that showcases the gameplay of Orion's Belt against a simple AI."]
         [:p "It's your turn to play. Perform your actions and then click Play turn."]
         [:p "Pro tip: on the top menu you can see CPU vs CPU and also the
-            traits of all units."]]]]))
+            traits of all units."]
+        [:p "Would you like to know more?"
+         [:ul
+          [:li [:a {:href "https://twitter.com/orionsbelt"} "Twitter"]
+          [:li [:a {:href "https://github.com/orionsbelt-battlegrounds/obb-rules"} "Github"]]]]]]]]))


Updated comment.

Updated comment.

--- src/oc/storage/api/entries.clj
+++ src/oc/storage/api/entries.clj
@@ -319,7 +319,7 @@
   :processable? (by-method {
     :options true
     :post (fn [ctx] (let [entry-props (:data ctx)]
-                      (or (nil? entry-props) ; no share is fine
+                      (or (nil? entry-props) ; no updates during publish is fine
                           (valid-entry-update? conn entry-uuid entry-props))))})
   :new? false
   :respond-with-entity? true


remove unrelated namespace comments

remove unrelated namespace comments

--- src/onyx_java/utils/object.clj
+++ src/onyx_java/utils/object.clj
@@ -1,10 +1,5 @@
 (ns onyx-java.utils.object
     (:gen-class))
-
-;; These vars should be defined where they are being used.
-    ;; (def class-pattern "org.onyxplatform.api.java.{class}")
-    ;; (def replace-classname-pattern "{class}")
-    ;; (def object-map {})

 ;; Class factory creation


move handler into separate named fn

move handler into separate named fn

--- src/open_company/api/entry.clj
+++ src/open_company/api/entry.clj
@@ -21,6 +21,12 @@

 ;; ----- Resources - see: http://clojure-liberator.github.io/liberator/assets/img/decision-graph.svg

+(defn handle-get [{:keys [user] :as _ctx}]
+  (let [companies (when user (company-res/get-companies-by-index "org-id" (:org-id user)))]
+    (json/generate-string
+      {:links (links user companies)}
+      {:pretty true})))
+
 (defresource entry-point []
   common/anonymous-resource

@@ -35,11 +41,7 @@
   :handle-not-acceptable (fn [_] (common/only-accept 406 "application/json"))
   :handle-unsupported-media-type (fn [_] (common/only-accept 415 "application/json"))

-  :handle-ok (fn [{:keys [user] :as _ctx}]
-               (let [companies (when user (company-res/get-companies-by-index "org-id" (:org-id user)))]
-                 (json/generate-string
-                  {:links (links user companies)}
-                  {:pretty true})))
+  :handle-ok handle-get

   :handle-options (common/options-response [:options :get]))


Fix error in path lookup

Fix error in path lookup

--- src/org/spootnik/cyanite/http.clj
+++ src/org/spootnik/cyanite/http.clj
@@ -58,6 +58,15 @@
            :body    (json/generate-string
                       (or body {:error (.getMessage e)}))})))))

+(defn lookup-path
+  [index tenant path]
+  (path/lookup index tenant path))
+
+(defn lookup-paths
+  [index tenant paths]
+  (let [paths (if (sequential? paths) paths [paths])]
+    (flatten (pmap (partial lookup-path index tenant) paths))))
+
 (defn metrics-handler [response-channel
                        {{:keys [index store rollups]} :local-params
                         {:keys [from to path agg tenant]} :params :as request}]
@@ -73,7 +82,7 @@
                    (if-let [{:keys [rollup period]} (find-best-rollup (str from) rollups)]
                      (let [to    (if to (Long/parseLong (str to)) (now))
                            from  (Long/parseLong (str from))
-                           paths (path/lookup index (or tenant "NONE") path)]
+                           paths (lookup-paths index (or tenant "NONE") path)]
                        (store/fetch store (or agg "mean") paths (or tenant "NONE") rollup period from to))
                      {:step nil :from nil :to nil :series {}})
                    )})


start js-core slide

start js-core slide

--- src/solar_system_of_js/core.cljs
+++ src/solar_system_of_js/core.cljs
@@ -24,7 +24,13 @@
    :js-face {:x 900
              :y 0
              :r 200
-             :alpha 1}})
+             :alpha 1
+             :angle 0}
+   :js-core {:x 0
+             :y 0
+             :r 200
+             :alpha 0}
+   })

 ;; Current state of the application.
 (defonce state
@@ -81,11 +87,11 @@
 (defn stroke-text! [text x y] (.strokeText ctx text x y))
 (defn text-align! [x] (aset ctx "textAlign" x))
 (defn text-baseline! [x] (aset ctx "textBaseline" x))
+(defn line-width! [x] (aset ctx "lineWidth" x))

 ;;--------------------------------------------------------------------------------
 ;; Slide Drawings
 ;;--------------------------------------------------------------------------------
-

 (defn draw-title!
   [{:keys [x y alpha]}]
@@ -99,12 +105,13 @@
   (restore!)
   )

-(defn draw-js!
-  [{:keys [x y r alpha]}]
-
+(defn draw-js-face!
+  [{:keys [x y r angle alpha]}]
   (save!)
   (global-alpha! alpha)
-  (circle! x y r)
+  (translate! x y)
+  (rotate! angle)
+  (circle! 0 0 r)
   (fill-style! "#f7df1e")
   (fill!)

@@ -113,9 +120,25 @@
   (text-baseline! "middle")
   (fill-style! "#222")
   (let [off 60]
-    (fill-text! "JS" (+ x off) (+ y off)))
+    (fill-text! "JS" off off))

   (restore!))
+
+(defn draw-js-core!
+  [{:keys [x y r alpha]}]
+  (save!)
+  (global-alpha! alpha)
+  (stroke-style! "#222")
+  (doseq [[i label] (reverse (map-indexed vector ["ES3" "ES5" "ES6" "ES7" "ES8"]))]
+    (let [cr (* (inc i) (/ r 5))]
+      (circle! x y cr)
+      (line-width! 10)
+      (stroke!)
+      (fill-style! "#f7df1e")
+      (fill!)))
+  (restore!)
+  )
+

 ;;--------------------------------------------------------------------------------
 ;; Drawing
@@ -138,7 +161,8 @@
   (set-cam! (:cam @state))

   (draw-title! (:title @state))
-  (draw-js! (:js-face @state))
+  (draw-js-core! (:js-core @state))
+  (draw-js-face! (:js-face @state))

   (restore!))

@@ -212,7 +236,7 @@
 (defn multi-animate!
   "Helper for concurrent animations with `animate!`.
    Returns a channel that closes when all are done."
-  [arg-pairs]
+  [& arg-pairs]
   (let [anims (->> (partition 2 arg-pairs)
                    (mapv #(apply animate! %)))]
     (go
@@ -227,13 +251,29 @@
   []
   (go
     (<! (multi-animate!
-          [{:a 0 :b 1 :duration 1}
-           #(swap! state assoc-in [:js-face :alpha] %)
-           {:a 900 :b 0 :duration 1}
+          {:a 900 :b 0 :duration 1}
            #(swap! state assoc-in [:js-face :x] %)
            {:a 1 :b 0 :duration 0.4}
            #(swap! state assoc-in [:title :alpha] %)
-           ]))))
+           ))))
+
+(defn go-go-slide2!
+  []
+  (go
+    (<! (multi-animate!
+          {:a 0 :b -600 :duration 2}
+          #(swap! state assoc-in [:js-face :y] %)
+          {:a 0 :b 600 :duration 2}
+          #(swap! state assoc-in [:js-face :x] %)
+          {:a 0 :b (* 2 PI) :duration 2}
+          #(swap! state assoc-in [:js-face :angle] %)
+          {:a 1 :b 0 :duration 2}
+          #(swap! state assoc-in [:js-face :alpha] %)
+          {:a 0 :b 1 :duration 1}
+          #(swap! state assoc-in [:js-core :alpha] %)
+          {:a 1 :b 1.5 :duration 1}
+          #(swap! state assoc-in [:cam :zoom] %)
+          ))))

 ;;--------------------------------------------------------------------------------
 ;; Slide Control
@@ -243,6 +283,7 @@
   "Actions to take for each slide."
   [nil
    go-go-slide1!
+   go-go-slide2!
    ])

 (def num-slides


[fix 8831] error when unblocking first blocked contact

when unlocking first blocked contact before relogin, an error occurs
this is because the first blocked contact is added to a list and you can't
disj an element from a list
this makes sure the first blocked contact is put into a set

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

--- src/status_im/contact/block.cljs
+++ src/status_im/contact/block.cljs
@@ -59,12 +59,12 @@
                      (:contacts/contacts db)
                      public-key)
                     (assoc :last-updated now)
-                    (update :system-tags conj :contact/blocked))
+                    (update :system-tags (fnil conj #{}) :contact/blocked))
         from-one-to-one-chat? (not (get-in db [:chats (:current-chat-id db) :group-chat]))]
     (fx/merge cofx
               {:db (-> db
                        ;; add the contact to blocked contacts
-                       (update :contacts/blocked conj public-key)
+                       (update :contacts/blocked (fnil conj #{}) public-key)
                        ;; update the contact in contacts list
                        (assoc-in [:contacts/contacts public-key] contact)
                        ;; remove the 1-1 chat if it exists


Added ending note.

Added ending note.

--- src/overtunes/songs/before.clj
+++ src/overtunes/songs/before.clj
@@ -96,7 +96,7 @@
       variation-section
     )
   )
-  (play-melody (n-times melody (/ (count chords) 2)) metro (metro))
+  (play-melody (concat (n-times melody (/ (count chords) 2)) [:Eb4]) metro (metro))
   (play-progression
     chords
     metro


speaker ui merges updates

speaker ui merges updates

--- src/tango/cljs/speaker/core.cljs
+++ src/tango/cljs/speaker/core.cljs
@@ -25,6 +25,8 @@
 (defn log [m]
   (.log js/console m))

+(declare reconciler)
+(declare app-state)
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Sente Socket setup
 (let [{:keys [chsk ch-recv send-fn state]}
@@ -66,8 +68,10 @@
       (log (str "Socket Event from server: " topic))
       (log (str "Socket Payload: " payload))
       (cond
-        (= payload 'app/select-activity)
-        (log "select")
+        (= payload 'app/set-speaker-activity)
+        (do
+          (log "select")
+          (om/transact! reconciler `[:app/speaker-activites]))

         (= (:topic payload) 'app/confirm-marks)
         (log "confirm")))))
@@ -189,16 +193,23 @@
       (:query edn)
       (go
         (let [response (async/<! (http/get "/query" {:query-params
-                                                     {:query (pr-str (:query edn))}}))
-              edn-response (second (cljs.reader/read-string (:body response)))]
+                                                     {:query (pr-str (if (map? (first (:query edn)))
+                                                                       (:query edn)
+                                                                       (om/get-query MainComponent)))}}))
+              edn-response (second (cljs.reader/read-string (:body response)))
+              known-numbers (set (map :activity/number (:app/speaker-activites @app-state)))
+              new-acts (filterv #(not (contains? known-numbers (:activity/number %)))
+                                (:app/speaker-activites edn-response))]
+          (log known-numbers)
+          (log new-acts)
           ;(log edn-response)
           ;; TODO - why is the response a vec?
-          (cb edn-response))
-        ))))
+          (cb {:app/speaker-activites (into (:app/speaker-activites @app-state)
+                                            new-acts)}))))))

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Application
-(defonce app-state (atom {:app/speaker-activites [{:activity/name "Test"}]}))
+(defonce app-state (atom {:app/speaker-activites []}))

 (def reconciler
   (om/reconciler


Cut off at 30 employees

Cut off at 30 employees

--- src/nine90_extractor/core.clj
+++ src/nine90_extractor/core.clj
@@ -115,19 +115,20 @@
             (with-image [file-two (save-image page-two)]
               (loop [idx 0
                      records []]
-                (if-let [record (try
-                                  (read-record file-one file-two idx)
-                                  (catch Exception e
-                                    (println "Failed to read record" idx)
-                                    (println "Exception:" (.getMessage e))
-                                    nil))]
-                  (do (print ".")
-                      (flush)
-                      (recur (inc idx)
-                             (conj records record)))
-                  {:year year-filed
-                   :ein ein
-                   :employees records})))))))))
+                (when (< idx 30)
+                  (if-let [record (try
+                                    (read-record file-one file-two idx)
+                                    (catch Exception e
+                                      (println "Failed to read record" idx)
+                                      (println "Exception:" (.getMessage e))
+                                      nil))]
+                    (do (print ".")
+                        (flush)
+                        (recur (inc idx)
+                               (conj records record)))
+                    {:year year-filed
+                     :ein ein
+                     :employees records}))))))))))

 (defn process-pdf [pdf out-path]
   (print "Processing" (.getName pdf))


Check for malformed request on paginated board GET. Fix render-board board url calls.

--- src/oc/storage/api/boards.clj
+++ src/oc/storage/api/boards.clj
@@ -26,7 +26,9 @@
             [oc.storage.resources.board :as board-res]
             [oc.storage.resources.entry :as entry-res]
             [oc.storage.resources.reaction :as reaction-res]
-            [oc.storage.util.sort :as sort]))
+            [oc.storage.util.sort :as sort]
+            [oc.storage.util.timestamp :as ts]
+            [oc.storage.urls.board :as board-url]))

 ;; ----- Utility functions -----

@@ -343,6 +345,21 @@
     :patch (fn [ctx] (access/allow-authors conn org-slug slug (:user ctx)))
     :delete (fn [ctx] (access/allow-authors conn org-slug slug (:user ctx)))})

+  :malformed? (by-method {
+    :options false
+    :get (fn [ctx] (let [ctx-params (keywordize-keys (-> ctx :request :params))
+                         start (:start ctx-params)
+                         valid-start? (if start (ts/valid-timestamp? start) true)
+                         direction (keyword (:direction ctx-params))
+                         ;; no direction is OK, but if specified it's from the allowed enumeration of options
+                         valid-direction? (if direction (#{:before :after :around} direction) true)
+                         ;; a specified start/direction must be together or ommitted
+                         pairing-allowed? (or (and start direction)
+                                              (and (not start) (not direction)))]
+                     (not (and valid-start? valid-direction? pairing-allowed?))))
+    :patch false
+    :delete false})
+
   ;; Validations
   :processable? (by-method {
     :options true
@@ -371,11 +388,12 @@
   :delete! (fn [ctx] (delete-board conn ctx org-slug slug))

   ;; Responses
-  :handle-ok (fn [ctx] (let [board (or (:updated-board ctx) (:existing-board ctx))]
+  :handle-ok (fn [ctx] (let [org (:existing-org ctx)
+                             board (or (:updated-board ctx) (:existing-board ctx))]
                           ;; For drafts board still use the full board
                           (if (= (:slug board) (:slug board-res/default-drafts-board))
-                            (let[full-board (assemble-board conn (:existing-org ctx) board ctx)]
-                              (board-rep/render-board org-slug full-board (:access-level ctx) nil))
+                            (let[full-board (assemble-board conn org board ctx)]
+                              (board-rep/render-board org full-board ctx nil))
                             ;; Render paginated board for all the rest
                             (let[ctx-params (keywordize-keys (-> ctx :request :params))
                                  start? (if (:start ctx-params) true false) ; flag if a start was specified
@@ -383,7 +401,7 @@
                                  direction (or (#{:after :around} (keyword (:direction ctx-params))) :before) ; default is before
                                  params (merge start-params {:direction direction :start? start?})
                                  full-board (assemble-paginated-board conn params board)]
-                              (board-rep/render-board org-slug full-board (:access-level ctx) params)))))
+                              (board-rep/render-board org full-board ctx params)))))
   :handle-unprocessable-entity (fn [ctx]
     (api-common/unprocessable-entity-response (schema/check common-res/Board (:board-update ctx)))))

@@ -434,8 +452,8 @@
                               (if pre-flight?
                                 (api-common/blank-response)
                                 (api-common/location-response
-                                  (board-rep/url org-slug board-slug)
-                                  (board-rep/render-board org-slug new-board (:access-level ctx) nil)
+                                  (board-url/url org-slug board-slug)
+                                  (board-rep/render-board org-slug new-board ctx nil)
                                   mt/board-media-type))))
   :handle-unprocessable-entity (fn [ctx]
     (api-common/unprocessable-entity-response (:reason ctx))))


Adds some notes about idempontency for coordinator impl.

--- src/onyx/coordinator/impl.clj
+++ src/onyx/coordinator/impl.clj
@@ -37,6 +37,10 @@
                (some #{(:state state)} states))))
       peers))))

+
+;;; Exception needs to go away, just pass if its already there.
+;;; Make it legal to go from :idle -> :idle, not a problem since
+;;; writes are serial.
 (defmethod extensions/mark-peer-born ZooKeeper
   [sync peer-node]
   (let [peer-data (extensions/read-node sync peer-node)
@@ -46,6 +50,7 @@
       (:node (extensions/create-at sync :peer-state (:id peer-data) state))
       (throw (ex-info "Tried to add a duplicate peer" {:peer-node peer-node})))))

+;;; Make it legal to go from :dead -> :dead.
 (defmethod extensions/mark-peer-dead ZooKeeper
   [sync peer-node]
   (let [node-data (extensions/read-node sync peer-node)
@@ -54,6 +59,9 @@
         state (assoc peer-state :state :dead)]
     (:node (extensions/create-at sync :peer-state (:id peer-state) state))))

+
+;;; Ensure "tasks" always has the same order.
+;;; Ensure that node creation is idempotent.
 (defmethod extensions/plan-job ZooKeeper
   [sync job-id tasks catalog workflow]
   (let [catalog-node (:node (extensions/create-at sync :catalog job-id catalog))
@@ -66,6 +74,7 @@
     (extensions/create sync :job job-id)
     job-id))

+;;; job-log-record can't be written twice
 (defmethod extensions/mark-offered ZooKeeper
   [sync task-node peer-id nodes]
   (let [peer-state-path (extensions/resolve-node sync :peer-state peer-id)
@@ -79,6 +88,9 @@
             job-log-record {:job (:task/job-id task) :task (:task/id task)}]
         (:node (extensions/create sync :job-log job-log-record))))))

+;;; Allow :active -> :active peer state transition
+;;; Exception can stay, it will just be thrown even though the peer acked
+;;; on the last available coordinator.
 (defmethod extensions/ack ZooKeeper
   [sync ack-node]
   (let [ack-data (extensions/read-node sync ack-node)
@@ -97,6 +109,7 @@
                      :peer-node peer-node}]
         (throw (ex-info "Failed to acknowledge task" err-val))))))

+;;; Allow :revoked -> :revoked
 (defmethod extensions/revoke-offer ZooKeeper
   [sync ack-node]
   (let [ack-data (extensions/read-node sync ack-node)
@@ -113,6 +126,7 @@
        (map (partial extensions/dereference sync))
        (filter #(= (:state (:content %)) :idle))))

+;;; Allow :sealing -> :sealing
 (defmethod extensions/seal-resource? ZooKeeper
   [sync exhaust-node]
   (let [node-data (extensions/read-node sync exhaust-node)
@@ -127,6 +141,8 @@
        :seal-node (:node/seal (:nodes peer-state))
        :exhaust-node (:node/exhaust (:nodes peer-state))})))

+;;; Result should be computed the same as the first time, so its okay
+;;; to rewrite the cooldown node, and even add another listener.
 (defmethod extensions/complete ZooKeeper
   [sync complete-node cooldown-down cb]
   (let [node-data (extensions/read-node sync complete-node)
@@ -141,7 +157,7 @@
         (when-not (= (:state peer-state) :dead)
           (extensions/create-at sync :peer-state (:id node-data) state))

-        ;; Peer may have died just after completion, hence n may be 0
+        ;; Peer may have died just after completion, n may again be 0
         (if (and (<= n 1) (not complete?))
           (do (complete-task sync (:task-node peer-state))
               (extensions/write-node sync cooldown-down {:completed? true}))


remove the precursor team migration, better to do that through the admin page

--- src/pc/datomic/migrations.clj
+++ src/pc/datomic/migrations.clj
@@ -107,17 +107,6 @@
     (document-ids->document-refs db conn)
     (access-entities-ids->refs db conn)))

-(defn add-precursor-team [conn]
-  (let [subdomain "precursor"]
-    (when-not (first (d/q '{:find [?t .]
-                            :where [[?t :team/subdomain ?s]]}
-                          (d/db conn) subdomain))
-      ;; no need to worry about races, unique constraint on subdomain will explode if
-      ;; we try to insert it twice
-      @(d/transact conn [{:db/id (d/tempid :db.part/user)
-                          :team/subdomain subdomain
-                          :team/uuid (d/squuid)}]))))
-
 (def migrations
   "Array-map of migrations, the migration version is the key in the map.
    Use an array-map to make it easier to resolve merge conflicts."
@@ -130,8 +119,7 @@
    5 #'archive/migrate-fake-documents
    6 #'archive/fix-bounding-boxes
    7 #'archive/add-frontend-ids
-   8 #'longs->refs
-   9 #'add-precursor-team))
+   8 #'longs->refs))

 (defn necessary-migrations
   "Returns tuples of migrations that need to be run, e.g. [[0 #'migration-one]]"


Change semantics of invalid check

Change semantics of invalid check

--- src/kixi/datastore/web_server.clj
+++ src/kixi/datastore/web_server.clj
@@ -183,16 +183,16 @@
                                   ::ms/size-bytes (:size-bytes file)
                                   ::ms/provenance {::ms/source "upload"
                                                    ::ms/pieces-count (:pieces-count file)}}]
-                    (let [invalid (or (spec/explain-data ::ms/filemetadata metadata)
-                                      (when-not (ss/exists schemastore (::ss/name metadata))
-                                        {:error :unknown-schema
-                                         :msg (::ss/name metadata)}))]
-                      (if-not invalid
-                        (do (c/submit communications metadata)
-                            (java.net.URI. (:uri (yada/uri-for ctx :file-entry {:route-params {:id (::ms/id metadata)}}))))
+                    (let [error (or (spec/explain-data ::ms/filemetadata metadata)
+                                    (when-not (ss/exists schemastore (::ss/name metadata))
+                                      {:error :unknown-schema
+                                       :msg (::ss/name metadata)}))]
+                      (if error
                         (assoc (:response ctx)
                                :status 400
-                               :body invalid)))))}}}))
+                               :body error)
+                        (do (c/submit communications metadata)
+                            (java.net.URI. (:uri (yada/uri-for ctx :file-entry {:route-params {:id (::ms/id metadata)}}))))))))}}}))

 (defn file-entry
   [metrics filestore]


add crl.pem to user data

add crl.pem to user data

--- src/terraboot/vpc.clj
+++ src/terraboot/vpc.clj
@@ -63,6 +63,9 @@
                                 :permissions "600"}
                                {:path "/etc/openvpn/server.conf"
                                 :content (from-template "server.conf" vars)
+                                :permissions "644"}
+                               {:path "/etc/openvpn/crl.pem"
+                                :content (snippet "vpn-keys/crl.pem")
                                 :permissions "644"}
                                {:path "/etc/sysctl.d/99-ip-forwarding.conf"
                                 :content "net.ipv4.ip_forward = 1\n"


Allow input->screen and screen->input to work without a camera

--- src/play_clj/core_graphics.clj
+++ src/play_clj/core_graphics.clj
@@ -258,13 +258,17 @@
     (screen->input screen 10 10)
     (screen->input screen 10 10 0)"
   ([screen {:keys [x y z] :or {x 0 y 0 z 0} :as entity}]
-    (let [^Camera camera (u/get-obj screen :camera)
-          coords (m/vector-3 x y z)]
-      (.project camera coords)
-      (assoc entity
-             :x (. coords x)
-             :y (. coords y)
-             :z (. coords z))))
+    (try
+      (let [^Camera camera (u/get-obj screen :camera)
+            coords (m/vector-3 x y z)]
+        (.project camera coords)
+        (assoc entity
+               :x (. coords x)
+               :y (. coords y)
+               :z (. coords z)))
+      ; if there's no camera, just flip the y axis
+      (catch Exception _
+        (assoc entity :y (- (game :height) y)))))
   ([screen x y]
     (screen->input screen {:x x :y y}))
   ([screen x y z]
@@ -278,13 +282,17 @@
     (input->screen screen 10 10)
     (input->screen screen 10 10 0)"
   ([screen {:keys [x y z] :or {x 0 y 0 z 0} :as entity}]
-    (let [^Camera camera (u/get-obj screen :camera)
-          coords (m/vector-3 x y z)]
-      (.unproject camera coords)
-      (assoc entity
-             :x (. coords x)
-             :y (. coords y)
-             :z (. coords z))))
+    (try
+      (let [^Camera camera (u/get-obj screen :camera)
+            coords (m/vector-3 x y z)]
+        (.unproject camera coords)
+        (assoc entity
+               :x (. coords x)
+               :y (. coords y)
+               :z (. coords z)))
+      ; if there's no camera, just flip the y axis
+      (catch Exception _
+        (assoc entity :y (- (game :height) y)))))
   ([screen x y]
     (input->screen screen {:x x :y y}))
   ([screen x y z]


Use more efficient way to get layer

Use more efficient way to get layer

--- src/play_clj/core_graphics.clj
+++ src/play_clj/core_graphics.clj
@@ -116,11 +116,10 @@
   ([screen layer]
     (if (isa? (type layer) MapLayer)
         layer
-        (->> ^BatchTiledMapRenderer (u/get-obj screen :renderer)
-             .getMap
-             .getLayers
-             (drop-while #(not= layer (.getName ^MapLayer %)))
-             first))))
+        (-> ^BatchTiledMapRenderer (u/get-obj screen :renderer)
+            .getMap
+            .getLayers
+            (.get layer)))))

 (defmacro tiled-map-layer
   "Returns a [TiledMapTileLayer](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/maps/tiled/TiledMapTileLayer.html)


Relayout charts using Boxes for simplicity

--- src/main/clojure/dm/viz/chart.clj
+++ src/main/clojure/dm/viz/chart.clj
@@ -1,6 +1,6 @@
 (ns dm.viz.chart
   (:import
-    (javax.swing BoxLayout JFrame SwingUtilities)
+    (javax.swing Box BoxLayout JFrame SwingUtilities)
     (org.jfree.chart ChartFactory ChartPanel StandardChartTheme)))

 (ChartFactory/setChartTheme (StandardChartTheme. "JFree/Shadow" true))
@@ -8,20 +8,21 @@
 (defmulti chart class)

 (defn- panel [chart]
-  (doto (ChartPanel. chart)
-    (.setMaximumDrawWidth 1600)
-    (.setMouseWheelEnabled true)))
+  (doto (Box. BoxLayout/Y_AXIS)
+    (.add (doto (ChartPanel. chart)
+            (.setMaximumDrawWidth 1600)
+            (.setMouseWheelEnabled true)))))

 (defn- add-charts [frame datasets]
-  (let [content-pane (.getContentPane frame)]
-    (.setLayout content-pane (BoxLayout. content-pane BoxLayout/Y_AXIS))
+  (let [box (Box. BoxLayout/Y_AXIS)]
+    (.setContentPane frame box)
     (doseq [dataset datasets]
-      (.add content-pane (panel (chart dataset))))))
+      (.add box (panel (chart dataset))))))

 (defn frame [title & datasets]
   (letfn [(show-later [f] (SwingUtilities/invokeLater #(.setVisible f true)))]
     (doto (JFrame. title)
-      (add-charts datasets)
       (.setExtendedState JFrame/MAXIMIZED_BOTH)
       (.setDefaultCloseOperation JFrame/DISPOSE_ON_CLOSE)
+      (add-charts datasets)
       (show-later))))


CMR-2133 Adds additional test case

CMR-2133 Adds additional test case

--- access-control-app/int_test/cmr/access_control/int_test/access_control_group_acl_test.clj
+++ access-control-app/int_test/cmr/access_control/int_test/access_control_group_acl_test.clj
@@ -51,13 +51,17 @@

   (e/grant-system-group-permissions-to-group (u/conn-context) "sys-group-readers" :read :create)
   (e/grant-provider-group-permissions-to-group (u/conn-context) "prov1-group-readers" "prov1guid" :read :create)
+  (e/grant-provider-group-permissions-to-group (u/conn-context) "prov2-group-creator" "prov2guid" :create)

   (let [token (e/login (u/conn-context) "user1" ["sys-group-readers" "prov1-group-readers"])
         no-group-token (e/login (u/conn-context) "user2")
         system-group (u/make-group)
         system-group-concept-id (:concept-id (u/create-group token system-group))
         prov-group (u/make-group {:provider-id "PROV1"})
-        prov-group-concept-id (:concept-id (u/create-group token prov-group))]
+        prov-group-concept-id (:concept-id (u/create-group token prov-group))
+        prov2-group (u/make-group {:provider-id "PROV2"})
+        prov2-creator-token (e/login (u/conn-context) "user3" ["prov2-group-creator"])
+        prov2-group-concept-id (:concept-id (u/create-group prov2-creator-token prov2-group))]

     (testing "reading system groups"
       (testing "with permission"
@@ -75,7 +79,10 @@
                (u/get-group token prov-group-concept-id))))

       (testing "without permission"
-        (testing "without permission"
-          (is (= {:status 401
-                  :errors ["You do not have permission to read access control groups for provider [PROV1]."]}
-                 (u/get-group no-group-token prov-group-concept-id))))))))
+        (is (= {:status 401
+                :errors ["You do not have permission to read access control groups for provider [PROV1]."]}
+               (u/get-group no-group-token prov-group-concept-id)))
+
+        (is (= {:status 401
+                :errors ["You do not have permission to read access control groups for provider [PROV2]."]}
+               (u/get-group token prov2-group-concept-id)))))))


Experiment with js-object element in 0.14

Doesn't seem to do much for performance, unfortunately.

--- src/reagent/impl/template.cljs
+++ src/reagent/impl/template.cljs
@@ -330,6 +330,33 @@
       (warn (hiccup-err x "Every element in a seq should have a unique :key")))
     res))

+;; From https://github.com/babel/babel/commit/1d0e68f5a19d721fe8799b1ea331041d8bf9120e
+;; (def react-element-type (or (and (exists? js/Symbol)
+;;                                  (.' js/Symbol :for)
+;;                                  (.' js/Symbol for "react.element"))
+;;                             60103))
+
+;; (defn make-element-fast [argv comp jsprops first-child]
+;;   (let [key (some-> jsprops (.' :key))
+;;         ref (some-> jsprops (.' :ref))
+;;         props (if (nil? jsprops) (js-obj) jsprops)]
+;;     (.! props :children
+;;         (case (- (count argv) first-child)
+;;           0 nil
+;;           1 (as-element (nth argv first-child))
+;;           (reduce-kv (fn [a k v]
+;;                        (when (>= k first-child)
+;;                          (.push a (as-element v)))
+;;                        a)
+;;                      #js[] argv)))
+;;     (js-obj "key" key
+;;             "ref" ref
+;;             "props" props
+;;             "$$typeof" react-element-type
+;;             "type" comp
+;;             ;; "_store" (js-obj)
+;;             )))
+
 (defn make-element [argv comp jsprops first-child]
   (case (- (count argv) first-child)
     ;; Optimize cases of zero or one child


Make cursor position work for <textarea>s

It turns out that the type attribute of a <textarea> is always "textarea"
http://www.w3.org/TR/2012/WD-html5-20121025/the-textarea-element.html#dom-textarea-type

--- src/reagent/impl/template.cljs
+++ src/reagent/impl/template.cljs
@@ -91,7 +91,7 @@
   (.! this :cljsInputValue nil))

 ;; <input type="??" >
-(def these-inputs-have-a-cursor #{"text" "password" "email" "number" "search" "tel" "url"})
+(def these-inputs-have-a-cursor #{"text" "textarea" "password" "email" "number" "search" "tel" "url"})

 (defn has-cursor?
   [input-type]


Use mapv on render

Use mapv on render

--- test/graphql_clj/parser_test.clj
+++ test/graphql_clj/parser_test.clj
@@ -26,8 +26,8 @@
   (pp/pprint parsed-data (clojure.java.io/writer (str "test/scenarios/parsed/" to-filename))))

 (defn render-all-parsed! []
-  (render-parsed! "statements.edn" (map parser/parse test-statements))
-  (render-parsed! "schemas.edn" (map parser/parse test-schemas)))
+  (render-parsed! "statements.edn" (mapv parser/parse test-statements))
+  (render-parsed! "schemas.edn" (mapv parser/parse test-schemas)))

 ;(def type-fields-kv-example
 ;  "type Hello {


Add failing tests for RFC 4180 compliance

--- test/testdouble/cljs/csv_test.cljs
+++ test/testdouble/cljs/csv_test.cljs
@@ -22,6 +22,10 @@
     (testing "quote each field"
       (is (= "\"1,000\",\"2\",\"3\"\n\"4\",\"5,000\",\"6\"" (csv/write-csv [["1,000" "2" "3"] ["4" "5,000" "6"]] :quote? true))))

+    (testing "valid characters in quoted fields"
+      (is (= "\"a\nb\",\"c\rd\"\n\"e,f\",\"g\"\"h\""
+             (csv/write-csv [["a\nb" "c\rd"] ["e,f" "g\"h"]] :quote? true))))
+
     (testing "error when newline is not one of :lf OR :cr+lf"
       (is (thrown-with-msg? js/Error #":newline" (csv/write-csv data :newline "foo"))))))

@@ -37,7 +41,11 @@
       (is (= data (csv/read-csv "1,2,3\r\n4,5,6" :newline :cr+lf))))

     (testing "user defined separator '|' and newline ':cr+lf'"
-      (is (= data (csv/read-csv "1|2|3\r\n4|5|6" :separator "|" :newline :cr+lf))))))
+      (is (= data (csv/read-csv "1|2|3\r\n4|5|6" :separator "|" :newline :cr+lf))))
+
+    (testing "valid characters in quoted fields"
+      (is (= [["a\nb" "c\rd"] ["e,f" "g\"h"]]
+             (csv/read-csv "\"a\nb\",\"c\rd\"\n\"e,f\",\"g\"\"h\""))))))

 (defn ^:export run []
   (run-tests))


unsure what's to be done next

unsure what's to be done next

--- src/util/funxions.clj
+++ src/util/funxions.clj
@@ -20,6 +20,7 @@
 ;you need not bind this though, unless you really want to name it something
 ;but it won't clash with others, supposedly - there may be some case when it could clash let within a let
 (def ^:dynamic *fxn_defBlock_symbol* (gensym 'fxn_defBlock))
+(def ^:dynamic *fxn_defBlockRaw_symbol* (gensym 'fxn_defBlockRaw))

 (defmacro get_fxn
@@ -44,6 +45,7 @@
   )

 (get_fxn *fxn_defBlock_symbol* defBlock) ;(defmacro get_fxn_defBlock ...)
+(get_fxn *fxn_defBlockRaw_symbol* defBlockRaw) ;(defmacro get_fxn_defBlockRaw ...)
 ;(defmacro get_fxn_defBlock2
 ;  []
 ;  ;like get the value of <the symbol returned by *fxn_defBlock_symbol*>
@@ -69,22 +71,19 @@
    passedDefBlock; a map
    & codeblocks ;multiple forms as code
    ]
-  (let [lst (list
-            'backtick/template;-fn
-            ;backtick/syntax-quote-fn
-            passedDefBlock)
-        x (eval lst)
-        ;e (eval x)
+  (let [lst (list 'backtick/template passedDefBlock)
+        evaDefBlock (eval lst) ;the defblock after ~ are evaluated
+        ;e (eval evaDefBlock)
         ]
-    ;(println x); x == `'~x
+    (clojure.pprint/pprint (list "evaDefBlock=" evaDefBlock)); x == `'~x
     ;(println e)
     `(defn ~fname [& all#]
-       (let [~*fxn_defBlock_symbol* '~x
-             ~'fxn_rawDefBlock '~passedDefBlock
+       (let [~*fxn_defBlock_symbol* '~evaDefBlock
+             ~*fxn_defBlockRaw_symbol* '~passedDefBlock
              ;~'fxn_evalled ~e
              ]
-         ;(clojure.pprint/pprint (list "fxn_rawDefBlock" ~'fxn_rawDefBlock))
-         (clojure.pprint/pprint (list ~'*fxn_defBlock_symbol* ~*fxn_defBlock_symbol*));symbol and its value
+         ;(clojure.pprint/pprint (list ~'*fxn_defBlockRaw_symbol* ~*fxn_defBlockRaw_symbol*))
+         ;(clojure.pprint/pprint (list ~'*fxn_defBlock_symbol* ~*fxn_defBlock_symbol*));symbol and its value
          ;(println ~e)
          ~@codeblocks
          #_(= (~(:c x) ~(:d x))
@@ -130,6 +129,11 @@
   ;if you want some form to be evaluate then place ~ before it
   ;this is the defblock
   {;:something {:a ~(+ 1 2)}
+   :a (hash-map :a 1 :b 2)
+   :b ~(hash-map :a 3 :b 4 :a 5) ;that's one way to use dup keys and you wouldn't even catch the bug
+   :c {:a 6 :b 7
+       ;:a 8 ;can't dup this, will throw
+       }
    ;aliases are supported to allow later renaming the params used within the defblock without worrying that you forgot to rename all instances
    :aliases {;p1 p2 where p1 is parameter name used in here and p2 is the actual name the param has in the function body
              ;all names are keywords to allow evaluating the entire defblock and they are actually symbols inside the function body
@@ -180,7 +184,7 @@
   ;TODO: allow invariants functions for each param and throw when any of them fail(obviously)
   ;TODO: ignore optional params that weren't passed on call
   ;TODO: throw when required params aren't passed on call
-  (clojure.pprint/pprint (get_fxn_defBlock));firsta)
+  (clojure.pprint/pprint (list "foocode" (get_fxn_defBlock)));firsta)
   )
 ;)


Whoops.  Can't rely on segments.gen anymore.

Probably better to track our own timestamp anyway.

--- src/net/dishevelled/mailindex.clj
+++ src/net/dishevelled/mailindex.clj
@@ -282,12 +282,17 @@

 (defn index-age
   "Return the mtime of a Lucene index."
-  [indexfile]
-  (let [index (File. (str indexfile "/segments.gen"))
-        index-mtime (.lastModified (file indexfile "segments.gen"))]
-    (if (.exists index)
-      index-mtime
+  [^String indexfile]
+  (let [stat-file (File. (str indexfile "/mailindex.stat"))]
+    (if (.exists stat-file)
+      (Long/valueOf ^String (slurp stat-file))
       nil)))
+
+(defn store-index-age [^String indexfile ^Date date]
+  "Record the mtime of a Lucene index."
+  (let [stat-file (File. (str indexfile "/mailindex.stat"))]
+    (spit stat-file (str (.getTime date)))))
+

 (defmacro with-writer
@@ -365,12 +370,14 @@
   "Kick off the indexer."
   [state indexfile connections]
   (try
-    (let [last-update (index-age indexfile)]
+    (let [last-update (index-age indexfile)
+          round-start (java.util.Date.)]
       (doseq [connection connections]
         (with-writer indexfile iw
           (index connection
                  ((:new-messages-fn @connection) connection last-update)
-                 iw)))
+                 iw))
+        (store-index-age indexfile round-start))
       (when (time-to-optimise?)
         (doseq [connection connections]
           (do-deletes connection indexfile))))


add clips shortcut to shortcuts menu

add clips shortcut to shortcuts menu

--- src-cljs/frontend/components/overlay.cljs
+++ src-cljs/frontend/components/overlay.cljs
@@ -781,6 +781,9 @@
               [:td [:div.shortcuts-key {:title "T Key"} "T"]]
               [:td [:div.shortcuts-result {:title "Switch to Text Tool."} "Text"]]]
              [:tr.make
+              [:td [:div.shortcuts-key {:title "X Key"} "X"]]
+              [:td [:div.shortcuts-result {:title "Open clipboard history menu."} "Clips"]]]
+             [:tr.make
               [:td [:div.shortcuts-key {:title "1 Key"} "1"]]
               [:td [:div.shortcuts-result {:title "Initial view when entering doc."} "Origin"]]]
              [:tr.make


add active class as featurette is centered

--- src-cljs/frontend/components/overlay.cljs
+++ src-cljs/frontend/components/overlay.cljs
@@ -10,8 +10,10 @@
             [frontend.components.doc-viewer :as doc-viewer]
             [frontend.datascript :as ds]
             [frontend.overlay :refer [current-overlay overlay-visible? overlay-count]]
+            [frontend.scroll :as scroll]
             [frontend.state :as state]
             [frontend.utils :as utils :include-macros true]
+            [goog.dom]
             [om.core :as om :include-macros true]
             [om.dom :as dom :include-macros true])
   (:require-macros [frontend.utils :refer [html]])
@@ -290,15 +292,28 @@
    [:path.border {:d "M0,24v608c0,4.4,3.6,8,8,8h1008 c4.4,0,8-3.6,8-8V24"}]
    [:path.actions {:d "M16,12c0,2.2-1.8,4-4,4s-4-1.8-4-4s1.8-4,4-4S16,9.8,16,12z M44,8c-2.2,0-4,1.8-4,4s1.8,4,4,4 c2.2,0,4-1.8,4-4S46.2,8,44,8z M28,8c-2.2,0-4,1.8-4,4s1.8,4,4,4s4-1.8,4-4S30.2,8,28,8z"}]])

+(defn past-center? [owner ref]
+  (let [node (om/get-node owner ref)
+        vh (.-height (goog.dom/getViewportSize))]
+    (< (.-top (.getBoundingClientRect node)) (/ vh 2))))
+
+;; TODO: update to new om so that we don't need this
+(defn maybe-set-state! [owner korks value]
+  (when (not= (om/get-state owner korks) value)
+    (om/set-state! owner korks value)))
+
 (defn overlay [app owner]
   (reify
-    om/IRender
-    (render [_]
+    om/IInitState (init-state [_] {:past-center-featurettes #{}})
+    om/IRenderState
+    (render-state [_ {:keys [past-center-featurettes]}]
       (let [cast! (om/get-shared owner :cast!)
             overlay-components (map #(get overlay-components %) (get-in app state/overlays-path))
             title (:title (last overlay-components))]
         (html
-          [:div.app-overlay {:on-click #(cast! :overlay-closed)}
+         [:div.app-overlay {:on-click #(cast! :overlay-closed)
+                            :on-scroll #(maybe-set-state! owner [:past-center-featurettes]
+                                                          (set (filter (partial past-center? owner) ["1" "2" "3" "4" "5"])))}
            [:div.app-overlay-background]
             [:div.app-overlay-home
              [:div.jumbotron
@@ -316,35 +331,40 @@
                [:h4 "Productive prototyping without all the nonsense."]
                [:button "Launch Precursor"]]]
              [:div.home-body
-              [:article.featurette
+              [:article.featurette {:ref "1"
+                                    :class (when (contains? past-center-featurettes "1") "active")}
                [:div.featurette-story
                 [:h2 "Sharing prototypes should be simple."]
                 [:p "Lorem ipsum dolor sit amet, consectetur adipiscing elit.
                     Sed felis enim, rhoncus a lobortis at, porttitor nec tellus.
                     Aliquam gravida consequat velit, ultrices porttitor turpis sagittis et."]]
                [:div.featurette-media screen]]
-              [:article.featurette.featurette-how
+              [:article.featurette.featurette-how  {:ref "2"
+                                                    :class (when (contains? past-center-featurettes "2") "active")}
                [:div.featurette-story
                 [:h2 "Express your ideas efficiently with simple tools."]
                 [:p "Lorem ipsum dolor sit amet, consectetur adipiscing elit.
                     Sed felis enim, rhoncus a lobortis at, porttitor nec tellus.
                     Aliquam gravida consequat velit, ultrices porttitor turpis sagittis et."]]
                [:div.featurette-media screen]]
-              [:article.featurette.featurette-how
+              [:article.featurette.featurette-how {:ref "3"
+                                                   :class (when (contains? past-center-featurettes "3") "active")}
                [:div.featurette-story
                 [:h2 "Interact with your ideas before building them."]
                 [:p "Lorem ipsum dolor sit amet, consectetur adipiscing elit.
                     Sed felis enim, rhoncus a lobortis at, porttitor nec tellus.
                     Aliquam gravida consequat velit, ultrices porttitor turpis sagittis et."]]
                [:div.featurette-media screen]]
-              [:article.featurette.featurette-how
+              [:article.featurette.featurette-how {:ref "4"
+                                                   :class (when (contains? past-center-featurettes "4") "active")}
                [:div.featurette-story
                 [:h2 "Share your ideas faster without forgetting them."]
                 [:p "Lorem ipsum dolor sit amet, consectetur adipiscing elit.
                     Sed felis enim, rhoncus a lobortis at, porttitor nec tellus.
                     Aliquam gravida consequat velit, ultrices porttitor turpis sagittis et."]]
                [:div.featurette-media screen]]
-              [:article.featurette
+              [:article.featurette {:ref "5"
+                                    :class (when (contains? past-center-featurettes "5") "active")}
                [:div.featurette-story
                 [:h2 "Pure prototyping, just focus on the idea."]
                 [:p "Lorem ipsum dolor sit amet, consectetur adipiscing elit.


Update clojure version to 1.7.0

Update clojure version to 1.7.0

--- ssclj/jar/project.clj
+++ ssclj/jar/project.clj
@@ -8,7 +8,7 @@
   :test-paths     ["src/test/clojure"]
   :resource-paths ["src/main/resources"]

-  :dependencies [[org.clojure/clojure                       "1.6.0"]
+  :dependencies [[org.clojure/clojure                       "1.7.0"]
                  [org.clojure/tools.logging                 "0.3.0"]
                  [org.clojure/tools.namespace               "0.2.5"]
                  [org.clojure/tools.cli                     "0.3.1"]


minor tweaks to scalar-power

minor tweaks to scalar-power

--- src/push/type/item/scalar.clj
+++ src/push/type/item/scalar.clj
@@ -261,7 +261,7 @@
 (def scalar-power
   (core/build-instruction
     scalar-power
-    "`:scalar-power` pops the top two `:scalar` values (call them `exponent` and `base` respectively). It calculates `(numeric-tower/expt base exponent)`. In cases of overflow, an :error is pushed."
+    "`:scalar-power` pops the top two `:scalar` values (call them `exponent` and `base` respectively). It calculates `(numeric-tower/expt base exponent)`."
     :tags #{:arithmetic :base :dangerous}

     (d/consume-top-of :scalar :as :exp)


Bump and fix cider and deps

Bump and fix cider and deps

--- lein/profiles.clj
+++ lein/profiles.clj
@@ -1,9 +1,10 @@
 {:user {:plugins [;;[lein-nodisassemble "0.1.2"]
                   [jonase/eastwood "0.1.4"]
                   [lein-try "0.4.3"]
-                  [cider/cider-nrepl "0.8.0-SNAPSHOT"]
+                  [cider/cider-nrepl "0.9.0-SNAPSHOT"]
                   [lein-gorilla "0.3.3"]
                   [lein-exec "0.3.4"]]
         :dependencies [[slamhound "1.5.5"]
-                       [criterium "0.4.3"]]
+                       [criterium "0.4.3"]
+                       [org.clojure/tools.nrepl "0.2.10"]]
         :repl-options {:init (require '[criterium.core :as crit])}}}


Avoid shadowed theme for smoother rendering

--- src/main/clojure/dm/viz/chart.clj
+++ src/main/clojure/dm/viz/chart.clj
@@ -4,7 +4,7 @@
     (org.jfree.chart ChartFactory ChartPanel StandardChartTheme)
     (org.jfree.chart.editor ChartEditorManager)))

-(ChartFactory/setChartTheme (StandardChartTheme. "JFree/Shadow" true))
+(ChartFactory/setChartTheme (StandardChartTheme/createJFreeTheme))

 (defmulti chart class)


Story ID: RPC-298 added remote save/restore of support viewer tickets

--- src/untangled/support_viewer.cljs
+++ src/untangled/support_viewer.cljs
@@ -2,25 +2,44 @@
   (:require
     [om.next :as om :refer-macros [defui]]
     [om.dom :as dom]
+    [untangled.client.data-fetch :refer [load-singleton]]
     [untangled.client.core :as core]
     [untangled.client.mutations :as m]
     [yahoo.intl-messageformat-with-locales]
     [untangled.i18n :refer-macros [tr trf]]
-    [untangled.client.impl.network :as net]))
+    [untangled.client.impl.network :as net])
+  (:import goog.Uri))
+
+(defn get-url
+  [] (-> js/window .-location .-href))
+
+(defn uri-params
+  ([] (uri-params (get-url)))
+  ([url]
+   (let [query-data (.getQueryData (goog.Uri. url))]
+     (into {}
+       (for [k (.getKeys query-data)]
+         [k (.get query-data k)])))))
+
+(defn get-url-param
+  ([param-name] (get-url-param (get-url) param-name))
+  ([url param-name]
+   (get (uri-params url) param-name)))

 (defui ^:once SupportViewerRoot
   static om/IQuery
-  (query [this] [:react-key :current-position :client-time :frames :position])
+  (query [this] [:react-key :current-position :client-time :frames :position :comments])
   Object
   (render [this]
-    (let [{:keys [react-key current-position client-time frames position] :or {react-key "ROOT"}} (om/props this)]
+    (let [{:keys [react-key current-position client-time frames position comments] :or {react-key "ROOT"}} (om/props this)]
       (dom/div #js {:key react-key :className (str "history-controls " (name position))}
         (dom/button #js {:onClick #(om/transact! this '[(support-viewer/toggle-position)])} (tr "<===>"))
         (dom/button #js {:onClick #(om/transact! this '[(support-viewer/step-back)])} (tr "<Back"))
         (dom/button #js {:onClick #(om/transact! this '[(support-viewer/step-forward)])} (tr "Forward>"))
         (dom/hr nil)
         (dom/span #js {:className "frame"} (trf "Frame {f,number} of {end,number} " :f (inc current-position) :end frames))
-        (dom/span #js {:className "timestamp"} (trf "{ts,date,short} {ts,time,long}" :ts client-time))))))
+        (dom/span #js {:className "timestamp"} (trf "{ts,date,short} {ts,time,long}" :ts client-time))
+        (dom/div #js {:className "user-comments"} comments)))))

 (defn history-entry [history n]
   (let [steps (:steps history)
@@ -35,7 +54,6 @@
       (do (core/refresh this) this)
       (do
         (reset! application (core/mount @application app-root dom-id))
-        (core/reset-state! @application (history-entry history (-> history :steps count dec)))
         (reset! support (core/mount @support SupportViewerRoot dom-id-or-node))
         @support)))

@@ -47,21 +65,37 @@
 (defn start-untangled-support-viewer
   "Create and display a new untangled support viewer on the given app root, with VCR controls to browse through the given history. The support HTML file must include
   a div with app-dom-id (to mount the app) and a div with support-dom-id to mount the viewer controls."
-  [support-dom-id AppRoot app-dom-id history]
+  [support-dom-id AppRoot app-dom-id]
   (let [app (atom (core/new-untangled-client :networking (net/mock-network)))
-        max-idx (dec (count (:steps history)))
-        viewer (map->SupportViewer {:history     history
-                                    :app-root    AppRoot
+        viewer (map->SupportViewer {:app-root    AppRoot
                                     :dom-id      app-dom-id
                                     :application app
                                     :support     (atom (core/new-untangled-client
-                                                         :initial-state {:history          history
+                                                         :initial-state {:history          {}
                                                                          :application      app
-                                                                         :position        :controls-left
+                                                                         :position         :controls-left
                                                                          :client-time      (js/Date.)
-                                                                         :frames           (inc max-idx)
-                                                                         :current-position max-idx}
-                                                         :networking (net/mock-network)))})]
+                                                                         :frames           0
+                                                                         :current-position 0}
+                                                         :started-callback
+                                                         (fn [{:keys [reconciler]}]
+                                                           (load-singleton reconciler `[:support-request]
+                                                             :callback (fn [state]
+                                                                         (swap! state
+                                                                           (fn [s]
+                                                                             (let [req (:support-request @state)
+                                                                                comments (:comment req)
+                                                                                history (:history req)
+                                                                                frames (-> history :steps count)
+                                                                                last-idx (dec frames)]
+                                                                               (core/reset-state! @app (history-entry history last-idx))
+                                                                               (-> s
+                                                                                (dissoc :support-request)
+                                                                                (assoc :comments comments)
+                                                                                (assoc :frames frames)
+                                                                                (assoc :history history)
+                                                                                (assoc :current-position last-idx))))))
+                                                             :params {:id (get-url-param "id")}))))})]
     (core/mount viewer SupportViewerRoot support-dom-id)))

 (defn history-step [state delta-fn]


Simplify projects initialize event.

Simplify projects initialize event.

--- src/uxbox/main/data/projects.cljs
+++ src/uxbox/main/data/projects.cljs
@@ -41,22 +41,9 @@
   (-apply-update [_ state]
     (assoc-in state [:dashboard :section] :dashboard/projects))

-  rs/EffectEvent
-  (-apply-effect [_ state]
-    (when-not (seq (:projects-by-id state))
-      (reset! st/loader true)))
-
   rs/WatchEvent
   (-apply-watch [_ state s]
-    (let [projects (seq (:projects-by-id state))]
-      (if projects
-        (rx/empty)
-        (rx/merge
-         (rx/of (fetch-projects))
-         (->> (rx/filter projects-fetched? s)
-              (rx/take 1)
-              (rx/do #(reset! st/loader false))
-              (rx/ignore)))))))
+    (rx/of (fetch-projects))))

 (defn initialize
   []


Implemented apply-pipeline to load and execute pipeline definitions

--- src/pipeline/grafter/pipeline.clj
+++ src/pipeline/grafter/pipeline.clj
@@ -125,6 +125,26 @@
     (catch java.io.FileNotFoundException e
       nil)))

+(defmulti apply-pipeline
+  "Takes a string representing a fully qualified function and reloads
+  and requires its namespace before applying it to the supplied arguments.
+
+  If given a function directly it will just apply it to the arguments
+  as normal."
+  (fn [pipeline inputs] (class pipeline)))
+
+(defmethod apply-pipeline String [pipeline inputs]
+  (let [fsym (symbol pipeline)
+        ns (symbol (namespace fsym))]
+    (require ns :reload-all)
+    (let [f (ns-resolve ns fsym)]
+      (if f
+        (apply-pipeline f inputs)
+        (throw (ex-info (str "Could not find pipeline " pipeline) {:error :could-not-find-pipeline :pipeline pipeline}))))))
+
+(defmethod apply-pipeline clojure.lang.IFn [pipeline inputs]
+  (apply pipeline inputs))
+
 (comment
   (->> (find-clj-classpath-resources)
        (mapcat find-resource-pipelines)


Remove duplicate code section.

Remove duplicate code section.

--- src/rdf-common/grafter/rdf/io.clj
+++ src/rdf-common/grafter/rdf/io.clj
@@ -208,13 +208,6 @@

   (sesame-rdf-type->type [this]
     this)
-
-  URI
-  (->sesame-rdf-type [this]
-    this)
-
-  (sesame-rdf-type->type [this]
-    (str this))

   LiteralImpl
   (->sesame-rdf-type [this]


Add missing import

Add missing import

Editing directly on github is probably never a good idea :(

--- src/refactor_nrepl/ns/helpers.clj
+++ src/refactor_nrepl/ns/helpers.clj
@@ -1,8 +1,7 @@
 (ns refactor-nrepl.ns.helpers
   (:require [clojure.string :as str]
             [clojure.tools.namespace.parse :refer [read-ns-decl]])
-  (:import java.io.PushbackReader
-           java.io.FileReader))
+  (:import [java.io FileReader PushbackReader StringReader]))

 (defn- libspec?
   [thing]


remove unused require

remove unused require

--- test/clj_money/api/lots_test.clj
+++ test/clj_money/api/lots_test.clj
@@ -9,8 +9,7 @@
             [clj-money.x-platform.util :refer [path
                                                map->query-string]]
             [clj-money.api.test-helper :refer [add-auth]]
-            [clj-money.web.test-helpers :refer [assert-successful
-                                                assert-not-found]]
+            [clj-money.web.test-helpers :refer [assert-successful]]
             [clj-money.serialization :as serialization]
             [clj-money.test-helpers :refer [reset-db
                                             pprint-diff


More testing fun...

More testing fun...

--- test/cljs/zetawar/subs_test.cljs
+++ test/cljs/zetawar/subs_test.cljs
@@ -205,6 +205,7 @@
                  :unit-type/description
                  :unit-type/min-range
                  :unit-type/max-range
+                 :unit-type/armor-type
                  :unit-type/can-capture
                  :unit-type/can-repair
                  :unit-type/image}


[#5031] Remove additional # to chat title when it is a public chat

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

--- src/status_im/chat/screen.cljs
+++ src/status_im/chat/screen.cljs
@@ -39,7 +39,7 @@
         [react/i18n-text {:style style/add-contact-text :key :add-to-contacts}]]])))

 (defn- on-options [chat-id chat-name group-chat? public?]
-  (list-selection/show {:title   (if public? (str "#" chat-name) chat-name)
+  (list-selection/show {:title   chat-name
                         :options (actions/actions group-chat? chat-id public?)}))

 (defview chat-toolbar [public?]


Remove unused imports.

Remove unused imports.

--- src/afterglow/web/routes/show_control.clj
+++ src/afterglow/web/routes/show_control.clj
@@ -8,7 +8,6 @@
             [afterglow.controllers :as controllers]
             [clojure.data.json :refer [read-json write-str]]
             [com.evocomputing.colors :as colors]
-            [compojure.core :refer [defroutes GET]]
             [org.httpkit.server :refer [with-channel on-receive on-close]]
             [overtone.at-at :refer [now after]]
             [ring.util.response :refer [response]]


remove trace output

remove trace output

--- src/clj/clj_money/models/transactions.clj
+++ src/clj/clj_money/models/transactions.clj
@@ -455,10 +455,6 @@
   ([storage-spec criteria]
    (search-items storage-spec criteria {}))
   ([storage-spec criteria options]
-
-   (pprint {:search-items criteria
-            :options options})
-
    (with-storage [s storage-spec]
      (map after-item-read
           (select-transaction-items s


Implémenté recherche selon valeur entrée dans champ

--- core-async/src/core_async/core.cljs
+++ core-async/src/core_async/core.cljs
@@ -34,4 +34,23 @@
 (defn query-url [q]
   (str wiki-search-url q))

-(go (.log js/console (<! (jsonp (query-url "cats")))))
+(defn user-query []
+  (.-value (dom/getElement "query")))
+
+(defn render-query [results]
+  (str
+    "
"
+    (apply str
+      (for [result results]
+        (str "
" result "
")))
+    "
"))
+
+(defn init []
+  (let [clicks (listen (dom/getElement "search") "click")
+        results-view (dom/getElement "results")]
+    (go (while true
+          (<! clicks)
+          (let [[_ results] (<! (jsonp (query-url (user-query))))]
+            (set! (.-innerHTML results-view) (render-query results)))))))
+
+(init)


Refactoring - flat-file-exporter

Refactoring - flat-file-exporter

--- src/emender_jenkins/metadata_exporter.clj
+++ src/emender_jenkins/metadata_exporter.clj
@@ -64,13 +64,9 @@
     (with-out-str
         (clojure.pprint/pprint data)))

-(defn export2csv
-    [columns data]
-    (data->csv (cons columns data)))
-
-(defn export2txt
-    [columns data]
-    (data->txt (cons columns data)))
+(defn flat-file-export
+    [columns data export-function]
+    (export-function (cons columns data)))

 (defn export2json
     [columns data]
@@ -99,7 +95,7 @@
     (case output-format
         :json  (export2json columns data)
         :edn   (export2edn columns data)
-        :csv   (export2csv columns data)
-        :txt   (export2txt columns data)
+        :csv   (flat-file-export columns data data->csv)
+        :txt   (flat-file-export columns data data->txt)
         :xml   (export2xml columns data)))


Revert "Backend now adds the original poster's name to replies"

This reverts commit 97219508695070d1be33a41d58750073e30af2ee.

--- src/statuses/backend/core.clj
+++ src/statuses/backend/core.clj
@@ -67,10 +67,9 @@
            (assoc :timeline (cons id (:timeline db)))
            (assoc :next-id (inc id)))))
   ([db author text reply-to]
-     (let [id (:next-id db)
-           other (:author (get-update db reply-to))]
+     (let [id (:next-id db)]
        (-> db
-           (add-update author (str "@" other " " text))
+           (add-update author text)
            (add-conversation id reply-to)))))

 (defn get-conversation


Separate paragraphs preprocess from rest of code

--- src/text_justification/model.cljs
+++ src/text_justification/model.cljs
@@ -5,7 +5,6 @@
 (enable-console-print!)

-;;;; TODO filter out empty words
 ;;;; TODO precalc badness to hash ?

@@ -22,10 +21,9 @@

 (defonce state (atom []))

-(defn- set-state    [new-state] (swap! state (fn [] new-state)))
+(defn- set-state    [new-state] (swap! state (fn [] new-state))) ;; TODO just use reset!
 (defn- clear-state  [] (set-state []))
 (defn- update-state [new-lines] (set-state (concat @state new-lines)))
-

 ;;;;
 ;;;; implementation
@@ -75,32 +73,50 @@
           (map inc (range (count words))) )))) ;; TODO (dec (count words)) ?

-(defn- prepare-text
-  "split by paragraphs or treat text as single text flow"
-  [text separate-paragraphs]
-  (if separate-paragraphs
-    (seq (.split text "\n"))
-    [(clojure.string/replace text #"\n" " ")]
-    ))
+(defn- split-word
+  "Split words that have length > max-len"
+  [max-len word]
+  (let [len (count word)]
+    (if (<= len max-len)
+      [word]
+      (concat
+        [(.substring word 0 max-len)]
+        (split-word max-len (str " -" (.substring word max-len))) ))))
+; (defn split-word-test [str]
+  ; (let [res (split-word 11 str)]
+  ; (println "test(" (count res) ")" res)))
+; (split-word-test "aaabbbccc111")
+; (split-word-test "aaabbbccc111aaabbbccc111")
+; (split-word-test "aaabbbccc111aaabbbccc111aaabbbccc111")

-(defn- prepare-word
-  "remove whitespaces, split word if it is too long"
-  [max-len word-raw]
-  (let [word (gstring/trim word-raw) len (count word)]
-    (cond
-      (<= max-len 0) [word]
-      (zero? len) [invisible-char]
-      (<= len max-len) [word]
-      :else (concat
-          [(.substring word 0 max-len)]
-          (prepare-word max-len (str " -" (.substring word max-len)))) )))
-; (defn prepare-word-test [str]
-  ; (let [res (prepare-word 11 str)]
-    ; (println "test(" (count res) ")" res)))
-; (prepare-word-test "aaabbbccc111")
-; (prepare-word-test "aaabbbccc111aaabbbccc111")
-; (prepare-word-test "aaabbbccc111aaabbbccc111aaabbbccc111")
+(defn- prepare-paragraph
+  [paragraph max-chars-in-line]
+  (-> paragraph
+         gstring/trim
+         (.split #" +")
+         (->> (mapv #(split-word max-chars-in-line %))
+              flatten
+              vec)))
+
+(defn- prepare-text
+  "Prepare whole text for justification.
+   1) split by paragraphs / treat text as single text flow
+   2) trim words
+   @return vector of lines, where each line is vector of words"
+  [text separate-paragraphs max-chars-in-line]
+  (let [paragraphs (if separate-paragraphs
+                        (seq (.split text "\n"))
+                        [(clojure.string/replace text #"\n" " ")] )]
+      (mapv #(prepare-paragraph % max-chars-in-line) paragraphs) ))
+; (defn prepare-text-test [str]
+  ; (let [res (prepare-text str true 11)]
+  ; (println "pt-test(" (count res) ")" res "\n\t\t" (mapv count res) )))
+; (prepare-text-test " aa ab ")
+; (prepare-text-test "aaabbbccc111aaabbbccc111aaabbbccc111")
+; (prepare-text-test "Lorem ipsum dolor sit amet, consectetur adipiscing elit")
+
+

 ;;;;
 ;;;; public interface
@@ -110,29 +126,24 @@
   "justify text provided as a collection of words to given page width"
   [text separate-paragraphs page-width]
   {:pre [(> page-width 0)]}
+
   (clear-state)
-  (doseq [paragraph (prepare-text text separate-paragraphs)]
-    ; (println "PARAGRAPH:" paragraph)
-    (.profile js.console "text-justification")
-    (let [words-raw (.split paragraph #" +")
-          ;;words (vec (filter .blank? (flatten (map #(prepare-word page-width %) words-raw))))
-          words (vec (flatten (map #(prepare-word page-width %) words-raw)))
-          word-lens (vec (map count words))
-          justified-text (tj-inner page-width word-lens)]
-        ; (.log js/console "words" (count words) ":" words)
-        ; (.log js/console "state" (count justified-text) ":" justified-text)
-        (update-state
+  (.profile js.console "text-justification")
+  (doseq [words-in-paragraph (prepare-text text separate-paragraphs page-width)]
+    ; (println "PARAGRAPH:" words-in-paragraph)
+    (let [words-lengths (mapv count words-in-paragraph)
+          justified-text (tj-inner page-width words-lengths)]
+       ; (.log js/console "words" (count words) ":" words)
+       ; (.log js/console "state" (count justified-text) ":" justified-text)
+       (update-state
         (second (reduce
-          (fn [[start-word-idx lines-atm] words-in-line]
-            (let [next-word-start-idx (+ start-word-idx words-in-line)
-                  words-in-this-line (subvec words start-word-idx next-word-start-idx)]
+          (fn [[start-word-idx lines-atm] line-words-count]
+            (let [next-word-start-idx (+ start-word-idx line-words-count)
+                  words-in-this-line (subvec words-in-paragraph start-word-idx next-word-start-idx)]
               ; (println words-in-this-line)
-              [next-word-start-idx (conj lines-atm words-in-this-line)]
-              ))
+              [next-word-start-idx (conj lines-atm words-in-this-line)] ))
           [0 []]
-          justified-text)))
-      )
-    (.profileEnd js.console)
-  ))
+          justified-text))) ))
+  (.profileEnd js.console)
+  )

-


Add docstring and minor improvements on public traverse api.

--- src/cats/core.cljc
+++ src/cats/core.cljc
@@ -740,8 +740,21 @@
      (foldm f z xs))))

 (defn traverse
+  "Map each element of a structure to an action, evaluate these
+  actions from left to right, and collect the results.
+
+      (defn inc-if-even
+        [n]
+        (if (even? n)
+          (maybe/just (inc n))
+          (maybe/nothing)))
+
+      (ctx/with-context maybe/context
+        (m/traverse inc-if-even [2 4]))
+      ;; => #<Just [3 4]>
+  "
   ([f tv]
-   (traverse (ctx/get-current) f tv))
+   (p/-traverse (p/-get-context tv) f tv))
   ([ctx f tv]
    (ctx/with-context ctx
      (p/-traverse (p/-get-context tv) f tv))))


add :trusted-strings true closure compiler option

this defaults to false for good reason, but for most code this
is actually unnecessary and confuses tools like tailwind jit.

for safety the closure compiler changes = to \x3d and <> chars.
basically everything that may lead to some XSS attack vector.

--- src/main/shadow/build/closure.clj
+++ src/main/shadow/build/closure.clj
@@ -209,6 +209,9 @@
         :local VariableRenamingPolicy/LOCAL
         :all VariableRenamingPolicy/ALL
         (throw (ex-info "invalid :variable-renaming (use :off, :local or :all)" {})))))
+
+  (when (true? (:trusted-strings opts))
+    (.setTrustedStrings closure-opts true))

   (when (contains? opts :property-renaming)
     (.setPropertyRenaming


ah-gawb-1396 fixed broken autocomplete query (#656)

* fixed broken autocomplete query
* add set-property method

--- src/cljs/main/broadfcui/page/workspace/summary/catalog/questions.cljs
+++ src/cljs/main/broadfcui/page/workspace/summary/catalog/questions.cljs
@@ -131,20 +131,21 @@
                              :onClick #(apply swap! state update :attributes dissoc
                                               (library-utils/get-related-id+label-props library-schema property))})]]))])

-(defn- render-populate-typeahead [{:keys [prop property inputHint]}]
+(defn- render-populate-typeahead [{:keys [property inputHint set-property]}]
   [:div {:style {:marginBottom "0.75em"}}
    [comps/AutocompleteFilter
     {:width "100%"
      :ref "text-filter"
      :placeholder inputHint
-     :bloodhoundInfo {:url (str (config/api-url-root) "/api/library/populate/suggest/" (name property) "/")
+     :on-filter set-property
+     :bloodhoundInfo {:url (str (config/api-url-root) "/api/library/populate/suggest/" (name property))
                       :cache false
                       :prepare (fn [query settings]
                                  (clj->js
                                    (assoc (js->clj settings)
                                      :headers {:Authorization (str "Bearer " (utils/get-access-token))}
                                      :type "GET"
-                                     :url (str (aget settings "url") query))))}
+                                     :url (str (aget settings "url") "?q=" query))))}
      :typeaheadSuggestionTemplate (fn [result]
                                     (str "
" result  "
"))}]])

@@ -206,6 +207,7 @@
                               :value-nullsafe (or current-value "") ;; avoids warning for nil value
                               :required? (contains? required-attributes property)
                               :update-property #(swap! state update :attributes assoc property (.. % -target -value))
+                              :set-property #(swap! state update :attributes assoc property %)
                               :radio (fn [{:keys [val label]}]
                                        [:label {:style (colorize {:display "inline-flex" :alignItems "center"
                                                                   :cursor "pointer" :marginRight "2em"})}


Send 2 Mdips input.

Send 2 Mdips input.

--- src/dsbdp/main.clj
+++ src/dsbdp/main.clj
@@ -124,7 +124,7 @@
                     (cond
                       (.endsWith scenario "-direct")
                         (let [proc-fn (condp = scenario
-                                        "busy-sleep-direct" (fn [in] (ExperimentHelper/busySleep (first in)))
+                                        "busy-sleep-direct" (fn [in] (ExperimentHelper/busySleep ^long (first in)))
                                         "factorial-direct" factorial
                                         "opennlp-single-direct" opennlp-single-sentence-direct-test-fn
                                         "opennlp-multi-direct" opennlp-multi-sentence-direct-test-fn
@@ -137,7 +137,7 @@
                             (.inc out-cntr)))
                       (not (nil? in-data)) (let [in-fn (get-in-fn pipeline)]
                                              (fn []
-                                               (doseq [i (repeat 1000 0)]
+                                               (doseq [i (repeat 2000 0)]
                                                  (in-fn in-data)
                                                  (.inc in-cntr))
                                                (sleep 1)))


Provide a means for braid consumers to stop the application

--- src/braid/core.clj
+++ src/braid/core.clj
@@ -1,24 +1,34 @@
 (ns braid.core
   (:gen-class)
   (:require
-    [mount.core :as mount]
-    [org.httpkit.client]
-    [org.httpkit.sni-client]
-    [braid.core.modules :as modules]
-    ;; all following requires are for mount:
-    [braid.core.server.core]
-    [braid.core.server.email-digest :refer [email-jobs]]))
+   [mount.core :as mount]
+   [org.httpkit.client]
+   [org.httpkit.sni-client]
+   [braid.core.modules :as modules]
+   ;; all following requires are for mount:
+   [braid.core.server.core]
+   [braid.core.server.email-digest :refer [email-jobs]]))

 ;; because we often use http-kit as our http-client
 ;; including this so that SNI works
 (alter-var-root #'org.httpkit.client/*default-client*
                 (fn [_] org.httpkit.sni-client/default-client))

+(defn start!
+  "Entry point for prod"
+  [port]
+  ;; modules must run first
+  (modules/init!)
+  (-> (mount/with-args {:port port})
+      (mount/start {:port port})))
+
+(defn stop!
+  "Helper function for stopping all Braid components."
+  []
+  (mount/stop))
+
 (defn -main
   "Entry point for prod"
   [& args]
   (let [port (Integer/parseInt (first args))]
-    ; modules must run first
-    (modules/init!)
-    (-> (mount/with-args {:port port})
-        (mount/start {:port port}))))
+    (start! port)))