@pipeline-builder/api-server 4.1.3 → 4.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -15,7 +15,7 @@ Assembles the standardized HTTP runtime shared by every backend service: a confi
15
15
  ### App factory & lifecycle (`./api`)
16
16
  | Export | Purpose |
17
17
  | --- | --- |
18
- | `createApp` | Configured Express app: CORS, Helmet (strict CSP), gzip/deflate compression, org-keyed rate limiting (shared Redis store when `redisUrl` is set), `/health`, `/ready`, `/warmup`, `/metrics`, and Swagger UI + OpenAPI at `/docs`. Fails fast if `JWT_SECRET` is unset. |
18
+ | `createApp` | Configured Express app: CORS, Helmet (strict CSP), gzip/deflate compression, org-keyed rate limiting (shared Redis store when `redisUrl` is set), `/health`, `/ready`, `/warmup`, `/metrics`, and Swagger UI + OpenAPI at `/docs`. Fails fast if this service's own internal signing key or the public key bundle is unset (`SERVICE_SIGNING_KEY_FILE`/`SERVICE_KEY_BUNDLE_FILE`). |
19
19
  | `startServer`, `runServer` | Server lifecycle with graceful shutdown |
20
20
 
21
21
  ### Middleware (`./api`)
@@ -12,8 +12,6 @@ export interface CreateAppOptions {
12
12
  enableHelmet?: boolean;
13
13
  /** Enable rate limiting (default: true) */
14
14
  enableRateLimit?: boolean;
15
- /** Redis URL for shared rate-limit state (e.g. 'redis://host:6379'). In-memory when omitted. */
16
- redisUrl?: string;
17
15
  /** Enable JSON body parsing (default: true) */
18
16
  enableJsonBody?: boolean;
19
17
  /** JSON body size limit (default: '1mb') */
@@ -31,6 +29,13 @@ export interface CreateAppOptions {
31
29
  urlEncodedLimit?: string;
32
30
  /** Custom SSE manager instance */
33
31
  sseManager?: SSEManager;
32
+ /**
33
+ * Serve the per-request build-log stream: `POST /logs/ticket` +
34
+ * `GET /logs/:requestId`, a log ticket store, the cross-pod relay, and
35
+ * `ctx.log` frames pushed to SSE. Default false — a service without it has no
36
+ * `/logs` routes and `ctx.log` only writes to the logger.
37
+ */
38
+ logStream?: boolean;
34
39
  /** Health check dependency checker — if provided, /health reports dependency status */
35
40
  checkDependencies?: () => Promise<Record<string, 'connected' | 'disconnected' | 'unknown'>>;
36
41
  /** Enable OpenAPI spec at /docs/openapi.json and Swagger UI at /docs (default: true) */
@@ -85,7 +90,7 @@ export interface CreateAppResult {
85
90
  * - Trust proxy settings
86
91
  * - Health check endpoint (/health)
87
92
  * - Metrics endpoint (/metrics)
88
- * - SSE logs endpoint (/logs/:requestId)
93
+ * - SSE logs endpoint (/logs/:requestId) — only with `logStream: true`
89
94
  *
90
95
  * @param options - Configuration options
91
96
  * @returns Configured Express app and SSE manager
@@ -1,6 +1,6 @@
1
1
  // Copyright 2026 Pipeline Builder Contributors
2
2
  // SPDX-License-Identifier: Apache-2.0
3
- import { sendSuccess, sendError, generateOpenApiSpec, ErrorCode, createLogger, verifyServicePrincipal, createHealthRouter, setCounterEmitter, safeCreateRequire, requireAuth, safeEqual, createEnvRedisClient } from '@pipeline-builder/api-core';
3
+ import { sendSuccess, sendError, generateOpenApiSpec, ErrorCode, createLogger, verifyServicePrincipal, createHealthRouter, setCounterEmitter, requireAuth, safeEqual, createEnvSseTicketStore, SSE_TICKET_TTL_MS } from '@pipeline-builder/api-core';
4
4
  import { Config, CoreConstants } from '@pipeline-builder/pipeline-core';
5
5
  import { getConnection } from '@pipeline-builder/pipeline-data';
6
6
  import compression from 'compression';
@@ -13,10 +13,10 @@ import { v7 as uuid } from 'uuid';
13
13
  import { etagMiddleware } from './etag-middleware.js';
14
14
  import { createEnvRedisIdempotencyStore, setIdempotencyStore } from './idempotency-middleware.js';
15
15
  import { metricsMiddleware, metricsHandler, incCounter } from './metrics.js';
16
+ import { createSharedRateLimitStore } from './rate-limit-store.js';
16
17
  import { readinessGuard } from './readiness.js';
17
18
  import { SSEManager, SSE_REQUEST_ID_RE } from '../http/sse-connection-manager.js';
18
19
  import { createEnvRedisSSERelay } from '../http/sse-relay.js';
19
- import { createEnvRedisTicketStore } from '../http/sse-ticket-store.js';
20
20
  // Wire api-core's counter shim to the real prom-client registry. This is
21
21
  // a no-op until incCounter is called for the first time (lazy registration
22
22
  // in metrics.ts), and lets api-core helpers like the quota client record
@@ -33,7 +33,7 @@ setCounterEmitter(incCounter);
33
33
  * - Trust proxy settings
34
34
  * - Health check endpoint (/health)
35
35
  * - Metrics endpoint (/metrics)
36
- * - SSE logs endpoint (/logs/:requestId)
36
+ * - SSE logs endpoint (/logs/:requestId) — only with `logStream: true`
37
37
  *
38
38
  * @param options - Configuration options
39
39
  * @returns Configured Express app and SSE manager
@@ -50,19 +50,27 @@ setCounterEmitter(incCounter);
50
50
  * ```
51
51
  */
52
52
  export function createApp(options = {}) {
53
- const { enableCors = true, enableHelmet = true, enableRateLimit = true, enableJsonBody = true, jsonLimit = '1mb', enableUrlEncoded = true, urlEncodedLimit = '1mb',
54
- // Default SSE manager wired to the shared env Redis ticket/ownership store
55
- // when Redis is configured (multi-pod correctness + cross-service stream
56
- // ownership), else the in-memory default. A caller-supplied `sseManager`
57
- // skips this entirely.
58
- sseManager = new SSEManager({
59
- ticketStore: createEnvRedisTicketStore() ?? undefined,
60
- relay: createEnvRedisSSERelay() ?? undefined,
61
- }), checkDependencies, enableOpenApi = process.env.NODE_ENV !== 'production', openApiOptions, enableCompression = true, warmupHooks = [], idempotencyStore, } = options;
62
- // Fail fast if JWT_SECRET is not configured — prevents silent auth failures at runtime
63
- if (!process.env.JWT_SECRET) {
64
- throw new Error('JWT_SECRET environment variable is required. Set it before starting the server.');
65
- }
53
+ const { enableCors = true, enableHelmet = true, enableRateLimit = true, enableJsonBody = true, jsonLimit = '1mb', enableUrlEncoded = true, urlEncodedLimit = '1mb', logStream = false, checkDependencies, enableOpenApi = process.env.NODE_ENV !== 'production', openApiOptions, enableCompression = true, warmupHooks = [], idempotencyStore, } = options;
54
+ const serviceName = process.env.SERVICE_NAME || 'api';
55
+ // Default SSE manager. The relay (this service's own Redis channel) is built
56
+ // only when something streams: the log stream turns it on here, and an
57
+ // org-keyed channel turns it on when registered (registerSseTicketChannel).
58
+ // The log ticket store exists only with the log stream. A caller-supplied
59
+ // `sseManager` skips this entirely.
60
+ const sseManager = options.sseManager ?? new SSEManager({
61
+ logStream,
62
+ relayFactory: () => createEnvRedisSSERelay(serviceName),
63
+ ...(logStream && {
64
+ ticketStore: createEnvSseTicketStore({
65
+ ttlMs: SSE_TICKET_TTL_MS,
66
+ maxTotal: parseInt(process.env.SSE_MAX_TOTAL_TICKETS || '1000', 10),
67
+ maxPerOrg: parseInt(process.env.SSE_MAX_TICKETS_PER_ORG || '10', 10),
68
+ keyPrefix: `logs:${serviceName}`,
69
+ }),
70
+ }),
71
+ });
72
+ if (logStream)
73
+ sseManager.enableRelay();
66
74
  // Wire the idempotency replay-cache backend used by the post-auth route
67
75
  // factories (createProtectedRoute / createAuthenticatedWithOrgRoute). Prefer
68
76
  // an explicitly injected store; otherwise auto-construct from the shared env
@@ -156,7 +164,7 @@ export function createApp(options = {}) {
156
164
  });
157
165
  // Health check registered before rate limiter so it is never throttled
158
166
  app.use(createHealthRouter({
159
- serviceName: process.env.SERVICE_NAME || 'api',
167
+ serviceName,
160
168
  checkDependencies,
161
169
  }));
162
170
  // Readiness guard — 503s business traffic while the service is NotReady
@@ -226,7 +234,7 @@ export function createApp(options = {}) {
226
234
  customSiteTitle: openApiOptions?.title ?? 'Pipeline Builder API Docs',
227
235
  }));
228
236
  }
229
- // Rate limiting — uses Redis when redisUrl is provided for shared state across instances
237
+ // Rate limiting — shared across replicas via the env Redis when configured
230
238
  if (enableRateLimit) {
231
239
  const rateLimitConfig = Config.get('rateLimit');
232
240
  const rateLimitOptions = {
@@ -247,47 +255,19 @@ export function createApp(options = {}) {
247
255
  // flood a victim org's bucket. ipKeyGenerator normalizes IPv6 to a /64
248
256
  // prefix (also required by express-rate-limit 8.x's validator).
249
257
  keyGenerator: (req) => ipKeyGenerator(req.ip || 'anon', 64),
258
+ // A store failure (Redis down / failing over) must degrade to "not rate
259
+ // limited", never to a 500 on every request of every service.
260
+ passOnStoreError: true,
250
261
  handler: (_req, res) => {
251
262
  sendError(res, 429, 'Too many requests, please try again later.', ErrorCode.RATE_LIMIT_EXCEEDED);
252
263
  },
253
264
  };
254
- // Shared state across instances.
255
- //
256
- // Falls back to the ENV Redis when no explicit `redisUrl` is passed — and
257
- // nothing passes one, so until now every service rate-limited PER POD. With
258
- // an HPA (pipeline scales to 4, billing to 3) the effective ceiling became
259
- // `max × replicas` for any client the load balancer spreads across pods,
260
- // i.e. the DoS control was weakest exactly when load was highest. Every
261
- // other Redis consumer here (idempotency, SSE tickets, token revocation)
262
- // already derives its client from the environment; this now matches them.
263
- //
264
- // `createEnvRedisClient` returns null when no Redis is configured, which
265
- // leaves the per-process memory store — correct for single-replica/local.
266
- const rateLimitRedis = options.redisUrl ?? createEnvRedisClient('rate-limit');
267
- if (rateLimitRedis) {
268
- try {
269
- // ESM has no global `require`; safeCreateRequire loads the optional
270
- // redis deps synchronously here (only when a redisUrl is configured).
271
- // (CJS-bundle safe — see api-core's safe-require.ts.)
272
- const require = safeCreateRequire(import.meta.url);
273
- // eslint-disable-next-line @typescript-eslint/no-require-imports
274
- const { RedisStore } = require('rate-limit-redis');
275
- // eslint-disable-next-line @typescript-eslint/no-require-imports
276
- const Redis = require('ioredis');
277
- // An explicit `redisUrl` still wins; otherwise reuse the env client.
278
- const redisClient = typeof rateLimitRedis === 'string' ? new Redis(rateLimitRedis) : rateLimitRedis;
279
- // ioredis emits 'error' on connection loss; without a listener Node
280
- // treats it as an unhandled 'error' event and CRASHES the process. Log
281
- // and let ioredis auto-reconnect (rate limiting falls back per-store).
282
- redisClient.on('error', (e) => createLogger('rate-limit').warn('Redis rate-limit store error', { error: e instanceof Error ? e.message : String(e) }));
283
- rateLimitOptions.store = new RedisStore({
284
- sendCommand: (...args) => redisClient.call(...args),
285
- });
286
- }
287
- catch {
288
- createLogger('rate-limit').warn('Redis store unavailable, falling back to in-memory rate limiting');
289
- }
290
- }
265
+ // Shared state across replicas (the process-wide rate-limit Redis connection;
266
+ // undefined without Redis → per-process memory store, right for one replica).
267
+ // Namespaced per SERVICE: every service shares one Redis, and the old
268
+ // unprefixed `rl:<ip>` key let one client's traffic to ANY service drain its
269
+ // budget on EVERY service.
270
+ rateLimitOptions.store = createSharedRateLimitStore(`${serviceName}:global`);
291
271
  app.use(rateLimit(rateLimitOptions));
292
272
  }
293
273
  // Express request timeout — uses CoreConstants to share the same default as Lambda handlers
@@ -326,49 +306,51 @@ export function createApp(options = {}) {
326
306
  // here is a permanent no-op (org always undefined → skip). It is instead wired
327
307
  // into the post-auth route chains — see `createProtectedRoute` /
328
308
  // `createAuthenticatedWithOrgRoute` in middleware-factory.ts.
329
- // SSE logs endpoint — ticket-gated (Wave 2b).
330
- // The stream carries per-org build logs, so it must not be world-readable.
331
- // Clients first POST /logs/ticket (JWT-authenticated) to mint a short-lived,
332
- // single-use ticket bound to their org AND to the specific `requestId` stream
333
- // they intend to open, then open the EventSource with ?ticket=<t>. This keeps
334
- // the JWT out of query strings / access logs while enforcing org ownership,
335
- // per-subject authorization, and the per-org connection cap on the stream.
336
- // Mirrors the message-service notifications SSE ticket exchange.
337
- app.post('/logs/ticket', requireAuth, async (req, res) => {
338
- const orgId = req.user?.organizationId?.toLowerCase();
339
- if (!orgId) {
340
- sendError(res, 400, 'Token missing organization', ErrorCode.VALIDATION_ERROR);
341
- return;
342
- }
343
- // The caller must name the stream subject up front so the ticket is bound to
344
- // it. Without this, a ticket could be replayed against ANY requestId the
345
- // org could guess, letting it attach to another org's log stream. Strictly
346
- // format-validated so it can't carry an injection payload into the subject.
347
- const requestId = req.body?.requestId;
348
- if (typeof requestId !== 'string' || !SSE_REQUEST_ID_RE.test(requestId)) {
349
- sendError(res, 400, 'Missing or invalid requestId', ErrorCode.VALIDATION_ERROR);
350
- return;
351
- }
352
- const result = await sseManager.createTicket(orgId, requestId);
353
- if (!result.ok) {
354
- if (result.reason === 'forbidden') {
355
- // The subject is owned by another org — do not confirm it exists; a plain
356
- // 403 is enough and leaks nothing about which requestIds are live.
357
- sendError(res, 403, 'Not authorized for this log stream', ErrorCode.INSUFFICIENT_PERMISSIONS);
309
+ if (logStream) {
310
+ // SSE logs endpoint — ticket-gated (Wave 2b).
311
+ // The stream carries per-org build logs, so it must not be world-readable.
312
+ // Clients first POST /logs/ticket (JWT-authenticated) to mint a short-lived,
313
+ // single-use ticket bound to their org AND to the specific `requestId` stream
314
+ // they intend to open, then open the EventSource with ?ticket=<t>. This keeps
315
+ // the JWT out of query strings / access logs while enforcing org ownership,
316
+ // per-subject authorization, and the per-org connection cap on the stream.
317
+ // Mirrors the message-service notifications SSE ticket exchange.
318
+ app.post('/logs/ticket', requireAuth, async (req, res) => {
319
+ const orgId = req.user?.organizationId?.toLowerCase();
320
+ if (!orgId) {
321
+ sendError(res, 400, 'Token missing organization', ErrorCode.VALIDATION_ERROR);
322
+ return;
358
323
  }
359
- else if (result.reason === 'org-limit') {
360
- sendError(res, 429, 'Too many log stream tickets issued', ErrorCode.QUOTA_EXCEEDED);
324
+ // The caller must name the stream subject up front so the ticket is bound to
325
+ // it. Without this, a ticket could be replayed against ANY requestId the
326
+ // org could guess, letting it attach to another org's log stream. Strictly
327
+ // format-validated so it can't carry an injection payload into the subject.
328
+ const requestId = req.body?.requestId;
329
+ if (typeof requestId !== 'string' || !SSE_REQUEST_ID_RE.test(requestId)) {
330
+ sendError(res, 400, 'Missing or invalid requestId', ErrorCode.VALIDATION_ERROR);
331
+ return;
361
332
  }
362
- else {
363
- sendError(res, 503, 'Log streaming subsystem at capacity', ErrorCode.QUOTA_EXCEEDED);
333
+ const result = await sseManager.createTicket(orgId, requestId);
334
+ if (!result.ok) {
335
+ if (result.reason === 'forbidden') {
336
+ // The subject is owned by another org — do not confirm it exists; a plain
337
+ // 403 is enough and leaks nothing about which requestIds are live.
338
+ sendError(res, 403, 'Not authorized for this log stream', ErrorCode.INSUFFICIENT_PERMISSIONS);
339
+ }
340
+ else if (result.reason === 'org-limit') {
341
+ sendError(res, 429, 'Too many log stream tickets issued', ErrorCode.QUOTA_EXCEEDED);
342
+ }
343
+ else {
344
+ sendError(res, 503, 'Log streaming subsystem at capacity', ErrorCode.QUOTA_EXCEEDED);
345
+ }
346
+ return;
364
347
  }
365
- return;
366
- }
367
- sendSuccess(res, 200, { ticket: result.ticket });
368
- });
369
- // The stream itself resolves + consumes the ticket inside middleware() and
370
- // rejects any anonymous / invalid / expired / already-used ticket with 401.
371
- app.get('/logs/:requestId', sseManager.middleware());
348
+ sendSuccess(res, 200, { ticket: result.ticket });
349
+ });
350
+ // The stream itself resolves + consumes the ticket inside middleware() and
351
+ // rejects any anonymous / invalid / expired / already-used ticket with 401.
352
+ app.get('/logs/:requestId', sseManager.middleware());
353
+ }
372
354
  return { app, sseManager };
373
355
  }
374
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwLWZhY3RvcnkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXBpL2FwcC1mYWN0b3J5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFFdEMsT0FBTyxFQUFFLFdBQVcsRUFBRSxTQUFTLEVBQUUsbUJBQW1CLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxzQkFBc0IsRUFBRSxrQkFBa0IsRUFBRSxpQkFBaUIsRUFBRSxpQkFBaUIsRUFBRSxXQUFXLEVBQUUsU0FBUyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFFbFAsT0FBTyxFQUFFLE1BQU0sRUFBRSxhQUFhLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUN4RSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDaEUsT0FBTyxXQUFXLE1BQU0sYUFBYSxDQUFDO0FBQ3RDLE9BQU8sSUFBSSxNQUFNLE1BQU0sQ0FBQztBQUN4QixPQUFPLE9BQU8sRUFBRSxFQUFnRSxNQUFNLFNBQVMsQ0FBQztBQUNoRyxPQUFPLFNBQVMsRUFBRSxFQUFFLGNBQWMsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQy9ELE9BQU8sTUFBTSxNQUFNLFFBQVEsQ0FBQztBQUM1QixPQUFPLFNBQVMsTUFBTSxvQkFBb0IsQ0FBQztBQUMzQyxPQUFPLEVBQUUsRUFBRSxJQUFJLElBQUksRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNsQyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDdEQsT0FBTyxFQUFFLDhCQUE4QixFQUFFLG1CQUFtQixFQUF5QixNQUFNLDZCQUE2QixDQUFDO0FBQ3pILE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxjQUFjLEVBQUUsVUFBVSxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQzdFLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUNoRCxPQUFPLEVBQUUsVUFBVSxFQUFFLGlCQUFpQixFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFDbEYsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDOUQsT0FBTyxFQUFFLHlCQUF5QixFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFFeEUseUVBQXlFO0FBQ3pFLDJFQUEyRTtBQUMzRSx5RUFBeUU7QUFDekUsbUVBQW1FO0FBQ25FLGlCQUFpQixDQUFDLFVBQVUsQ0FBQyxDQUFDO0FBNEU5Qjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0EwQkc7QUFDSCxNQUFNLFVBQVUsU0FBUyxDQUFDLE9BQU8sR0FBcUIsRUFBRTtJQUN0RCxNQUFNLEVBQ0osVUFBVSxHQUFHLElBQUksRUFDakIsWUFBWSxHQUFHLElBQUksRUFDbkIsZUFBZSxHQUFHLElBQUksRUFDdEIsY0FBYyxHQUFHLElBQUksRUFDckIsU0FBUyxHQUFHLEtBQUssRUFDakIsZ0JBQWdCLEdBQUcsSUFBSSxFQUN2QixlQUFlLEdBQUcsS0FBSztJQUN2QiwyRUFBMkU7SUFDM0UseUVBQXlFO0lBQ3pFLHlFQUF5RTtJQUN6RSx1QkFBdUI7SUFDdkIsVUFBVSxHQUFHLElBQUksVUFBVSxDQUFDO1FBQzFCLFdBQVcsRUFBRSx5QkFBeUIsRUFBRSxJQUFJLFNBQVM7UUFDckQsS0FBSyxFQUFFLHNCQUFzQixFQUFFLElBQUksU0FBUztLQUM3QyxDQUFDLEVBQ0YsaUJBQWlCLEVBQ2pCLGFBQWEsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLFFBQVEsS0FBSyxZQUFZLEVBQ3JELGNBQWMsRUFDZCxpQkFBaUIsR0FBRyxJQUFJLEVBQ3hCLFdBQVcsR0FBRyxFQUFFLEVBQ2hCLGdCQUFnQixHQUNqQixHQUFHLE9BQU8sQ0FBQztJQUVaLHVGQUF1RjtJQUN2RixJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUM1QixNQUFNLElBQUksS0FBSyxDQUFDLGlGQUFpRixDQUFDLENBQUM7SUFDckcsQ0FBQztJQUVELHdFQUF3RTtJQUN4RSw2RUFBNkU7SUFDN0UsNkVBQTZFO0lBQzdFLDRFQUE0RTtJQUM1RSw4RUFBOEU7SUFDOUUsTUFBTSx3QkFBd0IsR0FBRyxnQkFBZ0IsSUFBSSw4QkFBOEIsRUFBRSxDQUFDO0lBQ3RGLElBQUksd0JBQXdCLEVBQUUsQ0FBQztRQUM3QixtQkFBbUIsQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDO0lBQ2hELENBQUM7SUFFRCw2RUFBNkU7SUFDN0UseUVBQXlFO0lBQ3pFLDBFQUEwRTtJQUMxRSwyRUFBMkU7SUFDM0Usa0VBQWtFO0lBQ2xFLDRFQUE0RTtJQUU1RSxNQUFNLFlBQVksR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQzFDLE1BQU0sR0FBRyxHQUFHLE9BQU8sRUFBRSxDQUFDO0lBRXRCLHVCQUF1QjtJQUN2QixFQUFFO0lBQ0YseUVBQXlFO0lBQ3pFLDJFQUEyRTtJQUMzRSx5RUFBeUU7SUFDekUsMEVBQTBFO0lBQzFFLHNEQUFzRDtJQUN0RCxNQUFNLFlBQVksR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLFFBQVEsS0FBSyxZQUFZLENBQUM7SUFDM0QsTUFBTSxlQUFlLEdBQUcsYUFBYSxJQUFJLENBQUMsWUFBWSxDQUFDO0lBQ3ZELElBQUksWUFBWSxFQUFFLENBQUM7UUFDakIsR0FBRyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUM7WUFDYixxQkFBcUIsRUFBRTtnQkFDckIsVUFBVSxFQUFFO29CQUNWLFVBQVUsRUFBRSxDQUFDLFFBQVEsQ0FBQztvQkFDdEIsU0FBUyxFQUFFLGVBQWU7d0JBQ3hCLENBQUMsQ0FBQyxDQUFDLFFBQVEsRUFBRSxpQkFBaUIsRUFBRSxlQUFlLENBQUM7d0JBQ2hELENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQztvQkFDZCxRQUFRLEVBQUUsQ0FBQyxRQUFRLEVBQUUsaUJBQWlCLENBQUM7b0JBQ3ZDLE1BQU0sRUFBRSxDQUFDLFFBQVEsRUFBRSxPQUFPLEVBQUUsT0FBTyxDQUFDO29CQUNwQyxVQUFVLEVBQUUsQ0FBQyxRQUFRLENBQUM7b0JBQ3RCLE9BQU8sRUFBRSxDQUFDLFFBQVEsQ0FBQztvQkFDbkIsU0FBUyxFQUFFLENBQUMsUUFBUSxDQUFDO29CQUNyQixjQUFjLEVBQUUsQ0FBQyxRQUFRLENBQUM7b0JBQzFCLE9BQU8sRUFBRSxDQUFDLFFBQVEsQ0FBQztvQkFDbkIsVUFBVSxFQUFFLENBQUMsUUFBUSxDQUFDO2lCQUN2QjthQUNGO1NBQ0YsQ0FBQyxDQUFDLENBQUM7SUFDTixDQUFDO0lBRUQsSUFBSSxVQUFVLEVBQUUsQ0FBQztRQUNmLEdBQUcsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0lBQ25DLENBQUM7SUFFRCx5REFBeUQ7SUFDekQsSUFBSSxpQkFBaUIsRUFBRSxDQUFDO1FBQ3RCLEdBQUcsQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDO1lBQ2xCLE1BQU0sRUFBRSxDQUFDLEdBQVksRUFBRSxHQUFhLEVBQUUsRUFBRTtnQkFDdEMsdUVBQXVFO2dCQUN2RSx5RUFBeUU7Z0JBQ3pFLDRDQUE0QztnQkFDNUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsTUFBTSxJQUFJLEVBQUUsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxtQkFBbUIsQ0FBQztvQkFBRSxPQUFPLEtBQUssQ0FBQztnQkFDM0UsT0FBTyxXQUFXLENBQUMsTUFBTSxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQztZQUN0QyxDQUFDO1lBQ0QsU0FBUyxFQUFFLGFBQWEsQ0FBQywyQkFBMkI7U0FDckQsQ0FBQyxDQUFDLENBQUM7SUFDTixDQUFDO0lBRUQsK0RBQStEO0lBQy9ELEdBQUcsQ0FBQyxHQUFHLENBQUMsY0FBYyxFQUFFLENBQUMsQ0FBQztJQUUxQixlQUFlO0lBQ2YsSUFBSSxjQUFjLEVBQUUsQ0FBQztRQUNuQixNQUFNLFVBQVUsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRSxDQUFDLENBQUM7UUFDdEQsTUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDLGVBQWUsSUFBSSxFQUFFLENBQUM7UUFDOUMsSUFBSSxPQUFPLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ3ZCLCtFQUErRTtZQUMvRSxvREFBb0Q7WUFDcEQsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDbkgsQ0FBQzthQUFNLENBQUM7WUFDTixHQUFHLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ3RCLENBQUM7SUFDSCxDQUFDO0lBRUQsSUFBSSxnQkFBZ0IsRUFBRSxDQUFDO1FBQ3JCLEdBQUcsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLGVBQWUsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUMxRSxDQUFDO0lBRUQsNkVBQTZFO0lBQzdFLEdBQUcsQ0FBQyxHQUFHLENBQUMsYUFBYSxFQUFFLFlBQVksQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUVoRCx5RUFBeUU7SUFDekUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQVksRUFBRSxHQUFhLEVBQUUsSUFBa0IsRUFBRSxFQUFFO1FBQzFELE1BQU0sR0FBRyxHQUFHLEdBQUcsQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDLENBQUM7UUFDeEMsTUFBTSxTQUFTLEdBQUcsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLElBQUksRUFBRSxDQUFDO1FBQ2hFLEdBQUcsQ0FBQyxTQUFTLEdBQUcsU0FBUyxDQUFDO1FBQzFCLEdBQUcsQ0FBQyxTQUFTLENBQUMsY0FBYyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQ3pDLElBQUksRUFBRSxDQUFDO0lBQ1QsQ0FBQyxDQUFDLENBQUM7SUFFSCx1RUFBdUU7SUFDdkUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxrQkFBa0IsQ0FBQztRQUN6QixXQUFXLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxZQUFZLElBQUksS0FBSztRQUM5QyxpQkFBaUI7S0FDbEIsQ0FBQyxDQUFDLENBQUM7SUFFSix3RUFBd0U7SUFDeEUsMkVBQTJFO0lBQzNFLHdFQUF3RTtJQUN4RSw2RUFBNkU7SUFDN0Usb0VBQW9FO0lBQ3BFLDZFQUE2RTtJQUM3RSxHQUFHLENBQUMsR0FBRyxDQUFDLGNBQWMsRUFBRSxDQUFDLENBQUM7SUFFMUIsMEVBQTBFO0lBQzFFLHdFQUF3RTtJQUN4RSwwRUFBMEU7SUFDMUUsRUFBRTtJQUNGLDZFQUE2RTtJQUM3RSw4RUFBOEU7SUFDOUUseUVBQXlFO0lBQ3pFLHlFQUF5RTtJQUN6RSwrRUFBK0U7SUFDL0Usa0NBQWtDO0lBQ2xDLEdBQUcsQ0FBQyxHQUFHLENBQUMsU0FBUyxFQUFFLEtBQUssRUFBRSxHQUFZLEVBQUUsR0FBYSxFQUFFLEVBQUU7UUFDdkQsSUFBSSxDQUFDLHNCQUFzQixDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDakMsU0FBUyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsV0FBVyxDQUFDLENBQUM7WUFDakMsT0FBTztRQUNULENBQUM7UUFDRCxJQUFJLENBQUM7WUFDSCxNQUFNLE9BQU8sQ0FBQyxHQUFHLENBQUM7Z0JBQ2hCLGFBQWEsRUFBRSxDQUFDLGNBQWMsRUFBRTtnQkFDaEMsR0FBRyxXQUFXLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQzthQUNyQyxDQUFDLENBQUM7WUFDSCxXQUFXLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLFdBQVcsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO1FBQ3JFLENBQUM7UUFBQyxNQUFNLENBQUM7WUFDUCxTQUFTLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxlQUFlLENBQUMsQ0FBQztRQUN2QyxDQUFDO0lBQ0gsQ0FBQyxDQUFDLENBQUM7SUFFSCxxRUFBcUU7SUFDckUsRUFBRTtJQUNGLDhFQUE4RTtJQUM5RSwrRUFBK0U7SUFDL0UsMEVBQTBFO0lBQzFFLHlFQUF5RTtJQUN6RSwrRUFBK0U7SUFDL0Usc0VBQXNFO0lBQ3RFLE1BQU0sWUFBWSxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsb0JBQW9CLENBQUM7SUFDdEQsR0FBRyxDQUFDLEdBQUcsQ0FBQyxVQUFVLEVBQUUsQ0FBQyxHQUFZLEVBQUUsR0FBYSxFQUFFLElBQWtCLEVBQUUsRUFBRTtRQUN0RSxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7WUFDbEIsSUFBSSxFQUFFLENBQUM7WUFDUCxPQUFPO1FBQ1QsQ0FBQztRQUNELE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFDO1FBQ3pDLE1BQU0sU0FBUyxHQUFHLE1BQU0sRUFBRSxVQUFVLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztRQUM5RSx5RUFBeUU7UUFDekUsbUNBQW1DO1FBQ25DLElBQUksQ0FBQyxTQUFTLElBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxFQUFFLFlBQVksQ0FBQyxFQUFFLENBQUM7WUFDdEQsU0FBUyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsV0FBVyxDQUFDLENBQUM7WUFDakMsT0FBTztRQUNULENBQUM7UUFDRCxJQUFJLEVBQUUsQ0FBQztJQUNULENBQUMsRUFBRSxjQUFjLEVBQUUsQ0FBQyxDQUFDO0lBRXJCLCtEQUErRDtJQUMvRCxJQUFJLGFBQWEsRUFBRSxDQUFDO1FBQ2xCLE1BQU0sSUFBSSxHQUFHLG1CQUFtQixDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQ2pELEdBQUcsQ0FBQyxHQUFHLENBQUMsb0JBQW9CLEVBQUUsQ0FBQyxJQUFhLEVBQUUsR0FBYSxFQUFFLEVBQUU7WUFDN0QsR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNqQixDQUFDLENBQUMsQ0FBQztRQUNILEdBQUcsQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFLFNBQVMsQ0FBQyxLQUFLLEVBQUUsU0FBUyxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUU7WUFDdEQsZUFBZSxFQUFFLGNBQWMsRUFBRSxLQUFLLElBQUksMkJBQTJCO1NBQ3RFLENBQUMsQ0FBQyxDQUFDO0lBQ04sQ0FBQztJQUVELHlGQUF5RjtJQUN6RixJQUFJLGVBQWUsRUFBRSxDQUFDO1FBQ3BCLE1BQU0sZUFBZSxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLENBQUM7UUFFaEQsTUFBTSxnQkFBZ0IsR0FBb0M7WUFDeEQsR0FBRyxFQUFFLGVBQWUsQ0FBQyxHQUFHO1lBQ3hCLFFBQVEsRUFBRSxlQUFlLENBQUMsUUFBUTtZQUNsQyxlQUFlLEVBQUUsSUFBSTtZQUNyQixhQUFhLEVBQUUsS0FBSztZQUNwQiwwRUFBMEU7WUFDMUUsMEVBQTBFO1lBQzFFLHNFQUFzRTtZQUN0RSxvRUFBb0U7WUFDcEUsMERBQTBEO1lBQzFELDBCQUEwQjtZQUMxQixJQUFJLEVBQUUsQ0FBQyxHQUFZLEVBQUUsRUFBRSxDQUFDLHNCQUFzQixDQUFDLEdBQUcsQ0FBQztZQUNuRCwyRUFBMkU7WUFDM0UseUVBQXlFO1lBQ3pFLHNFQUFzRTtZQUN0RSx1RUFBdUU7WUFDdkUsZ0VBQWdFO1lBQ2hFLFlBQVksRUFBRSxDQUFDLEdBQVksRUFBRSxFQUFFLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxFQUFFLElBQUksTUFBTSxFQUFFLEVBQUUsQ0FBQztZQUNwRSxPQUFPLEVBQUUsQ0FBQyxJQUFhLEVBQUUsR0FBYSxFQUFFLEVBQUU7Z0JBQ3hDLFNBQVMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLDRDQUE0QyxFQUFFLFNBQVMsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO1lBQ25HLENBQUM7U0FDRixDQUFDO1FBRUYsaUNBQWlDO1FBQ2pDLEVBQUU7UUFDRiwwRUFBMEU7UUFDMUUsNEVBQTRFO1FBQzVFLDJFQUEyRTtRQUMzRSx5RUFBeUU7UUFDekUsd0VBQXdFO1FBQ3hFLHlFQUF5RTtRQUN6RSwwRUFBMEU7UUFDMUUsRUFBRTtRQUNGLHlFQUF5RTtRQUN6RSwwRUFBMEU7UUFDMUUsTUFBTSxjQUFjLEdBQUcsT0FBTyxDQUFDLFFBQVEsSUFBSSxvQkFBb0IsQ0FBaUQsWUFBWSxDQUFDLENBQUM7UUFDOUgsSUFBSSxjQUFjLEVBQUUsQ0FBQztZQUNuQixJQUFJLENBQUM7Z0JBQ0gsb0VBQW9FO2dCQUNwRSxzRUFBc0U7Z0JBQ3RFLHNEQUFzRDtnQkFDdEQsTUFBTSxPQUFPLEdBQUcsaUJBQWlCLENBQUMsT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQ25ELGlFQUFpRTtnQkFDakUsTUFBTSxFQUFFLFVBQVUsRUFBRSxHQUFHLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO2dCQUNuRCxpRUFBaUU7Z0JBQ2pFLE1BQU0sS0FBSyxHQUFHLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQztnQkFDakMscUVBQXFFO2dCQUNyRSxNQUFNLFdBQVcsR0FBRyxPQUFPLGNBQWMsS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLElBQUksS0FBSyxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxjQUFjLENBQUM7Z0JBQ3BHLG9FQUFvRTtnQkFDcEUsdUVBQXVFO2dCQUN2RSx1RUFBdUU7Z0JBQ3ZFLFdBQVcsQ0FBQyxFQUFFLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBVSxFQUFFLEVBQUUsQ0FDckMsWUFBWSxDQUFDLFlBQVksQ0FBQyxDQUFDLElBQUksQ0FBQyw4QkFBOEIsRUFBRSxFQUFFLEtBQUssRUFBRSxDQUFDLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7Z0JBQzFILGdCQUFnQixDQUFDLEtBQUssR0FBRyxJQUFJLFVBQVUsQ0FBQztvQkFDdEMsV0FBVyxFQUFFLENBQUMsR0FBRyxJQUFjLEVBQUUsRUFBRSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUM7aUJBQzlELENBQUMsQ0FBQztZQUNMLENBQUM7WUFBQyxNQUFNLENBQUM7Z0JBQ1AsWUFBWSxDQUFDLFlBQVksQ0FBQyxDQUFDLElBQUksQ0FBQyxrRUFBa0UsQ0FBQyxDQUFDO1lBQ3RHLENBQUM7UUFDSCxDQUFDO1FBRUQsR0FBRyxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDO0lBQ3ZDLENBQUM7SUFFRCw0RkFBNEY7SUFDNUYsTUFBTSxTQUFTLEdBQUcsYUFBYSxDQUFDLGtCQUFrQixDQUFDO0lBQ25ELEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFhLEVBQUUsR0FBYSxFQUFFLElBQWtCLEVBQUUsRUFBRTtRQUMzRCxHQUFHLENBQUMsVUFBVSxDQUFDLFNBQVMsRUFBRSxHQUFHLEVBQUU7WUFDN0IsSUFBSSxDQUFDLEdBQUcsQ0FBQyxXQUFXLEVBQUUsQ0FBQztnQkFDckIsU0FBUyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsaUJBQWlCLENBQUMsQ0FBQztZQUN6QyxDQUFDO1FBQ0gsQ0FBQyxDQUFDLENBQUM7UUFDSCxJQUFJLEVBQUUsQ0FBQztJQUNULENBQUMsQ0FBQyxDQUFDO0lBRUgsMkJBQTJCO0lBQzNCLE1BQU0sY0FBYyxHQUFHLFlBQVksQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO0lBQ3hELEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFZLEVBQUUsR0FBYSxFQUFFLElBQWtCLEVBQUUsRUFBRTtRQUMxRCxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7UUFDekIsR0FBRyxDQUFDLEVBQUUsQ0FBQyxRQUFRLEVBQUUsR0FBRyxFQUFFO1lBQ3BCLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxLQUFLLENBQUM7WUFDcEMsOEVBQThFO1lBQzlFLGtGQUFrRjtZQUNsRixjQUFjLENBQUMsSUFBSSxDQUFDLEdBQUcsR0FBRyxDQUFDLE1BQU0sSUFBSSxHQUFHLENBQUMsSUFBSSxJQUFJLEdBQUcsQ0FBQyxVQUFVLElBQUksUUFBUSxJQUFJLEVBQUU7Z0JBQy9FLE1BQU0sRUFBRSxHQUFHLENBQUMsTUFBTTtnQkFDbEIsSUFBSSxFQUFFLEdBQUcsQ0FBQyxJQUFJO2dCQUNkLFVBQVUsRUFBRSxHQUFHLENBQUMsVUFBVTtnQkFDMUIsVUFBVSxFQUFFLFFBQVE7Z0JBQ3BCLFNBQVMsRUFBRSxHQUFHLENBQUMsU0FBUzthQUN6QixDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztRQUNILElBQUksRUFBRSxDQUFDO0lBQ1QsQ0FBQyxDQUFDLENBQUM7SUFFSCxxRUFBcUU7SUFDckUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxpQkFBaUIsRUFBRSxDQUFDLENBQUM7SUFFN0IsNkVBQTZFO0lBQzdFLCtFQUErRTtJQUMvRSw0RUFBNEU7SUFDNUUsK0VBQStFO0lBQy9FLGlFQUFpRTtJQUNqRSw4REFBOEQ7SUFFOUQsOENBQThDO0lBQzlDLDJFQUEyRTtJQUMzRSw2RUFBNkU7SUFDN0UsOEVBQThFO0lBQzlFLDhFQUE4RTtJQUM5RSw0RUFBNEU7SUFDNUUsMkVBQTJFO0lBQzNFLGlFQUFpRTtJQUNqRSxHQUFHLENBQUMsSUFBSSxDQUFDLGNBQWMsRUFBRSxXQUFXLEVBQUUsS0FBSyxFQUFFLEdBQVksRUFBRSxHQUFhLEVBQUUsRUFBRTtRQUMxRSxNQUFNLEtBQUssR0FBRyxHQUFHLENBQUMsSUFBSSxFQUFFLGNBQWMsRUFBRSxXQUFXLEVBQUUsQ0FBQztRQUN0RCxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDWCxTQUFTLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSw0QkFBNEIsRUFBRSxTQUFTLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztZQUM5RSxPQUFPO1FBQ1QsQ0FBQztRQUNELDZFQUE2RTtRQUM3RSx5RUFBeUU7UUFDekUsMkVBQTJFO1FBQzNFLDRFQUE0RTtRQUM1RSxNQUFNLFNBQVMsR0FBSSxHQUFHLENBQUMsSUFBNEMsRUFBRSxTQUFTLENBQUM7UUFDL0UsSUFBSSxPQUFPLFNBQVMsS0FBSyxRQUFRLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQztZQUN4RSxTQUFTLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSw4QkFBOEIsRUFBRSxTQUFTLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztZQUNoRixPQUFPO1FBQ1QsQ0FBQztRQUNELE1BQU0sTUFBTSxHQUFHLE1BQU0sVUFBVSxDQUFDLFlBQVksQ0FBQyxLQUFLLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFDL0QsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsQ0FBQztZQUNmLElBQUksTUFBTSxDQUFDLE1BQU0sS0FBSyxXQUFXLEVBQUUsQ0FBQztnQkFDbEMsMEVBQTBFO2dCQUMxRSxtRUFBbUU7Z0JBQ25FLFNBQVMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLG9DQUFvQyxFQUFFLFNBQVMsQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDO1lBQ2hHLENBQUM7aUJBQU0sSUFBSSxNQUFNLENBQUMsTUFBTSxLQUFLLFdBQVcsRUFBRSxDQUFDO2dCQUN6QyxTQUFTLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxvQ0FBb0MsRUFBRSxTQUFTLENBQUMsY0FBYyxDQUFDLENBQUM7WUFDdEYsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLFNBQVMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLHFDQUFxQyxFQUFFLFNBQVMsQ0FBQyxjQUFjLENBQUMsQ0FBQztZQUN2RixDQUFDO1lBQ0QsT0FBTztRQUNULENBQUM7UUFDRCxXQUFXLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxFQUFFLE1BQU0sRUFBRSxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQztJQUNuRCxDQUFDLENBQUMsQ0FBQztJQUVILDJFQUEyRTtJQUMzRSw0RUFBNEU7SUFDNUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxrQkFBa0IsRUFBRSxVQUFVLENBQUMsVUFBVSxFQUFFLENBQUMsQ0FBQztJQUVyRCxPQUFPLEVBQUUsR0FBRyxFQUFFLFVBQVUsRUFBRSxDQUFDO0FBQzdCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuaW1wb3J0IHsgc2VuZFN1Y2Nlc3MsIHNlbmRFcnJvciwgZ2VuZXJhdGVPcGVuQXBpU3BlYywgRXJyb3JDb2RlLCBjcmVhdGVMb2dnZXIsIHZlcmlmeVNlcnZpY2VQcmluY2lwYWwsIGNyZWF0ZUhlYWx0aFJvdXRlciwgc2V0Q291bnRlckVtaXR0ZXIsIHNhZmVDcmVhdGVSZXF1aXJlLCByZXF1aXJlQXV0aCwgc2FmZUVxdWFsLCBjcmVhdGVFbnZSZWRpc0NsaWVudCB9IGZyb20gJ0BwaXBlbGluZS1idWlsZGVyL2FwaS1jb3JlJztcbmltcG9ydCB0eXBlIHsgT3BlbkFwaVNwZWNPcHRpb25zIH0gZnJvbSAnQHBpcGVsaW5lLWJ1aWxkZXIvYXBpLWNvcmUnO1xuaW1wb3J0IHsgQ29uZmlnLCBDb3JlQ29uc3RhbnRzIH0gZnJvbSAnQHBpcGVsaW5lLWJ1aWxkZXIvcGlwZWxpbmUtY29yZSc7XG5pbXBvcnQgeyBnZXRDb25uZWN0aW9uIH0gZnJvbSAnQHBpcGVsaW5lLWJ1aWxkZXIvcGlwZWxpbmUtZGF0YSc7XG5pbXBvcnQgY29tcHJlc3Npb24gZnJvbSAnY29tcHJlc3Npb24nO1xuaW1wb3J0IGNvcnMgZnJvbSAnY29ycyc7XG5pbXBvcnQgZXhwcmVzcywgeyB0eXBlIEV4cHJlc3MsIHR5cGUgTmV4dEZ1bmN0aW9uLCB0eXBlIFJlcXVlc3QsIHR5cGUgUmVzcG9uc2UgfSBmcm9tICdleHByZXNzJztcbmltcG9ydCByYXRlTGltaXQsIHsgaXBLZXlHZW5lcmF0b3IgfSBmcm9tICdleHByZXNzLXJhdGUtbGltaXQnO1xuaW1wb3J0IGhlbG1ldCBmcm9tICdoZWxtZXQnO1xuaW1wb3J0IHN3YWdnZXJVaSBmcm9tICdzd2FnZ2VyLXVpLWV4cHJlc3MnO1xuaW1wb3J0IHsgdjcgYXMgdXVpZCB9IGZyb20gJ3V1aWQnO1xuaW1wb3J0IHsgZXRhZ01pZGRsZXdhcmUgfSBmcm9tICcuL2V0YWctbWlkZGxld2FyZS5qcyc7XG5pbXBvcnQgeyBjcmVhdGVFbnZSZWRpc0lkZW1wb3RlbmN5U3RvcmUsIHNldElkZW1wb3RlbmN5U3RvcmUsIHR5cGUgSWRlbXBvdGVuY3lTdG9yZSB9IGZyb20gJy4vaWRlbXBvdGVuY3ktbWlkZGxld2FyZS5qcyc7XG5pbXBvcnQgeyBtZXRyaWNzTWlkZGxld2FyZSwgbWV0cmljc0hhbmRsZXIsIGluY0NvdW50ZXIgfSBmcm9tICcuL21ldHJpY3MuanMnO1xuaW1wb3J0IHsgcmVhZGluZXNzR3VhcmQgfSBmcm9tICcuL3JlYWRpbmVzcy5qcyc7XG5pbXBvcnQgeyBTU0VNYW5hZ2VyLCBTU0VfUkVRVUVTVF9JRF9SRSB9IGZyb20gJy4uL2h0dHAvc3NlLWNvbm5lY3Rpb24tbWFuYWdlci5qcyc7XG5pbXBvcnQgeyBjcmVhdGVFbnZSZWRpc1NTRVJlbGF5IH0gZnJvbSAnLi4vaHR0cC9zc2UtcmVsYXkuanMnO1xuaW1wb3J0IHsgY3JlYXRlRW52UmVkaXNUaWNrZXRTdG9yZSB9IGZyb20gJy4uL2h0dHAvc3NlLXRpY2tldC1zdG9yZS5qcyc7XG5cbi8vIFdpcmUgYXBpLWNvcmUncyBjb3VudGVyIHNoaW0gdG8gdGhlIHJlYWwgcHJvbS1jbGllbnQgcmVnaXN0cnkuIFRoaXMgaXNcbi8vIGEgbm8tb3AgdW50aWwgaW5jQ291bnRlciBpcyBjYWxsZWQgZm9yIHRoZSBmaXJzdCB0aW1lIChsYXp5IHJlZ2lzdHJhdGlvblxuLy8gaW4gbWV0cmljcy50cyksIGFuZCBsZXRzIGFwaS1jb3JlIGhlbHBlcnMgbGlrZSB0aGUgcXVvdGEgY2xpZW50IHJlY29yZFxuLy8gYHF1b3RhX2ZhaWxfb3Blbl90b3RhbGAgd2l0aG91dCB0YWtpbmcgYSBoYXJkIGRlcCBvbiBhcGktc2VydmVyLlxuc2V0Q291bnRlckVtaXR0ZXIoaW5jQ291bnRlcik7XG5cbi8qKlxuICogT3B0aW9ucyBmb3IgY3JlYXRpbmcgYW4gRXhwcmVzcyBhcHBsaWNhdGlvblxuICovXG5leHBvcnQgaW50ZXJmYWNlIENyZWF0ZUFwcE9wdGlvbnMge1xuICAvKiogRW5hYmxlIENPUlMgKGRlZmF1bHQ6IHRydWUpICovXG4gIGVuYWJsZUNvcnM/OiBib29sZWFuO1xuICAvKiogRW5hYmxlIEhlbG1ldCBzZWN1cml0eSBoZWFkZXJzIChkZWZhdWx0OiB0cnVlKSAqL1xuICBlbmFibGVIZWxtZXQ/OiBib29sZWFuO1xuICAvKiogRW5hYmxlIHJhdGUgbGltaXRpbmcgKGRlZmF1bHQ6IHRydWUpICovXG4gIGVuYWJsZVJhdGVMaW1pdD86IGJvb2xlYW47XG4gIC8qKiBSZWRpcyBVUkwgZm9yIHNoYXJlZCByYXRlLWxpbWl0IHN0YXRlIChlLmcuICdyZWRpczovL2hvc3Q6NjM3OScpLiBJbi1tZW1vcnkgd2hlbiBvbWl0dGVkLiAqL1xuICByZWRpc1VybD86IHN0cmluZztcbiAgLyoqIEVuYWJsZSBKU09OIGJvZHkgcGFyc2luZyAoZGVmYXVsdDogdHJ1ZSkgKi9cbiAgZW5hYmxlSnNvbkJvZHk/OiBib29sZWFuO1xuICAvKiogSlNPTiBib2R5IHNpemUgbGltaXQgKGRlZmF1bHQ6ICcxbWInKSAqL1xuICBqc29uTGltaXQ/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBQYXRoIHByZWZpeGVzIHRoZSBnbG9iYWwgSlNPTiBib2R5IHBhcnNlciBtdXN0IE5PVCB0b3VjaCDigJQgZm9yIHJvdXRlcyB0aGF0IG5lZWRcbiAgICogdGhlIHJhdyBib2R5IChlLmcuIGEgU3RyaXBlIHdlYmhvb2sgd2hvc2UgSE1BQyBpcyBjb21wdXRlZCBvdmVyIHRoZSBleGFjdCBieXRlcykuXG4gICAqIFdpdGhvdXQgdGhpcyB0aGUgZ2xvYmFsIHBhcnNlciBjb25zdW1lcyB0aGUgYm9keSBmaXJzdCBhbmQgYSBsYXRlciBgZXhwcmVzcy5yYXcoKWBcbiAgICogb24gdGhlIHNhbWUgcGF0aCBpcyBhIG5vLW9wLCBicmVha2luZyBzaWduYXR1cmUgdmVyaWZpY2F0aW9uLlxuICAgKi9cbiAganNvbkJvZHlFeGNsdWRlPzogc3RyaW5nW107XG4gIC8qKiBFbmFibGUgVVJMLWVuY29kZWQgYm9keSBwYXJzaW5nIChkZWZhdWx0OiB0cnVlKSAqL1xuICBlbmFibGVVcmxFbmNvZGVkPzogYm9vbGVhbjtcbiAgLyoqIFVSTC1lbmNvZGVkIGJvZHkgc2l6ZSBsaW1pdCAoZGVmYXVsdDogJzFtYicpICovXG4gIHVybEVuY29kZWRMaW1pdD86IHN0cmluZztcbiAgLyoqIEN1c3RvbSBTU0UgbWFuYWdlciBpbnN0YW5jZSAqL1xuICBzc2VNYW5hZ2VyPzogU1NFTWFuYWdlcjtcbiAgLyoqIEhlYWx0aCBjaGVjayBkZXBlbmRlbmN5IGNoZWNrZXIg4oCUIGlmIHByb3ZpZGVkLCAvaGVhbHRoIHJlcG9ydHMgZGVwZW5kZW5jeSBzdGF0dXMgKi9cbiAgY2hlY2tEZXBlbmRlbmNpZXM/OiAoKSA9PiBQcm9taXNlPFJlY29yZDxzdHJpbmcsICdjb25uZWN0ZWQnIHwgJ2Rpc2Nvbm5lY3RlZCcgfCAndW5rbm93bic+PjtcbiAgLyoqIEVuYWJsZSBPcGVuQVBJIHNwZWMgYXQgL2RvY3Mvb3BlbmFwaS5qc29uIGFuZCBTd2FnZ2VyIFVJIGF0IC9kb2NzIChkZWZhdWx0OiB0cnVlKSAqL1xuICAvKipcbiAgICogU2VydmUgdGhlIE9wZW5BUEkgc3BlYyBhdCBgL2RvY3Mvb3BlbmFwaS5qc29uYCBhbmQgU3dhZ2dlciBVSSBhdCBgL2RvY3NgLlxuICAgKlxuICAgKiBEZWZhdWx0cyB0byBPRkYgdW5kZXIgYE5PREVfRU5WPXByb2R1Y3Rpb25gOiB0aGUgcm91dGVzIGFyZSByZWdpc3RlcmVkIGFib3ZlXG4gICAqIHRoZSByYXRlIGxpbWl0ZXIgYW5kIHdlcmUgbmV2ZXIgYXV0aC1nYXRlZCwgc28gaW4gcHJvZHVjdGlvbiB0aGV5IHB1Ymxpc2hlZFxuICAgKiB0aGUgZnVsbCByb3V0ZSArIHNjaGVtYSBpbnZlbnRvcnkgb2YgZXZlcnkgc2VydmljZSB0byBhbnlvbmUgd2hvIGNvdWxkIHJlYWNoXG4gICAqIHRoZSBwb3J0LiBPbmx5IHRoZSBDU1Agd2FzIHRpZ2h0ZW5lZCBmb3IgcHJvZHVjdGlvbiBiZWZvcmUsIG5vdCB0aGUgcm91dGUuXG4gICAqIFBhc3MgYHRydWVgIGV4cGxpY2l0bHkgdG8gc2VydmUgdGhlbSBpbiBwcm9kdWN0aW9uIGFueXdheS5cbiAgICovXG4gIGVuYWJsZU9wZW5BcGk/OiBib29sZWFuO1xuICAvKiogT3BlbkFQSSBzcGVjIGN1c3RvbWl6YXRpb24gb3B0aW9ucyAqL1xuICBvcGVuQXBpT3B0aW9ucz86IE9wZW5BcGlTcGVjT3B0aW9ucztcbiAgLyoqIEVuYWJsZSBnemlwL2RlZmxhdGUgcmVzcG9uc2UgY29tcHJlc3Npb24gKGRlZmF1bHQ6IHRydWUpICovXG4gIGVuYWJsZUNvbXByZXNzaW9uPzogYm9vbGVhbjtcbiAgLyoqXG4gICAqIElkZW1wb3RlbmN5IHJlcGxheS1jYWNoZSBiYWNrZW5kIGZvciBrZXllZCBtdXRhdGlvbiByZXRyaWVzLiBXaGVuIG9taXR0ZWQsXG4gICAqIGNyZWF0ZUFwcCBhdXRvLXdpcmVzIHRoZSBzaGFyZWQgZW52IFJlZGlzIHN0b3JlIChtdWx0aS1yZXBsaWNhIGRlZHVwKSBpZlxuICAgKiBSZWRpcyBpcyBjb25maWd1cmVkLCBlbHNlIGtlZXBzIHRoZSBpbi1tZW1vcnkgZGVmYXVsdCAoc2luZ2xlLXJlcGxpY2EpLlxuICAgKiBQYXNzIGFuIGV4cGxpY2l0IHN0b3JlIHRvIGluamVjdCBhIGJlc3Bva2UgYmFja2VuZCAoZS5nLiBhIHNlcnZpY2UncyBvd25cbiAgICogaW9yZWRpcyBjb25uZWN0aW9uKS5cbiAgICovXG4gIGlkZW1wb3RlbmN5U3RvcmU/OiBJZGVtcG90ZW5jeVN0b3JlO1xuICAvKipcbiAgICogRXh0cmEgd2FybXVwIGNhbGxiYWNrcyBpbnZva2VkIGJ5IGBHRVQgL3dhcm11cGAgaW4gYWRkaXRpb24gdG8gdGhlXG4gICAqIGRlZmF1bHQgUG9zdGdyZXMgcGluZy4gVXNlIGZvciBzZXJ2aWNlcyB0aGF0IGRlcGVuZCBvbiBNb25nbywgUmVkaXMsXG4gICAqIFNRUywgZXRjLiDigJQgcHJlLXdhcm1pbmcgb3BlbnMgY29ubmVjdGlvbiBwb29scyBiZWZvcmUgcmVhbCB0cmFmZmljXG4gICAqIGFycml2ZXMuIEVhY2ggY2FsbGJhY2sgc2hvdWxkIHJlc29sdmUgd2hlbiBpdHMgZGVwZW5kZW5jeSBpcyByZWFkeTtcbiAgICogYW55IHJlamVjdGlvbiBjYXVzZXMgL3dhcm11cCB0byByZXR1cm4gNTAzLlxuICAgKi9cbiAgd2FybXVwSG9va3M/OiBBcnJheTwoKSA9PiBQcm9taXNlPHZvaWQ+Pjtcbn1cblxuLyoqXG4gKiBSZXN1bHQgb2YgY3JlYXRpbmcgYW4gRXhwcmVzcyBhcHBsaWNhdGlvblxuICovXG5leHBvcnQgaW50ZXJmYWNlIENyZWF0ZUFwcFJlc3VsdCB7XG4gIC8qKiBDb25maWd1cmVkIEV4cHJlc3MgYXBwbGljYXRpb24gKi9cbiAgYXBwOiBFeHByZXNzO1xuICAvKiogU1NFIG1hbmFnZXIgaW5zdGFuY2UgKi9cbiAgc3NlTWFuYWdlcjogU1NFTWFuYWdlcjtcbn1cblxuLyoqXG4gKiBDcmVhdGUgYW5kIGNvbmZpZ3VyZSBhbiBFeHByZXNzIGFwcGxpY2F0aW9uIHdpdGggY29tbW9uIG1pZGRsZXdhcmVcbiAqXG4gKiBTZXRzIHVwOlxuICogLSBDT1JTIHdpdGggY29uZmlndXJlZCBvcmlnaW5zXG4gKiAtIEhlbG1ldCBzZWN1cml0eSBoZWFkZXJzXG4gKiAtIFJhdGUgbGltaXRpbmdcbiAqIC0gSlNPTiBhbmQgVVJMLWVuY29kZWQgYm9keSBwYXJzaW5nXG4gKiAtIFRydXN0IHByb3h5IHNldHRpbmdzXG4gKiAtIEhlYWx0aCBjaGVjayBlbmRwb2ludCAoL2hlYWx0aClcbiAqIC0gTWV0cmljcyBlbmRwb2ludCAoL21ldHJpY3MpXG4gKiAtIFNTRSBsb2dzIGVuZHBvaW50ICgvbG9ncy86cmVxdWVzdElkKVxuICpcbiAqIEBwYXJhbSBvcHRpb25zIC0gQ29uZmlndXJhdGlvbiBvcHRpb25zXG4gKiBAcmV0dXJucyBDb25maWd1cmVkIEV4cHJlc3MgYXBwIGFuZCBTU0UgbWFuYWdlclxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCB7IGFwcCwgc3NlTWFuYWdlciB9ID0gY3JlYXRlQXBwKCk7XG4gKlxuICogYXBwLnBvc3QoJy9hcGkvcmVzb3VyY2UnLCByZXF1aXJlQXV0aCwgYXN5bmMgKHJlcSwgcmVzKSA9PiB7XG4gKiAgIC8vIFlvdXIgcm91dGUgaGFuZGxlclxuICogfSk7XG4gKlxuICogc3RhcnRTZXJ2ZXIoYXBwLCB7IG5hbWU6ICdNeSBTZXJ2aWNlJyB9KTtcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlQXBwKG9wdGlvbnM6IENyZWF0ZUFwcE9wdGlvbnMgPSB7fSk6IENyZWF0ZUFwcFJlc3VsdCB7XG4gIGNvbnN0IHtcbiAgICBlbmFibGVDb3JzID0gdHJ1ZSxcbiAgICBlbmFibGVIZWxtZXQgPSB0cnVlLFxuICAgIGVuYWJsZVJhdGVMaW1pdCA9IHRydWUsXG4gICAgZW5hYmxlSnNvbkJvZHkgPSB0cnVlLFxuICAgIGpzb25MaW1pdCA9ICcxbWInLFxuICAgIGVuYWJsZVVybEVuY29kZWQgPSB0cnVlLFxuICAgIHVybEVuY29kZWRMaW1pdCA9ICcxbWInLFxuICAgIC8vIERlZmF1bHQgU1NFIG1hbmFnZXIgd2lyZWQgdG8gdGhlIHNoYXJlZCBlbnYgUmVkaXMgdGlja2V0L293bmVyc2hpcCBzdG9yZVxuICAgIC8vIHdoZW4gUmVkaXMgaXMgY29uZmlndXJlZCAobXVsdGktcG9kIGNvcnJlY3RuZXNzICsgY3Jvc3Mtc2VydmljZSBzdHJlYW1cbiAgICAvLyBvd25lcnNoaXApLCBlbHNlIHRoZSBpbi1tZW1vcnkgZGVmYXVsdC4gQSBjYWxsZXItc3VwcGxpZWQgYHNzZU1hbmFnZXJgXG4gICAgLy8gc2tpcHMgdGhpcyBlbnRpcmVseS5cbiAgICBzc2VNYW5hZ2VyID0gbmV3IFNTRU1hbmFnZXIoe1xuICAgICAgdGlja2V0U3RvcmU6IGNyZWF0ZUVudlJlZGlzVGlja2V0U3RvcmUoKSA/PyB1bmRlZmluZWQsXG4gICAgICByZWxheTogY3JlYXRlRW52UmVkaXNTU0VSZWxheSgpID8/IHVuZGVmaW5lZCxcbiAgICB9KSxcbiAgICBjaGVja0RlcGVuZGVuY2llcyxcbiAgICBlbmFibGVPcGVuQXBpID0gcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyxcbiAgICBvcGVuQXBpT3B0aW9ucyxcbiAgICBlbmFibGVDb21wcmVzc2lvbiA9IHRydWUsXG4gICAgd2FybXVwSG9va3MgPSBbXSxcbiAgICBpZGVtcG90ZW5jeVN0b3JlLFxuICB9ID0gb3B0aW9ucztcblxuICAvLyBGYWlsIGZhc3QgaWYgSldUX1NFQ1JFVCBpcyBub3QgY29uZmlndXJlZCDigJQgcHJldmVudHMgc2lsZW50IGF1dGggZmFpbHVyZXMgYXQgcnVudGltZVxuICBpZiAoIXByb2Nlc3MuZW52LkpXVF9TRUNSRVQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0pXVF9TRUNSRVQgZW52aXJvbm1lbnQgdmFyaWFibGUgaXMgcmVxdWlyZWQuIFNldCBpdCBiZWZvcmUgc3RhcnRpbmcgdGhlIHNlcnZlci4nKTtcbiAgfVxuXG4gIC8vIFdpcmUgdGhlIGlkZW1wb3RlbmN5IHJlcGxheS1jYWNoZSBiYWNrZW5kIHVzZWQgYnkgdGhlIHBvc3QtYXV0aCByb3V0ZVxuICAvLyBmYWN0b3JpZXMgKGNyZWF0ZVByb3RlY3RlZFJvdXRlIC8gY3JlYXRlQXV0aGVudGljYXRlZFdpdGhPcmdSb3V0ZSkuIFByZWZlclxuICAvLyBhbiBleHBsaWNpdGx5IGluamVjdGVkIHN0b3JlOyBvdGhlcndpc2UgYXV0by1jb25zdHJ1Y3QgZnJvbSB0aGUgc2hhcmVkIGVudlxuICAvLyBSZWRpcyBzbyBrZXllZCBtdXRhdGlvbiByZXRyaWVzIGRlZHVwZSBhY3Jvc3MgcmVwbGljYXMuIEZhbGxzIGJhY2sgdG8gdGhlXG4gIC8vIGluLW1lbW9yeSBkZWZhdWx0IHdoZW4gbm8gUmVkaXMgaXMgY29uZmlndXJlZCAoc2luZ2xlLXJlcGxpY2EgY29ycmVjdG5lc3MpLlxuICBjb25zdCByZXNvbHZlZElkZW1wb3RlbmN5U3RvcmUgPSBpZGVtcG90ZW5jeVN0b3JlID8/IGNyZWF0ZUVudlJlZGlzSWRlbXBvdGVuY3lTdG9yZSgpO1xuICBpZiAocmVzb2x2ZWRJZGVtcG90ZW5jeVN0b3JlKSB7XG4gICAgc2V0SWRlbXBvdGVuY3lTdG9yZShyZXNvbHZlZElkZW1wb3RlbmN5U3RvcmUpO1xuICB9XG5cbiAgLy8gT3BlblRlbGVtZXRyeSBpcyBOT1QgaW5pdGlhbGl6ZWQgaGVyZTogYnkgdGhlIHRpbWUgY3JlYXRlQXBwIHJ1bnMsIGV4cHJlc3NcbiAgLy8gYW5kIGh0dHAgaGF2ZSBhbHJlYWR5IGJlZW4gcmVxdWlyZWQsIHNvIHRoZSBhdXRvLWluc3RydW1lbnRhdGlvbiBob29rc1xuICAvLyB3b3VsZCBoYXZlIG5vdGhpbmcgdG8gcGF0Y2ggKG5vIGluYm91bmQgc3BhbiDihpIgbm8gdHJhY2UgaWQpLiBUcmFjaW5nIGlzXG4gIC8vIHN0YXJ0ZWQgYnkgdGhlIGBvdGVsLWJvb3RzdHJhcC5qc2AgcHJlbG9hZCBpbnN0ZWFkIChub2RlIC1yIOKApiDigJQgc2VlIGVhY2hcbiAgLy8gc2VydmljZSdzIERvY2tlcmZpbGUgQ01EIC8gc3RhcnQgc2NyaXB0KSwgd2hpY2ggcnVucyBiZWZvcmUgYW55XG4gIC8vIGluc3RydW1lbnRlZCBtb2R1bGUgbG9hZHMuIGBjdXJyZW50VHJhY2VJZCgpYCB0aGVuIHJlYWRzIHRoZSBhY3RpdmUgc3Bhbi5cblxuICBjb25zdCBzZXJ2ZXJDb25maWcgPSBDb25maWcuZ2V0KCdzZXJ2ZXInKTtcbiAgY29uc3QgYXBwID0gZXhwcmVzcygpO1xuXG4gIC8vIFNlY3VyaXR5IG1pZGRsZXdhcmUuXG4gIC8vXG4gIC8vIFN3YWdnZXIgVUkgbmVlZHMgdW5zYWZlLWlubGluZSArIHVuc2FmZS1ldmFsIGZvciBpdHMgYnVuZGxlZCBzY3JpcHRzIOKAlFxuICAvLyBidXQgd2Ugb25seSByZWxheCBDU1AgdGhhdCBmYXIgd2hlbiAoYSkgT3BlbkFQSSBpcyBlbmFibGVkIEFORCAoYikgd2UncmVcbiAgLy8gbm90IGluIHByb2R1Y3Rpb24uIEluIHByb2QsIFN3YWdnZXIgc2hvdWxkIGJlIHNlcnZlZCBiZWhpbmQgYSBzZXBhcmF0ZVxuICAvLyBob3N0IG9yIGF1dGgtZ2F0ZWQgcm91dGU7IHRoZSBtYWluIGFwcCBrZWVwcyB0aGUgc3RyaWN0IENTUCBzbyBhIFN0b3JlZFxuICAvLyBYU1MgaW4gYW55IGhhbmRsZXIgY2FuJ3QgYGV2YWwoKWAgYXJiaXRyYXJ5IHNjcmlwdC5cbiAgY29uc3QgaXNQcm9kdWN0aW9uID0gcHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09ICdwcm9kdWN0aW9uJztcbiAgY29uc3QgYWxsb3dTd2FnZ2VyQ3NwID0gZW5hYmxlT3BlbkFwaSAmJiAhaXNQcm9kdWN0aW9uO1xuICBpZiAoZW5hYmxlSGVsbWV0KSB7XG4gICAgYXBwLnVzZShoZWxtZXQoe1xuICAgICAgY29udGVudFNlY3VyaXR5UG9saWN5OiB7XG4gICAgICAgIGRpcmVjdGl2ZXM6IHtcbiAgICAgICAgICBkZWZhdWx0U3JjOiBbXCInc2VsZidcIl0sXG4gICAgICAgICAgc2NyaXB0U3JjOiBhbGxvd1N3YWdnZXJDc3BcbiAgICAgICAgICAgID8gW1wiJ3NlbGYnXCIsIFwiJ3Vuc2FmZS1pbmxpbmUnXCIsIFwiJ3Vuc2FmZS1ldmFsJ1wiXVxuICAgICAgICAgICAgOiBbXCInc2VsZidcIl0sXG4gICAgICAgICAgc3R5bGVTcmM6IFtcIidzZWxmJ1wiLCBcIid1bnNhZmUtaW5saW5lJ1wiXSxcbiAgICAgICAgICBpbWdTcmM6IFtcIidzZWxmJ1wiLCAnZGF0YTonLCAnYmxvYjonXSxcbiAgICAgICAgICBjb25uZWN0U3JjOiBbXCInc2VsZidcIl0sXG4gICAgICAgICAgZm9udFNyYzogW1wiJ3NlbGYnXCJdLFxuICAgICAgICAgIG9iamVjdFNyYzogW1wiJ25vbmUnXCJdLFxuICAgICAgICAgIGZyYW1lQW5jZXN0b3JzOiBbXCInbm9uZSdcIl0sXG4gICAgICAgICAgYmFzZVVyaTogW1wiJ3NlbGYnXCJdLFxuICAgICAgICAgIGZvcm1BY3Rpb246IFtcIidzZWxmJ1wiXSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfSkpO1xuICB9XG5cbiAgaWYgKGVuYWJsZUNvcnMpIHtcbiAgICBhcHAudXNlKGNvcnMoc2VydmVyQ29uZmlnLmNvcnMpKTtcbiAgfVxuXG4gIC8vIFJlc3BvbnNlIGNvbXByZXNzaW9uIChnemlwL2RlZmxhdGUpIOKAlCBza2lwIFNTRSBzdHJlYW1zXG4gIGlmIChlbmFibGVDb21wcmVzc2lvbikge1xuICAgIGFwcC51c2UoY29tcHJlc3Npb24oe1xuICAgICAgZmlsdGVyOiAocmVxOiBSZXF1ZXN0LCByZXM6IFJlc3BvbnNlKSA9PiB7XG4gICAgICAgIC8vIERvbid0IGNvbXByZXNzIFNTRSBzdHJlYW1zLiBNYXRjaCBieSBpbmNsdXNpb246IHRoZSBBY2NlcHQgaGVhZGVyIGlzXG4gICAgICAgIC8vIG9mdGVuIGEgbGlzdCAoZS5nLiBcInRleHQvZXZlbnQtc3RyZWFtLCAqLypcIiksIHNvIGV4YWN0IGVxdWFsaXR5IG1pc3NlZFxuICAgICAgICAvLyB0aG9zZSBhbmQgY29tcHJlc3NlZC9idWZmZXJlZCB0aGUgc3RyZWFtLlxuICAgICAgICBpZiAoKHJlcS5oZWFkZXJzLmFjY2VwdCB8fCAnJykuaW5jbHVkZXMoJ3RleHQvZXZlbnQtc3RyZWFtJykpIHJldHVybiBmYWxzZTtcbiAgICAgICAgcmV0dXJuIGNvbXByZXNzaW9uLmZpbHRlcihyZXEsIHJlcyk7XG4gICAgICB9LFxuICAgICAgdGhyZXNob2xkOiBDb3JlQ29uc3RhbnRzLkNPTVBSRVNTSU9OX1RIUkVTSE9MRF9CWVRFUyxcbiAgICB9KSk7XG4gIH1cblxuICAvLyBFVGFnIHN1cHBvcnQgZm9yIGNvbmRpdGlvbmFsIEdFVCByZXF1ZXN0cyAoMzA0IE5vdCBNb2RpZmllZClcbiAgYXBwLnVzZShldGFnTWlkZGxld2FyZSgpKTtcblxuICAvLyBCb2R5IHBhcnNpbmdcbiAgaWYgKGVuYWJsZUpzb25Cb2R5KSB7XG4gICAgY29uc3QganNvblBhcnNlciA9IGV4cHJlc3MuanNvbih7IGxpbWl0OiBqc29uTGltaXQgfSk7XG4gICAgY29uc3QgZXhjbHVkZSA9IG9wdGlvbnMuanNvbkJvZHlFeGNsdWRlID8/IFtdO1xuICAgIGlmIChleGNsdWRlLmxlbmd0aCA+IDApIHtcbiAgICAgIC8vIFNraXAgdGhlIGdsb2JhbCBKU09OIHBhcnNlciBmb3IgcmF3LWJvZHkgcGF0aHMgc28gYSBwZXItcGF0aCBgZXhwcmVzcy5yYXcoKWBcbiAgICAgIC8vIGNhbiByZWFkIHRoZSBleGFjdCBieXRlcyAoc2VlIGBqc29uQm9keUV4Y2x1ZGVgKS5cbiAgICAgIGFwcC51c2UoKHJlcSwgcmVzLCBuZXh0KSA9PiAoZXhjbHVkZS5zb21lKChwKSA9PiByZXEucGF0aC5zdGFydHNXaXRoKHApKSA/IG5leHQoKSA6IGpzb25QYXJzZXIocmVxLCByZXMsIG5leHQpKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGFwcC51c2UoanNvblBhcnNlcik7XG4gICAgfVxuICB9XG5cbiAgaWYgKGVuYWJsZVVybEVuY29kZWQpIHtcbiAgICBhcHAudXNlKGV4cHJlc3MudXJsZW5jb2RlZCh7IGV4dGVuZGVkOiB0cnVlLCBsaW1pdDogdXJsRW5jb2RlZExpbWl0IH0pKTtcbiAgfVxuXG4gIC8vIFRydXN0IHByb3h5IChtdXN0IGJlIHNldCBiZWZvcmUgcmF0ZSBsaW1pdGVyIHNvIHJlcS5pcCByZXNvbHZlcyBjb3JyZWN0bHkpXG4gIGFwcC5zZXQoJ3RydXN0IHByb3h5Jywgc2VydmVyQ29uZmlnLnRydXN0UHJveHkpO1xuXG4gIC8vIFJlcXVlc3QgSUQg4oCUIHByZWZlciBleGlzdGluZyBoZWFkZXIgZnJvbSBuZ2lueCwgb3RoZXJ3aXNlIGdlbmVyYXRlIG9uZVxuICBhcHAudXNlKChyZXE6IFJlcXVlc3QsIHJlczogUmVzcG9uc2UsIG5leHQ6IE5leHRGdW5jdGlvbikgPT4ge1xuICAgIGNvbnN0IGhkciA9IHJlcS5oZWFkZXJzWyd4LXJlcXVlc3QtaWQnXTtcbiAgICBjb25zdCByZXF1ZXN0SWQgPSAoQXJyYXkuaXNBcnJheShoZHIpID8gaGRyWzBdIDogaGRyKSB8fCB1dWlkKCk7XG4gICAgcmVxLnJlcXVlc3RJZCA9IHJlcXVlc3RJZDtcbiAgICByZXMuc2V0SGVhZGVyKCdYLVJlcXVlc3QtSWQnLCByZXF1ZXN0SWQpO1xuICAgIG5leHQoKTtcbiAgfSk7XG5cbiAgLy8gSGVhbHRoIGNoZWNrIHJlZ2lzdGVyZWQgYmVmb3JlIHJhdGUgbGltaXRlciBzbyBpdCBpcyBuZXZlciB0aHJvdHRsZWRcbiAgYXBwLnVzZShjcmVhdGVIZWFsdGhSb3V0ZXIoe1xuICAgIHNlcnZpY2VOYW1lOiBwcm9jZXNzLmVudi5TRVJWSUNFX05BTUUgfHwgJ2FwaScsXG4gICAgY2hlY2tEZXBlbmRlbmNpZXMsXG4gIH0pKTtcblxuICAvLyBSZWFkaW5lc3MgZ3VhcmQg4oCUIDUwM3MgYnVzaW5lc3MgdHJhZmZpYyB3aGlsZSB0aGUgc2VydmljZSBpcyBOb3RSZWFkeVxuICAvLyAoZGF0YXN0b3JlIHN0aWxsIGNvbm5lY3RpbmcgYXQgc3RhcnR1cCwgb3IgZHJvcHBlZCkuIE1vdW50ZWQgcmlnaHQgYWZ0ZXJcbiAgLy8gdGhlIGhlYWx0aCByb3V0ZXIgYW5kIGJlZm9yZSBldmVyeXRoaW5nIGVsc2Ugc28gYSBOb3RSZWFkeSByZXF1ZXN0IGlzXG4gIC8vIHJlamVjdGVkIGNoZWFwbHksIGJlZm9yZSByYXRlLWxpbWl0IC8gaWRlbXBvdGVuY3kgLyBidXNpbmVzcyBoYW5kbGVycyBldmVyXG4gIC8vIHRvdWNoIGEgZGlzY29ubmVjdGVkIGRhdGFzdG9yZS4gSXQgYWxsb3dsaXN0cyB0aGUgaW5mcmEgZW5kcG9pbnRzXG4gIC8vICgvbWV0cmljcywgL3dhcm11cCwgL2RvY3MsIC9sb2dzKSByZWdpc3RlcmVkIGJlbG93LCBwbHVzIC9oZWFsdGggKyAvcmVhZHkuXG4gIGFwcC51c2UocmVhZGluZXNzR3VhcmQoKSk7XG5cbiAgLy8gV2FybS11cCBlbmRwb2ludCDigJQgcHJlLW9wZW5zIGNvbm5lY3Rpb24gcG9vbHMgc28gdGhlIGZpcnN0IHJlYWwgcmVxdWVzdFxuICAvLyBkb2Vzbid0IHBheSBjb2xkLXN0YXJ0IGxhdGVuY3kuIEFsd2F5cyBwaW5ncyBQb3N0Z3Jlczsgc2VydmljZXMgdXNpbmdcbiAgLy8gTW9uZ28gLyBSZWRpcyAvIFNRUyBwYXNzIGB3YXJtdXBIb29rc2Agc28gdGhvc2UgYXJlIHdhcm1lZCBpbiBwYXJhbGxlbC5cbiAgLy9cbiAgLy8gR0FURUQgdG8gdmVyaWZpZWQgc2VydmljZSBwcmluY2lwYWxzLiBFdmVyeSBoaXQgcnVucyBhIFBvc3RncmVzIHJvdW5kLXRyaXBcbiAgLy8gcGx1cyBhbGwgYHdhcm11cEhvb2tzYCAoTW9uZ28vUmVkaXMvU1FTKSwgc28gd2hpbGUgaXQgd2FzIG9wZW4gYW4gYW5vbnltb3VzXG4gIC8vIGxvb3AgYW1wbGlmaWVkIGludG8gZGF0YXN0b3JlIGxvYWQgb24gZXZlcnkgc2VydmljZSBpbiB0aGUgZmxlZXQg4oCUIGFuZFxuICAvLyBiZWNhdXNlIGl0IGlzIHJlZ2lzdGVyZWQgYWJvdmUgdGhlIHJhdGUgbGltaXRlciwgbm90aGluZyB0aHJvdHRsZWQgaXQuXG4gIC8vIGB2ZXJpZnlTZXJ2aWNlUHJpbmNpcGFsYCBjaGVja3MgdGhlIGJlYXJlciB0b2tlbiBjcnlwdG9ncmFwaGljYWxseSwgc28gaXQgaXNcbiAgLy8gc2FmZSBoZXJlLCBhYm92ZSBgcmVxdWlyZUF1dGhgLlxuICBhcHAuZ2V0KCcvd2FybXVwJywgYXN5bmMgKHJlcTogUmVxdWVzdCwgcmVzOiBSZXNwb25zZSkgPT4ge1xuICAgIGlmICghdmVyaWZ5U2VydmljZVByaW5jaXBhbChyZXEpKSB7XG4gICAgICBzZW5kRXJyb3IocmVzLCA0MDQsICdOb3QgZm91bmQnKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IFByb21pc2UuYWxsKFtcbiAgICAgICAgZ2V0Q29ubmVjdGlvbigpLnRlc3RDb25uZWN0aW9uKCksXG4gICAgICAgIC4uLndhcm11cEhvb2tzLm1hcCgoaG9vaykgPT4gaG9vaygpKSxcbiAgICAgIF0pO1xuICAgICAgc2VuZFN1Y2Nlc3MocmVzLCAyMDAsIHsgd2FybWVkOiB0cnVlLCBob29rczogd2FybXVwSG9va3MubGVuZ3RoIH0pO1xuICAgIH0gY2F0Y2gge1xuICAgICAgc2VuZEVycm9yKHJlcywgNTAzLCAnV2FybXVwIGZhaWxlZCcpO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gUHJvbWV0aGV1cyBtZXRyaWNzIGVuZHBvaW50IOKAlCBhbHdheXMgcmVnaXN0ZXJlZCAobmV2ZXIgdGhyb3R0bGVkKS5cbiAgLy9cbiAgLy8gT3B0aW9uYWxseSBnYXRlZDogd2hlbiBgTUVUUklDU19TQ1JBUEVfVE9LRU5gIGlzIHNldCwgdGhlIHNjcmFwZXIgbXVzdCBzZW5kXG4gIC8vIGl0IGFzIGEgYmVhcmVyIHRva2VuIChQcm9tZXRoZXVzIGBiZWFyZXJfdG9rZW5gIC8gYGJlYXJlcl90b2tlbl9maWxlYCBpbiB0aGVcbiAgLy8gc2NyYXBlIGNvbmZpZykuIExlZnQgdW5nYXRlZCB3aGVuIHVuc2V0IHNvIGVuYWJsaW5nIGl0IGlzIGEgZGVsaWJlcmF0ZSxcbiAgLy8gY29vcmRpbmF0ZWQgY2hhbmdlIHJhdGhlciB0aGFuIGEgc2lsZW50IG1vbml0b3Jpbmcgb3V0YWdlIOKAlCB0aGUgdGVuYW50XG4gIC8vIGRpc2Nsb3N1cmUgdGhhdCBtYWRlIGdhdGluZyB1cmdlbnQgaXMgY2xvc2VkIGluZGVwZW5kZW50bHkgYnkgZGVmYXVsdGluZyB0aGVcbiAgLy8gcGVyLW9yZyBsYWJlbCBPRkYgKHNlZSBIVFRQX01FVFJJQ1NfT1JHX1NBTVBMRV9SQVRFIGluIG1ldHJpY3MudHMpLlxuICBjb25zdCBtZXRyaWNzVG9rZW4gPSBwcm9jZXNzLmVudi5NRVRSSUNTX1NDUkFQRV9UT0tFTjtcbiAgYXBwLmdldCgnL21ldHJpY3MnLCAocmVxOiBSZXF1ZXN0LCByZXM6IFJlc3BvbnNlLCBuZXh0OiBOZXh0RnVuY3Rpb24pID0+IHtcbiAgICBpZiAoIW1ldHJpY3NUb2tlbikge1xuICAgICAgbmV4dCgpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBoZWFkZXIgPSByZXEuaGVhZGVycy5hdXRob3JpemF0aW9uO1xuICAgIGNvbnN0IHByZXNlbnRlZCA9IGhlYWRlcj8uc3RhcnRzV2l0aCgnQmVhcmVyICcpID8gaGVhZGVyLnNsaWNlKDcpIDogdW5kZWZpbmVkO1xuICAgIC8vIENvbnN0YW50LXRpbWUgY29tcGFyZSDigJQgYSBsZW5ndGgtaW5kZXBlbmRlbnQgZXF1YWxpdHkgY2hlY2sgaGVyZSB3b3VsZFxuICAgIC8vIGxlYWsgdGhlIHRva2VuIGEgYnl0ZSBhdCBhIHRpbWUuXG4gICAgaWYgKCFwcmVzZW50ZWQgfHwgIXNhZmVFcXVhbChwcmVzZW50ZWQsIG1ldHJpY3NUb2tlbikpIHtcbiAgICAgIHNlbmRFcnJvcihyZXMsIDQwNCwgJ05vdCBmb3VuZCcpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBuZXh0KCk7XG4gIH0sIG1ldHJpY3NIYW5kbGVyKCkpO1xuXG4gIC8vIE9wZW5BUEkgc3BlYyBhbmQgU3dhZ2dlciBVSSAocmVnaXN0ZXJlZCBiZWZvcmUgcmF0ZSBsaW1pdGVyKVxuICBpZiAoZW5hYmxlT3BlbkFwaSkge1xuICAgIGNvbnN0IHNwZWMgPSBnZW5lcmF0ZU9wZW5BcGlTcGVjKG9wZW5BcGlPcHRpb25zKTtcbiAgICBhcHAuZ2V0KCcvZG9jcy9vcGVuYXBpLmpzb24nLCAoX3JlcTogUmVxdWVzdCwgcmVzOiBSZXNwb25zZSkgPT4ge1xuICAgICAgcmVzLmpzb24oc3BlYyk7XG4gICAgfSk7XG4gICAgYXBwLnVzZSgnL2RvY3MnLCBzd2FnZ2VyVWkuc2VydmUsIHN3YWdnZXJVaS5zZXR1cChzcGVjLCB7XG4gICAgICBjdXN0b21TaXRlVGl0bGU6IG9wZW5BcGlPcHRpb25zPy50aXRsZSA/PyAnUGlwZWxpbmUgQnVpbGRlciBBUEkgRG9jcycsXG4gICAgfSkpO1xuICB9XG5cbiAgLy8gUmF0ZSBsaW1pdGluZyDigJQgdXNlcyBSZWRpcyB3aGVuIHJlZGlzVXJsIGlzIHByb3ZpZGVkIGZvciBzaGFyZWQgc3RhdGUgYWNyb3NzIGluc3RhbmNlc1xuICBpZiAoZW5hYmxlUmF0ZUxpbWl0KSB7XG4gICAgY29uc3QgcmF0ZUxpbWl0Q29uZmlnID0gQ29uZmlnLmdldCgncmF0ZUxpbWl0Jyk7XG5cbiAgICBjb25zdCByYXRlTGltaXRPcHRpb25zOiBQYXJhbWV0ZXJzPHR5cGVvZiByYXRlTGltaXQ+WzBdID0ge1xuICAgICAgbWF4OiByYXRlTGltaXRDb25maWcubWF4LFxuICAgICAgd2luZG93TXM6IHJhdGVMaW1pdENvbmZpZy53aW5kb3dNcyxcbiAgICAgIHN0YW5kYXJkSGVhZGVyczogdHJ1ZSxcbiAgICAgIGxlZ2FjeUhlYWRlcnM6IGZhbHNlLFxuICAgICAgLy8gU2tpcCByYXRlIGxpbWl0aW5nIG9ubHkgZm9yIENSWVBUT0dSQVBISUNBTExZLVZFUklGSUVEIGludGVybmFsIHNlcnZpY2VcbiAgICAgIC8vIGNhbGxlcnMuIFRoZSBsaW1pdGVyIHJ1bnMgYmVmb3JlIHJlcXVpcmVBdXRoLCBzbyB0aGUgcHJldmlvdXNseS10cnVzdGVkXG4gICAgICAvLyBwbGFpbnRleHQgYHgtaW50ZXJuYWwtc2VydmljZWAgaGVhZGVyIHdhcyBzcG9vZmFibGUgYnkgYW55IGV4dGVybmFsXG4gICAgICAvLyBjbGllbnQg4oaSIHRvdGFsIGJ5cGFzcy4gdmVyaWZ5U2VydmljZVByaW5jaXBhbCB2ZXJpZmllcyB0aGUgc2lnbmVkXG4gICAgICAvLyBzZXJ2aWNlIEpXVCBpbnN0ZWFkOyBpbnRlci1zZXJ2aWNlIGNhbGxlcnMgYWxsIHNlbmQgb25lXG4gICAgICAvLyAoZ2V0U2VydmljZUF1dGhIZWFkZXIpLlxuICAgICAgc2tpcDogKHJlcTogUmVxdWVzdCkgPT4gdmVyaWZ5U2VydmljZVByaW5jaXBhbChyZXEpLFxuICAgICAgLy8gS2V5IG9uIGNsaWVudCBJUCBvbmx5LiBUaGUgbGltaXRlciBydW5zIHByZS1hdXRoLCBzbyBgcmVxLnVzZXJgIGlzIHVuc2V0XG4gICAgICAvLyBhbmQgYW55IG9yZyBpZCB3b3VsZCBjb21lIGZyb20gdGhlIGNhbGxlci1zdXBwbGllZCBgeC1vcmctaWRgIGhlYWRlciDigJRcbiAgICAgIC8vIHNwb29mYWJsZSwgbGV0dGluZyBhbiBhdHRhY2tlciByb3RhdGUgdmFsdWVzIHRvIGV2YWRlIHRoZSBidWNrZXQgb3JcbiAgICAgIC8vIGZsb29kIGEgdmljdGltIG9yZydzIGJ1Y2tldC4gaXBLZXlHZW5lcmF0b3Igbm9ybWFsaXplcyBJUHY2IHRvIGEgLzY0XG4gICAgICAvLyBwcmVmaXggKGFsc28gcmVxdWlyZWQgYnkgZXhwcmVzcy1yYXRlLWxpbWl0IDgueCdzIHZhbGlkYXRvcikuXG4gICAgICBrZXlHZW5lcmF0b3I6IChyZXE6IFJlcXVlc3QpID0+IGlwS2V5R2VuZXJhdG9yKHJlcS5pcCB8fCAnYW5vbicsIDY0KSxcbiAgICAgIGhhbmRsZXI6IChfcmVxOiBSZXF1ZXN0LCByZXM6IFJlc3BvbnNlKSA9PiB7XG4gICAgICAgIHNlbmRFcnJvcihyZXMsIDQyOSwgJ1RvbyBtYW55IHJlcXVlc3RzLCBwbGVhc2UgdHJ5IGFnYWluIGxhdGVyLicsIEVycm9yQ29kZS5SQVRFX0xJTUlUX0VYQ0VFREVEKTtcbiAgICAgIH0sXG4gICAgfTtcblxuICAgIC8vIFNoYXJlZCBzdGF0ZSBhY3Jvc3MgaW5zdGFuY2VzLlxuICAgIC8vXG4gICAgLy8gRmFsbHMgYmFjayB0byB0aGUgRU5WIFJlZGlzIHdoZW4gbm8gZXhwbGljaXQgYHJlZGlzVXJsYCBpcyBwYXNzZWQg4oCUIGFuZFxuICAgIC8vIG5vdGhpbmcgcGFzc2VzIG9uZSwgc28gdW50aWwgbm93IGV2ZXJ5IHNlcnZpY2UgcmF0ZS1saW1pdGVkIFBFUiBQT0QuIFdpdGhcbiAgICAvLyBhbiBIUEEgKHBpcGVsaW5lIHNjYWxlcyB0byA0LCBiaWxsaW5nIHRvIDMpIHRoZSBlZmZlY3RpdmUgY2VpbGluZyBiZWNhbWVcbiAgICAvLyBgbWF4IMOXIHJlcGxpY2FzYCBmb3IgYW55IGNsaWVudCB0aGUgbG9hZCBiYWxhbmNlciBzcHJlYWRzIGFjcm9zcyBwb2RzLFxuICAgIC8vIGkuZS4gdGhlIERvUyBjb250cm9sIHdhcyB3ZWFrZXN0IGV4YWN0bHkgd2hlbiBsb2FkIHdhcyBoaWdoZXN0LiBFdmVyeVxuICAgIC8vIG90aGVyIFJlZGlzIGNvbnN1bWVyIGhlcmUgKGlkZW1wb3RlbmN5LCBTU0UgdGlja2V0cywgdG9rZW4gcmV2b2NhdGlvbilcbiAgICAvLyBhbHJlYWR5IGRlcml2ZXMgaXRzIGNsaWVudCBmcm9tIHRoZSBlbnZpcm9ubWVudDsgdGhpcyBub3cgbWF0Y2hlcyB0aGVtLlxuICAgIC8vXG4gICAgLy8gYGNyZWF0ZUVudlJlZGlzQ2xpZW50YCByZXR1cm5zIG51bGwgd2hlbiBubyBSZWRpcyBpcyBjb25maWd1cmVkLCB3aGljaFxuICAgIC8vIGxlYXZlcyB0aGUgcGVyLXByb2Nlc3MgbWVtb3J5IHN0b3JlIOKAlCBjb3JyZWN0IGZvciBzaW5nbGUtcmVwbGljYS9sb2NhbC5cbiAgICBjb25zdCByYXRlTGltaXRSZWRpcyA9IG9wdGlvbnMucmVkaXNVcmwgPz8gY3JlYXRlRW52UmVkaXNDbGllbnQ8eyBjYWxsOiAoLi4uYTogc3RyaW5nW10pID0+IFByb21pc2U8dW5rbm93bj4gfT4oJ3JhdGUtbGltaXQnKTtcbiAgICBpZiAocmF0ZUxpbWl0UmVkaXMpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIC8vIEVTTSBoYXMgbm8gZ2xvYmFsIGByZXF1aXJlYDsgc2FmZUNyZWF0ZVJlcXVpcmUgbG9hZHMgdGhlIG9wdGlvbmFsXG4gICAgICAgIC8vIHJlZGlzIGRlcHMgc3luY2hyb25vdXNseSBoZXJlIChvbmx5IHdoZW4gYSByZWRpc1VybCBpcyBjb25maWd1cmVkKS5cbiAgICAgICAgLy8gKENKUy1idW5kbGUgc2FmZSDigJQgc2VlIGFwaS1jb3JlJ3Mgc2FmZS1yZXF1aXJlLnRzLilcbiAgICAgICAgY29uc3QgcmVxdWlyZSA9IHNhZmVDcmVhdGVSZXF1aXJlKGltcG9ydC5tZXRhLnVybCk7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tcmVxdWlyZS1pbXBvcnRzXG4gICAgICAgIGNvbnN0IHsgUmVkaXNTdG9yZSB9ID0gcmVxdWlyZSgncmF0ZS1saW1pdC1yZWRpcycpO1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXJlcXVpcmUtaW1wb3J0c1xuICAgICAgICBjb25zdCBSZWRpcyA9IHJlcXVpcmUoJ2lvcmVkaXMnKTtcbiAgICAgICAgLy8gQW4gZXhwbGljaXQgYHJlZGlzVXJsYCBzdGlsbCB3aW5zOyBvdGhlcndpc2UgcmV1c2UgdGhlIGVudiBjbGllbnQuXG4gICAgICAgIGNvbnN0IHJlZGlzQ2xpZW50ID0gdHlwZW9mIHJhdGVMaW1pdFJlZGlzID09PSAnc3RyaW5nJyA/IG5ldyBSZWRpcyhyYXRlTGltaXRSZWRpcykgOiByYXRlTGltaXRSZWRpcztcbiAgICAgICAgLy8gaW9yZWRpcyBlbWl0cyAnZXJyb3InIG9uIGNvbm5lY3Rpb24gbG9zczsgd2l0aG91dCBhIGxpc3RlbmVyIE5vZGVcbiAgICAgICAgLy8gdHJlYXRzIGl0IGFzIGFuIHVuaGFuZGxlZCAnZXJyb3InIGV2ZW50IGFuZCBDUkFTSEVTIHRoZSBwcm9jZXNzLiBMb2dcbiAgICAgICAgLy8gYW5kIGxldCBpb3JlZGlzIGF1dG8tcmVjb25uZWN0IChyYXRlIGxpbWl0aW5nIGZhbGxzIGJhY2sgcGVyLXN0b3JlKS5cbiAgICAgICAgcmVkaXNDbGllbnQub24oJ2Vycm9yJywgKGU6IHVua25vd24pID0+XG4gICAgICAgICAgY3JlYXRlTG9nZ2VyKCdyYXRlLWxpbWl0Jykud2FybignUmVkaXMgcmF0ZS1saW1pdCBzdG9yZSBlcnJvcicsIHsgZXJyb3I6IGUgaW5zdGFuY2VvZiBFcnJvciA/IGUubWVzc2FnZSA6IFN0cmluZyhlKSB9KSk7XG4gICAgICAgIHJhdGVMaW1pdE9wdGlvbnMuc3RvcmUgPSBuZXcgUmVkaXNTdG9yZSh7XG4gICAgICAgICAgc2VuZENvbW1hbmQ6ICguLi5hcmdzOiBzdHJpbmdbXSkgPT4gcmVkaXNDbGllbnQuY2FsbCguLi5hcmdzKSxcbiAgICAgICAgfSk7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgY3JlYXRlTG9nZ2VyKCdyYXRlLWxpbWl0Jykud2FybignUmVkaXMgc3RvcmUgdW5hdmFpbGFibGUsIGZhbGxpbmcgYmFjayB0byBpbi1tZW1vcnkgcmF0ZSBsaW1pdGluZycpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGFwcC51c2UocmF0ZUxpbWl0KHJhdGVMaW1pdE9wdGlvbnMpKTtcbiAgfVxuXG4gIC8vIEV4cHJlc3MgcmVxdWVzdCB0aW1lb3V0IOKAlCB1c2VzIENvcmVDb25zdGFudHMgdG8gc2hhcmUgdGhlIHNhbWUgZGVmYXVsdCBhcyBMYW1iZGEgaGFuZGxlcnNcbiAgY29uc3QgdGltZW91dE1zID0gQ29yZUNvbnN0YW50cy5IQU5ETEVSX1RJTUVPVVRfTVM7XG4gIGFwcC51c2UoKF9yZXE6IFJlcXVlc3QsIHJlczogUmVzcG9uc2UsIG5leHQ6IE5leHRGdW5jdGlvbikgPT4ge1xuICAgIHJlcy5zZXRUaW1lb3V0KHRpbWVvdXRNcywgKCkgPT4ge1xuICAgICAgaWYgKCFyZXMuaGVhZGVyc1NlbnQpIHtcbiAgICAgICAgc2VuZEVycm9yKHJlcywgNTAzLCAnUmVxdWVzdCB0aW1lb3V0Jyk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgbmV4dCgpO1xuICB9KTtcblxuICAvLyBSZXF1ZXN0IGR1cmF0aW9uIGxvZ2dpbmdcbiAgY29uc3QgZHVyYXRpb25Mb2dnZXIgPSBjcmVhdGVMb2dnZXIoJ3JlcXVlc3QtZHVyYXRpb24nKTtcbiAgYXBwLnVzZSgocmVxOiBSZXF1ZXN0LCByZXM6IFJlc3BvbnNlLCBuZXh0OiBOZXh0RnVuY3Rpb24pID0+IHtcbiAgICBjb25zdCBzdGFydCA9IERhdGUubm93KCk7XG4gICAgcmVzLm9uKCdmaW5pc2gnLCAoKSA9PiB7XG4gICAgICBjb25zdCBkdXJhdGlvbiA9IERhdGUubm93KCkgLSBzdGFydDtcbiAgICAgIC8vIExvZyBgcmVxLnBhdGhgIChubyBxdWVyeSBzdHJpbmcpIOKAlCBhIHN0cmF5IGA/dG9rZW49YC9gP3RpY2tldD1gIG11c3Qgbm90IGJlXG4gICAgICAvLyBwZXJzaXN0ZWQgdmVyYmF0aW0gb24gZXZlcnkgcmVxdWVzdCAobWlycm9ycyB0aGUgYXV0aHotZGVuaWFsIGF1ZGl0b3IncyBzdHJpcCkuXG4gICAgICBkdXJhdGlvbkxvZ2dlci5pbmZvKGAke3JlcS5tZXRob2R9ICR7cmVxLnBhdGh9ICR7cmVzLnN0YXR1c0NvZGV9ICR7ZHVyYXRpb259bXNgLCB7XG4gICAgICAgIG1ldGhvZDogcmVxLm1ldGhvZCxcbiAgICAgICAgcGF0aDogcmVxLnBhdGgsXG4gICAgICAgIHN0YXR1c0NvZGU6IHJlcy5zdGF0dXNDb2RlLFxuICAgICAgICBkdXJhdGlvbk1zOiBkdXJhdGlvbixcbiAgICAgICAgcmVxdWVzdElkOiByZXEucmVxdWVzdElkLFxuICAgICAgfSk7XG4gICAgfSk7XG4gICAgbmV4dCgpO1xuICB9KTtcblxuICAvLyBQcm9tZXRoZXVzIG1ldHJpY3MgbWlkZGxld2FyZSDigJQgcmVjb3JkcyByZXF1ZXN0IGR1cmF0aW9uIGFuZCBjb3VudFxuICBhcHAudXNlKG1ldHJpY3NNaWRkbGV3YXJlKCkpO1xuXG4gIC8vIE5PVEU6IGlkZW1wb3RlbmN5IGlzIGludGVudGlvbmFsbHkgTk9UIG1vdW50ZWQgaGVyZS4gSXQgbmVlZHMgdGhlIFZFUklGSUVEXG4gIC8vIG9yZyBpZCB0byBuYW1lc3BhY2UgaXRzIHJlcGxheSBjYWNoZSwgYnV0IHRoaXMgcHJlLWF1dGggcG9zaXRpb24gcnVucyBiZWZvcmVcbiAgLy8gYHJlcXVpcmVBdXRoYC9gYXR0YWNoUmVxdWVzdENvbnRleHRgIHBvcHVsYXRlIGlkZW50aXR5LCBzbyBhIGdsb2JhbCBtb3VudFxuICAvLyBoZXJlIGlzIGEgcGVybWFuZW50IG5vLW9wIChvcmcgYWx3YXlzIHVuZGVmaW5lZCDihpIgc2tpcCkuIEl0IGlzIGluc3RlYWQgd2lyZWRcbiAgLy8gaW50byB0aGUgcG9zdC1hdXRoIHJvdXRlIGNoYWlucyDigJQgc2VlIGBjcmVhdGVQcm90ZWN0ZWRSb3V0ZWAgL1xuICAvLyBgY3JlYXRlQXV0aGVudGljYXRlZFdpdGhPcmdSb3V0ZWAgaW4gbWlkZGxld2FyZS1mYWN0b3J5LnRzLlxuXG4gIC8vIFNTRSBsb2dzIGVuZHBvaW50IOKAlCB0aWNrZXQtZ2F0ZWQgKFdhdmUgMmIpLlxuICAvLyBUaGUgc3RyZWFtIGNhcnJpZXMgcGVyLW9yZyBidWlsZCBsb2dzLCBzbyBpdCBtdXN0IG5vdCBiZSB3b3JsZC1yZWFkYWJsZS5cbiAgLy8gQ2xpZW50cyBmaXJzdCBQT1NUIC9sb2dzL3RpY2tldCAoSldULWF1dGhlbnRpY2F0ZWQpIHRvIG1pbnQgYSBzaG9ydC1saXZlZCxcbiAgLy8gc2luZ2xlLXVzZSB0aWNrZXQgYm91bmQgdG8gdGhlaXIgb3JnIEFORCB0byB0aGUgc3BlY2lmaWMgYHJlcXVlc3RJZGAgc3RyZWFtXG4gIC8vIHRoZXkgaW50ZW5kIHRvIG9wZW4sIHRoZW4gb3BlbiB0aGUgRXZlbnRTb3VyY2Ugd2l0aCA/dGlja2V0PTx0Pi4gVGhpcyBrZWVwc1xuICAvLyB0aGUgSldUIG91dCBvZiBxdWVyeSBzdHJpbmdzIC8gYWNjZXNzIGxvZ3Mgd2hpbGUgZW5mb3JjaW5nIG9yZyBvd25lcnNoaXAsXG4gIC8vIHBlci1zdWJqZWN0IGF1dGhvcml6YXRpb24sIGFuZCB0aGUgcGVyLW9yZyBjb25uZWN0aW9uIGNhcCBvbiB0aGUgc3RyZWFtLlxuICAvLyBNaXJyb3JzIHRoZSBtZXNzYWdlLXNlcnZpY2Ugbm90aWZpY2F0aW9ucyBTU0UgdGlja2V0IGV4Y2hhbmdlLlxuICBhcHAucG9zdCgnL2xvZ3MvdGlja2V0JywgcmVxdWlyZUF1dGgsIGFzeW5jIChyZXE6IFJlcXVlc3QsIHJlczogUmVzcG9uc2UpID0+IHtcbiAgICBjb25zdCBvcmdJZCA9IHJlcS51c2VyPy5vcmdhbml6YXRpb25JZD8udG9Mb3dlckNhc2UoKTtcbiAgICBpZiAoIW9yZ0lkKSB7XG4gICAgICBzZW5kRXJyb3IocmVzLCA0MDAsICdUb2tlbiBtaXNzaW5nIG9yZ2FuaXphdGlvbicsIEVycm9yQ29kZS5WQUxJREFUSU9OX0VSUk9SKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy8gVGhlIGNhbGxlciBtdXN0IG5hbWUgdGhlIHN0cmVhbSBzdWJqZWN0IHVwIGZyb250IHNvIHRoZSB0aWNrZXQgaXMgYm91bmQgdG9cbiAgICAvLyBpdC4gV2l0aG91dCB0aGlzLCBhIHRpY2tldCBjb3VsZCBiZSByZXBsYXllZCBhZ2FpbnN0IEFOWSByZXF1ZXN0SWQgdGhlXG4gICAgLy8gb3JnIGNvdWxkIGd1ZXNzLCBsZXR0aW5nIGl0IGF0dGFjaCB0byBhbm90aGVyIG9yZydzIGxvZyBzdHJlYW0uIFN0cmljdGx5XG4gICAgLy8gZm9ybWF0LXZhbGlkYXRlZCBzbyBpdCBjYW4ndCBjYXJyeSBhbiBpbmplY3Rpb24gcGF5bG9hZCBpbnRvIHRoZSBzdWJqZWN0LlxuICAgIGNvbnN0IHJlcXVlc3RJZCA9IChyZXEuYm9keSBhcyB7IHJlcXVlc3RJZD86IHVua25vd24gfSB8IHVuZGVmaW5lZCk/LnJlcXVlc3RJZDtcbiAgICBpZiAodHlwZW9mIHJlcXVlc3RJZCAhPT0gJ3N0cmluZycgfHwgIVNTRV9SRVFVRVNUX0lEX1JFLnRlc3QocmVxdWVzdElkKSkge1xuICAgICAgc2VuZEVycm9yKHJlcywgNDAwLCAnTWlzc2luZyBvciBpbnZhbGlkIHJlcXVlc3RJZCcsIEVycm9yQ29kZS5WQUxJREFUSU9OX0VSUk9SKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgc3NlTWFuYWdlci5jcmVhdGVUaWNrZXQob3JnSWQsIHJlcXVlc3RJZCk7XG4gICAgaWYgKCFyZXN1bHQub2spIHtcbiAgICAgIGlmIChyZXN1bHQucmVhc29uID09PSAnZm9yYmlkZGVuJykge1xuICAgICAgICAvLyBUaGUgc3ViamVjdCBpcyBvd25lZCBieSBhbm90aGVyIG9yZyDigJQgZG8gbm90IGNvbmZpcm0gaXQgZXhpc3RzOyBhIHBsYWluXG4gICAgICAgIC8vIDQwMyBpcyBlbm91Z2ggYW5kIGxlYWtzIG5vdGhpbmcgYWJvdXQgd2hpY2ggcmVxdWVzdElkcyBhcmUgbGl2ZS5cbiAgICAgICAgc2VuZEVycm9yKHJlcywgNDAzLCAnTm90IGF1dGhvcml6ZWQgZm9yIHRoaXMgbG9nIHN0cmVhbScsIEVycm9yQ29kZS5JTlNVRkZJQ0lFTlRfUEVSTUlTU0lPTlMpO1xuICAgICAgfSBlbHNlIGlmIChyZXN1bHQucmVhc29uID09PSAnb3JnLWxpbWl0Jykge1xuICAgICAgICBzZW5kRXJyb3IocmVzLCA0MjksICdUb28gbWFueSBsb2cgc3RyZWFtIHRpY2tldHMgaXNzdWVkJywgRXJyb3JDb2RlLlFVT1RBX0VYQ0VFREVEKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNlbmRFcnJvcihyZXMsIDUwMywgJ0xvZyBzdHJlYW1pbmcgc3Vic3lzdGVtIGF0IGNhcGFjaXR5JywgRXJyb3JDb2RlLlFVT1RBX0VYQ0VFREVEKTtcbiAgICAgIH1cbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgc2VuZFN1Y2Nlc3MocmVzLCAyMDAsIHsgdGlja2V0OiByZXN1bHQudGlja2V0IH0pO1xuICB9KTtcblxuICAvLyBUaGUgc3RyZWFtIGl0c2VsZiByZXNvbHZlcyArIGNvbnN1bWVzIHRoZSB0aWNrZXQgaW5zaWRlIG1pZGRsZXdhcmUoKSBhbmRcbiAgLy8gcmVqZWN0cyBhbnkgYW5vbnltb3VzIC8gaW52YWxpZCAvIGV4cGlyZWQgLyBhbHJlYWR5LXVzZWQgdGlja2V0IHdpdGggNDAxLlxuICBhcHAuZ2V0KCcvbG9ncy86cmVxdWVzdElkJywgc3NlTWFuYWdlci5taWRkbGV3YXJlKCkpO1xuXG4gIHJldHVybiB7IGFwcCwgc3NlTWFuYWdlciB9O1xufVxuIl19
356
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwLWZhY3RvcnkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXBpL2FwcC1mYWN0b3J5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFFdEMsT0FBTyxFQUFFLFdBQVcsRUFBRSxTQUFTLEVBQUUsbUJBQW1CLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxzQkFBc0IsRUFBRSxrQkFBa0IsRUFBRSxpQkFBaUIsRUFBRSxXQUFXLEVBQUUsU0FBUyxFQUFFLHVCQUF1QixFQUFFLGlCQUFpQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFFclAsT0FBTyxFQUFFLE1BQU0sRUFBRSxhQUFhLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUN4RSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDaEUsT0FBTyxXQUFXLE1BQU0sYUFBYSxDQUFDO0FBQ3RDLE9BQU8sSUFBSSxNQUFNLE1BQU0sQ0FBQztBQUN4QixPQUFPLE9BQU8sRUFBRSxFQUFnRSxNQUFNLFNBQVMsQ0FBQztBQUNoRyxPQUFPLFNBQVMsRUFBRSxFQUFFLGNBQWMsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQy9ELE9BQU8sTUFBTSxNQUFNLFFBQVEsQ0FBQztBQUM1QixPQUFPLFNBQVMsTUFBTSxvQkFBb0IsQ0FBQztBQUMzQyxPQUFPLEVBQUUsRUFBRSxJQUFJLElBQUksRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNsQyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDdEQsT0FBTyxFQUFFLDhCQUE4QixFQUFFLG1CQUFtQixFQUF5QixNQUFNLDZCQUE2QixDQUFDO0FBQ3pILE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxjQUFjLEVBQUUsVUFBVSxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQzdFLE9BQU8sRUFBRSwwQkFBMEIsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQ25FLE9BQU8sRUFB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RUFBRSxTQUFTLENBQUMsd0JBQXdCLENBQUMsQ0FBQztnQkFDaEcsQ0FBQztxQkFBTSxJQUFJLE1BQU0sQ0FBQyxNQUFNLEtBQUssV0FBVyxFQUFFLENBQUM7b0JBQ3pDLFNBQVMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLG9DQUFvQyxFQUFFLFNBQVMsQ0FBQyxjQUFjLENBQUMsQ0FBQztnQkFDdEYsQ0FBQztxQkFBTSxDQUFDO29CQUNOLFNBQVMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLHFDQUFxQyxFQUFFLFNBQVMsQ0FBQyxjQUFjLENBQUMsQ0FBQztnQkFDdkYsQ0FBQztnQkFDRCxPQUFPO1lBQ1QsQ0FBQztZQUNELFdBQVcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEVBQUUsTUFBTSxFQUFFLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO1FBQ25ELENBQUMsQ0FBQyxDQUFDO1FBRUgsMkVBQTJFO1FBQzNFLDRFQUE0RTtRQUM1RSxHQUFHLENBQUMsR0FBRyxDQUFDLGtCQUFrQixFQUFFLFVBQVUsQ0FBQyxVQUFVLEVBQUUsQ0FBQyxDQUFDO0lBQ3ZELENBQUM7SUFFRCxPQUFPLEVBQUUsR0FBRyxFQUFFLFVBQVUsRUFBRSxDQUFDO0FBQzdCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuaW1wb3J0IHsgc2VuZFN1Y2Nlc3MsIHNlbmRFcnJvciwgZ2VuZXJhdGVPcGVuQXBpU3BlYywgRXJyb3JDb2RlLCBjcmVhdGVMb2dnZXIsIHZlcmlmeVNlcnZpY2VQcmluY2lwYWwsIGNyZWF0ZUhlYWx0aFJvdXRlciwgc2V0Q291bnRlckVtaXR0ZXIsIHJlcXVpcmVBdXRoLCBzYWZlRXF1YWwsIGNyZWF0ZUVudlNzZVRpY2tldFN0b3JlLCBTU0VfVElDS0VUX1RUTF9NUyB9IGZyb20gJ0BwaXBlbGluZS1idWlsZGVyL2FwaS1jb3JlJztcbmltcG9ydCB0eXBlIHsgT3BlbkFwaVNwZWNPcHRpb25zIH0gZnJvbSAnQHBpcGVsaW5lLWJ1aWxkZXIvYXBpLWNvcmUnO1xuaW1wb3J0IHsgQ29uZmlnLCBDb3JlQ29uc3RhbnRzIH0gZnJvbSAnQHBpcGVsaW5lLWJ1aWxkZXIvcGlwZWxpbmUtY29yZSc7XG5pbXBvcnQgeyBnZXRDb25uZWN0aW9uIH0gZnJvbSAnQHBpcGVsaW5lLWJ1aWxkZXIvcGlwZWxpbmUtZGF0YSc7XG5pbXBvcnQgY29tcHJlc3Npb24gZnJvbSAnY29tcHJlc3Npb24nO1xuaW1wb3J0IGNvcnMgZnJvbSAnY29ycyc7XG5pbXBvcnQgZXhwcmVzcywgeyB0eXBlIEV4cHJlc3MsIHR5cGUgTmV4dEZ1bmN0aW9uLCB0eXBlIFJlcXVlc3QsIHR5cGUgUmVzcG9uc2UgfSBmcm9tICdleHByZXNzJztcbmltcG9ydCByYXRlTGltaXQsIHsgaXBLZXlHZW5lcmF0b3IgfSBmcm9tICdleHByZXNzLXJhdGUtbGltaXQnO1xuaW1wb3J0IGhlbG1ldCBmcm9tICdoZWxtZXQnO1xuaW1wb3J0IHN3YWdnZXJVaSBmcm9tICdzd2FnZ2VyLXVpLWV4cHJlc3MnO1xuaW1wb3J0IHsgdjcgYXMgdXVpZCB9IGZyb20gJ3V1aWQnO1xuaW1wb3J0IHsgZXRhZ01pZGRsZXdhcmUgfSBmcm9tICcuL2V0YWctbWlkZGxld2FyZS5qcyc7XG5pbXBvcnQgeyBjcmVhdGVFbnZSZWRpc0lkZW1wb3RlbmN5U3RvcmUsIHNldElkZW1wb3RlbmN5U3RvcmUsIHR5cGUgSWRlbXBvdGVuY3lTdG9yZSB9IGZyb20gJy4vaWRlbXBvdGVuY3ktbWlkZGxld2FyZS5qcyc7XG5pbXBvcnQgeyBtZXRyaWNzTWlkZGxld2FyZSwgbWV0cmljc0hhbmRsZXIsIGluY0NvdW50ZXIgfSBmcm9tICcuL21ldHJpY3MuanMnO1xuaW1wb3J0IHsgY3JlYXRlU2hhcmVkUmF0ZUxpbWl0U3RvcmUgfSBmcm9tICcuL3JhdGUtbGltaXQtc3RvcmUuanMnO1xuaW1wb3J0IHsgcmVhZGluZXNzR3VhcmQgfSBmcm9tICcuL3JlYWRpbmVzcy5qcyc7XG5pbXBvcnQgeyBTU0VNYW5hZ2VyLCBTU0VfUkVRVUVTVF9JRF9SRSB9IGZyb20gJy4uL2h0dHAvc3NlLWNvbm5lY3Rpb24tbWFuYWdlci5qcyc7XG5pbXBvcnQgeyBjcmVhdGVFbnZSZWRpc1NTRVJlbGF5IH0gZnJvbSAnLi4vaHR0cC9zc2UtcmVsYXkuanMnO1xuXG4vLyBXaXJlIGFwaS1jb3JlJ3MgY291bnRlciBzaGltIHRvIHRoZSByZWFsIHByb20tY2xpZW50IHJlZ2lzdHJ5LiBUaGlzIGlzXG4vLyBhIG5vLW9wIHVudGlsIGluY0NvdW50ZXIgaXMgY2FsbGVkIGZvciB0aGUgZmlyc3QgdGltZSAobGF6eSByZWdpc3RyYXRpb25cbi8vIGluIG1ldHJpY3MudHMpLCBhbmQgbGV0cyBhcGktY29yZSBoZWxwZXJzIGxpa2UgdGhlIHF1b3RhIGNsaWVudCByZWNvcmRcbi8vIGBxdW90YV9mYWlsX29wZW5fdG90YWxgIHdpdGhvdXQgdGFraW5nIGEgaGFyZCBkZXAgb24gYXBpLXNlcnZlci5cbnNldENvdW50ZXJFbWl0dGVyKGluY0NvdW50ZXIpO1xuXG4vKipcbiAqIE9wdGlvbnMgZm9yIGNyZWF0aW5nIGFuIEV4cHJlc3MgYXBwbGljYXRpb25cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDcmVhdGVBcHBPcHRpb25zIHtcbiAgLyoqIEVuYWJsZSBDT1JTIChkZWZhdWx0OiB0cnVlKSAqL1xuICBlbmFibGVDb3JzPzogYm9vbGVhbjtcbiAgLyoqIEVuYWJsZSBIZWxtZXQgc2VjdXJpdHkgaGVhZGVycyAoZGVmYXVsdDogdHJ1ZSkgKi9cbiAgZW5hYmxlSGVsbWV0PzogYm9vbGVhbjtcbiAgLyoqIEVuYWJsZSByYXRlIGxpbWl0aW5nIChkZWZhdWx0OiB0cnVlKSAqL1xuICBlbmFibGVSYXRlTGltaXQ/OiBib29sZWFuO1xuICAvKiogRW5hYmxlIEpTT04gYm9keSBwYXJzaW5nIChkZWZhdWx0OiB0cnVlKSAqL1xuICBlbmFibGVKc29uQm9keT86IGJvb2xlYW47XG4gIC8qKiBKU09OIGJvZHkgc2l6ZSBsaW1pdCAoZGVmYXVsdDogJzFtYicpICovXG4gIGpzb25MaW1pdD86IHN0cmluZztcbiAgLyoqXG4gICAqIFBhdGggcHJlZml4ZXMgdGhlIGdsb2JhbCBKU09OIGJvZHkgcGFyc2VyIG11c3QgTk9UIHRvdWNoIOKAlCBmb3Igcm91dGVzIHRoYXQgbmVlZFxuICAgKiB0aGUgcmF3IGJvZHkgKGUuZy4gYSBTdHJpcGUgd2ViaG9vayB3aG9zZSBITUFDIGlzIGNvbXB1dGVkIG92ZXIgdGhlIGV4YWN0IGJ5dGVzKS5cbiAgICogV2l0aG91dCB0aGlzIHRoZSBnbG9iYWwgcGFyc2VyIGNvbnN1bWVzIHRoZSBib2R5IGZpcnN0IGFuZCBhIGxhdGVyIGBleHByZXNzLnJhdygpYFxuICAgKiBvbiB0aGUgc2FtZSBwYXRoIGlzIGEgbm8tb3AsIGJyZWFraW5nIHNpZ25hdHVyZSB2ZXJpZmljYXRpb24uXG4gICAqL1xuICBqc29uQm9keUV4Y2x1ZGU/OiBzdHJpbmdbXTtcbiAgLyoqIEVuYWJsZSBVUkwtZW5jb2RlZCBib2R5IHBhcnNpbmcgKGRlZmF1bHQ6IHRydWUpICovXG4gIGVuYWJsZVVybEVuY29kZWQ/OiBib29sZWFuO1xuICAvKiogVVJMLWVuY29kZWQgYm9keSBzaXplIGxpbWl0IChkZWZhdWx0OiAnMW1iJykgKi9cbiAgdXJsRW5jb2RlZExpbWl0Pzogc3RyaW5nO1xuICAvKiogQ3VzdG9tIFNTRSBtYW5hZ2VyIGluc3RhbmNlICovXG4gIHNzZU1hbmFnZXI/OiBTU0VNYW5hZ2VyO1xuICAvKipcbiAgICogU2VydmUgdGhlIHBlci1yZXF1ZXN0IGJ1aWxkLWxvZyBzdHJlYW06IGBQT1NUIC9sb2dzL3RpY2tldGAgK1xuICAgKiBgR0VUIC9sb2dzLzpyZXF1ZXN0SWRgLCBhIGxvZyB0aWNrZXQgc3RvcmUsIHRoZSBjcm9zcy1wb2QgcmVsYXksIGFuZFxuICAgKiBgY3R4LmxvZ2AgZnJhbWVzIHB1c2hlZCB0byBTU0UuIERlZmF1bHQgZmFsc2Ug4oCUIGEgc2VydmljZSB3aXRob3V0IGl0IGhhcyBub1xuICAgKiBgL2xvZ3NgIHJvdXRlcyBhbmQgYGN0eC5sb2dgIG9ubHkgd3JpdGVzIHRvIHRoZSBsb2dnZXIuXG4gICAqL1xuICBsb2dTdHJlYW0/OiBib29sZWFuO1xuICAvKiogSGVhbHRoIGNoZWNrIGRlcGVuZGVuY3kgY2hlY2tlciDigJQgaWYgcHJvdmlkZWQsIC9oZWFsdGggcmVwb3J0cyBkZXBlbmRlbmN5IHN0YXR1cyAqL1xuICBjaGVja0RlcGVuZGVuY2llcz86ICgpID0+IFByb21pc2U8UmVjb3JkPHN0cmluZywgJ2Nvbm5lY3RlZCcgfCAnZGlzY29ubmVjdGVkJyB8ICd1bmtub3duJz4+O1xuICAvKiogRW5hYmxlIE9wZW5BUEkgc3BlYyBhdCAvZG9jcy9vcGVuYXBpLmpzb24gYW5kIFN3YWdnZXIgVUkgYXQgL2RvY3MgKGRlZmF1bHQ6IHRydWUpICovXG4gIC8qKlxuICAgKiBTZXJ2ZSB0aGUgT3BlbkFQSSBzcGVjIGF0IGAvZG9jcy9vcGVuYXBpLmpzb25gIGFuZCBTd2FnZ2VyIFVJIGF0IGAvZG9jc2AuXG4gICAqXG4gICAqIERlZmF1bHRzIHRvIE9GRiB1bmRlciBgTk9ERV9FTlY9cHJvZHVjdGlvbmA6IHRoZSByb3V0ZXMgYXJlIHJlZ2lzdGVyZWQgYWJvdmVcbiAgICogdGhlIHJhdGUgbGltaXRlciBhbmQgd2VyZSBuZXZlciBhdXRoLWdhdGVkLCBzbyBpbiBwcm9kdWN0aW9uIHRoZXkgcHVibGlzaGVkXG4gICAqIHRoZSBmdWxsIHJvdXRlICsgc2NoZW1hIGludmVudG9yeSBvZiBldmVyeSBzZXJ2aWNlIHRvIGFueW9uZSB3aG8gY291bGQgcmVhY2hcbiAgICogdGhlIHBvcnQuIE9ubHkgdGhlIENTUCB3YXMgdGlnaHRlbmVkIGZvciBwcm9kdWN0aW9uIGJlZm9yZSwgbm90IHRoZSByb3V0ZS5cbiAgICogUGFzcyBgdHJ1ZWAgZXhwbGljaXRseSB0byBzZXJ2ZSB0aGVtIGluIHByb2R1Y3Rpb24gYW55d2F5LlxuICAgKi9cbiAgZW5hYmxlT3BlbkFwaT86IGJvb2xlYW47XG4gIC8qKiBPcGVuQVBJIHNwZWMgY3VzdG9taXphdGlvbiBvcHRpb25zICovXG4gIG9wZW5BcGlPcHRpb25zPzogT3BlbkFwaVNwZWNPcHRpb25zO1xuICAvKiogRW5hYmxlIGd6aXAvZGVmbGF0ZSByZXNwb25zZSBjb21wcmVzc2lvbiAoZGVmYXVsdDogdHJ1ZSkgKi9cbiAgZW5hYmxlQ29tcHJlc3Npb24/OiBib29sZWFuO1xuICAvKipcbiAgICogSWRlbXBvdGVuY3kgcmVwbGF5LWNhY2hlIGJhY2tlbmQgZm9yIGtleWVkIG11dGF0aW9uIHJldHJpZXMuIFdoZW4gb21pdHRlZCxcbiAgICogY3JlYXRlQXBwIGF1dG8td2lyZXMgdGhlIHNoYXJlZCBlbnYgUmVkaXMgc3RvcmUgKG11bHRpLXJlcGxpY2EgZGVkdXApIGlmXG4gICAqIFJlZGlzIGlzIGNvbmZpZ3VyZWQsIGVsc2Uga2VlcHMgdGhlIGluLW1lbW9yeSBkZWZhdWx0IChzaW5nbGUtcmVwbGljYSkuXG4gICAqIFBhc3MgYW4gZXhwbGljaXQgc3RvcmUgdG8gaW5qZWN0IGEgYmVzcG9rZSBiYWNrZW5kIChlLmcuIGEgc2VydmljZSdzIG93blxuICAgKiBpb3JlZGlzIGNvbm5lY3Rpb24pLlxuICAgKi9cbiAgaWRlbXBvdGVuY3lTdG9yZT86IElkZW1wb3RlbmN5U3RvcmU7XG4gIC8qKlxuICAgKiBFeHRyYSB3YXJtdXAgY2FsbGJhY2tzIGludm9rZWQgYnkgYEdFVCAvd2FybXVwYCBpbiBhZGRpdGlvbiB0byB0aGVcbiAgICogZGVmYXVsdCBQb3N0Z3JlcyBwaW5nLiBVc2UgZm9yIHNlcnZpY2VzIHRoYXQgZGVwZW5kIG9uIE1vbmdvLCBSZWRpcyxcbiAgICogU1FTLCBldGMuIOKAlCBwcmUtd2FybWluZyBvcGVucyBjb25uZWN0aW9uIHBvb2xzIGJlZm9yZSByZWFsIHRyYWZmaWNcbiAgICogYXJyaXZlcy4gRWFjaCBjYWxsYmFjayBzaG91bGQgcmVzb2x2ZSB3aGVuIGl0cyBkZXBlbmRlbmN5IGlzIHJlYWR5O1xuICAgKiBhbnkgcmVqZWN0aW9uIGNhdXNlcyAvd2FybXVwIHRvIHJldHVybiA1MDMuXG4gICAqL1xuICB3YXJtdXBIb29rcz86IEFycmF5PCgpID0+IFByb21pc2U8dm9pZD4+O1xufVxuXG4vKipcbiAqIFJlc3VsdCBvZiBjcmVhdGluZyBhbiBFeHByZXNzIGFwcGxpY2F0aW9uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ3JlYXRlQXBwUmVzdWx0IHtcbiAgLyoqIENvbmZpZ3VyZWQgRXhwcmVzcyBhcHBsaWNhdGlvbiAqL1xuICBhcHA6IEV4cHJlc3M7XG4gIC8qKiBTU0UgbWFuYWdlciBpbnN0YW5jZSAqL1xuICBzc2VNYW5hZ2VyOiBTU0VNYW5hZ2VyO1xufVxuXG4vKipcbiAqIENyZWF0ZSBhbmQgY29uZmlndXJlIGFuIEV4cHJlc3MgYXBwbGljYXRpb24gd2l0aCBjb21tb24gbWlkZGxld2FyZVxuICpcbiAqIFNldHMgdXA6XG4gKiAtIENPUlMgd2l0aCBjb25maWd1cmVkIG9yaWdpbnNcbiAqIC0gSGVsbWV0IHNlY3VyaXR5IGhlYWRlcnNcbiAqIC0gUmF0ZSBsaW1pdGluZ1xuICogLSBKU09OIGFuZCBVUkwtZW5jb2RlZCBib2R5IHBhcnNpbmdcbiAqIC0gVHJ1c3QgcHJveHkgc2V0dGluZ3NcbiAqIC0gSGVhbHRoIGNoZWNrIGVuZHBvaW50ICgvaGVhbHRoKVxuICogLSBNZXRyaWNzIGVuZHBvaW50ICgvbWV0cmljcylcbiAqIC0gU1NFIGxvZ3MgZW5kcG9pbnQgKC9sb2dzLzpyZXF1ZXN0SWQpIOKAlCBvbmx5IHdpdGggYGxvZ1N0cmVhbTogdHJ1ZWBcbiAqXG4gKiBAcGFyYW0gb3B0aW9ucyAtIENvbmZpZ3VyYXRpb24gb3B0aW9uc1xuICogQHJldHVybnMgQ29uZmlndXJlZCBFeHByZXNzIGFwcCBhbmQgU1NFIG1hbmFnZXJcbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgeyBhcHAsIHNzZU1hbmFnZXIgfSA9IGNyZWF0ZUFwcCgpO1xuICpcbiAqIGFwcC5wb3N0KCcvYXBpL3Jlc291cmNlJywgcmVxdWlyZUF1dGgsIGFzeW5jIChyZXEsIHJlcykgPT4ge1xuICogICAvLyBZb3VyIHJvdXRlIGhhbmRsZXJcbiAqIH0pO1xuICpcbiAqIHN0YXJ0U2VydmVyKGFwcCwgeyBuYW1lOiAnTXkgU2VydmljZScgfSk7XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUFwcChvcHRpb25zOiBDcmVhdGVBcHBPcHRpb25zID0ge30pOiBDcmVhdGVBcHBSZXN1bHQge1xuICBjb25zdCB7XG4gICAgZW5hYmxlQ29ycyA9IHRydWUsXG4gICAgZW5hYmxlSGVsbWV0ID0gdHJ1ZSxcbiAgICBlbmFibGVSYXRlTGltaXQgPSB0cnVlLFxuICAgIGVuYWJsZUpzb25Cb2R5ID0gdHJ1ZSxcbiAgICBqc29uTGltaXQgPSAnMW1iJyxcbiAgICBlbmFibGVVcmxFbmNvZGVkID0gdHJ1ZSxcbiAgICB1cmxFbmNvZGVkTGltaXQgPSAnMW1iJyxcbiAgICBsb2dTdHJlYW0gPSBmYWxzZSxcbiAgICBjaGVja0RlcGVuZGVuY2llcyxcbiAgICBlbmFibGVPcGVuQXBpID0gcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyxcbiAgICBvcGVuQXBpT3B0aW9ucyxcbiAgICBlbmFibGVDb21wcmVzc2lvbiA9IHRydWUsXG4gICAgd2FybXVwSG9va3MgPSBbXSxcbiAgICBpZGVtcG90ZW5jeVN0b3JlLFxuICB9ID0gb3B0aW9ucztcblxuICBjb25zdCBzZXJ2aWNlTmFtZSA9IHByb2Nlc3MuZW52LlNFUlZJQ0VfTkFNRSB8fCAnYXBpJztcblxuICAvLyBEZWZhdWx0IFNTRSBtYW5hZ2VyLiBUaGUgcmVsYXkgKHRoaXMgc2VydmljZSdzIG93biBSZWRpcyBjaGFubmVsKSBpcyBidWlsdFxuICAvLyBvbmx5IHdoZW4gc29tZXRoaW5nIHN0cmVhbXM6IHRoZSBsb2cgc3RyZWFtIHR1cm5zIGl0IG9uIGhlcmUsIGFuZCBhblxuICAvLyBvcmcta2V5ZWQgY2hhbm5lbCB0dXJucyBpdCBvbiB3aGVuIHJlZ2lzdGVyZWQgKHJlZ2lzdGVyU3NlVGlja2V0Q2hhbm5lbCkuXG4gIC8vIFRoZSBsb2cgdGlja2V0IHN0b3JlIGV4aXN0cyBvbmx5IHdpdGggdGhlIGxvZyBzdHJlYW0uIEEgY2FsbGVyLXN1cHBsaWVkXG4gIC8vIGBzc2VNYW5hZ2VyYCBza2lwcyB0aGlzIGVudGlyZWx5LlxuICBjb25zdCBzc2VNYW5hZ2VyID0gb3B0aW9ucy5zc2VNYW5hZ2VyID8/IG5ldyBTU0VNYW5hZ2VyKHtcbiAgICBsb2dTdHJlYW0sXG4gICAgcmVsYXlGYWN0b3J5OiAoKSA9PiBjcmVhdGVFbnZSZWRpc1NTRVJlbGF5KHNlcnZpY2VOYW1lKSxcbiAgICAuLi4obG9nU3RyZWFtICYmIHtcbiAgICAgIHRpY2tldFN0b3JlOiBjcmVhdGVFbnZTc2VUaWNrZXRTdG9yZSh7XG4gICAgICAgIHR0bE1zOiBTU0VfVElDS0VUX1RUTF9NUyxcbiAgICAgICAgbWF4VG90YWw6IHBhcnNlSW50KHByb2Nlc3MuZW52LlNTRV9NQVhfVE9UQUxfVElDS0VUUyB8fCAnMTAwMCcsIDEwKSxcbiAgICAgICAgbWF4UGVyT3JnOiBwYXJzZUludChwcm9jZXNzLmVudi5TU0VfTUFYX1RJQ0tFVFNfUEVSX09SRyB8fCAnMTAnLCAxMCksXG4gICAgICAgIGtleVByZWZpeDogYGxvZ3M6JHtzZXJ2aWNlTmFtZX1gLFxuICAgICAgfSksXG4gICAgfSksXG4gIH0pO1xuICBpZiAobG9nU3RyZWFtKSBzc2VNYW5hZ2VyLmVuYWJsZVJlbGF5KCk7XG5cbiAgLy8gV2lyZSB0aGUgaWRlbXBvdGVuY3kgcmVwbGF5LWNhY2hlIGJhY2tlbmQgdXNlZCBieSB0aGUgcG9zdC1hdXRoIHJvdXRlXG4gIC8vIGZhY3RvcmllcyAoY3JlYXRlUHJvdGVjdGVkUm91dGUgLyBjcmVhdGVBdXRoZW50aWNhdGVkV2l0aE9yZ1JvdXRlKS4gUHJlZmVyXG4gIC8vIGFuIGV4cGxpY2l0bHkgaW5qZWN0ZWQgc3RvcmU7IG90aGVyd2lzZSBhdXRvLWNvbnN0cnVjdCBmcm9tIHRoZSBzaGFyZWQgZW52XG4gIC8vIFJlZGlzIHNvIGtleWVkIG11dGF0aW9uIHJldHJpZXMgZGVkdXBlIGFjcm9zcyByZXBsaWNhcy4gRmFsbHMgYmFjayB0byB0aGVcbiAgLy8gaW4tbWVtb3J5IGRlZmF1bHQgd2hlbiBubyBSZWRpcyBpcyBjb25maWd1cmVkIChzaW5nbGUtcmVwbGljYSBjb3JyZWN0bmVzcykuXG4gIGNvbnN0IHJlc29sdmVkSWRlbXBvdGVuY3lTdG9yZSA9IGlkZW1wb3RlbmN5U3RvcmUgPz8gY3JlYXRlRW52UmVkaXNJZGVtcG90ZW5jeVN0b3JlKCk7XG4gIGlmIChyZXNvbHZlZElkZW1wb3RlbmN5U3RvcmUpIHtcbiAgICBzZXRJZGVtcG90ZW5jeVN0b3JlKHJlc29sdmVkSWRlbXBvdGVuY3lTdG9yZSk7XG4gIH1cblxuICAvLyBPcGVuVGVsZW1ldHJ5IGlzIE5PVCBpbml0aWFsaXplZCBoZXJlOiBieSB0aGUgdGltZSBjcmVhdGVBcHAgcnVucywgZXhwcmVzc1xuICAvLyBhbmQgaHR0cCBoYXZlIGFscmVhZHkgYmVlbiByZXF1aXJlZCwgc28gdGhlIGF1dG8taW5zdHJ1bWVudGF0aW9uIGhvb2tzXG4gIC8vIHdvdWxkIGhhdmUgbm90aGluZyB0byBwYXRjaCAobm8gaW5ib3VuZCBzcGFuIOKGkiBubyB0cmFjZSBpZCkuIFRyYWNpbmcgaXNcbiAgLy8gc3RhcnRlZCBieSB0aGUgYG90ZWwtYm9vdHN0cmFwLmpzYCBwcmVsb2FkIGluc3RlYWQgKG5vZGUgLXIg4oCmIOKAlCBzZWUgZWFjaFxuICAvLyBzZXJ2aWNlJ3MgRG9ja2VyZmlsZSBDTUQgLyBzdGFydCBzY3JpcHQpLCB3aGljaCBydW5zIGJlZm9yZSBhbnlcbiAgLy8gaW5zdHJ1bWVudGVkIG1vZHVsZSBsb2Fkcy4gYGN1cnJlbnRUcmFjZUlkKClgIHRoZW4gcmVhZHMgdGhlIGFjdGl2ZSBzcGFuLlxuXG4gIGNvbnN0IHNlcnZlckNvbmZpZyA9IENvbmZpZy5nZXQoJ3NlcnZlcicpO1xuICBjb25zdCBhcHAgPSBleHByZXNzKCk7XG5cbiAgLy8gU2VjdXJpdHkgbWlkZGxld2FyZS5cbiAgLy9cbiAgLy8gU3dhZ2dlciBVSSBuZWVkcyB1bnNhZmUtaW5saW5lICsgdW5zYWZlLWV2YWwgZm9yIGl0cyBidW5kbGVkIHNjcmlwdHMg4oCUXG4gIC8vIGJ1dCB3ZSBvbmx5IHJlbGF4IENTUCB0aGF0IGZhciB3aGVuIChhKSBPcGVuQVBJIGlzIGVuYWJsZWQgQU5EIChiKSB3ZSdyZVxuICAvLyBub3QgaW4gcHJvZHVjdGlvbi4gSW4gcHJvZCwgU3dhZ2dlciBzaG91bGQgYmUgc2VydmVkIGJlaGluZCBhIHNlcGFyYXRlXG4gIC8vIGhvc3Qgb3IgYXV0aC1nYXRlZCByb3V0ZTsgdGhlIG1haW4gYXBwIGtlZXBzIHRoZSBzdHJpY3QgQ1NQIHNvIGEgU3RvcmVkXG4gIC8vIFhTUyBpbiBhbnkgaGFuZGxlciBjYW4ndCBgZXZhbCgpYCBhcmJpdHJhcnkgc2NyaXB0LlxuICBjb25zdCBpc1Byb2R1Y3Rpb24gPSBwcm9jZXNzLmVudi5OT0RFX0VOViA9PT0gJ3Byb2R1Y3Rpb24nO1xuICBjb25zdCBhbGxvd1N3YWdnZXJDc3AgPSBlbmFibGVPcGVuQXBpICYmICFpc1Byb2R1Y3Rpb247XG4gIGlmIChlbmFibGVIZWxtZXQpIHtcbiAgICBhcHAudXNlKGhlbG1ldCh7XG4gICAgICBjb250ZW50U2VjdXJpdHlQb2xpY3k6IHtcbiAgICAgICAgZGlyZWN0aXZlczoge1xuICAgICAgICAgIGRlZmF1bHRTcmM6IFtcIidzZWxmJ1wiXSxcbiAgICAgICAgICBzY3JpcHRTcmM6IGFsbG93U3dhZ2dlckNzcFxuICAgICAgICAgICAgPyBbXCInc2VsZidcIiwgXCIndW5zYWZlLWlubGluZSdcIiwgXCIndW5zYWZlLWV2YWwnXCJdXG4gICAgICAgICAgICA6IFtcIidzZWxmJ1wiXSxcbiAgICAgICAgICBzdHlsZVNyYzogW1wiJ3NlbGYnXCIsIFwiJ3Vuc2FmZS1pbmxpbmUnXCJdLFxuICAgICAgICAgIGltZ1NyYzogW1wiJ3NlbGYnXCIsICdkYXRhOicsICdibG9iOiddLFxuICAgICAgICAgIGNvbm5lY3RTcmM6IFtcIidzZWxmJ1wiXSxcbiAgICAgICAgICBmb250U3JjOiBbXCInc2VsZidcIl0sXG4gICAgICAgICAgb2JqZWN0U3JjOiBbXCInbm9uZSdcIl0sXG4gICAgICAgICAgZnJhbWVBbmNlc3RvcnM6IFtcIidub25lJ1wiXSxcbiAgICAgICAgICBiYXNlVXJpOiBbXCInc2VsZidcIl0sXG4gICAgICAgICAgZm9ybUFjdGlvbjogW1wiJ3NlbGYnXCJdLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9KSk7XG4gIH1cblxuICBpZiAoZW5hYmxlQ29ycykge1xuICAgIGFwcC51c2UoY29ycyhzZXJ2ZXJDb25maWcuY29ycykpO1xuICB9XG5cbiAgLy8gUmVzcG9uc2UgY29tcHJlc3Npb24gKGd6aXAvZGVmbGF0ZSkg4oCUIHNraXAgU1NFIHN0cmVhbXNcbiAgaWYgKGVuYWJsZUNvbXByZXNzaW9uKSB7XG4gICAgYXBwLnVzZShjb21wcmVzc2lvbih7XG4gICAgICBmaWx0ZXI6IChyZXE6IFJlcXVlc3QsIHJlczogUmVzcG9uc2UpID0+IHtcbiAgICAgICAgLy8gRG9uJ3QgY29tcHJlc3MgU1NFIHN0cmVhbXMuIE1hdGNoIGJ5IGluY2x1c2lvbjogdGhlIEFjY2VwdCBoZWFkZXIgaXNcbiAgICAgICAgLy8gb2Z0ZW4gYSBsaXN0IChlLmcuIFwidGV4dC9ldmVudC1zdHJlYW0sICovKlwiKSwgc28gZXhhY3QgZXF1YWxpdHkgbWlzc2VkXG4gICAgICAgIC8vIHRob3NlIGFuZCBjb21wcmVzc2VkL2J1ZmZlcmVkIHRoZSBzdHJlYW0uXG4gICAgICAgIGlmICgocmVxLmhlYWRlcnMuYWNjZXB0IHx8ICcnKS5pbmNsdWRlcygndGV4dC9ldmVudC1zdHJlYW0nKSkgcmV0dXJuIGZhbHNlO1xuICAgICAgICByZXR1cm4gY29tcHJlc3Npb24uZmlsdGVyKHJlcSwgcmVzKTtcbiAgICAgIH0sXG4gICAgICB0aHJlc2hvbGQ6IENvcmVDb25zdGFudHMuQ09NUFJFU1NJT05fVEhSRVNIT0xEX0JZVEVTLFxuICAgIH0pKTtcbiAgfVxuXG4gIC8vIEVUYWcgc3VwcG9ydCBmb3IgY29uZGl0aW9uYWwgR0VUIHJlcXVlc3RzICgzMDQgTm90IE1vZGlmaWVkKVxuICBhcHAudXNlKGV0YWdNaWRkbGV3YXJlKCkpO1xuXG4gIC8vIEJvZHkgcGFyc2luZ1xuICBpZiAoZW5hYmxlSnNvbkJvZHkpIHtcbiAgICBjb25zdCBqc29uUGFyc2VyID0gZXhwcmVzcy5qc29uKHsgbGltaXQ6IGpzb25MaW1pdCB9KTtcbiAgICBjb25zdCBleGNsdWRlID0gb3B0aW9ucy5qc29uQm9keUV4Y2x1ZGUgPz8gW107XG4gICAgaWYgKGV4Y2x1ZGUubGVuZ3RoID4gMCkge1xuICAgICAgLy8gU2tpcCB0aGUgZ2xvYmFsIEpTT04gcGFyc2VyIGZvciByYXctYm9keSBwYXRocyBzbyBhIHBlci1wYXRoIGBleHByZXNzLnJhdygpYFxuICAgICAgLy8gY2FuIHJlYWQgdGhlIGV4YWN0IGJ5dGVzIChzZWUgYGpzb25Cb2R5RXhjbHVkZWApLlxuICAgICAgYXBwLnVzZSgocmVxLCByZXMsIG5leHQpID0+IChleGNsdWRlLnNvbWUoKHApID0+IHJlcS5wYXRoLnN0YXJ0c1dpdGgocCkpID8gbmV4dCgpIDoganNvblBhcnNlcihyZXEsIHJlcywgbmV4dCkpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgYXBwLnVzZShqc29uUGFyc2VyKTtcbiAgICB9XG4gIH1cblxuICBpZiAoZW5hYmxlVXJsRW5jb2RlZCkge1xuICAgIGFwcC51c2UoZXhwcmVzcy51cmxlbmNvZGVkKHsgZXh0ZW5kZWQ6IHRydWUsIGxpbWl0OiB1cmxFbmNvZGVkTGltaXQgfSkpO1xuICB9XG5cbiAgLy8gVHJ1c3QgcHJveHkgKG11c3QgYmUgc2V0IGJlZm9yZSByYXRlIGxpbWl0ZXIgc28gcmVxLmlwIHJlc29sdmVzIGNvcnJlY3RseSlcbiAgYXBwLnNldCgndHJ1c3QgcHJveHknLCBzZXJ2ZXJDb25maWcudHJ1c3RQcm94eSk7XG5cbiAgLy8gUmVxdWVzdCBJRCDigJQgcHJlZmVyIGV4aXN0aW5nIGhlYWRlciBmcm9tIG5naW54LCBvdGhlcndpc2UgZ2VuZXJhdGUgb25lXG4gIGFwcC51c2UoKHJlcTogUmVxdWVzdCwgcmVzOiBSZXNwb25zZSwgbmV4dDogTmV4dEZ1bmN0aW9uKSA9PiB7XG4gICAgY29uc3QgaGRyID0gcmVxLmhlYWRlcnNbJ3gtcmVxdWVzdC1pZCddO1xuICAgIGNvbnN0IHJlcXVlc3RJZCA9IChBcnJheS5pc0FycmF5KGhkcikgPyBoZHJbMF0gOiBoZHIpIHx8IHV1aWQoKTtcbiAgICByZXEucmVxdWVzdElkID0gcmVxdWVzdElkO1xuICAgIHJlcy5zZXRIZWFkZXIoJ1gtUmVxdWVzdC1JZCcsIHJlcXVlc3RJZCk7XG4gICAgbmV4dCgpO1xuICB9KTtcblxuICAvLyBIZWFsdGggY2hlY2sgcmVnaXN0ZXJlZCBiZWZvcmUgcmF0ZSBsaW1pdGVyIHNvIGl0IGlzIG5ldmVyIHRocm90dGxlZFxuICBhcHAudXNlKGNyZWF0ZUhlYWx0aFJvdXRlcih7XG4gICAgc2VydmljZU5hbWUsXG4gICAgY2hlY2tEZXBlbmRlbmNpZXMsXG4gIH0pKTtcblxuICAvLyBSZWFkaW5lc3MgZ3VhcmQg4oCUIDUwM3MgYnVzaW5lc3MgdHJhZmZpYyB3aGlsZSB0aGUgc2VydmljZSBpcyBOb3RSZWFkeVxuICAvLyAoZGF0YXN0b3JlIHN0aWxsIGNvbm5lY3RpbmcgYXQgc3RhcnR1cCwgb3IgZHJvcHBlZCkuIE1vdW50ZWQgcmlnaHQgYWZ0ZXJcbiAgLy8gdGhlIGhlYWx0aCByb3V0ZXIgYW5kIGJlZm9yZSBldmVyeXRoaW5nIGVsc2Ugc28gYSBOb3RSZWFkeSByZXF1ZXN0IGlzXG4gIC8vIHJlamVjdGVkIGNoZWFwbHksIGJlZm9yZSByYXRlLWxpbWl0IC8gaWRlbXBvdGVuY3kgLyBidXNpbmVzcyBoYW5kbGVycyBldmVyXG4gIC8vIHRvdWNoIGEgZGlzY29ubmVjdGVkIGRhdGFzdG9yZS4gSXQgYWxsb3dsaXN0cyB0aGUgaW5mcmEgZW5kcG9pbnRzXG4gIC8vICgvbWV0cmljcywgL3dhcm11cCwgL2RvY3MsIC9sb2dzKSByZWdpc3RlcmVkIGJlbG93LCBwbHVzIC9oZWFsdGggKyAvcmVhZHkuXG4gIGFwcC51c2UocmVhZGluZXNzR3VhcmQoKSk7XG5cbiAgLy8gV2FybS11cCBlbmRwb2ludCDigJQgcHJlLW9wZW5zIGNvbm5lY3Rpb24gcG9vbHMgc28gdGhlIGZpcnN0IHJlYWwgcmVxdWVzdFxuICAvLyBkb2Vzbid0IHBheSBjb2xkLXN0YXJ0IGxhdGVuY3kuIEFsd2F5cyBwaW5ncyBQb3N0Z3Jlczsgc2VydmljZXMgdXNpbmdcbiAgLy8gTW9uZ28gLyBSZWRpcyAvIFNRUyBwYXNzIGB3YXJtdXBIb29rc2Agc28gdGhvc2UgYXJlIHdhcm1lZCBpbiBwYXJhbGxlbC5cbiAgLy9cbiAgLy8gR0FURUQgdG8gdmVyaWZpZWQgc2VydmljZSBwcmluY2lwYWxzLiBFdmVyeSBoaXQgcnVucyBhIFBvc3RncmVzIHJvdW5kLXRyaXBcbiAgLy8gcGx1cyBhbGwgYHdhcm11cEhvb2tzYCAoTW9uZ28vUmVkaXMvU1FTKSwgc28gd2hpbGUgaXQgd2FzIG9wZW4gYW4gYW5vbnltb3VzXG4gIC8vIGxvb3AgYW1wbGlmaWVkIGludG8gZGF0YXN0b3JlIGxvYWQgb24gZXZlcnkgc2VydmljZSBpbiB0aGUgZmxlZXQg4oCUIGFuZFxuICAvLyBiZWNhdXNlIGl0IGlzIHJlZ2lzdGVyZWQgYWJvdmUgdGhlIHJhdGUgbGltaXRlciwgbm90aGluZyB0aHJvdHRsZWQgaXQuXG4gIC8vIGB2ZXJpZnlTZXJ2aWNlUHJpbmNpcGFsYCBjaGVja3MgdGhlIGJlYXJlciB0b2tlbiBjcnlwdG9ncmFwaGljYWxseSwgc28gaXQgaXNcbiAgLy8gc2FmZSBoZXJlLCBhYm92ZSBgcmVxdWlyZUF1dGhgLlxuICBhcHAuZ2V0KCcvd2FybXVwJywgYXN5bmMgKHJlcTogUmVxdWVzdCwgcmVzOiBSZXNwb25zZSkgPT4ge1xuICAgIGlmICghdmVyaWZ5U2VydmljZVByaW5jaXBhbChyZXEpKSB7XG4gICAgICBzZW5kRXJyb3IocmVzLCA0MDQsICdOb3QgZm91bmQnKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IFByb21pc2UuYWxsKFtcbiAgICAgICAgZ2V0Q29ubmVjdGlvbigpLnRlc3RDb25uZWN0aW9uKCksXG4gICAgICAgIC4uLndhcm11cEhvb2tzLm1hcCgoaG9vaykgPT4gaG9vaygpKSxcbiAgICAgIF0pO1xuICAgICAgc2VuZFN1Y2Nlc3MocmVzLCAyMDAsIHsgd2FybWVkOiB0cnVlLCBob29rczogd2FybXVwSG9va3MubGVuZ3RoIH0pO1xuICAgIH0gY2F0Y2gge1xuICAgICAgc2VuZEVycm9yKHJlcywgNTAzLCAnV2FybXVwIGZhaWxlZCcpO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gUHJvbWV0aGV1cyBtZXRyaWNzIGVuZHBvaW50IOKAlCBhbHdheXMgcmVnaXN0ZXJlZCAobmV2ZXIgdGhyb3R0bGVkKS5cbiAgLy9cbiAgLy8gT3B0aW9uYWxseSBnYXRlZDogd2hlbiBgTUVUUklDU19TQ1JBUEVfVE9LRU5gIGlzIHNldCwgdGhlIHNjcmFwZXIgbXVzdCBzZW5kXG4gIC8vIGl0IGFzIGEgYmVhcmVyIHRva2VuIChQcm9tZXRoZXVzIGBiZWFyZXJfdG9rZW5gIC8gYGJlYXJlcl90b2tlbl9maWxlYCBpbiB0aGVcbiAgLy8gc2NyYXBlIGNvbmZpZykuIExlZnQgdW5nYXRlZCB3aGVuIHVuc2V0IHNvIGVuYWJsaW5nIGl0IGlzIGEgZGVsaWJlcmF0ZSxcbiAgLy8gY29vcmRpbmF0ZWQgY2hhbmdlIHJhdGhlciB0aGFuIGEgc2lsZW50IG1vbml0b3Jpbmcgb3V0YWdlIOKAlCB0aGUgdGVuYW50XG4gIC8vIGRpc2Nsb3N1cmUgdGhhdCBtYWRlIGdhdGluZyB1cmdlbnQgaXMgY2xvc2VkIGluZGVwZW5kZW50bHkgYnkgZGVmYXVsdGluZyB0aGVcbiAgLy8gcGVyLW9yZyBsYWJlbCBPRkYgKHNlZSBIVFRQX01FVFJJQ1NfT1JHX1NBTVBMRV9SQVRFIGluIG1ldHJpY3MudHMpLlxuICBjb25zdCBtZXRyaWNzVG9rZW4gPSBwcm9jZXNzLmVudi5NRVRSSUNTX1NDUkFQRV9UT0tFTjtcbiAgYXBwLmdldCgnL21ldHJpY3MnLCAocmVxOiBSZXF1ZXN0LCByZXM6IFJlc3BvbnNlLCBuZXh0OiBOZXh0RnVuY3Rpb24pID0+IHtcbiAgICBpZiAoIW1ldHJpY3NUb2tlbikge1xuICAgICAgbmV4dCgpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBoZWFkZXIgPSByZXEuaGVhZGVycy5hdXRob3JpemF0aW9uO1xuICAgIGNvbnN0IHByZXNlbnRlZCA9IGhlYWRlcj8uc3RhcnRzV2l0aCgnQmVhcmVyICcpID8gaGVhZGVyLnNsaWNlKDcpIDogdW5kZWZpbmVkO1xuICAgIC8vIENvbnN0YW50LXRpbWUgY29tcGFyZSDigJQgYSBsZW5ndGgtaW5kZXBlbmRlbnQgZXF1YWxpdHkgY2hlY2sgaGVyZSB3b3VsZFxuICAgIC8vIGxlYWsgdGhlIHRva2VuIGEgYnl0ZSBhdCBhIHRpbWUuXG4gICAgaWYgKCFwcmVzZW50ZWQgfHwgIXNhZmVFcXVhbChwcmVzZW50ZWQsIG1ldHJpY3NUb2tlbikpIHtcbiAgICAgIHNlbmRFcnJvcihyZXMsIDQwNCwgJ05vdCBmb3VuZCcpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBuZXh0KCk7XG4gIH0sIG1ldHJpY3NIYW5kbGVyKCkpO1xuXG4gIC8vIE9wZW5BUEkgc3BlYyBhbmQgU3dhZ2dlciBVSSAocmVnaXN0ZXJlZCBiZWZvcmUgcmF0ZSBsaW1pdGVyKVxuICBpZiAoZW5hYmxlT3BlbkFwaSkge1xuICAgIGNvbnN0IHNwZWMgPSBnZW5lcmF0ZU9wZW5BcGlTcGVjKG9wZW5BcGlPcHRpb25zKTtcbiAgICBhcHAuZ2V0KCcvZG9jcy9vcGVuYXBpLmpzb24nLCAoX3JlcTogUmVxdWVzdCwgcmVzOiBSZXNwb25zZSkgPT4ge1xuICAgICAgcmVzLmpzb24oc3BlYyk7XG4gICAgfSk7XG4gICAgYXBwLnVzZSgnL2RvY3MnLCBzd2FnZ2VyVWkuc2VydmUsIHN3YWdnZXJVaS5zZXR1cChzcGVjLCB7XG4gICAgICBjdXN0b21TaXRlVGl0bGU6IG9wZW5BcGlPcHRpb25zPy50aXRsZSA/PyAnUGlwZWxpbmUgQnVpbGRlciBBUEkgRG9jcycsXG4gICAgfSkpO1xuICB9XG5cbiAgLy8gUmF0ZSBsaW1pdGluZyDigJQgc2hhcmVkIGFjcm9zcyByZXBsaWNhcyB2aWEgdGhlIGVudiBSZWRpcyB3aGVuIGNvbmZpZ3VyZWRcbiAgaWYgKGVuYWJsZVJhdGVMaW1pdCkge1xuICAgIGNvbnN0IHJhdGVMaW1pdENvbmZpZyA9IENvbmZpZy5nZXQoJ3JhdGVMaW1pdCcpO1xuXG4gICAgY29uc3QgcmF0ZUxpbWl0T3B0aW9uczogUGFyYW1ldGVyczx0eXBlb2YgcmF0ZUxpbWl0PlswXSA9IHtcbiAgICAgIG1heDogcmF0ZUxpbWl0Q29uZmlnLm1heCxcbiAgICAgIHdpbmRvd01zOiByYXRlTGltaXRDb25maWcud2luZG93TXMsXG4gICAgICBzdGFuZGFyZEhlYWRlcnM6IHRydWUsXG4gICAgICBsZWdhY3lIZWFkZXJzOiBmYWxzZSxcbiAgICAgIC8vIFNraXAgcmF0ZSBsaW1pdGluZyBvbmx5IGZvciBDUllQVE9HUkFQSElDQUxMWS1WRVJJRklFRCBpbnRlcm5hbCBzZXJ2aWNlXG4gICAgICAvLyBjYWxsZXJzLiBUaGUgbGltaXRlciBydW5zIGJlZm9yZSByZXF1aXJlQXV0aCwgc28gdGhlIHByZXZpb3VzbHktdHJ1c3RlZFxuICAgICAgLy8gcGxhaW50ZXh0IGB4LWludGVybmFsLXNlcnZpY2VgIGhlYWRlciB3YXMgc3Bvb2ZhYmxlIGJ5IGFueSBleHRlcm5hbFxuICAgICAgLy8gY2xpZW50IOKGkiB0b3RhbCBieXBhc3MuIHZlcmlmeVNlcnZpY2VQcmluY2lwYWwgdmVyaWZpZXMgdGhlIHNpZ25lZFxuICAgICAgLy8gc2VydmljZSBKV1QgaW5zdGVhZDsgaW50ZXItc2VydmljZSBjYWxsZXJzIGFsbCBzZW5kIG9uZVxuICAgICAgLy8gKGdldFNlcnZpY2VBdXRoSGVhZGVyKS5cbiAgICAgIHNraXA6IChyZXE6IFJlcXVlc3QpID0+IHZlcmlmeVNlcnZpY2VQcmluY2lwYWwocmVxKSxcbiAgICAgIC8vIEtleSBvbiBjbGllbnQgSVAgb25seS4gVGhlIGxpbWl0ZXIgcnVucyBwcmUtYXV0aCwgc28gYHJlcS51c2VyYCBpcyB1bnNldFxuICAgICAgLy8gYW5kIGFueSBvcmcgaWQgd291bGQgY29tZSBmcm9tIHRoZSBjYWxsZXItc3VwcGxpZWQgYHgtb3JnLWlkYCBoZWFkZXIg4oCUXG4gICAgICAvLyBzcG9vZmFibGUsIGxldHRpbmcgYW4gYXR0YWNrZXIgcm90YXRlIHZhbHVlcyB0byBldmFkZSB0aGUgYnVja2V0IG9yXG4gICAgICAvLyBmbG9vZCBhIHZpY3RpbSBvcmcncyBidWNrZXQuIGlwS2V5R2VuZXJhdG9yIG5vcm1hbGl6ZXMgSVB2NiB0byBhIC82NFxuICAgICAgLy8gcHJlZml4IChhbHNvIHJlcXVpcmVkIGJ5IGV4cHJlc3MtcmF0ZS1saW1pdCA4LngncyB2YWxpZGF0b3IpLlxuICAgICAga2V5R2VuZXJhdG9yOiAocmVxOiBSZXF1ZXN0KSA9PiBpcEtleUdlbmVyYXRvcihyZXEuaXAgfHwgJ2Fub24nLCA2NCksXG4gICAgICAvLyBBIHN0b3JlIGZhaWx1cmUgKFJlZGlzIGRvd24gLyBmYWlsaW5nIG92ZXIpIG11c3QgZGVncmFkZSB0byBcIm5vdCByYXRlXG4gICAgICAvLyBsaW1pdGVkXCIsIG5ldmVyIHRvIGEgNTAwIG9uIGV2ZXJ5IHJlcXVlc3Qgb2YgZXZlcnkgc2VydmljZS5cbiAgICAgIHBhc3NPblN0b3JlRXJyb3I6IHRydWUsXG4gICAgICBoYW5kbGVyOiAoX3JlcTogUmVxdWVzdCwgcmVzOiBSZXNwb25zZSkgPT4ge1xuICAgICAgICBzZW5kRXJyb3IocmVzLCA0MjksICdUb28gbWFueSByZXF1ZXN0cywgcGxlYXNlIHRyeSBhZ2FpbiBsYXRlci4nLCBFcnJvckNvZGUuUkFURV9MSU1JVF9FWENFRURFRCk7XG4gICAgICB9LFxuICAgIH07XG5cbiAgICAvLyBTaGFyZWQgc3RhdGUgYWNyb3NzIHJlcGxpY2FzICh0aGUgcHJvY2Vzcy13aWRlIHJhdGUtbGltaXQgUmVkaXMgY29ubmVjdGlvbjtcbiAgICAvLyB1bmRlZmluZWQgd2l0aG91dCBSZWRpcyDihpIgcGVyLXByb2Nlc3MgbWVtb3J5IHN0b3JlLCByaWdodCBmb3Igb25lIHJlcGxpY2EpLlxuICAgIC8vIE5hbWVzcGFjZWQgcGVyIFNFUlZJQ0U6IGV2ZXJ5IHNlcnZpY2Ugc2hhcmVzIG9uZSBSZWRpcywgYW5kIHRoZSBvbGRcbiAgICAvLyB1bnByZWZpeGVkIGBybDo8aXA+YCBrZXkgbGV0IG9uZSBjbGllbnQncyB0cmFmZmljIHRvIEFOWSBzZXJ2aWNlIGRyYWluIGl0c1xuICAgIC8vIGJ1ZGdldCBvbiBFVkVSWSBzZXJ2aWNlLlxuICAgIHJhdGVMaW1pdE9wdGlvbnMuc3RvcmUgPSBjcmVhdGVTaGFyZWRSYXRlTGltaXRTdG9yZShgJHtzZXJ2aWNlTmFtZX06Z2xvYmFsYCk7XG5cbiAgICBhcHAudXNlKHJhdGVMaW1pdChyYXRlTGltaXRPcHRpb25zKSk7XG4gIH1cblxuICAvLyBFeHByZXNzIHJlcXVlc3QgdGltZW91dCDigJQgdXNlcyBDb3JlQ29uc3RhbnRzIHRvIHNoYXJlIHRoZSBzYW1lIGRlZmF1bHQgYXMgTGFtYmRhIGhhbmRsZXJzXG4gIGNvbnN0IHRpbWVvdXRNcyA9IENvcmVDb25zdGFudHMuSEFORExFUl9USU1FT1VUX01TO1xuICBhcHAudXNlKChfcmVxOiBSZXF1ZXN0LCByZXM6IFJlc3BvbnNlLCBuZXh0OiBOZXh0RnVuY3Rpb24pID0+IHtcbiAgICByZXMuc2V0VGltZW91dCh0aW1lb3V0TXMsICgpID0+IHtcbiAgICAgIGlmICghcmVzLmhlYWRlcnNTZW50KSB7XG4gICAgICAgIHNlbmRFcnJvcihyZXMsIDUwMywgJ1JlcXVlc3QgdGltZW91dCcpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIG5leHQoKTtcbiAgfSk7XG5cbiAgLy8gUmVxdWVzdCBkdXJhdGlvbiBsb2dnaW5nXG4gIGNvbnN0IGR1cmF0aW9uTG9nZ2VyID0gY3JlYXRlTG9nZ2VyKCdyZXF1ZXN0LWR1cmF0aW9uJyk7XG4gIGFwcC51c2UoKHJlcTogUmVxdWVzdCwgcmVzOiBSZXNwb25zZSwgbmV4dDogTmV4dEZ1bmN0aW9uKSA9PiB7XG4gICAgY29uc3Qgc3RhcnQgPSBEYXRlLm5vdygpO1xuICAgIHJlcy5vbignZmluaXNoJywgKCkgPT4ge1xuICAgICAgY29uc3QgZHVyYXRpb24gPSBEYXRlLm5vdygpIC0gc3RhcnQ7XG4gICAgICAvLyBMb2cgYHJlcS5wYXRoYCAobm8gcXVlcnkgc3RyaW5nKSDigJQgYSBzdHJheSBgP3Rva2VuPWAvYD90aWNrZXQ9YCBtdXN0IG5vdCBiZVxuICAgICAgLy8gcGVyc2lzdGVkIHZlcmJhdGltIG9uIGV2ZXJ5IHJlcXVlc3QgKG1pcnJvcnMgdGhlIGF1dGh6LWRlbmlhbCBhdWRpdG9yJ3Mgc3RyaXApLlxuICAgICAgZHVyYXRpb25Mb2dnZXIuaW5mbyhgJHtyZXEubWV0aG9kfSAke3JlcS5wYXRofSAke3Jlcy5zdGF0dXNDb2RlfSAke2R1cmF0aW9ufW1zYCwge1xuICAgICAgICBtZXRob2Q6IHJlcS5tZXRob2QsXG4gICAgICAgIHBhdGg6IHJlcS5wYXRoLFxuICAgICAgICBzdGF0dXNDb2RlOiByZXMuc3RhdHVzQ29kZSxcbiAgICAgICAgZHVyYXRpb25NczogZHVyYXRpb24sXG4gICAgICAgIHJlcXVlc3RJZDogcmVxLnJlcXVlc3RJZCxcbiAgICAgIH0pO1xuICAgIH0pO1xuICAgIG5leHQoKTtcbiAgfSk7XG5cbiAgLy8gUHJvbWV0aGV1cyBtZXRyaWNzIG1pZGRsZXdhcmUg4oCUIHJlY29yZHMgcmVxdWVzdCBkdXJhdGlvbiBhbmQgY291bnRcbiAgYXBwLnVzZShtZXRyaWNzTWlkZGxld2FyZSgpKTtcblxuICAvLyBOT1RFOiBpZGVtcG90ZW5jeSBpcyBpbnRlbnRpb25hbGx5IE5PVCBtb3VudGVkIGhlcmUuIEl0IG5lZWRzIHRoZSBWRVJJRklFRFxuICAvLyBvcmcgaWQgdG8gbmFtZXNwYWNlIGl0cyByZXBsYXkgY2FjaGUsIGJ1dCB0aGlzIHByZS1hdXRoIHBvc2l0aW9uIHJ1bnMgYmVmb3JlXG4gIC8vIGByZXF1aXJlQXV0aGAvYGF0dGFjaFJlcXVlc3RDb250ZXh0YCBwb3B1bGF0ZSBpZGVudGl0eSwgc28gYSBnbG9iYWwgbW91bnRcbiAgLy8gaGVyZSBpcyBhIHBlcm1hbmVudCBuby1vcCAob3JnIGFsd2F5cyB1bmRlZmluZWQg4oaSIHNraXApLiBJdCBpcyBpbnN0ZWFkIHdpcmVkXG4gIC8vIGludG8gdGhlIHBvc3QtYXV0aCByb3V0ZSBjaGFpbnMg4oCUIHNlZSBgY3JlYXRlUHJvdGVjdGVkUm91dGVgIC9cbiAgLy8gYGNyZWF0ZUF1dGhlbnRpY2F0ZWRXaXRoT3JnUm91dGVgIGluIG1pZGRsZXdhcmUtZmFjdG9yeS50cy5cblxuICBpZiAobG9nU3RyZWFtKSB7XG4gICAgLy8gU1NFIGxvZ3MgZW5kcG9pbnQg4oCUIHRpY2tldC1nYXRlZCAoV2F2ZSAyYikuXG4gICAgLy8gVGhlIHN0cmVhbSBjYXJyaWVzIHBlci1vcmcgYnVpbGQgbG9ncywgc28gaXQgbXVzdCBub3QgYmUgd29ybGQtcmVhZGFibGUuXG4gICAgLy8gQ2xpZW50cyBmaXJzdCBQT1NUIC9sb2dzL3RpY2tldCAoSldULWF1dGhlbnRpY2F0ZWQpIHRvIG1pbnQgYSBzaG9ydC1saXZlZCxcbiAgICAvLyBzaW5nbGUtdXNlIHRpY2tldCBib3VuZCB0byB0aGVpciBvcmcgQU5EIHRvIHRoZSBzcGVjaWZpYyBgcmVxdWVzdElkYCBzdHJlYW1cbiAgICAvLyB0aGV5IGludGVuZCB0byBvcGVuLCB0aGVuIG9wZW4gdGhlIEV2ZW50U291cmNlIHdpdGggP3RpY2tldD08dD4uIFRoaXMga2VlcHNcbiAgICAvLyB0aGUgSldUIG91dCBvZiBxdWVyeSBzdHJpbmdzIC8gYWNjZXNzIGxvZ3Mgd2hpbGUgZW5mb3JjaW5nIG9yZyBvd25lcnNoaXAsXG4gICAgLy8gcGVyLXN1YmplY3QgYXV0aG9yaXphdGlvbiwgYW5kIHRoZSBwZXItb3JnIGNvbm5lY3Rpb24gY2FwIG9uIHRoZSBzdHJlYW0uXG4gICAgLy8gTWlycm9ycyB0aGUgbWVzc2FnZS1zZXJ2aWNlIG5vdGlmaWNhdGlvbnMgU1NFIHRpY2tldCBleGNoYW5nZS5cbiAgICBhcHAucG9zdCgnL2xvZ3MvdGlja2V0JywgcmVxdWlyZUF1dGgsIGFzeW5jIChyZXE6IFJlcXVlc3QsIHJlczogUmVzcG9uc2UpID0+IHtcbiAgICAgIGNvbnN0IG9yZ0lkID0gcmVxLnVzZXI/Lm9yZ2FuaXphdGlvbklkPy50b0xvd2VyQ2FzZSgpO1xuICAgICAgaWYgKCFvcmdJZCkge1xuICAgICAgICBzZW5kRXJyb3IocmVzLCA0MDAsICdUb2tlbiBtaXNzaW5nIG9yZ2FuaXphdGlvbicsIEVycm9yQ29kZS5WQUxJREFUSU9OX0VSUk9SKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgLy8gVGhlIGNhbGxlciBtdXN0IG5hbWUgdGhlIHN0cmVhbSBzdWJqZWN0IHVwIGZyb250IHNvIHRoZSB0aWNrZXQgaXMgYm91bmQgdG9cbiAgICAgIC8vIGl0LiBXaXRob3V0IHRoaXMsIGEgdGlja2V0IGNvdWxkIGJlIHJlcGxheWVkIGFnYWluc3QgQU5ZIHJlcXVlc3RJZCB0aGVcbiAgICAgIC8vIG9yZyBjb3VsZCBndWVzcywgbGV0dGluZyBpdCBhdHRhY2ggdG8gYW5vdGhlciBvcmcncyBsb2cgc3RyZWFtLiBTdHJpY3RseVxuICAgICAgLy8gZm9ybWF0LXZhbGlkYXRlZCBzbyBpdCBjYW4ndCBjYXJyeSBhbiBpbmplY3Rpb24gcGF5bG9hZCBpbnRvIHRoZSBzdWJqZWN0LlxuICAgICAgY29uc3QgcmVxdWVzdElkID0gKHJlcS5ib2R5IGFzIHsgcmVxdWVzdElkPzogdW5rbm93biB9IHwgdW5kZWZpbmVkKT8ucmVxdWVzdElkO1xuICAgICAgaWYgKHR5cGVvZiByZXF1ZXN0SWQgIT09ICdzdHJpbmcnIHx8ICFTU0VfUkVRVUVTVF9JRF9SRS50ZXN0KHJlcXVlc3RJZCkpIHtcbiAgICAgICAgc2VuZEVycm9yKHJlcywgNDAwLCAnTWlzc2luZyBvciBpbnZhbGlkIHJlcXVlc3RJZCcsIEVycm9yQ29kZS5WQUxJREFUSU9OX0VSUk9SKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgc3NlTWFuYWdlci5jcmVhdGVUaWNrZXQob3JnSWQsIHJlcXVlc3RJZCk7XG4gICAgICBpZiAoIXJlc3VsdC5vaykge1xuICAgICAgICBpZiAocmVzdWx0LnJlYXNvbiA9PT0gJ2ZvcmJpZGRlbicpIHtcbiAgICAgICAgICAvLyBUaGUgc3ViamVjdCBpcyBvd25lZCBieSBhbm90aGVyIG9yZyDigJQgZG8gbm90IGNvbmZpcm0gaXQgZXhpc3RzOyBhIHBsYWluXG4gICAgICAgICAgLy8gNDAzIGlzIGVub3VnaCBhbmQgbGVha3Mgbm90aGluZyBhYm91dCB3aGljaCByZXF1ZXN0SWRzIGFyZSBsaXZlLlxuICAgICAgICAgIHNlbmRFcnJvcihyZXMsIDQwMywgJ05vdCBhdXRob3JpemVkIGZvciB0aGlzIGxvZyBzdHJlYW0nLCBFcnJvckNvZGUuSU5TVUZGSUNJRU5UX1BFUk1JU1NJT05TKTtcbiAgICAgICAgfSBlbHNlIGlmIChyZXN1bHQucmVhc29uID09PSAnb3JnLWxpbWl0Jykge1xuICAgICAgICAgIHNlbmRFcnJvcihyZXMsIDQyOSwgJ1RvbyBtYW55IGxvZyBzdHJlYW0gdGlja2V0cyBpc3N1ZWQnLCBFcnJvckNvZGUuUVVPVEFfRVhDRUVERUQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHNlbmRFcnJvcihyZXMsIDUwMywgJ0xvZyBzdHJlYW1pbmcgc3Vic3lzdGVtIGF0IGNhcGFjaXR5JywgRXJyb3JDb2RlLlFVT1RBX0VYQ0VFREVEKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBzZW5kU3VjY2VzcyhyZXMsIDIwMCwgeyB0aWNrZXQ6IHJlc3VsdC50aWNrZXQgfSk7XG4gICAgfSk7XG5cbiAgICAvLyBUaGUgc3RyZWFtIGl0c2VsZiByZXNvbHZlcyArIGNvbnN1bWVzIHRoZSB0aWNrZXQgaW5zaWRlIG1pZGRsZXdhcmUoKSBhbmRcbiAgICAvLyByZWplY3RzIGFueSBhbm9ueW1vdXMgLyBpbnZhbGlkIC8gZXhwaXJlZCAvIGFscmVhZHktdXNlZCB0aWNrZXQgd2l0aCA0MDEuXG4gICAgYXBwLmdldCgnL2xvZ3MvOnJlcXVlc3RJZCcsIHNzZU1hbmFnZXIubWlkZGxld2FyZSgpKTtcbiAgfVxuXG4gIHJldHVybiB7IGFwcCwgc3NlTWFuYWdlciB9O1xufVxuIl19
@@ -1,6 +1,6 @@
1
1
  // Copyright 2026 Pipeline Builder Contributors
2
2
  // SPDX-License-Identifier: Apache-2.0
3
- import { ErrorCode, createLogger, emitCounter, sendError, sendQuotaExceeded } from '@pipeline-builder/api-core';
3
+ import { ErrorCode, createLogger, emitCounter, getQuotaServiceAuthHeader, sendError, sendQuotaExceeded } from '@pipeline-builder/api-core';
4
4
  import { getContext } from './get-context.js';
5
5
  const logger = createLogger('check-quota');
6
6
  /** Human-readable labels for quota exceeded messages. */
@@ -27,12 +27,18 @@ const QUOTA_LABELS = {
27
27
  */
28
28
  export function checkQuota(quotaService, quotaType) {
29
29
  return async (req, res, next) => {
30
+ // The check is sent with THIS service's credentials, so it must only run for
31
+ // a VERIFIED caller — otherwise the org would come from the spoofable
32
+ // header-derived identity. Mounted after requireAuth everywhere; an
33
+ // unauthenticated request here is a wiring bug, so skip (fail open) loudly.
34
+ if (!req.user) {
35
+ logger.warn('Quota check skipped: request is not authenticated');
36
+ return next();
37
+ }
30
38
  let orgId;
31
- let authHeader = '';
32
39
  try {
33
40
  const ctx = getContext(req);
34
41
  orgId = ctx.identity.orgId;
35
- authHeader = req.headers.authorization || '';
36
42
  }
37
43
  catch {
38
44
  // Context middleware not applied — fail open (log and continue)
@@ -44,7 +50,12 @@ export function checkQuota(quotaService, quotaType) {
44
50
  return;
45
51
  }
46
52
  try {
47
- const quotaStatus = await quotaService.check(orgId, quotaType, authHeader);
53
+ // Authenticate as THIS service, not by forwarding the user's token: the
54
+ // user token 403s at the quota read route for custom roles without
55
+ // `quotas:read`, and (being non-service) counts against the quota
56
+ // service's per-IP limiter keyed on THIS pod's IP — both of which
57
+ // silently fail the gate open under load.
58
+ const quotaStatus = await quotaService.check(orgId, quotaType, getQuotaServiceAuthHeader(orgId));
48
59
  if (!quotaStatus.allowed) {
49
60
  logger.warn(`${quotaType} quota exceeded`, {
50
61
  orgId,
@@ -75,4 +86,4 @@ export function checkQuota(quotaService, quotaType) {
75
86
  }
76
87
  };
77
88
  }
78
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hlY2stcXVvdGEuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXBpL2NoZWNrLXF1b3RhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFFdEMsT0FBTyxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsV0FBVyxFQUFFLFNBQVMsRUFBRSxpQkFBaUIsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBR2hILE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUU5QyxNQUFNLE1BQU0sR0FBRyxZQUFZLENBQUMsYUFBYSxDQUFDLENBQUM7QUFFM0MseURBQXlEO0FBQ3pELE1BQU0sWUFBWSxHQUE4QjtJQUM5QyxRQUFRLEVBQUUsVUFBVTtJQUNwQixPQUFPLEVBQUUsU0FBUztJQUNsQixTQUFTLEVBQUUsVUFBVTtJQUNyQixPQUFPLEVBQUUsUUFBUTtJQUNqQixZQUFZLEVBQUUsa0JBQWtCO0lBQ2hDLFVBQVUsRUFBRSxXQUFXO0lBQ3ZCLFVBQVUsRUFBRSxZQUFZO0lBQ3hCLGlCQUFpQixFQUFFLG1CQUFtQjtJQUN0QyxVQUFVLEVBQUUsbUJBQW1CO0NBQ2hDLENBQUM7QUFFRjs7Ozs7Ozs7O0dBU0c7QUFDSCxNQUFNLFVBQVUsVUFBVSxDQUN4QixZQUEwQixFQUMxQixTQUFvQjtJQUVwQixPQUFPLEtBQUssRUFBRSxHQUFZLEVBQUUsR0FBYSxFQUFFLElBQWtCLEVBQWlCLEVBQUU7UUFDOUUsSUFBSSxLQUF5QixDQUFDO1FBQzlCLElBQUksVUFBVSxHQUFHLEVBQUUsQ0FBQztRQUVwQixJQUFJLENBQUM7WUFDSCxNQUFNLEdBQUcsR0FBRyxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDNUIsS0FBSyxHQUFHLEdBQUcsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDO1lBQzNCLFVBQVUsR0FBRyxHQUFHLENBQUMsT0FBTyxDQUFDLGFBQWEsSUFBSSxFQUFFLENBQUM7UUFDL0MsQ0FBQztRQUFDLE1BQU0sQ0FBQztZQUNQLGdFQUFnRTtZQUNoRSxNQUFNLENBQUMsSUFBSSxDQUFDLHNEQUFzRCxDQUFDLENBQUM7WUFDcEUsT0FBTyxJQUFJLEVBQUUsQ0FBQztRQUNoQixDQUFDO1FBRUQsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ1gsU0FBUyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsNkNBQTZDLEVBQUUsU0FBUyxDQUFDLGdCQUFnQixDQUFDLENBQUM7WUFDL0YsT0FBTztRQUNULENBQUM7UUFFRCxJQUFJLENBQUM7WUFDSCxNQUFNLFdBQVcsR0FBRyxNQUFNLFlBQVksQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLFNBQVMsRUFBRSxVQUFVLENBQUMsQ0FBQztZQUUzRSxJQUFJLENBQUMsV0FBVyxDQUFDLE9BQU8sRUFBRSxDQUFDO2dCQUN6QixNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsU0FBUyxpQkFBaUIsRUFBRTtvQkFDekMsS0FBSztvQkFDTCxLQUFLLEVBQUUsV0FBVyxDQUFDLEtBQUs7b0JBQ3hCLElBQUksRUFBRSxXQUFXLENBQUMsSUFBSTtpQkFDdkIsQ0FBQyxDQUFDO2dCQUVILHVFQUF1RTtnQkFDdkUsc0VBQXNFO2dCQUN0RSw0REFBNEQ7Z0JBQzVELHFDQUFxQztnQkFDckMsaUJBQWlCLENBQ2YsR0FBRyxFQUNILFNBQVMsRUFDVCxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLFdBQVcsQ0FBQyxLQUFLLEVBQUUsSUFBSSxFQUFFLFdBQVcsQ0FBQyxJQUFJLEVBQUUsU0FBUyxFQUFFLFdBQVcsQ0FBQyxTQUFTLEVBQUUsRUFDdkcsV0FBVyxDQUFDLE9BQU8sRUFDbkIsR0FBRyxZQUFZLENBQUMsU0FBUyxDQUFDLDRFQUE0RSxDQUN2RyxDQUFDO2dCQUNGLE9BQU87WUFDVCxDQUFDO1lBRUQsSUFBSSxFQUFFLENBQUM7UUFDVCxDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLGdFQUFnRTtZQUNoRSxNQUFNLENBQUMsSUFBSSxDQUFDLDBEQUEwRCxFQUFFO2dCQUN0RSxLQUFLO2dCQUNMLFNBQVM7Z0JBQ1QsS0FBSyxFQUFFLEtBQUssWUFBWSxLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUM7YUFDOUQsQ0FBQyxDQUFDO1lBQ0gsMEVBQTBFO1lBQzFFLHlFQUF5RTtZQUN6RSwyRUFBMkU7WUFDM0UsV0FBVyxDQUFDLHVCQUF1QixFQUFFLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsV0FBVyxFQUFFLFNBQVMsRUFBRSxDQUFDLENBQUM7WUFDN0YsSUFBSSxFQUFFLENBQUM7UUFDVCxDQUFDO0lBQ0gsQ0FBQyxDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDI2IFBpcGVsaW5lIEJ1aWxkZXIgQ29udHJpYnV0b3JzXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuXG5pbXBvcnQgeyBFcnJvckNvZGUsIGNyZWF0ZUxvZ2dlciwgZW1pdENvdW50ZXIsIHNlbmRFcnJvciwgc2VuZFF1b3RhRXhjZWVkZWQgfSBmcm9tICdAcGlwZWxpbmUtYnVpbGRlci9hcGktY29yZSc7XG5pbXBvcnQgdHlwZSB7IFF1b3RhVHlwZSwgUXVvdGFTZXJ2aWNlIH0gZnJvbSAnQHBpcGVsaW5lLWJ1aWxkZXIvYXBpLWNvcmUnO1xuaW1wb3J0IHR5cGUgeyBSZXF1ZXN0LCBSZXNwb25zZSwgTmV4dEZ1bmN0aW9uIH0gZnJvbSAnZXhwcmVzcyc7XG5pbXBvcnQgeyBnZXRDb250ZXh0IH0gZnJvbSAnLi9nZXQtY29udGV4dC5qcyc7XG5cbmNvbnN0IGxvZ2dlciA9IGNyZWF0ZUxvZ2dlcignY2hlY2stcXVvdGEnKTtcblxuLyoqIEh1bWFuLXJlYWRhYmxlIGxhYmVscyBmb3IgcXVvdGEgZXhjZWVkZWQgbWVzc2FnZXMuICovXG5jb25zdCBRVU9UQV9MQUJFTFM6IFJlY29yZDxRdW90YVR5cGUsIHN0cmluZz4gPSB7XG4gIGFwaUNhbGxzOiAnQVBJIGNhbGwnLFxuICBhaUNhbGxzOiAnQUkgY2FsbCcsXG4gIHBpcGVsaW5lczogJ1BpcGVsaW5lJyxcbiAgcGx1Z2luczogJ1BsdWdpbicsXG4gIHN0b3JhZ2VCeXRlczogJ1JlZ2lzdHJ5IHN0b3JhZ2UnLFxuICBkYXNoYm9hcmRzOiAnRGFzaGJvYXJkJyxcbiAgYWxlcnRSdWxlczogJ0FsZXJ0IHJ1bGUnLFxuICBhbGVydERlc3RpbmF0aW9uczogJ0FsZXJ0IGRlc3RpbmF0aW9uJyxcbiAgaWRwQ29uZmlnczogJ0lkUCBjb25maWd1cmF0aW9uJyxcbn07XG5cbi8qKlxuICogQ3JlYXRlIG1pZGRsZXdhcmUgdGhhdCBjaGVja3MgYSBzcGVjaWZpYyBxdW90YSB0eXBlIGJlZm9yZSBwcm9jZWVkaW5nLlxuICpcbiAqIE9uIHF1b3RhIGV4Y2VlZGVkLCByZXR1cm5zIGEgNDI5IHJlc3BvbnNlIHdpdGggcXVvdGEgZGV0YWlscy5cbiAqIE9uIHF1b3RhIHNlcnZpY2UgZmFpbHVyZSwgZmFpbHMgb3BlbiAoYWxsb3dzIHRoZSByZXF1ZXN0KS5cbiAqXG4gKiBAcGFyYW0gcXVvdGFTZXJ2aWNlIC0gUXVvdGEgc2VydmljZSBjbGllbnRcbiAqIEBwYXJhbSBxdW90YVR5cGUgLSBXaGljaCBxdW90YSB0byBjaGVjayAoZS5nLiAnYXBpQ2FsbHMnLCAncGlwZWxpbmVzJywgJ3BsdWdpbnMnKVxuICogQHJldHVybnMgRXhwcmVzcyBtaWRkbGV3YXJlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjaGVja1F1b3RhKFxuICBxdW90YVNlcnZpY2U6IFF1b3RhU2VydmljZSxcbiAgcXVvdGFUeXBlOiBRdW90YVR5cGUsXG4pIHtcbiAgcmV0dXJuIGFzeW5jIChyZXE6IFJlcXVlc3QsIHJlczogUmVzcG9uc2UsIG5leHQ6IE5leHRGdW5jdGlvbik6IFByb21pc2U8dm9pZD4gPT4ge1xuICAgIGxldCBvcmdJZDogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgIGxldCBhdXRoSGVhZGVyID0gJyc7XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgY3R4ID0gZ2V0Q29udGV4dChyZXEpO1xuICAgICAgb3JnSWQgPSBjdHguaWRlbnRpdHkub3JnSWQ7XG4gICAgICBhdXRoSGVhZGVyID0gcmVxLmhlYWRlcnMuYXV0aG9yaXphdGlvbiB8fCAnJztcbiAgICB9IGNhdGNoIHtcbiAgICAgIC8vIENvbnRleHQgbWlkZGxld2FyZSBub3QgYXBwbGllZCDigJQgZmFpbCBvcGVuIChsb2cgYW5kIGNvbnRpbnVlKVxuICAgICAgbG9nZ2VyLndhcm4oJ1F1b3RhIGNoZWNrIHNraXBwZWQ6IHJlcXVlc3QgY29udGV4dCBub3QgaW5pdGlhbGl6ZWQnKTtcbiAgICAgIHJldHVybiBuZXh0KCk7XG4gICAgfVxuXG4gICAgaWYgKCFvcmdJZCkge1xuICAgICAgc2VuZEVycm9yKHJlcywgNDAwLCAnT3JnYW5pemF0aW9uIElEIGlzIHJlcXVpcmVkIGZvciBxdW90YSBjaGVjaycsIEVycm9yQ29kZS5WQUxJREFUSU9OX0VSUk9SKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgcXVvdGFTdGF0dXMgPSBhd2FpdCBxdW90YVNlcnZpY2UuY2hlY2sob3JnSWQsIHF1b3RhVHlwZSwgYXV0aEhlYWRlcik7XG5cbiAgICAgIGlmICghcXVvdGFTdGF0dXMuYWxsb3dlZCkge1xuICAgICAgICBsb2dnZXIud2FybihgJHtxdW90YVR5cGV9IHF1b3RhIGV4Y2VlZGVkYCwge1xuICAgICAgICAgIG9yZ0lkLFxuICAgICAgICAgIGxpbWl0OiBxdW90YVN0YXR1cy5saW1pdCxcbiAgICAgICAgICB1c2VkOiBxdW90YVN0YXR1cy51c2VkLFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBSb3V0ZSB0aHJvdWdoIHRoZSBzaGFyZWQgaGVscGVyIHNvIHRoZSBjaGVjay1nYXRlIDQyOSBlbWl0cyB0aGUgc2FtZVxuICAgICAgICAvLyBSZXRyeS1BZnRlciArIFgtUXVvdGEtKiBoZWFkZXJzIGFzIHRoZSByZXNlcnZlLXBhdGggNDI5ICh0aGUgaW5saW5lXG4gICAgICAgIC8vIDQyOSB0aGlzIHJlcGxhY2VkIG9taXR0ZWQgdGhlbSkuIEN1c3RvbSBtZXNzYWdlIGtlZXBzIHRoZVxuICAgICAgICAvLyBcImNvbnRhY3QgeW91ciBhZG1pbmlzdHJhdG9yXCIgY29weS5cbiAgICAgICAgc2VuZFF1b3RhRXhjZWVkZWQoXG4gICAgICAgICAgcmVzLFxuICAgICAgICAgIHF1b3RhVHlwZSxcbiAgICAgICAgICB7IHR5cGU6IHF1b3RhVHlwZSwgbGltaXQ6IHF1b3RhU3RhdHVzLmxpbWl0LCB1c2VkOiBxdW90YVN0YXR1cy51c2VkLCByZW1haW5pbmc6IHF1b3RhU3RhdHVzLnJlbWFpbmluZyB9LFxuICAgICAgICAgIHF1b3RhU3RhdHVzLnJlc2V0QXQsXG4gICAgICAgICAgYCR7UVVPVEFfTEFCRUxTW3F1b3RhVHlwZV19IHF1b3RhIGV4Y2VlZGVkLiBQbGVhc2UgY29udGFjdCB5b3VyIGFkbWluaXN0cmF0b3IgdG8gaW5jcmVhc2UgeW91ciBxdW90YS5gLFxuICAgICAgICApO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIG5leHQoKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgLy8gRmFpbCBvcGVuIOKAlCBhbGxvdyB0aGUgcmVxdWVzdCBpZiBxdW90YSBzZXJ2aWNlIGlzIHVuYXZhaWxhYmxlXG4gICAgICBsb2dnZXIud2FybignUVVPVEFfRkFJTF9PUEVOOiBRdW90YSBjaGVjayBleGNlcHRpb24sIGFsbG93aW5nIHJlcXVlc3QnLCB7XG4gICAgICAgIG9yZ0lkLFxuICAgICAgICBxdW90YVR5cGUsXG4gICAgICAgIGVycm9yOiBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFN0cmluZyhlcnJvciksXG4gICAgICB9KTtcbiAgICAgIC8vIFNhbWUgY291bnRlciB0aGUgYXBpLWNvcmUgcXVvdGEgY2xpZW50IGVtaXRzLCBzbyBhIHF1b3RhLXNlcnZpY2Ugb3V0YWdlXG4gICAgICAvLyBpcyBBTEVSVEFCTEUgZnJvbSBvbmUgc2VyaWVzIHJlZ2FyZGxlc3Mgb2Ygd2hpY2ggbGF5ZXIgZmVsbCBvcGVuLiBPbmx5XG4gICAgICAvLyBhIGxvZyBsaW5lIGhlcmUgbWVhbnQgZXZlcnkgb3JnIHdhcyBzaWxlbnRseSB1bi1iaWxsZWQgZm9yIHRoZSBkdXJhdGlvbi5cbiAgICAgIGVtaXRDb3VudGVyKCdxdW90YV9mYWlsX29wZW5fdG90YWwnLCB7IG9wZXJhdGlvbjogJ2NoZWNrJywgcmVhc29uOiAnZXhjZXB0aW9uJywgcXVvdGFUeXBlIH0pO1xuICAgICAgbmV4dCgpO1xuICAgIH1cbiAgfTtcbn1cbiJdfQ==
89
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hlY2stcXVvdGEuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXBpL2NoZWNrLXF1b3RhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFFdEMsT0FBTyxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsV0FBVyxFQUFFLHlCQUF5QixFQUFFLFNBQVMsRUFBRSxpQkFBaUIsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBRzNJLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUU5QyxNQUFNLE1BQU0sR0FBRyxZQUFZLENBQUMsYUFBYSxDQUFDLENBQUM7QUFFM0MseURBQXlEO0FBQ3pELE1BQU0sWUFBWSxHQUE4QjtJQUM5QyxRQUFRLEVBQUUsVUFBVTtJQUNwQixPQUFPLEVBQUUsU0FBUztJQUNsQixTQUFTLEVBQUUsVUFBVTtJQUNyQixPQUFPLEVBQUUsUUFBUTtJQUNqQixZQUFZLEVBQUUsa0JBQWtCO0lBQ2hDLFVBQVUsRUFBRSxXQUFXO0lBQ3ZCLFVBQVUsRUFBRSxZQUFZO0lBQ3hCLGlCQUFpQixFQUFFLG1CQUFtQjtJQUN0QyxVQUFVLEVBQUUsbUJBQW1CO0NBQ2hDLENBQUM7QUFFRjs7Ozs7Ozs7O0dBU0c7QUFDSCxNQUFNLFVBQVUsVUFBVSxDQUN4QixZQUEwQixFQUMxQixTQUFvQjtJQUVwQixPQUFPLEtBQUssRUFBRSxHQUFZLEVBQUUsR0FBYSxFQUFFLElBQWtCLEVBQWlCLEVBQUU7UUFDOUUsNkVBQTZFO1FBQzdFLHNFQUFzRTtRQUN0RSxvRUFBb0U7UUFDcEUsNEVBQTRFO1FBQzVFLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDZCxNQUFNLENBQUMsSUFBSSxDQUFDLG1EQUFtRCxDQUFDLENBQUM7WUFDakUsT0FBTyxJQUFJLEVBQUUsQ0FBQztRQUNoQixDQUFDO1FBRUQsSUFBSSxLQUF5QixDQUFDO1FBRTlCLElBQUksQ0FBQztZQUNILE1BQU0sR0FBRyxHQUFHLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUM1QixLQUFLLEdBQUcsR0FBRyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUM7UUFDN0IsQ0FBQztRQUFDLE1BQU0sQ0FBQztZQUNQLGdFQUFnRTtZQUNoRSxNQUFNLENBQUMsSUFBSSxDQUFDLHNEQUFzRCxDQUFDLENBQUM7WUFDcEUsT0FBTyxJQUFJLEVBQUUsQ0FBQztRQUNoQixDQUFDO1FBRUQsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ1gsU0FBUyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsNkNBQTZDLEVBQUUsU0FBUyxDQUFDLGdCQUFnQixDQUFDLENBQUM7WUFDL0YsT0FBTztRQUNULENBQUM7UUFFRCxJQUFJLENBQUM7WUFDSCx3RUFBd0U7WUFDeEUsbUVBQW1FO1lBQ25FLGtFQUFrRTtZQUNsRSxrRUFBa0U7WUFDbEUsMENBQTBDO1lBQzFDLE1BQU0sV0FBVyxHQUFHLE1BQU0sWUFBWSxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsU0FBUyxFQUFFLHlCQUF5QixDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7WUFFakcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxPQUFPLEVBQUUsQ0FBQztnQkFDekIsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLFNBQVMsaUJBQWlCLEVBQUU7b0JBQ3pDLEtBQUs7b0JBQ0wsS0FBSyxFQUFFLFdBQVcsQ0FBQyxLQUFLO29CQUN4QixJQUFJLEVBQUUsV0FBVyxDQUFDLElBQUk7aUJBQ3ZCLENBQUMsQ0FBQztnQkFFSCx1RUFBdUU7Z0JBQ3ZFLHNFQUFzRTtnQkFDdEUsNERBQTREO2dCQUM1RCxxQ0FBcUM7Z0JBQ3JDLGlCQUFpQixDQUNmLEdBQUcsRUFDSCxTQUFTLEVBQ1QsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxXQUFXLENBQUMsS0FBSyxFQUFFLElBQUksRUFBRSxXQUFXLENBQUMsSUFBSSxFQUFFLFNBQVMsRUFBRSxXQUFXLENBQUMsU0FBUyxFQUFFLEVBQ3ZHLFdBQVcsQ0FBQyxPQUFPLEVBQ25CLEdBQUcsWUFBWSxDQUFDLFNBQVMsQ0FBQyw0RUFBNEUsQ0FDdkcsQ0FBQztnQkFDRixPQUFPO1lBQ1QsQ0FBQztZQUVELElBQUksRUFBRSxDQUFDO1FBQ1QsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixnRUFBZ0U7WUFDaEUsTUFBTSxDQUFDLElBQUksQ0FBQywwREFBMEQsRUFBRTtnQkFDdEUsS0FBSztnQkFDTCxTQUFTO2dCQUNULEtBQUssRUFBRSxLQUFLLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDO2FBQzlELENBQUMsQ0FBQztZQUNILDBFQUEwRTtZQUMxRSx5RUFBeUU7WUFDekUsMkVBQTJFO1lBQzNFLFdBQVcsQ0FBQyx1QkFBdUIsRUFBRSxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLFdBQVcsRUFBRSxTQUFTLEVBQUUsQ0FBQyxDQUFDO1lBQzdGLElBQUksRUFBRSxDQUFDO1FBQ1QsQ0FBQztJQUNILENBQUMsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuaW1wb3J0IHsgRXJyb3JDb2RlLCBjcmVhdGVMb2dnZXIsIGVtaXRDb3VudGVyLCBnZXRRdW90YVNlcnZpY2VBdXRoSGVhZGVyLCBzZW5kRXJyb3IsIHNlbmRRdW90YUV4Y2VlZGVkIH0gZnJvbSAnQHBpcGVsaW5lLWJ1aWxkZXIvYXBpLWNvcmUnO1xuaW1wb3J0IHR5cGUgeyBRdW90YVR5cGUsIFF1b3RhU2VydmljZSB9IGZyb20gJ0BwaXBlbGluZS1idWlsZGVyL2FwaS1jb3JlJztcbmltcG9ydCB0eXBlIHsgUmVxdWVzdCwgUmVzcG9uc2UsIE5leHRGdW5jdGlvbiB9IGZyb20gJ2V4cHJlc3MnO1xuaW1wb3J0IHsgZ2V0Q29udGV4dCB9IGZyb20gJy4vZ2V0LWNvbnRleHQuanMnO1xuXG5jb25zdCBsb2dnZXIgPSBjcmVhdGVMb2dnZXIoJ2NoZWNrLXF1b3RhJyk7XG5cbi8qKiBIdW1hbi1yZWFkYWJsZSBsYWJlbHMgZm9yIHF1b3RhIGV4Y2VlZGVkIG1lc3NhZ2VzLiAqL1xuY29uc3QgUVVPVEFfTEFCRUxTOiBSZWNvcmQ8UXVvdGFUeXBlLCBzdHJpbmc+ID0ge1xuICBhcGlDYWxsczogJ0FQSSBjYWxsJyxcbiAgYWlDYWxsczogJ0FJIGNhbGwnLFxuICBwaXBlbGluZXM6ICdQaXBlbGluZScsXG4gIHBsdWdpbnM6ICdQbHVnaW4nLFxuICBzdG9yYWdlQnl0ZXM6ICdSZWdpc3RyeSBzdG9yYWdlJyxcbiAgZGFzaGJvYXJkczogJ0Rhc2hib2FyZCcsXG4gIGFsZXJ0UnVsZXM6ICdBbGVydCBydWxlJyxcbiAgYWxlcnREZXN0aW5hdGlvbnM6ICdBbGVydCBkZXN0aW5hdGlvbicsXG4gIGlkcENvbmZpZ3M6ICdJZFAgY29uZmlndXJhdGlvbicsXG59O1xuXG4vKipcbiAqIENyZWF0ZSBtaWRkbGV3YXJlIHRoYXQgY2hlY2tzIGEgc3BlY2lmaWMgcXVvdGEgdHlwZSBiZWZvcmUgcHJvY2VlZGluZy5cbiAqXG4gKiBPbiBxdW90YSBleGNlZWRlZCwgcmV0dXJucyBhIDQyOSByZXNwb25zZSB3aXRoIHF1b3RhIGRldGFpbHMuXG4gKiBPbiBxdW90YSBzZXJ2aWNlIGZhaWx1cmUsIGZhaWxzIG9wZW4gKGFsbG93cyB0aGUgcmVxdWVzdCkuXG4gKlxuICogQHBhcmFtIHF1b3RhU2VydmljZSAtIFF1b3RhIHNlcnZpY2UgY2xpZW50XG4gKiBAcGFyYW0gcXVvdGFUeXBlIC0gV2hpY2ggcXVvdGEgdG8gY2hlY2sgKGUuZy4gJ2FwaUNhbGxzJywgJ3BpcGVsaW5lcycsICdwbHVnaW5zJylcbiAqIEByZXR1cm5zIEV4cHJlc3MgbWlkZGxld2FyZVxuICovXG5leHBvcnQgZnVuY3Rpb24gY2hlY2tRdW90YShcbiAgcXVvdGFTZXJ2aWNlOiBRdW90YVNlcnZpY2UsXG4gIHF1b3RhVHlwZTogUXVvdGFUeXBlLFxuKSB7XG4gIHJldHVybiBhc3luYyAocmVxOiBSZXF1ZXN0LCByZXM6IFJlc3BvbnNlLCBuZXh0OiBOZXh0RnVuY3Rpb24pOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgICAvLyBUaGUgY2hlY2sgaXMgc2VudCB3aXRoIFRISVMgc2VydmljZSdzIGNyZWRlbnRpYWxzLCBzbyBpdCBtdXN0IG9ubHkgcnVuIGZvclxuICAgIC8vIGEgVkVSSUZJRUQgY2FsbGVyIOKAlCBvdGhlcndpc2UgdGhlIG9yZyB3b3VsZCBjb21lIGZyb20gdGhlIHNwb29mYWJsZVxuICAgIC8vIGhlYWRlci1kZXJpdmVkIGlkZW50aXR5LiBNb3VudGVkIGFmdGVyIHJlcXVpcmVBdXRoIGV2ZXJ5d2hlcmU7IGFuXG4gICAgLy8gdW5hdXRoZW50aWNhdGVkIHJlcXVlc3QgaGVyZSBpcyBhIHdpcmluZyBidWcsIHNvIHNraXAgKGZhaWwgb3BlbikgbG91ZGx5LlxuICAgIGlmICghcmVxLnVzZXIpIHtcbiAgICAgIGxvZ2dlci53YXJuKCdRdW90YSBjaGVjayBza2lwcGVkOiByZXF1ZXN0IGlzIG5vdCBhdXRoZW50aWNhdGVkJyk7XG4gICAgICByZXR1cm4gbmV4dCgpO1xuICAgIH1cblxuICAgIGxldCBvcmdJZDogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGN0eCA9IGdldENvbnRleHQocmVxKTtcbiAgICAgIG9yZ0lkID0gY3R4LmlkZW50aXR5Lm9yZ0lkO1xuICAgIH0gY2F0Y2gge1xuICAgICAgLy8gQ29udGV4dCBtaWRkbGV3YXJlIG5vdCBhcHBsaWVkIOKAlCBmYWlsIG9wZW4gKGxvZyBhbmQgY29udGludWUpXG4gICAgICBsb2dnZXIud2FybignUXVvdGEgY2hlY2sgc2tpcHBlZDogcmVxdWVzdCBjb250ZXh0IG5vdCBpbml0aWFsaXplZCcpO1xuICAgICAgcmV0dXJuIG5leHQoKTtcbiAgICB9XG5cbiAgICBpZiAoIW9yZ0lkKSB7XG4gICAgICBzZW5kRXJyb3IocmVzLCA0MDAsICdPcmdhbml6YXRpb24gSUQgaXMgcmVxdWlyZWQgZm9yIHF1b3RhIGNoZWNrJywgRXJyb3JDb2RlLlZBTElEQVRJT05fRVJST1IpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICAvLyBBdXRoZW50aWNhdGUgYXMgVEhJUyBzZXJ2aWNlLCBub3QgYnkgZm9yd2FyZGluZyB0aGUgdXNlcidzIHRva2VuOiB0aGVcbiAgICAgIC8vIHVzZXIgdG9rZW4gNDAzcyBhdCB0aGUgcXVvdGEgcmVhZCByb3V0ZSBmb3IgY3VzdG9tIHJvbGVzIHdpdGhvdXRcbiAgICAgIC8vIGBxdW90YXM6cmVhZGAsIGFuZCAoYmVpbmcgbm9uLXNlcnZpY2UpIGNvdW50cyBhZ2FpbnN0IHRoZSBxdW90YVxuICAgICAgLy8gc2VydmljZSdzIHBlci1JUCBsaW1pdGVyIGtleWVkIG9uIFRISVMgcG9kJ3MgSVAg4oCUIGJvdGggb2Ygd2hpY2hcbiAgICAgIC8vIHNpbGVudGx5IGZhaWwgdGhlIGdhdGUgb3BlbiB1bmRlciBsb2FkLlxuICAgICAgY29uc3QgcXVvdGFTdGF0dXMgPSBhd2FpdCBxdW90YVNlcnZpY2UuY2hlY2sob3JnSWQsIHF1b3RhVHlwZSwgZ2V0UXVvdGFTZXJ2aWNlQXV0aEhlYWRlcihvcmdJZCkpO1xuXG4gICAgICBpZiAoIXF1b3RhU3RhdHVzLmFsbG93ZWQpIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oYCR7cXVvdGFUeXBlfSBxdW90YSBleGNlZWRlZGAsIHtcbiAgICAgICAgICBvcmdJZCxcbiAgICAgICAgICBsaW1pdDogcXVvdGFTdGF0dXMubGltaXQsXG4gICAgICAgICAgdXNlZDogcXVvdGFTdGF0dXMudXNlZCxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gUm91dGUgdGhyb3VnaCB0aGUgc2hhcmVkIGhlbHBlciBzbyB0aGUgY2hlY2stZ2F0ZSA0MjkgZW1pdHMgdGhlIHNhbWVcbiAgICAgICAgLy8gUmV0cnktQWZ0ZXIgKyBYLVF1b3RhLSogaGVhZGVycyBhcyB0aGUgcmVzZXJ2ZS1wYXRoIDQyOSAodGhlIGlubGluZVxuICAgICAgICAvLyA0MjkgdGhpcyByZXBsYWNlZCBvbWl0dGVkIHRoZW0pLiBDdXN0b20gbWVzc2FnZSBrZWVwcyB0aGVcbiAgICAgICAgLy8gXCJjb250YWN0IHlvdXIgYWRtaW5pc3RyYXRvclwiIGNvcHkuXG4gICAgICAgIHNlbmRRdW90YUV4Y2VlZGVkKFxuICAgICAgICAgIHJlcyxcbiAgICAgICAgICBxdW90YVR5cGUsXG4gICAgICAgICAgeyB0eXBlOiBxdW90YVR5cGUsIGxpbWl0OiBxdW90YVN0YXR1cy5saW1pdCwgdXNlZDogcXVvdGFTdGF0dXMudXNlZCwgcmVtYWluaW5nOiBxdW90YVN0YXR1cy5yZW1haW5pbmcgfSxcbiAgICAgICAgICBxdW90YVN0YXR1cy5yZXNldEF0LFxuICAgICAgICAgIGAke1FVT1RBX0xBQkVMU1txdW90YVR5cGVdfSBxdW90YSBleGNlZWRlZC4gUGxlYXNlIGNvbnRhY3QgeW91ciBhZG1pbmlzdHJhdG9yIHRvIGluY3JlYXNlIHlvdXIgcXVvdGEuYCxcbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBuZXh0KCk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIC8vIEZhaWwgb3BlbiDigJQgYWxsb3cgdGhlIHJlcXVlc3QgaWYgcXVvdGEgc2VydmljZSBpcyB1bmF2YWlsYWJsZVxuICAgICAgbG9nZ2VyLndhcm4oJ1FVT1RBX0ZBSUxfT1BFTjogUXVvdGEgY2hlY2sgZXhjZXB0aW9uLCBhbGxvd2luZyByZXF1ZXN0Jywge1xuICAgICAgICBvcmdJZCxcbiAgICAgICAgcXVvdGFUeXBlLFxuICAgICAgICBlcnJvcjogZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpLFxuICAgICAgfSk7XG4gICAgICAvLyBTYW1lIGNvdW50ZXIgdGhlIGFwaS1jb3JlIHF1b3RhIGNsaWVudCBlbWl0cywgc28gYSBxdW90YS1zZXJ2aWNlIG91dGFnZVxuICAgICAgLy8gaXMgQUxFUlRBQkxFIGZyb20gb25lIHNlcmllcyByZWdhcmRsZXNzIG9mIHdoaWNoIGxheWVyIGZlbGwgb3Blbi4gT25seVxuICAgICAgLy8gYSBsb2cgbGluZSBoZXJlIG1lYW50IGV2ZXJ5IG9yZyB3YXMgc2lsZW50bHkgdW4tYmlsbGVkIGZvciB0aGUgZHVyYXRpb24uXG4gICAgICBlbWl0Q291bnRlcigncXVvdGFfZmFpbF9vcGVuX3RvdGFsJywgeyBvcGVyYXRpb246ICdjaGVjaycsIHJlYXNvbjogJ2V4Y2VwdGlvbicsIHF1b3RhVHlwZSB9KTtcbiAgICAgIG5leHQoKTtcbiAgICB9XG4gIH07XG59XG4iXX0=
@@ -51,7 +51,7 @@ export interface RedisIdempotencyClient {
51
51
  export declare function createRedisIdempotencyStore(redis: RedisIdempotencyClient): IdempotencyStore;
52
52
  /**
53
53
  * Build a Redis-backed idempotency store from the shared env Redis (the same
54
- * `REDIS_URL` / `REDIS_HOST` wiring the rate-limiter and audit-spool use).
54
+ * `REDIS_URL` / `REDIS_SENTINELS` wiring the rate-limiter and audit-spool use).
55
55
  * Returns `null` when Redis isn't configured/available so the caller keeps the
56
56
  * in-memory default (single-replica correctness). Never throws.
57
57
  */