@inkbox/sdk 0.1.4 → 0.2.0

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 (47) hide show
  1. package/README.md +42 -2
  2. package/dist/_http.d.ts +7 -1
  3. package/dist/_http.d.ts.map +1 -1
  4. package/dist/_http.js +13 -1
  5. package/dist/_http.js.map +1 -1
  6. package/dist/agent_identity.d.ts +36 -4
  7. package/dist/agent_identity.d.ts.map +1 -1
  8. package/dist/agent_identity.js +70 -6
  9. package/dist/agent_identity.js.map +1 -1
  10. package/dist/authenticator/resources/accounts.d.ts +1 -1
  11. package/dist/authenticator/resources/accounts.js +1 -1
  12. package/dist/authenticator/resources/apps.d.ts +2 -2
  13. package/dist/authenticator/resources/apps.js +2 -2
  14. package/dist/credentials.d.ts +86 -0
  15. package/dist/credentials.d.ts.map +1 -0
  16. package/dist/credentials.js +130 -0
  17. package/dist/credentials.js.map +1 -0
  18. package/dist/identities/resources/identities.d.ts +1 -1
  19. package/dist/identities/resources/identities.js +1 -1
  20. package/dist/index.d.ts +8 -1
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +6 -1
  23. package/dist/index.js.map +1 -1
  24. package/dist/inkbox.d.ts +25 -0
  25. package/dist/inkbox.d.ts.map +1 -1
  26. package/dist/inkbox.js +34 -1
  27. package/dist/inkbox.js.map +1 -1
  28. package/dist/mail/resources/messages.d.ts +2 -2
  29. package/dist/mail/resources/messages.d.ts.map +1 -1
  30. package/dist/mail/resources/messages.js.map +1 -1
  31. package/dist/mail/types.d.ts +8 -1
  32. package/dist/mail/types.d.ts.map +1 -1
  33. package/dist/mail/types.js +8 -0
  34. package/dist/mail/types.js.map +1 -1
  35. package/dist/vault/crypto.d.ts +136 -0
  36. package/dist/vault/crypto.d.ts.map +1 -0
  37. package/dist/vault/crypto.js +265 -0
  38. package/dist/vault/crypto.js.map +1 -0
  39. package/dist/vault/resources/vault.d.ts +149 -0
  40. package/dist/vault/resources/vault.d.ts.map +1 -0
  41. package/dist/vault/resources/vault.js +291 -0
  42. package/dist/vault/resources/vault.js.map +1 -0
  43. package/dist/vault/types.d.ts +236 -0
  44. package/dist/vault/types.d.ts.map +1 -0
  45. package/dist/vault/types.js +225 -0
  46. package/dist/vault/types.js.map +1 -0
  47. package/package.json +4 -1
@@ -0,0 +1,265 @@
1
+ /**
2
+ * inkbox-vault/crypto.ts
3
+ *
4
+ * Client-side cryptography for the encrypted vault.
5
+ *
6
+ * Key derivation: Argon2id (vault key → master key, via hash-wasm)
7
+ * Encryption: AES-256-GCM (via Node.js crypto)
8
+ * Hashing: SHA-256 (via Node.js crypto)
9
+ *
10
+ * Salt derivation:
11
+ * The Argon2id salt is derived deterministically from the organisation ID
12
+ * so that both the dashboard (vault init) and the SDK (vault unlock) can
13
+ * compute the same master key from the same vault key:
14
+ *
15
+ * salt = TextEncoder.encode(orgId)
16
+ */
17
+ import { InkboxVaultKeyError } from "../_http.js";
18
+ import { argon2id } from "hash-wasm";
19
+ import { randomUUID, randomBytes, randomInt, createHash, createCipheriv, createDecipheriv, } from "node:crypto";
20
+ import { VaultKeyType } from "./types.js";
21
+ // ---------------------------------------------------------------------------
22
+ // Constants
23
+ // ---------------------------------------------------------------------------
24
+ const ARGON2_TIME_COST = 3;
25
+ const ARGON2_MEMORY_COST = 65536; // 64 MiB
26
+ const ARGON2_PARALLELISM = 1;
27
+ const ARGON2_HASH_LEN = 32;
28
+ const AES_KEY_BYTES = 32;
29
+ const AES_IV_BYTES = 12;
30
+ const AES_TAG_BYTES = 16;
31
+ // Recovery code alphabet (unambiguous uppercase + digits, no 0/O/1/I/L)
32
+ const RC_ALPHABET = "23456789ABCDEFGHJKMNPQRSTUVWXYZ";
33
+ const RC_GROUP_LEN = 4;
34
+ const RC_GROUPS = 8; // 8 groups × 4 chars ≈ 120 bits of entropy
35
+ // ---------------------------------------------------------------------------
36
+ // Vault key validation
37
+ // ---------------------------------------------------------------------------
38
+ /**
39
+ * Validate that a vault key meets minimum strength requirements.
40
+ *
41
+ * Requirements: at least 16 characters, one uppercase letter, one
42
+ * lowercase letter, one digit, and one special character.
43
+ *
44
+ * @param vaultKey - The vault key string to validate.
45
+ * @throws {@link InkboxVaultKeyError} If the vault key does not meet requirements.
46
+ */
47
+ export function validateVaultKey(vaultKey) {
48
+ if (vaultKey.length < 16)
49
+ throw new InkboxVaultKeyError("Vault key must be at least 16 characters");
50
+ if (!/[A-Z]/.test(vaultKey))
51
+ throw new InkboxVaultKeyError("Vault key must contain at least one uppercase letter");
52
+ if (!/[a-z]/.test(vaultKey))
53
+ throw new InkboxVaultKeyError("Vault key must contain at least one lowercase letter");
54
+ if (!/[0-9]/.test(vaultKey))
55
+ throw new InkboxVaultKeyError("Vault key must contain at least one digit");
56
+ if (!/[^A-Za-z0-9]/.test(vaultKey))
57
+ throw new InkboxVaultKeyError("Vault key must contain at least one special character");
58
+ }
59
+ // ---------------------------------------------------------------------------
60
+ // Salt derivation
61
+ // ---------------------------------------------------------------------------
62
+ /**
63
+ * Derive the Argon2id salt from the organisation ID.
64
+ *
65
+ * @param organizationId - The organisation ID string.
66
+ * @returns The raw UTF-8 bytes of the organisation ID.
67
+ */
68
+ export function deriveSalt(organizationId) {
69
+ return new TextEncoder().encode(organizationId);
70
+ }
71
+ // ---------------------------------------------------------------------------
72
+ // Key derivation
73
+ // ---------------------------------------------------------------------------
74
+ /**
75
+ * Derive a 256-bit master key from a vault key using Argon2id.
76
+ *
77
+ * @param vaultKey - The vault key or recovery code string.
78
+ * @param salt - Salt bytes from {@link deriveSalt}.
79
+ * @returns 32-byte master key.
80
+ */
81
+ export async function deriveMasterKey(vaultKey, salt) {
82
+ const hash = await argon2id({
83
+ password: vaultKey,
84
+ salt,
85
+ iterations: ARGON2_TIME_COST,
86
+ memorySize: ARGON2_MEMORY_COST,
87
+ parallelism: ARGON2_PARALLELISM,
88
+ hashLength: ARGON2_HASH_LEN,
89
+ outputType: "binary",
90
+ });
91
+ return new Uint8Array(hash);
92
+ }
93
+ /**
94
+ * Compute `SHA-256(masterKey)` as a hex digest.
95
+ *
96
+ * @param masterKey - The 32-byte master key.
97
+ * @returns 64-character hex string.
98
+ */
99
+ export function computeAuthHash(masterKey) {
100
+ return createHash("sha256").update(masterKey).digest("hex");
101
+ }
102
+ // ---------------------------------------------------------------------------
103
+ // AES-256-GCM
104
+ // ---------------------------------------------------------------------------
105
+ function aesGcmEncrypt(key, plaintext) {
106
+ const iv = randomBytes(AES_IV_BYTES);
107
+ const cipher = createCipheriv("aes-256-gcm", key, iv);
108
+ const encrypted = cipher.update(plaintext);
109
+ const final = cipher.final();
110
+ const tag = cipher.getAuthTag();
111
+ // ciphertext || nonce || tag
112
+ const result = new Uint8Array(encrypted.length + final.length + iv.length + tag.length);
113
+ result.set(encrypted, 0);
114
+ result.set(final, encrypted.length);
115
+ result.set(iv, encrypted.length + final.length);
116
+ result.set(tag, encrypted.length + final.length + iv.length);
117
+ return result;
118
+ }
119
+ function aesGcmDecrypt(key, blob) {
120
+ const tag = blob.slice(-AES_TAG_BYTES);
121
+ const nonce = blob.slice(-(AES_IV_BYTES + AES_TAG_BYTES), -AES_TAG_BYTES);
122
+ const ct = blob.slice(0, -(AES_IV_BYTES + AES_TAG_BYTES));
123
+ const decipher = createDecipheriv("aes-256-gcm", key, nonce);
124
+ decipher.setAuthTag(tag);
125
+ const decrypted = decipher.update(ct);
126
+ const final = decipher.final();
127
+ const result = new Uint8Array(decrypted.length + final.length);
128
+ result.set(decrypted, 0);
129
+ result.set(final, decrypted.length);
130
+ return result;
131
+ }
132
+ /**
133
+ * Wrap the org encryption key with a master key.
134
+ *
135
+ * @param masterKey - 32-byte master key.
136
+ * @param orgKey - 32-byte org encryption key to wrap.
137
+ * @returns Base64-encoded ciphertext blob.
138
+ */
139
+ export function wrapOrgKey(masterKey, orgKey) {
140
+ const blob = aesGcmEncrypt(masterKey, orgKey);
141
+ return Buffer.from(blob).toString("base64");
142
+ }
143
+ /**
144
+ * Unwrap the org encryption key using a master key.
145
+ *
146
+ * @param masterKey - 32-byte master key.
147
+ * @param wrappedB64 - Base64-encoded ciphertext blob from the server.
148
+ * @returns 32-byte org encryption key.
149
+ */
150
+ export function unwrapOrgKey(masterKey, wrappedB64) {
151
+ const blob = new Uint8Array(Buffer.from(wrappedB64, "base64"));
152
+ return aesGcmDecrypt(masterKey, blob);
153
+ }
154
+ // ---------------------------------------------------------------------------
155
+ // Secret payload encryption / decryption
156
+ // ---------------------------------------------------------------------------
157
+ /**
158
+ * Serialize a payload to JSON and encrypt it with the org encryption key.
159
+ *
160
+ * @param orgKey - 32-byte org encryption key.
161
+ * @param payload - Plain object to encrypt.
162
+ * @returns Base64-encoded ciphertext blob.
163
+ */
164
+ export function encryptPayload(orgKey, payload) {
165
+ const plaintext = new TextEncoder().encode(JSON.stringify(payload));
166
+ const blob = aesGcmEncrypt(orgKey, plaintext);
167
+ return Buffer.from(blob).toString("base64");
168
+ }
169
+ /**
170
+ * Decrypt a base64 ciphertext blob and parse the JSON payload.
171
+ *
172
+ * @param orgKey - 32-byte org encryption key.
173
+ * @param encryptedB64 - Base64-encoded ciphertext blob.
174
+ * @returns The decrypted payload as a plain object.
175
+ */
176
+ export function decryptPayload(orgKey, encryptedB64) {
177
+ const blob = new Uint8Array(Buffer.from(encryptedB64, "base64"));
178
+ const plaintext = aesGcmDecrypt(orgKey, blob);
179
+ return JSON.parse(new TextDecoder().decode(plaintext));
180
+ }
181
+ // ---------------------------------------------------------------------------
182
+ // Vault key material generation (used by dashboard / init code)
183
+ // ---------------------------------------------------------------------------
184
+ /**
185
+ * Generate a random 256-bit org encryption key.
186
+ *
187
+ * @returns 32 cryptographically random bytes.
188
+ */
189
+ export function generateOrgEncryptionKey() {
190
+ return randomBytes(AES_KEY_BYTES);
191
+ }
192
+ /**
193
+ * Convert {@link VaultKeyMaterial} to a JSON-ready object matching the API's
194
+ * expected snake_case schema.
195
+ */
196
+ export function vaultKeyMaterialToWire(m) {
197
+ return {
198
+ id: m.id,
199
+ wrapped_org_encryption_key: m.wrappedOrgEncryptionKey,
200
+ auth_hash: m.authHash,
201
+ key_type: m.keyType,
202
+ };
203
+ }
204
+ /**
205
+ * Generate vault key material from a vault key.
206
+ *
207
+ * Derives a master key via Argon2id and wraps the org encryption key.
208
+ *
209
+ * @param vaultKey - The vault key string.
210
+ * @param organizationId - Organisation ID (used as Argon2id salt).
211
+ * @param orgEncryptionKey - 32-byte org encryption key to wrap.
212
+ * @param options.keyType - `"primary"` (default) or `"recovery"`.
213
+ * @returns Material ready to send to the server.
214
+ * @throws {@link InkboxVaultKeyError} If the vault key fails validation.
215
+ */
216
+ export async function generateVaultKeyMaterial(vaultKey, organizationId, orgEncryptionKey, options = {}) {
217
+ validateVaultKey(vaultKey);
218
+ const salt = deriveSalt(organizationId);
219
+ const masterKey = await deriveMasterKey(vaultKey, salt);
220
+ const authHash = computeAuthHash(masterKey);
221
+ const wrapped = wrapOrgKey(masterKey, orgEncryptionKey);
222
+ return {
223
+ id: randomUUID(),
224
+ wrappedOrgEncryptionKey: wrapped,
225
+ authHash,
226
+ keyType: options.keyType ?? VaultKeyType.PRIMARY,
227
+ };
228
+ }
229
+ /**
230
+ * Generate a random recovery code and its vault key material.
231
+ *
232
+ * The recovery code is a human-readable string of the form
233
+ * `XXXX-XXXX-XXXX-XXXX-XXXX-XXXX-XXXX-XXXX` (~120 bits of entropy).
234
+ *
235
+ * @param organizationId - Organisation ID (used as Argon2id salt).
236
+ * @param orgEncryptionKey - 32-byte org encryption key to wrap.
237
+ * @returns `[codeString, material]` tuple. The code string must be stored
238
+ * securely — it cannot be recovered.
239
+ */
240
+ export async function generateRecoveryCode(organizationId, orgEncryptionKey) {
241
+ const groups = [];
242
+ for (let g = 0; g < RC_GROUPS; g++) {
243
+ let group = "";
244
+ for (let c = 0; c < RC_GROUP_LEN; c++) {
245
+ const idx = randomInt(RC_ALPHABET.length);
246
+ group += RC_ALPHABET[idx];
247
+ }
248
+ groups.push(group);
249
+ }
250
+ const code = groups.join("-");
251
+ // Recovery codes bypass validateVaultKey — they are auto-generated
252
+ // and don't follow vault key rules. Derive directly.
253
+ const salt = deriveSalt(organizationId);
254
+ const masterKey = await deriveMasterKey(code, salt);
255
+ const authHash = computeAuthHash(masterKey);
256
+ const wrapped = wrapOrgKey(masterKey, orgEncryptionKey);
257
+ const material = {
258
+ id: randomUUID(),
259
+ wrappedOrgEncryptionKey: wrapped,
260
+ authHash,
261
+ keyType: VaultKeyType.RECOVERY,
262
+ };
263
+ return [code, material];
264
+ }
265
+ //# sourceMappingURL=crypto.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crypto.js","sourceRoot":"","sources":["../../src/vault/crypto.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,149 @@
1
+ /**
2
+ * inkbox-vault/resources/vault.ts
3
+ *
4
+ * VaultResource — org-level vault operations.
5
+ * UnlockedVault — crypto-enabled wrapper for secret CRUD after unlock.
6
+ */
7
+ import { HttpTransport } from "../../_http.js";
8
+ import type { AccessRule, DecryptedVaultSecret, SecretPayload, VaultInfo, VaultKey, VaultSecret } from "../types.js";
9
+ /**
10
+ * Org-level vault operations.
11
+ *
12
+ * Access via `inkbox.vault`. Most read-only operations work without
13
+ * unlocking. To create, read, or update secret payloads, call
14
+ * {@link unlock} first.
15
+ */
16
+ export declare class VaultResource {
17
+ /** @internal */
18
+ readonly http: HttpTransport;
19
+ /** @internal */
20
+ _unlocked: UnlockedVault | null;
21
+ /** @internal */
22
+ constructor(http: HttpTransport);
23
+ /** Get vault metadata for the caller's organisation. */
24
+ info(): Promise<VaultInfo>;
25
+ /**
26
+ * List vault keys (metadata only — no wrapped key material).
27
+ *
28
+ * @param options.keyType - Optional filter: `"primary"` or `"recovery"`.
29
+ */
30
+ listKeys(options?: {
31
+ keyType?: string;
32
+ }): Promise<VaultKey[]>;
33
+ /**
34
+ * List vault secrets (metadata only, no encrypted payload).
35
+ *
36
+ * @param options.secretType - Optional filter: `"login"`, `"ssh_key"`,
37
+ * `"api_key"`, or `"other"`.
38
+ */
39
+ listSecrets(options?: {
40
+ secretType?: string;
41
+ }): Promise<VaultSecret[]>;
42
+ /**
43
+ * Delete a vault secret.
44
+ *
45
+ * @param secretId - UUID of the secret to delete.
46
+ */
47
+ deleteSecret(secretId: string): Promise<void>;
48
+ /**
49
+ * List identity access rules for a vault secret.
50
+ *
51
+ * @param secretId - UUID of the secret.
52
+ */
53
+ listAccessRules(secretId: string): Promise<AccessRule[]>;
54
+ /**
55
+ * Grant an identity access to a vault secret.
56
+ *
57
+ * @param secretId - UUID of the secret.
58
+ * @param identityId - UUID of the identity to grant access to.
59
+ */
60
+ grantAccess(secretId: string, identityId: string): Promise<AccessRule>;
61
+ /**
62
+ * Revoke an identity's access to a vault secret.
63
+ *
64
+ * @param secretId - UUID of the secret.
65
+ * @param identityId - UUID of the identity to revoke access from.
66
+ */
67
+ revokeAccess(secretId: string, identityId: string): Promise<void>;
68
+ /**
69
+ * Unlock the vault with a vault key.
70
+ *
71
+ * Derives the encryption key from the provided vault key, fetches
72
+ * and decrypts all vault secrets.
73
+ *
74
+ * @param vaultKey - Vault key or recovery code.
75
+ * @param options.identityId - Optional agent identity UUID. When
76
+ * provided, only secrets that this identity has been granted access
77
+ * to are included in {@link UnlockedVault.secrets}.
78
+ * @returns {@link UnlockedVault} with decrypted secrets and methods for
79
+ * secret CRUD.
80
+ * @throws If the vault key is incorrect or the vault key has been deleted.
81
+ */
82
+ unlock(vaultKey: string, options?: {
83
+ identityId?: string;
84
+ }): Promise<UnlockedVault>;
85
+ }
86
+ /**
87
+ * A vault unlocked with a valid vault key.
88
+ *
89
+ * Provides transparent encrypt/decrypt for secret CRUD operations.
90
+ *
91
+ * Obtain via {@link VaultResource.unlock}.
92
+ */
93
+ export declare class UnlockedVault {
94
+ private readonly http;
95
+ private readonly orgKey;
96
+ private readonly secretsCache;
97
+ constructor(http: HttpTransport, orgKey: Uint8Array, secretsCache: DecryptedVaultSecret[]);
98
+ /** All vault secrets decrypted from the unlock response. */
99
+ get secrets(): DecryptedVaultSecret[];
100
+ /**
101
+ * Fetch and decrypt a single vault secret.
102
+ *
103
+ * @param secretId - UUID of the secret.
104
+ */
105
+ getSecret(secretId: string): Promise<DecryptedVaultSecret>;
106
+ /**
107
+ * Encrypt and store a new secret.
108
+ *
109
+ * The `secretType` is inferred from the payload shape.
110
+ *
111
+ * @param options.name - Display name (max 255 characters).
112
+ * @param options.description - Optional description.
113
+ * @param options.payload - One of {@link LoginPayload}, {@link SSHKeyPayload},
114
+ * {@link APIKeyPayload}, or {@link OtherPayload}.
115
+ */
116
+ createSecret(options: {
117
+ name: string;
118
+ description?: string;
119
+ payload: SecretPayload;
120
+ }): Promise<VaultSecret>;
121
+ /**
122
+ * Update a vault secret's name, description, and/or encrypted payload.
123
+ *
124
+ * Only provided fields are sent to the server.
125
+ *
126
+ * **Note:** The `secretType` is immutable after creation. If a payload
127
+ * is provided it must be the **same type** as the original (e.g. update
128
+ * a `login` secret with a new {@link LoginPayload}). To change the
129
+ * type, delete the secret and create a new one.
130
+ *
131
+ * @param secretId - UUID of the secret to update.
132
+ * @param options.name - New display name.
133
+ * @param options.description - New description.
134
+ * @param options.payload - New payload of the **same type** as the
135
+ * original (will be re-encrypted).
136
+ */
137
+ updateSecret(secretId: string, options: {
138
+ name?: string;
139
+ description?: string;
140
+ payload?: SecretPayload;
141
+ }): Promise<VaultSecret>;
142
+ /**
143
+ * Delete a vault secret.
144
+ *
145
+ * @param secretId - UUID of the secret to delete.
146
+ */
147
+ deleteSecret(secretId: string): Promise<void>;
148
+ }
149
+ //# sourceMappingURL=vault.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vault.d.ts","sourceRoot":"","sources":["../../../src/vault/resources/vault.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAS/C,OAAO,KAAK,EACV,UAAU,EACV,oBAAoB,EACpB,aAAa,EACb,SAAS,EACT,QAAQ,EACR,WAAW,EAEZ,MAAM,aAAa,CAAC;AAoBrB;;;;;;GAMG;AACH,qBAAa,aAAa;IACxB,gBAAgB;IAChB,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAE7B,gBAAgB;IAChB,SAAS,EAAE,aAAa,GAAG,IAAI,CAAQ;IAEvC,gBAAgB;gBACJ,IAAI,EAAE,aAAa;IAQ/B,wDAAwD;IAClD,IAAI,IAAI,OAAO,CAAC,SAAS,CAAC;IAShC;;;;OAIG;IACG,QAAQ,CAAC,OAAO,GAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAWvE;;;;;OAKG;IACG,WAAW,CAAC,OAAO,GAAE;QAAE,UAAU,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAOhF;;;;OAIG;IACG,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQnD;;;;OAIG;IACG,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAO9D;;;;;OAKG;IACG,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAQ5E;;;;;OAKG;IACG,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQvE;;;;;;;;;;;;;OAaG;IACG,MAAM,CACV,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE;QAAE,UAAU,CAAC,EAAE,MAAM,CAAA;KAAO,GACpC,OAAO,CAAC,aAAa,CAAC;CAwE1B;AAED;;;;;;GAMG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAgB;IACrC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAa;IACpC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAyB;gBAGpD,IAAI,EAAE,aAAa,EACnB,MAAM,EAAE,UAAU,EAClB,YAAY,EAAE,oBAAoB,EAAE;IAOtC,4DAA4D;IAC5D,IAAI,OAAO,IAAI,oBAAoB,EAAE,CAEpC;IAMD;;;;OAIG;IACG,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAsBhE;;;;;;;;;OASG;IACG,YAAY,CAAC,OAAO,EAAE;QAC1B,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,OAAO,EAAE,aAAa,CAAC;KACxB,GAAG,OAAO,CAAC,WAAW,CAAC;IAcxB;;;;;;;;;;;;;;;OAeG;IACG,YAAY,CAChB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE;QACP,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,OAAO,CAAC,EAAE,aAAa,CAAC;KACzB,GACA,OAAO,CAAC,WAAW,CAAC;IA0BvB;;;;OAIG;IACG,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAGpD"}