regexp_parser 0.4.13 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ChangeLog +15 -0
- data/lib/regexp_parser/expression.rb +43 -51
- data/lib/regexp_parser/expression/classes/alternation.rb +6 -7
- data/lib/regexp_parser/expression/classes/character_class.rb +11 -0
- data/lib/regexp_parser/expression/classes/conditional.rb +10 -18
- data/lib/regexp_parser/expression/classes/free_space.rb +1 -1
- data/lib/regexp_parser/expression/classes/group.rb +9 -21
- data/lib/regexp_parser/expression/classes/property.rb +2 -2
- data/lib/regexp_parser/expression/classes/set.rb +1 -12
- data/lib/regexp_parser/expression/methods/traverse.rb +1 -1
- data/lib/regexp_parser/expression/quantifier.rb +9 -9
- data/lib/regexp_parser/expression/sequence.rb +5 -4
- data/lib/regexp_parser/expression/subexpression.rb +16 -59
- data/lib/regexp_parser/lexer.rb +31 -27
- data/lib/regexp_parser/parser.rb +179 -179
- data/lib/regexp_parser/scanner.rb +172 -166
- data/lib/regexp_parser/scanner/scanner.rl +44 -38
- data/lib/regexp_parser/syntax.rb +2 -53
- data/lib/regexp_parser/syntax/base.rb +13 -24
- data/lib/regexp_parser/syntax/tokens/character_class.rb +16 -0
- data/lib/regexp_parser/syntax/tokens/unicode_property.rb +26 -26
- data/lib/regexp_parser/syntax/version_lookup.rb +82 -0
- data/lib/regexp_parser/syntax/versions.rb +1 -5
- data/lib/regexp_parser/syntax/versions/1.8.6.rb +30 -0
- data/lib/regexp_parser/syntax/versions/1.9.1.rb +36 -0
- data/lib/regexp_parser/syntax/versions/1.9.3.rb +11 -0
- data/lib/regexp_parser/syntax/versions/2.0.0.rb +20 -0
- data/lib/regexp_parser/syntax/versions/2.2.0.rb +10 -0
- data/lib/regexp_parser/syntax/versions/2.3.0.rb +10 -0
- data/lib/regexp_parser/syntax/versions/2.4.0.rb +10 -0
- data/lib/regexp_parser/syntax/versions/2.4.1.rb +9 -0
- data/lib/regexp_parser/syntax/versions/2.5.0.rb +10 -0
- data/lib/regexp_parser/token.rb +6 -29
- data/lib/regexp_parser/version.rb +1 -1
- data/test/expression/test_strfregexp.rb +7 -0
- data/test/expression/test_to_h.rb +6 -0
- data/test/parser/test_properties.rb +12 -4
- data/test/support/warning_extractor.rb +3 -1
- data/test/syntax/test_all.rb +1 -1
- data/test/syntax/test_syntax.rb +5 -9
- data/test/syntax/{ruby → versions}/test_1.8.rb +14 -14
- data/test/syntax/{ruby → versions}/test_1.9.1.rb +7 -8
- data/test/syntax/{ruby → versions}/test_1.9.3.rb +7 -7
- data/test/syntax/versions/test_2.0.0.rb +37 -0
- data/test/syntax/{ruby → versions}/test_2.2.0.rb +7 -7
- data/test/syntax/versions/test_aliases.rb +129 -0
- data/test/syntax/{ruby → versions}/test_all.rb +1 -1
- metadata +73 -113
- data/lib/regexp_parser/syntax/ruby/1.8.6.rb +0 -37
- data/lib/regexp_parser/syntax/ruby/1.8.7.rb +0 -14
- data/lib/regexp_parser/syntax/ruby/1.8.rb +0 -13
- data/lib/regexp_parser/syntax/ruby/1.9.1.rb +0 -45
- data/lib/regexp_parser/syntax/ruby/1.9.2.rb +0 -9
- data/lib/regexp_parser/syntax/ruby/1.9.3.rb +0 -19
- data/lib/regexp_parser/syntax/ruby/1.9.rb +0 -8
- data/lib/regexp_parser/syntax/ruby/2.0.0.rb +0 -23
- data/lib/regexp_parser/syntax/ruby/2.0.rb +0 -8
- data/lib/regexp_parser/syntax/ruby/2.1.0.rb +0 -13
- data/lib/regexp_parser/syntax/ruby/2.1.10.rb +0 -13
- data/lib/regexp_parser/syntax/ruby/2.1.2.rb +0 -13
- data/lib/regexp_parser/syntax/ruby/2.1.3.rb +0 -13
- data/lib/regexp_parser/syntax/ruby/2.1.4.rb +0 -13
- data/lib/regexp_parser/syntax/ruby/2.1.5.rb +0 -13
- data/lib/regexp_parser/syntax/ruby/2.1.6.rb +0 -13
- data/lib/regexp_parser/syntax/ruby/2.1.7.rb +0 -13
- data/lib/regexp_parser/syntax/ruby/2.1.8.rb +0 -13
- data/lib/regexp_parser/syntax/ruby/2.1.9.rb +0 -13
- data/lib/regexp_parser/syntax/ruby/2.1.rb +0 -8
- data/lib/regexp_parser/syntax/ruby/2.2.0.rb +0 -16
- data/lib/regexp_parser/syntax/ruby/2.2.1.rb +0 -13
- data/lib/regexp_parser/syntax/ruby/2.2.10.rb +0 -13
- data/lib/regexp_parser/syntax/ruby/2.2.2.rb +0 -13
- data/lib/regexp_parser/syntax/ruby/2.2.3.rb +0 -13
- data/lib/regexp_parser/syntax/ruby/2.2.4.rb +0 -13
- data/lib/regexp_parser/syntax/ruby/2.2.5.rb +0 -13
- data/lib/regexp_parser/syntax/ruby/2.2.6.rb +0 -13
- data/lib/regexp_parser/syntax/ruby/2.2.7.rb +0 -13
- data/lib/regexp_parser/syntax/ruby/2.2.8.rb +0 -13
- data/lib/regexp_parser/syntax/ruby/2.2.9.rb +0 -13
- data/lib/regexp_parser/syntax/ruby/2.2.rb +0 -8
- data/lib/regexp_parser/syntax/ruby/2.3.0.rb +0 -16
- data/lib/regexp_parser/syntax/ruby/2.3.1.rb +0 -13
- data/lib/regexp_parser/syntax/ruby/2.3.2.rb +0 -13
- data/lib/regexp_parser/syntax/ruby/2.3.3.rb +0 -13
- data/lib/regexp_parser/syntax/ruby/2.3.4.rb +0 -13
- data/lib/regexp_parser/syntax/ruby/2.3.5.rb +0 -13
- data/lib/regexp_parser/syntax/ruby/2.3.6.rb +0 -13
- data/lib/regexp_parser/syntax/ruby/2.3.7.rb +0 -13
- data/lib/regexp_parser/syntax/ruby/2.3.rb +0 -8
- data/lib/regexp_parser/syntax/ruby/2.4.0.rb +0 -16
- data/lib/regexp_parser/syntax/ruby/2.4.1.rb +0 -15
- data/lib/regexp_parser/syntax/ruby/2.4.2.rb +0 -13
- data/lib/regexp_parser/syntax/ruby/2.4.3.rb +0 -13
- data/lib/regexp_parser/syntax/ruby/2.4.4.rb +0 -13
- data/lib/regexp_parser/syntax/ruby/2.4.rb +0 -8
- data/lib/regexp_parser/syntax/ruby/2.5.0.rb +0 -16
- data/lib/regexp_parser/syntax/ruby/2.5.1.rb +0 -13
- data/lib/regexp_parser/syntax/ruby/2.5.rb +0 -8
- data/lib/regexp_parser/syntax/ruby/2.6.0.rb +0 -13
- data/lib/regexp_parser/syntax/ruby/2.6.rb +0 -8
- data/test/syntax/ruby/test_2.0.0.rb +0 -32
- data/test/syntax/ruby/test_files.rb +0 -353
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f854518e5bf9e75b67ee68dd5ee895a24c176e9639d18734b883ed966989c68a
|
4
|
+
data.tar.gz: 5bf74000e06ec2a9b0e0c6f917d23125d191e5e79eb0dd5451c24c71e6f2e8ce
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 90bf54b0b86929d49ba3033389e5d0928afd829bf841c28e270124d6c2df05c93884e49a7bec48e2a3d191c996ba9522361fc804edc61ef38e8a5ed892de96b9
|
7
|
+
data.tar.gz: aa0fc2fcdebac4117e8611bcc107004d167ab45026fc696586b1940680de863f1712e0e38d38bf97784de07af7b65befb5e9fdd984f664521eff395fec51d99c
|
data/ChangeLog
CHANGED
@@ -1,3 +1,18 @@
|
|
1
|
+
Sun Apr 29 2018 Janosch Müller <janosch84@gmail.com>
|
2
|
+
|
3
|
+
* Changed handling of Ruby versions (PR #53)
|
4
|
+
- New Ruby versions are now supported by default
|
5
|
+
- Some deep-lying APIs have changed, which should not affect most users:
|
6
|
+
- `Regexp::Syntax::VERSIONS` is gone
|
7
|
+
- Syntax version names have changed from `Regexp::Syntax::Ruby::Vnnn`
|
8
|
+
to `Regexp::Syntax::Vn_n_n`
|
9
|
+
- Syntax version classes for Ruby versions without regex feature changes
|
10
|
+
are no longer predefined and are now only created on demand / lazily
|
11
|
+
- `Regexp::Syntax::supported?` returns true for any argument >= 1.8.6
|
12
|
+
* Fixed some use cases of Expression methods #strfregexp and #to_h (@e738107)
|
13
|
+
* Added full signature support to collection methods of Expressions (@aa7c55a)
|
14
|
+
* Bumped version to 0.5.0
|
15
|
+
|
1
16
|
Tue Apr 4 2018 ammarabuali@gmail.com <ammarabuali@gmail.com>
|
2
17
|
|
3
18
|
* Added ruby version files for 2.2.10 and 2.3.7
|
@@ -9,23 +9,23 @@ module Regexp::Expression
|
|
9
9
|
attr_accessor :options
|
10
10
|
|
11
11
|
def initialize(token, options = {})
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
12
|
+
self.type = token.type
|
13
|
+
self.token = token.token
|
14
|
+
self.text = token.text
|
15
|
+
self.ts = token.ts
|
16
|
+
self.level = token.level
|
17
|
+
self.set_level = token.set_level
|
18
|
+
self.conditional_level = token.conditional_level
|
19
|
+
self.quantifier = nil
|
20
|
+
self.options = options
|
21
21
|
end
|
22
22
|
|
23
23
|
def clone
|
24
|
-
copy =
|
24
|
+
copy = dup
|
25
25
|
|
26
|
-
copy.text = (
|
27
|
-
copy.options = (
|
28
|
-
copy.quantifier = (
|
26
|
+
copy.text = (text ? text.dup : nil)
|
27
|
+
copy.options = (options ? options.dup : nil)
|
28
|
+
copy.quantifier = (quantifier ? quantifier.clone : nil)
|
29
29
|
|
30
30
|
copy
|
31
31
|
end
|
@@ -34,9 +34,7 @@ module Regexp::Expression
|
|
34
34
|
::Regexp.new(to_s(format))
|
35
35
|
end
|
36
36
|
|
37
|
-
|
38
|
-
@ts
|
39
|
-
end
|
37
|
+
alias :starts_at :ts
|
40
38
|
|
41
39
|
def full_length
|
42
40
|
to_s.length
|
@@ -51,17 +49,11 @@ module Regexp::Expression
|
|
51
49
|
end
|
52
50
|
|
53
51
|
def to_s(format = :full)
|
54
|
-
|
55
|
-
|
56
|
-
case format
|
57
|
-
when :base
|
58
|
-
s << @text.dup
|
59
|
-
else
|
60
|
-
s << @text.dup
|
61
|
-
s << @quantifier if quantified?
|
62
|
-
end
|
52
|
+
"#{text}#{quantifier_affix(format)}"
|
53
|
+
end
|
63
54
|
|
64
|
-
|
55
|
+
def quantifier_affix(expression_format)
|
56
|
+
quantifier.to_s if quantified? && expression_format != :base
|
65
57
|
end
|
66
58
|
|
67
59
|
def terminal?
|
@@ -69,61 +61,61 @@ module Regexp::Expression
|
|
69
61
|
end
|
70
62
|
|
71
63
|
def quantify(token, text, min = nil, max = nil, mode = :greedy)
|
72
|
-
|
64
|
+
self.quantifier = Quantifier.new(token, text, min, max, mode)
|
73
65
|
end
|
74
66
|
|
75
67
|
def quantified?
|
76
|
-
|
68
|
+
!quantifier.nil?
|
77
69
|
end
|
78
70
|
|
79
71
|
def quantity
|
80
72
|
return [nil,nil] unless quantified?
|
81
|
-
[
|
73
|
+
[quantifier.min, quantifier.max]
|
82
74
|
end
|
83
75
|
|
84
76
|
def greedy?
|
85
|
-
quantified? and
|
77
|
+
quantified? and quantifier.mode == :greedy
|
86
78
|
end
|
87
79
|
|
88
80
|
def reluctant?
|
89
|
-
quantified? and
|
81
|
+
quantified? and quantifier.mode == :reluctant
|
90
82
|
end
|
91
83
|
alias :lazy? :reluctant?
|
92
84
|
|
93
85
|
def possessive?
|
94
|
-
quantified? and
|
86
|
+
quantified? and quantifier.mode == :possessive
|
95
87
|
end
|
96
88
|
|
97
89
|
def multiline?
|
98
|
-
|
90
|
+
options[:m] == true
|
99
91
|
end
|
100
92
|
alias :m? :multiline?
|
101
93
|
|
102
94
|
def case_insensitive?
|
103
|
-
|
95
|
+
options[:i] == true
|
104
96
|
end
|
105
97
|
alias :i? :case_insensitive?
|
106
98
|
alias :ignore_case? :case_insensitive?
|
107
99
|
|
108
100
|
def free_spacing?
|
109
|
-
|
101
|
+
options[:x] == true
|
110
102
|
end
|
111
103
|
alias :x? :free_spacing?
|
112
104
|
alias :extended? :free_spacing?
|
113
105
|
|
114
106
|
if RUBY_VERSION >= '2.0'
|
115
107
|
def default_classes?
|
116
|
-
|
108
|
+
options[:d] == true
|
117
109
|
end
|
118
110
|
alias :d? :default_classes?
|
119
111
|
|
120
112
|
def ascii_classes?
|
121
|
-
|
113
|
+
options[:a] == true
|
122
114
|
end
|
123
115
|
alias :a? :ascii_classes?
|
124
116
|
|
125
117
|
def unicode_classes?
|
126
|
-
|
118
|
+
options[:u] == true
|
127
119
|
end
|
128
120
|
alias :u? :unicode_classes?
|
129
121
|
end
|
@@ -139,16 +131,16 @@ module Regexp::Expression
|
|
139
131
|
|
140
132
|
def to_h
|
141
133
|
{
|
142
|
-
:type
|
143
|
-
:token
|
144
|
-
:
|
145
|
-
:
|
146
|
-
:
|
147
|
-
:level
|
148
|
-
:set_level
|
149
|
-
:
|
150
|
-
:options
|
151
|
-
:
|
134
|
+
type: type,
|
135
|
+
token: token,
|
136
|
+
text: to_s(:base),
|
137
|
+
starts_at: ts,
|
138
|
+
length: full_length,
|
139
|
+
level: level,
|
140
|
+
set_level: set_level,
|
141
|
+
conditional_level: conditional_level,
|
142
|
+
options: options,
|
143
|
+
quantifier: quantified? ? quantifier.to_h : nil,
|
152
144
|
}
|
153
145
|
end
|
154
146
|
end
|
@@ -162,9 +154,9 @@ module Regexp::Expression
|
|
162
154
|
when Regexp::Expression
|
163
155
|
exp
|
164
156
|
else
|
165
|
-
raise
|
166
|
-
|
167
|
-
|
157
|
+
raise ArgumentError, 'Expression.parsed accepts a String, Regexp, or '\
|
158
|
+
'a Regexp::Expression as a value for exp, but it '\
|
159
|
+
"was given #{exp.class.name}."
|
168
160
|
end
|
169
161
|
end
|
170
162
|
|
@@ -3,20 +3,19 @@ module Regexp::Expression
|
|
3
3
|
# This is not a subexpression really, but considering it one simplifies
|
4
4
|
# the API when it comes to handling the alternatives.
|
5
5
|
class Alternation < Regexp::Expression::Subexpression
|
6
|
+
alias :alternatives :expressions
|
7
|
+
|
6
8
|
def starts_at
|
7
|
-
|
9
|
+
expressions.first.starts_at
|
8
10
|
end
|
11
|
+
alias :ts :starts_at
|
9
12
|
|
10
13
|
def <<(exp)
|
11
|
-
|
14
|
+
expressions.last << exp
|
12
15
|
end
|
13
16
|
|
14
17
|
def alternative(exp = nil)
|
15
|
-
|
16
|
-
end
|
17
|
-
|
18
|
-
def alternatives
|
19
|
-
@expressions
|
18
|
+
expressions << (exp ? exp : Alternative.new(level, set_level, conditional_level))
|
20
19
|
end
|
21
20
|
|
22
21
|
def quantify(token, text, min = nil, max = nil, mode = :greedy)
|
@@ -11,45 +11,37 @@ module Regexp::Expression
|
|
11
11
|
class Branch < Regexp::Expression::Sequence; end
|
12
12
|
|
13
13
|
class Expression < Regexp::Expression::Subexpression
|
14
|
+
attr_reader :branches, :condition
|
15
|
+
|
14
16
|
def initialize(token, options = {})
|
15
17
|
super
|
16
|
-
|
17
|
-
@condition = nil
|
18
18
|
@branches = []
|
19
19
|
end
|
20
20
|
|
21
|
-
def condition(exp
|
22
|
-
return @condition unless exp
|
21
|
+
def condition=(exp)
|
23
22
|
@condition = exp
|
24
|
-
|
23
|
+
expressions << exp
|
25
24
|
end
|
26
25
|
|
27
26
|
def <<(exp)
|
28
|
-
|
27
|
+
expressions.last << exp
|
29
28
|
end
|
30
29
|
|
31
30
|
def branch(exp = nil)
|
32
|
-
raise TooManyBranches.new if
|
31
|
+
raise TooManyBranches.new if branches.length == 2
|
33
32
|
|
34
33
|
sequence = Branch.new(level, set_level, conditional_level + 1)
|
35
34
|
|
36
|
-
|
37
|
-
|
38
|
-
end
|
39
|
-
|
40
|
-
def branches
|
41
|
-
@branches
|
35
|
+
expressions << sequence
|
36
|
+
branches << expressions.last
|
42
37
|
end
|
43
38
|
|
44
39
|
def quantify(token, text, min = nil, max = nil, mode = :greedy)
|
45
40
|
branches.last.last.quantify(token, text, min, max, mode)
|
46
41
|
end
|
47
42
|
|
48
|
-
def to_s
|
49
|
-
|
50
|
-
s << @condition.text
|
51
|
-
s << branches.map{|e| e.to_s}.join('|')
|
52
|
-
s << ')'
|
43
|
+
def to_s(_format = :full)
|
44
|
+
text + condition.text + branches.join('|') + ')'
|
53
45
|
end
|
54
46
|
end
|
55
47
|
end
|
@@ -3,27 +3,15 @@ module Regexp::Expression
|
|
3
3
|
module Group
|
4
4
|
class Base < Regexp::Expression::Subexpression
|
5
5
|
def capturing?
|
6
|
-
[:capture, :named].include?
|
6
|
+
[:capture, :named].include?(token)
|
7
7
|
end
|
8
8
|
|
9
|
-
def comment
|
9
|
+
def comment?
|
10
|
+
type == :comment
|
11
|
+
end
|
10
12
|
|
11
13
|
def to_s(format = :full)
|
12
|
-
|
13
|
-
|
14
|
-
case format
|
15
|
-
when :base
|
16
|
-
s << @text.dup
|
17
|
-
s << @expressions.join
|
18
|
-
s << ')'
|
19
|
-
else
|
20
|
-
s << @text.dup
|
21
|
-
s << @expressions.join
|
22
|
-
s << ')'
|
23
|
-
s << @quantifier.to_s if quantified?
|
24
|
-
end
|
25
|
-
|
26
|
-
s
|
14
|
+
"#{text}#{expressions.join})#{quantifier_affix(format)}"
|
27
15
|
end
|
28
16
|
end
|
29
17
|
|
@@ -43,14 +31,14 @@ module Regexp::Expression
|
|
43
31
|
|
44
32
|
def clone
|
45
33
|
copy = super
|
46
|
-
copy.instance_variable_set(:@name,
|
34
|
+
copy.instance_variable_set(:@name, name.dup)
|
47
35
|
copy
|
48
36
|
end
|
49
37
|
end
|
50
38
|
|
51
|
-
class Comment
|
52
|
-
def to_s(
|
53
|
-
|
39
|
+
class Comment < Group::Base
|
40
|
+
def to_s(_format = :full)
|
41
|
+
text.dup
|
54
42
|
end
|
55
43
|
end
|
56
44
|
end
|
@@ -3,11 +3,11 @@ module Regexp::Expression
|
|
3
3
|
module UnicodeProperty
|
4
4
|
class Base < Regexp::Expression::Base
|
5
5
|
def negative?
|
6
|
-
|
6
|
+
type == :nonproperty
|
7
7
|
end
|
8
8
|
|
9
9
|
def name
|
10
|
-
|
10
|
+
text =~ /\A\\[pP]\{([^}]+)\}\z/; $1
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
@@ -100,18 +100,7 @@ module Regexp::Expression
|
|
100
100
|
end
|
101
101
|
|
102
102
|
def to_s(format = :full)
|
103
|
-
|
104
|
-
|
105
|
-
s << @text.dup
|
106
|
-
s << '^' if negative?
|
107
|
-
s << @members.join
|
108
|
-
s << ']'
|
109
|
-
|
110
|
-
unless format == :base
|
111
|
-
s << @quantifier.to_s if quantified?
|
112
|
-
end
|
113
|
-
|
114
|
-
s
|
103
|
+
"#{text}#{'^' if negative?}#{members.join}]#{quantifier_affix(format)}"
|
115
104
|
end
|
116
105
|
end
|
117
106
|
|
@@ -7,7 +7,7 @@ module Regexp::Expression
|
|
7
7
|
#
|
8
8
|
# The event argument is passed as follows:
|
9
9
|
#
|
10
|
-
# - For subexpressions, :enter upon
|
10
|
+
# - For subexpressions, :enter upon entering the subexpression, and
|
11
11
|
# :exit upon exiting it.
|
12
12
|
#
|
13
13
|
# - For terminal expressions, :visit is called once.
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Regexp::Expression
|
2
2
|
|
3
3
|
class Quantifier
|
4
|
-
attr_reader
|
4
|
+
attr_reader :token, :text, :min, :max, :mode
|
5
5
|
|
6
6
|
def initialize(token, text, min, max, mode)
|
7
7
|
@token = token
|
@@ -12,23 +12,23 @@ module Regexp::Expression
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def clone
|
15
|
-
copy =
|
16
|
-
copy.instance_variable_set(:@text,
|
15
|
+
copy = dup
|
16
|
+
copy.instance_variable_set(:@text, text.dup)
|
17
17
|
copy
|
18
18
|
end
|
19
19
|
|
20
20
|
def to_s
|
21
|
-
|
21
|
+
text.dup
|
22
22
|
end
|
23
23
|
alias :to_str :to_s
|
24
24
|
|
25
25
|
def to_h
|
26
26
|
{
|
27
|
-
:
|
28
|
-
:
|
29
|
-
:
|
30
|
-
:
|
31
|
-
:
|
27
|
+
token: token,
|
28
|
+
text: text,
|
29
|
+
mode: mode,
|
30
|
+
min: min,
|
31
|
+
max: max,
|
32
32
|
}
|
33
33
|
end
|
34
34
|
end
|