Add 2nd gen pokemon

Add 2nd gen pokemon

Try to add basic data from the 2nd gen Pokemon

--- frontend/src/cruncher/data/pokemon.cljs
+++ frontend/src/cruncher/data/pokemon.cljs
@@ -1727,4 +1727,1102 @@
                :fast-attacks   ["Unknown"]
                :special-attack ["Unknown"]
                :weight         "4.0 kg"
-               :height         "0.4 m"}})
+               :height         "0.4 m"}
+
+          152 {:pokemon-id     152
+               :name           "Chikorita"
+               :classification "New Species Pokémon"
+               :type-1         ["Grass"]
+               :weaknesses     ["Unknown"]
+               :fast-attacks   ["Unknown"]
+               :special-attack ["Unknown"]
+               :weight         "Unknown"
+               :height         "Unknown"
+               :next-evolution-requirements {:amount 25
+                                             :name   "Chikorita candies"}
+               :next-evolutions             [153]}
+
+          153 {:pokemon-id     153
+               :name           "Bayleef"
+               :classification "New Species Pokémon"
+               :type-1         ["Grass"]
+               :weaknesses     ["Unknown"]
+               :fast-attacks   ["Unknown"]
+               :special-attack ["Unknown"]
+               :weight         "Unknown"
+               :height         "Unknown"
+               :next-evolution-requirements {:amount 100
+                                             :name   "Chikorita candies"}
+               :next-evolutions             [154]
+               :previous-evolutions [152]}
+
+          154 {:pokemon-id     154
+               :name           " Meganium"
+               :classification "New Species Pokémon"
+               :type-1         ["Grass"]
+               :weaknesses     ["Unknown"]
+               :fast-attacks   ["Unknown"]
+               :special-attack ["Unknown"]
+               :weight         "Unknown"
+               :height         "Unknown"
+               :previous-evolutions [153]}
+
+          155 {:pokemon-id     155
+                :name           "Cyndaquil"
+                :classification "New Species Pokémon"
+                :type-1         ["Fire "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"
+                :next-evolution-requirements {:amount 25
+                                              :name   "Cyndaquil candies"
+                :next-evolutions [156]}
+
+          156 {:pokemon-id     156
+                :name           "Quilava"
+                :classification "New Species Pokémon"
+                :type-1         ["Fire "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"
+                :next-evolution-requirements {:amount 100
+                                              :name   "Quilava candies"
+                :next-evolutions [157]}
+
+          157 {:pokemon-id     157
+                :name           "Typhlosion"
+                :classification "New Species Pokémon"
+                :type-1         ["Fire "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          158 {:pokemon-id     158
+                :name           "Totodile"
+                :classification "New Species Pokémon"
+                :type-1         ["Water "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"
+                :next-evolution-requirements {:amount 25
+                                              :name   "Totodile candies"
+                :next-evolutions [159]}
+
+          159 {:pokemon-id     159
+                :name           "Croconaw"
+                :classification "New Species Pokémon"
+                :type-1         ["Water "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"
+                :next-evolution-requirements {:amount 100
+                                              :name   "Croconaw candies"
+                :next-evolutions [160]}
+
+          160 {:pokemon-id     160
+                :name           "Feraligatr"
+                :classification "New Species Pokémon"
+                :type-1         ["Water "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          161 {:pokemon-id     161
+                :name           "Sentret"
+                :classification "New Species Pokémon"
+                :type-1         ["Normal "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"
+                :next-evolution-requirements {:amount 25
+                                              :name   "Sentret candies"
+                :next-evolutions [162]}
+
+          162 {:pokemon-id     162
+                :name           "Furret"
+                :classification "New Species Pokémon"
+                :type-1         ["Normal "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          163 {:pokemon-id     163
+                :name           "Hoothoot"
+                :classification "New Species Pokémon"
+                :type-1         ["Normal "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"
+                :next-evolution-requirements {:amount 50
+                                              :name   "Hoothoot candies"
+                :next-evolutions [164]}
+
+          164 {:pokemon-id     164
+                :name           "Noctowl"
+                :classification "New Species Pokémon"
+                :type-1         ["Normal "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          165 {:pokemon-id     165
+                :name           "Ledyba"
+                :classification "New Species Pokémon"
+                :type-1         ["Bug "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"
+                :next-evolution-requirements {:amount 25
+                                              :name   "Ledyba candies"
+                :next-evolutions [166]}
+
+          166 {:pokemon-id     166
+                :name           "Ledian"
+                :classification "New Species Pokémon"
+                :type-1         ["Bug "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          167 {:pokemon-id     167
+                :name           "Spinarak"
+                :classification "New Species Pokémon"
+                :type-1         ["Bug "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"
+                :next-evolution-requirements {:amount 50
+                                              :name   "Spinarak candies"
+                :next-evolutions [168]}
+
+          168 {:pokemon-id     168
+                :name           "Ariados"
+                :classification "New Species Pokémon"
+                :type-1         ["Bug "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          169 {:pokemon-id     169
+                :name           "Crobat"
+                :classification "New Species Pokémon"
+                :type-1         ["Poison "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          170 {:pokemon-id     170
+                :name           "Chinchou"
+                :classification "New Species Pokémon"
+                :type-1         ["Water "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"
+                :next-evolution-requirements {:amount 50
+                                              :name   "Chinchou candies"
+                :next-evolutions [171]}
+
+          171 {:pokemon-id     171
+                :name           "Lanturn"
+                :classification "New Species Pokémon"
+                :type-1         ["Water "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          172 {:pokemon-id     172
+                :name           "Pichu"
+                :classification "New Species Pokémon"
+                :type-1         ["Electric "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"
+                :next-evolution-requirements {:amount 25
+                                              :name   "Pichu candies"
+                :next-evolutions [173]}
+
+          173 {:pokemon-id     173
+                :name           "Cleffa"
+                :classification "New Species Pokémon"
+                :type-1         ["Normal "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"
+                :next-evolution-requirements {:amount 25
+                                              :name   "Cleffa candies"
+                :next-evolutions [174]}
+
+          174 {:pokemon-id     174
+                :name           "Igglybuff"
+                :classification "New Species Pokémon"
+                :type-1         ["Normal "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"
+                :next-evolution-requirements {:amount 25
+                                              :name   "Igglybuff candies"
+                :next-evolutions [175]}
+
+          175 {:pokemon-id     175
+                :name           "Togepi"
+                :classification "New Species Pokémon"
+                :type-1         ["Normal "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"
+                :next-evolution-requirements {:amount 25
+                                              :name   "Togepi candies"
+                :next-evolutions [176]}
+
+          176 {:pokemon-id     176
+                :name           "Togetic"
+                :classification "New Species Pokémon"
+                :type-1         ["Normal "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          177 {:pokemon-id     177
+                :name           "Natu"
+                :classification "New Species Pokémon"
+                :type-1         ["Psychic "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"
+                :next-evolution-requirements {:amount 50
+                                              :name   "Natu candies"
+                :next-evolutions [178]}
+
+          178 {:pokemon-id     178
+                :name           "Xatu"
+                :classification "New Species Pokémon"
+                :type-1         ["Psychic "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          179 {:pokemon-id     179
+                :name           "Mareep"
+                :classification "New Species Pokémon"
+                :type-1         ["Electric "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          180 {:pokemon-id     180
+                :name           "Flaaffy"
+                :classification "New Species Pokémon"
+                :type-1         ["Electric "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          181 {:pokemon-id     181
+                :name           "Ampharos"
+                :classification "New Species Pokémon"
+                :type-1         ["Electric "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          182 {:pokemon-id     182
+                :name           "Bellossom"
+                :classification "New Species Pokémon"
+                :type-1         ["Grass "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          183 {:pokemon-id     183
+                :name           "Marill"
+                :classification "New Species Pokémon"
+                :type-1         ["Water "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"
+                :next-evolution-requirements {:amount 25
+                                              :name   "Marill candies"
+                :next-evolutions [184]}
+
+          184 {:pokemon-id     184
+                :name           "Azumarill"
+                :classification "New Species Pokémon"
+                :type-1         ["Water "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          185 {:pokemon-id     185
+                :name           "Sudowoodo"
+                :classification "New Species Pokémon"
+                :type-1         ["Rock "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          186 {:pokemon-id     186
+                :name           "Politoed"
+                :classification "New Species Pokémon"
+                :type-1         ["Water "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          187 {:pokemon-id     187
+                :name           "Hoppip"
+                :classification "New Species Pokémon"
+                :type-1         ["Grass "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"
+                :next-evolution-requirements {:amount 25
+                                              :name   "Hoppip candies"
+                :next-evolutions [188]}
+
+          188 {:pokemon-id     188
+                :name           "Skiploom"
+                :classification "New Species Pokémon"
+                :type-1         ["Grass "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          189 {:pokemon-id     189
+                :name           "Jumpluff"
+                :classification "New Species Pokémon"
+                :type-1         ["Grass "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          190 {:pokemon-id     190
+                :name           "Aipom"
+                :classification "New Species Pokémon"
+                :type-1         ["Normal "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          191 {:pokemon-id     191
+                :name           "Sunkern"
+                :classification "New Species Pokémon"
+                :type-1         ["Grass "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"
+                :next-evolution-requirements {:amount 50
+                                              :name   "Sunkern candies"
+                :next-evolutions [192]}
+
+          192 {:pokemon-id     192
+                :name           "Sunflora"
+                :classification "New Species Pokémon"
+                :type-1         ["Grass "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          193 {:pokemon-id     193
+                :name           "Yanma"
+                :classification "New Species Pokémon"
+                :type-1         ["Bug "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          194 {:pokemon-id     194
+                :name           "Wooper"
+                :classification "New Species Pokémon"
+                :type-1         ["Water "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"
+                :next-evolution-requirements {:amount 50
+                                              :name   "Wooper candies"
+                :next-evolutions [195]}
+
+          195 {:pokemon-id     195
+                :name           "Quagsire"
+                :classification "New Species Pokémon"
+                :type-1         ["Water "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          196 {:pokemon-id     196
+                :name           "Espeon"
+                :classification "New Species Pokémon"
+                :type-1         ["Psychic "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          197 {:pokemon-id     197
+                :name           "Umbreon"
+                :classification "New Species Pokémon"
+                :type-1         ["Dark "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          198 {:pokemon-id     198
+                :name           "Murkrow"
+                :classification "New Species Pokémon"
+                :type-1         ["Dark "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          199 {:pokemon-id     199
+                :name           "Slowking"
+                :classification "New Species Pokémon"
+                :type-1         ["Water "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          200 {:pokemon-id     200
+                :name           "Misdreavus"
+                :classification "New Species Pokémon"
+                :type-1         ["Ghost "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          201 {:pokemon-id     201
+                :name           "Unown"
+                :classification "New Species Pokémon"
+                :type-1         ["Psychic "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          202 {:pokemon-id     202
+                :name           "Wobbuffet"
+                :classification "New Species Pokémon"
+                :type-1         ["Psychic "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          203 {:pokemon-id     203
+                :name           "Girafarig"
+                :classification "New Species Pokémon"
+                :type-1         ["Normal "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          204 {:pokemon-id     204
+                :name           "Pineco"
+                :classification "New Species Pokémon"
+                :type-1         ["Bug "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"
+                :next-evolution-requirements {:amount 50
+                                              :name   "Pineco candies"
+                :next-evolutions [205]}
+
+          205 {:pokemon-id     205
+                :name           "Forretress"
+                :classification "New Species Pokémon"
+                :type-1         ["Bug "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          206 {:pokemon-id     206
+                :name           "Dunsparce"
+                :classification "New Species Pokémon"
+                :type-1         ["Normal "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          207 {:pokemon-id     207
+                :name           "Gligar"
+                :classification "New Species Pokémon"
+                :type-1         ["Ground "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          208 {:pokemon-id     208
+                :name           "Steelix"
+                :classification "New Species Pokémon"
+                :type-1         ["Steel "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          209 {:pokemon-id     209
+                :name           "Snubbull"
+                :classification "New Species Pokémon"
+                :type-1         ["Normal "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"
+                :next-evolution-requirements {:amount 50
+                                              :name   "Snubbull candies"
+                :next-evolutions [210]}
+
+          210 {:pokemon-id     210
+                :name           "Granbull"
+                :classification "New Species Pokémon"
+                :type-1         ["Normal "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          211 {:pokemon-id     211
+                :name           "Qwilfish"
+                :classification "New Species Pokémon"
+                :type-1         ["Water "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          212 {:pokemon-id     212
+                :name           "Scizor"
+                :classification "New Species Pokémon"
+                :type-1         ["Bug "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          213 {:pokemon-id     213
+                :name           "Shuckle"
+                :classification "New Species Pokémon"
+                :type-1         ["Bug "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          214 {:pokemon-id     214
+                :name           "Heracross"
+                :classification "New Species Pokémon"
+                :type-1         ["Bug "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          215 {:pokemon-id     215
+                :name           "Sneasel"
+                :classification "New Species Pokémon"
+                :type-1         ["Dark "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          216 {:pokemon-id     216
+                :name           "Teddiursa"
+                :classification "New Species Pokémon"
+                :type-1         ["Normal "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"
+                :next-evolution-requirements {:amount 50
+                                              :name   "Teddiursa candies"
+                :next-evolutions [217]}
+
+          217 {:pokemon-id     217
+                :name           "Ursaring"
+                :classification "New Species Pokémon"
+                :type-1         ["Normal "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          218 {:pokemon-id     218
+                :name           "Slugma"
+                :classification "New Species Pokémon"
+                :type-1         ["Fire "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"
+                :next-evolution-requirements {:amount 50
+                                              :name   "Slugma candies"
+                :next-evolutions [219]}
+
+          219 {:pokemon-id     219
+                :name           "Magcargo"
+                :classification "New Species Pokémon"
+                :type-1         ["Fire "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          220 {:pokemon-id     220
+                :name           "Swinub"
+                :classification "New Species Pokémon"
+                :type-1         ["Ice "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          221 {:pokemon-id     221
+                :name           "Piloswine"
+                :classification "New Species Pokémon"
+                :type-1         ["Ice "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          222 {:pokemon-id     222
+                :name           "Corsola"
+                :classification "New Species Pokémon"
+                :type-1         ["Water "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          223 {:pokemon-id     223
+                :name           "Remoraid"
+                :classification "New Species Pokémon"
+                :type-1         ["Water "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"
+                :next-evolution-requirements {:amount 50
+                                              :name   "Remoraid candies"
+                :next-evolutions [224]}
+
+          224 {:pokemon-id     224
+                :name           "Octillery"
+                :classification "New Species Pokémon"
+                :type-1         ["Water "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          225 {:pokemon-id     225
+                :name           "Delibird"
+                :classification "New Species Pokémon"
+                :type-1         ["Ice "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          226 {:pokemon-id     226
+                :name           "Mantine"
+                :classification "New Species Pokémon"
+                :type-1         ["Water "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          227 {:pokemon-id     227
+                :name           "Skarmory"
+                :classification "New Species Pokémon"
+                :type-1         ["Steel "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          228 {:pokemon-id     228
+                :name           "Houndour"
+                :classification "New Species Pokémon"
+                :type-1         ["Dark "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"
+                :next-evolution-requirements {:amount 50
+                                              :name   "Houndour candies"
+                :next-evolutions [229]}
+
+          229 {:pokemon-id     229
+                :name           "Houndoom"
+                :classification "New Species Pokémon"
+                :type-1         ["Dark "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          230 {:pokemon-id     230
+                :name           "Kingdra"
+                :classification "New Species Pokémon"
+                :type-1         ["Water "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          231 {:pokemon-id     231
+                :name           "Phanpy"
+                :classification "New Species Pokémon"
+                :type-1         ["Ground "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"
+                :next-evolution-requirements {:amount 50
+                                              :name   "Phanpy candies"
+                :next-evolutions [232]}
+
+          232 {:pokemon-id     232
+                :name           "Donphan"
+                :classification "New Species Pokémon"
+                :type-1         ["Ground "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          233 {:pokemon-id     233
+                :name           "Porygon2"
+                :classification "New Species Pokémon"
+                :type-1         ["Normal "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          234 {:pokemon-id     234
+                :name           "Stantler"
+                :classification "New Species Pokémon"
+                :type-1         ["Normal "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          235 {:pokemon-id     235
+                :name           "Smeargle"
+                :classification "New Species Pokémon"
+                :type-1         ["Normal "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          236 {:pokemon-id     236
+                :name           "Tyrogue"
+                :classification "New Species Pokémon"
+                :type-1         ["Fighting "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          237 {:pokemon-id     237
+                :name           "Hitmontop"
+                :classification "New Species Pokémon"
+                :type-1         ["Fighting "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          238 {:pokemon-id     238
+                :name           "Smoochum"
+                :classification "New Species Pokémon"
+                :type-1         ["Ice "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"
+                :next-evolution-requirements {:amount 25
+                                              :name   "Smoochum candies"
+                :next-evolutions [239]}
+
+          239 {:pokemon-id     239
+                :name           "Elekid"
+                :classification "New Species Pokémon"
+                :type-1         ["Electric "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"
+                :next-evolution-requirements {:amount 25
+                                              :name   "Elekid candies"
+                :next-evolutions [240]}
+
+          240 {:pokemon-id     240
+                :name           "Magby"
+                :classification "New Species Pokémon"
+                :type-1         ["Fire "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"
+                :next-evolution-requirements {:amount 25
+                                              :name   "Magby candies"
+                :next-evolutions [241]}
+
+          241 {:pokemon-id     241
+                :name           "Miltank"
+                :classification "New Species Pokémon"
+                :type-1         ["Normal "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          242 {:pokemon-id     242
+                :name           "Blissey"
+                :classification "New Species Pokémon"
+                :type-1         ["Normal "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          243 {:pokemon-id     243
+                :name           "Raikou"
+                :classification "New Species Pokémon"
+                :type-1         ["Electric "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          244 {:pokemon-id     244
+                :name           "Entei"
+                :classification "New Species Pokémon"
+                :type-1         ["Fire "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          245 {:pokemon-id     245
+                :name           "Suicune"
+                :classification "New Species Pokémon"
+                :type-1         ["Water "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          246 {:pokemon-id     246
+                :name           "Larvitar"
+                :classification "New Species Pokémon"
+                :type-1         ["Rock "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"
+                :next-evolution-requirements {:amount 25
+                                              :name   "Larvitar candies"
+                :next-evolutions [247]}
+
+          247 {:pokemon-id     247
+                :name           "Pupitar"
+                :classification "New Species Pokémon"
+                :type-1         ["Rock "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"
+                :next-evolution-requirements {:amount 100
+                                              :name   "Pupitar candies"
+                :next-evolutions [248]}
+
+          248 {:pokemon-id     248
+                :name           "Tyranitar"
+                :classification "New Species Pokémon"
+                :type-1         ["Rock "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          249 {:pokemon-id     249
+                :name           "Lugia"
+                :classification "New Species Pokémon"
+                :type-1         ["Psychic "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          250 {:pokemon-id     250
+                :name           "Ho-Oh"
+                :classification "New Species Pokémon"
+                :type-1         ["Fire "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}
+
+          251 {:pokemon-id     251
+                :name           "Celebi"
+                :classification "New Species Pokémon"
+                :type-1         ["Psychic "]
+                :weaknesses     ["Unknown"]
+                :fast-attacks   ["Unknown"]
+                :special-attack ["Unknown"]
+                :weight         "Unknown"
+                :height         "Unknown"}})


Fix fetching DB type on Heroku :yum:

Fix fetching DB type on Heroku :yum:

--- src/metabase/db.clj
+++ src/metabase/db.clj
@@ -42,11 +42,6 @@
                                   ;; if we don't have an absolute path then make sure we start from "user.dir"
                                   [(System/getProperty "user.dir") "/" db-file-name options]))))))

-(defn- db-type
-  "The type of backing DB used to run Metabase. `:h2`, `:mysql`, or `:postgres`."
-  ^clojure.lang.Keyword []
-  (config/config-kw :mb-db-type))
-
 (defn parse-connection-string
   "Parse a DB connection URI like `postgres://cam@localhost.com:5432/cams_cool_db?ssl=true&sslfactory=org.postgresql.ssl.NonValidatingFactory` and return a broken-out map."
   [uri]
@@ -61,11 +56,20 @@
                    codec/form-decode
                    walk/keywordize-keys))))

+(def ^:private connection-string-details
+  (delay (when-let [uri (config/config-str :mb-db-connection-uri)]
+           (parse-connection-string uri))))
+
+(defn- db-type
+  "The type of backing DB used to run Metabase. `:h2`, `:mysql`, or `:postgres`."
+  ^clojure.lang.Keyword []
+  (or (:type @connection-string-details)
+      (config/config-kw :mb-db-type)))
+
 (def db-connection-details
   "Connection details that can be used when pretending the Metabase DB is itself a `Database`
    (e.g., to use the Generic SQL driver functions on the Metabase DB itself)."
-  (delay (or (when-let [uri (config/config-str :mb-db-connection-uri)]
-               (parse-connection-string uri))
+  (delay (or @connection-string-details
              (case (db-type)
                :h2       {:type     :h2                               ; TODO - we probably don't need to specifc `:type` here since we can just call (db-type)
                           :db       @db-file}


Got rid of some magic strings.

Got rid of some magic strings.

--- nav-obj-splitter.clj
+++ nav-obj-splitter.clj
@@ -3,12 +3,13 @@
         [clojure.string :only [join]]))

 (def type-id-map {"Table" 1 "Form" 2 "Report" 3 "Dataport" 4 "Codeunit" 5 "XMLport" 6 "MenuSuite" 7 "Page" 8})
+(def first-line-regex #"^OBJECT (.+) (\d+) (.+)")
+(def source-file-extension ".txt")

 (defn parse-first-line
   "Parses meta data from the first line of the object source file."
   [line]
-  (let [first-line-format #"^OBJECT (.+) (\d+) (.+)"
-        matches (re-find (re-pattern first-line-format) line)
+  (let [matches (re-find (re-pattern first-line-regex) line)
         type (nth matches 1)
         id (nth matches 2)
         name (nth matches 3)]
@@ -18,7 +19,7 @@
   "Returns a file name built from object meta data."
   [object-metadata]
   (let [file-name (join "-" (map object-metadata [:type-id :type :id]))]
-    (str file-name ".txt")))
+    (str file-name source-file-extension)))

 ; Some tests
 (def meta-data-example {:type-id 1 :type "Table" :id "70902" :name "Test Table (48)"})


stop trying to load bits/null when queue is empty

--- src-cljs/core.cljs
+++ src-cljs/core.cljs
@@ -368,8 +368,7 @@
     ;; find out what track we should be playing
     (let [bits (best-media-url urls)
           actual-path (.getPath (goog.Uri. (.-src actual)))]
-      (when-not (= actual-path bits)
-        (println ["want " bits " got " (.-src actual)])
+      (when (and bits (not (= actual-path bits)))
         (set! (.-src actual) bits)))

     (when (and (.-paused actual) (:playing desired) urls)


Refining some rules to weed out false positives.

--- EkekoAspectJ/src/damp/ekeko/aspectj/assumptions.clj
+++ EkekoAspectJ/src/damp/ekeko/aspectj/assumptions.clj
@@ -240,15 +240,6 @@
            (aspect-advice ?aspect ?advice)
            (advice-pointcutdefinition ?advice ?pointcutdef)))

-;; check on pointcut name
-;; no longer needed
-;;(defn
-;; aspect-usedpointcutname
-;;  [?aspect ?pointcutname]
-;;  (l/fresh [?pointcut]
-;;    (aspect-usedpointcut ?aspect ?pointcut)
-;;    (pointcutdefinition-name ?pointcut ?pointcutname)))
-
 (defn aspect-allusedpointcutdefs
   [?aspect ?usedpointcutdefs]
   (l/all
@@ -265,6 +256,8 @@
            (l/!= ?aspect1 ?aspect2)
            (aspect-allusedpointcutdefs ?aspect1 ?usedpc1)
            (aspect-allusedpointcutdefs ?aspect2 ?usedpc2)
+           (l/!= ?usedpc1 [])
+           (l/!= ?usedpc2 [])
            (same-elements ?usedpc1 ?usedpc2)
            ))

@@ -281,6 +274,8 @@
            (l/!= ?aspect1 ?aspect2)
            (findall ?shadow1 (aspect-shadow ?aspect1 ?shadow1) ?shadows1)
            (findall ?shadow2 (aspect-shadow ?aspect2 ?shadow2) ?shadows2)
+           (l/!= ?shadows1 [])
+           (l/!= ?shadows2 [])
            (same-elements ?shadows1 ?shadows2)))

 ;;===========================================================================================


dependencies

dependencies

--- Clojure-Websockets/MainApp/project.clj
+++ Clojure-Websockets/MainApp/project.clj
@@ -7,8 +7,8 @@
                  [org.clojure/clojurescript "1.7.228"]
                  [clojurewerkz/elastisch "2.2.1"]
                  [org.clojure/tools.logging "0.3.1"]
-                 [com.taoensso/timbre "4.2.1"]
-                 [com.taoensso/encore "2.36.0"]
+                 [com.taoensso/timbre "4.2.1" :exclusions [io.aviso/pretty]]
+                 [com.taoensso/encore "2.36.2"]
                  [com.taoensso/carmine "2.12.2"]
                  [matthiasn/systems-toolbox "0.5.10"]
                  [matthiasn/systems-toolbox-sente "0.5.11"]


more (de)composition

more (de)composition

--- src/bitsplit_cli/core.cljs
+++ src/bitsplit_cli/core.cljs
@@ -18,6 +18,7 @@

 (def system {:storage storage :client client})
 (def build-cmd (partial assoc system :command))
+(def exec-cmd (comp execute build-cmd))

 (defn- read-prompt [message]
     (let [return (chan 1)]
@@ -44,13 +45,13 @@
     ; not really tied to repl in long term, but whatever
     ; (start-forwarding storage client)
     (sync-addresses! system)
-    (execute (build-cmd "list"))
+    (exec-cmd "list")
     (go-loop [command (<! (read-in))]
         (if (exit? command)
             (do (println "Shutting down...")
                 (.exit js/process))
             (do
-                (execute (build-cmd command))
+                (exec-cmd command)
                 (recur (<! (read-in)))))))

 (defn -main [& args]
@@ -59,7 +60,6 @@
         (->> args
             (map #(str % " "))
             (apply str)
-            build-cmd
-            execute)))
+            exec-cmd)))

 (set! *main-cli-fn* -main)


CLJS-935: script/noderepljs leaves node running after exit

cljs/repl/node.cljs: add `proc` field to NodeEnv, set atom in setup, destroy process
in -teardown

--- src/clj/cljs/repl/node.clj
+++ src/clj/cljs/repl/node.clj
@@ -81,6 +81,7 @@
       (Thread/sleep 300)
       (reset! (:socket repl-env)
         (socket (:host repl-env) (:port repl-env)))
+      (reset! (:proc repl-env) proc)
       ;; compile cljs.core & its dependencies, goog/base.js must be available
       ;; for bootstrap to load
       (let [core-js (closure/compile-file core
@@ -117,7 +118,7 @@
            (set! *print-fn* (.-print (js/require "util")))))
       )))

-(defrecord NodeEnv [host port socket]
+(defrecord NodeEnv [host port socket proc]
   repl/IJavaScriptEnv
   (-setup [this]
     (setup this))
@@ -128,10 +129,11 @@
   (-load [this provides url]
     (load-javascript this provides url))
   (-tear-down [this]
+    (.destroy ^Process @proc)
     (close-socket @socket)))

 (defn repl-env* [{:keys [host port] :or {host "localhost" port 5001}}]
-  (NodeEnv. host port (atom nil)))
+  (NodeEnv. host port (atom nil) (atom nil)))

 (defn repl-env
   [& options]


Thread display handling improvements on edit/refine

See https://app.asana.com/0/17212341701456/46485188045326

--- src/cljs/memento/core.cljs
+++ src/cljs/memento/core.cljs
@@ -228,11 +228,10 @@
     (let [note   (get-in app-state [:note :edit-note])
           memory (get-in app-state [:note :edit-memory])
           url    (str "/api/memory/" (:id memory) "/thought")]
-      (PUT url {:params        {:thought note :refine_id (get-in app-state [:note :focus :id])}
+      (PUT url {:params        {:thought note}
                 :headers       {:authorization (str "Token " (get-in app-state [:credentials :token]))}
                 :handler       #(dispatch [:memory-edit-save-success note])
-                :error-handler #(dispatch [:memory-edit-save-error %])})
-      )
+                :error-handler #(dispatch [:memory-edit-save-error %])}))
     (assoc-in app-state [:ui-state :is-busy?] true)
     ))

@@ -240,15 +239,18 @@
 (register-handler
   :memory-edit-save-success
   (fn [app-state [_ msg]]
-    (dispatch [:state-message (str "Updated memory to: " msg) "alert-success"])
-    (if (= :remember (get-in app-state [:ui-state :section]))         ; Just in case we allow editing from elsewhere...
-      (dispatch [:memories-load]))
-    (-> app-state
-        (assoc-in [:ui-state :is-busy?] false)
-        (assoc-in [:note :edit-memory] nil)
-        (assoc-in [:note :edit-note] "")
-        (assoc-in [:note :focus] nil)
-        )))
+    (let [thread (get-in app-state [:note :thread])]
+      (dispatch [:state-message (str "Updated memory to: " msg) "alert-success"])
+      (if (= :remember (get-in app-state [:ui-state :section]))       ; Just in case we allow editing from elsewhere...
+        (dispatch [:memories-load]))
+      (if thread
+        (dispatch [:thread-load (first thread)]))
+      (-> app-state
+          (assoc-in [:ui-state :is-busy?] false)
+          (assoc-in [:note :edit-memory] nil)
+          (assoc-in [:note :edit-note] "")
+          (assoc-in [:note :focus] nil)
+          ))))

 (register-handler
@@ -278,6 +280,8 @@
     (-> app-state
         (assoc-in [:ui-state :is-busy?] false)
         (assoc-in [:note :current-note] "")
+        (assoc-in [:note :thread] nil)
+        (assoc-in [:ui-state :show-thread?] false)
         (assoc-in [:note :focus] nil)
         )))


Only try to create the migration table if it doesn't exist

This prevents noise in the postgres logs for trying to create a table
that already exists. This also allows us to fail fast if we can't
create the table at all instead of swallowing the exception.

--- src/clojars/db/migrate.clj
+++ src/clojars/db/migrate.clj
@@ -30,12 +30,10 @@
   [#'initial-schema])

 (defn migrate [db]
-  (try (sql/db-do-commands db
-                           (sql/create-table-ddl "migrations"
-                                                 [:name :varchar "NOT NULL"]
-                                                 [:created_at :timestamp
-                                                  "NOT NULL"  "DEFAULT CURRENT_TIMESTAMP"]))
-       (catch Exception _))
+  (sql/db-do-commands db
+                      (str "create table if not exists migrations "
+                           "(name varchar not null, "
+                           "created_at timestamp not null default current_timestamp)"))
   (sql/with-db-transaction [trans db]
     (let [has-run? (sql/query trans ["SELECT name FROM migrations"]
                               :row-fn :name


Predicates for testing Path-ness and URI-ness.

--- src/clojure/parkour/fs.clj
+++ src/clojure/parkour/fs.clj
@@ -24,6 +24,10 @@
      (.write w (str x))
      (.write w "\"")))

+(defn path?
+  "True iff `x` is a Path."
+  [x] (instance? Path x))
+
 (defn uri
   "Coerce argument(s) to a URI, resolving successive arguments against base."
   {:tag `URI}
@@ -38,6 +42,10 @@
      (.write w "#java.net/uri \"")
      (.write w (str x))
      (.write w "\"")))
+
+(defn uri?
+  "True iff `x` is a URI."
+  [x] (instance? URI x))

 (defn path-fs
   "Hadoop filesystem for the path `p`."


OORR: Clean up

OORR: Clean up

--- src/hatti/views/table.cljs
+++ src/hatti/views/table.cljs
@@ -88,13 +88,11 @@
          :name label :toolTip label :sortable true
          :formatter (partial formatter field language)})))))

-(defn- init-sg-pager [grid dataview & {:keys [page-count]}]
-  (let [Pager (.. js/Slick -Controls -Pager)
-        pager (Pager. dataview
-                      grid
-                      (js/jQuery (str "#" pager-id))
-                      #js {:totalDisplayPages page-count})]
-    pager))
+(defn- init-sg-pager [grid dataview]
+  (let [Pager (.. js/Slick -Controls -Pager)]
+    (Pager. dataview
+            grid
+            (js/jQuery (str "#" pager-id)))))

 (def sg-options
   "Options to feed the slickgrid constructor."
@@ -163,9 +161,10 @@
                     (put! shared/event-chan {:submission-to-rank rank}))))

     ;; page, filter, and data set-up on the dataview
-    (init-sg-pager grid dataview :page-count total-page-count)
+    (init-sg-pager grid dataview)
     (.setPagingOptions dataview
-                       #js {:pageSize (or num-displayed-records 25)})
+                       #js {:pageSize (or num-displayed-records 25)
+                            :totalPages total-page-count})
     (.setFilter dataview (partial filterfn form))
     (.setItems dataview (clj->js data) _id)
     [grid dataview]))
@@ -182,8 +181,6 @@
        (let [e (<! event-chan)
              {:keys [submission-to-rank submission-clicked submission-unclicked
                      filter-by new-columns re-render]} e
-             {{{:keys [total-page-count]} :paging} :table-page}
-             @shared/app-state
              update-data! (partial om/update! app-state
                                    [:table-page :submission-clicked :data])]
          (when submission-to-rank
@@ -209,7 +206,7 @@
                (.resizeCanvas grid)
                (.invalidateAllRows grid)
                (.render grid)
-               (init-sg-pager grid dataview :page-count total-page-count))))))))
+               (init-sg-pager grid dataview))))))))

 ;; OM COMPONENTS


add support for -t ("time") for specifying cluster shutdown time

--- examples/leinproj/clj/stormlocal.clj
+++ examples/leinproj/clj/stormlocal.clj
@@ -10,19 +10,19 @@
   (:import  [backtype.storm StormSubmitter LocalCluster])
   (:gen-class :main true))

-(defn run-local! [topology-file debug]
+(defn run-local! [topology-file debug sleep]
   (try
     (let [cluster (LocalCluster.)]
       ;; submit the topology configured above
       (.submitTopology cluster
                       ;; topology name (arbitrary)
-                      "topology-local"
+                      "stormlocal"
                       ;; topology settings
                       {TOPOLOGY-DEBUG debug}
                       ;; topology configuration
                       (apply topology (var-get (load-file topology-file))))
       ;; sleep for 5 seconds before...
-      (Thread/sleep 5000)
+      (Thread/sleep sleep)
       ;; shutting down the cluster
       (.shutdown cluster)
       )
@@ -34,7 +34,7 @@
   (println (str "Options:\n" opts "\n"))
   (println (str "Arguments:\n" args "\n"))
   (println (apply topology (var-get (load-file (:spec opts)))))
-  (run-local! (:spec opts) (:debug opts))
+  (run-local! (:spec opts) (:debug opts) (:time opts))
 )

 (defn -main [& args]
@@ -47,6 +47,8 @@
              ["-c" "--config" "Storm Environment config FILE" :default "config.json"]
              ["-d" "--debug" "Enable Storm Topology debugging" :default true]
              ["-e" "--env" "Environment, e.g. prod or local" :default "local"]
+             ["-t" "--time" "Amount of time to keep cluster running in milliseconds" :default 5000
+                                                                                :parse-fn #(Integer/parseInt %)]
              )]
     (when (:help opts)
       (println banner)


make verbose logging more useful

make verbose logging more useful

--- src/main/cljs/cljs/js.cljs
+++ src/main/cljs/cljs/js.cljs
@@ -145,6 +145,8 @@
      (swap! *loaded* disj name))
    (when (= :reload-all reload)
      (reset! *loaded* #{}))
+   (when (:verbose opts)
+     (debug-prn (str "Loading " name (when (:macros-ns opts) " macros") " namespace")))
    (when-not (contains? @*loaded* name)
      (let [env (:*env* bound-vars)]
        (try
@@ -193,7 +195,7 @@
    (analyze-deps bound-vars ana-env lib deps nil cb))
   ([bound-vars ana-env lib deps opts cb]
    (when (:verbose opts)
-     (debug-prn "Loading dependencies"))
+     (debug-prn "Loading dependencies for" lib))
    (let [compiler @(:*compiler* bound-vars)]
      (binding [ana/*cljs-dep-set* (vary-meta (conj (:*cljs-dep-set* bound-vars) lib)
                                     update-in [:dep-path] conj lib)]
@@ -202,8 +204,6 @@
            (-> (:*cljs-dep-set* bound-vars) meta :dep-path)))
        (if (seq deps)
          (let [dep (first deps)]
-           (when (:verbose opts)
-             (debug-prn "Loading" dep))
            (require bound-vars dep opts
              (fn [res]
                (if-not (:error res)
@@ -254,18 +254,15 @@

 (defn load-macros [bound-vars k macros reload reloads opts cb]
   (if (seq macros)
-    (let [env  (:*compiler* bound-vars)
-          nsym (first (vals macros))]
-      (let [k (or (k reload)
-                  (get-in reloads [k nsym])
-                  (and (= nsym name) (:*reload-macros* bound-vars) :reload))]
-        (require bound-vars nsym k (assoc opts :macros-ns true)
-          (fn [res]
-            (if-not (:error res)
-              (load-macros bound-vars k (next macros) reload reloads opts cb)
-              (cb res))))
-        ;(intern-macros nsym k)
-        ))
+    (let [nsym (first (vals macros))
+          k    (or (k reload)
+                   (get-in reloads [k nsym])
+                   (and (= nsym name) (:*reload-macros* bound-vars) :reload))]
+      (require bound-vars nsym k (assoc opts :macros-ns true)
+        (fn [res]
+          (if-not (:error res)
+            (load-macros bound-vars k (next macros) reload reloads opts cb)
+            (cb res)))))
     (cb {:value nil})))

 (defn ns-side-effects
@@ -293,20 +290,20 @@
                        (cb res)
                        (if (:*load-macros* bound-vars)
                         (do
-                          (when (:verbose opts) (debug-prn "Loading :use-macros"))
+                          (when (:verbose opts) (debug-prn "Processing :use-macros for" (:name ast)))
                           (load-macros bound-vars :use-macros use-macros reload reloads opts
                             (fn [res]
                               (if (:error res)
                                 (cb res)
                                 (do
-                                  (when (:verbose opts) (debug-prn "Loading :require-macros"))
+                                  (when (:verbose opts) (debug-prn "Processing :require-macros for" (:name ast)))
                                   (load-macros bound-vars :require-macros require-macros reloads reloads opts
                                     (fn [res]
                                       (if (:error res)
                                         (cb res)
                                         (let [res (try
                                                     (when (seq use-macros)
-                                                      (when (:verbose opts) (debug-prn "Checking :use-macros"))
+                                                      (when (:verbose opts) (debug-prn "Checking :use-macros for" (:name ast)))
                                                       (ana/check-use-macros use-macros env))
                                                     {:value nil}
                                                     (catch :default cause
@@ -588,6 +585,7 @@
                              {:*cljs-ns* 'cljs.user
                               :*ns* (create-ns ana/*cljs-ns*)})
                      (:source-map opts) (assoc :*sm-data* (sm-data)))]
+    (when (:verbose opts) (debug-prn "Evaluating" name))
     ((fn compile-loop [ns]
        (binding [env/*compiler*         (:*compiler* bound-vars)
                  *eval-fn*              (:*eval-fn* bound-vars)


thru rm_cfg_rpt_wf_states

thru rm_cfg_rpt_wf_states

--- src/pg_demo/table_defs.clj
+++ src/pg_demo/table_defs.clj
@@ -2781,6 +2781,255 @@
               PRIMARY KEY (ENTERPRISE_ID,TEMPLATE_ID,SEQ_NUM)
           ); " }

+    { "rm_cfg_per_report"
+          "CREATE TABLE rm_cfg_per_report (
+              ENTERPRISE_ID numeric NOT NULL,
+              REPORT_FORM_ID numeric NOT NULL,
+              AGENCY_ID numeric,
+              INGREDIENT_ID numeric,
+              INDICATION varchar(50),
+              FORMULATION_ID numeric,
+              REPORT_NUM varchar(50),
+              REPORT_TITLE varchar(100),
+              INGREDIENT varchar(120),
+              TRADE_NAME varchar(400),
+              APPROVAL varchar(100),
+              INGD_TRD_APRV numeric(10),
+              AC_ID numeric,
+              INCL_OPTIONS numeric(10),
+              INCL_LINE_LISTING numeric(10),
+              GROUP_BY numeric,
+              SORT_BY numeric,
+              LINE_OPTIONS numeric(8),
+              LIST_ONCEALL_NARR numeric(10),
+              START_DATE timestamp,
+              DUE_DAYS numeric(10),
+              AUTO_GEN_PREG numeric(10),
+              AUTO_DAYS numeric(10),
+              AUTO_TIME varchar(5),
+              GROUP_ID numeric,
+              LANGUAGE numeric(10),
+              PRINT_CONFIG numeric,
+              CUM_START_DATE timestamp,
+              CUM_END_DATE timestamp,
+              DELETED timestamp,
+              SUMMARY numeric,
+              GROUP_BY2 numeric,
+              GROUP_BY3 numeric,
+              CATEGORY varchar(50),
+              SHARED numeric,
+              USER_ID numeric,
+              HIT_LIST numeric(1),
+              SORT_BY2 numeric,
+              SORT_BY3 numeric,
+              GROUP_BY4 numeric,
+              TITLE_PER_DRUG varchar(50),
+              TITLE_PER_DRUG_OPTION varchar(50),
+              REASSESSMENT numeric(3),
+              FOOTER varchar(120),
+              FDA_SHEETNAME varchar(40),
+              FDA_AGENCY_ID numeric,
+              SUB_CATEGORY varchar(50),
+              SOLICITED_AC_ID numeric,
+              SOLICITED_RPT_TITLE varchar(60),
+              SOLICITED_HIT_LIST numeric(1),
+              PREV_REPORT_START_DT timestamp,
+              MESSAGE_TYPE_ID numeric,
+              ICSR_AGENCY_ID numeric,
+              FROM_DATE timestamp,
+              TO_DATE timestamp,
+              INCL_DATE_FILTER_TYPE numeric,
+              LAST_MODIFIED_USER_ID numeric,
+              CREATE_TIME timestamp,
+              UPDATE_TIME timestamp,
+              JUSTIFICATION_TEXT varchar(1000),
+              PRINT_PAGE_NUM numeric,
+              JPN_APPROVAL varchar(100),
+              CSPS_DATE varchar(100),
+              CTPCS_DATE varchar(100),
+              ENABLE_DELIV_QTY numeric(1),
+              PRINT_ALL_AGENCY numeric,
+              PRINT_ALL_ANOTHER_NDA numeric(1) NOT NULL,
+              PRINT_ALL_CASES numeric(1) NOT NULL,
+              PRINT_ALL_EXPEDITED numeric(1) NOT NULL,
+              PRINT_ALL_FORM numeric(1) NOT NULL,
+              PRINT_ALL_PERIODIC numeric(1) NOT NULL,
+              PRINT_NO_WATERMARK numeric(1) NOT NULL,
+              PRIMARY KEY (ENTERPRISE_ID,REPORT_FORM_ID)
+          ); " }
+
+    { "rm_cfg_per_rpt_child"
+          "CREATE TABLE rm_cfg_per_rpt_child (
+              ENTERPRISE_ID numeric NOT NULL,
+              ID numeric NOT NULL,
+              REPORT_FORM_ID numeric NOT NULL,
+              REC_TYPE numeric(3),
+              FIELD numeric,
+              DATE_START timestamp,
+              DATE_END timestamp,
+              OPTIONS numeric(4),
+              DELETED timestamp,
+              SORT_ID numeric(2),
+              FIELD_TEXT varchar(250),
+              PRIMARY KEY (ENTERPRISE_ID,ID)
+          ); " }
+
+    { "rm_cfg_per_rpt_cri"
+          "CREATE TABLE rm_cfg_per_rpt_cri (
+              ENTERPRISE_ID numeric NOT NULL,
+              REPORT_TYPE numeric(10) NOT NULL,
+              REPORT_FORM_ID numeric NOT NULL,
+              REPORT_TYPE_ID numeric NOT NULL,
+              SERIOUS numeric(1),
+              FATAL numeric(1),
+              LISTEDNESS numeric(1),
+              RELATED numeric(1),
+              HCP numeric(1),
+              DATASHEET numeric,
+              SHEET_NAME varchar(40),
+              DELETED timestamp,
+              PRIMARY KEY (ENTERPRISE_ID,REPORT_TYPE)
+          ); " }
+
+    { "rm_cfg_per_rpt_freq"
+          "CREATE TABLE rm_cfg_per_rpt_freq (
+              ENTERPRISE_ID numeric NOT NULL,
+              ID numeric NOT NULL,
+              REPORT_FORM_ID numeric NOT NULL,
+              FREQ numeric(2),
+              START_MONTH numeric(8),
+              END_MONTH numeric(8),
+              SUBMITTED numeric(1),
+              TOTAL_DELIV_QTY varchar(15),
+              TOTAL_DELIV_QTY_UNIT_ID numeric,
+              DELETED timestamp,
+              PRIMARY KEY (ENTERPRISE_ID,ID,REPORT_FORM_ID)
+          ); " }
+
+    { "rm_cfg_per_rpt_security"
+          "CREATE TABLE rm_cfg_per_rpt_security (
+              ENTERPRISE_ID numeric NOT NULL,
+              SEQ_NUM numeric NOT NULL,
+              REPORT_FORM_ID numeric NOT NULL,
+              GROUP_ID numeric NOT NULL,
+              RIGHTS numeric NOT NULL,
+              DELETED timestamp,
+              PRIMARY KEY (ENTERPRISE_ID,SEQ_NUM)
+          ); " }
+
+    { "rm_cfg_placeholders"
+          "CREATE TABLE rm_cfg_placeholders (
+              ENTERPRISE_ID numeric NOT NULL,
+              PLACE_ID numeric NOT NULL,
+              PLACE_HOLDER_TYPE numeric,
+              PLACE_HOLDER varchar(40),
+              SQL_QUERY varchar(4000),
+              DELETED timestamp,
+              ORDERBY_CLAUSE1 varchar(200),
+              ORDERBY_CLAUSE2 varchar(200),
+              SQL_QUERY_J varchar(4000),
+              PRIMARY KEY (ENTERPRISE_ID,PLACE_ID)
+          ); " }
+
+    { "rm_cfg_priorities"
+          "CREATE TABLE rm_cfg_priorities (
+              ENTERPRISE_ID numeric NOT NULL,
+              PRIORITY_ID numeric NOT NULL,
+              ASSESS_SERIOUS numeric,
+              ASSESS_LISTED numeric,
+              ASSESS_CAUS numeric,
+              DUE_DATE_NOTIFY numeric,
+              DUE_SOON_DAYS numeric,
+              AC_ID numeric,
+              DELETED timestamp,
+              PRIMARY KEY (ENTERPRISE_ID,PRIORITY_ID)
+          ); " }
+
+    { "rm_cfg_psur_multi_ingredients"
+          "CREATE TABLE rm_cfg_psur_multi_ingredients (
+              ENTERPRISE_ID numeric NOT NULL,
+              ID numeric NOT NULL,
+              REPORT_FORM_ID numeric NOT NULL,
+              INGREDIENT_ID numeric NOT NULL,
+              DELETED timestamp,
+              PRIMARY KEY (ENTERPRISE_ID,ID)
+          ); " }
+
+    { "rm_cfg_reg_report_rules"
+          "CREATE TABLE rm_cfg_reg_report_rules (
+              ENTERPRISE_ID numeric NOT NULL,
+              REG_RPT_RULES_ID numeric NOT NULL,
+              COUNTRY_ID numeric,
+              LICENSE_TYPE_ID numeric,
+              TITLE varchar(40),
+              PERIODIC numeric,
+              IND_STUDIES numeric,
+              REPORT_FORM_ID numeric,
+              LANGUAGE_ID numeric,
+              TIMEFRAME numeric,
+              EVENT numeric,
+              FATAL numeric,
+              SERIOUS numeric,
+              LISTED numeric,
+              CAUSAL numeric,
+              AC_ID numeric,
+              AGENCY_ID numeric,
+              GROUP_ID numeric,
+              CAUSAL_RPTD numeric(1),
+              CASE_CAUSAL numeric(1),
+              CASE_CAUSAL_RPTD numeric(1),
+              MOST_CONSERV numeric(1),
+              TEMPLATE_ID numeric,
+              ACTIVE_MOIETY numeric(3),
+              PROTECT numeric(1),
+              SDRUG_NON_ADMIN numeric(2),
+              DELETED timestamp,
+              COMMENT_TYPE_ID numeric(10),
+              REF_TYPE_ID numeric,
+              ACTIVE numeric(1),
+              FAMILY_ID numeric,
+              PRODUCT_GROUP_ID numeric,
+              EVT_INTENSITY_ID numeric,
+              EVT_SERIOUSNESS numeric,
+              MESSAGE_TYPE_ID numeric,
+              NON_CLINICAL_TRIAL_CASES numeric(1),
+              AUTO_DISTRIBUTE_REPORTS numeric NOT NULL,
+              BLIND_STUDY_PRODUCT numeric(1) NOT NULL,
+              FORCE_DISTRIBUTE_DAYS numeric,
+              HCP_CASE numeric(1),
+              NO_FOLLOWUP_DOWNGRADE numeric(1),
+              RPT_CATEGORY_ID numeric,
+              LIC_CATEGORY_ID numeric,
+              SUPER_RULE numeric(1),
+              GROUP_2_COUNTRY_ADJUST_DAYS numeric,
+              DEVICE_CATEGORY_ID numeric,
+              PRIMARY KEY (ENTERPRISE_ID,REG_RPT_RULES_ID)
+          ); " }
+
+    { "rm_cfg_rpt_wf_rules"
+          "CREATE TABLE rm_cfg_rpt_wf_rules (
+              ENTERPRISE_ID numeric NOT NULL,
+              TO_STATE_ID numeric NOT NULL,
+              FR_STATE_ID numeric NOT NULL,
+              AC_ID numeric,
+              EXCLUSIVE_FLAG numeric,
+              EMAIL_FLAG numeric,
+              DELETED timestamp,
+              PRIMARY KEY (ENTERPRISE_ID,TO_STATE_ID,FR_STATE_ID)
+          ); " }
+
+    { "rm_cfg_rpt_wf_states"
+          "CREATE TABLE rm_cfg_rpt_wf_states (
+              ENTERPRISE_ID numeric NOT NULL,
+              REPORT_STATE_ID numeric NOT NULL,
+              STATE_DESC varchar(30),
+              STATE_NAME varchar(30),
+              DELETED timestamp,
+              STATE_DESC_J varchar(30),
+              STATE_NAME_J varchar(30),
+              PRIMARY KEY (ENTERPRISE_ID,REPORT_STATE_ID)
+          ); " }
+
   ] ))

 (def dummy


Better control over nREPL starting [IMMUTANT-416]

[:ring :nrepl] overrides [:immutant :nrepl-port] now. If the former
exists, then the latter will be ignored, so the value of [:ring :nrepl
:start?] determines whether a repl will be started. If [:ring :nrepl]
doesn't exist, then [:immutant :nrepl-port] will be used. If not set, it
will default to 0 when the :dev profile is active. If explicitly set to
nil, no repl will be started.

--- modules/core/src/main/clojure/immutant/repl.clj
+++ modules/core/src/main/clojure/immutant/repl.clj
@@ -88,10 +88,9 @@
 the appropriate servers."
   [config]
   (let [ring-nrepl-config (-> (registry/get :project) :ring :nrepl)
-        port (or (:nrepl-port config)
-                 (and (:start? ring-nrepl-config)
+        port (or (and (:start? ring-nrepl-config)
                       (:port ring-nrepl-config))
-                 (if (util/dev-mode?) 0 nil))
+               (:nrepl-port config (and (nil? ring-nrepl-config) (util/dev-mode?) 0)))
         interface (:nrepl-interface config)]
     (if (or port interface)
       (if-let [nrepl (start-nrepl interface (or port 0))]


updated slow move values

updated slow move values

--- frontend/src/cruncher/moves/data.cljs
+++ frontend/src/cruncher/moves/data.cljs
@@ -58,7 +58,7 @@
                :trainer-level-min      1
                :damage-window-start-ms 1850
                :id                     18
-               :power                  25
+               :power                  30
                :unique-id              "V0018_MOVE_SLUDGE"
                :duration-ms            2600
                :animation-id           5
@@ -74,7 +74,7 @@
                :trainer-level-min      1
                :damage-window-start-ms 1850
                :id                     20
-               :power                  15
+               :power                  25
                :unique-id              "V0020_MOVE_VIce_GRIP"
                :duration-ms            2100
                :animation-id           5
@@ -234,7 +234,7 @@
                :trainer-level-min      1
                :damage-window-start-ms 1950
                :id                     34
-               :power                  20
+               :power                  25
                :unique-id              "V0034_MOVE_HEART_STAMP"
                :duration-ms            2550
                :animation-id           5
@@ -298,7 +298,7 @@
                :trainer-level-min      1
                :damage-window-start-ms 2150
                :id                     39
-               :power                  50
+               :power                  65
                :unique-id              "V0039_MOVE_Ice_BEAM"
                :duration-ms            3650
                :animation-id           5
@@ -394,7 +394,7 @@
                :trainer-level-min      1
                :damage-window-start-ms 1400
                :id                     48
-               :power                  15
+               :power                  25
                :unique-id              "V0048_MOVE_MEGA_DRAIN"
                :duration-ms            3200
                :animation-id           5
@@ -491,7 +491,7 @@
                :trainer-level-min      1
                :damage-window-start-ms 2000
                :id                     56
-               :power                  25
+               :power                  30
                :unique-id              "V0056_MOVE_LOW_SWEEP"
                :duration-ms            2250
                :animation-id           5
@@ -587,7 +587,7 @@
                :trainer-level-min      1
                :damage-window-start-ms 2300
                :id                     63
-               :power                  25
+               :power                  30
                :unique-id              "V0063_MOVE_Rock_TOMB"
                :duration-ms            3400
                :animation-id           5
@@ -603,7 +603,7 @@
                :trainer-level-min      1
                :damage-window-start-ms 1500
                :id                     64
-               :power                  40
+               :power                  50
                :unique-id              "V0064_MOVE_Rock_SLIDE"
                :duration-ms            3200
                :animation-id           5
@@ -635,7 +635,7 @@
                :trainer-level-min      1
                :damage-window-start-ms 2300
                :id                     66
-               :power                  15
+               :power                  25
                :unique-id              "V0066_MOVE_SHADOW_SNEAK"
                :duration-ms            3100
                :animation-id           5
@@ -651,7 +651,7 @@
                :trainer-level-min      1
                :damage-window-start-ms 1400
                :id                     67
-               :power                  20
+               :power                  25
                :unique-id              "V0067_MOVE_SHADOW_PUNCH"
                :duration-ms            2100
                :animation-id           5
@@ -683,7 +683,7 @@
                :trainer-level-min      1
                :damage-window-start-ms 2300
                :id                     70
-               :power                  40
+               :power                  45
                :unique-id              "V0070_MOVE_SHADOW_BALL"
                :duration-ms            3080
                :animation-id           5
@@ -731,7 +731,7 @@
                :trainer-level-min      1
                :damage-window-start-ms 1300
                :id                     75
-               :power                  15
+               :power                  25
                :unique-id              "V0075_MOVE_PARABOLIC_CHARGE"
                :duration-ms            2100
                :animation-id           5
@@ -893,7 +893,7 @@
                :trainer-level-min      1
                :damage-window-start-ms 3500
                :id                     87
-               :power                  80
+               :power                  85
                :unique-id              "V0087_MOVE_MOONBLAST"
                :duration-ms            4100
                :animation-id           5
@@ -957,7 +957,7 @@
                :trainer-level-min      1
                :damage-window-start-ms 2400
                :id                     91
-               :power                  60
+               :power                  70
                :unique-id              "V0091_MOVE_SLUDGE_WAVE"
                :duration-ms            3400
                :animation-id           5
@@ -989,7 +989,7 @@
                :trainer-level-min      1
                :damage-window-start-ms 1250
                :id                     94
-               :power                  20
+               :power                  25
                :unique-id              "V0094_MOVE_BONE_CLUB"
                :duration-ms            1600
                :animation-id           5
@@ -1037,7 +1037,7 @@
                :trainer-level-min      1
                :damage-window-start-ms 2000
                :id                     99
-               :power                  35
+               :power                  45
                :unique-id              "V0099_MOVE_SIGNAL_BEAM"
                :duration-ms            3100
                :animation-id           5
@@ -1069,7 +1069,7 @@
                :trainer-level-min      1
                :damage-window-start-ms 2700
                :id                     101
-               :power                  20
+               :power                  25
                :unique-id              "V0101_MOVE_FLAME_CHARGE"
                :duration-ms            3100
                :animation-id           5
@@ -1085,7 +1085,7 @@
                :trainer-level-min      1
                :damage-window-start-ms 1200
                :id                     102
-               :power                  25
+               :power                  30
                :unique-id              "V0102_MOVE_FLAME_BURST"
                :duration-ms            2100
                :animation-id           5
@@ -1149,7 +1149,7 @@
                :trainer-level-min      1
                :damage-window-start-ms 1800
                :id                     106
-               :power                  35
+               :power                  55
                :unique-id              "V0106_MOVE_SCALD"
                :duration-ms            4000
                :animation-id           5
@@ -1165,7 +1165,7 @@
                :trainer-level-min      1
                :damage-window-start-ms 1500
                :id                     107
-               :power                  60
+               :power                  90
                :unique-id              "V0107_MOVE_HYDRO_PUMP"
                :duration-ms            3800
                :animation-id           5
@@ -1197,7 +1197,7 @@
                :trainer-level-min      1
                :damage-window-start-ms 4400
                :id                     109
-               :power                  70
+               :power                  100
                :unique-id              "V0109_MOVE_PSYSTRIKE"
                :duration-ms            5100
                :animation-id           5
@@ -1229,7 +1229,7 @@
                :trainer-level-min      1
                :damage-window-start-ms 350
                :id                     114
-               :power                  35
+               :power                  50
                :unique-id              "V0114_MOVE_GIGA_DRAIN"
                :duration-ms            3600
                :animation-id           5
@@ -1357,7 +1357,7 @@
                :trainer-level-min      1
                :damage-window-start-ms 2300
                :id                     125
-               :power                  25
+               :power                  30
                :unique-id              "V0125_MOVE_SWIFT"
                :duration-ms            3000
                :animation-id           5
@@ -1373,7 +1373,7 @@
                :trainer-level-min      1
                :damage-window-start-ms 1600
                :id                     126
-               :power                  20
+               :power                  25
                :unique-id              "V0126_MOVE_HORN_ATTACK"
                :duration-ms            2200
                :animation-id           5
@@ -1436,7 +1436,7 @@
                :trainer-level-min      1
                :damage-window-start-ms 1395
                :id                     132
-               :power                  35
+               :power                  50
                :unique-id              "V0132_MOVE_REST"
                :duration-ms            3100
                :animation-id           5
@@ -1467,7 +1467,7 @@
                :trainer-level-min      1
                :damage-window-start-ms 1800
                :id                     134
-               :power                  35
+               :power                  50
                :unique-id              "V0134_MOVE_SCALD_BLASTOISE"
                :duration-ms            4000
                :animation-id           5


remove dead tree-formatting code

remove dead tree-formatting code

--- src/babel/html.clj
+++ src/babel/html.clj
@@ -331,65 +331,6 @@
                  @(:head arg)
                  (:head arg))
                (concat path '(:head)) serialized opts)
-      "      	 	"
-      "
"
-      "
"
-      "
")
-
-
-     ;; displaying a phrase structure tree (2 children)
-     (and
-      (map? arg)
-
-      (not (= :subcat (last path)))
-
-      ;; display :extends properly (i.e. not a tree).
-      ;; :extends will have features :a,:b,:c,..
-      (not (= :a (last path)))
-      (not (= :b (last path)))
-      (not (= :c (last path)))
-      (not (= :d (last path)))
-      (not (= :e (last path)))
-      (not (= :f (last path)))
-      (not (= :g (last path)))
-
-      (not (= :none (:1 arg :none)))
-      (not (= :none (:2 arg :none))))
-
-     (str
-      "
" "PHRASE"
-      "
"
-      "
"
-      "       	"
-      (tablize (dissoc (dissoc arg :1) :2) path serialized opts)
-      "      	 	"
-      "
"
-      "
"
-      "      "
-      (if (ref? (:1 arg))
-        (str
-         "
"
-         (fs/path-to-ref-index serialized (concat path '(:1)) 0)
-         "
"))
-      "      	"
-      "      "
-      (tablize (if (ref? (:1 arg))
-                 @(:1 arg)
-                 (:1 arg))
-               (concat path '(:1)) serialized opts)
-      "      	"
-      "      "
-      (if (ref? (:2 arg))
-        (str
-         "
"
-         (fs/path-to-ref-index serialized (concat path '(:2)) 0)
-         "
"))
-         "      	"
-         "      "
-      (tablize (if (ref? (:2 arg))
-                 @(:2 arg)
-                 (:2 arg))
-               (concat path '(:2)) serialized opts)
       "      	 	"
       "
"
       "
"


Change update back to assoc/dissoc

Change update back to assoc/dissoc

--- src/aurora/btree.cljs
+++ src/aurora/btree.cljs
@@ -170,15 +170,6 @@

 ;; TREES

-;; update adds the delta to the current value for the key and returns either:
-;;   added if the value went from zero to non-zero
-;;   changed if the value went from non-zero to non-zero
-;;   deled if the value went from non-zero to zero
-
-(def added 1)
-(def changed 0)
-(def deled -1)
-
 (def left-child 0)
 (def right-child 1)

@@ -188,9 +179,10 @@
          (set! root (Node. nil nil #js [] #js [] nil nil nil)))
   (toString [this]
             (pr-str (into (sorted-map-by key-compare) (map vec this))))
-  (update [this key delta]
-          (assert (not (== delta 0)))
-          (.update root key delta max-keys))
+  (add [this key]
+       (.add root key max-keys))
+  (del [this key]
+       (.del root key max-keys))
   (push! [this ix key&val&child which-child]
            (let [left-child (if (== which-child left-child) (aget key&val&child 2) root)
                  right-child (if (== which-child right-child) (aget key&val&child 2) root)]
@@ -230,40 +222,37 @@

 (deftype Node [parent parent-ix keys vals children ^:mutable lower ^:mutable upper]
   Object
-  (update [this key delta max-keys]
-          (let [ix (key-find-gte keys key)]
+  (add [this key max-keys]
+       (let [ix (key-find-gte keys key)]
             (if (and (< ix (alength keys)) (key= key (aget keys ix)))
-              (let [old-val (aget vals ix)
-                    new-val (+ old-val delta)]
-                (if (== 0 new-val)
-                  ;; del
-                  (if (nil? children)
+              false
+              (if (nil? children)
+                (do
+                  (.push! this ix #js [key nil])
+                  (.maintain! this max-keys)
+                  true)
+                (.add (aget children ix) key max-keys)))))
+  (del [this key max-keys]
+       (let [ix (key-find-gte keys key)]
+            (if (and (< ix (alength keys)) (key= key (aget keys ix)))
+              (if (nil? children)
+                (do
+                  (.pop! this ix)
+                  (.maintain! this max-keys)
+                  true)
+                (loop [node (aget children (+ ix 1))]
+                  (if (not (nil? (.-children node)))
+                    (recur (aget (.-children node) 0))
                     (do
-                      (.pop! this ix)
+                      (aset keys ix (aget (.-keys node) 0))
+                      (aset vals ix (aget (.-vals node) 0))
+                      (.pop! node 0)
+                      (.maintain! node max-keys)
                       (.maintain! this max-keys)
-                      deled)
-                    (loop [node (aget children (+ ix 1))]
-                      (if (not (nil? (.-children node)))
-                        (recur (aget (.-children node) 0))
-                        (do
-                          (aset keys ix (aget (.-keys node) 0))
-                          (aset vals ix (aget (.-vals node) 0))
-                          (.pop! node 0)
-                          (.maintain! node max-keys)
-                          (.maintain! this max-keys)
-                          deled))))
-                  ;; change
-                  (do
-                    (aset vals ix new-val)
-                    changed)))
+                      true))))
               (if (nil? children)
-                ;; add
-                (do
-                  (.push! this ix #js [key delta])
-                  (.maintain! this max-keys)
-                  added)
-                ;; recur
-                (.update (aget children ix) key delta max-keys)))))
+                false
+                (.del (aget children ix) key max-keys)))))
   (push! [this ix key&val&child which-child] ;; on leaves, child and which-child are not required
          (.splice keys ix 0 (aget key&val&child 0))
          (.splice vals ix 0 (aget key&val&child 1))
@@ -912,31 +901,32 @@
 (defn gen-update [key-len]
   (gen/make-gen
    (fn [rnd size]
-     (let [key (make-simple-key rnd size key-len)
-           delta (make-simple-delta rnd size)]
-         [[:update key delta] nil]))))
+     (let [key (make-simple-key rnd size key-len)]
+       (if (pprng/boolean rnd)
+         [[:add key] nil]
+         [[:del key] nil])))))

 (defn apply-to-tree [tree updates]
   [tree
    (doall
     (for [update updates]
-      (.update tree (nth update 1) (nth update 2))))])
+      (case (nth update 0)
+        :add (.add tree (nth update 1))
+        :del (.del tree (nth update 1)))))])

 (defn apply-to-sorted-map [map updates]
   (let [map (atom map)
         results (doall
                  (for [update updates]
                    (let [key (nth update 1)
-                         delta (nth update 2)
-                         old-val (get @map key 0)
-                         new-val (+ old-val delta)]
-                     (if (== new-val 0)
-                       (swap! map dissoc key)
-                       (swap! map assoc key new-val))
-                     (cond
-                      (and (== old-val 0) (not (== new-val 0))) added
-                      (and (not (== old-val 0)) (not (== new-val 0))) changed
-                      (and (not (== old-val 0)) (== new-val 0)) deled))))]
+                         old (contains? @map key)]
+                     (case (nth update 0)
+                       :add (do
+                              (swap! map assoc key)
+                              (false? old))
+                       :del (do
+                              (swap! map dissoc key)
+                              (true? old))))))]
     [@map results]))

 (defn run-building-prop [min-keys key-len updates]


keep track of active matches

keep track of active matches

--- src/c4_arena/core.clj
+++ src/c4_arena/core.clj
@@ -30,8 +30,6 @@
 (defonce matcher (atom nil))
 ;;; All the ids waiting for a match
 (defonce awaiting (atom nil))
-
-(defonce match-count (atom {}))

 (defonce uid-counter (atom 0))

@@ -162,11 +160,18 @@
                    {:type :ignored :msg msg :reason "Waiting for match"})
              (recur)))))))

+(defonce match-count (atom {}))
+(defonce active-matches (atom #{}))
 (defn match-once [{:keys [id] :as player0}]
   (if-let [player1 (->> (vals @awaiting)
                         (remove
                          (fn [{other-id :id}]
                            (= id other-id)))
+                        ;; Do not match if there is an active game
+                        ;; going on
+                        (remove
+                         (fn [{other-id :id}]
+                           (@active-matches #{id other-id})))
                         ;; Try to match with the least matched person
                         (sort-by
                          (fn [{other-id :id}]
@@ -174,8 +179,14 @@
                         first)]
     ;; Someone is available!
     (do (async/close! (:waiter player1))
-        (swap! match-count update-in [#{(:id player0) (:id player1)}] (fnil inc 0))
-        (game-loop (->> [player0 player1] (map #(dissoc % :waiter)))))
+        (let [pair #{(:id player0) (:id player1)}]
+          (swap! match-count update-in [pair] (fnil inc 0))
+          (swap! active-matches conj pair)
+          (go
+            (<! (game-loop (->> [player0 player1] (map #(dissoc % :waiter)))))
+            ;; Loop ends when the game is over. We can then mark the
+            ;; match as no longer active
+            (swap! active-matches disj pair))))
     ;; Nobody is available
     (let [player0 (assoc player0 :waiter (chan))]
       (swap! awaiting assoc (:uid player0) player0)


Add information about last job run to background workers

Also show this info in logs

--- src/cfpb/qu/cache.clj
+++ src/cfpb/qu/cache.clj
@@ -200,11 +200,20 @@
 (defn- find-and-claim-unprocessed
   "Find the next unprocessed map-reduce job and claim it.
    Returns job."
-  [worker]
+  []
   (coll/find-and-modify *work-collection*
                         {:status "unprocessed"}
                         {"$set" {:status "processing"}}
                         :sort {:created 1}))
+
+(defn- reset-job
+  "Reset a job being processed back to unprocessed."
+  [job-id]
+  (coll/find-and-modify *work-collection*
+                        {:_id job-id :status "processing"}
+                        {"$set" {:status "unprocessed"
+                                 :created (now)}
+                         "$inc" {:reset_count 1}}))

 (defn- work-job
   "Given a map-reduce job, tells Mongo to perform the job.
@@ -230,12 +239,14 @@
   [worker]
   (when-not (:kill worker)
     (with-db (get-in worker [:cache :database])
-      (if-let [job (find-and-claim-unprocessed worker)]
-        (do (log/info "Aggregation" (:_id job) "started")
-            (work-job worker job)
-            (update-cache worker job)
-            (send *agent* #(update-in % [:processed] inc))
-            (log/info "Aggregation" (:_id job) "processed"))
+      (if-let [job (find-and-claim-unprocessed)]
+        (let [job-id (:_id job)]
+          (log/info "Aggregation" job-id "started")
+          (send *agent* #(assoc-in % [:last-job-id] job-id))
+          (work-job worker job)
+          (update-cache worker job)
+          (send *agent* #(update-in % [:processed] inc))
+          (log/info "Aggregation" job-id "processed"))
         (do
           (clean-cache (:cache worker))
           (Thread/sleep *wait-time*)))
@@ -275,10 +286,13 @@
   (let [worker-agent (agent worker
                             :error-mode :continue
                             :error-handler (fn [the-agent exception]
-                                             (log/warn "Error with cache worker" @the-agent)
-                                             (log/warn (.getMessage exception))
-                                             (log/warn "=== END EXCEPTION ===")
-                                             (send-off the-agent process-next-job)))]
+                                             (let [job-id (:last-job-id @the-agent)]
+                                               (log/error "Error with cache worker" @the-agent)
+                                               (log/error "Last job ID" job-id)
+                                               (log/error exception)
+                                               (log/error "=== END EXCEPTION ===")
+                                               (reset-job job-id)
+                                               (send-off the-agent process-next-job))))]
     (send worker-agent #(assoc % :kill false))
     (send-off worker-agent process-next-job)))