@amadeus-protocol/sdk 1.0.7 → 1.0.8
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.
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/mnemonic.d.ts +96 -0
- package/dist/mnemonic.d.ts.map +1 -0
- package/dist/mnemonic.js +128 -0
- package/dist/mnemonic.js.map +1 -0
- package/package.json +2 -1
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH,cAAc,SAAS,CAAA;AACvB,cAAc,aAAa,CAAA;AAC3B,cAAc,YAAY,CAAA;AAC1B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,kBAAkB,CAAA;AAChC,cAAc,UAAU,CAAA;AACxB,cAAc,cAAc,CAAA;AAC5B,cAAc,YAAY,CAAA;AAC1B,cAAc,cAAc,CAAA;AAC5B,cAAc,cAAc,CAAA;AAC5B,cAAc,cAAc,CAAA;AAC5B,cAAc,YAAY,CAAA;AAC1B,cAAc,sBAAsB,CAAA;AACpC,cAAc,uBAAuB,CAAA;AACrC,cAAc,UAAU,CAAA;AACxB,cAAc,OAAO,CAAA;AACrB,cAAc,OAAO,CAAA;AACrB,cAAc,aAAa,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH,cAAc,SAAS,CAAA;AACvB,cAAc,aAAa,CAAA;AAC3B,cAAc,YAAY,CAAA;AAC1B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,kBAAkB,CAAA;AAChC,cAAc,UAAU,CAAA;AACxB,cAAc,cAAc,CAAA;AAC5B,cAAc,YAAY,CAAA;AAC1B,cAAc,cAAc,CAAA;AAC5B,cAAc,YAAY,CAAA;AAC1B,cAAc,cAAc,CAAA;AAC5B,cAAc,cAAc,CAAA;AAC5B,cAAc,YAAY,CAAA;AAC1B,cAAc,sBAAsB,CAAA;AACpC,cAAc,uBAAuB,CAAA;AACrC,cAAc,UAAU,CAAA;AACxB,cAAc,OAAO,CAAA;AACrB,cAAc,OAAO,CAAA;AACrB,cAAc,aAAa,CAAA"}
|
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH,cAAc,SAAS,CAAA;AACvB,cAAc,aAAa,CAAA;AAC3B,cAAc,YAAY,CAAA;AAC1B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,kBAAkB,CAAA;AAChC,cAAc,UAAU,CAAA;AACxB,cAAc,cAAc,CAAA;AAC5B,cAAc,YAAY,CAAA;AAC1B,cAAc,cAAc,CAAA;AAC5B,cAAc,cAAc,CAAA;AAC5B,cAAc,cAAc,CAAA;AAC5B,cAAc,YAAY,CAAA;AAC1B,cAAc,sBAAsB,CAAA;AACpC,cAAc,uBAAuB,CAAA;AACrC,cAAc,UAAU,CAAA;AACxB,cAAc,OAAO,CAAA;AACrB,cAAc,OAAO,CAAA;AACrB,cAAc,aAAa,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH,cAAc,SAAS,CAAA;AACvB,cAAc,aAAa,CAAA;AAC3B,cAAc,YAAY,CAAA;AAC1B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,kBAAkB,CAAA;AAChC,cAAc,UAAU,CAAA;AACxB,cAAc,cAAc,CAAA;AAC5B,cAAc,YAAY,CAAA;AAC1B,cAAc,cAAc,CAAA;AAC5B,cAAc,YAAY,CAAA;AAC1B,cAAc,cAAc,CAAA;AAC5B,cAAc,cAAc,CAAA;AAC5B,cAAc,YAAY,CAAA;AAC1B,cAAc,sBAAsB,CAAA;AACpC,cAAc,uBAAuB,CAAA;AACrC,cAAc,UAAU,CAAA;AACxB,cAAc,OAAO,CAAA;AACrB,cAAc,OAAO,CAAA;AACrB,cAAc,aAAa,CAAA"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BIP39 Mnemonic Utilities for Amadeus Protocol
|
|
3
|
+
*
|
|
4
|
+
* This module provides BIP39 mnemonic generation, validation, and seed derivation
|
|
5
|
+
* for use with Amadeus Protocol wallets.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Generate a new 12-word BIP39 mnemonic
|
|
9
|
+
*
|
|
10
|
+
* @returns 12-word mnemonic phrase
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```ts
|
|
14
|
+
* const mnemonic = generateMnemonic()
|
|
15
|
+
* // "abandon ability able about above absent absorb abstract absurd abuse access accident"
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export declare function generateMnemonic(): string;
|
|
19
|
+
/**
|
|
20
|
+
* Validate a BIP39 mnemonic phrase
|
|
21
|
+
*
|
|
22
|
+
* @param mnemonic - Mnemonic phrase to validate
|
|
23
|
+
* @returns true if the mnemonic is valid
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```ts
|
|
27
|
+
* const isValid = validateMnemonic('abandon ability able ...')
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export declare function validateMnemonic(mnemonic: string): boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Derive an Amadeus seed (base58-encoded 64 bytes) from a BIP39 mnemonic.
|
|
33
|
+
* Uses BIP39 seed derivation (PBKDF2 with SHA-512) which produces a 64-byte seed,
|
|
34
|
+
* matching the Amadeus SDK's expected seed length.
|
|
35
|
+
*
|
|
36
|
+
* @param mnemonic - BIP39 mnemonic phrase
|
|
37
|
+
* @returns Base58-encoded 64-byte seed
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```ts
|
|
41
|
+
* const seed = mnemonicToSeedBase58('abandon ability able ...')
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
export declare function mnemonicToSeedBase58(mnemonic: string): string;
|
|
45
|
+
/**
|
|
46
|
+
* Detect whether input is a mnemonic phrase or a raw private key.
|
|
47
|
+
*
|
|
48
|
+
* @param input - User input string
|
|
49
|
+
* @returns 'mnemonic' if the input looks like a word-based mnemonic, or 'seed' if it looks like a base58-encoded key
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* ```ts
|
|
53
|
+
* const type = detectInputType('abandon ability able ...')
|
|
54
|
+
* // 'mnemonic'
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
export declare function detectInputType(input: string): 'mnemonic' | 'seed';
|
|
58
|
+
/**
|
|
59
|
+
* Vault data format that supports both mnemonic and raw seed storage.
|
|
60
|
+
* When decrypted, old vaults return a plain base58 string,
|
|
61
|
+
* new vaults return a JSON string with this shape.
|
|
62
|
+
*/
|
|
63
|
+
export interface VaultSecretData {
|
|
64
|
+
seed: string;
|
|
65
|
+
mnemonic?: string;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Encode vault secret data as a string for encryption.
|
|
69
|
+
* Always stores as JSON to include the optional mnemonic.
|
|
70
|
+
*
|
|
71
|
+
* @param seed - Base58-encoded seed
|
|
72
|
+
* @param mnemonic - Optional BIP39 mnemonic phrase
|
|
73
|
+
* @returns JSON string for vault encryption
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* ```ts
|
|
77
|
+
* const vaultData = encodeVaultSecret(seed, mnemonic)
|
|
78
|
+
* const encrypted = await encryptWithPassword(vaultData, password)
|
|
79
|
+
* ```
|
|
80
|
+
*/
|
|
81
|
+
export declare function encodeVaultSecret(seed: string, mnemonic?: string): string;
|
|
82
|
+
/**
|
|
83
|
+
* Decode vault secret data from a decrypted string.
|
|
84
|
+
* Handles both old format (plain base58 seed) and new format (JSON with seed + mnemonic).
|
|
85
|
+
*
|
|
86
|
+
* @param decrypted - Decrypted vault string
|
|
87
|
+
* @returns Parsed vault secret data
|
|
88
|
+
*
|
|
89
|
+
* @example
|
|
90
|
+
* ```ts
|
|
91
|
+
* const decrypted = await decryptWithPassword(encrypted, password)
|
|
92
|
+
* const { seed, mnemonic } = decodeVaultSecret(decrypted)
|
|
93
|
+
* ```
|
|
94
|
+
*/
|
|
95
|
+
export declare function decodeVaultSecret(decrypted: string): VaultSecretData;
|
|
96
|
+
//# sourceMappingURL=mnemonic.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mnemonic.d.ts","sourceRoot":"","sources":["../src/mnemonic.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAE1D;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAG7D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,GAAG,MAAM,CAUlE;AAED;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC/B,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAA;CACjB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAMzE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,eAAe,CAapE"}
|
package/dist/mnemonic.js
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BIP39 Mnemonic Utilities for Amadeus Protocol
|
|
3
|
+
*
|
|
4
|
+
* This module provides BIP39 mnemonic generation, validation, and seed derivation
|
|
5
|
+
* for use with Amadeus Protocol wallets.
|
|
6
|
+
*/
|
|
7
|
+
import * as bip39 from '@scure/bip39';
|
|
8
|
+
import { wordlist } from '@scure/bip39/wordlists/english.js';
|
|
9
|
+
import { toBase58 } from './encoding';
|
|
10
|
+
/**
|
|
11
|
+
* Generate a new 12-word BIP39 mnemonic
|
|
12
|
+
*
|
|
13
|
+
* @returns 12-word mnemonic phrase
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* const mnemonic = generateMnemonic()
|
|
18
|
+
* // "abandon ability able about above absent absorb abstract absurd abuse access accident"
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export function generateMnemonic() {
|
|
22
|
+
return bip39.generateMnemonic(wordlist, 128); // 128 bits = 12 words
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Validate a BIP39 mnemonic phrase
|
|
26
|
+
*
|
|
27
|
+
* @param mnemonic - Mnemonic phrase to validate
|
|
28
|
+
* @returns true if the mnemonic is valid
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```ts
|
|
32
|
+
* const isValid = validateMnemonic('abandon ability able ...')
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
export function validateMnemonic(mnemonic) {
|
|
36
|
+
return bip39.validateMnemonic(mnemonic.trim().toLowerCase(), wordlist);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Derive an Amadeus seed (base58-encoded 64 bytes) from a BIP39 mnemonic.
|
|
40
|
+
* Uses BIP39 seed derivation (PBKDF2 with SHA-512) which produces a 64-byte seed,
|
|
41
|
+
* matching the Amadeus SDK's expected seed length.
|
|
42
|
+
*
|
|
43
|
+
* @param mnemonic - BIP39 mnemonic phrase
|
|
44
|
+
* @returns Base58-encoded 64-byte seed
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```ts
|
|
48
|
+
* const seed = mnemonicToSeedBase58('abandon ability able ...')
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
export function mnemonicToSeedBase58(mnemonic) {
|
|
52
|
+
const seed = bip39.mnemonicToSeedSync(mnemonic.trim().toLowerCase());
|
|
53
|
+
return toBase58(seed);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Detect whether input is a mnemonic phrase or a raw private key.
|
|
57
|
+
*
|
|
58
|
+
* @param input - User input string
|
|
59
|
+
* @returns 'mnemonic' if the input looks like a word-based mnemonic, or 'seed' if it looks like a base58-encoded key
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* ```ts
|
|
63
|
+
* const type = detectInputType('abandon ability able ...')
|
|
64
|
+
* // 'mnemonic'
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
67
|
+
export function detectInputType(input) {
|
|
68
|
+
const trimmed = input.trim();
|
|
69
|
+
const words = trimmed.split(/\s+/);
|
|
70
|
+
// BIP39 mnemonics are 12 or 24 words
|
|
71
|
+
if (words.length === 12 || words.length === 24) {
|
|
72
|
+
// Check if all words look like English words (no numbers, no special chars)
|
|
73
|
+
const allWords = words.every((w) => /^[a-zA-Z]+$/.test(w));
|
|
74
|
+
if (allWords)
|
|
75
|
+
return 'mnemonic';
|
|
76
|
+
}
|
|
77
|
+
return 'seed';
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Encode vault secret data as a string for encryption.
|
|
81
|
+
* Always stores as JSON to include the optional mnemonic.
|
|
82
|
+
*
|
|
83
|
+
* @param seed - Base58-encoded seed
|
|
84
|
+
* @param mnemonic - Optional BIP39 mnemonic phrase
|
|
85
|
+
* @returns JSON string for vault encryption
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* ```ts
|
|
89
|
+
* const vaultData = encodeVaultSecret(seed, mnemonic)
|
|
90
|
+
* const encrypted = await encryptWithPassword(vaultData, password)
|
|
91
|
+
* ```
|
|
92
|
+
*/
|
|
93
|
+
export function encodeVaultSecret(seed, mnemonic) {
|
|
94
|
+
const data = { seed };
|
|
95
|
+
if (mnemonic) {
|
|
96
|
+
data.mnemonic = mnemonic;
|
|
97
|
+
}
|
|
98
|
+
return JSON.stringify(data);
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Decode vault secret data from a decrypted string.
|
|
102
|
+
* Handles both old format (plain base58 seed) and new format (JSON with seed + mnemonic).
|
|
103
|
+
*
|
|
104
|
+
* @param decrypted - Decrypted vault string
|
|
105
|
+
* @returns Parsed vault secret data
|
|
106
|
+
*
|
|
107
|
+
* @example
|
|
108
|
+
* ```ts
|
|
109
|
+
* const decrypted = await decryptWithPassword(encrypted, password)
|
|
110
|
+
* const { seed, mnemonic } = decodeVaultSecret(decrypted)
|
|
111
|
+
* ```
|
|
112
|
+
*/
|
|
113
|
+
export function decodeVaultSecret(decrypted) {
|
|
114
|
+
try {
|
|
115
|
+
const parsed = JSON.parse(decrypted);
|
|
116
|
+
if (parsed && typeof parsed.seed === 'string') {
|
|
117
|
+
return {
|
|
118
|
+
seed: parsed.seed,
|
|
119
|
+
mnemonic: parsed.mnemonic || undefined
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
// Not JSON — old format, plain base58 seed
|
|
125
|
+
}
|
|
126
|
+
return { seed: decrypted };
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=mnemonic.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mnemonic.js","sourceRoot":"","sources":["../src/mnemonic.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,mCAAmC,CAAA;AAC5D,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAErC;;;;;;;;;;GAUG;AACH,MAAM,UAAU,gBAAgB;IAC/B,OAAO,KAAK,CAAC,gBAAgB,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAA,CAAC,sBAAsB;AACpE,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAgB;IAChD,OAAO,KAAK,CAAC,gBAAgB,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,QAAQ,CAAC,CAAA;AACvE,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,oBAAoB,CAAC,QAAgB;IACpD,MAAM,IAAI,GAAG,KAAK,CAAC,kBAAkB,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAA;IACpE,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAA;AACtB,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,eAAe,CAAC,KAAa;IAC5C,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAA;IAC5B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;IAClC,qCAAqC;IACrC,IAAI,KAAK,CAAC,MAAM,KAAK,EAAE,IAAI,KAAK,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;QAChD,4EAA4E;QAC5E,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;QAC1D,IAAI,QAAQ;YAAE,OAAO,UAAU,CAAA;IAChC,CAAC;IACD,OAAO,MAAM,CAAA;AACd,CAAC;AAYD;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY,EAAE,QAAiB;IAChE,MAAM,IAAI,GAAoB,EAAE,IAAI,EAAE,CAAA;IACtC,IAAI,QAAQ,EAAE,CAAC;QACd,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAA;IACzB,CAAC;IACD,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;AAC5B,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,iBAAiB,CAAC,SAAiB;IAClD,IAAI,CAAC;QACJ,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;QACpC,IAAI,MAAM,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC/C,OAAO;gBACN,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,SAAS;aACtC,CAAA;QACF,CAAC;IACF,CAAC;IAAC,MAAM,CAAC;QACR,2CAA2C;IAC5C,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAA;AAC3B,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@amadeus-protocol/sdk",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.8",
|
|
4
4
|
"description": "Official TypeScript/JavaScript SDK for Amadeus Protocol - Core utilities for serialization, cryptography, transaction building, and API client",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -65,6 +65,7 @@
|
|
|
65
65
|
"dependencies": {
|
|
66
66
|
"@noble/curves": "^1.9.1",
|
|
67
67
|
"@noble/hashes": "^1.8.0",
|
|
68
|
+
"@scure/bip39": "^2.0.1",
|
|
68
69
|
"bs58": "^6.0.0",
|
|
69
70
|
"effect": "^3.19.8"
|
|
70
71
|
},
|