elasticsearch-api 0.4.11 → 1.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +2 -6
- data/README.md +3 -4
- data/lib/elasticsearch/api.rb +16 -9
- data/lib/elasticsearch/api/actions/cat/aliases.rb +67 -0
- data/lib/elasticsearch/api/actions/cat/allocation.rb +69 -0
- data/lib/elasticsearch/api/actions/cat/count.rb +59 -0
- data/lib/elasticsearch/api/actions/cat/health.rb +43 -0
- data/lib/elasticsearch/api/actions/cat/help.rb +25 -0
- data/lib/elasticsearch/api/actions/cat/indices.rb +77 -0
- data/lib/elasticsearch/api/actions/cat/master.rb +40 -0
- data/lib/elasticsearch/api/actions/cat/nodes.rb +38 -0
- data/lib/elasticsearch/api/actions/cat/pending_tasks.rb +40 -0
- data/lib/elasticsearch/api/actions/cat/recovery.rb +73 -0
- data/lib/elasticsearch/api/actions/cat/shards.rb +72 -0
- data/lib/elasticsearch/api/actions/cluster/put_settings.rb +3 -1
- data/lib/elasticsearch/api/actions/cluster/state.rb +23 -14
- data/lib/elasticsearch/api/actions/count_percolate.rb +78 -0
- data/lib/elasticsearch/api/actions/indices/exists.rb +4 -1
- data/lib/elasticsearch/api/actions/indices/exists_alias.rb +5 -3
- data/lib/elasticsearch/api/actions/indices/exists_template.rb +34 -0
- data/lib/elasticsearch/api/actions/indices/exists_type.rb +4 -1
- data/lib/elasticsearch/api/actions/indices/get_alias.rb +5 -3
- data/lib/elasticsearch/api/actions/indices/get_aliases.rb +6 -3
- data/lib/elasticsearch/api/actions/indices/get_field_mapping.rb +2 -1
- data/lib/elasticsearch/api/actions/indices/get_mapping.rb +8 -3
- data/lib/elasticsearch/api/actions/indices/get_settings.rb +7 -2
- data/lib/elasticsearch/api/actions/indices/get_warmer.rb +0 -2
- data/lib/elasticsearch/api/actions/indices/put_alias.rb +0 -1
- data/lib/elasticsearch/api/actions/indices/put_mapping.rb +11 -4
- data/lib/elasticsearch/api/actions/indices/put_warmer.rb +0 -1
- data/lib/elasticsearch/api/actions/mpercolate.rb +58 -0
- data/lib/elasticsearch/api/actions/mtermvectors.rb +67 -0
- data/lib/elasticsearch/api/actions/{cluster/node_hot_threads.rb → nodes/hot_threads.rb} +3 -3
- data/lib/elasticsearch/api/actions/{cluster/node_info.rb → nodes/info.rb} +3 -3
- data/lib/elasticsearch/api/actions/{cluster/node_shutdown.rb → nodes/shutdown.rb} +3 -3
- data/lib/elasticsearch/api/actions/nodes/stats.rb +79 -0
- data/lib/elasticsearch/api/actions/percolate.rb +67 -21
- data/lib/elasticsearch/api/actions/snapshot/create.rb +48 -0
- data/lib/elasticsearch/api/actions/snapshot/create_repository.rb +44 -0
- data/lib/elasticsearch/api/actions/snapshot/delete.rb +41 -0
- data/lib/elasticsearch/api/actions/snapshot/delete_repository.rb +38 -0
- data/lib/elasticsearch/api/actions/snapshot/get.rb +47 -0
- data/lib/elasticsearch/api/actions/snapshot/get_repository.rb +42 -0
- data/lib/elasticsearch/api/actions/snapshot/restore.rb +53 -0
- data/lib/elasticsearch/api/actions/termvector.rb +77 -0
- data/lib/elasticsearch/api/namespace/cat.rb +20 -0
- data/lib/elasticsearch/api/namespace/nodes.rb +20 -0
- data/lib/elasticsearch/api/namespace/snapshot.rb +20 -0
- data/lib/elasticsearch/api/utils.rb +2 -4
- data/lib/elasticsearch/api/version.rb +1 -1
- data/test/integration/yaml_test_runner.rb +37 -8
- data/test/unit/cat/aliases_test.rb +26 -0
- data/test/unit/cat/allocation_test.rb +26 -0
- data/test/unit/cat/count_test.rb +26 -0
- data/test/unit/cat/health_test.rb +26 -0
- data/test/unit/cat/help_test.rb +26 -0
- data/test/unit/cat/indices_test.rb +26 -0
- data/test/unit/cat/master_test.rb +26 -0
- data/test/unit/cat/nodes_test.rb +26 -0
- data/test/unit/cat/pending_tasks_test.rb +26 -0
- data/test/unit/cat/recovery_test.rb +26 -0
- data/test/unit/cat/shards_test.rb +26 -0
- data/test/unit/cluster/state_test.rb +12 -3
- data/test/unit/count_percolate_test.rb +26 -0
- data/test/unit/indices/exists_alias_test.rb +0 -6
- data/test/unit/indices/exists_template_test.rb +59 -0
- data/test/unit/indices/get_alias_test.rb +0 -6
- data/test/unit/indices/get_aliases_test.rb +10 -0
- data/test/unit/indices/get_field_mapping_test.rb +1 -1
- data/test/unit/indices/get_mapping_test.rb +3 -3
- data/test/unit/indices/get_settings_test.rb +10 -0
- data/test/unit/indices/get_warmer_test.rb +0 -6
- data/test/unit/indices/put_alias_test.rb +0 -6
- data/test/unit/indices/put_mapping_test.rb +5 -11
- data/test/unit/indices/put_settings_test.rb +9 -0
- data/test/unit/indices/put_warmer_test.rb +0 -6
- data/test/unit/mpercolate_test.rb +51 -0
- data/test/unit/mtermvectors_test.rb +38 -0
- data/test/unit/{cluster/node_hot_threads_test.rb → nodes/hot_threads_test.rb} +5 -5
- data/test/unit/{cluster/node_info_test.rb → nodes/info_test.rb} +6 -6
- data/test/unit/{cluster/node_shutdown_test.rb → nodes/shutdown_test.rb} +6 -6
- data/test/unit/{cluster/node_stats_test.rb → nodes/stats_test.rb} +10 -10
- data/test/unit/percolate_test.rb +2 -13
- data/test/unit/snapshot/create_repository_test.rb +38 -0
- data/test/unit/snapshot/create_test.rb +38 -0
- data/test/unit/snapshot/delete_repository_test.rb +35 -0
- data/test/unit/snapshot/delete_test.rb +38 -0
- data/test/unit/snapshot/get_repository_test.rb +26 -0
- data/test/unit/snapshot/get_test.rb +38 -0
- data/test/unit/snapshot/restore_test.rb +38 -0
- data/test/unit/termvector_test.rb +44 -0
- data/test/unit/utils_test.rb +11 -0
- metadata +89 -17
- data/lib/elasticsearch/api/actions/cluster/node_stats.rb +0 -75
@@ -0,0 +1,20 @@
|
|
1
|
+
module Elasticsearch
|
2
|
+
module API
|
3
|
+
module Cat
|
4
|
+
module Actions; end
|
5
|
+
|
6
|
+
# Client for the "cat" namespace (includes the {Cat::Actions} methods)
|
7
|
+
#
|
8
|
+
class CatClient
|
9
|
+
include Common::Client, Common::Client::Base, Cat::Actions
|
10
|
+
end
|
11
|
+
|
12
|
+
# Proxy method for {CatClient}, available in the receiving object
|
13
|
+
#
|
14
|
+
def cat
|
15
|
+
@cat ||= CatClient.new(self)
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Elasticsearch
|
2
|
+
module API
|
3
|
+
module Nodes
|
4
|
+
module Actions; end
|
5
|
+
|
6
|
+
# Client for the "nodes" namespace (includes the {Nodes::Actions} methods)
|
7
|
+
#
|
8
|
+
class NodesClient
|
9
|
+
include Common::Client, Common::Client::Base, Nodes::Actions
|
10
|
+
end
|
11
|
+
|
12
|
+
# Proxy method for {NodesClient}, available in the receiving object
|
13
|
+
#
|
14
|
+
def nodes
|
15
|
+
@nodes ||= NodesClient.new(self)
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Elasticsearch
|
2
|
+
module API
|
3
|
+
module Snapshot
|
4
|
+
module Actions; end
|
5
|
+
|
6
|
+
# Client for the "snapshot" namespace (includes the {Snapshot::Actions} methods)
|
7
|
+
#
|
8
|
+
class SnapshotClient
|
9
|
+
include Common::Client, Common::Client::Base, Snapshot::Actions
|
10
|
+
end
|
11
|
+
|
12
|
+
# Proxy method for {SnapshotClient}, available in the receiving object
|
13
|
+
#
|
14
|
+
def snapshot
|
15
|
+
@snapshot ||= SnapshotClient.new(self)
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -30,8 +30,6 @@ module Elasticsearch
|
|
30
30
|
#
|
31
31
|
# @api private
|
32
32
|
def __listify(*list)
|
33
|
-
# require 'pry'
|
34
|
-
# binding.pry
|
35
33
|
Array(list).flatten.
|
36
34
|
map { |e| e.respond_to?(:split) ? e.split(',') : e }.
|
37
35
|
flatten.
|
@@ -124,10 +122,10 @@ module Elasticsearch
|
|
124
122
|
def __validate_and_extract_params(arguments, valid_params=[])
|
125
123
|
arguments.each do |k,v|
|
126
124
|
raise ArgumentError, "URL parameter '#{k}' is not supported" \
|
127
|
-
unless
|
125
|
+
unless COMMON_PARAMS.include?(k) || COMMON_QUERY_PARAMS.include?(k) || valid_params.include?(k)
|
128
126
|
end
|
129
127
|
|
130
|
-
params = arguments.select { |k,v| valid_params.include?(k) }
|
128
|
+
params = arguments.select { |k,v| COMMON_QUERY_PARAMS.include?(k) || valid_params.include?(k) }
|
131
129
|
params = Hash[params] unless params.is_a?(Hash) # Normalize Ruby 1.8 and Ruby 1.9 Hash#select behaviour
|
132
130
|
params
|
133
131
|
end
|
@@ -13,6 +13,9 @@ require 'elasticsearch/extensions/test/cluster'
|
|
13
13
|
require 'elasticsearch/extensions/test/startup_shutdown'
|
14
14
|
require 'elasticsearch/extensions/test/profiling' unless JRUBY
|
15
15
|
|
16
|
+
# Skip features
|
17
|
+
SKIP_FEATURES = ENV['TEST_SKIP_FEATURES'] || ''
|
18
|
+
|
16
19
|
# Turn configuration
|
17
20
|
ENV['ansi'] = 'false' if ENV['CI']
|
18
21
|
Turn.config.format = :pretty
|
@@ -215,7 +218,9 @@ module Elasticsearch
|
|
215
218
|
|
216
219
|
def skip?(actions)
|
217
220
|
skip = actions.select { |a| a['skip'] }.first
|
218
|
-
|
221
|
+
|
222
|
+
# Skip version
|
223
|
+
if skip && skip['skip']['version']
|
219
224
|
min, max = skip['skip']['version'].split('-').map(&:strip)
|
220
225
|
|
221
226
|
min_normalized = sprintf "%03d-%03d-%03d",
|
@@ -234,7 +239,14 @@ module Elasticsearch
|
|
234
239
|
if min_normalized <= es_normalized && max_normalized >= es_normalized
|
235
240
|
return skip['skip']['reason'] ? skip['skip']['reason'] : true
|
236
241
|
end
|
242
|
+
|
243
|
+
# Skip features
|
244
|
+
elsif skip && skip['skip']['features']
|
245
|
+
if (skip['skip']['features'].split(',') & SKIP_FEATURES.split(',') ).size > 0
|
246
|
+
return skip['skip']['features']
|
247
|
+
end
|
237
248
|
end
|
249
|
+
|
238
250
|
return false
|
239
251
|
end
|
240
252
|
|
@@ -278,9 +290,11 @@ suites.each do |suite|
|
|
278
290
|
# Extract setup actions
|
279
291
|
setup_actions = tests.select { |t| t['setup'] }.first['setup'] rescue []
|
280
292
|
|
281
|
-
# Skip all the tests when `skip` is part
|
282
|
-
|
283
|
-
|
293
|
+
# Skip all the tests when `skip` is part of the `setup` part
|
294
|
+
if features = Runner.skip?(setup_actions)
|
295
|
+
$stdout.puts "#{'SKIP'.ansi(:yellow)} [#{name}] #{file.gsub(PATH.to_s, '').ansi(:bold)} (Feature not implemented: #{features})"
|
296
|
+
next
|
297
|
+
end
|
284
298
|
|
285
299
|
# Remove setup actions from tests
|
286
300
|
tests = tests.reject { |t| t['setup'] }
|
@@ -365,10 +379,25 @@ suites.each do |suite|
|
|
365
379
|
when a = action['match']
|
366
380
|
property, value = a.to_a.first
|
367
381
|
|
368
|
-
value
|
369
|
-
|
370
|
-
|
371
|
-
|
382
|
+
if value.is_a?(String) && value =~ %r{\s*^/\s*.*\s*/$\s*}mx # Begins and ends with /
|
383
|
+
pattern = Regexp.new(value.strip[1..-2], Regexp::EXTENDED|Regexp::MULTILINE)
|
384
|
+
else
|
385
|
+
value = Runner.fetch_or_return(value)
|
386
|
+
end
|
387
|
+
|
388
|
+
if property == '$body'
|
389
|
+
result = $results[test.hash]
|
390
|
+
else
|
391
|
+
result = Runner.evaluate(test, property)
|
392
|
+
end
|
393
|
+
|
394
|
+
if pattern
|
395
|
+
$stderr.puts "CHECK: Expected '#{property}' to match #{pattern}, is: #{result.inspect}" if ENV['DEBUG']
|
396
|
+
assert_match(pattern, result)
|
397
|
+
else
|
398
|
+
$stderr.puts "CHECK: Expected '#{property}' to be '#{value}', is: #{result.inspect}" if ENV['DEBUG']
|
399
|
+
assert_equal(value, result)
|
400
|
+
end
|
372
401
|
|
373
402
|
when a = action['length']
|
374
403
|
property, value = a.to_a.first
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Elasticsearch
|
4
|
+
module Test
|
5
|
+
class CatAliasesTest < ::Test::Unit::TestCase
|
6
|
+
|
7
|
+
context "Cat: Aliases" do
|
8
|
+
subject { FakeClient.new }
|
9
|
+
|
10
|
+
should "perform correct request" do
|
11
|
+
subject.expects(:perform_request).with do |method, url, params, body|
|
12
|
+
assert_equal 'GET', method
|
13
|
+
assert_equal '_cat/aliases', url
|
14
|
+
assert_equal Hash.new, params
|
15
|
+
assert_nil body
|
16
|
+
true
|
17
|
+
end.returns(FakeResponse.new)
|
18
|
+
|
19
|
+
subject.cat.aliases
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Elasticsearch
|
4
|
+
module Test
|
5
|
+
class CatAllocationTest < ::Test::Unit::TestCase
|
6
|
+
|
7
|
+
context "Cat: Allocation" do
|
8
|
+
subject { FakeClient.new }
|
9
|
+
|
10
|
+
should "perform correct request" do
|
11
|
+
subject.expects(:perform_request).with do |method, url, params, body|
|
12
|
+
assert_equal 'GET', method
|
13
|
+
assert_equal '_cat/allocation', url
|
14
|
+
assert_equal Hash.new, params
|
15
|
+
assert_nil body
|
16
|
+
true
|
17
|
+
end.returns(FakeResponse.new)
|
18
|
+
|
19
|
+
subject.cat.allocation
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Elasticsearch
|
4
|
+
module Test
|
5
|
+
class CatCountTest < ::Test::Unit::TestCase
|
6
|
+
|
7
|
+
context "Cat: Count" do
|
8
|
+
subject { FakeClient.new }
|
9
|
+
|
10
|
+
should "perform correct request" do
|
11
|
+
subject.expects(:perform_request).with do |method, url, params, body|
|
12
|
+
assert_equal 'GET', method
|
13
|
+
assert_equal '_cat/count', url
|
14
|
+
assert_equal Hash.new, params
|
15
|
+
assert_nil body
|
16
|
+
true
|
17
|
+
end.returns(FakeResponse.new)
|
18
|
+
|
19
|
+
subject.cat.count
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Elasticsearch
|
4
|
+
module Test
|
5
|
+
class CatHealthTest < ::Test::Unit::TestCase
|
6
|
+
|
7
|
+
context "Cat: Health" do
|
8
|
+
subject { FakeClient.new }
|
9
|
+
|
10
|
+
should "perform correct request" do
|
11
|
+
subject.expects(:perform_request).with do |method, url, params, body|
|
12
|
+
assert_equal 'GET', method
|
13
|
+
assert_equal '_cat/health', url
|
14
|
+
assert_equal Hash.new, params
|
15
|
+
assert_nil body
|
16
|
+
true
|
17
|
+
end.returns(FakeResponse.new)
|
18
|
+
|
19
|
+
subject.cat.health
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Elasticsearch
|
4
|
+
module Test
|
5
|
+
class CatHelpTest < ::Test::Unit::TestCase
|
6
|
+
|
7
|
+
context "Cat: Help" do
|
8
|
+
subject { FakeClient.new }
|
9
|
+
|
10
|
+
should "perform correct request" do
|
11
|
+
subject.expects(:perform_request).with do |method, url, params, body|
|
12
|
+
assert_equal 'GET', method
|
13
|
+
assert_equal '_cat', url
|
14
|
+
assert_equal Hash.new, params
|
15
|
+
assert_nil body
|
16
|
+
true
|
17
|
+
end.returns(FakeResponse.new)
|
18
|
+
|
19
|
+
subject.cat.help
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Elasticsearch
|
4
|
+
module Test
|
5
|
+
class CatIndicesTest < ::Test::Unit::TestCase
|
6
|
+
|
7
|
+
context "Cat: Indices" do
|
8
|
+
subject { FakeClient.new }
|
9
|
+
|
10
|
+
should "perform correct request" do
|
11
|
+
subject.expects(:perform_request).with do |method, url, params, body|
|
12
|
+
assert_equal 'GET', method
|
13
|
+
assert_equal '_cat/indices', url
|
14
|
+
assert_equal Hash.new, params
|
15
|
+
assert_nil body
|
16
|
+
true
|
17
|
+
end.returns(FakeResponse.new)
|
18
|
+
|
19
|
+
subject.cat.indices
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Elasticsearch
|
4
|
+
module Test
|
5
|
+
class CatMasterTest < ::Test::Unit::TestCase
|
6
|
+
|
7
|
+
context "Cat: Master" do
|
8
|
+
subject { FakeClient.new }
|
9
|
+
|
10
|
+
should "perform correct request" do
|
11
|
+
subject.expects(:perform_request).with do |method, url, params, body|
|
12
|
+
assert_equal 'GET', method
|
13
|
+
assert_equal '_cat/master', url
|
14
|
+
assert_equal Hash.new, params
|
15
|
+
assert_nil body
|
16
|
+
true
|
17
|
+
end.returns(FakeResponse.new)
|
18
|
+
|
19
|
+
subject.cat.master
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Elasticsearch
|
4
|
+
module Test
|
5
|
+
class CatNodesTest < ::Test::Unit::TestCase
|
6
|
+
|
7
|
+
context "Cat: Nodes" do
|
8
|
+
subject { FakeClient.new }
|
9
|
+
|
10
|
+
should "perform correct request" do
|
11
|
+
subject.expects(:perform_request).with do |method, url, params, body|
|
12
|
+
assert_equal 'GET', method
|
13
|
+
assert_equal '_cat/nodes', url
|
14
|
+
assert_equal Hash.new, params
|
15
|
+
assert_nil body
|
16
|
+
true
|
17
|
+
end.returns(FakeResponse.new)
|
18
|
+
|
19
|
+
subject.cat.nodes
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Elasticsearch
|
4
|
+
module Test
|
5
|
+
class CatPendingTasksTest < ::Test::Unit::TestCase
|
6
|
+
|
7
|
+
context "Cat: Pending tasks" do
|
8
|
+
subject { FakeClient.new }
|
9
|
+
|
10
|
+
should "perform correct request" do
|
11
|
+
subject.expects(:perform_request).with do |method, url, params, body|
|
12
|
+
assert_equal 'GET', method
|
13
|
+
assert_equal '_cat/pending_tasks', url
|
14
|
+
assert_equal Hash.new, params
|
15
|
+
assert_nil body
|
16
|
+
true
|
17
|
+
end.returns(FakeResponse.new)
|
18
|
+
|
19
|
+
subject.cat.pending_tasks
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Elasticsearch
|
4
|
+
module Test
|
5
|
+
class CatRecoveryTest < ::Test::Unit::TestCase
|
6
|
+
|
7
|
+
context "Cat: Recovery" do
|
8
|
+
subject { FakeClient.new }
|
9
|
+
|
10
|
+
should "perform correct request" do
|
11
|
+
subject.expects(:perform_request).with do |method, url, params, body|
|
12
|
+
assert_equal 'GET', method
|
13
|
+
assert_equal '_cat/recovery', url
|
14
|
+
assert_equal Hash.new, params
|
15
|
+
assert_nil body
|
16
|
+
true
|
17
|
+
end.returns(FakeResponse.new)
|
18
|
+
|
19
|
+
subject.cat.recovery
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|