blogs_captcha 0.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: a98ec2683e337c42986878b06c53998653e8f710c3f30bb419ce73bda44028a7
4
+ data.tar.gz: 8985a2a6bae218ec905c24fa6f4491fc0ee4363b41055fc78be0bd9505408311
5
+ SHA512:
6
+ metadata.gz: e476e5552dc73c8bcb21368f7a711dc258d4a808e249fd20f5552c9f5e12c6954bf9d3a1e28a9fa8c553ba146875945c8e8aa889987b26971c945462e5368071
7
+ data.tar.gz: c4ecc445a10458bdce54f1d1cd959d6cccc910ff498e4924fcb3271a0427b71b28a48083f1322ea25fe91c556c9084ed771036ab82d8191bd85c9f7248eba198
data/CHANGELOG.md ADDED
@@ -0,0 +1,234 @@
1
+ 2.4.0
2
+ -------
3
+
4
+ - Add skip_cache_store_check configuration. (#63)
5
+ - Fix for generate captcha with relative path, not url. (#58)
6
+
7
+ 2.3.2
8
+ -------
9
+
10
+ - Change Yellow and Green colors to Pink and Deep Purple to pass WCAG 2.0's contrast test. (#70)
11
+
12
+ 2.3.1
13
+ -------
14
+
15
+ - Fix #67 a y chars will invalid error (only in 2.3.0).
16
+
17
+ 2.3.0
18
+ -------
19
+
20
+ - Add `config.outline` for use outline style.
21
+ - Reduce colors down to 5 (red, blue, green, yellow and black).
22
+
23
+ 2.2.0
24
+ -----
25
+
26
+ - Add option `config.length` for support change number chars. (#57)
27
+ - Add option `config.strikethrough` for enable or disable strikethrough. (#57)
28
+
29
+ 2.1.3
30
+ -----
31
+
32
+ - Windows support fixed with `send_data` method. (#45)
33
+
34
+ 2.1.2
35
+ -----
36
+
37
+ - Do not change captcha when `HEAD /rucaptcha`.
38
+
39
+ 2.1.1
40
+ -----
41
+
42
+ - Mount engine use `prepend` method to get high priority in config/routes.rb.
43
+
44
+ 2.1.0
45
+ -----
46
+
47
+ - Mount Router by default, not need config now.
48
+
49
+ > IMPORTANT: Wen you upgrade this version, you need remove `mount RuCaptcha::Engine` line from your `config/routes.rb`
50
+ - Default use [:file_store, 'tmp/cache/rucaptcha/session'] as RuCaptcha.config.cache_store, now it can work without any configurations.
51
+
52
+ > NOTE: But you still need care about `config.cache_store` to setup on a right way.
53
+
54
+
55
+
56
+ 2.0.3
57
+ -----
58
+
59
+ - Use `ActiveSupport.on_load` to extend ActionController and ActionView.
60
+
61
+ 2.0.1
62
+ -----
63
+
64
+ - Fix `/rucaptcha` path issue when `config.action_controller.asset_host` has setup with CDN url.
65
+
66
+ 2.0.0
67
+ -----
68
+
69
+ *Break Changes!*
70
+
71
+ WARNING!: This version have so many break changes!
72
+
73
+ - Use C ext instead of ImageMagick, now it's no dependencies!
74
+ - New captcha style.
75
+ - Remove `len`, `font_size`, `cache_limit` config key, no support now.
76
+ - Output `GIF` format.
77
+
78
+ 1.2.0
79
+ -----
80
+
81
+ - 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.
82
+
83
+ 1.1.4
84
+ -----
85
+
86
+ - Fix #35 just give a warning message if not setup a right cache_store, only raise on :null_store.
87
+
88
+ 1.1.2
89
+ -----
90
+
91
+ - Fix #34 rucaptcha.root_url -> root_path, to avoid generate a http url in a https application.
92
+ - Fix spec to require Ruby 2.0.0, because there have a `Module#prepend` method called.
93
+
94
+ 1.1.1
95
+ -----
96
+
97
+ - Remove inspect log on verify_rucaptcha
98
+
99
+ 1.1.0
100
+ -----
101
+
102
+ - Add `cache_store` config key to setup a cache store location for RuCaptcha.
103
+ - Store captcha in custom cache store.
104
+
105
+ ## Security Notes
106
+
107
+ - Fix Session replay secure issue that when Rails application use CookieStore.
108
+
109
+ 1.0.0
110
+ -----
111
+
112
+ - Adjust to avoid lighter colors.
113
+ - Avoid continuous chars have same color.
114
+ - Use same color for each chars in :black_white mode.
115
+
116
+ 0.5.1
117
+ -----
118
+
119
+ - Make sure it will render image when ImageMagick stderr have warning messages. (#26)
120
+
121
+ 0.5.0
122
+ -----
123
+
124
+ - Fix cache with Rails 5.
125
+
126
+ 0.4.5
127
+ -----
128
+
129
+ - Removed `posix-spawn` dependency, used open3 instead (core funciontality), JRuby compatible (#24)
130
+
131
+ 0.4.4
132
+ -----
133
+
134
+ - Remove deprecated `width`, `height` config.
135
+ - Delete session key after verify (#23).
136
+ - Lighter text color, improve style.
137
+
138
+ 0.4.2
139
+ -----
140
+
141
+ - Fix NoMethodError bug when params[:_rucaptha] is nil.
142
+
143
+ 0.4.1
144
+ -----
145
+
146
+ - Add error message to resource when captcha code expired.
147
+
148
+ 0.4.0
149
+ -----
150
+
151
+ - Add `config.colorize` option, to allow use black text theme.
152
+
153
+ 0.3.3
154
+ -----
155
+
156
+ - Add `config.expires_in` to allow change captcha code expire time.
157
+
158
+ 0.3.2.1
159
+ -------
160
+
161
+ - Add Windows development env support.
162
+
163
+ 0.3.2
164
+ -----
165
+
166
+ - Make better render positions;
167
+ - Trim blank space.
168
+
169
+ 0.3.1
170
+ -----
171
+
172
+ - More complex Image render: compact text, strong lines, +/-5 rotate...
173
+ - [DEPRECATION] config.width, config.height removed, use config.font_size.
174
+ - Fix the render position in difference font sizes.
175
+ - Fix input field type, and disable autocorrect, autocapitalize, and limit maxlength with char length;
176
+
177
+ 0.2.5
178
+ -----
179
+
180
+ - Add `session[:_rucaptcha]` expire time, for protect Rails CookieSession Replay Attack.
181
+ - Captcha input field disable autocomplete, and set field type as `email` for shown correct keyboard on mobile view.
182
+
183
+ 0.2.3
184
+ -----
185
+
186
+ - It will raise error when call ImageMagick failed.
187
+
188
+ 0.2.2
189
+ -----
190
+
191
+ - Added locale for pt-BR language; @ramirovjr
192
+
193
+ 0.2.1
194
+ -----
195
+
196
+ - Fix issue when cache dir not exist.
197
+
198
+ 0.2.0
199
+ -----
200
+
201
+ - Added file cache, can setup how many images you want generate by `config.cache_limit`,
202
+ RuCaptcha will use cache for next requests.
203
+ When you restart Rails processes it will generate new again and clean the old caches.
204
+
205
+ 0.1.4
206
+ -----
207
+
208
+ - Fix `verify_rucaptcha?` logic in somecase.
209
+ - Locales fixed.
210
+
211
+ 0.1.3
212
+ -----
213
+
214
+ - `zh-TW` translate file fixed.
215
+ - Use xxx_url to fix bad captcha URL for `config.action_controller.asset_host` enabled case.
216
+
217
+ 0.1.2
218
+ -----
219
+
220
+ - No case sensitive;
221
+ - Export config.implode;
222
+ - Improve image color and style;
223
+ - Don't generate chars in 'l,o,0,1'.
224
+ - Render lower case chars on image.
225
+
226
+ 0.1.1
227
+ -----
228
+
229
+ - Include default validation I18n messages (en, zh-CN, zh-TW).
230
+
231
+ 0.1.0
232
+ -----
233
+
234
+ - First release.
data/README.md ADDED
@@ -0,0 +1,164 @@
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
+
6
+ This is a Captcha gem for Rails Applications which generates captcha image by C code.
7
+
8
+ [中文介绍和使用说明](https://ruby-china.org/topics/27832)
9
+
10
+ ## Example
11
+
12
+ <img src="https://user-images.githubusercontent.com/5518/49985459-f8492f80-ffa6-11e8-9ef5-8f8f522e4707.png" width="579px" />
13
+
14
+ ## Feature
15
+
16
+ - No dependencies. No ImageMagick. No RMagick;
17
+ - For Rails Application;
18
+ - Simple, Easy to use;
19
+ - High performance.
20
+
21
+ ## Usage
22
+
23
+ Put rucaptcha in your `Gemfile`:
24
+
25
+ ```
26
+ gem 'rucaptcha'
27
+ ```
28
+
29
+ Create `config/initializers/rucaptcha.rb`
30
+
31
+ ```rb
32
+ RuCaptcha.configure do
33
+ # Color style, default: :colorful, allows: [:colorful, :black_white]
34
+  # self.style = :colorful
35
+ # Custom captcha code expire time if you need, default: 2 minutes
36
+ # self.expires_in = 120
37
+  # [Requirement / 重要]
38
+ # Store Captcha code where, this config more like Rails config.cache_store
39
+ # default: Read config info from `Rails.application.config.cache_store`
40
+ # But RuCaptcha requirements cache_store not in [:null_store, :memory_store, :file_store]
41
+  # 默认:会从 Rails 配置的 cache_store 里面读取相同的配置信息,并尝试用可以运行的方式,用于存储验证码字符
42
+  # 但如果是 [:null_store, :memory_store, :file_store] 之类的,你可以通过下面的配置项单独给 RuCaptcha 配置 cache_store
43
+  self.cache_store = :mem_cache_store
44
+ # 如果想要 disable cache_store 的 warning,就设置为 true,default false
45
+ # self.skip_cache_store_check = true
46
+ # Chars length, default: 5, allows: [3 - 7]
47
+ # self.length = 5
48
+ # enable/disable Strikethrough.
49
+ # self.strikethrough = true
50
+ # enable/disable Outline style, for hard mode
51
+ # self.outline = false
52
+ end
53
+ ```
54
+
55
+ RuCaptcha 没有使用 Rails Session 来存储验证码信息,因为 Rails 的默认 Session 是存储在 Cookie 里面,如果验证码存在里面会存在 [Replay attack](https://en.wikipedia.org/wiki/Replay_attack) 漏洞,导致验证码关卡被攻破。
56
+
57
+ 所以我在设计上要求 RuCaptcha 得配置一个可以支持分布式的后端存储方案例如:Memcached 或 Redis 以及其他可以支持分布式的 cache_store 方案。
58
+
59
+ 同时,为了保障易用性,默认会尝试使用 `:file_store` 的方式,将验证码存在应用程序的 `tmp/cache/rucaptcha/session` 目录(但请注意,多机器部署这样是无法正常运作的)。
60
+
61
+ 所以,我建议大家使用的时候,配置上 `cache_store` (详见 [Rails Guides 缓存配置部分](https://ruby-china.github.io/rails-guides/caching_with_rails.html#%E9%85%8D%E7%BD%AE)的文档)到一个 Memcached 或 Redis,这才是最佳实践。
62
+
63
+ #
64
+ (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.
65
+
66
+ 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.
67
+
68
+ 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).
69
+
70
+ 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.)
71
+
72
+ #
73
+
74
+ Controller `app/controller/account_controller.rb`
75
+
76
+ When you called `verify_rucaptcha?`, it uses value from `params[:_rucaptcha]` to validate.
77
+
78
+ ```rb
79
+ class AccountController < ApplicationController
80
+ def create
81
+ @user = User.new(params[:user])
82
+ if verify_rucaptcha?(@user) && @user.save
83
+ redirect_to root_path, notice: 'Sign up successed.'
84
+ else
85
+ render 'account/new'
86
+ end
87
+ end
88
+ end
89
+
90
+ class ForgotPasswordController < ApplicationController
91
+ def create
92
+ # without any args
93
+ if verify_rucaptcha?
94
+ to_send_email
95
+ else
96
+ redirect_to '/forgot-password', alert: 'Invalid captcha code.'
97
+ end
98
+ end
99
+ end
100
+ ```
101
+
102
+ > 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`.
103
+
104
+ View `app/views/account/new.html.erb`
105
+
106
+ ```erb
107
+ <form method="POST">
108
+ ...
109
+ <div class="form-group">
110
+ <%= rucaptcha_input_tag(class: 'form-control', placeholder: 'Input Captcha') %>
111
+ <%= rucaptcha_image_tag(alt: 'Captcha') %>
112
+ </div>
113
+ ...
114
+
115
+ <div class="form-group">
116
+ <button type="submit" class="btn btn-primary">Submit</button>
117
+ </div>
118
+ </form>
119
+ ```
120
+
121
+ 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).
122
+
123
+ ### Write your test skip captcha validation
124
+
125
+ for RSpec
126
+
127
+ ```rb
128
+ describe 'sign up and login', type: :feature do
129
+ before do
130
+ allow_any_instance_of(ActionController::Base).to receive(:verify_rucaptcha?).and_return(true)
131
+ end
132
+
133
+ it { ... }
134
+ end
135
+ ```
136
+
137
+ for MiniTest
138
+
139
+ ```rb
140
+ class ActionDispatch::IntegrationTest
141
+ def sign_in(user)
142
+ ActionController::Base.any_instance.stubs(:verify_rucaptcha?).returns(true)
143
+ post user_session_path \
144
+ 'user[email]' => user.email,
145
+ 'user[password]' => user.password
146
+ end
147
+ end
148
+ ```
149
+
150
+ ### Invalid message without Devise
151
+
152
+ When you are using this gem without Devise, you may find out that the invalid message is missing.
153
+ For this case, use the trick below to add your i18n invalid message manually.
154
+
155
+ ```rb
156
+ if verify_rucaptcha?(@user) && @user.save
157
+ do_whatever_you_want
158
+ redirect_to someplace_you_want
159
+ else
160
+ # this is the trick
161
+ @user.errors.add(:base, t('rucaptcha.invalid'))
162
+ render :new
163
+ end
164
+ ```
@@ -0,0 +1,12 @@
1
+ module BlogsCaptcha
2
+ class CaptchaController < 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
+ rucaptcha:
3
+ invalid: "Captcha invalid!"
@@ -0,0 +1,3 @@
1
+ 'pt-BR':
2
+ rucaptcha:
3
+ invalid: "Código inválido!"
@@ -0,0 +1,3 @@
1
+ 'zh-CN':
2
+ rucaptcha:
3
+ invalid: "验证码不正确"
@@ -0,0 +1,3 @@
1
+ 'zh-TW':
2
+ rucaptcha:
3
+ invalid: "驗證碼不正確"
data/config/routes.rb ADDED
@@ -0,0 +1,3 @@
1
+ BlogsCaptcha::Engine.routes.draw do
2
+ root to: 'captcha#index'
3
+ end
@@ -0,0 +1,118 @@
1
+ // Colors from
2
+ // https://material.io/guidelines/style/color.html#color-ui-color-palette
3
+ // Color covert HEX RGB to \x??\x??\x??
4
+ static char *colors[] = {
5
+ // Black 500 #000000
6
+ "GIF89a" "\xc8\0\x46\0" "\x83" "\0\0"
7
+ "\x00\x00\x00"
8
+ "\x00\x00\x00"
9
+ "\x00\x00\x00"
10
+ "\x00\x00\x00"
11
+ "\x00\x00\x00"
12
+ "\x00\x00\x00"
13
+ "\x00\x00\x00"
14
+ "\x00\x00\x00"
15
+ "\x00\x00\x00"
16
+ "\x00\x00\x00"
17
+ "\x00\x00\x00"
18
+ "\x00\x00\x00"
19
+ "\x00\x00\x00"
20
+ "\x00\x00\x00"
21
+ "\x00\x00\x00"
22
+ "\xff\xff\xff" "," "\0\0\0\0" "\xc8\0\x46\0" "\0" "\x04",
23
+
24
+ // Red A700 #D50000
25
+ "GIF89a" "\xc8\0\x46\0" "\x83" "\0\0"
26
+ "\xD5\x00\x00"
27
+ "\xD5\x00\x00"
28
+ "\xD5\x00\x00"
29
+ "\xD5\x00\x00"
30
+ "\xD5\x00\x00"
31
+ "\xD5\x00\x00"
32
+ "\xD5\x00\x00"
33
+ "\xD5\x00\x00"
34
+ "\xD5\x00\x00"
35
+ "\xD5\x00\x00"
36
+ "\xD5\x00\x00"
37
+ "\xD5\x00\x00"
38
+ "\xD5\x00\x00"
39
+ "\xD5\x00\x00"
40
+ "\xD5\x00\x00"
41
+ "\xff\xff\xff" "," "\0\0\0\0" "\xc8\0\x46\0" "\0" "\x04",
42
+
43
+ // Deep Orange A700 #DD2C00
44
+ "GIF89a" "\xc8\0\x46\0" "\x83" "\0\0"
45
+ "\xDD\x2C\x00"
46
+ "\xDD\x2C\x00"
47
+ "\xDD\x2C\x00"
48
+ "\xDD\x2C\x00"
49
+ "\xDD\x2C\x00"
50
+ "\xDD\x2C\x00"
51
+ "\xDD\x2C\x00"
52
+ "\xDD\x2C\x00"
53
+ "\xDD\x2C\x00"
54
+ "\xDD\x2C\x00"
55
+ "\xDD\x2C\x00"
56
+ "\xDD\x2C\x00"
57
+ "\xDD\x2C\x00"
58
+ "\xDD\x2C\x00"
59
+ "\xDD\x2C\x00"
60
+ "\xff\xff\xff" "," "\0\0\0\0" "\xc8\0\x46\0" "\0" "\x04",
61
+
62
+ // Blue A700 #2962FF
63
+ "GIF89a" "\xc8\0\x46\0" "\x83" "\0\0"
64
+ "\x29\x62\xFF"
65
+ "\x29\x62\xFF"
66
+ "\x29\x62\xFF"
67
+ "\x29\x62\xFF"
68
+ "\x29\x62\xFF"
69
+ "\x29\x62\xFF"
70
+ "\x29\x62\xFF"
71
+ "\x29\x62\xFF"
72
+ "\x29\x62\xFF"
73
+ "\x29\x62\xFF"
74
+ "\x29\x62\xFF"
75
+ "\x29\x62\xFF"
76
+ "\x29\x62\xFF"
77
+ "\x29\x62\xFF"
78
+ "\x29\x62\xFF"
79
+ "\xff\xff\xff" "," "\0\0\0\0" "\xc8\0\x46\0" "\0" "\x04",
80
+
81
+ // Pink A700 #C51162
82
+ "GIF89a" "\xc8\0\x46\0" "\x83" "\0\0"
83
+ "\xC5\x11\x62"
84
+ "\xC5\x11\x62"
85
+ "\xC5\x11\x62"
86
+ "\xC5\x11\x62"
87
+ "\xC5\x11\x62"
88
+ "\xC5\x11\x62"
89
+ "\xC5\x11\x62"
90
+ "\xC5\x11\x62"
91
+ "\xC5\x11\x62"
92
+ "\xC5\x11\x62"
93
+ "\xC5\x11\x62"
94
+ "\xC5\x11\x62"
95
+ "\xC5\x11\x62"
96
+ "\xC5\x11\x62"
97
+ "\xC5\x11\x62"
98
+ "\xff\xff\xff" "," "\0\0\0\0" "\xc8\0\x46\0" "\0" "\x04",
99
+
100
+ // Deep Purple A700 #6200EA
101
+ "GIF89a" "\xc8\0\x46\0" "\x83" "\0\0"
102
+ "\x62\x00\xEA"
103
+ "\x62\x00\xEA"
104
+ "\x62\x00\xEA"
105
+ "\x62\x00\xEA"
106
+ "\x62\x00\xEA"
107
+ "\x62\x00\xEA"
108
+ "\x62\x00\xEA"
109
+ "\x62\x00\xEA"
110
+ "\x62\x00\xEA"
111
+ "\x62\x00\xEA"
112
+ "\x62\x00\xEA"
113
+ "\x62\x00\xEA"
114
+ "\x62\x00\xEA"
115
+ "\x62\x00\xEA"
116
+ "\x62\x00\xEA"
117
+ "\xff\xff\xff" "," "\0\0\0\0" "\xc8\0\x46\0" "\0" "\x04"
118
+ };
@@ -0,0 +1,2 @@
1
+ require 'mkmf'
2
+ create_makefile('blogs_captcha/blogs_captcha')
@@ -0,0 +1,27 @@
1
+ static int8_t lt0[]={-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-4,11,7,5,3,1,0,0,0,1,3,7,13,-100,-2,11,3,0,0,0,0,0,0,0,0,0,0,0,0,9,-100,-1,7,0,0,0,0,0,0,3,9,11,9,3,0,0,0,0,13,-100,9,0,0,0,0,0,0,3,-5,3,0,0,0,7,-100,5,0,0,0,0,0,1,13,-5,9,0,0,0,1,-100,7,0,0,0,0,1,13,-6,13,0,0,0,0,-100,-1,9,1,0,5,13,-8,0,0,0,0,13,-100,-14,0,0,0,0,11,-100,-14,0,0,0,0,11,-100,-14,0,0,0,0,11,-100,-12,13,5,0,0,0,0,11,-100,-8,13,9,5,1,0,0,0,0,0,0,11,-100,-4,13,7,3,1,0,0,0,0,1,1,0,0,0,0,11,-100,-2,13,5,0,0,0,0,0,5,9,13,-2,0,0,0,0,11,-100,-1,13,1,0,0,0,0,7,-6,0,0,0,0,11,-100,13,1,0,0,0,0,13,-7,0,0,0,0,11,-100,5,0,0,0,0,5,-8,0,0,0,0,11,-100,0,0,0,0,0,11,-8,0,0,0,0,11,-100,0,0,0,0,0,13,-7,13,0,0,0,0,11,-100,1,0,0,0,0,-7,9,0,0,0,0,0,9,-3,9,-100,5,0,0,0,0,3,13,-3,11,3,0,0,0,0,0,0,0,9,13,3,5,-100,13,0,0,0,0,0,0,1,1,0,0,0,1,11,9,0,0,0,0,0,0,1,13,-100,-1,11,1,0,0,0,0,0,0,0,0,5,-3,9,0,0,0,0,0,11,-100,-2,13,7,3,0,0,0,3,7,13,-5,9,0,1,3,9,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-101};
2
+ static int8_t lt1[]={-100,-100,-4,13,5,0,3,-100,-3,11,1,0,0,0,7,-100,-2,7,0,0,0,0,0,3,-100,13,3,0,0,0,0,0,0,5,-100,1,0,0,0,0,0,0,0,9,-100,1,0,0,0,0,0,0,0,13,-100,13,3,0,0,0,0,0,1,-100,-2,5,0,0,0,0,5,-100,-3,0,0,0,0,9,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,9,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,3,13,9,5,3,1,0,0,1,3,5,9,-100,-3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,13,-100,-3,0,0,0,0,0,5,13,-2,13,11,9,5,0,0,0,0,1,13,-100,-3,0,0,0,0,1,-8,13,1,0,0,0,5,-100,-3,3,0,0,0,5,-9,13,0,0,0,0,11,-100,-3,0,0,0,0,9,-10,7,0,0,0,5,-100,-3,1,0,0,0,11,-10,13,0,0,0,0,-100,-3,3,0,0,0,11,-11,3,0,0,0,11,-100,-3,1,0,0,0,11,-11,7,0,0,0,7,-100,-3,0,0,0,0,11,-11,9,0,0,0,3,-100,-3,0,0,0,0,11,-11,11,0,0,0,1,-100,-3,0,0,0,0,11,-11,11,0,0,0,1,-100,-3,0,0,0,0,11,-11,11,0,0,0,0,-100,-3,0,0,0,0,11,-11,9,0,0,0,0,-100,-3,0,0,0,0,11,-11,7,0,0,0,3,-100,-3,0,0,0,0,11,-11,3,0,0,0,7,-100,-3,0,0,0,0,11,-11,0,0,0,0,11,-100,-3,0,0,0,0,11,-10,9,0,0,0,3,-100,-3,0,0,0,0,9,-10,3,0,0,0,11,-100,-3,0,0,0,0,3,-9,11,0,0,0,5,-100,-2,13,0,0,0,0,0,9,-7,11,1,0,0,3,-100,-2,7,0,0,0,0,0,0,7,13,-2,13,9,3,0,0,0,3,13,-100,-2,13,0,0,5,13,11,1,0,0,0,0,0,0,0,0,0,7,-100,-3,9,11,-4,7,3,1,0,0,1,5,9,13,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-101};
3
+ static int8_t lt2[]={-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-6,13,7,3,1,0,0,1,3,7,13,-100,-5,9,0,0,0,0,0,0,0,0,0,0,5,13,-100,-3,13,3,0,0,0,5,13,13,7,0,0,0,0,0,1,13,-100,-2,13,1,0,0,0,9,-4,7,0,0,0,0,0,1,-100,-1,13,1,0,0,0,9,-6,5,0,0,0,0,0,13,-100,-1,5,0,0,0,3,-8,1,0,0,0,3,-100,13,0,0,0,0,11,-8,13,3,0,3,-100,7,0,0,0,1,-100,5,0,0,0,5,-100,3,0,0,0,9,-100,1,0,0,0,11,-100,0,0,0,0,11,-100,0,0,0,0,11,-100,0,0,0,0,11,-100,0,0,0,0,9,-100,1,0,0,0,5,-100,5,0,0,0,0,13,-100,11,0,0,0,0,7,-100,-1,3,0,0,0,0,13,-100,-1,11,0,0,0,0,3,-12,9,-100,-2,7,0,0,0,0,3,13,-8,9,1,3,-100,-3,5,0,0,0,0,1,9,-5,9,3,0,0,11,-100,-4,5,0,0,0,0,0,0,1,1,1,0,0,0,0,11,-100,-5,9,1,0,0,0,0,0,0,0,0,0,3,13,-100,-7,11,7,3,1,0,1,3,7,11,-100,-100,-100,-100,-100,-100,-100,-100,-100,-101};
4
+ static int8_t lt3[]={-100,-100,-100,-100,-18,11,3,0,-100,-16,13,3,0,0,0,-100,-14,9,3,0,0,0,0,0,-100,-13,3,0,0,0,0,0,0,0,-100,-13,0,0,0,0,0,0,0,0,-100,-13,9,1,0,0,0,0,0,0,-100,-15,13,5,0,0,0,0,-100,-17,1,0,0,0,-100,-17,3,0,0,0,-100,-17,1,0,0,0,-100,-17,0,0,0,0,-100,-16,13,0,0,0,0,-100,-16,13,0,0,0,0,-100,-6,11,5,3,1,0,0,1,5,9,13,13,0,0,0,0,-100,-4,13,3,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,-100,-3,13,1,0,0,0,0,5,11,-1,13,11,3,0,0,0,0,0,0,-100,-2,13,1,0,0,0,0,7,-6,11,0,0,0,0,0,-100,-2,3,0,0,0,0,9,-8,11,0,0,0,0,-100,-1,9,0,0,0,0,7,-9,11,0,0,0,0,-100,-1,1,0,0,0,0,13,-9,11,0,0,0,0,-100,11,0,0,0,0,3,-10,11,0,0,0,0,-100,5,0,0,0,0,13,-10,11,0,0,0,0,-100,3,0,0,0,3,-11,11,0,0,0,0,-100,0,0,0,0,7,-11,11,0,0,0,0,-100,0,0,0,0,11,-11,11,0,0,0,0,-100,0,0,0,0,11,-11,11,0,0,0,0,-100,0,0,0,0,11,-11,11,0,0,0,0,-100,1,0,0,0,9,-11,11,0,0,0,0,-100,3,0,0,0,7,-11,11,0,0,0,0,-100,7,0,0,0,3,-11,11,0,0,0,0,-100,13,0,0,0,0,13,-10,13,0,0,0,0,-100,-1,3,0,0,0,5,-11,0,0,0,0,-100,-1,13,0,0,0,0,11,-10,0,0,0,0,-100,-2,7,0,0,0,1,13,-8,13,0,0,0,0,13,-100,-3,5,0,0,0,1,11,-7,5,0,0,0,0,9,-100,-4,5,0,0,0,0,3,9,13,-1,13,11,1,0,0,0,0,0,0,0,5,-100,-5,9,1,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,1,13,-100,-7,9,3,1,0,0,3,7,13,-1,11,1,0,1,5,7,11,-100,-18,13,-100,-100,-100,-100,-100,-100,-100,-100,-101};
5
+ static int8_t lt4[]={-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-7,13,5,1,1,0,1,3,9,13,-100,-6,5,0,0,0,0,0,0,0,0,0,9,-100,-4,11,1,0,0,3,11,-1,13,7,1,0,0,0,9,-100,-3,9,0,0,0,1,13,-5,3,0,0,1,-100,-2,9,0,0,0,0,13,-6,11,0,0,0,9,-100,-1,13,0,0,0,0,9,-8,0,0,0,1,-100,-1,5,0,0,0,0,13,-8,3,0,0,0,11,-100,-1,0,0,0,0,0,-8,13,1,0,0,0,5,-100,9,0,0,0,0,0,3,11,-4,13,11,1,0,0,0,0,1,-100,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-100,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,-100,1,0,0,0,1,13,-100,0,0,0,0,11,-100,0,0,0,0,11,-100,1,0,0,0,9,-100,3,0,0,0,7,-100,7,0,0,0,5,-100,13,0,0,0,0,11,-100,-1,5,0,0,0,1,13,-100,-1,13,1,0,0,0,1,13,-10,13,11,-100,-2,11,0,0,0,0,1,13,-8,13,1,1,-100,-3,11,0,0,0,0,0,7,13,-4,11,7,0,0,9,-100,-4,11,1,0,0,0,0,0,1,1,1,0,0,0,0,7,-100,-5,13,5,0,0,0,0,0,0,0,0,0,1,9,-100,-7,13,7,3,0,0,0,1,5,9,-100,-100,-100,-100,-100,-100,-100,-100,-100,-101};
6
+ static int8_t lt5[]={-100,-100,-100,-100,-9,13,9,3,1,0,1,5,13,-100,-8,7,0,0,0,0,0,0,0,3,-100,-7,3,0,0,0,0,0,0,0,0,1,-100,-6,5,0,0,0,0,0,0,0,0,0,3,-100,-5,13,0,0,3,13,9,1,0,0,0,0,11,-100,-5,9,0,0,13,-2,13,5,0,1,9,-100,-5,5,0,0,-100,-5,1,0,1,-100,-5,1,0,0,-100,-5,0,0,0,-100,-5,0,0,0,13,-100,-5,0,0,0,9,-100,-5,0,0,0,7,-100,-5,0,0,0,5,-100,-3,13,7,0,0,0,0,9,-1,13,11,13,-100,3,0,0,0,0,0,0,0,0,0,0,0,0,0,9,-100,3,0,0,0,0,0,0,0,0,0,0,0,0,0,9,-100,-1,11,13,-1,7,0,0,0,0,5,-1,13,11,13,-100,-5,0,0,0,0,11,-100,-5,0,0,0,0,11,-100,-5,0,0,0,0,11,-100,-5,0,0,0,0,11,-100,-5,0,0,0,0,11,-100,-5,0,0,0,0,11,-100,-5,0,0,0,0,11,-100,-5,0,0,0,0,11,-100,-5,0,0,0,0,11,-100,-5,0,0,0,0,11,-100,-5,0,0,0,0,11,-100,-5,0,0,0,0,11,-100,-5,0,0,0,0,11,-100,-5,0,0,0,0,11,-100,-5,0,0,0,0,11,-100,-5,0,0,0,0,7,-100,-3,13,5,0,0,0,0,0,7,13,-100,-1,5,0,0,0,0,0,0,0,0,0,0,0,1,11,-100,-1,7,1,0,0,0,0,0,0,0,0,1,3,7,13,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-101};
7
+ static int8_t lt6[]={-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-7,11,7,3,1,0,0,1,3,7,13,-4,13,7,5,7,11,-100,-5,11,3,0,0,0,0,0,0,0,0,0,0,5,13,13,5,0,0,0,0,0,-100,-4,9,0,0,0,5,13,-1,13,9,3,0,0,0,0,0,0,0,0,0,0,0,1,-100,-3,11,0,0,0,5,-6,5,0,0,0,0,0,11,13,9,3,0,9,-100,-2,13,0,0,0,0,13,-7,1,0,0,0,0,13,-100,-2,1,0,0,0,7,-8,7,0,0,0,0,7,-100,-2,0,0,0,0,9,-8,11,0,0,0,0,3,-100,-2,0,0,0,0,11,-9,0,0,0,0,1,-100,-2,0,0,0,0,11,-9,0,0,0,0,0,-100,-2,0,0,0,0,9,-8,13,0,0,0,0,1,-100,-2,3,0,0,0,5,-8,9,0,0,0,0,7,-100,-2,13,1,0,0,0,13,-7,5,0,0,0,0,13,-100,-3,11,0,0,0,3,13,-5,7,0,0,0,0,11,-100,-4,7,0,0,0,1,9,13,-1,13,7,0,0,0,1,11,-100,-4,13,0,0,0,0,0,0,0,0,0,0,0,5,13,-100,-4,13,0,0,0,0,0,0,1,3,5,9,-100,-2,13,5,0,11,-100,-1,13,1,0,0,-100,-1,3,0,0,0,1,7,13,-100,-1,0,0,0,0,0,0,0,1,3,7,9,11,13,-100,-1,5,0,0,0,0,0,0,0,0,0,0,0,0,0,1,3,5,11,-100,-2,11,7,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,11,-100,-4,13,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,-100,-3,9,1,0,3,9,13,13,11,7,3,0,0,0,0,0,0,0,0,0,13,-100,-1,7,1,0,0,9,-8,11,7,3,0,0,0,0,0,5,-100,9,0,0,0,3,-13,11,1,0,0,1,-100,1,0,0,0,9,-15,0,0,0,-100,0,0,0,0,9,-14,13,0,0,1,-100,3,0,0,0,1,-14,7,0,0,5,-100,11,0,0,0,0,5,-12,11,0,0,0,13,-100,-1,11,1,0,0,0,1,7,11,13,-1,13,13,11,9,5,3,1,0,0,3,13,-100,-3,9,3,0,0,0,0,0,0,0,0,0,0,0,0,0,1,9,-100,-6,9,7,3,1,1,0,0,1,1,3,7,11,-100,-101};
8
+ static int8_t lt7[]={-100,-100,-100,-100,-4,13,7,1,9,-100,-2,13,7,0,0,0,3,-100,-1,7,0,0,0,0,0,5,-100,1,0,0,0,0,0,0,7,-100,3,0,0,0,0,0,0,7,-100,13,7,0,0,0,0,0,9,-100,-2,5,0,0,0,0,9,-100,-2,11,0,0,0,0,9,-100,-3,0,0,0,0,9,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,11,-5,11,5,1,0,1,7,-100,-3,0,0,0,0,11,-3,13,3,0,0,0,0,0,0,3,-100,-3,0,0,0,0,11,-2,7,0,0,0,0,0,0,0,0,0,9,-100,-3,0,0,0,0,11,11,3,0,5,11,-1,13,9,1,0,0,0,3,-100,-3,0,0,0,0,3,0,1,11,-6,1,0,0,0,13,-100,-3,0,0,0,0,0,5,-8,11,0,0,0,11,-100,-3,0,0,0,0,11,-10,0,0,0,7,-100,-3,0,0,0,0,13,-10,0,0,0,7,-100,-3,0,0,0,0,11,-10,0,0,0,7,-100,-3,0,0,0,0,11,-10,0,0,0,7,-100,-3,0,0,0,0,13,-10,0,0,0,9,-100,-3,0,0,0,0,13,-10,0,0,0,9,-100,-3,0,0,0,0,-11,0,0,0,11,-100,-3,0,0,0,1,-11,0,0,0,13,-100,-3,0,0,0,1,-11,0,0,0,13,-100,-3,0,0,0,3,-11,0,0,0,-100,-3,0,0,0,3,-11,0,0,0,-100,-3,0,0,0,3,-11,0,0,0,-100,-3,0,0,0,3,-10,13,0,0,0,13,-100,-3,0,0,0,1,-10,13,0,0,0,11,-100,-2,9,0,0,0,0,-10,11,0,0,0,5,-100,-1,7,0,0,0,0,0,5,13,-7,13,3,0,0,0,0,7,-100,5,0,0,0,0,0,0,0,0,3,-5,1,0,0,0,0,0,0,1,3,11,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-101};
9
+ static int8_t lt8[]={-100,-100,-100,-100,-3,5,1,0,3,11,-100,-2,7,0,0,0,0,0,11,-100,-2,1,0,0,0,0,0,5,-100,-2,0,0,0,0,0,0,5,-100,-2,5,0,0,0,0,0,11,-100,-3,7,0,0,3,9,-100,-4,13,-100,-100,-100,-100,-100,-100,-100,-4,11,3,0,9,-100,-2,9,3,0,0,0,9,-100,11,1,0,0,0,0,0,7,-100,1,0,0,0,0,0,0,7,-100,1,0,0,0,0,0,0,9,-100,-1,11,0,0,0,0,0,9,-100,-2,7,0,0,0,0,11,-100,-3,0,0,0,0,13,-100,-3,1,0,0,0,-100,-3,1,0,0,0,13,-100,-3,1,0,0,0,13,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,11,-100,-2,13,0,0,0,0,7,-100,-2,13,0,0,0,0,1,-100,-2,7,0,0,0,0,0,9,-100,7,0,0,0,0,0,0,0,0,3,-100,9,5,1,1,0,0,1,1,3,5,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-101};
10
+ static int8_t lt9[]={-100,-100,-100,-100,-6,5,0,1,5,13,-100,-5,5,0,0,0,0,1,-100,-5,1,0,0,0,0,0,13,-100,-5,0,0,0,0,0,0,-100,-5,5,0,0,0,0,3,-100,-6,7,1,0,5,13,-100,-100,-100,-100,-100,-100,-100,-100,-6,13,7,3,0,13,-100,-5,7,0,0,0,0,11,-100,-3,7,1,0,0,0,0,0,11,-100,-2,13,0,0,0,0,0,0,0,11,-100,-3,11,3,0,0,0,0,0,11,-100,-5,9,0,0,0,0,11,-100,-6,1,0,0,0,11,-100,-6,3,0,0,0,11,-100,-6,5,0,0,0,11,-100,-6,5,0,0,0,11,-100,-6,5,0,0,0,11,-100,-6,5,0,0,0,11,-100,-6,3,0,0,0,11,-100,-6,3,0,0,0,11,-100,-6,1,0,0,0,11,-100,-6,1,0,0,0,13,-100,-6,1,0,0,0,13,-100,-6,1,0,0,0,13,-100,-6,1,0,0,0,13,-100,-6,1,0,0,0,13,-100,-6,1,0,0,0,-100,-6,1,0,0,0,-100,-6,1,0,0,1,-100,-6,1,0,0,3,-100,-6,0,0,0,5,-100,-6,0,0,0,7,-100,-6,0,0,0,11,-100,11,0,0,0,5,5,0,0,5,-100,3,0,0,0,0,0,0,3,-100,0,0,0,0,0,0,0,13,-100,1,0,0,0,0,0,11,-100,13,3,0,0,3,11,-100,-100,-101};
11
+ static int8_t lt10[]={-100,-100,-100,-100,-6,9,1,13,-100,-3,13,5,0,0,0,11,-100,-1,13,5,0,0,0,0,0,11,-100,13,1,0,0,0,0,0,0,11,-100,3,0,0,0,0,0,0,0,11,-100,11,3,0,0,0,0,0,0,11,-100,-2,13,0,0,0,0,0,11,-100,-3,9,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-7,3,0,0,0,0,0,0,0,0,0,3,-100,-4,0,0,0,0,11,-7,5,0,0,0,0,0,0,0,1,7,13,-100,-4,0,0,0,0,11,-8,9,0,0,0,1,9,-100,-4,0,0,0,0,11,-7,13,1,0,0,7,-100,-4,0,0,0,0,11,-7,5,0,3,13,-100,-4,0,0,0,0,11,-6,5,0,5,-100,-4,0,0,0,0,11,-5,5,1,11,-100,-4,0,0,0,0,11,-3,11,3,1,-100,-4,0,0,0,0,11,-1,11,3,0,0,1,-100,-4,0,0,0,0,11,9,0,0,0,0,0,11,-100,-4,0,0,0,0,0,0,1,0,0,0,0,3,-100,-4,0,0,0,0,0,9,-1,11,1,0,0,0,9,-100,-4,0,0,0,0,5,-4,3,0,0,0,11,-100,-4,0,0,0,0,11,-4,13,1,0,0,0,13,-100,-4,0,0,0,0,11,-5,11,0,0,0,1,13,-100,-4,0,0,0,0,11,-6,3,0,0,0,3,-100,-4,0,0,0,0,11,-6,11,0,0,0,0,7,-100,-4,0,0,0,0,11,-7,3,0,0,0,0,7,-100,-3,13,0,0,0,0,11,-7,13,0,0,0,0,0,7,-100,-2,13,3,0,0,0,0,7,-7,9,0,0,0,0,0,0,3,11,-100,-1,1,0,0,0,0,0,0,0,0,1,3,-4,0,0,0,0,0,0,0,0,0,0,3,-100,-1,7,1,0,0,0,0,0,0,0,0,7,-4,3,0,0,0,0,0,0,1,1,5,9,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-101};
12
+ static int8_t lt11[]={-100,-100,-100,-6,11,7,11,-100,-4,11,3,0,0,5,-100,-3,5,0,0,0,0,5,-100,-1,11,1,0,0,0,0,0,7,-100,7,0,0,0,0,0,0,0,7,-100,0,0,0,0,0,0,0,0,9,-100,7,0,0,0,0,0,0,0,9,-100,-2,9,1,0,0,0,0,9,-100,-3,11,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,7,-100,-3,5,0,0,0,0,0,13,-100,-1,9,1,0,0,0,0,0,0,0,1,9,-100,-1,5,1,0,0,0,0,0,0,0,1,11,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-101};
13
+ static int8_t lt12[]={-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-5,11,5,0,-21,7,1,0,3,9,-100,-4,7,0,0,0,13,-4,11,5,1,1,0,1,7,-7,11,3,0,0,0,0,0,5,-100,-2,11,1,0,0,0,0,11,-2,9,1,0,0,0,0,0,0,0,9,-4,13,5,0,0,0,0,0,0,0,0,7,-100,13,3,0,0,0,0,0,0,7,13,3,0,0,0,1,0,0,0,0,0,0,7,-1,13,7,0,0,0,0,0,0,0,0,0,0,0,11,-100,3,0,0,0,0,0,0,0,1,0,0,5,11,-3,11,0,0,0,0,0,0,0,3,9,13,13,-3,7,0,0,0,0,5,-100,13,3,0,0,0,0,0,0,0,7,13,-6,3,0,0,0,0,0,9,-8,5,0,0,0,1,-100,-2,11,0,0,0,0,0,3,-8,9,0,0,0,0,7,-9,11,0,0,0,0,-100,-3,3,0,0,0,0,7,-8,13,0,0,0,0,-10,11,0,0,0,0,-100,-3,7,0,0,0,0,11,-9,0,0,0,0,-10,11,0,0,0,1,-100,-3,11,0,0,0,0,11,-9,0,0,0,0,-10,11,0,0,0,3,-100,-3,13,0,0,0,0,11,-8,13,0,0,0,0,-10,11,0,0,0,5,-100,-3,13,0,0,0,0,11,-8,11,0,0,0,0,-10,11,0,0,0,5,-100,-4,0,0,0,0,13,-8,9,0,0,0,0,-10,11,0,0,0,5,-100,-4,0,0,0,0,13,-8,11,0,0,0,0,-10,11,0,0,0,3,-100,-4,0,0,0,0,13,-8,11,0,0,0,0,-10,11,0,0,0,0,-100,-3,13,0,0,0,1,-9,13,0,0,0,0,-10,11,0,0,0,0,-100,-3,11,0,0,0,13,-10,0,0,0,0,-10,11,0,0,0,0,-100,-4,0,0,0,11,-10,0,0,0,0,-10,11,0,0,0,0,-100,-3,13,0,0,0,3,-9,13,0,0,0,0,13,-9,9,0,0,0,0,-100,-3,7,0,0,0,0,13,-8,11,0,0,0,0,11,-9,7,0,0,0,0,13,-100,-3,3,0,0,0,0,9,-8,5,0,0,0,0,5,-9,5,0,0,0,0,7,-100,-1,13,3,0,0,0,0,0,1,11,-6,9,0,0,0,0,0,0,3,-7,11,1,0,0,0,0,1,13,-100,11,0,0,0,0,0,0,0,0,0,3,-4,3,0,0,0,0,0,0,0,0,5,-5,1,0,0,0,0,0,0,0,0,9,-100,13,1,0,0,0,0,0,0,0,1,9,-4,1,0,0,0,0,0,0,0,1,5,-5,1,0,0,0,0,0,0,0,0,7,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-101};
14
+ static int8_t lt13[]={-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-3,13,7,3,0,13,-5,13,7,1,0,0,3,7,-100,-2,5,0,0,0,0,-4,13,3,0,0,0,0,0,0,0,7,-100,7,1,0,0,0,0,0,-3,7,0,0,0,0,0,0,0,0,0,0,13,-100,1,0,0,0,0,0,0,13,9,1,0,5,11,13,-1,11,3,0,0,0,0,9,-100,13,3,0,0,0,0,0,1,1,7,-7,3,0,0,0,3,-100,-2,1,0,0,0,0,7,-9,13,0,0,0,1,-100,-2,7,0,0,0,0,-11,1,0,0,0,-100,-2,9,0,0,0,0,-11,1,0,0,0,13,-100,-2,11,0,0,0,0,-11,3,0,0,0,13,-100,-2,11,0,0,0,0,-11,5,0,0,0,11,-100,-2,11,0,0,0,0,-11,3,0,0,0,11,-100,-2,11,0,0,0,0,-11,1,0,0,0,11,-100,-2,11,0,0,0,0,-11,0,0,0,0,11,-100,-2,11,0,0,0,0,-11,0,0,0,0,11,-100,-2,11,0,0,0,0,-11,1,0,0,0,11,-100,-2,11,0,0,0,0,-11,3,0,0,0,11,-100,-2,11,0,0,0,0,-11,3,0,0,0,11,-100,-2,11,0,0,0,0,13,-10,5,0,0,0,11,-100,-2,11,0,0,0,0,13,-10,5,0,0,0,11,-100,-2,11,0,0,0,0,9,-10,5,0,0,0,9,-100,-2,7,0,0,0,0,5,-10,3,0,0,0,7,-100,-1,13,1,0,0,0,0,1,11,-7,11,5,0,0,0,0,0,3,9,-100,-1,1,0,0,0,0,0,0,0,0,3,-4,3,0,0,0,0,0,0,0,0,0,3,-100,-1,0,0,0,0,0,0,0,0,0,3,-4,5,1,0,0,0,0,0,0,0,0,1,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-101};
15
+ static int8_t lt14[]={-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-7,13,7,3,1,0,0,1,5,9,-100,-6,7,0,0,0,0,0,0,0,0,0,1,7,-100,-4,11,1,0,0,1,9,13,-1,13,11,5,0,0,0,3,13,-100,-3,11,0,0,0,3,13,-6,13,1,0,0,0,13,-100,-2,11,0,0,0,1,13,-8,13,0,0,0,5,-100,-2,0,0,0,0,9,-10,5,0,0,0,11,-100,-1,7,0,0,0,1,-11,13,0,0,0,1,-100,-1,1,0,0,0,5,-12,1,0,0,0,9,-100,11,0,0,0,0,11,-12,5,0,0,0,3,-100,7,0,0,0,0,13,-12,9,0,0,0,0,-100,3,0,0,0,0,13,-12,11,0,0,0,0,-100,1,0,0,0,0,-13,11,0,0,0,1,-100,0,0,0,0,0,-13,11,0,0,0,1,-100,0,0,0,0,0,13,-12,11,0,0,0,0,-100,1,0,0,0,0,13,-12,9,0,0,0,1,-100,5,0,0,0,0,11,-12,5,0,0,0,3,-100,9,0,0,0,0,9,-12,3,0,0,0,7,-100,-1,1,0,0,0,5,-12,0,0,0,0,11,-100,-1,9,0,0,0,3,-11,13,0,0,0,3,-100,-2,3,0,0,0,13,-10,7,0,0,0,11,-100,-2,13,1,0,0,3,-9,13,0,0,0,7,-100,-3,13,1,0,0,3,13,-6,13,1,0,0,5,-100,-4,13,1,0,0,1,7,13,-3,9,0,0,0,7,-100,-6,7,0,0,0,0,0,0,0,0,0,3,11,-100,-7,13,7,3,0,0,0,0,3,11,-100,-100,-100,-100,-100,-100,-100,-100,-100,-101};
16
+ static int8_t lt15[]={-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-6,11,7,-100,-4,11,3,0,0,7,11,5,3,0,0,0,1,5,9,-100,-2,11,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,-100,13,5,0,0,0,0,0,0,0,1,7,11,13,-1,13,3,0,0,0,5,-100,1,0,0,0,0,0,0,0,3,-7,7,0,0,0,7,-100,1,0,0,0,0,0,0,0,11,-8,7,0,0,0,13,-100,-1,11,5,0,0,0,0,0,11,-9,1,0,0,3,-100,-3,7,0,0,0,0,11,-9,5,0,0,0,11,-100,-3,9,0,0,0,0,11,-9,9,0,0,0,5,-100,-3,11,0,0,0,0,11,-9,11,0,0,0,0,13,-100,-3,11,0,0,0,0,11,-9,13,0,0,0,0,11,-100,-3,13,0,0,0,0,11,-10,0,0,0,0,11,-100,-3,13,0,0,0,0,11,-10,0,0,0,0,11,-100,-3,13,0,0,0,0,11,-10,0,0,0,0,11,-100,-4,0,0,0,0,11,-10,0,0,0,0,13,-100,-4,0,0,0,0,11,-10,0,0,0,0,13,-100,-4,0,0,0,0,13,-10,0,0,0,0,-100,-4,0,0,0,9,-11,0,0,0,3,-100,-4,0,0,0,3,-11,0,0,0,9,-100,-4,0,0,0,0,13,-10,0,0,0,13,-100,-4,0,0,0,0,11,-9,5,0,0,0,-100,-4,0,0,0,0,11,-8,7,0,0,0,7,-100,-4,0,0,0,0,5,-7,9,0,0,0,3,-100,-4,0,0,0,0,0,3,11,13,-3,9,0,0,0,1,-100,-4,0,0,0,0,5,7,0,0,0,1,1,0,0,0,1,13,-100,-4,0,0,0,0,11,-2,9,5,1,0,0,3,7,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,7,-100,-4,0,0,0,0,3,-100,-3,7,0,0,0,0,0,9,-100,-1,5,0,0,0,0,0,0,0,0,0,0,5,-100,-1,3,1,0,0,0,0,0,0,0,0,0,5,-100,-101};
17
+ static int8_t lt16[]={-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-19,7,11,-100,-6,11,5,1,0,0,1,5,11,-4,5,0,3,-100,-4,13,3,0,0,0,0,0,0,0,0,1,11,13,5,0,0,1,-100,-3,13,1,0,0,1,5,11,-3,11,3,0,0,0,0,0,3,-100,-2,13,1,0,0,3,-8,3,0,0,0,0,5,-100,-1,13,1,0,0,0,13,-8,7,0,0,0,0,5,-100,-1,3,0,0,0,5,-9,11,0,0,0,0,7,-100,9,0,0,0,0,11,-9,13,0,0,0,0,9,-100,3,0,0,0,0,-10,13,0,0,0,0,9,-100,1,0,0,0,1,-11,0,0,0,0,9,-100,0,0,0,0,3,-11,0,0,0,0,11,-100,0,0,0,0,5,-11,0,0,0,0,11,-100,0,0,0,0,9,-11,0,0,0,0,11,-100,0,0,0,0,11,-11,0,0,0,0,11,-100,0,0,0,0,11,-11,0,0,0,0,11,-100,1,0,0,0,11,-11,0,0,0,0,11,-100,3,0,0,0,9,-11,0,0,0,0,11,-100,7,0,0,0,5,-11,0,0,0,0,11,-100,11,0,0,0,0,-11,0,0,0,0,11,-100,-1,1,0,0,0,7,-9,11,0,0,0,0,11,-100,-1,9,0,0,0,0,13,-8,9,0,0,0,0,11,-100,-2,3,0,0,0,1,13,-7,5,0,0,0,0,11,-100,-2,13,3,0,0,0,1,9,13,-3,13,7,0,0,0,0,0,11,-100,-4,9,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,11,-100,-6,11,7,3,1,0,0,5,9,-1,13,0,0,0,0,11,-100,-16,0,0,0,0,13,-100,-16,0,0,0,0,13,-100,-16,0,0,0,0,13,-100,-16,0,0,0,0,13,-100,-15,13,0,0,0,0,13,-100,-15,9,0,0,0,0,11,-100,-15,1,0,0,0,0,5,-100,-12,7,5,1,0,0,0,0,0,0,1,3,9,-100,-11,13,1,0,0,0,0,0,0,0,0,0,0,7,-100,-101};
18
+ static int8_t lt17[]={-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-3,13,5,0,3,-5,9,3,1,0,0,3,-100,-1,11,3,0,0,0,0,-3,7,0,0,0,0,0,0,0,5,-100,9,0,0,0,0,0,0,-2,3,0,0,0,0,0,0,0,0,1,-100,0,0,0,0,0,0,0,11,3,0,0,0,0,0,0,0,0,0,1,-100,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,-100,-1,7,0,0,0,0,0,0,7,13,-2,11,7,3,1,3,11,-100,-2,3,0,0,0,0,3,-100,-2,7,0,0,0,0,9,-100,-2,11,0,0,0,0,13,-100,-2,13,0,0,0,0,-100,-3,0,0,0,0,-100,-3,0,0,0,0,13,-100,-3,0,0,0,0,13,-100,-3,0,0,0,0,13,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,9,-100,-1,13,3,0,0,0,0,1,13,-100,3,0,0,0,0,0,0,0,0,0,0,13,-100,5,1,0,0,0,0,0,0,0,0,3,13,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-101};
19
+ static int8_t lt18[]={-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-3,13,7,1,0,1,3,9,11,9,9,13,-100,-2,13,1,0,0,0,0,0,0,0,0,0,5,-100,-2,1,0,5,13,-1,13,11,3,0,0,0,1,-100,-1,9,0,1,-6,9,0,0,0,13,-100,-1,3,0,9,-7,11,1,0,9,-100,-1,0,0,-9,13,1,5,-100,-1,0,0,11,-9,13,11,-100,13,0,0,1,13,-100,13,0,0,0,1,9,-100,-1,0,0,0,0,0,0,5,9,-100,-1,5,0,0,0,0,0,0,0,1,7,13,-100,-1,13,0,0,0,0,0,0,0,0,0,0,9,-100,-2,13,1,0,0,0,0,0,0,0,0,0,7,-100,-4,11,5,0,0,0,0,0,0,0,0,7,-100,-7,9,5,0,0,0,0,0,0,13,-100,-9,13,7,0,0,0,0,7,-100,-11,13,3,0,0,3,-100,-13,0,0,0,-100,7,5,-11,1,0,0,-100,1,0,5,-10,1,0,3,-100,0,0,0,3,-9,0,0,9,-100,1,0,0,0,3,13,-6,5,0,3,-100,7,0,0,0,0,1,7,11,13,13,9,3,0,1,13,-100,13,0,0,0,0,0,0,0,0,0,0,0,3,13,-100,-1,5,3,9,7,3,1,0,0,1,5,11,-100,-100,-100,-100,-100,-100,-100,-100,-100,-101};
20
+ static int8_t lt19[]={-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-6,5,0,5,-100,-5,13,0,0,0,7,-100,-5,7,0,0,0,9,-100,-5,3,0,0,0,13,-100,-4,11,0,0,0,0,-100,-4,3,0,0,0,0,-100,-3,5,0,0,0,0,1,-100,-2,3,0,0,0,0,0,7,-100,13,1,0,0,0,0,0,0,1,11,-100,3,0,0,0,0,0,0,0,0,0,0,0,0,0,5,13,-100,1,0,0,0,0,0,0,0,0,0,0,0,0,0,5,-100,-3,9,0,0,0,0,7,13,-100,-4,0,0,0,0,11,-100,-4,1,0,0,0,11,-100,-4,1,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,1,0,0,0,11,-100,-4,3,0,0,0,11,-100,-4,5,0,0,0,11,-100,-4,3,0,0,0,11,-100,-4,3,0,0,0,11,-100,-4,1,0,0,0,9,-100,-4,0,0,0,0,5,-100,-4,0,0,0,0,1,-100,-4,1,0,0,0,0,11,-100,-4,3,0,0,0,0,1,13,-1,9,5,1,3,-100,-4,9,0,0,0,0,0,0,0,0,0,0,5,-100,-5,5,0,0,0,0,0,0,0,0,5,-100,-6,9,3,1,0,0,1,5,11,-100,-100,-100,-100,-100,-100,-100,-100,-100,-101};
21
+ static int8_t lt20[]={-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-4,13,9,1,0,13,-11,11,5,1,5,-100,-2,11,3,0,0,0,0,11,-8,11,5,0,0,0,0,1,-100,13,3,0,0,0,0,0,0,11,-6,7,1,0,0,0,0,0,0,7,-100,5,0,0,0,0,0,0,0,11,-5,5,0,0,0,0,0,0,0,0,11,-100,11,1,0,0,0,0,0,0,11,-5,9,0,0,0,0,0,0,0,0,11,-100,-2,11,1,0,0,0,0,11,-6,13,7,3,0,0,0,0,0,11,-100,-3,9,0,0,0,0,11,-9,9,0,0,0,0,11,-100,-3,11,0,0,0,0,11,-10,0,0,0,0,11,-100,-3,13,0,0,0,0,11,-10,0,0,0,0,11,-100,-4,0,0,0,0,11,-10,0,0,0,0,11,-100,-4,0,0,0,0,11,-10,0,0,0,0,11,-100,-4,0,0,0,0,11,-10,0,0,0,0,11,-100,-4,0,0,0,0,11,-10,0,0,0,0,11,-100,-4,0,0,0,0,11,-10,0,0,0,0,11,-100,-4,0,0,0,0,11,-10,0,0,0,0,11,-100,-4,0,0,0,0,11,-10,0,0,0,0,11,-100,-4,0,0,0,0,11,-10,0,0,0,0,11,-100,-4,1,0,0,0,11,-9,13,0,0,0,0,11,-100,-4,1,0,0,0,11,-9,5,0,0,0,0,11,-100,-4,5,0,0,0,7,-8,7,0,0,0,0,0,11,-100,-4,7,0,0,0,0,13,-5,13,5,0,0,0,0,0,0,11,-100,-4,13,0,0,0,0,1,11,-1,13,11,5,0,0,7,5,0,0,0,0,3,13,-100,-5,3,0,0,0,0,0,0,0,0,0,3,13,-2,0,0,0,0,0,0,7,-100,-5,11,0,0,0,0,0,0,0,1,9,-4,0,0,0,0,0,0,0,-100,-6,13,5,1,0,1,3,9,-6,3,1,3,7,9,11,13,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-101};
22
+ static int8_t lt21[]={-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-6,13,9,1,3,13,-5,13,1,0,0,0,0,1,3,9,-100,1,0,0,0,0,0,0,0,0,0,1,-5,1,0,0,0,0,0,0,0,0,9,-100,3,0,0,0,0,0,0,0,0,0,5,-5,3,0,0,0,0,0,0,0,0,13,-100,-1,9,3,0,0,0,0,0,5,13,-7,13,9,0,0,0,0,1,11,-100,-3,7,0,0,0,0,-11,7,0,0,5,-100,-4,0,0,0,0,9,-10,9,0,5,-100,-4,5,0,0,0,1,-10,5,0,11,-100,-4,11,0,0,0,0,9,-9,0,1,-100,-5,1,0,0,0,3,-8,9,0,7,-100,-5,7,0,0,0,0,13,-7,3,0,13,-100,-5,13,0,0,0,0,7,-6,13,0,3,-100,-6,3,0,0,0,1,-6,7,0,11,-100,-6,9,0,0,0,0,9,-5,0,1,-100,-6,13,0,0,0,0,3,-4,7,0,7,-100,-7,5,0,0,0,0,11,-3,1,0,13,-100,-7,11,0,0,0,0,1,-2,9,0,5,-100,-8,1,0,0,0,0,5,-1,1,0,11,-100,-8,7,0,0,0,0,0,0,0,3,-100,-8,13,0,0,0,0,0,0,0,9,-100,-9,3,0,0,0,0,0,1,-100,-9,9,0,0,0,0,0,7,-100,-10,0,0,0,0,0,13,-100,-10,5,0,0,0,1,-100,-10,13,1,0,0,7,-100,-11,11,1,5,-100,-100,-100,-100,-100,-100,-100,-100,-100,-101};
23
+ static int8_t lt22[]={-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-29,13,-100,5,0,0,1,1,1,3,3,5,7,-3,7,0,0,0,0,0,0,0,0,0,11,-4,3,0,0,0,0,0,0,1,3,11,-100,5,0,0,0,0,0,0,0,1,7,-3,9,0,0,0,0,0,0,0,0,1,11,-4,9,1,0,0,0,0,0,0,1,13,-100,-1,13,5,0,0,0,0,0,13,-5,13,5,0,0,0,0,0,3,-8,9,0,0,0,0,5,-100,-3,5,0,0,0,0,-8,11,0,0,0,0,9,-9,9,0,0,9,-100,-4,1,0,0,0,13,-8,11,0,0,0,3,-10,0,3,-100,-4,7,0,0,0,11,-8,13,0,0,0,0,13,-8,9,0,11,-100,-4,13,0,0,0,7,-8,11,0,0,0,0,7,-8,1,1,-100,-5,5,0,0,1,-8,7,0,0,0,0,3,-8,5,11,-100,-5,11,0,0,0,9,-7,1,0,0,0,0,0,13,-100,-6,0,0,0,3,-6,9,0,3,13,0,0,0,7,-6,5,-100,-6,3,0,0,0,13,-5,1,0,11,-1,3,0,0,3,-6,1,-100,-6,9,0,0,0,9,-4,11,0,3,-2,7,0,0,0,13,-4,11,1,-100,-6,13,0,0,0,3,-4,5,0,9,-2,13,0,0,0,7,-4,5,3,-100,-7,3,0,0,0,13,-3,1,1,-4,0,0,0,1,-4,1,7,-100,-7,9,0,0,0,5,-2,13,0,7,-4,5,0,0,0,9,-2,9,0,13,-100,-8,1,0,0,0,13,-1,7,1,-5,11,0,0,0,1,-2,1,3,-100,-8,7,0,0,0,1,13,1,5,-6,1,0,0,0,13,9,0,9,-100,-8,13,0,0,0,0,0,0,11,-6,7,0,0,0,1,0,1,-100,-9,3,0,0,0,0,3,-7,13,0,0,0,0,0,9,-100,-9,9,0,0,0,0,5,-8,3,0,0,0,0,13,-100,-9,13,0,0,0,0,11,-8,9,0,0,0,1,-100,-10,3,0,0,0,-10,3,0,0,5,-100,-10,11,0,0,7,-10,13,1,1,13,-100,-11,11,11,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-101};
24
+ static int8_t lt23[]={-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-16,13,13,-1,13,9,5,1,0,1,5,13,-100,-1,3,0,0,0,0,0,0,0,0,1,7,-4,1,0,0,0,0,0,0,0,0,0,1,-100,-1,1,0,0,0,0,0,0,0,0,1,11,-4,7,0,0,0,0,0,0,0,0,0,5,-100,-2,13,7,0,0,0,0,0,0,13,-6,13,5,0,0,0,0,5,9,13,-100,-4,13,3,0,0,0,0,3,-7,13,0,0,5,13,-100,-6,3,0,0,0,0,5,-6,7,0,7,-100,-7,3,0,0,0,0,11,-4,11,0,9,-100,-8,5,0,0,0,1,-3,11,0,7,-100,-9,3,0,0,0,1,11,11,0,7,-100,-9,13,1,0,0,0,0,0,7,-100,-10,13,1,0,0,0,0,9,-100,-11,11,0,0,0,0,1,-100,-12,0,0,0,0,0,7,-100,-11,9,0,0,0,0,0,0,11,-100,-10,9,0,5,13,3,0,0,0,1,13,-100,-9,11,0,3,-2,13,1,0,0,0,1,13,-100,-8,11,0,3,13,-3,13,1,0,0,0,1,13,-100,-7,9,0,1,13,-5,11,0,0,0,0,1,13,-100,-6,9,0,0,7,-7,9,0,0,0,0,1,11,-100,-5,5,0,0,0,13,-8,7,0,0,0,0,0,9,-100,-3,13,3,0,0,0,0,13,-8,13,0,0,0,0,0,0,5,-100,9,3,1,0,0,0,0,0,0,1,11,-6,11,1,0,0,0,0,0,0,0,1,3,13,-100,3,0,0,0,0,0,0,0,0,0,3,-6,11,5,3,1,0,0,0,1,1,3,5,-100,13,13,13,13,-100,-100,-100,-100,-100,-100,-100,-100,-100,-101};
25
+ static int8_t lt24[]={-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-1,13,13,-2,13,13,11,11,11,13,-6,11,11,11,11,11,11,11,11,13,-100,3,0,0,0,0,0,0,0,0,0,0,3,-4,1,0,0,0,0,0,0,0,0,1,-100,7,0,0,0,0,0,0,0,0,0,0,5,-4,3,0,0,0,0,0,0,0,0,9,-100,-2,11,5,0,0,0,0,0,0,11,-6,11,0,0,0,0,1,7,13,-100,-4,11,0,0,0,0,0,-8,9,0,0,1,13,-100,-5,7,0,0,0,0,13,-7,9,0,0,13,-100,-6,1,0,0,0,9,-7,5,0,5,-100,-6,7,0,0,0,3,-7,1,0,13,-100,-6,13,0,0,0,0,13,-5,11,0,1,-100,-7,5,0,0,0,7,-5,7,0,7,-100,-7,11,0,0,0,3,-5,1,0,11,-100,-8,1,0,0,0,13,-3,13,0,3,-100,-8,7,0,0,0,7,-3,7,0,9,-100,-8,13,0,0,0,3,-3,1,1,-100,-9,5,0,0,0,13,-1,9,0,7,-100,-9,11,0,0,0,3,13,1,0,13,-100,-10,1,0,0,0,0,0,3,-100,-10,9,0,0,0,0,0,9,-100,-11,1,0,0,0,1,-100,-11,5,0,0,0,7,-100,-11,9,0,0,0,13,-100,-11,13,0,0,3,-100,-12,0,0,9,-100,-12,0,1,-100,-11,13,0,7,-100,-11,7,0,11,-100,-11,1,0,-100,-2,7,0,1,7,-4,11,0,3,-100,-1,11,0,0,0,0,1,9,13,11,1,0,9,-100,-1,3,0,0,0,0,0,0,0,0,0,3,-100,-1,0,0,0,0,0,0,0,0,0,1,13,-100,-1,7,0,0,0,0,0,0,0,1,13,-100,-2,9,3,0,0,1,3,7,-100,-101};
26
+ static int8_t *lt[]={lt0,lt1,lt2,lt3,lt0,lt5,lt0,lt7,lt8,lt9,lt10,lt11,lt12,lt13,lt14,lt15,lt16,lt17,lt18,lt19,lt20,lt21,lt22,lt23,lt24,};
27
+
@@ -0,0 +1,240 @@
1
+ // http://github.com/ITikhonov/captcha
2
+ const int gifsize;
3
+ void captcha(unsigned char im[70*200], unsigned char l[8], int length, int i_line, int i_filter);
4
+ void makegif(unsigned char im[70*200], unsigned char gif[gifsize], int style);
5
+
6
+ #include <unistd.h>
7
+ #include <stdint.h>
8
+ #include <stdlib.h>
9
+ #include <fcntl.h>
10
+ #include <string.h>
11
+ #include <time.h>
12
+ #include <ruby.h>
13
+ #include "font.h"
14
+ #include "colors.h"
15
+
16
+ static int8_t *lt[];
17
+ const int gifsize=17646;
18
+
19
+ void makegif(unsigned char im[70*200], unsigned char gif[gifsize], int style) {
20
+ // tag ; widthxheight ; GCT:0:0:7 ; bgcolor + aspect // GCT
21
+ // Image Separator // left x top // widthxheight // Flags
22
+ // LZW code size
23
+ srand(time(NULL));
24
+ int color_len = (int) sizeof(colors) / sizeof(colors[0]);
25
+ int color_idx = rand() % color_len;
26
+ if (style == 0) {
27
+ color_idx = 0;
28
+ }
29
+ memcpy(gif,colors[color_idx],13+48+10+1);
30
+
31
+ int x,y;
32
+ unsigned char *i=im;
33
+ unsigned char *p=gif+13+48+10+1;
34
+ for(y=0;y<70;y++) {
35
+ *p++=250; // Data length 5*50=250
36
+ for(x=0;x<50;x++)
37
+ {
38
+ unsigned char a=i[0]>>4,b=i[1]>>4,c=i[2]>>4,d=i[3]>>4;
39
+
40
+ p[0]=16|(a<<5); // bbb10000
41
+ p[1]=(a>>3)|64|(b<<7); // b10000xb
42
+ p[2]=b>>1; // 0000xbbb
43
+ p[3]=1|(c<<1); // 00xbbbb1
44
+ p[4]=4|(d<<3); // xbbbb100
45
+ i+=4;
46
+ p+=5;
47
+ }
48
+ }
49
+
50
+ // Data length // End of LZW (b10001) // Terminator // GIF End
51
+ memcpy(gif+gifsize-4,"\x01" "\x11" "\x00" ";",4);
52
+ }
53
+
54
+ static const int8_t sw[200]={0, 4, 8, 12, 16, 20, 23, 27, 31, 35, 39, 43, 47, 50, 54, 58, 61, 65, 68, 71, 75, 78, 81, 84, 87, 90, 93, 96, 98, 101, 103, 105, 108, 110, 112, 114, 115, 117, 119, 120, 121, 122, 123, 124, 125, 126, 126, 127, 127, 127, 127, 127, 127, 127, 126, 126, 125, 124, 123, 122, 121, 120, 119, 117, 115, 114, 112, 110, 108, 105, 103, 101, 98, 96, 93, 90, 87, 84, 81, 78, 75, 71, 68, 65, 61, 58, 54, 50, 47, 43, 39, 35, 31, 27, 23, 20, 16, 12, 8, 4, 0, -4, -8, -12, -16, -20, -23, -27, -31, -35, -39, -43, -47, -50, -54, -58, -61, -65, -68, -71, -75, -78, -81, -84, -87, -90, -93, -96, -98, -101, -103, -105, -108, -110, -112, -114, -115, -117, -119, -120, -121, -122, -123, -124, -125, -126, -126, -127, -127, -127, -127, -127, -127, -127, -126, -126, -125, -124, -123, -122, -121, -120, -119, -117, -115, -114, -112, -110, -108, -105, -103, -101, -98, -96, -93, -90, -87, -84, -81, -78, -75, -71, -68, -65, -61, -58, -54, -50, -47, -43, -39, -35, -31, -27, -23, -20, -16, -12, -8, -4};
55
+
56
+
57
+ #define MAX(x,y) ((x>y)?(x):(y))
58
+
59
+ static int letter(int n, int pos, unsigned char im[70*200], unsigned char swr[200], uint8_t s1, uint8_t s2) {
60
+ int8_t *p=lt[n];
61
+ unsigned char *r=im+200*16+pos;
62
+ unsigned char *i=r;
63
+ int sk1=s1+pos;
64
+ int sk2=s2+pos;
65
+ int mpos=pos;
66
+ int row=0;
67
+ for(;*p!=-101;p++) {
68
+ if(*p<0) {
69
+ if(*p==-100) { r+=200; i=r; sk1=s1+pos; row++; continue; }
70
+ i+=-*p;
71
+ continue;
72
+ }
73
+
74
+ if(sk1>=200) sk1=sk1%200;
75
+ int skew=sw[sk1]/16;
76
+ sk1+=(swr[pos+i-r]&0x1)+1;
77
+
78
+ if(sk2>=200) sk2=sk2%200;
79
+ int skewh=sw[sk2]/70;
80
+ sk2+=(swr[row]&0x1);
81
+
82
+ unsigned char *x=i+skew*200+skewh;
83
+ mpos=MAX(mpos,pos+i-r);
84
+
85
+ if((x-im)<70*200) *x=(*p)<<4;
86
+ i++;
87
+ }
88
+ return mpos + 3;
89
+ }
90
+
91
+ #define NDOTS 10
92
+
93
+ uint32_t dr[NDOTS];
94
+
95
+ static void line(unsigned char im[70*200], unsigned char swr[200], uint8_t s1) {
96
+ int x;
97
+ int sk1=s1;
98
+ for(x=0;x<199;x++) {
99
+ if(sk1>=200) sk1=sk1%200;
100
+ int skew=sw[sk1]/20;
101
+ sk1+=swr[x]&0x3+1;
102
+ unsigned char *i= im+(200*(45+skew)+x);
103
+ i[0]=0; i[1]=0; i[200]=0; i[201]=0;
104
+ }
105
+ }
106
+
107
+ static void dots(unsigned char im[70*200]) {
108
+ int n;
109
+ for(n=0;n<NDOTS;n++) {
110
+ uint32_t v=dr[n];
111
+ unsigned char *i=im+v%(200*67);
112
+
113
+ i[0]=0xff;
114
+ i[1]=0xff;
115
+ i[2]=0xff;
116
+ i[200]=0xff;
117
+ i[201]=0xff;
118
+ i[202]=0xff;
119
+ }
120
+ }
121
+
122
+ static void blur(unsigned char im[70*200]) {
123
+ unsigned char *i=im;
124
+ int x,y;
125
+ for(y=0;y<68;y++) {
126
+ for(x=0;x<198;x++) {
127
+ unsigned int c11=*i,c12=i[1],c21=i[200],c22=i[201];
128
+ *i++=((c11+c12+c21+c22)/4);
129
+ }
130
+ }
131
+ }
132
+
133
+ static void filter(unsigned char im[70*200]) {
134
+ unsigned char om[70*200];
135
+ unsigned char *i=im;
136
+ unsigned char *o=om;
137
+
138
+ memset(om,0xff,sizeof(om));
139
+
140
+ int x,y;
141
+ for(y=0;y<70;y++) {
142
+ for(x=4;x<200-4;x++) {
143
+ if(i[0]>0xf0 && i[1]<0xf0) { o[0]=0; o[1]=0; }
144
+ else if(i[0]<0xf0 && i[1]>0xf0) { o[0]=0; o[1]=0; }
145
+
146
+ i++;
147
+ o++;
148
+ }
149
+ }
150
+
151
+ memmove(im,om,sizeof(om));
152
+ }
153
+
154
+ static const char *letters="abcdafahijklmnopqrstuvwxyz";
155
+
156
+ void captcha(unsigned char im[70*200], unsigned char l[8], int length, int i_line, int i_filter) {
157
+ unsigned char swr[200];
158
+ uint8_t s1,s2;
159
+
160
+ int f=open("/dev/urandom",O_RDONLY);
161
+ read(f,l,5); read(f,swr,200); read(f,dr,sizeof(dr)); read(f,&s1,1); read(f,&s2,1);
162
+ close(f);
163
+ memset(im,0xff,200*70); s1=s1&0x7f; s2=s2&0x3f;
164
+
165
+ int x;
166
+ for(x=0;x<length;x++){
167
+ l[x]%=25;
168
+ }
169
+ for(x=length;x<8;x++){
170
+ l[length]=0;
171
+ }
172
+ //l[0]%=25; l[1]%=25; l[2]%=25; l[3]%=25; l[4]=0; // l[4]%=25; l[5]=0;
173
+ int p=30;
174
+ for(x=0;x<length;x++){
175
+ p=letter(l[x],p,im,swr,s1,s2);
176
+ }
177
+
178
+ if (i_line == 1) {
179
+ line(im,swr,s1);
180
+ }
181
+ // dots(im);
182
+ if (i_filter == 1) {
183
+ blur(im);
184
+ filter(im);
185
+ }
186
+
187
+ for(x=0;x<length;x++){
188
+ l[x]=letters[l[x]];
189
+ }
190
+ //l[1]=letters[l[1]]; l[2]=letters[l[2]]; l[3]=letters[l[3]]; //l[4]=letters[l[4]];
191
+ }
192
+
193
+ // #ifdef CAPTCHA
194
+ //
195
+ // int main() {
196
+ // char l[6];
197
+ // unsigned char im[70*200];
198
+ // unsigned char gif[gifsize];
199
+ //
200
+ // captcha(im,l);
201
+ // makegif(im,gif);
202
+ //
203
+ // write(1,gif,gifsize);
204
+ // write(2,l,5);
205
+ //
206
+ // return 0;
207
+ // }
208
+ //
209
+ // #endif
210
+
211
+ VALUE RuCaptcha = Qnil;
212
+
213
+ void Init_rucaptcha();
214
+
215
+ VALUE create(VALUE self, VALUE style, VALUE length, VALUE line, VALUE filter);
216
+
217
+ void Init_rucaptcha() {
218
+ RuCaptcha = rb_define_module("RuCaptcha");
219
+ rb_define_singleton_method(RuCaptcha, "create", create, 4);
220
+ }
221
+
222
+ VALUE create(VALUE self, VALUE style, VALUE length, VALUE line, VALUE filter) {
223
+ char l[8];
224
+ unsigned char im[80*200];
225
+ unsigned char gif[gifsize];
226
+ int i_style = FIX2INT(style);
227
+ int i_length = FIX2INT(length);
228
+ int i_line = FIX2INT(line);
229
+ int i_filter = FIX2INT(filter);
230
+
231
+ captcha(im, l, i_length, i_line, i_filter);
232
+ makegif(im, gif, i_style);
233
+
234
+ VALUE result = rb_ary_new2(2);
235
+ rb_ary_push(result, rb_str_new2(l));
236
+ rb_ary_push(result, rb_str_new(gif, gifsize));
237
+
238
+ return result;
239
+ }
240
+
@@ -0,0 +1,80 @@
1
+ require 'rails'
2
+ require 'action_controller'
3
+ require 'active_support/all'
4
+ require 'blogs_captcha/blogs_captcha'
5
+ require 'blogs_captcha/version'
6
+ require 'blogs_captcha/configuration'
7
+ require 'blogs_captcha/controller_helpers'
8
+ require 'blogs_captcha/view_helpers'
9
+ require 'blogs_captcha/cache'
10
+ require 'blogs_captcha/engine'
11
+ require 'blogs_captcha/errors/configuration'
12
+
13
+ module BlogsCaptcha
14
+ class << self
15
+ def config
16
+ return @config if defined?(@config)
17
+ @config = Configuration.new
18
+ @config.style = :colorful
19
+ @config.length = 5
20
+ @config.strikethrough = true
21
+ @config.outline = false
22
+ @config.expires_in = 2.minutes
23
+ @config.skip_cache_store_check = false
24
+
25
+ if Rails.application
26
+ @config.cache_store = Rails.application.config.cache_store
27
+ else
28
+ @config.cache_store = :mem_cache_store
29
+ end
30
+ @config.cache_store
31
+ @config
32
+ end
33
+
34
+ def configure(&block)
35
+ config.instance_exec(&block)
36
+ end
37
+
38
+ def generate()
39
+ style = config.style == :colorful ? 1 : 0
40
+ length = config.length
41
+
42
+ unless length.in?(3..7)
43
+ raise BlogsCaptcha::Errors::Configuration, 'length config error, value must in 3..7'
44
+ end
45
+
46
+ strikethrough = config.strikethrough ? 1 : 0
47
+ outline = config.outline ? 1 : 0
48
+ self.create(style, length, strikethrough, outline)
49
+ end
50
+
51
+ def check_cache_store!
52
+ cache_store = BlogsCaptcha.config.cache_store
53
+ store_name = cache_store.is_a?(Array) ? cache_store.first : cache_store
54
+ if [:memory_store, :null_store, :file_store].include?(store_name)
55
+ BlogsCaptcha.config.cache_store = [:file_store, Rails.root.join('tmp/cache/rucaptcha/session')]
56
+
57
+ puts "
58
+
59
+ RuCaptcha's cache_store requirements are stored across processes and machines,
60
+ such as :mem_cache_store, :redis_store, or other distributed storage.
61
+ But your current set is #{cache_store}, it has changed to :file_store for working.
62
+ NOTE: :file_store is still not a good way, it only works with single server case.
63
+
64
+ Please make config file `config/initializers/rucaptcha.rb` to setup `cache_store`.
65
+ More infomation please read GitHub RuCaptcha README file.
66
+ https://github.com/huacnlee/rucaptcha
67
+
68
+ "
69
+ end
70
+ end
71
+ end
72
+ end
73
+
74
+ ActiveSupport.on_load(:action_controller) do
75
+ ActionController::Base.send :include, BlogsCaptcha::ControllerHelpers
76
+ end
77
+
78
+ ActiveSupport.on_load(:action_view) do
79
+ include BlogsCaptcha::ViewHelpers
80
+ end
@@ -0,0 +1,11 @@
1
+ require 'fileutils'
2
+
3
+ module BlogsCaptcha
4
+ class << self
5
+ def cache
6
+ return @cache if defined? @cache
7
+ @cache = ActiveSupport::Cache.lookup_store(BlogsCaptcha.config.cache_store)
8
+ @cache
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,19 @@
1
+ module BlogsCaptcha
2
+ class Configuration
3
+ # Store Captcha code where, this config more like Rails config.cache_store
4
+ # default: Rails application config.cache_store
5
+ attr_accessor :cache_store
6
+ # rucaptcha expire time, default 2 minutes
7
+ attr_accessor :expires_in
8
+ # Color style, default: :colorful, allows: [:colorful, :black_white]
9
+ attr_accessor :style
10
+ # Chars length: default 5, allows: [3..7]
11
+ attr_accessor :length
12
+ # strikethrough, default: true
13
+ attr_accessor :strikethrough
14
+ # outline style for hard mode, default: false
15
+ attr_accessor :outline
16
+ # skip_cache_store_check, default: false
17
+ attr_accessor :skip_cache_store_check
18
+ end
19
+ end
@@ -0,0 +1,88 @@
1
+ module BlogsCaptcha
2
+ module ControllerHelpers
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ helper_method :verify_rucaptcha?
7
+ end
8
+
9
+ # session key of rucaptcha
10
+ def rucaptcha_sesion_key_key
11
+ session_id = session.respond_to?(:id) ? session.id : session[:session_id]
12
+ warning_when_session_invalid if session_id.blank?
13
+ ['rucaptcha-session', session_id].join(':')
14
+ end
15
+
16
+ # Generate a new Captcha
17
+ def generate_rucaptcha
18
+ res = BlogsCaptcha.generate()
19
+ session_val = {
20
+ code: res[0],
21
+ time: Time.now.to_i
22
+ }
23
+ RuCaptcha.cache.write(rucaptcha_sesion_key_key, session_val, expires_in: RuCaptcha.config.expires_in)
24
+ res[1]
25
+ end
26
+
27
+ # Verify captcha code
28
+ #
29
+ # params:
30
+ # resource - [optional] a ActiveModel object, if given will add validation error message to object.
31
+ # :keep_session - if true, RuCaptcha will not delete the captcha code session.
32
+ # :captcha - if given, the value of it will be used to verify the captcha,
33
+ # if do not give or blank, the value of params[:_rucaptcha] will be used to verify the captcha
34
+ #
35
+ # exmaples:
36
+ #
37
+ # verify_rucaptcha?
38
+ # verify_rucaptcha?(user, keep_session: true)
39
+ # verify_rucaptcha?(nil, keep_session: true)
40
+ # verify_rucaptcha?(nil, captcha: params[:user][:captcha])
41
+ #
42
+ def verify_rucaptcha?(resource = nil, opts = {})
43
+ opts ||= {}
44
+
45
+ store_info = BlogsCaptcha.cache.read(rucaptcha_sesion_key_key)
46
+ # make sure move used key
47
+ BlogsCaptcha.cache.delete(rucaptcha_sesion_key_key) unless opts[:keep_session]
48
+
49
+ # Make sure session exist
50
+ if store_info.blank?
51
+ return add_rucaptcha_validation_error
52
+ end
53
+
54
+ # Make sure not expire
55
+ if (Time.now.to_i - store_info[:time]) > BlogsCaptcha.config.expires_in
56
+ return add_rucaptcha_validation_error
57
+ end
58
+
59
+ # Make sure parama have captcha
60
+ captcha = (opts[:captcha] || params[:_rucaptcha] || '').downcase.strip
61
+ if captcha.blank?
62
+ return add_rucaptcha_validation_error
63
+ end
64
+
65
+ if captcha != store_info[:code]
66
+ return add_rucaptcha_validation_error
67
+ end
68
+
69
+ true
70
+ end
71
+
72
+ private
73
+
74
+ def add_rucaptcha_validation_error
75
+ if defined?(resource) && resource && resource.respond_to?(:errors)
76
+ resource.errors.add(:base, t('rucaptcha.invalid'))
77
+ end
78
+ false
79
+ end
80
+
81
+ def warning_when_session_invalid
82
+ Rails.logger.warn "
83
+ WARNING! The session.id is blank, RuCaptcha can't work properly, please keep session available.
84
+ More details about this: https://github.com/huacnlee/rucaptcha/pull/66
85
+ "
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,15 @@
1
+ module BlogsCaptcha
2
+ class Engine < ::Rails::Engine
3
+ isolate_namespace BlogsCaptcha
4
+
5
+ initializer 'rucaptcha.init' do |app|
6
+ # https://github.com/rails/rails/blob/3-2-stable/actionpack/lib/action_dispatch/routing/route_set.rb#L268
7
+ # `app.routes.prepend` start from Rails 3.2 - 5.0
8
+ app.routes.prepend do
9
+ mount BlogsCaptcha::Engine => '/rucaptcha'
10
+ end
11
+
12
+ BlogsCaptcha.check_cache_store! unless BlogsCaptcha.config.skip_cache_store_check
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,5 @@
1
+ module Rucaptcha
2
+ module Errors
3
+ class Configuration < StandardError; end
4
+ end
5
+ end
@@ -0,0 +1,3 @@
1
+ module BlogsCaptcha
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,19 @@
1
+ module BlogsCaptcha
2
+ module ViewHelpers
3
+ def rucaptcha_input_tag(opts = {})
4
+ opts[:name] = '_rucaptcha'
5
+ opts[:type] = 'text'
6
+ opts[:autocorrect] = 'off'
7
+ opts[:autocapitalize] = 'off'
8
+ opts[:pattern] = '[a-zA-Z]*'
9
+ opts[:autocomplete] = 'off'
10
+ opts[:maxlength] ||= 5
11
+ tag(:input, opts)
12
+ end
13
+
14
+ def rucaptcha_image_tag(opts = {})
15
+ opts[:class] = opts[:class] || 'rucaptcha-image'
16
+ image_tag(ru_captcha.root_path, opts)
17
+ end
18
+ end
19
+ end
metadata ADDED
@@ -0,0 +1,93 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: blogs_captcha
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Jason Lee
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-03-07 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: railties
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '3.2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '3.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake-compiler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1'
41
+ description:
42
+ email: huacnlee@gmail.com
43
+ executables: []
44
+ extensions:
45
+ - ext/blogs_captcha/extconf.rb
46
+ extra_rdoc_files: []
47
+ files:
48
+ - CHANGELOG.md
49
+ - README.md
50
+ - app/controllers/blogs_captcha/captcha_controller.rb
51
+ - config/locales/rucaptcha.en.yml
52
+ - config/locales/rucaptcha.pt-BR.yml
53
+ - config/locales/rucaptcha.zh-CN.yml
54
+ - config/locales/rucaptcha.zh-TW.yml
55
+ - config/routes.rb
56
+ - ext/blogs_captcha/colors.h
57
+ - ext/blogs_captcha/extconf.rb
58
+ - ext/blogs_captcha/font.h
59
+ - ext/blogs_captcha/rucaptcha.c
60
+ - lib/blogs_captcha.rb
61
+ - lib/blogs_captcha/cache.rb
62
+ - lib/blogs_captcha/configuration.rb
63
+ - lib/blogs_captcha/controller_helpers.rb
64
+ - lib/blogs_captcha/engine.rb
65
+ - lib/blogs_captcha/errors/configuration.rb
66
+ - lib/blogs_captcha/version.rb
67
+ - lib/blogs_captcha/view_helpers.rb
68
+ homepage: https://github.com/huacnlee/rucaptcha
69
+ licenses:
70
+ - MIT
71
+ metadata: {}
72
+ post_install_message:
73
+ rdoc_options: []
74
+ require_paths:
75
+ - lib
76
+ required_ruby_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: 2.0.0
81
+ required_rubygems_version: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ requirements: []
87
+ rubyforge_project:
88
+ rubygems_version: 2.7.8
89
+ signing_key:
90
+ specification_version: 4
91
+ summary: This is a Captcha gem for Rails Applications. It drawing captcha image with
92
+ C code so it no dependencies.
93
+ test_files: []