@dollhousemcp/mcp-server 2.0.18 → 2.0.20
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 +8 -0
- package/dist/generated/version.d.ts +2 -2
- package/dist/generated/version.js +3 -3
- package/dist/handlers/ElementCRUDHandler.d.ts +30 -0
- package/dist/handlers/ElementCRUDHandler.d.ts.map +1 -1
- package/dist/handlers/ElementCRUDHandler.js +141 -2
- package/dist/handlers/mcp-aql/MCPAQLHandler.d.ts +3 -0
- package/dist/handlers/mcp-aql/MCPAQLHandler.d.ts.map +1 -1
- package/dist/handlers/mcp-aql/MCPAQLHandler.js +98 -1
- package/dist/handlers/mcp-aql/OperationRouter.d.ts.map +1 -1
- package/dist/handlers/mcp-aql/OperationRouter.js +6 -1
- package/dist/handlers/mcp-aql/OperationSchema.d.ts.map +1 -1
- package/dist/handlers/mcp-aql/OperationSchema.js +17 -1
- package/dist/handlers/mcp-aql/policies/AgentToolPolicyTranslator.d.ts.map +1 -1
- package/dist/handlers/mcp-aql/policies/AgentToolPolicyTranslator.js +2 -1
- package/dist/handlers/mcp-aql/policies/ElementPolicies.d.ts.map +1 -1
- package/dist/handlers/mcp-aql/policies/ElementPolicies.js +2 -1
- package/dist/handlers/mcp-aql/policies/OperationPolicies.d.ts.map +1 -1
- package/dist/handlers/mcp-aql/policies/OperationPolicies.js +6 -1
- package/dist/handlers/mcp-aql/policies/ToolClassification.d.ts.map +1 -1
- package/dist/handlers/mcp-aql/policies/ToolClassification.js +2 -1
- package/dist/server/tools/MCPAQLTools.js +2 -1
- package/dist/web/console/IngestRoutes.d.ts +6 -0
- package/dist/web/console/IngestRoutes.d.ts.map +1 -1
- package/dist/web/console/IngestRoutes.js +38 -9
- package/dist/web/console/LeaderElection.d.ts +39 -0
- package/dist/web/console/LeaderElection.d.ts.map +1 -1
- package/dist/web/console/LeaderElection.js +147 -29
- package/dist/web/console/LeaderForwardingSink.d.ts.map +1 -1
- package/dist/web/console/LeaderForwardingSink.js +5 -1
- package/dist/web/console/PromotionManager.d.ts.map +1 -1
- package/dist/web/console/PromotionManager.js +3 -11
- package/dist/web/console/StaleProcessRecovery.d.ts +11 -0
- package/dist/web/console/StaleProcessRecovery.d.ts.map +1 -1
- package/dist/web/console/StaleProcessRecovery.js +229 -63
- package/dist/web/console/UnifiedConsole.d.ts +22 -1
- package/dist/web/console/UnifiedConsole.d.ts.map +1 -1
- package/dist/web/console/UnifiedConsole.js +172 -11
- package/dist/web/public/app.js +62 -1
- package/dist/web/public/index.html +19 -17
- package/dist/web/public/sessions.js +111 -0
- package/dist/web/server.d.ts.map +1 -1
- package/dist/web/server.js +12 -10
- package/package.json +1 -1
- package/server.json +2 -2
|
@@ -12,12 +12,14 @@
|
|
|
12
12
|
*
|
|
13
13
|
* @since v2.1.0 — Issue #1700
|
|
14
14
|
*/
|
|
15
|
+
import { UnicodeValidator } from '../../security/validators/unicodeValidator.js';
|
|
15
16
|
import { logger } from '../../utils/logger.js';
|
|
16
|
-
import { electLeader, isLeaderWebConsoleReachable, forceClaimLeadership, startHeartbeat, registerLeaderCleanup, detectLegacyLeader, } from './LeaderElection.js';
|
|
17
|
+
import { electLeader, isLeaderWebConsoleReachable, forceClaimLeadership, startHeartbeat, registerLeaderCleanup, detectLegacyLeader, readLeaderLock, deleteLeaderLock, LOCK_VERSION, CONSOLE_PROTOCOL_VERSION, LEGACY_SERVER_VERSION, } from './LeaderElection.js';
|
|
17
18
|
import { createIngestRoutes } from './IngestRoutes.js';
|
|
18
19
|
import { LeaderForwardingLogSink, SessionHeartbeat, } from './LeaderForwardingSink.js';
|
|
19
20
|
import { PromotionManager } from './PromotionManager.js';
|
|
20
21
|
import { ConsoleTokenStore } from './consoleToken.js';
|
|
22
|
+
import { findPidOnPort } from './StaleProcessRecovery.js';
|
|
21
23
|
import { env } from '../../config/env.js';
|
|
22
24
|
/**
|
|
23
25
|
* Default console port from the env var. Used as fallback when no port
|
|
@@ -27,6 +29,11 @@ import { env } from '../../config/env.js';
|
|
|
27
29
|
* 3. 41715 (hardcoded default in env.ts)
|
|
28
30
|
*/
|
|
29
31
|
const DEFAULT_CONSOLE_PORT = env.DOLLHOUSE_WEB_CONSOLE_PORT;
|
|
32
|
+
const LEGACY_CONSOLE_FALLBACK_PORT = 3939;
|
|
33
|
+
const SYNTHETIC_PORT_OWNER_SESSION_PREFIX = 'port-owner-';
|
|
34
|
+
function currentTimestamp() {
|
|
35
|
+
return new Date().toISOString();
|
|
36
|
+
}
|
|
30
37
|
/**
|
|
31
38
|
* Check for a running legacy (pre-authentication) DollhouseMCP console and
|
|
32
39
|
* log a WARN-level message if one is found (#1794).
|
|
@@ -56,7 +63,7 @@ export async function warnIfLegacyConsolePresent(currentPort, detect = detectLeg
|
|
|
56
63
|
`(pid=${legacy.pid}, port=${legacy.port}). Both consoles will run ` +
|
|
57
64
|
`independently on different ports with different security posture. ` +
|
|
58
65
|
`The authenticated console (this process) uses port ${currentPort}; ` +
|
|
59
|
-
`the legacy console uses port ${legacy.port ??
|
|
66
|
+
`the legacy console uses port ${legacy.port ?? LEGACY_CONSOLE_FALLBACK_PORT}. ` +
|
|
60
67
|
`For consistent security, update the legacy installation to a ` +
|
|
61
68
|
`version with the authenticated console.`);
|
|
62
69
|
}
|
|
@@ -70,6 +77,135 @@ export async function warnIfLegacyConsolePresent(currentPort, detect = detectLeg
|
|
|
70
77
|
return null;
|
|
71
78
|
}
|
|
72
79
|
}
|
|
80
|
+
function buildDiscoveryHeaders(authToken) {
|
|
81
|
+
return authToken ? { Authorization: `Bearer ${authToken}` } : {};
|
|
82
|
+
}
|
|
83
|
+
function buildLeaderInfoFromSession(port, ownerPid, leaderSession) {
|
|
84
|
+
return {
|
|
85
|
+
version: LOCK_VERSION,
|
|
86
|
+
pid: ownerPid,
|
|
87
|
+
port,
|
|
88
|
+
sessionId: UnicodeValidator.normalize(leaderSession.sessionId).normalizedContent,
|
|
89
|
+
startedAt: leaderSession.startedAt ?? currentTimestamp(),
|
|
90
|
+
heartbeat: leaderSession.lastHeartbeat ?? currentTimestamp(),
|
|
91
|
+
serverVersion: leaderSession.serverVersion ?? LEGACY_SERVER_VERSION,
|
|
92
|
+
consoleProtocolVersion: leaderSession.consoleProtocolVersion ?? CONSOLE_PROTOCOL_VERSION,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
function buildSyntheticLeaderInfo(port, ownerPid) {
|
|
96
|
+
const now = currentTimestamp();
|
|
97
|
+
return {
|
|
98
|
+
version: LOCK_VERSION,
|
|
99
|
+
pid: ownerPid,
|
|
100
|
+
port,
|
|
101
|
+
sessionId: `${SYNTHETIC_PORT_OWNER_SESSION_PREFIX}${ownerPid}`,
|
|
102
|
+
startedAt: now,
|
|
103
|
+
heartbeat: now,
|
|
104
|
+
serverVersion: LEGACY_SERVER_VERSION,
|
|
105
|
+
consoleProtocolVersion: CONSOLE_PROTOCOL_VERSION,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
async function discoverLeaderViaSessionsApi(port, ownerPid, authToken, fetchImpl) {
|
|
109
|
+
const response = await fetchImpl(`http://127.0.0.1:${port}/api/sessions`, {
|
|
110
|
+
headers: buildDiscoveryHeaders(authToken),
|
|
111
|
+
});
|
|
112
|
+
if (!response.ok) {
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
const payload = await response.json();
|
|
116
|
+
const sessions = Array.isArray(payload.sessions) ? payload.sessions : [];
|
|
117
|
+
const leaderSession = sessions.find((session) => session.pid === ownerPid &&
|
|
118
|
+
session.isLeader === true &&
|
|
119
|
+
session.kind === 'mcp' &&
|
|
120
|
+
session.status !== 'stopped');
|
|
121
|
+
return leaderSession ? buildLeaderInfoFromSession(port, ownerPid, leaderSession) : null;
|
|
122
|
+
}
|
|
123
|
+
export async function discoverLeaderServingPort(port, authToken, deps = {}) {
|
|
124
|
+
const fetchImpl = deps.fetchImpl ?? fetch;
|
|
125
|
+
const findPidOnPortImpl = deps.findPidOnPortImpl ?? findPidOnPort;
|
|
126
|
+
const readLeaderLockImpl = deps.readLeaderLockImpl ?? readLeaderLock;
|
|
127
|
+
const ownerPid = await findPidOnPortImpl(port);
|
|
128
|
+
if (ownerPid !== null) {
|
|
129
|
+
try {
|
|
130
|
+
const leaderInfo = await discoverLeaderViaSessionsApi(port, ownerPid, authToken, fetchImpl);
|
|
131
|
+
if (leaderInfo) {
|
|
132
|
+
return { ownerPid, source: 'api', leaderInfo };
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
catch (err) {
|
|
136
|
+
logger.debug('[UnifiedConsole] Failed to query active leader sessions', {
|
|
137
|
+
port,
|
|
138
|
+
ownerPid,
|
|
139
|
+
error: err instanceof Error ? err.message : String(err),
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
const lock = await readLeaderLockImpl();
|
|
144
|
+
if (lock?.port === port && (ownerPid === null || lock.pid === ownerPid)) {
|
|
145
|
+
return {
|
|
146
|
+
ownerPid: ownerPid ?? lock.pid,
|
|
147
|
+
source: 'lock',
|
|
148
|
+
leaderInfo: {
|
|
149
|
+
...lock,
|
|
150
|
+
sessionId: UnicodeValidator.normalize(lock.sessionId).normalizedContent,
|
|
151
|
+
},
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
if (ownerPid !== null) {
|
|
155
|
+
return {
|
|
156
|
+
ownerPid,
|
|
157
|
+
source: 'synthetic',
|
|
158
|
+
leaderInfo: buildSyntheticLeaderInfo(port, ownerPid),
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
return { leaderInfo: null, ownerPid: null, source: 'none' };
|
|
162
|
+
}
|
|
163
|
+
export async function recoverLeaderBindFailure(provisionalLeader, port, authToken, deps = {}) {
|
|
164
|
+
const readLeaderLockImpl = deps.readLeaderLockImpl ?? readLeaderLock;
|
|
165
|
+
const deleteLeaderLockImpl = deps.deleteLeaderLockImpl ?? deleteLeaderLock;
|
|
166
|
+
logger.info('[UnifiedConsole] Leader bind recovery initiated', {
|
|
167
|
+
provisionalSessionId: provisionalLeader.sessionId,
|
|
168
|
+
provisionalPid: provisionalLeader.pid,
|
|
169
|
+
port,
|
|
170
|
+
});
|
|
171
|
+
let fallback = await discoverLeaderServingPort(port, authToken, deps);
|
|
172
|
+
let lockCleanupAttempted = false;
|
|
173
|
+
let lockCleanupPerformed = false;
|
|
174
|
+
const currentLock = await readLeaderLockImpl();
|
|
175
|
+
const provisionalLockMatches = (currentLock?.pid === provisionalLeader.pid &&
|
|
176
|
+
currentLock.port === provisionalLeader.port &&
|
|
177
|
+
currentLock.sessionId === provisionalLeader.sessionId);
|
|
178
|
+
const fallbackPointsToProvisionalLeader = (fallback.leaderInfo?.pid === provisionalLeader.pid &&
|
|
179
|
+
fallback.leaderInfo.port === provisionalLeader.port &&
|
|
180
|
+
fallback.leaderInfo.sessionId === provisionalLeader.sessionId);
|
|
181
|
+
if (provisionalLockMatches) {
|
|
182
|
+
lockCleanupAttempted = true;
|
|
183
|
+
await deleteLeaderLockImpl();
|
|
184
|
+
lockCleanupPerformed = true;
|
|
185
|
+
logger.info('[UnifiedConsole] Removed provisional leader lock after bind failure', {
|
|
186
|
+
provisionalSessionId: provisionalLeader.sessionId,
|
|
187
|
+
provisionalPid: provisionalLeader.pid,
|
|
188
|
+
port,
|
|
189
|
+
});
|
|
190
|
+
if (fallbackPointsToProvisionalLeader) {
|
|
191
|
+
fallback = await discoverLeaderServingPort(port, authToken, deps);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
logger.info('[UnifiedConsole] Leader bind recovery completed', {
|
|
195
|
+
provisionalSessionId: provisionalLeader.sessionId,
|
|
196
|
+
provisionalPid: provisionalLeader.pid,
|
|
197
|
+
port,
|
|
198
|
+
discoverySource: fallback.source,
|
|
199
|
+
ownerPid: fallback.ownerPid,
|
|
200
|
+
lockCleanupAttempted,
|
|
201
|
+
lockCleanupPerformed,
|
|
202
|
+
});
|
|
203
|
+
return {
|
|
204
|
+
...fallback,
|
|
205
|
+
lockCleanupAttempted,
|
|
206
|
+
lockCleanupPerformed,
|
|
207
|
+
};
|
|
208
|
+
}
|
|
73
209
|
/**
|
|
74
210
|
* Start the unified web console.
|
|
75
211
|
*
|
|
@@ -134,10 +270,6 @@ async function startAsLeader(options, election, consolePort = DEFAULT_CONSOLE_PO
|
|
|
134
270
|
metricsOnSnapshot: (snapshot) => liveMetricsOnSnapshot?.(snapshot),
|
|
135
271
|
storeMetricsSnapshot: (snapshot) => options.metricsSink?.onSnapshot(snapshot),
|
|
136
272
|
});
|
|
137
|
-
// Register the leader as a session
|
|
138
|
-
ingestResult.registerLeaderSession(options.sessionId, process.pid);
|
|
139
|
-
// Register the web console itself so the session indicator is never empty (#1805)
|
|
140
|
-
ingestResult.registerConsoleSession();
|
|
141
273
|
// Start the web server with ingest routes mounted before the SPA fallback.
|
|
142
274
|
// If the port is occupied by a stale process, retry with exponential backoff.
|
|
143
275
|
const serverOpts = {
|
|
@@ -153,8 +285,34 @@ async function startAsLeader(options, election, consolePort = DEFAULT_CONSOLE_PO
|
|
|
153
285
|
// process on the port, then retrying. No external retry loop needed.
|
|
154
286
|
const webResult = await startWebServer(serverOpts);
|
|
155
287
|
if (webResult.bindResult && !webResult.bindResult.success) {
|
|
156
|
-
|
|
288
|
+
const fallback = await recoverLeaderBindFailure(election.leaderInfo, consolePort, primaryToken.token);
|
|
289
|
+
if (fallback.leaderInfo) {
|
|
290
|
+
logger.warn('[UnifiedConsole] Leader role aborted: bind failed, falling back to follower', {
|
|
291
|
+
port: consolePort,
|
|
292
|
+
bindError: webResult.bindResult.error,
|
|
293
|
+
bindDetail: webResult.bindResult.detail,
|
|
294
|
+
provisionalLeaderPid: election.leaderInfo.pid,
|
|
295
|
+
provisionalLeaderSessionId: election.leaderInfo.sessionId,
|
|
296
|
+
ownerPid: fallback.ownerPid,
|
|
297
|
+
source: fallback.source,
|
|
298
|
+
lockCleanupAttempted: fallback.lockCleanupAttempted,
|
|
299
|
+
lockCleanupPerformed: fallback.lockCleanupPerformed,
|
|
300
|
+
});
|
|
301
|
+
const followerElection = { role: 'follower', leaderInfo: fallback.leaderInfo };
|
|
302
|
+
return startAsFollower(options, followerElection, consolePort, primaryToken.token);
|
|
303
|
+
}
|
|
304
|
+
logger.error('[UnifiedConsole] Leader failed to bind and no active leader could be identified', {
|
|
305
|
+
port: consolePort,
|
|
306
|
+
provisionalLeaderPid: election.leaderInfo.pid,
|
|
307
|
+
bindError: webResult.bindResult.error,
|
|
308
|
+
bindDetail: webResult.bindResult.detail,
|
|
309
|
+
});
|
|
310
|
+
throw new Error(`Leader failed to bind port ${consolePort} and no active leader was discoverable`);
|
|
157
311
|
}
|
|
312
|
+
// Register the leader only after the HTTP listener is actually serving the port.
|
|
313
|
+
ingestResult.registerLeaderSession(options.sessionId, process.pid);
|
|
314
|
+
// Register the web console itself so the session indicator is never empty (#1805)
|
|
315
|
+
ingestResult.registerConsoleSession();
|
|
158
316
|
// Wire SSE broadcasts for this leader's own events
|
|
159
317
|
options.wireSSEBroadcasts(webResult, options.metricsSink);
|
|
160
318
|
// Now wire the live broadcast functions into the ingest routes
|
|
@@ -191,13 +349,16 @@ async function startAsLeader(options, election, consolePort = DEFAULT_CONSOLE_PO
|
|
|
191
349
|
* Start as a follower.
|
|
192
350
|
* Registers forwarding sinks with the LogManager, starts session heartbeat.
|
|
193
351
|
*/
|
|
194
|
-
async function startAsFollower(options, election, consolePort = DEFAULT_CONSOLE_PORT) {
|
|
352
|
+
async function startAsFollower(options, election, consolePort = DEFAULT_CONSOLE_PORT, initialAuthToken = null) {
|
|
195
353
|
const leaderUrl = `http://127.0.0.1:${election.leaderInfo.port}`;
|
|
196
354
|
// Read the console auth token (#1780) written by the leader. May be null
|
|
197
355
|
// if the file doesn't exist yet — the sinks handle that gracefully and
|
|
198
356
|
// simply omit the Bearer header, which is fine when auth is not enforced.
|
|
199
|
-
|
|
200
|
-
|
|
357
|
+
let authToken = initialAuthToken;
|
|
358
|
+
if (authToken === null) {
|
|
359
|
+
const { getPrimaryTokenFromFile } = await import('./consoleToken.js');
|
|
360
|
+
authToken = await getPrimaryTokenFromFile(env.DOLLHOUSE_CONSOLE_TOKEN_FILE);
|
|
361
|
+
}
|
|
201
362
|
if (authToken) {
|
|
202
363
|
logger.debug('[UnifiedConsole] Follower loaded console auth token');
|
|
203
364
|
}
|
|
@@ -233,4 +394,4 @@ async function startAsFollower(options, election, consolePort = DEFAULT_CONSOLE_
|
|
|
233
394
|
},
|
|
234
395
|
};
|
|
235
396
|
}
|
|
236
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVW5pZmllZENvbnNvbGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvd2ViL2NvbnNvbGUvVW5pZmllZENvbnNvbGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7R0FhRztBQU1ILE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUMvQyxPQUFPLEVBQ0wsV0FBVyxFQUNYLDJCQUEyQixFQUMzQixvQkFBb0IsRUFDcEIsY0FBYyxFQUNkLHFCQUFxQixFQUNyQixrQkFBa0IsR0FFbkIsTUFBTSxxQkFBcUIsQ0FBQztBQUM3QixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUN2RCxPQUFPLEVBQ0wsdUJBQXVCLEVBQ3ZCLGdCQUFnQixHQUNqQixNQUFNLDJCQUEyQixDQUFDO0FBQ25DLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQ3pELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ3RELE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUUxQzs7Ozs7O0dBTUc7QUFDSCxNQUFNLG9CQUFvQixHQUFHLEdBQUcsQ0FBQywwQkFBMEIsQ0FBQztBQW9DNUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBb0JHO0FBQ0gsTUFBTSxDQUFDLEtBQUssVUFBVSwwQkFBMEIsQ0FDOUMsV0FBbUIsRUFDbkIsU0FBb0Msa0JBQWtCLEVBQ3RELE1BQXFCLE1BQU07SUFFM0IsSUFBSSxDQUFDO1FBQ0gsTUFBTSxNQUFNLEdBQUcsTUFBTSxNQUFNLEVBQUUsQ0FBQztRQUM5QixJQUFJLE1BQU0sQ0FBQyxhQUFhLEVBQUUsQ0FBQztZQUN6QixHQUFHLENBQUMsSUFBSSxDQUNOLDZFQUE2RTtnQkFDN0UsUUFBUSxNQUFNLENBQUMsR0FBRyxVQUFVLE1BQU0sQ0FBQyxJQUFJLDRCQUE0QjtnQkFDbkUs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cmF0b3IuXG4gKlxuICogVGllcyB0b2dldGhlciBsZWFkZXIgZWxlY3Rpb24sIGNvbnNvbGUgc3RhcnR1cCwgZm9sbG93ZXIgd2lyaW5nLFxuICogYW5kIHNlc3Npb24gbGlmZWN5Y2xlIG1hbmFnZW1lbnQuIFRoaXMgaXMgdGhlIG1haW4gZW50cnkgcG9pbnRcbiAqIGNhbGxlZCBieSB0aGUgREkgY29udGFpbmVyIGR1cmluZyBkZWZlcnJlZCBzZXR1cC5cbiAqXG4gKiBGbG93OlxuICogMS4gUnVuIGxlYWRlciBlbGVjdGlvbiAocmVhZCBsb2NrIGZpbGUsIGNsYWltIG9yIGZvbGxvdylcbiAqIDIuIElmIGxlYWRlcjogc3RhcnQgd2ViIHNlcnZlciBvbiBmaXhlZCBwb3J0LCBtb3VudCBpbmdlc3Qgcm91dGVzLCBzdGFydCBoZWFydGJlYXRcbiAqIDMuIElmIGZvbGxvd2VyOiByZWdpc3RlciBmb3J3YXJkaW5nIHNpbmtzIHdpdGggTG9nTWFuYWdlciwgc3RhcnQgc2Vzc2lvbiBoZWFydGJlYXRcbiAqXG4gKiBAc2luY2UgdjIuMS4wIOKAlCBJc3N1ZSAjMTcwMFxuICovXG5cbmltcG9ydCB0eXBlIHsgVW5pZmllZExvZ0VudHJ5IH0gZnJvbSAnLi4vLi4vbG9nZ2luZy90eXBlcy5qcyc7XG5pbXBvcnQgdHlwZSB7IE1ldHJpY1NuYXBzaG90IH0gZnJvbSAnLi4vLi4vbWV0cmljcy90eXBlcy5qcyc7XG5pbXBvcnQgdHlwZSB7IE1lbW9yeUxvZ1NpbmsgfSBmcm9tICcuLi8uLi9sb2dnaW5nL3NpbmtzL01lbW9yeUxvZ1NpbmsuanMnO1xuaW1wb3J0IHR5cGUgeyBNZW1vcnlNZXRyaWNzU2luayB9IGZyb20gJy4uLy4uL21ldHJpY3Mvc2lua3MvTWVtb3J5TWV0cmljc1NpbmsuanMnO1xuaW1wb3J0IHsgbG9nZ2VyIH0gZnJvbSAnLi4vLi4vdXRpbHMvbG9nZ2VyLmpzJztcbmltcG9ydCB7XG4gIGVsZWN0TGVhZGVyLFxuICBpc0xlYWRlcldlYkNvbnNvbGVSZWFjaGFibGUsXG4gIGZvcmNlQ2xhaW1MZWFkZXJzaGlwLFxuICBzdGFydEhlYXJ0YmVhdCxcbiAgcmVnaXN0ZXJMZWFkZXJDbGVhbnVwLFxuICBkZXRlY3RMZWdhY3lMZWFkZXIsXG4gIHR5cGUgRWxlY3Rpb25SZXN1bHQsXG59IGZyb20gJy4vTGVhZGVyRWxlY3Rpb24uanMnO1xuaW1wb3J0IHsgY3JlYXRlSW5nZXN0Um91dGVzIH0gZnJvbSAnLi9Jbmdlc3RSb3V0ZXMuanMnO1xuaW1wb3J0IHtcbiAgTGVhZGVyRm9yd2FyZGluZ0xvZ1NpbmssXG4gIFNlc3Npb25IZWFydGJlYXQsXG59IGZyb20gJy4vTGVhZGVyRm9yd2FyZGluZ1NpbmsuanMnO1xuaW1wb3J0IHsgUHJvbW90aW9uTWFuYWdlciB9IGZyb20gJy4vUHJvbW90aW9uTWFuYWdlci5qcyc7XG5pbXBvcnQgeyBDb25zb2xlVG9rZW5TdG9yZSB9IGZyb20gJy4vY29uc29sZVRva2VuLmpzJztcbmltcG9ydCB7IGVudiB9IGZyb20gJy4uLy4uL2NvbmZpZy9lbnYuanMnO1xuXG4vKipcbiAqIERlZmF1bHQgY29uc29sZSBwb3J0IGZyb20gdGhlIGVudiB2YXIuIFVzZWQgYXMgZmFsbGJhY2sgd2hlbiBubyBwb3J0XG4gKiBpcyBwcm92aWRlZCB2aWEgY29uZmlnIGZpbGUgb3Igb3B0aW9ucy4gVGhlIHJlc29sdXRpb24gaGllcmFyY2h5IGlzOlxuICogICAxLiBvcHRpb25zLnBvcnQgKGZyb20gY29uZmlnIGZpbGUsIHJlc29sdmVkIGJ5IHRoZSBESSBjb250YWluZXIpXG4gKiAgIDIuIERPTExIT1VTRV9XRUJfQ09OU09MRV9QT1JUIGVudiB2YXJcbiAqICAgMy4gNDE3MTUgKGhhcmRjb2RlZCBkZWZhdWx0IGluIGVudi50cylcbiAqL1xuY29uc3QgREVGQVVMVF9DT05TT0xFX1BPUlQgPSBlbnYuRE9MTEhPVVNFX1dFQl9DT05TT0xFX1BPUlQ7XG5cbi8qKlxuICogT3B0aW9ucyBmb3Igc3RhcnRpbmcgdGhlIHVuaWZpZWQgY29uc29sZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBVbmlmaWVkQ29uc29sZU9wdGlvbnMge1xuICAvKiogVGhpcyBwcm9jZXNzJ3MgdW5pcXVlIHNlc3Npb24gSUQgKi9cbiAgc2Vzc2lvbklkOiBzdHJpbmc7XG4gIC8qKiBQb3J0Zm9saW8gYmFzZSBkaXJlY3RvcnkgKGZvciBzdGFydFdlYlNlcnZlcikgKi9cbiAgcG9ydGZvbGlvRGlyOiBzdHJpbmc7XG4gIC8qKiBMb2cgbWVtb3J5IHNpbmsgKGZvciBjb25zb2xlIGhpc3RvcnkpICovXG4gIG1lbW9yeVNpbms6IE1lbW9yeUxvZ1Npbms7XG4gIC8qKiBNZXRyaWNzIG1lbW9yeSBzaW5rICovXG4gIG1ldHJpY3NTaW5rPzogTWVtb3J5TWV0cmljc1Npbms7XG4gIC8qKiBNQ1AtQVFMIGhhbmRsZXIgZm9yIHBlcm1pc3Npb24gcm91dGVzICh0eXBlZCBhcyBhbnkgdG8gYXZvaWQgY2lyY3VsYXIgaW1wb3J0cykgKi9cbiAgbWNwQXFsSGFuZGxlcj86IGFueTtcbiAgLyoqIENhbGxiYWNrIHRvIHJlZ2lzdGVyIGEgbG9nIHNpbmsgd2l0aCB0aGUgTG9nTWFuYWdlciAqL1xuICByZWdpc3RlckxvZ1Npbms6IChzaW5rOiB7IHdyaXRlKGVudHJ5OiBVbmlmaWVkTG9nRW50cnkpOiB2b2lkOyBmbHVzaCgpOiBQcm9taXNlPHZvaWQ+OyBjbG9zZSgpOiBQcm9taXNlPHZvaWQ+IH0pID0+IHZvaWQ7XG4gIC8qKiBDYWxsYmFjayB0byB3aXJlIFNTRSBicm9hZGNhc3RzIGFmdGVyIHdlYiBzZXJ2ZXIgc3RhcnRzICovXG4gIHdpcmVTU0VCcm9hZGNhc3RzOiAod2ViUmVzdWx0OiB7IGxvZ0Jyb2FkY2FzdD86IChlbnRyeTogVW5pZmllZExvZ0VudHJ5KSA9PiB2b2lkOyBtZXRyaWNzT25TbmFwc2hvdD86IChzbmFwc2hvdDogTWV0cmljU25hcHNob3QpID0+IHZvaWQgfSwgbWV0cmljc1Npbms/OiBNZW1vcnlNZXRyaWNzU2luaykgPT4gdm9pZDtcbiAgLyoqIENvbnNvbGUgcG9ydCBvdmVycmlkZSBmcm9tIGNvbmZpZyBmaWxlLiBGYWxscyBiYWNrIHRvIGVudiB2YXIgaWYgbm90IHByb3ZpZGVkLiAqL1xuICBwb3J0PzogbnVtYmVyO1xufVxuXG4vKipcbiAqIFJlc3VsdCBvZiBzdGFydGluZyB0aGUgdW5pZmllZCBjb25zb2xlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFVuaWZpZWRDb25zb2xlUmVzdWx0IHtcbiAgcm9sZTogJ2xlYWRlcicgfCAnZm9sbG93ZXInO1xuICBlbGVjdGlvbjogRWxlY3Rpb25SZXN1bHQ7XG4gIC8qKiBQb3J0IHRoZSBjb25zb2xlIGlzIHJ1bm5pbmcgb24gKGxlYWRlciBvbmx5KSAqL1xuICBwb3J0PzogbnVtYmVyO1xuICAvKiogQ2xlYW51cCBmdW5jdGlvbiB0byBjYWxsIG9uIHNodXRkb3duICovXG4gIGNsZWFudXA6ICgpID0+IFByb21pc2U8dm9pZD47XG59XG5cbi8qKlxuICogQ2hlY2sgZm9yIGEgcnVubmluZyBsZWdhY3kgKHByZS1hdXRoZW50aWNhdGlvbikgRG9sbGhvdXNlTUNQIGNvbnNvbGUgYW5kXG4gKiBsb2cgYSBXQVJOLWxldmVsIG1lc3NhZ2UgaWYgb25lIGlzIGZvdW5kICgjMTc5NCkuXG4gKlxuICogRXh0cmFjdGVkIGZyb20gYHN0YXJ0VW5pZmllZENvbnNvbGVgIHNvIHRoZSB3aXJpbmcgY2FuIGJlIGludGVncmF0aW9uLVxuICogdGVzdGVkIGluIGlzb2xhdGlvbiB3aXRob3V0IHNwaW5uaW5nIHVwIGEgZnVsbCB3ZWIgc2VydmVyIGFuZCBsZWFkZXJcbiAqIGVsZWN0aW9uLiBUaGUgaW1wbGVtZW50YXRpb24gaXMgZmlyZS1hbmQtZm9yZ2V0OiBkZXRlY3Rpb24gZmFpbHVyZXNcbiAqIGFyZSBsb2dnZWQgYXQgREVCVUcgYW5kIG5ldmVyIHByb3BhZ2F0ZSwgYmVjYXVzZSBhIGZhaWx1cmUgaGVyZSBtdXN0XG4gKiBub3QgYmxvY2sgbGVhZGVyIGVsZWN0aW9uIG9mIHRoZSBhdXRoZW50aWNhdGVkIGNvbnNvbGUuXG4gKlxuICogQHBhcmFtIGN1cnJlbnRQb3J0IC0gVGhlIHBvcnQgdGhlIGF1dGhlbnRpY2F0ZWQgY29uc29sZSBpbnRlbmRzIHRvXG4gKiAgICAgICAgICAgICAgICAgICAgICBiaW5kIHRvLiBVc2VkIGluIHRoZSB3YXJuaW5nIG1lc3NhZ2UgdG8gaGVscCB0aGVcbiAqICAgICAgICAgICAgICAgICAgICAgIHVzZXIgdGVsbCB0aGUgdHdvIGNvbnNvbGVzIGFwYXJ0LlxuICogQHBhcmFtIGRldGVjdCAgICAgIC0gT3B0aW9uYWwgaW5qZWN0aW9uIHBvaW50IGZvciB0aGUgZGV0ZWN0aW9uXG4gKiAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbi4gRGVmYXVsdHMgdG8gYGRldGVjdExlZ2FjeUxlYWRlcmAuIFRlc3RzXG4gKiAgICAgICAgICAgICAgICAgICAgICBwYXNzIGEgc3R1Yi5cbiAqIEBwYXJhbSBsb2cgICAgICAgICAtIE9wdGlvbmFsIGluamVjdGlvbiBwb2ludCBmb3IgdGhlIGxvZ2dlci4gRGVmYXVsdHNcbiAqICAgICAgICAgICAgICAgICAgICAgIHRvIHRoZSBtb2R1bGUgbG9nZ2VyLiBUZXN0cyBwYXNzIGEgc3B5LlxuICogQHJldHVybnMgVGhlIGxlZ2FjeSBsZWFkZXIgaW5mbyBmcm9tIGBkZXRlY3QoKWAsIG9yIG51bGwgaWYgZGV0ZWN0aW9uXG4gKiAgICAgICAgICB0aHJldy4gRXhwb3NlZCBzbyB0ZXN0cyBjYW4gYXNzZXJ0IHRoZSBmdWxsIHJlc3VsdCBzaGFwZS5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHdhcm5JZkxlZ2FjeUNvbnNvbGVQcmVzZW50KFxuICBjdXJyZW50UG9ydDogbnVtYmVyLFxuICBkZXRlY3Q6IHR5cGVvZiBkZXRlY3RMZWdhY3lMZWFkZXIgPSBkZXRlY3RMZWdhY3lMZWFkZXIsXG4gIGxvZzogdHlwZW9mIGxvZ2dlciA9IGxvZ2dlcixcbik6IFByb21pc2U8QXdhaXRlZDxSZXR1cm5UeXBlPHR5cGVvZiBkZXRlY3RMZWdhY3lMZWFkZXI+PiB8IG51bGw+IHtcbiAgdHJ5IHtcbiAgICBjb25zdCBsZWdhY3kgPSBhd2FpdCBkZXRlY3QoKTtcbiAgICBpZiAobGVnYWN5LmxlZ2FjeVJ1bm5pbmcpIHtcbiAgICAgIGxvZy53YXJuKFxuICAgICAgICBgW1VuaWZpZWRDb25zb2xlXSBMZWdhY3kgKHByZS1hdXRoZW50aWNhdGlvbikgRG9sbGhvdXNlTUNQIGNvbnNvbGUgZGV0ZWN0ZWQgYCArXG4gICAgICAgIGAocGlkPSR7bGVnYWN5LnBpZH0sIHBvcnQ9JHtsZWdhY3kucG9ydH0pLiBCb3RoIGNvbnNvbGVzIHdpbGwgcnVuIGAgK1xuICAgICAgICBgaW5kZXBlbmRlbnRseSBvbiBkaWZmZXJlbnQgcG9ydHMgd2l0aCBkaWZmZXJlbnQgc2VjdXJpdHkgcG9zdHVyZS4gYCArXG4gICAgICAgIGBUaGUgYXV0aGVudGljYXRlZCBjb25zb2xlICh0aGlzIHByb2Nlc3MpIHVzZXMgcG9ydCAke2N1cnJlbnRQb3J0fTsgYCArXG4gICAgICAgIGB0aGUgbGVnYWN5IGNvbnNvbGUgdXNlcyBwb3J0ICR7bGVnYWN5LnBvcnQgPz8gMzkzOX0uIGAgK1xuICAgICAgICBgRm9yIGNvbnNpc3RlbnQgc2VjdXJpdHksIHVwZGF0ZSB0aGUgbGVnYWN5IGluc3RhbGxhdGlvbiB0byBhIGAgK1xuICAgICAgICBgdmVyc2lvbiB3aXRoIHRoZSBhdXRoZW50aWNhdGVkIGNvbnNvbGUuYCxcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiBsZWdhY3k7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIC8vIEJlc3QtZWZmb3J0IOKAlCBuZXZlciBibG9jayBlbGVjdGlvbiBvbiBhIGRldGVjdGlvbiBmYWlsdXJlXG4gICAgbG9nLmRlYnVnKCdbVW5pZmllZENvbnNvbGVdIExlZ2FjeSBsZWFkZXIgZGV0ZWN0aW9uIGZhaWxlZCcsIHtcbiAgICAgIGVycm9yOiBlcnIgaW5zdGFuY2VvZiBFcnJvciA/IGVyci5tZXNzYWdlIDogU3RyaW5nKGVyciksXG4gICAgfSk7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbn1cblxuLyoqXG4gKiBTdGFydCB0aGUgdW5pZmllZCB3ZWIgY29uc29sZS5cbiAqXG4gKiBSdW5zIGxlYWRlciBlbGVjdGlvbiwgdGhlbiBlaXRoZXIgc3RhcnRzIHRoZSBmdWxsIGNvbnNvbGUgKGxlYWRlcilcbiAqIG9yIHNldHMgdXAgZXZlbnQgZm9yd2FyZGluZyAoZm9sbG93ZXIpLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gc3RhcnRVbmlmaWVkQ29uc29sZShvcHRpb25zOiBVbmlmaWVkQ29uc29sZU9wdGlvbnMpOiBQcm9taXNlPFVuaWZpZWRDb25zb2xlUmVzdWx0PiB7XG4gIC8vIFJlc29sdmUgcG9ydDogb3B0aW9ucyAoY29uZmlnIGZpbGUpIOKGkiBlbnYgdmFyIOKGkiBkZWZhdWx0XG4gIGNvbnN0IGNvbnNvbGVQb3J0ID0gb3B0aW9ucy5wb3J0IHx8IERFRkFVTFRfQ09OU09MRV9QT1JUO1xuICBsb2dnZXIuZGVidWcoYFtVbmlmaWVkQ29uc29sZV0gUG9ydCByZXNvbHZlZDogJHtjb25zb2xlUG9ydH1gICtcbiAgICAob3B0aW9ucy5wb3J0ID8gJyAoZnJvbSBjb25maWcgZmlsZSknIDogYCAoZnJvbSBlbnYvZGVmYXVsdClgKSk7XG5cbiAgLy8gTGVnYWN5LWxlYWRlciBkZXRlY3Rpb24gKCMxNzk0KSDigJQgd2FybiB0aGUgdXNlciBpZiBhIHByZS1hdXRoXG4gIC8vIERvbGxob3VzZU1DUCBjb25zb2xlIGlzIHJ1bm5pbmcgYWxvbmdzaWRlIHRoaXMgYXV0aGVudGljYXRlZCBvbmUuXG4gIC8vIFRoZXkgd2lsbCBjb2V4aXN0IGZpbmUgYmVjYXVzZSBvZiBwb3J0ICsgbG9jayArIHRva2VuIGZpbGUgaXNvbGF0aW9uLFxuICAvLyBidXQgdGhlIHVzZXIgc2hvdWxkIGtub3cgYm90aCBleGlzdCBzbyB0aGUgZGlmZmVyaW5nIHNlY3VyaXR5IHBvc3R1cmVcbiAgLy8gYmV0d2VlbiB0aGVtIGRvZXNuJ3QgbG9vayBsaWtlIGEgYnVnLlxuICBhd2FpdCB3YXJuSWZMZWdhY3lDb25zb2xlUHJlc2VudChjb25zb2xlUG9ydCk7XG5cbiAgbGV0IGVsZWN0aW9uID0gYXdhaXQgZWxlY3RMZWFkZXIob3B0aW9ucy5zZXNzaW9uSWQsIGNvbnNvbGVQb3J0KTtcblxuICAvLyBJZiB3ZSBsb3N0IHRoZSBlbGVjdGlvbiwgY2hlY2sgaWYgdGhlIGxlYWRlciBpcyBhY3R1YWxseSBydW5uaW5nIGEgd2ViIGNvbnNvbGUuXG4gIC8vIEFuIE1DUCBzdGRpbyBwcm9jZXNzIG1heSBob2xkIGxlYWRlcnNoaXAgYnV0IG5vdCBzZXJ2ZSB3ZWIgcm91dGVzLlxuICAvLyBJbiB0aGF0IGNhc2UsIGZvcmNlIGEgdGFrZW92ZXIgc28gdGhlIHdlYiBjb25zb2xlIHdvcmtzIHByb3Blcmx5LlxuICBpZiAoZWxlY3Rpb24ucm9sZSA9PT0gJ2ZvbGxvd2VyJykge1xuICAgIGNvbnN0IHJlYWNoYWJsZSA9IGF3YWl0IGlzTGVhZGVyV2ViQ29uc29sZVJlYWNoYWJsZShlbGVjdGlvbi5sZWFkZXJJbmZvKTtcbiAgICBpZiAoIXJlYWNoYWJsZSkge1xuICAgICAgZWxlY3Rpb24gPSBhd2FpdCBmb3JjZUNsYWltTGVhZGVyc2hpcChvcHRpb25zLnNlc3Npb25JZCwgY29uc29sZVBvcnQpO1xuICAgIH1cbiAgfVxuXG4gIGlmIChlbGVjdGlvbi5yb2xlID09PSAnbGVhZGVyJykge1xuICAgIHJldHVybiBzdGFydEFzTGVhZGVyKG9wdGlvbnMsIGVsZWN0aW9uLCBjb25zb2xlUG9ydCk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHN0YXJ0QXNGb2xsb3dlcihvcHRpb25zLCBlbGVjdGlvbiwgY29uc29sZVBvcnQpO1xuICB9XG59XG5cbi8qKlxuICogU3RhcnQgYXMgdGhlIGNvbnNvbGUgbGVhZGVyLlxuICogQmluZHMgdGhlIHJlc29sdmVkIGNvbnNvbGUgcG9ydCAoY29uZmlnIGZpbGUg4oaSIGVudiB2YXIg4oaSIGRlZmF1bHQpLFxuICogbW91bnRzIGFsbCByb3V0ZXMgaW5jbHVkaW5nIGluZ2VzdGlvbiwgc3RhcnRzIGhlYXJ0YmVhdC5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gc3RhcnRBc0xlYWRlcihcbiAgb3B0aW9uczogVW5pZmllZENvbnNvbGVPcHRpb25zLFxuICBlbGVjdGlvbjogRWxlY3Rpb25SZXN1bHQsXG4gIGNvbnNvbGVQb3J0OiBudW1iZXIgPSBERUZBVUxUX0NPTlNPTEVfUE9SVCxcbik6IFByb21pc2U8VW5pZmllZENvbnNvbGVSZXN1bHQ+IHtcbiAgY29uc3QgeyBzdGFydFdlYlNlcnZlciB9ID0gYXdhaXQgaW1wb3J0KCcuLi9zZXJ2ZXIuanMnKTtcbiAgY29uc3QgeyBwaWNrUmFuZG9tVG9rZW5OYW1lIH0gPSBhd2FpdCBpbXBvcnQoJy4vU2Vzc2lvbk5hbWVzLmpzJyk7XG5cbiAgLy8gSW5pdGlhbGl6ZSB0aGUgY29uc29sZSB0b2tlbiBzdG9yZSAoIzE3ODApLiBDcmVhdGVzIHRoZSB0b2tlbiBmaWxlIG9uXG4gIC8vIGZpcnN0IHJ1biwgcmVhZHMgdGhlIGV4aXN0aW5nIHRva2VucyBvbiBzdWJzZXF1ZW50IHJ1bnMuIFRoZSB0b2tlbiBpc1xuICAvLyBwZXJzaXN0ZW50IGFjcm9zcyByZXN0YXJ0cyDigJQgb25seSByb3RhdGVkIG9uIGV4cGxpY2l0IHJlcXVlc3QgKFBoYXNlIDIpLlxuICAvLyBGZWF0dXJlIGZsYWcgRE9MTEhPVVNFX1dFQl9BVVRIX0VOQUJMRUQgY29udHJvbHMgZW5mb3JjZW1lbnQ7IHRoZSBmaWxlXG4gIC8vIGlzIGdlbmVyYXRlZCByZWdhcmRsZXNzIHNvIGNvbnN1bWVycyBjYW4gYXR0YWNoIHRva2VucyBwcmVlbXB0aXZlbHkuXG4gIGNvbnN0IHRva2VuU3RvcmUgPSBuZXcgQ29uc29sZVRva2VuU3RvcmUoZW52LkRPTExIT1VTRV9DT05TT0xFX1RPS0VOX0ZJTEUpO1xuICBjb25zdCBwcmltYXJ5VG9rZW4gPSBhd2FpdCB0b2tlblN0b3JlLmVuc3VyZUluaXRpYWxpemVkKHBpY2tSYW5kb21Ub2tlbk5hbWUoKSk7XG4gIGxvZ2dlci5pbmZvKCdbVW5pZmllZENvbnNvbGVdIENvbnNvbGUgdG9rZW4gc3RvcmUgaW5pdGlhbGl6ZWQnLCB7XG4gICAgdG9rZW5JZDogcHJpbWFyeVRva2VuLmlkLFxuICAgIHRva2VuTmFtZTogcHJpbWFyeVRva2VuLm5hbWUsXG4gICAgZmlsZTogdG9rZW5TdG9yZS5nZXRGaWxlUGF0aCgpLFxuICAgIGF1dGhFbmZvcmNlZDogZW52LkRPTExIT1VTRV9XRUJfQVVUSF9FTkFCTEVELFxuICB9KTtcblxuICAvLyBQcmUtY3JlYXRlIGEgcGxhY2Vob2xkZXIgYnJvYWRjYXN0IHRoYXQgd2UnbGwgd2lyZSB1cCBhZnRlciB0aGUgc2VydmVyIHN0YXJ0c1xuICBsZXQgbGl2ZUJyb2FkY2FzdDogKChlbnRyeTogVW5pZmllZExvZ0VudHJ5KSA9PiB2b2lkKSB8IHVuZGVmaW5lZDtcbiAgbGV0IGxpdmVNZXRyaWNzT25TbmFwc2hvdDogKChzbmFwc2hvdDogTWV0cmljU25hcHNob3QpID0+IHZvaWQpIHwgdW5kZWZpbmVkO1xuXG4gIC8vIENyZWF0ZSBpbmdlc3Rpb24gcm91dGVzIHdpdGggYSBkZWZlcnJlZCBicm9hZGNhc3QgKHdpcmVkIGFmdGVyIHNlcnZlciBzdGFydHMpXG4gIGNvbnN0IGluZ2VzdFJlc3VsdCA9IGNyZWF0ZUluZ2VzdFJvdXRlcyh7XG4gICAgbG9nQnJvYWRjYXN0OiAoZW50cnkpID0+IGxpdmVCcm9hZGNhc3Q/LihlbnRyeSksXG4gICAgbWV0cmljc09uU25hcHNob3Q6IChzbmFwc2hvdCkgPT4gbGl2ZU1ldHJpY3NPblNuYXBzaG90Py4oc25hcHNob3QpLFxuICAgIHN0b3JlTWV0cmljc1NuYXBzaG90OiAoc25hcHNob3QpID0+IG9wdGlvbnMubWV0cmljc1Npbms/Lm9uU25hcHNob3Qoc25hcHNob3QpLFxuICB9KTtcblxuICAvLyBSZWdpc3RlciB0aGUgbGVhZGVyIGFzIGEgc2Vzc2lvblxuICBpbmdlc3RSZXN1bHQucmVnaXN0ZXJMZWFkZXJTZXNzaW9uKG9wdGlvbnMuc2Vzc2lvbklkLCBwcm9jZXNzLnBpZCk7XG5cbiAgLy8gUmVnaXN0ZXIgdGhlIHdlYiBjb25zb2xlIGl0c2VsZiBzbyB0aGUgc2Vzc2lvbiBpbmRpY2F0b3IgaXMgbmV2ZXIgZW1wdHkgKCMxODA1KVxuICBpbmdlc3RSZXN1bHQucmVnaXN0ZXJDb25zb2xlU2Vzc2lvbigpO1xuXG4gIC8vIFN0YXJ0IHRoZSB3ZWIgc2VydmVyIHdpdGggaW5nZXN0IHJvdXRlcyBtb3VudGVkIGJlZm9yZSB0aGUgU1BBIGZhbGxiYWNrLlxuICAvLyBJZiB0aGUgcG9ydCBpcyBvY2N1cGllZCBieSBhIHN0YWxlIHByb2Nlc3MsIHJldHJ5IHdpdGggZXhwb25lbnRpYWwgYmFja29mZi5cbiAgY29uc3Qgc2VydmVyT3B0cyA9IHtcbiAgICBwb3J0Zm9saW9EaXI6IG9wdGlvbnMucG9ydGZvbGlvRGlyLFxuICAgIG1lbW9yeVNpbms6IG9wdGlvbnMubWVtb3J5U2luayxcbiAgICBtZXRyaWNzU2luazogb3B0aW9ucy5tZXRyaWNzU2luayxcbiAgICBwb3J0OiBjb25zb2xlUG9ydCxcbiAgICBhZGRpdGlvbmFsUm91dGVyczogW2luZ2VzdFJlc3VsdC5yb3V0ZXJdLFxuICAgIHRva2VuU3RvcmUsXG4gICAgLi4uKG9wdGlvbnMubWNwQXFsSGFuZGxlciA/IHsgbWNwQXFsSGFuZGxlcjogb3B0aW9ucy5tY3BBcWxIYW5kbGVyIH0gOiB7fSksXG4gIH07XG4gIC8vIGJpbmRBbmRMaXN0ZW4gbm93IGhhbmRsZXMgRUFERFJJTlVTRSBieSBmaW5kaW5nIGFuZCBraWxsaW5nIHRoZSBzdGFsZVxuICAvLyBwcm9jZXNzIG9uIHRoZSBwb3J0LCB0aGVuIHJldHJ5aW5nLiBObyBleHRlcm5hbCByZXRyeSBsb29wIG5lZWRlZC5cbiAgY29uc3Qgd2ViUmVzdWx0ID0gYXdhaXQgc3RhcnRXZWJTZXJ2ZXIoc2VydmVyT3B0cyk7XG5cbiAgaWYgKHdlYlJlc3VsdC5iaW5kUmVzdWx0ICYmICF3ZWJSZXN1bHQuYmluZFJlc3VsdC5zdWNjZXNzKSB7XG4gICAgbG9nZ2VyLmVycm9yKGBbVW5pZmllZENvbnNvbGVdIExlYWRlciBmYWlsZWQgdG8gYmluZCBwb3J0ICR7Y29uc29sZVBvcnR9IOKAlCBjb25zb2xlIHVuYXZhaWxhYmxlYCk7XG4gIH1cblxuICAvLyBXaXJlIFNTRSBicm9hZGNhc3RzIGZvciB0aGlzIGxlYWRlcidzIG93biBldmVudHNcbiAgb3B0aW9ucy53aXJlU1NFQnJvYWRjYXN0cyh3ZWJSZXN1bHQsIG9wdGlvbnMubWV0cmljc1NpbmspO1xuXG4gIC8vIE5vdyB3aXJlIHRoZSBsaXZlIGJyb2FkY2FzdCBmdW5jdGlvbnMgaW50byB0aGUgaW5nZXN0IHJvdXRlc1xuICBpZiAod2ViUmVzdWx0LmxvZ0Jyb2FkY2FzdCkge1xuICAgIGNvbnN0IG9yaWdpbmFsQnJvYWRjYXN0ID0gd2ViUmVzdWx0LmxvZ0Jyb2FkY2FzdDtcbiAgICAvLyBTdGFtcCBsZWFkZXIncyBvd24gZW50cmllcyB3aXRoIHNlc3Npb24gSURcbiAgICBsaXZlQnJvYWRjYXN0ID0gKGVudHJ5OiBVbmlmaWVkTG9nRW50cnkpID0+IHtcbiAgICAgIGNvbnN0IHN0YW1wZWQ6IFVuaWZpZWRMb2dFbnRyeSA9IHtcbiAgICAgICAgLi4uZW50cnksXG4gICAgICAgIGRhdGE6IHsgLi4uZW50cnkuZGF0YSwgX3Nlc3Npb25JZDogb3B0aW9ucy5zZXNzaW9uSWQgfSxcbiAgICAgIH07XG4gICAgICBvcmlnaW5hbEJyb2FkY2FzdChzdGFtcGVkKTtcbiAgICB9O1xuICB9XG4gIGxpdmVNZXRyaWNzT25TbmFwc2hvdCA9IHdlYlJlc3VsdC5tZXRyaWNzT25TbmFwc2hvdDtcblxuICBsb2dnZXIuaW5mbygnW1VuaWZpZWRDb25zb2xlXSBJbmdlc3Rpb24gcm91dGVzIG1vdW50ZWQnKTtcblxuICAvLyBTdGFydCBoZWFydGJlYXQgYW5kIHJlZ2lzdGVyIGNsZWFudXBcbiAgY29uc3Qgc3RvcEhlYXJ0YmVhdCA9IHN0YXJ0SGVhcnRiZWF0KGVsZWN0aW9uLmxlYWRlckluZm8pO1xuICByZWdpc3RlckxlYWRlckNsZWFudXAoKTtcblxuICBsb2dnZXIuaW5mbygnW1VuaWZpZWRDb25zb2xlXSBMZWFkZXIgc3RhcnRlZCcsIHtcbiAgICBzZXNzaW9uSWQ6IG9wdGlvbnMuc2Vzc2lvbklkLCBwb3J0OiBjb25zb2xlUG9ydCwgcGlkOiBwcm9jZXNzLnBpZCxcbiAgICByb2xlOiAnbGVhZGVyJywgaW5nZXN0Um91dGVzOiBbJy9hcGkvaW5nZXN0L2xvZ3MnLCAnL2FwaS9pbmdlc3QvbWV0cmljcycsICcvYXBpL2luZ2VzdC9zZXNzaW9uJywgJy9hcGkvc2Vzc2lvbnMnXSxcbiAgfSk7XG5cbiAgcmV0dXJuIHtcbiAgICByb2xlOiAnbGVhZGVyJyxcbiAgICBlbGVjdGlvbixcbiAgICBwb3J0OiBjb25zb2xlUG9ydCxcbiAgICBjbGVhbnVwOiBhc3luYyAoKSA9PiB7XG4gICAgICBzdG9wSGVhcnRiZWF0KCk7XG4gICAgfSxcbiAgfTtcbn1cblxuLyoqXG4gKiBTdGFydCBhcyBhIGZvbGxvd2VyLlxuICogUmVnaXN0ZXJzIGZvcndhcmRpbmcgc2lua3Mgd2l0aCB0aGUgTG9nTWFuYWdlciwgc3RhcnRzIHNlc3Npb24gaGVhcnRiZWF0LlxuICovXG5hc3luYyBmdW5jdGlvbiBzdGFydEFzRm9sbG93ZXIoXG4gIG9wdGlvbnM6IFVuaWZpZWRDb25zb2xlT3B0aW9ucyxcbiAgZWxlY3Rpb246IEVsZWN0aW9uUmVzdWx0LFxuICBjb25zb2xlUG9ydDogbnVtYmVyID0gREVGQVVMVF9DT05TT0xFX1BPUlQsXG4pOiBQcm9taXNlPFVuaWZpZWRDb25zb2xlUmVzdWx0PiB7XG4gIGNvbnN0IGxlYWRlclVybCA9IGBodHRwOi8vMTI3LjAuMC4xOiR7ZWxlY3Rpb24ubGVhZGVySW5mby5wb3J0fWA7XG5cbiAgLy8gUmVhZCB0aGUgY29uc29sZSBhdXRoIHRva2VuICgjMTc4MCkgd3JpdHRlbiBieSB0aGUgbGVhZGVyLiBNYXkgYmUgbnVsbFxuICAvLyBpZiB0aGUgZmlsZSBkb2Vzbid0IGV4aXN0IHlldCDigJQgdGhlIHNpbmtzIGhhbmRsZSB0aGF0IGdyYWNlZnVsbHkgYW5kXG4gIC8vIHNpbXBseSBvbWl0IHRoZSBCZWFyZXIgaGVhZGVyLCB3aGljaCBpcyBmaW5lIHdoZW4gYXV0aCBpcyBub3QgZW5mb3JjZWQuXG4gIGNvbnN0IHsgZ2V0UHJpbWFyeVRva2VuRnJvbUZpbGUgfSA9IGF3YWl0IGltcG9ydCgnLi9jb25zb2xlVG9rZW4uanMnKTtcbiAgY29uc3QgYXV0aFRva2VuID0gYXdhaXQgZ2V0UHJpbWFyeVRva2VuRnJvbUZpbGUoZW52LkRPTExIT1VTRV9DT05TT0xFX1RPS0VOX0ZJTEUpO1xuICBpZiAoYXV0aFRva2VuKSB7XG4gICAgbG9nZ2VyLmRlYnVnKCdbVW5pZmllZENvbnNvbGVdIEZvbGxvd2VyIGxvYWRlZCBjb25zb2xlIGF1dGggdG9rZW4nKTtcbiAgfSBlbHNlIHtcbiAgICBsb2dnZXIuZGVidWcoJ1tVbmlmaWVkQ29uc29sZV0gTm8gY29uc29sZSBhdXRoIHRva2VuIGZpbGUgZm91bmQ7IGZvbGxvd2VyIHdpbGwgUE9TVCB3aXRob3V0IEJlYXJlciBoZWFkZXInKTtcbiAgfVxuXG4gIC8vIFBlci1pbnN0YW5jZSBwcm9tb3Rpb24gbWFuYWdlciDigJQgdHJhY2tzIGl0cyBvd24gYXR0ZW1wdCBjb3VudGVyIHNvXG4gIC8vIG11bHRpcGxlIGZvbGxvd2VycyBkb24ndCBpbnRlcmZlcmUgd2l0aCBlYWNoIG90aGVyJ3MgcHJvbW90aW9uIGJ1ZGdldHMuXG4gIGNvbnN0IHByb21vdGlvbk1nciA9IG5ldyBQcm9tb3Rpb25NYW5hZ2VyKG9wdGlvbnMsIGNvbnNvbGVQb3J0LCBzdGFydEFzTGVhZGVyLCBzdGFydEFzRm9sbG93ZXIpO1xuXG4gIC8vIERlY2xhcmUgc2Vzc2lvbkhlYXJ0YmVhdCBiZWZvcmUgdGhlIHNpbmsgc28gdGhlIGNsb3N1cmUgY2FuIGNhcHR1cmUgaXQuXG4gIC8vIEJvdGggYXJlIGluaXRpYWxpemVkIGJlZm9yZSB0aGUgY2FsbGJhY2sgY291bGQgcG9zc2libHkgZmlyZSAobmVlZHMgNSsgZmFpbGVkIGZsdXNoZXMpLlxuICBsZXQgc2Vzc2lvbkhlYXJ0YmVhdDogU2Vzc2lvbkhlYXJ0YmVhdDtcblxuICAvLyBSZWdpc3RlciBhIGZvcndhcmRpbmcgbG9nIHNpbmsgd2l0aCBsZWFkZXItZGVhdGggY2FsbGJhY2sgKCMxODUwKS5cbiAgY29uc3QgZm9yd2FyZGluZ1NpbmsgPSBuZXcgTGVhZGVyRm9yd2FyZGluZ0xvZ1NpbmsobGVhZGVyVXJsLCBvcHRpb25zLnNlc3Npb25JZCwgYXV0aFRva2VuLCAoKSA9PiB7XG4gICAgcHJvbW90aW9uTWdyLnByb21vdGUoZm9yd2FyZGluZ1NpbmssIHNlc3Npb25IZWFydGJlYXQpXG4gICAgICAuY2F0Y2goZXJyID0+IGxvZ2dlci5lcnJvcignW1VuaWZpZWRDb25zb2xlXSBQcm9tb3Rpb24gY3Jhc2hlZCcsIHsgZXJyb3I6IFN0cmluZyhlcnIpIH0pKTtcbiAgfSk7XG4gIG9wdGlvbnMucmVnaXN0ZXJMb2dTaW5rKGZvcndhcmRpbmdTaW5rKTtcblxuICAvLyBTdGFydCBzZXNzaW9uIGhlYXJ0YmVhdCB0byB0aGUgbGVhZGVyXG4gIHNlc3Npb25IZWFydGJlYXQgPSBuZXcgU2Vzc2lvbkhlYXJ0YmVhdChsZWFkZXJVcmwsIG9wdGlvbnMuc2Vzc2lvbklkLCBwcm9jZXNzLnBpZCwgYXV0aFRva2VuKTtcbiAgYXdhaXQgc2Vzc2lvbkhlYXJ0YmVhdC5zdGFydCgpO1xuXG4gIGxvZ2dlci5pbmZvKCdbVW5pZmllZENvbnNvbGVdIEZvbGxvd2VyIHN0YXJ0ZWQnLCB7XG4gICAgc2Vzc2lvbklkOiBvcHRpb25zLnNlc3Npb25JZCwgcGlkOiBwcm9jZXNzLnBpZCwgcm9sZTogJ2ZvbGxvd2VyJyxcbiAgICBsZWFkZXJTZXNzaW9uOiBlbGVjdGlvbi5sZWFkZXJJbmZvLnNlc3Npb25JZCwgbGVhZGVyUGlkOiBlbGVjdGlvbi5sZWFkZXJJbmZvLnBpZCxcbiAgICBsZWFkZXJQb3J0OiBlbGVjdGlvbi5sZWFkZXJJbmZvLnBvcnQsIGxlYWRlclVybCxcbiAgfSk7XG5cbiAgcmV0dXJuIHtcbiAgICByb2xlOiAnZm9sbG93ZXInLFxuICAgIGVsZWN0aW9uLFxuICAgIGNsZWFudXA6IGFzeW5jICgpID0+IHtcbiAgICAgIGF3YWl0IHNlc3Npb25IZWFydGJlYXQuc3RvcCgpO1xuICAgICAgYXdhaXQgZm9yd2FyZGluZ1NpbmsuY2xvc2UoKTtcbiAgICB9LFxuICB9O1xufVxuIl19
|
|
397
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVW5pZmllZENvbnNvbGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvd2ViL2NvbnNvbGUvVW5pZmllZENvbnNvbGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7R0FhRztBQU1ILE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLCtDQUErQyxDQUFDO0FBQ2pGLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUMvQyxPQUFPLEVBQ0wsV0FBVyxFQUNYLDJCQUEyQixFQUMzQixvQkFBb0IsRUFDcEIsY0FBYyxFQUNkLHFCQUFxQixFQUNyQixrQkFBa0IsRUFDbEIsY0FBYyxFQUNkLGdCQUFnQixFQUNoQixZQUFZLEVBQ1osd0JBQXdCLEVBQ3hCLHFCQUFxQixHQUd0QixNQUFNLHFCQUFxQixDQUFDO0FBQzdCLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ3ZELE9BQU8sRUFDTCx1QkFBdUIsRUFDdkIsZ0JBQWdCLEdBQ2pCLE1BQU0sMkJBQTJCLENBQUM7QUFDbkMsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDekQsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDdEQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQzFELE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUUxQzs7Ozs7O0dBTUc7QUFDSCxNQUFNLG9CQUFvQixHQUFHLEdBQUcsQ0FBQywwQkFBMEIsQ0FBQztBQUM1RCxNQUFNLDRCQUE0QixHQUFHLElBQUksQ0FBQztBQUMxQyxNQUFNLG1DQUFtQyxHQUFHLGFBQWEsQ0FBQztBQUUxRCxTQUFTLGdCQUFnQjtJQUN2QixPQUFPLElBQUksSUFBSSxFQUFFLENBQUMsV0FBVyxFQUFFLENBQUM7QUFDbEMsQ0FBQztBQW9DRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FvQkc7QUFDSCxNQUFNLENBQUMsS0FBSyxVQUFVLDBCQUEwQixDQUM5QyxXQUFtQixFQUNuQixTQUFvQyxrQkFBa0IsRUFDdEQsTUFBcUIsTUFBTTtJQUUzQixJQUFJLENBQUM7UUFDSCxNQUFNLE1BQU0sR0FBRyxNQUFNLE1BQU0sRUFBRSxDQUFDO1FBQzlCLElBQUksTUFBTSxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQ3pCLEdBQUcsQ0FBQyxJQUFJLENBQ04sNkVBQTZFO2dCQUM3RSxRQUFRLE1BQU0sQ0FBQyxHQUFHLFVBQVUsTUFBTSxDQUFDLElBQUksNEJBQTRCO2dCQUNuRSxvRUFBb0U7Z0JBQ3BFLHNEQUFzRCxXQUFXLElBQUk7Z0JBQ3JFLGdDQUFnQyxNQUFNLENBQUMsSUFBSSxJQUFJLDRCQUE0QixJQUFJO2dCQUMvRSwrREFBK0Q7Z0JBQy9ELHlDQUF5QyxDQUMxQyxDQUFDO1FBQ0osQ0FBQztRQUNELE9BQU8sTUFBTSxDQUFDO0lBQ2hCLENBQUM7SUFBQyxPQUFPLEdBQUcsRUFBRSxDQUFDO1FBQ2IsNERBQTREO1FBQzVELEdBQUcsQ0FBQyxLQUFLLENBQUMsaURBQWlELEVBQUU7WUFDM0QsS0FBSyxFQUFFLEdBQUcsWUFBWSxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUM7U0FDeEQsQ0FBQyxDQUFDO1FBQ0gsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0FBQ0gsQ0FBQztBQStCRCxTQUFTLHFCQUFxQixDQUFDLFNBQXdCO0lBQ3JELE9BQU8sU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLGFBQWEsRUFBRSxVQUFVLFNBQVMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztBQUNuRSxDQUFDO0FBRUQsU0FBUywwQkFBMEIsQ0FBQyxJQUFZLEVBQUUsUUFBZ0IsRUFBRSxhQUErQjtJQUNqRyxPQUFPO1FBQ0wsT0FBTyxFQUFFLFlBQVk7UUFDckIsR0FBRyxFQUFFLFFBQVE7UUFDYixJQUFJO1FBQ0osU0FBUyxFQUFFLGdCQUFnQixDQUFDLFNBQVMsQ0FBQyxhQUFhLENBQUMsU0FBUyxDQUFDLENBQUMsaUJBQWlCO1FBQ2hGLFNBQVMsRUFBRSxhQUFhLENBQUMsU0FBUyxJQUFJLGdCQUFnQixFQUFFO1FBQ3hELFNBQVMsRUFBRSxhQUFhLENBQUMsYUFBYSxJQUFJLGdCQUFnQixFQUFFO1FBQzVELGFBQWEsRUFBRSxhQUFhLENBQUMsYUFBYSxJQUFJLHFCQUFxQjtRQUNuRSxzQkFBc0IsRUFBRSxhQUFhLENBQUMsc0JBQXNCLElBQUksd0JBQXdCO0tBQ3pGLENBQUM7QUFDSixDQUFDO0FBRUQsU0FBUyx3QkFBd0IsQ0FBQyxJQUFZLEVBQUUsUUFBZ0I7SUFDOUQsTUFBTSxHQUFHLEdBQUcsZ0JBQWdCLEVBQUUsQ0FBQztJQUMvQixPQUFPO1FBQ0wsT0FBTyxFQUFFLFlBQVk7UUFDckIsR0FBRyxFQUFFLFFBQVE7UUFDYixJQUFJO1FBQ0osU0FBUyxFQUFFLEdBQUcsbUNBQW1DLEdBQUcsUUFBUSxFQUFFO1FBQzlELFNBQVMsRUFBRSxHQUFHO1FBQ2QsU0FBUyxFQUFFLEdBQUc7UUFDZCxhQUFhLEVBQUUscUJBQXFCO1FBQ3BDLHNCQUFzQixFQUFFLHdCQUF3QjtLQUNqRCxDQUFDO0FBQ0osQ0FBQztBQUVELEtBQUssVUFBVSw0QkFBNEIsQ0FDekMsSUFBWSxFQUNaLFFBQWdCLEVBQ2hCLFNBQXdCLEVBQ3hCLFNBQXVCO0lBRXZCLE1BQU0sUUFBUSxHQUFHLE1BQU0sU0FBUyxDQUFDLG9CQUFvQixJQUFJLGVBQWUsRUFBRTtRQUN4RSxPQUFPLEVBQUUscUJBQXFCLENBQUMsU0FBUyxDQUFDO0tBQzFDLENBQUMsQ0FBQztJQUNILElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxFQUFFLENBQUM7UUFDakIsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsTUFBTSxPQUFPLEdBQUcsTUFBTSxRQUFRLENBQUMsSUFBSSxFQUF1QyxDQUFDO0lBQzNFLE1BQU0sUUFBUSxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7SUFDekUsTUFBTSxhQUFhLEdBQUcsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQzlDLE9BQU8sQ0FBQyxHQUFHLEtBQUssUUFBUTtRQUN4QixPQUFPLENBQUMsUUFBUSxLQUFLLElBQUk7UUFDekIsT0FBTyxDQUFDLElBQUksS0FBSyxLQUFLO1FBQ3RCLE9BQU8sQ0FBQyxNQUFNLEtBQUssU0FBUyxDQUM3QixDQUFDO0lBQ0YsT0FBTyxhQUFhLENBQUMsQ0FBQyxDQUFDLDBCQUEwQixDQUFDLElBQUksRUFBRSxRQUFRLEVBQUUsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztBQUMxRixDQUFDO0FBRUQsTUFBTSxDQUFDLEtBQUssVUFBVSx5QkFBeUIsQ0FDN0MsSUFBWSxFQUNaLFNBQXdCLEVBQ3hCLE9BQThCLEVBQUU7SUFFaEMsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLFNBQVMsSUFBSSxLQUFLLENBQUM7SUFDMUMsTUFBTSxpQkFBaUIsR0FBRyxJQUFJLENBQUMsaUJBQWlCLElBQUksYUFBYSxDQUFDO0lBQ2xFLE1BQU0sa0JBQWtCLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixJQUFJLGNBQWMsQ0FBQztJQUNyRSxNQUFNLFFBQVEsR0FBRyxNQUFNLGlCQUFpQixDQUFDLElBQUksQ0FBQyxDQUFDO0lBRS9DLElBQUksUUFBUSxLQUFLLElBQUksRUFBRSxDQUFDO1FBQ3RCLElBQUksQ0FBQztZQUNILE1BQU0sVUFBVSxHQUFHLE1BQU0sNEJBQTRCLENBQUMsSUFBSSxFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQUUsU0FBUyxDQUFDLENBQUM7WUFDNUYsSUFBSSxVQUFVLEVBQUUsQ0FBQztnQkFDZixPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsVUFBVSxFQUFFLENBQUM7WUFDakQsQ0FBQztRQUNILENBQUM7UUFBQyxPQUFPLEdBQUcsRUFBRSxDQUFDO1lBQ2IsTUFBTSxDQUFDLEtBQUssQ0FBQyx5REFBeUQsRUFBRTtnQkFDdEUsSUFBSTtnQkFDSixRQUFRO2dCQUNSLEtBQUssRUFBRSxHQUFHLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDO2FBQ3hELENBQUMsQ0FBQztRQUNMLENBQUM7SUFDSCxDQUFDO0lBRUQsTUFBTSxJQUFJLEdBQUcsTUFBTSxrQkFBa0IsRUFBRSxDQUFDO0lBQ3hDLElBQUksSUFBSSxFQUFFLElBQUksS0FBSyxJQUFJLElBQUksQ0FBQyxRQUFRLEtBQUssSUFBSSxJQUFJLElBQUksQ0FBQyxHQUFHLEtBQUssUUFBUSxDQUFDLEVBQUUsQ0FBQztRQUN4RSxPQUFPO1lBQ0wsUUFBUSxFQUFFLFFBQVEsSUFBSSxJQUFJLENBQUMsR0FBRztZQUM5QixNQUFNLEVBQUUsTUFBTTtZQUNkLFVBQVUsRUFBRTtnQkFDVixHQUFHLElBQUk7Z0JBQ1AsU0FBUyxFQUFFLGdCQUFnQixDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsaUJBQWlCO2FBQ3hFO1NBQ0YsQ0FBQztJQUNKLENBQUM7SUFFRCxJQUFJLFFBQVEsS0FBSyxJQUFJLEVBQUUsQ0FBQztRQUN0QixPQUFPO1lBQ0wsUUFBUTtZQUNSLE1BQU0sRUFBRSxXQUFXO1lBQ25CLFVBQVUsRUFBRSx3QkFBd0IsQ0FBQyxJQUFJLEVBQUUsUUFBUSxDQUFDO1NBQ3JELENBQUM7SUFDSixDQUFDO0lBRUQsT0FBTyxFQUFFLFVBQVUsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLENBQUM7QUFDOUQsQ0FBQztBQU1ELE1BQU0sQ0FBQyxLQUFLLFVBQVUsd0JBQXdCLENBQzVDLGlCQUFvQyxFQUNwQyxJQUFZLEVBQ1osU0FBd0IsRUFDeEIsT0FBd0MsRUFBRTtJQUUxQyxNQUFNLGtCQUFrQixHQUFHLElBQUksQ0FBQyxrQkFBa0IsSUFBSSxjQUFjLENBQUM7SUFDckUsTUFBTSxvQkFBb0IsR0FBRyxJQUFJLENBQUMsb0JBQW9CLElBQUksZ0JBQWdCLENBQUM7SUFDM0UsTUFBTSxDQUFDLElBQUksQ0FBQyxpREFBaUQsRUFBRTtRQUM3RCxvQkFBb0IsRUFBRSxpQkFBaUIsQ0FBQyxTQUFTO1FBQ2pELGNBQWMsRUFBRSxpQkFBaUIsQ0FBQyxHQUFHO1FBQ3JDLElBQUk7S0FDTCxDQUFDLENBQUM7SUFFSCxJQUFJLFFBQVEsR0FBRyxNQUFNLHlCQUF5QixDQUFDLElBQUksRUFBRSxTQUFTLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDdEUsSUFBSSxvQkFBb0IsR0FBRyxLQUFLLENBQUM7SUFDakMsSUFBSSxvQkFBb0IsR0FBRyxLQUFLLENBQUM7SUFDakMsTUFBTSxXQUFXLEdBQUcsTUFBTSxrQkFBa0IsRUFBRSxDQUFDO0lBQy9DLE1BQU0sc0JBQXNCLEdBQUcsQ0FDN0IsV0FBVyxFQUFFLEdBQUcsS0FBSyxpQkFBaUIsQ0FBQyxHQUFHO1FBQzFDLFdBQVcsQ0FBQyxJQUFJLEtBQUssaUJBQWlCLENBQUMsSUFBSTtRQUMzQyxXQUFXLENBQUMsU0FBUyxLQUFLLGlCQUFpQixDQUFDLFNBQVMsQ0FDdEQsQ0FBQztJQUNGLE1BQU0saUNBQWlDLEdBQUcsQ0FDeEMsUUFBUSxDQUFDLFVBQVUsRUFBRSxHQUFHLEtBQUssaUJBQWlCLENBQUMsR0FBRztRQUNsRCxRQUFRLENBQUMsVUFBVSxDQUFDLElBQUksS0FBSyxpQkFBaUIsQ0FBQyxJQUFJO1FBQ25ELFFBQVEsQ0FBQyxVQUFVLENBQUMsU0FBUyxLQUFLLGlCQUFpQixDQUFDLFNBQVMsQ0FDOUQsQ0FBQztJQUVGLElBQUksc0JBQXNCLEVBQUUsQ0FBQztRQUMzQixvQkFBb0IsR0FBRyxJQUFJLENBQUM7UUFDNUIsTUFBTSxvQkFBb0IsRUFBRSxDQUFDO1FBQzdCLG9CQUFvQixHQUFHLElBQUksQ0FBQztRQUM1QixNQUFNLENBQUMsSUFBSSxDQUFDLHFFQUFxRSxFQUFFO1lBQ2pGLG9CQUFvQixFQUFFLGlCQUFpQixDQUFDLFNBQVM7WUFDakQsY0FBYyxFQUFFLGlCQUFpQixDQUFDLEdBQUc7WUFDckMsSUFBSTtTQUNMLENBQUMsQ0FBQztRQUNILElBQUksaUNBQWlDLEVBQUUsQ0FBQztZQUN0QyxRQUFRLEdBQUcsTUFBTSx5QkFBeUIsQ0FBQyxJQUFJLEVBQUUsU0FBUyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ3BFLENBQUM7SUFDSCxDQUFDO0lBRUQsTUFBTSxDQUFDLElBQUksQ0FBQyxpREFBaUQsRUFBRTtRQUM3RCxvQkFBb0IsRUFBRSxpQkFBaUIsQ0FBQyxTQUFTO1FBQ2pELGNBQWMsRUFBRSxpQkFBaUIsQ0FBQyxHQUFHO1FBQ3JDLElBQUk7UUFDSixlQUFlLEVBQUUsUUFBUSxDQUFDLE1BQU07UUFDaEMsUUFBUSxFQUFFLFFBQVEsQ0FBQyxRQUFRO1FBQzNCLG9CQUFvQjtRQUNwQixvQkFBb0I7S0FDckIsQ0FBQyxDQUFDO0lBRUgsT0FBTztRQUNMLEdBQUcsUUFBUTtRQUNYLG9CQUFvQjtRQUNwQixvQkFBb0I7S0FDckIsQ0FBQztBQUNKLENBQUM7QUFFRDs7Ozs7R0FLRztBQUNILE1BQU0sQ0FBQyxLQUFLLFVBQVUsbUJBQW1CLENBQUMsT0FBOEI7SUFDdEUsMERBQTBEO0lBQzFELE1BQU0sV0FBVyxHQUFHLE9BQU8sQ0FBQyxJQUFJLElBQUksb0JBQW9CLENBQUM7SUFDekQsTUFBTSxDQUFDLEtBQUssQ0FBQyxtQ0FBbUMsV0FBVyxFQUFFO1FBQzNELENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMscUJBQXFCLENBQUMsQ0FBQyxDQUFDLHFCQUFxQixDQUFDLENBQUMsQ0FBQztJQUVsRSxnRUFBZ0U7SUFDaEUsb0VBQW9FO0lBQ3BFLHdFQUF3RTtJQUN4RSx3RUFBd0U7SUFDeEUsd0NBQXdDO0lBQ3hDLE1BQU0sMEJBQTBCLENBQUMsV0FBVyxDQUFDLENBQUM7SUFFOUMsSUFBSSxRQUFRLEdBQUcsTUFBTSxXQUFXLENBQUMsT0FBTyxDQUFDLFNBQVMsRUFBRSxXQUFXLENBQUMsQ0FBQztJQUVqRSxrRkFBa0Y7SUFDbEYscUVBQXFFO0lBQ3JFLG9FQUFvRTtJQUNwRSxJQUFJLFFBQVEsQ0FBQyxJQUFJLEtBQUssVUFBVSxFQUFFLENBQUM7UUFDakMsTUFBTSxTQUFTLEdBQUcsTUFBTSwyQkFBMkIsQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDekUsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBQ2YsUUFBUSxHQUFHLE1BQU0sb0JBQW9CLENBQUMsT0FBTyxDQUFDLFNBQVMsRUFBRSxXQUFXLENBQUMsQ0FBQztRQUN4RSxDQUFDO0lBQ0gsQ0FBQztJQUVELElBQUksUUFBUSxDQUFDLElBQUksS0FBSyxRQUFRLEVBQUUsQ0FBQztRQUMvQixPQUFPLGFBQWEsQ0FBQyxPQUFPLEVBQUUsUUFBUSxFQUFFLFdBQVcsQ0FBQyxDQUFDO0lBQ3ZELENBQUM7U0FBTSxDQUFDO1FBQ04sT0FBTyxlQUFlLENBQUMsT0FBTyxFQUFFLFFBQVEsRUFBRSxXQUFXLENBQUMsQ0FBQztJQUN6RCxDQUFDO0FBQ0gsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxLQUFLLFVBQVUsYUFBYSxDQUMxQixPQUE4QixFQUM5QixRQUF3QixFQUN4QixjQUFzQixvQkFBb0I7SUFFMUMsTUFBTSxFQUFFLGNBQWMsRUFBRSxHQUFHLE1BQU0sTUFBTSxDQUFDLGNBQWMsQ0FBQyxDQUFDO0lBQ3hELE1BQU0sRUFBRSxtQkFBbUIsRUFBRSxHQUFHLE1BQU0sTUFBTSxDQUFDLG1CQUFtQixDQUFDLENBQUM7SUFFbEUsd0VBQXdFO0lBQ3hFLHdFQUF3RTtJQUN4RSwyRUFBMkU7SUFDM0UseUVBQXlFO0lBQ3pFLHVFQUF1RTtJQUN2RSxNQUFNLFVBQVUsR0FBRyxJQUFJLGlCQUFpQixDQUFDLEdBQUcsQ0FBQyw0QkFBNEIsQ0FBQyxDQUFDO0lBQzNFLE1BQU0sWUFBWSxHQUFHLE1BQU0sVUFBVSxDQUFDLGlCQUFpQixDQUFDLG1CQUFtQixFQUFFLENBQUMsQ0FBQztJQUMvRSxNQUFNLENBQUMsSUFBSSxDQUFDLGtEQUFrRCxFQUFFO1FBQzlELE9BQU8sRUFBRSxZQUFZLENBQUMsRUFBRTtRQUN4QixTQUFTLEVBQUUsWUFBWSxDQUFDLElBQUk7UUFDNUIsSUFBSSxFQUFFLFVBQVUsQ0FBQyxXQUFXLEVBQUU7UUFDOUIsWUFBWSxFQUFFLEdBQUcsQ0FBQywwQkFBMEI7S0FDN0MsQ0FBQyxDQUFDO0lBRUgsZ0ZBQWdGO0lBQ2hGLElBQUksYUFBNkQsQ0FBQztJQUNsRSxJQUFJLHFCQUF1RSxDQUFDO0lBRTVFLGdGQUFnRjtJQUNoRixNQUFNLFlBQVksR0FBRyxrQkFBa0IsQ0FBQztRQUN0QyxZQUFZLEVBQUUsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLGFBQWEsRUFBRSxDQUFDLEtBQUssQ0FBQztRQUMvQyxpQkFBaUIsRUFBRSxDQUFDLFFBQVEsRUFBRSxFQUFFLENBQUMscUJBQXFCLEVBQUUsQ0FBQyxRQUFRLENBQUM7UUFDbEUsb0JBQW9CLEVBQUUsQ0FBQyxRQUFRLEVBQUUsRUFBRSxDQUFDLE9BQU8sQ0FBQyxXQUFXLEVBQUUsVUFBVSxDQUFDLFFBQVEsQ0FBQztLQUM5RSxDQUFDLENBQUM7SUFFSCwyRUFBMkU7SUFDM0UsOEVBQThFO0lBQzlFLE1BQU0sVUFBVSxHQUFHO1FBQ2pCLFlBQVksRUFBRSxPQUFPLENBQUMsWUFBWTtRQUNsQyxVQUFVLEVBQUUsT0FBTyxDQUFDLFVBQVU7UUFDOUIsV0FBVyxFQUFFLE9BQU8sQ0FBQyxXQUFXO1FBQ2hDLElBQUksRUFBRSxXQUFXO1FBQ2pCLGlCQUFpQixFQUFFLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQztRQUN4QyxVQUFVO1FBQ1YsR0FBRyxDQUFDLE9BQU8sQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLEVBQUUsYUFBYSxFQUFFLE9BQU8sQ0FBQyxhQUFhLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO0tBQzNFLENBQUM7SUFDRix3RUFBd0U7SUFDeEUscUVBQXFFO0lBQ3JFLE1BQU0sU0FBUyxHQUFHLE1BQU0sY0FBYyxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBRW5ELElBQUksU0FBUyxDQUFDLFVBQVUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDMUQsTUFBTSxRQUFRLEdBQUcsTUFBTSx3QkFBd0IsQ0FBQyxRQUFRLENBQUMsVUFBVSxFQUFFLFdBQVcsRUFBRSxZQUFZLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDdEcsSUFBSSxRQUFRLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDeEIsTUFBTSxDQUFDLElBQUksQ0FBQyw2RUFBNkUsRUFBRTtnQkFDekYsSUFBSSxFQUFFLFdBQVc7Z0JBQ2pCLFNBQVMsRUFBRSxTQUFTLENBQUMsVUFBVSxDQUFDLEtBQUs7Z0JBQ3JDLFVBQVUsRUFBRSxTQUFTLENBQUMsVUFBVSxDQUFDLE1BQU07Z0JBQ3ZDLG9CQUFvQixFQUFFLFFBQVEsQ0FBQyxVQUFVLENBQUMsR0FBRztnQkFDN0MsMEJBQTBCLEVBQUUsUUFBUSxDQUFDLFVBQVUsQ0FBQyxTQUFTO2dCQUN6RCxRQUFRLEVBQUUsUUFBUSxDQUFDLFFBQVE7Z0JBQzNCLE1BQU0sRUFBRSxRQUFRLENBQUMsTUFBTTtnQkFDdkIsb0JBQW9CLEVBQUUsUUFBUSxDQUFDLG9CQUFvQjtnQkFDbkQsb0JBQW9CLEVBQUUsUUFBUSxDQUFDLG9CQUFvQjthQUNwRCxDQUFDLENBQUM7WUFDSCxNQUFNLGdCQUFnQixHQUFtQixFQUFFLElBQUksRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLFFBQVEsQ0FBQyxVQUFVLEVBQUUsQ0FBQztZQUMvRixPQUFPLGVBQWUsQ0FBQyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsV0FBVyxFQUFFLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNyRixDQUFDO1FBRUQsTUFBTSxDQUFDLEtBQUssQ0FBQyxpRkFBaUYsRUFBRTtZQUM5RixJQUFJLEVBQUUsV0FBVztZQUNqQixvQkFBb0IsRUFBRSxRQUFRLENBQUMsVUFBVSxDQUFDLEdBQUc7WUFDN0MsU0FBUyxFQUFFLFNBQVMsQ0FBQyxVQUFVLENBQUMsS0FBSztZQUNyQyxVQUFVLEVBQUUsU0FBUyxDQUFDLFVBQVUsQ0FBQyxNQUFNO1NBQ3hDLENBQUMsQ0FBQztRQUNILE1BQU0sSUFBSSxLQUFLLENBQUMsOEJBQThCLFdBQVcsd0NBQXdDLENBQUMsQ0FBQztJQUNyRyxDQUFDO0lBRUQsaUZBQWlGO0lBQ2pGLFlBQVksQ0FBQyxxQkFBcUIsQ0FBQyxPQUFPLENBQUMsU0FBUyxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUVuRSxrRkFBa0Y7SUFDbEYsWUFBWSxDQUFDLHNCQUFzQixFQUFFLENBQUM7SUFFdEMsbURBQW1EO0lBQ25ELE9BQU8sQ0FBQyxpQkFBaUIsQ0FBQyxTQUFTLEVBQUUsT0FBTyxDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBRTFELCtEQUErRDtJQUMvRCxJQUFJLFNBQVMsQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUMzQixNQUFNLGlCQUFpQixHQUFHLFNBQVMsQ0FBQyxZQUFZLENBQUM7UUFDakQsNkNBQTZDO1FBQzdDLGFBQWEsR0FBRyxDQUFDLEtBQXNCLEVBQUUsRUFBRTtZQUN6QyxNQUFNLE9BQU8sR0FBb0I7Z0JBQy9CLEdBQUcsS0FBSztnQkFDUixJQUFJLEVBQUUsRUFBRSxHQUFHLEtBQUssQ0FBQyxJQUFJLEVBQUUsVUFBVSxFQUFFLE9BQU8sQ0FBQyxTQUFTLEVBQUU7YUFDdkQsQ0FBQztZQUNGLGlCQUFpQixDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQzdCLENBQUMsQ0FBQztJQUNKLENBQUM7SUFDRCxxQkFBcUIsR0FBRyxTQUFTLENBQUMsaUJBQWlCLENBQUM7SUFFcEQsTUFBTSxDQUFDLElBQUksQ0FBQywyQ0FBMkMsQ0FBQyxDQUFDO0lBRXpELHVDQUF1QztJQUN2QyxNQUFNLGFBQWEsR0FBRyxjQUFjLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQzFELHFCQUFxQixFQUFFLENBQUM7SUFFeEIsTUFBTSxDQUFDLElBQUksQ0FBQyxpQ0FBaUMsRUFBRTtRQUM3QyxTQUFTLEVBQUUsT0FBTyxDQUFDLFNBQVMsRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFFLEdBQUcsRUFBRSxPQUFPLENBQUMsR0FBRztRQUNqRSxJQUFJLEVBQUUsUUFBUSxFQUFFLFlBQVksRUFBRSxDQUFDLGtCQUFrQixFQUFFLHFCQUFxQixFQUFFLHFCQUFxQixFQUFFLGVBQWUsQ0FBQztLQUNsSCxDQUFDLENBQUM7SUFFSCxPQUFPO1FBQ0wsSUFBSSxFQUFFLFFBQVE7UUFDZCxRQUFRO1FBQ1IsSUFBSSxFQUFFLFdBQVc7UUFDakIsT0FBTyxFQUFFLEtBQUssSUFBSSxFQUFFO1lBQ2xCLGFBQWEsRUFBRSxDQUFDO1FBQ2xCLENBQUM7S0FDRixDQUFDO0FBQ0osQ0FBQztBQUVEOzs7R0FHRztBQUNILEtBQUssVUFBVSxlQUFlLENBQzVCLE9BQThCLEVBQzlCLFFBQXdCLEVBQ3hCLGNBQXNCLG9CQUFvQixFQUMxQyxtQkFBa0MsSUFBSTtJQUV0QyxNQUFNLFNBQVMsR0FBRyxvQkFBb0IsUUFBUSxDQUFDLFVBQVUsQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUVqRSx5RUFBeUU7SUFDekUsdUVBQXVFO0lBQ3ZFLDBFQUEwRTtJQUMxRSxJQUFJLFNBQVMsR0FBRyxnQkFBZ0IsQ0FBQztJQUNqQyxJQUFJLFNBQVMsS0FBSyxJQUFJLEVBQUUsQ0FBQztRQUN2QixNQUFNLEVBQUUsdUJBQXVCLEVBQUUsR0FBRyxNQUFNLE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO1FBQ3RFLFNBQVMsR0FBRyxNQUFNLHVCQUF1QixDQUFDLEdBQUcsQ0FBQyw0QkFBNEIsQ0FBQyxDQUFDO0lBQzlFLENBQUM7SUFDRCxJQUFJLFNBQVMsRUFBRSxDQUFDO1FBQ2QsTUFBTSxDQUFDLEtBQUssQ0FBQyxxREFBcUQsQ0FBQyxDQUFDO0lBQ3RFLENBQUM7U0FBTSxDQUFDO1FBQ04sTUFBTSxDQUFDLEtBQUssQ0FBQyw2RkFBNkYsQ0FBQyxDQUFDO0lBQzlHLENBQUM7SUFFRCxxRUFBcUU7SUFDckUsMEVBQTBFO0lBQzFFLE1BQU0sWUFBWSxHQUFHLElBQUksZ0JBQWdCLENBQUMsT0FBTyxFQUFFLFdBQVcsRUFBRSxhQUFhLEVBQUUsZUFBZSxDQUFDLENBQUM7SUFFaEcsMEVBQTBFO0lBQzFFLDBGQUEwRjtJQUMxRixJQUFJLGdCQUFrQyxDQUFDO0lBRXZDLHFFQUFxRTtJQUNyRSxNQUFNLGNBQWMsR0FBRyxJQUFJLHVCQUF1QixDQUFDLFNBQVMsRUFBRSxPQUFPLENBQUMsU0FBUyxFQUFFLFNBQVMsRUFBRSxHQUFHLEVBQUU7UUFDL0YsWUFBWSxDQUFDLE9BQU8sQ0FBQyxjQUFjLEVBQUUsZ0JBQWdCLENBQUM7YUFDbkQsS0FBSyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxvQ0FBb0MsRUFBRSxFQUFFLEtBQUssRUFBRSxNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDOUYsQ0FBQyxDQUFDLENBQUM7SUFDSCxPQUFPLENBQUMsZUFBZSxDQUFDLGNBQWMsQ0FBQyxDQUFDO0lBRXhDLHdDQUF3QztJQUN4QyxnQkFBZ0IsR0FBRyxJQUFJLGdCQUFnQixDQUFDLFNBQVMsRUFBRSxPQUFPLENBQUMsU0FBUyxFQUFFLE9BQU8sQ0FBQyxHQUFHLEVBQUUsU0FBUyxDQUFDLENBQUM7SUFDOUYsTUFBTSxnQkFBZ0IsQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUUvQixNQUFNLENBQUMsSUFBSSxDQUFDLG1DQUFtQyxFQUFFO1FBQy9DLFNBQVMsRUFBRSxPQUFPLENBQUMsU0FBUyxFQUFFLEdBQUcsRUFBRSxPQUFPLENBQUMsR0FBRyxFQUFFLElBQUksRUFBRSxVQUFVO1FBQ2hFLGFBQWEsRUFBRSxRQUFRLENBQUMsVUFBVSxDQUFDLFNBQVMsRUFBRSxTQUFTLEVBQUUsUUFBUSxDQUFDLFVBQVUsQ0FBQyxHQUFHO1FBQ2hGLFVBQVUsRUFBRSxRQUFRLENBQUMsVUFBVSxDQUFDLElBQUksRUFBRSxTQUFTO0tBQ2hELENBQUMsQ0FBQztJQUVILE9BQU87UUFDTCxJQUFJLEVBQUUsVUFBVTtRQUNoQixRQUFRO1FBQ1IsT0FBTyxFQUFFLEtBQUssSUFBSSxFQUFFO1lBQ2xCLE1BQU0sZ0JBQWdCLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDOUIsTUFBTSxjQUFjLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDL0IsQ0FBQztLQUNGLENBQUM7QUFDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBVbmlmaWVkIHdlYiBjb25zb2xlIG9yY2hlc3RyYXRvci5cbiAqXG4gKiBUaWVzIHRvZ2V0aGVyIGxlYWRlciBlbGVjdGlvbiwgY29uc29sZSBzdGFydHVwLCBmb2xsb3dlciB3aXJpbmcsXG4gKiBhbmQgc2Vzc2lvbiBsaWZlY3ljbGUgbWFuYWdlbWVudC4gVGhpcyBpcyB0aGUgbWFpbiBlbnRyeSBwb2ludFxuICogY2FsbGVkIGJ5IHRoZSBESSBjb250YWluZXIgZHVyaW5nIGRlZmVycmVkIHNldHVwLlxuICpcbiAqIEZsb3c6XG4gKiAxLiBSdW4gbGVhZGVyIGVsZWN0aW9uIChyZWFkIGxvY2sgZmlsZSwgY2xhaW0gb3IgZm9sbG93KVxuICogMi4gSWYgbGVhZGVyOiBzdGFydCB3ZWIgc2VydmVyIG9uIGZpeGVkIHBvcnQsIG1vdW50IGluZ2VzdCByb3V0ZXMsIHN0YXJ0IGhlYXJ0YmVhdFxuICogMy4gSWYgZm9sbG93ZXI6IHJlZ2lzdGVyIGZvcndhcmRpbmcgc2lua3Mgd2l0aCBMb2dNYW5hZ2VyLCBzdGFydCBzZXNzaW9uIGhlYXJ0YmVhdFxuICpcbiAqIEBzaW5jZSB2Mi4xLjAg4oCUIElzc3VlICMxNzAwXG4gKi9cblxuaW1wb3J0IHR5cGUgeyBVbmlmaWVkTG9nRW50cnkgfSBmcm9tICcuLi8uLi9sb2dnaW5nL3R5cGVzLmpzJztcbmltcG9ydCB0eXBlIHsgTWV0cmljU25hcHNob3QgfSBmcm9tICcuLi8uLi9tZXRyaWNzL3R5cGVzLmpzJztcbmltcG9ydCB0eXBlIHsgTWVtb3J5TG9nU2luayB9IGZyb20gJy4uLy4uL2xvZ2dpbmcvc2lua3MvTWVtb3J5TG9nU2luay5qcyc7XG5pbXBvcnQgdHlwZSB7IE1lbW9yeU1ldHJpY3NTaW5rIH0gZnJvbSAnLi4vLi4vbWV0cmljcy9zaW5rcy9NZW1vcnlNZXRyaWNzU2luay5qcyc7XG5pbXBvcnQgeyBVbmljb2RlVmFsaWRhdG9yIH0gZnJvbSAnLi4vLi4vc2VjdXJpdHkvdmFsaWRhdG9ycy91bmljb2RlVmFsaWRhdG9yLmpzJztcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gJy4uLy4uL3V0aWxzL2xvZ2dlci5qcyc7XG5pbXBvcnQge1xuICBlbGVjdExlYWRlcixcbiAgaXNMZWFkZXJXZWJDb25zb2xlUmVhY2hhYmxlLFxuICBmb3JjZUNsYWltTGVhZGVyc2hpcCxcbiAgc3RhcnRIZWFydGJlYXQsXG4gIHJlZ2lzdGVyTGVhZGVyQ2xlYW51cCxcbiAgZGV0ZWN0TGVnYWN5TGVhZGVyLFxuICByZWFkTGVhZGVyTG9jayxcbiAgZGVsZXRlTGVhZGVyTG9jayxcbiAgTE9DS19WRVJTSU9OLFxuICBDT05TT0xFX1BST1RPQ09MX1ZFUlNJT04sXG4gIExFR0FDWV9TRVJWRVJfVkVSU0lPTixcbiAgdHlwZSBFbGVjdGlvblJlc3VsdCxcbiAgdHlwZSBDb25zb2xlTGVhZGVySW5mbyxcbn0gZnJvbSAnLi9MZWFkZXJFbGVjdGlvbi5qcyc7XG5pbXBvcnQgeyBjcmVhdGVJbmdlc3RSb3V0ZXMgfSBmcm9tICcuL0luZ2VzdFJvdXRlcy5qcyc7XG5pbXBvcnQge1xuICBMZWFkZXJGb3J3YXJkaW5nTG9nU2luayxcbiAgU2Vzc2lvbkhlYXJ0YmVhdCxcbn0gZnJvbSAnLi9MZWFkZXJGb3J3YXJkaW5nU2luay5qcyc7XG5pbXBvcnQgeyBQcm9tb3Rpb25NYW5hZ2VyIH0gZnJvbSAnLi9Qcm9tb3Rpb25NYW5hZ2VyLmpzJztcbmltcG9ydCB7IENvbnNvbGVUb2tlblN0b3JlIH0gZnJvbSAnLi9jb25zb2xlVG9rZW4uanMnO1xuaW1wb3J0IHsgZmluZFBpZE9uUG9ydCB9IGZyb20gJy4vU3RhbGVQcm9jZXNzUmVjb3ZlcnkuanMnO1xuaW1wb3J0IHsgZW52IH0gZnJvbSAnLi4vLi4vY29uZmlnL2Vudi5qcyc7XG5cbi8qKlxuICogRGVmYXVsdCBjb25zb2xlIHBvcnQgZnJvbSB0aGUgZW52IHZhci4gVXNlZCBhcyBmYWxsYmFjayB3aGVuIG5vIHBvcnRcbiAqIGlzIHByb3ZpZGVkIHZpYSBjb25maWcgZmlsZSBvciBvcHRpb25zLiBUaGUgcmVzb2x1dGlvbiBoaWVyYXJjaHkgaXM6XG4gKiAgIDEuIG9wdGlvbnMucG9ydCAoZnJvbSBjb25maWcgZmlsZSwgcmVzb2x2ZWQgYnkgdGhlIERJIGNvbnRhaW5lcilcbiAqICAgMi4gRE9MTEhPVVNFX1dFQl9DT05TT0xFX1BPUlQgZW52IHZhclxuICogICAzLiA0MTcxNSAoaGFyZGNvZGVkIGRlZmF1bHQgaW4gZW52LnRzKVxuICovXG5jb25zdCBERUZBVUxUX0NPTlNPTEVfUE9SVCA9IGVudi5ET0xMSE9VU0VfV0VCX0NPTlNPTEVfUE9SVDtcbmNvbnN0IExFR0FDWV9DT05TT0xFX0ZBTExCQUNLX1BPUlQgPSAzOTM5O1xuY29uc3QgU1lOVEhFVElDX1BPUlRfT1dORVJfU0VTU0lPTl9QUkVGSVggPSAncG9ydC1vd25lci0nO1xuXG5mdW5jdGlvbiBjdXJyZW50VGltZXN0YW1wKCk6IHN0cmluZyB7XG4gIHJldHVybiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCk7XG59XG5cbi8qKlxuICogT3B0aW9ucyBmb3Igc3RhcnRpbmcgdGhlIHVuaWZpZWQgY29uc29sZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBVbmlmaWVkQ29uc29sZU9wdGlvbnMge1xuICAvKiogVGhpcyBwcm9jZXNzJ3MgdW5pcXVlIHNlc3Npb24gSUQgKi9cbiAgc2Vzc2lvbklkOiBzdHJpbmc7XG4gIC8qKiBQb3J0Zm9saW8gYmFzZSBkaXJlY3RvcnkgKGZvciBzdGFydFdlYlNlcnZlcikgKi9cbiAgcG9ydGZvbGlvRGlyOiBzdHJpbmc7XG4gIC8qKiBMb2cgbWVtb3J5IHNpbmsgKGZvciBjb25zb2xlIGhpc3RvcnkpICovXG4gIG1lbW9yeVNpbms6IE1lbW9yeUxvZ1Npbms7XG4gIC8qKiBNZXRyaWNzIG1lbW9yeSBzaW5rICovXG4gIG1ldHJpY3NTaW5rPzogTWVtb3J5TWV0cmljc1Npbms7XG4gIC8qKiBNQ1AtQVFMIGhhbmRsZXIgZm9yIHBlcm1pc3Npb24gcm91dGVzICh0eXBlZCBhcyBhbnkgdG8gYXZvaWQgY2lyY3VsYXIgaW1wb3J0cykgKi9cbiAgbWNwQXFsSGFuZGxlcj86IGFueTtcbiAgLyoqIENhbGxiYWNrIHRvIHJlZ2lzdGVyIGEgbG9nIHNpbmsgd2l0aCB0aGUgTG9nTWFuYWdlciAqL1xuICByZWdpc3RlckxvZ1Npbms6IChzaW5rOiB7IHdyaXRlKGVudHJ5OiBVbmlmaWVkTG9nRW50cnkpOiB2b2lkOyBmbHVzaCgpOiBQcm9taXNlPHZvaWQ+OyBjbG9zZSgpOiBQcm9taXNlPHZvaWQ+IH0pID0+IHZvaWQ7XG4gIC8qKiBDYWxsYmFjayB0byB3aXJlIFNTRSBicm9hZGNhc3RzIGFmdGVyIHdlYiBzZXJ2ZXIgc3RhcnRzICovXG4gIHdpcmVTU0VCcm9hZGNhc3RzOiAod2ViUmVzdWx0OiB7IGxvZ0Jyb2FkY2FzdD86IChlbnRyeTogVW5pZmllZExvZ0VudHJ5KSA9PiB2b2lkOyBtZXRyaWNzT25TbmFwc2hvdD86IChzbmFwc2hvdDogTWV0cmljU25hcHNob3QpID0+IHZvaWQgfSwgbWV0cmljc1Npbms/OiBNZW1vcnlNZXRyaWNzU2luaykgPT4gdm9pZDtcbiAgLyoqIENvbnNvbGUgcG9ydCBvdmVycmlkZSBmcm9tIGNvbmZpZyBmaWxlLiBGYWxscyBiYWNrIHRvIGVudiB2YXIgaWYgbm90IHByb3ZpZGVkLiAqL1xuICBwb3J0PzogbnVtYmVyO1xufVxuXG4vKipcbiAqIFJlc3VsdCBvZiBzdGFydGluZyB0aGUgdW5pZmllZCBjb25zb2xlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFVuaWZpZWRDb25zb2xlUmVzdWx0IHtcbiAgcm9sZTogJ2xlYWRlcicgfCAnZm9sbG93ZXInO1xuICBlbGVjdGlvbjogRWxlY3Rpb25SZXN1bHQ7XG4gIC8qKiBQb3J0IHRoZSBjb25zb2xlIGlzIHJ1bm5pbmcgb24gKGxlYWRlciBvbmx5KSAqL1xuICBwb3J0PzogbnVtYmVyO1xuICAvKiogQ2xlYW51cCBmdW5jdGlvbiB0byBjYWxsIG9uIHNodXRkb3duICovXG4gIGNsZWFudXA6ICgpID0+IFByb21pc2U8dm9pZD47XG59XG5cbi8qKlxuICogQ2hlY2sgZm9yIGEgcnVubmluZyBsZWdhY3kgKHByZS1hdXRoZW50aWNhdGlvbikgRG9sbGhvdXNlTUNQIGNvbnNvbGUgYW5kXG4gKiBsb2cgYSBXQVJOLWxldmVsIG1lc3NhZ2UgaWYgb25lIGlzIGZvdW5kICgjMTc5NCkuXG4gKlxuICogRXh0cmFjdGVkIGZyb20gYHN0YXJ0VW5pZmllZENvbnNvbGVgIHNvIHRoZSB3aXJpbmcgY2FuIGJlIGludGVncmF0aW9uLVxuICogdGVzdGVkIGluIGlzb2xhdGlvbiB3aXRob3V0IHNwaW5uaW5nIHVwIGEgZnVsbCB3ZWIgc2VydmVyIGFuZCBsZWFkZXJcbiAqIGVsZWN0aW9uLiBUaGUgaW1wbGVtZW50YXRpb24gaXMgZmlyZS1hbmQtZm9yZ2V0OiBkZXRlY3Rpb24gZmFpbHVyZXNcbiAqIGFyZSBsb2dnZWQgYXQgREVCVUcgYW5kIG5ldmVyIHByb3BhZ2F0ZSwgYmVjYXVzZSBhIGZhaWx1cmUgaGVyZSBtdXN0XG4gKiBub3QgYmxvY2sgbGVhZGVyIGVsZWN0aW9uIG9mIHRoZSBhdXRoZW50aWNhdGVkIGNvbnNvbGUuXG4gKlxuICogQHBhcmFtIGN1cnJlbnRQb3J0IC0gVGhlIHBvcnQgdGhlIGF1dGhlbnRpY2F0ZWQgY29uc29sZSBpbnRlbmRzIHRvXG4gKiAgICAgICAgICAgICAgICAgICAgICBiaW5kIHRvLiBVc2VkIGluIHRoZSB3YXJuaW5nIG1lc3NhZ2UgdG8gaGVscCB0aGVcbiAqICAgICAgICAgICAgICAgICAgICAgIHVzZXIgdGVsbCB0aGUgdHdvIGNvbnNvbGVzIGFwYXJ0LlxuICogQHBhcmFtIGRldGVjdCAgICAgIC0gT3B0aW9uYWwgaW5qZWN0aW9uIHBvaW50IGZvciB0aGUgZGV0ZWN0aW9uXG4gKiAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbi4gRGVmYXVsdHMgdG8gYGRldGVjdExlZ2FjeUxlYWRlcmAuIFRlc3RzXG4gKiAgICAgICAgICAgICAgICAgICAgICBwYXNzIGEgc3R1Yi5cbiAqIEBwYXJhbSBsb2cgICAgICAgICAtIE9wdGlvbmFsIGluamVjdGlvbiBwb2ludCBmb3IgdGhlIGxvZ2dlci4gRGVmYXVsdHNcbiAqICAgICAgICAgICAgICAgICAgICAgIHRvIHRoZSBtb2R1bGUgbG9nZ2VyLiBUZXN0cyBwYXNzIGEgc3B5LlxuICogQHJldHVybnMgVGhlIGxlZ2FjeSBsZWFkZXIgaW5mbyBmcm9tIGBkZXRlY3QoKWAsIG9yIG51bGwgaWYgZGV0ZWN0aW9uXG4gKiAgICAgICAgICB0aHJldy4gRXhwb3NlZCBzbyB0ZXN0cyBjYW4gYXNzZXJ0IHRoZSBmdWxsIHJlc3VsdCBzaGFwZS5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHdhcm5JZkxlZ2FjeUNvbnNvbGVQcmVzZW50KFxuICBjdXJyZW50UG9ydDogbnVtYmVyLFxuICBkZXRlY3Q6IHR5cGVvZiBkZXRlY3RMZWdhY3lMZWFkZXIgPSBkZXRlY3RMZWdhY3lMZWFkZXIsXG4gIGxvZzogdHlwZW9mIGxvZ2dlciA9IGxvZ2dlcixcbik6IFByb21pc2U8QXdhaXRlZDxSZXR1cm5UeXBlPHR5cGVvZiBkZXRlY3RMZWdhY3lMZWFkZXI+PiB8IG51bGw+IHtcbiAgdHJ5IHtcbiAgICBjb25zdCBsZWdhY3kgPSBhd2FpdCBkZXRlY3QoKTtcbiAgICBpZiAobGVnYWN5LmxlZ2FjeVJ1bm5pbmcpIHtcbiAgICAgIGxvZy53YXJuKFxuICAgICAgICBgW1VuaWZpZWRDb25zb2xlXSBMZWdhY3kgKHByZS1hdXRoZW50aWNhdGlvbikgRG9sbGhvdXNlTUNQIGNvbnNvbGUgZGV0ZWN0ZWQgYCArXG4gICAgICAgIGAocGlkPSR7bGVnYWN5LnBpZH0sIHBvcnQ9JHtsZWdhY3kucG9ydH0pLiBCb3RoIGNvbnNvbGVzIHdpbGwgcnVuIGAgK1xuICAgICAgICBgaW5kZXBlbmRlbnRseSBvbiBkaWZmZXJlbnQgcG9ydHMgd2l0aCBkaWZmZXJlbnQgc2VjdXJpdHkgcG9zdHVyZS4gYCArXG4gICAgICAgIGBUaGUgYXV0aGVudGljYXRlZCBjb25zb2xlICh0aGlzIHByb2Nlc3MpIHVzZXMgcG9ydCAke2N1cnJlbnRQb3J0fTsgYCArXG4gICAgICAgIGB0aGUgbGVnYWN5IGNvbnNvbGUgdXNlcyBwb3J0ICR7bGVnYWN5LnBvcnQgPz8gTEVHQUNZX0NPTlNPTEVfRkFMTEJBQ0tfUE9SVH0uIGAgK1xuICAgICAgICBgRm9yIGNvbnNpc3RlbnQgc2VjdXJpdHksIHVwZGF0ZSB0aGUgbGVnYWN5IGluc3RhbGxhdGlvbiB0byBhIGAgK1xuICAgICAgICBgdmVyc2lvbiB3aXRoIHRoZSBhdXRoZW50aWNhdGVkIGNvbnNvbGUuYCxcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiBsZWdhY3k7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIC8vIEJlc3QtZWZmb3J0IOKAlCBuZXZlciBibG9jayBlbGVjdGlvbiBvbiBhIGRldGVjdGlvbiBmYWlsdXJlXG4gICAgbG9nLmRlYnVnKCdbVW5pZmllZENvbnNvbGVdIExlZ2FjeSBsZWFkZXIgZGV0ZWN0aW9uIGZhaWxlZCcsIHtcbiAgICAgIGVycm9yOiBlcnIgaW5zdGFuY2VvZiBFcnJvciA/IGVyci5tZXNzYWdlIDogU3RyaW5nKGVyciksXG4gICAgfSk7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbn1cblxuaW50ZXJmYWNlIFNlc3Npb25BcGlSZWNvcmQge1xuICBzZXNzaW9uSWQ6IHN0cmluZztcbiAgcGlkOiBudW1iZXI7XG4gIHN0YXJ0ZWRBdD86IHN0cmluZztcbiAgbGFzdEhlYXJ0YmVhdD86IHN0cmluZztcbiAgc3RhdHVzPzogc3RyaW5nO1xuICBpc0xlYWRlcj86IGJvb2xlYW47XG4gIGtpbmQ/OiBzdHJpbmc7XG4gIHNlcnZlclZlcnNpb24/OiBzdHJpbmc7XG4gIGNvbnNvbGVQcm90b2NvbFZlcnNpb24/OiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUG9ydExlYWRlckRpc2NvdmVyeSB7XG4gIGxlYWRlckluZm86IENvbnNvbGVMZWFkZXJJbmZvIHwgbnVsbDtcbiAgb3duZXJQaWQ6IG51bWJlciB8IG51bGw7XG4gIHNvdXJjZTogJ2FwaScgfCAnbG9jaycgfCAnc3ludGhldGljJyB8ICdub25lJztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBCaW5kRmFpbHVyZVJlY292ZXJ5UmVzdWx0IGV4dGVuZHMgUG9ydExlYWRlckRpc2NvdmVyeSB7XG4gIGxvY2tDbGVhbnVwQXR0ZW1wdGVkOiBib29sZWFuO1xuICBsb2NrQ2xlYW51cFBlcmZvcm1lZDogYm9vbGVhbjtcbn1cblxuaW50ZXJmYWNlIERpc2NvdmVyeURlcGVuZGVuY2llcyB7XG4gIGZldGNoSW1wbD86IHR5cGVvZiBmZXRjaDtcbiAgZmluZFBpZE9uUG9ydEltcGw/OiB0eXBlb2YgZmluZFBpZE9uUG9ydDtcbiAgcmVhZExlYWRlckxvY2tJbXBsPzogdHlwZW9mIHJlYWRMZWFkZXJMb2NrO1xufVxuXG5mdW5jdGlvbiBidWlsZERpc2NvdmVyeUhlYWRlcnMoYXV0aFRva2VuOiBzdHJpbmcgfCBudWxsKTogUmVjb3JkPHN0cmluZywgc3RyaW5nPiB7XG4gIHJldHVybiBhdXRoVG9rZW4gPyB7IEF1dGhvcml6YXRpb246IGBCZWFyZXIgJHthdXRoVG9rZW59YCB9IDoge307XG59XG5cbmZ1bmN0aW9uIGJ1aWxkTGVhZGVySW5mb0Zyb21TZXNzaW9uKHBvcnQ6IG51bWJlciwgb3duZXJQaWQ6IG51bWJlciwgbGVhZGVyU2Vzc2lvbjogU2Vzc2lvbkFwaVJlY29yZCk6IENvbnNvbGVMZWFkZXJJbmZvIHtcbiAgcmV0dXJuIHtcbiAgICB2ZXJzaW9uOiBMT0NLX1ZFUlNJT04sXG4gICAgcGlkOiBvd25lclBpZCxcbiAgICBwb3J0LFxuICAgIHNlc3Npb25JZDogVW5pY29kZVZhbGlkYXRvci5ub3JtYWxpemUobGVhZGVyU2Vzc2lvbi5zZXNzaW9uSWQpLm5vcm1hbGl6ZWRDb250ZW50LFxuICAgIHN0YXJ0ZWRBdDogbGVhZGVyU2Vzc2lvbi5zdGFydGVkQXQgPz8gY3VycmVudFRpbWVzdGFtcCgpLFxuICAgIGhlYXJ0YmVhdDogbGVhZGVyU2Vzc2lvbi5sYXN0SGVhcnRiZWF0ID8/IGN1cnJlbnRUaW1lc3RhbXAoKSxcbiAgICBzZXJ2ZXJWZXJzaW9uOiBsZWFkZXJTZXNzaW9uLnNlcnZlclZlcnNpb24gPz8gTEVHQUNZX1NFUlZFUl9WRVJTSU9OLFxuICAgIGNvbnNvbGVQcm90b2NvbFZlcnNpb246IGxlYWRlclNlc3Npb24uY29uc29sZVByb3RvY29sVmVyc2lvbiA/PyBDT05TT0xFX1BST1RPQ09MX1ZFUlNJT04sXG4gIH07XG59XG5cbmZ1bmN0aW9uIGJ1aWxkU3ludGhldGljTGVhZGVySW5mbyhwb3J0OiBudW1iZXIsIG93bmVyUGlkOiBudW1iZXIpOiBDb25zb2xlTGVhZGVySW5mbyB7XG4gIGNvbnN0IG5vdyA9IGN1cnJlbnRUaW1lc3RhbXAoKTtcbiAgcmV0dXJuIHtcbiAgICB2ZXJzaW9uOiBMT0NLX1ZFUlNJT04sXG4gICAgcGlkOiBvd25lclBpZCxcbiAgICBwb3J0LFxuICAgIHNlc3Npb25JZDogYCR7U1lOVEhFVElDX1BPUlRfT1dORVJfU0VTU0lPTl9QUkVGSVh9JHtvd25lclBpZH1gLFxuICAgIHN0YXJ0ZWRBdDogbm93LFxuICAgIGhlYXJ0YmVhdDogbm93LFxuICAgIHNlcnZlclZlcnNpb246IExFR0FDWV9TRVJWRVJfVkVSU0lPTixcbiAgICBjb25zb2xlUHJvdG9jb2xWZXJzaW9uOiBDT05TT0xFX1BST1RPQ09MX1ZFUlNJT04sXG4gIH07XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGRpc2NvdmVyTGVhZGVyVmlhU2Vzc2lvbnNBcGkoXG4gIHBvcnQ6IG51bWJlcixcbiAgb3duZXJQaWQ6IG51bWJlcixcbiAgYXV0aFRva2VuOiBzdHJpbmcgfCBudWxsLFxuICBmZXRjaEltcGw6IHR5cGVvZiBmZXRjaCxcbik6IFByb21pc2U8Q29uc29sZUxlYWRlckluZm8gfCBudWxsPiB7XG4gIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2hJbXBsKGBodHRwOi8vMTI3LjAuMC4xOiR7cG9ydH0vYXBpL3Nlc3Npb25zYCwge1xuICAgIGhlYWRlcnM6IGJ1aWxkRGlzY292ZXJ5SGVhZGVycyhhdXRoVG9rZW4pLFxuICB9KTtcbiAgaWYgKCFyZXNwb25zZS5vaykge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgY29uc3QgcGF5bG9hZCA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKSBhcyB7IHNlc3Npb25zPzogU2Vzc2lvbkFwaVJlY29yZFtdIH07XG4gIGNvbnN0IHNlc3Npb25zID0gQXJyYXkuaXNBcnJheShwYXlsb2FkLnNlc3Npb25zKSA/IHBheWxvYWQuc2Vzc2lvbnMgOiBbXTtcbiAgY29uc3QgbGVhZGVyU2Vzc2lvbiA9IHNlc3Npb25zLmZpbmQoKHNlc3Npb24pID0+XG4gICAgc2Vzc2lvbi5waWQgPT09IG93bmVyUGlkICYmXG4gICAgc2Vzc2lvbi5pc0xlYWRlciA9PT0gdHJ1ZSAmJlxuICAgIHNlc3Npb24ua2luZCA9PT0gJ21jcCcgJiZcbiAgICBzZXNzaW9uLnN0YXR1cyAhPT0gJ3N0b3BwZWQnXG4gICk7XG4gIHJldHVybiBsZWFkZXJTZXNzaW9uID8gYnVpbGRMZWFkZXJJbmZvRnJvbVNlc3Npb24ocG9ydCwgb3duZXJQaWQsIGxlYWRlclNlc3Npb24pIDogbnVsbDtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGRpc2NvdmVyTGVhZGVyU2VydmluZ1BvcnQoXG4gIHBvcnQ6IG51bWJlcixcbiAgYXV0aFRva2VuOiBzdHJpbmcgfCBudWxsLFxuICBkZXBzOiBEaXNjb3ZlcnlEZXBlbmRlbmNpZXMgPSB7fSxcbik6IFByb21pc2U8UG9ydExlYWRlckRpc2NvdmVyeT4ge1xuICBjb25zdCBmZXRjaEltcGwgPSBkZXBzLmZldGNoSW1wbCA/PyBmZXRjaDtcbiAgY29uc3QgZmluZFBpZE9uUG9ydEltcGwgPSBkZXBzLmZpbmRQaWRPblBvcnRJbXBsID8/IGZpbmRQaWRPblBvcnQ7XG4gIGNvbnN0IHJlYWRMZWFkZXJMb2NrSW1wbCA9IGRlcHMucmVhZExlYWRlckxvY2tJbXBsID8/IHJlYWRMZWFkZXJMb2NrO1xuICBjb25zdCBvd25lclBpZCA9IGF3YWl0IGZpbmRQaWRPblBvcnRJbXBsKHBvcnQpO1xuXG4gIGlmIChvd25lclBpZCAhPT0gbnVsbCkge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBsZWFkZXJJbmZvID0gYXdhaXQgZGlzY292ZXJMZWFkZXJWaWFTZXNzaW9uc0FwaShwb3J0LCBvd25lclBpZCwgYXV0aFRva2VuLCBmZXRjaEltcGwpO1xuICAgICAgaWYgKGxlYWRlckluZm8pIHtcbiAgICAgICAgcmV0dXJuIHsgb3duZXJQaWQsIHNvdXJjZTogJ2FwaScsIGxlYWRlckluZm8gfTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIGxvZ2dlci5kZWJ1ZygnW1VuaWZpZWRDb25zb2xlXSBGYWlsZWQgdG8gcXVlcnkgYWN0aXZlIGxlYWRlciBzZXNzaW9ucycsIHtcbiAgICAgICAgcG9ydCxcbiAgICAgICAgb3duZXJQaWQsXG4gICAgICAgIGVycm9yOiBlcnIgaW5zdGFuY2VvZiBFcnJvciA/IGVyci5tZXNzYWdlIDogU3RyaW5nKGVyciksXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBjb25zdCBsb2NrID0gYXdhaXQgcmVhZExlYWRlckxvY2tJbXBsKCk7XG4gIGlmIChsb2NrPy5wb3J0ID09PSBwb3J0ICYmIChvd25lclBpZCA9PT0gbnVsbCB8fCBsb2NrLnBpZCA9PT0gb3duZXJQaWQpKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIG93bmVyUGlkOiBvd25lclBpZCA/PyBsb2NrLnBpZCxcbiAgICAgIHNvdXJjZTogJ2xvY2snLFxuICAgICAgbGVhZGVySW5mbzoge1xuICAgICAgICAuLi5sb2NrLFxuICAgICAgICBzZXNzaW9uSWQ6IFVuaWNvZGVWYWxpZGF0b3Iubm9ybWFsaXplKGxvY2suc2Vzc2lvbklkKS5ub3JtYWxpemVkQ29udGVudCxcbiAgICAgIH0sXG4gICAgfTtcbiAgfVxuXG4gIGlmIChvd25lclBpZCAhPT0gbnVsbCkge1xuICAgIHJldHVybiB7XG4gICAgICBvd25lclBpZCxcbiAgICAgIHNvdXJjZTogJ3N5bnRoZXRpYycsXG4gICAgICBsZWFkZXJJbmZvOiBidWlsZFN5bnRoZXRpY0xlYWRlckluZm8ocG9ydCwgb3duZXJQaWQpLFxuICAgIH07XG4gIH1cblxuICByZXR1cm4geyBsZWFkZXJJbmZvOiBudWxsLCBvd25lclBpZDogbnVsbCwgc291cmNlOiAnbm9uZScgfTtcbn1cblxuaW50ZXJmYWNlIEJpbmRGYWlsdXJlUmVjb3ZlcnlEZXBlbmRlbmNpZXMgZXh0ZW5kcyBEaXNjb3ZlcnlEZXBlbmRlbmNpZXMge1xuICBkZWxldGVMZWFkZXJMb2NrSW1wbD86IHR5cGVvZiBkZWxldGVMZWFkZXJMb2NrO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcmVjb3ZlckxlYWRlckJpbmRGYWlsdXJlKFxuICBwcm92aXNpb25hbExlYWRlcjogQ29uc29sZUxlYWRlckluZm8sXG4gIHBvcnQ6IG51bWJlcixcbiAgYXV0aFRva2VuOiBzdHJpbmcgfCBudWxsLFxuICBkZXBzOiBCaW5kRmFpbHVyZVJlY292ZXJ5RGVwZW5kZW5jaWVzID0ge30sXG4pOiBQcm9taXNlPEJpbmRGYWlsdXJlUmVjb3ZlcnlSZXN1bHQ+IHtcbiAgY29uc3QgcmVhZExlYWRlckxvY2tJbXBsID0gZGVwcy5yZWFkTGVhZGVyTG9ja0ltcGwgPz8gcmVhZExlYWRlckxvY2s7XG4gIGNvbnN0IGRlbGV0ZUxlYWRlckxvY2tJbXBsID0gZGVwcy5kZWxldGVMZWFkZXJMb2NrSW1wbCA/PyBkZWxldGVMZWFkZXJMb2NrO1xuICBsb2dnZXIuaW5mbygnW1VuaWZpZWRDb25zb2xlXSBMZWFkZXIgYmluZCByZWNvdmVyeSBpbml0aWF0ZWQnLCB7XG4gICAgcHJvdmlzaW9uYWxTZXNzaW9uSWQ6IHByb3Zpc2lvbmFsTGVhZGVyLnNlc3Npb25JZCxcbiAgICBwcm92aXNpb25hbFBpZDogcHJvdmlzaW9uYWxMZWFkZXIucGlkLFxuICAgIHBvcnQsXG4gIH0pO1xuXG4gIGxldCBmYWxsYmFjayA9IGF3YWl0IGRpc2NvdmVyTGVhZGVyU2VydmluZ1BvcnQocG9ydCwgYXV0aFRva2VuLCBkZXBzKTtcbiAgbGV0IGxvY2tDbGVhbnVwQXR0ZW1wdGVkID0gZmFsc2U7XG4gIGxldCBsb2NrQ2xlYW51cFBlcmZvcm1lZCA9IGZhbHNlO1xuICBjb25zdCBjdXJyZW50TG9jayA9IGF3YWl0IHJlYWRMZWFkZXJMb2NrSW1wbCgpO1xuICBjb25zdCBwcm92aXNpb25hbExvY2tNYXRjaGVzID0gKFxuICAgIGN1cnJlbnRMb2NrPy5waWQgPT09IHByb3Zpc2lvbmFsTGVhZGVyLnBpZCAmJlxuICAgIGN1cnJlbnRMb2NrLnBvcnQgPT09IHByb3Zpc2lvbmFsTGVhZGVyLnBvcnQgJiZcbiAgICBjdXJyZW50TG9jay5zZXNzaW9uSWQgPT09IHByb3Zpc2lvbmFsTGVhZGVyLnNlc3Npb25JZFxuICApO1xuICBjb25zdCBmYWxsYmFja1BvaW50c1RvUHJvdmlzaW9uYWxMZWFkZXIgPSAoXG4gICAgZmFsbGJhY2subGVhZGVySW5mbz8ucGlkID09PSBwcm92aXNpb25hbExlYWRlci5waWQgJiZcbiAgICBmYWxsYmFjay5sZWFkZXJJbmZvLnBvcnQgPT09IHByb3Zpc2lvbmFsTGVhZGVyLnBvcnQgJiZcbiAgICBmYWxsYmFjay5sZWFkZXJJbmZvLnNlc3Npb25JZCA9PT0gcHJvdmlzaW9uYWxMZWFkZXIuc2Vzc2lvbklkXG4gICk7XG5cbiAgaWYgKHByb3Zpc2lvbmFsTG9ja01hdGNoZXMpIHtcbiAgICBsb2NrQ2xlYW51cEF0dGVtcHRlZCA9IHRydWU7XG4gICAgYXdhaXQgZGVsZXRlTGVhZGVyTG9ja0ltcGwoKTtcbiAgICBsb2NrQ2xlYW51cFBlcmZvcm1lZCA9IHRydWU7XG4gICAgbG9nZ2VyLmluZm8oJ1tVbmlmaWVkQ29uc29sZV0gUmVtb3ZlZCBwcm92aXNpb25hbCBsZWFkZXIgbG9jayBhZnRlciBiaW5kIGZhaWx1cmUnLCB7XG4gICAgICBwcm92aXNpb25hbFNlc3Npb25JZDogcHJvdmlzaW9uYWxMZWFkZXIuc2Vzc2lvbklkLFxuICAgICAgcHJvdmlzaW9uYWxQaWQ6IHByb3Zpc2lvbmFsTGVhZGVyLnBpZCxcbiAgICAgIHBvcnQsXG4gICAgfSk7XG4gICAgaWYgKGZhbGxiYWNrUG9pbnRzVG9Qcm92aXNpb25hbExlYWRlcikge1xuICAgICAgZmFsbGJhY2sgPSBhd2FpdCBkaXNjb3ZlckxlYWRlclNlcnZpbmdQb3J0KHBvcnQsIGF1dGhUb2tlbiwgZGVwcyk7XG4gICAgfVxuICB9XG5cbiAgbG9nZ2VyLmluZm8oJ1tVbmlmaWVkQ29uc29sZV0gTGVhZGVyIGJpbmQgcmVjb3ZlcnkgY29tcGxldGVkJywge1xuICAgIHByb3Zpc2lvbmFsU2Vzc2lvbklkOiBwcm92aXNpb25hbExlYWRlci5zZXNzaW9uSWQsXG4gICAgcHJvdmlzaW9uYWxQaWQ6IHByb3Zpc2lvbmFsTGVhZGVyLnBpZCxcbiAgICBwb3J0LFxuICAgIGRpc2NvdmVyeVNvdXJjZTogZmFsbGJhY2suc291cmNlLFxuICAgIG93bmVyUGlkOiBmYWxsYmFjay5vd25lclBpZCxcbiAgICBsb2NrQ2xlYW51cEF0dGVtcHRlZCxcbiAgICBsb2NrQ2xlYW51cFBlcmZvcm1lZCxcbiAgfSk7XG5cbiAgcmV0dXJuIHtcbiAgICAuLi5mYWxsYmFjayxcbiAgICBsb2NrQ2xlYW51cEF0dGVtcHRlZCxcbiAgICBsb2NrQ2xlYW51cFBlcmZvcm1lZCxcbiAgfTtcbn1cblxuLyoqXG4gKiBTdGFydCB0aGUgdW5pZmllZCB3ZWIgY29uc29sZS5cbiAqXG4gKiBSdW5zIGxlYWRlciBlbGVjdGlvbiwgdGhlbiBlaXRoZXIgc3RhcnRzIHRoZSBmdWxsIGNvbnNvbGUgKGxlYWRlcilcbiAqIG9yIHNldHMgdXAgZXZlbnQgZm9yd2FyZGluZyAoZm9sbG93ZXIpLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gc3RhcnRVbmlmaWVkQ29uc29sZShvcHRpb25zOiBVbmlmaWVkQ29uc29sZU9wdGlvbnMpOiBQcm9taXNlPFVuaWZpZWRDb25zb2xlUmVzdWx0PiB7XG4gIC8vIFJlc29sdmUgcG9ydDogb3B0aW9ucyAoY29uZmlnIGZpbGUpIOKGkiBlbnYgdmFyIOKGkiBkZWZhdWx0XG4gIGNvbnN0IGNvbnNvbGVQb3J0ID0gb3B0aW9ucy5wb3J0IHx8IERFRkFVTFRfQ09OU09MRV9QT1JUO1xuICBsb2dnZXIuZGVidWcoYFtVbmlmaWVkQ29uc29sZV0gUG9ydCByZXNvbHZlZDogJHtjb25zb2xlUG9ydH1gICtcbiAgICAob3B0aW9ucy5wb3J0ID8gJyAoZnJvbSBjb25maWcgZmlsZSknIDogYCAoZnJvbSBlbnYvZGVmYXVsdClgKSk7XG5cbiAgLy8gTGVnYWN5LWxlYWRlciBkZXRlY3Rpb24gKCMxNzk0KSDigJQgd2FybiB0aGUgdXNlciBpZiBhIHByZS1hdXRoXG4gIC8vIERvbGxob3VzZU1DUCBjb25zb2xlIGlzIHJ1bm5pbmcgYWxvbmdzaWRlIHRoaXMgYXV0aGVudGljYXRlZCBvbmUuXG4gIC8vIFRoZXkgd2lsbCBjb2V4aXN0IGZpbmUgYmVjYXVzZSBvZiBwb3J0ICsgbG9jayArIHRva2VuIGZpbGUgaXNvbGF0aW9uLFxuICAvLyBidXQgdGhlIHVzZXIgc2hvdWxkIGtub3cgYm90aCBleGlzdCBzbyB0aGUgZGlmZmVyaW5nIHNlY3VyaXR5IHBvc3R1cmVcbiAgLy8gYmV0d2VlbiB0aGVtIGRvZXNuJ3QgbG9vayBsaWtlIGEgYnVnLlxuICBhd2FpdCB3YXJuSWZMZWdhY3lDb25zb2xlUHJlc2VudChjb25zb2xlUG9ydCk7XG5cbiAgbGV0IGVsZWN0aW9uID0gYXdhaXQgZWxlY3RMZWFkZXIob3B0aW9ucy5zZXNzaW9uSWQsIGNvbnNvbGVQb3J0KTtcblxuICAvLyBJZiB3ZSBsb3N0IHRoZSBlbGVjdGlvbiwgY2hlY2sgaWYgdGhlIGxlYWRlciBpcyBhY3R1YWxseSBydW5uaW5nIGEgd2ViIGNvbnNvbGUuXG4gIC8vIEFuIE1DUCBzdGRpbyBwcm9jZXNzIG1heSBob2xkIGxlYWRlcnNoaXAgYnV0IG5vdCBzZXJ2ZSB3ZWIgcm91dGVzLlxuICAvLyBJbiB0aGF0IGNhc2UsIGZvcmNlIGEgdGFrZW92ZXIgc28gdGhlIHdlYiBjb25zb2xlIHdvcmtzIHByb3Blcmx5LlxuICBpZiAoZWxlY3Rpb24ucm9sZSA9PT0gJ2ZvbGxvd2VyJykge1xuICAgIGNvbnN0IHJlYWNoYWJsZSA9IGF3YWl0IGlzTGVhZGVyV2ViQ29uc29sZVJlYWNoYWJsZShlbGVjdGlvbi5sZWFkZXJJbmZvKTtcbiAgICBpZiAoIXJlYWNoYWJsZSkge1xuICAgICAgZWxlY3Rpb24gPSBhd2FpdCBmb3JjZUNsYWltTGVhZGVyc2hpcChvcHRpb25zLnNlc3Npb25JZCwgY29uc29sZVBvcnQpO1xuICAgIH1cbiAgfVxuXG4gIGlmIChlbGVjdGlvbi5yb2xlID09PSAnbGVhZGVyJykge1xuICAgIHJldHVybiBzdGFydEFzTGVhZGVyKG9wdGlvbnMsIGVsZWN0aW9uLCBjb25zb2xlUG9ydCk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHN0YXJ0QXNGb2xsb3dlcihvcHRpb25zLCBlbGVjdGlvbiwgY29uc29sZVBvcnQpO1xuICB9XG59XG5cbi8qKlxuICogU3RhcnQgYXMgdGhlIGNvbnNvbGUgbGVhZGVyLlxuICogQmluZHMgdGhlIHJlc29sdmVkIGNvbnNvbGUgcG9ydCAoY29uZmlnIGZpbGUg4oaSIGVudiB2YXIg4oaSIGRlZmF1bHQpLFxuICogbW91bnRzIGFsbCByb3V0ZXMgaW5jbHVkaW5nIGluZ2VzdGlvbiwgc3RhcnRzIGhlYXJ0YmVhdC5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gc3RhcnRBc0xlYWRlcihcbiAgb3B0aW9uczogVW5pZmllZENvbnNvbGVPcHRpb25zLFxuICBlbGVjdGlvbjogRWxlY3Rpb25SZXN1bHQsXG4gIGNvbnNvbGVQb3J0OiBudW1iZXIgPSBERUZBVUxUX0NPTlNPTEVfUE9SVCxcbik6IFByb21pc2U8VW5pZmllZENvbnNvbGVSZXN1bHQ+IHtcbiAgY29uc3QgeyBzdGFydFdlYlNlcnZlciB9ID0gYXdhaXQgaW1wb3J0KCcuLi9zZXJ2ZXIuanMnKTtcbiAgY29uc3QgeyBwaWNrUmFuZG9tVG9rZW5OYW1lIH0gPSBhd2FpdCBpbXBvcnQoJy4vU2Vzc2lvbk5hbWVzLmpzJyk7XG5cbiAgLy8gSW5pdGlhbGl6ZSB0aGUgY29uc29sZSB0b2tlbiBzdG9yZSAoIzE3ODApLiBDcmVhdGVzIHRoZSB0b2tlbiBmaWxlIG9uXG4gIC8vIGZpcnN0IHJ1biwgcmVhZHMgdGhlIGV4aXN0aW5nIHRva2VucyBvbiBzdWJzZXF1ZW50IHJ1bnMuIFRoZSB0b2tlbiBpc1xuICAvLyBwZXJzaXN0ZW50IGFjcm9zcyByZXN0YXJ0cyDigJQgb25seSByb3RhdGVkIG9uIGV4cGxpY2l0IHJlcXVlc3QgKFBoYXNlIDIpLlxuICAvLyBGZWF0dXJlIGZsYWcgRE9MTEhPVVNFX1dFQl9BVVRIX0VOQUJMRUQgY29udHJvbHMgZW5mb3JjZW1lbnQ7IHRoZSBmaWxlXG4gIC8vIGlzIGdlbmVyYXRlZCByZWdhcmRsZXNzIHNvIGNvbnN1bWVycyBjYW4gYXR0YWNoIHRva2VucyBwcmVlbXB0aXZlbHkuXG4gIGNvbnN0IHRva2VuU3RvcmUgPSBuZXcgQ29uc29sZVRva2VuU3RvcmUoZW52LkRPTExIT1VTRV9DT05TT0xFX1RPS0VOX0ZJTEUpO1xuICBjb25zdCBwcmltYXJ5VG9rZW4gPSBhd2FpdCB0b2tlblN0b3JlLmVuc3VyZUluaXRpYWxpemVkKHBpY2tSYW5kb21Ub2tlbk5hbWUoKSk7XG4gIGxvZ2dlci5pbmZvKCdbVW5pZmllZENvbnNvbGVdIENvbnNvbGUgdG9rZW4gc3RvcmUgaW5pdGlhbGl6ZWQnLCB7XG4gICAgdG9rZW5JZDogcHJpbWFyeVRva2VuLmlkLFxuICAgIHRva2VuTmFtZTogcHJpbWFyeVRva2VuLm5hbWUsXG4gICAgZmlsZTogdG9rZW5TdG9yZS5nZXRGaWxlUGF0aCgpLFxuICAgIGF1dGhFbmZvcmNlZDogZW52LkRPTExIT1VTRV9XRUJfQVVUSF9FTkFCTEVELFxuICB9KTtcblxuICAvLyBQcmUtY3JlYXRlIGEgcGxhY2Vob2xkZXIgYnJvYWRjYXN0IHRoYXQgd2UnbGwgd2lyZSB1cCBhZnRlciB0aGUgc2VydmVyIHN0YXJ0c1xuICBsZXQgbGl2ZUJyb2FkY2FzdDogKChlbnRyeTogVW5pZmllZExvZ0VudHJ5KSA9PiB2b2lkKSB8IHVuZGVmaW5lZDtcbiAgbGV0IGxpdmVNZXRyaWNzT25TbmFwc2hvdDogKChzbmFwc2hvdDogTWV0cmljU25hcHNob3QpID0+IHZvaWQpIHwgdW5kZWZpbmVkO1xuXG4gIC8vIENyZWF0ZSBpbmdlc3Rpb24gcm91dGVzIHdpdGggYSBkZWZlcnJlZCBicm9hZGNhc3QgKHdpcmVkIGFmdGVyIHNlcnZlciBzdGFydHMpXG4gIGNvbnN0IGluZ2VzdFJlc3VsdCA9IGNyZWF0ZUluZ2VzdFJvdXRlcyh7XG4gICAgbG9nQnJvYWRjYXN0OiAoZW50cnkpID0+IGxpdmVCcm9hZGNhc3Q/LihlbnRyeSksXG4gICAgbWV0cmljc09uU25hcHNob3Q6IChzbmFwc2hvdCkgPT4gbGl2ZU1ldHJpY3NPblNuYXBzaG90Py4oc25hcHNob3QpLFxuICAgIHN0b3JlTWV0cmljc1NuYXBzaG90OiAoc25hcHNob3QpID0+IG9wdGlvbnMubWV0cmljc1Npbms/Lm9uU25hcHNob3Qoc25hcHNob3QpLFxuICB9KTtcblxuICAvLyBTdGFydCB0aGUgd2ViIHNlcnZlciB3aXRoIGluZ2VzdCByb3V0ZXMgbW91bnRlZCBiZWZvcmUgdGhlIFNQQSBmYWxsYmFjay5cbiAgLy8gSWYgdGhlIHBvcnQgaXMgb2NjdXBpZWQgYnkgYSBzdGFsZSBwcm9jZXNzLCByZXRyeSB3aXRoIGV4cG9uZW50aWFsIGJhY2tvZmYuXG4gIGNvbnN0IHNlcnZlck9wdHMgPSB7XG4gICAgcG9ydGZvbGlvRGlyOiBvcHRpb25zLnBvcnRmb2xpb0RpcixcbiAgICBtZW1vcnlTaW5rOiBvcHRpb25zLm1lbW9yeVNpbmssXG4gICAgbWV0cmljc1Npbms6IG9wdGlvbnMubWV0cmljc1NpbmssXG4gICAgcG9ydDogY29uc29sZVBvcnQsXG4gICAgYWRkaXRpb25hbFJvdXRlcnM6IFtpbmdlc3RSZXN1bHQucm91dGVyXSxcbiAgICB0b2tlblN0b3JlLFxuICAgIC4uLihvcHRpb25zLm1jcEFxbEhhbmRsZXIgPyB7IG1jcEFxbEhhbmRsZXI6IG9wdGlvbnMubWNwQXFsSGFuZGxlciB9IDoge30pLFxuICB9O1xuICAvLyBiaW5kQW5kTGlzdGVuIG5vdyBoYW5kbGVzIEVBRERSSU5VU0UgYnkgZmluZGluZyBhbmQga2lsbGluZyB0aGUgc3RhbGVcbiAgLy8gcHJvY2VzcyBvbiB0aGUgcG9ydCwgdGhlbiByZXRyeWluZy4gTm8gZXh0ZXJuYWwgcmV0cnkgbG9vcCBuZWVkZWQuXG4gIGNvbnN0IHdlYlJlc3VsdCA9IGF3YWl0IHN0YXJ0V2ViU2VydmVyKHNlcnZlck9wdHMpO1xuXG4gIGlmICh3ZWJSZXN1bHQuYmluZFJlc3VsdCAmJiAhd2ViUmVzdWx0LmJpbmRSZXN1bHQuc3VjY2Vzcykge1xuICAgIGNvbnN0IGZhbGxiYWNrID0gYXdhaXQgcmVjb3ZlckxlYWRlckJpbmRGYWlsdXJlKGVsZWN0aW9uLmxlYWRlckluZm8sIGNvbnNvbGVQb3J0LCBwcmltYXJ5VG9rZW4udG9rZW4pO1xuICAgIGlmIChmYWxsYmFjay5sZWFkZXJJbmZvKSB7XG4gICAgICBsb2dnZXIud2FybignW1VuaWZpZWRDb25zb2xlXSBMZWFkZXIgcm9sZSBhYm9ydGVkOiBiaW5kIGZhaWxlZCwgZmFsbGluZyBiYWNrIHRvIGZvbGxvd2VyJywge1xuICAgICAgICBwb3J0OiBjb25zb2xlUG9ydCxcbiAgICAgICAgYmluZEVycm9yOiB3ZWJSZXN1bHQuYmluZFJlc3VsdC5lcnJvcixcbiAgICAgICAgYmluZERldGFpbDogd2ViUmVzdWx0LmJpbmRSZXN1bHQuZGV0YWlsLFxuICAgICAgICBwcm92aXNpb25hbExlYWRlclBpZDogZWxlY3Rpb24ubGVhZGVySW5mby5waWQsXG4gICAgICAgIHByb3Zpc2lvbmFsTGVhZGVyU2Vzc2lvbklkOiBlbGVjdGlvbi5sZWFkZXJJbmZvLnNlc3Npb25JZCxcbiAgICAgICAgb3duZXJQaWQ6IGZhbGxiYWNrLm93bmVyUGlkLFxuICAgICAgICBzb3VyY2U6IGZhbGxiYWNrLnNvdXJjZSxcbiAgICAgICAgbG9ja0NsZWFudXBBdHRlbXB0ZWQ6IGZhbGxiYWNrLmxvY2tDbGVhbnVwQXR0ZW1wdGVkLFxuICAgICAgICBsb2NrQ2xlYW51cFBlcmZvcm1lZDogZmFsbGJhY2subG9ja0NsZWFudXBQZXJmb3JtZWQsXG4gICAgICB9KTtcbiAgICAgIGNvbnN0IGZvbGxvd2VyRWxlY3Rpb246IEVsZWN0aW9uUmVzdWx0ID0geyByb2xlOiAnZm9sbG93ZXInLCBsZWFkZXJJbmZvOiBmYWxsYmFjay5sZWFkZXJJbmZvIH07XG4gICAgICByZXR1cm4gc3RhcnRBc0ZvbGxvd2VyKG9wdGlvbnMsIGZvbGxvd2VyRWxlY3Rpb24sIGNvbnNvbGVQb3J0LCBwcmltYXJ5VG9rZW4udG9rZW4pO1xuICAgIH1cblxuICAgIGxvZ2dlci5lcnJvcignW1VuaWZpZWRDb25zb2xlXSBMZWFkZXIgZmFpbGVkIHRvIGJpbmQgYW5kIG5vIGFjdGl2ZSBsZWFkZXIgY291bGQgYmUgaWRlbnRpZmllZCcsIHtcbiAgICAgIHBvcnQ6IGNvbnNvbGVQb3J0LFxuICAgICAgcHJvdmlzaW9uYWxMZWFkZXJQaWQ6IGVsZWN0aW9uLmxlYWRlckluZm8ucGlkLFxuICAgICAgYmluZEVycm9yOiB3ZWJSZXN1bHQuYmluZFJlc3VsdC5lcnJvcixcbiAgICAgIGJpbmREZXRhaWw6IHdlYlJlc3VsdC5iaW5kUmVzdWx0LmRldGFpbCxcbiAgICB9KTtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYExlYWRlciBmYWlsZWQgdG8gYmluZCBwb3J0ICR7Y29uc29sZVBvcnR9IGFuZCBubyBhY3RpdmUgbGVhZGVyIHdhcyBkaXNjb3ZlcmFibGVgKTtcbiAgfVxuXG4gIC8vIFJlZ2lzdGVyIHRoZSBsZWFkZXIgb25seSBhZnRlciB0aGUgSFRUUCBsaXN0ZW5lciBpcyBhY3R1YWxseSBzZXJ2aW5nIHRoZSBwb3J0LlxuICBpbmdlc3RSZXN1bHQucmVnaXN0ZXJMZWFkZXJTZXNzaW9uKG9wdGlvbnMuc2Vzc2lvbklkLCBwcm9jZXNzLnBpZCk7XG5cbiAgLy8gUmVnaXN0ZXIgdGhlIHdlYiBjb25zb2xlIGl0c2VsZiBzbyB0aGUgc2Vzc2lvbiBpbmRpY2F0b3IgaXMgbmV2ZXIgZW1wdHkgKCMxODA1KVxuICBpbmdlc3RSZXN1bHQucmVnaXN0ZXJDb25zb2xlU2Vzc2lvbigpO1xuXG4gIC8vIFdpcmUgU1NFIGJyb2FkY2FzdHMgZm9yIHRoaXMgbGVhZGVyJ3Mgb3duIGV2ZW50c1xuICBvcHRpb25zLndpcmVTU0VCcm9hZGNhc3RzKHdlYlJlc3VsdCwgb3B0aW9ucy5tZXRyaWNzU2luayk7XG5cbiAgLy8gTm93IHdpcmUgdGhlIGxpdmUgYnJvYWRjYXN0IGZ1bmN0aW9ucyBpbnRvIHRoZSBpbmdlc3Qgcm91dGVzXG4gIGlmICh3ZWJSZXN1bHQubG9nQnJvYWRjYXN0KSB7XG4gICAgY29uc3Qgb3JpZ2luYWxCcm9hZGNhc3QgPSB3ZWJSZXN1bHQubG9nQnJvYWRjYXN0O1xuICAgIC8vIFN0YW1wIGxlYWRlcidzIG93biBlbnRyaWVzIHdpdGggc2Vzc2lvbiBJRFxuICAgIGxpdmVCcm9hZGNhc3QgPSAoZW50cnk6IFVuaWZpZWRMb2dFbnRyeSkgPT4ge1xuICAgICAgY29uc3Qgc3RhbXBlZDogVW5pZmllZExvZ0VudHJ5ID0ge1xuICAgICAgICAuLi5lbnRyeSxcbiAgICAgICAgZGF0YTogeyAuLi5lbnRyeS5kYXRhLCBfc2Vzc2lvbklkOiBvcHRpb25zLnNlc3Npb25JZCB9LFxuICAgICAgfTtcbiAgICAgIG9yaWdpbmFsQnJvYWRjYXN0KHN0YW1wZWQpO1xuICAgIH07XG4gIH1cbiAgbGl2ZU1ldHJpY3NPblNuYXBzaG90ID0gd2ViUmVzdWx0Lm1ldHJpY3NPblNuYXBzaG90O1xuXG4gIGxvZ2dlci5pbmZvKCdbVW5pZmllZENvbnNvbGVdIEluZ2VzdGlvbiByb3V0ZXMgbW91bnRlZCcpO1xuXG4gIC8vIFN0YXJ0IGhlYXJ0YmVhdCBhbmQgcmVnaXN0ZXIgY2xlYW51cFxuICBjb25zdCBzdG9wSGVhcnRiZWF0ID0gc3RhcnRIZWFydGJlYXQoZWxlY3Rpb24ubGVhZGVySW5mbyk7XG4gIHJlZ2lzdGVyTGVhZGVyQ2xlYW51cCgpO1xuXG4gIGxvZ2dlci5pbmZvKCdbVW5pZmllZENvbnNvbGVdIExlYWRlciBzdGFydGVkJywge1xuICAgIHNlc3Npb25JZDogb3B0aW9ucy5zZXNzaW9uSWQsIHBvcnQ6IGNvbnNvbGVQb3J0LCBwaWQ6IHByb2Nlc3MucGlkLFxuICAgIHJvbGU6ICdsZWFkZXInLCBpbmdlc3RSb3V0ZXM6IFsnL2FwaS9pbmdlc3QvbG9ncycsICcvYXBpL2luZ2VzdC9tZXRyaWNzJywgJy9hcGkvaW5nZXN0L3Nlc3Npb24nLCAnL2FwaS9zZXNzaW9ucyddLFxuICB9KTtcblxuICByZXR1cm4ge1xuICAgIHJvbGU6ICdsZWFkZXInLFxuICAgIGVsZWN0aW9uLFxuICAgIHBvcnQ6IGNvbnNvbGVQb3J0LFxuICAgIGNsZWFudXA6IGFzeW5jICgpID0+IHtcbiAgICAgIHN0b3BIZWFydGJlYXQoKTtcbiAgICB9LFxuICB9O1xufVxuXG4vKipcbiAqIFN0YXJ0IGFzIGEgZm9sbG93ZXIuXG4gKiBSZWdpc3RlcnMgZm9yd2FyZGluZyBzaW5rcyB3aXRoIHRoZSBMb2dNYW5hZ2VyLCBzdGFydHMgc2Vzc2lvbiBoZWFydGJlYXQuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHN0YXJ0QXNGb2xsb3dlcihcbiAgb3B0aW9uczogVW5pZmllZENvbnNvbGVPcHRpb25zLFxuICBlbGVjdGlvbjogRWxlY3Rpb25SZXN1bHQsXG4gIGNvbnNvbGVQb3J0OiBudW1iZXIgPSBERUZBVUxUX0NPTlNPTEVfUE9SVCxcbiAgaW5pdGlhbEF1dGhUb2tlbjogc3RyaW5nIHwgbnVsbCA9IG51bGwsXG4pOiBQcm9taXNlPFVuaWZpZWRDb25zb2xlUmVzdWx0PiB7XG4gIGNvbnN0IGxlYWRlclVybCA9IGBodHRwOi8vMTI3LjAuMC4xOiR7ZWxlY3Rpb24ubGVhZGVySW5mby5wb3J0fWA7XG5cbiAgLy8gUmVhZCB0aGUgY29uc29sZSBhdXRoIHRva2VuICgjMTc4MCkgd3JpdHRlbiBieSB0aGUgbGVhZGVyLiBNYXkgYmUgbnVsbFxuICAvLyBpZiB0aGUgZmlsZSBkb2Vzbid0IGV4aXN0IHlldCDigJQgdGhlIHNpbmtzIGhhbmRsZSB0aGF0IGdyYWNlZnVsbHkgYW5kXG4gIC8vIHNpbXBseSBvbWl0IHRoZSBCZWFyZXIgaGVhZGVyLCB3aGljaCBpcyBmaW5lIHdoZW4gYXV0aCBpcyBub3QgZW5mb3JjZWQuXG4gIGxldCBhdXRoVG9rZW4gPSBpbml0aWFsQXV0aFRva2VuO1xuICBpZiAoYXV0aFRva2VuID09PSBudWxsKSB7XG4gICAgY29uc3QgeyBnZXRQcmltYXJ5VG9rZW5Gcm9tRmlsZSB9ID0gYXdhaXQgaW1wb3J0KCcuL2NvbnNvbGVUb2tlbi5qcycpO1xuICAgIGF1dGhUb2tlbiA9IGF3YWl0IGdldFByaW1hcnlUb2tlbkZyb21GaWxlKGVudi5ET0xMSE9VU0VfQ09OU09MRV9UT0tFTl9GSUxFKTtcbiAgfVxuICBpZiAoYXV0aFRva2VuKSB7XG4gICAgbG9nZ2VyLmRlYnVnKCdbVW5pZmllZENvbnNvbGVdIEZvbGxvd2VyIGxvYWRlZCBjb25zb2xlIGF1dGggdG9rZW4nKTtcbiAgfSBlbHNlIHtcbiAgICBsb2dnZXIuZGVidWcoJ1tVbmlmaWVkQ29uc29sZV0gTm8gY29uc29sZSBhdXRoIHRva2VuIGZpbGUgZm91bmQ7IGZvbGxvd2VyIHdpbGwgUE9TVCB3aXRob3V0IEJlYXJlciBoZWFkZXInKTtcbiAgfVxuXG4gIC8vIFBlci1pbnN0YW5jZSBwcm9tb3Rpb24gbWFuYWdlciDigJQgdHJhY2tzIGl0cyBvd24gYXR0ZW1wdCBjb3VudGVyIHNvXG4gIC8vIG11bHRpcGxlIGZvbGxvd2VycyBkb24ndCBpbnRlcmZlcmUgd2l0aCBlYWNoIG90aGVyJ3MgcHJvbW90aW9uIGJ1ZGdldHMuXG4gIGNvbnN0IHByb21vdGlvbk1nciA9IG5ldyBQcm9tb3Rpb25NYW5hZ2VyKG9wdGlvbnMsIGNvbnNvbGVQb3J0LCBzdGFydEFzTGVhZGVyLCBzdGFydEFzRm9sbG93ZXIpO1xuXG4gIC8vIERlY2xhcmUgc2Vzc2lvbkhlYXJ0YmVhdCBiZWZvcmUgdGhlIHNpbmsgc28gdGhlIGNsb3N1cmUgY2FuIGNhcHR1cmUgaXQuXG4gIC8vIEJvdGggYXJlIGluaXRpYWxpemVkIGJlZm9yZSB0aGUgY2FsbGJhY2sgY291bGQgcG9zc2libHkgZmlyZSAobmVlZHMgNSsgZmFpbGVkIGZsdXNoZXMpLlxuICBsZXQgc2Vzc2lvbkhlYXJ0YmVhdDogU2Vzc2lvbkhlYXJ0YmVhdDtcblxuICAvLyBSZWdpc3RlciBhIGZvcndhcmRpbmcgbG9nIHNpbmsgd2l0aCBsZWFkZXItZGVhdGggY2FsbGJhY2sgKCMxODUwKS5cbiAgY29uc3QgZm9yd2FyZGluZ1NpbmsgPSBuZXcgTGVhZGVyRm9yd2FyZGluZ0xvZ1NpbmsobGVhZGVyVXJsLCBvcHRpb25zLnNlc3Npb25JZCwgYXV0aFRva2VuLCAoKSA9PiB7XG4gICAgcHJvbW90aW9uTWdyLnByb21vdGUoZm9yd2FyZGluZ1NpbmssIHNlc3Npb25IZWFydGJlYXQpXG4gICAgICAuY2F0Y2goZXJyID0+IGxvZ2dlci5lcnJvcignW1VuaWZpZWRDb25zb2xlXSBQcm9tb3Rpb24gY3Jhc2hlZCcsIHsgZXJyb3I6IFN0cmluZyhlcnIpIH0pKTtcbiAgfSk7XG4gIG9wdGlvbnMucmVnaXN0ZXJMb2dTaW5rKGZvcndhcmRpbmdTaW5rKTtcblxuICAvLyBTdGFydCBzZXNzaW9uIGhlYXJ0YmVhdCB0byB0aGUgbGVhZGVyXG4gIHNlc3Npb25IZWFydGJlYXQgPSBuZXcgU2Vzc2lvbkhlYXJ0YmVhdChsZWFkZXJVcmwsIG9wdGlvbnMuc2Vzc2lvbklkLCBwcm9jZXNzLnBpZCwgYXV0aFRva2VuKTtcbiAgYXdhaXQgc2Vzc2lvbkhlYXJ0YmVhdC5zdGFydCgpO1xuXG4gIGxvZ2dlci5pbmZvKCdbVW5pZmllZENvbnNvbGVdIEZvbGxvd2VyIHN0YXJ0ZWQnLCB7XG4gICAgc2Vzc2lvbklkOiBvcHRpb25zLnNlc3Npb25JZCwgcGlkOiBwcm9jZXNzLnBpZCwgcm9sZTogJ2ZvbGxvd2VyJyxcbiAgICBsZWFkZXJTZXNzaW9uOiBlbGVjdGlvbi5sZWFkZXJJbmZvLnNlc3Npb25JZCwgbGVhZGVyUGlkOiBlbGVjdGlvbi5sZWFkZXJJbmZvLnBpZCxcbiAgICBsZWFkZXJQb3J0OiBlbGVjdGlvbi5sZWFkZXJJbmZvLnBvcnQsIGxlYWRlclVybCxcbiAgfSk7XG5cbiAgcmV0dXJuIHtcbiAgICByb2xlOiAnZm9sbG93ZXInLFxuICAgIGVsZWN0aW9uLFxuICAgIGNsZWFudXA6IGFzeW5jICgpID0+IHtcbiAgICAgIGF3YWl0IHNlc3Npb25IZWFydGJlYXQuc3RvcCgpO1xuICAgICAgYXdhaXQgZm9yd2FyZGluZ1NpbmsuY2xvc2UoKTtcbiAgICB9LFxuICB9O1xufVxuIl19
|
package/dist/web/public/app.js
CHANGED
|
@@ -1978,12 +1978,70 @@ globalThis.DollhouseConsoleUI.clearBanner = function(bannerId) {
|
|
|
1978
1978
|
|
|
1979
1979
|
const TAB_KEY = 'dollhousemcp-active-tab';
|
|
1980
1980
|
const SETUP_SEEN_KEY = 'dollhousemcp-setup-seen';
|
|
1981
|
+
const FORCED_RELOAD_KEY = 'dollhousemcp-last-forced-reload';
|
|
1981
1982
|
// Server version injected at request time — used to show Setup tab once per version
|
|
1982
1983
|
// so upgraders automatically see it on each new release (not just first-ever visit).
|
|
1983
1984
|
// Validate format (semver-like) before trusting the value; malformed falls back to
|
|
1984
1985
|
// 'unknown' which safely triggers setup on every load rather than silently skipping.
|
|
1985
1986
|
const _rawVersion = document.querySelector('meta[name="dollhouse-server-version"]')?.content || '';
|
|
1986
1987
|
const currentServerVersion = /^\d+\.\d+\.\d+/.test(_rawVersion) ? _rawVersion : 'unknown';
|
|
1988
|
+
const _rawAssetVersion = document.querySelector('meta[name="dollhouse-console-asset-version"]')?.content || '';
|
|
1989
|
+
const currentAssetVersion = /^\d+\.\d+\.\d+/.test(_rawAssetVersion) ? _rawAssetVersion : currentServerVersion;
|
|
1990
|
+
let forcedReloadInFlight = false;
|
|
1991
|
+
|
|
1992
|
+
function normalizeReloadVersion(version) {
|
|
1993
|
+
return typeof version === 'string' && /^\d+\.\d+\.\d+/.test(version)
|
|
1994
|
+
? version
|
|
1995
|
+
: (currentAssetVersion || currentServerVersion || 'unknown');
|
|
1996
|
+
}
|
|
1997
|
+
|
|
1998
|
+
function shouldThrottleForcedReload(targetVersion) {
|
|
1999
|
+
try {
|
|
2000
|
+
const raw = sessionStorage.getItem(FORCED_RELOAD_KEY);
|
|
2001
|
+
if (!raw) return false;
|
|
2002
|
+
const parsed = JSON.parse(raw);
|
|
2003
|
+
return parsed
|
|
2004
|
+
&& parsed.version === targetVersion
|
|
2005
|
+
&& typeof parsed.at === 'number'
|
|
2006
|
+
&& Date.now() - parsed.at < 60_000;
|
|
2007
|
+
} catch {
|
|
2008
|
+
return false;
|
|
2009
|
+
}
|
|
2010
|
+
}
|
|
2011
|
+
|
|
2012
|
+
function rememberForcedReload(targetVersion, reason) {
|
|
2013
|
+
try {
|
|
2014
|
+
sessionStorage.setItem(FORCED_RELOAD_KEY, JSON.stringify({
|
|
2015
|
+
version: targetVersion,
|
|
2016
|
+
reason: reason || 'manual',
|
|
2017
|
+
at: Date.now(),
|
|
2018
|
+
}));
|
|
2019
|
+
} catch {
|
|
2020
|
+
// Ignore storage failures — reload still proceeds.
|
|
2021
|
+
}
|
|
2022
|
+
}
|
|
2023
|
+
|
|
2024
|
+
function buildCacheBustedConsoleUrl(targetVersion, reason) {
|
|
2025
|
+
const url = new URL(globalThis.location.href);
|
|
2026
|
+
url.searchParams.set('dollhouse_bust', targetVersion + '-' + Date.now());
|
|
2027
|
+
url.searchParams.set('dollhouse_asset_version', targetVersion);
|
|
2028
|
+
if (reason) {
|
|
2029
|
+
url.searchParams.set('dollhouse_reload_reason', reason);
|
|
2030
|
+
}
|
|
2031
|
+
return url.toString();
|
|
2032
|
+
}
|
|
2033
|
+
|
|
2034
|
+
function forceConsoleReload(reason, targetVersion) {
|
|
2035
|
+
const normalizedTargetVersion = normalizeReloadVersion(targetVersion);
|
|
2036
|
+
if (forcedReloadInFlight || shouldThrottleForcedReload(normalizedTargetVersion)) {
|
|
2037
|
+
return false;
|
|
2038
|
+
}
|
|
2039
|
+
forcedReloadInFlight = true;
|
|
2040
|
+
rememberForcedReload(normalizedTargetVersion, reason);
|
|
2041
|
+
const reloadUrl = buildCacheBustedConsoleUrl(normalizedTargetVersion, reason);
|
|
2042
|
+
globalThis.location.replace(reloadUrl);
|
|
2043
|
+
return true;
|
|
2044
|
+
}
|
|
1987
2045
|
|
|
1988
2046
|
// Determine which tab to show on load:
|
|
1989
2047
|
// 1. URL hash (deep link)
|
|
@@ -2022,6 +2080,9 @@ globalThis.DollhouseConsoleUI.clearBanner = function(bannerId) {
|
|
|
2022
2080
|
// Expose for other scripts (logs.js, metrics.js, permissions.js)
|
|
2023
2081
|
globalThis.DollhouseConsole = globalThis.DollhouseConsole || {};
|
|
2024
2082
|
globalThis.DollhouseConsole.getUrlParams = () => getTabAndParams().params;
|
|
2083
|
+
globalThis.DollhouseConsole.currentServerVersion = currentServerVersion;
|
|
2084
|
+
globalThis.DollhouseConsole.currentAssetVersion = currentAssetVersion;
|
|
2085
|
+
globalThis.DollhouseConsole.forceReload = forceConsoleReload;
|
|
2025
2086
|
|
|
2026
2087
|
/**
|
|
2027
2088
|
* Apply URL params to the portfolio tab.
|
|
@@ -2175,7 +2236,7 @@ globalThis.DollhouseConsoleUI.clearBanner = function(bannerId) {
|
|
|
2175
2236
|
toast.innerHTML = 'Console session token changed\u2009\u2014\u2009'
|
|
2176
2237
|
+ '<button style="background:#fff;color:#b91c1c;border:none;padding:6px 16px;'
|
|
2177
2238
|
+ 'border-radius:4px;cursor:pointer;font-weight:600;font-size:14px"'
|
|
2178
|
-
+ ' onclick="
|
|
2239
|
+
+ ' onclick="window.DollhouseConsole.forceReload(\'session-expired\')">Reload</button>';
|
|
2179
2240
|
document.body.appendChild(toast);
|
|
2180
2241
|
});
|
|
2181
2242
|
|
|
@@ -14,14 +14,16 @@
|
|
|
14
14
|
<meta name="dollhouse-console-token" content="{{CONSOLE_TOKEN}}">
|
|
15
15
|
<!-- Server version — injected at request time for version-aware UI behaviour (e.g. setup-seen per version). -->
|
|
16
16
|
<meta name="dollhouse-server-version" content="{{DOLLHOUSE_VERSION}}">
|
|
17
|
-
|
|
18
|
-
<
|
|
19
|
-
<link rel="stylesheet" href="
|
|
20
|
-
<link rel="stylesheet" href="
|
|
21
|
-
<link rel="stylesheet" href="
|
|
22
|
-
<link rel="stylesheet" href="
|
|
23
|
-
<link rel="stylesheet" href="
|
|
24
|
-
<link rel="stylesheet" href="
|
|
17
|
+
<!-- Asset version — injected at request time for cache-busting local CSS/JS/img files. -->
|
|
18
|
+
<meta name="dollhouse-console-asset-version" content="{{DOLLHOUSE_ASSET_VERSION}}">
|
|
19
|
+
<link rel="stylesheet" href="fonts.css?v={{DOLLHOUSE_ASSET_VERSION}}">
|
|
20
|
+
<link rel="stylesheet" href="styles.css?v={{DOLLHOUSE_ASSET_VERSION}}">
|
|
21
|
+
<link rel="stylesheet" href="logs.css?v={{DOLLHOUSE_ASSET_VERSION}}">
|
|
22
|
+
<link rel="stylesheet" href="metrics.css?v={{DOLLHOUSE_ASSET_VERSION}}">
|
|
23
|
+
<link rel="stylesheet" href="permissions.css?v={{DOLLHOUSE_ASSET_VERSION}}">
|
|
24
|
+
<link rel="stylesheet" href="sessions.css?v={{DOLLHOUSE_ASSET_VERSION}}">
|
|
25
|
+
<link rel="stylesheet" href="setup.css?v={{DOLLHOUSE_ASSET_VERSION}}">
|
|
26
|
+
<link rel="stylesheet" href="security.css?v={{DOLLHOUSE_ASSET_VERSION}}">
|
|
25
27
|
<!-- uPlot for metrics time-series charts -->
|
|
26
28
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/uplot@1.6.30/dist/uPlot.min.css" integrity="sha384-IfV0B7MIOYuO95kO9G5ySKPz/85zqFNOAs8iy4tkK5zd9izhJAB8b7lHrwYqqmYE" crossorigin="anonymous">
|
|
27
29
|
</head>
|
|
@@ -31,7 +33,7 @@
|
|
|
31
33
|
|
|
32
34
|
<header class="site-header">
|
|
33
35
|
<div class="header-brand">
|
|
34
|
-
<img src="dollhouse-logo.png" alt="DollhouseMCP" class="header-logo" width="32" height="32">
|
|
36
|
+
<img src="dollhouse-logo.png?v={{DOLLHOUSE_ASSET_VERSION}}" alt="DollhouseMCP" class="header-logo" width="32" height="32">
|
|
35
37
|
<div class="header-brand-text">
|
|
36
38
|
<h1 class="site-title">DollhouseMCP</h1>
|
|
37
39
|
<p class="site-tagline">Management Console</p>
|
|
@@ -598,13 +600,13 @@ npm install @dollhousemcp/mcp-server</code></pre>
|
|
|
598
600
|
<script src="https://cdn.jsdelivr.net/npm/uplot@1.6.30/dist/uPlot.iife.min.js" integrity="sha384-1NEYi76CBpge3gahk4+X4M4JzdOV3WYq84RnByqYdAd5SdvJBTNCPFh/nsoHfN6i" crossorigin="anonymous"></script>
|
|
599
601
|
<!-- Console auth helper must load first — it reads the token meta tag and
|
|
600
602
|
exposes window.DollhouseAuth for all subsequent scripts (#1780). -->
|
|
601
|
-
<script src="consoleAuth.js"></script>
|
|
602
|
-
<script src="setup.js"></script>
|
|
603
|
-
<script src="app.js"></script>
|
|
604
|
-
<script src="logs.js"></script>
|
|
605
|
-
<script src="metrics.js"></script>
|
|
606
|
-
<script src="permissions.js"></script>
|
|
607
|
-
<script src="sessions.js"></script>
|
|
608
|
-
<script src="security.js"></script>
|
|
603
|
+
<script src="consoleAuth.js?v={{DOLLHOUSE_ASSET_VERSION}}"></script>
|
|
604
|
+
<script src="setup.js?v={{DOLLHOUSE_ASSET_VERSION}}"></script>
|
|
605
|
+
<script src="app.js?v={{DOLLHOUSE_ASSET_VERSION}}"></script>
|
|
606
|
+
<script src="logs.js?v={{DOLLHOUSE_ASSET_VERSION}}"></script>
|
|
607
|
+
<script src="metrics.js?v={{DOLLHOUSE_ASSET_VERSION}}"></script>
|
|
608
|
+
<script src="permissions.js?v={{DOLLHOUSE_ASSET_VERSION}}"></script>
|
|
609
|
+
<script src="sessions.js?v={{DOLLHOUSE_ASSET_VERSION}}"></script>
|
|
610
|
+
<script src="security.js?v={{DOLLHOUSE_ASSET_VERSION}}"></script>
|
|
609
611
|
</body>
|
|
610
612
|
</html>
|