@stacksjs/ts-cloud 0.2.3 → 0.2.6

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.
Files changed (76) hide show
  1. package/dist/aws/acm.d.ts +215 -0
  2. package/dist/aws/application-autoscaling.d.ts +345 -0
  3. package/dist/aws/bedrock.d.ts +2672 -0
  4. package/dist/aws/client.d.ts +181 -0
  5. package/dist/aws/cloudformation.d.ts +187 -0
  6. package/dist/aws/cloudfront.d.ts +416 -0
  7. package/dist/aws/cloudwatch-logs.d.ts +70 -0
  8. package/dist/aws/comprehend.d.ts +616 -0
  9. package/dist/aws/connect.d.ts +533 -0
  10. package/dist/aws/deploy-imap.d.ts +26 -0
  11. package/dist/aws/dynamodb.d.ts +270 -0
  12. package/dist/aws/ec2.d.ts +545 -0
  13. package/dist/aws/ecr.d.ts +240 -0
  14. package/dist/aws/ecs.d.ts +267 -0
  15. package/dist/aws/efs.d.ts +36 -0
  16. package/dist/aws/elasticache.d.ts +112 -0
  17. package/dist/aws/elbv2.d.ts +389 -0
  18. package/dist/aws/email.d.ts +260 -0
  19. package/dist/aws/eventbridge.d.ts +197 -0
  20. package/dist/aws/iam.d.ts +1013 -0
  21. package/dist/aws/imap-server.d.ts +298 -0
  22. package/dist/aws/index.d.ts +53 -0
  23. package/dist/aws/kendra.d.ts +831 -0
  24. package/dist/aws/lambda.d.ts +319 -0
  25. package/dist/aws/opensearch.d.ts +121 -0
  26. package/dist/aws/personalize.d.ts +586 -0
  27. package/dist/aws/polly.d.ts +243 -0
  28. package/dist/aws/rds.d.ts +346 -0
  29. package/dist/aws/rekognition.d.ts +691 -0
  30. package/dist/aws/route53-domains.d.ts +161 -0
  31. package/dist/aws/route53.d.ts +330 -0
  32. package/dist/aws/s3.d.ts +535 -0
  33. package/dist/aws/scheduler.d.ts +224 -0
  34. package/dist/aws/secrets-manager.d.ts +267 -0
  35. package/dist/aws/ses.d.ts +441 -0
  36. package/dist/aws/setup-phone.d.ts +1 -0
  37. package/dist/aws/setup-sms.d.ts +116 -0
  38. package/dist/aws/sms.d.ts +477 -0
  39. package/dist/aws/smtp-server.d.ts +108 -0
  40. package/dist/aws/sns.d.ts +224 -0
  41. package/dist/aws/sqs.d.ts +107 -0
  42. package/dist/aws/ssm.d.ts +311 -0
  43. package/dist/aws/sts.d.ts +21 -0
  44. package/dist/aws/support.d.ts +139 -0
  45. package/dist/aws/test-imap.d.ts +15 -0
  46. package/dist/aws/textract.d.ts +477 -0
  47. package/dist/aws/transcribe.d.ts +79 -0
  48. package/dist/aws/translate.d.ts +424 -0
  49. package/dist/aws/voice.d.ts +361 -0
  50. package/dist/bin/cli.js +4480 -804
  51. package/dist/config.d.ts +5 -0
  52. package/dist/deploy/index.d.ts +6 -0
  53. package/dist/deploy/static-site-external-dns.d.ts +70 -0
  54. package/dist/deploy/static-site.d.ts +110 -0
  55. package/dist/dns/cloudflare.d.ts +74 -0
  56. package/dist/dns/godaddy.d.ts +63 -0
  57. package/dist/dns/index.d.ts +67 -0
  58. package/dist/dns/porkbun.d.ts +43 -0
  59. package/dist/dns/route53-adapter.d.ts +67 -0
  60. package/dist/dns/types.d.ts +100 -0
  61. package/dist/dns/validator.d.ts +105 -0
  62. package/dist/generators/index.d.ts +4 -0
  63. package/dist/generators/infrastructure.d.ts +115 -0
  64. package/dist/index.d.ts +9 -165
  65. package/dist/index.js +4971 -6013
  66. package/dist/push/apns.d.ts +140 -0
  67. package/dist/push/fcm.d.ts +205 -0
  68. package/dist/push/index.d.ts +44 -0
  69. package/dist/security/pre-deploy-scanner.d.ts +97 -0
  70. package/dist/ssl/acme-client.d.ts +133 -0
  71. package/dist/ssl/index.d.ts +6 -0
  72. package/dist/ssl/letsencrypt.d.ts +96 -0
  73. package/dist/utils/cli.d.ts +121 -0
  74. package/dist/validation/index.d.ts +4 -0
  75. package/dist/validation/template.d.ts +27 -0
  76. package/package.json +6 -6
@@ -0,0 +1,477 @@
1
+ /**
2
+ * Unified SMS Module
3
+ * Provides SMS sending and receiving with S3 storage for incoming messages
4
+ *
5
+ * Similar to the Email module, this provides:
6
+ * - Sending SMS via SNS
7
+ * - Receiving SMS stored in S3
8
+ * - Inbox management (list, read, delete)
9
+ * - Two-way messaging support
10
+ */
11
+ export interface SmsClientConfig {
12
+ region?: string;
13
+ inboxBucket?: string;
14
+ inboxPrefix?: string;
15
+ defaultSender?: string;
16
+ schedulerLambdaArn?: string;
17
+ schedulerRoleArn?: string;
18
+ scheduledBucket?: string;
19
+ scheduledPrefix?: string;
20
+ receiptBucket?: string;
21
+ receiptPrefix?: string;
22
+ trackDelivery?: boolean;
23
+ }
24
+ export interface SmsMessage {
25
+ key: string;
26
+ from: string;
27
+ to: string;
28
+ body: string;
29
+ timestamp: Date;
30
+ messageId?: string;
31
+ originationNumber?: string;
32
+ destinationNumber?: string;
33
+ read?: boolean;
34
+ readAt?: Date;
35
+ conversationId?: string;
36
+ status?: 'pending' | 'sent' | 'delivered' | 'failed';
37
+ deliveredAt?: Date;
38
+ raw?: any;
39
+ }
40
+ export interface SendSmsOptions {
41
+ to: string;
42
+ body: string;
43
+ from?: string;
44
+ type?: 'Promotional' | 'Transactional';
45
+ scheduledAt?: Date;
46
+ templateId?: string;
47
+ templateVariables?: Record<string, string>;
48
+ }
49
+ export interface ScheduledSms {
50
+ id: string;
51
+ to: string;
52
+ body: string;
53
+ from?: string;
54
+ scheduledAt: Date;
55
+ status: 'pending' | 'sent' | 'failed' | 'cancelled';
56
+ createdAt: Date;
57
+ sentAt?: Date;
58
+ messageId?: string;
59
+ error?: string;
60
+ templateId?: string;
61
+ templateVariables?: Record<string, string>;
62
+ }
63
+ export interface SmsTemplate {
64
+ id: string;
65
+ name: string;
66
+ body: string;
67
+ description?: string;
68
+ variables?: string[];
69
+ createdAt: Date;
70
+ updatedAt?: Date;
71
+ }
72
+ export interface InboxOptions {
73
+ prefix?: string;
74
+ maxResults?: number;
75
+ startAfter?: string;
76
+ }
77
+ export interface DeliveryReceipt {
78
+ messageId: string;
79
+ status: 'pending' | 'sent' | 'delivered' | 'failed' | 'unknown';
80
+ timestamp: Date;
81
+ to: string;
82
+ from?: string;
83
+ errorCode?: string;
84
+ errorMessage?: string;
85
+ carrierName?: string;
86
+ priceInUsd?: number;
87
+ messagePartCount?: number;
88
+ raw?: any;
89
+ }
90
+ export interface DeliveryReceiptWebhookConfig {
91
+ snsTopicArn?: string;
92
+ receiptBucket?: string;
93
+ receiptPrefix?: string;
94
+ webhookUrl?: string;
95
+ webhookSecret?: string;
96
+ }
97
+ /**
98
+ * SMS Client with S3 inbox storage
99
+ */
100
+ export declare class SmsClient {
101
+ private config;
102
+ private sns;
103
+ private s3?;
104
+ private scheduler?;
105
+ constructor(config?: SmsClientConfig);
106
+ /**
107
+ * Send an SMS message (optionally scheduled)
108
+ */
109
+ send(options: SendSmsOptions): Promise<{
110
+ messageId: string;
111
+ scheduledId?: string;
112
+ }>;
113
+ /**
114
+ * Send a text message (alias for send)
115
+ */
116
+ sendText(to: string, message: string, from?: string): Promise<{
117
+ messageId: string;
118
+ }>;
119
+ /**
120
+ * Get incoming SMS messages from S3 inbox
121
+ */
122
+ getInbox(options?: InboxOptions): Promise<SmsMessage[]>;
123
+ /**
124
+ * Get a specific SMS message by key
125
+ */
126
+ getMessage(key: string): Promise<SmsMessage | null>;
127
+ /**
128
+ * Delete an SMS message from inbox
129
+ */
130
+ deleteMessage(key: string): Promise<void>;
131
+ /**
132
+ * Move an SMS to a different folder (e.g., archive)
133
+ */
134
+ moveMessage(key: string, destinationPrefix: string): Promise<string>;
135
+ /**
136
+ * Archive an SMS message
137
+ */
138
+ archiveMessage(key: string): Promise<string>;
139
+ /**
140
+ * Mark a message as read
141
+ */
142
+ markAsRead(key: string): Promise<void>;
143
+ /**
144
+ * Mark a message as unread
145
+ */
146
+ markAsUnread(key: string): Promise<void>;
147
+ /**
148
+ * Get unread message count
149
+ */
150
+ getUnreadCount(): Promise<number>;
151
+ /**
152
+ * Batch mark messages as read
153
+ */
154
+ markManyAsRead(keys: string[]): Promise<void>;
155
+ /**
156
+ * Batch delete messages
157
+ */
158
+ deleteMany(keys: string[]): Promise<void>;
159
+ /**
160
+ * Get inbox count
161
+ */
162
+ getInboxCount(): Promise<number>;
163
+ /**
164
+ * Get conversation ID for a phone number pair
165
+ * Normalizes phone numbers and creates a consistent ID
166
+ */
167
+ getConversationId(phone1: string, phone2: string): string;
168
+ /**
169
+ * Get all messages in a conversation with a specific phone number
170
+ */
171
+ getConversation(phoneNumber: string, myNumber?: string): Promise<SmsMessage[]>;
172
+ /**
173
+ * Get unique conversations (grouped by contact)
174
+ */
175
+ getConversations(): Promise<Array<{
176
+ phoneNumber: string;
177
+ lastMessage: SmsMessage;
178
+ messageCount: number;
179
+ unreadCount: number;
180
+ }>>;
181
+ /**
182
+ * Store an incoming SMS to S3
183
+ * This is typically called from a Lambda handler that receives SNS webhooks
184
+ */
185
+ storeIncomingSms(message: {
186
+ from: string;
187
+ to: string;
188
+ body: string;
189
+ messageId?: string;
190
+ timestamp?: Date;
191
+ raw?: any;
192
+ }): Promise<string>;
193
+ /**
194
+ * Check if a phone number is opted out
195
+ */
196
+ isOptedOut(phoneNumber: string): Promise<boolean>;
197
+ /**
198
+ * Get list of opted-out phone numbers
199
+ */
200
+ getOptedOutNumbers(): Promise<string[]>;
201
+ /**
202
+ * Opt a phone number back in (requires user consent)
203
+ */
204
+ optIn(phoneNumber: string): Promise<void>;
205
+ /**
206
+ * Check if account is in SMS sandbox
207
+ */
208
+ isInSandbox(): Promise<boolean>;
209
+ /**
210
+ * Add a phone number to SMS sandbox for testing
211
+ */
212
+ addSandboxNumber(phoneNumber: string): Promise<void>;
213
+ /**
214
+ * Verify a sandbox phone number with OTP
215
+ */
216
+ verifySandboxNumber(phoneNumber: string, otp: string): Promise<void>;
217
+ /**
218
+ * List sandbox phone numbers
219
+ */
220
+ listSandboxNumbers(): Promise<Array<{
221
+ PhoneNumber: string;
222
+ Status: string;
223
+ }>>;
224
+ /**
225
+ * Schedule an SMS message for later delivery
226
+ */
227
+ scheduleMessage(options: {
228
+ to: string;
229
+ body: string;
230
+ from?: string;
231
+ scheduledAt: Date;
232
+ templateId?: string;
233
+ templateVariables?: Record<string, string>;
234
+ }): Promise<ScheduledSms>;
235
+ /**
236
+ * Get all scheduled SMS messages
237
+ */
238
+ getScheduledMessages(): Promise<ScheduledSms[]>;
239
+ /**
240
+ * Get a scheduled SMS by ID
241
+ */
242
+ getScheduledMessage(id: string): Promise<ScheduledSms | null>;
243
+ /**
244
+ * Cancel a scheduled SMS
245
+ */
246
+ cancelScheduledMessage(id: string): Promise<void>;
247
+ /**
248
+ * Send a scheduled SMS immediately (called by Lambda handler)
249
+ */
250
+ sendScheduledMessage(id: string): Promise<{
251
+ messageId: string;
252
+ }>;
253
+ /**
254
+ * Schedule SMS to send at a specific time (convenience method)
255
+ */
256
+ sendAt(to: string, body: string, scheduledAt: Date, from?: string): Promise<ScheduledSms>;
257
+ /**
258
+ * Schedule SMS to send after a delay (convenience method)
259
+ */
260
+ sendAfter(to: string, body: string, delayMinutes: number, from?: string): Promise<ScheduledSms>;
261
+ /**
262
+ * Create an SMS template
263
+ */
264
+ createTemplate(template: {
265
+ name: string;
266
+ body: string;
267
+ description?: string;
268
+ }): Promise<SmsTemplate>;
269
+ /**
270
+ * Get all SMS templates
271
+ */
272
+ getTemplates(): Promise<SmsTemplate[]>;
273
+ /**
274
+ * Get a template by ID
275
+ */
276
+ getTemplate(id: string): Promise<SmsTemplate | null>;
277
+ /**
278
+ * Get a template by name
279
+ */
280
+ getTemplateByName(name: string): Promise<SmsTemplate | null>;
281
+ /**
282
+ * Update a template
283
+ */
284
+ updateTemplate(id: string, updates: {
285
+ name?: string;
286
+ body?: string;
287
+ description?: string;
288
+ }): Promise<SmsTemplate>;
289
+ /**
290
+ * Delete a template
291
+ */
292
+ deleteTemplate(id: string): Promise<void>;
293
+ /**
294
+ * Send using a template
295
+ */
296
+ sendTemplate(to: string, templateId: string, variables: Record<string, string>, from?: string): Promise<{
297
+ messageId: string;
298
+ }>;
299
+ /**
300
+ * Apply variables to a template string
301
+ */
302
+ private applyTemplate;
303
+ /**
304
+ * Store a delivery receipt
305
+ * Called by the Lambda handler when a delivery status notification is received
306
+ */
307
+ storeDeliveryReceipt(receipt: {
308
+ messageId: string;
309
+ status: DeliveryReceipt['status'];
310
+ to: string;
311
+ from?: string;
312
+ errorCode?: string;
313
+ errorMessage?: string;
314
+ carrierName?: string;
315
+ priceInUsd?: number;
316
+ messagePartCount?: number;
317
+ timestamp?: Date;
318
+ raw?: any;
319
+ }): Promise<string>;
320
+ /**
321
+ * Get delivery receipt for a message
322
+ */
323
+ getDeliveryReceipt(messageId: string): Promise<DeliveryReceipt | null>;
324
+ /**
325
+ * Get all delivery receipts (recent)
326
+ */
327
+ getDeliveryReceipts(options?: {
328
+ maxResults?: number;
329
+ status?: DeliveryReceipt['status'];
330
+ }): Promise<DeliveryReceipt[]>;
331
+ /**
332
+ * Get delivery status for a message
333
+ */
334
+ getDeliveryStatus(messageId: string): Promise<DeliveryReceipt['status']>;
335
+ /**
336
+ * Wait for delivery confirmation (polling)
337
+ */
338
+ waitForDelivery(messageId: string, options?: {
339
+ timeoutMs?: number;
340
+ pollIntervalMs?: number;
341
+ }): Promise<DeliveryReceipt | null>;
342
+ /**
343
+ * Get failed message receipts
344
+ */
345
+ getFailedMessages(maxResults?: number): Promise<DeliveryReceipt[]>;
346
+ /**
347
+ * Get delivery statistics
348
+ */
349
+ getDeliveryStats(options?: {
350
+ since?: Date;
351
+ maxMessages?: number;
352
+ }): Promise<{
353
+ total: number;
354
+ delivered: number;
355
+ failed: number;
356
+ pending: number;
357
+ deliveryRate: number;
358
+ averagePriceUsd: number;
359
+ }>;
360
+ /**
361
+ * Send SMS and track delivery
362
+ * Combines send() with delivery tracking
363
+ */
364
+ sendAndTrack(options: SendSmsOptions): Promise<{
365
+ messageId: string;
366
+ trackDelivery: () => Promise<DeliveryReceipt | null>;
367
+ waitForDelivery: (timeoutMs?: number) => Promise<DeliveryReceipt | null>;
368
+ }>;
369
+ /**
370
+ * Parse incoming SMS from various formats (SNS notification, raw JSON)
371
+ */
372
+ private parseIncomingSms;
373
+ /**
374
+ * Extract SMS fields from various data formats
375
+ */
376
+ private extractSmsFields;
377
+ }
378
+ /**
379
+ * Create a Lambda handler for processing incoming SMS from SNS
380
+ * Use this with an SNS topic that receives two-way SMS messages
381
+ *
382
+ * @example
383
+ * ```typescript
384
+ * // lambda.ts
385
+ * import { createSmsInboxHandler } from 'ts-cloud/aws/sms'
386
+ *
387
+ * export const handler = createSmsInboxHandler({
388
+ * bucket: 'my-sms-bucket',
389
+ * prefix: 'sms/inbox/',
390
+ * region: 'us-east-1',
391
+ * })
392
+ * ```
393
+ */
394
+ export declare function createSmsInboxHandler(config: {
395
+ bucket: string;
396
+ prefix?: string;
397
+ region?: string;
398
+ onMessage?: (message: SmsMessage) => Promise<void>;
399
+ }): (event: any) => Promise<any>;
400
+ /**
401
+ * Create a Lambda handler for sending scheduled SMS messages
402
+ * This is invoked by EventBridge Scheduler at the scheduled time
403
+ *
404
+ * @example
405
+ * ```typescript
406
+ * // lambda.ts
407
+ * import { createScheduledSmsHandler } from 'ts-cloud/aws/sms'
408
+ *
409
+ * export const handler = createScheduledSmsHandler({
410
+ * bucket: 'my-sms-bucket',
411
+ * region: 'us-east-1',
412
+ * })
413
+ * ```
414
+ */
415
+ export declare function createScheduledSmsHandler(config: {
416
+ bucket: string;
417
+ scheduledPrefix?: string;
418
+ region?: string;
419
+ onSent?: (sms: ScheduledSms) => Promise<void>;
420
+ onError?: (sms: ScheduledSms, error: Error) => Promise<void>;
421
+ }): (event: any) => Promise<any>;
422
+ /**
423
+ * Convenience function to create an SMS client
424
+ */
425
+ export declare function createSmsClient(config?: SmsClientConfig): SmsClient;
426
+ /**
427
+ * Create a Lambda handler for processing SMS delivery receipts
428
+ * This handles SNS notifications for SMS delivery status events
429
+ *
430
+ * @example
431
+ * ```typescript
432
+ * // lambda.ts
433
+ * import { createDeliveryReceiptHandler } from 'ts-cloud/aws/sms'
434
+ *
435
+ * export const handler = createDeliveryReceiptHandler({
436
+ * bucket: 'my-sms-bucket',
437
+ * region: 'us-east-1',
438
+ * onDelivered: async (receipt) => {
439
+ * console.log(`SMS ${receipt.messageId} delivered to ${receipt.to}`)
440
+ * },
441
+ * onFailed: async (receipt) => {
442
+ * console.error(`SMS ${receipt.messageId} failed: ${receipt.errorMessage}`)
443
+ * },
444
+ * })
445
+ * ```
446
+ */
447
+ export declare function createDeliveryReceiptHandler(config: {
448
+ bucket: string;
449
+ receiptPrefix?: string;
450
+ region?: string;
451
+ onDelivered?: (receipt: DeliveryReceipt) => Promise<void>;
452
+ onFailed?: (receipt: DeliveryReceipt) => Promise<void>;
453
+ onReceipt?: (receipt: DeliveryReceipt) => Promise<void>;
454
+ webhookUrl?: string;
455
+ webhookSecret?: string;
456
+ }): (event: any) => Promise<any>;
457
+ /**
458
+ * Normalize a phone number to E.164 format
459
+ * Removes all non-numeric characters except leading +
460
+ */
461
+ export declare function normalizePhoneNumber(phone: string): string;
462
+ /**
463
+ * Format a phone number for display
464
+ */
465
+ export declare function formatPhoneNumber(phone: string, format?: 'national' | 'international' | 'e164'): string;
466
+ /**
467
+ * Validate a phone number
468
+ */
469
+ export declare function isValidPhoneNumber(phone: string): boolean;
470
+ /**
471
+ * Get the country code from a phone number
472
+ */
473
+ export declare function getCountryCode(phone: string): string | null;
474
+ /**
475
+ * Check if two phone numbers are the same (ignoring formatting)
476
+ */
477
+ export declare function isSamePhoneNumber(phone1: string, phone2: string): boolean;
@@ -0,0 +1,108 @@
1
+ /**
2
+ * SMTP Relay Server
3
+ * Provides SMTP access with user-friendly credentials that relays to AWS SES
4
+ *
5
+ * This allows email clients like Mail.app to send emails using:
6
+ * - Server: mail.yourdomain.com
7
+ * - Username: chris (or chris@yourdomain.com)
8
+ * - Password: your-password
9
+ *
10
+ * Instead of the unfriendly AWS SES SMTP credentials.
11
+ */
12
+ export interface SmtpServerConfig {
13
+ port?: number;
14
+ tlsPort?: number;
15
+ host?: string;
16
+ region?: string;
17
+ domain: string;
18
+ users: Record<string, {
19
+ password: string;
20
+ email: string;
21
+ }>;
22
+ tls?: {
23
+ key: string;
24
+ cert: string;
25
+ };
26
+ sentBucket?: string;
27
+ sentPrefix?: string;
28
+ }
29
+ /**
30
+ * SMTP Server that relays emails through AWS SES
31
+ */
32
+ export declare class SmtpServer {
33
+ private config;
34
+ private ses;
35
+ private s3?;
36
+ private server?;
37
+ private tlsServer?;
38
+ private sessions;
39
+ constructor(config: SmtpServerConfig);
40
+ /**
41
+ * Start the SMTP server
42
+ */
43
+ start(): Promise<void>;
44
+ /**
45
+ * Stop the SMTP server
46
+ */
47
+ stop(): Promise<void>;
48
+ /**
49
+ * Handle a new connection
50
+ */
51
+ private handleConnection;
52
+ /**
53
+ * Send a response to the client
54
+ */
55
+ private send;
56
+ /**
57
+ * Handle an SMTP command
58
+ */
59
+ private handleCommand;
60
+ /**
61
+ * Handle EHLO/HELO command
62
+ */
63
+ private handleEhlo;
64
+ /**
65
+ * Handle STARTTLS command
66
+ */
67
+ private handleStartTls;
68
+ /**
69
+ * Handle AUTH command
70
+ */
71
+ private handleAuth;
72
+ /**
73
+ * Handle AUTH PLAIN credentials
74
+ */
75
+ private handleAuthPlain;
76
+ /**
77
+ * Authenticate a user
78
+ */
79
+ private authenticateUser;
80
+ /**
81
+ * Handle MAIL FROM command
82
+ */
83
+ private handleMailFrom;
84
+ /**
85
+ * Handle RCPT TO command
86
+ */
87
+ private handleRcptTo;
88
+ /**
89
+ * Handle DATA command
90
+ */
91
+ private handleData;
92
+ /**
93
+ * Handle a line during DATA phase
94
+ */
95
+ private handleDataLine;
96
+ /**
97
+ * Send the email via SES
98
+ */
99
+ private sendEmail;
100
+ /**
101
+ * Reset session state for next message
102
+ */
103
+ private resetSession;
104
+ }
105
+ /**
106
+ * Start an SMTP server with the given configuration
107
+ */
108
+ export declare function startSmtpServer(config: SmtpServerConfig): Promise<SmtpServer>;