@pipeline-builder/api-core 4.1.3 → 4.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) 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/cache-service.d.ts +11 -26
  19. package/lib/services/cache-service.js +20 -74
  20. package/lib/services/compliance-event-subscriber.d.ts +5 -4
  21. package/lib/services/compliance-event-subscriber.js +8 -6
  22. package/lib/services/durable-event-bus.d.ts +22 -39
  23. package/lib/services/durable-event-bus.js +95 -43
  24. package/lib/services/env-redis.d.ts +27 -0
  25. package/lib/services/env-redis.js +63 -1
  26. package/lib/services/http-client.d.ts +10 -15
  27. package/lib/services/http-client.js +32 -27
  28. package/lib/services/index.d.ts +3 -0
  29. package/lib/services/index.js +4 -1
  30. package/lib/services/jwks-cache.d.ts +102 -0
  31. package/lib/services/jwks-cache.js +222 -0
  32. package/lib/services/quota.js +12 -4
  33. package/lib/services/remote-audit-client.d.ts +1 -1
  34. package/lib/services/remote-audit-client.js +32 -1
  35. package/lib/services/scheduler.d.ts +2 -3
  36. package/lib/services/scheduler.js +2 -2
  37. package/lib/services/service-boot.d.ts +4 -2
  38. package/lib/services/service-boot.js +7 -3
  39. package/lib/services/service-keys.d.ts +83 -0
  40. package/lib/services/service-keys.js +354 -0
  41. package/lib/services/sse-ticket-store.d.ts +55 -22
  42. package/lib/services/sse-ticket-store.js +122 -79
  43. package/lib/services/token-revocation.js +30 -18
  44. package/lib/testing/route-coverage.d.ts +64 -0
  45. package/lib/testing/route-coverage.js +183 -0
  46. package/lib/testing/service-tokens.d.ts +66 -0
  47. package/lib/testing/service-tokens.js +137 -0
  48. package/lib/testing/tier-mock.d.ts +2 -2
  49. package/lib/testing/tier-mock.js +3 -3
  50. package/lib/testing/user-tokens.d.ts +75 -0
  51. package/lib/testing/user-tokens.js +115 -0
  52. package/lib/types/catalog-metadata.d.ts +0 -2
  53. package/lib/types/catalog-metadata.js +1 -3
  54. package/lib/types/common.d.ts +103 -4
  55. package/lib/types/common.js +11 -1
  56. package/lib/types/error-codes.d.ts +15 -0
  57. package/lib/types/error-codes.js +22 -1
  58. package/lib/types/permissions.d.ts +35 -1
  59. package/lib/types/permissions.js +72 -2
  60. package/lib/utils/api-key.d.ts +34 -0
  61. package/lib/utils/api-key.js +75 -0
  62. package/lib/utils/env.d.ts +0 -2
  63. package/lib/utils/env.js +1 -6
  64. package/lib/utils/index.d.ts +4 -0
  65. package/lib/utils/index.js +5 -1
  66. package/lib/utils/jwk.d.ts +98 -0
  67. package/lib/utils/jwk.js +139 -0
  68. package/lib/utils/logger.d.ts +30 -1
  69. package/lib/utils/logger.js +74 -27
  70. package/lib/utils/secret-encryption.d.ts +7 -2
  71. package/lib/utils/secret-encryption.js +47 -4
  72. package/lib/utils/secret-rotation.d.ts +17 -0
  73. package/lib/utils/secret-rotation.js +54 -0
  74. package/lib/utils/sensitive-patterns.d.ts +49 -0
  75. package/lib/utils/sensitive-patterns.js +149 -0
  76. package/lib/validation/common-schemas.js +5 -4
  77. package/package.json +20 -1
@@ -182,8 +182,28 @@ function getDefaultProvider() {
182
182
  export function getDefaultKeyProvider() {
183
183
  return getDefaultProvider();
184
184
  }
185
- /** Reset the cached default provider for tests that mutate `process.env`. */
186
- export function resetDefaultKeyProvider() { defaultProvider = null; }
185
+ /**
186
+ * Rotation fallback: an `EnvKeyProvider` over `SECRET_ENCRYPTION_KEY_PREVIOUS`,
187
+ * or null when that env is unset. `undefined` = not yet resolved. While a
188
+ * master-key rotation is in progress, `decryptSecret` retries a failed decrypt
189
+ * under this key, so rows written under the old master stay readable until the
190
+ * re-encryption tool (platform `scripts/reencrypt-secrets.js`) has rewritten
191
+ * them under the new one. Encryption NEVER uses it.
192
+ */
193
+ let previousProvider;
194
+ function getPreviousProvider() {
195
+ if (previousProvider === undefined) {
196
+ const raw = process.env.SECRET_ENCRYPTION_KEY_PREVIOUS;
197
+ previousProvider = raw ? new EnvKeyProvider(raw) : null;
198
+ }
199
+ return previousProvider;
200
+ }
201
+ /** Read the rotation-fallback provider (null outside a master-key rotation). */
202
+ export function getPreviousKeyProvider() {
203
+ return getPreviousProvider();
204
+ }
205
+ /** Reset the cached default (and previous) provider for tests that mutate `process.env`. */
206
+ export function resetDefaultKeyProvider() { defaultProvider = null; previousProvider = undefined; }
187
207
  /** Replace the default provider services that opt into KMS call this
188
208
  * once at startup with a warmed-up `KmsKeyProvider`. */
189
209
  export function setKeyProvider(provider) { defaultProvider = provider; }
@@ -380,8 +400,11 @@ export async function encryptSecret(plaintext, orgId, provider = getDefaultProvi
380
400
  *
381
401
  * Callers handle the throw masking the failure as `null` would hide
382
402
  * silent corruption / wrong-org reads.
403
+ *
404
+ * `previous` (default: `SECRET_ENCRYPTION_KEY_PREVIOUS`, when set) is tried
405
+ * only after the primary key fails, and only for kid-less blobs.
383
406
  */
384
- export async function decryptSecret(blob, orgId, provider = getDefaultProvider()) {
407
+ export async function decryptSecret(blob, orgId, provider = getDefaultProvider(), previous = getPreviousProvider()) {
385
408
  if (blob.alg !== 'aes-256-gcm-v1') {
386
409
  throw new Error(`Unsupported encryption alg: ${blob.alg}`);
387
410
  }
@@ -396,6 +419,26 @@ export async function decryptSecret(blob, orgId, provider = getDefaultProvider()
396
419
  if (providerKid !== undefined && blob.kid !== undefined && providerKid !== blob.kid) {
397
420
  throw new Error(`KMS key id mismatch: blob was encrypted under ${blob.kid}, current provider uses ${providerKid} for org ${orgId}`);
398
421
  }
422
+ try {
423
+ return decryptWithKey(blob, key);
424
+ }
425
+ catch (err) {
426
+ // Master-key rotation window: retry under SECRET_ENCRYPTION_KEY_PREVIOUS.
427
+ // Only for a kid-less blob (the env-keyed shape) — a per-org KMS blob is
428
+ // bound to its CMK and the shared previous master can never open it. The
429
+ // ORIGINAL error surfaces when the previous key fails too, so a tampered or
430
+ // wrong-org blob still fails loud exactly as before.
431
+ if (previous && blob.kid === undefined) {
432
+ try {
433
+ return decryptWithKey(blob, await deriveKeyFor(previous, orgId));
434
+ }
435
+ catch { /* fall through to the primary error */ }
436
+ }
437
+ throw err;
438
+ }
439
+ }
440
+ /** AES-256-GCM open of a blob under one derived key. Throws on any auth-tag failure. */
441
+ function decryptWithKey(blob, key) {
399
442
  const iv = Buffer.from(blob.iv, 'base64');
400
443
  const all = Buffer.from(blob.ciphertext, 'base64');
401
444
  // Split off the 16-byte auth tag appended in encryptSecret. Any tampering
@@ -421,4 +464,4 @@ export function isEncryptedBlob(value) {
421
464
  && typeof value.iv === 'string'
422
465
  && typeof value.ciphertext === 'string');
423
466
  }
424
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VjcmV0LWVuY3J5cHRpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdXRpbHMvc2VjcmV0LWVuY3J5cHRpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQUV0Qzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0EwQkc7QUFFSCxPQUFPLEVBQUUsY0FBYyxFQUFFLGdCQUFnQixFQUFFLFFBQVEsRUFBRSxXQUFXLEVBQUUsTUFBTSxRQUFRLENBQUM7QUE2QmpGOzs7Ozs7O0dBT0c7QUFDSCxNQUFNLE9BQU8sY0FBYztJQUNSLFNBQVMsQ0FBUztJQUVuQyxZQUFZLGlCQUEwQjtRQUNwQyxNQUFNLEdBQUcsR0FBRyxpQkFBaUIsSUFBSSxPQUFPLENBQUMsR0FBRyxDQUFDLHFCQUFxQixDQUFDO1FBQ25FLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztZQUNULE1BQU0sSUFBSSxLQUFLLENBQUMsNkRBQTZELENBQUMsQ0FBQztRQUNqRixDQUFDO1FBQ0QsMEVBQTBFO1FBQzFFLHNEQUFzRDtRQUN0RCxNQUFNLE9BQU8sR0FBRyxHQUFHLENBQUMsTUFBTSxLQUFLLEVBQUUsSUFBSSxjQUFjLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQztZQUMzRCxDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDO1lBQ3pCLENBQUMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxRQUFRLENBQUMsQ0FBQztRQUMvQixJQUFJLE9BQU8sQ0FBQyxNQUFNLEtBQUssRUFBRSxFQUFFLENBQUM7WUFDMUIsTUFBTSxJQUFJLEtBQUssQ0FBQyxzREFBc0QsT0FBTyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7UUFDM0YsQ0FBQztRQUNELElBQUksQ0FBQyxTQUFTLEdBQUcsT0FBTyxDQUFDO0lBQzNCLENBQUM7SUFFRCxTQUFTLENBQUMsS0FBYTtRQUNy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QUcsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLE1BQU0sR0FBRyxFQUFFLENBQUMsQ0FBQztJQUMxQyxNQUFNLEdBQUcsR0FBRyxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsTUFBTSxHQUFHLEVBQUUsQ0FBQyxDQUFDO0lBQzdDLE1BQU0sUUFBUSxHQUFHLGdCQUFnQixDQUFDLGFBQWEsRUFBRSxHQUFHLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDMUQsUUFBUSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUN6QixNQUFNLEdBQUcsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxRQUFRLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ3BFLE9BQU8sR0FBRyxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUM5QixDQUFDO0FBRUQ7Ozs7O0dBS0c7QUFDSCxNQUFNLFVBQVUsZUFBZSxDQUFDLEtBQWM7SUFDNUMsT0FBTyxDQUFFLE9BQU8sS0FBSyxLQUFLLFFBQVE7V0FDN0IsS0FBSyxLQUFLLElBQUk7V0FDYixLQUEyQixDQUFDLEdBQUcsS0FBSyxnQkFBZ0I7V0FDckQsT0FBUSxLQUEwQixDQUFDLEVBQUUsS0FBSyxRQUFRO1dBQ2xELE9BQVEsS0FBa0MsQ0FBQyxVQUFVLEtBQUssUUFBUSxDQUN0RSxDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDI2IFBpcGVsaW5lIEJ1aWxkZXIgQ29udHJpYnV0b3JzXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuXG4vKipcbiAqICBQZXItb3JnIGVudmVsb3BlIGVuY3J5cHRpb24gZm9yIHNlY3JldCBjb2x1bW5zLlxuICpcbiAqIFRvZGF5J3MgcG9zdHVyZSBmb3Igb3JnLXNjb3BlZCBzZWNyZXRzIChhaVByb3ZpZGVyS2V5cywgd2ViaG9vayBVUkxzLFxuICogcmVnaXN0cnkgY3JlZGVudGlhbHMpIGlzIGNsZWFyLXRleHQgaW4gTW9uZ28gLyBQb3N0Z3JlcyB3aXRoIGFwcC1sYXllclxuICogbWFza2luZyBvbiBvdXRwdXQuIFRoaXMgbW9kdWxlIGlzIHRoZSBlbmNyeXB0aW9uIHByaW1pdGl2ZSB0aGF0IGxldHMgdGhlXG4gKiBtb2RlbCBsYXllciBzd2FwIGNsZWFyLXRleHQgc3RyaW5ncyBmb3IgYEVuY3J5cHRlZEJsb2JgIHZhbHVlcyBhdCB3cml0ZVxuICogdGltZSBhbmQgZGVjcnlwdCBhdCByZWFkIHRpbWUuXG4gKlxuICogQ3J5cHRvZ3JhcGh5ICogLSBBRVMtMjU2LUdDTSAoYXV0aGVudGljYXRlZCBlbmNyeXB0aW9uKS5cbiAqIC0gUGVyLW9yZyBrZXkgZGVyaXZlZCB2aWEgSEtERi1TSEEyNTYobWFzdGVyS2V5LCBzYWx0PW9yZ0lkLCBpbmZvPSdzZWNyZXRzLXYxJykuXG4gKiBFYWNoIG9yZyBnZXRzIGEgdW5pcXVlIGtleSB3aXRob3V0IG9wZXJhdG9yIGtleS1tYW5hZ2VtZW50IGNlcmVtb255LlxuICogLSAxMi1ieXRlIElWIGdlbmVyYXRlZCBwZXIgZW5jcnlwdGlvbiB3aXRoIGBjcnlwdG8ucmFuZG9tQnl0ZXNgLlxuICogLSAxNi1ieXRlIGF1dGhlbnRpY2F0aW9uIHRhZyBjb25jYXRlbmF0ZWQgd2l0aCBjaXBoZXJ0ZXh0IChzdGFuZGFyZCBHQ00pLlxuICpcbiAqIE9wZXJhdG9yIGNvbmZpZ3VyYXRpb24gKiAtIGBTRUNSRVRfRU5DUllQVElPTl9LRVlgIGVudjogaGV4LSBvciBiYXNlNjQtZW5jb2RlZCAzMi1ieXRlIG1hc3RlciBrZXkuXG4gKiBSZXF1aXJlZCB3aGVuIGBlbmNyeXB0U2VjcmV0YC9gZGVjcnlwdFNlY3JldGAgYXJlIGNhbGxlZC4gTWlzc2luZyBrZXlcbiAqIHRocm93cyAgZW5jcnlwdGlvbiBpcyBmYWlsLWNsb3NlZDsgd2UgbmV2ZXIgc2lsZW50bHkgcm91bmQtdHJpcCBhXG4gKiBzZWNyZXQgYXMgcGxhaW50ZXh0LlxuICpcbiAqIEtNUyBtaWdyYXRpb24gcGF0aCAqIC0gVGhlIHR3byBleHBvcnRlZCBmdW5jdGlvbnMgdGFrZSBhIGBwcm92aWRlcmAgcGFyYW1ldGVyLiBUaGUgZGVmYXVsdFxuICogYEVudktleVByb3ZpZGVyYCBpbXBsZW1lbnRzIEhLREYgZGVyaXZhdGlvbi4gQSBmdXR1cmUgYEF3c0ttc1Byb3ZpZGVyYFxuICogcGx1Z3MgaW4gaGVyZTogaXQgY2FuIGNhbGwgS01TIGBFbmNyeXB0YCAvIGBEZWNyeXB0YCB0byB3cmFwIGEgREVLXG4gKiByYXRoZXIgdGhhbiBob2xkaW5nIGEgbWFzdGVyIGtleSBpbiBlbnYuIFRoZSBvbi1kaXNrIGJsb2Igc2hhcGVcbiAqIChgeyBhbGcsIGl2LCBjaXBoZXJ0ZXh0LCBraWQ/IH1gKSBpcyBmb3J3YXJkLWNvbXBhdGlibGUgIGBraWRgXG4gKiBjYXJyaWVzIHRoZSBLTVMga2V5IGlkIHdoZW4gdGhlIHByb3ZpZGVyIG5lZWRzIGl0LlxuICovXG5cbmltcG9ydCB7IGNyZWF0ZUNpcGhlcml2LCBjcmVhdGVEZWNpcGhlcml2LCBoa2RmU3luYywgcmFuZG9tQnl0ZXMgfSBmcm9tICdjcnlwdG8nO1xuXG4vKiogT24tZGlzayBzaGFwZSBvZiBhbiBlbmNyeXB0ZWQgc2VjcmV0LiBKU09OLXNlcmlhbGl6YWJsZS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRW5jcnlwdGVkQmxvYiB7XG4gIC8qKiBBbGdvcml0aG0gdGFnLiBCdW1wIG9uIGZvcm1hdCBjaGFuZ2Ugc28gYSBmdXR1cmUgbWlncmF0aW9uIGNhbiBkZXRlY3Qgb2xkIGJsb2JzLiAqL1xuICBhbGc6ICdhZXMtMjU2LWdjbS12MSc7XG4gIC8qKiBCYXNlNjQtZW5jb2RlZCAxMi1ieXRlIElWLiAqL1xuICBpdjogc3RyaW5nO1xuICAvKiogQmFzZTY0LWVuY29kZWQgY2lwaGVydGV4dCArIDE2LWJ5dGUgYXV0aGVudGljYXRpb24gdGFnIGNvbmNhdGVuYXRlZC4gKi9cbiAgY2lwaGVydGV4dDogc3RyaW5nO1xuICAvKiogT3B0aW9uYWwga2V5IGlkICBwb3B1bGF0ZWQgYnkgS01TLWJhY2tlZCBwcm92aWRlcnMsIGlnbm9yZWQgYnkgdGhlIGVudiBwcm92aWRlci4gKi9cbiAga2lkPzogc3RyaW5nO1xufVxuXG4vKiogUGx1Z2dhYmxlIGtleSBzb3VyY2UuIEVudi1iYWNrZWQgYnkgZGVmYXVsdDsgS01TLWJhY2tlZCBhdmFpbGFibGUuICovXG5leHBvcnQgaW50ZXJmYWNlIEtleVByb3ZpZGVyIHtcbiAgLyoqIERlcml2ZSBhIDMyLWJ5dGUgc3ltbWV0cmljIGtleSBib3VuZCB0byBgb3JnSWRgLiAqL1xuICBkZXJpdmVLZXkob3JnSWQ6IHN0cmluZyk6IEJ1ZmZlcjtcbiAgLyoqIE9wdGlvbmFsIGFzeW5jIHZhcmlhbnQgZm9yIHByb3ZpZGVycyB0aGF0IG5lZWQgdG8gZG8gSS9PIChlLmcuXG4gICAqICBwZXItb3JnIEtNUyBsb29rdXAgdGhlIGZpcnN0IHRpbWUgYW4gb3JnIGlzIHNlZW4pLiBEZWZhdWx0XG4gICAqICBpbXBsZW1lbnRhdGlvbiBmb3J3YXJkcyB0byB0aGUgc3luYyBgZGVyaXZlS2V5YC4gKi9cbiAgZGVyaXZlS2V5QXN5bmM/KG9yZ0lkOiBzdHJpbmcpOiBQcm9taXNlPEJ1ZmZlcj47XG4gIC8qKiBPcHRpb25hbCBLTVMta2V5LWlkIHRoaXMgcHJvdmlkZXIgdXNlZCBmb3IgYG9yZ0lkYC4gRW1iZWRkZWQgaW4gdGhlXG4gICAqICBgRW5jcnlwdGVkQmxvYi5raWRgIGZpZWxkIG9uIHdyaXRlIHNvIGRlY3J5cHQgY2FuIHZlcmlmeSB0aGUgcmlnaHRcbiAgICogIEtNUyBDTUsgaXMgYmVpbmcgdXNlZCAoZGVmZW5zZSBhZ2FpbnN0IGFuIGF0dGFja2VyIHdobyBzd2FwcyBhIGJsb2JcbiAgICogIGJldHdlZW4gb3JncykuIERlZmF1bHQgcmV0dXJucyB1bmRlZmluZWQgKGVudiBwcm92aWRlcikuICovXG4gIGtpZEZvcj8ob3JnSWQ6IHN0cmluZyk6IHN0cmluZyB8IHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBEZWZhdWx0IHByb3ZpZGVyICBkZXJpdmVzIGEgcGVyLW9yZyBrZXkgZnJvbSBgU0VDUkVUX0VOQ1JZUFRJT05fS0VZYCB2aWFcbiAqIEhLREYtU0hBMjU2LiBTdWl0YWJsZSBmb3Igc2VsZi1ob3N0ZWQgLyBkZXYgd2hlcmUgb3BlcmF0b3JzIGRvbid0IGhhdmUgS01TLlxuICpcbiAqIEZhaWxzIGZhc3QgaWYgdGhlIGVudiBpcyBtaXNzaW5nIG9yIHRoZSBrZXkgaXMgdGhlIHdyb25nIGxlbmd0aCBzbyBtaXNjb25maWdcbiAqIHN1cmZhY2VzIGF0IGZpcnN0IHVzZSByYXRoZXIgdGhhbiBzaWxlbnRseSBmaW5nZXJwcmludGluZyBhbGwgd3JpdGVzIHdpdGhcbiAqIGEgZGVmYXVsdCB6ZXJvIGtleS5cbiAqL1xuZXhwb3J0IGNsYXNzIEVudktleVByb3ZpZGVyIGltcGxlbWVudHMgS2V5UHJvdmlkZXIge1xuICBwcml2YXRlIHJlYWRvbmx5IG1hc3RlcktleTogQnVmZmVyO1xuXG4gIGNvbnN0cnVjdG9yKG1hc3RlcktleU92ZXJyaWRlPzogc3RyaW5nKSB7XG4gICAgY29uc3QgcmF3ID0gbWFzdGVyS2V5T3ZlcnJpZGUgPz8gcHJvY2Vzcy5lbnYuU0VDUkVUX0VOQ1JZUFRJT05fS0VZO1xuICAgIGlmICghcmF3KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1NFQ1JFVF9FTkNSWVBUSU9OX0tFWSBlbnYgaXMgcmVxdWlyZWQgZm9yIHNlY3JldCBlbmNyeXB0aW9uJyk7XG4gICAgfVxuICAgIC8vIEFjY2VwdCBlaXRoZXIgaGV4ICg2NCBjaGFycykgb3IgYmFzZTY0ICg0NCBjaGFycyBpbmNsdWRpbmcgcGFkZGluZykgZm9yXG4gICAgLy8gb3BlcmF0b3IgY29udmVuaWVuY2UgIGJvdGggZGVjb2RlIHRvIGEgMzItYnl0ZSBrZXkuXG4gICAgY29uc3QgZGVjb2RlZCA9IHJhdy5sZW5ndGggPT09IDY0ICYmIC9eWzAtOWEtZl0rJC9pLnRlc3QocmF3KVxuICAgICAgPyBCdWZmZXIuZnJvbShyYXcsICdoZXgnKVxuICAgICAgOiBCdWZmZXIuZnJvbShyYXcsICdiYXNlNjQnKTtcbiAgICBpZiAoZGVjb2RlZC5sZW5ndGggIT09IDMyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFNFQ1JFVF9FTkNSWVBUSU9OX0tFWSBtdXN0IGRlY29kZSB0byAzMiBieXRlcyAoZ290ICR7ZGVjb2RlZC5sZW5ndGh9KWApO1xuICAgIH1cbiAgICB0aGlzLm1hc3RlcktleSA9IGRlY29kZWQ7XG4gIH1cblxuICBkZXJpdmVLZXkob3JnSWQ6IHN0cmluZyk6IEJ1ZmZlciB7XG4gICAgLy8gSEtERiBiaW5kcyB0aGUgbWFzdGVyIGtleSB0byB0aGUgb3JnIHNvIHR3byBvcmdzIGVuY3J5cHRpbmcgdGhlIHNhbWVcbiAgICAvLyBwbGFpbnRleHQgcHJvZHVjZSBkaWZmZXJlbnQgY2lwaGVydGV4dHMgIGtlZXBzIGEgc3RvbGVuIERCIHVuYWJsZSB0b1xuICAgIC8vIHRlbGwgd2hpY2ggb3JncyBzaGFyZSBzZWNyZXRzIHZpYSBjaXBoZXJ0ZXh0IGNvbXBhcmlzb24uXG4gICAgY29uc3QgZGVyaXZlZCA9IGhrZGZTeW5jKCAnc2hhMjU2JyxcbiAgICAgIHRoaXMubWFzdGVyS2V5LFxuICAgICAgQnVmZmVyLmZyb20ob3JnSWQsICd1dGY4JyksXG4gICAgICAnc2VjcmV0cy12MScsXG4gICAgICAzMixcbiAgICApO1xuICAgIC8vIGhrZGZTeW5jIHJldHVybnMgQXJyYXlCdWZmZXIgaW4gb2xkZXIgTm9kZSB0eXBpbmdzOyBub3JtYWxpemUgdG8gQnVmZmVyLlxuICAgIHJldHVybiBCdWZmZXIuZnJvbShkZXJpdmVkKTtcbiAgfVxufVxuXG4vKipcbiAqICBBV1MtS01TLWJhY2tlZCBLZXlQcm92aWRlci5cbiAqXG4gKiBUcmFkZS1vZmYgcGlja2VkOiBzdG9yZSBPTkUgbWFzdGVyIGtleSBlbmNyeXB0ZWQgdW5kZXIgYSBLTVMgQ01LOyBvblxuICogZmlyc3QgdXNlLCBjYWxsIGBrbXM6RGVjcnlwdGAgdG8gcmVjb3ZlciB0aGUgbWFzdGVyIGtleSBieXRlczsgSEtERi1cbiAqIGRlcml2ZSBwZXItb3JnIGZyb20gaXQgKHNhbWUgYXMgRW52S2V5UHJvdmlkZXIpLiBUaGUgcHJvY2VzcyB0aGVuIGhvbGRzXG4gKiB0aGUgcGxhaW50ZXh0IG1hc3RlciBrZXkgaW4gbWVtb3J5IHVudGlsIHJlc3RhcnQuXG4gKlxuICogUFJPUzogb25lIEtNUyBjYWxsIHBlciBwcm9jZXNzIGxpZmV0aW1lIChjaGVhcCwgbG93IHA5OSBpbXBhY3QpLFxuICogdGhlIGVuY3J5cHRlZC1tYXN0ZXIta2V5IGJsb2IgaXMgc2FmZSB0byBjb21taXQvbG9nL2NoZWNraW4sXG4gKiBLTVMgYXVkaXQgbG9nIHJlY29yZHMgd2hlbiB0aGUgbWFzdGVyIGlzIHJlY292ZXJlZC5cbiAqIENPTlM6IHByb2Nlc3MgbWVtb3J5IHN0aWxsIGhvbGRzIHRoZSBtYXN0ZXIga2V5ICBzYW1lIHBvc3R1cmUgYXNcbiAqIEVudktleVByb3ZpZGVyIG9uY2Ugd2FybWVkIHVwLiBGb3Igc3Ryb25nZXIgaXNvbGF0aW9uIGFuXG4gKiBvcGVyYXRvciBjYW4gbW92ZSB0byBwZXItcmVjb3JkIGVudmVsb3BlIGVuY3J5cHRpb24gKGNhbGxcbiAqIEdlbmVyYXRlRGF0YUtleSBvbiBldmVyeSB3cml0ZSk7IHRoYXQncyBhIGZvbGxvdy1vbi5cbiAqXG4gKiBPcGVyYXRvciBzZXR1cCAqIDEuIENyZWF0ZSBhIEtNUyBDTUsgd2l0aCBrZXkgcG9saWN5IGFsbG93aW5nIHRoZSBwbGF0Zm9ybSBzZXJ2aWNlJ3NcbiAqIElBTSByb2xlIGttczpEZWNyeXB0LlxuICogMi4gR2VuZXJhdGUgYSByYW5kb20gMzItYnl0ZSBtYXN0ZXIgKiBoZWFkIC1jIDMyIC9kZXYvdXJhbmRvbSB8IGJhc2U2NFxuICogMy4gV3JhcCBpdCB3aXRoIEtNUyAqIGF3cyBrbXMgZW5jcnlwdCAtLWtleS1pZCA8S0VZX0lEPiBcXFxuICogLS1wbGFpbnRleHQgPGJhc2U2NC1mcm9tLXN0ZXAtMj4gLS1vdXRwdXQgdGV4dCBcXFxuICogLS1xdWVyeSBDaXBoZXJ0ZXh0QmxvYlxuICogNC4gU2V0IG9uIHRoZSBzZXJ2aWNlICogU0VDUkVUX0VOQ1JZUFRJT05fS01TX0tFWV9JRD08S0VZX0lEPlxuICogU0VDUkVUX0VOQ1JZUFRJT05fS01TX0NJUEhFUlRFWFQ9PGJhc2U2NC1vdXRwdXQtb2Ytc3RlcC0zPlxuICogNS4gUGljayB0aGlzIHByb3ZpZGVyIHZpYSBgc2V0S2V5UHJvdmlkZXIobmV3IEttc0tleVByb3ZpZGVyKCkpYC5cbiAqXG4gKiBDb25zdHJ1Y3QgbGF6aWx5ICBpbXBvcnRpbmcgdGhlIEFXUyBTREsgaGFzIGEgbm9uLXRyaXZpYWwgY29sZC1zdGFydFxuICogY29zdCBzbyBlbnZzIHRoYXQgc3RheSBvbiBFbnZLZXlQcm92aWRlciBuZXZlciBsb2FkIGl0LlxuICovXG4vKipcbiAqIEtNUy1kZWNyeXB0IGEgYmFzZTY0IGNpcGhlcnRleHQgaW50byBhIDMyLWJ5dGUga2V5LiBTaGFyZWQgYnkgYm90aCBLTVMga2V5XG4gKiBwcm92aWRlcnMgKHNpbmdsZS1tYXN0ZXIgKyBwZXItb3JnKSwgd2hpY2ggcHJldmlvdXNseSBjb3B5LXBhc3RlZCB0aGlzXG4gKiBkeW5hbWljLWltcG9ydCArIERlY3J5cHQgKyBlbXB0eS9sZW5ndGggZ3VhcmRzLiBgQGF3cy1zZGsvY2xpZW50LWttc2AgaXNcbiAqIGR5bmFtaWNhbGx5IGltcG9ydGVkIHNvIEVudktleVByb3ZpZGVyLW9ubHkgZW52cyBuZXZlciBsb2FkIHRoZSBTREsuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGttc0RlY3J5cHQzMihrZXlJZDogc3RyaW5nLCBjaXBoZXJ0ZXh0QjY0OiBzdHJpbmcsIHJlZ2lvbj86IHN0cmluZywgZW5kcG9pbnQ/OiBzdHJpbmcpOiBQcm9taXNlPEJ1ZmZlcj4ge1xuICBjb25zdCB7IEtNU0NsaWVudCwgRGVjcnlwdENvbW1hbmQgfSA9IGF3YWl0IGltcG9ydCgnQGF3cy1zZGsvY2xpZW50LWttcycpO1xuICBjb25zdCBjbGllbnQgPSBuZXcgS01TQ2xpZW50KHsgcmVnaW9uLCAuLi4oZW5kcG9pbnQgPyB7IGVuZHBvaW50IH0gOiB7fSkgfSk7XG4gIGNvbnN0IHJlc3AgPSBhd2FpdCBjbGllbnQuc2VuZChuZXcgRGVjcnlwdENvbW1hbmQoe1xuICAgIEtleUlkOiBrZXlJZCxcbiAgICBDaXBoZXJ0ZXh0QmxvYjogQnVmZmVyLmZyb20oY2lwaGVydGV4dEI2NCwgJ2Jhc2U2NCcpLFxuICB9KSk7XG4gIGlmICghcmVzcC5QbGFpbnRleHQpIHRocm93IG5ldyBFcnJvcihgS01TIERlY3J5cHQgcmV0dXJuZWQgYW4gZW1wdHkgUGxhaW50ZXh0IGZvciBrZXkgJHtrZXlJZH1gKTtcbiAgY29uc3QgYnVmID0gQnVmZmVyLmZyb20ocmVzcC5QbGFpbnRleHQpO1xuICBpZiAoYnVmLmxlbmd0aCAhPT0gMzIpIHRocm93IG5ldyBFcnJvcihgS01TIERlY3J5cHQgcmV0dXJuZWQgJHtidWYubGVuZ3RofS1ieXRlIGtleSBmb3IgJHtrZXlJZH07IGV4cGVjdGVkIDMyYCk7XG4gIHJldHVybiBidWY7XG59XG5cbmV4cG9ydCBjbGFzcyBLbXNLZXlQcm92aWRlciBpbXBsZW1lbnRzIEtleVByb3ZpZGVyIHtcbiAgcHJpdmF0ZSBtYXN0ZXJLZXlDYWNoZTogQnVmZmVyIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgcmVhZG9ubHkga2V5SWQ6IHN0cmluZztcbiAgcHJpdmF0ZSByZWFkb25seSBjaXBoZXJ0ZXh0QjY0OiBzdHJpbmc7XG4gIHByaXZhdGUgcmVhZG9ubHkgcmVnaW9uPzogc3RyaW5nO1xuICBwcml2YXRlIHJlYWRvbmx5IGVuZHBvaW50Pzogc3RyaW5nO1xuICBwcml2YXRlIGRlY3J5cHRJbkZsaWdodDogUHJvbWlzZTxCdWZmZXI+IHwgbnVsbCA9IG51bGw7XG5cbiAgY29uc3RydWN0b3Iob3B0cz86IHsga2V5SWQ/OiBzdHJpbmc7IGNpcGhlcnRleHRCYXNlNjQ/OiBzdHJpbmc7IHJlZ2lvbj86IHN0cmluZzsgZW5kcG9pbnQ/OiBzdHJpbmcgfSkge1xuICAgIGNvbnN0IGtleUlkID0gb3B0cz8ua2V5SWQgPz8gcHJvY2Vzcy5lbnYuU0VDUkVUX0VOQ1JZUFRJT05fS01TX0tFWV9JRDtcbiAgICBjb25zdCBjaXBoZXJ0ZXh0ID0gb3B0cz8uY2lwaGVydGV4dEJhc2U2NCA/PyBwcm9jZXNzLmVudi5TRUNSRVRfRU5DUllQVElPTl9LTVNfQ0lQSEVSVEVYVDtcbiAgICBpZiAoIWtleUlkKSB0aHJvdyBuZXcgRXJyb3IoJ1NFQ1JFVF9FTkNSWVBUSU9OX0tNU19LRVlfSUQgZW52IGlzIHJlcXVpcmVkIGZvciBLbXNLZXlQcm92aWRlcicpO1xuICAgIGlmICghY2lwaGVydGV4dCkgdGhyb3cgbmV3IEVycm9yKCdTRUNSRVRfRU5DUllQVElPTl9LTVNfQ0lQSEVSVEVYVCBlbnYgaXMgcmVxdWlyZWQgZm9yIEttc0tleVByb3ZpZGVyJyk7XG4gICAgdGhpcy5rZXlJZCA9IGtleUlkO1xuICAgIHRoaXMuY2lwaGVydGV4dEI2NCA9IGNpcGhlcnRleHQ7XG4gICAgdGhpcy5yZWdpb24gPSBvcHRzPy5yZWdpb24gPz8gcHJvY2Vzcy5lbnYuQVdTX1JFR0lPTiA/PyBwcm9jZXNzLmVudi5BV1NfREVGQVVMVF9SRUdJT047XG4gICAgdGhpcy5lbmRwb2ludCA9IG9wdHM/LmVuZHBvaW50ID8/IHByb2Nlc3MuZW52LkFXU19LTVNfRU5EUE9JTlQ7XG4gIH1cblxuICBkZXJpdmVLZXkob3JnSWQ6IHN0cmluZyk6IEJ1ZmZlciB7XG4gICAgaWYgKCF0aGlzLm1hc3RlcktleUNhY2hlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoICdLbXNLZXlQcm92aWRlciBpcyBub3Qgd2FybWVkIHVwLiBDYWxsIGBhd2FpdCBwcm92aWRlci53YXJtdXAoKWAgb25jZSBhdCBzZXJ2aWNlIHN0YXJ0dXAgYmVmb3JlIGFueSBlbmNyeXB0L2RlY3J5cHQuJyxcbiAgICAgICk7XG4gICAgfVxuICAgIGNvbnN0IGRlcml2ZWQgPSBoa2RmU3luYygnc2hhMjU2JywgdGhpcy5tYXN0ZXJLZXlDYWNoZSwgQnVmZmVyLmZyb20ob3JnSWQsICd1dGY4JyksICdzZWNyZXRzLXYxJywgMzIpO1xuICAgIHJldHVybiBCdWZmZXIuZnJvbShkZXJpdmVkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFYWdlcmx5IHJlY292ZXIgdGhlIG1hc3RlciBrZXkgZnJvbSBLTVMgc28gc3Vic2VxdWVudCBgZGVyaXZlS2V5YFxuICAgKiBjYWxscyBhcmUgc3luYy4gSWRlbXBvdGVudCAgY29uY3VycmVudCBjYWxsZXJzIHNoYXJlIHRoZSBzYW1lIGluLVxuICAgKiBmbGlnaHQgcHJvbWlzZSBzbyB3ZSBkb24ndCBzcGF3biBtdWx0aXBsZSBLTVMgRGVjcnlwdCByZXF1ZXN0cyBhdFxuICAgKiBib290LiBUaHJvd3Mgb24gYW55IEtNUyBmYWlsdXJlOyB0aGUgY2FsbGVyICh0eXBpY2FsbHkgdGhlIHNlcnZpY2Unc1xuICAgKiBvbkJlZm9yZVN0YXJ0IGhvb2spIGRlY2lkZXMgd2hldGhlciB0byBmYWxsIGJhY2sgdG8gYSBkaWZmZXJlbnRcbiAgICogcHJvdmlkZXIgb3IgZmFpbC1zdGFydHVwLlxuICAgKi9cbiAgYXN5bmMgd2FybXVwKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICh0aGlzLm1hc3RlcktleUNhY2hlKSByZXR1cm47XG4gICAgaWYgKCF0aGlzLmRlY3J5cHRJbkZsaWdodCkge1xuICAgICAgdGhpcy5kZWNyeXB0SW5GbGlnaHQgPSB0aGlzLmZldGNoQW5kRGVjcnlwdCgpO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgdGhpcy5tYXN0ZXJLZXlDYWNoZSA9IGF3YWl0IHRoaXMuZGVjcnlwdEluRmxpZ2h0O1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgLy8gQSB0cmFuc2llbnQgS01TIGZhaWx1cmUgbXVzdCBub3QgcGVybWFuZW50bHkgcG9pc29uIHRoZSBwcm92aWRlcjogY2xlYXJcbiAgICAgIC8vIHRoZSByZWplY3RlZCBpbi1mbGlnaHQgcHJvbWlzZSBzbyBhIGxhdGVyIHdhcm11cCgpIHJldHJpZXMgaW5zdGVhZCBvZlxuICAgICAgLy8gcmUtYXdhaXRpbmcgdGhlIHNhbWUgcmVqZWN0aW9uIGZvcmV2ZXIgKG1hdGNoZXMgUGVyT3JnS21zS2V5UHJvdmlkZXIpLlxuICAgICAgdGhpcy5kZWNyeXB0SW5GbGlnaHQgPSBudWxsO1xuICAgICAgdGhyb3cgZXJyO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZmV0Y2hBbmREZWNyeXB0KCk6IFByb21pc2U8QnVmZmVyPiB7XG4gICAgcmV0dXJuIGttc0RlY3J5cHQzMih0aGlzLmtleUlkLCB0aGlzLmNpcGhlcnRleHRCNjQsIHRoaXMucmVnaW9uLCB0aGlzLmVuZHBvaW50KTtcbiAgfVxufVxuXG4vLyBMYXp5IHNpbmdsZXRvbiAgb3BlcmF0b3IgY29kZSBpbiBsb25nLWxpdmVkIHNlcnZpY2VzIHBheXMgdGhlIGVudi1wYXJzZVxuLy8gY29zdCBvbmNlLCBhbmQgdGVzdHMgY2FuIG1pbnQgdGhlaXIgb3duIHByb3ZpZGVyIHdpdGggYSBsaXRlcmFsIGtleS5cbmxldCBkZWZhdWx0UHJvdmlkZXI6IEtleVByb3ZpZGVyIHwgbnVsbCA9IG51bGw7XG5mdW5jdGlvbiBnZXREZWZhdWx0UHJvdmlkZXIoKTogS2V5UHJvdmlkZXIge1xuICBpZiAoIWRlZmF1bHRQcm92aWRlcikgZGVmYXVsdFByb3ZpZGVyID0gbmV3IEVudktleVByb3ZpZGVyKCk7XG4gIHJldHVybiBkZWZhdWx0UHJvdmlkZXI7XG59XG5cbi8qKiBSZWFkIHRoZSBhY3RpdmUgZGVmYXVsdCBwcm92aWRlci4gRXhwb3NlZCBzbyBzZXJ2aWNlIGNvZGUgKGUuZy4gYW5cbiAqICBhZG1pbiBlbmRwb2ludCB0aGF0IGp1c3Qgcm90YXRlZCBhbiBvcmcncyBLTVMgY29uZmlnKSBjYW4gY2FsbFxuICogIGBwcm92aWRlci5ldmljdChvcmdJZClgIG9uIHRoZSBsaXZlIHByb3ZpZGVyIHJhdGhlciB0aGFuIHJlY29uc3RydWN0aW5nXG4gKiAgb25lLiBUcmlnZ2VycyBsYXp5IGluaXRpYWxpemF0aW9uIG9uIGZpcnN0IGFjY2Vzcywgc2FtZSBhcyB0aGUgaW50ZXJuYWxcbiAqICBjYWxsZXJzIGJlbG93LiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldERlZmF1bHRLZXlQcm92aWRlcigpOiBLZXlQcm92aWRlciB7XG4gIHJldHVybiBnZXREZWZhdWx0UHJvdmlkZXIoKTtcbn1cblxuLyoqIFJlc2V0IHRoZSBjYWNoZWQgZGVmYXVsdCBwcm92aWRlciAgZm9yIHRlc3RzIHRoYXQgbXV0YXRlIGBwcm9jZXNzLmVudmAuICovXG5leHBvcnQgZnVuY3Rpb24gcmVzZXREZWZhdWx0S2V5UHJvdmlkZXIoKTogdm9pZCB7IGRlZmF1bHRQcm92aWRlciA9IG51bGw7IH1cblxuLyoqIFJlcGxhY2UgdGhlIGRlZmF1bHQgcHJvdmlkZXIgIHNlcnZpY2VzIHRoYXQgb3B0IGludG8gS01TIGNhbGwgdGhpc1xuICogb25jZSBhdCBzdGFydHVwIHdpdGggYSB3YXJtZWQtdXAgYEttc0tleVByb3ZpZGVyYC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZXRLZXlQcm92aWRlcihwcm92aWRlcjogS2V5UHJvdmlkZXIpOiB2b2lkIHsgZGVmYXVsdFByb3ZpZGVyID0gcHJvdmlkZXI7IH1cblxuLyoqIFBlci1vcmcgS01TIGNvbmZpZyB0aGUgb3BlcmF0b3Igc3VwcGxpZXMuIFRoZSBga2V5SWRgIGlkZW50aWZpZXMgdGhlXG4gKiAgS01TIENNSyB0byBjYWxsIERlY3J5cHQgb247IGBjaXBoZXJ0ZXh0QmFzZTY0YCBpcyB0aGUgd3JhcHBlZCAzMi1ieXRlXG4gKiAgbWFzdGVyIGdlbmVyYXRlZCBieSBgYXdzIGttcyBlbmNyeXB0YCBhZ2FpbnN0IHRoYXQga2V5LiAqL1xuZXhwb3J0IGludGVyZmFjZSBQZXJPcmdLbXNDb25maWcge1xuICBrZXlJZDogc3RyaW5nO1xuICBjaXBoZXJ0ZXh0QmFzZTY0OiBzdHJpbmc7XG59XG5cbi8qKlxuICogQXN5bmMgcmVzb2x2ZXIgdGhhdCBtYXBzIGFuIG9yZyBpZCB0byBpdHMgS01TIGNvbmZpZy4gUmV0dXJucyBgbnVsbGAgd2hlblxuICogdGhlIG9yZyBoYXMgbm8gcGVyLW9yZyBjb25maWcg4oCUIHRoZSBwcm92aWRlciB0aGVuIGZhbGxzIGJhY2sgdG8gdGhlXG4gKiBgZmFsbGJhY2tgIHByb3ZpZGVyIHN1cHBsaWVkIGF0IGNvbnN0cnVjdGlvbiAodXN1YWxseSBhbiBFbnZLZXlQcm92aWRlclxuICogb3IgYSBkZWZhdWx0IEttc0tleVByb3ZpZGVyKS5cbiAqL1xuZXhwb3J0IHR5cGUgUGVyT3JnS21zUmVzb2x2ZXIgPSAob3JnSWQ6IHN0cmluZykgPT4gUHJvbWlzZTxQZXJPcmdLbXNDb25maWcgfCBudWxsPjtcblxuLyoqXG4gKiBQZXItb3JnIEtNUy1iYWNrZWQgS2V5UHJvdmlkZXIuIFRoZSBibGFzdCByYWRpdXMgb2YgYSBLTVMga2V5IGNvbXByb21pc2VcbiAqIGlzIG9uZSBvcmcgaW5zdGVhZCBvZiBldmVyeSBvcmcgdW5kZXIgYSBzaGFyZWQgbWFzdGVyLlxuICpcbiAqIEVhY2ggb3JnIGhhcyBpdHMgb3duIEtNUyBDTUsgKyBpdHMgb3duIHdyYXBwZWQgbWFzdGVyIChzdG9yZWQgaW4gTW9uZ29cbiAqIHZpYSB0aGUgb3BlcmF0b3IncyBzZXR1cCBzY3JpcHQpLiBPbiBmaXJzdCBlbmNyeXB0L2RlY3J5cHQgZm9yIGFuIG9yZyxcbiAqIHRoZSBwcm92aWRlcjpcbiAqICAgMS4gQ2FsbHMgdGhlIHJlc29sdmVyIHRvIGZldGNoIHRoZSBvcmcncyBLTVMgY29uZmlnLlxuICogICAyLiBDYWxscyBga21zOkRlY3J5cHRgIHRvIHJlY292ZXIgdGhlIDMyLWJ5dGUgbWFzdGVyLlxuICogICAzLiBDYWNoZXMgdGhlIHJlY292ZXJlZCBtYXN0ZXIgaW4tbWVtb3J5IGZvciB0aGUgcHJvY2VzcyBsaWZldGltZS5cbiAqICAgNC4gSEtERi1kZXJpdmVzIHBlci1jYWxsIGZyb20gdGhhdCBtYXN0ZXIgKyB0aGUgb3JnIGlkIHNhbHQuXG4gKlxuICogQmxvYnMgZW5jcnlwdGVkIGJ5IHRoaXMgcHJvdmlkZXIgY2FycnkgYGtpZCA9IDxrbXMta2V5LWlkPmAgc28gdGhlXG4gKiBkZWNyeXB0IHBhdGggZGV0ZWN0cyBhIHN0YWxlIGNvbmZpZyAob3BlcmF0b3Igcm90YXRlZCB0aGUga2V5IGJ1dFxuICogZXhpc3Rpbmcgcm93cyB3ZXJlbid0IHJlLWVuY3J5cHRlZCkgQkVGT1JFIEFFUy1HQ00gdGhyb3dzIGFuIG9wYXF1ZVxuICogYXV0aGVudGljYXRpb24tdGFnIGVycm9yLlxuICpcbiAqIE9yZ3Mgd2l0aG91dCBwZXItb3JnIGNvbmZpZyBmYWxsIHRocm91Z2ggdG8gdGhlIGBmYWxsYmFja2AgcHJvdmlkZXIg4oCUXG4gKiBtaXhlZC1tb2RlIGRlcGxveW1lbnRzIHdoZXJlIHNvbWUgb3JncyBoYXZlIEtNUyBpc29sYXRpb24gYW5kIG90aGVyc1xuICogc3RheSBvbiB0aGUgc2hhcmVkIG1hc3RlciBhcmUgZXhwbGljaXRseSBzdXBwb3J0ZWQuXG4gKi9cbmV4cG9ydCBjbGFzcyBQZXJPcmdLbXNLZXlQcm92aWRlciBpbXBsZW1lbnRzIEtleVByb3ZpZGVyIHtcbiAgLyoqIENhY2hlZCBwZXItb3JnIG1hc3RlciBrZXlzLCBrZXllZCBieSBvcmdJZC4gKi9cbiAgcHJpdmF0ZSByZWFkb25seSBtYXN0ZXJzID0gbmV3IE1hcDxzdHJpbmcsIHsga2V5OiBCdWZmZXI7IGtpZDogc3RyaW5nIH0+KCk7XG4gIC8qKiBSZXNvbHZlZCBwZXItb3JnIGNvbmZpZ3MgY2FjaGVkIGZvciB0aGUgcHJvY2VzcyBsaWZldGltZS4gKi9cbiAgcHJpdmF0ZSByZWFkb25seSBjb25maWdzID0gbmV3IE1hcDxzdHJpbmcsIFBlck9yZ0ttc0NvbmZpZz4oKTtcbiAgLyoqIEluLWZsaWdodCByZXNvbHZlciBwcm9taXNlcyBzbyBjb25jdXJyZW50IGZpcnN0LXRvdWNoIGNhbGxlcnMgc2hhcmUgb25lIEtNUyBEZWNyeXB0LlxuICAgKiAgUmVzb2x2ZXMgdG8gYG51bGxgIGZvciBvcmdzIHdpdGggbm8gcGVyLW9yZyBjb25maWcg4oCUIGNhbGxlciB0cmVhdHMgbnVsbCBhc1xuICAgKiAgXCJmYWxsIHRocm91Z2ggdG8gdGhlIGZhbGxiYWNrIHByb3ZpZGVyXCIsIHNhbWUgYXMgYSBjb2xkIGNhY2hlIG1pc3MuICovXG4gIHByaXZhdGUgcmVhZG9ubHkgaW5GbGlnaHQgPSBuZXcgTWFwPHN0cmluZywgUHJvbWlzZTx7IGtleTogQnVmZmVyOyBraWQ6IHN0cmluZyB9IHwgbnVsbD4+KCk7XG4gIC8qKiBPcmdzIHRoZSByZXNvbHZlciBoYXMgUFJPVkVOIGhhdmUgbm8gcGVyLW9yZyBjb25maWcg4oCUIHRoZSBmYWxsYmFjayBwcm92aWRlclxuICAgKiAgaXMgdGhlIGNvcnJlY3QgYW5zd2VyIGZvciB0aGVzZSwgYW5kIGBkZXJpdmVLZXlgIG1heSBzZXJ2ZSB0aGVtXG4gICAqICBzeW5jaHJvbm91c2x5LiBEaXN0aW5jdCBmcm9tIFwibm90IHlldCByZXNvbHZlZFwiLCB3aGljaCBtdXN0IG5vdCBndWVzcy4gKi9cbiAgcHJpdmF0ZSByZWFkb25seSByZXNvbHZlZE5vUGVyT3JnQ29uZmlnID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gIC8qKiBQcm92aWRlciB1c2VkIGZvciBvcmdzIHRoYXQgaGF2ZSBubyBwZXItb3JnIGNvbmZpZy4gKi9cbiAgcHJpdmF0ZSByZWFkb25seSBmYWxsYmFjazogS2V5UHJvdmlkZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgcmVzb2x2ZXI6IFBlck9yZ0ttc1Jlc29sdmVyO1xuICBwcml2YXRlIHJlYWRvbmx5IHJlZ2lvbj86IHN0cmluZztcbiAgcHJpdmF0ZSByZWFkb25seSBlbmRwb2ludD86IHN0cmluZztcblxuICBjb25zdHJ1Y3RvcihvcHRzOiB7XG4gICAgcmVzb2x2ZXI6IFBlck9yZ0ttc1Jlc29sdmVyO1xuICAgIGZhbGxiYWNrOiBLZXlQcm92aWRlcjtcbiAgICByZWdpb24/OiBzdHJpbmc7XG4gICAgZW5kcG9pbnQ/OiBzdHJpbmc7XG4gIH0pIHtcbiAgICB0aGlzLnJlc29sdmVyID0gb3B0cy5yZXNvbHZlcjtcbiAgICB0aGlzLmZhbGxiYWNrID0gb3B0cy5mYWxsYmFjaztcbiAgICB0aGlzLnJlZ2lvbiA9IG9wdHMucmVnaW9uID8/IHByb2Nlc3MuZW52LkFXU19SRUdJT04gPz8gcHJvY2Vzcy5lbnYuQVdTX0RFRkFVTFRfUkVHSU9OO1xuICAgIHRoaXMuZW5kcG9pbnQgPSBvcHRzLmVuZHBvaW50ID8/IHByb2Nlc3MuZW52LkFXU19LTVNfRU5EUE9JTlQ7XG4gIH1cblxuICAvKipcbiAgICogU3luYyBkZXJpdmUuIE9ubHkgY29ycmVjdCBmb3IgYW4gb3JnIHdob3NlIGNvbmZpZyBoYXMgYWxyZWFkeSBiZWVuXG4gICAqIFJFU09MVkVEIOKAlCBlaXRoZXIgaXQgaGFzIGEgcGVyLW9yZyBtYXN0ZXIgKHVzZSBpdCkgb3IgaXQgcHJvdmFibHkgaGFzIG5vXG4gICAqIHBlci1vcmcgY29uZmlnICh0aGUgZmFsbGJhY2sgaXMgdGhlbiB0aGUgcmlnaHQgYW5zd2VyKS5cbiAgICpcbiAgICogRm9yIGFuIFVOUkVTT0xWRUQgb3JnIHRoaXMgVEhST1dTIHJhdGhlciB0aGFuIGd1ZXNzaW5nLiBJdCB1c2VkIHRvIGZhbGxcbiAgICogdGhyb3VnaCB0byB0aGUgZmFsbGJhY2ssIHdoaWNoIHNpbGVudGx5IGVuY3J5cHRlZCB0aGF0IG9yZydzIHNlY3JldHMgdW5kZXJcbiAgICogdGhlIFNIQVJFRCBtYXN0ZXIgYW5kIOKAlCBiZWNhdXNlIGBraWRGb3JgIGFsc28gcmV0dXJuZWQgdW5kZWZpbmVkLCBzbyB0aGVcbiAgICogYm90aC1raWRzLXByZXNlbnQgbWlzbWF0Y2ggZ3VhcmQgY291bGQgbmV2ZXIgZmlyZSDigJQgbGVmdCB0aGVtIHBlcm1hbmVudGx5XG4gICAqIHVuZGVjcnlwdGFibGUgb25jZSB0aGUgb3JnIHdhcm1lZDogYGRlY2lwaGVyLmZpbmFsKClgIHRoZW4gdGhyZXcgYW4gb3BhcXVlXG4gICAqIGF1dGgtdGFnIGVycm9yIHdpdGggbm8gZGlhZ25vc3RpYy4gRmFpbGluZyBsb3VkIGhlcmUgbWF0Y2hlc1xuICAgKiBgS21zS2V5UHJvdmlkZXIuZGVyaXZlS2V5YCwgd2hpY2ggaGFzIGFsd2F5cyByZWZ1c2VkIHRvIHdvcmsgY29sZC5cbiAgICpcbiAgICogYGVuY3J5cHRTZWNyZXRgL2BkZWNyeXB0U2VjcmV0YCBhcmUgYXN5bmMgYW5kIGF3YWl0IGBkZXJpdmVLZXlBc3luY2AsIHNvXG4gICAqIHRoZXkgcmVzb2x2ZSB0aGUgb3JnIGZpcnN0IGFuZCBuZXZlciBoaXQgdGhpcyBwYXRoOyBpdCBpcyB0aGUgYmFja3N0b3AgZm9yXG4gICAqIGEgY2FsbGVyIHRoYXQgcmVhY2hlcyBmb3IgdGhlIHN5bmMgQVBJIGRpcmVjdGx5LlxuICAgKi9cbiAgZGVyaXZlS2V5KG9yZ0lkOiBzdHJpbmcpOiBCdWZmZXIge1xuICAgIGNvbnN0IGNhY2hlZCA9IHRoaXMubWFzdGVycy5nZXQob3JnSWQpO1xuICAgIGlmICghY2FjaGVkKSB7XG4gICAgICBpZiAodGhpcy5yZXNvbHZlZE5vUGVyT3JnQ29uZmlnLmhhcyhvcmdJZCkpIHJldHVybiB0aGlzLmZhbGxiYWNrLmRlcml2ZUtleShvcmdJZCk7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoIGBQZXJPcmdLbXNLZXlQcm92aWRlciBoYXMgbm90IHJlc29sdmVkIG9yZyAke29yZ0lkfS4gYFxuICAgICAgICArICdDYWxsIGBhd2FpdCBwcm92aWRlci5lbnN1cmVXYXJtZWQob3JnSWQpYCAob3IgdXNlIHRoZSBhc3luYyBlbmNyeXB0U2VjcmV0L2RlY3J5cHRTZWNyZXQpICdcbiAgICAgICAgKyAnYmVmb3JlIGRlcml2aW5nIGEga2V5IOKAlCBndWVzc2luZyB0aGUgc2hhcmVkIG1hc3RlciB3b3VsZCB3cml0ZSBzZWNyZXRzIHRoYXQgY2Fubm90IGJlIGRlY3J5cHRlZCBsYXRlci4nLFxuICAgICAgKTtcbiAgICB9XG4gICAgY29uc3QgZGVyaXZlZCA9IGhrZGZTeW5jKCdzaGEyNTYnLCBjYWNoZWQua2V5LCBCdWZmZXIuZnJvbShvcmdJZCwgJ3V0ZjgnKSwgJ3NlY3JldHMtdjEnLCAzMik7XG4gICAgcmV0dXJuIEJ1ZmZlci5mcm9tKGRlcml2ZWQpO1xuICB9XG5cbiAgYXN5bmMgZGVyaXZlS2V5QXN5bmMob3JnSWQ6IHN0cmluZyk6IFByb21pc2U8QnVmZmVyPiB7XG4gICAgYXdhaXQgdGhpcy5lbnN1cmVXYXJtZWQob3JnSWQpO1xuICAgIHJldHVybiB0aGlzLmRlcml2ZUtleShvcmdJZCk7XG4gIH1cblxuICBraWRGb3Iob3JnSWQ6IHN0cmluZyk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgY2FjaGVkID0gdGhpcy5tYXN0ZXJzLmdldChvcmdJZCk7XG4gICAgaWYgKGNhY2hlZCkgcmV0dXJuIGNhY2hlZC5raWQ7XG4gICAgLy8gT25seSBzcGVhayBmb3IgYW4gb3JnIHdob3NlIGNvbmZpZyBpcyByZXNvbHZlZDsgYW4gdW5yZXNvbHZlZCBvcmcgaGFzIG5vXG4gICAgLy8gbWVhbmluZ2Z1bCBraWQsIGFuZCBjbGFpbWluZyBvbmUgd291bGQgZGVmZWF0IHRoZSBtaXNtYXRjaCBndWFyZC5cbiAgICBpZiAodGhpcy5yZXNvbHZlZE5vUGVyT3JnQ29uZmlnLmhhcyhvcmdJZCkpIHJldHVybiB0aGlzLmZhbGxiYWNrLmtpZEZvcj8uKG9yZ0lkKTtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlc29sdmUgdGhlIG9yZydzIEtNUyBjb25maWcsIGNhbGwgRGVjcnlwdCwgY2FjaGUgdGhlIG1hc3Rlci4gU3Vic2VxdWVudFxuICAgKiBjYWxscyBmb3IgdGhlIHNhbWUgb3JnIGFyZSBuby1vcHMuIENvbmN1cnJlbnQgY2FsbGVycyBzaGFyZSB0aGUgaW4tZmxpZ2h0XG4gICAqIERlY3J5cHQgcHJvbWlzZS5cbiAgICpcbiAgICogUmV0dXJucyBzaWxlbnRseSB3aGVuIHRoZSBvcmcgaGFzIG5vIHBlci1vcmcgY29uZmlnIOKAlCB0aGUgZmFsbGJhY2tcbiAgICogcHJvdmlkZXIgaGFuZGxlcyB0aG9zZSBvcmdzLlxuICAgKi9cbiAgYXN5bmMgZW5zdXJlV2FybWVkKG9yZ0lkOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAodGhpcy5tYXN0ZXJzLmhhcyhvcmdJZCkpIHJldHVybjtcbiAgICAvLyBJbnN0YWxsIHRoZSBpbi1mbGlnaHQgcHJvbWlzZSBTWU5DSFJPTk9VU0xZIGJlZm9yZSB5aWVsZGluZyBzbyBjb25jdXJyZW50XG4gICAgLy8gY2FsbGVycyBmaW5kIGl0IG9uIHRoZSBzZWNvbmQtYW5kLWxhdGVyIHBhc3Nlcy4gQXdhaXRpbmcgdGhlIHJlc29sdmVyXG4gICAgLy8gYmVmb3JlIHBvcHVsYXRpbmcgdGhlIG1hcCBpcyB0aGUgYnVnIHRoYXQgbGV0cyBhIFByb21pc2UuYWxsIG9mIDNcbiAgICAvLyBjYWxsZXJzIGZpcmUgMyBLTVMgRGVjcnlwdHMuXG4gICAgbGV0IHByb21pc2UgPSB0aGlzLmluRmxpZ2h0LmdldChvcmdJZCk7XG4gICAgaWYgKCFwcm9taXNlKSB7XG4gICAgICBwcm9taXNlID0gdGhpcy5yZXNvbHZlQW5kRGVjcnlwdChvcmdJZCk7XG4gICAgICB0aGlzLmluRmxpZ2h0LnNldChvcmdJZCwgcHJvbWlzZSk7XG4gICAgICB2b2lkIHByb21pc2UuZmluYWxseSgoKSA9PiB7IGlmICh0aGlzLmluRmxpZ2h0LmdldChvcmdJZCkgPT09IHByb21pc2UpIHRoaXMuaW5GbGlnaHQuZGVsZXRlKG9yZ0lkKTsgfSk7XG4gICAgfVxuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHByb21pc2U7XG4gICAgaWYgKHJlc3VsdCkgdGhpcy5tYXN0ZXJzLnNldChvcmdJZCwgcmVzdWx0KTtcbiAgICAvLyBSZW1lbWJlciB0aGUgTkVHQVRJVkUgb3V0Y29tZSB0b28sIHNvIHRoZSBzeW5jIGBkZXJpdmVLZXlgIGNhbiB0ZWxsXG4gICAgLy8gXCJubyBwZXItb3JnIGNvbmZpZywgZmFsbGJhY2sgaXMgY29ycmVjdFwiIGZyb20gXCJub3QgcmVzb2x2ZWQgeWV0XCIuXG4gICAgZWxzZSB0aGlzLnJlc29sdmVkTm9QZXJPcmdDb25maWcuYWRkKG9yZ0lkKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgcmVzb2x2ZUFuZERlY3J5cHQob3JnSWQ6IHN0cmluZyk6IFByb21pc2U8eyBrZXk6IEJ1ZmZlcjsga2lkOiBzdHJpbmcgfSB8IG51bGw+IHtcbiAgICBsZXQgY2ZnID0gdGhpcy5jb25maWdzLmdldChvcmdJZCk7XG4gICAgaWYgKCFjZmcpIHtcbiAgICAgIGNvbnN0IHJlc29sdmVkID0gYXdhaXQgdGhpcy5yZXNvbHZlcihvcmdJZCk7XG4gICAgICBpZiAoIXJlc29sdmVkKSByZXR1cm4gbnVsbDsgLy8gbm8gcGVyLW9yZyBjb25maWcg4oaSIGNhbGxlciB1c2VzIGZhbGxiYWNrXG4gICAgICBjZmcgPSByZXNvbHZlZDtcbiAgICAgIHRoaXMuY29uZmlncy5zZXQob3JnSWQsIGNmZyk7XG4gICAgfVxuICAgIGNvbnN0IGtleSA9IGF3YWl0IHRoaXMuZmV0Y2hBbmREZWNyeXB0KGNmZyk7XG4gICAgcmV0dXJuIHsga2V5LCBraWQ6IGNmZy5rZXlJZCB9O1xuICB9XG5cbiAgcHJpdmF0ZSBmZXRjaEFuZERlY3J5cHQoY2ZnOiBQZXJPcmdLbXNDb25maWcpOiBQcm9taXNlPEJ1ZmZlcj4ge1xuICAgIHJldHVybiBrbXNEZWNyeXB0MzIoY2ZnLmtleUlkLCBjZmcuY2lwaGVydGV4dEJhc2U2NCwgdGhpcy5yZWdpb24sIHRoaXMuZW5kcG9pbnQpO1xuICB9XG5cbiAgLyoqIEV2aWN0IGEgY2FjaGVkIHBlci1vcmcgbWFzdGVyLiBVc2UgYWZ0ZXIgYSBrZXkgcm90YXRpb24gc28gdGhlIG5leHRcbiAgICogIHRvdWNoIHJlLWZldGNoZXMgdGhlIG5ldyB3cmFwcGVkIG1hc3RlciBmcm9tIHRoZSByZXNvbHZlci4gKi9cbiAgZXZpY3Qob3JnSWQ6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMubWFzdGVycy5kZWxldGUob3JnSWQpO1xuICAgIHRoaXMuY29uZmlncy5kZWxldGUob3JnSWQpO1xuICAgIC8vIEFsc28gZm9yZ2V0IGEgTkVHQVRJVkUgcmVzb2x1dGlvbiwgb3IgYW4gb3JnIHRoYXQgZ2FpbnMgYSBwZXItb3JnIGNvbmZpZ1xuICAgIC8vIGFmdGVyIGJlaW5nIHJlc29sdmVkIGFzIFwibm8gY29uZmlnXCIgd291bGQga2VlcCB1c2luZyB0aGUgc2hhcmVkIG1hc3Rlci5cbiAgICB0aGlzLnJlc29sdmVkTm9QZXJPcmdDb25maWcuZGVsZXRlKG9yZ0lkKTtcbiAgfVxufVxuXG4vKipcbiAqIERlcml2ZSB0aGUga2V5IGZvciBgb3JnSWRgLCBnaXZpbmcgdGhlIHByb3ZpZGVyIGEgY2hhbmNlIHRvIGRvIEkvTyBmaXJzdC5cbiAqXG4gKiBUaGlzIGlzIHdoeSBgZW5jcnlwdFNlY3JldGAvYGRlY3J5cHRTZWNyZXRgIGFyZSBhc3luYzogYFBlck9yZ0ttc0tleVByb3ZpZGVyYFxuICogbmVlZHMgb25lIEtNUyBEZWNyeXB0IHRoZSBmaXJzdCB0aW1lIGl0IHNlZXMgYW4gb3JnLCBhbmQgZGVyaXZpbmdcbiAqIHN5bmNocm9ub3VzbHkgYmVmb3JlIHRoYXQgcmVzb2x2ZXMgd291bGQgc2lsZW50bHkgZmFsbCBiYWNrIHRvIHRoZSBzaGFyZWRcbiAqIG1hc3RlciBhbmQgcHJvZHVjZSBzZWNyZXRzIHRoYXQgY2Fubm90IGJlIGRlY3J5cHRlZCBhZnRlcndhcmRzLlxuICovXG5hc3luYyBmdW5jdGlvbiBkZXJpdmVLZXlGb3IocHJvdmlkZXI6IEtleVByb3ZpZGVyLCBvcmdJZDogc3RyaW5nKTogUHJvbWlzZTxCdWZmZXI+IHtcbiAgcmV0dXJuIHByb3ZpZGVyLmRlcml2ZUtleUFzeW5jID8gcHJvdmlkZXIuZGVyaXZlS2V5QXN5bmMob3JnSWQpIDogcHJvdmlkZXIuZGVyaXZlS2V5KG9yZ0lkKTtcbn1cblxuLyoqXG4gKiBFbmNyeXB0IGEgcGxhaW50ZXh0IHN0cmluZyBmb3Igc3RvcmFnZS4gUmV0dXJucyBhbiBgRW5jcnlwdGVkQmxvYmAgdGhhdFxuICogY2FuIGJlIEpTT04tc2VyaWFsaXplZCBpbnRvIHRoZSB1bmRlcmx5aW5nIGNvbHVtbiAvIE1vbmdvIGRvY3VtZW50LlxuICpcbiAqIEVtcHR5IHN0cmluZ3Mgcm91bmQtdHJpcCBhcyBgbnVsbGAgc28gdGhlIGNhbGxpbmcgbW9kZWwgbGF5ZXIgY2FuIHRyZWF0XG4gKiBcIm5vIHNlY3JldCBzZXRcIiBpZGVudGljYWxseSB0byBcImZpZWxkIGFic2VudFwiLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZW5jcnlwdFNlY3JldCggcGxhaW50ZXh0OiBzdHJpbmcsXG4gIG9yZ0lkOiBzdHJpbmcsXG4gIHByb3ZpZGVyOiBLZXlQcm92aWRlciA9IGdldERlZmF1bHRQcm92aWRlcigpLFxuKTogUHJvbWlzZTxFbmNyeXB0ZWRCbG9iPiB7XG4gIGlmICghcGxhaW50ZXh0KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdSZWZ1c2luZyB0byBlbmNyeXB0IGVtcHR5IHN0cmluZzsgY2FsbGVyIHNob3VsZCBzdG9yZSBudWxsIGluc3RlYWQnKTtcbiAgfVxuICAvLyBSZXNvbHZlIChhbmQgd2FybSkgdGhlIG9yZyBCRUZPUkUgcmVhZGluZyBga2lkRm9yYCBiZWxvdywgc28gYSBwZXItb3JnIEtNU1xuICAvLyBibG9iIGlzIGFsd2F5cyBzdGFtcGVkIHdpdGggdGhlIGtleSBpdCB3YXMgYWN0dWFsbHkgZW5jcnlwdGVkIHVuZGVyLlxuICBjb25zdCBrZXkgPSBhd2FpdCBkZXJpdmVLZXlGb3IocHJvdmlkZXIsIG9yZ0lkKTtcbiAgY29uc3QgaXYgPSByYW5kb21CeXRlcygxMik7XG4gIGNvbnN0IGNpcGhlciA9IGNyZWF0ZUNpcGhlcml2KCdhZXMtMjU2LWdjbScsIGtleSwgaXYpO1xuICBjb25zdCBlbmMgPSBCdWZmZXIuY29uY2F0KFtjaXBoZXIudXBkYXRlKHBsYWludGV4dCwgJ3V0ZjgnKSwgY2lwaGVyLmZpbmFsKCldKTtcbiAgY29uc3QgdGFnID0gY2lwaGVyLmdldEF1dGhUYWcoKTtcbiAgLy8gUGVyT3JnS21zS2V5UHJvdmlkZXIgdGFncyBibG9icyB3aXRoIHRoZSBLTVMga2V5IGlkIHVzZWQgc28gdGhlXG4gIC8vIGRlY3J5cHQgcGF0aCBjYW4gcmVmdXNlIHRvIG9wZXJhdGUgaWYgdGhlIG9wZXJhdG9yIGxhdGVyIHN3YXBzIGluIGFcbiAgLy8gZGlmZmVyZW50IHBlci1vcmcgY29uZmlnIChhIG1pc2NvbmZpZ3VyZWQgc3dhcCBzaG91bGRuJ3Qgc2lsZW50bHlcbiAgLy8gYWNjZXB0IGEgc3RhbGUgYmxvYiBpdCBjYW4ndCB2ZXJpZnkgYWdhaW5zdCB0aGUgcmlnaHQgQ01LKS5cbiAgY29uc3Qga2lkID0gcHJvdmlkZXIua2lkRm9yPy4ob3JnSWQpO1xuICByZXR1cm4ge1xuICAgIGFsZzogJ2Flcy0yNTYtZ2NtLXYxJyxcbiAgICBpdjogaXYudG9TdHJpbmcoJ2Jhc2U2NCcpLFxuICAgIC8vIEdDTSB0YWcgTVVTVCB0cmF2ZWwgd2l0aCB0aGUgY2lwaGVydGV4dCBvciBgZGVjcnlwdFNlY3JldGAgY2FuJ3RcbiAgICAvLyB2ZXJpZnkgaW50ZWdyaXR5ICBjb25jYXRlbmF0ZSBzbyB0aGUgb24tZGlzayBzaGFwZSBpcyBvbmUgZmllbGQuXG4gICAgY2lwaGVydGV4dDogQnVmZmVyLmNvbmNhdChbZW5jLCB0YWddKS50b1N0cmluZygnYmFzZTY0JyksXG4gICAgLi4uKGtpZCAhPT0gdW5kZWZpbmVkID8geyBraWQgfSA6IHt9KSxcbiAgfTtcbn1cblxuLyoqXG4gKiBEZWNyeXB0IGFuIGBFbmNyeXB0ZWRCbG9iYCB3cml0dGVuIGJ5IGBlbmNyeXB0U2VjcmV0YC4gVGhyb3dzIG9uICogLSB1bmtub3duIGBhbGdgIChmb3JjZXMgYW4gZXhwbGljaXQgbWlncmF0aW9uIHdoZW4gdGhlIGZvcm1hdCBjaGFuZ2VzKVxuICogLSB3cm9uZyBvcmdJZCAoSEtERiBiaW5kaW5nIG1pc21hdGNoIGZhaWxzIHRoZSBhdXRoIHRhZylcbiAqIC0gdGFtcGVyZWQgY2lwaGVydGV4dCAoR0NNIGF1dGggdGFnIGNoZWNrIGZhaWxzKVxuICpcbiAqIENhbGxlcnMgaGFuZGxlIHRoZSB0aHJvdyAgbWFza2luZyB0aGUgZmFpbHVyZSBhcyBgbnVsbGAgd291bGQgaGlkZVxuICogc2lsZW50IGNvcnJ1cHRpb24gLyB3cm9uZy1vcmcgcmVhZHMuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBkZWNyeXB0U2VjcmV0KCBibG9iOiBFbmNyeXB0ZWRCbG9iLFxuICBvcmdJZDogc3RyaW5nLFxuICBwcm92aWRlcjogS2V5UHJvdmlkZXIgPSBnZXREZWZhdWx0UHJvdmlkZXIoKSxcbik6IFByb21pc2U8c3RyaW5nPiB7XG4gIGlmIChibG9iLmFsZyAhPT0gJ2Flcy0yNTYtZ2NtLXYxJykge1xuICAgIHRocm93IG5ldyBFcnJvcihgVW5zdXBwb3J0ZWQgZW5jcnlwdGlvbiBhbGc6ICR7YmxvYi5hbGd9YCk7XG4gIH1cbiAgLy8gV2FybSBmaXJzdDogYGtpZEZvcmAgYW5kIGBkZXJpdmVLZXlgIGJlbG93IG11c3QgYm90aCBzcGVhayBmb3IgdGhlIG9yZydzXG4gIC8vIHJlYWwgY29uZmlnLCBvciB0aGUgbWlzbWF0Y2ggZ3VhcmQgc2lsZW50bHkgbm8tb3BzLlxuICBjb25zdCBrZXkgPSBhd2FpdCBkZXJpdmVLZXlGb3IocHJvdmlkZXIsIG9yZ0lkKTtcbiAgLy8gSWYgYm90aCB0aGUgcHJvdmlkZXIgQU5EIHRoZSBibG9iIHJlcG9ydCBhIGtpZCwgdGhleSBtdXN0IG1hdGNoLlxuICAvLyBNaXNtYXRjaCB1c3VhbGx5IG1lYW5zIGFuIG9wZXJhdG9yIHJvdGF0ZWQvcmVwbGFjZWQgYW4gb3JnJ3MgS01TXG4gIC8vIGNvbmZpZyBhbmQgaXMgbm93IHJlYWRpbmcgYSBibG9iIGVuY3J5cHRlZCB1bmRlciB0aGUgT0xEIGtleSDigJRcbiAgLy8gZmFpbGluZyBsb3VkIGhlcmUgYmVhdHMgbGV0dGluZyBBRVMtR0NNIHRocm93IGFuIG9wYXF1ZSBhdXRoLXRhZyBlcnJvci5cbiAgY29uc3QgcHJvdmlkZXJLaWQgPSBwcm92aWRlci5raWRGb3I/LihvcmdJZCk7XG4gIGlmIChwcm92aWRlcktpZCAhPT0gdW5kZWZpbmVkICYmIGJsb2Iua2lkICE9PSB1bmRlZmluZWQgJiYgcHJvdmlkZXJLaWQgIT09IGJsb2Iua2lkKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBLTVMga2V5IGlkIG1pc21hdGNoOiBibG9iIHdhcyBlbmNyeXB0ZWQgdW5kZXIgJHtibG9iLmtpZH0sIGN1cnJlbnQgcHJvdmlkZXIgdXNlcyAke3Byb3ZpZGVyS2lkfSBmb3Igb3JnICR7b3JnSWR9YCk7XG4gIH1cbiAgY29uc3QgaXYgPSBCdWZmZXIuZnJvbShibG9iLml2LCAnYmFzZTY0Jyk7XG4gIGNvbnN0IGFsbCA9IEJ1ZmZlci5mcm9tKGJsb2IuY2lwaGVydGV4dCwgJ2Jhc2U2NCcpO1xuICAvLyBTcGxpdCBvZmYgdGhlIDE2LWJ5dGUgYXV0aCB0YWcgYXBwZW5kZWQgaW4gZW5jcnlwdFNlY3JldC4gQW55IHRhbXBlcmluZ1xuICAvLyAgdG8gZWl0aGVyIHRoZSBjaXBoZXJ0ZXh0IE9SIHRoZSB0YWcgIGNhdXNlcyB0aGUgbmV4dCBgZmluYWwoKWAgdG9cbiAgLy8gdGhyb3cgd2l0aCBcIlVuc3VwcG9ydGVkIHN0YXRlIG9yIHVuYWJsZSB0byBhdXRoZW50aWNhdGUgZGF0YVwiLlxuICBjb25zdCB0YWcgPSBhbGwuc3ViYXJyYXkoYWxsLmxlbmd0aCAtIDE2KTtcbiAgY29uc3QgZW5jID0gYWxsLnN1YmFycmF5KDAsIGFsbC5sZW5ndGggLSAxNik7XG4gIGNvbnN0IGRlY2lwaGVyID0gY3JlYXRlRGVjaXBoZXJpdignYWVzLTI1Ni1nY20nLCBrZXksIGl2KTtcbiAgZGVjaXBoZXIuc2V0QXV0aFRhZyh0YWcpO1xuICBjb25zdCBkZWMgPSBCdWZmZXIuY29uY2F0KFtkZWNpcGhlci51cGRhdGUoZW5jKSwgZGVjaXBoZXIuZmluYWwoKV0pO1xuICByZXR1cm4gZGVjLnRvU3RyaW5nKCd1dGY4Jyk7XG59XG5cbi8qKlxuICogVHlwZSBndWFyZCAgaGFuZHkgZm9yIG1vZGVsIGxheWVycyB0aGF0IGhvbGQgYSBjb2x1bW4gd2hvc2UgdmFsdWUgbWF5IGJlXG4gKiBlaXRoZXIgYSBjbGVhci10ZXh0IHN0cmluZyAobGVnYWN5IC8gdW5lbmNyeXB0ZWQpIE9SIGFuIGVuY3J5cHRlZCBibG9iXG4gKiAocG9zdC1taWdyYXRpb24pLiBNaXhlZCBzdGF0ZXMgYXJpc2UgbWlkLW1pZ3JhdGlvbjsgdGhlIG1vZGVsIGRlY2lkZXNcbiAqIHdoYXQgdG8gZG8gKGRlY3J5cHQgb24gcmVhZCwgZW5jcnlwdCBvbiBuZXh0IHdyaXRlKS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzRW5jcnlwdGVkQmxvYih2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIEVuY3J5cHRlZEJsb2Ige1xuICByZXR1cm4gKCB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnXG4gICAgJiYgdmFsdWUgIT09IG51bGxcbiAgICAmJiAodmFsdWUgYXMgeyBhbGc/OiB1bmtub3duIH0pLmFsZyA9PT0gJ2Flcy0yNTYtZ2NtLXYxJ1xuICAgICYmIHR5cGVvZiAodmFsdWUgYXMgeyBpdj86IHVua25vd24gfSkuaXYgPT09ICdzdHJpbmcnXG4gICAgJiYgdHlwZW9mICh2YWx1ZSBhcyB7IGNpcGhlcnRleHQ/OiB1bmtub3duIH0pLmNpcGhlcnRleHQgPT09ICdzdHJpbmcnXG4gICk7XG59XG4iXX0=
467
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VjcmV0LWVuY3J5cHRpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdXRpbHMvc2VjcmV0LWVuY3J5cHRpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQUV0Qzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0EwQkc7QUFFSCxPQUFPLEVBQUUsY0FBYyxFQUFFLGdCQUFnQixFQUFFLFFBQVEsRUFBRSxXQUFXLEVBQUUsTUFBTSxRQUFRLENBQUM7QUE2QmpGOzs7Ozs7O0dBT0c7QUFDSCxNQUFNLE9BQU8sY0FBYztJQUNSLFNBQVMsQ0FBUztJQUVuQyxZQUFZLGlCQUEwQjtRQUNwQyxNQUFNLEdBQUcsR0FBRyxpQkFBaUIsSUFBSSxPQUFPLENBQUMsR0FBRyxDQUFDLHFCQUFxQixDQUFDO1FBQ25FLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztZQUNULE1BQU0sSUFBSSxLQUFLLENBQUMsNkRBQTZELENBQUMsQ0FBQztRQUNqRixDQUFDO1FBQ0QsMEVBQTBFO1FBQzFFLHNEQUFzRDtRQUN0RCxNQUFNLE9BQU8sR0FBRyxHQUFHLENBQUMsTUFBTSxLQUFLLEVBQUUsSUFBSSxjQUFjLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQztZQUMzRCxDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDO1lBQ3pCLENBQUMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxRQUFRLENBQUMsQ0FBQztRQUMvQixJQUFJLE9BQU8sQ0FBQyxNQUFNLEtBQUssRUFBRSxFQUFFLENBQUM7WUFDMUIsTUFBTSxJQUFJLEtBQUssQ0FBQyxzREFBc0QsT0FBTyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7UUFDM0YsQ0FBQztRQUNELElBQUksQ0FBQyxTQUFTLEdBQUcsT0FBTyxDQUFDO0lBQzNCLENBQUM7SUFFRCxTQUFTLENBQUMsS0FBYTtRQUNy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TSxHQUFHLEVBQUUsQ0FBQyxDQUFDO0lBQzFDLE1BQU0sR0FBRyxHQUFHLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxNQUFNLEdBQUcsRUFBRSxDQUFDLENBQUM7SUFDN0MsTUFBTSxRQUFRLEdBQUcsZ0JBQWdCLENBQUMsYUFBYSxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQztJQUMxRCxRQUFRLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ3pCLE1BQU0sR0FBRyxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDcEUsT0FBTyxHQUFHLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBQzlCLENBQUM7QUFFRDs7Ozs7R0FLRztBQUNILE1BQU0sVUFBVSxlQUFlLENBQUMsS0FBYztJQUM1QyxPQUFPLENBQUUsT0FBTyxLQUFLLEtBQUssUUFBUTtXQUM3QixLQUFLLEtBQUssSUFBSTtXQUNiLEtBQTJCLENBQUMsR0FBRyxLQUFLLGdCQUFnQjtXQUNyRCxPQUFRLEtBQTBCLENBQUMsRUFBRSxLQUFLLFFBQVE7V0FDbEQsT0FBUSxLQUFrQyxDQUFDLFVBQVUsS0FBSyxRQUFRLENBQ3RFLENBQUM7QUFDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbi8qKlxuICogIFBlci1vcmcgZW52ZWxvcGUgZW5jcnlwdGlvbiBmb3Igc2VjcmV0IGNvbHVtbnMuXG4gKlxuICogVG9kYXkncyBwb3N0dXJlIGZvciBvcmctc2NvcGVkIHNlY3JldHMgKGFpUHJvdmlkZXJLZXlzLCB3ZWJob29rIFVSTHMsXG4gKiByZWdpc3RyeSBjcmVkZW50aWFscykgaXMgY2xlYXItdGV4dCBpbiBNb25nbyAvIFBvc3RncmVzIHdpdGggYXBwLWxheWVyXG4gKiBtYXNraW5nIG9uIG91dHB1dC4gVGhpcyBtb2R1bGUgaXMgdGhlIGVuY3J5cHRpb24gcHJpbWl0aXZlIHRoYXQgbGV0cyB0aGVcbiAqIG1vZGVsIGxheWVyIHN3YXAgY2xlYXItdGV4dCBzdHJpbmdzIGZvciBgRW5jcnlwdGVkQmxvYmAgdmFsdWVzIGF0IHdyaXRlXG4gKiB0aW1lIGFuZCBkZWNyeXB0IGF0IHJlYWQgdGltZS5cbiAqXG4gKiBDcnlwdG9ncmFwaHkgKiAtIEFFUy0yNTYtR0NNIChhdXRoZW50aWNhdGVkIGVuY3J5cHRpb24pLlxuICogLSBQZXItb3JnIGtleSBkZXJpdmVkIHZpYSBIS0RGLVNIQTI1NihtYXN0ZXJLZXksIHNhbHQ9b3JnSWQsIGluZm89J3NlY3JldHMtdjEnKS5cbiAqIEVhY2ggb3JnIGdldHMgYSB1bmlxdWUga2V5IHdpdGhvdXQgb3BlcmF0b3Iga2V5LW1hbmFnZW1lbnQgY2VyZW1vbnkuXG4gKiAtIDEyLWJ5dGUgSVYgZ2VuZXJhdGVkIHBlciBlbmNyeXB0aW9uIHdpdGggYGNyeXB0by5yYW5kb21CeXRlc2AuXG4gKiAtIDE2LWJ5dGUgYXV0aGVudGljYXRpb24gdGFnIGNvbmNhdGVuYXRlZCB3aXRoIGNpcGhlcnRleHQgKHN0YW5kYXJkIEdDTSkuXG4gKlxuICogT3BlcmF0b3IgY29uZmlndXJhdGlvbiAqIC0gYFNFQ1JFVF9FTkNSWVBUSU9OX0tFWWAgZW52OiBoZXgtIG9yIGJhc2U2NC1lbmNvZGVkIDMyLWJ5dGUgbWFzdGVyIGtleS5cbiAqIFJlcXVpcmVkIHdoZW4gYGVuY3J5cHRTZWNyZXRgL2BkZWNyeXB0U2VjcmV0YCBhcmUgY2FsbGVkLiBNaXNzaW5nIGtleVxuICogdGhyb3dzICBlbmNyeXB0aW9uIGlzIGZhaWwtY2xvc2VkOyB3ZSBuZXZlciBzaWxlbnRseSByb3VuZC10cmlwIGFcbiAqIHNlY3JldCBhcyBwbGFpbnRleHQuXG4gKlxuICogS01TIG1pZ3JhdGlvbiBwYXRoICogLSBUaGUgdHdvIGV4cG9ydGVkIGZ1bmN0aW9ucyB0YWtlIGEgYHByb3ZpZGVyYCBwYXJhbWV0ZXIuIFRoZSBkZWZhdWx0XG4gKiBgRW52S2V5UHJvdmlkZXJgIGltcGxlbWVudHMgSEtERiBkZXJpdmF0aW9uLiBBIGZ1dHVyZSBgQXdzS21zUHJvdmlkZXJgXG4gKiBwbHVncyBpbiBoZXJlOiBpdCBjYW4gY2FsbCBLTVMgYEVuY3J5cHRgIC8gYERlY3J5cHRgIHRvIHdyYXAgYSBERUtcbiAqIHJhdGhlciB0aGFuIGhvbGRpbmcgYSBtYXN0ZXIga2V5IGluIGVudi4gVGhlIG9uLWRpc2sgYmxvYiBzaGFwZVxuICogKGB7IGFsZywgaXYsIGNpcGhlcnRleHQsIGtpZD8gfWApIGlzIGZvcndhcmQtY29tcGF0aWJsZSAgYGtpZGBcbiAqIGNhcnJpZXMgdGhlIEtNUyBrZXkgaWQgd2hlbiB0aGUgcHJvdmlkZXIgbmVlZHMgaXQuXG4gKi9cblxuaW1wb3J0IHsgY3JlYXRlQ2lwaGVyaXYsIGNyZWF0ZURlY2lwaGVyaXYsIGhrZGZTeW5jLCByYW5kb21CeXRlcyB9IGZyb20gJ2NyeXB0byc7XG5cbi8qKiBPbi1kaXNrIHNoYXBlIG9mIGFuIGVuY3J5cHRlZCBzZWNyZXQuIEpTT04tc2VyaWFsaXphYmxlLiAqL1xuZXhwb3J0IGludGVyZmFjZSBFbmNyeXB0ZWRCbG9iIHtcbiAgLyoqIEFsZ29yaXRobSB0YWcuIEJ1bXAgb24gZm9ybWF0IGNoYW5nZSBzbyBhIGZ1dHVyZSBtaWdyYXRpb24gY2FuIGRldGVjdCBvbGQgYmxvYnMuICovXG4gIGFsZzogJ2Flcy0yNTYtZ2NtLXYxJztcbiAgLyoqIEJhc2U2NC1lbmNvZGVkIDEyLWJ5dGUgSVYuICovXG4gIGl2OiBzdHJpbmc7XG4gIC8qKiBCYXNlNjQtZW5jb2RlZCBjaXBoZXJ0ZXh0ICsgMTYtYnl0ZSBhdXRoZW50aWNhdGlvbiB0YWcgY29uY2F0ZW5hdGVkLiAqL1xuICBjaXBoZXJ0ZXh0OiBzdHJpbmc7XG4gIC8qKiBPcHRpb25hbCBrZXkgaWQgIHBvcHVsYXRlZCBieSBLTVMtYmFja2VkIHByb3ZpZGVycywgaWdub3JlZCBieSB0aGUgZW52IHByb3ZpZGVyLiAqL1xuICBraWQ/OiBzdHJpbmc7XG59XG5cbi8qKiBQbHVnZ2FibGUga2V5IHNvdXJjZS4gRW52LWJhY2tlZCBieSBkZWZhdWx0OyBLTVMtYmFja2VkIGF2YWlsYWJsZS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgS2V5UHJvdmlkZXIge1xuICAvKiogRGVyaXZlIGEgMzItYnl0ZSBzeW1tZXRyaWMga2V5IGJvdW5kIHRvIGBvcmdJZGAuICovXG4gIGRlcml2ZUtleShvcmdJZDogc3RyaW5nKTogQnVmZmVyO1xuICAvKiogT3B0aW9uYWwgYXN5bmMgdmFyaWFudCBmb3IgcHJvdmlkZXJzIHRoYXQgbmVlZCB0byBkbyBJL08gKGUuZy5cbiAgICogIHBlci1vcmcgS01TIGxvb2t1cCB0aGUgZmlyc3QgdGltZSBhbiBvcmcgaXMgc2VlbikuIERlZmF1bHRcbiAgICogIGltcGxlbWVudGF0aW9uIGZvcndhcmRzIHRvIHRoZSBzeW5jIGBkZXJpdmVLZXlgLiAqL1xuICBkZXJpdmVLZXlBc3luYz8ob3JnSWQ6IHN0cmluZyk6IFByb21pc2U8QnVmZmVyPjtcbiAgLyoqIE9wdGlvbmFsIEtNUy1rZXktaWQgdGhpcyBwcm92aWRlciB1c2VkIGZvciBgb3JnSWRgLiBFbWJlZGRlZCBpbiB0aGVcbiAgICogIGBFbmNyeXB0ZWRCbG9iLmtpZGAgZmllbGQgb24gd3JpdGUgc28gZGVjcnlwdCBjYW4gdmVyaWZ5IHRoZSByaWdodFxuICAgKiAgS01TIENNSyBpcyBiZWluZyB1c2VkIChkZWZlbnNlIGFnYWluc3QgYW4gYXR0YWNrZXIgd2hvIHN3YXBzIGEgYmxvYlxuICAgKiAgYmV0d2VlbiBvcmdzKS4gRGVmYXVsdCByZXR1cm5zIHVuZGVmaW5lZCAoZW52IHByb3ZpZGVyKS4gKi9cbiAga2lkRm9yPyhvcmdJZDogc3RyaW5nKTogc3RyaW5nIHwgdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIERlZmF1bHQgcHJvdmlkZXIgIGRlcml2ZXMgYSBwZXItb3JnIGtleSBmcm9tIGBTRUNSRVRfRU5DUllQVElPTl9LRVlgIHZpYVxuICogSEtERi1TSEEyNTYuIFN1aXRhYmxlIGZvciBzZWxmLWhvc3RlZCAvIGRldiB3aGVyZSBvcGVyYXRvcnMgZG9uJ3QgaGF2ZSBLTVMuXG4gKlxuICogRmFpbHMgZmFzdCBpZiB0aGUgZW52IGlzIG1pc3Npbmcgb3IgdGhlIGtleSBpcyB0aGUgd3JvbmcgbGVuZ3RoIHNvIG1pc2NvbmZpZ1xuICogc3VyZmFjZXMgYXQgZmlyc3QgdXNlIHJhdGhlciB0aGFuIHNpbGVudGx5IGZpbmdlcnByaW50aW5nIGFsbCB3cml0ZXMgd2l0aFxuICogYSBkZWZhdWx0IHplcm8ga2V5LlxuICovXG5leHBvcnQgY2xhc3MgRW52S2V5UHJvdmlkZXIgaW1wbGVtZW50cyBLZXlQcm92aWRlciB7XG4gIHByaXZhdGUgcmVhZG9ubHkgbWFzdGVyS2V5OiBCdWZmZXI7XG5cbiAgY29uc3RydWN0b3IobWFzdGVyS2V5T3ZlcnJpZGU/OiBzdHJpbmcpIHtcbiAgICBjb25zdCByYXcgPSBtYXN0ZXJLZXlPdmVycmlkZSA/PyBwcm9jZXNzLmVudi5TRUNSRVRfRU5DUllQVElPTl9LRVk7XG4gICAgaWYgKCFyYXcpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignU0VDUkVUX0VOQ1JZUFRJT05fS0VZIGVudiBpcyByZXF1aXJlZCBmb3Igc2VjcmV0IGVuY3J5cHRpb24nKTtcbiAgICB9XG4gICAgLy8gQWNjZXB0IGVpdGhlciBoZXggKDY0IGNoYXJzKSBvciBiYXNlNjQgKDQ0IGNoYXJzIGluY2x1ZGluZyBwYWRkaW5nKSBmb3JcbiAgICAvLyBvcGVyYXRvciBjb252ZW5pZW5jZSAgYm90aCBkZWNvZGUgdG8gYSAzMi1ieXRlIGtleS5cbiAgICBjb25zdCBkZWNvZGVkID0gcmF3Lmxlbmd0aCA9PT0gNjQgJiYgL15bMC05YS1mXSskL2kudGVzdChyYXcpXG4gICAgICA/IEJ1ZmZlci5mcm9tKHJhdywgJ2hleCcpXG4gICAgICA6IEJ1ZmZlci5mcm9tKHJhdywgJ2Jhc2U2NCcpO1xuICAgIGlmIChkZWNvZGVkLmxlbmd0aCAhPT0gMzIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgU0VDUkVUX0VOQ1JZUFRJT05fS0VZIG11c3QgZGVjb2RlIHRvIDMyIGJ5dGVzIChnb3QgJHtkZWNvZGVkLmxlbmd0aH0pYCk7XG4gICAgfVxuICAgIHRoaXMubWFzdGVyS2V5ID0gZGVjb2RlZDtcbiAgfVxuXG4gIGRlcml2ZUtleShvcmdJZDogc3RyaW5nKTogQnVmZmVyIHtcbiAgICAvLyBIS0RGIGJpbmRzIHRoZSBtYXN0ZXIga2V5IHRvIHRoZSBvcmcgc28gdHdvIG9yZ3MgZW5jcnlwdGluZyB0aGUgc2FtZVxuICAgIC8vIHBsYWludGV4dCBwcm9kdWNlIGRpZmZlcmVudCBjaXBoZXJ0ZXh0cyAga2VlcHMgYSBzdG9sZW4gREIgdW5hYmxlIHRvXG4gICAgLy8gdGVsbCB3aGljaCBvcmdzIHNoYXJlIHNlY3JldHMgdmlhIGNpcGhlcnRleHQgY29tcGFyaXNvbi5cbiAgICBjb25zdCBkZXJpdmVkID0gaGtkZlN5bmMoICdzaGEyNTYnLFxuICAgICAgdGhpcy5tYXN0ZXJLZXksXG4gICAgICBCdWZmZXIuZnJvbShvcmdJZCwgJ3V0ZjgnKSxcbiAgICAgICdzZWNyZXRzLXYxJyxcbiAgICAgIDMyLFxuICAgICk7XG4gICAgLy8gaGtkZlN5bmMgcmV0dXJucyBBcnJheUJ1ZmZlciBpbiBvbGRlciBOb2RlIHR5cGluZ3M7IG5vcm1hbGl6ZSB0byBCdWZmZXIuXG4gICAgcmV0dXJuIEJ1ZmZlci5mcm9tKGRlcml2ZWQpO1xuICB9XG59XG5cbi8qKlxuICogIEFXUy1LTVMtYmFja2VkIEtleVByb3ZpZGVyLlxuICpcbiAqIFRyYWRlLW9mZiBwaWNrZWQ6IHN0b3JlIE9ORSBtYXN0ZXIga2V5IGVuY3J5cHRlZCB1bmRlciBhIEtNUyBDTUs7IG9uXG4gKiBmaXJzdCB1c2UsIGNhbGwgYGttczpEZWNyeXB0YCB0byByZWNvdmVyIHRoZSBtYXN0ZXIga2V5IGJ5dGVzOyBIS0RGLVxuICogZGVyaXZlIHBlci1vcmcgZnJvbSBpdCAoc2FtZSBhcyBFbnZLZXlQcm92aWRlcikuIFRoZSBwcm9jZXNzIHRoZW4gaG9sZHNcbiAqIHRoZSBwbGFpbnRleHQgbWFzdGVyIGtleSBpbiBtZW1vcnkgdW50aWwgcmVzdGFydC5cbiAqXG4gKiBQUk9TOiBvbmUgS01TIGNhbGwgcGVyIHByb2Nlc3MgbGlmZXRpbWUgKGNoZWFwLCBsb3cgcDk5IGltcGFjdCksXG4gKiB0aGUgZW5jcnlwdGVkLW1hc3Rlci1rZXkgYmxvYiBpcyBzYWZlIHRvIGNvbW1pdC9sb2cvY2hlY2tpbixcbiAqIEtNUyBhdWRpdCBsb2cgcmVjb3JkcyB3aGVuIHRoZSBtYXN0ZXIgaXMgcmVjb3ZlcmVkLlxuICogQ09OUzogcHJvY2VzcyBtZW1vcnkgc3RpbGwgaG9sZHMgdGhlIG1hc3RlciBrZXkgIHNhbWUgcG9zdHVyZSBhc1xuICogRW52S2V5UHJvdmlkZXIgb25jZSB3YXJtZWQgdXAuIEZvciBzdHJvbmdlciBpc29sYXRpb24gYW5cbiAqIG9wZXJhdG9yIGNhbiBtb3ZlIHRvIHBlci1yZWNvcmQgZW52ZWxvcGUgZW5jcnlwdGlvbiAoY2FsbFxuICogR2VuZXJhdGVEYXRhS2V5IG9uIGV2ZXJ5IHdyaXRlKTsgdGhhdCdzIGEgZm9sbG93LW9uLlxuICpcbiAqIE9wZXJhdG9yIHNldHVwICogMS4gQ3JlYXRlIGEgS01TIENNSyB3aXRoIGtleSBwb2xpY3kgYWxsb3dpbmcgdGhlIHBsYXRmb3JtIHNlcnZpY2Unc1xuICogSUFNIHJvbGUga21zOkRlY3J5cHQuXG4gKiAyLiBHZW5lcmF0ZSBhIHJhbmRvbSAzMi1ieXRlIG1hc3RlciAqIGhlYWQgLWMgMzIgL2Rldi91cmFuZG9tIHwgYmFzZTY0XG4gKiAzLiBXcmFwIGl0IHdpdGggS01TICogYXdzIGttcyBlbmNyeXB0IC0ta2V5LWlkIDxLRVlfSUQ+IFxcXG4gKiAtLXBsYWludGV4dCA8YmFzZTY0LWZyb20tc3RlcC0yPiAtLW91dHB1dCB0ZXh0IFxcXG4gKiAtLXF1ZXJ5IENpcGhlcnRleHRCbG9iXG4gKiA0LiBTZXQgb24gdGhlIHNlcnZpY2UgKiBTRUNSRVRfRU5DUllQVElPTl9LTVNfS0VZX0lEPTxLRVlfSUQ+XG4gKiBTRUNSRVRfRU5DUllQVElPTl9LTVNfQ0lQSEVSVEVYVD08YmFzZTY0LW91dHB1dC1vZi1zdGVwLTM+XG4gKiA1LiBQaWNrIHRoaXMgcHJvdmlkZXIgdmlhIGBzZXRLZXlQcm92aWRlcihuZXcgS21zS2V5UHJvdmlkZXIoKSlgLlxuICpcbiAqIENvbnN0cnVjdCBsYXppbHkgIGltcG9ydGluZyB0aGUgQVdTIFNESyBoYXMgYSBub24tdHJpdmlhbCBjb2xkLXN0YXJ0XG4gKiBjb3N0IHNvIGVudnMgdGhhdCBzdGF5IG9uIEVudktleVByb3ZpZGVyIG5ldmVyIGxvYWQgaXQuXG4gKi9cbi8qKlxuICogS01TLWRlY3J5cHQgYSBiYXNlNjQgY2lwaGVydGV4dCBpbnRvIGEgMzItYnl0ZSBrZXkuIFNoYXJlZCBieSBib3RoIEtNUyBrZXlcbiAqIHByb3ZpZGVycyAoc2luZ2xlLW1hc3RlciArIHBlci1vcmcpLCB3aGljaCBwcmV2aW91c2x5IGNvcHktcGFzdGVkIHRoaXNcbiAqIGR5bmFtaWMtaW1wb3J0ICsgRGVjcnlwdCArIGVtcHR5L2xlbmd0aCBndWFyZHMuIGBAYXdzLXNkay9jbGllbnQta21zYCBpc1xuICogZHluYW1pY2FsbHkgaW1wb3J0ZWQgc28gRW52S2V5UHJvdmlkZXItb25seSBlbnZzIG5ldmVyIGxvYWQgdGhlIFNESy5cbiAqL1xuYXN5bmMgZnVuY3Rpb24ga21zRGVjcnlwdDMyKGtleUlkOiBzdHJpbmcsIGNpcGhlcnRleHRCNjQ6IHN0cmluZywgcmVnaW9uPzogc3RyaW5nLCBlbmRwb2ludD86IHN0cmluZyk6IFByb21pc2U8QnVmZmVyPiB7XG4gIGNvbnN0IHsgS01TQ2xpZW50LCBEZWNyeXB0Q29tbWFuZCB9ID0gYXdhaXQgaW1wb3J0KCdAYXdzLXNkay9jbGllbnQta21zJyk7XG4gIGNvbnN0IGNsaWVudCA9IG5ldyBLTVNDbGllbnQoeyByZWdpb24sIC4uLihlbmRwb2ludCA/IHsgZW5kcG9pbnQgfSA6IHt9KSB9KTtcbiAgY29uc3QgcmVzcCA9IGF3YWl0IGNsaWVudC5zZW5kKG5ldyBEZWNyeXB0Q29tbWFuZCh7XG4gICAgS2V5SWQ6IGtleUlkLFxuICAgIENpcGhlcnRleHRCbG9iOiBCdWZmZXIuZnJvbShjaXBoZXJ0ZXh0QjY0LCAnYmFzZTY0JyksXG4gIH0pKTtcbiAgaWYgKCFyZXNwLlBsYWludGV4dCkgdGhyb3cgbmV3IEVycm9yKGBLTVMgRGVjcnlwdCByZXR1cm5lZCBhbiBlbXB0eSBQbGFpbnRleHQgZm9yIGtleSAke2tleUlkfWApO1xuICBjb25zdCBidWYgPSBCdWZmZXIuZnJvbShyZXNwLlBsYWludGV4dCk7XG4gIGlmIChidWYubGVuZ3RoICE9PSAzMikgdGhyb3cgbmV3IEVycm9yKGBLTVMgRGVjcnlwdCByZXR1cm5lZCAke2J1Zi5sZW5ndGh9LWJ5dGUga2V5IGZvciAke2tleUlkfTsgZXhwZWN0ZWQgMzJgKTtcbiAgcmV0dXJuIGJ1Zjtcbn1cblxuZXhwb3J0IGNsYXNzIEttc0tleVByb3ZpZGVyIGltcGxlbWVudHMgS2V5UHJvdmlkZXIge1xuICBwcml2YXRlIG1hc3RlcktleUNhY2hlOiBCdWZmZXIgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSByZWFkb25seSBrZXlJZDogc3RyaW5nO1xuICBwcml2YXRlIHJlYWRvbmx5IGNpcGhlcnRleHRCNjQ6IHN0cmluZztcbiAgcHJpdmF0ZSByZWFkb25seSByZWdpb24/OiBzdHJpbmc7XG4gIHByaXZhdGUgcmVhZG9ubHkgZW5kcG9pbnQ/OiBzdHJpbmc7XG4gIHByaXZhdGUgZGVjcnlwdEluRmxpZ2h0OiBQcm9taXNlPEJ1ZmZlcj4gfCBudWxsID0gbnVsbDtcblxuICBjb25zdHJ1Y3RvcihvcHRzPzogeyBrZXlJZD86IHN0cmluZzsgY2lwaGVydGV4dEJhc2U2ND86IHN0cmluZzsgcmVnaW9uPzogc3RyaW5nOyBlbmRwb2ludD86IHN0cmluZyB9KSB7XG4gICAgY29uc3Qga2V5SWQgPSBvcHRzPy5rZXlJZCA/PyBwcm9jZXNzLmVudi5TRUNSRVRfRU5DUllQVElPTl9LTVNfS0VZX0lEO1xuICAgIGNvbnN0IGNpcGhlcnRleHQgPSBvcHRzPy5jaXBoZXJ0ZXh0QmFzZTY0ID8/IHByb2Nlc3MuZW52LlNFQ1JFVF9FTkNSWVBUSU9OX0tNU19DSVBIRVJURVhUO1xuICAgIGlmICgha2V5SWQpIHRocm93IG5ldyBFcnJvcignU0VDUkVUX0VOQ1JZUFRJT05fS01TX0tFWV9JRCBlbnYgaXMgcmVxdWlyZWQgZm9yIEttc0tleVByb3ZpZGVyJyk7XG4gICAgaWYgKCFjaXBoZXJ0ZXh0KSB0aHJvdyBuZXcgRXJyb3IoJ1NFQ1JFVF9FTkNSWVBUSU9OX0tNU19DSVBIRVJURVhUIGVudiBpcyByZXF1aXJlZCBmb3IgS21zS2V5UHJvdmlkZXInKTtcbiAgICB0aGlzLmtleUlkID0ga2V5SWQ7XG4gICAgdGhpcy5jaXBoZXJ0ZXh0QjY0ID0gY2lwaGVydGV4dDtcbiAgICB0aGlzLnJlZ2lvbiA9IG9wdHM/LnJlZ2lvbiA/PyBwcm9jZXNzLmVudi5BV1NfUkVHSU9OID8/IHByb2Nlc3MuZW52LkFXU19ERUZBVUxUX1JFR0lPTjtcbiAgICB0aGlzLmVuZHBvaW50ID0gb3B0cz8uZW5kcG9pbnQgPz8gcHJvY2Vzcy5lbnYuQVdTX0tNU19FTkRQT0lOVDtcbiAgfVxuXG4gIGRlcml2ZUtleShvcmdJZDogc3RyaW5nKTogQnVmZmVyIHtcbiAgICBpZiAoIXRoaXMubWFzdGVyS2V5Q2FjaGUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvciggJ0ttc0tleVByb3ZpZGVyIGlzIG5vdCB3YXJtZWQgdXAuIENhbGwgYGF3YWl0IHByb3ZpZGVyLndhcm11cCgpYCBvbmNlIGF0IHNlcnZpY2Ugc3RhcnR1cCBiZWZvcmUgYW55IGVuY3J5cHQvZGVjcnlwdC4nLFxuICAgICAgKTtcbiAgICB9XG4gICAgY29uc3QgZGVyaXZlZCA9IGhrZGZTeW5jKCdzaGEyNTYnLCB0aGlzLm1hc3RlcktleUNhY2hlLCBCdWZmZXIuZnJvbShvcmdJZCwgJ3V0ZjgnKSwgJ3NlY3JldHMtdjEnLCAzMik7XG4gICAgcmV0dXJuIEJ1ZmZlci5mcm9tKGRlcml2ZWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIEVhZ2VybHkgcmVjb3ZlciB0aGUgbWFzdGVyIGtleSBmcm9tIEtNUyBzbyBzdWJzZXF1ZW50IGBkZXJpdmVLZXlgXG4gICAqIGNhbGxzIGFyZSBzeW5jLiBJZGVtcG90ZW50ICBjb25jdXJyZW50IGNhbGxlcnMgc2hhcmUgdGhlIHNhbWUgaW4tXG4gICAqIGZsaWdodCBwcm9taXNlIHNvIHdlIGRvbid0IHNwYXduIG11bHRpcGxlIEtNUyBEZWNyeXB0IHJlcXVlc3RzIGF0XG4gICAqIGJvb3QuIFRocm93cyBvbiBhbnkgS01TIGZhaWx1cmU7IHRoZSBjYWxsZXIgKHR5cGljYWxseSB0aGUgc2VydmljZSdzXG4gICAqIG9uQmVmb3JlU3RhcnQgaG9vaykgZGVjaWRlcyB3aGV0aGVyIHRvIGZhbGwgYmFjayB0byBhIGRpZmZlcmVudFxuICAgKiBwcm92aWRlciBvciBmYWlsLXN0YXJ0dXAuXG4gICAqL1xuICBhc3luYyB3YXJtdXAoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMubWFzdGVyS2V5Q2FjaGUpIHJldHVybjtcbiAgICBpZiAoIXRoaXMuZGVjcnlwdEluRmxpZ2h0KSB7XG4gICAgICB0aGlzLmRlY3J5cHRJbkZsaWdodCA9IHRoaXMuZmV0Y2hBbmREZWNyeXB0KCk7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICB0aGlzLm1hc3RlcktleUNhY2hlID0gYXdhaXQgdGhpcy5kZWNyeXB0SW5GbGlnaHQ7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAvLyBBIHRyYW5zaWVudCBLTVMgZmFpbHVyZSBtdXN0IG5vdCBwZXJtYW5lbnRseSBwb2lzb24gdGhlIHByb3ZpZGVyOiBjbGVhclxuICAgICAgLy8gdGhlIHJlamVjdGVkIGluLWZsaWdodCBwcm9taXNlIHNvIGEgbGF0ZXIgd2FybXVwKCkgcmV0cmllcyBpbnN0ZWFkIG9mXG4gICAgICAvLyByZS1hd2FpdGluZyB0aGUgc2FtZSByZWplY3Rpb24gZm9yZXZlciAobWF0Y2hlcyBQZXJPcmdLbXNLZXlQcm92aWRlcikuXG4gICAgICB0aGlzLmRlY3J5cHRJbkZsaWdodCA9IG51bGw7XG4gICAgICB0aHJvdyBlcnI7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBmZXRjaEFuZERlY3J5cHQoKTogUHJvbWlzZTxCdWZmZXI+IHtcbiAgICByZXR1cm4ga21zRGVjcnlwdDMyKHRoaXMua2V5SWQsIHRoaXMuY2lwaGVydGV4dEI2NCwgdGhpcy5yZWdpb24sIHRoaXMuZW5kcG9pbnQpO1xuICB9XG59XG5cbi8vIExhenkgc2luZ2xldG9uICBvcGVyYXRvciBjb2RlIGluIGxvbmctbGl2ZWQgc2VydmljZXMgcGF5cyB0aGUgZW52LXBhcnNlXG4vLyBjb3N0IG9uY2UsIGFuZCB0ZXN0cyBjYW4gbWludCB0aGVpciBvd24gcHJvdmlkZXIgd2l0aCBhIGxpdGVyYWwga2V5LlxubGV0IGRlZmF1bHRQcm92aWRlcjogS2V5UHJvdmlkZXIgfCBudWxsID0gbnVsbDtcbmZ1bmN0aW9uIGdldERlZmF1bHRQcm92aWRlcigpOiBLZXlQcm92aWRlciB7XG4gIGlmICghZGVmYXVsdFByb3ZpZGVyKSBkZWZhdWx0UHJvdmlkZXIgPSBuZXcgRW52S2V5UHJvdmlkZXIoKTtcbiAgcmV0dXJuIGRlZmF1bHRQcm92aWRlcjtcbn1cblxuLyoqIFJlYWQgdGhlIGFjdGl2ZSBkZWZhdWx0IHByb3ZpZGVyLiBFeHBvc2VkIHNvIHNlcnZpY2UgY29kZSAoZS5nLiBhblxuICogIGFkbWluIGVuZHBvaW50IHRoYXQganVzdCByb3RhdGVkIGFuIG9yZydzIEtNUyBjb25maWcpIGNhbiBjYWxsXG4gKiAgYHByb3ZpZGVyLmV2aWN0KG9yZ0lkKWAgb24gdGhlIGxpdmUgcHJvdmlkZXIgcmF0aGVyIHRoYW4gcmVjb25zdHJ1Y3RpbmdcbiAqICBvbmUuIFRyaWdnZXJzIGxhenkgaW5pdGlhbGl6YXRpb24gb24gZmlyc3QgYWNjZXNzLCBzYW1lIGFzIHRoZSBpbnRlcm5hbFxuICogIGNhbGxlcnMgYmVsb3cuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0RGVmYXVsdEtleVByb3ZpZGVyKCk6IEtleVByb3ZpZGVyIHtcbiAgcmV0dXJuIGdldERlZmF1bHRQcm92aWRlcigpO1xufVxuXG4vKipcbiAqIFJvdGF0aW9uIGZhbGxiYWNrOiBhbiBgRW52S2V5UHJvdmlkZXJgIG92ZXIgYFNFQ1JFVF9FTkNSWVBUSU9OX0tFWV9QUkVWSU9VU2AsXG4gKiBvciBudWxsIHdoZW4gdGhhdCBlbnYgaXMgdW5zZXQuIGB1bmRlZmluZWRgID0gbm90IHlldCByZXNvbHZlZC4gV2hpbGUgYVxuICogbWFzdGVyLWtleSByb3RhdGlvbiBpcyBpbiBwcm9ncmVzcywgYGRlY3J5cHRTZWNyZXRgIHJldHJpZXMgYSBmYWlsZWQgZGVjcnlwdFxuICogdW5kZXIgdGhpcyBrZXksIHNvIHJvd3Mgd3JpdHRlbiB1bmRlciB0aGUgb2xkIG1hc3RlciBzdGF5IHJlYWRhYmxlIHVudGlsIHRoZVxuICogcmUtZW5jcnlwdGlvbiB0b29sIChwbGF0Zm9ybSBgc2NyaXB0cy9yZWVuY3J5cHQtc2VjcmV0cy5qc2ApIGhhcyByZXdyaXR0ZW5cbiAqIHRoZW0gdW5kZXIgdGhlIG5ldyBvbmUuIEVuY3J5cHRpb24gTkVWRVIgdXNlcyBpdC5cbiAqL1xubGV0IHByZXZpb3VzUHJvdmlkZXI6IEtleVByb3ZpZGVyIHwgbnVsbCB8IHVuZGVmaW5lZDtcbmZ1bmN0aW9uIGdldFByZXZpb3VzUHJvdmlkZXIoKTogS2V5UHJvdmlkZXIgfCBudWxsIHtcbiAgaWYgKHByZXZpb3VzUHJvdmlkZXIgPT09IHVuZGVmaW5lZCkge1xuICAgIGNvbnN0IHJhdyA9IHByb2Nlc3MuZW52LlNFQ1JFVF9FTkNSWVBUSU9OX0tFWV9QUkVWSU9VUztcbiAgICBwcmV2aW91c1Byb3ZpZGVyID0gcmF3ID8gbmV3IEVudktleVByb3ZpZGVyKHJhdykgOiBudWxsO1xuICB9XG4gIHJldHVybiBwcmV2aW91c1Byb3ZpZGVyO1xufVxuXG4vKiogUmVhZCB0aGUgcm90YXRpb24tZmFsbGJhY2sgcHJvdmlkZXIgKG51bGwgb3V0c2lkZSBhIG1hc3Rlci1rZXkgcm90YXRpb24pLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFByZXZpb3VzS2V5UHJvdmlkZXIoKTogS2V5UHJvdmlkZXIgfCBudWxsIHtcbiAgcmV0dXJuIGdldFByZXZpb3VzUHJvdmlkZXIoKTtcbn1cblxuLyoqIFJlc2V0IHRoZSBjYWNoZWQgZGVmYXVsdCAoYW5kIHByZXZpb3VzKSBwcm92aWRlciAgZm9yIHRlc3RzIHRoYXQgbXV0YXRlIGBwcm9jZXNzLmVudmAuICovXG5leHBvcnQgZnVuY3Rpb24gcmVzZXREZWZhdWx0S2V5UHJvdmlkZXIoKTogdm9pZCB7IGRlZmF1bHRQcm92aWRlciA9IG51bGw7IHByZXZpb3VzUHJvdmlkZXIgPSB1bmRlZmluZWQ7IH1cblxuLyoqIFJlcGxhY2UgdGhlIGRlZmF1bHQgcHJvdmlkZXIgIHNlcnZpY2VzIHRoYXQgb3B0IGludG8gS01TIGNhbGwgdGhpc1xuICogb25jZSBhdCBzdGFydHVwIHdpdGggYSB3YXJtZWQtdXAgYEttc0tleVByb3ZpZGVyYC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZXRLZXlQcm92aWRlcihwcm92aWRlcjogS2V5UHJvdmlkZXIpOiB2b2lkIHsgZGVmYXVsdFByb3ZpZGVyID0gcHJvdmlkZXI7IH1cblxuLyoqIFBlci1vcmcgS01TIGNvbmZpZyB0aGUgb3BlcmF0b3Igc3VwcGxpZXMuIFRoZSBga2V5SWRgIGlkZW50aWZpZXMgdGhlXG4gKiAgS01TIENNSyB0byBjYWxsIERlY3J5cHQgb247IGBjaXBoZXJ0ZXh0QmFzZTY0YCBpcyB0aGUgd3JhcHBlZCAzMi1ieXRlXG4gKiAgbWFzdGVyIGdlbmVyYXRlZCBieSBgYXdzIGttcyBlbmNyeXB0YCBhZ2FpbnN0IHRoYXQga2V5LiAqL1xuZXhwb3J0IGludGVyZmFjZSBQZXJPcmdLbXNDb25maWcge1xuICBrZXlJZDogc3RyaW5nO1xuICBjaXBoZXJ0ZXh0QmFzZTY0OiBzdHJpbmc7XG59XG5cbi8qKlxuICogQXN5bmMgcmVzb2x2ZXIgdGhhdCBtYXBzIGFuIG9yZyBpZCB0byBpdHMgS01TIGNvbmZpZy4gUmV0dXJucyBgbnVsbGAgd2hlblxuICogdGhlIG9yZyBoYXMgbm8gcGVyLW9yZyBjb25maWcg4oCUIHRoZSBwcm92aWRlciB0aGVuIGZhbGxzIGJhY2sgdG8gdGhlXG4gKiBgZmFsbGJhY2tgIHByb3ZpZGVyIHN1cHBsaWVkIGF0IGNvbnN0cnVjdGlvbiAodXN1YWxseSBhbiBFbnZLZXlQcm92aWRlclxuICogb3IgYSBkZWZhdWx0IEttc0tleVByb3ZpZGVyKS5cbiAqL1xuZXhwb3J0IHR5cGUgUGVyT3JnS21zUmVzb2x2ZXIgPSAob3JnSWQ6IHN0cmluZykgPT4gUHJvbWlzZTxQZXJPcmdLbXNDb25maWcgfCBudWxsPjtcblxuLyoqXG4gKiBQZXItb3JnIEtNUy1iYWNrZWQgS2V5UHJvdmlkZXIuIFRoZSBibGFzdCByYWRpdXMgb2YgYSBLTVMga2V5IGNvbXByb21pc2VcbiAqIGlzIG9uZSBvcmcgaW5zdGVhZCBvZiBldmVyeSBvcmcgdW5kZXIgYSBzaGFyZWQgbWFzdGVyLlxuICpcbiAqIEVhY2ggb3JnIGhhcyBpdHMgb3duIEtNUyBDTUsgKyBpdHMgb3duIHdyYXBwZWQgbWFzdGVyIChzdG9yZWQgaW4gTW9uZ29cbiAqIHZpYSB0aGUgb3BlcmF0b3IncyBzZXR1cCBzY3JpcHQpLiBPbiBmaXJzdCBlbmNyeXB0L2RlY3J5cHQgZm9yIGFuIG9yZyxcbiAqIHRoZSBwcm92aWRlcjpcbiAqICAgMS4gQ2FsbHMgdGhlIHJlc29sdmVyIHRvIGZldGNoIHRoZSBvcmcncyBLTVMgY29uZmlnLlxuICogICAyLiBDYWxscyBga21zOkRlY3J5cHRgIHRvIHJlY292ZXIgdGhlIDMyLWJ5dGUgbWFzdGVyLlxuICogICAzLiBDYWNoZXMgdGhlIHJlY292ZXJlZCBtYXN0ZXIgaW4tbWVtb3J5IGZvciB0aGUgcHJvY2VzcyBsaWZldGltZS5cbiAqICAgNC4gSEtERi1kZXJpdmVzIHBlci1jYWxsIGZyb20gdGhhdCBtYXN0ZXIgKyB0aGUgb3JnIGlkIHNhbHQuXG4gKlxuICogQmxvYnMgZW5jcnlwdGVkIGJ5IHRoaXMgcHJvdmlkZXIgY2FycnkgYGtpZCA9IDxrbXMta2V5LWlkPmAgc28gdGhlXG4gKiBkZWNyeXB0IHBhdGggZGV0ZWN0cyBhIHN0YWxlIGNvbmZpZyAob3BlcmF0b3Igcm90YXRlZCB0aGUga2V5IGJ1dFxuICogZXhpc3Rpbmcgcm93cyB3ZXJlbid0IHJlLWVuY3J5cHRlZCkgQkVGT1JFIEFFUy1HQ00gdGhyb3dzIGFuIG9wYXF1ZVxuICogYXV0aGVudGljYXRpb24tdGFnIGVycm9yLlxuICpcbiAqIE9yZ3Mgd2l0aG91dCBwZXItb3JnIGNvbmZpZyBmYWxsIHRocm91Z2ggdG8gdGhlIGBmYWxsYmFja2AgcHJvdmlkZXIg4oCUXG4gKiBtaXhlZC1tb2RlIGRlcGxveW1lbnRzIHdoZXJlIHNvbWUgb3JncyBoYXZlIEtNUyBpc29sYXRpb24gYW5kIG90aGVyc1xuICogc3RheSBvbiB0aGUgc2hhcmVkIG1hc3RlciBhcmUgZXhwbGljaXRseSBzdXBwb3J0ZWQuXG4gKi9cbmV4cG9ydCBjbGFzcyBQZXJPcmdLbXNLZXlQcm92aWRlciBpbXBsZW1lbnRzIEtleVByb3ZpZGVyIHtcbiAgLyoqIENhY2hlZCBwZXItb3JnIG1hc3RlciBrZXlzLCBrZXllZCBieSBvcmdJZC4gKi9cbiAgcHJpdmF0ZSByZWFkb25seSBtYXN0ZXJzID0gbmV3IE1hcDxzdHJpbmcsIHsga2V5OiBCdWZmZXI7IGtpZDogc3RyaW5nIH0+KCk7XG4gIC8qKiBSZXNvbHZlZCBwZXItb3JnIGNvbmZpZ3MgY2FjaGVkIGZvciB0aGUgcHJvY2VzcyBsaWZldGltZS4gKi9cbiAgcHJpdmF0ZSByZWFkb25seSBjb25maWdzID0gbmV3IE1hcDxzdHJpbmcsIFBlck9yZ0ttc0NvbmZpZz4oKTtcbiAgLyoqIEluLWZsaWdodCByZXNvbHZlciBwcm9taXNlcyBzbyBjb25jdXJyZW50IGZpcnN0LXRvdWNoIGNhbGxlcnMgc2hhcmUgb25lIEtNUyBEZWNyeXB0LlxuICAgKiAgUmVzb2x2ZXMgdG8gYG51bGxgIGZvciBvcmdzIHdpdGggbm8gcGVyLW9yZyBjb25maWcg4oCUIGNhbGxlciB0cmVhdHMgbnVsbCBhc1xuICAgKiAgXCJmYWxsIHRocm91Z2ggdG8gdGhlIGZhbGxiYWNrIHByb3ZpZGVyXCIsIHNhbWUgYXMgYSBjb2xkIGNhY2hlIG1pc3MuICovXG4gIHByaXZhdGUgcmVhZG9ubHkgaW5GbGlnaHQgPSBuZXcgTWFwPHN0cmluZywgUHJvbWlzZTx7IGtleTogQnVmZmVyOyBraWQ6IHN0cmluZyB9IHwgbnVsbD4+KCk7XG4gIC8qKiBPcmdzIHRoZSByZXNvbHZlciBoYXMgUFJPVkVOIGhhdmUgbm8gcGVyLW9yZyBjb25maWcg4oCUIHRoZSBmYWxsYmFjayBwcm92aWRlclxuICAgKiAgaXMgdGhlIGNvcnJlY3QgYW5zd2VyIGZvciB0aGVzZSwgYW5kIGBkZXJpdmVLZXlgIG1heSBzZXJ2ZSB0aGVtXG4gICAqICBzeW5jaHJvbm91c2x5LiBEaXN0aW5jdCBmcm9tIFwibm90IHlldCByZXNvbHZlZFwiLCB3aGljaCBtdXN0IG5vdCBndWVzcy4gKi9cbiAgcHJpdmF0ZSByZWFkb25seSByZXNvbHZlZE5vUGVyT3JnQ29uZmlnID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gIC8qKiBQcm92aWRlciB1c2VkIGZvciBvcmdzIHRoYXQgaGF2ZSBubyBwZXItb3JnIGNvbmZpZy4gKi9cbiAgcHJpdmF0ZSByZWFkb25seSBmYWxsYmFjazogS2V5UHJvdmlkZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgcmVzb2x2ZXI6IFBlck9yZ0ttc1Jlc29sdmVyO1xuICBwcml2YXRlIHJlYWRvbmx5IHJlZ2lvbj86IHN0cmluZztcbiAgcHJpdmF0ZSByZWFkb25seSBlbmRwb2ludD86IHN0cmluZztcblxuICBjb25zdHJ1Y3RvcihvcHRzOiB7XG4gICAgcmVzb2x2ZXI6IFBlck9yZ0ttc1Jlc29sdmVyO1xuICAgIGZhbGxiYWNrOiBLZXlQcm92aWRlcjtcbiAgICByZWdpb24/OiBzdHJpbmc7XG4gICAgZW5kcG9pbnQ/OiBzdHJpbmc7XG4gIH0pIHtcbiAgICB0aGlzLnJlc29sdmVyID0gb3B0cy5yZXNvbHZlcjtcbiAgICB0aGlzLmZhbGxiYWNrID0gb3B0cy5mYWxsYmFjaztcbiAgICB0aGlzLnJlZ2lvbiA9IG9wdHMucmVnaW9uID8/IHByb2Nlc3MuZW52LkFXU19SRUdJT04gPz8gcHJvY2Vzcy5lbnYuQVdTX0RFRkFVTFRfUkVHSU9OO1xuICAgIHRoaXMuZW5kcG9pbnQgPSBvcHRzLmVuZHBvaW50ID8/IHByb2Nlc3MuZW52LkFXU19LTVNfRU5EUE9JTlQ7XG4gIH1cblxuICAvKipcbiAgICogU3luYyBkZXJpdmUuIE9ubHkgY29ycmVjdCBmb3IgYW4gb3JnIHdob3NlIGNvbmZpZyBoYXMgYWxyZWFkeSBiZWVuXG4gICAqIFJFU09MVkVEIOKAlCBlaXRoZXIgaXQgaGFzIGEgcGVyLW9yZyBtYXN0ZXIgKHVzZSBpdCkgb3IgaXQgcHJvdmFibHkgaGFzIG5vXG4gICAqIHBlci1vcmcgY29uZmlnICh0aGUgZmFsbGJhY2sgaXMgdGhlbiB0aGUgcmlnaHQgYW5zd2VyKS5cbiAgICpcbiAgICogRm9yIGFuIFVOUkVTT0xWRUQgb3JnIHRoaXMgVEhST1dTIHJhdGhlciB0aGFuIGd1ZXNzaW5nLiBJdCB1c2VkIHRvIGZhbGxcbiAgICogdGhyb3VnaCB0byB0aGUgZmFsbGJhY2ssIHdoaWNoIHNpbGVudGx5IGVuY3J5cHRlZCB0aGF0IG9yZydzIHNlY3JldHMgdW5kZXJcbiAgICogdGhlIFNIQVJFRCBtYXN0ZXIgYW5kIOKAlCBiZWNhdXNlIGBraWRGb3JgIGFsc28gcmV0dXJuZWQgdW5kZWZpbmVkLCBzbyB0aGVcbiAgICogYm90aC1raWRzLXByZXNlbnQgbWlzbWF0Y2ggZ3VhcmQgY291bGQgbmV2ZXIgZmlyZSDigJQgbGVmdCB0aGVtIHBlcm1hbmVudGx5XG4gICAqIHVuZGVjcnlwdGFibGUgb25jZSB0aGUgb3JnIHdhcm1lZDogYGRlY2lwaGVyLmZpbmFsKClgIHRoZW4gdGhyZXcgYW4gb3BhcXVlXG4gICAqIGF1dGgtdGFnIGVycm9yIHdpdGggbm8gZGlhZ25vc3RpYy4gRmFpbGluZyBsb3VkIGhlcmUgbWF0Y2hlc1xuICAgKiBgS21zS2V5UHJvdmlkZXIuZGVyaXZlS2V5YCwgd2hpY2ggaGFzIGFsd2F5cyByZWZ1c2VkIHRvIHdvcmsgY29sZC5cbiAgICpcbiAgICogYGVuY3J5cHRTZWNyZXRgL2BkZWNyeXB0U2VjcmV0YCBhcmUgYXN5bmMgYW5kIGF3YWl0IGBkZXJpdmVLZXlBc3luY2AsIHNvXG4gICAqIHRoZXkgcmVzb2x2ZSB0aGUgb3JnIGZpcnN0IGFuZCBuZXZlciBoaXQgdGhpcyBwYXRoOyBpdCBpcyB0aGUgYmFja3N0b3AgZm9yXG4gICAqIGEgY2FsbGVyIHRoYXQgcmVhY2hlcyBmb3IgdGhlIHN5bmMgQVBJIGRpcmVjdGx5LlxuICAgKi9cbiAgZGVyaXZlS2V5KG9yZ0lkOiBzdHJpbmcpOiBCdWZmZXIge1xuICAgIGNvbnN0IGNhY2hlZCA9IHRoaXMubWFzdGVycy5nZXQob3JnSWQpO1xuICAgIGlmICghY2FjaGVkKSB7XG4gICAgICBpZiAodGhpcy5yZXNvbHZlZE5vUGVyT3JnQ29uZmlnLmhhcyhvcmdJZCkpIHJldHVybiB0aGlzLmZhbGxiYWNrLmRlcml2ZUtleShvcmdJZCk7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoIGBQZXJPcmdLbXNLZXlQcm92aWRlciBoYXMgbm90IHJlc29sdmVkIG9yZyAke29yZ0lkfS4gYFxuICAgICAgICArICdDYWxsIGBhd2FpdCBwcm92aWRlci5lbnN1cmVXYXJtZWQob3JnSWQpYCAob3IgdXNlIHRoZSBhc3luYyBlbmNyeXB0U2VjcmV0L2RlY3J5cHRTZWNyZXQpICdcbiAgICAgICAgKyAnYmVmb3JlIGRlcml2aW5nIGEga2V5IOKAlCBndWVzc2luZyB0aGUgc2hhcmVkIG1hc3RlciB3b3VsZCB3cml0ZSBzZWNyZXRzIHRoYXQgY2Fubm90IGJlIGRlY3J5cHRlZCBsYXRlci4nLFxuICAgICAgKTtcbiAgICB9XG4gICAgY29uc3QgZGVyaXZlZCA9IGhrZGZTeW5jKCdzaGEyNTYnLCBjYWNoZWQua2V5LCBCdWZmZXIuZnJvbShvcmdJZCwgJ3V0ZjgnKSwgJ3NlY3JldHMtdjEnLCAzMik7XG4gICAgcmV0dXJuIEJ1ZmZlci5mcm9tKGRlcml2ZWQpO1xuICB9XG5cbiAgYXN5bmMgZGVyaXZlS2V5QXN5bmMob3JnSWQ6IHN0cmluZyk6IFByb21pc2U8QnVmZmVyPiB7XG4gICAgYXdhaXQgdGhpcy5lbnN1cmVXYXJtZWQob3JnSWQpO1xuICAgIHJldHVybiB0aGlzLmRlcml2ZUtleShvcmdJZCk7XG4gIH1cblxuICBraWRGb3Iob3JnSWQ6IHN0cmluZyk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgY2FjaGVkID0gdGhpcy5tYXN0ZXJzLmdldChvcmdJZCk7XG4gICAgaWYgKGNhY2hlZCkgcmV0dXJuIGNhY2hlZC5raWQ7XG4gICAgLy8gT25seSBzcGVhayBmb3IgYW4gb3JnIHdob3NlIGNvbmZpZyBpcyByZXNvbHZlZDsgYW4gdW5yZXNvbHZlZCBvcmcgaGFzIG5vXG4gICAgLy8gbWVhbmluZ2Z1bCBraWQsIGFuZCBjbGFpbWluZyBvbmUgd291bGQgZGVmZWF0IHRoZSBtaXNtYXRjaCBndWFyZC5cbiAgICBpZiAodGhpcy5yZXNvbHZlZE5vUGVyT3JnQ29uZmlnLmhhcyhvcmdJZCkpIHJldHVybiB0aGlzLmZhbGxiYWNrLmtpZEZvcj8uKG9yZ0lkKTtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlc29sdmUgdGhlIG9yZydzIEtNUyBjb25maWcsIGNhbGwgRGVjcnlwdCwgY2FjaGUgdGhlIG1hc3Rlci4gU3Vic2VxdWVudFxuICAgKiBjYWxscyBmb3IgdGhlIHNhbWUgb3JnIGFyZSBuby1vcHMuIENvbmN1cnJlbnQgY2FsbGVycyBzaGFyZSB0aGUgaW4tZmxpZ2h0XG4gICAqIERlY3J5cHQgcHJvbWlzZS5cbiAgICpcbiAgICogUmV0dXJucyBzaWxlbnRseSB3aGVuIHRoZSBvcmcgaGFzIG5vIHBlci1vcmcgY29uZmlnIOKAlCB0aGUgZmFsbGJhY2tcbiAgICogcHJvdmlkZXIgaGFuZGxlcyB0aG9zZSBvcmdzLlxuICAgKi9cbiAgYXN5bmMgZW5zdXJlV2FybWVkKG9yZ0lkOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAodGhpcy5tYXN0ZXJzLmhhcyhvcmdJZCkpIHJldHVybjtcbiAgICAvLyBJbnN0YWxsIHRoZSBpbi1mbGlnaHQgcHJvbWlzZSBTWU5DSFJPTk9VU0xZIGJlZm9yZSB5aWVsZGluZyBzbyBjb25jdXJyZW50XG4gICAgLy8gY2FsbGVycyBmaW5kIGl0IG9uIHRoZSBzZWNvbmQtYW5kLWxhdGVyIHBhc3Nlcy4gQXdhaXRpbmcgdGhlIHJlc29sdmVyXG4gICAgLy8gYmVmb3JlIHBvcHVsYXRpbmcgdGhlIG1hcCBpcyB0aGUgYnVnIHRoYXQgbGV0cyBhIFByb21pc2UuYWxsIG9mIDNcbiAgICAvLyBjYWxsZXJzIGZpcmUgMyBLTVMgRGVjcnlwdHMuXG4gICAgbGV0IHByb21pc2UgPSB0aGlzLmluRmxpZ2h0LmdldChvcmdJZCk7XG4gICAgaWYgKCFwcm9taXNlKSB7XG4gICAgICBwcm9taXNlID0gdGhpcy5yZXNvbHZlQW5kRGVjcnlwdChvcmdJZCk7XG4gICAgICB0aGlzLmluRmxpZ2h0LnNldChvcmdJZCwgcHJvbWlzZSk7XG4gICAgICB2b2lkIHByb21pc2UuZmluYWxseSgoKSA9PiB7IGlmICh0aGlzLmluRmxpZ2h0LmdldChvcmdJZCkgPT09IHByb21pc2UpIHRoaXMuaW5GbGlnaHQuZGVsZXRlKG9yZ0lkKTsgfSk7XG4gICAgfVxuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHByb21pc2U7XG4gICAgaWYgKHJlc3VsdCkgdGhpcy5tYXN0ZXJzLnNldChvcmdJZCwgcmVzdWx0KTtcbiAgICAvLyBSZW1lbWJlciB0aGUgTkVHQVRJVkUgb3V0Y29tZSB0b28sIHNvIHRoZSBzeW5jIGBkZXJpdmVLZXlgIGNhbiB0ZWxsXG4gICAgLy8gXCJubyBwZXItb3JnIGNvbmZpZywgZmFsbGJhY2sgaXMgY29ycmVjdFwiIGZyb20gXCJub3QgcmVzb2x2ZWQgeWV0XCIuXG4gICAgZWxzZSB0aGlzLnJlc29sdmVkTm9QZXJPcmdDb25maWcuYWRkKG9yZ0lkKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgcmVzb2x2ZUFuZERlY3J5cHQob3JnSWQ6IHN0cmluZyk6IFByb21pc2U8eyBrZXk6IEJ1ZmZlcjsga2lkOiBzdHJpbmcgfSB8IG51bGw+IHtcbiAgICBsZXQgY2ZnID0gdGhpcy5jb25maWdzLmdldChvcmdJZCk7XG4gICAgaWYgKCFjZmcpIHtcbiAgICAgIGNvbnN0IHJlc29sdmVkID0gYXdhaXQgdGhpcy5yZXNvbHZlcihvcmdJZCk7XG4gICAgICBpZiAoIXJlc29sdmVkKSByZXR1cm4gbnVsbDsgLy8gbm8gcGVyLW9yZyBjb25maWcg4oaSIGNhbGxlciB1c2VzIGZhbGxiYWNrXG4gICAgICBjZmcgPSByZXNvbHZlZDtcbiAgICAgIHRoaXMuY29uZmlncy5zZXQob3JnSWQsIGNmZyk7XG4gICAgfVxuICAgIGNvbnN0IGtleSA9IGF3YWl0IHRoaXMuZmV0Y2hBbmREZWNyeXB0KGNmZyk7XG4gICAgcmV0dXJuIHsga2V5LCBraWQ6IGNmZy5rZXlJZCB9O1xuICB9XG5cbiAgcHJpdmF0ZSBmZXRjaEFuZERlY3J5cHQoY2ZnOiBQZXJPcmdLbXNDb25maWcpOiBQcm9taXNlPEJ1ZmZlcj4ge1xuICAgIHJldHVybiBrbXNEZWNyeXB0MzIoY2ZnLmtleUlkLCBjZmcuY2lwaGVydGV4dEJhc2U2NCwgdGhpcy5yZWdpb24sIHRoaXMuZW5kcG9pbnQpO1xuICB9XG5cbiAgLyoqIEV2aWN0IGEgY2FjaGVkIHBlci1vcmcgbWFzdGVyLiBVc2UgYWZ0ZXIgYSBrZXkgcm90YXRpb24gc28gdGhlIG5leHRcbiAgICogIHRvdWNoIHJlLWZldGNoZXMgdGhlIG5ldyB3cmFwcGVkIG1hc3RlciBmcm9tIHRoZSByZXNvbHZlci4gKi9cbiAgZXZpY3Qob3JnSWQ6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMubWFzdGVycy5kZWxldGUob3JnSWQpO1xuICAgIHRoaXMuY29uZmlncy5kZWxldGUob3JnSWQpO1xuICAgIC8vIEFsc28gZm9yZ2V0IGEgTkVHQVRJVkUgcmVzb2x1dGlvbiwgb3IgYW4gb3JnIHRoYXQgZ2FpbnMgYSBwZXItb3JnIGNvbmZpZ1xuICAgIC8vIGFmdGVyIGJlaW5nIHJlc29sdmVkIGFzIFwibm8gY29uZmlnXCIgd291bGQga2VlcCB1c2luZyB0aGUgc2hhcmVkIG1hc3Rlci5cbiAgICB0aGlzLnJlc29sdmVkTm9QZXJPcmdDb25maWcuZGVsZXRlKG9yZ0lkKTtcbiAgfVxufVxuXG4vKipcbiAqIERlcml2ZSB0aGUga2V5IGZvciBgb3JnSWRgLCBnaXZpbmcgdGhlIHByb3ZpZGVyIGEgY2hhbmNlIHRvIGRvIEkvTyBmaXJzdC5cbiAqXG4gKiBUaGlzIGlzIHdoeSBgZW5jcnlwdFNlY3JldGAvYGRlY3J5cHRTZWNyZXRgIGFyZSBhc3luYzogYFBlck9yZ0ttc0tleVByb3ZpZGVyYFxuICogbmVlZHMgb25lIEtNUyBEZWNyeXB0IHRoZSBmaXJzdCB0aW1lIGl0IHNlZXMgYW4gb3JnLCBhbmQgZGVyaXZpbmdcbiAqIHN5bmNocm9ub3VzbHkgYmVmb3JlIHRoYXQgcmVzb2x2ZXMgd291bGQgc2lsZW50bHkgZmFsbCBiYWNrIHRvIHRoZSBzaGFyZWRcbiAqIG1hc3RlciBhbmQgcHJvZHVjZSBzZWNyZXRzIHRoYXQgY2Fubm90IGJlIGRlY3J5cHRlZCBhZnRlcndhcmRzLlxuICovXG5hc3luYyBmdW5jdGlvbiBkZXJpdmVLZXlGb3IocHJvdmlkZXI6IEtleVByb3ZpZGVyLCBvcmdJZDogc3RyaW5nKTogUHJvbWlzZTxCdWZmZXI+IHtcbiAgcmV0dXJuIHByb3ZpZGVyLmRlcml2ZUtleUFzeW5jID8gcHJvdmlkZXIuZGVyaXZlS2V5QXN5bmMob3JnSWQpIDogcHJvdmlkZXIuZGVyaXZlS2V5KG9yZ0lkKTtcbn1cblxuLyoqXG4gKiBFbmNyeXB0IGEgcGxhaW50ZXh0IHN0cmluZyBmb3Igc3RvcmFnZS4gUmV0dXJucyBhbiBgRW5jcnlwdGVkQmxvYmAgdGhhdFxuICogY2FuIGJlIEpTT04tc2VyaWFsaXplZCBpbnRvIHRoZSB1bmRlcmx5aW5nIGNvbHVtbiAvIE1vbmdvIGRvY3VtZW50LlxuICpcbiAqIEVtcHR5IHN0cmluZ3Mgcm91bmQtdHJpcCBhcyBgbnVsbGAgc28gdGhlIGNhbGxpbmcgbW9kZWwgbGF5ZXIgY2FuIHRyZWF0XG4gKiBcIm5vIHNlY3JldCBzZXRcIiBpZGVudGljYWxseSB0byBcImZpZWxkIGFic2VudFwiLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZW5jcnlwdFNlY3JldCggcGxhaW50ZXh0OiBzdHJpbmcsXG4gIG9yZ0lkOiBzdHJpbmcsXG4gIHByb3ZpZGVyOiBLZXlQcm92aWRlciA9IGdldERlZmF1bHRQcm92aWRlcigpLFxuKTogUHJvbWlzZTxFbmNyeXB0ZWRCbG9iPiB7XG4gIGlmICghcGxhaW50ZXh0KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdSZWZ1c2luZyB0byBlbmNyeXB0IGVtcHR5IHN0cmluZzsgY2FsbGVyIHNob3VsZCBzdG9yZSBudWxsIGluc3RlYWQnKTtcbiAgfVxuICAvLyBSZXNvbHZlIChhbmQgd2FybSkgdGhlIG9yZyBCRUZPUkUgcmVhZGluZyBga2lkRm9yYCBiZWxvdywgc28gYSBwZXItb3JnIEtNU1xuICAvLyBibG9iIGlzIGFsd2F5cyBzdGFtcGVkIHdpdGggdGhlIGtleSBpdCB3YXMgYWN0dWFsbHkgZW5jcnlwdGVkIHVuZGVyLlxuICBjb25zdCBrZXkgPSBhd2FpdCBkZXJpdmVLZXlGb3IocHJvdmlkZXIsIG9yZ0lkKTtcbiAgY29uc3QgaXYgPSByYW5kb21CeXRlcygxMik7XG4gIGNvbnN0IGNpcGhlciA9IGNyZWF0ZUNpcGhlcml2KCdhZXMtMjU2LWdjbScsIGtleSwgaXYpO1xuICBjb25zdCBlbmMgPSBCdWZmZXIuY29uY2F0KFtjaXBoZXIudXBkYXRlKHBsYWludGV4dCwgJ3V0ZjgnKSwgY2lwaGVyLmZpbmFsKCldKTtcbiAgY29uc3QgdGFnID0gY2lwaGVyLmdldEF1dGhUYWcoKTtcbiAgLy8gUGVyT3JnS21zS2V5UHJvdmlkZXIgdGFncyBibG9icyB3aXRoIHRoZSBLTVMga2V5IGlkIHVzZWQgc28gdGhlXG4gIC8vIGRlY3J5cHQgcGF0aCBjYW4gcmVmdXNlIHRvIG9wZXJhdGUgaWYgdGhlIG9wZXJhdG9yIGxhdGVyIHN3YXBzIGluIGFcbiAgLy8gZGlmZmVyZW50IHBlci1vcmcgY29uZmlnIChhIG1pc2NvbmZpZ3VyZWQgc3dhcCBzaG91bGRuJ3Qgc2lsZW50bHlcbiAgLy8gYWNjZXB0IGEgc3RhbGUgYmxvYiBpdCBjYW4ndCB2ZXJpZnkgYWdhaW5zdCB0aGUgcmlnaHQgQ01LKS5cbiAgY29uc3Qga2lkID0gcHJvdmlkZXIua2lkRm9yPy4ob3JnSWQpO1xuICByZXR1cm4ge1xuICAgIGFsZzogJ2Flcy0yNTYtZ2NtLXYxJyxcbiAgICBpdjogaXYudG9TdHJpbmcoJ2Jhc2U2NCcpLFxuICAgIC8vIEdDTSB0YWcgTVVTVCB0cmF2ZWwgd2l0aCB0aGUgY2lwaGVydGV4dCBvciBgZGVjcnlwdFNlY3JldGAgY2FuJ3RcbiAgICAvLyB2ZXJpZnkgaW50ZWdyaXR5ICBjb25jYXRlbmF0ZSBzbyB0aGUgb24tZGlzayBzaGFwZSBpcyBvbmUgZmllbGQuXG4gICAgY2lwaGVydGV4dDogQnVmZmVyLmNvbmNhdChbZW5jLCB0YWddKS50b1N0cmluZygnYmFzZTY0JyksXG4gICAgLi4uKGtpZCAhPT0gdW5kZWZpbmVkID8geyBraWQgfSA6IHt9KSxcbiAgfTtcbn1cblxuLyoqXG4gKiBEZWNyeXB0IGFuIGBFbmNyeXB0ZWRCbG9iYCB3cml0dGVuIGJ5IGBlbmNyeXB0U2VjcmV0YC4gVGhyb3dzIG9uICogLSB1bmtub3duIGBhbGdgIChmb3JjZXMgYW4gZXhwbGljaXQgbWlncmF0aW9uIHdoZW4gdGhlIGZvcm1hdCBjaGFuZ2VzKVxuICogLSB3cm9uZyBvcmdJZCAoSEtERiBiaW5kaW5nIG1pc21hdGNoIGZhaWxzIHRoZSBhdXRoIHRhZylcbiAqIC0gdGFtcGVyZWQgY2lwaGVydGV4dCAoR0NNIGF1dGggdGFnIGNoZWNrIGZhaWxzKVxuICpcbiAqIENhbGxlcnMgaGFuZGxlIHRoZSB0aHJvdyAgbWFza2luZyB0aGUgZmFpbHVyZSBhcyBgbnVsbGAgd291bGQgaGlkZVxuICogc2lsZW50IGNvcnJ1cHRpb24gLyB3cm9uZy1vcmcgcmVhZHMuXG4gKlxuICogYHByZXZpb3VzYCAoZGVmYXVsdDogYFNFQ1JFVF9FTkNSWVBUSU9OX0tFWV9QUkVWSU9VU2AsIHdoZW4gc2V0KSBpcyB0cmllZFxuICogb25seSBhZnRlciB0aGUgcHJpbWFyeSBrZXkgZmFpbHMsIGFuZCBvbmx5IGZvciBraWQtbGVzcyBibG9icy5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGRlY3J5cHRTZWNyZXQoIGJsb2I6IEVuY3J5cHRlZEJsb2IsXG4gIG9yZ0lkOiBzdHJpbmcsXG4gIHByb3ZpZGVyOiBLZXlQcm92aWRlciA9IGdldERlZmF1bHRQcm92aWRlcigpLFxuICBwcmV2aW91czogS2V5UHJvdmlkZXIgfCBudWxsID0gZ2V0UHJldmlvdXNQcm92aWRlcigpLFxuKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgaWYgKGJsb2IuYWxnICE9PSAnYWVzLTI1Ni1nY20tdjEnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBVbnN1cHBvcnRlZCBlbmNyeXB0aW9uIGFsZzogJHtibG9iLmFsZ31gKTtcbiAgfVxuICAvLyBXYXJtIGZpcnN0OiBga2lkRm9yYCBhbmQgYGRlcml2ZUtleWAgYmVsb3cgbXVzdCBib3RoIHNwZWFrIGZvciB0aGUgb3JnJ3NcbiAgLy8gcmVhbCBjb25maWcsIG9yIHRoZSBtaXNtYXRjaCBndWFyZCBzaWxlbnRseSBuby1vcHMuXG4gIGNvbnN0IGtleSA9IGF3YWl0IGRlcml2ZUtleUZvcihwcm92aWRlciwgb3JnSWQpO1xuICAvLyBJZiBib3RoIHRoZSBwcm92aWRlciBBTkQgdGhlIGJsb2IgcmVwb3J0IGEga2lkLCB0aGV5IG11c3QgbWF0Y2guXG4gIC8vIE1pc21hdGNoIHVzdWFsbHkgbWVhbnMgYW4gb3BlcmF0b3Igcm90YXRlZC9yZXBsYWNlZCBhbiBvcmcncyBLTVNcbiAgLy8gY29uZmlnIGFuZCBpcyBub3cgcmVhZGluZyBhIGJsb2IgZW5jcnlwdGVkIHVuZGVyIHRoZSBPTEQga2V5IOKAlFxuICAvLyBmYWlsaW5nIGxvdWQgaGVyZSBiZWF0cyBsZXR0aW5nIEFFUy1HQ00gdGhyb3cgYW4gb3BhcXVlIGF1dGgtdGFnIGVycm9yLlxuICBjb25zdCBwcm92aWRlcktpZCA9IHByb3ZpZGVyLmtpZEZvcj8uKG9yZ0lkKTtcbiAgaWYgKHByb3ZpZGVyS2lkICE9PSB1bmRlZmluZWQgJiYgYmxvYi5raWQgIT09IHVuZGVmaW5lZCAmJiBwcm92aWRlcktpZCAhPT0gYmxvYi5raWQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYEtNUyBrZXkgaWQgbWlzbWF0Y2g6IGJsb2Igd2FzIGVuY3J5cHRlZCB1bmRlciAke2Jsb2Iua2lkfSwgY3VycmVudCBwcm92aWRlciB1c2VzICR7cHJvdmlkZXJLaWR9IGZvciBvcmcgJHtvcmdJZH1gKTtcbiAgfVxuICB0cnkge1xuICAgIHJldHVybiBkZWNyeXB0V2l0aEtleShibG9iLCBrZXkpO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICAvLyBNYXN0ZXIta2V5IHJvdGF0aW9uIHdpbmRvdzogcmV0cnkgdW5kZXIgU0VDUkVUX0VOQ1JZUFRJT05fS0VZX1BSRVZJT1VTLlxuICAgIC8vIE9ubHkgZm9yIGEga2lkLWxlc3MgYmxvYiAodGhlIGVudi1rZXllZCBzaGFwZSkg4oCUIGEgcGVyLW9yZyBLTVMgYmxvYiBpc1xuICAgIC8vIGJvdW5kIHRvIGl0cyBDTUsgYW5kIHRoZSBzaGFyZWQgcHJldmlvdXMgbWFzdGVyIGNhbiBuZXZlciBvcGVuIGl0LiBUaGVcbiAgICAvLyBPUklHSU5BTCBlcnJvciBzdXJmYWNlcyB3aGVuIHRoZSBwcmV2aW91cyBrZXkgZmFpbHMgdG9vLCBzbyBhIHRhbXBlcmVkIG9yXG4gICAgLy8gd3Jvbmctb3JnIGJsb2Igc3RpbGwgZmFpbHMgbG91ZCBleGFjdGx5IGFzIGJlZm9yZS5cbiAgICBpZiAocHJldmlvdXMgJiYgYmxvYi5raWQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIGRlY3J5cHRXaXRoS2V5KGJsb2IsIGF3YWl0IGRlcml2ZUtleUZvcihwcmV2aW91cywgb3JnSWQpKTtcbiAgICAgIH0gY2F0Y2ggeyAvKiBmYWxsIHRocm91Z2ggdG8gdGhlIHByaW1hcnkgZXJyb3IgKi8gfVxuICAgIH1cbiAgICB0aHJvdyBlcnI7XG4gIH1cbn1cblxuLyoqIEFFUy0yNTYtR0NNIG9wZW4gb2YgYSBibG9iIHVuZGVyIG9uZSBkZXJpdmVkIGtleS4gVGhyb3dzIG9uIGFueSBhdXRoLXRhZyBmYWlsdXJlLiAqL1xuZnVuY3Rpb24gZGVjcnlwdFdpdGhLZXkoYmxvYjogRW5jcnlwdGVkQmxvYiwga2V5OiBCdWZmZXIpOiBzdHJpbmcge1xuICBjb25zdCBpdiA9IEJ1ZmZlci5mcm9tKGJsb2IuaXYsICdiYXNlNjQnKTtcbiAgY29uc3QgYWxsID0gQnVmZmVyLmZyb20oYmxvYi5jaXBoZXJ0ZXh0LCAnYmFzZTY0Jyk7XG4gIC8vIFNwbGl0IG9mZiB0aGUgMTYtYnl0ZSBhdXRoIHRhZyBhcHBlbmRlZCBpbiBlbmNyeXB0U2VjcmV0LiBBbnkgdGFtcGVyaW5nXG4gIC8vICB0byBlaXRoZXIgdGhlIGNpcGhlcnRleHQgT1IgdGhlIHRhZyAgY2F1c2VzIHRoZSBuZXh0IGBmaW5hbCgpYCB0b1xuICAvLyB0aHJvdyB3aXRoIFwiVW5zdXBwb3J0ZWQgc3RhdGUgb3IgdW5hYmxlIHRvIGF1dGhlbnRpY2F0ZSBkYXRhXCIuXG4gIGNvbnN0IHRhZyA9IGFsbC5zdWJhcnJheShhbGwubGVuZ3RoIC0gMTYpO1xuICBjb25zdCBlbmMgPSBhbGwuc3ViYXJyYXkoMCwgYWxsLmxlbmd0aCAtIDE2KTtcbiAgY29uc3QgZGVjaXBoZXIgPSBjcmVhdGVEZWNpcGhlcml2KCdhZXMtMjU2LWdjbScsIGtleSwgaXYpO1xuICBkZWNpcGhlci5zZXRBdXRoVGFnKHRhZyk7XG4gIGNvbnN0IGRlYyA9IEJ1ZmZlci5jb25jYXQoW2RlY2lwaGVyLnVwZGF0ZShlbmMpLCBkZWNpcGhlci5maW5hbCgpXSk7XG4gIHJldHVybiBkZWMudG9TdHJpbmcoJ3V0ZjgnKTtcbn1cblxuLyoqXG4gKiBUeXBlIGd1YXJkICBoYW5keSBmb3IgbW9kZWwgbGF5ZXJzIHRoYXQgaG9sZCBhIGNvbHVtbiB3aG9zZSB2YWx1ZSBtYXkgYmVcbiAqIGVpdGhlciBhIGNsZWFyLXRleHQgc3RyaW5nIChsZWdhY3kgLyB1bmVuY3J5cHRlZCkgT1IgYW4gZW5jcnlwdGVkIGJsb2JcbiAqIChwb3N0LW1pZ3JhdGlvbikuIE1peGVkIHN0YXRlcyBhcmlzZSBtaWQtbWlncmF0aW9uOyB0aGUgbW9kZWwgZGVjaWRlc1xuICogd2hhdCB0byBkbyAoZGVjcnlwdCBvbiByZWFkLCBlbmNyeXB0IG9uIG5leHQgd3JpdGUpLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNFbmNyeXB0ZWRCbG9iKHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgRW5jcnlwdGVkQmxvYiB7XG4gIHJldHVybiAoIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCdcbiAgICAmJiB2YWx1ZSAhPT0gbnVsbFxuICAgICYmICh2YWx1ZSBhcyB7IGFsZz86IHVua25vd24gfSkuYWxnID09PSAnYWVzLTI1Ni1nY20tdjEnXG4gICAgJiYgdHlwZW9mICh2YWx1ZSBhcyB7IGl2PzogdW5rbm93biB9KS5pdiA9PT0gJ3N0cmluZydcbiAgICAmJiB0eXBlb2YgKHZhbHVlIGFzIHsgY2lwaGVydGV4dD86IHVua25vd24gfSkuY2lwaGVydGV4dCA9PT0gJ3N0cmluZydcbiAgKTtcbn1cbiJdfQ==
@@ -0,0 +1,17 @@
1
+ /** Gauge name exported by api-server and platform. */
2
+ export declare const SECRET_ROTATION_PREVIOUS_GAUGE = "secret_rotation_previous_set";
3
+ /** True when an env var holds a non-empty value (an empty `KEY=` in .env is unset). */
4
+ export declare function isEnvSet(name: string): boolean;
5
+ /**
6
+ * Register (or replace) the probe for `secret` — the base name, e.g.
7
+ * `SECRET_ENCRYPTION_KEY`, or `TOKEN_SIGNING_KEY` for a credential whose overlap
8
+ * is not an env value at all (there, the probe asks the signer whether a
9
+ * retiring key is still published). The probe is evaluated at every metrics
10
+ * scrape, so it must be cheap and must not throw.
11
+ */
12
+ export declare function registerPreviousSecretProbe(secret: string, isPreviousSet: () => boolean): void;
13
+ /** Current state of every registered probe; a throwing probe reports `false`. */
14
+ export declare function previousSecretStates(): Array<{
15
+ secret: string;
16
+ previousSet: boolean;
17
+ }>;
@@ -0,0 +1,54 @@
1
+ // Copyright 2026 Pipeline Builder Contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ /**
4
+ * Rotation-window visibility for "previous" secrets.
5
+ *
6
+ * Every rotatable secret keeps a `*_PREVIOUS` value (or, for the registry
7
+ * signing cert, a second cert in the trust bundle) that is accepted ONLY for
8
+ * the overlap window of a rotation. Leaving it set indefinitely silently keeps
9
+ * the old credential valid — the very thing the rotation was meant to end.
10
+ *
11
+ * Each service registers a probe per secret it owns; the metrics layer exports
12
+ * them as the `secret_rotation_previous_set{secret}` gauge (1 while the previous
13
+ * value is set) and the `SecretRotationPreviousLingering` alert fires when it
14
+ * stays 1 past the overlap window. See docs/runbooks/secret-rotation.md.
15
+ *
16
+ * `SERVICE_SIGNING_KEY` is registered here because every service that loads
17
+ * api-core signs its internal SERVICE tokens with its own key (#14). Its
18
+ * overlap is not an env value: while a rotation is open, the shared key bundle
19
+ * publishes TWO public keys for this service, so the probe asks the key loader
20
+ * whether the retiring one is still trusted. The ES256 user-token signing key is
21
+ * platform's alone, so its probe is registered there.
22
+ */
23
+ import { isRetiringServiceKeyPublished } from '../services/service-keys.js';
24
+ /** Gauge name exported by api-server and platform. */
25
+ export const SECRET_ROTATION_PREVIOUS_GAUGE = 'secret_rotation_previous_set';
26
+ /** True when an env var holds a non-empty value (an empty `KEY=` in .env is unset). */
27
+ export function isEnvSet(name) {
28
+ return (process.env[name] ?? '') !== '';
29
+ }
30
+ const probes = new Map([
31
+ ['SERVICE_SIGNING_KEY', isRetiringServiceKeyPublished],
32
+ ]);
33
+ /**
34
+ * Register (or replace) the probe for `secret` — the base name, e.g.
35
+ * `SECRET_ENCRYPTION_KEY`, or `TOKEN_SIGNING_KEY` for a credential whose overlap
36
+ * is not an env value at all (there, the probe asks the signer whether a
37
+ * retiring key is still published). The probe is evaluated at every metrics
38
+ * scrape, so it must be cheap and must not throw.
39
+ */
40
+ export function registerPreviousSecretProbe(secret, isPreviousSet) {
41
+ probes.set(secret, isPreviousSet);
42
+ }
43
+ /** Current state of every registered probe; a throwing probe reports `false`. */
44
+ export function previousSecretStates() {
45
+ return [...probes.entries()].map(([secret, probe]) => {
46
+ let previousSet = false;
47
+ try {
48
+ previousSet = probe() === true;
49
+ }
50
+ catch { /* a broken probe must not break /metrics */ }
51
+ return { secret, previousSet };
52
+ });
53
+ }
54
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VjcmV0LXJvdGF0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3V0aWxzL3NlY3JldC1yb3RhdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwrQ0FBK0M7QUFDL0Msc0NBQXNDO0FBRXRDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBbUJHO0FBRUgsT0FBTyxFQUFFLDZCQUE2QixFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFFNUUsc0RBQXNEO0FBQ3RELE1BQU0sQ0FBQyxNQUFNLDhCQUE4QixHQUFHLDhCQUE4QixDQUFDO0FBRTdFLHVGQUF1RjtBQUN2RixNQUFNLFVBQVUsUUFBUSxDQUFDLElBQVk7SUFDbkMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDLEtBQUssRUFBRSxDQUFDO0FBQzFDLENBQUM7QUFFRCxNQUFNLE1BQU0sR0FBRyxJQUFJLEdBQUcsQ0FBd0I7SUFDNUMsQ0FBQyxxQkFBcUIsRUFBRSw2QkFBNkIsQ0FBQztDQUN2RCxDQUFDLENBQUM7QUFFSDs7Ozs7O0dBTUc7QUFDSCxNQUFNLFVBQVUsMkJBQTJCLENBQUMsTUFBYyxFQUFFLGFBQTRCO0lBQ3RGLE1BQU0sQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLGFBQWEsQ0FBQyxDQUFDO0FBQ3BDLENBQUM7QUFFRCxpRkFBaUY7QUFDakYsTUFBTSxVQUFVLG9CQUFvQjtJQUNsQyxPQUFPLENBQUMsR0FBRyxNQUFNLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxLQUFLLENBQUMsRUFBRSxFQUFFO1FBQ25ELElBQUksV0FBVyxHQUFHLEtBQUssQ0FBQztRQUN4QixJQUFJLENBQUM7WUFBQyxXQUFXLEdBQUcsS0FBSyxFQUFFLEtBQUssSUFBSSxDQUFDO1FBQUMsQ0FBQztRQUFDLE1BQU0sQ0FBQyxDQUFDLDRDQUE0QyxDQUFDLENBQUM7UUFDOUYsT0FBTyxFQUFFLE1BQU0sRUFBRSxXQUFXLEVBQUUsQ0FBQztJQUNqQyxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuLyoqXG4gKiBSb3RhdGlvbi13aW5kb3cgdmlzaWJpbGl0eSBmb3IgXCJwcmV2aW91c1wiIHNlY3JldHMuXG4gKlxuICogRXZlcnkgcm90YXRhYmxlIHNlY3JldCBrZWVwcyBhIGAqX1BSRVZJT1VTYCB2YWx1ZSAob3IsIGZvciB0aGUgcmVnaXN0cnlcbiAqIHNpZ25pbmcgY2VydCwgYSBzZWNvbmQgY2VydCBpbiB0aGUgdHJ1c3QgYnVuZGxlKSB0aGF0IGlzIGFjY2VwdGVkIE9OTFkgZm9yXG4gKiB0aGUgb3ZlcmxhcCB3aW5kb3cgb2YgYSByb3RhdGlvbi4gTGVhdmluZyBpdCBzZXQgaW5kZWZpbml0ZWx5IHNpbGVudGx5IGtlZXBzXG4gKiB0aGUgb2xkIGNyZWRlbnRpYWwgdmFsaWQg4oCUIHRoZSB2ZXJ5IHRoaW5nIHRoZSByb3RhdGlvbiB3YXMgbWVhbnQgdG8gZW5kLlxuICpcbiAqIEVhY2ggc2VydmljZSByZWdpc3RlcnMgYSBwcm9iZSBwZXIgc2VjcmV0IGl0IG93bnM7IHRoZSBtZXRyaWNzIGxheWVyIGV4cG9ydHNcbiAqIHRoZW0gYXMgdGhlIGBzZWNyZXRfcm90YXRpb25fcHJldmlvdXNfc2V0e3NlY3JldH1gIGdhdWdlICgxIHdoaWxlIHRoZSBwcmV2aW91c1xuICogdmFsdWUgaXMgc2V0KSBhbmQgdGhlIGBTZWNyZXRSb3RhdGlvblByZXZpb3VzTGluZ2VyaW5nYCBhbGVydCBmaXJlcyB3aGVuIGl0XG4gKiBzdGF5cyAxIHBhc3QgdGhlIG92ZXJsYXAgd2luZG93LiBTZWUgZG9jcy9ydW5ib29rcy9zZWNyZXQtcm90YXRpb24ubWQuXG4gKlxuICogYFNFUlZJQ0VfU0lHTklOR19LRVlgIGlzIHJlZ2lzdGVyZWQgaGVyZSBiZWNhdXNlIGV2ZXJ5IHNlcnZpY2UgdGhhdCBsb2Fkc1xuICogYXBpLWNvcmUgc2lnbnMgaXRzIGludGVybmFsIFNFUlZJQ0UgdG9rZW5zIHdpdGggaXRzIG93biBrZXkgKCMxNCkuIEl0c1xuICogb3ZlcmxhcCBpcyBub3QgYW4gZW52IHZhbHVlOiB3aGlsZSBhIHJvdGF0aW9uIGlzIG9wZW4sIHRoZSBzaGFyZWQga2V5IGJ1bmRsZVxuICogcHVibGlzaGVzIFRXTyBwdWJsaWMga2V5cyBmb3IgdGhpcyBzZXJ2aWNlLCBzbyB0aGUgcHJvYmUgYXNrcyB0aGUga2V5IGxvYWRlclxuICogd2hldGhlciB0aGUgcmV0aXJpbmcgb25lIGlzIHN0aWxsIHRydXN0ZWQuIFRoZSBFUzI1NiB1c2VyLXRva2VuIHNpZ25pbmcga2V5IGlzXG4gKiBwbGF0Zm9ybSdzIGFsb25lLCBzbyBpdHMgcHJvYmUgaXMgcmVnaXN0ZXJlZCB0aGVyZS5cbiAqL1xuXG5pbXBvcnQgeyBpc1JldGlyaW5nU2VydmljZUtleVB1Ymxpc2hlZCB9IGZyb20gJy4uL3NlcnZpY2VzL3NlcnZpY2Uta2V5cy5qcyc7XG5cbi8qKiBHYXVnZSBuYW1lIGV4cG9ydGVkIGJ5IGFwaS1zZXJ2ZXIgYW5kIHBsYXRmb3JtLiAqL1xuZXhwb3J0IGNvbnN0IFNFQ1JFVF9ST1RBVElPTl9QUkVWSU9VU19HQVVHRSA9ICdzZWNyZXRfcm90YXRpb25fcHJldmlvdXNfc2V0JztcblxuLyoqIFRydWUgd2hlbiBhbiBlbnYgdmFyIGhvbGRzIGEgbm9uLWVtcHR5IHZhbHVlIChhbiBlbXB0eSBgS0VZPWAgaW4gLmVudiBpcyB1bnNldCkuICovXG5leHBvcnQgZnVuY3Rpb24gaXNFbnZTZXQobmFtZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHJldHVybiAocHJvY2Vzcy5lbnZbbmFtZV0gPz8gJycpICE9PSAnJztcbn1cblxuY29uc3QgcHJvYmVzID0gbmV3IE1hcDxzdHJpbmcsICgpID0+IGJvb2xlYW4+KFtcbiAgWydTRVJWSUNFX1NJR05JTkdfS0VZJywgaXNSZXRpcmluZ1NlcnZpY2VLZXlQdWJsaXNoZWRdLFxuXSk7XG5cbi8qKlxuICogUmVnaXN0ZXIgKG9yIHJlcGxhY2UpIHRoZSBwcm9iZSBmb3IgYHNlY3JldGAg4oCUIHRoZSBiYXNlIG5hbWUsIGUuZy5cbiAqIGBTRUNSRVRfRU5DUllQVElPTl9LRVlgLCBvciBgVE9LRU5fU0lHTklOR19LRVlgIGZvciBhIGNyZWRlbnRpYWwgd2hvc2Ugb3ZlcmxhcFxuICogaXMgbm90IGFuIGVudiB2YWx1ZSBhdCBhbGwgKHRoZXJlLCB0aGUgcHJvYmUgYXNrcyB0aGUgc2lnbmVyIHdoZXRoZXIgYVxuICogcmV0aXJpbmcga2V5IGlzIHN0aWxsIHB1Ymxpc2hlZCkuIFRoZSBwcm9iZSBpcyBldmFsdWF0ZWQgYXQgZXZlcnkgbWV0cmljc1xuICogc2NyYXBlLCBzbyBpdCBtdXN0IGJlIGNoZWFwIGFuZCBtdXN0IG5vdCB0aHJvdy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlZ2lzdGVyUHJldmlvdXNTZWNyZXRQcm9iZShzZWNyZXQ6IHN0cmluZywgaXNQcmV2aW91c1NldDogKCkgPT4gYm9vbGVhbik6IHZvaWQge1xuICBwcm9iZXMuc2V0KHNlY3JldCwgaXNQcmV2aW91c1NldCk7XG59XG5cbi8qKiBDdXJyZW50IHN0YXRlIG9mIGV2ZXJ5IHJlZ2lzdGVyZWQgcHJvYmU7IGEgdGhyb3dpbmcgcHJvYmUgcmVwb3J0cyBgZmFsc2VgLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHByZXZpb3VzU2VjcmV0U3RhdGVzKCk6IEFycmF5PHsgc2VjcmV0OiBzdHJpbmc7IHByZXZpb3VzU2V0OiBib29sZWFuIH0+IHtcbiAgcmV0dXJuIFsuLi5wcm9iZXMuZW50cmllcygpXS5tYXAoKFtzZWNyZXQsIHByb2JlXSkgPT4ge1xuICAgIGxldCBwcmV2aW91c1NldCA9IGZhbHNlO1xuICAgIHRyeSB7IHByZXZpb3VzU2V0ID0gcHJvYmUoKSA9PT0gdHJ1ZTsgfSBjYXRjaCB7IC8qIGEgYnJva2VuIHByb2JlIG11c3Qgbm90IGJyZWFrIC9tZXRyaWNzICovIH1cbiAgICByZXR1cm4geyBzZWNyZXQsIHByZXZpb3VzU2V0IH07XG4gIH0pO1xufVxuIl19
@@ -0,0 +1,49 @@
1
+ export declare const REDACTED = "[REDACTED]";
2
+ /**
3
+ * Keys whose VALUE must be masked wholesale, regardless of the value's shape.
4
+ * Case-insensitive, anchored-substring match.
5
+ *
6
+ * Add a term only for leakage you've actually seen — over-redaction makes
7
+ * incident debugging harder, and these logs are now a product surface.
8
+ */
9
+ export declare const SENSITIVE_KEY_PATTERN: RegExp;
10
+ /**
11
+ * One secret-shaped value pattern.
12
+ *
13
+ * `js` is used by the Node-side layers. `re2` is the equivalent source for
14
+ * promtail's `replace` stage — Go's RE2 has no lookaround, so a pattern that
15
+ * needs it has `re2: null` and stays Node-only (L2/L4 still catch it; it just
16
+ * isn't scrubbed before storage). `(?i)` is spelled inline for RE2 because
17
+ * promtail takes a bare source string, while the JS form uses the `i` flag.
18
+ */
19
+ export interface SensitiveValuePattern {
20
+ /** Stable identifier, used as the promtail stage comment. */
21
+ name: string;
22
+ js: RegExp;
23
+ /** RE2 source for promtail, or null when the pattern is JS-only. */
24
+ re2: string | null;
25
+ /** Replacement text. `$1` keeps a leading capture (e.g. the `?token=` prefix). */
26
+ replacement: string;
27
+ }
28
+ /**
29
+ * Ordered — earlier patterns win, so the specific (a Stripe key) is masked
30
+ * before the generic (a `secret=` assignment) can produce a messier result.
31
+ */
32
+ export declare const SENSITIVE_VALUE_PATTERNS: readonly SensitiveValuePattern[];
33
+ /**
34
+ * Mask secret-shaped values in a single string.
35
+ *
36
+ * Also scrubs AWS account identifiers via {@link scrubAwsIdentifiersFromString}
37
+ * — a hard repo rule (an AWS account id must never be persisted or surfaced),
38
+ * composed here rather than duplicated so the two rules can't drift.
39
+ *
40
+ * Non-throwing and allocation-light on the common path: strings with no match
41
+ * come back by identity.
42
+ */
43
+ export declare function maskLine(input: string): string;
44
+ /**
45
+ * Does this string look like it CONTAINS a secret? Used to reject log-search
46
+ * terms, closing the other end of the oracle described at the top of this file:
47
+ * masking the result is pointless if the query itself can confirm a guess.
48
+ */
49
+ export declare function looksSensitive(input: string): boolean;
@@ -0,0 +1,149 @@
1
+ // Copyright 2026 Pipeline Builder Contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ /**
4
+ * Single source of truth for "what counts as sensitive" across every masking
5
+ * layer.
6
+ *
7
+ * Four layers consume this module (see `docs/plans/frontend-logs.md` §3.4):
8
+ *
9
+ * L1 key-based, write-time — winston `redactFormat` (metadata keys)
10
+ * L2 value-based, write-time — winston `maskFormat` (the message string)
11
+ * L3 value-based, ingest-time — promtail `replace` stages ← AUTHORITATIVE
12
+ * L4 value-based, read-time — platform's Loki client, before serving/export
13
+ *
14
+ * **L3 is the guarantee, not L4.** Read-time masking only masks the DISPLAY: the
15
+ * secret is still in Loki and still matchable, so a user can search a candidate
16
+ * value and learn from the hit that it is present, even though the line renders
17
+ * `[REDACTED]`. Repeat that and search becomes an oracle. Masking therefore has
18
+ * to happen before storage for anything the search path can match; L4 exists to
19
+ * cover history written before L3 shipped, and as defense in depth.
20
+ *
21
+ * Because L3 runs inside promtail (Go / RE2) and L1/L2/L4 run in Node, each
22
+ * pattern carries BOTH forms and a generator emits the promtail YAML from this
23
+ * list — see `scripts/gen-promtail-masking.mjs`. Keeping one list is the point:
24
+ * `SENSITIVE_KEY_PATTERN` previously existed in two hand-synced copies, and a
25
+ * third would have made drift certain.
26
+ */
27
+ import { scrubAwsIdentifiersFromString } from './aws-scrub.js';
28
+ export const REDACTED = '[REDACTED]';
29
+ /**
30
+ * Keys whose VALUE must be masked wholesale, regardless of the value's shape.
31
+ * Case-insensitive, anchored-substring match.
32
+ *
33
+ * Add a term only for leakage you've actually seen — over-redaction makes
34
+ * incident debugging harder, and these logs are now a product surface.
35
+ */
36
+ export const SENSITIVE_KEY_PATTERN = /password|secret|bearer|api[_-]?key|cookie|token|^auth(orization|_header)?$|stripe[_-]?(key|secret)|mongo(db)?[_-]?uri/i;
37
+ /**
38
+ * Ordered — earlier patterns win, so the specific (a Stripe key) is masked
39
+ * before the generic (a `secret=` assignment) can produce a messier result.
40
+ */
41
+ export const SENSITIVE_VALUE_PATTERNS = [
42
+ {
43
+ // A PEM block spans lines, so promtail (which replaces per line) can't see
44
+ // the whole thing — JS-only. The BEGIN line alone is still a strong signal.
45
+ name: 'pem_private_key',
46
+ js: /-----BEGIN[A-Z ]*PRIVATE KEY-----[\s\S]*?-----END[A-Z ]*PRIVATE KEY-----/g,
47
+ re2: null,
48
+ replacement: REDACTED,
49
+ },
50
+ {
51
+ name: 'pem_private_key_header',
52
+ js: /-----BEGIN[A-Z ]*PRIVATE KEY-----/g,
53
+ re2: '-----BEGIN[A-Z ]*PRIVATE KEY-----',
54
+ replacement: REDACTED,
55
+ },
56
+ {
57
+ name: 'jwt',
58
+ js: /eyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]*/g,
59
+ re2: 'eyJ[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]*',
60
+ replacement: REDACTED,
61
+ },
62
+ {
63
+ name: 'bearer_token',
64
+ js: /bearer\s+[A-Za-z0-9._~+/-]+=*/gi,
65
+ re2: '(?i)bearer\\s+[A-Za-z0-9._~+/-]+=*',
66
+ replacement: `Bearer ${REDACTED}`,
67
+ },
68
+ {
69
+ name: 'aws_access_key_id',
70
+ js: /\b(?:A3T[A-Z0-9]|AKIA|ASIA|ABIA|ACCA)[A-Z0-9]{16}\b/g,
71
+ re2: '\\b(A3T[A-Z0-9]|AKIA|ASIA|ABIA|ACCA)[A-Z0-9]{16}\\b',
72
+ replacement: REDACTED,
73
+ },
74
+ {
75
+ name: 'stripe_key',
76
+ js: /\b(?:sk|rk)_(?:live|test)_[A-Za-z0-9]{10,}\b/g,
77
+ re2: '\\b(sk|rk)_(live|test)_[A-Za-z0-9]{10,}\\b',
78
+ replacement: REDACTED,
79
+ },
80
+ {
81
+ name: 'github_token',
82
+ js: /\bgh[pousr]_[A-Za-z0-9]{20,}\b/g,
83
+ re2: '\\bgh[pousr]_[A-Za-z0-9]{20,}\\b',
84
+ replacement: REDACTED,
85
+ },
86
+ {
87
+ name: 'slack_token',
88
+ js: /\bxox[abprs]-[A-Za-z0-9-]{10,}\b/g,
89
+ re2: '\\bxox[abprs]-[A-Za-z0-9-]{10,}\\b',
90
+ replacement: REDACTED,
91
+ },
92
+ {
93
+ // `scheme://user:pass@host` — keep the scheme so the line stays readable.
94
+ name: 'url_credentials',
95
+ js: /([a-zA-Z][a-zA-Z0-9+.-]*:\/\/)[^:@/\s]+:[^@/\s]+@/g,
96
+ re2: '([a-zA-Z][a-zA-Z0-9+.-]*://)[^:@/\\s]+:[^@/\\s]+@',
97
+ replacement: `$1${REDACTED}@`,
98
+ },
99
+ {
100
+ // `?token=…` / `&api_key=…` in a URL. Keeps the parameter name visible.
101
+ name: 'url_secret_param',
102
+ js: /([?&](?:access[_-]?token|api[_-]?key|apikey|auth|password|secret|sig|signature|token)=)[^&\s"'<>]+/gi,
103
+ re2: '(?i)([?&](access[_-]?token|api[_-]?key|apikey|auth|password|secret|sig|signature|token)=)[^&\\s"\'<>]+',
104
+ replacement: `$1${REDACTED}`,
105
+ },
106
+ {
107
+ // `secret=…` / `"password": "…"` style assignments in free text.
108
+ // `&` is excluded from the value class so this can't run on after
109
+ // `url_secret_param` and swallow the rest of a query string — the URL rule
110
+ // has already masked those, and this one must not eat `&page=2`.
111
+ name: 'inline_secret_assignment',
112
+ js: /((?:aws_)?(?:secret_access_key|client_secret|api[_-]?key|apikey|password|passwd|secret|token)"?\s*[=:]\s*"?)[^\s"',;}&]+/gi,
113
+ re2: '(?i)(((aws_)?(secret_access_key|client_secret|api[_-]?key|apikey|password|passwd|secret|token))"?\\s*[=:]\\s*"?)[^\\s"\',;}&]+',
114
+ replacement: `$1${REDACTED}`,
115
+ },
116
+ ];
117
+ /**
118
+ * Mask secret-shaped values in a single string.
119
+ *
120
+ * Also scrubs AWS account identifiers via {@link scrubAwsIdentifiersFromString}
121
+ * — a hard repo rule (an AWS account id must never be persisted or surfaced),
122
+ * composed here rather than duplicated so the two rules can't drift.
123
+ *
124
+ * Non-throwing and allocation-light on the common path: strings with no match
125
+ * come back by identity.
126
+ */
127
+ export function maskLine(input) {
128
+ if (!input)
129
+ return input;
130
+ let out = input;
131
+ for (const { js, replacement } of SENSITIVE_VALUE_PATTERNS) {
132
+ // `js` carries the /g flag, so reset lastIndex — a shared RegExp object is
133
+ // stateful across calls and would otherwise skip matches intermittently.
134
+ js.lastIndex = 0;
135
+ out = out.replace(js, replacement);
136
+ }
137
+ return scrubAwsIdentifiersFromString(out);
138
+ }
139
+ /**
140
+ * Does this string look like it CONTAINS a secret? Used to reject log-search
141
+ * terms, closing the other end of the oracle described at the top of this file:
142
+ * masking the result is pointless if the query itself can confirm a guess.
143
+ */
144
+ export function looksSensitive(input) {
145
+ if (!input)
146
+ return false;
147
+ return maskLine(input) !== input;
148
+ }
149
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2Vuc2l0aXZlLXBhdHRlcm5zLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3V0aWxzL3NlbnNpdGl2ZS1wYXR0ZXJucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwrQ0FBK0M7QUFDL0Msc0NBQXNDO0FBRXRDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXVCRztBQUVILE9BQU8sRUFBRSw2QkFBNkIsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRS9ELE1BQU0sQ0FBQyxNQUFNLFFBQVEsR0FBRyxZQUFZLENBQUM7QUFFckM7Ozs7OztHQU1HO0FBQ0gsTUFBTSxDQUFDLE1BQU0scUJBQXFCLEdBQUcsd0hBQXdILENBQUM7QUFxQjlKOzs7R0FHRztBQUNILE1BQU0sQ0FBQyxNQUFNLHdCQUF3QixHQUFxQztJQUN4RTtRQUNFLDJFQUEyRTtRQUMzRSw0RUFBNEU7UUFDNUUsSUFBSSxFQUFFLGlCQUFpQjtRQUN2QixFQUFFLEVBQUUsMkVBQTJFO1FBQy9FLEdBQUcsRUFBRSxJQUFJO1FBQ1QsV0FBVyxFQUFFLFFBQVE7S0FDdEI7SUFDRDtRQUNFLElBQUksRUFBRSx3QkFBd0I7UUFDOUIsRUFBRSxFQUFFLG9DQUFvQztRQUN4QyxHQUFHLEVBQUUsbUNBQW1DO1FBQ3hDLFdBQVcsRUFBRSxRQUFRO0tBQ3RCO0lBQ0Q7UUFDRSxJQUFJLEVBQUUsS0FBSztRQUNYLEVBQUUsRUFBRSwwREFBMEQ7UUFDOUQsR0FBRyxFQUFFLDJEQUEyRDtRQUNoRSxXQUFXLEVBQUUsUUFBUTtLQUN0QjtJQUNEO1FBQ0UsSUFBSSxFQUFFLGNBQWM7UUFDcEIsRUFBRSxFQUFFLGlDQUFpQztRQUNyQyxHQUFHLEVBQUUsb0NBQW9DO1FBQ3pDLFdBQVcsRUFBRSxVQUFVLFFBQVEsRUFBRTtLQUNsQztJQUNEO1FBQ0UsSUFBSSxFQUFFLG1CQUFtQjtRQUN6QixFQUFFLEVBQUUsc0RBQXNEO1FBQzFELEdBQUcsRUFBRSxxREFBcUQ7UUFDMUQsV0FBVyxFQUFFLFFBQVE7S0FDdEI7SUFDRDtRQUNFLElBQUksRUFBRSxZQUFZO1FBQ2xCLEVBQUUsRUFBRSwrQ0FBK0M7UUFDbkQsR0FBRyxFQUFFLDRDQUE0QztRQUNqRCxXQUFXLEVBQUUsUUFBUTtLQUN0QjtJQUNEO1FBQ0UsSUFBSSxFQUFFLGNBQWM7UUFDcEIsRUFBRSxFQUFFLGlDQUFpQztRQUNyQyxHQUFHLEVBQUUsa0NBQWtDO1FBQ3ZDLFdBQVcsRUFBRSxRQUFRO0tBQ3RCO0lBQ0Q7UUFDRSxJQUFJLEVBQUUsYUFBYTtRQUNuQixFQUFFLEVBQUUsbUNBQW1DO1FBQ3ZDLEdBQUcsRUFBRSxvQ0FBb0M7UUFDekMsV0FBVyxFQUFFLFFBQVE7S0FDdEI7SUFDRDtRQUNFLDBFQUEwRTtRQUMxRSxJQUFJLEVBQUUsaUJBQWlCO1FBQ3ZCLEVBQUUsRUFBRSxvREFBb0Q7UUFDeEQsR0FBRyxFQUFFLG1EQUFtRDtRQUN4RCxXQUFXLEVBQUUsS0FBSyxRQUFRLEdBQUc7S0FDOUI7SUFDRDtRQUNFLHdFQUF3RTtRQUN4RSxJQUFJLEVBQUUsa0JBQWtCO1FBQ3hCLEVBQUUsRUFBRSxzR0FBc0c7UUFDMUcsR0FBRyxFQUFFLHdHQUF3RztRQUM3RyxXQUFXLEVBQUUsS0FBSyxRQUFRLEVBQUU7S0FDN0I7SUFDRDtRQUNFLGlFQUFpRTtRQUNqRSxrRUFBa0U7UUFDbEUsMkVBQTJFO1FBQzNFLGlFQUFpRTtRQUNqRSxJQUFJLEVBQUUsMEJBQTBCO1FBQ2hDLEVBQUUsRUFBRSw0SEFBNEg7UUFDaEksR0FBRyxFQUFFLGdJQUFnSTtRQUNySSxXQUFXLEVBQUUsS0FBSyxRQUFRLEVBQUU7S0FDN0I7Q0FDRixDQUFDO0FBRUY7Ozs7Ozs7OztHQVNHO0FBQ0gsTUFBTSxVQUFVLFFBQVEsQ0FBQyxLQUFhO0lBQ3BDLElBQUksQ0FBQyxLQUFLO1FBQUUsT0FBTyxLQUFLLENBQUM7SUFDekIsSUFBSSxHQUFHLEdBQUcsS0FBSyxDQUFDO0lBQ2hCLEtBQUssTUFBTSxFQUFFLEVBQUUsRUFBRSxXQUFXLEVBQUUsSUFBSSx3QkFBd0IsRUFBRSxDQUFDO1FBQzNELDJFQUEyRTtRQUMzRSx5RUFBeUU7UUFDekUsRUFBRSxDQUFDLFNBQVMsR0FBRyxDQUFDLENBQUM7UUFDakIsR0FBRyxHQUFHLEdBQUcsQ0FBQyxPQUFPLENBQUMsRUFBRSxFQUFFLFdBQVcsQ0FBQyxDQUFDO0lBQ3JDLENBQUM7SUFDRCxPQUFPLDZCQUE2QixDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQzVDLENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsTUFBTSxVQUFVLGNBQWMsQ0FBQyxLQUFhO0lBQzFDLElBQUksQ0FBQyxLQUFLO1FBQUUsT0FBTyxLQUFLLENBQUM7SUFDekIsT0FBTyxRQUFRLENBQUMsS0FBSyxDQUFDLEtBQUssS0FBSyxDQUFDO0FBQ25DLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuLyoqXG4gKiBTaW5nbGUgc291cmNlIG9mIHRydXRoIGZvciBcIndoYXQgY291bnRzIGFzIHNlbnNpdGl2ZVwiIGFjcm9zcyBldmVyeSBtYXNraW5nXG4gKiBsYXllci5cbiAqXG4gKiBGb3VyIGxheWVycyBjb25zdW1lIHRoaXMgbW9kdWxlIChzZWUgYGRvY3MvcGxhbnMvZnJvbnRlbmQtbG9ncy5tZGAgwqczLjQpOlxuICpcbiAqICAgTDEgIGtleS1iYXNlZCwgd3JpdGUtdGltZSAgIOKAlCB3aW5zdG9uIGByZWRhY3RGb3JtYXRgIChtZXRhZGF0YSBrZXlzKVxuICogICBMMiAgdmFsdWUtYmFzZWQsIHdyaXRlLXRpbWUg4oCUIHdpbnN0b24gYG1hc2tGb3JtYXRgICh0aGUgbWVzc2FnZSBzdHJpbmcpXG4gKiAgIEwzICB2YWx1ZS1iYXNlZCwgaW5nZXN0LXRpbWUg4oCUIHByb210YWlsIGByZXBsYWNlYCBzdGFnZXMgIOKGkCBBVVRIT1JJVEFUSVZFXG4gKiAgIEw0ICB2YWx1ZS1iYXNlZCwgcmVhZC10aW1lICDigJQgcGxhdGZvcm0ncyBMb2tpIGNsaWVudCwgYmVmb3JlIHNlcnZpbmcvZXhwb3J0XG4gKlxuICogKipMMyBpcyB0aGUgZ3VhcmFudGVlLCBub3QgTDQuKiogUmVhZC10aW1lIG1hc2tpbmcgb25seSBtYXNrcyB0aGUgRElTUExBWTogdGhlXG4gKiBzZWNyZXQgaXMgc3RpbGwgaW4gTG9raSBhbmQgc3RpbGwgbWF0Y2hhYmxlLCBzbyBhIHVzZXIgY2FuIHNlYXJjaCBhIGNhbmRpZGF0ZVxuICogdmFsdWUgYW5kIGxlYXJuIGZyb20gdGhlIGhpdCB0aGF0IGl0IGlzIHByZXNlbnQsIGV2ZW4gdGhvdWdoIHRoZSBsaW5lIHJlbmRlcnNcbiAqIGBbUkVEQUNURURdYC4gUmVwZWF0IHRoYXQgYW5kIHNlYXJjaCBiZWNvbWVzIGFuIG9yYWNsZS4gTWFza2luZyB0aGVyZWZvcmUgaGFzXG4gKiB0byBoYXBwZW4gYmVmb3JlIHN0b3JhZ2UgZm9yIGFueXRoaW5nIHRoZSBzZWFyY2ggcGF0aCBjYW4gbWF0Y2g7IEw0IGV4aXN0cyB0b1xuICogY292ZXIgaGlzdG9yeSB3cml0dGVuIGJlZm9yZSBMMyBzaGlwcGVkLCBhbmQgYXMgZGVmZW5zZSBpbiBkZXB0aC5cbiAqXG4gKiBCZWNhdXNlIEwzIHJ1bnMgaW5zaWRlIHByb210YWlsIChHbyAvIFJFMikgYW5kIEwxL0wyL0w0IHJ1biBpbiBOb2RlLCBlYWNoXG4gKiBwYXR0ZXJuIGNhcnJpZXMgQk9USCBmb3JtcyBhbmQgYSBnZW5lcmF0b3IgZW1pdHMgdGhlIHByb210YWlsIFlBTUwgZnJvbSB0aGlzXG4gKiBsaXN0IOKAlCBzZWUgYHNjcmlwdHMvZ2VuLXByb210YWlsLW1hc2tpbmcubWpzYC4gS2VlcGluZyBvbmUgbGlzdCBpcyB0aGUgcG9pbnQ6XG4gKiBgU0VOU0lUSVZFX0tFWV9QQVRURVJOYCBwcmV2aW91c2x5IGV4aXN0ZWQgaW4gdHdvIGhhbmQtc3luY2VkIGNvcGllcywgYW5kIGFcbiAqIHRoaXJkIHdvdWxkIGhhdmUgbWFkZSBkcmlmdCBjZXJ0YWluLlxuICovXG5cbmltcG9ydCB7IHNjcnViQXdzSWRlbnRpZmllcnNGcm9tU3RyaW5nIH0gZnJvbSAnLi9hd3Mtc2NydWIuanMnO1xuXG5leHBvcnQgY29uc3QgUkVEQUNURUQgPSAnW1JFREFDVEVEXSc7XG5cbi8qKlxuICogS2V5cyB3aG9zZSBWQUxVRSBtdXN0IGJlIG1hc2tlZCB3aG9sZXNhbGUsIHJlZ2FyZGxlc3Mgb2YgdGhlIHZhbHVlJ3Mgc2hhcGUuXG4gKiBDYXNlLWluc2Vuc2l0aXZlLCBhbmNob3JlZC1zdWJzdHJpbmcgbWF0Y2guXG4gKlxuICogQWRkIGEgdGVybSBvbmx5IGZvciBsZWFrYWdlIHlvdSd2ZSBhY3R1YWxseSBzZWVuIOKAlCBvdmVyLXJlZGFjdGlvbiBtYWtlc1xuICogaW5jaWRlbnQgZGVidWdnaW5nIGhhcmRlciwgYW5kIHRoZXNlIGxvZ3MgYXJlIG5vdyBhIHByb2R1Y3Qgc3VyZmFjZS5cbiAqL1xuZXhwb3J0IGNvbnN0IFNFTlNJVElWRV9LRVlfUEFUVEVSTiA9IC9wYXNzd29yZHxzZWNyZXR8YmVhcmVyfGFwaVtfLV0/a2V5fGNvb2tpZXx0b2tlbnxeYXV0aChvcml6YXRpb258X2hlYWRlcik/JHxzdHJpcGVbXy1dPyhrZXl8c2VjcmV0KXxtb25nbyhkYik/W18tXT91cmkvaTtcblxuLyoqXG4gKiBPbmUgc2VjcmV0LXNoYXBlZCB2YWx1ZSBwYXR0ZXJuLlxuICpcbiAqIGBqc2AgaXMgdXNlZCBieSB0aGUgTm9kZS1zaWRlIGxheWVycy4gYHJlMmAgaXMgdGhlIGVxdWl2YWxlbnQgc291cmNlIGZvclxuICogcHJvbXRhaWwncyBgcmVwbGFjZWAgc3RhZ2Ug4oCUIEdvJ3MgUkUyIGhhcyBubyBsb29rYXJvdW5kLCBzbyBhIHBhdHRlcm4gdGhhdFxuICogbmVlZHMgaXQgaGFzIGByZTI6IG51bGxgIGFuZCBzdGF5cyBOb2RlLW9ubHkgKEwyL0w0IHN0aWxsIGNhdGNoIGl0OyBpdCBqdXN0XG4gKiBpc24ndCBzY3J1YmJlZCBiZWZvcmUgc3RvcmFnZSkuIGAoP2kpYCBpcyBzcGVsbGVkIGlubGluZSBmb3IgUkUyIGJlY2F1c2VcbiAqIHByb210YWlsIHRha2VzIGEgYmFyZSBzb3VyY2Ugc3RyaW5nLCB3aGlsZSB0aGUgSlMgZm9ybSB1c2VzIHRoZSBgaWAgZmxhZy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTZW5zaXRpdmVWYWx1ZVBhdHRlcm4ge1xuICAvKiogU3RhYmxlIGlkZW50aWZpZXIsIHVzZWQgYXMgdGhlIHByb210YWlsIHN0YWdlIGNvbW1lbnQuICovXG4gIG5hbWU6IHN0cmluZztcbiAganM6IFJlZ0V4cDtcbiAgLyoqIFJFMiBzb3VyY2UgZm9yIHByb210YWlsLCBvciBudWxsIHdoZW4gdGhlIHBhdHRlcm4gaXMgSlMtb25seS4gKi9cbiAgcmUyOiBzdHJpbmcgfCBudWxsO1xuICAvKiogUmVwbGFjZW1lbnQgdGV4dC4gYCQxYCBrZWVwcyBhIGxlYWRpbmcgY2FwdHVyZSAoZS5nLiB0aGUgYD90b2tlbj1gIHByZWZpeCkuICovXG4gIHJlcGxhY2VtZW50OiBzdHJpbmc7XG59XG5cbi8qKlxuICogT3JkZXJlZCDigJQgZWFybGllciBwYXR0ZXJucyB3aW4sIHNvIHRoZSBzcGVjaWZpYyAoYSBTdHJpcGUga2V5KSBpcyBtYXNrZWRcbiAqIGJlZm9yZSB0aGUgZ2VuZXJpYyAoYSBgc2VjcmV0PWAgYXNzaWdubWVudCkgY2FuIHByb2R1Y2UgYSBtZXNzaWVyIHJlc3VsdC5cbiAqL1xuZXhwb3J0IGNvbnN0IFNFTlNJVElWRV9WQUxVRV9QQVRURVJOUzogcmVhZG9ubHkgU2Vuc2l0aXZlVmFsdWVQYXR0ZXJuW10gPSBbXG4gIHtcbiAgICAvLyBBIFBFTSBibG9jayBzcGFucyBsaW5lcywgc28gcHJvbXRhaWwgKHdoaWNoIHJlcGxhY2VzIHBlciBsaW5lKSBjYW4ndCBzZWVcbiAgICAvLyB0aGUgd2hvbGUgdGhpbmcg4oCUIEpTLW9ubHkuIFRoZSBCRUdJTiBsaW5lIGFsb25lIGlzIHN0aWxsIGEgc3Ryb25nIHNpZ25hbC5cbiAgICBuYW1lOiAncGVtX3ByaXZhdGVfa2V5JyxcbiAgICBqczogLy0tLS0tQkVHSU5bQS1aIF0qUFJJVkFURSBLRVktLS0tLVtcXHNcXFNdKj8tLS0tLUVORFtBLVogXSpQUklWQVRFIEtFWS0tLS0tL2csXG4gICAgcmUyOiBudWxsLFxuICAgIHJlcGxhY2VtZW50OiBSRURBQ1RFRCxcbiAgfSxcbiAge1xuICAgIG5hbWU6ICdwZW1fcHJpdmF0ZV9rZXlfaGVhZGVyJyxcbiAgICBqczogLy0tLS0tQkVHSU5bQS1aIF0qUFJJVkFURSBLRVktLS0tLS9nLFxuICAgIHJlMjogJy0tLS0tQkVHSU5bQS1aIF0qUFJJVkFURSBLRVktLS0tLScsXG4gICAgcmVwbGFjZW1lbnQ6IFJFREFDVEVELFxuICB9LFxuICB7XG4gICAgbmFtZTogJ2p3dCcsXG4gICAganM6IC9leUpbQS1aYS16MC05Xy1dezgsfVxcLltBLVphLXowLTlfLV17OCx9XFwuW0EtWmEtejAtOV8tXSovZyxcbiAgICByZTI6ICdleUpbQS1aYS16MC05Xy1dezgsfVxcXFwuW0EtWmEtejAtOV8tXXs4LH1cXFxcLltBLVphLXowLTlfLV0qJyxcbiAgICByZXBsYWNlbWVudDogUkVEQUNURUQsXG4gIH0sXG4gIHtcbiAgICBuYW1lOiAnYmVhcmVyX3Rva2VuJyxcbiAgICBqczogL2JlYXJlclxccytbQS1aYS16MC05Ll9+Ky8tXSs9Ki9naSxcbiAgICByZTI6ICcoP2kpYmVhcmVyXFxcXHMrW0EtWmEtejAtOS5ffisvLV0rPSonLFxuICAgIHJlcGxhY2VtZW50OiBgQmVhcmVyICR7UkVEQUNURUR9YCxcbiAgfSxcbiAge1xuICAgIG5hbWU6ICdhd3NfYWNjZXNzX2tleV9pZCcsXG4gICAganM6IC9cXGIoPzpBM1RbQS1aMC05XXxBS0lBfEFTSUF8QUJJQXxBQ0NBKVtBLVowLTldezE2fVxcYi9nLFxuICAgIHJlMjogJ1xcXFxiKEEzVFtBLVowLTldfEFLSUF8QVNJQXxBQklBfEFDQ0EpW0EtWjAtOV17MTZ9XFxcXGInLFxuICAgIHJlcGxhY2VtZW50OiBSRURBQ1RFRCxcbiAgfSxcbiAge1xuICAgIG5hbWU6ICdzdHJpcGVfa2V5JyxcbiAgICBqczogL1xcYig/OnNrfHJrKV8oPzpsaXZlfHRlc3QpX1tBLVphLXowLTldezEwLH1cXGIvZyxcbiAgICByZTI6ICdcXFxcYihza3xyaylfKGxpdmV8dGVzdClfW0EtWmEtejAtOV17MTAsfVxcXFxiJyxcbiAgICByZXBsYWNlbWVudDogUkVEQUNURUQsXG4gIH0sXG4gIHtcbiAgICBuYW1lOiAnZ2l0aHViX3Rva2VuJyxcbiAgICBqczogL1xcYmdoW3BvdXNyXV9bQS1aYS16MC05XXsyMCx9XFxiL2csXG4gICAgcmUyOiAnXFxcXGJnaFtwb3Vzcl1fW0EtWmEtejAtOV17MjAsfVxcXFxiJyxcbiAgICByZXBsYWNlbWVudDogUkVEQUNURUQsXG4gIH0sXG4gIHtcbiAgICBuYW1lOiAnc2xhY2tfdG9rZW4nLFxuICAgIGpzOiAvXFxieG94W2FicHJzXS1bQS1aYS16MC05LV17MTAsfVxcYi9nLFxuICAgIHJlMjogJ1xcXFxieG94W2FicHJzXS1bQS1aYS16MC05LV17MTAsfVxcXFxiJyxcbiAgICByZXBsYWNlbWVudDogUkVEQUNURUQsXG4gIH0sXG4gIHtcbiAgICAvLyBgc2NoZW1lOi8vdXNlcjpwYXNzQGhvc3RgIOKAlCBrZWVwIHRoZSBzY2hlbWUgc28gdGhlIGxpbmUgc3RheXMgcmVhZGFibGUuXG4gICAgbmFtZTogJ3VybF9jcmVkZW50aWFscycsXG4gICAganM6IC8oW2EtekEtWl1bYS16QS1aMC05Ky4tXSo6XFwvXFwvKVteOkAvXFxzXSs6W15AL1xcc10rQC9nLFxuICAgIHJlMjogJyhbYS16QS1aXVthLXpBLVowLTkrLi1dKjovLylbXjpAL1xcXFxzXSs6W15AL1xcXFxzXStAJyxcbiAgICByZXBsYWNlbWVudDogYCQxJHtSRURBQ1RFRH1AYCxcbiAgfSxcbiAge1xuICAgIC8vIGA/dG9rZW494oCmYCAvIGAmYXBpX2tleT3igKZgIGluIGEgVVJMLiBLZWVwcyB0aGUgcGFyYW1ldGVyIG5hbWUgdmlzaWJsZS5cbiAgICBuYW1lOiAndXJsX3NlY3JldF9wYXJhbScsXG4gICAganM6IC8oWz8mXSg/OmFjY2Vzc1tfLV0/dG9rZW58YXBpW18tXT9rZXl8YXBpa2V5fGF1dGh8cGFzc3dvcmR8c2VjcmV0fHNpZ3xzaWduYXR1cmV8dG9rZW4pPSlbXiZcXHNcIic8Pl0rL2dpLFxuICAgIHJlMjogJyg/aSkoWz8mXShhY2Nlc3NbXy1dP3Rva2VufGFwaVtfLV0/a2V5fGFwaWtleXxhdXRofHBhc3N3b3JkfHNlY3JldHxzaWd8c2lnbmF0dXJlfHRva2VuKT0pW14mXFxcXHNcIlxcJzw+XSsnLFxuICAgIHJlcGxhY2VtZW50OiBgJDEke1JFREFDVEVEfWAsXG4gIH0sXG4gIHtcbiAgICAvLyBgc2VjcmV0PeKApmAgLyBgXCJwYXNzd29yZFwiOiBcIuKAplwiYCBzdHlsZSBhc3NpZ25tZW50cyBpbiBmcmVlIHRleHQuXG4gICAgLy8gYCZgIGlzIGV4Y2x1ZGVkIGZyb20gdGhlIHZhbHVlIGNsYXNzIHNvIHRoaXMgY2FuJ3QgcnVuIG9uIGFmdGVyXG4gICAgLy8gYHVybF9zZWNyZXRfcGFyYW1gIGFuZCBzd2FsbG93IHRoZSByZXN0IG9mIGEgcXVlcnkgc3RyaW5nIOKAlCB0aGUgVVJMIHJ1bGVcbiAgICAvLyBoYXMgYWxyZWFkeSBtYXNrZWQgdGhvc2UsIGFuZCB0aGlzIG9uZSBtdXN0IG5vdCBlYXQgYCZwYWdlPTJgLlxuICAgIG5hbWU6ICdpbmxpbmVfc2VjcmV0X2Fzc2lnbm1lbnQnLFxuICAgIGpzOiAvKCg/OmF3c18pPyg/OnNlY3JldF9hY2Nlc3Nfa2V5fGNsaWVudF9zZWNyZXR8YXBpW18tXT9rZXl8YXBpa2V5fHBhc3N3b3JkfHBhc3N3ZHxzZWNyZXR8dG9rZW4pXCI/XFxzKls9Ol1cXHMqXCI/KVteXFxzXCInLDt9Jl0rL2dpLFxuICAgIHJlMjogJyg/aSkoKChhd3NfKT8oc2VjcmV0X2FjY2Vzc19rZXl8Y2xpZW50X3NlY3JldHxhcGlbXy1dP2tleXxhcGlrZXl8cGFzc3dvcmR8cGFzc3dkfHNlY3JldHx0b2tlbikpXCI/XFxcXHMqWz06XVxcXFxzKlwiPylbXlxcXFxzXCJcXCcsO30mXSsnLFxuICAgIHJlcGxhY2VtZW50OiBgJDEke1JFREFDVEVEfWAsXG4gIH0sXG5dO1xuXG4vKipcbiAqIE1hc2sgc2VjcmV0LXNoYXBlZCB2YWx1ZXMgaW4gYSBzaW5nbGUgc3RyaW5nLlxuICpcbiAqIEFsc28gc2NydWJzIEFXUyBhY2NvdW50IGlkZW50aWZpZXJzIHZpYSB7QGxpbmsgc2NydWJBd3NJZGVudGlmaWVyc0Zyb21TdHJpbmd9XG4gKiDigJQgYSBoYXJkIHJlcG8gcnVsZSAoYW4gQVdTIGFjY291bnQgaWQgbXVzdCBuZXZlciBiZSBwZXJzaXN0ZWQgb3Igc3VyZmFjZWQpLFxuICogY29tcG9zZWQgaGVyZSByYXRoZXIgdGhhbiBkdXBsaWNhdGVkIHNvIHRoZSB0d28gcnVsZXMgY2FuJ3QgZHJpZnQuXG4gKlxuICogTm9uLXRocm93aW5nIGFuZCBhbGxvY2F0aW9uLWxpZ2h0IG9uIHRoZSBjb21tb24gcGF0aDogc3RyaW5ncyB3aXRoIG5vIG1hdGNoXG4gKiBjb21lIGJhY2sgYnkgaWRlbnRpdHkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYXNrTGluZShpbnB1dDogc3RyaW5nKTogc3RyaW5nIHtcbiAgaWYgKCFpbnB1dCkgcmV0dXJuIGlucHV0O1xuICBsZXQgb3V0ID0gaW5wdXQ7XG4gIGZvciAoY29uc3QgeyBqcywgcmVwbGFjZW1lbnQgfSBvZiBTRU5TSVRJVkVfVkFMVUVfUEFUVEVSTlMpIHtcbiAgICAvLyBganNgIGNhcnJpZXMgdGhlIC9nIGZsYWcsIHNvIHJlc2V0IGxhc3RJbmRleCDigJQgYSBzaGFyZWQgUmVnRXhwIG9iamVjdCBpc1xuICAgIC8vIHN0YXRlZnVsIGFjcm9zcyBjYWxscyBhbmQgd291bGQgb3RoZXJ3aXNlIHNraXAgbWF0Y2hlcyBpbnRlcm1pdHRlbnRseS5cbiAgICBqcy5sYXN0SW5kZXggPSAwO1xuICAgIG91dCA9IG91dC5yZXBsYWNlKGpzLCByZXBsYWNlbWVudCk7XG4gIH1cbiAgcmV0dXJuIHNjcnViQXdzSWRlbnRpZmllcnNGcm9tU3RyaW5nKG91dCk7XG59XG5cbi8qKlxuICogRG9lcyB0aGlzIHN0cmluZyBsb29rIGxpa2UgaXQgQ09OVEFJTlMgYSBzZWNyZXQ/IFVzZWQgdG8gcmVqZWN0IGxvZy1zZWFyY2hcbiAqIHRlcm1zLCBjbG9zaW5nIHRoZSBvdGhlciBlbmQgb2YgdGhlIG9yYWNsZSBkZXNjcmliZWQgYXQgdGhlIHRvcCBvZiB0aGlzIGZpbGU6XG4gKiBtYXNraW5nIHRoZSByZXN1bHQgaXMgcG9pbnRsZXNzIGlmIHRoZSBxdWVyeSBpdHNlbGYgY2FuIGNvbmZpcm0gYSBndWVzcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxvb2tzU2Vuc2l0aXZlKGlucHV0OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgaWYgKCFpbnB1dCkgcmV0dXJuIGZhbHNlO1xuICByZXR1cm4gbWFza0xpbmUoaW5wdXQpICE9PSBpbnB1dDtcbn1cbiJdfQ==