concise_rucaptcha 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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 331f2c90c6608b9aeea4f2f24d3b903ec10dc776
4
+ data.tar.gz: ecf674e8e7e5fc370c0ce2dbc3fda3031e84f633
5
+ SHA512:
6
+ metadata.gz: 8235abeb7f74dd67ba7d933e985738c7d40e8ba0bb8f547dc01888807380f07bb1c286f93905eb46b77035a6689ce0bac02c19dc7f95c5e9a4272baf5b18507a
7
+ data.tar.gz: 922e52dc9b561a982253bfc3d4246ffab9445ba0986c6c237937600909cf5b28dfaaace42d4f7d6525a9df3a27f305e90dfc7bf012f2244987716507c6cc1793
@@ -0,0 +1,206 @@
1
+ 2.1.3
2
+ -----
3
+
4
+ - Windows support fixed with `send_data` method. (#45)
5
+
6
+ 2.1.2
7
+ -----
8
+
9
+ - Do not change captcha when `HEAD /rucaptcha`.
10
+
11
+ 2.1.1
12
+ -----
13
+
14
+ - Mount engine use `prepend` method to get high priority in config/routes.rb.
15
+
16
+ 2.1.0
17
+ -----
18
+
19
+ - Mount Router by default, not need config now.
20
+
21
+ > IMPORTANT: Wen you upgrade this version, you need remove `mount RuCaptcha::Engine` line from your `config/routes.rb`
22
+ - Default use [:file_store, 'tmp/cache/rucaptcha/session'] as RuCaptcha.config.cache_store, now it can work without any configurations.
23
+
24
+ > NOTE: But you still need care about `config.cache_store` to setup on a right way.
25
+
26
+
27
+
28
+ 2.0.3
29
+ -----
30
+
31
+ - Use `ActiveSupport.on_load` to extend ActionController and ActionView.
32
+
33
+ 2.0.1
34
+ -----
35
+
36
+ - Fix `/rucaptcha` path issue when `config.action_controller.asset_host` has setup with CDN url.
37
+
38
+ 2.0.0
39
+ -----
40
+
41
+ *Break Changes!*
42
+
43
+ WARNING!: This version have so many break changes!
44
+
45
+ - Use C ext instead of ImageMagick, now it's no dependencies!
46
+ - New captcha style.
47
+ - Remove `len`, `font_size`, `cache_limit` config key, no support now.
48
+ - Output `GIF` format.
49
+
50
+ 1.2.0
51
+ -----
52
+
53
+ - Add an `:keep_session` option for `verify_rucaptcha?` method to giva a way for let you keep session on verify, if true, RuCaptcha will not delete the captcha code session after validation.
54
+
55
+ 1.1.4
56
+ -----
57
+
58
+ - Fix #35 just give a warning message if not setup a right cache_store, only raise on :null_store.
59
+
60
+ 1.1.2
61
+ -----
62
+
63
+ - Fix #34 rucaptcha.root_url -> root_path, to avoid generate a http url in a https application.
64
+ - Fix spec to require Ruby 2.0.0, because there have a `Module#prepend` method called.
65
+
66
+ 1.1.1
67
+ -----
68
+
69
+ - Remove inspect log on verify_rucaptcha
70
+
71
+ 1.1.0
72
+ -----
73
+
74
+ - Add `cache_store` config key to setup a cache store location for RuCaptcha.
75
+ - Store captcha in custom cache store.
76
+
77
+ ## Security Notes
78
+
79
+ - Fix Session replay secure issue that when Rails application use CookieStore.
80
+
81
+ 1.0.0
82
+ -----
83
+
84
+ - Adjust to avoid lighter colors.
85
+ - Avoid continuous chars have same color.
86
+ - Use same color for each chars in :black_white mode.
87
+
88
+ 0.5.1
89
+ -----
90
+
91
+ - Make sure it will render image when ImageMagick stderr have warning messages. (#26)
92
+
93
+ 0.5.0
94
+ -----
95
+
96
+ - Fix cache with Rails 5.
97
+
98
+ 0.4.5
99
+ -----
100
+
101
+ - Removed `posix-spawn` dependency, used open3 instead (core funciontality), JRuby compatible (#24)
102
+
103
+ 0.4.4
104
+ -----
105
+
106
+ - Remove deprecated `width`, `height` config.
107
+ - Delete session key after verify (#23).
108
+ - Lighter text color, improve style.
109
+
110
+ 0.4.2
111
+ -----
112
+
113
+ - Fix NoMethodError bug when params[:_rucaptha] is nil.
114
+
115
+ 0.4.1
116
+ -----
117
+
118
+ - Add error message to resource when captcha code expired.
119
+
120
+ 0.4.0
121
+ -----
122
+
123
+ - Add `config.colorize` option, to allow use black text theme.
124
+
125
+ 0.3.3
126
+ -----
127
+
128
+ - Add `config.expires_in` to allow change captcha code expire time.
129
+
130
+ 0.3.2.1
131
+ -------
132
+
133
+ - Add Windows development env support.
134
+
135
+ 0.3.2
136
+ -----
137
+
138
+ - Make better render positions;
139
+ - Trim blank space.
140
+
141
+ 0.3.1
142
+ -----
143
+
144
+ - More complex Image render: compact text, strong lines, +/-5 rotate...
145
+ - [DEPRECATION] config.width, config.height removed, use config.font_size.
146
+ - Fix the render position in difference font sizes.
147
+ - Fix input field type, and disable autocorrect, autocapitalize, and limit maxlength with char length;
148
+
149
+ 0.2.5
150
+ -----
151
+
152
+ - Add `session[:_rucaptcha]` expire time, for protect Rails CookieSession Replay Attack.
153
+ - Captcha input field disable autocomplete, and set field type as `email` for shown correct keyboard on mobile view.
154
+
155
+ 0.2.3
156
+ -----
157
+
158
+ - It will raise error when call ImageMagick failed.
159
+
160
+ 0.2.2
161
+ -----
162
+
163
+ - Added locale for pt-BR language; @ramirovjr
164
+
165
+ 0.2.1
166
+ -----
167
+
168
+ - Fix issue when cache dir not exist.
169
+
170
+ 0.2.0
171
+ -----
172
+
173
+ - Added file cache, can setup how many images you want generate by `config.cache_limit`,
174
+ RuCaptcha will use cache for next requests.
175
+ When you restart Rails processes it will generate new again and clean the old caches.
176
+
177
+ 0.1.4
178
+ -----
179
+
180
+ - Fix `verify_rucaptcha?` logic in somecase.
181
+ - Locales fixed.
182
+
183
+ 0.1.3
184
+ -----
185
+
186
+ - `zh-TW` translate file fixed.
187
+ - Use xxx_url to fix bad captcha URL for `config.action_controller.asset_host` enabled case.
188
+
189
+ 0.1.2
190
+ -----
191
+
192
+ - No case sensitive;
193
+ - Export config.implode;
194
+ - Improve image color and style;
195
+ - Don't generate chars in 'l,o,0,1'.
196
+ - Render lower case chars on image.
197
+
198
+ 0.1.1
199
+ -----
200
+
201
+ - Include default validation I18n messages (en, zh-CN, zh-TW).
202
+
203
+ 0.1.0
204
+ -----
205
+
206
+ - First release.
@@ -0,0 +1,156 @@
1
+ # RuCaptcha
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/rucaptcha.svg)](https://badge.fury.io/rb/rucaptcha)
4
+ [![Build Status](https://travis-ci.org/huacnlee/rucaptcha.svg)](https://travis-ci.org/huacnlee/rucaptcha)
5
+ [![Code Climate](https://codeclimate.com/github/huacnlee/rucaptcha/badges/gpa.svg)](https://codeclimate.com/github/huacnlee/rucaptcha)
6
+
7
+ This is a Captcha gem for Rails Applications which generates captcha image by C code.
8
+
9
+ ## Example
10
+
11
+ <img src="https://cloud.githubusercontent.com/assets/5518/22151425/e02390c8-df58-11e6-974d-5eb9b1a4e577.gif" width="150px" /> <img src="https://cloud.githubusercontent.com/assets/5518/22151427/e4939d92-df58-11e6-9754-4a46a86acea8.gif" width="150px" /> <img src="https://cloud.githubusercontent.com/assets/5518/22151431/e494576e-df58-11e6-9845-a5590904c175.gif" width="150px" /> <img src="https://cloud.githubusercontent.com/assets/5518/22151432/e495066e-df58-11e6-92b8-38b40b73aba0.gif" width="150px" /> <img src="https://cloud.githubusercontent.com/assets/5518/22151428/e49404ee-df58-11e6-8e2d-8b17b33a3710.gif" width="150px" /> <img src="https://cloud.githubusercontent.com/assets/5518/22151430/e4942406-df58-11e6-9ff8-6e2325304b41.gif" width="150px" /> <img src="https://cloud.githubusercontent.com/assets/5518/22151429/e4941ae2-df58-11e6-8107-757296573b2f.gif" width="150px" /> <img src="https://cloud.githubusercontent.com/assets/5518/22151433/e4c7c89c-df58-11e6-9853-1ffbb4986962.gif" width="150px" /> <img src="https://cloud.githubusercontent.com/assets/5518/22151435/e4c97ea8-df58-11e6-8959-b4c78716271d.gif" width="150px" /> <img src="https://cloud.githubusercontent.com/assets/5518/22151436/e4cc09f2-df58-11e6-965c-673333b33c0d.gif" width="150px" /> <img src="https://cloud.githubusercontent.com/assets/5518/22151434/e4c87788-df58-11e6-9490-c255aaafce71.gif" width="150px" /> <img src="https://cloud.githubusercontent.com/assets/5518/22151445/ee35ff66-df58-11e6-8660-a3673ef3f5ee.gif" width="150px" /> <img src="https://cloud.githubusercontent.com/assets/5518/22151446/ee67b074-df58-11e6-9b95-7d53eec21c33.gif" width="150px" />
12
+
13
+ [中文介绍和使用说明](https://ruby-china.org/topics/27832)
14
+
15
+ ## Feature
16
+
17
+ - No dependencies. No ImageMagick. No RMagick;
18
+ - For Rails Application;
19
+ - Simple, Easy to use;
20
+ - High performance.
21
+
22
+ ## Usage
23
+
24
+ Put rucaptcha in your `Gemfile`:
25
+
26
+ ```
27
+ gem 'rucaptcha'
28
+ ```
29
+
30
+ Create `config/initializers/rucaptcha.rb`
31
+
32
+ ```rb
33
+ RuCaptcha.configure do
34
+ # Color style, default: :colorful, allows: [:colorful, :black_white]
35
+  # self.style = :colorful
36
+ # Custom captcha code expire time if you need, default: 2 minutes
37
+ # self.expires_in = 120
38
+  # [Requirement / 重要]
39
+ # Store Captcha code where, this config more like Rails config.cache_store
40
+ # default: Read config info from `Rails.application.config.cache_store`
41
+ # But RuCaptcha requirements cache_store not in [:null_store, :memory_store, :file_store]
42
+  # 默认:会从 Rails 配置的 cache_store 里面读取相同的配置信息,并尝试用可以运行的方式,用于存储验证码字符
43
+  # 但如果是 [:null_store, :memory_store, :file_store] 之类的,你可以通过下面的配置项单独给 RuCaptcha 配置 cache_store
44
+  self.cache_store = :mem_cache_store
45
+ end
46
+ ```
47
+
48
+ RuCaptcha 没有使用 Rails Session 来存储验证码信息,因为 Rails 的默认 Session 是存储在 Cookie 里面,如果验证码存在里面会存在 [Replay attack](https://en.wikipedia.org/wiki/Replay_attack) 漏洞,导致验证码关卡被攻破。
49
+
50
+ 所以我在设计上要求 RuCaptcha 得配置一个可以支持分布式的后端存储方案例如:Memcached 或 Redis 以及其他可以支持分布式的 cache_store 方案。
51
+
52
+ 同时,为了保障易用性,默认会尝试使用 `:file_store` 的方式,将验证码存在应用程序的 `tmp/cache/rucaptcha/session` 目录(但请注意,多机器部署这样是无法正常运作的)。
53
+
54
+ 所以,我建议大家使用的时候,配置上 `cache_store` (详见 [Rails Guides 缓存配置部分](https://ruby-china.github.io/rails-guides/caching_with_rails.html#%E9%85%8D%E7%BD%AE)的文档)到一个 Memcached 或 Redis,这才是最佳实践。
55
+
56
+ #
57
+ (RuCaptha do not use Rails Session to store captcha information. As the default session is stored in Cookie in Rails, there's a [Replay attack](https://en.wikipedia.org/wiki/Replay_attack) bug which may causes capthcha being destroyed if we store captcha in Rails Session.
58
+
59
+ So in my design I require RuCaptcha to configure a distributed backend storage scheme, such as Memcached, Redis or other cache_store schemes which support distribution.
60
+
61
+ Meanwhile, for the ease of use, RuCapthca would try to use `:file_store` by default and store the capthca in `tmp/cache/rucaptcha/session` directory (kindly note that it's not working if deploy on multiple machine).
62
+
63
+ For recommendation, configure the `cache_store`(more details on [Rails Guides Configuration of Cache Stores](http://guides.rubyonrails.org/caching_with_rails.html#configuration)) to Memcached or Redis, that would be the best practice.)
64
+ #
65
+
66
+ Controller `app/controller/account_controller.rb`
67
+
68
+ When you called `verify_rucaptcha?`, it uses value from `params[:_rucaptcha]` to validate.
69
+
70
+ ```rb
71
+ class AccountController < ApplicationController
72
+ def create
73
+ @user = User.new(params[:user])
74
+ if verify_rucaptcha?(@user) && @user.save
75
+ redirect_to root_path, notice: 'Sign up successed.'
76
+ else
77
+ render 'account/new'
78
+ end
79
+ end
80
+ end
81
+
82
+ class ForgotPasswordController < ApplicationController
83
+ def create
84
+ # without any args
85
+ if verify_rucaptcha?
86
+ to_send_email
87
+ else
88
+ redirect_to '/forgot-password', alert: 'Invalid captcha code.'
89
+ end
90
+ end
91
+ end
92
+ ```
93
+
94
+ > TIP: Sometimes you may need to keep last verified captcha code in session on `verify_rucaptcha?` method call, you can use `keep_session: true`. For example: `verify_rucaptcha? @user, keep_session: true`.
95
+
96
+ View `app/views/account/new.html.erb`
97
+
98
+ ```erb
99
+ <form method="POST">
100
+ ...
101
+ <div class="form-group">
102
+ <%= rucaptcha_input_tag(class: 'form-control', placeholder: 'Input Captcha') %>
103
+ <%= rucaptcha_image_tag(alt: 'Captcha') %>
104
+ </div>
105
+ ...
106
+
107
+ <div class="form-group">
108
+ <button type="submit" class="btn btn-primary">Submit</button>
109
+ </div>
110
+ </form>
111
+ ```
112
+
113
+ And if you are using [Devise](https://github.com/plataformatec/devise), you can read this reference to add validation: [RuCaptcha with Devise](https://github.com/huacnlee/rucaptcha/wiki/Working-with-Devise).
114
+
115
+ ### Write your test skip captcha validation
116
+
117
+ for RSpec
118
+
119
+ ```rb
120
+ describe 'sign up and login', type: :feature do
121
+ before do
122
+ allow_any_instance_of(ActionController::Base).to receive(:verify_rucaptcha?).and_return(true)
123
+ end
124
+
125
+ it { ... }
126
+ end
127
+ ```
128
+
129
+ for MiniTest
130
+
131
+ ```rb
132
+ class ActionDispatch::IntegrationTest
133
+ def sign_in(user)
134
+ ActionController::Base.any_instance.stubs(:verify_rucaptcha?).returns(true)
135
+ post user_session_path \
136
+ 'user[email]' => user.email,
137
+ 'user[password]' => user.password
138
+ end
139
+ end
140
+ ```
141
+
142
+ ### Invalid message without Devise
143
+
144
+ When you are using this gem without Devise, you may find out that the invalid message is missing.
145
+ For this case, use the trick below to add your i18n invalid message manually.
146
+
147
+ ```rb
148
+ if verify_rucaptcha?(@user) && @user.save
149
+ do_whatever_you_want
150
+ redirect_to someplace_you_want
151
+ else
152
+ # this is the trick
153
+ @user.errors.add(:base, t('rucaptcha.invalid'))
154
+ render :new
155
+ end
156
+ ```
@@ -0,0 +1,12 @@
1
+ module ConciseRuCaptcha
2
+ class ConciseCaptchaController < ActionController::Base
3
+ def index
4
+ return head :ok if request.head?
5
+ headers['Cache-Control'] = 'no-cache, no-store, max-age=0, must-revalidate'
6
+ headers['Pragma'] = 'no-cache'
7
+ data = generate_rucaptcha
8
+ opts = { disposition: 'inline', type: 'image/gif' }
9
+ send_data data, opts
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,3 @@
1
+ en:
2
+ concise_rucaptcha:
3
+ invalid: "Captcha invalid!"
@@ -0,0 +1,3 @@
1
+ 'pt-BR':
2
+ concise_rucaptcha:
3
+ invalid: "Código inválido!"
@@ -0,0 +1,3 @@
1
+ 'zh-CN':
2
+ concise_rucaptcha:
3
+ invalid: "验证码不正确"
@@ -0,0 +1,3 @@
1
+ 'zh-TW':
2
+ concise_rucaptcha:
3
+ invalid: "驗證碼不正確"
@@ -0,0 +1,3 @@
1
+ ConciseRuCaptcha::Engine.routes.draw do
2
+ root to: 'concise_captcha#index'
3
+ end
@@ -0,0 +1,345 @@
1
+ // Colors from
2
+ // https://material.io/guidelines/style/color.html#color-ui-color-palette
3
+ static char *colors[] = {
4
+ // Black 500 #000000
5
+ "GIF89a" "\xc8\0\x46\0" "\x83" "\0\0"
6
+ "\x11\x11\x11"
7
+ "\x11\x11\x11"
8
+ "\x11\x11\x11"
9
+ "\x11\x11\x11"
10
+ "\x11\x11\x11"
11
+ "\x11\x11\x11"
12
+ "\x11\x11\x11"
13
+ "\x11\x11\x11"
14
+ "\x11\x11\x11"
15
+ "\x11\x11\x11"
16
+ "\x11\x11\x11"
17
+ "\x11\x11\x11"
18
+ "\x11\x11\x11"
19
+ "\x11\x11\x11"
20
+ "\x11\x11\x11"
21
+ "\xff\xff\xff" "," "\0\0\0\0" "\xc8\0\x46\0" "\0" "\x04",
22
+
23
+ // Red 500 #F44336
24
+ "GIF89a" "\xc8\0\x46\0" "\x83" "\0\0"
25
+ "\xF4\x43\x36"
26
+ "\xF4\x43\x36"
27
+ "\xF4\x43\x36"
28
+ "\xF4\x43\x36"
29
+ "\xF4\x43\x36"
30
+ "\xF4\x43\x36"
31
+ "\xF4\x43\x36"
32
+ "\xF4\x43\x36"
33
+ "\xF4\x43\x36"
34
+ "\xF4\x43\x36"
35
+ "\xF4\x43\x36"
36
+ "\xF4\x43\x36"
37
+ "\xF4\x43\x36"
38
+ "\xF4\x43\x36"
39
+ "\xF4\x43\x36"
40
+ "\xff\xff\xff" "," "\0\0\0\0" "\xc8\0\x46\0" "\0" "\x04",
41
+
42
+ // Pink 500 #E91E63
43
+ "GIF89a" "\xc8\0\x46\0" "\x83" "\0\0"
44
+ "\xE9\x1E\x63"
45
+ "\xE9\x1E\x63"
46
+ "\xE9\x1E\x63"
47
+ "\xE9\x1E\x63"
48
+ "\xE9\x1E\x63"
49
+ "\xE9\x1E\x63"
50
+ "\xE9\x1E\x63"
51
+ "\xE9\x1E\x63"
52
+ "\xE9\x1E\x63"
53
+ "\xE9\x1E\x63"
54
+ "\xE9\x1E\x63"
55
+ "\xE9\x1E\x63"
56
+ "\xE9\x1E\x63"
57
+ "\xE9\x1E\x63"
58
+ "\xE9\x1E\x63"
59
+ "\xff\xff\xff" "," "\0\0\0\0" "\xc8\0\x46\0" "\0" "\x04",
60
+
61
+ // Purple 500 #9C27B0
62
+ "GIF89a" "\xc8\0\x46\0" "\x83" "\0\0"
63
+ "\x9C\x27\xB0"
64
+ "\x9C\x27\xB0"
65
+ "\x9C\x27\xB0"
66
+ "\x9C\x27\xB0"
67
+ "\x9C\x27\xB0"
68
+ "\x9C\x27\xB0"
69
+ "\x9C\x27\xB0"
70
+ "\x9C\x27\xB0"
71
+ "\x9C\x27\xB0"
72
+ "\x9C\x27\xB0"
73
+ "\x9C\x27\xB0"
74
+ "\x9C\x27\xB0"
75
+ "\x9C\x27\xB0"
76
+ "\x9C\x27\xB0"
77
+ "\x9C\x27\xB0"
78
+ "\xff\xff\xff" "," "\0\0\0\0" "\xc8\0\x46\0" "\0" "\x04",
79
+
80
+ // Deep Purple 500 #673AB7
81
+ "GIF89a" "\xc8\0\x46\0" "\x83" "\0\0"
82
+ "\x67\x3A\xB7"
83
+ "\x67\x3A\xB7"
84
+ "\x67\x3A\xB7"
85
+ "\x67\x3A\xB7"
86
+ "\x67\x3A\xB7"
87
+ "\x67\x3A\xB7"
88
+ "\x67\x3A\xB7"
89
+ "\x67\x3A\xB7"
90
+ "\x67\x3A\xB7"
91
+ "\x67\x3A\xB7"
92
+ "\x67\x3A\xB7"
93
+ "\x67\x3A\xB7"
94
+ "\x67\x3A\xB7"
95
+ "\x67\x3A\xB7"
96
+ "\x67\x3A\xB7"
97
+ "\xff\xff\xff" "," "\0\0\0\0" "\xc8\0\x46\0" "\0" "\x04",
98
+
99
+ // Indigo 500 #3F51B5
100
+ "GIF89a" "\xc8\0\x46\0" "\x83" "\0\0"
101
+ "\x3F\x51\xB5"
102
+ "\x3F\x51\xB5"
103
+ "\x3F\x51\xB5"
104
+ "\x3F\x51\xB5"
105
+ "\x3F\x51\xB5"
106
+ "\x3F\x51\xB5"
107
+ "\x3F\x51\xB5"
108
+ "\x3F\x51\xB5"
109
+ "\x3F\x51\xB5"
110
+ "\x3F\x51\xB5"
111
+ "\x3F\x51\xB5"
112
+ "\x3F\x51\xB5"
113
+ "\x3F\x51\xB5"
114
+ "\x3F\x51\xB5"
115
+ "\x3F\x51\xB5"
116
+ "\xff\xff\xff" "," "\0\0\0\0" "\xc8\0\x46\0" "\0" "\x04",
117
+
118
+ // Blue 500 #2196F3
119
+ "GIF89a" "\xc8\0\x46\0" "\x83" "\0\0"
120
+ "\x21\x96\xF3"
121
+ "\x21\x96\xF3"
122
+ "\x21\x96\xF3"
123
+ "\x21\x96\xF3"
124
+ "\x21\x96\xF3"
125
+ "\x21\x96\xF3"
126
+ "\x21\x96\xF3"
127
+ "\x21\x96\xF3"
128
+ "\x21\x96\xF3"
129
+ "\x21\x96\xF3"
130
+ "\x21\x96\xF3"
131
+ "\x21\x96\xF3"
132
+ "\x21\x96\xF3"
133
+ "\x21\x96\xF3"
134
+ "\x21\x96\xF3"
135
+ "\xff\xff\xff" "," "\0\0\0\0" "\xc8\0\x46\0" "\0" "\x04",
136
+
137
+ // Light Blue 500 #03A9F4
138
+ "GIF89a" "\xc8\0\x46\0" "\x83" "\0\0"
139
+ "\x03\xA9\xF4"
140
+ "\x03\xA9\xF4"
141
+ "\x03\xA9\xF4"
142
+ "\x03\xA9\xF4"
143
+ "\x03\xA9\xF4"
144
+ "\x03\xA9\xF4"
145
+ "\x03\xA9\xF4"
146
+ "\x03\xA9\xF4"
147
+ "\x03\xA9\xF4"
148
+ "\x03\xA9\xF4"
149
+ "\x03\xA9\xF4"
150
+ "\x03\xA9\xF4"
151
+ "\x03\xA9\xF4"
152
+ "\x03\xA9\xF4"
153
+ "\x03\xA9\xF4"
154
+ "\xff\xff\xff" "," "\0\0\0\0" "\xc8\0\x46\0" "\0" "\x04",
155
+
156
+ // Cyan 500 #00BCD4
157
+ "GIF89a" "\xc8\0\x46\0" "\x83" "\0\0"
158
+ "\x00\xBC\xD4"
159
+ "\x00\xBC\xD4"
160
+ "\x00\xBC\xD4"
161
+ "\x00\xBC\xD4"
162
+ "\x00\xBC\xD4"
163
+ "\x00\xBC\xD4"
164
+ "\x00\xBC\xD4"
165
+ "\x00\xBC\xD4"
166
+ "\x00\xBC\xD4"
167
+ "\x00\xBC\xD4"
168
+ "\x00\xBC\xD4"
169
+ "\x00\xBC\xD4"
170
+ "\x00\xBC\xD4"
171
+ "\x00\xBC\xD4"
172
+ "\x00\xBC\xD4"
173
+ "\xff\xff\xff" "," "\0\0\0\0" "\xc8\0\x46\0" "\0" "\x04",
174
+
175
+ // Teal 500 #009688
176
+ "GIF89a" "\xc8\0\x46\0" "\x83" "\0\0"
177
+ "\x00\x96\x88"
178
+ "\x00\x96\x88"
179
+ "\x00\x96\x88"
180
+ "\x00\x96\x88"
181
+ "\x00\x96\x88"
182
+ "\x00\x96\x88"
183
+ "\x00\x96\x88"
184
+ "\x00\x96\x88"
185
+ "\x00\x96\x88"
186
+ "\x00\x96\x88"
187
+ "\x00\x96\x88"
188
+ "\x00\x96\x88"
189
+ "\x00\x96\x88"
190
+ "\x00\x96\x88"
191
+ "\x00\x96\x88"
192
+ "\xff\xff\xff" "," "\0\0\0\0" "\xc8\0\x46\0" "\0" "\x04",
193
+
194
+ // Green 500 #4CAF50
195
+ "GIF89a" "\xc8\0\x46\0" "\x83" "\0\0"
196
+ "\x4C\xAF\x50"
197
+ "\x4C\xAF\x50"
198
+ "\x4C\xAF\x50"
199
+ "\x4C\xAF\x50"
200
+ "\x4C\xAF\x50"
201
+ "\x4C\xAF\x50"
202
+ "\x4C\xAF\x50"
203
+ "\x4C\xAF\x50"
204
+ "\x4C\xAF\x50"
205
+ "\x4C\xAF\x50"
206
+ "\x4C\xAF\x50"
207
+ "\x4C\xAF\x50"
208
+ "\x4C\xAF\x50"
209
+ "\x4C\xAF\x50"
210
+ "\x4C\xAF\x50"
211
+ "\xff\xff\xff" "," "\0\0\0\0" "\xc8\0\x46\0" "\0" "\x04",
212
+
213
+ // Light Green 500 #8BC34A
214
+ "GIF89a" "\xc8\0\x46\0" "\x83" "\0\0"
215
+ "\x8B\xC3\x4A"
216
+ "\x8B\xC3\x4A"
217
+ "\x8B\xC3\x4A"
218
+ "\x8B\xC3\x4A"
219
+ "\x8B\xC3\x4A"
220
+ "\x8B\xC3\x4A"
221
+ "\x8B\xC3\x4A"
222
+ "\x8B\xC3\x4A"
223
+ "\x8B\xC3\x4A"
224
+ "\x8B\xC3\x4A"
225
+ "\x8B\xC3\x4A"
226
+ "\x8B\xC3\x4A"
227
+ "\x8B\xC3\x4A"
228
+ "\x8B\xC3\x4A"
229
+ "\x8B\xC3\x4A"
230
+ "\xff\xff\xff" "," "\0\0\0\0" "\xc8\0\x46\0" "\0" "\x04",
231
+
232
+ // Lime 500 #CDDC39
233
+ "GIF89a" "\xc8\0\x46\0" "\x83" "\0\0"
234
+ "\xCD\xDC\x39"
235
+ "\xCD\xDC\x39"
236
+ "\xCD\xDC\x39"
237
+ "\xCD\xDC\x39"
238
+ "\xCD\xDC\x39"
239
+ "\xCD\xDC\x39"
240
+ "\xCD\xDC\x39"
241
+ "\xCD\xDC\x39"
242
+ "\xCD\xDC\x39"
243
+ "\xCD\xDC\x39"
244
+ "\xCD\xDC\x39"
245
+ "\xCD\xDC\x39"
246
+ "\xCD\xDC\x39"
247
+ "\xCD\xDC\x39"
248
+ "\xCD\xDC\x39"
249
+ "\xff\xff\xff" "," "\0\0\0\0" "\xc8\0\x46\0" "\0" "\x04",
250
+
251
+ // Yellow 500 #FFEB3B
252
+ "GIF89a" "\xc8\0\x46\0" "\x83" "\0\0"
253
+ "\xFF\xEB\x3B"
254
+ "\xFF\xEB\x3B"
255
+ "\xFF\xEB\x3B"
256
+ "\xFF\xEB\x3B"
257
+ "\xFF\xEB\x3B"
258
+ "\xFF\xEB\x3B"
259
+ "\xFF\xEB\x3B"
260
+ "\xFF\xEB\x3B"
261
+ "\xFF\xEB\x3B"
262
+ "\xFF\xEB\x3B"
263
+ "\xFF\xEB\x3B"
264
+ "\xFF\xEB\x3B"
265
+ "\xFF\xEB\x3B"
266
+ "\xFF\xEB\x3B"
267
+ "\xFF\xEB\x3B"
268
+ "\xff\xff\xff" "," "\0\0\0\0" "\xc8\0\x46\0" "\0" "\x04",
269
+
270
+ // Amber 500 #FFC107
271
+ "GIF89a" "\xc8\0\x46\0" "\x83" "\0\0"
272
+ "\xFF\xC1\x07"
273
+ "\xFF\xC1\x07"
274
+ "\xFF\xC1\x07"
275
+ "\xFF\xC1\x07"
276
+ "\xFF\xC1\x07"
277
+ "\xFF\xC1\x07"
278
+ "\xFF\xC1\x07"
279
+ "\xFF\xC1\x07"
280
+ "\xFF\xC1\x07"
281
+ "\xFF\xC1\x07"
282
+ "\xFF\xC1\x07"
283
+ "\xFF\xC1\x07"
284
+ "\xFF\xC1\x07"
285
+ "\xFF\xC1\x07"
286
+ "\xFF\xC1\x07"
287
+ "\xff\xff\xff" "," "\0\0\0\0" "\xc8\0\x46\0" "\0" "\x04",
288
+
289
+ // Orange 500 #FF9800
290
+ "GIF89a" "\xc8\0\x46\0" "\x83" "\0\0"
291
+ "\xFF\x98\x00"
292
+ "\xFF\x98\x00"
293
+ "\xFF\x98\x00"
294
+ "\xFF\x98\x00"
295
+ "\xFF\x98\x00"
296
+ "\xFF\x98\x00"
297
+ "\xFF\x98\x00"
298
+ "\xFF\x98\x00"
299
+ "\xFF\x98\x00"
300
+ "\xFF\x98\x00"
301
+ "\xFF\x98\x00"
302
+ "\xFF\x98\x00"
303
+ "\xFF\x98\x00"
304
+ "\xFF\x98\x00"
305
+ "\xFF\x98\x00"
306
+ "\xff\xff\xff" "," "\0\0\0\0" "\xc8\0\x46\0" "\0" "\x04",
307
+
308
+ // Deep Orange 500 #FF5722
309
+ "GIF89a" "\xc8\0\x46\0" "\x83" "\0\0"
310
+ "\xFF\x57\x22"
311
+ "\xFF\x57\x22"
312
+ "\xFF\x57\x22"
313
+ "\xFF\x57\x22"
314
+ "\xFF\x57\x22"
315
+ "\xFF\x57\x22"
316
+ "\xFF\x57\x22"
317
+ "\xFF\x57\x22"
318
+ "\xFF\x57\x22"
319
+ "\xFF\x57\x22"
320
+ "\xFF\x57\x22"
321
+ "\xFF\x57\x22"
322
+ "\xFF\x57\x22"
323
+ "\xFF\x57\x22"
324
+ "\xFF\x57\x22"
325
+ "\xff\xff\xff" "," "\0\0\0\0" "\xc8\0\x46\0" "\0" "\x04",
326
+
327
+ // Brown 500 #795548
328
+ "GIF89a" "\xc8\0\x46\0" "\x83" "\0\0"
329
+ "\x79\x55\x48"
330
+ "\x79\x55\x48"
331
+ "\x79\x55\x48"
332
+ "\x79\x55\x48"
333
+ "\x79\x55\x48"
334
+ "\x79\x55\x48"
335
+ "\x79\x55\x48"
336
+ "\x79\x55\x48"
337
+ "\x79\x55\x48"
338
+ "\x79\x55\x48"
339
+ "\x79\x55\x48"
340
+ "\x79\x55\x48"
341
+ "\x79\x55\x48"
342
+ "\x79\x55\x48"
343
+ "\x79\x55\x48"
344
+ "\xff\xff\xff" "," "\0\0\0\0" "\xc8\0\x46\0" "\0" "\x04"
345
+ };