* src/cljs/cljs/reader.cljs: remove coercive-not & coercive-not= from reader.cljs

--- src/cljs/cljs/reader.cljs
+++ src/cljs/cljs/reader.cljs
@@ -72,9 +72,9 @@
   (throw (js/Error. (apply str msg))))

 (defn ^boolean macro-terminating? [ch]
-  (and (coercive-not= ch "#")
-       (coercive-not= ch \')
-       (coercive-not= ch ":")
+  (and (not (identical? ch "#"))
+       (not (identical? ch \'))
+       (not (identical? ch ":"))
        (macros ch)))

 (defn read-token
@@ -104,7 +104,7 @@
 (defn- re-find*
   [re s]
   (let [matches (.exec re s)]
-    (when (coercive-not= matches nil)
+    (when-not (nil? matches)
       (if (== (alength matches) 1)
         (aget matches 0)
         matches))))
@@ -113,9 +113,8 @@
   [s]
   (let [groups (re-find* int-pattern s)
         group3 (aget groups 2)]
-    (if (coercive-not
-         (or (nil? group3)
-             (< (alength group3) 1)))
+    (if-not (or (nil? group3)
+                (< (alength group3) 1))
       0
       (let [negate (if (identical? "-" (aget groups 1)) -1 1)
             a (cond
@@ -145,7 +144,7 @@
 (defn- re-matches*
   [re s]
   (let [matches (.exec re s)]
-    (when (and (coercive-not= matches nil)
+    (when (and (not (nil? matches))
                (identical? (aget matches 0) s))
       (if (== (alength matches) 1)
         (aget matches 0)
@@ -332,12 +331,12 @@
         token (aget a 0)
         ns (aget a 1)
         name (aget a 2)]
-    (if (or (and (coercive-not (undefined? ns))
+    (if (or (and (not (undefined? ns))
                  (identical? (. ns (substring (- (.-length ns) 2) (.-length ns))) ":/"))
             (identical? (aget name (dec (.-length name))) ":")
-            (coercive-not (== (.indexOf token "::" 1) -1)))
+            (not (== (.indexOf token "::" 1) -1)))
       (reader-error reader "Invalid token: " token)
-      (if (and (coercive-not= ns nil) (> (.-length ns) 0))
+      (if (and (not (nil? ns)) (> (.-length ns) 0))
         (keyword (.substring ns 0 (.indexOf ns "/")) name)
         (keyword token)))))


emacs old buffer saving floppy to flappy. problem solved

--- src/cljs/neat/floppy.cljs
+++ src/cljs/neat/floppy.cljs
@@ -9,7 +9,7 @@

 (def settings
   {:stale-species 15
-   :population 300
+   :population 50
    :inputs 301
    :outputs 1
    :max-nodes 600
@@ -39,5 +39,7 @@
    :commands i/commands
    :wait 500})

-(if (js/document.getElementById "floppy")
+(def floppy? (js/document.getElementById "floppy"))
+
+(if floppy?
   (defonce run!! (r/runner (p/pool settings) interactions)))


Print day map keys.

Print day map keys.

--- src/cljs/tunnit/core.cljs
+++ src/cljs/tunnit/core.cljs
@@ -1,15 +1,37 @@
 (ns tunnit.core
   (:require [om.core :as om :include-macros true]
-            [om.dom :as dom :include-macros true]))
+            [om.dom :as dom :include-macros true]
+            [cljs-time.core :as time]
+            [om-tools.dom :as ot :include-macros true]
+            [om-tools.core :refer-macros [defcomponent]]
+            ))

-(defonce app-state (atom {:text "Hello Chestnut!"}))
+(enable-console-print!)
+
+(defonce app-state (atom {:text "Viikko"}))
+
+(def week-map
+  {:mon [] :tue [] :wed [] :thu [] :fri [] :sat [] :sun []})
+
+(defcomponent week-view [app owner]
+              (render [this]
+                      (ot/div
+                        (map (fn [day]
+                               (ot/output (str day)))
+                             (keys week-map))
+                        ))
+              )
+
+(defcomponent app-view [app owner]
+              (render [this]
+                      (ot/div {:class "column-main"}
+                              (dom/h1 nil (:text app))
+                              (om/build week-view app)
+                              )
+                      ))

 (defn main []
   (om/root
-    (fn [app owner]
-      (reify
-        om/IRender
-        (render [_]
-          (dom/h1 nil (:text app)))))
+    app-view
     app-state
-    {:target (. js/document (getElementById "app"))}))
+    {:target (. js/document (getElementById "app"))}))


Disabling tracing by default.

Disabling tracing by default.

--- src/cmr/ingest/system.clj
+++ src/cmr/ingest/system.clj
@@ -23,7 +23,7 @@
   {:log (log/create-logger)
    :config default-config
    :web (web/create-web-server 3002 routes/make-api)
-   :zipkin (context/zipkin-config "Ingest")})
+   :zipkin (context/zipkin-config "Ingest" false)})

 (defn start
   "Performs side effects to initialize the system, acquire resources,


update to 0.18

update to 0.18

--- src/otp_api_proxy/util.clj
+++ src/otp_api_proxy/util.clj
@@ -150,7 +150,8 @@
                              (str arg "=" (get params arg))
                              ""))
         otp-url
-        (str "http://anaheim-otp.groth-geodata.com/otp/routers/default/plan"
+        ; (str "http://anaheim-otp.groth-geodata.com/otp/routers/default/plan"
+        (str "http://anaheim-otp.groth-geodata.com/otp-0.18/routers/default/plan"
              "?"
              ;; banned routes format is: agency_id '__' route_id
              ;; agency_id 248 is Anaheim, route id 1711 is route 20


add ixi snare drum

add ixi snare drum

--- src/overtone/synth/ixi.clj
+++ src/overtone/synth/ixi.clj
@@ -77,3 +77,27 @@
                   (env-gen:ar (perc 0.0001 sustain)
                               :action FREE))]
     (out out-bus (pan2 signal pan))))
+
+(defsynth snare
+  [drum-mode-level 1
+   snare-level 50
+   snare-tightness 1200
+   sustain 0.04
+   pan 0
+   amp 0.3
+   out-bus 0]
+  (let [freq 305
+        drum-mode-env   (env-gen:ar (perc 0.005 sustain) :action FREE)
+        drum-mode-sin-1 (* (sin-osc (* freq 0.53)) drum-mode-env 0.5)
+        drum-mode-sin-2 (* (sin-osc freq) drum-mode-env 0.5)
+        drum-mode-pmosc (* 5 drum-mode-env (pm-osc (saw (* freq 0.85)) 184 (/ 0.5 1.3)))
+        drum-mode-mix   (* drum-mode-level (+ drum-mode-sin-1 drum-mode-sin-2 drum-mode-pmosc))
+        snare-noise     (* amp 0.8 (lf-noise0 9000))
+        snare-env       (env-gen:ar (perc 0.0001 sustain) :action FREE)
+        snare-brf-1     (* 0.5 (brf snare-noise 8000 0.1))
+        snare-brf-2     (* 0.5 (brf snare-brf-1 5000 0.1))
+        snare-brf-3     (* 0.5 (brf snare-brf-2 3600 0.1))
+        snare-brf-4     (* snare-env (brf snare-brf-3 2000 0.1))
+        snare-reson     (* snare-level (resonz snare-brf-4 snare-tightness))
+        snare-drum-mix  (* amp (+ drum-mode-mix snare-reson))]
+    (out out-bus (pan2 snare-drum-mix pan))))


thru rm_case_relationships

thru rm_case_relationships

--- src/pg_demo/table_defs.clj
+++ src/pg_demo/table_defs.clj
@@ -1955,6 +1955,270 @@
               PRIMARY KEY (ENTERPRISE_ID,CASE_ID,SEQ_NUM,DLP_REVISION_NUMBER)
           ); " }

+    { "rm_case_prod_devices_pmda"
+          "CREATE TABLE rm_case_prod_devices_pmda (
+              ENTERPRISE_ID numeric NOT NULL,
+              CASE_ID numeric NOT NULL,
+              PROD_SEQ_NUM numeric NOT NULL,
+              REPORTING_CATEGORY numeric,
+              MALFUNCTION_DATE timestamp,
+              NEXT_REPORT_DATE timestamp,
+              MALFUNCTION_STATUS numeric,
+              MALFUNCTION_NAME varchar(255),
+              RESPONSIBLE_OFFICER varchar(50),
+              PATIENT_STATUS text,
+              PATIENT_TREATMENT text,
+              FIRST_TIME_USE numeric,
+              TIMES_OF_USE numeric,
+              SINCE_FIRST_USE numeric,
+              SINCE_FIRST_USE_DURATION numeric,
+              CURRENT_STATUS numeric,
+              RECALL_DISPOSED numeric,
+              RECALL_VESTIGIAL numeric,
+              RECALL_PLANNED numeric,
+              RECALL_IMPOSSIBLE numeric,
+              REMARKS text,
+              INVESTIGATION_RESULTS text,
+              ACTION_TAKEN_UNTIL_NOW text,
+              FUTURE_ACTIONS numeric,
+              DEVICE_SUMMARY text,
+              MEASURE_CLASSIFICATION varchar(100),
+              RESEARCH_AND_MEASURES text,
+              DELETED timestamp,
+              DLP_REVISION_NUMBER numeric NOT NULL,
+              REVISION_DELETE_FLAG numeric,
+              DELETED_FLAG numeric(1) NOT NULL,
+              EFFECTIVE_START_DATE timestamp NOT NULL,
+              EFFECTIVE_END_DATE timestamp NOT NULL,
+              PRIMARY KEY (ENTERPRISE_ID,CASE_ID,PROD_SEQ_NUM,DLP_REVISION_NUMBER)
+          ); " }
+
+    { "rm_case_prod_drugs"
+          "CREATE TABLE rm_case_prod_drugs (
+              ENTERPRISE_ID numeric NOT NULL,
+              CASE_ID numeric NOT NULL,
+              SEQ_NUM numeric NOT NULL,
+              FORMULATION_ID numeric,
+              CONCENTRATION varchar(10),
+              CONC_UNITS_ID numeric,
+              ACT_TAKEN_ID numeric,
+              SEVERITY_ID numeric,
+              INTERACTION numeric,
+              CONTRAIND numeric,
+              FIRST_DOSE timestamp,
+              FIRST_DOSE_RES numeric,
+              LAST_DOSE timestamp,
+              LAST_DOSE_RES numeric,
+              TOTAL_DOSE numeric(22,7),
+              TOT_DOSE_UNIT_ID numeric,
+              PREV_USE numeric,
+              ABUSE numeric,
+              OVERDOSE numeric,
+              PROTOCOL numeric,
+              DECHALLENGE numeric,
+              DECHALL_DATE timestamp,
+              RECHALLENGE numeric,
+              RECHALL_START timestamp,
+              RECHALL_STOP timestamp,
+              RECHALL_OUTCOME numeric,
+              SORT_ID numeric,
+              B_WEIGHT_GRAMS numeric,
+              N_SIBLINGS numeric,
+              B_WEIGHT_OZS numeric,
+              FIRST_DOSE_PARTIAL varchar(20),
+              LAST_DOSE_PARTIAL varchar(20),
+              TAMPERING numeric(4),
+              CUMULATIVE_DOSE numeric(22,7),
+              CUMULATIVE_DOSE_UNIT varchar(10),
+              DELETED timestamp,
+              UD_TEXT_1 varchar(100),
+              UD_TEXT_2 varchar(100),
+              UD_TEXT_3 varchar(100),
+              UD_TEXT_4 varchar(100),
+              UD_TEXT_5 varchar(100),
+              UD_TEXT_6 varchar(100),
+              UD_TEXT_7 varchar(100),
+              UD_TEXT_8 varchar(100),
+              UD_TEXT_9 varchar(100),
+              UD_TEXT_10 varchar(100),
+              UD_TEXT_11 varchar(100),
+              UD_TEXT_12 varchar(100),
+              UD_DATE_1 timestamp,
+              UD_DATE_2 timestamp,
+              UD_DATE_3 timestamp,
+              UD_DATE_4 timestamp,
+              UD_DATE_5 timestamp,
+              UD_DATE_6 timestamp,
+              UD_DATE_7 timestamp,
+              UD_DATE_8 timestamp,
+              UD_DATE_9 timestamp,
+              UD_DATE_10 timestamp,
+              UD_DATE_11 timestamp,
+              UD_DATE_12 timestamp,
+              UD_NUMBER_1 numeric(30,10),
+              UD_NUMBER_2 numeric(30,10),
+              UD_NUMBER_3 numeric(30,10),
+              UD_NUMBER_4 numeric(30,10),
+              UD_NUMBER_5 numeric(30,10),
+              UD_NUMBER_6 numeric(30,10),
+              UD_NUMBER_7 numeric(30,10),
+              UD_NUMBER_8 numeric(30,10),
+              UD_NUMBER_9 numeric(30,10),
+              UD_NUMBER_10 numeric(30,10),
+              UD_NUMBER_11 numeric(30,10),
+              UD_NUMBER_12 numeric(30,10),
+              CUMULATIVE_DOSE_UNIT_ID numeric,
+              OBTAIN_DRUG_COUNTRY_ID numeric,
+              DRUG_AUTH_COUNTRY_ID numeric,
+              DURATION_SECONDS numeric,
+              LATENCY_SECONDS numeric,
+              DELAY_SECONDS numeric,
+              UD_TEXT_1_J varchar(100),
+              UD_TEXT_2_J varchar(100),
+              UD_TEXT_3_J varchar(100),
+              UD_TEXT_4_J varchar(100),
+              UD_TEXT_5_J varchar(100),
+              UD_TEXT_6_J varchar(100),
+              UD_TEXT_7_J varchar(100),
+              UD_TEXT_8_J varchar(100),
+              UD_TEXT_9_J varchar(100),
+              UD_TEXT_10_J varchar(100),
+              UD_TEXT_11_J varchar(100),
+              UD_TEXT_12_J varchar(100),
+              DLP_REVISION_NUMBER numeric NOT NULL,
+              REVISION_DELETE_FLAG numeric,
+              DELETED_FLAG numeric(1) NOT NULL,
+              EFFECTIVE_START_DATE timestamp NOT NULL,
+              EFFECTIVE_END_DATE timestamp NOT NULL,
+              PRIMARY KEY (ENTERPRISE_ID,CASE_ID,SEQ_NUM,DLP_REVISION_NUMBER)
+          ); " }
+
+    { "rm_case_prod_indications"
+          "CREATE TABLE rm_case_prod_indications (
+              ENTERPRISE_ID numeric NOT NULL,
+              CASE_ID numeric NOT NULL,
+              PROD_SEQ_NUM numeric NOT NULL,
+              SEQ_NUM numeric NOT NULL,
+              SORT_ID numeric,
+              IND_REPTD varchar(255),
+              IND_CODED varchar(255),
+              IND_CODE varchar(50),
+              IND_PREF_TERM varchar(250),
+              IND_LLT_CODE varchar(50),
+              IND_LLT varchar(250),
+              IND_HLT_CODE varchar(50),
+              IND_HLT varchar(250),
+              IND_HLGT_CODE varchar(50),
+              IND_HLGT varchar(250),
+              IND_SOC_CODE varchar(50),
+              IND_SOC varchar(250),
+              IND_SYN_CODE numeric,
+              IND_CODE_DICT numeric,
+              IND_CODE_STATUS numeric(3),
+              IND_CODED_J varchar(255),
+              IND_CODE_STATUS_J numeric,
+              IND_HLGT_J varchar(250),
+              IND_HLT_J varchar(250),
+              IND_LLT_CODE_J varchar(50),
+              IND_LLT_J varchar(250),
+              IND_PREF_TERM_J varchar(250),
+              IND_REPTD_J varchar(255),
+              IND_SOC_J varchar(250),
+              IND_SYN_CODE_J numeric,
+              DELETED timestamp,
+              DLP_REVISION_NUMBER numeric NOT NULL,
+              REVISION_DELETE_FLAG numeric,
+              DELETED_FLAG numeric(1) NOT NULL,
+              EFFECTIVE_START_DATE timestamp NOT NULL,
+              EFFECTIVE_END_DATE timestamp NOT NULL,
+              PRIMARY KEY (ENTERPRISE_ID,CASE_ID,PROD_SEQ_NUM,SEQ_NUM,DLP_REVISION_NUMBER)
+          ); " }
+
+    { "rm_case_prod_ingredient"
+          "CREATE TABLE rm_case_prod_ingredient (
+              ENTERPRISE_ID numeric NOT NULL,
+              CASE_ID numeric NOT NULL,
+              SEQ_NUM numeric NOT NULL,
+              ITEM numeric NOT NULL,
+              INGREDIENT_ID numeric,
+              CONC_UNIT_ID numeric,
+              CONCENTRATION varchar(10),
+              DELETED timestamp,
+              DLP_REVISION_NUMBER numeric NOT NULL,
+              REVISION_DELETE_FLAG numeric,
+              DELETED_FLAG numeric(1) NOT NULL,
+              EFFECTIVE_START_DATE timestamp NOT NULL,
+              EFFECTIVE_END_DATE timestamp NOT NULL,
+              PRIMARY KEY (ENTERPRISE_ID,CASE_ID,SEQ_NUM,ITEM,DLP_REVISION_NUMBER)
+          ); " }
+
+    { "rm_case_prod_qc_cid"
+          "CREATE TABLE rm_case_prod_qc_cid (
+              ENTERPRISE_ID numeric NOT NULL,
+              CASE_ID numeric NOT NULL,
+              PROD_SEQ_NUM numeric NOT NULL,
+              SEQ_NUM numeric NOT NULL,
+              SORT_ID numeric,
+              CID_NUMBER varchar(20),
+              PCID_NUMBER varchar(20),
+              LOT_NUMBER varchar(35),
+              DELETED timestamp,
+              DLP_REVISION_NUMBER numeric NOT NULL,
+              EFFECTIVE_START_DATE timestamp NOT NULL,
+              EFFECTIVE_END_DATE timestamp NOT NULL,
+              DELETED_FLAG numeric(1) NOT NULL,
+              REVISION_DELETE_FLAG numeric,
+              PRIMARY KEY (ENTERPRISE_ID,CASE_ID,PROD_SEQ_NUM,SEQ_NUM,DLP_REVISION_NUMBER)
+          ); " }
+
+    { "rm_case_reference"
+          "CREATE TABLE rm_case_reference (
+              ENTERPRISE_ID numeric NOT NULL,
+              CASE_ID numeric NOT NULL,
+              SEQ_NUM numeric NOT NULL,
+              REF_NO varchar(100),
+              REF_TYPE_ID numeric,
+              NOTES varchar(200),
+              REF_CASE_ID numeric,
+              SORT_ID numeric,
+              NOTES_J varchar(200),
+              DELETED timestamp,
+              DLP_REVISION_NUMBER numeric NOT NULL,
+              REVISION_DELETE_FLAG numeric,
+              DELETED_FLAG numeric(1) NOT NULL,
+              EFFECTIVE_START_DATE timestamp NOT NULL,
+              EFFECTIVE_END_DATE timestamp NOT NULL,
+              PRIMARY KEY (ENTERPRISE_ID,CASE_ID,SEQ_NUM,DLP_REVISION_NUMBER)
+          ); " }
+
+    { "rm_case_reg_reports"
+          "CREATE TABLE rm_case_reg_reports (
+              ENTERPRISE_ID numeric NOT NULL,
+              CASE_ID numeric NOT NULL,
+              SEQ_NUM numeric NOT NULL,
+              REG_REPORT_ID numeric,
+              DATE_ASSESSED timestamp,
+              SORT_ID numeric,
+              DELETED timestamp,
+              PRIMARY KEY (ENTERPRISE_ID,CASE_ID,SEQ_NUM)
+          ); " }
+
+    { "rm_case_relationships"
+          "CREATE TABLE rm_case_relationships (
+              ENTERPRISE_ID numeric NOT NULL,
+              CASE_ID numeric NOT NULL,
+              SEQ_NUM numeric NOT NULL,
+              DIAGNOSIS numeric,
+              SYMPTOM numeric,
+              DELETED timestamp,
+              DLP_REVISION_NUMBER numeric NOT NULL,
+              REVISION_DELETE_FLAG numeric,
+              DELETED_FLAG numeric(1) NOT NULL,
+              EFFECTIVE_START_DATE timestamp NOT NULL,
+              EFFECTIVE_END_DATE timestamp NOT NULL,
+              PRIMARY KEY (ENTERPRISE_ID,CASE_ID,SEQ_NUM,DLP_REVISION_NUMBER)
+          ); " }
+
   ] ))

 (def dummy


maybe fix npm/find-resource stackoverflow?

still havent' reproduced this yet. this is my best guess so far.

--- src/main/shadow/build/npm.clj
+++ src/main/shadow/build/npm.clj
@@ -301,7 +301,6 @@
    "_stream_readable" "readable-stream/readable.js"
    "_stream_transform" "readable-stream/transform.js"
    "_stream_writable" "readable-stream/writable.js"
-   "string_decoder" "string_decoder"
    "sys" "util/util.js"
    "timers" "timers-browserify"
    "tls" false
@@ -689,7 +688,7 @@
           (false? override)
           empty-rc

-          (string? override)
+          (and (string? override) (not= override rel-path))
           (or (if (util/is-relative? override)
                 (find-resource-in-package npm package require-from override)
                 (find-resource npm require-from override))
@@ -769,7 +768,7 @@

       (cond
         ;; common path, no override
-        (nil? override)
+        (or (nil? override) (= override require))
         (when-let [{:keys [package-name] :as package} (find-package-for-require npm require-from require)]
           (if (= require package-name)
             ;; plain package require turns into "./" rel require


without letters fix

without letters fix

--- src-clj/acha/achievement.clj
+++ src-clj/acha/achievement.clj
@@ -97,7 +97,7 @@
   (make-message-scanner
     [:no-more-letters
     (fn [message]
-      (some #(Character/isLetter (.charValue %)) message))]))
+      (not (some #(Character/isLetter (.charValue %)) message)))]))

 (def narcissist
   [:narcissist


return new entries on board creation.

return new entries on board creation.

--- src/oc/storage/api/boards.clj
+++ src/oc/storage/api/boards.clj
@@ -39,7 +39,7 @@
   "Assemble the entry, author, and viewer data needed for a board response."

   ;; Draft board
-  ([conn org :guard map? board :guard #(= (:slug %) (:slug board-res/default-drafts-board)) ctx]
+  ([conn org :guard map? board :guard #(or (:draft %) (= (:slug %) (:slug board-res/default-drafts-board))) ctx]
   (let [org-slug (:slug org)
         slug (:slug board)
         entries (entry-res/list-entries-by-org-author conn (:uuid org) (-> ctx :user :user-id) :draft {})
@@ -49,7 +49,7 @@
         entry-reps (map #(entry-rep/render-entry-for-collection org (or (board-map (:board-uuid %)) board) %
                             [] []
                             (:access-level ctx) (-> ctx :user :user-id))
-                      entries)]
+                        entries)]
     (assemble-board org-slug board entry-reps ctx)))

   ;; Regular board
@@ -197,7 +197,7 @@
                               ;; retrieve the board again to get final list of members
                               (board-res/get-board conn (:uuid board-result)))]
           (notification/send-trigger! (notification/->trigger :add org {:new created-board :notifications notifications} user invitation-note))
-          {:created-board created-board}))
+          {:created-board (assemble-board conn org created-board ctx)}))

     (do (timbre/error "Failed creating board for org:" org-slug) false))))


clarify IMetronome docstring.

clarify IMetronome docstring.

--- src/overtone/music/rhythm.clj
+++ src/overtone/music/rhythm.clj
@@ -24,7 +24,7 @@

 (defprotocol IMetronome
   (start [this] [this start-beat]
-    "Returns the start time of the metronome or restart's the metronome at
+    "Returns the start time of the metronome. Also restart's the metronome at
      'start-beat' if given.")
   (tick [this]
     "Returns the duration of one metronome 'tick' in milleseconds.")


beef up server limits as our machines are now a lot more powerful than they were when sc was first created

--- src/overtone/sc/allocator.clj
+++ src/overtone/sc/allocator.clj
@@ -1,11 +1,11 @@
 (ns overtone.sc.allocator)

 ;; ## SCSynth limits
-(def MAX-NODES 1024)
-(def MAX-BUFFERS 1024)
-(def MAX-SDEFS 1024)
-(def MAX-AUDIO-BUS 128)
-(def MAX-CONTROL-BUS 4096)
+(def MAX-NODES 4000)
+(def MAX-BUFFERS 4000)
+(def MAX-SDEFS 2000)
+(def MAX-AUDIO-BUS 1000)
+(def MAX-CONTROL-BUS 4000)

 ;; ## Allocators
 ;;


don't allow a project name to be figwheel

--- src/leiningen/new/figwheel.clj
+++ src/leiningen/new/figwheel.clj
@@ -39,6 +39,10 @@
    nothing but a print statment is added in core.cljs"
   [name & opts]
   (do
+    (when (= name "figwheel")
+      (main/abort
+       (str "Cannot name a figwheel project \"figwheel\" the namspace will clash.\n"
+            "Please choose a different name, maybe \"tryfig\"?")))
     (clean-opts valid-options opts) ;; Check options for errors
     (let [data {:name name
                 :sanitized (name-to-path name)


Improve add-types to consider actual entity types

--- src/lt/plugins/kukui/sync.cljs
+++ src/lt/plugins/kukui/sync.cljs
@@ -30,9 +30,13 @@
                @new-tags)
           entities-with-tags)))

-(defn add-types [entities]
-  (let [existing-types (set (d/qf '[:find ?type
-                                     :where [?e :type ?type]]))]
+(defn add-types
+  [entities]
+  (let [existing-types (cset/union
+                        (set (d/qf '[:find ?name
+                                     :where [?e :type "type"] [?e :name ?name]]))
+                        (set (d/qf '[:find ?type
+                                     :where [?e :type ?type]])))]
     (->> entities
          (keep :type)
          set


Simplify foreach logic and add fn end tags

--- src/icfp2014/compiler.clj
+++ src/icfp2014/compiler.clj
@@ -179,16 +179,13 @@
                [:st 0 (.indexOf @locals x) (format "; store %s" x)]
                (load-local xs-sym)
                [:cdr]
-               [:st 0 (.indexOf @locals xs-sym) (format "; store %s" xs-sym)]]
-
-              (compile-form vars fns body)
+               [:st 0 (.indexOf @locals x) (format "; store %s" x)]
+               (compile-form vars fns body)]

               (tag-with cond-tag [(load-local xs-sym)])
-              [[:atom]
-               [:tsel (str "@" done-tag) (str "@" loop-tag)]]
-
-              (tag-with loop-tag [[:ldc 0]])
-              [[:sel (str "@" body-tag) (str "@" body-tag)]
+              [[:cdr]
+               [:atom]
+               [:sel (str "@" done-tag) (str "@" body-tag)]
                [:cons]
                [:join]]

@@ -262,7 +259,7 @@
   (let [code [[:ldc 0 "; #main"]
               (load-fn 0 'step)
               [:cons]
-              [:rtn]]
+              [:rtn "; end main"]]
         main {:name 'main
               :code code
               :length (count code)}]
@@ -276,7 +273,7 @@
                      loads
                      [[:ldf "@main ; load main"]
                       [:rap (count fns)]
-                      [:rtn]])
+                      [:rtn "; end prelude"]])
         prelude {:name 'prelude
               :code code
               :length (count code)}]
@@ -310,7 +307,7 @@
           code (->> body
                     (mapcat #(compile-form args fns %))
                     (tag-with localname))
-          code (concat code [[:rtn]])
+          code (concat code [[:rtn (str "; end " name)]])
           num-locals (count @locals)
           local-scope (concat [[:dum num-locals]]
                        (vec (repeatedly num-locals #(identity [:ldc 0])))


Simplify some code

Simplify some code

--- src/io/aviso/twixt/utils.clj
+++ src/io/aviso/twixt/utils.clj
@@ -77,18 +77,18 @@

 (defn compute-relative-path
   [^String start ^String relative]
-  (loop [path-terms (-> (.split start "/") seq drop-last vec) ; Drop the "file" part of the path, leaving the "folders" list
-         terms (.split relative "/")]
-    (if (empty? terms)
-      (str/join path-terms "/")
-      (let [[term & remaining] terms]
-        (cond
-          (or (= term ".") (= term "")) (recur path-terms remaining)
-          (= term "..") (if (empty? path-terms)
-                          ;; You could rewrite this with reduce, but then generating this exception would be more difficult:
-                          (throw (IllegalArgumentException. (format "Relative path `%s' for `%s' would go above root." relative start)))
-                          (recur (-> path-terms drop-last vec) remaining))
-          :else (recur (conj path-terms term) remaining))))))
+  ;; Convert the start path into a stack of just the folders
+  (loop [path-terms (-> (.split start "/") reverse rest)
+         terms (-> relative (.split "/"))]
+    (let [[term & remaining] terms]
+      (cond
+        (empty? terms) (->> path-terms reverse (str/join "/"))
+        (or (= term ".") (= term "")) (recur path-terms remaining)
+        (= term "..") (if (empty? path-terms)
+                        ;; You could rewrite this with reduce, but then generating this exception would be more difficult:
+                        (throw (IllegalArgumentException. (format "Relative path `%s' for `%s' would go above root." relative start)))
+                        (recur (rest path-terms) remaining))
+        :else (recur (cons term path-terms) remaining)))))

 (defn- url-to-file
   [^URL url]


Catch errors

Catch errors

--- src/ipython_clojure/core.clj
+++ src/ipython_clojure/core.clj
@@ -207,31 +207,59 @@
                        :status "ok"
                        :started (now)} session-id signer (:idents message))

-        (let [s# (new java.io.StringWriter)
+        (try
+          (let [s# (new java.io.StringWriter)
               [output results]
               (binding [*out* s#]
                 (let [result (pr-str (eval (load-string (get-in message [:content :code]))))
                       output (str s#)]
                   [output, result]
-                  )
-                )
+                  ))
               ]

-          ;; Send stdout
-          (send-message iopub-socket "pyout"
-                        {:execution_count @execution-count
-                         :data {:text/plain output}
-                         :metadata {}
-                         }
-                        parent-header {} session-id signer)
-
-          ;; Send results
-          (send-message iopub-socket "execute_result"
-                        {:execution_count @execution-count
-                         :data {:text/plain results}
-                         :metadata {}
-                         }
-                        parent-header {} session-id signer))
+            ;; Send stdout
+            (send-message iopub-socket "pyout"
+                          {:execution_count @execution-count
+                           :data {:text/plain output}
+                           :metadata {}
+                           }
+                          parent-header {} session-id signer)
+
+            ;; Send results
+            (send-message iopub-socket "execute_result"
+                          {:execution_count @execution-count
+                           :data {:text/plain results}
+                           :metadata {}
+                           }
+                          parent-header {} session-id signer))
+
+          (catch Exception e
+            ;; Send error on iopub socket
+            (send-message iopub-socket "error"
+                          {:execution_count @execution-count
+                           :ename (.getSimpleName (.getClass e))
+                           :evalue (.getLocalizedMessage e)
+                           :traceback (map #(.toString %) (.getStackTrace e))
+                           :user_variables {}
+                           :user_expressions {}
+                           }
+                          parent-header {} session-id signer)
+
+            ;; Send an error execute_reply message
+            (send-router-message shell-socket "execute_reply"
+                                 {:status "error"
+                                  :execution_count @execution-count
+                                  :ename (.getSimpleName (.getClass e))
+                                  :evalue (.getLocalizedMessage e)
+                                  :traceback (map #(.toString %) (.getStackTrace e))
+                                  :user_variables {}
+                                  :user_expressions {}}
+                                 parent-header
+                                 {:dependencies_met "True"
+                                  :engine session-id
+                                  :status "ok"
+                                  :started (now)} session-id signer (:idents message)))
+          )

         (send-message iopub-socket "status" (status-content "idle")


Guard against empty user names.

Guard against empty user names.

This prevents a 500, which is always worrying on a log in page.

--- src/kixi/hecuba/security.clj
+++ src/kixi/hecuba/security.clj
@@ -40,20 +40,22 @@
 (defn get-user [store]
   (let [user-cql (db/prepare-statement (:hecuba-session store) "select * from users where id = ?;")]
     (fn [username]
-      (log/debugf "Getting user: %s" username)
-      (db/with-session [session (:hecuba-session store)]
-        (let [user (first
-                    (db/execute-prepared
-                     session
-                     user-cql
-                     {:values [username]}))]
-          (log/debugf "Got user: %s" user)
-          (if user
-            (merge {:username (:username user)
-                    :id       (:id user)
-                    :password (:password user)}
-                   (edn/read-string (:data user)))
-            nil))))))
+      (if (seq username)
+        (db/with-session [session (:hecuba-session store)]
+          (log/debugf "Getting user: [%s]" username)
+          (let [user (first
+                      (db/execute-prepared
+                       session
+                       user-cql
+                       {:values [username]}))]
+            (log/debugf "Got user: [%s]" user)
+            (if user
+              (merge {:username (:username user)
+                      :id       (:id user)
+                      :password (:password user)}
+                     (edn/read-string (:data user)))
+              nil)))
+        (log/warn "Get user called empty username.")))))

 (defn update-user-data! [store username user-data]
   (db/with-session [session (:hecuba-session store)]


#1 Working also with CLI specified WAR location

--- src/leiningen/amp/deploy.clj
+++ src/leiningen/amp/deploy.clj
@@ -124,5 +124,5 @@
    :amp-target-war"
   [project args]
   (let [amp (locate-amp project)
-        war (locate-war project) args]
+        war (locate-war project args)]
     (install! amp war)))


WIP2 notify-team

WIP2 notify-team

--- src/polismath/meta/notify.clj
+++ src/polismath/meta/notify.clj
@@ -5,16 +5,21 @@

 ;; Keep track of the type of notifications sent, and when they were sent, so you can avoid spamming.
-;; Maps from error code to time last sent in millis.
-(def team-notifications (atom {}))
+;; Maps from message type to a list of timestamps. If there are more than N timestamps within T seconds, it prevents sending. Timestamps older than T seconds will be cleared.
+(def team-notifications-per-message-type-throttle (atom {}))
+;; Maps from zid,message-type to time last sent in millis.
+(def team-notifications-per-convo (atom {}))

-(defn send-team-notification [subject body]
+(def throttle-count 5) ; number of messages of message-type that can be sent during a throttle-time amount of time
+(def throttle-time (* 60 60 1000))
+(def min-wait (* 60 60 1000))
+
+(defn send-team-notification [config subject body]
   (try
-    (let [darwin-config (-> darwin :config)
-          response (client/post (str (:webserver-url darwin-config) "/notifyTeam")
-                       {:form-params {:webserver_username (:webserver-username darwin-config)
-                                      :webserver_pass (:webserver-pass darwin-config)
+    (let [response (client/post (str (:webserver-url config) "/notifyTeam")
+                       {:form-params {:webserver_username (:webserver-username config)
+                                      :webserver_pass (:webserver-pass config)
                                       :subject subject
                                       :body body}
                         :content-type :json
@@ -23,14 +28,20 @@
     (catch Exception e
       (log/error e "failed to notifyTeam:\n"))))

-(defn notify-team [error-code subject body]
+(defn notify-team [config message-type zid subject body]
   (let [now (quot (System/currentTimeMillis) 1000)
-        min-wait (* 60 60 1000)]
-    (if (or
-          (not (contains? team-notifications error-code))
-          (>= now (+ min-wait (get team-notifications error-code))))
+        per-convo-key [zid message-type]
+        oldest (- now throttle-time)
+        trimmed-throttle-list (filter (get team-notifications-per-message-type-throttle message-type) (fn [t] (> t oldest)))
+        message-type-throttle-count (count trimmed-throttle-list)]
+    (if (and
+          (< message-type-throttle-count throttle-count) ; don't send more than 5 per hour for a given message type
+          (or ; don't send more than one per zid,message-type per hour
+            (not (contains? team-notifications-per-convo per-convo-key))
+            (>= now (+ min-wait (get team-notifications-per-convo per-convo-key)))))
       (do
-        (send-team-notification subject body)
-        (swap! team-notifications (fn [old] (assoc old error-code now)))))))
+        (send-team-notification config subject body)
+        (swap! team-notifications-per-convo (fn [old] (assoc old per-convo-key now)))
+        (swap! team-notifications-per-message-type-throttle (fn [old] (assoc old message-type (conj trimmed-throttle-list now))))))))

 :ok


fix formatting - remove trailing space

fix formatting - remove trailing space

--- test/keypin/core_test.clj
+++ test/keypin/core_test.clj
@@ -215,7 +215,7 @@
  (let [no-keys []
        min-keys ["hello"]
        mod-keys ["hello" "hola"]
-       max-keys ["hello" "hola" "34" "false"]
+       max-keys ["hello" "hola" "34" "false"]
        bad-keys ["hello" "hola" "true" "78"]
        bad-keys2 ["hello" "hola" "150" "None"]]
    (testing "Failures"


Fix typos in docstrings

Fix typos in docstrings

--- src/re_frame/interceptor.cljc
+++ src/re_frame/interceptor.cljc
@@ -150,7 +150,7 @@
        {:before  (fn [context] ...)     ;; returns possibly modified context
         :after   (fn [context] ...)}    ;; `identity` would be a noop

-   Walks the queue of iterceptors from beginning to end, calling the
+   Walks the queue of interceptors from beginning to end, calling the
    `:before` fn on each, then reverse direction and walk backwards,
    calling the `:after` fn on each.

@@ -168,7 +168,7 @@
       :stack     <a collection of interceptors already walked>}

    `context` has `:coeffects` and `:effects` which, if this was a web
-   server, would be somewhat anologous to `request` and `response`
+   server, would be somewhat analogous to `request` and `response`
    respectively.

    `coeffects` will contain data like `event` and the initial


metabadge cron

metabadge cron

--- src/clj/salava/metabadge/cron.clj
+++ src/clj/salava/metabadge/cron.clj
@@ -4,6 +4,7 @@
             [clojure.java.jdbc :as jdbc]
             [clojure.tools.logging :as log]
             [salava.metabadge.metabadge :as mb]
+            [salava.metabadge.db :as db]
             [clojure.string :as string]))

 (defn- fetch-json-data [url]
@@ -21,89 +22,99 @@
     (when-not (every? nil? (-> data (dissoc :last_modified) vals))
       (if (nil? (:metabadge data))
         (jdbc/execute! db-conn
-                       ["INSERT IGNORE INTO user_badge_metabadge (user_badge_id, meta_badge_req) VALUES (?,?)"
-                        (:id user_badge) (:required_badge data)])
+                       ["INSERT IGNORE INTO user_badge_metabadge (user_badge_id, meta_badge_req, last_modified) VALUES (?,?,?)"
+                        (:id user_badge) (:required_badge data) (:last_modified data)])
         (doseq [m (:metabadge data)]
           (jdbc/execute! db-conn
-                         ["INSERT IGNORE INTO user_badge_metabadge (user_badge_id, meta_badge, meta_badge_req) VALUES (?,?,?)"
-                          (:id user_badge) m (:required_badge data)]))))))
+                         ["INSERT IGNORE INTO user_badge_metabadge (user_badge_id, meta_badge, meta_badge_req, last_modified) VALUES (?,?,?,?)"
+                          (:id user_badge) m (:required_badge data) (:last_modified data)]))))))

-  (defn- get-metabadge! [ctx db-conn factory-url user_badge]
-    (let [url (str factory-url "/v1/assertion/metabadge/?url=" (u/url-encode (:assertion_url user_badge)))
-          metabadges (:metabadge (fetch-json-data url))]
-      (when-not (empty? metabadges)
-        (doseq [metabadge metabadges
-                :let [metabadge-badge-content (fetch-json-data (-> metabadge :badge :url))
-                      {:keys [description criteria image]} metabadge-badge-content]]
-          (when-not (-> metabadge :badge :received)
+(defn- get-metabadge! [ctx db-conn factory-url user_badge]
+  (let [url (str factory-url "/v1/assertion/metabadge/?url=" (u/url-encode (:assertion_url user_badge)))
+        metabadges (:metabadge (fetch-json-data url))]
+    (when-not (empty? metabadges)
+      (doseq [metabadge metabadges
+              :let [metabadge-badge-content (when-not (-> metabadge :badge :received) (fetch-json-data (-> metabadge :badge :url)))
+                    user_metabadge_id (when (-> metabadge :badge :received) (db/user-badge-by-assertion ctx (-> metabadge :badge :url)))
+                    {:keys [description criteria image]} metabadge-badge-content]]
+
+        (if-not (-> metabadge :badge :received)
+          (jdbc/execute! db-conn
+                         ["INSERT IGNORE INTO factory_metabadge (id, name, description, criteria, image_file, min_required, ctime, mtime ) VALUES (?,?,?,?,?,?,?,?)"
+                          (:id metabadge) (:name metabadge) description (u/md->html criteria) (u/file-from-url ctx image) (:min_required metabadge) (u/now) (u/now)])
+          (jdbc/execute! db-conn
+                         ["INSERT IGNORE INTO user_metabadge_received (metabadge_id, user_badge_id, user_id, name, min_required, last_modified) VALUES (?,?,?,?,?,?)"
+                          (:id metabadge) (:id user_metabadge_id) (:user_id user_badge) (:name metabadge) (:min_required metabadge) (:last_modified user_badge) ])
+          )
+        (doseq [badge (:required_badges metabadge)
+                :let [required-badge-content (when-not (:received badge) (fetch-json-data (:url badge)))
+                      user-badge-id (when (:received badge) (db/user-badge-by-assertion ctx (:url badge)))
+                      {:keys [name description image criteria]} required-badge-content]]
+          (if-not (:received badge)
             (jdbc/execute! db-conn
-                           ["INSERT IGNORE INTO factory_metabadge (id, name, description, criteria, image_file, min_required, ctime, mtime ) VALUES (?,?,?,?,?,?,?,?)"
-                            (:id metabadge) (:name metabadge) description (u/md->html criteria) (u/file-from-url ctx image) (:min_required metabadge) (u/now) (u/now)]))
-          (doseq [badge (:required_badges metabadge)
-                  :let [required-badge-content (fetch-json-data (:url badge))
-                        {:keys [name description image criteria]} required-badge-content]]
-            (when-not (:received badge)
-              (jdbc/execute! db-conn
-                             ["INSERT IGNORE INTO factory_metabadge_required (metabadge_id, required_badge_id, name, description, criteria, image_file, ctime, mtime) VALUES (?,?,?,?,?,?,?,?)"
-                              (:id metabadge) (:id badge) name description (u/md->html criteria) (u/file-from-url ctx image) (u/now) (u/now)])
-              ))))))
+                           ["INSERT IGNORE INTO factory_metabadge_required (metabadge_id, required_badge_id, name, description, criteria, image_file, ctime, mtime) VALUES (?,?,?,?,?,?,?,?)"
+                            (:id metabadge) (:id badge) name description (u/md->html criteria) (u/file-from-url ctx image) (u/now) (u/now)])
+            (jdbc/execute! db-conn
+                           ["INSERT IGNORE INTO user_metabadge_required_received (metabadge_id, user_metabadge_id, user_required_badge_id, user_id, last_modified) VALUES (?,?,?,?,?)"
+                            (:id metabadge) (:id user_metabadge_id) (:id user-badge-id) (:user_id user_badge) (:last_modified user_badge)])
+            ))))))

-  (defn- badge->metabadge! [ctx factory-url]
-    (log/info "get metabadges: started working")
-    (jdbc/with-db-transaction  [db-conn (:connection (u/get-db ctx))]
-      (let [time-limit (+ (System/currentTimeMillis) (* 15 60 1000))
-            sql "SELECT DISTINCT ub.id, ub.assertion_url FROM user_badge_metabadge AS ubm
-            JOIN user_badge AS ub ON ubm.user_badge_id = ub.id
-            WHERE ubm.meta_badge IS NOT NULL OR ubm.meta_badge_req IS NOT NULL"
-            badges (jdbc/query db-conn [sql])
-            ]
-        (doseq [chunk (partition-all 10 badges)]
-          (when (> time-limit (System/currentTimeMillis))
-            (doseq [user-badge chunk]
-              (try
-                (get-metabadge! ctx db-conn factory-url user-badge)
-                (catch Throwable ex
-                  (log/error "get-metabadges failed")
-                  (log/error (.toString ex))
-                  )
+(defn- badge->metabadge! [ctx factory-url]
+  (log/info "get metabadges: started working")
+  (jdbc/with-db-transaction  [db-conn (:connection (u/get-db ctx))]
+    (let [time-limit (+ (System/currentTimeMillis) (* 15 60 1000))
+          sql "SELECT DISTINCT ub.id, ub.user_id, ub.assertion_url, ubm.last_modified FROM user_badge_metabadge AS ubm
+          JOIN user_badge AS ub ON ubm.user_badge_id = ub.id
+          WHERE ubm.meta_badge IS NOT NULL OR ubm.meta_badge_req IS NOT NULL"
+          badges (jdbc/query db-conn [sql])]
+
+      (doseq [chunk (partition-all 10 badges)]
+        (when (> time-limit (System/currentTimeMillis))
+          (doseq [user-badge chunk]
+            (try
+              (get-metabadge! ctx db-conn factory-url user-badge)
+              (catch Throwable ex
+                (log/error "get-metabadges failed")
+                (log/error (.toString ex))
                 )
               )
-            (try (Thread/sleep 1000) (catch InterruptedException _))
-            ))
-        (log/info "get metabadges: done")
-        )))
+            )
+          (try (Thread/sleep 1000) (catch InterruptedException _))
+          ))
+      (log/info "get metabadges: done")
+      )))

-  (defn- check-metabadges [ctx factory-url]
-    (log/info "check for metabadges: started working")
-    (jdbc/with-db-transaction  [db-conn (:connection (u/get-db ctx))]
-      (let [time-limit (+ (System/currentTimeMillis) (* 15 60 1000))
-            sql "SELECT id, assertion_url FROM user_badge
-            WHERE assertion_url IS NOT NULL
-            AND deleted = 0 AND revoked = 0 AND status != 'declined'
-            AND (expires_on IS NULL OR expires_on > UNIX_TIMESTAMP())
-            ORDER BY last_checked LIMIT 1000"
-            ; all-badges (jdbc/query db-conn [sql])
-            badges (filter #(and (not (nil? (:assertion_url %))) (string/starts-with? (:assertion_url %) factory-url)) (jdbc/query db-conn [sql]))
-            ]
-        (doseq [chunk (partition-all 10 badges)]
-          (when (> time-limit (System/currentTimeMillis))
-            (doseq [user-badge chunk]
-              (try
-                (metabadge?! db-conn factory-url user-badge)
-                (catch Throwable ex
-                  (log/error "check-metabadges failed")
-                  (log/error (.toString ex))
-                  )
+(defn- check-metabadges [ctx factory-url]
+  (log/info "check for metabadges: started working")
+  (jdbc/with-db-transaction  [db-conn (:connection (u/get-db ctx))]
+    (let [time-limit (+ (System/currentTimeMillis) (* 15 60 1000))
+          sql "SELECT id, assertion_url FROM user_badge
+          WHERE assertion_url IS NOT NULL
+          AND deleted = 0 AND revoked = 0 AND status != 'declined'
+          AND (expires_on IS NULL OR expires_on > UNIX_TIMESTAMP())
+          ORDER BY last_checked LIMIT 1000"
+          ; all-badges (jdbc/query db-conn [sql])
+          badges (filter #(and (not (nil? (:assertion_url %))) (string/starts-with? (:assertion_url %) factory-url)) (jdbc/query db-conn [sql]))
+          ]
+      (doseq [chunk (partition-all 10 badges)]
+        (when (> time-limit (System/currentTimeMillis))
+          (doseq [user-badge chunk]
+            (try
+              (metabadge?! db-conn factory-url user-badge)
+              (catch Throwable ex
+                (log/error "check-metabadges failed")
+                (log/error (.toString ex))
                 )
               )
-            (try (Thread/sleep 1000) (catch InterruptedException _))
             )
+          (try (Thread/sleep 1000) (catch InterruptedException _))
           )
-        ;;call other function
         )
-      (log/info "check for metabadges: done")
-      ;(badge->metabadge! ctx factory-url)
-      ))
+      ;;call other function
+      )
+    (log/info "check for metabadges: done")
+    (badge->metabadge! ctx factory-url)
+    ))

-  (defn every-hour [ctx]
-    (check-metabadges ctx (get-in ctx [:config :factory :url])))
+(defn every-hour [ctx]
+  (check-metabadges ctx (get-in ctx [:config :factory :url])))


fix misaki.test.core/get-post-files-test

--- test/misaki/test/core.clj
+++ test/misaki/test/core.clj
@@ -118,9 +118,10 @@
           "2000.01.01-foo.html.clj" (.getName c)))))

   (testing "with posts-per-page"
-    (bind-config [:posts-per-page 1]
+    (bind-config [:post-sort-type :date
+                  :posts-per-page 1]
       (binding [*page-index* 0]
-        (let [files (get-post-files)]
+        (let [files (get-post-files :sort? true)]
           (is (= 1 (count files)))
           (is (= "2000.01.01-foo.html.clj" (.getName (first files))))))
       (binding [*page-index* 1]
@@ -133,21 +134,6 @@
           (is (= "2022.02.02-bar.html.clj" (.getName (first files))))))
       (binding [*page-index* 3]
         (is (zero? (count (get-post-files)))))))
-
-  (testing "with sort and posts-per-page"
-    (bind-config [:post-sort-type :date-desc
-                  :posts-per-page 2]
-      (binding [*page-index* 0]
-        (let [[a b :as files] (get-post-files :sort? true)]
-          (are [x y] (= x y)
-            2 (count files)
-            "2022.02.02-bar.html.clj" (.getName a)
-            "2011.01.01-foo.html.clj" (.getName b))))
-      (binding [*page-index* 1]
-        (let [[a :as files] (get-post-files :sort? true)]
-          (are [x y] (= x y)
-            1 (count files)
-            "2000.01.01-foo.html.clj" (.getName a))))))

   (testing "with all? option"
     (is (= 3 (count (get-post-files))))


Fix drained?. Stop batch read once a nil is read. drained? would previously return true even though values were in the retry channel. This would lead to values after :done on output tasks.

--- src/onyx/plugin/core_async.clj
+++ src/onyx/plugin/core_async.clj
@@ -9,6 +9,7 @@
   [_ event]
   (assert (:core.async/chan event) ":core.async/chan not found - add it via inject-lifecycle-resources.")
   {:core.async/pending-messages (atom {})
+   :core.async/drained? (atom false)
    :core.async/retry-ch (chan 1000)})

 (defmethod l-ext/inject-lifecycle-resources :core.async/write-to-chan
@@ -17,8 +18,8 @@
   {})

 (defmethod p-ext/read-batch :core.async/read-from-chan
-  [{:keys [onyx.core/task-map core.async/chan core.async/retry-ch
-           core.async/pending-messages] :as event}]
+  [{:keys [onyx.core/task-map core.async/chan core.async/retry-ch
+           core.async/pending-messages core.async/drained?] :as event}]
   (let [pending (count @pending-messages)
         max-pending (or (:onyx/max-pending task-map) (:onyx/max-pending defaults))
         batch-size (:onyx/batch-size task-map)
@@ -28,14 +29,22 @@
         timeout-ch (timeout ms)
         batch (if (zero? max-segments)
                 (<!! timeout-ch)
-                (->> (range max-segments)
-                     (map (fn [_]
-                            {:id (java.util.UUID/randomUUID)
-                             :input :core.async
-                             :message (first (alts!! [retry-ch chan timeout-ch] :priority true))}))
-                     (remove (comp nil? :message))))]
+                (loop [segments [] cnt 0]
+                  (if (= cnt batch-size)
+                    segments
+                    (if-let [message (first (alts!! [retry-ch chan timeout-ch] :priority true))]
+                      (recur (conj segments
+                                   {:id (java.util.UUID/randomUUID)
+                                    :input :core.async
+                                    :message message})
+                             (inc cnt))
+                      segments))))]
     (doseq [m batch]
       (swap! pending-messages assoc (:id m) (:message m)))
+    (when (and (= 1 (count @pending-messages))
+               (= (count batch) 1)
+               (= (:message (first batch)) :done))
+      (reset! drained? true))
     {:onyx.core/batch batch}))

 (defmethod p-ext/ack-message :core.async/read-from-chan
@@ -53,10 +62,8 @@
   (get @pending-messages message-id))

 (defmethod p-ext/drained? :core.async/read-from-chan
-  [{:keys [core.async/pending-messages] :as event}]
-  (let [x @pending-messages]
-    (and (= (count x) 1)
-         (= (first (vals x)) :done))))
+  [{:keys [core.async/drained? core.async/pending-messages] :as event}]
+  @drained?)

 (defmethod p-ext/write-batch :core.async/write-to-chan
   [{:keys [onyx.core/results core.async/chan] :as event}]


clean up and add (dissoc-in) to remove negatively scaled notes

--- src/overtone/gui/pianoroll.clj
+++ src/overtone/gui/pianoroll.clj
@@ -14,6 +14,20 @@

 (def NUM_BEATS 4)
 (def NUM_BARS 4)
+
+(defn dissoc-in
+  "Dissociates an entry from a nested associative structure returning a new
+  nested structure. keys is a sequence of keys. Any empty maps that result
+  will not be present in the new structure."
+  [m [k & ks :as keys]]
+  (if ks
+    (if-let [nextmap (get m k)]
+      (let [newmap (dissoc-in nextmap ks)]
+        (if (seq newmap)
+          (assoc m k newmap)
+          (dissoc m k)))
+      m)
+    (dissoc m k)))

 (defn note-matrix [notes n-octaves n-measures n-bars n-beats n-steps-per-beat]
@@ -33,7 +47,7 @@
             (draw g
               (rounded-rect x y w h 3 3)
                 (style :stroke 1.0
-                       :background (color 0 255 0 200)
+                       :background (color 0 255 0 150)
                        :foreground (color 0 150 0))))
                        )
                        )))
@@ -102,12 +116,7 @@
           ;; paint the active notes last
           (paint-active-notes notes active-notes g note-width note-height)))

-(defn contains-in?
-  [note-map x y]
-  (let [result (not (nil? (get (get note-map x) y)))]
-    result))
-
-(defn contains-in? [note-map x y note-width]
+(defn get-note [note-map x y note-width]
   (let [r (atom nil)]
     (doseq [[note-x notes] note-map]
       (if (<= note-x x)
@@ -121,10 +130,8 @@
                        (>= (- x 1) note-x)
                        (= y note-y)) ;; bounds checking
                        (do
-                          ; (println "contains-in? is in" r x x-max x note-x y note-y)
                           (swap! r (fn [_] {note-x {note-y data}}))))
                         )))))
-    ; (println "contains in? return-note" r)
     @r))

@@ -132,14 +139,13 @@
   (let [x (int (/ x note-width))
         y (int (/ y note-height))
         length (count @active-notes-atom)
-        return-note (atom (contains-in? @active-notes-atom x y note-width))
+        return-note (atom (get-note @active-notes-atom x y note-width))
         new-note-data {:velocity 1.0 :duration 1}]

       (if (not (nil? @return-note))
         (do
             (doseq [[k note] @return-note]
               (doseq [[n note-data] note]
-               ; (swap! return-note (fn [_] {k {n note-data}} ))
                 (swap! x-cell (fn [_] k))
                 (swap! y-cell (fn [_] n)))))
         (do
@@ -157,8 +163,14 @@
         offset (- x cell-x-start)
         offset-diff (+ offset cell-diff)]  ;; <<-- NEED TO FIX THIS SO THAT IT GRABS THE CURRENT VELOCITY NOT JUST SETS IT TO 0
     (swap! active-notes-atom (fn [notes]
-      (update-in notes [cell-x-start cell-y-start] (fn [_]{:velocity v :duration cell-diff})))) ;;adding one to the cell diff makes the update happen directly under the mouse. if you dont it is always one cell behind when dragging
-      (swap! active-note (fn [_] {cell-x-start {cell-y-start {:velocity v :duration cell-diff}}}))))
+      (if (>= 0 cell-diff)
+        (do
+          (dissoc-in notes [cell-x-start cell-y-start])
+          )
+        (do
+          (update-in notes [cell-x-start cell-y-start] (fn [_]{:velocity v :duration cell-diff}))))))
+
+    (swap! active-note (fn [_] {cell-x-start {cell-y-start {:velocity v :duration cell-diff}}}))))

 (def active-note (atom nil))

@@ -193,7 +205,7 @@
             (swap! start-x (fn [_] (int (/ x note-width))))
             (swap! start-y (fn [_] (int (/ y note-height))))
             (swap! active-note (fn [n] (update-active-notes active-notes-atom active-note x y cell-x-start cell-y-start note-width note-height)))
-            (println "mouse pressed" start-x start-y cell-x-start cell-y-start)
+
             (.repaint (.getSource e))))

       :mouse-dragged
@@ -203,18 +215,17 @@
                 measure (int (/ piano-roll-width MEASURE_WIDTH))
                 current-x-cell (int (/ (.getX e) note-width))
                 cell-delta (- current-x-cell @cell-x-start)
-                diff(if (> cell-delta 0) cell-delta 0)]
-                    (println "mouse dragged" x-cell y-cell start-x start-y cell-x-start cell-y-start cell-delta diff)
-
-                    (update-note x-cell y-cell active-notes-atom active-note diff)
-
-                    (.repaint (.getSource e))))
+                diff(+ 1 cell-delta)]
+
+                (update-note x-cell y-cell active-notes-atom active-note diff)
+                (.repaint (.getSource e))))

       :mouse-released
         (fn [e]

-          (swap! creating-note (fn [b] false))
-          (.repaint (.getSource e))))
+          ; (swap! creating-note (fn [b] false))
+          ; (.repaint (.getSource e)))
+          ))
     panel))

 (defn create-piano-roll


Less brittle mapping to midi-notes. Don't depending on the name of the sample once downloaded to disk map. Explicitly map freesound ids to the notes.


Allow entities with no type to be drawn

Allow entities with no type to be drawn

--- src/play_clj/core_graphics.clj
+++ src/play_clj/core_graphics.clj
@@ -172,6 +172,8 @@
 ; rendering

 (defmulti draw-entity! #(-> % second :type))
+
+(defmethod draw-entity! nil [_])

 (defmethod draw-entity! :actor
   [[^SpriteBatch batch {:keys [^Actor object] :as entity}]]


Added a partial-pca updater

Added a partial-pca updater

--- src/polismath/conversation.clj
+++ src/polismath/conversation.clj
@@ -19,7 +19,6 @@
 ;   * base-cluster-full [ptpt to base mpa]

-
 (def base-conv-update-graph
   {:opts'       (plmb/fnk [opts]
                   "Merge in opts with the following defaults"
@@ -36,6 +35,7 @@
 (def small-conv-update-graph
   (merge base-conv-update-graph
     {:mat   (plmb/fnk [rating-mat]
+              "swap nils for zeros"
               (map (fn [row] (map #(if (nil? %) 0 %) row))
                 (:matrix rating-mat)))
      :pca   (plmb/fnk [conv mat opts']
@@ -50,16 +50,28 @@
                 (:group-k opts')
                 :last-clusters (:group-clusters conv)
                 :cluster-iters (:cluster-iters opts')))
+     ;:repness
+            ;(plmb/fnk [...]
+                      ;(...))
                       }))

-;(defn format-conv [conv]
-  ;(letfn [(frmt [conv' cmpnt f]
-            ;(assoc conv cmpnt (f (conv cmpnt))))]
-  ;(-> conv
-    ;(frmt :pca #(hash-map :center (:center pca)
-                ;:pcs (:pcs pca))
-  ;{:last-updated (conv :last-updated)
-   ;:base-clusters (
+(defn partial-pca
+  [rating-matrix pca indices & {:keys [n-comps iters learning-rate]
+                                :or {n-comps 2 iters 10 learning-rate 0.01}}]
+  "This function takes in the rating matrix, the current pca and a set of row indices and
+  computes the partial pca off of those, returning a lambda that will take the latest PCA
+  and make the update on that in case there have been other mini batch updates since started"
+  (let [rating-subset (row-subset rating-matrix indices)
+        patial-pca (powerit-pca rating-subset n-comps
+                     :start-vectors (:comps pca)
+                     :iters iters)
+        forget-rate (- 1 learning-rate)]
+    (fn [pca']
+      "Actual updater lambda"
+      (plmb/map-vals #(+ (* forget-rate %1) (* learning-rate %2)) pca' patial-pca))))

+(def small-conv-update (graph/eager-compile small-conv-update-graph))
+
+


Minor internal naming change.

Minor internal naming change.

--- src/bide/core.cljs
+++ src/bide/core.cljs
@@ -35,7 +35,7 @@

 (defprotocol IRouter
   (-navigate [_ loc params query])
-  (-replace-location [_ loc params query]))
+  (-replace [_ loc params query]))

 (defprotocol IPathRepr
   "Path parameters coercion protocol."
@@ -172,7 +172,7 @@
           (-navigate [_ id params query]
             (when-let [path (resolve router id params query)]
               (.setToken history path)))
-          (-replace-location [_ id params query]
+          (-replace [_ id params query]
             (when-let [path (resolve router id params query)]
               (.replaceToken history path))))))))

@@ -190,4 +190,4 @@
   ([router id params] (replace! router id params nil))
   ([router id params query]
    {:pre [(router? router)]}
-   (-replace-location router id params query)))
+   (-replace router id params query)))


Change build task to install jar to maven repo instead of building uberjar.

--- project/scrape-trs/build.boot
+++ project/scrape-trs/build.boot
@@ -11,10 +11,9 @@
 (task-options!
     aot {:all true}
     pom {:project 'scrape-trs
-         :version "0.0.0"}
-    jar {:main 'scrape-trs.core})
+         :version "0.0.0"})

 (deftask build
-  "Build scrape-trs uberjar."
+  "Build scrape-trs jar and install to local maven repo."
   []
-  (comp (aot) (pom) (uber) (jar) (target)))
+  (comp (aot) (pom) (jar) (install)))


- lists: make items label :width "100%" so that clicking beyond actual label string but within list bounds still registers

--- src/re_com/selection_list.cljs
+++ src/re_com/selection_list.cljs
@@ -11,7 +11,7 @@
 ;; ----------------------------------------------------------------------------
 (defn label-style [selected? as-exclusions?]
   ;;TODO: margin-top required because currently checkbox & radio-button don't center label
-  (let [base-style {:margin-top "1px"}]
+  (let [base-style {:margin-top "1px" :width "100%"}]
     (if (and selected? as-exclusions?)
       (merge base-style {:text-decoration "line-through"})
       base-style)))


Speed up conversion to js a lot by using reduce-kv

--- src/reagent/impl/template.cljs
+++ src/reagent/impl/template.cljs
@@ -36,13 +36,22 @@
 (def cached-prop-name (memoize undash-prop-name))
 (def cached-style-name (memoize dash-to-camel))

+(defn to-js-val [v]
+  (if-not (ifn? v)
+    v
+    (cond (keyword? v) (name v)
+          (symbol? v) (str v)
+          (coll? v) (clj->js v)
+          :else (fn [& args] (apply v args)))))
+
 (defn convert-prop-value [val]
-  (cond (map? val) (let [obj (js-obj)]
-                     (doseq [[k v] val]
-                       (aset obj (cached-style-name k) (clj->js v)))
-                     obj)
-        (ifn? val) (fn [& args] (apply val args))
-        :else (clj->js val)))
+  (if (map? val)
+    (reduce-kv (fn [res k v]
+                 (doto res
+                   (aset (cached-prop-name k)
+                         (to-js-val v))))
+               (js-obj) val)
+    (to-js-val val)))

 (defn set-id-class [props [id class]]
   (aset props "id" id)
@@ -58,9 +67,10 @@
      (identical? (type props) js/Object) props
      :else (let [objprops (js-obj)]
              (when-not is-empty
-               (doseq [[k v] props]
-                 (aset objprops (cached-prop-name k)
-                       (convert-prop-value v))))
+               (reduce-kv (fn [o k v]
+                            (doto o (aset (cached-prop-name k)
+                                          (convert-prop-value v))))
+                          objprops props))
              (when-not (nil? id-class)
                (set-id-class objprops id-class))
              objprops))))
@@ -90,10 +100,10 @@
   (let [props (get-props this)
         on-change (or (props :on-change) (props "onChange"))]
     (when-not (nil? on-change)
-      (on-change e)
       (let [target (.-target e)]
         (.setState this #js {:value (.-value target)
-                             :checked (.-checked target)})))))
+                             :checked (.-checked target)}))
+      (on-change e))))

 (defn input-will-receive-props [this new-props]
   (let [props (aget new-props cljs-props)]


protect against errors while loading swank

--- src/cake/swank.clj
+++ src/cake/swank.clj
@@ -21,7 +21,9 @@
   "Try to load a namespace reference. If sucessful, evaluate then-form otherwise evaluate else-form."
   `(try (ns ~(.getName *ns*) ~ns-reference)
         (eval '~then-form)
-        (catch java.io.FileNotFoundException e#
+        (catch Exception e#
+          (when (not (instance? java.io.FileNotFoundException e#))
+            (println "Error loading swank:" (.getMessage e#)))
           (eval '~else-form))))

 (if-ns (:use [swank.swank :only [start-repl]]


Added Friend and fixed ambiguities.

Added Friend and fixed ambiguities.

--- web/project.clj
+++ web/project.clj
@@ -7,20 +7,29 @@
   :dependencies [[org.clojure/clojure "1.8.0"]
                  [org.clojure/java.jdbc "0.4.2"]
                  [org.clojure/data.json "0.2.6"]
+                 [org.clojure/core.cache "0.6.5"]
                  [org.postgresql/postgresql "9.4.1208"]
                  [migratus "0.8.13"]
                  [ring/ring-jetty-adapter "1.4.0"]
                  [ring/ring-defaults "0.1.5"]
+                 [ring-logger "0.7.6"]
                  [compojure "1.4.0"]
                  [liberator "0.13"]
+                 [com.cemerick/friend "0.2.1"]
                  [hiccup "1.0.5"]
+                 [commons-codec/commons-codec "1.10"]
                  [commons-validator/commons-validator "1.5.0"]
+                 [org.apache.httpcomponents/httpclient "4.5.1"]
+                 [clj-http "2.1.0" :exclusions [org.apache.httpcomponents/httpcore]]
+                 [slingshot "0.12.2"]
+                 [cheshire "5.5.0"]
                  [clojurewerkz/elastisch "2.2.1"]]
   :main ^:skip-aot sound-effector.web
   :uberjar-name "sound-effector-standalone.jar"
   :plugins [[lein-ring "0.9.7"]]
   :ring {:handler sound-effector.web/application
-         :init    sound-effector.web/migrate}
+         :init    sound-effector.web/migrate
+         :port    3000}
   :profiles {:dev     {:dependencies [[javax.servlet/servlet-api "2.5"]
                                       [ring-mock "0.1.5"]]}
              :uberjar {:omit-source true


Registering ch into vis chs.

Registering ch into vis chs.

--- src/cbfg/core.cljs
+++ src/cbfg/core.cljs
@@ -60,14 +60,24 @@
    "atake"
    {:beg (fn [vis actx args]
            (let [[ch] args]
-             (swap! vis #(assoc-in % [:actxs actx :wait-chs ch] :take))))
+             (swap! vis #(assoc-in % [:actxs actx :wait-chs ch] :take))
+             (swap! vis #(update-in % [:chs ch]
+                                    (fn [v]
+                                      (if (nil? v)
+                                        {:id ((:gen-id @vis)) :msgs {}}
+                                        (assoc-in v [:msgs msg] true)))))))
     :end (fn [vis actx args]
            (let [[ch result] args]
              (swap! vis #(dissoc-in % [:actxs actx :wait-chs ch]))))}
    "aput"
    {:beg (fn [vis actx args]
            (let [[ch msg] args]
-             (swap! vis #(assoc-in % [:actxs actx :wait-chs ch] :put))))
+             (swap! vis #(assoc-in % [:actxs actx :wait-chs ch] :put))
+             (swap! vis #(update-in % [:chs ch]
+                                    (fn [v]
+                                      (if (nil? v)
+                                        {:id ((:gen-id @vis)) :msgs {msg true}}
+                                        (assoc-in v [:msgs msg] true)))))))
     :end (fn [vis actx args]
            (let [[ch msg result] args]
              (swap! vis #(dissoc-in % [:actxs actx :wait-chs ch]))))}
@@ -96,7 +106,10 @@
       ["<div>" (string/join ":" (last actx))
        (if (not-empty wait-chs)
          [" -- waiting: ("
-          (map (fn [kv] [(second kv) ", "]) wait-chs)
+          (map (fn [kv]
+                 (let [[ch wait-kind] kv]
+                   [(:id (get (:chs vis) ch)) wait-kind ", "]))
+               wait-chs)
           ")"]
          [])
        "<ul>"
@@ -109,15 +122,17 @@
     "no actx"))

 (defn vis-init [cmds cmd-handlers]
-  (let [vis (atom {:actxs {} ; {actx -> {:children {}, :wait-chs {}}}.
-                   :chs {}}) ; {ch -> [ msgs... ]}.
-        max-inflight (atom 10)
+  (let [max-inflight (atom 10)
         event-delay (atom 0)
         event-ch (chan)
         last-id (atom 0)
+        gen-id #(swap! last-id inc)
+        w [{:gen-id gen-id
+            :event-ch event-ch}]
         root-actx (atom nil)
-        w [{:gen-id #(swap! last-id inc)
-            :event-ch event-ch}]]
+        vis (atom {:actxs {} ; {actx -> {:children {}, :wait-chs {}}}.
+                   :chs {}   ; {ch -> {:id (gen-id), :msgs {}}}.
+                   :gen-id gen-id})]
     (go-loop [num-events 0]
       (let [tdv @event-delay]
         (when (> tdv 0)


Fixed the update-password function with the workaround for H2 field names in update queries bug in korma

--- src/sdos_site/models/users.clj
+++ src/sdos_site/models/users.clj
@@ -84,7 +84,7 @@
   (when-let [id (:id user)]
     (-> (base-users-query db)
         (k/update
-         (k/set-fields {:password (hash-password new-password)})
+         (k/set-fields {"PASSWORD" (hash-password new-password)})
          (k/where {:id id})))))

 (defn match-of


use ec2 request

use ec2 request

--- src/shuppet/securitygroups.clj
+++ src/shuppet/securitygroups.clj
@@ -2,6 +2,7 @@
   (:require
    [shuppet
     [signature :refer [v2-url]]
+    [ec2 :as ec2]
     [util :refer :all]
     [campfire :as cf]]
    [environ.core :refer [env]]
@@ -16,27 +17,20 @@
 (def ^:private ec2-version (env :service-aws-ec2-api-version))

 (defn- acceptable-error?
-  [action status body];AWS sometimes doesnt return all the ip ranges!!!
+  [action status code];AWS sometimes doesnt return all the ip ranges!!!
   (and
    (or (= action "AuthorizeSecurityGroupIngress") (= action "AuthorizeSecurityGroupEgress"))
    (= status 400)
-   (= "InvalidPermission.Duplicate" (xml1-> body :Errors :Error :Code text))))
+   (= code "InvalidPermission.Duplicate")))

 (defn- get-request
   [params]
-  (let [url (v2-url ec2-url (merge {"Version" ec2-version} params))
-        response (client/get url {:as :stream
-                                  :throw-exceptions false})
-        status (:status response)
-        body (-> (:body response)
-                 (xml/parse)
-                 (zip/xml-zip))]
-    (log/info "Security group request: " url)
-
-    (cond
-     (= 200 status) body
-     (acceptable-error? (get params "Action") status body) nil
-     :else (throw-aws-exception "EC2" (get params "Action") url status body)) ))
+  (try+
+   (ec2/get-request params)
+   (catch [:type :shuppet.util/aws] {:keys [status code] :as e}
+       (if (acceptable-error? (params "Action") status code)
+         nil
+         (throw+ e)))))

 (defn- create-params [opts]
   (without-nils {"GroupName" (:GroupName opts)


ignore error when deleting sg

ignore error when deleting sg

--- src/shuppet/securitygroups.clj
+++ src/shuppet/securitygroups.clj
@@ -58,11 +58,15 @@
     :CreateSecurityGroup (create params)
     (get-request (merge params {"Action" (name action)}))))

+(defn- filter-params
+  [name vpc-id]
+  {"Filter.1.Name" "group-name"
+   "Filter.1.Value" name
+   "Filter.2.Name" "vpc-id"
+   "Filter.2.Value" vpc-id})
+
 (defn- retrieve-sg-id [name vpc-id]
-  (xml1-> (process :DescribeSecurityGroups {"Filter.1.Name" "group-name"
-                                              "Filter.1.Value" name
-                                              "Filter.2.Name" "vpc-id"
-                                              "Filter.2.Value" vpc-id})
+  (xml1-> (process :DescribeSecurityGroups (filter-params name vpc-id))
           :securityGroupInfo :item :groupId text))

 (defn- sg-rule
@@ -174,14 +178,16 @@

 (defn- delete-sg
   [name vpc-id]
-  (if-let [id (sg-id name vpc-id)]
-    (do
-      (process :DeleteSecurityGroup {"GroupId" id})
-      (cf/info  (str "I've succesfully deleted the security group '" name "' with id: " id)))))
+  (try+
+   (if-let [id (sg-id name vpc-id)]
+     (do
+       (process :DeleteSecurityGroup {"GroupId" id})
+       (cf/info  (str "I've succesfully deleted the security group '" name "' with id: " id))))
+   (catch [:type :shuppet.securitygroups/sg-not-found] _
+     (log/info "Ignore sg-not-found when deleting"))))

 (defn- build-sg
   [opts]
-  (delete-sg (:GroupName opts) (:VpcId opts))
   (if-let [sg-id (create opts)]
     (try+
      (do
@@ -190,15 +196,6 @@
      (catch map? error
        (delete-sg (:GroupName opts) (:VpcId opts))
        (throw+ error)))))
-
-(defn- filter-params
-  [opts]
-  {"Filter.1.Name" "group-name"
-   "Filter.1.Value" (:GroupName opts)
-   "Filter.2.Name" "vpc-id"
-   "Filter.2.Value" (:VpcId opts)
-   "Filter.3.Name" "description"
-   "Filter.3.Value" (:GroupDescription opts)})

 (defn- update-sg-id
   [name vpc-id]
@@ -223,11 +220,11 @@
   "Get details of the security group, if one exists
    if not present create and apply ingress/outgress
    if present compare with the local config and apply changes if needed"
-  [opts]
+  [{:keys [VpcId GroupName Ingress Egress] :as opts}]
   (let [opts (-> opts
-                 (assoc :Ingress (update-sg-ids (:Ingress opts) (:VpcId opts)))
-                 (assoc :Egress (update-sg-ids (:Egress opts) (:VpcId opts))))
-        response (process :DescribeSecurityGroups (filter-params opts))]
+                 (assoc :Ingress (update-sg-ids Ingress VpcId))
+                 (assoc :Egress (update-sg-ids Egress VpcId)))
+        response (process :DescribeSecurityGroups (filter-params GroupName VpcId))]
     (if-let [sg-id (xml1-> response :securityGroupInfo :item :groupId text)]
       (compare-sg sg-id response opts)
       (build-sg opts))))


implement param-query w/ qvars & 2-way join query vertices

--- src/thi/ng/fabric/triples.cljc
+++ src/thi/ng/fabric/triples.cljc
@@ -46,9 +46,15 @@
        ;;(info :coll-select val incoming)
        val))))

-(defn score-aggregate-select
-  [vertex]
-  (if (> 3 (count (vals (peek (::f/uncollected @(:state vertex)))))) 0 1))
+(defn score-collect-min-signal-vals
+  [num]
+  (fn [vertex]
+    (if (> num (count (vals (peek (::f/uncollected @(:state vertex)))))) 0 1)))
+
+(defn score-collect-min-signals
+  [num]
+  (fn [vertex]
+    (if (> num (count (::f/uncollected @(:state vertex)))) 0 1)))

 (defn aggregate-select
   [g]
@@ -137,7 +143,7 @@
           res (f/add-vertex!
                g {:val (delay nil)
                   ::f/collect-fn (aggregate-select g)
-                  ::f/score-collect-fn score-aggregate-select})]
+                  ::f/score-collect-fn (score-collect-min-signal-vals 3)})]
       (f/add-edge! g subj acc signal-select [0 s])
       (f/add-edge! g pred acc signal-select [1 p])
       (f/add-edge! g obj  acc signal-select [2 o])
@@ -182,17 +188,116 @@
     (f/add-edge! g src v f/signal-forward nil)
     v))

+(defn qvar?
+  "Returns true, if x is a qvar (a symbol prefixed with '?')"
+  [x] (and (symbol? x) (= \? (.charAt ^String (name x) 0))))
+
+(defn bind-translator
+  [vs? vp? vo? s p o]
+  (if vs?
+    (if vp?
+      (if vo?
+        (fn [r] {s (r 0) p (r 1) o (r 2)})
+        (fn [r] {s (r 0) p (r 1)}))
+      (if vo?
+        (fn [r] {s (r 0) o (r 2)})
+        (fn [r] {s (r 0)})))
+    (if vp?
+      (if vo?
+        (fn [r] {p (r 1) o (r 2)})
+        (fn [r] {p (r 1)}))
+      (if vo?
+        (fn [r] {o (r 2)})
+        (fn [_] {})))))
+
+(defn pattern-translator
+  [vs? vp? vo? [s p o]]
+  (if (qvar? vs? s)
+    (if (qvar? vp? p)
+      (if (qvar? vo? o)
+        (fn [p] [nil nil nil])
+        (fn [p] [nil nil (p 2)]))
+      (if (qvar? vo? o)
+        (fn [p] [nil (p 1) nil])
+        (fn [p] (assoc p 0 nil))))
+    (if (qvar? vp? p)
+      (if (qvar? vo? o)
+        (fn [p] [(p 0) nil nil])
+        (fn [p] (assoc p 1 nil)))
+      (if (qvar? vo? o)
+        (fn [p] (assoc p 2 nil))
+        identity))))
+
+(defn triple-verifier
+  [ts tp to vars varp varo]
+  (cond
+    (and vars varp varo) (cond
+                           (= ts tp to) (fn [r] (= (r 0) (r 1) (r 2)))
+                           (= ts tp) (fn [r] (and (= (r 0) (r 1)) (not= (r 0) (r 2))))
+                           (= ts to) (fn [r] (and (= (r 0) (r 2)) (not= (r 0) (r 1))))
+                           (= tp to) (fn [r] (and (= (r 1) (r 2)) (not= (r 0) (r 1))))
+                           :else (constantly true))
+    (and vars varp)      (if (= ts tp)
+                           (fn [r] (= (r 0) (r 1)))
+                           (fn [r] (not= (r 0) (r 1))))
+    (and vars varo)      (if (= ts to)
+                           (fn [r] (= (r 0) (r 2)))
+                           (fn [r] (not= (r 0) (r 2))))
+    (and varp varo)      (if (= tp to)
+                           (fn [r] (= (r 1) (r 2)))
+                           (fn [r] (not= (r 1) (r 2))))
+    :else                (constantly true)))
+
+(defn param-query
+  [g id [s p o]]
+  (let [vs?        (qvar? s), vp? (qvar? p), vo? (qvar? o)
+        vmap       (bind-translator vs? vp? vo? s p o)
+        verify     (triple-verifier s p o vs? vp? vo?)
+        collect-fn (f/simple-collect
+                    (fn [_ incoming]
+                      (delay
+                       (when-let [res (peek incoming)]
+                         (into #{}
+                               (comp (map #(if (verify %) (vmap %)))
+                                     (filter identity))
+                               @res)))))
+        q-pattern  [(if vs? nil s) (if vp? nil p) (if vo? nil o)]
+        q-spec     (add-query! g id q-pattern)
+        r-vertex   (f/add-vertex! g {:val (delay nil) ::f/collect-fn collect-fn})]
+    (f/add-edge! g (:result q-spec) r-vertex f/signal-forward nil)
+    (assoc q-spec :qvar-result r-vertex)))
+
+(defn add-join-query
+  [g pat-a pat-b]
+  (let [qa  (param-query g (keyword (gensym)) pat-a)
+        qb  (param-query g (keyword (gensym)) pat-b)
+        jfn (fn [vertex]
+              (let [state (:state vertex)
+                    a @(get-in @state [::f/signal-map (:id (:qvar-result qa))])
+                    b @(get-in @state [::f/signal-map (:id (:qvar-result qb))])]
+                (info :join-sets a b)
+                (swap! state assoc :val (set/join a b))))
+        jv  (f/add-vertex!
+             g {:val (delay nil)
+                ::f/collect-fn jfn
+                ::f/score-collect-fn #(if (== (count (::f/signal-map @(:state %))) 2) 1 0)})]
+    (f/add-edge! g (:qvar-result qa) jv f/signal-forward nil)
+    (f/add-edge! g (:qvar-result qb) jv f/signal-forward nil)
+    {:a qa :b qb :join jv}))
+
 (defn start
   []
   (let [g (triple-graph (f/compute-graph))
         toxi (:result (add-query! g :toxi ['toxi nil nil]))
         types (:result (add-query! g :types [nil 'type nil]))
         projects (:result (add-query! g :projects [nil 'type 'project]))
+        knows (:result (add-query! g :projects [nil 'knows nil]))
         all (:result (add-query! g :all [nil nil nil]))
         num-projects (add-counter! g projects)
         num-types (add-counter! g types)
         inf1 (add-rule! g :knows [nil 'knows nil] (fn [[s p o]] [[s 'type 'person] [o 'type 'person] [o 'knows s]]))
-
+        pq (:qvar-result (param-query g :pq '[?s knows ?o]))
+        jq (:join (add-join-query g '[?p author ?prj] '[?prj type project]))
         ctx (f/async-context {:graph g :processor f/eager-vertex-processor :timeout nil})]
     (f/execute! ctx)
     (mapv
@@ -206,6 +311,9 @@
      :all all
      :toxi toxi
      :types types
+     :knows knows
      :projects projects
+     :pq pq
+     :jq jq
      :num-projects num-projects
      :num-types num-types}))


Document :on-duplicate-key-update clause order number

--- src/onyx/plugin/mysql.clj
+++ src/onyx/plugin/mysql.clj
@@ -18,4 +18,9 @@
                              (str (hformat/to-sql k) " = "
                                   (hformat/to-sql v))))))

-(hformat/register-clause! :on-duplicate-key-update 225)
+;; This number is used to insert the clause towards the end of the constructed
+;; SQL string. honeysql-postgres was used as reference:
+;; https://github.com/nilenso/honeysql-postgres/blob/master/src/honeysql_postgres/format.clj#L19
+(def clause-order 225)
+
+(hformat/register-clause! :on-duplicate-key-update clause-order)


Make sure that no pipeline is created for pmap scenarios.

--- src/dsbdp/main.clj
+++ src/dsbdp/main.clj
@@ -171,7 +171,8 @@
                    (.inc out-cntr))
           pipeline (if (and
                          (not (nil? in-data))
-                         (not (.endsWith scenario "-direct")))
+                         (not (.endsWith scenario "-direct"))
+                         (not (.endsWith scenario "-pmap")))
                      (create-local-processing-pipeline
                        @proc-fns
                        out-fn))


Cleaned up safe door close/open and commented


also exclude clojure.core/list

also exclude clojure.core/list


Fix cluser start using credentials

Fix cluser start using credentials


Adds: delete the exhibitor bucket on destroy

Without the :force_destroy you get the following error:

* aws_s3_bucket.sandpit-staging-exhibitor-s3-bucket: Error deleting S3 Bucket: BucketNotEmpty: The bucket you tried to delete is not empty
	status code: 409, request id: 335F9D5BC263A461


Comment fixes

Comment fixes

--- src/workshop/challenge_3_0.clj
+++ src/workshop/challenge_3_0.clj
@@ -65,7 +65,7 @@
 ;; in a few ways, but typically it's most convenient to use
 ;; :onyx/params in the catalog entry. Parameters are prepended
 ;; to *the front* of the function signature. The segment always
-;; comes last. That is, the a function with two added parameters
+;; comes last. That is, a function with two added parameters
 ;; will have signature:
 ;;
 ;; (fn name [param-1 param-2 segment])


Rename Queryable to QueryableStory.

Rename Queryable to QueryableStory.

--- src/isla/story.clj
+++ src/isla/story.clj
@@ -9,7 +9,6 @@

 (declare types name-into-objs extract-by-class get-story-ctx seq-to-hash resolve-)

-(defprotocol Queryable
   (get-all-items [this])
   (get-item [this name]))
 (defrecord Monster [name summary])
@@ -19,12 +18,13 @@
 (def player-defaults ["" "" :undefined])

+(defprotocol QueryableStory

 (defprotocol Playable

 (defrecord Story [player rooms]
-  Queryable
   (get-all-items [this]
+  QueryableStory
     (concat (map (fn [x] (:items x)) rooms)))
   (get-item [this name]
     (if-let [item (first (filter (fn [y] (= name (:name y))) (get-all-items this)))]


Fix whitespace

Fix whitespace

--- src/mdr2/views.clj
+++ src/mdr2/views.clj
@@ -126,7 +126,6 @@
                           [:button.btn.btn-default
                            (layout/glyphicon "transfer")]])]])]])))

-
 (defn production-catalog [request id library_signature]
   (let [user (friend/current-authentication request)
         p (assoc (prod/find id)


Need a PrintWriter.

Need a PrintWriter.

--- src/monocle/io.clj
+++ src/monocle/io.clj
@@ -42,7 +42,7 @@
           (for [b (interpose ["-- "]
                              (partition-all batch (line-seq reader)))
                 l b]
-            (.println ptr l)))))
+            (.println (-> ptr java.io.PrintWriter.) l)))))

 (defn write-stdout [reader batch]
   (write-printer *out* reader batch))


window/id spec now allows uuid.

window/id spec now allows uuid.

--- src/onyx/spec.cljc
+++ src/onyx/spec.cljc
@@ -201,7 +201,7 @@
     :millisecond :milliseconds
     :element :elements})

-(s/def :window/id keyword?)
+(s/def :window/id (s/or :keyword keyword? :uuid uuid?))

 (s/def :window/task keyword?)


added single address capability

added single address capability

--- src/rodeo/core.clj
+++ src/rodeo/core.clj
@@ -7,10 +7,22 @@

 (defn batch
   "Takes a vector of addresses and
-  makes a request to Geocodio"
+  makes a request to Geocodio.
+  Returns a Clojure map of results."
   [addresses]
   (let [addr-json (che/generate-string addresses)]
     (che/parse-string
       (->> {:body addr-json :content-type :json :accept :json}
            (http/post url)
            (:body)) true)))
+
+(defn single
+  "Takes a single address string and
+  makes a request to Geocodio. Returns
+  a Clojure map of results"
+  [address]
+  (let [get-url (str url "&q=" address)]
+    (-> get-url
+        (http/get)
+        (:body)
+        (che/parse-string true))))


`transform-reads` when calling `transact!` against the reconciler

--- src/main/compassus/core.cljs
+++ src/main/compassus/core.cljs
@@ -74,7 +74,8 @@
          next-route (cond-> next-route
                       (keyword? next-route) (vector '_))]
      (om/transact! reconciler (cond-> `[(update-route! {:route ~next-route})]
-                                queue? (conj ::route-data))))))
+                                queue?
+                                (into (om/transform-reads reconciler [::route-data])))))))

 (defn- infer-query
   [{:keys [query]} route]


WIP selenium tests for clicking artist/album name


Add missing "color" namespace.

Add missing "color" namespace.

--- src/videotest/coral/coral.clj
+++ src/videotest/coral/coral.clj
@@ -1,6 +1,7 @@
 (ns videotest.coral.coral
   (:require
    [quil.core :as q]
+   [videotest.coral.color :as color]
    [videotest.coral.hex :as hex]))


fix leading 0 getting dropped sometimes

fix leading 0 getting dropped sometimes

--- src/vip/data_processor/s3.clj
+++ src/vip/data_processor/s3.clj
@@ -72,7 +72,7 @@
           (.toByteArray xout))
         algorithm (MessageDigest/getInstance "sha-512")
         raw (.digest algorithm bytes')]
-    (format "%032x" (BigInteger. 1 raw))))
+    (apply str (map #(format "%02x" %) raw))))

 (defn upload-to-s3
   "Zips up the xml output file and uploads to the specified S3 bucket if there


extend minmax to localdate fixes #88

extend minmax to localdate fixes #88

--- src/tick/core.cljc
+++ src/tick/core.cljc
@@ -948,6 +948,9 @@
   LocalTime
   (min-of-type [_] cljc.java-time.local-time/min)
   (max-of-type [_] cljc.java-time.local-time/max)
+  LocalDate
+  (min-of-type [_] cljc.java-time.local-date/min)
+  (max-of-type [_] cljc.java-time.local-date/max)
   LocalDateTime
   (min-of-type [_] cljc.java-time.local-date-time/min)
   (max-of-type [_] cljc.java-time.local-date-time/max)


Fix tests

Fix tests

--- src/tick/core.cljc
+++ src/tick/core.cljc
@@ -203,13 +203,7 @@
   (inst [zdt] (inst (instant zdt)))
   (instant [zdt] (.toInstant zdt))
   (offset-date-time [zdt] (.toOffsetDateTime zdt))
-  (zoned-date-time [zdt] zdt)
-
-  ;; Durations between the epoch and a time. These are useful
-  ;; conversion functions in the case where numerics are used.
-  Duration
-  (instant [d] (java.time.Instant/ofEpochMilli (millis d)))
-  (inst [d] (inst (instant d))))
+  (zoned-date-time [zdt] zdt))

 (extend-protocol IExtraction
   #?(:clj Object :cljs object)
@@ -623,6 +617,13 @@
   (months [_] "Return the given quantity in months.")
   (years [_] "Return the given quantity in years."))

+(extend-protocol IConversion
+  ;; Durations between the epoch and a time. These are useful
+  ;; conversion functions in the case where numerics are used.
+  Duration
+  (instant [d] (java.time.Instant/ofEpochMilli (millis d)))
+  (inst [d] (inst (instant d))))
+
 (extend-protocol ITimeLength
   Duration
   (nanos [d] (.toNanos d))


repl can remove todos and notes - save file by exit

--- src/todos/core.clj
+++ src/todos/core.clj
@@ -4,25 +4,6 @@
   (:require [todos.todo-item :as t-item])
   (:require [todos.storage :as storage])
   (:require [clojure.string :as stri]))
-
-(defn demo
-  "This is currently just a demo!"
-  []
-  (let
-    [todolist (t-item/todo-load-from-plain (storage/load-data
-                                             (((t-item/todo-create "main") :plain))
-                                             ))
-     sub-a    (t-item/todo-create (inp/user-str-input "Beispielname für SubTodo-A: "))
-     sub-b    (t-item/todo-create (inp/user-str-input "Beispielname für SubTodo-B: "))]
-    ((todolist :note-add) (inp/user-str-input "Beispielnotiz: "))
-    ((todolist :todo-add) sub-a)
-    ((todolist :todo-add) sub-b)
-    ((sub-a :set-done) true)
-    ((sub-b :note-add) "arbeit arbeit")
-    ((todolist :print) "")
-    (println ((todolist :plain)))
-    (storage/save-data ((todolist :plain)))
-    ))

 (def todolist
   (t-item/todo-load-from-plain
@@ -70,6 +51,19 @@
         ;
         (= cmd "note")
         ((current-todo :note-add) joined-args)
+        ;
+        ; remove
+        ;
+        (= cmd "remove")
+        (let [m (find-by-name ((current-todo :todos)) joined-args)]
+          (if (and m (= "yes" (inp/user-str-input
+                                (format "Are you sure to delete \"%s\"? (yes/no) " ((m :name)))
+                                )))
+            ((current-todo :todo-rm) m)
+            ))
+        ;
+        (= cmd "rm-note")
+        ((current-todo :note-rm) joined-args)
         ;
         ; manipulation
         ;
@@ -125,5 +119,8 @@
 (defn -main
   "Start the demo ..."
   [& args]
-  (command-repl))
+  (do
+    (command-repl)
+    (storage/save-data ((todolist :plain)))
+    ))


Cleanup import and hinting

Cleanup import and hinting

--- src/onyx/messaging/aeron.clj
+++ src/onyx/messaging/aeron.clj
@@ -8,15 +8,12 @@
             [onyx.extensions :as extensions]
             [onyx.compression.nippy :refer [compress decompress]]
             [onyx.static.default-vals :refer [defaults arg-or-default]])
-  (:import [uk.co.real_logic.aeron Aeron FragmentAssembler]
-           [uk.co.real_logic.aeron Aeron$Context]
-           [uk.co.real_logic.aeron Publication]
+  (:import [uk.co.real_logic.aeron Aeron Aeron$Context FragmentAssembler Publication Subscription]
            [uk.co.real_logic.aeron.driver MediaDriver MediaDriver$Context ThreadingMode]
            [uk.co.real_logic.aeron.logbuffer FragmentHandler]
-           [uk.co.real_logic.agrona.concurrent UnsafeBuffer]
-           [uk.co.real_logic.agrona CloseHelper]
-           [uk.co.real_logic.agrona ErrorHandler]
-           [uk.co.real_logic.agrona.concurrent IdleStrategy BackoffIdleStrategy BusySpinIdleStrategy]
+           [uk.co.real_logic.agrona ErrorHandler CloseHelper]
+           [uk.co.real_logic.agrona.concurrent
+            UnsafeBuffer IdleStrategy BackoffIdleStrategy BusySpinIdleStrategy]
            [java.util.function Consumer]
            [java.util.concurrent TimeUnit]))

@@ -112,7 +109,7 @@
   (reify Consumer
     (accept [this subscription]
       (while (not (Thread/interrupted))
-        (let [fragments-read (.poll ^uk.co.real_logic.aeron.Subscription subscription ^FragmentHandler handler ^int limit)]
+        (let [fragments-read (.poll ^Subscription subscription ^FragmentHandler handler ^int limit)]
           (.idle idle-strategy fragments-read))))))

 (defn handle-message [decompress-f virtual-peers buffer offset length header]
@@ -260,7 +257,7 @@
     (future-cancel (:pub-gc-thread component))
     (doseq [subscriber subscribers]
       (future-cancel (:subscriber-fut subscriber))
-      (.close ^uk.co.real_logic.aeron.Subscription (:subscription subscriber))
+      (.close ^Subscription (:subscription subscriber))
       (.close ^Aeron (:conn subscriber)))
     (doseq [pub (vals @publications)]
       (.close ^Publication (:publication pub)))


Alternative discover-tasks that allows us to override id gen

--- src/onyx/static/planning.clj
+++ src/onyx/static/planning.clj
@@ -79,16 +79,19 @@
         (map (juxt identity (fn [_] (java.util.UUID/randomUUID)))
              nodes)))

-(defn discover-tasks [catalog workflow]
-  (let [dag (to-dependency-graph workflow)
-        sorted-dag (dep/topo-sort dag)
-        task-ids (gen-task-ids sorted-dag)]
-    (remove-dupes
-     (reduce
-      (fn [tasks element]
-        (let [parents (dep/immediate-dependencies dag element)
-              children (dep/immediate-dependents dag element)
-              parent-entries (filter #(some #{(:name %)} parents) tasks)]
-          (conj tasks (create-task task-ids catalog element parent-entries children))))
-      []
-      sorted-dag))))
+(defn discover-tasks
+  ([catalog workflow]
+   (discover-tasks catalog workflow gen-task-ids))
+  ([catalog workflow gen-task-fn]
+   (let [dag (to-dependency-graph workflow)
+         sorted-dag (dep/topo-sort dag)
+         task-ids (gen-task-fn sorted-dag)]
+     (remove-dupes
+       (reduce
+         (fn [tasks element]
+           (let [parents (dep/immediate-dependencies dag element)
+                 children (dep/immediate-dependents dag element)
+                 parent-entries (filter #(some #{(:name %)} parents) tasks)]
+             (conj tasks (create-task task-ids catalog element parent-entries children))))
+         []
+         sorted-dag)))))


goals to int

goals to int

--- src/paulkrake/datacenter.clj
+++ src/paulkrake/datacenter.clj
@@ -158,11 +158,12 @@
              (vector home away hg_new ag_new)))
          x)))

+(defn score [saison spieltag-nr]
+  (as-> (data saison spieltag-nr "score") x
+    (map (fn [[h g hg gg]] (vector h g (int hg) (int gg))) x)))
+
 (defn spieltag [saison spieltag-nr]
-  (data saison spieltag-nr "score"))
-
-(defn score [saison spieltag-nr]
-  (data saison spieltag-nr "score"))
+  (score saison spieltag-nr))

 (defn shots-on-goal [saison spieltag-nr]
   (data saison spieltag-nr "shots"))


small changes

small changes

--- figwheel-repl/src/figwheel/repl.cljc
+++ figwheel-repl/src/figwheel/repl.cljc
@@ -262,7 +262,7 @@
 ;; Websocket REPL
 ;; --------------------------------------------------------------

-(goog-define connect-url "ws://[[client-host]]:[[client-port]]/figwheel-connect")
+(goog-define connect-url "ws://[[client-hostname]]:[[client-port]]/figwheel-connect")

 (def state (atom {}))

@@ -947,7 +947,8 @@
                                                 :ring-server-options
                                                 :ring-stack
                                                 :ring-stack-options])
-                         (select-keys opts [:target]))
+                         (select-keys opts [:target
+                                            :output-to]))
                   *connections*)]
       (reset! (:server-kill repl-env) (fn [] (.stop server)))))
   ;; printing