@r2wa-org/eden 0.0.65 → 0.0.67

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.
@@ -0,0 +1,2 @@
1
+ export declare const ASSET_PRICE_MAIN_ANCHOR_ASSET: "CNY";
2
+ export declare const ASSET_PRICE_DEFAULT_SOURCE: "ADMIN_PANEL";
@@ -2,6 +2,7 @@ export * from "./locales/zh";
2
2
  export declare const AssetPriceErrorCodes: {
3
3
  readonly ASSET_PRICE_BASE_ASSET_REQUIRED: "ASSET_PRICE_BASE_ASSET_REQUIRED";
4
4
  readonly ASSET_PRICE_QUOTE_ASSET_REQUIRED: "ASSET_PRICE_QUOTE_ASSET_REQUIRED";
5
+ readonly ASSET_PRICE_QUOTE_ASSET_MUST_BE_CNY: "ASSET_PRICE_QUOTE_ASSET_MUST_BE_CNY";
5
6
  readonly ASSET_PRICE_ASSET_NOT_FOUND: "ASSET_PRICE_ASSET_NOT_FOUND";
6
7
  readonly ASSET_PRICE_PAIR_INVALID: "ASSET_PRICE_PAIR_INVALID";
7
8
  readonly ASSET_PRICE_VALUE_INVALID: "ASSET_PRICE_VALUE_INVALID";
@@ -1,6 +1,7 @@
1
1
  export declare const zh: {
2
2
  ASSET_PRICE_BASE_ASSET_REQUIRED: string;
3
3
  ASSET_PRICE_QUOTE_ASSET_REQUIRED: string;
4
+ ASSET_PRICE_QUOTE_ASSET_MUST_BE_CNY: string;
4
5
  ASSET_PRICE_ASSET_NOT_FOUND: string;
5
6
  ASSET_PRICE_PAIR_INVALID: string;
6
7
  ASSET_PRICE_VALUE_INVALID: string;
@@ -1,5 +1,6 @@
1
1
  export * from "./admin/dto.schemas";
2
2
  export * from "./admin/service";
3
+ export * from "./constants";
3
4
  export * from "./db.schemas";
4
5
  export * from "./errors";
5
6
  export * from "./internal/service";
@@ -1,45 +1,5 @@
1
- import type { AssetPriceAdminCreateInputType, AssetPriceAdminListQueryType } from "../admin/dto.schemas";
2
- declare abstract class BaseAssetPriceService {
3
- protected static isUniqueViolationError(error: unknown): boolean;
4
- protected static normalizeBaseAsset(baseAsset: string): string;
5
- protected static normalizeQuoteAsset(quoteAsset: string): string;
6
- protected static validatePair(baseAsset: string, quoteAsset: string): void;
7
- protected static getActiveAssetByCode(code: string): Promise<{
8
- id: string;
9
- code: string;
10
- }>;
11
- protected static validatePrice(price: string): string;
12
- protected static buildWhere(query?: AssetPriceAdminListQueryType): import("drizzle-orm").SQL<unknown> | undefined;
13
- }
14
- export declare abstract class InternalAssetPriceService extends BaseAssetPriceService {
15
- static getLatestPrice(baseAsset: string, quoteAsset: string): Promise<{
16
- id: string;
17
- createdAt: Date;
18
- updatedAt: Date;
19
- baseAssetId: string;
20
- baseAsset: string;
21
- quoteAssetId: string;
22
- quoteAsset: string;
23
- price: string;
24
- source: string;
25
- effectiveAt: Date;
26
- }>;
27
- static listPrices(query?: AssetPriceAdminListQueryType): Promise<{
28
- items: {
29
- id: string;
30
- createdAt: Date;
31
- updatedAt: Date;
32
- baseAssetId: string;
33
- baseAsset: string;
34
- quoteAssetId: string;
35
- quoteAsset: string;
36
- price: string;
37
- source: string;
38
- effectiveAt: Date;
39
- }[];
40
- total: number;
41
- }>;
42
- static createPrice(input: AssetPriceAdminCreateInputType): Promise<{
1
+ export declare abstract class InternalAssetPriceService {
2
+ static getLatestPrice(baseAsset: string): Promise<{
43
3
  id: string;
44
4
  createdAt: Date;
45
5
  updatedAt: Date;
@@ -52,4 +12,3 @@ export declare abstract class InternalAssetPriceService extends BaseAssetPriceSe
52
12
  effectiveAt: Date;
53
13
  }>;
54
14
  }
55
- export {};
@@ -1,181 +1,13 @@
1
- export declare const assetPriceUserResponseSchema: import("drizzle-typebox").BuildSchema<"select", {
2
- createdAt: import("drizzle-orm/pg-core").PgColumn<{
3
- name: "created_at";
4
- tableName: "asset_price";
5
- dataType: "date";
6
- columnType: "PgTimestamp";
7
- data: Date;
8
- driverParam: string;
9
- notNull: true;
10
- hasDefault: true;
11
- isPrimaryKey: false;
12
- isAutoincrement: false;
13
- hasRuntimeDefault: false;
14
- enumValues: undefined;
15
- baseColumn: never;
16
- identity: undefined;
17
- generated: undefined;
18
- }, {}, {}>;
19
- updatedAt: import("drizzle-orm/pg-core").PgColumn<{
20
- name: "updated_at";
21
- tableName: "asset_price";
22
- dataType: "date";
23
- columnType: "PgTimestamp";
24
- data: Date;
25
- driverParam: string;
26
- notNull: true;
27
- hasDefault: true;
28
- isPrimaryKey: false;
29
- isAutoincrement: false;
30
- hasRuntimeDefault: false;
31
- enumValues: undefined;
32
- baseColumn: never;
33
- identity: undefined;
34
- generated: undefined;
35
- }, {}, {}>;
36
- id: import("drizzle-orm/pg-core").PgColumn<{
37
- name: "id";
38
- tableName: "asset_price";
39
- dataType: "string";
40
- columnType: "PgUUID";
41
- data: string;
42
- driverParam: string;
43
- notNull: true;
44
- hasDefault: true;
45
- isPrimaryKey: true;
46
- isAutoincrement: false;
47
- hasRuntimeDefault: false;
48
- enumValues: undefined;
49
- baseColumn: never;
50
- identity: undefined;
51
- generated: undefined;
52
- }, {}, {}>;
53
- baseAssetId: import("drizzle-orm/pg-core").PgColumn<{
54
- name: "base_asset_id";
55
- tableName: "asset_price";
56
- dataType: "string";
57
- columnType: "PgUUID";
58
- data: string;
59
- driverParam: string;
60
- notNull: true;
61
- hasDefault: false;
62
- isPrimaryKey: false;
63
- isAutoincrement: false;
64
- hasRuntimeDefault: false;
65
- enumValues: undefined;
66
- baseColumn: never;
67
- identity: undefined;
68
- generated: undefined;
69
- }, {}, {}>;
70
- baseAsset: import("drizzle-orm/pg-core").PgColumn<{
71
- name: "base_asset";
72
- tableName: "asset_price";
73
- dataType: "string";
74
- columnType: "PgVarchar";
75
- data: string;
76
- driverParam: string;
77
- notNull: true;
78
- hasDefault: false;
79
- isPrimaryKey: false;
80
- isAutoincrement: false;
81
- hasRuntimeDefault: false;
82
- enumValues: [string, ...string[]];
83
- baseColumn: never;
84
- identity: undefined;
85
- generated: undefined;
86
- }, {}, {
87
- length: 32;
88
- }>;
89
- quoteAssetId: import("drizzle-orm/pg-core").PgColumn<{
90
- name: "quote_asset_id";
91
- tableName: "asset_price";
92
- dataType: "string";
93
- columnType: "PgUUID";
94
- data: string;
95
- driverParam: string;
96
- notNull: true;
97
- hasDefault: false;
98
- isPrimaryKey: false;
99
- isAutoincrement: false;
100
- hasRuntimeDefault: false;
101
- enumValues: undefined;
102
- baseColumn: never;
103
- identity: undefined;
104
- generated: undefined;
105
- }, {}, {}>;
106
- quoteAsset: import("drizzle-orm/pg-core").PgColumn<{
107
- name: "quote_asset";
108
- tableName: "asset_price";
109
- dataType: "string";
110
- columnType: "PgVarchar";
111
- data: string;
112
- driverParam: string;
113
- notNull: true;
114
- hasDefault: false;
115
- isPrimaryKey: false;
116
- isAutoincrement: false;
117
- hasRuntimeDefault: false;
118
- enumValues: [string, ...string[]];
119
- baseColumn: never;
120
- identity: undefined;
121
- generated: undefined;
122
- }, {}, {
123
- length: 32;
124
- }>;
125
- price: import("drizzle-orm/pg-core").PgColumn<{
126
- name: "price";
127
- tableName: "asset_price";
128
- dataType: "string";
129
- columnType: "PgNumeric";
130
- data: string;
131
- driverParam: string;
132
- notNull: true;
133
- hasDefault: false;
134
- isPrimaryKey: false;
135
- isAutoincrement: false;
136
- hasRuntimeDefault: false;
137
- enumValues: undefined;
138
- baseColumn: never;
139
- identity: undefined;
140
- generated: undefined;
141
- }, {}, {}>;
142
- source: import("drizzle-orm/pg-core").PgColumn<{
143
- name: "source";
144
- tableName: "asset_price";
145
- dataType: "string";
146
- columnType: "PgVarchar";
147
- data: string;
148
- driverParam: string;
149
- notNull: true;
150
- hasDefault: false;
151
- isPrimaryKey: false;
152
- isAutoincrement: false;
153
- hasRuntimeDefault: false;
154
- enumValues: [string, ...string[]];
155
- baseColumn: never;
156
- identity: undefined;
157
- generated: undefined;
158
- }, {}, {
159
- length: 64;
160
- }>;
161
- effectiveAt: import("drizzle-orm/pg-core").PgColumn<{
162
- name: "effective_at";
163
- tableName: "asset_price";
164
- dataType: "date";
165
- columnType: "PgTimestamp";
166
- data: Date;
167
- driverParam: string;
168
- notNull: true;
169
- hasDefault: false;
170
- isPrimaryKey: false;
171
- isAutoincrement: false;
172
- hasRuntimeDefault: false;
173
- enumValues: undefined;
174
- baseColumn: never;
175
- identity: undefined;
176
- generated: undefined;
177
- }, {}, {}>;
178
- }, undefined>;
1
+ export declare const assetPriceUserResponseSchema: import("@sinclair/typebox").TObject<{
2
+ id: import("@sinclair/typebox").TString;
3
+ createdAt: import("@sinclair/typebox").TDate;
4
+ updatedAt: import("@sinclair/typebox").TDate;
5
+ baseAssetId: import("@sinclair/typebox").TString;
6
+ baseAsset: import("@sinclair/typebox").TString;
7
+ price: import("@sinclair/typebox").TString;
8
+ source: import("@sinclair/typebox").TString;
9
+ effectiveAt: import("@sinclair/typebox").TDate;
10
+ }>;
179
11
  export type AssetPriceUserResponseType = typeof assetPriceUserResponseSchema.static;
180
12
  export declare const assetPriceUserListQuerySchema: import("@sinclair/typebox").TObject<{
181
13
  limit: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
@@ -183,7 +15,6 @@ export declare const assetPriceUserListQuerySchema: import("@sinclair/typebox").
183
15
  offset: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
184
16
  pageIndex: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
185
17
  baseAsset: import("@sinclair/typebox").TString;
186
- quoteAsset: import("@sinclair/typebox").TString;
187
18
  source: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
188
19
  startDate: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TDate>;
189
20
  endDate: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TDate>;
@@ -191,192 +22,19 @@ export declare const assetPriceUserListQuerySchema: import("@sinclair/typebox").
191
22
  export type AssetPriceUserListQueryType = typeof assetPriceUserListQuerySchema.static;
192
23
  export declare const assetPriceUserLatestParamsSchema: import("@sinclair/typebox").TObject<{
193
24
  baseAsset: import("@sinclair/typebox").TString;
194
- quoteAsset: import("@sinclair/typebox").TString;
195
25
  }>;
196
26
  export type AssetPriceUserLatestParamsType = typeof assetPriceUserLatestParamsSchema.static;
197
- export declare const assetPriceUserLatestCnyParamsSchema: import("@sinclair/typebox").TObject<{
198
- baseAsset: import("@sinclair/typebox").TString;
199
- }>;
200
- export type AssetPriceUserLatestCnyParamsType = typeof assetPriceUserLatestCnyParamsSchema.static;
201
27
  export declare const assetPriceUserListResponseSchema: import("@sinclair/typebox").TObject<{
202
- data: import("@sinclair/typebox").TArray<import("drizzle-typebox").BuildSchema<"select", {
203
- createdAt: import("drizzle-orm/pg-core").PgColumn<{
204
- name: "created_at";
205
- tableName: "asset_price";
206
- dataType: "date";
207
- columnType: "PgTimestamp";
208
- data: Date;
209
- driverParam: string;
210
- notNull: true;
211
- hasDefault: true;
212
- isPrimaryKey: false;
213
- isAutoincrement: false;
214
- hasRuntimeDefault: false;
215
- enumValues: undefined;
216
- baseColumn: never;
217
- identity: undefined;
218
- generated: undefined;
219
- }, {}, {}>;
220
- updatedAt: import("drizzle-orm/pg-core").PgColumn<{
221
- name: "updated_at";
222
- tableName: "asset_price";
223
- dataType: "date";
224
- columnType: "PgTimestamp";
225
- data: Date;
226
- driverParam: string;
227
- notNull: true;
228
- hasDefault: true;
229
- isPrimaryKey: false;
230
- isAutoincrement: false;
231
- hasRuntimeDefault: false;
232
- enumValues: undefined;
233
- baseColumn: never;
234
- identity: undefined;
235
- generated: undefined;
236
- }, {}, {}>;
237
- id: import("drizzle-orm/pg-core").PgColumn<{
238
- name: "id";
239
- tableName: "asset_price";
240
- dataType: "string";
241
- columnType: "PgUUID";
242
- data: string;
243
- driverParam: string;
244
- notNull: true;
245
- hasDefault: true;
246
- isPrimaryKey: true;
247
- isAutoincrement: false;
248
- hasRuntimeDefault: false;
249
- enumValues: undefined;
250
- baseColumn: never;
251
- identity: undefined;
252
- generated: undefined;
253
- }, {}, {}>;
254
- baseAssetId: import("drizzle-orm/pg-core").PgColumn<{
255
- name: "base_asset_id";
256
- tableName: "asset_price";
257
- dataType: "string";
258
- columnType: "PgUUID";
259
- data: string;
260
- driverParam: string;
261
- notNull: true;
262
- hasDefault: false;
263
- isPrimaryKey: false;
264
- isAutoincrement: false;
265
- hasRuntimeDefault: false;
266
- enumValues: undefined;
267
- baseColumn: never;
268
- identity: undefined;
269
- generated: undefined;
270
- }, {}, {}>;
271
- baseAsset: import("drizzle-orm/pg-core").PgColumn<{
272
- name: "base_asset";
273
- tableName: "asset_price";
274
- dataType: "string";
275
- columnType: "PgVarchar";
276
- data: string;
277
- driverParam: string;
278
- notNull: true;
279
- hasDefault: false;
280
- isPrimaryKey: false;
281
- isAutoincrement: false;
282
- hasRuntimeDefault: false;
283
- enumValues: [string, ...string[]];
284
- baseColumn: never;
285
- identity: undefined;
286
- generated: undefined;
287
- }, {}, {
288
- length: 32;
289
- }>;
290
- quoteAssetId: import("drizzle-orm/pg-core").PgColumn<{
291
- name: "quote_asset_id";
292
- tableName: "asset_price";
293
- dataType: "string";
294
- columnType: "PgUUID";
295
- data: string;
296
- driverParam: string;
297
- notNull: true;
298
- hasDefault: false;
299
- isPrimaryKey: false;
300
- isAutoincrement: false;
301
- hasRuntimeDefault: false;
302
- enumValues: undefined;
303
- baseColumn: never;
304
- identity: undefined;
305
- generated: undefined;
306
- }, {}, {}>;
307
- quoteAsset: import("drizzle-orm/pg-core").PgColumn<{
308
- name: "quote_asset";
309
- tableName: "asset_price";
310
- dataType: "string";
311
- columnType: "PgVarchar";
312
- data: string;
313
- driverParam: string;
314
- notNull: true;
315
- hasDefault: false;
316
- isPrimaryKey: false;
317
- isAutoincrement: false;
318
- hasRuntimeDefault: false;
319
- enumValues: [string, ...string[]];
320
- baseColumn: never;
321
- identity: undefined;
322
- generated: undefined;
323
- }, {}, {
324
- length: 32;
325
- }>;
326
- price: import("drizzle-orm/pg-core").PgColumn<{
327
- name: "price";
328
- tableName: "asset_price";
329
- dataType: "string";
330
- columnType: "PgNumeric";
331
- data: string;
332
- driverParam: string;
333
- notNull: true;
334
- hasDefault: false;
335
- isPrimaryKey: false;
336
- isAutoincrement: false;
337
- hasRuntimeDefault: false;
338
- enumValues: undefined;
339
- baseColumn: never;
340
- identity: undefined;
341
- generated: undefined;
342
- }, {}, {}>;
343
- source: import("drizzle-orm/pg-core").PgColumn<{
344
- name: "source";
345
- tableName: "asset_price";
346
- dataType: "string";
347
- columnType: "PgVarchar";
348
- data: string;
349
- driverParam: string;
350
- notNull: true;
351
- hasDefault: false;
352
- isPrimaryKey: false;
353
- isAutoincrement: false;
354
- hasRuntimeDefault: false;
355
- enumValues: [string, ...string[]];
356
- baseColumn: never;
357
- identity: undefined;
358
- generated: undefined;
359
- }, {}, {
360
- length: 64;
361
- }>;
362
- effectiveAt: import("drizzle-orm/pg-core").PgColumn<{
363
- name: "effective_at";
364
- tableName: "asset_price";
365
- dataType: "date";
366
- columnType: "PgTimestamp";
367
- data: Date;
368
- driverParam: string;
369
- notNull: true;
370
- hasDefault: false;
371
- isPrimaryKey: false;
372
- isAutoincrement: false;
373
- hasRuntimeDefault: false;
374
- enumValues: undefined;
375
- baseColumn: never;
376
- identity: undefined;
377
- generated: undefined;
378
- }, {}, {}>;
379
- }, undefined>>;
28
+ data: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
29
+ id: import("@sinclair/typebox").TString;
30
+ createdAt: import("@sinclair/typebox").TDate;
31
+ updatedAt: import("@sinclair/typebox").TDate;
32
+ baseAssetId: import("@sinclair/typebox").TString;
33
+ baseAsset: import("@sinclair/typebox").TString;
34
+ price: import("@sinclair/typebox").TString;
35
+ source: import("@sinclair/typebox").TString;
36
+ effectiveAt: import("@sinclair/typebox").TDate;
37
+ }>>;
380
38
  pagination: import("@sinclair/typebox").TObject<{
381
39
  pageSize: import("@sinclair/typebox").TNumber;
382
40
  pageIndex: import("@sinclair/typebox").TNumber;
@@ -393,7 +393,6 @@ export declare const assetPriceRouter: Elysia<"/asset_prices", {
393
393
  pageIndex?: number | undefined;
394
394
  endDate?: Date | undefined;
395
395
  baseAsset: string;
396
- quoteAsset: string;
397
396
  };
398
397
  headers: {};
399
398
  response: {
@@ -404,8 +403,6 @@ export declare const assetPriceRouter: Elysia<"/asset_prices", {
404
403
  updatedAt: Date;
405
404
  baseAssetId: string;
406
405
  baseAsset: string;
407
- quoteAssetId: string;
408
- quoteAsset: string;
409
406
  price: string;
410
407
  source: string;
411
408
  effectiveAt: Date;
@@ -431,84 +428,38 @@ export declare const assetPriceRouter: Elysia<"/asset_prices", {
431
428
  };
432
429
  };
433
430
  };
434
- } & {
435
- asset_prices: {
436
- latest: {
437
- cny: {
438
- ":baseAsset": {
439
- get: {
440
- body: {};
441
- params: {
442
- baseAsset: string;
443
- };
444
- query: {};
445
- headers: {};
446
- response: {
447
- 200: {
448
- id: string;
449
- createdAt: Date;
450
- updatedAt: Date;
451
- baseAssetId: string;
452
- baseAsset: string;
453
- quoteAssetId: string;
454
- quoteAsset: string;
455
- price: string;
456
- source: string;
457
- effectiveAt: Date;
458
- };
459
- 422: {
460
- type: "validation";
461
- on: string;
462
- summary?: string;
463
- message?: string;
464
- found?: unknown;
465
- property?: string;
466
- expected?: string;
467
- };
468
- 401: "Unauthorized";
469
- };
470
- };
471
- };
472
- };
473
- };
474
- };
475
431
  } & {
476
432
  asset_prices: {
477
433
  latest: {
478
434
  ":baseAsset": {
479
- ":quoteAsset": {
480
- get: {
481
- body: {};
482
- params: {
435
+ get: {
436
+ body: {};
437
+ params: {
438
+ baseAsset: string;
439
+ };
440
+ query: {};
441
+ headers: {};
442
+ response: {
443
+ 200: {
444
+ id: string;
445
+ createdAt: Date;
446
+ updatedAt: Date;
447
+ baseAssetId: string;
483
448
  baseAsset: string;
484
- quoteAsset: string;
449
+ price: string;
450
+ source: string;
451
+ effectiveAt: Date;
485
452
  };
486
- query: {};
487
- headers: {};
488
- response: {
489
- 200: {
490
- id: string;
491
- createdAt: Date;
492
- updatedAt: Date;
493
- baseAssetId: string;
494
- baseAsset: string;
495
- quoteAssetId: string;
496
- quoteAsset: string;
497
- price: string;
498
- source: string;
499
- effectiveAt: Date;
500
- };
501
- 422: {
502
- type: "validation";
503
- on: string;
504
- summary?: string;
505
- message?: string;
506
- found?: unknown;
507
- property?: string;
508
- expected?: string;
509
- };
510
- 401: "Unauthorized";
453
+ 422: {
454
+ type: "validation";
455
+ on: string;
456
+ summary?: string;
457
+ message?: string;
458
+ found?: unknown;
459
+ property?: string;
460
+ expected?: string;
511
461
  };
462
+ 401: "Unauthorized";
512
463
  };
513
464
  };
514
465
  };
@@ -1,43 +1,26 @@
1
- import { InternalAssetPriceService } from "../internal/service";
2
1
  import type { AssetPriceUserListQueryType } from "./dto.schemas";
3
- export declare abstract class UserAssetPriceService extends InternalAssetPriceService {
2
+ export declare abstract class UserAssetPriceService {
4
3
  static listAssetPrices(query: AssetPriceUserListQueryType): Promise<{
5
4
  items: {
6
5
  id: string;
7
- createdAt: Date;
8
- updatedAt: Date;
9
6
  baseAssetId: string;
10
7
  baseAsset: string;
11
- quoteAssetId: string;
12
- quoteAsset: string;
13
8
  price: string;
14
9
  source: string;
15
10
  effectiveAt: Date;
11
+ createdAt: Date;
12
+ updatedAt: Date;
16
13
  }[];
17
14
  total: number;
18
15
  }>;
19
- static getLatestAssetPrice(baseAsset: string, quoteAsset: string): Promise<{
16
+ static getLatestAssetPrice(baseAsset: string): Promise<{
20
17
  id: string;
21
- createdAt: Date;
22
- updatedAt: Date;
23
18
  baseAssetId: string;
24
19
  baseAsset: string;
25
- quoteAssetId: string;
26
- quoteAsset: string;
27
20
  price: string;
28
21
  source: string;
29
22
  effectiveAt: Date;
30
- }>;
31
- static getLatestAssetPriceToCny(baseAsset: string): Promise<{
32
- id: string;
33
23
  createdAt: Date;
34
24
  updatedAt: Date;
35
- baseAssetId: string;
36
- baseAsset: string;
37
- quoteAssetId: string;
38
- quoteAsset: string;
39
- price: string;
40
- source: string;
41
- effectiveAt: Date;
42
25
  }>;
43
26
  }