simple-navigation 3.14.0 → 4.0.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 +4 -4
- data/.gitignore +3 -0
- data/.rspec +1 -0
- data/.travis.yml +10 -2
- data/CHANGELOG.md +400 -0
- data/Guardfile +4 -2
- data/README.md +1 -1
- data/gemfiles/.bundle/config +2 -0
- data/gemfiles/rails-3-2-stable.gemfile +10 -0
- data/gemfiles/rails-4-1-stable.gemfile +6 -0
- data/gemfiles/rails-4-2-stable.gemfile +7 -0
- data/generators/navigation_config/navigation_config_generator.rb +0 -1
- data/generators/navigation_config/templates/config/navigation.rb +18 -15
- data/lib/simple_navigation.rb +25 -42
- data/lib/simple_navigation/adapters/rails.rb +1 -24
- data/lib/simple_navigation/adapters/sinatra.rb +2 -11
- data/lib/simple_navigation/config_file.rb +36 -0
- data/lib/simple_navigation/config_file_finder.rb +42 -0
- data/lib/simple_navigation/{core/configuration.rb → configuration.rb} +7 -1
- data/lib/simple_navigation/{rendering/helpers.rb → helpers.rb} +0 -4
- data/lib/simple_navigation/{core/item.rb → item.rb} +76 -85
- data/lib/simple_navigation/{core/item_adapter.rb → item_adapter.rb} +3 -17
- data/lib/simple_navigation/{core/item_container.rb → item_container.rb} +23 -14
- data/lib/simple_navigation/{core/items_provider.rb → items_provider.rb} +0 -0
- data/lib/simple_navigation/railtie.rb +7 -0
- data/lib/simple_navigation/renderer.rb +12 -0
- data/lib/simple_navigation/{rendering/renderer → renderer}/base.rb +1 -1
- data/lib/simple_navigation/{rendering/renderer → renderer}/breadcrumbs.rb +0 -0
- data/lib/simple_navigation/{rendering/renderer → renderer}/json.rb +2 -0
- data/lib/simple_navigation/{rendering/renderer → renderer}/links.rb +0 -0
- data/lib/simple_navigation/{rendering/renderer → renderer}/list.rb +0 -0
- data/lib/simple_navigation/{rendering/renderer → renderer}/text.rb +0 -0
- data/lib/simple_navigation/version.rb +1 -1
- data/simple-navigation.gemspec +5 -4
- data/spec/fake_app/config/navigation.rb +6 -0
- data/spec/fake_app/rails_app.rb +35 -0
- data/spec/initializers/coveralls.rb +3 -0
- data/spec/initializers/have_css_matcher.rb +8 -3
- data/spec/initializers/memfs.rb +7 -0
- data/spec/initializers/rails.rb +4 -0
- data/spec/initializers/rspec.rb +7 -0
- data/spec/integration/rendering_navigation_spec.rb +12 -0
- data/spec/{lib/simple_navigation → simple_navigation}/adapters/padrino_spec.rb +0 -2
- data/spec/{lib/simple_navigation → simple_navigation}/adapters/rails_spec.rb +36 -93
- data/spec/{lib/simple_navigation → simple_navigation}/adapters/sinatra_spec.rb +4 -6
- data/spec/simple_navigation/config_file_finder_spec.rb +50 -0
- data/spec/simple_navigation/config_file_spec.rb +25 -0
- data/spec/{lib/simple_navigation/core → simple_navigation}/configuration_spec.rb +29 -19
- data/spec/{lib/simple_navigation/rendering → simple_navigation}/helpers_spec.rb +10 -13
- data/spec/{lib/simple_navigation/core → simple_navigation}/item_adapter_spec.rb +14 -11
- data/spec/{lib/simple_navigation/core → simple_navigation}/item_container_spec.rb +130 -42
- data/spec/simple_navigation/item_spec.rb +467 -0
- data/spec/{lib/simple_navigation/core → simple_navigation}/items_provider_spec.rb +1 -3
- data/spec/{lib/simple_navigation/rendering → simple_navigation}/renderer/base_spec.rb +34 -36
- data/spec/{lib/simple_navigation/rendering → simple_navigation}/renderer/breadcrumbs_spec.rb +4 -7
- data/spec/{lib/simple_navigation/rendering → simple_navigation}/renderer/json_spec.rb +5 -11
- data/spec/{lib/simple_navigation/rendering → simple_navigation}/renderer/links_spec.rb +5 -8
- data/spec/{lib/simple_navigation/rendering → simple_navigation}/renderer/list_spec.rb +4 -7
- data/spec/{lib/simple_navigation/rendering → simple_navigation}/renderer/text_spec.rb +4 -7
- data/spec/simple_navigation_spec.rb +190 -0
- data/spec/spec_helper.rb +29 -35
- metadata +103 -68
- data/CHANGELOG +0 -292
- data/lib/simple_navigation/core.rb +0 -5
- data/lib/simple_navigation/rails_controller_methods.rb +0 -164
- data/lib/simple_navigation/rendering.rb +0 -12
- data/rails/init.rb +0 -1
- data/spec/lib/simple_navigation/core/item_spec.rb +0 -703
- data/spec/lib/simple_navigation/rails_controller_methods_spec.rb +0 -270
- data/spec/lib/simple_navigation_spec.rb +0 -300
@@ -0,0 +1,467 @@
|
|
1
|
+
module SimpleNavigation
|
2
|
+
describe Item do
|
3
|
+
let!(:item_container) { ItemContainer.new }
|
4
|
+
|
5
|
+
let(:adapter) { double(:adapter) }
|
6
|
+
let(:item_args) { [item_container, :my_key, 'name', url, options] }
|
7
|
+
let(:item) { Item.new(*item_args) }
|
8
|
+
let(:options) { Hash.new }
|
9
|
+
let(:url) { 'url' }
|
10
|
+
|
11
|
+
before { allow(SimpleNavigation).to receive_messages(adapter: adapter) }
|
12
|
+
|
13
|
+
describe '#highlights_on' do
|
14
|
+
let(:options) {{ highlights_on: :test }}
|
15
|
+
|
16
|
+
it "returns the item's highlights_on option" do
|
17
|
+
expect(item.highlights_on).to eq :test
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe '#initialize' do
|
22
|
+
context 'when there is a sub_navigation' do
|
23
|
+
let(:subnav_container) { double(:subnav_container).as_null_object }
|
24
|
+
|
25
|
+
shared_examples 'creating sub navigation container' do
|
26
|
+
it 'creates a sub navigation container with a level+1' do
|
27
|
+
expect(item.sub_navigation.level).to eq 2
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'when a block is given' do
|
32
|
+
it_behaves_like 'creating sub navigation container' do
|
33
|
+
let(:item) { Item.new(*item_args) {} }
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'calls the block' do
|
37
|
+
allow(ItemContainer).to receive_messages(new: subnav_container)
|
38
|
+
|
39
|
+
expect{ |blk|
|
40
|
+
Item.new(*item_args, &blk)
|
41
|
+
}.to yield_with_args(subnav_container)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'when no block is given' do
|
46
|
+
context 'and items are given' do
|
47
|
+
let(:items) { [] }
|
48
|
+
let(:options) {{ items: items }}
|
49
|
+
|
50
|
+
it_behaves_like 'creating sub navigation container'
|
51
|
+
|
52
|
+
it "sets the items on the subnav_container" do
|
53
|
+
expect(item.sub_navigation.items).to eq items
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context 'and no items are given' do
|
58
|
+
it "doesn't create a new ItemContainer" do
|
59
|
+
item = Item.new(*item_args)
|
60
|
+
expect(item.sub_navigation).to be_nil
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
context 'when a :method option is given' do
|
67
|
+
let(:options) {{ method: :delete }}
|
68
|
+
|
69
|
+
it "sets the item's method" do
|
70
|
+
expect(item.method).to eq :delete
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
context 'when no :method option is given' do
|
75
|
+
it "sets the item's method to nil" do
|
76
|
+
expect(item.method).to be_nil
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
context 'when an :highlights_on option is given' do
|
81
|
+
let(:highlights_on) { double(:highlights_on) }
|
82
|
+
let(:options) {{ highlights_on: highlights_on }}
|
83
|
+
|
84
|
+
it "sets the item's highlights_on" do
|
85
|
+
expect(item.highlights_on).to eq highlights_on
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
context 'when no :highlights_on option is given' do
|
90
|
+
it "sets the item's highlights_on to nil" do
|
91
|
+
expect(item.highlights_on).to be_nil
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
context 'when a url is given' do
|
96
|
+
context 'and it is a string' do
|
97
|
+
it "sets the item's url accordingly" do
|
98
|
+
expect(item.url).to eq 'url'
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
context 'and it is a proc' do
|
103
|
+
let(:url) { proc{ "my_" + "url" } }
|
104
|
+
|
105
|
+
it "sets the item's url accordingly" do
|
106
|
+
expect(item.url).to eq 'my_url'
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
context 'and it is nil' do
|
111
|
+
let(:url) { nil }
|
112
|
+
|
113
|
+
it "sets the item's url accordingly" do
|
114
|
+
expect(item.url).to be_nil
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
context 'when no url nor options is specified' do
|
120
|
+
let(:item_args) { [item_container, :my_key, 'name'] }
|
121
|
+
|
122
|
+
it "sets the item's url to nil" do
|
123
|
+
expect(item.url).to be_nil
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
context 'when only a url is given' do
|
128
|
+
let(:item_args) { [item_container, :my_key, 'name', 'url'] }
|
129
|
+
|
130
|
+
it "set the item's url accordingly" do
|
131
|
+
expect(item.url).to eq 'url'
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
context 'when url and options are given' do
|
136
|
+
let(:options) {{ html: { option: true } }}
|
137
|
+
|
138
|
+
before { allow(adapter).to receive_messages(current_page?: false) }
|
139
|
+
|
140
|
+
it "set the item's url accordingly" do
|
141
|
+
expect(item.url).to eq 'url'
|
142
|
+
end
|
143
|
+
|
144
|
+
it "sets the item's html_options accordingly" do
|
145
|
+
allow(item).to \
|
146
|
+
receive_messages(selected_by_subnav?: false,
|
147
|
+
selected_by_condition?: false)
|
148
|
+
expect(item.html_options).to include(option: true)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
describe '#link_html_options' do
|
154
|
+
let(:options) {{ link_html: :test }}
|
155
|
+
|
156
|
+
it "returns the item's link_html option" do
|
157
|
+
expect(item.link_html_options).to eq :test
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
describe '#method' do
|
162
|
+
let(:options) {{ method: :test }}
|
163
|
+
|
164
|
+
it "returns the item's method option" do
|
165
|
+
expect(item.method).to eq :test
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
describe '#name' do
|
170
|
+
before do
|
171
|
+
allow(SimpleNavigation.config).to \
|
172
|
+
receive_messages(name_generator: proc{ |name| "<span>#{name}</span>" })
|
173
|
+
end
|
174
|
+
|
175
|
+
context 'when no option is given' do
|
176
|
+
context 'and the name_generator uses only the name' do
|
177
|
+
it 'uses the default name_generator' do
|
178
|
+
expect(item.name).to eq '<span>name</span>'
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
context 'and the name_generator uses only the item itself' do
|
183
|
+
before do
|
184
|
+
allow(SimpleNavigation.config).to \
|
185
|
+
receive_messages(name_generator: proc{ |name, item| "<span>#{item.key}</span>" })
|
186
|
+
end
|
187
|
+
|
188
|
+
it 'uses the default name_generator' do
|
189
|
+
expect(item.name).to eq '<span>my_key</span>'
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
context 'when the :apply_generator is false' do
|
195
|
+
it "returns the item's name" do
|
196
|
+
expect(item.name(apply_generator: false)).to eq 'name'
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
context 'when a block is given' do
|
201
|
+
let(:item_args) { [item_container, :my_key, -> { 'Name in block' }, url, options] }
|
202
|
+
|
203
|
+
it "returns the item's name that is defined in the block" do
|
204
|
+
expect(item.name).to include 'Name in block'
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
describe '#selected?' do
|
210
|
+
context 'when the item has no :highlights_on option' do
|
211
|
+
before { allow(SimpleNavigation).to receive_messages(config: config) }
|
212
|
+
|
213
|
+
context 'and auto highlighting is off' do
|
214
|
+
let(:config) { double(:config, auto_highlight: false) }
|
215
|
+
|
216
|
+
it 'returns false' do
|
217
|
+
expect(item.selected?).to be false
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
context 'and auto highlighting is on' do
|
222
|
+
let(:config) { double(:config, ignore_query_params_on_auto_highlight: true, ignore_anchors_on_auto_highlight: true, auto_highlight: true) }
|
223
|
+
|
224
|
+
context "and the current url matches the item's url" do
|
225
|
+
before { allow(adapter).to receive_messages(current_page?: true) }
|
226
|
+
|
227
|
+
it 'returns true' do
|
228
|
+
expect(item.selected?).to be true
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
context "and the current url does not match the item's url" do
|
233
|
+
let(:config) do
|
234
|
+
double(:config, auto_highlight: false, highlight_on_subpath: false)
|
235
|
+
end
|
236
|
+
|
237
|
+
before { allow(adapter).to receive_messages(current_page?: false) }
|
238
|
+
|
239
|
+
it 'returns false' do
|
240
|
+
expect(item.selected?).to be false
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
context 'and highlights_on_subpath is on' do
|
245
|
+
let(:config) do
|
246
|
+
double(:config, auto_highlight: true, highlight_on_subpath: true, ignore_query_params_on_auto_highlight: true, ignore_anchors_on_auto_highlight: true)
|
247
|
+
end
|
248
|
+
|
249
|
+
context "and the current url is a sub path of the item's url" do
|
250
|
+
before do
|
251
|
+
allow(adapter).to \
|
252
|
+
receive_messages(current_page?: false, request_uri: 'url/test')
|
253
|
+
end
|
254
|
+
|
255
|
+
it 'returns true' do
|
256
|
+
expect(item.selected?).to be true
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
context "and the current url is not a sub path of the item's url" do
|
261
|
+
before do
|
262
|
+
allow(adapter).to \
|
263
|
+
receive_messages(current_page?: false, request_uri: 'other/test')
|
264
|
+
end
|
265
|
+
|
266
|
+
it 'returns false' do
|
267
|
+
expect(item.selected?).to be false
|
268
|
+
end
|
269
|
+
end
|
270
|
+
end
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
context 'when the item has a :highlights_on option' do
|
275
|
+
context 'and it is a regular expression' do
|
276
|
+
before { allow(adapter).to receive_messages(request_uri: '/test') }
|
277
|
+
|
278
|
+
context 'and the current url matches the expression' do
|
279
|
+
let(:options) {{ highlights_on: /test/ }}
|
280
|
+
|
281
|
+
it 'returns true' do
|
282
|
+
expect(item.selected?).to be true
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
context 'and the current url does not match the expression' do
|
287
|
+
let(:options) {{ highlights_on: /other/ }}
|
288
|
+
|
289
|
+
it 'returns false' do
|
290
|
+
expect(item.selected?).to be false
|
291
|
+
end
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|
295
|
+
context 'and it is a callable object' do
|
296
|
+
context 'and the call returns true' do
|
297
|
+
let(:options) {{ highlights_on: -> { true } }}
|
298
|
+
|
299
|
+
it 'returns true' do
|
300
|
+
expect(item.selected?).to be true
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
context 'and the call returns false' do
|
305
|
+
let(:options) {{ highlights_on: -> { false } }}
|
306
|
+
|
307
|
+
it 'returns false' do
|
308
|
+
expect(item.selected?).to be false
|
309
|
+
end
|
310
|
+
end
|
311
|
+
end
|
312
|
+
|
313
|
+
context 'and it is the :subpath symbol' do
|
314
|
+
let(:options) {{ highlights_on: :subpath }}
|
315
|
+
|
316
|
+
context "and the current url is a sub path of the item's url" do
|
317
|
+
before do
|
318
|
+
allow(adapter).to receive_messages(request_uri: 'url/test')
|
319
|
+
end
|
320
|
+
|
321
|
+
it 'returns true' do
|
322
|
+
expect(item.selected?).to be true
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
326
|
+
context "and the current url is not a sub path of the item's url" do
|
327
|
+
before do
|
328
|
+
allow(adapter).to receive_messages(request_uri: 'other/test')
|
329
|
+
end
|
330
|
+
|
331
|
+
it 'returns false' do
|
332
|
+
expect(item.selected?).to be false
|
333
|
+
end
|
334
|
+
end
|
335
|
+
end
|
336
|
+
|
337
|
+
context 'and it is non usable' do
|
338
|
+
let(:options) {{ highlights_on: :hello }}
|
339
|
+
|
340
|
+
it 'raises an exception' do
|
341
|
+
expect{ item.selected? }.to raise_error
|
342
|
+
end
|
343
|
+
end
|
344
|
+
end
|
345
|
+
end
|
346
|
+
|
347
|
+
describe '#selected_class' do
|
348
|
+
context 'when the item is selected' do
|
349
|
+
before { allow(item).to receive_messages(selected?: true) }
|
350
|
+
|
351
|
+
it 'returns the default selected_class' do
|
352
|
+
expect(item.selected_class).to eq 'selected'
|
353
|
+
end
|
354
|
+
|
355
|
+
context 'and selected_class is defined in the context' do
|
356
|
+
before { allow(item_container).to receive_messages(selected_class: 'defined') }
|
357
|
+
|
358
|
+
it "returns the context's selected_class" do
|
359
|
+
expect(item.selected_class).to eq 'defined'
|
360
|
+
end
|
361
|
+
end
|
362
|
+
end
|
363
|
+
|
364
|
+
context 'when the item is not selected' do
|
365
|
+
before { allow(item).to receive_messages(selected?: false) }
|
366
|
+
|
367
|
+
it 'returns nil' do
|
368
|
+
expect(item.selected_class).to be_nil
|
369
|
+
end
|
370
|
+
end
|
371
|
+
end
|
372
|
+
|
373
|
+
describe ':html_options argument' do
|
374
|
+
let(:selected_classes) { 'selected simple-navigation-active-leaf' }
|
375
|
+
|
376
|
+
context 'when the :class option is given' do
|
377
|
+
let(:options) {{ html: { class: 'my_class' } }}
|
378
|
+
|
379
|
+
context 'and the item is selected' do
|
380
|
+
before { allow(item).to receive_messages(selected?: true, selected_by_condition?: true) }
|
381
|
+
|
382
|
+
it "adds the specified class to the item's html classes" do
|
383
|
+
expect(item.html_options[:class]).to include('my_class')
|
384
|
+
end
|
385
|
+
|
386
|
+
it "doesn't replace the default html classes of a selected item" do
|
387
|
+
expect(item.html_options[:class]).to include(selected_classes)
|
388
|
+
end
|
389
|
+
end
|
390
|
+
|
391
|
+
context "and the item isn't selected" do
|
392
|
+
before { allow(item).to receive_messages(selected?: false, selected_by_condition?: false) }
|
393
|
+
|
394
|
+
it "sets the specified class as the item's html classes" do
|
395
|
+
expect(item.html_options[:class]).to include('my_class')
|
396
|
+
end
|
397
|
+
end
|
398
|
+
end
|
399
|
+
|
400
|
+
context "when the :class option isn't given" do
|
401
|
+
context 'and the item is selected' do
|
402
|
+
before { allow(item).to receive_messages(selected?: true, selected_by_condition?: true) }
|
403
|
+
|
404
|
+
it "sets the default html classes of a selected item" do
|
405
|
+
expect(item.html_options[:class]).to include(selected_classes)
|
406
|
+
end
|
407
|
+
end
|
408
|
+
|
409
|
+
context "and the item isn't selected" do
|
410
|
+
before { allow(item).to receive_messages(selected?: false, selected_by_condition?: false) }
|
411
|
+
|
412
|
+
it "doesn't set any html class on the item" do
|
413
|
+
expect(item.html_options[:class]).to be_blank
|
414
|
+
end
|
415
|
+
end
|
416
|
+
end
|
417
|
+
|
418
|
+
shared_examples 'generating id' do |id|
|
419
|
+
it "sets the item's html id to the specified id" do
|
420
|
+
expect(item.html_options[:id]).to eq id
|
421
|
+
end
|
422
|
+
end
|
423
|
+
|
424
|
+
describe 'when the :id option is given' do
|
425
|
+
let(:options) {{ html: { id: 'my_id' } }}
|
426
|
+
|
427
|
+
before do
|
428
|
+
allow(SimpleNavigation.config).to receive_messages(autogenerate_item_ids: generate_ids)
|
429
|
+
allow(item).to receive_messages(selected?: false, selected_by_condition?: false)
|
430
|
+
end
|
431
|
+
|
432
|
+
context 'and :autogenerate_item_ids is true' do
|
433
|
+
let(:generate_ids) { true }
|
434
|
+
|
435
|
+
it_behaves_like 'generating id', 'my_id'
|
436
|
+
end
|
437
|
+
|
438
|
+
context 'and :autogenerate_item_ids is false' do
|
439
|
+
let(:generate_ids) { false }
|
440
|
+
|
441
|
+
it_behaves_like 'generating id', 'my_id'
|
442
|
+
end
|
443
|
+
end
|
444
|
+
|
445
|
+
context "when the :id option isn't given" do
|
446
|
+
before do
|
447
|
+
allow(SimpleNavigation.config).to receive_messages(autogenerate_item_ids: generate_ids)
|
448
|
+
allow(item).to receive_messages(selected?: false, selected_by_condition?: false)
|
449
|
+
end
|
450
|
+
|
451
|
+
context 'and :autogenerate_item_ids is true' do
|
452
|
+
let(:generate_ids) { true }
|
453
|
+
|
454
|
+
it_behaves_like 'generating id', 'my_key'
|
455
|
+
end
|
456
|
+
|
457
|
+
context 'and :autogenerate_item_ids is false' do
|
458
|
+
let(:generate_ids) { false }
|
459
|
+
|
460
|
+
it "doesn't set any html id on the item" do
|
461
|
+
expect(item.html_options[:id]).to be_blank
|
462
|
+
end
|
463
|
+
end
|
464
|
+
end
|
465
|
+
end
|
466
|
+
end
|
467
|
+
end
|