New program flow

New program flow

--- src/juzi/core.clj
+++ src/juzi/core.clj
@@ -21,23 +21,21 @@
 (defn start []
   (clear-screen)
   (let [cr (ConsoleReader.)]
-    (println "Press 'y' if you know how to say Chinese word/sentence for this following English word/sentence, press something else otherwise.")
-    (println "Ready? Press any key to continue ...")
-    (.readCharacter cr)
     (clear-screen)
     (loop [s (s/make-session (expand-data (load-sources)))]
       (if-let [w (s/next-word s)]
         (let [{:keys [id en zh]} w]
-          (println en)
-          (flush)
+          (println (str "What's Chinese for \"" en "\"?" " Make sure you get the tones right!" ))
+          (println)
+          (println "Press any key to see the answer ...")
+          (.readCharacter cr)
+          (println)
+          (println "answer:" zh)
+          (println)
+          (println "Were you correct? [y/n]")
           (let [i (.readCharacter cr)]
+            (clear-screen)
             (if (= \y (char i))
-              (do (println "ans:" zh)
-                  (.readCharacter cr)
-                  (clear-screen)
-                  (recur (s/mark-passed s id)))
-              (do (println "ans:" zh)
-                  (.readCharacter cr)
-                  (clear-screen)
-                  (recur s)))))
+              (recur (s/mark-passed s id))
+              (recur s))))
         (println "You have passed all the words! Gōngxǐ. Zàijiàn.")))))


Update boot.clj

Update boot.clj

--- src/meta/boot.clj
+++ src/meta/boot.clj
@@ -39,8 +39,8 @@
 (boot/deftask standup
   "Standup cross project builds."
   []
-  (comp (ver/version)
-        (dependencies)))
+  (comp (ver/version)))
+        ;(dependencies)))
         ;(shadow/server)))

 (boot/deftask client


Updated lein-cucumber version

Updated lein-cucumber version

--- examples/clojure_cukes/project.clj
+++ examples/clojure_cukes/project.clj
@@ -1,5 +1,5 @@
 (defproject clojure_cukes "1.0.X"
   :description "A demo of Cucumber with Clojure and Leiningen"
   :dependencies [[org.clojure/clojure "1.5.0-beta1"]]
-  :plugins [[lein-cucumber "1.0.0"]]
+  :plugins [[lein-cucumber "1.0.1"]]
   :cucumber-feature-paths ["test/features/"])


pre-reserve seats

pre-reserve seats

--- src/kmc_booking/db.clj
+++ src/kmc_booking/db.clj
@@ -119,11 +119,33 @@
 ;; TODO: Update seats with status
 (defn create-booking [name phone seats]
 	(let [booking-id (gen-id)
-		  records (for [rows (range 3 4)
+		  records (concat
+		  			(for [rows (range 3 4)
                  	  cols (range 4 37)]
                       {:id (str rows "-" cols)
                        :status "paid"
-                       :booking_id booking-id})]
+                       :booking_id booking-id})
+
+		  			(for [rows (range 1 3)
+                          cols (range 1 4)]
+                      {:id (str rows "-" cols)
+                       :status "paid"
+                       :booking_id booking-id})
+
+		  			(for [rows (range 1 3)
+                          cols (range 37 40)]
+                      {:id (str rows "-" cols)
+                       :status "paid"
+                       :booking_id booking-id})
+
+		  			(for [rows (range 11 12)
+                          cols (range 20 26)]
+                      {:id (str rows "-" cols)
+                       :status "paid"
+                       :booking_id booking-id})
+		  			)
+
+		  			]

 		(sql/with-db-connection [c CONN]
 			(sql/insert! c "bookings"
@@ -155,7 +177,7 @@
 			(gen-seats-data seat-schema))))

 (defn migrate__seats_for_judges! []
-	(create-booking "ЖУРІ" "-" [])
+	(create-booking "ЖУРІ & передзамовлення" "-" [])
 	)


Hopefully compiles?

Hopefully compiles?

--- src/lazubot/master.clj
+++ src/lazubot/master.clj
@@ -5,6 +5,7 @@
             [clojure.set :refer [difference]]
             [clojure.core.async :refer [<! >! go chan sliding-buffer]]
             [clojure-zulip.core :as zulip]
+            [clojail.core :refer [sandbox]]
             [com.keminglabs.zmq-async.core :refer [register-socket!]])
   (:import [java.io PushbackReader]))


Catch errors when requiring tasks in help. Fixes #172.

--- src/leiningen/help.clj
+++ src/leiningen/help.clj
@@ -72,7 +72,9 @@

 ;; affected by clojure ticket #130: bug of AOT'd namespaces losing metadata
 (defn help-summary-for [task-ns]
-  (require task-ns)
+  (try (require task-ns)
+       (catch Error e
+         (println (format "Failed to load %s: %s" task-ns (.getMessage e)))))
   (let [task-name (last (.split (name task-ns) "\\."))]
     (str task-name (apply str (repeat (- 12 (count task-name)) " "))
          (:doc (meta (find-ns task-ns))))))


Change directory to first project named for 'box-add.

--- src/leiningen/voom.clj
+++ src/leiningen/voom.clj
@@ -671,7 +671,12 @@
       (println "box adding" (str (-> dep meta :voom)) dep)
       (case (count repo-infos)
         0 (throw (ex-info "Could not find matching projects" {:dep dep}))
-        1 (box-repo-add (first repo-infos))
+        1 (let [repo-info (first repo-infos)
+                pname (proj-id->name (:proj repo-info))
+                pdir (adj-path *pwd* pname)]
+            (box-repo-add repo-info)
+            (when (= dep (first deps))
+              (box-cmd "target_dir='" (.getAbsolutePath pdir) "'")))
         (do
           (print "Multiple projects / locations match" (str \" dep \"\:))
           (print-repo-infos repo-infos))))))


Remove a println

Remove a println

--- src/pani/core.clj
+++ src/pani/core.clj
@@ -54,9 +54,7 @@
   "Bind to a certain property under the given root"
   ([root type korks]
    (let [bc (chan)]
-     (pani.core/bind root type korks #(do
-                                        (println "Pushing" %)
-                                        (go (>! bc %))))
+     (pani.core/bind root type korks #(go (>! bc %)))
      bc))

   ([root type korks cb]


remove inspect

remove inspect

--- src/pc/server.clj
+++ src/pc/server.clj
@@ -58,7 +58,7 @@

 ;; We'll redefine this function at run-time to test in production
 (defn use-frontend-ids? [req]
-  (pc.utils/inspect (contains? #{"dwwoelfel@gmail.com" "danny.newidea@gmail.com"} (get-in req [:auth :cust :cust/email])))
+  (contains? #{"dwwoelfel@gmail.com" "danny.newidea@gmail.com"} (get-in req [:auth :cust :cust/email]))
   false
   )


URL Encode search query.

URL Encode search query.

Fixes #464

--- src-cljs/kixi/hecuba/tabs/hierarchy/data.cljs
+++ src-cljs/kixi/hecuba/tabs/hierarchy/data.cljs
@@ -282,7 +282,7 @@
 (defn search-properties [data page size query]
   (log "Searching for: " query)
   (om/update! data :fetching true)
-  (GET (str "/4/entities/?q=" query "&page=" page "&size=" size)
+  (GET (str "/4/entities/?q=" (js/encodeURIComponent query) "&page=" page "&size=" size)
        {:handler (fn [response]
                    (let [entities (:entities response)]
                      (om/update! data :data (into [] entities))


only render things that are displayable

only render things that are displayable

--- src/pc/render.clj
+++ src/pc/render.clj
@@ -8,6 +8,40 @@
             [pc.utils :as utils]
             [hiccup.core :refer (h html)])
   (:import [org.apache.commons.io IOUtils]))
+
+(defmulti displayable? (fn [layer] (:layer/type layer)))
+
+(defmethod displayable? :default [layer] false)
+
+(defmethod displayable? :layer.type/rect
+  [layer]
+  (and (:layer/start-x layer)
+       (:layer/end-x layer)
+       (:layer/start-y layer)
+       (:layer/end-y layer)
+       (not (zero? (- (:layer/start-x layer)
+                      (:layer/end-x layer))))
+       (not (zero? (- (:layer/start-y layer)
+                      (:layer/end-y layer))))))
+
+(defmethod displayable? :layer.type/line
+  [layer]
+  (and (:layer/start-x layer)
+       (:layer/end-x layer)
+       (:layer/start-y layer)
+       (:layer/end-y layer)
+       (not= [(:layer/start-x layer) (:layer/start-y layer)]
+             [(:layer/end-x layer) (:layer/end-y layer)])))
+
+(defmethod displayable? :layer.type/path
+  [layer]
+  (and (:layer/path layer)
+       (pos? (count (:layer/path layer)))))
+
+(defmethod displayable? :layer.type/text
+  [layer]
+  (seq (:layer/text layer)))
+

 (defmulti svg-element (fn [layer opts] (:layer/type layer)))

@@ -111,8 +145,7 @@
 ;; If they've drawn in negative directions, then we to shift the viewport in the
 ;; that direction with a transform.
 (defn render-layers [layers & {:keys [invert-colors? size-limit] :as args}]
-  (let [layers (map #(into {} %) (filter #(and (:layer/type %)
-                                               (not= :layer.type/group (:layer/type %))) layers))
+  (let [layers (map #(into {} %) (filter displayable? layers))
         {:keys [width height offset-top offset-left padding scale-factor]} (utils/apply-map svg-props layers args)]
     (html [:svg (merge
                  {:viewBox (str "0 0 " width " " height)


get rid of /api/transact

get rid of /api/transact

--- src/pc/server.clj
+++ src/pc/server.clj
@@ -39,9 +39,6 @@
   (routes
    (POST "/api/entity-ids" request
          (datomic/entity-id-request (-> request :body slurp edn/read-string :count)))
-   (POST "/api/transact" request
-         (let [body (-> request :body slurp edn/read-string)]
-           (datomic/transact! (:datoms body) (:document-id body) (get-in request [:session :uid]))))
    (GET "/api/document/:id" [id]
         ;; TODO: should probably verify document exists
         ;; TODO: take tx-date as a param


adding license

adding license

--- src/puny/core.clj
+++ src/puny/core.clj
@@ -1,3 +1,14 @@
+(comment
+   Celestial, Copyright 2012 Ronen Narkis, narkisr.com
+   Licensed under the Apache License,
+   Version 2.0  (the "License") you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.)
+
 (ns puny.core
   "A tiny redis based ORM,
    Caveat: crud+index operations are not atomic, introducing lua procedures will fix that."


Remove some needless log statements.

Remove some needless log statements.

--- metlog-vault/src-client/tsplot.cljs
+++ metlog-vault/src-client/tsplot.cljs
@@ -102,19 +102,12 @@
     (.stroke ctx)))

 (defn draw [ ctx w h sinfo ]
-  (.log js/console (:end sinfo))
-  (.log js/console "query-range: " (pr-str (dissoc sinfo :data)))
   (draw-background ctx w h)
   (let [w (- w y-axis-space tsplot-right-margin)
         h (- h x-axis-space)]
     (with-preserved-ctx ctx
       (.translate ctx y-axis-space 0)
       (draw-series-background ctx w h)
-      (.log js/console "data-range:" (let [ sxr (s-xrange (:data sinfo)) ]
-                                       (.log js/console (time-coerce/from-long (:max sxr)))
-                                       (pr-str {:max (time-coerce/from-long (:max sxr))
-                                                :min (time-coerce/from-long (:min sxr))})))
-
       (draw-series ctx w h (:data sinfo) {:min (:begin sinfo) :max (:end sinfo)})
       (draw-frame ctx w h))))


add mdl-shadow--2dp for singleporjec

add mdl-shadow--2dp for singleporjec

--- app/src/cljs/app/components.cljs
+++ app/src/cljs/app/components.cljs
@@ -56,7 +56,7 @@

 (defn single-project-component
   [project]
-  [:div.projectcomponent.mdl-card.mdl-shadow--2dp
+  [:div.mdl-cell.mdl-cell--4-col.singleproject.mdl-shadow--2dp
    [:div.projecttitle
     [:a {:href (:url project)} (:title project)]]
    [:div.projectimg
@@ -68,9 +68,11 @@
   [projects]
   [:div#projects
    [section-component
-    [:div.projectsheader.mdl-grid--no-spacing
-     [:h3.mdl-cell.mdl-cell--12-col "projects"]
-     (into [:div.project.mdl-cell.mdl-cell--4-col] (map #(single-project-component %) projects))]]])
+    [:div.mdl-grid--no-spacing
+     [:h3.projectsheader.mdl-cell.mdl-cell--12-col "projects"]
+     [:div
+      (into [:div.project.mdl-grid]
+            (map #(single-project-component %) projects))]]]])

 (defn single-employment-component
   [employment]


type-hinting, bug-fix, lose println

type-hinting, bug-fix, lose println

--- src/main/clojure/org/dada/demo/whales.clj
+++ src/main/clojure/org/dada/demo/whales.clj
@@ -4,6 +4,7 @@
  (:use [org.dada.core])
  (:import [clojure.lang Symbol])
  (:import [java.math BigDecimal])
+ (:import [java.util Collection])
  (:import [org.dada.core
 	   Average
 	   Creator
@@ -15,6 +16,7 @@
 	   Transformer$Transform
 	   VersionedModelView

+	   Update
 	   Reducer
 	   Reducer$Strategy
 	   ])
@@ -113,7 +115,7 @@
 ;; create 10,000 whales and insert them into model
 (insert-n
  whales
- (let [num-whales 10
+ (let [num-whales 10000
        time (System/currentTimeMillis)
        #^Creator creator (.getCreator whale-metadata)
        max-length-x-100 (* max-length 100)
@@ -157,7 +159,7 @@
 (def longer-whales-weight (do-transform "weight" longer-whales :time :version :weight))
 (insert *metamodel* longer-whales-weight)

-(def heavier-whales-length (do-transform "length" heavier-whales :time :version :length))
+(def #^Model heavier-whales-length (do-transform "length" heavier-whales :time :version :length))
 (insert *metamodel* heavier-whales-length)

 ;;----------------------------------------
@@ -195,8 +197,8 @@
 			       [:key String :version Integer :sum Number])
       getter (.getAttributeGetter (.getMetadata heavier-whales-length) "length")
       accessor (fn [value] (.get getter value))
-      new-value #(accessor (.getNewValue %))
-      old-value #(accessor (.getOldValue %))]
+      new-value (fn [#^Update update] (accessor (.getNewValue update)))
+      old-value (fn [#^Update update] (accessor (.getOldValue update)))]
   (def sum
        (proxy
 	[Reducer$Strategy]
@@ -204,8 +206,7 @@
 	(initialValue [] 0M)
 	(initialType [type] type)
 	(currentValue [key version value]
-		      (println "currentValue: " key version value)
-		      (.create metadata [key version value]))
+		      (.create #^Metadata metadata #^Collection (collection key version value)))
 	(reduce [insertions updates deletions]
 		(-
 		 (+
@@ -214,7 +215,6 @@
 		 (reduce #(+ %1 (old-value %2)) 0 deletions))
 		)
 	(apply [currentValue delta]
-	       (println "apply: " currentValue  delta)
 	       (+ currentValue delta))
 	))


remove debug print

remove debug print

--- src/qmon/core.clj
+++ src/qmon/core.clj
@@ -120,7 +120,6 @@
                        (.setText button (if x "Wake" "Sleep" ))
                        (if-not x (.setText text-area waitmsg))
                        (not x))]
-    (println user)
     (do
       (doto text-area
         (.setFont (Font. "Monospaced" (Font/PLAIN) 12))


DO make current-graphics public now. Add metadata to it.

--- src/quil/core.clj
+++ src/quil/core.clj
@@ -12,7 +12,13 @@
        :private true}
   *graphics* nil)

-(defn- ^PGraphics current-graphics
+(defn
+  ^{:requires-bindings true
+    :category "Environment"
+    :subcategory nil
+    :added "2.0"
+    :tag PGraphics}
+  current-graphics
   "Graphics currently used for drawing. By default it is sketch graphics,
   but if called inside with-graphics macro - graphics passed to the macro
   is returned. This method should be used if you need to call some methods


Move defn in sqs-test

Move defn in sqs-test

--- test/eulalie/sqs_test.clj
+++ test/eulalie/sqs_test.clj
@@ -19,6 +19,8 @@
         (get-queue-url* q-name)
         (throw e)))))

+(defn delete-queue* [queue] (sqs!! :delete-queue {:queue-url queue}))
+
 (defn with-transient-queue [f]
   (let [q-name (str "eulalie-transient-" (gensym))
         q-url  (create-queue* q-name)]
@@ -28,7 +30,6 @@
         (delete-queue* q-url)))))

 (defn purge-queue*  [queue] (sqs!! :purge-queue  {:queue-url queue}))
-(defn delete-queue* [queue] (sqs!! :delete-queue {:queue-url queue}))

 (deftest get-queue-attributes+
   (with-transient-queue


Remove contrib dependencies from ring.m.session.cookie.

--- ring-core/src/ring/middleware/session/cookie.clj
+++ ring-core/src/ring/middleware/session/cookie.clj
@@ -1,8 +1,7 @@
 (ns ring.middleware.session.cookie
   "Encrypted cookie session storage."
-  (:use [clojure.contrib.def :only (defvar-)]
-        ring.middleware.session.store)
-  (:require (ring.util [codec :as codec]))
+  (:use ring.middleware.session.store)
+  (:require [ring.util.codec :as codec])
   (:import java.security.SecureRandom
            (javax.crypto Cipher Mac)
            (javax.crypto.spec SecretKeySpec IvParameterSpec)))


Test for IRC msg color functions

Test for IRC msg color functions

--- test/clj_mrazik/dictionary_test.clj
+++ test/clj_mrazik/dictionary_test.clj
@@ -125,3 +125,51 @@
         (is (= java.lang.String (type (highlight "string" "code"))))
         (is (= (char 3) (.charAt (highlight "string" "code") 0)))))

+(deftest test-black
+    "Checks the function black."
+    (testing "the function black."
+        (is (= java.lang.String (type (black "string"))))
+        (is (= (subs (black "string") 3 9) "string"))
+        (is (= (subs (black "string") 1 3) "01"))))
+
+(deftest test-red
+    "Checks the function red."
+    (testing "the function red."
+        (is (= java.lang.String (type (red "string"))))
+        (is (= (subs (red "string") 3 9) "string"))
+        (is (= (subs (red "string") 1 3) "04"))))
+
+(deftest test-green
+    "Checks the function green."
+    (testing "the function green."
+        (is (= java.lang.String (type (green "string"))))
+        (is (= (subs (green "string") 3 9) "string"))
+        (is (= (subs (green "string") 1 3) "03"))))
+
+(deftest test-blue
+    "Checks the function blue."
+    (testing "the function blue."
+        (is (= java.lang.String (type (blue "string"))))
+        (is (= (subs (blue "string") 3 9) "string"))
+        (is (= (subs (blue "string") 1 3) "02"))))
+
+(deftest test-purple
+    "Checks the function purple."
+    (testing "the function purple."
+        (is (= java.lang.String (type (purple "string"))))
+        (is (= (subs (purple "string") 3 9) "string"))
+        (is (= (subs (purple "string") 1 3) "06"))))
+
+(deftest test-yellow
+    "Checks the function yellow."
+    (testing "the function yellow."
+        (is (= java.lang.String (type (yellow "string"))))
+        (is (= (subs (yellow "string") 3 9) "string"))
+        (is (= (subs (yellow "string") 1 3) "08"))))
+
+(deftest test-bold
+    "Checks the function bold."
+    (testing "the function bold."
+        (is (= java.lang.String (type (bold "string"))))
+        (is (= (subs (bold "string") 1 7) "string"))))
+


fix: only require modules that are not commented out

--- resources/leiningen/new/expo/env/dev/user.clj
+++ resources/leiningen/new/expo/env/dev/user.clj
@@ -125,6 +125,15 @@
         (catch Exception e
           (println "Error: " e)))))

+(defn- required-modules
+  "returns a vector of string with the names of the imported modules. Ignoring those
+  that are commented out"
+  [file-content]
+  (some->> file-content
+           (re-seq #"(?m)^[^;\n]+?\(js/require \"([^\"]+)\"\)")
+           (map last)
+           (vec)))
+
   ;; Each file maybe corresponds to multiple modules.
   (defn watch-for-external-modules
     []
@@ -144,19 +153,7 @@

                                   (when (.exists file)
                                     (let [content (slurp file)
-                                          js-modules (some->>
-                                                       content
-                                                       (re-seq #"\(js/require \"([^\"]+)\"\)")
-                                                       (map last)
-                                                       (vec))
-                                          commented-modules (some->>
-                                                              content
-                                                              (re-seq #"[;]{2,}.*\(js/require \"([^\"]+)\"\)")
-                                                              (map last)
-                                                              (set))
-                                          js-modules (if commented-modules
-                                                       (vec (remove commented-modules js-modules))
-                                                       js-modules)]
+                                          js-modules (required-modules content)]
                                       (let [old-js-modules (get m file-name)]
                                         (when (not= old-js-modules js-modules)
                                           (let [new-m (if (seq js-modules)
@@ -180,19 +177,7 @@
           (let [file-name (-> (.getPath file)
                               (str/replace (str (System/getProperty "user.dir") "/") ""))
                 content (slurp file)
-                js-modules (some->>
-                             content
-                             (re-seq #"\(js/require \"([^\"]+)\"\)")
-                             (map last)
-                             (vec))
-                commented-modules (some->>
-                                    content
-                                    (re-seq #"[;]{2,}.*\(js/require \"([^\"]+)\"\)")
-                                    (map last)
-                                    (set))
-                js-modules (if commented-modules
-                             (vec (remove commented-modules js-modules))
-                             js-modules)]
+                js-modules (required-modules content)]
             (if js-modules
               (swap! m assoc file-name (vec js-modules))))))
       (spit path @m)


New tests: test-store-ccs-description-existence and test-store-changes-existence

--- test/clouseau/test_db_interface.clj
+++ test/clouseau/test_db_interface.clj
@@ -88,3 +88,13 @@
     (testing "if the clouseau.db-interface/read-all-packages-provided-by-ccs definition exists."
         (is (callable? 'clouseau.db-interface/read-all-packages-provided-by-ccs))))

+(deftest test-store-ccs-description-existence
+    "Check that the clouseau.db-interface/store-ccs-description definition exists."
+    (testing "if the clouseau.db-interface/store-ccs-description definition exists."
+        (is (callable? 'clouseau.db-interface/store-ccs-description))))
+
+(deftest test-store-changes-existence
+    "Check that the clouseau.db-interface/store-changes definition exists."
+    (testing "if the clouseau.db-interface/store-changes definition exists."
+        (is (callable? 'clouseau.db-interface/store-changes))))
+


Add begin-contour/end-contour functions.

--- src/quil/core.clj
+++ src/quil/core.clj
@@ -385,6 +385,20 @@
   For most situations the camera function will be sufficient."
   []
   (.beginCamera (current-surface)))
+
+(defn
+  ^{:requires-bindings true
+    :processing-name "beginContour()"
+    :category "Shape"
+    :subcategory "Vertex"
+    :added "2.0"}
+  begin-contour
+  "Use the begin-contour and end-contour function to create negative
+  shapes within shapes. These functions can only be within a
+  begin-shape/end-shape pair and they only work with the :p2d and :p3d
+  renderers."
+  []
+  (.beginContour (current-surface)))

 (defn
   ^{:requires-bindings true
@@ -1442,6 +1456,22 @@
   "Unsets the matrix mode from the camera matrix. See begin-camera."
   []
   (.endCamera (current-surface)))
+
+
+(defn
+  ^{:requires-bindings true
+    :processing-name "endContour()"
+    :category "Shape"
+    :subcategory "Vertex"
+    :added "2.0"}
+  end-contour
+  "Use the begin-contour and end-contour function to create negative
+  shapes within shapes. These functions can only be within a
+  begin-shape/end-shape pair and they only work with the :p2d and :p3d
+  renderers."
+  []
+  (.endContour (current-surface)))
+

 (defn
   ^{:requires-bindings true


Added remaining filters.

Added remaining filters.

--- src/cljs/wombats_web_client/panels/games.cljs
+++ src/cljs/wombats_web_client/panels/games.cljs
@@ -47,28 +47,50 @@
     (= status :closed)))

 (defn is-mine?
-  [game github-username]
-  (> (count (filter #(= github-username
+  [game current-user]
+  (> (count (filter #(= (:user/github-username current-user)
                         (get-in % [:player/user :user/github-username]))
                     (:game/players game)))
      0))
+
+(defn get-open-games
+  [games]
+  (reduce-kv (fn [coll _ [game]]
+               (if (is-open? game)
+                 (conj coll game)
+                 coll)) [] games))

 (defn get-my-open-games
   [games current-user]
   (reduce-kv (fn [coll _ [game]]
                (if (and (is-open? game)
-                        (is-mine? game (:user/github-username current-user)))
+                        (is-mine? game current-user))
+                 (conj coll game)
+                 coll)) [] games))
+
+(defn get-closed-games
+  [games]
+  (reduce-kv (fn [coll _ [game]]
+               (if (is-closed? game)
+                 (conj coll game)
+                 coll)) [] games))
+
+(defn get-my-closed-games
+  [games current-user]
+  (reduce-kv (fn [coll _ [game]]
+               (if (and (is-closed? games)
+                        (is-mine? game current-user))
                  (conj coll game)
                  coll)) [] games))

 ;; End Utils

-(defn get-sorted-games [{:keys [show-open show-my-games open closed my-open my-closed games current-user]}]
+(defn get-sorted-games [{:keys [show-open show-my-games games current-user]}]
   (cond
     (and show-open show-my-games) (sort-by :game/start-time (get-my-open-games games current-user))
-    (and (not show-open) show-my-games) (sort-by :game/end-time > my-closed)
-    (and show-open (not show-my-games)) (sort-by :game/start-time open)
-    (and (not show-open) (not show-my-games)) (sort-by :game/end-time > closed)))
+    (and (not show-open) show-my-games) (sort-by :game/end-time > (get-my-closed-games games current-user))
+    (and show-open (not show-my-games)) (sort-by :game/start-time (get-open-games games))
+    (and (not show-open) (not show-my-games)) (sort-by :game/end-time > (get-closed-games games))))

 (defn get-empty-state [show-open show-my-games]
   (cond


Change record accessor

Change record accessor

--- src/obb_rules/unit.clj
+++ src/obb_rules/unit.clj
@@ -29,7 +29,7 @@
 (defn gather-units
   "Gets all the available units"
   []
-  (map #(map->CombatUnit %)
+  (mapv #(map->CombatUnit %)
     [obb-rules.units.rain/metadata
      obb-rules.units.nova/metadata
      obb-rules.units.pretorian/metadata
@@ -76,19 +76,19 @@
   (let [identifier (name raw)]
     (or (get-unit-by-name identifier) (get-unit-by-code identifier))))

-(defn unit-name "Gets a unit's name" [unit] (.name unit))
-(defn unit-code "Gets a unit's code" [unit] (.code unit))
-(defn unit-attack "Gets a unit's attack" [unit] (.attack unit))
-(defn unit-bonus "Gets a unit's bonus" [unit] (.bonus unit))
-(defn unit-range "Gets a unit's range" [unit] (.range unit))
-(defn unit-defense "Gets a unit's defense" [unit] (.defense unit))
-(defn unit-movement-cost "Gets a unit's movement cost" [unit] (.movement-cost unit))
-(defn unit-movement-type "Gets a unit's movement type" [unit] (.movement-type unit))
-(defn unit-category "Gets a unit's category" [unit] (.category unit))
-(defn unit-displacement "Gets a unit's displacement" [unit] (.displacement unit))
-(defn unit-type "Gets a unit's type" [unit] (.type unit))
-(defn unit-value "Gets a unit's hardcore value" [unit] (or (.value unit) 0))
-(defn attack-type "Gets the unit's attack type" [unit] (or (.attack-type unit) :direct))
+(defn unit-name "Gets a unit's name" [unit] (:name unit))
+(defn unit-code "Gets a unit's code" [unit] (:code unit))
+(defn unit-attack "Gets a unit's attack" [unit] (:attack unit))
+(defn unit-bonus "Gets a unit's bonus" [unit] (:bonus unit))
+(defn unit-range "Gets a unit's range" [unit] (:range unit))
+(defn unit-defense "Gets a unit's defense" [unit] (:defense unit))
+(defn unit-movement-cost "Gets a unit's movement cost" [unit] (:movement-cost unit))
+(defn unit-movement-type "Gets a unit's movement type" [unit] (:movement-type unit))
+(defn unit-category "Gets a unit's category" [unit] (:category unit))
+(defn unit-displacement "Gets a unit's displacement" [unit] (:displacement unit))
+(defn unit-type "Gets a unit's type" [unit] (:type unit))
+(defn unit-value "Gets a unit's hardcore value" [unit] (or (:value unit) 0))
+(defn attack-type "Gets the unit's attack type" [unit] (or (:attack-type unit) :direct))
 (defn event-hooks "Gets the hooks for an event" [unit event] (event unit))
 (defn catapult? "True if the unit has catapult" [unit] (= :catapult (attack-type unit)))


Update doc link

Update doc link

--- tutorial/pull.clj
+++ tutorial/pull.clj
@@ -6,8 +6,8 @@
 ;   the terms of this license.
 ;   You must not remove this notice, or any other, from this software.

-;; The examples below parallel http://docs.datomic.com/pull.html
-;; sample data at https://github.com/Datomic/mbrainz-sample
+;; The examples below parallel http://docs.datomic.com/cloud/query/query-pull.html
+;; sample data at https://github.com/Datomic/mbrainz-importer

 ;; get connected
 (require '[datomic.client.api.alpha :as d])


force users to see admin

force users to see admin

--- src/ontrail/unread.clj
+++ src/ontrail/unread.clj
@@ -24,6 +24,7 @@

 (defn is-own? [user ex]
   (or (= user (:user ex))
+      (= "admin" (:user ex))
       (contains? (set (map :user (:comments ex))) user)))

 (defn comments-own [user]


comments; naming

comments; naming

--- Clojure-Websockets/MainApp/src/cljs/birdwatch/charts/ts_chart.cljs
+++ Clojure-Websockets/MainApp/src/cljs/birdwatch/charts/ts_chart.cljs
@@ -5,28 +5,34 @@
             [reagent.core :as r :refer [atom]]
             [cljs.core.async :as async :refer [chan sub timeout sliding-buffer]]))

-(enable-console-print!)
-
-(def bars (atom []))
+(def bars-atom (atom []))
 (def label (atom {}))

 (def ts-elem (util/by-id "timeseries1"))
 (def ts-w (aget ts-elem "offsetWidth"))
 (def ts-h 100)

-(defn bar [x y h w idx]
+(defn bar
+  "Renders a vertical bar. Enables showing a label when the mouse is
+   positioned above the bar."
+  [x y h w idx]
   [:rect {:x x :y (- y h) :fill "steelblue" :width w :height h
           :on-mouse-enter #(reset! label {:idx idx})
           :on-mouse-leave #(reset! label {})}])

-(defn barchart [indexed mx cnt w]
+(defn barchart
+  "Renders a bar chart, making use of the bar function above. Returns
+   entire SVG element."
+  [indexed mx cnt w]
   (let [gap (/ (/ ts-w 20) cnt)]
     [:svg {:width ts-w :height ts-h}
      [:g
       (for [[idx [k v]] indexed]
         ^{:key k} [bar (* idx w) ts-h (* (/ v mx) ts-h) (- w gap) idx])]]))

-(defn labels [bars mx cnt w]
+(defn labels
+  "Renders a label for a bar chart. Makes use of Rickshaw's CSS."
+  [bars mx cnt w]
   (when-not (empty? @label)
     (let [idx (:idx @label)
           [k v] (get bars idx)
@@ -37,8 +43,12 @@
        [:div.item.active {:class lr :style {:top top}} "Tweets: " v]
        [:div.dot.active {:style {:top top :border-color "steelblue"}}]])))

-(defn ts-chart []
-  (let [bars @bars
+(defn ts-chart
+  "Renders time series chart consisting of SVG for the bars and a label.
+   Appearance is similar to the Rickshaw timeseries chart, which this
+   component replaced, except for the CSS."
+  []
+  (let [bars @bars-atom
         indexed (vec (map-indexed vector bars))
         mx (apply max (map (fn [[k v]] v) bars))
         cnt (count bars)
@@ -55,7 +65,7 @@
   (let [state-chan (chan (sliding-buffer 1))]
     (go-loop []
              (let [[_ state] (<! state-chan)]
-               (reset! bars (ts/ts-data state))
+               (reset! bars-atom (ts/ts-data state))
                (<! (timeout every-ms))
                (recur)))
     (sub state-pub :app-state state-chan)))


whitespace fix

whitespace fix

--- frontend/components/changelog.cljs
+++ frontend/components/changelog.cljs
@@ -41,9 +41,9 @@
                                       (str "https://twitter.com/" (:twitter team-member))
                                       (str "https://github.com/" (:github team-member)))}
                           (:name team-member)]
-                         " on "))
+                         " on"))
                  [:a {:href (:link entry)}
-                  (datetime/as-time-since (:pubDate entry))]]]
+                  " " (datetime/as-time-since (:pubDate entry))]]]
                [:div.entry-avatar
                 (when team-member
                   [:img {:src (:img-path team-member)}])]])]]])))))


Reorder core

Reorder core

--- src/tick/core.clj
+++ src/tick/core.clj
@@ -218,33 +218,62 @@
   (instant [zdt] (.toInstant zdt))
   (zone [zdt] (.getZone zdt)))

-(defprotocol IDuration
-  (nanos [_] "Return the given quantity in nanoseconds.")
-  (micros [_] "Return the given quantity in microseconds.")
-  (millis [_] "Return the given quantity in milliseconds.")
-  (seconds [_] "Return the given quantity in seconds.")
-  (minutes [_] "Return the given quantity in minutes.")
-  (hours [_] "Return the given quantity in hours.")
-  (days [_] "Return the given quantity in days."))
-
-(extend-protocol IDuration
-  Number
-  (nanos [n] (Duration/ofNanos n))
-  (micros [n] (Duration/ofNanos (* n 1000)))
-  (millis [n] (Duration/ofMillis n))
-  (seconds [n] (Duration/ofSeconds n))
-  (minutes [n] (Duration/ofMinutes n))
-  (hours [n] (Duration/ofHours n))
-  (days [n] (Duration/ofDays n))
-
-  Duration
-  (nanos [d] (.toNanos d))
-  (micros [d] (Long/divideUnsigned (nanos d) 1000))
-  (millis [d] (.toMillis d))
-  (seconds [d] (.getSeconds d))
-  (minutes [d] (.toMinutes d))
-  (hours [d] (.toHours d))
-  (days [d] (.toDays d)))
+(defprotocol ITimeComparison
+  (< [x y] "Is x before y?")
+  (<= [x y] "Is x before or at the same time as y?")
+  (> [x y] "Is x after y?")
+  (>= [x y] "Is x after or at the same time as y?"))
+
+(extend-protocol ITimeComparison
+  Instant
+  (< [x y] (.isBefore x y))
+  (<= [x y] (not (.isAfter x y)))
+  (> [x y] (.isAfter x y))
+  (>= [x y] (not (.isBefore x y)))
+
+  LocalDateTime
+  (< [x y] (.isBefore x y))
+  (<= [x y] (not (.isAfter x y)))
+  (> [x y] (.isAfter x y))
+  (>= [x y] (not (.isBefore x y)))
+
+  LocalTime
+  (< [x y] (.isBefore x y))
+  (<= [x y] (not (.isAfter x y)))
+  (> [x y] (.isAfter x y))
+  (>= [x y] (not (.isBefore x y)))
+
+  LocalDate
+  (< [x y] (.isBefore x y))
+  (<= [x y] (not (.isAfter x y)))
+  (> [x y] (.isAfter x y))
+  (>= [x y] (not (.isBefore x y)))
+
+  OffsetDateTime
+  (< [x y] (.isBefore x y))
+  (<= [x y] (not (.isAfter x y)))
+  (> [x y] (.isAfter x y))
+  (>= [x y] (not (.isBefore x y)))
+
+  ZonedDateTime
+  (< [x y] (.isBefore x y))
+  (<= [x y] (not (.isAfter x y)))
+  (> [x y] (.isAfter x y))
+  (>= [x y] (not (.isBefore x y)))
+
+  YearMonth
+  (< [x y] (.isBefore x y))
+  (<= [x y] (not (.isAfter x y)))
+  (> [x y] (.isAfter x y))
+  (>= [x y] (not (.isBefore x y)))
+
+  Year
+  (< [x y] (.isBefore x y))
+  (<= [x y] (not (.isAfter x y)))
+  (> [x y] (.isAfter x y))
+  (>= [x y] (not (.isBefore x y))))
+
+;; Units

 (def unit-map
   {:nanos ChronoUnit/NANOS
@@ -264,6 +293,45 @@
    :eras ChronoUnit/ERAS
    :forever ChronoUnit/FOREVER})

+(def reverse-unit-map (into {} (map vec (map reverse unit-map))))
+
+(defn units [x]
+  (into {}
+        (for [tu (.getUnits x)
+              :let [k (reverse-unit-map tu)]
+              :when k]
+          [k (.get x tu)])))
+
+;; Durations
+
+(defprotocol IDuration
+  (nanos [_] "Return the given quantity in nanoseconds.")
+  (micros [_] "Return the given quantity in microseconds.")
+  (millis [_] "Return the given quantity in milliseconds.")
+  (seconds [_] "Return the given quantity in seconds.")
+  (minutes [_] "Return the given quantity in minutes.")
+  (hours [_] "Return the given quantity in hours.")
+  (days [_] "Return the given quantity in days."))
+
+(extend-protocol IDuration
+  Number
+  (nanos [n] (Duration/ofNanos n))
+  (micros [n] (Duration/ofNanos (* n 1000)))
+  (millis [n] (Duration/ofMillis n))
+  (seconds [n] (Duration/ofSeconds n))
+  (minutes [n] (Duration/ofMinutes n))
+  (hours [n] (Duration/ofHours n))
+  (days [n] (Duration/ofDays n))
+
+  Duration
+  (nanos [d] (.toNanos d))
+  (micros [d] (Long/divideUnsigned (nanos d) 1000))
+  (millis [d] (.toMillis d))
+  (seconds [d] (.getSeconds d))
+  (minutes [d] (.toMinutes d))
+  (hours [d] (.toHours d))
+  (days [d] (.toDays d)))
+
 (defn duration [n u]
   (let [unit (unit-map u)]
     (assert unit (str "Not a unit: " u))
@@ -287,92 +355,6 @@
     :months (Period/ofMonths n)
     :years (Period/ofYears n)))

-;; Units
-
-(def reverse-unit-map (into {} (map vec (map reverse unit-map))))
-
-(defn units [x]
-  (into {}
-        (for [tu (.getUnits x)
-              :let [k (reverse-unit-map tu)]
-              :when k]
-          [k (.get x tu)])))
-
-;; Between
-
-(defprotocol ITimeBetween
-  (between [t1 t2] "Return the most appropriate type of value that
-  represents the gap between two times"))
-
-(extend-protocol ITimeBetween
-  Instant
-  (between [inst _] (throw (ex-info "TODO" {}))))
-
-(defprotocol ITimeComparison
-  (< [x y] "Is x before y?")
-  (<= [x y] "Is x before or at the same time as y?")
-  (> [x y] "Is x after y?")
-  (>= [x y] "Is x after or at the same time as y?"))
-
-(extend-protocol ITimeComparison
-  Instant
-  (< [x y] (.isBefore x y))
-  (<= [x y] (not (.isAfter x y)))
-  (> [x y] (.isAfter x y))
-  (>= [x y] (not (.isBefore x y)))
-
-  LocalDateTime
-  (< [x y] (.isBefore x y))
-  (<= [x y] (not (.isAfter x y)))
-  (> [x y] (.isAfter x y))
-  (>= [x y] (not (.isBefore x y)))
-
-  LocalTime
-  (< [x y] (.isBefore x y))
-  (<= [x y] (not (.isAfter x y)))
-  (> [x y] (.isAfter x y))
-  (>= [x y] (not (.isBefore x y)))
-
-  LocalDate
-  (< [x y] (.isBefore x y))
-  (<= [x y] (not (.isAfter x y)))
-  (> [x y] (.isAfter x y))
-  (>= [x y] (not (.isBefore x y)))
-
-  OffsetDateTime
-  (< [x y] (.isBefore x y))
-  (<= [x y] (not (.isAfter x y)))
-  (> [x y] (.isAfter x y))
-  (>= [x y] (not (.isBefore x y)))
-
-  ZonedDateTime
-  (< [x y] (.isBefore x y))
-  (<= [x y] (not (.isAfter x y)))
-  (> [x y] (.isAfter x y))
-  (>= [x y] (not (.isBefore x y)))
-
-  YearMonth
-  (< [x y] (.isBefore x y))
-  (<= [x y] (not (.isAfter x y)))
-  (> [x y] (.isAfter x y))
-  (>= [x y] (not (.isBefore x y)))
-
-  Year
-  (< [x y] (.isBefore x y))
-  (<= [x y] (not (.isAfter x y)))
-  (> [x y] (.isAfter x y))
-  (>= [x y] (not (.isBefore x y))))
-
-(defprotocol ITimeRangeable
-  (range [_] [_ _] [_ _ _] "Returns a lazy seq of times from start (inclusive) to end (exclusive, nil means forever), by step, where start defaults to 0, step to 1, and end to infinity."))
-
-(defprotocol IDivisible
-  (/ [_ _] "Divide time"))
-
-(extend-protocol IDivisible
-  String
-  (/ [s d] (/ (parse s) d)))
-
 (defprotocol ITimeArithmetic
   (+ [_ _] "Add time")
   (- [_ _] "Subtract time"))
@@ -380,6 +362,9 @@
 (defprotocol ITimeIncDec
   (inc [_] "Increment time")
   (dec [_] "Decrement time"))
+
+(defprotocol ITimeRangeable
+  (range [_] [_ _] [_ _ _] "Returns a lazy seq of times from start (inclusive) to end (exclusive, nil means forever), by step, where start defaults to 0, step to 1, and end to infinity."))

 (defn greater [x y]
   (if (neg? (compare x y)) y x))
@@ -506,10 +491,17 @@
     ([from to step] (cond->> (iterate #(.plus % step) from)
                       to (take-while #(< % to))))))

-(defprotocol IDivisbleDuration
+(defprotocol IDivisible
+  (/ [_ _] "Divide time"))
+
+(extend-protocol IDivisible
+  String
+  (/ [s d] (/ (parse s) d)))
+
+(defprotocol IDivisibleDuration
   (divide-duration [divisor duration] "Divide a duration"))

-(extend-protocol IDivisbleDuration
+(extend-protocol IDivisibleDuration
   Long
   (divide-duration [n duration] (.dividedBy duration n))
   Duration
@@ -531,6 +523,14 @@
 (defprotocol ITimeSpan
   (beginning [_] "Return the beginning of a span of time")
   (end [_] "Return the end of a span of time"))
+
+(defprotocol ITimeBetween
+  (between [t1 t2] "Return the most appropriate type of value that
+  represents the gap between two times"))
+
+(extend-protocol ITimeBetween
+  Instant
+  (between [inst _] (throw (ex-info "TODO" {}))))

 (defn length
   "Return the distance between the beginning and end as a duration or


Make the Contact Sales button text white

--- src-cljs/frontend/components/license.cljs
+++ src-cljs/frontend/components/license.cljs
@@ -35,9 +35,9 @@
          (list
           " "
           description))])
-    [:a.contact-sales
+    [:a.contact-sales.btn
      {:href "mailto:enterprise@circleci.com"}
-     "Contact Sales…"])))
+     "Contact Sales"])))

 (defn- banner-for-license
   "Returns the banner for the given license, or nil if no banner applies."


ignore first line of vector model

ignore first line of vector model

--- src/neuseg/db.clj
+++ src/neuseg/db.clj
@@ -28,7 +28,7 @@
 (defn load-db [name]
   (with-open [rdr (clojure.java.io/reader (str "data" "/" name))]
     (map (partial reg-wd-neglect name)
-         (reduce enum-splited-line [] (line-seq rdr)))))
+         (reduce enum-splited-line [] (rest (line-seq rdr))))))

 (def unigram  (matrix (load-db "unigram")))
 (def bigram   (matrix (load-db "bigram")))


restore option parsing priority

restore option parsing priority

Signed-off-by: Eric Baur <a1c9c5f8609c68027db0779b39e5f932d4cb0053@robeybaur.org>

--- src/obcc/core.clj
+++ src/obcc/core.clj
@@ -44,14 +44,15 @@

 (defn -app [& args]
   (let [ {:keys [options arguments errors summary]} (parse-opts args cli-options) ]
-    (cond (not= errors nil)
-          (exit -1 "Error: " (string/join errors))
-
+    (cond
           (:help options)
           (exit 0 (usage summary))

           (:version options)
           (exit 0 (version))
+
+          (not= errors nil)
+          (exit -1 "Error: " (string/join errors))

           (= (count arguments) 0)
           (exit 0 (usage summary))


Revert to old submit behaviour

Revert to old submit behaviour

--- src/status_im/chat/views/input/input.cljs
+++ src/status_im/chat/views/input/input.cljs
@@ -32,7 +32,8 @@
        :on-focus               #(re-frame/dispatch [:set-chat-ui-props {:input-focused?    true
                                                                         :messages-focused? false}])
        :on-blur                #(re-frame/dispatch [:set-chat-ui-props {:input-focused? false}])
-       :on-submit-editing      #(re-frame/dispatch [:send-current-message])
+       :on-submit-editing      #(when single-line-input?
+                                  (re-frame/dispatch [:send-current-message]))
        :on-layout              #(set-container-width-fn (.-width (.-layout (.-nativeEvent %))))
        :on-change              #(re-frame/dispatch [:set-chat-input-text (.-text (.-nativeEvent %))])
        :on-selection-change    #(let [s (-> (.-nativeEvent %)


Inline maximum/minimum

Inline maximum/minimum

No longer required to be extensible, implementation always the same.

--- src/tick/core.clj
+++ src/tick/core.clj
@@ -312,9 +312,7 @@
   (< [x y] "Is x before y?")
   (<= [x y] "Is x before or at the same time as y?")
   (> [x y] "Is x after y?")
-  (>= [x y] "Is x after or at the same time as y?")
-  (maximum [_ _] "Return maximum")
-  (minimum [_ _] "Return minimum"))
+  (>= [x y] "Is x after or at the same time as y?"))

 (extend-protocol ITimeComparison
   Instant
@@ -322,69 +320,48 @@
   (<= [x y] (not (.isAfter x y)))
   (> [x y] (.isAfter x y))
   (>= [x y] (not (.isBefore x y)))
-  (maximum [x y] (if (neg? (compare x y)) y x))
-  (minimum [x y] (if (neg? (compare x y)) x y))

   LocalDateTime
   (< [x y] (.isBefore x y))
   (<= [x y] (not (.isAfter x y)))
   (> [x y] (.isAfter x y))
   (>= [x y] (not (.isBefore x y)))
-  ;; TODO: Rename maximum to 'greater' and minimum to 'lesser'
-  (maximum [x y] (if (neg? (compare x y)) y x))
-  (minimum [x y] (if (neg? (compare x y)) x y))

   LocalTime
   (< [x y] (.isBefore x y))
   (<= [x y] (not (.isAfter x y)))
   (> [x y] (.isAfter x y))
   (>= [x y] (not (.isBefore x y)))
-  (maximum [x y] (if (neg? (compare x y)) y x))
-  (minimum [x y] (if (neg? (compare x y)) x y))

   LocalDate
   (< [x y] (.isBefore x y))
   (<= [x y] (not (.isAfter x y)))
   (> [x y] (.isAfter x y))
   (>= [x y] (not (.isBefore x y)))
-  (maximum [x y] (if (neg? (compare x y)) y x))
-  (minimum [x y] (if (neg? (compare x y)) x y))

   OffsetDateTime
   (< [x y] (.isBefore x y))
   (<= [x y] (not (.isAfter x y)))
   (> [x y] (.isAfter x y))
   (>= [x y] (not (.isBefore x y)))
-  (maximum [x y] (if (neg? (compare x y)) y x))
-  (minimum [x y] (if (neg? (compare x y)) x y))

   ZonedDateTime
   (< [x y] (.isBefore x y))
   (<= [x y] (not (.isAfter x y)))
   (> [x y] (.isAfter x y))
   (>= [x y] (not (.isBefore x y)))
-  (maximum [x y] (if (neg? (compare x y)) y x))
-  (minimum [x y] (if (neg? (compare x y)) x y))

   YearMonth
   (< [x y] (.isBefore x y))
   (<= [x y] (not (.isAfter x y)))
   (> [x y] (.isAfter x y))
   (>= [x y] (not (.isBefore x y)))
-  (maximum [x y] (if (neg? (compare x y)) y x))
-  (minimum [x y] (if (neg? (compare x y)) x y))

   Year
   (< [x y] (.isBefore x y))
   (<= [x y] (not (.isAfter x y)))
   (> [x y] (.isAfter x y))
-  (>= [x y] (not (.isBefore x y)))
-  (maximum [x y] (if (neg? (compare x y)) y x))
-  (minimum [x y] (if (neg? (compare x y)) x y))
-
-  Duration
-  (maximum [x y] (if (neg? (compare x y)) y x))
-  (minimum [x y] (if (neg? (compare x y)) x y)))
+  (>= [x y] (not (.isBefore x y))))

 (defprotocol ITimeRangeable
   (range [_] [_ _] [_ _ _] "Returns a lazy seq of times from start (inclusive) to end (exclusive, nil means forever), by step, where start defaults to 0, step to 1, and end to infinity."))
@@ -404,11 +381,17 @@
   (inc [_] "Increment time")
   (dec [_] "Decrement time"))

+(defn greater [x y]
+  (if (neg? (compare x y)) y x))
+
 (defn max [arg & args]
-  (reduce #(maximum %1 %2) arg args))
+  (reduce #(greater %1 %2) arg args))
+
+(defn lesser [x y]
+  (if (neg? (compare x y)) x y))

 (defn min [arg & args]
-  (reduce #(minimum %1 %2) arg args))
+  (reduce #(lesser %1 %2) arg args))

 (extend-type Instant
   ITimeArithmetic


Create a core which carries the API

Create a core which carries the API

--- src/re_frame/core.cljs
+++ src/re_frame/core.cljs
@@ -1 +1,35 @@
-(ns re-frame.core)
+(ns re-frame.core
+  (:require
+            [re-frame.handlers   :as handlers]
+            [re-frame.subs       :as subs]
+            [re-frame.middleware :as  middleware]))
+
+
+;; --  API  -------
+
+(def register-handler handlers/register)
+(def dispatch         handlers/dispatch)
+(def dispatch-sync    handlers/dispatch-sync)
+
+(def register-subs subs/register)
+(def subscribe     subs/subscribe)
+
+
+
+(def pure        middleware/pure)
+(def undoable    middleware/undoable)
+(def path        middleware/path)
+(def validate    middleware/validate)
+(def log-events  middleware/log-events)
+(def apply-event middleware/apply-event)
+
+
+
+;; --  Convienience API  -------
+
+;; virtually ever handler will be pure, make it easy
+(defn register-pure-handler
+  ([id handler]
+    (register-handler id pure handler))
+  ([id middleware handler]
+    (register-handler id (comp pure middleware) handler)))


Improve comment

Improve comment

--- src/re_frame/undo.cljs
+++ src/re_frame/undo.cljs
@@ -128,10 +128,9 @@
     (recur (dec n))))

 (handlers/register-base     ;; not a pure handler
-  :undo                     ;; usage:  (dispatch [:undo n])
+  :undo                     ;; usage:  (dispatch [:undo n])  n is optional, defaults to 1
   (fn handler
     [_ [_ n]]
-    ;; if n absent, defaults to 1. If clear-redos? absent, defaults to false.
     (if-not (undos?)
       (warn "re-frame: you did a (dispatch [:undo]), but there is nothing to undo.")
       (undo-n (or n 1)))))


Setting dirty on on-set is not necessary any more

--- src/reagent/ratom.cljs
+++ src/reagent/ratom.cljs
@@ -283,7 +283,6 @@
     (let [oldval state]
       (set! state newval)
       (when (some? on-set)
-        (set! dirtyness dirty)
         (on-set oldval newval))
       (-notify-watches a oldval newval)
       newval))


handle non-Throwable error types

handle non-Throwable error types

--- src/yada/core.clj
+++ src/yada/core.clj
@@ -462,10 +462,18 @@
                                              :duration (- t1 t0)})
              output)))))))

+(defn error-data
+  [e]
+  (cond
+    (instance? clojure.lang.ExceptionInfo e) (ex-data e)
+    (instance? java.lang.Throwable e) nil
+    :else e))
+
 (defn default-error-handler [e]
-  (let [data (ex-data e)]
+  (let [data (error-data e)]
     (when-not (and (:status data) (< (:status data) 500))
-      (errorf e "Internal Error %s" (or (:status data) ""))
+      (when (instance? java.lang.Throwable e)
+        (errorf e "Internal Error %" (or (some-> data :status str) "")))
       (when data (errorf "ex-data: %s" data)))))

 (defn- handle-request
@@ -498,9 +506,10 @@

      ;; Handle non-local exits
      (d/catch
+         java.lang.Object
          (fn [e]
            (error-handler e)
-           (let [data (when (instance? clojure.lang.ExceptionInfo e) (ex-data e))]
+           (let [data (error-data e)]
              (do
                (when-let [journal (:journal handler)]
                  (swap! journal assoc id (swap! journal-entry assoc :error {:exception e :data data})))


Remove unnecessary core.async code

Remove unnecessary core.async code

--- src/yada/util.clj
+++ src/yada/util.clj
@@ -8,29 +8,11 @@
    [clojure.tools.logging :refer :all]
    [byte-streams :as bs]
    [manifold.deferred :as d]
-   [manifold.stream :as s]
-   clojure.core.async.impl.protocols)
+   [manifold.stream :as s])
   (:import
-   [clojure.core.async.impl.protocols ReadPort]
    [java.nio ByteBuffer]
    (java.util Map$Entry)
    (clojure.lang IPersistentVector)))
-
-;; Old comment :-
-;; If this is something we can take from, in the core.async
-;; sense, then call body again. We need this clause here
-;; because: (satisfies? d/Deferrable (a/chan)) => true, so
-;; (deferrable?  (a/chan) is (consequently) true too.
-
-(defn deferrable?
-  "An alternative version of deferrable that discounts
-  ReadPort. Otherwise, core.async channels are considered as streams
-  rather than values, which isn't what we want."
-  [o]
-  (and o
-       (not (instance? ReadPort o))
-       (d/deferrable? o)))
-

 ;; ------------------------------------------------------------------------
 ;; XML Parsing Transducers
@@ -266,4 +248,3 @@
   (let [^java.lang.reflect.Method m (first (.getDeclaredMethods (class f)))
         p (.getParameterTypes m)]
     (alength p)))
-


Respond with the created item on create

Respond with the created item on create

--- src/scavenger/core.clj
+++ src/scavenger/core.clj
@@ -16,9 +16,11 @@
   (GET "/items" []
     (response (str (into [] (get-all-items)))))
   (POST "/items" {body :body}
-    (let [data (merge (read-string (slurp body)) {:db/id (d/tempid :items)})]
-      @(d/transact conn [data]))
-    "OK")
+    (let [tempid (d/tempid :items)
+          data (merge (read-string (slurp body)) {:db/id tempid})
+          tx @(d/transact conn [data])
+          id (d/resolve-tempid (db conn) (:tempids tx) tempid)]
+      (response (str (d/touch (d/entity (db conn) id))))))
   (route/not-found "Page not found"))

 (def app


refactored utils

refactored utils

--- src/ui/utils.cljs
+++ src/ui/utils.cljs
@@ -5,14 +5,9 @@
             [om-i.core :as omi])
   (:import [goog.ui IdGenerator]))

-(enable-console-print!)
-(def debug true)
-
 (def host "http://127.0.0.1:3449/")

 (defonce base-url (str js/window.location.origin "/"))
-
-;; Logging

 (defn log
   "log messages if the browser console is open"
@@ -26,24 +21,20 @@
     (log (apply pr-str values))
     (last values))

-;; Interop
-
 (defn $ [id]
   (.getElementById js/document id))

 (defn to-clj [data]
   (js->clj data :keywordize-keys true))

-;; String
-
 (defn format
   "Format a string using goog.string.format"
   [fmt & args]
   (apply goog.string/format fmt args))

-;; Stuff
-
-(defn guid []
+(defn guid
+  "Generate a Guid"
+  []
   (-> IdGenerator
       .getInstance
       .getNextUniqueId))
@@ -59,13 +50,9 @@
                        (take 3 (drop 15 r)) ["-"]
                        (take 12 (drop 18 r))))))

-
-
-;; Om Instrumentation
-
 (defn with-omi []
+  "Adds Om Instrumentation (dev mode)"
   (fn [f cursor m]
     (om/build* f cursor
                (assoc m
                       :descriptor omi/instrumentation-methods))))
-


Adding routes test cases

Adding routes test cases

--- test/vignette/http/routes_test.clj
+++ test/vignette/http/routes_test.clj
@@ -90,6 +90,10 @@
     (provided
      (u/get-or-generate-thumbnail ..wiki-store.. route-params) => (ls/create-stored-object (io/file "image-samples/ropes.jpg")))

+    (:headers ((create-routes (image-routes {:wikia-store ..wiki-store.. :static-store ..static-store..})) (request :get "/lotr/3/35/ropes.jpg/revision/latest/thumbnail/width/10/height/10"))) => (contains {"Content-Type" "image/jpeg"})
+    (provided
+      (u/get-or-generate-thumbnail ..wiki-store.. route-params) => (ls/create-stored-object (io/file "image-samples/ropes.jpg")))
+
     ((create-routes (image-routes {:wikia-store ..wiki-store.. :static-store ..static-store..})) (request :get "/lotr/3/35/ropes.jpg/revision/latest/thumbnail/width/10/height/10")) => (contains {:status 404})
     (provided
      (u/get-or-generate-thumbnail ..wiki-store.. route-params) => nil
@@ -100,6 +104,23 @@
     (provided
       (u/get-or-generate-thumbnail ..wiki-store.. route-params) =throws=> (NullPointerException.))))

+(facts :all-routes-thumbnail-webp
+       (let [route-params {:request-type :thumbnail
+                           :image-type "images"
+                           :original "ropes.jpg"
+                           :revision "latest"
+                           :middle-dir "35"
+                           :top-dir "3"
+                           :wikia "lotr"
+                           :thumbnail-mode "thumbnail"
+                           :height "10"
+                           :width "10"
+                           :requested-format nil
+                           :options {:format "webp"}}]
+         ((create-routes (image-routes {:wikia-store ..wiki-store.. :static-store ..static-store..})) (assoc-in (request :get "/lotr/3/35/ropes.jpg/revision/latest/thumbnail/width/10/height/10") [:headers "accept"] "image/webp")) => (contains {:status 200})
+         (provided
+           (u/get-or-generate-thumbnail ..wiki-store.. route-params) => (ls/create-stored-object (io/file "image-samples/ropes.jpg"))
+           )))

 (facts :all-routes-original
   (let [route-params {:request-type :original


SER-2525 | add missing dependency

SER-2525 | add missing dependency

--- test/vignette/http/routes_test.clj
+++ test/vignette/http/routes_test.clj
@@ -16,7 +16,8 @@
             [vignette.setup :refer [image-routes]]
             [vignette.http.legacy.routes :as hlr]
             [vignette.media-types :as mt]
-            [vignette.util.regex :refer :all]))
+            [vignette.util.regex :refer :all]
+            [vignette.perfmonitoring.core :refer :all]))

 (def in-wiki-context-route-matches (partial context-route-matches ["/:wikia:image-type/:top-dir/:middle-dir/:original/revision/:revision"
                                                                    :wikia wikia-regex


reverse the order of args in use-reducer, resolves #213

--- src/rum/core.cljs
+++ src/rum/core.cljs
@@ -482,9 +482,9 @@
   "Takes reducing function and initial state value.
   Returns a tuple of [value dispatch!], where `value` is current state value and `dispatch` is a function that schedules re-render.

-  (defmulti value-reducer (fn [event value] event))
-
-  (defmethod value-reducer :inc [_ value]
+  (defmulti value-reducer (fn [value event] event))
+
+  (defmethod value-reducer :inc [value _]
     (inc value))

   (let [[value dispatch!] (rum/use-reducer value-reducer 0)]
@@ -493,7 +493,7 @@

   Read more at https://reactjs.org/docs/hooks-reference.html#usereducer"
   ([reducer-fn initial-value]
-   (.useReducer js/React #(reducer-fn %2 %1) initial-value identity)))
+   (.useReducer js/React #(reducer-fn %1 %2) initial-value identity)))

 (defn use-effect!
   "Takes setup-fn that executes either on the first render or after every update.


get-or-create-defaults rather than destructuring the arg

--- src/shale/sessions.clj
+++ src/shale/sessions.clj
@@ -253,45 +253,34 @@
    (s/optional-key :extra-desired-capabilities) Capabilities
    (s/optional-key :force-create)               s/Bool})

-(defn get-or-create-session
-  [{:keys [browser-name
-           node
-           reserved
-           tags
-           extra-desired-capabilities
-           reserve-after-create
-           force-create
-           current-url]
-    :or {browser-name "firefox"
-         node nil
-         reserved false
-         tags []
-         extra-desired-capabilities nil
-         reserve-after-create nil
-         force-create nil
-         current-url nil}
-    :as arg}]
-  (s/validate OldGetOrCreateArg arg)
-  (with-car*
-    (car/return
-      (or
-        (if force-create
-          (create-session
-            (rename-keys arg
-                         {:reserve-after-create :reserved})))
-        (if-let [candidate (->> (view-models)
-                                (filter #(matches-requirements % (dissoc arg :reserve-after-create)))
-                                first)]
-          (if (or reserve-after-create current-url)
-            (modify-session (get candidate :id)
-                            (rename-keys
-                              (select-keys arg
-                                           [:reserve-after-create
-                                            :current-url
-                                            :tags])
-                              {:reserve-after-create :reserved}))
-            candidate))
-        (create-session arg)))))
+(def get-or-create-defaults
+  {:browser-name "firefox"
+   :tags []
+   :reserved false})
+(s/validate OldGetOrCreateArg get-or-create-defaults)
+
+(defn get-or-create-session [arg]
+  (let [arg (s/validate OldGetOrCreateArg (merge get-or-create-defaults arg))]
+    (with-car*
+      (car/return
+        (or
+          (if (arg :force-create)
+            (create-session
+              (rename-keys arg
+                           {:reserve-after-create :reserved})))
+          (if-let [candidate (->> (view-models)
+                                  (filter #(matches-requirements % (dissoc arg :reserve-after-create)))
+                                  first)]
+            (if (or (arg :reserve-after-create) (arg :current-url))
+              (modify-session (get candidate :id)
+                              (rename-keys
+                                (select-keys arg
+                                             [:reserve-after-create
+                                              :current-url
+                                              :tags])
+                                {:reserve-after-create :reserved}))
+              candidate))
+          (create-session arg))))))

 (defn resume-webdriver-from-id [session-id]
   (if-let [model (view-model session-id)]


Removed hard tabs from source file.

Removed hard tabs from source file.

--- src/appengine_magic/leiningen_helpers.clj
+++ src/appengine_magic/leiningen_helpers.clj
@@ -11,9 +11,9 @@
         appengine-sdk (cond
                        ;; not given
                        (nil? appengine-sdk)
-		       (if-let [from-env (System/getenv "APPENGINE_HOME")]
-			 from-env
-			 (lein/abort (str task-name "no App Engine SDK specified: set :appengine-sdk in project.clj, or APPENGINE_HOME in the environment")))
+                       (if-let [from-env (System/getenv "APPENGINE_HOME")]
+                           from-env
+                           (lein/abort (str task-name "no App Engine SDK specified: set :appengine-sdk in project.clj, or APPENGINE_HOME in the environment")))
                        ;; a string
                        (string? appengine-sdk)
                        appengine-sdk


only mount the Open a PR button when the build has loaded (#1597)

--- src-cljs/frontend/components/pages/build.cljs
+++ src-cljs/frontend/components/pages/build.cljs
@@ -125,7 +125,8 @@
                   :title             "cancel this build"
                   :on-click #(raise! owner [:cancel-build-clicked (build-model/build-args build)])}
                  [:i.material-icons "cancel"]])))
-           (when (feature/enabled? :open-pull-request)
+           (when (and (feature/enabled? :open-pull-request)
+                      (not-empty build))
              (om/build open-pull-request-action {:build build}))
            (when can-trigger-builds?
              (om/build rebuild-actions {:build build :project project}))


Updated comments in server module

Updated comments in server module

--- src/zg/server.clj
+++ src/zg/server.clj
@@ -7,14 +7,16 @@
 ;  http://www.eclipse.org/legal/epl-v10.html
 ;
 ;  Contributors:
-;      Pavel Tisnovsky
-;
-
-(ns zg.server)
+;      Pavel Tisnovsky
+;
+
+(ns zg.server
+    "Server module with functions to accept requests and send response back to users via HTTP.")

 (require '[ring.util.response     :as http-response])
 (require '[clojure.data.json      :as json])
 (require '[clojure.xml            :as xml])
+(require '[clojure.data.csv       :as csv])

 (require '[zg.db-interface        :as db-interface])
 (require '[zg.html-renderer       :as html-renderer])


A few changes to the Readers datatypes, added InputStreamReader, moved some functions

--- src/blind/reader.clj
+++ src/blind/reader.clj
@@ -5,100 +5,153 @@
   (:import (clojure.lang BigInt Numbers PersistentHashMap PersistentHashSet IMeta ISeq
                          RT IReference Symbol IPersistentList Reflector Var Symbol Keyword IObj
                          PersistentVector IPersistentCollection IRecord Namespace)
+           java.io.InputStream
            (java.util ArrayList regex.Pattern regex.Matcher)
            java.lang.reflect.Constructor))

+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; utils
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
 (defmacro ^:private update! [what f]
-          (list 'set! what (list f what)))
+  (list 'set! what (list f what)))

 (defn- char [x]
   (try (clojure.core/char x)
        (catch NullPointerException e)))

-(defprotocol PushbackReader
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; reader protocols
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defprotocol Reader
   (read-char [reader] "Returns the next char from the Reader, nil if the end of stream has been reached")
-  (peek-char [reader] "Same as (let [c (read-char rdr)] (unread rdr c) c) but without the overhead of unread")
+  (peek-char [reader] "Returns the next char from the Reader without removing it from the reader stream"))
+
+(defprotocol IPushbackReader
   (unread [reader ch] "Push back a single character on to the stream"))

-(deftype StringPushbackReader
-    [^:unsynchronized-mutable ^String s s-len ^:unsynchronized-mutable s-pos
-     ^objects buf buf-len ^:unsynchronized-mutable buf-pos]
-  PushbackReader
+(defprotocol IndexingReader
+  (get-line-number [reader])
+  (get-column-number [reader]))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; reader deftypes
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(deftype StringReader
+    [^String s s-len ^:unsynchronized-mutable s-pos]
+  Reader
+  (read-char [reader]
+    (when (> s-len s-pos)
+      (let [r (.charAt s s-pos)]
+        (update! s-pos inc)
+        r)))
+  (peek-char [reader]
+    (when (> s-len s-pos)
+      (.charAt s s-pos))))
+
+(deftype InputStreamReader [^InputStream is ^:unsynchronized-mutable ^bytes buf]
+  Reader
+  (read-char [reader]
+    (if buf
+      (let [c (aget buf 0)]
+        (set! buf nil)
+        (char c))
+      (let [c (.read is)]
+        (when-not (== c -1)
+          (char c)))))
+  (peek-char [reader]
+    (when-not buf
+      (set! buf (byte-array 1))
+      (when (== -1 (.read is buf))
+        (set! buf nil)))
+    (when buf
+      (char (aget buf 0)))))
+
+(deftype PushbackReader
+    [rdr ^objects buf buf-len ^:unsynchronized-mutable buf-pos]
+  Reader
   (read-char [reader]
     (if (< buf-pos buf-len)
       (let [r (aget buf buf-pos)]
         (update! buf-pos inc)
         r)
-      (when (> s-len s-pos)
-        (let [r (.charAt s s-pos)]
-          (update! s-pos inc)
-          r))))
+      (read-char rdr)))
   (peek-char [reader]
     (if (< buf-pos buf-len)
       (aget buf buf-pos)
-      (when (> s-len s-pos)
-        (.charAt s s-pos))))
+      (peek-char rdr)))
+  IPushbackReader
   (unread [reader ch]
     (when ch
       (if (zero? buf-pos) (throw (RuntimeException. "Pushback buffer is full")))
       (update! buf-pos dec)
       (aset buf buf-pos ch))))

+(declare newline?)
+
+(deftype IndexingPushbackReader
+    [rdr ^:unsynchronized-mutable line ^:unsynchronized-mutable column
+     ^:unsynchronized-mutable line-start? ^:unsynchronized-mutable prev]
+  Reader
+  (read-char [reader]
+    (when-let [ch (char (read-char rdr))]
+      (let [ch (if (identical? \return ch)
+                 (let [c (char (peek-char rdr))]
+                   (when (identical? \formfeed c)
+                     (read-char rdr))
+                   \newline)
+                 ch)]
+        (set! prev line-start?)
+        (set! line-start? (newline? ch))
+        (when line-start?
+          (set! column 0)
+          (update! line inc))
+        (update! column inc)
+        ch)))
+
+  (peek-char [reader]
+    (peek-char rdr))
+
+  IPushbackReader
+  (unread [reader ch]
+    (when line-start? (update! line dec))
+    (set! line-start? prev)
+    (update! column dec)
+    (unread rdr ch))
+
+  IndexingReader
+  (get-line-number [reader] (inc line))
+  (get-column-number [reader]  column))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; constructors
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defn string-reader
+  "Creates a StringReader from a given string"
+  ([^String s]
+     (StringReader. s (.length s) 0)))
+
 (defn string-push-back-reader
   "Creates a StringPushbackReader from a given string"
   ([s]
      (string-push-back-reader s 1))
   ([^String s buf-len]
-     (StringPushbackReader. s (.length s) 0 (object-array buf-len) buf-len buf-len)))
-
-(defprotocol IndexingReader
-  (get-line-number [reader])
-  (get-column-number [reader]))
-
-(defn read-line [rdr]
-  (loop [c (char (read-char rdr)) s (StringBuilder.)]
-    (if (or (identical? \newline c)
-            (nil? c))
-      (.toString s)
-      (recur (char (read-char rdr)) (.append s c)))))
-
-(deftype IndexingPushbackReader
-    [^StringPushbackReader spr ^:unsynchronized-mutable line ^:unsynchronized-mutable column
-     ^:unsynchronized-mutable line-start? ^:unsynchronized-mutable prev]
-  PushbackReader
-  (read-char [reader]
-    (when-let [ch (read-char spr)]
-      (let [ch (if (= \return ch)
-                 (let [c (peek-char spr)]
-                   (when (= \formfeed c)
-                     (read-char spr))
-                   \newline)
-                 ch)]
-        (set! prev line-start?)
-        (set! line-start? (= ch \newline))
-        (when line-start?
-          (set! column 0)
-          (update! line inc))
-        (update! column inc)
-        ch)))
-
-  (peek-char [reader]
-    (peek-char spr))
-
-  (unread [reader ch]
-    (when line-start? (update! line dec))
-    (set! line-start? prev)
-    (update! column dec)
-    (unread spr ch))
-
-  IndexingReader
-  (get-line-number [reader] (inc line))
-  (get-column-number [reader]  column))
+     (PushbackReader. (string-reader s) (object-array buf-len) buf-len buf-len)))
+
+(defn input-stream-reader
+  "Creates an InputStreamReader from an InputString"
+  [is]
+  (InputStreamReader. is nil))

 (defn indexing-push-back-reader
-  "Creates an IndexingPushBackReader from a given string"
-  ([s] (IndexingPushbackReader. (string-push-back-reader s) 0 1 true nil))
-  ([s buf-len] (IndexingPushbackReader. (string-push-back-reader s buf-len) 0 1 true nil)))
+  "Creates an IndexingPushbackReader from a given string"
+  ([s]
+     (IndexingPushbackReader. (string-push-back-reader s) 0 1 true nil))
+  ([s buf-len]
+     (IndexingPushbackReader. (string-push-back-reader s buf-len) 0 1 true nil)))

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; predicates
@@ -130,18 +183,24 @@
         (and (or (identical? \+ c) (identical?  \- c))
              (numeric? (peek-char reader))))))

+(defn newline? [c]
+  "Checks whether the character is a newline"
+  (let [c (char c)]
+    (or (identical? \newline c)
+        (nil? c))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; read helpers
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
 (declare read macros dispatch-macros)
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; read helpers
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

 (defn reader-error
   "Throws an Exception info, if rdr is an IndexingReader, additional information about column and line number is provided"
   [rdr & msg]
   (throw (ex-info (apply str msg)
                   (merge {:type :reader-exception}
-                         (if (instance? IndexingPushbackReader rdr)
+                         (if (instance? blind.reader.IndexingReader rdr)
                            {:line (get-line-number rdr)
                             :column (get-column-number rdr)})))))

@@ -173,10 +232,19 @@
       (recur (read-char rdr))
       ch)))

+(defn read-line [rdr]
+  "Reads a line from the reader"
+  (loop [c (char (read-char rdr)) s (StringBuilder.)]
+    (if (newline? c)
+      (.toString s)
+      (recur (char (read-char rdr)) (.append s c)))))
+
 (defn skip-line
   "Advances the reader to the end of a line. Returns the reader"
   [reader _]
-  (read-line reader)
+  (loop []
+    (when-not (newline? (read-char reader))
+      (recur)))
   reader)

 (def ^Pattern int-pattern #"([-+]?)(?:(0)|([1-9][0-9]*)|0[xX]([0-9A-Fa-f]+)|0([0-7]+)|([1-9][0-9]?)[rR]([0-9A-Za-z]+)|0[0-9]+)(N)?")
@@ -224,9 +292,39 @@
     (.contains s ".") (match-float s (doto (.matcher float-pattern s) .matches))
     :else (match-int s (doto (.matcher int-pattern s) .matches))))

-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; unicode
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+(defn- parse-symbol [^String token]
+  (when (not (= "" token))
+    (let [ns-idx (.indexOf token "/")
+          ns (if-not (== -1 ns-idx) (.substring token 0 ns-idx))]
+      (if (nil? ns)
+        [nil token]
+        (when-not (== (inc ns-idx) (count token))
+          (let [sym (.substring token (inc ns-idx))]
+            (when (and (not (numeric? (.charAt sym 0)))
+                       (not (= "" sym))
+                       (or (= sym "/")
+                           (== -1 (.indexOf sym "/"))))
+              [ns sym])))))))
+
+(defn read-dispatch
+  [rdr _]
+  (if-let [ch (read-char rdr)]
+    (if-let [dm (dispatch-macros ch)]
+      (dm rdr ch)
+      (if-let [obj (read-tagged (doto rdr (unread ch)) ch)] ;; ctor reader is implemented as a taggged literal
+        obj
+        (reader-error rdr "No dispatch macro for " ch)))
+    (reader-error rdr "EOF while reading character")))
+
+(defn read-unmatched-delimiter
+  [rdr ch]
+  (reader-error rdr "Unmatched delimiter " ch))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; readers
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(def read-comment skip-line)

 (defn read-unicode-char
   ([^String token offset length base]
@@ -301,9 +399,11 @@
           :else (reader-error rdr "Unsupported character: \\" token)))
       (reader-error rdr "EOF while reading character"))))

+(declare read-tagged)
+
 (defn ^PersistentVector read-delimited-list
   [delim rdr recursive?]
-  (let [first-line  (when (instance? IndexingPushbackReader rdr)
+  (let [first-line  (when (instance? blind.reader.IndexingReader rdr)
                       (get-line-number rdr))
         delim ^char delim]
     (loop [a (transient [])]
@@ -322,29 +422,9 @@
               (let [o (read rdr true nil recursive?)]
                 (recur (if-not (identical? o rdr) (conj! a o) a))))))))))

-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; data structure readers
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-(declare read-tagged)
-
-(defn read-dispatch
-  [rdr _]
-  (if-let [ch (read-char rdr)]
-    (if-let [dm (dispatch-macros ch)]
-      (dm rdr ch)
-      (if-let [obj (read-tagged (doto rdr (unread ch)) ch)] ;; ctor reader is implemented as a taggged literal
-        obj
-        (reader-error rdr "No dispatch macro for " ch)))
-    (reader-error rdr "EOF while reading character")))
-
-(defn read-unmatched-delimiter
-  [rdr ch]
-  (reader-error rdr "Unmatched delimiter " ch))
-
 (defn read-list
   [rdr _]
-  (let [[line column] (when (instance? IndexingPushbackReader rdr)
+  (let [[line column] (when (instance? blind.reader.IndexingReader rdr)
                         [(get-line-number rdr) (dec (get-column-number rdr))])
         the-list (read-delimited-list \) rdr true)]
     (if (empty? the-list)
@@ -352,8 +432,6 @@
       (if-not line
         (clojure.lang.PersistentList/create the-list)
         (with-meta (clojure.lang.PersistentList/create the-list) {:line line :column column})))))
-
-(def read-comment skip-line)

 (defn read-vector
   [rdr _]
@@ -411,20 +489,6 @@
       \" (.toString sb)
       (recur (doto sb (.append ch)) (char (read-char reader))))))

-(defn- parse-symbol [^String token]
-  (when (not (= "" token))
-    (let [ns-idx (.indexOf token "/")
-          ns (if-not (== -1 ns-idx) (.substring token 0 ns-idx))]
-      (if (nil? ns)
-        [nil token]
-        (when-not (== (inc ns-idx) (count token))
-          (let [sym (.substring token (inc ns-idx))]
-            (when (and (not (numeric? (.charAt sym 0)))
-                       (not (= "" sym))
-                       (or (= sym "/")
-                           (== -1 (.indexOf sym "/"))))
-              [ns sym])))))))
-
 (defn read-symbol
   [rdr initch]
   (when-let [token (read-token rdr initch)]
@@ -441,7 +505,7 @@

       (or (when-let [p (parse-symbol token)]
             (symbol (p 0) (p 1)))
-          (reader-error rdr "Invalid token:" token)))))
+          (reader-error rdr "Invalid token: " token)))))

 (defn- resolve-ns [sym]
   (or ((ns-aliases *ns*) sym)
@@ -487,7 +551,7 @@

 (defn read-meta
   [rdr _]
-  (let [[line column] (when (instance? IndexingPushbackReader rdr)
+  (let [[line column] (when (instance? blind.reader.IndexingReader rdr)
                         [(get-line-number rdr) (dec (get-column-number rdr))])
         m (desugar-meta (read rdr true nil true))]
     (when-not (map? m)
@@ -791,7 +855,7 @@
       nil)))

 (defn read
-  "Reads the first object from a PushbackReader. Returns the object read.
+  "Reads the first object from a IPushbackReader. Returns the object read.
    If EOF, throws if eof-is-error is true. Otherwise returns sentinel."
   [reader eof-is-error sentinel is-recursive]
   (try
@@ -813,7 +877,7 @@
         (throw e)
         (throw (ex-info (.getCause e)
                         (merge {:type :reader-exception}
-                               (if (instance? IndexingPushbackReader reader)
+                               (if (instance? blind.reader.IndexingReader reader)
                                  {:line (get-line-number reader)
                                   :column (get-column-number reader)}))
                         e))))))


Fixed memory leak in resilient_decoder   * Remove key from unpaired_frags once fragment set is complete.

--- src/ais/resilient_decoder.clj
+++ src/ais/resilient_decoder.clj
@@ -118,13 +118,16 @@
       acc)))

 (defn assemble-multipart [frag-groups]
+  ;; Return complete multipart message if possible, sorted by fragment number
   (if (= 1 (count frag-groups))
     (let [frags (first (vals frag-groups))]
       (if (and (not-any? nil? frags)
                (= (ais-ex/parse "frag-count" (first frags)) (count frags)))
         (sort-by (partial ais-ex/parse "frag-num") frags)))))

-(defn find-match! [frag-groups unpaired-frags]
+(defn find-matches! [frag-groups unpaired-frags]
+  ;; For input (frag-group-key, [frag-1 .. frag-n]) tuple, look up remaining group members
+  ;; in unpaired frags.  If set complete, sort fragments and add to result set.
   (loop [pairs (seq frag-groups)
          result []]
     (if-let [[grp-k frags] (first pairs)]
@@ -132,7 +135,9 @@
         (let [n (ais-ex/parse "frag-count" (first unpaired-ret))]
           ;; |frags| + |unpaired-ret| == n --> complete fragment set
           (if (= (+ (count unpaired-ret) (count frags)) n)
-            (recur (rest pairs) (conj result (sort-by (partial ais-ex/parse "frag-num") (concat frags unpaired-ret))))
+            (do
+              (swap! unpaired-frags dissoc grp-k) ; fragment set complete, remove key
+              (recur (rest pairs) (conj result (sort-by (partial ais-ex/parse "frag-num") (concat frags unpaired-ret)))))
             (do
               (swap! unpaired-frags update grp-k concat frags)
               (recur (rest pairs) result))))
@@ -144,9 +149,7 @@
 (defn send-multipart [frag-groups unpaired-frags out-ch]
   (if-let [frag-set (assemble-multipart frag-groups)]
     (async/>!! out-ch frag-set)
-    ;; foreach frag key, search for matching frags in unpaired-frags.  If match completes set,
-    ;; send, otherwise persist
-    (doseq [match (find-match! frag-groups unpaired-frags)]
+    (doseq [match (find-matches! frag-groups unpaired-frags)]
       (async/>!! out-ch match))))

 (defn passthru? [supported-types m]


[Fix] main using *sign-reverse*

[Fix] main using *sign-reverse*

--- src/clj_elm/core.clj
+++ src/clj_elm/core.clj
@@ -241,19 +241,20 @@
 (defn -main [& args]
   {:pre [(string? (first args))]}
   (p :main
-     (if (= (count args) 8)
-       (let [[datap1 classidx1 header1 datap2 classidx2 header2 L n-of-cv] args]
-         (printfl "Start exp\n")
-         (def dataset (atom (read-dataset datap1 (read-string classidx1) :header (read-string header1))))
-         (printfl (str "Fin read-data " datap1 "\n"))
-         (def datasets (atom (read-dataset datap2 (read-string classidx2) :header (read-string header2))))
-         (printfl (str "Fin read-data " datap1 "\n"))
-         (reset! dataset (data/concat-dataset @dataset @datasets))
-         (printfl "Fin data concat\n")
-         (reset! dataset (data/shuffle-dataset @dataset))
-         (printfl "Fin data shuffle\n")
-         (let [result (cross-validate @dataset (read-string L) (read-string n-of-cv))]
-           (printfl "Final result:\n")
-           (print-exp-data result)
-           (flush))
-         (System/exit 0)))))
+     (if (= (count args) 9)
+       (let [[datap1 classidx1 header1 datap2 classidx2 header2 L n-of-cv sign-m] args]
+         (binding [*sign-reverse* sign-m]
+           (printfl "Start exp\n")
+           (def dataset (atom (read-dataset datap1 (read-string classidx1) :header (read-string header1))))
+           (printfl (str "Fin read-data " datap1 "\n"))
+           (def datasets (atom (read-dataset datap2 (read-string classidx2) :header (read-string header2))))
+           (printfl (str "Fin read-data " datap1 "\n"))
+           (reset! dataset (data/concat-dataset @dataset @datasets))
+           (printfl "Fin data concat\n")
+           (reset! dataset (data/shuffle-dataset @dataset))
+           (printfl "Fin data shuffle\n")
+           (let [result (cross-validate @dataset (read-string L) (read-string n-of-cv))]
+             (printfl "Final result:\n")
+             (print-exp-data result)
+             (flush))
+           (System/exit 0))))))


Emit Neu in Braille with new heading hierarchy

--- src/catalog/layout/dtbook.clj
+++ src/catalog/layout/dtbook.clj
@@ -95,8 +95,18 @@
     [:bodymatter
      [:level1 [:h1 "Editorial"] [:p "..."]]
      [:level1 [:h1 "Buchtipps"] [:p "..."]]
-     [:level1 [:h1 "Neue Braillebücher"]
-      (for [genre layout/braille-genres] (genre-entries genre items))]]]])
+     (when-let [items (not-empty
+                       (select-keys
+                        items
+                        [:belletristik :kinder-und-jugendbücher :sachbücher]))]
+       [:level1 [:h1 "Neue Braillebücher"]
+        (for [genre layout/braille-genres] (genre-entries genre items))])
+     (when-let [items (not-empty (:musiknoten items))]
+       [:level1 [:h1 "Neue Braille-Musiknoten"]
+        (catalog-entries items)])
+     (when-let [items (not-empty (:taktilesbuch items))]
+       [:level1 [:h1 "Neue Taktile Bücher"]
+        (catalog-entries items)])]]])

 (defn dtbook
   [items]


openstack swagger model

openstack swagger model

--- src/celestial/api/systems.clj
+++ src/celestial/api/systems.clj
@@ -37,6 +37,7 @@
   :machine {:type "Machine"}
   :aws {:type "Aws" :description "An EC2 based system"}
   :physical {:type "Physical" :description "A physical machine"}
+  :openstack {:type "Openstack" :description "An openstack based instance"}
   :proxmox {:type "Proxmox" :description "A Proxmox based system"}
   :vcenter {:type "Vcenter" :description "A vCenter based system"})

@@ -54,6 +55,10 @@
 (defmodel physical :mac :string)

 (defmodel aws :instance-type :string :key-name :string :endpoint :string)
+
+(defmodel openstack
+  :flavor :string :key-name :string :tenant :string
+  :security-groups {:type "List"} :networks {:type "List"})

 (defmodel vcenter :pool :string :datacenter :string :hostsystem :string :disk-format :string)


fix `cljs.analyzer.api/all-ns` docstring

--- src/clj/cljs/analyzer/api.clj
+++ src/clj/cljs/analyzer/api.clj
@@ -23,8 +23,8 @@
     (catch Exception e)))

 (defn all-ns
-  "Return all the namespace analysis maps. Analagous to clojure.core/all-ns but
-  returns analysis maps not Namespace instances."
+  "Return all namespaces. Analagous to clojure.core/all-ns but
+  returns symbols identifying namespaces not Namespace instances."
   []
   (keys (get @env/*compiler* ::ana/namespaces)))


Let Museum of History use one prompt to shuffle up to N cards into R&D.

--- src/clj/game/cards-assets.clj
+++ src/clj/game/cards-assets.clj
@@ -413,14 +413,26 @@

    "Museum of History"
    {:flags {:corp-phase-12 (req (pos? (count (get-in @state [:corp :discard]))))}
-    :abilities [{:label "Shuffle a card in Archives into R&D"
-                 :prompt "Choose a card in Archives to shuffle into R&D"
-                 :choices {:req #(and (card-is? % :side :corp) (= (:zone %) [:discard]))}
-                 :show-discard true :priority true
-                 :msg (msg "to shuffle " (if (:seen target) (:title target) "a card")
+    :abilities [{:label "Shuffle cards in Archives into R&D"
+                 :prompt (msg (let [mus (count (filter #(= "10019" (:code %)) (all-installed state :corp)))]
+                                (str "Choose " (if (< 1 mus) (str mus " cards") "a card")
+                                     " in Archives to shuffle into R&D")))
+                 :choices {:req #(and (card-is? % :side :corp) (= (:zone %) [:discard]))
+                           :max (req (count (filter #(= "10019" (:code %)) (all-installed state :corp))))}
+                 :show-discard true
+                 :priority 1
+                 :once :per-turn
+                 :once-key :museum-of-history
+                 :msg (msg "shuffle "
+                           (let [seen (filter :seen targets)]
+                             (str (join ", " (map :title seen))
+                                  (let [n (count (filter #(not (:seen %)) targets))]
+                                    (when (pos? n)
+                                      (str (when-not (empty? seen) " and ") n " card"
+                                           (when (> n 1) "s"))))))
                            " into R&D")
-                 :effect (effect (move :corp target :deck)
-                                 (shuffle! :corp :deck))}]}
+                 :effect (req (doseq [c targets] (move state side c :deck))
+                              (shuffle! state side :deck))}]}

    "Net Police"
    {:recurring (effect (set-prop card :rec-counter (:link runner)))


adding configuration for the thread pool

--- src/clj/http/async/client.clj
+++ src/clj/http/async/client.clj
@@ -49,7 +49,8 @@
              realm
              request-timeout
              user-agent
-             async-connect]}]
+             async-connect
+             executor-service]}]
   (AsyncHttpClient.
    (.build
     (let [b (AsyncHttpClientConfig$Builder.)]
@@ -68,6 +69,7 @@
                                 (.removeProperty NettyAsyncHttpProviderConfig/USE_BLOCKING_IO)
                                 (.addProperty NettyAsyncHttpProviderConfig/EXECUTE_ASYNC_CONNECT true))]
           (.setAsyncHttpClientProviderConfig b provider-config)))
+      (when executor-service (.setExecutorService b executor-service))
       (set-proxy proxy b)
       (when realm
         (set-realm realm b))


paths with symlink could cause conflicts

resolve path fully and do not include if already included

--- src/clj/shadow/cljs/build.clj
+++ src/clj/shadow/cljs/build.clj
@@ -25,7 +25,7 @@
             [loom.alg :as la]
             [cognitect.transit :as transit]
             [shadow.cljs.util :as util]
-     [clojure.pprint :refer (pprint)]
+            [clojure.pprint :refer (pprint)]
             ))

 (defn ^com.google.javascript.jscomp.Compiler make-closure-compiler []
@@ -290,7 +290,7 @@
   [state path]
   {:pre [(compiler-state? state)]}
   (let [file (io/file path)
-        abs-path (.getAbsolutePath file)
+        abs-path (.getCanonicalPath file)
         jar-file (JarFile. file)
         last-modified (.lastModified file)
         entries (.entries jar-file)
@@ -418,10 +418,11 @@
   {:pre [(compiler-state? state)
          (seq path)]}
   (let [root (io/file path)
-        root-path (.getAbsolutePath root)
+        root-path (.getCanonicalPath root)
         root-len (inc (count root-path))]
     (into [] (for [file (file-seq root)
-                   :let [abs-path (.getAbsolutePath file)]
+                   :let [file (.getCanonicalFile file)
+                         abs-path (.getCanonicalPath file)]
                    :when (and (is-cljs-resource? abs-path)
                               (not (.isHidden file)))
                    :let [name (-> abs-path
@@ -912,17 +913,19 @@
   ([state path]
    (merge-resources-in-path state path {:reloadable true}))
   ([state path path-opts]
-   (let [file (io/file path)
-         resources (do-find-resources-in-path state path)]
-     (-> state
-         (cond->
-           (.isDirectory file)
-           (assoc-in [:source-paths (.getAbsolutePath file)]
-             (assoc path-opts
-               :file file
-               :abs-path (.getAbsolutePath file)
-               :path path)))
-         (merge-resources resources)))))
+   (let [file (.getCanonicalFile (io/file path))
+         abs-path (.getCanonicalPath file)]
+     ;; checkout deps with a lot of symlinks can cause duplicates on classpath
+     (if (contains? (:source-paths state) abs-path)
+       state
+       (let [resources (do-find-resources-in-path state abs-path)
+             state
+             (if (.isDirectory file)
+               (assoc-in state [:source-paths abs-path] (assoc path-opts
+                                                          :file file
+                                                          :path abs-path))
+               state)]
+         (merge-resources state resources))))))

 (defn find-resources
   "finds cljs resources in the given path"
@@ -932,7 +935,7 @@
    (with-logged-time
      [(:logger state) (format "Find cljs resources in path: \"%s\"" path)]
      (let [file (io/file path)
-           abs-path (.getAbsolutePath file)]
+           abs-path (.getCanonicalPath file)]
        (when-not (.exists file)
          (throw (ex-info (format "\"%s\" does not exist" path) {:path path})))


render account name in budget item row

render account name in budget item row

--- src/clj_money/web/budgets.clj
+++ src/clj_money/web/budgets.clj
@@ -134,7 +134,10 @@
   [budget item]
   [:tr
    (html
-     [:td (:account-id item)]
+     [:td (->> item
+               :account-id
+               (accounts/find-by-id (env :db))
+               :name)]
      (map budget-period-cell (:periods item))
      [:td (format-number (reduce + 0 (map :amount (:periods item))))])])


Added a high rez HTML5 timer

Added a high rez HTML5 timer

Not sure if it works :D

--- src/cljs/my_project/core.cljs
+++ src/cljs/my_project/core.cljs
@@ -129,10 +129,48 @@
 ;; {{{ Main
 (defonce first-time? (atom true))

+(def counter (atom {:previous nil
+                    :now nil}))
+
+(defprotocol ITimer
+  (tick! [_]))
+
+(defn is-valid? [{:keys [previous now] :as c}]
+  (not (or
+         (nil? previous)
+         (nil? now))))
+
+(defn time-passed [{:keys [previous now] :as c}]
+  (if (is-valid? c)
+    (- now previous)
+    0))
+
+(defn html-timer []
+  (let [c (atom {:previous nil
+                 :now nil})]
+    (reify ITimer
+      (tick! [_]
+        (do
+          (swap!  c assoc
+               :previous (:now @c)
+               :now (.now js/performace)))
+        (if (is-valid? @c)
+          (- (:now @c) (:previous @c))
+          0)))))
+
+(def my-timer (html-timer))
+
+(defn animate [f]
+  (do
+    (.requestAnimationFrame js/window animate)
+    (let [dt (tick! my-timer)]
+      (when (not= dt 0)
+        (f dt)))))
+
 (when @first-time?
     (do
       (swap! first-time? not)
-      (js/setInterval (fn [] (put! time-chan (/ 1 60))) 16)))
+      (js/setInterval (fn [] (put! time-chan (/ 1 60))) 16)))

 (defn main []
   (do
@@ -145,6 +183,12 @@
       draggable-log-window
       {:in-chan log-chan :class-name "pane" :position {:left 100 :top 20}}
       {:target (by-id "app")})
+
+    (let [rm (rmhtml/mk-resource-manager "resources")
+          _ (clear-resources! rm)
+          ; img-chan (load-img! rm "tiles")
+          rend (create-render-target! rm "shit" 300 300) ]
+      )

     ; (let [rm (rmhtml/mk-resource-manager "resources")
     ;       _ (clear-resources! rm)
@@ -154,7 +198,9 @@
     ;     (let [img (<! img-chan)]
     ;       (log-js (rman/height img))
     ;       (log-js (rman/width img)))))
+
     ))
+
 ;; }}}

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


up snapshot version

up snapshot version

--- kafka-clj/project.clj
+++ kafka-clj/project.clj
@@ -1,4 +1,4 @@
-(defproject kafka-clj "3.6.1-SNAPSHOT"
+(defproject kafka-clj "3.6.2-SNAPSHOT"
   :description "fast kafka library implemented in clojure"
   :url "https://github.com/gerritjvv/kafka-fast"
   :license {:name "Eclipse Public License"


no need to separated load user data on init

--- src/cljs/daveconservatoire/site/core.cljs
+++ src/cljs/daveconservatoire/site/core.cljs
@@ -1,12 +1,9 @@
 (ns daveconservatoire.site.core
   (:require [untangled.client.core :as uc]
             [daveconservatoire.site.routes :as r]
-            [om.next :as om]
-            [untangled.client.data-fetch :as df]
-            [daveconservatoire.site.ui :as ui]))
+            [om.next :as om]))

 (defn start-callback [{:keys [reconciler]}]
-  (df/load reconciler :app/me ui/DesktopMenu)
   (om/transact! reconciler `[(app/set-route ~(r/current-handler))]))

 (defonce app


Update apartment

Update apartment

--- src/cljs/gampg/learn_gamma/apartment.cljs
+++ src/cljs/gampg/learn_gamma/apartment.cljs
@@ -153,6 +153,18 @@
 (def u-light-angle
   (g/uniform "uLightAngle" :vec3))

+(def u-point-lighting-location
+  (g/uniform "uPointLightingLocation" :vec3))
+
+(def u-point-lighting-color
+  (g/uniform "uPointLightingColor" :vec3))
+
+(def v-transformed-normal
+  (g/varying "vTransformedNormal" :vec3 :mediump))
+
+(def v-position
+  (g/varying "vPosition" :vec4 :highp))
+
 (def program-diffuse-flat
   (p/program
    {:vertex-shader   {(g/gl-position) (-> u-p-matrix
@@ -208,6 +220,37 @@
                        {(g/gl-frag-color) l-color})
     :precision {:float :mediump}}))

+(def program-diffuse-per-fragment
+  (p/program
+   {:vertex-shader   {v-position           (g/* u-mv-matrix (g/vec4 a-position 1))
+                      (g/gl-position)      (g/* u-p-matrix v-position)
+                      v-transformed-normal (g/* u-n-matrix a-vertex-normal)}
+    :fragment-shader (let [light-direction           (g/normalize (g/- u-point-lighting-location (g/swizzle v-position :xyz)))
+                           direction-light-weighting (g/max (g/dot (g/normalize v-transformed-normal) light-direction) 0)
+                           light-weighting           (g/* (g/+ u-ambient-color u-point-lighting-color)
+                                                          direction-light-weighting)
+                           l-diffuse                 u-diffuse
+                           a                         (g/swizzle l-diffuse :a)
+                           rgb                       (g/* (g/swizzle l-diffuse :rgb) light-weighting)]
+                       {(g/gl-frag-color) (g/vec4 rgb (g/swizzle l-diffuse :a))})
+    :precision       {:float :mediump}}))
+
+(def program-texture-per-fragment
+  (p/program
+   {:vertex-shader   {v-position           (g/* u-mv-matrix (g/vec4 a-position 1))
+                      (g/gl-position)      (g/* u-p-matrix v-position)
+                      v-texture-coord      a-tex-coord-0
+                      v-transformed-normal (g/* u-n-matrix a-vertex-normal)}
+    :fragment-shader (let [light-direction           (g/normalize (g/- u-point-lighting-location (g/swizzle v-position :xyz)))
+                           direction-light-weighting (g/max (g/dot (g/normalize v-transformed-normal) light-direction) 0)
+                           light-weighting           (g/* (g/+ u-ambient-color u-point-lighting-color)
+                                                          direction-light-weighting)
+                           texture-color             (g/texture2D u-sampler (g/vec2 (g/swizzle v-texture-coord :st)))
+                           a                         (g/swizzle texture-color :a)
+                           rgb                       (g/* (g/swizzle texture-color :rgb) light-weighting)]
+                       {(g/gl-frag-color) (g/vec4 rgb (g/swizzle texture-color :a))})
+    :precision {:float :mediump}}))
+
 (def u-sky-box-inverse-mv-matrix
   (g/uniform "uSkyBoxInverseMVMatrix" :mat4))

@@ -259,7 +302,7 @@
                                                                       (boolean vertices)
                                                                       (boolean normals)]))
   (let [[x y z] [(js/Math.sin now)
-                 (js/Math.cos now)
+                 5;;(js/Math.cos now)
                  (js/Math.sin (* now 2))]]
     {u-p-matrix           (object-array p)
      u-mv-matrix          (object-array mv)
@@ -267,8 +310,10 @@
      u-ambient-color      #js [0.5 0.5 0.5]
      u-lighting-direction #js [-0.25 0.25 1]
      u-directional-color  #js [0 0 0]
+     u-point-lighting-location #js[x y z]
+     u-point-lighting-color #js[0.8 0.8 0.8]
      u-use-lighting       true
-     u-light-angle        #js [x y z] ;;[1 1 1]
+     u-light-angle        #js [x y z]
      u-diffuse            (or diffuse [1 1 0 1])
      a-position           vertices
      a-vertex-normal      normals
@@ -391,8 +436,8 @@
                                       sampler          (:sampler material)
                                       draw-count       (:count indices)
                                       program-name     (if texture-program?
-                                                         :texture-light
-                                                         :diffuse-light)
+                                                         :texture-per-fragment-light
+                                                         :diffuse-per-fragment-light)
                                       program          (get-in state [:runtime :programs program-name])
                                       scene-data       (when normals
                                                          (select-keys (get-data now
@@ -587,11 +632,13 @@
         height           (.-clientHeight node)
         driver           (make-driver gl)
         starting-program 0
-        programs         {:diffuse-flat  (gd/program driver program-diffuse-flat)
-                          :diffuse-light (gd/program driver program-diffuse-light)
-                          :texture-flat  (gd/program driver program-texture-flat)
-                          :texture-light (gd/program driver program-texture-light)
-                          :sky-box       (gd/program driver program-sky-box)}
+        programs         {:diffuse-flat               (gd/program driver program-diffuse-flat)
+                          :diffuse-light              (gd/program driver program-diffuse-light)
+                          :texture-flat               (gd/program driver program-texture-flat)
+                          :texture-light              (gd/program driver program-texture-light)
+                          :diffuse-per-fragment-light (gd/program driver program-diffuse-per-fragment)
+                          :texture-per-fragment-light (gd/program driver program-texture-per-fragment)
+                          :sky-box                    (gd/program driver program-sky-box)}
         now              (.getTime (js/Date.))
         app-state        (-> (app-state width height gl node now)
                              (update-in [:comms] merge {:controls controls