torre 0.3.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1834) hide show
  1. torre/__init__.py +6 -0
  2. torre/__main__.py +4 -0
  3. torre/analysis/__init__.py +1 -0
  4. torre/analysis/analyze.py +337 -0
  5. torre/analysis/board_view.py +195 -0
  6. torre/analysis/bot_report.py +79 -0
  7. torre/analysis/engine_service.py +263 -0
  8. torre/analysis/engines.py +928 -0
  9. torre/analysis/game_export.py +157 -0
  10. torre/analysis/game_moves.py +42 -0
  11. torre/analysis/game_stats.py +518 -0
  12. torre/analysis/insights.py +394 -0
  13. torre/analysis/motifs.py +141 -0
  14. torre/analysis/opening_book.py +97 -0
  15. torre/analysis/pgn_export.py +82 -0
  16. torre/analysis/report.py +151 -0
  17. torre/analysis/scoring.py +313 -0
  18. torre/cli.py +272 -0
  19. torre/coaching/__init__.py +1 -0
  20. torre/coaching/coach.py +524 -0
  21. torre/coaching/coach_ai.py +132 -0
  22. torre/coaching/coach_focus.py +162 -0
  23. torre/coaching/coach_home.py +177 -0
  24. torre/coaching/coach_ledger.py +364 -0
  25. torre/coaching/coach_lessons.py +674 -0
  26. torre/coaching/coach_plan.py +97 -0
  27. torre/coaching/explain.py +207 -0
  28. torre/coaching/skills.py +139 -0
  29. torre/content/chess-library.json +1249 -0
  30. torre/content/es/awards.json +122 -0
  31. torre/content/es/messages.json +61 -0
  32. torre/content/es/themes.json +150 -0
  33. torre/content/grading.json +13 -0
  34. torre/content/lessons/README.md +203 -0
  35. torre/content/lessons/anastasias-mate.json +60 -0
  36. torre/content/lessons/anderssen-staunton-1851.json +106 -0
  37. torre/content/lessons/arabian-mate.json +60 -0
  38. torre/content/lessons/attraction.json +59 -0
  39. torre/content/lessons/back-rank-mate.json +69 -0
  40. torre/content/lessons/blackburne-shilling-trap.json +102 -0
  41. torre/content/lessons/bodens-mate.json +60 -0
  42. torre/content/lessons/botvinnik-capablanca-1938.json +212 -0
  43. torre/content/lessons/capablanca-marshall-1909.json +101 -0
  44. torre/content/lessons/capablanca-tartakower-1924.json +104 -0
  45. torre/content/lessons/carlsen-anand-2013.json +236 -0
  46. torre/content/lessons/carlsen-ernst-2004.json +180 -0
  47. torre/content/lessons/castling.json +71 -0
  48. torre/content/lessons/check-and-checkmate.json +85 -0
  49. torre/content/lessons/colle-attack.json +84 -0
  50. torre/content/lessons/colle-setup.json +71 -0
  51. torre/content/lessons/deflection.json +59 -0
  52. torre/content/lessons/discovered-attack.json +60 -0
  53. torre/content/lessons/double-check.json +60 -0
  54. torre/content/lessons/doubled-and-backward-pawns.json +71 -0
  55. torre/content/lessons/dovetail-mate.json +60 -0
  56. torre/content/lessons/draws.json +76 -0
  57. torre/content/lessons/elephant-trap.json +127 -0
  58. torre/content/lessons/en-passant.json +71 -0
  59. torre/content/lessons/englund-trap.json +120 -0
  60. torre/content/lessons/es/anastasias-mate.json +49 -0
  61. torre/content/lessons/es/anderssen-staunton-1851.json +99 -0
  62. torre/content/lessons/es/arabian-mate.json +49 -0
  63. torre/content/lessons/es/attraction.json +48 -0
  64. torre/content/lessons/es/back-rank-mate.json +54 -0
  65. torre/content/lessons/es/blackburne-shilling-trap.json +55 -0
  66. torre/content/lessons/es/bodens-mate.json +49 -0
  67. torre/content/lessons/es/botvinnik-capablanca-1938.json +98 -0
  68. torre/content/lessons/es/capablanca-marshall-1909.json +90 -0
  69. torre/content/lessons/es/capablanca-tartakower-1924.json +96 -0
  70. torre/content/lessons/es/carlsen-anand-2013.json +90 -0
  71. torre/content/lessons/es/carlsen-ernst-2004.json +92 -0
  72. torre/content/lessons/es/castling.json +55 -0
  73. torre/content/lessons/es/check-and-checkmate.json +67 -0
  74. torre/content/lessons/es/colle-attack.json +61 -0
  75. torre/content/lessons/es/colle-setup.json +55 -0
  76. torre/content/lessons/es/deflection.json +48 -0
  77. torre/content/lessons/es/discovered-attack.json +48 -0
  78. torre/content/lessons/es/double-check.json +48 -0
  79. torre/content/lessons/es/doubled-and-backward-pawns.json +55 -0
  80. torre/content/lessons/es/dovetail-mate.json +49 -0
  81. torre/content/lessons/es/draws.json +59 -0
  82. torre/content/lessons/es/elephant-trap.json +69 -0
  83. torre/content/lessons/es/en-passant.json +55 -0
  84. torre/content/lessons/es/englund-trap.json +64 -0
  85. torre/content/lessons/es/fischer-petrosian-1971.json +96 -0
  86. torre/content/lessons/es/fischer-spassky-1972.json +91 -0
  87. torre/content/lessons/es/fishing-pole.json +64 -0
  88. torre/content/lessons/es/fried-liver.json +78 -0
  89. torre/content/lessons/es/game-of-the-century.json +101 -0
  90. torre/content/lessons/es/good-and-bad-bishops.json +47 -0
  91. torre/content/lessons/es/hanging-pieces.json +74 -0
  92. torre/content/lessons/es/hastings-1895.json +102 -0
  93. torre/content/lessons/es/hook-mate.json +49 -0
  94. torre/content/lessons/es/interference.json +48 -0
  95. torre/content/lessons/es/isolated-pawn.json +73 -0
  96. torre/content/lessons/es/karpov-unzicker-1974.json +91 -0
  97. torre/content/lessons/es/kasparov-topalov-1999.json +96 -0
  98. torre/content/lessons/es/key-squares.json +62 -0
  99. torre/content/lessons/es/king-and-pawn-vs-king.json +62 -0
  100. torre/content/lessons/es/knight-fork.json +48 -0
  101. torre/content/lessons/es/lasker-bauer-1889.json +99 -0
  102. torre/content/lessons/es/lasker-trap.json +78 -0
  103. torre/content/lessons/es/legals-mate.json +75 -0
  104. torre/content/lessons/es/london-model-game.json +81 -0
  105. torre/content/lessons/es/london-plans.json +55 -0
  106. torre/content/lessons/es/london-setup.json +61 -0
  107. torre/content/lessons/es/london-traps.json +55 -0
  108. torre/content/lessons/es/london-vs-c5-qb6.json +71 -0
  109. torre/content/lessons/es/lucena.json +48 -0
  110. torre/content/lessons/es/mikhail-tal.json +88 -0
  111. torre/content/lessons/es/morphy-bird-1858.json +97 -0
  112. torre/content/lessons/es/morphy-opera-game.json +79 -0
  113. torre/content/lessons/es/morphy-paulsen-1857.json +93 -0
  114. torre/content/lessons/es/morphy-vs-anderssen.json +90 -0
  115. torre/content/lessons/es/noahs-ark-trap.json +72 -0
  116. torre/content/lessons/es/open-files.json +55 -0
  117. torre/content/lessons/es/opening-principles.json +90 -0
  118. torre/content/lessons/es/opposition.json +54 -0
  119. torre/content/lessons/es/outposts.json +55 -0
  120. torre/content/lessons/es/outside-passed-pawn.json +54 -0
  121. torre/content/lessons/es/overloading.json +48 -0
  122. torre/content/lessons/es/passed-pawns.json +79 -0
  123. torre/content/lessons/es/pawn-breakthrough.json +54 -0
  124. torre/content/lessons/es/pawn-chains.json +53 -0
  125. torre/content/lessons/es/petrosian-spassky-1966.json +93 -0
  126. torre/content/lessons/es/philidor-model-game.json +76 -0
  127. torre/content/lessons/es/philidor-plans.json +55 -0
  128. torre/content/lessons/es/philidor-position.json +54 -0
  129. torre/content/lessons/es/philidor-setup.json +55 -0
  130. torre/content/lessons/es/philidor-traps.json +61 -0
  131. torre/content/lessons/es/pins.json +40 -0
  132. torre/content/lessons/es/polgar-berkes-2003.json +92 -0
  133. torre/content/lessons/es/promotion-basics.json +49 -0
  134. torre/content/lessons/es/prophylaxis.json +69 -0
  135. torre/content/lessons/es/queen-mate.json +55 -0
  136. torre/content/lessons/es/removing-the-defender.json +48 -0
  137. torre/content/lessons/es/rook-behind-passed-pawn.json +54 -0
  138. torre/content/lessons/es/rook-mate.json +57 -0
  139. torre/content/lessons/es/rook-on-the-seventh.json +55 -0
  140. torre/content/lessons/es/scholars-mate.json +63 -0
  141. torre/content/lessons/es/skewer.json +48 -0
  142. torre/content/lessons/es/smothered-mate.json +57 -0
  143. torre/content/lessons/es/square-of-the-pawn.json +48 -0
  144. torre/content/lessons/es/st-petersburg-1914.json +96 -0
  145. torre/content/lessons/es/stalemate.json +55 -0
  146. torre/content/lessons/es/steinitz-zukertort-1886.json +96 -0
  147. torre/content/lessons/es/tal-hecht-varna-1962.json +98 -0
  148. torre/content/lessons/es/tal-larsen-bled-1965.json +90 -0
  149. torre/content/lessons/es/the-bishop.json +55 -0
  150. torre/content/lessons/es/the-evergreen-game.json +82 -0
  151. torre/content/lessons/es/the-immortal-game.json +79 -0
  152. torre/content/lessons/es/the-king.json +55 -0
  153. torre/content/lessons/es/the-knight.json +61 -0
  154. torre/content/lessons/es/the-pawn.json +55 -0
  155. torre/content/lessons/es/the-queen.json +55 -0
  156. torre/content/lessons/es/the-rook.json +55 -0
  157. torre/content/lessons/es/triangulation.json +54 -0
  158. torre/content/lessons/es/two-bishops-mate.json +57 -0
  159. torre/content/lessons/es/two-rook-ladder.json +55 -0
  160. torre/content/lessons/es/weak-squares-and-holes.json +55 -0
  161. torre/content/lessons/es/wrong-colored-bishop.json +54 -0
  162. torre/content/lessons/es/x-ray.json +48 -0
  163. torre/content/lessons/es/zwischenzug.json +48 -0
  164. torre/content/lessons/fischer-petrosian-1971.json +195 -0
  165. torre/content/lessons/fischer-spassky-1972.json +204 -0
  166. torre/content/lessons/fishing-pole.json +112 -0
  167. torre/content/lessons/fried-liver.json +163 -0
  168. torre/content/lessons/game-of-the-century.json +217 -0
  169. torre/content/lessons/good-and-bad-bishops.json +59 -0
  170. torre/content/lessons/hanging-pieces.json +82 -0
  171. torre/content/lessons/hastings-1895.json +105 -0
  172. torre/content/lessons/hook-mate.json +60 -0
  173. torre/content/lessons/interference.json +59 -0
  174. torre/content/lessons/isolated-pawn.json +82 -0
  175. torre/content/lessons/karpov-unzicker-1974.json +209 -0
  176. torre/content/lessons/kasparov-topalov-1999.json +216 -0
  177. torre/content/lessons/key-squares.json +81 -0
  178. torre/content/lessons/king-and-pawn-vs-king.json +81 -0
  179. torre/content/lessons/knight-fork.json +58 -0
  180. torre/content/lessons/lasker-bauer-1889.json +104 -0
  181. torre/content/lessons/lasker-trap.json +160 -0
  182. torre/content/lessons/legals-mate.json +158 -0
  183. torre/content/lessons/london-model-game.json +68 -0
  184. torre/content/lessons/london-plans.json +74 -0
  185. torre/content/lessons/london-setup.json +80 -0
  186. torre/content/lessons/london-traps.json +73 -0
  187. torre/content/lessons/london-vs-c5-qb6.json +96 -0
  188. torre/content/lessons/lucena.json +59 -0
  189. torre/content/lessons/mikhail-tal.json +72 -0
  190. torre/content/lessons/morphy-bird-1858.json +100 -0
  191. torre/content/lessons/morphy-opera-game.json +69 -0
  192. torre/content/lessons/morphy-paulsen-1857.json +103 -0
  193. torre/content/lessons/morphy-vs-anderssen.json +102 -0
  194. torre/content/lessons/noahs-ark-trap.json +141 -0
  195. torre/content/lessons/open-files.json +71 -0
  196. torre/content/lessons/opening-principles.json +96 -0
  197. torre/content/lessons/opposition.json +68 -0
  198. torre/content/lessons/outposts.json +71 -0
  199. torre/content/lessons/outside-passed-pawn.json +69 -0
  200. torre/content/lessons/overloading.json +59 -0
  201. torre/content/lessons/passed-pawns.json +85 -0
  202. torre/content/lessons/pawn-breakthrough.json +70 -0
  203. torre/content/lessons/pawn-chains.json +71 -0
  204. torre/content/lessons/petrosian-spassky-1966.json +184 -0
  205. torre/content/lessons/philidor-model-game.json +66 -0
  206. torre/content/lessons/philidor-plans.json +73 -0
  207. torre/content/lessons/philidor-position.json +71 -0
  208. torre/content/lessons/philidor-setup.json +72 -0
  209. torre/content/lessons/philidor-traps.json +85 -0
  210. torre/content/lessons/pins.json +47 -0
  211. torre/content/lessons/polgar-berkes-2003.json +170 -0
  212. torre/content/lessons/promotion-basics.json +62 -0
  213. torre/content/lessons/prophylaxis.json +75 -0
  214. torre/content/lessons/queen-mate.json +72 -0
  215. torre/content/lessons/removing-the-defender.json +59 -0
  216. torre/content/lessons/rook-behind-passed-pawn.json +69 -0
  217. torre/content/lessons/rook-mate.json +73 -0
  218. torre/content/lessons/rook-on-the-seventh.json +71 -0
  219. torre/content/lessons/scholars-mate.json +124 -0
  220. torre/content/lessons/skewer.json +60 -0
  221. torre/content/lessons/smothered-mate.json +72 -0
  222. torre/content/lessons/square-of-the-pawn.json +59 -0
  223. torre/content/lessons/st-petersburg-1914.json +104 -0
  224. torre/content/lessons/stalemate.json +70 -0
  225. torre/content/lessons/steinitz-zukertort-1886.json +103 -0
  226. torre/content/lessons/tal-hecht-varna-1962.json +231 -0
  227. torre/content/lessons/tal-larsen-bled-1965.json +194 -0
  228. torre/content/lessons/the-bishop.json +71 -0
  229. torre/content/lessons/the-evergreen-game.json +70 -0
  230. torre/content/lessons/the-immortal-game.json +69 -0
  231. torre/content/lessons/the-king.json +69 -0
  232. torre/content/lessons/the-knight.json +80 -0
  233. torre/content/lessons/the-pawn.json +70 -0
  234. torre/content/lessons/the-queen.json +70 -0
  235. torre/content/lessons/the-rook.json +72 -0
  236. torre/content/lessons/triangulation.json +70 -0
  237. torre/content/lessons/two-bishops-mate.json +73 -0
  238. torre/content/lessons/two-rook-ladder.json +71 -0
  239. torre/content/lessons/units.json +8 -0
  240. torre/content/lessons/weak-squares-and-holes.json +71 -0
  241. torre/content/lessons/wrong-colored-bishop.json +70 -0
  242. torre/content/lessons/x-ray.json +60 -0
  243. torre/content/lessons/zwischenzug.json +59 -0
  244. torre/content/opening-book.json +60895 -0
  245. torre/content/puzzles/anastasia-mate.json +192 -0
  246. torre/content/puzzles/arabian-mate.json +210 -0
  247. torre/content/puzzles/attraction.json +227 -0
  248. torre/content/puzzles/back-rank-mate.json +221 -0
  249. torre/content/puzzles/bishop-endgame.json +240 -0
  250. torre/content/puzzles/boden-mate.json +184 -0
  251. torre/content/puzzles/capturing-defender.json +217 -0
  252. torre/content/puzzles/clearance.json +221 -0
  253. torre/content/puzzles/defensive-move.json +222 -0
  254. torre/content/puzzles/deflection.json +230 -0
  255. torre/content/puzzles/discovered-attack.json +240 -0
  256. torre/content/puzzles/double-check.json +223 -0
  257. torre/content/puzzles/exposed-king.json +221 -0
  258. torre/content/puzzles/fork.json +240 -0
  259. torre/content/puzzles/hanging-piece.json +240 -0
  260. torre/content/puzzles/hook-mate.json +212 -0
  261. torre/content/puzzles/interference.json +212 -0
  262. torre/content/puzzles/kingside-attack.json +240 -0
  263. torre/content/puzzles/knight-endgame.json +240 -0
  264. torre/content/puzzles/mate-in-1.json +203 -0
  265. torre/content/puzzles/mate-in-2.json +227 -0
  266. torre/content/puzzles/mate-in-3.json +240 -0
  267. torre/content/puzzles/mate-in-4.json +220 -0
  268. torre/content/puzzles/pawn-endgame.json +240 -0
  269. torre/content/puzzles/pin.json +234 -0
  270. torre/content/puzzles/promotion.json +240 -0
  271. torre/content/puzzles/queen-endgame.json +240 -0
  272. torre/content/puzzles/quiet-move.json +240 -0
  273. torre/content/puzzles/rook-endgame.json +240 -0
  274. torre/content/puzzles/sacrifice.json +240 -0
  275. torre/content/puzzles/skewer.json +240 -0
  276. torre/content/puzzles/smothered-mate.json +178 -0
  277. torre/content/puzzles/trapped-piece.json +216 -0
  278. torre/content/puzzles/underpromotion.json +202 -0
  279. torre/content/puzzles/x-ray.json +225 -0
  280. torre/content/puzzles/zwischenzug.json +212 -0
  281. torre/content/videos.json +124 -0
  282. torre/games/__init__.py +1 -0
  283. torre/games/arena.py +511 -0
  284. torre/games/chesscom_common.py +88 -0
  285. torre/games/download_masters.py +80 -0
  286. torre/games/importer.py +469 -0
  287. torre/games/masters.py +375 -0
  288. torre/jsonio.py +141 -0
  289. torre/learning/__init__.py +1 -0
  290. torre/learning/achievements.py +407 -0
  291. torre/learning/drills.py +245 -0
  292. torre/learning/endgames.py +275 -0
  293. torre/learning/ladder.py +219 -0
  294. torre/learning/lessons.py +499 -0
  295. torre/learning/my_puzzles.py +337 -0
  296. torre/learning/openings.py +262 -0
  297. torre/learning/packs.py +157 -0
  298. torre/learning/puzzles.py +446 -0
  299. torre/learning/story.py +199 -0
  300. torre/learning/trainer.py +279 -0
  301. torre/paths.py +25 -0
  302. torre/server/__init__.py +1 -0
  303. torre/server/access.py +47 -0
  304. torre/server/api_board.py +361 -0
  305. torre/server/api_coach.py +146 -0
  306. torre/server/api_engines.py +156 -0
  307. torre/server/api_games.py +334 -0
  308. torre/server/api_training.py +370 -0
  309. torre/server/appdata.py +160 -0
  310. torre/server/applog.py +43 -0
  311. torre/server/hosts.py +45 -0
  312. torre/server/jobs.py +95 -0
  313. torre/server/routes.py +129 -0
  314. torre/server/studio.py +282 -0
  315. torre/tools/__init__.py +3 -0
  316. torre/tools/build_opening_book.py +43 -0
  317. torre/tools/build_packs.py +55 -0
  318. torre/tools/clean_wording.py +103 -0
  319. torre/tools/download_books.py +882 -0
  320. torre/tools/game_story.py +186 -0
  321. torre/tools/import_puzzles.py +104 -0
  322. torre/tools/lichess_import.py +93 -0
  323. torre/tools/release_vela.py +76 -0
  324. torre/tools/repair_game_dates.py +57 -0
  325. torre/tools/translate_content.py +455 -0
  326. torre/tools/verify_lessons.py +211 -0
  327. torre/translations.py +66 -0
  328. torre/ui/art/avatars/01-3.webp +0 -0
  329. torre/ui/art/avatars/01-4.webp +0 -0
  330. torre/ui/art/avatars/01-5.webp +0 -0
  331. torre/ui/art/avatars/01-7.webp +0 -0
  332. torre/ui/art/avatars/02-3.webp +0 -0
  333. torre/ui/art/avatars/02-4.webp +0 -0
  334. torre/ui/art/avatars/02-6.webp +0 -0
  335. torre/ui/art/avatars/03-3.webp +0 -0
  336. torre/ui/art/avatars/03-6.webp +0 -0
  337. torre/ui/art/avatars/04-1.webp +0 -0
  338. torre/ui/art/avatars/04-5.webp +0 -0
  339. torre/ui/art/avatars/04-7.webp +0 -0
  340. torre/ui/art/avatars/04-8.webp +0 -0
  341. torre/ui/art/avatars/05-1.webp +0 -0
  342. torre/ui/art/avatars/05-2.webp +0 -0
  343. torre/ui/art/avatars/05-4.webp +0 -0
  344. torre/ui/art/avatars/05-5.webp +0 -0
  345. torre/ui/art/avatars/06-3.webp +0 -0
  346. torre/ui/art/avatars/06-7.webp +0 -0
  347. torre/ui/art/avatars/06-8.webp +0 -0
  348. torre/ui/art/avatars/07-2.webp +0 -0
  349. torre/ui/art/avatars/07-3.webp +0 -0
  350. torre/ui/art/avatars/07-6.webp +0 -0
  351. torre/ui/art/avatars/07-7.webp +0 -0
  352. torre/ui/art/avatars/08-2.webp +0 -0
  353. torre/ui/art/avatars/08-7.webp +0 -0
  354. torre/ui/art/avatars/10-1.webp +0 -0
  355. torre/ui/art/avatars/10-8.webp +0 -0
  356. torre/ui/art/avatars/11-1.webp +0 -0
  357. torre/ui/art/avatars/11-2.webp +0 -0
  358. torre/ui/art/avatars/13-6.webp +0 -0
  359. torre/ui/art/avatars/13-7.webp +0 -0
  360. torre/ui/art/avatars/14-1.webp +0 -0
  361. torre/ui/art/avatars/14-3.webp +0 -0
  362. torre/ui/art/avatars/14-6.webp +0 -0
  363. torre/ui/art/avatars/15-1.webp +0 -0
  364. torre/ui/art/avatars/17-4.webp +0 -0
  365. torre/ui/art/avatars/17-5.webp +0 -0
  366. torre/ui/art/avatars/17-6.webp +0 -0
  367. torre/ui/art/avatars/18-6.webp +0 -0
  368. torre/ui/art/avatars/ukraine-1.webp +0 -0
  369. torre/ui/art/avatars/ukraine-2.webp +0 -0
  370. torre/ui/art/avatars/ukraine-3.webp +0 -0
  371. torre/ui/art/avatars/ukraine-4.webp +0 -0
  372. torre/ui/art/avatars/ukraine-5.webp +0 -0
  373. torre/ui/art/avatars/ukraine-6.webp +0 -0
  374. torre/ui/art/avatars/ukraine-7.webp +0 -0
  375. torre/ui/art/avatars/ukraine-8.webp +0 -0
  376. torre/ui/art/badges/back-rank-bronze.webp +0 -0
  377. torre/ui/art/badges/back-rank-color.webp +0 -0
  378. torre/ui/art/badges/back-rank-gold.webp +0 -0
  379. torre/ui/art/badges/back-rank-silver.webp +0 -0
  380. torre/ui/art/badges/blitz-bronze.webp +0 -0
  381. torre/ui/art/badges/blitz-color.webp +0 -0
  382. torre/ui/art/badges/blitz-gold.webp +0 -0
  383. torre/ui/art/badges/blitz-silver.webp +0 -0
  384. torre/ui/art/badges/brilliant-bronze.webp +0 -0
  385. torre/ui/art/badges/brilliant-color.webp +0 -0
  386. torre/ui/art/badges/brilliant-gold.webp +0 -0
  387. torre/ui/art/badges/brilliant-silver.webp +0 -0
  388. torre/ui/art/badges/castle-bronze.webp +0 -0
  389. torre/ui/art/badges/castle-color.webp +0 -0
  390. torre/ui/art/badges/castle-gold.webp +0 -0
  391. torre/ui/art/badges/castle-silver.webp +0 -0
  392. torre/ui/art/badges/checkmate-bronze.webp +0 -0
  393. torre/ui/art/badges/checkmate-color.webp +0 -0
  394. torre/ui/art/badges/checkmate-gold.webp +0 -0
  395. torre/ui/art/badges/checkmate-silver.webp +0 -0
  396. torre/ui/art/badges/deflection-bronze.webp +0 -0
  397. torre/ui/art/badges/deflection-color.webp +0 -0
  398. torre/ui/art/badges/deflection-gold.webp +0 -0
  399. torre/ui/art/badges/deflection-silver.webp +0 -0
  400. torre/ui/art/badges/discovery-bronze.webp +0 -0
  401. torre/ui/art/badges/discovery-color.webp +0 -0
  402. torre/ui/art/badges/discovery-gold.webp +0 -0
  403. torre/ui/art/badges/discovery-silver.webp +0 -0
  404. torre/ui/art/badges/endgame-bronze.webp +0 -0
  405. torre/ui/art/badges/endgame-color.webp +0 -0
  406. torre/ui/art/badges/endgame-gold.webp +0 -0
  407. torre/ui/art/badges/endgame-silver.webp +0 -0
  408. torre/ui/art/badges/fork-bronze.webp +0 -0
  409. torre/ui/art/badges/fork-color.webp +0 -0
  410. torre/ui/art/badges/fork-gold.webp +0 -0
  411. torre/ui/art/badges/fork-silver.webp +0 -0
  412. torre/ui/art/badges/good-sport-bronze.webp +0 -0
  413. torre/ui/art/badges/good-sport-color.webp +0 -0
  414. torre/ui/art/badges/good-sport-gold.webp +0 -0
  415. torre/ui/art/badges/good-sport-silver.webp +0 -0
  416. torre/ui/art/badges/legend-bronze.webp +0 -0
  417. torre/ui/art/badges/legend-color.webp +0 -0
  418. torre/ui/art/badges/legend-gold.webp +0 -0
  419. torre/ui/art/badges/legend-silver.webp +0 -0
  420. torre/ui/art/badges/outpost-bronze.webp +0 -0
  421. torre/ui/art/badges/outpost-color.webp +0 -0
  422. torre/ui/art/badges/outpost-gold.webp +0 -0
  423. torre/ui/art/badges/outpost-silver.webp +0 -0
  424. torre/ui/art/badges/passed-pawn-bronze.webp +0 -0
  425. torre/ui/art/badges/passed-pawn-color.webp +0 -0
  426. torre/ui/art/badges/passed-pawn-gold.webp +0 -0
  427. torre/ui/art/badges/passed-pawn-silver.webp +0 -0
  428. torre/ui/art/badges/patience-bronze.webp +0 -0
  429. torre/ui/art/badges/patience-color.webp +0 -0
  430. torre/ui/art/badges/patience-gold.webp +0 -0
  431. torre/ui/art/badges/patience-silver.webp +0 -0
  432. torre/ui/art/badges/pin-bronze.webp +0 -0
  433. torre/ui/art/badges/pin-color.webp +0 -0
  434. torre/ui/art/badges/pin-gold.webp +0 -0
  435. torre/ui/art/badges/pin-silver.webp +0 -0
  436. torre/ui/art/badges/precision-bronze.webp +0 -0
  437. torre/ui/art/badges/precision-color.webp +0 -0
  438. torre/ui/art/badges/precision-gold.webp +0 -0
  439. torre/ui/art/badges/precision-silver.webp +0 -0
  440. torre/ui/art/badges/promotion-bronze.webp +0 -0
  441. torre/ui/art/badges/promotion-color.webp +0 -0
  442. torre/ui/art/badges/promotion-gold.webp +0 -0
  443. torre/ui/art/badges/promotion-silver.webp +0 -0
  444. torre/ui/art/badges/sacrifice-bronze.webp +0 -0
  445. torre/ui/art/badges/sacrifice-color.webp +0 -0
  446. torre/ui/art/badges/sacrifice-gold.webp +0 -0
  447. torre/ui/art/badges/sacrifice-silver.webp +0 -0
  448. torre/ui/art/badges/scholar-bronze.webp +0 -0
  449. torre/ui/art/badges/scholar-color.webp +0 -0
  450. torre/ui/art/badges/scholar-gold.webp +0 -0
  451. torre/ui/art/badges/scholar-silver.webp +0 -0
  452. torre/ui/art/badges/skewer-bronze.webp +0 -0
  453. torre/ui/art/badges/skewer-color.webp +0 -0
  454. torre/ui/art/badges/skewer-gold.webp +0 -0
  455. torre/ui/art/badges/skewer-silver.webp +0 -0
  456. torre/ui/art/badges/summit-bronze.webp +0 -0
  457. torre/ui/art/badges/summit-color.webp +0 -0
  458. torre/ui/art/badges/summit-gold.webp +0 -0
  459. torre/ui/art/badges/summit-silver.webp +0 -0
  460. torre/ui/art/badges/swindle-bronze.webp +0 -0
  461. torre/ui/art/badges/swindle-color.webp +0 -0
  462. torre/ui/art/badges/swindle-gold.webp +0 -0
  463. torre/ui/art/badges/swindle-silver.webp +0 -0
  464. torre/ui/art/badges/tactician-bronze.webp +0 -0
  465. torre/ui/art/badges/tactician-color.webp +0 -0
  466. torre/ui/art/badges/tactician-gold.webp +0 -0
  467. torre/ui/art/badges/tactician-silver.webp +0 -0
  468. torre/ui/art/badges/zugzwang-bronze.webp +0 -0
  469. torre/ui/art/badges/zugzwang-color.webp +0 -0
  470. torre/ui/art/badges/zugzwang-gold.webp +0 -0
  471. torre/ui/art/badges/zugzwang-silver.webp +0 -0
  472. torre/ui/art/bots/01-1.webp +0 -0
  473. torre/ui/art/bots/01-2.webp +0 -0
  474. torre/ui/art/bots/01-3.webp +0 -0
  475. torre/ui/art/bots/01-4.webp +0 -0
  476. torre/ui/art/bots/01-5.webp +0 -0
  477. torre/ui/art/bots/01-6.webp +0 -0
  478. torre/ui/art/bots/01-7.webp +0 -0
  479. torre/ui/art/bots/01-8.webp +0 -0
  480. torre/ui/art/bots/02-1.webp +0 -0
  481. torre/ui/art/bots/02-2.webp +0 -0
  482. torre/ui/art/bots/02-3.webp +0 -0
  483. torre/ui/art/bots/02-4.webp +0 -0
  484. torre/ui/art/bots/02-5.webp +0 -0
  485. torre/ui/art/bots/02-6.webp +0 -0
  486. torre/ui/art/bots/02-7.webp +0 -0
  487. torre/ui/art/bots/02-8.webp +0 -0
  488. torre/ui/art/bots/03-2.webp +0 -0
  489. torre/ui/art/bots/03-3.webp +0 -0
  490. torre/ui/art/bots/03-4.webp +0 -0
  491. torre/ui/art/bots/03-5.webp +0 -0
  492. torre/ui/art/bots/03-6.webp +0 -0
  493. torre/ui/art/bots/03-7.webp +0 -0
  494. torre/ui/art/bots/03-8.webp +0 -0
  495. torre/ui/art/bots/04-1.webp +0 -0
  496. torre/ui/art/bots/04-2.webp +0 -0
  497. torre/ui/art/bots/04-3.webp +0 -0
  498. torre/ui/art/bots/04-4.webp +0 -0
  499. torre/ui/art/bots/04-5.webp +0 -0
  500. torre/ui/art/bots/04-6.webp +0 -0
  501. torre/ui/art/bots/04-7.webp +0 -0
  502. torre/ui/art/bots/04-8.webp +0 -0
  503. torre/ui/art/bots/05-1.webp +0 -0
  504. torre/ui/art/bots/05-2.webp +0 -0
  505. torre/ui/art/bots/05-3.webp +0 -0
  506. torre/ui/art/bots/05-4.webp +0 -0
  507. torre/ui/art/bots/05-5.webp +0 -0
  508. torre/ui/art/bots/05-7.webp +0 -0
  509. torre/ui/art/bots/05-8.webp +0 -0
  510. torre/ui/art/bots/06-1.webp +0 -0
  511. torre/ui/art/bots/06-2.webp +0 -0
  512. torre/ui/art/bots/06-3.webp +0 -0
  513. torre/ui/art/bots/06-4.webp +0 -0
  514. torre/ui/art/bots/06-5.webp +0 -0
  515. torre/ui/art/bots/06-7.webp +0 -0
  516. torre/ui/art/bots/06-8.webp +0 -0
  517. torre/ui/art/bots/07-1.webp +0 -0
  518. torre/ui/art/bots/07-2.webp +0 -0
  519. torre/ui/art/bots/07-3.webp +0 -0
  520. torre/ui/art/bots/07-4.webp +0 -0
  521. torre/ui/art/bots/07-5.webp +0 -0
  522. torre/ui/art/bots/07-6.webp +0 -0
  523. torre/ui/art/bots/07-7.webp +0 -0
  524. torre/ui/art/bots/07-8.webp +0 -0
  525. torre/ui/art/bots/08-1.webp +0 -0
  526. torre/ui/art/bots/08-2.webp +0 -0
  527. torre/ui/art/bots/08-3.webp +0 -0
  528. torre/ui/art/bots/08-4.webp +0 -0
  529. torre/ui/art/bots/08-5.webp +0 -0
  530. torre/ui/art/bots/08-6.webp +0 -0
  531. torre/ui/art/bots/08-7.webp +0 -0
  532. torre/ui/art/bots/08-8.webp +0 -0
  533. torre/ui/art/bots/10-1.webp +0 -0
  534. torre/ui/art/bots/10-2.webp +0 -0
  535. torre/ui/art/bots/10-3.webp +0 -0
  536. torre/ui/art/bots/10-4.webp +0 -0
  537. torre/ui/art/bots/10-6.webp +0 -0
  538. torre/ui/art/bots/10-7.webp +0 -0
  539. torre/ui/art/bots/10-8.webp +0 -0
  540. torre/ui/art/bots/11-1.webp +0 -0
  541. torre/ui/art/bots/11-2.webp +0 -0
  542. torre/ui/art/bots/11-3.webp +0 -0
  543. torre/ui/art/bots/11-4.webp +0 -0
  544. torre/ui/art/bots/11-5.webp +0 -0
  545. torre/ui/art/bots/11-6.webp +0 -0
  546. torre/ui/art/bots/11-7.webp +0 -0
  547. torre/ui/art/bots/11-8.webp +0 -0
  548. torre/ui/art/bots/12-1.webp +0 -0
  549. torre/ui/art/bots/12-2.webp +0 -0
  550. torre/ui/art/bots/12-3.webp +0 -0
  551. torre/ui/art/bots/12-4.webp +0 -0
  552. torre/ui/art/bots/12-7.webp +0 -0
  553. torre/ui/art/bots/12-8.webp +0 -0
  554. torre/ui/art/bots/13-2.webp +0 -0
  555. torre/ui/art/bots/13-3.webp +0 -0
  556. torre/ui/art/bots/13-4.webp +0 -0
  557. torre/ui/art/bots/13-5.webp +0 -0
  558. torre/ui/art/bots/13-6.webp +0 -0
  559. torre/ui/art/bots/13-7.webp +0 -0
  560. torre/ui/art/bots/13-8.webp +0 -0
  561. torre/ui/art/bots/14-1.webp +0 -0
  562. torre/ui/art/bots/14-2.webp +0 -0
  563. torre/ui/art/bots/14-3.webp +0 -0
  564. torre/ui/art/bots/14-4.webp +0 -0
  565. torre/ui/art/bots/14-6.webp +0 -0
  566. torre/ui/art/bots/14-7.webp +0 -0
  567. torre/ui/art/bots/14-8.webp +0 -0
  568. torre/ui/art/bots/15-1.webp +0 -0
  569. torre/ui/art/bots/15-2.webp +0 -0
  570. torre/ui/art/bots/15-3.webp +0 -0
  571. torre/ui/art/bots/15-4.webp +0 -0
  572. torre/ui/art/bots/15-5.webp +0 -0
  573. torre/ui/art/bots/15-6.webp +0 -0
  574. torre/ui/art/bots/15-7.webp +0 -0
  575. torre/ui/art/bots/15-8.webp +0 -0
  576. torre/ui/art/bots/16-1.webp +0 -0
  577. torre/ui/art/bots/16-2.webp +0 -0
  578. torre/ui/art/bots/16-3.webp +0 -0
  579. torre/ui/art/bots/16-4.webp +0 -0
  580. torre/ui/art/bots/16-5.webp +0 -0
  581. torre/ui/art/bots/16-6.webp +0 -0
  582. torre/ui/art/bots/16-7.webp +0 -0
  583. torre/ui/art/bots/16-8.webp +0 -0
  584. torre/ui/art/bots/17-1.webp +0 -0
  585. torre/ui/art/bots/17-2.webp +0 -0
  586. torre/ui/art/bots/17-3.webp +0 -0
  587. torre/ui/art/bots/17-4.webp +0 -0
  588. torre/ui/art/bots/17-5.webp +0 -0
  589. torre/ui/art/bots/17-6.webp +0 -0
  590. torre/ui/art/bots/17-7.webp +0 -0
  591. torre/ui/art/bots/17-8.webp +0 -0
  592. torre/ui/art/bots/18-1.webp +0 -0
  593. torre/ui/art/bots/18-2.webp +0 -0
  594. torre/ui/art/bots/18-3.webp +0 -0
  595. torre/ui/art/bots/18-4.webp +0 -0
  596. torre/ui/art/bots/18-5.webp +0 -0
  597. torre/ui/art/bots/18-6.webp +0 -0
  598. torre/ui/art/bots/18-7.webp +0 -0
  599. torre/ui/art/bots/18-8.webp +0 -0
  600. torre/ui/art/bots/albania-1.webp +0 -0
  601. torre/ui/art/bots/albania-2.webp +0 -0
  602. torre/ui/art/bots/albania-3.webp +0 -0
  603. torre/ui/art/bots/albania-4.webp +0 -0
  604. torre/ui/art/bots/albania-5.webp +0 -0
  605. torre/ui/art/bots/albania-6.webp +0 -0
  606. torre/ui/art/bots/albania-7.webp +0 -0
  607. torre/ui/art/bots/albania-8.webp +0 -0
  608. torre/ui/art/bots/arabia-1.webp +0 -0
  609. torre/ui/art/bots/arabia-2.webp +0 -0
  610. torre/ui/art/bots/arabia-3.webp +0 -0
  611. torre/ui/art/bots/arabia-4.webp +0 -0
  612. torre/ui/art/bots/arabia-5.webp +0 -0
  613. torre/ui/art/bots/arabia-6.webp +0 -0
  614. torre/ui/art/bots/arabia-7.webp +0 -0
  615. torre/ui/art/bots/arabia-8.webp +0 -0
  616. torre/ui/art/bots/argentina-1.webp +0 -0
  617. torre/ui/art/bots/argentina-2.webp +0 -0
  618. torre/ui/art/bots/argentina-3.webp +0 -0
  619. torre/ui/art/bots/argentina-4.webp +0 -0
  620. torre/ui/art/bots/argentina-5.webp +0 -0
  621. torre/ui/art/bots/argentina-6.webp +0 -0
  622. torre/ui/art/bots/argentina-7.webp +0 -0
  623. torre/ui/art/bots/argentina-8.webp +0 -0
  624. torre/ui/art/bots/armenia-1.webp +0 -0
  625. torre/ui/art/bots/armenia-2.webp +0 -0
  626. torre/ui/art/bots/armenia-3.webp +0 -0
  627. torre/ui/art/bots/armenia-4.webp +0 -0
  628. torre/ui/art/bots/armenia-5.webp +0 -0
  629. torre/ui/art/bots/armenia-6.webp +0 -0
  630. torre/ui/art/bots/armenia-7.webp +0 -0
  631. torre/ui/art/bots/armenia-8.webp +0 -0
  632. torre/ui/art/bots/brazil-1.webp +0 -0
  633. torre/ui/art/bots/brazil-2.webp +0 -0
  634. torre/ui/art/bots/brazil-3.webp +0 -0
  635. torre/ui/art/bots/brazil-4.webp +0 -0
  636. torre/ui/art/bots/brazil-5.webp +0 -0
  637. torre/ui/art/bots/brazil-6.webp +0 -0
  638. torre/ui/art/bots/brazil-7.webp +0 -0
  639. torre/ui/art/bots/brazil-8.webp +0 -0
  640. torre/ui/art/bots/canada-1.webp +0 -0
  641. torre/ui/art/bots/canada-2.webp +0 -0
  642. torre/ui/art/bots/canada-3.webp +0 -0
  643. torre/ui/art/bots/canada-4.webp +0 -0
  644. torre/ui/art/bots/canada-5.webp +0 -0
  645. torre/ui/art/bots/canada-6.webp +0 -0
  646. torre/ui/art/bots/canada-7.webp +0 -0
  647. torre/ui/art/bots/canada-8.webp +0 -0
  648. torre/ui/art/bots/chile-1.webp +0 -0
  649. torre/ui/art/bots/chile-2.webp +0 -0
  650. torre/ui/art/bots/chile-3.webp +0 -0
  651. torre/ui/art/bots/chile-4.webp +0 -0
  652. torre/ui/art/bots/chile-5.webp +0 -0
  653. torre/ui/art/bots/chile-6.webp +0 -0
  654. torre/ui/art/bots/chile-7.webp +0 -0
  655. torre/ui/art/bots/chile-8.webp +0 -0
  656. torre/ui/art/bots/china-1.webp +0 -0
  657. torre/ui/art/bots/china-2.webp +0 -0
  658. torre/ui/art/bots/china-3.webp +0 -0
  659. torre/ui/art/bots/china-4.webp +0 -0
  660. torre/ui/art/bots/china-5.webp +0 -0
  661. torre/ui/art/bots/china-6.webp +0 -0
  662. torre/ui/art/bots/china-7.webp +0 -0
  663. torre/ui/art/bots/china-8.webp +0 -0
  664. torre/ui/art/bots/colombia-1.webp +0 -0
  665. torre/ui/art/bots/colombia-2.webp +0 -0
  666. torre/ui/art/bots/colombia-3.webp +0 -0
  667. torre/ui/art/bots/colombia-4.webp +0 -0
  668. torre/ui/art/bots/colombia-5.webp +0 -0
  669. torre/ui/art/bots/colombia-6.webp +0 -0
  670. torre/ui/art/bots/colombia-7.webp +0 -0
  671. torre/ui/art/bots/colombia-8.webp +0 -0
  672. torre/ui/art/bots/diaspora-albania.webp +0 -0
  673. torre/ui/art/bots/diaspora-arabia.webp +0 -0
  674. torre/ui/art/bots/diaspora-argentina.webp +0 -0
  675. torre/ui/art/bots/diaspora-armenia.webp +0 -0
  676. torre/ui/art/bots/diaspora-brazil.webp +0 -0
  677. torre/ui/art/bots/diaspora-canada.webp +0 -0
  678. torre/ui/art/bots/diaspora-chile.webp +0 -0
  679. torre/ui/art/bots/diaspora-china.webp +0 -0
  680. torre/ui/art/bots/diaspora-colombia.webp +0 -0
  681. torre/ui/art/bots/diaspora-el-salvador.webp +0 -0
  682. torre/ui/art/bots/diaspora-france.webp +0 -0
  683. torre/ui/art/bots/diaspora-germany.webp +0 -0
  684. torre/ui/art/bots/diaspora-hawaii.webp +0 -0
  685. torre/ui/art/bots/diaspora-hungary.webp +0 -0
  686. torre/ui/art/bots/diaspora-india.webp +0 -0
  687. torre/ui/art/bots/diaspora-italy.webp +0 -0
  688. torre/ui/art/bots/diaspora-japan.webp +0 -0
  689. torre/ui/art/bots/diaspora-korea.webp +0 -0
  690. torre/ui/art/bots/diaspora-mexico.webp +0 -0
  691. torre/ui/art/bots/diaspora-netherlands.webp +0 -0
  692. torre/ui/art/bots/diaspora-nordic.webp +0 -0
  693. torre/ui/art/bots/diaspora-panama.webp +0 -0
  694. torre/ui/art/bots/diaspora-peru.webp +0 -0
  695. torre/ui/art/bots/diaspora-philippines.webp +0 -0
  696. torre/ui/art/bots/diaspora-portugal.webp +0 -0
  697. torre/ui/art/bots/diaspora-russia.webp +0 -0
  698. torre/ui/art/bots/diaspora-serbia.webp +0 -0
  699. torre/ui/art/bots/diaspora-spain.webp +0 -0
  700. torre/ui/art/bots/diaspora-sweden.webp +0 -0
  701. torre/ui/art/bots/diaspora-turkey.webp +0 -0
  702. torre/ui/art/bots/diaspora-ukraine.webp +0 -0
  703. torre/ui/art/bots/diaspora-usa.webp +0 -0
  704. torre/ui/art/bots/el-salvador-1.webp +0 -0
  705. torre/ui/art/bots/el-salvador-2.webp +0 -0
  706. torre/ui/art/bots/el-salvador-3.webp +0 -0
  707. torre/ui/art/bots/el-salvador-4.webp +0 -0
  708. torre/ui/art/bots/el-salvador-5.webp +0 -0
  709. torre/ui/art/bots/el-salvador-6.webp +0 -0
  710. torre/ui/art/bots/el-salvador-7.webp +0 -0
  711. torre/ui/art/bots/el-salvador-8.webp +0 -0
  712. torre/ui/art/bots/france-1.webp +0 -0
  713. torre/ui/art/bots/france-2.webp +0 -0
  714. torre/ui/art/bots/france-3.webp +0 -0
  715. torre/ui/art/bots/france-4.webp +0 -0
  716. torre/ui/art/bots/france-5.webp +0 -0
  717. torre/ui/art/bots/france-6.webp +0 -0
  718. torre/ui/art/bots/france-7.webp +0 -0
  719. torre/ui/art/bots/france-8.webp +0 -0
  720. torre/ui/art/bots/germany-1.webp +0 -0
  721. torre/ui/art/bots/germany-2.webp +0 -0
  722. torre/ui/art/bots/germany-3.webp +0 -0
  723. torre/ui/art/bots/germany-4.webp +0 -0
  724. torre/ui/art/bots/germany-5.webp +0 -0
  725. torre/ui/art/bots/germany-6.webp +0 -0
  726. torre/ui/art/bots/germany-7.webp +0 -0
  727. torre/ui/art/bots/germany-8.webp +0 -0
  728. torre/ui/art/bots/gym-1.webp +0 -0
  729. torre/ui/art/bots/gym-2.webp +0 -0
  730. torre/ui/art/bots/gym-3.webp +0 -0
  731. torre/ui/art/bots/gym-4.webp +0 -0
  732. torre/ui/art/bots/gym-5.webp +0 -0
  733. torre/ui/art/bots/gym-6.webp +0 -0
  734. torre/ui/art/bots/gym-7.webp +0 -0
  735. torre/ui/art/bots/gym-8.webp +0 -0
  736. torre/ui/art/bots/hawaii-1.webp +0 -0
  737. torre/ui/art/bots/hawaii-2.webp +0 -0
  738. torre/ui/art/bots/hawaii-3.webp +0 -0
  739. torre/ui/art/bots/hawaii-4.webp +0 -0
  740. torre/ui/art/bots/hawaii-5.webp +0 -0
  741. torre/ui/art/bots/hawaii-6.webp +0 -0
  742. torre/ui/art/bots/hawaii-7.webp +0 -0
  743. torre/ui/art/bots/hawaii-8.webp +0 -0
  744. torre/ui/art/bots/hungary-1.webp +0 -0
  745. torre/ui/art/bots/hungary-2.webp +0 -0
  746. torre/ui/art/bots/hungary-3.webp +0 -0
  747. torre/ui/art/bots/hungary-4.webp +0 -0
  748. torre/ui/art/bots/hungary-5.webp +0 -0
  749. torre/ui/art/bots/hungary-6.webp +0 -0
  750. torre/ui/art/bots/hungary-7.webp +0 -0
  751. torre/ui/art/bots/hungary-8.webp +0 -0
  752. torre/ui/art/bots/india-1.webp +0 -0
  753. torre/ui/art/bots/india-2.webp +0 -0
  754. torre/ui/art/bots/india-3.webp +0 -0
  755. torre/ui/art/bots/india-4.webp +0 -0
  756. torre/ui/art/bots/india-5.webp +0 -0
  757. torre/ui/art/bots/india-6.webp +0 -0
  758. torre/ui/art/bots/india-7.webp +0 -0
  759. torre/ui/art/bots/india-8.webp +0 -0
  760. torre/ui/art/bots/italy-1.webp +0 -0
  761. torre/ui/art/bots/italy-2.webp +0 -0
  762. torre/ui/art/bots/italy-3.webp +0 -0
  763. torre/ui/art/bots/italy-4.webp +0 -0
  764. torre/ui/art/bots/italy-5.webp +0 -0
  765. torre/ui/art/bots/italy-6.webp +0 -0
  766. torre/ui/art/bots/italy-7.webp +0 -0
  767. torre/ui/art/bots/italy-8.webp +0 -0
  768. torre/ui/art/bots/japan-1.webp +0 -0
  769. torre/ui/art/bots/japan-2.webp +0 -0
  770. torre/ui/art/bots/japan-3.webp +0 -0
  771. torre/ui/art/bots/japan-4.webp +0 -0
  772. torre/ui/art/bots/japan-5.webp +0 -0
  773. torre/ui/art/bots/japan-6.webp +0 -0
  774. torre/ui/art/bots/japan-7.webp +0 -0
  775. torre/ui/art/bots/japan-8.webp +0 -0
  776. torre/ui/art/bots/kitchen-table-1.webp +0 -0
  777. torre/ui/art/bots/kitchen-table-2.webp +0 -0
  778. torre/ui/art/bots/kitchen-table-3.webp +0 -0
  779. torre/ui/art/bots/kitchen-table-4.webp +0 -0
  780. torre/ui/art/bots/kitchen-table-5.webp +0 -0
  781. torre/ui/art/bots/kitchen-table-6.webp +0 -0
  782. torre/ui/art/bots/kitchen-table-7.webp +0 -0
  783. torre/ui/art/bots/kitchen-table-8.webp +0 -0
  784. torre/ui/art/bots/korea-1.webp +0 -0
  785. torre/ui/art/bots/korea-2.webp +0 -0
  786. torre/ui/art/bots/korea-3.webp +0 -0
  787. torre/ui/art/bots/korea-4.webp +0 -0
  788. torre/ui/art/bots/korea-5.webp +0 -0
  789. torre/ui/art/bots/korea-6.webp +0 -0
  790. torre/ui/art/bots/korea-7.webp +0 -0
  791. torre/ui/art/bots/korea-8.webp +0 -0
  792. torre/ui/art/bots/makers-1.webp +0 -0
  793. torre/ui/art/bots/makers-2.webp +0 -0
  794. torre/ui/art/bots/makers-3.webp +0 -0
  795. torre/ui/art/bots/makers-4.webp +0 -0
  796. torre/ui/art/bots/makers-5.webp +0 -0
  797. torre/ui/art/bots/makers-6.webp +0 -0
  798. torre/ui/art/bots/makers-7.webp +0 -0
  799. torre/ui/art/bots/makers-8.webp +0 -0
  800. torre/ui/art/bots/mexico-1.webp +0 -0
  801. torre/ui/art/bots/mexico-2.webp +0 -0
  802. torre/ui/art/bots/mexico-3.webp +0 -0
  803. torre/ui/art/bots/mexico-4.webp +0 -0
  804. torre/ui/art/bots/mexico-5.webp +0 -0
  805. torre/ui/art/bots/mexico-6.webp +0 -0
  806. torre/ui/art/bots/mexico-7.webp +0 -0
  807. torre/ui/art/bots/mexico-8.webp +0 -0
  808. torre/ui/art/bots/netherlands-1.webp +0 -0
  809. torre/ui/art/bots/netherlands-2.webp +0 -0
  810. torre/ui/art/bots/netherlands-3.webp +0 -0
  811. torre/ui/art/bots/netherlands-4.webp +0 -0
  812. torre/ui/art/bots/netherlands-5.webp +0 -0
  813. torre/ui/art/bots/netherlands-6.webp +0 -0
  814. torre/ui/art/bots/netherlands-7.webp +0 -0
  815. torre/ui/art/bots/netherlands-8.webp +0 -0
  816. torre/ui/art/bots/night-owls-1.webp +0 -0
  817. torre/ui/art/bots/night-owls-2.webp +0 -0
  818. torre/ui/art/bots/night-owls-3.webp +0 -0
  819. torre/ui/art/bots/night-owls-4.webp +0 -0
  820. torre/ui/art/bots/night-owls-5.webp +0 -0
  821. torre/ui/art/bots/night-owls-6.webp +0 -0
  822. torre/ui/art/bots/night-owls-7.webp +0 -0
  823. torre/ui/art/bots/night-owls-8.webp +0 -0
  824. torre/ui/art/bots/nordic-1.webp +0 -0
  825. torre/ui/art/bots/nordic-2.webp +0 -0
  826. torre/ui/art/bots/nordic-3.webp +0 -0
  827. torre/ui/art/bots/nordic-4.webp +0 -0
  828. torre/ui/art/bots/nordic-5.webp +0 -0
  829. torre/ui/art/bots/nordic-6.webp +0 -0
  830. torre/ui/art/bots/nordic-7.webp +0 -0
  831. torre/ui/art/bots/nordic-8.webp +0 -0
  832. torre/ui/art/bots/panama-1.webp +0 -0
  833. torre/ui/art/bots/panama-2.webp +0 -0
  834. torre/ui/art/bots/panama-3.webp +0 -0
  835. torre/ui/art/bots/panama-4.webp +0 -0
  836. torre/ui/art/bots/panama-5.webp +0 -0
  837. torre/ui/art/bots/panama-6.webp +0 -0
  838. torre/ui/art/bots/panama-7.webp +0 -0
  839. torre/ui/art/bots/panama-8.webp +0 -0
  840. torre/ui/art/bots/peru-1.webp +0 -0
  841. torre/ui/art/bots/peru-2.webp +0 -0
  842. torre/ui/art/bots/peru-3.webp +0 -0
  843. torre/ui/art/bots/peru-4.webp +0 -0
  844. torre/ui/art/bots/peru-5.webp +0 -0
  845. torre/ui/art/bots/peru-6.webp +0 -0
  846. torre/ui/art/bots/peru-7.webp +0 -0
  847. torre/ui/art/bots/peru-8.webp +0 -0
  848. torre/ui/art/bots/philippines-1.webp +0 -0
  849. torre/ui/art/bots/philippines-2.webp +0 -0
  850. torre/ui/art/bots/philippines-3.webp +0 -0
  851. torre/ui/art/bots/philippines-4.webp +0 -0
  852. torre/ui/art/bots/philippines-5.webp +0 -0
  853. torre/ui/art/bots/philippines-6.webp +0 -0
  854. torre/ui/art/bots/philippines-7.webp +0 -0
  855. torre/ui/art/bots/philippines-8.webp +0 -0
  856. torre/ui/art/bots/russia-1.webp +0 -0
  857. torre/ui/art/bots/russia-2.webp +0 -0
  858. torre/ui/art/bots/russia-3.webp +0 -0
  859. torre/ui/art/bots/russia-4.webp +0 -0
  860. torre/ui/art/bots/russia-5.webp +0 -0
  861. torre/ui/art/bots/russia-6.webp +0 -0
  862. torre/ui/art/bots/russia-7.webp +0 -0
  863. torre/ui/art/bots/russia-8.webp +0 -0
  864. torre/ui/art/bots/science-lab-1.webp +0 -0
  865. torre/ui/art/bots/science-lab-2.webp +0 -0
  866. torre/ui/art/bots/science-lab-3.webp +0 -0
  867. torre/ui/art/bots/science-lab-4.webp +0 -0
  868. torre/ui/art/bots/science-lab-5.webp +0 -0
  869. torre/ui/art/bots/science-lab-6.webp +0 -0
  870. torre/ui/art/bots/science-lab-7.webp +0 -0
  871. torre/ui/art/bots/science-lab-8.webp +0 -0
  872. torre/ui/art/bots/sea-shore-1.webp +0 -0
  873. torre/ui/art/bots/sea-shore-2.webp +0 -0
  874. torre/ui/art/bots/sea-shore-3.webp +0 -0
  875. torre/ui/art/bots/sea-shore-4.webp +0 -0
  876. torre/ui/art/bots/sea-shore-5.webp +0 -0
  877. torre/ui/art/bots/sea-shore-6.webp +0 -0
  878. torre/ui/art/bots/sea-shore-7.webp +0 -0
  879. torre/ui/art/bots/sea-shore-8.webp +0 -0
  880. torre/ui/art/bots/seasonal/carnaval/01-1.webp +0 -0
  881. torre/ui/art/bots/seasonal/carnaval/01-2.webp +0 -0
  882. torre/ui/art/bots/seasonal/carnaval/01-6.webp +0 -0
  883. torre/ui/art/bots/seasonal/carnaval/13-2.webp +0 -0
  884. torre/ui/art/bots/seasonal/carnaval/14-7.webp +0 -0
  885. torre/ui/art/bots/seasonal/carnaval/15-4.webp +0 -0
  886. torre/ui/art/bots/seasonal/carnaval/15-7.webp +0 -0
  887. torre/ui/art/bots/seasonal/carnaval/18-1.webp +0 -0
  888. torre/ui/art/bots/seasonal/chess-day/08-1.webp +0 -0
  889. torre/ui/art/bots/seasonal/chess-day/08-6.webp +0 -0
  890. torre/ui/art/bots/seasonal/chess-day/10-6.webp +0 -0
  891. torre/ui/art/bots/seasonal/chess-day/12-2.webp +0 -0
  892. torre/ui/art/bots/seasonal/chess-day/15-3.webp +0 -0
  893. torre/ui/art/bots/seasonal/chess-day/18-3.webp +0 -0
  894. torre/ui/art/bots/seasonal/chess-day/18-7.webp +0 -0
  895. torre/ui/art/bots/seasonal/chess-day/18-8.webp +0 -0
  896. torre/ui/art/bots/seasonal/christmas/01-1-alt.webp +0 -0
  897. torre/ui/art/bots/seasonal/christmas/01-1.webp +0 -0
  898. torre/ui/art/bots/seasonal/christmas/01-2-alt.webp +0 -0
  899. torre/ui/art/bots/seasonal/christmas/01-2.webp +0 -0
  900. torre/ui/art/bots/seasonal/christmas/01-3.webp +0 -0
  901. torre/ui/art/bots/seasonal/christmas/01-4.webp +0 -0
  902. torre/ui/art/bots/seasonal/christmas/01-5.webp +0 -0
  903. torre/ui/art/bots/seasonal/christmas/01-6-alt.webp +0 -0
  904. torre/ui/art/bots/seasonal/christmas/01-6.webp +0 -0
  905. torre/ui/art/bots/seasonal/christmas/01-7.webp +0 -0
  906. torre/ui/art/bots/seasonal/christmas/04-1.webp +0 -0
  907. torre/ui/art/bots/seasonal/christmas/06-8.webp +0 -0
  908. torre/ui/art/bots/seasonal/christmas/07-6.webp +0 -0
  909. torre/ui/art/bots/seasonal/christmas/08-1.webp +0 -0
  910. torre/ui/art/bots/seasonal/christmas/08-6.webp +0 -0
  911. torre/ui/art/bots/seasonal/christmas/10-6.webp +0 -0
  912. torre/ui/art/bots/seasonal/christmas/10-8.webp +0 -0
  913. torre/ui/art/bots/seasonal/christmas/12-2.webp +0 -0
  914. torre/ui/art/bots/seasonal/christmas/13-2-alt.webp +0 -0
  915. torre/ui/art/bots/seasonal/christmas/13-2.webp +0 -0
  916. torre/ui/art/bots/seasonal/christmas/14-7-alt.webp +0 -0
  917. torre/ui/art/bots/seasonal/christmas/14-7.webp +0 -0
  918. torre/ui/art/bots/seasonal/christmas/15-3.webp +0 -0
  919. torre/ui/art/bots/seasonal/christmas/15-4-alt.webp +0 -0
  920. torre/ui/art/bots/seasonal/christmas/15-4.webp +0 -0
  921. torre/ui/art/bots/seasonal/christmas/15-7-alt.webp +0 -0
  922. torre/ui/art/bots/seasonal/christmas/15-7.webp +0 -0
  923. torre/ui/art/bots/seasonal/christmas/18-1-alt.webp +0 -0
  924. torre/ui/art/bots/seasonal/christmas/18-1.webp +0 -0
  925. torre/ui/art/bots/seasonal/christmas/18-3.webp +0 -0
  926. torre/ui/art/bots/seasonal/christmas/18-7.webp +0 -0
  927. torre/ui/art/bots/seasonal/christmas/18-8.webp +0 -0
  928. torre/ui/art/bots/seasonal/cruz-de-mayo/01-3.webp +0 -0
  929. torre/ui/art/bots/seasonal/cruz-de-mayo/01-4.webp +0 -0
  930. torre/ui/art/bots/seasonal/cruz-de-mayo/01-5.webp +0 -0
  931. torre/ui/art/bots/seasonal/cruz-de-mayo/01-7.webp +0 -0
  932. torre/ui/art/bots/seasonal/cruz-de-mayo/04-1.webp +0 -0
  933. torre/ui/art/bots/seasonal/cruz-de-mayo/06-8.webp +0 -0
  934. torre/ui/art/bots/seasonal/cruz-de-mayo/07-6.webp +0 -0
  935. torre/ui/art/bots/seasonal/cruz-de-mayo/10-8.webp +0 -0
  936. torre/ui/art/bots/seasonal/dia-de-la-juventud/08-1.webp +0 -0
  937. torre/ui/art/bots/seasonal/dia-de-la-juventud/08-6.webp +0 -0
  938. torre/ui/art/bots/seasonal/dia-de-la-juventud/10-6.webp +0 -0
  939. torre/ui/art/bots/seasonal/dia-de-la-juventud/12-2.webp +0 -0
  940. torre/ui/art/bots/seasonal/dia-de-la-juventud/15-3.webp +0 -0
  941. torre/ui/art/bots/seasonal/dia-de-la-juventud/18-3.webp +0 -0
  942. torre/ui/art/bots/seasonal/dia-de-la-juventud/18-7.webp +0 -0
  943. torre/ui/art/bots/seasonal/dia-de-la-juventud/18-8.webp +0 -0
  944. torre/ui/art/bots/seasonal/dia-de-muertos/01-3.webp +0 -0
  945. torre/ui/art/bots/seasonal/dia-de-muertos/01-4.webp +0 -0
  946. torre/ui/art/bots/seasonal/dia-de-muertos/01-5.webp +0 -0
  947. torre/ui/art/bots/seasonal/dia-de-muertos/01-7.webp +0 -0
  948. torre/ui/art/bots/seasonal/dia-de-muertos/04-1.webp +0 -0
  949. torre/ui/art/bots/seasonal/dia-de-muertos/06-8.webp +0 -0
  950. torre/ui/art/bots/seasonal/dia-de-muertos/07-6.webp +0 -0
  951. torre/ui/art/bots/seasonal/dia-de-muertos/10-8.webp +0 -0
  952. torre/ui/art/bots/seasonal/dia-del-maestro/01-1.webp +0 -0
  953. torre/ui/art/bots/seasonal/dia-del-maestro/01-2.webp +0 -0
  954. torre/ui/art/bots/seasonal/dia-del-maestro/01-6.webp +0 -0
  955. torre/ui/art/bots/seasonal/dia-del-maestro/08-1.webp +0 -0
  956. torre/ui/art/bots/seasonal/dia-del-maestro/08-6.webp +0 -0
  957. torre/ui/art/bots/seasonal/dia-del-maestro/10-6.webp +0 -0
  958. torre/ui/art/bots/seasonal/dia-del-maestro/12-2.webp +0 -0
  959. torre/ui/art/bots/seasonal/dia-del-maestro/13-2.webp +0 -0
  960. torre/ui/art/bots/seasonal/dia-del-maestro/14-7.webp +0 -0
  961. torre/ui/art/bots/seasonal/dia-del-maestro/15-3.webp +0 -0
  962. torre/ui/art/bots/seasonal/dia-del-maestro/15-4.webp +0 -0
  963. torre/ui/art/bots/seasonal/dia-del-maestro/15-7.webp +0 -0
  964. torre/ui/art/bots/seasonal/dia-del-maestro/18-1.webp +0 -0
  965. torre/ui/art/bots/seasonal/dia-del-maestro/18-3.webp +0 -0
  966. torre/ui/art/bots/seasonal/dia-del-maestro/18-7.webp +0 -0
  967. torre/ui/art/bots/seasonal/dia-del-maestro/18-8.webp +0 -0
  968. torre/ui/art/bots/seasonal/diablos-de-yare/01-1.webp +0 -0
  969. torre/ui/art/bots/seasonal/diablos-de-yare/01-2.webp +0 -0
  970. torre/ui/art/bots/seasonal/diablos-de-yare/01-6.webp +0 -0
  971. torre/ui/art/bots/seasonal/diablos-de-yare/13-2.webp +0 -0
  972. torre/ui/art/bots/seasonal/diablos-de-yare/14-7.webp +0 -0
  973. torre/ui/art/bots/seasonal/diablos-de-yare/15-4.webp +0 -0
  974. torre/ui/art/bots/seasonal/diablos-de-yare/15-7.webp +0 -0
  975. torre/ui/art/bots/seasonal/diablos-de-yare/18-1.webp +0 -0
  976. torre/ui/art/bots/seasonal/halloween/01-1-alt.webp +0 -0
  977. torre/ui/art/bots/seasonal/halloween/01-1.webp +0 -0
  978. torre/ui/art/bots/seasonal/halloween/01-2-alt.webp +0 -0
  979. torre/ui/art/bots/seasonal/halloween/01-2.webp +0 -0
  980. torre/ui/art/bots/seasonal/halloween/01-3.webp +0 -0
  981. torre/ui/art/bots/seasonal/halloween/01-4.webp +0 -0
  982. torre/ui/art/bots/seasonal/halloween/01-5.webp +0 -0
  983. torre/ui/art/bots/seasonal/halloween/01-6-alt.webp +0 -0
  984. torre/ui/art/bots/seasonal/halloween/01-6.webp +0 -0
  985. torre/ui/art/bots/seasonal/halloween/01-7.webp +0 -0
  986. torre/ui/art/bots/seasonal/halloween/04-1.webp +0 -0
  987. torre/ui/art/bots/seasonal/halloween/06-8.webp +0 -0
  988. torre/ui/art/bots/seasonal/halloween/07-6.webp +0 -0
  989. torre/ui/art/bots/seasonal/halloween/08-1.webp +0 -0
  990. torre/ui/art/bots/seasonal/halloween/08-6.webp +0 -0
  991. torre/ui/art/bots/seasonal/halloween/10-6.webp +0 -0
  992. torre/ui/art/bots/seasonal/halloween/10-8.webp +0 -0
  993. torre/ui/art/bots/seasonal/halloween/12-2.webp +0 -0
  994. torre/ui/art/bots/seasonal/halloween/13-2-alt.webp +0 -0
  995. torre/ui/art/bots/seasonal/halloween/13-2.webp +0 -0
  996. torre/ui/art/bots/seasonal/halloween/14-7-alt.webp +0 -0
  997. torre/ui/art/bots/seasonal/halloween/14-7.webp +0 -0
  998. torre/ui/art/bots/seasonal/halloween/15-3.webp +0 -0
  999. torre/ui/art/bots/seasonal/halloween/15-4-alt.webp +0 -0
  1000. torre/ui/art/bots/seasonal/halloween/15-4.webp +0 -0
  1001. torre/ui/art/bots/seasonal/halloween/15-7-alt.webp +0 -0
  1002. torre/ui/art/bots/seasonal/halloween/15-7.webp +0 -0
  1003. torre/ui/art/bots/seasonal/halloween/18-1-alt.webp +0 -0
  1004. torre/ui/art/bots/seasonal/halloween/18-1.webp +0 -0
  1005. torre/ui/art/bots/seasonal/halloween/18-3.webp +0 -0
  1006. torre/ui/art/bots/seasonal/halloween/18-7.webp +0 -0
  1007. torre/ui/art/bots/seasonal/halloween/18-8.webp +0 -0
  1008. torre/ui/art/bots/seasonal/independencia/01-1.webp +0 -0
  1009. torre/ui/art/bots/seasonal/independencia/01-2.webp +0 -0
  1010. torre/ui/art/bots/seasonal/independencia/01-6.webp +0 -0
  1011. torre/ui/art/bots/seasonal/independencia/13-2.webp +0 -0
  1012. torre/ui/art/bots/seasonal/independencia/14-7.webp +0 -0
  1013. torre/ui/art/bots/seasonal/independencia/15-4.webp +0 -0
  1014. torre/ui/art/bots/seasonal/independencia/15-7.webp +0 -0
  1015. torre/ui/art/bots/seasonal/independencia/18-1.webp +0 -0
  1016. torre/ui/art/bots/seasonal/leyendas/08-1.webp +0 -0
  1017. torre/ui/art/bots/seasonal/leyendas/08-6.webp +0 -0
  1018. torre/ui/art/bots/seasonal/leyendas/10-6.webp +0 -0
  1019. torre/ui/art/bots/seasonal/leyendas/12-2.webp +0 -0
  1020. torre/ui/art/bots/seasonal/leyendas/15-3.webp +0 -0
  1021. torre/ui/art/bots/seasonal/leyendas/18-3.webp +0 -0
  1022. torre/ui/art/bots/seasonal/leyendas/18-7.webp +0 -0
  1023. torre/ui/art/bots/seasonal/leyendas/18-8.webp +0 -0
  1024. torre/ui/art/bots/seasonal/lunar-new-year/01-3.webp +0 -0
  1025. torre/ui/art/bots/seasonal/lunar-new-year/01-4.webp +0 -0
  1026. torre/ui/art/bots/seasonal/lunar-new-year/01-5.webp +0 -0
  1027. torre/ui/art/bots/seasonal/lunar-new-year/01-7.webp +0 -0
  1028. torre/ui/art/bots/seasonal/lunar-new-year/04-1.webp +0 -0
  1029. torre/ui/art/bots/seasonal/lunar-new-year/06-8.webp +0 -0
  1030. torre/ui/art/bots/seasonal/lunar-new-year/07-6.webp +0 -0
  1031. torre/ui/art/bots/seasonal/lunar-new-year/10-8.webp +0 -0
  1032. torre/ui/art/bots/seasonal/new-year/01-1.webp +0 -0
  1033. torre/ui/art/bots/seasonal/new-year/01-2.webp +0 -0
  1034. torre/ui/art/bots/seasonal/new-year/01-6.webp +0 -0
  1035. torre/ui/art/bots/seasonal/new-year/13-2.webp +0 -0
  1036. torre/ui/art/bots/seasonal/new-year/14-7.webp +0 -0
  1037. torre/ui/art/bots/seasonal/new-year/15-4.webp +0 -0
  1038. torre/ui/art/bots/seasonal/new-year/15-7.webp +0 -0
  1039. torre/ui/art/bots/seasonal/new-year/18-1.webp +0 -0
  1040. torre/ui/art/bots/seasonal/semana-santa/01-3.webp +0 -0
  1041. torre/ui/art/bots/seasonal/semana-santa/01-4.webp +0 -0
  1042. torre/ui/art/bots/seasonal/semana-santa/01-5.webp +0 -0
  1043. torre/ui/art/bots/seasonal/semana-santa/01-7.webp +0 -0
  1044. torre/ui/art/bots/seasonal/semana-santa/04-1.webp +0 -0
  1045. torre/ui/art/bots/seasonal/semana-santa/06-8.webp +0 -0
  1046. torre/ui/art/bots/seasonal/semana-santa/07-6.webp +0 -0
  1047. torre/ui/art/bots/seasonal/semana-santa/10-8.webp +0 -0
  1048. torre/ui/art/bots/seasonal/spring/01-3.webp +0 -0
  1049. torre/ui/art/bots/seasonal/spring/01-4.webp +0 -0
  1050. torre/ui/art/bots/seasonal/spring/01-5.webp +0 -0
  1051. torre/ui/art/bots/seasonal/spring/01-7.webp +0 -0
  1052. torre/ui/art/bots/seasonal/spring/04-1.webp +0 -0
  1053. torre/ui/art/bots/seasonal/spring/06-8.webp +0 -0
  1054. torre/ui/art/bots/seasonal/spring/07-6.webp +0 -0
  1055. torre/ui/art/bots/seasonal/spring/10-8.webp +0 -0
  1056. torre/ui/art/bots/seasonal/st-patricks/08-1.webp +0 -0
  1057. torre/ui/art/bots/seasonal/st-patricks/08-6.webp +0 -0
  1058. torre/ui/art/bots/seasonal/st-patricks/10-6.webp +0 -0
  1059. torre/ui/art/bots/seasonal/st-patricks/12-2.webp +0 -0
  1060. torre/ui/art/bots/seasonal/st-patricks/15-3.webp +0 -0
  1061. torre/ui/art/bots/seasonal/st-patricks/18-3.webp +0 -0
  1062. torre/ui/art/bots/seasonal/st-patricks/18-7.webp +0 -0
  1063. torre/ui/art/bots/seasonal/st-patricks/18-8.webp +0 -0
  1064. torre/ui/art/bots/seasonal/summer/08-1.webp +0 -0
  1065. torre/ui/art/bots/seasonal/summer/08-6.webp +0 -0
  1066. torre/ui/art/bots/seasonal/summer/10-6.webp +0 -0
  1067. torre/ui/art/bots/seasonal/summer/12-2.webp +0 -0
  1068. torre/ui/art/bots/seasonal/summer/15-3.webp +0 -0
  1069. torre/ui/art/bots/seasonal/summer/18-3.webp +0 -0
  1070. torre/ui/art/bots/seasonal/summer/18-7.webp +0 -0
  1071. torre/ui/art/bots/seasonal/summer/18-8.webp +0 -0
  1072. torre/ui/art/bots/seasonal/thanksgiving/01-3.webp +0 -0
  1073. torre/ui/art/bots/seasonal/thanksgiving/01-4.webp +0 -0
  1074. torre/ui/art/bots/seasonal/thanksgiving/01-5.webp +0 -0
  1075. torre/ui/art/bots/seasonal/thanksgiving/01-7.webp +0 -0
  1076. torre/ui/art/bots/seasonal/thanksgiving/04-1.webp +0 -0
  1077. torre/ui/art/bots/seasonal/thanksgiving/06-8.webp +0 -0
  1078. torre/ui/art/bots/seasonal/thanksgiving/07-6.webp +0 -0
  1079. torre/ui/art/bots/seasonal/thanksgiving/10-8.webp +0 -0
  1080. torre/ui/art/bots/seasonal/valentines/08-1.webp +0 -0
  1081. torre/ui/art/bots/seasonal/valentines/08-6.webp +0 -0
  1082. torre/ui/art/bots/seasonal/valentines/10-6.webp +0 -0
  1083. torre/ui/art/bots/seasonal/valentines/12-2.webp +0 -0
  1084. torre/ui/art/bots/seasonal/valentines/15-3.webp +0 -0
  1085. torre/ui/art/bots/seasonal/valentines/18-3.webp +0 -0
  1086. torre/ui/art/bots/seasonal/valentines/18-7.webp +0 -0
  1087. torre/ui/art/bots/seasonal/valentines/18-8.webp +0 -0
  1088. torre/ui/art/bots/serbia-1.webp +0 -0
  1089. torre/ui/art/bots/serbia-2.webp +0 -0
  1090. torre/ui/art/bots/serbia-3.webp +0 -0
  1091. torre/ui/art/bots/serbia-4.webp +0 -0
  1092. torre/ui/art/bots/serbia-5.webp +0 -0
  1093. torre/ui/art/bots/serbia-6.webp +0 -0
  1094. torre/ui/art/bots/serbia-7.webp +0 -0
  1095. torre/ui/art/bots/serbia-8.webp +0 -0
  1096. torre/ui/art/bots/spain-1.webp +0 -0
  1097. torre/ui/art/bots/spain-2.webp +0 -0
  1098. torre/ui/art/bots/spain-3.webp +0 -0
  1099. torre/ui/art/bots/spain-4.webp +0 -0
  1100. torre/ui/art/bots/spain-5.webp +0 -0
  1101. torre/ui/art/bots/spain-6.webp +0 -0
  1102. torre/ui/art/bots/spain-7.webp +0 -0
  1103. torre/ui/art/bots/spain-8.webp +0 -0
  1104. torre/ui/art/bots/stage-1.webp +0 -0
  1105. torre/ui/art/bots/stage-2.webp +0 -0
  1106. torre/ui/art/bots/stage-3.webp +0 -0
  1107. torre/ui/art/bots/stage-4.webp +0 -0
  1108. torre/ui/art/bots/stage-5.webp +0 -0
  1109. torre/ui/art/bots/stage-6.webp +0 -0
  1110. torre/ui/art/bots/stage-7.webp +0 -0
  1111. torre/ui/art/bots/stage-8.webp +0 -0
  1112. torre/ui/art/bots/sweden-1.webp +0 -0
  1113. torre/ui/art/bots/sweden-2.webp +0 -0
  1114. torre/ui/art/bots/sweden-3.webp +0 -0
  1115. torre/ui/art/bots/sweden-4.webp +0 -0
  1116. torre/ui/art/bots/sweden-5.webp +0 -0
  1117. torre/ui/art/bots/sweden-6.webp +0 -0
  1118. torre/ui/art/bots/sweden-7.webp +0 -0
  1119. torre/ui/art/bots/sweden-8.webp +0 -0
  1120. torre/ui/art/bots/turkey-1.webp +0 -0
  1121. torre/ui/art/bots/turkey-2.webp +0 -0
  1122. torre/ui/art/bots/turkey-3.webp +0 -0
  1123. torre/ui/art/bots/turkey-4.webp +0 -0
  1124. torre/ui/art/bots/turkey-5.webp +0 -0
  1125. torre/ui/art/bots/turkey-6.webp +0 -0
  1126. torre/ui/art/bots/turkey-7.webp +0 -0
  1127. torre/ui/art/bots/turkey-8.webp +0 -0
  1128. torre/ui/art/bots/ukraine-1.webp +0 -0
  1129. torre/ui/art/bots/ukraine-2.webp +0 -0
  1130. torre/ui/art/bots/ukraine-3.webp +0 -0
  1131. torre/ui/art/bots/ukraine-4.webp +0 -0
  1132. torre/ui/art/bots/ukraine-5.webp +0 -0
  1133. torre/ui/art/bots/ukraine-6.webp +0 -0
  1134. torre/ui/art/bots/ukraine-7.webp +0 -0
  1135. torre/ui/art/bots/ukraine-8.webp +0 -0
  1136. torre/ui/art/bots/usa-1.webp +0 -0
  1137. torre/ui/art/bots/usa-2.webp +0 -0
  1138. torre/ui/art/bots/usa-3.webp +0 -0
  1139. torre/ui/art/bots/usa-4.webp +0 -0
  1140. torre/ui/art/bots/usa-5.webp +0 -0
  1141. torre/ui/art/bots/usa-6.webp +0 -0
  1142. torre/ui/art/bots/usa-7.webp +0 -0
  1143. torre/ui/art/bots/usa-8.webp +0 -0
  1144. torre/ui/art/bots/venezuela-1-1.webp +0 -0
  1145. torre/ui/art/bots/venezuela-1-2.webp +0 -0
  1146. torre/ui/art/bots/venezuela-1-3.webp +0 -0
  1147. torre/ui/art/bots/venezuela-1-4.webp +0 -0
  1148. torre/ui/art/bots/venezuela-1-5.webp +0 -0
  1149. torre/ui/art/bots/venezuela-1-6.webp +0 -0
  1150. torre/ui/art/bots/venezuela-1-7.webp +0 -0
  1151. torre/ui/art/bots/venezuela-1-8.webp +0 -0
  1152. torre/ui/art/bots/venezuela-2-1.webp +0 -0
  1153. torre/ui/art/bots/venezuela-2-2.webp +0 -0
  1154. torre/ui/art/bots/venezuela-2-3.webp +0 -0
  1155. torre/ui/art/bots/venezuela-2-4.webp +0 -0
  1156. torre/ui/art/bots/venezuela-2-5.webp +0 -0
  1157. torre/ui/art/bots/venezuela-2-6.webp +0 -0
  1158. torre/ui/art/bots/venezuela-2-7.webp +0 -0
  1159. torre/ui/art/bots/venezuela-2-8.webp +0 -0
  1160. torre/ui/art/engines/leela.webp +0 -0
  1161. torre/ui/art/engines/maia.webp +0 -0
  1162. torre/ui/art/engines/random.webp +0 -0
  1163. torre/ui/art/engines/sf11.webp +0 -0
  1164. torre/ui/art/engines/sf18.webp +0 -0
  1165. torre/ui/art/grades/best.webp +0 -0
  1166. torre/ui/art/grades/blunder.webp +0 -0
  1167. torre/ui/art/grades/brilliant.webp +0 -0
  1168. torre/ui/art/grades/good.webp +0 -0
  1169. torre/ui/art/grades/icon/best.webp +0 -0
  1170. torre/ui/art/grades/icon/blunder.webp +0 -0
  1171. torre/ui/art/grades/icon/book.webp +0 -0
  1172. torre/ui/art/grades/icon/brilliant.webp +0 -0
  1173. torre/ui/art/grades/icon/good.webp +0 -0
  1174. torre/ui/art/grades/icon/great.webp +0 -0
  1175. torre/ui/art/grades/icon/inaccuracy.webp +0 -0
  1176. torre/ui/art/grades/icon/mistake.webp +0 -0
  1177. torre/ui/art/grades/inaccuracy.webp +0 -0
  1178. torre/ui/art/grades/mistake.webp +0 -0
  1179. torre/ui/art/history/alekhine.webp +0 -0
  1180. torre/ui/art/history/anand.webp +0 -0
  1181. torre/ui/art/history/botvinnik.webp +0 -0
  1182. torre/ui/art/history/capablanca.webp +0 -0
  1183. torre/ui/art/history/carlsen.webp +0 -0
  1184. torre/ui/art/history/engine-era.webp +0 -0
  1185. torre/ui/art/history/evergreen-game.webp +0 -0
  1186. torre/ui/art/history/fischer.webp +0 -0
  1187. torre/ui/art/history/game-of-the-century.webp +0 -0
  1188. torre/ui/art/history/hypermodern.webp +0 -0
  1189. torre/ui/art/history/immortal-game.webp +0 -0
  1190. torre/ui/art/history/karpov.webp +0 -0
  1191. torre/ui/art/history/kasparov.webp +0 -0
  1192. torre/ui/art/history/kramnik.webp +0 -0
  1193. torre/ui/art/history/lasker.webp +0 -0
  1194. torre/ui/art/history/morphy.webp +0 -0
  1195. torre/ui/art/history/petrosian.webp +0 -0
  1196. torre/ui/art/history/polgar.webp +0 -0
  1197. torre/ui/art/history/romantic-era.webp +0 -0
  1198. torre/ui/art/history/soviet-school.webp +0 -0
  1199. torre/ui/art/history/spassky.webp +0 -0
  1200. torre/ui/art/history/steinitz.webp +0 -0
  1201. torre/ui/art/history/tal.webp +0 -0
  1202. torre/ui/art/history/the-turk.webp +0 -0
  1203. torre/ui/art/home/balloon.webp +0 -0
  1204. torre/ui/art/home/bishop-telescope.webp +0 -0
  1205. torre/ui/art/home/bots.webp +0 -0
  1206. torre/ui/art/home/break.webp +0 -0
  1207. torre/ui/art/home/butterflies.webp +0 -0
  1208. torre/ui/art/home/campfire.webp +0 -0
  1209. torre/ui/art/home/cloud-long.webp +0 -0
  1210. torre/ui/art/home/cloud-puff.webp +0 -0
  1211. torre/ui/art/home/islet-tree.webp +0 -0
  1212. torre/ui/art/home/islet-waterfall.webp +0 -0
  1213. torre/ui/art/home/journey.webp +0 -0
  1214. torre/ui/art/home/king-bush.webp +0 -0
  1215. torre/ui/art/home/knight-sneak.webp +0 -0
  1216. torre/ui/art/home/leapfrog.webp +0 -0
  1217. torre/ui/art/home/leaves.webp +0 -0
  1218. torre/ui/art/home/moon.webp +0 -0
  1219. torre/ui/art/home/paper-plane.webp +0 -0
  1220. torre/ui/art/home/pawn-cloud.webp +0 -0
  1221. torre/ui/art/home/picnic.webp +0 -0
  1222. torre/ui/art/home/puzzles.webp +0 -0
  1223. torre/ui/art/home/queen-reading.webp +0 -0
  1224. torre/ui/art/home/robot.webp +0 -0
  1225. torre/ui/art/home/rook-nap.webp +0 -0
  1226. torre/ui/art/home/sun.webp +0 -0
  1227. torre/ui/art/home/train.webp +0 -0
  1228. torre/ui/art/home/tumbling.webp +0 -0
  1229. torre/ui/art/icons/hint.png +0 -0
  1230. torre/ui/art/icons/resign.png +0 -0
  1231. torre/ui/art/legends/Alekhine.webp +0 -0
  1232. torre/ui/art/legends/Anand.webp +0 -0
  1233. torre/ui/art/legends/Anderssen.webp +0 -0
  1234. torre/ui/art/legends/Aronian.webp +0 -0
  1235. torre/ui/art/legends/Botvinnik.webp +0 -0
  1236. torre/ui/art/legends/Bronstein.webp +0 -0
  1237. torre/ui/art/legends/Capablanca.webp +0 -0
  1238. torre/ui/art/legends/Carlsen.webp +0 -0
  1239. torre/ui/art/legends/Caruana.webp +0 -0
  1240. torre/ui/art/legends/Chiburdanidze.webp +0 -0
  1241. torre/ui/art/legends/Chigorin.webp +0 -0
  1242. torre/ui/art/legends/DeLaBourdonnais.webp +0 -0
  1243. torre/ui/art/legends/Ding.webp +0 -0
  1244. torre/ui/art/legends/Euwe.webp +0 -0
  1245. torre/ui/art/legends/Firouzja.webp +0 -0
  1246. torre/ui/art/legends/Fischer.webp +0 -0
  1247. torre/ui/art/legends/Gaprindashvili.webp +0 -0
  1248. torre/ui/art/legends/Gukesh.webp +0 -0
  1249. torre/ui/art/legends/Hou.webp +0 -0
  1250. torre/ui/art/legends/JuWenjun.webp +0 -0
  1251. torre/ui/art/legends/Karpov.webp +0 -0
  1252. torre/ui/art/legends/Kasparov.webp +0 -0
  1253. torre/ui/art/legends/Keres.webp +0 -0
  1254. torre/ui/art/legends/Korchnoi.webp +0 -0
  1255. torre/ui/art/legends/Kramnik.webp +0 -0
  1256. torre/ui/art/legends/Larsen.webp +0 -0
  1257. torre/ui/art/legends/Lasker.webp +0 -0
  1258. torre/ui/art/legends/Marshall.webp +0 -0
  1259. torre/ui/art/legends/Menchik.webp +0 -0
  1260. torre/ui/art/legends/Morphy.webp +0 -0
  1261. torre/ui/art/legends/Najdorf.webp +0 -0
  1262. torre/ui/art/legends/Nakamura.webp +0 -0
  1263. torre/ui/art/legends/Nepomniachtchi.webp +0 -0
  1264. torre/ui/art/legends/Nimzowitsch.webp +0 -0
  1265. torre/ui/art/legends/Petrosian.webp +0 -0
  1266. torre/ui/art/legends/Philidor.webp +0 -0
  1267. torre/ui/art/legends/Pillsbury.webp +0 -0
  1268. torre/ui/art/legends/PolgarJ.webp +0 -0
  1269. torre/ui/art/legends/PolgarS.webp +0 -0
  1270. torre/ui/art/legends/Reti.webp +0 -0
  1271. torre/ui/art/legends/Rubinstein.webp +0 -0
  1272. torre/ui/art/legends/Smyslov.webp +0 -0
  1273. torre/ui/art/legends/So.webp +0 -0
  1274. torre/ui/art/legends/Spassky.webp +0 -0
  1275. torre/ui/art/legends/Steinitz.webp +0 -0
  1276. torre/ui/art/legends/Tal.webp +0 -0
  1277. torre/ui/art/legends/Tartakower.webp +0 -0
  1278. torre/ui/art/legends/Topalov.webp +0 -0
  1279. torre/ui/art/legends/era-cold-war.webp +0 -0
  1280. torre/ui/art/legends/era-golden.webp +0 -0
  1281. torre/ui/art/legends/era-modern.webp +0 -0
  1282. torre/ui/art/legends/era-romantic.webp +0 -0
  1283. torre/ui/art/legends/hall-banner.webp +0 -0
  1284. torre/ui/art/legends/hall-cloud.webp +0 -0
  1285. torre/ui/art/legends/hall-pedestal.webp +0 -0
  1286. torre/ui/art/legends/hall-swords.webp +0 -0
  1287. torre/ui/art/legends/hall-wreath.webp +0 -0
  1288. torre/ui/art/logo/app-icon-192.png +0 -0
  1289. torre/ui/art/logo/app-icon-32.png +0 -0
  1290. torre/ui/art/logo/app-icon-512.png +0 -0
  1291. torre/ui/art/logo/app-icon-64.png +0 -0
  1292. torre/ui/art/logo/mark.png +0 -0
  1293. torre/ui/art/mascot/alarm.webp +0 -0
  1294. torre/ui/art/mascot/bored.webp +0 -0
  1295. torre/ui/art/mascot/calculating.webp +0 -0
  1296. torre/ui/art/mascot/check.webp +0 -0
  1297. torre/ui/art/mascot/cheer.webp +0 -0
  1298. torre/ui/art/mascot/clap.webp +0 -0
  1299. torre/ui/art/mascot/confetti.webp +0 -0
  1300. torre/ui/art/mascot/confused.webp +0 -0
  1301. torre/ui/art/mascot/content.webp +0 -0
  1302. torre/ui/art/mascot/cursor/body-arms-up.webp +0 -0
  1303. torre/ui/art/mascot/cursor/body-crossed.webp +0 -0
  1304. torre/ui/art/mascot/cursor/body-hips.webp +0 -0
  1305. torre/ui/art/mascot/cursor/body-reach.webp +0 -0
  1306. torre/ui/art/mascot/cursor/body.webp +0 -0
  1307. torre/ui/art/mascot/cursor/boop.webp +0 -0
  1308. torre/ui/art/mascot/cursor/bye.webp +0 -0
  1309. torre/ui/art/mascot/cursor/dizzy.webp +0 -0
  1310. torre/ui/art/mascot/cursor/doze.webp +0 -0
  1311. torre/ui/art/mascot/cursor/hello.webp +0 -0
  1312. torre/ui/art/mascot/cursor/startled.webp +0 -0
  1313. torre/ui/art/mascot/cursor/tickled.webp +0 -0
  1314. torre/ui/art/mascot/cursor/wake.webp +0 -0
  1315. torre/ui/art/mascot/dancing.webp +0 -0
  1316. torre/ui/art/mascot/detective.webp +0 -0
  1317. torre/ui/art/mascot/determined.webp +0 -0
  1318. torre/ui/art/mascot/dizzy.webp +0 -0
  1319. torre/ui/art/mascot/excited.webp +0 -0
  1320. torre/ui/art/mascot/facepalm.webp +0 -0
  1321. torre/ui/art/mascot/gift.webp +0 -0
  1322. torre/ui/art/mascot/happy.webp +0 -0
  1323. torre/ui/art/mascot/host.webp +0 -0
  1324. torre/ui/art/mascot/hug.webp +0 -0
  1325. torre/ui/art/mascot/idea.webp +0 -0
  1326. torre/ui/art/mascot/magnify.webp +0 -0
  1327. torre/ui/art/mascot/move-piece.webp +0 -0
  1328. torre/ui/art/mascot/nervous.webp +0 -0
  1329. torre/ui/art/mascot/neutral.webp +0 -0
  1330. torre/ui/art/mascot/no.webp +0 -0
  1331. torre/ui/art/mascot/nod.webp +0 -0
  1332. torre/ui/art/mascot/notes.webp +0 -0
  1333. torre/ui/art/mascot/panic.webp +0 -0
  1334. torre/ui/art/mascot/playing.webp +0 -0
  1335. torre/ui/art/mascot/point-board.webp +0 -0
  1336. torre/ui/art/mascot/point.webp +0 -0
  1337. torre/ui/art/mascot/pointer.webp +0 -0
  1338. torre/ui/art/mascot/present.webp +0 -0
  1339. torre/ui/art/mascot/proud.webp +0 -0
  1340. torre/ui/art/mascot/puzzle.webp +0 -0
  1341. torre/ui/art/mascot/ready.webp +0 -0
  1342. torre/ui/art/mascot/relieved.webp +0 -0
  1343. torre/ui/art/mascot/rival.webp +0 -0
  1344. torre/ui/art/mascot/sad.webp +0 -0
  1345. torre/ui/art/mascot/salute.webp +0 -0
  1346. torre/ui/art/mascot/sheepish.webp +0 -0
  1347. torre/ui/art/mascot/shield.webp +0 -0
  1348. torre/ui/art/mascot/shocked.webp +0 -0
  1349. torre/ui/art/mascot/shrug.webp +0 -0
  1350. torre/ui/art/mascot/sleepy.webp +0 -0
  1351. torre/ui/art/mascot/star.webp +0 -0
  1352. torre/ui/art/mascot/starry.webp +0 -0
  1353. torre/ui/art/mascot/study.webp +0 -0
  1354. torre/ui/art/mascot/teary.webp +0 -0
  1355. torre/ui/art/mascot/thinking.webp +0 -0
  1356. torre/ui/art/mascot/thumbs-up.webp +0 -0
  1357. torre/ui/art/mascot/trophy.webp +0 -0
  1358. torre/ui/art/mascot/warn.webp +0 -0
  1359. torre/ui/art/mascot/wave.webp +0 -0
  1360. torre/ui/art/mascot/wink.webp +0 -0
  1361. torre/ui/art/mascot/yawn.webp +0 -0
  1362. torre/ui/art/nav/awards.png +0 -0
  1363. torre/ui/art/nav/explore.png +0 -0
  1364. torre/ui/art/nav/games.png +0 -0
  1365. torre/ui/art/nav/home.png +0 -0
  1366. torre/ui/art/nav/lessons.png +0 -0
  1367. torre/ui/art/nav/play.png +0 -0
  1368. torre/ui/art/nav/puzzles.png +0 -0
  1369. torre/ui/art/nav/train.png +0 -0
  1370. torre/ui/art/openings/bird.webp +0 -0
  1371. torre/ui/art/openings/caro-kann.webp +0 -0
  1372. torre/ui/art/openings/colle.webp +0 -0
  1373. torre/ui/art/openings/dutch.webp +0 -0
  1374. torre/ui/art/openings/english.webp +0 -0
  1375. torre/ui/art/openings/french.webp +0 -0
  1376. torre/ui/art/openings/italian.webp +0 -0
  1377. torre/ui/art/openings/kings-gambit.webp +0 -0
  1378. torre/ui/art/openings/kings-indian.webp +0 -0
  1379. torre/ui/art/openings/kings-knight.webp +0 -0
  1380. torre/ui/art/openings/kings-pawn.webp +0 -0
  1381. torre/ui/art/openings/london.webp +0 -0
  1382. torre/ui/art/openings/philidor.webp +0 -0
  1383. torre/ui/art/openings/pirc.webp +0 -0
  1384. torre/ui/art/openings/queens-gambit.webp +0 -0
  1385. torre/ui/art/openings/queens-pawn.webp +0 -0
  1386. torre/ui/art/openings/ruy-lopez.webp +0 -0
  1387. torre/ui/art/openings/scandinavian.webp +0 -0
  1388. torre/ui/art/openings/scotch.webp +0 -0
  1389. torre/ui/art/openings/sicilian.webp +0 -0
  1390. torre/ui/art/openings/slav.webp +0 -0
  1391. torre/ui/art/openings/trompowsky.webp +0 -0
  1392. torre/ui/art/openings/uncommon.webp +0 -0
  1393. torre/ui/art/openings/vienna.webp +0 -0
  1394. torre/ui/art/pieces/black-bishop.webp +0 -0
  1395. torre/ui/art/pieces/black-king.webp +0 -0
  1396. torre/ui/art/pieces/black-knight.webp +0 -0
  1397. torre/ui/art/pieces/black-pawn.webp +0 -0
  1398. torre/ui/art/pieces/black-queen.webp +0 -0
  1399. torre/ui/art/pieces/black-resigned.webp +0 -0
  1400. torre/ui/art/pieces/black-rook.webp +0 -0
  1401. torre/ui/art/pieces/black-winner.webp +0 -0
  1402. torre/ui/art/pieces/board/bB.webp +0 -0
  1403. torre/ui/art/pieces/board/bK.webp +0 -0
  1404. torre/ui/art/pieces/board/bN.webp +0 -0
  1405. torre/ui/art/pieces/board/bP.webp +0 -0
  1406. torre/ui/art/pieces/board/bQ.webp +0 -0
  1407. torre/ui/art/pieces/board/bR.webp +0 -0
  1408. torre/ui/art/pieces/board/wB.webp +0 -0
  1409. torre/ui/art/pieces/board/wK.webp +0 -0
  1410. torre/ui/art/pieces/board/wN.webp +0 -0
  1411. torre/ui/art/pieces/board/wP.webp +0 -0
  1412. torre/ui/art/pieces/board/wQ.webp +0 -0
  1413. torre/ui/art/pieces/board/wR.webp +0 -0
  1414. torre/ui/art/pieces/staunton/bB.webp +0 -0
  1415. torre/ui/art/pieces/staunton/bK.webp +0 -0
  1416. torre/ui/art/pieces/staunton/bN.webp +0 -0
  1417. torre/ui/art/pieces/staunton/bP.webp +0 -0
  1418. torre/ui/art/pieces/staunton/bQ.webp +0 -0
  1419. torre/ui/art/pieces/staunton/bR.webp +0 -0
  1420. torre/ui/art/pieces/staunton/wB.webp +0 -0
  1421. torre/ui/art/pieces/staunton/wK.webp +0 -0
  1422. torre/ui/art/pieces/staunton/wN.webp +0 -0
  1423. torre/ui/art/pieces/staunton/wP.webp +0 -0
  1424. torre/ui/art/pieces/staunton/wQ.webp +0 -0
  1425. torre/ui/art/pieces/staunton/wR.webp +0 -0
  1426. torre/ui/art/pieces/white-bishop.webp +0 -0
  1427. torre/ui/art/pieces/white-king.webp +0 -0
  1428. torre/ui/art/pieces/white-knight.webp +0 -0
  1429. torre/ui/art/pieces/white-pawn.webp +0 -0
  1430. torre/ui/art/pieces/white-queen.webp +0 -0
  1431. torre/ui/art/pieces/white-resigned.webp +0 -0
  1432. torre/ui/art/pieces/white-rook.webp +0 -0
  1433. torre/ui/art/pieces/white-winner.webp +0 -0
  1434. torre/ui/art/progress/calendar.webp +0 -0
  1435. torre/ui/art/progress/clock.webp +0 -0
  1436. torre/ui/art/progress/growth.webp +0 -0
  1437. torre/ui/art/progress/study.webp +0 -0
  1438. torre/ui/art/progress/target.webp +0 -0
  1439. torre/ui/art/progress/victory.webp +0 -0
  1440. torre/ui/art/robots/robot-1.webp +0 -0
  1441. torre/ui/art/robots/robot-2.webp +0 -0
  1442. torre/ui/art/robots/robot-3.webp +0 -0
  1443. torre/ui/art/robots/robot-4.webp +0 -0
  1444. torre/ui/art/robots/robot-5.webp +0 -0
  1445. torre/ui/art/robots/robot-6.webp +0 -0
  1446. torre/ui/art/robots/robot-7.webp +0 -0
  1447. torre/ui/art/robots/robot-8.webp +0 -0
  1448. torre/ui/art/stars/star-empty.png +0 -0
  1449. torre/ui/art/stars/star-gold.png +0 -0
  1450. torre/ui/art/story/basics/boulder.webp +0 -0
  1451. torre/ui/art/story/basics/bridge.webp +0 -0
  1452. torre/ui/art/story/basics/castle.webp +0 -0
  1453. torre/ui/art/story/basics/edge-1.webp +0 -0
  1454. torre/ui/art/story/basics/fence.webp +0 -0
  1455. torre/ui/art/story/basics/flowers.webp +0 -0
  1456. torre/ui/art/story/basics/mushrooms.webp +0 -0
  1457. torre/ui/art/story/basics/pine.webp +0 -0
  1458. torre/ui/art/story/basics/tree.webp +0 -0
  1459. torre/ui/art/story/birds.webp +0 -0
  1460. torre/ui/art/story/boss-gate.webp +0 -0
  1461. torre/ui/art/story/chapter/complete.webp +0 -0
  1462. torre/ui/art/story/chapter/first-moves.webp +0 -0
  1463. torre/ui/art/story/chapter/opening-ideas.webp +0 -0
  1464. torre/ui/art/story/chapter/the-immortals.webp +0 -0
  1465. torre/ui/art/story/chapter/the-last-twenty-moves.webp +0 -0
  1466. torre/ui/art/story/chapter/the-mating-net.webp +0 -0
  1467. torre/ui/art/story/chapter/the-quiet-board.webp +0 -0
  1468. torre/ui/art/story/chapter/tricks-of-the-trade.webp +0 -0
  1469. torre/ui/art/story/checkmates/dead-tree.webp +0 -0
  1470. torre/ui/art/story/checkmates/edge-1.webp +0 -0
  1471. torre/ui/art/story/checkmates/edge-2.webp +0 -0
  1472. torre/ui/art/story/checkmates/ferns.webp +0 -0
  1473. torre/ui/art/story/checkmates/lantern.webp +0 -0
  1474. torre/ui/art/story/checkmates/log.webp +0 -0
  1475. torre/ui/art/story/checkmates/net.webp +0 -0
  1476. torre/ui/art/story/checkmates/pine.webp +0 -0
  1477. torre/ui/art/story/checkmates/tower.webp +0 -0
  1478. torre/ui/art/story/checkmates/web.webp +0 -0
  1479. torre/ui/art/story/chest.webp +0 -0
  1480. torre/ui/art/story/cloud.webp +0 -0
  1481. torre/ui/art/story/endgames/bush.webp +0 -0
  1482. torre/ui/art/story/endgames/cabin.webp +0 -0
  1483. torre/ui/art/story/endgames/campfire.webp +0 -0
  1484. torre/ui/art/story/endgames/edge-1.webp +0 -0
  1485. torre/ui/art/story/endgames/edge-2.webp +0 -0
  1486. torre/ui/art/story/endgames/ice-rock.webp +0 -0
  1487. torre/ui/art/story/endgames/peak.webp +0 -0
  1488. torre/ui/art/story/endgames/pine.webp +0 -0
  1489. torre/ui/art/story/endgames/sled.webp +0 -0
  1490. torre/ui/art/story/endgames/snowman.webp +0 -0
  1491. torre/ui/art/story/gauntlet.webp +0 -0
  1492. torre/ui/art/story/hero-cheer.webp +0 -0
  1493. torre/ui/art/story/hero-flag.webp +0 -0
  1494. torre/ui/art/story/history/amphora.webp +0 -0
  1495. torre/ui/art/story/history/archway.webp +0 -0
  1496. torre/ui/art/story/history/column.webp +0 -0
  1497. torre/ui/art/story/history/cypress.webp +0 -0
  1498. torre/ui/art/story/history/edge-1.webp +0 -0
  1499. torre/ui/art/story/history/edge-2.webp +0 -0
  1500. torre/ui/art/story/history/laurel.webp +0 -0
  1501. torre/ui/art/story/history/rubble.webp +0 -0
  1502. torre/ui/art/story/history/tablet.webp +0 -0
  1503. torre/ui/art/story/history/temple.webp +0 -0
  1504. torre/ui/art/story/openings/barrels.webp +0 -0
  1505. torre/ui/art/story/openings/cottage.webp +0 -0
  1506. torre/ui/art/story/openings/edge-1.webp +0 -0
  1507. torre/ui/art/story/openings/edge-2.webp +0 -0
  1508. torre/ui/art/story/openings/haystack.webp +0 -0
  1509. torre/ui/art/story/openings/signpost.webp +0 -0
  1510. torre/ui/art/story/openings/sunflowers.webp +0 -0
  1511. torre/ui/art/story/openings/tree.webp +0 -0
  1512. torre/ui/art/story/openings/wheelbarrow.webp +0 -0
  1513. torre/ui/art/story/openings/windmill.webp +0 -0
  1514. torre/ui/art/story/quote-hill.webp +0 -0
  1515. torre/ui/art/story/strategy/bamboo.webp +0 -0
  1516. torre/ui/art/story/strategy/blossom.webp +0 -0
  1517. torre/ui/art/story/strategy/bonsai.webp +0 -0
  1518. torre/ui/art/story/strategy/edge-1.webp +0 -0
  1519. torre/ui/art/story/strategy/edge-2.webp +0 -0
  1520. torre/ui/art/story/strategy/lantern.webp +0 -0
  1521. torre/ui/art/story/strategy/pagoda.webp +0 -0
  1522. torre/ui/art/story/strategy/pond.webp +0 -0
  1523. torre/ui/art/story/strategy/red-bridge.webp +0 -0
  1524. torre/ui/art/story/strategy/sand.webp +0 -0
  1525. torre/ui/art/story/tactics/arch.webp +0 -0
  1526. torre/ui/art/story/tactics/bush.webp +0 -0
  1527. torre/ui/art/story/tactics/cactus.webp +0 -0
  1528. torre/ui/art/story/tactics/crate.webp +0 -0
  1529. torre/ui/art/story/tactics/edge-1.webp +0 -0
  1530. torre/ui/art/story/tactics/edge-2.webp +0 -0
  1531. torre/ui/art/story/tactics/mesa.webp +0 -0
  1532. torre/ui/art/story/tactics/rope-bridge.webp +0 -0
  1533. torre/ui/art/story/tactics/spire.webp +0 -0
  1534. torre/ui/art/story/tactics/tumbleweed.webp +0 -0
  1535. torre/ui/art/topics/analysis.webp +0 -0
  1536. torre/ui/art/topics/anastasia-mate.webp +0 -0
  1537. torre/ui/art/topics/arabian-mate.webp +0 -0
  1538. torre/ui/art/topics/as-black.webp +0 -0
  1539. torre/ui/art/topics/as-white.webp +0 -0
  1540. torre/ui/art/topics/attraction.webp +0 -0
  1541. torre/ui/art/topics/bishop-endgame.webp +0 -0
  1542. torre/ui/art/topics/boden-mate.webp +0 -0
  1543. torre/ui/art/topics/bots.webp +0 -0
  1544. torre/ui/art/topics/bridge.webp +0 -0
  1545. torre/ui/art/topics/capture-defender.webp +0 -0
  1546. torre/ui/art/topics/defensive-move.webp +0 -0
  1547. torre/ui/art/topics/double-check.webp +0 -0
  1548. torre/ui/art/topics/endgame.webp +0 -0
  1549. torre/ui/art/topics/explore.webp +0 -0
  1550. torre/ui/art/topics/exposed-king.webp +0 -0
  1551. torre/ui/art/topics/form.webp +0 -0
  1552. torre/ui/art/topics/games.webp +0 -0
  1553. torre/ui/art/topics/hanging-piece.webp +0 -0
  1554. torre/ui/art/topics/hook-mate.webp +0 -0
  1555. torre/ui/art/topics/import.webp +0 -0
  1556. torre/ui/art/topics/insights.webp +0 -0
  1557. torre/ui/art/topics/kingside-attack.webp +0 -0
  1558. torre/ui/art/topics/knight-endgame.webp +0 -0
  1559. torre/ui/art/topics/mate-in-1.webp +0 -0
  1560. torre/ui/art/topics/mate-in-2.webp +0 -0
  1561. torre/ui/art/topics/mate-in-3.webp +0 -0
  1562. torre/ui/art/topics/middlegame.webp +0 -0
  1563. torre/ui/art/topics/mistakes.webp +0 -0
  1564. torre/ui/art/topics/new-game.webp +0 -0
  1565. torre/ui/art/topics/opening.webp +0 -0
  1566. torre/ui/art/topics/opposition.webp +0 -0
  1567. torre/ui/art/topics/pawn-endgame.webp +0 -0
  1568. torre/ui/art/topics/pawn-push.webp +0 -0
  1569. torre/ui/art/topics/queen-endgame.webp +0 -0
  1570. torre/ui/art/topics/queen-mate.webp +0 -0
  1571. torre/ui/art/topics/quiet-move.webp +0 -0
  1572. torre/ui/art/topics/rating.webp +0 -0
  1573. torre/ui/art/topics/recurring.webp +0 -0
  1574. torre/ui/art/topics/retry.webp +0 -0
  1575. torre/ui/art/topics/rook-endgame.webp +0 -0
  1576. torre/ui/art/topics/smothered-mate.webp +0 -0
  1577. torre/ui/art/topics/train.webp +0 -0
  1578. torre/ui/art/topics/trapped-piece.webp +0 -0
  1579. torre/ui/art/topics/underpromotion.webp +0 -0
  1580. torre/ui/art/topics/zwischenzug.webp +0 -0
  1581. torre/ui/art/ui3d/achievement.webp +0 -0
  1582. torre/ui/art/ui3d/defeat.webp +0 -0
  1583. torre/ui/art/ui3d/help.webp +0 -0
  1584. torre/ui/art/ui3d/info.webp +0 -0
  1585. torre/ui/art/ui3d/level-complete.webp +0 -0
  1586. torre/ui/art/ui3d/locked.webp +0 -0
  1587. torre/ui/art/ui3d/mute.webp +0 -0
  1588. torre/ui/art/ui3d/pause.webp +0 -0
  1589. torre/ui/art/ui3d/play.webp +0 -0
  1590. torre/ui/art/ui3d/retry.webp +0 -0
  1591. torre/ui/art/ui3d/reward.webp +0 -0
  1592. torre/ui/art/ui3d/settings.webp +0 -0
  1593. torre/ui/art/ui3d/sound.webp +0 -0
  1594. torre/ui/art/ui3d/time.webp +0 -0
  1595. torre/ui/art/ui3d/unlocked.webp +0 -0
  1596. torre/ui/art/ui3d/victory.webp +0 -0
  1597. torre/ui/art/video/figure-alekhine-attack.webp +0 -0
  1598. torre/ui/art/video/figure-anderssen-evergreen.webp +0 -0
  1599. torre/ui/art/video/figure-anderssen-immortal.webp +0 -0
  1600. torre/ui/art/video/figure-botvinnik-worried.webp +0 -0
  1601. torre/ui/art/video/figure-byrne.webp +0 -0
  1602. torre/ui/art/video/figure-capablanca-qgd.webp +0 -0
  1603. torre/ui/art/video/figure-dufresne.webp +0 -0
  1604. torre/ui/art/video/figure-duke-and-count.webp +0 -0
  1605. torre/ui/art/video/figure-fischer-alone.webp +0 -0
  1606. torre/ui/art/video/figure-fischer-c4.webp +0 -0
  1607. torre/ui/art/video/figure-fischer-champion.webp +0 -0
  1608. torre/ui/art/video/figure-fischer-demands.webp +0 -0
  1609. torre/ui/art/video/figure-fischer-focused.webp +0 -0
  1610. torre/ui/art/video/figure-fischer-sacrifice.webp +0 -0
  1611. torre/ui/art/video/figure-fischer-young.webp +0 -0
  1612. torre/ui/art/video/figure-gurgenidze.webp +0 -0
  1613. torre/ui/art/video/figure-hecht.webp +0 -0
  1614. torre/ui/art/video/figure-karpov-rival.webp +0 -0
  1615. torre/ui/art/video/figure-kasparov-champion.webp +0 -0
  1616. torre/ui/art/video/figure-kasparov-deep-blue.webp +0 -0
  1617. torre/ui/art/video/figure-kasparov-fierce.webp +0 -0
  1618. torre/ui/art/video/figure-kasparov-qg.webp +0 -0
  1619. torre/ui/art/video/figure-kasparov-sacrifice.webp +0 -0
  1620. torre/ui/art/video/figure-kasparov-young.webp +0 -0
  1621. torre/ui/art/video/figure-kieseritzky-shocked.webp +0 -0
  1622. torre/ui/art/video/figure-larsen-bold.webp +0 -0
  1623. torre/ui/art/video/figure-morphy-blindfold.webp +0 -0
  1624. torre/ui/art/video/figure-morphy-opera.webp +0 -0
  1625. torre/ui/art/video/figure-morphy-young.webp +0 -0
  1626. torre/ui/art/video/figure-najdorf-resigns.webp +0 -0
  1627. torre/ui/art/video/figure-portisch-pained.webp +0 -0
  1628. torre/ui/art/video/figure-portisch.webp +0 -0
  1629. torre/ui/art/video/figure-rook-books.webp +0 -0
  1630. torre/ui/art/video/figure-rook-cheers.webp +0 -0
  1631. torre/ui/art/video/figure-rook-gift.webp +0 -0
  1632. torre/ui/art/video/figure-rook-points-d4.webp +0 -0
  1633. torre/ui/art/video/figure-rook-presents.webp +0 -0
  1634. torre/ui/art/video/figure-rook-warns.webp +0 -0
  1635. torre/ui/art/video/figure-rubinstein-study.webp +0 -0
  1636. torre/ui/art/video/figure-smyslov-shocked.webp +0 -0
  1637. torre/ui/art/video/figure-spassky-applauds.webp +0 -0
  1638. torre/ui/art/video/figure-spassky-calm.webp +0 -0
  1639. torre/ui/art/video/figure-tal-champion.webp +0 -0
  1640. torre/ui/art/video/figure-tal-grin.webp +0 -0
  1641. torre/ui/art/video/figure-tal-magic.webp +0 -0
  1642. torre/ui/art/video/figure-tal-sacrifice.webp +0 -0
  1643. torre/ui/art/video/figure-tal-thinking.webp +0 -0
  1644. torre/ui/art/video/figure-tal-young.webp +0 -0
  1645. torre/ui/art/video/moment-alarm-king.webp +0 -0
  1646. torre/ui/art/video/moment-brilliant-gem.webp +0 -0
  1647. torre/ui/art/video/moment-candidates-cup.webp +0 -0
  1648. torre/ui/art/video/moment-checkmate-net.webp +0 -0
  1649. torre/ui/art/video/moment-chess-clock.webp +0 -0
  1650. torre/ui/art/video/moment-exploding-board.webp +0 -0
  1651. torre/ui/art/video/moment-fire-rook.webp +0 -0
  1652. torre/ui/art/video/moment-hanging-bishop.webp +0 -0
  1653. torre/ui/art/video/moment-lightning-knight.webp +0 -0
  1654. torre/ui/art/video/moment-newspaper.webp +0 -0
  1655. torre/ui/art/video/moment-only-move.webp +0 -0
  1656. torre/ui/art/video/moment-qg-accepted-hug.webp +0 -0
  1657. torre/ui/art/video/moment-qg-cant-hold.webp +0 -0
  1658. torre/ui/art/video/moment-qg-center.webp +0 -0
  1659. torre/ui/art/video/moment-qg-crowned-pawn.webp +0 -0
  1660. torre/ui/art/video/moment-qg-declined-wall.webp +0 -0
  1661. torre/ui/art/video/moment-qg-duel.webp +0 -0
  1662. torre/ui/art/video/moment-qg-elephant-trap.webp +0 -0
  1663. torre/ui/art/video/moment-qg-gift-queen.webp +0 -0
  1664. torre/ui/art/video/moment-qg-greedy-pawn.webp +0 -0
  1665. torre/ui/art/video/moment-qg-isolated-pawn.webp +0 -0
  1666. torre/ui/art/video/moment-qg-lasker-trap.webp +0 -0
  1667. torre/ui/art/video/moment-qg-minority-attack.webp +0 -0
  1668. torre/ui/art/video/moment-qg-offer.webp +0 -0
  1669. torre/ui/art/video/moment-qg-pin.webp +0 -0
  1670. torre/ui/art/video/moment-qg-slav-shield.webp +0 -0
  1671. torre/ui/art/video/moment-qg-tempted-pawn.webp +0 -0
  1672. torre/ui/art/video/moment-qg-trapdoor.webp +0 -0
  1673. torre/ui/art/video/moment-qg-two-doors.webp +0 -0
  1674. torre/ui/art/video/moment-queen-sacrifice.webp +0 -0
  1675. torre/ui/art/video/moment-resign.webp +0 -0
  1676. torre/ui/art/video/moment-scoresheet.webp +0 -0
  1677. torre/ui/art/video/moment-shocked-queen.webp +0 -0
  1678. torre/ui/art/video/moment-spotlight-board.webp +0 -0
  1679. torre/ui/art/video/moment-trapped-queen.webp +0 -0
  1680. torre/ui/art/video/moment-world-crown.webp +0 -0
  1681. torre/ui/art/video/venue-berlin-1852.webp +0 -0
  1682. torre/ui/art/video/venue-bled.webp +0 -0
  1683. torre/ui/art/video/venue-leipzig.webp +0 -0
  1684. torre/ui/art/video/venue-london-1851.webp +0 -0
  1685. torre/ui/art/video/venue-moscow-1985.webp +0 -0
  1686. torre/ui/art/video/venue-moscow-match.webp +0 -0
  1687. torre/ui/art/video/venue-new-york-1956.webp +0 -0
  1688. torre/ui/art/video/venue-new-york-1997.webp +0 -0
  1689. torre/ui/art/video/venue-paris-opera-1858.webp +0 -0
  1690. torre/ui/art/video/venue-reykjavik-1972.webp +0 -0
  1691. torre/ui/art/video/venue-reykjavik.webp +0 -0
  1692. torre/ui/art/video/venue-riga.webp +0 -0
  1693. torre/ui/art/video/venue-tilburg.webp +0 -0
  1694. torre/ui/art/video/venue-varna.webp +0 -0
  1695. torre/ui/art/video/venue-wijk-aan-zee-1999.webp +0 -0
  1696. torre/ui/art/video/venue-zurich.webp +0 -0
  1697. torre/ui/art/yours/endgame-grinder.webp +0 -0
  1698. torre/ui/art/yours/opening-tourist.webp +0 -0
  1699. torre/ui/art/yours/positional-master.webp +0 -0
  1700. torre/ui/art/yours/present-you.webp +0 -0
  1701. torre/ui/art/yours/reckless-attacker.webp +0 -0
  1702. torre/ui/art/yours/tactical-sharpie.webp +0 -0
  1703. torre/ui/art/yours/the-trader.webp +0 -0
  1704. torre/ui/art/yours/train.webp +0 -0
  1705. torre/ui/assets/AiSetup-D0ojvOo6.js +1 -0
  1706. torre/ui/assets/AnalysisBanner-CgzZjuOs.js +1 -0
  1707. torre/ui/assets/ArenaPage-DhhtFsO6.js +1 -0
  1708. torre/ui/assets/AwardsPage-DIBR--pI.js +1 -0
  1709. torre/ui/assets/BoardWorkspace-Cxrtuejv.js +1 -0
  1710. torre/ui/assets/BotCollectionPage-DMIe2Mqp.js +1 -0
  1711. torre/ui/assets/BotReport-CegOQG0r.js +1 -0
  1712. torre/ui/assets/BotsHomePage-D73LJY3O.js +1 -0
  1713. torre/ui/assets/CoachExplain-CfTPObIL.js +1 -0
  1714. torre/ui/assets/CoachPage-D01hygof.js +1 -0
  1715. torre/ui/assets/CursorRook-B7eCvqMP.js +1 -0
  1716. torre/ui/assets/EndgamesPage-DJGzTpkE.js +1 -0
  1717. torre/ui/assets/ExplorePage-iB6Kc6kX.js +1 -0
  1718. torre/ui/assets/GamesPage-BeCyNtCU.js +1 -0
  1719. torre/ui/assets/HomePage-jcAUG1nj.js +1 -0
  1720. torre/ui/assets/ImportPage-Bn5g3rvQ.js +4 -0
  1721. torre/ui/assets/InsightsPage-CHoneM_p.js +1 -0
  1722. torre/ui/assets/LessonsPage-DeE2ulM2.js +1 -0
  1723. torre/ui/assets/MoveList-DytFbAp6.js +1 -0
  1724. torre/ui/assets/NavIcon-Cdek5ONP.js +1 -0
  1725. torre/ui/assets/OpeningStory-CnmDg1zw.js +1 -0
  1726. torre/ui/assets/OpeningsPage-DydTgh8d.js +1 -0
  1727. torre/ui/assets/PlayPage-DK9-UawI.js +3 -0
  1728. torre/ui/assets/ProfilePage-DOSgcVMv.js +1 -0
  1729. torre/ui/assets/PuzzlesPage-ofZhK6FU.js +1 -0
  1730. torre/ui/assets/RookSpeaker-B_HLzkJm.js +2 -0
  1731. torre/ui/assets/Segments-B8XJlwPB.js +1 -0
  1732. torre/ui/assets/SettingsPage-C4mt0o7O.js +1 -0
  1733. torre/ui/assets/Sidebar-Cio69IXU.js +1 -0
  1734. torre/ui/assets/StagePage-CMmIR1l-.js +1 -0
  1735. torre/ui/assets/StoryPage-DplmoBTf.js +1 -0
  1736. torre/ui/assets/Streak-Co_cfm0s.js +1 -0
  1737. torre/ui/assets/TodayPlan-D_0arCyI.js +1 -0
  1738. torre/ui/assets/TrainPage-D5NthACf.js +1 -0
  1739. torre/ui/assets/TrainerPages-BHIhhs8R.js +1 -0
  1740. torre/ui/assets/awards-B1W0K4TV.js +1 -0
  1741. torre/ui/assets/bots-CqReul03.js +1 -0
  1742. torre/ui/assets/collections-2qe_ozuB.js +1 -0
  1743. torre/ui/assets/content-D7CTF3q9.js +1 -0
  1744. torre/ui/assets/content-en-CcyMO59M.js +1 -0
  1745. torre/ui/assets/content-es-CvyOw0FZ.js +1 -0
  1746. torre/ui/assets/events-ClR1xEWT.js +1 -0
  1747. torre/ui/assets/format-BR0clSXu.js +1 -0
  1748. torre/ui/assets/grades-CM1ebojp.js +1 -0
  1749. torre/ui/assets/i18n-C6NUi9Vs.js +2 -0
  1750. torre/ui/assets/i18n-en-BnZCUyK7.js +1 -0
  1751. torre/ui/assets/i18n-es-SAH-03ta.js +1 -0
  1752. torre/ui/assets/index-Cl_QBZkR.js +2 -0
  1753. torre/ui/assets/index-Zp2E1Y4q.css +1 -0
  1754. torre/ui/assets/lastVisited-ChiJXsfH.js +1 -0
  1755. torre/ui/assets/rolldown-runtime-hePW80VL.js +1 -0
  1756. torre/ui/assets/routes-C8cKcny6.js +1 -0
  1757. torre/ui/assets/stars-De-qIuRF.js +1 -0
  1758. torre/ui/assets/storage-CWyoBvAQ.js +1 -0
  1759. torre/ui/assets/story-DGV08-e8.js +1 -0
  1760. torre/ui/assets/useChess-DdakFbd7.js +1 -0
  1761. torre/ui/assets/useMasters-CW1vT-o3.js +1 -0
  1762. torre/ui/assets/useNarration-IQPX4VHr.js +1 -0
  1763. torre/ui/assets/usePlanning-BfNQrrQD.js +1 -0
  1764. torre/ui/assets/useProfile-COaif7mf.js +1 -0
  1765. torre/ui/assets/useSounds-DtGm8WF1.js +1 -0
  1766. torre/ui/assets/vendor-DVQGMHsh.js +12 -0
  1767. torre/ui/assets/whyItFails-CQZuFn5V.js +1 -0
  1768. torre/ui/index.html +23 -0
  1769. torre/ui/locales/en/arena.json +180 -0
  1770. torre/ui/locales/en/awards.json +21 -0
  1771. torre/ui/locales/en/board.json +281 -0
  1772. torre/ui/locales/en/coach.json +138 -0
  1773. torre/ui/locales/en/coachlines.json +217 -0
  1774. torre/ui/locales/en/commentary.json +862 -0
  1775. torre/ui/locales/en/common.json +32 -0
  1776. torre/ui/locales/en/content.json +6210 -0
  1777. torre/ui/locales/en/endgames.json +68 -0
  1778. torre/ui/locales/en/engineProfile.json +17 -0
  1779. torre/ui/locales/en/engines.json +71 -0
  1780. torre/ui/locales/en/games.json +130 -0
  1781. torre/ui/locales/en/home.json +80 -0
  1782. torre/ui/locales/en/import.json +104 -0
  1783. torre/ui/locales/en/insights.json +110 -0
  1784. torre/ui/locales/en/lessons.json +207 -0
  1785. torre/ui/locales/en/nav.json +106 -0
  1786. torre/ui/locales/en/openings.json +66 -0
  1787. torre/ui/locales/en/play.json +405 -0
  1788. torre/ui/locales/en/profile.json +129 -0
  1789. torre/ui/locales/en/puzzles.json +179 -0
  1790. torre/ui/locales/en/rooky.json +83 -0
  1791. torre/ui/locales/en/settings.json +344 -0
  1792. torre/ui/locales/en/setup.json +10 -0
  1793. torre/ui/locales/en/stats.json +72 -0
  1794. torre/ui/locales/en/story.json +151 -0
  1795. torre/ui/locales/en/train.json +82 -0
  1796. torre/ui/locales/en/trainer.json +81 -0
  1797. torre/ui/locales/en/voice.json +91 -0
  1798. torre/ui/locales/es/arena.json +180 -0
  1799. torre/ui/locales/es/awards.json +21 -0
  1800. torre/ui/locales/es/board.json +281 -0
  1801. torre/ui/locales/es/coach.json +138 -0
  1802. torre/ui/locales/es/coachlines.json +217 -0
  1803. torre/ui/locales/es/commentary.json +890 -0
  1804. torre/ui/locales/es/common.json +32 -0
  1805. torre/ui/locales/es/content.json +6210 -0
  1806. torre/ui/locales/es/endgames.json +68 -0
  1807. torre/ui/locales/es/engineProfile.json +17 -0
  1808. torre/ui/locales/es/engines.json +71 -0
  1809. torre/ui/locales/es/games.json +130 -0
  1810. torre/ui/locales/es/home.json +80 -0
  1811. torre/ui/locales/es/import.json +104 -0
  1812. torre/ui/locales/es/insights.json +110 -0
  1813. torre/ui/locales/es/lessons.json +207 -0
  1814. torre/ui/locales/es/nav.json +106 -0
  1815. torre/ui/locales/es/openings.json +66 -0
  1816. torre/ui/locales/es/play.json +405 -0
  1817. torre/ui/locales/es/profile.json +129 -0
  1818. torre/ui/locales/es/puzzles.json +179 -0
  1819. torre/ui/locales/es/rooky.json +83 -0
  1820. torre/ui/locales/es/settings.json +344 -0
  1821. torre/ui/locales/es/setup.json +10 -0
  1822. torre/ui/locales/es/stats.json +72 -0
  1823. torre/ui/locales/es/story.json +151 -0
  1824. torre/ui/locales/es/train.json +82 -0
  1825. torre/ui/locales/es/trainer.json +81 -0
  1826. torre/ui/locales/es/voice.json +91 -0
  1827. torre/voice/__init__.py +1 -0
  1828. torre/voice/narrate.py +305 -0
  1829. torre-0.3.0.dist-info/METADATA +414 -0
  1830. torre-0.3.0.dist-info/RECORD +1834 -0
  1831. torre-0.3.0.dist-info/WHEEL +5 -0
  1832. torre-0.3.0.dist-info/entry_points.txt +2 -0
  1833. torre-0.3.0.dist-info/licenses/LICENSE +674 -0
  1834. torre-0.3.0.dist-info/top_level.txt +1 -0
torre/__init__.py ADDED
@@ -0,0 +1,6 @@
1
+ """Torre: the chess studio's Python side (server, coach, engines, lessons, puzzles).
2
+
3
+ Run the studio with `python -m torre.server.studio`, the command line with `python -m torre`.
4
+ """
5
+
6
+ __version__ = '0.3.0'
torre/__main__.py ADDED
@@ -0,0 +1,4 @@
1
+ """`python -m torre ...`: the command line (cli.py)."""
2
+ from torre.cli import main
3
+
4
+ raise SystemExit(main())
@@ -0,0 +1 @@
1
+ """Engines, analysis and scoring: Stockfish runs, move grades, motifs, stats, reports and exports."""
@@ -0,0 +1,337 @@
1
+ """Analyze games with Stockfish: Lichess-style judgments and accuracy.
2
+
3
+ Reads: data/games.jsonl
4
+ Writes: data/analysis.jsonl (resume-safe; one record per game)
5
+
6
+ Moves are judged the way Lichess does it, by the drop in winning chances
7
+ (inaccuracy / mistake / blunder), and game accuracy uses Lichess's formula;
8
+ see scoring.py. Moves matching the engine's choice are tagged "best", and
9
+ sound sacrifices "brilliant". Centipawn loss (capped at +/-1500, mate beyond
10
+ the cap) is still recorded for the ACPL statistics.
11
+
12
+ Records from an older SCORING_VERSION are re-analyzed first. analyze_archive is
13
+ the whole pipeline (analysis, then puzzles mined from the new analyses) behind
14
+ `torre analyze` and the studio's background analysis.
15
+
16
+ Usage: .venv/Scripts/python analyze.py [--depth 12] [--limit N] (the same as torre analyze)
17
+ """
18
+
19
+ import io
20
+ import json
21
+ import logging
22
+ import sys
23
+ import threading
24
+ from pathlib import Path
25
+
26
+ import chess
27
+ import chess.engine
28
+ import chess.pgn
29
+
30
+ from torre.analysis import scoring
31
+ from torre.analysis import engines
32
+ from torre import jsonio
33
+ GAMES_FILE = Path("data/games.jsonl")
34
+ ANALYSIS_FILE = Path("data/analysis.jsonl")
35
+
36
+ # v3: shared eight-grade classification, opening provenance and runner-up evaluations.
37
+ SCORING_VERSION = 3
38
+ EVAL_CAP = 1500
39
+ DEFAULT_DEPTH = 12
40
+ MATED_CP = 100_000 # stored cp for a checkmated side (White POV sign)
41
+ # Appends to analysis files and their compaction take turns (within this process).
42
+ ANALYSIS_LOCK = threading.Lock()
43
+ log = logging.getLogger(__name__)
44
+
45
+
46
+ def phase_of(fullmove: int) -> str:
47
+ if fullmove <= 10:
48
+ return "opening"
49
+ if fullmove <= 30:
50
+ return "middlegame"
51
+ return "endgame"
52
+
53
+
54
+ def evaluate(engine, board: chess.Board, depth: int, alternatives=None):
55
+ """White-POV [cp, mate] for `board`, plus the engine's best move (uci)."""
56
+ if board.is_checkmate():
57
+ if alternatives is not None:
58
+ alternatives.append(None)
59
+ return [-MATED_CP if board.turn == chess.WHITE else MATED_CP, None], None
60
+ if board.is_stalemate() or board.is_insufficient_material():
61
+ if alternatives is not None:
62
+ alternatives.append(None)
63
+ return [0, None], None
64
+ infos = engine.analyse(board, chess.engine.Limit(depth=depth), multipv=2)
65
+ info = infos[0]
66
+ if alternatives is not None:
67
+ runner = infos[1]['score'].white() if len(infos) > 1 else None
68
+ alternatives.append([runner.score(), runner.mate()] if runner is not None else None)
69
+ score = info["score"].white()
70
+ pv = info.get("pv") or []
71
+ best = pv[0].uci() if pv else None
72
+ if score.is_mate():
73
+ return [None, score.mate()], best
74
+ return [score.score(), None], best
75
+
76
+
77
+ def legacy_cp(ev, pov: chess.Color) -> int:
78
+ """Capped centipawns from `pov`, mate beyond the cap (the ACPL scale)."""
79
+ cp, mate = ev
80
+ sign = 1 if pov == chess.WHITE else -1
81
+ if mate is not None or abs(cp) >= MATED_CP:
82
+ winning = (mate if mate is not None else cp) * sign > 0
83
+ return (EVAL_CAP + 1000) if winning else -(EVAL_CAP + 1000)
84
+ return max(-EVAL_CAP, min(EVAL_CAP, cp * sign))
85
+
86
+
87
+ def judge_ply(board: chess.Board, move: chess.Move, before, after):
88
+ """(win_before, win_after, judgment, brilliant) for `move` played in
89
+ `board`, from the mover's point of view. `before` / `after` are the stored
90
+ White-POV evals around the move."""
91
+ white = board.turn == chess.WHITE
92
+ win_before, win_after = scoring.win_pct(*before), scoring.win_pct(*after)
93
+ if not white:
94
+ win_before, win_after = 100 - win_before, 100 - win_after
95
+ if after[0] is not None and abs(after[0]) >= MATED_CP: # the move gives checkmate
96
+ return win_before, win_after, None, False
97
+ cls = scoring.judge(before, after, white)
98
+ brilliant = cls is None and scoring.is_brilliant(board, move, win_before, win_after)
99
+ return win_before, win_after, cls, brilliant
100
+
101
+
102
+ def analyze_game(engine, rec: dict, depth: int) -> dict:
103
+ game = chess.pgn.read_game(io.StringIO(rec["pgn"]))
104
+ user_color = chess.WHITE if rec["user_color"] == "white" else chess.BLACK
105
+ standard_start = game.board().fen() == chess.STARTING_FEN
106
+
107
+ # Evaluate the start position and the position after every ply.
108
+ moves = list(game.mainline_moves())
109
+ board = game.board()
110
+ evals, best_moves, alternatives = [], [], []
111
+ for mv in moves:
112
+ ev, best = evaluate(engine, board, depth, alternatives)
113
+ evals.append(ev)
114
+ best_moves.append(best)
115
+ board.push(mv)
116
+ final_ev, _ = evaluate(engine, board, depth)
117
+ evals.append(final_ev)
118
+
119
+ win = [scoring.win_pct(*ev) for ev in evals]
120
+ acc_timeline = [scoring.win_pct(scoring.STANDARD_START_CP)] + win[1:] if standard_start else win
121
+ accuracy = scoring.game_accuracy(acc_timeline, white_starts=game.board().turn == chess.WHITE)
122
+
123
+ user_moves, all_grades = [], []
124
+ board = game.board()
125
+ for i, mv in enumerate(moves):
126
+ mover = board.turn
127
+ graded = scoring.classify(board, mv,
128
+ {'cp': evals[i][0], 'mate': evals[i][1], 'best': best_moves[i], 'alternative': alternatives[i]},
129
+ {'cp': evals[i + 1][0], 'mate': evals[i + 1][1]})
130
+ all_grades.append(graded)
131
+ if mover == user_color:
132
+ win_before, win_after, cls, brilliant = judge_ply(board, mv, evals[i], evals[i + 1])
133
+ before = legacy_cp(evals[i], mover)
134
+ cpl = max(0, before - legacy_cp(evals[i + 1], mover))
135
+ user_moves.append({
136
+ "ply": i + 1,
137
+ "move_number": board.fullmove_number,
138
+ "san": board.san(mv),
139
+ "fen": board.fen(),
140
+ "phase": phase_of(board.fullmove_number),
141
+ "eval_before": before,
142
+ "cpl": cpl,
143
+ "win_before": round(win_before, 1),
144
+ "win_after": round(win_after, 1),
145
+ **graded,
146
+ })
147
+ board.push(mv)
148
+
149
+ counts = {"inaccuracy": 0, "mistake": 0, "blunder": 0}
150
+ for m in user_moves:
151
+ if m["class"]:
152
+ counts[m["class"]] += 1
153
+
154
+ worst = sorted((m for m in user_moves if m["class"]), key=lambda m: m["win_after"] - m["win_before"])[:5]
155
+ opp = "black" if user_color == chess.WHITE else "white"
156
+ rounded = lambda x: None if x is None else round(x, 1)
157
+
158
+ return {
159
+ "id": rec["id"],
160
+ "scoring_version": SCORING_VERSION,
161
+ "move_grades": all_grades,
162
+ "alternatives": alternatives,
163
+ "grades": {name: sum(scoring.grade(m) == name for m in user_moves) for name in scoring.GRADES},
164
+ "date": rec.get("date"),
165
+ "type": rec.get("type"),
166
+ "opponent": rec.get("opponent"),
167
+ "user_color": rec["user_color"],
168
+ "user_result": rec.get("user_result"),
169
+ "user_accuracy": rec.get("user_accuracy"),
170
+ "accuracy": rounded(accuracy[rec["user_color"]]),
171
+ "opp_accuracy": rounded(accuracy[opp]),
172
+ "opp_rating": rec.get("opp_rating"),
173
+ "user_rating": rec.get("user_rating"),
174
+ "user_move_count": len(user_moves),
175
+ "avg_cpl": round(sum(m["cpl"] for m in user_moves) / max(1, len(user_moves)), 1),
176
+ **counts,
177
+ "best": sum(m["best"] for m in user_moves),
178
+ "brilliant": sum(m["brilliant"] for m in user_moves),
179
+ "phase_counts": {
180
+ ph: {
181
+ "moves": sum(1 for m in user_moves if m["phase"] == ph),
182
+ "cpl": sum(m["cpl"] for m in user_moves if m["phase"] == ph),
183
+ "blunders": sum(1 for m in user_moves if m["phase"] == ph and m["class"] == "blunder"),
184
+ "mistakes": sum(1 for m in user_moves if m["phase"] == ph and m["class"] == "mistake"),
185
+ }
186
+ for ph in ("opening", "middlegame", "endgame")
187
+ },
188
+ "worst_moves": worst,
189
+ "key_moments": scoring.key_moments(user_moves),
190
+ "moves": [{k: m[k] for k in ("ply", "san", "class", "best", "brilliant", "great", "book", "accuracy")} for m in user_moves],
191
+ "evals": evals,
192
+ "best_moves": best_moves,
193
+ }
194
+
195
+
196
+ def review_moves(record):
197
+ """Player moves with the same flags as the full grading timeline, when available."""
198
+ timeline = record.get('move_grades') or []
199
+ return [{**m, **(timeline[m['ply'] - 1] if 0 < m['ply'] <= len(timeline) else {})}
200
+ for m in record.get('moves') or []]
201
+
202
+
203
+ def _latest(rows) -> dict:
204
+ """One record per game id, preferring the current scoring version, then the latest written."""
205
+ records = {}
206
+ for rec in rows:
207
+ if not isinstance(rec, dict) or "id" not in rec:
208
+ continue
209
+ gid = rec["id"]
210
+ old = records.get(gid)
211
+ if old is None or rec.get("scoring_version") == SCORING_VERSION or old.get("scoring_version") != SCORING_VERSION:
212
+ records[gid] = rec
213
+ return records
214
+
215
+
216
+ def latest(analysis_file: Path = ANALYSIS_FILE) -> dict:
217
+ """The analysis records by game id (see _latest), without changing the file. Shared: read-only."""
218
+ return jsonio.cached(Path(analysis_file), _latest_in)
219
+
220
+
221
+ def _latest_in(path):
222
+ return _latest(jsonio.read_jsonl(path))
223
+
224
+
225
+ def compact(analysis_file: Path = ANALYSIS_FILE) -> dict:
226
+ """Rewrite the analysis file with one record per game (see _latest), in one atomic step and
227
+ never while this process appends to it. Returns the records by id."""
228
+ analysis_file = Path(analysis_file)
229
+ with ANALYSIS_LOCK:
230
+ if not analysis_file.exists():
231
+ return {}
232
+ lines, rows = 0, []
233
+ with analysis_file.open(encoding="utf-8") as f:
234
+ for line in f:
235
+ lines += 1
236
+ try:
237
+ rows.append(json.loads(line))
238
+ except json.JSONDecodeError:
239
+ continue
240
+ records = _latest(rows)
241
+ if lines != len(records):
242
+ try:
243
+ jsonio.write_atomic(analysis_file, "".join(json.dumps(r) + "\n" for r in records.values()))
244
+ except OSError: # the file stays as it is: readers already skip the duplicates
245
+ log.warning("Could not compact %s", analysis_file, exc_info=True)
246
+ return records
247
+
248
+
249
+ def pending(games_file: Path = GAMES_FILE, analysis_file: Path = ANALYSIS_FILE):
250
+ """Games still to analyze (outdated records first), and how many are current. Read-only:
251
+ the analysis file is compacted by the analysis run, never here."""
252
+ records = latest(analysis_file)
253
+ done = {gid for gid, rec in records.items() if rec.get("scoring_version") == SCORING_VERSION}
254
+ outdated = set(records) - done
255
+ games = [rec for rec in jsonio.read_jsonl(Path(games_file))
256
+ if isinstance(rec, dict) and "id" in rec and rec["id"] not in done]
257
+ # Outdated records first, then the newest games: recent mistakes are the ones worth drilling.
258
+ games.sort(key=lambda r: r.get("date") or "", reverse=True)
259
+ games.sort(key=lambda r: r["id"] not in outdated)
260
+ return games, len(done), len(outdated)
261
+
262
+
263
+ def run(games, engine_path, analysis_file: Path = ANALYSIS_FILE, depth=DEFAULT_DEPTH, threads=8,
264
+ progress=None, should_stop=lambda: False):
265
+ """Analyze `games`, appending each record as it finishes. `progress` is
266
+ called as progress(index, game, result_or_None, error_or_None)."""
267
+ engine = chess.engine.SimpleEngine.popen_uci(str(engine_path))
268
+ engine.configure({"Threads": threads, "Hash": 512})
269
+ try:
270
+ for i, rec in enumerate(games, 1):
271
+ if should_stop():
272
+ break
273
+ try:
274
+ result = analyze_game(engine, rec, depth)
275
+ except Exception as e: # one unreadable game must not stop the run
276
+ if progress:
277
+ progress(i, rec, None, e)
278
+ continue
279
+ # Opened per record, so compact() can replace the file between two of them.
280
+ with ANALYSIS_LOCK, Path(analysis_file).open("a", encoding="utf-8") as out:
281
+ out.write(json.dumps(result) + "\n")
282
+ if progress:
283
+ progress(i, rec, result, None)
284
+ finally:
285
+ engine.quit()
286
+ compact(analysis_file)
287
+
288
+
289
+ def analyze_archive(games, engine_path, games_file, analysis_file, pack_file, *, depth=DEFAULT_DEPTH, threads=8,
290
+ batch=None, mine=True, progress=None, mine_progress=None, on_mine=None, should_stop=lambda: False):
291
+ """Analyze `games` (pending()'s list), then mine the new analyses into the "From your games"
292
+ puzzles in `pack_file` (my_puzzles.py). Returns (pack, games mined), the pack being None
293
+ when nothing was mined.
294
+
295
+ With `batch`, mining follows every `batch` games, so a long run stopped halfway already feeds
296
+ the puzzles and drills. Each engine takes up to `threads` from engines.POOL.budget.
297
+ progress(index, game, result, error) follows each game and mine_progress (my_puzzles.run's)
298
+ each mined one. on_mine('start', None) comes before each mining pass, then
299
+ on_mine('done', (pack, mined)) or on_mine('failed', exc): a failed pass is then reported
300
+ and the run goes on; without on_mine it is raised.
301
+ """
302
+ from torre.learning import my_puzzles # it imports this module
303
+ batch = batch or len(games) or 1
304
+ pack, total = None, 0
305
+ for start in range(0, max(len(games), 1), batch):
306
+ chunk = games[start:start + batch]
307
+ if chunk:
308
+ with engines.POOL.budget.reserve(threads) as granted:
309
+ run(chunk, engine_path, analysis_file, depth=depth, threads=granted, should_stop=should_stop,
310
+ progress=progress and (lambda i, *rest, at=start: progress(at + i, *rest)))
311
+ if mine:
312
+ if on_mine:
313
+ on_mine('start', None)
314
+ try:
315
+ with engines.POOL.budget.reserve(threads) as granted:
316
+ pack, mined = my_puzzles.run(games_file, analysis_file, pack_file=pack_file, engine_path=engine_path,
317
+ threads=granted, progress=mine_progress)
318
+ except Exception as exc: # a failed mine never hides the analysis itself
319
+ if not on_mine:
320
+ raise
321
+ on_mine('failed', exc)
322
+ else:
323
+ total += mined
324
+ if on_mine:
325
+ on_mine('done', (pack, mined))
326
+ if should_stop():
327
+ break
328
+ return pack, total
329
+
330
+
331
+ def main(argv=None):
332
+ from torre import cli as torre
333
+ return torre.main(['analyze', *(sys.argv[1:] if argv is None else argv)])
334
+
335
+
336
+ if __name__ == "__main__":
337
+ raise SystemExit(main())
@@ -0,0 +1,195 @@
1
+ """Boards as the app sees them: a position from a start and a move list, what the board page
2
+ draws for it (state), and games read from PGN."""
3
+ import io
4
+
5
+ import chess
6
+ import chess.pgn
7
+
8
+ from torre.analysis import opening_book
9
+ from torre.server.routes import BadRequest
10
+
11
+
12
+ def moves_of(payload):
13
+ """The request's "moves": a list of UCI strings (none when absent)."""
14
+ moves = payload.get('moves', [])
15
+ if not isinstance(moves, list) or not all(isinstance(uci, str) for uci in moves):
16
+ raise BadRequest('"moves" must be a list of moves.')
17
+ return moves
18
+
19
+
20
+ def position(payload):
21
+ fen = payload.get('initialFen') or chess.STARTING_FEN
22
+ if not isinstance(fen, str):
23
+ raise BadRequest('This position is not a valid chess position.')
24
+ board = chess.Board(fen)
25
+ if not board.is_valid():
26
+ raise ValueError('This position is not a valid chess position.')
27
+ for uci in moves_of(payload):
28
+ move = chess.Move.from_uci(uci)
29
+ if move not in board.legal_moves:
30
+ raise ValueError('The move history contains an illegal move.')
31
+ board.push(move)
32
+ return board
33
+
34
+
35
+ def line_sans(payload):
36
+ """SAN for a line of UCI moves, cut at the first illegal one (with an error)."""
37
+ board = position({'initialFen': payload.get('initialFen')})
38
+ moves = []
39
+ for uci in moves_of(payload):
40
+ try:
41
+ move = chess.Move.from_uci(uci)
42
+ except (ValueError, TypeError):
43
+ move = None
44
+ if move is None or move not in board.legal_moves:
45
+ return {'moves': moves, 'error': 'This line contains an illegal move. It was cut at the last legal one.'}
46
+ moves.append({'uci': move.uci(), 'san': board.san(move)})
47
+ board.push(move)
48
+ return {'moves': moves}
49
+
50
+
51
+ def illegal_reason(board, from_square, to_square):
52
+ """Why the side to move cannot play from `from_square` to `to_square`, as a rule a learner can
53
+ read: (reason, details) or None when the move is legal or there is nothing to explain (an empty
54
+ square, the other side's piece, or the mover's own piece in the way, which selects it instead).
55
+
56
+ Reasons: pinned (the piece shields its king from `attacker`), inCheck (the king is in check from
57
+ `attacker` and this does not answer it), kingAttacked (the king would step onto a square
58
+ `attacker` covers), exposesKing (it would uncover the king to `attacker`), castleInCheck,
59
+ castleThroughCheck, castleRights, castleBlocked, pathBlocked (`blocker` stands in the way),
60
+ pawnForward (pawns capture diagonally, never straight ahead), pawnDiagonal (a pawn moves
61
+ diagonally only to capture), pawnDouble (two squares only from the starting rank), movement
62
+ (that piece never moves that way)."""
63
+ piece = board.piece_at(from_square)
64
+ if piece is None or piece.color != board.turn:
65
+ return None
66
+ target = board.piece_at(to_square)
67
+ if target is not None and target.color == board.turn:
68
+ return None
69
+ king = board.king(board.turn)
70
+ name = chess.piece_name(piece.piece_type)
71
+ moves = [m for m in (chess.Move(from_square, to_square, promotion=p) for p in (None, chess.QUEEN)) if board.is_pseudo_legal(m)]
72
+ if any(board.is_legal(m) for m in moves) or (board.piece_type_at(from_square) == chess.KING and any(
73
+ m.from_square == from_square and m.to_square == to_square for m in board.generate_castling_moves())):
74
+ return None
75
+ castle = piece.piece_type == chess.KING and chess.square_rank(from_square) == chess.square_rank(to_square) \
76
+ and abs(chess.square_file(from_square) - chess.square_file(to_square)) == 2
77
+ if castle:
78
+ rook_file = 7 if chess.square_file(to_square) > chess.square_file(from_square) else 0
79
+ rook = chess.square(rook_file, chess.square_rank(from_square))
80
+ if not board.has_castling_rights(board.turn) or not (board.castling_rights & chess.BB_SQUARES[rook]):
81
+ return 'castleRights', {}
82
+ if board.is_check():
83
+ return 'castleInCheck', {}
84
+ step = 1 if rook_file == 7 else -1
85
+ between = range(chess.square_file(from_square) + step, rook_file, step)
86
+ if any(board.piece_at(chess.square(f, chess.square_rank(from_square))) for f in between):
87
+ return 'castleBlocked', {}
88
+ return 'castleThroughCheck', {}
89
+ if moves:
90
+ move = moves[0]
91
+ after = board.copy(stack=False)
92
+ after.push(move)
93
+ king_after = after.king(board.turn)
94
+ attackers = sorted(after.attackers(not board.turn, king_after))
95
+ attacker = {'attacker': chess.square_name(attackers[0])} if attackers else {}
96
+ if piece.piece_type == chess.KING:
97
+ return 'kingAttacked', attacker
98
+ if board.is_check():
99
+ return 'inCheck', {'attacker': chess.square_name(sorted(board.checkers())[0])}
100
+ if board.is_pinned(board.turn, from_square):
101
+ return 'pinned', {'piece': name, **attacker}
102
+ return 'exposesKing', attacker
103
+ if piece.piece_type == chess.PAWN:
104
+ forward = 8 if board.turn == chess.WHITE else -8
105
+ start_rank = 1 if board.turn == chess.WHITE else 6
106
+ files = chess.square_file(to_square) - chess.square_file(from_square)
107
+ if files == 0 and to_square - from_square in (forward, 2 * forward):
108
+ if to_square - from_square == 2 * forward and chess.square_rank(from_square) != start_rank:
109
+ return 'pawnDouble', {}
110
+ return 'pawnForward', {}
111
+ if abs(files) == 1 and to_square - from_square in (forward - 1, forward + 1):
112
+ return 'pawnDiagonal', {}
113
+ return 'movement', {'piece': name}
114
+ # A slider aimed along its own line, with something between.
115
+ if piece.piece_type in (chess.BISHOP, chess.ROOK, chess.QUEEN) and to_square in chess.SquareSet(chess.BB_RAYS[from_square][to_square]):
116
+ diagonal = chess.square_file(from_square) != chess.square_file(to_square) and chess.square_rank(from_square) != chess.square_rank(to_square)
117
+ fits = piece.piece_type == chess.QUEEN or (piece.piece_type == chess.BISHOP) == diagonal
118
+ between = chess.SquareSet(chess.between(from_square, to_square)) & board.occupied
119
+ if fits and between:
120
+ return 'pathBlocked', {'piece': name, 'blocker': chess.square_name(min(between, key=lambda s: chess.square_distance(s, from_square)))}
121
+ return 'movement', {'piece': name}
122
+
123
+
124
+ def board_guidance(board):
125
+ """Attacks describe control; planning paths also respect blockers and king safety."""
126
+ plans = {}
127
+ for color in (chess.WHITE, chess.BLACK):
128
+ hypothetical = board.copy(stack=False)
129
+ hypothetical.turn = color
130
+ if color != board.turn:
131
+ hypothetical.ep_square = None
132
+ for move in hypothetical.legal_moves:
133
+ target = hypothetical.piece_at(move.to_square)
134
+ if target and target.piece_type == chess.KING:
135
+ continue
136
+ origin = chess.square_name(move.from_square)
137
+ destination = chess.square_name(move.to_square)
138
+ if destination not in plans.setdefault(origin, []):
139
+ plans[origin].append(destination)
140
+ control = {chess.square_name(square): {
141
+ 'white': [chess.square_name(s) for s in board.attackers(chess.WHITE, square)],
142
+ 'black': [chess.square_name(s) for s in board.attackers(chess.BLACK, square)],
143
+ } for square in chess.SQUARES}
144
+ return {'plans': plans, 'control': control}
145
+
146
+
147
+ def state(board):
148
+ outcome = board.outcome(claim_draw=True)
149
+ return {
150
+ **board_guidance(board),
151
+ 'fen': board.fen(), 'turn': 'white' if board.turn else 'black',
152
+ 'pieces': {chess.square_name(s): p.symbol() for s, p in board.piece_map().items()},
153
+ 'legal': [m.uci() for m in board.legal_moves],
154
+ 'check': chess.square_name(board.king(board.turn)) if board.is_check() else None,
155
+ 'result': outcome.result() if outcome else None,
156
+ 'termination': outcome.termination.name.replace('_', ' ').lower() if outcome else None,
157
+ }
158
+
159
+
160
+ def parse_pgn(pgn):
161
+ if not isinstance(pgn, str) or not pgn.strip():
162
+ raise ValueError('Paste a PGN game to import.')
163
+ game = chess.pgn.read_game(io.StringIO(pgn))
164
+ if game is None or game.errors:
165
+ raise ValueError('Could not read this PGN. Check the headers and move notation.')
166
+ board = game.board()
167
+ initial = board.fen()
168
+ if not board.is_valid():
169
+ raise ValueError('The PGN starts from an invalid position.')
170
+ moves = []
171
+ for node in game.mainline():
172
+ move, clock = node.move, node.clock()
173
+ moves.append({'uci': move.uci(), 'san': board.san(move), **({'clock': round(clock, 1)} if clock is not None else {})})
174
+ board.push(move)
175
+ if not moves and not pgn.lstrip().startswith('['):
176
+ raise ValueError('No chess moves were found. Paste PGN headers and move notation.')
177
+ return {'initialFen': initial, 'moves': moves, 'headers': dict(game.headers), 'opening': opening_book.recognize(game)}
178
+
179
+
180
+ def with_clocks(detail, record):
181
+ """Clocks for a game whose PGN has none, from the chess.com timestamps saved with it (tenths of a
182
+ second left after each move, from the extension export and the callback API)."""
183
+ stamps, moves = record.get('move_timestamps'), detail['moves']
184
+ if isinstance(stamps, str): # the callback API sends "5991,5980,...", the extension a list
185
+ try:
186
+ stamps = [float(stamp) for stamp in stamps.split(',')]
187
+ except ValueError:
188
+ return detail
189
+ # Live games carry one more value than moves, after the last: each move's clock is still in order.
190
+ if not isinstance(stamps, list) or len(stamps) not in (len(moves), len(moves) + 1) or any('clock' in move for move in moves):
191
+ return detail
192
+ stamps = stamps[:len(moves)]
193
+ if not all(isinstance(stamp, (int, float)) and stamp >= 0 for stamp in stamps):
194
+ return detail
195
+ return {**detail, 'moves': [{**move, 'clock': round(stamp / 10, 1)} for move, stamp in zip(moves, stamps)]}
@@ -0,0 +1,79 @@
1
+ """How a game against a bot was really played, phase by phase: the after-game card that shows
2
+ whether the bot kept to the strength it was set to.
3
+
4
+ A bot plays every move at the rating it was given (one rating, or one per phase; see
5
+ api_board._phase_elo), and weak bots now and then play a deliberate weaker move (a "slip",
6
+ engines.strength_options). Neither changes during a game on its own. This module puts numbers
7
+ on that, from the engine's review of the finished game:
8
+
9
+ phases accuracy and errors for you and the bot in the opening, middlegame and endgame
10
+ (game_stats.position_phase; Lichess accuracy, game_stats.aggregate_accuracy)
11
+ slips the bot's deliberate weaker moves and how each turned out: one can land on a
12
+ good move by chance, which is why a weak bot sometimes looks strong
13
+ ratings the rating the bot was set to in each phase it played
14
+ retry your costliest mistake, with the position before it, to play again from there
15
+
16
+ All evals are White-POV [cp, mate] pairs, one per position (the start and after every move).
17
+ """
18
+ import chess
19
+
20
+ from torre.analysis import game_stats
21
+ from torre.analysis import scoring
22
+ SIDES = ('you', 'bot')
23
+
24
+
25
+ def _pair(ev):
26
+ """An engine_lines entry or a [cp, mate] pair as (cp, mate), mate taking the place of cp."""
27
+ if isinstance(ev, dict):
28
+ return (None, ev['mate']) if ev.get('mate') is not None else (ev.get('cp'), None)
29
+ return tuple(ev)
30
+
31
+
32
+ def report(initial_fen, ucis, player_color, evals, notes=()):
33
+ """The card for a finished game. `evals` holds len(ucis) + 1 White-POV evals; `notes` the
34
+ bot's own record of its moves ({ply, slip, elo}), as the play page saved them."""
35
+ board = chess.Board(initial_fen)
36
+ evals = [_pair(ev) for ev in evals]
37
+ if len(evals) != len(ucis) + 1:
38
+ raise ValueError('The review does not cover the whole game.')
39
+ you = chess.WHITE if player_color == 'white' else chess.BLACK
40
+ win = [game_stats.win_pct(*ev) for ev in evals]
41
+ weights = game_stats.volatility_weights(win)
42
+ by_ply = {n['ply']: n for n in notes if isinstance(n, dict) and isinstance(n.get('ply'), int)}
43
+ rows = {phase: {side: [] for side in SIDES} for phase in game_stats.PHASES}
44
+ slips, ratings, phase, worst = [], {}, None, None
45
+ for i, uci in enumerate(ucis):
46
+ move = chess.Move.from_uci(uci)
47
+ phase = game_stats.position_phase(board, phase)
48
+ mover = board.turn
49
+ side = 'you' if mover == you else 'bot'
50
+ before, after = (win[i], win[i + 1]) if mover == chess.WHITE else (100 - win[i], 100 - win[i + 1])
51
+ judged = scoring.judge(evals[i], evals[i + 1], mover == chess.WHITE)
52
+ rows[phase][side].append({'accuracy': game_stats.move_accuracy(before, after), 'weight': weights[i], 'class': judged})
53
+ if side == 'you' and judged in ('mistake', 'blunder') and (worst is None or before - after > worst['drop']):
54
+ worst = {'ply': i + 1, 'san': board.san(move), 'class': judged, 'fen': board.fen(), 'drop': before - after}
55
+ note = by_ply.get(i + 1)
56
+ if side == 'bot' and note:
57
+ if isinstance(note.get('elo'), int):
58
+ ratings.setdefault(phase, set()).add(note['elo'])
59
+ if note.get('slip'):
60
+ slips.append({'ply': i + 1, 'san': board.san(move), 'phase': phase, 'class': judged})
61
+ board.push(move)
62
+
63
+ def summary(moves):
64
+ if not moves:
65
+ return None
66
+ accuracy = game_stats.aggregate_accuracy([(m['accuracy'], m['weight']) for m in moves])
67
+ return {'moves': len(moves), 'accuracy': round(accuracy, 1),
68
+ **{e: sum(m['class'] == e for m in moves) for e in game_stats.ERRORS}}
69
+
70
+ overall = {side: summary([m for phase in game_stats.PHASES for m in rows[phase][side]]) for side in SIDES}
71
+ return {
72
+ 'phases': {phase: {side: summary(rows[phase][side]) for side in SIDES} for phase in game_stats.PHASES},
73
+ 'overall': overall,
74
+ 'slips': slips,
75
+ # A slip that came out fine (no error by the judgment rules) is luck, not a stronger bot.
76
+ 'luckySlips': sum(1 for s in slips if s['class'] is None),
77
+ 'ratings': {phase: sorted(values) for phase, values in ratings.items()},
78
+ 'retry': {k: v for k, v in worst.items() if k != 'drop'} if worst else None,
79
+ }