@ni-c/mcp-hub 0.9.2 → 0.10.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 (59) hide show
  1. package/CHANGELOG.md +231 -0
  2. package/README.md +114 -54
  3. package/dist/admin.js +231 -7
  4. package/dist/admin.js.map +1 -1
  5. package/dist/auth/address.js +89 -0
  6. package/dist/auth/address.js.map +1 -0
  7. package/dist/auth/cimd.js +367 -0
  8. package/dist/auth/cimd.js.map +1 -0
  9. package/dist/auth/consent-page.js +4 -7
  10. package/dist/auth/consent-page.js.map +1 -1
  11. package/dist/auth/login-page.js +4 -7
  12. package/dist/auth/login-page.js.map +1 -1
  13. package/dist/auth/page.js +22 -0
  14. package/dist/auth/page.js.map +1 -1
  15. package/dist/auth/pinned-fetch.js +129 -0
  16. package/dist/auth/pinned-fetch.js.map +1 -0
  17. package/dist/auth/private-key-jwt.js +213 -0
  18. package/dist/auth/private-key-jwt.js.map +1 -0
  19. package/dist/auth/provider.js +102 -45
  20. package/dist/auth/provider.js.map +1 -1
  21. package/dist/auth/rate-limit.js +43 -0
  22. package/dist/auth/rate-limit.js.map +1 -0
  23. package/dist/auth/redirect-uri.js +58 -0
  24. package/dist/auth/redirect-uri.js.map +1 -0
  25. package/dist/auth/registration.js +146 -0
  26. package/dist/auth/registration.js.map +1 -0
  27. package/dist/auth/routes.js +67 -41
  28. package/dist/auth/routes.js.map +1 -1
  29. package/dist/auth/signed-token.js +49 -0
  30. package/dist/auth/signed-token.js.map +1 -0
  31. package/dist/auth/store.js +357 -5
  32. package/dist/auth/store.js.map +1 -1
  33. package/dist/auth/text.js +51 -0
  34. package/dist/auth/text.js.map +1 -0
  35. package/dist/config.js +130 -4
  36. package/dist/config.js.map +1 -1
  37. package/dist/health.js +22 -3
  38. package/dist/health.js.map +1 -1
  39. package/dist/hub.js +28 -0
  40. package/dist/hub.js.map +1 -1
  41. package/dist/index.js +123 -10
  42. package/dist/index.js.map +1 -1
  43. package/dist/proxy.js +25 -3
  44. package/dist/proxy.js.map +1 -1
  45. package/dist/stdio.js +27 -2
  46. package/dist/stdio.js.map +1 -1
  47. package/dist/supervisor.js +152 -8
  48. package/dist/supervisor.js.map +1 -1
  49. package/dist/tool-filter.js +58 -0
  50. package/dist/tool-filter.js.map +1 -0
  51. package/dist/upstream/auth.js +435 -0
  52. package/dist/upstream/auth.js.map +1 -0
  53. package/dist/upstream/login.js +94 -0
  54. package/dist/upstream/login.js.map +1 -0
  55. package/dist/upstream/provider.js +286 -0
  56. package/dist/upstream/provider.js.map +1 -0
  57. package/dist/upstream/routes.js +96 -0
  58. package/dist/upstream/routes.js.map +1 -0
  59. package/package.json +5 -2
package/dist/admin.js CHANGED
@@ -1,16 +1,33 @@
1
1
  #!/usr/bin/env node
2
- import { AuthStore } from './auth/store.js';
2
+ import crypto from 'node:crypto';
3
+ import { AuthStore, clientLimitsFromEnv } from './auth/store.js';
4
+ import { isSafeRedirectUri } from './auth/redirect-uri.js';
5
+ import { clampDisplayName } from './auth/text.js';
6
+ import { isClientIdMetadataUrl } from './auth/cimd.js';
3
7
  import { mintApiToken } from './auth/provider.js';
8
+ import { loadConfig } from './config.js';
9
+ import { authFor, requireOAuthServer, startUpstreamLogin, upstreamStatus } from './upstream/login.js';
4
10
  function usage() {
5
11
  console.error([
6
12
  'Usage:',
7
13
  ' mcp-hub-admin clients list',
8
- ' mcp-hub-admin clients revoke <client-id>',
14
+ ' mcp-hub-admin clients add --name <text> --redirect-uri <uri> [--public]',
15
+ ' mcp-hub-admin clients revoke <client-id> (withdraws access, keeps the registration)',
16
+ ' mcp-hub-admin clients delete <client-id> (removes the registration outright)',
17
+ ' mcp-hub-admin clients prune [--dry-run]',
9
18
  ' mcp-hub-admin tokens create --resource <name|hub> [--days <n>] [--label <text>]',
10
19
  ' mcp-hub-admin tokens list',
11
20
  ' mcp-hub-admin tokens revoke <token-id>',
21
+ ' mcp-hub-admin upstream list',
22
+ ' mcp-hub-admin upstream status <server>',
23
+ ' mcp-hub-admin upstream login <server> [--no-wait]',
24
+ ' mcp-hub-admin upstream register <server> (obtain a client_id without logging in)',
25
+ ' mcp-hub-admin upstream refresh <server> (renew the token now)',
26
+ ' mcp-hub-admin upstream logout <server> (forget it here and revoke it there)',
12
27
  '',
13
- 'tokens create needs EXTERNAL_URL in the environment (same value the hub runs with).'
28
+ 'tokens create needs EXTERNAL_URL in the environment (same value the hub runs with).',
29
+ 'upstream commands read CONFIG_PATH; run them inside the hub container so the',
30
+ 'same mcp.json and the same ${VAR} values are in scope.'
14
31
  ].join('\n'));
15
32
  process.exit(2);
16
33
  }
@@ -25,38 +42,138 @@ function flag(args, name) {
25
42
  }
26
43
  return value;
27
44
  }
45
+ /** How this client came to exist, for `clients list`. */
46
+ function clientOrigin(clientId) {
47
+ if (isClientIdMetadataUrl(clientId))
48
+ return 'cimd';
49
+ return store.isOperatorManaged(clientId) ? 'static' : 'dcr';
50
+ }
28
51
  const [, , group, action, ...rest] = process.argv;
29
- const store = new AuthStore(process.env.DATA_PATH ?? '/data');
52
+ // The same limits the hub runs with, so a prune here removes exactly what the
53
+ // hub would. `docker exec` into the hub container shares its environment.
54
+ const store = new AuthStore(process.env.DATA_PATH ?? '/data', clientLimitsFromEnv());
30
55
  if (group === 'clients' && action === 'list') {
31
56
  const approvals = store.listApprovals();
32
- const rows = Object.entries(store.listClients()).map(([id, client]) => ({
57
+ const clients = store.listClients();
58
+ const rows = Object.entries(clients).map(([id, client]) => ({
33
59
  clientId: id,
34
60
  clientName: client.client_name ?? '',
61
+ via: clientOrigin(id),
35
62
  registeredRedirectUris: client.redirect_uris,
36
63
  approvedRedirectUris: approvals[id]?.redirectUris ?? [],
37
64
  approvedAt: approvals[id] ? new Date(approvals[id].approvedAt * 1000).toISOString() : null
38
65
  }));
66
+ // Metadata-document clients are never stored — the document is fetched fresh
67
+ // on every authorization — so an approval is the only trace they leave. They
68
+ // would otherwise be a blind spot in the one command that answers "who can
69
+ // reach this hub", even though `clients revoke` works on them fine.
70
+ for (const [id, approval] of Object.entries(approvals)) {
71
+ if (clients[id])
72
+ continue;
73
+ rows.push({
74
+ clientId: id,
75
+ clientName: approval.clientName ?? '',
76
+ via: clientOrigin(id),
77
+ registeredRedirectUris: [],
78
+ approvedRedirectUris: approval.redirectUris,
79
+ approvedAt: new Date(approval.approvedAt * 1000).toISOString()
80
+ });
81
+ }
39
82
  console.log(JSON.stringify(rows, null, 2));
40
83
  process.exit(0);
41
84
  }
85
+ if (group === 'clients' && action === 'add') {
86
+ const name = flag(rest, 'name');
87
+ const redirectUri = flag(rest, 'redirect-uri');
88
+ if (!name || !redirectUri)
89
+ usage();
90
+ if (!isSafeRedirectUri(redirectUri, { allowPrivateUseSchemes: true })) {
91
+ console.error(`redirect-uri must be https, a loopback address or a private-use scheme: ${redirectUri}`);
92
+ process.exit(2);
93
+ }
94
+ const isPublic = rest.includes('--public');
95
+ const clientId = crypto.randomBytes(16).toString('base64url');
96
+ const clientSecret = isPublic ? undefined : crypto.randomBytes(32).toString('hex');
97
+ const stored = {
98
+ client_id: clientId,
99
+ client_id_issued_at: Math.floor(Date.now() / 1000),
100
+ client_name: clampDisplayName(name),
101
+ redirect_uris: [redirectUri],
102
+ grant_types: ['authorization_code', 'refresh_token'],
103
+ response_types: ['code'],
104
+ token_endpoint_auth_method: isPublic ? 'none' : 'client_secret_post',
105
+ ...(clientSecret ? { client_secret: clientSecret, client_secret_expires_at: 0 } : {})
106
+ };
107
+ // operatorManaged: exempt from the ceiling and from every expiry rule. A
108
+ // client somebody typed out by hand must not vanish after ninety idle days.
109
+ store.addClient(stored, undefined, { operatorManaged: true });
110
+ // Creating it *is* the approval: the operator named the redirect URI, so
111
+ // sending them through a browser to confirm what they just typed is noise.
112
+ store.saveApproval(clientId, redirectUri, stored.client_name);
113
+ console.error('OAuth client created. This is the only time the secret is shown:');
114
+ console.log(JSON.stringify({ client_id: clientId, ...(clientSecret ? { client_secret: clientSecret } : {}) }, null, 2));
115
+ console.error(JSON.stringify({ clientName: stored.client_name, redirectUri, public: isPublic, approved: true }, null, 2));
116
+ process.exit(0);
117
+ }
42
118
  if (group === 'clients' && action === 'revoke') {
43
119
  const clientId = rest[0];
44
120
  if (!clientId)
45
121
  usage();
122
+ // A metadata-document client has no stored registration, so its approval is
123
+ // what proves it was ever let in.
46
124
  const client = store.getClient(clientId);
47
- if (!client) {
125
+ const approval = store.getApproval(clientId);
126
+ if (!client && !approval) {
48
127
  console.error(`Unknown OAuth client: ${clientId}`);
49
128
  process.exit(1);
50
129
  }
51
130
  const result = store.revokeClientAccess(clientId);
52
131
  console.log(JSON.stringify({
53
132
  clientId,
54
- clientName: client.client_name ?? '',
133
+ clientName: client?.client_name ?? approval?.clientName ?? '',
55
134
  revokedRefreshTokens: result.refreshTokens,
56
135
  revokedAt: new Date(result.revokedBefore).toISOString()
57
136
  }, null, 2));
58
137
  process.exit(0);
59
138
  }
139
+ if (group === 'clients' && action === 'delete') {
140
+ const clientId = rest[0];
141
+ if (!clientId)
142
+ usage();
143
+ const client = store.getClient(clientId);
144
+ const approval = store.getApproval(clientId);
145
+ if (!client && !approval) {
146
+ console.error(`Unknown OAuth client: ${clientId}`);
147
+ process.exit(1);
148
+ }
149
+ // Unlike revoke, this leaves nothing behind: the client would have to
150
+ // register again from scratch.
151
+ store.deleteClient(clientId);
152
+ console.log(JSON.stringify({ clientId, clientName: client?.client_name ?? approval?.clientName ?? '', deleted: true }, null, 2));
153
+ process.exit(0);
154
+ }
155
+ if (group === 'clients' && action === 'prune') {
156
+ const dryRun = rest.includes('--dry-run');
157
+ const limits = store.clientLimits;
158
+ const describe = (ids) => ids.map(id => ({ clientId: id, clientName: store.getClient(id)?.client_name ?? '' }));
159
+ // Read the plan before acting so a dry run and a real run report the same
160
+ // shape, and so the names are still resolvable.
161
+ const planned = store.planClientPrune();
162
+ const report = {
163
+ dryRun,
164
+ limits: {
165
+ maxClients: limits.maxClients,
166
+ pendingTtlHours: limits.pendingTtlSeconds / 3600,
167
+ inactiveDays: limits.inactiveSeconds / 86_400
168
+ },
169
+ neverApproved: describe(planned.pending),
170
+ unused: describe(planned.inactive)
171
+ };
172
+ if (!dryRun)
173
+ store.pruneClients();
174
+ console.log(JSON.stringify(report, null, 2));
175
+ process.exit(0);
176
+ }
60
177
  if (group === 'tokens' && action === 'create') {
61
178
  const externalUrl = process.env.EXTERNAL_URL;
62
179
  if (!externalUrl) {
@@ -107,5 +224,112 @@ if (group === 'tokens' && action === 'revoke') {
107
224
  console.log(JSON.stringify({ id, revoked: true }, null, 2));
108
225
  process.exit(0);
109
226
  }
227
+ if (group === 'upstream') {
228
+ const configPath = process.env.CONFIG_PATH ?? '/config/mcp.json';
229
+ let config;
230
+ try {
231
+ config = loadConfig(configPath);
232
+ }
233
+ catch (error) {
234
+ console.error(`Cannot read ${configPath}: ${error.message}`);
235
+ process.exit(1);
236
+ }
237
+ // The image sets CONFIG_PATH and DATA_PATH but never EXTERNAL_URL, so the
238
+ // value the hub recorded at boot is normally the one that applies.
239
+ const externalUrl = process.env.EXTERNAL_URL ?? store.getExternalUrl();
240
+ const name = rest.find(argument => !argument.startsWith('--'));
241
+ const fail = message => {
242
+ console.error(message);
243
+ process.exit(2);
244
+ };
245
+ if (action === 'list' || action === 'status') {
246
+ try {
247
+ console.log(JSON.stringify(upstreamStatus(store, config, action === 'status' ? name : undefined), null, 2));
248
+ }
249
+ catch (error) {
250
+ fail(error.message);
251
+ }
252
+ process.exit(0);
253
+ }
254
+ if (!name)
255
+ usage();
256
+ if (!externalUrl) {
257
+ console.error('upstream commands need EXTERNAL_URL (the origin the hub runs under), or a hub that has run at least once');
258
+ process.exit(1);
259
+ }
260
+ let auth;
261
+ try {
262
+ auth = authFor(store, new URL(externalUrl).href, name, requireOAuthServer(config, name));
263
+ }
264
+ catch (error) {
265
+ fail(error.message);
266
+ }
267
+ if (action === 'login') {
268
+ let started;
269
+ try {
270
+ started = await startUpstreamLogin(store, auth);
271
+ }
272
+ catch (error) {
273
+ fail(error.message);
274
+ }
275
+ console.error('Open this in a browser that is signed in to the hub:');
276
+ console.log(started.authorizationUrl);
277
+ if (rest.includes('--no-wait'))
278
+ process.exit(0);
279
+ console.error('Waiting for the upstream to redirect back…');
280
+ // The callback lands on the hub, in another process, and writes the tokens
281
+ // to the same state file. Each poll is a stat, so this stays cheap.
282
+ const before = store.getUpstreamCredentials(name, auth.fingerprint)?.obtainedAt ?? 0;
283
+ for (;;) {
284
+ const record = store.getUpstreamCredentials(name, auth.fingerprint);
285
+ if (record?.tokens && record.obtainedAt >= before) {
286
+ console.log(JSON.stringify({ server: name, authorized: true }, null, 2));
287
+ process.exit(0);
288
+ }
289
+ if (Date.now() > started.expiresAt) {
290
+ console.error('The login was not completed in time. Run it again.');
291
+ process.exit(1);
292
+ }
293
+ await new Promise(resolve => setTimeout(resolve, 1_000));
294
+ }
295
+ }
296
+ if (action === 'register') {
297
+ try {
298
+ const discovery = await auth.discover(true);
299
+ const information = await auth.clientInformation(discovery);
300
+ console.log(JSON.stringify({ server: name, clientId: information.client_id }, null, 2));
301
+ }
302
+ catch (error) {
303
+ fail(error.message);
304
+ }
305
+ process.exit(0);
306
+ }
307
+ if (action === 'refresh') {
308
+ try {
309
+ await auth.prepare({ force: true });
310
+ }
311
+ catch (error) {
312
+ fail(error.message);
313
+ }
314
+ const record = store.getUpstreamCredentials(name, auth.fingerprint);
315
+ console.log(JSON.stringify({
316
+ server: name,
317
+ refreshed: true,
318
+ ...(record?.accessTokenValidUntil ? { accessTokenValidUntil: new Date(record.accessTokenValidUntil * 1000).toISOString() } : {})
319
+ }, null, 2));
320
+ process.exit(0);
321
+ }
322
+ if (action === 'logout') {
323
+ // Best effort at the upstream, unconditional locally: a third party being
324
+ // unreachable must never leave a credential behind here.
325
+ const problems = await auth.revokeRemotely().catch(error => [error.message]);
326
+ const forgotten = store.forgetUpstreamCredentials(name);
327
+ for (const problem of problems)
328
+ console.error(`Upstream revocation: ${problem}`);
329
+ console.log(JSON.stringify({ server: name, forgotten, revokedAtUpstream: problems.length === 0 }, null, 2));
330
+ process.exit(problems.length > 0 ? 1 : 0);
331
+ }
332
+ usage();
333
+ }
110
334
  usage();
111
335
  //# sourceMappingURL=admin.js.map
package/dist/admin.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"admin.js","sourceRoot":"","sources":["../src/admin.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"admin.js","sourceRoot":"","sources":["../src/admin.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,89 @@
1
+ import dns from 'node:dns/promises';
2
+ import net from 'node:net';
3
+ /**
4
+ * Which addresses the hub refuses to make an outbound request to, and the
5
+ * resolution step that decides it.
6
+ *
7
+ * Shared by the two places that fetch a URL somebody else chose: a client's
8
+ * metadata document (inbound registration) and an upstream's authorization
9
+ * server (outbound login). In both cases the URL, or a URL derived from a
10
+ * document at that URL, is not the operator's.
11
+ */
12
+ /** RFC 1918/4193/3927/6598 and friends: anything a public host could not
13
+ * legitimately be on, and that the hub can reach from inside. */
14
+ export function isPrivateAddress(address) {
15
+ const version = net.isIP(address);
16
+ if (version === 4) {
17
+ const [a, b, c] = address.split('.').map(Number);
18
+ if (a === 10 || a === 127 || a === 0)
19
+ return true;
20
+ if (a === 169 && b === 254)
21
+ return true; // link-local, incl. cloud metadata
22
+ if (a === 172 && b >= 16 && b <= 31)
23
+ return true;
24
+ if (a === 192 && b === 168)
25
+ return true;
26
+ if (a === 100 && b >= 64 && b <= 127)
27
+ return true; // CGNAT
28
+ if (a === 192 && b === 0 && (c === 0 || c === 2))
29
+ return true; // protocol assignments, TEST-NET-1
30
+ if (a === 198 && (b === 18 || b === 19))
31
+ return true; // benchmarking
32
+ if (a === 198 && b === 51 && c === 100)
33
+ return true; // TEST-NET-2
34
+ if (a === 203 && b === 0 && c === 113)
35
+ return true; // TEST-NET-3
36
+ return a >= 224; // multicast and reserved
37
+ }
38
+ if (version !== 6)
39
+ return true; // not an address we resolved — refuse
40
+ const normalized = address.toLowerCase().replace(/^\[|\]$/g, '');
41
+ if (normalized === '::1' || normalized === '::')
42
+ return true;
43
+ if (normalized.startsWith('fe80') || normalized.startsWith('fec0'))
44
+ return true;
45
+ if (/^f[cd]/.test(normalized))
46
+ return true; // unique local
47
+ // 6to4 and NAT64 carry an IPv4 address that the textual form hides, so the
48
+ // ranges above would never see it — `64:ff9b::a9fe:a9fe` reaches the cloud
49
+ // metadata endpoint. Both prefixes are refused whole: neither is a plausible
50
+ // place for a public host.
51
+ if (normalized.startsWith('2002:'))
52
+ return true; // 6to4 (RFC 3056)
53
+ if (normalized.startsWith('64:ff9b:'))
54
+ return true; // NAT64 (RFC 6052)
55
+ if (normalized.startsWith('::ffff:'))
56
+ return isPrivateAddress(normalized.slice(7));
57
+ return false;
58
+ }
59
+ /**
60
+ * Resolves a hostname and refuses every private or loopback answer, returning
61
+ * the address the connection must then be pinned to.
62
+ *
63
+ * Resolving here and letting `fetch` resolve again would leave the check and
64
+ * the connection looking at two different answers — see pinned-fetch.ts.
65
+ * Undefined means there is nothing to pin: a literal address cannot be
66
+ * re-resolved, and the development escape hatch skips the check entirely.
67
+ */
68
+ export async function resolvePublicAddress(hostname, allowPrivate = false) {
69
+ if (allowPrivate)
70
+ return undefined;
71
+ const literal = hostname.replace(/^\[|\]$/g, '');
72
+ if (net.isIP(literal)) {
73
+ if (isPrivateAddress(literal))
74
+ throw new Error(`${hostname} is a private address`);
75
+ return undefined;
76
+ }
77
+ let addresses;
78
+ try {
79
+ addresses = await dns.lookup(hostname, { all: true });
80
+ }
81
+ catch (error) {
82
+ throw new Error(`cannot resolve ${hostname}: ${error.message}`);
83
+ }
84
+ if (addresses.some(entry => isPrivateAddress(entry.address))) {
85
+ throw new Error(`${hostname} resolves to a private address`);
86
+ }
87
+ return addresses[0]?.address;
88
+ }
89
+ //# sourceMappingURL=address.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"address.js","sourceRoot":"","sources":["../../src/auth/address.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,mBAAmB,CAAC;AACpC,OAAO,GAAG,MAAM,UAAU,CAAC;AAE3B;;;;;;;;GAQG;AAEH;kEACkE;AAClE,MAAM,UAAU,gBAAgB,CAAC,OAAe;IAC9C,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAClC,IAAI,OAAO,KAAK,CAAC,EAAE,CAAC;QAClB,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACjD,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QAClD,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG;YAAE,OAAO,IAAI,CAAC,CAAC,mCAAmC;QAC5E,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE;YAAE,OAAO,IAAI,CAAC;QACjD,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG;YAAE,OAAO,IAAI,CAAC;QACxC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,GAAG;YAAE,OAAO,IAAI,CAAC,CAAC,QAAQ;QAC3D,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC,CAAC,mCAAmC;QAClG,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;YAAE,OAAO,IAAI,CAAC,CAAC,eAAe;QACrE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,GAAG;YAAE,OAAO,IAAI,CAAC,CAAC,aAAa;QAClE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,GAAG;YAAE,OAAO,IAAI,CAAC,CAAC,aAAa;QACjE,OAAO,CAAC,IAAI,GAAG,CAAC,CAAC,yBAAyB;IAC5C,CAAC;IACD,IAAI,OAAO,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC,CAAC,sCAAsC;IACtE,MAAM,UAAU,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IACjE,IAAI,UAAU,KAAK,KAAK,IAAI,UAAU,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAC7D,IAAI,UAAU,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,UAAU,CAAC,UAAU,CAAC,MAAM,CAAC;QAAE,OAAO,IAAI,CAAC;IAChF,IAAI,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC;QAAE,OAAO,IAAI,CAAC,CAAC,eAAe;IAC3D,2EAA2E;IAC3E,2EAA2E;IAC3E,6EAA6E;IAC7E,2BAA2B;IAC3B,IAAI,UAAU,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC,CAAC,kBAAkB;IACnE,IAAI,UAAU,CAAC,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO,IAAI,CAAC,CAAC,mBAAmB;IACvE,IAAI,UAAU,CAAC,UAAU,CAAC,SAAS,CAAC;QAAE,OAAO,gBAAgB,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACnF,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,QAAgB,EAAE,YAAY,GAAG,KAAK;IAC/E,IAAI,YAAY;QAAE,OAAO,SAAS,CAAC;IACnC,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IACjD,IAAI,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QACtB,IAAI,gBAAgB,CAAC,OAAO,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,GAAG,QAAQ,uBAAuB,CAAC,CAAC;QACnF,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,IAAI,SAAgC,CAAC;IACrC,IAAI,CAAC;QACH,SAAS,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;IACxD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,kBAAkB,QAAQ,KAAM,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC;IAC7E,CAAC;IACD,IAAI,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,gBAAgB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC;QAC7D,MAAM,IAAI,KAAK,CAAC,GAAG,QAAQ,gCAAgC,CAAC,CAAC;IAC/D,CAAC;IACD,OAAO,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC;AAC/B,CAAC"}