fun_ci 1.2.1 → 2.0.1

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 (228) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +236 -0
  3. data/README.md +182 -59
  4. data/lib/fun_ci/agent/age.rb +15 -0
  5. data/lib/fun_ci/agent/command_support.rb +27 -0
  6. data/lib/fun_ci/agent/commands.rb +27 -0
  7. data/lib/fun_ci/agent/context.rb +10 -0
  8. data/lib/fun_ci/agent/digest.rb +49 -0
  9. data/lib/fun_ci/agent/events.rb +47 -0
  10. data/lib/fun_ci/agent/events_command.rb +61 -0
  11. data/lib/fun_ci/agent/evidence_text.rb +46 -0
  12. data/lib/fun_ci/agent/exit_code.rb +11 -0
  13. data/lib/fun_ci/agent/git.rb +32 -0
  14. data/lib/fun_ci/agent/live_pipeline.rb +35 -0
  15. data/lib/fun_ci/agent/options.rb +75 -0
  16. data/lib/fun_ci/agent/output.rb +81 -0
  17. data/lib/fun_ci/agent/report_stage.rb +71 -0
  18. data/lib/fun_ci/agent/reports.rb +47 -0
  19. data/lib/fun_ci/agent/run_report.rb +30 -0
  20. data/lib/fun_ci/agent/runs_command.rb +34 -0
  21. data/lib/fun_ci/agent/runs_text.rb +27 -0
  22. data/lib/fun_ci/agent/snapshots.rb +39 -0
  23. data/lib/fun_ci/agent/stage_summary.rb +30 -0
  24. data/lib/fun_ci/agent/status_command.rb +36 -0
  25. data/lib/fun_ci/agent/status_json.rb +27 -0
  26. data/lib/fun_ci/agent/status_text.rb +37 -0
  27. data/lib/fun_ci/agent/system_clock.rb +11 -0
  28. data/lib/fun_ci/agent/verdict.rb +32 -0
  29. data/lib/fun_ci/agent/wait_command.rb +71 -0
  30. data/lib/fun_ci/agent/waiting.rb +32 -0
  31. data/lib/fun_ci/agent/why_command.rb +50 -0
  32. data/lib/fun_ci/agent/why_json.rb +35 -0
  33. data/lib/fun_ci/agent/why_text.rb +43 -0
  34. data/lib/fun_ci/cli.rb +72 -94
  35. data/lib/fun_ci/cli_help.rb +65 -0
  36. data/lib/fun_ci/console/board_data.rb +66 -0
  37. data/lib/fun_ci/console/board_heartbeat.rb +40 -0
  38. data/lib/fun_ci/console/console_events.rb +20 -0
  39. data/lib/fun_ci/console/console_log.rb +26 -0
  40. data/lib/fun_ci/console/console_loop.rb +41 -0
  41. data/lib/fun_ci/console/console_session.rb +82 -0
  42. data/lib/fun_ci/console/console_state.rb +42 -0
  43. data/lib/fun_ci/console/key_handler.rb +73 -0
  44. data/lib/fun_ci/console/launcher.rb +43 -0
  45. data/lib/fun_ci/console/milestone_events.rb +38 -0
  46. data/lib/fun_ci/console/milestones.rb +25 -0
  47. data/lib/fun_ci/console/renderer_lookup.rb +51 -0
  48. data/lib/fun_ci/console/renderer_process.rb +60 -0
  49. data/lib/fun_ci/console/run_message.rb +33 -0
  50. data/lib/fun_ci/console/stage_change_detector.rb +32 -0
  51. data/lib/fun_ci/console/stage_events.rb +31 -0
  52. data/lib/fun_ci/console/stop_report.rb +39 -0
  53. data/lib/fun_ci/console/streak_counter.rb +19 -0
  54. data/lib/fun_ci/console/view.rb +47 -0
  55. data/lib/fun_ci/evidence/about.rb +12 -0
  56. data/lib/fun_ci/evidence/about_stage.rb +29 -0
  57. data/lib/fun_ci/evidence/caps.rb +77 -0
  58. data/lib/fun_ci/evidence/catalog.rb +83 -0
  59. data/lib/fun_ci/evidence/collector.rb +95 -0
  60. data/lib/fun_ci/evidence/command_output.rb +45 -0
  61. data/lib/fun_ci/evidence/command_reading.rb +38 -0
  62. data/lib/fun_ci/evidence/command_runner.rb +75 -0
  63. data/lib/fun_ci/evidence/context.rb +21 -0
  64. data/lib/fun_ci/evidence/context_document.rb +29 -0
  65. data/lib/fun_ci/evidence/deadline.rb +15 -0
  66. data/lib/fun_ci/evidence/detection.rb +82 -0
  67. data/lib/fun_ci/evidence/document.rb +59 -0
  68. data/lib/fun_ci/evidence/extract_command.rb +83 -0
  69. data/lib/fun_ci/evidence/extract_options.rb +45 -0
  70. data/lib/fun_ci/evidence/extraction.rb +54 -0
  71. data/lib/fun_ci/evidence/extractors/command.rb +52 -0
  72. data/lib/fun_ci/evidence/extractors/grep.rb +49 -0
  73. data/lib/fun_ci/evidence/extractors/json_log.rb +45 -0
  74. data/lib/fun_ci/evidence/extractors/junit_files.rb +32 -0
  75. data/lib/fun_ci/evidence/extractors/last_lines.rb +25 -0
  76. data/lib/fun_ci/evidence/extractors/log_file.rb +62 -0
  77. data/lib/fun_ci/evidence/extractors/process_tree.rb +51 -0
  78. data/lib/fun_ci/evidence/extractors/section.rb +49 -0
  79. data/lib/fun_ci/evidence/findings.rb +14 -0
  80. data/lib/fun_ci/evidence/line_ranges.rb +21 -0
  81. data/lib/fun_ci/evidence/line_scan.rb +22 -0
  82. data/lib/fun_ci/evidence/log_record.rb +58 -0
  83. data/lib/fun_ci/evidence/masking.rb +55 -0
  84. data/lib/fun_ci/evidence/option_check.rb +53 -0
  85. data/lib/fun_ci/evidence/outcome.rb +15 -0
  86. data/lib/fun_ci/evidence/patterns.rb +22 -0
  87. data/lib/fun_ci/evidence/presets/README.md +7 -0
  88. data/lib/fun_ci/evidence/presets/bun-test.yml +6 -0
  89. data/lib/fun_ci/evidence/presets/cargo-test.yml +6 -0
  90. data/lib/fun_ci/evidence/presets/dart-test.yml +6 -0
  91. data/lib/fun_ci/evidence/presets/deno-test.yml +6 -0
  92. data/lib/fun_ci/evidence/presets/dotnet-test.yml +6 -0
  93. data/lib/fun_ci/evidence/presets/ecs.yml +3 -0
  94. data/lib/fun_ci/evidence/presets/eslint.yml +6 -0
  95. data/lib/fun_ci/evidence/presets/exunit.yml +6 -0
  96. data/lib/fun_ci/evidence/presets/gcc.yml +6 -0
  97. data/lib/fun_ci/evidence/presets/go-build.yml +5 -0
  98. data/lib/fun_ci/evidence/presets/go-test.yml +6 -0
  99. data/lib/fun_ci/evidence/presets/gradle.yml +6 -0
  100. data/lib/fun_ci/evidence/presets/gtest.yml +6 -0
  101. data/lib/fun_ci/evidence/presets/jest.yml +6 -0
  102. data/lib/fun_ci/evidence/presets/logstash.yml +3 -0
  103. data/lib/fun_ci/evidence/presets/maven.yml +6 -0
  104. data/lib/fun_ci/evidence/presets/minitest.yml +6 -0
  105. data/lib/fun_ci/evidence/presets/mocha.yml +6 -0
  106. data/lib/fun_ci/evidence/presets/mypy.yml +6 -0
  107. data/lib/fun_ci/evidence/presets/node-test.yml +6 -0
  108. data/lib/fun_ci/evidence/presets/phpunit.yml +6 -0
  109. data/lib/fun_ci/evidence/presets/pino.yml +5 -0
  110. data/lib/fun_ci/evidence/presets/prove.yml +6 -0
  111. data/lib/fun_ci/evidence/presets/pytest.yml +6 -0
  112. data/lib/fun_ci/evidence/presets/rspec.yml +6 -0
  113. data/lib/fun_ci/evidence/presets/rubocop.yml +6 -0
  114. data/lib/fun_ci/evidence/presets/ruff.yml +6 -0
  115. data/lib/fun_ci/evidence/presets/rustc.yml +6 -0
  116. data/lib/fun_ci/evidence/presets/shellcheck.yml +5 -0
  117. data/lib/fun_ci/evidence/presets/structlog.yml +4 -0
  118. data/lib/fun_ci/evidence/presets/swift-test.yml +5 -0
  119. data/lib/fun_ci/evidence/presets/tsc.yml +6 -0
  120. data/lib/fun_ci/evidence/presets/unittest.yml +6 -0
  121. data/lib/fun_ci/evidence/presets/vitest.yml +6 -0
  122. data/lib/fun_ci/evidence/presets.rb +30 -0
  123. data/lib/fun_ci/evidence/problem.rb +9 -0
  124. data/lib/fun_ci/evidence/process_table.rb +40 -0
  125. data/lib/fun_ci/evidence/saved_run.rb +22 -0
  126. data/lib/fun_ci/evidence/section_walk.rb +49 -0
  127. data/lib/fun_ci/evidence/settings.rb +64 -0
  128. data/lib/fun_ci/evidence/settings_check.rb +78 -0
  129. data/lib/fun_ci/evidence/source.rb +34 -0
  130. data/lib/fun_ci/evidence/sources.rb +21 -0
  131. data/lib/fun_ci/evidence/stage_context.rb +30 -0
  132. data/lib/fun_ci/evidence/stamp.rb +10 -0
  133. data/lib/fun_ci/evidence/start.rb +36 -0
  134. data/lib/fun_ci/evidence/worktree.rb +62 -0
  135. data/lib/fun_ci/persistence/active_runs.rb +69 -0
  136. data/lib/fun_ci/persistence/database.rb +63 -30
  137. data/lib/fun_ci/persistence/null_recorder.rb +25 -0
  138. data/lib/fun_ci/persistence/output_tail.rb +24 -0
  139. data/lib/fun_ci/persistence/pipeline_recorder.rb +78 -32
  140. data/lib/fun_ci/persistence/pipeline_run.rb +26 -17
  141. data/lib/fun_ci/persistence/project_runs.rb +52 -0
  142. data/lib/fun_ci/persistence/raw_outputs.rb +46 -0
  143. data/lib/fun_ci/persistence/retention.rb +25 -0
  144. data/lib/fun_ci/persistence/run_status.rb +31 -0
  145. data/lib/fun_ci/persistence/stage_job.rb +61 -14
  146. data/lib/fun_ci/persistence/state_dir.rb +26 -0
  147. data/lib/fun_ci/persistence/write_trouble.rb +46 -0
  148. data/lib/fun_ci/pipeline/background_fork.rb +42 -0
  149. data/lib/fun_ci/pipeline/command_executor.rb +58 -0
  150. data/lib/fun_ci/pipeline/gate.rb +35 -0
  151. data/lib/fun_ci/pipeline/git_environment.rb +16 -0
  152. data/lib/fun_ci/pipeline/head_part.rb +40 -0
  153. data/lib/fun_ci/pipeline/in_place.rb +17 -0
  154. data/lib/fun_ci/pipeline/output_window.rb +73 -0
  155. data/lib/fun_ci/pipeline/pipeline_forker.rb +18 -16
  156. data/lib/fun_ci/pipeline/process_runner.rb +90 -17
  157. data/lib/fun_ci/pipeline/run_canceller.rb +75 -0
  158. data/lib/fun_ci/pipeline/slot.rb +30 -0
  159. data/lib/fun_ci/pipeline/slot_lock.rb +13 -0
  160. data/lib/fun_ci/pipeline/slot_run.rb +86 -0
  161. data/lib/fun_ci/pipeline/stage_dir.rb +50 -0
  162. data/lib/fun_ci/pipeline/stage_end.rb +70 -0
  163. data/lib/fun_ci/pipeline/stage_execution.rb +67 -0
  164. data/lib/fun_ci/pipeline/stage_runner.rb +42 -65
  165. data/lib/fun_ci/pipeline/stale_pipeline_canceller.rb +16 -33
  166. data/lib/fun_ci/pipeline/tail_segments.rb +60 -0
  167. data/lib/fun_ci/pipeline/test_report.rb +48 -0
  168. data/lib/fun_ci/pipeline/trigger.rb +55 -115
  169. data/lib/fun_ci/pipeline/trigger_command.rb +62 -0
  170. data/lib/fun_ci/pipeline/trigger_params.rb +56 -0
  171. data/lib/fun_ci/pipeline/workspaces.rb +22 -0
  172. data/lib/fun_ci/pipeline/worktree_pool.rb +66 -0
  173. data/lib/fun_ci/pipeline/worktree_prune.rb +49 -0
  174. data/lib/fun_ci/pipeline/worktrees.rb +45 -0
  175. data/lib/fun_ci/setup/agent_instructions.rb +31 -0
  176. data/lib/fun_ci/setup/commands.rb +49 -0
  177. data/lib/fun_ci/setup/git_hooks.rb +20 -0
  178. data/lib/fun_ci/setup/hook_script.rb +47 -0
  179. data/lib/fun_ci/setup/hook_writer.rb +13 -31
  180. data/lib/fun_ci/setup/installer.rb +39 -23
  181. data/lib/fun_ci/setup/legacy_hooks.rb +38 -0
  182. data/lib/fun_ci/setup/project_config.rb +43 -17
  183. data/lib/fun_ci/setup/project_detector.rb +39 -7
  184. data/lib/fun_ci/setup/settings.rb +36 -0
  185. data/lib/fun_ci/setup/setup_checker.rb +18 -12
  186. data/lib/fun_ci/setup/stage_templates/javascript.rb +18 -0
  187. data/lib/fun_ci/setup/stage_templates/managed.rb +24 -0
  188. data/lib/fun_ci/setup/stage_templates/native.rb +25 -0
  189. data/lib/fun_ci/setup/stage_templates/scripting.rb +27 -0
  190. data/lib/fun_ci/setup/stage_templates/shell.rb +16 -0
  191. data/lib/fun_ci/setup/stage_templates.rb +25 -0
  192. data/lib/fun_ci/setup/template_writer.rb +11 -36
  193. data/lib/fun_ci/version.rb +1 -1
  194. data/lib/fun_ci.rb +0 -1
  195. metadata +205 -41
  196. data/exe/fun-ci-trigger +0 -19
  197. data/exe/fun-ci-tui +0 -23
  198. data/lib/fun_ci/animations/celebrate.rb +0 -210
  199. data/lib/fun_ci/animations/explosion.rb +0 -138
  200. data/lib/fun_ci/animations/flash.rb +0 -205
  201. data/lib/fun_ci/animations/idle.rb +0 -127
  202. data/lib/fun_ci/animations/leprechauns.rb +0 -240
  203. data/lib/fun_ci/animations/running.rb +0 -129
  204. data/lib/fun_ci/animations/success.rb +0 -281
  205. data/lib/fun_ci/animations/yay.rb +0 -169
  206. data/lib/fun_ci/persistence/state_machine.rb +0 -50
  207. data/lib/fun_ci/pipeline/background_wrapper.rb +0 -27
  208. data/lib/fun_ci/tui/admin_tui.rb +0 -90
  209. data/lib/fun_ci/tui/animation.rb +0 -49
  210. data/lib/fun_ci/tui/animation_compositor.rb +0 -107
  211. data/lib/fun_ci/tui/animation_frames.rb +0 -112
  212. data/lib/fun_ci/tui/animation_library.rb +0 -46
  213. data/lib/fun_ci/tui/animation_renderer.rb +0 -144
  214. data/lib/fun_ci/tui/ansi.rb +0 -34
  215. data/lib/fun_ci/tui/board_data.rb +0 -53
  216. data/lib/fun_ci/tui/board_renderer.rb +0 -105
  217. data/lib/fun_ci/tui/duration_formatter.rb +0 -24
  218. data/lib/fun_ci/tui/header_animation_manager.rb +0 -71
  219. data/lib/fun_ci/tui/header_animation_player.rb +0 -45
  220. data/lib/fun_ci/tui/key_handler.rb +0 -86
  221. data/lib/fun_ci/tui/looping_animation_player.rb +0 -45
  222. data/lib/fun_ci/tui/relative_time.rb +0 -22
  223. data/lib/fun_ci/tui/row_formatter.rb +0 -108
  224. data/lib/fun_ci/tui/screen.rb +0 -103
  225. data/lib/fun_ci/tui/spinner.rb +0 -24
  226. data/lib/fun_ci/tui/stage_change_detector.rb +0 -58
  227. data/lib/fun_ci/tui/streak_counter.rb +0 -29
  228. data/lib/fun_ci/tui/terminal_input.rb +0 -69
@@ -1,138 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module FunCi
4
- module Animations
5
- module Explosion
6
- # Failure explosion animation — expanding fireball with debris
7
- # Run: ruby exe/animation-player animations/explosion.rb
8
-
9
- r = "\e[1;31m" # bold red
10
- o = "\e[38;5;208m" # orange
11
- y = "\e[1;33m" # bold yellow
12
- w = "\e[1;37m" # bold white
13
- d = "\e[2;31m" # dim red
14
- k = "\e[38;5;52m" # dark red
15
- x = "\e[0m" # reset
16
-
17
- raw_frames = [
18
- # Frame 1 — spark
19
- [
20
- "",
21
- "",
22
- "",
23
- "",
24
- " #{w}*#{x}",
25
- "",
26
- "",
27
- "",
28
- "",
29
- "",
30
- ],
31
- # Frame 2 — ignition
32
- [
33
- "",
34
- "",
35
- "",
36
- " #{y}\\|/#{x}",
37
- " #{w}-#{r}*#{w}-#{x}",
38
- " #{y}/|\\#{x}",
39
- "",
40
- "",
41
- "",
42
- "",
43
- ],
44
- # Frame 3 — small burst
45
- [
46
- "",
47
- "",
48
- " #{o}. * .#{x}",
49
- " #{y}*#{r}(#)#{y}*#{x}",
50
- " #{r}(#{y}*#{w}@@@#{y}*#{r})#{x}",
51
- " #{y}*#{r}(#)#{y}*#{x}",
52
- " #{o}' * '#{x}",
53
- "",
54
- "",
55
- "",
56
- ],
57
- # Frame 4 — expanding fireball
58
- [
59
- "",
60
- " #{o}* . *#{x}",
61
- " #{y}.#{r}* #{o}( ) #{r}*#{y}.#{x}",
62
- " #{r}(#{y}*#{w} @@@@@ #{y}*#{r})#{x}",
63
- " #{r}(#{o}*#{w}@@@#{y}X#{w}@@@#{o}*#{r})#{x}",
64
- " #{r}(#{y}*#{w} @@@@@ #{y}*#{r})#{x}",
65
- " #{y}'#{r}* #{o}( ) #{r}*#{y}'#{x}",
66
- " #{o}* ' *#{x}",
67
- "",
68
- "",
69
- ],
70
- # Frame 5 — full explosion
71
- [
72
- " #{d}. #{o}* * .#{d} .#{x}",
73
- " #{o}* #{y}.#{r}* *#{y}. #{o}*#{x}",
74
- " #{y}. #{r}*#{o}(#{w} @@@@@@@@ #{o})#{r}*#{y} .#{x}",
75
- " #{r}( #{y}*#{w}@@@@#{y}BOOM#{w}@@@@#{y}* #{r})#{x}",
76
- " #{r}(#{o}*#{w}@@@@@@@#{y}X#{w}@@@@@@@#{o}*#{r})#{x}",
77
- " #{r}( #{y}*#{w}@@@@@@@@@@@#{y}* #{r})#{x}",
78
- " #{y}' #{r}*#{o}(#{w} @@@@@@@@ #{o})#{r}*#{y} '#{x}",
79
- " #{o}* #{y}'#{r}* *#{y}' #{o}*#{x}",
80
- " #{d}' #{o}* * '#{d} '#{x}",
81
- "",
82
- ],
83
- # Frame 6 — debris flying out
84
- [
85
- " #{d}.#{x} #{o}*#{x} #{o}*#{x} #{d}.#{x}",
86
- " #{o}. #{y}*#{x} #{d}. .#{x} #{y}* #{o}.#{x}",
87
- " #{y}*#{x} #{r}*#{o}( #{d}::::: #{o})#{r}*#{x} #{y}*#{x}",
88
- " #{r}(#{x} #{y}*#{x} #{d}::#w}@@#{y}X#{w}@@#{d}::#{x} #{y}*#{x} #{r})#{x}",
89
- " #{o}*#{x} #{d}:::#{w}@@@@@@@#{d}:::#{x} #{o}*#{x}",
90
- " #{r}(#{x} #{y}*#{x} #{d}::#{w}@@@@@#{d}::#{x} #{y}*#{x} #{r})#{x}",
91
- " #{y}*#{x} #{r}*#{o}( #{d}::::: #{o})#{r}*#{x} #{y}*#{x}",
92
- " #{o}' #{y}*#{x} #{d}' '#{x} #{y}* #{o}'#{x}",
93
- " #{d}'#{x} #{o}*#{x} #{o}*#{x} #{d}'#{x}",
94
- " #{d}.#{x} #{d}. .#{x} #{d}.#{x}",
95
- ],
96
- # Frame 7 — dissipating smoke
97
- [
98
- " #{d}.#{x} #{d}.#{x} #{d}.#{x} #{d}.#{x}",
99
- " #{d}*#{x} #{d}*#{x}",
100
- " #{d}. #{k}::: #{d}.#{x}",
101
- " #{d}*#{x} #{k}::#{d}.....#{k}::#{x} #{d}*#{x}",
102
- " #{k}:#{d}.. ..#{k}:#{x}",
103
- " #{d}*#{x} #{k}::#{d}.....#{k}::#{x} #{d}*#{x}",
104
- " #{d}' #{k}::: #{d}'#{x}",
105
- " #{d}*#{x} #{d}*#{x}",
106
- " #{d}'#{x} #{d}'#{x} #{d}'#{x} #{d}'#{x}",
107
- "",
108
- ],
109
- # Frame 8 — fading embers
110
- [
111
- "",
112
- " #{d}.#{x} #{d}.#{x}",
113
- "",
114
- " #{k}. . .#{x}",
115
- " #{d}.#{x} #{k}. .#{x} #{d}.#{x}",
116
- " #{k}' ' '#{x}",
117
- "",
118
- " #{d}'#{x} #{d}'#{x}",
119
- "",
120
- "",
121
- ],
122
- ]
123
-
124
- # Pad lines so all rows in each frame have equal stripped length —
125
- # prevents the player's per-line centering from misaligning the art.
126
- max = raw_frames.flatten.map { |l| l.gsub(/\e\[[0-9;]*m/, "").length }.max
127
- raw_frames.each do |frame|
128
- frame.map! { |l| l + " " * (max - l.gsub(/\e\[[0-9;]*m/, "").length) }
129
- end
130
-
131
- DATA = {
132
- name: "Explosion",
133
- fps: 8,
134
- frames: raw_frames
135
- }.freeze
136
- end
137
- end
138
- end
@@ -1,205 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module FunCi
4
- module Animations
5
- module Flash
6
- # Flash of inspiration — dense colour field with jagged lightning bolt
7
- # Run: ruby exe/animation-player animations/flash.rb
8
-
9
- w = "\e[1;37m" # bold white
10
- y = "\e[1;33m" # bold yellow
11
- Y = "\e[33m" # yellow
12
- g = "\e[1;32m" # bold green
13
- G = "\e[32m" # green
14
- d = "\e[2;32m" # dim green
15
- c = "\e[1;36m" # bold cyan
16
- C = "\e[36m" # cyan
17
- D = "\e[2;37m" # dim white
18
- x = "\e[0m" # reset
19
-
20
- raw_frames = [
21
- # Frame 1 — green field, tiny seed
22
- [
23
- " #{d}* . * . * . * . * . * . * . * . * . * . *#{x}",
24
- " #{d}. * . * . * . * . * . * . * . * . * . * .#{x}",
25
- " #{d}* . * . * . * . * . * . * . * . * . * . *#{x}",
26
- " #{d}. * . * . * . * . * . * . * . * . * . * .#{x}",
27
- " #{d}* . * . * . * . * . * . * . * . * . * . *#{x}",
28
- " #{d}. * . * . * . * . #{D}o#{d} . * . * . * . * . .#{x}",
29
- " #{d}* . * . * . * . * . * . * . * . * . * . *#{x}",
30
- " #{d}. * . * . * . * . * . * . * . * . * . * .#{x}",
31
- " #{d}* . * . * . * . * . * . * . * . * . * . *#{x}",
32
- " #{d}. * . * . * . * . * . * . * . * . * . * .#{x}",
33
- " #{d}* . * . * . * . * . * . * . * . * . * . *#{x}",
34
- ],
35
- # Frame 2 — seed brightens, faint bolt flicker
36
- [
37
- " #{d}. * . * . * . * . * . * . * . * . * . * .#{x}",
38
- " #{d}* . * . * . * . * . * . * . * . * . * . *#{x}",
39
- " #{d}. * . * . * . * . #{D}|#{d} . * . * . * . * . .#{x}",
40
- " #{d}* . * . * .#{G} * . *#{D}/#{G}* . *#{d} . * . * . * .#{x}",
41
- " #{d}. * . * . *#{G} . * #{y}*#{G} * . *#{d} . * . * . * .#{x}",
42
- " #{d}* . * . * .#{G} * .#{D}\\#{G}* . * .#{d} * . * . * . *#{x}",
43
- " #{d}. * . * . * . * . #{D}|#{d} . * . * . * . * . .#{x}",
44
- " #{d}* . * . * . * . * . * . * . * . * . * . *#{x}",
45
- " #{d}. * . * . * . * . * . * . * . * . * . * .#{x}",
46
- " #{d}* . * . * . * . * . * . * . * . * . * . *#{x}",
47
- " #{d}. * . * . * . * . * . * . * . * . * . * .#{x}",
48
- ],
49
- # Frame 3 — bolt appears, core ignites
50
- [
51
- " #{d}. * . * . * . * . #{Y}|#{d} . * . * . * . * . .#{x}",
52
- " #{d}* . * . * . * . *#{Y}/#{d}* . * . * . * . * . *#{x}",
53
- " #{d}. * . * .#{G} * . #{g}*#{y}|#{g}*#{G} . #{g}*#{G} . *#{d} . * . * . * .#{x}",
54
- " #{d}* . * . *#{G} . #{g}*#{G} .#{y}\\#{C}*#{G} . #{g}*#{G} .#{d} * . * . * .#{x}",
55
- " #{d}. * . * .#{G} * #{c}*#{Y} . #{w}*#{y}|#{w}*#{Y} . #{c}*#{G} *#{d} . * . * . * .#{x}",
56
- " #{d}* . * . *#{G} . #{g}*#{G} .#{y}/#{C}*#{G} . #{g}*#{G} .#{d} * . * . * .#{x}",
57
- " #{d}. * . * .#{G} * . #{g}*#{y}|#{g}*#{G} . #{g}*#{G} . *#{d} . * . * . * .#{x}",
58
- " #{d}* . * . * . * .#{Y}\\#{d}* . * . * . * . * . * .#{x}",
59
- " #{d}. * . * . * . * . #{Y}|#{d} . * . * . * . * . .#{x}",
60
- " #{d}* . * . * . * . * . * . * . * . * . * . *#{x}",
61
- " #{d}. * . * . * . * . * . * . * . * . * . * .#{x}",
62
- ],
63
- # Frame 4 — bolt strikes through, core expands
64
- [
65
- " #{d}. * . * . * .#{G} *#{g} .#{y}|#{g} .#{G} * .#{d} * . * . * . * .#{x}",
66
- " #{d}* . *#{G} . * . #{g}*#{G} .#{y}/#{g}*#{G} . #{g}*#{G} . #{g}*#{G} . *#{d} . * . * .#{x}",
67
- " #{d}. * .#{G} * #{g}*#{c} . #{c}*#{C} .#{y}|#{c}*#{C} . #{c}*#{C} . #{c}*#{g} . *#{d} . * . .#{x}",
68
- " #{d}* . #{G}.#{g} *#{c} .#{C} *#{y} .#{Y} *#{y}\\#{w} @#{y} @#{Y} *#{y} .#{C} *#{c} .#{g} *#{G} .#{d} * . *#{x}",
69
- " #{d}. * #{g}*#{c} .#{C} *#{y} .#{Y} *#{w} @#{w}##{y}|#{w}##{w}@#{Y} *#{y} .#{C} *#{c} .#{g} *#{d} . * .#{x}",
70
- " #{d}* . #{G}.#{g} *#{c} .#{C} *#{y} .#{Y} *#{y}/#{w} @#{y} @#{Y} *#{y} .#{C} *#{c} .#{g} *#{G} .#{d} * . *#{x}",
71
- " #{d}. * .#{G} * #{g}*#{c} . #{c}*#{C} .#{y}|#{c}*#{C} . #{c}*#{C} . #{c}*#{g} . *#{d} . * . .#{x}",
72
- " #{d}* . *#{G} . * . #{g}*#{G} .#{y}\\#{g}*#{G} . #{g}*#{G} . #{g}*#{G} . *#{d} . * . * .#{x}",
73
- " #{d}. * . * . * . * . #{Y}|#{d} . * . * . * . * . .#{x}",
74
- " #{d}* . * . * . * . *#{Y}/#{d}* . * . * . * . * . *#{x}",
75
- " #{d}. * . * . * . * . #{Y}|#{d} . * . * . * . * . .#{x}",
76
- ],
77
- # Frame 5 — FLASH! bolt blazes, white-hot core
78
- [
79
- " #{d}* .#{G} *#{g} .#{G} *#{g} .#{G} *#{w}|#{G} *#{g} .#{G} *#{g} .#{G} *#{g} .#{G} * #{g}.#{d} * . *#{x}",
80
- " #{G}. *#{g} .#{c} *#{g} .#{c} *#{g} .#{w}/#{C} .#{c} *#{g} .#{c} *#{g} .#{c} *#{g} .#{G} * . *#{x}",
81
- " #{g}*#{c} . *#{C} .#{c} *#{C} .#{c} *#{w}|#{Y} *#{y} .#{Y} *#{c} .#{C} *#{c} .#{C} *#{c} . #{g}*#{d} .#{x}",
82
- " #{c}.#{C} * .#{y} *#{Y} .#{y} *#{Y} .#{w}\\#{w} @#{w} @#{w} @#{Y} *#{y} .#{Y} *#{y} .#{C} *#{c} . *#{g} .#{x}",
83
- " #{c}*#{C} .#{y} *#{Y} .#{w} *#{w} @#{w}##{w}@#{w}|#{w}@#{w}##{w}@#{w}##{w}@#{w} *#{Y} .#{y} *#{C} .#{c} *#{g} .#{x}",
84
- " #{c}.#{C} * .#{y} *#{Y} .#{y} *#{Y} .#{w}/#{w} @#{w} @#{w} @#{Y} *#{y} .#{Y} *#{y} .#{C} *#{c} . *#{g} .#{x}",
85
- " #{g}*#{c} . *#{C} .#{c} *#{C} .#{c} *#{w}|#{Y} *#{y} .#{Y} *#{c} .#{C} *#{c} .#{C} *#{c} . #{g}*#{d} .#{x}",
86
- " #{G}. *#{g} .#{c} *#{g} .#{c} *#{g} .#{w}\\#{C} .#{c} *#{g} .#{c} *#{g} .#{c} *#{g} .#{G} * . *#{x}",
87
- " #{d}* .#{G} *#{g} .#{G} *#{g} .#{G} *#{w}|#{G} *#{g} .#{G} *#{g} .#{G} *#{g} .#{G} * #{g}.#{d} * . *#{x}",
88
- " #{d}. * . * . * . *#{w}/#{d}* . * . * . * . * . * .#{x}",
89
- " #{d}* . * . * . * . #{w}|#{d} . * . * . * . * . * .#{x}",
90
- ],
91
- # Frame 6 — BIGGER FLASH, bolt thick and branching
92
- [
93
- " #{g}.#{G} *#{g} .#{c} *#{g} .#{c} *#{w}|#{c} *#{g} .#{c} *#{g} .#{c} *#{g} .#{c} *#{g} .#{G} * #{g}.#{x}",
94
- " #{c}*#{g} .#{c} *#{C} .#{c} *#{C} #{w}/#{c} *#{C} .#{c} *#{C} .#{c} *#{C} .#{c} *#{C} .#{c} *#{g} . #{c}*#{x}",
95
- " #{c}.#{C} *#{c} .#{C} *#{y} .#{w}|#{y} *#{y} .#{Y} *#{y} .#{Y} *#{y} .#{c} *#{y} .#{C} *#{c} .#{C} * #{c}.#{x}",
96
- " #{C}*#{y} .#{Y} *#{y} .#{Y} #{w}\\#{w} .#{w} @#{w} @#{w} @#{w} @#{w} @#{w} .#{Y} *#{y} .#{Y} *#{y} . #{C}*#{x}",
97
- " #{y}.#{Y} *#{w} .#{w} @#{w} @#{w}##{w}@#{w}|#{w}@#{w}##{w}@#{w}##{w}@#{w}##{w}@#{w} @#{w} .#{Y} *#{y} . #{y}*#{x}",
98
- " #{C}*#{y} .#{Y} *#{y} .#{Y} #{w}/#{w} .#{w} @#{w} @#{w} @#{w} @#{w} @#{w} .#{Y} *#{y} .#{Y} *#{y} . #{C}*#{x}",
99
- " #{c}.#{C} *#{c} .#{C} *#{y} .#{w}|#{y} *#{y} .#{Y} *#{y} .#{Y} *#{y} .#{c} *#{y} .#{C} *#{c} .#{C} * #{c}.#{x}",
100
- " #{c}*#{g} .#{c} *#{C} .#{c} *#{w}\\#{c} *#{C} .#{c} *#{C} .#{c} *#{C} .#{c} *#{C} .#{c} *#{g} . #{c}*#{x}",
101
- " #{g}.#{G} *#{g} .#{c} *#{g} .#{c} #{w}|#{g} .#{c} *#{g} .#{c} *#{g} .#{c} *#{g} .#{c} *#{g} .#{G} * #{g}.#{x}",
102
- " #{d}*#{G} . *#{g} . *#{g} . #{w}/#{g} . * #{g}. *#{g} . *#{g} . *#{G} . *#{d} . *#{x}",
103
- " #{d}. * . * . * . #{w}|#{d} . * . * . * . * . * . * .#{x}",
104
- ],
105
- # Frame 7 — PEAK: bolt blazes top to bottom, everything lit
106
- [
107
- " #{g}*#{c} .#{g} *#{c} .#{g} *#{c} #{w}|#{c} .#{g} *#{c} .#{g} *#{c} .#{g} *#{c} .#{g} *#{c} .#{g} *#{c} .#{x}",
108
- " #{c}.#{C} *#{c} .#{C} *#{c} .#{w}/#{c} .#{C} *#{c} .#{C} *#{c} .#{C} *#{c} .#{C} *#{c} .#{C} *#{c} .#{x}",
109
- " #{C}*#{y} .#{C} *#{y} .#{C} #{w}|#{y} .#{Y} *#{y} .#{Y} *#{y} .#{C} *#{y} .#{C} *#{y} .#{C} *#{y} .#{C} *#{x}",
110
- " #{y}.#{Y} *#{y} .#{Y} *#{w} .#{w}\\@#{w} @#{w}##{w}@#{w}##{w}@#{w} @#{w} .#{Y} *#{y} .#{Y} *#{y} .#{Y} *#{x}",
111
- " #{y}*#{w} .#{w} @#{w} @#{w}##{w}@#{w}##{w}@#{w}|#{w}@#{w}##{w}@#{w}##{w}@#{w}##{w}@#{w}##{w}@#{w} @#{w} .#{y} *#{y} .#{x}",
112
- " #{y}.#{Y} *#{y} .#{Y} *#{w} .#{w} @#{w}/#{w}##{w}@#{w}##{w}@#{w} @#{w} .#{Y} *#{y} .#{Y} *#{y} .#{Y} *#{x}",
113
- " #{C}*#{y} .#{C} *#{y} .#{C} *#{w}|#{Y} *#{y} .#{Y} *#{y} .#{C} *#{y} .#{C} *#{y} .#{C} *#{y} .#{C} *#{x}",
114
- " #{c}.#{C} *#{c} .#{C} *#{c} #{w}\\#{C} *#{c} .#{C} *#{c} .#{C} *#{c} .#{C} *#{c} .#{C} *#{c} .#{x}",
115
- " #{g}*#{c} .#{g} *#{c} .#{g} *#{w}|#{g} *#{c} .#{g} *#{c} .#{g} *#{c} .#{g} *#{c} .#{g} *#{c} .#{g} *#{c} .#{x}",
116
- " #{G}.#{g} *#{G} .#{g} *#{G} #{w}/#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{x}",
117
- " #{d}*#{G} .#{d} *#{G} .#{d} #{w}|#{G} .#{d} *#{G} .#{d} *#{G} .#{d} *#{G} .#{d} *#{G} .#{d} *#{G} .#{x}",
118
- ],
119
- # (hold peak — bolt shifts one tick)
120
- [
121
- " #{c}.#{g} *#{c} .#{g} *#{c} .#{g} #{w}|#{c} .#{g} *#{c} .#{g} *#{c} .#{g} *#{c} .#{g} *#{c} .#{g} *#{x}",
122
- " #{C}*#{c} .#{C} *#{c} .#{C} *#{w}\\#{c} .#{C} *#{c} .#{C} *#{c} .#{C} *#{c} .#{C} *#{c} .#{C} *#{x}",
123
- " #{y}.#{C} *#{y} .#{C} *#{y} .#{C} #{w}|#{y} .#{Y} *#{y} .#{Y} *#{y} .#{C} *#{y} .#{C} *#{y} .#{C} *#{y} .#{x}",
124
- " #{Y}*#{y} .#{Y} *#{w} .#{w} @#{w} @#{w}\\#{w}@#{w}##{w}@#{w}##{w}@#{w} @#{w} .#{Y} *#{y} .#{Y} *#{y} .#{Y} *#{x}",
125
- " #{w}.#{w} @#{w}##{w}@#{w}##{w}@#{w}##{w}@#{w}##{w}@#{w}|#{w}@#{w}##{w}@#{w}##{w}@#{w}##{w}@#{w}##{w}@#{w}##{w}@ #{w}.#{y} *#{x}",
126
- " #{Y}*#{y} .#{Y} *#{w} .#{w} @#{w} @#{w}##{w}/#{w}##{w}@#{w}##{w}@#{w} @#{w} .#{Y} *#{y} .#{Y} *#{y} .#{Y} *#{x}",
127
- " #{y}.#{C} *#{y} .#{C} *#{y} .#{C} #{w}|#{y} .#{Y} *#{y} .#{Y} *#{y} .#{C} *#{y} .#{C} *#{y} .#{C} *#{y} .#{x}",
128
- " #{C}*#{c} .#{C} *#{c} .#{C} #{w}/#{c} .#{C} *#{c} .#{C} *#{c} .#{C} *#{c} .#{C} *#{c} .#{C} *#{c} .#{C} *#{x}",
129
- " #{c}.#{g} *#{c} .#{g} *#{c} #{w}|#{g} *#{c} .#{g} *#{c} .#{g} *#{c} .#{g} *#{c} .#{g} *#{c} .#{g} *#{x}",
130
- " #{g}*#{G} .#{g} *#{G} .#{g} #{w}\\#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{x}",
131
- " #{G}.#{d} *#{G} .#{d} *#{G} .#{w}|#{G} .#{d} *#{G} .#{d} *#{G} .#{d} *#{G} .#{d} *#{G} .#{d} *#{G} .#{d} *#{x}",
132
- ],
133
- # Frame 8 — bolt fading, afterglow lines remain
134
- [
135
- " #{g}*#{c} .#{g} *#{c} .#{g} *#{c} .#{g} *#{c} .#{g} *#{c} .#{g} *#{c} .#{g} *#{c} .#{g} *#{c} .#{g} *#{c} .#{x}",
136
- " #{c}.#{C} *#{c} .#{C} *#{c} .#{C} *#{c} .#{C} *#{c} .#{C} *#{c} .#{C} *#{c} .#{C} *#{c} .#{C} *#{c} .#{x}",
137
- " #{C}*#{c} .#{C} *#{c} .#{c} *#{C} #{y}|#{y} *#{Y} .#{Y} *#{y} .#{C} *#{c} .#{c} *#{C} .#{c} *#{C} . #{c}*#{x}",
138
- " #{c}.#{C} *#{y} .#{Y} *#{y} .#{Y} #{y}\\#{w} @#{w}##{w}@#{w}##{w}@#{Y} *#{y} .#{Y} *#{y} .#{C} *#{c} . #{c}*#{x}",
139
- " #{C}*#{y} .#{w} @#{w} @#{w}##{w}@#{w}##{y}|#{w}##{w}@#{w}##{w}@#{w}##{w}@#{w} @#{w} .#{y} *#{C} .#{c} * #{C}.#{x}",
140
- " #{c}.#{C} *#{y} .#{Y} *#{y} .#{Y} #{y}/#{w} @#{w}##{w}@#{w}##{w}@#{Y} *#{y} .#{Y} *#{y} .#{C} *#{c} . #{c}*#{x}",
141
- " #{C}*#{c} .#{C} *#{c} .#{c} *#{C} #{y}|#{y} *#{Y} .#{Y} *#{y} .#{C} *#{c} .#{c} *#{C} .#{c} *#{C} . #{c}*#{x}",
142
- " #{c}.#{C} *#{c} .#{C} *#{c} .#{C} #{y}\\#{c} .#{C} *#{c} .#{C} *#{c} .#{C} *#{c} .#{C} *#{c} .#{C} *#{c} .#{x}",
143
- " #{g}*#{c} .#{g} *#{c} .#{g} *#{c} .#{Y}|#{c} .#{g} *#{c} .#{g} *#{c} .#{g} *#{c} .#{g} *#{c} .#{g} *#{c} .#{x}",
144
- " #{G}.#{g} *#{G} .#{g} *#{G} .#{g} #{Y}/#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{x}",
145
- " #{d}*#{G} .#{d} *#{G} .#{d} *#{G} .#{d} *#{G} .#{d} *#{G} .#{d} *#{G} .#{d} *#{G} .#{d} *#{G} .#{d} *#{G} .#{x}",
146
- ],
147
- # Frame 9 — bolt ghost, green waves rippling
148
- [
149
- " #{G}.#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{x}",
150
- " #{g}*#{c} .#{g} *#{c} .#{g} *#{c} .#{g} *#{c} .#{g} *#{c} .#{g} *#{c} .#{g} *#{c} .#{g} *#{c} .#{g} *#{x}",
151
- " #{c}.#{C} *#{c} .#{C} *#{c} .#{C} *#{c} .#{C} *#{c} .#{C} *#{c} .#{C} *#{c} .#{C} *#{c} .#{C} *#{c} .#{x}",
152
- " #{C}*#{c} .#{C} *#{c} .#{c} *#{c} #{D}|#{c} *#{C} .#{C} *#{c} .#{c} *#{c} .#{C} *#{c} .#{C} *#{C} . #{c}*#{x}",
153
- " #{c}.#{c} *#{c} .#{c} *#{c} .#{C} #{D}\\#{y} .#{y} *#{w}##{y} *#{y} .#{C} *#{c} .#{c} *#{c} .#{c} *#{c} . #{c}.#{x}",
154
- " #{C}*#{c} .#{C} *#{c} .#{c} *#{c} .#{D}|#{c} *#{C} .#{C} *#{c} .#{c} *#{c} .#{C} *#{c} .#{C} *#{C} . #{c}*#{x}",
155
- " #{c}.#{C} *#{c} .#{C} *#{c} .#{C} #{D}/#{c} .#{C} *#{c} .#{C} *#{c} .#{C} *#{c} .#{C} *#{c} .#{C} *#{c} .#{x}",
156
- " #{g}*#{c} .#{g} *#{c} .#{g} *#{c} #{D}|#{g} *#{c} .#{g} *#{c} .#{g} *#{c} .#{g} *#{c} .#{g} *#{c} .#{g} *#{x}",
157
- " #{G}.#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{x}",
158
- " #{d}*#{G} .#{d} *#{G} .#{d} *#{G} .#{d} *#{G} .#{d} *#{G} .#{d} *#{G} .#{d} *#{G} .#{d} *#{G} .#{d} *#{G} .#{x}",
159
- " #{d}. * . * . * . * . * . * . * . * . * . * .#{x}",
160
- ],
161
- # Frame 10 — green shimmer everywhere, warm afterglow
162
- [
163
- " #{d}*#{G} .#{d} *#{G} .#{d} *#{G} .#{d} *#{G} .#{d} *#{G} .#{d} *#{G} .#{d} *#{G} .#{d} *#{G} .#{d} *#{G} .#{x}",
164
- " #{G}.#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{x}",
165
- " #{g}*#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{x}",
166
- " #{G}.#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{x}",
167
- " #{g}*#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{Y} .#{y} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{x}",
168
- " #{G}.#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{x}",
169
- " #{g}*#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{x}",
170
- " #{G}.#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{x}",
171
- " #{d}*#{G} .#{d} *#{G} .#{d} *#{G} .#{d} *#{G} .#{d} *#{G} .#{d} *#{G} .#{d} *#{G} .#{d} *#{G} .#{d} *#{G} .#{x}",
172
- " #{d}. * . * . * . * . * . * . * . * . * . * .#{x}",
173
- " #{d}* . * . * . * . * . * . * . * . * . * . *#{x}",
174
- ],
175
- # Frame 11 — cooling to green field
176
- [
177
- " #{d}. * . * . * . * . * . * . * . * . * . * .#{x}",
178
- " #{d}*#{G} .#{d} *#{G} .#{d} *#{G} .#{d} *#{G} .#{d} *#{G} .#{d} *#{G} .#{d} *#{G} .#{d} *#{G} .#{d} *#{G} .#{x}",
179
- " #{G}.#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{x}",
180
- " #{d}*#{G} .#{d} *#{G} .#{G} *#{g} .#{G} *#{g} .#{G} *#{G} .#{d} *#{G} .#{d} *#{G} .#{d} *#{G} .#{d} *#{x}",
181
- " #{G}.#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{Y} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{x}",
182
- " #{d}*#{G} .#{d} *#{G} .#{G} *#{g} .#{G} *#{g} .#{G} *#{G} .#{d} *#{G} .#{d} *#{G} .#{d} *#{G} .#{d} *#{x}",
183
- " #{G}.#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{g} *#{G} .#{x}",
184
- " #{d}*#{G} .#{d} *#{G} .#{d} *#{G} .#{d} *#{G} .#{d} *#{G} .#{d} *#{G} .#{d} *#{G} .#{d} *#{G} .#{d} *#{G} .#{x}",
185
- " #{d}. * . * . * . * . * . * . * . * . * . * .#{x}",
186
- " #{d}* . * . * . * . * . * . * . * . * . * . *#{x}",
187
- " #{d}. * . * . * . * . * . * . * . * . * . * .#{x}",
188
- ],
189
- ]
190
-
191
- # Pad lines so all rows in each frame have equal stripped length —
192
- # prevents the player's per-line centering from misaligning the art.
193
- max = raw_frames.flatten.map { |l| l.gsub(/\e\[[0-9;]*m/, "").length }.max
194
- raw_frames.each do |frame|
195
- frame.map! { |l| l + " " * (max - l.gsub(/\e\[[0-9;]*m/, "").length) }
196
- end
197
-
198
- DATA = {
199
- name: "Flash",
200
- fps: 10,
201
- frames: raw_frames
202
- }.freeze
203
- end
204
- end
205
- end
@@ -1,127 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module FunCi
4
- module Animations
5
- module Idle
6
- # Gentle starfield -- sparse dots that drift slowly downward
7
- # Visible but calm: regular cyan (not dim), sparse placement, slow drift
8
-
9
- d = "\e[2;36m" # dim cyan
10
- c = "\e[36m" # cyan
11
- x = "\e[0m"
12
-
13
- # Each frame drifts the pattern down by ~2 lines, wrapping around.
14
- # Sparse enough to feel ambient, bright enough to actually see.
15
-
16
- raw_frames = [
17
- [
18
- " #{c}*#{x} #{d}.#{x} #{c}.#{x}",
19
- "",
20
- " #{d}.#{x} #{c}*#{x}",
21
- " #{c}.#{x} #{d}.#{x}",
22
- "",
23
- " #{d}.#{x} #{d}.#{x} #{c}*#{x}",
24
- "",
25
- " #{c}.#{x} #{d}.#{x}",
26
- " #{d}.#{x} #{c}.#{x}",
27
- "",
28
- " #{c}*#{x} #{d}.#{x}",
29
- " #{d}.#{x} #{c}.#{x}",
30
- "",
31
- " #{d}.#{x} #{d}.#{x}",
32
- ],
33
- [
34
- " #{d}.#{x} #{d}.#{x}",
35
- " #{c}*#{x} #{d}.#{x} #{c}.#{x}",
36
- "",
37
- " #{d}.#{x} #{c}*#{x}",
38
- " #{c}.#{x} #{d}.#{x}",
39
- "",
40
- " #{d}.#{x} #{d}.#{x} #{c}*#{x}",
41
- "",
42
- " #{c}.#{x} #{d}.#{x}",
43
- " #{d}.#{x} #{c}.#{x}",
44
- "",
45
- " #{c}*#{x} #{d}.#{x}",
46
- " #{d}.#{x} #{c}.#{x}",
47
- "",
48
- ],
49
- [
50
- " #{d}.#{x} #{c}.#{x}",
51
- "",
52
- " #{d}.#{x} #{d}.#{x}",
53
- " #{c}*#{x} #{d}.#{x} #{c}.#{x}",
54
- "",
55
- " #{d}.#{x} #{c}*#{x}",
56
- " #{c}.#{x} #{d}.#{x}",
57
- "",
58
- " #{d}.#{x} #{d}.#{x} #{c}*#{x}",
59
- "",
60
- " #{c}.#{x} #{d}.#{x}",
61
- " #{d}.#{x} #{c}.#{x}",
62
- "",
63
- " #{c}*#{x} #{d}.#{x}",
64
- ],
65
- [
66
- " #{c}*#{x} #{d}.#{x}",
67
- " #{d}.#{x} #{c}.#{x}",
68
- "",
69
- " #{d}.#{x} #{d}.#{x}",
70
- " #{c}*#{x} #{d}.#{x} #{c}.#{x}",
71
- "",
72
- " #{d}.#{x} #{c}*#{x}",
73
- " #{c}.#{x} #{d}.#{x}",
74
- "",
75
- " #{d}.#{x} #{d}.#{x} #{c}*#{x}",
76
- "",
77
- " #{c}.#{x} #{d}.#{x}",
78
- " #{d}.#{x} #{c}.#{x}",
79
- "",
80
- ],
81
- [
82
- " #{d}.#{x} #{c}.#{x}",
83
- "",
84
- " #{c}*#{x} #{d}.#{x}",
85
- " #{d}.#{x} #{c}.#{x}",
86
- "",
87
- " #{d}.#{x} #{d}.#{x}",
88
- " #{c}*#{x} #{d}.#{x} #{c}.#{x}",
89
- "",
90
- " #{d}.#{x} #{c}*#{x}",
91
- " #{c}.#{x} #{d}.#{x}",
92
- "",
93
- " #{d}.#{x} #{d}.#{x} #{c}*#{x}",
94
- "",
95
- " #{c}.#{x} #{d}.#{x}",
96
- ],
97
- [
98
- " #{c}.#{x} #{d}.#{x}",
99
- " #{d}.#{x} #{c}.#{x}",
100
- "",
101
- " #{c}*#{x} #{d}.#{x}",
102
- " #{d}.#{x} #{c}.#{x}",
103
- "",
104
- " #{d}.#{x} #{d}.#{x}",
105
- " #{c}*#{x} #{d}.#{x} #{c}.#{x}",
106
- "",
107
- " #{d}.#{x} #{c}*#{x}",
108
- " #{c}.#{x} #{d}.#{x}",
109
- "",
110
- " #{d}.#{x} #{d}.#{x} #{c}*#{x}",
111
- "",
112
- ],
113
- ]
114
-
115
- max = raw_frames.flatten.map { |l| l.gsub(/\e\[[0-9;]*m/, "").length }.max
116
- raw_frames.each do |frame|
117
- frame.map! { |l| l + " " * (max - l.gsub(/\e\[[0-9;]*m/, "").length) }
118
- end
119
-
120
- DATA = {
121
- name: "Idle",
122
- fps: 4,
123
- frames: raw_frames
124
- }.freeze
125
- end
126
- end
127
- end