natty-ui 0.12.1 → 0.25.0

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 (77) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +1 -1
  3. data/README.md +22 -26
  4. data/examples/24bit-colors.rb +4 -7
  5. data/examples/3bit-colors.rb +28 -6
  6. data/examples/8bit-colors.rb +18 -21
  7. data/examples/attributes.rb +30 -22
  8. data/examples/cols.rb +40 -0
  9. data/examples/elements.rb +31 -0
  10. data/examples/examples.rb +45 -0
  11. data/examples/illustration.rb +56 -54
  12. data/examples/ls.rb +16 -16
  13. data/examples/named-colors.rb +23 -0
  14. data/examples/sections.rb +29 -0
  15. data/examples/tables.rb +62 -0
  16. data/examples/tasks.rb +52 -0
  17. data/lib/natty-ui/attributes.rb +604 -0
  18. data/lib/natty-ui/choice.rb +56 -0
  19. data/lib/natty-ui/dumb_choice.rb +45 -0
  20. data/lib/natty-ui/element.rb +78 -0
  21. data/lib/natty-ui/features.rb +798 -0
  22. data/lib/natty-ui/framed.rb +51 -0
  23. data/lib/natty-ui/ls_renderer.rb +93 -0
  24. data/lib/natty-ui/progress.rb +187 -0
  25. data/lib/natty-ui/section.rb +69 -0
  26. data/lib/natty-ui/table.rb +241 -0
  27. data/lib/natty-ui/table_renderer.rb +147 -0
  28. data/lib/natty-ui/task.rb +44 -0
  29. data/lib/natty-ui/temporary.rb +38 -0
  30. data/lib/natty-ui/theme.rb +303 -0
  31. data/lib/natty-ui/utils.rb +79 -0
  32. data/lib/natty-ui/version.rb +1 -1
  33. data/lib/natty-ui/width_finder.rb +125 -0
  34. data/lib/natty-ui.rb +89 -147
  35. metadata +44 -53
  36. data/examples/animate.rb +0 -42
  37. data/examples/attributes_list.rb +0 -12
  38. data/examples/demo.rb +0 -51
  39. data/examples/message.rb +0 -30
  40. data/examples/progress.rb +0 -66
  41. data/examples/query.rb +0 -39
  42. data/examples/read_key.rb +0 -13
  43. data/examples/table.rb +0 -39
  44. data/lib/natty-ui/animation/binary.rb +0 -36
  45. data/lib/natty-ui/animation/default.rb +0 -38
  46. data/lib/natty-ui/animation/matrix.rb +0 -51
  47. data/lib/natty-ui/animation/rainbow.rb +0 -28
  48. data/lib/natty-ui/animation/type_writer.rb +0 -44
  49. data/lib/natty-ui/animation.rb +0 -69
  50. data/lib/natty-ui/ansi/constants.rb +0 -75
  51. data/lib/natty-ui/ansi.rb +0 -530
  52. data/lib/natty-ui/ansi_wrapper.rb +0 -232
  53. data/lib/natty-ui/frame.rb +0 -53
  54. data/lib/natty-ui/glyph.rb +0 -64
  55. data/lib/natty-ui/key_map.rb +0 -142
  56. data/lib/natty-ui/preload.rb +0 -12
  57. data/lib/natty-ui/spinner.rb +0 -120
  58. data/lib/natty-ui/text/east_asian_width.rb +0 -2529
  59. data/lib/natty-ui/text.rb +0 -203
  60. data/lib/natty-ui/wrapper/animate.rb +0 -17
  61. data/lib/natty-ui/wrapper/ask.rb +0 -78
  62. data/lib/natty-ui/wrapper/element.rb +0 -79
  63. data/lib/natty-ui/wrapper/features.rb +0 -21
  64. data/lib/natty-ui/wrapper/framed.rb +0 -45
  65. data/lib/natty-ui/wrapper/heading.rb +0 -64
  66. data/lib/natty-ui/wrapper/horizontal_rule.rb +0 -37
  67. data/lib/natty-ui/wrapper/list_in_columns.rb +0 -138
  68. data/lib/natty-ui/wrapper/message.rb +0 -109
  69. data/lib/natty-ui/wrapper/mixins.rb +0 -75
  70. data/lib/natty-ui/wrapper/progress.rb +0 -63
  71. data/lib/natty-ui/wrapper/query.rb +0 -89
  72. data/lib/natty-ui/wrapper/quote.rb +0 -25
  73. data/lib/natty-ui/wrapper/request.rb +0 -54
  74. data/lib/natty-ui/wrapper/section.rb +0 -118
  75. data/lib/natty-ui/wrapper/table.rb +0 -550
  76. data/lib/natty-ui/wrapper/task.rb +0 -55
  77. data/lib/natty-ui/wrapper.rb +0 -239
@@ -1,232 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'wrapper'
4
-
5
- module NattyUI
6
- class AnsiWrapper < Wrapper
7
- def ansi? = true
8
-
9
- def cursor=(value)
10
- if value
11
- (@stream << Ansi::CURSOR_SHOW).flush if @cursor == 1
12
- @cursor -= 1 if @cursor.positive?
13
- return
14
- end
15
- (@stream << Ansi::CURSOR_HIDE).flush if @cursor.zero?
16
- @cursor += 1
17
- end
18
-
19
- def puts(*args, **kwargs)
20
- return super if args.empty? || (animation = kwargs[:animation]).nil?
21
- animation = Animation[animation].new(wrapper, args, kwargs)
22
- self.cursor = false
23
- animation.perform(@stream)
24
- @lines_written += animation.lines_written
25
- self.cursor = true
26
- self
27
- end
28
-
29
- def page
30
- unless block_given?
31
- @stream.flush
32
- return self
33
- end
34
- (@stream << Ansi::SCREEN_BLANK).flush
35
- begin
36
- yield(self)
37
- ensure
38
- (@stream << Ansi::SCREEN_UNBLANK).flush
39
- end
40
- end
41
-
42
- def cls
43
- (@stream << Ansi::CLS).flush
44
- self
45
- end
46
-
47
- protected
48
-
49
- def pprint(strs, opts)
50
- prefix = opts[:prefix] and prefix = Text.embellish(prefix)
51
- suffix = opts[:suffix] and suffix = Text.embellish(suffix)
52
- return yield("#{prefix}#{suffix}") if strs.empty?
53
- max_width =
54
- opts.fetch(:max_width) do
55
- screen_columns - (opts[:prefix_width] || Text.width(prefix)) -
56
- (opts[:suffix_width] || Text.width(suffix))
57
- end
58
- case opts[:align]
59
- when :right
60
- Text.each_line(strs, max_width) do |line, width|
61
- width = max_width - width
62
- yield("#{prefix}#{' ' * width}#{line}#{suffix}")
63
- end
64
- when :center
65
- Text.each_line(strs, max_width) do |line, width|
66
- width = max_width - width
67
- right = width / 2
68
- yield(
69
- "#{prefix}#{' ' * (width - right)}#{line}#{' ' * right}#{suffix}"
70
- )
71
- end
72
- else
73
- Text.each_line(strs, max_width) { yield("#{prefix}#{_1}#{suffix}") }
74
- end
75
- end
76
-
77
- def temp_func
78
- count = @lines_written
79
- lambda do
80
- if (c = @lines_written - count).nonzero?
81
- @stream << Ansi.cursor_prev_line(c) << Ansi.screen_erase(:below) <<
82
- Ansi::CURSOR_FIRST_COLUMN
83
- @lines_written -= c
84
- end
85
- @stream.flush
86
- self
87
- end
88
- end
89
-
90
- class Progress < Element
91
- include ProgressAttributes
92
- include ValueAttributes
93
-
94
- protected
95
-
96
- def call(title, max_value, spinner)
97
- @title = "[b 27]➔[/b] #{title}"
98
- @info = nil
99
- @final_text = [title]
100
- if max_value
101
- @max_value = [0, max_value.to_f].max
102
- else
103
- @spinner = NattyUI::Spinner[spinner]
104
- end
105
- @value = 0
106
- @pos = wrapper.lines_written
107
- wrapper.cursor = false
108
- @parent.puts(@last_render = render)
109
- @height = wrapper.lines_written - @pos
110
- self
111
- end
112
-
113
- def redraw
114
- return if @status
115
- current = render
116
- return if @last_render == current
117
- wrapper.stream << Ansi.cursor_previous_line(@height) << Ansi::LINE_ERASE
118
- cl = wrapper.lines_written
119
- @parent.puts(@last_render = current)
120
- @height = wrapper.lines_written - cl
121
- end
122
-
123
- def render
124
- return "#{@title} #{@spinner.next}#{" #{@info}" if @info}" if @spinner
125
- percent = @max_value.zero? ? 100.0 : @value / @max_value
126
- count = [(30 * percent).round, 30].min
127
- mv = @max_value.round.to_s
128
- "#{@title} [27 on27]#{'█' * count}[ec onec]#{
129
- '▁' * (30 - count)
130
- }[/bg] [e2 b]#{(percent * 100).round.to_s.rjust(3)}%[/b] [f6](#{
131
- @value.round.to_s.rjust(mv.size)
132
- }/#{mv})[/]#{" #{@info}" if @info}"
133
- end
134
-
135
- def finish
136
- wrapper.stream << Ansi.cursor_previous_line(@height) << Ansi::LINE_ERASE
137
- wrapper.instance_variable_set(:@lines_written, @pos)
138
- wrapper.cursor = true
139
- return @parent.failed(*@final_text) if failed?
140
- @parent.message(*@final_text, glyph: @status = :completed)
141
- end
142
- end
143
-
144
- module Temporary
145
- def temporary
146
- unless block_given?
147
- wrapper.stream.flush
148
- return self
149
- end
150
- count = wrapper.lines_written
151
- begin
152
- yield(self)
153
- ensure
154
- count = wrapper.lines_written - count
155
- if count.nonzero?
156
- wrapper.stream << Ansi.cursor_prev_line(count) <<
157
- Ansi.display(:erase_below)
158
- end
159
- wrapper.stream.flush
160
- end
161
- end
162
- end
163
-
164
- class Section < Section
165
- include Temporary
166
- end
167
-
168
- class Quote < Quote
169
- include Temporary
170
-
171
- def initialize(...)
172
- super
173
- @prefix = "#{Ansi[39]}#{@prefix}#{Ansi::RESET}"
174
- end
175
- end
176
-
177
- class Framed < Framed
178
- def color(str) = "#{Ansi[39]}#{str}#{Ansi::RESET}"
179
-
180
- def init(type)
181
- @prefix = "#{color(type[4])} "
182
- @suffix = "#{Ansi.cursor_column(parent.rcol)}#{color(type[4])}"
183
- aw = @parent.available_width - 2
184
- parent.puts(color("#{type[0]}#{type[5] * aw}#{type[1]}"))
185
- @finish = color("#{type[2]}#{type[5] * aw}#{type[3]}")
186
- end
187
- end
188
-
189
- class Message < Section
190
- protected
191
-
192
- def initialize(parent, title:, glyph:, **opts)
193
- color = COLORS[glyph] || COLORS[:default]
194
- glyph = NattyUI::Glyph[glyph]
195
- prefix_width = Text.width(glyph) + 1
196
- parent.puts(
197
- title,
198
- prefix: "#{glyph} #{color}",
199
- prefix_width: prefix_width,
200
- suffix: Ansi::RESET,
201
- suffix_width: 0
202
- )
203
- super(
204
- parent,
205
- prefix: ' ' * prefix_width,
206
- prefix_width: prefix_width,
207
- **opts
208
- )
209
- end
210
-
211
- white = Ansi[255]
212
- COLORS = {
213
- default: white,
214
- point: white,
215
- information: white,
216
- warning: Ansi[221],
217
- error: Ansi[208],
218
- completed: Ansi[82],
219
- failed: Ansi[196],
220
- task: Ansi[39],
221
- query: white
222
- }.compare_by_identity.freeze
223
- end
224
-
225
- class Task < Message
226
- include ProgressAttributes
227
- include TaskMethods
228
- end
229
- end
230
-
231
- private_constant :AnsiWrapper
232
- end
@@ -1,53 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module NattyUI
4
- # Helper class to select frame types.
5
- # @see Features#framed
6
- # @see Features#table
7
- module Frame
8
- # Define frame type used by default.
9
- #
10
- # @attribute [w] self.default
11
- # @param value [Symbol] type name
12
- # @return [Symbol] type name
13
- def self.default=(value)
14
- @default = self[value.nil? || value == :default ? :rounded : value]
15
- end
16
-
17
- # Defined frame type names.
18
- # @see []
19
- #
20
- # @attribute [r] self.names
21
- # @return [Array<Symbol>] supported attribute names
22
- def self.names = @all.keys
23
-
24
- # @param name [Symbol, String]
25
- # defined type name (see {.names})
26
- # or frame elements
27
- # @return [String] frame definition
28
- def self.[](name)
29
- return @default if name == :default
30
- if name.is_a?(Symbol)
31
- ret = @all[name] and return ret
32
- elsif name.is_a?(String)
33
- return name if name.size == 11
34
- return name * 11 if name.size == 1
35
- end
36
- raise(ArgumentError, "invalid frame type - #{name}")
37
- end
38
-
39
- @all = {
40
- cols: ' │ │ ',
41
- double: '╔╗╚╝║═╬╦╩╠╣',
42
- heavy: '┏┓┗┛┃━╋┳┻┣┫',
43
- rounded: '╭╮╰╯│─┼┬┴├┤',
44
- rows: ' ── ',
45
- semi: '╒╕╘╛│═╪╤╧╞╡',
46
- semi2: '╓╖╙╜│─╫╥╨╟╢',
47
- simple: '┌┐└┘│─┼┬┴├┤',
48
- undecorated: ' '
49
- }.compare_by_identity
50
-
51
- self.default = nil
52
- end
53
- end
@@ -1,64 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'text'
4
-
5
- module NattyUI
6
- # Helper class to select glyph types.
7
- # @see Features#message
8
- module Glyph
9
- # Define glyph type used by default.
10
- # @attribute [w] self.default
11
- # @param value [Symbol] type name
12
- # @return [Symbol] type name
13
- def self.default=(value)
14
- @default = self[value.nil? || value == :default ? :point : value]
15
- end
16
-
17
- # Defined glyph type names.
18
- # @see []
19
- #
20
- # @attribute [r] self.names
21
- # @return [Array<Symbol>] supported attribute names
22
- def self.names = @all.keys
23
-
24
- # @param name [Symbol, #to_s]
25
- # defined type name (see {.names})
26
- # or glyph
27
- # @return [String] glyph definition
28
- def self.[](name)
29
- return @default if name == :default
30
- Text.embellish(
31
- if name.is_a?(Symbol)
32
- @all[name] or raise(ArgumentError, "invalid glyph type - #{name}")
33
- else
34
- name.to_s
35
- end
36
- )
37
- end
38
-
39
- @all = {
40
- completed: '[b 52]✓',
41
- dot: '[27]•',
42
- error: '[b d0]𝙓',
43
- failed: '[b c4]𝑭',
44
- information: '[b 77]𝒊',
45
- point: '[27]◉',
46
- query: '[b 27]▸',
47
- task: '[b 27]➔',
48
- warning: '[b dd]!'
49
- }.compare_by_identity
50
-
51
- # GLYPH = {
52
- # default: '●',
53
- # information: '🅸 ',
54
- # warning: '🆆 ',
55
- # error: '🅴 ',
56
- # completed: '✓',
57
- # failed: '🅵 ',
58
- # task: '➔',
59
- # query: '🆀 '
60
- # }.compare_by_identity.freeze
61
-
62
- self.default = nil
63
- end
64
- end
@@ -1,142 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module NattyUI
4
- KEY_MAP =
5
- Module # generator
6
- .new do
7
- def self.add_modifiers(**keys)
8
- @mods.each_pair do |mod, pref|
9
- @map.merge!(
10
- keys.to_h do |name, code|
11
- ["\e[1;#{mod}#{code}", "#{pref}+#{name}"]
12
- end
13
- )
14
- end
15
- end
16
-
17
- def self.add_keys(**keys)
18
- @map.merge!(keys.to_h { |name, code| ["\e[#{code}", name] })
19
- add_modifiers(**keys)
20
- end
21
-
22
- def self.add_fkeys(**keys)
23
- @map.merge!(keys.to_h { |name, code| ["\e[#{code}~", name] })
24
- @mods.each_pair do |mod, prefix|
25
- @map.merge!(
26
- keys.to_h do |name, code|
27
- ["\e[#{code};#{mod}~", "#{prefix}+#{name}"]
28
- end
29
- )
30
- end
31
- end
32
-
33
- def self.add_alt_keys(**keys)
34
- keys.each_pair do |name, code|
35
- @map[code] = name
36
- @map["\e#{code}"] = "Alt+#{name}" # kitty
37
- end
38
- end
39
-
40
- def self.to_hash
41
- # control codes
42
- num = 0
43
- @map = ('A'..'Z').to_h { [(num += 1).chr, "Ctrl+#{_1}"] }
44
-
45
- add_modifiers('F1' => 'P', 'F2' => 'Q', 'F3' => 'R', 'F4' => 'S')
46
-
47
- add_keys(
48
- 'Up' => 'A',
49
- 'Down' => 'B',
50
- 'Right' => 'C',
51
- 'Left' => 'D',
52
- 'End' => 'F',
53
- 'Home' => 'H'
54
- )
55
-
56
- add_fkeys(
57
- 'DEL' => '3',
58
- 'PgUp' => '5',
59
- 'PgDown' => '6',
60
- # -
61
- 'F1' => 'F1',
62
- 'F2' => 'F2',
63
- 'F3' => 'F3',
64
- 'F4' => 'F4',
65
- # -
66
- 'F5' => '15',
67
- 'F6' => '17',
68
- 'F7' => '18',
69
- 'F8' => '19',
70
- 'F9' => '20',
71
- 'F10' => '21',
72
- 'F11' => '23',
73
- 'F12' => '24',
74
- 'F13' => '25',
75
- 'F14' => '26',
76
- 'F15' => '28',
77
- 'F16' => '29',
78
- 'F17' => '31',
79
- 'F18' => '32',
80
- 'F19' => '33',
81
- 'F20' => '34'
82
- )
83
-
84
- add_fkeys('F3' => '13') # kitty
85
-
86
- add_alt_keys(
87
- 'ESC' => "\e",
88
- 'ENTER' => "\r",
89
- 'TAB' => "\t",
90
- 'BACK' => "\u007F",
91
- 'Ctrl+BACK' => "\b",
92
- 'Shift+TAB' => "\e[Z"
93
- )
94
-
95
- # overrides and additionals
96
- @map.merge!(
97
- "\4" => 'DEL',
98
- "\e[5" => 'PgUp',
99
- "\e[6" => 'PgDown',
100
- # SS3 control (VT 100 etc)
101
- "\eOA" => 'Up',
102
- "\eOB" => 'Down',
103
- "\eOC" => 'Right',
104
- "\eOD" => 'Left',
105
- "\eOP" => 'F1',
106
- "\eOQ" => 'F2',
107
- "\eOR" => 'F3',
108
- "\eOS" => 'F4',
109
- "\eO2P" => 'Shift+F1',
110
- "\eO2Q" => 'Shift+F2',
111
- "\eO2R" => 'Shift+F3',
112
- "\eO2S" => 'Shift+F4',
113
- "\eOt" => 'F5',
114
- "\eOu" => 'F6',
115
- "\eOv" => 'F7',
116
- "\eOw" => 'F8',
117
- "\eOl" => 'F9',
118
- "\eOx" => 'F10'
119
- )
120
- end
121
-
122
- @mods = {
123
- 2 => 'Shift',
124
- 3 => 'Alt',
125
- 4 => 'Alt-Shift',
126
- 5 => 'Ctrl',
127
- 6 => 'Ctrl-Shift',
128
- 7 => 'Ctrl-Alt',
129
- 8 => 'Ctrl-Alt-Shift',
130
- 9 => 'Meta',
131
- 10 => 'Meta-Shift',
132
- 11 => 'Meta-Alt',
133
- 12 => 'Meta-Alt-Shift',
134
- 13 => 'Ctrl-Meta',
135
- 14 => 'Ctrl-Meta-Shift',
136
- 15 => 'Ctrl-Meta-Alt',
137
- 16 => 'Ctrl-Meta-Alt-Shift'
138
- }.compare_by_identity
139
- end
140
- .to_hash
141
- .freeze
142
- end
@@ -1,12 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative '../natty-ui'
4
-
5
- module NattyUI
6
- Animation[nil]
7
- Frame[:default]
8
- Glyph[:default]
9
- KEY_MAP[0]
10
- Spinner[:default]
11
- Text.width("\u1100")
12
- end
@@ -1,120 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'ansi'
4
-
5
- module NattyUI
6
- # Helper class to select spinner types.
7
- # @see Features#progress
8
- module Spinner
9
- class << self
10
- # Define spinner type used by default.
11
- # @attribute [w] self.default
12
- # @param value [Symbol] type name
13
- # @return [Symbol] type name
14
- def default=(value)
15
- @default = self[value.nil? || value == :default ? :pulse : value]
16
- end
17
-
18
- # Defined spinner type names.
19
- # @see []
20
- #
21
- # @attribute [r] self.names
22
- # @return [Array<Symbol>] supported attribute names
23
- def names = @all.keys
24
-
25
- # @param name [Symbol, #to_a, #to_s]
26
- # defined type name (see {.names})
27
- # or spinner elements
28
- # @return [Enumerator] spinner definition
29
- def [](name)
30
- return @default if name == :default
31
- parts =
32
- if name.is_a?(Symbol)
33
- @all[name] or raise(ArgumentError, "invalid spinner type - #{name}")
34
- else
35
- name
36
- end
37
- parts =
38
- (parts.respond_to?(:map) ? parts : parts.to_s.chars).map do |part|
39
- "#{@style}#{part}#{Ansi::RESET}"
40
- end
41
- raise(ArgumentError, "invalid spinner type - #{name}") if parts.empty?
42
- parts = parts.zip(parts).flatten(1) while parts.size < 6
43
- Enumerator.new { |y| parts.each { y << _1 } while true }
44
- end
45
-
46
- private
47
-
48
- def slide(a, b, size, prefix = nil, suffix = prefix)
49
- Enumerator.new do |y|
50
- fn =
51
- lambda do |i|
52
- y << "#{prefix}#{a * (i += 1)}#{b * (size - i)}#{suffix}"
53
- end
54
- size.times(&fn)
55
- a, b = b, a
56
- size.times(&fn)
57
- end
58
- end
59
-
60
- def bounce(a, b, size, prefix = nil, suffix = prefix)
61
- Enumerator.new do |y|
62
- fn =
63
- lambda do |i|
64
- y << "#{prefix}#{a * (i += 1)}#{b * (size - i)}#{suffix}"
65
- end
66
- size.times(&fn)
67
- a, b = b, a
68
- (size - 1).times(&fn)
69
- fn = ->(i) { y << "#{prefix}#{a * i}#{b * (size - i)}#{suffix}" }
70
- (size - 2).downto(0, &fn)
71
- a, b = b, a
72
- (size - 1).downto(0, &fn)
73
- end
74
- end
75
-
76
- def move(a, b, size, prefix = nil, suffix = prefix)
77
- Enumerator.new do |y|
78
- size.times do |i|
79
- y << "#{prefix}#{b * i}#{a}#{b * (size - i - 1)}#{suffix}"
80
- end
81
- y << "#{prefix}#{b * size}#{suffix}"
82
- end
83
- end
84
- end
85
-
86
- @style = Ansi[:bold, 220]
87
- @all = {
88
- bar: '▁▂▃▄▅▆▇█▇▆▅▄▃▂',
89
- blink: '■□▪▫',
90
- blocks: '▖▘▝▗',
91
- bounce: bounce('◼︎', '◻︎', 7),
92
- bounce2: bounce('▰', '▱', 7),
93
- bounce3: bounce('● ', '◌ ', 7),
94
- bounce4: bounce('=', ' ', 5, '[', ']'),
95
- circle: '◐◓◑◒',
96
- colors: '🟨🟨🟧🟧🟥🟥🟦🟦🟪🟪🟩🟩',
97
- dots: '⣷⣯⣟⡿⢿⣻⣽⣾',
98
- dots2: '⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏',
99
- dots3: '⠋⠙⠚⠞⠖⠦⠴⠲⠳⠓',
100
- dots4: '⠄⠆⠇⠋⠙⠸⠰⠠⠰⠸⠙⠋⠇⠆',
101
- dots5: '⠋⠙⠚⠒⠂⠂⠒⠲⠴⠦⠖⠒⠐⠐⠒⠓⠋',
102
- move: move('◼︎', '◻︎', 7),
103
- move2: move('▰', '▱', 7),
104
- move3: move('● ', '◌ ', 7),
105
- move4: move('=', ' ', 5, '[', ']'),
106
- pulse: '•✺◉●◉✺',
107
- slide: slide('◼︎', '◻︎', 7),
108
- slide2: slide('▰', '▱', 7),
109
- slide3: slide('● ', '◌ ', 7),
110
- slide4: slide('=', ' ', 5, '[', ']'),
111
- slide5: slide('.', ' ', 3),
112
- snake: '⠁⠉⠙⠸⢰⣠⣄⡆⠇⠃',
113
- stod: '⡿⣟⣯⣷⣾⣽⣻⢿',
114
- swap: '㊂㊀㊁',
115
- vintage: '-\\|/'
116
- }.compare_by_identity
117
-
118
- self.default = nil
119
- end
120
- end