@dollhousemcp/mcp-server 2.0.11 → 2.0.12-rc.2
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/CHANGELOG.md +33 -0
- package/dist/config/ConfigManager.d.ts +34 -0
- package/dist/config/ConfigManager.d.ts.map +1 -1
- package/dist/config/ConfigManager.js +46 -1
- package/dist/config/env.d.ts +18 -0
- package/dist/config/env.d.ts.map +1 -1
- package/dist/config/env.js +89 -2
- package/dist/di/Container.d.ts +1 -0
- package/dist/di/Container.d.ts.map +1 -1
- package/dist/di/Container.js +38 -2
- package/dist/elements/agents/AgentManager.js +2 -2
- package/dist/generated/version.d.ts +2 -2
- package/dist/generated/version.d.ts.map +1 -1
- package/dist/generated/version.js +3 -3
- package/dist/handlers/mcp-aql/GatekeeperSession.d.ts.map +1 -1
- package/dist/handlers/mcp-aql/GatekeeperSession.js +3 -2
- package/dist/handlers/mcp-aql/MCPAQLHandler.d.ts.map +1 -1
- package/dist/handlers/mcp-aql/MCPAQLHandler.js +11 -3
- package/dist/handlers/mcp-aql/OperationSchema.d.ts.map +1 -1
- package/dist/handlers/mcp-aql/OperationSchema.js +11 -6
- package/dist/handlers/mcp-aql/policies/ToolClassification.d.ts.map +1 -1
- package/dist/handlers/mcp-aql/policies/ToolClassification.js +8 -1
- package/dist/index.js +53 -3
- package/dist/security/InputNormalizer.d.ts +4 -6
- package/dist/security/InputNormalizer.d.ts.map +1 -1
- package/dist/security/InputNormalizer.js +10 -16
- package/dist/security/audit/config/suppressions.d.ts.map +1 -1
- package/dist/security/audit/config/suppressions.js +26 -1
- package/dist/security/constants.d.ts +7 -0
- package/dist/security/constants.d.ts.map +1 -1
- package/dist/security/constants.js +10 -1
- package/dist/security/contentValidator.d.ts.map +1 -1
- package/dist/security/contentValidator.js +14 -6
- package/dist/security/encryption/PatternEncryptor.d.ts.map +1 -1
- package/dist/security/encryption/PatternEncryptor.js +18 -10
- package/dist/security/securityMonitor.d.ts +1 -1
- package/dist/security/securityMonitor.d.ts.map +1 -1
- package/dist/security/securityMonitor.js +1 -1
- package/dist/security/tokenManager.d.ts +18 -2
- package/dist/security/tokenManager.d.ts.map +1 -1
- package/dist/security/tokenManager.js +47 -15
- package/dist/security/validators/unicodeValidator.d.ts +4 -5
- package/dist/security/validators/unicodeValidator.d.ts.map +1 -1
- package/dist/security/validators/unicodeValidator.js +19 -20
- package/dist/services/VerificationNotifier.d.ts.map +1 -1
- package/dist/services/VerificationNotifier.js +15 -13
- package/dist/services/validation/GenericElementValidator.js +5 -5
- package/dist/web/console/IngestRoutes.d.ts +14 -2
- package/dist/web/console/IngestRoutes.d.ts.map +1 -1
- package/dist/web/console/IngestRoutes.js +69 -5
- package/dist/web/console/LeaderElection.d.ts +37 -3
- package/dist/web/console/LeaderElection.d.ts.map +1 -1
- package/dist/web/console/LeaderElection.js +67 -7
- package/dist/web/console/LeaderForwardingSink.d.ts +19 -3
- package/dist/web/console/LeaderForwardingSink.d.ts.map +1 -1
- package/dist/web/console/LeaderForwardingSink.js +44 -9
- package/dist/web/console/PromotionManager.d.ts +29 -0
- package/dist/web/console/PromotionManager.d.ts.map +1 -0
- package/dist/web/console/PromotionManager.js +94 -0
- package/dist/web/console/SessionNames.d.ts +7 -0
- package/dist/web/console/SessionNames.d.ts.map +1 -1
- package/dist/web/console/SessionNames.js +10 -1
- package/dist/web/console/UnifiedConsole.d.ts +26 -1
- package/dist/web/console/UnifiedConsole.d.ts.map +1 -1
- package/dist/web/console/UnifiedConsole.js +143 -20
- package/dist/web/portDiscovery.d.ts +4 -3
- package/dist/web/portDiscovery.d.ts.map +1 -1
- package/dist/web/portDiscovery.js +7 -5
- package/dist/web/public/app.js +35 -18
- package/dist/web/public/consoleAuth.js +152 -0
- package/dist/web/public/index.html +243 -9
- package/dist/web/public/logs.js +1 -1
- package/dist/web/public/metrics.js +3 -3
- package/dist/web/public/permissions.js +1 -1
- package/dist/web/public/security.css +396 -0
- package/dist/web/public/security.js +393 -0
- package/dist/web/public/sessions.css +54 -4
- package/dist/web/public/sessions.js +46 -6
- package/dist/web/public/setup.css +439 -0
- package/dist/web/public/setup.js +490 -18
- package/dist/web/public/styles.css +10 -0
- package/dist/web/routes/permissionRoutes.d.ts.map +1 -1
- package/dist/web/routes/permissionRoutes.js +8 -3
- package/dist/web/routes/setupRoutes.d.ts +4 -0
- package/dist/web/routes/setupRoutes.d.ts.map +1 -1
- package/dist/web/routes/setupRoutes.js +418 -7
- package/dist/web/routes.d.ts.map +1 -1
- package/dist/web/routes.js +9 -5
- package/dist/web/server.d.ts +49 -3
- package/dist/web/server.d.ts.map +1 -1
- package/dist/web/server.js +282 -82
- package/package.json +11 -2
- package/server.json +2 -2
|
@@ -13,11 +13,63 @@
|
|
|
13
13
|
* @since v2.1.0 — Issue #1700
|
|
14
14
|
*/
|
|
15
15
|
import { logger } from '../../utils/logger.js';
|
|
16
|
-
import { electLeader, isLeaderWebConsoleReachable, forceClaimLeadership, startHeartbeat, registerLeaderCleanup, } from './LeaderElection.js';
|
|
16
|
+
import { electLeader, isLeaderWebConsoleReachable, forceClaimLeadership, startHeartbeat, registerLeaderCleanup, detectLegacyLeader, } from './LeaderElection.js';
|
|
17
17
|
import { createIngestRoutes } from './IngestRoutes.js';
|
|
18
18
|
import { LeaderForwardingLogSink, SessionHeartbeat, } from './LeaderForwardingSink.js';
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
import { PromotionManager } from './PromotionManager.js';
|
|
20
|
+
import { ConsoleTokenStore } from './consoleToken.js';
|
|
21
|
+
import { env } from '../../config/env.js';
|
|
22
|
+
/**
|
|
23
|
+
* Default console port from the env var. Used as fallback when no port
|
|
24
|
+
* is provided via config file or options. The resolution hierarchy is:
|
|
25
|
+
* 1. options.port (from config file, resolved by the DI container)
|
|
26
|
+
* 2. DOLLHOUSE_WEB_CONSOLE_PORT env var
|
|
27
|
+
* 3. 41715 (hardcoded default in env.ts)
|
|
28
|
+
*/
|
|
29
|
+
const DEFAULT_CONSOLE_PORT = env.DOLLHOUSE_WEB_CONSOLE_PORT;
|
|
30
|
+
/**
|
|
31
|
+
* Check for a running legacy (pre-authentication) DollhouseMCP console and
|
|
32
|
+
* log a WARN-level message if one is found (#1794).
|
|
33
|
+
*
|
|
34
|
+
* Extracted from `startUnifiedConsole` so the wiring can be integration-
|
|
35
|
+
* tested in isolation without spinning up a full web server and leader
|
|
36
|
+
* election. The implementation is fire-and-forget: detection failures
|
|
37
|
+
* are logged at DEBUG and never propagate, because a failure here must
|
|
38
|
+
* not block leader election of the authenticated console.
|
|
39
|
+
*
|
|
40
|
+
* @param currentPort - The port the authenticated console intends to
|
|
41
|
+
* bind to. Used in the warning message to help the
|
|
42
|
+
* user tell the two consoles apart.
|
|
43
|
+
* @param detect - Optional injection point for the detection
|
|
44
|
+
* function. Defaults to `detectLegacyLeader`. Tests
|
|
45
|
+
* pass a stub.
|
|
46
|
+
* @param log - Optional injection point for the logger. Defaults
|
|
47
|
+
* to the module logger. Tests pass a spy.
|
|
48
|
+
* @returns The legacy leader info from `detect()`, or null if detection
|
|
49
|
+
* threw. Exposed so tests can assert the full result shape.
|
|
50
|
+
*/
|
|
51
|
+
export async function warnIfLegacyConsolePresent(currentPort, detect = detectLegacyLeader, log = logger) {
|
|
52
|
+
try {
|
|
53
|
+
const legacy = await detect();
|
|
54
|
+
if (legacy.legacyRunning) {
|
|
55
|
+
log.warn(`[UnifiedConsole] Legacy (pre-authentication) DollhouseMCP console detected ` +
|
|
56
|
+
`(pid=${legacy.pid}, port=${legacy.port}). Both consoles will run ` +
|
|
57
|
+
`independently on different ports with different security posture. ` +
|
|
58
|
+
`The authenticated console (this process) uses port ${currentPort}; ` +
|
|
59
|
+
`the legacy console uses port ${legacy.port ?? 3939}. ` +
|
|
60
|
+
`For consistent security, update the legacy installation to a ` +
|
|
61
|
+
`version with the authenticated console.`);
|
|
62
|
+
}
|
|
63
|
+
return legacy;
|
|
64
|
+
}
|
|
65
|
+
catch (err) {
|
|
66
|
+
// Best-effort — never block election on a detection failure
|
|
67
|
+
log.debug('[UnifiedConsole] Legacy leader detection failed', {
|
|
68
|
+
error: err instanceof Error ? err.message : String(err),
|
|
69
|
+
});
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
21
73
|
/**
|
|
22
74
|
* Start the unified web console.
|
|
23
75
|
*
|
|
@@ -25,29 +77,54 @@ const CONSOLE_PORT = 3939;
|
|
|
25
77
|
* or sets up event forwarding (follower).
|
|
26
78
|
*/
|
|
27
79
|
export async function startUnifiedConsole(options) {
|
|
28
|
-
|
|
80
|
+
// Resolve port: options (config file) → env var → default
|
|
81
|
+
const consolePort = options.port || DEFAULT_CONSOLE_PORT;
|
|
82
|
+
logger.debug(`[UnifiedConsole] Port resolved: ${consolePort}` +
|
|
83
|
+
(options.port ? ' (from config file)' : ` (from env/default)`));
|
|
84
|
+
// Legacy-leader detection (#1794) — warn the user if a pre-auth
|
|
85
|
+
// DollhouseMCP console is running alongside this authenticated one.
|
|
86
|
+
// They will coexist fine because of port + lock + token file isolation,
|
|
87
|
+
// but the user should know both exist so the differing security posture
|
|
88
|
+
// between them doesn't look like a bug.
|
|
89
|
+
await warnIfLegacyConsolePresent(consolePort);
|
|
90
|
+
let election = await electLeader(options.sessionId, consolePort);
|
|
29
91
|
// If we lost the election, check if the leader is actually running a web console.
|
|
30
92
|
// An MCP stdio process may hold leadership but not serve web routes.
|
|
31
93
|
// In that case, force a takeover so the web console works properly.
|
|
32
94
|
if (election.role === 'follower') {
|
|
33
95
|
const reachable = await isLeaderWebConsoleReachable(election.leaderInfo);
|
|
34
96
|
if (!reachable) {
|
|
35
|
-
election = await forceClaimLeadership(options.sessionId,
|
|
97
|
+
election = await forceClaimLeadership(options.sessionId, consolePort);
|
|
36
98
|
}
|
|
37
99
|
}
|
|
38
100
|
if (election.role === 'leader') {
|
|
39
|
-
return startAsLeader(options, election);
|
|
101
|
+
return startAsLeader(options, election, consolePort);
|
|
40
102
|
}
|
|
41
103
|
else {
|
|
42
|
-
return startAsFollower(options, election);
|
|
104
|
+
return startAsFollower(options, election, consolePort);
|
|
43
105
|
}
|
|
44
106
|
}
|
|
45
107
|
/**
|
|
46
108
|
* Start as the console leader.
|
|
47
|
-
* Binds port
|
|
109
|
+
* Binds the resolved console port (config file → env var → default),
|
|
110
|
+
* mounts all routes including ingestion, starts heartbeat.
|
|
48
111
|
*/
|
|
49
|
-
async function startAsLeader(options, election) {
|
|
112
|
+
async function startAsLeader(options, election, consolePort = DEFAULT_CONSOLE_PORT) {
|
|
50
113
|
const { startWebServer } = await import('../server.js');
|
|
114
|
+
const { pickRandomPuppetName } = await import('./SessionNames.js');
|
|
115
|
+
// Initialize the console token store (#1780). Creates the token file on
|
|
116
|
+
// first run, reads the existing tokens on subsequent runs. The token is
|
|
117
|
+
// persistent across restarts — only rotated on explicit request (Phase 2).
|
|
118
|
+
// Feature flag DOLLHOUSE_WEB_AUTH_ENABLED controls enforcement; the file
|
|
119
|
+
// is generated regardless so consumers can attach tokens preemptively.
|
|
120
|
+
const tokenStore = new ConsoleTokenStore(env.DOLLHOUSE_CONSOLE_TOKEN_FILE);
|
|
121
|
+
const primaryToken = await tokenStore.ensureInitialized(pickRandomPuppetName());
|
|
122
|
+
logger.info('[UnifiedConsole] Console token store initialized', {
|
|
123
|
+
tokenId: primaryToken.id,
|
|
124
|
+
tokenName: primaryToken.name,
|
|
125
|
+
file: tokenStore.getFilePath(),
|
|
126
|
+
authEnforced: env.DOLLHOUSE_WEB_AUTH_ENABLED,
|
|
127
|
+
});
|
|
51
128
|
// Pre-create a placeholder broadcast that we'll wire up after the server starts
|
|
52
129
|
let liveBroadcast;
|
|
53
130
|
let liveMetricsOnSnapshot;
|
|
@@ -58,15 +135,41 @@ async function startAsLeader(options, election) {
|
|
|
58
135
|
});
|
|
59
136
|
// Register the leader as a session
|
|
60
137
|
ingestResult.registerLeaderSession(options.sessionId, process.pid);
|
|
61
|
-
//
|
|
62
|
-
|
|
138
|
+
// Register the web console itself so the session indicator is never empty (#1805)
|
|
139
|
+
ingestResult.registerConsoleSession();
|
|
140
|
+
// Start the web server with ingest routes mounted before the SPA fallback.
|
|
141
|
+
// If the port is occupied by a stale process, retry with exponential backoff.
|
|
142
|
+
const serverOpts = {
|
|
63
143
|
portfolioDir: options.portfolioDir,
|
|
64
144
|
memorySink: options.memorySink,
|
|
65
145
|
metricsSink: options.metricsSink,
|
|
66
|
-
port:
|
|
146
|
+
port: consolePort,
|
|
67
147
|
additionalRouters: [ingestResult.router],
|
|
148
|
+
tokenStore,
|
|
68
149
|
...(options.mcpAqlHandler ? { mcpAqlHandler: options.mcpAqlHandler } : {}),
|
|
69
|
-
}
|
|
150
|
+
};
|
|
151
|
+
const BIND_RETRY_DELAYS = env.DOLLHOUSE_CONSOLE_BIND_RETRY_DELAYS?.length
|
|
152
|
+
? env.DOLLHOUSE_CONSOLE_BIND_RETRY_DELAYS
|
|
153
|
+
: [1000, 2000, 4000];
|
|
154
|
+
const webResult = await startWebServer(serverOpts);
|
|
155
|
+
// If the port is occupied, retry the bind only — don't recreate the Express
|
|
156
|
+
// app and routes (startWebServer early-returns when serverRunning is false
|
|
157
|
+
// but the app is already configured). We call retryBind on the existing app.
|
|
158
|
+
if (webResult.bindResult && !webResult.bindResult.success && webResult.bindResult.error === 'EADDRINUSE' && webResult.app) {
|
|
159
|
+
const { retryBind } = await import('../server.js');
|
|
160
|
+
for (let i = 0; i < BIND_RETRY_DELAYS.length; i++) {
|
|
161
|
+
logger.warn(`[UnifiedConsole] Port ${consolePort} occupied — retry ${i + 1}/${BIND_RETRY_DELAYS.length} in ${BIND_RETRY_DELAYS[i]}ms`);
|
|
162
|
+
await new Promise(r => setTimeout(r, BIND_RETRY_DELAYS[i]));
|
|
163
|
+
const retryResult = await retryBind(webResult.app, consolePort, serverOpts);
|
|
164
|
+
if (retryResult.success) {
|
|
165
|
+
webResult.bindResult = retryResult;
|
|
166
|
+
break;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
if (webResult.bindResult && !webResult.bindResult.success) {
|
|
170
|
+
logger.error(`[UnifiedConsole] Leader failed to bind port ${consolePort} after ${BIND_RETRY_DELAYS.length} retries — console unavailable`);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
70
173
|
// Wire SSE broadcasts for this leader's own events
|
|
71
174
|
options.wireSSEBroadcasts(webResult, options.metricsSink);
|
|
72
175
|
// Now wire the live broadcast functions into the ingest routes
|
|
@@ -87,13 +190,13 @@ async function startAsLeader(options, election) {
|
|
|
87
190
|
const stopHeartbeat = startHeartbeat(election.leaderInfo);
|
|
88
191
|
registerLeaderCleanup();
|
|
89
192
|
logger.info('[UnifiedConsole] Leader started', {
|
|
90
|
-
sessionId: options.sessionId, port:
|
|
193
|
+
sessionId: options.sessionId, port: consolePort, pid: process.pid,
|
|
91
194
|
role: 'leader', ingestRoutes: ['/api/ingest/logs', '/api/ingest/metrics', '/api/ingest/session', '/api/sessions'],
|
|
92
195
|
});
|
|
93
196
|
return {
|
|
94
197
|
role: 'leader',
|
|
95
198
|
election,
|
|
96
|
-
port:
|
|
199
|
+
port: consolePort,
|
|
97
200
|
cleanup: async () => {
|
|
98
201
|
stopHeartbeat();
|
|
99
202
|
},
|
|
@@ -103,13 +206,33 @@ async function startAsLeader(options, election) {
|
|
|
103
206
|
* Start as a follower.
|
|
104
207
|
* Registers forwarding sinks with the LogManager, starts session heartbeat.
|
|
105
208
|
*/
|
|
106
|
-
async function startAsFollower(options, election) {
|
|
209
|
+
async function startAsFollower(options, election, consolePort = DEFAULT_CONSOLE_PORT) {
|
|
107
210
|
const leaderUrl = `http://127.0.0.1:${election.leaderInfo.port}`;
|
|
108
|
-
//
|
|
109
|
-
|
|
211
|
+
// Read the console auth token (#1780) written by the leader. May be null
|
|
212
|
+
// if the file doesn't exist yet — the sinks handle that gracefully and
|
|
213
|
+
// simply omit the Bearer header, which is fine when auth is not enforced.
|
|
214
|
+
const { getPrimaryTokenFromFile } = await import('./consoleToken.js');
|
|
215
|
+
const authToken = await getPrimaryTokenFromFile(env.DOLLHOUSE_CONSOLE_TOKEN_FILE);
|
|
216
|
+
if (authToken) {
|
|
217
|
+
logger.debug('[UnifiedConsole] Follower loaded console auth token');
|
|
218
|
+
}
|
|
219
|
+
else {
|
|
220
|
+
logger.debug('[UnifiedConsole] No console auth token file found; follower will POST without Bearer header');
|
|
221
|
+
}
|
|
222
|
+
// Per-instance promotion manager — tracks its own attempt counter so
|
|
223
|
+
// multiple followers don't interfere with each other's promotion budgets.
|
|
224
|
+
const promotionMgr = new PromotionManager(options, consolePort, startAsLeader, startAsFollower);
|
|
225
|
+
// Declare sessionHeartbeat before the sink so the closure can capture it.
|
|
226
|
+
// Both are initialized before the callback could possibly fire (needs 5+ failed flushes).
|
|
227
|
+
let sessionHeartbeat;
|
|
228
|
+
// Register a forwarding log sink with leader-death callback (#1850).
|
|
229
|
+
const forwardingSink = new LeaderForwardingLogSink(leaderUrl, options.sessionId, authToken, () => {
|
|
230
|
+
promotionMgr.promote(forwardingSink, sessionHeartbeat)
|
|
231
|
+
.catch(err => logger.error('[UnifiedConsole] Promotion crashed', { error: String(err) }));
|
|
232
|
+
});
|
|
110
233
|
options.registerLogSink(forwardingSink);
|
|
111
234
|
// Start session heartbeat to the leader
|
|
112
|
-
|
|
235
|
+
sessionHeartbeat = new SessionHeartbeat(leaderUrl, options.sessionId, process.pid, authToken);
|
|
113
236
|
await sessionHeartbeat.start();
|
|
114
237
|
logger.info('[UnifiedConsole] Follower started', {
|
|
115
238
|
sessionId: options.sessionId, pid: process.pid, role: 'follower',
|
|
@@ -125,4 +248,4 @@ async function startAsFollower(options, election) {
|
|
|
125
248
|
},
|
|
126
249
|
};
|
|
127
250
|
}
|
|
128
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVW5pZmllZENvbnNvbGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvd2ViL2NvbnNvbGUvVW5pZmllZENvbnNvbGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7R0FhRztBQU1ILE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUMvQyxPQUFPLEVBQ0wsV0FBVyxFQUNYLDJCQUEyQixFQUMzQixvQkFBb0IsRUFDcEIsY0FBYyxFQUNkLHFCQUFxQixHQUV0QixNQUFNLHFCQUFxQixDQUFDO0FBQzdCLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ3ZELE9BQU8sRUFDTCx1QkFBdUIsRUFDdkIsZ0JBQWdCLEdBQ2pCLE1BQU0sMkJBQTJCLENBQUM7QUFFbkMsZ0RBQWdEO0FBQ2hELE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQztBQWtDMUI7Ozs7O0dBS0c7QUFDSCxNQUFNLENBQUMsS0FBSyxVQUFVLG1CQUFtQixDQUFDLE9BQThCO0lBQ3RFLElBQUksUUFBUSxHQUFHLE1BQU0sV0FBVyxDQUFDLE9BQU8sQ0FBQyxTQUFTLEVBQUUsWUFBWSxDQUFDLENBQUM7SUFFbEUsa0ZBQWtGO0lBQ2xGLHFFQUFxRTtJQUNyRSxvRUFBb0U7SUFDcEUsSUFBSSxRQUFRLENBQUMsSUFBSSxLQUFLLFVBQVUsRUFBRSxDQUFDO1FBQ2pDLE1BQU0sU0FBUyxHQUFHLE1BQU0sMkJBQTJCLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ3pFLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUNmLFFBQVEsR0FBRyxNQUFNLG9CQUFvQixDQUFDLE9BQU8sQ0FBQyxTQUFTLEVBQUUsWUFBWSxDQUFDLENBQUM7UUFDekUsQ0FBQztJQUNILENBQUM7SUFFRCxJQUFJLFFBQVEsQ0FBQyxJQUFJLEtBQUssUUFBUSxFQUFFLENBQUM7UUFDL0IsT0FBTyxhQUFhLENB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biAqIFVuaWZpZWQgd2ViIGNvbnNvbGUgb3JjaGVzdHJhdG9yLlxuICpcbiAqIFRpZXMgdG9nZXRoZXIgbGVhZGVyIGVsZWN0aW9uLCBjb25zb2xlIHN0YXJ0dXAsIGZvbGxvd2VyIHdpcmluZyxcbiAqIGFuZCBzZXNzaW9uIGxpZmVjeWNsZSBtYW5hZ2VtZW50LiBUaGlzIGlzIHRoZSBtYWluIGVudHJ5IHBvaW50XG4gKiBjYWxsZWQgYnkgdGhlIERJIGNvbnRhaW5lciBkdXJpbmcgZGVmZXJyZWQgc2V0dXAuXG4gKlxuICogRmxvdzpcbiAqIDEuIFJ1biBsZWFkZXIgZWxlY3Rpb24gKHJlYWQgbG9jayBmaWxlLCBjbGFpbSBvciBmb2xsb3cpXG4gKiAyLiBJZiBsZWFkZXI6IHN0YXJ0IHdlYiBzZXJ2ZXIgb24gZml4ZWQgcG9ydCwgbW91bnQgaW5nZXN0IHJvdXRlcywgc3RhcnQgaGVhcnRiZWF0XG4gKiAzLiBJZiBmb2xsb3dlcjogcmVnaXN0ZXIgZm9yd2FyZGluZyBzaW5rcyB3aXRoIExvZ01hbmFnZXIsIHN0YXJ0IHNlc3Npb24gaGVhcnRiZWF0XG4gKlxuICogQHNpbmNlIHYyLjEuMCDigJQgSXNzdWUgIzE3MDBcbiAqL1xuXG5pbXBvcnQgdHlwZSB7IFVuaWZpZWRMb2dFbnRyeSB9IGZyb20gJy4uLy4uL2xvZ2dpbmcvdHlwZXMuanMnO1xuaW1wb3J0IHR5cGUgeyBNZXRyaWNTbmFwc2hvdCB9IGZyb20gJy4uLy4uL21ldHJpY3MvdHlwZXMuanMnO1xuaW1wb3J0IHR5cGUgeyBNZW1vcnlMb2dTaW5rIH0gZnJvbSAnLi4vLi4vbG9nZ2luZy9zaW5rcy9NZW1vcnlMb2dTaW5rLmpzJztcbmltcG9ydCB0eXBlIHsgTWVtb3J5TWV0cmljc1NpbmsgfSBmcm9tICcuLi8uLi9tZXRyaWNzL3NpbmtzL01lbW9yeU1ldHJpY3NTaW5rLmpzJztcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gJy4uLy4uL3V0aWxzL2xvZ2dlci5qcyc7XG5pbXBvcnQge1xuICBlbGVjdExlYWRlcixcbiAgaXNMZWFkZXJXZWJDb25zb2xlUmVhY2hhYmxlLFxuICBmb3JjZUNsYWltTGVhZGVyc2hpcCxcbiAgc3RhcnRIZWFydGJlYXQsXG4gIHJlZ2lzdGVyTGVhZGVyQ2xlYW51cCxcbiAgdHlwZSBFbGVjdGlvblJlc3VsdCxcbn0gZnJvbSAnLi9MZWFkZXJFbGVjdGlvbi5qcyc7XG5pbXBvcnQgeyBjcmVhdGVJbmdlc3RSb3V0ZXMgfSBmcm9tICcuL0luZ2VzdFJvdXRlcy5qcyc7XG5pbXBvcnQge1xuICBMZWFkZXJGb3J3YXJkaW5nTG9nU2luayxcbiAgU2Vzc2lvbkhlYXJ0YmVhdCxcbn0gZnJvbSAnLi9MZWFkZXJGb3J3YXJkaW5nU2luay5qcyc7XG5cbi8qKiBGaXhlZCBwb3J0IGZvciB0aGUgdW5pZmllZCBjb25zb2xlIGxlYWRlciAqL1xuY29uc3QgQ09OU09MRV9QT1JUID0gMzkzOTtcblxuLyoqXG4gKiBPcHRpb25zIGZvciBzdGFydGluZyB0aGUgdW5pZmllZCBjb25zb2xlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFVuaWZpZWRDb25zb2xlT3B0aW9ucyB7XG4gIC8qKiBUaGlzIHByb2Nlc3MncyB1bmlxdWUgc2Vzc2lvbiBJRCAqL1xuICBzZXNzaW9uSWQ6IHN0cmluZztcbiAgLyoqIFBvcnRmb2xpbyBiYXNlIGRpcmVjdG9yeSAoZm9yIHN0YXJ0V2ViU2VydmVyKSAqL1xuICBwb3J0Zm9saW9EaXI6IHN0cmluZztcbiAgLyoqIExvZyBtZW1vcnkgc2luayAoZm9yIGNvbnNvbGUgaGlzdG9yeSkgKi9cbiAgbWVtb3J5U2luazogTWVtb3J5TG9nU2luaztcbiAgLyoqIE1ldHJpY3MgbWVtb3J5IHNpbmsgKi9cbiAgbWV0cmljc1Npbms/OiBNZW1vcnlNZXRyaWNzU2luaztcbiAgLyoqIE1DUC1BUUwgaGFuZGxlciBmb3IgcGVybWlzc2lvbiByb3V0ZXMgKHR5cGVkIGFzIGFueSB0byBhdm9pZCBjaXJjdWxhciBpbXBvcnRzKSAqL1xuICBtY3BBcWxIYW5kbGVyPzogYW55O1xuICAvKiogQ2FsbGJhY2sgdG8gcmVnaXN0ZXIgYSBsb2cgc2luayB3aXRoIHRoZSBMb2dNYW5hZ2VyICovXG4gIHJlZ2lzdGVyTG9nU2luazogKHNpbms6IHsgd3JpdGUoZW50cnk6IFVuaWZpZWRMb2dFbnRyeSk6IHZvaWQ7IGZsdXNoKCk6IFByb21pc2U8dm9pZD47IGNsb3NlKCk6IFByb21pc2U8dm9pZD4gfSkgPT4gdm9pZDtcbiAgLyoqIENhbGxiYWNrIHRvIHdpcmUgU1NFIGJyb2FkY2FzdHMgYWZ0ZXIgd2ViIHNlcnZlciBzdGFydHMgKi9cbiAgd2lyZVNTRUJyb2FkY2FzdHM6ICh3ZWJSZXN1bHQ6IHsgbG9nQnJvYWRjYXN0PzogKGVudHJ5OiBVbmlmaWVkTG9nRW50cnkpID0+IHZvaWQ7IG1ldHJpY3NPblNuYXBzaG90PzogKHNuYXBzaG90OiBNZXRyaWNTbmFwc2hvdCkgPT4gdm9pZCB9LCBtZXRyaWNzU2luaz86IE1lbW9yeU1ldHJpY3NTaW5rKSA9PiB2b2lkO1xufVxuXG4vKipcbiAqIFJlc3VsdCBvZiBzdGFydGluZyB0aGUgdW5pZmllZCBjb25zb2xlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFVuaWZpZWRDb25zb2xlUmVzdWx0IHtcbiAgcm9sZTogJ2xlYWRlcicgfCAnZm9sbG93ZXInO1xuICBlbGVjdGlvbjogRWxlY3Rpb25SZXN1bHQ7XG4gIC8qKiBQb3J0IHRoZSBjb25zb2xlIGlzIHJ1bm5pbmcgb24gKGxlYWRlciBvbmx5KSAqL1xuICBwb3J0PzogbnVtYmVyO1xuICAvKiogQ2xlYW51cCBmdW5jdGlvbiB0byBjYWxsIG9uIHNodXRkb3duICovXG4gIGNsZWFudXA6ICgpID0+IFByb21pc2U8dm9pZD47XG59XG5cbi8qKlxuICogU3RhcnQgdGhlIHVuaWZpZWQgd2ViIGNvbnNvbGUuXG4gKlxuICogUnVucyBsZWFkZXIgZWxlY3Rpb24sIHRoZW4gZWl0aGVyIHN0YXJ0cyB0aGUgZnVsbCBjb25zb2xlIChsZWFkZXIpXG4gKiBvciBzZXRzIHVwIGV2ZW50IGZvcndhcmRpbmcgKGZvbGxvd2VyKS5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHN0YXJ0VW5pZmllZENvbnNvbGUob3B0aW9uczogVW5pZmllZENvbnNvbGVPcHRpb25zKTogUHJvbWlzZTxVbmlmaWVkQ29uc29sZVJlc3VsdD4ge1xuICBsZXQgZWxlY3Rpb24gPSBhd2FpdCBlbGVjdExlYWRlcihvcHRpb25zLnNlc3Npb25JZCwgQ09OU09MRV9QT1JUKTtcblxuICAvLyBJZiB3ZSBsb3N0IHRoZSBlbGVjdGlvbiwgY2hlY2sgaWYgdGhlIGxlYWRlciBpcyBhY3R1YWxseSBydW5uaW5nIGEgd2ViIGNvbnNvbGUuXG4gIC8vIEFuIE1DUCBzdGRpbyBwcm9jZXNzIG1heSBob2xkIGxlYWRlcnNoaXAgYnV0IG5vdCBzZXJ2ZSB3ZWIgcm91dGVzLlxuICAvLyBJbiB0aGF0IGNhc2UsIGZvcmNlIGEgdGFrZW92ZXIgc28gdGhlIHdlYiBjb25zb2xlIHdvcmtzIHByb3Blcmx5LlxuICBpZiAoZWxlY3Rpb24ucm9sZSA9PT0gJ2ZvbGxvd2VyJykge1xuICAgIGNvbnN0IHJlYWNoYWJsZSA9IGF3YWl0IGlzTGVhZGVyV2ViQ29uc29sZVJlYWNoYWJsZShlbGVjdGlvbi5sZWFkZXJJbmZvKTtcbiAgICBpZiAoIXJlYWNoYWJsZSkge1xuICAgICAgZWxlY3Rpb24gPSBhd2FpdCBmb3JjZUNsYWltTGVhZGVyc2hpcChvcHRpb25zLnNlc3Npb25JZCwgQ09OU09MRV9QT1JUKTtcbiAgICB9XG4gIH1cblxuICBpZiAoZWxlY3Rpb24ucm9sZSA9PT0gJ2xlYWRlcicpIHtcbiAgICByZXR1cm4gc3RhcnRBc0xlYWRlcihvcHRpb25zLCBlbGVjdGlvbik7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHN0YXJ0QXNGb2xsb3dlcihvcHRpb25zLCBlbGVjdGlvbik7XG4gIH1cbn1cblxuLyoqXG4gKiBTdGFydCBhcyB0aGUgY29uc29sZSBsZWFkZXIuXG4gKiBCaW5kcyBwb3J0IDM5MzksIG1vdW50cyBhbGwgcm91dGVzIGluY2x1ZGluZyBpbmdlc3Rpb24sIHN0YXJ0cyBoZWFydGJlYXQuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHN0YXJ0QXNMZWFkZXIoXG4gIG9wdGlvbnM6IFVuaWZpZWRDb25zb2xlT3B0aW9ucyxcbiAgZWxlY3Rpb246IEVsZWN0aW9uUmVzdWx0LFxuKTogUHJvbWlzZTxVbmlmaWVkQ29uc29sZVJlc3VsdD4ge1xuICBjb25zdCB7IHN0YXJ0V2ViU2VydmVyIH0gPSBhd2FpdCBpbXBvcnQoJy4uL3NlcnZlci5qcycpO1xuXG4gIC8vIFByZS1jcmVhdGUgYSBwbGFjZWhvbGRlciBicm9hZGNhc3QgdGhhdCB3ZSdsbCB3aXJlIHVwIGFmdGVyIHRoZSBzZXJ2ZXIgc3RhcnRzXG4gIGxldCBsaXZlQnJvYWRjYXN0OiAoKGVudHJ5OiBVbmlmaWVkTG9nRW50cnkpID0+IHZvaWQpIHwgdW5kZWZpbmVkO1xuICBsZXQgbGl2ZU1ldHJpY3NPblNuYXBzaG90OiAoKHNuYXBzaG90OiBNZXRyaWNTbmFwc2hvdCkgPT4gdm9pZCkgfCB1bmRlZmluZWQ7XG5cbiAgLy8gQ3JlYXRlIGluZ2VzdGlvbiByb3V0ZXMgd2l0aCBhIGRlZmVycmVkIGJyb2FkY2FzdCAod2lyZWQgYWZ0ZXIgc2VydmVyIHN0YXJ0cylcbiAgY29uc3QgaW5nZXN0UmVzdWx0ID0gY3JlYXRlSW5nZXN0Um91dGVzKHtcbiAgICBsb2dCcm9hZGNhc3Q6IChlbnRyeSkgPT4gbGl2ZUJyb2FkY2FzdD8uKGVudHJ5KSxcbiAgICBtZXRyaWNzT25TbmFwc2hvdDogKHNuYXBzaG90KSA9PiBsaXZlTWV0cmljc09uU25hcHNob3Q/LihzbmFwc2hvdCksXG4gIH0pO1xuXG4gIC8vIFJlZ2lzdGVyIHRoZSBsZWFkZXIgYXMgYSBzZXNzaW9uXG4gIGluZ2VzdFJlc3VsdC5yZWdpc3RlckxlYWRlclNlc3Npb24ob3B0aW9ucy5zZXNzaW9uSWQsIHByb2Nlc3MucGlkKTtcblxuICAvLyBTdGFydCB0aGUgd2ViIHNlcnZlciB3aXRoIGluZ2VzdCByb3V0ZXMgbW91bnRlZCBiZWZvcmUgdGhlIFNQQSBmYWxsYmFja1xuICBjb25zdCB3ZWJSZXN1bHQgPSBhd2FpdCBzdGFydFdlYlNlcnZlcih7XG4gICAgcG9ydGZvbGlvRGlyOiBvcHRpb25zLnBvcnRmb2xpb0RpcixcbiAgICBtZW1vcnlTaW5rOiBvcHRpb25zLm1lbW9yeVNpbmssXG4gICAgbWV0cmljc1Npbms6IG9wdGlvbnMubWV0cmljc1NpbmssXG4gICAgcG9ydDogQ09OU09MRV9QT1JULFxuICAgIGFkZGl0aW9uYWxSb3V0ZXJzOiBbaW5nZXN0UmVzdWx0LnJvdXRlcl0sXG4gICAgLi4uKG9wdGlvbnMubWNwQXFsSGFuZGxlciA/IHsgbWNwQXFsSGFuZGxlcjogb3B0aW9ucy5tY3BBcWxIYW5kbGVyIH0gOiB7fSksXG4gIH0pO1xuXG4gIC8vIFdpcmUgU1NFIGJyb2FkY2FzdHMgZm9yIHRoaXMgbGVhZGVyJ3Mgb3duIGV2ZW50c1xuICBvcHRpb25zLndpcmVTU0VCcm9hZGNhc3RzKHdlYlJlc3VsdCwgb3B0aW9ucy5tZXRyaWNzU2luayk7XG5cbiAgLy8gTm93IHdpcmUgdGhlIGxpdmUgYnJvYWRjYXN0IGZ1bmN0aW9ucyBpbnRvIHRoZSBpbmdlc3Qgcm91dGVzXG4gIGlmICh3ZWJSZXN1bHQubG9nQnJvYWRjYXN0KSB7XG4gICAgY29uc3Qgb3JpZ2luYWxCcm9hZGNhc3QgPSB3ZWJSZXN1bHQubG9nQnJvYWRjYXN0O1xuICAgIC8vIFN0YW1wIGxlYWRlcidzIG93biBlbnRyaWVzIHdpdGggc2Vzc2lvbiBJRFxuICAgIGxpdmVCcm9hZGNhc3QgPSAoZW50cnk6IFVuaWZpZWRMb2dFbnRyeSkgPT4ge1xuICAgICAgY29uc3Qgc3RhbXBlZDogVW5pZmllZExvZ0VudHJ5ID0ge1xuICAgICAgICAuLi5lbnRyeSxcbiAgICAgICAgZGF0YTogeyAuLi5lbnRyeS5kYXRhLCBfc2Vzc2lvbklkOiBvcHRpb25zLnNlc3Npb25JZCB9LFxuICAgICAgfTtcbiAgICAgIG9yaWdpbmFsQnJvYWRjYXN0KHN0YW1wZWQpO1xuICAgIH07XG4gIH1cbiAgbGl2ZU1ldHJpY3NPblNuYXBzaG90ID0gd2ViUmVzdWx0Lm1ldHJpY3NPblNuYXBzaG90O1xuXG4gIGxvZ2dlci5pbmZvKCdbVW5pZmllZENvbnNvbGVdIEluZ2VzdGlvbiByb3V0ZXMgbW91bnRlZCcpO1xuXG4gIC8vIFN0YXJ0IGhlYXJ0YmVhdCBhbmQgcmVnaXN0ZXIgY2xlYW51cFxuICBjb25zdCBzdG9wSGVhcnRiZWF0ID0gc3RhcnRIZWFydGJlYXQoZWxlY3Rpb24ubGVhZGVySW5mbyk7XG4gIHJlZ2lzdGVyTGVhZGVyQ2xlYW51cCgpO1xuXG4gIGxvZ2dlci5pbmZvKCdbVW5pZmllZENvbnNvbGVdIExlYWRlciBzdGFydGVkJywge1xuICAgIHNlc3Npb25JZDogb3B0aW9ucy5zZXNzaW9uSWQsIHBvcnQ6IENPTlNPTEVfUE9SVCwgcGlkOiBwcm9jZXNzLnBpZCxcbiAgICByb2xlOiAnbGVhZGVyJywgaW5nZXN0Um91dGVzOiBbJy9hcGkvaW5nZXN0L2xvZ3MnLCAnL2FwaS9pbmdlc3QvbWV0cmljcycsICcvYXBpL2luZ2VzdC9zZXNzaW9uJywgJy9hcGkvc2Vzc2lvbnMnXSxcbiAgfSk7XG5cbiAgcmV0dXJuIHtcbiAgICByb2xlOiAnbGVhZGVyJyxcbiAgICBlbGVjdGlvbixcbiAgICBwb3J0OiBDT05TT0xFX1BPUlQsXG4gICAgY2xlYW51cDogYXN5bmMgKCkgPT4ge1xuICAgICAgc3RvcEhlYXJ0YmVhdCgpO1xuICAgIH0sXG4gIH07XG59XG5cbi8qKlxuICogU3RhcnQgYXMgYSBmb2xsb3dlci5cbiAqIFJlZ2lzdGVycyBmb3J3YXJkaW5nIHNpbmtzIHdpdGggdGhlIExvZ01hbmFnZXIsIHN0YXJ0cyBzZXNzaW9uIGhlYXJ0YmVhdC5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gc3RhcnRBc0ZvbGxvd2VyKFxuICBvcHRpb25zOiBVbmlmaWVkQ29uc29sZU9wdGlvbnMsXG4gIGVsZWN0aW9uOiBFbGVjdGlvblJlc3VsdCxcbik6IFByb21pc2U8VW5pZmllZENvbnNvbGVSZXN1bHQ+IHtcbiAgY29uc3QgbGVhZGVyVXJsID0gYGh0dHA6Ly8xMjcuMC4wLjE6JHtlbGVjdGlvbi5sZWFkZXJJbmZvLnBvcnR9YDtcblxuICAvLyBSZWdpc3RlciBhIGZvcndhcmRpbmcgbG9nIHNpbmtcbiAgY29uc3QgZm9yd2FyZGluZ1NpbmsgPSBuZXcgTGVhZGVyRm9yd2FyZGluZ0xvZ1NpbmsobGVhZGVyVXJsLCBvcHRpb25zLnNlc3Npb25JZCk7XG4gIG9wdGlvbnMucmVnaXN0ZXJMb2dTaW5rKGZvcndhcmRpbmdTaW5rKTtcblxuICAvLyBTdGFydCBzZXNzaW9uIGhlYXJ0YmVhdCB0byB0aGUgbGVhZGVyXG4gIGNvbnN0IHNlc3Npb25IZWFydGJlYXQgPSBuZXcgU2Vzc2lvbkhlYXJ0YmVhdChsZWFkZXJVcmwsIG9wdGlvbnMuc2Vzc2lvbklkLCBwcm9jZXNzLnBpZCk7XG4gIGF3YWl0IHNlc3Npb25IZWFydGJlYXQuc3RhcnQoKTtcblxuICBsb2dnZXIuaW5mbygnW1VuaWZpZWRDb25zb2xlXSBGb2xsb3dlciBzdGFydGVkJywge1xuICAgIHNlc3Npb25JZDogb3B0aW9ucy5zZXNzaW9uSWQsIHBpZDogcHJvY2Vzcy5waWQsIHJvbGU6ICdmb2xsb3dlcicsXG4gICAgbGVhZGVyU2Vzc2lvbjogZWxlY3Rpb24ubGVhZGVySW5mby5zZXNzaW9uSWQsIGxlYWRlclBpZDogZWxlY3Rpb24ubGVhZGVySW5mby5waWQsXG4gICAgbGVhZGVyUG9ydDogZWxlY3Rpb24ubGVhZGVySW5mby5wb3J0LCBsZWFkZXJVcmwsXG4gIH0pO1xuXG4gIHJldHVybiB7XG4gICAgcm9sZTogJ2ZvbGxvd2VyJyxcbiAgICBlbGVjdGlvbixcbiAgICBjbGVhbnVwOiBhc3luYyAoKSA9PiB7XG4gICAgICBhd2FpdCBzZXNzaW9uSGVhcnRiZWF0LnN0b3AoKTtcbiAgICAgIGF3YWl0IGZvcndhcmRpbmdTaW5rLmNsb3NlKCk7XG4gICAgfSxcbiAgfTtcbn1cbiJdfQ==
|
|
251
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVW5pZmllZENvbnNvbGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvd2ViL2NvbnNvbGUvVW5pZmllZENvbnNvbGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7R0FhRztBQU1ILE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUMvQyxPQUFPLEVBQ0wsV0FBVyxFQUNYLDJCQUEyQixFQUMzQixvQkFBb0IsRUFDcEIsY0FBYyxFQUNkLHFCQUFxQixFQUNyQixrQkFBa0IsR0FFbkIsTUFBTSxxQkFBcUIsQ0FBQztBQUM3QixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUN2RCxPQUFPLEVBQ0wsdUJBQXVCLEVBQ3ZCLGdCQUFnQixHQUNqQixNQUFNLDJCQUEyQixDQUFDO0FBQ25DLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQ3pELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ3RELE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUUxQzs7Ozs7O0dBTUc7QUFDSCxNQUFNLG9CQUFvQixHQUFHLEdBQUcsQ0FBQywwQkFBMEIsQ0FBQztBQW9DNUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBb0JHO0FBQ0gsTUFBTSxDQUFDLEtBQUssVUFBVSwwQkFBMEIsQ0FDOUMsV0FBbUIsRUFDbkIsU0FBb0Msa0JBQWtCLEVBQ3RELE1BQXFCLE1BQU07SUFFM0IsSUFBSSxDQUFDO1FBQ0gsTUFBTSxNQUFNLEdBQUcsTUFBTSxNQUFNLEVBQUUsQ0FBQztRQUM5QixJQUFJLE1BQU0sQ0FBQyxhQUFhLEVBQUUsQ0FBQztZQUN6QixHQUFHLENBQUMsSUFBSSxDQUNOLDZFQUE2RTtnQkFDN0UsUUFBUSxNQUFNLENBQUMsR0FBRyxVQUFVLE1BQU0sQ0FBQyxJQUFJLDRCQUE0QjtnQkFDbkUs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LENBQUMsS0FBSyxDQUFDLG9DQUFvQyxFQUFFLEVBQUUsS0FBSyxFQUFFLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUM5RixDQUFDLENBQUMsQ0FBQztJQUNILE9BQU8sQ0FBQyxlQUFlLENBQUMsY0FBYyxDQUFDLENBQUM7SUFFeEMsd0NBQXdDO0lBQ3hDLGdCQUFnQixHQUFHLElBQUksZ0JBQWdCLENBQUMsU0FBUyxFQUFFLE9BQU8sQ0FBQyxTQUFTLEVBQUUsT0FBTyxDQUFDLEdBQUcsRUFBRSxTQUFTLENBQUMsQ0FBQztJQUM5RixNQUFNLGdCQUFnQixDQUFDLEtBQUssRUFBRSxDQUFDO0lBRS9CLE1BQU0sQ0FBQyxJQUFJLENBQUMsbUNBQW1DLEVBQUU7UUFDL0MsU0FBUyxFQUFFLE9BQU8sQ0FBQyxTQUFTLEVBQUUsR0FBRyxFQUFFLE9BQU8sQ0FBQyxHQUFHLEVBQUUsSUFBSSxFQUFFLFVBQVU7UUFDaEUsYUFBYSxFQUFFLFFBQVEsQ0FBQyxVQUFVLENBQUMsU0FBUyxFQUFFLFNBQVMsRUFBRSxRQUFRLENBQUMsVUFBVSxDQUFDLEdBQUc7UUFDaEYsVUFBVSxFQUFFLFFBQVEsQ0FBQyxVQUFVLENBQUMsSUFBSSxFQUFFLFNBQVM7S0FDaEQsQ0FBQyxDQUFDO0lBRUgsT0FBTztRQUNMLElBQUksRUFBRSxVQUFVO1FBQ2hCLFFBQVE7UUFDUixPQUFPLEVBQUUsS0FBSyxJQUFJLEVBQUU7WUFDbEIsTUFBTSxnQkFBZ0IsQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUM5QixNQUFNLGNBQWMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUMvQixDQUFDO0tBQ0YsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFVuaWZpZWQgd2ViIGNvbnNvbGUgb3JjaGVzdHJhdG9yLlxuICpcbiAqIFRpZXMgdG9nZXRoZXIgbGVhZGVyIGVsZWN0aW9uLCBjb25zb2xlIHN0YXJ0dXAsIGZvbGxvd2VyIHdpcmluZyxcbiAqIGFuZCBzZXNzaW9uIGxpZmVjeWNsZSBtYW5hZ2VtZW50LiBUaGlzIGlzIHRoZSBtYWluIGVudHJ5IHBvaW50XG4gKiBjYWxsZWQgYnkgdGhlIERJIGNvbnRhaW5lciBkdXJpbmcgZGVmZXJyZWQgc2V0dXAuXG4gKlxuICogRmxvdzpcbiAqIDEuIFJ1biBsZWFkZXIgZWxlY3Rpb24gKHJlYWQgbG9jayBmaWxlLCBjbGFpbSBvciBmb2xsb3cpXG4gKiAyLiBJZiBsZWFkZXI6IHN0YXJ0IHdlYiBzZXJ2ZXIgb24gZml4ZWQgcG9ydCwgbW91bnQgaW5nZXN0IHJvdXRlcywgc3RhcnQgaGVhcnRiZWF0XG4gKiAzLiBJZiBmb2xsb3dlcjogcmVnaXN0ZXIgZm9yd2FyZGluZyBzaW5rcyB3aXRoIExvZ01hbmFnZXIsIHN0YXJ0IHNlc3Npb24gaGVhcnRiZWF0XG4gKlxuICogQHNpbmNlIHYyLjEuMCDigJQgSXNzdWUgIzE3MDBcbiAqL1xuXG5pbXBvcnQgdHlwZSB7IFVuaWZpZWRMb2dFbnRyeSB9IGZyb20gJy4uLy4uL2xvZ2dpbmcvdHlwZXMuanMnO1xuaW1wb3J0IHR5cGUgeyBNZXRyaWNTbmFwc2hvdCB9IGZyb20gJy4uLy4uL21ldHJpY3MvdHlwZXMuanMnO1xuaW1wb3J0IHR5cGUgeyBNZW1vcnlMb2dTaW5rIH0gZnJvbSAnLi4vLi4vbG9nZ2luZy9zaW5rcy9NZW1vcnlMb2dTaW5rLmpzJztcbmltcG9ydCB0eXBlIHsgTWVtb3J5TWV0cmljc1NpbmsgfSBmcm9tICcuLi8uLi9tZXRyaWNzL3NpbmtzL01lbW9yeU1ldHJpY3NTaW5rLmpzJztcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gJy4uLy4uL3V0aWxzL2xvZ2dlci5qcyc7XG5pbXBvcnQge1xuICBlbGVjdExlYWRlcixcbiAgaXNMZWFkZXJXZWJDb25zb2xlUmVhY2hhYmxlLFxuICBmb3JjZUNsYWltTGVhZGVyc2hpcCxcbiAgc3RhcnRIZWFydGJlYXQsXG4gIHJlZ2lzdGVyTGVhZGVyQ2xlYW51cCxcbiAgZGV0ZWN0TGVnYWN5TGVhZGVyLFxuICB0eXBlIEVsZWN0aW9uUmVzdWx0LFxufSBmcm9tICcuL0xlYWRlckVsZWN0aW9uLmpzJztcbmltcG9ydCB7IGNyZWF0ZUluZ2VzdFJvdXRlcyB9IGZyb20gJy4vSW5nZXN0Um91dGVzLmpzJztcbmltcG9ydCB7XG4gIExlYWRlckZvcndhcmRpbmdMb2dTaW5rLFxuICBTZXNzaW9uSGVhcnRiZWF0LFxufSBmcm9tICcuL0xlYWRlckZvcndhcmRpbmdTaW5rLmpzJztcbmltcG9ydCB7IFByb21vdGlvbk1hbmFnZXIgfSBmcm9tICcuL1Byb21vdGlvbk1hbmFnZXIuanMnO1xuaW1wb3J0IHsgQ29uc29sZVRva2VuU3RvcmUgfSBmcm9tICcuL2NvbnNvbGVUb2tlbi5qcyc7XG5pbXBvcnQgeyBlbnYgfSBmcm9tICcuLi8uLi9jb25maWcvZW52LmpzJztcblxuLyoqXG4gKiBEZWZhdWx0IGNvbnNvbGUgcG9ydCBmcm9tIHRoZSBlbnYgdmFyLiBVc2VkIGFzIGZhbGxiYWNrIHdoZW4gbm8gcG9ydFxuICogaXMgcHJvdmlkZWQgdmlhIGNvbmZpZyBmaWxlIG9yIG9wdGlvbnMuIFRoZSByZXNvbHV0aW9uIGhpZXJhcmNoeSBpczpcbiAqICAgMS4gb3B0aW9ucy5wb3J0IChmcm9tIGNvbmZpZyBmaWxlLCByZXNvbHZlZCBieSB0aGUgREkgY29udGFpbmVyKVxuICogICAyLiBET0xMSE9VU0VfV0VCX0NPTlNPTEVfUE9SVCBlbnYgdmFyXG4gKiAgIDMuIDQxNzE1IChoYXJkY29kZWQgZGVmYXVsdCBpbiBlbnYudHMpXG4gKi9cbmNvbnN0IERFRkFVTFRfQ09OU09MRV9QT1JUID0gZW52LkRPTExIT1VTRV9XRUJfQ09OU09MRV9QT1JUO1xuXG4vKipcbiAqIE9wdGlvbnMgZm9yIHN0YXJ0aW5nIHRoZSB1bmlmaWVkIGNvbnNvbGUuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVW5pZmllZENvbnNvbGVPcHRpb25zIHtcbiAgLyoqIFRoaXMgcHJvY2VzcydzIHVuaXF1ZSBzZXNzaW9uIElEICovXG4gIHNlc3Npb25JZDogc3RyaW5nO1xuICAvKiogUG9ydGZvbGlvIGJhc2UgZGlyZWN0b3J5IChmb3Igc3RhcnRXZWJTZXJ2ZXIpICovXG4gIHBvcnRmb2xpb0Rpcjogc3RyaW5nO1xuICAvKiogTG9nIG1lbW9yeSBzaW5rIChmb3IgY29uc29sZSBoaXN0b3J5KSAqL1xuICBtZW1vcnlTaW5rOiBNZW1vcnlMb2dTaW5rO1xuICAvKiogTWV0cmljcyBtZW1vcnkgc2luayAqL1xuICBtZXRyaWNzU2luaz86IE1lbW9yeU1ldHJpY3NTaW5rO1xuICAvKiogTUNQLUFRTCBoYW5kbGVyIGZvciBwZXJtaXNzaW9uIHJvdXRlcyAodHlwZWQgYXMgYW55IHRvIGF2b2lkIGNpcmN1bGFyIGltcG9ydHMpICovXG4gIG1jcEFxbEhhbmRsZXI/OiBhbnk7XG4gIC8qKiBDYWxsYmFjayB0byByZWdpc3RlciBhIGxvZyBzaW5rIHdpdGggdGhlIExvZ01hbmFnZXIgKi9cbiAgcmVnaXN0ZXJMb2dTaW5rOiAoc2luazogeyB3cml0ZShlbnRyeTogVW5pZmllZExvZ0VudHJ5KTogdm9pZDsgZmx1c2goKTogUHJvbWlzZTx2b2lkPjsgY2xvc2UoKTogUHJvbWlzZTx2b2lkPiB9KSA9PiB2b2lkO1xuICAvKiogQ2FsbGJhY2sgdG8gd2lyZSBTU0UgYnJvYWRjYXN0cyBhZnRlciB3ZWIgc2VydmVyIHN0YXJ0cyAqL1xuICB3aXJlU1NFQnJvYWRjYXN0czogKHdlYlJlc3VsdDogeyBsb2dCcm9hZGNhc3Q/OiAoZW50cnk6IFVuaWZpZWRMb2dFbnRyeSkgPT4gdm9pZDsgbWV0cmljc09uU25hcHNob3Q/OiAoc25hcHNob3Q6IE1ldHJpY1NuYXBzaG90KSA9PiB2b2lkIH0sIG1ldHJpY3NTaW5rPzogTWVtb3J5TWV0cmljc1NpbmspID0+IHZvaWQ7XG4gIC8qKiBDb25zb2xlIHBvcnQgb3ZlcnJpZGUgZnJvbSBjb25maWcgZmlsZS4gRmFsbHMgYmFjayB0byBlbnYgdmFyIGlmIG5vdCBwcm92aWRlZC4gKi9cbiAgcG9ydD86IG51bWJlcjtcbn1cblxuLyoqXG4gKiBSZXN1bHQgb2Ygc3RhcnRpbmcgdGhlIHVuaWZpZWQgY29uc29sZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBVbmlmaWVkQ29uc29sZVJlc3VsdCB7XG4gIHJvbGU6ICdsZWFkZXInIHwgJ2ZvbGxvd2VyJztcbiAgZWxlY3Rpb246IEVsZWN0aW9uUmVzdWx0O1xuICAvKiogUG9ydCB0aGUgY29uc29sZSBpcyBydW5uaW5nIG9uIChsZWFkZXIgb25seSkgKi9cbiAgcG9ydD86IG51bWJlcjtcbiAgLyoqIENsZWFudXAgZnVuY3Rpb24gdG8gY2FsbCBvbiBzaHV0ZG93biAqL1xuICBjbGVhbnVwOiAoKSA9PiBQcm9taXNlPHZvaWQ+O1xufVxuXG4vKipcbiAqIENoZWNrIGZvciBhIHJ1bm5pbmcgbGVnYWN5IChwcmUtYXV0aGVudGljYXRpb24pIERvbGxob3VzZU1DUCBjb25zb2xlIGFuZFxuICogbG9nIGEgV0FSTi1sZXZlbCBtZXNzYWdlIGlmIG9uZSBpcyBmb3VuZCAoIzE3OTQpLlxuICpcbiAqIEV4dHJhY3RlZCBmcm9tIGBzdGFydFVuaWZpZWRDb25zb2xlYCBzbyB0aGUgd2lyaW5nIGNhbiBiZSBpbnRlZ3JhdGlvbi1cbiAqIHRlc3RlZCBpbiBpc29sYXRpb24gd2l0aG91dCBzcGlubmluZyB1cCBhIGZ1bGwgd2ViIHNlcnZlciBhbmQgbGVhZGVyXG4gKiBlbGVjdGlvbi4gVGhlIGltcGxlbWVudGF0aW9uIGlzIGZpcmUtYW5kLWZvcmdldDogZGV0ZWN0aW9uIGZhaWx1cmVzXG4gKiBhcmUgbG9nZ2VkIGF0IERFQlVHIGFuZCBuZXZlciBwcm9wYWdhdGUsIGJlY2F1c2UgYSBmYWlsdXJlIGhlcmUgbXVzdFxuICogbm90IGJsb2NrIGxlYWRlciBlbGVjdGlvbiBvZiB0aGUgYXV0aGVudGljYXRlZCBjb25zb2xlLlxuICpcbiAqIEBwYXJhbSBjdXJyZW50UG9ydCAtIFRoZSBwb3J0IHRoZSBhdXRoZW50aWNhdGVkIGNvbnNvbGUgaW50ZW5kcyB0b1xuICogICAgICAgICAgICAgICAgICAgICAgYmluZCB0by4gVXNlZCBpbiB0aGUgd2FybmluZyBtZXNzYWdlIHRvIGhlbHAgdGhlXG4gKiAgICAgICAgICAgICAgICAgICAgICB1c2VyIHRlbGwgdGhlIHR3byBjb25zb2xlcyBhcGFydC5cbiAqIEBwYXJhbSBkZXRlY3QgICAgICAtIE9wdGlvbmFsIGluamVjdGlvbiBwb2ludCBmb3IgdGhlIGRldGVjdGlvblxuICogICAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24uIERlZmF1bHRzIHRvIGBkZXRlY3RMZWdhY3lMZWFkZXJgLiBUZXN0c1xuICogICAgICAgICAgICAgICAgICAgICAgcGFzcyBhIHN0dWIuXG4gKiBAcGFyYW0gbG9nICAgICAgICAgLSBPcHRpb25hbCBpbmplY3Rpb24gcG9pbnQgZm9yIHRoZSBsb2dnZXIuIERlZmF1bHRzXG4gKiAgICAgICAgICAgICAgICAgICAgICB0byB0aGUgbW9kdWxlIGxvZ2dlci4gVGVzdHMgcGFzcyBhIHNweS5cbiAqIEByZXR1cm5zIFRoZSBsZWdhY3kgbGVhZGVyIGluZm8gZnJvbSBgZGV0ZWN0KClgLCBvciBudWxsIGlmIGRldGVjdGlvblxuICogICAgICAgICAgdGhyZXcuIEV4cG9zZWQgc28gdGVzdHMgY2FuIGFzc2VydCB0aGUgZnVsbCByZXN1bHQgc2hhcGUuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiB3YXJuSWZMZWdhY3lDb25zb2xlUHJlc2VudChcbiAgY3VycmVudFBvcnQ6IG51bWJlcixcbiAgZGV0ZWN0OiB0eXBlb2YgZGV0ZWN0TGVnYWN5TGVhZGVyID0gZGV0ZWN0TGVnYWN5TGVhZGVyLFxuICBsb2c6IHR5cGVvZiBsb2dnZXIgPSBsb2dnZXIsXG4pOiBQcm9taXNlPEF3YWl0ZWQ8UmV0dXJuVHlwZTx0eXBlb2YgZGV0ZWN0TGVnYWN5TGVhZGVyPj4gfCBudWxsPiB7XG4gIHRyeSB7XG4gICAgY29uc3QgbGVnYWN5ID0gYXdhaXQgZGV0ZWN0KCk7XG4gICAgaWYgKGxlZ2FjeS5sZWdhY3lSdW5uaW5nKSB7XG4gICAgICBsb2cud2FybihcbiAgICAgICAgYFtVbmlmaWVkQ29uc29sZV0gTGVnYWN5IChwcmUtYXV0aGVudGljYXRpb24pIERvbGxob3VzZU1DUCBjb25zb2xlIGRldGVjdGVkIGAgK1xuICAgICAgICBgKHBpZD0ke2xlZ2FjeS5waWR9LCBwb3J0PSR7bGVnYWN5LnBvcnR9KS4gQm90aCBjb25zb2xlcyB3aWxsIHJ1biBgICtcbiAgICAgICAgYGluZGVwZW5kZW50bHkgb24gZGlmZmVyZW50IHBvcnRzIHdpdGggZGlmZmVyZW50IHNlY3VyaXR5IHBvc3R1cmUuIGAgK1xuICAgICAgICBgVGhlIGF1dGhlbnRpY2F0ZWQgY29uc29sZSAodGhpcyBwcm9jZXNzKSB1c2VzIHBvcnQgJHtjdXJyZW50UG9ydH07IGAgK1xuICAgICAgICBgdGhlIGxlZ2FjeSBjb25zb2xlIHVzZXMgcG9ydCAke2xlZ2FjeS5wb3J0ID8/IDM5Mzl9LiBgICtcbiAgICAgICAgYEZvciBjb25zaXN0ZW50IHNlY3VyaXR5LCB1cGRhdGUgdGhlIGxlZ2FjeSBpbnN0YWxsYXRpb24gdG8gYSBgICtcbiAgICAgICAgYHZlcnNpb24gd2l0aCB0aGUgYXV0aGVudGljYXRlZCBjb25zb2xlLmAsXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gbGVnYWN5O1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICAvLyBCZXN0LWVmZm9ydCDigJQgbmV2ZXIgYmxvY2sgZWxlY3Rpb24gb24gYSBkZXRlY3Rpb24gZmFpbHVyZVxuICAgIGxvZy5kZWJ1ZygnW1VuaWZpZWRDb25zb2xlXSBMZWdhY3kgbGVhZGVyIGRldGVjdGlvbiBmYWlsZWQnLCB7XG4gICAgICBlcnJvcjogZXJyIGluc3RhbmNlb2YgRXJyb3IgPyBlcnIubWVzc2FnZSA6IFN0cmluZyhlcnIpLFxuICAgIH0pO1xuICAgIHJldHVybiBudWxsO1xuICB9XG59XG5cbi8qKlxuICogU3RhcnQgdGhlIHVuaWZpZWQgd2ViIGNvbnNvbGUuXG4gKlxuICogUnVucyBsZWFkZXIgZWxlY3Rpb24sIHRoZW4gZWl0aGVyIHN0YXJ0cyB0aGUgZnVsbCBjb25zb2xlIChsZWFkZXIpXG4gKiBvciBzZXRzIHVwIGV2ZW50IGZvcndhcmRpbmcgKGZvbGxvd2VyKS5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHN0YXJ0VW5pZmllZENvbnNvbGUob3B0aW9uczogVW5pZmllZENvbnNvbGVPcHRpb25zKTogUHJvbWlzZTxVbmlmaWVkQ29uc29sZVJlc3VsdD4ge1xuICAvLyBSZXNvbHZlIHBvcnQ6IG9wdGlvbnMgKGNvbmZpZyBmaWxlKSDihpIgZW52IHZhciDihpIgZGVmYXVsdFxuICBjb25zdCBjb25zb2xlUG9ydCA9IG9wdGlvbnMucG9ydCB8fCBERUZBVUxUX0NPTlNPTEVfUE9SVDtcbiAgbG9nZ2VyLmRlYnVnKGBbVW5pZmllZENvbnNvbGVdIFBvcnQgcmVzb2x2ZWQ6ICR7Y29uc29sZVBvcnR9YCArXG4gICAgKG9wdGlvbnMucG9ydCA/ICcgKGZyb20gY29uZmlnIGZpbGUpJyA6IGAgKGZyb20gZW52L2RlZmF1bHQpYCkpO1xuXG4gIC8vIExlZ2FjeS1sZWFkZXIgZGV0ZWN0aW9uICgjMTc5NCkg4oCUIHdhcm4gdGhlIHVzZXIgaWYgYSBwcmUtYXV0aFxuICAvLyBEb2xsaG91c2VNQ1AgY29uc29sZSBpcyBydW5uaW5nIGFsb25nc2lkZSB0aGlzIGF1dGhlbnRpY2F0ZWQgb25lLlxuICAvLyBUaGV5IHdpbGwgY29leGlzdCBmaW5lIGJlY2F1c2Ugb2YgcG9ydCArIGxvY2sgKyB0b2tlbiBmaWxlIGlzb2xhdGlvbixcbiAgLy8gYnV0IHRoZSB1c2VyIHNob3VsZCBrbm93IGJvdGggZXhpc3Qgc28gdGhlIGRpZmZlcmluZyBzZWN1cml0eSBwb3N0dXJlXG4gIC8vIGJldHdlZW4gdGhlbSBkb2Vzbid0IGxvb2sgbGlrZSBhIGJ1Zy5cbiAgYXdhaXQgd2FybklmTGVnYWN5Q29uc29sZVByZXNlbnQoY29uc29sZVBvcnQpO1xuXG4gIGxldCBlbGVjdGlvbiA9IGF3YWl0IGVsZWN0TGVhZGVyKG9wdGlvbnMuc2Vzc2lvbklkLCBjb25zb2xlUG9ydCk7XG5cbiAgLy8gSWYgd2UgbG9zdCB0aGUgZWxlY3Rpb24sIGNoZWNrIGlmIHRoZSBsZWFkZXIgaXMgYWN0dWFsbHkgcnVubmluZyBhIHdlYiBjb25zb2xlLlxuICAvLyBBbiBNQ1Agc3RkaW8gcHJvY2VzcyBtYXkgaG9sZCBsZWFkZXJzaGlwIGJ1dCBub3Qgc2VydmUgd2ViIHJvdXRlcy5cbiAgLy8gSW4gdGhhdCBjYXNlLCBmb3JjZSBhIHRha2VvdmVyIHNvIHRoZSB3ZWIgY29uc29sZSB3b3JrcyBwcm9wZXJseS5cbiAgaWYgKGVsZWN0aW9uLnJvbGUgPT09ICdmb2xsb3dlcicpIHtcbiAgICBjb25zdCByZWFjaGFibGUgPSBhd2FpdCBpc0xlYWRlcldlYkNvbnNvbGVSZWFjaGFibGUoZWxlY3Rpb24ubGVhZGVySW5mbyk7XG4gICAgaWYgKCFyZWFjaGFibGUpIHtcbiAgICAgIGVsZWN0aW9uID0gYXdhaXQgZm9yY2VDbGFpbUxlYWRlcnNoaXAob3B0aW9ucy5zZXNzaW9uSWQsIGNvbnNvbGVQb3J0KTtcbiAgICB9XG4gIH1cblxuICBpZiAoZWxlY3Rpb24ucm9sZSA9PT0gJ2xlYWRlcicpIHtcbiAgICByZXR1cm4gc3RhcnRBc0xlYWRlcihvcHRpb25zLCBlbGVjdGlvbiwgY29uc29sZVBvcnQpO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBzdGFydEFzRm9sbG93ZXIob3B0aW9ucywgZWxlY3Rpb24sIGNvbnNvbGVQb3J0KTtcbiAgfVxufVxuXG4vKipcbiAqIFN0YXJ0IGFzIHRoZSBjb25zb2xlIGxlYWRlci5cbiAqIEJpbmRzIHRoZSByZXNvbHZlZCBjb25zb2xlIHBvcnQgKGNvbmZpZyBmaWxlIOKGkiBlbnYgdmFyIOKGkiBkZWZhdWx0KSxcbiAqIG1vdW50cyBhbGwgcm91dGVzIGluY2x1ZGluZyBpbmdlc3Rpb24sIHN0YXJ0cyBoZWFydGJlYXQuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHN0YXJ0QXNMZWFkZXIoXG4gIG9wdGlvbnM6IFVuaWZpZWRDb25zb2xlT3B0aW9ucyxcbiAgZWxlY3Rpb246IEVsZWN0aW9uUmVzdWx0LFxuICBjb25zb2xlUG9ydDogbnVtYmVyID0gREVGQVVMVF9DT05TT0xFX1BPUlQsXG4pOiBQcm9taXNlPFVuaWZpZWRDb25zb2xlUmVzdWx0PiB7XG4gIGNvbnN0IHsgc3RhcnRXZWJTZXJ2ZXIgfSA9IGF3YWl0IGltcG9ydCgnLi4vc2VydmVyLmpzJyk7XG4gIGNvbnN0IHsgcGlja1JhbmRvbVB1cHBldE5hbWUgfSA9IGF3YWl0IGltcG9ydCgnLi9TZXNzaW9uTmFtZXMuanMnKTtcblxuICAvLyBJbml0aWFsaXplIHRoZSBjb25zb2xlIHRva2VuIHN0b3JlICgjMTc4MCkuIENyZWF0ZXMgdGhlIHRva2VuIGZpbGUgb25cbiAgLy8gZmlyc3QgcnVuLCByZWFkcyB0aGUgZXhpc3RpbmcgdG9rZW5zIG9uIHN1YnNlcXVlbnQgcnVucy4gVGhlIHRva2VuIGlzXG4gIC8vIHBlcnNpc3RlbnQgYWNyb3NzIHJlc3RhcnRzIOKAlCBvbmx5IHJvdGF0ZWQgb24gZXhwbGljaXQgcmVxdWVzdCAoUGhhc2UgMikuXG4gIC8vIEZlYXR1cmUgZmxhZyBET0xMSE9VU0VfV0VCX0FVVEhfRU5BQkxFRCBjb250cm9scyBlbmZvcmNlbWVudDsgdGhlIGZpbGVcbiAgLy8gaXMgZ2VuZXJhdGVkIHJlZ2FyZGxlc3Mgc28gY29uc3VtZXJzIGNhbiBhdHRhY2ggdG9rZW5zIHByZWVtcHRpdmVseS5cbiAgY29uc3QgdG9rZW5TdG9yZSA9IG5ldyBDb25zb2xlVG9rZW5TdG9yZShlbnYuRE9MTEhPVVNFX0NPTlNPTEVfVE9LRU5fRklMRSk7XG4gIGNvbnN0IHByaW1hcnlUb2tlbiA9IGF3YWl0IHRva2VuU3RvcmUuZW5zdXJlSW5pdGlhbGl6ZWQocGlja1JhbmRvbVB1cHBldE5hbWUoKSk7XG4gIGxvZ2dlci5pbmZvKCdbVW5pZmllZENvbnNvbGVdIENvbnNvbGUgdG9rZW4gc3RvcmUgaW5pdGlhbGl6ZWQnLCB7XG4gICAgdG9rZW5JZDogcHJpbWFyeVRva2VuLmlkLFxuICAgIHRva2VuTmFtZTogcHJpbWFyeVRva2VuLm5hbWUsXG4gICAgZmlsZTogdG9rZW5TdG9yZS5nZXRGaWxlUGF0aCgpLFxuICAgIGF1dGhFbmZvcmNlZDogZW52LkRPTExIT1VTRV9XRUJfQVVUSF9FTkFCTEVELFxuICB9KTtcblxuICAvLyBQcmUtY3JlYXRlIGEgcGxhY2Vob2xkZXIgYnJvYWRjYXN0IHRoYXQgd2UnbGwgd2lyZSB1cCBhZnRlciB0aGUgc2VydmVyIHN0YXJ0c1xuICBsZXQgbGl2ZUJyb2FkY2FzdDogKChlbnRyeTogVW5pZmllZExvZ0VudHJ5KSA9PiB2b2lkKSB8IHVuZGVmaW5lZDtcbiAgbGV0IGxpdmVNZXRyaWNzT25TbmFwc2hvdDogKChzbmFwc2hvdDogTWV0cmljU25hcHNob3QpID0+IHZvaWQpIHwgdW5kZWZpbmVkO1xuXG4gIC8vIENyZWF0ZSBpbmdlc3Rpb24gcm91dGVzIHdpdGggYSBkZWZlcnJlZCBicm9hZGNhc3QgKHdpcmVkIGFmdGVyIHNlcnZlciBzdGFydHMpXG4gIGNvbnN0IGluZ2VzdFJlc3VsdCA9IGNyZWF0ZUluZ2VzdFJvdXRlcyh7XG4gICAgbG9nQnJvYWRjYXN0OiAoZW50cnkpID0+IGxpdmVCcm9hZGNhc3Q/LihlbnRyeSksXG4gICAgbWV0cmljc09uU25hcHNob3Q6IChzbmFwc2hvdCkgPT4gbGl2ZU1ldHJpY3NPblNuYXBzaG90Py4oc25hcHNob3QpLFxuICB9KTtcblxuICAvLyBSZWdpc3RlciB0aGUgbGVhZGVyIGFzIGEgc2Vzc2lvblxuICBpbmdlc3RSZXN1bHQucmVnaXN0ZXJMZWFkZXJTZXNzaW9uKG9wdGlvbnMuc2Vzc2lvbklkLCBwcm9jZXNzLnBpZCk7XG5cbiAgLy8gUmVnaXN0ZXIgdGhlIHdlYiBjb25zb2xlIGl0c2VsZiBzbyB0aGUgc2Vzc2lvbiBpbmRpY2F0b3IgaXMgbmV2ZXIgZW1wdHkgKCMxODA1KVxuICBpbmdlc3RSZXN1bHQucmVnaXN0ZXJDb25zb2xlU2Vzc2lvbigpO1xuXG4gIC8vIFN0YXJ0IHRoZSB3ZWIgc2VydmVyIHdpdGggaW5nZXN0IHJvdXRlcyBtb3VudGVkIGJlZm9yZSB0aGUgU1BBIGZhbGxiYWNrLlxuICAvLyBJZiB0aGUgcG9ydCBpcyBvY2N1cGllZCBieSBhIHN0YWxlIHByb2Nlc3MsIHJldHJ5IHdpdGggZXhwb25lbnRpYWwgYmFja29mZi5cbiAgY29uc3Qgc2VydmVyT3B0cyA9IHtcbiAgICBwb3J0Zm9saW9EaXI6IG9wdGlvbnMucG9ydGZvbGlvRGlyLFxuICAgIG1lbW9yeVNpbms6IG9wdGlvbnMubWVtb3J5U2luayxcbiAgICBtZXRyaWNzU2luazogb3B0aW9ucy5tZXRyaWNzU2luayxcbiAgICBwb3J0OiBjb25zb2xlUG9ydCxcbiAgICBhZGRpdGlvbmFsUm91dGVyczogW2luZ2VzdFJlc3VsdC5yb3V0ZXJdLFxuICAgIHRva2VuU3RvcmUsXG4gICAgLi4uKG9wdGlvbnMubWNwQXFsSGFuZGxlciA/IHsgbWNwQXFsSGFuZGxlcjogb3B0aW9ucy5tY3BBcWxIYW5kbGVyIH0gOiB7fSksXG4gIH07XG4gIGNvbnN0IEJJTkRfUkVUUllfREVMQVlTID0gZW52LkRPTExIT1VTRV9DT05TT0xFX0JJTkRfUkVUUllfREVMQVlTPy5sZW5ndGhcbiAgICA/IGVudi5ET0xMSE9VU0VfQ09OU09MRV9CSU5EX1JFVFJZX0RFTEFZU1xuICAgIDogWzEwMDAsIDIwMDAsIDQwMDBdO1xuICBjb25zdCB3ZWJSZXN1bHQgPSBhd2FpdCBzdGFydFdlYlNlcnZlcihzZXJ2ZXJPcHRzKTtcblxuICAvLyBJZiB0aGUgcG9ydCBpcyBvY2N1cGllZCwgcmV0cnkgdGhlIGJpbmQgb25seSDigJQgZG9uJ3QgcmVjcmVhdGUgdGhlIEV4cHJlc3NcbiAgLy8gYXBwIGFuZCByb3V0ZXMgKHN0YXJ0V2ViU2VydmVyIGVhcmx5LXJldHVybnMgd2hlbiBzZXJ2ZXJSdW5uaW5nIGlzIGZhbHNlXG4gIC8vIGJ1dCB0aGUgYXBwIGlzIGFscmVhZHkgY29uZmlndXJlZCkuIFdlIGNhbGwgcmV0cnlCaW5kIG9uIHRoZSBleGlzdGluZyBhcHAuXG4gIGlmICh3ZWJSZXN1bHQuYmluZFJlc3VsdCAmJiAhd2ViUmVzdWx0LmJpbmRSZXN1bHQuc3VjY2VzcyAmJiB3ZWJSZXN1bHQuYmluZFJlc3VsdC5lcnJvciA9PT0gJ0VBRERSSU5VU0UnICYmIHdlYlJlc3VsdC5hcHApIHtcbiAgICBjb25zdCB7IHJldHJ5QmluZCB9ID0gYXdhaXQgaW1wb3J0KCcuLi9zZXJ2ZXIuanMnKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IEJJTkRfUkVUUllfREVMQVlTLmxlbmd0aDsgaSsrKSB7XG4gICAgICBsb2dnZXIud2FybihgW1VuaWZpZWRDb25zb2xlXSBQb3J0ICR7Y29uc29sZVBvcnR9IG9jY3VwaWVkIOKAlCByZXRyeSAke2kgKyAxfS8ke0JJTkRfUkVUUllfREVMQVlTLmxlbmd0aH0gaW4gJHtCSU5EX1JFVFJZX0RFTEFZU1tpXX1tc2ApO1xuICAgICAgYXdhaXQgbmV3IFByb21pc2UociA9PiBzZXRUaW1lb3V0KHIsIEJJTkRfUkVUUllfREVMQVlTW2ldKSk7XG4gICAgICBjb25zdCByZXRyeVJlc3VsdCA9IGF3YWl0IHJldHJ5QmluZCh3ZWJSZXN1bHQuYXBwLCBjb25zb2xlUG9ydCwgc2VydmVyT3B0cyk7XG4gICAgICBpZiAocmV0cnlSZXN1bHQuc3VjY2Vzcykge1xuICAgICAgICB3ZWJSZXN1bHQuYmluZFJlc3VsdCA9IHJldHJ5UmVzdWx0O1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHdlYlJlc3VsdC5iaW5kUmVzdWx0ICYmICF3ZWJSZXN1bHQuYmluZFJlc3VsdC5zdWNjZXNzKSB7XG4gICAgICBsb2dnZXIuZXJyb3IoYFtVbmlmaWVkQ29uc29sZV0gTGVhZGVyIGZhaWxlZCB0byBiaW5kIHBvcnQgJHtjb25zb2xlUG9ydH0gYWZ0ZXIgJHtCSU5EX1JFVFJZX0RFTEFZUy5sZW5ndGh9IHJldHJpZXMg4oCUIGNvbnNvbGUgdW5hdmFpbGFibGVgKTtcbiAgICB9XG4gIH1cblxuICAvLyBXaXJlIFNTRSBicm9hZGNhc3RzIGZvciB0aGlzIGxlYWRlcidzIG93biBldmVudHNcbiAgb3B0aW9ucy53aXJlU1NFQnJvYWRjYXN0cyh3ZWJSZXN1bHQsIG9wdGlvbnMubWV0cmljc1NpbmspO1xuXG4gIC8vIE5vdyB3aXJlIHRoZSBsaXZlIGJyb2FkY2FzdCBmdW5jdGlvbnMgaW50byB0aGUgaW5nZXN0IHJvdXRlc1xuICBpZiAod2ViUmVzdWx0LmxvZ0Jyb2FkY2FzdCkge1xuICAgIGNvbnN0IG9yaWdpbmFsQnJvYWRjYXN0ID0gd2ViUmVzdWx0LmxvZ0Jyb2FkY2FzdDtcbiAgICAvLyBTdGFtcCBsZWFkZXIncyBvd24gZW50cmllcyB3aXRoIHNlc3Npb24gSURcbiAgICBsaXZlQnJvYWRjYXN0ID0gKGVudHJ5OiBVbmlmaWVkTG9nRW50cnkpID0+IHtcbiAgICAgIGNvbnN0IHN0YW1wZWQ6IFVuaWZpZWRMb2dFbnRyeSA9IHtcbiAgICAgICAgLi4uZW50cnksXG4gICAgICAgIGRhdGE6IHsgLi4uZW50cnkuZGF0YSwgX3Nlc3Npb25JZDogb3B0aW9ucy5zZXNzaW9uSWQgfSxcbiAgICAgIH07XG4gICAgICBvcmlnaW5hbEJyb2FkY2FzdChzdGFtcGVkKTtcbiAgICB9O1xuICB9XG4gIGxpdmVNZXRyaWNzT25TbmFwc2hvdCA9IHdlYlJlc3VsdC5tZXRyaWNzT25TbmFwc2hvdDtcblxuICBsb2dnZXIuaW5mbygnW1VuaWZpZWRDb25zb2xlXSBJbmdlc3Rpb24gcm91dGVzIG1vdW50ZWQnKTtcblxuICAvLyBTdGFydCBoZWFydGJlYXQgYW5kIHJlZ2lzdGVyIGNsZWFudXBcbiAgY29uc3Qgc3RvcEhlYXJ0YmVhdCA9IHN0YXJ0SGVhcnRiZWF0KGVsZWN0aW9uLmxlYWRlckluZm8pO1xuICByZWdpc3RlckxlYWRlckNsZWFudXAoKTtcblxuICBsb2dnZXIuaW5mbygnW1VuaWZpZWRDb25zb2xlXSBMZWFkZXIgc3RhcnRlZCcsIHtcbiAgICBzZXNzaW9uSWQ6IG9wdGlvbnMuc2Vzc2lvbklkLCBwb3J0OiBjb25zb2xlUG9ydCwgcGlkOiBwcm9jZXNzLnBpZCxcbiAgICByb2xlOiAnbGVhZGVyJywgaW5nZXN0Um91dGVzOiBbJy9hcGkvaW5nZXN0L2xvZ3MnLCAnL2FwaS9pbmdlc3QvbWV0cmljcycsICcvYXBpL2luZ2VzdC9zZXNzaW9uJywgJy9hcGkvc2Vzc2lvbnMnXSxcbiAgfSk7XG5cbiAgcmV0dXJuIHtcbiAgICByb2xlOiAnbGVhZGVyJyxcbiAgICBlbGVjdGlvbixcbiAgICBwb3J0OiBjb25zb2xlUG9ydCxcbiAgICBjbGVhbnVwOiBhc3luYyAoKSA9PiB7XG4gICAgICBzdG9wSGVhcnRiZWF0KCk7XG4gICAgfSxcbiAgfTtcbn1cblxuLyoqXG4gKiBTdGFydCBhcyBhIGZvbGxvd2VyLlxuICogUmVnaXN0ZXJzIGZvcndhcmRpbmcgc2lua3Mgd2l0aCB0aGUgTG9nTWFuYWdlciwgc3RhcnRzIHNlc3Npb24gaGVhcnRiZWF0LlxuICovXG5hc3luYyBmdW5jdGlvbiBzdGFydEFzRm9sbG93ZXIoXG4gIG9wdGlvbnM6IFVuaWZpZWRDb25zb2xlT3B0aW9ucyxcbiAgZWxlY3Rpb246IEVsZWN0aW9uUmVzdWx0LFxuICBjb25zb2xlUG9ydDogbnVtYmVyID0gREVGQVVMVF9DT05TT0xFX1BPUlQsXG4pOiBQcm9taXNlPFVuaWZpZWRDb25zb2xlUmVzdWx0PiB7XG4gIGNvbnN0IGxlYWRlclVybCA9IGBodHRwOi8vMTI3LjAuMC4xOiR7ZWxlY3Rpb24ubGVhZGVySW5mby5wb3J0fWA7XG5cbiAgLy8gUmVhZCB0aGUgY29uc29sZSBhdXRoIHRva2VuICgjMTc4MCkgd3JpdHRlbiBieSB0aGUgbGVhZGVyLiBNYXkgYmUgbnVsbFxuICAvLyBpZiB0aGUgZmlsZSBkb2Vzbid0IGV4aXN0IHlldCDigJQgdGhlIHNpbmtzIGhhbmRsZSB0aGF0IGdyYWNlZnVsbHkgYW5kXG4gIC8vIHNpbXBseSBvbWl0IHRoZSBCZWFyZXIgaGVhZGVyLCB3aGljaCBpcyBmaW5lIHdoZW4gYXV0aCBpcyBub3QgZW5mb3JjZWQuXG4gIGNvbnN0IHsgZ2V0UHJpbWFyeVRva2VuRnJvbUZpbGUgfSA9IGF3YWl0IGltcG9ydCgnLi9jb25zb2xlVG9rZW4uanMnKTtcbiAgY29uc3QgYXV0aFRva2VuID0gYXdhaXQgZ2V0UHJpbWFyeVRva2VuRnJvbUZpbGUoZW52LkRPTExIT1VTRV9DT05TT0xFX1RPS0VOX0ZJTEUpO1xuICBpZiAoYXV0aFRva2VuKSB7XG4gICAgbG9nZ2VyLmRlYnVnKCdbVW5pZmllZENvbnNvbGVdIEZvbGxvd2VyIGxvYWRlZCBjb25zb2xlIGF1dGggdG9rZW4nKTtcbiAgfSBlbHNlIHtcbiAgICBsb2dnZXIuZGVidWcoJ1tVbmlmaWVkQ29uc29sZV0gTm8gY29uc29sZSBhdXRoIHRva2VuIGZpbGUgZm91bmQ7IGZvbGxvd2VyIHdpbGwgUE9TVCB3aXRob3V0IEJlYXJlciBoZWFkZXInKTtcbiAgfVxuXG4gIC8vIFBlci1pbnN0YW5jZSBwcm9tb3Rpb24gbWFuYWdlciDigJQgdHJhY2tzIGl0cyBvd24gYXR0ZW1wdCBjb3VudGVyIHNvXG4gIC8vIG11bHRpcGxlIGZvbGxvd2VycyBkb24ndCBpbnRlcmZlcmUgd2l0aCBlYWNoIG90aGVyJ3MgcHJvbW90aW9uIGJ1ZGdldHMuXG4gIGNvbnN0IHByb21vdGlvbk1nciA9IG5ldyBQcm9tb3Rpb25NYW5hZ2VyKG9wdGlvbnMsIGNvbnNvbGVQb3J0LCBzdGFydEFzTGVhZGVyLCBzdGFydEFzRm9sbG93ZXIpO1xuXG4gIC8vIERlY2xhcmUgc2Vzc2lvbkhlYXJ0YmVhdCBiZWZvcmUgdGhlIHNpbmsgc28gdGhlIGNsb3N1cmUgY2FuIGNhcHR1cmUgaXQuXG4gIC8vIEJvdGggYXJlIGluaXRpYWxpemVkIGJlZm9yZSB0aGUgY2FsbGJhY2sgY291bGQgcG9zc2libHkgZmlyZSAobmVlZHMgNSsgZmFpbGVkIGZsdXNoZXMpLlxuICBsZXQgc2Vzc2lvbkhlYXJ0YmVhdDogU2Vzc2lvbkhlYXJ0YmVhdDtcblxuICAvLyBSZWdpc3RlciBhIGZvcndhcmRpbmcgbG9nIHNpbmsgd2l0aCBsZWFkZXItZGVhdGggY2FsbGJhY2sgKCMxODUwKS5cbiAgY29uc3QgZm9yd2FyZGluZ1NpbmsgPSBuZXcgTGVhZGVyRm9yd2FyZGluZ0xvZ1NpbmsobGVhZGVyVXJsLCBvcHRpb25zLnNlc3Npb25JZCwgYXV0aFRva2VuLCAoKSA9PiB7XG4gICAgcHJvbW90aW9uTWdyLnByb21vdGUoZm9yd2FyZGluZ1NpbmssIHNlc3Npb25IZWFydGJlYXQpXG4gICAgICAuY2F0Y2goZXJyID0+IGxvZ2dlci5lcnJvcignW1VuaWZpZWRDb25zb2xlXSBQcm9tb3Rpb24gY3Jhc2hlZCcsIHsgZXJyb3I6IFN0cmluZyhlcnIpIH0pKTtcbiAgfSk7XG4gIG9wdGlvbnMucmVnaXN0ZXJMb2dTaW5rKGZvcndhcmRpbmdTaW5rKTtcblxuICAvLyBTdGFydCBzZXNzaW9uIGhlYXJ0YmVhdCB0byB0aGUgbGVhZGVyXG4gIHNlc3Npb25IZWFydGJlYXQgPSBuZXcgU2Vzc2lvbkhlYXJ0YmVhdChsZWFkZXJVcmwsIG9wdGlvbnMuc2Vzc2lvbklkLCBwcm9jZXNzLnBpZCwgYXV0aFRva2VuKTtcbiAgYXdhaXQgc2Vzc2lvbkhlYXJ0YmVhdC5zdGFydCgpO1xuXG4gIGxvZ2dlci5pbmZvKCdbVW5pZmllZENvbnNvbGVdIEZvbGxvd2VyIHN0YXJ0ZWQnLCB7XG4gICAgc2Vzc2lvbklkOiBvcHRpb25zLnNlc3Npb25JZCwgcGlkOiBwcm9jZXNzLnBpZCwgcm9sZTogJ2ZvbGxvd2VyJyxcbiAgICBsZWFkZXJTZXNzaW9uOiBlbGVjdGlvbi5sZWFkZXJJbmZvLnNlc3Npb25JZCwgbGVhZGVyUGlkOiBlbGVjdGlvbi5sZWFkZXJJbmZvLnBpZCxcbiAgICBsZWFkZXJQb3J0OiBlbGVjdGlvbi5sZWFkZXJJbmZvLnBvcnQsIGxlYWRlclVybCxcbiAgfSk7XG5cbiAgcmV0dXJuIHtcbiAgICByb2xlOiAnZm9sbG93ZXInLFxuICAgIGVsZWN0aW9uLFxuICAgIGNsZWFudXA6IGFzeW5jICgpID0+IHtcbiAgICAgIGF3YWl0IHNlc3Npb25IZWFydGJlYXQuc3RvcCgpO1xuICAgICAgYXdhaXQgZm9yd2FyZGluZ1NpbmsuY2xvc2UoKTtcbiAgICB9LFxuICB9O1xufVxuXG4iXX0=
|
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
* Claude Code windows, IDE instances, or agent sessions), each needs its
|
|
6
6
|
* own web console port. This module handles:
|
|
7
7
|
*
|
|
8
|
-
* 1. Finding an available port starting from the default
|
|
8
|
+
* 1. Finding an available port starting from the configured default
|
|
9
|
+
* (see `DOLLHOUSE_WEB_CONSOLE_PORT` in `src/config/env.ts`)
|
|
9
10
|
* 2. Writing port discovery files so external tools know which port to use
|
|
10
11
|
* 3. Cleaning up port files on process exit
|
|
11
12
|
*
|
|
@@ -20,7 +21,7 @@
|
|
|
20
21
|
* and a held server to prevent TOCTOU race conditions. The caller should
|
|
21
22
|
* close the held server after binding their own Express app to the port.
|
|
22
23
|
*
|
|
23
|
-
* @param startPort - Port to try first (default
|
|
24
|
+
* @param startPort - Port to try first (see `DOLLHOUSE_WEB_CONSOLE_PORT` for the default)
|
|
24
25
|
* @param maxAttempts - Maximum ports to try (default: 10, configurable via DOLLHOUSE_MAX_PORT_ATTEMPTS)
|
|
25
26
|
* @returns Object with port number and held server, or throws if all attempts fail
|
|
26
27
|
*/
|
|
@@ -51,7 +52,7 @@ export declare function registerPortCleanup(): void;
|
|
|
51
52
|
* This is the recommended entry point for Container startup. Combines
|
|
52
53
|
* port discovery, file writing, and cleanup registration in one call.
|
|
53
54
|
*
|
|
54
|
-
* @param defaultPort - Port to try first (default
|
|
55
|
+
* @param defaultPort - Port to try first (see `DOLLHOUSE_WEB_CONSOLE_PORT` for the default)
|
|
55
56
|
* @returns The port the server should bind to, or undefined if discovery failed
|
|
56
57
|
*/
|
|
57
58
|
export declare function discoverAndBindPort(defaultPort?: number): Promise<number | undefined>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"portDiscovery.d.ts","sourceRoot":"","sources":["../../src/web/portDiscovery.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"portDiscovery.d.ts","sourceRoot":"","sources":["../../src/web/portDiscovery.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAyCH;;;;;;;;;;GAUG;AACH,wBAAsB,iBAAiB,CACrC,SAAS,EAAE,MAAM,EACjB,WAAW,GAAE,MAAqF,GACjG,OAAO,CAAC,MAAM,CAAC,CAuBjB;AAED;;;;;;;;;GASG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CASjE;AAED;;GAEG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAIrD;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAK1C;AAED;;;;;;;;GAQG;AACH,wBAAsB,mBAAmB,CACvC,WAAW,GAAE,MAAuC,GACnD,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAY7B"}
|
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
* Claude Code windows, IDE instances, or agent sessions), each needs its
|
|
6
6
|
* own web console port. This module handles:
|
|
7
7
|
*
|
|
8
|
-
* 1. Finding an available port starting from the default
|
|
8
|
+
* 1. Finding an available port starting from the configured default
|
|
9
|
+
* (see `DOLLHOUSE_WEB_CONSOLE_PORT` in `src/config/env.ts`)
|
|
9
10
|
* 2. Writing port discovery files so external tools know which port to use
|
|
10
11
|
* 3. Cleaning up port files on process exit
|
|
11
12
|
*
|
|
@@ -17,6 +18,7 @@ import { createServer } from 'node:net';
|
|
|
17
18
|
import { homedir } from 'node:os';
|
|
18
19
|
import { join } from 'node:path';
|
|
19
20
|
import { mkdir, writeFile, unlink } from 'node:fs/promises';
|
|
21
|
+
import { env } from '../config/env.js';
|
|
20
22
|
import { logger } from '../utils/logger.js';
|
|
21
23
|
/** Default maximum port attempts before giving up */
|
|
22
24
|
const DEFAULT_MAX_PORT_ATTEMPTS = 10;
|
|
@@ -54,7 +56,7 @@ function tryBindPort(port) {
|
|
|
54
56
|
* and a held server to prevent TOCTOU race conditions. The caller should
|
|
55
57
|
* close the held server after binding their own Express app to the port.
|
|
56
58
|
*
|
|
57
|
-
* @param startPort - Port to try first (default
|
|
59
|
+
* @param startPort - Port to try first (see `DOLLHOUSE_WEB_CONSOLE_PORT` for the default)
|
|
58
60
|
* @param maxAttempts - Maximum ports to try (default: 10, configurable via DOLLHOUSE_MAX_PORT_ATTEMPTS)
|
|
59
61
|
* @returns Object with port number and held server, or throws if all attempts fail
|
|
60
62
|
*/
|
|
@@ -125,10 +127,10 @@ export function registerPortCleanup() {
|
|
|
125
127
|
* This is the recommended entry point for Container startup. Combines
|
|
126
128
|
* port discovery, file writing, and cleanup registration in one call.
|
|
127
129
|
*
|
|
128
|
-
* @param defaultPort - Port to try first (default
|
|
130
|
+
* @param defaultPort - Port to try first (see `DOLLHOUSE_WEB_CONSOLE_PORT` for the default)
|
|
129
131
|
* @returns The port the server should bind to, or undefined if discovery failed
|
|
130
132
|
*/
|
|
131
|
-
export async function discoverAndBindPort(defaultPort =
|
|
133
|
+
export async function discoverAndBindPort(defaultPort = env.DOLLHOUSE_WEB_CONSOLE_PORT) {
|
|
132
134
|
try {
|
|
133
135
|
const port = await findAvailablePort(defaultPort);
|
|
134
136
|
await writePortFile(port);
|
|
@@ -140,4 +142,4 @@ export async function discoverAndBindPort(defaultPort = 3939) {
|
|
|
140
142
|
return undefined;
|
|
141
143
|
}
|
|
142
144
|
}
|
|
143
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG9ydERpc2NvdmVyeS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy93ZWIvcG9ydERpc2NvdmVyeS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7R0FjRztBQUVILE9BQU8sRUFBRSxZQUFZLEVBQWUsTUFBTSxVQUFVLENBQUM7QUFDckQsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUNsQyxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQ2pDLE9BQU8sRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLE1BQU0sRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQzVELE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUU1QyxxREFBcUQ7QUFDckQsTUFBTSx5QkFBeUIsR0FBRyxFQUFFLENBQUM7QUFFckMsb0VBQW9FO0FBQ3BFLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxPQUFPLEVBQUUsRUFBRSxZQUFZLEVBQUUsS0FBSyxDQUFDLENBQUM7QUFFckQsdUNBQXVDO0FBQ3ZDLElBQUksWUFBWSxHQUFrQixJQUFJLENBQUM7QUFFdkM7Ozs7R0FJRztBQUNILFNBQVMsV0FBVyxDQUFDLElBQVk7SUFDL0IsT0FBTyxJQUFJLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFO1FBQzdCLE1BQU0sTUFBTSxHQUFHLFlBQVksRUFBRSxDQUFDO1FBQzlCLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUMsR0FBMEIsRUFBRSxFQUFFO1lBQ2xELElBQUksR0FBRyxDQUFDLElBQUksS0FBSyxZQUFZLEVBQUUsQ0FBQztnQkFDOUIsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ2hCLENBQUM7aUJBQU0sQ0FBQztnQkFDTixPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBQ2QsTUFBTSxDQUFDLEtBQUssQ0FBQyw0Q0FBNEMsSUFBSSxLQUFLLEdBQUcsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO1lBQ2hGLENBQUM7UUFDSCxDQUFDLENBQUMsQ0FBQztRQUNILE1BQU0sQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLEdBQUcsRUFBRTtZQUM1QixPQUFPLENBQUMsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQztRQUM1QixDQUFDLENBQUMsQ0FBQztRQUNILE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLFdBQVcsQ0FBQyxDQUFDO0lBQ25DLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQztBQUVEOzs7Ozs7Ozs7O0dBVUc7QUFDSCxNQUFNLENBQUMsS0FBSyxVQUFVLGlCQUFpQixDQUNyQyxTQUFpQixFQUNqQixjQUFzQixNQUFNLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQywyQkFBMkIsQ0FBQyxJQUFJLHlCQUF5QjtJQUVsRyxLQUFLLElBQUksT0FBTyxHQUFHLENBQUMsRUFBRSxPQUFPLEdBQUcsV0FBVyxFQUFFLE9BQU8sRUFBRSxFQUFFLENBQUM7UUFDdkQsTUFBTSxJQUFJLEdBQUcsU0FBUyxHQUFHLE9BQU8sQ0FBQztRQUNqQyxNQUFNLENBQUMsS0FBSyxDQUFDLCtCQUErQixJQUFJLGFBQWEsT0FBTyxHQUFHLENBQUMsSUFBSSxXQUFXLEdBQUcsQ0FBQyxDQUFDO1FBRTVGLE1BQU0sTUFBTSxHQUFHLE1BQU0sV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3ZDLElBQUksTUFBTSxFQUFFLENBQUM7WUFDWCxzRUFBc0U7WUFDdEUsb0VBQW9FO1lBQ3BFLHdFQUF3RTtZQUN4RSxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ3RCLElBQUksT0FBTyxHQUFHLENBQUMsRUFBRSxDQUFDO2dCQUNoQixNQUFNLENBQUMsSUFBSSxDQUFDLHdCQUF3QixTQUFTLGtCQUFrQixJQUFJLFdBQVcsT0FBTyxRQUFRLE9BQU8sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztZQUMxSCxDQUFDO1lBQ0QsT0FBTyxJQUFJLENBQUM7UUFDZCxDQUFDO1FBQ0QsTUFBTSxDQUFDLEtBQUssQ0FBQyx3QkFBd0IsSUFBSSxzQkFBc0IsQ0FBQyxDQUFDO0lBQ25FLENBQUM7SUFFRCxNQUFNLElBQUksS0FBSyxDQUNiLG9DQUFvQyxTQUFTLElBQUksU0FBUyxHQUFHLFdBQVcsR0FBRyxDQUFDLEdBQUc7UUFDL0UsU0FBUyxXQUFXLG1FQUFtRSxDQUN4RixDQUFDO0FBQ0osQ0FBQztBQUVEOzs7Ozs7Ozs7R0FTRztBQUNILE1BQU0sQ0FBQyxLQUFLLFVBQVUsYUFBYSxDQUFDLElBQVk7SUFDOUMsTUFBTSxLQUFLLENBQUMsT0FBTyxFQUFFLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7SUFDMUMsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLE9BQU8sRUFBRSxxQkFBcUIsT0FBTyxDQUFDLEdBQUcsT0FBTyxDQUFDLENBQUM7SUFDdkUsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLE9BQU8sRUFBRSx3QkFBd0IsQ0FBQyxDQUFDO0lBQzNELE1BQU0sU0FBUyxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDaEQsTUFBTSxTQUFTLENBQUMsVUFBVSxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQztJQUNuRCxZQUFZLEdBQUcsT0FBTyxDQUFDO0lBQ3ZCLE1BQU0sQ0FBQyxLQUFLLENBQUMsc0NBQXNDLE9BQU8sRUFBRSxDQUFDLENBQUM7SUFDOUQsT0FBTyxPQUFPLENBQUM7QUFDakIsQ0FBQztBQUVEOztHQUVHO0FBQ0gsTUFBTSxDQUFDLEtBQUssVUFBVSxlQUFlO0lBQ25DLElBQUksWUFBWSxFQUFFLENBQUM7UUFDakIsSUFBSSxDQUFDO1lBQUMsTUFBTSxNQUFNLENBQUMsWUFBWSxDQUFDLENBQUM7UUFBQyxDQUFDO1FBQUMsTUFBTSxDQUFDLENBQUMsa0JBQWtCLENBQUMsQ0FBQztJQUNsRSxDQUFDO0FBQ0gsQ0FBQztBQUVEOzs7R0FHRztBQUNILE1BQU0sVUFBVSxtQkFBbUI7SUFDakMsTUFBTSxXQUFXLEdBQUcsR0FBRyxFQUFFLEdBQUcsZUFBZSxFQUFFLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxHQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ2pFLE9BQU8sQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLFdBQVcsQ0FBQyxDQUFDO0lBQ2xDLE9BQU8sQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLFdBQVcsQ0FBQyxDQUFDO0lBQ3JDLE9BQU8sQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLFdBQVcsQ0FBQyxDQUFDO0FBQ3RDLENBQUM7QUFFRDs7Ozs7Ozs7R0FRRztBQUNILE1BQU0sQ0FBQyxLQUFLLFVBQVUsbUJBQW1CLENBQUMsY0FBc0IsSUFBSTtJQUNsRSxJQUFJLENBQUM7UUFDSCxNQUFNLElBQUksR0FBRyxNQUFNLGlCQUFpQixDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBRWxELE1BQU0sYUFBYSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzFCLG1CQUFtQixFQUFFLENBQUM7UUFFdEIsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBQUMsT0FBTyxHQUFHLEVBQUUsQ0FBQztRQUNiLE1BQU0sQ0FBQyxJQUFJLENBQUMsd0NBQXdDLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDM0QsT0FBTyxTQUFTLENBQUM7SUFDbkIsQ0FBQztBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIER5bmFtaWMgcG9ydCBhbGxvY2F0aW9uIGFuZCBwb3J0IGZpbGUgZGlzY292ZXJ5IGZvciB0aGUgd2ViIGNvbnNvbGUuXG4gKlxuICogV2hlbiBtdWx0aXBsZSBEb2xsaG91c2VNQ1Agc2Vzc2lvbnMgcnVuIHNpbXVsdGFuZW91c2x5IChlLmcuLCBtdWx0aXBsZVxuICogQ2xhdWRlIENvZGUgd2luZG93cywgSURFIGluc3RhbmNlcywgb3IgYWdlbnQgc2Vzc2lvbnMpLCBlYWNoIG5lZWRzIGl0c1xuICogb3duIHdlYiBjb25zb2xlIHBvcnQuIFRoaXMgbW9kdWxlIGhhbmRsZXM6XG4gKlxuICogMS4gRmluZGluZyBhbiBhdmFpbGFibGUgcG9ydCBzdGFydGluZyBmcm9tIHRoZSBkZWZhdWx0ICgzOTM5KVxuICogMi4gV3JpdGluZyBwb3J0IGRpc2NvdmVyeSBmaWxlcyBzbyBleHRlcm5hbCB0b29scyBrbm93IHdoaWNoIHBvcnQgdG8gdXNlXG4gKiAzLiBDbGVhbmluZyB1cCBwb3J0IGZpbGVzIG9uIHByb2Nlc3MgZXhpdFxuICpcbiAqIFBvcnQgZmlsZXMgYXJlIHdyaXR0ZW4gdG8gfi8uZG9sbGhvdXNlL3J1bi86XG4gKiAtIHBlcm1pc3Npb24tc2VydmVyLXtwaWR9LnBvcnQg4oCUIHBlci1wcm9jZXNzIGZpbGUgKGNsZWFuZWQgb24gZXhpdClcbiAqIC0gcGVybWlzc2lvbi1zZXJ2ZXIucG9ydCDigJQgbGF0ZXN0IHBvcnQgKGNvbnZlbmllbmNlIGZvciBzY3JpcHRzKVxuICovXG5cbmltcG9ydCB7IGNyZWF0ZVNlcnZlciwgdHlwZSBTZXJ2ZXIgfSBmcm9tICdub2RlOm5ldCc7XG5pbXBvcnQgeyBob21lZGlyIH0gZnJvbSAnbm9kZTpvcyc7XG5pbXBvcnQgeyBqb2luIH0gZnJvbSAnbm9kZTpwYXRoJztcbmltcG9ydCB7IG1rZGlyLCB3cml0ZUZpbGUsIHVubGluayB9IGZyb20gJ25vZGU6ZnMvcHJvbWlzZXMnO1xuaW1wb3J0IHsgbG9nZ2VyIH0gZnJvbSAnLi4vdXRpbHMvbG9nZ2VyLmpzJztcblxuLyoqIERlZmF1bHQgbWF4aW11bSBwb3J0IGF0dGVtcHRzIGJlZm9yZSBnaXZpbmcgdXAgKi9cbmNvbnN0IERFRkFVTFRfTUFYX1BPUlRfQVRURU1QVFMgPSAxMDtcblxuLyoqIERpcmVjdG9yeSBmb3IgcnVudGltZSBzdGF0ZSBmaWxlcyAocG9ydCBkaXNjb3ZlcnksIFBJRCBmaWxlcykgKi9cbmNvbnN0IFJVTl9ESVIgPSBqb2luKGhvbWVkaXIoKSwgJy5kb2xsaG91c2UnLCAncnVuJyk7XG5cbi8qKiBUcmFjayBwb3J0IGZpbGUgcGF0aCBmb3IgY2xlYW51cCAqL1xubGV0IHBvcnRGaWxlUGF0aDogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG5cbi8qKlxuICogQXR0ZW1wdCB0byBiaW5kIHRvIGEgc2luZ2xlIHBvcnQuIFJldHVybnMgdGhlIHBvcnQgaWYgc3VjY2Vzc2Z1bCwgbnVsbCBpZiBpbiB1c2UuXG4gKiBLZWVwcyB0aGUgc2VydmVyIGxpc3RlbmluZyB0byBwcmV2ZW50IFRPQ1RPVSByYWNlIGNvbmRpdGlvbnMg4oCUIGNhbGxlciBtdXN0XG4gKiBjbG9zZSB0aGUgcmV0dXJuZWQgc2VydmVyIGFmdGVyIHRoZWlyIG93biBzZXJ2ZXIgYmluZHMuXG4gKi9cbmZ1bmN0aW9uIHRyeUJpbmRQb3J0KHBvcnQ6IG51bWJlcik6IFByb21pc2U8eyBwb3J0OiBudW1iZXI7IHNlcnZlcjogU2VydmVyIH0gfCBudWxsPiB7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgIGNvbnN0IHNlcnZlciA9IGNyZWF0ZVNlcnZlcigpO1xuICAgIHNlcnZlci5vbmNlKCdlcnJvcicsIChlcnI6IE5vZGVKUy5FcnJub0V4Y2VwdGlvbikgPT4ge1xuICAgICAgaWYgKGVyci5jb2RlID09PSAnRUFERFJJTlVTRScpIHtcbiAgICAgICAgcmVzb2x2ZShudWxsKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlc29sdmUobnVsbCk7XG4gICAgICAgIGxvZ2dlci5kZWJ1ZyhgW1BvcnREaXNjb3ZlcnldIFVuZXhwZWN0ZWQgZXJyb3Igb24gcG9ydCAke3BvcnR9OiAke2Vyci5jb2RlfWApO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHNlcnZlci5vbmNlKCdsaXN0ZW5pbmcnLCAoKSA9PiB7XG4gICAgICByZXNvbHZlKHsgcG9ydCwgc2VydmVyIH0pO1xuICAgIH0pO1xuICAgIHNlcnZlci5saXN0ZW4ocG9ydCwgJzEyNy4wLjAuMScpO1xuICB9KTtcbn1cblxuLyoqXG4gKiBGaW5kIGFuIGF2YWlsYWJsZSBwb3J0IHN0YXJ0aW5nIGZyb20gdGhlIGdpdmVuIHBvcnQuXG4gKlxuICogVHJpZXMgc2VxdWVudGlhbCBwb3J0cywgbG9nZ2luZyBlYWNoIGF0dGVtcHQuIFJldHVybnMgYm90aCB0aGUgcG9ydCBudW1iZXJcbiAqIGFuZCBhIGhlbGQgc2VydmVyIHRvIHByZXZlbnQgVE9DVE9VIHJhY2UgY29uZGl0aW9ucy4gVGhlIGNhbGxlciBzaG91bGRcbiAqIGNsb3NlIHRoZSBoZWxkIHNlcnZlciBhZnRlciBiaW5kaW5nIHRoZWlyIG93biBFeHByZXNzIGFwcCB0byB0aGUgcG9ydC5cbiAqXG4gKiBAcGFyYW0gc3RhcnRQb3J0IC0gUG9ydCB0byB0cnkgZmlyc3QgKGRlZmF1bHQ6IDM5MzkpXG4gKiBAcGFyYW0gbWF4QXR0ZW1wdHMgLSBNYXhpbXVtIHBvcnRzIHRvIHRyeSAoZGVmYXVsdDogMTAsIGNvbmZpZ3VyYWJsZSB2aWEgRE9MTEhPVVNFX01BWF9QT1JUX0FUVEVNUFRTKVxuICogQHJldHVybnMgT2JqZWN0IHdpdGggcG9ydCBudW1iZXIgYW5kIGhlbGQgc2VydmVyLCBvciB0aHJvd3MgaWYgYWxsIGF0dGVtcHRzIGZhaWxcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGZpbmRBdmFpbGFibGVQb3J0KFxuICBzdGFydFBvcnQ6IG51bWJlcixcbiAgbWF4QXR0ZW1wdHM6IG51bWJlciA9IE51bWJlcihwcm9jZXNzLmVudi5ET0xMSE9VU0VfTUFYX1BPUlRfQVRURU1QVFMpIHx8IERFRkFVTFRfTUFYX1BPUlRfQVRURU1QVFMsXG4pOiBQcm9taXNlPG51bWJlcj4ge1xuICBmb3IgKGxldCBhdHRlbXB0ID0gMDsgYXR0ZW1wdCA8IG1heEF0dGVtcHRzOyBhdHRlbXB0KyspIHtcbiAgICBjb25zdCBwb3J0ID0gc3RhcnRQb3J0ICsgYXR0ZW1wdDtcbiAgICBsb2dnZXIuZGVidWcoYFtQb3J0RGlzY292ZXJ5XSBUcnlpbmcgcG9ydCAke3BvcnR9IChhdHRlbXB0ICR7YXR0ZW1wdCArIDF9LyR7bWF4QXR0ZW1wdHN9KWApO1xuXG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdHJ5QmluZFBvcnQocG9ydCk7XG4gICAgaWYgKHJlc3VsdCkge1xuICAgICAgLy8gQ2xvc2UgdGhlIHByb2JlIHNlcnZlciDigJQgdGhlcmUncyBhIGJyaWVmIFRPQ1RPVSB3aW5kb3cgaGVyZSBiZXR3ZWVuXG4gICAgICAvLyBjbG9zaW5nIGFuZCB0aGUgY2FsbGVyIGJpbmRpbmcsIGJ1dCBpdCdzIG5lZ2xpZ2libGUgb24gbG9jYWxob3N0LlxuICAgICAgLy8gQSBmdXR1cmUgaW1wcm92ZW1lbnQgY291bGQgcmV0dXJuIHRoZSBzZXJ2ZXIgZm9yIHRoZSBjYWxsZXIgdG8gYWRvcHQuXG4gICAgICByZXN1bHQuc2VydmVyLmNsb3NlKCk7XG4gICAgICBpZiAoYXR0ZW1wdCA+IDApIHtcbiAgICAgICAgbG9nZ2VyLmluZm8oYFtQb3J0RGlzY292ZXJ5XSBQb3J0ICR7c3RhcnRQb3J0fSBpbiB1c2UsIHVzaW5nICR7cG9ydH0gKGFmdGVyICR7YXR0ZW1wdH0gc2tpcCR7YXR0ZW1wdCA+IDEgPyAncycgOiAnJ30pYCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gcG9ydDtcbiAgICB9XG4gICAgbG9nZ2VyLmRlYnVnKGBbUG9ydERpc2NvdmVyeV0gUG9ydCAke3BvcnR9IGluIHVzZSwgdHJ5aW5nIG5leHRgKTtcbiAgfVxuXG4gIHRocm93IG5ldyBFcnJvcihcbiAgICBgTm8gYXZhaWxhYmxlIHBvcnQgZm91bmQgaW4gcmFuZ2UgJHtzdGFydFBvcnR9LSR7c3RhcnRQb3J0ICsgbWF4QXR0ZW1wdHMgLSAxfSBgICtcbiAgICBgYWZ0ZXIgJHttYXhBdHRlbXB0c30gYXR0ZW1wdHMuIFNldCBET0xMSE9VU0VfTUFYX1BPUlRfQVRURU1QVFMgdG8gaW5jcmVhc2UgdGhlIHJhbmdlLmBcbiAgKTtcbn1cblxuLyoqXG4gKiBXcml0ZSB0aGUgYWN0aXZlIHNlcnZlciBwb3J0IHRvIGEgZGlzY292ZXJhYmxlIGZpbGUuXG4gKlxuICogQ3JlYXRlcyB0d28gZmlsZXM6XG4gKiAtIFBJRC1rZXllZCBmaWxlIGZvciBwZXItcHJvY2VzcyBjbGVhbnVwXG4gKiAtIExhdGVzdCBmaWxlIGZvciBjb252ZW5pZW5jZSAoc2NyaXB0cyBjYW4gcmVhZCB0aGlzIHdpdGhvdXQga25vd2luZyB0aGUgUElEKVxuICpcbiAqIEBwYXJhbSBwb3J0IC0gVGhlIHBvcnQgdGhlIHdlYiBzZXJ2ZXIgaXMgbGlzdGVuaW5nIG9uXG4gKiBAcmV0dXJucyBQYXRoIHRvIHRoZSBQSUQta2V5ZWQgcG9ydCBmaWxlXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiB3cml0ZVBvcnRGaWxlKHBvcnQ6IG51bWJlcik6IFByb21pc2U8c3RyaW5nPiB7XG4gIGF3YWl0IG1rZGlyKFJVTl9ESVIsIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICBjb25zdCBwaWRGaWxlID0gam9pbihSVU5fRElSLCBgcGVybWlzc2lvbi1zZXJ2ZXItJHtwcm9jZXNzLnBpZH0ucG9ydGApO1xuICBjb25zdCBsYXRlc3RGaWxlID0gam9pbihSVU5fRElSLCAncGVybWlzc2lvbi1zZXJ2ZXIucG9ydCcpO1xuICBhd2FpdCB3cml0ZUZpbGUocGlkRmlsZSwgU3RyaW5nKHBvcnQpLCAndXRmLTgnKTtcbiAgYXdhaXQgd3JpdGVGaWxlKGxhdGVzdEZpbGUsIFN0cmluZyhwb3J0KSwgJ3V0Zi04Jyk7XG4gIHBvcnRGaWxlUGF0aCA9IHBpZEZpbGU7XG4gIGxvZ2dlci5kZWJ1ZyhgW1BvcnREaXNjb3ZlcnldIFBvcnQgZmlsZSB3cml0dGVuOiAke3BpZEZpbGV9YCk7XG4gIHJldHVybiBwaWRGaWxlO1xufVxuXG4vKipcbiAqIENsZWFuIHVwIHBvcnQgZmlsZSBvbiBzaHV0ZG93bi5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNsZWFudXBQb3J0RmlsZSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgaWYgKHBvcnRGaWxlUGF0aCkge1xuICAgIHRyeSB7IGF3YWl0IHVubGluayhwb3J0RmlsZVBhdGgpOyB9IGNhdGNoIHsgLyogYWxyZWFkeSBnb25lICovIH1cbiAgfVxufVxuXG4vKipcbiAqIFJlZ2lzdGVyIHByb2Nlc3MgZXhpdCBoYW5kbGVycyB0byBjbGVhbiB1cCBwb3J0IGZpbGVzLlxuICogU2hvdWxkIGJlIGNhbGxlZCBvbmNlIGFmdGVyIHRoZSB3ZWIgc2VydmVyIHN1Y2Nlc3NmdWxseSBzdGFydHMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWdpc3RlclBvcnRDbGVhbnVwKCk6IHZvaWQge1xuICBjb25zdCBleGl0Q2xlYW51cCA9ICgpID0+IHsgY2xlYW51cFBvcnRGaWxlKCkuY2F0Y2goKCkgPT4ge30pOyB9O1xuICBwcm9jZXNzLm9uY2UoJ2V4aXQnLCBleGl0Q2xlYW51cCk7XG4gIHByb2Nlc3Mub25jZSgnU0lHVEVSTScsIGV4aXRDbGVhbnVwKTtcbiAgcHJvY2Vzcy5vbmNlKCdTSUdJTlQnLCBleGl0Q2xlYW51cCk7XG59XG5cbi8qKlxuICogRGlzY292ZXIgYW4gYXZhaWxhYmxlIHBvcnQsIHdyaXRlIGRpc2NvdmVyeSBmaWxlcywgYW5kIHJlZ2lzdGVyIGNsZWFudXAuXG4gKlxuICogVGhpcyBpcyB0aGUgcmVjb21tZW5kZWQgZW50cnkgcG9pbnQgZm9yIENvbnRhaW5lciBzdGFydHVwLiBDb21iaW5lc1xuICogcG9ydCBkaXNjb3ZlcnksIGZpbGUgd3JpdGluZywgYW5kIGNsZWFudXAgcmVnaXN0cmF0aW9uIGluIG9uZSBjYWxsLlxuICpcbiAqIEBwYXJhbSBkZWZhdWx0UG9ydCAtIFBvcnQgdG8gdHJ5IGZpcnN0IChkZWZhdWx0OiAzOTM5KVxuICogQHJldHVybnMgVGhlIHBvcnQgdGhlIHNlcnZlciBzaG91bGQgYmluZCB0bywgb3IgdW5kZWZpbmVkIGlmIGRpc2NvdmVyeSBmYWlsZWRcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGRpc2NvdmVyQW5kQmluZFBvcnQoZGVmYXVsdFBvcnQ6IG51bWJlciA9IDM5MzkpOiBQcm9taXNlPG51bWJlciB8IHVuZGVmaW5lZD4ge1xuICB0cnkge1xuICAgIGNvbnN0IHBvcnQgPSBhd2FpdCBmaW5kQXZhaWxhYmxlUG9ydChkZWZhdWx0UG9ydCk7XG5cbiAgICBhd2FpdCB3cml0ZVBvcnRGaWxlKHBvcnQpO1xuICAgIHJlZ2lzdGVyUG9ydENsZWFudXAoKTtcblxuICAgIHJldHVybiBwb3J0O1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICBsb2dnZXIud2FybignW1BvcnREaXNjb3ZlcnldIFBvcnQgZGlzY292ZXJ5IGZhaWxlZDonLCBlcnIpO1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbn1cbiJdfQ==
|
|
145
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG9ydERpc2NvdmVyeS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy93ZWIvcG9ydERpc2NvdmVyeS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7O0dBZUc7QUFFSCxPQUFPLEVBQUUsWUFBWSxFQUFlLE1BQU0sVUFBVSxDQUFDO0FBQ3JELE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFDbEMsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUNqQyxPQUFPLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUM1RCxPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDdkMsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBRTVDLHFEQUFxRDtBQUNyRCxNQUFNLHlCQUF5QixHQUFHLEVBQUUsQ0FBQztBQUVyQyxvRUFBb0U7QUFDcEUsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLE9BQU8sRUFBRSxFQUFFLFlBQVksRUFBRSxLQUFLLENBQUMsQ0FBQztBQUVyRCx1Q0FBdUM7QUFDdkMsSUFBSSxZQUFZLEdBQWtCLElBQUksQ0FBQztBQUV2Qzs7OztHQUlHO0FBQ0gsU0FBUyxXQUFXLENBQUMsSUFBWTtJQUMvQixPQUFPLElBQUksT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUU7UUFDN0IsTUFBTSxNQUFNLEdBQUcsWUFBWSxFQUFFLENBQUM7UUFDOUIsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQyxHQUEwQixFQUFFLEVBQUU7WUFDbEQsSUFBSSxHQUFHLENBQUMsSUFBSSxLQUFLLFlBQVksRUFBRSxDQUFDO2dCQUM5QixPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDaEIsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDZCxNQUFNLENBQUMsS0FBSyxDQUFDLDRDQUE0QyxJQUFJLEtBQUssR0FBRyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7WUFDaEYsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO1FBQ0gsTUFBTSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsR0FBRyxFQUFFO1lBQzVCLE9BQU8sQ0FBQyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDO1FBQzVCLENBQUMsQ0FBQyxDQUFDO1FBQ0gsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsV0FBVyxDQUFDLENBQUM7SUFDbkMsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDO0FBRUQ7Ozs7Ozs7Ozs7R0FVRztBQUNILE1BQU0sQ0FBQyxLQUFLLFVBQVUsaUJBQWlCLENBQ3JDLFNBQWlCLEVBQ2pCLGNBQXNCLE1BQU0sQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLDJCQUEyQixDQUFDLElBQUkseUJBQXlCO0lBRWxHLEtBQUssSUFBSSxPQUFPLEdBQUcsQ0FBQyxFQUFFLE9BQU8sR0FBRyxXQUFXLEVBQUUsT0FBTyxFQUFFLEVBQUUsQ0FBQztRQUN2RCxNQUFNLElBQUksR0FBRyxTQUFTLEdBQUcsT0FBTyxDQUFDO1FBQ2pDLE1BQU0sQ0FBQyxLQUFLLENBQUMsK0JBQStCLElBQUksYUFBYSxPQUFPLEdBQUcsQ0FBQyxJQUFJLFdBQVcsR0FBRyxDQUFDLENBQUM7UUFFNUYsTUFBTSxNQUFNLEdBQUcsTUFBTSxXQUFXLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDdkMsSUFBSSxNQUFNLEVBQUUsQ0FBQztZQUNYLHNFQUFzRTtZQUN0RSxvRUFBb0U7WUFDcEUsd0VBQXdFO1lBQ3hFLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDdEIsSUFBSSxPQUFPLEdBQUcsQ0FBQyxFQUFFLENBQUM7Z0JBQ2hCLE1BQU0sQ0FBQyxJQUFJLENBQUMsd0JBQXdCLFNBQVMsa0JBQWtCLElBQUksV0FBVyxPQUFPLFFBQVEsT0FBTyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1lBQzFILENBQUM7WUFDRCxPQUFPLElBQUksQ0FBQztRQUNkLENBQUM7UUFDRCxNQUFNLENBQUMsS0FBSyxDQUFDLHdCQUF3QixJQUFJLHNCQUFzQixDQUFDLENBQUM7SUFDbkUsQ0FBQztJQUVELE1BQU0sSUFBSSxLQUFLLENBQ2Isb0NBQW9DLFNBQVMsSUFBSSxTQUFTLEdBQUcsV0FBVyxHQUFHLENBQUMsR0FBRztRQUMvRSxTQUFTLFdBQVcsbUVBQW1FLENBQ3hGLENBQUM7QUFDSixDQUFDO0FBRUQ7Ozs7Ozs7OztHQVNHO0FBQ0gsTUFBTSxDQUFDLEtBQUssVUFBVSxhQUFhLENBQUMsSUFBWTtJQUM5QyxNQUFNLEtBQUssQ0FBQyxPQUFPLEVBQUUsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztJQUMxQyxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsT0FBTyxFQUFFLHFCQUFxQixPQUFPLENBQUMsR0FBRyxPQUFPLENBQUMsQ0FBQztJQUN2RSxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsT0FBTyxFQUFFLHdCQUF3QixDQUFDLENBQUM7SUFDM0QsTUFBTSxTQUFTLENBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQztJQUNoRCxNQUFNLFNBQVMsQ0FBQyxVQUFVLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQ25ELFlBQVksR0FBRyxPQUFPLENBQUM7SUFDdkIsTUFBTSxDQUFDLEtBQUssQ0FBQyxzQ0FBc0MsT0FBTyxFQUFFLENBQUMsQ0FBQztJQUM5RCxPQUFPLE9BQU8sQ0FBQztBQUNqQixDQUFDO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLENBQUMsS0FBSyxVQUFVLGVBQWU7SUFDbkMsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUNqQixJQUFJLENBQUM7WUFBQyxNQUFNLE1BQU0sQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUFDLENBQUM7UUFBQyxNQUFNLENBQUMsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO0lBQ2xFLENBQUM7QUFDSCxDQUFDO0FBRUQ7OztHQUdHO0FBQ0gsTUFBTSxVQUFVLG1CQUFtQjtJQUNqQyxNQUFNLFdBQVcsR0FBRyxHQUFHLEVBQUUsR0FBRyxlQUFlLEVBQUUsQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLEdBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDakUsT0FBTyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsV0FBVyxDQUFDLENBQUM7SUFDbEMsT0FBTyxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsV0FBVyxDQUFDLENBQUM7SUFDckMsT0FBTyxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsV0FBVyxDQUFDLENBQUM7QUFDdEMsQ0FBQztBQUVEOzs7Ozs7OztHQVFHO0FBQ0gsTUFBTSxDQUFDLEtBQUssVUFBVSxtQkFBbUIsQ0FDdkMsY0FBc0IsR0FBRyxDQUFDLDBCQUEwQjtJQUVwRCxJQUFJLENBQUM7UUFDSCxNQUFNLElBQUksR0FBRyxNQUFNLGlCQUFpQixDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBRWxELE1BQU0sYUFBYSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzFCLG1CQUFtQixFQUFFLENBQUM7UUFFdEIsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBQUMsT0FBTyxHQUFHLEVBQUUsQ0FBQztRQUNiLE1BQU0sQ0FBQyxJQUFJLENBQUMsd0NBQXdDLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDM0QsT0FBTyxTQUFTLENBQUM7SUFDbkIsQ0FBQztBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIER5bmFtaWMgcG9ydCBhbGxvY2F0aW9uIGFuZCBwb3J0IGZpbGUgZGlzY292ZXJ5IGZvciB0aGUgd2ViIGNvbnNvbGUuXG4gKlxuICogV2hlbiBtdWx0aXBsZSBEb2xsaG91c2VNQ1Agc2Vzc2lvbnMgcnVuIHNpbXVsdGFuZW91c2x5IChlLmcuLCBtdWx0aXBsZVxuICogQ2xhdWRlIENvZGUgd2luZG93cywgSURFIGluc3RhbmNlcywgb3IgYWdlbnQgc2Vzc2lvbnMpLCBlYWNoIG5lZWRzIGl0c1xuICogb3duIHdlYiBjb25zb2xlIHBvcnQuIFRoaXMgbW9kdWxlIGhhbmRsZXM6XG4gKlxuICogMS4gRmluZGluZyBhbiBhdmFpbGFibGUgcG9ydCBzdGFydGluZyBmcm9tIHRoZSBjb25maWd1cmVkIGRlZmF1bHRcbiAqICAgIChzZWUgYERPTExIT1VTRV9XRUJfQ09OU09MRV9QT1JUYCBpbiBgc3JjL2NvbmZpZy9lbnYudHNgKVxuICogMi4gV3JpdGluZyBwb3J0IGRpc2NvdmVyeSBmaWxlcyBzbyBleHRlcm5hbCB0b29scyBrbm93IHdoaWNoIHBvcnQgdG8gdXNlXG4gKiAzLiBDbGVhbmluZyB1cCBwb3J0IGZpbGVzIG9uIHByb2Nlc3MgZXhpdFxuICpcbiAqIFBvcnQgZmlsZXMgYXJlIHdyaXR0ZW4gdG8gfi8uZG9sbGhvdXNlL3J1bi86XG4gKiAtIHBlcm1pc3Npb24tc2VydmVyLXtwaWR9LnBvcnQg4oCUIHBlci1wcm9jZXNzIGZpbGUgKGNsZWFuZWQgb24gZXhpdClcbiAqIC0gcGVybWlzc2lvbi1zZXJ2ZXIucG9ydCDigJQgbGF0ZXN0IHBvcnQgKGNvbnZlbmllbmNlIGZvciBzY3JpcHRzKVxuICovXG5cbmltcG9ydCB7IGNyZWF0ZVNlcnZlciwgdHlwZSBTZXJ2ZXIgfSBmcm9tICdub2RlOm5ldCc7XG5pbXBvcnQgeyBob21lZGlyIH0gZnJvbSAnbm9kZTpvcyc7XG5pbXBvcnQgeyBqb2luIH0gZnJvbSAnbm9kZTpwYXRoJztcbmltcG9ydCB7IG1rZGlyLCB3cml0ZUZpbGUsIHVubGluayB9IGZyb20gJ25vZGU6ZnMvcHJvbWlzZXMnO1xuaW1wb3J0IHsgZW52IH0gZnJvbSAnLi4vY29uZmlnL2Vudi5qcyc7XG5pbXBvcnQgeyBsb2dnZXIgfSBmcm9tICcuLi91dGlscy9sb2dnZXIuanMnO1xuXG4vKiogRGVmYXVsdCBtYXhpbXVtIHBvcnQgYXR0ZW1wdHMgYmVmb3JlIGdpdmluZyB1cCAqL1xuY29uc3QgREVGQVVMVF9NQVhfUE9SVF9BVFRFTVBUUyA9IDEwO1xuXG4vKiogRGlyZWN0b3J5IGZvciBydW50aW1lIHN0YXRlIGZpbGVzIChwb3J0IGRpc2NvdmVyeSwgUElEIGZpbGVzKSAqL1xuY29uc3QgUlVOX0RJUiA9IGpvaW4oaG9tZWRpcigpLCAnLmRvbGxob3VzZScsICdydW4nKTtcblxuLyoqIFRyYWNrIHBvcnQgZmlsZSBwYXRoIGZvciBjbGVhbnVwICovXG5sZXQgcG9ydEZpbGVQYXRoOiBzdHJpbmcgfCBudWxsID0gbnVsbDtcblxuLyoqXG4gKiBBdHRlbXB0IHRvIGJpbmQgdG8gYSBzaW5nbGUgcG9ydC4gUmV0dXJucyB0aGUgcG9ydCBpZiBzdWNjZXNzZnVsLCBudWxsIGlmIGluIHVzZS5cbiAqIEtlZXBzIHRoZSBzZXJ2ZXIgbGlzdGVuaW5nIHRvIHByZXZlbnQgVE9DVE9VIHJhY2UgY29uZGl0aW9ucyDigJQgY2FsbGVyIG11c3RcbiAqIGNsb3NlIHRoZSByZXR1cm5lZCBzZXJ2ZXIgYWZ0ZXIgdGhlaXIgb3duIHNlcnZlciBiaW5kcy5cbiAqL1xuZnVuY3Rpb24gdHJ5QmluZFBvcnQocG9ydDogbnVtYmVyKTogUHJvbWlzZTx7IHBvcnQ6IG51bWJlcjsgc2VydmVyOiBTZXJ2ZXIgfSB8IG51bGw+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgY29uc3Qgc2VydmVyID0gY3JlYXRlU2VydmVyKCk7XG4gICAgc2VydmVyLm9uY2UoJ2Vycm9yJywgKGVycjogTm9kZUpTLkVycm5vRXhjZXB0aW9uKSA9PiB7XG4gICAgICBpZiAoZXJyLmNvZGUgPT09ICdFQUREUklOVVNFJykge1xuICAgICAgICByZXNvbHZlKG51bGwpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzb2x2ZShudWxsKTtcbiAgICAgICAgbG9nZ2VyLmRlYnVnKGBbUG9ydERpc2NvdmVyeV0gVW5leHBlY3RlZCBlcnJvciBvbiBwb3J0ICR7cG9ydH06ICR7ZXJyLmNvZGV9YCk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgc2VydmVyLm9uY2UoJ2xpc3RlbmluZycsICgpID0+IHtcbiAgICAgIHJlc29sdmUoeyBwb3J0LCBzZXJ2ZXIgfSk7XG4gICAgfSk7XG4gICAgc2VydmVyLmxpc3Rlbihwb3J0LCAnMTI3LjAuMC4xJyk7XG4gIH0pO1xufVxuXG4vKipcbiAqIEZpbmQgYW4gYXZhaWxhYmxlIHBvcnQgc3RhcnRpbmcgZnJvbSB0aGUgZ2l2ZW4gcG9ydC5cbiAqXG4gKiBUcmllcyBzZXF1ZW50aWFsIHBvcnRzLCBsb2dnaW5nIGVhY2ggYXR0ZW1wdC4gUmV0dXJucyBib3RoIHRoZSBwb3J0IG51bWJlclxuICogYW5kIGEgaGVsZCBzZXJ2ZXIgdG8gcHJldmVudCBUT0NUT1UgcmFjZSBjb25kaXRpb25zLiBUaGUgY2FsbGVyIHNob3VsZFxuICogY2xvc2UgdGhlIGhlbGQgc2VydmVyIGFmdGVyIGJpbmRpbmcgdGhlaXIgb3duIEV4cHJlc3MgYXBwIHRvIHRoZSBwb3J0LlxuICpcbiAqIEBwYXJhbSBzdGFydFBvcnQgLSBQb3J0IHRvIHRyeSBmaXJzdCAoc2VlIGBET0xMSE9VU0VfV0VCX0NPTlNPTEVfUE9SVGAgZm9yIHRoZSBkZWZhdWx0KVxuICogQHBhcmFtIG1heEF0dGVtcHRzIC0gTWF4aW11bSBwb3J0cyB0byB0cnkgKGRlZmF1bHQ6IDEwLCBjb25maWd1cmFibGUgdmlhIERPTExIT1VTRV9NQVhfUE9SVF9BVFRFTVBUUylcbiAqIEByZXR1cm5zIE9iamVjdCB3aXRoIHBvcnQgbnVtYmVyIGFuZCBoZWxkIHNlcnZlciwgb3IgdGhyb3dzIGlmIGFsbCBhdHRlbXB0cyBmYWlsXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBmaW5kQXZhaWxhYmxlUG9ydChcbiAgc3RhcnRQb3J0OiBudW1iZXIsXG4gIG1heEF0dGVtcHRzOiBudW1iZXIgPSBOdW1iZXIocHJvY2Vzcy5lbnYuRE9MTEhPVVNFX01BWF9QT1JUX0FUVEVNUFRTKSB8fCBERUZBVUxUX01BWF9QT1JUX0FUVEVNUFRTLFxuKTogUHJvbWlzZTxudW1iZXI+IHtcbiAgZm9yIChsZXQgYXR0ZW1wdCA9IDA7IGF0dGVtcHQgPCBtYXhBdHRlbXB0czsgYXR0ZW1wdCsrKSB7XG4gICAgY29uc3QgcG9ydCA9IHN0YXJ0UG9ydCArIGF0dGVtcHQ7XG4gICAgbG9nZ2VyLmRlYnVnKGBbUG9ydERpc2NvdmVyeV0gVHJ5aW5nIHBvcnQgJHtwb3J0fSAoYXR0ZW1wdCAke2F0dGVtcHQgKyAxfS8ke21heEF0dGVtcHRzfSlgKTtcblxuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRyeUJpbmRQb3J0KHBvcnQpO1xuICAgIGlmIChyZXN1bHQpIHtcbiAgICAgIC8vIENsb3NlIHRoZSBwcm9iZSBzZXJ2ZXIg4oCUIHRoZXJlJ3MgYSBicmllZiBUT0NUT1Ugd2luZG93IGhlcmUgYmV0d2VlblxuICAgICAgLy8gY2xvc2luZyBhbmQgdGhlIGNhbGxlciBiaW5kaW5nLCBidXQgaXQncyBuZWdsaWdpYmxlIG9uIGxvY2FsaG9zdC5cbiAgICAgIC8vIEEgZnV0dXJlIGltcHJvdmVtZW50IGNvdWxkIHJldHVybiB0aGUgc2VydmVyIGZvciB0aGUgY2FsbGVyIHRvIGFkb3B0LlxuICAgICAgcmVzdWx0LnNlcnZlci5jbG9zZSgpO1xuICAgICAgaWYgKGF0dGVtcHQgPiAwKSB7XG4gICAgICAgIGxvZ2dlci5pbmZvKGBbUG9ydERpc2NvdmVyeV0gUG9ydCAke3N0YXJ0UG9ydH0gaW4gdXNlLCB1c2luZyAke3BvcnR9IChhZnRlciAke2F0dGVtcHR9IHNraXAke2F0dGVtcHQgPiAxID8gJ3MnIDogJyd9KWApO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHBvcnQ7XG4gICAgfVxuICAgIGxvZ2dlci5kZWJ1ZyhgW1BvcnREaXNjb3ZlcnldIFBvcnQgJHtwb3J0fSBpbiB1c2UsIHRyeWluZyBuZXh0YCk7XG4gIH1cblxuICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgYE5vIGF2YWlsYWJsZSBwb3J0IGZvdW5kIGluIHJhbmdlICR7c3RhcnRQb3J0fS0ke3N0YXJ0UG9ydCArIG1heEF0dGVtcHRzIC0gMX0gYCArXG4gICAgYGFmdGVyICR7bWF4QXR0ZW1wdHN9IGF0dGVtcHRzLiBTZXQgRE9MTEhPVVNFX01BWF9QT1JUX0FUVEVNUFRTIHRvIGluY3JlYXNlIHRoZSByYW5nZS5gXG4gICk7XG59XG5cbi8qKlxuICogV3JpdGUgdGhlIGFjdGl2ZSBzZXJ2ZXIgcG9ydCB0byBhIGRpc2NvdmVyYWJsZSBmaWxlLlxuICpcbiAqIENyZWF0ZXMgdHdvIGZpbGVzOlxuICogLSBQSUQta2V5ZWQgZmlsZSBmb3IgcGVyLXByb2Nlc3MgY2xlYW51cFxuICogLSBMYXRlc3QgZmlsZSBmb3IgY29udmVuaWVuY2UgKHNjcmlwdHMgY2FuIHJlYWQgdGhpcyB3aXRob3V0IGtub3dpbmcgdGhlIFBJRClcbiAqXG4gKiBAcGFyYW0gcG9ydCAtIFRoZSBwb3J0IHRoZSB3ZWIgc2VydmVyIGlzIGxpc3RlbmluZyBvblxuICogQHJldHVybnMgUGF0aCB0byB0aGUgUElELWtleWVkIHBvcnQgZmlsZVxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gd3JpdGVQb3J0RmlsZShwb3J0OiBudW1iZXIpOiBQcm9taXNlPHN0cmluZz4ge1xuICBhd2FpdCBta2RpcihSVU5fRElSLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgY29uc3QgcGlkRmlsZSA9IGpvaW4oUlVOX0RJUiwgYHBlcm1pc3Npb24tc2VydmVyLSR7cHJvY2Vzcy5waWR9LnBvcnRgKTtcbiAgY29uc3QgbGF0ZXN0RmlsZSA9IGpvaW4oUlVOX0RJUiwgJ3Blcm1pc3Npb24tc2VydmVyLnBvcnQnKTtcbiAgYXdhaXQgd3JpdGVGaWxlKHBpZEZpbGUsIFN0cmluZyhwb3J0KSwgJ3V0Zi04Jyk7XG4gIGF3YWl0IHdyaXRlRmlsZShsYXRlc3RGaWxlLCBTdHJpbmcocG9ydCksICd1dGYtOCcpO1xuICBwb3J0RmlsZVBhdGggPSBwaWRGaWxlO1xuICBsb2dnZXIuZGVidWcoYFtQb3J0RGlzY292ZXJ5XSBQb3J0IGZpbGUgd3JpdHRlbjogJHtwaWRGaWxlfWApO1xuICByZXR1cm4gcGlkRmlsZTtcbn1cblxuLyoqXG4gKiBDbGVhbiB1cCBwb3J0IGZpbGUgb24gc2h1dGRvd24uXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjbGVhbnVwUG9ydEZpbGUoKTogUHJvbWlzZTx2b2lkPiB7XG4gIGlmIChwb3J0RmlsZVBhdGgpIHtcbiAgICB0cnkgeyBhd2FpdCB1bmxpbmsocG9ydEZpbGVQYXRoKTsgfSBjYXRjaCB7IC8qIGFscmVhZHkgZ29uZSAqLyB9XG4gIH1cbn1cblxuLyoqXG4gKiBSZWdpc3RlciBwcm9jZXNzIGV4aXQgaGFuZGxlcnMgdG8gY2xlYW4gdXAgcG9ydCBmaWxlcy5cbiAqIFNob3VsZCBiZSBjYWxsZWQgb25jZSBhZnRlciB0aGUgd2ViIHNlcnZlciBzdWNjZXNzZnVsbHkgc3RhcnRzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVnaXN0ZXJQb3J0Q2xlYW51cCgpOiB2b2lkIHtcbiAgY29uc3QgZXhpdENsZWFudXAgPSAoKSA9PiB7IGNsZWFudXBQb3J0RmlsZSgpLmNhdGNoKCgpID0+IHt9KTsgfTtcbiAgcHJvY2Vzcy5vbmNlKCdleGl0JywgZXhpdENsZWFudXApO1xuICBwcm9jZXNzLm9uY2UoJ1NJR1RFUk0nLCBleGl0Q2xlYW51cCk7XG4gIHByb2Nlc3Mub25jZSgnU0lHSU5UJywgZXhpdENsZWFudXApO1xufVxuXG4vKipcbiAqIERpc2NvdmVyIGFuIGF2YWlsYWJsZSBwb3J0LCB3cml0ZSBkaXNjb3ZlcnkgZmlsZXMsIGFuZCByZWdpc3RlciBjbGVhbnVwLlxuICpcbiAqIFRoaXMgaXMgdGhlIHJlY29tbWVuZGVkIGVudHJ5IHBvaW50IGZvciBDb250YWluZXIgc3RhcnR1cC4gQ29tYmluZXNcbiAqIHBvcnQgZGlzY292ZXJ5LCBmaWxlIHdyaXRpbmcsIGFuZCBjbGVhbnVwIHJlZ2lzdHJhdGlvbiBpbiBvbmUgY2FsbC5cbiAqXG4gKiBAcGFyYW0gZGVmYXVsdFBvcnQgLSBQb3J0IHRvIHRyeSBmaXJzdCAoc2VlIGBET0xMSE9VU0VfV0VCX0NPTlNPTEVfUE9SVGAgZm9yIHRoZSBkZWZhdWx0KVxuICogQHJldHVybnMgVGhlIHBvcnQgdGhlIHNlcnZlciBzaG91bGQgYmluZCB0bywgb3IgdW5kZWZpbmVkIGlmIGRpc2NvdmVyeSBmYWlsZWRcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGRpc2NvdmVyQW5kQmluZFBvcnQoXG4gIGRlZmF1bHRQb3J0OiBudW1iZXIgPSBlbnYuRE9MTEhPVVNFX1dFQl9DT05TT0xFX1BPUlQsXG4pOiBQcm9taXNlPG51bWJlciB8IHVuZGVmaW5lZD4ge1xuICB0cnkge1xuICAgIGNvbnN0IHBvcnQgPSBhd2FpdCBmaW5kQXZhaWxhYmxlUG9ydChkZWZhdWx0UG9ydCk7XG5cbiAgICBhd2FpdCB3cml0ZVBvcnRGaWxlKHBvcnQpO1xuICAgIHJlZ2lzdGVyUG9ydENsZWFudXAoKTtcblxuICAgIHJldHVybiBwb3J0O1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICBsb2dnZXIud2FybignW1BvcnREaXNjb3ZlcnldIFBvcnQgZGlzY292ZXJ5IGZhaWxlZDonLCBlcnIpO1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbn1cbiJdfQ==
|
package/dist/web/public/app.js
CHANGED
|
@@ -96,7 +96,7 @@ function safeParseYaml(content) {
|
|
|
96
96
|
showGridMessage('loading', 'Loading portfolio…');
|
|
97
97
|
|
|
98
98
|
// Load portfolio from local API
|
|
99
|
-
const portfolioRes = await
|
|
99
|
+
const portfolioRes = await DollhouseAuth.apiFetch('/api/elements');
|
|
100
100
|
if (!portfolioRes.ok) throw new Error(`HTTP ${portfolioRes.status} fetching portfolio`);
|
|
101
101
|
const portfolioData = await portfolioRes.json();
|
|
102
102
|
|
|
@@ -116,7 +116,7 @@ function safeParseYaml(content) {
|
|
|
116
116
|
applyFilters();
|
|
117
117
|
|
|
118
118
|
// Load community collection (non-blocking — portfolio shows immediately)
|
|
119
|
-
|
|
119
|
+
DollhouseAuth.apiFetch('/api/collection')
|
|
120
120
|
.then(r => r.ok ? r.json() : Promise.reject('not available'))
|
|
121
121
|
.then(mergeCollectionData)
|
|
122
122
|
.catch(() => { /* collection not available — portfolio-only mode */ });
|
|
@@ -537,7 +537,7 @@ function safeParseYaml(content) {
|
|
|
537
537
|
if (el._content) {
|
|
538
538
|
content = el._content;
|
|
539
539
|
} else if (el._local) {
|
|
540
|
-
const res = await
|
|
540
|
+
const res = await DollhouseAuth.apiFetch(`/api/elements/${el.path}`);
|
|
541
541
|
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
542
542
|
content = await res.text();
|
|
543
543
|
} else {
|
|
@@ -630,7 +630,7 @@ function safeParseYaml(content) {
|
|
|
630
630
|
btn.textContent = '⏳ Installing…';
|
|
631
631
|
btn.disabled = true;
|
|
632
632
|
try {
|
|
633
|
-
const res = await
|
|
633
|
+
const res = await DollhouseAuth.apiFetch('/api/install', {
|
|
634
634
|
method: 'POST',
|
|
635
635
|
headers: { 'Content-Type': 'application/json' },
|
|
636
636
|
body: JSON.stringify({ path: element.path, name: element.name, type: element.type }),
|
|
@@ -726,13 +726,13 @@ function safeParseYaml(content) {
|
|
|
726
726
|
if (element._content) {
|
|
727
727
|
content = element._content;
|
|
728
728
|
} else if (element._local) {
|
|
729
|
-
const res = await
|
|
729
|
+
const res = await DollhouseAuth.apiFetch(`/api/elements/${element.path}`);
|
|
730
730
|
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
731
731
|
const data = await res.json();
|
|
732
732
|
structured = data;
|
|
733
733
|
content = data.raw;
|
|
734
734
|
} else {
|
|
735
|
-
const res = await
|
|
735
|
+
const res = await DollhouseAuth.apiFetch(`/api/collection/content/${element.path}`);
|
|
736
736
|
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
737
737
|
const data = await res.json();
|
|
738
738
|
structured = data;
|
|
@@ -1931,7 +1931,7 @@ function safeParseYaml(content) {
|
|
|
1931
1931
|
|
|
1932
1932
|
// ── Tab switching ─────────────────────────────────────────────────────────
|
|
1933
1933
|
const consoleTabs = document.getElementById('console-tabs');
|
|
1934
|
-
const tabInits = { logs: false, metrics: false, permissions: false };
|
|
1934
|
+
const tabInits = { logs: false, metrics: false, permissions: false, security: false };
|
|
1935
1935
|
|
|
1936
1936
|
const TAB_KEY = 'dollhousemcp-active-tab';
|
|
1937
1937
|
const SETUP_SEEN_KEY = 'dollhousemcp-setup-seen';
|
|
@@ -2069,6 +2069,7 @@ function safeParseYaml(content) {
|
|
|
2069
2069
|
const savedTab = localStorage.getItem(TAB_KEY);
|
|
2070
2070
|
if (savedTab) {
|
|
2071
2071
|
switchToTab(savedTab);
|
|
2072
|
+
lazyInitTab(savedTab, tabInits);
|
|
2072
2073
|
} else if (!localStorage.getItem(SETUP_SEEN_KEY)) {
|
|
2073
2074
|
localStorage.setItem(SETUP_SEEN_KEY, '1');
|
|
2074
2075
|
switchToTab('setup');
|
|
@@ -2094,20 +2095,36 @@ function safeParseYaml(content) {
|
|
|
2094
2095
|
|
|
2095
2096
|
function lazyInitTab(tab, tabInits, params) {
|
|
2096
2097
|
const dc = globalThis.DollhouseConsole;
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
}
|
|
2105
|
-
if (tab === 'permissions' && dc?.permissions) {
|
|
2106
|
-
if (!tabInits.permissions) { tabInits.permissions = true; dc.permissions.init(params); }
|
|
2107
|
-
else if (dc.permissions.refresh) { dc.permissions.refresh(); }
|
|
2098
|
+
const module = dc?.[tab];
|
|
2099
|
+
if (!module) return;
|
|
2100
|
+
if (!tabInits[tab]) {
|
|
2101
|
+
tabInits[tab] = true;
|
|
2102
|
+
module.init(params);
|
|
2103
|
+
} else if (module.refresh) {
|
|
2104
|
+
module.refresh();
|
|
2108
2105
|
}
|
|
2109
2106
|
}
|
|
2110
2107
|
|
|
2108
|
+
// 401 recovery (#1792): when the cached token becomes stale (rotation,
|
|
2109
|
+
// restart, file deletion), consoleAuth.js fires this event. Show a
|
|
2110
|
+
// persistent, idempotent reload banner so the user knows why the UI
|
|
2111
|
+
// stopped updating.
|
|
2112
|
+
globalThis.addEventListener('dollhouse:session-expired', function () {
|
|
2113
|
+
if (document.getElementById('session-expired-toast')) return;
|
|
2114
|
+
const toast = document.createElement('div');
|
|
2115
|
+
toast.id = 'session-expired-toast';
|
|
2116
|
+
toast.setAttribute('role', 'alert');
|
|
2117
|
+
toast.style.cssText = 'position:fixed;bottom:24px;left:50%;transform:translateX(-50%);'
|
|
2118
|
+
+ 'background:#b91c1c;color:#fff;padding:12px 24px;border-radius:8px;'
|
|
2119
|
+
+ 'font-size:14px;z-index:99999;display:flex;align-items:center;gap:12px;'
|
|
2120
|
+
+ 'box-shadow:0 4px 12px rgba(0,0,0,0.3);';
|
|
2121
|
+
toast.innerHTML = 'Console session token changed\u2009\u2014\u2009'
|
|
2122
|
+
+ '<button style="background:#fff;color:#b91c1c;border:none;padding:6px 16px;'
|
|
2123
|
+
+ 'border-radius:4px;cursor:pointer;font-weight:600;font-size:14px"'
|
|
2124
|
+
+ ' onclick="location.reload()">Reload</button>';
|
|
2125
|
+
document.body.appendChild(toast);
|
|
2126
|
+
});
|
|
2127
|
+
|
|
2111
2128
|
init();
|
|
2112
2129
|
});
|
|
2113
2130
|
|