make opcode-table work on both jvm and node

Signed-off-by: Yen-Chin Lee <082d453d72dce940e12089a4ad48b97cfe1f3ec4@gmail.com>

--- src/emulator_chip8/opcode.cljc
+++ src/emulator_chip8/opcode.cljc
@@ -1,5 +1,5 @@
 (ns emulator-chip8.opcode
-  ;;  #?(:cljs (:require-macros [emulator-chip8.opcode :refer [defop to-opcode-func]]))
+  #?(:cljs (:require-macros [emulator-chip8.opcode :refer [defop]]))
   )

 ;; #?(:clj
@@ -19,14 +19,14 @@

 (def opcode-table (atom #{}))

-(defmacro defop
-  [opcode args & body]
-  (let [key (keyword (name opcode))
-        pname (symbol (str "opcode-" (name opcode)))
-        ]
-    `(defn ~pname [~@args] ~@body)
-    (swap! opcode-table conj key)
-    ))
+#?(:clj
+   (defmacro defop
+     [opcode args & body]
+     (let [pname (symbol (str "opcode-" (name opcode)))]
+       `(do
+          (defn ~pname ~args ~@body)
+
+          (swap! opcode-table conj ~opcode)))))

 ;; http://stackoverflow.com/questions/24897818/how-to-add-docstring-support-to-defn-like-clojure-macro

@@ -112,7 +112,7 @@

 (defop :8XYE
   "Store the value of register VY shifted left one bit in register VX.
-Set register VF to the most significant bit prior to the shift."
+  Set register VF to the most significant bit prior to the shift."
   [])

 (defop :9XY0
@@ -120,352 +120,196 @@
   the value of register VY."
   [])

-
-
 ;;;;;;

-
-(deref opcode-table)
-(reset! opcode-table #{})
-
-(swap! opcode-table conj (keyword (name :aaa)))
-
-(swap! opcode-table conj :as)
-
-(defn make-opcode-match-list
-  [opcode]
-  (let [code (format "%04X" opcode)
-        ZNNN (format "%SNNN" (subs code 0 1))
-        ZXNN (format "%SXNN" (subs code 0 1))
-        ZXYN (format "%SXYN" (subs code 0 1))
-        ZXYZ (format "%SXY%S" (subs code 0 1) (subs code 3 4))
-        ZXZZ (format "%SX%S"  (subs code 0 1) (subs code 2 4))]
-    (list code ZNNN ZXNN ZXZZ ZXYN ZXYZ)))
-
-(defn make-opcode-sets
-  [opcode]
-  ;; Create possible opcode set for handler-list
-  (->> (make-opcode-match-list opcode)
-       (map keyword)
-       (set)))
-
-(def handler-list
-  {;; Execute machine language subroutine at address NNN
-   ;;   :0NNN 'unimplement
-
-   ;; Clear the screen
-   ;;   :00E0 'clear-screen
-
-   ;; Return from a subroutine
-   :00EE 'return-from-subroutine
-
-   ;; Jump to address NNN
-   :1NNN 'jump-to-address
-
-   ;; Execute subroutine starting at address NNN
-   :2NNN 'call-subroutine
-
-   ;; Skip the following instruction if the value of register VX equals NN
-   :3XNN 'skip-when-VX-equal-NN
-
-   ;; Skip the following instruction if the value of register VX is
-   ;; not equal to NN
-   :4XNN 'skip-when-VX-not-equal-NN
-
-   ;; Skip the following instruction if the value of register VX is
-   ;; equal to the value of register VY
-   :5XY0 'skip-when-VX-equal-VY
-
-   ;; Store number NN in register VX
-   :6XNN 'store-NN-in-VX
-
-   ;; Add the value NN to register VX
-   :7XNN 'add-NN-to-VX
-
-   ;; Store the value of register VY in register VX
-   :8XY0 'store-VY-in-VX
-
-   ;; Set VX to VX OR VY
-   :8XY1 'set-VX-to-VX-or-VY
-
-   ;; Set VX to VX AND VY
-   :8XY2 'set-VX-to-VX-and-VY
-
-   ;; Set VX to VX XOR VY
-   :8XY3 'set-VX-to-VX-xor-VY
-
-   ;; Add the value of register VY to register VX
-   ;; Set VF to 1 if a carry occurs
-   ;; Set VF to 0 if a carry does not occur
-   :8XY4 'add-VY-to-VX
-
-   ;; Subtract the value of register VY from register VX
-   ;; Set VF to 0 if a borrow occurs
-   ;; Set VF to 1 if a borrow does not occur
-   :8XY5 'substract-VY-from-VX
-
-   ;; Store the value of register VY shifted right one bit in register VX
-   ;; Set register VF to the least significant bit prior to the
-   ;; shift
-   :8XY6 'unimplement
-
-   ;; Set register VX to the value of VY minus VX
-   ;; Set VF to 00 if a borrow occurs
-   ;; Set VF to 01 if a borrow does not occur
-   :8XY7 'unimplement
-
-   ;; Store the value of register VY shifted left one bit in register VX
-   ;; Set register VF to the most significant bit prior to the shift
-   :8XYE 'unimplement
-
-   ;; Skip the following instruction if the value of register VX is
-   ;; not equal to the value of register VY
-   :9XY0 'unimplement
-
-   ;; Store memory address NNN in register I
-   :ANNN 'store-NNN-in-I
-
-   ;; Jump to address NNN + V0
-   :BNNN 'unimplement
-
-   ;; Set VX to a random number with a mask of NN
-   :CXNN 'set-VX-random-mask-NN
-
-   ;; Draw a sprite at position VX, VY with N bytes of sprite data
-   ;; starting at the address stored in I
-   ;; Set VF to 01 if any set pixels are changed to unset, and 00
-   ;; otherwise
-   :DXYN 'unimplement
-
-   ;; Skip the following instruction if the key corresponding to
-   ;; the hex value currently stored in register VX is pressed
-   :EX9E 'unimplement
-
-   ;; Skip the following instruction if the key corresponding to the
-   ;; hex value currently stored in register VX is not pressed
-   :EXA1 'unimplement
-
-   ;; Store the current value of the delay timer in register VX
-   :FX07 'store-delay-timer-to-VX
-
-   ;; Wait for a keypress and store the result in register VX
-   :FX0A 'unimplement
-
-   ;; Set the delay timer to the value of register VX
-   :FX15 'store-VX-to-delay-timer
-
-   ;; Set the sound timer to the value of register VX
-   :FX18 'store-VX-to-sound-timer
-
-   ;; Add the value stored in register VX to register I
-   :FX1E 'unimplement
-
-   ;; Set I to the memory address of the sprite data corresponding
-   ;; to the hexadecimal digit stored in register VX
-   :FX29 'unimplement
-
-   ;; Store the binary-coded decimal equivalent of the value stored
-   ;; in register VX at addresses I, I + 1, and I + 2
-   :FX33 'unimplement
-
-   ;; Store the values of registers V0 to VX inclusive in memory
-   ;; starting at address I
-   ;; I is set to I + X + 1 after operation
-   :FX55 'unimplement
-
-   ;; Fill registers V0 to VX inclusive with the values stored in
-   ;; memory starting at address I
-   ;; I is set to I + X + 1 after operation
-   :FX65 'unimplement
-   })
-
-(defn find-match-handler
-  "Search for matching handler in handler list.
+;;(deref opcode-table)
+;;(reset! opcode-table #{})
+
+;; (swap! opcode-table conj (keyword (name :aaa)))
+
+;; (swap! opcode-table conj :as)
+
+(comment
+
+  (defn make-opcode-match-list
+    [opcode]
+    (let [code (format "%04X" opcode)
+          ZNNN (format "%SNNN" (subs code 0 1))
+          ZXNN (format "%SXNN" (subs code 0 1))
+          ZXYN (format "%SXYN" (subs code 0 1))
+          ZXYZ (format "%SXY%S" (subs code 0 1) (subs code 3 4))
+          ZXZZ (format "%SX%S"  (subs code 0 1) (subs code 2 4))]
+      (list code ZNNN ZXNN ZXZZ ZXYN ZXYZ)))
+
+  (defn make-opcode-sets
+    [opcode]
+    ;; Create possible opcode set for handler-list
+    (->> (make-opcode-match-list opcode)
+         (map keyword)
+         (set)))
+
+  (def handler-list
+    {;; Execute machine language subroutine at address NNN
+     ;;   :0NNN 'unimplement
+
+     ;; Clear the screen
+     ;;   :00E0 'clear-screen
+
+     ;; Return from a subroutine
+     :00EE 'return-from-subroutine
+
+     ;; Jump to address NNN
+     :1NNN 'jump-to-address
+
+     ;; Execute subroutine starting at address NNN
+     :2NNN 'call-subroutine
+
+     ;; Skip the following instruction if the value of register VX equals NN
+     :3XNN 'skip-when-VX-equal-NN
+
+     ;; Skip the following instruction if the value of register VX is
+     ;; not equal to NN
+     :4XNN 'skip-when-VX-not-equal-NN
+
+     ;; Skip the following instruction if the value of register VX is
+     ;; equal to the value of register VY
+     :5XY0 'skip-when-VX-equal-VY
+
+     ;; Store number NN in register VX
+     :6XNN 'store-NN-in-VX
+
+     ;; Add the value NN to register VX
+     :7XNN 'add-NN-to-VX
+
+     ;; Store the value of register VY in register VX
+     :8XY0 'store-VY-in-VX
+
+     ;; Set VX to VX OR VY
+     :8XY1 'set-VX-to-VX-or-VY
+
+     ;; Set VX to VX AND VY
+     :8XY2 'set-VX-to-VX-and-VY
+
+     ;; Set VX to VX XOR VY
+     :8XY3 'set-VX-to-VX-xor-VY
+
+     ;; Add the value of register VY to register VX
+     ;; Set VF to 1 if a carry occurs
+     ;; Set VF to 0 if a carry does not occur
+     :8XY4 'add-VY-to-VX
+
+     ;; Subtract the value of register VY from register VX
+     ;; Set VF to 0 if a borrow occurs
+     ;; Set VF to 1 if a borrow does not occur
+     :8XY5 'substract-VY-from-VX
+
+     ;; Store the value of register VY shifted right one bit in register VX
+     ;; Set register VF to the least significant bit prior to the
+     ;; shift
+     :8XY6 'unimplement
+
+     ;; Set register VX to the value of VY minus VX
+     ;; Set VF to 00 if a borrow occurs
+     ;; Set VF to 01 if a borrow does not occur
+     :8XY7 'unimplement
+
+     ;; Store the value of register VY shifted left one bit in register VX
+     ;; Set register VF to the most significant bit prior to the shift
+     :8XYE 'unimplement
+
+     ;; Skip the following instruction if the value of register VX is
+     ;; not equal to the value of register VY
+     :9XY0 'unimplement
+
+     ;; Store memory address NNN in register I
+     :ANNN 'store-NNN-in-I
+
+     ;; Jump to address NNN + V0
+     :BNNN 'unimplement
+
+     ;; Set VX to a random number with a mask of NN
+     :CXNN 'set-VX-random-mask-NN
+
+     ;; Draw a sprite at position VX, VY with N bytes of sprite data
+     ;; starting at the address stored in I
+     ;; Set VF to 01 if any set pixels are changed to unset, and 00
+     ;; otherwise
+     :DXYN 'unimplement
+
+     ;; Skip the following instruction if the key corresponding to
+     ;; the hex value currently stored in register VX is pressed
+     :EX9E 'unimplement
+
+     ;; Skip the following instruction if the key corresponding to the
+     ;; hex value currently stored in register VX is not pressed
+     :EXA1 'unimplement
+
+     ;; Store the current value of the delay timer in register VX
+     :FX07 'store-delay-timer-to-VX
+
+     ;; Wait for a keypress and store the result in register VX
+     :FX0A 'unimplement
+
+     ;; Set the delay timer to the value of register VX
+     :FX15 'store-VX-to-delay-timer
+
+     ;; Set the sound timer to the value of register VX
+     :FX18 'store-VX-to-sound-timer
+
+     ;; Add the value stored in register VX to register I
+     :FX1E 'unimplement
+
+     ;; Set I to the memory address of the sprite data corresponding
+     ;; to the hexadecimal digit stored in register VX
+     :FX29 'unimplement
+
+     ;; Store the binary-coded decimal equivalent of the value stored
+     ;; in register VX at addresses I, I + 1, and I + 2
+     :FX33 'unimplement
+
+     ;; Store the values of registers V0 to VX inclusive in memory
+     ;; starting at address I
+     ;; I is set to I + X + 1 after operation
+     :FX55 'unimplement
+
+     ;; Fill registers V0 to VX inclusive with the values stored in
+     ;; memory starting at address I
+     ;; I is set to I + X + 1 after operation
+     :FX65 'unimplement
+     })
+
+  (defn find-match-handler
+    "Search for matching handler in handler list.
   If nothing find, return nil else return keyword."
-  [handler opcode]
-  (str "opcode-" (name (some (make-opcode-sets opcode) (keys handler))) )
-  )
-
-(defn make-handler-args
-  "Parse the code to find how many VX, VY, NNN, NN, N
+    [handler opcode]
+    (str "opcode-" (name (some (make-opcode-sets opcode) (keys handler))) )
+    )
+
+  (defn make-handler-args
+    "Parse the code to find how many VX, VY, NNN, NN, N
   and create argument lists."
-  [opcode]
-  (let [code (format "%04X" opcode)]
-    {:NNN (subs code 1 4)
-     :NN  (subs code 2 4)
-     :N   (subs code 3 4)
-     :VX  (subs code 1 2)
-     :VY  (subs code 2 3)}))
-
-(comment
-  (make-opcode-sets 0xf155) ;; FX55
-  (make-handler-args 0xf155) ;; FX55
-
-  (find-match-handler handler-list 0xf155)
-
-  (keys handler-list)
-  )
-
-
-(defn find-match-handler
-  "Search for matching handler in handler list.
+    [opcode]
+    (let [code (format "%04X" opcode)]
+      {:NNN (subs code 1 4)
+       :NN  (subs code 2 4)
+       :N   (subs code 3 4)
+       :VX  (subs code 1 2)
+       :VY  (subs code 2 3)}))
+
+  (comment
+    (make-opcode-sets 0xf155) ;; FX55
+    (make-handler-args 0xf155) ;; FX55
+
+    (find-match-handler handler-list 0xf155)
+
+    (keys handler-list)
+    )
+
+
+  (defn find-match-handler
+    "Search for matching handler in handler list.
   If nothing find, return nil else return keyword."
-  [handler opcode]
-  (some (make-opcode-sets opcode) (keys handler)))
-
-
-
-
-;; 0NNN
-(defop 0NNN
-  )
-
-;; 00E0
-(defn opcode-00E0
-  "Clear the screen. This function will also set draw-flag to 1
-  to make canvas function refresh."
-  [])
-
-;; 00EE
-(defn opcode-00EE
-  [])
-
-;; 1NNN
-(defn opcode-1NNN
-  "Jump to address NNN."
-  [])
-
-;; 2NNN
-(defn opcode-2NNN
-  [])
-
-;; 3XNN
-(defn opcode-3XNN
-  "Skip next instruction if the value of register VX equals NN"
-  [])
-
-;; 4XNN
-(defn opcode-4XNN
-  "Skip next instruction if the value of register VX is
-  not equal to NN."
-  [])
-
-;; 5XY0
-(defn opcode-5XY0
-  "Skip next instruction if the value of register VX is
-  equal to the value of register VY."
-  [])
-
-;; 6XNN
-(defn opcode-6XNN
-  "Store number NN in register VX."
-  [])
-
-;; 7XNN
-(defn opcode-7XNN
-  "Add the value NN to register VX."
-  [])
-
-;; 8XY0
-(defn opcode-8XY0
-  "Store the value of register VY in register VX."
-  [])
-
-;; 8XY1
-(defn opcode-8XY1
-  "Set VX to VX OR VY."
-  [])
-
-;; 8XY2
-(defn opcode-8XY2
-  "Set VX to VX AND VY."
-  [])
-
-;; 8XY3
-(defn opcode-8XY3
-  "Set VX to VX XOR VY."
-  [])
-
-;; 8XY4
-(defn opcode-8XY4
-  "Add the value of register VY to register VX.
-  Set VF to 1 if a carry occurs
-  Set VF to 0 if a carry does not occur"
-  [])
-
-;; 8XY5
-(defn opcode-8XY5
-  "Subtract the value of register VY from register VX.
-  Set VF to 0 if a borrow occurs
-  Set VF to 1 if a borrow does not occur"
-  [])
-
-;; 8XY6
-(defn opcode-8XY6
-  ""
-  [])
-
-;; 8XY7
-(defn opcode-8XY7
-  ""
-  [])
-
-;; 8XYE
-(defn opcode-8XYE
-  ""
-  [])
-
-;; 9XY0
-(defn opcode-9XY0
-  ""
-  [])
-
-;; ANNN
-(defn opcode-ANNN
-  "Store memory address NNN in register I."
-  [])
-
-;; BNNN
-(defn opcode-BNNN
-  ""
-  [])
-
-;; CXNN
-(defn opcode-CXNN
-  "Set VX to a random number with a mask of NN"
-  [])
-
-;; DXYN
-(defn opcode-DXYN
-  ""
-  [])
-
-;; EX9E
-(defn opcode-EX9E
-  ""
-  [])
-
-;; EXA1
-(defn opcode-EXA1
-  ""
-  [])
-
-;; FX07
-(defn opcode-FX07
-  "Store the current value of the delay timer in register VX."
-  [])
-
-;; FX0A
-(defn opcode-FX0A
-  ""
-  [])
-
-;; FX15
-(defn opcode-FX15
-  "Set the delay timer to the value of register VX."
-  [])
-
-;; FX18
-(defn opcode-FX18
-  "Set the sound timer to the value of register VX."
-  [])
+    [handler opcode]
+    (some (make-opcode-sets opcode) (keys handler)))
+
+  )


bump eastwood & cljfmt

bump eastwood & cljfmt

--- dot/lein/profiles.clj
+++ dot/lein/profiles.clj
@@ -4,8 +4,8 @@
             [lein-hiera "1.0.0"]
             [lein-kibit "0.1.6"]
             [lein-pprint "1.2.0"]
-            [jonase/eastwood "0.2.9"]
+            [jonase/eastwood "0.3.1"]
             ;;[com.billpiel/sayid "0.0.10"]
-            [lein-cljfmt "0.6.0"]]
+            [lein-cljfmt "0.6.1"]]
   :dependencies [[slamhound "1.5.5"]]
   :aliases {"slamhound" ["run" "-m" "slam.hound"]}}}


[#9206] fix wrong ping handling on signing messages

--- src/status_im/hardwallet/core.cljs
+++ src/status_im/hardwallet/core.cljs
@@ -913,7 +913,7 @@
                            :utils/show-popup {:title   (i18n/label :t/error)
                                               :content (i18n/label :t/cannot-read-card)}}
                           (navigation/navigate-to-cofx :keycard-connection-lost nil))
-                (show-wrong-keycard-alert cofx true)))))
+                (show-wrong-keycard-alert true)))))

 (fx/defn on-delete-success
   [{:keys [db] :as cofx}]
@@ -1117,7 +1117,7 @@
         setup? (boolean (get-in db [:hardwallet :setup-step]))]
     (log/debug "[hardwallet] verify pin error" error)
     (fx/merge cofx
-              (if tag-was-lost?
+              (when tag-was-lost?
                 (fx/merge cofx
                           {:db               (-> db
                                                  (assoc-in [:hardwallet :on-card-connected] :hardwallet/verify-pin)
@@ -1140,7 +1140,7 @@
                             (when-not setup?
                               (navigation/navigate-to-cofx :enter-pin-settings nil))
                             (get-application-info (get-pairing db) nil))
-                  (show-wrong-keycard-alert cofx true))))))
+                  (show-wrong-keycard-alert true))))))

 (fx/defn on-change-pin-success
   [{:keys [db] :as cofx}]
@@ -1186,7 +1186,7 @@
                                                                          :error-label  :t/pin-mismatch})}
                             (navigation/navigate-to-cofx :enter-pin-settings nil)
                             (get-application-info (get-pairing db) nil))
-                  (show-wrong-keycard-alert cofx true))))))
+                  (show-wrong-keycard-alert true))))))

 (fx/defn on-unpair-success
   [{:keys [db] :as cofx}]
@@ -1800,7 +1800,7 @@
                   (if (= flow :import)
                     (navigation/navigate-to-cofx :keycard-recovery-pin nil)
                     (navigation/navigate-to-cofx :keycard-login-pin nil)))
-        (show-wrong-keycard-alert cofx true)))))
+        (show-wrong-keycard-alert true)))))

 (fx/defn send-transaction-with-signature
   [_ data]
@@ -1842,20 +1842,22 @@
   (log/debug "[hardwallet] sign error: " error)
   (let [tag-was-lost? (= "Tag was lost." (:error error))]
     (fx/merge cofx
-              (if tag-was-lost?
-                (fx/merge cofx
-                          {:db             (-> db
-                                               (assoc-in [:hardwallet :on-card-connected] :hardwallet/prepare-to-sign)
-                                               (assoc-in [:hardwallet :pin :status] nil)
-                                               (assoc-in [:signing/sign :keycard-step] :connect))
-                           :utils/show-popup {:title   (i18n/label :t/error)
-                                              :content (i18n/label :t/cannot-read-card)}}))
+              (when tag-was-lost?
+                (fn [{:keys [db] :as cofx}]
+                  (fx/merge cofx
+                            {:db             (-> db
+                                                 (assoc-in [:hardwallet :on-card-connected] :hardwallet/prepare-to-sign)
+                                                 (assoc-in [:hardwallet :pin :status] nil)
+                                                 (assoc-in [:signing/sign :keycard-step] :connect))
+                             :utils/show-popup {:title   (i18n/label :t/error)
+                                                :content (i18n/label :t/cannot-read-card)}})))
               (if (re-matches pin-mismatch-error (:error error))
-                (fx/merge cofx
-                          {:db (-> db
-                                   (update-in [:hardwallet :pin] merge {:status      :error
-                                                                        :sign        []
-                                                                        :error-label :t/pin-mismatch})
-                                   (assoc-in [:signing/sign :keycard-step] :pin))}
-                          (get-application-info (get-pairing db) nil))
-                (show-wrong-keycard-alert cofx true)))))
+                (fn [{:keys [db] :as cofx}]
+                  (fx/merge cofx
+                            {:db (-> db
+                                     (update-in [:hardwallet :pin] merge {:status      :error
+                                                                          :sign        []
+                                                                          :error-label :t/pin-mismatch})
+                                     (assoc-in [:signing/sign :keycard-step] :pin))}
+                            (get-application-info (get-pairing db) nil)))
+                (show-wrong-keycard-alert true)))))


CW & RS | 16 | Redirect using absolute paths - fix infinite recursion

--- src/stonecutter_client/handler.clj
+++ src/stonecutter_client/handler.clj
@@ -31,7 +31,7 @@
 (defn auth-url [] (get-env :auth-url "http://localhost:3000"))

 (defn absolute-path [resource]
-  (str (base-url) (absolute-path resource)))
+  (str (base-url) (path resource)))

 (defn html-response [s]
   (-> s


Include pprint and clojure.repl fns in eval

--- src/yetibot/core/commands/eval.clj
+++ src/yetibot/core/commands/eval.clj
@@ -1,5 +1,7 @@
 (ns yetibot.core.commands.eval
   (:require
+    [clojure.repl :refer :all]
+    [clojure.pprint :refer [pprint]]
     [yetibot.core.config :refer [config-for-ns]]
     [yetibot.core.hooks :refer [cmd-hook]]
     [clojure.string :refer [split]]))


(maint) Make :producer_timestamp an optional key

Prior to this commit our configure-expiration-wireformat-schema
required a :producer_timestamp key in the body of the command,
this key should be optional.

--- src/puppetlabs/puppetdb/nodes.clj
+++ src/puppetlabs/puppetdb/nodes.clj
@@ -18,7 +18,7 @@
 (def configure-expiration-wireformat-schema
   {:certname s/Str
    :expire expire-wireformat-schema
-   :producer_timestamp (s/maybe pls/Timestamp)})
+   (s/optional-key :producer_timestamp) (s/maybe pls/Timestamp)})

 (def nodes-wireformat-schema
   {:certname s/Str


display warnings for invalid/deprecated flags. (closes #15)

--- src/leiningen/ancient/utils/cli.clj
+++ src/leiningen/ancient/utils/cli.clj
@@ -19,14 +19,22 @@
    ":no-tests"        :no-tests
    ":overwrite-backup":overwrite-backup})

+(def ^:private CLI_DEPRECATED
+  "Flags that are no longer supported."
+  {":upgrade"        "use task 'upgrade' instead"
+   ":upgrade-global" "use task 'upgrade-global' instead"
+   ":get"            "use task 'get' instead"})
+
 (defn parse-cli
   "Parse Command Line, return map of Settings."
   [args]
   (let [data (->> (for [^String flag args]
-                    (when (contains? CLI_FLAGS flag)
-                      (vector
-                        (get CLI_FLAGS flag)
-                        true)))
+                    (cond (contains? CLI_DEPRECATED flag) (println "WARN: option" (str "'" flag "'") "is no longer supported"
+                                                                   (str "(" (get CLI_DEPRECATED flag) ")."))
+                          (contains? CLI_FLAGS flag) (vector
+                                                       (get CLI_FLAGS flag)
+                                                       true)
+                          :else (println "WARN: option" (str "'" flag "'") "not recognized.")))
                (into {}))
         data (assoc data
                     :aggressive? (:aggressive? data false)


Remove reference to buildable-at to fix test

--- test/cljs/zetawar/subs_test.cljs
+++ test/cljs/zetawar/subs_test.cljs
@@ -207,7 +207,6 @@
                  :unit-type/max-range
                  :unit-type/can-capture
                  :unit-type/armor-type
-                 :unit-type/buildable-at
                  :unit-type/image}
                (into #{} unit-type-keys)))))))


Added seq-response test

Added seq-response test

--- test/compojure/http/response.clj
+++ test/compojure/http/response.clj
@@ -17,6 +17,10 @@
   (is (= (:body (create-response {} "Lorem Ipsum"))
          "Lorem Ipsum")))

+(deftest seq-response
+  (is (= (:body (create-response {} (list "a" "b" "c")))
+         (list "a" "b" "c"))))
+
 (deftest map-response
   (let [response {:status  200
                   :headers {"Content-Type" "text/plain"}


Add news about track! and dispose!

Add news about track! and dispose!

--- demo/reagentdemo/news/news060.cljs
+++ demo/reagentdemo/news/news060.cljs
@@ -39,6 +39,16 @@
     [:ul
      (for [i ids]
        ^{:key i} [name-comp i])]))
+
+
+(defn log-app-state []
+  (prn @app-state))
+
+(def --space nil)
+
+#_(defonce logger (r/track! log-app-state))
+
+#_(r/dispose! logger)

 (defn mouse-pos-comp []
@@ -100,7 +110,6 @@

 (defn cursor-example []
   (let [first-person (r/cursor app-state [:people 1])]
-    (dbg first-person)
     [:p "A person: " (:name @first-person)]))

@@ -135,12 +144,13 @@
        [:p "Here's an example: "]

        [demo-component {:comp name-list
-                        :src (s/src-of [:app-state
-                                        :people
-                                        :person-keys
-                                        :person
-                                        :name-comp
-                                        :name-list])}]
+                        :src [:pre ns-src
+                              (s/src-of [:app-state
+                                         :people
+                                         :person-keys
+                                         :person
+                                         :name-comp
+                                         :name-list])]}]

        [:p "Here, the " [:code "name-list"] " component will only be
        re-rendered if the keys of the " [:code ":people"] " map
@@ -166,6 +176,23 @@
         uses of " [:code "@(r/track people)"] " in the example above
         will only result in one call to the " [:code "people"] "
         function (both initially, and when the state atom changes)."]]
+
+       [:h2 "track!"]
+
+       [:p [:code "track!"]" is another new function. It works just
+       like "[:code "track"]", except that the function passed is
+       invoked immediately, and continues to be invoked whenever any
+       atoms used within it changes."]
+
+       [:p "For example, given this function:"]
+
+       [demo-component {:src (s/src-of [:log-app-state])}]
+
+       [:p "you could use " [:code "(defonce logger (r/track!
+       log-app-state))"]" to monitor changes
+       to "[:code "app-state"]". "[:code "log-app-state"]" would
+       continue to run until you stop it, using "[:code "(r/dispose!
+       logger)"]"."]

        [:h2 "Handling destruction"]

@@ -209,8 +236,9 @@
          [:li "allows recursive applications of "[:code "rswap!"]" on the same
          atom."]]

-        [:p "Here’s an example that uses "[:code "rswap!"]" to edit
-        the data introduced in the section about track above:"]
+        [:p "Here’s an example that uses event handling
+        with "[:code "rswap!"]" to edit the data introduced in the
+        section about "[:code "track"]" above:"]

         [demo-component {:comp edit-fields
                          :src (s/src-of [:event-handler
@@ -222,7 +250,7 @@
         function, consisting of a trivial application
         of "[:code "rswap!"]" and some optional logging. This is the
         only place where application state actually changes – the rest
-        is pure functions all the way."]
+        is pure functions."]

         [:p "The actual event handling is done
         in "[:code "event-handler"]", which takes state and event as
@@ -324,10 +352,11 @@
        [:section.demo-text
         [:h2 "Tapping into the rendering loop"]

-        [:p [:code "next-tick"]" is an existing function, that now has
-        a more predictable timing. It takes a function that is invoked
-        immediately before the next rendering (which is in turn
-        triggered using "[:code "requestAnimationFrame"]")."]
+        [:p "The "[:code "next-tick"]" function now has a more
+        predictable timing. The function passed
+        to "[:code "next-tick"]" is now invoked immediately before the
+        next rendering (which is in turn triggered
+        using "[:code "requestAnimationFrame"]")."]

         [:p [:code "after-update"]" works just
         like "[:code "next-tick"]", except that the function given is


fix unittests - refresh now takes two args

--- test/greybear/websocket_test.clj
+++ test/greybear/websocket_test.clj
@@ -7,4 +7,4 @@
  (on-message nil "make-move: 142 1-3") => nil
  (provided
   (make-move 142 "1-3") => anything
-  (refresh anything) => nil))
+  (refresh anything anything) => nil))


fix broken `if` in cljs.pprint caught by new check

--- src/main/cljs/cljs/pprint.cljs
+++ src/main/cljs/cljs/pprint.cljs
@@ -2879,7 +2879,7 @@
       (write-out
         (if (and (satisfies? IPending o) (not (-realized? o)))
           :not-delivered
-          :else @o)))))
+          @o)))))

 (def ^{:private true} pprint-pqueue (formatter-out "~<<-(~;~@{~w~^ ~_~}~;)-<~:>"))


Things to do right now

Things to do right now

--- org-mode/src/com/gfredericks/org_agenda.clj
+++ org-mode/src/com/gfredericks/org_agenda.clj
@@ -548,6 +548,9 @@
                        :else
                        (throw (ex-info "Bad preamble"
                                        {:preamble preamble})))))
+
+      (println (format "Things to do right now: %d\n" (:todo-now-count agenda)))
+
       (when (seq deadlines)
         (println "== DEADLINES ==")
         (println "(TODO: show upcoming deadlines based on the -0d cookie)")
@@ -659,15 +662,19 @@
                                                          (assoc item
                                                                 :timetable-slot [t1 t2]
                                                                 :past? past?)))))}])
-        sort-key (juxt (comp - priority) :created-at :file :line-number)]
-    {:deadlines (sort-by sort-key deadlines)
-     :triage    (sort-by sort-key triage)
-     :backlog   (sort-by sort-key backlog)
-     :today     (second (first not-past))
-     :future    (rest not-past)
-     :past      (for [[date :as date+item] (reverse (sort by-day))
-                      :when (compare/<= date today)]
-                  date+item)}))
+        sort-key (juxt (comp - priority) :created-at :file :line-number)
+        today-stuff (second (first not-past))]
+    {:deadlines      (sort-by sort-key deadlines)
+     :triage         (sort-by sort-key triage)
+     :backlog        (sort-by sort-key backlog)
+     :today          today-stuff
+     :future         (rest not-past)
+     :past           (for [[date :as date+item] (reverse (sort by-day))
+                           :when (compare/<= date today)]
+                       date+item)
+     :todo-now-count (->> (concat (:todos today-stuff) triage deadlines)
+                          (remove #(= "[#C]" (:priority-cookie %)))
+                          (count))}))

 (defn all-agenda-data
   [directory now]


Fix password reset unit test

Fix password reset unit test

--- test/metabase/email/messages_test.clj
+++ test/metabase/email/messages_test.clj
@@ -23,10 +23,8 @@
     [{:from "notifications@metabase.com",
       :to ["test@test.com"],
       :subject "[Metabase] Password Reset Request",
-      :body [{:type "text/html; charset=utf-8",
-              :content (str "
You're receiving this e-mail because you or someone else has requested a password for your user account at test.domain.com. "
-                            "It can be safely ignored if you did not request a password reset. Click the link below to reset your password.
"
-                            "
http://localhost/some/url
")}]}]
+      :body [{:type "text/html; charset=utf-8"}]}]
   (with-fake-inbox
     (send-password-reset-email "test@test.com" "test.domain.com" "http://localhost/some/url")
-    (@inbox "test@test.com")))
+    (-> (@inbox "test@test.com")
+        (update-in [0 :body 0] dissoc :content))))


Some fixes on text ticks on rules.

Some fixes on text ticks on rules.

--- src/uxbox/ui/workspace/rules.cljs
+++ src/uxbox/ui/workspace/rules.cljs
@@ -38,13 +38,10 @@
   [zoom acc value]
   (let [big-ticks-mod (big-ticks-mod zoom)
         mid-ticks-mod (mid-ticks-mod zoom)
-        big-step? (< (mod value big-ticks-mod) step-size)
-        mid-step? (< (mod value mid-ticks-mod) step-size)
         pos (+ value
                rule-padding
-               wb/canvas-start-x
-               wb/canvas-scroll-padding)
-        pos (* pos zoom)]
+               (* wb/canvas-start-x zoom)
+               wb/canvas-scroll-padding)]
     (cond
       (< (mod value big-ticks-mod) step-size)
       (conj acc (str/format "M %s %s L %s %s" pos 5 pos step-padding))
@@ -60,9 +57,8 @@
   (let [big-ticks-mod (big-ticks-mod zoom)
         mid-ticks-mod (mid-ticks-mod zoom)
         pos (+ value
-               wb/canvas-start-x
-               wb/canvas-scroll-padding)
-        pos (* pos zoom)]
+               (* wb/canvas-start-x zoom)
+               wb/canvas-scroll-padding)]
     (cond
       (< (mod value big-ticks-mod) step-size)
       (conj acc (str/format "M %s %s L %s %s" 5 pos step-padding pos))
@@ -80,9 +76,8 @@
   (let [big-ticks-mod (big-ticks-mod zoom)
         pos (+ value
                rule-padding
-               wb/canvas-start-x
-               wb/canvas-scroll-padding)
-        pos (* pos zoom)]
+               (* wb/canvas-start-x zoom)
+               wb/canvas-scroll-padding)]
     (when (< (mod value big-ticks-mod) step-size)
       (html
        [:text {:x (+ pos 2)
@@ -98,9 +93,9 @@
   [zoom value]
   (let [big-ticks-mod (big-ticks-mod zoom)
         pos (+ value
-               wb/canvas-start-x
-               wb/canvas-scroll-padding)
-        pos (* pos zoom)]
+               (* wb/canvas-start-x zoom)
+               ;; wb/canvas-start-x
+               wb/canvas-scroll-padding)]
     (when (< (mod value big-ticks-mod) step-size)
       (html
        [:text {:y (- pos 3)


(maint) - Change data field's schema to string -> any

--- src/puppetlabs/cthun/validation.clj
+++ src/puppetlabs/cthun/validation.clj
@@ -18,7 +18,7 @@
    (s/required-key :sender) s/Str
    (s/required-key :expires) ISO8601
    (s/required-key :hops) [{s/Keyword ISO8601}]
-   (s/optional-key :data) {s/Keyword s/Str}})
+   (s/optional-key :data) {s/Keyword s/Any}})

 ; Server message data types
 (def LoginMessageData


(PDB-5022) attempt-exec-command: remove unused arity

eastwood noticed parens were missing, and it appears to be vestigial
anyway.

--- src/puppetlabs/puppetdb/command.clj
+++ src/puppetlabs/puppetdb/command.clj
@@ -547,10 +547,7 @@
 (def quick-retry-count 4)

 (defn attempt-exec-command
-  ([{:keys [callback] :as cmd} db conn-status response-pub-chan stats-atom
-   shutdown-for-ex]
-   attempt-exec-command cmd db conn-status response-pub-chan stats-atom shutdown-for-ex {})
-  ([{:keys [callback] :as cmd} db conn-status response-pub-chan stats-atom
+  [{:keys [callback] :as cmd} db conn-status response-pub-chan stats-atom
    shutdown-for-ex options-config]
   (try
     (let [result (call-with-quick-retry quick-retry-count
@@ -567,7 +564,7 @@
       (callback {:command cmd :exception ex})
       (async/>!! response-pub-chan
                  (make-cmd-processed-message cmd ex))
-      (throw ex)))))
+      (throw ex))))

 ;; The number of times a message can be retried before we discard it
 (def maximum-allowable-retries 5)


Tweak example-plan to work for testing grandfathering.

--- test-cljs/frontend/test_utils.cljs
+++ test-cljs/frontend/test_utils.cljs
@@ -62,25 +62,30 @@
                                     :id "t1"
                                     :price 0
                                     :type "trial"}}
+                 :amount 0
                  :trial_end (->> 5
                                  (time/days)
                                  (time/from-now)
                                  (time-format/unparse (:basic-date-time time-format/formatters)))}
+         :free {:free {:template {:id "f1"
+                                  :free_containers 1
+                                  :type "free"}}
+                :amount 0}
          :paid {:paid {:template {:id "p18"
                                   :free_containers 0
                                   :price 0
                                   :container_cost 50
                                   :type "containers"}}
+                :amount (* 4 5000)
                 :containers 4}
          :big-paid {:paid {:template {:id "p18"
                                       :free_containers 0
                                       :price 0
                                       :container_cost 50
                                       :type "containers"}}
+                    :amount (* 60 5000)
                     :containers 60}
-         :free {:free {:template {:id "f1"
-                                  :free_containers 1
-                                  :type "free"}}}
+
          :grandfathered {:paid {:template {:id "p18"
                                            :free_containers 0
                                            :price 0


whoops, bad copy&paste

whoops, bad copy&paste

--- src/main/shadow/cljs/build.clj
+++ src/main/shadow/cljs/build.clj
@@ -2464,14 +2464,14 @@
               {:keys [protocol-info]} meta

               prefix
-              (str (cljs-comp/protocol-prefix name))]
+              (str (comp/protocol-prefix name))]

           ;; the marker prop
           ;; some.prototype.cljs$core$ISeq$ = cljs.core.PROTOCOL_SENTINEL;
           (.registerPropertyOnType type-reg prefix obj-type)

           (doseq [[meth-name meth-sigs] (:methods protocol-info)
-                  :let [munged-name (cljs-comp/munge meth-name)]
+                  :let [munged-name (comp/munge meth-name)]
                   meth-sig meth-sigs]

             (let [arity


failed source excerpts shouldn't fail a build

they are just for warning anyways.

sometimes the CLJS compiler will have invalid line/column metadata
pointing to locations that don't actually exist, mostly related to
some macro expansions where suddenly line/column map to their
location in a .clj file but not containing any info to detect that

closes #82

--- src/main/shadow/build/warnings.clj
+++ src/main/shadow/build/warnings.clj
@@ -1,6 +1,7 @@
 (ns shadow.build.warnings
   (:require [clojure.string :as str]
-            [shadow.build.data :as data])
+            [shadow.build.data :as data]
+            [clojure.tools.logging :as log])
   (:import (java.io BufferedReader StringReader)))

 (defn get-source-excerpts
@@ -41,9 +42,18 @@
          (into []))))

 (defn get-source-excerpt [state rc location]
-  ;; defaults to a seq of locations to avoid parsing a file multiple times
-  (-> (get-source-excerpts state rc [location])
-      (first)))
+  (try
+    ;; defaults to a seq of locations to avoid parsing a file multiple times
+    (-> (get-source-excerpts state rc [location])
+        (first))
+    (catch Exception e
+      (log/warnf e
+        "failed to get source excerpt for %s at %s"
+        (or (:file rc)
+            (:url rc)
+            (:resource-name rc))
+        location)
+      nil)))

 ;; https://en.wikipedia.org/wiki/ANSI_escape_code
 ;; https://github.com/chalk/ansi-styles/blob/master/index.js


Fix public orgs listing.

Fix public orgs listing.

--- src/oc/storage/api/entry_point.clj
+++ src/oc/storage/api/entry_point.clj
@@ -32,9 +32,10 @@
                 [])
         org-uuids (set (map :uuid authed-orgs))
         org-slugs (set (map :slug authed-orgs)) ; set of the org slugs for this user
-        requested-org-slug (get-in request [:params "requested"]) ; a public org may be requested specifically
+        requested-org-slug (or (get-in request [:query-params "requested"]) ; a public org may be requested specifically
+                               (get-in request [:params "requested"])) ; let's make sure we get params from all places, depending on the ring version
         check-for-public? (and (slugify/valid-slug? requested-org-slug)   ; it's a valid slug
-                               (not (or (org-uuids requested-org-slug)    ; and the requested string is or a valud uuid
+                               (not (or (org-uuids requested-org-slug)    ; and the requested string is or a valid uuid
                                         (org-slugs requested-org-slug)))) ; or a valid slug of an org the user has access to
         public-org (when check-for-public? (org-if-public-boards conn requested-org-slug)) ; requested org if public
         orgs (if public-org (conj authed-orgs public-org) authed-orgs)] ; final set of orgs


use boolean value

use boolean value

--- src/oc/storage/resources/entry.clj
+++ src/oc/storage/resources/entry.clj
@@ -235,14 +235,14 @@
   Given the UUID of the org, an order, one of `:asc` or `:desc`, a start date as an ISO8601 timestamp,
   and a direction, one of `:before` or `:after`, return the published entries for the org with any interactions.
   "
-  [conn org-uuid :- lib-schema/UniqueID order start :- lib-schema/ISO8601 direction allowed-boards :- [lib-schema/UniqueID] {:keys [must-read count] :or {must-read nil count false}}]
+  [conn org-uuid :- lib-schema/UniqueID order start :- lib-schema/ISO8601 direction allowed-boards :- [lib-schema/UniqueID] {:keys [must-read count] :or {must-read false count false}}]
   {:pre [(db-common/conn? conn)
           (#{:desc :asc} order)
           (#{:before :after} direction)]}
   (let [filter-map (if-not must-read
                      [{:fn :contains :value allowed-boards :field :board-uuid}]
                      [{:fn :contains :value allowed-boards :field :board-uuid}
-                      {:fn :eq :field :must-read :value (#{true "true"} must-read)}]
+                      {:fn :eq :field :must-read :value (boolean (#{true "true"} must-read))}]
                      )]
     (db-common/read-resources-and-relations conn table-name
       :status-org-uuid [[:published org-uuid]]


Remove replace meta from access-level key.

--- src/oc/storage/api/entries.clj
+++ src/oc/storage/api/entries.clj
@@ -624,7 +624,7 @@
                         {:existing-org (api-common/rep org) :existing-board (api-common/rep board)
                          :existing-entry (api-common/rep entry) :existing-comments (api-common/rep comments)
                          :existing-reactions (api-common/rep reactions)
-                         :access-level (api-common/rep access-level)}
+                         :access-level access-level}
                         false))

   ;; Responses


add back the auto share on publish after publishing a draft.

--- src/oc/storage/api/entries.clj
+++ src/oc/storage/api/entries.clj
@@ -165,6 +165,7 @@
             publish-result (entry-res/publish-entry! conn (:uuid updated-entry) updated-entry user)]
     (do
       (timbre/info "Published entry for:" (:uuid updated-entry))
+      (auto-share-on-publish conn ctx publish-result)
       (change/send-trigger! (change/->trigger :add publish-result))
       (timbre/info "Published entry:" entry-for)
       (notification/send-trigger! (notification/->trigger :add org board {:new publish-result} user))


Comment out failure ch.

Comment out failure ch.

--- src/onyx/coordinator/async.clj
+++ src/onyx/coordinator/async.clj
@@ -132,8 +132,8 @@
 (defn failure-ch-loop [failure-tail]
   (loop []
     (when-let [failure (<!! failure-tail)]
-      (prn "Failed: " (:ch failure))
-      (prn "Details: " (:e failure))
+      ;; (prn "Failed: " (:ch failure))
+      ;; (prn "Details: " (:e failure))
       (recur))))

 (defn print-if-not-thread-death [e & _]


Only store log entry if not empty

Only store log entry if not empty

--- src/onyx/peer/window_state.clj
+++ src/onyx/peer/window_state.clj
@@ -252,21 +252,25 @@
                          (swap! filter-state state-extensions/apply-filter-id task-event unique-id))
                        (if process?
                          (let [_ (st-ack/prepare acking-state unique-id fused-ack)
-                               updated (swap! windows-state fire-state-event state-event**)]
-                           (swap! windows-state clean-windows-states)
+                               updated (swap! windows-state fire-state-event state-event**)
+                               _ (swap! windows-state clean-windows-states)]
                            (list #(st-ack/ack acking-state unique-id fused-ack)
                                  (list unique-id (doall (map log-entries updated)))))
                          (list #(st-ack/defer acking-state unique-id fused-ack)))))
                    (:leaves leaf)))
                (:tree results)
                (:acks results)))
+        ack-fns (doall (map first rs))
         success-fn (fn []
                      (run! (fn [f] (f)) (map first rs))
+                     (run! (fn [f] (f)) ack-fns)
                      (emit-latency-value :window-log-write-entry
                                          monitoring
                                          (- (System/currentTimeMillis) start-time)))
         log-entry (keep second rs)]
     (state-extensions/store-log-entry state-log task-event success-fn log-entry)))
+    (when-not (empty? log-entry)
+      (state-extensions/store-log-entry state-log task-event success-fn log-entry))))

 (defn process-event [compiled {:keys [task-event] :as state-event}]
   (let [{:keys [onyx.core/windows-state onyx.core/state-log]} task-event


Remove margin for scroll

Remove margin for scroll

--- src/org/knotation/editor/util.cljs
+++ src/org/knotation/editor/util.cljs
@@ -28,5 +28,5 @@
   (range 0 (.lineCount ed)))

 (defn scroll-into-view!
-  [ed & {:keys [line ch margin] :or {ch 0 margin 60}}]
+  [ed & {:keys [line ch margin] :or {ch 0 margin 0}}]
   (.scrollIntoView ed (clj->js {:line line :ch ch}) margin))


Added a final chord.

Added a final chord.

--- src/overtunes/songs/before.clj
+++ src/overtunes/songs/before.clj
@@ -46,6 +46,11 @@
   (chord :Eb4 :major)
   (chord :Bb3 :major)
   (chord :Bb3 :major)
+])
+
+(def finish [
+  (chord :Eb4 :major)
+  (chord :Eb4 :major)
 ])

 (defn play-chord [notes duration] ( do
@@ -98,7 +103,7 @@
   )
   (play-melody (n-times (/ (count chords) 2.5) melody) metro (metro))
   (play-progression
-    chords
+    (concat chords finish)
     metro
     (metro)
   )


Generate a real do form with emit-clj

Generate a real do form with emit-clj

--- src/oxcart/passes/emit_clj.clj
+++ src/oxcart/passes/emit_clj.clj
@@ -29,4 +29,5 @@
   [{:keys [modules] :as whole-ast} options]
   (->> whole-ast
        util/whole-ast->forms
-       (map emit/emit-form)))
+       (map emit/emit-form)
+       (cons 'do)))


Fixup docstring

Fixup docstring

--- src/puppetlabs/kitchensink/ssl.clj
+++ src/puppetlabs/kitchensink/ssl.clj
@@ -68,7 +68,7 @@

 (defn pem->private-keys
   "Given the path to a PEM file (or some other object supported by clojure's `reader`),
-  decodes the contents into an instance of `PrivateKey`."
+  decodes the contents into a collection of `PrivateKey` instances."
   [pem]
   (map obj->private-key (pem->objs pem)))


Improvement is documentation, ahead of an API release

--- src/re_frame/std_interceptors.cljc
+++ src/re_frame/std_interceptors.cljc
@@ -14,7 +14,9 @@
   "An interceptor which logs data about the handling of an event.

   Includes a `clojure.data/diff` of the db, before vs after, showing
-  the changes caused by the event handler.
+  the changes caused by the event handler.  You absolutely will have
+  to understand https://clojuredocs.org/clojure.data/diff to
+  understand the output.

   You'd typically want this interceptor after (to the right of) any
   path interceptor.
@@ -23,14 +25,14 @@
   can be slow. So, you won't want this interceptor present in production
   code. So condition it out like this:

-    (re-frame.core/reg-event
+    (re-frame.core/reg-event-db
        :evt-id
        [(when ^boolean goog.DEBUG re-frame.core/debug)]  ;; <-- conditional
        (fn [db v]
          ...))

-  You'll also have to set goog.DEBUG to false in your production builds - look
-  in project.clj of /examples/todomvc.
+  To make this code fragment work, you'll also have to set goog.DEBUG to
+  false in your production builds - look in `project.clj` of /examples/todomvc.
   "
   (->interceptor
     :id     :debug
@@ -58,7 +60,7 @@

 (def trim-v
   "An interceptor which removes the first element of the event vector,
-  allowing you to write more aesthetically pleasing db handlers. No
+  allowing you to write more aesthetically pleasing event handlers. No
   leading underscore on the event-v!
   Your event handlers will look like this:

@@ -145,18 +147,28 @@

 (defn path
-  "An interceptor factory which supplies a sub-path of `:db` to the handler.
-  It's action is somewhat analogous to clojure's `update-in`. It grafts the return
-  value from the handler back into db.
-
-  Usage:
+  "An interceptor factory which supplies the value at a sub-path of `db` to
+  the handler, rather than all of `db`.
+  Afterwards, it grafts the handler's return value back into db, at the right path.
+  Its overall action is to make the handler behave like the function you
+  might give to clojure's `update-in`.
+
+  Examples:
     (path :some :path)
     (path [:some :path])
     (path [:some :path] :to :here)
     (path [:some :path] [:to] :here)

+  Example Use:
+
+    (reg-event-db
+      :event-id
+      (path [:a :b])  ;; used here, in interceptor chain
+      (fn [b v]       ;; 1st arg is now not db. Is the value from that path within db
+        ... new-b))      ;; must return a new value for that path (not db)
+
   Notes:
-    1. `path` may appear more than once in an interceptor chain
+    1. `path` may appear more than once in an interceptor chain. Progressive narrowing.
     2. if `:effects` contains no `:db` effect, can't graft a value back in.
   "
   [& args]
@@ -249,13 +261,13 @@
   "Interceptor factory which runs a given function `f` in the \"after\"
   position, presumably for side effects.

-  `f` is called with two arguments: the `effects` value of `:db`
+  `f` is called with two arguments: the `:effects` value for `:db`
   (or the `coeffect` value of db if no db effect is returned) and the event.
-   Its return value is ignored so `f` can only side-effect.
+  Its return value is ignored, so `f` can only side-effect.

   Examples use can be seen in the /examples/todomvc:
      - `f` runs schema validation (reporting any errors found).
-     - `f` writes some aspect of db to localstorage."
+     - `f` writes to localstorage."
   [f]
   (->interceptor
     :id    :after


Improve the formatting of find-symbol.clj

- Tidy up the formatting of find-symbol/node->var

- Use :refer :as instead of :all

- Improve formatting of find-invokes

- Improve formatting of contains-const?

- Improve formatting of find-symbol-in-ast

- Improve formatting on find-symbol-in-file
  - use nil-punning instead of when-not + empty?
  - move the long anonymous fn to the let

- Improve formatting on find-global-symbol

- Refactor find-local-symbol and find-symbol-in-file

- Format find-symbol

- Mapcat is more idiomatic than flatten

- Inline fn-invoked into fns-invoked?
  - Use `contains?` to be more explicit about operating on a set

- Add doc-string to node->var

- Add doc-string to fns-invoked?

- Add doc-string for find-nodes

- Better be explicit about using set as a predicate

- Inline contains-var

- Format find-invokes for better readability
  - Also invoke the set instead of using set? for the fear of breaking
    something.

- Add doc-string for contains-var?

--- src/refactor_nrepl/find_symbol.clj
+++ src/refactor_nrepl/find_symbol.clj
@@ -1,33 +1,38 @@
 (ns refactor-nrepl.find-symbol
   (:require [clojure.string :as str]
-            [clojure.tools.analyzer.ast :refer :all]
+            [clojure.tools.analyzer.ast :refer [nodes]]
             [refactor-nrepl
              [analyzer :refer [ns-ast]]
-             [util :refer :all]]))
+             [util :as util]]))

-(defn- node->var [alias-info node]
-  (let [class (or (:class node) (-> node
-                                    :var
-                                    str
-                                    (str/replace "#'" "")
-                                    (str/replace "clojure.core/" "")))
+(defn- node->var
+  "Returns a fully qualified symbol for vars other those from clojure.core, for
+  which the non-qualified name is returned."
+  [alias-info node]
+  (let [class (or (:class node)
+                  (-> (str (:var node))
+                      (str/replace "#'" "")
+                      (str/replace "clojure.core/" "")))
         full-class (get alias-info class class)]
     (str/join "/" (remove nil? [full-class (:field node)]))))

-(defn- fn-invoked [alias-info node]
-  (node->var alias-info (:fn node)))
+(defn- fns-invoked?
+  "Checks if `node` is a function-call present in `fn-set`."
+  [fn-set alias-info node]
+  (and (= :invoke (:op node))
+       (fn-set (node->var alias-info (:fn node)))))

-(defn- fns-invoked? [fns alias-info node]
-  (and (= :invoke (:op node))
-       (fns (fn-invoked alias-info node))))
+(defn- contains-var?
+  "Checks if the var of `node` is present in the `var-set`."
+  [var-set alias-info node]
+  (var-set (node->var alias-info node)))

-(defn- contains-var? [var-name alias-info node]
-  (var-name (node->var alias-info node)))
-
-(defn- find-nodes [ast pred]
-  (->> ast
-       (map nodes)
-       flatten
+(defn- find-nodes
+  "Filters `ast` with `pred` and returns a list of vectors with line-beg, line-end,
+  colum-beg, column-end and the result of applying pred to the node for each
+  node in the AST."
+  [ast pred]
+  (->> (mapcat nodes ast)
        (filter pred)
        (map (juxt (comp :line :env)
                   (comp :end-line :env)
@@ -39,34 +44,36 @@
   "Finds fn invokes in the AST.
   Returns a list of line, end-line, column, end-column and fn name tuples"
   [ast fn-names]
-  (find-nodes ast (partial fns-invoked? (into #{} (str/split fn-names #",")) (alias-info ast))))
-
-(defn- contains-var [var-name alias-info node]
-  (contains-var? #{var-name} alias-info node))
+  (find-nodes ast
+              #(fns-invoked? (into #{} (str/split fn-names #","))
+                             (util/alias-info ast)
+                             %)))

 (def ^:private symbol-regex #"[\w\.:\*\+\-_!\?]+")

-(defn- contains-const? [var-name alias-info node]
+(defn- contains-const?
+  [var-name alias-info node]
   (let [[ns name] (str/split var-name #"/")
         const-node? (= :const (:op node))
-        node-val-words (when const-node? (->> node
-                                              :val
-                                              str
-                                              (re-seq symbol-regex)
-                                              set))]
+        node-val-words (when const-node?
+                         (->> (str (:val node))
+                              (re-seq symbol-regex)
+                              set))]
     (and const-node?
          (node-val-words ns)
-         (or (not name)
-             (node-val-words name))
+         (or (not name) (node-val-words name))
          var-name)))

 (defn- contains-var-or-const? [var-name alias-info node]
-  (or (contains-var var-name alias-info node)
+  (or (contains-var? #{var-name} alias-info node)
       (contains-const? var-name alias-info node)))

 (defn- find-symbol-in-ast [name ast]
   (when ast
-    (find-nodes ast (partial contains-var-or-const? name (alias-info ast)))))
+    (find-nodes ast
+                (partial contains-var-or-const?
+                         name
+                         (util/alias-info ast)))))

 (defn- match [file-content line end-line]
   (let [line-index (dec line)
@@ -80,22 +87,24 @@

 (defn- find-symbol-in-file [fully-qualified-name file]
   (let [file-content (slurp file)
-        locs (->> file-content
-                  ns-ast
+        locs (->> (ns-ast file-content)
                   (find-symbol-in-ast fully-qualified-name)
-                  (filter #(first %)))]
-    (when-not (empty? locs)
-      (map #(conj % (.getCanonicalPath file) (match file-content (first %) (second %)))
-           locs))))
+                  (filter first))
+        gather (fn [info]
+                 (conj info
+                       (.getCanonicalPath file)
+                       (match file-content
+                              (first info)
+                              (second info))))]
+    (when (seq locs) (map gather locs))))

 (defn- find-global-symbol [file ns var-name clj-dir]
   (let [dir (or clj-dir ".")
-        namespace (or ns (ns-from-string (slurp file)))
+        namespace (or ns (util/ns-from-string (slurp file)))
         fully-qualified-name (if (= namespace "clojure.core")
                                var-name
                                (str/join "/" [namespace var-name]))]
-    (->> dir
-         list-project-clj-files
+    (->> (util/list-project-clj-files dir)
          (mapcat (partial find-symbol-in-file fully-qualified-name))
          (map identity))))

@@ -110,22 +119,33 @@
   {:pre [(number? line)
          (number? column)
          (not-empty file)]}
-  (let [ns-string (slurp file)
-        ast (ns-ast ns-string)]
-    (when-let [form-index (top-level-form-index line column ast)]
+  (let [file-content (slurp file)
+        ast (ns-ast file-content)]
+    (when-let [form-index (util/top-level-form-index line column ast)]
       (let [top-level-form-ast (nth ast form-index)
             local-var-name (->> top-level-form-ast
                                 nodes
-                                (filter #(and (#{:local :binding} (:op %)) (= var-name (-> % :form str)) (:local %)))
-                                (filter (partial node-at-loc? line column))
+                                (filter #(and (#{:local :binding} (:op %))
+                                              (= var-name (-> % :form str))
+                                              (:local %)))
+                                (filter (partial util/node-at-loc? line column))
                                 first
                                 :name)]
-        (->> (find-nodes [top-level-form-ast] #(and (#{:local :binding} (:op %)) (= local-var-name (-> % :name)) (:local %)))
-             (map #(conj (vec (take 4 %)) var-name (.getCanonicalPath (java.io.File. file)) (match ns-string (first %) (second %)))))))))
+        (map #(conj (vec (take 4 %))
+                    var-name
+                    (.getCanonicalPath (java.io.File. file))
+                    (match file-content
+                           (first %)
+                           (second %)))
+             (find-nodes [top-level-form-ast]
+                         #(and (#{:local :binding} (:op %))
+                               (= local-var-name (-> % :name))
+                               (:local %))))))))

 (defn find-symbol [{:keys [file ns name dir line column]}]
-  (throw-unless-clj-file file)
-  (or (when (and file (not-empty file)) (not-empty (find-local-symbol file name line column)))
+  (util/throw-unless-clj-file file)
+  (or (when (and file (not-empty file))
+        (not-empty (find-local-symbol file name line column)))
       (find-global-symbol file ns name dir)))

 (defn create-result-alist


Update da.cljs

Update da.cljs

Major update with new sentences from en.cljs

--- src/status_im/translations/da.cljs
+++ src/status_im/translations/da.cljs
@@ -8,11 +8,23 @@
    :chat-name                             "Chatnavn"
    :notifications-title                   "Notifikationer"
    :offline                               "Offline"
+   :search-for                            "Søg efter..."
+   :cancel                                "Annullér"
+   :next                                  "Næste"
+   :type-a-message                        "Skriv en besked..."
+   :type-a-command                        "Skriv en kommando..."
+   :error                                 "Fejl"
+
+   :camera-access-error                   "Gå venligst til dine systemindstillinger og sørg  for at du Status > Kamera er tilladt."
+   :photos-access-error                   "Gå venligst til dine systemindstillinger og sørg  for at du Status > Billeder er tilladt."

    ;drawer
    :invite-friends                        "Inviter venner"
    :faq                                   "FAQ"
-   :switch-users                          "Skift brugere"
+   :switch-users                          "Skift bruger"
+   :feedback                              "Ryst din telefon for at give os feedback!"
+   :view-all                              "Vis alle"
+   :current-network                       "Nuværende netværk"

    ;chat
    :is-typing                             "skriver"
@@ -21,15 +33,18 @@
    :members                               {:one   "1 medlem"
                                            :other "{{count}} medlemmer"
                                            :zero  "ingen medlemmer"}
-   :members-active                        {:one   "1 medlem, 1 aktiv"
-                                           :other "{{count}} medlemmer, {{count}} aktive"
+   :members-active                        {:one   "1 medlem"
+                                           :other "{{count}} medlemmer"
                                            :zero  "ingen medlemmer"}
+   :public-group-status                   "Offentlig"
    :active-online                         "Online"
    :active-unknown                        "Ukendt"
-   :available                             "Tilgængelig"
+   :available                             "Til stede"
    :no-messages                           "Ingen beskeder"
    :suggestions-requests                  "Anmodninger"
-   :suggestions-commands                  "kommandoer"
+   :suggestions-commands                  "Kommandoer"
+   :faucet-success                        "Faucet request er modtaget"
+   :faucet-error                          "Faucet request fejl"

    ;sync
    :sync-in-progress                      "Synkroniserer..."
@@ -45,6 +60,7 @@
    :status-failed                         "Mislykket"

    ;datetime
+   :datetime-ago-format                   "{{number}} {{time-intervals}} {{ago}}"
    :datetime-second                       {:one   "sekund"
                                            :other "sekunder"}
    :datetime-minute                       {:one   "minut"
@@ -60,6 +76,7 @@

    ;profile
    :profile                               "Profil"
+   :edit-profile                          "Rediger profil"
    :report-user                           "Anmeld bruger"
    :message                               "Meddelelser"
    :username                              "Brugrenavn"
@@ -67,8 +84,16 @@
    :public-key                            "Offentlig nøgle"
    :phone-number                          "Telefonnummer"
    :email                                 "Email"
+   :update-status                         "Opdater din status..."
+   :add-a-status                          "Tilføj en status..."
+   :status-prompt                         "Lav en status for at lade folk vide hvad du tilbyder. Du kan også bruge #hashtags."
    :profile-no-status                     "Ingen status"
-   :add-to-contacts                       "Tilføg til kontakter"
+   :add-to-contacts                       "Tilføj til kontakter"
+   :in-contacts                           "I kontakter"
+   :remove-from-contacts                  "Fjern fra kontakter"
+   :start-conversation                    "Begynd samtale"
+   :send-transaction                      "Send transaktion"
+   :share-qr                              "Del QR-kode"
    :error-incorrect-name                  "Fejl: Forkert navn"
    :error-incorrect-email                 "Fejl: Forkert email"

@@ -77,6 +102,16 @@
    :image-source-make-photo               "Tag billede"
    :image-source-gallery                  "Vælg fra galleri"
    :image-source-cancel                   "Afbryd"
+
+   ;;sharing
+   :sharing-copy-to-clipboard             "Kopier til udklipsholderen"
+   :sharing-share                         "Del..."
+   :sharing-cancel                        "Annullér"
+
+   :browsing-title                        "Browse"
+   :browsing-browse                       "@browse"
+   :browsing-open-in-web-browser          "Åben i web browser"
+   :browsing-cancel                       "Annullér"

    ;sign-up
    :contacts-syncronized                  "Dine kontakter er synkroniseret"
@@ -88,14 +123,30 @@
    :here-is-your-passphrase               "Her er din kodesætning (passphrase), *skriv den ned og gem den sikkert!* Du behøver den for at gendanne din konto."
    :written-down                          "Sørg for at du har skrevet den sikkert ned"
    :phone-number-required                 "Klik her for at indtaste dit telefonnummer, så vil jeg finde dine venner"
+   :shake-your-phone                      "Fundet en bug eller har du et foreslag. Blot ryst din telefon!"
    :intro-status                          "Chat med mig for at opsætte din konto og ændre dine indstillinger!!"
    :intro-message1                        "Velkommen til Status\n Tryk på denne meddelelse for at angive din adgangskode og komme i gang!"
    :account-generation-message            "Vent et øjeblik, jeg er nødt til at gøre nogle skøre beregninger for at generere din konto!"
+   :move-to-internal-failure-message      "Vi skal flyyte nogle vigtige filer fra din eksterne til din interne hukommelse. For at gøre dette har vi brug for din tilladelse. Vi vil ikke bruge din eksterne hukkomelse i kommende versioner."
+   :debug-enabled                         "Debug server has been launched! You can now execute *status-dev-cli scan* to find the server from your computer on the same network."
+
+   ;phone types
+   :phone-e164                            "International 1"
+   :phone-international                   "International 2"
+   :phone-national                        "National"
+   :phone-significant                     "Significant"

    ;chats
-   :chats                                 "Chats"
-   :new-chat                              "Ny chat"
-   :new-group-chat                        "Ny gruppchat"
+   :chats                                 "Samtale"
+   :new-chat                              "Ny samtale"
+   :delete-chat                           "Fjern samtale"
+   :new-group-chat                        "Ny gruppsamtale"
+   :new-public-group-chat                  "Deltag i offentlig samtale"
+   :edit-chats                            "Rediger samtaler"
+   :search-chats                          "Søg samtaler"
+   :empty-topic                           "Tomt emne"
+   :topic-format                          "Forkert format [a-z0-9\\-]+"
+   :public-group-topic                    "Emne"

    ;discover
    :discover                              "Opdag"
@@ -104,6 +155,7 @@
    :popular-tags                          "Populære tags"
    :recent                                "Seneste"
    :no-statuses-discovered                "Ingen statusser opdaget"
+   :no-statuses-found                     "Inger statusser fundet"

    ;settings
    :settings                              "Indstillinger"
@@ -111,18 +163,29 @@
    ;contacts
    :contacts                              "Kontakter"
    :new-contact                           "Ny kontakt"
+   :delete-contact                        "Fjern kontakt"
+   :delete-contact-confirmation           "Denne kontakt vil blive fjernet fra dine kontakter"
+   :remove-from-group                     "Fjern fra gruppe"
+   :edit-contacts                         "Rediger kontakter"
+   :search-contacts                       "Søg efter kontakter"
    :show-all                              "Vis alle"
    :contacts-group-dapps                  "ÐApps"
    :contacts-group-people                 "Mennesker"
    :contacts-group-new-chat               "Start en ny chat"
+   :choose-from-contacts                  "Vælg fra kontakter"
    :no-contacts                           "Ingen kontakter endnu"
    :show-qr                               "Vis QR-kode"
+   :enter-address                         "Indtast adresse"
+   :more                                  "mere"

    ;group-settings
    :remove                                "Fjern"
    :save                                  "Gem"
+   :delete                                "Slet"
    :change-color                          "Ændre farve"
    :clear-history                         "Fjern historik"
+   :mute-notifications                    "Sluk for notifikationer"
+   :leave-chat                            "Forlad samtale"
    :delete-and-leave                      "Slet og forlad"
    :chat-settings                         "Chatindstillinger"
    :edit                                  "Rediger"
@@ -152,7 +215,16 @@
    :group-chat-name                       "Gruppechat navn"
    :empty-group-chat-name                 "Angiv et navn"
    :illegal-group-chat-name               "Vælg venligst et andet navn"
-
+   :new-group                             "Ny gruppe"
+   :reorder-groups                        "Arranger grupper"
+   :group-name                            "Gruppenavn"
+   :edit-group                            "Rediger gruppe"
+   :delete-group                          "Slet gruppe"
+   :delete-group-confirmation             "Denne gruppe vil blivve fjernet fra dine grupper. Dette vil ikke påvirke dine kontakter."
+   :delete-group-prompt                   "Dette vil ikke påvirke dine kontakter"
+   :group-members                         "Gruppemedlemmer"
+   :contact-s                             {:one   "kontakt"
+                                           :other "kontakter"}
    ;participants
    :add-participants                      "Tilføj deltagere"
    :remove-participants                   "Fjern deltagere"
@@ -169,20 +241,24 @@
    :add-new-contact                       "Tilføj ny kontakt"
    :import-qr                             "Importer QR-kode"
    :scan-qr                               "Skan QR-kode"
+   :swow-qr                               "Vis QR"
    :name                                  "Navn"
    :whisper-identity                      "Whisper identitet"
-   :address-explication                   ""
-   :enter-valid-address                   "Indtast en gyldig adresse eller scan en QR-kode"
+   :address-explication                   "Maybe here should be some text explaining what an address is and where to look for it"
+   :enter-valid-address                   "Indtast venligst en gyldig adresse eller scan en QR-kode"
+   :enter-valid-public-key                "Indtast venligst en gyldig offentlig nøgle eller scan en QR-kode"
    :contact-already-added                 "Kontakten er allerede tilføjet"
-   :can-not-add-yourself                  "Du kan ikke tilføje dig selv"
+   :can-not-add-yourself                  "Du kan ikke tilføje dig selv fjolle"
    :unknown-address                       "Ukendt adresse"

    ;login
    :connect                               "Tilslut"
-   :address                               "adresse"
+   :address                               "Adresse"
    :password                              "Kodeord"
    :login                                 "Login"
+   :sign-in-to-status                     "Log på Status"
+   :sign-in                               "Log på"
    :wrong-password                        "Forkert kodeord"

    ;recover
@@ -192,10 +268,12 @@
    :recover                               "Gendan"
    :enter-valid-passphrase                "Angiv korrekt kodesætning (passphrase)"
    :enter-valid-password                  "Angiv korrekt kodeord"
+   :twelve-words-in-correct-order         "12 ord i den korrekte rækkefølge"

    ;accounts
    :recover-access                        "Gendan adgang"
    :add-account                           "Tilføj konto"
+   :create-new-account                    "Lav ny konto"

    ;wallet-qr-code
    :done                                  "Klar"
@@ -207,15 +285,30 @@
    :not-enough-eth                        (str "'Ikke tilstrækkeligt ETH på kontoen "
                                                "({{balance}} ETH)")
    ;transactions
+   :confirm                               "Bekræft"
    :confirm-transactions                  {:one   "Bekræft transaktionen"
                                            :other "Bekræft {{count}} transaktioner"
                                            :zero  "Ingen transaktioner"}
+   :transactions-confirmed                {:one   "Transaktionen bekræftet"
+                                           :other "{{count}} transaktioner bekræftet"
+                                           :zero  "Ingen transaktioner bekræftet"}
+   :transaction                           "Transaktion"
+   :unsigned-transactions                 "Usignerede transaktioner"
+   :no-unsigned-transactions              "Ingen usignerede transaktioner"
+   :enter-password-transactions           {:one   "Bekræft transaktionen ved at indtaste dit kodeord"
+                                           :other "Bekræft transaktionerne ved at indtaste dit kodeord"}
    :status                                "Status"
    :pending-confirmation                  "Venter på bekræftelse"
    :recipient                             "Modtager"
    :one-more-item                         "En ting til"
    :fee                                   "Gebyr"
+   :estimated-fee                         "Forventet gebyr"
    :value                                 "Værdi"
+   :to                                    "Til"
+   :from                                  "Fra"
+   :data                                  "Data"
+   :got-it                                "Forstået"
+   :contract-creation                     "Kontraktoprettelse"

    ;:webview
    :web-view-error                        "hovsa, fejl"})


Fixes test failing due to ns loading.

Fixes test failing due to ns loading.

--- test/onyx/peer/multi_peer_test.clj
+++ test/onyx/peer/multi_peer_test.clj
@@ -53,7 +53,7 @@
     :hornetq/batch-size 2
     :hornetq/timeout 50}
    {:onyx/name :inc
-    :onyx/fn :onyx.coordinator.single-peer-test/my-inc
+    :onyx/fn :onyx.coordinator.multi-peer-test/my-inc
     :onyx/type :transformer
     :onyx/consumption :concurrent
     :onyx/batch-size 2


Authenticating on callback, using callbacks to log events, and bringing back async take

--- test/time_tracker/test_helpers.clj
+++ test/time_tracker/test_helpers.clj
@@ -6,6 +6,7 @@
             [gniazdo.core :as ws]
             [clojure.test :as test]
             [clojure.spec.test :as stest]
+            [time-tracker.logging :as log]
             [time-tracker.util :as util]))

 (defn http-request-raw
@@ -30,21 +31,38 @@

 (defn try-take!!
   [channel]
-  (async/<!! channel))
+  (alt!!
+    channel ([value] value)
+    (async/timeout 10000) (throw (ex-info "Take from channel timed out" {:channel channel}))))

 (defn make-ws-connection
   "Opens a connection and completes the auth handshake."
   [google-id]
   (let [response-chan (chan 5)
-        socket        (ws/connect "ws://localhost:8000/api/timers/ws-connect/"
-                                  :on-receive #(put! response-chan
-                                                     (json/decode % keyword)))]
-    (ws/send-msg socket (json/encode
-                         {:command "authenticate"
-                          :token   (json/encode {:sub google-id})}))
+        socket        (promise)]
+
+    (deliver socket (ws/connect "ws://localhost:8000/api/timers/ws-connect/"
+                                :on-receive (fn [data]
+                                              (log/debug {:event ::received-ws-data
+                                                          :data  data})
+                                              (put! response-chan (json/decode data keyword)))
+                                :on-close (fn on-close [status desc]
+                                            (log/debug {:event       ::closed-ws-connection
+                                                        :status      status
+                                                        :description desc}))
+                                :on-error (fn [ex]
+                                            (log/error ex {:event ::ws-error}))
+                                :on-connect (fn [_]
+                                              (log/debug {:event ::established-ws-connection})
+                                              (ws/send-msg @socket
+                                                           (json/encode
+                                                            {:command "authenticate"
+                                                             :token   (json/encode {:sub google-id})}))
+                                              (log/debug {:event ::sent-authentication-message}))))
+
     (if (= "success"
            (:auth-status (try-take!! response-chan)))
-      [response-chan socket]
+      [response-chan @socket]
       (throw (ex-info "Authentication failed" {})))))

 (defn- num-tests-from-config []


More string tests

More string tests

--- test/yada/string_resource_test.clj
+++ test/yada/string_resource_test.clj
@@ -45,9 +45,8 @@
       (given response
         :status := 200
         :headers :> {"content-length" (count "Hello World!")}
-        :body :? string?)
+        :body :? string?)))

-      ))

   (testing "if-last-modified"
     (time/do-at (time/minus (time/now) (time/days 6))
@@ -71,4 +70,17 @@
                 response @(handler request)]

             (given response
-              :status := 304)))))))
+              :status := 304))))))
+
+  (testing "safe-by-default"
+    (let [resource "Hello World!"
+          handler (yada resource)]
+
+      (given @(handler (request :put "/"))
+        :status := 405)
+      (given @(handler (request :post "/"))
+        :status := 405)))
+
+  ;; OPTIONS
+
+  )


Adding backend dependencies

Adding backend dependencies

--- zambuko-back/project.clj
+++ zambuko-back/project.clj
@@ -2,6 +2,7 @@
   :description "FIXME: write description"
   :url "http://example.com/FIXME"
   :dependencies [[org.clojure/clojure "1.5.1"]
+                 [clj-time "0.5.1"]
                  [lib-noir "0.6.6"]
                  [compojure "1.1.5"]
                  [ring-server "0.2.8"]
@@ -10,8 +11,10 @@
                  [com.postspectacular/rotor "0.1.0"]
                  [com.taoensso/tower "1.7.1"]
                  [markdown-clj "0.9.28"]
+                 [com.novemberain/monger "1.5.0"]
                  [org.jclouds/jclouds-allblobstore "1.6.0"]
                  [org.hornetq/hornetq-core-client "2.3.3.Final"]
+                 [com.cemerick/friend "0.1.5" :exclusions [com.google.inject/guice]]
                  [org.activiti/activiti-engine "5.13"]
                  [org.clojure/tools.nrepl "0.2.3"]]
   :plugins [[lein-ring "0.8.5"]]


delete old ns

delete old ns

--- src/re_frame_http_fx/core.cljs
+++ src/re_frame_http_fx/core.cljs
@@ -1,67 +0,0 @@
-(ns re-frame-http-fx.core
-  (:require
-    [goog.net.ErrorCode :as errors]
-    [re-frame.core      :refer [def-fx dispatch console]]
-    [ajax.core          :as ajax]
-    [cljs.spec          :as s]))
-
-;; I provide the :http-xhrio effect handler leveraging cljs-ajax lib
-;; see API docs https://github.com/JulianBirch/cljs-ajax
-;; Note we use the ajax-request.
-;;
-;; Deviation from cljs-ajax options in request
-;; :handler       - not supported, see :on-success and :on-failure
-;; :on-success    - event vector dispatched with result
-;; :on-failure    - event vector dispatched with result
-;;
-;; NOTE: if you nee tokens or other values for your handlers,
-;;       provide them in the on-success and on-failure event e.g.
-;;       [:success-event "my-token"] your handler will get event-v
-;;       [:success-event "my-token" result]
-
-
-(defn ajax-xhrio-handler
-  "ajax-request only provides a single handler for success and errors"
-  [on-success on-failure xhrio [success? response]]
-  ; see http://docs.closure-library.googlecode.com/git/class_goog_net_XhrIo.html
-  (if success?
-    (on-success response)
-    (let [details (merge
-                    {:uri             (.getLastUri xhrio)
-                     :last-method     (.-lastMethod_ xhrio)
-                     :last-error      (.getLastError xhrio)
-                     :last-error-code (.getLastErrorCode xhrio)
-                     :debug-message   (-> xhrio .getLastErrorCode (errors/getDebugMessage))}
-                    response)]
-      (on-failure details))))
-
-
-(defn request->xhrio-options
-  [{:as   request
-    :keys [on-success on-failure]
-    :or   {on-success      [:http-no-on-success]
-           on-failure      [:http-no-on-failure]}}]
-  ; wrap events in cljs-ajax callback
-  (let [api (new js/goog.net.XhrIo)]
-  (-> request
-      (assoc
-        :api     api
-        :handler (partial ajax-xhrio-handler
-                          #(dispatch (conj on-success %))
-                          #(dispatch (conj on-failure %))
-                          api))
-      (dissoc :on-success :on-failure))))
-
-(s/def ::sequential-or-map (s/or :list-or-vector sequential? :map map?))
-
-(def-fx
-  :http-xhrio
-  (fn http-effect [request]
-    (when (= :cljs.spec/invalid (s/conform ::sequential-or-map request))
-      (console :error (s/explain-str ::sequential-or-map request)))
-    ;;TODO verify detail request(s) using spec for ajax-request api
-    (cond
-      (sequential? request) (doseq [each request] (http-effect each))
-      (map? request)        (-> request request->xhrio-options ajax/ajax-request)
-      :else
-      (console :error "re-frame-http-fx: expected request to be a list or vector or map, but got: " request))))


- Relations over weaver's ProgramElement hierarchy are now private to the weaver namespace. - New relations between types and their members.

--- EkekoAspectJ/src/damp/ekeko/aspectj/weaverworld.clj
+++ EkekoAspectJ/src/damp/ekeko/aspectj/weaverworld.clj
@@ -70,10 +70,12 @@

 ;; ProgramElement hierarchy
-;; (but prefer not to use these)
-;; -----------------------------
-
-(defn
+;; ------------------------
+
+;; Prefer not to expose these relations, as the hierarchy is still managed by the facade created by AsmRelationshipProvider
+
+
+(defn-
   root
   "Relation of ProgramElement hierarchy roots."
   [?element]
@@ -83,7 +85,7 @@

 (clojure.core/declare element)

-(defn
+(defn-
   element-child
   "Relation of roots of the weaver world ProgramElement hierarchy."
   [?element ?child-element]
@@ -91,7 +93,7 @@
     (element ?element)
     (contains (.getChildren ?element) ?child-element)))

-(defn
+(defn-
   element-child+
   "Relation between a ProgramElement ?element and one of its descendants ?child."
   [?element ?child]
@@ -100,7 +102,7 @@
          (conde [(== ?ch ?child)]
                 [(element-child+ ?ch ?child)])))

-(defn
+(defn-
   element
   "Relation of elements of the ProgramElement hierarchy."
   [?element]
@@ -113,7 +115,7 @@
             (conde [(== ?element ?root)]
                    [(element-child+ ?root ?element)]))]))

-(defn
+(defn-
   element-parent
   "Relation between a ProgramElement and its parent ProgramElement."
   [?element ?parent]
@@ -122,7 +124,7 @@
     (equals ?parent (.getParent ?element))))

-(defn
+(defn-
   element-kind
   "Relation between a ProgramElement ?element and its kind ?kind."
   [?element ?kind]
@@ -131,7 +133,7 @@
     (equals ?kind (.getKind ?element))))

 ;note that these are not JVM signature strings, as produced for ResolvedType hierarchy
-(defn
+(defn-
   element-signature
   "Relation between a ProgramElement and its signature string."
   [?element ?signature]
@@ -139,7 +141,7 @@
     (element ?element)
     (equals ?signature (.toSignatureString ?element))))

-(defn
+(defn-
   element-handle
   "Relation between a ProgramElement and its handle."
   [?element ?handle]
@@ -147,7 +149,7 @@
     (element ?element)
     (equals ?handle (.getHandleIdentifier ?element))))

-(defn
+(defn-
   element-sourcelocation
   "Relation between a ProgramElement and its SourceLocation."
   [?element ?handle]
@@ -190,7 +192,7 @@
                 (recur (.getParent parent)))))]
          (ancestortypedeclaration (.getParent element))))

-(defn
+(defn-
   element-enclosingtypedeclaration-element
   "Relation between a ProgramElement and its enclosing aspect (if any)."
   [?element ?typedeclaration]
@@ -199,21 +201,21 @@
     (equals ?typedeclaration (enclosingtypedeclaration-of-element ?element))
     (!= nil ?typedeclaration)))

-(defn
+(defn-
   elementaspect
   [?element]
   (all
     (element ?element)
     (equals (IProgramElement$Kind/ASPECT) (.getKind ?element))))

-(defn
+(defn-
   elementclass
   [?element]
   (all
     (element ?element)
     (equals (IProgramElement$Kind/CLASS) (.getKind ?element))))

-(defn
+(defn-
   elementinterface
   [?element]
   (all
@@ -221,14 +223,14 @@
     (equals (IProgramElement$Kind/INTERFACE) (.getKind ?element))))

-(defn
+(defn-
   elementenum
   [?element]
   (all
     (element ?element)
     (equals (IProgramElement$Kind/ENUM) (.getKind ?element))))

-(defn
+(defn-
   elementtypedeclaration
   [?element]
   (conde
@@ -237,18 +239,16 @@
     [(elementaspect ?element)]
     [(elementinterface ?element)]))

-
-
-;above is about programelement hierarchy, which is still managed by facade
-;created by AsmRelationshipProvider

 ;; Actual Reification of WeaverWorld
 ;; ---------------------------------
+

 (defn-
   weaverworld-typemap
   "Relation between an AspectJ weaverworld and its non-expandable TypeMap."
   [?world ?typemap]
+  ;see org.aspectj.weaver.World$TypeMap, consider configuring TypeMap.DONT_USE_REFS to avoid the weaver from discarding expandable types.
   (all
     (weaverworld ?world)
     (equals ?typemap (-> ?world .getTypeMap .getMainMap))))
@@ -256,12 +256,16 @@

 (defn
   type
-  "Relation of non-expandable (i.e., project-defined) types known to the AspectJ weaver."
+  "Relation of non-expandable types known to the AspectJ weaver.
+   Instances of org.aspectj.weaver.ResolvedType."
   [?resolvedtype]
-  (fresh [?world ?map ?entry]
-       (weaverworld-typemap ?world ?map)
-       (contains ?map ?entry)
-       (equals ?resolvedtype (.getValue ?entry))))
+  (conda [(v+ ?resolvedtype)
+          (succeeds (instance? org.aspectj.weaver.ResolvedType ?resolvedtype))]
+         [(v- ?resolvedtype)
+          (fresh [?world ?map ?entry]
+                 (weaverworld-typemap ?world ?map)
+                 (contains ?map ?entry)
+                 (equals ?resolvedtype (.getValue ?entry)))]))

 (defn
@@ -298,51 +302,20 @@
     (succeeds (.isEnum ?resolvedtype))))

 (defn
-  nested
+  nestedtype
   "Relation of nested types known to the AspectJ weaver.
    This includes: member classes, local classes, anonymous classes."
   [?resolvedtype]
   (all
     (type ?resolvedtype)
     (succeeds (.isNested ?resolvedtype))))
-
-
-

-;can be used to go from xcut to weaverworld types
-;NO: because need JVM signature rather than what is returned by the xcut elements
-;(defn
-;  weaverworld-signature-resolvedtype
-;  "Non-relational. Unifies ?resolved-type with the type known to the AspectJ weaver
-;   ?world with the given ?signature string.
-;
-;   Can be used to go from XCut types to weaver world types."
-;  [?world ?signature ?resolved-type]
-;  (equals ?resolved-type (.resolve ?world ?signature)))
-
-(defn
-  element-type
-  "Relation between a ProgramElement of kind Aspect/Enum/Class/Interface
-   and the ResolvedType instance from the weaver world it corresponds to."
-  [?element ?type]
-  (fresh [?element-name] ;todo: take correct world into account
-         (elementtypedeclaration ?element)
-         (equals ?element-name (str (.getPackageName ?element) "." (.getName ?element))) ;todo: check what this returns for parameterized types
-         (type ?type)
-         (equals ?element-name (.getName ?type)))) ;or .getBaseName if above includes type parameters
-
 (defn
   aspect
   "Relation of aspects known to the weaver."
   [?aspect]
   (all
-    ;;would normally use a conda here, but gives an exception in type
-    ;;even though ?aspect is untouched in the first condition of each clause
-    (conde
-      [(v+ ?aspect)
-       (succeeds (instance? ReferenceType ?aspect))]
-      [(v- ?aspect)
-       (type ?aspect)])
+    (type ?aspect)
     (succeeds (.isAspect ?aspect))))

 (defn
@@ -371,61 +344,156 @@

 (defn
   type-fields
-  "Relation between a type and its fields as known to the weaver."
+  "Relation between a type and its declared fields as known to the weaver.
+   For fields that do not declare a field, ?fields==[]."
   [?resolvedtype ?fields]
   (all
     (type ?resolvedtype)
-    (equals ?fields (.getDeclaredFields ?resolvedtype))))
+    (equals ?fields (vec (.getDeclaredFields ?resolvedtype)))))
+
+(defn
+  type-fields+
+  "Relation between a type and all of its declared and inherited fields (as known to the weaver)."
+  ;;see org.apectj.weaver.ResolvedType.getFields()
+  [?resolvedtype ?fields]
+  (all
+    (type ?resolvedtype)
+    (equals ?fields (vec (iterator-seq (.getFields ?resolvedtype))))))

 (defn
   type-field
-  "Relation between a type and one of its fields as known to the weaver."
+  "Relation between a type and one of its declared fields as known to the weaver."
   [?resolvedtype ?field]
   (fresh [?fields]
     (type-fields ?resolvedtype ?fields)
     (contains ?fields ?field)))

+(defn
+  type-field+
+  "Relation between a type and one of its declared or inherited fields (as known to the weaver).
+
+  e.g., inherited fields:
+  (damp.ekeko/ekeko* [?t ?f]
+                  (type-field+ ?t ?f)
+                  (fails
+                    (type-field ?t ?f)))"
+  [?resolvedtype ?field]
+  (fresh [?fields]
+    (type-fields+ ?resolvedtype ?fields)
+    (contains ?fields ?field)))
+
+(defn
+  field
+  "Relation of field members known to the weaver."
+  [?field]
+  (fresh [?type]
+         (type-field ?type ?field)))

 (defn
   type-methods
-  "Relation between a type and its methods as known to the weaver."
+  "Relation between a type and its declared methods as known to the weaver."
   [?resolvedtype ?methods]
   (all
     (type ?resolvedtype)
-    (equals ?methods (.getDeclaredMethods ?resolvedtype))))
+    (equals ?methods (vec (.getDeclaredMethods ?resolvedtype)))))
+
+
+;TODO: configured not to erase generic types (first boolean),
+;      and not to consider declare parent itds
+;      -> current reasoning: no equivalent for fields+
+;
+;      might want to reconsider
+;      (note that there is also an unrelated ITD getter)
+(defn
+  type-methods+
+  "Relation between a type and all of its declared and inherited methods (as known to the weaver).
+   Does not include methods added through an ITD."
+  ;;see org.apectj.weaver.ResolvedType.getMethods(boolean wantGenerics, boolean wantDeclaredParents)
+  [?resolvedtype ?methods]
+  (all
+    (type ?resolvedtype)
+    (equals ?methods (vec (iterator-seq (.getMethods ?resolvedtype true false))))))

 (defn
   type-method
-  "Relation between a type and one of its methods as known to the weaver."
+  "Relation between a type and one of its declared methods as known to the weaver."
   [?resolvedtype ?method]
   (fresh [?methods]
     (type-methods ?resolvedtype ?methods)
     (contains ?methods ?method)))

+(defn
+  type-method+
+  "Relation between a type and one of its declared or inherited methods (as known to the weaver)."
+  [?resolvedtype ?method]
+  (fresh [?methods]
+    (type-methods+ ?resolvedtype ?methods)
+    (contains ?methods ?method)))
+
+
+(defn
+  method
+  "Relation of method members known to the weaver."
+  [?method]
+  (fresh [?type]
+         (type-method ?type ?method)))
+
+
+
+(clojure.core/declare type-pointcutdefinition)
+
+
+(defn
+  type-member
+  "Relation between a type and one of its declared members (i.e., a field / method / pointcutdefinition)."
+  [?type ?member]
+  (all
+    (type ?type)
+    (conde [(type-method ?type ?member)]
+           [(type-field ?type ?member)]
+           [(type-pointcutdefinition ?type ?member)]
+           ;[(type-intertype ?type ?member)] not a subtype of ResolvedMember
+           )))
+
+
+(defn
+  member
+  "Relation of declared members known to the weaver."
+  [?member]
+  (conda
+    [(v+ ?member)
+     (succeeds (instance? org.aspectj.weaver.ResolvedMember ?member))]
+    [(v- ?member)
+     (fresh [?type]
+            (type-member ?type ?member))]))
+
+;(defn
+;  type-member
+;  "Relation between a type and one of its declared members as known to the weaver."
+
+
+
 (defn-
   resolvedmember-synthetic?
   [?resolvedmember ?syntheticbool]
   (all
+    (member ?resolvedmember)
     (equals ?syntheticbool (.isSynthetic ?resolvedmember))))

 (defn
   syntheticmember
-  "Non-relational.
-   Succeeds for ResolvedMember instances (e.g., fields / methods of a type) that are synthetic."
+  "Relation of synthetic members."
   [?resolvedmember]
   (all
-     (resolvedmember-synthetic? ?resolvedmember true)))
-
+    (resolvedmember-synthetic? ?resolvedmember true)))
+
 (defn
   nonsyntheticmember
-  "Non-relational.
-   Succeeds for ResolvedMember instances (e.g., fields / methods of a type) that are non-synthetic."
+  "Relation of nonsynethic members."
   [?resolvedmember]
   (all
      (resolvedmember-synthetic? ?resolvedmember false)))
-
-

 (defn
@@ -699,6 +767,13 @@
   (all
     (intertype ?intertype)
     (equals ?aspect (.getAspectType ?intertype))))
+
+
+(def
+  ^{:doc "Alias for aspect-intertype."}
+  type-intertype
+  aspect-intertype)
+

 ;changed in order to be analogous to aspect-advice
 ;(defn
@@ -723,6 +798,7 @@
             (equals ?set (.getCrosscuttingMembersSet ?world))
             (conde [(contains (.getTypeMungers ?set) ?intertype)]
                    [(contains (.getLateTypeMungers ?set) ?intertype)]))]))
+

 ;(defn
 ;  intertype
@@ -868,15 +944,37 @@
 ;; --------------------

 (defn
+  aspect-pointcutdefinitions
+  "Relation between an aspect and its declared pointcutdefinitions.
+   Note that these are instances of ResolvedPointcutDefinition,
+   rather than the Pointcut instances within ShadowMungers (advice)."
+  [?aspect ?pointcutdefinitions]
+  (all
+    (aspect ?aspect)
+    (equals ?pointcutdefinitions (.getDeclaredPointcuts ?aspect))))
+
+(def
+  ^{:doc "Alias for aspect-pointcutdefinitions."}
+  type-pointcutdefinitions
+  aspect-pointcutdefinitions)
+
+
+
+(defn
   aspect-pointcutdefinition
   "Relation between an aspect and one of the pointcuts it declares.
    Note that these are instances of ResolvedPointcutDefinition,
    rather than the Pointcut instances within ShadowMungers (advice)."
   [?aspect ?pointcutdefinition]
-  (all
-    (aspect ?aspect)
-    (contains (.getDeclaredPointcuts ?aspect) ?pointcutdefinition)
-    ))
+  (fresh [?pointcutdefinitions]
+         (aspect-pointcutdefinitions ?aspect ?pointcutdefinitions)
+         (contains ?pointcutdefinitions ?pointcutdefinition)))
+
+
+(def
+  ^{:doc "Alias for aspect-pointcutdefinition."}
+  type-pointcutdefinition
+  aspect-pointcutdefinition)

 (defn
   pointcutdefinition
@@ -1061,7 +1159,37 @@
            (fails (aspect-dominates-aspect-explicitly+ ?subordinate ?dominator)))))

+
+
+;; Link between ProgramElement (weaverworld/element) and ResolvedType (weaverworld/type)
+;; -------------------------------------------------------------------------------------
+
+;can be used to go from xcut to weaverworld types
+;NO: because need JVM signature rather than what is returned by the xcut elements
+;(defn
+;  weaverworld-signature-resolvedtype
+;  "Non-relational. Unifies ?resolved-type with the type known to the AspectJ weaver
+;   ?world with the given ?signature string.
+;
+;   Can be used to go from XCut types to weaver world types."
+;  [?world ?signature ?resolved-type]
+;  (equals ?resolved-type (.resolve ?world ?signature)))
+
+(defn
+  element-type
+  "Relation between a ProgramElement of kind Aspect/Enum/Class/Interface
+   and the ResolvedType instance from the weaver world it corresponds to."
+  [?element ?type]
+  (fresh [?element-name] ;todo: take correct world into account
+         (elementtypedeclaration ?element)
+         (equals ?element-name (str (.getPackageName ?element) "." (.getName ?element))) ;todo: check what this returns for parameterized types
+         (type ?type)
+         (equals ?element-name (.getName ?type)))) ;or .getBaseName if above includes type parameters
+
+
+
 ;; Link between World (aka weaverworld) and AJProjectModelFacade (aka xcut)
+;; ------------------------------------------------------------------------

 (defn
   weaverworld-xcut


install devtools prettyprint override

install devtools prettyprint override

https://github.com/binaryage/cljs-devtools

--- src/sierpinski_sieve/core.cljs
+++ src/sierpinski_sieve/core.cljs
@@ -1,11 +1,9 @@
 (ns sierpinski-sieve.core
-  (:require [reagent.core :as reagent :refer [atom]]))
+  (:require [devtools.core :as devtools]
+            [reagent.core :as reagent :refer [atom]]))

 (enable-console-print!)
-
-(println "This text is printed from src/sierpinski-sieve/core.cljs. Go ahead and edit it and see reloading in action.")
-
-;; define your app data so that it doesn't get over-written on reload
+(devtools/install!)

 (defonce app-state (atom {:text "Hello world!"}))


Locks: housekeeping

Locks: housekeeping

--- src/taoensso/carmine/locks.clj
+++ src/taoensso/carmine/locks.clj
@@ -13,10 +13,7 @@

 (utils/defonce* config "Alpha - subject to change."
   (atom {:conns {:pool (car/make-conn-pool)
-                 :spec (car/make-conn-spec)}
-         ;; :defaults {:lock-timeout-ms 2000
-         ;;            :wait-timeout-ms 500}
-         }))
+                 :spec (car/make-conn-spec)}}))

 (defn set-config! [[k & ks] val] (swap! config assoc-in (cons k ks) val))

@@ -25,11 +22,10 @@
   `(let [{pool# :pool spec# :spec} (:conns @config)]
      (car/with-conn pool# spec# ~@body)))

-;;(def ^:private lkey (memoize (car/make-keyfn "carmine" "lock")))
-(defn- lkey [lock-name] (str "carmine:lock:" (name lock-name)))
+(def ^:private lkey (car/make-keyfn "carmine" "lock"))

 (defn acquire-lock
-  "Attempts to acquire a distributed lock, returning owner's UUID iff successful."
+  "Attempts to acquire a distributed lock, returning an owner UUID iff successful."
   [lock-name lock-timeout-ms wait-timeout-ms]
   (let [max-udt (+ wait-timeout-ms (System/currentTimeMillis))
         uuid    (str (java.util.UUID/randomUUID))]
@@ -56,15 +52,15 @@
   "Attempts to release a distributed lock, returning true iff successful."
   [lock-name owner-uuid]
   (-> (car/lua-script
-       "if redis.call('get', _:lkey) == _:uuid then
+        "if redis.call('get', _:lkey) == _:uuid then
          redis.call('del', _:lkey)
          return 1
        else
          return 0
        end"
-       {:lkey (lkey lock-name)}
-       {:uuid owner-uuid})
-      car/parse-bool wcar))
+        {:lkey (lkey lock-name)}
+        {:uuid owner-uuid})
+       car/parse-bool wcar))

 (comment
   (when-let [uuid (acquire-lock "my-lock" 2000 500)]