activemerchant 1.52.0 → 1.53.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +56 -0
  3. data/README.md +1 -1
  4. data/lib/active_merchant/billing/gateways/authorize_net.rb +4 -1
  5. data/lib/active_merchant/billing/gateways/banwire.rb +11 -0
  6. data/lib/active_merchant/billing/gateways/beanstream.rb +12 -1
  7. data/lib/active_merchant/billing/gateways/blue_pay.rb +519 -506
  8. data/lib/active_merchant/billing/gateways/borgun.rb +10 -0
  9. data/lib/active_merchant/billing/gateways/braintree/braintree_common.rb +13 -1
  10. data/lib/active_merchant/billing/gateways/braintree_blue.rb +2 -2
  11. data/lib/active_merchant/billing/gateways/braintree_orange.rb +0 -1
  12. data/lib/active_merchant/billing/gateways/card_stream.rb +14 -19
  13. data/lib/active_merchant/billing/gateways/cecabank.rb +11 -1
  14. data/lib/active_merchant/billing/gateways/cenpos.rb +62 -2
  15. data/lib/active_merchant/billing/gateways/checkout.rb +1 -1
  16. data/lib/active_merchant/billing/gateways/checkout_v2.rb +3 -3
  17. data/lib/active_merchant/billing/gateways/conekta.rb +11 -1
  18. data/lib/active_merchant/billing/gateways/creditcall.rb +208 -0
  19. data/lib/active_merchant/billing/gateways/epay.rb +12 -0
  20. data/lib/active_merchant/billing/gateways/eway.rb +11 -0
  21. data/lib/active_merchant/billing/gateways/eway_rapid.rb +11 -0
  22. data/lib/active_merchant/billing/gateways/forte.rb +238 -0
  23. data/lib/active_merchant/billing/gateways/iridium.rb +11 -0
  24. data/lib/active_merchant/billing/gateways/jetpay.rb +10 -1
  25. data/lib/active_merchant/billing/gateways/linkpoint.rb +11 -0
  26. data/lib/active_merchant/billing/gateways/litle.rb +8 -1
  27. data/lib/active_merchant/billing/gateways/merchant_ware_version_four.rb +1 -1
  28. data/lib/active_merchant/billing/gateways/micropayment.rb +167 -0
  29. data/lib/active_merchant/billing/gateways/migs.rb +13 -4
  30. data/lib/active_merchant/billing/gateways/monei.rb +1 -1
  31. data/lib/active_merchant/billing/gateways/netbilling.rb +11 -1
  32. data/lib/active_merchant/billing/gateways/nmi.rb +164 -178
  33. data/lib/active_merchant/billing/gateways/ogone.rb +50 -15
  34. data/lib/active_merchant/billing/gateways/openpay.rb +10 -1
  35. data/lib/active_merchant/billing/gateways/pac_net_raven.rb +5 -5
  36. data/lib/active_merchant/billing/gateways/payment_express.rb +11 -0
  37. data/lib/active_merchant/billing/gateways/paymill.rb +11 -0
  38. data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +1 -1
  39. data/lib/active_merchant/billing/gateways/paystation.rb +3 -4
  40. data/lib/active_merchant/billing/gateways/pin.rb +10 -0
  41. data/lib/active_merchant/billing/gateways/quickpay/quickpay_v10.rb +106 -57
  42. data/lib/active_merchant/billing/gateways/realex.rb +10 -0
  43. data/lib/active_merchant/billing/gateways/redsys.rb +20 -0
  44. data/lib/active_merchant/billing/gateways/s5.rb +1 -0
  45. data/lib/active_merchant/billing/gateways/sage_pay.rb +11 -0
  46. data/lib/active_merchant/billing/gateways/secure_net.rb +1 -0
  47. data/lib/active_merchant/billing/gateways/stripe.rb +10 -4
  48. data/lib/active_merchant/billing/gateways/tns.rb +15 -4
  49. data/lib/active_merchant/billing/gateways/trust_commerce.rb +11 -0
  50. data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +12 -2
  51. data/lib/active_merchant/billing/gateways/wirecard.rb +11 -1
  52. data/lib/active_merchant/billing/gateways/worldpay.rb +11 -0
  53. data/lib/active_merchant/billing/gateways/worldpay_online_payments.rb +1 -1
  54. data/lib/active_merchant/version.rb +1 -1
  55. metadata +5 -2
@@ -58,7 +58,8 @@ module ActiveMerchant #:nodoc:
58
58
  requires!(options, :order_id)
59
59
 
60
60
  post = {}
61
- post[:Amount] = amount(money)
61
+
62
+ add_amount(post, money, options)
62
63
  add_invoice(post, options)
63
64
  add_creditcard(post, creditcard)
64
65
  add_standard_parameters('pay', post, options[:unique_id])
@@ -78,7 +79,8 @@ module ActiveMerchant #:nodoc:
78
79
  requires!(@options, :advanced_login, :advanced_password)
79
80
 
80
81
  post = options.merge(:TransNo => authorization)
81
- post[:Amount] = amount(money)
82
+
83
+ add_amount(post, money, options)
82
84
  add_advanced_user(post)
83
85
  add_standard_parameters('capture', post, options[:unique_id])
84
86
 
@@ -93,7 +95,8 @@ module ActiveMerchant #:nodoc:
93
95
  requires!(@options, :advanced_login, :advanced_password)
94
96
 
95
97
  post = options.merge(:TransNo => authorization)
96
- post[:Amount] = amount(money)
98
+
99
+ add_amount(post, money, options)
97
100
  add_advanced_user(post)
98
101
  add_standard_parameters('refund', post, options[:unique_id])
99
102
 
@@ -143,7 +146,8 @@ module ActiveMerchant #:nodoc:
143
146
  requires!(@options, :secure_hash)
144
147
 
145
148
  post = {}
146
- post[:Amount] = amount(money)
149
+
150
+ add_amount(post, money, options)
147
151
  add_invoice(post, options)
148
152
  add_creditcard_type(post, options[:card_type]) if options[:card_type]
149
153
 
@@ -184,6 +188,11 @@ module ActiveMerchant #:nodoc:
184
188
 
185
189
  private
186
190
 
191
+ def add_amount(post, money, options)
192
+ post[:Amount] = amount(money)
193
+ post[:Currency] = options[:currency] if options[:currency]
194
+ end
195
+
187
196
  def add_advanced_user(post)
188
197
  post[:User] = @options[:advanced_login]
189
198
  post[:Password] = @options[:advanced_password]
@@ -45,7 +45,7 @@ module ActiveMerchant #:nodoc:
45
45
  # :currency Sale currency to override money object or default (optional)
46
46
  #
47
47
  # Returns Active Merchant response object
48
- def purchase(money, credit_card, options)
48
+ def purchase(money, credit_card, options={})
49
49
  execute_new_order(:purchase, money, credit_card, options)
50
50
  end
51
51
 
@@ -105,6 +105,17 @@ module ActiveMerchant #:nodoc:
105
105
  (@options[:login] == TEST_LOGIN || super)
106
106
  end
107
107
 
108
+ def supports_scrubbing
109
+ true
110
+ end
111
+
112
+ def scrub(transcript)
113
+ transcript.
114
+ gsub(%r((Authorization: Basic )\w+), '\1[FILTERED]').
115
+ gsub(%r((&?card_number=)[^&]*), '\1[FILTERED]').
116
+ gsub(%r((&?card_cvv2=)[^&]*), '\1[FILTERED]')
117
+ end
118
+
108
119
  private
109
120
 
110
121
  def add_amount(post, money)
@@ -221,4 +232,3 @@ module ActiveMerchant #:nodoc:
221
232
  end
222
233
  end
223
234
  end
224
-
@@ -1,256 +1,242 @@
1
1
  module ActiveMerchant #:nodoc:
2
2
  module Billing #:nodoc:
3
3
  class NmiGateway < Gateway
4
- API_VERSION = '3.1'
5
4
 
6
- self.test_url = 'https://secure.networkmerchants.com/gateway/transact.dll'
7
- self.live_url = 'https://secure.networkmerchants.com/gateway/transact.dll'
8
-
9
- class_attribute :duplicate_window
10
-
11
- APPROVED, DECLINED, ERROR, FRAUD_REVIEW = 1, 2, 3, 4
12
-
13
- RESPONSE_CODE, RESPONSE_REASON_CODE, RESPONSE_REASON_TEXT, AUTHORIZATION_CODE = 0, 2, 3, 4
14
- AVS_RESULT_CODE, TRANSACTION_ID, CARD_CODE_RESPONSE_CODE, CARDHOLDER_AUTH_CODE = 5, 6, 38, 39
5
+ DUP_WINDOW_DEPRECATION_MESSAGE = "The class-level duplicate_window variable is deprecated. Please use the :dup_seconds transaction option instead."
15
6
 
7
+ self.test_url = self.live_url = 'https://secure.nmi.com/api/transact.php'
16
8
  self.default_currency = 'USD'
17
-
9
+ self.money_format = :dollars
18
10
  self.supported_countries = ['US']
19
11
  self.supported_cardtypes = [:visa, :master, :american_express, :discover]
20
12
  self.homepage_url = 'http://nmi.com/'
21
13
  self.display_name = 'NMI'
22
14
 
23
- CARD_CODE_ERRORS = %w( N S )
24
- AVS_ERRORS = %w( A E N R W Z )
25
- AVS_REASON_CODES = %w(27 45)
26
- TRANSACTION_ALREADY_ACTIONED = %w(310 311)
15
+ def self.duplicate_window=(seconds)
16
+ ActiveMerchant.deprecated(DUP_WINDOW_DEPRECATION_MESSAGE)
17
+ @dup_seconds = seconds
18
+ end
19
+
20
+ def self.duplicate_window
21
+ instance_variable_defined?(:@dup_seconds) ? @dup_seconds : nil
22
+ end
27
23
 
28
24
  def initialize(options = {})
29
25
  requires!(options, :login, :password)
30
26
  super
31
27
  end
32
28
 
33
- def authorize(money, paysource, options = {})
29
+ def purchase(amount, payment_method, options={})
34
30
  post = {}
35
- add_currency_code(post, money, options)
36
- add_invoice(post, options)
37
- add_payment_source(post, paysource, options)
38
- add_address(post, options)
31
+ add_invoice(post, amount, options)
32
+ add_payment_method(post, payment_method)
39
33
  add_customer_data(post, options)
40
- add_duplicate_window(post)
34
+ add_merchant_defined_fields(post, options)
41
35
 
42
- commit('AUTH_ONLY', money, post)
36
+ commit("sale", post)
43
37
  end
44
38
 
45
- def purchase(money, paysource, options = {})
39
+ def authorize(amount, payment_method, options={})
46
40
  post = {}
47
- add_currency_code(post, money, options)
48
- add_invoice(post, options)
49
- add_payment_source(post, paysource, options)
50
- add_address(post, options)
41
+ add_invoice(post, amount, options)
42
+ add_payment_method(post, payment_method)
51
43
  add_customer_data(post, options)
52
- add_duplicate_window(post)
44
+ add_merchant_defined_fields(post, options)
53
45
 
54
- commit('AUTH_CAPTURE', money, post)
46
+ commit("auth", post)
55
47
  end
56
48
 
57
- def capture(money, authorization, options = {})
58
- post = {:trans_id => authorization}
59
- add_customer_data(post, options)
60
- add_invoice(post, options)
61
- commit('PRIOR_AUTH_CAPTURE', money, post)
62
- end
49
+ def capture(amount, authorization, options={})
50
+ post = {}
51
+ add_invoice(post, amount, options)
52
+ add_reference(post, authorization)
53
+ add_merchant_defined_fields(post, options)
63
54
 
64
- def void(authorization, options = {})
65
- post = {:trans_id => authorization}
66
- add_duplicate_window(post)
67
- commit('VOID', nil, post)
55
+ commit("capture", post)
68
56
  end
69
57
 
70
- def refund(money, identification, options = {})
71
- requires!(options, :card_number)
72
-
73
- post = { :trans_id => identification,
74
- :card_num => options[:card_number]
75
- }
76
-
77
- post[:first_name] = options[:first_name] if options[:first_name]
78
- post[:last_name] = options[:last_name] if options[:last_name]
79
- post[:zip] = options[:zip] if options[:zip]
80
-
81
- add_invoice(post, options)
82
- add_duplicate_window(post)
58
+ def void(authorization, options={})
59
+ post = {}
60
+ add_reference(post, authorization)
83
61
 
84
- commit('CREDIT', money, post)
62
+ commit("void", post)
85
63
  end
86
64
 
87
- def credit(money, identification, options = {})
88
- ActiveMerchant.deprecated CREDIT_DEPRECATION_MESSAGE
89
- refund(money, identification, options)
90
- end
65
+ def refund(amount, authorization, options={})
66
+ post = {}
67
+ add_invoice(post, amount, options)
68
+ add_reference(post, authorization)
91
69
 
92
- def verify(credit_card, options = {})
93
- MultiResponse.run(:use_first_response) do |r|
94
- r.process { authorize(100, credit_card, options) }
95
- r.process(:ignore_result) { void(r.authorization, options) }
96
- end
70
+ commit("refund", post)
97
71
  end
98
72
 
99
- private
100
-
101
- def commit(action, money, parameters)
102
- parameters[:amount] = amount(money) unless action == 'VOID'
103
-
104
- url = test? ? self.test_url : self.live_url
105
- data = ssl_post(url, post_data(action, parameters))
106
-
107
- response = parse(data)
108
- response[:action] = action
109
-
110
- message = message_from(response)
111
-
112
- Response.new(success?(response), message, response,
113
- :test => test?,
114
- :authorization => response[:transaction_id],
115
- :fraud_review => fraud_review?(response),
116
- :avs_result => { :code => response[:avs_result_code] },
117
- :cvv_result => response[:card_code]
118
- )
119
- end
73
+ def credit(amount, payment_method, options={})
74
+ post = {}
75
+ add_invoice(post, amount, options)
76
+ add_payment_method(post, payment_method)
77
+ add_customer_data(post, options)
120
78
 
121
- def success?(response)
122
- response[:response_code] == APPROVED && TRANSACTION_ALREADY_ACTIONED.exclude?(response[:response_reason_code])
79
+ commit("credit", post)
123
80
  end
124
81
 
125
- def fraud_review?(response)
126
- response[:response_code] == FRAUD_REVIEW
127
- end
82
+ def verify(payment_method, options={})
83
+ post = {}
84
+ add_payment_method(post, payment_method)
85
+ add_customer_data(post, options)
86
+ add_merchant_defined_fields(post, options)
128
87
 
129
- def parse(body)
130
- fields = split(body)
131
-
132
- results = {
133
- :response_code => fields[RESPONSE_CODE].to_i,
134
- :response_reason_code => fields[RESPONSE_REASON_CODE],
135
- :response_reason_text => fields[RESPONSE_REASON_TEXT],
136
- :avs_result_code => fields[AVS_RESULT_CODE],
137
- :transaction_id => fields[TRANSACTION_ID],
138
- :card_code => fields[CARD_CODE_RESPONSE_CODE],
139
- :authorization_code => fields[AUTHORIZATION_CODE],
140
- :cardholder_authentication_code => fields[CARDHOLDER_AUTH_CODE]
141
- }
142
- results
88
+ commit("validate", post)
143
89
  end
144
90
 
145
- def post_data(action, parameters = {})
91
+ def store(payment_method, options = {})
146
92
  post = {}
93
+ add_invoice(post, nil, options)
94
+ add_payment_method(post, payment_method)
95
+ add_customer_data(post, options)
96
+ add_merchant_defined_fields(post, options)
147
97
 
148
- post[:version] = API_VERSION
149
- post[:login] = @options[:login]
150
- post[:tran_key] = @options[:password]
151
- post[:relay_response] = "FALSE"
152
- post[:type] = action
153
- post[:delim_data] = "TRUE"
154
- post[:delim_char] = ","
155
- post[:encap_char] = "$"
156
- post[:solution_ID] = application_id if application_id.present? && application_id != "ActiveMerchant"
157
-
158
- request = post.merge(parameters).collect { |key, value| "x_#{key}=#{CGI.escape(value.to_s)}" }.join("&")
159
- request
98
+ commit("add_customer", post)
160
99
  end
161
100
 
162
- def add_currency_code(post, money, options)
163
- post[:currency_code] = options[:currency] || currency(money)
101
+ def supports_scrubbing?
102
+ true
164
103
  end
165
104
 
166
- def add_invoice(post, options)
167
- post[:invoice_num] = options[:order_id]
168
- post[:description] = options[:description]
105
+ def scrub(transcript)
106
+ transcript.
107
+ gsub(%r((password=)\w+), '\1[FILTERED]').
108
+ gsub(%r((ccnumber=)\d+), '\1[FILTERED]').
109
+ gsub(%r((cvv=)\d+), '\1[FILTERED]').
110
+ gsub(%r((checkaba=)\d+), '\1[FILTERED]').
111
+ gsub(%r((checkaccount=)\d+), '\1[FILTERED]')
169
112
  end
170
113
 
171
- def add_creditcard(post, creditcard, options={})
172
- post[:card_num] = creditcard.number
173
- post[:card_code] = creditcard.verification_value if creditcard.verification_value?
174
- post[:exp_date] = expdate(creditcard)
175
- post[:first_name] = creditcard.first_name
176
- post[:last_name] = creditcard.last_name
114
+ private
177
115
 
178
- post[:recurring_billing] = "TRUE" if options[:recurring]
116
+ def add_invoice(post, money, options)
117
+ post[:amount] = amount(money)
118
+ post[:orderid] = options[:order_id]
119
+ post[:orderdescription] = options[:description]
120
+ post[:currency] = options[:currency] || currency(money)
121
+ post[:billing_method] = "recurring" if options[:recurring]
122
+ if (dup_seconds = (options[:dup_seconds] || self.class.duplicate_window))
123
+ post[:dup_seconds] = dup_seconds
124
+ end
179
125
  end
180
126
 
181
- def add_payment_source(params, source, options={})
182
- add_creditcard(params, source, options)
127
+ def add_payment_method(post, payment_method)
128
+ if(payment_method.is_a?(String))
129
+ post[:customer_vault_id] = payment_method
130
+ elsif(card_brand(payment_method) == 'check')
131
+ post[:payment] = 'check'
132
+ post[:checkname] = payment_method.name
133
+ post[:checkaba] = payment_method.routing_number
134
+ post[:checkaccount] = payment_method.account_number
135
+ post[:account_holder_type] = payment_method.account_holder_type
136
+ post[:account_type] = payment_method.account_type
137
+ post[:sec_code] = 'WEB'
138
+ else
139
+ post[:payment] = 'creditcard'
140
+ post[:firstname] = payment_method.first_name
141
+ post[:lastname] = payment_method.last_name
142
+ post[:ccnumber] = payment_method.number
143
+ post[:cvv] = payment_method.verification_value
144
+ post[:ccexp] = exp_date(payment_method)
145
+ end
183
146
  end
184
147
 
185
148
  def add_customer_data(post, options)
186
- if options.has_key? :email
187
- post[:email] = options[:email]
188
- post[:email_customer] = false
149
+ post[:email] = options[:email]
150
+ post[:ipaddress] = options[:ip]
151
+ post[:customer_id] = options[:customer_id] || options[:customer]
152
+
153
+ if(billing_address = options[:billing_address] || options[:address])
154
+ post[:company] = billing_address[:company]
155
+ post[:address1] = billing_address[:address1]
156
+ post[:address2] = billing_address[:address2]
157
+ post[:city] = billing_address[:city]
158
+ post[:state] = billing_address[:state]
159
+ post[:country] = billing_address[:country]
160
+ post[:zip] = billing_address[:zip]
161
+ post[:phone] = billing_address[:phone]
189
162
  end
190
163
 
191
- if options.has_key? :customer
192
- post[:cust_id] = options[:customer] if Float(options[:customer]) rescue nil
164
+ if(shipping_address = options[:shipping_address])
165
+ post[:shipping_company] = shipping_address[:company]
166
+ post[:shipping_address1] = shipping_address[:address1]
167
+ post[:shipping_address2] = shipping_address[:address2]
168
+ post[:shipping_city] = shipping_address[:city]
169
+ post[:shipping_state] = shipping_address[:state]
170
+ post[:shipping_country] = shipping_address[:country]
171
+ post[:shipping_zip] = shipping_address[:zip]
172
+ post[:shipping_phone] = shipping_address[:phone]
193
173
  end
174
+ end
194
175
 
195
- if options.has_key? :ip
196
- post[:customer_ip] = options[:ip]
176
+ def add_merchant_defined_fields(post, options)
177
+ (1..20).each do |each|
178
+ key = "merchant_defined_field_#{each}".to_sym
179
+ post[key] = options[key] if options[key]
197
180
  end
181
+ end
198
182
 
199
- if options.has_key? :cardholder_authentication_value
200
- post[:cardholder_authentication_value] = options[:cardholder_authentication_value]
201
- end
183
+ def add_reference(post, authorization)
184
+ post[:transactionid] = authorization
185
+ end
202
186
 
203
- if options.has_key? :authentication_indicator
204
- post[:authentication_indicator] = options[:authentication_indicator]
205
- end
187
+ def exp_date(payment_method)
188
+ "#{format(payment_method.month, :two_digits)}#{format(payment_method.year, :two_digits)}"
189
+ end
190
+
191
+ def commit(action, params)
206
192
 
193
+ params[action == "add_customer" ? :customer_vault : :type] = action
194
+ params[:username] = @options[:login]
195
+ params[:password] = @options[:password]
196
+
197
+ raw_response = ssl_post(url, post_data(action, params), headers)
198
+ response = parse(raw_response)
199
+ succeeded = success_from(response)
200
+
201
+ Response.new(
202
+ succeeded,
203
+ message_from(succeeded, response),
204
+ response,
205
+ authorization: response[:transactionid],
206
+ avs_result: AVSResult.new(code: response[:avsresponse]),
207
+ cvv_result: CVVResult.new(response[:cvvresponse]),
208
+ test: test?
209
+ )
207
210
  end
208
211
 
209
- def add_duplicate_window(post)
210
- unless duplicate_window.nil?
211
- post[:duplicate_window] = duplicate_window
212
- end
212
+ def headers
213
+ { "Content-Type" => "application/x-www-form-urlencoded;charset=UTF-8" }
213
214
  end
214
215
 
215
- def add_address(post, options)
216
- if address = options[:billing_address] || options[:address]
217
- post[:address] = address[:address1].to_s
218
- post[:company] = address[:company].to_s
219
- post[:phone] = address[:phone].to_s
220
- post[:zip] = address[:zip].to_s
221
- post[:city] = address[:city].to_s
222
- post[:country] = address[:country].to_s
223
- post[:state] = address[:state].blank? ? 'n/a' : address[:state]
224
- end
216
+ def post_data(action, params)
217
+ params.map {|k, v| "#{k}=#{CGI.escape(v.to_s)}"}.join('&')
218
+ end
225
219
 
226
- if address = options[:shipping_address]
227
- post[:ship_to_first_name] = address[:first_name].to_s
228
- post[:ship_to_last_name] = address[:last_name].to_s
229
- post[:ship_to_address] = address[:address1].to_s
230
- post[:ship_to_company] = address[:company].to_s
231
- post[:ship_to_phone] = address[:phone].to_s
232
- post[:ship_to_zip] = address[:zip].to_s
233
- post[:ship_to_city] = address[:city].to_s
234
- post[:ship_to_country] = address[:country].to_s
235
- post[:ship_to_state] = address[:state].blank? ? 'n/a' : address[:state]
236
- end
220
+ def url
221
+ test? ? test_url : live_url
237
222
  end
238
223
 
239
- def message_from(results)
240
- if results[:response_code] == DECLINED
241
- return CVVResult.messages[ results[:card_code] ] if CARD_CODE_ERRORS.include?(results[:card_code])
242
- if AVS_REASON_CODES.include?(results[:response_reason_code]) && AVS_ERRORS.include?(results[:avs_result_code])
243
- return AVSResult.messages[ results[:avs_result_code] ]
244
- end
245
- end
224
+ def parse(body)
225
+ Hash[CGI::parse(body).map { |k,v| [k.intern, v.first] }]
226
+ end
246
227
 
247
- (results[:response_reason_text] ? results[:response_reason_text].chomp('.') : '')
228
+ def success_from(response)
229
+ response[:response] == "1"
248
230
  end
249
231
 
250
- def split(response)
251
- response[1..-2].split(/\$,\$/)
232
+ def message_from(succeeded, response)
233
+ if succeeded
234
+ "Succeeded"
235
+ else
236
+ response[:responsetext]
237
+ end
252
238
  end
239
+
253
240
  end
254
241
  end
255
242
  end
256
-