@structured-world/gitlab-mcp 6.41.4 → 6.42.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.
@@ -0,0 +1,218 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.detectTokenScopes = detectTokenScopes;
4
+ exports.isToolAvailableForScopes = isToolAvailableForScopes;
5
+ exports.getToolsForScopes = getToolsForScopes;
6
+ exports.getToolScopeRequirements = getToolScopeRequirements;
7
+ exports.getTokenCreationUrl = getTokenCreationUrl;
8
+ exports.logTokenScopeInfo = logTokenScopeInfo;
9
+ const zod_1 = require("zod");
10
+ const logger_1 = require("../logger");
11
+ const config_1 = require("../config");
12
+ const fetch_1 = require("../utils/fetch");
13
+ const GITLAB_SCOPES = [
14
+ "api",
15
+ "read_api",
16
+ "read_user",
17
+ "read_repository",
18
+ "write_repository",
19
+ "read_registry",
20
+ "write_registry",
21
+ "sudo",
22
+ "admin_mode",
23
+ "create_runner",
24
+ "manage_runner",
25
+ "ai_features",
26
+ "k8s_proxy",
27
+ ];
28
+ const GitLabScopeSchema = zod_1.z.enum(GITLAB_SCOPES);
29
+ const TokenSelfResponseSchema = zod_1.z.object({
30
+ id: zod_1.z.number(),
31
+ name: zod_1.z.string(),
32
+ scopes: zod_1.z
33
+ .array(zod_1.z.string())
34
+ .transform(arr => arr.filter((s) => GitLabScopeSchema.safeParse(s).success)),
35
+ expires_at: zod_1.z.string().nullable(),
36
+ active: zod_1.z.boolean(),
37
+ revoked: zod_1.z.boolean(),
38
+ });
39
+ const TOOL_SCOPE_REQUIREMENTS = {
40
+ browse_projects: ["api", "read_api"],
41
+ browse_namespaces: ["api", "read_api"],
42
+ browse_commits: ["api", "read_api"],
43
+ browse_events: ["api", "read_api", "read_user"],
44
+ browse_users: ["api", "read_api", "read_user"],
45
+ browse_todos: ["api", "read_api"],
46
+ manage_project: ["api"],
47
+ manage_namespace: ["api"],
48
+ manage_todos: ["api"],
49
+ browse_labels: ["api", "read_api"],
50
+ manage_label: ["api"],
51
+ browse_merge_requests: ["api", "read_api"],
52
+ browse_mr_discussions: ["api", "read_api"],
53
+ manage_merge_request: ["api"],
54
+ manage_mr_discussion: ["api"],
55
+ manage_draft_notes: ["api"],
56
+ browse_files: ["api", "read_api", "read_repository"],
57
+ manage_files: ["api", "write_repository"],
58
+ browse_milestones: ["api", "read_api"],
59
+ manage_milestone: ["api"],
60
+ browse_pipelines: ["api", "read_api"],
61
+ manage_pipeline: ["api"],
62
+ manage_pipeline_job: ["api"],
63
+ browse_variables: ["api", "read_api"],
64
+ manage_variable: ["api"],
65
+ browse_wiki: ["api", "read_api"],
66
+ manage_wiki: ["api"],
67
+ browse_work_items: ["api", "read_api"],
68
+ manage_work_item: ["api"],
69
+ browse_snippets: ["api", "read_api"],
70
+ manage_snippet: ["api"],
71
+ browse_webhooks: ["api", "read_api"],
72
+ manage_webhook: ["api"],
73
+ browse_integrations: ["api", "read_api"],
74
+ manage_integration: ["api"],
75
+ browse_releases: ["api", "read_api"],
76
+ manage_release: ["api"],
77
+ browse_refs: ["api", "read_api"],
78
+ manage_ref: ["api"],
79
+ browse_members: ["api", "read_api"],
80
+ manage_member: ["api"],
81
+ browse_search: ["api", "read_api"],
82
+ browse_iterations: ["api", "read_api"],
83
+ };
84
+ async function detectTokenScopes() {
85
+ if (!config_1.GITLAB_BASE_URL || !config_1.GITLAB_TOKEN) {
86
+ return null;
87
+ }
88
+ try {
89
+ const response = await (0, fetch_1.enhancedFetch)(`${config_1.GITLAB_BASE_URL}/api/v4/personal_access_tokens/self`, {
90
+ headers: {
91
+ "PRIVATE-TOKEN": config_1.GITLAB_TOKEN,
92
+ Accept: "application/json",
93
+ },
94
+ retry: false,
95
+ });
96
+ if (!response.ok) {
97
+ if (response.status === 404) {
98
+ logger_1.logger.debug("Token self-introspection endpoint not available (older GitLab version)");
99
+ return null;
100
+ }
101
+ if (response.status === 401) {
102
+ logger_1.logger.info("Token is invalid or expired");
103
+ return null;
104
+ }
105
+ if (response.status === 403) {
106
+ logger_1.logger.debug("Token self-introspection not permitted for this token type");
107
+ return null;
108
+ }
109
+ logger_1.logger.debug({ status: response.status }, "Unexpected response from token self-introspection");
110
+ return null;
111
+ }
112
+ const raw = await response.json();
113
+ const parsed = TokenSelfResponseSchema.safeParse(raw);
114
+ if (!parsed.success) {
115
+ logger_1.logger.debug({ error: parsed.error.message }, "Token self-introspection response validation failed");
116
+ return null;
117
+ }
118
+ const data = parsed.data;
119
+ const scopes = data.scopes;
120
+ const hasGraphQLAccess = scopes.some(s => s === "api" || s === "read_api");
121
+ const hasWriteAccess = scopes.includes("api");
122
+ let daysUntilExpiry = null;
123
+ if (data.expires_at) {
124
+ const [yearStr, monthStr, dayStr] = data.expires_at.split("-");
125
+ const year = Number(yearStr);
126
+ const month = Number(monthStr);
127
+ const day = Number(dayStr);
128
+ if (!Number.isNaN(year) && !Number.isNaN(month) && !Number.isNaN(day)) {
129
+ const expiryUtcMs = Date.UTC(year, month - 1, day);
130
+ const now = new Date();
131
+ const todayUtcMs = Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate());
132
+ daysUntilExpiry = Math.ceil((expiryUtcMs - todayUtcMs) / (1000 * 60 * 60 * 24));
133
+ }
134
+ }
135
+ const tokenType = "unknown";
136
+ return {
137
+ name: data.name,
138
+ scopes,
139
+ expiresAt: data.expires_at,
140
+ active: data.active && !data.revoked,
141
+ tokenType,
142
+ hasGraphQLAccess,
143
+ hasWriteAccess,
144
+ daysUntilExpiry,
145
+ };
146
+ }
147
+ catch (error) {
148
+ logger_1.logger.debug({ error: error instanceof Error ? error.message : String(error) }, "Token scope detection failed (network error)");
149
+ return null;
150
+ }
151
+ }
152
+ function isToolAvailableForScopes(toolName, scopes) {
153
+ const requiredScopes = TOOL_SCOPE_REQUIREMENTS[toolName];
154
+ if (!requiredScopes) {
155
+ return true;
156
+ }
157
+ return requiredScopes.some(required => scopes.includes(required));
158
+ }
159
+ function getToolsForScopes(scopes) {
160
+ return Object.keys(TOOL_SCOPE_REQUIREMENTS).filter(toolName => isToolAvailableForScopes(toolName, scopes));
161
+ }
162
+ function getToolScopeRequirements() {
163
+ return Object.fromEntries(Object.entries(TOOL_SCOPE_REQUIREMENTS).map(([toolName, scopes]) => [toolName, [...scopes]]));
164
+ }
165
+ function getTokenCreationUrl(baseUrl, scopes = ["api", "read_user"]) {
166
+ try {
167
+ const url = new URL(baseUrl);
168
+ const basePath = url.pathname === "/" ? "" : url.pathname.replace(/\/$/, "");
169
+ url.pathname = `${basePath}/-/user_settings/personal_access_tokens`;
170
+ url.searchParams.set("name", "gitlab-mcp");
171
+ url.searchParams.set("scopes", scopes.join(","));
172
+ return url.toString();
173
+ }
174
+ catch {
175
+ const base = baseUrl.replace(/\/$/, "");
176
+ const params = new URLSearchParams({
177
+ name: "gitlab-mcp",
178
+ scopes: scopes.join(","),
179
+ });
180
+ return `${base}/-/user_settings/personal_access_tokens?${params.toString()}`;
181
+ }
182
+ }
183
+ function logTokenScopeInfo(info, totalTools) {
184
+ const availableTools = getToolsForScopes(info.scopes);
185
+ const scopeList = info.scopes.join(", ");
186
+ if (info.daysUntilExpiry !== null && info.daysUntilExpiry <= 7) {
187
+ if (info.daysUntilExpiry < 0) {
188
+ logger_1.logger.warn({ tokenName: info.name, expiresAt: info.expiresAt }, `Token "${info.name}" has expired! Please create a new token.`);
189
+ }
190
+ else if (info.daysUntilExpiry === 0) {
191
+ logger_1.logger.warn({ tokenName: info.name, expiresAt: info.expiresAt }, `Token "${info.name}" expires today!`);
192
+ }
193
+ else {
194
+ logger_1.logger.warn({ tokenName: info.name, daysUntilExpiry: info.daysUntilExpiry, expiresAt: info.expiresAt }, `Token "${info.name}" expires in ${info.daysUntilExpiry} day(s)`);
195
+ }
196
+ }
197
+ if (info.hasWriteAccess) {
198
+ logger_1.logger.info({
199
+ tokenName: info.name,
200
+ scopes: scopeList,
201
+ expiresAt: info.expiresAt ?? "never",
202
+ }, `Token "${info.name}" detected (scopes: ${scopeList})`);
203
+ }
204
+ else {
205
+ logger_1.logger.info({
206
+ tokenName: info.name,
207
+ scopes: scopeList,
208
+ availableTools: availableTools.length,
209
+ totalTools,
210
+ }, `Token "${info.name}" has limited scopes - ${availableTools.length} of ${totalTools} scope-gated tools available`);
211
+ if (!info.hasGraphQLAccess) {
212
+ logger_1.logger.info("GraphQL introspection skipped (requires 'api' or 'read_api' scope)");
213
+ }
214
+ const fixUrl = getTokenCreationUrl(config_1.GITLAB_BASE_URL);
215
+ logger_1.logger.info({ url: fixUrl }, `For full functionality, create a token with 'api' scope: ${fixUrl}`);
216
+ }
217
+ }
218
+ //# sourceMappingURL=TokenScopeDetector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TokenScopeDetector.js","sourceRoot":"","sources":["../../../src/services/TokenScopeDetector.ts"],"names":[],"mappings":";;AAsLA,8CA0FC;AAKD,4DAUC;AAKD,8CAIC;AAOD,4DAIC;AAKD,kDAqBC;AAKD,8CAwDC;AAhYD,6BAAwB;AACxB,sCAAmC;AACnC,sCAA0D;AAC1D,0CAA+C;AAe/C,MAAM,aAAa,GAAG;IACpB,KAAK;IACL,UAAU;IACV,WAAW;IACX,iBAAiB;IACjB,kBAAkB;IAClB,eAAe;IACf,gBAAgB;IAChB,MAAM;IACN,YAAY;IACZ,eAAe;IACf,eAAe;IACf,aAAa;IACb,WAAW;CACH,CAAC;AAEX,MAAM,iBAAiB,GAAG,OAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;AAOhD,MAAM,uBAAuB,GAAG,OAAC,CAAC,MAAM,CAAC;IACvC,EAAE,EAAE,OAAC,CAAC,MAAM,EAAE;IACd,IAAI,EAAE,OAAC,CAAC,MAAM,EAAE;IAChB,MAAM,EAAE,OAAC;SACN,KAAK,CAAC,OAAC,CAAC,MAAM,EAAE,CAAC;SACjB,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAoB,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IAChG,UAAU,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACjC,MAAM,EAAE,OAAC,CAAC,OAAO,EAAE;IACnB,OAAO,EAAE,OAAC,CAAC,OAAO,EAAE;CACrB,CAAC,CAAC;AA4BH,MAAM,uBAAuB,GAAkC;IAE7D,eAAe,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC;IACpC,iBAAiB,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC;IACtC,cAAc,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC;IACnC,aAAa,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,WAAW,CAAC;IAC/C,YAAY,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,WAAW,CAAC;IAC9C,YAAY,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC;IACjC,cAAc,EAAE,CAAC,KAAK,CAAC;IACvB,gBAAgB,EAAE,CAAC,KAAK,CAAC;IACzB,YAAY,EAAE,CAAC,KAAK,CAAC;IAKrB,aAAa,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC;IAClC,YAAY,EAAE,CAAC,KAAK,CAAC;IAGrB,qBAAqB,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC;IAC1C,qBAAqB,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC;IAC1C,oBAAoB,EAAE,CAAC,KAAK,CAAC;IAC7B,oBAAoB,EAAE,CAAC,KAAK,CAAC;IAC7B,kBAAkB,EAAE,CAAC,KAAK,CAAC;IAG3B,YAAY,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,iBAAiB,CAAC;IACpD,YAAY,EAAE,CAAC,KAAK,EAAE,kBAAkB,CAAC;IAGzC,iBAAiB,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC;IACtC,gBAAgB,EAAE,CAAC,KAAK,CAAC;IAGzB,gBAAgB,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC;IACrC,eAAe,EAAE,CAAC,KAAK,CAAC;IACxB,mBAAmB,EAAE,CAAC,KAAK,CAAC;IAG5B,gBAAgB,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC;IACrC,eAAe,EAAE,CAAC,KAAK,CAAC;IAGxB,WAAW,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC;IAChC,WAAW,EAAE,CAAC,KAAK,CAAC;IAGpB,iBAAiB,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC;IACtC,gBAAgB,EAAE,CAAC,KAAK,CAAC;IAGzB,eAAe,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC;IACpC,cAAc,EAAE,CAAC,KAAK,CAAC;IAGvB,eAAe,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC;IACpC,cAAc,EAAE,CAAC,KAAK,CAAC;IAGvB,mBAAmB,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC;IACxC,kBAAkB,EAAE,CAAC,KAAK,CAAC;IAG3B,eAAe,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC;IACpC,cAAc,EAAE,CAAC,KAAK,CAAC;IAGvB,WAAW,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC;IAChC,UAAU,EAAE,CAAC,KAAK,CAAC;IAGnB,cAAc,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC;IACnC,aAAa,EAAE,CAAC,KAAK,CAAC;IAGtB,aAAa,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC;IAGlC,iBAAiB,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC;CACvC,CAAC;AAeK,KAAK,UAAU,iBAAiB;IACrC,IAAI,CAAC,wBAAe,IAAI,CAAC,qBAAY,EAAE,CAAC;QACtC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,IAAA,qBAAa,EAAC,GAAG,wBAAe,qCAAqC,EAAE;YAC5F,OAAO,EAAE;gBACP,eAAe,EAAE,qBAAY;gBAC7B,MAAM,EAAE,kBAAkB;aAC3B;YACD,KAAK,EAAE,KAAK;SACb,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YAEjB,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;gBAC5B,eAAM,CAAC,KAAK,CAAC,wEAAwE,CAAC,CAAC;gBACvF,OAAO,IAAI,CAAC;YACd,CAAC;YACD,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;gBAC5B,eAAM,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;gBAC3C,OAAO,IAAI,CAAC;YACd,CAAC;YACD,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;gBAE5B,eAAM,CAAC,KAAK,CAAC,4DAA4D,CAAC,CAAC;gBAC3E,OAAO,IAAI,CAAC;YACd,CAAC;YACD,eAAM,CAAC,KAAK,CACV,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,EAC3B,mDAAmD,CACpD,CAAC;YACF,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,GAAG,GAAY,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QAC3C,MAAM,MAAM,GAAG,uBAAuB,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QACtD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,eAAM,CAAC,KAAK,CACV,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,EAC/B,qDAAqD,CACtD,CAAC;YACF,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;QAEzB,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAC3B,MAAM,gBAAgB,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,UAAU,CAAC,CAAC;QAC3E,MAAM,cAAc,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAI9C,IAAI,eAAe,GAAkB,IAAI,CAAC;QAC1C,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,MAAM,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC/D,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;YAC7B,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;YAC/B,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;YAE3B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;gBACtE,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC;gBACnD,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;gBACvB,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,cAAc,EAAE,EAAE,GAAG,CAAC,WAAW,EAAE,EAAE,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC;gBACvF,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,WAAW,GAAG,UAAU,CAAC,GAAG,CAAC,IAAI,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;YAClF,CAAC;QACH,CAAC;QAID,MAAM,SAAS,GAAoB,SAAS,CAAC;QAE7C,OAAO;YACL,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,MAAM;YACN,SAAS,EAAE,IAAI,CAAC,UAAU;YAC1B,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO;YACpC,SAAS;YACT,gBAAgB;YAChB,cAAc;YACd,eAAe;SAChB,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAEf,eAAM,CAAC,KAAK,CACV,EAAE,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,EACjE,8CAA8C,CAC/C,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAKD,SAAgB,wBAAwB,CAAC,QAAgB,EAAE,MAAqB;IAC9E,MAAM,cAAc,GAAG,uBAAuB,CAAC,QAAQ,CAAC,CAAC;IAGzD,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,OAAO,IAAI,CAAC;IACd,CAAC;IAGD,OAAO,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;AACpE,CAAC;AAKD,SAAgB,iBAAiB,CAAC,MAAqB;IACrD,OAAO,MAAM,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAC5D,wBAAwB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAC3C,CAAC;AACJ,CAAC;AAOD,SAAgB,wBAAwB;IACtC,OAAO,MAAM,CAAC,WAAW,CACvB,MAAM,CAAC,OAAO,CAAC,uBAAuB,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAC7F,CAAC;AACJ,CAAC;AAKD,SAAgB,mBAAmB,CACjC,OAAe,EACf,SAAmB,CAAC,KAAK,EAAE,WAAW,CAAC;IAEvC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC;QAE7B,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAC7E,GAAG,CAAC,QAAQ,GAAG,GAAG,QAAQ,yCAAyC,CAAC;QACpE,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;QAC3C,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QACjD,OAAO,GAAG,CAAC,QAAQ,EAAE,CAAC;IACxB,CAAC;IAAC,MAAM,CAAC;QAEP,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACxC,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC;YACjC,IAAI,EAAE,YAAY;YAClB,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;SACzB,CAAC,CAAC;QACH,OAAO,GAAG,IAAI,2CAA2C,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC;IAC/E,CAAC;AACH,CAAC;AAKD,SAAgB,iBAAiB,CAAC,IAAoB,EAAE,UAAkB;IACxE,MAAM,cAAc,GAAG,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACtD,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAGzC,IAAI,IAAI,CAAC,eAAe,KAAK,IAAI,IAAI,IAAI,CAAC,eAAe,IAAI,CAAC,EAAE,CAAC;QAC/D,IAAI,IAAI,CAAC,eAAe,GAAG,CAAC,EAAE,CAAC;YAC7B,eAAM,CAAC,IAAI,CACT,EAAE,SAAS,EAAE,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,EACnD,UAAU,IAAI,CAAC,IAAI,2CAA2C,CAC/D,CAAC;QACJ,CAAC;aAAM,IAAI,IAAI,CAAC,eAAe,KAAK,CAAC,EAAE,CAAC;YACtC,eAAM,CAAC,IAAI,CACT,EAAE,SAAS,EAAE,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,EACnD,UAAU,IAAI,CAAC,IAAI,kBAAkB,CACtC,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,eAAM,CAAC,IAAI,CACT,EAAE,SAAS,EAAE,IAAI,CAAC,IAAI,EAAE,eAAe,EAAE,IAAI,CAAC,eAAe,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,EAC1F,UAAU,IAAI,CAAC,IAAI,gBAAgB,IAAI,CAAC,eAAe,SAAS,CACjE,CAAC;QACJ,CAAC;IACH,CAAC;IAED,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;QAExB,eAAM,CAAC,IAAI,CACT;YACE,SAAS,EAAE,IAAI,CAAC,IAAI;YACpB,MAAM,EAAE,SAAS;YACjB,SAAS,EAAE,IAAI,CAAC,SAAS,IAAI,OAAO;SACrC,EACD,UAAU,IAAI,CAAC,IAAI,uBAAuB,SAAS,GAAG,CACvD,CAAC;IACJ,CAAC;SAAM,CAAC;QAEN,eAAM,CAAC,IAAI,CACT;YACE,SAAS,EAAE,IAAI,CAAC,IAAI;YACpB,MAAM,EAAE,SAAS;YACjB,cAAc,EAAE,cAAc,CAAC,MAAM;YACrC,UAAU;SACX,EACD,UAAU,IAAI,CAAC,IAAI,0BAA0B,cAAc,CAAC,MAAM,OAAO,UAAU,8BAA8B,CAClH,CAAC;QAEF,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC3B,eAAM,CAAC,IAAI,CAAC,oEAAoE,CAAC,CAAC;QACpF,CAAC;QAED,MAAM,MAAM,GAAG,mBAAmB,CAAC,wBAAe,CAAC,CAAC;QACpD,eAAM,CAAC,IAAI,CACT,EAAE,GAAG,EAAE,MAAM,EAAE,EACf,4DAA4D,MAAM,EAAE,CACrE,CAAC;IACJ,CAAC;AACH,CAAC"}