@rool-dev/client 0.3.0-dev.54184fd → 0.3.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 +25 -49
- package/dist/auth.d.ts +34 -6
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +326 -34
- package/dist/auth.js.map +1 -1
- package/dist/client.d.ts +1 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +5 -2
- package/dist/client.js.map +1 -1
- package/dist/types.d.ts +7 -9
- package/dist/types.d.ts.map +1 -1
- package/package.json +3 -9
- package/dist/auth-browser.d.ts +0 -70
- package/dist/auth-browser.d.ts.map +0 -1
- package/dist/auth-browser.js +0 -335
- package/dist/auth-browser.js.map +0 -1
- package/dist/auth-node.d.ts +0 -35
- package/dist/auth-node.d.ts.map +0 -1
- package/dist/auth-node.js +0 -270
- package/dist/auth-node.js.map +0 -1
package/dist/auth-node.js
DELETED
|
@@ -1,270 +0,0 @@
|
|
|
1
|
-
import * as http from 'node:http';
|
|
2
|
-
import * as fs from 'node:fs';
|
|
3
|
-
import * as path from 'node:path';
|
|
4
|
-
import * as os from 'node:os';
|
|
5
|
-
import open from 'open';
|
|
6
|
-
const GCIP_REFRESH_ENDPOINT = 'https://securetoken.googleapis.com/v1/token';
|
|
7
|
-
export class NodeAuthProvider {
|
|
8
|
-
config;
|
|
9
|
-
apiKey = null;
|
|
10
|
-
_serverUrl = null;
|
|
11
|
-
constructor(config = {}) {
|
|
12
|
-
this.config = config;
|
|
13
|
-
}
|
|
14
|
-
setServerUrl(url) {
|
|
15
|
-
this._serverUrl = url;
|
|
16
|
-
}
|
|
17
|
-
get credentialsPath() {
|
|
18
|
-
if (this.config.credentialsPath) {
|
|
19
|
-
return this.config.credentialsPath;
|
|
20
|
-
}
|
|
21
|
-
const homeDir = os.homedir();
|
|
22
|
-
const configDir = path.join(homeDir, '.config', 'rool');
|
|
23
|
-
return path.join(configDir, 'credentials.json');
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* Get the base URL for auth endpoints (e.g. https://api.rool.dev/auth).
|
|
27
|
-
* Does NOT include trailing slash.
|
|
28
|
-
*/
|
|
29
|
-
get authEndpoint() {
|
|
30
|
-
// 1. Use explicit authUrl if provided
|
|
31
|
-
if (this.config.authUrl) {
|
|
32
|
-
return this.config.authUrl.replace(/\/+$/, '');
|
|
33
|
-
}
|
|
34
|
-
// 2. Derive from serverUrl
|
|
35
|
-
if (!this._serverUrl) {
|
|
36
|
-
throw new Error('Auth URL not configured and Server URL not set.');
|
|
37
|
-
}
|
|
38
|
-
try {
|
|
39
|
-
const url = new URL(this._serverUrl);
|
|
40
|
-
return `${url.origin}/auth`;
|
|
41
|
-
}
|
|
42
|
-
catch {
|
|
43
|
-
// Fallback for weird inputs
|
|
44
|
-
return `${this._serverUrl.replace(/\/rool-server\/?$/, '')}/auth`;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
initialize() {
|
|
48
|
-
return this.isAuthenticated();
|
|
49
|
-
}
|
|
50
|
-
async getToken() {
|
|
51
|
-
const creds = this.readCredentials();
|
|
52
|
-
if (!creds)
|
|
53
|
-
return undefined;
|
|
54
|
-
// Refresh if expiring in less than 5 minutes
|
|
55
|
-
if (Date.now() >= creds.expires_at - 5 * 60 * 1000) {
|
|
56
|
-
return this.refreshToken(creds);
|
|
57
|
-
}
|
|
58
|
-
return creds.access_token;
|
|
59
|
-
}
|
|
60
|
-
getUser() {
|
|
61
|
-
const creds = this.readCredentials();
|
|
62
|
-
if (!creds?.access_token)
|
|
63
|
-
return { email: null, name: null };
|
|
64
|
-
try {
|
|
65
|
-
const payload = JSON.parse(Buffer.from(creds.access_token.split('.')[1], 'base64').toString());
|
|
66
|
-
return {
|
|
67
|
-
email: payload.email || null,
|
|
68
|
-
name: payload.name || null,
|
|
69
|
-
};
|
|
70
|
-
}
|
|
71
|
-
catch {
|
|
72
|
-
return { email: null, name: null };
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
isAuthenticated() {
|
|
76
|
-
const creds = this.readCredentials();
|
|
77
|
-
if (!creds)
|
|
78
|
-
return false;
|
|
79
|
-
// We consider it authenticated if we have a refresh token,
|
|
80
|
-
// effectively "remember me" behavior for CLI
|
|
81
|
-
return !!creds.refresh_token || Date.now() < creds.expires_at;
|
|
82
|
-
}
|
|
83
|
-
async login() {
|
|
84
|
-
const { server, closeAll } = await this.startLoopbackServer();
|
|
85
|
-
const port = server.address().port;
|
|
86
|
-
const redirectUri = `http://localhost:${port}`;
|
|
87
|
-
// Generate code verifier/state if needed, currently just state
|
|
88
|
-
const state = Math.random().toString(36).substring(2);
|
|
89
|
-
// Auth endpoint is the root of the auth service
|
|
90
|
-
const loginUrl = new URL(`${this.authEndpoint}/`);
|
|
91
|
-
loginUrl.searchParams.set('redirect_uri', redirectUri);
|
|
92
|
-
loginUrl.searchParams.set('state', state);
|
|
93
|
-
console.log('Opening browser to login:', loginUrl.toString());
|
|
94
|
-
await open(loginUrl.toString());
|
|
95
|
-
const timeoutMs = this.config.loginTimeoutMs ?? 5 * 60 * 1000; // 5 minutes default
|
|
96
|
-
return new Promise((resolve, reject) => {
|
|
97
|
-
const timeout = setTimeout(() => {
|
|
98
|
-
closeAll();
|
|
99
|
-
reject(new Error('Login timed out. Please try again.'));
|
|
100
|
-
}, timeoutMs);
|
|
101
|
-
server.on('authenticated', (tokens) => {
|
|
102
|
-
clearTimeout(timeout);
|
|
103
|
-
const expiresAt = Date.now() + (tokens.expires_in * 1000);
|
|
104
|
-
this.writeCredentials({
|
|
105
|
-
access_token: tokens.id_token, // GCIP returns id_token
|
|
106
|
-
refresh_token: tokens.refresh_token,
|
|
107
|
-
expires_at: expiresAt
|
|
108
|
-
});
|
|
109
|
-
this.config.onAuthStateChanged?.(true);
|
|
110
|
-
closeAll();
|
|
111
|
-
resolve();
|
|
112
|
-
});
|
|
113
|
-
server.on('error', (err) => {
|
|
114
|
-
clearTimeout(timeout);
|
|
115
|
-
closeAll();
|
|
116
|
-
reject(err);
|
|
117
|
-
});
|
|
118
|
-
});
|
|
119
|
-
}
|
|
120
|
-
logout() {
|
|
121
|
-
const filePath = this.credentialsPath;
|
|
122
|
-
if (fs.existsSync(filePath)) {
|
|
123
|
-
fs.unlinkSync(filePath);
|
|
124
|
-
}
|
|
125
|
-
this.config.onAuthStateChanged?.(false);
|
|
126
|
-
}
|
|
127
|
-
// ===========================================================================
|
|
128
|
-
// Private Helpers
|
|
129
|
-
// ===========================================================================
|
|
130
|
-
readCredentials() {
|
|
131
|
-
try {
|
|
132
|
-
const filePath = this.credentialsPath;
|
|
133
|
-
if (!fs.existsSync(filePath))
|
|
134
|
-
return null;
|
|
135
|
-
const data = fs.readFileSync(filePath, 'utf-8');
|
|
136
|
-
return JSON.parse(data);
|
|
137
|
-
}
|
|
138
|
-
catch {
|
|
139
|
-
return null;
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
writeCredentials(creds) {
|
|
143
|
-
const filePath = this.credentialsPath;
|
|
144
|
-
const dir = path.dirname(filePath);
|
|
145
|
-
try {
|
|
146
|
-
fs.mkdirSync(dir, { recursive: true });
|
|
147
|
-
fs.writeFileSync(filePath, JSON.stringify(creds, null, 2), { mode: 0o600 });
|
|
148
|
-
}
|
|
149
|
-
catch (error) {
|
|
150
|
-
console.error('[RoolClient] Failed to save credentials:', error);
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
async getApiKey() {
|
|
154
|
-
if (this.apiKey)
|
|
155
|
-
return this.apiKey;
|
|
156
|
-
try {
|
|
157
|
-
const response = await fetch(`${this.authEndpoint}/config.json`);
|
|
158
|
-
if (!response.ok)
|
|
159
|
-
return null;
|
|
160
|
-
const data = await response.json();
|
|
161
|
-
this.apiKey = data.apiKey;
|
|
162
|
-
return this.apiKey;
|
|
163
|
-
}
|
|
164
|
-
catch {
|
|
165
|
-
return null;
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
async refreshToken(creds) {
|
|
169
|
-
if (!creds.refresh_token)
|
|
170
|
-
return undefined;
|
|
171
|
-
const apiKey = await this.getApiKey();
|
|
172
|
-
if (!apiKey) {
|
|
173
|
-
console.warn('[RoolClient] Cannot refresh: API key not found');
|
|
174
|
-
return undefined;
|
|
175
|
-
}
|
|
176
|
-
try {
|
|
177
|
-
const response = await fetch(`${GCIP_REFRESH_ENDPOINT}?key=${apiKey}`, {
|
|
178
|
-
method: 'POST',
|
|
179
|
-
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
180
|
-
body: new URLSearchParams({
|
|
181
|
-
grant_type: 'refresh_token',
|
|
182
|
-
refresh_token: creds.refresh_token,
|
|
183
|
-
}),
|
|
184
|
-
});
|
|
185
|
-
if (!response.ok)
|
|
186
|
-
throw new Error('Refresh failed');
|
|
187
|
-
const data = await response.json();
|
|
188
|
-
const newCreds = {
|
|
189
|
-
access_token: data.id_token || data.access_token,
|
|
190
|
-
refresh_token: data.refresh_token || creds.refresh_token,
|
|
191
|
-
expires_at: Date.now() + (Number(data.expires_in) * 1000),
|
|
192
|
-
};
|
|
193
|
-
this.writeCredentials(newCreds);
|
|
194
|
-
return newCreds.access_token;
|
|
195
|
-
}
|
|
196
|
-
catch (error) {
|
|
197
|
-
console.error('[RoolClient] Refresh failed:', error);
|
|
198
|
-
// Don't auto-logout on network error, but if it's a 400 it might be invalid grant
|
|
199
|
-
return undefined;
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
startLoopbackServer() {
|
|
203
|
-
return new Promise((resolve) => {
|
|
204
|
-
const server = http.createServer((req, res) => {
|
|
205
|
-
const url = new URL(req.url || '/', `http://localhost`);
|
|
206
|
-
// 1. Serve the capture page if we just have a root request
|
|
207
|
-
if (url.pathname === '/') {
|
|
208
|
-
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
209
|
-
res.end(`
|
|
210
|
-
<html>
|
|
211
|
-
<body>
|
|
212
|
-
<h1>Authenticating...</h1>
|
|
213
|
-
<script>
|
|
214
|
-
// Extract hash and post to /callback
|
|
215
|
-
if (window.location.hash) {
|
|
216
|
-
const hash = window.location.hash.substring(1);
|
|
217
|
-
fetch('/callback', {
|
|
218
|
-
method: 'POST',
|
|
219
|
-
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
|
|
220
|
-
body: hash
|
|
221
|
-
})
|
|
222
|
-
.then(() => document.body.innerHTML = '<h1>Login Successful. You can close this window.</h1>')
|
|
223
|
-
.catch(err => document.body.innerHTML = '<h1>Error: ' + err.message + '</h1>');
|
|
224
|
-
}
|
|
225
|
-
</script>
|
|
226
|
-
</body>
|
|
227
|
-
</html>
|
|
228
|
-
`);
|
|
229
|
-
return;
|
|
230
|
-
}
|
|
231
|
-
// 2. Handle the callback POST
|
|
232
|
-
if (url.pathname === '/callback' && req.method === 'POST') {
|
|
233
|
-
let body = '';
|
|
234
|
-
req.on('data', (chunk) => body += chunk.toString());
|
|
235
|
-
req.on('end', () => {
|
|
236
|
-
const params = new URLSearchParams(body);
|
|
237
|
-
const idToken = params.get('id_token');
|
|
238
|
-
const refreshToken = params.get('refresh_token');
|
|
239
|
-
const expiresIn = params.get('expires_in');
|
|
240
|
-
if (idToken && expiresIn) {
|
|
241
|
-
res.writeHead(200);
|
|
242
|
-
res.end('OK');
|
|
243
|
-
server.emit('authenticated', {
|
|
244
|
-
id_token: idToken,
|
|
245
|
-
refresh_token: refreshToken,
|
|
246
|
-
expires_in: Number(expiresIn)
|
|
247
|
-
});
|
|
248
|
-
}
|
|
249
|
-
else {
|
|
250
|
-
res.writeHead(400);
|
|
251
|
-
res.end('Invalid tokens');
|
|
252
|
-
}
|
|
253
|
-
});
|
|
254
|
-
return;
|
|
255
|
-
}
|
|
256
|
-
res.writeHead(404);
|
|
257
|
-
res.end();
|
|
258
|
-
});
|
|
259
|
-
// Listen on random port
|
|
260
|
-
server.listen(0, '127.0.0.1', () => resolve({
|
|
261
|
-
server,
|
|
262
|
-
closeAll: () => {
|
|
263
|
-
server.close();
|
|
264
|
-
server.closeAllConnections();
|
|
265
|
-
},
|
|
266
|
-
}));
|
|
267
|
-
});
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
//# sourceMappingURL=auth-node.js.map
|
package/dist/auth-node.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"auth-node.js","sourceRoot":"","sources":["../src/auth-node.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,IAAI,MAAM,MAAM,CAAC;AAGxB,MAAM,qBAAqB,GAAG,6CAA6C,CAAC;AAkB5E,MAAM,OAAO,gBAAgB;IACjB,MAAM,CAAiB;IACvB,MAAM,GAAkB,IAAI,CAAC;IAC7B,UAAU,GAAkB,IAAI,CAAC;IAEzC,YAAY,SAAyB,EAAE;QACnC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACzB,CAAC;IAED,YAAY,CAAC,GAAW;QACpB,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC;IAC1B,CAAC;IAED,IAAY,eAAe;QACvB,IAAI,IAAI,CAAC,MAAM,CAAC,eAAe,EAAE,CAAC;YAC9B,OAAO,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC;QACvC,CAAC;QACD,MAAM,OAAO,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC;QAC7B,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;QACxD,OAAO,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,kBAAkB,CAAC,CAAC;IACpD,CAAC;IAED;;;OAGG;IACH,IAAY,YAAY;QACpB,sCAAsC;QACtC,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACtB,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACnD,CAAC;QAED,2BAA2B;QAC3B,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;QACvE,CAAC;QAED,IAAI,CAAC;YACD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YACrC,OAAO,GAAG,GAAG,CAAC,MAAM,OAAO,CAAC;QAChC,CAAC;QAAC,MAAM,CAAC;YACL,4BAA4B;YAC5B,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,mBAAmB,EAAE,EAAE,CAAC,OAAO,CAAC;QACtE,CAAC;IACL,CAAC;IAED,UAAU;QACN,OAAO,IAAI,CAAC,eAAe,EAAE,CAAC;IAClC,CAAC;IAED,KAAK,CAAC,QAAQ;QACV,MAAM,KAAK,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC;QACrC,IAAI,CAAC,KAAK;YAAE,OAAO,SAAS,CAAC;QAE7B,6CAA6C;QAC7C,IAAI,IAAI,CAAC,GAAG,EAAE,IAAI,KAAK,CAAC,UAAU,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,EAAE,CAAC;YACjD,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;QACpC,CAAC;QAED,OAAO,KAAK,CAAC,YAAY,CAAC;IAC9B,CAAC;IAED,OAAO;QACH,MAAM,KAAK,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC;QACrC,IAAI,CAAC,KAAK,EAAE,YAAY;YAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;QAE7D,IAAI,CAAC;YACD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;YAC/F,OAAO;gBACH,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,IAAI;gBAC5B,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,IAAI;aAC7B,CAAC;QACN,CAAC;QAAC,MAAM,CAAC;YACL,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;QACvC,CAAC;IACL,CAAC;IAED,eAAe;QACX,MAAM,KAAK,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC;QACrC,IAAI,CAAC,KAAK;YAAE,OAAO,KAAK,CAAC;QACzB,4DAA4D;QAC5D,6CAA6C;QAC7C,OAAO,CAAC,CAAC,KAAK,CAAC,aAAa,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,UAAU,CAAC;IAClE,CAAC;IAED,KAAK,CAAC,KAAK;QACP,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC9D,MAAM,IAAI,GAAI,MAAM,CAAC,OAAO,EAAU,CAAC,IAAI,CAAC;QAC5C,MAAM,WAAW,GAAG,oBAAoB,IAAI,EAAE,CAAC;QAE/C,+DAA+D;QAC/D,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;QAEtD,gDAAgD;QAChD,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,GAAG,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC;QAClD,QAAQ,CAAC,YAAY,CAAC,GAAG,CAAC,cAAc,EAAE,WAAW,CAAC,CAAC;QACvD,QAAQ,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAE1C,OAAO,CAAC,GAAG,CAAC,2BAA2B,EAAE,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC;QAC9D,MAAM,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC;QAEhC,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,cAAc,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,oBAAoB;QAEnF,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACnC,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE;gBAC5B,QAAQ,EAAE,CAAC;gBACX,MAAM,CAAC,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC,CAAC;YAC5D,CAAC,EAAE,SAAS,CAAC,CAAC;YAEd,MAAM,CAAC,EAAE,CAAC,eAAe,EAAE,CAAC,MAAW,EAAE,EAAE;gBACvC,YAAY,CAAC,OAAO,CAAC,CAAC;gBACtB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;gBAC1D,IAAI,CAAC,gBAAgB,CAAC;oBAClB,YAAY,EAAE,MAAM,CAAC,QAAQ,EAAE,wBAAwB;oBACvD,aAAa,EAAE,MAAM,CAAC,aAAa;oBACnC,UAAU,EAAE,SAAS;iBACxB,CAAC,CAAC;gBACH,IAAI,CAAC,MAAM,CAAC,kBAAkB,EAAE,CAAC,IAAI,CAAC,CAAC;gBACvC,QAAQ,EAAE,CAAC;gBACX,OAAO,EAAE,CAAC;YACd,CAAC,CAAC,CAAC;YAEH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAU,EAAE,EAAE;gBAC9B,YAAY,CAAC,OAAO,CAAC,CAAC;gBACtB,QAAQ,EAAE,CAAC;gBACX,MAAM,CAAC,GAAG,CAAC,CAAC;YAChB,CAAC,CAAC,CAAC;QACP,CAAC,CAAC,CAAC;IACP,CAAC;IAED,MAAM;QACF,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC;QACtC,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC1B,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;QAC5B,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,kBAAkB,EAAE,CAAC,KAAK,CAAC,CAAC;IAC5C,CAAC;IAED,8EAA8E;IAC9E,kBAAkB;IAClB,8EAA8E;IAEtE,eAAe;QACnB,IAAI,CAAC;YACD,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC;YACtC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC;gBAAE,OAAO,IAAI,CAAC;YAC1C,MAAM,IAAI,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YAChD,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC;QAAC,MAAM,CAAC;YACL,OAAO,IAAI,CAAC;QAChB,CAAC;IACL,CAAC;IAEO,gBAAgB,CAAC,KAAwB;QAC7C,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC;QACtC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QAEnC,IAAI,CAAC;YACD,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YACvC,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAChF,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,0CAA0C,EAAE,KAAK,CAAC,CAAC;QACrE,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,SAAS;QACnB,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC,MAAM,CAAC;QAEpC,IAAI,CAAC;YACD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,YAAY,cAAc,CAAC,CAAC;YACjE,IAAI,CAAC,QAAQ,CAAC,EAAE;gBAAE,OAAO,IAAI,CAAC;YAC9B,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YACnC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;YAC1B,OAAO,IAAI,CAAC,MAAM,CAAC;QACvB,CAAC;QAAC,MAAM,CAAC;YACL,OAAO,IAAI,CAAC;QAChB,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,YAAY,CAAC,KAAwB;QAC/C,IAAI,CAAC,KAAK,CAAC,aAAa;YAAE,OAAO,SAAS,CAAC;QAE3C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;QACtC,IAAI,CAAC,MAAM,EAAE,CAAC;YACV,OAAO,CAAC,IAAI,CAAC,gDAAgD,CAAC,CAAC;YAC/D,OAAO,SAAS,CAAC;QACrB,CAAC;QAED,IAAI,CAAC;YACD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,qBAAqB,QAAQ,MAAM,EAAE,EAAE;gBACnE,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,EAAE,cAAc,EAAE,mCAAmC,EAAE;gBAChE,IAAI,EAAE,IAAI,eAAe,CAAC;oBACtB,UAAU,EAAE,eAAe;oBAC3B,aAAa,EAAE,KAAK,CAAC,aAAa;iBACrC,CAAC;aACL,CAAC,CAAC;YAEH,IAAI,CAAC,QAAQ,CAAC,EAAE;gBAAE,MAAM,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC;YACpD,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YAEnC,MAAM,QAAQ,GAAsB;gBAChC,YAAY,EAAE,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,YAAY;gBAChD,aAAa,EAAE,IAAI,CAAC,aAAa,IAAI,KAAK,CAAC,aAAa;gBACxD,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC;aAC5D,CAAC;YAEF,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;YAChC,OAAO,QAAQ,CAAC,YAAY,CAAC;QACjC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,8BAA8B,EAAE,KAAK,CAAC,CAAC;YACrD,kFAAkF;YAClF,OAAO,SAAS,CAAC;QACrB,CAAC;IACL,CAAC;IAEO,mBAAmB;QACvB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YAC3B,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC,GAAyB,EAAE,GAAwB,EAAE,EAAE;gBACrF,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,EAAE,kBAAkB,CAAC,CAAC;gBAExD,2DAA2D;gBAC3D,IAAI,GAAG,CAAC,QAAQ,KAAK,GAAG,EAAE,CAAC;oBACvB,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,WAAW,EAAE,CAAC,CAAC;oBACpD,GAAG,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;WAmBjB,CAAC,CAAC;oBACO,OAAO;gBACX,CAAC;gBAED,8BAA8B;gBAC9B,IAAI,GAAG,CAAC,QAAQ,KAAK,WAAW,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;oBACxD,IAAI,IAAI,GAAG,EAAE,CAAC;oBACd,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,IAAI,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;oBAC5D,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;wBACf,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,IAAI,CAAC,CAAC;wBACzC,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;wBACvC,MAAM,YAAY,GAAG,MAAM,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;wBACjD,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;wBAE3C,IAAI,OAAO,IAAI,SAAS,EAAE,CAAC;4BACvB,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;4BACnB,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;4BACd,MAAM,CAAC,IAAI,CAAC,eAAe,EAAE;gCACzB,QAAQ,EAAE,OAAO;gCACjB,aAAa,EAAE,YAAY;gCAC3B,UAAU,EAAE,MAAM,CAAC,SAAS,CAAC;6BAChC,CAAC,CAAC;wBACP,CAAC;6BAAM,CAAC;4BACJ,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;4BACnB,GAAG,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;wBAC9B,CAAC;oBACL,CAAC,CAAC,CAAC;oBACH,OAAO;gBACX,CAAC;gBAED,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;gBACnB,GAAG,CAAC,GAAG,EAAE,CAAC;YACd,CAAC,CAAC,CAAC;YAEH,wBAAwB;YACxB,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,WAAW,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC;gBACxC,MAAM;gBACN,QAAQ,EAAE,GAAG,EAAE;oBACX,MAAM,CAAC,KAAK,EAAE,CAAC;oBACf,MAAM,CAAC,mBAAmB,EAAE,CAAC;gBACjC,CAAC;aACJ,CAAC,CAAC,CAAC;QACR,CAAC,CAAC,CAAC;IACP,CAAC;CACJ"}
|