sevencop 0.12.1 → 0.13.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/Gemfile.lock +1 -1
- data/README.md +18 -37
- data/config/default.yml +7 -14
- data/lib/rubocop/cop/sevencop/method_definition_keyword_arguments_ordered.rb +58 -0
- data/lib/sevencop/version.rb +1 -1
- data/lib/sevencop.rb +1 -2
- metadata +3 -4
- data/lib/rubocop/cop/sevencop/factory_bot_create_list.rb +0 -95
- data/lib/rubocop/cop/sevencop/redundant_existence_check.rb +0 -188
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ed778fc5bb1459cd5c3c35812b5274177e48515b434b2581c897f40ae6d47448
|
4
|
+
data.tar.gz: 179393f59351517e7d510cdf5a1a4c0762d2b2f64186f0f8470017125ae42d77
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cc12be9dc75e7507094a9349560ce08f8e9d5e61755837d2747fd101763b51885383b4d4f3416571303ea9e8e593ed0dc99cc6581206c248a82a41c5ce53a874
|
7
|
+
data.tar.gz: 96286dac7849f571eac18cfde45e76b81044f0381246943082f003abab28109b9f1b19c9127e013a260d1deb7654b6e67a03133714caa9d86b02dc6830645660
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -88,25 +88,6 @@ belongs_to :group, options
|
|
88
88
|
|
89
89
|
This is useful for migration of `config.active_record.belongs_to_required_by_default`.
|
90
90
|
|
91
|
-
### Sevencop/FactoryBotCreateList
|
92
|
-
|
93
|
-
Finds possible substitutions for `FactoryBot.create_list`.
|
94
|
-
|
95
|
-
```ruby
|
96
|
-
# bad
|
97
|
-
Array.new(2) do
|
98
|
-
create(:user)
|
99
|
-
end
|
100
|
-
|
101
|
-
# good
|
102
|
-
create_list(:user, 2)
|
103
|
-
|
104
|
-
# good
|
105
|
-
Array.new(2) do |i|
|
106
|
-
create(:user, order: i)
|
107
|
-
end
|
108
|
-
```
|
109
|
-
|
110
91
|
### Sevencop/HashLiteralOrder
|
111
92
|
|
112
93
|
Sort Hash literal entries by key.
|
@@ -145,6 +126,24 @@ RSpec.describe User
|
|
145
126
|
RSpec.describe User, type: :request
|
146
127
|
```
|
147
128
|
|
129
|
+
### Sevencop/MethodDefinitionKeywordArgumentsOrdered
|
130
|
+
|
131
|
+
Sort method definition keyword arguments in alphabetical order.
|
132
|
+
|
133
|
+
```ruby
|
134
|
+
# bad
|
135
|
+
def foo(b:, a:); end
|
136
|
+
|
137
|
+
# good
|
138
|
+
def foo(a:, b:); end
|
139
|
+
|
140
|
+
# bad
|
141
|
+
def foo(c:, d:, b: 1, a: 2); end
|
142
|
+
|
143
|
+
# good
|
144
|
+
def foo(c:, d:, a: 2, b: 1); end
|
145
|
+
```
|
146
|
+
|
148
147
|
### Sevencop/MethodDefinitionMultilineArguments
|
149
148
|
|
150
149
|
Inserts new lines between method definition parameters.
|
@@ -183,24 +182,6 @@ reorder('field(id, ?)', a)
|
|
183
182
|
reorder(Arel.sql('field(id, ?)'), a)
|
184
183
|
```
|
185
184
|
|
186
|
-
### Sevencop/RedundantExistenceCheck
|
187
|
-
|
188
|
-
Identifies redundant existent check before file operation.
|
189
|
-
|
190
|
-
```ruby
|
191
|
-
# bad
|
192
|
-
FileUtils.mkdir(a) unless FileTest.exist?(a)
|
193
|
-
|
194
|
-
# good
|
195
|
-
FileUtils.mkdir_p(a)
|
196
|
-
|
197
|
-
# bad
|
198
|
-
FileUtils.rm(a) if FileTest.exist?(a)
|
199
|
-
|
200
|
-
# good
|
201
|
-
FileUtils.rm_f(a)
|
202
|
-
```
|
203
|
-
|
204
185
|
### Sevencop/UniquenessValidatorExplicitCaseSensitivity
|
205
186
|
|
206
187
|
Identifies use of UniquenessValidator without :case_sensitive option.
|
data/config/default.yml
CHANGED
@@ -2,7 +2,7 @@ Sevencop/AutoloadOrdered:
|
|
2
2
|
Description: |
|
3
3
|
Sort `autoload` in alphabetical order.
|
4
4
|
Enabled: false
|
5
|
-
VersionAdded: '0.12
|
5
|
+
VersionAdded: '0.12'
|
6
6
|
|
7
7
|
Sevencop/BelongsToOptional:
|
8
8
|
Description: |
|
@@ -11,12 +11,6 @@ Sevencop/BelongsToOptional:
|
|
11
11
|
Safe: false
|
12
12
|
VersionAdded: '0.5'
|
13
13
|
|
14
|
-
Sevencop/FactoryBotCreateList:
|
15
|
-
Description: |
|
16
|
-
Finds possible substitutions for `FactoryBot.create_list`.
|
17
|
-
Enabled: false
|
18
|
-
VersionAdded: '0.10'
|
19
|
-
|
20
14
|
Sevencop/HashLiteralOrder:
|
21
15
|
Description: |
|
22
16
|
Sort Hash literal entries by key.
|
@@ -29,6 +23,12 @@ Sevencop/InferredSpecType:
|
|
29
23
|
Enabled: false
|
30
24
|
VersionAdded: '0.9'
|
31
25
|
|
26
|
+
Sevencop/MethodDefinitionKeywordArgumentsOrdered:
|
27
|
+
Description: |
|
28
|
+
Sort method definition keyword arguments in alphabetical order.
|
29
|
+
Enabled: false
|
30
|
+
VersionAdded: '0.13'
|
31
|
+
|
32
32
|
Sevencop/MethodDefinitionMultilineArguments:
|
33
33
|
Description: |
|
34
34
|
Inserts new lines between method definition parameters.
|
@@ -42,13 +42,6 @@ Sevencop/OrderField:
|
|
42
42
|
Safe: false
|
43
43
|
VersionAdded: '0.4'
|
44
44
|
|
45
|
-
Sevencop/RedundantExistenceCheck:
|
46
|
-
Description: |
|
47
|
-
Avoid redundant existent check before file operation.
|
48
|
-
Enabled: false
|
49
|
-
Safe: false
|
50
|
-
VersionAdded: '0.1'
|
51
|
-
|
52
45
|
Sevencop/ToSWithArgument:
|
53
46
|
Description: |
|
54
47
|
Identifies passing any argument to `#to_s`.
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Sevencop
|
6
|
+
# Sort method definition keyword arguments in alphabetical order.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
# # bad
|
10
|
+
# def foo(b:, a:); end
|
11
|
+
#
|
12
|
+
# # good
|
13
|
+
# def foo(a:, b:); end
|
14
|
+
#
|
15
|
+
# # bad
|
16
|
+
# def foo(c:, d:, b: 1, a: 2); end
|
17
|
+
#
|
18
|
+
# # good
|
19
|
+
# def foo(c:, d:, a: 2, b: 1); end
|
20
|
+
class MethodDefinitionKeywordArgumentsOrdered < Base
|
21
|
+
extend AutoCorrector
|
22
|
+
|
23
|
+
MSG = 'Sort method definition keyword arguments in alphabetical order.'
|
24
|
+
|
25
|
+
# @param node [RuboCop::AST::ArgNode]
|
26
|
+
def on_kwarg(node)
|
27
|
+
previous_older_kwarg = find_previous_older_sibling(node)
|
28
|
+
return unless previous_older_kwarg
|
29
|
+
|
30
|
+
add_offense(node) do |corrector|
|
31
|
+
corrector.insert_before(
|
32
|
+
previous_older_kwarg,
|
33
|
+
"#{node.source}, "
|
34
|
+
)
|
35
|
+
corrector.remove(
|
36
|
+
node.location.expression.with(
|
37
|
+
begin_pos: node.left_sibling.location.expression.end_pos
|
38
|
+
)
|
39
|
+
)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
alias on_kwoptarg on_kwarg
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
# @param node [RuboCop::AST::ArgNode]
|
47
|
+
# @return [RuboCop::AST::ArgNode]
|
48
|
+
def find_previous_older_sibling(node)
|
49
|
+
node.left_siblings.find do |sibling|
|
50
|
+
next if sibling.type != node.type
|
51
|
+
|
52
|
+
sibling.name > node.name
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
data/lib/sevencop/version.rb
CHANGED
data/lib/sevencop.rb
CHANGED
@@ -5,12 +5,11 @@ require_relative 'sevencop/version'
|
|
5
5
|
|
6
6
|
require_relative 'rubocop/cop/sevencop/autoload_ordered'
|
7
7
|
require_relative 'rubocop/cop/sevencop/belongs_to_optional'
|
8
|
-
require_relative 'rubocop/cop/sevencop/factory_bot_create_list'
|
9
8
|
require_relative 'rubocop/cop/sevencop/hash_literal_order'
|
10
9
|
require_relative 'rubocop/cop/sevencop/inferred_spec_type'
|
10
|
+
require_relative 'rubocop/cop/sevencop/method_definition_keyword_arguments_ordered'
|
11
11
|
require_relative 'rubocop/cop/sevencop/method_definition_multiline_arguments'
|
12
12
|
require_relative 'rubocop/cop/sevencop/order_field'
|
13
|
-
require_relative 'rubocop/cop/sevencop/redundant_existence_check'
|
14
13
|
require_relative 'rubocop/cop/sevencop/to_s_with_argument'
|
15
14
|
require_relative 'rubocop/cop/sevencop/uniqueness_validator_explicit_case_sensitivity'
|
16
15
|
require_relative 'rubocop/cop/sevencop/where_not'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sevencop
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.13.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryo Nakamura
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-09-
|
11
|
+
date: 2022-09-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rubocop
|
@@ -43,12 +43,11 @@ files:
|
|
43
43
|
- config/default.yml
|
44
44
|
- lib/rubocop/cop/sevencop/autoload_ordered.rb
|
45
45
|
- lib/rubocop/cop/sevencop/belongs_to_optional.rb
|
46
|
-
- lib/rubocop/cop/sevencop/factory_bot_create_list.rb
|
47
46
|
- lib/rubocop/cop/sevencop/hash_literal_order.rb
|
48
47
|
- lib/rubocop/cop/sevencop/inferred_spec_type.rb
|
48
|
+
- lib/rubocop/cop/sevencop/method_definition_keyword_arguments_ordered.rb
|
49
49
|
- lib/rubocop/cop/sevencop/method_definition_multiline_arguments.rb
|
50
50
|
- lib/rubocop/cop/sevencop/order_field.rb
|
51
|
-
- lib/rubocop/cop/sevencop/redundant_existence_check.rb
|
52
51
|
- lib/rubocop/cop/sevencop/to_s_with_argument.rb
|
53
52
|
- lib/rubocop/cop/sevencop/uniqueness_validator_explicit_case_sensitivity.rb
|
54
53
|
- lib/rubocop/cop/sevencop/where_not.rb
|
@@ -1,95 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module RuboCop
|
4
|
-
module Cop
|
5
|
-
module Sevencop
|
6
|
-
# Finds possible substitutions for `FactoryBot.create_list`.
|
7
|
-
#
|
8
|
-
# @example
|
9
|
-
#
|
10
|
-
# # bad
|
11
|
-
# Array.new(2) do
|
12
|
-
# create(:user)
|
13
|
-
# end
|
14
|
-
#
|
15
|
-
# # good
|
16
|
-
# create_list(:user, 2)
|
17
|
-
#
|
18
|
-
# # good
|
19
|
-
# Array.new(2) do |i|
|
20
|
-
# create(:user, order: i)
|
21
|
-
# end
|
22
|
-
#
|
23
|
-
# @note
|
24
|
-
# This cop does not support `Integer#times` intentionally because it
|
25
|
-
# should be treated by `Performance/TimesMap` cop.
|
26
|
-
#
|
27
|
-
class FactoryBotCreateList < Base
|
28
|
-
extend AutoCorrector
|
29
|
-
|
30
|
-
MSG = 'Use `create_list` instead.'
|
31
|
-
|
32
|
-
# @param node [RuboCop::AST::BlockNode]
|
33
|
-
# @return [void]
|
34
|
-
def on_block(node)
|
35
|
-
count_node, factory_name_node, extra_argument_nodes = extract(node)
|
36
|
-
return unless count_node
|
37
|
-
|
38
|
-
add_offense(node) do |corrector|
|
39
|
-
corrector.replace(
|
40
|
-
node,
|
41
|
-
format(
|
42
|
-
'create_list(%<arguments>s)',
|
43
|
-
arguments: [
|
44
|
-
factory_name_node,
|
45
|
-
count_node,
|
46
|
-
*extra_argument_nodes
|
47
|
-
].map(&:source).join(', ')
|
48
|
-
)
|
49
|
-
)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
alias on_numblock on_block
|
53
|
-
|
54
|
-
private
|
55
|
-
|
56
|
-
# @!method extract(node)
|
57
|
-
# @param node [RuboCop::AST::BlockNode]
|
58
|
-
# @return [Array(Integer, RuboCop::AST::SendNode)]
|
59
|
-
def_node_matcher :extract, <<~PATTERN
|
60
|
-
(block
|
61
|
-
(send
|
62
|
-
(const {nil? | cbase} :Array)
|
63
|
-
:new
|
64
|
-
$(int _)
|
65
|
-
)
|
66
|
-
(args)
|
67
|
-
(send
|
68
|
-
nil?
|
69
|
-
:create
|
70
|
-
$(sym _) $(...)?
|
71
|
-
)
|
72
|
-
)
|
73
|
-
PATTERN
|
74
|
-
|
75
|
-
# @param corrector [RuboCop::Cop::Corrector]
|
76
|
-
# @param node [RuboCop::AST::BlockNode]
|
77
|
-
# @return [void]
|
78
|
-
def autocorrect(corrector, node)
|
79
|
-
count_node, factory_name_node, extra_argument_nodes = extract(node)
|
80
|
-
corrector.replace(
|
81
|
-
node,
|
82
|
-
format(
|
83
|
-
'create_list(%<arguments>s)',
|
84
|
-
arguments: [
|
85
|
-
factory_name_node,
|
86
|
-
count_node,
|
87
|
-
*extra_argument_nodes
|
88
|
-
].map(&:source).join(', ')
|
89
|
-
)
|
90
|
-
)
|
91
|
-
end
|
92
|
-
end
|
93
|
-
end
|
94
|
-
end
|
95
|
-
end
|
@@ -1,188 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module RuboCop
|
4
|
-
module Cop
|
5
|
-
module Sevencop
|
6
|
-
# Identifies redundant existent check before file operation.
|
7
|
-
#
|
8
|
-
# @safety
|
9
|
-
# This cop is unsafe because it can register a false positive where the check is truly needed.
|
10
|
-
#
|
11
|
-
# @example
|
12
|
-
#
|
13
|
-
# # bad
|
14
|
-
# FileUtils.mkdir(a) unless FileTest.exist?(a)
|
15
|
-
#
|
16
|
-
# # good
|
17
|
-
# FileUtils.mkdir_p(a)
|
18
|
-
#
|
19
|
-
# # bad
|
20
|
-
# FileUtils.rm(a) if File.exist?(a)
|
21
|
-
#
|
22
|
-
# # good
|
23
|
-
# FileUtils.rm_f(a)
|
24
|
-
#
|
25
|
-
class RedundantExistenceCheck < Base
|
26
|
-
extend AutoCorrector
|
27
|
-
|
28
|
-
CLASS_NAMES_FOR_EXIST = ::Set[
|
29
|
-
:File,
|
30
|
-
:FileTest,
|
31
|
-
]
|
32
|
-
|
33
|
-
CLASS_NAMES_FOR_OPERATION = ::Set[
|
34
|
-
:File,
|
35
|
-
:FileUtils,
|
36
|
-
]
|
37
|
-
|
38
|
-
METHOD_NAMES_FOR_MAKE = ::Set[
|
39
|
-
:makedirs,
|
40
|
-
:mkdir,
|
41
|
-
:mkdir_p,
|
42
|
-
:mkpath,
|
43
|
-
:touch,
|
44
|
-
]
|
45
|
-
|
46
|
-
METHOD_NAMES_FOR_REMOVE = ::Set[
|
47
|
-
:delete,
|
48
|
-
:remove,
|
49
|
-
:remove_dir,
|
50
|
-
:remove_entry,
|
51
|
-
:remove_entry_secure,
|
52
|
-
:remove_file,
|
53
|
-
:rm,
|
54
|
-
:rm_f,
|
55
|
-
:rm_r,
|
56
|
-
:rm_rf,
|
57
|
-
:rmdir,
|
58
|
-
:rmtree,
|
59
|
-
:safe_unlink,
|
60
|
-
:unlink,
|
61
|
-
]
|
62
|
-
|
63
|
-
METHOD_NAMES_FOR_EXIST = ::Set[
|
64
|
-
:exist?,
|
65
|
-
:exists?,
|
66
|
-
]
|
67
|
-
|
68
|
-
METHOD_NAMES_FOR_FORCE_OPERATION = ::Set[
|
69
|
-
:makedirs,
|
70
|
-
:mkdir_p,
|
71
|
-
:mkpath,
|
72
|
-
:rm_f,
|
73
|
-
:rm_rf,
|
74
|
-
:rm_tree,
|
75
|
-
:safe_unlink,
|
76
|
-
:touch,
|
77
|
-
]
|
78
|
-
|
79
|
-
METHOD_MAPPING_FOR_FORCE_REPLACEMENT = {
|
80
|
-
'FileUtils.mkdir' => 'FileUtils.mkdir_p',
|
81
|
-
'File.delete' => 'FileUtils.rm_f',
|
82
|
-
'File.unlink' => 'FileUtils.rm_f'
|
83
|
-
}.freeze
|
84
|
-
|
85
|
-
MSG = 'Avoid redundant existent check before file operation.'
|
86
|
-
|
87
|
-
# @!method make_unless_exist?(node)
|
88
|
-
def_node_matcher :make_unless_exist?, <<~PATTERN
|
89
|
-
(if
|
90
|
-
(send (const nil? CLASS_NAMES_FOR_EXIST) METHOD_NAMES_FOR_EXIST _)
|
91
|
-
nil?
|
92
|
-
(send (const nil? CLASS_NAMES_FOR_OPERATION) METHOD_NAMES_FOR_MAKE ...)
|
93
|
-
)
|
94
|
-
PATTERN
|
95
|
-
|
96
|
-
# @!method remove_if_exist?(node)
|
97
|
-
def_node_matcher :remove_if_exist?, <<~PATTERN
|
98
|
-
(if
|
99
|
-
(send (const nil? CLASS_NAMES_FOR_EXIST) METHOD_NAMES_FOR_EXIST _)
|
100
|
-
(send (const nil? CLASS_NAMES_FOR_OPERATION) METHOD_NAMES_FOR_REMOVE ...)
|
101
|
-
nil?
|
102
|
-
)
|
103
|
-
PATTERN
|
104
|
-
|
105
|
-
def on_if(node)
|
106
|
-
return unless redundant_on_if(node) || redundant_on_unless(node)
|
107
|
-
|
108
|
-
add_offense(node) do |corrector|
|
109
|
-
corrector.replace(
|
110
|
-
node.location.expression,
|
111
|
-
enforce(node)
|
112
|
-
)
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
|
-
private
|
117
|
-
|
118
|
-
def enforce(node)
|
119
|
-
if force_operation?(node)
|
120
|
-
node.if_branch.source
|
121
|
-
elsif force_replaceable_method?(node)
|
122
|
-
enforce_by_replacement(node)
|
123
|
-
else
|
124
|
-
enforce_by_force_option(node)
|
125
|
-
end
|
126
|
-
end
|
127
|
-
|
128
|
-
def enforce_by_force_option(node)
|
129
|
-
arguments = node.if_branch.arguments.map(&:source)
|
130
|
-
arguments << 'force: true' unless force_operation?(node)
|
131
|
-
format(
|
132
|
-
'%<receiver>s.%<method_name>s(%<arguments>s)',
|
133
|
-
arguments: arguments.join(', '),
|
134
|
-
method_name: node.if_branch.method_name,
|
135
|
-
receiver: node.if_branch.receiver.source
|
136
|
-
)
|
137
|
-
end
|
138
|
-
|
139
|
-
def enforce_by_replacement(node)
|
140
|
-
format(
|
141
|
-
'%<signature>s(%<arguments>s)',
|
142
|
-
arguments: node.if_branch.arguments.map(&:source).join(', '),
|
143
|
-
signature: METHOD_MAPPING_FOR_FORCE_REPLACEMENT[operation_method_signature(node)]
|
144
|
-
)
|
145
|
-
end
|
146
|
-
|
147
|
-
def force_operation?(node)
|
148
|
-
force_operation_method_name?(node) || force_operation_argument?(node)
|
149
|
-
end
|
150
|
-
|
151
|
-
def force_operation_argument?(node)
|
152
|
-
node.if_branch.last_argument.hash_type? &&
|
153
|
-
node.if_branch.last_argument.pairs.any? do |pair|
|
154
|
-
pair.key.value == :force && pair.value.true_type?
|
155
|
-
end
|
156
|
-
end
|
157
|
-
|
158
|
-
def force_operation_method_name?(node)
|
159
|
-
METHOD_NAMES_FOR_FORCE_OPERATION.include?(node.if_branch.method_name)
|
160
|
-
end
|
161
|
-
|
162
|
-
def redundant_on_if(node)
|
163
|
-
remove_if_exist?(node) && same_argument?(node)
|
164
|
-
end
|
165
|
-
|
166
|
-
def redundant_on_unless(node)
|
167
|
-
make_unless_exist?(node) && same_argument?(node)
|
168
|
-
end
|
169
|
-
|
170
|
-
def force_replaceable_method?(node)
|
171
|
-
METHOD_MAPPING_FOR_FORCE_REPLACEMENT.key?(operation_method_signature(node))
|
172
|
-
end
|
173
|
-
|
174
|
-
def operation_method_signature(node)
|
175
|
-
format(
|
176
|
-
'%<receiver>s.%<method_name>s',
|
177
|
-
method_name: node.if_branch.method_name,
|
178
|
-
receiver: node.if_branch.receiver.source
|
179
|
-
)
|
180
|
-
end
|
181
|
-
|
182
|
-
def same_argument?(node)
|
183
|
-
node.condition.first_argument == node.if_branch.first_argument
|
184
|
-
end
|
185
|
-
end
|
186
|
-
end
|
187
|
-
end
|
188
|
-
end
|