rock_fintech 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +55 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +63 -0
- data/LICENSE.txt +21 -0
- data/README.md +43 -0
- data/Rakefile +12 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/rock_fintech/api/account/account_balance.rb +40 -0
- data/lib/rock_fintech/api/account/find_account_by_id.rb +42 -0
- data/lib/rock_fintech/api/account/find_account_by_mobile.rb +41 -0
- data/lib/rock_fintech/api/account/unbind_bank_card.rb +46 -0
- data/lib/rock_fintech/api/api_helper.rb +53 -0
- data/lib/rock_fintech/api/asset/.gitkeep +0 -0
- data/lib/rock_fintech/api/asset/asset_query.rb +48 -0
- data/lib/rock_fintech/api/asset/assets_enroll.rb +62 -0
- data/lib/rock_fintech/api/asset/assets_revoke.rb +48 -0
- data/lib/rock_fintech/api/batch/.gitkeep +0 -0
- data/lib/rock_fintech/api/batch/batch_end_credit_b.rb +59 -0
- data/lib/rock_fintech/api/batch/batch_payment_b.rb +76 -0
- data/lib/rock_fintech/api/batch/batch_repayment_b.rb +78 -0
- data/lib/rock_fintech/api/enterprise/.gitkeep +0 -0
- data/lib/rock_fintech/api/money/bank_recharge.rb +50 -0
- data/lib/rock_fintech/api/money/coupon_recharge.rb +40 -0
- data/lib/rock_fintech/api/money/coupon_withdraw.rb +40 -0
- data/lib/rock_fintech/api/platform/.gitkeep +0 -0
- data/lib/rock_fintech/api/query/.gitkeep +0 -0
- data/lib/rock_fintech/api/trade/.gitkeep +0 -0
- data/lib/rock_fintech/api/trade/auto_bid_apply.rb +61 -0
- data/lib/rock_fintech/api/trade/revoke_auto_bid.rb +44 -0
- data/lib/rock_fintech/client.rb +45 -0
- data/lib/rock_fintech/encrypt/rsa.rb +29 -0
- data/lib/rock_fintech/extensions.rb +7 -0
- data/lib/rock_fintech/form/account/bind_bank_card_p.rb +43 -0
- data/lib/rock_fintech/form/account/create_account_p.rb +52 -0
- data/lib/rock_fintech/form/account/set_password_p.rb +52 -0
- data/lib/rock_fintech/form/asset/.gitkeep +0 -0
- data/lib/rock_fintech/form/batch/.gitkeep +0 -0
- data/lib/rock_fintech/form/enterprise/.gitkeep +0 -0
- data/lib/rock_fintech/form/money/recharge_p.rb +59 -0
- data/lib/rock_fintech/form/money/sign_borrower_p.rb +48 -0
- data/lib/rock_fintech/form/money/sign_transfer_p.rb +44 -0
- data/lib/rock_fintech/form/money/withdraw_p.rb +58 -0
- data/lib/rock_fintech/form/platform/.gitkeep +0 -0
- data/lib/rock_fintech/form/query/.gitkeep +0 -0
- data/lib/rock_fintech/form/trade/.gitkeep +0 -0
- data/lib/rock_fintech/form/trade/bid_apply_p.rb +58 -0
- data/lib/rock_fintech/form/trade/sign_auto_bid_p.rb +46 -0
- data/lib/rock_fintech/http/error_code/account.rb +34 -0
- data/lib/rock_fintech/http/error_code/asset.rb +20 -0
- data/lib/rock_fintech/http/error_code/batch.rb +20 -0
- data/lib/rock_fintech/http/error_code/money.rb +37 -0
- data/lib/rock_fintech/http/error_code/trade.rb +23 -0
- data/lib/rock_fintech/http/request.rb +103 -0
- data/lib/rock_fintech/http/response.rb +54 -0
- data/lib/rock_fintech/railtie.rb +7 -0
- data/lib/rock_fintech/sign/md5.rb +18 -0
- data/lib/rock_fintech/utils.rb +75 -0
- data/lib/rock_fintech/version.rb +3 -0
- data/lib/rock_fintech.rb +51 -0
- data/rock_fintech.gemspec +41 -0
- metadata +223 -0
File without changes
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
module RockFintech
|
3
|
+
module Api
|
4
|
+
module Money
|
5
|
+
module BankRecharge
|
6
|
+
# 网关充值
|
7
|
+
#
|
8
|
+
# @return [ Hash ] 结果集
|
9
|
+
# * :result [String] "S"/"F"/"P"
|
10
|
+
# * :request_params [Hash] 请求参数
|
11
|
+
# * :response [Object] 请求返回对象
|
12
|
+
# * :code [String] 结果代码
|
13
|
+
# * :msg [String] 结果信息
|
14
|
+
# * :data: 具体业务返回信息
|
15
|
+
# * :url [String] 支付 url
|
16
|
+
# * :order_no [String] 订单号
|
17
|
+
# * :amount [Number] 金额
|
18
|
+
#
|
19
|
+
def bank_recharge(card_no, bank_type, callback_url, customer_no, redirect_url,
|
20
|
+
product_name, product_detail, order_no, bank_name, bank_id_no, amount,
|
21
|
+
devise='000001', remark='')
|
22
|
+
service = 'bank_recharge'
|
23
|
+
|
24
|
+
params = {
|
25
|
+
card_no: card_no,
|
26
|
+
bank_type: bank_type,
|
27
|
+
callback_url: callback_url,
|
28
|
+
customer_no: customer_no,
|
29
|
+
redirect_url: redirect_url,
|
30
|
+
product_name: product_name,
|
31
|
+
product_detail: product_detail,
|
32
|
+
order_no: order_no,
|
33
|
+
bank_name: bank_name,
|
34
|
+
bank_id_no: bank_id_no,
|
35
|
+
amount: amount,
|
36
|
+
client: devise,
|
37
|
+
custom: remark,
|
38
|
+
}
|
39
|
+
|
40
|
+
res = operate_post(:operate, service, params, Http::ErrorCode.bank_recharge, ['RD000000'])
|
41
|
+
|
42
|
+
RockFintech.logger.info res
|
43
|
+
|
44
|
+
res
|
45
|
+
end
|
46
|
+
|
47
|
+
end # module
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
module RockFintech
|
3
|
+
module Api
|
4
|
+
module Money
|
5
|
+
module CouponRecharge
|
6
|
+
# 营销账户充值
|
7
|
+
#
|
8
|
+
# @return [ Hash ] 结果集
|
9
|
+
# * :result [String] "S"/"F"/"P"
|
10
|
+
# * :request_params [Hash] 请求参数
|
11
|
+
# * :response [Object] 请求返回对象
|
12
|
+
# * :code [String] 结果代码
|
13
|
+
# * :msg [String] 结果信息
|
14
|
+
# * :data: 具体业务返回信息
|
15
|
+
# * :serial_no [String] 交易流水号
|
16
|
+
# * :order_no [String] 订单号
|
17
|
+
# * :amount [Number] 金额
|
18
|
+
# * :balance [Number] 操作后账户余额
|
19
|
+
#
|
20
|
+
def coupon_recharge(amount, serial_no, devise='000001', remark='')
|
21
|
+
service = 'coupon_recharge'
|
22
|
+
|
23
|
+
params = {
|
24
|
+
amount: amount,
|
25
|
+
serial_no: serial_no,
|
26
|
+
client: devise,
|
27
|
+
custom: remark,
|
28
|
+
}
|
29
|
+
|
30
|
+
res = operate_post(:operate, service, params, Http::ErrorCode.coupon_recharge, ['RD000000'])
|
31
|
+
|
32
|
+
RockFintech.logger.info res
|
33
|
+
|
34
|
+
res
|
35
|
+
end
|
36
|
+
|
37
|
+
end # module
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
module RockFintech
|
3
|
+
module Api
|
4
|
+
module Money
|
5
|
+
module CouponWithdraw
|
6
|
+
# 营销账户提现
|
7
|
+
#
|
8
|
+
# @return [ Hash ] 结果集
|
9
|
+
# * :result [String] "S"/"F"/"P"
|
10
|
+
# * :request_params [Hash] 请求参数
|
11
|
+
# * :response [Object] 请求返回对象
|
12
|
+
# * :code [String] 结果代码
|
13
|
+
# * :msg [String] 结果信息
|
14
|
+
# * :data: 具体业务返回信息
|
15
|
+
# * :serial_no [String] 交易流水号
|
16
|
+
# * :order_no [String] 订单号
|
17
|
+
# * :amount [Number] 金额
|
18
|
+
# * :balance [Number] 操作后账户余额
|
19
|
+
#
|
20
|
+
def coupon_withdraw(amount, serial_no, devise='000001', remark='')
|
21
|
+
service = 'coupon_withdraw'
|
22
|
+
|
23
|
+
params = {
|
24
|
+
amount: amount,
|
25
|
+
serial_no: serial_no,
|
26
|
+
client: devise,
|
27
|
+
custom: remark,
|
28
|
+
}
|
29
|
+
|
30
|
+
res = operate_post(:operate, service, params, Http::ErrorCode.coupon_withdraw, ['RD000000'])
|
31
|
+
|
32
|
+
RockFintech.logger.info res
|
33
|
+
|
34
|
+
res
|
35
|
+
end
|
36
|
+
|
37
|
+
end # module
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
module RockFintech
|
3
|
+
module Api
|
4
|
+
module Trade
|
5
|
+
module AutoBidApply
|
6
|
+
|
7
|
+
# 一键投标
|
8
|
+
#
|
9
|
+
# @return [ Hash ] 结果集
|
10
|
+
# * :result [String] "S"/"F"/"P"
|
11
|
+
# * :request_params [Hash] 请求参数
|
12
|
+
# * :response [Object] 请求返回对象
|
13
|
+
# * :code [String] 结果代码
|
14
|
+
# * :msg [String] 结果信息
|
15
|
+
# * :data: 具体业务返回信息
|
16
|
+
# * :out_serial_no [String] 申请流水号
|
17
|
+
# * :card_no [String] 电子账号
|
18
|
+
# * :name [String] 姓名
|
19
|
+
# * :bid_amount [String] 投标金额
|
20
|
+
# * :forcast_income [String] 预期收益
|
21
|
+
# * :buy_date [String] 投标日期
|
22
|
+
# * :state [String] 记录状态 (1: 投标中, 2: 计息中, 3: 到期待返还, 4: 本息已返还)
|
23
|
+
# * :auth_code [String] 投标申请授权码
|
24
|
+
#
|
25
|
+
def auto_bid_apply(card_no, out_serial_no, amount,
|
26
|
+
use_bonus, bonus_amount, auth_code,
|
27
|
+
asset_no, interest_date, interest_type,
|
28
|
+
interest_day, end_date, interest_rate,
|
29
|
+
frozen_flag, frozen_no="",
|
30
|
+
devise='000001', remark='')
|
31
|
+
|
32
|
+
service = 'auto_bid_apply'
|
33
|
+
|
34
|
+
params = {
|
35
|
+
card_no: card_no,
|
36
|
+
out_serial_no: out_serial_no,
|
37
|
+
amount: amount,
|
38
|
+
use_bonus: use_bonus,
|
39
|
+
bonus_amount: bonus_amount,
|
40
|
+
auth_code: auth_code,
|
41
|
+
asset_no: asset_no,
|
42
|
+
interest_date: interest_date,
|
43
|
+
interest_type: interest_type,
|
44
|
+
interest_day: interest_day,
|
45
|
+
end_date: end_date,
|
46
|
+
interest_rate: interest_rate,
|
47
|
+
frozen_flag: frozen_flag,
|
48
|
+
frozen_no: frozen_no,
|
49
|
+
client: devise,
|
50
|
+
custom: remark,
|
51
|
+
}
|
52
|
+
|
53
|
+
res = operate_post(:operate, service, params, Http::ErrorCode.auto_bid_apply, ['RD000000'])
|
54
|
+
|
55
|
+
res
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
module RockFintech
|
3
|
+
module Api
|
4
|
+
module Trade
|
5
|
+
module RevokeAutoBid
|
6
|
+
|
7
|
+
# 撤销自动投标签约
|
8
|
+
#
|
9
|
+
# @return [ Hash ] 结果集
|
10
|
+
# * :result [String] "S"/"F"/"P"
|
11
|
+
# * :request_params [Hash] 请求参数
|
12
|
+
# * :response [Object] 请求返回对象
|
13
|
+
# * :code [String] 结果代码
|
14
|
+
# * :msg [String] 结果信息
|
15
|
+
# * :data: 具体业务返回信息
|
16
|
+
# * :out_serial_no [String] 申请流水号
|
17
|
+
# * :card_no [String] 电子账号
|
18
|
+
# * :name [String] 持卡人姓名
|
19
|
+
# * :sign_flag [String] 签约状态 "having(已签约), revoking(已撤销)"
|
20
|
+
# * :sign_date [String] 签约日期
|
21
|
+
# * :sign_time [String] 签约时间
|
22
|
+
#
|
23
|
+
def revoke_auto_bid(card_no, out_serial_no, origin_serial_no="",
|
24
|
+
devise='000001', remark='')
|
25
|
+
|
26
|
+
service = 'revoke_auto_bid'
|
27
|
+
|
28
|
+
params = {
|
29
|
+
card_no: card_no,
|
30
|
+
out_serial_no: out_serial_no,
|
31
|
+
origin_serial_no: origin_serial_no,
|
32
|
+
client: devise,
|
33
|
+
custom: remark,
|
34
|
+
}
|
35
|
+
|
36
|
+
res = operate_post(:operate, service, params, Http::ErrorCode.revoke_auto_bid, ['RD000000'])
|
37
|
+
|
38
|
+
res
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
# 客户端
|
3
|
+
|
4
|
+
module RockFintech
|
5
|
+
class Client
|
6
|
+
|
7
|
+
attr_accessor :config
|
8
|
+
|
9
|
+
def initialize(options_arg)
|
10
|
+
options = Utils.symbolize_keys(options_arg)
|
11
|
+
@config = {
|
12
|
+
uri: options[:url],
|
13
|
+
rft_token: options[:rft_token],
|
14
|
+
rft_org: options[:rft_org],
|
15
|
+
rft_key: options[:rft_key],
|
16
|
+
rft_secret: options[:rft_secret],
|
17
|
+
private_key: OpenSSL::PKey::RSA.new(options[:private_key]),
|
18
|
+
public_key: OpenSSL::PKey::RSA.new(options[:public_key]),
|
19
|
+
}
|
20
|
+
|
21
|
+
# 自动 include api 下的模块
|
22
|
+
recursive_include_api('RockFintech::Api')
|
23
|
+
|
24
|
+
# 自动 include form 下的模块
|
25
|
+
recursive_include_api('RockFintech::Form')
|
26
|
+
end
|
27
|
+
|
28
|
+
def decode_notify_data(encryptkey, data)
|
29
|
+
# ::RockFintech::Http::Decode.decode_notify_data(encryptkey, data, @config)
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def recursive_include_api(module_chain)
|
35
|
+
modules = eval("#{module_chain}.constants").each{ |constant| eval("#{module_chain}::#{constant}").class.kind_of?(Module) }
|
36
|
+
|
37
|
+
if modules.empty?
|
38
|
+
self.class.send(:include, eval(module_chain))
|
39
|
+
else
|
40
|
+
modules.each{ |constant| recursive_include_api("#{module_chain}::#{constant}") }
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
module RockFintech
|
3
|
+
module Encrypt
|
4
|
+
module RSA
|
5
|
+
|
6
|
+
def self.encrypt(content, public_key)
|
7
|
+
content_str = ''
|
8
|
+
content.scan(/.{1,100}/).each{ |str|
|
9
|
+
content_str += public_key.public_encrypt(str)
|
10
|
+
}
|
11
|
+
Base64.strict_encode64(content_str)
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.decrypt(content, private_key)
|
15
|
+
content_str = Base64.strict_decode64(content)
|
16
|
+
|
17
|
+
result_str = ''
|
18
|
+
count = content_str.length / 256
|
19
|
+
count.times.each{ |i|
|
20
|
+
str = content_str[256*i, 256]
|
21
|
+
result_str += private_key.private_decrypt(str)
|
22
|
+
}
|
23
|
+
|
24
|
+
result_str
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
module RockFintech
|
3
|
+
module Form
|
4
|
+
module Account
|
5
|
+
module BindBankCardP
|
6
|
+
# 绑卡网关接口
|
7
|
+
#
|
8
|
+
# @return [ Hash ] 结果集
|
9
|
+
# * :result [String] "S"/"F"/"P"
|
10
|
+
# * :request_params [Hash] 请求参数
|
11
|
+
# * :response [Object] 请求返回对象
|
12
|
+
# * :code [String] 结果代码
|
13
|
+
# * :msg [String] 结果信息
|
14
|
+
# * :data: 具体业务返回信息
|
15
|
+
# * :out_serial_no [String] 申请流水号
|
16
|
+
# * :order_id [String] 订单号
|
17
|
+
# * :url [String] 页面跳转 url
|
18
|
+
#
|
19
|
+
def bind_bank_card_p(card_type, flow_id,
|
20
|
+
success_url, fail_url, callback_url,
|
21
|
+
card_no, devise='000001', remark='')
|
22
|
+
service = 'bind_bank_card_p'
|
23
|
+
|
24
|
+
params = {
|
25
|
+
card_type: card_type,
|
26
|
+
out_serial_no: flow_id,
|
27
|
+
success_url: success_url,
|
28
|
+
fail_url: fail_url,
|
29
|
+
callback_url: callback_url,
|
30
|
+
card_no: card_no,
|
31
|
+
client: devise,
|
32
|
+
custom: remark,
|
33
|
+
}
|
34
|
+
|
35
|
+
res = operate_post(:operate, service, params, Http::ErrorCode.bind_bank_card_p, ['RD000000'])
|
36
|
+
|
37
|
+
res
|
38
|
+
end
|
39
|
+
|
40
|
+
end # module
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
module RockFintech
|
3
|
+
module Form
|
4
|
+
module Account
|
5
|
+
module CreateAccountP
|
6
|
+
# 开户
|
7
|
+
#
|
8
|
+
# @param flow_id [ String ] 申请流水号
|
9
|
+
# @param account_type [ String ] 账户类型 普通户200201,企业户200204
|
10
|
+
# @param role_type [ String ] 用户角色 1:出借角色,2:借款角色,3:代偿角色
|
11
|
+
# @param success_url [ String ] 成功 url
|
12
|
+
# @param fail_url [ String ] 失败 url
|
13
|
+
# @param callback_url [String] 回调 url
|
14
|
+
# @param devise [ String ] 交易终端,默认手机 000001手机APP 000002网页 000003微信 000004柜面
|
15
|
+
# @param remark [ String ] 备注,默认为空
|
16
|
+
#
|
17
|
+
# @return [ Hash ] 结果集
|
18
|
+
# * :result [String] "S"/"F"/"P"
|
19
|
+
# * :request_params [Hash] 请求参数
|
20
|
+
# * :response [Object] 请求返回对象
|
21
|
+
# * :code [String] 结果代码
|
22
|
+
# * :msg [String] 结果信息
|
23
|
+
# * :data: 具体业务返回信息
|
24
|
+
# * :out_serial_no [String] 申请流水号
|
25
|
+
# * :order_id [String] 订单号
|
26
|
+
# * :url [String] 页面跳转 url
|
27
|
+
#
|
28
|
+
def create_account_p(flow_id, account_type, role_type,
|
29
|
+
success_url, fail_url, callback_url,
|
30
|
+
devise='000001', remark='')
|
31
|
+
service = 'create_account_p'
|
32
|
+
|
33
|
+
params = {
|
34
|
+
out_serial_no: flow_id,
|
35
|
+
account_type: account_type,
|
36
|
+
role_type: role_type,
|
37
|
+
success_url: success_url,
|
38
|
+
fail_url: fail_url,
|
39
|
+
callback_url: callback_url,
|
40
|
+
client: devise,
|
41
|
+
custom: remark,
|
42
|
+
}
|
43
|
+
|
44
|
+
res = operate_post(:operate, service, params, Http::ErrorCode.create_account_p, ['RD000000'])
|
45
|
+
|
46
|
+
res
|
47
|
+
end
|
48
|
+
|
49
|
+
end # module
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
module RockFintech
|
3
|
+
module Form
|
4
|
+
module Account
|
5
|
+
module SetPasswordP
|
6
|
+
# 重置密码
|
7
|
+
#
|
8
|
+
# @param flow_id [ String ] 申请流水号
|
9
|
+
# @param customer_no [ String ] 客户号
|
10
|
+
# @param card_no [ String ] 电子账户
|
11
|
+
# @param success_url [ String ] 成功 url
|
12
|
+
# @param fail_url [ String ] 失败 url
|
13
|
+
# @param callback_url [String] 回调 url
|
14
|
+
# @param devise [ String ] 交易终端,默认手机 000001手机APP 000002网页 000003微信 000004柜面
|
15
|
+
# @param remark [ String ] 备注,默认为空
|
16
|
+
#
|
17
|
+
# @return [ Hash ] 结果集
|
18
|
+
# * :result [String] "S"/"F"/"P"
|
19
|
+
# * :request_params [Hash] 请求参数
|
20
|
+
# * :response [Object] 请求返回对象
|
21
|
+
# * :code [String] 结果代码
|
22
|
+
# * :msg [String] 结果信息
|
23
|
+
# * :data: 具体业务返回信息
|
24
|
+
# * :out_serial_no [String] 申请流水号
|
25
|
+
# * :order_id [String] 订单号
|
26
|
+
# * :url [String] 页面跳转 url
|
27
|
+
#
|
28
|
+
def set_password_p(flow_id, customer_no, card_no,
|
29
|
+
success_url, fail_url, callback_url,
|
30
|
+
devise='000001', remark='')
|
31
|
+
service = 'set_password_p'
|
32
|
+
|
33
|
+
params = {
|
34
|
+
out_serial_no: flow_id,
|
35
|
+
customer_no: customer_no,
|
36
|
+
card_no: card_no,
|
37
|
+
success_url: success_url,
|
38
|
+
fail_url: fail_url,
|
39
|
+
callback_url: callback_url,
|
40
|
+
client: devise,
|
41
|
+
custom: remark,
|
42
|
+
}
|
43
|
+
|
44
|
+
res = operate_post(:operate, service, params, Http::ErrorCode.set_password_p, ['RD000000'])
|
45
|
+
|
46
|
+
res
|
47
|
+
end
|
48
|
+
|
49
|
+
end # module
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|