opener-tree-tagger 3.2.3 → 3.2.4

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.
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- NDZlNWM0ZDJkNmY1NzI0YjBmMzJkZjViNTIwODFiY2I0Njc4ZjdlNQ==
5
- data.tar.gz: !binary |-
6
- Zjc2MDA0OGNmYzZkMzQ1NDZiMTJhNGQzM2M0N2QyMjAzZmFhY2ZiMg==
2
+ SHA1:
3
+ metadata.gz: f02a0878183c9f6df7ed50944257698ff369a130
4
+ data.tar.gz: 101a607039771002fdcf962b7e11ef8bcc863387
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- Mzg1ODg3MDU3MDhkMGI4M2U5ZjIxMzM2NTAxODIwOWYyOWU0MjM5NGYzZjY2
10
- MjgyNDNlZDBiOTg5MTdjODNlYTBhNjYyZDUyYTYzZmVmOWQ0OTNiNDA5Y2Y3
11
- OGNkZWJkMWY5YTg1ZTJhY2U3NzdjMGE5ZGY0ZDcyNTA2YWFlODU=
12
- data.tar.gz: !binary |-
13
- YWVlOGU3YzdmOGJjODQzMjdiNGVkZWZlMzA4YTE3NzE0MTI4YTk2MGU0NTFh
14
- OWE4MDk5ZmU4NTg5MGFjYTZhYTE4NzVkMDQ4NDM0MmI4YTJjZTI4YmQ4NzFj
15
- YmM4ODY0MDEwYjVmMzc3Y2Y1MDJlNTFmZmMzNzRlMDQ4M2ZhMDU=
6
+ metadata.gz: 2b6c0d06f37d18d94bcf74cf9b61f671b995e2296bdbb6ae2c832f491b7169619186c6d1f591c1470dc90c1a998106124ef3afd5ca278c1d346313aaaa999fab
7
+ data.tar.gz: 80e5eb90d1012ac73aa0fe00a19471e632d0cf72d5e16191ced19ca833182cdd139810f0a3c2294229d16a085202745709058193676366a88332f85a3340c985
data/README.md CHANGED
@@ -101,7 +101,7 @@ The component is a fat wrapper around the actual language technology core. You c
101
101
  Where to go from here
102
102
  ---------------------
103
103
 
104
- * [Check the project websitere](http://opener-project.github.io)
104
+ * [Check the project website](http://opener-project.github.io)
105
105
  * [Checkout the webservice](http://opener.olery.com/tree-tagger)
106
106
 
107
107
  Report problem/Get help
data/ext/hack/Rakefile CHANGED
@@ -1,17 +1,8 @@
1
- require 'rake'
2
- require_relative 'support'
1
+ import File.expand_path('../../../task/requirements.rake', __FILE__)
2
+ import File.expand_path('../../../task/python.rake', __FILE__)
3
3
 
4
- desc 'Verifies the requirements'
5
- task :requirements do
6
- verify_requirements
7
- end
8
-
9
- task :compile => :requirements do
10
- install_tree_tagger
11
- end
12
-
13
- task :default => [:compile, :requirements] do
14
- path = File.join(PYTHON_SITE_PACKAGES, 'pre_install')
15
-
16
- pip_install(PRE_INSTALL_REQUIREMENTS, path)
4
+ task :default => :requirements do
5
+ Dir.chdir(File.expand_path('../../../', __FILE__)) do
6
+ Rake::Task['core/site-packages/pre_install'].invoke
7
+ end
17
8
  end
@@ -1,8 +1,10 @@
1
1
  require 'open3'
2
2
  require 'optparse'
3
+ require 'nokogiri'
3
4
 
4
5
  require_relative 'tree_tagger/version'
5
6
  require_relative 'tree_tagger/cli'
7
+ require_relative 'tree_tagger/error_layer'
6
8
 
7
9
  module Opener
8
10
  class TreeTagger
@@ -29,15 +31,13 @@ module Opener
29
31
  end
30
32
 
31
33
  def run(input)
32
- stdout, stderr, process = capture(input)
33
-
34
- if process.success?
35
- STDERR.puts(stderr) unless stderr.empty?
36
- else
37
- abort stderr
38
- end
39
-
40
- return stdout, stderr, process
34
+ begin
35
+ stdout, stderr, process = capture(input)
36
+ raise stderr unless process.success?
37
+ return stdout
38
+ rescue Exception => error
39
+ return ErrorLayer.new(input, error.message, self.class).add
40
+ end
41
41
  end
42
42
 
43
43
  def capture(input)
@@ -45,17 +45,11 @@ module Opener
45
45
  end
46
46
 
47
47
  def command
48
- "#{adjust_python_path} #{prepend_tree_tagger_path} python -E -OO #{kernel} #{args.join(' ')}"
48
+ return "#{adjust_python_path} python -E -OO #{kernel} #{args.join(' ')}"
49
49
  end
50
50
 
51
51
  protected
52
52
 
53
- def prepend_tree_tagger_path
54
- return if ENV['TREE_TAGGER_PATH']
55
- path = File.expand_path('../../../core/vendor/build', __FILE__)
56
- return "TREE_TAGGER_PATH=#{path}"
57
- end
58
-
59
53
  ##
60
54
  # @return [String]
61
55
  #
@@ -35,17 +35,7 @@ Examples:
35
35
 
36
36
  tagger = TreeTagger.new(options)
37
37
 
38
- stdout, stderr, process = tagger.run(input)
39
-
40
- if process.success?
41
- puts stdout
42
-
43
- if options[:logging] and !stderr.empty?
44
- STDERR.puts(stderr)
45
- end
46
- else
47
- abort stderr
48
- end
38
+ puts tagger.run(input)
49
39
  end
50
40
 
51
41
  private
@@ -0,0 +1,89 @@
1
+ module Opener
2
+ class TreeTagger
3
+ ##
4
+ # Add Error Layer to KAF file instead of throwing an error.
5
+ #
6
+ class ErrorLayer
7
+ attr_accessor :input, :document, :error, :klass
8
+
9
+ def initialize(input, error, klass)
10
+ @input = input.to_s
11
+ # Make sure there is always a document, even if it is empty.
12
+ @document = Nokogiri::XML(input) rescue Nokogiri::XML(nil)
13
+ @error = error
14
+ @klass = klass
15
+ end
16
+
17
+ def add
18
+ if is_xml?
19
+ unless has_errors_layer?
20
+ add_errors_layer
21
+ end
22
+ else
23
+ add_root
24
+ add_text
25
+ add_errors_layer
26
+ end
27
+ add_error
28
+
29
+ xml = !!document.encoding ? document.to_xml : document.to_xml(:encoding => "UTF-8")
30
+
31
+ return xml
32
+ end
33
+
34
+ ##
35
+ # Check if the document is a valid XML file.
36
+ #
37
+ def is_xml?
38
+ !!document.root
39
+ end
40
+
41
+ ##
42
+ # Add root element to the XML file.
43
+ #
44
+ def add_root
45
+ root = Nokogiri::XML::Node.new "KAF", document
46
+ document.add_child(root)
47
+ end
48
+
49
+ ##
50
+ # Check if the document already has an errors layer.
51
+ #
52
+ def has_errors_layer?
53
+ !!document.at('errors')
54
+ end
55
+
56
+ ##
57
+ # Add errors element to the XML file.
58
+ #
59
+ def add_errors_layer
60
+ node = Nokogiri::XML::Node.new "errors", document
61
+ document.root.add_child(node)
62
+ end
63
+
64
+ ##
65
+ # Add the text file incase it is not a valid XML document. More
66
+ # info for debugging.
67
+ #
68
+ def add_text
69
+ node = Nokogiri::XML::Node.new "raw", document
70
+ node.inner_html = input
71
+ document.root.add_child(node)
72
+
73
+ end
74
+
75
+ ##
76
+ # Add the actual error to the errors layer.
77
+ #
78
+ def add_error
79
+ node = document.at('errors')
80
+ error_node = Nokogiri::XML::Node.new "error", node
81
+ error_node['class'] = klass.to_s
82
+ error_node['version'] = klass::VERSION
83
+ error_node.inner_html = error
84
+ node.add_child(error_node)
85
+ end
86
+
87
+ end # ErrorLayer
88
+ end # TreeTagger
89
+ end # Opener
@@ -1,5 +1,5 @@
1
1
  module Opener
2
2
  class TreeTagger
3
- VERSION = "3.2.3"
3
+ VERSION = "3.2.4"
4
4
  end
5
5
  end
@@ -18,19 +18,21 @@ Gem::Specification.new do |gem|
18
18
  'config.ru',
19
19
  '*.gemspec',
20
20
  '*_requirements.txt',
21
- 'README.md'
21
+ 'README.md',
22
+ 'task/*'
22
23
  ]).select { |file| File.file?(file) }
23
24
 
24
25
  gem.executables = Dir.glob('bin/*').map { |file| File.basename(file) }
25
26
 
26
27
  gem.add_dependency 'opener-daemons'
27
- gem.add_dependency 'opener-build-tools', ['>= 0.2.7']
28
28
  gem.add_dependency 'rake'
29
29
  gem.add_dependency 'sinatra'
30
30
  gem.add_dependency 'httpclient'
31
31
  gem.add_dependency 'puma'
32
32
  gem.add_dependency 'opener-webservice'
33
+ gem.add_dependency 'nokogiri'
34
+ gem.add_dependency 'cliver'
33
35
 
34
- gem.add_development_dependency 'rspec'
36
+ gem.add_development_dependency 'rspec', '~> 3.0'
35
37
  gem.add_development_dependency 'cucumber'
36
38
  end
data/task/compile.rake ADDED
@@ -0,0 +1,2 @@
1
+ desc 'Verifies requirements and compiles the core'
2
+ task :compile => ['requirements', 'python:compile']
data/task/python.rake ADDED
@@ -0,0 +1,11 @@
1
+ # NOTE: pre_build/pre_install directories are created by pip.
2
+
3
+ directory 'core/site-packages/pre_install' do |task|
4
+ sh "pip install --requirement=pre_install_requirements.txt " \
5
+ "--target=#{task.name} --ignore-installed"
6
+ end
7
+
8
+ namespace :python do
9
+ desc 'Installs Python packages in a local directory'
10
+ task :compile => ['core/site-packages/pre_install']
11
+ end
@@ -0,0 +1,7 @@
1
+ desc 'Verifies the requirements'
2
+ task :requirements do
3
+ require 'cliver'
4
+
5
+ Cliver.detect!('python', '~> 2.6')
6
+ Cliver.detect!('pip', '~> 1.3')
7
+ end
data/task/test.rake ADDED
@@ -0,0 +1,4 @@
1
+ desc 'Runs the tests'
2
+ task :test => :compile do
3
+ sh('cucumber features')
4
+ end
metadata CHANGED
@@ -1,143 +1,157 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: opener-tree-tagger
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.2.3
4
+ version: 3.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - rubenIzquierdo
8
8
  - sparkboxx
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-05-26 00:00:00.000000000 Z
12
+ date: 2014-06-12 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: opener-daemons
16
+ version_requirements: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - '>='
19
+ - !ruby/object:Gem::Version
20
+ version: '0'
16
21
  requirement: !ruby/object:Gem::Requirement
17
22
  requirements:
18
- - - ! '>='
23
+ - - '>='
19
24
  - !ruby/object:Gem::Version
20
25
  version: '0'
21
- type: :runtime
22
26
  prerelease: false
27
+ type: :runtime
28
+ - !ruby/object:Gem::Dependency
29
+ name: rake
23
30
  version_requirements: !ruby/object:Gem::Requirement
24
31
  requirements:
25
- - - ! '>='
32
+ - - '>='
26
33
  - !ruby/object:Gem::Version
27
34
  version: '0'
28
- - !ruby/object:Gem::Dependency
29
- name: opener-build-tools
30
35
  requirement: !ruby/object:Gem::Requirement
31
36
  requirements:
32
- - - ! '>='
37
+ - - '>='
33
38
  - !ruby/object:Gem::Version
34
- version: 0.2.7
35
- type: :runtime
39
+ version: '0'
36
40
  prerelease: false
41
+ type: :runtime
42
+ - !ruby/object:Gem::Dependency
43
+ name: sinatra
37
44
  version_requirements: !ruby/object:Gem::Requirement
38
45
  requirements:
39
- - - ! '>='
46
+ - - '>='
40
47
  - !ruby/object:Gem::Version
41
- version: 0.2.7
42
- - !ruby/object:Gem::Dependency
43
- name: rake
48
+ version: '0'
44
49
  requirement: !ruby/object:Gem::Requirement
45
50
  requirements:
46
- - - ! '>='
51
+ - - '>='
47
52
  - !ruby/object:Gem::Version
48
53
  version: '0'
49
- type: :runtime
50
54
  prerelease: false
55
+ type: :runtime
56
+ - !ruby/object:Gem::Dependency
57
+ name: httpclient
51
58
  version_requirements: !ruby/object:Gem::Requirement
52
59
  requirements:
53
- - - ! '>='
60
+ - - '>='
54
61
  - !ruby/object:Gem::Version
55
62
  version: '0'
56
- - !ruby/object:Gem::Dependency
57
- name: sinatra
58
63
  requirement: !ruby/object:Gem::Requirement
59
64
  requirements:
60
- - - ! '>='
65
+ - - '>='
61
66
  - !ruby/object:Gem::Version
62
67
  version: '0'
63
- type: :runtime
64
68
  prerelease: false
69
+ type: :runtime
70
+ - !ruby/object:Gem::Dependency
71
+ name: puma
65
72
  version_requirements: !ruby/object:Gem::Requirement
66
73
  requirements:
67
- - - ! '>='
74
+ - - '>='
68
75
  - !ruby/object:Gem::Version
69
76
  version: '0'
70
- - !ruby/object:Gem::Dependency
71
- name: httpclient
72
77
  requirement: !ruby/object:Gem::Requirement
73
78
  requirements:
74
- - - ! '>='
79
+ - - '>='
75
80
  - !ruby/object:Gem::Version
76
81
  version: '0'
77
- type: :runtime
78
82
  prerelease: false
83
+ type: :runtime
84
+ - !ruby/object:Gem::Dependency
85
+ name: opener-webservice
79
86
  version_requirements: !ruby/object:Gem::Requirement
80
87
  requirements:
81
- - - ! '>='
88
+ - - '>='
82
89
  - !ruby/object:Gem::Version
83
90
  version: '0'
84
- - !ruby/object:Gem::Dependency
85
- name: puma
86
91
  requirement: !ruby/object:Gem::Requirement
87
92
  requirements:
88
- - - ! '>='
93
+ - - '>='
89
94
  - !ruby/object:Gem::Version
90
95
  version: '0'
91
- type: :runtime
92
96
  prerelease: false
97
+ type: :runtime
98
+ - !ruby/object:Gem::Dependency
99
+ name: nokogiri
93
100
  version_requirements: !ruby/object:Gem::Requirement
94
101
  requirements:
95
- - - ! '>='
102
+ - - '>='
96
103
  - !ruby/object:Gem::Version
97
104
  version: '0'
98
- - !ruby/object:Gem::Dependency
99
- name: opener-webservice
100
105
  requirement: !ruby/object:Gem::Requirement
101
106
  requirements:
102
- - - ! '>='
107
+ - - '>='
103
108
  - !ruby/object:Gem::Version
104
109
  version: '0'
105
- type: :runtime
106
110
  prerelease: false
111
+ type: :runtime
112
+ - !ruby/object:Gem::Dependency
113
+ name: cliver
107
114
  version_requirements: !ruby/object:Gem::Requirement
108
115
  requirements:
109
- - - ! '>='
116
+ - - '>='
110
117
  - !ruby/object:Gem::Version
111
118
  version: '0'
112
- - !ruby/object:Gem::Dependency
113
- name: rspec
114
119
  requirement: !ruby/object:Gem::Requirement
115
120
  requirements:
116
- - - ! '>='
121
+ - - '>='
117
122
  - !ruby/object:Gem::Version
118
123
  version: '0'
119
- type: :development
120
124
  prerelease: false
125
+ type: :runtime
126
+ - !ruby/object:Gem::Dependency
127
+ name: rspec
121
128
  version_requirements: !ruby/object:Gem::Requirement
122
129
  requirements:
123
- - - ! '>='
130
+ - - ~>
124
131
  - !ruby/object:Gem::Version
125
- version: '0'
126
- - !ruby/object:Gem::Dependency
127
- name: cucumber
132
+ version: '3.0'
128
133
  requirement: !ruby/object:Gem::Requirement
129
134
  requirements:
130
- - - ! '>='
135
+ - - ~>
131
136
  - !ruby/object:Gem::Version
132
- version: '0'
133
- type: :development
137
+ version: '3.0'
134
138
  prerelease: false
139
+ type: :development
140
+ - !ruby/object:Gem::Dependency
141
+ name: cucumber
135
142
  version_requirements: !ruby/object:Gem::Requirement
136
143
  requirements:
137
- - - ! '>='
144
+ - - '>='
138
145
  - !ruby/object:Gem::Version
139
146
  version: '0'
140
- description: ! 'Ruby wrapped KAF based Tree Tagger for 6 languages '
147
+ requirement: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - '>='
150
+ - !ruby/object:Gem::Version
151
+ version: '0'
152
+ prerelease: false
153
+ type: :development
154
+ description: 'Ruby wrapped KAF based Tree Tagger for 6 languages '
141
155
  email:
142
156
  - ruben.izquierdobevia@vu.nl
143
157
  - wilco@olery.com
@@ -149,6 +163,11 @@ extensions:
149
163
  - ext/hack/Rakefile
150
164
  extra_rdoc_files: []
151
165
  files:
166
+ - README.md
167
+ - bin/tree-tagger
168
+ - bin/tree-tagger-daemon
169
+ - bin/tree-tagger-server
170
+ - config.ru
152
171
  - core/dutch.map.treetagger.kaf.csv
153
172
  - core/english.map.treetagger.kaf.csv
154
173
  - core/french.map.treetagger.kaf.csv
@@ -159,43 +178,41 @@ files:
159
178
  - core/tt_from_kaf_to_kaf.py
160
179
  - exec/tree-tagger.rb
161
180
  - ext/hack/Rakefile
162
- - ext/hack/support.rb
181
+ - lib/opener/tree_tagger.rb
163
182
  - lib/opener/tree_tagger/cli.rb
183
+ - lib/opener/tree_tagger/error_layer.rb
164
184
  - lib/opener/tree_tagger/public/markdown.css
165
185
  - lib/opener/tree_tagger/server.rb
166
186
  - lib/opener/tree_tagger/version.rb
167
187
  - lib/opener/tree_tagger/views/index.erb
168
188
  - lib/opener/tree_tagger/views/result.erb
169
- - lib/opener/tree_tagger.rb
170
- - config.ru
171
189
  - opener-tree-tagger.gemspec
172
190
  - pre_install_requirements.txt
173
- - README.md
174
- - bin/tree-tagger
175
- - bin/tree-tagger-daemon
176
- - bin/tree-tagger-server
191
+ - task/compile.rake
192
+ - task/python.rake
193
+ - task/requirements.rake
194
+ - task/test.rake
177
195
  homepage: http://opener-project.github.com/
178
196
  licenses: []
179
197
  metadata: {}
180
- post_install_message:
198
+ post_install_message:
181
199
  rdoc_options: []
182
200
  require_paths:
183
201
  - lib
184
202
  required_ruby_version: !ruby/object:Gem::Requirement
185
203
  requirements:
186
- - - ! '>='
204
+ - - '>='
187
205
  - !ruby/object:Gem::Version
188
206
  version: '0'
189
207
  required_rubygems_version: !ruby/object:Gem::Requirement
190
208
  requirements:
191
- - - ! '>='
209
+ - - '>='
192
210
  - !ruby/object:Gem::Version
193
211
  version: '0'
194
212
  requirements: []
195
- rubyforge_project:
196
- rubygems_version: 2.1.11
197
- signing_key:
213
+ rubyforge_project:
214
+ rubygems_version: 2.2.2
215
+ signing_key:
198
216
  specification_version: 4
199
217
  summary: Ruby wrapped KAF based Tree Tagger for 6 languages
200
218
  test_files: []
201
- has_rdoc:
data/ext/hack/support.rb DELETED
@@ -1,65 +0,0 @@
1
- require 'opener/build-tools'
2
-
3
- include Opener::BuildTools::Requirements
4
- include Opener::BuildTools::Python
5
- include Opener::BuildTools::Files
6
-
7
- # Directory where packages will be installed to.
8
- PYTHON_SITE_PACKAGES = File.expand_path(
9
- '../../../core/site-packages',
10
- __FILE__
11
- )
12
-
13
- # Directory containing the temporary files.
14
- TMP_DIRECTORY = File.expand_path('../../../tmp', __FILE__)
15
-
16
- # Path to the pip requirements file used to install requirements before
17
- # packaging the Gem.
18
- PRE_BUILD_REQUIREMENTS = File.expand_path(
19
- '../../../pre_build_requirements.txt',
20
- __FILE__
21
- )
22
-
23
- # Path to the pip requirements file used to install requirements upon Gem
24
- # installation.
25
- PRE_INSTALL_REQUIREMENTS = File.expand_path(
26
- '../../../pre_install_requirements.txt',
27
- __FILE__
28
- )
29
-
30
- # Path to the vendor directory for C code.
31
- VENDOR_DIRECTORY = File.expand_path('../../../core/vendor', __FILE__)
32
-
33
- # Path to the directory to install vendored C code into.
34
- VENDOR_BUILD_DIRECTORY = File.expand_path(
35
- '../../../core/vendor/build',
36
- __FILE__
37
- )
38
-
39
- ##
40
- # Verifies the requirements to install thi Gem.
41
- #
42
- def verify_requirements
43
- require_executable('python')
44
- require_version('python', python_version, '2.6.0')
45
- require_executable('pip')
46
- require_version('pip', pip_version, '1.3.1')
47
- end
48
-
49
- def install_tree_tagger
50
- #return if ENV['TREE_TAGGER_PATH']
51
- build = VENDOR_BUILD_DIRECTORY
52
- mkdir_p(build)
53
- cd build do
54
- sh "curl -o tree-tagger-linux-3.2.tar.gz http://www.cis.uni-muenchen.de/~schmid/tools/TreeTagger/data/tree-tagger-linux-3.2.tar.gz"
55
- sh "curl -o tagger-scripts.tar.gz http://www.cis.uni-muenchen.de/~schmid/tools/TreeTagger/data/tagger-scripts.tar.gz"
56
- sh "curl -o install-tagger.sh http://www.cis.uni-muenchen.de/~schmid/tools/TreeTagger/data/install-tagger.sh"
57
- sh "curl -o dutch-par-linux-3.2-utf8.bin.gz http://www.cis.uni-muenchen.de/~schmid/tools/TreeTagger/data/dutch-par-linux-3.2-utf8.bin.gz"
58
- sh "curl -o french-par-linux-3.2-utf8.bin.gz http://www.cis.uni-muenchen.de/~schmid/tools/TreeTagger/data/french-par-linux-3.2-utf8.bin.gz"
59
- sh "curl -o german-par-linux-3.2-utf8.bin.gz http://www.cis.uni-muenchen.de/~schmid/tools/TreeTagger/data/german-par-linux-3.2-utf8.bin.gz"
60
- sh "curl -o italian-par-linux-3.2-utf8.bin.gz http://www.cis.uni-muenchen.de/~schmid/tools/TreeTagger/data/italian-par-linux-3.2-utf8.bin.gz"
61
- sh "curl -o spanish-par-linux-3.2-utf8.bin.gz http://www.cis.uni-muenchen.de/~schmid/tools/TreeTagger/data/spanish-par-linux-3.2-utf8.bin.gz"
62
- sh "curl -o english-par-linux-3.2.bin.gz http://www.cis.uni-muenchen.de/~schmid/tools/TreeTagger/data/english-par-linux-3.2.bin.gz"
63
- sh "sh install-tagger.sh"
64
- end
65
- end