hansi 0.1.0 → 0.1.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.
@@ -0,0 +1,93 @@
1
+ module Hansi
2
+ class ColorParser
3
+ IllegalValue ||= Class.new(ArgumentError)
4
+ singleton_class.send(:private, :new)
5
+
6
+ def self.parse(*values)
7
+ @parser ||= new
8
+ @parser.parse(values)
9
+ end
10
+
11
+ def initialize
12
+ @cache = {}
13
+ end
14
+
15
+ def parse(values, potentially_illegal: nil)
16
+ @cache[values] ||= parse_values(values, potentially_illegal)
17
+ end
18
+
19
+ def parse_values(values, potentially_illegal)
20
+ values = values.first while values.size == 1 and values.first.is_a? Array
21
+ values = values.flat_map { |value| parse_value(value, potentially_illegal) }
22
+
23
+ if values.size == 1 and values.first.is_a? AnsiCode
24
+ values.first
25
+ else
26
+ values *= 3 if values.size == 1
27
+ Color.new(*values)
28
+ end
29
+ end
30
+
31
+ def parse_value(value, potentially_illegal)
32
+ case value
33
+ when Float then parse_float(value, potentially_illegal)
34
+ when Integer then parse_integer(value, potentially_illegal)
35
+ when String then parse_string(value, potentially_illegal)
36
+ when Hash then parse_hash(potentially_illegal, **value)
37
+ when Symbol then parse_symbol(value, potentially_illegal)
38
+ when AnsiCode then value
39
+ else illegal(potentially_illegal || value)
40
+ end
41
+ end
42
+
43
+ def parse_hash(potentially_illegal, red: 0, green: 0, blue: 0)
44
+ [red, green, blue].map { |v| parse_value(v, potentially_illegal) }
45
+ end
46
+
47
+ def parse_color(color, potentially_illegal)
48
+ [color.red, color.green, color.blue]
49
+ end
50
+
51
+ def parse_float(value, potentially_illegal)
52
+ value *= 255 if value.between? 0, 1
53
+ parse_integer(value.to_i, potentially_illegal || value)
54
+ end
55
+
56
+ def parse_integer(value, potentially_illegal)
57
+ return value if value.between? 0, 255
58
+ value > 255 ? 255 : 0
59
+ end
60
+
61
+ def parse_string(string, potentially_illegal)
62
+ return parse_ansi(string, potentially_illegal || string) if string.start_with? ?\e
63
+ return parse_hash(potentially_illegal || string, red: $1.to_i, green: $2.to_i, blue: $3.to_i) if string =~ /^rgb\((\d{1,3}),(\d{1,3}),(\d{1,3})\)$/m
64
+ return parse_symbol(string, potentially_illegal || string) if string !~ /^#?[0-9a-f]+$/
65
+ string = string[1..-1] if string.start_with?(?#)
66
+ case string.size
67
+ when 1 then (string*2).to_i(16)
68
+ when 2 then string.to_i(16)
69
+ when 3 then string.each_char.map { |c| (c*2).to_i(16) }
70
+ when 6 then [string[0,2].to_i(16), string[2,2].to_i(16), string[4,2].to_i(16)]
71
+ else illegal(potentially_illegal || string)
72
+ end
73
+ end
74
+
75
+ def parse_ansi(string, potentially_illegal)
76
+ case string
77
+ when /\e\[(?:\d;)?38;2;(\d{1,3});(\d{1,3});(\d{1,3})(?:;\d)?m/ then parse_hash(potentially_illegal, red: $1.to_i, green: $2.to_i, blue: $3.to_i)
78
+ when /\e\[(?:\d;)?38;5;(\d{1,3})(?:;\d)?m/ then parse_color(PALETTES[ 'xterm-256color' ].fetch("\e[38;5;#{$1.to_i}m") { illegal(potentially_illegal) }, potentially_illegal)
79
+ when /\e\[(?:\d;)?([39]\d)(?:;\d)?m/ then parse_color(PALETTES[ 'xterm' ].fetch("\e[#{$1}m") { illegal(potentially_illegal) }, potentially_illegal)
80
+ end
81
+ end
82
+
83
+ def parse_symbol(symbol, potentially_illegal)
84
+ value = symbol.to_s.downcase.gsub(/[^a-z]/, '').to_sym
85
+ value = PALETTES['special'][value] || PALETTES['web'][value]
86
+ parse_value(value, potentially_illegal || symbol)
87
+ end
88
+
89
+ def illegal(value)
90
+ raise IllegalValue, 'illegal color value %p' % value
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,20 @@
1
+ require 'strscan'
2
+
3
+ module Hansi
4
+ class ColorRenderer
5
+ def self.render(*input, **options)
6
+ new(**options).render(*input)
7
+ end
8
+
9
+ def initialize(mode: Hansi.mode, join: "")
10
+ @mode = mode
11
+ @join = join
12
+ end
13
+
14
+ def render(color, *input)
15
+ output = color.to_ansi(mode: @mode)
16
+ output += input.join(@join) + Hansi.reset if input.any?
17
+ output
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,200 @@
1
+ require 'shellwords'
2
+
3
+ module Hansi
4
+ class ModeDetector
5
+ TERMS = { # only includes $TERM values that don't have the color amout in ther name and support more than 8 colors
6
+ 0 => ["dummy"],
7
+ 15 => ["emu"],
8
+ 16 => [
9
+ "amiga-vnc", "d430-dg", "d430-unix", "d430-unix-25", "d430-unix-s", "d430-unix-sr", "d430-unix-w", "d430c-dg", "d430c-unix", "d430c-unix-25",
10
+ "d430c-unix-s", "d430c-unix-sr", "d430c-unix-w", "d470", "d470-7b", "d470-dg", "d470c", "d470c-7b", "d470c-dg", "dg+color", "dg+fixed", "dgmode+color",
11
+ "dgunix+fixed", "hp+color", "hp2397", "hp2397a", "ncr260wy325pp", "ncr260wy325wpp", "ncr260wy350pp", "ncr260wy350wpp", "nsterm+c", "nsterm-7-c",
12
+ "nsterm-7-c-s", "nsterm-acs-c", "nsterm-acs-c-s", "nsterm-c", "nsterm-c-7", "nsterm-c-acs", "nsterm-c-s", "nsterm-c-s-7", "nsterm-c-s-acs"
13
+ ],
14
+ 52 => [
15
+ "d430-dg-ccc", "d430-unix-25-ccc", "d430-unix-ccc", "d430-unix-s-ccc", "d430-unix-sr-ccc", "d430-unix-w-ccc", "d430c-dg-ccc", "d430c-unix-25-ccc",
16
+ "d430c-unix-ccc", "d430c-unix-s-ccc", "d430c-unix-sr-ccc", "d430c-unix-w-ccc", "dg+ccc", "dgunix+ccc"
17
+ ],
18
+ 64 => [
19
+ "hpterm-color", "wy370", "wy370-101k", "wy370-105k", "wy370-EPC", "wy370-nk", "wy370-rv", "wy370-vb", "wy370-w", "wy370-wvb", "wyse370"
20
+ ],
21
+ 256 => ["Eterm"]
22
+ }
23
+
24
+ TRUE_COLOR_COMMANDS = [ "finalterm", "konsole", "sakura", "roxterm", "yakuake", "st", "tilda" ]
25
+ COMMANDS = [
26
+ "gnome-terminal", "gnome-terminal-server", "xterm", "iTerm2", "guake", "termit", "evilvte", "terminator",
27
+ "lxterminal", "terminology", "xfce4-terminal", "stjerm", *TRUE_COLOR_COMMANDS
28
+ ]
29
+
30
+ attr_reader :env, :supported, :io
31
+ def initialize(env , shell_out: nil, io: nil, supported: [0, 8, 16, 88, 256, Hansi::TRUE_COLOR])
32
+ shell_out = true if shell_out.nil? and env == ENV
33
+ io = $stdout if io.nil? and env == ENV
34
+ @env, @shell_out, @supported , @io = env, shell_out, supported, io
35
+ end
36
+
37
+ def mode
38
+ @mode ||= begin
39
+ mode = from_tput || from_term_program || from_term
40
+ mode = Hansi::TRUE_COLOR if mode == 256 and maximum >= Hansi::TRUE_COLOR and true_color?
41
+ mode ||= 8 if io and io.tty?
42
+ mode ||= 0
43
+ supported?(mode) ? mode : minimum
44
+ end
45
+ end
46
+
47
+ def from_tput
48
+ return unless shell_out?
49
+ colors = `tput #{"-T#{term}" if term} colors`.to_i
50
+ colors if colors > 8
51
+ rescue Errno::ENOENT
52
+ end
53
+
54
+ def from_term_program
55
+ term_program = env['TERM_PROGRAM']
56
+ 256 if term_program == 'Apple_Terminal' or term_program == 'MacTerm'
57
+ end
58
+
59
+ def from_term
60
+ case term
61
+ when /[\-\+](\d+)color/ then $1.to_i
62
+ when /[\-\+](\d+)bit/ then 2 ** $1.to_i
63
+ when /[\-\+](\d+)byte/ then 2 ** (8*$1.to_i)
64
+ when 'xterm' then from_xterm
65
+ else TERMS.keys.detect { |key| TERMS[key].include? term }
66
+ end
67
+ end
68
+
69
+ def from_xterm
70
+ terminal_command ? 256 : 16
71
+ end
72
+
73
+ def term
74
+ env['TERM']
75
+ end
76
+
77
+ def true_color?
78
+ return true if TRUE_COLOR_COMMANDS.include? terminal_command
79
+ return iterm_true_color? if iterm?
80
+ return xterm_true_color? if actual_xterm?
81
+ return gnome_true_color? if gnome_terminal?
82
+ false
83
+ end
84
+
85
+ def gnome_terminal?
86
+ terminal_command == "gnome-terminal" or terminal_command == "gnome-terminal-server"
87
+ end
88
+
89
+ def actual_xterm?
90
+ terminal_command == "xterm"
91
+ end
92
+
93
+ def iterm?
94
+ env.include? 'ITERM_SESSION_ID' or env['TERM_PROGRAM'] == 'iTerm.app' or terminal_command == 'iTerm2'
95
+ end
96
+
97
+ def xterm_true_color?
98
+ `xterm -version`[/\d+/].to_i >= 282
99
+ rescue Errno::ENOENT
100
+ false
101
+ end
102
+
103
+ def gnome_true_color?
104
+ major, minor = `gnome-terminal --version`[/\d+\.\d+/].split(?.).map(&:to_i)
105
+ major == 3 ? minor > 11 : major > 3
106
+ rescue Errno::ENOENT
107
+ false
108
+ end
109
+
110
+ def iterm_true_color?
111
+ return false unless iterm_version
112
+ major, minor, patch = iterm_version.split('.').map(&:to_i)
113
+ if major == 2 and minor == 9
114
+ patch > 20130908
115
+ else
116
+ major >= 3
117
+ end
118
+ end
119
+
120
+ def iterm_version
121
+ @iterm_version ||= env['TERM_PROGRAM_VERSION']
122
+ @iterm_version ||= if shell_out? and iterm_path = commands.detect { |c| c["/iTerm.app/Contents/MacOS/iTerm2"] }
123
+ info_path = Shellwords.escape(File.expand_path('../../Info', iterm_path))
124
+ `defaults read #{info_path} CFBundleVersion`.chomp if system 'which defaults >/dev/null'
125
+ end
126
+ rescue Errno::ENOENT
127
+ end
128
+
129
+ def terminal_command(command = full_terminal_command)
130
+ command &&= File.basename(command)
131
+ command &&= command[/\S+/]
132
+ command
133
+ end
134
+
135
+ def full_terminal_command
136
+ commands.detect do |command|
137
+ command = terminal_command(command)
138
+ COMMANDS.include?(command) or command == env['TERM_PROGRAM']
139
+ end
140
+ end
141
+
142
+ def commands
143
+ @commands ||= begin
144
+ commands = []
145
+ pid = Process.pid
146
+ processes = self.processes
147
+ while pid and processes.include? pid
148
+ commands << processes[pid][:command]
149
+ pid = processes[pid][:ppid]
150
+ end
151
+ commands
152
+ end
153
+ end
154
+
155
+ def processes
156
+ return {} unless shell_out?
157
+ @processes ||= begin
158
+ ps = `ps -A -o pid,ppid,command`.scan(/^\s*(\d+)\s+(\d+)\s+(.+)$/)
159
+ Hash[ps.map { |pid, ppid, command| [pid.to_i, ppid: ppid.to_i, command: command] }]
160
+ end
161
+ rescue Errno::ENOENT
162
+ {}
163
+ end
164
+
165
+ def shell_out?
166
+ @shell_out and not windows?
167
+ end
168
+
169
+ def windows?
170
+ File::ALT_SEPARATOR == "\\"
171
+ end
172
+
173
+ def supported?(value)
174
+ case supported
175
+ when Array then supported.include? value
176
+ when true, false then supported
177
+ when Integer then supported == value
178
+ else false
179
+ end
180
+ end
181
+
182
+ def maximum
183
+ case supported
184
+ when Array then supported.max
185
+ when true then 1/0.0
186
+ when Integer then supported
187
+ else 0
188
+ end
189
+ end
190
+
191
+ def minimum
192
+ case supported
193
+ when Array then supported.min
194
+ when true then 8
195
+ when Integer then supported
196
+ else 0
197
+ end
198
+ end
199
+ end
200
+ end
@@ -0,0 +1,591 @@
1
+ module Hansi
2
+ PALETTES = {}
3
+ private_constant :PALETTES
4
+
5
+ reset_css = {
6
+ color: :inherit,
7
+ font_weight: :normal,
8
+ font_syle: :normal,
9
+ text_decoration: :none,
10
+ visibility: :visible
11
+ }
12
+
13
+ PALETTES['special'] = {
14
+ reset: Hansi::Special.new(0, reset_css),
15
+ bold: Hansi::Special.new(1, font_weight: :bold),
16
+ faint: Hansi::Special.new(2, font_weight: :lighter),
17
+ italic: Hansi::Special.new(3, font_style: :italic),
18
+ underline: Hansi::Special.new(4, text_decoration: :underline),
19
+ blink: Hansi::Special.new(5, text_decoration: :blink),
20
+ rapid_blink: Hansi::Special.new(6, text_decoration: :blink),
21
+ inverse: Hansi::Special.new(7),
22
+ reverse: Hansi::Special.new(7),
23
+ conceal: Hansi::Special.new(8, visibility: :hidden),
24
+ crossed_out: Hansi::Special.new(9, text_decoration: :line_through),
25
+ default: Hansi::Special.new(10),
26
+ fraktur: Hansi::Special.new(20),
27
+ framed: Hansi::Special.new(51),
28
+ encircled: Hansi::Special.new(52),
29
+ overline: Hansi::Special.new(54, text_decoration: :overline),
30
+ }
31
+
32
+ PALETTES['ansi'] = {
33
+ "\e[30m" => Hansi[ 0, 0, 0 ],
34
+ "\e[31m" => Hansi[ 194, 54, 33 ],
35
+ "\e[32m" => Hansi[ 37, 188, 36 ],
36
+ "\e[33m" => Hansi[ 173, 173, 39 ],
37
+ "\e[34m" => Hansi[ 73, 46, 225 ],
38
+ "\e[35m" => Hansi[ 211, 56, 211 ],
39
+ "\e[36m" => Hansi[ 51, 187, 200 ],
40
+ "\e[37m" => Hansi[ 203, 204, 205 ]
41
+ }
42
+
43
+ PALETTES['xterm'] = {
44
+ "\e[90m" => Hansi[ 129, 131, 131 ],
45
+ "\e[91m" => Hansi[ 252, 57, 31 ],
46
+ "\e[92m" => Hansi[ 49, 231, 34 ],
47
+ "\e[93m" => Hansi[ 234, 236, 35 ],
48
+ "\e[94m" => Hansi[ 88, 51, 255 ],
49
+ "\e[95m" => Hansi[ 249, 53, 248 ],
50
+ "\e[96m" => Hansi[ 20, 240, 240 ],
51
+ "\e[97m" => Hansi[ 233, 235, 235 ]
52
+ }.merge(PALETTES['ansi'])
53
+
54
+ PALETTES['xterm-88color'] = {
55
+ "\e[38;5;0m" => Hansi[ 0, 0, 0 ],
56
+ "\e[38;5;1m" => Hansi[ 205, 0, 0 ],
57
+ "\e[38;5;2m" => Hansi[ 0, 205, 0 ],
58
+ "\e[38;5;3m" => Hansi[ 205, 205, 0 ],
59
+ "\e[38;5;4m" => Hansi[ 30, 144, 255 ],
60
+ "\e[38;5;5m" => Hansi[ 205, 0, 205 ],
61
+ "\e[38;5;6m" => Hansi[ 0, 205, 205 ],
62
+ "\e[38;5;7m" => Hansi[ 229, 229, 229 ],
63
+ "\e[38;5;8m" => Hansi[ 127, 127, 127 ],
64
+ "\e[38;5;9m" => Hansi[ 255, 0, 0 ],
65
+ "\e[38;5;10m" => Hansi[ 0, 255, 0 ],
66
+ "\e[38;5;11m" => Hansi[ 255, 255, 0 ],
67
+ "\e[38;5;12m" => Hansi[ 99, 184, 255 ],
68
+ "\e[38;5;13m" => Hansi[ 255, 0, 255 ],
69
+ "\e[38;5;14m" => Hansi[ 0, 255, 255 ],
70
+ "\e[38;5;15m" => Hansi[ 255, 255, 255 ],
71
+ "\e[38;5;16m" => Hansi[ 0, 0, 0 ],
72
+ "\e[38;5;17m" => Hansi[ 0, 0, 139 ],
73
+ "\e[38;5;18m" => Hansi[ 0, 0, 205 ],
74
+ "\e[38;5;19m" => Hansi[ 0, 0, 255 ],
75
+ "\e[38;5;20m" => Hansi[ 0, 139, 0 ],
76
+ "\e[38;5;21m" => Hansi[ 0, 139, 139 ],
77
+ "\e[38;5;22m" => Hansi[ 0, 139, 205 ],
78
+ "\e[38;5;23m" => Hansi[ 0, 139, 255 ],
79
+ "\e[38;5;24m" => Hansi[ 0, 205, 0 ],
80
+ "\e[38;5;25m" => Hansi[ 0, 205, 139 ],
81
+ "\e[38;5;26m" => Hansi[ 0, 205, 205 ],
82
+ "\e[38;5;27m" => Hansi[ 0, 205, 255 ],
83
+ "\e[38;5;28m" => Hansi[ 0, 255, 0 ],
84
+ "\e[38;5;29m" => Hansi[ 0, 255, 139 ],
85
+ "\e[38;5;30m" => Hansi[ 0, 255, 205 ],
86
+ "\e[38;5;31m" => Hansi[ 0, 255, 255 ],
87
+ "\e[38;5;32m" => Hansi[ 139, 0, 0 ],
88
+ "\e[38;5;33m" => Hansi[ 139, 0, 139 ],
89
+ "\e[38;5;34m" => Hansi[ 139, 0, 205 ],
90
+ "\e[38;5;35m" => Hansi[ 139, 0, 255 ],
91
+ "\e[38;5;36m" => Hansi[ 139, 139, 0 ],
92
+ "\e[38;5;37m" => Hansi[ 139, 139, 139 ],
93
+ "\e[38;5;38m" => Hansi[ 139, 139, 205 ],
94
+ "\e[38;5;39m" => Hansi[ 139, 139, 255 ],
95
+ "\e[38;5;40m" => Hansi[ 139, 205, 0 ],
96
+ "\e[38;5;41m" => Hansi[ 139, 205, 139 ],
97
+ "\e[38;5;42m" => Hansi[ 139, 205, 205 ],
98
+ "\e[38;5;43m" => Hansi[ 139, 205, 255 ],
99
+ "\e[38;5;44m" => Hansi[ 139, 255, 0 ],
100
+ "\e[38;5;45m" => Hansi[ 139, 255, 139 ],
101
+ "\e[38;5;46m" => Hansi[ 139, 255, 205 ],
102
+ "\e[38;5;47m" => Hansi[ 139, 255, 255 ],
103
+ "\e[38;5;48m" => Hansi[ 205, 0, 0 ],
104
+ "\e[38;5;49m" => Hansi[ 205, 0, 139 ],
105
+ "\e[38;5;50m" => Hansi[ 205, 0, 205 ],
106
+ "\e[38;5;51m" => Hansi[ 205, 0, 255 ],
107
+ "\e[38;5;52m" => Hansi[ 205, 139, 0 ],
108
+ "\e[38;5;53m" => Hansi[ 205, 139, 139 ],
109
+ "\e[38;5;54m" => Hansi[ 205, 139, 205 ],
110
+ "\e[38;5;55m" => Hansi[ 205, 139, 255 ],
111
+ "\e[38;5;56m" => Hansi[ 205, 205, 0 ],
112
+ "\e[38;5;57m" => Hansi[ 205, 205, 139 ],
113
+ "\e[38;5;58m" => Hansi[ 205, 205, 205 ],
114
+ "\e[38;5;59m" => Hansi[ 205, 205, 255 ],
115
+ "\e[38;5;60m" => Hansi[ 205, 255, 0 ],
116
+ "\e[38;5;61m" => Hansi[ 205, 255, 139 ],
117
+ "\e[38;5;62m" => Hansi[ 205, 255, 205 ],
118
+ "\e[38;5;63m" => Hansi[ 205, 255, 255 ],
119
+ "\e[38;5;64m" => Hansi[ 255, 0, 0 ],
120
+ "\e[38;5;65m" => Hansi[ 255, 0, 139 ],
121
+ "\e[38;5;66m" => Hansi[ 255, 0, 205 ],
122
+ "\e[38;5;67m" => Hansi[ 255, 0, 255 ],
123
+ "\e[38;5;68m" => Hansi[ 255, 139, 0 ],
124
+ "\e[38;5;69m" => Hansi[ 255, 139, 139 ],
125
+ "\e[38;5;70m" => Hansi[ 255, 139, 205 ],
126
+ "\e[38;5;71m" => Hansi[ 255, 139, 255 ],
127
+ "\e[38;5;72m" => Hansi[ 255, 205, 0 ],
128
+ "\e[38;5;73m" => Hansi[ 255, 205, 139 ],
129
+ "\e[38;5;74m" => Hansi[ 255, 205, 205 ],
130
+ "\e[38;5;75m" => Hansi[ 255, 205, 255 ],
131
+ "\e[38;5;76m" => Hansi[ 255, 255, 0 ],
132
+ "\e[38;5;77m" => Hansi[ 255, 255, 139 ],
133
+ "\e[38;5;78m" => Hansi[ 255, 255, 205 ],
134
+ "\e[38;5;79m" => Hansi[ 255, 255, 255 ],
135
+ "\e[38;5;80m" => Hansi[ 46, 46, 46 ],
136
+ "\e[38;5;81m" => Hansi[ 92, 92, 92 ],
137
+ "\e[38;5;82m" => Hansi[ 113, 113, 113 ],
138
+ "\e[38;5;83m" => Hansi[ 139, 139, 139 ],
139
+ "\e[38;5;84m" => Hansi[ 162, 162, 162 ],
140
+ "\e[38;5;85m" => Hansi[ 185, 185, 185 ],
141
+ "\e[38;5;86m" => Hansi[ 208, 208, 208 ],
142
+ "\e[38;5;87m" => Hansi[ 231, 231, 231 ]
143
+ }
144
+
145
+ PALETTES['xterm-256color'] = {
146
+ "\e[38;5;0m" => Hansi["000000"],
147
+ "\e[38;5;1m" => Hansi["800000"],
148
+ "\e[38;5;2m" => Hansi["008000"],
149
+ "\e[38;5;3m" => Hansi["808000"],
150
+ "\e[38;5;4m" => Hansi["000080"],
151
+ "\e[38;5;5m" => Hansi["800080"],
152
+ "\e[38;5;6m" => Hansi["008080"],
153
+ "\e[38;5;7m" => Hansi["c0c0c0"],
154
+ "\e[38;5;8m" => Hansi["808080"],
155
+ "\e[38;5;9m" => Hansi["ff0000"],
156
+ "\e[38;5;10m" => Hansi["00ff00"],
157
+ "\e[38;5;11m" => Hansi["ffff00"],
158
+ "\e[38;5;12m" => Hansi["0000ff"],
159
+ "\e[38;5;13m" => Hansi["ff00ff"],
160
+ "\e[38;5;14m" => Hansi["00ffff"],
161
+ "\e[38;5;15m" => Hansi["ffffff"],
162
+ "\e[38;5;16m" => Hansi["000000"],
163
+ "\e[38;5;17m" => Hansi["00005f"],
164
+ "\e[38;5;18m" => Hansi["000087"],
165
+ "\e[38;5;19m" => Hansi["0000af"],
166
+ "\e[38;5;20m" => Hansi["0000d7"],
167
+ "\e[38;5;21m" => Hansi["0000ff"],
168
+ "\e[38;5;22m" => Hansi["005f00"],
169
+ "\e[38;5;23m" => Hansi["005f5f"],
170
+ "\e[38;5;24m" => Hansi["005f87"],
171
+ "\e[38;5;25m" => Hansi["005faf"],
172
+ "\e[38;5;26m" => Hansi["005fd7"],
173
+ "\e[38;5;27m" => Hansi["005fff"],
174
+ "\e[38;5;28m" => Hansi["008700"],
175
+ "\e[38;5;29m" => Hansi["00875f"],
176
+ "\e[38;5;30m" => Hansi["008787"],
177
+ "\e[38;5;31m" => Hansi["0087af"],
178
+ "\e[38;5;32m" => Hansi["0087d7"],
179
+ "\e[38;5;33m" => Hansi["0087ff"],
180
+ "\e[38;5;34m" => Hansi["00af00"],
181
+ "\e[38;5;35m" => Hansi["00af5f"],
182
+ "\e[38;5;36m" => Hansi["00af87"],
183
+ "\e[38;5;37m" => Hansi["00afaf"],
184
+ "\e[38;5;38m" => Hansi["00afd7"],
185
+ "\e[38;5;39m" => Hansi["00afff"],
186
+ "\e[38;5;40m" => Hansi["00d700"],
187
+ "\e[38;5;41m" => Hansi["00d75f"],
188
+ "\e[38;5;42m" => Hansi["00d787"],
189
+ "\e[38;5;43m" => Hansi["00d7af"],
190
+ "\e[38;5;44m" => Hansi["00d7d7"],
191
+ "\e[38;5;45m" => Hansi["00d7ff"],
192
+ "\e[38;5;46m" => Hansi["00ff00"],
193
+ "\e[38;5;47m" => Hansi["00ff5f"],
194
+ "\e[38;5;48m" => Hansi["00ff87"],
195
+ "\e[38;5;49m" => Hansi["00ffaf"],
196
+ "\e[38;5;50m" => Hansi["00ffd7"],
197
+ "\e[38;5;51m" => Hansi["00ffff"],
198
+ "\e[38;5;52m" => Hansi["5f0000"],
199
+ "\e[38;5;53m" => Hansi["5f005f"],
200
+ "\e[38;5;54m" => Hansi["5f0087"],
201
+ "\e[38;5;55m" => Hansi["5f00af"],
202
+ "\e[38;5;56m" => Hansi["5f00d7"],
203
+ "\e[38;5;57m" => Hansi["5f00ff"],
204
+ "\e[38;5;58m" => Hansi["5f5f00"],
205
+ "\e[38;5;59m" => Hansi["5f5f5f"],
206
+ "\e[38;5;60m" => Hansi["5f5f87"],
207
+ "\e[38;5;61m" => Hansi["5f5faf"],
208
+ "\e[38;5;62m" => Hansi["5f5fd7"],
209
+ "\e[38;5;63m" => Hansi["5f5fff"],
210
+ "\e[38;5;64m" => Hansi["5f8700"],
211
+ "\e[38;5;65m" => Hansi["5f875f"],
212
+ "\e[38;5;66m" => Hansi["5f8787"],
213
+ "\e[38;5;67m" => Hansi["5f87af"],
214
+ "\e[38;5;68m" => Hansi["5f87d7"],
215
+ "\e[38;5;69m" => Hansi["5f87ff"],
216
+ "\e[38;5;70m" => Hansi["5faf00"],
217
+ "\e[38;5;71m" => Hansi["5faf5f"],
218
+ "\e[38;5;72m" => Hansi["5faf87"],
219
+ "\e[38;5;73m" => Hansi["5fafaf"],
220
+ "\e[38;5;74m" => Hansi["5fafd7"],
221
+ "\e[38;5;75m" => Hansi["5fafff"],
222
+ "\e[38;5;76m" => Hansi["5fd700"],
223
+ "\e[38;5;77m" => Hansi["5fd75f"],
224
+ "\e[38;5;78m" => Hansi["5fd787"],
225
+ "\e[38;5;79m" => Hansi["5fd7af"],
226
+ "\e[38;5;80m" => Hansi["5fd7d7"],
227
+ "\e[38;5;81m" => Hansi["5fd7ff"],
228
+ "\e[38;5;82m" => Hansi["5fff00"],
229
+ "\e[38;5;83m" => Hansi["5fff5f"],
230
+ "\e[38;5;84m" => Hansi["5fff87"],
231
+ "\e[38;5;85m" => Hansi["5fffaf"],
232
+ "\e[38;5;86m" => Hansi["5fffd7"],
233
+ "\e[38;5;87m" => Hansi["5fffff"],
234
+ "\e[38;5;88m" => Hansi["870000"],
235
+ "\e[38;5;89m" => Hansi["87005f"],
236
+ "\e[38;5;90m" => Hansi["870087"],
237
+ "\e[38;5;91m" => Hansi["8700af"],
238
+ "\e[38;5;92m" => Hansi["8700d7"],
239
+ "\e[38;5;93m" => Hansi["8700ff"],
240
+ "\e[38;5;94m" => Hansi["875f00"],
241
+ "\e[38;5;95m" => Hansi["875f5f"],
242
+ "\e[38;5;96m" => Hansi["875f87"],
243
+ "\e[38;5;97m" => Hansi["875faf"],
244
+ "\e[38;5;98m" => Hansi["875fd7"],
245
+ "\e[38;5;99m" => Hansi["875fff"],
246
+ "\e[38;5;100m" => Hansi["878700"],
247
+ "\e[38;5;101m" => Hansi["87875f"],
248
+ "\e[38;5;102m" => Hansi["878787"],
249
+ "\e[38;5;103m" => Hansi["8787af"],
250
+ "\e[38;5;104m" => Hansi["8787d7"],
251
+ "\e[38;5;105m" => Hansi["8787ff"],
252
+ "\e[38;5;106m" => Hansi["87af00"],
253
+ "\e[38;5;107m" => Hansi["87af5f"],
254
+ "\e[38;5;108m" => Hansi["87af87"],
255
+ "\e[38;5;109m" => Hansi["87afaf"],
256
+ "\e[38;5;110m" => Hansi["87afd7"],
257
+ "\e[38;5;111m" => Hansi["87afff"],
258
+ "\e[38;5;112m" => Hansi["87d700"],
259
+ "\e[38;5;113m" => Hansi["87d75f"],
260
+ "\e[38;5;114m" => Hansi["87d787"],
261
+ "\e[38;5;115m" => Hansi["87d7af"],
262
+ "\e[38;5;116m" => Hansi["87d7d7"],
263
+ "\e[38;5;117m" => Hansi["87d7ff"],
264
+ "\e[38;5;118m" => Hansi["87ff00"],
265
+ "\e[38;5;119m" => Hansi["87ff5f"],
266
+ "\e[38;5;120m" => Hansi["87ff87"],
267
+ "\e[38;5;121m" => Hansi["87ffaf"],
268
+ "\e[38;5;122m" => Hansi["87ffd7"],
269
+ "\e[38;5;123m" => Hansi["87ffff"],
270
+ "\e[38;5;124m" => Hansi["af0000"],
271
+ "\e[38;5;125m" => Hansi["af005f"],
272
+ "\e[38;5;126m" => Hansi["af0087"],
273
+ "\e[38;5;127m" => Hansi["af00af"],
274
+ "\e[38;5;128m" => Hansi["af00d7"],
275
+ "\e[38;5;129m" => Hansi["af00ff"],
276
+ "\e[38;5;130m" => Hansi["af5f00"],
277
+ "\e[38;5;131m" => Hansi["af5f5f"],
278
+ "\e[38;5;132m" => Hansi["af5f87"],
279
+ "\e[38;5;133m" => Hansi["af5faf"],
280
+ "\e[38;5;134m" => Hansi["af5fd7"],
281
+ "\e[38;5;135m" => Hansi["af5fff"],
282
+ "\e[38;5;136m" => Hansi["af8700"],
283
+ "\e[38;5;137m" => Hansi["af875f"],
284
+ "\e[38;5;138m" => Hansi["af8787"],
285
+ "\e[38;5;139m" => Hansi["af87af"],
286
+ "\e[38;5;140m" => Hansi["af87d7"],
287
+ "\e[38;5;141m" => Hansi["af87ff"],
288
+ "\e[38;5;142m" => Hansi["afaf00"],
289
+ "\e[38;5;143m" => Hansi["afaf5f"],
290
+ "\e[38;5;144m" => Hansi["afaf87"],
291
+ "\e[38;5;145m" => Hansi["afafaf"],
292
+ "\e[38;5;146m" => Hansi["afafd7"],
293
+ "\e[38;5;147m" => Hansi["afafff"],
294
+ "\e[38;5;148m" => Hansi["afd700"],
295
+ "\e[38;5;149m" => Hansi["afd75f"],
296
+ "\e[38;5;150m" => Hansi["afd787"],
297
+ "\e[38;5;151m" => Hansi["afd7af"],
298
+ "\e[38;5;152m" => Hansi["afd7d7"],
299
+ "\e[38;5;153m" => Hansi["afd7ff"],
300
+ "\e[38;5;154m" => Hansi["afff00"],
301
+ "\e[38;5;155m" => Hansi["afff5f"],
302
+ "\e[38;5;156m" => Hansi["afff87"],
303
+ "\e[38;5;157m" => Hansi["afffaf"],
304
+ "\e[38;5;158m" => Hansi["afffd7"],
305
+ "\e[38;5;159m" => Hansi["afffff"],
306
+ "\e[38;5;160m" => Hansi["d70000"],
307
+ "\e[38;5;161m" => Hansi["d7005f"],
308
+ "\e[38;5;162m" => Hansi["d70087"],
309
+ "\e[38;5;163m" => Hansi["d700af"],
310
+ "\e[38;5;164m" => Hansi["d700d7"],
311
+ "\e[38;5;165m" => Hansi["d700ff"],
312
+ "\e[38;5;166m" => Hansi["d75f00"],
313
+ "\e[38;5;167m" => Hansi["d75f5f"],
314
+ "\e[38;5;168m" => Hansi["d75f87"],
315
+ "\e[38;5;169m" => Hansi["d75faf"],
316
+ "\e[38;5;170m" => Hansi["d75fd7"],
317
+ "\e[38;5;171m" => Hansi["d75fff"],
318
+ "\e[38;5;172m" => Hansi["d78700"],
319
+ "\e[38;5;173m" => Hansi["d7875f"],
320
+ "\e[38;5;174m" => Hansi["d78787"],
321
+ "\e[38;5;175m" => Hansi["d787af"],
322
+ "\e[38;5;176m" => Hansi["d787d7"],
323
+ "\e[38;5;177m" => Hansi["d787ff"],
324
+ "\e[38;5;178m" => Hansi["dfaf00"],
325
+ "\e[38;5;179m" => Hansi["dfaf5f"],
326
+ "\e[38;5;180m" => Hansi["dfaf87"],
327
+ "\e[38;5;181m" => Hansi["dfafaf"],
328
+ "\e[38;5;182m" => Hansi["dfafdf"],
329
+ "\e[38;5;183m" => Hansi["dfafff"],
330
+ "\e[38;5;184m" => Hansi["dfdf00"],
331
+ "\e[38;5;185m" => Hansi["dfdf5f"],
332
+ "\e[38;5;186m" => Hansi["dfdf87"],
333
+ "\e[38;5;187m" => Hansi["dfdfaf"],
334
+ "\e[38;5;188m" => Hansi["dfdfdf"],
335
+ "\e[38;5;189m" => Hansi["dfdfff"],
336
+ "\e[38;5;190m" => Hansi["dfff00"],
337
+ "\e[38;5;191m" => Hansi["dfff5f"],
338
+ "\e[38;5;192m" => Hansi["dfff87"],
339
+ "\e[38;5;193m" => Hansi["dfffaf"],
340
+ "\e[38;5;194m" => Hansi["dfffdf"],
341
+ "\e[38;5;195m" => Hansi["dfffff"],
342
+ "\e[38;5;196m" => Hansi["ff0000"],
343
+ "\e[38;5;197m" => Hansi["ff005f"],
344
+ "\e[38;5;198m" => Hansi["ff0087"],
345
+ "\e[38;5;199m" => Hansi["ff00af"],
346
+ "\e[38;5;200m" => Hansi["ff00df"],
347
+ "\e[38;5;201m" => Hansi["ff00ff"],
348
+ "\e[38;5;202m" => Hansi["ff5f00"],
349
+ "\e[38;5;203m" => Hansi["ff5f5f"],
350
+ "\e[38;5;204m" => Hansi["ff5f87"],
351
+ "\e[38;5;205m" => Hansi["ff5faf"],
352
+ "\e[38;5;206m" => Hansi["ff5fdf"],
353
+ "\e[38;5;207m" => Hansi["ff5fff"],
354
+ "\e[38;5;208m" => Hansi["ff8700"],
355
+ "\e[38;5;209m" => Hansi["ff875f"],
356
+ "\e[38;5;210m" => Hansi["ff8787"],
357
+ "\e[38;5;211m" => Hansi["ff87af"],
358
+ "\e[38;5;212m" => Hansi["ff87df"],
359
+ "\e[38;5;213m" => Hansi["ff87ff"],
360
+ "\e[38;5;214m" => Hansi["ffaf00"],
361
+ "\e[38;5;215m" => Hansi["ffaf5f"],
362
+ "\e[38;5;216m" => Hansi["ffaf87"],
363
+ "\e[38;5;217m" => Hansi["ffafaf"],
364
+ "\e[38;5;218m" => Hansi["ffafdf"],
365
+ "\e[38;5;219m" => Hansi["ffafff"],
366
+ "\e[38;5;220m" => Hansi["ffdf00"],
367
+ "\e[38;5;221m" => Hansi["ffdf5f"],
368
+ "\e[38;5;222m" => Hansi["ffdf87"],
369
+ "\e[38;5;223m" => Hansi["ffdfaf"],
370
+ "\e[38;5;224m" => Hansi["ffdfdf"],
371
+ "\e[38;5;225m" => Hansi["ffdfff"],
372
+ "\e[38;5;226m" => Hansi["ffff00"],
373
+ "\e[38;5;227m" => Hansi["ffff5f"],
374
+ "\e[38;5;228m" => Hansi["ffff87"],
375
+ "\e[38;5;229m" => Hansi["ffffaf"],
376
+ "\e[38;5;230m" => Hansi["ffffdf"],
377
+ "\e[38;5;231m" => Hansi["ffffff"],
378
+ "\e[38;5;232m" => Hansi["080808"],
379
+ "\e[38;5;233m" => Hansi["121212"],
380
+ "\e[38;5;234m" => Hansi["1c1c1c"],
381
+ "\e[38;5;235m" => Hansi["262626"],
382
+ "\e[38;5;236m" => Hansi["303030"],
383
+ "\e[38;5;237m" => Hansi["3a3a3a"],
384
+ "\e[38;5;238m" => Hansi["444444"],
385
+ "\e[38;5;239m" => Hansi["4e4e4e"],
386
+ "\e[38;5;240m" => Hansi["585858"],
387
+ "\e[38;5;241m" => Hansi["626262"],
388
+ "\e[38;5;242m" => Hansi["6c6c6c"],
389
+ "\e[38;5;243m" => Hansi["767676"],
390
+ "\e[38;5;244m" => Hansi["808080"],
391
+ "\e[38;5;245m" => Hansi["8a8a8a"],
392
+ "\e[38;5;246m" => Hansi["949494"],
393
+ "\e[38;5;247m" => Hansi["9e9e9e"],
394
+ "\e[38;5;248m" => Hansi["a8a8a8"],
395
+ "\e[38;5;249m" => Hansi["b2b2b2"],
396
+ "\e[38;5;250m" => Hansi["bcbcbc"],
397
+ "\e[38;5;251m" => Hansi["c6c6c6"],
398
+ "\e[38;5;252m" => Hansi["d0d0d0"],
399
+ "\e[38;5;253m" => Hansi["dadada"],
400
+ "\e[38;5;254m" => Hansi["e4e4e4"],
401
+ "\e[38;5;255m" => Hansi["eeeeee"]
402
+ }
403
+
404
+ PALETTES['web'] = {
405
+ aliceblue: Hansi["f0f8ff"],
406
+ aluminum: Hansi["999999"],
407
+ antiquewhite: Hansi["faebd7"],
408
+ aqua: Hansi["00ffff"],
409
+ aquamarine: Hansi["7fffd4"],
410
+ azure: Hansi["f0ffff"],
411
+ beccapurple: Hansi["663399"],
412
+ beige: Hansi["f5f5dc"],
413
+ bisque: Hansi["ffe4c4"],
414
+ black: Hansi["000000"],
415
+ blanchedalmond: Hansi["ffebcd"],
416
+ blue: Hansi["0000ff"],
417
+ blueviolet: Hansi["8a2be2"],
418
+ brown: Hansi["a52a2a"],
419
+ burlywood: Hansi["deb887"],
420
+ cadetblue: Hansi["5f9ea0"],
421
+ carnation: Hansi["ff5ed0"],
422
+ cayenne: Hansi["8d0000"],
423
+ chartreuse: Hansi["7fff00"],
424
+ chocolate: Hansi["d2691e"],
425
+ coolcopper: Hansi["d98719"],
426
+ copper: Hansi["b87333"],
427
+ coral: Hansi["ff7f50"],
428
+ cornflowerblue: Hansi["6495ed"],
429
+ cornsilk: Hansi["fff8dc"],
430
+ crimson: Hansi["dc143c"],
431
+ cyan: Hansi["00ffff"],
432
+ darkblue: Hansi["00008b"],
433
+ darkcyan: Hansi["008b8b"],
434
+ darkgoldenrod: Hansi["b8860b"],
435
+ darkgray: Hansi["a9a9a9"],
436
+ darkgreen: Hansi["006400"],
437
+ darkgrey: Hansi["a9a9a9"],
438
+ darkkhaki: Hansi["bdb76b"],
439
+ darkmagenta: Hansi["8b008b"],
440
+ darkolivegreen: Hansi["556b2f"],
441
+ darkorange: Hansi["ff8c00"],
442
+ darkorchid: Hansi["9932cc"],
443
+ darkred: Hansi["8b0000"],
444
+ darksalmon: Hansi["e9967a"],
445
+ darkseagreen: Hansi["8fbc8f"],
446
+ darkslateblue: Hansi["483d8b"],
447
+ darkslategray: Hansi["2f4f4f"],
448
+ darkslategrey: Hansi["2f4f4f"],
449
+ darkturquoise: Hansi["00ced1"],
450
+ darkviolet: Hansi["9400d3"],
451
+ deeppink: Hansi["ff1493"],
452
+ deepskyblue: Hansi["00bfbf"],
453
+ dimgray: Hansi["696969"],
454
+ dimgrey: Hansi["696969"],
455
+ dodgerblue: Hansi["1e90ff"],
456
+ feldspar: Hansi["d19275"],
457
+ firebrick: Hansi["b22222"],
458
+ floralwhite: Hansi["fffaf0"],
459
+ forestgreen: Hansi["228b22"],
460
+ fuchsia: Hansi["ff00ff"],
461
+ gainsboro: Hansi["dcdcdc"],
462
+ ghostwhite: Hansi["f8f8ff"],
463
+ gold: Hansi["ffd700"],
464
+ goldenrod: Hansi["daa520"],
465
+ gray: Hansi["808080"],
466
+ gray10: Hansi["1a1a1a"],
467
+ gray20: Hansi["333333"],
468
+ gray30: Hansi["4d4d4d"],
469
+ gray40: Hansi["666666"],
470
+ gray50: Hansi["808080"],
471
+ gray60: Hansi["999999"],
472
+ gray70: Hansi["b3b3b3"],
473
+ gray80: Hansi["cccccc"],
474
+ gray90: Hansi["e6e6e6"],
475
+ green: Hansi["008000"],
476
+ greenyellow: Hansi["adff2f"],
477
+ grey: Hansi["808080"],
478
+ grey10: Hansi["1a1a1a"],
479
+ grey20: Hansi["333333"],
480
+ grey30: Hansi["4d4d4d"],
481
+ grey40: Hansi["666666"],
482
+ grey50: Hansi["808080"],
483
+ grey60: Hansi["999999"],
484
+ grey70: Hansi["b3b3b3"],
485
+ grey80: Hansi["cccccc"],
486
+ grey90: Hansi["e6e6e6"],
487
+ honeydew: Hansi["f0fff0"],
488
+ hotpink: Hansi["ff69b4"],
489
+ indianred: Hansi["cd5c5c"],
490
+ indigo: Hansi["4b0082"],
491
+ iron: Hansi["4c4c4c"],
492
+ ivory: Hansi["fffff0"],
493
+ khaki: Hansi["f0e68c"],
494
+ lavender: Hansi["e6e6fa"],
495
+ lavenderblush: Hansi["fff0f5"],
496
+ lawngreen: Hansi["7cfc00"],
497
+ lead: Hansi["191919"],
498
+ lemonchiffon: Hansi["fffacd"],
499
+ lightblue: Hansi["add8e6"],
500
+ lightcoral: Hansi["f08080"],
501
+ lightcyan: Hansi["e0ffff"],
502
+ lightgoldenrodyellow: Hansi["fafad2"],
503
+ lightgray: Hansi["d3d3d3"],
504
+ lightgreen: Hansi["90ee90"],
505
+ lightgrey: Hansi["d3d3d3"],
506
+ lightpink: Hansi["ffb6c1"],
507
+ lightsalmon: Hansi["ffa07a"],
508
+ lightseagreen: Hansi["20b2aa"],
509
+ lightskyblue: Hansi["87cefa"],
510
+ lightslateblue: Hansi["8470ff"],
511
+ lightslategray: Hansi["778899"],
512
+ lightslategrey: Hansi["778899"],
513
+ lightsteelblue: Hansi["b0c4de"],
514
+ lightyellow: Hansi["ffffe0"],
515
+ lime: Hansi["00ff00"],
516
+ limegreen: Hansi["32cd32"],
517
+ linen: Hansi["faf0e6"],
518
+ magenta: Hansi["ff00ff"],
519
+ magnesium: Hansi["b3b3b3"],
520
+ maroon: Hansi["800000"],
521
+ mediumaquamarine: Hansi["66cdaa"],
522
+ mediumblue: Hansi["0000cd"],
523
+ mediumorchid: Hansi["ba55d3"],
524
+ mediumpurple: Hansi["9370db"],
525
+ mediumseagreen: Hansi["3cb371"],
526
+ mediumslateblue: Hansi["7b68ee"],
527
+ mediumspringgreen: Hansi["00fa9a"],
528
+ mediumturquoise: Hansi["48d1cc"],
529
+ mediumvioletred: Hansi["c71585"],
530
+ mercury: Hansi["e6e6e6"],
531
+ midnightblue: Hansi["191970"],
532
+ mintcream: Hansi["f5fffa"],
533
+ mistyrose: Hansi["ffe4e1"],
534
+ moccasin: Hansi["ffe4b5"],
535
+ navajowhite: Hansi["ffdead"],
536
+ navy: Hansi["000080"],
537
+ nickel: Hansi["808080"],
538
+ oldlace: Hansi["fdf5e6"],
539
+ olive: Hansi["808000"],
540
+ olivedrab: Hansi["6b8e23"],
541
+ orange: Hansi["ffa500"],
542
+ orangered: Hansi["ff4500"],
543
+ orchid: Hansi["da70d6"],
544
+ palegoldenrod: Hansi["eee8aa"],
545
+ palegreen: Hansi["98fb98"],
546
+ paleturquoise: Hansi["afeeee"],
547
+ palevioletred: Hansi["db7093"],
548
+ papayawhip: Hansi["ffefd5"],
549
+ peachpuff: Hansi["ffdab9"],
550
+ peru: Hansi["cd853f"],
551
+ pink: Hansi["ffc0cb"],
552
+ plum: Hansi["dda0dd"],
553
+ poly: Hansi["600000"],
554
+ polysilicon: Hansi["600000"],
555
+ powderblue: Hansi["b0e0e6"],
556
+ purple: Hansi["800080"],
557
+ rebeccapurple: Hansi["663399"],
558
+ red: Hansi["ff0000"],
559
+ rosybrown: Hansi["bc8f8f"],
560
+ royalblue: Hansi["4169e1"],
561
+ saddlebrown: Hansi["8b4513"],
562
+ salmon: Hansi["fa8072"],
563
+ sandybrown: Hansi["f4a460"],
564
+ seagreen: Hansi["2e8b57"],
565
+ seashell: Hansi["fff5ee"],
566
+ sienna: Hansi["a0522d"],
567
+ silver: Hansi["cccccc"],
568
+ skyblue: Hansi["87ceeb"],
569
+ slateblue: Hansi["6a5acd"],
570
+ slategray: Hansi["708090"],
571
+ slategrey: Hansi["708090"],
572
+ snow: Hansi["fffafa"],
573
+ springgreen: Hansi["00ff7f"],
574
+ steel: Hansi["666666"],
575
+ steelblue: Hansi["4682b4"],
576
+ tan: Hansi["d2b48c"],
577
+ teal: Hansi["008080"],
578
+ thistle: Hansi["d8bfd8"],
579
+ tin: Hansi["7f7f7f"],
580
+ tomato: Hansi["ff6347"],
581
+ tungsten: Hansi["333333"],
582
+ turquoise: Hansi["40e0d0"],
583
+ violet: Hansi["ee82ee"],
584
+ violetred: Hansi["d02090"],
585
+ wheat: Hansi["f5deb3"],
586
+ white: Hansi["ffffff"],
587
+ whitesmoke: Hansi["f5f5f5"],
588
+ yellow: Hansi["ffff00"],
589
+ yellowgreen: Hansi["9acd32"]
590
+ }
591
+ end