amee 3.2.1 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. data/CHANGELOG.txt +1 -24
  2. data/Gemfile +7 -8
  3. data/Gemfile.lock +33 -14
  4. data/README.txt +33 -15
  5. data/Rakefile +15 -29
  6. data/VERSION +1 -1
  7. data/amee.gemspec +21 -24
  8. data/lib/amee.rb +11 -0
  9. data/lib/amee/connection.rb +1 -1
  10. data/lib/amee/logger.rb +10 -5
  11. data/lib/amee/rails.rb +12 -16
  12. data/lib/amee/v3.rb +2 -0
  13. data/lib/amee/v3/collection.rb +4 -6
  14. data/lib/amee/v3/connection.rb +0 -5
  15. data/lib/amee/v3/item_definition.rb +12 -19
  16. data/lib/amee/v3/item_value_definition.rb +6 -7
  17. data/lib/amee/v3/item_value_definition_list.rb +3 -3
  18. data/lib/amee/v3/return_value_definition.rb +4 -4
  19. data/spec/amee_spec.rb +1 -1
  20. data/spec/cache_spec.rb +1 -1
  21. data/spec/connection_spec.rb +1 -1
  22. data/spec/data_category_spec.rb +4 -4
  23. data/spec/data_item_spec.rb +5 -5
  24. data/spec/data_item_value_history_spec.rb +1 -1
  25. data/spec/data_item_value_spec.rb +1 -1
  26. data/spec/data_object_spec.rb +1 -1
  27. data/spec/drill_down_spec.rb +1 -1
  28. data/spec/fixtures/itemdef.xml +1 -6
  29. data/spec/fixtures/itemdef_441BF4BEA15B.xml +12 -20
  30. data/spec/item_definition_spec.rb +7 -7
  31. data/spec/item_value_definition_spec.rb +9 -9
  32. data/spec/logger_spec.rb +1 -1
  33. data/spec/object_spec.rb +1 -1
  34. data/spec/parse_helper_spec.rb +1 -1
  35. data/spec/profile_category_spec.rb +19 -19
  36. data/spec/profile_item_spec.rb +16 -16
  37. data/spec/profile_item_value_spec.rb +1 -1
  38. data/spec/profile_object_spec.rb +1 -1
  39. data/spec/profile_spec.rb +1 -1
  40. data/spec/rails_spec.rb +1 -6
  41. data/spec/spec_helper.rb +3 -4
  42. data/spec/user_spec.rb +7 -7
  43. data/spec/v3/connection_spec.rb +11 -11
  44. data/spec/v3/item_definition_spec.rb +13 -15
  45. data/spec/v3/item_value_definition_spec.rb +6 -6
  46. data/spec/v3/return_value_definition_spec.rb +10 -9
  47. metadata +87 -79
  48. data/init.rb +0 -4
  49. data/lib/amee/config.rb +0 -37
  50. data/lib/amee/core-extensions/hash.rb +0 -43
  51. data/rails/init.rb +0 -18
  52. data/spec/fixtures/rails_config.yml +0 -13
  53. data/spec/spec_amee_config.rb +0 -46
data/CHANGELOG.txt CHANGED
@@ -1,28 +1,5 @@
1
1
  = Changelog
2
2
 
3
- == 3.2.1
4
- * Add algorithm details to ItemDefinitions
5
- * Bugfix when using AMEE::Rails.connection from locations other than Rails.root
6
-
7
- == 3.2.0
8
- * Add algorithm details to ItemDefinitions
9
-
10
- == 4.1.3 (also 3.1.2 for Rails 2)
11
- * Documentation update
12
-
13
- == 4.1.2 (also 3.1.1 for Rails 2)
14
- * Fix bug in initialisation of AMEE::Rails#connection from configuration.
15
-
16
- == 4.1.1
17
- * Configuration bugfix
18
-
19
- == 4.1.0 (also 3.1.0 for Rails 2)
20
- * Add option to set connection details using environment variables, for
21
- instance in Heroku deployments.
22
-
23
- == 4.0.0
24
- * Rails 3 support. Rails 2 apps will not work with this version.
25
-
26
3
  == 3.0.0
27
4
  * Add some pre-release functionality for AMEEconnect v3 in order to support
28
5
  AMEEappkit gems.
@@ -66,4 +43,4 @@
66
43
  * Include accessors from other objects
67
44
  * Internal improvements including
68
45
  * Improved paging support
69
- * Tidier code for collections
46
+ * Tidier code for collections
data/Gemfile CHANGED
@@ -1,18 +1,17 @@
1
1
  source "http://rubygems.org"
2
2
 
3
- gem "activesupport", "~> 2.3.5"
3
+ gem "activesupport", "~> 3.0.10"
4
4
  gem "json"
5
5
  gem "log4r"
6
6
  gem "nokogiri", "~> 1.4.3.1"
7
7
 
8
- # Add dependencies to develop your gem here.
9
- # Include everything needed to run rake, tests, features, etc.
10
8
  group :development do
11
9
  gem "bundler", "~> 1.0.0"
12
10
  gem "jeweler", "~> 1.6.4"
13
- gem 'rspec', '1.3.0'
11
+ gem 'rspec', '2.6.0'
12
+ gem 'flexmock', '> 0.8.6'
13
+ gem 'memcache-client'
14
14
  gem 'rcov'
15
- gem 'rspec_spinner', '1.1.3'
16
- gem 'activerecord', "~> 2.3.5" # To test Rails integration
17
- gem 'flexmock'
18
- end
15
+ gem 'rdoc'
16
+ gem 'activerecord', "~> 3.0.10" # To test Rails integration
17
+ end
data/Gemfile.lock CHANGED
@@ -1,37 +1,56 @@
1
1
  GEM
2
2
  remote: http://rubygems.org/
3
3
  specs:
4
- activerecord (2.3.12)
5
- activesupport (= 2.3.12)
6
- activesupport (2.3.12)
4
+ activemodel (3.0.10)
5
+ activesupport (= 3.0.10)
6
+ builder (~> 2.1.2)
7
+ i18n (~> 0.5.0)
8
+ activerecord (3.0.10)
9
+ activemodel (= 3.0.10)
10
+ activesupport (= 3.0.10)
11
+ arel (~> 2.0.10)
12
+ tzinfo (~> 0.3.23)
13
+ activesupport (3.0.10)
14
+ arel (2.0.10)
15
+ builder (2.1.2)
16
+ diff-lcs (1.1.3)
7
17
  flexmock (0.9.0)
8
18
  git (1.2.5)
19
+ i18n (0.5.0)
9
20
  jeweler (1.6.4)
10
21
  bundler (~> 1.0)
11
22
  git (>= 1.2.5)
12
23
  rake
13
- json (1.5.3)
24
+ json (1.5.4)
14
25
  log4r (1.1.9)
26
+ memcache-client (1.8.5)
15
27
  nokogiri (1.4.3.1)
16
28
  rake (0.9.2)
17
- rcov (0.9.9)
18
- rspec (1.3.0)
19
- rspec_spinner (1.1.3)
20
- rtui
21
- rtui (0.2.2)
29
+ rcov (0.9.10)
30
+ rdoc (3.9.4)
31
+ rspec (2.6.0)
32
+ rspec-core (~> 2.6.0)
33
+ rspec-expectations (~> 2.6.0)
34
+ rspec-mocks (~> 2.6.0)
35
+ rspec-core (2.6.4)
36
+ rspec-expectations (2.6.0)
37
+ diff-lcs (~> 1.1.2)
38
+ rspec-mocks (2.6.0)
39
+ tzinfo (0.3.29)
22
40
 
23
41
  PLATFORMS
24
42
  ruby
25
43
 
26
44
  DEPENDENCIES
27
- activerecord (~> 2.3.5)
28
- activesupport (~> 2.3.5)
45
+ activerecord (~> 3.0.10)
46
+ activesupport (~> 3.0.10)
29
47
  bundler (~> 1.0.0)
30
- flexmock
48
+ flexmock (> 0.8.6)
31
49
  jeweler (~> 1.6.4)
32
50
  json
33
51
  log4r
52
+ memcache-client
34
53
  nokogiri (~> 1.4.3.1)
35
54
  rcov
36
- rspec (= 1.3.0)
37
- rspec_spinner (= 1.1.3)
55
+ rdoc
56
+ rspec (= 2.6.0)
data/README.txt CHANGED
@@ -19,14 +19,22 @@ Documentation: http://rubydoc.info/gems/amee/frames
19
19
 
20
20
  == REQUIREMENTS
21
21
 
22
- If you are using Rails, note that version 4.x of this gem supports Rails 3 apps
23
- only. If you are using Rails 2, you should stay with version 3.x. See the 'Rails'
24
- section below for more details.
25
-
26
22
  'Nokogiri' is used for XML parsing, and requires libxml2. See
27
23
  http://nokogiri.org/tutorials/installing_nokogiri.html for instructions if you
28
24
  have problems installing.
29
25
 
26
+ == IMPORTANT CHANGES when upgrading to 2.2.0 and above
27
+
28
+ SSL connections are now supported, and are used BY DEFAULT.If you do not want to
29
+ use SSL, you can disable it using the ":ssl => false" option to Connection.new, or
30
+ by adding "ssl: false" to your amee.yml if you are using Rails.
31
+
32
+ == IMPORTANT CHANGES when upgrading beyond 2.0.25
33
+
34
+ If you are using the $amee connection in your Rails apps, this is now deprecated
35
+ and will be removed in future releases. See the "Rails" section below for details
36
+ of what you should use instead.
37
+
30
38
  == USAGE
31
39
 
32
40
  Currently, you can read DataCategories, DataItems and DataItemValues. See
@@ -58,13 +66,11 @@ this interface yet.
58
66
 
59
67
  == RAILS
60
68
 
61
- This gem can also be used as a Rails plugin.
62
-
63
- Rails 2: add the following to environment.rb:
64
- config.gem "amee", :version => '~> 3.1'
69
+ This gem can also be used as a Rails plugin. You can either extract it into
70
+ vendor/plugins, or use the new-style config.gem command in environment.rb. For
71
+ example:
65
72
 
66
- Rails 3: add the following to your Gemfile:
67
- gem "amee", '~> 4.1'
73
+ config.gem "amee", :version => '~> 2.2.0'
68
74
 
69
75
  If you copy amee.example.yml from the gem source directory to amee.yml in your
70
76
  app's config directory, a persistent AMEE connection will be available from
@@ -76,10 +82,6 @@ also use the global_amee_connection function to access the same global connectio
76
82
  If you do not use this facility, you will have to create your own connection
77
83
  objects and manage them yourself, which you can do using AMEE::Connection#new
78
84
 
79
- Instead of using an amee.yml file, you can set ENV['AMEE_USERNAME'], ENV['AMEE_PASSWORD']
80
- and ENV['AMEE_SERVER'] to achieve the same effect. This is useful for deploying
81
- to environments like Heroku, for instance.
82
-
83
85
  There is a helper for ActiveRecord models which should be linked to an AMEE profile.
84
86
  By adding:
85
87
 
@@ -116,4 +118,20 @@ change the number of retry attempts, 3 is just used as an example above.
116
118
 
117
119
  The Connection object also allows a timeout to be set for requests. By default this is
118
120
  set to 60 seconds, but if you want to provide a different value (30 seconds for
119
- instance), pass ':timeout => 30' to AMEE::Connection.new, or 'timeout: 30' in amee.yml.
121
+ instance), pass ':timeout => 30' to AMEE::Connection.new, or 'timeout: 30' in amee.yml.
122
+
123
+ == UPGRADING TO VERSION > 2
124
+
125
+ There are a few changes to the API exposed by this gem for version 2. The main
126
+ ones are:
127
+
128
+ 1) AMEE::Connection#new takes a hash of options instead of an explicit parameter list.
129
+ Whereas before you would have used new(server, username, password, use_json, enable_cache, enable_debug)
130
+ you would now use new(server, username, password, :format => :json, :enable_caching => true, :enable_debug => true)
131
+
132
+ 2) Many get functions take a hash of options instead of explicit date and itemsPerPage parameters.
133
+ get(... , :start_date => {your_date}, :itemsPerPage => 20)
134
+
135
+ 3) total_amount_per_month functions have been replaced with total_amount. There are also
136
+ total_amount_unit and total_amount_per_unit functions which give the units that the total
137
+ amount is in.
data/Rakefile CHANGED
@@ -10,16 +10,14 @@ rescue Bundler::BundlerError => e
10
10
  exit e.status_code
11
11
  end
12
12
  require 'rake'
13
- require 'spec'
14
- require 'spec/rake/spectask'
13
+ require 'rspec'
14
+ require 'rspec/core/rake_task'
15
15
 
16
16
  task :default => [:spec]
17
17
 
18
- Spec::Rake::SpecTask.new do |t|
19
- t.spec_opts = ['--options', "spec/spec.opts"]
20
- t.spec_files = FileList['spec/**/*_spec.rb']
21
- t.rcov = true
22
- t.rcov_opts = ['--exclude', 'spec,/*ruby*,']
18
+ desc "Run specs"
19
+ RSpec::Core::RakeTask.new do |t|
20
+ # Put spec opts in a file named .rspec in root
23
21
  end
24
22
 
25
23
  require 'jeweler'
@@ -70,29 +68,17 @@ Jeweler::Tasks.new do |gem|
70
68
  end
71
69
  Jeweler::RubygemsDotOrgTasks.new
72
70
 
73
- require 'rake/testtask'
74
- Rake::TestTask.new(:test) do |test|
75
- test.libs << 'lib' << 'test'
76
- test.pattern = 'test/**/test_*.rb'
77
- test.verbose = true
78
- end
79
-
80
71
  require 'rcov/rcovtask'
81
- Rcov::RcovTask.new do |test|
82
- test.libs << 'test'
83
- test.pattern = 'test/**/test_*.rb'
84
- test.verbose = true
85
- test.rcov_opts << '--exclude "gems/*"'
72
+ desc "Generate code coverage"
73
+ RSpec::Core::RakeTask.new(:coverage) do |t|
74
+ t.rcov = true
75
+ t.rcov_opts = ['--exclude', 'spec']
86
76
  end
87
77
 
88
- task :default => :test
89
-
90
- require 'rake/rdoctask'
91
- Rake::RDocTask.new do |rdoc|
92
- version = File.exist?('VERSION') ? File.read('VERSION') : ""
93
-
94
- rdoc.rdoc_dir = 'rdoc'
95
- rdoc.title = "amee-ruby #{version}"
96
- rdoc.rdoc_files.include('README*')
97
- rdoc.rdoc_files.include('lib/**/*.rb')
78
+ require 'rdoc/task'
79
+ RDoc::Task.new do |rd|
80
+ rd.title = "AMEE Ruby"
81
+ rd.rdoc_dir = 'doc'
82
+ rd.main = "README"
83
+ rd.rdoc_files.include("README", "lib/**/*.rb")
98
84
  end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 3.2.1
1
+ 4.0.0
data/amee.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{amee}
8
- s.version = "3.2.1"
8
+ s.version = "4.0.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["James Smith", "James Hetherington", "Andrew Hill", "Andrew Berkeley"]
12
- s.date = %q{2011-11-16}
12
+ s.date = %q{2011-09-28}
13
13
  s.default_executable = %q{ameesh}
14
14
  s.email = %q{james@floppy.org.uk}
15
15
  s.executables = ["ameesh"]
@@ -36,12 +36,9 @@ Gem::Specification.new do |s|
36
36
  "examples/view_data_category.rb",
37
37
  "examples/view_data_item.rb",
38
38
  "examples/view_profile_item.rb",
39
- "init.rb",
40
39
  "lib/amee.rb",
41
40
  "lib/amee/collection.rb",
42
- "lib/amee/config.rb",
43
41
  "lib/amee/connection.rb",
44
- "lib/amee/core-extensions/hash.rb",
45
42
  "lib/amee/data_category.rb",
46
43
  "lib/amee/data_item.rb",
47
44
  "lib/amee/data_item_value.rb",
@@ -71,7 +68,6 @@ Gem::Specification.new do |s|
71
68
  "lib/amee/v3/item_value_definition_list.rb",
72
69
  "lib/amee/v3/meta_helper.rb",
73
70
  "lib/amee/v3/return_value_definition.rb",
74
- "rails/init.rb",
75
71
  "spec/amee_spec.rb",
76
72
  "spec/cache_spec.rb",
77
73
  "spec/connection_spec.rb",
@@ -101,7 +97,6 @@ Gem::Specification.new do |s|
101
97
  "spec/fixtures/ivdlist.xml",
102
98
  "spec/fixtures/ivdlist_BD88D30D1214.xml",
103
99
  "spec/fixtures/parse_test.xml",
104
- "spec/fixtures/rails_config.yml",
105
100
  "spec/fixtures/return_value_definition.xml",
106
101
  "spec/fixtures/return_value_definition_list.xml",
107
102
  "spec/fixtures/v0_data_transport_transport_drill_transportType_Car1.xml",
@@ -117,7 +112,6 @@ Gem::Specification.new do |s|
117
112
  "spec/profile_spec.rb",
118
113
  "spec/rails_spec.rb",
119
114
  "spec/spec.opts",
120
- "spec/spec_amee_config.rb",
121
115
  "spec/spec_helper.rb",
122
116
  "spec/user_spec.rb",
123
117
  "spec/v3/connection_spec.rb",
@@ -128,49 +122,52 @@ Gem::Specification.new do |s|
128
122
  s.homepage = %q{http://github.com/AMEE/amee-ruby}
129
123
  s.licenses = ["BSD 3-Clause"]
130
124
  s.require_paths = ["lib"]
131
- s.rubygems_version = %q{1.6.2}
125
+ s.rubygems_version = %q{1.4.2}
132
126
  s.summary = %q{Ruby interface to the AMEE carbon calculator}
133
127
 
134
128
  if s.respond_to? :specification_version then
135
129
  s.specification_version = 3
136
130
 
137
131
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
138
- s.add_runtime_dependency(%q<activesupport>, ["~> 2.3.5"])
132
+ s.add_runtime_dependency(%q<activesupport>, ["~> 3.0.10"])
139
133
  s.add_runtime_dependency(%q<json>, [">= 0"])
140
134
  s.add_runtime_dependency(%q<log4r>, [">= 0"])
141
135
  s.add_runtime_dependency(%q<nokogiri>, ["~> 1.4.3.1"])
142
136
  s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
143
137
  s.add_development_dependency(%q<jeweler>, ["~> 1.6.4"])
144
- s.add_development_dependency(%q<rspec>, ["= 1.3.0"])
138
+ s.add_development_dependency(%q<rspec>, ["= 2.6.0"])
139
+ s.add_development_dependency(%q<flexmock>, ["> 0.8.6"])
140
+ s.add_development_dependency(%q<memcache-client>, [">= 0"])
145
141
  s.add_development_dependency(%q<rcov>, [">= 0"])
146
- s.add_development_dependency(%q<rspec_spinner>, ["= 1.1.3"])
147
- s.add_development_dependency(%q<activerecord>, ["~> 2.3.5"])
148
- s.add_development_dependency(%q<flexmock>, [">= 0"])
142
+ s.add_development_dependency(%q<rdoc>, [">= 0"])
143
+ s.add_development_dependency(%q<activerecord>, ["~> 3.0.10"])
149
144
  else
150
- s.add_dependency(%q<activesupport>, ["~> 2.3.5"])
145
+ s.add_dependency(%q<activesupport>, ["~> 3.0.10"])
151
146
  s.add_dependency(%q<json>, [">= 0"])
152
147
  s.add_dependency(%q<log4r>, [">= 0"])
153
148
  s.add_dependency(%q<nokogiri>, ["~> 1.4.3.1"])
154
149
  s.add_dependency(%q<bundler>, ["~> 1.0.0"])
155
150
  s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
156
- s.add_dependency(%q<rspec>, ["= 1.3.0"])
151
+ s.add_dependency(%q<rspec>, ["= 2.6.0"])
152
+ s.add_dependency(%q<flexmock>, ["> 0.8.6"])
153
+ s.add_dependency(%q<memcache-client>, [">= 0"])
157
154
  s.add_dependency(%q<rcov>, [">= 0"])
158
- s.add_dependency(%q<rspec_spinner>, ["= 1.1.3"])
159
- s.add_dependency(%q<activerecord>, ["~> 2.3.5"])
160
- s.add_dependency(%q<flexmock>, [">= 0"])
155
+ s.add_dependency(%q<rdoc>, [">= 0"])
156
+ s.add_dependency(%q<activerecord>, ["~> 3.0.10"])
161
157
  end
162
158
  else
163
- s.add_dependency(%q<activesupport>, ["~> 2.3.5"])
159
+ s.add_dependency(%q<activesupport>, ["~> 3.0.10"])
164
160
  s.add_dependency(%q<json>, [">= 0"])
165
161
  s.add_dependency(%q<log4r>, [">= 0"])
166
162
  s.add_dependency(%q<nokogiri>, ["~> 1.4.3.1"])
167
163
  s.add_dependency(%q<bundler>, ["~> 1.0.0"])
168
164
  s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
169
- s.add_dependency(%q<rspec>, ["= 1.3.0"])
165
+ s.add_dependency(%q<rspec>, ["= 2.6.0"])
166
+ s.add_dependency(%q<flexmock>, ["> 0.8.6"])
167
+ s.add_dependency(%q<memcache-client>, [">= 0"])
170
168
  s.add_dependency(%q<rcov>, [">= 0"])
171
- s.add_dependency(%q<rspec_spinner>, ["= 1.1.3"])
172
- s.add_dependency(%q<activerecord>, ["~> 2.3.5"])
173
- s.add_dependency(%q<flexmock>, [">= 0"])
169
+ s.add_dependency(%q<rdoc>, [">= 0"])
170
+ s.add_dependency(%q<activerecord>, ["~> 3.0.10"])
174
171
  end
175
172
  end
176
173
 
data/lib/amee.rb CHANGED
@@ -4,6 +4,7 @@
4
4
  require 'rexml/document'
5
5
  require 'nokogiri'
6
6
  require 'active_support'
7
+ require 'active_support/time'
7
8
  require 'log4r'
8
9
 
9
10
  # We don't NEED the JSON gem, but if it's available, use it.
@@ -54,6 +55,16 @@ require 'amee/item_value_definition'
54
55
  require 'amee/user'
55
56
  require 'amee/v3'
56
57
 
58
+ if defined?(Rails)
59
+ require 'amee/rails'
60
+ ActiveRecord::Base.send :include, AMEE::Rails
61
+
62
+ amee_config = "config/amee.yml"
63
+ if File.exist?(amee_config)
64
+ $AMEE_CONFIG = YAML.load_file(amee_config)[Rails.env]
65
+ end
66
+ end
67
+
57
68
  class Date
58
69
  def amee1_date
59
70
  strftime("%Y%m%d")
@@ -32,7 +32,7 @@ module AMEE
32
32
  end
33
33
  # Create cache store
34
34
  if options[:cache] &&
35
- (options[:cache_store].is_a?(ActiveSupport::Cache::MemCacheStore) ||
35
+ (options[:cache_store].class.name == "ActiveSupport::Cache::MemCacheStore" ||
36
36
  options[:cache].to_sym == :mem_cache_store)
37
37
  raise 'ActiveSupport::Cache::MemCacheStore is not supported, as it doesn\'t allow regexp expiry'
38
38
  end
data/lib/amee/logger.rb CHANGED
@@ -7,15 +7,20 @@
7
7
  # AMEE::Log.to logtothis
8
8
 
9
9
  module AMEE
10
- module Logger
11
- @@log=Log4r::Logger.new('AMEERuby')
12
- @@log.outputters=[Log4r::StderrOutputter.new('AMEERubyStdout')]
13
- @@log.level=Log4r::WARN
10
+ class Logger
14
11
  def self.log
15
- @@log
12
+ @@log ||= setup_logger
16
13
  end
17
14
  def self.to(log)
18
15
  @@log=log
19
16
  end
17
+
18
+ private
19
+ def self.setup_logger
20
+ log = Log4r::Logger.new('AMEERuby')
21
+ log.outputters = [Log4r::StderrOutputter.new('AMEERubyStdout')]
22
+ log.level=Log4r::WARN
23
+ log
24
+ end
20
25
  end
21
26
  end