spinners.py 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531
  1. #!/usr/bin/env python
  2. # License: GPLv3 Copyright: 2021, Kovid Goyal <kovid at kovidgoyal.net>
  3. from typing import Dict, Sequence
  4. from kitty.fast_data_types import monotonic
  5. from kitty.typing import TypedDict
  6. class SpinnerDef(TypedDict):
  7. interval: int
  8. frames: Sequence[str]
  9. # Spinner definitions are from
  10. # https://raw.githubusercontent.com/sindresorhus/cli-spinners/main/spinners.json
  11. spinners: Dict[str, SpinnerDef] = { # {{{
  12. "dots": {
  13. "interval": 80,
  14. "frames": ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"]
  15. },
  16. "dots2": {
  17. "interval": 80,
  18. "frames": ["⣾", "⣽", "⣻", "⢿", "⡿", "⣟", "⣯", "⣷"]
  19. },
  20. "dots3": {
  21. "interval": 80,
  22. "frames": ["⠋", "⠙", "⠚", "⠞", "⠖", "⠦", "⠴", "⠲", "⠳", "⠓"]
  23. },
  24. "dots4": {
  25. "interval":
  26. 80,
  27. "frames":
  28. ["⠄", "⠆", "⠇", "⠋", "⠙", "⠸", "⠰", "⠠", "⠰", "⠸", "⠙", "⠋", "⠇", "⠆"]
  29. },
  30. "dots5": {
  31. "interval":
  32. 80,
  33. "frames": [
  34. "⠋", "⠙", "⠚", "⠒", "⠂", "⠂", "⠒", "⠲", "⠴", "⠦", "⠖", "⠒", "⠐",
  35. "⠐", "⠒", "⠓", "⠋"
  36. ]
  37. },
  38. "dots6": {
  39. "interval":
  40. 80,
  41. "frames": [
  42. "⠁", "⠉", "⠙", "⠚", "⠒", "⠂", "⠂", "⠒", "⠲", "⠴", "⠤", "⠄", "⠄",
  43. "⠤", "⠴", "⠲", "⠒", "⠂", "⠂", "⠒", "⠚", "⠙", "⠉", "⠁"
  44. ]
  45. },
  46. "dots7": {
  47. "interval":
  48. 80,
  49. "frames": [
  50. "⠈", "⠉", "⠋", "⠓", "⠒", "⠐", "⠐", "⠒", "⠖", "⠦", "⠤", "⠠", "⠠",
  51. "⠤", "⠦", "⠖", "⠒", "⠐", "⠐", "⠒", "⠓", "⠋", "⠉", "⠈"
  52. ]
  53. },
  54. "dots8": {
  55. "interval":
  56. 80,
  57. "frames": [
  58. "⠁", "⠁", "⠉", "⠙", "⠚", "⠒", "⠂", "⠂", "⠒", "⠲", "⠴", "⠤", "⠄",
  59. "⠄", "⠤", "⠠", "⠠", "⠤", "⠦", "⠖", "⠒", "⠐", "⠐", "⠒", "⠓", "⠋",
  60. "⠉", "⠈", "⠈"
  61. ]
  62. },
  63. "dots9": {
  64. "interval": 80,
  65. "frames": ["⢹", "⢺", "⢼", "⣸", "⣇", "⡧", "⡗", "⡏"]
  66. },
  67. "dots10": {
  68. "interval": 80,
  69. "frames": ["⢄", "⢂", "⢁", "⡁", "⡈", "⡐", "⡠"]
  70. },
  71. "dots11": {
  72. "interval": 100,
  73. "frames": ["⠁", "⠂", "⠄", "⡀", "⢀", "⠠", "⠐", "⠈"]
  74. },
  75. "dots12": {
  76. "interval":
  77. 80,
  78. "frames": [
  79. "⢀⠀", "⡀⠀", "⠄⠀", "⢂⠀", "⡂⠀", "⠅⠀", "⢃⠀", "⡃⠀", "⠍⠀", "⢋⠀", "⡋⠀",
  80. "⠍⠁", "⢋⠁", "⡋⠁", "⠍⠉", "⠋⠉", "⠋⠉", "⠉⠙", "⠉⠙", "⠉⠩", "⠈⢙", "⠈⡙",
  81. "⢈⠩", "⡀⢙", "⠄⡙", "⢂⠩", "⡂⢘", "⠅⡘", "⢃⠨", "⡃⢐", "⠍⡐", "⢋⠠", "⡋⢀",
  82. "⠍⡁", "⢋⠁", "⡋⠁", "⠍⠉", "⠋⠉", "⠋⠉", "⠉⠙", "⠉⠙", "⠉⠩", "⠈⢙", "⠈⡙",
  83. "⠈⠩", "⠀⢙", "⠀⡙", "⠀⠩", "⠀⢘", "⠀⡘", "⠀⠨", "⠀⢐", "⠀⡐", "⠀⠠", "⠀⢀",
  84. "⠀⡀"
  85. ]
  86. },
  87. "dots8Bit": {
  88. "interval":
  89. 80,
  90. "frames": [
  91. "⠀", "⠁", "⠂", "⠃", "⠄", "⠅", "⠆", "⠇", "⡀", "⡁", "⡂", "⡃", "⡄",
  92. "⡅", "⡆", "⡇", "⠈", "⠉", "⠊", "⠋", "⠌", "⠍", "⠎", "⠏", "⡈", "⡉",
  93. "⡊", "⡋", "⡌", "⡍", "⡎", "⡏", "⠐", "⠑", "⠒", "⠓", "⠔", "⠕", "⠖",
  94. "⠗", "⡐", "⡑", "⡒", "⡓", "⡔", "⡕", "⡖", "⡗", "⠘", "⠙", "⠚", "⠛",
  95. "⠜", "⠝", "⠞", "⠟", "⡘", "⡙", "⡚", "⡛", "⡜", "⡝", "⡞", "⡟", "⠠",
  96. "⠡", "⠢", "⠣", "⠤", "⠥", "⠦", "⠧", "⡠", "⡡", "⡢", "⡣", "⡤", "⡥",
  97. "⡦", "⡧", "⠨", "⠩", "⠪", "⠫", "⠬", "⠭", "⠮", "⠯", "⡨", "⡩", "⡪",
  98. "⡫", "⡬", "⡭", "⡮", "⡯", "⠰", "⠱", "⠲", "⠳", "⠴", "⠵", "⠶", "⠷",
  99. "⡰", "⡱", "⡲", "⡳", "⡴", "⡵", "⡶", "⡷", "⠸", "⠹", "⠺", "⠻", "⠼",
  100. "⠽", "⠾", "⠿", "⡸", "⡹", "⡺", "⡻", "⡼", "⡽", "⡾", "⡿", "⢀", "⢁",
  101. "⢂", "⢃", "⢄", "⢅", "⢆", "⢇", "⣀", "⣁", "⣂", "⣃", "⣄", "⣅", "⣆",
  102. "⣇", "⢈", "⢉", "⢊", "⢋", "⢌", "⢍", "⢎", "⢏", "⣈", "⣉", "⣊", "⣋",
  103. "⣌", "⣍", "⣎", "⣏", "⢐", "⢑", "⢒", "⢓", "⢔", "⢕", "⢖", "⢗", "⣐",
  104. "⣑", "⣒", "⣓", "⣔", "⣕", "⣖", "⣗", "⢘", "⢙", "⢚", "⢛", "⢜", "⢝",
  105. "⢞", "⢟", "⣘", "⣙", "⣚", "⣛", "⣜", "⣝", "⣞", "⣟", "⢠", "⢡", "⢢",
  106. "⢣", "⢤", "⢥", "⢦", "⢧", "⣠", "⣡", "⣢", "⣣", "⣤", "⣥", "⣦", "⣧",
  107. "⢨", "⢩", "⢪", "⢫", "⢬", "⢭", "⢮", "⢯", "⣨", "⣩", "⣪", "⣫", "⣬",
  108. "⣭", "⣮", "⣯", "⢰", "⢱", "⢲", "⢳", "⢴", "⢵", "⢶", "⢷", "⣰", "⣱",
  109. "⣲", "⣳", "⣴", "⣵", "⣶", "⣷", "⢸", "⢹", "⢺", "⢻", "⢼", "⢽", "⢾",
  110. "⢿", "⣸", "⣹", "⣺", "⣻", "⣼", "⣽", "⣾", "⣿"
  111. ]
  112. },
  113. "line": {
  114. "interval": 130,
  115. "frames": ["-", "\\", "|", "/"]
  116. },
  117. "line2": {
  118. "interval": 100,
  119. "frames": ["⠂", "-", "–", "—", "–", "-"]
  120. },
  121. "pipe": {
  122. "interval": 100,
  123. "frames": ["┤", "┘", "┴", "└", "├", "┌", "┬", "┐"]
  124. },
  125. "simpleDots": {
  126. "interval": 400,
  127. "frames": [". ", ".. ", "...", " "]
  128. },
  129. "simpleDotsScrolling": {
  130. "interval": 200,
  131. "frames": [". ", ".. ", "...", " ..", " .", " "]
  132. },
  133. "star": {
  134. "interval": 70,
  135. "frames": ["✶", "✸", "✹", "✺", "✹", "✷"]
  136. },
  137. "star2": {
  138. "interval": 80,
  139. "frames": ["+", "x", "*"]
  140. },
  141. "flip": {
  142. "interval": 70,
  143. "frames": ["_", "_", "_", "-", "`", "`", "'", "´", "-", "_", "_", "_"]
  144. },
  145. "hamburger": {
  146. "interval": 100,
  147. "frames": ["☱", "☲", "☴"]
  148. },
  149. "growVertical": {
  150. "interval": 120,
  151. "frames": ["▁", "▃", "▄", "▅", "▆", "▇", "▆", "▅", "▄", "▃"]
  152. },
  153. "growHorizontal": {
  154. "interval": 120,
  155. "frames": ["▏", "▎", "▍", "▌", "▋", "▊", "▉", "▊", "▋", "▌", "▍", "▎"]
  156. },
  157. "balloon": {
  158. "interval": 140,
  159. "frames": [" ", ".", "o", "O", "@", "*", " "]
  160. },
  161. "balloon2": {
  162. "interval": 120,
  163. "frames": [".", "o", "O", "°", "O", "o", "."]
  164. },
  165. "noise": {
  166. "interval": 100,
  167. "frames": ["▓", "▒", "░"]
  168. },
  169. "bounce": {
  170. "interval": 120,
  171. "frames": ["⠁", "⠂", "⠄", "⠂"]
  172. },
  173. "boxBounce": {
  174. "interval": 120,
  175. "frames": ["▖", "▘", "▝", "▗"]
  176. },
  177. "boxBounce2": {
  178. "interval": 100,
  179. "frames": ["▌", "▀", "▐", "▄"]
  180. },
  181. "triangle": {
  182. "interval": 50,
  183. "frames": ["◢", "◣", "◤", "◥"]
  184. },
  185. "arc": {
  186. "interval": 100,
  187. "frames": ["◜", "◠", "◝", "◞", "◡", "◟"]
  188. },
  189. "circle": {
  190. "interval": 120,
  191. "frames": ["◡", "⊙", "◠"]
  192. },
  193. "squareCorners": {
  194. "interval": 180,
  195. "frames": ["◰", "◳", "◲", "◱"]
  196. },
  197. "circleQuarters": {
  198. "interval": 120,
  199. "frames": ["◴", "◷", "◶", "◵"]
  200. },
  201. "circleHalves": {
  202. "interval": 50,
  203. "frames": ["◐", "◓", "◑", "◒"]
  204. },
  205. "squish": {
  206. "interval": 100,
  207. "frames": ["╫", "╪"]
  208. },
  209. "toggle": {
  210. "interval": 250,
  211. "frames": ["⊶", "⊷"]
  212. },
  213. "toggle2": {
  214. "interval": 80,
  215. "frames": ["▫", "▪"]
  216. },
  217. "toggle3": {
  218. "interval": 120,
  219. "frames": ["□", "■"]
  220. },
  221. "toggle4": {
  222. "interval": 100,
  223. "frames": ["■", "□", "▪", "▫"]
  224. },
  225. "toggle5": {
  226. "interval": 100,
  227. "frames": ["▮", "▯"]
  228. },
  229. "toggle6": {
  230. "interval": 300,
  231. "frames": ["ဝ", "၀"]
  232. },
  233. "toggle7": {
  234. "interval": 80,
  235. "frames": ["⦾", "⦿"]
  236. },
  237. "toggle8": {
  238. "interval": 100,
  239. "frames": ["◍", "◌"]
  240. },
  241. "toggle9": {
  242. "interval": 100,
  243. "frames": ["◉", "◎"]
  244. },
  245. "toggle10": {
  246. "interval": 100,
  247. "frames": ["㊂", "㊀", "㊁"]
  248. },
  249. "toggle11": {
  250. "interval": 50,
  251. "frames": ["⧇", "⧆"]
  252. },
  253. "toggle12": {
  254. "interval": 120,
  255. "frames": ["☗", "☖"]
  256. },
  257. "toggle13": {
  258. "interval": 80,
  259. "frames": ["=", "*", "-"]
  260. },
  261. "arrow": {
  262. "interval": 100,
  263. "frames": ["←", "↖", "↑", "↗", "→", "↘", "↓", "↙"]
  264. },
  265. "arrow2": {
  266. "interval": 80,
  267. "frames": ["⬆️ ", "↗️ ", "➡️ ", "↘️ ", "⬇️ ", "↙️ ", "⬅️ ", "↖️ "]
  268. },
  269. "arrow3": {
  270. "interval": 120,
  271. "frames": ["▹▹▹▹▹", "▸▹▹▹▹", "▹▸▹▹▹", "▹▹▸▹▹", "▹▹▹▸▹", "▹▹▹▹▸"]
  272. },
  273. "bouncingBar": {
  274. "interval":
  275. 80,
  276. "frames": [
  277. "[ ]", "[= ]", "[== ]", "[=== ]", "[ ===]", "[ ==]",
  278. "[ =]", "[ ]", "[ =]", "[ ==]", "[ ===]", "[====]",
  279. "[=== ]", "[== ]", "[= ]"
  280. ]
  281. },
  282. "bouncingBall": {
  283. "interval":
  284. 80,
  285. "frames": [
  286. "( ● )", "( ● )", "( ● )", "( ● )", "( ●)",
  287. "( ● )", "( ● )", "( ● )", "( ● )", "(● )"
  288. ]
  289. },
  290. "smiley": {
  291. "interval": 200,
  292. "frames": ["😄 ", "😝 "]
  293. },
  294. "monkey": {
  295. "interval": 300,
  296. "frames": ["🙈 ", "🙈 ", "🙉 ", "🙊 "]
  297. },
  298. "hearts": {
  299. "interval": 100,
  300. "frames": ["💛 ", "💙 ", "💜 ", "💚 ", "❤️ "]
  301. },
  302. "clock": {
  303. "interval":
  304. 100,
  305. "frames": [
  306. "🕛 ", "🕐 ", "🕑 ", "🕒 ", "🕓 ", "🕔 ", "🕕 ", "🕖 ", "🕗 ", "🕘 ", "🕙 ",
  307. "🕚 "
  308. ]
  309. },
  310. "earth": {
  311. "interval": 180,
  312. "frames": ["🌍 ", "🌎 ", "🌏 "]
  313. },
  314. "material": {
  315. "interval":
  316. 17,
  317. "frames": [
  318. "█▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁", "██▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁",
  319. "███▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁", "████▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁",
  320. "██████▁▁▁▁▁▁▁▁▁▁▁▁▁▁", "██████▁▁▁▁▁▁▁▁▁▁▁▁▁▁",
  321. "███████▁▁▁▁▁▁▁▁▁▁▁▁▁", "████████▁▁▁▁▁▁▁▁▁▁▁▁",
  322. "█████████▁▁▁▁▁▁▁▁▁▁▁", "█████████▁▁▁▁▁▁▁▁▁▁▁",
  323. "██████████▁▁▁▁▁▁▁▁▁▁", "███████████▁▁▁▁▁▁▁▁▁",
  324. "█████████████▁▁▁▁▁▁▁", "██████████████▁▁▁▁▁▁",
  325. "██████████████▁▁▁▁▁▁", "▁██████████████▁▁▁▁▁",
  326. "▁██████████████▁▁▁▁▁", "▁██████████████▁▁▁▁▁",
  327. "▁▁██████████████▁▁▁▁", "▁▁▁██████████████▁▁▁",
  328. "▁▁▁▁█████████████▁▁▁", "▁▁▁▁██████████████▁▁",
  329. "▁▁▁▁██████████████▁▁", "▁▁▁▁▁██████████████▁",
  330. "▁▁▁▁▁██████████████▁", "▁▁▁▁▁██████████████▁",
  331. "▁▁▁▁▁▁██████████████", "▁▁▁▁▁▁██████████████",
  332. "▁▁▁▁▁▁▁█████████████", "▁▁▁▁▁▁▁█████████████",
  333. "▁▁▁▁▁▁▁▁████████████", "▁▁▁▁▁▁▁▁████████████",
  334. "▁▁▁▁▁▁▁▁▁███████████", "▁▁▁▁▁▁▁▁▁███████████",
  335. "▁▁▁▁▁▁▁▁▁▁██████████", "▁▁▁▁▁▁▁▁▁▁██████████",
  336. "▁▁▁▁▁▁▁▁▁▁▁▁████████", "▁▁▁▁▁▁▁▁▁▁▁▁▁███████",
  337. "▁▁▁▁▁▁▁▁▁▁▁▁▁▁██████", "▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█████",
  338. "▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█████", "█▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁████",
  339. "██▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁███", "██▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁███",
  340. "███▁▁▁▁▁▁▁▁▁▁▁▁▁▁███", "████▁▁▁▁▁▁▁▁▁▁▁▁▁▁██",
  341. "█████▁▁▁▁▁▁▁▁▁▁▁▁▁▁█", "█████▁▁▁▁▁▁▁▁▁▁▁▁▁▁█",
  342. "██████▁▁▁▁▁▁▁▁▁▁▁▁▁█", "████████▁▁▁▁▁▁▁▁▁▁▁▁",
  343. "█████████▁▁▁▁▁▁▁▁▁▁▁", "█████████▁▁▁▁▁▁▁▁▁▁▁",
  344. "█████████▁▁▁▁▁▁▁▁▁▁▁", "█████████▁▁▁▁▁▁▁▁▁▁▁",
  345. "███████████▁▁▁▁▁▁▁▁▁", "████████████▁▁▁▁▁▁▁▁",
  346. "████████████▁▁▁▁▁▁▁▁", "██████████████▁▁▁▁▁▁",
  347. "██████████████▁▁▁▁▁▁", "▁██████████████▁▁▁▁▁",
  348. "▁██████████████▁▁▁▁▁", "▁▁▁█████████████▁▁▁▁",
  349. "▁▁▁▁▁████████████▁▁▁", "▁▁▁▁▁████████████▁▁▁",
  350. "▁▁▁▁▁▁███████████▁▁▁", "▁▁▁▁▁▁▁▁█████████▁▁▁",
  351. "▁▁▁▁▁▁▁▁█████████▁▁▁", "▁▁▁▁▁▁▁▁▁█████████▁▁",
  352. "▁▁▁▁▁▁▁▁▁█████████▁▁", "▁▁▁▁▁▁▁▁▁▁█████████▁",
  353. "▁▁▁▁▁▁▁▁▁▁▁████████▁", "▁▁▁▁▁▁▁▁▁▁▁████████▁",
  354. "▁▁▁▁▁▁▁▁▁▁▁▁███████▁", "▁▁▁▁▁▁▁▁▁▁▁▁███████▁",
  355. "▁▁▁▁▁▁▁▁▁▁▁▁▁███████", "▁▁▁▁▁▁▁▁▁▁▁▁▁███████",
  356. "▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█████", "▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁████",
  357. "▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁████", "▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁████",
  358. "▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁███", "▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁███",
  359. "▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁██", "▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁██",
  360. "▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁██", "▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█",
  361. "▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█", "▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█",
  362. "▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁", "▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁",
  363. "▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁", "▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁"
  364. ]
  365. },
  366. "moon": {
  367. "interval": 80,
  368. "frames": ["🌑 ", "🌒 ", "🌓 ", "🌔 ", "🌕 ", "🌖 ", "🌗 ", "🌘 "]
  369. },
  370. "runner": {
  371. "interval": 140,
  372. "frames": ["🚶 ", "🏃 "]
  373. },
  374. "pong": {
  375. "interval":
  376. 80,
  377. "frames": [
  378. "▐⠂ ▌", "▐⠈ ▌", "▐ ⠂ ▌", "▐ ⠠ ▌",
  379. "▐ ⡀ ▌", "▐ ⠠ ▌", "▐ ⠂ ▌", "▐ ⠈ ▌",
  380. "▐ ⠂ ▌", "▐ ⠠ ▌", "▐ ⡀ ▌", "▐ ⠠ ▌",
  381. "▐ ⠂ ▌", "▐ ⠈ ▌", "▐ ⠂▌", "▐ ⠠▌",
  382. "▐ ⡀▌", "▐ ⠠ ▌", "▐ ⠂ ▌", "▐ ⠈ ▌",
  383. "▐ ⠂ ▌", "▐ ⠠ ▌", "▐ ⡀ ▌", "▐ ⠠ ▌",
  384. "▐ ⠂ ▌", "▐ ⠈ ▌", "▐ ⠂ ▌", "▐ ⠠ ▌",
  385. "▐ ⡀ ▌", "▐⠠ ▌"
  386. ]
  387. },
  388. "shark": {
  389. "interval":
  390. 120,
  391. "frames": [
  392. "▐|\\____________▌", "▐_|\\___________▌", "▐__|\\__________▌",
  393. "▐___|\\_________▌", "▐____|\\________▌", "▐_____|\\_______▌",
  394. "▐______|\\______▌", "▐_______|\\_____▌", "▐________|\\____▌",
  395. "▐_________|\\___▌", "▐__________|\\__▌", "▐___________|\\_▌",
  396. "▐____________|\\▌", "▐____________/|▌", "▐___________/|_▌",
  397. "▐__________/|__▌", "▐_________/|___▌", "▐________/|____▌",
  398. "▐_______/|_____▌", "▐______/|______▌", "▐_____/|_______▌",
  399. "▐____/|________▌", "▐___/|_________▌", "▐__/|__________▌",
  400. "▐_/|___________▌", "▐/|____________▌"
  401. ]
  402. },
  403. "dqpb": {
  404. "interval": 100,
  405. "frames": ["d", "q", "p", "b"]
  406. },
  407. "weather": {
  408. "interval":
  409. 100,
  410. "frames": [
  411. "☀️ ", "☀️ ", "☀️ ", "🌤 ", "⛅️ ", "🌥 ", "☁️ ", "🌧 ", "🌨 ", "🌧 ",
  412. "🌨 ", "🌧 ", "🌨 ", "⛈ ", "🌨 ", "🌧 ", "🌨 ", "☁️ ", "🌥 ", "⛅️ ", "🌤 ",
  413. "☀️ ", "☀️ "
  414. ]
  415. },
  416. "christmas": {
  417. "interval": 400,
  418. "frames": ["🌲", "🎄"]
  419. },
  420. "grenade": {
  421. "interval":
  422. 80,
  423. "frames": [
  424. "، ", "′ ", " ´ ", " ‾ ", " ⸌", " ⸊", " |", " ⁎", " ⁕",
  425. " ෴ ", " ⁓", " ", " ", " "
  426. ]
  427. },
  428. "point": {
  429. "interval": 125,
  430. "frames": ["∙∙∙", "●∙∙", "∙●∙", "∙∙●", "∙∙∙"]
  431. },
  432. "layer": {
  433. "interval": 150,
  434. "frames": ["-", "=", "≡"]
  435. },
  436. "betaWave": {
  437. "interval":
  438. 80,
  439. "frames": [
  440. "ρββββββ", "βρβββββ", "ββρββββ", "βββρβββ", "ββββρββ", "βββββρβ",
  441. "ββββββρ"
  442. ]
  443. },
  444. "fingerDance": {
  445. "interval": 160,
  446. "frames": ["🤘 ", "🤟 ", "🖖 ", "✋ ", "🤚 ", "👆 "]
  447. },
  448. "fistBump": {
  449. "interval":
  450. 80,
  451. "frames": [
  452. "🤜\u3000\u3000\u3000\u3000🤛 ", "🤜\u3000\u3000\u3000\u3000🤛 ",
  453. "🤜\u3000\u3000\u3000\u3000🤛 ", "\u3000🤜\u3000\u3000🤛\u3000 ",
  454. "\u3000\u3000🤜🤛\u3000\u3000 ", "\u3000🤜✨🤛\u3000\u3000 ",
  455. "🤜\u3000✨\u3000🤛\u3000 "
  456. ]
  457. },
  458. "soccerHeader": {
  459. "interval":
  460. 80,
  461. "frames": [
  462. " 🧑⚽️ 🧑 ", "🧑 ⚽️ 🧑 ", "🧑 ⚽️ 🧑 ", "🧑 ⚽️ 🧑 ",
  463. "🧑 ⚽️ 🧑 ", "🧑 ⚽️ 🧑 ", "🧑 ⚽️🧑 ", "🧑 ⚽️ 🧑 ",
  464. "🧑 ⚽️ 🧑 ", "🧑 ⚽️ 🧑 ", "🧑 ⚽️ 🧑 ", "🧑 ⚽️ 🧑 "
  465. ]
  466. },
  467. "mindblown": {
  468. "interval":
  469. 160,
  470. "frames": [
  471. "😐 ", "😐 ", "😮 ", "😮 ", "😦 ", "😦 ", "😧 ", "😧 ", "🤯 ", "💥 ", "✨ ",
  472. "\u3000 ", "\u3000 ", "\u3000 "
  473. ]
  474. },
  475. "speaker": {
  476. "interval": 160,
  477. "frames": ["🔈 ", "🔉 ", "🔊 ", "🔉 "]
  478. },
  479. "orangePulse": {
  480. "interval": 100,
  481. "frames": ["🔸 ", "🔶 ", "🟠 ", "🟠 ", "🔶 "]
  482. },
  483. "bluePulse": {
  484. "interval": 100,
  485. "frames": ["🔹 ", "🔷 ", "🔵 ", "🔵 ", "🔷 "]
  486. },
  487. "orangeBluePulse": {
  488. "interval": 100,
  489. "frames": ["🔸 ", "🔶 ", "🟠 ", "🟠 ", "🔶 ", "🔹 ", "🔷 ", "🔵 ", "🔵 ", "🔷 "]
  490. },
  491. "timeTravel": {
  492. "interval":
  493. 100,
  494. "frames": [
  495. "🕛 ", "🕚 ", "🕙 ", "🕘 ", "🕗 ", "🕖 ", "🕕 ", "🕔 ", "🕓 ", "🕒 ", "🕑 ",
  496. "🕐 "
  497. ]
  498. },
  499. "aesthetic": {
  500. "interval":
  501. 80,
  502. "frames": [
  503. "▰▱▱▱▱▱▱", "▰▰▱▱▱▱▱", "▰▰▰▱▱▱▱", "▰▰▰▰▱▱▱", "▰▰▰▰▰▱▱", "▰▰▰▰▰▰▱",
  504. "▰▰▰▰▰▰▰", "▰▱▱▱▱▱▱"
  505. ]
  506. }
  507. } # }}}
  508. class Spinner:
  509. def __init__(self, name: str = 'dots'):
  510. definition = spinners[name]
  511. self.interval = definition['interval'] / 1000
  512. self.frames = definition['frames']
  513. self.current_frame = -1
  514. self.last_change_at = -self.interval
  515. def __call__(self) -> str:
  516. now = monotonic()
  517. if now - self.last_change_at >= self.interval:
  518. self.last_change_at = now
  519. self.current_frame = (self.current_frame + 1) % len(self.frames)
  520. return self.frames[self.current_frame]