appwrite 1.0.11 → 2.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +16 -0
  3. data/Gemfile +1 -0
  4. data/LICENSE +1 -1
  5. data/README.md +72 -5
  6. data/appwrite.gemspec +3 -5
  7. data/docs/examples/account/create-recovery.md +15 -0
  8. data/docs/examples/account/create-verification.md +15 -0
  9. data/docs/examples/account/delete-session.md +15 -0
  10. data/docs/examples/account/delete-sessions.md +15 -0
  11. data/docs/examples/account/delete.md +15 -0
  12. data/docs/examples/account/get-logs.md +15 -0
  13. data/docs/examples/account/get-prefs.md +15 -0
  14. data/docs/examples/account/get-sessions.md +15 -0
  15. data/docs/examples/account/get.md +15 -0
  16. data/docs/examples/account/update-email.md +15 -0
  17. data/docs/examples/account/update-name.md +15 -0
  18. data/docs/examples/account/update-password.md +15 -0
  19. data/docs/examples/account/update-prefs.md +15 -0
  20. data/docs/examples/account/update-recovery.md +15 -0
  21. data/docs/examples/account/update-verification.md +15 -0
  22. data/docs/examples/{database/get-collection-logs.md → avatars/get-initials.md} +2 -2
  23. data/docs/examples/database/create-document.md +1 -1
  24. data/docs/examples/database/update-collection.md +1 -1
  25. data/docs/examples/database/update-document.md +1 -1
  26. data/docs/examples/functions/create-execution.md +15 -0
  27. data/docs/examples/functions/create-tag.md +15 -0
  28. data/docs/examples/functions/create.md +15 -0
  29. data/docs/examples/functions/delete-tag.md +15 -0
  30. data/docs/examples/functions/delete.md +15 -0
  31. data/docs/examples/functions/get-execution.md +15 -0
  32. data/docs/examples/functions/get-tag.md +15 -0
  33. data/docs/examples/functions/get.md +15 -0
  34. data/docs/examples/functions/list-executions.md +15 -0
  35. data/docs/examples/functions/list-tags.md +15 -0
  36. data/docs/examples/functions/list.md +15 -0
  37. data/docs/examples/functions/update-tag.md +15 -0
  38. data/docs/examples/functions/update.md +15 -0
  39. data/docs/examples/locale/get-languages.md +15 -0
  40. data/docs/examples/storage/create-file.md +1 -1
  41. data/docs/examples/teams/delete-membership.md +1 -1
  42. data/docs/examples/teams/update-membership-roles.md +15 -0
  43. data/docs/examples/teams/update-membership-status.md +15 -0
  44. data/docs/examples/users/delete.md +15 -0
  45. data/docs/examples/users/update-status.md +1 -1
  46. data/lib/appwrite.rb +5 -0
  47. data/lib/appwrite/client.rb +46 -5
  48. data/lib/appwrite/exception.rb +14 -0
  49. data/lib/appwrite/file.rb +23 -0
  50. data/lib/appwrite/services/account.rb +280 -0
  51. data/lib/appwrite/services/avatars.rb +133 -34
  52. data/lib/appwrite/services/database.rb +199 -67
  53. data/lib/appwrite/services/functions.rb +357 -0
  54. data/lib/appwrite/services/health.rb +12 -24
  55. data/lib/appwrite/services/locale.rb +16 -12
  56. data/lib/appwrite/services/storage.rb +124 -35
  57. data/lib/appwrite/services/teams.rb +187 -34
  58. data/lib/appwrite/services/users.rb +115 -31
  59. metadata +44 -11
@@ -1,15 +1,26 @@
1
1
  module Appwrite
2
2
  class Database < Service
3
3
 
4
- def list_collections(search: '', limit: 25, offset: 0, order_type: 'ASC')
4
+ def list_collections(search: nil, limit: nil, offset: nil, order_type: nil)
5
5
  path = '/database/collections'
6
6
 
7
- params = {
8
- 'search': search,
9
- 'limit': limit,
10
- 'offset': offset,
11
- 'orderType': order_type
12
- }
7
+ params = {}
8
+
9
+ if !search.nil?
10
+ params[:search] = search
11
+ end
12
+
13
+ if !limit.nil?
14
+ params[:limit] = limit
15
+ end
16
+
17
+ if !offset.nil?
18
+ params[:offset] = offset
19
+ end
20
+
21
+ if !order_type.nil?
22
+ params[:orderType] = order_type
23
+ end
13
24
 
14
25
  return @client.call('get', path, {
15
26
  'content-type' => 'application/json',
@@ -17,14 +28,41 @@ module Appwrite
17
28
  end
18
29
 
19
30
  def create_collection(name:, read:, write:, rules:)
31
+ if name.nil?
32
+ raise Appwrite::Exception.new('Missing required parameter: "name"')
33
+ end
34
+
35
+ if read.nil?
36
+ raise Appwrite::Exception.new('Missing required parameter: "read"')
37
+ end
38
+
39
+ if write.nil?
40
+ raise Appwrite::Exception.new('Missing required parameter: "write"')
41
+ end
42
+
43
+ if rules.nil?
44
+ raise Appwrite::Exception.new('Missing required parameter: "rules"')
45
+ end
46
+
20
47
  path = '/database/collections'
21
48
 
22
- params = {
23
- 'name': name,
24
- 'read': read,
25
- 'write': write,
26
- 'rules': rules
27
- }
49
+ params = {}
50
+
51
+ if !name.nil?
52
+ params[:name] = name
53
+ end
54
+
55
+ if !read.nil?
56
+ params[:read] = read
57
+ end
58
+
59
+ if !write.nil?
60
+ params[:write] = write
61
+ end
62
+
63
+ if !rules.nil?
64
+ params[:rules] = rules
65
+ end
28
66
 
29
67
  return @client.call('post', path, {
30
68
  'content-type' => 'application/json',
@@ -32,27 +70,49 @@ module Appwrite
32
70
  end
33
71
 
34
72
  def get_collection(collection_id:)
73
+ if collection_id.nil?
74
+ raise Appwrite::Exception.new('Missing required parameter: "collectionId"')
75
+ end
76
+
35
77
  path = '/database/collections/{collectionId}'
36
78
  .gsub('{collectionId}', collection_id)
37
79
 
38
- params = {
39
- }
80
+ params = {}
40
81
 
41
82
  return @client.call('get', path, {
42
83
  'content-type' => 'application/json',
43
84
  }, params);
44
85
  end
45
86
 
46
- def update_collection(collection_id:, name:, read:, write:, rules: [])
87
+ def update_collection(collection_id:, name:, read: nil, write: nil, rules: nil)
88
+ if collection_id.nil?
89
+ raise Appwrite::Exception.new('Missing required parameter: "collectionId"')
90
+ end
91
+
92
+ if name.nil?
93
+ raise Appwrite::Exception.new('Missing required parameter: "name"')
94
+ end
95
+
47
96
  path = '/database/collections/{collectionId}'
48
97
  .gsub('{collectionId}', collection_id)
49
98
 
50
- params = {
51
- 'name': name,
52
- 'read': read,
53
- 'write': write,
54
- 'rules': rules
55
- }
99
+ params = {}
100
+
101
+ if !name.nil?
102
+ params[:name] = name
103
+ end
104
+
105
+ if !read.nil?
106
+ params[:read] = read
107
+ end
108
+
109
+ if !write.nil?
110
+ params[:write] = write
111
+ end
112
+
113
+ if !rules.nil?
114
+ params[:rules] = rules
115
+ end
56
116
 
57
117
  return @client.call('put', path, {
58
118
  'content-type' => 'application/json',
@@ -60,50 +120,100 @@ module Appwrite
60
120
  end
61
121
 
62
122
  def delete_collection(collection_id:)
123
+ if collection_id.nil?
124
+ raise Appwrite::Exception.new('Missing required parameter: "collectionId"')
125
+ end
126
+
63
127
  path = '/database/collections/{collectionId}'
64
128
  .gsub('{collectionId}', collection_id)
65
129
 
66
- params = {
67
- }
130
+ params = {}
68
131
 
69
132
  return @client.call('delete', path, {
70
133
  'content-type' => 'application/json',
71
134
  }, params);
72
135
  end
73
136
 
74
- def list_documents(collection_id:, filters: [], offset: 0, limit: 50, order_field: '$id', order_type: 'ASC', order_cast: 'string', search: '', first: 0, last: 0)
137
+ def list_documents(collection_id:, filters: nil, limit: nil, offset: nil, order_field: nil, order_type: nil, order_cast: nil, search: nil)
138
+ if collection_id.nil?
139
+ raise Appwrite::Exception.new('Missing required parameter: "collectionId"')
140
+ end
141
+
75
142
  path = '/database/collections/{collectionId}/documents'
76
143
  .gsub('{collectionId}', collection_id)
77
144
 
78
- params = {
79
- 'filters': filters,
80
- 'offset': offset,
81
- 'limit': limit,
82
- 'orderField': order_field,
83
- 'orderType': order_type,
84
- 'orderCast': order_cast,
85
- 'search': search,
86
- 'first': first,
87
- 'last': last
88
- }
145
+ params = {}
146
+
147
+ if !filters.nil?
148
+ params[:filters] = filters
149
+ end
150
+
151
+ if !limit.nil?
152
+ params[:limit] = limit
153
+ end
154
+
155
+ if !offset.nil?
156
+ params[:offset] = offset
157
+ end
158
+
159
+ if !order_field.nil?
160
+ params[:orderField] = order_field
161
+ end
162
+
163
+ if !order_type.nil?
164
+ params[:orderType] = order_type
165
+ end
166
+
167
+ if !order_cast.nil?
168
+ params[:orderCast] = order_cast
169
+ end
170
+
171
+ if !search.nil?
172
+ params[:search] = search
173
+ end
89
174
 
90
175
  return @client.call('get', path, {
91
176
  'content-type' => 'application/json',
92
177
  }, params);
93
178
  end
94
179
 
95
- def create_document(collection_id:, data:, read:, write:, parent_document: '', parent_property: '', parent_property_type: 'assign')
180
+ def create_document(collection_id:, data:, read: nil, write: nil, parent_document: nil, parent_property: nil, parent_property_type: nil)
181
+ if collection_id.nil?
182
+ raise Appwrite::Exception.new('Missing required parameter: "collectionId"')
183
+ end
184
+
185
+ if data.nil?
186
+ raise Appwrite::Exception.new('Missing required parameter: "data"')
187
+ end
188
+
96
189
  path = '/database/collections/{collectionId}/documents'
97
190
  .gsub('{collectionId}', collection_id)
98
191
 
99
- params = {
100
- 'data': data,
101
- 'read': read,
102
- 'write': write,
103
- 'parentDocument': parent_document,
104
- 'parentProperty': parent_property,
105
- 'parentPropertyType': parent_property_type
106
- }
192
+ params = {}
193
+
194
+ if !data.nil?
195
+ params[:data] = data
196
+ end
197
+
198
+ if !read.nil?
199
+ params[:read] = read
200
+ end
201
+
202
+ if !write.nil?
203
+ params[:write] = write
204
+ end
205
+
206
+ if !parent_document.nil?
207
+ params[:parentDocument] = parent_document
208
+ end
209
+
210
+ if !parent_property.nil?
211
+ params[:parentProperty] = parent_property
212
+ end
213
+
214
+ if !parent_property_type.nil?
215
+ params[:parentPropertyType] = parent_property_type
216
+ end
107
217
 
108
218
  return @client.call('post', path, {
109
219
  'content-type' => 'application/json',
@@ -111,28 +221,55 @@ module Appwrite
111
221
  end
112
222
 
113
223
  def get_document(collection_id:, document_id:)
224
+ if collection_id.nil?
225
+ raise Appwrite::Exception.new('Missing required parameter: "collectionId"')
226
+ end
227
+
228
+ if document_id.nil?
229
+ raise Appwrite::Exception.new('Missing required parameter: "documentId"')
230
+ end
231
+
114
232
  path = '/database/collections/{collectionId}/documents/{documentId}'
115
233
  .gsub('{collectionId}', collection_id)
116
234
  .gsub('{documentId}', document_id)
117
235
 
118
- params = {
119
- }
236
+ params = {}
120
237
 
121
238
  return @client.call('get', path, {
122
239
  'content-type' => 'application/json',
123
240
  }, params);
124
241
  end
125
242
 
126
- def update_document(collection_id:, document_id:, data:, read:, write:)
243
+ def update_document(collection_id:, document_id:, data:, read: nil, write: nil)
244
+ if collection_id.nil?
245
+ raise Appwrite::Exception.new('Missing required parameter: "collectionId"')
246
+ end
247
+
248
+ if document_id.nil?
249
+ raise Appwrite::Exception.new('Missing required parameter: "documentId"')
250
+ end
251
+
252
+ if data.nil?
253
+ raise Appwrite::Exception.new('Missing required parameter: "data"')
254
+ end
255
+
127
256
  path = '/database/collections/{collectionId}/documents/{documentId}'
128
257
  .gsub('{collectionId}', collection_id)
129
258
  .gsub('{documentId}', document_id)
130
259
 
131
- params = {
132
- 'data': data,
133
- 'read': read,
134
- 'write': write
135
- }
260
+ params = {}
261
+
262
+ if !data.nil?
263
+ params[:data] = data
264
+ end
265
+
266
+ if !read.nil?
267
+ params[:read] = read
268
+ end
269
+
270
+ if !write.nil?
271
+ params[:write] = write
272
+ end
136
273
 
137
274
  return @client.call('patch', path, {
138
275
  'content-type' => 'application/json',
@@ -140,30 +277,25 @@ module Appwrite
140
277
  end
141
278
 
142
279
  def delete_document(collection_id:, document_id:)
280
+ if collection_id.nil?
281
+ raise Appwrite::Exception.new('Missing required parameter: "collectionId"')
282
+ end
283
+
284
+ if document_id.nil?
285
+ raise Appwrite::Exception.new('Missing required parameter: "documentId"')
286
+ end
287
+
143
288
  path = '/database/collections/{collectionId}/documents/{documentId}'
144
289
  .gsub('{collectionId}', collection_id)
145
290
  .gsub('{documentId}', document_id)
146
291
 
147
- params = {
148
- }
292
+ params = {}
149
293
 
150
294
  return @client.call('delete', path, {
151
295
  'content-type' => 'application/json',
152
296
  }, params);
153
297
  end
154
298
 
155
- def get_collection_logs(collection_id:)
156
- path = '/database/collections/{collectionId}/logs'
157
- .gsub('{collectionId}', collection_id)
158
-
159
- params = {
160
- }
161
-
162
- return @client.call('get', path, {
163
- 'content-type' => 'application/json',
164
- }, params);
165
- end
166
-
167
299
 
168
300
  protected
169
301
 
@@ -0,0 +1,357 @@
1
+ module Appwrite
2
+ class Functions < Service
3
+
4
+ def list(search: nil, limit: nil, offset: nil, order_type: nil)
5
+ path = '/functions'
6
+
7
+ params = {}
8
+
9
+ if !search.nil?
10
+ params[:search] = search
11
+ end
12
+
13
+ if !limit.nil?
14
+ params[:limit] = limit
15
+ end
16
+
17
+ if !offset.nil?
18
+ params[:offset] = offset
19
+ end
20
+
21
+ if !order_type.nil?
22
+ params[:orderType] = order_type
23
+ end
24
+
25
+ return @client.call('get', path, {
26
+ 'content-type' => 'application/json',
27
+ }, params);
28
+ end
29
+
30
+ def create(name:, execute:, env:, vars: nil, events: nil, schedule: nil, timeout: nil)
31
+ if name.nil?
32
+ raise Appwrite::Exception.new('Missing required parameter: "name"')
33
+ end
34
+
35
+ if execute.nil?
36
+ raise Appwrite::Exception.new('Missing required parameter: "execute"')
37
+ end
38
+
39
+ if env.nil?
40
+ raise Appwrite::Exception.new('Missing required parameter: "env"')
41
+ end
42
+
43
+ path = '/functions'
44
+
45
+ params = {}
46
+
47
+ if !name.nil?
48
+ params[:name] = name
49
+ end
50
+
51
+ if !execute.nil?
52
+ params[:execute] = execute
53
+ end
54
+
55
+ if !env.nil?
56
+ params[:env] = env
57
+ end
58
+
59
+ if !vars.nil?
60
+ params[:vars] = vars
61
+ end
62
+
63
+ if !events.nil?
64
+ params[:events] = events
65
+ end
66
+
67
+ if !schedule.nil?
68
+ params[:schedule] = schedule
69
+ end
70
+
71
+ if !timeout.nil?
72
+ params[:timeout] = timeout
73
+ end
74
+
75
+ return @client.call('post', path, {
76
+ 'content-type' => 'application/json',
77
+ }, params);
78
+ end
79
+
80
+ def get(function_id:)
81
+ if function_id.nil?
82
+ raise Appwrite::Exception.new('Missing required parameter: "functionId"')
83
+ end
84
+
85
+ path = '/functions/{functionId}'
86
+ .gsub('{functionId}', function_id)
87
+
88
+ params = {}
89
+
90
+ return @client.call('get', path, {
91
+ 'content-type' => 'application/json',
92
+ }, params);
93
+ end
94
+
95
+ def update(function_id:, name:, execute:, vars: nil, events: nil, schedule: nil, timeout: nil)
96
+ if function_id.nil?
97
+ raise Appwrite::Exception.new('Missing required parameter: "functionId"')
98
+ end
99
+
100
+ if name.nil?
101
+ raise Appwrite::Exception.new('Missing required parameter: "name"')
102
+ end
103
+
104
+ if execute.nil?
105
+ raise Appwrite::Exception.new('Missing required parameter: "execute"')
106
+ end
107
+
108
+ path = '/functions/{functionId}'
109
+ .gsub('{functionId}', function_id)
110
+
111
+ params = {}
112
+
113
+ if !name.nil?
114
+ params[:name] = name
115
+ end
116
+
117
+ if !execute.nil?
118
+ params[:execute] = execute
119
+ end
120
+
121
+ if !vars.nil?
122
+ params[:vars] = vars
123
+ end
124
+
125
+ if !events.nil?
126
+ params[:events] = events
127
+ end
128
+
129
+ if !schedule.nil?
130
+ params[:schedule] = schedule
131
+ end
132
+
133
+ if !timeout.nil?
134
+ params[:timeout] = timeout
135
+ end
136
+
137
+ return @client.call('put', path, {
138
+ 'content-type' => 'application/json',
139
+ }, params);
140
+ end
141
+
142
+ def delete(function_id:)
143
+ if function_id.nil?
144
+ raise Appwrite::Exception.new('Missing required parameter: "functionId"')
145
+ end
146
+
147
+ path = '/functions/{functionId}'
148
+ .gsub('{functionId}', function_id)
149
+
150
+ params = {}
151
+
152
+ return @client.call('delete', path, {
153
+ 'content-type' => 'application/json',
154
+ }, params);
155
+ end
156
+
157
+ def list_executions(function_id:, search: nil, limit: nil, offset: nil, order_type: nil)
158
+ if function_id.nil?
159
+ raise Appwrite::Exception.new('Missing required parameter: "functionId"')
160
+ end
161
+
162
+ path = '/functions/{functionId}/executions'
163
+ .gsub('{functionId}', function_id)
164
+
165
+ params = {}
166
+
167
+ if !search.nil?
168
+ params[:search] = search
169
+ end
170
+
171
+ if !limit.nil?
172
+ params[:limit] = limit
173
+ end
174
+
175
+ if !offset.nil?
176
+ params[:offset] = offset
177
+ end
178
+
179
+ if !order_type.nil?
180
+ params[:orderType] = order_type
181
+ end
182
+
183
+ return @client.call('get', path, {
184
+ 'content-type' => 'application/json',
185
+ }, params);
186
+ end
187
+
188
+ def create_execution(function_id:, data: nil)
189
+ if function_id.nil?
190
+ raise Appwrite::Exception.new('Missing required parameter: "functionId"')
191
+ end
192
+
193
+ path = '/functions/{functionId}/executions'
194
+ .gsub('{functionId}', function_id)
195
+
196
+ params = {}
197
+
198
+ if !data.nil?
199
+ params[:data] = data
200
+ end
201
+
202
+ return @client.call('post', path, {
203
+ 'content-type' => 'application/json',
204
+ }, params);
205
+ end
206
+
207
+ def get_execution(function_id:, execution_id:)
208
+ if function_id.nil?
209
+ raise Appwrite::Exception.new('Missing required parameter: "functionId"')
210
+ end
211
+
212
+ if execution_id.nil?
213
+ raise Appwrite::Exception.new('Missing required parameter: "executionId"')
214
+ end
215
+
216
+ path = '/functions/{functionId}/executions/{executionId}'
217
+ .gsub('{functionId}', function_id)
218
+ .gsub('{executionId}', execution_id)
219
+
220
+ params = {}
221
+
222
+ return @client.call('get', path, {
223
+ 'content-type' => 'application/json',
224
+ }, params);
225
+ end
226
+
227
+ def update_tag(function_id:, tag:)
228
+ if function_id.nil?
229
+ raise Appwrite::Exception.new('Missing required parameter: "functionId"')
230
+ end
231
+
232
+ if tag.nil?
233
+ raise Appwrite::Exception.new('Missing required parameter: "tag"')
234
+ end
235
+
236
+ path = '/functions/{functionId}/tag'
237
+ .gsub('{functionId}', function_id)
238
+
239
+ params = {}
240
+
241
+ if !tag.nil?
242
+ params[:tag] = tag
243
+ end
244
+
245
+ return @client.call('patch', path, {
246
+ 'content-type' => 'application/json',
247
+ }, params);
248
+ end
249
+
250
+ def list_tags(function_id:, search: nil, limit: nil, offset: nil, order_type: nil)
251
+ if function_id.nil?
252
+ raise Appwrite::Exception.new('Missing required parameter: "functionId"')
253
+ end
254
+
255
+ path = '/functions/{functionId}/tags'
256
+ .gsub('{functionId}', function_id)
257
+
258
+ params = {}
259
+
260
+ if !search.nil?
261
+ params[:search] = search
262
+ end
263
+
264
+ if !limit.nil?
265
+ params[:limit] = limit
266
+ end
267
+
268
+ if !offset.nil?
269
+ params[:offset] = offset
270
+ end
271
+
272
+ if !order_type.nil?
273
+ params[:orderType] = order_type
274
+ end
275
+
276
+ return @client.call('get', path, {
277
+ 'content-type' => 'application/json',
278
+ }, params);
279
+ end
280
+
281
+ def create_tag(function_id:, command:, code:)
282
+ if function_id.nil?
283
+ raise Appwrite::Exception.new('Missing required parameter: "functionId"')
284
+ end
285
+
286
+ if command.nil?
287
+ raise Appwrite::Exception.new('Missing required parameter: "command"')
288
+ end
289
+
290
+ if code.nil?
291
+ raise Appwrite::Exception.new('Missing required parameter: "code"')
292
+ end
293
+
294
+ path = '/functions/{functionId}/tags'
295
+ .gsub('{functionId}', function_id)
296
+
297
+ params = {}
298
+
299
+ if !command.nil?
300
+ params[:command] = command
301
+ end
302
+
303
+ if !code.nil?
304
+ params[:code] = code
305
+ end
306
+
307
+ return @client.call('post', path, {
308
+ 'content-type' => 'multipart/form-data',
309
+ }, params);
310
+ end
311
+
312
+ def get_tag(function_id:, tag_id:)
313
+ if function_id.nil?
314
+ raise Appwrite::Exception.new('Missing required parameter: "functionId"')
315
+ end
316
+
317
+ if tag_id.nil?
318
+ raise Appwrite::Exception.new('Missing required parameter: "tagId"')
319
+ end
320
+
321
+ path = '/functions/{functionId}/tags/{tagId}'
322
+ .gsub('{functionId}', function_id)
323
+ .gsub('{tagId}', tag_id)
324
+
325
+ params = {}
326
+
327
+ return @client.call('get', path, {
328
+ 'content-type' => 'application/json',
329
+ }, params);
330
+ end
331
+
332
+ def delete_tag(function_id:, tag_id:)
333
+ if function_id.nil?
334
+ raise Appwrite::Exception.new('Missing required parameter: "functionId"')
335
+ end
336
+
337
+ if tag_id.nil?
338
+ raise Appwrite::Exception.new('Missing required parameter: "tagId"')
339
+ end
340
+
341
+ path = '/functions/{functionId}/tags/{tagId}'
342
+ .gsub('{functionId}', function_id)
343
+ .gsub('{tagId}', tag_id)
344
+
345
+ params = {}
346
+
347
+ return @client.call('delete', path, {
348
+ 'content-type' => 'application/json',
349
+ }, params);
350
+ end
351
+
352
+
353
+ protected
354
+
355
+ private
356
+ end
357
+ end