highrise 2.0.1 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +3 -0
- data/Gemfile.lock +38 -0
- data/MIT-LICENSE +1 -1
- data/README.mkdn +21 -29
- data/Rakefile +6 -31
- data/autotest/discover.rb +1 -3
- data/examples/config_initializers_highrise.rb +1 -9
- data/examples/sample.rb +0 -1
- data/highrise.gemspec +24 -117
- data/lib/highrise.rb +6 -5
- data/lib/highrise/account.rb +0 -1
- data/lib/highrise/base.rb +15 -3
- data/lib/highrise/comment.rb +1 -2
- data/lib/highrise/company.rb +3 -2
- data/lib/highrise/deal.rb +4 -1
- data/lib/highrise/deal_category.rb +3 -0
- data/lib/highrise/group.rb +1 -2
- data/lib/highrise/kase.rb +13 -2
- data/lib/highrise/membership.rb +1 -2
- data/lib/highrise/pagination.rb +8 -1
- data/lib/highrise/party.rb +11 -0
- data/lib/highrise/person.rb +1 -4
- data/lib/highrise/recording.rb +5 -0
- data/lib/highrise/searchable.rb +22 -0
- data/lib/highrise/subject.rb +6 -0
- data/lib/highrise/tag.rb +0 -5
- data/lib/highrise/taggable.rb +4 -1
- data/lib/highrise/task_category.rb +3 -0
- data/lib/highrise/version.rb +3 -0
- data/spec/highrise/account_spec.rb +5 -11
- data/spec/highrise/base_spec.rb +45 -10
- data/spec/highrise/comment_spec.rb +2 -11
- data/spec/highrise/company_spec.rb +10 -72
- data/spec/highrise/deal_category_spec.rb +13 -0
- data/spec/highrise/deal_spec.rb +16 -13
- data/spec/highrise/email_spec.rb +7 -19
- data/spec/highrise/group_spec.rb +2 -11
- data/spec/highrise/kase_spec.rb +10 -18
- data/spec/highrise/membership_spec.rb +2 -11
- data/spec/highrise/note_spec.rb +8 -17
- data/spec/highrise/pagination_behavior.rb +20 -0
- data/spec/highrise/pagination_spec.rb +4 -6
- data/spec/highrise/party_spec.rb +16 -0
- data/spec/highrise/person_spec.rb +23 -80
- data/spec/highrise/recording_spec.rb +13 -0
- data/spec/highrise/searchable_behavior.rb +13 -0
- data/spec/highrise/searchable_spec.rb +8 -0
- data/spec/highrise/subject_spec.rb +20 -35
- data/spec/highrise/tag_spec.rb +8 -13
- data/spec/highrise/taggable_behavior.rb +27 -0
- data/spec/highrise/taggable_spec.rb +9 -0
- data/spec/highrise/task_category_spec.rb +13 -0
- data/spec/highrise/task_spec.rb +6 -18
- data/spec/highrise/user_spec.rb +11 -28
- data/spec/spec_helper.rb +9 -18
- metadata +55 -42
- data/CHANGELOG +0 -131
- data/VERSION.yml +0 -5
- data/install.rb +0 -1
- data/lib/cachable.rb +0 -83
- data/spec/cachable_spec.rb +0 -84
- data/spec/spec.opts +0 -7
- data/uninstall.rb +0 -1
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
highrise (3.0.0.pre04)
|
5
|
+
activeresource (~> 3.0.0)
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: http://rubygems.org/
|
9
|
+
specs:
|
10
|
+
activemodel (3.0.1)
|
11
|
+
activesupport (= 3.0.1)
|
12
|
+
builder (~> 2.1.2)
|
13
|
+
i18n (~> 0.4.1)
|
14
|
+
activeresource (3.0.1)
|
15
|
+
activemodel (= 3.0.1)
|
16
|
+
activesupport (= 3.0.1)
|
17
|
+
activesupport (3.0.1)
|
18
|
+
builder (2.1.2)
|
19
|
+
diff-lcs (1.1.2)
|
20
|
+
i18n (0.4.2)
|
21
|
+
rspec (2.0.1)
|
22
|
+
rspec-core (~> 2.0.1)
|
23
|
+
rspec-expectations (~> 2.0.1)
|
24
|
+
rspec-mocks (~> 2.0.1)
|
25
|
+
rspec-core (2.0.1)
|
26
|
+
rspec-expectations (2.0.1)
|
27
|
+
diff-lcs (>= 1.1.2)
|
28
|
+
rspec-mocks (2.0.1)
|
29
|
+
rspec-core (~> 2.0.1)
|
30
|
+
rspec-expectations (~> 2.0.1)
|
31
|
+
|
32
|
+
PLATFORMS
|
33
|
+
ruby
|
34
|
+
|
35
|
+
DEPENDENCIES
|
36
|
+
activeresource (~> 3.0.0)
|
37
|
+
highrise!
|
38
|
+
rspec
|
data/MIT-LICENSE
CHANGED
data/README.mkdn
CHANGED
@@ -1,10 +1,10 @@
|
|
1
|
-
# Highrise (
|
1
|
+
# Highrise (3.0.0)
|
2
2
|
|
3
3
|
## What is it?
|
4
4
|
|
5
5
|
This gem provides a set of classes to access information on [Highrise][h] via the published [API][api]:
|
6
6
|
|
7
|
-
Account, Comment, Company, Deal, Email, Group, Case, Membership, Note, Person, Subject, Tag, Task, User.
|
7
|
+
Account, Comment, Company, Deal, DealCategory, Email, Group, Case, Membership, Note, Party, Person, Recording, Subject, Tag, Task, TaskCategory and User.
|
8
8
|
|
9
9
|
All these classes are inherited from ActiveResouce::Base. Refer to the [ActiveResouce][ar] documentation for more information.
|
10
10
|
|
@@ -12,24 +12,19 @@ All these classes are inherited from ActiveResouce::Base. Refer to the [ActiveRe
|
|
12
12
|
|
13
13
|
gem install highrise
|
14
14
|
|
15
|
-
### Dependencies (see
|
15
|
+
### Dependencies (see <code>highrise.gemspec</code> or run <code>bundle check</code>)
|
16
16
|
|
17
17
|
### Documentation
|
18
18
|
|
19
|
-
I'm on [rdoc.info][rdoc]
|
19
|
+
I'm on [rdoc.info][rdoc]
|
20
20
|
|
21
21
|
### Configure your key
|
22
22
|
|
23
|
-
require 'rubygems'
|
24
23
|
require 'highrise'
|
25
24
|
|
26
25
|
Highrise::Base.site = 'http://your_site.highrisehq.com'
|
27
26
|
Highrise::Base.user = 'api-auth-token'
|
28
27
|
|
29
|
-
and, if you want [caching][c]:
|
30
|
-
|
31
|
-
Highrise::Base.connection.cache_store= <your normal ActiveSupport::Caching options>
|
32
|
-
|
33
28
|
If you are using this in a Rails application, putting this code in a config/initializers/highrise.rb
|
34
29
|
file is recommended. See config_initializers_highrise.rb in the examples/ directory.
|
35
30
|
|
@@ -49,36 +44,33 @@ This code is free to be used under the terms of the [MIT license][mit].
|
|
49
44
|
|
50
45
|
Comments are welcome. Send your feedback through the [issue tracker on GitHub][i]
|
51
46
|
|
47
|
+
If you have fixes: Submit via pull requests. Do not include version changes to the
|
48
|
+
version file.
|
49
|
+
|
52
50
|
## Authors
|
53
51
|
|
54
|
-
* [Marcos Tapajós][
|
55
|
-
* [Ken Mayer][
|
52
|
+
* [Marcos Tapajós][tapajos]
|
53
|
+
* [Ken Mayer][kmayer]
|
56
54
|
|
57
55
|
## Contributors
|
58
56
|
|
59
|
-
* [Nicolas Bianco][
|
60
|
-
* [Luis Gustavo][
|
61
|
-
* [Thiago Lelis][
|
62
|
-
|
63
|
-
## Special Thanks
|
57
|
+
* [Nicolas Bianco][slainer86]
|
58
|
+
* [Luis Gustavo][luisbebop]
|
59
|
+
* [Thiago Lelis][ThiagoLelis]
|
60
|
+
* [Denis Odorcic][odorcicd]
|
64
61
|
|
65
|
-
|
66
|
-
[How to Cache Anything With ActiveSupport][rh] on the very *day* I started writing the cache code. Thank you, Rein
|
67
|
-
for writing an excellent tutorial and [posting your source][e] on GitHub.
|
62
|
+
## References
|
68
63
|
|
69
64
|
[api]: http://developer.37signals.com/highrise
|
70
65
|
[ar]: http://api.rubyonrails.org/classes/ActiveResource/Base.html
|
71
66
|
[c]: http://api.rubyonrails.org/classes/ActiveSupport/Cache
|
72
|
-
[e]: http://github.com/primedia/endeca/tree/master
|
73
67
|
[h]: http://www.highrisehq.com/
|
74
|
-
[i]:
|
75
|
-
[
|
76
|
-
[lg]:
|
68
|
+
[i]: https://github.com/tapajos/highrise/issues
|
69
|
+
[kmayer]: https://github.com/kmayer
|
70
|
+
[lg]: https://github.com/luisbebop
|
77
71
|
[mit]:http://www.opensource.org/licenses/mit-license.php
|
78
|
-
[
|
79
|
-
[
|
80
|
-
[re]: http://www.railsenvy.com/2009/4/29/rails-envy-podcast-episode-077-04-29-2009
|
81
|
-
[rh]: http://reinh.com/blog/2009/04/27/how-to-cache-anything-with-activesupport.html
|
82
|
-
[tl]: http://github.com/ThiagoLelis
|
72
|
+
[nb]: https://github.com/slainer86
|
73
|
+
[odorcicd]: https://github.com/odorcicd
|
83
74
|
[rdoc]: http://rdoc.info/projects/tapajos/highrise
|
84
|
-
[
|
75
|
+
[tapajos]: http://www.improveit.com.br/en/company/tapajos
|
76
|
+
[tl]: https://github.com/ThiagoLelis
|
data/Rakefile
CHANGED
@@ -1,39 +1,14 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
+
require 'bundler'
|
3
|
+
Bundler::GemHelper.install_tasks
|
2
4
|
|
3
|
-
|
4
|
-
require 'spec/rake/spectask'
|
5
|
-
|
6
|
-
begin
|
7
|
-
require 'jeweler'
|
8
|
-
Jeweler::Tasks.new do |gemspec|
|
9
|
-
gemspec.name = "highrise"
|
10
|
-
gemspec.summary = "Ruby wrapper around Highrise API"
|
11
|
-
gemspec.email = ["marcos@tapajos.me", "kmayer@bitwrangler.com"]
|
12
|
-
gemspec.homepage = "http://github.com/tapajos/highrise"
|
13
|
-
gemspec.description = %{
|
14
|
-
Based on the original API module from DHH, http://developer.37signals.com/highrise/, this
|
15
|
-
gem is a cleaned up, tested version of the same. Contributors have added support for tags
|
16
|
-
which are not supported by the API directly
|
17
|
-
|
18
|
-
Configure by adding the following:
|
19
|
-
|
20
|
-
require 'highrise'
|
21
|
-
Highrise::Base.site = 'http://your_site.highrisehq.com/'
|
22
|
-
Highrise::Base.user = 'your_api_auth_token'
|
23
|
-
}
|
24
|
-
gemspec.authors = ["Marcos Tapajós", "Ken Mayer"]
|
25
|
-
gemspec.add_dependency('activeresource', '>= 2.1')
|
26
|
-
gemspec.add_dependency('activesupport', '>= 2.1')
|
27
|
-
end
|
28
|
-
rescue LoadError
|
29
|
-
puts "Jeweler not available. Install it with: sudo gem install jeweler -s http://gems.github.com"
|
30
|
-
end
|
5
|
+
require 'rspec/core/rake_task'
|
31
6
|
|
32
7
|
desc 'Default: run unit tests.'
|
33
8
|
task :default => :spec
|
34
9
|
|
35
10
|
desc "Run all specs"
|
36
|
-
|
37
|
-
t.
|
38
|
-
t.
|
11
|
+
RSpec::Core::RakeTask.new do |t|
|
12
|
+
t.pattern = 'spec/**/*_spec.rb'
|
13
|
+
t.rspec_opts = ["-c", "-f progress"]
|
39
14
|
end
|
data/autotest/discover.rb
CHANGED
@@ -1,12 +1,4 @@
|
|
1
1
|
if Rails.env != 'test' then
|
2
2
|
Highrise::Base.site = 'https://example.com.i'
|
3
|
-
|
4
|
-
if Highrise::Base.respond_to? :user
|
5
|
-
Highrise::Base.user = 'my_fancy_auth_token'
|
6
|
-
else
|
7
|
-
Highrise::Base.site = 'https://my_fancy_auth_token@example.com.i'
|
8
|
-
end
|
9
|
-
# The cache store can be anything that ActiveSupport can handle
|
10
|
-
Highrise::Base.connection.cache_store = ActiveSupport::Cache.lookup_store :mem_cache_store
|
11
|
-
Highrise::Base.connection.store_options = { :expires_in => 60.seconds }
|
3
|
+
Highrise::Base.user = 'my_fancy_auth_token'
|
12
4
|
end
|
data/examples/sample.rb
CHANGED
data/highrise.gemspec
CHANGED
@@ -1,126 +1,33 @@
|
|
1
|
-
# Generated by jeweler
|
2
|
-
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
1
|
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "highrise/version"
|
5
4
|
|
6
5
|
Gem::Specification.new do |s|
|
7
|
-
s.name
|
8
|
-
s.version
|
6
|
+
s.name = "highrise"
|
7
|
+
s.version = Highrise::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
9
|
|
10
|
-
s.required_rubygems_version =
|
11
|
-
s.
|
12
|
-
s.
|
13
|
-
s.description = %q{
|
14
|
-
Based on the original API module from DHH, http://developer.37signals.com/highrise/, this
|
15
|
-
gem is a cleaned up, tested version of the same. Contributors have added support for tags
|
16
|
-
which are not supported by the API directly
|
10
|
+
s.required_rubygems_version = ">= 1.3.6"
|
11
|
+
s.add_dependency "activeresource", "~>3.0.0"
|
12
|
+
s.add_development_dependency "rspec"
|
17
13
|
|
18
|
-
|
19
|
-
|
20
|
-
require 'highrise'
|
21
|
-
Highrise::Base.site = 'http://your_site.highrisehq.com/'
|
22
|
-
Highrise::Base.user = 'your_api_auth_token'
|
23
|
-
}
|
24
|
-
s.email = ["marcos@tapajos.me", "kmayer@bitwrangler.com"]
|
25
|
-
s.extra_rdoc_files = [
|
26
|
-
"README.mkdn"
|
27
|
-
]
|
28
|
-
s.files = [
|
29
|
-
".gitignore",
|
30
|
-
"CHANGELOG",
|
31
|
-
"MIT-LICENSE",
|
32
|
-
"README.mkdn",
|
33
|
-
"Rakefile",
|
34
|
-
"VERSION.yml",
|
35
|
-
"autotest/discover.rb",
|
36
|
-
"examples/config_initializers_highrise.rb",
|
37
|
-
"examples/extending.rb",
|
38
|
-
"examples/sample.rb",
|
39
|
-
"highrise.gemspec",
|
40
|
-
"install.rb",
|
41
|
-
"lib/cachable.rb",
|
42
|
-
"lib/highrise.rb",
|
43
|
-
"lib/highrise/account.rb",
|
44
|
-
"lib/highrise/base.rb",
|
45
|
-
"lib/highrise/comment.rb",
|
46
|
-
"lib/highrise/company.rb",
|
47
|
-
"lib/highrise/deal.rb",
|
48
|
-
"lib/highrise/email.rb",
|
49
|
-
"lib/highrise/group.rb",
|
50
|
-
"lib/highrise/kase.rb",
|
51
|
-
"lib/highrise/membership.rb",
|
52
|
-
"lib/highrise/note.rb",
|
53
|
-
"lib/highrise/pagination.rb",
|
54
|
-
"lib/highrise/person.rb",
|
55
|
-
"lib/highrise/subject.rb",
|
56
|
-
"lib/highrise/tag.rb",
|
57
|
-
"lib/highrise/taggable.rb",
|
58
|
-
"lib/highrise/task.rb",
|
59
|
-
"lib/highrise/user.rb",
|
60
|
-
"spec/cachable_spec.rb",
|
61
|
-
"spec/highrise/account_spec.rb",
|
62
|
-
"spec/highrise/base_spec.rb",
|
63
|
-
"spec/highrise/comment_spec.rb",
|
64
|
-
"spec/highrise/company_spec.rb",
|
65
|
-
"spec/highrise/deal_spec.rb",
|
66
|
-
"spec/highrise/email_spec.rb",
|
67
|
-
"spec/highrise/group_spec.rb",
|
68
|
-
"spec/highrise/kase_spec.rb",
|
69
|
-
"spec/highrise/membership_spec.rb",
|
70
|
-
"spec/highrise/note_spec.rb",
|
71
|
-
"spec/highrise/pagination_spec.rb",
|
72
|
-
"spec/highrise/person_spec.rb",
|
73
|
-
"spec/highrise/subject_spec.rb",
|
74
|
-
"spec/highrise/tag_spec.rb",
|
75
|
-
"spec/highrise/task_spec.rb",
|
76
|
-
"spec/highrise/user_spec.rb",
|
77
|
-
"spec/spec.opts",
|
78
|
-
"spec/spec_helper.rb",
|
79
|
-
"uninstall.rb"
|
80
|
-
]
|
81
|
-
s.homepage = %q{http://github.com/tapajos/highrise}
|
82
|
-
s.rdoc_options = ["--charset=UTF-8"]
|
14
|
+
s.files = `git ls-files`.split("\n")
|
15
|
+
s.test_files = `git ls-files -- {test,spec,features,examples}/*`.split("\n")
|
83
16
|
s.require_paths = ["lib"]
|
84
|
-
s.rubygems_version = %q{1.3.7}
|
85
|
-
s.summary = %q{Ruby wrapper around Highrise API}
|
86
|
-
s.test_files = [
|
87
|
-
"spec/cachable_spec.rb",
|
88
|
-
"spec/highrise/account_spec.rb",
|
89
|
-
"spec/highrise/base_spec.rb",
|
90
|
-
"spec/highrise/comment_spec.rb",
|
91
|
-
"spec/highrise/company_spec.rb",
|
92
|
-
"spec/highrise/deal_spec.rb",
|
93
|
-
"spec/highrise/email_spec.rb",
|
94
|
-
"spec/highrise/group_spec.rb",
|
95
|
-
"spec/highrise/kase_spec.rb",
|
96
|
-
"spec/highrise/membership_spec.rb",
|
97
|
-
"spec/highrise/note_spec.rb",
|
98
|
-
"spec/highrise/pagination_spec.rb",
|
99
|
-
"spec/highrise/person_spec.rb",
|
100
|
-
"spec/highrise/subject_spec.rb",
|
101
|
-
"spec/highrise/tag_spec.rb",
|
102
|
-
"spec/highrise/task_spec.rb",
|
103
|
-
"spec/highrise/user_spec.rb",
|
104
|
-
"spec/spec_helper.rb",
|
105
|
-
"examples/config_initializers_highrise.rb",
|
106
|
-
"examples/extending.rb",
|
107
|
-
"examples/sample.rb"
|
108
|
-
]
|
109
17
|
|
110
|
-
|
111
|
-
|
112
|
-
|
18
|
+
s.authors = ["Marcos Tapaj\303\263s", "Ken Mayer"]
|
19
|
+
s.email = ["marcos@tapajos.me", "kmayer@bitwrangler.com"]
|
20
|
+
s.homepage = "http://github.com/tapajos/highrise"
|
21
|
+
s.summary = %q{Ruby wrapper around Highrise API}
|
22
|
+
s.description = <<-EOT
|
23
|
+
Based on the original API module from DHH, http://developer.37signals.com/highrise/, this
|
24
|
+
gem is a cleaned up, tested version of the same.
|
113
25
|
|
114
|
-
|
115
|
-
s.add_runtime_dependency(%q<activeresource>, [">= 2.1"])
|
116
|
-
s.add_runtime_dependency(%q<activesupport>, [">= 2.1"])
|
117
|
-
else
|
118
|
-
s.add_dependency(%q<activeresource>, [">= 2.1"])
|
119
|
-
s.add_dependency(%q<activesupport>, [">= 2.1"])
|
120
|
-
end
|
121
|
-
else
|
122
|
-
s.add_dependency(%q<activeresource>, [">= 2.1"])
|
123
|
-
s.add_dependency(%q<activesupport>, [">= 2.1"])
|
124
|
-
end
|
125
|
-
end
|
26
|
+
Configure by adding the following:
|
126
27
|
|
28
|
+
require 'highrise'
|
29
|
+
Highrise::Base.site = 'http://your_site.highrisehq.com/'
|
30
|
+
Highrise::Base.user = 'your_api_auth_token'
|
31
|
+
EOT
|
32
|
+
|
33
|
+
end
|
data/lib/highrise.rb
CHANGED
@@ -1,10 +1,7 @@
|
|
1
|
-
gem 'activeresource', " >= 2.3.8"
|
2
|
-
require 'active_resource'
|
3
|
-
$:.unshift(File.dirname(__FILE__))
|
4
|
-
|
5
1
|
require 'highrise/base'
|
6
2
|
require 'highrise/pagination'
|
7
3
|
require 'highrise/taggable'
|
4
|
+
require 'highrise/searchable'
|
8
5
|
require 'highrise/subject'
|
9
6
|
require 'highrise/comment'
|
10
7
|
require 'highrise/company'
|
@@ -18,4 +15,8 @@ require 'highrise/task'
|
|
18
15
|
require 'highrise/user'
|
19
16
|
require 'highrise/tag'
|
20
17
|
require 'highrise/deal'
|
21
|
-
require 'highrise/account'
|
18
|
+
require 'highrise/account'
|
19
|
+
require 'highrise/deal_category'
|
20
|
+
require 'highrise/task_category'
|
21
|
+
require 'highrise/party'
|
22
|
+
require 'highrise/recording'
|
data/lib/highrise/account.rb
CHANGED
data/lib/highrise/base.rb
CHANGED
@@ -1,7 +1,19 @@
|
|
1
|
-
require
|
1
|
+
require 'active_resource'
|
2
2
|
|
3
3
|
module Highrise
|
4
4
|
class Base < ActiveResource::Base
|
5
|
-
|
5
|
+
protected
|
6
|
+
# Dynamic finder for attributes
|
7
|
+
def self.method_missing(method, *args)
|
8
|
+
if method.to_s =~ /^find_(all_)?by_([_a-zA-Z]\w*)$/
|
9
|
+
raise ArgumentError, "Dynamic finder method must take an argument." if args.empty?
|
10
|
+
options = args.extract_options!
|
11
|
+
resources = respond_to?(:find_all_across_pages) ? send(:find_all_across_pages, options) : send(:find, :all)
|
12
|
+
resources.send($1 == 'all_' ? 'select' : 'detect') { |container| container.send($2) == args.first }
|
13
|
+
else
|
14
|
+
super
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
6
18
|
end
|
7
|
-
end
|
19
|
+
end
|
data/lib/highrise/comment.rb
CHANGED
data/lib/highrise/company.rb
CHANGED
@@ -2,13 +2,14 @@ module Highrise
|
|
2
2
|
class Company < Subject
|
3
3
|
include Pagination
|
4
4
|
include Taggable
|
5
|
+
include Searchable
|
5
6
|
|
6
7
|
def self.find_all_across_pages_since(time)
|
7
|
-
find_all_across_pages(:params => { :since => time.utc.
|
8
|
+
find_all_across_pages(:params => { :since => time.utc.strftime("%Y%m%d%H%M%S") })
|
8
9
|
end
|
9
10
|
|
10
11
|
def people
|
11
|
-
Person.
|
12
|
+
Person.find_all_across_pages(:from => "/companies/#{id}/people.xml")
|
12
13
|
end
|
13
14
|
|
14
15
|
def label
|