@pipeline-builder/api-core 3.4.126 → 4.0.1

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.
Files changed (54) hide show
  1. package/README.md +2 -2
  2. package/lib/constants/ai-providers.d.ts +18 -0
  3. package/lib/constants/ai-providers.js +51 -1
  4. package/lib/helpers/access-helpers.d.ts +52 -11
  5. package/lib/helpers/access-helpers.js +63 -18
  6. package/lib/helpers/restore-helpers.d.ts +8 -5
  7. package/lib/helpers/restore-helpers.js +12 -10
  8. package/lib/index.d.ts +1 -1
  9. package/lib/index.js +2 -2
  10. package/lib/middleware/auth.d.ts +11 -13
  11. package/lib/middleware/auth.js +61 -21
  12. package/lib/openapi/routes/ask-routes.d.ts +7 -0
  13. package/lib/openapi/routes/ask-routes.js +62 -0
  14. package/lib/openapi/routes/image-registry-routes.d.ts +7 -0
  15. package/lib/openapi/routes/image-registry-routes.js +98 -0
  16. package/lib/openapi/routes/index.js +8 -1
  17. package/lib/openapi/routes/pipeline-routes.js +10 -1
  18. package/lib/openapi/routes/pipeline-template-routes.js +8 -6
  19. package/lib/openapi/schema-registry.js +4 -4
  20. package/lib/services/circuit-breaker.d.ts +45 -0
  21. package/lib/services/circuit-breaker.js +138 -0
  22. package/lib/services/durable-event-bus.d.ts +96 -0
  23. package/lib/services/durable-event-bus.js +204 -0
  24. package/lib/services/http-client.js +42 -2
  25. package/lib/services/index.d.ts +2 -0
  26. package/lib/services/index.js +3 -1
  27. package/lib/services/quota.js +8 -1
  28. package/lib/services/remote-audit-client.d.ts +1 -1
  29. package/lib/services/remote-audit-client.js +7 -1
  30. package/lib/services/sse-ticket-store.d.ts +7 -0
  31. package/lib/services/sse-ticket-store.js +10 -5
  32. package/lib/services/token-revocation.js +10 -1
  33. package/lib/types/index.d.ts +1 -0
  34. package/lib/types/index.js +2 -1
  35. package/lib/types/permissions.d.ts +1 -1
  36. package/lib/types/permissions.js +6 -3
  37. package/lib/types/pipeline.d.ts +0 -11
  38. package/lib/types/pipeline.js +1 -11
  39. package/lib/types/visibility.d.ts +20 -0
  40. package/lib/types/visibility.js +22 -0
  41. package/lib/utils/audit.js +1 -1
  42. package/lib/utils/response.js +6 -3
  43. package/lib/validation/ai-schemas.d.ts +2 -1
  44. package/lib/validation/ai-schemas.js +3 -3
  45. package/lib/validation/common-schemas.d.ts +8 -6
  46. package/lib/validation/common-schemas.js +8 -7
  47. package/lib/validation/message-schemas.d.ts +2 -1
  48. package/lib/validation/pipeline-schemas.d.ts +6 -3
  49. package/lib/validation/pipeline-schemas.js +4 -4
  50. package/lib/validation/pipeline-template-schemas.d.ts +9 -6
  51. package/lib/validation/pipeline-template-schemas.js +5 -4
  52. package/lib/validation/plugin-schemas.d.ts +8 -4
  53. package/lib/validation/plugin-schemas.js +5 -5
  54. package/package.json +1 -1
@@ -8,6 +8,7 @@ import { hasPermission } from '../types/permissions.js';
8
8
  import { getHeaderString } from '../utils/headers.js';
9
9
  import { getIdentity } from '../utils/identity.js';
10
10
  import { createLogger } from '../utils/logger.js';
11
+ import { emitCounter } from '../utils/metric-emitter.js';
11
12
  import { sendError } from '../utils/response.js';
12
13
  const logger = createLogger('auth-middleware');
13
14
  /** Cached JWT secret with periodic refresh from env var. */
@@ -105,7 +106,11 @@ let tokenRevocationStore;
105
106
  */
106
107
  export function setTokenRevocationStore(store) {
107
108
  tokenRevocationStore = store;
109
+ if (store)
110
+ revocationStoreMissingWarned = false; // re-arm if a store is (re)registered
108
111
  }
112
+ /** One-shot guard so the "revocation inactive" warning doesn't flood the logs. */
113
+ let revocationStoreMissingWarned = false;
109
114
  /**
110
115
  * Returns true when `decoded` has been revoked per the registered store: its
111
116
  * embedded `tokenVersion` is strictly behind the store's current version.
@@ -114,7 +119,18 @@ export function setTokenRevocationStore(store) {
114
119
  */
115
120
  async function isTokenRevoked(decoded) {
116
121
  const store = tokenRevocationStore;
117
- if (!store || !decoded.sub || typeof decoded.tokenVersion !== 'number')
122
+ if (!store) {
123
+ // Make the "revocation is OFF" state OBSERVABLE: a service that verifies user
124
+ // tokens but forgot `setTokenRevocationStore()` silently disables the session
125
+ // kill-switch. Warn ONCE (only for a revocable user token) so a misconfigured
126
+ // boot surfaces in the logs instead of failing open invisibly.
127
+ if (!revocationStoreMissingWarned && decoded.sub && typeof decoded.tokenVersion === 'number') {
128
+ revocationStoreMissingWarned = true;
129
+ logger.warn('Token revocation store NOT registered — revocation checks are INACTIVE (setTokenRevocationStore was never called); revoked/compromised sessions stay valid until natural TTL');
130
+ }
131
+ return false;
132
+ }
133
+ if (!decoded.sub || typeof decoded.tokenVersion !== 'number')
118
134
  return false;
119
135
  try {
120
136
  const current = await store.getCurrentVersion(decoded.sub);
@@ -169,6 +185,17 @@ function _requireAuth(options, req, res, next) {
169
185
  if (!decoded.sub || !decoded.role) {
170
186
  return sendError(res, HttpStatus.UNAUTHORIZED, 'Token missing required fields', ErrorCode.TOKEN_INVALID);
171
187
  }
188
+ // Service-token kill-switch: reject a service principal whose service has
189
+ // been added to the denylist. Rotating the shared JWT secret is the only
190
+ // other way to invalidate a service token before its (short) TTL — but that
191
+ // nukes EVERY service token fleet-wide. This lets one compromised/rogue
192
+ // service be cut off surgically. O(1) Set lookup, zero cost when the denylist
193
+ // is empty (the default), so it never taxes the S2S hot path unless armed.
194
+ if (decoded.sub.startsWith('service:') && isServiceTokenDenied(decoded.sub)) {
195
+ emitCounter('service_token_denied_total', { service: decoded.sub.slice('service:'.length) });
196
+ logger.warn('Rejected denylisted service token', { sub: decoded.sub });
197
+ return sendError(res, HttpStatus.UNAUTHORIZED, 'Service token revoked', ErrorCode.TOKEN_REVOKED);
198
+ }
172
199
  req.user = { ...decoded };
173
200
  // The x-org-id/x-org-name override lets a SYS-ADMIN act on a chosen org
174
201
  // (cross-org admin tooling). It is gated on the verified `isSuperAdmin` claim
@@ -439,24 +466,6 @@ export function requireFeature(feature) {
439
466
  next();
440
467
  };
441
468
  }
442
- /**
443
- * Resolve the effective access modifier for an entity being created/updated.
444
- * 'public' is permitted only for a caller holding the relevant publish
445
- * capability (`pipelines:publish` / `plugins:publish`) — superadmins pass via
446
- * implicit-all. Everyone else (including callers who requested 'public' without
447
- * the permission, and service principals) gets 'private'.
448
- *
449
- * Permission-based (not coarse-role-based): a bespoke custom Role can be granted
450
- * publish rights and is no longer forced private by its `member` label. Built-in
451
- * Admin/Owner bundles carry the publish permissions, so their behavior is
452
- * unchanged; the built-in Member bundle does not, so members stay private-only.
453
- */
454
- export function resolveAccessModifier(req, requested, publishPermission) {
455
- if (requested === 'public' && userHasPermission(req, publishPermission)) {
456
- return 'public';
457
- }
458
- return 'private';
459
- }
460
469
  // ---------------------------------------------------------------------------
461
470
  // Service-to-service tokens
462
471
  //
@@ -472,6 +481,29 @@ export function resolveAccessModifier(req, requested, publishPermission) {
472
481
  // short enough that a leaked token is low-value.
473
482
  // ---------------------------------------------------------------------------
474
483
  const DEFAULT_SERVICE_TOKEN_TTL_SECONDS = 300;
484
+ /**
485
+ * Denylist of service NAMES (the `<name>` in `sub: service:<name>`) whose tokens
486
+ * `requireAuth` must reject. Seeded from `SERVICE_TOKEN_DENYLIST` (comma-separated)
487
+ * at module load; a service can push live updates (e.g. from a Redis-subscribed
488
+ * kill-switch) via {@link setServiceTokenDenylist} so a compromised service can be
489
+ * cut off WITHOUT rotating the shared JWT secret (which invalidates all of them).
490
+ */
491
+ let serviceTokenDenylist = new Set((process.env.SERVICE_TOKEN_DENYLIST || '')
492
+ .split(',')
493
+ .map((s) => s.trim())
494
+ .filter(Boolean));
495
+ /** Replace the service-token denylist (service names). Empty ⇒ kill-switch off. */
496
+ export function setServiceTokenDenylist(names) {
497
+ serviceTokenDenylist = new Set([...names].map((s) => s.trim()).filter(Boolean));
498
+ }
499
+ /** True when `sub` is `service:<name>` and `<name>` is on the denylist. */
500
+ export function isServiceTokenDenied(sub) {
501
+ if (serviceTokenDenylist.size === 0)
502
+ return false;
503
+ if (!sub.startsWith('service:'))
504
+ return false;
505
+ return serviceTokenDenylist.has(sub.slice('service:'.length));
506
+ }
475
507
  /**
476
508
  * Mint a JWT identifying the calling service. Used for inter-service HTTP calls.
477
509
  * The token satisfies `requireAuth` and (when orgId is present) `requireOrganization`.
@@ -488,6 +520,9 @@ export function signServiceToken(opts) {
488
520
  type: 'access',
489
521
  organizationId: opts.orgId,
490
522
  organizationName: opts.orgName ?? opts.orgId,
523
+ // Least-privilege capability claim (optional) — lets a member-role token
524
+ // satisfy a specific permission gate without carrying isAdmin.
525
+ ...(opts.permissions && opts.permissions.length > 0 ? { permissions: opts.permissions } : {}),
491
526
  };
492
527
  // Match the optional issuer/audience that requireAuth verifies, when
493
528
  // configured. Without these, a service token signed here would fail
@@ -539,10 +574,15 @@ export function verifyServicePrincipal(req) {
539
574
  if (process.env.JWT_AUDIENCE)
540
575
  verifyOptions.audience = process.env.JWT_AUDIENCE;
541
576
  const decoded = verifyJwtWithRotation(parts[1], verifyOptions);
542
- return decoded.type === 'access' && typeof decoded.sub === 'string' && decoded.sub.startsWith('service:');
577
+ if (decoded.type !== 'access' || typeof decoded.sub !== 'string' || !decoded.sub.startsWith('service:'))
578
+ return false;
579
+ // A denylisted (killed) service must NOT be treated as a trusted principal —
580
+ // otherwise it keeps the rate-limiter exemption even though requireAuth rejects
581
+ // it on real routes. Fold the kill-switch into the pre-auth check too.
582
+ return !isServiceTokenDenied(decoded.sub);
543
583
  }
544
584
  catch {
545
585
  return false;
546
586
  }
547
587
  }
548
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXV0aC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9taWRkbGV3YXJlL2F1dGgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQUV0QyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sUUFBUSxDQUFDO0FBRXBDLE9BQU8sR0FBRyxNQUFNLGNBQWMsQ0FBQztBQUMvQixPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFFekQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBRXBELE9BQU8sRUFBbUIsYUFBYSxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDekUsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3RELE9BQU8sRUFBRSxXQUFXLEVBQXdCLE1BQU0sc0JBQXNCLENBQUM7QUFDekUsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ2xELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUVqRCxNQUFNLE1BQU0sR0FBRyxZQUFZLENBQUMsaUJBQWlCLENBQUMsQ0FBQztBQUUvQyw0REFBNEQ7QUFDNUQsSUFBSSxVQUE4QixDQUFDO0FBQ25DLElBQUkscUJBQXFCLEdBQUcsQ0FBQyxDQUFDO0FBQzlCLDhFQUE4RTtBQUM5RSxJQUFJLGtCQUFzQyxDQUFDO0FBQzNDLElBQUksNkJBQTZCLEdBQUcsQ0FBQyxDQUFDO0FBQ3RDLE1BQU0sOEJBQThCLEdBQUcsT0FBTyxDQUFDLENBQUMsWUFBWTtBQUU1RCxTQUFTLFlBQVk7SUFDbkIsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO0lBQ3ZCLElBQUksQ0FBQyxVQUFVLElBQUksR0FBRyxHQUFHLHFCQUFxQixHQUFHLDhCQUE4QixFQUFFLENBQUM7UUFDaEYsTUFBTSxNQUFNLEdBQUcsT0FBTyxDQUFDLEdB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LGFBQWEsSUFBSSxPQUFPLENBQWtCLENBQUMsRUFBRSxDQUFDO1FBQ25ILElBQUksT0FBTyxDQUFDLEdBQUcsQ0FBQyxVQUFVO1lBQUUsYUFBYSxDQUFDLE1BQU0sR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQztRQUMxRSxJQUFJLE9BQU8sQ0FBQyxHQUFHLENBQUMsWUFBWTtZQUFFLGFBQWEsQ0FBQyxRQUFRLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxZQUFZLENBQUM7UUFDaEYsTUFBTSxPQUFPLEdBQUcscUJBQXFCLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLGFBQWEsQ0FBQyxDQUFDO1FBQy9ELE9BQU8sT0FBTyxDQUFDLElBQUksS0FBSyxRQUFRLElBQUksT0FBTyxPQUFPLENBQUMsR0FBRyxLQUFLLFFBQVEsSUFBSSxPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUM1RyxDQUFDO0lBQUMsTUFBTSxDQUFDO1FBQ1AsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0FBQ0gsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDI2IFBpcGVsaW5lIEJ1aWxkZXIgQ29udHJpYnV0b3JzXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuXG5pbXBvcnQgeyByYW5kb21VVUlEIH0gZnJvbSAnY3J5cHRvJztcbmltcG9ydCB0eXBlIHsgUmVxdWVzdCwgUmVzcG9uc2UsIE5leHRGdW5jdGlvbiB9IGZyb20gJ2V4cHJlc3MnO1xuaW1wb3J0IGp3dCBmcm9tICdqc29ud2VidG9rZW4nO1xuaW1wb3J0IHsgSHR0cFN0YXR1cyB9IGZyb20gJy4uL2NvbnN0YW50cy9odHRwLXN0YXR1cy5qcyc7XG5pbXBvcnQgdHlwZSB7IEp3dFBheWxvYWQgfSBmcm9tICcuLi90eXBlcy9jb21tb24uanMnO1xuaW1wb3J0IHsgRXJyb3JDb2RlIH0gZnJvbSAnLi4vdHlwZXMvZXJyb3ItY29kZXMuanMnO1xuaW1wb3J0IHR5cGUgeyBIdHRwUmVxdWVzdCB9IGZyb20gJy4uL3R5cGVzL2h0dHAuanMnO1xuaW1wb3J0IHsgdHlwZSBQZXJtaXNzaW9uLCBoYXNQZXJtaXNzaW9uIH0gZnJvbSAnLi4vdHlwZXMvcGVybWlzc2lvbnMuanMnO1xuaW1wb3J0IHsgZ2V0SGVhZGVyU3RyaW5nIH0gZnJvbSAnLi4vdXRpbHMvaGVhZGVycy5qcyc7XG5pbXBvcnQgeyBnZXRJZGVudGl0eSwgdHlwZSBSZXF1ZXN0SWRlbnRpdHkgfSBmcm9tICcuLi91dGlscy9pZGVudGl0eS5qcyc7XG5pbXBvcnQgeyBjcmVhdGVMb2dnZXIgfSBmcm9tICcuLi91dGlscy9sb2dnZXIuanMnO1xuaW1wb3J0IHsgc2VuZEVycm9yIH0gZnJvbSAnLi4vdXRpbHMvcmVzcG9uc2UuanMnO1xuXG5jb25zdCBsb2dnZXIgPSBjcmVhdGVMb2dnZXIoJ2F1dGgtbWlkZGxld2FyZScpO1xuXG4vKiogQ2FjaGVkIEpXVCBzZWNyZXQgd2l0aCBwZXJpb2RpYyByZWZyZXNoIGZyb20gZW52IHZhci4gKi9cbmxldCBfand0U2VjcmV0OiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5sZXQgX2p3dFNlY3JldFJlZnJlc2hlZEF0ID0gMDtcbi8qKiBDYWNoZWQgUFJFVklPVVMgSldUIHNlY3JldCAob3B0aW9uYWwpIOKAlCBlbmFibGVzIHplcm8tZG93bnRpbWUgcm90YXRpb24uICovXG5sZXQgX2p3dFNlY3JldFByZXZpb3VzOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5sZXQgX2p3dFNlY3JldFByZXZpb3VzUmVmcmVzaGVkQXQgPSAwO1xuY29uc3QgSldUX1NFQ1JFVF9SRUZSRVNIX0lOVEVSVkFMX01TID0gMzAwXzAwMDsgLy8gNSBtaW51dGVzXG5cbmZ1bmN0aW9uIGdldEp3dFNlY3JldCgpOiBzdHJpbmcge1xuICBjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuICBpZiAoIV9qd3RTZWNyZXQgfHwgbm93IC0gX2p3dFNlY3JldFJlZnJlc2hlZEF0ID4gSldUX1NFQ1JFVF9SRUZSRVNIX0lOVEVSVkFMX01TKSB7XG4gICAgY29uc3Qgc2VjcmV0ID0gcHJvY2Vzcy5lbnYuSldUX1NFQ1JFVDtcbiAgICBpZiAoIXNlY3JldCkge1xuICAgICAgbG9nZ2VyLmVycm9yKCdKV1RfU0VDUkVUIGVudmlyb25tZW50IHZhcmlhYmxlIGlzIG5vdCBzZXQnKTtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSldUX1NFQ1JFVCBlbnZpcm9ubWVudCB2YXJpYWJsZSBpcyByZXF1aXJlZCcpO1xuICAgIH1cbiAgICBpZiAoX2p3dFNlY3JldCAmJiBfand0U2VjcmV0ICE9PSBzZWNyZXQpIHtcbiAgICAgIGxvZ2dlci5pbmZvKCdKV1Qgc2VjcmV0IHJvdGF0ZWQnKTtcbiAgICB9XG4gICAgX2p3dFNlY3JldCA9IHNlY3JldDtcbiAgICBfand0U2VjcmV0UmVmcmVzaGVkQXQgPSBub3c7XG4gIH1cbiAgcmV0dXJuIF9qd3RTZWNyZXQ7XG59XG5cbi8qKlxuICogVGhlIG9wdGlvbmFsIFBSRVZJT1VTIEpXVCBzZWNyZXQgKGBKV1RfU0VDUkVUX1BSRVZJT1VTYCksIGNhY2hlZCB3aXRoIHRoZSBzYW1lXG4gKiBUVEwgYXMgdGhlIHByaW1hcnkuIFJldHVybnMgYHVuZGVmaW5lZGAgd2hlbiB1bnNldC4gRHVyaW5nIGEgYEpXVF9TRUNSRVRgXG4gKiByb3RhdGlvbiwgb3BlcmF0b3JzIHNldCBgSldUX1NFQ1JFVF9QUkVWSU9VU2AgdG8gdGhlIG9sZCB2YWx1ZSBzbyB0b2tlbnMgc2lnbmVkXG4gKiB3aXRoIEVJVEhFUiBzZWNyZXQga2VlcCB2ZXJpZnlpbmcg4oCUIGNsb3NpbmcgdGhlIGF1dGgtb3V0YWdlIHdpbmRvdyB3aGVyZVxuICogc3RpbGwtdmFsaWQgb2xkLXNpZ25lZCAob3IgZnJlc2hseSBuZXctc2lnbmVkKSB0b2tlbnMgd291bGQgb3RoZXJ3aXNlIGJlXG4gKiByZWplY3RlZC4gYHVuZGVmaW5lZGAgaXMgYSB2YWxpZCBjYWNoZWQgdmFsdWUsIHNvIHRoaXMgcmVmcmVzaGVzIHB1cmVseSBvbiB0aGVcbiAqIHRpbWUgaW50ZXJ2YWwgKG5vdCBvbiBlbXB0aW5lc3MpLlxuICovXG5mdW5jdGlvbiBnZXRKd3RTZWNyZXRQcmV2aW91cygpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICBjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuICBpZiAobm93IC0gX2p3dFNlY3JldFByZXZpb3VzUmVmcmVzaGVkQXQgPiBKV1RfU0VDUkVUX1JFRlJFU0hfSU5URVJWQUxfTVMpIHtcbiAgICBfand0U2VjcmV0UHJldmlvdXMgPSBwcm9jZXNzLmVudi5KV1RfU0VDUkVUX1BSRVZJT1VTIHx8IHVuZGVmaW5lZDtcbiAgICBfand0U2VjcmV0UHJldmlvdXNSZWZyZXNoZWRBdCA9IG5vdztcbiAgfVxuICByZXR1cm4gX2p3dFNlY3JldFByZXZpb3VzO1xufVxuXG4vKipcbiAqIFZlcmlmeSBhIEpXVCBhZ2FpbnN0IHRoZSBwcmltYXJ5IHNlY3JldCwgZmFsbGluZyBiYWNrIHRvIHRoZSBwcmV2aW91cyBzZWNyZXRcbiAqICh3aGVuIGBKV1RfU0VDUkVUX1BSRVZJT1VTYCBpcyBjb25maWd1cmVkKSBPTkxZIG9uIGEgc2lnbmF0dXJlL3ZlcmlmaWNhdGlvblxuICogZmFpbHVyZS4gVGhpcyBtYWtlcyB0b2tlbiB2ZXJpZmljYXRpb24gc3Vydml2ZSBhIHNlY3JldCByb3RhdGlvbiB3aXRoIHplcm9cbiAqIGRvd250aW1lOiBhIHRva2VuIHZhbGlkIHVuZGVyIEVJVEhFUiBzZWNyZXQgcGFzc2VzLlxuICpcbiAqIGpzb253ZWJ0b2tlbidzIGB2ZXJpZnlgIHRha2VzIGEgc2luZ2xlIHNlY3JldCwgc28gdGhpcyBpcyB0cnktcHJpbWFyeS10aGVuLVxuICogcHJldmlvdXMg4oCUIE5PVCBhIHNlY3JldCBhcnJheS4gTm8gZXhpc3RpbmcgY2hlY2sgaXMgd2Vha2VuZWQ6XG4gKiAgIC0gYHZlcmlmeU9wdGlvbnNgIChhbGdvcml0aG0gcGlubmluZyArIG9wdGlvbmFsIGlzc3Vlci9hdWRpZW5jZSkgaXMgYXBwbGllZFxuICogICAgIGlkZW50aWNhbGx5IG9uIEJPVEggYXR0ZW1wdHMsIHNvIGFsZy1jb25mdXNpb24gLyBgYWxnOm5vbmVgIHN0YXkgYmxvY2tlZC5cbiAqICAgLSBFeHBpcnkgLyBub3QtYmVmb3JlIGZyb20gdGhlIFBSSU1BUlkgYXR0ZW1wdCBhcmUgYXV0aG9yaXRhdGl2ZSBhbmQgYXJlXG4gKiAgICAgcmUtdGhyb3duIHdpdGhvdXQgYSBwcmV2aW91cy1zZWNyZXQgcmV0cnksIHNvIGEgYFRva2VuRXhwaXJlZEVycm9yYCBpc1xuICogICAgIG5ldmVyIG1hc2tlZCBpbnRvIGFuIFwiaW52YWxpZCBzaWduYXR1cmVcIi5cbiAqICAgLSBXaGVuIG5vIHByZXZpb3VzIHNlY3JldCBpcyBzZXQsIGJlaGF2aW91ciBpcyBieXRlLWZvci1ieXRlIHRoZSBvcmlnaW5hbDpcbiAqICAgICB0aGUgcHJpbWFyeSBlcnJvciBwcm9wYWdhdGVzIHVuY2hhbmdlZC5cbiAqL1xuZnVuY3Rpb24gdmVyaWZ5Snd0V2l0aFJvdGF0aW9uKHRva2VuOiBzdHJpbmcsIHZlcmlmeU9wdGlvbnM6IGp3dC5WZXJpZnlPcHRpb25zKTogSnd0UGF5bG9hZCB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIGp3dC52ZXJpZnkodG9rZW4sIGdldEp3dFNlY3JldCgpLCB2ZXJpZnlPcHRpb25zKSBhcyBKd3RQYXlsb2FkO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICBjb25zdCBwcmV2aW91cyA9IGdldEp3dFNlY3JldFByZXZpb3VzKCk7XG4gICAgLy8gRmFsbCBiYWNrIHRvIHRoZSBwcmV2aW91cyBzZWNyZXQgb25seSBmb3IgYSBzaWduYXR1cmUvdmVyaWZpY2F0aW9uIGZhaWx1cmVcbiAgICAvLyAoYSBwbGFpbiBKc29uV2ViVG9rZW5FcnJvcikuIEV4cGlyeSAvIG5vdC1iZWZvcmUgYXJlIGVuZm9yY2VkIHJlZ2FyZGxlc3Mgb2ZcbiAgICAvLyB3aGljaCBzZWNyZXQgc2lnbmVkIHRoZSB0b2tlbiwgc28gdGhvc2UgZXJyb3JzIG11c3Qgc3VyZmFjZSBhcy1pcy5cbiAgICBpZiAoXG4gICAgICBwcmV2aW91c1xuICAgICAgJiYgZXJyIGluc3RhbmNlb2Ygand0Lkpzb25XZWJUb2tlbkVycm9yXG4gICAgICAmJiAhKGVyciBpbnN0YW5jZW9mIGp3dC5Ub2tlbkV4cGlyZWRFcnJvcilcbiAgICAgICYmICEoZXJyIGluc3RhbmNlb2Ygand0Lk5vdEJlZm9yZUVycm9yKVxuICAgICkge1xuICAgICAgLy8gQSB0b2tlbiBzaWduZWQgYnkgdGhlIHByZXZpb3VzIHNlY3JldCB2ZXJpZmllcyBoZXJlOyBpZiBpdCBpcyBpbnN0ZWFkXG4gICAgICAvLyBleHBpcmVkL2ludmFsaWQgdW5kZXIgdGhlIHByZXZpb3VzIHNlY3JldCwgdGhhdCBlcnJvciBwcm9wYWdhdGVzIGFuZCBpc1xuICAgICAgLy8gaGFuZGxlZCBieSB0aGUgY2FsbGVyIGV4YWN0bHkgbGlrZSBhIHByaW1hcnkgZmFpbHVyZS5cbiAgICAgIHJldHVybiBqd3QudmVyaWZ5KHRva2VuLCBwcmV2aW91cywgdmVyaWZ5T3B0aW9ucykgYXMgSnd0UGF5bG9hZDtcbiAgICB9XG4gICAgdGhyb3cgZXJyO1xuICB9XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVxdWlyZUF1dGhPcHRpb25zIHtcbiAgLyoqXG4gICAqIEFsbG93IHgtb3JnLWlkL3gtb3JnLW5hbWUgaGVhZGVycyB0byBvdmVycmlkZSB0aGUgSldUJ3Mgb3JnYW5pemF0aW9uIGZpZWxkcy5cbiAgICpcbiAgICogV2hlbiBlbmFibGVkLCB0aGUgYHgtb3JnLWlkYC9geC1vcmctbmFtZWAgaGVhZGVycyBvdmVycmlkZSB0aGUgY2FsbGVyJ3Mgb3JnXG4gICAqIOKAlCBidXQgT05MWSBmb3IgYSB2ZXJpZmllZCBTWVMtQURNSU4gKGBpc1N1cGVyQWRtaW5gIGNsYWltKS4gRm9yIGFueSBvcmRpbmFyeVxuICAgKiBhdXRoZW50aWNhdGVkIHVzZXIgdGhlIGhlYWRlcnMgYXJlIGlnbm9yZWQsIHNvIGVuYWJsaW5nIHRoaXMgY2FuIG5ldmVyIGxldCBhXG4gICAqIG5vcm1hbCB1c2VyIGltcGVyc29uYXRlIGFub3RoZXIgdGVuYW50J3Mgb3JnLiBVc2UgZm9yIGNyb3NzLW9yZyBhZG1pbiB0b29saW5nXG4gICAqIChlLmcuIGEgc3lzYWRtaW4gbWFuYWdpbmcgYSBnaXZlbiBvcmcncyBiaWxsaW5nKS4gSWYgdW5zdXJlLCBsZWF2ZSBpdCBkaXNhYmxlZC5cbiAgICovXG4gIGFsbG93T3JnSGVhZGVyT3ZlcnJpZGU/OiBib29sZWFuO1xufVxuXG4vKiogSldUIGF1dGggbWlkZGxld2FyZS4gVXNlIGRpcmVjdGx5IG9yIGNhbGwgd2l0aCBvcHRpb25zLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlcXVpcmVBdXRoKFxuICByZXE6IFJlcXVlc3QsXG4gIHJlczogUmVzcG9uc2UsXG4gIG5leHQ6IE5leHRGdW5jdGlvbixcbik6IHZvaWQ7XG5leHBvcnQgZnVuY3Rpb24gcmVxdWlyZUF1dGgoXG4gIG9wdGlvbnM/OiBSZXF1aXJlQXV0aE9wdGlvbnMsXG4pOiAocmVxOiBSZXF1ZXN0LCByZXM6IFJlc3BvbnNlLCBuZXh0OiBOZXh0RnVuY3Rpb24pID0+IHZvaWQ7XG5leHBvcnQgZnVuY3Rpb24gcmVxdWlyZUF1dGgoXG4gIHJlcU9yT3B0aW9ucz86IFJlcXVlc3QgfCBSZXF1aXJlQXV0aE9wdGlvbnMsXG4gIHJlcz86IFJlc3BvbnNlLFxuICBuZXh0PzogTmV4dEZ1bmN0aW9uLFxuKTogdm9pZCB8ICgocmVxOiBSZXF1ZXN0LCByZXM6IFJlc3BvbnNlLCBuZXh0OiBOZXh0RnVuY3Rpb24pID0+IHZvaWQpIHtcbiAgaWYgKHJlcU9yT3B0aW9ucyAmJiByZXMgJiYgbmV4dCAmJiAnaGVhZGVycycgaW4gcmVxT3JPcHRpb25zKSB7XG4gICAgcmV0dXJuIF9yZXF1aXJlQXV0aCh7fSwgcmVxT3JPcHRpb25zIGFzIFJlcXVlc3QsIHJlcywgbmV4dCk7XG4gIH1cblxuICBjb25zdCBvcHRpb25zID0gKHJlcU9yT3B0aW9ucyBhcyBSZXF1aXJlQXV0aE9wdGlvbnMpIHx8IHt9O1xuICByZXR1cm4gKHJlcTogUmVxdWVzdCwgcmVzSW5uZXI6IFJlc3BvbnNlLCBuZXh0SW5uZXI6IE5leHRGdW5jdGlvbikgPT4ge1xuICAgIF9yZXF1aXJlQXV0aChvcHRpb25zLCByZXEsIHJlc0lubmVyLCBuZXh0SW5uZXIpO1xuICB9O1xufVxuXG4vKipcbiAqIEEgc291cmNlIG9mIHRoZSBDVVJSRU5UIGB0b2tlblZlcnNpb25gIGZvciBhIHVzZXIsIGJhY2tlZCBieSBhIHN0b3JlIHRoZVxuICogc3RhdGVsZXNzIHNlcnZpY2VzIGNhbiByZWFkIChpbiBwcmFjdGljZSBhIFJlZGlzIGtleSB0aGUgcGxhdGZvcm0gcHVibGlzaGVzXG4gKiB0byBvbiBldmVyeSBwcml2aWxlZ2UgY2hhbmdlKS4gUmVnaXN0ZXJlZCB2aWEge0BsaW5rIHNldFRva2VuUmV2b2NhdGlvblN0b3JlfS5cbiAqXG4gKiBgZ2V0Q3VycmVudFZlcnNpb25gIHJldHVybnMgdGhlIHVzZXIncyBjdXJyZW50IHZlcnNpb24sIG9yIGBudWxsYCB3aGVuIHRoZVxuICogc3RvcmUgaGFzIG5vIGVudHJ5IOKAlCBhIG1pc3MgaXMgdHJlYXRlZCBhcyBcIm5vIGtub3duIHJldm9jYXRpb25cIiAoZmFpbC1vcGVuKTpcbiAqIHJldm9jYXRpb24gZW50cmllcyBhcmUgcHVibGlzaGVkIHdpdGggYSBUVEwgbWF0Y2hpbmcgdGhlIGFjY2Vzcy10b2tlblxuICogbGlmZXRpbWUsIHNvIGEgbWlzc2luZyBlbnRyeSBtZWFucyBhbnkgdG9rZW4gb2xkIGVub3VnaCB0byBwcmVkYXRlIGl0IGhhc1xuICogYWxyZWFkeSBleHBpcmVkIG9uIGl0cyBvd24uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVG9rZW5SZXZvY2F0aW9uU3RvcmUge1xuICBnZXRDdXJyZW50VmVyc2lvbih1c2VySWQ6IHN0cmluZyk6IFByb21pc2U8bnVtYmVyIHwgbnVsbD47XG59XG5cbmxldCB0b2tlblJldm9jYXRpb25TdG9yZTogVG9rZW5SZXZvY2F0aW9uU3RvcmUgfCB1bmRlZmluZWQ7XG5cbi8qKlxuICogUmVnaXN0ZXIgKG9yIGNsZWFyLCB3aXRoIGB1bmRlZmluZWRgKSB0aGUgcHJvY2Vzcy13aWRlIHRva2VuLXJldm9jYXRpb24gc3RvcmUuXG4gKiBXaGVuIHVuc2V0ICh0aGUgZGVmYXVsdCksIGByZXF1aXJlQXV0aGAgcGVyZm9ybXMgTk8gcmV2b2NhdGlvbiBjaGVjayAoaXQgcmVsaWVzXG4gKiBvbiB0aGUgc2hvcnQgYWNjZXNzLXRva2VuIFRUTCk7IHNlcnZpY2VzIG9wdCBpbiBhdCBib290IGJ5IHdpcmluZyB0aGVpciBSZWRpc1xuICogY2xpZW50LiBQbGF0Zm9ybSBrZWVwcyBpdHMgb3duIE1vbmdvLWJhY2tlZCBjaGVjayBhbmQgbmVlZCBub3QgcmVnaXN0ZXIgb25lLlxuICovXG5leHBvcnQgZnVuY3Rpb24gc2V0VG9rZW5SZXZvY2F0aW9uU3RvcmUoc3RvcmU6IFRva2VuUmV2b2NhdGlvblN0b3JlIHwgdW5kZWZpbmVkKTogdm9pZCB7XG4gIHRva2VuUmV2b2NhdGlvblN0b3JlID0gc3RvcmU7XG59XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIHdoZW4gYGRlY29kZWRgIGhhcyBiZWVuIHJldm9rZWQgcGVyIHRoZSByZWdpc3RlcmVkIHN0b3JlOiBpdHNcbiAqIGVtYmVkZGVkIGB0b2tlblZlcnNpb25gIGlzIHN0cmljdGx5IGJlaGluZCB0aGUgc3RvcmUncyBjdXJyZW50IHZlcnNpb24uXG4gKiBGYWlsLW9wZW4g4oCUIGFueSBzdG9yZSBlcnJvciwgYSBtaXNzaW5nIGVudHJ5LCBvciBhIHRva2VuL3N0b3JlIHdpdGhvdXQgYVxuICogdXNhYmxlIHZlcnNpb24geWllbGRzIGBmYWxzZWAgKGFsbG93KS4gTmV2ZXIgdGhyb3dzLlxuICovXG5hc3luYyBmdW5jdGlvbiBpc1Rva2VuUmV2b2tlZChkZWNvZGVkOiBKd3RQYXlsb2FkKTogUHJvbWlzZTxib29sZWFuPiB7XG4gIGNvbnN0IHN0b3JlID0gdG9rZW5SZXZvY2F0aW9uU3RvcmU7XG4gIGlmICghc3RvcmUgfHwgIWRlY29kZWQuc3ViIHx8IHR5cGVvZiBkZWNvZGVkLnRva2VuVmVyc2lvbiAhPT0gJ251bWJlcicpIHJldHVybiBmYWxzZTtcbiAgdHJ5IHtcbiAgICBjb25zdCBjdXJyZW50ID0gYXdhaXQgc3RvcmUuZ2V0Q3VycmVudFZlcnNpb24oZGVjb2RlZC5zdWIpO1xuICAgIHJldHVybiBjdXJyZW50ICE9PSBudWxsICYmIGRlY29kZWQudG9rZW5WZXJzaW9uIDwgY3VycmVudDtcbiAgfSBjYXRjaCB7XG4gICAgLy8gRmFpbC1vcGVuOiBhIHJldm9jYXRpb24tc3RvcmUgb3V0YWdlIG11c3Qgbm90IGxvY2sgZXZlcnkgdXNlciBvdXQuXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG5cbi8qKlxuICogUHVibGljIHJldm9jYXRpb24gY2hlY2sgZm9yIHJvdXRlcyB0aGF0IHZlcmlmeSBhIHBsYXRmb3JtIEpXVCBPVVRTSURFXG4gKiBgcmVxdWlyZUF1dGhgIChlLmcuIHRoZSBpbWFnZS1yZWdpc3RyeSBgL3Rva2VuYCBtaW50IHBhdGgsIHdoaWNoIHJlc29sdmVzXG4gKiBpZGVudGl0eSBpdHNlbGYpLiBSZXR1cm5zIHRydWUgd2hlbiB0aGUgdG9rZW4ncyBgdG9rZW5WZXJzaW9uYCBpcyBzdHJpY3RseVxuICogYmVoaW5kIHRoZSBzdG9yZSdzIGN1cnJlbnQgdmVyc2lvbi4gRmFpbC1vcGVuIChuZXZlciB0aHJvd3MpIOKAlCBhIHN0b3JlIG91dGFnZVxuICogb3IgYSB0b2tlbi9zdG9yZSB3aXRob3V0IGEgdXNhYmxlIHZlcnNpb24geWllbGRzIGZhbHNlIChhbGxvdyksIG1hdGNoaW5nXG4gKiBgcmVxdWlyZUF1dGhgLiBQYXNzIHRoZSB2ZXJpZmllZCBKV1QgY2xhaW1zIChgc3ViYCwgYHRva2VuVmVyc2lvbmApLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gaXNBY2Nlc3NUb2tlblJldm9rZWQoY2xhaW1zOiB7IHN1Yj86IHN0cmluZzsgdG9rZW5WZXJzaW9uPzogbnVtYmVyIH0pOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgcmV0dXJuIGlzVG9rZW5SZXZva2VkKGNsYWltcyBhcyBKd3RQYXlsb2FkKTtcbn1cblxuZnVuY3Rpb24gX3JlcXVpcmVBdXRoKFxuICBvcHRpb25zOiBSZXF1aXJlQXV0aE9wdGlvbnMsXG4gIHJlcTogUmVxdWVzdCxcbiAgcmVzOiBSZXNwb25zZSxcbiAgbmV4dDogTmV4dEZ1bmN0aW9uLFxuKTogdm9pZCB7XG4gIGNvbnN0IGF1dGhIZWFkZXIgPSByZXEuaGVhZGVycy5hdXRob3JpemF0aW9uO1xuXG4gIGlmICghYXV0aEhlYWRlcikge1xuICAgIHJldHVybiBzZW5kRXJyb3IocmVzLCBIdHRwU3RhdHVzLlVOQVVUSE9SSVpFRCwgJ0F1dGhvcml6YXRpb24gaGVhZGVyIHJlcXVpcmVkJywgRXJyb3JDb2RlLlRPS0VOX01JU1NJTkcpO1xuICB9XG5cbiAgY29uc3QgcGFydHMgPSBhdXRoSGVhZGVyLnNwbGl0KCcgJyk7XG4gIGlmIChwYXJ0cy5sZW5ndGggIT09IDIgfHwgcGFydHNbMF0gIT09ICdCZWFyZXInKSB7XG4gICAgcmV0dXJuIHNlbmRFcnJvcihyZXMsIEh0dHBTdGF0dXMuVU5BVVRIT1JJWkVELCAnSW52YWxpZCBhdXRob3JpemF0aW9uIGZvcm1hdC4gVXNlOiBCZWFyZXIgPHRva2VuPicsIEVycm9yQ29kZS5UT0tFTl9JTlZBTElEKTtcbiAgfVxuXG4gIHRyeSB7XG4gICAgLy8gUGFzcyB0aHJvdWdoIG9wdGlvbmFsIGlzc3Vlci9hdWRpZW5jZSB2ZXJpZmljYXRpb24gd2hlbiBlbnYtY29uZmlndXJlZC5cbiAgICAvLyBXaXRob3V0IHRoZXNlLCBhIEpXVCBzaWduZWQgYnkgYW55IHN5c3RlbSB0aGF0IGhhcHBlbnMgdG8gc2hhcmUgdGhlXG4gICAgLy8gc2FtZSBKV1RfU0VDUkVUIHdvdWxkIGJlIGFjY2VwdGVkIOKAlCBkZWZlbmNlLWluLWRlcHRoIGZvciBzaGFyZWQtc2VjcmV0XG4gICAgLy8gbWlzY29uZmlndXJhdGlvbnMgYWNyb3NzIHNlcnZpY2VzIC8gZW52aXJvbm1lbnRzLlxuICAgIC8vIFBpbiB0aGUgYWNjZXB0ZWQgYWxnb3JpdGhtIHRvIHRoZSBjb25maWd1cmVkIEhNQUMgYWxnIChkZWZhdWx0IEhTMjU2KS5cbiAgICAvLyBXaXRob3V0IGFuIGFsbG93LWxpc3QsIGBqd3QudmVyaWZ5YCBhY2NlcHRzIGFueSBhbGdvcml0aG0gdGhlIGtleSBjYW5cbiAgICAvLyB2ZXJpZnkg4oCUIHRoZSBjbGFzc2ljIGFsZy1jb25mdXNpb24gdmVjdG9yIChhbmQgYSBoYXJkIGd1YXJkIGFnYWluc3RcbiAgICAvLyBgYWxnOm5vbmVgKS4gRW52LWRyaXZlbiBzbyBpdCBzdGF5cyBpbiBsb2Nrc3RlcCB3aXRoIGhvdyB0b2tlbnMgYXJlXG4gICAgLy8gc2lnbmVkIChzZWUgc2lnblNlcnZpY2VUb2tlbiArIHBsYXRmb3JtJ3MgY29uZmlnLmF1dGguand0LmFsZ29yaXRobSkuXG4gICAgY29uc3QgdmVyaWZ5T3B0aW9uczogand0LlZlcmlmeU9wdGlvbnMgPSB7IGFsZ29yaXRobXM6IFsocHJvY2Vzcy5lbnYuSldUX0FMR09SSVRITSB8fCAnSFMyNTYnKSBhcyBqd3QuQWxnb3JpdGhtXSB9O1xuICAgIGNvbnN0IGV4cGVjdGVkSXNzdWVyID0gcHJvY2Vzcy5lbnYuSldUX0lTU1VFUjtcbiAgICBjb25zdCBleHBlY3RlZEF1ZGllbmNlID0gcHJvY2Vzcy5lbnYuSldUX0FVRElFTkNFO1xuICAgIGlmIChleHBlY3RlZElzc3VlcikgdmVyaWZ5T3B0aW9ucy5pc3N1ZXIgPSBleHBlY3RlZElzc3VlcjtcbiAgICBpZiAoZXhwZWN0ZWRBdWRpZW5jZSkgdmVyaWZ5T3B0aW9ucy5hdWRpZW5jZSA9IGV4cGVjdGVkQXVkaWVuY2U7XG4gICAgY29uc3QgZGVjb2RlZCA9IHZlcmlmeUp3dFdpdGhSb3RhdGlvbihwYXJ0c1sxXSwgdmVyaWZ5T3B0aW9ucyk7XG5cbiAgICBpZiAoZGVjb2RlZC50eXBlICE9PSAnYWNjZXNzJykge1xuICAgICAgcmV0dXJuIHNlbmRFcnJvcihyZXMsIEh0dHBTdGF0dXMuVU5BVVRIT1JJWkVELCAnT25seSBhY2Nlc3MgdG9rZW5zIGNhbiBiZSB1c2VkIGZvciBBUEkgcmVxdWVzdHMnLCBFcnJvckNvZGUuVE9LRU5fSU5WQUxJRCk7XG4gICAgfVxuXG4gICAgaWYgKCFkZWNvZGVkLnN1YiB8fCAhZGVjb2RlZC5yb2xlKSB7XG4gICAgICByZXR1cm4gc2VuZEVycm9yKHJlcywgSHR0cFN0YXR1cy5VTkFVVEhPUklaRUQsICdUb2tlbiBtaXNzaW5nIHJlcXVpcmVkIGZpZWxkcycsIEVycm9yQ29kZS5UT0tFTl9JTlZBTElEKTtcbiAgICB9XG5cbiAgICByZXEudXNlciA9IHsgLi4uZGVjb2RlZCB9O1xuXG4gICAgLy8gVGhlIHgtb3JnLWlkL3gtb3JnLW5hbWUgb3ZlcnJpZGUgbGV0cyBhIFNZUy1BRE1JTiBhY3Qgb24gYSBjaG9zZW4gb3JnXG4gICAgLy8gKGNyb3NzLW9yZyBhZG1pbiB0b29saW5nKS4gSXQgaXMgZ2F0ZWQgb24gdGhlIHZlcmlmaWVkIGBpc1N1cGVyQWRtaW5gIGNsYWltXG4gICAgLy8gaGVyZSBzbyB0aGF0IGV2ZW4gYSByb3V0ZSB3aGljaCBtaXN0YWtlbmx5IGVuYWJsZXMgYGFsbG93T3JnSGVhZGVyT3ZlcnJpZGVgXG4gICAgLy8gY2FuIE5FVkVSIGxldCBhbiBvcmRpbmFyeSBhdXRoZW50aWNhdGVkIHVzZXIgc3Bvb2YgYW5vdGhlciB0ZW5hbnQncyBvcmcgdmlhXG4gICAgLy8gdGhlIGhlYWRlciDigJQgZGVmZW5jZS1pbi1kZXB0aCBhZ2FpbnN0IHRoZSBjcm9zcy10ZW5hbnQgYnJlYWsgdGhpcyBjYXVzZWQuXG4gICAgaWYgKG9wdGlvbnMuYWxsb3dPcmdIZWFkZXJPdmVycmlkZSAmJiBkZWNvZGVkLmlzU3VwZXJBZG1pbiA9PT0gdHJ1ZSkge1xuICAgICAgY29uc3QgaGVhZGVyT3JnSWQgPSBnZXRIZWFkZXJTdHJpbmcocmVxLmhlYWRlcnNbJ3gtb3JnLWlkJ10pO1xuICAgICAgY29uc3QgaGVhZGVyT3JnTmFtZSA9IGdldEhlYWRlclN0cmluZyhyZXEuaGVhZGVyc1sneC1vcmctbmFtZSddKTtcbiAgICAgIGlmIChoZWFkZXJPcmdJZCkgcmVxLnVzZXIub3JnYW5pemF0aW9uSWQgPSBoZWFkZXJPcmdJZDtcbiAgICAgIGlmIChoZWFkZXJPcmdOYW1lKSByZXEudXNlci5vcmdhbml6YXRpb25OYW1lID0gaGVhZGVyT3JnTmFtZTtcbiAgICB9XG5cbiAgICAvLyBSZS1kZXJpdmUgdGhlIHJlcXVlc3QncyB0ZW5hbnQgaWRlbnRpdHkgZnJvbSB0aGUgTk9XLXZlcmlmaWVkIEpXVC5cbiAgICAvL1xuICAgIC8vIGBhdHRhY2hSZXF1ZXN0Q29udGV4dGAgcnVucyBhcyBhIGdsb2JhbCBtaWRkbGV3YXJlIEJFRk9SRSB0aGlzIHBlci1yb3V0ZVxuICAgIC8vIGByZXF1aXJlQXV0aGAsIHNvIGl0IGNhcHR1cmVkIGByZXEuY29udGV4dC5pZGVudGl0eWAgd2hpbGUgYHJlcS51c2VyYCB3YXNcbiAgICAvLyBzdGlsbCB1bmRlZmluZWQg4oCUIGF0IHdoaWNoIHBvaW50IGBnZXRJZGVudGl0eWAgZmFsbHMgYmFjayB0byB0aGUgcmF3LFxuICAgIC8vIGNsaWVudC1zZXR0YWJsZSBgeC1vcmctaWRgL2B4LXVzZXItaWRgIGhlYWRlcnMuIEV2ZXJ5IGRvd25zdHJlYW0gdGVuYW50LVxuICAgIC8vIGF1dGhvcml0eSBjb25zdW1lciAocmVxdWlyZU9yZ0lkLCB3aXRoVGVuYW50Q29udGV4dCdzIFJMUyBzY29wZSwgY2hlY2tRdW90YSxcbiAgICAvLyB3aXRoUm91dGUsIGFuZCB0aGUgaWRlbXBvdGVuY3kgbmFtZXNwYWNlKSByZWFkcyBgcmVxLmNvbnRleHQuaWRlbnRpdHlgLCBzb1xuICAgIC8vIHRoYXQgZnJvemVuIGhlYWRlci1kZXJpdmVkIHZhbHVlIOKAlCBub3QgdGhlIEpXVCDigJQgd2FzIGdvdmVybmluZyB0ZW5hbmN5IG9uXG4gICAgLy8gYW55IG5vbi1uZ2lueCBwYXRoLiBSZWNvbXB1dGluZyBoZXJlLCBhdCB0aGUgc2luZ2xlIHBvc3QtdmVyaWZpY2F0aW9uIGNob2tlXG4gICAgLy8gcG9pbnQsIG1ha2VzIGBnZXRJZGVudGl0eWAgcHJlZmVyIHRoZSB2ZXJpZmllZCBgcmVxLnVzZXJgIChzZWUgaWRlbnRpdHkudHMpXG4gICAgLy8gc28gdGVuYW5jeSBpcyBKV1QtYXV0aG9yaXRhdGl2ZS4gVGhlIG5naW54IGB4LW9yZy1pZGAgb3ZlcndyaXRlIHN0YXlzIGFzXG4gICAgLy8gZGVmZW5jZS1pbi1kZXB0aC4gR3VhcmRlZCBvbiBgcmVxLmNvbnRleHRgIHNvIHNlcnZpY2VzL3BhdGhzIHRoYXQgbmV2ZXJcbiAgICAvLyBhdHRhY2ggYSBjb250ZXh0IChvciBydW4gcmVxdWlyZUF1dGggcHJlLWNvbnRleHQpIGFyZSB1bmFmZmVjdGVkLlxuICAgIGNvbnN0IHJlcUN0eCA9IChyZXEgYXMgUmVxdWVzdCAmIHsgY29udGV4dD86IHsgaWRlbnRpdHk6IFJlcXVlc3RJZGVudGl0eSB9IH0pLmNvbnRleHQ7XG4gICAgaWYgKHJlcUN0eCkge1xuICAgICAgcmVxQ3R4LmlkZW50aXR5ID0gZ2V0SWRlbnRpdHkocmVxIGFzIHVua25vd24gYXMgSHR0cFJlcXVlc3QpO1xuICAgIH1cblxuICAgIC8vIFNlc3Npb24taW52YWxpZGF0aW9uIGNoZWNrIGZvciB0aGUgc3RhdGVsZXNzIHNlcnZpY2VzOiByZWplY3QgYSB0b2tlblxuICAgIC8vIHdob3NlIGB0b2tlblZlcnNpb25gIGlzIGJlaGluZCB0aGUgcmV2b2NhdGlvbiBzdG9yZSdzIGN1cnJlbnQgdmFsdWUgKGFcbiAgICAvLyBwcml2aWxlZ2UgY2hhbmdlIHRoZSBwbGF0Zm9ybSBwdWJsaXNoZWQpLiBObyBzdG9yZSByZWdpc3RlcmVkIOKHkiB0aGlzIGlzIGFcbiAgICAvLyBuby1vcCBhbmQgY29udHJvbCBwYXNzZXMgc3RyYWlnaHQgdGhyb3VnaC4gRmFpbC1vcGVuIG9uIGFueSBzdG9yZSBlcnJvci5cbiAgICBpZiAodG9rZW5SZXZvY2F0aW9uU3RvcmUgJiYgZGVjb2RlZC5zdWIgJiYgdHlwZW9mIGRlY29kZWQudG9rZW5WZXJzaW9uID09PSAnbnVtYmVyJykge1xuICAgICAgLy8gYC5jYXRjaChuZXh0KWAgZm9yd2FyZHMgYSBET1dOU1RSRUFNIHN5bmNocm9ub3VzIHRocm93IGZyb20gYG5leHQoKWAgdG9cbiAgICAgIC8vIEV4cHJlc3MncyBlcnJvciBtaWRkbGV3YXJlIOKAlCB3aXRob3V0IGl0LCB0aGF0IHRocm93IHdvdWxkIHN1cmZhY2UgYXMgYW5cbiAgICAgIC8vIHVuaGFuZGxlZCByZWplY3Rpb24gKHRoaXMgYG5leHQoKWAgcnVucyBpbiBhIG1pY3JvdGFzaywgb3V0c2lkZSB0aGVcbiAgICAgIC8vIHN1cnJvdW5kaW5nIHRyeS9jYXRjaCBhbmQgRXhwcmVzcydzIHBlci1sYXllciBkaXNwYXRjaCkuIGBpc1Rva2VuUmV2b2tlZGBcbiAgICAgIC8vIGl0c2VsZiBuZXZlciByZWplY3RzIChpdCBmYWlsLW9wZW5zIGludGVybmFsbHkpLCBzbyB0aGUgY2F0Y2ggb25seSBldmVyXG4gICAgICAvLyBzZWVzIGEgZ2VudWluZSBkb3duc3RyZWFtIGVycm9yLlxuICAgICAgaXNUb2tlblJldm9rZWQoZGVjb2RlZClcbiAgICAgICAgLnRoZW4oKHJldm9rZWQpID0+IHtcbiAgICAgICAgICBpZiAocmV2b2tlZCkge1xuICAgICAgICAgICAgcmV0dXJuIHNlbmRFcnJvcihyZXMsIEh0dHBTdGF0dXMuVU5BVVRIT1JJWkVELCAnU2Vzc2lvbiBoYXMgYmVlbiByZXZva2VkOyBwbGVhc2Ugc2lnbiBpbiBhZ2FpbicsIEVycm9yQ29kZS5UT0tFTl9SRVZPS0VEKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgbmV4dCgpO1xuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2gobmV4dCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbmV4dCgpO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIGp3dC5Ub2tlbkV4cGlyZWRFcnJvcikge1xuICAgICAgcmV0dXJuIHNlbmRFcnJvcihyZXMsIEh0dHBTdGF0dXMuVU5BVVRIT1JJWkVELCAnVG9rZW4gaGFzIGV4cGlyZWQnLCBFcnJvckNvZGUuVE9LRU5fRVhQSVJFRCk7XG4gICAgfVxuXG4gICAgaWYgKGVycm9yIGluc3RhbmNlb2Ygand0Lkpzb25XZWJUb2tlbkVycm9yKSB7XG4gICAgICByZXR1cm4gc2VuZEVycm9yKHJlcywgSHR0cFN0YXR1cy5VTkFVVEhPUklaRUQsICdJbnZhbGlkIHRva2VuJywgRXJyb3JDb2RlLlRPS0VOX0lOVkFMSUQpO1xuICAgIH1cblxuICAgIHJldHVybiBzZW5kRXJyb3IocmVzLCBIdHRwU3RhdHVzLlVOQVVUSE9SSVpFRCwgJ0F1dGhlbnRpY2F0aW9uIGZhaWxlZCcsIEVycm9yQ29kZS5VTkFVVEhPUklaRUQpO1xuICB9XG59XG5cbi8qKlxuICogV2hldGhlciB0aGUgcmVxdWVzdCdzIHVzZXIgaG9sZHMgYHBlcm1pc3Npb25gLiBTdXBlcmFkbWlucyBpbXBsaWNpdGx5IGhvbGRcbiAqIGV2ZXJ5IHBlcm1pc3Npb24uIFJlYWRzIHRoZSByZXNvbHZlZCBgcGVybWlzc2lvbnNgIGNsYWltIChzZXQgYXQgdG9rZW4gaXNzdWUsXG4gKiBvciByZS1kZXJpdmVkIHBlciByZXF1ZXN0IGJ5IHRoZSBwbGF0Zm9ybSkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1c2VySGFzUGVybWlzc2lvbihyZXE6IFJlcXVlc3QsIHBlcm1pc3Npb246IFBlcm1pc3Npb24pOiBib29sZWFuIHtcbiAgcmV0dXJuIGhhc1Blcm1pc3Npb24ocmVxLnVzZXI/LnBlcm1pc3Npb25zLCBwZXJtaXNzaW9uLCByZXEudXNlcj8uaXNTdXBlckFkbWluKTtcbn1cblxuLyoqXG4gKiBDb250ZXh0IHBhc3NlZCB0byBhIHJlZ2lzdGVyZWQgYXV0aG9yaXphdGlvbi1kZW5pYWwgYXVkaXRvciB3aGVuIGFcbiAqIHN0YXRlLWNoYW5naW5nIHJlcXVlc3QgaXMgcmVqZWN0ZWQgYnkgYHJlcXVpcmVQZXJtaXNzaW9uYCAvXG4gKiBgcmVxdWlyZVN5c3RlbUFkbWluYC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBdXRoekRlbmlhbEluZm8ge1xuICAvKiogVGhlIGRlbmllZCB1c2VyJ3MgaWQgKGBzdWJgKSwgaWYgYXV0aGVudGljYXRlZC4gKi9cbiAgYWN0b3JJZD86IHN0cmluZztcbiAgYWN0b3JFbWFpbD86IHN0cmluZztcbiAgLyoqIFRoZSB1c2VyJ3MgYWN0aXZlIG9yZyBhdCBkZW5pYWwgdGltZS4gKi9cbiAgb3JnSWQ/OiBzdHJpbmc7XG4gIC8qKiBIVFRQIG1ldGhvZCArIHBhdGggb2YgdGhlIHJlamVjdGVkIHJlcXVlc3QuICovXG4gIG1ldGhvZDogc3RyaW5nO1xuICBwYXRoOiBzdHJpbmc7XG4gIC8qKiBXaGF0IHdhcyByZXF1aXJlZDogdGhlIG1pc3NpbmcgcGVybWlzc2lvbihzKSwgb3IgJ3N5c3RlbS1hZG1pbicuICovXG4gIHJlcXVpcmVkOiBzdHJpbmc7XG59XG5cbi8qKlxuICogT3B0aW9uYWwgc2luayBmb3IgZGVuaWVkLWF1dGhvcml6YXRpb24gZXZlbnRzLiBMZWZ0IHVuc2V0IGJ5IGRlZmF1bHQgc29cbiAqIGFwaS1jb3JlIHN0YXlzIGRlY291cGxlZCBmcm9tIGFueSBhdWRpdCB0cmFuc3BvcnQg4oCUIGEgc2VydmljZSByZWdpc3RlcnMgb25lXG4gKiBhdCBib290ICh0eXBpY2FsbHkgZm9yd2FyZGluZyB0byBpdHMgYFJlbW90ZUF1ZGl0Q2xpZW50YCBhcyBhblxuICogYGF1dGh6LmRlbmllZGAgZXZlbnQsIG9yLCBvbiBwbGF0Zm9ybSwgdG8gdGhlIGxvY2FsIGBhdWRpdCgpYCBoZWxwZXIpLlxuICogTVVTVCBiZSBiZXN0LWVmZm9ydDogaXQgaXMgaW52b2tlZCBpbnNpZGUgdGhlIHJlcXVlc3QgcGF0aCwgc28gaXQgbXVzdCBuZXZlclxuICogdGhyb3cgb3IgYmxvY2sgKHRoZSBnYXRlIHdyYXBzIHRoZSBjYWxsIGluIHRyeS9jYXRjaCByZWdhcmRsZXNzKS5cbiAqL1xubGV0IGF1dGh6RGVuaWFsQXVkaXRvcjogKChpbmZvOiBBdXRoekRlbmlhbEluZm8pID0+IHZvaWQpIHwgdW5kZWZpbmVkO1xuXG4vKipcbiAqIFJlZ2lzdGVyIChvciBjbGVhciwgd2l0aCBgdW5kZWZpbmVkYCkgdGhlIHByb2Nlc3Mtd2lkZSBhdXRob3JpemF0aW9uLWRlbmlhbFxuICogYXVkaXRvci4gSWRlbXBvdGVudDsgdGhlIGxhc3QgcmVnaXN0cmF0aW9uIHdpbnMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZXRBdXRoekRlbmlhbEF1ZGl0b3IoZm46ICgoaW5mbzogQXV0aHpEZW5pYWxJbmZvKSA9PiB2b2lkKSB8IHVuZGVmaW5lZCk6IHZvaWQge1xuICBhdXRoekRlbmlhbEF1ZGl0b3IgPSBmbjtcbn1cblxuLyoqXG4gKiBFbWl0IGEgZGVuaWFsIGV2ZW50LCBiZXN0LWVmZm9ydC4gT25seSBmaXJlcyBmb3Igc3RhdGUtY2hhbmdpbmcgKG5vbi1HRVQsXG4gKiBub24tSEVBRC9PUFRJT05TKSByZXF1ZXN0cyDigJQgYSByZWplY3RlZCBHRVQgaXMgbG93LXNpZ25hbCBwcm9iaW5nIG5vaXNlIGFuZFxuICogd291bGQgYW1wbGlmeSBhdWRpdCB2b2x1bWUgdW5kZXIgYSBzY2FuLiBOZXZlciB0aHJvd3MuXG4gKi9cbmZ1bmN0aW9uIGF1ZGl0QXV0aHpEZW5pYWwocmVxOiBSZXF1ZXN0LCByZXF1aXJlZDogc3RyaW5nKTogdm9pZCB7XG4gIGNvbnN0IGF1ZGl0b3IgPSBhdXRoekRlbmlhbEF1ZGl0b3I7XG4gIGlmICghYXVkaXRvcikgcmV0dXJuO1xuICBjb25zdCBtZXRob2QgPSByZXEubWV0aG9kLnRvVXBwZXJDYXNlKCk7XG4gIGlmIChtZXRob2QgPT09ICdHRVQnIHx8IG1ldGhvZCA9PT0gJ0hFQUQnIHx8IG1ldGhvZCA9PT0gJ09QVElPTlMnKSByZXR1cm47XG4gIHRyeSB7XG4gICAgYXVkaXRvcih7XG4gICAgICBhY3RvcklkOiByZXEudXNlcj8uc3ViLFxuICAgICAgYWN0b3JFbWFpbDogcmVxLnVzZXI/LmVtYWlsLFxuICAgICAgb3JnSWQ6IHJlcS51c2VyPy5vcmdhbml6YXRpb25JZCxcbiAgICAgIG1ldGhvZCxcbiAgICAgIC8vIFN0cmlwIHRoZSBxdWVyeSBzdHJpbmcg4oCUIGEgZGVuaWVkIHJlcXVlc3QgbWF5IGNhcnJ5IGEgdG9rZW4vc2VjcmV0IGFzIGFcbiAgICAgIC8vIHF1ZXJ5IHBhcmFtLCBhbmQgdGhpcyBwYXRoIGlzIHBlcnNpc3RlZCB2ZXJiYXRpbSBpbnRvIHRoZSBhdWRpdCBsb2cuXG4gICAgICBwYXRoOiAocmVxLm9yaWdpbmFsVXJsIHx8IHJlcS51cmwpLnNwbGl0KCc/JylbMF0sXG4gICAgICByZXF1aXJlZCxcbiAgICB9KTtcbiAgfSBjYXRjaCB7XG4gICAgLy8gQmVzdC1lZmZvcnQg4oCUIGEgYnJva2VuIGF1ZGl0b3IgbXVzdCBuZXZlciBicmVhayB0aGUgYXV0aCBnYXRlLlxuICB9XG59XG5cbi8qKlxuICogUmVxdWlyZXMgdGhhdCB0aGUgdXNlciBob2xkIEFUIExFQVNUIE9ORSBvZiB0aGUgZ2l2ZW4gcGVybWlzc2lvbnMgKG9yIGJlIGFcbiAqIHN1cGVyYWRtaW4pLiBVc2UgYWZ0ZXIgcmVxdWlyZUF1dGguIE1pcnJvcnMgYHJlcXVpcmVSb2xlYCdzIGFueS1vZiBzZW1hbnRpY3M7XG4gKiBwYXNzIGEgc2luZ2xlIHBlcm1pc3Npb24gZm9yIGEgc3BlY2lmaWMgYWN0aW9uLCBvciBzZXZlcmFsIHdoZW4gYW55IG9uZSBvZlxuICogdGhlbSBzaG91bGQgZ3JhbnQgYWNjZXNzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVxdWlyZVBlcm1pc3Npb24oLi4ucGVybWlzc2lvbnM6IFBlcm1pc3Npb25bXSkge1xuICByZXR1cm4gKHJlcTogUmVxdWVzdCwgcmVzOiBSZXNwb25zZSwgbmV4dDogTmV4dEZ1bmN0aW9uKTogdm9pZCA9PiB7XG4gICAgaWYgKCFyZXEudXNlcikge1xuICAgICAgcmV0dXJuIHNlbmRFcnJvcihyZXMsIEh0dHBTdGF0dXMuVU5BVVRIT1JJWkVELCAnQXV0aGVudGljYXRpb24gcmVxdWlyZWQnLCBFcnJvckNvZGUuVU5BVVRIT1JJWkVEKTtcbiAgICB9XG4gICAgLy8gdXNlckhhc1Blcm1pc3Npb24g4oaSIGhhc1Blcm1pc3Npb24gYWxyZWFkeSBncmFudHMgc3VwZXJhZG1pbnMgZXZlcnlcbiAgICAvLyBwZXJtaXNzaW9uLCBzbyB0aGlzIHNpbmdsZSBjaGVjayBjb3ZlcnMgYm90aCB0aGUgc3VwZXJhZG1pbiBieXBhc3MgYW5kXG4gICAgLy8gdGhlIGFueS1vZiBtZW1iZXJzaGlwIHRlc3Qgd2l0aG91dCByZS1pbmxpbmluZyBlaXRoZXIuXG4gICAgaWYgKHBlcm1pc3Npb25zLnNvbWUoKHApID0+IHVzZXJIYXNQZXJtaXNzaW9uKHJlcSwgcCkpKSByZXR1cm4gbmV4dCgpO1xuICAgIGF1ZGl0QXV0aHpEZW5pYWwocmVxLCBwZXJtaXNzaW9ucy5qb2luKCcgb3IgJykpO1xuICAgIHJldHVybiBzZW5kRXJyb3IoXG4gICAgICByZXMsIEh0dHBTdGF0dXMuRk9SQklEREVOLFxuICAgICAgYE1pc3NpbmcgcmVxdWlyZWQgcGVybWlzc2lvbjogJHtwZXJtaXNzaW9ucy5qb2luKCcgb3IgJyl9YCxcbiAgICAgIEVycm9yQ29kZS5JTlNVRkZJQ0lFTlRfUEVSTUlTU0lPTlMsXG4gICAgKTtcbiAgfTtcbn1cblxuLyoqXG4gKiBSZXF1aXJlcyB0aGF0IHRoZSB1c2VyIGhvbGQgRVZFUlkgb25lIG9mIHRoZSBnaXZlbiBwZXJtaXNzaW9ucyAob3IgYmUgYVxuICogc3VwZXJhZG1pbikg4oCUIHRoZSBBTkQgY291bnRlcnBhcnQgdG8gYHJlcXVpcmVQZXJtaXNzaW9uYCdzIGFueS1vZi4gVXNlIGZvciBhXG4gKiBzZW5zaXRpdmUgYWN0aW9uIHRoYXQgbGVnaXRpbWF0ZWx5IGRlbWFuZHMgdHdvIGRpc3RpbmN0IGNhcGFiaWxpdGllcyBhdCBvbmNlXG4gKiAoZS5nLiBhIGNyb3NzLXN1cmZhY2Ugb3BlcmF0aW9uKSwgc28gdGhlIGd1YXJhbnRlZSBpcyBleHBsaWNpdCByYXRoZXIgdGhhblxuICogYXBwcm94aW1hdGVkIGJ5IGNoYWluaW5nIHR3byBgcmVxdWlyZVBlcm1pc3Npb25gIGdhdGVzLiBTdXBlcmFkbWlucyBieXBhc3NcbiAqICh0aGV5IGltcGxpY2l0bHkgaG9sZCBldmVyeSBwZXJtaXNzaW9uKS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlcXVpcmVBbGxQZXJtaXNzaW9ucyguLi5wZXJtaXNzaW9uczogUGVybWlzc2lvbltdKSB7XG4gIHJldHVybiAocmVxOiBSZXF1ZXN0LCByZXM6IFJlc3BvbnNlLCBuZXh0OiBOZXh0RnVuY3Rpb24pOiB2b2lkID0+IHtcbiAgICBpZiAoIXJlcS51c2VyKSB7XG4gICAgICByZXR1cm4gc2VuZEVycm9yKHJlcywgSHR0cFN0YXR1cy5VTkFVVEhPUklaRUQsICdBdXRoZW50aWNhdGlvbiByZXF1aXJlZCcsIEVycm9yQ29kZS5VTkFVVEhPUklaRUQpO1xuICAgIH1cbiAgICBjb25zdCBtaXNzaW5nID0gcGVybWlzc2lvbnMuZmlsdGVyKChwKSA9PiAhdXNlckhhc1Blcm1pc3Npb24ocmVxLCBwKSk7XG4gICAgaWYgKG1pc3NpbmcubGVuZ3RoID09PSAwKSByZXR1cm4gbmV4dCgpO1xuICAgIGF1ZGl0QXV0aHpEZW5pYWwocmVxLCBwZXJtaXNzaW9ucy5qb2luKCcgYW5kICcpKTtcbiAgICByZXR1cm4gc2VuZEVycm9yKFxuICAgICAgcmVzLCBIdHRwU3RhdHVzLkZPUkJJRERFTixcbiAgICAgIGBNaXNzaW5nIHJlcXVpcmVkIHBlcm1pc3Npb246ICR7bWlzc2luZy5qb2luKCcgYW5kICcpfWAsXG4gICAgICBFcnJvckNvZGUuSU5TVUZGSUNJRU5UX1BFUk1JU1NJT05TLFxuICAgICk7XG4gIH07XG59XG5cbi8qKlxuICogTGlrZSB7QGxpbmsgcmVxdWlyZVBlcm1pc3Npb259IChhbnktb2YpIGJ1dCBBTFNPIGFkbWl0cyBhbiBpbnRlcm5hbCBzZXJ2aWNlXG4gKiBwcmluY2lwYWwgKGEgYHNlcnZpY2U6KmAgbWFjaGluZSB0b2tlbikuIEZvciBSRUFEIGVuZHBvaW50cyB0aGF0IEJPVEhcbiAqIGludGVyYWN0aXZlIHVzZXJzIOKAlCB3aG8gbXVzdCBob2xkIG9uZSBvZiB0aGUgYDpyZWFkYCBjYXBhYmlsaXRpZXMg4oCUIEFORFxuICogc2VydmljZS10by1zZXJ2aWNlIGNhbGxlcnMgbGVnaXRpbWF0ZWx5IGhpdDsgc2VydmljZSB0b2tlbnMgY2Fycnkgbm9cbiAqIHBlcm1pc3Npb24gY2xhaW1zICh0aGV5J3JlIGxlYXN0LXByaXZpbGVnZSBgcm9sZTptZW1iZXJgKSwgc28gYSBwbGFpblxuICogYHJlcXVpcmVQZXJtaXNzaW9uYCB3b3VsZCB3cm9uZ2x5IDQwMyB0aGVtLiBTdXBlcmFkbWlucyBwYXNzIHZpYVxuICogYHVzZXJIYXNQZXJtaXNzaW9uYCdzIGltcGxpY2l0LWFsbC4gVXNlIG9ubHkgd2hlcmUgYSBzZXJ2aWNlIGNhbGxlciBpcyBhIGtub3duLFxuICogaW50ZW5kZWQgY29uc3VtZXIgb2YgdGhlIHJvdXRlICh2ZXJpZnkgdGhlIGNhbGxlcnMpOyBwcmVmZXIgcGxhaW5cbiAqIGByZXF1aXJlUGVybWlzc2lvbmAgZm9yIHB1cmVseSB1c2VyLWZhY2luZyByZWFkcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlcXVpcmVQZXJtaXNzaW9uT3JTZXJ2aWNlKC4uLnBlcm1pc3Npb25zOiBQZXJtaXNzaW9uW10pIHtcbiAgcmV0dXJuIChyZXE6IFJlcXVlc3QsIHJlczogUmVzcG9uc2UsIG5leHQ6IE5leHRGdW5jdGlvbik6IHZvaWQgPT4ge1xuICAgIGlmICghcmVxLnVzZXIpIHtcbiAgICAgIHJldHVybiBzZW5kRXJyb3IocmVzLCBIdHRwU3RhdHVzLlVOQVVUSE9SSVpFRCwgJ0F1dGhlbnRpY2F0aW9uIHJlcXVpcmVkJywgRXJyb3JDb2RlLlVOQVVUSE9SSVpFRCk7XG4gICAgfVxuICAgIGlmIChpc1NlcnZpY2VQcmluY2lwYWwocmVxKSB8fCBwZXJtaXNzaW9ucy5zb21lKChwKSA9PiB1c2VySGFzUGVybWlzc2lvbihyZXEsIHApKSkgcmV0dXJuIG5leHQoKTtcbiAgICBhdWRpdEF1dGh6RGVuaWFsKHJlcSwgcGVybWlzc2lvbnMuam9pbignIG9yICcpKTtcbiAgICByZXR1cm4gc2VuZEVycm9yKFxuICAgICAgcmVzLCBIdHRwU3RhdHVzLkZPUkJJRERFTixcbiAgICAgIGBNaXNzaW5nIHJlcXVpcmVkIHBlcm1pc3Npb246ICR7cGVybWlzc2lvbnMuam9pbignIG9yICcpfWAsXG4gICAgICBFcnJvckNvZGUuSU5TVUZGSUNJRU5UX1BFUk1JU1NJT05TLFxuICAgICk7XG4gIH07XG59XG5cbi8qKlxuICogR2F0ZSBhbiBlbmRwb2ludCB0byBpbnRlcm5hbCBzZXJ2aWNlLXRvLXNlcnZpY2UgY2FsbGVycyBvbmx5IChhIGBzZXJ2aWNlOipgXG4gKiBtYWNoaW5lIHByaW5jaXBhbCBtaW50ZWQgdmlhIHtAbGluayBzaWduU2VydmljZVRva2VufSAvIGBnZXRTZXJ2aWNlQXV0aEhlYWRlcmApLlxuICogUmVqZWN0cyBhbnkgdXNlciB0b2tlbi4gRm9yIE5PTi11c2VyLWZhY2luZyBlbmRwb2ludHMg4oCUIGVudGl0eS1ldmVudCBpbmdlc3QsXG4gKiBhdXRvLXN1YnNjcmliZSwgYW5kIHNpbWlsYXIgcGVlci1zZXJ2aWNlIGhvb2tzIOKAlCB0aGF0IGEgYnJvd3NlciBtdXN0IG5ldmVyXG4gKiByZWFjaC4gQ29tcG9zZSBhZnRlciBgcmVxdWlyZUF1dGhgIHNvIGByZXEudXNlcmAgaXMgcG9wdWxhdGVkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVxdWlyZVNlcnZpY2VQcmluY2lwYWwocmVxOiBSZXF1ZXN0LCByZXM6IFJlc3BvbnNlLCBuZXh0OiBOZXh0RnVuY3Rpb24pOiB2b2lkIHtcbiAgaWYgKCFpc1NlcnZpY2VQcmluY2lwYWwocmVxKSkge1xuICAgIC8vIDQwMyAobm90IDQwMCkg4oCUIHRoaXMgaXMgYW4gYXV0aG9yaXphdGlvbiByZWZ1c2FsOyBzdGF0dXMgbXVzdCBtYXRjaCB0aGVcbiAgICAvLyBJTlNVRkZJQ0lFTlRfUEVSTUlTU0lPTlMgY29kZSBhbmQgdGhlIHNpYmxpbmcgZ2F0ZXMgKHJlcXVpcmVQZXJtaXNzaW9uLCBldGMuKS5cbiAgICByZXR1cm4gc2VuZEVycm9yKHJlcywgSHR0cFN0YXR1cy5GT1JCSURERU4sICdJbnRlcm5hbCBzZXJ2aWNlIGNhbGxzIG9ubHknLCBFcnJvckNvZGUuSU5TVUZGSUNJRU5UX1BFUk1JU1NJT05TKTtcbiAgfVxuICBuZXh0KCk7XG59XG5cbi8qKlxuICogVGhlIHN5c3RlbSB0ZW5hbnQncyBjYW5vbmljYWwgb3JnICoqaWQqKiDigJQgYSBmaXhlZCwgd2VsbC1rbm93biBPYmplY3RJZCAoTk9UXG4gKiB0aGUgc3RyaW5nICdzeXN0ZW0nKS4gVGhpcyBpcyB0aGUgc2luZ2xlIGtub2IgZXZlcnkgc2VydmljZSByZXNvbHZlcyB0aGVcbiAqIHN5c3RlbSB0ZW5hbnQgdGhyb3VnaDsgb3ZlcnJpZGUgdmlhIHRoZSBgU1lTVEVNX09SR19JRGAgZW52IGZvciBhbHRlcm5hdGVcbiAqIGluc3RhbGxzLiBUaGUgc3lzdGVtIG9yZydzIGh1bWFuIGlkZW50aWZpZXIgc3RheXMgdGhlIHNsdWcvbmFtZSAnc3lzdGVtJ1xuICogKHNlZSB7QGxpbmsgU1lTVEVNX09SR19TTFVHfSk7IG9ubHkgaXRzIGBfaWRgIGlzIHRoaXMgT2JqZWN0SWQuXG4gKi9cbmV4cG9ydCBjb25zdCBTWVNURU1fT1JHX0lEID0gKHByb2Nlc3MuZW52LlNZU1RFTV9PUkdfSUQgfHwgJzAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMScpLnRvTG93ZXJDYXNlKCk7XG5cbi8qKiBUaGUgc3lzdGVtIG9yZydzIHdlbGwta25vd24gc2x1Zy9uYW1lICh0aGUgaHVtYW4gaWRlbnRpZmllcjsgaXRzIGBfaWRgIGlzIHtAbGluayBTWVNURU1fT1JHX0lEfSkuICovXG5leHBvcnQgY29uc3QgU1lTVEVNX09SR19TTFVHID0gJ3N5c3RlbSc7XG5cbi8qKlxuICogQ2hlY2sgaWYgYW4gb3JnSWQgb3Igb3JnTmFtZS9zbHVnIG1hdGNoZXMgdGhlIHN5c3RlbSBvcmcuIFVzZSB0aGlzIGluc3RlYWQgb2ZcbiAqIGNvbXBhcmluZyBkaXJlY3RseTogdGhlIGlkIGlzIG5vdyBhbiBPYmplY3RJZCAoe0BsaW5rIFNZU1RFTV9PUkdfSUR9KSB3aGlsZSB0aGVcbiAqIG5hbWUvc2x1ZyBpcyAnc3lzdGVtJyAoe0BsaW5rIFNZU1RFTV9PUkdfU0xVR30pLCBzbyB0aGUgdHdvIGFyZSBjb21wYXJlZCBhZ2FpbnN0XG4gKiB0aGVpciByZXNwZWN0aXZlIGNhbm9uaWNhbCB2YWx1ZXMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1N5c3RlbU9yZ0lkKG9yZ0lkPzogc3RyaW5nLCBvcmdOYW1lPzogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHJldHVybiBvcmdJZD8udG9Mb3dlckNhc2UoKSA9PT0gU1lTVEVNX09SR19JRCB8fCBvcmdOYW1lPy50b0xvd2VyQ2FzZSgpID09PSBTWVNURU1fT1JHX1NMVUc7XG59XG5cbi8qKlxuICogQ2hlY2sgaWYgdGhlIHJlcXVlc3QgaXMgZnJvbSBhIHN5c3RlbSBhZG1pbi5cbiAqXG4gKiBBdXRob3JpdHkgaXMgZ3JhbnRlZCBzb2xlbHkgYnkgdGhlIHVzZXItbGV2ZWwgYGlzU3VwZXJBZG1pbmAgZmxhZyBjYXJyaWVkXG4gKiBpbiB0aGUgSldULiBUaGUgXCJtZW1iZXJzaGlwIGluIHRoZSB3ZWxsLWtub3duICdzeXN0ZW0nIG9yZyB3aXRoIHJvbGVcbiAqIGFkbWluL293bmVyXCIgcGF0aCB3YXMgcmVtb3ZlZCDigJQgaXQgY29uZmxhdGVkIGEgUGlwZWxpbmUgQnVpbGRlciBvcGVyYXRvclxuICogd2l0aCBhIHJlYWwgY3VzdG9tZXIgdGVuYW50IGluIHRoZSBkYXRhIG1vZGVsLCBhbmQgbWVhbnQgYW55IHVuaW50ZW5kZWRcbiAqIHdyaXRlIHRoYXQgY3JlYXRlZCBhICdzeXN0ZW0nLW5hbWVkIG9yZyBjb3VsZCBxdWlldGx5IGdyYW50IGNyb3NzLW9yZ1xuICogYXV0aG9yaXR5LiBUaGUgYHN5c3RlbWAgb3JnIHN0aWxsIGV4aXN0cyBhcyBhICpjb250ZW50IGhvbGRlciogZm9yIHNoYXJlZFxuICogc2FtcGxlIGRhdGE7IGl0IGp1c3Qgbm8gbG9uZ2VyIGNvbmZlcnMgcHJpdmlsZWdlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNTeXN0ZW1BZG1pbihyZXE6IFJlcXVlc3QpOiBib29sZWFuIHtcbiAgcmV0dXJuIHJlcS51c2VyPy5pc1N1cGVyQWRtaW4gPT09IHRydWU7XG59XG5cbi8qKlxuICogV2hldGhlciB0aGUgcmVxdWVzdCdzIHRva2VuIGNhcnJpZXMgYSBzcGVjaWZpYyBjYXBhYmlsaXR5IGBzY29wZWAgKGUuZy5cbiAqIGAncmVwb3J0aW5nOmluZ2VzdCdgKS4gVXNlZCB0byBnYXRlIGVuZHBvaW50cyB0aGF0IGFjY2VwdCBhIG5hcnJvdyBtYWNoaW5lXG4gKiBpZGVudGl0eSDigJQgYSBub3JtYWwgaW50ZXJhY3RpdmUgdXNlciB0b2tlbiBoYXMgbm8gYHNjb3BlYCBhbmQgcmV0dXJucyBmYWxzZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGhhc1Njb3BlKHJlcTogUmVxdWVzdCwgc2NvcGU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICByZXR1cm4gcmVxLnVzZXI/LnNjb3BlID09PSBzY29wZTtcbn1cblxuLyoqIFJlcXVpcmVzIGEgc3lzdGVtIGFkbWluIOKAlCBncmFudGVkIHNvbGVseSBieSB0aGUgYGlzU3VwZXJBZG1pbmAgdG9rZW4gY2xhaW1cbiAqICAodGhlIG9yZy1tZW1iZXJzaGlwIHBhdGggd2FzIHJlbW92ZWQpLiBVc2UgYWZ0ZXIgcmVxdWlyZUF1dGguICovXG5leHBvcnQgZnVuY3Rpb24gcmVxdWlyZVN5c3RlbUFkbWluKFxuICByZXE6IFJlcXVlc3QsXG4gIHJlczogUmVzcG9uc2UsXG4gIG5leHQ6IE5leHRGdW5jdGlvbixcbik6IHZvaWQge1xuICBpZiAoIWlzU3lzdGVtQWRtaW4ocmVxKSkge1xuICAgIGF1ZGl0QXV0aHpEZW5pYWwocmVxLCAnc3lzdGVtLWFkbWluJyk7XG4gICAgcmV0dXJuIHNlbmRFcnJvcihcbiAgICAgIHJlcywgSHR0cFN0YXR1cy5GT1JCSURERU4sXG4gICAgICAnQWNjZXNzIGRlbmllZC4gT25seSBzeXN0ZW0gYWRtaW5pc3RyYXRvcnMgY2FuIHBlcmZvcm0gdGhpcyBhY3Rpb24uJyxcbiAgICAgIEVycm9yQ29kZS5JTlNVRkZJQ0lFTlRfUEVSTUlTU0lPTlMsXG4gICAgKTtcbiAgfVxuICBuZXh0KCk7XG59XG5cbi8qKlxuICogUmVxdWlyZSBhIHNwZWNpZmljIGZlYXR1cmUgZmxhZy4gVXNlIGFmdGVyIHJlcXVpcmVBdXRoLlxuICogQ2hlY2tzIHRoZSBgZmVhdHVyZXNgIGFycmF5IGluIHRoZSBKV1QgcGF5bG9hZCAoc2V0IGF0IHRva2VuIGlzc3VhbmNlKS5cbiAqIFN5c2FkbWlucyAoaXNTdXBlckFkbWluKSBieXBhc3Mg4oCUIHRoZXkgYWx3YXlzIGhhdmUgZXZlcnkgZmVhdHVyZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlcXVpcmVGZWF0dXJlKGZlYXR1cmU6IHN0cmluZykge1xuICByZXR1cm4gKHJlcTogUmVxdWVzdCwgcmVzOiBSZXNwb25zZSwgbmV4dDogTmV4dEZ1bmN0aW9uKTogdm9pZCA9PiB7XG4gICAgaWYgKCFyZXEudXNlcikge1xuICAgICAgcmV0dXJuIHNlbmRFcnJvcihyZXMsIEh0dHBTdGF0dXMuVU5BVVRIT1JJWkVELCAnQXV0aGVudGljYXRpb24gcmVxdWlyZWQnLCBFcnJvckNvZGUuVU5BVVRIT1JJWkVEKTtcbiAgICB9XG5cbiAgICAvLyBTeXNhZG1pbnMgZ2V0IGFsbCBmZWF0dXJlczsgdGhlIGBmZWF0dXJlc2AgYXJyYXkgb24gdGhlaXIgdG9rZW4gaXNcbiAgICAvLyBwb3B1bGF0ZWQgd2l0aCBldmVyeSBmbGFnIGF0IGlzc3VhbmNlIHRpbWUgYnV0IHRoZSBieXBhc3MgaGVyZSBrZWVwc1xuICAgIC8vIHRoZSBydWxlIGV4cGxpY2l0IGFuZCBzdXJ2aXZlcyBhIHRva2VuIGlzc3VlZCBiZWZvcmUgYSBuZXcgZmVhdHVyZVxuICAgIC8vIGZsYWcgd2FzIGFkZGVkLlxuICAgIGlmIChyZXEudXNlci5pc1N1cGVyQWRtaW4gPT09IHRydWUpIHJldHVybiBuZXh0KCk7XG5cbiAgICBpZiAoIXJlcS51c2VyLmZlYXR1cmVzPy5pbmNsdWRlcyhmZWF0dXJlKSkge1xuICAgICAgLy8gUm91dGUgZmVhdHVyZS1nYXRlIGRlbmlhbHMgdGhyb3VnaCB0aGUgc2FtZSBhdWRpdCBzaW5rIGFzXG4gICAgICAvLyByZXF1aXJlUGVybWlzc2lvbiAvIHJlcXVpcmVTeXN0ZW1BZG1pbiBzbyBhIHByb2JlIGZvciBhblxuICAgICAgLy8gdW5lbnRpdGxlZCBjYXBhYmlsaXR5IGxlYXZlcyBhIHRyYWlsIChzdGF0ZS1jaGFuZ2luZyBtZXRob2RzIG9ubHkpLlxuICAgICAgYXVkaXRBdXRoekRlbmlhbChyZXEsIGBmZWF0dXJlOiR7ZmVhdHVyZX1gKTtcbiAgICAgIHJldHVybiBzZW5kRXJyb3IoXG4gICAgICAgIHJlcywgSHR0cFN0YXR1cy5GT1JCSURERU4sXG4gICAgICAgIGBUaGlzIGZlYXR1cmUgcmVxdWlyZXMgYSBoaWdoZXIgcGxhbiAoJHtmZWF0dXJlfSlgLFxuICAgICAgICBFcnJvckNvZGUuSU5TVUZGSUNJRU5UX1BFUk1JU1NJT05TLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBuZXh0KCk7XG4gIH07XG59XG5cbi8qKlxuICogUmVzb2x2ZSB0aGUgZWZmZWN0aXZlIGFjY2VzcyBtb2RpZmllciBmb3IgYW4gZW50aXR5IGJlaW5nIGNyZWF0ZWQvdXBkYXRlZC5cbiAqICdwdWJsaWMnIGlzIHBlcm1pdHRlZCBvbmx5IGZvciBhIGNhbGxlciBob2xkaW5nIHRoZSByZWxldmFudCBwdWJsaXNoXG4gKiBjYXBhYmlsaXR5IChgcGlwZWxpbmVzOnB1Ymxpc2hgIC8gYHBsdWdpbnM6cHVibGlzaGApIOKAlCBzdXBlcmFkbWlucyBwYXNzIHZpYVxuICogaW1wbGljaXQtYWxsLiBFdmVyeW9uZSBlbHNlIChpbmNsdWRpbmcgY2FsbGVycyB3aG8gcmVxdWVzdGVkICdwdWJsaWMnIHdpdGhvdXRcbiAqIHRoZSBwZXJtaXNzaW9uLCBhbmQgc2VydmljZSBwcmluY2lwYWxzKSBnZXRzICdwcml2YXRlJy5cbiAqXG4gKiBQZXJtaXNzaW9uLWJhc2VkIChub3QgY29hcnNlLXJvbGUtYmFzZWQpOiBhIGJlc3Bva2UgY3VzdG9tIFJvbGUgY2FuIGJlIGdyYW50ZWRcbiAqIHB1Ymxpc2ggcmlnaHRzIGFuZCBpcyBubyBsb25nZXIgZm9yY2VkIHByaXZhdGUgYnkgaXRzIGBtZW1iZXJgIGxhYmVsLiBCdWlsdC1pblxuICogQWRtaW4vT3duZXIgYnVuZGxlcyBjYXJyeSB0aGUgcHVibGlzaCBwZXJtaXNzaW9ucywgc28gdGhlaXIgYmVoYXZpb3IgaXNcbiAqIHVuY2hhbmdlZDsgdGhlIGJ1aWx0LWluIE1lbWJlciBidW5kbGUgZG9lcyBub3QsIHNvIG1lbWJlcnMgc3RheSBwcml2YXRlLW9ubHkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlQWNjZXNzTW9kaWZpZXIoXG4gIHJlcTogUmVxdWVzdCxcbiAgcmVxdWVzdGVkOiBzdHJpbmcgfCB1bmRlZmluZWQsXG4gIHB1Ymxpc2hQZXJtaXNzaW9uOiBQZXJtaXNzaW9uLFxuKTogJ3B1YmxpYycgfCAncHJpdmF0ZScge1xuICBpZiAocmVxdWVzdGVkID09PSAncHVibGljJyAmJiB1c2VySGFzUGVybWlzc2lvbihyZXEsIHB1Ymxpc2hQZXJtaXNzaW9uKSkge1xuICAgIHJldHVybiAncHVibGljJztcbiAgfVxuICByZXR1cm4gJ3ByaXZhdGUnO1xufVxuXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFNlcnZpY2UtdG8tc2VydmljZSB0b2tlbnNcbi8vXG4vLyBJbnRlci1zZXJ2aWNlIEhUVFAgY2FsbHMgKGJpbGxpbmcg4oaSIG1lc3NhZ2UsIHBsYXRmb3JtIOKGkiBjb21wbGlhbmNlLCBldGMuKVxuLy8gbmVlZCB0byBzYXRpc2Z5IHRoZSBzYW1lIGByZXF1aXJlQXV0aGAgbWlkZGxld2FyZSBhcyB1c2VyIHJlcXVlc3RzLlxuLy8gYHNpZ25TZXJ2aWNlVG9rZW5gIG1pbnRzIGEgc2hvcnQtbGl2ZWQgSldUIHNpZ25lZCB3aXRoIHRoZSBzaGFyZWRcbi8vIEpXVF9TRUNSRVQsIGlkZW50aWZ5aW5nIHRoZSBjYWxsaW5nIHNlcnZpY2UgdmlhIGBzdWI6ICdzZXJ2aWNlOjxuYW1lPidgLlxuLy8gYHJlcXVpcmVBdXRoYCBhY2NlcHRzIHRoZXNlIHRva2VucyB0cmFuc3BhcmVudGx5IOKAlCB0aGV5IHBhc3MgYGRlY29kZWQuc3ViYFxuLy8gYW5kIGBkZWNvZGVkLnJvbGVgIGNoZWNrcywgYW5kIGRvd25zdHJlYW0gYHJlcXVpcmVPcmdhbml6YXRpb25gIC9cbi8vIGByZXF1aXJlU3lzdGVtQWRtaW5gIHJlbHkgb24gdGhlIG9yZy9yb2xlIGVtYmVkZGVkIGluIHRoZSB0b2tlbi5cbi8vXG4vLyBUb2tlbnMgZGVmYXVsdCB0byA1LW1pbnV0ZSBUVEwg4oCUIGxvbmcgZW5vdWdoIHRvIHN1cnZpdmUgYSBiYWNrZW5kIGhvcCxcbi8vIHNob3J0IGVub3VnaCB0aGF0IGEgbGVha2VkIHRva2VuIGlzIGxvdy12YWx1ZS5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5jb25zdCBERUZBVUxUX1NFUlZJQ0VfVE9LRU5fVFRMX1NFQ09ORFMgPSAzMDA7XG5cbmV4cG9ydCBpbnRlcmZhY2UgU2VydmljZVRva2VuT3B0aW9ucyB7XG4gIC8qKiBDYWxsaW5nIHNlcnZpY2UgaWRlbnRpZmllciAoZS5nLiAnYmlsbGluZycsICdwbGF0Zm9ybScpLiBFbWJlZGRlZCBhcyBgc3ViOiBzZXJ2aWNlOjxuYW1lPmAuICovXG4gIHNlcnZpY2VOYW1lOiBzdHJpbmc7XG4gIC8qKiBBY3RpdmUgb3JnIGNvbnRleHQgZm9yIHRoZSBjYWxsLiBVc2UgdGhlIHRhcmdldCB0ZW5hbnQncyBvcmcgaWQsIG9yIHRoZVxuICAgKiAgd2VsbC1rbm93biBgU1lTVEVNX09SR19JRGAgKGFuIE9iamVjdElkKSBmb3Igc3lzdGVtLXdpZGUgb3BzIOKAlCBOT1QgdGhlIHN0cmluZ1xuICAgKiAgJ3N5c3RlbScsIHdoaWNoIGlkLWJhc2VkIHN5c3RlbS1vcmcgY2hlY2tzIHdvbid0IHJlY29nbml6ZS4gKi9cbiAgb3JnSWQ/OiBzdHJpbmc7XG4gIC8qKiBBY3RpdmUgb3JnIG5hbWUuIERlZmF1bHRzIHRvIG9yZ0lkLiAqL1xuICBvcmdOYW1lPzogc3RyaW5nO1xuICAvKiogVFRMIGluIHNlY29uZHMgKGRlZmF1bHQgMzAwKS4gKi9cbiAgdHRsU2Vjb25kcz86IG51bWJlcjtcbiAgLyoqXG4gICAqIFJvbGUgdGhlIHRva2VuIGNhcnJpZXMgKHJlcXVpcmVkIOKAlCBubyBpbXBsaWNpdCBkZWZhdWx0KS4gKipQYXNzIHRoZSBMT1dFU1RcbiAgICogcm9sZSB0aGUgY2FsbCBhY3R1YWxseSBuZWVkcyoqIChgJ21lbWJlcidgIGZvciByZWFkIC8gZGF0YS1wbGFuZSBjYWxscykgc28gYVxuICAgKiBsZWFrZWQgc2VydmljZSB0b2tlbiBjYW4ndCBwZXJmb3JtIGFkbWluIGFjdGlvbnMgaW4gdGhlIHRhcmdldCBvcmcuXG4gICAqIGBpc0FkbWluYCBpcyBkZXJpdmVkIGZyb20gdGhpcyAoYWRtaW58b3duZXIg4oaSIHRydWUpLlxuICAgKi9cbiAgcm9sZTogJ293bmVyJyB8ICdhZG1pbicgfCAnbWVtYmVyJztcbn1cblxuLyoqXG4gKiBNaW50IGEgSldUIGlkZW50aWZ5aW5nIHRoZSBjYWxsaW5nIHNlcnZpY2UuIFVzZWQgZm9yIGludGVyLXNlcnZpY2UgSFRUUCBjYWxscy5cbiAqIFRoZSB0b2tlbiBzYXRpc2ZpZXMgYHJlcXVpcmVBdXRoYCBhbmQgKHdoZW4gb3JnSWQgaXMgcHJlc2VudCkgYHJlcXVpcmVPcmdhbml6YXRpb25gLlxuICogU2NvcGUgaXQgd2l0aCBgb3B0cy5yb2xlYCDigJQgbGVhc3QgcHJpdmlsZWdlIGtlZXBzIGEgbGVha2VkIHRva2VuIGxvdy12YWx1ZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNpZ25TZXJ2aWNlVG9rZW4ob3B0czogU2VydmljZVRva2VuT3B0aW9ucyk6IHN0cmluZyB7XG4gIGNvbnN0IHJvbGUgPSBvcHRzLnJvbGU7XG4gIGNvbnN0IHBheWxvYWQ6IEp3dFBheWxvYWQgPSB7XG4gICAgc3ViOiBgc2VydmljZToke29wdHMuc2VydmljZU5hbWV9YCxcbiAgICB1c2VybmFtZTogYCR7b3B0cy5zZXJ2aWNlTmFtZX0tc2VydmljZWAsXG4gICAgZW1haWw6IGAke29wdHMuc2VydmljZU5hbWV9QGludGVybmFsYCxcbiAgICByb2xlLFxuICAgIGlzQWRtaW46IHJvbGUgPT09ICdvd25lcicgfHwgcm9sZSA9PT0gJ2FkbWluJyxcbiAgICB0eXBlOiAnYWNjZXNzJyxcbiAgICBvcmdhbml6YXRpb25JZDogb3B0cy5vcmdJZCxcbiAgICBvcmdhbml6YXRpb25OYW1lOiBvcHRzLm9yZ05hbWUgPz8gb3B0cy5vcmdJZCxcbiAgfTtcbiAgLy8gTWF0Y2ggdGhlIG9wdGlvbmFsIGlzc3Vlci9hdWRpZW5jZSB0aGF0IHJlcXVpcmVBdXRoIHZlcmlmaWVzLCB3aGVuXG4gIC8vIGNvbmZpZ3VyZWQuIFdpdGhvdXQgdGhlc2UsIGEgc2VydmljZSB0b2tlbiBzaWduZWQgaGVyZSB3b3VsZCBmYWlsXG4gIC8vIHJlcXVpcmVBdXRoIGluIGEgZGVwbG95bWVudCB0aGF0IGhhcyBzZXQgSldUX0lTU1VFUi9KV1RfQVVESUVOQ0UuXG4gIGNvbnN0IHNpZ25PcHRpb25zOiBqd3QuU2lnbk9wdGlvbnMgPSB7XG4gICAgZXhwaXJlc0luOiBvcHRzLnR0bFNlY29uZHMgPz8gREVGQVVMVF9TRVJWSUNFX1RPS0VOX1RUTF9TRUNPTkRTLFxuICAgIC8vIFNpZ24gd2l0aCB0aGUgc2FtZSBjb25maWd1cmVkIGFsZyByZXF1aXJlQXV0aCBwaW5zIG9uIHZlcmlmeSwgc28gc2VydmljZVxuICAgIC8vIHRva2VucyBzdGF5IHZhbGlkIHVuZGVyIGEgbm9uLWRlZmF1bHQgSldUX0FMR09SSVRITS5cbiAgICBhbGdvcml0aG06IChwcm9jZXNzLmVudi5KV1RfQUxHT1JJVEhNIHx8ICdIUzI1NicpIGFzIGp3dC5BbGdvcml0aG0sXG4gICAgLy8gVW5pcXVlIHRva2VuIGlkIG9uIGV2ZXJ5IG1pbnQuIENvbWJpbmVkIHdpdGggdGhlIHNob3J0ICgzMDBzIGRlZmF1bHQpIFRUTFxuICAgIC8vIHRoaXMgZ2l2ZXMgZWFjaCBzZXJ2aWNlIHRva2VuIGEgZGlzdGluY3QgaWRlbnRpdHkg4oCUIHRoZSBidWlsZGluZyBibG9jayBmb3JcbiAgICAvLyByZXBsYXkgZGV0ZWN0aW9uIChhIHZlcmlmaWVyIGNhbiB0cmFjayBzZWVuIGp0aXMpIGFuZCB0aGUgY29ycmVsYXRpb25cbiAgICAvLyBoYW5kbGUgZm9yIHRyYWNpbmcgd2hpY2ggbWludCBwZXJmb3JtZWQgYSBjcm9zcy1zZXJ2aWNlIGFjdGlvbi4gSXQgZG9lc1xuICAgIC8vIE5PVCBieSBpdHNlbGYgcHJldmVudCByZXBsYXkgd2l0aGluIHRoZSBUVEwgd2luZG93OyB0cnVlIHJlcGxheSBkZWZlbmNlXG4gICAgLy8gbmVlZHMgdGhlIGFzeW1tZXRyaWMta2V5IHdvcmsgdHJhY2tlZCBzZXBhcmF0ZWx5LlxuICAgIGp3dGlkOiByYW5kb21VVUlEKCksXG4gIH07XG4gIGlmIChwcm9jZXNzLmVudi5KV1RfSVNTVUVSKSBzaWduT3B0aW9ucy5pc3N1ZXIgPSBwcm9jZXNzLmVudi5KV1RfSVNTVUVSO1xuICBpZiAocHJvY2Vzcy5lbnYuSldUX0FVRElFTkNFKSBzaWduT3B0aW9ucy5hdWRpZW5jZSA9IHByb2Nlc3MuZW52LkpXVF9BVURJRU5DRTtcbiAgcmV0dXJuIGp3dC5zaWduKHBheWxvYWQsIGdldEp3dFNlY3JldCgpLCBzaWduT3B0aW9ucyk7XG59XG5cbi8qKiBDb252ZW5pZW5jZTogcmV0dXJucyBhIGBCZWFyZXIgPHRva2VuPmAgaGVhZGVyIHZhbHVlIGZvciBmZXRjaC9heGlvcyBjYWxscy4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRTZXJ2aWNlQXV0aEhlYWRlcihvcHRzOiBTZXJ2aWNlVG9rZW5PcHRpb25zKTogc3RyaW5nIHtcbiAgcmV0dXJuIGBCZWFyZXIgJHtzaWduU2VydmljZVRva2VuKG9wdHMpfWA7XG59XG5cbi8qKiBUcnVlIHdoZW4gYHJlcS51c2VyLnN1YmAgd2FzIGlzc3VlZCBieSBgc2lnblNlcnZpY2VUb2tlbmAgKGkuZS4gc3RhcnRzIHdpdGggYHNlcnZpY2U6YCkuICovXG5leHBvcnQgZnVuY3Rpb24gaXNTZXJ2aWNlUHJpbmNpcGFsKHJlcTogUmVxdWVzdCk6IGJvb2xlYW4ge1xuICByZXR1cm4gcmVxLnVzZXI/LnN1Yj8uc3RhcnRzV2l0aCgnc2VydmljZTonKSA/PyBmYWxzZTtcbn1cblxuLyoqXG4gKiBQUkUtYXV0aCBjaGVjazogY3J5cHRvZ3JhcGhpY2FsbHkgdmVyaWZ5IHRoZSByZXF1ZXN0IGNhcnJpZXMgYSB2YWxpZCwgc2lnbmVkXG4gKiBTRVJWSUNFIHRva2VuIChgc3ViYCBzdGFydHMgd2l0aCBgc2VydmljZTpgKS4gVW5saWtlIHtAbGluayBpc1NlcnZpY2VQcmluY2lwYWx9XG4gKiAod2hpY2ggcmVhZHMgdGhlIGFscmVhZHktcG9wdWxhdGVkIGByZXEudXNlcmApLCB0aGlzIHZlcmlmaWVzIHRoZSBiZWFyZXIgdG9rZW5cbiAqIGl0c2VsZiwgc28gaXQgaXMgc2FmZSB0byBjYWxsIEJFRk9SRSBgcmVxdWlyZUF1dGhgIHJ1bnMg4oCUIGUuZy4gdGhlIGdsb2JhbCByYXRlXG4gKiBsaW1pdGVyJ3MgYHNraXBgLCB3aGljaCBtdXN0IG5vdCB0cnVzdCB0aGUgc3Bvb2ZhYmxlIGB4LWludGVybmFsLXNlcnZpY2VgXG4gKiBoZWFkZXIuIE1pcnJvcnMgYHJlcXVpcmVBdXRoYCdzIHZlcmlmaWNhdGlvbiAoYWxnb3JpdGhtIHBpbm5pbmcgKyBvcHRpb25hbFxuICogaXNzdWVyL2F1ZGllbmNlKSBhbmQgcmV0dXJucyBgZmFsc2VgIG9uIGFueSBtaXNzaW5nL2ludmFsaWQvbm9uLXNlcnZpY2UgdG9rZW4uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2ZXJpZnlTZXJ2aWNlUHJpbmNpcGFsKHJlcTogUmVxdWVzdCk6IGJvb2xlYW4ge1xuICBjb25zdCBwYXJ0cyA9IHJlcS5oZWFkZXJzLmF1dGhvcml6YXRpb24/LnNwbGl0KCcgJyk7XG4gIGlmICghcGFydHMgfHwgcGFydHMubGVuZ3RoICE9PSAyIHx8IHBhcnRzWzBdICE9PSAnQmVhcmVyJykgcmV0dXJuIGZhbHNlO1xuICB0cnkge1xuICAgIGNvbnN0IHZlcmlmeU9wdGlvbnM6IGp3dC5WZXJpZnlPcHRpb25zID0geyBhbGdvcml0aG1zOiBbKHByb2Nlc3MuZW52LkpXVF9BTEdPUklUSE0gfHwgJ0hTMjU2JykgYXMgand0LkFsZ29yaXRobV0gfTtcbiAgICBpZiAocHJvY2Vzcy5lbnYuSldUX0lTU1VFUikgdmVyaWZ5T3B0aW9ucy5pc3N1ZXIgPSBwcm9jZXNzLmVudi5KV1RfSVNTVUVSO1xuICAgIGlmIChwcm9jZXNzLmVudi5KV1RfQVVESUVOQ0UpIHZlcmlmeU9wdGlvbnMuYXVkaWVuY2UgPSBwcm9jZXNzLmVudi5KV1RfQVVESUVOQ0U7XG4gICAgY29uc3QgZGVjb2RlZCA9IHZlcmlmeUp3dFdpdGhSb3RhdGlvbihwYXJ0c1sxXSwgdmVyaWZ5T3B0aW9ucyk7XG4gICAgcmV0dXJuIGRlY29kZWQudHlwZSA9PT0gJ2FjY2VzcycgJiYgdHlwZW9mIGRlY29kZWQuc3ViID09PSAnc3RyaW5nJyAmJiBkZWNvZGVkLnN1Yi5zdGFydHNXaXRoKCdzZXJ2aWNlOicpO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cbiJdfQ==
588
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXV0aC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9taWRkbGV3YXJlL2F1dGgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQUV0QyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sUUFBUSxDQUFDO0FBRXBDLE9BQU8sR0FBRyxNQUFNLGNBQWMsQ0FBQztBQUMvQixPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFFekQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBRXBELE9BQU8sRUFBbUIsYUFBYSxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDekUsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3RELE9BQU8sRUFBRSxXQUFXLEVBQXdCLE1BQU0sc0JBQXNCLENBQUM7QUFDekUsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ2xELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUN6RCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFFakQsTUFBTSxNQUFNLEdBQUcsWUFBWSxDQUFDLGlCQUFpQixDQUFDLENBQUM7QUFFL0MsNERBQTREO0FBQzVELElBQUksVUFBOEIsQ0FBQztBQUNuQyxJQUFJLHFCQUFxQixHQUFHLENBQUMsQ0FBQztBQUM5Qiw4RUFBOEU7QUFDOUUsSUFBSSxrQkFBc0MsQ0FBQztBQUMzQyxJQUFJLDZCQUE2QixHQUFHLENBQUMsQ0FBQztBQUN0QyxNQUFNLDhCQUE4QixHQUFHLE9BQU8sQ0FBQyxDQUFDLFlBQVk7QUFFNUQsU0FBUyxZQUFZO0lBQ25CLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztJQUN2QixJQUFJLENBQUMsVUFBVSxJQUFJLEdBQUcsR0FBRyxxQkFBcUIsR0FBRyw4QkFBOEIs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Q0FBQyxFQUFFLGFBQWEsQ0FBQyxDQUFDO1FBQy9ELElBQUksT0FBTyxDQUFDLElBQUksS0FBSyxRQUFRLElBQUksT0FBTyxPQUFPLENBQUMsR0FBRyxLQUFLLFFBQVEsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQztZQUFFLE9BQU8sS0FBSyxDQUFDO1FBQ3RILDZFQUE2RTtRQUM3RSxnRkFBZ0Y7UUFDaEYsdUVBQXVFO1FBQ3ZFLE9BQU8sQ0FBQyxvQkFBb0IsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDNUMsQ0FBQztJQUFDLE1BQU0sQ0FBQztRQUNQLE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuaW1wb3J0IHsgcmFuZG9tVVVJRCB9IGZyb20gJ2NyeXB0byc7XG5pbXBvcnQgdHlwZSB7IFJlcXVlc3QsIFJlc3BvbnNlLCBOZXh0RnVuY3Rpb24gfSBmcm9tICdleHByZXNzJztcbmltcG9ydCBqd3QgZnJvbSAnanNvbndlYnRva2VuJztcbmltcG9ydCB7IEh0dHBTdGF0dXMgfSBmcm9tICcuLi9jb25zdGFudHMvaHR0cC1zdGF0dXMuanMnO1xuaW1wb3J0IHR5cGUgeyBKd3RQYXlsb2FkIH0gZnJvbSAnLi4vdHlwZXMvY29tbW9uLmpzJztcbmltcG9ydCB7IEVycm9yQ29kZSB9IGZyb20gJy4uL3R5cGVzL2Vycm9yLWNvZGVzLmpzJztcbmltcG9ydCB0eXBlIHsgSHR0cFJlcXVlc3QgfSBmcm9tICcuLi90eXBlcy9odHRwLmpzJztcbmltcG9ydCB7IHR5cGUgUGVybWlzc2lvbiwgaGFzUGVybWlzc2lvbiB9IGZyb20gJy4uL3R5cGVzL3Blcm1pc3Npb25zLmpzJztcbmltcG9ydCB7IGdldEhlYWRlclN0cmluZyB9IGZyb20gJy4uL3V0aWxzL2hlYWRlcnMuanMnO1xuaW1wb3J0IHsgZ2V0SWRlbnRpdHksIHR5cGUgUmVxdWVzdElkZW50aXR5IH0gZnJvbSAnLi4vdXRpbHMvaWRlbnRpdHkuanMnO1xuaW1wb3J0IHsgY3JlYXRlTG9nZ2VyIH0gZnJvbSAnLi4vdXRpbHMvbG9nZ2VyLmpzJztcbmltcG9ydCB7IGVtaXRDb3VudGVyIH0gZnJvbSAnLi4vdXRpbHMvbWV0cmljLWVtaXR0ZXIuanMnO1xuaW1wb3J0IHsgc2VuZEVycm9yIH0gZnJvbSAnLi4vdXRpbHMvcmVzcG9uc2UuanMnO1xuXG5jb25zdCBsb2dnZXIgPSBjcmVhdGVMb2dnZXIoJ2F1dGgtbWlkZGxld2FyZScpO1xuXG4vKiogQ2FjaGVkIEpXVCBzZWNyZXQgd2l0aCBwZXJpb2RpYyByZWZyZXNoIGZyb20gZW52IHZhci4gKi9cbmxldCBfand0U2VjcmV0OiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5sZXQgX2p3dFNlY3JldFJlZnJlc2hlZEF0ID0gMDtcbi8qKiBDYWNoZWQgUFJFVklPVVMgSldUIHNlY3JldCAob3B0aW9uYWwpIOKAlCBlbmFibGVzIHplcm8tZG93bnRpbWUgcm90YXRpb24uICovXG5sZXQgX2p3dFNlY3JldFByZXZpb3VzOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5sZXQgX2p3dFNlY3JldFByZXZpb3VzUmVmcmVzaGVkQXQgPSAwO1xuY29uc3QgSldUX1NFQ1JFVF9SRUZSRVNIX0lOVEVSVkFMX01TID0gMzAwXzAwMDsgLy8gNSBtaW51dGVzXG5cbmZ1bmN0aW9uIGdldEp3dFNlY3JldCgpOiBzdHJpbmcge1xuICBjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuICBpZiAoIV9qd3RTZWNyZXQgfHwgbm93IC0gX2p3dFNlY3JldFJlZnJlc2hlZEF0ID4gSldUX1NFQ1JFVF9SRUZSRVNIX0lOVEVSVkFMX01TKSB7XG4gICAgY29uc3Qgc2VjcmV0ID0gcHJvY2Vzcy5lbnYuSldUX1NFQ1JFVDtcbiAgICBpZiAoIXNlY3JldCkge1xuICAgICAgbG9nZ2VyLmVycm9yKCdKV1RfU0VDUkVUIGVudmlyb25tZW50IHZhcmlhYmxlIGlzIG5vdCBzZXQnKTtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSldUX1NFQ1JFVCBlbnZpcm9ubWVudCB2YXJpYWJsZSBpcyByZXF1aXJlZCcpO1xuICAgIH1cbiAgICBpZiAoX2p3dFNlY3JldCAmJiBfand0U2VjcmV0ICE9PSBzZWNyZXQpIHtcbiAgICAgIGxvZ2dlci5pbmZvKCdKV1Qgc2VjcmV0IHJvdGF0ZWQnKTtcbiAgICB9XG4gICAgX2p3dFNlY3JldCA9IHNlY3JldDtcbiAgICBfand0U2VjcmV0UmVmcmVzaGVkQXQgPSBub3c7XG4gIH1cbiAgcmV0dXJuIF9qd3RTZWNyZXQ7XG59XG5cbi8qKlxuICogVGhlIG9wdGlvbmFsIFBSRVZJT1VTIEpXVCBzZWNyZXQgKGBKV1RfU0VDUkVUX1BSRVZJT1VTYCksIGNhY2hlZCB3aXRoIHRoZSBzYW1lXG4gKiBUVEwgYXMgdGhlIHByaW1hcnkuIFJldHVybnMgYHVuZGVmaW5lZGAgd2hlbiB1bnNldC4gRHVyaW5nIGEgYEpXVF9TRUNSRVRgXG4gKiByb3RhdGlvbiwgb3BlcmF0b3JzIHNldCBgSldUX1NFQ1JFVF9QUkVWSU9VU2AgdG8gdGhlIG9sZCB2YWx1ZSBzbyB0b2tlbnMgc2lnbmVkXG4gKiB3aXRoIEVJVEhFUiBzZWNyZXQga2VlcCB2ZXJpZnlpbmcg4oCUIGNsb3NpbmcgdGhlIGF1dGgtb3V0YWdlIHdpbmRvdyB3aGVyZVxuICogc3RpbGwtdmFsaWQgb2xkLXNpZ25lZCAob3IgZnJlc2hseSBuZXctc2lnbmVkKSB0b2tlbnMgd291bGQgb3RoZXJ3aXNlIGJlXG4gKiByZWplY3RlZC4gYHVuZGVmaW5lZGAgaXMgYSB2YWxpZCBjYWNoZWQgdmFsdWUsIHNvIHRoaXMgcmVmcmVzaGVzIHB1cmVseSBvbiB0aGVcbiAqIHRpbWUgaW50ZXJ2YWwgKG5vdCBvbiBlbXB0aW5lc3MpLlxuICovXG5mdW5jdGlvbiBnZXRKd3RTZWNyZXRQcmV2aW91cygpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICBjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuICBpZiAobm93IC0gX2p3dFNlY3JldFByZXZpb3VzUmVmcmVzaGVkQXQgPiBKV1RfU0VDUkVUX1JFRlJFU0hfSU5URVJWQUxfTVMpIHtcbiAgICBfand0U2VjcmV0UHJldmlvdXMgPSBwcm9jZXNzLmVudi5KV1RfU0VDUkVUX1BSRVZJT1VTIHx8IHVuZGVmaW5lZDtcbiAgICBfand0U2VjcmV0UHJldmlvdXNSZWZyZXNoZWRBdCA9IG5vdztcbiAgfVxuICByZXR1cm4gX2p3dFNlY3JldFByZXZpb3VzO1xufVxuXG4vKipcbiAqIFZlcmlmeSBhIEpXVCBhZ2FpbnN0IHRoZSBwcmltYXJ5IHNlY3JldCwgZmFsbGluZyBiYWNrIHRvIHRoZSBwcmV2aW91cyBzZWNyZXRcbiAqICh3aGVuIGBKV1RfU0VDUkVUX1BSRVZJT1VTYCBpcyBjb25maWd1cmVkKSBPTkxZIG9uIGEgc2lnbmF0dXJlL3ZlcmlmaWNhdGlvblxuICogZmFpbHVyZS4gVGhpcyBtYWtlcyB0b2tlbiB2ZXJpZmljYXRpb24gc3Vydml2ZSBhIHNlY3JldCByb3RhdGlvbiB3aXRoIHplcm9cbiAqIGRvd250aW1lOiBhIHRva2VuIHZhbGlkIHVuZGVyIEVJVEhFUiBzZWNyZXQgcGFzc2VzLlxuICpcbiAqIGpzb253ZWJ0b2tlbidzIGB2ZXJpZnlgIHRha2VzIGEgc2luZ2xlIHNlY3JldCwgc28gdGhpcyBpcyB0cnktcHJpbWFyeS10aGVuLVxuICogcHJldmlvdXMg4oCUIE5PVCBhIHNlY3JldCBhcnJheS4gTm8gZXhpc3RpbmcgY2hlY2sgaXMgd2Vha2VuZWQ6XG4gKiAgIC0gYHZlcmlmeU9wdGlvbnNgIChhbGdvcml0aG0gcGlubmluZyArIG9wdGlvbmFsIGlzc3Vlci9hdWRpZW5jZSkgaXMgYXBwbGllZFxuICogICAgIGlkZW50aWNhbGx5IG9uIEJPVEggYXR0ZW1wdHMsIHNvIGFsZy1jb25mdXNpb24gLyBgYWxnOm5vbmVgIHN0YXkgYmxvY2tlZC5cbiAqICAgLSBFeHBpcnkgLyBub3QtYmVmb3JlIGZyb20gdGhlIFBSSU1BUlkgYXR0ZW1wdCBhcmUgYXV0aG9yaXRhdGl2ZSBhbmQgYXJlXG4gKiAgICAgcmUtdGhyb3duIHdpdGhvdXQgYSBwcmV2aW91cy1zZWNyZXQgcmV0cnksIHNvIGEgYFRva2VuRXhwaXJlZEVycm9yYCBpc1xuICogICAgIG5ldmVyIG1hc2tlZCBpbnRvIGFuIFwiaW52YWxpZCBzaWduYXR1cmVcIi5cbiAqICAgLSBXaGVuIG5vIHByZXZpb3VzIHNlY3JldCBpcyBzZXQsIGJlaGF2aW91ciBpcyBieXRlLWZvci1ieXRlIHRoZSBvcmlnaW5hbDpcbiAqICAgICB0aGUgcHJpbWFyeSBlcnJvciBwcm9wYWdhdGVzIHVuY2hhbmdlZC5cbiAqL1xuZnVuY3Rpb24gdmVyaWZ5Snd0V2l0aFJvdGF0aW9uKHRva2VuOiBzdHJpbmcsIHZlcmlmeU9wdGlvbnM6IGp3dC5WZXJpZnlPcHRpb25zKTogSnd0UGF5bG9hZCB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIGp3dC52ZXJpZnkodG9rZW4sIGdldEp3dFNlY3JldCgpLCB2ZXJpZnlPcHRpb25zKSBhcyBKd3RQYXlsb2FkO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICBjb25zdCBwcmV2aW91cyA9IGdldEp3dFNlY3JldFByZXZpb3VzKCk7XG4gICAgLy8gRmFsbCBiYWNrIHRvIHRoZSBwcmV2aW91cyBzZWNyZXQgb25seSBmb3IgYSBzaWduYXR1cmUvdmVyaWZpY2F0aW9uIGZhaWx1cmVcbiAgICAvLyAoYSBwbGFpbiBKc29uV2ViVG9rZW5FcnJvcikuIEV4cGlyeSAvIG5vdC1iZWZvcmUgYXJlIGVuZm9yY2VkIHJlZ2FyZGxlc3Mgb2ZcbiAgICAvLyB3aGljaCBzZWNyZXQgc2lnbmVkIHRoZSB0b2tlbiwgc28gdGhvc2UgZXJyb3JzIG11c3Qgc3VyZmFjZSBhcy1pcy5cbiAgICBpZiAoXG4gICAgICBwcmV2aW91c1xuICAgICAgJiYgZXJyIGluc3RhbmNlb2Ygand0Lkpzb25XZWJUb2tlbkVycm9yXG4gICAgICAmJiAhKGVyciBpbnN0YW5jZW9mIGp3dC5Ub2tlbkV4cGlyZWRFcnJvcilcbiAgICAgICYmICEoZXJyIGluc3RhbmNlb2Ygand0Lk5vdEJlZm9yZUVycm9yKVxuICAgICkge1xuICAgICAgLy8gQSB0b2tlbiBzaWduZWQgYnkgdGhlIHByZXZpb3VzIHNlY3JldCB2ZXJpZmllcyBoZXJlOyBpZiBpdCBpcyBpbnN0ZWFkXG4gICAgICAvLyBleHBpcmVkL2ludmFsaWQgdW5kZXIgdGhlIHByZXZpb3VzIHNlY3JldCwgdGhhdCBlcnJvciBwcm9wYWdhdGVzIGFuZCBpc1xuICAgICAgLy8gaGFuZGxlZCBieSB0aGUgY2FsbGVyIGV4YWN0bHkgbGlrZSBhIHByaW1hcnkgZmFpbHVyZS5cbiAgICAgIHJldHVybiBqd3QudmVyaWZ5KHRva2VuLCBwcmV2aW91cywgdmVyaWZ5T3B0aW9ucykgYXMgSnd0UGF5bG9hZDtcbiAgICB9XG4gICAgdGhyb3cgZXJyO1xuICB9XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVxdWlyZUF1dGhPcHRpb25zIHtcbiAgLyoqXG4gICAqIEFsbG93IHgtb3JnLWlkL3gtb3JnLW5hbWUgaGVhZGVycyB0byBvdmVycmlkZSB0aGUgSldUJ3Mgb3JnYW5pemF0aW9uIGZpZWxkcy5cbiAgICpcbiAgICogV2hlbiBlbmFibGVkLCB0aGUgYHgtb3JnLWlkYC9geC1vcmctbmFtZWAgaGVhZGVycyBvdmVycmlkZSB0aGUgY2FsbGVyJ3Mgb3JnXG4gICAqIOKAlCBidXQgT05MWSBmb3IgYSB2ZXJpZmllZCBTWVMtQURNSU4gKGBpc1N1cGVyQWRtaW5gIGNsYWltKS4gRm9yIGFueSBvcmRpbmFyeVxuICAgKiBhdXRoZW50aWNhdGVkIHVzZXIgdGhlIGhlYWRlcnMgYXJlIGlnbm9yZWQsIHNvIGVuYWJsaW5nIHRoaXMgY2FuIG5ldmVyIGxldCBhXG4gICAqIG5vcm1hbCB1c2VyIGltcGVyc29uYXRlIGFub3RoZXIgdGVuYW50J3Mgb3JnLiBVc2UgZm9yIGNyb3NzLW9yZyBhZG1pbiB0b29saW5nXG4gICAqIChlLmcuIGEgc3lzYWRtaW4gbWFuYWdpbmcgYSBnaXZlbiBvcmcncyBiaWxsaW5nKS4gSWYgdW5zdXJlLCBsZWF2ZSBpdCBkaXNhYmxlZC5cbiAgICovXG4gIGFsbG93T3JnSGVhZGVyT3ZlcnJpZGU/OiBib29sZWFuO1xufVxuXG4vKiogSldUIGF1dGggbWlkZGxld2FyZS4gVXNlIGRpcmVjdGx5IG9yIGNhbGwgd2l0aCBvcHRpb25zLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlcXVpcmVBdXRoKFxuICByZXE6IFJlcXVlc3QsXG4gIHJlczogUmVzcG9uc2UsXG4gIG5leHQ6IE5leHRGdW5jdGlvbixcbik6IHZvaWQ7XG5leHBvcnQgZnVuY3Rpb24gcmVxdWlyZUF1dGgoXG4gIG9wdGlvbnM/OiBSZXF1aXJlQXV0aE9wdGlvbnMsXG4pOiAocmVxOiBSZXF1ZXN0LCByZXM6IFJlc3BvbnNlLCBuZXh0OiBOZXh0RnVuY3Rpb24pID0+IHZvaWQ7XG5leHBvcnQgZnVuY3Rpb24gcmVxdWlyZUF1dGgoXG4gIHJlcU9yT3B0aW9ucz86IFJlcXVlc3QgfCBSZXF1aXJlQXV0aE9wdGlvbnMsXG4gIHJlcz86IFJlc3BvbnNlLFxuICBuZXh0PzogTmV4dEZ1bmN0aW9uLFxuKTogdm9pZCB8ICgocmVxOiBSZXF1ZXN0LCByZXM6IFJlc3BvbnNlLCBuZXh0OiBOZXh0RnVuY3Rpb24pID0+IHZvaWQpIHtcbiAgaWYgKHJlcU9yT3B0aW9ucyAmJiByZXMgJiYgbmV4dCAmJiAnaGVhZGVycycgaW4gcmVxT3JPcHRpb25zKSB7XG4gICAgcmV0dXJuIF9yZXF1aXJlQXV0aCh7fSwgcmVxT3JPcHRpb25zIGFzIFJlcXVlc3QsIHJlcywgbmV4dCk7XG4gIH1cblxuICBjb25zdCBvcHRpb25zID0gKHJlcU9yT3B0aW9ucyBhcyBSZXF1aXJlQXV0aE9wdGlvbnMpIHx8IHt9O1xuICByZXR1cm4gKHJlcTogUmVxdWVzdCwgcmVzSW5uZXI6IFJlc3BvbnNlLCBuZXh0SW5uZXI6IE5leHRGdW5jdGlvbikgPT4ge1xuICAgIF9yZXF1aXJlQXV0aChvcHRpb25zLCByZXEsIHJlc0lubmVyLCBuZXh0SW5uZXIpO1xuICB9O1xufVxuXG4vKipcbiAqIEEgc291cmNlIG9mIHRoZSBDVVJSRU5UIGB0b2tlblZlcnNpb25gIGZvciBhIHVzZXIsIGJhY2tlZCBieSBhIHN0b3JlIHRoZVxuICogc3RhdGVsZXNzIHNlcnZpY2VzIGNhbiByZWFkIChpbiBwcmFjdGljZSBhIFJlZGlzIGtleSB0aGUgcGxhdGZvcm0gcHVibGlzaGVzXG4gKiB0byBvbiBldmVyeSBwcml2aWxlZ2UgY2hhbmdlKS4gUmVnaXN0ZXJlZCB2aWEge0BsaW5rIHNldFRva2VuUmV2b2NhdGlvblN0b3JlfS5cbiAqXG4gKiBgZ2V0Q3VycmVudFZlcnNpb25gIHJldHVybnMgdGhlIHVzZXIncyBjdXJyZW50IHZlcnNpb24sIG9yIGBudWxsYCB3aGVuIHRoZVxuICogc3RvcmUgaGFzIG5vIGVudHJ5IOKAlCBhIG1pc3MgaXMgdHJlYXRlZCBhcyBcIm5vIGtub3duIHJldm9jYXRpb25cIiAoZmFpbC1vcGVuKTpcbiAqIHJldm9jYXRpb24gZW50cmllcyBhcmUgcHVibGlzaGVkIHdpdGggYSBUVEwgbWF0Y2hpbmcgdGhlIGFjY2Vzcy10b2tlblxuICogbGlmZXRpbWUsIHNvIGEgbWlzc2luZyBlbnRyeSBtZWFucyBhbnkgdG9rZW4gb2xkIGVub3VnaCB0byBwcmVkYXRlIGl0IGhhc1xuICogYWxyZWFkeSBleHBpcmVkIG9uIGl0cyBvd24uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVG9rZW5SZXZvY2F0aW9uU3RvcmUge1xuICBnZXRDdXJyZW50VmVyc2lvbih1c2VySWQ6IHN0cmluZyk6IFByb21pc2U8bnVtYmVyIHwgbnVsbD47XG59XG5cbmxldCB0b2tlblJldm9jYXRpb25TdG9yZTogVG9rZW5SZXZvY2F0aW9uU3RvcmUgfCB1bmRlZmluZWQ7XG5cbi8qKlxuICogUmVnaXN0ZXIgKG9yIGNsZWFyLCB3aXRoIGB1bmRlZmluZWRgKSB0aGUgcHJvY2Vzcy13aWRlIHRva2VuLXJldm9jYXRpb24gc3RvcmUuXG4gKiBXaGVuIHVuc2V0ICh0aGUgZGVmYXVsdCksIGByZXF1aXJlQXV0aGAgcGVyZm9ybXMgTk8gcmV2b2NhdGlvbiBjaGVjayAoaXQgcmVsaWVzXG4gKiBvbiB0aGUgc2hvcnQgYWNjZXNzLXRva2VuIFRUTCk7IHNlcnZpY2VzIG9wdCBpbiBhdCBib290IGJ5IHdpcmluZyB0aGVpciBSZWRpc1xuICogY2xpZW50LiBQbGF0Zm9ybSBrZWVwcyBpdHMgb3duIE1vbmdvLWJhY2tlZCBjaGVjayBhbmQgbmVlZCBub3QgcmVnaXN0ZXIgb25lLlxuICovXG5leHBvcnQgZnVuY3Rpb24gc2V0VG9rZW5SZXZvY2F0aW9uU3RvcmUoc3RvcmU6IFRva2VuUmV2b2NhdGlvblN0b3JlIHwgdW5kZWZpbmVkKTogdm9pZCB7XG4gIHRva2VuUmV2b2NhdGlvblN0b3JlID0gc3RvcmU7XG4gIGlmIChzdG9yZSkgcmV2b2NhdGlvblN0b3JlTWlzc2luZ1dhcm5lZCA9IGZhbHNlOyAvLyByZS1hcm0gaWYgYSBzdG9yZSBpcyAocmUpcmVnaXN0ZXJlZFxufVxuXG4vKiogT25lLXNob3QgZ3VhcmQgc28gdGhlIFwicmV2b2NhdGlvbiBpbmFjdGl2ZVwiIHdhcm5pbmcgZG9lc24ndCBmbG9vZCB0aGUgbG9ncy4gKi9cbmxldCByZXZvY2F0aW9uU3RvcmVNaXNzaW5nV2FybmVkID0gZmFsc2U7XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIHdoZW4gYGRlY29kZWRgIGhhcyBiZWVuIHJldm9rZWQgcGVyIHRoZSByZWdpc3RlcmVkIHN0b3JlOiBpdHNcbiAqIGVtYmVkZGVkIGB0b2tlblZlcnNpb25gIGlzIHN0cmljdGx5IGJlaGluZCB0aGUgc3RvcmUncyBjdXJyZW50IHZlcnNpb24uXG4gKiBGYWlsLW9wZW4g4oCUIGFueSBzdG9yZSBlcnJvciwgYSBtaXNzaW5nIGVudHJ5LCBvciBhIHRva2VuL3N0b3JlIHdpdGhvdXQgYVxuICogdXNhYmxlIHZlcnNpb24geWllbGRzIGBmYWxzZWAgKGFsbG93KS4gTmV2ZXIgdGhyb3dzLlxuICovXG5hc3luYyBmdW5jdGlvbiBpc1Rva2VuUmV2b2tlZChkZWNvZGVkOiBKd3RQYXlsb2FkKTogUHJvbWlzZTxib29sZWFuPiB7XG4gIGNvbnN0IHN0b3JlID0gdG9rZW5SZXZvY2F0aW9uU3RvcmU7XG4gIGlmICghc3RvcmUpIHtcbiAgICAvLyBNYWtlIHRoZSBcInJldm9jYXRpb24gaXMgT0ZGXCIgc3RhdGUgT0JTRVJWQUJMRTogYSBzZXJ2aWNlIHRoYXQgdmVyaWZpZXMgdXNlclxuICAgIC8vIHRva2VucyBidXQgZm9yZ290IGBzZXRUb2tlblJldm9jYXRpb25TdG9yZSgpYCBzaWxlbnRseSBkaXNhYmxlcyB0aGUgc2Vzc2lvblxuICAgIC8vIGtpbGwtc3dpdGNoLiBXYXJuIE9OQ0UgKG9ubHkgZm9yIGEgcmV2b2NhYmxlIHVzZXIgdG9rZW4pIHNvIGEgbWlzY29uZmlndXJlZFxuICAgIC8vIGJvb3Qgc3VyZmFjZXMgaW4gdGhlIGxvZ3MgaW5zdGVhZCBvZiBmYWlsaW5nIG9wZW4gaW52aXNpYmx5LlxuICAgIGlmICghcmV2b2NhdGlvblN0b3JlTWlzc2luZ1dhcm5lZCAmJiBkZWNvZGVkLnN1YiAmJiB0eXBlb2YgZGVjb2RlZC50b2tlblZlcnNpb24gPT09ICdudW1iZXInKSB7XG4gICAgICByZXZvY2F0aW9uU3RvcmVNaXNzaW5nV2FybmVkID0gdHJ1ZTtcbiAgICAgIGxvZ2dlci53YXJuKCdUb2tlbiByZXZvY2F0aW9uIHN0b3JlIE5PVCByZWdpc3RlcmVkIOKAlCByZXZvY2F0aW9uIGNoZWNrcyBhcmUgSU5BQ1RJVkUgKHNldFRva2VuUmV2b2NhdGlvblN0b3JlIHdhcyBuZXZlciBjYWxsZWQpOyByZXZva2VkL2NvbXByb21pc2VkIHNlc3Npb25zIHN0YXkgdmFsaWQgdW50aWwgbmF0dXJhbCBUVEwnKTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlmICghZGVjb2RlZC5zdWIgfHwgdHlwZW9mIGRlY29kZWQudG9rZW5WZXJzaW9uICE9PSAnbnVtYmVyJykgcmV0dXJuIGZhbHNlO1xuICB0cnkge1xuICAgIGNvbnN0IGN1cnJlbnQgPSBhd2FpdCBzdG9yZS5nZXRDdXJyZW50VmVyc2lvbihkZWNvZGVkLnN1Yik7XG4gICAgcmV0dXJuIGN1cnJlbnQgIT09IG51bGwgJiYgZGVjb2RlZC50b2tlblZlcnNpb24gPCBjdXJyZW50O1xuICB9IGNhdGNoIHtcbiAgICAvLyBGYWlsLW9wZW46IGEgcmV2b2NhdGlvbi1zdG9yZSBvdXRhZ2UgbXVzdCBub3QgbG9jayBldmVyeSB1c2VyIG91dC5cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cblxuLyoqXG4gKiBQdWJsaWMgcmV2b2NhdGlvbiBjaGVjayBmb3Igcm91dGVzIHRoYXQgdmVyaWZ5IGEgcGxhdGZvcm0gSldUIE9VVFNJREVcbiAqIGByZXF1aXJlQXV0aGAgKGUuZy4gdGhlIGltYWdlLXJlZ2lzdHJ5IGAvdG9rZW5gIG1pbnQgcGF0aCwgd2hpY2ggcmVzb2x2ZXNcbiAqIGlkZW50aXR5IGl0c2VsZikuIFJldHVybnMgdHJ1ZSB3aGVuIHRoZSB0b2tlbidzIGB0b2tlblZlcnNpb25gIGlzIHN0cmljdGx5XG4gKiBiZWhpbmQgdGhlIHN0b3JlJ3MgY3VycmVudCB2ZXJzaW9uLiBGYWlsLW9wZW4gKG5ldmVyIHRocm93cykg4oCUIGEgc3RvcmUgb3V0YWdlXG4gKiBvciBhIHRva2VuL3N0b3JlIHdpdGhvdXQgYSB1c2FibGUgdmVyc2lvbiB5aWVsZHMgZmFsc2UgKGFsbG93KSwgbWF0Y2hpbmdcbiAqIGByZXF1aXJlQXV0aGAuIFBhc3MgdGhlIHZlcmlmaWVkIEpXVCBjbGFpbXMgKGBzdWJgLCBgdG9rZW5WZXJzaW9uYCkuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBpc0FjY2Vzc1Rva2VuUmV2b2tlZChjbGFpbXM6IHsgc3ViPzogc3RyaW5nOyB0b2tlblZlcnNpb24/OiBudW1iZXIgfSk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICByZXR1cm4gaXNUb2tlblJldm9rZWQoY2xhaW1zIGFzIEp3dFBheWxvYWQpO1xufVxuXG5mdW5jdGlvbiBfcmVxdWlyZUF1dGgoXG4gIG9wdGlvbnM6IFJlcXVpcmVBdXRoT3B0aW9ucyxcbiAgcmVxOiBSZXF1ZXN0LFxuICByZXM6IFJlc3BvbnNlLFxuICBuZXh0OiBOZXh0RnVuY3Rpb24sXG4pOiB2b2lkIHtcbiAgY29uc3QgYXV0aEhlYWRlciA9IHJlcS5oZWFkZXJzLmF1dGhvcml6YXRpb247XG5cbiAgaWYgKCFhdXRoSGVhZGVyKSB7XG4gICAgcmV0dXJuIHNlbmRFcnJvcihyZXMsIEh0dHBTdGF0dXMuVU5BVVRIT1JJWkVELCAnQXV0aG9yaXphdGlvbiBoZWFkZXIgcmVxdWlyZWQnLCBFcnJvckNvZGUuVE9LRU5fTUlTU0lORyk7XG4gIH1cblxuICBjb25zdCBwYXJ0cyA9IGF1dGhIZWFkZXIuc3BsaXQoJyAnKTtcbiAgaWYgKHBhcnRzLmxlbmd0aCAhPT0gMiB8fCBwYXJ0c1swXSAhPT0gJ0JlYXJlcicpIHtcbiAgICByZXR1cm4gc2VuZEVycm9yKHJlcywgSHR0cFN0YXR1cy5VTkFVVEhPUklaRUQsICdJbnZhbGlkIGF1dGhvcml6YXRpb24gZm9ybWF0LiBVc2U6IEJlYXJlciA8dG9rZW4+JywgRXJyb3JDb2RlLlRPS0VOX0lOVkFMSUQpO1xuICB9XG5cbiAgdHJ5IHtcbiAgICAvLyBQYXNzIHRocm91Z2ggb3B0aW9uYWwgaXNzdWVyL2F1ZGllbmNlIHZlcmlmaWNhdGlvbiB3aGVuIGVudi1jb25maWd1cmVkLlxuICAgIC8vIFdpdGhvdXQgdGhlc2UsIGEgSldUIHNpZ25lZCBieSBhbnkgc3lzdGVtIHRoYXQgaGFwcGVucyB0byBzaGFyZSB0aGVcbiAgICAvLyBzYW1lIEpXVF9TRUNSRVQgd291bGQgYmUgYWNjZXB0ZWQg4oCUIGRlZmVuY2UtaW4tZGVwdGggZm9yIHNoYXJlZC1zZWNyZXRcbiAgICAvLyBtaXNjb25maWd1cmF0aW9ucyBhY3Jvc3Mgc2VydmljZXMgLyBlbnZpcm9ubWVudHMuXG4gICAgLy8gUGluIHRoZSBhY2NlcHRlZCBhbGdvcml0aG0gdG8gdGhlIGNvbmZpZ3VyZWQgSE1BQyBhbGcgKGRlZmF1bHQgSFMyNTYpLlxuICAgIC8vIFdpdGhvdXQgYW4gYWxsb3ctbGlzdCwgYGp3dC52ZXJpZnlgIGFjY2VwdHMgYW55IGFsZ29yaXRobSB0aGUga2V5IGNhblxuICAgIC8vIHZlcmlmeSDigJQgdGhlIGNsYXNzaWMgYWxnLWNvbmZ1c2lvbiB2ZWN0b3IgKGFuZCBhIGhhcmQgZ3VhcmQgYWdhaW5zdFxuICAgIC8vIGBhbGc6bm9uZWApLiBFbnYtZHJpdmVuIHNvIGl0IHN0YXlzIGluIGxvY2tzdGVwIHdpdGggaG93IHRva2VucyBhcmVcbiAgICAvLyBzaWduZWQgKHNlZSBzaWduU2VydmljZVRva2VuICsgcGxhdGZvcm0ncyBjb25maWcuYXV0aC5qd3QuYWxnb3JpdGhtKS5cbiAgICBjb25zdCB2ZXJpZnlPcHRpb25zOiBqd3QuVmVyaWZ5T3B0aW9ucyA9IHsgYWxnb3JpdGhtczogWyhwcm9jZXNzLmVudi5KV1RfQUxHT1JJVEhNIHx8ICdIUzI1NicpIGFzIGp3dC5BbGdvcml0aG1dIH07XG4gICAgY29uc3QgZXhwZWN0ZWRJc3N1ZXIgPSBwcm9jZXNzLmVudi5KV1RfSVNTVUVSO1xuICAgIGNvbnN0IGV4cGVjdGVkQXVkaWVuY2UgPSBwcm9jZXNzLmVudi5KV1RfQVVESUVOQ0U7XG4gICAgaWYgKGV4cGVjdGVkSXNzdWVyKSB2ZXJpZnlPcHRpb25zLmlzc3VlciA9IGV4cGVjdGVkSXNzdWVyO1xuICAgIGlmIChleHBlY3RlZEF1ZGllbmNlKSB2ZXJpZnlPcHRpb25zLmF1ZGllbmNlID0gZXhwZWN0ZWRBdWRpZW5jZTtcbiAgICBjb25zdCBkZWNvZGVkID0gdmVyaWZ5Snd0V2l0aFJvdGF0aW9uKHBhcnRzWzFdLCB2ZXJpZnlPcHRpb25zKTtcblxuICAgIGlmIChkZWNvZGVkLnR5cGUgIT09ICdhY2Nlc3MnKSB7XG4gICAgICByZXR1cm4gc2VuZEVycm9yKHJlcywgSHR0cFN0YXR1cy5VTkFVVEhPUklaRUQsICdPbmx5IGFjY2VzcyB0b2tlbnMgY2FuIGJlIHVzZWQgZm9yIEFQSSByZXF1ZXN0cycsIEVycm9yQ29kZS5UT0tFTl9JTlZBTElEKTtcbiAgICB9XG5cbiAgICBpZiAoIWRlY29kZWQuc3ViIHx8ICFkZWNvZGVkLnJvbGUpIHtcbiAgICAgIHJldHVybiBzZW5kRXJyb3IocmVzLCBIdHRwU3RhdHVzLlVOQVVUSE9SSVpFRCwgJ1Rva2VuIG1pc3NpbmcgcmVxdWlyZWQgZmllbGRzJywgRXJyb3JDb2RlLlRPS0VOX0lOVkFMSUQpO1xuICAgIH1cblxuICAgIC8vIFNlcnZpY2UtdG9rZW4ga2lsbC1zd2l0Y2g6IHJlamVjdCBhIHNlcnZpY2UgcHJpbmNpcGFsIHdob3NlIHNlcnZpY2UgaGFzXG4gICAgLy8gYmVlbiBhZGRlZCB0byB0aGUgZGVueWxpc3QuIFJvdGF0aW5nIHRoZSBzaGFyZWQgSldUIHNlY3JldCBpcyB0aGUgb25seVxuICAgIC8vIG90aGVyIHdheSB0byBpbnZhbGlkYXRlIGEgc2VydmljZSB0b2tlbiBiZWZvcmUgaXRzIChzaG9ydCkgVFRMIOKAlCBidXQgdGhhdFxuICAgIC8vIG51a2VzIEVWRVJZIHNlcnZpY2UgdG9rZW4gZmxlZXQtd2lkZS4gVGhpcyBsZXRzIG9uZSBjb21wcm9taXNlZC9yb2d1ZVxuICAgIC8vIHNlcnZpY2UgYmUgY3V0IG9mZiBzdXJnaWNhbGx5LiBPKDEpIFNldCBsb29rdXAsIHplcm8gY29zdCB3aGVuIHRoZSBkZW55bGlzdFxuICAgIC8vIGlzIGVtcHR5ICh0aGUgZGVmYXVsdCksIHNvIGl0IG5ldmVyIHRheGVzIHRoZSBTMlMgaG90IHBhdGggdW5sZXNzIGFybWVkLlxuICAgIGlmIChkZWNvZGVkLnN1Yi5zdGFydHNXaXRoKCdzZXJ2aWNlOicpICYmIGlzU2VydmljZVRva2VuRGVuaWVkKGRlY29kZWQuc3ViKSkge1xuICAgICAgZW1pdENvdW50ZXIoJ3NlcnZpY2VfdG9rZW5fZGVuaWVkX3RvdGFsJywgeyBzZXJ2aWNlOiBkZWNvZGVkLnN1Yi5zbGljZSgnc2VydmljZTonLmxlbmd0aCkgfSk7XG4gICAgICBsb2dnZXIud2FybignUmVqZWN0ZWQgZGVueWxpc3RlZCBzZXJ2aWNlIHRva2VuJywgeyBzdWI6IGRlY29kZWQuc3ViIH0pO1xuICAgICAgcmV0dXJuIHNlbmRFcnJvcihyZXMsIEh0dHBTdGF0dXMuVU5BVVRIT1JJWkVELCAnU2VydmljZSB0b2tlbiByZXZva2VkJywgRXJyb3JDb2RlLlRPS0VOX1JFVk9LRUQpO1xuICAgIH1cblxuICAgIHJlcS51c2VyID0geyAuLi5kZWNvZGVkIH07XG5cbiAgICAvLyBUaGUgeC1vcmctaWQveC1vcmctbmFtZSBvdmVycmlkZSBsZXRzIGEgU1lTLUFETUlOIGFjdCBvbiBhIGNob3NlbiBvcmdcbiAgICAvLyAoY3Jvc3Mtb3JnIGFkbWluIHRvb2xpbmcpLiBJdCBpcyBnYXRlZCBvbiB0aGUgdmVyaWZpZWQgYGlzU3VwZXJBZG1pbmAgY2xhaW1cbiAgICAvLyBoZXJlIHNvIHRoYXQgZXZlbiBhIHJvdXRlIHdoaWNoIG1pc3Rha2VubHkgZW5hYmxlcyBgYWxsb3dPcmdIZWFkZXJPdmVycmlkZWBcbiAgICAvLyBjYW4gTkVWRVIgbGV0IGFuIG9yZGluYXJ5IGF1dGhlbnRpY2F0ZWQgdXNlciBzcG9vZiBhbm90aGVyIHRlbmFudCdzIG9yZyB2aWFcbiAgICAvLyB0aGUgaGVhZGVyIOKAlCBkZWZlbmNlLWluLWRlcHRoIGFnYWluc3QgdGhlIGNyb3NzLXRlbmFudCBicmVhayB0aGlzIGNhdXNlZC5cbiAgICBpZiAob3B0aW9ucy5hbGxvd09yZ0hlYWRlck92ZXJyaWRlICYmIGRlY29kZWQuaXNTdXBlckFkbWluID09PSB0cnVlKSB7XG4gICAgICBjb25zdCBoZWFkZXJPcmdJZCA9IGdldEhlYWRlclN0cmluZyhyZXEuaGVhZGVyc1sneC1vcmctaWQnXSk7XG4gICAgICBjb25zdCBoZWFkZXJPcmdOYW1lID0gZ2V0SGVhZGVyU3RyaW5nKHJlcS5oZWFkZXJzWyd4LW9yZy1uYW1lJ10pO1xuICAgICAgaWYgKGhlYWRlck9yZ0lkKSByZXEudXNlci5vcmdhbml6YXRpb25JZCA9IGhlYWRlck9yZ0lkO1xuICAgICAgaWYgKGhlYWRlck9yZ05hbWUpIHJlcS51c2VyLm9yZ2FuaXphdGlvbk5hbWUgPSBoZWFkZXJPcmdOYW1lO1xuICAgIH1cblxuICAgIC8vIFJlLWRlcml2ZSB0aGUgcmVxdWVzdCdzIHRlbmFudCBpZGVudGl0eSBmcm9tIHRoZSBOT1ctdmVyaWZpZWQgSldULlxuICAgIC8vXG4gICAgLy8gYGF0dGFjaFJlcXVlc3RDb250ZXh0YCBydW5zIGFzIGEgZ2xvYmFsIG1pZGRsZXdhcmUgQkVGT1JFIHRoaXMgcGVyLXJvdXRlXG4gICAgLy8gYHJlcXVpcmVBdXRoYCwgc28gaXQgY2FwdHVyZWQgYHJlcS5jb250ZXh0LmlkZW50aXR5YCB3aGlsZSBgcmVxLnVzZXJgIHdhc1xuICAgIC8vIHN0aWxsIHVuZGVmaW5lZCDigJQgYXQgd2hpY2ggcG9pbnQgYGdldElkZW50aXR5YCBmYWxscyBiYWNrIHRvIHRoZSByYXcsXG4gICAgLy8gY2xpZW50LXNldHRhYmxlIGB4LW9yZy1pZGAvYHgtdXNlci1pZGAgaGVhZGVycy4gRXZlcnkgZG93bnN0cmVhbSB0ZW5hbnQtXG4gICAgLy8gYXV0aG9yaXR5IGNvbnN1bWVyIChyZXF1aXJlT3JnSWQsIHdpdGhUZW5hbnRDb250ZXh0J3MgUkxTIHNjb3BlLCBjaGVja1F1b3RhLFxuICAgIC8vIHdpdGhSb3V0ZSwgYW5kIHRoZSBpZGVtcG90ZW5jeSBuYW1lc3BhY2UpIHJlYWRzIGByZXEuY29udGV4dC5pZGVudGl0eWAsIHNvXG4gICAgLy8gdGhhdCBmcm96ZW4gaGVhZGVyLWRlcml2ZWQgdmFsdWUg4oCUIG5vdCB0aGUgSldUIOKAlCB3YXMgZ292ZXJuaW5nIHRlbmFuY3kgb25cbiAgICAvLyBhbnkgbm9uLW5naW54IHBhdGguIFJlY29tcHV0aW5nIGhlcmUsIGF0IHRoZSBzaW5nbGUgcG9zdC12ZXJpZmljYXRpb24gY2hva2VcbiAgICAvLyBwb2ludCwgbWFrZXMgYGdldElkZW50aXR5YCBwcmVmZXIgdGhlIHZlcmlmaWVkIGByZXEudXNlcmAgKHNlZSBpZGVudGl0eS50cylcbiAgICAvLyBzbyB0ZW5hbmN5IGlzIEpXVC1hdXRob3JpdGF0aXZlLiBUaGUgbmdpbnggYHgtb3JnLWlkYCBvdmVyd3JpdGUgc3RheXMgYXNcbiAgICAvLyBkZWZlbmNlLWluLWRlcHRoLiBHdWFyZGVkIG9uIGByZXEuY29udGV4dGAgc28gc2VydmljZXMvcGF0aHMgdGhhdCBuZXZlclxuICAgIC8vIGF0dGFjaCBhIGNvbnRleHQgKG9yIHJ1biByZXF1aXJlQXV0aCBwcmUtY29udGV4dCkgYXJlIHVuYWZmZWN0ZWQuXG4gICAgY29uc3QgcmVxQ3R4ID0gKHJlcSBhcyBSZXF1ZXN0ICYgeyBjb250ZXh0PzogeyBpZGVudGl0eTogUmVxdWVzdElkZW50aXR5IH0gfSkuY29udGV4dDtcbiAgICBpZiAocmVxQ3R4KSB7XG4gICAgICByZXFDdHguaWRlbnRpdHkgPSBnZXRJZGVudGl0eShyZXEgYXMgdW5rbm93biBhcyBIdHRwUmVxdWVzdCk7XG4gICAgfVxuXG4gICAgLy8gU2Vzc2lvbi1pbnZhbGlkYXRpb24gY2hlY2sgZm9yIHRoZSBzdGF0ZWxlc3Mgc2VydmljZXM6IHJlamVjdCBhIHRva2VuXG4gICAgLy8gd2hvc2UgYHRva2VuVmVyc2lvbmAgaXMgYmVoaW5kIHRoZSByZXZvY2F0aW9uIHN0b3JlJ3MgY3VycmVudCB2YWx1ZSAoYVxuICAgIC8vIHByaXZpbGVnZSBjaGFuZ2UgdGhlIHBsYXRmb3JtIHB1Ymxpc2hlZCkuIE5vIHN0b3JlIHJlZ2lzdGVyZWQg4oeSIHRoaXMgaXMgYVxuICAgIC8vIG5vLW9wIGFuZCBjb250cm9sIHBhc3NlcyBzdHJhaWdodCB0aHJvdWdoLiBGYWlsLW9wZW4gb24gYW55IHN0b3JlIGVycm9yLlxuICAgIGlmICh0b2tlblJldm9jYXRpb25TdG9yZSAmJiBkZWNvZGVkLnN1YiAmJiB0eXBlb2YgZGVjb2RlZC50b2tlblZlcnNpb24gPT09ICdudW1iZXInKSB7XG4gICAgICAvLyBgLmNhdGNoKG5leHQpYCBmb3J3YXJkcyBhIERPV05TVFJFQU0gc3luY2hyb25vdXMgdGhyb3cgZnJvbSBgbmV4dCgpYCB0b1xuICAgICAgLy8gRXhwcmVzcydzIGVycm9yIG1pZGRsZXdhcmUg4oCUIHdpdGhvdXQgaXQsIHRoYXQgdGhyb3cgd291bGQgc3VyZmFjZSBhcyBhblxuICAgICAgLy8gdW5oYW5kbGVkIHJlamVjdGlvbiAodGhpcyBgbmV4dCgpYCBydW5zIGluIGEgbWljcm90YXNrLCBvdXRzaWRlIHRoZVxuICAgICAgLy8gc3Vycm91bmRpbmcgdHJ5L2NhdGNoIGFuZCBFeHByZXNzJ3MgcGVyLWxheWVyIGRpc3BhdGNoKS4gYGlzVG9rZW5SZXZva2VkYFxuICAgICAgLy8gaXRzZWxmIG5ldmVyIHJlamVjdHMgKGl0IGZhaWwtb3BlbnMgaW50ZXJuYWxseSksIHNvIHRoZSBjYXRjaCBvbmx5IGV2ZXJcbiAgICAgIC8vIHNlZXMgYSBnZW51aW5lIGRvd25zdHJlYW0gZXJyb3IuXG4gICAgICBpc1Rva2VuUmV2b2tlZChkZWNvZGVkKVxuICAgICAgICAudGhlbigocmV2b2tlZCkgPT4ge1xuICAgICAgICAgIGlmIChyZXZva2VkKSB7XG4gICAgICAgICAgICByZXR1cm4gc2VuZEVycm9yKHJlcywgSHR0cFN0YXR1cy5VTkFVVEhPUklaRUQsICdTZXNzaW9uIGhhcyBiZWVuIHJldm9rZWQ7IHBsZWFzZSBzaWduIGluIGFnYWluJywgRXJyb3JDb2RlLlRPS0VOX1JFVk9LRUQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBuZXh0KCk7XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaChuZXh0KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBuZXh0KCk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgaWYgKGVycm9yIGluc3RhbmNlb2Ygand0LlRva2VuRXhwaXJlZEVycm9yKSB7XG4gICAgICByZXR1cm4gc2VuZEVycm9yKHJlcywgSHR0cFN0YXR1cy5VTkFVVEhPUklaRUQsICdUb2tlbiBoYXMgZXhwaXJlZCcsIEVycm9yQ29kZS5UT0tFTl9FWFBJUkVEKTtcbiAgICB9XG5cbiAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBqd3QuSnNvbldlYlRva2VuRXJyb3IpIHtcbiAgICAgIHJldHVybiBzZW5kRXJyb3IocmVzLCBIdHRwU3RhdHVzLlVOQVVUSE9SSVpFRCwgJ0ludmFsaWQgdG9rZW4nLCBFcnJvckNvZGUuVE9LRU5fSU5WQUxJRCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHNlbmRFcnJvcihyZXMsIEh0dHBTdGF0dXMuVU5BVVRIT1JJWkVELCAnQXV0aGVudGljYXRpb24gZmFpbGVkJywgRXJyb3JDb2RlLlVOQVVUSE9SSVpFRCk7XG4gIH1cbn1cblxuLyoqXG4gKiBXaGV0aGVyIHRoZSByZXF1ZXN0J3MgdXNlciBob2xkcyBgcGVybWlzc2lvbmAuIFN1cGVyYWRtaW5zIGltcGxpY2l0bHkgaG9sZFxuICogZXZlcnkgcGVybWlzc2lvbi4gUmVhZHMgdGhlIHJlc29sdmVkIGBwZXJtaXNzaW9uc2AgY2xhaW0gKHNldCBhdCB0b2tlbiBpc3N1ZSxcbiAqIG9yIHJlLWRlcml2ZWQgcGVyIHJlcXVlc3QgYnkgdGhlIHBsYXRmb3JtKS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHVzZXJIYXNQZXJtaXNzaW9uKHJlcTogUmVxdWVzdCwgcGVybWlzc2lvbjogUGVybWlzc2lvbik6IGJvb2xlYW4ge1xuICByZXR1cm4gaGFzUGVybWlzc2lvbihyZXEudXNlcj8ucGVybWlzc2lvbnMsIHBlcm1pc3Npb24sIHJlcS51c2VyPy5pc1N1cGVyQWRtaW4pO1xufVxuXG4vKipcbiAqIENvbnRleHQgcGFzc2VkIHRvIGEgcmVnaXN0ZXJlZCBhdXRob3JpemF0aW9uLWRlbmlhbCBhdWRpdG9yIHdoZW4gYVxuICogc3RhdGUtY2hhbmdpbmcgcmVxdWVzdCBpcyByZWplY3RlZCBieSBgcmVxdWlyZVBlcm1pc3Npb25gIC9cbiAqIGByZXF1aXJlU3lzdGVtQWRtaW5gLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEF1dGh6RGVuaWFsSW5mbyB7XG4gIC8qKiBUaGUgZGVuaWVkIHVzZXIncyBpZCAoYHN1YmApLCBpZiBhdXRoZW50aWNhdGVkLiAqL1xuICBhY3RvcklkPzogc3RyaW5nO1xuICBhY3RvckVtYWlsPzogc3RyaW5nO1xuICAvKiogVGhlIHVzZXIncyBhY3RpdmUgb3JnIGF0IGRlbmlhbCB0aW1lLiAqL1xuICBvcmdJZD86IHN0cmluZztcbiAgLyoqIEhUVFAgbWV0aG9kICsgcGF0aCBvZiB0aGUgcmVqZWN0ZWQgcmVxdWVzdC4gKi9cbiAgbWV0aG9kOiBzdHJpbmc7XG4gIHBhdGg6IHN0cmluZztcbiAgLyoqIFdoYXQgd2FzIHJlcXVpcmVkOiB0aGUgbWlzc2luZyBwZXJtaXNzaW9uKHMpLCBvciAnc3lzdGVtLWFkbWluJy4gKi9cbiAgcmVxdWlyZWQ6IHN0cmluZztcbn1cblxuLyoqXG4gKiBPcHRpb25hbCBzaW5rIGZvciBkZW5pZWQtYXV0aG9yaXphdGlvbiBldmVudHMuIExlZnQgdW5zZXQgYnkgZGVmYXVsdCBzb1xuICogYXBpLWNvcmUgc3RheXMgZGVjb3VwbGVkIGZyb20gYW55IGF1ZGl0IHRyYW5zcG9ydCDigJQgYSBzZXJ2aWNlIHJlZ2lzdGVycyBvbmVcbiAqIGF0IGJvb3QgKHR5cGljYWxseSBmb3J3YXJkaW5nIHRvIGl0cyBgUmVtb3RlQXVkaXRDbGllbnRgIGFzIGFuXG4gKiBgYXV0aHouZGVuaWVkYCBldmVudCwgb3IsIG9uIHBsYXRmb3JtLCB0byB0aGUgbG9jYWwgYGF1ZGl0KClgIGhlbHBlcikuXG4gKiBNVVNUIGJlIGJlc3QtZWZmb3J0OiBpdCBpcyBpbnZva2VkIGluc2lkZSB0aGUgcmVxdWVzdCBwYXRoLCBzbyBpdCBtdXN0IG5ldmVyXG4gKiB0aHJvdyBvciBibG9jayAodGhlIGdhdGUgd3JhcHMgdGhlIGNhbGwgaW4gdHJ5L2NhdGNoIHJlZ2FyZGxlc3MpLlxuICovXG5sZXQgYXV0aHpEZW5pYWxBdWRpdG9yOiAoKGluZm86IEF1dGh6RGVuaWFsSW5mbykgPT4gdm9pZCkgfCB1bmRlZmluZWQ7XG5cbi8qKlxuICogUmVnaXN0ZXIgKG9yIGNsZWFyLCB3aXRoIGB1bmRlZmluZWRgKSB0aGUgcHJvY2Vzcy13aWRlIGF1dGhvcml6YXRpb24tZGVuaWFsXG4gKiBhdWRpdG9yLiBJZGVtcG90ZW50OyB0aGUgbGFzdCByZWdpc3RyYXRpb24gd2lucy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNldEF1dGh6RGVuaWFsQXVkaXRvcihmbjogKChpbmZvOiBBdXRoekRlbmlhbEluZm8pID0+IHZvaWQpIHwgdW5kZWZpbmVkKTogdm9pZCB7XG4gIGF1dGh6RGVuaWFsQXVkaXRvciA9IGZuO1xufVxuXG4vKipcbiAqIEVtaXQgYSBkZW5pYWwgZXZlbnQsIGJlc3QtZWZmb3J0LiBPbmx5IGZpcmVzIGZvciBzdGF0ZS1jaGFuZ2luZyAobm9uLUdFVCxcbiAqIG5vbi1IRUFEL09QVElPTlMpIHJlcXVlc3RzIOKAlCBhIHJlamVjdGVkIEdFVCBpcyBsb3ctc2lnbmFsIHByb2Jpbmcgbm9pc2UgYW5kXG4gKiB3b3VsZCBhbXBsaWZ5IGF1ZGl0IHZvbHVtZSB1bmRlciBhIHNjYW4uIE5ldmVyIHRocm93cy5cbiAqL1xuZnVuY3Rpb24gYXVkaXRBdXRoekRlbmlhbChyZXE6IFJlcXVlc3QsIHJlcXVpcmVkOiBzdHJpbmcpOiB2b2lkIHtcbiAgY29uc3QgYXVkaXRvciA9IGF1dGh6RGVuaWFsQXVkaXRvcjtcbiAgaWYgKCFhdWRpdG9yKSByZXR1cm47XG4gIGNvbnN0IG1ldGhvZCA9IHJlcS5tZXRob2QudG9VcHBlckNhc2UoKTtcbiAgaWYgKG1ldGhvZCA9PT0gJ0dFVCcgfHwgbWV0aG9kID09PSAnSEVBRCcgfHwgbWV0aG9kID09PSAnT1BUSU9OUycpIHJldHVybjtcbiAgdHJ5IHtcbiAgICBhdWRpdG9yKHtcbiAgICAgIGFjdG9ySWQ6IHJlcS51c2VyPy5zdWIsXG4gICAgICBhY3RvckVtYWlsOiByZXEudXNlcj8uZW1haWwsXG4gICAgICBvcmdJZDogcmVxLnVzZXI/Lm9yZ2FuaXphdGlvbklkLFxuICAgICAgbWV0aG9kLFxuICAgICAgLy8gU3RyaXAgdGhlIHF1ZXJ5IHN0cmluZyDigJQgYSBkZW5pZWQgcmVxdWVzdCBtYXkgY2FycnkgYSB0b2tlbi9zZWNyZXQgYXMgYVxuICAgICAgLy8gcXVlcnkgcGFyYW0sIGFuZCB0aGlzIHBhdGggaXMgcGVyc2lzdGVkIHZlcmJhdGltIGludG8gdGhlIGF1ZGl0IGxvZy5cbiAgICAgIHBhdGg6IChyZXEub3JpZ2luYWxVcmwgfHwgcmVxLnVybCkuc3BsaXQoJz8nKVswXSxcbiAgICAgIHJlcXVpcmVkLFxuICAgIH0pO1xuICB9IGNhdGNoIHtcbiAgICAvLyBCZXN0LWVmZm9ydCDigJQgYSBicm9rZW4gYXVkaXRvciBtdXN0IG5ldmVyIGJyZWFrIHRoZSBhdXRoIGdhdGUuXG4gIH1cbn1cblxuLyoqXG4gKiBSZXF1aXJlcyB0aGF0IHRoZSB1c2VyIGhvbGQgQVQgTEVBU1QgT05FIG9mIHRoZSBnaXZlbiBwZXJtaXNzaW9ucyAob3IgYmUgYVxuICogc3VwZXJhZG1pbikuIFVzZSBhZnRlciByZXF1aXJlQXV0aC4gTWlycm9ycyBgcmVxdWlyZVJvbGVgJ3MgYW55LW9mIHNlbWFudGljcztcbiAqIHBhc3MgYSBzaW5nbGUgcGVybWlzc2lvbiBmb3IgYSBzcGVjaWZpYyBhY3Rpb24sIG9yIHNldmVyYWwgd2hlbiBhbnkgb25lIG9mXG4gKiB0aGVtIHNob3VsZCBncmFudCBhY2Nlc3MuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXF1aXJlUGVybWlzc2lvbiguLi5wZXJtaXNzaW9uczogUGVybWlzc2lvbltdKSB7XG4gIHJldHVybiAocmVxOiBSZXF1ZXN0LCByZXM6IFJlc3BvbnNlLCBuZXh0OiBOZXh0RnVuY3Rpb24pOiB2b2lkID0+IHtcbiAgICBpZiAoIXJlcS51c2VyKSB7XG4gICAgICByZXR1cm4gc2VuZEVycm9yKHJlcywgSHR0cFN0YXR1cy5VTkFVVEhPUklaRUQsICdBdXRoZW50aWNhdGlvbiByZXF1aXJlZCcsIEVycm9yQ29kZS5VTkFVVEhPUklaRUQpO1xuICAgIH1cbiAgICAvLyB1c2VySGFzUGVybWlzc2lvbiDihpIgaGFzUGVybWlzc2lvbiBhbHJlYWR5IGdyYW50cyBzdXBlcmFkbWlucyBldmVyeVxuICAgIC8vIHBlcm1pc3Npb24sIHNvIHRoaXMgc2luZ2xlIGNoZWNrIGNvdmVycyBib3RoIHRoZSBzdXBlcmFkbWluIGJ5cGFzcyBhbmRcbiAgICAvLyB0aGUgYW55LW9mIG1lbWJlcnNoaXAgdGVzdCB3aXRob3V0IHJlLWlubGluaW5nIGVpdGhlci5cbiAgICBpZiAocGVybWlzc2lvbnMuc29tZSgocCkgPT4gdXNlckhhc1Blcm1pc3Npb24ocmVxLCBwKSkpIHJldHVybiBuZXh0KCk7XG4gICAgYXVkaXRBdXRoekRlbmlhbChyZXEsIHBlcm1pc3Npb25zLmpvaW4oJyBvciAnKSk7XG4gICAgcmV0dXJuIHNlbmRFcnJvcihcbiAgICAgIHJlcywgSHR0cFN0YXR1cy5GT1JCSURERU4sXG4gICAgICBgTWlzc2luZyByZXF1aXJlZCBwZXJtaXNzaW9uOiAke3Blcm1pc3Npb25zLmpvaW4oJyBvciAnKX1gLFxuICAgICAgRXJyb3JDb2RlLklOU1VGRklDSUVOVF9QRVJNSVNTSU9OUyxcbiAgICApO1xuICB9O1xufVxuXG4vKipcbiAqIFJlcXVpcmVzIHRoYXQgdGhlIHVzZXIgaG9sZCBFVkVSWSBvbmUgb2YgdGhlIGdpdmVuIHBlcm1pc3Npb25zIChvciBiZSBhXG4gKiBzdXBlcmFkbWluKSDigJQgdGhlIEFORCBjb3VudGVycGFydCB0byBgcmVxdWlyZVBlcm1pc3Npb25gJ3MgYW55LW9mLiBVc2UgZm9yIGFcbiAqIHNlbnNpdGl2ZSBhY3Rpb24gdGhhdCBsZWdpdGltYXRlbHkgZGVtYW5kcyB0d28gZGlzdGluY3QgY2FwYWJpbGl0aWVzIGF0IG9uY2VcbiAqIChlLmcuIGEgY3Jvc3Mtc3VyZmFjZSBvcGVyYXRpb24pLCBzbyB0aGUgZ3VhcmFudGVlIGlzIGV4cGxpY2l0IHJhdGhlciB0aGFuXG4gKiBhcHByb3hpbWF0ZWQgYnkgY2hhaW5pbmcgdHdvIGByZXF1aXJlUGVybWlzc2lvbmAgZ2F0ZXMuIFN1cGVyYWRtaW5zIGJ5cGFzc1xuICogKHRoZXkgaW1wbGljaXRseSBob2xkIGV2ZXJ5IHBlcm1pc3Npb24pLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVxdWlyZUFsbFBlcm1pc3Npb25zKC4uLnBlcm1pc3Npb25zOiBQZXJtaXNzaW9uW10pIHtcbiAgcmV0dXJuIChyZXE6IFJlcXVlc3QsIHJlczogUmVzcG9uc2UsIG5leHQ6IE5leHRGdW5jdGlvbik6IHZvaWQgPT4ge1xuICAgIGlmICghcmVxLnVzZXIpIHtcbiAgICAgIHJldHVybiBzZW5kRXJyb3IocmVzLCBIdHRwU3RhdHVzLlVOQVVUSE9SSVpFRCwgJ0F1dGhlbnRpY2F0aW9uIHJlcXVpcmVkJywgRXJyb3JDb2RlLlVOQVVUSE9SSVpFRCk7XG4gICAgfVxuICAgIGNvbnN0IG1pc3NpbmcgPSBwZXJtaXNzaW9ucy5maWx0ZXIoKHApID0+ICF1c2VySGFzUGVybWlzc2lvbihyZXEsIHApKTtcbiAgICBpZiAobWlzc2luZy5sZW5ndGggPT09IDApIHJldHVybiBuZXh0KCk7XG4gICAgYXVkaXRBdXRoekRlbmlhbChyZXEsIHBlcm1pc3Npb25zLmpvaW4oJyBhbmQgJykpO1xuICAgIHJldHVybiBzZW5kRXJyb3IoXG4gICAgICByZXMsIEh0dHBTdGF0dXMuRk9SQklEREVOLFxuICAgICAgYE1pc3NpbmcgcmVxdWlyZWQgcGVybWlzc2lvbjogJHttaXNzaW5nLmpvaW4oJyBhbmQgJyl9YCxcbiAgICAgIEVycm9yQ29kZS5JTlNVRkZJQ0lFTlRfUEVSTUlTU0lPTlMsXG4gICAgKTtcbiAgfTtcbn1cblxuLyoqXG4gKiBMaWtlIHtAbGluayByZXF1aXJlUGVybWlzc2lvbn0gKGFueS1vZikgYnV0IEFMU08gYWRtaXRzIGFuIGludGVybmFsIHNlcnZpY2VcbiAqIHByaW5jaXBhbCAoYSBgc2VydmljZToqYCBtYWNoaW5lIHRva2VuKS4gRm9yIFJFQUQgZW5kcG9pbnRzIHRoYXQgQk9USFxuICogaW50ZXJhY3RpdmUgdXNlcnMg4oCUIHdobyBtdXN0IGhvbGQgb25lIG9mIHRoZSBgOnJlYWRgIGNhcGFiaWxpdGllcyDigJQgQU5EXG4gKiBzZXJ2aWNlLXRvLXNlcnZpY2UgY2FsbGVycyBsZWdpdGltYXRlbHkgaGl0OyBzZXJ2aWNlIHRva2VucyBjYXJyeSBub1xuICogcGVybWlzc2lvbiBjbGFpbXMgKHRoZXkncmUgbGVhc3QtcHJpdmlsZWdlIGByb2xlOm1lbWJlcmApLCBzbyBhIHBsYWluXG4gKiBgcmVxdWlyZVBlcm1pc3Npb25gIHdvdWxkIHdyb25nbHkgNDAzIHRoZW0uIFN1cGVyYWRtaW5zIHBhc3MgdmlhXG4gKiBgdXNlckhhc1Blcm1pc3Npb25gJ3MgaW1wbGljaXQtYWxsLiBVc2Ugb25seSB3aGVyZSBhIHNlcnZpY2UgY2FsbGVyIGlzIGEga25vd24sXG4gKiBpbnRlbmRlZCBjb25zdW1lciBvZiB0aGUgcm91dGUgKHZlcmlmeSB0aGUgY2FsbGVycyk7IHByZWZlciBwbGFpblxuICogYHJlcXVpcmVQZXJtaXNzaW9uYCBmb3IgcHVyZWx5IHVzZXItZmFjaW5nIHJlYWRzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVxdWlyZVBlcm1pc3Npb25PclNlcnZpY2UoLi4ucGVybWlzc2lvbnM6IFBlcm1pc3Npb25bXSkge1xuICByZXR1cm4gKHJlcTogUmVxdWVzdCwgcmVzOiBSZXNwb25zZSwgbmV4dDogTmV4dEZ1bmN0aW9uKTogdm9pZCA9PiB7XG4gICAgaWYgKCFyZXEudXNlcikge1xuICAgICAgcmV0dXJuIHNlbmRFcnJvcihyZXMsIEh0dHBTdGF0dXMuVU5BVVRIT1JJWkVELCAnQXV0aGVudGljYXRpb24gcmVxdWlyZWQnLCBFcnJvckNvZGUuVU5BVVRIT1JJWkVEKTtcbiAgICB9XG4gICAgaWYgKGlzU2VydmljZVByaW5jaXBhbChyZXEpIHx8IHBlcm1pc3Npb25zLnNvbWUoKHApID0+IHVzZXJIYXNQZXJtaXNzaW9uKHJlcSwgcCkpKSByZXR1cm4gbmV4dCgpO1xuICAgIGF1ZGl0QXV0aHpEZW5pYWwocmVxLCBwZXJtaXNzaW9ucy5qb2luKCcgb3IgJykpO1xuICAgIHJldHVybiBzZW5kRXJyb3IoXG4gICAgICByZXMsIEh0dHBTdGF0dXMuRk9SQklEREVOLFxuICAgICAgYE1pc3NpbmcgcmVxdWlyZWQgcGVybWlzc2lvbjogJHtwZXJtaXNzaW9ucy5qb2luKCcgb3IgJyl9YCxcbiAgICAgIEVycm9yQ29kZS5JTlNVRkZJQ0lFTlRfUEVSTUlTU0lPTlMsXG4gICAgKTtcbiAgfTtcbn1cblxuLyoqXG4gKiBHYXRlIGFuIGVuZHBvaW50IHRvIGludGVybmFsIHNlcnZpY2UtdG8tc2VydmljZSBjYWxsZXJzIG9ubHkgKGEgYHNlcnZpY2U6KmBcbiAqIG1hY2hpbmUgcHJpbmNpcGFsIG1pbnRlZCB2aWEge0BsaW5rIHNpZ25TZXJ2aWNlVG9rZW59IC8gYGdldFNlcnZpY2VBdXRoSGVhZGVyYCkuXG4gKiBSZWplY3RzIGFueSB1c2VyIHRva2VuLiBGb3IgTk9OLXVzZXItZmFjaW5nIGVuZHBvaW50cyDigJQgZW50aXR5LWV2ZW50IGluZ2VzdCxcbiAqIGF1dG8tc3Vic2NyaWJlLCBhbmQgc2ltaWxhciBwZWVyLXNlcnZpY2UgaG9va3Mg4oCUIHRoYXQgYSBicm93c2VyIG11c3QgbmV2ZXJcbiAqIHJlYWNoLiBDb21wb3NlIGFmdGVyIGByZXF1aXJlQXV0aGAgc28gYHJlcS51c2VyYCBpcyBwb3B1bGF0ZWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXF1aXJlU2VydmljZVByaW5jaXBhbChyZXE6IFJlcXVlc3QsIHJlczogUmVzcG9uc2UsIG5leHQ6IE5leHRGdW5jdGlvbik6IHZvaWQge1xuICBpZiAoIWlzU2VydmljZVByaW5jaXBhbChyZXEpKSB7XG4gICAgLy8gNDAzIChub3QgNDAwKSDigJQgdGhpcyBpcyBhbiBhdXRob3JpemF0aW9uIHJlZnVzYWw7IHN0YXR1cyBtdXN0IG1hdGNoIHRoZVxuICAgIC8vIElOU1VGRklDSUVOVF9QRVJNSVNTSU9OUyBjb2RlIGFuZCB0aGUgc2libGluZyBnYXRlcyAocmVxdWlyZVBlcm1pc3Npb24sIGV0Yy4pLlxuICAgIHJldHVybiBzZW5kRXJyb3IocmVzLCBIdHRwU3RhdHVzLkZPUkJJRERFTiwgJ0ludGVybmFsIHNlcnZpY2UgY2FsbHMgb25seScsIEVycm9yQ29kZS5JTlNVRkZJQ0lFTlRfUEVSTUlTU0lPTlMpO1xuICB9XG4gIG5leHQoKTtcbn1cblxuLyoqXG4gKiBUaGUgc3lzdGVtIHRlbmFudCdzIGNhbm9uaWNhbCBvcmcgKippZCoqIOKAlCBhIGZpeGVkLCB3ZWxsLWtub3duIE9iamVjdElkIChOT1RcbiAqIHRoZSBzdHJpbmcgJ3N5c3RlbScpLiBUaGlzIGlzIHRoZSBzaW5nbGUga25vYiBldmVyeSBzZXJ2aWNlIHJlc29sdmVzIHRoZVxuICogc3lzdGVtIHRlbmFudCB0aHJvdWdoOyBvdmVycmlkZSB2aWEgdGhlIGBTWVNURU1fT1JHX0lEYCBlbnYgZm9yIGFsdGVybmF0ZVxuICogaW5zdGFsbHMuIFRoZSBzeXN0ZW0gb3JnJ3MgaHVtYW4gaWRlbnRpZmllciBzdGF5cyB0aGUgc2x1Zy9uYW1lICdzeXN0ZW0nXG4gKiAoc2VlIHtAbGluayBTWVNURU1fT1JHX1NMVUd9KTsgb25seSBpdHMgYF9pZGAgaXMgdGhpcyBPYmplY3RJZC5cbiAqL1xuZXhwb3J0IGNvbnN0IFNZU1RFTV9PUkdfSUQgPSAocHJvY2Vzcy5lbnYuU1lTVEVNX09SR19JRCB8fCAnMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAxJykudG9Mb3dlckNhc2UoKTtcblxuLyoqIFRoZSBzeXN0ZW0gb3JnJ3Mgd2VsbC1rbm93biBzbHVnL25hbWUgKHRoZSBodW1hbiBpZGVudGlmaWVyOyBpdHMgYF9pZGAgaXMge0BsaW5rIFNZU1RFTV9PUkdfSUR9KS4gKi9cbmV4cG9ydCBjb25zdCBTWVNURU1fT1JHX1NMVUcgPSAnc3lzdGVtJztcblxuLyoqXG4gKiBDaGVjayBpZiBhbiBvcmdJZCBvciBvcmdOYW1lL3NsdWcgbWF0Y2hlcyB0aGUgc3lzdGVtIG9yZy4gVXNlIHRoaXMgaW5zdGVhZCBvZlxuICogY29tcGFyaW5nIGRpcmVjdGx5OiB0aGUgaWQgaXMgbm93IGFuIE9iamVjdElkICh7QGxpbmsgU1lTVEVNX09SR19JRH0pIHdoaWxlIHRoZVxuICogbmFtZS9zbHVnIGlzICdzeXN0ZW0nICh7QGxpbmsgU1lTVEVNX09SR19TTFVHfSksIHNvIHRoZSB0d28gYXJlIGNvbXBhcmVkIGFnYWluc3RcbiAqIHRoZWlyIHJlc3BlY3RpdmUgY2Fub25pY2FsIHZhbHVlcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzU3lzdGVtT3JnSWQob3JnSWQ/OiBzdHJpbmcsIG9yZ05hbWU/OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgcmV0dXJuIG9yZ0lkPy50b0xvd2VyQ2FzZSgpID09PSBTWVNURU1fT1JHX0lEIHx8IG9yZ05hbWU/LnRvTG93ZXJDYXNlKCkgPT09IFNZU1RFTV9PUkdfU0xVRztcbn1cblxuLyoqXG4gKiBDaGVjayBpZiB0aGUgcmVxdWVzdCBpcyBmcm9tIGEgc3lzdGVtIGFkbWluLlxuICpcbiAqIEF1dGhvcml0eSBpcyBncmFudGVkIHNvbGVseSBieSB0aGUgdXNlci1sZXZlbCBgaXNTdXBlckFkbWluYCBmbGFnIGNhcnJpZWRcbiAqIGluIHRoZSBKV1QuIFRoZSBcIm1lbWJlcnNoaXAgaW4gdGhlIHdlbGwta25vd24gJ3N5c3RlbScgb3JnIHdpdGggcm9sZVxuICogYWRtaW4vb3duZXJcIiBwYXRoIHdhcyByZW1vdmVkIOKAlCBpdCBjb25mbGF0ZWQgYSBQaXBlbGluZSBCdWlsZGVyIG9wZXJhdG9yXG4gKiB3aXRoIGEgcmVhbCBjdXN0b21lciB0ZW5hbnQgaW4gdGhlIGRhdGEgbW9kZWwsIGFuZCBtZWFudCBhbnkgdW5pbnRlbmRlZFxuICogd3JpdGUgdGhhdCBjcmVhdGVkIGEgJ3N5c3RlbSctbmFtZWQgb3JnIGNvdWxkIHF1aWV0bHkgZ3JhbnQgY3Jvc3Mtb3JnXG4gKiBhdXRob3JpdHkuIFRoZSBgc3lzdGVtYCBvcmcgc3RpbGwgZXhpc3RzIGFzIGEgKmNvbnRlbnQgaG9sZGVyKiBmb3Igc2hhcmVkXG4gKiBzYW1wbGUgZGF0YTsgaXQganVzdCBubyBsb25nZXIgY29uZmVycyBwcml2aWxlZ2UuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1N5c3RlbUFkbWluKHJlcTogUmVxdWVzdCk6IGJvb2xlYW4ge1xuICByZXR1cm4gcmVxLnVzZXI/LmlzU3VwZXJBZG1pbiA9PT0gdHJ1ZTtcbn1cblxuLyoqXG4gKiBXaGV0aGVyIHRoZSByZXF1ZXN0J3MgdG9rZW4gY2FycmllcyBhIHNwZWNpZmljIGNhcGFiaWxpdHkgYHNjb3BlYCAoZS5nLlxuICogYCdyZXBvcnRpbmc6aW5nZXN0J2ApLiBVc2VkIHRvIGdhdGUgZW5kcG9pbnRzIHRoYXQgYWNjZXB0IGEgbmFycm93IG1hY2hpbmVcbiAqIGlkZW50aXR5IOKAlCBhIG5vcm1hbCBpbnRlcmFjdGl2ZSB1c2VyIHRva2VuIGhhcyBubyBgc2NvcGVgIGFuZCByZXR1cm5zIGZhbHNlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaGFzU2NvcGUocmVxOiBSZXF1ZXN0LCBzY29wZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHJldHVybiByZXEudXNlcj8uc2NvcGUgPT09IHNjb3BlO1xufVxuXG4vKiogUmVxdWlyZXMgYSBzeXN0ZW0gYWRtaW4g4oCUIGdyYW50ZWQgc29sZWx5IGJ5IHRoZSBgaXNTdXBlckFkbWluYCB0b2tlbiBjbGFpbVxuICogICh0aGUgb3JnLW1lbWJlcnNoaXAgcGF0aCB3YXMgcmVtb3ZlZCkuIFVzZSBhZnRlciByZXF1aXJlQXV0aC4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXF1aXJlU3lzdGVtQWRtaW4oXG4gIHJlcTogUmVxdWVzdCxcbiAgcmVzOiBSZXNwb25zZSxcbiAgbmV4dDogTmV4dEZ1bmN0aW9uLFxuKTogdm9pZCB7XG4gIGlmICghaXNTeXN0ZW1BZG1pbihyZXEpKSB7XG4gICAgYXVkaXRBdXRoekRlbmlhbChyZXEsICdzeXN0ZW0tYWRtaW4nKTtcbiAgICByZXR1cm4gc2VuZEVycm9yKFxuICAgICAgcmVzLCBIdHRwU3RhdHVzLkZPUkJJRERFTixcbiAgICAgICdBY2Nlc3MgZGVuaWVkLiBPbmx5IHN5c3RlbSBhZG1pbmlzdHJhdG9ycyBjYW4gcGVyZm9ybSB0aGlzIGFjdGlvbi4nLFxuICAgICAgRXJyb3JDb2RlLklOU1VGRklDSUVOVF9QRVJNSVNTSU9OUyxcbiAgICApO1xuICB9XG4gIG5leHQoKTtcbn1cblxuLyoqXG4gKiBSZXF1aXJlIGEgc3BlY2lmaWMgZmVhdHVyZSBmbGFnLiBVc2UgYWZ0ZXIgcmVxdWlyZUF1dGguXG4gKiBDaGVja3MgdGhlIGBmZWF0dXJlc2AgYXJyYXkgaW4gdGhlIEpXVCBwYXlsb2FkIChzZXQgYXQgdG9rZW4gaXNzdWFuY2UpLlxuICogU3lzYWRtaW5zIChpc1N1cGVyQWRtaW4pIGJ5cGFzcyDigJQgdGhleSBhbHdheXMgaGF2ZSBldmVyeSBmZWF0dXJlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVxdWlyZUZlYXR1cmUoZmVhdHVyZTogc3RyaW5nKSB7XG4gIHJldHVybiAocmVxOiBSZXF1ZXN0LCByZXM6IFJlc3BvbnNlLCBuZXh0OiBOZXh0RnVuY3Rpb24pOiB2b2lkID0+IHtcbiAgICBpZiAoIXJlcS51c2VyKSB7XG4gICAgICByZXR1cm4gc2VuZEVycm9yKHJlcywgSHR0cFN0YXR1cy5VTkFVVEhPUklaRUQsICdBdXRoZW50aWNhdGlvbiByZXF1aXJlZCcsIEVycm9yQ29kZS5VTkFVVEhPUklaRUQpO1xuICAgIH1cblxuICAgIC8vIFN5c2FkbWlucyBnZXQgYWxsIGZlYXR1cmVzOyB0aGUgYGZlYXR1cmVzYCBhcnJheSBvbiB0aGVpciB0b2tlbiBpc1xuICAgIC8vIHBvcHVsYXRlZCB3aXRoIGV2ZXJ5IGZsYWcgYXQgaXNzdWFuY2UgdGltZSBidXQgdGhlIGJ5cGFzcyBoZXJlIGtlZXBzXG4gICAgLy8gdGhlIHJ1bGUgZXhwbGljaXQgYW5kIHN1cnZpdmVzIGEgdG9rZW4gaXNzdWVkIGJlZm9yZSBhIG5ldyBmZWF0dXJlXG4gICAgLy8gZmxhZyB3YXMgYWRkZWQuXG4gICAgaWYgKHJlcS51c2VyLmlzU3VwZXJBZG1pbiA9PT0gdHJ1ZSkgcmV0dXJuIG5leHQoKTtcblxuICAgIGlmICghcmVxLnVzZXIuZmVhdHVyZXM/LmluY2x1ZGVzKGZlYXR1cmUpKSB7XG4gICAgICAvLyBSb3V0ZSBmZWF0dXJlLWdhdGUgZGVuaWFscyB0aHJvdWdoIHRoZSBzYW1lIGF1ZGl0IHNpbmsgYXNcbiAgICAgIC8vIHJlcXVpcmVQZXJtaXNzaW9uIC8gcmVxdWlyZVN5c3RlbUFkbWluIHNvIGEgcHJvYmUgZm9yIGFuXG4gICAgICAvLyB1bmVudGl0bGVkIGNhcGFiaWxpdHkgbGVhdmVzIGEgdHJhaWwgKHN0YXRlLWNoYW5naW5nIG1ldGhvZHMgb25seSkuXG4gICAgICBhdWRpdEF1dGh6RGVuaWFsKHJlcSwgYGZlYXR1cmU6JHtmZWF0dXJlfWApO1xuICAgICAgcmV0dXJuIHNlbmRFcnJvcihcbiAgICAgICAgcmVzLCBIdHRwU3RhdHVzLkZPUkJJRERFTixcbiAgICAgICAgYFRoaXMgZmVhdHVyZSByZXF1aXJlcyBhIGhpZ2hlciBwbGFuICgke2ZlYXR1cmV9KWAsXG4gICAgICAgIEVycm9yQ29kZS5JTlNVRkZJQ0lFTlRfUEVSTUlTU0lPTlMsXG4gICAgICApO1xuICAgIH1cblxuICAgIG5leHQoKTtcbiAgfTtcbn1cblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBTZXJ2aWNlLXRvLXNlcnZpY2UgdG9rZW5zXG4vL1xuLy8gSW50ZXItc2VydmljZSBIVFRQIGNhbGxzIChiaWxsaW5nIOKGkiBtZXNzYWdlLCBwbGF0Zm9ybSDihpIgY29tcGxpYW5jZSwgZXRjLilcbi8vIG5lZWQgdG8gc2F0aXNmeSB0aGUgc2FtZSBgcmVxdWlyZUF1dGhgIG1pZGRsZXdhcmUgYXMgdXNlciByZXF1ZXN0cy5cbi8vIGBzaWduU2VydmljZVRva2VuYCBtaW50cyBhIHNob3J0LWxpdmVkIEpXVCBzaWduZWQgd2l0aCB0aGUgc2hhcmVkXG4vLyBKV1RfU0VDUkVULCBpZGVudGlmeWluZyB0aGUgY2FsbGluZyBzZXJ2aWNlIHZpYSBgc3ViOiAnc2VydmljZTo8bmFtZT4nYC5cbi8vIGByZXF1aXJlQXV0aGAgYWNjZXB0cyB0aGVzZSB0b2tlbnMgdHJhbnNwYXJlbnRseSDigJQgdGhleSBwYXNzIGBkZWNvZGVkLnN1YmBcbi8vIGFuZCBgZGVjb2RlZC5yb2xlYCBjaGVja3MsIGFuZCBkb3duc3RyZWFtIGByZXF1aXJlT3JnYW5pemF0aW9uYCAvXG4vLyBgcmVxdWlyZVN5c3RlbUFkbWluYCByZWx5IG9uIHRoZSBvcmcvcm9sZSBlbWJlZGRlZCBpbiB0aGUgdG9rZW4uXG4vL1xuLy8gVG9rZW5zIGRlZmF1bHQgdG8gNS1taW51dGUgVFRMIOKAlCBsb25nIGVub3VnaCB0byBzdXJ2aXZlIGEgYmFja2VuZCBob3AsXG4vLyBzaG9ydCBlbm91Z2ggdGhhdCBhIGxlYWtlZCB0b2tlbiBpcyBsb3ctdmFsdWUuXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuY29uc3QgREVGQVVMVF9TRVJWSUNFX1RPS0VOX1RUTF9TRUNPTkRTID0gMzAwO1xuXG4vKipcbiAqIERlbnlsaXN0IG9mIHNlcnZpY2UgTkFNRVMgKHRoZSBgPG5hbWU+YCBpbiBgc3ViOiBzZXJ2aWNlOjxuYW1lPmApIHdob3NlIHRva2Vuc1xuICogYHJlcXVpcmVBdXRoYCBtdXN0IHJlamVjdC4gU2VlZGVkIGZyb20gYFNFUlZJQ0VfVE9LRU5fREVOWUxJU1RgIChjb21tYS1zZXBhcmF0ZWQpXG4gKiBhdCBtb2R1bGUgbG9hZDsgYSBzZXJ2aWNlIGNhbiBwdXNoIGxpdmUgdXBkYXRlcyAoZS5nLiBmcm9tIGEgUmVkaXMtc3Vic2NyaWJlZFxuICoga2lsbC1zd2l0Y2gpIHZpYSB7QGxpbmsgc2V0U2VydmljZVRva2VuRGVueWxpc3R9IHNvIGEgY29tcHJvbWlzZWQgc2VydmljZSBjYW4gYmVcbiAqIGN1dCBvZmYgV0lUSE9VVCByb3RhdGluZyB0aGUgc2hhcmVkIEpXVCBzZWNyZXQgKHdoaWNoIGludmFsaWRhdGVzIGFsbCBvZiB0aGVtKS5cbiAqL1xubGV0IHNlcnZpY2VUb2tlbkRlbnlsaXN0ID0gbmV3IFNldChcbiAgKHByb2Nlc3MuZW52LlNFUlZJQ0VfVE9LRU5fREVOWUxJU1QgfHwgJycpXG4gICAgLnNwbGl0KCcsJylcbiAgICAubWFwKChzKSA9PiBzLnRyaW0oKSlcbiAgICAuZmlsdGVyKEJvb2xlYW4pLFxuKTtcblxuLyoqIFJlcGxhY2UgdGhlIHNlcnZpY2UtdG9rZW4gZGVueWxpc3QgKHNlcnZpY2UgbmFtZXMpLiBFbXB0eSDih5Iga2lsbC1zd2l0Y2ggb2ZmLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNldFNlcnZpY2VUb2tlbkRlbnlsaXN0KG5hbWVzOiBJdGVyYWJsZTxzdHJpbmc+KTogdm9pZCB7XG4gIHNlcnZpY2VUb2tlbkRlbnlsaXN0ID0gbmV3IFNldChbLi4ubmFtZXNdLm1hcCgocykgPT4gcy50cmltKCkpLmZpbHRlcihCb29sZWFuKSk7XG59XG5cbi8qKiBUcnVlIHdoZW4gYHN1YmAgaXMgYHNlcnZpY2U6PG5hbWU+YCBhbmQgYDxuYW1lPmAgaXMgb24gdGhlIGRlbnlsaXN0LiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzU2VydmljZVRva2VuRGVuaWVkKHN1Yjogc3RyaW5nKTogYm9vbGVhbiB7XG4gIGlmIChzZXJ2aWNlVG9rZW5EZW55bGlzdC5zaXplID09PSAwKSByZXR1cm4gZmFsc2U7XG4gIGlmICghc3ViLnN0YXJ0c1dpdGgoJ3NlcnZpY2U6JykpIHJldHVybiBmYWxzZTtcbiAgcmV0dXJuIHNlcnZpY2VUb2tlbkRlbnlsaXN0LmhhcyhzdWIuc2xpY2UoJ3NlcnZpY2U6Jy5sZW5ndGgpKTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBTZXJ2aWNlVG9rZW5PcHRpb25zIHtcbiAgLyoqIENhbGxpbmcgc2VydmljZSBpZGVudGlmaWVyIChlLmcuICdiaWxsaW5nJywgJ3BsYXRmb3JtJykuIEVtYmVkZGVkIGFzIGBzdWI6IHNlcnZpY2U6PG5hbWU+YC4gKi9cbiAgc2VydmljZU5hbWU6IHN0cmluZztcbiAgLyoqIEFjdGl2ZSBvcmcgY29udGV4dCBmb3IgdGhlIGNhbGwuIFVzZSB0aGUgdGFyZ2V0IHRlbmFudCdzIG9yZyBpZCwgb3IgdGhlXG4gICAqICB3ZWxsLWtub3duIGBTWVNURU1fT1JHX0lEYCAoYW4gT2JqZWN0SWQpIGZvciBzeXN0ZW0td2lkZSBvcHMg4oCUIE5PVCB0aGUgc3RyaW5nXG4gICAqICAnc3lzdGVtJywgd2hpY2ggaWQtYmFzZWQgc3lzdGVtLW9yZyBjaGVja3Mgd29uJ3QgcmVjb2duaXplLiAqL1xuICBvcmdJZD86IHN0cmluZztcbiAgLyoqIEFjdGl2ZSBvcmcgbmFtZS4gRGVmYXVsdHMgdG8gb3JnSWQuICovXG4gIG9yZ05hbWU/OiBzdHJpbmc7XG4gIC8qKiBUVEwgaW4gc2Vjb25kcyAoZGVmYXVsdCAzMDApLiAqL1xuICB0dGxTZWNvbmRzPzogbnVtYmVyO1xuICAvKipcbiAgICogUm9sZSB0aGUgdG9rZW4gY2FycmllcyAocmVxdWlyZWQg4oCUIG5vIGltcGxpY2l0IGRlZmF1bHQpLiAqKlBhc3MgdGhlIExPV0VTVFxuICAgKiByb2xlIHRoZSBjYWxsIGFjdHVhbGx5IG5lZWRzKiogKGAnbWVtYmVyJ2AgZm9yIHJlYWQgLyBkYXRhLXBsYW5lIGNhbGxzKSBzbyBhXG4gICAqIGxlYWtlZCBzZXJ2aWNlIHRva2VuIGNhbid0IHBlcmZvcm0gYWRtaW4gYWN0aW9ucyBpbiB0aGUgdGFyZ2V0IG9yZy5cbiAgICogYGlzQWRtaW5gIGlzIGRlcml2ZWQgZnJvbSB0aGlzIChhZG1pbnxvd25lciDihpIgdHJ1ZSkuXG4gICAqL1xuICByb2xlOiAnb3duZXInIHwgJ2FkbWluJyB8ICdtZW1iZXInO1xuICAvKipcbiAgICogT3B0aW9uYWwgZmluZS1ncmFpbmVkIHBlcm1pc3Npb24gY2xhaW0uIFByZWZlciB0aGlzICsgYHJvbGU6ICdtZW1iZXInYCBvdmVyIGFcbiAgICogaGlnaCByb2xlIHdoZW4gYSBjYWxsIG5lZWRzIE9ORSBzcGVjaWZpYyBjYXBhYmlsaXR5IChlLmcuIGBbJ3BsdWdpbnM6d3JpdGUnXWBcbiAgICogdG8gcHVzaCBhIHBsdWdpbiBpbWFnZSkg4oCUIHRoZSB0b2tlbiB0aGVuIHNhdGlzZmllcyB0aGF0IHBlcm1pc3Npb24gZ2F0ZVxuICAgKiBXSVRIT1VUIGNhcnJ5aW5nIGBpc0FkbWluYCwgc28gYSBsZWFrZWQgdG9rZW4gY2FuJ3QgcGVyZm9ybSBhZG1pbiBhY3Rpb25zLlxuICAgKi9cbiAgcGVybWlzc2lvbnM/OiBQZXJtaXNzaW9uW107XG59XG5cbi8qKlxuICogTWludCBhIEpXVCBpZGVudGlmeWluZyB0aGUgY2FsbGluZyBzZXJ2aWNlLiBVc2VkIGZvciBpbnRlci1zZXJ2aWNlIEhUVFAgY2FsbHMuXG4gKiBUaGUgdG9rZW4gc2F0aXNmaWVzIGByZXF1aXJlQXV0aGAgYW5kICh3aGVuIG9yZ0lkIGlzIHByZXNlbnQpIGByZXF1aXJlT3JnYW5pemF0aW9uYC5cbiAqIFNjb3BlIGl0IHdpdGggYG9wdHMucm9sZWAg4oCUIGxlYXN0IHByaXZpbGVnZSBrZWVwcyBhIGxlYWtlZCB0b2tlbiBsb3ctdmFsdWUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzaWduU2VydmljZVRva2VuKG9wdHM6IFNlcnZpY2VUb2tlbk9wdGlvbnMpOiBzdHJpbmcge1xuICBjb25zdCByb2xlID0gb3B0cy5yb2xlO1xuICBjb25zdCBwYXlsb2FkOiBKd3RQYXlsb2FkID0ge1xuICAgIHN1YjogYHNlcnZpY2U6JHtvcHRzLnNlcnZpY2VOYW1lfWAsXG4gICAgdXNlcm5hbWU6IGAke29wdHMuc2VydmljZU5hbWV9LXNlcnZpY2VgLFxuICAgIGVtYWlsOiBgJHtvcHRzLnNlcnZpY2VOYW1lfUBpbnRlcm5hbGAsXG4gICAgcm9sZSxcbiAgICBpc0FkbWluOiByb2xlID09PSAnb3duZXInIHx8IHJvbGUgPT09ICdhZG1pbicsXG4gICAgdHlwZTogJ2FjY2VzcycsXG4gICAgb3JnYW5pemF0aW9uSWQ6IG9wdHMub3JnSWQsXG4gICAgb3JnYW5pemF0aW9uTmFtZTogb3B0cy5vcmdOYW1lID8/IG9wdHMub3JnSWQsXG4gICAgLy8gTGVhc3QtcHJpdmlsZWdlIGNhcGFiaWxpdHkgY2xhaW0gKG9wdGlvbmFsKSDigJQgbGV0cyBhIG1lbWJlci1yb2xlIHRva2VuXG4gICAgLy8gc2F0aXNmeSBhIHNwZWNpZmljIHBlcm1pc3Npb24gZ2F0ZSB3aXRob3V0IGNhcnJ5aW5nIGlzQWRtaW4uXG4gICAgLi4uKG9wdHMucGVybWlzc2lvbnMgJiYgb3B0cy5wZXJtaXNzaW9ucy5sZW5ndGggPiAwID8geyBwZXJtaXNzaW9uczogb3B0cy5wZXJtaXNzaW9ucyB9IDoge30pLFxuICB9O1xuICAvLyBNYXRjaCB0aGUgb3B0aW9uYWwgaXNzdWVyL2F1ZGllbmNlIHRoYXQgcmVxdWlyZUF1dGggdmVyaWZpZXMsIHdoZW5cbiAgLy8gY29uZmlndXJlZC4gV2l0aG91dCB0aGVzZSwgYSBzZXJ2aWNlIHRva2VuIHNpZ25lZCBoZXJlIHdvdWxkIGZhaWxcbiAgLy8gcmVxdWlyZUF1dGggaW4gYSBkZXBsb3ltZW50IHRoYXQgaGFzIHNldCBKV1RfSVNTVUVSL0pXVF9BVURJRU5DRS5cbiAgY29uc3Qgc2lnbk9wdGlvbnM6IGp3dC5TaWduT3B0aW9ucyA9IHtcbiAgICBleHBpcmVzSW46IG9wdHMudHRsU2Vjb25kcyA/PyBERUZBVUxUX1NFUlZJQ0VfVE9LRU5fVFRMX1NFQ09ORFMsXG4gICAgLy8gU2lnbiB3aXRoIHRoZSBzYW1lIGNvbmZpZ3VyZWQgYWxnIHJlcXVpcmVBdXRoIHBpbnMgb24gdmVyaWZ5LCBzbyBzZXJ2aWNlXG4gICAgLy8gdG9rZW5zIHN0YXkgdmFsaWQgdW5kZXIgYSBub24tZGVmYXVsdCBKV1RfQUxHT1JJVEhNLlxuICAgIGFsZ29yaXRobTogKHByb2Nlc3MuZW52LkpXVF9BTEdPUklUSE0gfHwgJ0hTMjU2JykgYXMgand0LkFsZ29yaXRobSxcbiAgICAvLyBVbmlxdWUgdG9rZW4gaWQgb24gZXZlcnkgbWludC4gQ29tYmluZWQgd2l0aCB0aGUgc2hvcnQgKDMwMHMgZGVmYXVsdCkgVFRMXG4gICAgLy8gdGhpcyBnaXZlcyBlYWNoIHNlcnZpY2UgdG9rZW4gYSBkaXN0aW5jdCBpZGVudGl0eSDigJQgdGhlIGJ1aWxkaW5nIGJsb2NrIGZvclxuICAgIC8vIHJlcGxheSBkZXRlY3Rpb24gKGEgdmVyaWZpZXIgY2FuIHRyYWNrIHNlZW4ganRpcykgYW5kIHRoZSBjb3JyZWxhdGlvblxuICAgIC8vIGhhbmRsZSBmb3IgdHJhY2luZyB3aGljaCBtaW50IHBlcmZvcm1lZCBhIGNyb3NzLXNlcnZpY2UgYWN0aW9uLiBJdCBkb2VzXG4gICAgLy8gTk9UIGJ5IGl0c2VsZiBwcmV2ZW50IHJlcGxheSB3aXRoaW4gdGhlIFRUTCB3aW5kb3c7IHRydWUgcmVwbGF5IGRlZmVuY2VcbiAgICAvLyBuZWVkcyB0aGUgYXN5bW1ldHJpYy1rZXkgd29yayB0cmFja2VkIHNlcGFyYXRlbHkuXG4gICAgand0aWQ6IHJhbmRvbVVVSUQoKSxcbiAgfTtcbiAgaWYgKHByb2Nlc3MuZW52LkpXVF9JU1NVRVIpIHNpZ25PcHRpb25zLmlzc3VlciA9IHByb2Nlc3MuZW52LkpXVF9JU1NVRVI7XG4gIGlmIChwcm9jZXNzLmVudi5KV1RfQVVESUVOQ0UpIHNpZ25PcHRpb25zLmF1ZGllbmNlID0gcHJvY2Vzcy5lbnYuSldUX0FVRElFTkNFO1xuICByZXR1cm4gand0LnNpZ24ocGF5bG9hZCwgZ2V0Snd0U2VjcmV0KCksIHNpZ25PcHRpb25zKTtcbn1cblxuLyoqIENvbnZlbmllbmNlOiByZXR1cm5zIGEgYEJlYXJlciA8dG9rZW4+YCBoZWFkZXIgdmFsdWUgZm9yIGZldGNoL2F4aW9zIGNhbGxzLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFNlcnZpY2VBdXRoSGVhZGVyKG9wdHM6IFNlcnZpY2VUb2tlbk9wdGlvbnMpOiBzdHJpbmcge1xuICByZXR1cm4gYEJlYXJlciAke3NpZ25TZXJ2aWNlVG9rZW4ob3B0cyl9YDtcbn1cblxuLyoqIFRydWUgd2hlbiBgcmVxLnVzZXIuc3ViYCB3YXMgaXNzdWVkIGJ5IGBzaWduU2VydmljZVRva2VuYCAoaS5lLiBzdGFydHMgd2l0aCBgc2VydmljZTpgKS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1NlcnZpY2VQcmluY2lwYWwocmVxOiBSZXF1ZXN0KTogYm9vbGVhbiB7XG4gIHJldHVybiByZXEudXNlcj8uc3ViPy5zdGFydHNXaXRoKCdzZXJ2aWNlOicpID8/IGZhbHNlO1xufVxuXG4vKipcbiAqIFBSRS1hdXRoIGNoZWNrOiBjcnlwdG9ncmFwaGljYWxseSB2ZXJpZnkgdGhlIHJlcXVlc3QgY2FycmllcyBhIHZhbGlkLCBzaWduZWRcbiAqIFNFUlZJQ0UgdG9rZW4gKGBzdWJgIHN0YXJ0cyB3aXRoIGBzZXJ2aWNlOmApLiBVbmxpa2Uge0BsaW5rIGlzU2VydmljZVByaW5jaXBhbH1cbiAqICh3aGljaCByZWFkcyB0aGUgYWxyZWFkeS1wb3B1bGF0ZWQgYHJlcS51c2VyYCksIHRoaXMgdmVyaWZpZXMgdGhlIGJlYXJlciB0b2tlblxuICogaXRzZWxmLCBzbyBpdCBpcyBzYWZlIHRvIGNhbGwgQkVGT1JFIGByZXF1aXJlQXV0aGAgcnVucyDigJQgZS5nLiB0aGUgZ2xvYmFsIHJhdGVcbiAqIGxpbWl0ZXIncyBgc2tpcGAsIHdoaWNoIG11c3Qgbm90IHRydXN0IHRoZSBzcG9vZmFibGUgYHgtaW50ZXJuYWwtc2VydmljZWBcbiAqIGhlYWRlci4gTWlycm9ycyBgcmVxdWlyZUF1dGhgJ3MgdmVyaWZpY2F0aW9uIChhbGdvcml0aG0gcGlubmluZyArIG9wdGlvbmFsXG4gKiBpc3N1ZXIvYXVkaWVuY2UpIGFuZCByZXR1cm5zIGBmYWxzZWAgb24gYW55IG1pc3NpbmcvaW52YWxpZC9ub24tc2VydmljZSB0b2tlbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZlcmlmeVNlcnZpY2VQcmluY2lwYWwocmVxOiBSZXF1ZXN0KTogYm9vbGVhbiB7XG4gIGNvbnN0IHBhcnRzID0gcmVxLmhlYWRlcnMuYXV0aG9yaXphdGlvbj8uc3BsaXQoJyAnKTtcbiAgaWYgKCFwYXJ0cyB8fCBwYXJ0cy5sZW5ndGggIT09IDIgfHwgcGFydHNbMF0gIT09ICdCZWFyZXInKSByZXR1cm4gZmFsc2U7XG4gIHRyeSB7XG4gICAgY29uc3QgdmVyaWZ5T3B0aW9uczogand0LlZlcmlmeU9wdGlvbnMgPSB7IGFsZ29yaXRobXM6IFsocHJvY2Vzcy5lbnYuSldUX0FMR09SSVRITSB8fCAnSFMyNTYnKSBhcyBqd3QuQWxnb3JpdGhtXSB9O1xuICAgIGlmIChwcm9jZXNzLmVudi5KV1RfSVNTVUVSKSB2ZXJpZnlPcHRpb25zLmlzc3VlciA9IHByb2Nlc3MuZW52LkpXVF9JU1NVRVI7XG4gICAgaWYgKHByb2Nlc3MuZW52LkpXVF9BVURJRU5DRSkgdmVyaWZ5T3B0aW9ucy5hdWRpZW5jZSA9IHByb2Nlc3MuZW52LkpXVF9BVURJRU5DRTtcbiAgICBjb25zdCBkZWNvZGVkID0gdmVyaWZ5Snd0V2l0aFJvdGF0aW9uKHBhcnRzWzFdLCB2ZXJpZnlPcHRpb25zKTtcbiAgICBpZiAoZGVjb2RlZC50eXBlICE9PSAnYWNjZXNzJyB8fCB0eXBlb2YgZGVjb2RlZC5zdWIgIT09ICdzdHJpbmcnIHx8ICFkZWNvZGVkLnN1Yi5zdGFydHNXaXRoKCdzZXJ2aWNlOicpKSByZXR1cm4gZmFsc2U7XG4gICAgLy8gQSBkZW55bGlzdGVkIChraWxsZWQpIHNlcnZpY2UgbXVzdCBOT1QgYmUgdHJlYXRlZCBhcyBhIHRydXN0ZWQgcHJpbmNpcGFsIOKAlFxuICAgIC8vIG90aGVyd2lzZSBpdCBrZWVwcyB0aGUgcmF0ZS1saW1pdGVyIGV4ZW1wdGlvbiBldmVuIHRob3VnaCByZXF1aXJlQXV0aCByZWplY3RzXG4gICAgLy8gaXQgb24gcmVhbCByb3V0ZXMuIEZvbGQgdGhlIGtpbGwtc3dpdGNoIGludG8gdGhlIHByZS1hdXRoIGNoZWNrIHRvby5cbiAgICByZXR1cm4gIWlzU2VydmljZVRva2VuRGVuaWVkKGRlY29kZWQuc3ViKTtcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG4iXX0=
@@ -0,0 +1,7 @@
1
+ /**
2
+ * OpenAPI definitions for the "Ask" assistant service (api/ask), mounted at
3
+ * `/ask`. All routes are gated by the `ai_generation` feature and are READ /
4
+ * PROPOSE only — the agent never mutates; `propose_*` tool results are drafts the
5
+ * user confirms in the UI.
6
+ */
7
+ export declare function registerAskRoutes(): void;
@@ -0,0 +1,62 @@
1
+ // Copyright 2026 Pipeline Builder Contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ import { registry } from '../registry.js';
4
+ const tags = ['Ask'];
5
+ const auth = [{ bearerAuth: [] }];
6
+ /**
7
+ * OpenAPI definitions for the "Ask" assistant service (api/ask), mounted at
8
+ * `/ask`. All routes are gated by the `ai_generation` feature and are READ /
9
+ * PROPOSE only — the agent never mutates; `propose_*` tool results are drafts the
10
+ * user confirms in the UI.
11
+ */
12
+ export function registerAskRoutes() {
13
+ registry.registerPath({
14
+ method: 'get',
15
+ path: '/ask/providers',
16
+ summary: 'List configured AI providers',
17
+ description: 'The AI providers/models available to the Ask assistant (from server env — cloud keys and/or the OpenAI-compatible local endpoint).',
18
+ tags,
19
+ security: auth,
20
+ responses: { 200: { description: 'Configured providers' }, 403: { description: 'ai_generation feature required' } },
21
+ });
22
+ registry.registerPath({
23
+ method: 'post',
24
+ path: '/ask',
25
+ summary: 'Grounded how-to answer (non-streaming)',
26
+ description: 'Answer a platform how-to question grounded in the docs corpus. Reserves one aiCalls quota slot.',
27
+ tags,
28
+ security: auth,
29
+ responses: {
30
+ 200: { description: 'Answer with grounded sources' },
31
+ 403: { description: 'ai_generation feature required' },
32
+ 429: { description: 'aiCalls quota exceeded or rate limited' },
33
+ },
34
+ });
35
+ registry.registerPath({
36
+ method: 'post',
37
+ path: '/ask/stream',
38
+ summary: 'Grounded how-to answer (SSE stream)',
39
+ description: 'Same as POST /ask but streams the grounded sources then answer tokens as Server-Sent Events.',
40
+ tags,
41
+ security: auth,
42
+ responses: {
43
+ 200: { description: 'text/event-stream of sources + answer tokens' },
44
+ 403: { description: 'ai_generation feature required' },
45
+ 429: { description: 'aiCalls quota exceeded or rate limited' },
46
+ },
47
+ });
48
+ registry.registerPath({
49
+ method: 'post',
50
+ path: '/ask/agent/stream',
51
+ summary: 'Tool-calling Ask agent (SSE stream)',
52
+ description: 'Runs the tool-calling assistant loop and streams reasoning tokens, tool-call events, and reviewable `propose_*` drafts (pipeline/plugin/template) as SSE. Read-only: proposals are confirmed separately in the UI.',
53
+ tags,
54
+ security: auth,
55
+ responses: {
56
+ 200: { description: 'text/event-stream of tokens, tool-calls, and proposal drafts' },
57
+ 403: { description: 'ai_generation feature required' },
58
+ 429: { description: 'aiCalls quota exceeded or rate limited' },
59
+ },
60
+ });
61
+ }
62
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXNrLXJvdXRlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9vcGVuYXBpL3JvdXRlcy9hc2stcm91dGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFFdEMsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRTFDLE1BQU0sSUFBSSxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDckIsTUFBTSxJQUFJLEdBQUcsQ0FBQyxFQUFFLFVBQVUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0FBRWxDOzs7OztHQUtHO0FBQ0gsTUFBTSxVQUFVLGlCQUFpQjtJQUMvQixRQUFRLENBQUMsWUFBWSxDQUFDO1FBQ3BCLE1BQU0sRUFBRSxLQUFLO1FBQ2IsSUFBSSxFQUFFLGdCQUFnQjtRQUN0QixPQUFPLEVBQUUsOEJBQThCO1FBQ3ZDLFdBQVcsRUFBRSxvSUFBb0k7UUFDakosSUFBSTtRQUNKLFFBQVEsRUFBRSxJQUFJO1FBQ2QsU0FBUyxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsV0FBVyxFQUFFLHNCQUFzQixFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsV0FBVyxFQUFFLGdDQUFnQyxFQUFFLEVBQUU7S0FDcEgsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLFlBQVksQ0FBQztRQUNwQixNQUFNLEVBQUUsTUFBTTtRQUNkLElBQUksRUFBRSxNQUFNO1FBQ1osT0FBTyxFQUFFLHdDQUF3QztRQUNqRCxXQUFXLEVBQUUsaUdBQWlHO1FBQzlHLElBQUk7UUFDSixRQUFRLEVBQUUsSUFBSTtRQUNkLFNBQVMsRUFBRTtZQUNULEdBQUcsRUFBRSxFQUFFLFdBQVcsRUFBRSw4QkFBOEIsRUFBRTtZQUNwRCxHQUFHLEVBQUUsRUFBRSxXQUFXLEVBQUUsZ0NBQWdDLEVBQUU7WUFDdEQsR0FBRyxFQUFFLEVBQUUsV0FBVyxFQUFFLHdDQUF3QyxFQUFFO1NBQy9EO0tBQ0YsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLFlBQVksQ0FBQztRQUNwQixNQUFNLEVBQUUsTUFBTTtRQUNkLElBQUksRUFBRSxhQUFhO1FBQ25CLE9BQU8sRUFBRSxxQ0FBcUM7UUFDOUMsV0FBVyxFQUFFLDhGQUE4RjtRQUMzRyxJQUFJO1FBQ0osUUFBUSxFQUFFLElBQUk7UUFDZCxTQUFTLEVBQUU7WUFDVCxHQUFHLEVBQUUsRUFBRSxXQUFXLEVBQUUsOENBQThDLEVBQUU7WUFDcEUsR0FBRyxFQUFFLEVBQUUsV0FBVyxFQUFFLGdDQUFnQyxFQUFFO1lBQ3RELEdBQUcsRUFBRSxFQUFFLFdBQVcsRUFBRSx3Q0FBd0MsRUFBRTtTQUMvRDtLQUNGLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxZQUFZLENBQUM7UUFDcEIsTUFBTSxFQUFFLE1BQU07UUFDZCxJQUFJLEVBQUUsbUJBQW1CO1FBQ3pCLE9BQU8sRUFBRSxxQ0FBcUM7UUFDOUMsV0FBVyxFQUFFLG9OQUFvTjtRQUNqTyxJQUFJO1FBQ0osUUFBUSxFQUFFLElBQUk7UUFDZCxTQUFTLEVBQUU7WUFDVCxHQUFHLEVBQUUsRUFBRSxXQUFXLEVBQUUsOERBQThELEVBQUU7WUFDcEYsR0FBRyxFQUFFLEVBQUUsV0FBVyxFQUFFLGdDQUFnQyxFQUFFO1lBQ3RELEdBQUcsRUFBRSxFQUFFLFdBQVcsRUFBRSx3Q0FBd0MsRUFBRTtTQUMvRDtLQUNGLENBQUMsQ0FBQztBQUNMLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuaW1wb3J0IHsgcmVnaXN0cnkgfSBmcm9tICcuLi9yZWdpc3RyeS5qcyc7XG5cbmNvbnN0IHRhZ3MgPSBbJ0FzayddO1xuY29uc3QgYXV0aCA9IFt7IGJlYXJlckF1dGg6IFtdIH1dO1xuXG4vKipcbiAqIE9wZW5BUEkgZGVmaW5pdGlvbnMgZm9yIHRoZSBcIkFza1wiIGFzc2lzdGFudCBzZXJ2aWNlIChhcGkvYXNrKSwgbW91bnRlZCBhdFxuICogYC9hc2tgLiBBbGwgcm91dGVzIGFyZSBnYXRlZCBieSB0aGUgYGFpX2dlbmVyYXRpb25gIGZlYXR1cmUgYW5kIGFyZSBSRUFEIC9cbiAqIFBST1BPU0Ugb25seSDigJQgdGhlIGFnZW50IG5ldmVyIG11dGF0ZXM7IGBwcm9wb3NlXypgIHRvb2wgcmVzdWx0cyBhcmUgZHJhZnRzIHRoZVxuICogdXNlciBjb25maXJtcyBpbiB0aGUgVUkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWdpc3RlckFza1JvdXRlcygpOiB2b2lkIHtcbiAgcmVnaXN0cnkucmVnaXN0ZXJQYXRoKHtcbiAgICBtZXRob2Q6ICdnZXQnLFxuICAgIHBhdGg6ICcvYXNrL3Byb3ZpZGVycycsXG4gICAgc3VtbWFyeTogJ0xpc3QgY29uZmlndXJlZCBBSSBwcm92aWRlcnMnLFxuICAgIGRlc2NyaXB0aW9uOiAnVGhlIEFJIHByb3ZpZGVycy9tb2RlbHMgYXZhaWxhYmxlIHRvIHRoZSBBc2sgYXNzaXN0YW50IChmcm9tIHNlcnZlciBlbnYg4oCUIGNsb3VkIGtleXMgYW5kL29yIHRoZSBPcGVuQUktY29tcGF0aWJsZSBsb2NhbCBlbmRwb2ludCkuJyxcbiAgICB0YWdzLFxuICAgIHNlY3VyaXR5OiBhdXRoLFxuICAgIHJlc3BvbnNlczogeyAyMDA6IHsgZGVzY3JpcHRpb246ICdDb25maWd1cmVkIHByb3ZpZGVycycgfSwgNDAzOiB7IGRlc2NyaXB0aW9uOiAnYWlfZ2VuZXJhdGlvbiBmZWF0dXJlIHJlcXVpcmVkJyB9IH0sXG4gIH0pO1xuXG4gIHJlZ2lzdHJ5LnJlZ2lzdGVyUGF0aCh7XG4gICAgbWV0aG9kOiAncG9zdCcsXG4gICAgcGF0aDogJy9hc2snLFxuICAgIHN1bW1hcnk6ICdHcm91bmRlZCBob3ctdG8gYW5zd2VyIChub24tc3RyZWFtaW5nKScsXG4gICAgZGVzY3JpcHRpb246ICdBbnN3ZXIgYSBwbGF0Zm9ybSBob3ctdG8gcXVlc3Rpb24gZ3JvdW5kZWQgaW4gdGhlIGRvY3MgY29ycHVzLiBSZXNlcnZlcyBvbmUgYWlDYWxscyBxdW90YSBzbG90LicsXG4gICAgdGFncyxcbiAgICBzZWN1cml0eTogYXV0aCxcbiAgICByZXNwb25zZXM6IHtcbiAgICAgIDIwMDogeyBkZXNjcmlwdGlvbjogJ0Fuc3dlciB3aXRoIGdyb3VuZGVkIHNvdXJjZXMnIH0sXG4gICAgICA0MDM6IHsgZGVzY3JpcHRpb246ICdhaV9nZW5lcmF0aW9uIGZlYXR1cmUgcmVxdWlyZWQnIH0sXG4gICAgICA0Mjk6IHsgZGVzY3JpcHRpb246ICdhaUNhbGxzIHF1b3RhIGV4Y2VlZGVkIG9yIHJhdGUgbGltaXRlZCcgfSxcbiAgICB9LFxuICB9KTtcblxuICByZWdpc3RyeS5yZWdpc3RlclBhdGgoe1xuICAgIG1ldGhvZDogJ3Bvc3QnLFxuICAgIHBhdGg6ICcvYXNrL3N0cmVhbScsXG4gICAgc3VtbWFyeTogJ0dyb3VuZGVkIGhvdy10byBhbnN3ZXIgKFNTRSBzdHJlYW0pJyxcbiAgICBkZXNjcmlwdGlvbjogJ1NhbWUgYXMgUE9TVCAvYXNrIGJ1dCBzdHJlYW1zIHRoZSBncm91bmRlZCBzb3VyY2VzIHRoZW4gYW5zd2VyIHRva2VucyBhcyBTZXJ2ZXItU2VudCBFdmVudHMuJyxcbiAgICB0YWdzLFxuICAgIHNlY3VyaXR5OiBhdXRoLFxuICAgIHJlc3BvbnNlczoge1xuICAgICAgMjAwOiB7IGRlc2NyaXB0aW9uOiAndGV4dC9ldmVudC1zdHJlYW0gb2Ygc291cmNlcyArIGFuc3dlciB0b2tlbnMnIH0sXG4gICAgICA0MDM6IHsgZGVzY3JpcHRpb246ICdhaV9nZW5lcmF0aW9uIGZlYXR1cmUgcmVxdWlyZWQnIH0sXG4gICAgICA0Mjk6IHsgZGVzY3JpcHRpb246ICdhaUNhbGxzIHF1b3RhIGV4Y2VlZGVkIG9yIHJhdGUgbGltaXRlZCcgfSxcbiAgICB9LFxuICB9KTtcblxuICByZWdpc3RyeS5yZWdpc3RlclBhdGgoe1xuICAgIG1ldGhvZDogJ3Bvc3QnLFxuICAgIHBhdGg6ICcvYXNrL2FnZW50L3N0cmVhbScsXG4gICAgc3VtbWFyeTogJ1Rvb2wtY2FsbGluZyBBc2sgYWdlbnQgKFNTRSBzdHJlYW0pJyxcbiAgICBkZXNjcmlwdGlvbjogJ1J1bnMgdGhlIHRvb2wtY2FsbGluZyBhc3Npc3RhbnQgbG9vcCBhbmQgc3RyZWFtcyByZWFzb25pbmcgdG9rZW5zLCB0b29sLWNhbGwgZXZlbnRzLCBhbmQgcmV2aWV3YWJsZSBgcHJvcG9zZV8qYCBkcmFmdHMgKHBpcGVsaW5lL3BsdWdpbi90ZW1wbGF0ZSkgYXMgU1NFLiBSZWFkLW9ubHk6IHByb3Bvc2FscyBhcmUgY29uZmlybWVkIHNlcGFyYXRlbHkgaW4gdGhlIFVJLicsXG4gICAgdGFncyxcbiAgICBzZWN1cml0eTogYXV0aCxcbiAgICByZXNwb25zZXM6IHtcbiAgICAgIDIwMDogeyBkZXNjcmlwdGlvbjogJ3RleHQvZXZlbnQtc3RyZWFtIG9mIHRva2VucywgdG9vbC1jYWxscywgYW5kIHByb3Bvc2FsIGRyYWZ0cycgfSxcbiAgICAgIDQwMzogeyBkZXNjcmlwdGlvbjogJ2FpX2dlbmVyYXRpb24gZmVhdHVyZSByZXF1aXJlZCcgfSxcbiAgICAgIDQyOTogeyBkZXNjcmlwdGlvbjogJ2FpQ2FsbHMgcXVvdGEgZXhjZWVkZWQgb3IgcmF0ZSBsaW1pdGVkJyB9LFxuICAgIH0sXG4gIH0pO1xufVxuIl19
@@ -0,0 +1,7 @@
1
+ /**
2
+ * OpenAPI definitions for the image-registry service (api/image-registry): the
3
+ * Docker-registry token endpoint (`/token`), the org-scoped image API
4
+ * (`/api/images`), and the admin API (`/api/admin`). Image read/write is gated by
5
+ * the `registry:read` / `registry:write` permissions.
6
+ */
7
+ export declare function registerImageRegistryRoutes(): void;