djatoka 0.0.11 → 0.0.12

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/Rakefile CHANGED
@@ -14,7 +14,7 @@ begin
14
14
  #gem.add_development_dependency "ruby-debug", ">= 0"
15
15
  gem.add_development_dependency "hanna", ">= 0"
16
16
  gem.add_development_dependency "fakeweb", ">= 0"
17
- gem.add_dependency "addressable", "2.1.2"
17
+ gem.add_dependency "addressable"
18
18
  gem.add_development_dependency "curb", ">= 0"
19
19
  gem.add_dependency "json", ">= 0"
20
20
  gem.add_dependency 'trollop', '>= 0'
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.11
1
+ 0.0.12
File without changes
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: djatoka
3
3
  version: !ruby/object:Gem::Version
4
- hash: 9
5
- prerelease: false
4
+ hash: 7
5
+ prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 11
10
- version: 0.0.11
9
+ - 12
10
+ version: 0.0.12
11
11
  platform: ruby
12
12
  authors:
13
13
  - Jason Ronallo
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-12-21 00:00:00 -05:00
18
+ date: 2011-08-02 00:00:00 -04:00
19
19
  default_executable: djatoka_url
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -66,14 +66,12 @@ dependencies:
66
66
  requirement: &id004 !ruby/object:Gem::Requirement
67
67
  none: false
68
68
  requirements:
69
- - - "="
69
+ - - ">="
70
70
  - !ruby/object:Gem::Version
71
- hash: 15
71
+ hash: 3
72
72
  segments:
73
- - 2
74
- - 1
75
- - 2
76
- version: 2.1.2
73
+ - 0
74
+ version: "0"
77
75
  type: :runtime
78
76
  version_requirements: *id004
79
77
  - !ruby/object:Gem::Dependency
@@ -167,13 +165,6 @@ files:
167
165
  - lib/djatoka/region.rb
168
166
  - lib/djatoka/resolver.rb
169
167
  - lib/djatoka/view_helpers.rb
170
- - test/helper.rb
171
- - test/test_common.rb
172
- - test/test_djatoka.rb
173
- - test/test_metadata.rb
174
- - test/test_region.rb
175
- - test/test_resolver.rb
176
- - test/test_view_helpers.rb
177
168
  has_rdoc: true
178
169
  homepage: http://github.com/jronallo/djatoka
179
170
  licenses: []
@@ -204,15 +195,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
204
195
  requirements: []
205
196
 
206
197
  rubyforge_project:
207
- rubygems_version: 1.3.7
198
+ rubygems_version: 1.6.2
208
199
  signing_key:
209
200
  specification_version: 3
210
201
  summary: Djatoka image server helpers for Ruby and Rails.
211
- test_files:
212
- - test/helper.rb
213
- - test/test_common.rb
214
- - test/test_djatoka.rb
215
- - test/test_metadata.rb
216
- - test/test_region.rb
217
- - test/test_resolver.rb
218
- - test/test_view_helpers.rb
202
+ test_files: []
203
+
@@ -1,43 +0,0 @@
1
- require 'rubygems'
2
- require 'test/unit'
3
- require 'shoulda'
4
- require 'fakeweb'
5
-
6
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
7
- $LOAD_PATH.unshift(File.dirname(__FILE__))
8
- require 'djatoka'
9
- #require 'ruby-debug'
10
-
11
- class Test::Unit::TestCase
12
- def self.with_a_resolver(&block)
13
- context 'resolver setup' do
14
- setup do
15
- @resolver = Djatoka::Resolver.new('http://african.lanl.gov/adore-djatoka/resolver')
16
- @identifier = 'info:lanl-repo/ds/5aa182c2-c092-4596-af6e-e95d2e263de3'
17
- @url_encoded_identifier = 'info%3Alanl-repo%2Fds%2F5aa182c2-c092-4596-af6e-e95d2e263de3'
18
- end
19
-
20
- merge_block(&block) if block_given?
21
- end
22
- end
23
-
24
- def set_testing_curb
25
- Djatoka.use_curb = false
26
- # begin
27
- # require 'curb'
28
- # Djatoka.use_curb = true
29
- # rescue LoadError
30
- # Djatoka.use_curb = false
31
- # end
32
- end
33
-
34
- end
35
-
36
-
37
- #curl -is -H 'Accept: application/json' -d "url_ver=Z39.88-2004&rft_id=ua023_015-006-bx0003-014-075&svc_id=info%3Alanl-repo%2Fsvc%2FgetMetadata" http://scrc.lib.ncsu.edu/adore-djatoka/resolver > test/fixtures/ua023_015-006-bx0003-014-075-metadata.json
38
-
39
- FakeWeb.register_uri(:get, "http://african.lanl.gov/adore-djatoka/resolver?rft_id=ua023_015-006-bx0003-014-075&svc_id=info%3Alanl-repo%2Fsvc%2FgetMetadata&url_ver=Z39.88-2004",
40
- :response => File.read('test/fixtures/ua023_015-006-bx0003-014-075-metadata.json'))
41
-
42
- FakeWeb.register_uri(:get, "http://african.lanl.gov/adore-djatoka/resolver?rft_id=asdf&svc_id=info%3Alanl-repo%2Fsvc%2FgetMetadata&url_ver=Z39.88-2004",
43
- :response => File.read('test/fixtures/empty-metadata.json'))
@@ -1,97 +0,0 @@
1
- require 'helper'
2
-
3
- class TestDjatokaCommon < Test::Unit::TestCase
4
-
5
- context 'A Djatoka Resolver' do
6
- with_a_resolver do
7
- setup do
8
- @region = Djatoka::Region.new(@resolver, @identifier)
9
- end
10
- should 'create a query for a 75x75 version of the image' do
11
- assert_equal '0,874,106,106', @region.smallbox.query.region
12
- assert_equal '75', @region.smallbox.query.scale
13
- end
14
-
15
- should 'return a String for a smallbox URL' do
16
- assert @region.smallbox_url.is_a? String
17
- assert @region.smallbox_url.include? 'http://african.lanl.gov'
18
- assert @region.smallbox_url.include? 'svc.region=0%2C874%2C106%2C106'
19
- end
20
-
21
- should 'return a uri for a small square version of the image' do
22
- assert_equal '0,874,106,106', @region.smallbox.uri.query_values['svc.region']
23
- end
24
-
25
- should 'create a query for a square version of the image' do
26
- assert_equal '0,874,3372,3372', @region.square.query.region
27
- assert_equal nil, @region.square.query.scale
28
- end
29
- should 'create a query for a left justified version of the image' do
30
- assert_equal '0,0,3372,3372', @region.top_left_square.query.region
31
- end
32
- should 'create a query for a right justified version of the image' do
33
- assert_equal '0,1748,3372,3372', @region.bottom_right_square.query.region
34
- end
35
- should 'return a uri for a square version of the image' do
36
- assert_equal '0,874,3372,3372', @region.square_uri.query_values['svc.region']
37
- assert_equal nil, @region.square_uri.query_values['svc.scale']
38
- end
39
- should 'return a url for a square version of the image' do
40
- assert @region.square_url.is_a? String
41
- assert @region.square_url.include? 'http://african.lanl.gov'
42
- assert @region.square_url.include? 'svc.region=0%2C874%2C3372%2C3372'
43
- end
44
- should 'create a query for a square version of the image at a good level' do
45
- @region.scale('555')
46
- assert_equal '0,874,843,843', @region.square.query.region
47
- assert_equal '555', @region.square.query.scale
48
- assert_equal '4', @region.square.query.level
49
- end
50
-
51
- should 'pick the best level' do
52
- metadata = Djatoka::Metadata.new(@resolver, @identifier).perform
53
- @region.scale('200')
54
- best_level = @region.pick_best_level(metadata)
55
- assert_equal 2, best_level
56
- end
57
-
58
- context 'an image which is higher than it is wider' do
59
- setup do
60
- @region = Djatoka::Region.new(@resolver, 'info:lanl-repo/ds/b820f537-26a1-4af8-b86a-e7a4cac6187a')
61
- end
62
- should 'crop appropriately into a centered square' do
63
- assert_equal '513,0,4093,4093', @region.square.query.region
64
- end
65
- should 'crop appropriately into a top justified square' do
66
- assert_equal '0,0,4093,4093', @region.top_left_square.query.region
67
- end
68
- should 'crop appropriately into bottom justified square' do
69
- assert_equal '1027,0,4093,4093', @region.bottom_right_square.query.region
70
- end
71
- end
72
-
73
- context 'an image where the dwt_levels do not match the djatoka levels' do
74
- setup do
75
- @region2 = Djatoka::Region.new(@resolver, 'ua023_015-006-bx0003-014-075')
76
- end
77
- should 'be able to scale properly' do
78
- @region2.scale('300').square
79
- assert @region2.url
80
- end
81
- end
82
-
83
- context 'an request for a non-existent image' do
84
- setup do
85
- @no_region = Djatoka::Region.new(@resolver, 'asdf')
86
- end
87
- should 'not raise when no metadata and trying to create a square at scale' do
88
- @no_region.scale(300).square
89
- assert @no_region.url
90
- end
91
- end
92
-
93
- end
94
-
95
- end
96
- end
97
-
@@ -1,29 +0,0 @@
1
- require 'helper'
2
-
3
- class TestDjatoka < Test::Unit::TestCase
4
- should 'allow Djatoka.use_curb to be set' do
5
- Djatoka.use_curb=true
6
- assert Djatoka.use_curb?
7
- set_testing_curb
8
- end
9
-
10
- with_a_resolver do
11
- should 'be able to set Djatoka.resolver to a Djatoka::Resolver' do
12
- Djatoka.resolver = @resolver
13
- assert Djatoka.resolver.is_a? Djatoka::Resolver
14
- end
15
-
16
- should 'be able to set Djatoka.resolver to a URL and get a Djatoka::Resolver' do
17
- Djatoka.resolver = 'http://african.lanl.gov/adore-djatoka/resolver'
18
- assert Djatoka.resolver.is_a? Djatoka::Resolver
19
- assert_equal 'http://african.lanl.gov/adore-djatoka/resolver', Djatoka.resolver.url
20
- end
21
-
22
- should_eventually 'not be able to set a Djatoka.resolver to a bad string' do
23
- Djatoka.resolver = 'asdf'
24
- assert Djatoka.resolver.nil?
25
- end
26
- end
27
-
28
- end
29
-
@@ -1,103 +0,0 @@
1
- require 'helper'
2
-
3
- class TestDjatokaMetadata < Test::Unit::TestCase
4
- with_a_resolver do
5
- context 'a metadata object' do
6
- setup do
7
- @metadata_obj = @resolver.metadata(@identifier)
8
- @metadata = @metadata_obj.perform
9
- end
10
-
11
- should 'create a metadata object' do
12
- assert @metadata.is_a? Djatoka::Metadata
13
- end
14
-
15
- should "create a metadata URL for an identifier" do
16
- assert @metadata.url.include? 'http://african.lanl.gov/adore-djatoka/resolver?'
17
- assert @metadata.url.include? 'url_ver=Z39.88-2004'
18
- assert @metadata.url.include? '&svc_id=info%3Alanl-repo%2Fsvc%2FgetMetadata'
19
- assert @metadata.url.include? '&rft_id=info%3Alanl-repo%2Fds%2F5aa182c2-c092-4596-af6e-e95d2e263de3'
20
- end
21
-
22
- should 'create a metadata uri for an identifier' do
23
- uri = @metadata.uri
24
- assert_equal 'african.lanl.gov', uri.host
25
- end
26
-
27
- should "return imagefile metadata for an identifier" do
28
- assert_equal '/lanl/data/loc/cc5fc4f7-e50a-455f-b3ce-a6a8b54824e6/WEJLNXSBWO7LPLC7Z6DITFX7A45XR3GS.jp2',
29
- @metadata.imagefile
30
- end
31
-
32
- should 'return an identifier for a good request' do
33
- assert_equal @identifier,
34
- @metadata.identifier
35
- end
36
-
37
- should 'return a height for a good request' do
38
- assert_equal '3372', @metadata.height
39
- end
40
-
41
- should 'return a width for a good request' do
42
- assert_equal '5120', @metadata.width
43
- end
44
-
45
- should 'return an OK status for a good request' do
46
- metadata = @metadata.status
47
- end
48
-
49
- should 'return a nil for a bad request' do
50
- metadata = @resolver.metadata('asdf')
51
- assert_equal nil, metadata.status
52
- end
53
- end #context metadata response
54
-
55
- context 'using net::http' do
56
- should 'return a height for a good request' do
57
- Djatoka.use_curb=false
58
- assert_equal '3372', Djatoka::Metadata.new(@resolver, @identifier).perform.height
59
- set_testing_curb
60
- end
61
- end
62
-
63
- context 'determining all the levels for a particular metadata response' do
64
- setup do
65
- @metadata_obj = @resolver.metadata(@identifier)
66
- @metadata = @metadata_obj.perform
67
- @levels = @metadata.all_levels
68
- end
69
- should 'create the number of metadata levels as djatoka provides' do
70
- assert_equal 7, @levels.length
71
- end
72
- should 'return height and width for all levels' do
73
- expected_levels = { "0"=>{"height"=>53, "width"=>80},
74
- "1"=>{"height"=>106, "width"=>160},
75
- "2"=>{"height"=>211, "width"=>320},
76
- "3"=>{"height"=>422, "width"=>640},
77
- "4"=>{"height"=>843, "width"=>1280},
78
- "5"=>{"height"=>1686, "width"=>2560},
79
- "6"=>{"height"=>3372, "width"=>5120}}
80
- assert_equal expected_levels, @levels
81
- end
82
- should 'know which is the max level' do
83
- assert_equal "6", @metadata.max_level
84
- end
85
-
86
- should 'return appropriate height and width for all levels when levels and dwt_levels do not match' do
87
- levels = {"0"=>{"height"=>58, "width"=>37},
88
- "1"=>{"height"=>115, "width"=>74},
89
- "2"=>{"height"=>229, "width"=>148},
90
- "3"=>{"height"=>458, "width"=>296},
91
- "4"=>{"height"=>915, "width"=>592}}
92
- metadata = @resolver.metadata('ua023_015-006-bx0003-014-075').perform
93
- returned_levels = metadata.all_levels
94
- assert_equal levels, returned_levels
95
-
96
- end
97
-
98
- end # levels
99
-
100
- end #with_a_resolver
101
-
102
- end
103
-
@@ -1,151 +0,0 @@
1
- require 'helper'
2
-
3
- class TestDjatokaMetadata < Test::Unit::TestCase
4
- with_a_resolver do
5
- context 'creates image URLs for a region' do
6
- setup do
7
- @region = Djatoka::Region.new(@resolver, @identifier)
8
- end
9
-
10
- should 'create good region parameters' do
11
- good_params = {'rft_id'=>"info:lanl-repo/ds/5aa182c2-c092-4596-af6e-e95d2e263de3",
12
- "svc_val_fmt"=>"info:ofi/fmt:kev:mtx:jpeg2000",
13
- "svc_id"=>"info:lanl-repo/svc/getRegion",
14
- 'url_ver'=>"Z39.88-2004"}
15
- assert_equal good_params, @region.region_params
16
- end
17
-
18
- context 'create a new region if given a string as a resolver' do
19
- should 'create a resolver object' do
20
- region = Djatoka::Region.new('http://african.lanl.gov/adore-djatoka/resolver', @identifier)
21
- assert region.resolver.is_a? Djatoka::Resolver
22
- assert_equal 'http://african.lanl.gov/adore-djatoka/resolver', region.resolver.to_s
23
- assert_equal 'african.lanl.gov', region.resolver.host
24
- end
25
- end
26
-
27
- context 'create a default region uri' do
28
- setup do
29
- @region_uri = @region.uri
30
- @query_values = @region.uri.query_values
31
- end
32
- should 'create a default region uri' do
33
- assert_equal @identifier, @query_values['rft_id']
34
- assert_equal nil, @query_values['svc.scale']
35
- end
36
- should 'output a region url' do
37
- assert @region.url.is_a? String
38
- assert @region.url.include? 'http://african.lanl.gov'
39
- end
40
- end
41
-
42
- context 'add query parameters' do
43
- should 'accept a scale as a String' do
44
- scale_region = @region.scale('96')
45
- assert_equal '96', scale_region.query.scale
46
- end
47
- should 'accept a scale as a single Integer' do
48
- assert_equal '96', @region.scale(96).query.scale
49
- end
50
- should 'accept a scale as a Float' do
51
- assert_equal '0.5', @region.scale(0.5).query.scale
52
- end
53
- should 'accept a scale as an Array of 2' do
54
- assert_equal '1024,768', @region.scale([1024,768]).query.scale
55
- assert_equal '10,60', @region.scale(['10', '60']).query.scale
56
- end
57
-
58
- should 'accept a level as a String' do
59
- level_region = @region.level('2')
60
- assert_equal '2', level_region.query.level
61
- end
62
- should 'accept a level as an Integer' do
63
- assert_equal '3', @region.level(3).query.level
64
- end
65
-
66
- should 'accept a rotate as a String' do
67
- assert_equal '180', @region.rotate('180').query.rotate
68
- end
69
- should 'accept a rotate as an Integer' do
70
- assert_equal '180', @region.rotate(180).query.rotate
71
- end
72
-
73
- should 'accept a region as a String' do
74
- assert_equal '0,0,256,256', @region.region('0,0,256,256').query.region
75
- end
76
- should 'accept a region as an Array of Strings' do
77
- assert_equal '0,0,256,256', @region.region(['0','0','256','256']).query.region
78
- end
79
- should 'accept a region as an Array of Integers and/or Floats' do
80
- assert_equal '0.1,0.1,5,5', @region.region([0.1, 0.1, 5, 5]).query.region
81
- end
82
-
83
- should 'accept a format as a String' do
84
- assert_equal 'image/png', @region.format('image/png').query.format
85
- end
86
- should 'accept a clayer as a String' do
87
- assert_equal '0', @region.clayer('0').query.clayer
88
- end
89
- end
90
-
91
- context 'add empty or null query parameters' do
92
- should 'have no value in the uri' do
93
- assert_equal nil, @region.level(nil).uri.query_values['svc.level']
94
- end
95
- end
96
-
97
- context 'create a query uri with svc values' do
98
- should 'have a svc.scale paramter' do
99
- assert_equal '96', @region.scale('96').uri.query_values['svc.scale']
100
- end
101
- context 'and method chaining' do
102
- setup do
103
- @region2 = @region.dup.scale('96').level('3')
104
- @region2_query_values = @region2.uri.query_values
105
- end
106
- should 'have svc.scale and svc.level parameters after method chaining' do
107
- assert_equal '96', @region2_query_values['svc.scale']
108
- assert_equal '3', @region2_query_values['svc.level']
109
- end
110
- should 'have default values after method chaining svc values' do
111
- assert_equal 'info:lanl-repo/svc/getRegion', @region2_query_values['svc_id']
112
- end
113
- end
114
- end #context create a query uri with svc values
115
-
116
- context 'create a new region and pass in query parameters' do
117
- should 'accept param keys as symbols' do
118
- params = {:level=> 3, :rotate=>180, :region => '0,0,500,500',
119
- :scale => 75, :format => 'image/png'
120
- }
121
- region = Djatoka::Region.new(@resolver,@identifier,params)
122
- assert_equal '3', region.query.level
123
- assert_equal '180', region.query.rotate
124
- assert_equal '0,0,500,500', region.query.region
125
- assert_equal '75', region.query.scale
126
- assert_equal 'image/png', region.query.format
127
- end
128
- should 'accept param keys as strings' do
129
- params = {'level'=> 3, 'rotate'=> 180, 'region' => '0,0,500,500',
130
- 'scale' => 75, 'format' => 'image/png'
131
- }
132
- region = Djatoka::Region.new(@resolver,@identifier,params)
133
- assert_equal '3', region.query.level
134
- assert_equal '180', region.query.rotate
135
- assert_equal '0,0,500,500', region.query.region
136
- assert_equal '75', region.query.scale
137
- assert_equal 'image/png', region.query.format
138
- end
139
- should 'not choke on params it responds to but are not instance methods' do
140
- region = Djatoka::Region.new(@resolver,@identifier,{:class => 'djatoka_image'})
141
- assert region.is_a? Djatoka::Region
142
- assert_equal nil, region.uri.query_values['svc.class']
143
- end
144
- end
145
-
146
- end #context
147
-
148
- end #with_a_resolver
149
-
150
- end
151
-
@@ -1,88 +0,0 @@
1
- require 'helper'
2
-
3
- class TestDjatokaResolver < Test::Unit::TestCase
4
- with_a_resolver do
5
- context 'A Djatoka Resolver' do
6
-
7
- should 'hold a good host from a base_url' do
8
- assert_equal 'african.lanl.gov', @resolver.host
9
- end
10
-
11
- should 'hold a good path from a base_url' do
12
- assert_equal '/adore-djatoka/resolver', @resolver.path
13
- end
14
-
15
- should 'create a ping url' do
16
- assert_equal 'http://african.lanl.gov/adore-djatoka/resolver?url_ver=Z39.88-2004&svc_id=info:lanl-repo/svc/ping&rft_id=info%3Alanl-repo%2Fds%2F5aa182c2-c092-4596-af6e-e95d2e263de3',
17
- @resolver.ping_url(@identifier)
18
- end
19
-
20
- context 'a ping request' do
21
- setup do
22
- @ping_response = @resolver.ping(@identifier)
23
- end
24
-
25
- should 'return an OK status for a good request' do
26
- assert_equal 'OK', @ping_response['status']
27
- end
28
-
29
- should 'return the identifier for a good request' do
30
- assert_equal @identifier, @ping_response['identifier']
31
- end
32
-
33
- should 'return a nil for a bad request' do
34
- ping_response = @resolver.ping('asdf')
35
- assert_equal nil, ping_response
36
- end
37
- end
38
-
39
- context 'a ping request using net::http' do
40
- setup do
41
- Djatoka.use_curb=false
42
- end
43
- should 'return an OK status for a good request' do
44
- assert_equal 'OK', @resolver.ping(@identifier).status
45
- Djatoka.use_curb=true
46
- end
47
- should 'return a nil for a bad request' do
48
- ping_response = @resolver.ping('asdf')
49
- assert_equal nil, ping_response
50
- Djatoka.use_curb=true
51
- end
52
- end
53
-
54
- should 'create a region from a resolver' do
55
- assert @resolver.region(@identifier).is_a? Djatoka::Region
56
- end
57
- should 'create a region uri from a resolver' do
58
- assert @resolver.region_uri(@identifier).is_a? Addressable::URI
59
- end
60
-
61
- end #context a Djatoka::Resolver
62
-
63
- context 'a resolver with a port number' do
64
- setup do
65
- @resolver_port = Djatoka::Resolver.new('http://example.com:8080/adore-djatoka/resolver')
66
- end
67
- should 'hold good uri data' do
68
- assert_equal 'example.com', @resolver_port.host
69
- assert_equal 8080, @resolver_port.port
70
- assert_equal '/adore-djatoka/resolver', @resolver_port.path
71
- end
72
- should 'create a good metadata uri' do
73
- metadata_url = Djatoka::Metadata.new(@resolver_port, 'asdf').uri
74
- assert_equal 8080, metadata_url.port
75
- end
76
- should 'create a metadata url' do
77
- metadata_url = @resolver_port.metadata_url(@identifier)
78
- assert metadata_url.is_a? String
79
- assert metadata_url.include?('getMetadata')
80
- end
81
- should 'create a good url' do
82
- assert_equal 'http://example.com:8080/adore-djatoka/resolver', @resolver_port.url
83
- end
84
- end #context: resolver with a port number
85
-
86
- end #with_a_resolver
87
- end
88
-
@@ -1,15 +0,0 @@
1
- require 'helper'
2
-
3
- class TestDjatokaViewHelpers < Test::Unit::TestCase
4
- with_a_resolver do
5
- context 'Rails view helpers' do
6
- should 'be true' do
7
- assert true
8
- end
9
- should_eventually 'Test the Rails view helpers' do
10
- assert_equal '', djatoka_image_tag(@identifier)
11
- end
12
- end
13
- end
14
- end
15
-