oniguruma 1.0.1-mswin32
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/History.txt +49 -0
- data/Manifest.txt +10 -0
- data/README.txt +71 -0
- data/Rakefile +41 -0
- data/Syntax.txt +396 -0
- data/ext/oregexp.c +712 -0
- data/lib/oniguruma.rb +479 -0
- data/test/test_oniguruma.rb +361 -0
- data/win/oregexp.so +0 -0
- metadata +57 -0
@@ -0,0 +1,361 @@
|
|
1
|
+
require 'oniguruma'
|
2
|
+
require 'test/unit'
|
3
|
+
|
4
|
+
|
5
|
+
class ORegexpTestCase < Test::Unit::TestCase
|
6
|
+
def test_initialization
|
7
|
+
assert_nothing_raised do
|
8
|
+
reg = Oniguruma::ORegexp.new( "(3.)(.*)(3.)" )
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_compile
|
13
|
+
assert_nothing_raised do
|
14
|
+
reg = Oniguruma::ORegexp.compile( "(3.)(.*)(3.)" )
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_escape
|
19
|
+
assert_equal( '\\\\\*\?\{\}\.', Oniguruma::ORegexp.escape('\\*?{}.') )
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_last_match
|
23
|
+
assert_equal( 0, Oniguruma::ORegexp.new( 'c(.)t') =~ 'cat' )
|
24
|
+
assert_equal( "cat", Oniguruma::ORegexp.last_match(0) )
|
25
|
+
assert_equal( "a", Oniguruma::ORegexp.last_match(1) )
|
26
|
+
assert_equal( nil, Oniguruma::ORegexp.last_match(2) )
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_bad_initialization
|
30
|
+
assert_raises(ArgumentError) do
|
31
|
+
reg = Oniguruma::ORegexp.new( "(3.)(.*)(3.))" )
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_match
|
36
|
+
reg = Oniguruma::ORegexp.new( "(3.)(.*)(3.)" )
|
37
|
+
assert_not_nil( reg.match( "12345634" ) )
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_no_match
|
41
|
+
reg = Oniguruma::ORegexp.new( "(3.)(.*)(3.)" )
|
42
|
+
assert_nil( reg.match( "12145614" ) )
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_sub
|
46
|
+
reg = Oniguruma::ORegexp.new( 'pe')
|
47
|
+
assert_equal( "**nelope", reg.sub( 'penelope', '**' ) )
|
48
|
+
assert_equal( "++nelope", reg.sub( 'penelope' ) { |m| '++' })
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_gsub
|
52
|
+
reg = Oniguruma::ORegexp.new( '\(\?#(\w+?)\)')
|
53
|
+
string = 'My favorite fruits are (?#fruit1), (?#fruit2), and (?#fruit3)'
|
54
|
+
assert_equal( "My favorite fruits are *, *, and *", reg.gsub( string, '*' ) )
|
55
|
+
fruits = { "fruit1" => "apples", "fruit2" => "bananas", "fruit3" => "grapes" }
|
56
|
+
assert_equal( "My favorite fruits are apples, bananas, and grapes", reg.gsub( string ) { |match| fruits[match[1]]} )
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_eql
|
60
|
+
assert_equal( Oniguruma::ORegexp.new( 'expression'), Oniguruma::ORegexp.new( 'expression') )
|
61
|
+
assert_not_equal( Oniguruma::ORegexp.new( 'expression'), Oniguruma::ORegexp.new( 'expresssion') )
|
62
|
+
assert_not_equal( Oniguruma::ORegexp.new( 'expression', :encoding => Oniguruma::ENCODING_ASCII ), Oniguruma::ORegexp.new( 'expression', :encoding => Oniguruma::ENCODING_ISO_8859_1 ) )
|
63
|
+
assert_not_equal( Oniguruma::ORegexp.new( 'expression', :options => Oniguruma::OPTION_IGNORECASE ), Oniguruma::ORegexp.new( 'expression', :options => Oniguruma::OPTION_NONE ) )
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_case_eql
|
67
|
+
a = "HELLO"
|
68
|
+
result = ""
|
69
|
+
case a
|
70
|
+
when Oniguruma::ORegexp.new('^[a-z]*$'); result = "Lower case\n"
|
71
|
+
when Oniguruma::ORegexp.new('^[A-Z]*$'); result = "Upper case\n"
|
72
|
+
else; result = "Mixed case\n"
|
73
|
+
end
|
74
|
+
|
75
|
+
assert_equal( "Upper case\n", result )
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_case_eql_compat
|
79
|
+
# === method should not raise when used in case statements
|
80
|
+
a = Time.now
|
81
|
+
result = ""
|
82
|
+
case a
|
83
|
+
when /./ ; result = "rgx"
|
84
|
+
when Oniguruma::ORegexp.new('.'); result = "ore"
|
85
|
+
else; result = "else"
|
86
|
+
end
|
87
|
+
assert_equal( "else", result )
|
88
|
+
end
|
89
|
+
|
90
|
+
def test_operator_match
|
91
|
+
assert_equal( nil, Oniguruma::ORegexp.new( 'SIT' ) =~ "insensitive" )
|
92
|
+
assert_equal( 5, Oniguruma::ORegexp.new( 'SIT', :options => Oniguruma::OPTION_IGNORECASE ) =~ "insensitive" )
|
93
|
+
assert_equal( 5, Oniguruma::ORegexp.new( 'SIT', 'i' ) =~ "insensitive" )
|
94
|
+
end
|
95
|
+
|
96
|
+
# def test_operator_match_2
|
97
|
+
# $_ = "input data"
|
98
|
+
# assert_equal( 7, ~Oniguruma::ORegexp.new( 'at' ) )
|
99
|
+
# end
|
100
|
+
|
101
|
+
def test_inspect
|
102
|
+
assert_equal( "/cat/im", Oniguruma::ORegexp.new( 'cat', :options => Oniguruma::OPTION_IGNORECASE | Oniguruma::OPTION_MULTILINE ).inspect )
|
103
|
+
end
|
104
|
+
|
105
|
+
def test_to_s
|
106
|
+
assert_equal( "(?im-x)cat", Oniguruma::ORegexp.new( 'cat', :options => Oniguruma::OPTION_IGNORECASE | Oniguruma::OPTION_MULTILINE ).to_s )
|
107
|
+
end
|
108
|
+
|
109
|
+
def test_kcode
|
110
|
+
reg = Oniguruma::ORegexp.new( "(3.)(.*)(3.)" )
|
111
|
+
assert_equal( Oniguruma::ENCODING_ASCII, reg.kcode )
|
112
|
+
reg = Oniguruma::ORegexp.new( "(3.)(.*)(3.)", '', 'SJIS' )
|
113
|
+
assert_equal( Oniguruma::ENCODING_SJIS, reg.kcode )
|
114
|
+
end
|
115
|
+
|
116
|
+
def test_options
|
117
|
+
assert_equal( 3, Oniguruma::ORegexp.new( 'abc', :options => Oniguruma::OPTION_IGNORECASE | Oniguruma::OPTION_EXTEND ).options )
|
118
|
+
end
|
119
|
+
|
120
|
+
def test_source
|
121
|
+
string = '(?<=\n)\\.*ocatarinetabelachitchix'
|
122
|
+
assert_equal( string, Oniguruma::ORegexp.new( string ).source )
|
123
|
+
end
|
124
|
+
|
125
|
+
def test_named_sub_backrefs
|
126
|
+
re = Oniguruma::ORegexp.new('(?<pre>\w+?)\d+(?<after>\w+)')
|
127
|
+
assert_equal(' def123abc ', re.sub('abc123def', ' \<after>123\<pre> ') )
|
128
|
+
end
|
129
|
+
|
130
|
+
def test_named_sub_backrefs_dupes
|
131
|
+
re = Oniguruma::ORegexp.new('(?<pre>\w+?)\d+(?<pre>\w+)')
|
132
|
+
assert_equal('123def', re.sub('abc123def', '123\<pre>') )
|
133
|
+
end
|
134
|
+
|
135
|
+
def test_backref_set_for_match
|
136
|
+
re = Oniguruma::ORegexp.new('Date:(\d{4})/(\d{2})/(\d{2})')
|
137
|
+
assert re.match( "Date:2007/03/25" )
|
138
|
+
assert_not_nil $~
|
139
|
+
assert_equal "2007", $1
|
140
|
+
assert_equal "03", $2
|
141
|
+
assert_equal "25", $3
|
142
|
+
end
|
143
|
+
|
144
|
+
def test_backref_set_for_match_op
|
145
|
+
re = Oniguruma::ORegexp.new('Date:(\d{4})/(\d{2})/(\d{2})')
|
146
|
+
assert re =~ "Date:2007/03/25"
|
147
|
+
assert_not_nil $~
|
148
|
+
assert_equal "2007", $1
|
149
|
+
assert_equal "03", $2
|
150
|
+
assert_equal "25", $3
|
151
|
+
end
|
152
|
+
|
153
|
+
def test_multibyte_named_backrefs
|
154
|
+
r = Oniguruma::ORegexp.new('(?<группа>test).+(\k<группа>)', :encoding => Oniguruma::ENCODING_UTF8)
|
155
|
+
assert_equal "should !test!", r.sub("should test this damned test", '!\<группа>!')
|
156
|
+
end
|
157
|
+
|
158
|
+
end
|
159
|
+
|
160
|
+
class MatchDataTestCase < Test::Unit::TestCase
|
161
|
+
def setup
|
162
|
+
@reg = Oniguruma::ORegexp.new( '(.)(.)(\d+)(\d)' )
|
163
|
+
end
|
164
|
+
|
165
|
+
def test_square_brackets
|
166
|
+
matches = @reg.match( "THX1138." )
|
167
|
+
assert_equal( "HX1138", matches[0] )
|
168
|
+
assert_equal( ["H", "X"], matches[1, 2] )
|
169
|
+
assert_equal( ["H", "X", "113"], matches[1..3] )
|
170
|
+
assert_equal( ["X", "113"], matches[-3, 2] )
|
171
|
+
end
|
172
|
+
|
173
|
+
def test_begin
|
174
|
+
matches = @reg.match( "THX1138." )
|
175
|
+
assert_equal( 1, matches.begin )
|
176
|
+
assert_equal( 1, matches.begin(0) )
|
177
|
+
assert_equal( 2, matches.begin(2) )
|
178
|
+
end
|
179
|
+
|
180
|
+
def test_captures
|
181
|
+
matches = @reg.match( "THX1138." )
|
182
|
+
assert_equal( ["H", "X", "113", "8" ], matches.captures )
|
183
|
+
end
|
184
|
+
|
185
|
+
def test_end
|
186
|
+
matches = @reg.match( "THX1138." )
|
187
|
+
assert_equal( 7, matches.end )
|
188
|
+
assert_equal( 7, matches.end(0) )
|
189
|
+
assert_equal( 3, matches.end(2) )
|
190
|
+
end
|
191
|
+
|
192
|
+
def test_size
|
193
|
+
matches = @reg.match( "THX1138." )
|
194
|
+
assert_equal( 5, matches.length )
|
195
|
+
assert_equal( 5, matches.size )
|
196
|
+
end
|
197
|
+
|
198
|
+
def test_offset
|
199
|
+
matches = @reg.match( "THX1138." )
|
200
|
+
assert_equal( [1, 7], matches.offset )
|
201
|
+
assert_equal( [1, 7], matches.offset(0) )
|
202
|
+
assert_equal( [6, 7], matches.offset(4) )
|
203
|
+
end
|
204
|
+
|
205
|
+
def test_post_match
|
206
|
+
matches = @reg.match( "THX1138: The Movie" )
|
207
|
+
assert_equal( ": The Movie", matches.post_match )
|
208
|
+
end
|
209
|
+
|
210
|
+
def test_pre_match
|
211
|
+
matches = @reg.match( "THX1138." )
|
212
|
+
assert_equal( "T", matches.pre_match )
|
213
|
+
end
|
214
|
+
|
215
|
+
def test_select
|
216
|
+
matches = @reg.match( "THX1138: The Movie" )
|
217
|
+
assert_equal( ["HX1138", "113"], matches.select{ |v| v =~ /\d\d/} )
|
218
|
+
end
|
219
|
+
|
220
|
+
def test_string
|
221
|
+
matches = @reg.match( "THX1138." )
|
222
|
+
assert_equal( "THX1138.", matches.string )
|
223
|
+
assert( matches.string.frozen? )
|
224
|
+
end
|
225
|
+
|
226
|
+
def test_to_a
|
227
|
+
matches = @reg.match( "THX1138." )
|
228
|
+
assert_equal( ["HX1138", "H", "X", "113", "8" ], matches.to_a )
|
229
|
+
end
|
230
|
+
|
231
|
+
def test_to_s
|
232
|
+
matches = @reg.match( "THX1138." )
|
233
|
+
assert_equal( "HX1138", matches.to_s )
|
234
|
+
end
|
235
|
+
|
236
|
+
def test_values_at
|
237
|
+
matches = @reg.match( "THX1138: The Movie" )
|
238
|
+
assert_equal( ["HX1138", "X", "113"], matches.values_at( 0, 2, -2) )
|
239
|
+
end
|
240
|
+
|
241
|
+
def test_match_all
|
242
|
+
reg = Oniguruma::ORegexp.new( 'ca' )
|
243
|
+
matches = reg.match_all( 'ocatacachaca' )
|
244
|
+
a = []
|
245
|
+
matches.each { |m| a << m.offset(0) }
|
246
|
+
assert_equal( [ [1,3], [5,7], [10,12] ], a)
|
247
|
+
assert_equal( 3, matches.size )
|
248
|
+
assert_equal( 10, matches[2].begin( 0 ) )
|
249
|
+
assert_equal( "ca", matches[1].string[matches[1].begin( 0 )...matches[1].end( 0 )])
|
250
|
+
end
|
251
|
+
|
252
|
+
def test_scan
|
253
|
+
reg = Oniguruma::ORegexp.new( 'ca' )
|
254
|
+
a = []
|
255
|
+
matches = reg.match_all( 'ocatacachaca' ) { |m| a << m.offset(0) }
|
256
|
+
#assert_kind_of(Oniguruma::MultiMatchData, matches)
|
257
|
+
assert_equal( [ [1,3], [5,7], [10,12] ], a)
|
258
|
+
end
|
259
|
+
|
260
|
+
def test_match_empty_string
|
261
|
+
reg = Oniguruma::ORegexp.new( '^\s*?(\n|\r)', :options => Oniguruma::OPTION_MULTILINE )
|
262
|
+
matches = reg.match( "\n\n\n\n\n" )
|
263
|
+
assert_not_nil( matches )
|
264
|
+
assert_equal( "\n\n\n\n", matches.post_match )
|
265
|
+
end
|
266
|
+
|
267
|
+
def test_group_by_name
|
268
|
+
reg = Oniguruma::ORegexp.new( '(?<begin>\()(?<body>.*)(?<end>\))', :options => Oniguruma::OPTION_MULTILINE )
|
269
|
+
matches = reg.match( "blah (content) blah" )
|
270
|
+
assert_not_nil( matches )
|
271
|
+
assert_equal $~, matches
|
272
|
+
assert_equal( '(', matches[:begin] )
|
273
|
+
assert_equal( 'content', matches[:body] )
|
274
|
+
assert_equal( ')', matches[:end] )
|
275
|
+
assert_equal( nil, matches[:inexistent])
|
276
|
+
end
|
277
|
+
|
278
|
+
def test_multibyte_named_backrefs
|
279
|
+
r = Oniguruma::ORegexp.new('(?<имя>test).+(\k<имя>)', :encoding => Oniguruma::ENCODING_UTF8)
|
280
|
+
assert_equal "should TEST", r.sub("should test this damned test") {|m| m[:"имя"].upcase }
|
281
|
+
end
|
282
|
+
|
283
|
+
def test_no_named_backrefs
|
284
|
+
r = Oniguruma::ORegexp.new('(.+).+(.+)')
|
285
|
+
r.match("text")
|
286
|
+
assert_not_nil $~
|
287
|
+
assert_equal 0, $~.instance_variables.size
|
288
|
+
r = Oniguruma::ORegexp.new('(?<a>.+).+(?<b>.+)')
|
289
|
+
r.match("text")
|
290
|
+
assert_not_nil $~
|
291
|
+
assert_equal 1, $~.instance_variables.size
|
292
|
+
|
293
|
+
end
|
294
|
+
|
295
|
+
# casefolding for full Unicode set is not present in versions prior to 5.
|
296
|
+
if Oniguruma::VERSION >= '5.0.0'
|
297
|
+
def test_utf8_ignore_case
|
298
|
+
reg = Oniguruma::ORegexp.new( '([а-я])+', :options => Oniguruma::OPTION_IGNORECASE, :encoding => Oniguruma::ENCODING_UTF8 )
|
299
|
+
matches = reg.match("Text: Ехал Грека Через Реку")
|
300
|
+
assert_not_nil( matches )
|
301
|
+
assert_equal("Ехал", matches[0])
|
302
|
+
reg = Oniguruma::ORegexp.new( 'р(уби.*)', :options => Oniguruma::OPTION_IGNORECASE, :encoding => Oniguruma::ENCODING_UTF8 )
|
303
|
+
assert_equal("*убил бы*", reg.gsub("Руби", '*\1л бы*') )
|
304
|
+
end
|
305
|
+
|
306
|
+
def test_utf8_gsub
|
307
|
+
reg = Oniguruma::ORegexp.new( '([а-я])([а-я])([а-я]+)', :options => Oniguruma::OPTION_IGNORECASE, :encoding => Oniguruma::ENCODING_UTF8 )
|
308
|
+
new_str = reg.gsub("Text: Ехал Грека Через Реку") {|m| m[1]*2+m[2]*2+m[3] }
|
309
|
+
assert_equal("Text: ЕЕххал ГГррека ЧЧеерез РРееку", new_str)
|
310
|
+
end
|
311
|
+
|
312
|
+
def test_utf8_gsub2
|
313
|
+
reg = Oniguruma::ORegexp.new( '[а-я]', :options => Oniguruma::OPTION_IGNORECASE, :encoding => Oniguruma::ENCODING_UTF8 )
|
314
|
+
new_str = reg.gsub("Text: Ехал Грека Через Реку") {|m| m[0]*2 }
|
315
|
+
assert_equal("Text: ЕЕххаалл ГГррееккаа ЧЧеерреезз РРееккуу", new_str)
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
319
|
+
def test_sub_compatibility
|
320
|
+
$x = "a.gif"
|
321
|
+
assert_equal("b.gif", $x.osub('.*\.([^\.]+)$', 'b.\1'))
|
322
|
+
assert_equal("\\.gif", $x.osub('.*\.([^\.]+)$', '\\.\1'))
|
323
|
+
assert_equal("gif", $x.osub('.*\.([^\.]+)$', '\1'))
|
324
|
+
assert_equal("", $x.osub('.*\.([^\.]+)$', '\2'))
|
325
|
+
assert_equal("ab", $x.osub('.*\.([^\.]+)$', 'a\2b'))
|
326
|
+
assert_equal("<a.gif>", $x.osub('.*\.([^\.]+)$', '<\&>'))
|
327
|
+
assert_equal("a.a.", $x.osub('(gif)', '\`') )
|
328
|
+
end
|
329
|
+
|
330
|
+
def test_gsub_compat
|
331
|
+
assert_equal("hello".ogsub('[aeiou]', '*') , "h*ll*")
|
332
|
+
assert_equal("hello".ogsub('([aeiou])', '<\1>') , "h<e>ll<o>")
|
333
|
+
i = 0
|
334
|
+
assert_equal("12345" , Oniguruma::ORegexp.new('.').gsub("hello") {|m| i+=1; i.to_s})
|
335
|
+
assert_equal("214365", Oniguruma::ORegexp.new('(.)(.)').gsub("123456") {|m| m[2] + m[1] })
|
336
|
+
a = "test"
|
337
|
+
a.ogsub!('t', a)
|
338
|
+
assert_equal("testestest", a)
|
339
|
+
end
|
340
|
+
|
341
|
+
def test_match_compat
|
342
|
+
t = Oniguruma::ORegexp.new('(.)(.)').gsub("123456") {|m| "#$2#$1" }
|
343
|
+
assert_equal("214365", t )
|
344
|
+
t = Oniguruma::ORegexp.new('([aeiou])').gsub("hello") {|m| "<#$1>" }
|
345
|
+
assert_equal( "h<e>ll<o>", t)
|
346
|
+
end
|
347
|
+
|
348
|
+
def _u16(str)
|
349
|
+
str.unpack("U*").pack("n*")
|
350
|
+
end
|
351
|
+
puts Oniguruma::VERSION
|
352
|
+
if Oniguruma::VERSION >= '4.0.0'
|
353
|
+
def test_utf16_gsub
|
354
|
+
r = Oniguruma::ORegexp.new( _u16('[aeiou]'), :encoding => Oniguruma::ENCODING_UTF16_BE)
|
355
|
+
assert_equal( _u16("h*ll*"), r.gsub( _u16("hello"), _u16('*')) )
|
356
|
+
r = Oniguruma::ORegexp.new( _u16('([aeiou])'), :encoding => Oniguruma::ENCODING_UTF16_BE)
|
357
|
+
assert_equal( _u16("h<e>\\ll<o>\\"), r.gsub( _u16("hello"), _u16('<\1>\\')) )
|
358
|
+
end
|
359
|
+
end
|
360
|
+
|
361
|
+
end
|
data/win/oregexp.so
ADDED
Binary file
|
metadata
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.9.2
|
3
|
+
specification_version: 1
|
4
|
+
name: oniguruma
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: 1.0.1
|
7
|
+
date: 2007-03-28 00:00:00 +02:00
|
8
|
+
summary: Bindings for the oniguruma regular expression library
|
9
|
+
require_paths:
|
10
|
+
- win
|
11
|
+
- lib
|
12
|
+
- ext
|
13
|
+
email: dichodaemon@gmail.com
|
14
|
+
homepage: http://oniguruma.rubyforge.org
|
15
|
+
rubyforge_project: oniguruma
|
16
|
+
description: Ruby bindings to the Oniguruma[http://www.geocities.jp/kosako3/oniguruma/] regular expression library (no need to recompile Ruby).
|
17
|
+
autorequire:
|
18
|
+
default_executable:
|
19
|
+
bindir: bin
|
20
|
+
has_rdoc: true
|
21
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
22
|
+
requirements:
|
23
|
+
- - ">"
|
24
|
+
- !ruby/object:Gem::Version
|
25
|
+
version: 0.0.0
|
26
|
+
version:
|
27
|
+
platform: mswin32
|
28
|
+
signing_key:
|
29
|
+
cert_chain:
|
30
|
+
post_install_message:
|
31
|
+
authors:
|
32
|
+
- Dizan Vasquez
|
33
|
+
- Nikolai Lugovoi
|
34
|
+
files:
|
35
|
+
- History.txt
|
36
|
+
- Manifest.txt
|
37
|
+
- README.txt
|
38
|
+
- Syntax.txt
|
39
|
+
- Rakefile
|
40
|
+
- lib/oniguruma.rb
|
41
|
+
- ext/oregexp.c
|
42
|
+
- test/test_oniguruma.rb
|
43
|
+
- win/oregexp.so
|
44
|
+
test_files:
|
45
|
+
- test/test_oniguruma.rb
|
46
|
+
rdoc_options: []
|
47
|
+
|
48
|
+
extra_rdoc_files: []
|
49
|
+
|
50
|
+
executables: []
|
51
|
+
|
52
|
+
extensions: []
|
53
|
+
|
54
|
+
requirements: []
|
55
|
+
|
56
|
+
dependencies: []
|
57
|
+
|