concise_rucaptcha 2.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +206 -0
- data/README.md +156 -0
- data/app/controllers/concise_ru_captcha/concise_captcha_controller.rb +12 -0
- data/config/locales/concise_rucaptcha.en.yml +3 -0
- data/config/locales/concise_rucaptcha.pt-BR.yml +3 -0
- data/config/locales/concise_rucaptcha.zh-CN.yml +3 -0
- data/config/locales/concise_rucaptcha.zh-TW.yml +3 -0
- data/config/routes.rb +3 -0
- data/ext/concise_rucaptcha/colors.h +345 -0
- data/ext/concise_rucaptcha/concise_rucaptcha.c +215 -0
- data/ext/concise_rucaptcha/extconf.rb +2 -0
- data/ext/concise_rucaptcha/font.h +27 -0
- data/lib/concise_rucaptcha.rb +66 -0
- data/lib/concise_rucaptcha/cache.rb +11 -0
- data/lib/concise_rucaptcha/configuration.rb +11 -0
- data/lib/concise_rucaptcha/controller_helpers.rb +77 -0
- data/lib/concise_rucaptcha/engine.rb +15 -0
- data/lib/concise_rucaptcha/version.rb +3 -0
- data/lib/concise_rucaptcha/view_helpers.rb +19 -0
- metadata +92 -0
checksums.yaml
ADDED
@@ -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
|
data/CHANGELOG.md
ADDED
@@ -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.
|
data/README.md
ADDED
@@ -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
|
data/config/routes.rb
ADDED
@@ -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
|
+
};
|