@pipeline-builder/api-server 3.4.130 → 3.4.131
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/lib/api/app-factory.d.ts +9 -0
- package/lib/api/app-factory.js +26 -5
- package/lib/api/idempotency-middleware.d.ts +32 -2
- package/lib/api/idempotency-middleware.js +73 -3
- package/lib/api/request-types.js +8 -3
- package/lib/api/route-wrapper.js +6 -2
- package/lib/api/tenant-context.js +4 -1
- package/lib/http/index.d.ts +1 -0
- package/lib/http/index.js +2 -1
- package/lib/http/sse-connection-manager.d.ts +45 -12
- package/lib/http/sse-connection-manager.js +54 -37
- package/lib/http/sse-ticket-store.d.ts +69 -0
- package/lib/http/sse-ticket-store.js +160 -0
- package/package.json +4 -4
|
@@ -4,6 +4,7 @@ import { randomBytes } from 'node:crypto';
|
|
|
4
4
|
import { createLogger, SSE_TICKET_TTL_MS } from '@pipeline-builder/api-core';
|
|
5
5
|
import { CoreConstants } from '@pipeline-builder/pipeline-core';
|
|
6
6
|
import { v7 as uuid } from 'uuid';
|
|
7
|
+
import { createMemoryTicketStore } from './sse-ticket-store.js';
|
|
7
8
|
const logger = createLogger('sse-manager');
|
|
8
9
|
/**
|
|
9
10
|
* A build-log stream subject id: either a dashed UUID (api-server's `uuid()`)
|
|
@@ -38,16 +39,17 @@ export class SSEManager {
|
|
|
38
39
|
* map mirrors `clients[].orgId` counts at all times. Orgs reach zero are
|
|
39
40
|
* deleted to keep the map bounded. */
|
|
40
41
|
orgClientCounts = new Map();
|
|
41
|
-
/**
|
|
42
|
-
* `maxTotalTickets` / `maxTicketsPerOrg
|
|
43
|
-
* validated
|
|
44
|
-
|
|
42
|
+
/** Ticket + stream-ownership backend (in-memory default; Redis for multi-pod).
|
|
43
|
+
* Bounded by `maxTotalTickets` / `maxTicketsPerOrg`, enforced in createTicket;
|
|
44
|
+
* expiry is validated at consume time and swept on the cleanup interval. */
|
|
45
|
+
ticketStore;
|
|
45
46
|
maxClientsPerRequest;
|
|
46
47
|
maxTotalClients;
|
|
47
48
|
maxClientsPerOrg;
|
|
48
49
|
maxTotalTickets;
|
|
49
50
|
maxTicketsPerOrg;
|
|
50
51
|
ticketTtlMs;
|
|
52
|
+
streamOwnerTtlMs;
|
|
51
53
|
clientTimeoutMs;
|
|
52
54
|
cleanupInterval = null;
|
|
53
55
|
constructor(options = {}) {
|
|
@@ -57,6 +59,8 @@ export class SSEManager {
|
|
|
57
59
|
this.maxTotalTickets = options.maxTotalTickets ?? parseInt(process.env.SSE_MAX_TOTAL_TICKETS || '1000', 10);
|
|
58
60
|
this.maxTicketsPerOrg = options.maxTicketsPerOrg ?? parseInt(process.env.SSE_MAX_TICKETS_PER_ORG || '10', 10);
|
|
59
61
|
this.ticketTtlMs = options.ticketTtlMs ?? SSE_TICKET_TTL_MS;
|
|
62
|
+
this.streamOwnerTtlMs = options.streamOwnerTtlMs ?? parseInt(process.env.SSE_STREAM_OWNER_TTL_MS || '3600000', 10); // 1 hour
|
|
63
|
+
this.ticketStore = options.ticketStore ?? createMemoryTicketStore();
|
|
60
64
|
this.clientTimeoutMs = options.clientTimeoutMs ?? parseInt(process.env.SSE_CLIENT_TIMEOUT_MS || '1800000', 10); // 30 minutes
|
|
61
65
|
const cleanupIntervalMs = options.cleanupIntervalMs ?? parseInt(process.env.SSE_CLEANUP_INTERVAL_MS || '300000', 10); // 5 minutes
|
|
62
66
|
this.startCleanupInterval(cleanupIntervalMs);
|
|
@@ -81,14 +85,20 @@ export class SSEManager {
|
|
|
81
85
|
static normalizeRequestId(requestId) {
|
|
82
86
|
return requestId.replace(/-/g, '').toLowerCase();
|
|
83
87
|
}
|
|
84
|
-
/**
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
88
|
+
/**
|
|
89
|
+
* Record the org that OWNS a stream subject. The stream PRODUCER calls this
|
|
90
|
+
* when it creates a build-log stream so that ticket minting can assert the
|
|
91
|
+
* caller's org owns the subject (see {@link createTicket}). Backed by the
|
|
92
|
+
* injected ticket store, so when a Redis store is wired the platform producer
|
|
93
|
+
* (a different service sharing the same Redis) can bind ownership that this
|
|
94
|
+
* service reads — closing the cross-tenant attach gap where any org could mint
|
|
95
|
+
* a ticket for a guessed requestId.
|
|
96
|
+
*
|
|
97
|
+
* @param requestId - The stream subject (format-validated by the caller).
|
|
98
|
+
* @param orgId - The owning org (already normalized by the caller).
|
|
99
|
+
*/
|
|
100
|
+
async bindStreamOwner(requestId, orgId) {
|
|
101
|
+
await this.ticketStore.bindStreamOwner(SSEManager.normalizeRequestId(requestId), orgId, this.streamOwnerTtlMs);
|
|
92
102
|
}
|
|
93
103
|
/**
|
|
94
104
|
* Mint a short-lived, single-use SSE ticket bound to `orgId` AND a specific
|
|
@@ -98,6 +108,13 @@ export class SSEManager {
|
|
|
98
108
|
* ticket can then only be consumed to open that one subject's stream — see
|
|
99
109
|
* {@link consumeTicket} — which is what enforces per-subject authorization.
|
|
100
110
|
*
|
|
111
|
+
* ORG-OWNERSHIP: if a stream owner has been bound for this subject (via
|
|
112
|
+
* {@link bindStreamOwner}) and it is a DIFFERENT org, minting is refused
|
|
113
|
+
* (`reason: 'forbidden'`) — an org cannot mint a ticket for another org's
|
|
114
|
+
* stream even if it guesses the requestId. When no owner is bound (producer
|
|
115
|
+
* wiring not yet present), minting falls back to binding the ticket to the
|
|
116
|
+
* caller's own org, preserving current behavior.
|
|
117
|
+
*
|
|
101
118
|
* Bounded by `maxTotalTickets` (process-wide) and `maxTicketsPerOrg`
|
|
102
119
|
* (per-tenant). Mirrors the message-service notifications ticket store.
|
|
103
120
|
*
|
|
@@ -105,26 +122,29 @@ export class SSEManager {
|
|
|
105
122
|
* @param requestId - The build-log stream subject this ticket authorizes.
|
|
106
123
|
* The caller must have format-validated it (see {@link SSE_REQUEST_ID_RE}).
|
|
107
124
|
* @returns `{ ok: true, ticket }` on success, or `{ ok: false, reason }`
|
|
108
|
-
* where reason is `'org-limit'`
|
|
125
|
+
* where reason is `'org-limit'`, `'capacity'`, or `'forbidden'`.
|
|
109
126
|
*/
|
|
110
|
-
createTicket(orgId, requestId) {
|
|
111
|
-
|
|
112
|
-
//
|
|
127
|
+
async createTicket(orgId, requestId) {
|
|
128
|
+
// Ownership gate first — a cross-tenant mint attempt should never even
|
|
129
|
+
// consume cap budget. Only enforced when an owner is actually bound.
|
|
130
|
+
const normalized = SSEManager.normalizeRequestId(requestId);
|
|
131
|
+
const owner = await this.ticketStore.getStreamOwner(normalized);
|
|
132
|
+
if (owner && owner !== orgId) {
|
|
133
|
+
logger.warn(`SSE ticket refused: org ${orgId} does not own stream subject`);
|
|
134
|
+
return { ok: false, reason: 'forbidden' };
|
|
135
|
+
}
|
|
136
|
+
// Total cap next — protects process memory even when a single org is
|
|
113
137
|
// the offender. Then the per-org cap for fair-share.
|
|
114
|
-
if (this.
|
|
138
|
+
if ((await this.ticketStore.total()) >= this.maxTotalTickets) {
|
|
115
139
|
logger.warn(`SSE ticket cap reached (max: ${this.maxTotalTickets}); rejecting ticket request`);
|
|
116
140
|
return { ok: false, reason: 'capacity' };
|
|
117
141
|
}
|
|
118
|
-
if (this.
|
|
142
|
+
if ((await this.ticketStore.countForOrg(orgId)) >= this.maxTicketsPerOrg) {
|
|
119
143
|
logger.warn(`Per-org SSE ticket cap reached for ${orgId} (max: ${this.maxTicketsPerOrg})`);
|
|
120
144
|
return { ok: false, reason: 'org-limit' };
|
|
121
145
|
}
|
|
122
146
|
const ticket = randomBytes(24).toString('base64url');
|
|
123
|
-
this.
|
|
124
|
-
orgId,
|
|
125
|
-
requestId: SSEManager.normalizeRequestId(requestId),
|
|
126
|
-
expiresAt: now + this.ticketTtlMs,
|
|
127
|
-
});
|
|
147
|
+
await this.ticketStore.put(ticket, { orgId, requestId: normalized }, this.ticketTtlMs);
|
|
128
148
|
return { ok: true, ticket };
|
|
129
149
|
}
|
|
130
150
|
/**
|
|
@@ -145,10 +165,9 @@ export class SSEManager {
|
|
|
145
165
|
* @param requestId - The stream subject from the URL path (`:requestId`),
|
|
146
166
|
* already format-validated by the caller.
|
|
147
167
|
*/
|
|
148
|
-
consumeTicket(ticketId, requestId) {
|
|
149
|
-
const ticket = this.
|
|
150
|
-
|
|
151
|
-
if (!ticket || Date.now() > ticket.expiresAt)
|
|
168
|
+
async consumeTicket(ticketId, requestId) {
|
|
169
|
+
const ticket = await this.ticketStore.consume(ticketId); // single-use
|
|
170
|
+
if (!ticket)
|
|
152
171
|
return null;
|
|
153
172
|
// Subject binding — reject a ticket presented for a subject it was not
|
|
154
173
|
// minted for. Both sides are normalized so dashed/undashed forms match.
|
|
@@ -406,7 +425,7 @@ export class SSEManager {
|
|
|
406
425
|
* ```
|
|
407
426
|
*/
|
|
408
427
|
middleware() {
|
|
409
|
-
return (req, res) => {
|
|
428
|
+
return async (req, res) => {
|
|
410
429
|
const { requestId } = req.params;
|
|
411
430
|
if (!SSE_REQUEST_ID_RE.test(requestId)) {
|
|
412
431
|
res.status(400).end('Invalid requestId format');
|
|
@@ -423,7 +442,7 @@ export class SSEManager {
|
|
|
423
442
|
res.status(401).end('Missing ticket');
|
|
424
443
|
return;
|
|
425
444
|
}
|
|
426
|
-
const consumed = this.consumeTicket(ticketId, requestId);
|
|
445
|
+
const consumed = await this.consumeTicket(ticketId, requestId);
|
|
427
446
|
if (!consumed) {
|
|
428
447
|
res.status(401).end('Invalid or expired ticket');
|
|
429
448
|
return;
|
|
@@ -484,13 +503,11 @@ export class SSEManager {
|
|
|
484
503
|
cleanup() {
|
|
485
504
|
const now = Date.now();
|
|
486
505
|
let cleaned = 0;
|
|
487
|
-
// Sweep expired tickets so
|
|
488
|
-
// minted but never consumed (client closed the tab before
|
|
489
|
-
// Consume-time still re-checks expiry, so this is memory
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
this.tickets.delete(id);
|
|
493
|
-
}
|
|
506
|
+
// Sweep expired tickets/owners so an in-memory store stays bounded even when
|
|
507
|
+
// tickets are minted but never consumed (client closed the tab before
|
|
508
|
+
// connecting). Consume-time still re-checks expiry, so this is memory
|
|
509
|
+
// hygiene only; the Redis store relies on native key TTL (sweep is a no-op).
|
|
510
|
+
void this.ticketStore.sweep?.();
|
|
494
511
|
for (const [requestId, clients] of this.clients.entries()) {
|
|
495
512
|
const stale = [];
|
|
496
513
|
const active = [];
|
|
@@ -541,4 +558,4 @@ export class SSEManager {
|
|
|
541
558
|
logger.info('SSE Manager shut down');
|
|
542
559
|
}
|
|
543
560
|
}
|
|
544
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3NlLWNvbm5lY3Rpb24tbWFuYWdlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9odHRwL3NzZS1jb25uZWN0aW9uLW1hbmFnZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQUV0QyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQzFDLE9BQU8sRUFBRSxZQUFZLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUM3RSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFFaEUsT0FBTyxFQUFFLEVBQUUsSUFBSSxJQUFJLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFFbEMsTUFBTSxNQUFNLEdBQUcsWUFBWSxDQUFDLGFBQWEsQ0FBQyxDQUFDO0FBNEUzQzs7Ozs7OztHQU9HO0FBQ0gsTUFBTSxDQUFDLE1BQU0saUJBQWlCLEdBQUcscUVBQXFFLENBQUM7QUErQnZHOzs7Ozs7Ozs7Ozs7Ozs7OztHQWlCRztBQUNILE1BQU0sT0FBTyxVQUFVO0lBQ2IsT0FBTyxHQUFHLElBQUksR0FBRyxFQUF1QixDQUFDO0lBQ2pEOzsyQ0FFdUM7SUFDL0IsZUFBZSxHQUFHLElBQUksR0FBRyxFQUFrQixDQUFDO0lBQ3BEOzs4Q0FFMEM7SUFDbEMsT0FBTyxHQUFHLElBQUksR0FBRyxFQUFxQixDQUFDO0lBQzlCLG9CQUFvQixDQUFTO0lBQzdCLGVBQWUsQ0FBUztJQUN4QixnQkFBZ0IsQ0FBUztJQUN6QixlQUFlLENBQVM7SUFDeEIsZ0JBQWdCLENBQVM7SUFDekIsV0FBVyxDQUFTO0lBQ3BCLGVBQWUsQ0FBUztJQUNqQyxlQUFlLEdBQTBCLElBQUksQ0FBQztJQUV0RCxZQUFZLE9BQU8sR0FBc0IsRUFBRTtRQUN6QyxJQUFJLENBQUMsb0JBQW9CLEdBQUcsT0FBTyxDQUFDLG9CQUFvQixJQUFJLFFBQVEsQ0FBQyxPQUFPLENBQUMsR0FBRyxD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LEdBQUcsRUFBRSxDQUFDO2dCQUFDLENBQUM7Z0JBQUMsTUFBTSxDQUFDLENBQUMsb0JBQW9CLENBQUMsQ0FBQztnQkFDeEQsT0FBTyxFQUFFLENBQUM7WUFDWixDQUFDO1lBRUQsSUFBSSxNQUFNLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO2dCQUN4QixJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUNqQyxDQUFDO2lCQUFNLElBQUksS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztnQkFDNUIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsU0FBUyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQ3RDLENBQUM7UUFDSCxDQUFDO1FBRUQsSUFBSSxPQUFPLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDaEIsTUFBTSxDQUFDLElBQUksQ0FBQyxjQUFjLE9BQU8sd0JBQXdCLENBQUMsQ0FBQztRQUM3RCxDQUFDO0lBQ0gsQ0FBQztJQUVEOztPQUVHO0lBQ0gsUUFBUTtRQUNOLElBQUksSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO1lBQ3pCLGFBQWEsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUM7WUFDcEMsSUFBSSxDQUFDLGVBQWUsR0FBRyxJQUFJLENBQUM7UUFDOUIsQ0FBQztRQUVELEtBQUssTUFBTSxTQUFTLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDO1lBQ2pELElBQUksQ0FBQyxZQUFZLENBQUMsU0FBUyxFQUFFLHNCQUFzQixDQUFDLENBQUM7UUFDdkQsQ0FBQztRQUVELE1BQU0sQ0FBQyxJQUFJLENBQUMsdUJBQXVCLENBQUMsQ0FBQztJQUN2QyxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuaW1wb3J0IHsgcmFuZG9tQnl0ZXMgfSBmcm9tICdub2RlOmNyeXB0byc7XG5pbXBvcnQgeyBjcmVhdGVMb2dnZXIsIFNTRV9USUNLRVRfVFRMX01TIH0gZnJvbSAnQHBpcGVsaW5lLWJ1aWxkZXIvYXBpLWNvcmUnO1xuaW1wb3J0IHsgQ29yZUNvbnN0YW50cyB9IGZyb20gJ0BwaXBlbGluZS1idWlsZGVyL3BpcGVsaW5lLWNvcmUnO1xuaW1wb3J0IHR5cGUgeyBSZXNwb25zZSB9IGZyb20gJ2V4cHJlc3MnO1xuaW1wb3J0IHsgdjcgYXMgdXVpZCB9IGZyb20gJ3V1aWQnO1xuXG5jb25zdCBsb2dnZXIgPSBjcmVhdGVMb2dnZXIoJ3NzZS1tYW5hZ2VyJyk7XG5cbi8qKlxuICogRXZlbnQgdHlwZXMgZm9yIFNTRSBsb2dnaW5nXG4gKi9cbmV4cG9ydCB0eXBlIFNTRUV2ZW50VHlwZSA9ICdJTkZPJyB8ICdXQVJOJyB8ICdFUlJPUicgfCAnQ09NUExFVEVEJyB8ICdST0xMQkFDSycgfCAnTUVTU0FHRSc7XG5cbi8qKlxuICogU1NFIHBheWxvYWQgc3RydWN0dXJlXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU1NFUGF5bG9hZCB7XG4gIHRzOiBzdHJpbmc7XG4gIHR5cGU6IFNTRUV2ZW50VHlwZTtcbiAgbWVzc2FnZTogc3RyaW5nO1xuICBkYXRhPzogdW5rbm93bjtcbn1cblxuLyoqXG4gKiBTU0UgY2xpZW50IHdpdGggY29ubmVjdGlvbiB0cmFja2luZ1xuICovXG5leHBvcnQgaW50ZXJmYWNlIFNTRUNsaWVudCB7XG4gIGlkOiBzdHJpbmc7XG4gIHJlczogUmVzcG9uc2U7XG4gIGNvbm5lY3RlZEF0OiBudW1iZXI7XG4gIHRpbWVvdXQ6IE5vZGVKUy5UaW1lb3V0O1xuICAvKiogTnVtYmVyIG9mIGNvbnNlY3V0aXZlIGJhY2twcmVzc3VyZSBldmVudHMgKHdyaXRlIHJldHVybmVkIGZhbHNlKS4gKi9cbiAgYmFja3ByZXNzdXJlQ291bnQ6IG51bWJlcjtcbiAgLyoqIE93bmluZyBvcmcgaWQg4oCUIHBvcHVsYXRlZCB3aGVuIHRoZSByZXF1ZXN0IHdhcyBhdXRoZW50aWNhdGVkLiBVc2VkIHRvXG4gICAqICBkZWNyZW1lbnQgdGhlIHBlci1vcmcgY291bnRlciBvbiBkaXNjb25uZWN0IC8gY2xlYW51cC4gKi9cbiAgb3JnSWQ/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogU1NFIE1hbmFnZXIgY29uZmlndXJhdGlvbiBvcHRpb25zXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU1NFTWFuYWdlck9wdGlvbnMge1xuICAvKiogTWF4aW11bSBjbGllbnRzIGFsbG93ZWQgcGVyIHJlcXVlc3QgSUQgKGRlZmF1bHQ6IDEwKSAqL1xuICBtYXhDbGllbnRzUGVyUmVxdWVzdD86IG51bWJlcjtcbiAgLyoqIENsaWVudCB0aW1lb3V0IGluIG1pbGxpc2Vjb25kcyAoZGVmYXVsdDogMzAgbWludXRlcykgKi9cbiAgY2xpZW50VGltZW91dE1zPzogbnVtYmVyO1xuICAvKiogSW50ZXJ2YWwgZm9yIGNsZWFudXAgY2hlY2tzIGluIG1pbGxpc2Vjb25kcyAoZGVmYXVsdDogNSBtaW51dGVzKSAqL1xuICBjbGVhbnVwSW50ZXJ2YWxNcz86IG51bWJlcjtcbiAgLyoqXG4gICAqIEhhcmQgY2FwIG9uIHRvdGFsIG9wZW4gY29ubmVjdGlvbnMgcGVyIHByb2Nlc3MuIERlZmF1bHRzIHRvIDEwMDAgZnJvbVxuICAgKiBgU1NFX01BWF9UT1RBTF9DTElFTlRTYC4gTmV3IGNvbm5lY3Rpb25zIGJleW9uZCB0aGlzIGFyZSByZWplY3RlZCBhdFxuICAgKiBgYWRkQ2xpZW50KClgLiBUdW5lIHVwIGlmIHlvdXIgc2VydmljZSBzZXJ2ZXMgPiAxMDAwIGNvbmN1cnJlbnQgU1NFXG4gICAqIGRhc2hib2FyZHMsIGJ1dCBiZSBhd2FyZSBOb2RlLmpzIGZkIGxpbWl0cyBkb21pbmF0ZSBhYm92ZSB+NTAwMC5cbiAgICovXG4gIG1heFRvdGFsQ2xpZW50cz86IG51bWJlcjtcbiAgLyoqXG4gICAqIFBlci1vcmcgY2VpbGluZyBvbiBjb25jdXJyZW50IFNTRSBzdHJlYW1zLiBEZWZhdWx0cyB0byA1MCBmcm9tXG4gICAqIGBTU0VfTUFYX0NMSUVOVFNfUEVSX09SR2AuIFByb3RlY3RzIGFnYWluc3Qgb25lIG5vaXN5IG9yZyBjb25zdW1pbmcgdGhlXG4gICAqIHByb2Nlc3Mtd2lkZSBidWRnZXQg4oCUIHdpdGhvdXQgaXQsIGFuIGF1dGhlbnRpY2F0ZWQgdXNlciBjYW4gZmFuIG91dFxuICAgKiB0aG91c2FuZHMgb2Ygc3RyZWFtcyAob25lIHBlciBkYXNoYm9hcmQgLyBsb2cgc3RyZWFtKSBhbmQgc3RhcnZlIG90aGVyXG4gICAqIG9yZ3Mgb2YgY29ubmVjdGlvbiBzbG90cy4gVGhlIGNhcCBpcyBlbmZvcmNlZCBvbmx5IG9uIGBhZGRDbGllbnRgIGNhbGxzXG4gICAqIHRoYXQgY2FycnkgYW4gYG9yZ0lkYDsgc2VydmljZS1pbnRlcm5hbCAvIGFub255bW91cyBTU0UgdHJhZmZpYyBza2lwcyBpdC5cbiAgICovXG4gIG1heENsaWVudHNQZXJPcmc/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBIYXJkIGNhcCBvbiB0b3RhbCBsaXZlICh1bmNvbnN1bWVkLCB1bmV4cGlyZWQpIFNTRSB0aWNrZXRzIGFjcm9zcyB0aGVcbiAgICogcHJvY2Vzcy4gRGVmYXVsdHMgdG8gMTAwMCBmcm9tIGBTU0VfTUFYX1RPVEFMX1RJQ0tFVFNgLiBCb3VuZHMgbWVtb3J5XG4gICAqIHVuZGVyIGFidXNlIOKAlCBgY3JlYXRlVGlja2V0YCByZXR1cm5zIGB7IG9rOiBmYWxzZSwgcmVhc29uOiAnY2FwYWNpdHknIH1gXG4gICAqIG9uY2UgcmVhY2hlZC5cbiAgICovXG4gIG1heFRvdGFsVGlja2V0cz86IG51bWJlcjtcbiAgLyoqXG4gICAqIFBlci1vcmcgY2FwIG9uIGxpdmUgU1NFIHRpY2tldHMuIERlZmF1bHRzIHRvIDEwIGZyb21cbiAgICogYFNTRV9NQVhfVElDS0VUU19QRVJfT1JHYC4gUHJldmVudHMgYSBzaW5nbGUgdGVuYW50IGZyb20gc2F0dXJhdGluZyB0aGVcbiAgICogdGlja2V0IHRhYmxlIOKAlCBgY3JlYXRlVGlja2V0YCByZXR1cm5zIGB7IG9rOiBmYWxzZSwgcmVhc29uOiAnb3JnLWxpbWl0JyB9YFxuICAgKiBvbmNlIHJlYWNoZWQuXG4gICAqL1xuICBtYXhUaWNrZXRzUGVyT3JnPzogbnVtYmVyO1xuICAvKiogVGlja2V0IFRUTCBpbiBtcyAoZGVmYXVsdDogYFNTRV9USUNLRVRfVFRMX01TYCBmcm9tIGFwaS1jb3JlKS4gKi9cbiAgdGlja2V0VHRsTXM/OiBudW1iZXI7XG59XG5cbi8qKlxuICogQSBidWlsZC1sb2cgc3RyZWFtIHN1YmplY3QgaWQ6IGVpdGhlciBhIGRhc2hlZCBVVUlEIChhcGktc2VydmVyJ3MgYHV1aWQoKWApXG4gKiBvciBuZ2lueCdzIGAkcmVxdWVzdF9pZGAg4oCUIDE2IHJhbmRvbSBieXRlcyByZW5kZXJlZCBhcyAzMiBoZXggY2hhcnMgd2l0aCBOT1xuICogZGFzaGVzLiBBY2NlcHQgYm90aCBieSBtYWtpbmcgdGhlIGdyb3VwIHNlcGFyYXRvcnMgb3B0aW9uYWw7IHN0aWxsIHN0cmljdGx5XG4gKiAzMiBoZXggY2hhcnMgc28gaXQgY2FuJ3QgY2FycnkgYW4gaW5qZWN0aW9uIC8gcGF0aC10cmF2ZXJzYWwgcGF5bG9hZCBpbnRvIHRoZVxuICogU1NFIHN1YmplY3QuIFNoYXJlZCBieSB0aGUgdGlja2V0LW1pbnQgcm91dGUgYW5kIHRoZSBzdHJlYW0gbWlkZGxld2FyZSBzb1xuICogYm90aCB2YWxpZGF0ZSB0aGUgc3ViamVjdCBpZGVudGljYWxseS5cbiAqL1xuZXhwb3J0IGNvbnN0IFNTRV9SRVFVRVNUX0lEX1JFID0gL15bMC05YS1mXXs4fS0/WzAtOWEtZl17NH0tP1swLTlhLWZdezR9LT9bMC05YS1mXXs0fS0/WzAtOWEtZl17MTJ9JC9pO1xuXG4vKiogQSBtaW50ZWQgU1NFIHRpY2tldCDigJQgc2luZ2xlLXVzZSwgb3JnLWJvdW5kLCBzdWJqZWN0LWJvdW5kLCBzaG9ydC1saXZlZC4gKi9cbmludGVyZmFjZSBTU0VUaWNrZXQge1xuICBvcmdJZDogc3RyaW5nO1xuICAvKipcbiAgICogVGhlIGJ1aWxkLWxvZyBzdHJlYW0gc3ViamVjdCB0aGlzIHRpY2tldCBhdXRob3JpemVzLiBBIHRpY2tldCBtYXkgT05MWSBiZVxuICAgKiBjb25zdW1lZCB0byBvcGVuIHRoZSBzdHJlYW0gZm9yIHRoaXMgZXhhY3QgcmVxdWVzdElkLiBCaW5kcyB0aGUgc2luZ2xlLXVzZVxuICAgKiB0aWNrZXQgdG8gYSBzcGVjaWZpYyBzdWJqZWN0IHNvIGFuIGF1dGhlbnRpY2F0ZWQgb3JnIGNhbid0IGF0dGFjaCB0byBhXG4gICAqIHN0cmVhbSBpdCB3YXMgbmV2ZXIgaXNzdWVkIGZvciAocHJldmlvdXNseSB0aGUgYDpyZXF1ZXN0SWRgIHdhcyBvbmx5XG4gICAqIGZvcm1hdC12YWxpZGF0ZWQsIHNvIGFueSBvcmcgY291bGQgc3Vic2NyaWJlIHRvIGFueSBzdWJqZWN0IGl0IGNvdWxkXG4gICAqIGd1ZXNzKS4gU3RvcmVkIG5vcm1hbGl6ZWQgKGRhc2hlcyBzdHJpcHBlZCwgbG93ZXJjYXNlZCkgZm9yIGNvbXBhcmlzb24uXG4gICAqL1xuICByZXF1ZXN0SWQ6IHN0cmluZztcbiAgZXhwaXJlc0F0OiBudW1iZXI7XG59XG5cbi8qKiBSZXN1bHQgb2Yge0BsaW5rIFNTRU1hbmFnZXIuY3JlYXRlVGlja2V0fS4gKi9cbmV4cG9ydCB0eXBlIENyZWF0ZVRpY2tldFJlc3VsdCA9XG4gIHwgeyBvazogdHJ1ZTsgdGlja2V0OiBzdHJpbmcgfVxuICB8IHsgb2s6IGZhbHNlOyByZWFzb246ICdvcmctbGltaXQnIHwgJ2NhcGFjaXR5JyB9O1xuXG4vKipcbiAqIFNTRSBNYW5hZ2VyIHN0YXRpc3RpY3NcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTU0VNYW5hZ2VyU3RhdHMge1xuICB0b3RhbFJlcXVlc3RzOiBudW1iZXI7XG4gIHRvdGFsQ2xpZW50czogbnVtYmVyO1xuICBvbGRlc3RDb25uZWN0aW9uTXM6IG51bWJlciB8IG51bGw7XG59XG5cbi8qKlxuICogU1NFIGhlbHBlciBjbGFzcyB3aXRoIG1lbW9yeSBsZWFrIHByb3RlY3Rpb25cbiAqXG4gKiBGZWF0dXJlczpcbiAqIC0gQ2xpZW50IGxpbWl0cyBwZXIgcmVxdWVzdCBJRFxuICogLSBBdXRvbWF0aWMgdGltZW91dCBmb3IgaWRsZSBjb25uZWN0aW9uc1xuICogLSBQZXJpb2RpYyBjbGVhbnVwIG9mIHN0YWxlIGNvbm5lY3Rpb25zXG4gKiAtIENvbm5lY3Rpb24gc3RhdGlzdGljc1xuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCBzc2VNYW5hZ2VyID0gbmV3IFNTRU1hbmFnZXIoeyBtYXhDbGllbnRzUGVyUmVxdWVzdDogNSB9KTtcbiAqIGFwcC5nZXQoJy9sb2dzLzpyZXF1ZXN0SWQnLCBzc2VNYW5hZ2VyLm1pZGRsZXdhcmUoKSk7XG4gKlxuICogLy8gU2VuZCBldmVudHNcbiAqIHNzZU1hbmFnZXIuc2VuZCgncmVxdWVzdC0xMjMnLCAnSU5GTycsICdQcm9jZXNzaW5nLi4uJyk7XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGNsYXNzIFNTRU1hbmFnZXIge1xuICBwcml2YXRlIGNsaWVudHMgPSBuZXcgTWFwPHN0cmluZywgU1NFQ2xpZW50W10+KCk7XG4gIC8qKiBQZXItb3JnIG9wZW4tY2xpZW50IGNvdW50ZXJzLiBEZWNyZW1lbnRlZCBvbiByZW1vdmVDbGllbnQvY2xlYW51cCBzbyB0aGVcbiAgICogIG1hcCBtaXJyb3JzIGBjbGllbnRzW10ub3JnSWRgIGNvdW50cyBhdCBhbGwgdGltZXMuIE9yZ3MgcmVhY2ggemVybyBhcmVcbiAgICogIGRlbGV0ZWQgdG8ga2VlcCB0aGUgbWFwIGJvdW5kZWQuICovXG4gIHByaXZhdGUgb3JnQ2xpZW50Q291bnRzID0gbmV3IE1hcDxzdHJpbmcsIG51bWJlcj4oKTtcbiAgLyoqIFNpbmdsZS11c2UgU1NFIHRpY2tldHMsIGtleWVkIGJ5IG9wYXF1ZSB0aWNrZXQgaWQuIEJvdW5kZWQgYnlcbiAgICogIGBtYXhUb3RhbFRpY2tldHNgIC8gYG1heFRpY2tldHNQZXJPcmdgOyBzd2VwdCBvbiB0aGUgY2xlYW51cCBpbnRlcnZhbCBhbmRcbiAgICogIHZhbGlkYXRlZCAoZXhwaXJ5KSBhdCBjb25zdW1lIHRpbWUuICovXG4gIHByaXZhdGUgdGlja2V0cyA9IG5ldyBNYXA8c3RyaW5nLCBTU0VUaWNrZXQ+KCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgbWF4Q2xpZW50c1BlclJlcXVlc3Q6IG51bWJlcjtcbiAgcHJpdmF0ZSByZWFkb25seSBtYXhUb3RhbENsaWVudHM6IG51bWJlcjtcbiAgcHJpdmF0ZSByZWFkb25seSBtYXhDbGllbnRzUGVyT3JnOiBudW1iZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgbWF4VG90YWxUaWNrZXRzOiBudW1iZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgbWF4VGlja2V0c1Blck9yZzogbnVtYmVyO1xuICBwcml2YXRlIHJlYWRvbmx5IHRpY2tldFR0bE1zOiBudW1iZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgY2xpZW50VGltZW91dE1zOiBudW1iZXI7XG4gIHByaXZhdGUgY2xlYW51cEludGVydmFsOiBOb2RlSlMuVGltZW91dCB8IG51bGwgPSBudWxsO1xuXG4gIGNvbnN0cnVjdG9yKG9wdGlvbnM6IFNTRU1hbmFnZXJPcHRpb25zID0ge30pIHtcbiAgICB0aGlzLm1heENsaWVudHNQZXJSZXF1ZXN0ID0gb3B0aW9ucy5tYXhDbGllbnRzUGVyUmVxdWVzdCA/PyBwYXJzZUludChwcm9jZXNzLmVudi5TU0VfTUFYX0NMSUVOVFNfUEVSX1JFUVVFU1QgfHwgJzEwJywgMTApO1xuICAgIHRoaXMubWF4VG90YWxDbGllbnRzID0gb3B0aW9ucy5tYXhUb3RhbENsaWVudHMgPz8gcGFyc2VJbnQocHJvY2Vzcy5lbnYuU1NFX01BWF9UT1RBTF9DTElFTlRTIHx8ICcxMDAwJywgMTApO1xuICAgIHRoaXMubWF4Q2xpZW50c1Blck9yZyA9IG9wdGlvbnMubWF4Q2xpZW50c1Blck9yZyA/PyBwYXJzZUludChwcm9jZXNzLmVudi5TU0VfTUFYX0NMSUVOVFNfUEVSX09SRyB8fCAnNTAnLCAxMCk7XG4gICAgdGhpcy5tYXhUb3RhbFRpY2tldHMgPSBvcHRpb25zLm1heFRvdGFsVGlja2V0cyA/PyBwYXJzZUludChwcm9jZXNzLmVudi5TU0VfTUFYX1RPVEFMX1RJQ0tFVFMgfHwgJzEwMDAnLCAxMCk7XG4gICAgdGhpcy5tYXhUaWNrZXRzUGVyT3JnID0gb3B0aW9ucy5tYXhUaWNrZXRzUGVyT3JnID8/IHBhcnNlSW50KHByb2Nlc3MuZW52LlNTRV9NQVhfVElDS0VUU19QRVJfT1JHIHx8ICcxMCcsIDEwKTtcbiAgICB0aGlzLnRpY2tldFR0bE1zID0gb3B0aW9ucy50aWNrZXRUdGxNcyA/PyBTU0VfVElDS0VUX1RUTF9NUztcbiAgICB0aGlzLmNsaWVudFRpbWVvdXRNcyA9IG9wdGlvbnMuY2xpZW50VGltZW91dE1zID8/IHBhcnNlSW50KHByb2Nlc3MuZW52LlNTRV9DTElFTlRfVElNRU9VVF9NUyB8fCAnMTgwMDAwMCcsIDEwKTsgLy8gMzAgbWludXRlc1xuXG4gICAgY29uc3QgY2xlYW51cEludGVydmFsTXMgPSBvcHRpb25zLmNsZWFudXBJbnRlcnZhbE1zID8/IHBhcnNlSW50KHByb2Nlc3MuZW52LlNTRV9DTEVBTlVQX0lOVEVSVkFMX01TIHx8ICczMDAwMDAnLCAxMCk7IC8vIDUgbWludXRlc1xuICAgIHRoaXMuc3RhcnRDbGVhbnVwSW50ZXJ2YWwoY2xlYW51cEludGVydmFsTXMpO1xuICB9XG5cbiAgLyoqIFRvdGFsIG9wZW4gY29ubmVjdGlvbnMgYWNyb3NzIGFsbCByZXF1ZXN0cy4gKi9cbiAgcHJpdmF0ZSB0b3RhbENsaWVudHMoKTogbnVtYmVyIHtcbiAgICBsZXQgbiA9IDA7XG4gICAgZm9yIChjb25zdCBjbGllbnRzIG9mIHRoaXMuY2xpZW50cy52YWx1ZXMoKSkgbiArPSBjbGllbnRzLmxlbmd0aDtcbiAgICByZXR1cm4gbjtcbiAgfVxuXG4gIC8qKiBDdXJyZW50IG9wZW4tc3RyZWFtIGNvdW50IGZvciBhbiBvcmcgKDAgaWYgdW5zZWVuKS4gKi9cbiAgZ2V0T3JnQ2xpZW50Q291bnQob3JnSWQ6IHN0cmluZyk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMub3JnQ2xpZW50Q291bnRzLmdldChvcmdJZCkgPz8gMDtcbiAgfVxuXG4gIC8qKlxuICAgKiBDYW5vbmljYWwgZm9ybSBvZiBhIHJlcXVlc3RJZCBmb3IgZXF1YWxpdHkgY2hlY2tzOiBkYXNoZXMgc3RyaXBwZWQgYW5kXG4gICAqIGxvd2VyY2FzZWQsIHNvIHRoZSBkYXNoZWQgKGFwaS1zZXJ2ZXIgYHV1aWQoKWApIGFuZCB1bmRhc2hlZCAobmdpbnhcbiAgICogYCRyZXF1ZXN0X2lkYCkgcmVuZGVyaW5ncyBvZiB0aGUgc2FtZSBpZCBjb21wYXJlIGVxdWFsLiBDYWxsZXJzIGFyZVxuICAgKiBleHBlY3RlZCB0byBoYXZlIGFscmVhZHkgZm9ybWF0LXZhbGlkYXRlZCBhZ2FpbnN0IHtAbGluayBTU0VfUkVRVUVTVF9JRF9SRX0uXG4gICAqL1xuICBwcml2YXRlIHN0YXRpYyBub3JtYWxpemVSZXF1ZXN0SWQocmVxdWVzdElkOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiByZXF1ZXN0SWQucmVwbGFjZSgvLS9nLCAnJykudG9Mb3dlckNhc2UoKTtcbiAgfVxuXG4gIC8qKiBDb3VudCBvZiBsaXZlICh1bmV4cGlyZWQpIHRpY2tldHMgY3VycmVudGx5IGhlbGQgZm9yIGFuIG9yZy4gKi9cbiAgcHJpdmF0ZSBjb3VudExpdmVUaWNrZXRzRm9yT3JnKG9yZ0lkOiBzdHJpbmcsIG5vdzogbnVtYmVyKTogbnVtYmVyIHtcbiAgICBsZXQgY291bnQgPSAwO1xuICAgIGZvciAoY29uc3QgdGlja2V0IG9mIHRoaXMudGlja2V0cy52YWx1ZXMoKSkge1xuICAgICAgaWYgKHRpY2tldC5vcmdJZCA9PT0gb3JnSWQgJiYgdGlja2V0LmV4cGlyZXNBdCA+IG5vdykgY291bnQrKztcbiAgICB9XG4gICAgcmV0dXJuIGNvdW50O1xuICB9XG5cbiAgLyoqXG4gICAqIE1pbnQgYSBzaG9ydC1saXZlZCwgc2luZ2xlLXVzZSBTU0UgdGlja2V0IGJvdW5kIHRvIGBvcmdJZGAgQU5EIGEgc3BlY2lmaWNcbiAgICogc3RyZWFtIHN1YmplY3QgKGByZXF1ZXN0SWRgKS4gQ2xpZW50cyBQT1NUIHRvIG9idGFpbiBvbmUgKEpXVC1hdXRoZW50aWNhdGVkKVxuICAgKiBmb3IgdGhlIGV4YWN0IHN0cmVhbSB0aGV5IGludGVuZCB0byBvcGVuLCB0aGVuIG9wZW4gdGhlIEV2ZW50U291cmNlIHdpdGhcbiAgICogYD90aWNrZXQ9PHQ+YCBzbyB0aGUgSldUIG5ldmVyIGxhbmRzIGluIGEgcXVlcnkgc3RyaW5nIC8gYWNjZXNzIGxvZy4gVGhlXG4gICAqIHRpY2tldCBjYW4gdGhlbiBvbmx5IGJlIGNvbnN1bWVkIHRvIG9wZW4gdGhhdCBvbmUgc3ViamVjdCdzIHN0cmVhbSDigJQgc2VlXG4gICAqIHtAbGluayBjb25zdW1lVGlja2V0fSDigJQgd2hpY2ggaXMgd2hhdCBlbmZvcmNlcyBwZXItc3ViamVjdCBhdXRob3JpemF0aW9uLlxuICAgKlxuICAgKiBCb3VuZGVkIGJ5IGBtYXhUb3RhbFRpY2tldHNgIChwcm9jZXNzLXdpZGUpIGFuZCBgbWF4VGlja2V0c1Blck9yZ2BcbiAgICogKHBlci10ZW5hbnQpLiBNaXJyb3JzIHRoZSBtZXNzYWdlLXNlcnZpY2Ugbm90aWZpY2F0aW9ucyB0aWNrZXQgc3RvcmUuXG4gICAqXG4gICAqIEBwYXJhbSBvcmdJZCAtIE93bmluZyBvcmcgKGFscmVhZHkgbm9ybWFsaXplZCBieSB0aGUgY2FsbGVyKS5cbiAgICogQHBhcmFtIHJlcXVlc3RJZCAtIFRoZSBidWlsZC1sb2cgc3RyZWFtIHN1YmplY3QgdGhpcyB0aWNrZXQgYXV0aG9yaXplcy5cbiAgICogICBUaGUgY2FsbGVyIG11c3QgaGF2ZSBmb3JtYXQtdmFsaWRhdGVkIGl0IChzZWUge0BsaW5rIFNTRV9SRVFVRVNUX0lEX1JFfSkuXG4gICAqIEByZXR1cm5zIGB7IG9rOiB0cnVlLCB0aWNrZXQgfWAgb24gc3VjY2Vzcywgb3IgYHsgb2s6IGZhbHNlLCByZWFzb24gfWBcbiAgICogICB3aGVyZSByZWFzb24gaXMgYCdvcmctbGltaXQnYCAocGVyLW9yZyBjYXApIG9yIGAnY2FwYWNpdHknYCAodG90YWwgY2FwKS5cbiAgICovXG4gIGNyZWF0ZVRpY2tldChvcmdJZDogc3RyaW5nLCByZXF1ZXN0SWQ6IHN0cmluZyk6IENyZWF0ZVRpY2tldFJlc3VsdCB7XG4gICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKTtcbiAgICAvLyBUb3RhbCBjYXAgZmlyc3Qg4oCUIHByb3RlY3RzIHByb2Nlc3MgbWVtb3J5IGV2ZW4gd2hlbiBhIHNpbmdsZSBvcmcgaXNcbiAgICAvLyB0aGUgb2ZmZW5kZXIuIFRoZW4gdGhlIHBlci1vcmcgY2FwIGZvciBmYWlyLXNoYXJlLlxuICAgIGlmICh0aGlzLnRpY2tldHMuc2l6ZSA+PSB0aGlzLm1heFRvdGFsVGlja2V0cykge1xuICAgICAgbG9nZ2VyLndhcm4oYFNTRSB0aWNrZXQgY2FwIHJlYWNoZWQgKG1heDogJHt0aGlzLm1heFRvdGFsVGlja2V0c30pOyByZWplY3RpbmcgdGlja2V0IHJlcXVlc3RgKTtcbiAgICAgIHJldHVybiB7IG9rOiBmYWxzZSwgcmVhc29uOiAnY2FwYWNpdHknIH07XG4gICAgfVxuICAgIGlmICh0aGlzLmNvdW50TGl2ZVRpY2tldHNGb3JPcmcob3JnSWQsIG5vdykgPj0gdGhpcy5tYXhUaWNrZXRzUGVyT3JnKSB7XG4gICAgICBsb2dnZXIud2FybihgUGVyLW9yZyBTU0UgdGlja2V0IGNhcCByZWFjaGVkIGZvciAke29yZ0lkfSAobWF4OiAke3RoaXMubWF4VGlja2V0c1Blck9yZ30pYCk7XG4gICAgICByZXR1cm4geyBvazogZmFsc2UsIHJlYXNvbjogJ29yZy1saW1pdCcgfTtcbiAgICB9XG5cbiAgICBjb25zdCB0aWNrZXQgPSByYW5kb21CeXRlcygyNCkudG9TdHJpbmcoJ2Jhc2U2NHVybCcpO1xuICAgIHRoaXMudGlja2V0cy5zZXQodGlja2V0LCB7XG4gICAgICBvcmdJZCxcbiAgICAgIHJlcXVlc3RJZDogU1NFTWFuYWdlci5ub3JtYWxpemVSZXF1ZXN0SWQocmVxdWVzdElkKSxcbiAgICAgIGV4cGlyZXNBdDogbm93ICsgdGhpcy50aWNrZXRUdGxNcyxcbiAgICB9KTtcbiAgICByZXR1cm4geyBvazogdHJ1ZSwgdGlja2V0IH07XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGUgYW5kIENPTlNVTUUgYSB0aWNrZXQgZm9yIGEgc3BlY2lmaWMgc3RyZWFtIHN1YmplY3QuIFNpbmdsZS11c2U6XG4gICAqIHRoZSB0aWNrZXQgaXMgZGVsZXRlZCB3aGV0aGVyIG9yIG5vdCBpdCB0dXJucyBvdXQgdG8gYmUgdmFsaWQsIHNvIGEgcmVwbGF5XG4gICAqIG9mIHRoZSBzYW1lIHZhbHVlIGFsd2F5cyBmYWlscy4gUmV0dXJucyB0aGUgYm91bmQgb3JnIG9uIHN1Y2Nlc3MsIG9yIG51bGxcbiAgICogd2hlbiB0aGUgdGlja2V0IGlzIHVua25vd24gLyBhbHJlYWR5LXVzZWQgLyBleHBpcmVkIC8gT1Igd2FzIG1pbnRlZCBmb3IgYVxuICAgKiBESUZGRVJFTlQgYHJlcXVlc3RJZGAgdGhhbiB0aGUgb25lIGJlaW5nIG9wZW5lZC5cbiAgICpcbiAgICogVGhlIHN1YmplY3QgY2hlY2sgaXMgdGhlIGF1dGhvcml6YXRpb24gZml4OiB3aXRob3V0IGl0LCBhIHRpY2tldCBtaW50ZWQgZm9yXG4gICAqIG9uZSBzdHJlYW0gY291bGQgYmUgcHJlc2VudGVkIHRvIG9wZW4gQU5ZIHN0cmVhbSB0aGUgaG9sZGVyJ3Mgb3JnIGNvdWxkXG4gICAqIG5hbWUsIGxldHRpbmcgYW4gYXV0aGVudGljYXRlZCBvcmcgYXR0YWNoIHRvIGFub3RoZXIgb3JnJ3MgbG9nIHN0cmVhbSBieVxuICAgKiBndWVzc2luZyBpdHMgcmVxdWVzdElkLiBUaGUgZ2VuZXJpYyA0MDEgdGhlIGNhbGxlciByZXR1cm5zIGRvZXMgbm90XG4gICAqIGRpc3Rpbmd1aXNoIFwidW5rbm93biB0aWNrZXRcIiBmcm9tIFwid3Jvbmcgc3ViamVjdFwiLCBzbyBpdCBsZWFrcyBub3RoaW5nXG4gICAqIGFib3V0IHdoaWNoIHJlcXVlc3RJZHMgZXhpc3QuXG4gICAqXG4gICAqIEBwYXJhbSB0aWNrZXRJZCAtIFRoZSBvcGFxdWUgdGlja2V0IHZhbHVlIGZyb20gYD90aWNrZXQ9YC5cbiAgICogQHBhcmFtIHJlcXVlc3RJZCAtIFRoZSBzdHJlYW0gc3ViamVjdCBmcm9tIHRoZSBVUkwgcGF0aCAoYDpyZXF1ZXN0SWRgKSxcbiAgICogICBhbHJlYWR5IGZvcm1hdC12YWxpZGF0ZWQgYnkgdGhlIGNhbGxlci5cbiAgICovXG4gIGNvbnN1bWVUaWNrZXQodGlja2V0SWQ6IHN0cmluZywgcmVxdWVzdElkOiBzdHJpbmcpOiB7IG9yZ0lkOiBzdHJpbmcgfSB8IG51bGwge1xuICAgIGNvbnN0IHRpY2tldCA9IHRoaXMudGlja2V0cy5nZXQodGlja2V0SWQpO1xuICAgIHRoaXMudGlja2V0cy5kZWxldGUodGlja2V0SWQpOyAvLyBzaW5nbGUtdXNlIOKAlCBjb25zdW1lIGltbWVkaWF0ZWx5XG4gICAgaWYgKCF0aWNrZXQgfHwgRGF0ZS5ub3coKSA+IHRpY2tldC5leHBpcmVzQXQpIHJldHVybiBudWxsO1xuICAgIC8vIFN1YmplY3QgYmluZGluZyDigJQgcmVqZWN0IGEgdGlja2V0IHByZXNlbnRlZCBmb3IgYSBzdWJqZWN0IGl0IHdhcyBub3RcbiAgICAvLyBtaW50ZWQgZm9yLiBCb3RoIHNpZGVzIGFyZSBub3JtYWxpemVkIHNvIGRhc2hlZC91bmRhc2hlZCBmb3JtcyBtYXRjaC5cbiAgICBpZiAodGlja2V0LnJlcXVlc3RJZCAhPT0gU1NFTWFuYWdlci5ub3JtYWxpemVSZXF1ZXN0SWQocmVxdWVzdElkKSkgcmV0dXJuIG51bGw7XG4gICAgcmV0dXJuIHsgb3JnSWQ6IHRpY2tldC5vcmdJZCB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYSBjbGllbnQgdG8gdGhlIFNTRSBtYW5hZ2VyXG4gICAqXG4gICAqIEBwYXJhbSByZXF1ZXN0SWQgLSBVbmlxdWUgcmVxdWVzdCBJRFxuICAgKiBAcGFyYW0gcmVzIC0gRXhwcmVzcyBSZXNwb25zZSBvYmplY3RcbiAgICogQHBhcmFtIG9yZ0lkIC0gQXV0aGVudGljYXRlZCBvcmcgaWQgKG9wdGlvbmFsKS4gV2hlbiBzZXQsIGVuZm9yY2VzIHRoZVxuICAgKiAgIHBlci1vcmcgY2FwIGFuZCB0aGUgY291bnRlciBpcyBkZWNyZW1lbnRlZCBvbiBkaXNjb25uZWN0L2NsZWFudXAuXG4gICAqIEByZXR1cm5zIHRydWUgaWYgY2xpZW50IHdhcyBhZGRlZCwgZmFsc2UgaWYgcmVqZWN0ZWQgKGxpbWl0IHJlYWNoZWQpXG4gICAqL1xuICBhZGRDbGllbnQocmVxdWVzdElkOiBzdHJpbmcsIHJlczogUmVzcG9uc2UsIG9yZ0lkPzogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgY29uc3QgZXhpc3RpbmcgPSB0aGlzLmNsaWVudHMuZ2V0KHJlcXVlc3RJZCkgfHwgW107XG5cbiAgICAvLyBDaGVjayBjbGllbnQgbGltaXRcbiAgICBpZiAoZXhpc3RpbmcubGVuZ3RoID49IHRoaXMubWF4Q2xpZW50c1BlclJlcXVlc3QpIHtcbiAgICAgIGxvZ2dlci53YXJuKGBDbGllbnQgbGltaXQgcmVhY2hlZCBmb3IgcmVxdWVzdCAke3JlcXVlc3RJZH0gKG1heDogJHt0aGlzLm1heENsaWVudHNQZXJSZXF1ZXN0fSlgKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvLyBQcm9jZXNzLXdpZGUgY2FwOiBwcm90ZWN0cyBmZCB0YWJsZSArIG1lbW9yeSBmcm9tIHJ1bmF3YXkgZGFzaGJvYXJkcy5cbiAgICBpZiAodGhpcy50b3RhbENsaWVudHMoKSA+PSB0aGlzLm1heFRvdGFsQ2xpZW50cykge1xuICAgICAgbG9nZ2VyLndhcm4oYFRvdGFsIFNTRSBjbGllbnQgY2FwIHJlYWNoZWQgKG1heDogJHt0aGlzLm1heFRvdGFsQ2xpZW50c30pOyByZWplY3RpbmcgbmV3IGNvbm5lY3Rpb25gKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvLyBQZXItb3JnIGNhcDogcHJldmVudHMgb25lIG5vaXN5IG9yZyBmcm9tIG1vbm9wb2xpemluZyBwcm9jZXNzLXdpZGVcbiAgICAvLyBzbG90cy4gRW5mb3JjZWQgb25seSB3aGVuIG9yZ0lkIGlzIGtub3duIOKAlCBzZXJ2aWNlLWludGVybmFsIC8gYW5vbnltb3VzXG4gICAgLy8gc3RyZWFtcyB0aGF0IG5ldmVyIGlkZW50aWZ5IHdpdGggYW4gb3JnSWQgc3RheSBzdWJqZWN0IHRvIHRoZSBnbG9iYWxcbiAgICAvLyBjZWlsaW5ncyBhYm92ZS4gUmVzZXJ2ZSBhdG9taWNhbGx5IGJlZm9yZSBpbnNlcnQgc28gdHdvIGNvbmN1cnJlbnRcbiAgICAvLyByZXF1ZXN0cyBhdCB0aGUgbGltaXQgY2FuJ3QgYm90aCBzdWNjZWVkLlxuICAgIGlmIChvcmdJZCkge1xuICAgICAgY29uc3Qgb3JnQ3VycmVudCA9IHRoaXMub3JnQ2xpZW50Q291bnRzLmdldChvcmdJZCkgPz8gMDtcbiAgICAgIGlmIChvcmdDdXJyZW50ID49IHRoaXMubWF4Q2xpZW50c1Blck9yZykge1xuICAgICAgICBsb2dnZXIud2FybihgUGVyLW9yZyBTU0UgY2xpZW50IGNhcCByZWFjaGVkIGZvciAke29yZ0lkfSAobWF4OiAke3RoaXMubWF4Q2xpZW50c1Blck9yZ30pOyByZWplY3RpbmcgbmV3IGNvbm5lY3Rpb25gKTtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgdGhpcy5vcmdDbGllbnRDb3VudHMuc2V0KG9yZ0lkLCBvcmdDdXJyZW50ICsgMSk7XG4gICAgfVxuXG4gICAgLy8gQ3JlYXRlIHRpbWVvdXQgZm9yIHRoaXMgY2xpZW50XG4gICAgY29uc3QgY2xpZW50SWQgPSB1dWlkKCk7XG4gICAgY29uc3QgdGltZW91dCA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgbG9nZ2VyLmRlYnVnKGBDbGllbnQgJHtjbGllbnRJZH0gdGltZWQgb3V0IGZvciByZXF1ZXN0ICR7cmVxdWVzdElkfWApO1xuICAgICAgdGhpcy5yZW1vdmVDbGllbnQocmVxdWVzdElkLCBjbGllbnRJZCk7XG4gICAgICB0cnkge1xuICAgICAgICByZXMuZW5kKCk7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgbG9nZ2VyLmRlYnVnKCdSZXNwb25zZSBhbHJlYWR5IGNsb3NlZCBvbiB0aW1lb3V0JywgeyByZXF1ZXN0SWQsIGNsaWVudElkLCBlcnJvcjogZXJyIGluc3RhbmNlb2YgRXJyb3IgPyBlcnIubWVzc2FnZSA6IFN0cmluZyhlcnIpIH0pO1xuICAgICAgfVxuICAgIH0sIHRoaXMuY2xpZW50VGltZW91dE1zKTtcblxuICAgIGNvbnN0IGNsaWVudDogU1NFQ2xpZW50ID0ge1xuICAgICAgaWQ6IGNsaWVudElkLFxuICAgICAgcmVzLFxuICAgICAgY29ubmVjdGVkQXQ6IERhdGUubm93KCksXG4gICAgICB0aW1lb3V0LFxuICAgICAgYmFja3ByZXNzdXJlQ291bnQ6IDAsXG4gICAgICBvcmdJZCxcbiAgICB9O1xuXG4gICAgLy8gSGFuZGxlIGRpc2Nvbm5lY3Rpb25cbiAgICByZXMub24oJ2Nsb3NlJywgKCkgPT4ge1xuICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xuICAgICAgdGhpcy5yZW1vdmVDbGllbnQocmVxdWVzdElkLCBjbGllbnRJZCk7XG4gICAgfSk7XG5cbiAgICByZXMub24oJ2Vycm9yJywgKGVycikgPT4ge1xuICAgICAgbG9nZ2VyLmVycm9yKGBTU0UgY2xpZW50IGVycm9yIGZvciByZXF1ZXN0ICR7cmVxdWVzdElkfTpgLCBlcnIpO1xuICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xuICAgICAgdGhpcy5yZW1vdmVDbGllbnQocmVxdWVzdElkLCBjbGllbnRJZCk7XG4gICAgfSk7XG5cbiAgICBleGlzdGluZy5wdXNoKGNsaWVudCk7XG4gICAgdGhpcy5jbGllbnRzLnNldChyZXF1ZXN0SWQsIGV4aXN0aW5nKTtcblxuICAgIGxvZ2dlci5kZWJ1ZyhgQ2xpZW50ICR7Y2xpZW50SWR9IGNvbm5lY3RlZCBmb3IgcmVxdWVzdCAke3JlcXVlc3RJZH0gKHRvdGFsOiAke2V4aXN0aW5nLmxlbmd0aH0pYCk7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvKiogRHJvcCBvbmUgZnJvbSB0aGUgcGVyLW9yZyBjb3VudGVyLiBJZGVtcG90ZW50OiBhIGNvdW50ZXIgYXQgMCBzdGF5cyBhdCAwXG4gICAqICBhbmQgdGhlIG9yZyBrZXkgaXMgcmVtb3ZlZCBmcm9tIHRoZSBtYXAuICovXG4gIHByaXZhdGUgZGVjcmVtZW50T3JnQ291bnQob3JnSWQ/OiBzdHJpbmcpOiB2b2lkIHtcbiAgICBpZiAoIW9yZ0lkKSByZXR1cm47XG4gICAgY29uc3QgY3VycmVudCA9IHRoaXMub3JnQ2xpZW50Q291bnRzLmdldChvcmdJZCkgPz8gMDtcbiAgICBpZiAoY3VycmVudCA8PSAxKSB0aGlzLm9yZ0NsaWVudENvdW50cy5kZWxldGUob3JnSWQpO1xuICAgIGVsc2UgdGhpcy5vcmdDbGllbnRDb3VudHMuc2V0KG9yZ0lkLCBjdXJyZW50IC0gMSk7XG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlcyBhIGNsaWVudCBmcm9tIHRoZSBtYW5hZ2VyXG4gICAqL1xuICBwcml2YXRlIHJlbW92ZUNsaWVudChyZXF1ZXN0SWQ6IHN0cmluZywgY2xpZW50SWQ6IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IGNsaWVudHMgPSB0aGlzLmNsaWVudHMuZ2V0KHJlcXVlc3RJZCk7XG4gICAgaWYgKCFjbGllbnRzKSByZXR1cm47XG5cbiAgICBjb25zdCByZW1haW5pbmcgPSBjbGllbnRzLmZpbHRlcihjID0+IHtcbiAgICAgIGlmIChjLmlkID09PSBjbGllbnRJZCkge1xuICAgICAgICBjbGVhclRpbWVvdXQoYy50aW1lb3V0KTtcbiAgICAgICAgLy8gTWlycm9yIHRoZSBwZXItb3JnIGNvdW50ZXIg4oCUIG11c3QgZGVjcmVtZW50IGhlcmUsIG5vdCBqdXN0IGluIHRoZVxuICAgICAgICAvLyBleHBsaWNpdCBjbG9zZSBwYXRocywgc2luY2UgJ2Nsb3NlJy8nZXJyb3InIGV2ZW50IGhhbmRsZXJzIGFyZSB0aGVcbiAgICAgICAgLy8gcHJpbWFyeSBkaXNjb25uZWN0IHNpZ25hbCBpbiBwcmFjdGljZS5cbiAgICAgICAgdGhpcy5kZWNyZW1lbnRPcmdDb3VudChjLm9yZ0lkKTtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSk7XG5cbiAgICBpZiAocmVtYWluaW5nLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhpcy5jbGllbnRzLmRlbGV0ZShyZXF1ZXN0SWQpO1xuICAgICAgbG9nZ2VyLmRlYnVnKGBBbGwgY2xpZW50cyBkaXNjb25uZWN0ZWQgZm9yIHJlcXVlc3QgJHtyZXF1ZXN0SWR9YCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuY2xpZW50cy5zZXQocmVxdWVzdElkLCByZW1haW5pbmcpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBTZW5kcyBhIG1lc3NhZ2UgdG8gYWxsIFNTRSBjbGllbnRzIGZvciBhIHJlcXVlc3RJZFxuICAgKlxuICAgKiBAcGFyYW0gcmVxdWVzdElkIC0gUmVxdWVzdCBJRFxuICAgKiBAcGFyYW0gdHlwZSAtIEV2ZW50IHR5cGVcbiAgICogQHBhcmFtIG1lc3NhZ2UgLSBNZXNzYWdlIHN0cmluZ1xuICAgKiBAcGFyYW0gZGF0YSAtIE9wdGlvbmFsIGFkZGl0aW9uYWwgZGF0YVxuICAgKiBAcmV0dXJucyBOdW1iZXIgb2YgY2xpZW50cyB0aGUgbWVzc2FnZSB3YXMgc2VudCB0b1xuICAgKi9cbiAgc2VuZChyZXF1ZXN0SWQ6IHN0cmluZywgdHlwZTogU1NFRXZlbnRUeXBlLCBtZXNzYWdlOiBzdHJpbmcsIGRhdGE/OiB1bmtub3duKTogbnVtYmVyIHtcbiAgICBjb25zdCBwYXlsb2FkOiBTU0VQYXlsb2FkID0ge1xuICAgICAgdHM6IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKSxcbiAgICAgIHR5cGUsXG4gICAgICBtZXNzYWdlLFxuICAgICAgZGF0YSxcbiAgICB9O1xuXG4gICAgY29uc3QgY2xpZW50cyA9IFsuLi4odGhpcy5jbGllbnRzLmdldChyZXF1ZXN0SWQpIHx8IFtdKV07XG4gICAgbGV0IHNlbnRDb3VudCA9IDA7XG4gICAgY29uc3Qgc2VyaWFsaXplZCA9IGBkYXRhOiAke0pTT04uc3RyaW5naWZ5KHBheWxvYWQpfVxcblxcbmA7XG5cbiAgICBmb3IgKGNvbnN0IGNsaWVudCBvZiBjbGllbnRzKSB7XG4gICAgICB0cnkge1xuICAgICAgICAvLyBCYWNrcHJlc3N1cmU6IHNraXAgY2xpZW50cyB3aG9zZSB3cml0ZSBidWZmZXIgaXMgZnVsbFxuICAgICAgICBpZiAoY2xpZW50LnJlcy53cml0YWJsZUVuZGVkKSB7XG4gICAgICAgICAgdGhpcy5yZW1vdmVDbGllbnQocmVxdWVzdElkLCBjbGllbnQuaWQpO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGNhbldyaXRlID0gY2xpZW50LnJlcy53cml0ZShzZXJpYWxpemVkKTtcbiAgICAgICAgaWYgKCFjYW5Xcml0ZSkge1xuICAgICAgICAgIGNsaWVudC5iYWNrcHJlc3N1cmVDb3VudCsrO1xuICAgICAgICAgIC8vIERpc2Nvbm5lY3QgY2xpZW50cyB0aGF0IGNvbnNpc3RlbnRseSBjYW4ndCBrZWVwIHVwICgxMCBjb25zZWN1dGl2ZSBiYWNrcHJlc3N1cmUgZXZlbnRzKVxuICAgICAgICAgIGlmIChjbGllbnQuYmFja3ByZXNzdXJlQ291bnQgPj0gQ29yZUNvbnN0YW50cy5TU0VfQkFDS1BSRVNTVVJFX1RIUkVTSE9MRCkge1xuICAgICAgICAgICAgbG9nZ2VyLndhcm4oYERpc2Nvbm5lY3Rpbmcgc2xvdyBjbGllbnQgJHtjbGllbnQuaWR9IGZvciByZXF1ZXN0ICR7cmVxdWVzdElkfSAoJHtjbGllbnQuYmFja3ByZXNzdXJlQ291bnR9IGJhY2twcmVzc3VyZSBldmVudHMpYCk7XG4gICAgICAgICAgICB0aGlzLnJlbW92ZUNsaWVudChyZXF1ZXN0SWQsIGNsaWVudC5pZCk7XG4gICAgICAgICAgICB0cnkgeyBjbGllbnQucmVzLmVuZCgpOyB9IGNhdGNoIHsgLyogYWxyZWFkeSBjbG9zZWQgKi8gfVxuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNsaWVudC5iYWNrcHJlc3N1cmVDb3VudCA9IDA7IC8vIFJlc2V0IG9uIHN1Y2Nlc3NmdWwgd3JpdGVcbiAgICAgICAgfVxuICAgICAgICBzZW50Q291bnQrKztcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGxvZ2dlci5lcnJvcihgRmFpbGVkIHRvIHNlbmQgdG8gY2xpZW50ICR7Y2xpZW50LmlkfTpgLCBlcnJvcik7XG4gICAgICAgIHRoaXMucmVtb3ZlQ2xpZW50KHJlcXVlc3RJZCwgY2xpZW50LmlkKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gc2VudENvdW50O1xuICB9XG5cbiAgLyoqXG4gICAqIEJyb2FkY2FzdCBhIG1lc3NhZ2UgdG8gYWxsIGNvbm5lY3RlZCBjbGllbnRzIGFjcm9zcyBhbGwgcmVxdWVzdHNcbiAgICpcbiAgICogQHBhcmFtIHR5cGUgLSBFdmVudCB0eXBlXG4gICAqIEBwYXJhbSBtZXNzYWdlIC0gTWVzc2FnZSBzdHJpbmdcbiAgICogQHBhcmFtIGRhdGEgLSBPcHRpb25hbCBhZGRpdGlvbmFsIGRhdGFcbiAgICogQHJldHVybnMgVG90YWwgbnVtYmVyIG9mIGNsaWVudHMgdGhlIG1lc3NhZ2Ugd2FzIHNlbnQgdG9cbiAgICovXG4gIGJyb2FkY2FzdCh0eXBlOiBTU0VFdmVudFR5cGUsIG1lc3NhZ2U6IHN0cmluZywgZGF0YT86IHVua25vd24pOiBudW1iZXIge1xuICAgIGxldCB0b3RhbFNlbnQgPSAwO1xuICAgIGZvciAoY29uc3QgcmVxdWVzdElkIG9mIHRoaXMuY2xpZW50cy5rZXlzKCkpIHtcbiAgICAgIHRvdGFsU2VudCArPSB0aGlzLnNlbmQocmVxdWVzdElkLCB0eXBlLCBtZXNzYWdlLCBkYXRhKTtcbiAgICB9XG4gICAgcmV0dXJuIHRvdGFsU2VudDtcbiAgfVxuXG4gIC8qKlxuICAgKiBDbG9zZSBhbGwgY2xpZW50cyBmb3IgYSBzcGVjaWZpYyByZXF1ZXN0XG4gICAqXG4gICAqIEBwYXJhbSByZXF1ZXN0SWQgLSBSZXF1ZXN0IElEIHRvIGNsb3NlXG4gICAqIEBwYXJhbSBmaW5hbE1lc3NhZ2UgLSBPcHRpb25hbCBmaW5hbCBtZXNzYWdlIHRvIHNlbmQgYmVmb3JlIGNsb3NpbmdcbiAgICovXG4gIGNsb3NlUmVxdWVzdChyZXF1ZXN0SWQ6IHN0cmluZywgZmluYWxNZXNzYWdlPzogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgY2xpZW50cyA9IHRoaXMuY2xpZW50cy5nZXQocmVxdWVzdElkKTtcbiAgICBpZiAoIWNsaWVudHMpIHJldHVybjtcblxuICAgIGlmIChmaW5hbE1lc3NhZ2UpIHtcbiAgICAgIHRoaXMuc2VuZChyZXF1ZXN0SWQsICdDT01QTEVURUQnLCBmaW5hbE1lc3NhZ2UpO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgY2xpZW50IG9mIGNsaWVudHMpIHtcbiAgICAgIGNsZWFyVGltZW91dChjbGllbnQudGltZW91dCk7XG4gICAgICB0aGlzLmRlY3JlbWVudE9yZ0NvdW50KGNsaWVudC5vcmdJZCk7XG4gICAgICB0cnkge1xuICAgICAgICBjbGllbnQucmVzLmVuZCgpO1xuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIGxvZ2dlci5kZWJ1ZygnUmVzcG9uc2UgYWxyZWFkeSBjbG9zZWQgb24gcmVxdWVzdCBjbG9zZScsIHsgcmVxdWVzdElkLCBjbGllbnRJZDogY2xpZW50LmlkLCBlcnJvcjogZXJyIGluc3RhbmNlb2YgRXJyb3IgPyBlcnIubWVzc2FnZSA6IFN0cmluZyhlcnIpIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuY2xpZW50cy5kZWxldGUocmVxdWVzdElkKTtcbiAgICBsb2dnZXIuZGVidWcoYENsb3NlZCBhbGwgY2xpZW50cyBmb3IgcmVxdWVzdCAke3JlcXVlc3RJZH1gKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgc3RhdGlzdGljcyBhYm91dCBjdXJyZW50IGNvbm5lY3Rpb25zXG4gICAqL1xuICBnZXRTdGF0cygpOiBTU0VNYW5hZ2VyU3RhdHMge1xuICAgIGxldCB0b3RhbENsaWVudHMgPSAwO1xuICAgIGxldCBvbGRlc3RDb25uZWN0aW9uOiBudW1iZXIgfCBudWxsID0gbnVsbDtcbiAgICBjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuXG4gICAgZm9yIChjb25zdCBjbGllbnRzIG9mIHRoaXMuY2xpZW50cy52YWx1ZXMoKSkge1xuICAgICAgdG90YWxDbGllbnRzICs9IGNsaWVudHMubGVuZ3RoO1xuICAgICAgZm9yIChjb25zdCBjbGllbnQgb2YgY2xpZW50cykge1xuICAgICAgICBjb25zdCBhZ2UgPSBub3cgLSBjbGllbnQuY29ubmVjdGVkQXQ7XG4gICAgICAgIGlmIChvbGRlc3RDb25uZWN0aW9uID09PSBudWxsIHx8IGFnZSA+IG9sZGVzdENvbm5lY3Rpb24pIHtcbiAgICAgICAgICBvbGRlc3RDb25uZWN0aW9uID0gYWdlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIHRvdGFsUmVxdWVzdHM6IHRoaXMuY2xpZW50cy5zaXplLFxuICAgICAgdG90YWxDbGllbnRzLFxuICAgICAgb2xkZXN0Q29ubmVjdGlvbk1zOiBvbGRlc3RDb25uZWN0aW9uLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2sgaWYgYSByZXF1ZXN0IGhhcyBhbnkgY29ubmVjdGVkIGNsaWVudHNcbiAgICovXG4gIGhhc0NsaWVudHMocmVxdWVzdElkOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICBjb25zdCBjbGllbnRzID0gdGhpcy5jbGllbnRzLmdldChyZXF1ZXN0SWQpO1xuICAgIHJldHVybiBjbGllbnRzICE9PSB1bmRlZmluZWQgJiYgY2xpZW50cy5sZW5ndGggPiAwO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgbnVtYmVyIG9mIGNsaWVudHMgZm9yIGEgc3BlY2lmaWMgcmVxdWVzdFxuICAgKi9cbiAgZ2V0Q2xpZW50Q291bnQocmVxdWVzdElkOiBzdHJpbmcpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLmNsaWVudHMuZ2V0KHJlcXVlc3RJZCk/Lmxlbmd0aCA/PyAwO1xuICB9XG5cbiAgLyoqXG4gICAqIE1pZGRsZXdhcmUgdG8gaW5pdGlhbGl6ZSBhIHRpY2tldC1hdXRoZW50aWNhdGVkIFNTRSBjb25uZWN0aW9uLlxuICAgKlxuICAgKiBUaGUgc3RyZWFtIGlzIE5PVCBvcGVuIHRvIHRoZSB3b3JsZDogdGhlIGNhbGxlciBtdXN0IGZpcnN0IGV4Y2hhbmdlIGl0c1xuICAgKiBKV1QgZm9yIGEgc2hvcnQtbGl2ZWQgc2luZ2xlLXVzZSB0aWNrZXQgKHNlZSB7QGxpbmsgY3JlYXRlVGlja2V0fSwgd2lyZWQgdG9cbiAgICogYFBPU1QgL2xvZ3MvdGlja2V0YCkgYW5kIHBhc3MgaXQgYXMgYD90aWNrZXQ9PHQ+YC4gVGhlIG1pZGRsZXdhcmUgdmFsaWRhdGVzXG4gICAqICsgY29uc3VtZXMgdGhlIHRpY2tldCwgYmluZHMgdGhlIGNvbm5lY3Rpb24gdG8gdGhlIHRpY2tldCdzIG9yZywgYW5kXG4gICAqIGVuZm9yY2VzIHRoZSBwZXItb3JnIGNvbm5lY3Rpb24gY2FwLiBBIG1pc3NpbmcgLyBpbnZhbGlkIC8gZXhwaXJlZCAvXG4gICAqIGFscmVhZHktdXNlZCB0aWNrZXQgaXMgcmVqZWN0ZWQgd2l0aCA0MDEgYmVmb3JlIGFueSBTU0UgaGVhZGVycyBmbHVzaC5cbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogYGBgdHlwZXNjcmlwdFxuICAgKiBhcHAuZ2V0KCcvbG9ncy86cmVxdWVzdElkJywgc3NlTWFuYWdlci5taWRkbGV3YXJlKCkpO1xuICAgKiBgYGBcbiAgICovXG4gIG1pZGRsZXdhcmUoKSB7XG4gICAgcmV0dXJuIChyZXE6IHsgcGFyYW1zOiB7IHJlcXVlc3RJZDogc3RyaW5nIH07IHF1ZXJ5PzogeyB0aWNrZXQ/OiB1bmtub3duIH0gfSwgcmVzOiBSZXNwb25zZSkgPT4ge1xuICAgICAgY29uc3QgeyByZXF1ZXN0SWQgfSA9IHJlcS5wYXJhbXM7XG5cbiAgICAgIGlmICghU1NFX1JFUVVFU1RfSURfUkUudGVzdChyZXF1ZXN0SWQpKSB7XG4gICAgICAgIHJlcy5zdGF0dXMoNDAwKS5lbmQoJ0ludmFsaWQgcmVxdWVzdElkIGZvcm1hdCcpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIFRpY2tldCBhdXRoIOKAlCByZXF1aXJlZC4gUmVzb2x2ZSBgP3RpY2tldD08dD5gLCB0aGVuIHZhbGlkYXRlICsgY29uc3VtZVxuICAgICAgLy8gaXQgKHNpbmdsZS11c2UpIEZPUiBUSElTIFNVQkpFQ1QuIEFuIGFub255bW91cywgbWFsZm9ybWVkLCB1bmtub3duLFxuICAgICAgLy8gZXhwaXJlZCwgYWxyZWFkeS1jb25zdW1lZCwgb3Igd3Jvbmctc3ViamVjdCB0aWNrZXQgaXMgYSA0MDEuIFRoZSBvcmcgaXNcbiAgICAgIC8vIHRha2VuIGZyb20gdGhlIHRpY2tldCwgc28gdGhlIHN0cmVhbSBpcyBhbHdheXMgYm91bmQgdG8gYSB2ZXJpZmllZFxuICAgICAgLy8gdGVuYW50IEFORCB0byB0aGUgZXhhY3Qgc3ViamVjdCB0aGUgdGlja2V0IHdhcyBtaW50ZWQgZm9yIChubyBhbm9ueW1vdXNcbiAgICAgIC8vIHN0cmVhbXMsIG5vIGNyb3NzLXN1YmplY3QgYXR0YWNoKS5cbiAgICAgIGNvbnN0IHRpY2tldElkID0gcmVxLnF1ZXJ5Py50aWNrZXQ7XG4gICAgICBpZiAodHlwZW9mIHRpY2tldElkICE9PSAnc3RyaW5nJyB8fCB0aWNrZXRJZC5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmVzLnN0YXR1cyg0MDEpLmVuZCgnTWlzc2luZyB0aWNrZXQnKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgY29uc3QgY29uc3VtZWQgPSB0aGlzLmNvbnN1bWVUaWNrZXQodGlja2V0SWQsIHJlcXVlc3RJZCk7XG4gICAgICBpZiAoIWNvbnN1bWVkKSB7XG4gICAgICAgIHJlcy5zdGF0dXMoNDAxKS5lbmQoJ0ludmFsaWQgb3IgZXhwaXJlZCB0aWNrZXQnKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgY29uc3Qgb3JnSWQgPSBjb25zdW1lZC5vcmdJZDtcblxuICAgICAgLy8gUHJlLWZsaWdodCBwZXItcmVxdWVzdCBjYXAgc28gd2UgY2FuIHJldHVybiA0MjkgYmVmb3JlIGZsdXNoaW5nXG4gICAgICAvLyBTU0UgaGVhZGVycyAoYWZ0ZXIgaGVhZGVycyBhcmUgZmx1c2hlZCB0aGUgY2xpZW50IGNhbid0IHJlYWQgYSA0MjkpLlxuICAgICAgY29uc3QgZXhpc3RpbmcgPSB0aGlzLmNsaWVudHMuZ2V0KHJlcXVlc3RJZCkgfHwgW107XG4gICAgICBpZiAoZXhpc3RpbmcubGVuZ3RoID49IHRoaXMubWF4Q2xpZW50c1BlclJlcXVlc3QpIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oYENsaWVudCBsaW1pdCByZWFjaGVkIGZvciByZXF1ZXN0ICR7cmVxdWVzdElkfSAobWF4OiAke3RoaXMubWF4Q2xpZW50c1BlclJlcXVlc3R9KWApO1xuICAgICAgICByZXMuc3RhdHVzKDQyOSkuZW5kKCdUb28gbWFueSBjb25uZWN0aW9ucyBmb3IgdGhpcyByZXF1ZXN0Jyk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgLy8gU2FtZSBmb3IgdGhlIHBlci1vcmcgY2FwIOKAlCBiZXR0ZXIgdG8gc2VuZCA0MjkgdGhhbiBvcGVuIHRoZSBzdHJlYW0gYW5kXG4gICAgICAvLyBpbW1lZGlhdGVseSBjbG9zZSBpdC4gVGhlIHRpY2tldCBndWFyYW50ZWVzIGEgdmVyaWZpZWQgb3JnIGlkLCBzbyB0aGVcbiAgICAgIC8vIHBlci1vcmcgY2VpbGluZyBpcyBhbHdheXMgZW5mb3JjZWQgZm9yIHRoZSAvbG9ncyBzdHJlYW0uXG4gICAgICBpZiAoKHRoaXMub3JnQ2xpZW50Q291bnRzLmdldChvcmdJZCkgPz8gMCkgPj0gdGhpcy5tYXhDbGllbnRzUGVyT3JnKSB7XG4gICAgICAgIGxvZ2dlci53YXJuKGBQZXItb3JnIFNTRSBjbGllbnQgY2FwIHJlYWNoZWQgZm9yICR7b3JnSWR9IChtYXg6ICR7dGhpcy5tYXhDbGllbnRzUGVyT3JnfSlgKTtcbiAgICAgICAgcmVzLnN0YXR1cyg0MjkpLmVuZCgnVG9vIG1hbnkgU1NFIGNvbm5lY3Rpb25zIGZvciB0aGlzIG9yZ2FuaXphdGlvbicpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHJlcy5zZXRIZWFkZXIoJ0NvbnRlbnQtVHlwZScsICd0ZXh0L2V2ZW50LXN0cmVhbScpO1xuICAgICAgcmVzLnNldEhlYWRlcignQ2FjaGUtQ29udHJvbCcsICduby1jYWNoZScpO1xuICAgICAgcmVzLnNldEhlYWRlcignQ29ubmVjdGlvbicsICdrZWVwLWFsaXZlJyk7XG4gICAgICByZXMuc2V0SGVhZGVyKCdYLUFjY2VsLUJ1ZmZlcmluZycsICdubycpOyAvLyBEaXNhYmxlIG5naW54IGJ1ZmZlcmluZ1xuICAgICAgcmVzLmZsdXNoSGVhZGVycygpO1xuXG4gICAgICAvLyBIZWFkZXJzIGFyZSBmbHVzaGVkIOKAlCB3ZSBjYW4gbm8gbG9uZ2VyIHNlbmQgYSA0MjkuIGFkZENsaWVudCByZS1jaGVja3NcbiAgICAgIC8vIHRoZSBjYXBzIChpbmNsdWRpbmcgdGhlIHByb2Nlc3Mtd2lkZSB0b3RhbC1jbGllbnRzIGNhcCwgd2hpY2ggdGhlXG4gICAgICAvLyBwcmUtZmxpZ2h0IGFib3ZlIGRvZXMgbm90KSBhbmQgY2FuIHN0aWxsIHJlamVjdCBvbiBhIHJhY2U6IGEgY29uY3VycmVudFxuICAgICAgLy8gY29ubmVjdGlvbiBtYXkgaGF2ZSBmaWxsZWQgYSBjYXAgYmV0d2VlbiB0aGUgcHJlLWZsaWdodCBjaGVjayBhbmQgaGVyZS5cbiAgICAgIC8vIE9uIHJlamVjdGlvbiwgY2xvc2UgdGhlIG5vdy1kYW5nbGluZyByZXNwb25zZSBpbnN0ZWFkIG9mIGxlYXZpbmcgYW5cbiAgICAgIC8vIG9wZW4gc29ja2V0IHdpdGggbm8gY2xpZW50IHJlY29yZCAod2hpY2ggd291bGQgbGVhayBhbiBmZCArIG5ldmVyIGVtaXRcbiAgICAgIC8vIHN0cmVhbSBkYXRhKS5cbiAgICAgIGNvbnN0IGFkZGVkID0gdGhpcy5hZGRDbGllbnQocmVxdWVzdElkLCByZXMsIG9yZ0lkKTtcbiAgICAgIGlmICghYWRkZWQpIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oYFNTRSBhZGRDbGllbnQgcmVqZWN0ZWQgYWZ0ZXIgaGVhZGVycyBmbHVzaGVkIGZvciByZXF1ZXN0ICR7cmVxdWVzdElkfTsgY2xvc2luZyBkYW5nbGluZyByZXNwb25zZWApO1xuICAgICAgICB0cnkgeyByZXMuZW5kKCk7IH0gY2F0Y2ggeyAvKiBhbHJlYWR5IGNsb3NlZCAqLyB9XG4gICAgICB9XG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdGFydCBwZXJpb2RpYyBjbGVhbnVwIG9mIHN0YWxlIGNvbm5lY3Rpb25zXG4gICAqL1xuICBwcml2YXRlIHN0YXJ0Q2xlYW51cEludGVydmFsKGludGVydmFsTXM6IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMuY2xlYW51cEludGVydmFsID0gc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAgdGhpcy5jbGVhbnVwKCk7XG4gICAgfSwgaW50ZXJ2YWxNcyk7XG5cbiAgICAvLyBEb24ndCBwcmV2ZW50IHByb2Nlc3MgZXhpdFxuICAgIHRoaXMuY2xlYW51cEludGVydmFsLnVucmVmKCk7XG4gIH1cblxuICAvKipcbiAgICogQ2xlYW4gdXAgc3RhbGUgY29ubmVjdGlvbnMgdXNpbmcgc2luZ2xlLXBhc3MgcGFydGl0aW9uLlxuICAgKiBPKFIgw5cgQykgaW5zdGVhZCBvZiBPKFIgw5cgQ8KyKSwgYW5kIGF2b2lkcyBtdXRhdGlvbi1kdXJpbmctaXRlcmF0aW9uLlxuICAgKi9cbiAgcHJpdmF0ZSBjbGVhbnVwKCk6IHZvaWQge1xuICAgIGNvbnN0IG5vdyA9IERhdGUubm93KCk7XG4gICAgbGV0IGNsZWFuZWQgPSAwO1xuXG4gICAgLy8gU3dlZXAgZXhwaXJlZCB0aWNrZXRzIHNvIHRoZSBzdG9yZSBzdGF5cyBib3VuZGVkIGV2ZW4gd2hlbiB0aWNrZXRzIGFyZVxuICAgIC8vIG1pbnRlZCBidXQgbmV2ZXIgY29uc3VtZWQgKGNsaWVudCBjbG9zZWQgdGhlIHRhYiBiZWZvcmUgY29ubmVjdGluZykuXG4gICAgLy8gQ29uc3VtZS10aW1lIHN0aWxsIHJlLWNoZWNrcyBleHBpcnksIHNvIHRoaXMgaXMgbWVtb3J5IGh5Z2llbmUgb25seS5cbiAgICBmb3IgKGNvbnN0IFtpZCwgdGlja2V0XSBvZiB0aGlzLnRpY2tldHMpIHtcbiAgICAgIGlmIChub3cgPiB0aWNrZXQuZXhwaXJlc0F0KSB0aGlzLnRpY2tldHMuZGVsZXRlKGlkKTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IFtyZXF1ZXN0SWQsIGNsaWVudHNdIG9mIHRoaXMuY2xpZW50cy5lbnRyaWVzKCkpIHtcbiAgICAgIGNvbnN0IHN0YWxlOiBTU0VDbGllbnRbXSA9IFtdO1xuICAgICAgY29uc3QgYWN0aXZlOiBTU0VDbGllbnRbXSA9IFtdO1xuXG4gICAgICBmb3IgKGNvbnN0IGNsaWVudCBvZiBjbGllbnRzKSB7XG4gICAgICAgIC8vIFRpbWUtYmFzZWQgZXZpY3Rpb24gT1IgYSBzb2NrZXQgdGhhdCBzaWxlbnRseSBjbG9zZWQgKG5vICdjbG9zZSdcbiAgICAgICAgLy8gZXZlbnQpIOKAlCBOb2RlIHNvbWV0aW1lcyBkcm9wcyBzb2NrZXRzIHdpdGhvdXQgZmlyaW5nIHRoZSBldmVudCxcbiAgICAgICAgLy8gc28gd2UgZXhwbGljaXRseSBjaGVjayB3cml0YWJsZUVuZGVkL2Rlc3Ryb3llZCBoZXJlLlxuICAgICAgICBjb25zdCBhZ2VTdGFsZSA9IG5vdyAtIGNsaWVudC5jb25uZWN0ZWRBdCA+IHRoaXMuY2xpZW50VGltZW91dE1zO1xuICAgICAgICBjb25zdCBzb2NrZXREZWFkID0gY2xpZW50LnJlcy53cml0YWJsZUVuZGVkIHx8IChjbGllbnQucmVzIGFzIHsgZGVzdHJveWVkPzogYm9vbGVhbiB9KS5kZXN0cm95ZWQgPT09IHRydWU7XG4gICAgICAgIGlmIChhZ2VTdGFsZSB8fCBzb2NrZXREZWFkKSB7XG4gICAgICAgICAgc3RhbGUucHVzaChjbGllbnQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGFjdGl2ZS5wdXNoKGNsaWVudCk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgZm9yIChjb25zdCBjbGllbnQgb2Ygc3RhbGUpIHtcbiAgICAgICAgY2xlYXJUaW1lb3V0KGNsaWVudC50aW1lb3V0KTtcbiAgICAgICAgdGhpcy5kZWNyZW1lbnRPcmdDb3VudChjbGllbnQub3JnSWQpO1xuICAgICAgICB0cnkgeyBjbGllbnQucmVzLmVuZCgpOyB9IGNhdGNoIHsgLyogYWxyZWFkeSBjbG9zZWQgKi8gfVxuICAgICAgICBjbGVhbmVkKys7XG4gICAgICB9XG5cbiAgICAgIGlmIChhY3RpdmUubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHRoaXMuY2xpZW50cy5kZWxldGUocmVxdWVzdElkKTtcbiAgICAgIH0gZWxzZSBpZiAoc3RhbGUubGVuZ3RoID4gMCkge1xuICAgICAgICB0aGlzLmNsaWVudHMuc2V0KHJlcXVlc3RJZCwgYWN0aXZlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoY2xlYW5lZCA+IDApIHtcbiAgICAgIGxvZ2dlci5pbmZvKGBDbGVhbmVkIHVwICR7Y2xlYW5lZH0gc3RhbGUgU1NFIGNvbm5lY3Rpb25zYCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFNodXRkb3duIHRoZSBTU0UgbWFuYWdlciBhbmQgY2xvc2UgYWxsIGNvbm5lY3Rpb25zXG4gICAqL1xuICBzaHV0ZG93bigpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5jbGVhbnVwSW50ZXJ2YWwpIHtcbiAgICAgIGNsZWFySW50ZXJ2YWwodGhpcy5jbGVhbnVwSW50ZXJ2YWwpO1xuICAgICAgdGhpcy5jbGVhbnVwSW50ZXJ2YWwgPSBudWxsO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgcmVxdWVzdElkIG9mIFsuLi50aGlzLmNsaWVudHMua2V5cygpXSkge1xuICAgICAgdGhpcy5jbG9zZVJlcXVlc3QocmVxdWVzdElkLCAnU2VydmVyIHNodXR0aW5nIGRvd24nKTtcbiAgICB9XG5cbiAgICBsb2dnZXIuaW5mbygnU1NFIE1hbmFnZXIgc2h1dCBkb3duJyk7XG4gIH1cbn1cbiJdfQ==
|
|
561
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3NlLWNvbm5lY3Rpb24tbWFuYWdlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9odHRwL3NzZS1jb25uZWN0aW9uLW1hbmFnZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQUV0QyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQzFDLE9BQU8sRUFBRSxZQUFZLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUM3RSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFFaEUsT0FBTyxFQUFFLEVBQUUsSUFBSSxJQUFJLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDbEMsT0FBTyxFQUFFLHVCQUF1QixFQUF1QixNQUFNLHVCQUF1QixDQUFDO0FBRXJGLE1BQU0sTUFBTSxHQUFHLFlBQVksQ0FBQyxhQUFhLENBQUMsQ0FBQztBQXlGM0M7Ozs7Ozs7R0FPRztBQUNILE1BQU0sQ0FBQyxNQUFNLGlCQUFpQixHQUFHLHFFQUFxRSxDQUFDO0FBZ0J2Rzs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FpQkc7QUFDSCxNQUFNLE9BQU8sVUFBVTtJQUNiLE9BQU8sR0FBRyxJQUFJLEdBQUcsRUFBdUIsQ0FBQztJQUNqRDs7MkNBRXVDO0lBQy9CLGVBQWUsR0FBRyxJQUFJLEdBQUcsRUFBa0IsQ0FBQztJQUNwRDs7aUZBRTZFO0lBQzVELFdBQVcsQ0FBaUI7SUFDNUIsb0JBQW9CLENBQVM7SUFDN0IsZUFBZSxDQUFTO0lBQ3hCLGdCQUFnQixDQUFTO0lBQ3pCLGVBQWUsQ0FBUztJQUN4QixnQkFBZ0IsQ0FBUztJQUN6QixXQUFXLENBQVM7SUFDcEIsZ0JBQWdCLENBQVM7SUFDekIsZUFBZSxDQUFTO0lBQ2pDLGVBQWUsR0FBMEIsSUFBSSxDQUFDO0lBRXRELFlBQVksT0FBTyxHQUFzQixFQUFFO1FBQ3pDLElBQUksQ0FBQyxvQkFBb0IsR0FBRyxPQUFP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LENBQUMsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDO1lBQ2pELElBQUksQ0FBQyxZQUFZLENBQUMsU0FBUyxFQUFFLHNCQUFzQixDQUFDLENBQUM7UUFDdkQsQ0FBQztRQUVELE1BQU0sQ0FBQyxJQUFJLENBQUMsdUJBQXVCLENBQUMsQ0FBQztJQUN2QyxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuaW1wb3J0IHsgcmFuZG9tQnl0ZXMgfSBmcm9tICdub2RlOmNyeXB0byc7XG5pbXBvcnQgeyBjcmVhdGVMb2dnZXIsIFNTRV9USUNLRVRfVFRMX01TIH0gZnJvbSAnQHBpcGVsaW5lLWJ1aWxkZXIvYXBpLWNvcmUnO1xuaW1wb3J0IHsgQ29yZUNvbnN0YW50cyB9IGZyb20gJ0BwaXBlbGluZS1idWlsZGVyL3BpcGVsaW5lLWNvcmUnO1xuaW1wb3J0IHR5cGUgeyBSZXNwb25zZSB9IGZyb20gJ2V4cHJlc3MnO1xuaW1wb3J0IHsgdjcgYXMgdXVpZCB9IGZyb20gJ3V1aWQnO1xuaW1wb3J0IHsgY3JlYXRlTWVtb3J5VGlja2V0U3RvcmUsIHR5cGUgU1NFVGlja2V0U3RvcmUgfSBmcm9tICcuL3NzZS10aWNrZXQtc3RvcmUuanMnO1xuXG5jb25zdCBsb2dnZXIgPSBjcmVhdGVMb2dnZXIoJ3NzZS1tYW5hZ2VyJyk7XG5cbi8qKlxuICogRXZlbnQgdHlwZXMgZm9yIFNTRSBsb2dnaW5nXG4gKi9cbmV4cG9ydCB0eXBlIFNTRUV2ZW50VHlwZSA9ICdJTkZPJyB8ICdXQVJOJyB8ICdFUlJPUicgfCAnQ09NUExFVEVEJyB8ICdST0xMQkFDSycgfCAnTUVTU0FHRSc7XG5cbi8qKlxuICogU1NFIHBheWxvYWQgc3RydWN0dXJlXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU1NFUGF5bG9hZCB7XG4gIHRzOiBzdHJpbmc7XG4gIHR5cGU6IFNTRUV2ZW50VHlwZTtcbiAgbWVzc2FnZTogc3RyaW5nO1xuICBkYXRhPzogdW5rbm93bjtcbn1cblxuLyoqXG4gKiBTU0UgY2xpZW50IHdpdGggY29ubmVjdGlvbiB0cmFja2luZ1xuICovXG5leHBvcnQgaW50ZXJmYWNlIFNTRUNsaWVudCB7XG4gIGlkOiBzdHJpbmc7XG4gIHJlczogUmVzcG9uc2U7XG4gIGNvbm5lY3RlZEF0OiBudW1iZXI7XG4gIHRpbWVvdXQ6IE5vZGVKUy5UaW1lb3V0O1xuICAvKiogTnVtYmVyIG9mIGNvbnNlY3V0aXZlIGJhY2twcmVzc3VyZSBldmVudHMgKHdyaXRlIHJldHVybmVkIGZhbHNlKS4gKi9cbiAgYmFja3ByZXNzdXJlQ291bnQ6IG51bWJlcjtcbiAgLyoqIE93bmluZyBvcmcgaWQg4oCUIHBvcHVsYXRlZCB3aGVuIHRoZSByZXF1ZXN0IHdhcyBhdXRoZW50aWNhdGVkLiBVc2VkIHRvXG4gICAqICBkZWNyZW1lbnQgdGhlIHBlci1vcmcgY291bnRlciBvbiBkaXNjb25uZWN0IC8gY2xlYW51cC4gKi9cbiAgb3JnSWQ/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogU1NFIE1hbmFnZXIgY29uZmlndXJhdGlvbiBvcHRpb25zXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU1NFTWFuYWdlck9wdGlvbnMge1xuICAvKiogTWF4aW11bSBjbGllbnRzIGFsbG93ZWQgcGVyIHJlcXVlc3QgSUQgKGRlZmF1bHQ6IDEwKSAqL1xuICBtYXhDbGllbnRzUGVyUmVxdWVzdD86IG51bWJlcjtcbiAgLyoqIENsaWVudCB0aW1lb3V0IGluIG1pbGxpc2Vjb25kcyAoZGVmYXVsdDogMzAgbWludXRlcykgKi9cbiAgY2xpZW50VGltZW91dE1zPzogbnVtYmVyO1xuICAvKiogSW50ZXJ2YWwgZm9yIGNsZWFudXAgY2hlY2tzIGluIG1pbGxpc2Vjb25kcyAoZGVmYXVsdDogNSBtaW51dGVzKSAqL1xuICBjbGVhbnVwSW50ZXJ2YWxNcz86IG51bWJlcjtcbiAgLyoqXG4gICAqIEhhcmQgY2FwIG9uIHRvdGFsIG9wZW4gY29ubmVjdGlvbnMgcGVyIHByb2Nlc3MuIERlZmF1bHRzIHRvIDEwMDAgZnJvbVxuICAgKiBgU1NFX01BWF9UT1RBTF9DTElFTlRTYC4gTmV3IGNvbm5lY3Rpb25zIGJleW9uZCB0aGlzIGFyZSByZWplY3RlZCBhdFxuICAgKiBgYWRkQ2xpZW50KClgLiBUdW5lIHVwIGlmIHlvdXIgc2VydmljZSBzZXJ2ZXMgPiAxMDAwIGNvbmN1cnJlbnQgU1NFXG4gICAqIGRhc2hib2FyZHMsIGJ1dCBiZSBhd2FyZSBOb2RlLmpzIGZkIGxpbWl0cyBkb21pbmF0ZSBhYm92ZSB+NTAwMC5cbiAgICovXG4gIG1heFRvdGFsQ2xpZW50cz86IG51bWJlcjtcbiAgLyoqXG4gICAqIFBlci1vcmcgY2VpbGluZyBvbiBjb25jdXJyZW50IFNTRSBzdHJlYW1zLiBEZWZhdWx0cyB0byA1MCBmcm9tXG4gICAqIGBTU0VfTUFYX0NMSUVOVFNfUEVSX09SR2AuIFByb3RlY3RzIGFnYWluc3Qgb25lIG5vaXN5IG9yZyBjb25zdW1pbmcgdGhlXG4gICAqIHByb2Nlc3Mtd2lkZSBidWRnZXQg4oCUIHdpdGhvdXQgaXQsIGFuIGF1dGhlbnRpY2F0ZWQgdXNlciBjYW4gZmFuIG91dFxuICAgKiB0aG91c2FuZHMgb2Ygc3RyZWFtcyAob25lIHBlciBkYXNoYm9hcmQgLyBsb2cgc3RyZWFtKSBhbmQgc3RhcnZlIG90aGVyXG4gICAqIG9yZ3Mgb2YgY29ubmVjdGlvbiBzbG90cy4gVGhlIGNhcCBpcyBlbmZvcmNlZCBvbmx5IG9uIGBhZGRDbGllbnRgIGNhbGxzXG4gICAqIHRoYXQgY2FycnkgYW4gYG9yZ0lkYDsgc2VydmljZS1pbnRlcm5hbCAvIGFub255bW91cyBTU0UgdHJhZmZpYyBza2lwcyBpdC5cbiAgICovXG4gIG1heENsaWVudHNQZXJPcmc/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBIYXJkIGNhcCBvbiB0b3RhbCBsaXZlICh1bmNvbnN1bWVkLCB1bmV4cGlyZWQpIFNTRSB0aWNrZXRzIGFjcm9zcyB0aGVcbiAgICogcHJvY2Vzcy4gRGVmYXVsdHMgdG8gMTAwMCBmcm9tIGBTU0VfTUFYX1RPVEFMX1RJQ0tFVFNgLiBCb3VuZHMgbWVtb3J5XG4gICAqIHVuZGVyIGFidXNlIOKAlCBgY3JlYXRlVGlja2V0YCByZXR1cm5zIGB7IG9rOiBmYWxzZSwgcmVhc29uOiAnY2FwYWNpdHknIH1gXG4gICAqIG9uY2UgcmVhY2hlZC5cbiAgICovXG4gIG1heFRvdGFsVGlja2V0cz86IG51bWJlcjtcbiAgLyoqXG4gICAqIFBlci1vcmcgY2FwIG9uIGxpdmUgU1NFIHRpY2tldHMuIERlZmF1bHRzIHRvIDEwIGZyb21cbiAgICogYFNTRV9NQVhfVElDS0VUU19QRVJfT1JHYC4gUHJldmVudHMgYSBzaW5nbGUgdGVuYW50IGZyb20gc2F0dXJhdGluZyB0aGVcbiAgICogdGlja2V0IHRhYmxlIOKAlCBgY3JlYXRlVGlja2V0YCByZXR1cm5zIGB7IG9rOiBmYWxzZSwgcmVhc29uOiAnb3JnLWxpbWl0JyB9YFxuICAgKiBvbmNlIHJlYWNoZWQuXG4gICAqL1xuICBtYXhUaWNrZXRzUGVyT3JnPzogbnVtYmVyO1xuICAvKiogVGlja2V0IFRUTCBpbiBtcyAoZGVmYXVsdDogYFNTRV9USUNLRVRfVFRMX01TYCBmcm9tIGFwaS1jb3JlKS4gKi9cbiAgdGlja2V0VHRsTXM/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBUaWNrZXQgKyBzdHJlYW0tb3duZXJzaGlwIGJhY2tlbmQuIERlZmF1bHRzIHRvIGFuIGluLW1lbW9yeSBzdG9yZSAoY29ycmVjdFxuICAgKiBzaW5nbGUtcmVwbGljYSBvbmx5KS4gSW5qZWN0IGBjcmVhdGVFbnZSZWRpc1RpY2tldFN0b3JlKClgIChvciBhIGJlc3Bva2VcbiAgICogYFNTRVRpY2tldFN0b3JlYCkgc28gdGlja2V0IG1pbnQvcmVkZWVtIEFORCBzdHJlYW0gb3duZXJzaGlwIHdvcmsgYWNyb3NzXG4gICAqIGhvcml6b250YWxseS1zY2FsZWQgcG9kcyBhbmQg4oCUIGNyaXRpY2FsbHkg4oCUIHNvIHRoZSBwbGF0Zm9ybSBzdHJlYW0gcHJvZHVjZXJcbiAgICogKGEgZGlmZmVyZW50IHNlcnZpY2UpIGNhbiBiaW5kIG93bmVyc2hpcCB0aGF0IHRoaXMgc2VydmljZSByZWFkcy5cbiAgICovXG4gIHRpY2tldFN0b3JlPzogU1NFVGlja2V0U3RvcmU7XG4gIC8qKlxuICAgKiBUVEwgZm9yIGEgc3RyZWFtLW93bmVyc2hpcCBiaW5kaW5nIChkZWZhdWx0OiBgU1NFX1NUUkVBTV9PV05FUl9UVExfTVNgIGVudiBvclxuICAgKiAxaCkuIExvbmcgZW5vdWdoIHRvIG91dGxpdmUgYSBidWlsZDsgdGhlIHByb2R1Y2VyIHJlLWJpbmRzIGFzIG5lZWRlZC5cbiAgICovXG4gIHN0cmVhbU93bmVyVHRsTXM/OiBudW1iZXI7XG59XG5cbi8qKlxuICogQSBidWlsZC1sb2cgc3RyZWFtIHN1YmplY3QgaWQ6IGVpdGhlciBhIGRhc2hlZCBVVUlEIChhcGktc2VydmVyJ3MgYHV1aWQoKWApXG4gKiBvciBuZ2lueCdzIGAkcmVxdWVzdF9pZGAg4oCUIDE2IHJhbmRvbSBieXRlcyByZW5kZXJlZCBhcyAzMiBoZXggY2hhcnMgd2l0aCBOT1xuICogZGFzaGVzLiBBY2NlcHQgYm90aCBieSBtYWtpbmcgdGhlIGdyb3VwIHNlcGFyYXRvcnMgb3B0aW9uYWw7IHN0aWxsIHN0cmljdGx5XG4gKiAzMiBoZXggY2hhcnMgc28gaXQgY2FuJ3QgY2FycnkgYW4gaW5qZWN0aW9uIC8gcGF0aC10cmF2ZXJzYWwgcGF5bG9hZCBpbnRvIHRoZVxuICogU1NFIHN1YmplY3QuIFNoYXJlZCBieSB0aGUgdGlja2V0LW1pbnQgcm91dGUgYW5kIHRoZSBzdHJlYW0gbWlkZGxld2FyZSBzb1xuICogYm90aCB2YWxpZGF0ZSB0aGUgc3ViamVjdCBpZGVudGljYWxseS5cbiAqL1xuZXhwb3J0IGNvbnN0IFNTRV9SRVFVRVNUX0lEX1JFID0gL15bMC05YS1mXXs4fS0/WzAtOWEtZl17NH0tP1swLTlhLWZdezR9LT9bMC05YS1mXXs0fS0/WzAtOWEtZl17MTJ9JC9pO1xuXG4vKiogUmVzdWx0IG9mIHtAbGluayBTU0VNYW5hZ2VyLmNyZWF0ZVRpY2tldH0uICovXG5leHBvcnQgdHlwZSBDcmVhdGVUaWNrZXRSZXN1bHQgPVxuICB8IHsgb2s6IHRydWU7IHRpY2tldDogc3RyaW5nIH1cbiAgfCB7IG9rOiBmYWxzZTsgcmVhc29uOiAnb3JnLWxpbWl0JyB8ICdjYXBhY2l0eScgfCAnZm9yYmlkZGVuJyB9O1xuXG4vKipcbiAqIFNTRSBNYW5hZ2VyIHN0YXRpc3RpY3NcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTU0VNYW5hZ2VyU3RhdHMge1xuICB0b3RhbFJlcXVlc3RzOiBudW1iZXI7XG4gIHRvdGFsQ2xpZW50czogbnVtYmVyO1xuICBvbGRlc3RDb25uZWN0aW9uTXM6IG51bWJlciB8IG51bGw7XG59XG5cbi8qKlxuICogU1NFIGhlbHBlciBjbGFzcyB3aXRoIG1lbW9yeSBsZWFrIHByb3RlY3Rpb25cbiAqXG4gKiBGZWF0dXJlczpcbiAqIC0gQ2xpZW50IGxpbWl0cyBwZXIgcmVxdWVzdCBJRFxuICogLSBBdXRvbWF0aWMgdGltZW91dCBmb3IgaWRsZSBjb25uZWN0aW9uc1xuICogLSBQZXJpb2RpYyBjbGVhbnVwIG9mIHN0YWxlIGNvbm5lY3Rpb25zXG4gKiAtIENvbm5lY3Rpb24gc3RhdGlzdGljc1xuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCBzc2VNYW5hZ2VyID0gbmV3IFNTRU1hbmFnZXIoeyBtYXhDbGllbnRzUGVyUmVxdWVzdDogNSB9KTtcbiAqIGFwcC5nZXQoJy9sb2dzLzpyZXF1ZXN0SWQnLCBzc2VNYW5hZ2VyLm1pZGRsZXdhcmUoKSk7XG4gKlxuICogLy8gU2VuZCBldmVudHNcbiAqIHNzZU1hbmFnZXIuc2VuZCgncmVxdWVzdC0xMjMnLCAnSU5GTycsICdQcm9jZXNzaW5nLi4uJyk7XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGNsYXNzIFNTRU1hbmFnZXIge1xuICBwcml2YXRlIGNsaWVudHMgPSBuZXcgTWFwPHN0cmluZywgU1NFQ2xpZW50W10+KCk7XG4gIC8qKiBQZXItb3JnIG9wZW4tY2xpZW50IGNvdW50ZXJzLiBEZWNyZW1lbnRlZCBvbiByZW1vdmVDbGllbnQvY2xlYW51cCBzbyB0aGVcbiAgICogIG1hcCBtaXJyb3JzIGBjbGllbnRzW10ub3JnSWRgIGNvdW50cyBhdCBhbGwgdGltZXMuIE9yZ3MgcmVhY2ggemVybyBhcmVcbiAgICogIGRlbGV0ZWQgdG8ga2VlcCB0aGUgbWFwIGJvdW5kZWQuICovXG4gIHByaXZhdGUgb3JnQ2xpZW50Q291bnRzID0gbmV3IE1hcDxzdHJpbmcsIG51bWJlcj4oKTtcbiAgLyoqIFRpY2tldCArIHN0cmVhbS1vd25lcnNoaXAgYmFja2VuZCAoaW4tbWVtb3J5IGRlZmF1bHQ7IFJlZGlzIGZvciBtdWx0aS1wb2QpLlxuICAgKiAgQm91bmRlZCBieSBgbWF4VG90YWxUaWNrZXRzYCAvIGBtYXhUaWNrZXRzUGVyT3JnYCwgZW5mb3JjZWQgaW4gY3JlYXRlVGlja2V0O1xuICAgKiAgZXhwaXJ5IGlzIHZhbGlkYXRlZCBhdCBjb25zdW1lIHRpbWUgYW5kIHN3ZXB0IG9uIHRoZSBjbGVhbnVwIGludGVydmFsLiAqL1xuICBwcml2YXRlIHJlYWRvbmx5IHRpY2tldFN0b3JlOiBTU0VUaWNrZXRTdG9yZTtcbiAgcHJpdmF0ZSByZWFkb25seSBtYXhDbGllbnRzUGVyUmVxdWVzdDogbnVtYmVyO1xuICBwcml2YXRlIHJlYWRvbmx5IG1heFRvdGFsQ2xpZW50czogbnVtYmVyO1xuICBwcml2YXRlIHJlYWRvbmx5IG1heENsaWVudHNQZXJPcmc6IG51bWJlcjtcbiAgcHJpdmF0ZSByZWFkb25seSBtYXhUb3RhbFRpY2tldHM6IG51bWJlcjtcbiAgcHJpdmF0ZSByZWFkb25seSBtYXhUaWNrZXRzUGVyT3JnOiBudW1iZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgdGlja2V0VHRsTXM6IG51bWJlcjtcbiAgcHJpdmF0ZSByZWFkb25seSBzdHJlYW1Pd25lclR0bE1zOiBudW1iZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgY2xpZW50VGltZW91dE1zOiBudW1iZXI7XG4gIHByaXZhdGUgY2xlYW51cEludGVydmFsOiBOb2RlSlMuVGltZW91dCB8IG51bGwgPSBudWxsO1xuXG4gIGNvbnN0cnVjdG9yKG9wdGlvbnM6IFNTRU1hbmFnZXJPcHRpb25zID0ge30pIHtcbiAgICB0aGlzLm1heENsaWVudHNQZXJSZXF1ZXN0ID0gb3B0aW9ucy5tYXhDbGllbnRzUGVyUmVxdWVzdCA/PyBwYXJzZUludChwcm9jZXNzLmVudi5TU0VfTUFYX0NMSUVOVFNfUEVSX1JFUVVFU1QgfHwgJzEwJywgMTApO1xuICAgIHRoaXMubWF4VG90YWxDbGllbnRzID0gb3B0aW9ucy5tYXhUb3RhbENsaWVudHMgPz8gcGFyc2VJbnQocHJvY2Vzcy5lbnYuU1NFX01BWF9UT1RBTF9DTElFTlRTIHx8ICcxMDAwJywgMTApO1xuICAgIHRoaXMubWF4Q2xpZW50c1Blck9yZyA9IG9wdGlvbnMubWF4Q2xpZW50c1Blck9yZyA/PyBwYXJzZUludChwcm9jZXNzLmVudi5TU0VfTUFYX0NMSUVOVFNfUEVSX09SRyB8fCAnNTAnLCAxMCk7XG4gICAgdGhpcy5tYXhUb3RhbFRpY2tldHMgPSBvcHRpb25zLm1heFRvdGFsVGlja2V0cyA/PyBwYXJzZUludChwcm9jZXNzLmVudi5TU0VfTUFYX1RPVEFMX1RJQ0tFVFMgfHwgJzEwMDAnLCAxMCk7XG4gICAgdGhpcy5tYXhUaWNrZXRzUGVyT3JnID0gb3B0aW9ucy5tYXhUaWNrZXRzUGVyT3JnID8/IHBhcnNlSW50KHByb2Nlc3MuZW52LlNTRV9NQVhfVElDS0VUU19QRVJfT1JHIHx8ICcxMCcsIDEwKTtcbiAgICB0aGlzLnRpY2tldFR0bE1zID0gb3B0aW9ucy50aWNrZXRUdGxNcyA/PyBTU0VfVElDS0VUX1RUTF9NUztcbiAgICB0aGlzLnN0cmVhbU93bmVyVHRsTXMgPSBvcHRpb25zLnN0cmVhbU93bmVyVHRsTXMgPz8gcGFyc2VJbnQocHJvY2Vzcy5lbnYuU1NFX1NUUkVBTV9PV05FUl9UVExfTVMgfHwgJzM2MDAwMDAnLCAxMCk7IC8vIDEgaG91clxuICAgIHRoaXMudGlja2V0U3RvcmUgPSBvcHRpb25zLnRpY2tldFN0b3JlID8/IGNyZWF0ZU1lbW9yeVRpY2tldFN0b3JlKCk7XG4gICAgdGhpcy5jbGllbnRUaW1lb3V0TXMgPSBvcHRpb25zLmNsaWVudFRpbWVvdXRNcyA/PyBwYXJzZUludChwcm9jZXNzLmVudi5TU0VfQ0xJRU5UX1RJTUVPVVRfTVMgfHwgJzE4MDAwMDAnLCAxMCk7IC8vIDMwIG1pbnV0ZXNcblxuICAgIGNvbnN0IGNsZWFudXBJbnRlcnZhbE1zID0gb3B0aW9ucy5jbGVhbnVwSW50ZXJ2YWxNcyA/PyBwYXJzZUludChwcm9jZXNzLmVudi5TU0VfQ0xFQU5VUF9JTlRFUlZBTF9NUyB8fCAnMzAwMDAwJywgMTApOyAvLyA1IG1pbnV0ZXNcbiAgICB0aGlzLnN0YXJ0Q2xlYW51cEludGVydmFsKGNsZWFudXBJbnRlcnZhbE1zKTtcbiAgfVxuXG4gIC8qKiBUb3RhbCBvcGVuIGNvbm5lY3Rpb25zIGFjcm9zcyBhbGwgcmVxdWVzdHMuICovXG4gIHByaXZhdGUgdG90YWxDbGllbnRzKCk6IG51bWJlciB7XG4gICAgbGV0IG4gPSAwO1xuICAgIGZvciAoY29uc3QgY2xpZW50cyBvZiB0aGlzLmNsaWVudHMudmFsdWVzKCkpIG4gKz0gY2xpZW50cy5sZW5ndGg7XG4gICAgcmV0dXJuIG47XG4gIH1cblxuICAvKiogQ3VycmVudCBvcGVuLXN0cmVhbSBjb3VudCBmb3IgYW4gb3JnICgwIGlmIHVuc2VlbikuICovXG4gIGdldE9yZ0NsaWVudENvdW50KG9yZ0lkOiBzdHJpbmcpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLm9yZ0NsaWVudENvdW50cy5nZXQob3JnSWQpID8/IDA7XG4gIH1cblxuICAvKipcbiAgICogQ2Fub25pY2FsIGZvcm0gb2YgYSByZXF1ZXN0SWQgZm9yIGVxdWFsaXR5IGNoZWNrczogZGFzaGVzIHN0cmlwcGVkIGFuZFxuICAgKiBsb3dlcmNhc2VkLCBzbyB0aGUgZGFzaGVkIChhcGktc2VydmVyIGB1dWlkKClgKSBhbmQgdW5kYXNoZWQgKG5naW54XG4gICAqIGAkcmVxdWVzdF9pZGApIHJlbmRlcmluZ3Mgb2YgdGhlIHNhbWUgaWQgY29tcGFyZSBlcXVhbC4gQ2FsbGVycyBhcmVcbiAgICogZXhwZWN0ZWQgdG8gaGF2ZSBhbHJlYWR5IGZvcm1hdC12YWxpZGF0ZWQgYWdhaW5zdCB7QGxpbmsgU1NFX1JFUVVFU1RfSURfUkV9LlxuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgbm9ybWFsaXplUmVxdWVzdElkKHJlcXVlc3RJZDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICByZXR1cm4gcmVxdWVzdElkLnJlcGxhY2UoLy0vZywgJycpLnRvTG93ZXJDYXNlKCk7XG4gIH1cblxuICAvKipcbiAgICogUmVjb3JkIHRoZSBvcmcgdGhhdCBPV05TIGEgc3RyZWFtIHN1YmplY3QuIFRoZSBzdHJlYW0gUFJPRFVDRVIgY2FsbHMgdGhpc1xuICAgKiB3aGVuIGl0IGNyZWF0ZXMgYSBidWlsZC1sb2cgc3RyZWFtIHNvIHRoYXQgdGlja2V0IG1pbnRpbmcgY2FuIGFzc2VydCB0aGVcbiAgICogY2FsbGVyJ3Mgb3JnIG93bnMgdGhlIHN1YmplY3QgKHNlZSB7QGxpbmsgY3JlYXRlVGlja2V0fSkuIEJhY2tlZCBieSB0aGVcbiAgICogaW5qZWN0ZWQgdGlja2V0IHN0b3JlLCBzbyB3aGVuIGEgUmVkaXMgc3RvcmUgaXMgd2lyZWQgdGhlIHBsYXRmb3JtIHByb2R1Y2VyXG4gICAqIChhIGRpZmZlcmVudCBzZXJ2aWNlIHNoYXJpbmcgdGhlIHNhbWUgUmVkaXMpIGNhbiBiaW5kIG93bmVyc2hpcCB0aGF0IHRoaXNcbiAgICogc2VydmljZSByZWFkcyDigJQgY2xvc2luZyB0aGUgY3Jvc3MtdGVuYW50IGF0dGFjaCBnYXAgd2hlcmUgYW55IG9yZyBjb3VsZCBtaW50XG4gICAqIGEgdGlja2V0IGZvciBhIGd1ZXNzZWQgcmVxdWVzdElkLlxuICAgKlxuICAgKiBAcGFyYW0gcmVxdWVzdElkIC0gVGhlIHN0cmVhbSBzdWJqZWN0IChmb3JtYXQtdmFsaWRhdGVkIGJ5IHRoZSBjYWxsZXIpLlxuICAgKiBAcGFyYW0gb3JnSWQgLSBUaGUgb3duaW5nIG9yZyAoYWxyZWFkeSBub3JtYWxpemVkIGJ5IHRoZSBjYWxsZXIpLlxuICAgKi9cbiAgYXN5bmMgYmluZFN0cmVhbU93bmVyKHJlcXVlc3RJZDogc3RyaW5nLCBvcmdJZDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgdGhpcy50aWNrZXRTdG9yZS5iaW5kU3RyZWFtT3duZXIoXG4gICAgICBTU0VNYW5hZ2VyLm5vcm1hbGl6ZVJlcXVlc3RJZChyZXF1ZXN0SWQpLFxuICAgICAgb3JnSWQsXG4gICAgICB0aGlzLnN0cmVhbU93bmVyVHRsTXMsXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNaW50IGEgc2hvcnQtbGl2ZWQsIHNpbmdsZS11c2UgU1NFIHRpY2tldCBib3VuZCB0byBgb3JnSWRgIEFORCBhIHNwZWNpZmljXG4gICAqIHN0cmVhbSBzdWJqZWN0IChgcmVxdWVzdElkYCkuIENsaWVudHMgUE9TVCB0byBvYnRhaW4gb25lIChKV1QtYXV0aGVudGljYXRlZClcbiAgICogZm9yIHRoZSBleGFjdCBzdHJlYW0gdGhleSBpbnRlbmQgdG8gb3BlbiwgdGhlbiBvcGVuIHRoZSBFdmVudFNvdXJjZSB3aXRoXG4gICAqIGA/dGlja2V0PTx0PmAgc28gdGhlIEpXVCBuZXZlciBsYW5kcyBpbiBhIHF1ZXJ5IHN0cmluZyAvIGFjY2VzcyBsb2cuIFRoZVxuICAgKiB0aWNrZXQgY2FuIHRoZW4gb25seSBiZSBjb25zdW1lZCB0byBvcGVuIHRoYXQgb25lIHN1YmplY3QncyBzdHJlYW0g4oCUIHNlZVxuICAgKiB7QGxpbmsgY29uc3VtZVRpY2tldH0g4oCUIHdoaWNoIGlzIHdoYXQgZW5mb3JjZXMgcGVyLXN1YmplY3QgYXV0aG9yaXphdGlvbi5cbiAgICpcbiAgICogT1JHLU9XTkVSU0hJUDogaWYgYSBzdHJlYW0gb3duZXIgaGFzIGJlZW4gYm91bmQgZm9yIHRoaXMgc3ViamVjdCAodmlhXG4gICAqIHtAbGluayBiaW5kU3RyZWFtT3duZXJ9KSBhbmQgaXQgaXMgYSBESUZGRVJFTlQgb3JnLCBtaW50aW5nIGlzIHJlZnVzZWRcbiAgICogKGByZWFzb246ICdmb3JiaWRkZW4nYCkg4oCUIGFuIG9yZyBjYW5ub3QgbWludCBhIHRpY2tldCBmb3IgYW5vdGhlciBvcmcnc1xuICAgKiBzdHJlYW0gZXZlbiBpZiBpdCBndWVzc2VzIHRoZSByZXF1ZXN0SWQuIFdoZW4gbm8gb3duZXIgaXMgYm91bmQgKHByb2R1Y2VyXG4gICAqIHdpcmluZyBub3QgeWV0IHByZXNlbnQpLCBtaW50aW5nIGZhbGxzIGJhY2sgdG8gYmluZGluZyB0aGUgdGlja2V0IHRvIHRoZVxuICAgKiBjYWxsZXIncyBvd24gb3JnLCBwcmVzZXJ2aW5nIGN1cnJlbnQgYmVoYXZpb3IuXG4gICAqXG4gICAqIEJvdW5kZWQgYnkgYG1heFRvdGFsVGlja2V0c2AgKHByb2Nlc3Mtd2lkZSkgYW5kIGBtYXhUaWNrZXRzUGVyT3JnYFxuICAgKiAocGVyLXRlbmFudCkuIE1pcnJvcnMgdGhlIG1lc3NhZ2Utc2VydmljZSBub3RpZmljYXRpb25zIHRpY2tldCBzdG9yZS5cbiAgICpcbiAgICogQHBhcmFtIG9yZ0lkIC0gT3duaW5nIG9yZyAoYWxyZWFkeSBub3JtYWxpemVkIGJ5IHRoZSBjYWxsZXIpLlxuICAgKiBAcGFyYW0gcmVxdWVzdElkIC0gVGhlIGJ1aWxkLWxvZyBzdHJlYW0gc3ViamVjdCB0aGlzIHRpY2tldCBhdXRob3JpemVzLlxuICAgKiAgIFRoZSBjYWxsZXIgbXVzdCBoYXZlIGZvcm1hdC12YWxpZGF0ZWQgaXQgKHNlZSB7QGxpbmsgU1NFX1JFUVVFU1RfSURfUkV9KS5cbiAgICogQHJldHVybnMgYHsgb2s6IHRydWUsIHRpY2tldCB9YCBvbiBzdWNjZXNzLCBvciBgeyBvazogZmFsc2UsIHJlYXNvbiB9YFxuICAgKiAgIHdoZXJlIHJlYXNvbiBpcyBgJ29yZy1saW1pdCdgLCBgJ2NhcGFjaXR5J2AsIG9yIGAnZm9yYmlkZGVuJ2AuXG4gICAqL1xuICBhc3luYyBjcmVhdGVUaWNrZXQob3JnSWQ6IHN0cmluZywgcmVxdWVzdElkOiBzdHJpbmcpOiBQcm9taXNlPENyZWF0ZVRpY2tldFJlc3VsdD4ge1xuICAgIC8vIE93bmVyc2hpcCBnYXRlIGZpcnN0IOKAlCBhIGNyb3NzLXRlbmFudCBtaW50IGF0dGVtcHQgc2hvdWxkIG5ldmVyIGV2ZW5cbiAgICAvLyBjb25zdW1lIGNhcCBidWRnZXQuIE9ubHkgZW5mb3JjZWQgd2hlbiBhbiBvd25lciBpcyBhY3R1YWxseSBib3VuZC5cbiAgICBjb25zdCBub3JtYWxpemVkID0gU1NFTWFuYWdlci5ub3JtYWxpemVSZXF1ZXN0SWQocmVxdWVzdElkKTtcbiAgICBjb25zdCBvd25lciA9IGF3YWl0IHRoaXMudGlja2V0U3RvcmUuZ2V0U3RyZWFtT3duZXIobm9ybWFsaXplZCk7XG4gICAgaWYgKG93bmVyICYmIG93bmVyICE9PSBvcmdJZCkge1xuICAgICAgbG9nZ2VyLndhcm4oYFNTRSB0aWNrZXQgcmVmdXNlZDogb3JnICR7b3JnSWR9IGRvZXMgbm90IG93biBzdHJlYW0gc3ViamVjdGApO1xuICAgICAgcmV0dXJuIHsgb2s6IGZhbHNlLCByZWFzb246ICdmb3JiaWRkZW4nIH07XG4gICAgfVxuXG4gICAgLy8gVG90YWwgY2FwIG5leHQg4oCUIHByb3RlY3RzIHByb2Nlc3MgbWVtb3J5IGV2ZW4gd2hlbiBhIHNpbmdsZSBvcmcgaXNcbiAgICAvLyB0aGUgb2ZmZW5kZXIuIFRoZW4gdGhlIHBlci1vcmcgY2FwIGZvciBmYWlyLXNoYXJlLlxuICAgIGlmICgoYXdhaXQgdGhpcy50aWNrZXRTdG9yZS50b3RhbCgpKSA+PSB0aGlzLm1heFRvdGFsVGlja2V0cykge1xuICAgICAgbG9nZ2VyLndhcm4oYFNTRSB0aWNrZXQgY2FwIHJlYWNoZWQgKG1heDogJHt0aGlzLm1heFRvdGFsVGlja2V0c30pOyByZWplY3RpbmcgdGlja2V0IHJlcXVlc3RgKTtcbiAgICAgIHJldHVybiB7IG9rOiBmYWxzZSwgcmVhc29uOiAnY2FwYWNpdHknIH07XG4gICAgfVxuICAgIGlmICgoYXdhaXQgdGhpcy50aWNrZXRTdG9yZS5jb3VudEZvck9yZyhvcmdJZCkpID49IHRoaXMubWF4VGlja2V0c1Blck9yZykge1xuICAgICAgbG9nZ2VyLndhcm4oYFBlci1vcmcgU1NFIHRpY2tldCBjYXAgcmVhY2hlZCBmb3IgJHtvcmdJZH0gKG1heDogJHt0aGlzLm1heFRpY2tldHNQZXJPcmd9KWApO1xuICAgICAgcmV0dXJuIHsgb2s6IGZhbHNlLCByZWFzb246ICdvcmctbGltaXQnIH07XG4gICAgfVxuXG4gICAgY29uc3QgdGlja2V0ID0gcmFuZG9tQnl0ZXMoMjQpLnRvU3RyaW5nKCdiYXNlNjR1cmwnKTtcbiAgICBhd2FpdCB0aGlzLnRpY2tldFN0b3JlLnB1dCh0aWNrZXQsIHsgb3JnSWQsIHJlcXVlc3RJZDogbm9ybWFsaXplZCB9LCB0aGlzLnRpY2tldFR0bE1zKTtcbiAgICByZXR1cm4geyBvazogdHJ1ZSwgdGlja2V0IH07XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGUgYW5kIENPTlNVTUUgYSB0aWNrZXQgZm9yIGEgc3BlY2lmaWMgc3RyZWFtIHN1YmplY3QuIFNpbmdsZS11c2U6XG4gICAqIHRoZSB0aWNrZXQgaXMgZGVsZXRlZCB3aGV0aGVyIG9yIG5vdCBpdCB0dXJucyBvdXQgdG8gYmUgdmFsaWQsIHNvIGEgcmVwbGF5XG4gICAqIG9mIHRoZSBzYW1lIHZhbHVlIGFsd2F5cyBmYWlscy4gUmV0dXJucyB0aGUgYm91bmQgb3JnIG9uIHN1Y2Nlc3MsIG9yIG51bGxcbiAgICogd2hlbiB0aGUgdGlja2V0IGlzIHVua25vd24gLyBhbHJlYWR5LXVzZWQgLyBleHBpcmVkIC8gT1Igd2FzIG1pbnRlZCBmb3IgYVxuICAgKiBESUZGRVJFTlQgYHJlcXVlc3RJZGAgdGhhbiB0aGUgb25lIGJlaW5nIG9wZW5lZC5cbiAgICpcbiAgICogVGhlIHN1YmplY3QgY2hlY2sgaXMgdGhlIGF1dGhvcml6YXRpb24gZml4OiB3aXRob3V0IGl0LCBhIHRpY2tldCBtaW50ZWQgZm9yXG4gICAqIG9uZSBzdHJlYW0gY291bGQgYmUgcHJlc2VudGVkIHRvIG9wZW4gQU5ZIHN0cmVhbSB0aGUgaG9sZGVyJ3Mgb3JnIGNvdWxkXG4gICAqIG5hbWUsIGxldHRpbmcgYW4gYXV0aGVudGljYXRlZCBvcmcgYXR0YWNoIHRvIGFub3RoZXIgb3JnJ3MgbG9nIHN0cmVhbSBieVxuICAgKiBndWVzc2luZyBpdHMgcmVxdWVzdElkLiBUaGUgZ2VuZXJpYyA0MDEgdGhlIGNhbGxlciByZXR1cm5zIGRvZXMgbm90XG4gICAqIGRpc3Rpbmd1aXNoIFwidW5rbm93biB0aWNrZXRcIiBmcm9tIFwid3Jvbmcgc3ViamVjdFwiLCBzbyBpdCBsZWFrcyBub3RoaW5nXG4gICAqIGFib3V0IHdoaWNoIHJlcXVlc3RJZHMgZXhpc3QuXG4gICAqXG4gICAqIEBwYXJhbSB0aWNrZXRJZCAtIFRoZSBvcGFxdWUgdGlja2V0IHZhbHVlIGZyb20gYD90aWNrZXQ9YC5cbiAgICogQHBhcmFtIHJlcXVlc3RJZCAtIFRoZSBzdHJlYW0gc3ViamVjdCBmcm9tIHRoZSBVUkwgcGF0aCAoYDpyZXF1ZXN0SWRgKSxcbiAgICogICBhbHJlYWR5IGZvcm1hdC12YWxpZGF0ZWQgYnkgdGhlIGNhbGxlci5cbiAgICovXG4gIGFzeW5jIGNvbnN1bWVUaWNrZXQodGlja2V0SWQ6IHN0cmluZywgcmVxdWVzdElkOiBzdHJpbmcpOiBQcm9taXNlPHsgb3JnSWQ6IHN0cmluZyB9IHwgbnVsbD4ge1xuICAgIGNvbnN0IHRpY2tldCA9IGF3YWl0IHRoaXMudGlja2V0U3RvcmUuY29uc3VtZSh0aWNrZXRJZCk7IC8vIHNpbmdsZS11c2VcbiAgICBpZiAoIXRpY2tldCkgcmV0dXJuIG51bGw7XG4gICAgLy8gU3ViamVjdCBiaW5kaW5nIOKAlCByZWplY3QgYSB0aWNrZXQgcHJlc2VudGVkIGZvciBhIHN1YmplY3QgaXQgd2FzIG5vdFxuICAgIC8vIG1pbnRlZCBmb3IuIEJvdGggc2lkZXMgYXJlIG5vcm1hbGl6ZWQgc28gZGFzaGVkL3VuZGFzaGVkIGZvcm1zIG1hdGNoLlxuICAgIGlmICh0aWNrZXQucmVxdWVzdElkICE9PSBTU0VNYW5hZ2VyLm5vcm1hbGl6ZVJlcXVlc3RJZChyZXF1ZXN0SWQpKSByZXR1cm4gbnVsbDtcbiAgICByZXR1cm4geyBvcmdJZDogdGlja2V0Lm9yZ0lkIH07XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBhIGNsaWVudCB0byB0aGUgU1NFIG1hbmFnZXJcbiAgICpcbiAgICogQHBhcmFtIHJlcXVlc3RJZCAtIFVuaXF1ZSByZXF1ZXN0IElEXG4gICAqIEBwYXJhbSByZXMgLSBFeHByZXNzIFJlc3BvbnNlIG9iamVjdFxuICAgKiBAcGFyYW0gb3JnSWQgLSBBdXRoZW50aWNhdGVkIG9yZyBpZCAob3B0aW9uYWwpLiBXaGVuIHNldCwgZW5mb3JjZXMgdGhlXG4gICAqICAgcGVyLW9yZyBjYXAgYW5kIHRoZSBjb3VudGVyIGlzIGRlY3JlbWVudGVkIG9uIGRpc2Nvbm5lY3QvY2xlYW51cC5cbiAgICogQHJldHVybnMgdHJ1ZSBpZiBjbGllbnQgd2FzIGFkZGVkLCBmYWxzZSBpZiByZWplY3RlZCAobGltaXQgcmVhY2hlZClcbiAgICovXG4gIGFkZENsaWVudChyZXF1ZXN0SWQ6IHN0cmluZywgcmVzOiBSZXNwb25zZSwgb3JnSWQ/OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICBjb25zdCBleGlzdGluZyA9IHRoaXMuY2xpZW50cy5nZXQocmVxdWVzdElkKSB8fCBbXTtcblxuICAgIC8vIENoZWNrIGNsaWVudCBsaW1pdFxuICAgIGlmIChleGlzdGluZy5sZW5ndGggPj0gdGhpcy5tYXhDbGllbnRzUGVyUmVxdWVzdCkge1xuICAgICAgbG9nZ2VyLndhcm4oYENsaWVudCBsaW1pdCByZWFjaGVkIGZvciByZXF1ZXN0ICR7cmVxdWVzdElkfSAobWF4OiAke3RoaXMubWF4Q2xpZW50c1BlclJlcXVlc3R9KWApO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIC8vIFByb2Nlc3Mtd2lkZSBjYXA6IHByb3RlY3RzIGZkIHRhYmxlICsgbWVtb3J5IGZyb20gcnVuYXdheSBkYXNoYm9hcmRzLlxuICAgIGlmICh0aGlzLnRvdGFsQ2xpZW50cygpID49IHRoaXMubWF4VG90YWxDbGllbnRzKSB7XG4gICAgICBsb2dnZXIud2FybihgVG90YWwgU1NFIGNsaWVudCBjYXAgcmVhY2hlZCAobWF4OiAke3RoaXMubWF4VG90YWxDbGllbnRzfSk7IHJlamVjdGluZyBuZXcgY29ubmVjdGlvbmApO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIC8vIFBlci1vcmcgY2FwOiBwcmV2ZW50cyBvbmUgbm9pc3kgb3JnIGZyb20gbW9ub3BvbGl6aW5nIHByb2Nlc3Mtd2lkZVxuICAgIC8vIHNsb3RzLiBFbmZvcmNlZCBvbmx5IHdoZW4gb3JnSWQgaXMga25vd24g4oCUIHNlcnZpY2UtaW50ZXJuYWwgLyBhbm9ueW1vdXNcbiAgICAvLyBzdHJlYW1zIHRoYXQgbmV2ZXIgaWRlbnRpZnkgd2l0aCBhbiBvcmdJZCBzdGF5IHN1YmplY3QgdG8gdGhlIGdsb2JhbFxuICAgIC8vIGNlaWxpbmdzIGFib3ZlLiBSZXNlcnZlIGF0b21pY2FsbHkgYmVmb3JlIGluc2VydCBzbyB0d28gY29uY3VycmVudFxuICAgIC8vIHJlcXVlc3RzIGF0IHRoZSBsaW1pdCBjYW4ndCBib3RoIHN1Y2NlZWQuXG4gICAgaWYgKG9yZ0lkKSB7XG4gICAgICBjb25zdCBvcmdDdXJyZW50ID0gdGhpcy5vcmdDbGllbnRDb3VudHMuZ2V0KG9yZ0lkKSA/PyAwO1xuICAgICAgaWYgKG9yZ0N1cnJlbnQgPj0gdGhpcy5tYXhDbGllbnRzUGVyT3JnKSB7XG4gICAgICAgIGxvZ2dlci53YXJuKGBQZXItb3JnIFNTRSBjbGllbnQgY2FwIHJlYWNoZWQgZm9yICR7b3JnSWR9IChtYXg6ICR7dGhpcy5tYXhDbGllbnRzUGVyT3JnfSk7IHJlamVjdGluZyBuZXcgY29ubmVjdGlvbmApO1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICB0aGlzLm9yZ0NsaWVudENvdW50cy5zZXQob3JnSWQsIG9yZ0N1cnJlbnQgKyAxKTtcbiAgICB9XG5cbiAgICAvLyBDcmVhdGUgdGltZW91dCBmb3IgdGhpcyBjbGllbnRcbiAgICBjb25zdCBjbGllbnRJZCA9IHV1aWQoKTtcbiAgICBjb25zdCB0aW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICBsb2dnZXIuZGVidWcoYENsaWVudCAke2NsaWVudElkfSB0aW1lZCBvdXQgZm9yIHJlcXVlc3QgJHtyZXF1ZXN0SWR9YCk7XG4gICAgICB0aGlzLnJlbW92ZUNsaWVudChyZXF1ZXN0SWQsIGNsaWVudElkKTtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJlcy5lbmQoKTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBsb2dnZXIuZGVidWcoJ1Jlc3BvbnNlIGFscmVhZHkgY2xvc2VkIG9uIHRpbWVvdXQnLCB7IHJlcXVlc3RJZCwgY2xpZW50SWQsIGVycm9yOiBlcnIgaW5zdGFuY2VvZiBFcnJvciA/IGVyci5tZXNzYWdlIDogU3RyaW5nKGVycikgfSk7XG4gICAgICB9XG4gICAgfSwgdGhpcy5jbGllbnRUaW1lb3V0TXMpO1xuXG4gICAgY29uc3QgY2xpZW50OiBTU0VDbGllbnQgPSB7XG4gICAgICBpZDogY2xpZW50SWQsXG4gICAgICByZXMsXG4gICAgICBjb25uZWN0ZWRBdDogRGF0ZS5ub3coKSxcbiAgICAgIHRpbWVvdXQsXG4gICAgICBiYWNrcHJlc3N1cmVDb3VudDogMCxcbiAgICAgIG9yZ0lkLFxuICAgIH07XG5cbiAgICAvLyBIYW5kbGUgZGlzY29ubmVjdGlvblxuICAgIHJlcy5vbignY2xvc2UnLCAoKSA9PiB7XG4gICAgICBjbGVhclRpbWVvdXQodGltZW91dCk7XG4gICAgICB0aGlzLnJlbW92ZUNsaWVudChyZXF1ZXN0SWQsIGNsaWVudElkKTtcbiAgICB9KTtcblxuICAgIHJlcy5vbignZXJyb3InLCAoZXJyKSA9PiB7XG4gICAgICBsb2dnZXIuZXJyb3IoYFNTRSBjbGllbnQgZXJyb3IgZm9yIHJlcXVlc3QgJHtyZXF1ZXN0SWR9OmAsIGVycik7XG4gICAgICBjbGVhclRpbWVvdXQodGltZW91dCk7XG4gICAgICB0aGlzLnJlbW92ZUNsaWVudChyZXF1ZXN0SWQsIGNsaWVudElkKTtcbiAgICB9KTtcblxuICAgIGV4aXN0aW5nLnB1c2goY2xpZW50KTtcbiAgICB0aGlzLmNsaWVudHMuc2V0KHJlcXVlc3RJZCwgZXhpc3RpbmcpO1xuXG4gICAgbG9nZ2VyLmRlYnVnKGBDbGllbnQgJHtjbGllbnRJZH0gY29ubmVjdGVkIGZvciByZXF1ZXN0ICR7cmVxdWVzdElkfSAodG90YWw6ICR7ZXhpc3RpbmcubGVuZ3RofSlgKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8qKiBEcm9wIG9uZSBmcm9tIHRoZSBwZXItb3JnIGNvdW50ZXIuIElkZW1wb3RlbnQ6IGEgY291bnRlciBhdCAwIHN0YXlzIGF0IDBcbiAgICogIGFuZCB0aGUgb3JnIGtleSBpcyByZW1vdmVkIGZyb20gdGhlIG1hcC4gKi9cbiAgcHJpdmF0ZSBkZWNyZW1lbnRPcmdDb3VudChvcmdJZD86IHN0cmluZyk6IHZvaWQge1xuICAgIGlmICghb3JnSWQpIHJldHVybjtcbiAgICBjb25zdCBjdXJyZW50ID0gdGhpcy5vcmdDbGllbnRDb3VudHMuZ2V0KG9yZ0lkKSA/PyAwO1xuICAgIGlmIChjdXJyZW50IDw9IDEpIHRoaXMub3JnQ2xpZW50Q291bnRzLmRlbGV0ZShvcmdJZCk7XG4gICAgZWxzZSB0aGlzLm9yZ0NsaWVudENvdW50cy5zZXQob3JnSWQsIGN1cnJlbnQgLSAxKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmVzIGEgY2xpZW50IGZyb20gdGhlIG1hbmFnZXJcbiAgICovXG4gIHByaXZhdGUgcmVtb3ZlQ2xpZW50KHJlcXVlc3RJZDogc3RyaW5nLCBjbGllbnRJZDogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgY2xpZW50cyA9IHRoaXMuY2xpZW50cy5nZXQocmVxdWVzdElkKTtcbiAgICBpZiAoIWNsaWVudHMpIHJldHVybjtcblxuICAgIGNvbnN0IHJlbWFpbmluZyA9IGNsaWVudHMuZmlsdGVyKGMgPT4ge1xuICAgICAgaWYgKGMuaWQgPT09IGNsaWVudElkKSB7XG4gICAgICAgIGNsZWFyVGltZW91dChjLnRpbWVvdXQpO1xuICAgICAgICAvLyBNaXJyb3IgdGhlIHBlci1vcmcgY291bnRlciDigJQgbXVzdCBkZWNyZW1lbnQgaGVyZSwgbm90IGp1c3QgaW4gdGhlXG4gICAgICAgIC8vIGV4cGxpY2l0IGNsb3NlIHBhdGhzLCBzaW5jZSAnY2xvc2UnLydlcnJvcicgZXZlbnQgaGFuZGxlcnMgYXJlIHRoZVxuICAgICAgICAvLyBwcmltYXJ5IGRpc2Nvbm5lY3Qgc2lnbmFsIGluIHByYWN0aWNlLlxuICAgICAgICB0aGlzLmRlY3JlbWVudE9yZ0NvdW50KGMub3JnSWQpO1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9KTtcblxuICAgIGlmIChyZW1haW5pbmcubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aGlzLmNsaWVudHMuZGVsZXRlKHJlcXVlc3RJZCk7XG4gICAgICBsb2dnZXIuZGVidWcoYEFsbCBjbGllbnRzIGRpc2Nvbm5lY3RlZCBmb3IgcmVxdWVzdCAke3JlcXVlc3RJZH1gKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5jbGllbnRzLnNldChyZXF1ZXN0SWQsIHJlbWFpbmluZyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFNlbmRzIGEgbWVzc2FnZSB0byBhbGwgU1NFIGNsaWVudHMgZm9yIGEgcmVxdWVzdElkXG4gICAqXG4gICAqIEBwYXJhbSByZXF1ZXN0SWQgLSBSZXF1ZXN0IElEXG4gICAqIEBwYXJhbSB0eXBlIC0gRXZlbnQgdHlwZVxuICAgKiBAcGFyYW0gbWVzc2FnZSAtIE1lc3NhZ2Ugc3RyaW5nXG4gICAqIEBwYXJhbSBkYXRhIC0gT3B0aW9uYWwgYWRkaXRpb25hbCBkYXRhXG4gICAqIEByZXR1cm5zIE51bWJlciBvZiBjbGllbnRzIHRoZSBtZXNzYWdlIHdhcyBzZW50IHRvXG4gICAqL1xuICBzZW5kKHJlcXVlc3RJZDogc3RyaW5nLCB0eXBlOiBTU0VFdmVudFR5cGUsIG1lc3NhZ2U6IHN0cmluZywgZGF0YT86IHVua25vd24pOiBudW1iZXIge1xuICAgIGNvbnN0IHBheWxvYWQ6IFNTRVBheWxvYWQgPSB7XG4gICAgICB0czogbmV3IERhdGUoKS50b0lTT1N0cmluZygpLFxuICAgICAgdHlwZSxcbiAgICAgIG1lc3NhZ2UsXG4gICAgICBkYXRhLFxuICAgIH07XG5cbiAgICBjb25zdCBjbGllbnRzID0gWy4uLih0aGlzLmNsaWVudHMuZ2V0KHJlcXVlc3RJZCkgfHwgW10pXTtcbiAgICBsZXQgc2VudENvdW50ID0gMDtcbiAgICBjb25zdCBzZXJpYWxpemVkID0gYGRhdGE6ICR7SlNPTi5zdHJpbmdpZnkocGF5bG9hZCl9XFxuXFxuYDtcblxuICAgIGZvciAoY29uc3QgY2xpZW50IG9mIGNsaWVudHMpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIC8vIEJhY2twcmVzc3VyZTogc2tpcCBjbGllbnRzIHdob3NlIHdyaXRlIGJ1ZmZlciBpcyBmdWxsXG4gICAgICAgIGlmIChjbGllbnQucmVzLndyaXRhYmxlRW5kZWQpIHtcbiAgICAgICAgICB0aGlzLnJlbW92ZUNsaWVudChyZXF1ZXN0SWQsIGNsaWVudC5pZCk7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgY2FuV3JpdGUgPSBjbGllbnQucmVzLndyaXRlKHNlcmlhbGl6ZWQpO1xuICAgICAgICBpZiAoIWNhbldyaXRlKSB7XG4gICAgICAgICAgY2xpZW50LmJhY2twcmVzc3VyZUNvdW50Kys7XG4gICAgICAgICAgLy8gRGlzY29ubmVjdCBjbGllbnRzIHRoYXQgY29uc2lzdGVudGx5IGNhbid0IGtlZXAgdXAgKDEwIGNvbnNlY3V0aXZlIGJhY2twcmVzc3VyZSBldmVudHMpXG4gICAgICAgICAgaWYgKGNsaWVudC5iYWNrcHJlc3N1cmVDb3VudCA+PSBDb3JlQ29uc3RhbnRzLlNTRV9CQUNLUFJFU1NVUkVfVEhSRVNIT0xEKSB7XG4gICAgICAgICAgICBsb2dnZXIud2FybihgRGlzY29ubmVjdGluZyBzbG93IGNsaWVudCAke2NsaWVudC5pZH0gZm9yIHJlcXVlc3QgJHtyZXF1ZXN0SWR9ICgke2NsaWVudC5iYWNrcHJlc3N1cmVDb3VudH0gYmFja3ByZXNzdXJlIGV2ZW50cylgKTtcbiAgICAgICAgICAgIHRoaXMucmVtb3ZlQ2xpZW50KHJlcXVlc3RJZCwgY2xpZW50LmlkKTtcbiAgICAgICAgICAgIHRyeSB7IGNsaWVudC5yZXMuZW5kKCk7IH0gY2F0Y2ggeyAvKiBhbHJlYWR5IGNsb3NlZCAqLyB9XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY2xpZW50LmJhY2twcmVzc3VyZUNvdW50ID0gMDsgLy8gUmVzZXQgb24gc3VjY2Vzc2Z1bCB3cml0ZVxuICAgICAgICB9XG4gICAgICAgIHNlbnRDb3VudCsrO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgbG9nZ2VyLmVycm9yKGBGYWlsZWQgdG8gc2VuZCB0byBjbGllbnQgJHtjbGllbnQuaWR9OmAsIGVycm9yKTtcbiAgICAgICAgdGhpcy5yZW1vdmVDbGllbnQocmVxdWVzdElkLCBjbGllbnQuaWQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBzZW50Q291bnQ7XG4gIH1cblxuICAvKipcbiAgICogQnJvYWRjYXN0IGEgbWVzc2FnZSB0byBhbGwgY29ubmVjdGVkIGNsaWVudHMgYWNyb3NzIGFsbCByZXF1ZXN0c1xuICAgKlxuICAgKiBAcGFyYW0gdHlwZSAtIEV2ZW50IHR5cGVcbiAgICogQHBhcmFtIG1lc3NhZ2UgLSBNZXNzYWdlIHN0cmluZ1xuICAgKiBAcGFyYW0gZGF0YSAtIE9wdGlvbmFsIGFkZGl0aW9uYWwgZGF0YVxuICAgKiBAcmV0dXJucyBUb3RhbCBudW1iZXIgb2YgY2xpZW50cyB0aGUgbWVzc2FnZSB3YXMgc2VudCB0b1xuICAgKi9cbiAgYnJvYWRjYXN0KHR5cGU6IFNTRUV2ZW50VHlwZSwgbWVzc2FnZTogc3RyaW5nLCBkYXRhPzogdW5rbm93bik6IG51bWJlciB7XG4gICAgbGV0IHRvdGFsU2VudCA9IDA7XG4gICAgZm9yIChjb25zdCByZXF1ZXN0SWQgb2YgdGhpcy5jbGllbnRzLmtleXMoKSkge1xuICAgICAgdG90YWxTZW50ICs9IHRoaXMuc2VuZChyZXF1ZXN0SWQsIHR5cGUsIG1lc3NhZ2UsIGRhdGEpO1xuICAgIH1cbiAgICByZXR1cm4gdG90YWxTZW50O1xuICB9XG5cbiAgLyoqXG4gICAqIENsb3NlIGFsbCBjbGllbnRzIGZvciBhIHNwZWNpZmljIHJlcXVlc3RcbiAgICpcbiAgICogQHBhcmFtIHJlcXVlc3RJZCAtIFJlcXVlc3QgSUQgdG8gY2xvc2VcbiAgICogQHBhcmFtIGZpbmFsTWVzc2FnZSAtIE9wdGlvbmFsIGZpbmFsIG1lc3NhZ2UgdG8gc2VuZCBiZWZvcmUgY2xvc2luZ1xuICAgKi9cbiAgY2xvc2VSZXF1ZXN0KHJlcXVlc3RJZDogc3RyaW5nLCBmaW5hbE1lc3NhZ2U/OiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBjbGllbnRzID0gdGhpcy5jbGllbnRzLmdldChyZXF1ZXN0SWQpO1xuICAgIGlmICghY2xpZW50cykgcmV0dXJuO1xuXG4gICAgaWYgKGZpbmFsTWVzc2FnZSkge1xuICAgICAgdGhpcy5zZW5kKHJlcXVlc3RJZCwgJ0NPTVBMRVRFRCcsIGZpbmFsTWVzc2FnZSk7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBjbGllbnQgb2YgY2xpZW50cykge1xuICAgICAgY2xlYXJUaW1lb3V0KGNsaWVudC50aW1lb3V0KTtcbiAgICAgIHRoaXMuZGVjcmVtZW50T3JnQ291bnQoY2xpZW50Lm9yZ0lkKTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNsaWVudC5yZXMuZW5kKCk7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgbG9nZ2VyLmRlYnVnKCdSZXNwb25zZSBhbHJlYWR5IGNsb3NlZCBvbiByZXF1ZXN0IGNsb3NlJywgeyByZXF1ZXN0SWQsIGNsaWVudElkOiBjbGllbnQuaWQsIGVycm9yOiBlcnIgaW5zdGFuY2VvZiBFcnJvciA/IGVyci5tZXNzYWdlIDogU3RyaW5nKGVycikgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5jbGllbnRzLmRlbGV0ZShyZXF1ZXN0SWQpO1xuICAgIGxvZ2dlci5kZWJ1ZyhgQ2xvc2VkIGFsbCBjbGllbnRzIGZvciByZXF1ZXN0ICR7cmVxdWVzdElkfWApO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBzdGF0aXN0aWNzIGFib3V0IGN1cnJlbnQgY29ubmVjdGlvbnNcbiAgICovXG4gIGdldFN0YXRzKCk6IFNTRU1hbmFnZXJTdGF0cyB7XG4gICAgbGV0IHRvdGFsQ2xpZW50cyA9IDA7XG4gICAgbGV0IG9sZGVzdENvbm5lY3Rpb246IG51bWJlciB8IG51bGwgPSBudWxsO1xuICAgIGNvbnN0IG5vdyA9IERhdGUubm93KCk7XG5cbiAgICBmb3IgKGNvbnN0IGNsaWVudHMgb2YgdGhpcy5jbGllbnRzLnZhbHVlcygpKSB7XG4gICAgICB0b3RhbENsaWVudHMgKz0gY2xpZW50cy5sZW5ndGg7XG4gICAgICBmb3IgKGNvbnN0IGNsaWVudCBvZiBjbGllbnRzKSB7XG4gICAgICAgIGNvbnN0IGFnZSA9IG5vdyAtIGNsaWVudC5jb25uZWN0ZWRBdDtcbiAgICAgICAgaWYgKG9sZGVzdENvbm5lY3Rpb24gPT09IG51bGwgfHwgYWdlID4gb2xkZXN0Q29ubmVjdGlvbikge1xuICAgICAgICAgIG9sZGVzdENvbm5lY3Rpb24gPSBhZ2U7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgdG90YWxSZXF1ZXN0czogdGhpcy5jbGllbnRzLnNpemUsXG4gICAgICB0b3RhbENsaWVudHMsXG4gICAgICBvbGRlc3RDb25uZWN0aW9uTXM6IG9sZGVzdENvbm5lY3Rpb24sXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiBhIHJlcXVlc3QgaGFzIGFueSBjb25uZWN0ZWQgY2xpZW50c1xuICAgKi9cbiAgaGFzQ2xpZW50cyhyZXF1ZXN0SWQ6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IGNsaWVudHMgPSB0aGlzLmNsaWVudHMuZ2V0KHJlcXVlc3RJZCk7XG4gICAgcmV0dXJuIGNsaWVudHMgIT09IHVuZGVmaW5lZCAmJiBjbGllbnRzLmxlbmd0aCA+IDA7XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSBudW1iZXIgb2YgY2xpZW50cyBmb3IgYSBzcGVjaWZpYyByZXF1ZXN0XG4gICAqL1xuICBnZXRDbGllbnRDb3VudChyZXF1ZXN0SWQ6IHN0cmluZyk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuY2xpZW50cy5nZXQocmVxdWVzdElkKT8ubGVuZ3RoID8/IDA7XG4gIH1cblxuICAvKipcbiAgICogTWlkZGxld2FyZSB0byBpbml0aWFsaXplIGEgdGlja2V0LWF1dGhlbnRpY2F0ZWQgU1NFIGNvbm5lY3Rpb24uXG4gICAqXG4gICAqIFRoZSBzdHJlYW0gaXMgTk9UIG9wZW4gdG8gdGhlIHdvcmxkOiB0aGUgY2FsbGVyIG11c3QgZmlyc3QgZXhjaGFuZ2UgaXRzXG4gICAqIEpXVCBmb3IgYSBzaG9ydC1saXZlZCBzaW5nbGUtdXNlIHRpY2tldCAoc2VlIHtAbGluayBjcmVhdGVUaWNrZXR9LCB3aXJlZCB0b1xuICAgKiBgUE9TVCAvbG9ncy90aWNrZXRgKSBhbmQgcGFzcyBpdCBhcyBgP3RpY2tldD08dD5gLiBUaGUgbWlkZGxld2FyZSB2YWxpZGF0ZXNcbiAgICogKyBjb25zdW1lcyB0aGUgdGlja2V0LCBiaW5kcyB0aGUgY29ubmVjdGlvbiB0byB0aGUgdGlja2V0J3Mgb3JnLCBhbmRcbiAgICogZW5mb3JjZXMgdGhlIHBlci1vcmcgY29ubmVjdGlvbiBjYXAuIEEgbWlzc2luZyAvIGludmFsaWQgLyBleHBpcmVkIC9cbiAgICogYWxyZWFkeS11c2VkIHRpY2tldCBpcyByZWplY3RlZCB3aXRoIDQwMSBiZWZvcmUgYW55IFNTRSBoZWFkZXJzIGZsdXNoLlxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiBgYGB0eXBlc2NyaXB0XG4gICAqIGFwcC5nZXQoJy9sb2dzLzpyZXF1ZXN0SWQnLCBzc2VNYW5hZ2VyLm1pZGRsZXdhcmUoKSk7XG4gICAqIGBgYFxuICAgKi9cbiAgbWlkZGxld2FyZSgpIHtcbiAgICByZXR1cm4gYXN5bmMgKHJlcTogeyBwYXJhbXM6IHsgcmVxdWVzdElkOiBzdHJpbmcgfTsgcXVlcnk/OiB7IHRpY2tldD86IHVua25vd24gfSB9LCByZXM6IFJlc3BvbnNlKSA9PiB7XG4gICAgICBjb25zdCB7IHJlcXVlc3RJZCB9ID0gcmVxLnBhcmFtcztcblxuICAgICAgaWYgKCFTU0VfUkVRVUVTVF9JRF9SRS50ZXN0KHJlcXVlc3RJZCkpIHtcbiAgICAgICAgcmVzLnN0YXR1cyg0MDApLmVuZCgnSW52YWxpZCByZXF1ZXN0SWQgZm9ybWF0Jyk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgLy8gVGlja2V0IGF1dGgg4oCUIHJlcXVpcmVkLiBSZXNvbHZlIGA/dGlja2V0PTx0PmAsIHRoZW4gdmFsaWRhdGUgKyBjb25zdW1lXG4gICAgICAvLyBpdCAoc2luZ2xlLXVzZSkgRk9SIFRISVMgU1VCSkVDVC4gQW4gYW5vbnltb3VzLCBtYWxmb3JtZWQsIHVua25vd24sXG4gICAgICAvLyBleHBpcmVkLCBhbHJlYWR5LWNvbnN1bWVkLCBvciB3cm9uZy1zdWJqZWN0IHRpY2tldCBpcyBhIDQwMS4gVGhlIG9yZyBpc1xuICAgICAgLy8gdGFrZW4gZnJvbSB0aGUgdGlja2V0LCBzbyB0aGUgc3RyZWFtIGlzIGFsd2F5cyBib3VuZCB0byBhIHZlcmlmaWVkXG4gICAgICAvLyB0ZW5hbnQgQU5EIHRvIHRoZSBleGFjdCBzdWJqZWN0IHRoZSB0aWNrZXQgd2FzIG1pbnRlZCBmb3IgKG5vIGFub255bW91c1xuICAgICAgLy8gc3RyZWFtcywgbm8gY3Jvc3Mtc3ViamVjdCBhdHRhY2gpLlxuICAgICAgY29uc3QgdGlja2V0SWQgPSByZXEucXVlcnk/LnRpY2tldDtcbiAgICAgIGlmICh0eXBlb2YgdGlja2V0SWQgIT09ICdzdHJpbmcnIHx8IHRpY2tldElkLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICByZXMuc3RhdHVzKDQwMSkuZW5kKCdNaXNzaW5nIHRpY2tldCcpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBjb25zdCBjb25zdW1lZCA9IGF3YWl0IHRoaXMuY29uc3VtZVRpY2tldCh0aWNrZXRJZCwgcmVxdWVzdElkKTtcbiAgICAgIGlmICghY29uc3VtZWQpIHtcbiAgICAgICAgcmVzLnN0YXR1cyg0MDEpLmVuZCgnSW52YWxpZCBvciBleHBpcmVkIHRpY2tldCcpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBjb25zdCBvcmdJZCA9IGNvbnN1bWVkLm9yZ0lkO1xuXG4gICAgICAvLyBQcmUtZmxpZ2h0IHBlci1yZXF1ZXN0IGNhcCBzbyB3ZSBjYW4gcmV0dXJuIDQyOSBiZWZvcmUgZmx1c2hpbmdcbiAgICAgIC8vIFNTRSBoZWFkZXJzIChhZnRlciBoZWFkZXJzIGFyZSBmbHVzaGVkIHRoZSBjbGllbnQgY2FuJ3QgcmVhZCBhIDQyOSkuXG4gICAgICBjb25zdCBleGlzdGluZyA9IHRoaXMuY2xpZW50cy5nZXQocmVxdWVzdElkKSB8fCBbXTtcbiAgICAgIGlmIChleGlzdGluZy5sZW5ndGggPj0gdGhpcy5tYXhDbGllbnRzUGVyUmVxdWVzdCkge1xuICAgICAgICBsb2dnZXIud2FybihgQ2xpZW50IGxpbWl0IHJlYWNoZWQgZm9yIHJlcXVlc3QgJHtyZXF1ZXN0SWR9IChtYXg6ICR7dGhpcy5tYXhDbGllbnRzUGVyUmVxdWVzdH0pYCk7XG4gICAgICAgIHJlcy5zdGF0dXMoNDI5KS5lbmQoJ1RvbyBtYW55IGNvbm5lY3Rpb25zIGZvciB0aGlzIHJlcXVlc3QnKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICAvLyBTYW1lIGZvciB0aGUgcGVyLW9yZyBjYXAg4oCUIGJldHRlciB0byBzZW5kIDQyOSB0aGFuIG9wZW4gdGhlIHN0cmVhbSBhbmRcbiAgICAgIC8vIGltbWVkaWF0ZWx5IGNsb3NlIGl0LiBUaGUgdGlja2V0IGd1YXJhbnRlZXMgYSB2ZXJpZmllZCBvcmcgaWQsIHNvIHRoZVxuICAgICAgLy8gcGVyLW9yZyBjZWlsaW5nIGlzIGFsd2F5cyBlbmZvcmNlZCBmb3IgdGhlIC9sb2dzIHN0cmVhbS5cbiAgICAgIGlmICgodGhpcy5vcmdDbGllbnRDb3VudHMuZ2V0KG9yZ0lkKSA/PyAwKSA+PSB0aGlzLm1heENsaWVudHNQZXJPcmcpIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oYFBlci1vcmcgU1NFIGNsaWVudCBjYXAgcmVhY2hlZCBmb3IgJHtvcmdJZH0gKG1heDogJHt0aGlzLm1heENsaWVudHNQZXJPcmd9KWApO1xuICAgICAgICByZXMuc3RhdHVzKDQyOSkuZW5kKCdUb28gbWFueSBTU0UgY29ubmVjdGlvbnMgZm9yIHRoaXMgb3JnYW5pemF0aW9uJyk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgcmVzLnNldEhlYWRlcignQ29udGVudC1UeXBlJywgJ3RleHQvZXZlbnQtc3RyZWFtJyk7XG4gICAgICByZXMuc2V0SGVhZGVyKCdDYWNoZS1Db250cm9sJywgJ25vLWNhY2hlJyk7XG4gICAgICByZXMuc2V0SGVhZGVyKCdDb25uZWN0aW9uJywgJ2tlZXAtYWxpdmUnKTtcbiAgICAgIHJlcy5zZXRIZWFkZXIoJ1gtQWNjZWwtQnVmZmVyaW5nJywgJ25vJyk7IC8vIERpc2FibGUgbmdpbnggYnVmZmVyaW5nXG4gICAgICByZXMuZmx1c2hIZWFkZXJzKCk7XG5cbiAgICAgIC8vIEhlYWRlcnMgYXJlIGZsdXNoZWQg4oCUIHdlIGNhbiBubyBsb25nZXIgc2VuZCBhIDQyOS4gYWRkQ2xpZW50IHJlLWNoZWNrc1xuICAgICAgLy8gdGhlIGNhcHMgKGluY2x1ZGluZyB0aGUgcHJvY2Vzcy13aWRlIHRvdGFsLWNsaWVudHMgY2FwLCB3aGljaCB0aGVcbiAgICAgIC8vIHByZS1mbGlnaHQgYWJvdmUgZG9lcyBub3QpIGFuZCBjYW4gc3RpbGwgcmVqZWN0IG9uIGEgcmFjZTogYSBjb25jdXJyZW50XG4gICAgICAvLyBjb25uZWN0aW9uIG1heSBoYXZlIGZpbGxlZCBhIGNhcCBiZXR3ZWVuIHRoZSBwcmUtZmxpZ2h0IGNoZWNrIGFuZCBoZXJlLlxuICAgICAgLy8gT24gcmVqZWN0aW9uLCBjbG9zZSB0aGUgbm93LWRhbmdsaW5nIHJlc3BvbnNlIGluc3RlYWQgb2YgbGVhdmluZyBhblxuICAgICAgLy8gb3BlbiBzb2NrZXQgd2l0aCBubyBjbGllbnQgcmVjb3JkICh3aGljaCB3b3VsZCBsZWFrIGFuIGZkICsgbmV2ZXIgZW1pdFxuICAgICAgLy8gc3RyZWFtIGRhdGEpLlxuICAgICAgY29uc3QgYWRkZWQgPSB0aGlzLmFkZENsaWVudChyZXF1ZXN0SWQsIHJlcywgb3JnSWQpO1xuICAgICAgaWYgKCFhZGRlZCkge1xuICAgICAgICBsb2dnZXIud2FybihgU1NFIGFkZENsaWVudCByZWplY3RlZCBhZnRlciBoZWFkZXJzIGZsdXNoZWQgZm9yIHJlcXVlc3QgJHtyZXF1ZXN0SWR9OyBjbG9zaW5nIGRhbmdsaW5nIHJlc3BvbnNlYCk7XG4gICAgICAgIHRyeSB7IHJlcy5lbmQoKTsgfSBjYXRjaCB7IC8qIGFscmVhZHkgY2xvc2VkICovIH1cbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFN0YXJ0IHBlcmlvZGljIGNsZWFudXAgb2Ygc3RhbGUgY29ubmVjdGlvbnNcbiAgICovXG4gIHByaXZhdGUgc3RhcnRDbGVhbnVwSW50ZXJ2YWwoaW50ZXJ2YWxNczogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5jbGVhbnVwSW50ZXJ2YWwgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICB0aGlzLmNsZWFudXAoKTtcbiAgICB9LCBpbnRlcnZhbE1zKTtcblxuICAgIC8vIERvbid0IHByZXZlbnQgcHJvY2VzcyBleGl0XG4gICAgdGhpcy5jbGVhbnVwSW50ZXJ2YWwudW5yZWYoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDbGVhbiB1cCBzdGFsZSBjb25uZWN0aW9ucyB1c2luZyBzaW5nbGUtcGFzcyBwYXJ0aXRpb24uXG4gICAqIE8oUiDDlyBDKSBpbnN0ZWFkIG9mIE8oUiDDlyBDwrIpLCBhbmQgYXZvaWRzIG11dGF0aW9uLWR1cmluZy1pdGVyYXRpb24uXG4gICAqL1xuICBwcml2YXRlIGNsZWFudXAoKTogdm9pZCB7XG4gICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKTtcbiAgICBsZXQgY2xlYW5lZCA9IDA7XG5cbiAgICAvLyBTd2VlcCBleHBpcmVkIHRpY2tldHMvb3duZXJzIHNvIGFuIGluLW1lbW9yeSBzdG9yZSBzdGF5cyBib3VuZGVkIGV2ZW4gd2hlblxuICAgIC8vIHRpY2tldHMgYXJlIG1pbnRlZCBidXQgbmV2ZXIgY29uc3VtZWQgKGNsaWVudCBjbG9zZWQgdGhlIHRhYiBiZWZvcmVcbiAgICAvLyBjb25uZWN0aW5nKS4gQ29uc3VtZS10aW1lIHN0aWxsIHJlLWNoZWNrcyBleHBpcnksIHNvIHRoaXMgaXMgbWVtb3J5XG4gICAgLy8gaHlnaWVuZSBvbmx5OyB0aGUgUmVkaXMgc3RvcmUgcmVsaWVzIG9uIG5hdGl2ZSBrZXkgVFRMIChzd2VlcCBpcyBhIG5vLW9wKS5cbiAgICB2b2lkIHRoaXMudGlja2V0U3RvcmUuc3dlZXA/LigpO1xuXG4gICAgZm9yIChjb25zdCBbcmVxdWVzdElkLCBjbGllbnRzXSBvZiB0aGlzLmNsaWVudHMuZW50cmllcygpKSB7XG4gICAgICBjb25zdCBzdGFsZTogU1NFQ2xpZW50W10gPSBbXTtcbiAgICAgIGNvbnN0IGFjdGl2ZTogU1NFQ2xpZW50W10gPSBbXTtcblxuICAgICAgZm9yIChjb25zdCBjbGllbnQgb2YgY2xpZW50cykge1xuICAgICAgICAvLyBUaW1lLWJhc2VkIGV2aWN0aW9uIE9SIGEgc29ja2V0IHRoYXQgc2lsZW50bHkgY2xvc2VkIChubyAnY2xvc2UnXG4gICAgICAgIC8vIGV2ZW50KSDigJQgTm9kZSBzb21ldGltZXMgZHJvcHMgc29ja2V0cyB3aXRob3V0IGZpcmluZyB0aGUgZXZlbnQsXG4gICAgICAgIC8vIHNvIHdlIGV4cGxpY2l0bHkgY2hlY2sgd3JpdGFibGVFbmRlZC9kZXN0cm95ZWQgaGVyZS5cbiAgICAgICAgY29uc3QgYWdlU3RhbGUgPSBub3cgLSBjbGllbnQuY29ubmVjdGVkQXQgPiB0aGlzLmNsaWVudFRpbWVvdXRNcztcbiAgICAgICAgY29uc3Qgc29ja2V0RGVhZCA9IGNsaWVudC5yZXMud3JpdGFibGVFbmRlZCB8fCAoY2xpZW50LnJlcyBhcyB7IGRlc3Ryb3llZD86IGJvb2xlYW4gfSkuZGVzdHJveWVkID09PSB0cnVlO1xuICAgICAgICBpZiAoYWdlU3RhbGUgfHwgc29ja2V0RGVhZCkge1xuICAgICAgICAgIHN0YWxlLnB1c2goY2xpZW50KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBhY3RpdmUucHVzaChjbGllbnQpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGZvciAoY29uc3QgY2xpZW50IG9mIHN0YWxlKSB7XG4gICAgICAgIGNsZWFyVGltZW91dChjbGllbnQudGltZW91dCk7XG4gICAgICAgIHRoaXMuZGVjcmVtZW50T3JnQ291bnQoY2xpZW50Lm9yZ0lkKTtcbiAgICAgICAgdHJ5IHsgY2xpZW50LnJlcy5lbmQoKTsgfSBjYXRjaCB7IC8qIGFscmVhZHkgY2xvc2VkICovIH1cbiAgICAgICAgY2xlYW5lZCsrO1xuICAgICAgfVxuXG4gICAgICBpZiAoYWN0aXZlLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB0aGlzLmNsaWVudHMuZGVsZXRlKHJlcXVlc3RJZCk7XG4gICAgICB9IGVsc2UgaWYgKHN0YWxlLmxlbmd0aCA+IDApIHtcbiAgICAgICAgdGhpcy5jbGllbnRzLnNldChyZXF1ZXN0SWQsIGFjdGl2ZSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGNsZWFuZWQgPiAwKSB7XG4gICAgICBsb2dnZXIuaW5mbyhgQ2xlYW5lZCB1cCAke2NsZWFuZWR9IHN0YWxlIFNTRSBjb25uZWN0aW9uc2ApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBTaHV0ZG93biB0aGUgU1NFIG1hbmFnZXIgYW5kIGNsb3NlIGFsbCBjb25uZWN0aW9uc1xuICAgKi9cbiAgc2h1dGRvd24oKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuY2xlYW51cEludGVydmFsKSB7XG4gICAgICBjbGVhckludGVydmFsKHRoaXMuY2xlYW51cEludGVydmFsKTtcbiAgICAgIHRoaXMuY2xlYW51cEludGVydmFsID0gbnVsbDtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IHJlcXVlc3RJZCBvZiBbLi4udGhpcy5jbGllbnRzLmtleXMoKV0pIHtcbiAgICAgIHRoaXMuY2xvc2VSZXF1ZXN0KHJlcXVlc3RJZCwgJ1NlcnZlciBzaHV0dGluZyBkb3duJyk7XG4gICAgfVxuXG4gICAgbG9nZ2VyLmluZm8oJ1NTRSBNYW5hZ2VyIHNodXQgZG93bicpO1xuICB9XG59XG4iXX0=
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/** A minted ticket's bound identity: owning org + normalized stream subject. */
|
|
2
|
+
export interface SSETicketRecord {
|
|
3
|
+
orgId: string;
|
|
4
|
+
/** Normalized (dashes stripped, lowercased) stream subject id. */
|
|
5
|
+
requestId: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Pluggable backend for SSE log-stream tickets AND stream-ownership.
|
|
9
|
+
*
|
|
10
|
+
* Two concerns share one store because both must be consistent across pods:
|
|
11
|
+
* - **Tickets** — short-lived, single-use, bound to (org, subject). The default
|
|
12
|
+
* in-memory store is correct only single-replica; the Redis store makes the
|
|
13
|
+
* mint (one pod) / redeem (another pod) exchange work behind a load balancer.
|
|
14
|
+
* - **Stream ownership** — which org OWNS a given stream subject. The stream
|
|
15
|
+
* producer (platform, a different service) records this so ticket minting can
|
|
16
|
+
* assert the caller's org owns the subject, closing the cross-tenant attach
|
|
17
|
+
* gap where any org could mint a ticket for a guessed requestId.
|
|
18
|
+
*
|
|
19
|
+
* All methods are async (Redis is async) and best-effort on the failure side per
|
|
20
|
+
* their doc — a store outage must degrade gracefully, never crash the stream.
|
|
21
|
+
*/
|
|
22
|
+
export interface SSETicketStore {
|
|
23
|
+
/** Persist a single-use ticket bound to `record`, expiring after `ttlMs`. */
|
|
24
|
+
put(ticketId: string, record: SSETicketRecord, ttlMs: number): Promise<void>;
|
|
25
|
+
/** Atomically fetch-and-delete a ticket (single-use). Null if absent/expired. */
|
|
26
|
+
consume(ticketId: string): Promise<SSETicketRecord | null>;
|
|
27
|
+
/** Count of live (unexpired) tickets held for an org (per-org cap). */
|
|
28
|
+
countForOrg(orgId: string): Promise<number>;
|
|
29
|
+
/** Count of all live tickets across the store (capacity cap). */
|
|
30
|
+
total(): Promise<number>;
|
|
31
|
+
/** Record the org that OWNS a stream subject (producer-side), TTL `ttlMs`. */
|
|
32
|
+
bindStreamOwner(requestId: string, orgId: string, ttlMs: number): Promise<void>;
|
|
33
|
+
/** The owning org of a stream subject, or null when none is bound. */
|
|
34
|
+
getStreamOwner(requestId: string): Promise<string | null>;
|
|
35
|
+
/** Optional hygiene sweep of expired entries (Redis TTL makes this a no-op). */
|
|
36
|
+
sweep?(): Promise<void>;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* In-memory ticket store — the default. Correct for a single replica only;
|
|
40
|
+
* mirrors the behavior the SSEManager previously implemented inline.
|
|
41
|
+
*/
|
|
42
|
+
export declare function createMemoryTicketStore(): SSETicketStore;
|
|
43
|
+
/**
|
|
44
|
+
* Minimal ioredis surface the Redis ticket store needs. `set` takes the variadic
|
|
45
|
+
* option tail (`EX <s>`); `zadd`/`zremrangebyscore`/`zcard` back the cap counters.
|
|
46
|
+
*/
|
|
47
|
+
export interface RedisTicketClient {
|
|
48
|
+
get(key: string): Promise<string | null>;
|
|
49
|
+
set(key: string, value: string, ...args: (string | number)[]): Promise<string | null>;
|
|
50
|
+
del(...keys: string[]): Promise<number>;
|
|
51
|
+
zadd(key: string, score: number, member: string): Promise<number>;
|
|
52
|
+
zrem(key: string, ...members: string[]): Promise<number>;
|
|
53
|
+
zcard(key: string): Promise<number>;
|
|
54
|
+
zremrangebyscore(key: string, min: number | string, max: number | string): Promise<number>;
|
|
55
|
+
expire(key: string, seconds: number): Promise<number>;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Redis-backed ticket store — required for multi-pod correctness. Tickets are
|
|
59
|
+
* per-key with native TTL; cap counters are ZSETs scored by expiry (pruned on
|
|
60
|
+
* read). Stream ownership is a per-subject key with its own TTL. All reads are
|
|
61
|
+
* fail-safe (null / 0) so a Redis blip never wedges the stream.
|
|
62
|
+
*/
|
|
63
|
+
export declare function createRedisTicketStore(redis: RedisTicketClient): SSETicketStore;
|
|
64
|
+
/**
|
|
65
|
+
* Build a Redis-backed ticket store from the shared env Redis (same wiring as
|
|
66
|
+
* the rate-limiter / audit-spool). Returns null when Redis isn't configured so
|
|
67
|
+
* the caller keeps the in-memory default. Never throws.
|
|
68
|
+
*/
|
|
69
|
+
export declare function createEnvRedisTicketStore(): SSETicketStore | null;
|