@claudeskill/cli 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.
- package/README.md +3 -3
- package/dist/api.d.ts +213 -0
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +123 -0
- package/dist/api.js.map +1 -1
- package/dist/commands/checkout.js +3 -3
- package/dist/commands/checkout.js.map +1 -1
- package/dist/commands/diff.js +2 -2
- package/dist/commands/diff.js.map +1 -1
- package/dist/commands/log.js +2 -2
- package/dist/commands/log.js.map +1 -1
- package/dist/commands/login.js +2 -2
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/pull.js +3 -3
- package/dist/commands/pull.js.map +1 -1
- package/dist/commands/push.d.ts.map +1 -1
- package/dist/commands/push.js +26 -3
- package/dist/commands/push.js.map +1 -1
- package/dist/commands/status.js +3 -3
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/team.d.ts +74 -0
- package/dist/commands/team.d.ts.map +1 -0
- package/dist/commands/team.js +551 -0
- package/dist/commands/team.js.map +1 -0
- package/dist/index.js +195 -13
- package/dist/index.js.map +1 -1
- package/dist/menu.js +12 -12
- package/dist/onboarding.js +5 -5
- package/dist/onboarding.js.map +1 -1
- package/dist/sync.d.ts.map +1 -1
- package/dist/sync.js +35 -11
- package/dist/sync.js.map +1 -1
- package/dist/team.d.ts +51 -0
- package/dist/team.d.ts.map +1 -0
- package/dist/team.js +246 -0
- package/dist/team.js.map +1 -0
- package/package.json +4 -4
|
@@ -0,0 +1,551 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Team management commands
|
|
3
|
+
*/
|
|
4
|
+
import * as p from "@clack/prompts";
|
|
5
|
+
import { listTeams, createTeam, getTeam, createTeamInvite, acceptTeamInvite, listAllPendingMembers, distributeTeamKey, getSharingKey, setSharingKey, getKeypair, setKeypair, getMyTeamKey, listTeamMembers, removeTeamMember, getTeamSkillVersions, getTeamSkillVersion, } from "../api.js";
|
|
6
|
+
import { loadCredentials, saveCredentials } from "../credentials.js";
|
|
7
|
+
import { decryptSkill } from "../sync.js";
|
|
8
|
+
import { pushTeamSkills, pullTeamSkills, writeTeamSkill } from "../team.js";
|
|
9
|
+
import { computeKeyFingerprint, generateX25519KeyPair, encryptTeamKeyForMember, decryptTeamKeyAsMember, generateTeamKey, encrypt, decrypt, toBase64, fromBase64, } from "@claudeskill/core";
|
|
10
|
+
/**
|
|
11
|
+
* Derive a filesystem-safe slug from a team name.
|
|
12
|
+
*/
|
|
13
|
+
const deriveTeamSlug = (name) => {
|
|
14
|
+
return name.toLowerCase().replace(/[^a-z0-9]+/g, "-");
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Ensure user has a keypair for team operations
|
|
18
|
+
* Generates one if not present
|
|
19
|
+
*/
|
|
20
|
+
const ensureKeypair = async (masterKey) => {
|
|
21
|
+
const credentials = await loadCredentials();
|
|
22
|
+
if (!credentials) {
|
|
23
|
+
throw new Error("Not logged in");
|
|
24
|
+
}
|
|
25
|
+
// Check if we have a local keypair
|
|
26
|
+
if (credentials.publicKey &&
|
|
27
|
+
credentials.encryptedPrivateKey &&
|
|
28
|
+
credentials.privateKeyIv &&
|
|
29
|
+
credentials.privateKeyTag) {
|
|
30
|
+
// Decrypt private key
|
|
31
|
+
const privateKey = decrypt(fromBase64(credentials.encryptedPrivateKey), masterKey, fromBase64(credentials.privateKeyIv), fromBase64(credentials.privateKeyTag));
|
|
32
|
+
return {
|
|
33
|
+
publicKey: fromBase64(credentials.publicKey),
|
|
34
|
+
privateKey,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
// Check server for existing keypair
|
|
38
|
+
const serverKeypair = await getSharingKey();
|
|
39
|
+
const legacyServerKeypair = !serverKeypair.ok && serverKeypair.status === 404 ? await getKeypair() : null;
|
|
40
|
+
const keypairResponse = serverKeypair.ok || serverKeypair.status !== 404
|
|
41
|
+
? serverKeypair
|
|
42
|
+
: legacyServerKeypair;
|
|
43
|
+
if (keypairResponse?.ok && keypairResponse.data.hasKeypair) {
|
|
44
|
+
// Download and decrypt
|
|
45
|
+
const privateKey = decrypt(fromBase64(keypairResponse.data.encryptedPrivateKey), masterKey, fromBase64(keypairResponse.data.privateKeyIv), fromBase64(keypairResponse.data.privateKeyTag));
|
|
46
|
+
// Save locally
|
|
47
|
+
await saveCredentials({
|
|
48
|
+
...credentials,
|
|
49
|
+
publicKey: keypairResponse.data.publicKey,
|
|
50
|
+
publicKeyFingerprint: keypairResponse.data.publicKeyFingerprint ?? undefined,
|
|
51
|
+
encryptedPrivateKey: keypairResponse.data.encryptedPrivateKey,
|
|
52
|
+
privateKeyIv: keypairResponse.data.privateKeyIv,
|
|
53
|
+
privateKeyTag: keypairResponse.data.privateKeyTag,
|
|
54
|
+
});
|
|
55
|
+
return {
|
|
56
|
+
publicKey: fromBase64(keypairResponse.data.publicKey),
|
|
57
|
+
privateKey,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
// Generate new keypair
|
|
61
|
+
p.log.info("Generating keypair for team operations...");
|
|
62
|
+
const keypair = generateX25519KeyPair();
|
|
63
|
+
// Encrypt private key with master key
|
|
64
|
+
const { ciphertext, iv, tag } = encrypt(keypair.privateKey, masterKey);
|
|
65
|
+
// Upload to server
|
|
66
|
+
const uploadResult = await setSharingKey(toBase64(keypair.publicKey), toBase64(ciphertext), toBase64(iv), toBase64(tag));
|
|
67
|
+
if (!uploadResult.ok) {
|
|
68
|
+
const legacyUploadResult = await setKeypair(toBase64(keypair.publicKey), toBase64(ciphertext), toBase64(iv), toBase64(tag));
|
|
69
|
+
if (!legacyUploadResult.ok) {
|
|
70
|
+
throw new Error(`Failed to upload keypair: ${uploadResult.error}`);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
// Save locally
|
|
74
|
+
await saveCredentials({
|
|
75
|
+
...credentials,
|
|
76
|
+
publicKey: toBase64(keypair.publicKey),
|
|
77
|
+
publicKeyFingerprint: computeKeyFingerprint(keypair.publicKey),
|
|
78
|
+
encryptedPrivateKey: toBase64(ciphertext),
|
|
79
|
+
privateKeyIv: toBase64(iv),
|
|
80
|
+
privateKeyTag: toBase64(tag),
|
|
81
|
+
});
|
|
82
|
+
p.log.success("Keypair generated and saved");
|
|
83
|
+
return keypair;
|
|
84
|
+
};
|
|
85
|
+
/**
|
|
86
|
+
* List teams command
|
|
87
|
+
*/
|
|
88
|
+
export const runTeamList = async () => {
|
|
89
|
+
const spinner = p.spinner();
|
|
90
|
+
spinner.start("Loading teams...");
|
|
91
|
+
const result = await listTeams();
|
|
92
|
+
if (!result.ok) {
|
|
93
|
+
spinner.stop("Failed to load teams");
|
|
94
|
+
p.log.error(result.error);
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
spinner.stop("Teams loaded");
|
|
98
|
+
if (result.data.teams.length === 0) {
|
|
99
|
+
p.log.info("You are not a member of any teams.");
|
|
100
|
+
p.log.info("Create a team with: claudeskill team create <name>");
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
console.log("\nYour teams:\n");
|
|
104
|
+
for (const team of result.data.teams) {
|
|
105
|
+
const status = team.status === "pending" ? " (pending key)" : "";
|
|
106
|
+
console.log(` ${team.name} [${team.role}]${status}\n` +
|
|
107
|
+
` ID: ${team.id}\n` +
|
|
108
|
+
` Members: ${team.memberCount} | Skills: ${team.skillCount}\n`);
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
export const runTeamCreate = async (name, masterKey) => {
|
|
112
|
+
const spinner = p.spinner();
|
|
113
|
+
spinner.start("Creating team and generating team key...");
|
|
114
|
+
const created = await createTeamWithKey(name, masterKey);
|
|
115
|
+
if (!created) {
|
|
116
|
+
spinner.stop("Failed to create team");
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
spinner.stop("Team created");
|
|
120
|
+
p.log.success(`Team "${name}" created successfully!`);
|
|
121
|
+
p.log.info(`Team ID: ${created.teamId}`);
|
|
122
|
+
p.log.info("You can now invite members with: claudeskill team invite <team-id> <email>");
|
|
123
|
+
};
|
|
124
|
+
/**
|
|
125
|
+
* Show team details command
|
|
126
|
+
*/
|
|
127
|
+
export const runTeamShow = async (teamId) => {
|
|
128
|
+
const spinner = p.spinner();
|
|
129
|
+
spinner.start("Loading team...");
|
|
130
|
+
const result = await getTeam(teamId);
|
|
131
|
+
if (!result.ok) {
|
|
132
|
+
spinner.stop("Failed to load team");
|
|
133
|
+
p.log.error(result.error);
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
spinner.stop("Team loaded");
|
|
137
|
+
const team = result.data;
|
|
138
|
+
console.log(`\nTeam: ${team.name}`);
|
|
139
|
+
console.log(`Role: ${team.role} | Status: ${team.status}`);
|
|
140
|
+
console.log(`ID: ${team.id}\n`);
|
|
141
|
+
console.log("Members:");
|
|
142
|
+
for (const member of team.members) {
|
|
143
|
+
const status = member.status === "pending" ? " (pending)" : "";
|
|
144
|
+
const keyStatus = member.hasTeamKey ? "" : " [no key]";
|
|
145
|
+
console.log(` ${member.email} [${member.role}]${status}${keyStatus}`);
|
|
146
|
+
}
|
|
147
|
+
if (team.skills.length > 0) {
|
|
148
|
+
console.log("\nSkills:");
|
|
149
|
+
for (const skill of team.skills) {
|
|
150
|
+
console.log(` ${skill.skillKey} (${skill.currentHash ?? "no versions"})`);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
console.log("\nNo skills shared with this team yet.");
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
/**
|
|
158
|
+
* Invite member to team
|
|
159
|
+
*/
|
|
160
|
+
export const runTeamInvite = async (teamId, email, role = "editor") => {
|
|
161
|
+
const validRoles = ["admin", "editor", "viewer"];
|
|
162
|
+
if (!validRoles.includes(role)) {
|
|
163
|
+
p.log.error(`Invalid role: ${role}. Must be one of: ${validRoles.join(", ")}`);
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
const spinner = p.spinner();
|
|
167
|
+
spinner.start("Creating invite...");
|
|
168
|
+
const result = await createTeamInvite(teamId, email, role);
|
|
169
|
+
if (!result.ok) {
|
|
170
|
+
spinner.stop("Failed to create invite");
|
|
171
|
+
p.log.error(result.error);
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
spinner.stop("Invite created");
|
|
175
|
+
p.log.success(`Invite sent to ${email} as ${role}`);
|
|
176
|
+
console.log("\nShare this invite token with the user:");
|
|
177
|
+
console.log(`\n ${result.data.token}\n`);
|
|
178
|
+
p.log.info(`Expires: ${new Date(result.data.expiresAt).toLocaleString()}`);
|
|
179
|
+
p.log.info("They can accept with: claudeskill team accept <token>");
|
|
180
|
+
};
|
|
181
|
+
/**
|
|
182
|
+
* Accept team invite
|
|
183
|
+
*/
|
|
184
|
+
export const runTeamAccept = async (token, masterKey) => {
|
|
185
|
+
// Ensure we have a keypair first
|
|
186
|
+
await ensureKeypair(masterKey);
|
|
187
|
+
const spinner = p.spinner();
|
|
188
|
+
spinner.start("Accepting invite...");
|
|
189
|
+
const result = await acceptTeamInvite(token);
|
|
190
|
+
if (!result.ok) {
|
|
191
|
+
spinner.stop("Failed to accept invite");
|
|
192
|
+
p.log.error(result.error);
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
spinner.stop("Invite accepted");
|
|
196
|
+
p.log.success(`Joined team "${result.data.teamName}" as ${result.data.role}`);
|
|
197
|
+
p.log.info(result.data.message);
|
|
198
|
+
p.log.info("A team admin will distribute the team key to you. Run 'sync' again later to check.");
|
|
199
|
+
};
|
|
200
|
+
/**
|
|
201
|
+
* Distribute team keys to pending members
|
|
202
|
+
* This is called automatically during sync for owners/admins
|
|
203
|
+
*/
|
|
204
|
+
export const runDistributeKeys = async (masterKey, teamKeys) => {
|
|
205
|
+
const credentials = await loadCredentials();
|
|
206
|
+
if (!credentials) {
|
|
207
|
+
p.log.warning("Not logged in. Skipping team key distribution.");
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
let knownPublicKeyFingerprints = credentials.knownPublicKeyFingerprints ?? {};
|
|
211
|
+
// Get all pending members across teams we manage
|
|
212
|
+
const pendingResult = await listAllPendingMembers();
|
|
213
|
+
if (!pendingResult.ok) {
|
|
214
|
+
p.log.warning(`Could not check for pending members: ${pendingResult.error}`);
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
const pending = pendingResult.data.pendingMembers;
|
|
218
|
+
if (pending.length === 0) {
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
p.log.info(`Found ${pending.length} pending team member(s) waiting for keys`);
|
|
222
|
+
for (const member of pending) {
|
|
223
|
+
// Check if member has a public key
|
|
224
|
+
if (!member.publicKey) {
|
|
225
|
+
p.log.warning(`${member.email} hasn't set up their keypair yet. Skipping.`);
|
|
226
|
+
continue;
|
|
227
|
+
}
|
|
228
|
+
// Get the team key (we need to have it)
|
|
229
|
+
const teamKey = teamKeys.get(member.teamId);
|
|
230
|
+
if (!teamKey) {
|
|
231
|
+
p.log.warning(`You don't have the key for team "${member.teamName}". Skipping.`);
|
|
232
|
+
continue;
|
|
233
|
+
}
|
|
234
|
+
const fingerprint = member.publicKeyFingerprint ??
|
|
235
|
+
computeKeyFingerprint(fromBase64(member.publicKey));
|
|
236
|
+
const cacheKey = member.userId;
|
|
237
|
+
const cachedFingerprint = knownPublicKeyFingerprints[cacheKey];
|
|
238
|
+
if (cachedFingerprint && cachedFingerprint !== fingerprint) {
|
|
239
|
+
const confirm = await p.confirm({
|
|
240
|
+
message: `Public key fingerprint changed for ${member.email} (${fingerprint}). Encrypt anyway?`,
|
|
241
|
+
});
|
|
242
|
+
if (p.isCancel(confirm) || !confirm) {
|
|
243
|
+
p.log.warning(`Skipped ${member.email} because their public key fingerprint changed.`);
|
|
244
|
+
continue;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
else if (!cachedFingerprint) {
|
|
248
|
+
const confirm = await p.confirm({
|
|
249
|
+
message: `Trust public key for ${member.email}? Fingerprint: ${fingerprint}`,
|
|
250
|
+
});
|
|
251
|
+
if (p.isCancel(confirm) || !confirm) {
|
|
252
|
+
p.log.warning(`Skipped ${member.email} because their public key is not trusted yet.`);
|
|
253
|
+
continue;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
// Encrypt team key for this member
|
|
257
|
+
const memberPublicKey = fromBase64(member.publicKey);
|
|
258
|
+
const encrypted = encryptTeamKeyForMember(teamKey, memberPublicKey);
|
|
259
|
+
// Upload encrypted key
|
|
260
|
+
const result = await distributeTeamKey(member.teamId, member.userId, encrypted.encryptedKey, encrypted.iv, encrypted.tag, encrypted.ephemeralPublicKey);
|
|
261
|
+
if (result.ok) {
|
|
262
|
+
await saveCredentials({
|
|
263
|
+
...credentials,
|
|
264
|
+
knownPublicKeyFingerprints: {
|
|
265
|
+
...knownPublicKeyFingerprints,
|
|
266
|
+
[cacheKey]: fingerprint,
|
|
267
|
+
},
|
|
268
|
+
});
|
|
269
|
+
knownPublicKeyFingerprints = {
|
|
270
|
+
...knownPublicKeyFingerprints,
|
|
271
|
+
[cacheKey]: fingerprint,
|
|
272
|
+
};
|
|
273
|
+
p.log.success(`Distributed team key to ${member.email} for "${member.teamName}"`);
|
|
274
|
+
}
|
|
275
|
+
else {
|
|
276
|
+
p.log.error(`Failed to distribute key to ${member.email}: ${result.error}`);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
};
|
|
280
|
+
/**
|
|
281
|
+
* Get team key for a team (download and decrypt if needed)
|
|
282
|
+
*/
|
|
283
|
+
export const getTeamKeyForTeam = async (teamId, masterKey, keypair) => {
|
|
284
|
+
const result = await getMyTeamKey(teamId);
|
|
285
|
+
if (!result.ok) {
|
|
286
|
+
return null;
|
|
287
|
+
}
|
|
288
|
+
// Decrypt team key using our private key
|
|
289
|
+
const teamKey = decryptTeamKeyAsMember(result.data.ephemeralPublicKey, result.data.encryptedTeamKey, result.data.iv, result.data.tag, keypair.privateKey);
|
|
290
|
+
return teamKey;
|
|
291
|
+
};
|
|
292
|
+
/**
|
|
293
|
+
* Create a new team with initial team key
|
|
294
|
+
* Returns the team key for immediate use
|
|
295
|
+
*/
|
|
296
|
+
export const createTeamWithKey = async (name, masterKey) => {
|
|
297
|
+
// Ensure we have a keypair
|
|
298
|
+
const keypair = await ensureKeypair(masterKey);
|
|
299
|
+
// Create team
|
|
300
|
+
const createResult = await createTeam(name);
|
|
301
|
+
if (!createResult.ok) {
|
|
302
|
+
p.log.error(`Failed to create team: ${createResult.error}`);
|
|
303
|
+
return null;
|
|
304
|
+
}
|
|
305
|
+
// Generate team key
|
|
306
|
+
const teamKey = generateTeamKey();
|
|
307
|
+
// Encrypt team key for ourselves (as owner)
|
|
308
|
+
const encrypted = encryptTeamKeyForMember(teamKey, keypair.publicKey);
|
|
309
|
+
// Get our own user ID from team details
|
|
310
|
+
const teamDetailsResult = await getTeam(createResult.data.id);
|
|
311
|
+
if (!teamDetailsResult.ok) {
|
|
312
|
+
p.log.warning(`Team created but failed to get team details: ${teamDetailsResult.error}`);
|
|
313
|
+
return { teamId: createResult.data.id, teamKey };
|
|
314
|
+
}
|
|
315
|
+
const ownerMember = teamDetailsResult.data.members.find((m) => m.role === "owner");
|
|
316
|
+
if (!ownerMember) {
|
|
317
|
+
p.log.warning("Could not find owner in team members");
|
|
318
|
+
return { teamId: createResult.data.id, teamKey };
|
|
319
|
+
}
|
|
320
|
+
// Store our own team key
|
|
321
|
+
const keyResult = await distributeTeamKey(createResult.data.id, ownerMember.userId, encrypted.encryptedKey, encrypted.iv, encrypted.tag, encrypted.ephemeralPublicKey, createResult.data.activeKeyVersion ?? 1);
|
|
322
|
+
if (!keyResult.ok) {
|
|
323
|
+
p.log.warning(`Team created but failed to store team key: ${keyResult.error}`);
|
|
324
|
+
}
|
|
325
|
+
return { teamId: createResult.data.id, teamKey };
|
|
326
|
+
};
|
|
327
|
+
/**
|
|
328
|
+
* Push team skills to server
|
|
329
|
+
*/
|
|
330
|
+
export const runTeamPush = async (teamId, masterKey, skillFilter, message) => {
|
|
331
|
+
const keypair = await ensureKeypair(masterKey);
|
|
332
|
+
const teamKey = await getTeamKeyForTeam(teamId, masterKey, keypair);
|
|
333
|
+
if (!teamKey) {
|
|
334
|
+
p.log.error("Could not decrypt team key. You may not have access to this team.");
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
// Get team key version from API
|
|
338
|
+
const teamResult = await getTeam(teamId);
|
|
339
|
+
if (!teamResult.ok) {
|
|
340
|
+
p.log.error(`Failed to get team info: ${teamResult.error}`);
|
|
341
|
+
return;
|
|
342
|
+
}
|
|
343
|
+
const teamSlug = deriveTeamSlug(teamResult.data.name);
|
|
344
|
+
const spinner = p.spinner();
|
|
345
|
+
spinner.start("Pushing team skills...");
|
|
346
|
+
const result = await pushTeamSkills({
|
|
347
|
+
teamId,
|
|
348
|
+
teamSlug,
|
|
349
|
+
teamKey,
|
|
350
|
+
teamKeyVersion: teamResult.data.activeKeyVersion ?? 1,
|
|
351
|
+
skillFilter,
|
|
352
|
+
message,
|
|
353
|
+
onProgress: (msg) => spinner.message(msg),
|
|
354
|
+
});
|
|
355
|
+
spinner.stop("Push complete");
|
|
356
|
+
if (result.pushed > 0) {
|
|
357
|
+
p.log.success(`Pushed ${result.pushed} team skill(s)`);
|
|
358
|
+
}
|
|
359
|
+
else {
|
|
360
|
+
p.log.info("No changes to push");
|
|
361
|
+
}
|
|
362
|
+
for (const error of result.errors) {
|
|
363
|
+
p.log.error(error);
|
|
364
|
+
}
|
|
365
|
+
};
|
|
366
|
+
/**
|
|
367
|
+
* Pull team skills from server
|
|
368
|
+
*/
|
|
369
|
+
export const runTeamPull = async (teamId, masterKey) => {
|
|
370
|
+
const keypair = await ensureKeypair(masterKey);
|
|
371
|
+
const teamKey = await getTeamKeyForTeam(teamId, masterKey, keypair);
|
|
372
|
+
if (!teamKey) {
|
|
373
|
+
p.log.error("Could not decrypt team key. You may not have access to this team.");
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
376
|
+
const teamResult = await getTeam(teamId);
|
|
377
|
+
if (!teamResult.ok) {
|
|
378
|
+
p.log.error(`Failed to get team info: ${teamResult.error}`);
|
|
379
|
+
return;
|
|
380
|
+
}
|
|
381
|
+
const teamSlug = deriveTeamSlug(teamResult.data.name);
|
|
382
|
+
const spinner = p.spinner();
|
|
383
|
+
spinner.start("Pulling team skills...");
|
|
384
|
+
const result = await pullTeamSkills({
|
|
385
|
+
teamId,
|
|
386
|
+
teamSlug,
|
|
387
|
+
teamKey,
|
|
388
|
+
onProgress: (msg) => spinner.message(msg),
|
|
389
|
+
});
|
|
390
|
+
spinner.stop("Pull complete");
|
|
391
|
+
if (result.pulled > 0) {
|
|
392
|
+
p.log.success(`Pulled ${result.pulled} team skill(s)`);
|
|
393
|
+
}
|
|
394
|
+
else {
|
|
395
|
+
p.log.info("No new team skills to pull");
|
|
396
|
+
}
|
|
397
|
+
for (const error of result.errors) {
|
|
398
|
+
p.log.error(error);
|
|
399
|
+
}
|
|
400
|
+
if (result.conflicts.length > 0) {
|
|
401
|
+
p.log.warning(`${result.conflicts.length} skill(s) skipped due to local modifications:`);
|
|
402
|
+
for (const conflict of result.conflicts) {
|
|
403
|
+
p.log.warning(` ${conflict.skillKey}: ${conflict.reason}`);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
};
|
|
407
|
+
/**
|
|
408
|
+
* Show team skill version history
|
|
409
|
+
*/
|
|
410
|
+
export const runTeamLog = async (teamId, skillKey) => {
|
|
411
|
+
const spinner = p.spinner();
|
|
412
|
+
spinner.start("Loading history...");
|
|
413
|
+
const result = await getTeamSkillVersions(teamId, skillKey);
|
|
414
|
+
if (!result.ok) {
|
|
415
|
+
spinner.stop("Failed");
|
|
416
|
+
p.log.error(result.error);
|
|
417
|
+
return;
|
|
418
|
+
}
|
|
419
|
+
spinner.stop("Loaded");
|
|
420
|
+
console.log(`\nVersion history for ${skillKey}`);
|
|
421
|
+
console.log("═".repeat(50));
|
|
422
|
+
for (const version of result.data.versions) {
|
|
423
|
+
const head = version.hash === result.data.currentHash ? " (HEAD)" : "";
|
|
424
|
+
console.log(`${version.hash}${head}`);
|
|
425
|
+
console.log(` Key version: ${version.teamKeyVersion}`);
|
|
426
|
+
console.log(` Date: ${new Date(version.createdAt).toLocaleString()}`);
|
|
427
|
+
if (version.message) {
|
|
428
|
+
console.log(` Message: ${version.message}`);
|
|
429
|
+
}
|
|
430
|
+
if (version.parentHash) {
|
|
431
|
+
console.log(` Parent: ${version.parentHash}`);
|
|
432
|
+
}
|
|
433
|
+
console.log("");
|
|
434
|
+
}
|
|
435
|
+
};
|
|
436
|
+
/**
|
|
437
|
+
* Restore a specific team skill version
|
|
438
|
+
*/
|
|
439
|
+
export const runTeamCheckout = async (teamId, skillKey, hash, masterKey) => {
|
|
440
|
+
const keypair = await ensureKeypair(masterKey);
|
|
441
|
+
const teamKey = await getTeamKeyForTeam(teamId, masterKey, keypair);
|
|
442
|
+
if (!teamKey) {
|
|
443
|
+
p.log.error("Could not decrypt team key. You may not have access to this team.");
|
|
444
|
+
return;
|
|
445
|
+
}
|
|
446
|
+
const teamResult = await getTeam(teamId);
|
|
447
|
+
if (!teamResult.ok) {
|
|
448
|
+
p.log.error(`Failed to get team info: ${teamResult.error}`);
|
|
449
|
+
return;
|
|
450
|
+
}
|
|
451
|
+
const teamSlug = deriveTeamSlug(teamResult.data.name);
|
|
452
|
+
const spinner = p.spinner();
|
|
453
|
+
spinner.start("Fetching version...");
|
|
454
|
+
const result = await getTeamSkillVersion(teamId, skillKey, hash);
|
|
455
|
+
if (!result.ok) {
|
|
456
|
+
spinner.stop("Failed");
|
|
457
|
+
p.log.error(result.error);
|
|
458
|
+
return;
|
|
459
|
+
}
|
|
460
|
+
const decrypted = decryptSkill(result.data.encryptedData, result.data.iv, result.data.tag, teamKey);
|
|
461
|
+
await writeTeamSkill(teamSlug, decrypted);
|
|
462
|
+
spinner.stop("Checked out");
|
|
463
|
+
p.log.success(`Restored ${skillKey} @ ${hash}`);
|
|
464
|
+
};
|
|
465
|
+
/**
|
|
466
|
+
* List team members with roles
|
|
467
|
+
*/
|
|
468
|
+
export const runTeamMembers = async (teamId) => {
|
|
469
|
+
const spinner = p.spinner();
|
|
470
|
+
spinner.start("Loading members...");
|
|
471
|
+
const result = await listTeamMembers(teamId);
|
|
472
|
+
if (!result.ok) {
|
|
473
|
+
spinner.stop("Failed");
|
|
474
|
+
p.log.error(result.error);
|
|
475
|
+
return;
|
|
476
|
+
}
|
|
477
|
+
spinner.stop("Members loaded");
|
|
478
|
+
console.log("\nTeam members:\n");
|
|
479
|
+
for (const member of result.data.members) {
|
|
480
|
+
const status = member.status === "pending" ? " (pending)" : "";
|
|
481
|
+
const keyStatus = member.hasTeamKey ? "" : " [no key]";
|
|
482
|
+
const fingerprint = member.publicKeyFingerprint
|
|
483
|
+
? ` fingerprint: ${member.publicKeyFingerprint}`
|
|
484
|
+
: "";
|
|
485
|
+
console.log(` ${member.email} [${member.role}]${status}${keyStatus}${fingerprint}`);
|
|
486
|
+
}
|
|
487
|
+
console.log("");
|
|
488
|
+
};
|
|
489
|
+
/**
|
|
490
|
+
* Remove a team member and rotate the team key
|
|
491
|
+
*/
|
|
492
|
+
export const runTeamRemoveMember = async (teamId, email, masterKey) => {
|
|
493
|
+
const spinner = p.spinner();
|
|
494
|
+
spinner.start("Loading team members...");
|
|
495
|
+
const membersResult = await listTeamMembers(teamId);
|
|
496
|
+
if (!membersResult.ok) {
|
|
497
|
+
spinner.stop("Failed");
|
|
498
|
+
p.log.error(membersResult.error);
|
|
499
|
+
return;
|
|
500
|
+
}
|
|
501
|
+
const target = membersResult.data.members.find((m) => m.email.toLowerCase() === email.toLowerCase() && m.status === "active");
|
|
502
|
+
if (!target) {
|
|
503
|
+
spinner.stop("Not found");
|
|
504
|
+
p.log.error(`Active member not found: ${email}`);
|
|
505
|
+
return;
|
|
506
|
+
}
|
|
507
|
+
spinner.stop("Member found");
|
|
508
|
+
const confirmRemoval = await p.confirm({
|
|
509
|
+
message: `Remove ${email} from team? This will rotate the team key.`,
|
|
510
|
+
});
|
|
511
|
+
if (p.isCancel(confirmRemoval) || !confirmRemoval) {
|
|
512
|
+
p.cancel("Removal cancelled.");
|
|
513
|
+
return;
|
|
514
|
+
}
|
|
515
|
+
spinner.start("Rotating team key...");
|
|
516
|
+
// Get current team key version
|
|
517
|
+
const teamResult = await getTeam(teamId);
|
|
518
|
+
if (!teamResult.ok) {
|
|
519
|
+
spinner.stop("Failed");
|
|
520
|
+
p.log.error(teamResult.error);
|
|
521
|
+
return;
|
|
522
|
+
}
|
|
523
|
+
const nextKeyVersion = (teamResult.data.activeKeyVersion ?? 1) + 1;
|
|
524
|
+
// Generate new team key
|
|
525
|
+
const newTeamKey = generateTeamKey();
|
|
526
|
+
// Encrypt new key for all remaining active members (except the removed one)
|
|
527
|
+
const envelopes = membersResult.data.members
|
|
528
|
+
.filter((m) => m.status === "active" &&
|
|
529
|
+
m.userId !== target.userId &&
|
|
530
|
+
m.publicKey)
|
|
531
|
+
.map((m) => {
|
|
532
|
+
const encrypted = encryptTeamKeyForMember(newTeamKey, fromBase64(m.publicKey));
|
|
533
|
+
return {
|
|
534
|
+
recipientUserId: m.userId,
|
|
535
|
+
encryptedTeamKey: encrypted.encryptedKey,
|
|
536
|
+
iv: encrypted.iv,
|
|
537
|
+
tag: encrypted.tag,
|
|
538
|
+
ephemeralPublicKey: encrypted.ephemeralPublicKey,
|
|
539
|
+
};
|
|
540
|
+
});
|
|
541
|
+
const result = await removeTeamMember(teamId, target.userId, nextKeyVersion, envelopes);
|
|
542
|
+
if (!result.ok) {
|
|
543
|
+
spinner.stop("Failed");
|
|
544
|
+
p.log.error(result.error);
|
|
545
|
+
return;
|
|
546
|
+
}
|
|
547
|
+
spinner.stop("Removed");
|
|
548
|
+
p.log.success(`Removed ${email} and rotated team key to version ${nextKeyVersion}`);
|
|
549
|
+
};
|
|
550
|
+
export { ensureKeypair };
|
|
551
|
+
//# sourceMappingURL=team.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"team.js","sourceRoot":"","sources":["../../src/commands/team.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,CAAC,MAAM,gBAAgB,CAAC;AACpC,OAAO,EACL,SAAS,EACT,UAAU,EACV,OAAO,EACP,gBAAgB,EAChB,gBAAgB,EAChB,qBAAqB,EACrB,iBAAiB,EACjB,aAAa,EACb,aAAa,EACb,UAAU,EACV,UAAU,EACV,YAAY,EACZ,eAAe,EACf,gBAAgB,EAChB,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5E,OAAO,EACL,qBAAqB,EACrB,qBAAqB,EACrB,uBAAuB,EACvB,sBAAsB,EACtB,eAAe,EACf,OAAO,EACP,OAAO,EACP,QAAQ,EACR,UAAU,GACX,MAAM,mBAAmB,CAAC;AAE3B;;GAEG;AACH,MAAM,cAAc,GAAG,CAAC,IAAY,EAAU,EAAE;IAC9C,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC;AACxD,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,aAAa,GAAG,KAAK,EACzB,SAAqB,EACuC,EAAE;IAC9D,MAAM,WAAW,GAAG,MAAM,eAAe,EAAE,CAAC;IAC5C,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC;IACnC,CAAC;IAED,mCAAmC;IACnC,IACE,WAAW,CAAC,SAAS;QACrB,WAAW,CAAC,mBAAmB;QAC/B,WAAW,CAAC,YAAY;QACxB,WAAW,CAAC,aAAa,EACzB,CAAC;QACD,sBAAsB;QACtB,MAAM,UAAU,GAAG,OAAO,CACxB,UAAU,CAAC,WAAW,CAAC,mBAAmB,CAAC,EAC3C,SAAS,EACT,UAAU,CAAC,WAAW,CAAC,YAAY,CAAC,EACpC,UAAU,CAAC,WAAW,CAAC,aAAa,CAAC,CACtC,CAAC;QACF,OAAO;YACL,SAAS,EAAE,UAAU,CAAC,WAAW,CAAC,SAAS,CAAC;YAC5C,UAAU;SACX,CAAC;IACJ,CAAC;IAED,oCAAoC;IACpC,MAAM,aAAa,GAAG,MAAM,aAAa,EAAE,CAAC;IAC5C,MAAM,mBAAmB,GACvB,CAAC,aAAa,CAAC,EAAE,IAAI,aAAa,CAAC,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,MAAM,UAAU,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IAChF,MAAM,eAAe,GACnB,aAAa,CAAC,EAAE,IAAI,aAAa,CAAC,MAAM,KAAK,GAAG;QAC9C,CAAC,CAAC,aAAa;QACf,CAAC,CAAC,mBAAmB,CAAC;IAC1B,IAAI,eAAe,EAAE,EAAE,IAAI,eAAe,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;QAC3D,uBAAuB;QACvB,MAAM,UAAU,GAAG,OAAO,CACxB,UAAU,CAAC,eAAe,CAAC,IAAI,CAAC,mBAAoB,CAAC,EACrD,SAAS,EACT,UAAU,CAAC,eAAe,CAAC,IAAI,CAAC,YAAa,CAAC,EAC9C,UAAU,CAAC,eAAe,CAAC,IAAI,CAAC,aAAc,CAAC,CAChD,CAAC;QAEF,eAAe;QACf,MAAM,eAAe,CAAC;YACpB,GAAG,WAAW;YACd,SAAS,EAAE,eAAe,CAAC,IAAI,CAAC,SAAS;YACzC,oBAAoB,EAAE,eAAe,CAAC,IAAI,CAAC,oBAAoB,IAAI,SAAS;YAC5E,mBAAmB,EAAE,eAAe,CAAC,IAAI,CAAC,mBAAmB;YAC7D,YAAY,EAAE,eAAe,CAAC,IAAI,CAAC,YAAY;YAC/C,aAAa,EAAE,eAAe,CAAC,IAAI,CAAC,aAAa;SAClD,CAAC,CAAC;QAEH,OAAO;YACL,SAAS,EAAE,UAAU,CAAC,eAAe,CAAC,IAAI,CAAC,SAAU,CAAC;YACtD,UAAU;SACX,CAAC;IACJ,CAAC;IAED,uBAAuB;IACvB,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAC;IACxD,MAAM,OAAO,GAAG,qBAAqB,EAAE,CAAC;IAExC,sCAAsC;IACtC,MAAM,EAAE,UAAU,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;IAEvE,mBAAmB;IACnB,MAAM,YAAY,GAAG,MAAM,aAAa,CACtC,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,EAC3B,QAAQ,CAAC,UAAU,CAAC,EACpB,QAAQ,CAAC,EAAE,CAAC,EACZ,QAAQ,CAAC,GAAG,CAAC,CACd,CAAC;IAEF,IAAI,CAAC,YAAY,CAAC,EAAE,EAAE,CAAC;QACrB,MAAM,kBAAkB,GAAG,MAAM,UAAU,CACzC,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,EAC3B,QAAQ,CAAC,UAAU,CAAC,EACpB,QAAQ,CAAC,EAAE,CAAC,EACZ,QAAQ,CAAC,GAAG,CAAC,CACd,CAAC;QAEF,IAAI,CAAC,kBAAkB,CAAC,EAAE,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CAAC,6BAA6B,YAAY,CAAC,KAAK,EAAE,CAAC,CAAC;QACrE,CAAC;IACH,CAAC;IAED,eAAe;IACf,MAAM,eAAe,CAAC;QACpB,GAAG,WAAW;QACd,SAAS,EAAE,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC;QACtC,oBAAoB,EAAE,qBAAqB,CAAC,OAAO,CAAC,SAAS,CAAC;QAC9D,mBAAmB,EAAE,QAAQ,CAAC,UAAU,CAAC;QACzC,YAAY,EAAE,QAAQ,CAAC,EAAE,CAAC;QAC1B,aAAa,EAAE,QAAQ,CAAC,GAAG,CAAC;KAC7B,CAAC,CAAC;IAEH,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,6BAA6B,CAAC,CAAC;IAE7C,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,KAAK,IAAmB,EAAE;IACnD,MAAM,OAAO,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC;IAC5B,OAAO,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;IAElC,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAC;IAEjC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;QACrC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC1B,OAAO;IACT,CAAC;IAED,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IAE7B,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACnC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,oCAAoC,CAAC,CAAC;QACjD,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,oDAAoD,CAAC,CAAC;QACjE,OAAO;IACT,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IAC/B,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QACrC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC;QACjE,OAAO,CAAC,GAAG,CACT,KAAK,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,IAAI,MAAM,IAAI;YACxC,WAAW,IAAI,CAAC,EAAE,IAAI;YACtB,gBAAgB,IAAI,CAAC,WAAW,cAAc,IAAI,CAAC,UAAU,IAAI,CACpE,CAAC;IACJ,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,EAChC,IAAY,EACZ,SAAqB,EACN,EAAE;IACjB,MAAM,OAAO,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC;IAC5B,OAAO,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAC;IAE1D,MAAM,OAAO,GAAG,MAAM,iBAAiB,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IACzD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;QACtC,OAAO;IACT,CAAC;IAED,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IAC7B,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,IAAI,yBAAyB,CAAC,CAAC;IACtD,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACzC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,4EAA4E,CAAC,CAAC;AAC3F,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,KAAK,EAAE,MAAc,EAAiB,EAAE;IACjE,MAAM,OAAO,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC;IAC5B,OAAO,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;IAEjC,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IAErC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;QACpC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC1B,OAAO;IACT,CAAC;IAED,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IAE5B,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;IACzB,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IACpC,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,CAAC,IAAI,cAAc,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IAC3D,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC;IAEhC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IACxB,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;QAClC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/D,MAAM,SAAS,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC;QACvD,OAAO,CAAC,GAAG,CAAC,KAAK,MAAM,CAAC,KAAK,KAAK,MAAM,CAAC,IAAI,IAAI,MAAM,GAAG,SAAS,EAAE,CAAC,CAAC;IACzE,CAAC;IAED,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3B,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACzB,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChC,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,QAAQ,KAAK,KAAK,CAAC,WAAW,IAAI,aAAa,GAAG,CAAC,CAAC;QAC7E,CAAC;IACH,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,wCAAwC,CAAC,CAAC;IACxD,CAAC;AACH,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,EAChC,MAAc,EACd,KAAa,EACb,OAAe,QAAQ,EACR,EAAE;IACjB,MAAM,UAAU,GAAG,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACjD,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAC/B,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,iBAAiB,IAAI,qBAAqB,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC/E,OAAO;IACT,CAAC;IAED,MAAM,OAAO,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC;IAC5B,OAAO,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;IAEpC,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;IAE3D,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;QACxC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC1B,OAAO;IACT,CAAC;IAED,OAAO,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IAC/B,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,kBAAkB,KAAK,OAAO,IAAI,EAAE,CAAC,CAAC;IACpD,OAAO,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAC;IACxD,OAAO,CAAC,GAAG,CAAC,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC;IAC1C,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;IAC3E,CAAC,CAAC,GAAG,CAAC,IAAI,CACR,uDAAuD,CACxD,CAAC;AACJ,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,EAChC,KAAa,EACb,SAAqB,EACN,EAAE;IACjB,iCAAiC;IACjC,MAAM,aAAa,CAAC,SAAS,CAAC,CAAC;IAE/B,MAAM,OAAO,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC;IAC5B,OAAO,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;IAErC,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,KAAK,CAAC,CAAC;IAE7C,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;QACxC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC1B,OAAO;IACT,CAAC;IAED,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;IAChC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,gBAAgB,MAAM,CAAC,IAAI,CAAC,QAAQ,QAAQ,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IAC9E,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAChC,CAAC,CAAC,GAAG,CAAC,IAAI,CACR,oFAAoF,CACrF,CAAC;AACJ,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,KAAK,EACpC,SAAqB,EACrB,QAAiC,EAClB,EAAE;IACjB,MAAM,WAAW,GAAG,MAAM,eAAe,EAAE,CAAC;IAC5C,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,gDAAgD,CAAC,CAAC;QAChE,OAAO;IACT,CAAC;IACD,IAAI,0BAA0B,GAAG,WAAW,CAAC,0BAA0B,IAAI,EAAE,CAAC;IAE9E,iDAAiD;IACjD,MAAM,aAAa,GAAG,MAAM,qBAAqB,EAAE,CAAC;IAEpD,IAAI,CAAC,aAAa,CAAC,EAAE,EAAE,CAAC;QACtB,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,wCAAwC,aAAa,CAAC,KAAK,EAAE,CAAC,CAAC;QAC7E,OAAO;IACT,CAAC;IAED,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,CAAC,cAAc,CAAC;IAClD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO;IACT,CAAC;IAED,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,OAAO,CAAC,MAAM,0CAA0C,CAAC,CAAC;IAE9E,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,mCAAmC;QACnC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;YACtB,CAAC,CAAC,GAAG,CAAC,OAAO,CACX,GAAG,MAAM,CAAC,KAAK,6CAA6C,CAC7D,CAAC;YACF,SAAS;QACX,CAAC;QAED,wCAAwC;QACxC,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC5C,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,CAAC,CAAC,GAAG,CAAC,OAAO,CACX,oCAAoC,MAAM,CAAC,QAAQ,cAAc,CAClE,CAAC;YACF,SAAS;QACX,CAAC;QAED,MAAM,WAAW,GACf,MAAM,CAAC,oBAAoB;YAC3B,qBAAqB,CAAC,UAAU,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;QACtD,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC;QAC/B,MAAM,iBAAiB,GAAG,0BAA0B,CAAC,QAAQ,CAAC,CAAC;QAE/D,IAAI,iBAAiB,IAAI,iBAAiB,KAAK,WAAW,EAAE,CAAC;YAC3D,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC,OAAO,CAAC;gBAC9B,OAAO,EACL,sCAAsC,MAAM,CAAC,KAAK,KAAK,WAAW,oBAAoB;aACzF,CAAC,CAAC;YAEH,IAAI,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;gBACpC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,WAAW,MAAM,CAAC,KAAK,gDAAgD,CAAC,CAAC;gBACvF,SAAS;YACX,CAAC;QACH,CAAC;aAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;YAC9B,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC,OAAO,CAAC;gBAC9B,OAAO,EACL,wBAAwB,MAAM,CAAC,KAAK,kBAAkB,WAAW,EAAE;aACtE,CAAC,CAAC;YAEH,IAAI,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;gBACpC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,WAAW,MAAM,CAAC,KAAK,+CAA+C,CAAC,CAAC;gBACtF,SAAS;YACX,CAAC;QACH,CAAC;QAED,mCAAmC;QACnC,MAAM,eAAe,GAAG,UAAU,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QACrD,MAAM,SAAS,GAAG,uBAAuB,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;QAEpE,uBAAuB;QACvB,MAAM,MAAM,GAAG,MAAM,iBAAiB,CACpC,MAAM,CAAC,MAAM,EACb,MAAM,CAAC,MAAM,EACb,SAAS,CAAC,YAAY,EACtB,SAAS,CAAC,EAAE,EACZ,SAAS,CAAC,GAAG,EACb,SAAS,CAAC,kBAAkB,CAC7B,CAAC;QAEF,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;YACd,MAAM,eAAe,CAAC;gBACpB,GAAG,WAAW;gBACd,0BAA0B,EAAE;oBAC1B,GAAG,0BAA0B;oBAC7B,CAAC,QAAQ,CAAC,EAAE,WAAW;iBACxB;aACF,CAAC,CAAC;YACH,0BAA0B,GAAG;gBAC3B,GAAG,0BAA0B;gBAC7B,CAAC,QAAQ,CAAC,EAAE,WAAW;aACxB,CAAC;YACF,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,2BAA2B,MAAM,CAAC,KAAK,SAAS,MAAM,CAAC,QAAQ,GAAG,CAAC,CAAC;QACpF,CAAC;aAAM,CAAC;YACN,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,+BAA+B,MAAM,CAAC,KAAK,KAAK,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;QAC9E,CAAC;IACH,CAAC;AACH,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,KAAK,EACpC,MAAc,EACd,SAAqB,EACrB,OAA0D,EAC9B,EAAE;IAC9B,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,MAAM,CAAC,CAAC;IAE1C,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;QACf,OAAO,IAAI,CAAC;IACd,CAAC;IAED,yCAAyC;IACzC,MAAM,OAAO,GAAG,sBAAsB,CACpC,MAAM,CAAC,IAAI,CAAC,kBAAkB,EAC9B,MAAM,CAAC,IAAI,CAAC,gBAAgB,EAC5B,MAAM,CAAC,IAAI,CAAC,EAAE,EACd,MAAM,CAAC,IAAI,CAAC,GAAG,EACf,OAAO,CAAC,UAAU,CACnB,CAAC;IAEF,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,KAAK,EACpC,IAAY,EACZ,SAAqB,EACoC,EAAE;IAC3D,2BAA2B;IAC3B,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,SAAS,CAAC,CAAC;IAE/C,cAAc;IACd,MAAM,YAAY,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,CAAC;IAC5C,IAAI,CAAC,YAAY,CAAC,EAAE,EAAE,CAAC;QACrB,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,0BAA0B,YAAY,CAAC,KAAK,EAAE,CAAC,CAAC;QAC5D,OAAO,IAAI,CAAC;IACd,CAAC;IAED,oBAAoB;IACpB,MAAM,OAAO,GAAG,eAAe,EAAE,CAAC;IAElC,4CAA4C;IAC5C,MAAM,SAAS,GAAG,uBAAuB,CAAC,OAAO,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;IAEtE,wCAAwC;IACxC,MAAM,iBAAiB,GAAG,MAAM,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC9D,IAAI,CAAC,iBAAiB,CAAC,EAAE,EAAE,CAAC;QAC1B,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,gDAAgD,iBAAiB,CAAC,KAAK,EAAE,CAAC,CAAC;QACzF,OAAO,EAAE,MAAM,EAAE,YAAY,CAAC,IAAI,CAAC,EAAE,EAAE,OAAO,EAAE,CAAC;IACnD,CAAC;IAED,MAAM,WAAW,GAAG,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CACrD,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAC1B,CAAC;IACF,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,sCAAsC,CAAC,CAAC;QACtD,OAAO,EAAE,MAAM,EAAE,YAAY,CAAC,IAAI,CAAC,EAAE,EAAE,OAAO,EAAE,CAAC;IACnD,CAAC;IAED,yBAAyB;IACzB,MAAM,SAAS,GAAG,MAAM,iBAAiB,CACvC,YAAY,CAAC,IAAI,CAAC,EAAE,EACpB,WAAW,CAAC,MAAM,EAClB,SAAS,CAAC,YAAY,EACtB,SAAS,CAAC,EAAE,EACZ,SAAS,CAAC,GAAG,EACb,SAAS,CAAC,kBAAkB,EAC5B,YAAY,CAAC,IAAI,CAAC,gBAAgB,IAAI,CAAC,CACxC,CAAC;IAEF,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC;QAClB,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,8CAA8C,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC;IACjF,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,YAAY,CAAC,IAAI,CAAC,EAAE,EAAE,OAAO,EAAE,CAAC;AACnD,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,KAAK,EAC9B,MAAc,EACd,SAAqB,EACrB,WAAoB,EACpB,OAAgB,EACD,EAAE;IACjB,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,SAAS,CAAC,CAAC;IAC/C,MAAM,OAAO,GAAG,MAAM,iBAAiB,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;IACpE,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,mEAAmE,CAAC,CAAC;QACjF,OAAO;IACT,CAAC;IAED,gCAAgC;IAChC,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IACzC,IAAI,CAAC,UAAU,CAAC,EAAE,EAAE,CAAC;QACnB,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,4BAA4B,UAAU,CAAC,KAAK,EAAE,CAAC,CAAC;QAC5D,OAAO;IACT,CAAC;IAED,MAAM,QAAQ,GAAG,cAAc,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtD,MAAM,OAAO,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC;IAC5B,OAAO,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;IAExC,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC;QAClC,MAAM;QACN,QAAQ;QACR,OAAO;QACP,cAAc,EAAE,UAAU,CAAC,IAAI,CAAC,gBAAgB,IAAI,CAAC;QACrD,WAAW;QACX,OAAO;QACP,UAAU,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC;KAC1C,CAAC,CAAC;IAEH,OAAO,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IAE9B,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtB,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,MAAM,CAAC,MAAM,gBAAgB,CAAC,CAAC;IACzD,CAAC;SAAM,CAAC;QACN,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;IACnC,CAAC;IACD,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAClC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACrB,CAAC;AACH,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,KAAK,EAC9B,MAAc,EACd,SAAqB,EACN,EAAE;IACjB,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,SAAS,CAAC,CAAC;IAC/C,MAAM,OAAO,GAAG,MAAM,iBAAiB,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;IACpE,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,mEAAmE,CAAC,CAAC;QACjF,OAAO;IACT,CAAC;IAED,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IACzC,IAAI,CAAC,UAAU,CAAC,EAAE,EAAE,CAAC;QACnB,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,4BAA4B,UAAU,CAAC,KAAK,EAAE,CAAC,CAAC;QAC5D,OAAO;IACT,CAAC;IAED,MAAM,QAAQ,GAAG,cAAc,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtD,MAAM,OAAO,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC;IAC5B,OAAO,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;IAExC,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC;QAClC,MAAM;QACN,QAAQ;QACR,OAAO;QACP,UAAU,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC;KAC1C,CAAC,CAAC;IAEH,OAAO,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IAE9B,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtB,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,MAAM,CAAC,MAAM,gBAAgB,CAAC,CAAC;IACzD,CAAC;SAAM,CAAC;QACN,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;IAC3C,CAAC;IACD,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAClC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACrB,CAAC;IACD,IAAI,MAAM,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAChC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,MAAM,CAAC,SAAS,CAAC,MAAM,+CAA+C,CAAC,CAAC;QACzF,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;YACxC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,QAAQ,KAAK,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;QAC9D,CAAC;IACH,CAAC;AACH,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,KAAK,EAC7B,MAAc,EACd,QAAgB,EACD,EAAE;IACjB,MAAM,OAAO,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC;IAC5B,OAAO,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;IAEpC,MAAM,MAAM,GAAG,MAAM,oBAAoB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC5D,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACvB,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC1B,OAAO;IACT,CAAC;IAED,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAEvB,OAAO,CAAC,GAAG,CAAC,yBAAyB,QAAQ,EAAE,CAAC,CAAC;IACjD,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;IAC5B,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC3C,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,KAAK,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;QACvE,OAAO,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,EAAE,CAAC,CAAC;QACtC,OAAO,CAAC,GAAG,CAAC,kBAAkB,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;QACxD,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;QACvE,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;YACpB,OAAO,CAAC,GAAG,CAAC,cAAc,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;QAC/C,CAAC;QACD,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;YACvB,OAAO,CAAC,GAAG,CAAC,aAAa,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;QACjD,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,EAClC,MAAc,EACd,QAAgB,EAChB,IAAY,EACZ,SAAqB,EACN,EAAE;IACjB,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,SAAS,CAAC,CAAC;IAC/C,MAAM,OAAO,GAAG,MAAM,iBAAiB,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;IACpE,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,mEAAmE,CAAC,CAAC;QACjF,OAAO;IACT,CAAC;IAED,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IACzC,IAAI,CAAC,UAAU,CAAC,EAAE,EAAE,CAAC;QACnB,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,4BAA4B,UAAU,CAAC,KAAK,EAAE,CAAC,CAAC;QAC5D,OAAO;IACT,CAAC;IAED,MAAM,QAAQ,GAAG,cAAc,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtD,MAAM,OAAO,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC;IAC5B,OAAO,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;IAErC,MAAM,MAAM,GAAG,MAAM,mBAAmB,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;IACjE,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACvB,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC1B,OAAO;IACT,CAAC;IAED,MAAM,SAAS,GAAG,YAAY,CAC5B,MAAM,CAAC,IAAI,CAAC,aAAa,EACzB,MAAM,CAAC,IAAI,CAAC,EAAE,EACd,MAAM,CAAC,IAAI,CAAC,GAAG,EACf,OAAO,CACR,CAAC;IACF,MAAM,cAAc,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IAE1C,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IAC5B,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,YAAY,QAAQ,MAAM,IAAI,EAAE,CAAC,CAAC;AAClD,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,EAAE,MAAc,EAAiB,EAAE;IACpE,MAAM,OAAO,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC;IAC5B,OAAO,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;IAEpC,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,MAAM,CAAC,CAAC;IAC7C,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACvB,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC1B,OAAO;IACT,CAAC;IAED,OAAO,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IAE/B,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;IACjC,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;QACzC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/D,MAAM,SAAS,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC;QACvD,MAAM,WAAW,GAAG,MAAM,CAAC,oBAAoB;YAC7C,CAAC,CAAC,kBAAkB,MAAM,CAAC,oBAAoB,EAAE;YACjD,CAAC,CAAC,EAAE,CAAC;QACP,OAAO,CAAC,GAAG,CAAC,KAAK,MAAM,CAAC,KAAK,KAAK,MAAM,CAAC,IAAI,IAAI,MAAM,GAAG,SAAS,GAAG,WAAW,EAAE,CAAC,CAAC;IACvF,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAClB,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,KAAK,EACtC,MAAc,EACd,KAAa,EACb,SAAqB,EACN,EAAE;IACjB,MAAM,OAAO,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC;IAC5B,OAAO,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC;IAEzC,MAAM,aAAa,GAAG,MAAM,eAAe,CAAC,MAAM,CAAC,CAAC;IACpD,IAAI,CAAC,aAAa,CAAC,EAAE,EAAE,CAAC;QACtB,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACvB,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QACjC,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAC5C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,KAAK,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,MAAM,KAAK,QAAQ,CAC9E,CAAC;IACF,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAC1B,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,4BAA4B,KAAK,EAAE,CAAC,CAAC;QACjD,OAAO;IACT,CAAC;IAED,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IAE7B,MAAM,cAAc,GAAG,MAAM,CAAC,CAAC,OAAO,CAAC;QACrC,OAAO,EAAE,UAAU,KAAK,4CAA4C;KACrE,CAAC,CAAC;IAEH,IAAI,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;QAClD,CAAC,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;QAC/B,OAAO;IACT,CAAC;IAED,OAAO,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;IAEtC,+BAA+B;IAC/B,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IACzC,IAAI,CAAC,UAAU,CAAC,EAAE,EAAE,CAAC;QACnB,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACvB,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QAC9B,OAAO;IACT,CAAC;IAED,MAAM,cAAc,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,gBAAgB,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IAEnE,wBAAwB;IACxB,MAAM,UAAU,GAAG,eAAe,EAAE,CAAC;IAErC,4EAA4E;IAC5E,MAAM,SAAS,GAAG,aAAa,CAAC,IAAI,CAAC,OAAO;SACzC,MAAM,CACL,CAAC,CAAC,EAAE,EAAE,CACJ,CAAC,CAAC,MAAM,KAAK,QAAQ;QACrB,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM;QAC1B,CAAC,CAAC,SAAS,CACd;SACA,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACT,MAAM,SAAS,GAAG,uBAAuB,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,SAAU,CAAC,CAAC,CAAC;QAChF,OAAO;YACL,eAAe,EAAE,CAAC,CAAC,MAAM;YACzB,gBAAgB,EAAE,SAAS,CAAC,YAAY;YACxC,EAAE,EAAE,SAAS,CAAC,EAAE;YAChB,GAAG,EAAE,SAAS,CAAC,GAAG;YAClB,kBAAkB,EAAE,SAAS,CAAC,kBAAkB;SACjD,CAAC;IACJ,CAAC,CAAC,CAAC;IAEL,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,EAAE,SAAS,CAAC,CAAC;IACxF,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACvB,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC1B,OAAO;IACT,CAAC;IAED,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACxB,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,WAAW,KAAK,oCAAoC,cAAc,EAAE,CAAC,CAAC;AACtF,CAAC,CAAC;AAEF,OAAO,EAAE,aAAa,EAAE,CAAC"}
|