@pipeline-builder/api-core 4.1.2 → 4.1.4

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 (81) hide show
  1. package/README.md +3 -3
  2. package/lib/errors/app-errors.d.ts +0 -4
  3. package/lib/errors/app-errors.js +1 -8
  4. package/lib/helpers/restore-helpers.d.ts +3 -3
  5. package/lib/helpers/restore-helpers.js +4 -4
  6. package/lib/helpers/sse-helpers.d.ts +8 -1
  7. package/lib/helpers/sse-helpers.js +11 -3
  8. package/lib/middleware/auth.d.ts +174 -43
  9. package/lib/middleware/auth.js +384 -179
  10. package/lib/middleware/index.d.ts +1 -0
  11. package/lib/middleware/index.js +2 -1
  12. package/lib/middleware/route-table.d.ts +104 -0
  13. package/lib/middleware/route-table.js +230 -0
  14. package/lib/middleware/step-up.d.ts +48 -16
  15. package/lib/middleware/step-up.js +74 -36
  16. package/lib/services/api-key-exchange.d.ts +25 -0
  17. package/lib/services/api-key-exchange.js +219 -0
  18. package/lib/services/audit-spool.d.ts +2 -3
  19. package/lib/services/audit-spool.js +3 -4
  20. package/lib/services/cache-service.d.ts +65 -21
  21. package/lib/services/cache-service.js +173 -78
  22. package/lib/services/compliance-event-subscriber.d.ts +5 -4
  23. package/lib/services/compliance-event-subscriber.js +8 -6
  24. package/lib/services/durable-event-bus.d.ts +22 -39
  25. package/lib/services/durable-event-bus.js +109 -47
  26. package/lib/services/env-redis.d.ts +114 -35
  27. package/lib/services/env-redis.js +215 -73
  28. package/lib/services/http-client.d.ts +10 -15
  29. package/lib/services/http-client.js +32 -27
  30. package/lib/services/index.d.ts +3 -0
  31. package/lib/services/index.js +4 -1
  32. package/lib/services/jwks-cache.d.ts +102 -0
  33. package/lib/services/jwks-cache.js +222 -0
  34. package/lib/services/leader-lock.d.ts +6 -3
  35. package/lib/services/leader-lock.js +20 -5
  36. package/lib/services/quota.d.ts +44 -10
  37. package/lib/services/quota.js +95 -51
  38. package/lib/services/remote-audit-client.d.ts +1 -1
  39. package/lib/services/remote-audit-client.js +32 -1
  40. package/lib/services/scheduler.d.ts +2 -3
  41. package/lib/services/scheduler.js +2 -2
  42. package/lib/services/service-boot.d.ts +4 -2
  43. package/lib/services/service-boot.js +7 -3
  44. package/lib/services/service-keys.d.ts +83 -0
  45. package/lib/services/service-keys.js +354 -0
  46. package/lib/services/sse-ticket-store.d.ts +55 -22
  47. package/lib/services/sse-ticket-store.js +122 -79
  48. package/lib/services/token-revocation.d.ts +1 -1
  49. package/lib/services/token-revocation.js +31 -19
  50. package/lib/testing/route-coverage.d.ts +64 -0
  51. package/lib/testing/route-coverage.js +183 -0
  52. package/lib/testing/service-tokens.d.ts +66 -0
  53. package/lib/testing/service-tokens.js +137 -0
  54. package/lib/testing/tier-mock.d.ts +2 -2
  55. package/lib/testing/tier-mock.js +3 -3
  56. package/lib/testing/user-tokens.d.ts +75 -0
  57. package/lib/testing/user-tokens.js +115 -0
  58. package/lib/types/catalog-metadata.d.ts +0 -2
  59. package/lib/types/catalog-metadata.js +1 -3
  60. package/lib/types/common.d.ts +103 -4
  61. package/lib/types/common.js +11 -1
  62. package/lib/types/error-codes.d.ts +15 -0
  63. package/lib/types/error-codes.js +22 -1
  64. package/lib/types/permissions.d.ts +35 -1
  65. package/lib/types/permissions.js +70 -2
  66. package/lib/utils/api-key.d.ts +34 -0
  67. package/lib/utils/api-key.js +75 -0
  68. package/lib/utils/env.d.ts +0 -2
  69. package/lib/utils/env.js +1 -6
  70. package/lib/utils/index.d.ts +3 -0
  71. package/lib/utils/index.js +4 -1
  72. package/lib/utils/jwk.d.ts +98 -0
  73. package/lib/utils/jwk.js +139 -0
  74. package/lib/utils/logger.d.ts +4 -1
  75. package/lib/utils/logger.js +1 -22
  76. package/lib/utils/secret-encryption.d.ts +7 -2
  77. package/lib/utils/secret-encryption.js +47 -4
  78. package/lib/utils/secret-rotation.d.ts +17 -0
  79. package/lib/utils/secret-rotation.js +54 -0
  80. package/lib/validation/common-schemas.js +5 -4
  81. package/package.json +20 -1
@@ -1,11 +1,35 @@
1
1
  // Copyright 2026 Pipeline Builder Contributors
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
  /**
4
- * Deep-clone a value so the in-memory backend hands back an INDEPENDENT copy on
5
- * every read — matching the Redis backend, which returns a fresh `JSON.parse`
6
- * clone each time. Without this the in-memory cache returns the same stored
7
- * object reference, so a consumer mutating a "cached" object silently corrupts
8
- * the shared cache (a footgun that only bites under the memory backend).
4
+ * Lightweight caching service with TTL support.
5
+ *
6
+ * Storage is a per-process true-LRU Map (no external dependencies).
7
+ *
8
+ * Cross-replica invalidation: every service runs several
9
+ * replicas (HPA), each with its OWN in-memory cache. An invalidation performed on
10
+ * one pod (`del` / `invalidatePattern` / `clear`) is broadcast over Redis pub/sub
11
+ * ({@link CacheInvalidationBus}, wired from the ambient Redis env by default) and
12
+ * applied by every other pod, so a write on pod A can't leave pod B serving the
13
+ * stale entry until its TTL lapses. A pod whose subscriber (re)connects flushes
14
+ * its local cache — it may have missed invalidations while disconnected — and a
15
+ * `getOrSet` whose factory raced an invalidation does not cache its result.
16
+ *
17
+ * Design:
18
+ * - All operations are fail-safe: cache misses/errors return null, never throw
19
+ * - Reads deep-clone, so every caller gets an independent copy (mutating a
20
+ * result is always safe)
21
+ * - `getOrSet` is single-flight: concurrent misses share one factory() call
22
+ * - Key namespace prefixing to avoid collisions between services
23
+ */
24
+ import { randomUUID } from 'crypto';
25
+ import { createEnvRedisClient } from './env-redis.js';
26
+ import { createLogger } from '../utils/logger.js';
27
+ import { emitCounter } from '../utils/metric-emitter.js';
28
+ const logger = createLogger('cache-service');
29
+ /**
30
+ * Deep-clone a value so the cache hands back an INDEPENDENT copy on every read.
31
+ * Without this it returns the same stored object reference, so a consumer
32
+ * mutating a "cached" object silently corrupts the shared cache.
9
33
  *
10
34
  * Primitives are returned as-is. Prefers the structured-clone algorithm; falls
11
35
  * back to a JSON round-trip on older runtimes or exotic values.
@@ -20,6 +44,87 @@ function cloneValue(value) {
20
44
  return JSON.parse(JSON.stringify(value));
21
45
  }
22
46
  }
47
+ const CACHE_INVALIDATION_CHANNEL = 'cache:invalidate';
48
+ /**
49
+ * Redis pub/sub invalidation bus. PUBLISH on the given client; SUBSCRIBE on a
50
+ * `duplicate()` (a subscribed ioredis connection can't run other commands).
51
+ *
52
+ * The SUBSCRIBE is issued on every `ready` (initial connect AND each reconnect)
53
+ * rather than once at construction: the env client runs without an offline
54
+ * queue, so a subscribe issued before the connection is up is rejected and would
55
+ * never be retried. Each `ready` also triggers `onResync` so every cache flushes
56
+ * whatever it may have missed while disconnected.
57
+ */
58
+ export function createRedisCacheInvalidationBus(publisher) {
59
+ const subscriber = publisher.duplicate();
60
+ const messageHandlers = [];
61
+ const resyncHandlers = [];
62
+ const resync = () => {
63
+ for (const h of resyncHandlers) {
64
+ try {
65
+ h();
66
+ }
67
+ catch { /* isolated */ }
68
+ }
69
+ };
70
+ const doSubscribe = () => {
71
+ void Promise.resolve(subscriber.subscribe(CACHE_INVALIDATION_CHANNEL))
72
+ .then(() => resync())
73
+ .catch((err) => {
74
+ emitCounter('cache_invalidation_subscribe_failed_total', {});
75
+ logger.warn('Cache invalidation subscribe failed; will retry on next reconnect', {
76
+ error: err instanceof Error ? err.message : String(err),
77
+ });
78
+ });
79
+ };
80
+ subscriber.on('message', (channel, raw) => {
81
+ if (channel !== CACHE_INVALIDATION_CHANNEL)
82
+ return;
83
+ let msg;
84
+ try {
85
+ msg = JSON.parse(raw);
86
+ }
87
+ catch {
88
+ return;
89
+ }
90
+ for (const h of messageHandlers) {
91
+ try {
92
+ h(msg);
93
+ }
94
+ catch { /* one cache can't break the others */ }
95
+ }
96
+ });
97
+ subscriber.on('ready', doSubscribe);
98
+ subscriber.on('error', (e) => logger.warn('Cache invalidation subscriber error', { error: e instanceof Error ? e.message : String(e) }));
99
+ if (subscriber.status === 'ready')
100
+ doSubscribe();
101
+ return {
102
+ publish(msg) {
103
+ void Promise.resolve()
104
+ .then(() => publisher.publish(CACHE_INVALIDATION_CHANNEL, JSON.stringify(msg)))
105
+ .catch((err) => {
106
+ emitCounter('cache_invalidation_publish_failed_total', { prefix: msg.prefix });
107
+ logger.warn('Cache invalidation publish failed (other replicas keep the entry until TTL)', {
108
+ prefix: msg.prefix, op: msg.op, error: err instanceof Error ? err.message : String(err),
109
+ });
110
+ });
111
+ },
112
+ subscribe(onMessage, onResync) {
113
+ messageHandlers.push(onMessage);
114
+ resyncHandlers.push(onResync);
115
+ },
116
+ };
117
+ }
118
+ // undefined = not yet attempted; null = attempted, Redis not configured.
119
+ let envInvalidationBus;
120
+ /** Process-wide invalidation bus from the ambient Redis env (null without Redis). */
121
+ function getEnvCacheInvalidationBus() {
122
+ if (envInvalidationBus === undefined) {
123
+ const client = createEnvRedisClient('cache-invalidation');
124
+ envInvalidationBus = client ? createRedisCacheInvalidationBus(client) : null;
125
+ }
126
+ return envInvalidationBus;
127
+ }
23
128
  /**
24
129
  * Cache service with get/set/del operations and automatic TTL expiry.
25
130
  *
@@ -51,14 +156,55 @@ export class CacheService {
51
156
  prefix;
52
157
  defaultTtlMs;
53
158
  maxEntries;
54
- redis;
159
+ bus;
160
+ instanceId = randomUUID();
161
+ /**
162
+ * Bumped on EVERY invalidation (local or remote). `getOrSet` only caches a
163
+ * factory result if no invalidation happened while the factory ran — otherwise
164
+ * it could re-cache a value read before the write that invalidated it.
165
+ */
166
+ generation = 0;
55
167
  /** Cache metrics — tracks hits, misses, and invalidations. */
56
168
  metrics = { hits: 0, misses: 0, sets: 0, invalidations: 0 };
57
169
  constructor(config) {
58
170
  this.prefix = config.prefix;
59
171
  this.defaultTtlMs = config.defaultTtlSeconds * 1000;
60
172
  this.maxEntries = config.maxEntries ?? 1000;
61
- this.redis = config.redis;
173
+ this.bus = config.invalidationBus === undefined ? getEnvCacheInvalidationBus() : config.invalidationBus;
174
+ this.bus?.subscribe((msg) => {
175
+ if (msg.origin === this.instanceId || msg.prefix !== this.prefix)
176
+ return;
177
+ this.applyLocalInvalidation(msg.op, msg.key);
178
+ }, () => this.applyLocalInvalidation('clear'));
179
+ }
180
+ /** Broadcast an invalidation to the other replicas. */
181
+ broadcast(op, key) {
182
+ this.bus?.publish({ origin: this.instanceId, prefix: this.prefix, op, ...(key !== undefined && { key }) });
183
+ }
184
+ /** Apply an invalidation to THIS process's in-memory entries. Returns the count removed. */
185
+ applyLocalInvalidation(op, key) {
186
+ this.generation++;
187
+ if (op === 'clear') {
188
+ const n = this.memory.size;
189
+ this.memory.clear();
190
+ return n;
191
+ }
192
+ if (op === 'del') {
193
+ return this.memory.delete(this.fullKey(key ?? '')) ? 1 : 0;
194
+ }
195
+ // Glob pattern. Escape regex metacharacters first so a literal `.`/`(`/`[`
196
+ // in a key prefix (e.g. `org:v1.2:*`) can't over-match or throw (a throw
197
+ // here would leave entries stale); only `*` is treated as a wildcard.
198
+ const fp = this.fullKey(key ?? '');
199
+ const regex = new RegExp('^' + fp.replace(/[.*+?^${}()|[\]\\]/g, '\\$&').replace(/\\\*/g, '.*') + '$');
200
+ let deleted = 0;
201
+ for (const k of this.memory.keys()) {
202
+ if (regex.test(k)) {
203
+ this.memory.delete(k);
204
+ deleted++;
205
+ }
206
+ }
207
+ return deleted;
62
208
  }
63
209
  fullKey(key) {
64
210
  return `${this.prefix}${key}`;
@@ -67,23 +213,11 @@ export class CacheService {
67
213
  * Get a cached value. Returns null on miss or error.
68
214
  *
69
215
  * The returned value is an INDEPENDENT deep copy — mutating it never affects
70
- * the cached entry (the in-memory backend clones on read for parity with
71
- * Redis, which returns a fresh JSON clone). Callers may still treat results as
72
- * immutable, but doing so is no longer load-bearing for cache integrity.
216
+ * the cached entry.
73
217
  */
74
218
  async get(key) {
75
219
  const fk = this.fullKey(key);
76
220
  try {
77
- if (this.redis) {
78
- const raw = await this.redis.get(fk);
79
- if (!raw) {
80
- this.metrics.misses++;
81
- return null;
82
- }
83
- this.metrics.hits++;
84
- return JSON.parse(raw);
85
- }
86
- // In-memory
87
221
  const entry = this.memory.get(fk);
88
222
  if (!entry) {
89
223
  this.metrics.misses++;
@@ -112,7 +246,7 @@ export class CacheService {
112
246
  * Set a cached value with optional TTL override.
113
247
  *
114
248
  * @param key - Cache key (prefix is added automatically)
115
- * @param value - Value to cache (must be JSON-serializable for Redis)
249
+ * @param value - Value to cache
116
250
  * @param ttlSeconds - TTL override (uses default if not provided)
117
251
  */
118
252
  async set(key, value, ttlSeconds) {
@@ -120,11 +254,7 @@ export class CacheService {
120
254
  const ttl = ttlSeconds ?? this.defaultTtlMs / 1000;
121
255
  try {
122
256
  this.metrics.sets++;
123
- if (this.redis) {
124
- await this.redis.set(fk, JSON.stringify(value), 'EX', ttl);
125
- return;
126
- }
127
- // In-memory — a write counts as a use, so drop any existing entry first
257
+ // A write counts as a use, so drop any existing entry first
128
258
  // and re-insert below as the newest (Map preserves insertion order). This
129
259
  // keeps the Map ordered oldest-USED → newest-USED so the eviction below is
130
260
  // true LRU, and avoids evicting a victim when merely updating a key.
@@ -147,13 +277,9 @@ export class CacheService {
147
277
  * Delete a cached value.
148
278
  */
149
279
  async del(key) {
150
- const fk = this.fullKey(key);
151
280
  try {
152
- if (this.redis) {
153
- await this.redis.del(fk);
154
- return;
155
- }
156
- this.memory.delete(fk);
281
+ this.applyLocalInvalidation('del', key);
282
+ this.broadcast('del', key);
157
283
  }
158
284
  catch {
159
285
  // Cache delete failure is non-fatal
@@ -161,33 +287,13 @@ export class CacheService {
161
287
  }
162
288
  /**
163
289
  * Invalidate all keys matching a pattern (e.g., 'org123:*').
164
- * Uses SCAN for Redis (non-blocking) with KEYS fallback, or regex for in-memory.
290
+ * Only `*` is a wildcard.
165
291
  */
166
292
  async invalidatePattern(pattern) {
167
- const fp = this.fullKey(pattern);
168
293
  try {
169
- if (this.redis) {
170
- const keys = this.redis.scanStream
171
- ? await this.scanKeys(fp)
172
- : await this.redis.keys(fp);
173
- if (keys.length > 0) {
174
- await this.redis.del(...keys);
175
- this.metrics.invalidations += keys.length;
176
- }
177
- return keys.length;
178
- }
179
- // In-memory — match glob-style pattern. Escape regex metacharacters first
180
- // so a literal `.`/`(`/`[` in a key prefix (e.g. `org:v1.2:*`) can't
181
- // over-match or throw (a throw here is swallowed → nothing invalidated →
182
- // stale reads); only `*` is treated as a wildcard.
183
- const regex = new RegExp('^' + fp.replace(/[.*+?^${}()|[\]\\]/g, '\\$&').replace(/\\\*/g, '.*') + '$');
184
- let deleted = 0;
185
- for (const key of this.memory.keys()) {
186
- if (regex.test(key)) {
187
- this.memory.delete(key);
188
- deleted++;
189
- }
190
- }
294
+ // Apply locally, then fan out to the other replicas.
295
+ const deleted = this.applyLocalInvalidation('pattern', pattern);
296
+ this.broadcast('pattern', pattern);
191
297
  this.metrics.invalidations += deleted;
192
298
  return deleted;
193
299
  }
@@ -195,16 +301,6 @@ export class CacheService {
195
301
  return 0;
196
302
  }
197
303
  }
198
- /** Collect keys via Redis SCAN (non-blocking alternative to KEYS). */
199
- scanKeys(pattern) {
200
- return new Promise((resolve, reject) => {
201
- const stream = this.redis.scanStream({ match: pattern, count: 100 });
202
- const keys = [];
203
- stream.on('data', (batch) => keys.push(...batch));
204
- stream.once('end', () => resolve(keys));
205
- stream.once('error', reject);
206
- });
207
- }
208
304
  /**
209
305
  * Get or compute: returns cached value if available, otherwise calls the
210
306
  * factory function, caches the result, and returns it.
@@ -230,13 +326,17 @@ export class CacheService {
230
326
  // Cloning inside the flight instead would hand one shared clone to all N
231
327
  // coalesced callers, so one caller mutating its "independent" result would
232
328
  // corrupt what the others read — the exact footgun get()'s clone-on-read
233
- // prevents. (Redis backend is unaffected: set serializes, get JSON.parses.)
329
+ // prevents.
234
330
  const existing = this.inflight.get(fk);
235
331
  if (existing)
236
332
  return cloneValue(await existing);
333
+ const generationAtStart = this.generation;
237
334
  const flight = (async () => {
238
335
  const value = await factory();
239
- await this.set(key, value, ttlSeconds);
336
+ // An invalidation (here or on another replica) landed while the factory
337
+ // ran: its read may predate that write, so don't cache it.
338
+ if (this.generation === generationAtStart)
339
+ await this.set(key, value, ttlSeconds);
240
340
  return value;
241
341
  })();
242
342
  this.inflight.set(fk, flight);
@@ -251,12 +351,8 @@ export class CacheService {
251
351
  * Clear all entries (useful for testing).
252
352
  */
253
353
  async clear() {
254
- if (this.redis) {
255
- await this.invalidatePattern('*');
256
- }
257
- else {
258
- this.memory.clear();
259
- }
354
+ this.applyLocalInvalidation('clear');
355
+ this.broadcast('clear');
260
356
  }
261
357
  /** Current in-memory cache size (for diagnostics). */
262
358
  get size() {
@@ -268,9 +364,8 @@ export class CacheService {
268
364
  *
269
365
  * @param prefix - Namespace prefix (e.g., 'compliance:', 'plugin:')
270
366
  * @param defaultTtlSeconds - Default TTL in seconds (default 300 = 5 min)
271
- * @param redis - Optional Redis client for cross-process caching
272
367
  */
273
- export function createCacheService(prefix, defaultTtlSeconds = 300, redis) {
274
- return new CacheService({ prefix, defaultTtlSeconds, redis });
368
+ export function createCacheService(prefix, defaultTtlSeconds = 300) {
369
+ return new CacheService({ prefix, defaultTtlSeconds });
275
370
  }
276
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FjaGUtc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zZXJ2aWNlcy9jYWNoZS1zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUEwQnRDOzs7Ozs7Ozs7R0FTRztBQUNILFNBQVMsVUFBVSxDQUFJLEtBQVE7SUFDN0IsSUFBSSxLQUFLLEtBQUssSUFBSSxJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVE7UUFBRSxPQUFPLEtBQUssQ0FBQztJQUM5RCxJQUFJLENBQUM7UUFDSCxPQUFPLGVBQWUsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNoQyxDQUFDO0lBQUMsTUFBTSxDQUFDO1FBQ1AsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQU0sQ0FBQztJQUNoRCxDQUFDO0FBQ0gsQ0FBQztBQTBCRDs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW1CRztBQUNILE1BQU0sT0FBTyxZQUFZO0lBQ2YsTUFBTSxHQUFHLElBQUksR0FBRyxFQUErQixDQUFDO0lBQ3hEOzs7O09BSUc7SUFDSyxRQUFRLEdBQUcsSUFBSSxHQUFHLEVBQTRCLENBQUM7SUFDdEMsTUFBTSxDQUFTO0lBQ2YsWUFBWSxDQUFTO0lBQ3JCLFVBQVUsQ0FBUztJQUNuQixLQUFLLENBQW9CO0lBRTFDLDhEQUE4RDtJQUNyRCxPQUFPLEdBQUcsRUFBRSxJQUFJLEVBQUUsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRSxhQUFhLEVBQUUsQ0FBQyxFQUFFLENBQUM7SUFFckUsWUFBWSxNQUFtQjtRQUM3QixJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUM7UUFDNUIsSUFBSSxDQUFDLFlBQVksR0FBRyxNQUFNLENBQUMsaUJBQWlCLEdBQUcsSUFBSSxDQUFDO1FBQ3BELElBQUksQ0FBQyxVQUFVLEdB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RXhCLE9BQU8sSUFBSSxZQUFZLENBQUMsRUFBRSxNQUFNLEVBQUUsaUJBQWlCLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztBQUNoRSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbi8qKlxuICogTGlnaHR3ZWlnaHQgY2FjaGluZyBzZXJ2aWNlIHdpdGggVFRMIHN1cHBvcnQuXG4gKlxuICogVHdvIGltcGxlbWVudGF0aW9uczpcbiAqIC0gSW4tbWVtb3J5IChkZWZhdWx0KTogdHJ1ZS1MUlUgTWFwIGNhY2hlLCBubyBleHRlcm5hbCBkZXBlbmRlbmNpZXNcbiAqIC0gUmVkaXM6IFdoZW4gYSBSZWRpcyBjbGllbnQgaXMgcHJvdmlkZWQsIHVzZXMgUmVkaXMgZm9yIGNyb3NzLXByb2Nlc3MgY2FjaGluZ1xuICpcbiAqIERlc2lnbjpcbiAqIC0gQWxsIG9wZXJhdGlvbnMgYXJlIGZhaWwtc2FmZTogY2FjaGUgbWlzc2VzL2Vycm9ycyByZXR1cm4gbnVsbCwgbmV2ZXIgdGhyb3dcbiAqIC0gSlNPTiBzZXJpYWxpemF0aW9uIGZvciBSZWRpczsgdGhlIGluLW1lbW9yeSBiYWNrZW5kIGRlZXAtY2xvbmVzIG9uIHJlYWQgc29cbiAqICAgYm90aCBiYWNrZW5kcyByZXR1cm4gYW4gaW5kZXBlbmRlbnQgY29weSAobXV0YXRpbmcgYSByZXN1bHQgaXMgYWx3YXlzIHNhZmUpXG4gKiAtIGBnZXRPclNldGAgaXMgc2luZ2xlLWZsaWdodDogY29uY3VycmVudCBtaXNzZXMgc2hhcmUgb25lIGZhY3RvcnkoKSBjYWxsXG4gKiAtIEtleSBuYW1lc3BhY2UgcHJlZml4aW5nIHRvIGF2b2lkIGNvbGxpc2lvbnMgYmV0d2VlbiBzZXJ2aWNlc1xuICovXG5cblxuLyoqXG4gKiBDYWNoZSBlbnRyeSB3aXRoIHZhbHVlIGFuZCBleHBpcmF0aW9uIHRpbWUuXG4gKi9cbmludGVyZmFjZSBDYWNoZUVudHJ5PFQ+IHtcbiAgdmFsdWU6IFQ7XG4gIGV4cGlyZXNBdDogbnVtYmVyOyAvLyBVbml4IHRpbWVzdGFtcCBpbiBtc1xufVxuXG4vKipcbiAqIERlZXAtY2xvbmUgYSB2YWx1ZSBzbyB0aGUgaW4tbWVtb3J5IGJhY2tlbmQgaGFuZHMgYmFjayBhbiBJTkRFUEVOREVOVCBjb3B5IG9uXG4gKiBldmVyeSByZWFkIOKAlCBtYXRjaGluZyB0aGUgUmVkaXMgYmFja2VuZCwgd2hpY2ggcmV0dXJucyBhIGZyZXNoIGBKU09OLnBhcnNlYFxuICogY2xvbmUgZWFjaCB0aW1lLiBXaXRob3V0IHRoaXMgdGhlIGluLW1lbW9yeSBjYWNoZSByZXR1cm5zIHRoZSBzYW1lIHN0b3JlZFxuICogb2JqZWN0IHJlZmVyZW5jZSwgc28gYSBjb25zdW1lciBtdXRhdGluZyBhIFwiY2FjaGVkXCIgb2JqZWN0IHNpbGVudGx5IGNvcnJ1cHRzXG4gKiB0aGUgc2hhcmVkIGNhY2hlIChhIGZvb3RndW4gdGhhdCBvbmx5IGJpdGVzIHVuZGVyIHRoZSBtZW1vcnkgYmFja2VuZCkuXG4gKlxuICogUHJpbWl0aXZlcyBhcmUgcmV0dXJuZWQgYXMtaXMuIFByZWZlcnMgdGhlIHN0cnVjdHVyZWQtY2xvbmUgYWxnb3JpdGhtOyBmYWxsc1xuICogYmFjayB0byBhIEpTT04gcm91bmQtdHJpcCBvbiBvbGRlciBydW50aW1lcyBvciBleG90aWMgdmFsdWVzLlxuICovXG5mdW5jdGlvbiBjbG9uZVZhbHVlPFQ+KHZhbHVlOiBUKTogVCB7XG4gIGlmICh2YWx1ZSA9PT0gbnVsbCB8fCB0eXBlb2YgdmFsdWUgIT09ICdvYmplY3QnKSByZXR1cm4gdmFsdWU7XG4gIHRyeSB7XG4gICAgcmV0dXJuIHN0cnVjdHVyZWRDbG9uZSh2YWx1ZSk7XG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHZhbHVlKSkgYXMgVDtcbiAgfVxufVxuXG4vKipcbiAqIE1pbmltYWwgUmVkaXMtbGlrZSBjbGllbnQgaW50ZXJmYWNlIChzdWJzZXQgb2YgaW9yZWRpcykuXG4gKiBTZXJ2aWNlcyBwYXNzIHRoZWlyIG93biBSZWRpcyBjbGllbnQgaW5zdGFuY2UuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUmVkaXNDYWNoZUNsaWVudCB7XG4gIGdldChrZXk6IHN0cmluZyk6IFByb21pc2U8c3RyaW5nIHwgbnVsbD47XG4gIHNldChrZXk6IHN0cmluZywgdmFsdWU6IHN0cmluZywgLi4uYXJnczogdW5rbm93bltdKTogUHJvbWlzZTx1bmtub3duPjtcbiAgZGVsKC4uLmtleXM6IHN0cmluZ1tdKTogUHJvbWlzZTxudW1iZXI+O1xuICBrZXlzKHBhdHRlcm46IHN0cmluZyk6IFByb21pc2U8c3RyaW5nW10+O1xuICAvKiogU0NBTi1iYXNlZCBpdGVyYXRpb24gKHByZWZlcnJlZCBvdmVyIEtFWVMgZm9yIHByb2R1Y3Rpb24pLiAqL1xuICBzY2FuU3RyZWFtPyhvcHRpb25zOiB7IG1hdGNoOiBzdHJpbmc7IGNvdW50PzogbnVtYmVyIH0pOiBOb2RlSlMuUmVhZGFibGVTdHJlYW07XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2FjaGVDb25maWcge1xuICAvKiogS2V5IHByZWZpeCBmb3IgbmFtZXNwYWNlIGlzb2xhdGlvbiAoZS5nLiwgJ3BsdWdpbjonLCAnY29tcGxpYW5jZTonKSAqL1xuICBwcmVmaXg6IHN0cmluZztcbiAgLyoqIERlZmF1bHQgVFRMIGluIHNlY29uZHMgKi9cbiAgZGVmYXVsdFR0bFNlY29uZHM6IG51bWJlcjtcbiAgLyoqIE1heCBlbnRyaWVzIGZvciBpbi1tZW1vcnkgY2FjaGUgKGRlZmF1bHQgMTAwMCkgKi9cbiAgbWF4RW50cmllcz86IG51bWJlcjtcbiAgLyoqIE9wdGlvbmFsIFJlZGlzIGNsaWVudCDigJQgdXNlcyBpbi1tZW1vcnkgY2FjaGUgaWYgbm90IHByb3ZpZGVkICovXG4gIHJlZGlzPzogUmVkaXNDYWNoZUNsaWVudDtcbn1cblxuLyoqXG4gKiBDYWNoZSBzZXJ2aWNlIHdpdGggZ2V0L3NldC9kZWwgb3BlcmF0aW9ucyBhbmQgYXV0b21hdGljIFRUTCBleHBpcnkuXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IGNhY2hlID0gbmV3IENhY2hlU2VydmljZSh7IHByZWZpeDogJ3BsdWdpbjonLCBkZWZhdWx0VHRsU2Vjb25kczogMzAwIH0pO1xuICpcbiAqIC8vIFNldCB3aXRoIGRlZmF1bHQgVFRMXG4gKiBhd2FpdCBjYWNoZS5zZXQoJ29yZzEyMzpsaXN0JywgcGx1Z2lucyk7XG4gKlxuICogLy8gR2V0IChyZXR1cm5zIG51bGwgb24gbWlzcylcbiAqIGNvbnN0IGNhY2hlZCA9IGF3YWl0IGNhY2hlLmdldDxQbHVnaW5bXT4oJ29yZzEyMzpsaXN0Jyk7XG4gKlxuICogLy8gSW52YWxpZGF0ZVxuICogYXdhaXQgY2FjaGUuZGVsKCdvcmcxMjM6bGlzdCcpO1xuICpcbiAqIC8vIEludmFsaWRhdGUgYnkgcGF0dGVyblxuICogYXdhaXQgY2FjaGUuaW52YWxpZGF0ZVBhdHRlcm4oJ29yZzEyMzoqJyk7XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGNsYXNzIENhY2hlU2VydmljZSB7XG4gIHByaXZhdGUgbWVtb3J5ID0gbmV3IE1hcDxzdHJpbmcsIENhY2hlRW50cnk8dW5rbm93bj4+KCk7XG4gIC8qKlxuICAgKiBJbi1mbGlnaHQgYGdldE9yU2V0YCBmYWN0b3J5IHByb21pc2VzLCBrZXllZCBieSBmdWxsIGNhY2hlIGtleS4gQ29hbGVzY2VzXG4gICAqIGNvbmN1cnJlbnQgY29sZCBjYWxsZXJzIG9udG8gYSBzaW5nbGUgYGZhY3RvcnkoKWAgaW52b2NhdGlvbiAoc2luZ2xlLWZsaWdodFxuICAgKiAvIHN0YW1wZWRlIHByb3RlY3Rpb24pOyBlbnRyaWVzIGFyZSBjbGVhcmVkIG9uY2UgdGhlIHByb21pc2Ugc2V0dGxlcy5cbiAgICovXG4gIHByaXZhdGUgaW5mbGlnaHQgPSBuZXcgTWFwPHN0cmluZywgUHJvbWlzZTx1bmtub3duPj4oKTtcbiAgcHJpdmF0ZSByZWFkb25seSBwcmVmaXg6IHN0cmluZztcbiAgcHJpdmF0ZSByZWFkb25seSBkZWZhdWx0VHRsTXM6IG51bWJlcjtcbiAgcHJpdmF0ZSByZWFkb25seSBtYXhFbnRyaWVzOiBudW1iZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgcmVkaXM/OiBSZWRpc0NhY2hlQ2xpZW50O1xuXG4gIC8qKiBDYWNoZSBtZXRyaWNzIOKAlCB0cmFja3MgaGl0cywgbWlzc2VzLCBhbmQgaW52YWxpZGF0aW9ucy4gKi9cbiAgcmVhZG9ubHkgbWV0cmljcyA9IHsgaGl0czogMCwgbWlzc2VzOiAwLCBzZXRzOiAwLCBpbnZhbGlkYXRpb25zOiAwIH07XG5cbiAgY29uc3RydWN0b3IoY29uZmlnOiBDYWNoZUNvbmZpZykge1xuICAgIHRoaXMucHJlZml4ID0gY29uZmlnLnByZWZpeDtcbiAgICB0aGlzLmRlZmF1bHRUdGxNcyA9IGNvbmZpZy5kZWZhdWx0VHRsU2Vjb25kcyAqIDEwMDA7XG4gICAgdGhpcy5tYXhFbnRyaWVzID0gY29uZmlnLm1heEVudHJpZXMgPz8gMTAwMDtcbiAgICB0aGlzLnJlZGlzID0gY29uZmlnLnJlZGlzO1xuICB9XG5cbiAgcHJpdmF0ZSBmdWxsS2V5KGtleTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICByZXR1cm4gYCR7dGhpcy5wcmVmaXh9JHtrZXl9YDtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgYSBjYWNoZWQgdmFsdWUuIFJldHVybnMgbnVsbCBvbiBtaXNzIG9yIGVycm9yLlxuICAgKlxuICAgKiBUaGUgcmV0dXJuZWQgdmFsdWUgaXMgYW4gSU5ERVBFTkRFTlQgZGVlcCBjb3B5IOKAlCBtdXRhdGluZyBpdCBuZXZlciBhZmZlY3RzXG4gICAqIHRoZSBjYWNoZWQgZW50cnkgKHRoZSBpbi1tZW1vcnkgYmFja2VuZCBjbG9uZXMgb24gcmVhZCBmb3IgcGFyaXR5IHdpdGhcbiAgICogUmVkaXMsIHdoaWNoIHJldHVybnMgYSBmcmVzaCBKU09OIGNsb25lKS4gQ2FsbGVycyBtYXkgc3RpbGwgdHJlYXQgcmVzdWx0cyBhc1xuICAgKiBpbW11dGFibGUsIGJ1dCBkb2luZyBzbyBpcyBubyBsb25nZXIgbG9hZC1iZWFyaW5nIGZvciBjYWNoZSBpbnRlZ3JpdHkuXG4gICAqL1xuICBhc3luYyBnZXQ8VD4oa2V5OiBzdHJpbmcpOiBQcm9taXNlPFQgfCBudWxsPiB7XG4gICAgY29uc3QgZmsgPSB0aGlzLmZ1bGxLZXkoa2V5KTtcblxuICAgIHRyeSB7XG4gICAgICBpZiAodGhpcy5yZWRpcykge1xuICAgICAgICBjb25zdCByYXcgPSBhd2FpdCB0aGlzLnJlZGlzLmdldChmayk7XG4gICAgICAgIGlmICghcmF3KSB7IHRoaXMubWV0cmljcy5taXNzZXMrKzsgcmV0dXJuIG51bGw7IH1cbiAgICAgICAgdGhpcy5tZXRyaWNzLmhpdHMrKztcbiAgICAgICAgcmV0dXJuIEpTT04ucGFyc2UocmF3KSBhcyBUO1xuICAgICAgfVxuXG4gICAgICAvLyBJbi1tZW1vcnlcbiAgICAgIGNvbnN0IGVudHJ5ID0gdGhpcy5tZW1vcnkuZ2V0KGZrKTtcbiAgICAgIGlmICghZW50cnkpIHsgdGhpcy5tZXRyaWNzLm1pc3NlcysrOyByZXR1cm4gbnVsbDsgfVxuICAgICAgaWYgKERhdGUubm93KCkgPiBlbnRyeS5leHBpcmVzQXQpIHtcbiAgICAgICAgdGhpcy5tZW1vcnkuZGVsZXRlKGZrKTtcbiAgICAgICAgdGhpcy5tZXRyaWNzLm1pc3NlcysrO1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICAgIC8vIExSVSB0b3VjaDogZGVsZXRlICsgcmUtaW5zZXJ0IG1vdmVzIHRoaXMga2V5IHRvIHRoZSBuZXdlc3QgcG9zaXRpb25cbiAgICAgIC8vIChNYXAgcHJlc2VydmVzIGluc2VydGlvbiBvcmRlciksIHNvIGBzZXRgJ3Mgb2xkZXN0LWZpcnN0IGV2aWN0aW9uIGlzIGFcbiAgICAgIC8vIHRydWUgbGVhc3QtcmVjZW50bHktVVNFRCBldmljdGlvbiByYXRoZXIgdGhhbiBmaXJzdC1pbnNlcnRlZCAoRklGTykuXG4gICAgICB0aGlzLm1lbW9yeS5kZWxldGUoZmspO1xuICAgICAgdGhpcy5tZW1vcnkuc2V0KGZrLCBlbnRyeSk7XG4gICAgICB0aGlzLm1ldHJpY3MuaGl0cysrO1xuICAgICAgLy8gQ2xvbmUgc28gYSBjYWxsZXIgbXV0YXRpbmcgdGhlIHJlc3VsdCBjYW4ndCBjb3JydXB0IHRoZSBzaGFyZWQgZW50cnkuXG4gICAgICByZXR1cm4gY2xvbmVWYWx1ZShlbnRyeS52YWx1ZSkgYXMgVDtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHRoaXMubWV0cmljcy5taXNzZXMrKztcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBTZXQgYSBjYWNoZWQgdmFsdWUgd2l0aCBvcHRpb25hbCBUVEwgb3ZlcnJpZGUuXG4gICAqXG4gICAqIEBwYXJhbSBrZXkgLSBDYWNoZSBrZXkgKHByZWZpeCBpcyBhZGRlZCBhdXRvbWF0aWNhbGx5KVxuICAgKiBAcGFyYW0gdmFsdWUgLSBWYWx1ZSB0byBjYWNoZSAobXVzdCBiZSBKU09OLXNlcmlhbGl6YWJsZSBmb3IgUmVkaXMpXG4gICAqIEBwYXJhbSB0dGxTZWNvbmRzIC0gVFRMIG92ZXJyaWRlICh1c2VzIGRlZmF1bHQgaWYgbm90IHByb3ZpZGVkKVxuICAgKi9cbiAgYXN5bmMgc2V0PFQ+KGtleTogc3RyaW5nLCB2YWx1ZTogVCwgdHRsU2Vjb25kcz86IG51bWJlcik6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGZrID0gdGhpcy5mdWxsS2V5KGtleSk7XG4gICAgY29uc3QgdHRsID0gdHRsU2Vjb25kcyA/PyB0aGlzLmRlZmF1bHRUdGxNcyAvIDEwMDA7XG5cbiAgICB0cnkge1xuICAgICAgdGhpcy5tZXRyaWNzLnNldHMrKztcbiAgICAgIGlmICh0aGlzLnJlZGlzKSB7XG4gICAgICAgIGF3YWl0IHRoaXMucmVkaXMuc2V0KGZrLCBKU09OLnN0cmluZ2lmeSh2YWx1ZSksICdFWCcsIHR0bCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgLy8gSW4tbWVtb3J5IOKAlCBhIHdyaXRlIGNvdW50cyBhcyBhIHVzZSwgc28gZHJvcCBhbnkgZXhpc3RpbmcgZW50cnkgZmlyc3RcbiAgICAgIC8vIGFuZCByZS1pbnNlcnQgYmVsb3cgYXMgdGhlIG5ld2VzdCAoTWFwIHByZXNlcnZlcyBpbnNlcnRpb24gb3JkZXIpLiBUaGlzXG4gICAgICAvLyBrZWVwcyB0aGUgTWFwIG9yZGVyZWQgb2xkZXN0LVVTRUQg4oaSIG5ld2VzdC1VU0VEIHNvIHRoZSBldmljdGlvbiBiZWxvdyBpc1xuICAgICAgLy8gdHJ1ZSBMUlUsIGFuZCBhdm9pZHMgZXZpY3RpbmcgYSB2aWN0aW0gd2hlbiBtZXJlbHkgdXBkYXRpbmcgYSBrZXkuXG4gICAgICB0aGlzLm1lbW9yeS5kZWxldGUoZmspO1xuICAgICAgaWYgKHRoaXMubWVtb3J5LnNpemUgPj0gdGhpcy5tYXhFbnRyaWVzKSB7XG4gICAgICAgIGNvbnN0IGZpcnN0S2V5ID0gdGhpcy5tZW1vcnkua2V5cygpLm5leHQoKS52YWx1ZTtcbiAgICAgICAgaWYgKGZpcnN0S2V5KSB0aGlzLm1lbW9yeS5kZWxldGUoZmlyc3RLZXkpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLm1lbW9yeS5zZXQoZmssIHtcbiAgICAgICAgdmFsdWUsXG4gICAgICAgIGV4cGlyZXNBdDogRGF0ZS5ub3coKSArIHR0bCAqIDEwMDAsXG4gICAgICB9KTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIC8vIENhY2hlIHNldCBmYWlsdXJlIGlzIG5vbi1mYXRhbFxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBEZWxldGUgYSBjYWNoZWQgdmFsdWUuXG4gICAqL1xuICBhc3luYyBkZWwoa2V5OiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBmayA9IHRoaXMuZnVsbEtleShrZXkpO1xuXG4gICAgdHJ5IHtcbiAgICAgIGlmICh0aGlzLnJlZGlzKSB7XG4gICAgICAgIGF3YWl0IHRoaXMucmVkaXMuZGVsKGZrKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdGhpcy5tZW1vcnkuZGVsZXRlKGZrKTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIC8vIENhY2hlIGRlbGV0ZSBmYWlsdXJlIGlzIG5vbi1mYXRhbFxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBJbnZhbGlkYXRlIGFsbCBrZXlzIG1hdGNoaW5nIGEgcGF0dGVybiAoZS5nLiwgJ29yZzEyMzoqJykuXG4gICAqIFVzZXMgU0NBTiBmb3IgUmVkaXMgKG5vbi1ibG9ja2luZykgd2l0aCBLRVlTIGZhbGxiYWNrLCBvciByZWdleCBmb3IgaW4tbWVtb3J5LlxuICAgKi9cbiAgYXN5bmMgaW52YWxpZGF0ZVBhdHRlcm4ocGF0dGVybjogc3RyaW5nKTogUHJvbWlzZTxudW1iZXI+IHtcbiAgICBjb25zdCBmcCA9IHRoaXMuZnVsbEtleShwYXR0ZXJuKTtcblxuICAgIHRyeSB7XG4gICAgICBpZiAodGhpcy5yZWRpcykge1xuICAgICAgICBjb25zdCBrZXlzID0gdGhpcy5yZWRpcy5zY2FuU3RyZWFtXG4gICAgICAgICAgPyBhd2FpdCB0aGlzLnNjYW5LZXlzKGZwKVxuICAgICAgICAgIDogYXdhaXQgdGhpcy5yZWRpcy5rZXlzKGZwKTtcbiAgICAgICAgaWYgKGtleXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgIGF3YWl0IHRoaXMucmVkaXMuZGVsKC4uLmtleXMpO1xuICAgICAgICAgIHRoaXMubWV0cmljcy5pbnZhbGlkYXRpb25zICs9IGtleXMubGVuZ3RoO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBrZXlzLmxlbmd0aDtcbiAgICAgIH1cblxuICAgICAgLy8gSW4tbWVtb3J5IOKAlCBtYXRjaCBnbG9iLXN0eWxlIHBhdHRlcm4uIEVzY2FwZSByZWdleCBtZXRhY2hhcmFjdGVycyBmaXJzdFxuICAgICAgLy8gc28gYSBsaXRlcmFsIGAuYC9gKGAvYFtgIGluIGEga2V5IHByZWZpeCAoZS5nLiBgb3JnOnYxLjI6KmApIGNhbid0XG4gICAgICAvLyBvdmVyLW1hdGNoIG9yIHRocm93IChhIHRocm93IGhlcmUgaXMgc3dhbGxvd2VkIOKGkiBub3RoaW5nIGludmFsaWRhdGVkIOKGklxuICAgICAgLy8gc3RhbGUgcmVhZHMpOyBvbmx5IGAqYCBpcyB0cmVhdGVkIGFzIGEgd2lsZGNhcmQuXG4gICAgICBjb25zdCByZWdleCA9IG5ldyBSZWdFeHAoJ14nICsgZnAucmVwbGFjZSgvWy4qKz9eJHt9KCl8W1xcXVxcXFxdL2csICdcXFxcJCYnKS5yZXBsYWNlKC9cXFxcXFwqL2csICcuKicpICsgJyQnKTtcbiAgICAgIGxldCBkZWxldGVkID0gMDtcbiAgICAgIGZvciAoY29uc3Qga2V5IG9mIHRoaXMubWVtb3J5LmtleXMoKSkge1xuICAgICAgICBpZiAocmVnZXgudGVzdChrZXkpKSB7XG4gICAgICAgICAgdGhpcy5tZW1vcnkuZGVsZXRlKGtleSk7XG4gICAgICAgICAgZGVsZXRlZCsrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICB0aGlzLm1ldHJpY3MuaW52YWxpZGF0aW9ucyArPSBkZWxldGVkO1xuICAgICAgcmV0dXJuIGRlbGV0ZWQ7XG4gICAgfSBjYXRjaCB7XG4gICAgICByZXR1cm4gMDtcbiAgICB9XG4gIH1cblxuICAvKiogQ29sbGVjdCBrZXlzIHZpYSBSZWRpcyBTQ0FOIChub24tYmxvY2tpbmcgYWx0ZXJuYXRpdmUgdG8gS0VZUykuICovXG4gIHByaXZhdGUgc2NhbktleXMocGF0dGVybjogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmdbXT4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBjb25zdCBzdHJlYW0gPSB0aGlzLnJlZGlzIS5zY2FuU3RyZWFtISh7IG1hdGNoOiBwYXR0ZXJuLCBjb3VudDogMTAwIH0pO1xuICAgICAgY29uc3Qga2V5czogc3RyaW5nW10gPSBbXTtcbiAgICAgIHN0cmVhbS5vbignZGF0YScsIChiYXRjaDogc3RyaW5nW10pID0+IGtleXMucHVzaCguLi5iYXRjaCkpO1xuICAgICAgc3RyZWFtLm9uY2UoJ2VuZCcsICgpID0+IHJlc29sdmUoa2V5cykpO1xuICAgICAgc3RyZWFtLm9uY2UoJ2Vycm9yJywgcmVqZWN0KTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgb3IgY29tcHV0ZTogcmV0dXJucyBjYWNoZWQgdmFsdWUgaWYgYXZhaWxhYmxlLCBvdGhlcndpc2UgY2FsbHMgdGhlXG4gICAqIGZhY3RvcnkgZnVuY3Rpb24sIGNhY2hlcyB0aGUgcmVzdWx0LCBhbmQgcmV0dXJucyBpdC5cbiAgICpcbiAgICogU2luZ2xlLWZsaWdodCAvIHN0YW1wZWRlIHByb3RlY3Rpb246IHdoZW4gTiBjYWxsZXJzIG1pc3MgY29uY3VycmVudGx5IGZvclxuICAgKiB0aGUgc2FtZSBrZXksIG9ubHkgT05FIGBmYWN0b3J5KClgIHJ1bnMg4oCUIHRoZSByZXN0IGF3YWl0IGl0cyBzaGFyZWQgcHJvbWlzZS5cbiAgICogVGhlIGluLWZsaWdodCBlbnRyeSBpcyBjbGVhcmVkIG9uY2UgaXQgc2V0dGxlcyAoc3VjY2VzcyBvciBmYWlsdXJlKSwgc28gYVxuICAgKiBmYWlsZWQgZmFjdG9yeSBkb2Vzbid0IHBvaXNvbiBsYXRlciBjYWxscy5cbiAgICpcbiAgICogQHBhcmFtIGtleSAtIENhY2hlIGtleVxuICAgKiBAcGFyYW0gZmFjdG9yeSAtIEFzeW5jIGZ1bmN0aW9uIHRvIGNvbXB1dGUgdGhlIHZhbHVlIG9uIGNhY2hlIG1pc3NcbiAgICogQHBhcmFtIHR0bFNlY29uZHMgLSBPcHRpb25hbCBUVEwgb3ZlcnJpZGVcbiAgICogQHJldHVybnMgVGhlIGNhY2hlZCBvciBjb21wdXRlZCB2YWx1ZVxuICAgKi9cbiAgYXN5bmMgZ2V0T3JTZXQ8VD4oa2V5OiBzdHJpbmcsIGZhY3Rvcnk6ICgpID0+IFByb21pc2U8VD4sIHR0bFNlY29uZHM/OiBudW1iZXIpOiBQcm9taXNlPFQ+IHtcbiAgICBjb25zdCBjYWNoZWQgPSBhd2FpdCB0aGlzLmdldDxUPihrZXkpO1xuICAgIGlmIChjYWNoZWQgIT09IG51bGwpIHJldHVybiBjYWNoZWQ7XG5cbiAgICBjb25zdCBmayA9IHRoaXMuZnVsbEtleShrZXkpO1xuICAgIC8vIENvYWxlc2NlIGNvbmN1cnJlbnQgY29sZCBjYWxsZXJzIG9udG8gYSBzaW5nbGUgZmFjdG9yeSgpIGludm9jYXRpb24uIFRoZVxuICAgIC8vIGluLWZsaWdodCBwcm9taXNlIHJlc29sdmVzIHRvIHRoZSBSQVcgdmFsdWU7IGVhY2ggYXdhaXRlciAodGhlIHByaW1hcnlcbiAgICAvLyBjYWxsZXIgYmVsb3cgQU5EIGV2ZXJ5IGNvYWxlc2NlZCBjYWxsZXIgaGVyZSkgY2xvbmVzIGl0IElOREVQRU5ERU5UTFkuXG4gICAgLy8gQ2xvbmluZyBpbnNpZGUgdGhlIGZsaWdodCBpbnN0ZWFkIHdvdWxkIGhhbmQgb25lIHNoYXJlZCBjbG9uZSB0byBhbGwgTlxuICAgIC8vIGNvYWxlc2NlZCBjYWxsZXJzLCBzbyBvbmUgY2FsbGVyIG11dGF0aW5nIGl0cyBcImluZGVwZW5kZW50XCIgcmVzdWx0IHdvdWxkXG4gICAgLy8gY29ycnVwdCB3aGF0IHRoZSBvdGhlcnMgcmVhZCDigJQgdGhlIGV4YWN0IGZvb3RndW4gZ2V0KCkncyBjbG9uZS1vbi1yZWFkXG4gICAgLy8gcHJldmVudHMuIChSZWRpcyBiYWNrZW5kIGlzIHVuYWZmZWN0ZWQ6IHNldCBzZXJpYWxpemVzLCBnZXQgSlNPTi5wYXJzZXMuKVxuICAgIGNvbnN0IGV4aXN0aW5nID0gdGhpcy5pbmZsaWdodC5nZXQoZmspIGFzIFByb21pc2U8VD4gfCB1bmRlZmluZWQ7XG4gICAgaWYgKGV4aXN0aW5nKSByZXR1cm4gY2xvbmVWYWx1ZShhd2FpdCBleGlzdGluZyk7XG5cbiAgICBjb25zdCBmbGlnaHQgPSAoYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgdmFsdWUgPSBhd2FpdCBmYWN0b3J5KCk7XG4gICAgICBhd2FpdCB0aGlzLnNldChrZXksIHZhbHVlLCB0dGxTZWNvbmRzKTtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9KSgpO1xuICAgIHRoaXMuaW5mbGlnaHQuc2V0KGZrLCBmbGlnaHQpO1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gY2xvbmVWYWx1ZShhd2FpdCBmbGlnaHQpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICB0aGlzLmluZmxpZ2h0LmRlbGV0ZShmayk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENsZWFyIGFsbCBlbnRyaWVzICh1c2VmdWwgZm9yIHRlc3RpbmcpLlxuICAgKi9cbiAgYXN5bmMgY2xlYXIoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMucmVkaXMpIHtcbiAgICAgIGF3YWl0IHRoaXMuaW52YWxpZGF0ZVBhdHRlcm4oJyonKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5tZW1vcnkuY2xlYXIoKTtcbiAgICB9XG4gIH1cblxuICAvKiogQ3VycmVudCBpbi1tZW1vcnkgY2FjaGUgc2l6ZSAoZm9yIGRpYWdub3N0aWNzKS4gKi9cbiAgZ2V0IHNpemUoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5tZW1vcnkuc2l6ZTtcbiAgfVxufVxuXG4vKipcbiAqIENyZWF0ZSBhIGNhY2hlIHNlcnZpY2UgaW5zdGFuY2UuXG4gKlxuICogQHBhcmFtIHByZWZpeCAtIE5hbWVzcGFjZSBwcmVmaXggKGUuZy4sICdjb21wbGlhbmNlOicsICdwbHVnaW46JylcbiAqIEBwYXJhbSBkZWZhdWx0VHRsU2Vjb25kcyAtIERlZmF1bHQgVFRMIGluIHNlY29uZHMgKGRlZmF1bHQgMzAwID0gNSBtaW4pXG4gKiBAcGFyYW0gcmVkaXMgLSBPcHRpb25hbCBSZWRpcyBjbGllbnQgZm9yIGNyb3NzLXByb2Nlc3MgY2FjaGluZ1xuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlQ2FjaGVTZXJ2aWNlKFxuICBwcmVmaXg6IHN0cmluZyxcbiAgZGVmYXVsdFR0bFNlY29uZHMgPSAzMDAsXG4gIHJlZGlzPzogUmVkaXNDYWNoZUNsaWVudCxcbik6IENhY2hlU2VydmljZSB7XG4gIHJldHVybiBuZXcgQ2FjaGVTZXJ2aWNlKHsgcHJlZml4LCBkZWZhdWx0VHRsU2Vjb25kcywgcmVkaXMgfSk7XG59XG4iXX0=
371
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FjaGUtc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zZXJ2aWNlcy9jYWNoZS1zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFFdEM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBb0JHO0FBRUgsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLFFBQVEsQ0FBQztBQUVwQyxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUN0RCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDbEQsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBRXpELE1BQU0sTUFBTSxHQUFHLFlBQVksQ0FBQyxlQUFlLENBQUMsQ0FBQztBQVU3Qzs7Ozs7OztHQU9HO0FBQ0gsU0FBUyxVQUFVLENBQUksS0FBUTtJQUM3QixJQUFJLEtBQUssS0FBSyxJQUFJLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUTtRQUFFLE9BQU8sS0FBSyxDQUFDO0lBQzlELElBQUksQ0FBQztRQUNILE9BQU8sZUFBZSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ2hDLENBQUM7SUFBQyxNQUFNLENBQUM7UUFDUCxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBTSxDQUFDO0lBQ2hELENBQUM7QUFDSCxDQUFDO0FBMkRELE1BQU0sMEJBQTBCLEdBQUcsa0JBQWtCLENBQUM7QUFFdEQ7Ozs7Ozs7OztHQVNHO0FBQ0gsTUFBTSxVQUFVLCtCQUErQixDQUFDLFNBQWtDO0lBQ2hGLE1BQU0sVUFBVSxHQUFHLFNBQVMsQ0FBQyxTQUFTLEVBQUUsQ0FBQztJQUN6QyxNQUFNLGVBQWUsR0FBbUQsRUFBRSxDQUFDO0lBQzNFLE1BQU0sY0FBYyxHQUFzQixFQUFFLENBQUM7SUFFN0MsTUFBTSxNQUFNLEdBQUcs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QUksSUFBSSxDQUFDLFVBQVUsS0FBSyxpQkFBaUI7Z0JBQUUsTUFBTSxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxLQUFLLEVBQUUsVUFBVSxDQUFDLENBQUM7WUFDbEYsT0FBTyxLQUFLLENBQUM7UUFDZixDQUFDLENBQUMsRUFBRSxDQUFDO1FBQ0wsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQzlCLElBQUksQ0FBQztZQUNILE9BQU8sVUFBVSxDQUFDLE1BQU0sTUFBTSxDQUFDLENBQUM7UUFDbEMsQ0FBQztnQkFBUyxDQUFDO1lBQ1QsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDM0IsQ0FBQztJQUNILENBQUM7SUFFRDs7T0FFRztJQUNILEtBQUssQ0FBQyxLQUFLO1FBQ1QsSUFBSSxDQUFDLHNCQUFzQixDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3JDLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDMUIsQ0FBQztJQUVELHNEQUFzRDtJQUN0RCxJQUFJLElBQUk7UUFDTixPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDO0lBQzFCLENBQUM7Q0FDRjtBQUVEOzs7OztHQUtHO0FBQ0gsTUFBTSxVQUFVLGtCQUFrQixDQUFDLE1BQWMsRUFBRSxpQkFBaUIsR0FBRyxHQUFHO0lBQ3hFLE9BQU8sSUFBSSxZQUFZLENBQUMsRUFBRSxNQUFNLEVBQUUsaUJBQWlCLEVBQUUsQ0FBQyxDQUFDO0FBQ3pELENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuLyoqXG4gKiBMaWdodHdlaWdodCBjYWNoaW5nIHNlcnZpY2Ugd2l0aCBUVEwgc3VwcG9ydC5cbiAqXG4gKiBTdG9yYWdlIGlzIGEgcGVyLXByb2Nlc3MgdHJ1ZS1MUlUgTWFwIChubyBleHRlcm5hbCBkZXBlbmRlbmNpZXMpLlxuICpcbiAqIENyb3NzLXJlcGxpY2EgaW52YWxpZGF0aW9uOiBldmVyeSBzZXJ2aWNlIHJ1bnMgc2V2ZXJhbFxuICogcmVwbGljYXMgKEhQQSksIGVhY2ggd2l0aCBpdHMgT1dOIGluLW1lbW9yeSBjYWNoZS4gQW4gaW52YWxpZGF0aW9uIHBlcmZvcm1lZCBvblxuICogb25lIHBvZCAoYGRlbGAgLyBgaW52YWxpZGF0ZVBhdHRlcm5gIC8gYGNsZWFyYCkgaXMgYnJvYWRjYXN0IG92ZXIgUmVkaXMgcHViL3N1YlxuICogKHtAbGluayBDYWNoZUludmFsaWRhdGlvbkJ1c30sIHdpcmVkIGZyb20gdGhlIGFtYmllbnQgUmVkaXMgZW52IGJ5IGRlZmF1bHQpIGFuZFxuICogYXBwbGllZCBieSBldmVyeSBvdGhlciBwb2QsIHNvIGEgd3JpdGUgb24gcG9kIEEgY2FuJ3QgbGVhdmUgcG9kIEIgc2VydmluZyB0aGVcbiAqIHN0YWxlIGVudHJ5IHVudGlsIGl0cyBUVEwgbGFwc2VzLiBBIHBvZCB3aG9zZSBzdWJzY3JpYmVyIChyZSljb25uZWN0cyBmbHVzaGVzXG4gKiBpdHMgbG9jYWwgY2FjaGUg4oCUIGl0IG1heSBoYXZlIG1pc3NlZCBpbnZhbGlkYXRpb25zIHdoaWxlIGRpc2Nvbm5lY3RlZCDigJQgYW5kIGFcbiAqIGBnZXRPclNldGAgd2hvc2UgZmFjdG9yeSByYWNlZCBhbiBpbnZhbGlkYXRpb24gZG9lcyBub3QgY2FjaGUgaXRzIHJlc3VsdC5cbiAqXG4gKiBEZXNpZ246XG4gKiAtIEFsbCBvcGVyYXRpb25zIGFyZSBmYWlsLXNhZmU6IGNhY2hlIG1pc3Nlcy9lcnJvcnMgcmV0dXJuIG51bGwsIG5ldmVyIHRocm93XG4gKiAtIFJlYWRzIGRlZXAtY2xvbmUsIHNvIGV2ZXJ5IGNhbGxlciBnZXRzIGFuIGluZGVwZW5kZW50IGNvcHkgKG11dGF0aW5nIGFcbiAqICAgcmVzdWx0IGlzIGFsd2F5cyBzYWZlKVxuICogLSBgZ2V0T3JTZXRgIGlzIHNpbmdsZS1mbGlnaHQ6IGNvbmN1cnJlbnQgbWlzc2VzIHNoYXJlIG9uZSBmYWN0b3J5KCkgY2FsbFxuICogLSBLZXkgbmFtZXNwYWNlIHByZWZpeGluZyB0byBhdm9pZCBjb2xsaXNpb25zIGJldHdlZW4gc2VydmljZXNcbiAqL1xuXG5pbXBvcnQgeyByYW5kb21VVUlEIH0gZnJvbSAnY3J5cHRvJztcblxuaW1wb3J0IHsgY3JlYXRlRW52UmVkaXNDbGllbnQgfSBmcm9tICcuL2Vudi1yZWRpcy5qcyc7XG5pbXBvcnQgeyBjcmVhdGVMb2dnZXIgfSBmcm9tICcuLi91dGlscy9sb2dnZXIuanMnO1xuaW1wb3J0IHsgZW1pdENvdW50ZXIgfSBmcm9tICcuLi91dGlscy9tZXRyaWMtZW1pdHRlci5qcyc7XG5cbmNvbnN0IGxvZ2dlciA9IGNyZWF0ZUxvZ2dlcignY2FjaGUtc2VydmljZScpO1xuXG4vKipcbiAqIENhY2hlIGVudHJ5IHdpdGggdmFsdWUgYW5kIGV4cGlyYXRpb24gdGltZS5cbiAqL1xuaW50ZXJmYWNlIENhY2hlRW50cnk8VD4ge1xuICB2YWx1ZTogVDtcbiAgZXhwaXJlc0F0OiBudW1iZXI7IC8vIFVuaXggdGltZXN0YW1wIGluIG1zXG59XG5cbi8qKlxuICogRGVlcC1jbG9uZSBhIHZhbHVlIHNvIHRoZSBjYWNoZSBoYW5kcyBiYWNrIGFuIElOREVQRU5ERU5UIGNvcHkgb24gZXZlcnkgcmVhZC5cbiAqIFdpdGhvdXQgdGhpcyBpdCByZXR1cm5zIHRoZSBzYW1lIHN0b3JlZCBvYmplY3QgcmVmZXJlbmNlLCBzbyBhIGNvbnN1bWVyXG4gKiBtdXRhdGluZyBhIFwiY2FjaGVkXCIgb2JqZWN0IHNpbGVudGx5IGNvcnJ1cHRzIHRoZSBzaGFyZWQgY2FjaGUuXG4gKlxuICogUHJpbWl0aXZlcyBhcmUgcmV0dXJuZWQgYXMtaXMuIFByZWZlcnMgdGhlIHN0cnVjdHVyZWQtY2xvbmUgYWxnb3JpdGhtOyBmYWxsc1xuICogYmFjayB0byBhIEpTT04gcm91bmQtdHJpcCBvbiBvbGRlciBydW50aW1lcyBvciBleG90aWMgdmFsdWVzLlxuICovXG5mdW5jdGlvbiBjbG9uZVZhbHVlPFQ+KHZhbHVlOiBUKTogVCB7XG4gIGlmICh2YWx1ZSA9PT0gbnVsbCB8fCB0eXBlb2YgdmFsdWUgIT09ICdvYmplY3QnKSByZXR1cm4gdmFsdWU7XG4gIHRyeSB7XG4gICAgcmV0dXJuIHN0cnVjdHVyZWRDbG9uZSh2YWx1ZSk7XG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHZhbHVlKSkgYXMgVDtcbiAgfVxufVxuXG4vKipcbiAqIE1pbmltYWwgUmVkaXMga2V5L3ZhbHVlIGNsaWVudCBzdXJmYWNlIChzdWJzZXQgb2YgaW9yZWRpcykgc2hhcmVkIGJ5IHRoZVxuICogdG9rZW4tcmV2b2NhdGlvbiBwdWJsaXNoZXIvcmVhZGVyIGFuZCBwbGF0Zm9ybSdzIFJlZGlzIGhlbHBlcnMuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUmVkaXNDYWNoZUNsaWVudCB7XG4gIGdldChrZXk6IHN0cmluZyk6IFByb21pc2U8c3RyaW5nIHwgbnVsbD47XG4gIHNldChrZXk6IHN0cmluZywgdmFsdWU6IHN0cmluZywgLi4uYXJnczogdW5rbm93bltdKTogUHJvbWlzZTx1bmtub3duPjtcbiAgZGVsKC4uLmtleXM6IHN0cmluZ1tdKTogUHJvbWlzZTxudW1iZXI+O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIENhY2hlQ29uZmlnIHtcbiAgLyoqIEtleSBwcmVmaXggZm9yIG5hbWVzcGFjZSBpc29sYXRpb24gKGUuZy4sICdwbHVnaW46JywgJ2NvbXBsaWFuY2U6JykgKi9cbiAgcHJlZml4OiBzdHJpbmc7XG4gIC8qKiBEZWZhdWx0IFRUTCBpbiBzZWNvbmRzICovXG4gIGRlZmF1bHRUdGxTZWNvbmRzOiBudW1iZXI7XG4gIC8qKiBNYXggZW50cmllcyBmb3IgdGhlIGNhY2hlIChkZWZhdWx0IDEwMDApICovXG4gIG1heEVudHJpZXM/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBDcm9zcy1yZXBsaWNhIGludmFsaWRhdGlvbiBidXMuIE9taXQgdG8gdXNlIHRoZSBzaGFyZWQgZW52LVJlZGlzIGJ1cyAobnVsbFxuICAgKiB3aGVuIFJlZGlzIGlzbid0IGNvbmZpZ3VyZWQg4oaSIHNpbmdsZS1wcm9jZXNzIHNlbWFudGljcyk7IHBhc3MgYG51bGxgIHRvXG4gICAqIGRpc2FibGUgZXhwbGljaXRseS5cbiAgICovXG4gIGludmFsaWRhdGlvbkJ1cz86IENhY2hlSW52YWxpZGF0aW9uQnVzIHwgbnVsbDtcbn1cblxuLyoqIE9uZSBpbnZhbGlkYXRpb24gYnJvYWRjYXN0IHRvIGV2ZXJ5IHJlcGxpY2EuICovXG5leHBvcnQgaW50ZXJmYWNlIENhY2hlSW52YWxpZGF0aW9uTWVzc2FnZSB7XG4gIC8qKiBJZCBvZiB0aGUgQ2FjaGVTZXJ2aWNlIGluc3RhbmNlIHRoYXQgaW52YWxpZGF0ZWQgKGl0IGlnbm9yZXMgaXRzIG93biBlY2hvKS4gKi9cbiAgb3JpZ2luOiBzdHJpbmc7XG4gIC8qKiBUaGUgY2FjaGUgbmFtZXNwYWNlIChgQ2FjaGVDb25maWcucHJlZml4YCkgdGhlIGludmFsaWRhdGlvbiBhcHBsaWVzIHRvLiAqL1xuICBwcmVmaXg6IHN0cmluZztcbiAgb3A6ICdkZWwnIHwgJ3BhdHRlcm4nIHwgJ2NsZWFyJztcbiAgLyoqIFVuLXByZWZpeGVkIGtleSAoYGRlbGApIG9yIGdsb2IgcGF0dGVybiAoYHBhdHRlcm5gKS4gKi9cbiAga2V5Pzogc3RyaW5nO1xufVxuXG4vKiogVHJhbnNwb3J0IHRoYXQgZmFucyBjYWNoZSBpbnZhbGlkYXRpb25zIG91dCB0byBldmVyeSByZXBsaWNhLiAqL1xuZXhwb3J0IGludGVyZmFjZSBDYWNoZUludmFsaWRhdGlvbkJ1cyB7XG4gIC8qKiBGaXJlLWFuZC1mb3JnZXQgYnJvYWRjYXN0LiBOZXZlciB0aHJvd3MuICovXG4gIHB1Ymxpc2gobXNnOiBDYWNoZUludmFsaWRhdGlvbk1lc3NhZ2UpOiB2b2lkO1xuICAvKipcbiAgICogUmVnaXN0ZXIgaGFuZGxlcnMuIGBvbk1lc3NhZ2VgIHJlY2VpdmVzIGV2ZXJ5IGJyb2FkY2FzdCAoaW5jbHVkaW5nIHRoaXNcbiAgICogcHJvY2VzcydzIG93bik7IGBvblJlc3luY2AgZmlyZXMgd2hlbmV2ZXIgdGhlIHN1YnNjcmlwdGlvbiBpcyAocmUpZXN0YWJsaXNoZWQsXG4gICAqIGkuZS4gd2hlbmV2ZXIgaW52YWxpZGF0aW9ucyBtYXkgaGF2ZSBiZWVuIG1pc3NlZC5cbiAgICovXG4gIHN1YnNjcmliZShvbk1lc3NhZ2U6IChtc2c6IENhY2hlSW52YWxpZGF0aW9uTWVzc2FnZSkgPT4gdm9pZCwgb25SZXN5bmM6ICgpID0+IHZvaWQpOiB2b2lkO1xufVxuXG4vKiogTWluaW1hbCBpb3JlZGlzIHB1Yi9zdWIgc3VyZmFjZSB0aGUgZW52IGJ1cyBuZWVkcy4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUmVkaXNJbnZhbGlkYXRpb25DbGllbnQge1xuICBwdWJsaXNoKGNoYW5uZWw6IHN0cmluZywgbWVzc2FnZTogc3RyaW5nKTogUHJvbWlzZTxudW1iZXI+O1xuICBzdWJzY3JpYmUoLi4uY2hhbm5lbHM6IHN0cmluZ1tdKTogUHJvbWlzZTx1bmtub3duPjtcbiAgb24oZXZlbnQ6IHN0cmluZywgY2I6ICguLi5hcmdzOiBhbnlbXSkgPT4gdm9pZCk6IHVua25vd247XG4gIGR1cGxpY2F0ZSgpOiBSZWRpc0ludmFsaWRhdGlvbkNsaWVudDtcbiAgc3RhdHVzPzogc3RyaW5nO1xufVxuXG5jb25zdCBDQUNIRV9JTlZBTElEQVRJT05fQ0hBTk5FTCA9ICdjYWNoZTppbnZhbGlkYXRlJztcblxuLyoqXG4gKiBSZWRpcyBwdWIvc3ViIGludmFsaWRhdGlvbiBidXMuIFBVQkxJU0ggb24gdGhlIGdpdmVuIGNsaWVudDsgU1VCU0NSSUJFIG9uIGFcbiAqIGBkdXBsaWNhdGUoKWAgKGEgc3Vic2NyaWJlZCBpb3JlZGlzIGNvbm5lY3Rpb24gY2FuJ3QgcnVuIG90aGVyIGNvbW1hbmRzKS5cbiAqXG4gKiBUaGUgU1VCU0NSSUJFIGlzIGlzc3VlZCBvbiBldmVyeSBgcmVhZHlgIChpbml0aWFsIGNvbm5lY3QgQU5EIGVhY2ggcmVjb25uZWN0KVxuICogcmF0aGVyIHRoYW4gb25jZSBhdCBjb25zdHJ1Y3Rpb246IHRoZSBlbnYgY2xpZW50IHJ1bnMgd2l0aG91dCBhbiBvZmZsaW5lXG4gKiBxdWV1ZSwgc28gYSBzdWJzY3JpYmUgaXNzdWVkIGJlZm9yZSB0aGUgY29ubmVjdGlvbiBpcyB1cCBpcyByZWplY3RlZCBhbmQgd291bGRcbiAqIG5ldmVyIGJlIHJldHJpZWQuIEVhY2ggYHJlYWR5YCBhbHNvIHRyaWdnZXJzIGBvblJlc3luY2Agc28gZXZlcnkgY2FjaGUgZmx1c2hlc1xuICogd2hhdGV2ZXIgaXQgbWF5IGhhdmUgbWlzc2VkIHdoaWxlIGRpc2Nvbm5lY3RlZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVJlZGlzQ2FjaGVJbnZhbGlkYXRpb25CdXMocHVibGlzaGVyOiBSZWRpc0ludmFsaWRhdGlvbkNsaWVudCk6IENhY2hlSW52YWxpZGF0aW9uQnVzIHtcbiAgY29uc3Qgc3Vic2NyaWJlciA9IHB1Ymxpc2hlci5kdXBsaWNhdGUoKTtcbiAgY29uc3QgbWVzc2FnZUhhbmRsZXJzOiBBcnJheTwobXNnOiBDYWNoZUludmFsaWRhdGlvbk1lc3NhZ2UpID0+IHZvaWQ+ID0gW107XG4gIGNvbnN0IHJlc3luY0hhbmRsZXJzOiBBcnJheTwoKSA9PiB2b2lkPiA9IFtdO1xuXG4gIGNvbnN0IHJlc3luYyA9ICgpOiB2b2lkID0+IHtcbiAgICBmb3IgKGNvbnN0IGggb2YgcmVzeW5jSGFuZGxlcnMpIHtcbiAgICAgIHRyeSB7IGgoKTsgfSBjYXRjaCB7IC8qIGlzb2xhdGVkICovIH1cbiAgICB9XG4gIH07XG4gIGNvbnN0IGRvU3Vic2NyaWJlID0gKCk6IHZvaWQgPT4ge1xuICAgIHZvaWQgUHJvbWlzZS5yZXNvbHZlKHN1YnNjcmliZXIuc3Vic2NyaWJlKENBQ0hFX0lOVkFMSURBVElPTl9DSEFOTkVMKSlcbiAgICAgIC50aGVuKCgpID0+IHJlc3luYygpKVxuICAgICAgLmNhdGNoKChlcnI6IHVua25vd24pID0+IHtcbiAgICAgICAgZW1pdENvdW50ZXIoJ2NhY2hlX2ludmFsaWRhdGlvbl9zdWJzY3JpYmVfZmFpbGVkX3RvdGFsJywge30pO1xuICAgICAgICBsb2dnZXIud2FybignQ2FjaGUgaW52YWxpZGF0aW9uIHN1YnNjcmliZSBmYWlsZWQ7IHdpbGwgcmV0cnkgb24gbmV4dCByZWNvbm5lY3QnLCB7XG4gICAgICAgICAgZXJyb3I6IGVyciBpbnN0YW5jZW9mIEVycm9yID8gZXJyLm1lc3NhZ2UgOiBTdHJpbmcoZXJyKSxcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgfTtcblxuICBzdWJzY3JpYmVyLm9uKCdtZXNzYWdlJywgKGNoYW5uZWw6IHN0cmluZywgcmF3OiBzdHJpbmcpID0+IHtcbiAgICBpZiAoY2hhbm5lbCAhPT0gQ0FDSEVfSU5WQUxJREFUSU9OX0NIQU5ORUwpIHJldHVybjtcbiAgICBsZXQgbXNnOiBDYWNoZUludmFsaWRhdGlvbk1lc3NhZ2U7XG4gICAgdHJ5IHtcbiAgICAgIG1zZyA9IEpTT04ucGFyc2UocmF3KSBhcyBDYWNoZUludmFsaWRhdGlvbk1lc3NhZ2U7XG4gICAgfSBjYXRjaCB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGZvciAoY29uc3QgaCBvZiBtZXNzYWdlSGFuZGxlcnMpIHtcbiAgICAgIHRyeSB7IGgobXNnKTsgfSBjYXRjaCB7IC8qIG9uZSBjYWNoZSBjYW4ndCBicmVhayB0aGUgb3RoZXJzICovIH1cbiAgICB9XG4gIH0pO1xuICBzdWJzY3JpYmVyLm9uKCdyZWFkeScsIGRvU3Vic2NyaWJlKTtcbiAgc3Vic2NyaWJlci5vbignZXJyb3InLCAoZTogdW5rbm93bikgPT5cbiAgICBsb2dnZXIud2FybignQ2FjaGUgaW52YWxpZGF0aW9uIHN1YnNjcmliZXIgZXJyb3InLCB7IGVycm9yOiBlIGluc3RhbmNlb2YgRXJyb3IgPyBlLm1lc3NhZ2UgOiBTdHJpbmcoZSkgfSkpO1xuICBpZiAoc3Vic2NyaWJlci5zdGF0dXMgPT09ICdyZWFkeScpIGRvU3Vic2NyaWJlKCk7XG5cbiAgcmV0dXJuIHtcbiAgICBwdWJsaXNoKG1zZykge1xuICAgICAgdm9pZCBQcm9taXNlLnJlc29sdmUoKVxuICAgICAgICAudGhlbigoKSA9PiBwdWJsaXNoZXIucHVibGlzaChDQUNIRV9JTlZBTElEQVRJT05fQ0hBTk5FTCwgSlNPTi5zdHJpbmdpZnkobXNnKSkpXG4gICAgICAgIC5jYXRjaCgoZXJyOiB1bmtub3duKSA9PiB7XG4gICAgICAgICAgZW1pdENvdW50ZXIoJ2NhY2hlX2ludmFsaWRhdGlvbl9wdWJsaXNoX2ZhaWxlZF90b3RhbCcsIHsgcHJlZml4OiBtc2cucHJlZml4IH0pO1xuICAgICAgICAgIGxvZ2dlci53YXJuKCdDYWNoZSBpbnZhbGlkYXRpb24gcHVibGlzaCBmYWlsZWQgKG90aGVyIHJlcGxpY2FzIGtlZXAgdGhlIGVudHJ5IHVudGlsIFRUTCknLCB7XG4gICAgICAgICAgICBwcmVmaXg6IG1zZy5wcmVmaXgsIG9wOiBtc2cub3AsIGVycm9yOiBlcnIgaW5zdGFuY2VvZiBFcnJvciA/IGVyci5tZXNzYWdlIDogU3RyaW5nKGVyciksXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH0sXG4gICAgc3Vic2NyaWJlKG9uTWVzc2FnZSwgb25SZXN5bmMpIHtcbiAgICAgIG1lc3NhZ2VIYW5kbGVycy5wdXNoKG9uTWVzc2FnZSk7XG4gICAgICByZXN5bmNIYW5kbGVycy5wdXNoKG9uUmVzeW5jKTtcbiAgICB9LFxuICB9O1xufVxuXG4vLyB1bmRlZmluZWQgPSBub3QgeWV0IGF0dGVtcHRlZDsgbnVsbCA9IGF0dGVtcHRlZCwgUmVkaXMgbm90IGNvbmZpZ3VyZWQuXG5sZXQgZW52SW52YWxpZGF0aW9uQnVzOiBDYWNoZUludmFsaWRhdGlvbkJ1cyB8IG51bGwgfCB1bmRlZmluZWQ7XG5cbi8qKiBQcm9jZXNzLXdpZGUgaW52YWxpZGF0aW9uIGJ1cyBmcm9tIHRoZSBhbWJpZW50IFJlZGlzIGVudiAobnVsbCB3aXRob3V0IFJlZGlzKS4gKi9cbmZ1bmN0aW9uIGdldEVudkNhY2hlSW52YWxpZGF0aW9uQnVzKCk6IENhY2hlSW52YWxpZGF0aW9uQnVzIHwgbnVsbCB7XG4gIGlmIChlbnZJbnZhbGlkYXRpb25CdXMgPT09IHVuZGVmaW5lZCkge1xuICAgIGNvbnN0IGNsaWVudCA9IGNyZWF0ZUVudlJlZGlzQ2xpZW50PFJlZGlzSW52YWxpZGF0aW9uQ2xpZW50PignY2FjaGUtaW52YWxpZGF0aW9uJyk7XG4gICAgZW52SW52YWxpZGF0aW9uQnVzID0gY2xpZW50ID8gY3JlYXRlUmVkaXNDYWNoZUludmFsaWRhdGlvbkJ1cyhjbGllbnQpIDogbnVsbDtcbiAgfVxuICByZXR1cm4gZW52SW52YWxpZGF0aW9uQnVzO1xufVxuXG4vKipcbiAqIENhY2hlIHNlcnZpY2Ugd2l0aCBnZXQvc2V0L2RlbCBvcGVyYXRpb25zIGFuZCBhdXRvbWF0aWMgVFRMIGV4cGlyeS5cbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgY2FjaGUgPSBuZXcgQ2FjaGVTZXJ2aWNlKHsgcHJlZml4OiAncGx1Z2luOicsIGRlZmF1bHRUdGxTZWNvbmRzOiAzMDAgfSk7XG4gKlxuICogLy8gU2V0IHdpdGggZGVmYXVsdCBUVExcbiAqIGF3YWl0IGNhY2hlLnNldCgnb3JnMTIzOmxpc3QnLCBwbHVnaW5zKTtcbiAqXG4gKiAvLyBHZXQgKHJldHVybnMgbnVsbCBvbiBtaXNzKVxuICogY29uc3QgY2FjaGVkID0gYXdhaXQgY2FjaGUuZ2V0PFBsdWdpbltdPignb3JnMTIzOmxpc3QnKTtcbiAqXG4gKiAvLyBJbnZhbGlkYXRlXG4gKiBhd2FpdCBjYWNoZS5kZWwoJ29yZzEyMzpsaXN0Jyk7XG4gKlxuICogLy8gSW52YWxpZGF0ZSBieSBwYXR0ZXJuXG4gKiBhd2FpdCBjYWNoZS5pbnZhbGlkYXRlUGF0dGVybignb3JnMTIzOionKTtcbiAqIGBgYFxuICovXG5leHBvcnQgY2xhc3MgQ2FjaGVTZXJ2aWNlIHtcbiAgcHJpdmF0ZSBtZW1vcnkgPSBuZXcgTWFwPHN0cmluZywgQ2FjaGVFbnRyeTx1bmtub3duPj4oKTtcbiAgLyoqXG4gICAqIEluLWZsaWdodCBgZ2V0T3JTZXRgIGZhY3RvcnkgcHJvbWlzZXMsIGtleWVkIGJ5IGZ1bGwgY2FjaGUga2V5LiBDb2FsZXNjZXNcbiAgICogY29uY3VycmVudCBjb2xkIGNhbGxlcnMgb250byBhIHNpbmdsZSBgZmFjdG9yeSgpYCBpbnZvY2F0aW9uIChzaW5nbGUtZmxpZ2h0XG4gICAqIC8gc3RhbXBlZGUgcHJvdGVjdGlvbik7IGVudHJpZXMgYXJlIGNsZWFyZWQgb25jZSB0aGUgcHJvbWlzZSBzZXR0bGVzLlxuICAgKi9cbiAgcHJpdmF0ZSBpbmZsaWdodCA9IG5ldyBNYXA8c3RyaW5nLCBQcm9taXNlPHVua25vd24+PigpO1xuICBwcml2YXRlIHJlYWRvbmx5IHByZWZpeDogc3RyaW5nO1xuICBwcml2YXRlIHJlYWRvbmx5IGRlZmF1bHRUdGxNczogbnVtYmVyO1xuICBwcml2YXRlIHJlYWRvbmx5IG1heEVudHJpZXM6IG51bWJlcjtcbiAgcHJpdmF0ZSByZWFkb25seSBidXM6IENhY2hlSW52YWxpZGF0aW9uQnVzIHwgbnVsbDtcbiAgcHJpdmF0ZSByZWFkb25seSBpbnN0YW5jZUlkID0gcmFuZG9tVVVJRCgpO1xuICAvKipcbiAgICogQnVtcGVkIG9uIEVWRVJZIGludmFsaWRhdGlvbiAobG9jYWwgb3IgcmVtb3RlKS4gYGdldE9yU2V0YCBvbmx5IGNhY2hlcyBhXG4gICAqIGZhY3RvcnkgcmVzdWx0IGlmIG5vIGludmFsaWRhdGlvbiBoYXBwZW5lZCB3aGlsZSB0aGUgZmFjdG9yeSByYW4g4oCUIG90aGVyd2lzZVxuICAgKiBpdCBjb3VsZCByZS1jYWNoZSBhIHZhbHVlIHJlYWQgYmVmb3JlIHRoZSB3cml0ZSB0aGF0IGludmFsaWRhdGVkIGl0LlxuICAgKi9cbiAgcHJpdmF0ZSBnZW5lcmF0aW9uID0gMDtcblxuICAvKiogQ2FjaGUgbWV0cmljcyDigJQgdHJhY2tzIGhpdHMsIG1pc3NlcywgYW5kIGludmFsaWRhdGlvbnMuICovXG4gIHJlYWRvbmx5IG1ldHJpY3MgPSB7IGhpdHM6IDAsIG1pc3NlczogMCwgc2V0czogMCwgaW52YWxpZGF0aW9uczogMCB9O1xuXG4gIGNvbnN0cnVjdG9yKGNvbmZpZzogQ2FjaGVDb25maWcpIHtcbiAgICB0aGlzLnByZWZpeCA9IGNvbmZpZy5wcmVmaXg7XG4gICAgdGhpcy5kZWZhdWx0VHRsTXMgPSBjb25maWcuZGVmYXVsdFR0bFNlY29uZHMgKiAxMDAwO1xuICAgIHRoaXMubWF4RW50cmllcyA9IGNvbmZpZy5tYXhFbnRyaWVzID8/IDEwMDA7XG4gICAgdGhpcy5idXMgPSBjb25maWcuaW52YWxpZGF0aW9uQnVzID09PSB1bmRlZmluZWQgPyBnZXRFbnZDYWNoZUludmFsaWRhdGlvbkJ1cygpIDogY29uZmlnLmludmFsaWRhdGlvbkJ1cztcbiAgICB0aGlzLmJ1cz8uc3Vic2NyaWJlKFxuICAgICAgKG1zZykgPT4ge1xuICAgICAgICBpZiAobXNnLm9yaWdpbiA9PT0gdGhpcy5pbnN0YW5jZUlkIHx8IG1zZy5wcmVmaXggIT09IHRoaXMucHJlZml4KSByZXR1cm47XG4gICAgICAgIHRoaXMuYXBwbHlMb2NhbEludmFsaWRhdGlvbihtc2cub3AsIG1zZy5rZXkpO1xuICAgICAgfSxcbiAgICAgICgpID0+IHRoaXMuYXBwbHlMb2NhbEludmFsaWRhdGlvbignY2xlYXInKSxcbiAgICApO1xuICB9XG5cbiAgLyoqIEJyb2FkY2FzdCBhbiBpbnZhbGlkYXRpb24gdG8gdGhlIG90aGVyIHJlcGxpY2FzLiAqL1xuICBwcml2YXRlIGJyb2FkY2FzdChvcDogQ2FjaGVJbnZhbGlkYXRpb25NZXNzYWdlWydvcCddLCBrZXk/OiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLmJ1cz8ucHVibGlzaCh7IG9yaWdpbjogdGhpcy5pbnN0YW5jZUlkLCBwcmVmaXg6IHRoaXMucHJlZml4LCBvcCwgLi4uKGtleSAhPT0gdW5kZWZpbmVkICYmIHsga2V5IH0pIH0pO1xuICB9XG5cbiAgLyoqIEFwcGx5IGFuIGludmFsaWRhdGlvbiB0byBUSElTIHByb2Nlc3MncyBpbi1tZW1vcnkgZW50cmllcy4gUmV0dXJucyB0aGUgY291bnQgcmVtb3ZlZC4gKi9cbiAgcHJpdmF0ZSBhcHBseUxvY2FsSW52YWxpZGF0aW9uKG9wOiBDYWNoZUludmFsaWRhdGlvbk1lc3NhZ2VbJ29wJ10sIGtleT86IHN0cmluZyk6IG51bWJlciB7XG4gICAgdGhpcy5nZW5lcmF0aW9uKys7XG4gICAgaWYgKG9wID09PSAnY2xlYXInKSB7XG4gICAgICBjb25zdCBuID0gdGhpcy5tZW1vcnkuc2l6ZTtcbiAgICAgIHRoaXMubWVtb3J5LmNsZWFyKCk7XG4gICAgICByZXR1cm4gbjtcbiAgICB9XG4gICAgaWYgKG9wID09PSAnZGVsJykge1xuICAgICAgcmV0dXJuIHRoaXMubWVtb3J5LmRlbGV0ZSh0aGlzLmZ1bGxLZXkoa2V5ID8/ICcnKSkgPyAxIDogMDtcbiAgICB9XG4gICAgLy8gR2xvYiBwYXR0ZXJuLiBFc2NhcGUgcmVnZXggbWV0YWNoYXJhY3RlcnMgZmlyc3Qgc28gYSBsaXRlcmFsIGAuYC9gKGAvYFtgXG4gICAgLy8gaW4gYSBrZXkgcHJlZml4IChlLmcuIGBvcmc6djEuMjoqYCkgY2FuJ3Qgb3Zlci1tYXRjaCBvciB0aHJvdyAoYSB0aHJvd1xuICAgIC8vIGhlcmUgd291bGQgbGVhdmUgZW50cmllcyBzdGFsZSk7IG9ubHkgYCpgIGlzIHRyZWF0ZWQgYXMgYSB3aWxkY2FyZC5cbiAgICBjb25zdCBmcCA9IHRoaXMuZnVsbEtleShrZXkgPz8gJycpO1xuICAgIGNvbnN0IHJlZ2V4ID0gbmV3IFJlZ0V4cCgnXicgKyBmcC5yZXBsYWNlKC9bLiorP14ke30oKXxbXFxdXFxcXF0vZywgJ1xcXFwkJicpLnJlcGxhY2UoL1xcXFxcXCovZywgJy4qJykgKyAnJCcpO1xuICAgIGxldCBkZWxldGVkID0gMDtcbiAgICBmb3IgKGNvbnN0IGsgb2YgdGhpcy5tZW1vcnkua2V5cygpKSB7XG4gICAgICBpZiAocmVnZXgudGVzdChrKSkge1xuICAgICAgICB0aGlzLm1lbW9yeS5kZWxldGUoayk7XG4gICAgICAgIGRlbGV0ZWQrKztcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGRlbGV0ZWQ7XG4gIH1cblxuICBwcml2YXRlIGZ1bGxLZXkoa2V5OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiBgJHt0aGlzLnByZWZpeH0ke2tleX1gO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBhIGNhY2hlZCB2YWx1ZS4gUmV0dXJucyBudWxsIG9uIG1pc3Mgb3IgZXJyb3IuXG4gICAqXG4gICAqIFRoZSByZXR1cm5lZCB2YWx1ZSBpcyBhbiBJTkRFUEVOREVOVCBkZWVwIGNvcHkg4oCUIG11dGF0aW5nIGl0IG5ldmVyIGFmZmVjdHNcbiAgICogdGhlIGNhY2hlZCBlbnRyeS5cbiAgICovXG4gIGFzeW5jIGdldDxUPihrZXk6IHN0cmluZyk6IFByb21pc2U8VCB8IG51bGw+IHtcbiAgICBjb25zdCBmayA9IHRoaXMuZnVsbEtleShrZXkpO1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGVudHJ5ID0gdGhpcy5tZW1vcnkuZ2V0KGZrKTtcbiAgICAgIGlmICghZW50cnkpIHsgdGhpcy5tZXRyaWNzLm1pc3NlcysrOyByZXR1cm4gbnVsbDsgfVxuICAgICAgaWYgKERhdGUubm93KCkgPiBlbnRyeS5leHBpcmVzQXQpIHtcbiAgICAgICAgdGhpcy5tZW1vcnkuZGVsZXRlKGZrKTtcbiAgICAgICAgdGhpcy5tZXRyaWNzLm1pc3NlcysrO1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICAgIC8vIExSVSB0b3VjaDogZGVsZXRlICsgcmUtaW5zZXJ0IG1vdmVzIHRoaXMga2V5IHRvIHRoZSBuZXdlc3QgcG9zaXRpb25cbiAgICAgIC8vIChNYXAgcHJlc2VydmVzIGluc2VydGlvbiBvcmRlciksIHNvIGBzZXRgJ3Mgb2xkZXN0LWZpcnN0IGV2aWN0aW9uIGlzIGFcbiAgICAgIC8vIHRydWUgbGVhc3QtcmVjZW50bHktVVNFRCBldmljdGlvbiByYXRoZXIgdGhhbiBmaXJzdC1pbnNlcnRlZCAoRklGTykuXG4gICAgICB0aGlzLm1lbW9yeS5kZWxldGUoZmspO1xuICAgICAgdGhpcy5tZW1vcnkuc2V0KGZrLCBlbnRyeSk7XG4gICAgICB0aGlzLm1ldHJpY3MuaGl0cysrO1xuICAgICAgLy8gQ2xvbmUgc28gYSBjYWxsZXIgbXV0YXRpbmcgdGhlIHJlc3VsdCBjYW4ndCBjb3JydXB0IHRoZSBzaGFyZWQgZW50cnkuXG4gICAgICByZXR1cm4gY2xvbmVWYWx1ZShlbnRyeS52YWx1ZSkgYXMgVDtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHRoaXMubWV0cmljcy5taXNzZXMrKztcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBTZXQgYSBjYWNoZWQgdmFsdWUgd2l0aCBvcHRpb25hbCBUVEwgb3ZlcnJpZGUuXG4gICAqXG4gICAqIEBwYXJhbSBrZXkgLSBDYWNoZSBrZXkgKHByZWZpeCBpcyBhZGRlZCBhdXRvbWF0aWNhbGx5KVxuICAgKiBAcGFyYW0gdmFsdWUgLSBWYWx1ZSB0byBjYWNoZVxuICAgKiBAcGFyYW0gdHRsU2Vjb25kcyAtIFRUTCBvdmVycmlkZSAodXNlcyBkZWZhdWx0IGlmIG5vdCBwcm92aWRlZClcbiAgICovXG4gIGFzeW5jIHNldDxUPihrZXk6IHN0cmluZywgdmFsdWU6IFQsIHR0bFNlY29uZHM/OiBudW1iZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBmayA9IHRoaXMuZnVsbEtleShrZXkpO1xuICAgIGNvbnN0IHR0bCA9IHR0bFNlY29uZHMgPz8gdGhpcy5kZWZhdWx0VHRsTXMgLyAxMDAwO1xuXG4gICAgdHJ5IHtcbiAgICAgIHRoaXMubWV0cmljcy5zZXRzKys7XG4gICAgICAvLyBBIHdyaXRlIGNvdW50cyBhcyBhIHVzZSwgc28gZHJvcCBhbnkgZXhpc3RpbmcgZW50cnkgZmlyc3RcbiAgICAgIC8vIGFuZCByZS1pbnNlcnQgYmVsb3cgYXMgdGhlIG5ld2VzdCAoTWFwIHByZXNlcnZlcyBpbnNlcnRpb24gb3JkZXIpLiBUaGlzXG4gICAgICAvLyBrZWVwcyB0aGUgTWFwIG9yZGVyZWQgb2xkZXN0LVVTRUQg4oaSIG5ld2VzdC1VU0VEIHNvIHRoZSBldmljdGlvbiBiZWxvdyBpc1xuICAgICAgLy8gdHJ1ZSBMUlUsIGFuZCBhdm9pZHMgZXZpY3RpbmcgYSB2aWN0aW0gd2hlbiBtZXJlbHkgdXBkYXRpbmcgYSBrZXkuXG4gICAgICB0aGlzLm1lbW9yeS5kZWxldGUoZmspO1xuICAgICAgaWYgKHRoaXMubWVtb3J5LnNpemUgPj0gdGhpcy5tYXhFbnRyaWVzKSB7XG4gICAgICAgIGNvbnN0IGZpcnN0S2V5ID0gdGhpcy5tZW1vcnkua2V5cygpLm5leHQoKS52YWx1ZTtcbiAgICAgICAgaWYgKGZpcnN0S2V5KSB0aGlzLm1lbW9yeS5kZWxldGUoZmlyc3RLZXkpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLm1lbW9yeS5zZXQoZmssIHtcbiAgICAgICAgdmFsdWUsXG4gICAgICAgIGV4cGlyZXNBdDogRGF0ZS5ub3coKSArIHR0bCAqIDEwMDAsXG4gICAgICB9KTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIC8vIENhY2hlIHNldCBmYWlsdXJlIGlzIG5vbi1mYXRhbFxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBEZWxldGUgYSBjYWNoZWQgdmFsdWUuXG4gICAqL1xuICBhc3luYyBkZWwoa2V5OiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0cnkge1xuICAgICAgdGhpcy5hcHBseUxvY2FsSW52YWxpZGF0aW9uKCdkZWwnLCBrZXkpO1xuICAgICAgdGhpcy5icm9hZGNhc3QoJ2RlbCcsIGtleSk7XG4gICAgfSBjYXRjaCB7XG4gICAgICAvLyBDYWNoZSBkZWxldGUgZmFpbHVyZSBpcyBub24tZmF0YWxcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogSW52YWxpZGF0ZSBhbGwga2V5cyBtYXRjaGluZyBhIHBhdHRlcm4gKGUuZy4sICdvcmcxMjM6KicpLlxuICAgKiBPbmx5IGAqYCBpcyBhIHdpbGRjYXJkLlxuICAgKi9cbiAgYXN5bmMgaW52YWxpZGF0ZVBhdHRlcm4ocGF0dGVybjogc3RyaW5nKTogUHJvbWlzZTxudW1iZXI+IHtcbiAgICB0cnkge1xuICAgICAgLy8gQXBwbHkgbG9jYWxseSwgdGhlbiBmYW4gb3V0IHRvIHRoZSBvdGhlciByZXBsaWNhcy5cbiAgICAgIGNvbnN0IGRlbGV0ZWQgPSB0aGlzLmFwcGx5TG9jYWxJbnZhbGlkYXRpb24oJ3BhdHRlcm4nLCBwYXR0ZXJuKTtcbiAgICAgIHRoaXMuYnJvYWRjYXN0KCdwYXR0ZXJuJywgcGF0dGVybik7XG4gICAgICB0aGlzLm1ldHJpY3MuaW52YWxpZGF0aW9ucyArPSBkZWxldGVkO1xuICAgICAgcmV0dXJuIGRlbGV0ZWQ7XG4gICAgfSBjYXRjaCB7XG4gICAgICByZXR1cm4gMDtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogR2V0IG9yIGNvbXB1dGU6IHJldHVybnMgY2FjaGVkIHZhbHVlIGlmIGF2YWlsYWJsZSwgb3RoZXJ3aXNlIGNhbGxzIHRoZVxuICAgKiBmYWN0b3J5IGZ1bmN0aW9uLCBjYWNoZXMgdGhlIHJlc3VsdCwgYW5kIHJldHVybnMgaXQuXG4gICAqXG4gICAqIFNpbmdsZS1mbGlnaHQgLyBzdGFtcGVkZSBwcm90ZWN0aW9uOiB3aGVuIE4gY2FsbGVycyBtaXNzIGNvbmN1cnJlbnRseSBmb3JcbiAgICogdGhlIHNhbWUga2V5LCBvbmx5IE9ORSBgZmFjdG9yeSgpYCBydW5zIOKAlCB0aGUgcmVzdCBhd2FpdCBpdHMgc2hhcmVkIHByb21pc2UuXG4gICAqIFRoZSBpbi1mbGlnaHQgZW50cnkgaXMgY2xlYXJlZCBvbmNlIGl0IHNldHRsZXMgKHN1Y2Nlc3Mgb3IgZmFpbHVyZSksIHNvIGFcbiAgICogZmFpbGVkIGZhY3RvcnkgZG9lc24ndCBwb2lzb24gbGF0ZXIgY2FsbHMuXG4gICAqXG4gICAqIEBwYXJhbSBrZXkgLSBDYWNoZSBrZXlcbiAgICogQHBhcmFtIGZhY3RvcnkgLSBBc3luYyBmdW5jdGlvbiB0byBjb21wdXRlIHRoZSB2YWx1ZSBvbiBjYWNoZSBtaXNzXG4gICAqIEBwYXJhbSB0dGxTZWNvbmRzIC0gT3B0aW9uYWwgVFRMIG92ZXJyaWRlXG4gICAqIEByZXR1cm5zIFRoZSBjYWNoZWQgb3IgY29tcHV0ZWQgdmFsdWVcbiAgICovXG4gIGFzeW5jIGdldE9yU2V0PFQ+KGtleTogc3RyaW5nLCBmYWN0b3J5OiAoKSA9PiBQcm9taXNlPFQ+LCB0dGxTZWNvbmRzPzogbnVtYmVyKTogUHJvbWlzZTxUPiB7XG4gICAgY29uc3QgY2FjaGVkID0gYXdhaXQgdGhpcy5nZXQ8VD4oa2V5KTtcbiAgICBpZiAoY2FjaGVkICE9PSBudWxsKSByZXR1cm4gY2FjaGVkO1xuXG4gICAgY29uc3QgZmsgPSB0aGlzLmZ1bGxLZXkoa2V5KTtcbiAgICAvLyBDb2FsZXNjZSBjb25jdXJyZW50IGNvbGQgY2FsbGVycyBvbnRvIGEgc2luZ2xlIGZhY3RvcnkoKSBpbnZvY2F0aW9uLiBUaGVcbiAgICAvLyBpbi1mbGlnaHQgcHJvbWlzZSByZXNvbHZlcyB0byB0aGUgUkFXIHZhbHVlOyBlYWNoIGF3YWl0ZXIgKHRoZSBwcmltYXJ5XG4gICAgLy8gY2FsbGVyIGJlbG93IEFORCBldmVyeSBjb2FsZXNjZWQgY2FsbGVyIGhlcmUpIGNsb25lcyBpdCBJTkRFUEVOREVOVExZLlxuICAgIC8vIENsb25pbmcgaW5zaWRlIHRoZSBmbGlnaHQgaW5zdGVhZCB3b3VsZCBoYW5kIG9uZSBzaGFyZWQgY2xvbmUgdG8gYWxsIE5cbiAgICAvLyBjb2FsZXNjZWQgY2FsbGVycywgc28gb25lIGNhbGxlciBtdXRhdGluZyBpdHMgXCJpbmRlcGVuZGVudFwiIHJlc3VsdCB3b3VsZFxuICAgIC8vIGNvcnJ1cHQgd2hhdCB0aGUgb3RoZXJzIHJlYWQg4oCUIHRoZSBleGFjdCBmb290Z3VuIGdldCgpJ3MgY2xvbmUtb24tcmVhZFxuICAgIC8vIHByZXZlbnRzLlxuICAgIGNvbnN0IGV4aXN0aW5nID0gdGhpcy5pbmZsaWdodC5nZXQoZmspIGFzIFByb21pc2U8VD4gfCB1bmRlZmluZWQ7XG4gICAgaWYgKGV4aXN0aW5nKSByZXR1cm4gY2xvbmVWYWx1ZShhd2FpdCBleGlzdGluZyk7XG5cbiAgICBjb25zdCBnZW5lcmF0aW9uQXRTdGFydCA9IHRoaXMuZ2VuZXJhdGlvbjtcbiAgICBjb25zdCBmbGlnaHQgPSAoYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgdmFsdWUgPSBhd2FpdCBmYWN0b3J5KCk7XG4gICAgICAvLyBBbiBpbnZhbGlkYXRpb24gKGhlcmUgb3Igb24gYW5vdGhlciByZXBsaWNhKSBsYW5kZWQgd2hpbGUgdGhlIGZhY3RvcnlcbiAgICAgIC8vIHJhbjogaXRzIHJlYWQgbWF5IHByZWRhdGUgdGhhdCB3cml0ZSwgc28gZG9uJ3QgY2FjaGUgaXQuXG4gICAgICBpZiAodGhpcy5nZW5lcmF0aW9uID09PSBnZW5lcmF0aW9uQXRTdGFydCkgYXdhaXQgdGhpcy5zZXQoa2V5LCB2YWx1ZSwgdHRsU2Vjb25kcyk7XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfSkoKTtcbiAgICB0aGlzLmluZmxpZ2h0LnNldChmaywgZmxpZ2h0KTtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGNsb25lVmFsdWUoYXdhaXQgZmxpZ2h0KTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgdGhpcy5pbmZsaWdodC5kZWxldGUoZmspO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDbGVhciBhbGwgZW50cmllcyAodXNlZnVsIGZvciB0ZXN0aW5nKS5cbiAgICovXG4gIGFzeW5jIGNsZWFyKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRoaXMuYXBwbHlMb2NhbEludmFsaWRhdGlvbignY2xlYXInKTtcbiAgICB0aGlzLmJyb2FkY2FzdCgnY2xlYXInKTtcbiAgfVxuXG4gIC8qKiBDdXJyZW50IGluLW1lbW9yeSBjYWNoZSBzaXplIChmb3IgZGlhZ25vc3RpY3MpLiAqL1xuICBnZXQgc2l6ZSgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLm1lbW9yeS5zaXplO1xuICB9XG59XG5cbi8qKlxuICogQ3JlYXRlIGEgY2FjaGUgc2VydmljZSBpbnN0YW5jZS5cbiAqXG4gKiBAcGFyYW0gcHJlZml4IC0gTmFtZXNwYWNlIHByZWZpeCAoZS5nLiwgJ2NvbXBsaWFuY2U6JywgJ3BsdWdpbjonKVxuICogQHBhcmFtIGRlZmF1bHRUdGxTZWNvbmRzIC0gRGVmYXVsdCBUVEwgaW4gc2Vjb25kcyAoZGVmYXVsdCAzMDAgPSA1IG1pbilcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUNhY2hlU2VydmljZShwcmVmaXg6IHN0cmluZywgZGVmYXVsdFR0bFNlY29uZHMgPSAzMDApOiBDYWNoZVNlcnZpY2Uge1xuICByZXR1cm4gbmV3IENhY2hlU2VydmljZSh7IHByZWZpeCwgZGVmYXVsdFR0bFNlY29uZHMgfSk7XG59XG4iXX0=
@@ -8,9 +8,10 @@ import { type ServiceConfig } from '../types/common.js';
8
8
  *
9
9
  * @param config - Optional service config override (defaults to COMPLIANCE_SERVICE_HOST/PORT env vars)
10
10
  * @param serviceName - Service identifier baked into the signed JWT's `sub`
11
- * (e.g. 'pipeline', 'plugin'). The compliance route requires a service
12
- * principal — a spoofable `x-internal-service: true` header is no longer
13
- * accepted. Defaults to a generic 'entity-events' when unspecified, but
14
- * callers should pass their service name for accurate audit trails.
11
+ * (e.g. 'pipeline', 'plugin'). The compliance route is an INTERNAL route: it
12
+ * admits only those two services' own signed tokens, and no user token.
13
+ * Defaults to THIS process's identity (`SERVICE_NAME`) — since #14 a service
14
+ * holds only its own signing key, so a placeholder name would mint a token no
15
+ * peer could verify.
15
16
  */
16
17
  export declare function registerComplianceEventSubscriber(config?: Partial<ServiceConfig>, serviceName?: string): void;
@@ -2,6 +2,7 @@
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
  import { entityEvents } from './entity-events.js';
4
4
  import { InternalHttpClient } from './http-client.js';
5
+ import { serviceIdentity } from './service-keys.js';
5
6
  import { getServiceAuthHeader } from '../middleware/auth.js';
6
7
  import {} from '../types/common.js';
7
8
  import { createLogger } from '../utils/logger.js';
@@ -16,12 +17,13 @@ const logger = createLogger('compliance-events');
16
17
  *
17
18
  * @param config - Optional service config override (defaults to COMPLIANCE_SERVICE_HOST/PORT env vars)
18
19
  * @param serviceName - Service identifier baked into the signed JWT's `sub`
19
- * (e.g. 'pipeline', 'plugin'). The compliance route requires a service
20
- * principal — a spoofable `x-internal-service: true` header is no longer
21
- * accepted. Defaults to a generic 'entity-events' when unspecified, but
22
- * callers should pass their service name for accurate audit trails.
20
+ * (e.g. 'pipeline', 'plugin'). The compliance route is an INTERNAL route: it
21
+ * admits only those two services' own signed tokens, and no user token.
22
+ * Defaults to THIS process's identity (`SERVICE_NAME`) — since #14 a service
23
+ * holds only its own signing key, so a placeholder name would mint a token no
24
+ * peer could verify.
23
25
  */
24
- export function registerComplianceEventSubscriber(config, serviceName = 'entity-events') {
26
+ export function registerComplianceEventSubscriber(config, serviceName = serviceIdentity()) {
25
27
  const serviceConfig = {
26
28
  host: config?.host ?? process.env.COMPLIANCE_SERVICE_HOST ?? 'compliance',
27
29
  port: config?.port ?? parseInt(process.env.COMPLIANCE_SERVICE_PORT ?? '3000', 10),
@@ -69,4 +71,4 @@ export function registerComplianceEventSubscriber(config, serviceName = 'entity-
69
71
  port: serviceConfig.port,
70
72
  });
71
73
  }
72
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcGxpYW5jZS1ldmVudC1zdWJzY3JpYmVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3NlcnZpY2VzL2NvbXBsaWFuY2UtZXZlbnQtc3Vic2NyaWJlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwrQ0FBK0M7QUFDL0Msc0NBQXNDO0FBRXRDLE9BQU8sRUFBRSxZQUFZLEVBQWdELE1BQU0sb0JBQW9CLENBQUM7QUFDaEcsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDdEQsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDN0QsT0FBTyxFQUFzQixNQUFNLG9CQUFvQixDQUFDO0FBQ3hELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNsRCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFFekQsTUFBTSxNQUFNLEdBQUcsWUFBWSxDQUFDLG1CQUFtQixDQUFDLENBQUM7QUFFakQ7Ozs7Ozs7Ozs7Ozs7R0FhRztBQUNILE1BQU0sVUFBVSxpQ0FBaUMsQ0FDL0MsTUFBK0IsRUFDL0IsV0FBVyxHQUFXLGVBQWU7SUFFckMsTUFBTSxhQUFhLEdBQWtCO1FBQ25DLElBQUksRUFBRSxNQUFNLEVBQUUsSUFBSSxJQUFJLE9BQU8sQ0FBQyxHQUFHLENBQUMsdUJBQXVCLElBQUksWUFBWTtRQUN6RSxJQUFJLEVBQUUsTUFBTSxFQUFFLElBQUksSUFBSSxRQUFRLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyx1QkFBdUIsSUFBSSxNQUFNLEVBQUUsRUFBRSxDQUFDO0tBQ2xGLENBQUM7SUFFRixNQUFNLE1BQU0sR0FBRyxJQUFJLGtCQUFrQixDQUFDLGFBQWEsQ0FBQyxDQUFDO0lBRXJELE1BQU0sVUFBVSxHQUEwQjtRQUN4QyxLQUFLLENBQUMsYUFBYSxDQUFDLEtBQWtCO1lBQ3BDLElBQUksQ0FBQztnQkFDSCxnRUFBZ0U7Z0JBQ2hFLGtFQUFrRTtnQkFDbEUsb0RBQW9EO2dCQUNwRCxnRUFBZ0U7Z0JBQ2hFLHNEQUFzRDtnQkFDdEQsRUFBRTtnQkFDRixvRUFBb0U7Z0JBQ3BFLDZEQUE2RDtnQkFDN0Qsc0VBQXNFO2dCQUN0RSx1RUFBdUU7Z0JBQ3ZFLHdFQUF3RTtnQkFDeEUsNkRBQTZEO2dCQUM3RCxNQUFNLE1BQU0sQ0FBQyxJQUFJLENBQUMsMkJBQTJCLEVBQUUsS0FBSyxFQUFFO29CQUNwRCxPQUFPLEVBQUU7d0JBQ1AsZUFBZSxFQUFFLG9CQUFvQixDQUFDLEVBQUUsV0FBVyxFQUFFLEtBQUssRUFBRSxLQUFLLENBQUMsS0FBSyxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsQ0FBQzt3QkFDMUYsaUJBQWlCLEVBQUUsR0FBRyxLQUFLLENBQUMsTUFBTSxJQUFJLEtBQUssQ0FBQyxRQUFRLElBQUksS0FBSyxDQUFDLFNBQVMsSUFBSSxLQUFLLENBQUMsU0FBUyxDQUFDLFdBQVcsRUFBRSxFQUFFO3FCQUMzRztpQkFDRixDQUFDLENBQUM7WUFDTCxDQUFDO1lBQUMsT0FBTyxHQUFHLEVBQUUsQ0FBQztnQkFDYixzRUFBc0U7Z0JBQ3RFLHdFQUF3RTtnQkFDeEUseURBQXlEO2dCQUN6RCxXQUFXLENBQUMsNkJBQTZCLEVBQUUsRUFBRSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sRUFBRSxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQztnQkFDM0YsTUFBTSxDQUFDLElBQUksQ0FBQyxxREFBcUQsRUFBRTtvQkFDakUsTUFBTSxFQUFFLEtBQUssQ0FBQyxNQUFNO29CQUNwQixTQUFTLEVBQUUsS0FBSyxDQUFDLFNBQVM7b0JBQzFCLFFBQVEsRUFBRSxLQUFLLENBQUMsUUFBUTtvQkFDeEIsS0FBSyxFQUFFLEdBQUcsWUFBWSxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUM7aUJBQ3hELENBQUMsQ0FBQztZQUNMLENBQUM7UUFDSCxDQUFDO0tBQ0YsQ0FBQztJQUVGLFlBQVksQ0FBQyxTQUFTLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDbkMsTUFBTSxDQUFDLElBQUksQ0FBQyx3Q0FBd0MsRUFBRTtRQUNwRCxJQUFJLEVBQUUsYUFBYSxDQUFDLElBQUk7UUFDeEIsSUFBSSxFQUFFLGFBQWEsQ0FBQyxJQUFJO0tBQ3pCLENBQUMsQ0FBQztBQUNMLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuaW1wb3J0IHsgZW50aXR5RXZlbnRzLCB0eXBlIEVudGl0eUV2ZW50LCB0eXBlIEVudGl0eUV2ZW50U3Vic2NyaWJlciB9IGZyb20gJy4vZW50aXR5LWV2ZW50cy5qcyc7XG5pbXBvcnQgeyBJbnRlcm5hbEh0dHBDbGllbnQgfSBmcm9tICcuL2h0dHAtY2xpZW50LmpzJztcbmltcG9ydCB7IGdldFNlcnZpY2VBdXRoSGVhZGVyIH0gZnJvbSAnLi4vbWlkZGxld2FyZS9hdXRoLmpzJztcbmltcG9ydCB7IHR5cGUgU2VydmljZUNvbmZpZyB9IGZyb20gJy4uL3R5cGVzL2NvbW1vbi5qcyc7XG5pbXBvcnQgeyBjcmVhdGVMb2dnZXIgfSBmcm9tICcuLi91dGlscy9sb2dnZXIuanMnO1xuaW1wb3J0IHsgZW1pdENvdW50ZXIgfSBmcm9tICcuLi91dGlscy9tZXRyaWMtZW1pdHRlci5qcyc7XG5cbmNvbnN0IGxvZ2dlciA9IGNyZWF0ZUxvZ2dlcignY29tcGxpYW5jZS1ldmVudHMnKTtcblxuLyoqXG4gKiBSZWdpc3RlcnMgYW4gZW50aXR5IGV2ZW50IHN1YnNjcmliZXIgdGhhdCBmb3J3YXJkcyBldmVudHMgdG8gdGhlIGNvbXBsaWFuY2Ugc2VydmljZS5cbiAqXG4gKiBDYWxsIHRoaXMgYXQgc2VydmljZSBzdGFydHVwIChpbiBpbmRleC50cykgdG8gZW5hYmxlIGF1dG9tYXRpYyBjb21wbGlhbmNlXG4gKiBub3RpZmljYXRpb24gb24gZW50aXR5IG11dGF0aW9ucy4gRXZlbnRzIGFyZSBmaXJlLWFuZC1mb3JnZXQg4oCUIGZhaWx1cmVzXG4gKiBhcmUgbG9nZ2VkIGJ1dCBuZXZlciBibG9jayB0aGUgb3JpZ2luYWwgcmVxdWVzdC5cbiAqXG4gKiBAcGFyYW0gY29uZmlnIC0gT3B0aW9uYWwgc2VydmljZSBjb25maWcgb3ZlcnJpZGUgKGRlZmF1bHRzIHRvIENPTVBMSUFOQ0VfU0VSVklDRV9IT1NUL1BPUlQgZW52IHZhcnMpXG4gKiBAcGFyYW0gc2VydmljZU5hbWUgLSBTZXJ2aWNlIGlkZW50aWZpZXIgYmFrZWQgaW50byB0aGUgc2lnbmVkIEpXVCdzIGBzdWJgXG4gKiAgIChlLmcuICdwaXBlbGluZScsICdwbHVnaW4nKS4gVGhlIGNvbXBsaWFuY2Ugcm91dGUgcmVxdWlyZXMgYSBzZXJ2aWNlXG4gKiAgIHByaW5jaXBhbCDigJQgYSBzcG9vZmFibGUgYHgtaW50ZXJuYWwtc2VydmljZTogdHJ1ZWAgaGVhZGVyIGlzIG5vIGxvbmdlclxuICogICBhY2NlcHRlZC4gRGVmYXVsdHMgdG8gYSBnZW5lcmljICdlbnRpdHktZXZlbnRzJyB3aGVuIHVuc3BlY2lmaWVkLCBidXRcbiAqICAgY2FsbGVycyBzaG91bGQgcGFzcyB0aGVpciBzZXJ2aWNlIG5hbWUgZm9yIGFjY3VyYXRlIGF1ZGl0IHRyYWlscy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlZ2lzdGVyQ29tcGxpYW5jZUV2ZW50U3Vic2NyaWJlcihcbiAgY29uZmlnPzogUGFydGlhbDxTZXJ2aWNlQ29uZmlnPixcbiAgc2VydmljZU5hbWU6IHN0cmluZyA9ICdlbnRpdHktZXZlbnRzJyxcbik6IHZvaWQge1xuICBjb25zdCBzZXJ2aWNlQ29uZmlnOiBTZXJ2aWNlQ29uZmlnID0ge1xuICAgIGhvc3Q6IGNvbmZpZz8uaG9zdCA/PyBwcm9jZXNzLmVudi5DT01QTElBTkNFX1NFUlZJQ0VfSE9TVCA/PyAnY29tcGxpYW5jZScsXG4gICAgcG9ydDogY29uZmlnPy5wb3J0ID8/IHBhcnNlSW50KHByb2Nlc3MuZW52LkNPTVBMSUFOQ0VfU0VSVklDRV9QT1JUID8/ICczMDAwJywgMTApLFxuICB9O1xuXG4gIGNvbnN0IGNsaWVudCA9IG5ldyBJbnRlcm5hbEh0dHBDbGllbnQoc2VydmljZUNvbmZpZyk7XG5cbiAgY29uc3Qgc3Vic2NyaWJlcjogRW50aXR5RXZlbnRTdWJzY3JpYmVyID0ge1xuICAgIGFzeW5jIG9uRW50aXR5RXZlbnQoZXZlbnQ6IEVudGl0eUV2ZW50KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICB0cnkge1xuICAgICAgICAvLyBNaW50IGEgcGVyLWV2ZW50IHNlcnZpY2UgSldUIHNjb3BlZCB0byB0aGUgZXZlbnQncyBvcmcgc28gdGhlXG4gICAgICAgIC8vIGNvbXBsaWFuY2Ugcm91dGUncyBgcnVuV2l0aFRlbmFudENvbnRleHRgIHNlZXMgdGhlIHJpZ2h0IHRlbmFudFxuICAgICAgICAvLyBHVUMuIFRoZSBjb21wbGlhbmNlIHNpZGUgZW5mb3JjZXMgYHJlcXVpcmVBdXRoYCArXG4gICAgICAgIC8vIGByZXF1aXJlU2VydmljZVByaW5jaXBhbGAg4oCUIHRoZSBwcmV2aW91cyBgeC1pbnRlcm5hbC1zZXJ2aWNlYFxuICAgICAgICAvLyBoZWFkZXIgaXMgbm8gbG9uZ2VyIHN1ZmZpY2llbnQgKGFuZCB3YXMgc3Bvb2ZhYmxlKS5cbiAgICAgICAgLy9cbiAgICAgICAgLy8gVGhpcyBIVFRQIG5vdGlmeSBpcyB0aGUgU0lOR0xFIGRlbGl2ZXJ5IGNoYW5uZWwgZm9yIHBvc3QtbXV0YXRpb25cbiAgICAgICAgLy8gcmUtdmFsaWRhdGlvbiAocHJpbWFyeSBlbmZvcmNlbWVudCBpcyB0aGUgZmFpbC1DTE9TRUQgbGl2ZVxuICAgICAgICAvLyB2YWxpZGF0ZSBwYXRoKS4gQSBzdGFibGUgcGVyLWV2ZW50IGBJZGVtcG90ZW5jeS1LZXlgIG1ha2VzIHRoZSBQT1NUXG4gICAgICAgIC8vIHJldHJ5LXNhZmUgaW4gdGhlIGh0dHAtY2xpZW50LCBzbyBhIHRyYW5zaWVudCA1eHgvdGltZW91dCBpcyByZXRyaWVkXG4gICAgICAgIC8vIHJhdGhlciB0aGFuIGRyb3BwZWQgb24gdGhlIGZpcnN0IGF0dGVtcHQ7IGNvbXBsaWFuY2UgcmUtZXZhbHVhdGlvbiBpc1xuICAgICAgICAvLyBuYXR1cmFsbHkgaWRlbXBvdGVudCwgc28gYSBkdXBsaWNhdGUgZGVsaXZlcnkgaXMgaGFybWxlc3MuXG4gICAgICAgIGF3YWl0IGNsaWVudC5wb3N0KCcvY29tcGxpYW5jZS9ldmVudHMvZW50aXR5JywgZXZlbnQsIHtcbiAgICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgICAnQXV0aG9yaXphdGlvbic6IGdldFNlcnZpY2VBdXRoSGVhZGVyKHsgc2VydmljZU5hbWUsIG9yZ0lkOiBldmVudC5vcmdJZCwgcm9sZTogJ21lbWJlcicgfSksXG4gICAgICAgICAgICAnSWRlbXBvdGVuY3ktS2V5JzogYCR7ZXZlbnQudGFyZ2V0fToke2V2ZW50LmVudGl0eUlkfToke2V2ZW50LmV2ZW50VHlwZX06JHtldmVudC50aW1lc3RhbXAudG9JU09TdHJpbmcoKX1gLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIC8vIEZpcmUtYW5kLWZvcmdldDogbG9nICsgYSBkcm9wIG1ldHJpYyBzbyBzdXN0YWluZWQgbG9zcyBpcyBhbGVydGFibGVcbiAgICAgICAgLy8gKG9wZXJhdG9ycyBjYW4ndCBhY3Qgb24gYSB3YXJuIGxpbmUgYWxvbmUpLCB0aGVuIHN3YWxsb3cg4oCUIGNvbXBsaWFuY2VcbiAgICAgICAgLy8gbm90aWZpY2F0aW9uIGlzIG5vbi1mYXRhbCB0byB0aGUgb3JpZ2luYXRpbmcgbXV0YXRpb24uXG4gICAgICAgIGVtaXRDb3VudGVyKCdjb21wbGlhbmNlX2V2ZW50X2Ryb3BfdG90YWwnLCB7IHNlcnZpY2U6IHNlcnZpY2VOYW1lLCB0YXJnZXQ6IGV2ZW50LnRhcmdldCB9KTtcbiAgICAgICAgbG9nZ2VyLndhcm4oJ0ZhaWxlZCB0byBub3RpZnkgY29tcGxpYW5jZSBzZXJ2aWNlIG9mIGVudGl0eSBldmVudCcsIHtcbiAgICAgICAgICB0YXJnZXQ6IGV2ZW50LnRhcmdldCxcbiAgICAgICAgICBldmVudFR5cGU6IGV2ZW50LmV2ZW50VHlwZSxcbiAgICAgICAgICBlbnRpdHlJZDogZXZlbnQuZW50aXR5SWQsXG4gICAgICAgICAgZXJyb3I6IGVyciBpbnN0YW5jZW9mIEVycm9yID8gZXJyLm1lc3NhZ2UgOiBTdHJpbmcoZXJyKSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSxcbiAgfTtcblxuICBlbnRpdHlFdmVudHMuc3Vic2NyaWJlKHN1YnNjcmliZXIpO1xuICBsb2dnZXIuaW5mbygnQ29tcGxpYW5jZSBldmVudCBzdWJzY3JpYmVyIHJlZ2lzdGVyZWQnLCB7XG4gICAgaG9zdDogc2VydmljZUNvbmZpZy5ob3N0LFxuICAgIHBvcnQ6IHNlcnZpY2VDb25maWcucG9ydCxcbiAgfSk7XG59XG4iXX0=
74
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcGxpYW5jZS1ldmVudC1zdWJzY3JpYmVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3NlcnZpY2VzL2NvbXBsaWFuY2UtZXZlbnQtc3Vic2NyaWJlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwrQ0FBK0M7QUFDL0Msc0NBQXNDO0FBRXRDLE9BQU8sRUFBRSxZQUFZLEVBQWdELE1BQU0sb0JBQW9CLENBQUM7QUFDaEcsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDdEQsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ3BELE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQzdELE9BQU8sRUFBc0IsTUFBTSxvQkFBb0IsQ0FBQztBQUN4RCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDbEQsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBRXpELE1BQU0sTUFBTSxHQUFHLFlBQVksQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO0FBRWpEOzs7Ozs7Ozs7Ozs7OztHQWNHO0FBQ0gsTUFBTSxVQUFVLGlDQUFpQyxDQUMvQyxNQUErQixFQUMvQixXQUFXLEdBQVcsZUFBZSxFQUFFO0lBRXZDLE1BQU0sYUFBYSxHQUFrQjtRQUNuQyxJQUFJLEVBQUUsTUFBTSxFQUFFLElBQUksSUFBSSxPQUFPLENBQUMsR0FBRyxDQUFDLHVCQUF1QixJQUFJLFlBQVk7UUFDekUsSUFBSSxFQUFFLE1BQU0sRUFBRSxJQUFJLElBQUksUUFBUSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsdUJBQXVCLElBQUksTUFBTSxFQUFFLEVBQUUsQ0FBQztLQUNsRixDQUFDO0lBRUYsTUFBTSxNQUFNLEdBQUcsSUFBSSxrQkFBa0IsQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUVyRCxNQUFNLFVBQVUsR0FBMEI7UUFDeEMsS0FBSyxDQUFDLGFBQWEsQ0FBQyxLQUFrQjtZQUNwQyxJQUFJLENBQUM7Z0JBQ0gsZ0VBQWdFO2dCQUNoRSxrRUFBa0U7Z0JBQ2xFLG9EQUFvRDtnQkFDcEQsZ0VBQWdFO2dCQUNoRSxzREFBc0Q7Z0JBQ3RELEVBQUU7Z0JBQ0Ysb0VBQW9FO2dCQUNwRSw2REFBNkQ7Z0JBQzdELHNFQUFzRTtnQkFDdEUsdUVBQXVFO2dCQUN2RSx3RUFBd0U7Z0JBQ3hFLDZEQUE2RDtnQkFDN0QsTUFBTSxNQUFNLENBQUMsSUFBSSxDQUFDLDJCQUEyQixFQUFFLEtBQUssRUFBRTtvQkFDcEQsT0FBTyxFQUFFO3dCQUNQLGVBQWUsRUFBRSxvQkFBb0IsQ0FBQyxFQUFFLFdBQVcsRUFBRSxLQUFLLEVBQUUsS0FBSyxDQUFDLEtBQUssRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLENBQUM7d0JBQzFGLGlCQUFpQixFQUFFLEdBQUcsS0FBSyxDQUFDLE1BQU0sSUFBSSxLQUFLLENBQUMsUUFBUSxJQUFJLEtBQUssQ0FBQyxTQUFTLElBQUksS0FBSyxDQUFDLFNBQVMsQ0FBQyxXQUFXLEVBQUUsRUFBRTtxQkFDM0c7aUJBQ0YsQ0FBQyxDQUFDO1lBQ0wsQ0FBQztZQUFDLE9BQU8sR0FBRyxFQUFFLENBQUM7Z0JBQ2Isc0VBQXNFO2dCQUN0RSx3RUFBd0U7Z0JBQ3hFLHlEQUF5RDtnQkFDekQsV0FBVyxDQUFDLDZCQUE2QixFQUFFLEVBQUUsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLEVBQUUsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUM7Z0JBQzNGLE1BQU0sQ0FBQyxJQUFJLENBQUMscURBQXFELEVBQUU7b0JBQ2pFLE1BQU0sRUFBRSxLQUFLLENBQUMsTUFBTTtvQkFDcEIsU0FBUyxFQUFFLEtBQUssQ0FBQyxTQUFTO29CQUMxQixRQUFRLEVBQUUsS0FBSyxDQUFDLFFBQVE7b0JBQ3hCLEtBQUssRUFBRSxHQUFHLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDO2lCQUN4RCxDQUFDLENBQUM7WUFDTCxDQUFDO1FBQ0gsQ0FBQztLQUNGLENBQUM7SUFFRixZQUFZLENBQUMsU0FBUyxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQ25DLE1BQU0sQ0FBQyxJQUFJLENBQUMsd0NBQXdDLEVBQUU7UUFDcEQsSUFBSSxFQUFFLGFBQWEsQ0FBQyxJQUFJO1FBQ3hCLElBQUksRUFBRSxhQUFhLENBQUMsSUFBSTtLQUN6QixDQUFDLENBQUM7QUFDTCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbmltcG9ydCB7IGVudGl0eUV2ZW50cywgdHlwZSBFbnRpdHlFdmVudCwgdHlwZSBFbnRpdHlFdmVudFN1YnNjcmliZXIgfSBmcm9tICcuL2VudGl0eS1ldmVudHMuanMnO1xuaW1wb3J0IHsgSW50ZXJuYWxIdHRwQ2xpZW50IH0gZnJvbSAnLi9odHRwLWNsaWVudC5qcyc7XG5pbXBvcnQgeyBzZXJ2aWNlSWRlbnRpdHkgfSBmcm9tICcuL3NlcnZpY2Uta2V5cy5qcyc7XG5pbXBvcnQgeyBnZXRTZXJ2aWNlQXV0aEhlYWRlciB9IGZyb20gJy4uL21pZGRsZXdhcmUvYXV0aC5qcyc7XG5pbXBvcnQgeyB0eXBlIFNlcnZpY2VDb25maWcgfSBmcm9tICcuLi90eXBlcy9jb21tb24uanMnO1xuaW1wb3J0IHsgY3JlYXRlTG9nZ2VyIH0gZnJvbSAnLi4vdXRpbHMvbG9nZ2VyLmpzJztcbmltcG9ydCB7IGVtaXRDb3VudGVyIH0gZnJvbSAnLi4vdXRpbHMvbWV0cmljLWVtaXR0ZXIuanMnO1xuXG5jb25zdCBsb2dnZXIgPSBjcmVhdGVMb2dnZXIoJ2NvbXBsaWFuY2UtZXZlbnRzJyk7XG5cbi8qKlxuICogUmVnaXN0ZXJzIGFuIGVudGl0eSBldmVudCBzdWJzY3JpYmVyIHRoYXQgZm9yd2FyZHMgZXZlbnRzIHRvIHRoZSBjb21wbGlhbmNlIHNlcnZpY2UuXG4gKlxuICogQ2FsbCB0aGlzIGF0IHNlcnZpY2Ugc3RhcnR1cCAoaW4gaW5kZXgudHMpIHRvIGVuYWJsZSBhdXRvbWF0aWMgY29tcGxpYW5jZVxuICogbm90aWZpY2F0aW9uIG9uIGVudGl0eSBtdXRhdGlvbnMuIEV2ZW50cyBhcmUgZmlyZS1hbmQtZm9yZ2V0IOKAlCBmYWlsdXJlc1xuICogYXJlIGxvZ2dlZCBidXQgbmV2ZXIgYmxvY2sgdGhlIG9yaWdpbmFsIHJlcXVlc3QuXG4gKlxuICogQHBhcmFtIGNvbmZpZyAtIE9wdGlvbmFsIHNlcnZpY2UgY29uZmlnIG92ZXJyaWRlIChkZWZhdWx0cyB0byBDT01QTElBTkNFX1NFUlZJQ0VfSE9TVC9QT1JUIGVudiB2YXJzKVxuICogQHBhcmFtIHNlcnZpY2VOYW1lIC0gU2VydmljZSBpZGVudGlmaWVyIGJha2VkIGludG8gdGhlIHNpZ25lZCBKV1QncyBgc3ViYFxuICogICAoZS5nLiAncGlwZWxpbmUnLCAncGx1Z2luJykuIFRoZSBjb21wbGlhbmNlIHJvdXRlIGlzIGFuIElOVEVSTkFMIHJvdXRlOiBpdFxuICogICBhZG1pdHMgb25seSB0aG9zZSB0d28gc2VydmljZXMnIG93biBzaWduZWQgdG9rZW5zLCBhbmQgbm8gdXNlciB0b2tlbi5cbiAqICAgRGVmYXVsdHMgdG8gVEhJUyBwcm9jZXNzJ3MgaWRlbnRpdHkgKGBTRVJWSUNFX05BTUVgKSDigJQgc2luY2UgIzE0IGEgc2VydmljZVxuICogICBob2xkcyBvbmx5IGl0cyBvd24gc2lnbmluZyBrZXksIHNvIGEgcGxhY2Vob2xkZXIgbmFtZSB3b3VsZCBtaW50IGEgdG9rZW4gbm9cbiAqICAgcGVlciBjb3VsZCB2ZXJpZnkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWdpc3RlckNvbXBsaWFuY2VFdmVudFN1YnNjcmliZXIoXG4gIGNvbmZpZz86IFBhcnRpYWw8U2VydmljZUNvbmZpZz4sXG4gIHNlcnZpY2VOYW1lOiBzdHJpbmcgPSBzZXJ2aWNlSWRlbnRpdHkoKSxcbik6IHZvaWQge1xuICBjb25zdCBzZXJ2aWNlQ29uZmlnOiBTZXJ2aWNlQ29uZmlnID0ge1xuICAgIGhvc3Q6IGNvbmZpZz8uaG9zdCA/PyBwcm9jZXNzLmVudi5DT01QTElBTkNFX1NFUlZJQ0VfSE9TVCA/PyAnY29tcGxpYW5jZScsXG4gICAgcG9ydDogY29uZmlnPy5wb3J0ID8/IHBhcnNlSW50KHByb2Nlc3MuZW52LkNPTVBMSUFOQ0VfU0VSVklDRV9QT1JUID8/ICczMDAwJywgMTApLFxuICB9O1xuXG4gIGNvbnN0IGNsaWVudCA9IG5ldyBJbnRlcm5hbEh0dHBDbGllbnQoc2VydmljZUNvbmZpZyk7XG5cbiAgY29uc3Qgc3Vic2NyaWJlcjogRW50aXR5RXZlbnRTdWJzY3JpYmVyID0ge1xuICAgIGFzeW5jIG9uRW50aXR5RXZlbnQoZXZlbnQ6IEVudGl0eUV2ZW50KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICB0cnkge1xuICAgICAgICAvLyBNaW50IGEgcGVyLWV2ZW50IHNlcnZpY2UgSldUIHNjb3BlZCB0byB0aGUgZXZlbnQncyBvcmcgc28gdGhlXG4gICAgICAgIC8vIGNvbXBsaWFuY2Ugcm91dGUncyBgcnVuV2l0aFRlbmFudENvbnRleHRgIHNlZXMgdGhlIHJpZ2h0IHRlbmFudFxuICAgICAgICAvLyBHVUMuIFRoZSBjb21wbGlhbmNlIHNpZGUgZW5mb3JjZXMgYHJlcXVpcmVBdXRoYCArXG4gICAgICAgIC8vIGByZXF1aXJlU2VydmljZVByaW5jaXBhbGAg4oCUIHRoZSBwcmV2aW91cyBgeC1pbnRlcm5hbC1zZXJ2aWNlYFxuICAgICAgICAvLyBoZWFkZXIgaXMgbm8gbG9uZ2VyIHN1ZmZpY2llbnQgKGFuZCB3YXMgc3Bvb2ZhYmxlKS5cbiAgICAgICAgLy9cbiAgICAgICAgLy8gVGhpcyBIVFRQIG5vdGlmeSBpcyB0aGUgU0lOR0xFIGRlbGl2ZXJ5IGNoYW5uZWwgZm9yIHBvc3QtbXV0YXRpb25cbiAgICAgICAgLy8gcmUtdmFsaWRhdGlvbiAocHJpbWFyeSBlbmZvcmNlbWVudCBpcyB0aGUgZmFpbC1DTE9TRUQgbGl2ZVxuICAgICAgICAvLyB2YWxpZGF0ZSBwYXRoKS4gQSBzdGFibGUgcGVyLWV2ZW50IGBJZGVtcG90ZW5jeS1LZXlgIG1ha2VzIHRoZSBQT1NUXG4gICAgICAgIC8vIHJldHJ5LXNhZmUgaW4gdGhlIGh0dHAtY2xpZW50LCBzbyBhIHRyYW5zaWVudCA1eHgvdGltZW91dCBpcyByZXRyaWVkXG4gICAgICAgIC8vIHJhdGhlciB0aGFuIGRyb3BwZWQgb24gdGhlIGZpcnN0IGF0dGVtcHQ7IGNvbXBsaWFuY2UgcmUtZXZhbHVhdGlvbiBpc1xuICAgICAgICAvLyBuYXR1cmFsbHkgaWRlbXBvdGVudCwgc28gYSBkdXBsaWNhdGUgZGVsaXZlcnkgaXMgaGFybWxlc3MuXG4gICAgICAgIGF3YWl0IGNsaWVudC5wb3N0KCcvY29tcGxpYW5jZS9ldmVudHMvZW50aXR5JywgZXZlbnQsIHtcbiAgICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgICAnQXV0aG9yaXphdGlvbic6IGdldFNlcnZpY2VBdXRoSGVhZGVyKHsgc2VydmljZU5hbWUsIG9yZ0lkOiBldmVudC5vcmdJZCwgcm9sZTogJ21lbWJlcicgfSksXG4gICAgICAgICAgICAnSWRlbXBvdGVuY3ktS2V5JzogYCR7ZXZlbnQudGFyZ2V0fToke2V2ZW50LmVudGl0eUlkfToke2V2ZW50LmV2ZW50VHlwZX06JHtldmVudC50aW1lc3RhbXAudG9JU09TdHJpbmcoKX1gLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIC8vIEZpcmUtYW5kLWZvcmdldDogbG9nICsgYSBkcm9wIG1ldHJpYyBzbyBzdXN0YWluZWQgbG9zcyBpcyBhbGVydGFibGVcbiAgICAgICAgLy8gKG9wZXJhdG9ycyBjYW4ndCBhY3Qgb24gYSB3YXJuIGxpbmUgYWxvbmUpLCB0aGVuIHN3YWxsb3cg4oCUIGNvbXBsaWFuY2VcbiAgICAgICAgLy8gbm90aWZpY2F0aW9uIGlzIG5vbi1mYXRhbCB0byB0aGUgb3JpZ2luYXRpbmcgbXV0YXRpb24uXG4gICAgICAgIGVtaXRDb3VudGVyKCdjb21wbGlhbmNlX2V2ZW50X2Ryb3BfdG90YWwnLCB7IHNlcnZpY2U6IHNlcnZpY2VOYW1lLCB0YXJnZXQ6IGV2ZW50LnRhcmdldCB9KTtcbiAgICAgICAgbG9nZ2VyLndhcm4oJ0ZhaWxlZCB0byBub3RpZnkgY29tcGxpYW5jZSBzZXJ2aWNlIG9mIGVudGl0eSBldmVudCcsIHtcbiAgICAgICAgICB0YXJnZXQ6IGV2ZW50LnRhcmdldCxcbiAgICAgICAgICBldmVudFR5cGU6IGV2ZW50LmV2ZW50VHlwZSxcbiAgICAgICAgICBlbnRpdHlJZDogZXZlbnQuZW50aXR5SWQsXG4gICAgICAgICAgZXJyb3I6IGVyciBpbnN0YW5jZW9mIEVycm9yID8gZXJyLm1lc3NhZ2UgOiBTdHJpbmcoZXJyKSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSxcbiAgfTtcblxuICBlbnRpdHlFdmVudHMuc3Vic2NyaWJlKHN1YnNjcmliZXIpO1xuICBsb2dnZXIuaW5mbygnQ29tcGxpYW5jZSBldmVudCBzdWJzY3JpYmVyIHJlZ2lzdGVyZWQnLCB7XG4gICAgaG9zdDogc2VydmljZUNvbmZpZy5ob3N0LFxuICAgIHBvcnQ6IHNlcnZpY2VDb25maWcucG9ydCxcbiAgfSk7XG59XG4iXX0=