chute 0.0.2 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +16 -2
- data/Gemfile.lock +52 -0
- data/LICENSE.txt +20 -0
- data/README.md +46 -0
- data/Rakefile +48 -6
- data/VERSION +1 -0
- data/chute.gemspec +120 -16
- data/lib/chute.rb +7 -20
- data/lib/chute/client.rb +42 -0
- data/lib/chute/configuration.rb +40 -0
- data/lib/chute/connection.rb +64 -0
- data/lib/chute/response.rb +22 -0
- data/lib/chute/v2/albums.rb +60 -0
- data/lib/chute/v2/assets.rb +55 -0
- data/lib/chute/v2/comments.rb +29 -0
- data/lib/chute/v2/flags.rb +21 -0
- data/lib/chute/v2/hearts.rb +21 -0
- data/lib/chute/v2/parcels.rb +21 -0
- data/lib/chute/v2/tags.rb +36 -0
- data/lib/chute/v2/triggers.rb +26 -0
- data/lib/chute/v2/users.rb +18 -0
- data/lib/chute/v2/votes.rb +21 -0
- data/lib/chute/version.rb +7 -1
- data/spec/chute/chute_spec.rb +64 -0
- data/spec/chute/client_spec.rb +82 -0
- data/spec/chute/connection_spec.rb +47 -0
- data/spec/chute/response_spec.rb +16 -0
- data/spec/chute/v2/albums_spec.rb +197 -0
- data/spec/chute/v2/assets_spec.rb +171 -0
- data/spec/chute/v2/comments_spec.rb +88 -0
- data/spec/chute/v2/flags_spec.rb +56 -0
- data/spec/chute/v2/hearts_spec.rb +57 -0
- data/spec/chute/v2/parcels_spec.rb +24 -0
- data/spec/chute/v2/tags_spec.rb +79 -0
- data/spec/chute/v2/trigger_spec.rb +127 -0
- data/spec/chute/v2/users_spec.rb +53 -0
- data/spec/chute/v2/votes_spec.rb +56 -0
- data/spec/fixtures/chute_cassettes/albums/album_create_with_permission_view.yml +69 -0
- data/spec/fixtures/chute_cassettes/albums/albums_add_remove_assets.yml +187 -0
- data/spec/fixtures/chute_cassettes/albums/albums_create.yml +69 -0
- data/spec/fixtures/chute_cassettes/albums/albums_delete.yml +128 -0
- data/spec/fixtures/chute_cassettes/albums/albums_get.yml +135 -0
- data/spec/fixtures/chute_cassettes/albums/albums_list.yml +89 -0
- data/spec/fixtures/chute_cassettes/albums/albums_stats.yml +128 -0
- data/spec/fixtures/chute_cassettes/albums/albums_update.yml +135 -0
- data/spec/fixtures/chute_cassettes/assets/assets_delete.yml +131 -0
- data/spec/fixtures/chute_cassettes/assets/assets_geo.yml +197 -0
- data/spec/fixtures/chute_cassettes/assets/assets_get.yml +138 -0
- data/spec/fixtures/chute_cassettes/assets/assets_import.yml +76 -0
- data/spec/fixtures/chute_cassettes/assets/assets_list.yml +77 -0
- data/spec/fixtures/chute_cassettes/assets/assets_update.yml +138 -0
- data/spec/fixtures/chute_cassettes/comments/comments_create.yml +196 -0
- data/spec/fixtures/chute_cassettes/comments/comments_list.yml +259 -0
- data/spec/fixtures/chute_cassettes/flags/flags_methods.yml +313 -0
- data/spec/fixtures/chute_cassettes/hearts/hearts_methods.yml +254 -0
- data/spec/fixtures/chute_cassettes/tags/tags_assets.yml +311 -0
- data/spec/fixtures/chute_cassettes/triggers/trigger_errors.yml +62 -0
- data/spec/fixtures/chute_cassettes/triggers/triggers_cleanup.yml +184 -0
- data/spec/fixtures/chute_cassettes/triggers/triggers_create.yml +65 -0
- data/spec/fixtures/chute_cassettes/triggers/triggers_delete.yml +124 -0
- data/spec/fixtures/chute_cassettes/triggers/triggers_list.yml +66 -0
- data/spec/fixtures/chute_cassettes/triggers/triggers_update.yml +127 -0
- data/spec/fixtures/chute_cassettes/users/users_get.yml +128 -0
- data/spec/fixtures/chute_cassettes/users/users_me.yml +66 -0
- data/spec/fixtures/chute_cassettes/votes/votes_methods.yml +313 -0
- data/spec/spec_helper.rb +27 -0
- metadata +210 -33
- data/.gitignore +0 -5
- data/README +0 -125
- data/config/chute.rb +0 -0
- data/lib/chute/account.rb +0 -58
- data/lib/chute/app.rb +0 -32
- data/lib/chute/asset.rb +0 -124
- data/lib/chute/bundle.rb +0 -72
- data/lib/chute/chute.rb +0 -203
- data/lib/chute/collection.rb +0 -47
- data/lib/chute/comment.rb +0 -32
- data/lib/chute/exception.rb +0 -7
- data/lib/chute/http_service.rb +0 -114
- data/lib/chute/inbox.rb +0 -41
- data/lib/chute/parcel.rb +0 -45
- data/lib/chute/resource.rb +0 -354
- data/lib/chute/user.rb +0 -113
- data/lib/chute/util.rb +0 -14
- data/test/test_sudoku.rb +0 -7
data/lib/chute/app.rb
DELETED
@@ -1,32 +0,0 @@
|
|
1
|
-
module Chute
|
2
|
-
class GCApp < GCResource
|
3
|
-
|
4
|
-
def save
|
5
|
-
raise NotImplementedError
|
6
|
-
end
|
7
|
-
|
8
|
-
def update
|
9
|
-
raise NotImplementedError
|
10
|
-
end
|
11
|
-
|
12
|
-
def destroy
|
13
|
-
raise NotImplementedError
|
14
|
-
end
|
15
|
-
|
16
|
-
# Public: Resource name
|
17
|
-
def resource_name
|
18
|
-
'app'
|
19
|
-
end
|
20
|
-
|
21
|
-
# Public: Resource name
|
22
|
-
def resource_path
|
23
|
-
'app'
|
24
|
-
end
|
25
|
-
|
26
|
-
# Public: Resource name
|
27
|
-
def class_path
|
28
|
-
'app'
|
29
|
-
end
|
30
|
-
|
31
|
-
end
|
32
|
-
end
|
data/lib/chute/asset.rb
DELETED
@@ -1,124 +0,0 @@
|
|
1
|
-
module Chute
|
2
|
-
class GCAsset < GCResource
|
3
|
-
|
4
|
-
attr_accessor :id,
|
5
|
-
:url,
|
6
|
-
:share_url,
|
7
|
-
:is_portrait
|
8
|
-
|
9
|
-
def initialize(attributes = {})
|
10
|
-
super
|
11
|
-
@id = attributes[:id]
|
12
|
-
@url = attributes[:url]
|
13
|
-
@share_url = attributes[:share_url]
|
14
|
-
@is_portrait = attributes[:is_portrait]
|
15
|
-
end
|
16
|
-
|
17
|
-
# Public: Returns pluralized name of the resource.
|
18
|
-
def resource_name
|
19
|
-
'assets'
|
20
|
-
end
|
21
|
-
|
22
|
-
# Public: Relative url of an asset for a custom geometry
|
23
|
-
#
|
24
|
-
# height - Integer: height of the asset images
|
25
|
-
# width - String: width of the asset image
|
26
|
-
#
|
27
|
-
# Examples
|
28
|
-
#
|
29
|
-
# asset.url = "asset url"
|
30
|
-
# asset.custom_url(200, 300)
|
31
|
-
# # => "asset url/200x300"
|
32
|
-
# Returns the url to the custom image
|
33
|
-
|
34
|
-
def custom_url(height, width)
|
35
|
-
"#{url}/#{height}x#{width}" if url
|
36
|
-
end
|
37
|
-
|
38
|
-
#================================================#
|
39
|
-
# Class Methods #
|
40
|
-
#================================================#
|
41
|
-
|
42
|
-
# Public: Fetch asset from its id.
|
43
|
-
# id - Integer: identifier.
|
44
|
-
#
|
45
|
-
# Example
|
46
|
-
#
|
47
|
-
# Chute::GCAsset.find_by_id(23)
|
48
|
-
# # => asset
|
49
|
-
# # => false if not found
|
50
|
-
# Returns GCAsset
|
51
|
-
|
52
|
-
def self.find_by_id(id)
|
53
|
-
asset = Chute::GCAsset.new
|
54
|
-
asset.perform(get("/assets/#{id}")) ? asset : false
|
55
|
-
end
|
56
|
-
|
57
|
-
# Public: Returns pluralized name of the resource.
|
58
|
-
def self.class_path
|
59
|
-
"assets"
|
60
|
-
end
|
61
|
-
|
62
|
-
# Public: Make asset as favorite
|
63
|
-
# id - Identifier.
|
64
|
-
#
|
65
|
-
# Example
|
66
|
-
#
|
67
|
-
# Chute::GCAsset.heart(23)
|
68
|
-
# # => true
|
69
|
-
# Returns boolean true or false
|
70
|
-
|
71
|
-
def self.heart(id)
|
72
|
-
response = get("/assets/#{id}/heart")
|
73
|
-
response.is_success
|
74
|
-
end
|
75
|
-
|
76
|
-
# Public: Remove asset as favorite
|
77
|
-
# id - Identifier.
|
78
|
-
#
|
79
|
-
# Example
|
80
|
-
#
|
81
|
-
# Chute::GCAsset.unheart(23)
|
82
|
-
# # => true
|
83
|
-
# Returns boolean true or false
|
84
|
-
|
85
|
-
def self.unheart(id)
|
86
|
-
response = get("/assets/#{id}/unheart")
|
87
|
-
response.is_success
|
88
|
-
end
|
89
|
-
|
90
|
-
# Public: Remove assets
|
91
|
-
# ids - Array: Identifier list
|
92
|
-
#
|
93
|
-
# Example
|
94
|
-
#
|
95
|
-
# Chute::GCAsset.remove([1, 23, 56])
|
96
|
-
# # => true
|
97
|
-
# Returns boolean true or false
|
98
|
-
|
99
|
-
def self.remove(ids=[])
|
100
|
-
response = post("/assets/remove", {:asset_ids => ids})
|
101
|
-
response.is_success
|
102
|
-
end
|
103
|
-
|
104
|
-
# Public: Verify assets
|
105
|
-
# files - Array: [URL, size, md5]
|
106
|
-
#
|
107
|
-
# Example
|
108
|
-
#
|
109
|
-
# files = [{
|
110
|
-
# :url => "Users/payalgupta/Desktop/39-Dcroe.jpg",
|
111
|
-
# :size => 34500,
|
112
|
-
# :md5 => 34500
|
113
|
-
# }]
|
114
|
-
# Chute::GCAsset.verify(files)
|
115
|
-
# # => true
|
116
|
-
# Returns boolean true or false
|
117
|
-
|
118
|
-
def self.verify(files=[])
|
119
|
-
response = post("/assets/verify", {:files => files})
|
120
|
-
response.is_success
|
121
|
-
end
|
122
|
-
|
123
|
-
end
|
124
|
-
end
|
data/lib/chute/bundle.rb
DELETED
@@ -1,72 +0,0 @@
|
|
1
|
-
module Chute
|
2
|
-
class GCBundle < GCResource
|
3
|
-
attr_accessor :id,
|
4
|
-
:url,
|
5
|
-
:shortcut
|
6
|
-
|
7
|
-
def initialize(attributes={})
|
8
|
-
super
|
9
|
-
@id = attributes[:id]
|
10
|
-
@url = attributes[:url]
|
11
|
-
@shortcut = attributes[:shortcut]
|
12
|
-
end
|
13
|
-
|
14
|
-
# Public: Returns pluralized name of the resource.
|
15
|
-
def resource_name
|
16
|
-
'bundles'
|
17
|
-
end
|
18
|
-
|
19
|
-
def destroy
|
20
|
-
raise NotImplementedError
|
21
|
-
end
|
22
|
-
|
23
|
-
# Public: Add assets to a bundle
|
24
|
-
# asset_ids - Array: Identifier list of assets
|
25
|
-
#
|
26
|
-
# Example
|
27
|
-
#
|
28
|
-
# Chute::GCBundle.add_assets([1, 23, 56])
|
29
|
-
# # => true
|
30
|
-
# Returns boolean true or false
|
31
|
-
|
32
|
-
def add_assets(asset_ids)
|
33
|
-
response = self.class.post("/bundles/#{id}/add", :asset_ids => "#{asset_ids}")
|
34
|
-
response.is_success
|
35
|
-
end
|
36
|
-
|
37
|
-
# Public: Remove assets from a bundle
|
38
|
-
# asset_ids - Array: Identifier list of assets
|
39
|
-
#
|
40
|
-
# Example
|
41
|
-
#
|
42
|
-
# Chute::GCBundle.remove_assets([1, 23, 56])
|
43
|
-
# # => true
|
44
|
-
# Returns boolean true or false
|
45
|
-
|
46
|
-
def remove_assets(asset_ids)
|
47
|
-
response = self.class.post("/bundles/#{id}/remove", :asset_ids => "#{asset_ids}")
|
48
|
-
response.is_success
|
49
|
-
end
|
50
|
-
|
51
|
-
# Public: Fetch bundle from its id.
|
52
|
-
# id - Integer: identifier.
|
53
|
-
#
|
54
|
-
# Example
|
55
|
-
#
|
56
|
-
# Chute::GCBundle.find_by_id(23)
|
57
|
-
# # => bundle
|
58
|
-
# # => false if not found
|
59
|
-
# Returns GCBundle
|
60
|
-
|
61
|
-
def self.find_by_id(id)
|
62
|
-
bundle = Chute::GCBundle.new
|
63
|
-
bundle.perform(get("/bundles/#{id}")) ? bundle : false
|
64
|
-
end
|
65
|
-
|
66
|
-
# Public: Returns pluralized name of the resource.
|
67
|
-
def self.class_path
|
68
|
-
"bundles"
|
69
|
-
end
|
70
|
-
|
71
|
-
end
|
72
|
-
end
|
data/lib/chute/chute.rb
DELETED
@@ -1,203 +0,0 @@
|
|
1
|
-
module Chute
|
2
|
-
class GCChute < GCResource
|
3
|
-
|
4
|
-
CHUTE_STATUS = {
|
5
|
-
"401" => "Password Protected",
|
6
|
-
"200" => "Public"
|
7
|
-
}
|
8
|
-
|
9
|
-
attr_accessor :id,
|
10
|
-
:name,
|
11
|
-
:shortcut,
|
12
|
-
:created_at,
|
13
|
-
:updated_at,
|
14
|
-
:assets_count,
|
15
|
-
:members_count,
|
16
|
-
:contributors_count,
|
17
|
-
:moderate_photos,
|
18
|
-
:moderate_members,
|
19
|
-
:moderate_comments,
|
20
|
-
:permission_view,
|
21
|
-
:permission_add_photos,
|
22
|
-
:permission_add_members,
|
23
|
-
:permission_add_comments
|
24
|
-
|
25
|
-
def initialize(attributes = {})
|
26
|
-
super
|
27
|
-
@id = attributes[:id]
|
28
|
-
@name = attributes[:name]
|
29
|
-
@shortcut = attributes[:shortcut]
|
30
|
-
|
31
|
-
@created_at = attributes[:created_at]
|
32
|
-
@updated_at = attributes[:updated_at]
|
33
|
-
|
34
|
-
@assets_count = attributes[:assets_count]
|
35
|
-
@members_count = attributes[:members_count]
|
36
|
-
@contributors_count = attributes[:contributors_count]
|
37
|
-
|
38
|
-
@moderate_photos = attributes[:moderate_photos]
|
39
|
-
@moderate_members = attributes[:moderate_members]
|
40
|
-
@moderate_comments = attributes[:moderate_comments]
|
41
|
-
|
42
|
-
@permission_view = attributes[:permission_view]
|
43
|
-
@permission_add_photos = attributes[:permission_add_photos]
|
44
|
-
@permission_add_members = attributes[:permission_add_members]
|
45
|
-
@permission_add_comments = attributes[:permission_add_comments]
|
46
|
-
end
|
47
|
-
|
48
|
-
# Public: Fetch child chutes for a chute
|
49
|
-
#
|
50
|
-
# Returns GCCollection of GCChute
|
51
|
-
|
52
|
-
def children
|
53
|
-
self.class.perform(self.class.get("/chutes/#{id}/children"))
|
54
|
-
end
|
55
|
-
|
56
|
-
# Public: Send a join request for a chute.
|
57
|
-
#
|
58
|
-
# Password - String, required for password protected chutes.
|
59
|
-
#
|
60
|
-
# Returns membership details and status.
|
61
|
-
# Public Chute - Request accepted.
|
62
|
-
# Password-protected Chute - Password required.
|
63
|
-
# Private Chute - Request for approval sent to admin.
|
64
|
-
|
65
|
-
def join(password=nil)
|
66
|
-
response = self.class.get("/chutes/#{id}/join")
|
67
|
-
response.data
|
68
|
-
end
|
69
|
-
|
70
|
-
# Public: Leave a chute.
|
71
|
-
def leave
|
72
|
-
response = self.class.post("/chutes/#{id}/leave")
|
73
|
-
response.data
|
74
|
-
end
|
75
|
-
|
76
|
-
# Public: Fetch list of chute contributors.
|
77
|
-
def contributors
|
78
|
-
Chute::GCChute.perform(self.class.post("/chutes/#{id}/contributors"))
|
79
|
-
end
|
80
|
-
|
81
|
-
# Public: Fetch assets for a chute
|
82
|
-
#
|
83
|
-
# Returns GCCollection of GCAsset
|
84
|
-
def assets
|
85
|
-
Chute::GCAsset.perform(self.class.get("/chutes/#{id}/assets"))
|
86
|
-
end
|
87
|
-
|
88
|
-
# def add_assets(asset_ids)
|
89
|
-
# response = self.class.post("/chutes/#{id}/add_assets", :asset_ids => "#{asset_ids}")
|
90
|
-
# response.is_success
|
91
|
-
# end
|
92
|
-
|
93
|
-
# Public: Remove assets from a chute
|
94
|
-
#
|
95
|
-
# Example
|
96
|
-
#
|
97
|
-
# Chute::GCChute.remove_assets([1, 23, 56])
|
98
|
-
# # => true
|
99
|
-
#
|
100
|
-
# Returns boolean true or false
|
101
|
-
def remove_assets(asset_ids)
|
102
|
-
response = self.class.post("/chutes/#{id}/assets/remove", :asset_ids => asset_ids)
|
103
|
-
response.is_success
|
104
|
-
end
|
105
|
-
|
106
|
-
# Public: Comment on an asset in a chute
|
107
|
-
#
|
108
|
-
# text - String, comment
|
109
|
-
# asset_id - Identifier of the asset
|
110
|
-
#
|
111
|
-
# Example
|
112
|
-
#
|
113
|
-
# Chute::GCChute.add_comment("Nice Picture", 24)
|
114
|
-
# # => comment
|
115
|
-
#
|
116
|
-
# Returns GCComment instance
|
117
|
-
def add_comment(text, asset_id)
|
118
|
-
comment = Chute::GCComment.new
|
119
|
-
comment.perform(self.class.post("/chutes/#{id}/assets/#{asset_id}/comments", {:comment => "test comment by payal"}))
|
120
|
-
comment
|
121
|
-
end
|
122
|
-
|
123
|
-
# Public: Fetch comments for a asset
|
124
|
-
#
|
125
|
-
# asset_id - Identifier for asset
|
126
|
-
#
|
127
|
-
# Returns GCCollection of GCAsset
|
128
|
-
def comments(asset_id)
|
129
|
-
Chute::GCComment.perform(self.class.get("/chutes/#{id}/assets/#{asset_id}/comments"))
|
130
|
-
end
|
131
|
-
|
132
|
-
# Public: Returns pluralized name of the resource.
|
133
|
-
def resource_name
|
134
|
-
'chutes'
|
135
|
-
end
|
136
|
-
|
137
|
-
# Public: Fetch chute status from its shortcut.
|
138
|
-
# shortcut - String: shortcut of the chute.
|
139
|
-
#
|
140
|
-
# Example
|
141
|
-
#
|
142
|
-
# Chute::GCChute.fetch_status("adsvyh")
|
143
|
-
# # => public, password-protected or inaccessible
|
144
|
-
# Returns public, password-protected or inaccessibles string
|
145
|
-
|
146
|
-
def self.fetch_status(shortcut)
|
147
|
-
chute = Chute::GCChute.new
|
148
|
-
response = get("/chutes/#{shortcut}/public/assets.js")
|
149
|
-
CHUTE_STATUS[response.status] || "InAccessible"
|
150
|
-
end
|
151
|
-
|
152
|
-
# Public: Fetch chute from its shortcut.
|
153
|
-
# shortcut - String: shortcut of the chute.
|
154
|
-
#
|
155
|
-
# Example
|
156
|
-
#
|
157
|
-
# Chute::GCChute.find_by_shortcut("adsvyh")
|
158
|
-
# # => chute
|
159
|
-
# # => false if not found
|
160
|
-
# Returns GCChute.
|
161
|
-
|
162
|
-
def self.find_by_shortcut(shortcut)
|
163
|
-
chute = Chute::GCChute.new
|
164
|
-
chute.perform(get("/chutes/#{shortcut}"))
|
165
|
-
end
|
166
|
-
|
167
|
-
# Public: Fetch chute from its id.
|
168
|
-
# id - Integer: identifier.
|
169
|
-
#
|
170
|
-
# Example
|
171
|
-
#
|
172
|
-
# Chute::GCChute.find_by_id(23)
|
173
|
-
# # => chute
|
174
|
-
# # => false if not found
|
175
|
-
# Returns GCChute.
|
176
|
-
|
177
|
-
def self.find_by_id(id)
|
178
|
-
chute = Chute::GCChute.new
|
179
|
-
chute.perform(get("/chutes/#{id}")) ? chute : false
|
180
|
-
end
|
181
|
-
|
182
|
-
# Public: Fetch all chutes for the user.
|
183
|
-
#
|
184
|
-
# Returns GCCollection of GCChutes.
|
185
|
-
def self.all
|
186
|
-
self.perform(get("/me/chutes"))
|
187
|
-
end
|
188
|
-
|
189
|
-
# Public: Fetch chute heirarchy for the user
|
190
|
-
#
|
191
|
-
# Returns GCCollection of GCChute
|
192
|
-
|
193
|
-
def self.tree
|
194
|
-
perform(get("/chutes/tree"))
|
195
|
-
end
|
196
|
-
|
197
|
-
# Public: Returns pluralized name of the resource.
|
198
|
-
def self.class_path
|
199
|
-
"chutes"
|
200
|
-
end
|
201
|
-
|
202
|
-
end
|
203
|
-
end
|
data/lib/chute/collection.rb
DELETED
@@ -1,47 +0,0 @@
|
|
1
|
-
module Chute
|
2
|
-
class GCCollection < Array
|
3
|
-
|
4
|
-
# Public: Append an item to collection
|
5
|
-
# single_or_array - Single item or an Array of item
|
6
|
-
#
|
7
|
-
# Example
|
8
|
-
#
|
9
|
-
# gc_collection = Chute::GCChute.all
|
10
|
-
# chute = Chute.new(:name => "New Chute Added")
|
11
|
-
# chute.save
|
12
|
-
#
|
13
|
-
# gc_collection.append(chute)
|
14
|
-
# # => appends the chute to the colection
|
15
|
-
# Returns GCCollection.
|
16
|
-
|
17
|
-
def append(single_or_array)
|
18
|
-
if Array === single_or_array
|
19
|
-
self.concat(single_or_array)
|
20
|
-
else
|
21
|
-
self << single_or_array
|
22
|
-
end
|
23
|
-
self.uniq!
|
24
|
-
end
|
25
|
-
|
26
|
-
# Public: Remove an item to collection
|
27
|
-
# single_or_array - Single item or an Array of item
|
28
|
-
#
|
29
|
-
# Example
|
30
|
-
#
|
31
|
-
# gc_collection = Chute::GCChute.all
|
32
|
-
# chute = Chute.find_by_id(23)
|
33
|
-
#
|
34
|
-
# gc_collection.remove(chute)
|
35
|
-
# # => remove the chute from the colection
|
36
|
-
# Returns GCCollection.
|
37
|
-
|
38
|
-
def remove(single_or_array)
|
39
|
-
if Array === single_or_array
|
40
|
-
self.reject!{|elem| single_or_array.include?(elem)}
|
41
|
-
else
|
42
|
-
self.delete(single_or_array)
|
43
|
-
end
|
44
|
-
self.uniq!
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|