mailboxer 0.11.0 → 0.12.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.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.travis.yml +4 -3
  4. data/Appraisals +6 -14
  5. data/Gemfile +1 -1
  6. data/README.md +2 -2
  7. data/app/mailers/mailboxer/base_mailer.rb +14 -0
  8. data/app/mailers/{message_mailer.rb → mailboxer/message_mailer.rb} +9 -14
  9. data/app/mailers/mailboxer/notification_mailer.rb +17 -0
  10. data/app/models/mailboxer/conversation.rb +196 -0
  11. data/app/models/mailboxer/conversation/opt_out.rb +15 -0
  12. data/app/models/{mailbox.rb → mailboxer/mailbox.rb} +10 -10
  13. data/app/models/mailboxer/message.rb +49 -0
  14. data/app/models/{notification.rb → mailboxer/notification.rb} +44 -40
  15. data/app/models/{receipt.rb → mailboxer/receipt.rb} +12 -11
  16. data/app/views/{message_mailer → mailboxer/message_mailer}/new_message_email.html.erb +3 -3
  17. data/app/views/{message_mailer → mailboxer/message_mailer}/new_message_email.text.erb +2 -2
  18. data/app/views/{message_mailer → mailboxer/message_mailer}/reply_message_email.html.erb +3 -3
  19. data/app/views/{message_mailer → mailboxer/message_mailer}/reply_message_email.text.erb +2 -2
  20. data/app/views/{notification_mailer → mailboxer/notification_mailer}/new_notification_email.html.erb +0 -0
  21. data/app/views/{notification_mailer → mailboxer/notification_mailer}/new_notification_email.text.erb +0 -0
  22. data/db/migrate/20110511145103_create_mailboxer.rb +18 -14
  23. data/db/migrate/20131206080416_add_conversation_optout.rb +14 -0
  24. data/gemfiles/rails3.2.gemfile +2 -3
  25. data/gemfiles/rails4.0.gemfile +3 -4
  26. data/gemfiles/rails4.1.gemfile +7 -0
  27. data/lib/generators/mailboxer/install_generator.rb +1 -4
  28. data/lib/generators/mailboxer/namespacing_compatibility_generator.rb +22 -0
  29. data/lib/generators/mailboxer/templates/initializer.rb +8 -4
  30. data/lib/generators/mailboxer/templates/mailboxer_namespacing_compatibility.rb +24 -0
  31. data/lib/mailboxer.rb +7 -1
  32. data/lib/mailboxer/cleaner.rb +9 -0
  33. data/lib/mailboxer/engine.rb +1 -1
  34. data/lib/mailboxer/mail_dispatcher.rb +48 -0
  35. data/lib/mailboxer/models/messageable.rb +21 -20
  36. data/lib/mailboxer/version.rb +3 -0
  37. data/mailboxer.gemspec +16 -8
  38. data/spec/dummy/Gemfile +1 -1
  39. data/spec/dummy/app/models/duck.rb +2 -2
  40. data/spec/dummy/config/initializers/mailboxer.rb +4 -0
  41. data/spec/dummy/db/migrate/20120305103200_create_mailboxer.rb +18 -14
  42. data/spec/dummy/db/migrate/20131206080416_add_conversation_optout.rb +14 -0
  43. data/spec/dummy/db/schema.rb +30 -21
  44. data/spec/integration/message_and_receipt_spec.rb +212 -212
  45. data/spec/mailboxer/mail_dispatcher_spec.rb +114 -0
  46. data/spec/mailers/message_mailer_spec.rb +4 -4
  47. data/spec/mailers/notification_mailer_spec.rb +2 -2
  48. data/spec/models/conversation_spec.rb +148 -47
  49. data/spec/models/mailbox_spec.rb +50 -50
  50. data/spec/models/mailboxer_models_messageable_spec.rb +52 -52
  51. data/spec/models/message_spec.rb +1 -1
  52. data/spec/models/notification_spec.rb +50 -18
  53. data/spec/models/receipt_spec.rb +1 -1
  54. data/spec/spec_helper.rb +3 -0
  55. metadata +68 -57
  56. data/app/mailers/notification_mailer.rb +0 -21
  57. data/app/models/conversation.rb +0 -166
  58. data/app/models/message.rb +0 -68
  59. data/db/migrate/20110719110700_add_notified_object.rb +0 -17
  60. data/db/migrate/20110912163911_add_notification_code.rb +0 -13
  61. data/db/migrate/20111204163911_add_attachments.rb +0 -9
  62. data/db/migrate/20120813110712_rename_receipts_read.rb +0 -9
  63. data/db/migrate/20130305144212_add_global_notification_support.rb +0 -9
  64. data/gemfiles/rails3.0.gemfile +0 -8
  65. data/gemfiles/rails3.1.gemfile +0 -8
  66. data/lib/mailboxer/concerns/configurable_mailer.rb +0 -13
  67. data/spec/dummy/db/migrate/20120305103201_add_notified_object.rb +0 -17
  68. data/spec/dummy/db/migrate/20120305103202_add_notification_code.rb +0 -13
  69. data/spec/dummy/db/migrate/20120305103203_add_attachments.rb +0 -5
  70. data/spec/dummy/db/migrate/20120813110712_rename_receipts_read.rb +0 -9
  71. data/spec/dummy/db/migrate/20130305144212_add_global_notification_support.rb +0 -11
  72. data/spec/mailboxer/concerns/configurable_mailer_spec.rb +0 -27
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Receipt do
3
+ describe Mailboxer::Receipt do
4
4
 
5
5
  before do
6
6
  @entity1 = FactoryGirl.create(:user)
data/spec/spec_helper.rb CHANGED
@@ -25,6 +25,9 @@ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
25
25
  require 'factory_girl'
26
26
  Dir["#{File.dirname(__FILE__)}/factories/*.rb"].each {|f| require f}
27
27
 
28
+ # Shoulda Matchers
29
+ require 'shoulda/matchers'
30
+
28
31
  RSpec.configure do |config|
29
32
  # Remove this line if you don't want RSpec's should and should_not
30
33
  # methods or matchers
metadata CHANGED
@@ -1,139 +1,153 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mailboxer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.0
4
+ version: 0.12.0.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eduardo Casanova Cuesta
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-08-23 00:00:00.000000000 Z
11
+ date: 2014-04-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: foreigner
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - '>='
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: 0.9.1
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - '>='
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: 0.9.1
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rails
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - '>'
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: 3.0.0
33
+ version: 3.2.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - '>'
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: 3.0.0
40
+ version: 3.2.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: carrierwave
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - '>='
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
47
  version: 0.5.8
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - '>='
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: 0.5.8
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rspec-rails
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - '>='
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
61
  version: 2.6.1
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - '>='
66
+ - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: 2.6.1
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: appraisal
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - '>='
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 1.0.0
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 1.0.0
83
+ - !ruby/object:Gem::Dependency
84
+ name: shoulda-matchers
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
74
88
  - !ruby/object:Gem::Version
75
89
  version: '0'
76
90
  type: :development
77
91
  prerelease: false
78
92
  version_requirements: !ruby/object:Gem::Requirement
79
93
  requirements:
80
- - - '>='
94
+ - - ">="
81
95
  - !ruby/object:Gem::Version
82
96
  version: '0'
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: factory_girl
85
99
  requirement: !ruby/object:Gem::Requirement
86
100
  requirements:
87
- - - ~>
101
+ - - "~>"
88
102
  - !ruby/object:Gem::Version
89
103
  version: 2.6.0
90
104
  type: :development
91
105
  prerelease: false
92
106
  version_requirements: !ruby/object:Gem::Requirement
93
107
  requirements:
94
- - - ~>
108
+ - - "~>"
95
109
  - !ruby/object:Gem::Version
96
110
  version: 2.6.0
97
111
  - !ruby/object:Gem::Dependency
98
112
  name: forgery
99
113
  requirement: !ruby/object:Gem::Requirement
100
114
  requirements:
101
- - - '>='
115
+ - - ">="
102
116
  - !ruby/object:Gem::Version
103
117
  version: 0.3.6
104
118
  type: :development
105
119
  prerelease: false
106
120
  version_requirements: !ruby/object:Gem::Requirement
107
121
  requirements:
108
- - - '>='
122
+ - - ">="
109
123
  - !ruby/object:Gem::Version
110
124
  version: 0.3.6
111
125
  - !ruby/object:Gem::Dependency
112
126
  name: capybara
113
127
  requirement: !ruby/object:Gem::Requirement
114
128
  requirements:
115
- - - '>='
129
+ - - ">="
116
130
  - !ruby/object:Gem::Version
117
131
  version: 0.3.9
118
132
  type: :development
119
133
  prerelease: false
120
134
  version_requirements: !ruby/object:Gem::Requirement
121
135
  requirements:
122
- - - '>='
136
+ - - ">="
123
137
  - !ruby/object:Gem::Version
124
138
  version: 0.3.9
125
139
  - !ruby/object:Gem::Dependency
126
140
  name: sqlite3
127
141
  requirement: !ruby/object:Gem::Requirement
128
142
  requirements:
129
- - - '>='
143
+ - - ">="
130
144
  - !ruby/object:Gem::Version
131
145
  version: '0'
132
146
  type: :development
133
147
  prerelease: false
134
148
  version_requirements: !ruby/object:Gem::Requirement
135
149
  requirements:
136
- - - '>='
150
+ - - ">="
137
151
  - !ruby/object:Gem::Version
138
152
  version: '0'
139
153
  description: A Rails engine that allows any model to act as messageable, adding the
@@ -147,47 +161,48 @@ executables: []
147
161
  extensions: []
148
162
  extra_rdoc_files: []
149
163
  files:
150
- - .gitignore
151
- - .rspec
152
- - .travis.yml
153
- - .yardopts
164
+ - ".gitignore"
165
+ - ".rspec"
166
+ - ".travis.yml"
167
+ - ".yardopts"
154
168
  - Appraisals
155
169
  - Gemfile
156
170
  - LICENSE.txt
157
171
  - README.md
158
172
  - Rakefile
159
- - app/mailers/message_mailer.rb
160
- - app/mailers/notification_mailer.rb
161
- - app/models/conversation.rb
162
- - app/models/mailbox.rb
163
- - app/models/message.rb
164
- - app/models/notification.rb
165
- - app/models/receipt.rb
173
+ - app/mailers/mailboxer/base_mailer.rb
174
+ - app/mailers/mailboxer/message_mailer.rb
175
+ - app/mailers/mailboxer/notification_mailer.rb
176
+ - app/models/mailboxer/conversation.rb
177
+ - app/models/mailboxer/conversation/opt_out.rb
178
+ - app/models/mailboxer/mailbox.rb
179
+ - app/models/mailboxer/message.rb
180
+ - app/models/mailboxer/notification.rb
181
+ - app/models/mailboxer/receipt.rb
166
182
  - app/uploaders/attachment_uploader.rb
167
- - app/views/message_mailer/new_message_email.html.erb
168
- - app/views/message_mailer/new_message_email.text.erb
169
- - app/views/message_mailer/reply_message_email.html.erb
170
- - app/views/message_mailer/reply_message_email.text.erb
171
- - app/views/notification_mailer/new_notification_email.html.erb
172
- - app/views/notification_mailer/new_notification_email.text.erb
183
+ - app/views/mailboxer/message_mailer/new_message_email.html.erb
184
+ - app/views/mailboxer/message_mailer/new_message_email.text.erb
185
+ - app/views/mailboxer/message_mailer/reply_message_email.html.erb
186
+ - app/views/mailboxer/message_mailer/reply_message_email.text.erb
187
+ - app/views/mailboxer/notification_mailer/new_notification_email.html.erb
188
+ - app/views/mailboxer/notification_mailer/new_notification_email.text.erb
173
189
  - config/locales/en.yml
174
190
  - db/migrate/20110511145103_create_mailboxer.rb
175
- - db/migrate/20110719110700_add_notified_object.rb
176
- - db/migrate/20110912163911_add_notification_code.rb
177
- - db/migrate/20111204163911_add_attachments.rb
178
- - db/migrate/20120813110712_rename_receipts_read.rb
179
- - db/migrate/20130305144212_add_global_notification_support.rb
180
- - gemfiles/rails3.0.gemfile
181
- - gemfiles/rails3.1.gemfile
191
+ - db/migrate/20131206080416_add_conversation_optout.rb
182
192
  - gemfiles/rails3.2.gemfile
183
193
  - gemfiles/rails4.0.gemfile
194
+ - gemfiles/rails4.1.gemfile
184
195
  - lib/generators/mailboxer/install_generator.rb
196
+ - lib/generators/mailboxer/namespacing_compatibility_generator.rb
185
197
  - lib/generators/mailboxer/templates/initializer.rb
198
+ - lib/generators/mailboxer/templates/mailboxer_namespacing_compatibility.rb
186
199
  - lib/generators/mailboxer/views_generator.rb
187
200
  - lib/mailboxer.rb
188
- - lib/mailboxer/concerns/configurable_mailer.rb
201
+ - lib/mailboxer/cleaner.rb
189
202
  - lib/mailboxer/engine.rb
203
+ - lib/mailboxer/mail_dispatcher.rb
190
204
  - lib/mailboxer/models/messageable.rb
205
+ - lib/mailboxer/version.rb
191
206
  - mailboxer.gemspec
192
207
  - spec/dummy/.gitignore
193
208
  - spec/dummy/Gemfile
@@ -223,11 +238,7 @@ files:
223
238
  - spec/dummy/db/migrate/20110306002940_create_ducks.rb
224
239
  - spec/dummy/db/migrate/20110306015107_create_cylons.rb
225
240
  - spec/dummy/db/migrate/20120305103200_create_mailboxer.rb
226
- - spec/dummy/db/migrate/20120305103201_add_notified_object.rb
227
- - spec/dummy/db/migrate/20120305103202_add_notification_code.rb
228
- - spec/dummy/db/migrate/20120305103203_add_attachments.rb
229
- - spec/dummy/db/migrate/20120813110712_rename_receipts_read.rb
230
- - spec/dummy/db/migrate/20130305144212_add_global_notification_support.rb
241
+ - spec/dummy/db/migrate/20131206080416_add_conversation_optout.rb
231
242
  - spec/dummy/db/schema.rb
232
243
  - spec/dummy/public/404.html
233
244
  - spec/dummy/public/422.html
@@ -242,7 +253,7 @@ files:
242
253
  - spec/factories/user.rb
243
254
  - spec/integration/message_and_receipt_spec.rb
244
255
  - spec/integration/navigation_spec.rb
245
- - spec/mailboxer/concerns/configurable_mailer_spec.rb
256
+ - spec/mailboxer/mail_dispatcher_spec.rb
246
257
  - spec/mailboxer_spec.rb
247
258
  - spec/mailers/message_mailer_spec.rb
248
259
  - spec/mailers/notification_mailer_spec.rb
@@ -264,17 +275,17 @@ require_paths:
264
275
  - lib
265
276
  required_ruby_version: !ruby/object:Gem::Requirement
266
277
  requirements:
267
- - - '>='
278
+ - - ">="
268
279
  - !ruby/object:Gem::Version
269
280
  version: '0'
270
281
  required_rubygems_version: !ruby/object:Gem::Requirement
271
282
  requirements:
272
- - - '>='
283
+ - - ">"
273
284
  - !ruby/object:Gem::Version
274
- version: '0'
285
+ version: 1.3.1
275
286
  requirements: []
276
287
  rubyforge_project:
277
- rubygems_version: 2.0.5
288
+ rubygems_version: 2.2.2
278
289
  signing_key:
279
290
  specification_version: 4
280
291
  summary: Messaging system for rails apps.
@@ -1,21 +0,0 @@
1
- class NotificationMailer < ActionMailer::Base
2
- default :from => Mailboxer.default_from
3
- #Sends and email for indicating a new notification to a receiver.
4
- #It calls new_notification_email.
5
- def send_email(notification,receiver)
6
- new_notification_email(notification,receiver)
7
- end
8
-
9
- include ActionView::Helpers::SanitizeHelper
10
-
11
- #Sends an email for indicating a new message for the receiver
12
- def new_notification_email(notification,receiver)
13
- @notification = notification
14
- @receiver = receiver
15
- subject = notification.subject.to_s
16
- subject = strip_tags(subject) unless subject.html_safe?
17
- mail :to => receiver.send(Mailboxer.email_method,notification),
18
- :subject => t('mailboxer.notification_mailer.subject', :subject => subject),
19
- :template_name => 'new_notification_email'
20
- end
21
- end
@@ -1,166 +0,0 @@
1
- class Conversation < ActiveRecord::Base
2
- attr_accessible :subject if Mailboxer.protected_attributes?
3
-
4
- has_many :messages, :dependent => :destroy
5
- has_many :receipts, :through => :messages
6
-
7
- validates_presence_of :subject
8
-
9
- before_validation :clean
10
-
11
- scope :participant, lambda {|participant|
12
- select('DISTINCT conversations.*').
13
- where('notifications.type'=> Message.name).
14
- order("conversations.updated_at DESC").
15
- joins(:receipts).merge(Receipt.recipient(participant))
16
- }
17
- scope :inbox, lambda {|participant|
18
- participant(participant).merge(Receipt.inbox.not_trash.not_deleted)
19
- }
20
- scope :sentbox, lambda {|participant|
21
- participant(participant).merge(Receipt.sentbox.not_trash.not_deleted)
22
- }
23
- scope :trash, lambda {|participant|
24
- participant(participant).merge(Receipt.trash)
25
- }
26
- scope :unread, lambda {|participant|
27
- participant(participant).merge(Receipt.is_unread)
28
- }
29
- scope :not_trash, lambda {|participant|
30
- participant(participant).merge(Receipt.not_trash)
31
- }
32
-
33
- #Mark the conversation as read for one of the participants
34
- def mark_as_read(participant)
35
- return if participant.nil?
36
- self.receipts_for(participant).mark_as_read
37
- end
38
-
39
- #Mark the conversation as unread for one of the participants
40
- def mark_as_unread(participant)
41
- return if participant.nil?
42
- self.receipts_for(participant).mark_as_unread
43
- end
44
-
45
- #Move the conversation to the trash for one of the participants
46
- def move_to_trash(participant)
47
- return if participant.nil?
48
- self.receipts_for(participant).move_to_trash
49
- end
50
-
51
- #Takes the conversation out of the trash for one of the participants
52
- def untrash(participant)
53
- return if participant.nil?
54
- self.receipts_for(participant).untrash
55
- end
56
-
57
- #Mark the conversation as deleted for one of the participants
58
- def mark_as_deleted(participant)
59
- return if participant.nil?
60
- return self.receipts_for(participant).mark_as_deleted
61
- end
62
-
63
- #Returns an array of participants
64
- def recipients
65
- if self.last_message
66
- recps = self.last_message.recipients
67
- recps = recps.is_a?(Array) ? recps : [recps]
68
- recps
69
- else
70
- []
71
- end
72
- end
73
-
74
- #Returns an array of participants
75
- def participants
76
- recipients
77
- end
78
-
79
- #Originator of the conversation.
80
- def originator
81
- @originator ||= self.original_message.sender
82
- end
83
-
84
- #First message of the conversation.
85
- def original_message
86
- @original_message ||= self.messages.order('created_at').first
87
- end
88
-
89
- #Sender of the last message.
90
- def last_sender
91
- @last_sender ||= self.last_message.sender
92
- end
93
-
94
- #Last message in the conversation.
95
- def last_message
96
- @last_message ||= self.messages.order('created_at DESC').first
97
- end
98
-
99
- #Returns the receipts of the conversation for one participants
100
- def receipts_for(participant)
101
- Receipt.conversation(self).recipient(participant)
102
- end
103
-
104
- #Returns the number of messages of the conversation
105
- def count_messages
106
- Message.conversation(self).count
107
- end
108
-
109
- #Returns true if the messageable is a participant of the conversation
110
- def is_participant?(participant)
111
- return false if participant.nil?
112
- self.receipts_for(participant).count != 0
113
- end
114
-
115
- #Adds a new participant to the conversation
116
- def add_participant(participant)
117
- messages = self.messages
118
- messages.each do |message|
119
- receipt = Receipt.new
120
- receipt.notification = message
121
- receipt.is_read = false
122
- receipt.receiver = participant
123
- receipt.mailbox_type = 'inbox'
124
- receipt.updated_at = message.updated_at
125
- receipt.created_at = message.created_at
126
- receipt.save
127
- end
128
- end
129
-
130
- #Returns true if the participant has at least one trashed message of the conversation
131
- def is_trashed?(participant)
132
- return false if participant.nil?
133
- self.receipts_for(participant).trash.count != 0
134
- end
135
-
136
- #Returns true if the participant has deleted the conversation
137
- def is_deleted?(participant)
138
- return false if participant.nil?
139
- return self.receipts_for(participant).trash.count==0
140
- end
141
-
142
- #Returns true if the participant has trashed all the messages of the conversation
143
- def is_completely_trashed?(participant)
144
- return false if participant.nil?
145
- self.receipts_for(participant).trash.count == self.receipts_for(participant).count
146
- end
147
-
148
- def is_read?(participant)
149
- !self.is_unread?(participant)
150
- end
151
-
152
- #Returns true if the participant has at least one unread message of the conversation
153
- def is_unread?(participant)
154
- return false if participant.nil?
155
- self.receipts_for(participant).not_trash.is_unread.count != 0
156
- end
157
-
158
- protected
159
-
160
- include ActionView::Helpers::SanitizeHelper
161
-
162
- #Use the default sanitize to clean the conversation subject
163
- def clean
164
- self.subject = sanitize self.subject
165
- end
166
- end