exception_notification 3.0.1 → 4.0.0.rc1
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.
- data/.gitignore +2 -0
- data/.travis.yml +9 -0
- data/Appraisals +11 -0
- data/CHANGELOG.rdoc +21 -0
- data/Gemfile +1 -1
- data/Gemfile.lock +49 -7
- data/README.md +417 -184
- data/Rakefile +4 -2
- data/examples/sinatra/Gemfile +8 -0
- data/examples/sinatra/Gemfile.lock +95 -0
- data/examples/sinatra/Procfile +2 -0
- data/examples/sinatra/README.md +11 -0
- data/examples/sinatra/config.ru +3 -0
- data/examples/sinatra/sinatra_app.rb +28 -0
- data/exception_notification.gemspec +10 -4
- data/gemfiles/rails3_1.gemfile +7 -0
- data/gemfiles/rails3_2.gemfile +7 -0
- data/gemfiles/rails4_0.gemfile +7 -0
- data/lib/exception_notification.rb +10 -0
- data/lib/exception_notification/rack.rb +45 -0
- data/lib/exception_notification/rails.rb +8 -0
- data/lib/exception_notification/resque.rb +24 -0
- data/lib/exception_notification/sidekiq.rb +22 -0
- data/lib/exception_notifier.rb +89 -61
- data/lib/exception_notifier/campfire_notifier.rb +2 -7
- data/lib/exception_notifier/email_notifier.rb +181 -0
- data/lib/exception_notifier/notifier.rb +9 -178
- data/lib/exception_notifier/views/exception_notifier/_backtrace.html.erb +3 -1
- data/lib/exception_notifier/views/exception_notifier/_data.html.erb +6 -1
- data/lib/exception_notifier/views/exception_notifier/_environment.html.erb +16 -6
- data/lib/exception_notifier/views/exception_notifier/_environment.text.erb +1 -1
- data/lib/exception_notifier/views/exception_notifier/_request.html.erb +24 -5
- data/lib/exception_notifier/views/exception_notifier/_request.text.erb +2 -0
- data/lib/exception_notifier/views/exception_notifier/_session.html.erb +10 -2
- data/lib/exception_notifier/views/exception_notifier/_session.text.erb +1 -1
- data/lib/exception_notifier/views/exception_notifier/_title.html.erb +3 -3
- data/lib/exception_notifier/views/exception_notifier/background_exception_notification.html.erb +38 -11
- data/lib/exception_notifier/views/exception_notifier/background_exception_notification.text.erb +0 -1
- data/lib/exception_notifier/views/exception_notifier/exception_notification.html.erb +39 -21
- data/lib/exception_notifier/views/exception_notifier/exception_notification.text.erb +0 -1
- data/lib/exception_notifier/webhook_notifier.rb +21 -0
- data/lib/generators/exception_notification/install_generator.rb +15 -0
- data/lib/generators/exception_notification/templates/exception_notification.rb +47 -0
- data/test/dummy/Gemfile +2 -1
- data/test/dummy/Gemfile.lock +79 -78
- data/test/dummy/config/environment.rb +9 -7
- data/test/dummy/test/functional/posts_controller_test.rb +22 -37
- data/test/{campfire_test.rb → exception_notifier/campfire_notifier_test.rb} +4 -4
- data/test/exception_notifier/email_notifier_test.rb +144 -0
- data/test/exception_notifier/webhook_notifier_test.rb +41 -0
- data/test/exception_notifier_test.rb +101 -0
- data/test/test_helper.rb +4 -1
- metadata +136 -18
- data/test/background_exception_notification_test.rb +0 -82
- data/test/exception_notification_test.rb +0 -73
data/test/test_helper.rb
CHANGED
@@ -1,11 +1,14 @@
|
|
1
1
|
# Configure Rails Environment
|
2
2
|
ENV["RAILS_ENV"] = "test"
|
3
3
|
|
4
|
+
require "coveralls"
|
5
|
+
Coveralls.wear!
|
6
|
+
|
4
7
|
require File.expand_path("../dummy/config/environment.rb", __FILE__)
|
5
8
|
require "rails/test_help"
|
6
9
|
require File.expand_path("../dummy/test/test_helper.rb", __FILE__)
|
7
10
|
|
8
11
|
require "test/unit"
|
9
|
-
require "mocha"
|
12
|
+
require "mocha/setup"
|
10
13
|
|
11
14
|
Rails.backtrace_cleaner.remove_silencers!
|
metadata
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: exception_notification
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
5
|
-
prerelease:
|
4
|
+
version: 4.0.0.rc1
|
5
|
+
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Jamis Buck
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2013-
|
13
|
+
date: 2013-06-20 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: actionmailer
|
@@ -28,6 +28,70 @@ dependencies:
|
|
28
28
|
- - ! '>='
|
29
29
|
- !ruby/object:Gem::Version
|
30
30
|
version: 3.0.4
|
31
|
+
- !ruby/object:Gem::Dependency
|
32
|
+
name: activesupport
|
33
|
+
requirement: !ruby/object:Gem::Requirement
|
34
|
+
none: false
|
35
|
+
requirements:
|
36
|
+
- - ! '>='
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: 3.0.4
|
39
|
+
type: :runtime
|
40
|
+
prerelease: false
|
41
|
+
version_requirements: !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ! '>='
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 3.0.4
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rails
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 3.0.4
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: !ruby/object:Gem::Requirement
|
58
|
+
none: false
|
59
|
+
requirements:
|
60
|
+
- - ! '>='
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: 3.0.4
|
63
|
+
- !ruby/object:Gem::Dependency
|
64
|
+
name: resque
|
65
|
+
requirement: !ruby/object:Gem::Requirement
|
66
|
+
none: false
|
67
|
+
requirements:
|
68
|
+
- - ~>
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: 1.2.0
|
71
|
+
type: :development
|
72
|
+
prerelease: false
|
73
|
+
version_requirements: !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
75
|
+
requirements:
|
76
|
+
- - ~>
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: 1.2.0
|
79
|
+
- !ruby/object:Gem::Dependency
|
80
|
+
name: sidekiq
|
81
|
+
requirement: !ruby/object:Gem::Requirement
|
82
|
+
none: false
|
83
|
+
requirements:
|
84
|
+
- - ~>
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: '2.0'
|
87
|
+
type: :development
|
88
|
+
prerelease: false
|
89
|
+
version_requirements: !ruby/object:Gem::Requirement
|
90
|
+
none: false
|
91
|
+
requirements:
|
92
|
+
- - ~>
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: '2.0'
|
31
95
|
- !ruby/object:Gem::Dependency
|
32
96
|
name: tinder
|
33
97
|
requirement: !ruby/object:Gem::Requirement
|
@@ -45,21 +109,21 @@ dependencies:
|
|
45
109
|
- !ruby/object:Gem::Version
|
46
110
|
version: '1.8'
|
47
111
|
- !ruby/object:Gem::Dependency
|
48
|
-
name:
|
112
|
+
name: httparty
|
49
113
|
requirement: !ruby/object:Gem::Requirement
|
50
114
|
none: false
|
51
115
|
requirements:
|
52
|
-
- -
|
116
|
+
- - ~>
|
53
117
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
118
|
+
version: 0.10.2
|
55
119
|
type: :development
|
56
120
|
prerelease: false
|
57
121
|
version_requirements: !ruby/object:Gem::Requirement
|
58
122
|
none: false
|
59
123
|
requirements:
|
60
|
-
- -
|
124
|
+
- - ~>
|
61
125
|
- !ruby/object:Gem::Version
|
62
|
-
version:
|
126
|
+
version: 0.10.2
|
63
127
|
- !ruby/object:Gem::Dependency
|
64
128
|
name: mocha
|
65
129
|
requirement: !ruby/object:Gem::Requirement
|
@@ -67,7 +131,7 @@ dependencies:
|
|
67
131
|
requirements:
|
68
132
|
- - ! '>='
|
69
133
|
- !ruby/object:Gem::Version
|
70
|
-
version: 0.
|
134
|
+
version: 0.13.0
|
71
135
|
type: :development
|
72
136
|
prerelease: false
|
73
137
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -75,7 +139,7 @@ dependencies:
|
|
75
139
|
requirements:
|
76
140
|
- - ! '>='
|
77
141
|
- !ruby/object:Gem::Version
|
78
|
-
version: 0.
|
142
|
+
version: 0.13.0
|
79
143
|
- !ruby/object:Gem::Dependency
|
80
144
|
name: sqlite3
|
81
145
|
requirement: !ruby/object:Gem::Requirement
|
@@ -92,6 +156,38 @@ dependencies:
|
|
92
156
|
- - ! '>='
|
93
157
|
- !ruby/object:Gem::Version
|
94
158
|
version: 1.3.4
|
159
|
+
- !ruby/object:Gem::Dependency
|
160
|
+
name: coveralls
|
161
|
+
requirement: !ruby/object:Gem::Requirement
|
162
|
+
none: false
|
163
|
+
requirements:
|
164
|
+
- - ~>
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: 0.6.5
|
167
|
+
type: :development
|
168
|
+
prerelease: false
|
169
|
+
version_requirements: !ruby/object:Gem::Requirement
|
170
|
+
none: false
|
171
|
+
requirements:
|
172
|
+
- - ~>
|
173
|
+
- !ruby/object:Gem::Version
|
174
|
+
version: 0.6.5
|
175
|
+
- !ruby/object:Gem::Dependency
|
176
|
+
name: appraisal
|
177
|
+
requirement: !ruby/object:Gem::Requirement
|
178
|
+
none: false
|
179
|
+
requirements:
|
180
|
+
- - ! '>='
|
181
|
+
- !ruby/object:Gem::Version
|
182
|
+
version: '0'
|
183
|
+
type: :development
|
184
|
+
prerelease: false
|
185
|
+
version_requirements: !ruby/object:Gem::Requirement
|
186
|
+
none: false
|
187
|
+
requirements:
|
188
|
+
- - ! '>='
|
189
|
+
- !ruby/object:Gem::Version
|
190
|
+
version: '0'
|
95
191
|
description:
|
96
192
|
email: smartinez87@gmail.com
|
97
193
|
executables: []
|
@@ -99,16 +195,33 @@ extensions: []
|
|
99
195
|
extra_rdoc_files: []
|
100
196
|
files:
|
101
197
|
- .gemtest
|
198
|
+
- .gitignore
|
199
|
+
- .travis.yml
|
200
|
+
- Appraisals
|
102
201
|
- CHANGELOG.rdoc
|
103
202
|
- CONTRIBUTING.md
|
104
203
|
- Gemfile
|
105
204
|
- Gemfile.lock
|
106
205
|
- README.md
|
107
206
|
- Rakefile
|
207
|
+
- examples/sinatra/Gemfile
|
208
|
+
- examples/sinatra/Gemfile.lock
|
209
|
+
- examples/sinatra/Procfile
|
210
|
+
- examples/sinatra/README.md
|
211
|
+
- examples/sinatra/config.ru
|
212
|
+
- examples/sinatra/sinatra_app.rb
|
108
213
|
- exception_notification.gemspec
|
214
|
+
- gemfiles/rails3_1.gemfile
|
215
|
+
- gemfiles/rails3_2.gemfile
|
216
|
+
- gemfiles/rails4_0.gemfile
|
109
217
|
- lib/exception_notification.rb
|
218
|
+
- lib/exception_notification/rack.rb
|
219
|
+
- lib/exception_notification/rails.rb
|
220
|
+
- lib/exception_notification/resque.rb
|
221
|
+
- lib/exception_notification/sidekiq.rb
|
110
222
|
- lib/exception_notifier.rb
|
111
223
|
- lib/exception_notifier/campfire_notifier.rb
|
224
|
+
- lib/exception_notifier/email_notifier.rb
|
112
225
|
- lib/exception_notifier/notifier.rb
|
113
226
|
- lib/exception_notifier/views/exception_notifier/_backtrace.html.erb
|
114
227
|
- lib/exception_notifier/views/exception_notifier/_backtrace.text.erb
|
@@ -126,8 +239,9 @@ files:
|
|
126
239
|
- lib/exception_notifier/views/exception_notifier/background_exception_notification.text.erb
|
127
240
|
- lib/exception_notifier/views/exception_notifier/exception_notification.html.erb
|
128
241
|
- lib/exception_notifier/views/exception_notifier/exception_notification.text.erb
|
129
|
-
-
|
130
|
-
-
|
242
|
+
- lib/exception_notifier/webhook_notifier.rb
|
243
|
+
- lib/generators/exception_notification/install_generator.rb
|
244
|
+
- lib/generators/exception_notification/templates/exception_notification.rb
|
131
245
|
- test/dummy/.gitignore
|
132
246
|
- test/dummy/Gemfile
|
133
247
|
- test/dummy/Gemfile.lock
|
@@ -183,7 +297,10 @@ files:
|
|
183
297
|
- test/dummy/test/fixtures/posts.yml
|
184
298
|
- test/dummy/test/functional/posts_controller_test.rb
|
185
299
|
- test/dummy/test/test_helper.rb
|
186
|
-
- test/
|
300
|
+
- test/exception_notifier/campfire_notifier_test.rb
|
301
|
+
- test/exception_notifier/email_notifier_test.rb
|
302
|
+
- test/exception_notifier/webhook_notifier_test.rb
|
303
|
+
- test/exception_notifier_test.rb
|
187
304
|
- test/test_helper.rb
|
188
305
|
homepage: http://smartinez87.github.com/exception_notification
|
189
306
|
licenses: []
|
@@ -200,9 +317,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
200
317
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
201
318
|
none: false
|
202
319
|
requirements:
|
203
|
-
- - ! '
|
320
|
+
- - ! '>'
|
204
321
|
- !ruby/object:Gem::Version
|
205
|
-
version:
|
322
|
+
version: 1.3.1
|
206
323
|
requirements: []
|
207
324
|
rubyforge_project:
|
208
325
|
rubygems_version: 1.8.23
|
@@ -210,8 +327,6 @@ signing_key:
|
|
210
327
|
specification_version: 3
|
211
328
|
summary: Exception notification for Rails apps
|
212
329
|
test_files:
|
213
|
-
- test/background_exception_notification_test.rb
|
214
|
-
- test/campfire_test.rb
|
215
330
|
- test/dummy/.gitignore
|
216
331
|
- test/dummy/Gemfile
|
217
332
|
- test/dummy/Gemfile.lock
|
@@ -267,5 +382,8 @@ test_files:
|
|
267
382
|
- test/dummy/test/fixtures/posts.yml
|
268
383
|
- test/dummy/test/functional/posts_controller_test.rb
|
269
384
|
- test/dummy/test/test_helper.rb
|
270
|
-
- test/
|
385
|
+
- test/exception_notifier/campfire_notifier_test.rb
|
386
|
+
- test/exception_notifier/email_notifier_test.rb
|
387
|
+
- test/exception_notifier/webhook_notifier_test.rb
|
388
|
+
- test/exception_notifier_test.rb
|
271
389
|
- test/test_helper.rb
|
@@ -1,82 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
class BackgroundExceptionNotificationTest < ActiveSupport::TestCase
|
4
|
-
setup do
|
5
|
-
begin
|
6
|
-
1/0
|
7
|
-
rescue => e
|
8
|
-
@exception = e
|
9
|
-
@time = Time.current
|
10
|
-
@mail = ExceptionNotifier::Notifier.background_exception_notification(@exception,
|
11
|
-
:data => {:job => 'DivideWorkerJob', :payload => '1/0', :message => 'My Custom Message'})
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
test "mail should be plain text and UTF-8 enconded by default" do
|
16
|
-
assert @mail.content_type == "text/plain; charset=UTF-8"
|
17
|
-
end
|
18
|
-
|
19
|
-
test "should have raised an exception" do
|
20
|
-
assert_not_nil @exception
|
21
|
-
end
|
22
|
-
|
23
|
-
test "should have generated a notification email" do
|
24
|
-
assert_not_nil @mail
|
25
|
-
end
|
26
|
-
|
27
|
-
test "mail should have a from address set" do
|
28
|
-
assert @mail.from == ["dummynotifier@example.com"]
|
29
|
-
end
|
30
|
-
|
31
|
-
test "mail should have a to address set" do
|
32
|
-
assert @mail.to == ["dummyexceptions@example.com"]
|
33
|
-
end
|
34
|
-
|
35
|
-
test "mail should have a descriptive subject" do
|
36
|
-
assert @mail.subject == "[Dummy ERROR] (ZeroDivisionError) \"divided by 0\""
|
37
|
-
end
|
38
|
-
|
39
|
-
test "mail should say exception was raised in background at show timestamp" do
|
40
|
-
assert @mail.encoded.include? "A ZeroDivisionError occurred in background at #{@time}"
|
41
|
-
end
|
42
|
-
|
43
|
-
test "mail should prefix exception class with 'an' instead of 'a' when it starts with a vowel" do
|
44
|
-
begin
|
45
|
-
raise ActiveRecord::RecordNotFound
|
46
|
-
rescue => e
|
47
|
-
@vowel_exception = e
|
48
|
-
@vowel_mail = ExceptionNotifier::Notifier.background_exception_notification(@vowel_exception)
|
49
|
-
end
|
50
|
-
|
51
|
-
assert @vowel_mail.encoded.include? "An ActiveRecord::RecordNotFound occurred in background at #{@time}"
|
52
|
-
end
|
53
|
-
|
54
|
-
test "mail should contain backtrace in body" do
|
55
|
-
assert @mail.encoded.include?("test/background_exception_notification_test.rb:6"), "\n#{@mail.inspect}"
|
56
|
-
end
|
57
|
-
|
58
|
-
test "mail should contain data in body" do
|
59
|
-
assert @mail.encoded.include? '* data:'
|
60
|
-
assert @mail.encoded.include? ':payload=>"1/0"'
|
61
|
-
assert @mail.encoded.include? ':job=>"DivideWorkerJob"'
|
62
|
-
assert @mail.encoded.include? "My Custom Message"
|
63
|
-
end
|
64
|
-
|
65
|
-
test "mail should not contain any attachments" do
|
66
|
-
assert @mail.attachments == []
|
67
|
-
end
|
68
|
-
|
69
|
-
test "should not send notification if one of ignored exceptions" do
|
70
|
-
begin
|
71
|
-
raise ActiveRecord::RecordNotFound
|
72
|
-
rescue => e
|
73
|
-
@ignored_exception = e
|
74
|
-
unless ExceptionNotifier.default_ignore_exceptions.include?(@ignored_exception.class.name)
|
75
|
-
@ignored_mail = ExceptionNotifier::Notifier.background_exception_notification(@ignored_exception)
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
assert @ignored_exception.class.inspect == "ActiveRecord::RecordNotFound"
|
80
|
-
assert_nil @ignored_mail
|
81
|
-
end
|
82
|
-
end
|
@@ -1,73 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
class ExceptionNotificationTest < ActiveSupport::TestCase
|
4
|
-
test "should have default ignored exceptions" do
|
5
|
-
assert ExceptionNotifier.default_ignore_exceptions == ['ActiveRecord::RecordNotFound', 'AbstractController::ActionNotFound', 'ActionController::RoutingError']
|
6
|
-
end
|
7
|
-
|
8
|
-
test "should have default sender address overridden" do
|
9
|
-
assert ExceptionNotifier::Notifier.default_sender_address == %("Dummy Notifier" <dummynotifier@example.com>)
|
10
|
-
end
|
11
|
-
|
12
|
-
test "should have default email prefix overridden" do
|
13
|
-
assert ExceptionNotifier::Notifier.default_email_prefix == "[Dummy ERROR] "
|
14
|
-
end
|
15
|
-
|
16
|
-
test "should have default email format overridden" do
|
17
|
-
assert ExceptionNotifier::Notifier.default_email_format == :text
|
18
|
-
end
|
19
|
-
|
20
|
-
test "should have default email headers overridden" do
|
21
|
-
assert ExceptionNotifier::Notifier.default_email_headers == { "X-Custom-Header" => "foobar"}
|
22
|
-
end
|
23
|
-
|
24
|
-
test "should have default sections" do
|
25
|
-
for section in %w(request session environment backtrace)
|
26
|
-
assert ExceptionNotifier::Notifier.default_sections.include? section
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
test "should have default section overridden" do
|
31
|
-
begin
|
32
|
-
test_string = '--- this is a test ---'
|
33
|
-
env = {}
|
34
|
-
exception = StandardError.new("Test Error")
|
35
|
-
options = {:sections => %w(environment)}
|
36
|
-
|
37
|
-
section_partial = Rails.root.join('app', 'views', 'exception_notifier', '_environment.text.erb')
|
38
|
-
|
39
|
-
File.open(section_partial, 'w+') { |f| f.puts test_string }
|
40
|
-
|
41
|
-
assert ExceptionNotifier::Notifier.exception_notification(env, exception, options).body =~ /#{test_string}/
|
42
|
-
ensure
|
43
|
-
File.delete section_partial
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
test "should have default background sections" do
|
48
|
-
for section in %w(backtrace data)
|
49
|
-
assert ExceptionNotifier::Notifier.default_background_sections.include? section
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
test "should have verbose subject by default" do
|
54
|
-
assert ExceptionNotifier::Notifier.default_options[:verbose_subject] == true
|
55
|
-
end
|
56
|
-
|
57
|
-
test "should have ignored crawler by default" do
|
58
|
-
assert ExceptionNotifier.default_ignore_crawlers == []
|
59
|
-
end
|
60
|
-
|
61
|
-
test "should normalize multiple digits into one N" do
|
62
|
-
assert_equal 'N foo N bar N baz N',
|
63
|
-
ExceptionNotifier::Notifier.normalize_digits('1 foo 12 bar 123 baz 1234')
|
64
|
-
end
|
65
|
-
|
66
|
-
test "should have normalize_subject false by default" do
|
67
|
-
assert ExceptionNotifier::Notifier.default_options[:normalize_subject] == false
|
68
|
-
end
|
69
|
-
|
70
|
-
test "should have smtp_settings nil by default" do
|
71
|
-
assert ExceptionNotifier::Notifier.default_options[:smtp_settings] == nil
|
72
|
-
end
|
73
|
-
end
|