@quantiya/codevibe-claude-plugin 1.0.7 → 1.0.9
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/.claude-plugin/plugin.json +2 -2
- package/README.md +3 -3
- package/dist/server.d.ts +8 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +27 -20
- package/dist/server.js.map +1 -1
- package/hooks/permission-request.sh +6 -3
- package/hooks/stop.sh +15 -10
- package/node_modules/@quantiya/codevibe-core/dist/appsync/appsync-client.js +6 -5
- package/node_modules/@quantiya/codevibe-core/dist/auth/auth-service.d.ts +35 -1
- package/node_modules/@quantiya/codevibe-core/dist/auth/auth-service.js +164 -10
- package/node_modules/@quantiya/codevibe-core/dist/auth/fetch-helpers.d.ts +11 -0
- package/node_modules/@quantiya/codevibe-core/dist/auth/fetch-helpers.js +165 -0
- package/node_modules/@quantiya/codevibe-core/package.json +1 -1
- package/package.json +7 -4
|
@@ -41,11 +41,13 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
41
41
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
42
|
exports.authService = exports.AuthService = void 0;
|
|
43
43
|
const crypto = __importStar(require("crypto"));
|
|
44
|
+
const fs = __importStar(require("fs"));
|
|
44
45
|
const http = __importStar(require("http"));
|
|
45
46
|
const child_process_1 = require("child_process");
|
|
46
47
|
const config_1 = require("../config");
|
|
47
48
|
const keychain_1 = require("../keychain");
|
|
48
49
|
const logger_1 = require("../logger");
|
|
50
|
+
const fetch_helpers_1 = require("./fetch-helpers");
|
|
49
51
|
const CALLBACK_PORT = 8080;
|
|
50
52
|
const CALLBACK_PATH = '/callback';
|
|
51
53
|
const REDIRECT_URI = `http://localhost:${CALLBACK_PORT}${CALLBACK_PATH}`;
|
|
@@ -61,10 +63,154 @@ class AuthService {
|
|
|
61
63
|
return AuthService.instance;
|
|
62
64
|
}
|
|
63
65
|
/**
|
|
64
|
-
* Open URL in default browser
|
|
66
|
+
* Open URL in the user's default browser. Cross-platform: macOS, Linux,
|
|
67
|
+
* WSL, Windows. Always prints the URL to stdout first as a fallback —
|
|
68
|
+
* if no browser-opening command is available, the user can copy-paste.
|
|
69
|
+
*
|
|
70
|
+
* On WSL, prefers opening the Windows host browser via WSL interop
|
|
71
|
+
* (wslview → cmd.exe → powershell.exe) before falling back to xdg-open.
|
|
65
72
|
*/
|
|
66
73
|
openBrowser(url) {
|
|
67
|
-
|
|
74
|
+
// Always print the URL first so users can copy-paste if automatic
|
|
75
|
+
// browser-opening fails (especially important on headless WSL setups).
|
|
76
|
+
console.log('');
|
|
77
|
+
console.log('Opening your browser for sign-in...');
|
|
78
|
+
console.log('If your browser does not open automatically, visit this URL manually:');
|
|
79
|
+
console.log(` ${url}`);
|
|
80
|
+
console.log('');
|
|
81
|
+
const attempts = this.getBrowserCommands();
|
|
82
|
+
this.tryBrowserCommand(attempts, url, 0);
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Returns the list of browser-opening commands to try in order, based on
|
|
86
|
+
* the current platform. On WSL, returns WSL interop commands first so the
|
|
87
|
+
* Windows browser opens (which is what users actually want on WSL).
|
|
88
|
+
*/
|
|
89
|
+
getBrowserCommands() {
|
|
90
|
+
const platform = process.platform;
|
|
91
|
+
if (platform === 'darwin') {
|
|
92
|
+
return [{ cmd: 'open', fixedArgs: [] }];
|
|
93
|
+
}
|
|
94
|
+
if (platform === 'win32') {
|
|
95
|
+
// cmd's start needs an empty title as the first arg so that URLs
|
|
96
|
+
// containing special characters aren't misinterpreted as the title.
|
|
97
|
+
return [{ cmd: 'cmd', fixedArgs: ['/c', 'start', ''] }];
|
|
98
|
+
}
|
|
99
|
+
// Linux or WSL
|
|
100
|
+
const attempts = [];
|
|
101
|
+
if (this.isRunningInWSL()) {
|
|
102
|
+
// Prefer opening the Windows host browser via WSL interop.
|
|
103
|
+
attempts.push({ cmd: 'wslview', fixedArgs: [] });
|
|
104
|
+
attempts.push({ cmd: 'cmd.exe', fixedArgs: ['/c', 'start', ''] });
|
|
105
|
+
attempts.push({
|
|
106
|
+
cmd: 'powershell.exe',
|
|
107
|
+
fixedArgs: ['-NoProfile', '-Command', 'Start-Process'],
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
// Fall back to generic Linux openers
|
|
111
|
+
attempts.push({ cmd: 'xdg-open', fixedArgs: [] });
|
|
112
|
+
return attempts;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Detect whether we're running inside WSL (1 or 2). Returns false on
|
|
116
|
+
* any non-Linux platform or if /proc/sys/kernel/osrelease is not readable.
|
|
117
|
+
*/
|
|
118
|
+
isRunningInWSL() {
|
|
119
|
+
if (process.platform !== 'linux')
|
|
120
|
+
return false;
|
|
121
|
+
try {
|
|
122
|
+
const osRelease = fs.readFileSync('/proc/sys/kernel/osrelease', 'utf8');
|
|
123
|
+
return /microsoft|wsl/i.test(osRelease);
|
|
124
|
+
}
|
|
125
|
+
catch {
|
|
126
|
+
return false;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Try each browser-opening command in order. Advances to the next fallback on:
|
|
131
|
+
* - Spawn failure (ENOENT / the command not being installed)
|
|
132
|
+
* - Synchronous throw from spawn()
|
|
133
|
+
* - Runtime failure where the command spawns but exits with a non-zero
|
|
134
|
+
* code (e.g. wslview when WSL interop is disabled, xdg-open when no
|
|
135
|
+
* default browser is registered, cmd.exe failing to launch start)
|
|
136
|
+
* - Process terminated by signal
|
|
137
|
+
*
|
|
138
|
+
* Stays on the current command when:
|
|
139
|
+
* - Process exits with code 0 (success)
|
|
140
|
+
* - Process is still running after 3 seconds (assumed success — opener
|
|
141
|
+
* is doing real work like launching a slow app, not hung)
|
|
142
|
+
*
|
|
143
|
+
* If all attempts exhaust, logs at debug level — the user still has the
|
|
144
|
+
* sign-in URL printed to stdout as a copy-paste fallback.
|
|
145
|
+
*/
|
|
146
|
+
tryBrowserCommand(attempts, url, index) {
|
|
147
|
+
if (index >= attempts.length) {
|
|
148
|
+
logger_1.logger.debug('[AuthService] No browser-opening command succeeded. ' +
|
|
149
|
+
'User must open the sign-in URL manually (printed to stdout above).');
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
const attempt = attempts[index];
|
|
153
|
+
const args = [...attempt.fixedArgs, url];
|
|
154
|
+
let settled = false;
|
|
155
|
+
// Helper to advance exactly once — guards against both 'error' and 'exit'
|
|
156
|
+
// events firing for the same child, or the timeout racing with an event.
|
|
157
|
+
const advance = (reason) => {
|
|
158
|
+
if (settled)
|
|
159
|
+
return;
|
|
160
|
+
settled = true;
|
|
161
|
+
logger_1.logger.debug(`[AuthService] Browser command '${attempt.cmd}' ${reason}; trying next fallback`);
|
|
162
|
+
this.tryBrowserCommand(attempts, url, index + 1);
|
|
163
|
+
};
|
|
164
|
+
// Helper to mark this attempt as successful so no future event handlers
|
|
165
|
+
// fire tryBrowserCommand on the next index.
|
|
166
|
+
const stopTrying = (reason) => {
|
|
167
|
+
if (settled)
|
|
168
|
+
return;
|
|
169
|
+
settled = true;
|
|
170
|
+
logger_1.logger.debug(`[AuthService] Browser command '${attempt.cmd}' ${reason}`);
|
|
171
|
+
};
|
|
172
|
+
let child;
|
|
173
|
+
try {
|
|
174
|
+
child = (0, child_process_1.spawn)(attempt.cmd, args, {
|
|
175
|
+
detached: true,
|
|
176
|
+
stdio: 'ignore',
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
catch (err) {
|
|
180
|
+
advance(`threw synchronously: ${err?.message || err}`);
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
// Fires when the OS cannot spawn the process at all (most commonly ENOENT
|
|
184
|
+
// for "command not found"). The process never actually ran.
|
|
185
|
+
child.on('error', (err) => {
|
|
186
|
+
advance(`failed to spawn: ${err?.message || err}`);
|
|
187
|
+
});
|
|
188
|
+
// Fires after the spawned process exits. code === 0 is success (opener
|
|
189
|
+
// delegated cleanly and returned). Non-zero code or a signal means the
|
|
190
|
+
// opener failed at runtime — we fall through to the next fallback.
|
|
191
|
+
child.on('exit', (code, signal) => {
|
|
192
|
+
if (code === 0) {
|
|
193
|
+
stopTrying('exited successfully');
|
|
194
|
+
}
|
|
195
|
+
else if (signal) {
|
|
196
|
+
advance(`terminated by signal ${signal}`);
|
|
197
|
+
}
|
|
198
|
+
else {
|
|
199
|
+
advance(`exited with code ${code}`);
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
// If the opener is still running after 3 seconds, it is almost certainly
|
|
203
|
+
// doing real work (launching a slow browser, waiting for Windows interop)
|
|
204
|
+
// rather than hung. Stop trying more fallbacks so we don't spawn multiple
|
|
205
|
+
// browsers. The child keeps running independently because detached:true.
|
|
206
|
+
const timer = setTimeout(() => {
|
|
207
|
+
stopTrying('still running after 3s, assuming success');
|
|
208
|
+
}, 3000);
|
|
209
|
+
// Don't let the timer itself keep the Node event loop alive.
|
|
210
|
+
timer.unref();
|
|
211
|
+
// Detach the child from the parent's event loop so Node doesn't block
|
|
212
|
+
// on its exit. Exit handler still fires if/when the child actually exits.
|
|
213
|
+
child.unref();
|
|
68
214
|
}
|
|
69
215
|
/**
|
|
70
216
|
* Generate state for CSRF protection
|
|
@@ -98,11 +244,11 @@ class AuthService {
|
|
|
98
244
|
code: code,
|
|
99
245
|
redirect_uri: REDIRECT_URI,
|
|
100
246
|
});
|
|
101
|
-
const response = await
|
|
247
|
+
const response = await (0, fetch_helpers_1.fetchWithDiagnostics)(tokenUrl, {
|
|
102
248
|
method: 'POST',
|
|
103
249
|
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
104
250
|
body: params.toString(),
|
|
105
|
-
});
|
|
251
|
+
}, 'Token exchange');
|
|
106
252
|
if (!response.ok) {
|
|
107
253
|
const errorText = await response.text();
|
|
108
254
|
throw new Error(`Token exchange failed: ${response.status} ${errorText}`);
|
|
@@ -135,11 +281,11 @@ class AuthService {
|
|
|
135
281
|
client_id: config.aws.cognitoClientId,
|
|
136
282
|
refresh_token: refreshToken,
|
|
137
283
|
});
|
|
138
|
-
const response = await
|
|
284
|
+
const response = await (0, fetch_helpers_1.fetchWithDiagnostics)(tokenUrl, {
|
|
139
285
|
method: 'POST',
|
|
140
286
|
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
141
287
|
body: params.toString(),
|
|
142
|
-
});
|
|
288
|
+
}, 'Token refresh');
|
|
143
289
|
if (!response.ok) {
|
|
144
290
|
throw new Error(`Token refresh failed: ${response.status}`);
|
|
145
291
|
}
|
|
@@ -209,14 +355,22 @@ class AuthService {
|
|
|
209
355
|
}, 500);
|
|
210
356
|
}
|
|
211
357
|
catch (err) {
|
|
358
|
+
// HTML-escape the error message so newlines and special chars
|
|
359
|
+
// render safely. Multi-line diagnostic messages (from
|
|
360
|
+
// fetchWithDiagnostics) need <pre> to preserve formatting.
|
|
361
|
+
const safeMessage = String(err?.message || err)
|
|
362
|
+
.replace(/&/g, '&')
|
|
363
|
+
.replace(/</g, '<')
|
|
364
|
+
.replace(/>/g, '>');
|
|
212
365
|
res.writeHead(400, { 'Content-Type': 'text/html; charset=utf-8' });
|
|
213
366
|
res.end(`
|
|
214
367
|
<!DOCTYPE html>
|
|
215
368
|
<html>
|
|
216
369
|
<head><title>Error</title></head>
|
|
217
|
-
<body style="font-family: system-ui; max-width:
|
|
218
|
-
<h1 style="color: #ef4444;">✗ Authentication Failed</h1>
|
|
219
|
-
<
|
|
370
|
+
<body style="font-family: system-ui; max-width: 720px; margin: 50px auto; padding: 0 16px;">
|
|
371
|
+
<h1 style="color: #ef4444; text-align: center;">✗ Authentication Failed</h1>
|
|
372
|
+
<pre style="background: #f4f4f5; padding: 16px; border-radius: 8px; white-space: pre-wrap; word-wrap: break-word; font-size: 13px; line-height: 1.5;">${safeMessage}</pre>
|
|
373
|
+
<p style="text-align: center; color: #71717a; margin-top: 24px;">You can close this window and try again in your terminal.</p>
|
|
220
374
|
</body>
|
|
221
375
|
</html>
|
|
222
376
|
`);
|
|
@@ -307,4 +461,4 @@ class AuthService {
|
|
|
307
461
|
}
|
|
308
462
|
exports.AuthService = AuthService;
|
|
309
463
|
exports.authService = AuthService.getInstance();
|
|
310
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXV0aC1zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2F1dGgvYXV0aC1zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxFQUFFO0FBQ0Ysa0JBQWtCO0FBQ2xCLGdCQUFnQjtBQUNoQixFQUFFO0FBQ0YsK0JBQStCO0FBQy9CLEVBQUU7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUVGLCtDQUFpQztBQUNqQywyQ0FBNkI7QUFDN0IsaURBQXNDO0FBQ3RDLHNDQUFzRDtBQUN0RCwwQ0FBOEM7QUFDOUMsc0NBQW1DO0FBR25DLE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQztBQUMzQixNQUFNLGFBQWEsR0FBRyxXQUFXLENBQUM7QUFDbEMsTUFBTSxZQUFZLEdBQUcsb0JBQW9CLGFBQWEsR0FBRyxhQUFhLEVBQUUsQ0FBQztBQUV6RTs7R0FFRztBQUNILE1BQWEsV0FBVztJQUd0QixnQkFBdUIsQ0FBQztJQUV4QixNQUFNLENBQUMsV0FBVztRQUNoQixJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQzFCLFdBQVcsQ0FBQyxRQUFRLEdBQUcsSUFBSSxXQUFXLEVBQUUsQ0FBQztRQUMzQyxDQUFDO1FBQ0QsT0FBTyxXQUFXLENBQUMsUUFBUSxDQUFDO0lBQzlCLENBQUM7SUFFRDs7T0FFRztJQUNLLFdBQVcsQ0FBQyxHQUFXO1FBQzdCLElBQUEscUJBQUssRUFBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUM7SUFDcEUsQ0FBQztJQUVEOztPQUVHO0lBQ0ssYUFBYTtRQUNuQixPQUFPLE1BQU0sQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ2hELENBQUM7SUFFRDs7T0FF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LEtBQUssQ0FBQyxHQUFHLEVBQUUsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztnQkFDcEMsQ0FBQyxFQUFFLEVBQUUsR0FBRyxJQUFJLENBQUMsQ0FBQztZQUNoQixDQUFDLENBQUMsQ0FBQztRQUNMLENBQUM7UUFFRCxPQUFPLE9BQU8sQ0FBQztJQUNqQixDQUFDO0lBRUQ7O09BRUc7SUFDSCxLQUFLLENBQUMsU0FBUztRQUNiLE1BQU0sTUFBTSxHQUFHLE1BQU0sMEJBQWUsQ0FBQyxTQUFTLENBQUMsSUFBQSx1QkFBYyxHQUFFLENBQUMsQ0FBQztRQUNqRSxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDWixPQUFPLEVBQUUsYUFBYSxFQUFFLEtBQUssRUFBRSxDQUFDO1FBQ2xDLENBQUM7UUFFRCxPQUFPO1lBQ0wsYUFBYSxFQUFFLENBQUMsMEJBQWUsQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDO1lBQ3RELE1BQU07U0FDUCxDQUFDO0lBQ0osQ0FBQztDQUNGO0FBeFRELGtDQXdUQztBQUVZLFFBQUEsV0FBVyxHQUFHLFdBQVcsQ0FBQyxXQUFXLEVBQUUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vXG4vLyBhdXRoLXNlcnZpY2UudHNcbi8vIENvZGVWaWJlIENvcmVcbi8vXG4vLyBPQXV0aCBhdXRoZW50aWNhdGlvbiBzZXJ2aWNlXG4vL1xuXG5pbXBvcnQgKiBhcyBjcnlwdG8gZnJvbSAnY3J5cHRvJztcbmltcG9ydCAqIGFzIGh0dHAgZnJvbSAnaHR0cCc7XG5pbXBvcnQgeyBzcGF3biB9IGZyb20gJ2NoaWxkX3Byb2Nlc3MnO1xuaW1wb3J0IHsgZ2V0Q29uZmlnLCBnZXRFbnZpcm9ubWVudCB9IGZyb20gJy4uL2NvbmZpZyc7XG5pbXBvcnQgeyBrZXljaGFpbk1hbmFnZXIgfSBmcm9tICcuLi9rZXljaGFpbic7XG5pbXBvcnQgeyBsb2dnZXIgfSBmcm9tICcuLi9sb2dnZXInO1xuaW1wb3J0IHsgVG9rZW5EYXRhIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5jb25zdCBDQUxMQkFDS19QT1JUID0gODA4MDtcbmNvbnN0IENBTExCQUNLX1BBVEggPSAnL2NhbGxiYWNrJztcbmNvbnN0IFJFRElSRUNUX1VSSSA9IGBodHRwOi8vbG9jYWxob3N0OiR7Q0FMTEJBQ0tfUE9SVH0ke0NBTExCQUNLX1BBVEh9YDtcblxuLyoqXG4gKiBBdXRoZW50aWNhdGlvbiBzZXJ2aWNlIGZvciBPQXV0aCBmbG93c1xuICovXG5leHBvcnQgY2xhc3MgQXV0aFNlcnZpY2Uge1xuICBwcml2YXRlIHN0YXRpYyBpbnN0YW5jZTogQXV0aFNlcnZpY2U7XG5cbiAgcHJpdmF0ZSBjb25zdHJ1Y3RvcigpIHt9XG5cbiAgc3RhdGljIGdldEluc3RhbmNlKCk6IEF1dGhTZXJ2aWNlIHtcbiAgICBpZiAoIUF1dGhTZXJ2aWNlLmluc3RhbmNlKSB7XG4gICAgICBBdXRoU2VydmljZS5pbnN0YW5jZSA9IG5ldyBBdXRoU2VydmljZSgpO1xuICAgIH1cbiAgICByZXR1cm4gQXV0aFNlcnZpY2UuaW5zdGFuY2U7XG4gIH1cblxuICAvKipcbiAgICogT3BlbiBVUkwgaW4gZGVmYXVsdCBicm93c2VyXG4gICAqL1xuICBwcml2YXRlIG9wZW5Ccm93c2VyKHVybDogc3RyaW5nKTogdm9pZCB7XG4gICAgc3Bhd24oJ29wZW4nLCBbdXJsXSwgeyBkZXRhY2hlZDogdHJ1ZSwgc3RkaW86ICdpZ25vcmUnIH0pLnVucmVmKCk7XG4gIH1cblxuICAvKipcbiAgICogR2VuZXJhdGUgc3RhdGUgZm9yIENTUkYgcHJvdGVjdGlvblxuICAgKi9cbiAgcHJpdmF0ZSBnZW5lcmF0ZVN0YXRlKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGNyeXB0by5yYW5kb21CeXRlcygzMikudG9TdHJpbmcoJ2hleCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkIGF1dGhvcml6YXRpb24gVVJMXG4gICAqL1xuICBwcml2YXRlIGJ1aWxkQXV0aFVybChzdGF0ZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBjb25zdCBjb25maWcgPSBnZXRDb25maWcoKTtcbiAgICBjb25zdCBwYXJhbXMgPSBuZXcgVVJMU2VhcmNoUGFyYW1zKHtcbiAgICAgIGNsaWVudF9pZDogY29uZmlnLmF3cy5jb2duaXRvQ2xpZW50SWQsXG4gICAgICByZXNwb25zZV90eXBlOiAnY29kZScsXG4gICAgICBzY29wZTogJ2VtYWlsIG9wZW5pZCBwcm9maWxlJyxcbiAgICAgIHJlZGlyZWN0X3VyaTogUkVESVJFQ1RfVVJJLFxuICAgICAgc3RhdGU6IHN0YXRlLFxuICAgIH0pO1xuXG4gICAgcmV0dXJuIGBodHRwczovLyR7Y29uZmlnLmF3cy5jb2duaXRvRG9tYWlufS9vYXV0aDIvYXV0aG9yaXplPyR7cGFyYW1zLnRvU3RyaW5nKCl9YDtcbiAgfVxuXG4gIC8qKlxuICAgKiBFeGNoYW5nZSBhdXRob3JpemF0aW9uIGNvZGUgZm9yIHRva2Vuc1xuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBleGNoYW5nZUNvZGVGb3JUb2tlbnMoY29kZTogc3RyaW5nKTogUHJvbWlzZTx7XG4gICAgYWNjZXNzVG9rZW46IHN0cmluZztcbiAgICBpZFRva2VuOiBzdHJpbmc7XG4gICAgcmVmcmVzaFRva2VuOiBzdHJpbmc7XG4gICAgZXhwaXJlc0luOiBudW1iZXI7XG4gIH0+IHtcbiAgICBjb25zdCBjb25maWcgPSBnZXRDb25maWcoKTtcbiAgICBjb25zdCB0b2tlblVybCA9IGBodHRwczovLyR7Y29uZmlnLmF3cy5jb2duaXRvRG9tYWlufS9vYXV0aDIvdG9rZW5gO1xuXG4gICAgY29uc3QgcGFyYW1zID0gbmV3IFVSTFNlYXJjaFBhcmFtcyh7XG4gICAgICBncmFudF90eXBlOiAnYXV0aG9yaXphdGlvbl9jb2RlJyxcbiAgICAgIGNsaWVudF9pZDogY29uZmlnLmF3cy5jb2duaXRvQ2xpZW50SWQsXG4gICAgICBjb2RlOiBjb2RlLFxuICAgICAgcmVkaXJlY3RfdXJpOiBSRURJUkVDVF9VUkksXG4gICAgfSk7XG5cbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKHRva2VuVXJsLCB7XG4gICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgIGhlYWRlcnM6IHsgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnIH0sXG4gICAgICBib2R5OiBwYXJhbXMudG9TdHJpbmcoKSxcbiAgICB9KTtcblxuICAgIGlmICghcmVzcG9uc2Uub2spIHtcbiAgICAgIGNvbnN0IGVycm9yVGV4dCA9IGF3YWl0IHJlc3BvbnNlLnRleHQoKTtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVG9rZW4gZXhjaGFuZ2UgZmFpbGVkOiAke3Jlc3BvbnNlLnN0YXR1c30gJHtlcnJvclRleHR9YCk7XG4gICAgfVxuXG4gICAgY29uc3QgZGF0YSA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKSBhcyB7XG4gICAgICBhY2Nlc3NfdG9rZW46IHN0cmluZztcbiAgICAgIGlkX3Rva2VuOiBzdHJpbmc7XG4gICAgICByZWZyZXNoX3Rva2VuOiBzdHJpbmc7XG4gICAgICBleHBpcmVzX2luOiBudW1iZXI7XG4gICAgfTtcblxuICAgIHJldHVybiB7XG4gICAgICBhY2Nlc3NUb2tlbjogZGF0YS5hY2Nlc3NfdG9rZW4sXG4gICAgICBpZFRva2VuOiBkYXRhLmlkX3Rva2VuLFxuICAgICAgcmVmcmVzaFRva2VuOiBkYXRhLnJlZnJlc2hfdG9rZW4sXG4gICAgICBleHBpcmVzSW46IGRhdGEuZXhwaXJlc19pbixcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIERlY29kZSBKV1QgcGF5bG9hZFxuICAgKi9cbiAgcHJpdmF0ZSBkZWNvZGVKd3QodG9rZW46IHN0cmluZyk6IGFueSB7XG4gICAgY29uc3QgcGFydHMgPSB0b2tlbi5zcGxpdCgnLicpO1xuICAgIGlmIChwYXJ0cy5sZW5ndGggIT09IDMpIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBKV1QnKTtcbiAgICByZXR1cm4gSlNPTi5wYXJzZShCdWZmZXIuZnJvbShwYXJ0c1sxXSwgJ2Jhc2U2NCcpLnRvU3RyaW5nKCd1dGYtOCcpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWZyZXNoIHRva2Vuc1xuICAgKi9cbiAgYXN5bmMgcmVmcmVzaFRva2VucyhyZWZyZXNoVG9rZW46IHN0cmluZyk6IFByb21pc2U8e1xuICAgIGFjY2Vzc1Rva2VuOiBzdHJpbmc7XG4gICAgaWRUb2tlbjogc3RyaW5nO1xuICAgIGV4cGlyZXNJbjogbnVtYmVyO1xuICB9PiB7XG4gICAgY29uc3QgY29uZmlnID0gZ2V0Q29uZmlnKCk7XG4gICAgY29uc3QgdG9rZW5VcmwgPSBgaHR0cHM6Ly8ke2NvbmZpZy5hd3MuY29nbml0b0RvbWFpbn0vb2F1dGgyL3Rva2VuYDtcblxuICAgIGNvbnN0IHBhcmFtcyA9IG5ldyBVUkxTZWFyY2hQYXJhbXMoe1xuICAgICAgZ3JhbnRfdHlwZTogJ3JlZnJlc2hfdG9rZW4nLFxuICAgICAgY2xpZW50X2lkOiBjb25maWcuYXdzLmNvZ25pdG9DbGllbnRJZCxcbiAgICAgIHJlZnJlc2hfdG9rZW46IHJlZnJlc2hUb2tlbixcbiAgICB9KTtcblxuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2godG9rZW5VcmwsIHtcbiAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgaGVhZGVyczogeyAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCcgfSxcbiAgICAgIGJvZHk6IHBhcmFtcy50b1N0cmluZygpLFxuICAgIH0pO1xuXG4gICAgaWYgKCFyZXNwb25zZS5vaykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBUb2tlbiByZWZyZXNoIGZhaWxlZDogJHtyZXNwb25zZS5zdGF0dXN9YCk7XG4gICAgfVxuXG4gICAgY29uc3QgZGF0YSA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKSBhcyB7XG4gICAgICBhY2Nlc3NfdG9rZW46IHN0cmluZztcbiAgICAgIGlkX3Rva2VuOiBzdHJpbmc7XG4gICAgICBleHBpcmVzX2luOiBudW1iZXI7XG4gICAgfTtcblxuICAgIHJldHVybiB7XG4gICAgICBhY2Nlc3NUb2tlbjogZGF0YS5hY2Nlc3NfdG9rZW4sXG4gICAgICBpZFRva2VuOiBkYXRhLmlkX3Rva2VuLFxuICAgICAgZXhwaXJlc0luOiBkYXRhLmV4cGlyZXNfaW4sXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMb2dpbiB2aWEgT0F1dGggYnJvd3NlciBmbG93XG4gICAqL1xuICBhc3luYyBsb2dpbigpOiBQcm9taXNlPFRva2VuRGF0YSB8IG51bGw+IHtcbiAgICAvLyBDaGVjayBpZiBhbHJlYWR5IGxvZ2dlZCBpblxuICAgIGNvbnN0IGV4aXN0aW5nID0gYXdhaXQga2V5Y2hhaW5NYW5hZ2VyLmdldFRva2VucyhnZXRFbnZpcm9ubWVudCgpKTtcbiAgICBpZiAoZXhpc3RpbmcgJiYgIWtleWNoYWluTWFuYWdlci5pc1Rva2VuRXhwaXJlZChleGlzdGluZykpIHtcbiAgICAgIHJldHVybiBleGlzdGluZztcbiAgICB9XG5cbiAgICBjb25zdCBzdGF0ZSA9IHRoaXMuZ2VuZXJhdGVTdGF0ZSgpO1xuICAgIGNvbnN0IGF1dGhVcmwgPSB0aGlzLmJ1aWxkQXV0aFVybChzdGF0ZSk7XG5cbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgY29uc3Qgc2VydmVyID0gaHR0cC5jcmVhdGVTZXJ2ZXIoYXN5bmMgKHJlcSwgcmVzKSA9PiB7XG4gICAgICAgIGlmICghcmVxLnVybD8uc3RhcnRzV2l0aChDQUxMQkFDS19QQVRIKSkge1xuICAgICAgICAgIHJlcy53cml0ZUhlYWQoNDA0KTtcbiAgICAgICAgICByZXMuZW5kKCdOb3QgZm91bmQnKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IHVybCA9IG5ldyBVUkwocmVxLnVybCwgYGh0dHA6Ly9sb2NhbGhvc3Q6JHtDQUxMQkFDS19QT1JUfWApO1xuICAgICAgICAgIGNvbnN0IGNvZGUgPSB1cmwuc2VhcmNoUGFyYW1zLmdldCgnY29kZScpO1xuICAgICAgICAgIGNvbnN0IHJldHVybmVkU3RhdGUgPSB1cmwuc2VhcmNoUGFyYW1zLmdldCgnc3RhdGUnKTtcbiAgICAgICAgICBjb25zdCBlcnJvciA9IHVybC5zZWFyY2hQYXJhbXMuZ2V0KCdlcnJvcicpO1xuXG4gICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE9BdXRoIGVycm9yOiAke2Vycm9yfWApO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChyZXR1cm5lZFN0YXRlICE9PSBzdGF0ZSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdTdGF0ZSBtaXNtYXRjaCcpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmICghY29kZSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdObyBhdXRob3JpemF0aW9uIGNvZGUnKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCB0b2tlbnMgPSBhd2FpdCB0aGlzLmV4Y2hhbmdlQ29kZUZvclRva2Vucyhjb2RlKTtcbiAgICAgICAgICBjb25zdCBpZFBheWxvYWQgPSB0aGlzLmRlY29kZUp3dCh0b2tlbnMuaWRUb2tlbik7XG5cbiAgICAgICAgICBjb25zdCB0b2tlbkRhdGE6IFRva2VuRGF0YSA9IHtcbiAgICAgICAgICAgIGFjY2Vzc1Rva2VuOiB0b2tlbnMuYWNjZXNzVG9rZW4sXG4gICAgICAgICAgICBpZFRva2VuOiB0b2tlbnMuaWRUb2tlbixcbiAgICAgICAgICAgIHJlZnJlc2hUb2tlbjogdG9rZW5zLnJlZnJlc2hUb2tlbixcbiAgICAgICAgICAgIGV4cGlyZXNBdDogRGF0ZS5ub3coKSArICh0b2tlbnMuZXhwaXJlc0luICogMTAwMCksXG4gICAgICAgICAgICB1c2VySWQ6IGlkUGF5bG9hZC5zdWIsXG4gICAgICAgICAgICBlbWFpbDogaWRQYXlsb2FkLmVtYWlsIHx8ICd1bmtub3duJyxcbiAgICAgICAgICB9O1xuXG4gICAgICAgICAgYXdhaXQga2V5Y2hhaW5NYW5hZ2VyLnNldFRva2Vucyh0b2tlbkRhdGEsIGdldEVudmlyb25tZW50KCkpO1xuXG4gICAgICAgICAgcmVzLndyaXRlSGVhZCgyMDAsIHsgJ0NvbnRlbnQtVHlwZSc6ICd0ZXh0L2h0bWw7IGNoYXJzZXQ9dXRmLTgnIH0pO1xuICAgICAgICAgIHJlcy5lbmQoYFxuICAgICAgICAgICAgPCFET0NUWVBFIGh0bWw+XG4gICAgICAgICAgICA8aHRtbD5cbiAgICAgICAgICAgIDxoZWFkPjx0aXRsZT5TdWNjZXNzPC90aXRsZT48L2hlYWQ+XG4gICAgICAgICAgICA8Ym9keSBzdHlsZT1cImZvbnQtZmFtaWx5OiBzeXN0ZW0tdWk7IG1heC13aWR0aDogNjAwcHg7IG1hcmdpbjogNTBweCBhdXRvOyB0ZXh0LWFsaWduOiBjZW50ZXI7XCI+XG4gICAgICAgICAgICAgIDxoMSBzdHlsZT1cImNvbG9yOiAjMjJjNTVlO1wiPiYjMTAwMDM7IEF1dGhlbnRpY2F0aW9uIFN1Y2Nlc3NmdWw8L2gxPlxuICAgICAgICAgICAgICA8cD5Zb3UgY2FuIGNsb3NlIHRoaXMgd2luZG93LjwvcD5cbiAgICAgICAgICAgIDwvYm9keT5cbiAgICAgICAgICAgIDwvaHRtbD5cbiAgICAgICAgICBgKTtcblxuICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgc2VydmVyLmNsb3NlKCgpID0+IHJlc29sdmUodG9rZW5EYXRhKSk7XG4gICAgICAgICAgfSwgNTAwKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyOiBhbnkpIHtcbiAgICAgICAgICByZXMud3JpdGVIZWFkKDQwMCwgeyAnQ29udGVudC1UeXBlJzogJ3RleHQvaHRtbDsgY2hhcnNldD11dGYtOCcgfSk7XG4gICAgICAgICAgcmVzLmVuZChgXG4gICAgICAgICAgICA8IURPQ1RZUEUgaHRtbD5cbiAgICAgICAgICAgIDxodG1sPlxuICAgICAgICAgICAgPGhlYWQ+PHRpdGxlPkVycm9yPC90aXRsZT48L2hlYWQ+XG4gICAgICAgICAgICA8Ym9keSBzdHlsZT1cImZvbnQtZmFtaWx5OiBzeXN0ZW0tdWk7IG1heC13aWR0aDogNjAwcHg7IG1hcmdpbjogNTBweCBhdXRvOyB0ZXh0LWFsaWduOiBjZW50ZXI7XCI+XG4gICAgICAgICAgICAgIDxoMSBzdHlsZT1cImNvbG9yOiAjZWY0NDQ0O1wiPiYjMTAwMDc7IEF1dGhlbnRpY2F0aW9uIEZhaWxlZDwvaDE+XG4gICAgICAgICAgICAgIDxwPiR7ZXJyLm1lc3NhZ2V9PC9wPlxuICAgICAgICAgICAgPC9ib2R5PlxuICAgICAgICAgICAgPC9odG1sPlxuICAgICAgICAgIGApO1xuXG4gICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICBzZXJ2ZXIuY2xvc2UoKCkgPT4gcmVqZWN0KGVycikpO1xuICAgICAgICAgIH0sIDUwMCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIub24oJ2Vycm9yJywgKGVycjogYW55KSA9PiB7XG4gICAgICAgIGlmIChlcnIuY29kZSA9PT0gJ0VBRERSSU5VU0UnKSB7XG4gICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcihgUG9ydCAke0NBTExCQUNLX1BPUlR9IGlzIGluIHVzZWApKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZWplY3QoZXJyKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5saXN0ZW4oQ0FMTEJBQ0tfUE9SVCwgJ2xvY2FsaG9zdCcsICgpID0+IHtcbiAgICAgICAgbG9nZ2VyLmluZm8oJ1tBdXRoU2VydmljZV0gQ2FsbGJhY2sgc2VydmVyIHN0YXJ0ZWQnKTtcbiAgICAgICAgdGhpcy5vcGVuQnJvd3NlcihhdXRoVXJsKTtcbiAgICAgIH0pO1xuXG4gICAgICAvLyBUaW1lb3V0XG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgc2VydmVyLmNsb3NlKCgpID0+IHJlamVjdChuZXcgRXJyb3IoJ0xvZ2luIHRpbWVvdXQnKSkpO1xuICAgICAgfSwgMiAqIDYwICogMTAwMCk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogTG9nb3V0XG4gICAqL1xuICBhc3luYyBsb2dvdXQoKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgY29uc3QgY29uZmlnID0gZ2V0Q29uZmlnKCk7XG4gICAgY29uc3QgZGVsZXRlZCA9IGF3YWl0IGtleWNoYWluTWFuYWdlci5kZWxldGVUb2tlbnMoZ2V0RW52aXJvbm1lbnQoKSk7XG5cbiAgICBpZiAoZGVsZXRlZCkge1xuICAgICAgLy8gU3RhcnQgdGVtcG9yYXJ5IHNlcnZlciB0byBoYW5kbGUgc2lnbm91dCBjYWxsYmFja1xuICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgICAgIGNvbnN0IHNlcnZlciA9IGh0dHAuY3JlYXRlU2VydmVyKChyZXEsIHJlcykgPT4ge1xuICAgICAgICAgIGlmIChyZXEudXJsPy5zdGFydHNXaXRoKCcvc2lnbm91dCcpKSB7XG4gICAgICAgICAgICByZXMud3JpdGVIZWFkKDIwMCwgeyAnQ29udGVudC1UeXBlJzogJ3RleHQvaHRtbDsgY2hhcnNldD11dGYtOCcgfSk7XG4gICAgICAgICAgICByZXMuZW5kKGBcbiAgICAgICAgICAgICAgPCFET0NUWVBFIGh0bWw+XG4gICAgICAgICAgICAgIDxodG1sPlxuICAgICAgICAgICAgICA8aGVhZD48dGl0bGU+U2lnbmVkIE91dDwvdGl0bGU+PC9oZWFkPlxuICAgICAgICAgICAgICA8Ym9keSBzdHlsZT1cImZvbnQtZmFtaWx5OiBzeXN0ZW0tdWk7IG1heC13aWR0aDogNjAwcHg7IG1hcmdpbjogNTBweCBhdXRvOyB0ZXh0LWFsaWduOiBjZW50ZXI7XCI+XG4gICAgICAgICAgICAgICAgPGgxIHN0eWxlPVwiY29sb3I6ICMyMmM1NWU7XCI+JiMxMDAwMzsgU2lnbmVkIE91dDwvaDE+XG4gICAgICAgICAgICAgICAgPHA+WW91IGNhbiBjbG9zZSB0aGlzIHdpbmRvdy48L3A+XG4gICAgICAgICAgICAgIDwvYm9keT5cbiAgICAgICAgICAgICAgPC9odG1sPlxuICAgICAgICAgICAgYCk7XG5cbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICBzZXJ2ZXIuY2xvc2UoKCkgPT4gcmVzb2x2ZSh0cnVlKSk7XG4gICAgICAgICAgICB9LCA1MDApO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXMud3JpdGVIZWFkKDQwNCk7XG4gICAgICAgICAgICByZXMuZW5kKCdOb3QgZm91bmQnKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHNlcnZlci5vbignZXJyb3InLCAoKSA9PiB7XG4gICAgICAgICAgcmVzb2x2ZSh0cnVlKTsgLy8gU3RpbGwgcmV0dXJuIHRydWUgc2luY2UgdG9rZW5zIHdlcmUgZGVsZXRlZFxuICAgICAgICB9KTtcblxuICAgICAgICBzZXJ2ZXIubGlzdGVuKENBTExCQUNLX1BPUlQsICdsb2NhbGhvc3QnLCAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgbG9nb3V0VXJsID0gYGh0dHBzOi8vJHtjb25maWcuYXdzLmNvZ25pdG9Eb21haW59L2xvZ291dD9gICtcbiAgICAgICAgICAgIGBjbGllbnRfaWQ9JHtjb25maWcuYXdzLmNvZ25pdG9DbGllbnRJZH0mYCArXG4gICAgICAgICAgICBgbG9nb3V0X3VyaT0ke2VuY29kZVVSSUNvbXBvbmVudChSRURJUkVDVF9VUkkucmVwbGFjZSgnL2NhbGxiYWNrJywgJy9zaWdub3V0JykpfWA7XG5cbiAgICAgICAgICB0aGlzLm9wZW5Ccm93c2VyKGxvZ291dFVybCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFRpbWVvdXQgYWZ0ZXIgMzAgc2Vjb25kc1xuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICBzZXJ2ZXIuY2xvc2UoKCkgPT4gcmVzb2x2ZSh0cnVlKSk7XG4gICAgICAgIH0sIDMwICogMTAwMCk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gZGVsZXRlZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgY3VycmVudCBhdXRoIHN0YXR1c1xuICAgKi9cbiAgYXN5bmMgZ2V0U3RhdHVzKCk6IFByb21pc2U8eyBhdXRoZW50aWNhdGVkOiBib29sZWFuOyB0b2tlbnM/OiBUb2tlbkRhdGEgfT4ge1xuICAgIGNvbnN0IHRva2VucyA9IGF3YWl0IGtleWNoYWluTWFuYWdlci5nZXRUb2tlbnMoZ2V0RW52aXJvbm1lbnQoKSk7XG4gICAgaWYgKCF0b2tlbnMpIHtcbiAgICAgIHJldHVybiB7IGF1dGhlbnRpY2F0ZWQ6IGZhbHNlIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGF1dGhlbnRpY2F0ZWQ6ICFrZXljaGFpbk1hbmFnZXIuaXNUb2tlbkV4cGlyZWQodG9rZW5zKSxcbiAgICAgIHRva2VucyxcbiAgICB9O1xuICB9XG59XG5cbmV4cG9ydCBjb25zdCBhdXRoU2VydmljZSA9IEF1dGhTZXJ2aWNlLmdldEluc3RhbmNlKCk7XG4iXX0=
|
|
464
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXV0aC1zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2F1dGgvYXV0aC1zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxFQUFFO0FBQ0Ysa0JBQWtCO0FBQ2xCLGdCQUFnQjtBQUNoQixFQUFFO0FBQ0YsK0JBQStCO0FBQy9CLEVBQUU7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUVGLCtDQUFpQztBQUNqQyx1Q0FBeUI7QUFDekIsMkNBQTZCO0FBQzdCLGlEQUFzQztBQUN0QyxzQ0FBc0Q7QUFDdEQsMENBQThDO0FBQzlDLHNDQUFtQztBQUVuQyxtREFBdUQ7QUFFdkQsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDO0FBQzNCLE1BQU0sYUFBYSxHQUFHLFdBQVcsQ0FBQztBQUNsQyxNQUFNLFlBQVksR0FBRyxvQkFBb0IsYUFBYSxHQUFHLGFBQWEsRUFBRSxDQUFDO0FBRXpFOztHQUVHO0FBQ0gsTUFBYSxXQUFXO0lBR3RCLGdCQUF1QixDQUFDO0lBRXhCLE1BQU0sQ0FBQyxXQUFXO1FBQ2hCLElBQUksQ0FBQyxXQUFXLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDMUIsV0FBVyxDQUFDLFFBQVEsR0FBRyxJQUFJLFdBQVcsRUFBRSxDQUFDO1FBQzNDLENBQUM7UUFDRCxPQUFPLFdBQVcsQ0FBQyxRQUFRLENBQUM7SUFDOUIsQ0FBQztJQUVEOzs7Ozs7O09BT0c7SUFDSyxXQUFXLENBQUMsR0FBVztRQUM3QixrRUFBa0U7UUFDbEUsdUVBQXVFO1FBQ3ZFLE9BQU8sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDaEIsT0FBTyxDQUFDLEdBQUcsQ0FBQyxxQ0FBcUMsQ0FBQyxDQUFDO1FBQ25ELE9BQU8sQ0FBQyxHQUFHLENBQUMsdUVBQXVFLENBQUMsQ0FBQztRQUNyRixPQUFPLENBQUMsR0FBRyxDQUFDLEtBQUssR0FBRyxFQUFFLENBQUMsQ0FBQztRQUN4QixPQUFP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Q0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO2dCQUNwQyxDQUFDLEVBQUUsRUFBRSxHQUFHLElBQUksQ0FBQyxDQUFDO1lBQ2hCLENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztRQUVELE9BQU8sT0FBTyxDQUFDO0lBQ2pCLENBQUM7SUFFRDs7T0FFRztJQUNILEtBQUssQ0FBQyxTQUFTO1FBQ2IsTUFBTSxNQUFNLEdBQUcsTUFBTSwwQkFBZSxDQUFDLFNBQVMsQ0FBQyxJQUFBLHVCQUFjLEdBQUUsQ0FBQyxDQUFDO1FBQ2pFLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUNaLE9BQU8sRUFBRSxhQUFhLEVBQUUsS0FBSyxFQUFFLENBQUM7UUFDbEMsQ0FBQztRQUVELE9BQU87WUFDTCxhQUFhLEVBQUUsQ0FBQywwQkFBZSxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUM7WUFDdEQsTUFBTTtTQUNQLENBQUM7SUFDSixDQUFDO0NBQ0Y7QUE1ZUQsa0NBNGVDO0FBRVksUUFBQSxXQUFXLEdBQUcsV0FBVyxDQUFDLFdBQVcsRUFBRSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy9cbi8vIGF1dGgtc2VydmljZS50c1xuLy8gQ29kZVZpYmUgQ29yZVxuLy9cbi8vIE9BdXRoIGF1dGhlbnRpY2F0aW9uIHNlcnZpY2Vcbi8vXG5cbmltcG9ydCAqIGFzIGNyeXB0byBmcm9tICdjcnlwdG8nO1xuaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMnO1xuaW1wb3J0ICogYXMgaHR0cCBmcm9tICdodHRwJztcbmltcG9ydCB7IHNwYXduIH0gZnJvbSAnY2hpbGRfcHJvY2Vzcyc7XG5pbXBvcnQgeyBnZXRDb25maWcsIGdldEVudmlyb25tZW50IH0gZnJvbSAnLi4vY29uZmlnJztcbmltcG9ydCB7IGtleWNoYWluTWFuYWdlciB9IGZyb20gJy4uL2tleWNoYWluJztcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gJy4uL2xvZ2dlcic7XG5pbXBvcnQgeyBUb2tlbkRhdGEgfSBmcm9tICcuLi90eXBlcyc7XG5pbXBvcnQgeyBmZXRjaFdpdGhEaWFnbm9zdGljcyB9IGZyb20gJy4vZmV0Y2gtaGVscGVycyc7XG5cbmNvbnN0IENBTExCQUNLX1BPUlQgPSA4MDgwO1xuY29uc3QgQ0FMTEJBQ0tfUEFUSCA9ICcvY2FsbGJhY2snO1xuY29uc3QgUkVESVJFQ1RfVVJJID0gYGh0dHA6Ly9sb2NhbGhvc3Q6JHtDQUxMQkFDS19QT1JUfSR7Q0FMTEJBQ0tfUEFUSH1gO1xuXG4vKipcbiAqIEF1dGhlbnRpY2F0aW9uIHNlcnZpY2UgZm9yIE9BdXRoIGZsb3dzXG4gKi9cbmV4cG9ydCBjbGFzcyBBdXRoU2VydmljZSB7XG4gIHByaXZhdGUgc3RhdGljIGluc3RhbmNlOiBBdXRoU2VydmljZTtcblxuICBwcml2YXRlIGNvbnN0cnVjdG9yKCkge31cblxuICBzdGF0aWMgZ2V0SW5zdGFuY2UoKTogQXV0aFNlcnZpY2Uge1xuICAgIGlmICghQXV0aFNlcnZpY2UuaW5zdGFuY2UpIHtcbiAgICAgIEF1dGhTZXJ2aWNlLmluc3RhbmNlID0gbmV3IEF1dGhTZXJ2aWNlKCk7XG4gICAgfVxuICAgIHJldHVybiBBdXRoU2VydmljZS5pbnN0YW5jZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBPcGVuIFVSTCBpbiB0aGUgdXNlcidzIGRlZmF1bHQgYnJvd3Nlci4gQ3Jvc3MtcGxhdGZvcm06IG1hY09TLCBMaW51eCxcbiAgICogV1NMLCBXaW5kb3dzLiBBbHdheXMgcHJpbnRzIHRoZSBVUkwgdG8gc3Rkb3V0IGZpcnN0IGFzIGEgZmFsbGJhY2sg4oCUXG4gICAqIGlmIG5vIGJyb3dzZXItb3BlbmluZyBjb21tYW5kIGlzIGF2YWlsYWJsZSwgdGhlIHVzZXIgY2FuIGNvcHktcGFzdGUuXG4gICAqXG4gICAqIE9uIFdTTCwgcHJlZmVycyBvcGVuaW5nIHRoZSBXaW5kb3dzIGhvc3QgYnJvd3NlciB2aWEgV1NMIGludGVyb3BcbiAgICogKHdzbHZpZXcg4oaSIGNtZC5leGUg4oaSIHBvd2Vyc2hlbGwuZXhlKSBiZWZvcmUgZmFsbGluZyBiYWNrIHRvIHhkZy1vcGVuLlxuICAgKi9cbiAgcHJpdmF0ZSBvcGVuQnJvd3Nlcih1cmw6IHN0cmluZyk6IHZvaWQge1xuICAgIC8vIEFsd2F5cyBwcmludCB0aGUgVVJMIGZpcnN0IHNvIHVzZXJzIGNhbiBjb3B5LXBhc3RlIGlmIGF1dG9tYXRpY1xuICAgIC8vIGJyb3dzZXItb3BlbmluZyBmYWlscyAoZXNwZWNpYWxseSBpbXBvcnRhbnQgb24gaGVhZGxlc3MgV1NMIHNldHVwcykuXG4gICAgY29uc29sZS5sb2coJycpO1xuICAgIGNvbnNvbGUubG9nKCdPcGVuaW5nIHlvdXIgYnJvd3NlciBmb3Igc2lnbi1pbi4uLicpO1xuICAgIGNvbnNvbGUubG9nKCdJZiB5b3VyIGJyb3dzZXIgZG9lcyBub3Qgb3BlbiBhdXRvbWF0aWNhbGx5LCB2aXNpdCB0aGlzIFVSTCBtYW51YWxseTonKTtcbiAgICBjb25zb2xlLmxvZyhgICAke3VybH1gKTtcbiAgICBjb25zb2xlLmxvZygnJyk7XG5cbiAgICBjb25zdCBhdHRlbXB0cyA9IHRoaXMuZ2V0QnJvd3NlckNvbW1hbmRzKCk7XG4gICAgdGhpcy50cnlCcm93c2VyQ29tbWFuZChhdHRlbXB0cywgdXJsLCAwKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBsaXN0IG9mIGJyb3dzZXItb3BlbmluZyBjb21tYW5kcyB0byB0cnkgaW4gb3JkZXIsIGJhc2VkIG9uXG4gICAqIHRoZSBjdXJyZW50IHBsYXRmb3JtLiBPbiBXU0wsIHJldHVybnMgV1NMIGludGVyb3AgY29tbWFuZHMgZmlyc3Qgc28gdGhlXG4gICAqIFdpbmRvd3MgYnJvd3NlciBvcGVucyAod2hpY2ggaXMgd2hhdCB1c2VycyBhY3R1YWxseSB3YW50IG9uIFdTTCkuXG4gICAqL1xuICBwcml2YXRlIGdldEJyb3dzZXJDb21tYW5kcygpOiBBcnJheTx7IGNtZDogc3RyaW5nOyBmaXhlZEFyZ3M6IHN0cmluZ1tdIH0+IHtcbiAgICBjb25zdCBwbGF0Zm9ybSA9IHByb2Nlc3MucGxhdGZvcm07XG5cbiAgICBpZiAocGxhdGZvcm0gPT09ICdkYXJ3aW4nKSB7XG4gICAgICByZXR1cm4gW3sgY21kOiAnb3BlbicsIGZpeGVkQXJnczogW10gfV07XG4gICAgfVxuXG4gICAgaWYgKHBsYXRmb3JtID09PSAnd2luMzInKSB7XG4gICAgICAvLyBjbWQncyBzdGFydCBuZWVkcyBhbiBlbXB0eSB0aXRsZSBhcyB0aGUgZmlyc3QgYXJnIHNvIHRoYXQgVVJMc1xuICAgICAgLy8gY29udGFpbmluZyBzcGVjaWFsIGNoYXJhY3RlcnMgYXJlbid0IG1pc2ludGVycHJldGVkIGFzIHRoZSB0aXRsZS5cbiAgICAgIHJldHVybiBbeyBjbWQ6ICdjbWQnLCBmaXhlZEFyZ3M6IFsnL2MnLCAnc3RhcnQnLCAnJ10gfV07XG4gICAgfVxuXG4gICAgLy8gTGludXggb3IgV1NMXG4gICAgY29uc3QgYXR0ZW1wdHM6IEFycmF5PHsgY21kOiBzdHJpbmc7IGZpeGVkQXJnczogc3RyaW5nW10gfT4gPSBbXTtcblxuICAgIGlmICh0aGlzLmlzUnVubmluZ0luV1NMKCkpIHtcbiAgICAgIC8vIFByZWZlciBvcGVuaW5nIHRoZSBXaW5kb3dzIGhvc3QgYnJvd3NlciB2aWEgV1NMIGludGVyb3AuXG4gICAgICBhdHRlbXB0cy5wdXNoKHsgY21kOiAnd3NsdmlldycsIGZpeGVkQXJnczogW10gfSk7XG4gICAgICBhdHRlbXB0cy5wdXNoKHsgY21kOiAnY21kLmV4ZScsIGZpeGVkQXJnczogWycvYycsICdzdGFydCcsICcnXSB9KTtcbiAgICAgIGF0dGVtcHRzLnB1c2goe1xuICAgICAgICBjbWQ6ICdwb3dlcnNoZWxsLmV4ZScsXG4gICAgICAgIGZpeGVkQXJnczogWyctTm9Qcm9maWxlJywgJy1Db21tYW5kJywgJ1N0YXJ0LVByb2Nlc3MnXSxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIEZhbGwgYmFjayB0byBnZW5lcmljIExpbnV4IG9wZW5lcnNcbiAgICBhdHRlbXB0cy5wdXNoKHsgY21kOiAneGRnLW9wZW4nLCBmaXhlZEFyZ3M6IFtdIH0pO1xuXG4gICAgcmV0dXJuIGF0dGVtcHRzO1xuICB9XG5cbiAgLyoqXG4gICAqIERldGVjdCB3aGV0aGVyIHdlJ3JlIHJ1bm5pbmcgaW5zaWRlIFdTTCAoMSBvciAyKS4gUmV0dXJucyBmYWxzZSBvblxuICAgKiBhbnkgbm9uLUxpbnV4IHBsYXRmb3JtIG9yIGlmIC9wcm9jL3N5cy9rZXJuZWwvb3NyZWxlYXNlIGlzIG5vdCByZWFkYWJsZS5cbiAgICovXG4gIHByaXZhdGUgaXNSdW5uaW5nSW5XU0woKTogYm9vbGVhbiB7XG4gICAgaWYgKHByb2Nlc3MucGxhdGZvcm0gIT09ICdsaW51eCcpIHJldHVybiBmYWxzZTtcbiAgICB0cnkge1xuICAgICAgY29uc3Qgb3NSZWxlYXNlID0gZnMucmVhZEZpbGVTeW5jKCcvcHJvYy9zeXMva2VybmVsL29zcmVsZWFzZScsICd1dGY4Jyk7XG4gICAgICByZXR1cm4gL21pY3Jvc29mdHx3c2wvaS50ZXN0KG9zUmVsZWFzZSk7XG4gICAgfSBjYXRjaCB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFRyeSBlYWNoIGJyb3dzZXItb3BlbmluZyBjb21tYW5kIGluIG9yZGVyLiBBZHZhbmNlcyB0byB0aGUgbmV4dCBmYWxsYmFjayBvbjpcbiAgICogICAtIFNwYXduIGZhaWx1cmUgKEVOT0VOVCAvIHRoZSBjb21tYW5kIG5vdCBiZWluZyBpbnN0YWxsZWQpXG4gICAqICAgLSBTeW5jaHJvbm91cyB0aHJvdyBmcm9tIHNwYXduKClcbiAgICogICAtIFJ1bnRpbWUgZmFpbHVyZSB3aGVyZSB0aGUgY29tbWFuZCBzcGF3bnMgYnV0IGV4aXRzIHdpdGggYSBub24temVyb1xuICAgKiAgICAgY29kZSAoZS5nLiB3c2x2aWV3IHdoZW4gV1NMIGludGVyb3AgaXMgZGlzYWJsZWQsIHhkZy1vcGVuIHdoZW4gbm9cbiAgICogICAgIGRlZmF1bHQgYnJvd3NlciBpcyByZWdpc3RlcmVkLCBjbWQuZXhlIGZhaWxpbmcgdG8gbGF1bmNoIHN0YXJ0KVxuICAgKiAgIC0gUHJvY2VzcyB0ZXJtaW5hdGVkIGJ5IHNpZ25hbFxuICAgKlxuICAgKiBTdGF5cyBvbiB0aGUgY3VycmVudCBjb21tYW5kIHdoZW46XG4gICAqICAgLSBQcm9jZXNzIGV4aXRzIHdpdGggY29kZSAwIChzdWNjZXNzKVxuICAgKiAgIC0gUHJvY2VzcyBpcyBzdGlsbCBydW5uaW5nIGFmdGVyIDMgc2Vjb25kcyAoYXNzdW1lZCBzdWNjZXNzIOKAlCBvcGVuZXJcbiAgICogICAgIGlzIGRvaW5nIHJlYWwgd29yayBsaWtlIGxhdW5jaGluZyBhIHNsb3cgYXBwLCBub3QgaHVuZylcbiAgICpcbiAgICogSWYgYWxsIGF0dGVtcHRzIGV4aGF1c3QsIGxvZ3MgYXQgZGVidWcgbGV2ZWwg4oCUIHRoZSB1c2VyIHN0aWxsIGhhcyB0aGVcbiAgICogc2lnbi1pbiBVUkwgcHJpbnRlZCB0byBzdGRvdXQgYXMgYSBjb3B5LXBhc3RlIGZhbGxiYWNrLlxuICAgKi9cbiAgcHJpdmF0ZSB0cnlCcm93c2VyQ29tbWFuZChcbiAgICBhdHRlbXB0czogQXJyYXk8eyBjbWQ6IHN0cmluZzsgZml4ZWRBcmdzOiBzdHJpbmdbXSB9PixcbiAgICB1cmw6IHN0cmluZyxcbiAgICBpbmRleDogbnVtYmVyXG4gICk6IHZvaWQge1xuICAgIGlmIChpbmRleCA+PSBhdHRlbXB0cy5sZW5ndGgpIHtcbiAgICAgIGxvZ2dlci5kZWJ1ZyhcbiAgICAgICAgJ1tBdXRoU2VydmljZV0gTm8gYnJvd3Nlci1vcGVuaW5nIGNvbW1hbmQgc3VjY2VlZGVkLiAnICtcbiAgICAgICAgICAnVXNlciBtdXN0IG9wZW4gdGhlIHNpZ24taW4gVVJMIG1hbnVhbGx5IChwcmludGVkIHRvIHN0ZG91dCBhYm92ZSkuJ1xuICAgICAgKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBhdHRlbXB0ID0gYXR0ZW1wdHNbaW5kZXhdO1xuICAgIGNvbnN0IGFyZ3MgPSBbLi4uYXR0ZW1wdC5maXhlZEFyZ3MsIHVybF07XG4gICAgbGV0IHNldHRsZWQgPSBmYWxzZTtcblxuICAgIC8vIEhlbHBlciB0byBhZHZhbmNlIGV4YWN0bHkgb25jZSDigJQgZ3VhcmRzIGFnYWluc3QgYm90aCAnZXJyb3InIGFuZCAnZXhpdCdcbiAgICAvLyBldmVudHMgZmlyaW5nIGZvciB0aGUgc2FtZSBjaGlsZCwgb3IgdGhlIHRpbWVvdXQgcmFjaW5nIHdpdGggYW4gZXZlbnQuXG4gICAgY29uc3QgYWR2YW5jZSA9IChyZWFzb246IHN0cmluZykgPT4ge1xuICAgICAgaWYgKHNldHRsZWQpIHJldHVybjtcbiAgICAgIHNldHRsZWQgPSB0cnVlO1xuICAgICAgbG9nZ2VyLmRlYnVnKFxuICAgICAgICBgW0F1dGhTZXJ2aWNlXSBCcm93c2VyIGNvbW1hbmQgJyR7YXR0ZW1wdC5jbWR9JyAke3JlYXNvbn07IHRyeWluZyBuZXh0IGZhbGxiYWNrYFxuICAgICAgKTtcbiAgICAgIHRoaXMudHJ5QnJvd3NlckNvbW1hbmQoYXR0ZW1wdHMsIHVybCwgaW5kZXggKyAxKTtcbiAgICB9O1xuXG4gICAgLy8gSGVscGVyIHRvIG1hcmsgdGhpcyBhdHRlbXB0IGFzIHN1Y2Nlc3NmdWwgc28gbm8gZnV0dXJlIGV2ZW50IGhhbmRsZXJzXG4gICAgLy8gZmlyZSB0cnlCcm93c2VyQ29tbWFuZCBvbiB0aGUgbmV4dCBpbmRleC5cbiAgICBjb25zdCBzdG9wVHJ5aW5nID0gKHJlYXNvbjogc3RyaW5nKSA9PiB7XG4gICAgICBpZiAoc2V0dGxlZCkgcmV0dXJuO1xuICAgICAgc2V0dGxlZCA9IHRydWU7XG4gICAgICBsb2dnZXIuZGVidWcoYFtBdXRoU2VydmljZV0gQnJvd3NlciBjb21tYW5kICcke2F0dGVtcHQuY21kfScgJHtyZWFzb259YCk7XG4gICAgfTtcblxuICAgIGxldCBjaGlsZDtcbiAgICB0cnkge1xuICAgICAgY2hpbGQgPSBzcGF3bihhdHRlbXB0LmNtZCwgYXJncywge1xuICAgICAgICBkZXRhY2hlZDogdHJ1ZSxcbiAgICAgICAgc3RkaW86ICdpZ25vcmUnLFxuICAgICAgfSk7XG4gICAgfSBjYXRjaCAoZXJyOiBhbnkpIHtcbiAgICAgIGFkdmFuY2UoYHRocmV3IHN5bmNocm9ub3VzbHk6ICR7ZXJyPy5tZXNzYWdlIHx8IGVycn1gKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBGaXJlcyB3aGVuIHRoZSBPUyBjYW5ub3Qgc3Bhd24gdGhlIHByb2Nlc3MgYXQgYWxsIChtb3N0IGNvbW1vbmx5IEVOT0VOVFxuICAgIC8vIGZvciBcImNvbW1hbmQgbm90IGZvdW5kXCIpLiBUaGUgcHJvY2VzcyBuZXZlciBhY3R1YWxseSByYW4uXG4gICAgY2hpbGQub24oJ2Vycm9yJywgKGVycjogYW55KSA9PiB7XG4gICAgICBhZHZhbmNlKGBmYWlsZWQgdG8gc3Bhd246ICR7ZXJyPy5tZXNzYWdlIHx8IGVycn1gKTtcbiAgICB9KTtcblxuICAgIC8vIEZpcmVzIGFmdGVyIHRoZSBzcGF3bmVkIHByb2Nlc3MgZXhpdHMuIGNvZGUgPT09IDAgaXMgc3VjY2VzcyAob3BlbmVyXG4gICAgLy8gZGVsZWdhdGVkIGNsZWFubHkgYW5kIHJldHVybmVkKS4gTm9uLXplcm8gY29kZSBvciBhIHNpZ25hbCBtZWFucyB0aGVcbiAgICAvLyBvcGVuZXIgZmFpbGVkIGF0IHJ1bnRpbWUg4oCUIHdlIGZhbGwgdGhyb3VnaCB0byB0aGUgbmV4dCBmYWxsYmFjay5cbiAgICBjaGlsZC5vbignZXhpdCcsIChjb2RlOiBudW1iZXIgfCBudWxsLCBzaWduYWw6IHN0cmluZyB8IG51bGwpID0+IHtcbiAgICAgIGlmIChjb2RlID09PSAwKSB7XG4gICAgICAgIHN0b3BUcnlpbmcoJ2V4aXRlZCBzdWNjZXNzZnVsbHknKTtcbiAgICAgIH0gZWxzZSBpZiAoc2lnbmFsKSB7XG4gICAgICAgIGFkdmFuY2UoYHRlcm1pbmF0ZWQgYnkgc2lnbmFsICR7c2lnbmFsfWApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYWR2YW5jZShgZXhpdGVkIHdpdGggY29kZSAke2NvZGV9YCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICAvLyBJZiB0aGUgb3BlbmVyIGlzIHN0aWxsIHJ1bm5pbmcgYWZ0ZXIgMyBzZWNvbmRzLCBpdCBpcyBhbG1vc3QgY2VydGFpbmx5XG4gICAgLy8gZG9pbmcgcmVhbCB3b3JrIChsYXVuY2hpbmcgYSBzbG93IGJyb3dzZXIsIHdhaXRpbmcgZm9yIFdpbmRvd3MgaW50ZXJvcClcbiAgICAvLyByYXRoZXIgdGhhbiBodW5nLiBTdG9wIHRyeWluZyBtb3JlIGZhbGxiYWNrcyBzbyB3ZSBkb24ndCBzcGF3biBtdWx0aXBsZVxuICAgIC8vIGJyb3dzZXJzLiBUaGUgY2hpbGQga2VlcHMgcnVubmluZyBpbmRlcGVuZGVudGx5IGJlY2F1c2UgZGV0YWNoZWQ6dHJ1ZS5cbiAgICBjb25zdCB0aW1lciA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgc3RvcFRyeWluZygnc3RpbGwgcnVubmluZyBhZnRlciAzcywgYXNzdW1pbmcgc3VjY2VzcycpO1xuICAgIH0sIDMwMDApO1xuICAgIC8vIERvbid0IGxldCB0aGUgdGltZXIgaXRzZWxmIGtlZXAgdGhlIE5vZGUgZXZlbnQgbG9vcCBhbGl2ZS5cbiAgICB0aW1lci51bnJlZigpO1xuXG4gICAgLy8gRGV0YWNoIHRoZSBjaGlsZCBmcm9tIHRoZSBwYXJlbnQncyBldmVudCBsb29wIHNvIE5vZGUgZG9lc24ndCBibG9ja1xuICAgIC8vIG9uIGl0cyBleGl0LiBFeGl0IGhhbmRsZXIgc3RpbGwgZmlyZXMgaWYvd2hlbiB0aGUgY2hpbGQgYWN0dWFsbHkgZXhpdHMuXG4gICAgY2hpbGQudW5yZWYoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZW5lcmF0ZSBzdGF0ZSBmb3IgQ1NSRiBwcm90ZWN0aW9uXG4gICAqL1xuICBwcml2YXRlIGdlbmVyYXRlU3RhdGUoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gY3J5cHRvLnJhbmRvbUJ5dGVzKDMyKS50b1N0cmluZygnaGV4Jyk7XG4gIH1cblxuICAvKipcbiAgICogQnVpbGQgYXV0aG9yaXphdGlvbiBVUkxcbiAgICovXG4gIHByaXZhdGUgYnVpbGRBdXRoVXJsKHN0YXRlOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGNvbnN0IGNvbmZpZyA9IGdldENvbmZpZygpO1xuICAgIGNvbnN0IHBhcmFtcyA9IG5ldyBVUkxTZWFyY2hQYXJhbXMoe1xuICAgICAgY2xpZW50X2lkOiBjb25maWcuYXdzLmNvZ25pdG9DbGllbnRJZCxcbiAgICAgIHJlc3BvbnNlX3R5cGU6ICdjb2RlJyxcbiAgICAgIHNjb3BlOiAnZW1haWwgb3BlbmlkIHByb2ZpbGUnLFxuICAgICAgcmVkaXJlY3RfdXJpOiBSRURJUkVDVF9VUkksXG4gICAgICBzdGF0ZTogc3RhdGUsXG4gICAgfSk7XG5cbiAgICByZXR1cm4gYGh0dHBzOi8vJHtjb25maWcuYXdzLmNvZ25pdG9Eb21haW59L29hdXRoMi9hdXRob3JpemU/JHtwYXJhbXMudG9TdHJpbmcoKX1gO1xuICB9XG5cbiAgLyoqXG4gICAqIEV4Y2hhbmdlIGF1dGhvcml6YXRpb24gY29kZSBmb3IgdG9rZW5zXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGV4Y2hhbmdlQ29kZUZvclRva2Vucyhjb2RlOiBzdHJpbmcpOiBQcm9taXNlPHtcbiAgICBhY2Nlc3NUb2tlbjogc3RyaW5nO1xuICAgIGlkVG9rZW46IHN0cmluZztcbiAgICByZWZyZXNoVG9rZW46IHN0cmluZztcbiAgICBleHBpcmVzSW46IG51bWJlcjtcbiAgfT4ge1xuICAgIGNvbnN0IGNvbmZpZyA9IGdldENvbmZpZygpO1xuICAgIGNvbnN0IHRva2VuVXJsID0gYGh0dHBzOi8vJHtjb25maWcuYXdzLmNvZ25pdG9Eb21haW59L29hdXRoMi90b2tlbmA7XG5cbiAgICBjb25zdCBwYXJhbXMgPSBuZXcgVVJMU2VhcmNoUGFyYW1zKHtcbiAgICAgIGdyYW50X3R5cGU6ICdhdXRob3JpemF0aW9uX2NvZGUnLFxuICAgICAgY2xpZW50X2lkOiBjb25maWcuYXdzLmNvZ25pdG9DbGllbnRJZCxcbiAgICAgIGNvZGU6IGNvZGUsXG4gICAgICByZWRpcmVjdF91cmk6IFJFRElSRUNUX1VSSSxcbiAgICB9KTtcblxuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2hXaXRoRGlhZ25vc3RpY3MoXG4gICAgICB0b2tlblVybCxcbiAgICAgIHtcbiAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgIGhlYWRlcnM6IHsgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnIH0sXG4gICAgICAgIGJvZHk6IHBhcmFtcy50b1N0cmluZygpLFxuICAgICAgfSxcbiAgICAgICdUb2tlbiBleGNoYW5nZSdcbiAgICApO1xuXG4gICAgaWYgKCFyZXNwb25zZS5vaykge1xuICAgICAgY29uc3QgZXJyb3JUZXh0ID0gYXdhaXQgcmVzcG9uc2UudGV4dCgpO1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBUb2tlbiBleGNoYW5nZSBmYWlsZWQ6ICR7cmVzcG9uc2Uuc3RhdHVzfSAke2Vycm9yVGV4dH1gKTtcbiAgICB9XG5cbiAgICBjb25zdCBkYXRhID0gYXdhaXQgcmVzcG9uc2UuanNvbigpIGFzIHtcbiAgICAgIGFjY2Vzc190b2tlbjogc3RyaW5nO1xuICAgICAgaWRfdG9rZW46IHN0cmluZztcbiAgICAgIHJlZnJlc2hfdG9rZW46IHN0cmluZztcbiAgICAgIGV4cGlyZXNfaW46IG51bWJlcjtcbiAgICB9O1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGFjY2Vzc1Rva2VuOiBkYXRhLmFjY2Vzc190b2tlbixcbiAgICAgIGlkVG9rZW46IGRhdGEuaWRfdG9rZW4sXG4gICAgICByZWZyZXNoVG9rZW46IGRhdGEucmVmcmVzaF90b2tlbixcbiAgICAgIGV4cGlyZXNJbjogZGF0YS5leHBpcmVzX2luLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogRGVjb2RlIEpXVCBwYXlsb2FkXG4gICAqL1xuICBwcml2YXRlIGRlY29kZUp3dCh0b2tlbjogc3RyaW5nKTogYW55IHtcbiAgICBjb25zdCBwYXJ0cyA9IHRva2VuLnNwbGl0KCcuJyk7XG4gICAgaWYgKHBhcnRzLmxlbmd0aCAhPT0gMykgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIEpXVCcpO1xuICAgIHJldHVybiBKU09OLnBhcnNlKEJ1ZmZlci5mcm9tKHBhcnRzWzFdLCAnYmFzZTY0JykudG9TdHJpbmcoJ3V0Zi04JykpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlZnJlc2ggdG9rZW5zXG4gICAqL1xuICBhc3luYyByZWZyZXNoVG9rZW5zKHJlZnJlc2hUb2tlbjogc3RyaW5nKTogUHJvbWlzZTx7XG4gICAgYWNjZXNzVG9rZW46IHN0cmluZztcbiAgICBpZFRva2VuOiBzdHJpbmc7XG4gICAgZXhwaXJlc0luOiBudW1iZXI7XG4gIH0+IHtcbiAgICBjb25zdCBjb25maWcgPSBnZXRDb25maWcoKTtcbiAgICBjb25zdCB0b2tlblVybCA9IGBodHRwczovLyR7Y29uZmlnLmF3cy5jb2duaXRvRG9tYWlufS9vYXV0aDIvdG9rZW5gO1xuXG4gICAgY29uc3QgcGFyYW1zID0gbmV3IFVSTFNlYXJjaFBhcmFtcyh7XG4gICAgICBncmFudF90eXBlOiAncmVmcmVzaF90b2tlbicsXG4gICAgICBjbGllbnRfaWQ6IGNvbmZpZy5hd3MuY29nbml0b0NsaWVudElkLFxuICAgICAgcmVmcmVzaF90b2tlbjogcmVmcmVzaFRva2VuLFxuICAgIH0pO1xuXG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaFdpdGhEaWFnbm9zdGljcyhcbiAgICAgIHRva2VuVXJsLFxuICAgICAge1xuICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgaGVhZGVyczogeyAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCcgfSxcbiAgICAgICAgYm9keTogcGFyYW1zLnRvU3RyaW5nKCksXG4gICAgICB9LFxuICAgICAgJ1Rva2VuIHJlZnJlc2gnXG4gICAgKTtcblxuICAgIGlmICghcmVzcG9uc2Uub2spIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVG9rZW4gcmVmcmVzaCBmYWlsZWQ6ICR7cmVzcG9uc2Uuc3RhdHVzfWApO1xuICAgIH1cblxuICAgIGNvbnN0IGRhdGEgPSBhd2FpdCByZXNwb25zZS5qc29uKCkgYXMge1xuICAgICAgYWNjZXNzX3Rva2VuOiBzdHJpbmc7XG4gICAgICBpZF90b2tlbjogc3RyaW5nO1xuICAgICAgZXhwaXJlc19pbjogbnVtYmVyO1xuICAgIH07XG5cbiAgICByZXR1cm4ge1xuICAgICAgYWNjZXNzVG9rZW46IGRhdGEuYWNjZXNzX3Rva2VuLFxuICAgICAgaWRUb2tlbjogZGF0YS5pZF90b2tlbixcbiAgICAgIGV4cGlyZXNJbjogZGF0YS5leHBpcmVzX2luLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogTG9naW4gdmlhIE9BdXRoIGJyb3dzZXIgZmxvd1xuICAgKi9cbiAgYXN5bmMgbG9naW4oKTogUHJvbWlzZTxUb2tlbkRhdGEgfCBudWxsPiB7XG4gICAgLy8gQ2hlY2sgaWYgYWxyZWFkeSBsb2dnZWQgaW5cbiAgICBjb25zdCBleGlzdGluZyA9IGF3YWl0IGtleWNoYWluTWFuYWdlci5nZXRUb2tlbnMoZ2V0RW52aXJvbm1lbnQoKSk7XG4gICAgaWYgKGV4aXN0aW5nICYmICFrZXljaGFpbk1hbmFnZXIuaXNUb2tlbkV4cGlyZWQoZXhpc3RpbmcpKSB7XG4gICAgICByZXR1cm4gZXhpc3Rpbmc7XG4gICAgfVxuXG4gICAgY29uc3Qgc3RhdGUgPSB0aGlzLmdlbmVyYXRlU3RhdGUoKTtcbiAgICBjb25zdCBhdXRoVXJsID0gdGhpcy5idWlsZEF1dGhVcmwoc3RhdGUpO1xuXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGNvbnN0IHNlcnZlciA9IGh0dHAuY3JlYXRlU2VydmVyKGFzeW5jIChyZXEsIHJlcykgPT4ge1xuICAgICAgICBpZiAoIXJlcS51cmw/LnN0YXJ0c1dpdGgoQ0FMTEJBQ0tfUEFUSCkpIHtcbiAgICAgICAgICByZXMud3JpdGVIZWFkKDQwNCk7XG4gICAgICAgICAgcmVzLmVuZCgnTm90IGZvdW5kJyk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCB1cmwgPSBuZXcgVVJMKHJlcS51cmwsIGBodHRwOi8vbG9jYWxob3N0OiR7Q0FMTEJBQ0tfUE9SVH1gKTtcbiAgICAgICAgICBjb25zdCBjb2RlID0gdXJsLnNlYXJjaFBhcmFtcy5nZXQoJ2NvZGUnKTtcbiAgICAgICAgICBjb25zdCByZXR1cm5lZFN0YXRlID0gdXJsLnNlYXJjaFBhcmFtcy5nZXQoJ3N0YXRlJyk7XG4gICAgICAgICAgY29uc3QgZXJyb3IgPSB1cmwuc2VhcmNoUGFyYW1zLmdldCgnZXJyb3InKTtcblxuICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBPQXV0aCBlcnJvcjogJHtlcnJvcn1gKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAocmV0dXJuZWRTdGF0ZSAhPT0gc3RhdGUpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignU3RhdGUgbWlzbWF0Y2gnKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoIWNvZGUpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTm8gYXV0aG9yaXphdGlvbiBjb2RlJyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3QgdG9rZW5zID0gYXdhaXQgdGhpcy5leGNoYW5nZUNvZGVGb3JUb2tlbnMoY29kZSk7XG4gICAgICAgICAgY29uc3QgaWRQYXlsb2FkID0gdGhpcy5kZWNvZGVKd3QodG9rZW5zLmlkVG9rZW4pO1xuXG4gICAgICAgICAgY29uc3QgdG9rZW5EYXRhOiBUb2tlbkRhdGEgPSB7XG4gICAgICAgICAgICBhY2Nlc3NUb2tlbjogdG9rZW5zLmFjY2Vzc1Rva2VuLFxuICAgICAgICAgICAgaWRUb2tlbjogdG9rZW5zLmlkVG9rZW4sXG4gICAgICAgICAgICByZWZyZXNoVG9rZW46IHRva2Vucy5yZWZyZXNoVG9rZW4sXG4gICAgICAgICAgICBleHBpcmVzQXQ6IERhdGUubm93KCkgKyAodG9rZW5zLmV4cGlyZXNJbiAqIDEwMDApLFxuICAgICAgICAgICAgdXNlcklkOiBpZFBheWxvYWQuc3ViLFxuICAgICAgICAgICAgZW1haWw6IGlkUGF5bG9hZC5lbWFpbCB8fCAndW5rbm93bicsXG4gICAgICAgICAgfTtcblxuICAgICAgICAgIGF3YWl0IGtleWNoYWluTWFuYWdlci5zZXRUb2tlbnModG9rZW5EYXRhLCBnZXRFbnZpcm9ubWVudCgpKTtcblxuICAgICAgICAgIHJlcy53cml0ZUhlYWQoMjAwLCB7ICdDb250ZW50LVR5cGUnOiAndGV4dC9odG1sOyBjaGFyc2V0PXV0Zi04JyB9KTtcbiAgICAgICAgICByZXMuZW5kKGBcbiAgICAgICAgICAgIDwhRE9DVFlQRSBodG1sPlxuICAgICAgICAgICAgPGh0bWw+XG4gICAgICAgICAgICA8aGVhZD48dGl0bGU+U3VjY2VzczwvdGl0bGU+PC9oZWFkPlxuICAgICAgICAgICAgPGJvZHkgc3R5bGU9XCJmb250LWZhbWlseTogc3lzdGVtLXVpOyBtYXgtd2lkdGg6IDYwMHB4OyBtYXJnaW46IDUwcHggYXV0bzsgdGV4dC1hbGlnbjogY2VudGVyO1wiPlxuICAgICAgICAgICAgICA8aDEgc3R5bGU9XCJjb2xvcjogIzIyYzU1ZTtcIj4mIzEwMDAzOyBBdXRoZW50aWNhdGlvbiBTdWNjZXNzZnVsPC9oMT5cbiAgICAgICAgICAgICAgPHA+WW91IGNhbiBjbG9zZSB0aGlzIHdpbmRvdy48L3A+XG4gICAgICAgICAgICA8L2JvZHk+XG4gICAgICAgICAgICA8L2h0bWw+XG4gICAgICAgICAgYCk7XG5cbiAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIHNlcnZlci5jbG9zZSgoKSA9PiByZXNvbHZlKHRva2VuRGF0YSkpO1xuICAgICAgICAgIH0sIDUwMCk7XG4gICAgICAgIH0gY2F0Y2ggKGVycjogYW55KSB7XG4gICAgICAgICAgLy8gSFRNTC1lc2NhcGUgdGhlIGVycm9yIG1lc3NhZ2Ugc28gbmV3bGluZXMgYW5kIHNwZWNpYWwgY2hhcnNcbiAgICAgICAgICAvLyByZW5kZXIgc2FmZWx5LiBNdWx0aS1saW5lIGRpYWdub3N0aWMgbWVzc2FnZXMgKGZyb21cbiAgICAgICAgICAvLyBmZXRjaFdpdGhEaWFnbm9zdGljcykgbmVlZCA8cHJlPiB0byBwcmVzZXJ2ZSBmb3JtYXR0aW5nLlxuICAgICAgICAgIGNvbnN0IHNhZmVNZXNzYWdlID0gU3RyaW5nKGVycj8ubWVzc2FnZSB8fCBlcnIpXG4gICAgICAgICAgICAucmVwbGFjZSgvJi9nLCAnJmFtcDsnKVxuICAgICAgICAgICAgLnJlcGxhY2UoLzwvZywgJyZsdDsnKVxuICAgICAgICAgICAgLnJlcGxhY2UoLz4vZywgJyZndDsnKTtcblxuICAgICAgICAgIHJlcy53cml0ZUhlYWQoNDAwLCB7ICdDb250ZW50LVR5cGUnOiAndGV4dC9odG1sOyBjaGFyc2V0PXV0Zi04JyB9KTtcbiAgICAgICAgICByZXMuZW5kKGBcbiAgICAgICAgICAgIDwhRE9DVFlQRSBodG1sPlxuICAgICAgICAgICAgPGh0bWw+XG4gICAgICAgICAgICA8aGVhZD48dGl0bGU+RXJyb3I8L3RpdGxlPjwvaGVhZD5cbiAgICAgICAgICAgIDxib2R5IHN0eWxlPVwiZm9udC1mYW1pbHk6IHN5c3RlbS11aTsgbWF4LXdpZHRoOiA3MjBweDsgbWFyZ2luOiA1MHB4IGF1dG87IHBhZGRpbmc6IDAgMTZweDtcIj5cbiAgICAgICAgICAgICAgPGgxIHN0eWxlPVwiY29sb3I6ICNlZjQ0NDQ7IHRleHQtYWxpZ246IGNlbnRlcjtcIj4mIzEwMDA3OyBBdXRoZW50aWNhdGlvbiBGYWlsZWQ8L2gxPlxuICAgICAgICAgICAgICA8cHJlIHN0eWxlPVwiYmFja2dyb3VuZDogI2Y0ZjRmNTsgcGFkZGluZzogMTZweDsgYm9yZGVyLXJhZGl1czogOHB4OyB3aGl0ZS1zcGFjZTogcHJlLXdyYXA7IHdvcmQtd3JhcDogYnJlYWstd29yZDsgZm9udC1zaXplOiAxM3B4OyBsaW5lLWhlaWdodDogMS41O1wiPiR7c2FmZU1lc3NhZ2V9PC9wcmU+XG4gICAgICAgICAgICAgIDxwIHN0eWxlPVwidGV4dC1hbGlnbjogY2VudGVyOyBjb2xvcjogIzcxNzE3YTsgbWFyZ2luLXRvcDogMjRweDtcIj5Zb3UgY2FuIGNsb3NlIHRoaXMgd2luZG93IGFuZCB0cnkgYWdhaW4gaW4geW91ciB0ZXJtaW5hbC48L3A+XG4gICAgICAgICAgICA8L2JvZHk+XG4gICAgICAgICAgICA8L2h0bWw+XG4gICAgICAgICAgYCk7XG5cbiAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIHNlcnZlci5jbG9zZSgoKSA9PiByZWplY3QoZXJyKSk7XG4gICAgICAgICAgfSwgNTAwKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5vbignZXJyb3InLCAoZXJyOiBhbnkpID0+IHtcbiAgICAgICAgaWYgKGVyci5jb2RlID09PSAnRUFERFJJTlVTRScpIHtcbiAgICAgICAgICByZWplY3QobmV3IEVycm9yKGBQb3J0ICR7Q0FMTEJBQ0tfUE9SVH0gaXMgaW4gdXNlYCkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLmxpc3RlbihDQUxMQkFDS19QT1JULCAnbG9jYWxob3N0JywgKCkgPT4ge1xuICAgICAgICBsb2dnZXIuaW5mbygnW0F1dGhTZXJ2aWNlXSBDYWxsYmFjayBzZXJ2ZXIgc3RhcnRlZCcpO1xuICAgICAgICB0aGlzLm9wZW5Ccm93c2VyKGF1dGhVcmwpO1xuICAgICAgfSk7XG5cbiAgICAgIC8vIFRpbWVvdXRcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICBzZXJ2ZXIuY2xvc2UoKCkgPT4gcmVqZWN0KG5ldyBFcnJvcignTG9naW4gdGltZW91dCcpKSk7XG4gICAgICB9LCAyICogNjAgKiAxMDAwKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMb2dvdXRcbiAgICovXG4gIGFzeW5jIGxvZ291dCgpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBjb25zdCBjb25maWcgPSBnZXRDb25maWcoKTtcbiAgICBjb25zdCBkZWxldGVkID0gYXdhaXQga2V5Y2hhaW5NYW5hZ2VyLmRlbGV0ZVRva2VucyhnZXRFbnZpcm9ubWVudCgpKTtcblxuICAgIGlmIChkZWxldGVkKSB7XG4gICAgICAvLyBTdGFydCB0ZW1wb3Jhcnkgc2VydmVyIHRvIGhhbmRsZSBzaWdub3V0IGNhbGxiYWNrXG4gICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgICAgY29uc3Qgc2VydmVyID0gaHR0cC5jcmVhdGVTZXJ2ZXIoKHJlcSwgcmVzKSA9PiB7XG4gICAgICAgICAgaWYgKHJlcS51cmw/LnN0YXJ0c1dpdGgoJy9zaWdub3V0JykpIHtcbiAgICAgICAgICAgIHJlcy53cml0ZUhlYWQoMjAwLCB7ICdDb250ZW50LVR5cGUnOiAndGV4dC9odG1sOyBjaGFyc2V0PXV0Zi04JyB9KTtcbiAgICAgICAgICAgIHJlcy5lbmQoYFxuICAgICAgICAgICAgICA8IURPQ1RZUEUgaHRtbD5cbiAgICAgICAgICAgICAgPGh0bWw+XG4gICAgICAgICAgICAgIDxoZWFkPjx0aXRsZT5TaWduZWQgT3V0PC90aXRsZT48L2hlYWQ+XG4gICAgICAgICAgICAgIDxib2R5IHN0eWxlPVwiZm9udC1mYW1pbHk6IHN5c3RlbS11aTsgbWF4LXdpZHRoOiA2MDBweDsgbWFyZ2luOiA1MHB4IGF1dG87IHRleHQtYWxpZ246IGNlbnRlcjtcIj5cbiAgICAgICAgICAgICAgICA8aDEgc3R5bGU9XCJjb2xvcjogIzIyYzU1ZTtcIj4mIzEwMDAzOyBTaWduZWQgT3V0PC9oMT5cbiAgICAgICAgICAgICAgICA8cD5Zb3UgY2FuIGNsb3NlIHRoaXMgd2luZG93LjwvcD5cbiAgICAgICAgICAgICAgPC9ib2R5PlxuICAgICAgICAgICAgICA8L2h0bWw+XG4gICAgICAgICAgICBgKTtcblxuICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgIHNlcnZlci5jbG9zZSgoKSA9PiByZXNvbHZlKHRydWUpKTtcbiAgICAgICAgICAgIH0sIDUwMCk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJlcy53cml0ZUhlYWQoNDA0KTtcbiAgICAgICAgICAgIHJlcy5lbmQoJ05vdCBmb3VuZCcpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgc2VydmVyLm9uKCdlcnJvcicsICgpID0+IHtcbiAgICAgICAgICByZXNvbHZlKHRydWUpOyAvLyBTdGlsbCByZXR1cm4gdHJ1ZSBzaW5jZSB0b2tlbnMgd2VyZSBkZWxldGVkXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHNlcnZlci5saXN0ZW4oQ0FMTEJBQ0tfUE9SVCwgJ2xvY2FsaG9zdCcsICgpID0+IHtcbiAgICAgICAgICBjb25zdCBsb2dvdXRVcmwgPSBgaHR0cHM6Ly8ke2NvbmZpZy5hd3MuY29nbml0b0RvbWFpbn0vbG9nb3V0P2AgK1xuICAgICAgICAgICAgYGNsaWVudF9pZD0ke2NvbmZpZy5hd3MuY29nbml0b0NsaWVudElkfSZgICtcbiAgICAgICAgICAgIGBsb2dvdXRfdXJpPSR7ZW5jb2RlVVJJQ29tcG9uZW50KFJFRElSRUNUX1VSSS5yZXBsYWNlKCcvY2FsbGJhY2snLCAnL3NpZ25vdXQnKSl9YDtcblxuICAgICAgICAgIHRoaXMub3BlbkJyb3dzZXIobG9nb3V0VXJsKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gVGltZW91dCBhZnRlciAzMCBzZWNvbmRzXG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgIHNlcnZlci5jbG9zZSgoKSA9PiByZXNvbHZlKHRydWUpKTtcbiAgICAgICAgfSwgMzAgKiAxMDAwKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBkZWxldGVkO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBjdXJyZW50IGF1dGggc3RhdHVzXG4gICAqL1xuICBhc3luYyBnZXRTdGF0dXMoKTogUHJvbWlzZTx7IGF1dGhlbnRpY2F0ZWQ6IGJvb2xlYW47IHRva2Vucz86IFRva2VuRGF0YSB9PiB7XG4gICAgY29uc3QgdG9rZW5zID0gYXdhaXQga2V5Y2hhaW5NYW5hZ2VyLmdldFRva2VucyhnZXRFbnZpcm9ubWVudCgpKTtcbiAgICBpZiAoIXRva2Vucykge1xuICAgICAgcmV0dXJuIHsgYXV0aGVudGljYXRlZDogZmFsc2UgfTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgYXV0aGVudGljYXRlZDogIWtleWNoYWluTWFuYWdlci5pc1Rva2VuRXhwaXJlZCh0b2tlbnMpLFxuICAgICAgdG9rZW5zLFxuICAgIH07XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IGF1dGhTZXJ2aWNlID0gQXV0aFNlcnZpY2UuZ2V0SW5zdGFuY2UoKTtcbiJdfQ==
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wraps fetch() and rewrites "fetch failed" errors to include the underlying
|
|
3
|
+
* cause and a user-actionable diagnostic tip when possible. Non-network errors
|
|
4
|
+
* and HTTP error responses (non-2xx) are not affected — the caller still
|
|
5
|
+
* handles response.ok checks themselves.
|
|
6
|
+
*
|
|
7
|
+
* @param url The URL to fetch
|
|
8
|
+
* @param init Standard fetch init options
|
|
9
|
+
* @param context Optional short label (e.g. "token exchange") for the error message
|
|
10
|
+
*/
|
|
11
|
+
export declare function fetchWithDiagnostics(url: string, init?: any, context?: string): Promise<Response>;
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
//
|
|
3
|
+
// fetch-helpers.ts
|
|
4
|
+
// CodeVibe Core
|
|
5
|
+
//
|
|
6
|
+
// Wrapper around Node's built-in fetch() that surfaces the underlying cause
|
|
7
|
+
// of "fetch failed" errors with platform-specific diagnostic tips.
|
|
8
|
+
//
|
|
9
|
+
// Background: Node 18+'s built-in fetch (via undici) throws a generic
|
|
10
|
+
// TypeError with message "fetch failed" for all network-level errors (DNS
|
|
11
|
+
// failures, timeouts, TLS issues, etc.). The real cause is buried in the
|
|
12
|
+
// error's .cause property. This wrapper unpacks that cause and returns a
|
|
13
|
+
// detailed, actionable error message — critical for WSL users where fetch
|
|
14
|
+
// failures are common and usually fixable with known workarounds.
|
|
15
|
+
//
|
|
16
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
17
|
+
if (k2 === undefined) k2 = k;
|
|
18
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
19
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
20
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
21
|
+
}
|
|
22
|
+
Object.defineProperty(o, k2, desc);
|
|
23
|
+
}) : (function(o, m, k, k2) {
|
|
24
|
+
if (k2 === undefined) k2 = k;
|
|
25
|
+
o[k2] = m[k];
|
|
26
|
+
}));
|
|
27
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
28
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
29
|
+
}) : function(o, v) {
|
|
30
|
+
o["default"] = v;
|
|
31
|
+
});
|
|
32
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
33
|
+
var ownKeys = function(o) {
|
|
34
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
35
|
+
var ar = [];
|
|
36
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
37
|
+
return ar;
|
|
38
|
+
};
|
|
39
|
+
return ownKeys(o);
|
|
40
|
+
};
|
|
41
|
+
return function (mod) {
|
|
42
|
+
if (mod && mod.__esModule) return mod;
|
|
43
|
+
var result = {};
|
|
44
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
45
|
+
__setModuleDefault(result, mod);
|
|
46
|
+
return result;
|
|
47
|
+
};
|
|
48
|
+
})();
|
|
49
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
50
|
+
exports.fetchWithDiagnostics = fetchWithDiagnostics;
|
|
51
|
+
const dns = __importStar(require("dns"));
|
|
52
|
+
const fs = __importStar(require("fs"));
|
|
53
|
+
// Node 17+ changed the default DNS result order from 'ipv4first' to
|
|
54
|
+
// 'verbatim' (RFC-compliant but problematic for hosts with broken IPv6).
|
|
55
|
+
// On WSL Ubuntu specifically, the kernel often advertises IPv6 addresses
|
|
56
|
+
// via getaddrinfo even though the WSL network namespace has no route to
|
|
57
|
+
// the IPv6 internet — causing every IPv6 connection attempt to fail with
|
|
58
|
+
// EHOSTUNREACH. curl handles this via Happy Eyeballs fallback, but undici
|
|
59
|
+
// (Node's built-in fetch) does not, and throws "fetch failed" without
|
|
60
|
+
// ever trying IPv4.
|
|
61
|
+
//
|
|
62
|
+
// We apply 'ipv4first' ONLY when running inside WSL. On macOS, native
|
|
63
|
+
// Linux, and Windows we leave Node's default ('verbatim') alone — those
|
|
64
|
+
// platforms have healthy dual-stack networking and the current behavior
|
|
65
|
+
// is correct. Narrowly scoping the override to WSL means zero behavioral
|
|
66
|
+
// change for non-WSL users (including IPv6-only networks where ipv4first
|
|
67
|
+
// would add first-connection latency).
|
|
68
|
+
//
|
|
69
|
+
// This runs as a side effect of importing codevibe-core's fetch-helpers,
|
|
70
|
+
// which happens early in every plugin's startup path. Documented here
|
|
71
|
+
// so future maintainers understand why there's a side effect on import.
|
|
72
|
+
if (isRunningInWSL()) {
|
|
73
|
+
try {
|
|
74
|
+
dns.setDefaultResultOrder('ipv4first');
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
// Older Node versions (< 18.6) don't expose setDefaultResultOrder;
|
|
78
|
+
// skip silently. Users on those versions can still set the
|
|
79
|
+
// NODE_OPTIONS="--dns-result-order=ipv4first" environment variable
|
|
80
|
+
// manually if they hit IPv6 issues.
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Detect whether we're running inside WSL (1 or 2). Returns false on any
|
|
85
|
+
* non-Linux platform or if /proc/sys/kernel/osrelease is not readable.
|
|
86
|
+
* Duplicated from auth-service.ts as a module-level helper so it can run
|
|
87
|
+
* at import time, before any class is instantiated.
|
|
88
|
+
*/
|
|
89
|
+
function isRunningInWSL() {
|
|
90
|
+
if (process.platform !== 'linux')
|
|
91
|
+
return false;
|
|
92
|
+
try {
|
|
93
|
+
const osRelease = fs.readFileSync('/proc/sys/kernel/osrelease', 'utf8');
|
|
94
|
+
return /microsoft|wsl/i.test(osRelease);
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Wraps fetch() and rewrites "fetch failed" errors to include the underlying
|
|
102
|
+
* cause and a user-actionable diagnostic tip when possible. Non-network errors
|
|
103
|
+
* and HTTP error responses (non-2xx) are not affected — the caller still
|
|
104
|
+
* handles response.ok checks themselves.
|
|
105
|
+
*
|
|
106
|
+
* @param url The URL to fetch
|
|
107
|
+
* @param init Standard fetch init options
|
|
108
|
+
* @param context Optional short label (e.g. "token exchange") for the error message
|
|
109
|
+
*/
|
|
110
|
+
async function fetchWithDiagnostics(url, init, context) {
|
|
111
|
+
try {
|
|
112
|
+
return await fetch(url, init);
|
|
113
|
+
}
|
|
114
|
+
catch (err) {
|
|
115
|
+
// Node's undici wraps real errors in err.cause
|
|
116
|
+
const causeCode = err?.cause?.code;
|
|
117
|
+
const causeMessage = err?.cause?.message;
|
|
118
|
+
const causeSummary = causeCode || causeMessage || err?.message || 'unknown';
|
|
119
|
+
const tip = getDiagnosticTip(causeCode);
|
|
120
|
+
const contextLabel = context ? `${context}: ` : '';
|
|
121
|
+
const platformInfo = `Node ${process.version} on ${process.platform}`;
|
|
122
|
+
const detailLines = [
|
|
123
|
+
`${contextLabel}Cannot reach ${url}`,
|
|
124
|
+
` Underlying error: ${causeSummary}`,
|
|
125
|
+
];
|
|
126
|
+
if (tip) {
|
|
127
|
+
detailLines.push(` Suggested fix: ${tip}`);
|
|
128
|
+
}
|
|
129
|
+
detailLines.push(` Platform: ${platformInfo}`);
|
|
130
|
+
const detailedError = new Error(detailLines.join('\n'));
|
|
131
|
+
// Preserve the original error as cause so callers can still inspect it
|
|
132
|
+
detailedError.cause = err;
|
|
133
|
+
throw detailedError;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Map common Node network error codes to user-actionable diagnostic hints.
|
|
138
|
+
* Returns null if the code isn't one we recognize.
|
|
139
|
+
*/
|
|
140
|
+
function getDiagnosticTip(errorCode) {
|
|
141
|
+
if (!errorCode)
|
|
142
|
+
return null;
|
|
143
|
+
switch (errorCode) {
|
|
144
|
+
case 'ENOTFOUND':
|
|
145
|
+
case 'EAI_AGAIN':
|
|
146
|
+
return 'DNS resolution failed. On WSL Ubuntu, check /etc/resolv.conf, or try running with NODE_OPTIONS="--dns-result-order=ipv4first".';
|
|
147
|
+
case 'ETIMEDOUT':
|
|
148
|
+
case 'ECONNREFUSED':
|
|
149
|
+
case 'ECONNRESET':
|
|
150
|
+
case 'EHOSTUNREACH':
|
|
151
|
+
case 'ENETUNREACH':
|
|
152
|
+
return 'Network unreachable. On WSL Ubuntu, try NODE_OPTIONS="--dns-result-order=ipv4first" (WSL\'s IPv6 is often broken). If behind a corporate proxy, set HTTPS_PROXY.';
|
|
153
|
+
case 'CERT_HAS_EXPIRED':
|
|
154
|
+
case 'CERT_NOT_YET_VALID':
|
|
155
|
+
return 'TLS certificate time error — likely system clock drift. On WSL, run `sudo hwclock -s`, or shut down WSL from PowerShell with `wsl --shutdown` and restart.';
|
|
156
|
+
case 'UNABLE_TO_GET_ISSUER_CERT_LOCALLY':
|
|
157
|
+
case 'SELF_SIGNED_CERT_IN_CHAIN':
|
|
158
|
+
case 'UNABLE_TO_VERIFY_LEAF_SIGNATURE':
|
|
159
|
+
case 'DEPTH_ZERO_SELF_SIGNED_CERT':
|
|
160
|
+
return 'Corporate HTTPS proxy detected — the TLS cert is not trusted by Node. Set NODE_EXTRA_CA_CERTS=/path/to/corporate-ca.pem, or configure HTTPS_PROXY if a proxy is required.';
|
|
161
|
+
default:
|
|
162
|
+
return null;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmV0Y2gtaGVscGVycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hdXRoL2ZldGNoLWhlbHBlcnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLEVBQUU7QUFDRixtQkFBbUI7QUFDbkIsZ0JBQWdCO0FBQ2hCLEVBQUU7QUFDRiw0RUFBNEU7QUFDNUUsbUVBQW1FO0FBQ25FLEVBQUU7QUFDRixzRUFBc0U7QUFDdEUsMEVBQTBFO0FBQzFFLHlFQUF5RTtBQUN6RSx5RUFBeUU7QUFDekUsMEVBQTBFO0FBQzFFLGtFQUFrRTtBQUNsRSxFQUFFOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQTZERixvREErQkM7QUExRkQseUNBQTJCO0FBQzNCLHVDQUF5QjtBQUV6QixvRUFBb0U7QUFDcEUseUVBQXlFO0FBQ3pFLHlFQUF5RTtBQUN6RSx3RUFBd0U7QUFDeEUseUVBQXlFO0FBQ3pFLDBFQUEwRTtBQUMxRSxzRUFBc0U7QUFDdEUsb0JBQW9CO0FBQ3BCLEVBQUU7QUFDRixzRUFBc0U7QUFDdEUsd0VBQXdFO0FBQ3hFLHdFQUF3RTtBQUN4RSx5RUFBeUU7QUFDekUseUVBQXlFO0FBQ3pFLHVDQUF1QztBQUN2QyxFQUFFO0FBQ0YseUVBQXlFO0FBQ3pFLHNFQUFzRTtBQUN0RSx3RUFBd0U7QUFDeEUsSUFBSSxjQUFjLEVBQUUsRUFBRSxDQUFDO0lBQ3JCLElBQUksQ0FBQztRQUNILEdBQUcsQ0FBQyxxQkFBcUIsQ0FBQyxXQUFXLENBQUMsQ0FBQztJQUN6QyxDQUFDO0lBQUMsTUFBTSxDQUFDO1FBQ1AsbUVBQW1FO1FBQ25FLDJEQUEyRDtRQUMzRCxtRUFBbUU7UUFDbkUsb0NBQW9DO0lBQ3RDLENBQUM7QUFDSCxDQUFDO0FBRUQ7Ozs7O0dBS0c7QUFDSCxTQUFTLGNBQWM7SUFDckIsSUFBSSxPQUFPLENBQUMsUUFBUSxLQUFLLE9BQU87UUFBRSxPQUFPLEtBQUssQ0FBQztJQUMvQyxJQUFJLENBQUM7UUFDSCxNQUFNLFNBQVMsR0FBRyxFQUFFLENBQUMsWUFBWSxDQUFDLDRCQUE0QixFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQ3hFLE9BQU8sZ0JBQWdCLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQzFDLENBQUM7SUFBQyxNQUFNLENBQUM7UUFDUCxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7QUFDSCxDQUFDO0FBRUQ7Ozs7Ozs7OztHQVNHO0FBQ0ksS0FBSyxVQUFVLG9CQUFvQixDQUN4QyxHQUFXLEVBQ1gsSUFBVSxFQUNWLE9BQWdCO0lBRWhCLElBQUksQ0FBQztRQUNILE9BQU8sTUFBTSxLQUFLLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQ2hDLENBQUM7SUFBQyxPQUFPLEdBQVEsRUFBRSxDQUFDO1FBQ2xCLCtDQUErQztRQUMvQyxNQUFNLFNBQVMsR0FBdUIsR0FBRyxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUM7UUFDdkQsTUFBTSxZQUFZLEdBQXVCLEdBQUcsRUFBRSxLQUFLLEVBQUUsT0FBTyxDQUFDO1FBQzdELE1BQU0sWUFBWSxHQUFHLFNBQVMsSUFBSSxZQUFZLElBQUksR0FBRyxFQUFFLE9BQU8sSUFBSSxTQUFTLENBQUM7UUFFNUUsTUFBTSxHQUFHLEdBQUcsZ0JBQWdCLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDeEMsTUFBTSxZQUFZLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQyxHQUFHLE9BQU8sSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDbkQsTUFBTSxZQUFZLEdBQUcsUUFBUSxPQUFPLENBQUMsT0FBTyxPQUFPLE9BQU8sQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUV0RSxNQUFNLFdBQVcsR0FBYTtZQUM1QixHQUFHLFlBQVksZ0JBQWdCLEdBQUcsRUFBRTtZQUNwQyx1QkFBdUIsWUFBWSxFQUFFO1NBQ3RDLENBQUM7UUFDRixJQUFJLEdBQUcsRUFBRSxDQUFDO1lBQ1IsV0FBVyxDQUFDLElBQUksQ0FBQyxvQkFBb0IsR0FBRyxFQUFFLENBQUMsQ0FBQztRQUM5QyxDQUFDO1FBQ0QsV0FBVyxDQUFDLElBQUksQ0FBQyxlQUFlLFlBQVksRUFBRSxDQUFDLENBQUM7UUFFaEQsTUFBTSxhQUFhLEdBQUcsSUFBSSxLQUFLLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1FBQ3hELHVFQUF1RTtRQUN0RSxhQUFxQixDQUFDLEtBQUssR0FBRyxHQUFHLENBQUM7UUFDbkMsTUFBTSxhQUFhLENBQUM7SUFDdEIsQ0FBQztBQUNILENBQUM7QUFFRDs7O0dBR0c7QUFDSCxTQUFTLGdCQUFnQixDQUFDLFNBQWtCO0lBQzFDLElBQUksQ0FBQyxTQUFTO1FBQUUsT0FBTyxJQUFJLENBQUM7SUFFNUIsUUFBUSxTQUFTLEVBQUUsQ0FBQztRQUNsQixLQUFLLFdBQVcsQ0FBQztRQUNqQixLQUFLLFdBQVc7WUFDZCxPQUFPLGdJQUFnSSxDQUFDO1FBRTFJLEtBQUssV0FBVyxDQUFDO1FBQ2pCLEtBQUssY0FBYyxDQUFDO1FBQ3BCLEtBQUssWUFBWSxDQUFDO1FBQ2xCLEtBQUssY0FBYyxDQUFDO1FBQ3BCLEtBQUssYUFBYTtZQUNoQixPQUFPLGtLQUFrSyxDQUFDO1FBRTVLLEtBQUssa0JBQWtCLENBQUM7UUFDeEIsS0FBSyxvQkFBb0I7WUFDdkIsT0FBTyw0SkFBNEosQ0FBQztRQUV0SyxLQUFLLG1DQUFtQyxDQUFDO1FBQ3pDLEtBQUssMkJBQTJCLENBQUM7UUFDakMsS0FBSyxpQ0FBaUMsQ0FBQztRQUN2QyxLQUFLLDZCQUE2QjtZQUNoQyxPQUFPLDJLQUEySyxDQUFDO1FBRXJMO1lBQ0UsT0FBTyxJQUFJLENBQUM7SUFDaEIsQ0FBQztBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvL1xuLy8gZmV0Y2gtaGVscGVycy50c1xuLy8gQ29kZVZpYmUgQ29yZVxuLy9cbi8vIFdyYXBwZXIgYXJvdW5kIE5vZGUncyBidWlsdC1pbiBmZXRjaCgpIHRoYXQgc3VyZmFjZXMgdGhlIHVuZGVybHlpbmcgY2F1c2Vcbi8vIG9mIFwiZmV0Y2ggZmFpbGVkXCIgZXJyb3JzIHdpdGggcGxhdGZvcm0tc3BlY2lmaWMgZGlhZ25vc3RpYyB0aXBzLlxuLy9cbi8vIEJhY2tncm91bmQ6IE5vZGUgMTgrJ3MgYnVpbHQtaW4gZmV0Y2ggKHZpYSB1bmRpY2kpIHRocm93cyBhIGdlbmVyaWNcbi8vIFR5cGVFcnJvciB3aXRoIG1lc3NhZ2UgXCJmZXRjaCBmYWlsZWRcIiBmb3IgYWxsIG5ldHdvcmstbGV2ZWwgZXJyb3JzIChETlNcbi8vIGZhaWx1cmVzLCB0aW1lb3V0cywgVExTIGlzc3VlcywgZXRjLikuIFRoZSByZWFsIGNhdXNlIGlzIGJ1cmllZCBpbiB0aGVcbi8vIGVycm9yJ3MgLmNhdXNlIHByb3BlcnR5LiBUaGlzIHdyYXBwZXIgdW5wYWNrcyB0aGF0IGNhdXNlIGFuZCByZXR1cm5zIGFcbi8vIGRldGFpbGVkLCBhY3Rpb25hYmxlIGVycm9yIG1lc3NhZ2Ug4oCUIGNyaXRpY2FsIGZvciBXU0wgdXNlcnMgd2hlcmUgZmV0Y2hcbi8vIGZhaWx1cmVzIGFyZSBjb21tb24gYW5kIHVzdWFsbHkgZml4YWJsZSB3aXRoIGtub3duIHdvcmthcm91bmRzLlxuLy9cblxuaW1wb3J0ICogYXMgZG5zIGZyb20gJ2Rucyc7XG5pbXBvcnQgKiBhcyBmcyBmcm9tICdmcyc7XG5cbi8vIE5vZGUgMTcrIGNoYW5nZWQgdGhlIGRlZmF1bHQgRE5TIHJlc3VsdCBvcmRlciBmcm9tICdpcHY0Zmlyc3QnIHRvXG4vLyAndmVyYmF0aW0nIChSRkMtY29tcGxpYW50IGJ1dCBwcm9ibGVtYXRpYyBmb3IgaG9zdHMgd2l0aCBicm9rZW4gSVB2NikuXG4vLyBPbiBXU0wgVWJ1bnR1IHNwZWNpZmljYWxseSwgdGhlIGtlcm5lbCBvZnRlbiBhZHZlcnRpc2VzIElQdjYgYWRkcmVzc2VzXG4vLyB2aWEgZ2V0YWRkcmluZm8gZXZlbiB0aG91Z2ggdGhlIFdTTCBuZXR3b3JrIG5hbWVzcGFjZSBoYXMgbm8gcm91dGUgdG9cbi8vIHRoZSBJUHY2IGludGVybmV0IOKAlCBjYXVzaW5nIGV2ZXJ5IElQdjYgY29ubmVjdGlvbiBhdHRlbXB0IHRvIGZhaWwgd2l0aFxuLy8gRUhPU1RVTlJFQUNILiBjdXJsIGhhbmRsZXMgdGhpcyB2aWEgSGFwcHkgRXllYmFsbHMgZmFsbGJhY2ssIGJ1dCB1bmRpY2lcbi8vIChOb2RlJ3MgYnVpbHQtaW4gZmV0Y2gpIGRvZXMgbm90LCBhbmQgdGhyb3dzIFwiZmV0Y2ggZmFpbGVkXCIgd2l0aG91dFxuLy8gZXZlciB0cnlpbmcgSVB2NC5cbi8vXG4vLyBXZSBhcHBseSAnaXB2NGZpcnN0JyBPTkxZIHdoZW4gcnVubmluZyBpbnNpZGUgV1NMLiBPbiBtYWNPUywgbmF0aXZlXG4vLyBMaW51eCwgYW5kIFdpbmRvd3Mgd2UgbGVhdmUgTm9kZSdzIGRlZmF1bHQgKCd2ZXJiYXRpbScpIGFsb25lIOKAlCB0aG9zZVxuLy8gcGxhdGZvcm1zIGhhdmUgaGVhbHRoeSBkdWFsLXN0YWNrIG5ldHdvcmtpbmcgYW5kIHRoZSBjdXJyZW50IGJlaGF2aW9yXG4vLyBpcyBjb3JyZWN0LiBOYXJyb3dseSBzY29waW5nIHRoZSBvdmVycmlkZSB0byBXU0wgbWVhbnMgemVybyBiZWhhdmlvcmFsXG4vLyBjaGFuZ2UgZm9yIG5vbi1XU0wgdXNlcnMgKGluY2x1ZGluZyBJUHY2LW9ubHkgbmV0d29ya3Mgd2hlcmUgaXB2NGZpcnN0XG4vLyB3b3VsZCBhZGQgZmlyc3QtY29ubmVjdGlvbiBsYXRlbmN5KS5cbi8vXG4vLyBUaGlzIHJ1bnMgYXMgYSBzaWRlIGVmZmVjdCBvZiBpbXBvcnRpbmcgY29kZXZpYmUtY29yZSdzIGZldGNoLWhlbHBlcnMsXG4vLyB3aGljaCBoYXBwZW5zIGVhcmx5IGluIGV2ZXJ5IHBsdWdpbidzIHN0YXJ0dXAgcGF0aC4gRG9jdW1lbnRlZCBoZXJlXG4vLyBzbyBmdXR1cmUgbWFpbnRhaW5lcnMgdW5kZXJzdGFuZCB3aHkgdGhlcmUncyBhIHNpZGUgZWZmZWN0IG9uIGltcG9ydC5cbmlmIChpc1J1bm5pbmdJbldTTCgpKSB7XG4gIHRyeSB7XG4gICAgZG5zLnNldERlZmF1bHRSZXN1bHRPcmRlcignaXB2NGZpcnN0Jyk7XG4gIH0gY2F0Y2gge1xuICAgIC8vIE9sZGVyIE5vZGUgdmVyc2lvbnMgKDwgMTguNikgZG9uJ3QgZXhwb3NlIHNldERlZmF1bHRSZXN1bHRPcmRlcjtcbiAgICAvLyBza2lwIHNpbGVudGx5LiBVc2VycyBvbiB0aG9zZSB2ZXJzaW9ucyBjYW4gc3RpbGwgc2V0IHRoZVxuICAgIC8vIE5PREVfT1BUSU9OUz1cIi0tZG5zLXJlc3VsdC1vcmRlcj1pcHY0Zmlyc3RcIiBlbnZpcm9ubWVudCB2YXJpYWJsZVxuICAgIC8vIG1hbnVhbGx5IGlmIHRoZXkgaGl0IElQdjYgaXNzdWVzLlxuICB9XG59XG5cbi8qKlxuICogRGV0ZWN0IHdoZXRoZXIgd2UncmUgcnVubmluZyBpbnNpZGUgV1NMICgxIG9yIDIpLiBSZXR1cm5zIGZhbHNlIG9uIGFueVxuICogbm9uLUxpbnV4IHBsYXRmb3JtIG9yIGlmIC9wcm9jL3N5cy9rZXJuZWwvb3NyZWxlYXNlIGlzIG5vdCByZWFkYWJsZS5cbiAqIER1cGxpY2F0ZWQgZnJvbSBhdXRoLXNlcnZpY2UudHMgYXMgYSBtb2R1bGUtbGV2ZWwgaGVscGVyIHNvIGl0IGNhbiBydW5cbiAqIGF0IGltcG9ydCB0aW1lLCBiZWZvcmUgYW55IGNsYXNzIGlzIGluc3RhbnRpYXRlZC5cbiAqL1xuZnVuY3Rpb24gaXNSdW5uaW5nSW5XU0woKTogYm9vbGVhbiB7XG4gIGlmIChwcm9jZXNzLnBsYXRmb3JtICE9PSAnbGludXgnKSByZXR1cm4gZmFsc2U7XG4gIHRyeSB7XG4gICAgY29uc3Qgb3NSZWxlYXNlID0gZnMucmVhZEZpbGVTeW5jKCcvcHJvYy9zeXMva2VybmVsL29zcmVsZWFzZScsICd1dGY4Jyk7XG4gICAgcmV0dXJuIC9taWNyb3NvZnR8d3NsL2kudGVzdChvc1JlbGVhc2UpO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cblxuLyoqXG4gKiBXcmFwcyBmZXRjaCgpIGFuZCByZXdyaXRlcyBcImZldGNoIGZhaWxlZFwiIGVycm9ycyB0byBpbmNsdWRlIHRoZSB1bmRlcmx5aW5nXG4gKiBjYXVzZSBhbmQgYSB1c2VyLWFjdGlvbmFibGUgZGlhZ25vc3RpYyB0aXAgd2hlbiBwb3NzaWJsZS4gTm9uLW5ldHdvcmsgZXJyb3JzXG4gKiBhbmQgSFRUUCBlcnJvciByZXNwb25zZXMgKG5vbi0yeHgpIGFyZSBub3QgYWZmZWN0ZWQg4oCUIHRoZSBjYWxsZXIgc3RpbGxcbiAqIGhhbmRsZXMgcmVzcG9uc2Uub2sgY2hlY2tzIHRoZW1zZWx2ZXMuXG4gKlxuICogQHBhcmFtIHVybCBUaGUgVVJMIHRvIGZldGNoXG4gKiBAcGFyYW0gaW5pdCBTdGFuZGFyZCBmZXRjaCBpbml0IG9wdGlvbnNcbiAqIEBwYXJhbSBjb250ZXh0IE9wdGlvbmFsIHNob3J0IGxhYmVsIChlLmcuIFwidG9rZW4gZXhjaGFuZ2VcIikgZm9yIHRoZSBlcnJvciBtZXNzYWdlXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBmZXRjaFdpdGhEaWFnbm9zdGljcyhcbiAgdXJsOiBzdHJpbmcsXG4gIGluaXQ/OiBhbnksXG4gIGNvbnRleHQ/OiBzdHJpbmdcbik6IFByb21pc2U8UmVzcG9uc2U+IHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gYXdhaXQgZmV0Y2godXJsLCBpbml0KTtcbiAgfSBjYXRjaCAoZXJyOiBhbnkpIHtcbiAgICAvLyBOb2RlJ3MgdW5kaWNpIHdyYXBzIHJlYWwgZXJyb3JzIGluIGVyci5jYXVzZVxuICAgIGNvbnN0IGNhdXNlQ29kZTogc3RyaW5nIHwgdW5kZWZpbmVkID0gZXJyPy5jYXVzZT8uY29kZTtcbiAgICBjb25zdCBjYXVzZU1lc3NhZ2U6IHN0cmluZyB8IHVuZGVmaW5lZCA9IGVycj8uY2F1c2U/Lm1lc3NhZ2U7XG4gICAgY29uc3QgY2F1c2VTdW1tYXJ5ID0gY2F1c2VDb2RlIHx8IGNhdXNlTWVzc2FnZSB8fCBlcnI/Lm1lc3NhZ2UgfHwgJ3Vua25vd24nO1xuXG4gICAgY29uc3QgdGlwID0gZ2V0RGlhZ25vc3RpY1RpcChjYXVzZUNvZGUpO1xuICAgIGNvbnN0IGNvbnRleHRMYWJlbCA9IGNvbnRleHQgPyBgJHtjb250ZXh0fTogYCA6ICcnO1xuICAgIGNvbnN0IHBsYXRmb3JtSW5mbyA9IGBOb2RlICR7cHJvY2Vzcy52ZXJzaW9ufSBvbiAke3Byb2Nlc3MucGxhdGZvcm19YDtcblxuICAgIGNvbnN0IGRldGFpbExpbmVzOiBzdHJpbmdbXSA9IFtcbiAgICAgIGAke2NvbnRleHRMYWJlbH1DYW5ub3QgcmVhY2ggJHt1cmx9YCxcbiAgICAgIGAgIFVuZGVybHlpbmcgZXJyb3I6ICR7Y2F1c2VTdW1tYXJ5fWAsXG4gICAgXTtcbiAgICBpZiAodGlwKSB7XG4gICAgICBkZXRhaWxMaW5lcy5wdXNoKGAgIFN1Z2dlc3RlZCBmaXg6ICR7dGlwfWApO1xuICAgIH1cbiAgICBkZXRhaWxMaW5lcy5wdXNoKGAgIFBsYXRmb3JtOiAke3BsYXRmb3JtSW5mb31gKTtcblxuICAgIGNvbnN0IGRldGFpbGVkRXJyb3IgPSBuZXcgRXJyb3IoZGV0YWlsTGluZXMuam9pbignXFxuJykpO1xuICAgIC8vIFByZXNlcnZlIHRoZSBvcmlnaW5hbCBlcnJvciBhcyBjYXVzZSBzbyBjYWxsZXJzIGNhbiBzdGlsbCBpbnNwZWN0IGl0XG4gICAgKGRldGFpbGVkRXJyb3IgYXMgYW55KS5jYXVzZSA9IGVycjtcbiAgICB0aHJvdyBkZXRhaWxlZEVycm9yO1xuICB9XG59XG5cbi8qKlxuICogTWFwIGNvbW1vbiBOb2RlIG5ldHdvcmsgZXJyb3IgY29kZXMgdG8gdXNlci1hY3Rpb25hYmxlIGRpYWdub3N0aWMgaGludHMuXG4gKiBSZXR1cm5zIG51bGwgaWYgdGhlIGNvZGUgaXNuJ3Qgb25lIHdlIHJlY29nbml6ZS5cbiAqL1xuZnVuY3Rpb24gZ2V0RGlhZ25vc3RpY1RpcChlcnJvckNvZGU/OiBzdHJpbmcpOiBzdHJpbmcgfCBudWxsIHtcbiAgaWYgKCFlcnJvckNvZGUpIHJldHVybiBudWxsO1xuXG4gIHN3aXRjaCAoZXJyb3JDb2RlKSB7XG4gICAgY2FzZSAnRU5PVEZPVU5EJzpcbiAgICBjYXNlICdFQUlfQUdBSU4nOlxuICAgICAgcmV0dXJuICdETlMgcmVzb2x1dGlvbiBmYWlsZWQuIE9uIFdTTCBVYnVudHUsIGNoZWNrIC9ldGMvcmVzb2x2LmNvbmYsIG9yIHRyeSBydW5uaW5nIHdpdGggTk9ERV9PUFRJT05TPVwiLS1kbnMtcmVzdWx0LW9yZGVyPWlwdjRmaXJzdFwiLic7XG5cbiAgICBjYXNlICdFVElNRURPVVQnOlxuICAgIGNhc2UgJ0VDT05OUkVGVVNFRCc6XG4gICAgY2FzZSAnRUNPTk5SRVNFVCc6XG4gICAgY2FzZSAnRUhPU1RVTlJFQUNIJzpcbiAgICBjYXNlICdFTkVUVU5SRUFDSCc6XG4gICAgICByZXR1cm4gJ05ldHdvcmsgdW5yZWFjaGFibGUuIE9uIFdTTCBVYnVudHUsIHRyeSBOT0RFX09QVElPTlM9XCItLWRucy1yZXN1bHQtb3JkZXI9aXB2NGZpcnN0XCIgKFdTTFxcJ3MgSVB2NiBpcyBvZnRlbiBicm9rZW4pLiBJZiBiZWhpbmQgYSBjb3Jwb3JhdGUgcHJveHksIHNldCBIVFRQU19QUk9YWS4nO1xuXG4gICAgY2FzZSAnQ0VSVF9IQVNfRVhQSVJFRCc6XG4gICAgY2FzZSAnQ0VSVF9OT1RfWUVUX1ZBTElEJzpcbiAgICAgIHJldHVybiAnVExTIGNlcnRpZmljYXRlIHRpbWUgZXJyb3Ig4oCUIGxpa2VseSBzeXN0ZW0gY2xvY2sgZHJpZnQuIE9uIFdTTCwgcnVuIGBzdWRvIGh3Y2xvY2sgLXNgLCBvciBzaHV0IGRvd24gV1NMIGZyb20gUG93ZXJTaGVsbCB3aXRoIGB3c2wgLS1zaHV0ZG93bmAgYW5kIHJlc3RhcnQuJztcblxuICAgIGNhc2UgJ1VOQUJMRV9UT19HRVRfSVNTVUVSX0NFUlRfTE9DQUxMWSc6XG4gICAgY2FzZSAnU0VMRl9TSUdORURfQ0VSVF9JTl9DSEFJTic6XG4gICAgY2FzZSAnVU5BQkxFX1RPX1ZFUklGWV9MRUFGX1NJR05BVFVSRSc6XG4gICAgY2FzZSAnREVQVEhfWkVST19TRUxGX1NJR05FRF9DRVJUJzpcbiAgICAgIHJldHVybiAnQ29ycG9yYXRlIEhUVFBTIHByb3h5IGRldGVjdGVkIOKAlCB0aGUgVExTIGNlcnQgaXMgbm90IHRydXN0ZWQgYnkgTm9kZS4gU2V0IE5PREVfRVhUUkFfQ0FfQ0VSVFM9L3BhdGgvdG8vY29ycG9yYXRlLWNhLnBlbSwgb3IgY29uZmlndXJlIEhUVFBTX1BST1hZIGlmIGEgcHJveHkgaXMgcmVxdWlyZWQuJztcblxuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gbnVsbDtcbiAgfVxufVxuIl19
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quantiya/codevibe-claude-plugin",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "Mobile companion for Claude Code - monitor and control your Claude Code sessions from your
|
|
3
|
+
"version": "1.0.9",
|
|
4
|
+
"description": "Mobile companion for Claude Code - monitor and control your Claude Code sessions from your phone with CodeVibe",
|
|
5
5
|
"main": "dist/server.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"codevibe-claude": "./bin/codevibe-claude"
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"dev": "ts-node src/server.ts",
|
|
23
23
|
"start": "node dist/server.js",
|
|
24
24
|
"watch": "tsc --watch",
|
|
25
|
-
"test": "
|
|
25
|
+
"test": "jest --config jest.config.js --forceExit"
|
|
26
26
|
},
|
|
27
27
|
"repository": {
|
|
28
28
|
"type": "git",
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"darwin"
|
|
54
54
|
],
|
|
55
55
|
"dependencies": {
|
|
56
|
-
"@quantiya/codevibe-core": "^1.0.
|
|
56
|
+
"@quantiya/codevibe-core": "^1.0.3",
|
|
57
57
|
"dotenv": "^16.6.1",
|
|
58
58
|
"express": "^5.1.0",
|
|
59
59
|
"graphql": "^16.12.0",
|
|
@@ -70,9 +70,12 @@
|
|
|
70
70
|
],
|
|
71
71
|
"devDependencies": {
|
|
72
72
|
"@types/express": "^5.0.5",
|
|
73
|
+
"@types/jest": "^30.0.0",
|
|
73
74
|
"@types/node": "^24.10.1",
|
|
74
75
|
"@types/uuid": "^10.0.0",
|
|
75
76
|
"@types/ws": "^8.18.1",
|
|
77
|
+
"jest": "^30.3.0",
|
|
78
|
+
"ts-jest": "^29.4.9",
|
|
76
79
|
"ts-node": "^10.9.2",
|
|
77
80
|
"typescript": "^5.9.3"
|
|
78
81
|
},
|