activemerchant 1.11.0 → 1.12.0
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +3 -1
- data/CHANGELOG +17 -0
- data/CONTRIBUTORS +16 -0
- data/README.rdoc +5 -0
- data/lib/active_merchant.rb +0 -1
- data/lib/active_merchant/billing/gateway.rb +1 -1
- data/lib/active_merchant/billing/gateways/authorize_net.rb +5 -2
- data/lib/active_merchant/billing/gateways/federated_canada.rb +169 -0
- data/lib/active_merchant/billing/gateways/garanti.rb +13 -1
- data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +4 -4
- data/lib/active_merchant/billing/gateways/nmi.rb +13 -0
- data/lib/active_merchant/billing/gateways/pay_junction.rb +8 -8
- data/lib/active_merchant/billing/gateways/paybox_direct.rb +3 -4
- data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +2 -2
- data/lib/active_merchant/billing/gateways/paypal_express.rb +37 -5
- data/lib/active_merchant/billing/gateways/qbms.rb +290 -0
- data/lib/active_merchant/billing/integrations/direc_pay/helper.rb +25 -21
- data/lib/active_merchant/billing/integrations/moneybookers.rb +23 -0
- data/lib/active_merchant/billing/integrations/moneybookers/helper.rb +33 -0
- data/lib/active_merchant/billing/integrations/moneybookers/notification.rb +101 -0
- data/lib/active_merchant/billing/integrations/valitor/helper.rb +5 -1
- data/lib/active_merchant/billing/integrations/world_pay.rb +34 -0
- data/lib/active_merchant/billing/integrations/world_pay/helper.rb +100 -0
- data/lib/active_merchant/billing/integrations/world_pay/notification.rb +160 -0
- data/lib/active_merchant/version.rb +1 -1
- metadata +13 -4
- metadata.gz.sig +0 -0
data.tar.gz.sig
CHANGED
@@ -1 +1,3 @@
|
|
1
|
-
|
1
|
+
>:v��e̴�T�(&������@#R�ߗ8}����q7��9�2%�#* ����{8�"���
|
2
|
+
(����=y1++�c�rP������>�X��!cADd�1`F@v��w�!�m���pX�b�R�>F�X���jB���P
|
3
|
+
�1ϗ<U�CaT#_����艓�?oOY��a�X-/m��R1|��R���i��6�x�o�I\��@��2MD-�� ���٤c!��.��.��2��ӊYEU
|
data/CHANGELOG
CHANGED
@@ -1,5 +1,22 @@
|
|
1
1
|
= ActiveMerchant CHANGELOG
|
2
2
|
|
3
|
+
== Version 1.12.0 (Mar 1, 2011)
|
4
|
+
|
5
|
+
* DirecPay: Send phone number as mobile phone by default [Soleone]
|
6
|
+
* Support sending line items for PayPal Express transactions [Jonathan Rudenberg]
|
7
|
+
* Update PayPal Express XML format to latest version [Jonathan Rudenberg]
|
8
|
+
* Fix custom image header for PayPal Express [mwagg]
|
9
|
+
* Add InvoiceID and OrderDescription to PayPal Express Authorize and Capture [cody]
|
10
|
+
* Add Moneybookers integration [Alex Diakov]
|
11
|
+
* Add QBMS (Quickbooks Merchant Services) gateway [ntalbott]
|
12
|
+
* Add NMI gateway [ntalbott]
|
13
|
+
* Make fully compatible with Rails 2 & 3, and Ruby 1.8 & 1.9 [ntalbott]
|
14
|
+
* Authorize.Net: Only return AVS message for AVS-related reason codes. [ntalbott]
|
15
|
+
* Add Federated Canada gateway [ntalbott]
|
16
|
+
* Garanti: Fix text normalization for nil values [Selem Delul]
|
17
|
+
* Valitor: Always send amount without any decimal places [Soleone]
|
18
|
+
* Add WorldPay integration [Soleone]
|
19
|
+
|
3
20
|
== Version 1.11.0 (Feb 11, 2011)
|
4
21
|
|
5
22
|
* Bump dependency for activesupport from 2.3.2 to 2.3.8 [Soleone]
|
data/CONTRIBUTORS
CHANGED
@@ -199,3 +199,19 @@ Barclays ePDQ
|
|
199
199
|
|
200
200
|
* Original code by Rob W (rfwatson)
|
201
201
|
* Refactored by Nathaniel Talbott
|
202
|
+
|
203
|
+
Federated Canada
|
204
|
+
|
205
|
+
* Bob Larrick (deathbob)
|
206
|
+
|
207
|
+
NMI
|
208
|
+
|
209
|
+
* Nathaniel Talbott (ntalbott)
|
210
|
+
|
211
|
+
QBMS
|
212
|
+
|
213
|
+
* Will Glozer (wg)
|
214
|
+
WorldPay (Feb 17, 2011)
|
215
|
+
|
216
|
+
* Original code by Unknown from this patch: https://jadedpixel.lighthouseapp.com/projects/11599/tickets/3-patch-integration-support-for-worldpay-uk
|
217
|
+
* Refactored by Soleone
|
data/README.rdoc
CHANGED
@@ -25,6 +25,7 @@ The {ActiveMerchant Wiki}[http://github.com/Shopify/active_merchant/wikis] conta
|
|
25
25
|
* {ePay}[http://www.epay.dk/] - DK
|
26
26
|
* {eWAY}[http://www.eway.com.au/] - AU
|
27
27
|
* {E-xact}[http://www.e-xact.com] - CA, US
|
28
|
+
* {Federated Canada}[http://www.federatedcanada.com/] - CA
|
28
29
|
* {FirstPay}[http://www.first-pay.com] - US
|
29
30
|
* {Garanti Sanal POS}[https://ccpos.garanti.com.tr/ccRaporlar/garanti/ccReports] - US, TR
|
30
31
|
* {Inspire}[http://www.inspiregateway.com] - US
|
@@ -40,6 +41,7 @@ The {ActiveMerchant Wiki}[http://github.com/Shopify/active_merchant/wikis] conta
|
|
40
41
|
* {NetRegistry}[http://www.netregistry.com.au] - AU
|
41
42
|
* {NELiX TransaX Gateway}[http://www.nelixtransax.com] - US
|
42
43
|
* {NETbilling}[http://www.netbilling.com] - US
|
44
|
+
* {NMI}[http://nmi.com/] - US
|
43
45
|
* {Ogone DirectLink}[http://www.ogone.com] - BE, DE, FR, NL, AT, CH
|
44
46
|
* {PayBox Direct}[http://www.paybox.com] - FR
|
45
47
|
* {PayJunction}[http://www.payjunction.com/] - US
|
@@ -56,6 +58,7 @@ The {ActiveMerchant Wiki}[http://github.com/Shopify/active_merchant/wikis] conta
|
|
56
58
|
* {Psigate}[http://www.psigate.com/] - CA
|
57
59
|
* {PSL Payment Solutions}[http://www.paymentsolutionsltd.com/] - GB
|
58
60
|
* {Quantum}[http://www.quantumgateway.com] - US
|
61
|
+
* {QuickBooks Merchant Services}[http://payments.intuit.com/] - US
|
59
62
|
* {Quickpay}[http://quickpay.dk/] - DK
|
60
63
|
* {Rabobank Nederland}[http://www.rabobank.nl/] - NL
|
61
64
|
* {Realex}[http://www.realexpayments.com/] - IE, GB
|
@@ -80,10 +83,12 @@ The {ActiveMerchant Wiki}[http://github.com/Shopify/active_merchant/wikis] conta
|
|
80
83
|
* {Chronopay}[http://www.chronopay.com]
|
81
84
|
* {DirecPay}[http://www.timesofmoney.com/direcpay/jsp/home.jsp]
|
82
85
|
* {HiTRUST}[http://www.hitrust.com.hk/]
|
86
|
+
* {Moneybookers}[http://www.moneybookers.com]
|
83
87
|
* {Nochex}[http://www.nochex.com]
|
84
88
|
* {PayPal Website Payments Standard}[https://www.paypal.com/cgi-bin/webscr?cmd=_wp-standard-overview-outside]
|
85
89
|
* {SagePay Form}[http://www.sagepay.com/products_services/sage_pay_go/integration/form]
|
86
90
|
* {Valitor}[http://www.valitor.is/] - IS
|
91
|
+
* {WorldPay}[http://www.worldpay.com]
|
87
92
|
|
88
93
|
== Download
|
89
94
|
|
data/lib/active_merchant.rb
CHANGED
@@ -32,7 +32,6 @@ require 'active_support/core_ext/class/attribute_accessors'
|
|
32
32
|
require 'active_support/core_ext/class/delegating_attributes'
|
33
33
|
require 'active_support/core_ext/module/attribute_accessors'
|
34
34
|
require 'active_support/core_ext/kernel/requires'
|
35
|
-
require 'active_support/core_ext/module/deprecation'
|
36
35
|
require 'active_support/base64'
|
37
36
|
require 'active_support/secure_random'
|
38
37
|
|
@@ -48,6 +48,7 @@ module ActiveMerchant #:nodoc:
|
|
48
48
|
|
49
49
|
CARD_CODE_ERRORS = %w( N S )
|
50
50
|
AVS_ERRORS = %w( A E N R W Z )
|
51
|
+
AVS_REASON_CODES = %w(27 45)
|
51
52
|
|
52
53
|
AUTHORIZE_NET_ARB_NAMESPACE = 'AnetApi/xml/v1/schema/AnetApiSchema.xsd'
|
53
54
|
|
@@ -370,10 +371,12 @@ module ActiveMerchant #:nodoc:
|
|
370
371
|
def message_from(results)
|
371
372
|
if results[:response_code] == DECLINED
|
372
373
|
return CVVResult.messages[ results[:card_code] ] if CARD_CODE_ERRORS.include?(results[:card_code])
|
373
|
-
|
374
|
+
if AVS_REASON_CODES.include?(results[:response_reason_code]) && AVS_ERRORS.include?(results[:avs_result_code])
|
375
|
+
return AVSResult.messages[ results[:avs_result_code] ]
|
376
|
+
end
|
374
377
|
end
|
375
378
|
|
376
|
-
|
379
|
+
(results[:response_reason_text] ? results[:response_reason_text].chomp('.') : '')
|
377
380
|
end
|
378
381
|
|
379
382
|
def expdate(creditcard)
|
@@ -0,0 +1,169 @@
|
|
1
|
+
module ActiveMerchant #:nodoc:
|
2
|
+
module Billing #:nodoc:
|
3
|
+
class FederatedCanadaGateway < Gateway
|
4
|
+
# Same URL for both test and live, testing is done by using the test username (demo) and password (password).
|
5
|
+
URL = 'https://secure.federatedgateway.com/api/transact.php'
|
6
|
+
|
7
|
+
APPROVED, DECLINED, ERROR = 1, 2, 3
|
8
|
+
|
9
|
+
# The countries the gateway supports merchants from as 2 digit ISO country codes
|
10
|
+
self.supported_countries = ['CA']
|
11
|
+
|
12
|
+
self.default_currency = 'CAD'
|
13
|
+
|
14
|
+
# The card types supported by the payment gateway
|
15
|
+
self.supported_cardtypes = [:visa, :master, :american_express, :discover]
|
16
|
+
|
17
|
+
# The homepage URL of the gateway
|
18
|
+
self.homepage_url = 'http://www.federatedcanada.com/'
|
19
|
+
|
20
|
+
# The name of the gateway
|
21
|
+
self.display_name = 'Federated Canada'
|
22
|
+
|
23
|
+
def initialize(options = {})
|
24
|
+
requires!(options, :login, :password)
|
25
|
+
@options = options
|
26
|
+
super
|
27
|
+
end
|
28
|
+
|
29
|
+
def purchase(money, creditcard, options = {})
|
30
|
+
post = {}
|
31
|
+
add_invoice(post, options)
|
32
|
+
add_creditcard(post, creditcard)
|
33
|
+
add_address(post, options)
|
34
|
+
add_customer_data(post, options)
|
35
|
+
commit('sale', money, post)
|
36
|
+
end
|
37
|
+
|
38
|
+
def authorize(money, creditcard, options = {})
|
39
|
+
post = {}
|
40
|
+
add_invoice(post, options)
|
41
|
+
add_creditcard(post, creditcard)
|
42
|
+
add_address(post, options)
|
43
|
+
add_customer_data(post, options)
|
44
|
+
commit('auth', money, post)
|
45
|
+
end
|
46
|
+
|
47
|
+
def capture(money, authorization, options = {})
|
48
|
+
options[:transactionid] = authorization
|
49
|
+
commit('capture', money, options)
|
50
|
+
end
|
51
|
+
|
52
|
+
def credit(money, identification, options = {}) # also referred to as refund
|
53
|
+
post = { :transactionid => identification}
|
54
|
+
commit('refund', money, post)
|
55
|
+
end
|
56
|
+
|
57
|
+
def void(authorization, options = {})
|
58
|
+
options[:transactionid] = authorization
|
59
|
+
commit('void', nil, options)
|
60
|
+
end
|
61
|
+
|
62
|
+
def refund(money, authorization, options = {})
|
63
|
+
options[:transactionid] = authorization
|
64
|
+
commit('refund', money, options)
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
def add_customer_data(post, options)
|
70
|
+
post[:firstname] = options[:first_name]
|
71
|
+
post[:lastname] = options[:last_name]
|
72
|
+
|
73
|
+
post[:email] = options[:email]
|
74
|
+
end
|
75
|
+
|
76
|
+
def add_address(post, options)
|
77
|
+
if address = (options[:billing_address] || options[:address])
|
78
|
+
post[:company] = address[:company]
|
79
|
+
post[:address1] = address[:address1]
|
80
|
+
post[:address2] = address[:address2]
|
81
|
+
post[:city] = address[:city]
|
82
|
+
post[:state] = address[:state]
|
83
|
+
post[:zip] = address[:zip]
|
84
|
+
post[:country] = address[:country]
|
85
|
+
post[:phone] = address[:phone]
|
86
|
+
end
|
87
|
+
if address = options[:shipping_address]
|
88
|
+
post[:shipping_firstname] = address[:first_name]
|
89
|
+
post[:shipping_lastname] = address[:last_name]
|
90
|
+
post[:shipping_company] = address[:company]
|
91
|
+
post[:shipping_address1] = address[:address1]
|
92
|
+
post[:shipping_address2] = address[:address2]
|
93
|
+
post[:shipping_city] = address[:city]
|
94
|
+
post[:shipping_state] = address[:state]
|
95
|
+
post[:shipping_zip] = address[:zip]
|
96
|
+
post[:shipping_country] = address[:country]
|
97
|
+
post[:shipping_email] = address[:email]
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def add_invoice(post, options)
|
102
|
+
post[:orderid] = options[:order_id]
|
103
|
+
post[:orderdescription] = options[:description]
|
104
|
+
end
|
105
|
+
|
106
|
+
def add_creditcard(post, creditcard)
|
107
|
+
post[:ccnumber] = creditcard.number
|
108
|
+
post[:ccexp] = expdate(creditcard)
|
109
|
+
post[:cvv] = creditcard.verification_value
|
110
|
+
end
|
111
|
+
|
112
|
+
def expdate(creditcard)
|
113
|
+
year = sprintf("%.4i", creditcard.year)
|
114
|
+
month = sprintf("%.2i", creditcard.month)
|
115
|
+
"#{month}#{year[-2..-1]}"
|
116
|
+
end
|
117
|
+
|
118
|
+
def parse(body)
|
119
|
+
body.split('&').inject({}) do |memo, x|
|
120
|
+
k, v = x.split('=')
|
121
|
+
memo[k] = v
|
122
|
+
memo
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def commit(action, money, parameters)
|
127
|
+
parameters[:amount] = amount(money)
|
128
|
+
data = ssl_post(URL, post_data(action, parameters))
|
129
|
+
response = parse(data)
|
130
|
+
message = message_from(response)
|
131
|
+
test_mode = test?
|
132
|
+
|
133
|
+
Response.new(success?(response), message, response,
|
134
|
+
:test => test?,
|
135
|
+
:authorization => response['transactionid'],
|
136
|
+
:avs_result => {:code => response['avsresponse']},
|
137
|
+
:cvv_result => response['cvvresponse']
|
138
|
+
)
|
139
|
+
end
|
140
|
+
|
141
|
+
def success?(response)
|
142
|
+
response['response'] == '1'
|
143
|
+
end
|
144
|
+
|
145
|
+
def test?
|
146
|
+
(@options[:login].eql?('demo')) && (@options[:password].eql?('password'))
|
147
|
+
end
|
148
|
+
|
149
|
+
def message_from(response)
|
150
|
+
case response['response'].to_i
|
151
|
+
when APPROVED
|
152
|
+
"Transaction Approved"
|
153
|
+
when DECLINED
|
154
|
+
"Transaction Declined"
|
155
|
+
else
|
156
|
+
"Error in transaction data or system error"
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
def post_data(action, parameters = {})
|
161
|
+
parameters[:type] = action
|
162
|
+
parameters[:username] = @options[:login]
|
163
|
+
parameters[:password] = @options[:password]
|
164
|
+
parameters.map{|k, v| "#{k}=#{CGI.escape(v.to_s)}"}.join('&')
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
@@ -1,3 +1,7 @@
|
|
1
|
+
if RUBY_VERSION < '1.9' && $KCODE == "NONE"
|
2
|
+
$KCODE = 'u'
|
3
|
+
end
|
4
|
+
|
1
5
|
module ActiveMerchant #:nodoc:
|
2
6
|
module Billing #:nodoc:
|
3
7
|
class GarantiGateway < Gateway
|
@@ -193,7 +197,15 @@ module ActiveMerchant #:nodoc:
|
|
193
197
|
end
|
194
198
|
|
195
199
|
def normalize(text)
|
196
|
-
|
200
|
+
return unless text
|
201
|
+
|
202
|
+
if ActiveSupport::Inflector.method(:transliterate).arity == -2
|
203
|
+
ActiveSupport::Inflector.transliterate(text,'')
|
204
|
+
elsif RUBY_VERSION >= '1.9'
|
205
|
+
text.gsub(/[^\x00-\x7F]+/, '')
|
206
|
+
else
|
207
|
+
ActiveSupport::Inflector.transliterate(text).to_s
|
208
|
+
end
|
197
209
|
end
|
198
210
|
|
199
211
|
def add_transaction_data(xml, money, options)
|
@@ -56,20 +56,20 @@ module ActiveMerchant #:nodoc:
|
|
56
56
|
post[:card_id] = card_id
|
57
57
|
commit('X', nil, post)
|
58
58
|
end
|
59
|
-
|
59
|
+
|
60
60
|
def credit(money, creditcard_or_card_id, options = {})
|
61
61
|
post ={}
|
62
62
|
add_payment_source(post, creditcard_or_card_id, options)
|
63
63
|
commit('C', money, post)
|
64
64
|
end
|
65
65
|
|
66
|
-
def void(transaction_id)
|
66
|
+
def void(transaction_id, options = {})
|
67
67
|
post = {}
|
68
68
|
post[:transaction_id] = transaction_id
|
69
69
|
commit('V', nil, post)
|
70
70
|
end
|
71
|
-
|
72
|
-
private
|
71
|
+
|
72
|
+
private
|
73
73
|
|
74
74
|
def add_address(post, options)
|
75
75
|
if address = options[:billing_address] || options[:address]
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module ActiveMerchant #:nodoc:
|
2
|
+
module Billing #:nodoc:
|
3
|
+
class NmiGateway < AuthorizeNetGateway
|
4
|
+
self.test_url = 'https://secure.networkmerchants.com/gateway/transact.dll'
|
5
|
+
self.live_url = 'https://secure.networkmerchants.com/gateway/transact.dll'
|
6
|
+
self.homepage_url = 'http://nmi.com/'
|
7
|
+
self.display_name = 'NMI'
|
8
|
+
self.supported_countries = ['US']
|
9
|
+
self.supported_cardtypes = [:visa, :master, :american_express, :discover]
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
@@ -101,7 +101,7 @@ module ActiveMerchant #:nodoc:
|
|
101
101
|
|
102
102
|
class_inheritable_accessor :test_url, :live_url
|
103
103
|
|
104
|
-
self.test_url = "https://
|
104
|
+
self.test_url = "https://www.payjunctionlabs.com/quick_link"
|
105
105
|
self.live_url = "https://payjunction.com/quick_link"
|
106
106
|
|
107
107
|
TEST_LOGIN = 'pj-ql-01'
|
@@ -207,22 +207,22 @@ module ActiveMerchant #:nodoc:
|
|
207
207
|
:transaction_amount => amount(money),
|
208
208
|
:transaction_id => authorization
|
209
209
|
}
|
210
|
-
|
210
|
+
|
211
211
|
commit('CREDIT', parameters)
|
212
212
|
end
|
213
|
-
|
213
|
+
|
214
214
|
# Cancel a transaction that has been charged but has not yet made it
|
215
215
|
# through the batch process.
|
216
|
-
def void(
|
216
|
+
def void(authorization, options = {})
|
217
217
|
parameters = {
|
218
218
|
:transaction_id => authorization,
|
219
219
|
:posture => 'void'
|
220
220
|
}
|
221
|
-
|
222
|
-
add_optional_fields(parameters, options)
|
221
|
+
|
222
|
+
add_optional_fields(parameters, options)
|
223
223
|
commit('update', parameters)
|
224
224
|
end
|
225
|
-
|
225
|
+
|
226
226
|
# Set up a sale that will be made on a regular basis for the same amount
|
227
227
|
# (ex. $20 a month for 12 months)
|
228
228
|
#
|
@@ -389,4 +389,4 @@ module ActiveMerchant #:nodoc:
|
|
389
389
|
|
390
390
|
end
|
391
391
|
end
|
392
|
-
end
|
392
|
+
end
|
@@ -3,13 +3,12 @@ require 'iconv'
|
|
3
3
|
module ActiveMerchant #:nodoc:
|
4
4
|
module Billing #:nodoc:
|
5
5
|
class PayboxDirectGateway < Gateway
|
6
|
-
TEST_URL = 'https://ppps.paybox.com/PPPS.php'
|
7
|
-
TEST_URL_BACKUP = 'https://ppps1.paybox.com/PPPS.php'
|
6
|
+
TEST_URL = 'https://preprod-ppps.paybox.com/PPPS.php'
|
8
7
|
LIVE_URL = 'https://ppps.paybox.com/PPPS.php'
|
9
8
|
LIVE_URL_BACKUP = 'https://ppps1.paybox.com/PPPS.php'
|
10
9
|
|
11
10
|
# Payment API Version
|
12
|
-
API_VERSION = '
|
11
|
+
API_VERSION = '00103'
|
13
12
|
|
14
13
|
# Transactions hash
|
15
14
|
TRANSACTIONS = {
|
@@ -142,7 +141,7 @@ module ActiveMerchant #:nodoc:
|
|
142
141
|
parameters[:devise] = CURRENCY_CODES[options[:currency] || currency(money)]
|
143
142
|
request_data = post_data(action,parameters)
|
144
143
|
response = parse(ssl_post(test? ? TEST_URL : LIVE_URL, request_data))
|
145
|
-
response = parse(ssl_post(
|
144
|
+
response = parse(ssl_post(LIVE_URL_BACKUP, request_data)) if service_unavailable?(response) && !test?
|
146
145
|
Response.new(success?(response), message_from(response), response.merge(
|
147
146
|
:timestamp => parameters[:dateq]),
|
148
147
|
:test => test?,
|
@@ -8,7 +8,7 @@ module ActiveMerchant #:nodoc:
|
|
8
8
|
base.cattr_accessor :signature
|
9
9
|
end
|
10
10
|
|
11
|
-
API_VERSION = '
|
11
|
+
API_VERSION = '62.0'
|
12
12
|
|
13
13
|
URLS = {
|
14
14
|
:test => { :certificate => 'https://api.sandbox.paypal.com/2.0/',
|
@@ -323,4 +323,4 @@ module ActiveMerchant #:nodoc:
|
|
323
323
|
end
|
324
324
|
end
|
325
325
|
end
|
326
|
-
end
|
326
|
+
end
|