@pipeline-builder/api-core 5.2.3 → 5.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/lib/constants/ai-providers.d.ts +3 -22
  2. package/lib/constants/ai-providers.js +6 -56
  3. package/lib/errors/app-errors.d.ts +14 -0
  4. package/lib/errors/app-errors.js +21 -1
  5. package/lib/helpers/sse-helpers.d.ts +33 -3
  6. package/lib/helpers/sse-helpers.js +91 -19
  7. package/lib/middleware/auth.js +6 -3
  8. package/lib/middleware/deferred-quota-check.d.ts +5 -0
  9. package/lib/middleware/deferred-quota-check.js +33 -0
  10. package/lib/middleware/ecosystem-guard.d.ts +3 -3
  11. package/lib/middleware/ecosystem-guard.js +5 -5
  12. package/lib/middleware/index.d.ts +5 -2
  13. package/lib/middleware/index.js +6 -3
  14. package/lib/middleware/on-behalf.d.ts +37 -0
  15. package/lib/middleware/on-behalf.js +143 -0
  16. package/lib/middleware/permission-gates.d.ts +11 -0
  17. package/lib/middleware/permission-gates.js +7 -1
  18. package/lib/middleware/quota-exempt-routes.d.ts +36 -0
  19. package/lib/middleware/quota-exempt-routes.js +47 -0
  20. package/lib/middleware/route-table.d.ts +104 -0
  21. package/lib/middleware/route-table.js +72 -2
  22. package/lib/middleware/service-tokens.d.ts +8 -0
  23. package/lib/middleware/service-tokens.js +2 -1
  24. package/lib/middleware/step-up.js +11 -1
  25. package/lib/services/ai-call-weight.d.ts +24 -0
  26. package/lib/services/ai-call-weight.js +77 -0
  27. package/lib/services/audit-context.d.ts +105 -0
  28. package/lib/services/audit-context.js +134 -0
  29. package/lib/services/index.d.ts +7 -2
  30. package/lib/services/index.js +7 -2
  31. package/lib/services/org-ai-client.d.ts +61 -0
  32. package/lib/services/org-ai-client.js +112 -0
  33. package/lib/services/quota-increment-batcher.d.ts +81 -0
  34. package/lib/services/quota-increment-batcher.js +166 -0
  35. package/lib/services/quota.d.ts +158 -14
  36. package/lib/services/quota.js +252 -22
  37. package/lib/services/remote-audit-client.d.ts +44 -1
  38. package/lib/services/remote-audit-client.js +106 -20
  39. package/lib/services/version-vuln-policy.d.ts +174 -0
  40. package/lib/services/version-vuln-policy.js +242 -0
  41. package/lib/types/ai-catalog.d.ts +63 -0
  42. package/lib/types/ai-catalog.js +82 -0
  43. package/lib/types/ask-proposals.js +6 -6
  44. package/lib/types/build-catalog.d.ts +154 -0
  45. package/lib/types/build-catalog.js +158 -0
  46. package/lib/types/common.d.ts +37 -3
  47. package/lib/types/common.js +20 -2
  48. package/lib/types/ecosystem-notifications.d.ts +5 -5
  49. package/lib/types/ecosystem-notifications.js +9 -3
  50. package/lib/types/error-codes.d.ts +13 -6
  51. package/lib/types/error-codes.js +18 -8
  52. package/lib/types/feature-flags.d.ts +6 -4
  53. package/lib/types/feature-flags.js +11 -6
  54. package/lib/types/index.d.ts +6 -4
  55. package/lib/types/index.js +12 -5
  56. package/lib/types/metadata-keys.d.ts +6 -0
  57. package/lib/types/metadata-keys.js +4 -1
  58. package/lib/types/permissions.d.ts +344 -3
  59. package/lib/types/permissions.js +596 -21
  60. package/lib/types/pipeline.d.ts +39 -0
  61. package/lib/types/pipeline.js +57 -1
  62. package/lib/types/plugin-health.d.ts +0 -2
  63. package/lib/types/plugin-health.js +1 -11
  64. package/lib/types/plugin-scan.d.ts +192 -42
  65. package/lib/types/plugin-scan.js +159 -43
  66. package/lib/types/quota-catalog.d.ts +247 -0
  67. package/lib/types/quota-catalog.js +122 -0
  68. package/lib/types/quota-tiers.d.ts +118 -0
  69. package/lib/types/quota-tiers.js +153 -2
  70. package/lib/types/remote-audit-actions.d.ts +1 -1
  71. package/lib/types/remote-audit-actions.js +131 -1
  72. package/lib/types/wire-vocabulary.js +8 -1
  73. package/lib/utils/index.d.ts +1 -1
  74. package/lib/utils/index.js +2 -2
  75. package/lib/utils/response.d.ts +35 -2
  76. package/lib/utils/response.js +42 -3
  77. package/lib/validation/ai-schemas.d.ts +27 -0
  78. package/lib/validation/ai-schemas.js +31 -5
  79. package/lib/validation/plugin-schemas.d.ts +15 -0
  80. package/lib/validation/plugin-schemas.js +28 -1
  81. package/package.json +31 -2
@@ -0,0 +1,5 @@
1
+ import type { NextFunction, Request, RequestHandler, Response } from 'express';
2
+ /** Arm `check` to run after this request authenticates. */
3
+ export declare function armDeferredQuotaCheck(res: Response, check: RequestHandler): void;
4
+ /** `requireAuth`'s `next()`: run the armed quota check, if any, then continue. */
5
+ export declare function runDeferredQuotaCheck(req: Request, res: Response, next: NextFunction): void;
@@ -0,0 +1,33 @@
1
+ // Copyright 2026 Pipeline Builder Contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ /**
4
+ * A quota check armed at MOUNT time and run by `requireAuth` once the caller is
5
+ * verified.
6
+ *
7
+ * Why deferred: the apiCalls meter + check mount ONCE per service, ahead of its
8
+ * whole user surface (api-server `apiCallsQuota`), but authentication is per
9
+ * route — routers mix public, user and machine routes under one prefix. At mount
10
+ * time there is no verified org to check yet, and checking a header-derived or
11
+ * peeked one would hand a forged token a victim org's usage in the 429 body. So
12
+ * the mount only ARMS the check here, and `requireAuth` (api-core's, and
13
+ * platform's own) runs it at its single post-verification choke point, after
14
+ * the request identity has been re-derived from the JWT. A route that never
15
+ * authenticates never runs it — there is no org to bill.
16
+ *
17
+ * At most once per request: running it empties the slot, so a second
18
+ * `requireAuth` in the same chain is a plain `next()`.
19
+ */
20
+ const SLOT = 'deferredQuotaCheck';
21
+ /** Arm `check` to run after this request authenticates. */
22
+ export function armDeferredQuotaCheck(res, check) {
23
+ res.locals[SLOT] = check;
24
+ }
25
+ /** `requireAuth`'s `next()`: run the armed quota check, if any, then continue. */
26
+ export function runDeferredQuotaCheck(req, res, next) {
27
+ const check = res.locals?.[SLOT];
28
+ if (!check)
29
+ return next();
30
+ delete res.locals[SLOT];
31
+ void check(req, res, next);
32
+ }
33
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVmZXJyZWQtcXVvdGEtY2hlY2suanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbWlkZGxld2FyZS9kZWZlcnJlZC1xdW90YS1jaGVjay50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwrQ0FBK0M7QUFDL0Msc0NBQXNDO0FBSXRDOzs7Ozs7Ozs7Ozs7Ozs7O0dBZ0JHO0FBQ0gsTUFBTSxJQUFJLEdBQUcsb0JBQW9CLENBQUM7QUFFbEMsMkRBQTJEO0FBQzNELE1BQU0sVUFBVSxxQkFBcUIsQ0FBQyxHQUFhLEVBQUUsS0FBcUI7SUFDeEUsR0FBRyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxLQUFLLENBQUM7QUFDM0IsQ0FBQztBQUVELGtGQUFrRjtBQUNsRixNQUFNLFVBQVUscUJBQXFCLENBQUMsR0FBWSxFQUFFLEdBQWEsRUFBRSxJQUFrQjtJQUNuRixNQUFNLEtBQUssR0FBRyxHQUFHLENBQUMsTUFBTSxFQUFFLENBQUMsSUFBSSxDQUErQixDQUFDO0lBQy9ELElBQUksQ0FBQyxLQUFLO1FBQUUsT0FBTyxJQUFJLEVBQUUsQ0FBQztJQUMxQixPQUFPLEdBQUcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDeEIsS0FBSyxLQUFLLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQztBQUM3QixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbmltcG9ydCB0eXBlIHsgTmV4dEZ1bmN0aW9uLCBSZXF1ZXN0LCBSZXF1ZXN0SGFuZGxlciwgUmVzcG9uc2UgfSBmcm9tICdleHByZXNzJztcblxuLyoqXG4gKiBBIHF1b3RhIGNoZWNrIGFybWVkIGF0IE1PVU5UIHRpbWUgYW5kIHJ1biBieSBgcmVxdWlyZUF1dGhgIG9uY2UgdGhlIGNhbGxlciBpc1xuICogdmVyaWZpZWQuXG4gKlxuICogV2h5IGRlZmVycmVkOiB0aGUgYXBpQ2FsbHMgbWV0ZXIgKyBjaGVjayBtb3VudCBPTkNFIHBlciBzZXJ2aWNlLCBhaGVhZCBvZiBpdHNcbiAqIHdob2xlIHVzZXIgc3VyZmFjZSAoYXBpLXNlcnZlciBgYXBpQ2FsbHNRdW90YWApLCBidXQgYXV0aGVudGljYXRpb24gaXMgcGVyXG4gKiByb3V0ZSDigJQgcm91dGVycyBtaXggcHVibGljLCB1c2VyIGFuZCBtYWNoaW5lIHJvdXRlcyB1bmRlciBvbmUgcHJlZml4LiBBdCBtb3VudFxuICogdGltZSB0aGVyZSBpcyBubyB2ZXJpZmllZCBvcmcgdG8gY2hlY2sgeWV0LCBhbmQgY2hlY2tpbmcgYSBoZWFkZXItZGVyaXZlZCBvclxuICogcGVla2VkIG9uZSB3b3VsZCBoYW5kIGEgZm9yZ2VkIHRva2VuIGEgdmljdGltIG9yZydzIHVzYWdlIGluIHRoZSA0MjkgYm9keS4gU29cbiAqIHRoZSBtb3VudCBvbmx5IEFSTVMgdGhlIGNoZWNrIGhlcmUsIGFuZCBgcmVxdWlyZUF1dGhgIChhcGktY29yZSdzLCBhbmRcbiAqIHBsYXRmb3JtJ3Mgb3duKSBydW5zIGl0IGF0IGl0cyBzaW5nbGUgcG9zdC12ZXJpZmljYXRpb24gY2hva2UgcG9pbnQsIGFmdGVyXG4gKiB0aGUgcmVxdWVzdCBpZGVudGl0eSBoYXMgYmVlbiByZS1kZXJpdmVkIGZyb20gdGhlIEpXVC4gQSByb3V0ZSB0aGF0IG5ldmVyXG4gKiBhdXRoZW50aWNhdGVzIG5ldmVyIHJ1bnMgaXQg4oCUIHRoZXJlIGlzIG5vIG9yZyB0byBiaWxsLlxuICpcbiAqIEF0IG1vc3Qgb25jZSBwZXIgcmVxdWVzdDogcnVubmluZyBpdCBlbXB0aWVzIHRoZSBzbG90LCBzbyBhIHNlY29uZFxuICogYHJlcXVpcmVBdXRoYCBpbiB0aGUgc2FtZSBjaGFpbiBpcyBhIHBsYWluIGBuZXh0KClgLlxuICovXG5jb25zdCBTTE9UID0gJ2RlZmVycmVkUXVvdGFDaGVjayc7XG5cbi8qKiBBcm0gYGNoZWNrYCB0byBydW4gYWZ0ZXIgdGhpcyByZXF1ZXN0IGF1dGhlbnRpY2F0ZXMuICovXG5leHBvcnQgZnVuY3Rpb24gYXJtRGVmZXJyZWRRdW90YUNoZWNrKHJlczogUmVzcG9uc2UsIGNoZWNrOiBSZXF1ZXN0SGFuZGxlcik6IHZvaWQge1xuICByZXMubG9jYWxzW1NMT1RdID0gY2hlY2s7XG59XG5cbi8qKiBgcmVxdWlyZUF1dGhgJ3MgYG5leHQoKWA6IHJ1biB0aGUgYXJtZWQgcXVvdGEgY2hlY2ssIGlmIGFueSwgdGhlbiBjb250aW51ZS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBydW5EZWZlcnJlZFF1b3RhQ2hlY2socmVxOiBSZXF1ZXN0LCByZXM6IFJlc3BvbnNlLCBuZXh0OiBOZXh0RnVuY3Rpb24pOiB2b2lkIHtcbiAgY29uc3QgY2hlY2sgPSByZXMubG9jYWxzPy5bU0xPVF0gYXMgUmVxdWVzdEhhbmRsZXIgfCB1bmRlZmluZWQ7XG4gIGlmICghY2hlY2spIHJldHVybiBuZXh0KCk7XG4gIGRlbGV0ZSByZXMubG9jYWxzW1NMT1RdO1xuICB2b2lkIGNoZWNrKHJlcSwgcmVzLCBuZXh0KTtcbn1cbiJdfQ==
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Only the system org manages or approves the ecosystem. A route that exercises
5
5
  * a system-org-only permission (`plugins:moderate`, `publishers:verify`) must
6
- * therefore check three things, and {@link requireEcosystemPermission} composes
6
+ * therefore check three things, and {@link requireSystemOrgPermission} composes
7
7
  * them so no route can forget one:
8
8
  *
9
9
  * 1. {@link requireSystemOrg} — the caller's ACTIVE org is the system org. A
@@ -36,7 +36,7 @@ export declare const requireSystemOrg: (req: Request, res: Response, next: NextF
36
36
  * as an array, which Express flattens:
37
37
  *
38
38
  * ```ts
39
- * router.post('/requests/:id/approve', requireAuth, requireEcosystemPermission('plugins:moderate'),
39
+ * router.post('/requests/:id/approve', requireAuth, requireSystemOrgPermission('plugins:moderate'),
40
40
  * requireStepUp, audited('plugin.request.approve'), handler);
41
41
  * ```
42
42
  *
@@ -44,4 +44,4 @@ export declare const requireSystemOrg: (req: Request, res: Response, next: NextF
44
44
  * system-org-only — a tenant permission behind this gate would be unreachable
45
45
  * for every tenant, which is always a wiring mistake.
46
46
  */
47
- export declare function requireEcosystemPermission(...permissions: Permission[]): RequestHandler[];
47
+ export declare function requireSystemOrgPermission(...permissions: Permission[]): RequestHandler[];
@@ -36,7 +36,7 @@ export const requireSystemOrg = tagRouteGate(function requireSystemOrg(req, res,
36
36
  * as an array, which Express flattens:
37
37
  *
38
38
  * ```ts
39
- * router.post('/requests/:id/approve', requireAuth, requireEcosystemPermission('plugins:moderate'),
39
+ * router.post('/requests/:id/approve', requireAuth, requireSystemOrgPermission('plugins:moderate'),
40
40
  * requireStepUp, audited('plugin.request.approve'), handler);
41
41
  * ```
42
42
  *
@@ -44,12 +44,12 @@ export const requireSystemOrg = tagRouteGate(function requireSystemOrg(req, res,
44
44
  * system-org-only — a tenant permission behind this gate would be unreachable
45
45
  * for every tenant, which is always a wiring mistake.
46
46
  */
47
- export function requireEcosystemPermission(...permissions) {
47
+ export function requireSystemOrgPermission(...permissions) {
48
48
  if (permissions.length === 0)
49
- throw new Error('requireEcosystemPermission needs at least one permission');
49
+ throw new Error('requireSystemOrgPermission needs at least one permission');
50
50
  const tenant = permissions.filter((p) => !isSystemOrgOnlyPermission(p));
51
51
  if (tenant.length > 0) {
52
- throw new Error(`requireEcosystemPermission only takes system-org-only permissions; got ${tenant.join(', ')}`);
52
+ throw new Error(`requireSystemOrgPermission only takes system-org-only permissions; got ${tenant.join(', ')}`);
53
53
  }
54
54
  return [
55
55
  requireSystemOrg,
@@ -57,4 +57,4 @@ export function requireEcosystemPermission(...permissions) {
57
57
  requireAssurance({ minAssurance: 2 }),
58
58
  ];
59
59
  }
60
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWNvc3lzdGVtLWd1YXJkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL21pZGRsZXdhcmUvZWNvc3lzdGVtLWd1YXJkLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUF3QnRDLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ2xELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQzdFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUNoRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDaEQsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQ3pELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUNwRCxPQUFPLEVBQUUseUJBQXlCLEVBQW1CLE1BQU0seUJBQXlCLENBQUM7QUFDckYsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ3pELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUVqRDsrRUFDK0U7QUFDL0UsTUFBTSxVQUFVLGtCQUFrQixDQUFDLEdBQVk7SUFDN0MsT0FBTyxhQUFhLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxjQUFjLENBQUMsQ0FBQztBQUNqRCxDQUFDO0FBRUQ7Ozs7O0dBS0c7QUFDSCxNQUFNLENBQUMsTUFBTSxnQkFBZ0IsR0FBRyxZQUFZLENBQUMsU0FBUyxnQkFBZ0IsQ0FBQyxHQUFZLEVBQUUsR0FBYSxFQUFFLElBQWtCO0lBQ3BILElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDZCxPQUFPLFNBQVMsQ0FBQyxHQUFHLEVBQUUsVUFBVSxDQUFDLFlBQVksRUFBRSx5QkFBeUIsRUFBRSxTQUFTLENBQUMsWUFBWSxDQUFDLENBQUM7SUFDcEcsQ0FBQztJQUNELElBQUksa0JBQWtCLENBQUMsR0FBRyxDQUFDO1FBQUUsT0FBTyxJQUFJLEVBQUUsQ0FBQztJQUMzQyxXQUFXLENBQUMsZ0NBQWdDLEVBQUUsRUFBRSxTQUFTLEVBQUUsR0FBRyxDQUFDLElBQUksQ0FBQyxhQUFhLElBQUksU0FBUyxFQUFFLENBQUMsQ0FBQztJQUNsRyxpQkFBaUIsQ0FBQyxHQUFHLEVBQUUsWUFBWSxDQUFDLENBQUM7SUFDckMsT0FBTyxTQUFTLENBQ2QsR0FBRyxFQUFFLFVBQVUsQ0FBQyxTQUFTLEVBQ3pCLG1HQUFtRyxFQUNuRyxTQUFTLENBQUMsbUJBQW1CLENBQzlCLENBQUM7QUFDSixDQUFDLEVBQUUsRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFFLENBQUMsQ0FBQztBQUUxQjs7Ozs7Ozs7Ozs7OztHQWFHO0FBQ0gsTUFBTSxVQUFVLDBCQUEwQixDQUFDLEdBQUcsV0FBeUI7SUFDckUsSUFBSSxXQUFXLENBQUMsTUFBTSxLQUFLLENBQUM7UUFBRSxNQUFNLElBQUksS0FBSyxDQUFDLDBEQUEwRCxDQUFDLENBQUM7SUFDMUcsTUFBTSxNQUFNLEdBQUcsV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3hFLElBQUksTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztRQUN0QixNQUFNLElBQUksS0FBSyxDQUFDLDBFQUEwRSxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUNqSCxDQUFDO0lBQ0QsT0FBTztRQUNMLGdCQUFnQjtRQUNoQixpQkFBaUIsQ0FBQyxHQUFHLFdBQVcsQ0FBQztRQUNqQyxnQkFBZ0IsQ0FBQyxFQUFFLFlBQVksRUFBRSxDQUFDLEVBQUUsQ0FBQztLQUNsQixDQUFDO0FBQ3hCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuLyoqXG4gKiBUaGUgcGx1Z2luLWVjb3N5c3RlbSBnb3Zlcm5hbmNlIGdhdGUgKGRvY3MvcnVuYm9va3MvZWNvc3lzdGVtLW1vZGVyYXRpb24ubWQpLlxuICpcbiAqIE9ubHkgdGhlIHN5c3RlbSBvcmcgbWFuYWdlcyBvciBhcHByb3ZlcyB0aGUgZWNvc3lzdGVtLiBBIHJvdXRlIHRoYXQgZXhlcmNpc2VzXG4gKiBhIHN5c3RlbS1vcmctb25seSBwZXJtaXNzaW9uIChgcGx1Z2luczptb2RlcmF0ZWAsIGBwdWJsaXNoZXJzOnZlcmlmeWApIG11c3RcbiAqIHRoZXJlZm9yZSBjaGVjayB0aHJlZSB0aGluZ3MsIGFuZCB7QGxpbmsgcmVxdWlyZUVjb3N5c3RlbVBlcm1pc3Npb259IGNvbXBvc2VzXG4gKiB0aGVtIHNvIG5vIHJvdXRlIGNhbiBmb3JnZXQgb25lOlxuICpcbiAqICAxLiB7QGxpbmsgcmVxdWlyZVN5c3RlbU9yZ30g4oCUIHRoZSBjYWxsZXIncyBBQ1RJVkUgb3JnIGlzIHRoZSBzeXN0ZW0gb3JnLiBBXG4gKiAgICAgdG9rZW4gbWludGVkIGluIGEgdGVuYW50IG9yZyBpcyByZWZ1c2VkIGV2ZW4gZm9yIHRoZSBzYW1lIHBlcnNvbiAoYW5kIGV2ZW5cbiAqICAgICBmb3IgYSBzdXBlcmFkbWluOiB0aGV5IHN3aXRjaCB0byB0aGUgc3lzdGVtIG9yZyB0byBhY3Qgb24gdGhlIGVjb3N5c3RlbSxcbiAqICAgICBzbyBldmVyeSBnb3Zlcm5hbmNlIGRlY2lzaW9uIGlzIHJlY29yZGVkIHdpdGggdGhlIHN5c3RlbSBvcmcncyBpZCkuXG4gKiAgMi4gdGhlIHBlcm1pc3Npb24gaXRzZWxmIChgcmVxdWlyZVBlcm1pc3Npb25gLCBhbnktb2YpO1xuICogIDMuIGFuIE1GQS1ncmFkZSBzZXNzaW9uIChgcmVxdWlyZUFzc3VyYW5jZSh7IG1pbkFzc3VyYW5jZTogMiB9KWApLCB3aGljaCBhbHNvXG4gKiAgICAgcmVmdXNlcyBldmVyeSBtYWNoaW5lIGNyZWRlbnRpYWwuXG4gKlxuICogVGhlIHJvdXRlLWNvdmVyYWdlIGdvdmVybmFuY2UgY2hlY2sgKGBmaW5kU3lzdGVtT3JnR3VhcmRWaW9sYXRpb25zYCBpblxuICogYHRlc3Rpbmcvcm91dGUtY292ZXJhZ2UudHNgKSBmYWlscyBhbnkgcm91dGUgdGhhdCBnYXRlcyBvbiBhIHN5c3RlbS1vcmctb25seVxuICogcGVybWlzc2lvbiB3aXRob3V0IDEgYW5kIDMsIHNvIGEgaGFuZC1yb2xsZWQgY2hhaW4gY2Fubm90IHNsaXAgdGhyb3VnaC5cbiAqL1xuXG5pbXBvcnQgdHlwZSB7IE5leHRGdW5jdGlvbiwgUmVxdWVzdCwgUmVxdWVzdEhhbmRsZXIsIFJlc3BvbnNlIH0gZnJvbSAnZXhwcmVzcyc7XG5pbXBvcnQgeyByZXF1aXJlQXNzdXJhbmNlIH0gZnJvbSAnLi9hc3N1cmFuY2UuanMnO1xuaW1wb3J0IHsgcmVjb3JkQXV0aHpEZW5pYWwsIHJlcXVpcmVQZXJtaXNzaW9uIH0gZnJvbSAnLi9wZXJtaXNzaW9uLWdhdGVzLmpzJztcbmltcG9ydCB7IHRhZ1JvdXRlR2F0ZSB9IGZyb20gJy4vcm91dGUtdGFibGUuanMnO1xuaW1wb3J0IHsgaXNTeXN0ZW1PcmdJZCB9IGZyb20gJy4vc3lzdGVtLW9yZy5qcyc7XG5pbXBvcnQgeyBIdHRwU3RhdHVzIH0gZnJvbSAnLi4vY29uc3RhbnRzL2h0dHAtc3RhdHVzLmpzJztcbmltcG9ydCB7IEVycm9yQ29kZSB9IGZyb20gJy4uL3R5cGVzL2Vycm9yLWNvZGVzLmpzJztcbmltcG9ydCB7IGlzU3lzdGVtT3JnT25seVBlcm1pc3Npb24sIHR5cGUgUGVybWlzc2lvbiB9IGZyb20gJy4uL3R5cGVzL3Blcm1pc3Npb25zLmpzJztcbmltcG9ydCB7IGVtaXRDb3VudGVyIH0gZnJvbSAnLi4vdXRpbHMvbWV0cmljLWVtaXR0ZXIuanMnO1xuaW1wb3J0IHsgc2VuZEVycm9yIH0gZnJvbSAnLi4vdXRpbHMvcmVzcG9uc2UuanMnO1xuXG4vKiogV2hldGhlciB0aGUgcmVxdWVzdCdzIEFDVElWRSBvcmcgKHRoZSB0b2tlbidzIGBvcmdhbml6YXRpb25JZGApIGlzIHRoZSBzeXN0ZW1cbiAqICBvcmcuIENvbXBhcmVkIGJ5IGlkIG9ubHkg4oCUIGFuIG9yZyBtZXJlbHkgTkFNRUQgXCJzeXN0ZW1cIiBuZXZlciBxdWFsaWZpZXMuICovXG5leHBvcnQgZnVuY3Rpb24gaXNTeXN0ZW1PcmdSZXF1ZXN0KHJlcTogUmVxdWVzdCk6IGJvb2xlYW4ge1xuICByZXR1cm4gaXNTeXN0ZW1PcmdJZChyZXEudXNlcj8ub3JnYW5pemF0aW9uSWQpO1xufVxuXG4vKipcbiAqIFJlcXVpcmUgdGhhdCB0aGUgY2FsbGVyJ3MgYWN0aXZlIG9yZyBpcyB0aGUgc3lzdGVtIG9yZy4gQ29tcG9zZSBhZnRlclxuICogYHJlcXVpcmVBdXRoYC4gUmVmdXNhbHMgYXJlIDQwMyBgU1lTVEVNX09SR19SRVFVSVJFRGAsIGNvdW50ZWRcbiAqIChgc3lzdGVtX29yZ19ndWFyZF9yZWZ1c2VkX3RvdGFsYCkgYW5kIGF1ZGl0ZWQgdGhyb3VnaCB0aGUgc2hhcmVkXG4gKiBgYXV0aHouZGVuaWVkYCBzaW5rIChgcmVxdWlyZWQ6ICdzeXN0ZW0tb3JnJ2ApLlxuICovXG5leHBvcnQgY29uc3QgcmVxdWlyZVN5c3RlbU9yZyA9IHRhZ1JvdXRlR2F0ZShmdW5jdGlvbiByZXF1aXJlU3lzdGVtT3JnKHJlcTogUmVxdWVzdCwgcmVzOiBSZXNwb25zZSwgbmV4dDogTmV4dEZ1bmN0aW9uKTogdm9pZCB7XG4gIGlmICghcmVxLnVzZXIpIHtcbiAgICByZXR1cm4gc2VuZEVycm9yKHJlcywgSHR0cFN0YXR1cy5VTkFVVEhPUklaRUQsICdBdXRoZW50aWNhdGlvbiByZXF1aXJlZCcsIEVycm9yQ29kZS5VTkFVVEhPUklaRUQpO1xuICB9XG4gIGlmIChpc1N5c3RlbU9yZ1JlcXVlc3QocmVxKSkgcmV0dXJuIG5leHQoKTtcbiAgZW1pdENvdW50ZXIoJ3N5c3RlbV9vcmdfZ3VhcmRfcmVmdXNlZF90b3RhbCcsIHsgcHJpbmNpcGFsOiByZXEudXNlci5wcmluY2lwYWxUeXBlID8/ICd1bmtub3duJyB9KTtcbiAgcmVjb3JkQXV0aHpEZW5pYWwocmVxLCAnc3lzdGVtLW9yZycpO1xuICByZXR1cm4gc2VuZEVycm9yKFxuICAgIHJlcywgSHR0cFN0YXR1cy5GT1JCSURERU4sXG4gICAgJ1RoaXMgYWN0aW9uIGlzIHJlc2VydmVkIGZvciB0aGUgc3lzdGVtIG9yZ2FuaXphdGlvbiDigJQgc3dpdGNoIHRvIGl0IHRvIG1hbmFnZSB0aGUgcGx1Z2luIGVjb3N5c3RlbScsXG4gICAgRXJyb3JDb2RlLlNZU1RFTV9PUkdfUkVRVUlSRUQsXG4gICk7XG59LCB7IGtpbmQ6ICdzeXN0ZW1PcmcnIH0pO1xuXG4vKipcbiAqIFRIRSBnYXRlIGZvciBhbiBlY29zeXN0ZW0tZ292ZXJuYW5jZSByb3V0ZTogc3lzdGVtIG9yZyArIChhbnkgb2YpIHRoZSBnaXZlblxuICogc3lzdGVtLW9yZy1vbmx5IHBlcm1pc3Npb24ocykgKyBhbiBNRkEtZ3JhZGUgaHVtYW4gc2Vzc2lvbi4gUmV0dXJucyB0aGUgY2hhaW5cbiAqIGFzIGFuIGFycmF5LCB3aGljaCBFeHByZXNzIGZsYXR0ZW5zOlxuICpcbiAqIGBgYHRzXG4gKiByb3V0ZXIucG9zdCgnL3JlcXVlc3RzLzppZC9hcHByb3ZlJywgcmVxdWlyZUF1dGgsIHJlcXVpcmVFY29zeXN0ZW1QZXJtaXNzaW9uKCdwbHVnaW5zOm1vZGVyYXRlJyksXG4gKiAgIHJlcXVpcmVTdGVwVXAsIGF1ZGl0ZWQoJ3BsdWdpbi5yZXF1ZXN0LmFwcHJvdmUnKSwgaGFuZGxlcik7XG4gKiBgYGBcbiAqXG4gKiBUaHJvd3MgYXQgcm91dGUtZGVmaW5pdGlvbiB0aW1lIHdoZW4gaGFuZGVkIGEgcGVybWlzc2lvbiB0aGF0IGlzIE5PVFxuICogc3lzdGVtLW9yZy1vbmx5IOKAlCBhIHRlbmFudCBwZXJtaXNzaW9uIGJlaGluZCB0aGlzIGdhdGUgd291bGQgYmUgdW5yZWFjaGFibGVcbiAqIGZvciBldmVyeSB0ZW5hbnQsIHdoaWNoIGlzIGFsd2F5cyBhIHdpcmluZyBtaXN0YWtlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVxdWlyZUVjb3N5c3RlbVBlcm1pc3Npb24oLi4ucGVybWlzc2lvbnM6IFBlcm1pc3Npb25bXSk6IFJlcXVlc3RIYW5kbGVyW10ge1xuICBpZiAocGVybWlzc2lvbnMubGVuZ3RoID09PSAwKSB0aHJvdyBuZXcgRXJyb3IoJ3JlcXVpcmVFY29zeXN0ZW1QZXJtaXNzaW9uIG5lZWRzIGF0IGxlYXN0IG9uZSBwZXJtaXNzaW9uJyk7XG4gIGNvbnN0IHRlbmFudCA9IHBlcm1pc3Npb25zLmZpbHRlcigocCkgPT4gIWlzU3lzdGVtT3JnT25seVBlcm1pc3Npb24ocCkpO1xuICBpZiAodGVuYW50Lmxlbmd0aCA+IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYHJlcXVpcmVFY29zeXN0ZW1QZXJtaXNzaW9uIG9ubHkgdGFrZXMgc3lzdGVtLW9yZy1vbmx5IHBlcm1pc3Npb25zOyBnb3QgJHt0ZW5hbnQuam9pbignLCAnKX1gKTtcbiAgfVxuICByZXR1cm4gW1xuICAgIHJlcXVpcmVTeXN0ZW1PcmcsXG4gICAgcmVxdWlyZVBlcm1pc3Npb24oLi4ucGVybWlzc2lvbnMpLFxuICAgIHJlcXVpcmVBc3N1cmFuY2UoeyBtaW5Bc3N1cmFuY2U6IDIgfSksXG4gIF0gYXMgUmVxdWVzdEhhbmRsZXJbXTtcbn1cbiJdfQ==
60
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWNvc3lzdGVtLWd1YXJkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL21pZGRsZXdhcmUvZWNvc3lzdGVtLWd1YXJkLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUF3QnRDLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ2xELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQzdFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUNoRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDaEQsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQ3pELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUNwRCxPQUFPLEVBQUUseUJBQXlCLEVBQW1CLE1BQU0seUJBQXlCLENBQUM7QUFDckYsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ3pELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUVqRDsrRUFDK0U7QUFDL0UsTUFBTSxVQUFVLGtCQUFrQixDQUFDLEdBQVk7SUFDN0MsT0FBTyxhQUFhLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxjQUFjLENBQUMsQ0FBQztBQUNqRCxDQUFDO0FBRUQ7Ozs7O0dBS0c7QUFDSCxNQUFNLENBQUMsTUFBTSxnQkFBZ0IsR0FBRyxZQUFZLENBQUMsU0FBUyxnQkFBZ0IsQ0FBQyxHQUFZLEVBQUUsR0FBYSxFQUFFLElBQWtCO0lBQ3BILElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDZCxPQUFPLFNBQVMsQ0FBQyxHQUFHLEVBQUUsVUFBVSxDQUFDLFlBQVksRUFBRSx5QkFBeUIsRUFBRSxTQUFTLENBQUMsWUFBWSxDQUFDLENBQUM7SUFDcEcsQ0FBQztJQUNELElBQUksa0JBQWtCLENBQUMsR0FBRyxDQUFDO1FBQUUsT0FBTyxJQUFJLEVBQUUsQ0FBQztJQUMzQyxXQUFXLENBQUMsZ0NBQWdDLEVBQUUsRUFBRSxTQUFTLEVBQUUsR0FBRyxDQUFDLElBQUksQ0FBQyxhQUFhLElBQUksU0FBUyxFQUFFLENBQUMsQ0FBQztJQUNsRyxpQkFBaUIsQ0FBQyxHQUFHLEVBQUUsWUFBWSxDQUFDLENBQUM7SUFDckMsT0FBTyxTQUFTLENBQ2QsR0FBRyxFQUFFLFVBQVUsQ0FBQyxTQUFTLEVBQ3pCLG1HQUFtRyxFQUNuRyxTQUFTLENBQUMsbUJBQW1CLENBQzlCLENBQUM7QUFDSixDQUFDLEVBQUUsRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFFLENBQUMsQ0FBQztBQUUxQjs7Ozs7Ozs7Ozs7OztHQWFHO0FBQ0gsTUFBTSxVQUFVLDBCQUEwQixDQUFDLEdBQUcsV0FBeUI7SUFDckUsSUFBSSxXQUFXLENBQUMsTUFBTSxLQUFLLENBQUM7UUFBRSxNQUFNLElBQUksS0FBSyxDQUFDLDBEQUEwRCxDQUFDLENBQUM7SUFDMUcsTUFBTSxNQUFNLEdBQUcsV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3hFLElBQUksTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztRQUN0QixNQUFNLElBQUksS0FBSyxDQUFDLDBFQUEwRSxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUNqSCxDQUFDO0lBQ0QsT0FBTztRQUNMLGdCQUFnQjtRQUNoQixpQkFBaUIsQ0FBQyxHQUFHLFdBQVcsQ0FBQztRQUNqQyxnQkFBZ0IsQ0FBQyxFQUFFLFlBQVksRUFBRSxDQUFDLEVBQUUsQ0FBQztLQUNsQixDQUFDO0FBQ3hCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuLyoqXG4gKiBUaGUgcGx1Z2luLWVjb3N5c3RlbSBnb3Zlcm5hbmNlIGdhdGUgKGRvY3MvcnVuYm9va3MvZWNvc3lzdGVtLW1vZGVyYXRpb24ubWQpLlxuICpcbiAqIE9ubHkgdGhlIHN5c3RlbSBvcmcgbWFuYWdlcyBvciBhcHByb3ZlcyB0aGUgZWNvc3lzdGVtLiBBIHJvdXRlIHRoYXQgZXhlcmNpc2VzXG4gKiBhIHN5c3RlbS1vcmctb25seSBwZXJtaXNzaW9uIChgcGx1Z2luczptb2RlcmF0ZWAsIGBwdWJsaXNoZXJzOnZlcmlmeWApIG11c3RcbiAqIHRoZXJlZm9yZSBjaGVjayB0aHJlZSB0aGluZ3MsIGFuZCB7QGxpbmsgcmVxdWlyZVN5c3RlbU9yZ1Blcm1pc3Npb259IGNvbXBvc2VzXG4gKiB0aGVtIHNvIG5vIHJvdXRlIGNhbiBmb3JnZXQgb25lOlxuICpcbiAqICAxLiB7QGxpbmsgcmVxdWlyZVN5c3RlbU9yZ30g4oCUIHRoZSBjYWxsZXIncyBBQ1RJVkUgb3JnIGlzIHRoZSBzeXN0ZW0gb3JnLiBBXG4gKiAgICAgdG9rZW4gbWludGVkIGluIGEgdGVuYW50IG9yZyBpcyByZWZ1c2VkIGV2ZW4gZm9yIHRoZSBzYW1lIHBlcnNvbiAoYW5kIGV2ZW5cbiAqICAgICBmb3IgYSBzdXBlcmFkbWluOiB0aGV5IHN3aXRjaCB0byB0aGUgc3lzdGVtIG9yZyB0byBhY3Qgb24gdGhlIGVjb3N5c3RlbSxcbiAqICAgICBzbyBldmVyeSBnb3Zlcm5hbmNlIGRlY2lzaW9uIGlzIHJlY29yZGVkIHdpdGggdGhlIHN5c3RlbSBvcmcncyBpZCkuXG4gKiAgMi4gdGhlIHBlcm1pc3Npb24gaXRzZWxmIChgcmVxdWlyZVBlcm1pc3Npb25gLCBhbnktb2YpO1xuICogIDMuIGFuIE1GQS1ncmFkZSBzZXNzaW9uIChgcmVxdWlyZUFzc3VyYW5jZSh7IG1pbkFzc3VyYW5jZTogMiB9KWApLCB3aGljaCBhbHNvXG4gKiAgICAgcmVmdXNlcyBldmVyeSBtYWNoaW5lIGNyZWRlbnRpYWwuXG4gKlxuICogVGhlIHJvdXRlLWNvdmVyYWdlIGdvdmVybmFuY2UgY2hlY2sgKGBmaW5kU3lzdGVtT3JnR3VhcmRWaW9sYXRpb25zYCBpblxuICogYHRlc3Rpbmcvcm91dGUtY292ZXJhZ2UudHNgKSBmYWlscyBhbnkgcm91dGUgdGhhdCBnYXRlcyBvbiBhIHN5c3RlbS1vcmctb25seVxuICogcGVybWlzc2lvbiB3aXRob3V0IDEgYW5kIDMsIHNvIGEgaGFuZC1yb2xsZWQgY2hhaW4gY2Fubm90IHNsaXAgdGhyb3VnaC5cbiAqL1xuXG5pbXBvcnQgdHlwZSB7IE5leHRGdW5jdGlvbiwgUmVxdWVzdCwgUmVxdWVzdEhhbmRsZXIsIFJlc3BvbnNlIH0gZnJvbSAnZXhwcmVzcyc7XG5pbXBvcnQgeyByZXF1aXJlQXNzdXJhbmNlIH0gZnJvbSAnLi9hc3N1cmFuY2UuanMnO1xuaW1wb3J0IHsgcmVjb3JkQXV0aHpEZW5pYWwsIHJlcXVpcmVQZXJtaXNzaW9uIH0gZnJvbSAnLi9wZXJtaXNzaW9uLWdhdGVzLmpzJztcbmltcG9ydCB7IHRhZ1JvdXRlR2F0ZSB9IGZyb20gJy4vcm91dGUtdGFibGUuanMnO1xuaW1wb3J0IHsgaXNTeXN0ZW1PcmdJZCB9IGZyb20gJy4vc3lzdGVtLW9yZy5qcyc7XG5pbXBvcnQgeyBIdHRwU3RhdHVzIH0gZnJvbSAnLi4vY29uc3RhbnRzL2h0dHAtc3RhdHVzLmpzJztcbmltcG9ydCB7IEVycm9yQ29kZSB9IGZyb20gJy4uL3R5cGVzL2Vycm9yLWNvZGVzLmpzJztcbmltcG9ydCB7IGlzU3lzdGVtT3JnT25seVBlcm1pc3Npb24sIHR5cGUgUGVybWlzc2lvbiB9IGZyb20gJy4uL3R5cGVzL3Blcm1pc3Npb25zLmpzJztcbmltcG9ydCB7IGVtaXRDb3VudGVyIH0gZnJvbSAnLi4vdXRpbHMvbWV0cmljLWVtaXR0ZXIuanMnO1xuaW1wb3J0IHsgc2VuZEVycm9yIH0gZnJvbSAnLi4vdXRpbHMvcmVzcG9uc2UuanMnO1xuXG4vKiogV2hldGhlciB0aGUgcmVxdWVzdCdzIEFDVElWRSBvcmcgKHRoZSB0b2tlbidzIGBvcmdhbml6YXRpb25JZGApIGlzIHRoZSBzeXN0ZW1cbiAqICBvcmcuIENvbXBhcmVkIGJ5IGlkIG9ubHkg4oCUIGFuIG9yZyBtZXJlbHkgTkFNRUQgXCJzeXN0ZW1cIiBuZXZlciBxdWFsaWZpZXMuICovXG5leHBvcnQgZnVuY3Rpb24gaXNTeXN0ZW1PcmdSZXF1ZXN0KHJlcTogUmVxdWVzdCk6IGJvb2xlYW4ge1xuICByZXR1cm4gaXNTeXN0ZW1PcmdJZChyZXEudXNlcj8ub3JnYW5pemF0aW9uSWQpO1xufVxuXG4vKipcbiAqIFJlcXVpcmUgdGhhdCB0aGUgY2FsbGVyJ3MgYWN0aXZlIG9yZyBpcyB0aGUgc3lzdGVtIG9yZy4gQ29tcG9zZSBhZnRlclxuICogYHJlcXVpcmVBdXRoYC4gUmVmdXNhbHMgYXJlIDQwMyBgU1lTVEVNX09SR19SRVFVSVJFRGAsIGNvdW50ZWRcbiAqIChgc3lzdGVtX29yZ19ndWFyZF9yZWZ1c2VkX3RvdGFsYCkgYW5kIGF1ZGl0ZWQgdGhyb3VnaCB0aGUgc2hhcmVkXG4gKiBgYXV0aHouZGVuaWVkYCBzaW5rIChgcmVxdWlyZWQ6ICdzeXN0ZW0tb3JnJ2ApLlxuICovXG5leHBvcnQgY29uc3QgcmVxdWlyZVN5c3RlbU9yZyA9IHRhZ1JvdXRlR2F0ZShmdW5jdGlvbiByZXF1aXJlU3lzdGVtT3JnKHJlcTogUmVxdWVzdCwgcmVzOiBSZXNwb25zZSwgbmV4dDogTmV4dEZ1bmN0aW9uKTogdm9pZCB7XG4gIGlmICghcmVxLnVzZXIpIHtcbiAgICByZXR1cm4gc2VuZEVycm9yKHJlcywgSHR0cFN0YXR1cy5VTkFVVEhPUklaRUQsICdBdXRoZW50aWNhdGlvbiByZXF1aXJlZCcsIEVycm9yQ29kZS5VTkFVVEhPUklaRUQpO1xuICB9XG4gIGlmIChpc1N5c3RlbU9yZ1JlcXVlc3QocmVxKSkgcmV0dXJuIG5leHQoKTtcbiAgZW1pdENvdW50ZXIoJ3N5c3RlbV9vcmdfZ3VhcmRfcmVmdXNlZF90b3RhbCcsIHsgcHJpbmNpcGFsOiByZXEudXNlci5wcmluY2lwYWxUeXBlID8/ICd1bmtub3duJyB9KTtcbiAgcmVjb3JkQXV0aHpEZW5pYWwocmVxLCAnc3lzdGVtLW9yZycpO1xuICByZXR1cm4gc2VuZEVycm9yKFxuICAgIHJlcywgSHR0cFN0YXR1cy5GT1JCSURERU4sXG4gICAgJ1RoaXMgYWN0aW9uIGlzIHJlc2VydmVkIGZvciB0aGUgc3lzdGVtIG9yZ2FuaXphdGlvbiDigJQgc3dpdGNoIHRvIGl0IHRvIG1hbmFnZSB0aGUgcGx1Z2luIGVjb3N5c3RlbScsXG4gICAgRXJyb3JDb2RlLlNZU1RFTV9PUkdfUkVRVUlSRUQsXG4gICk7XG59LCB7IGtpbmQ6ICdzeXN0ZW1PcmcnIH0pO1xuXG4vKipcbiAqIFRIRSBnYXRlIGZvciBhbiBlY29zeXN0ZW0tZ292ZXJuYW5jZSByb3V0ZTogc3lzdGVtIG9yZyArIChhbnkgb2YpIHRoZSBnaXZlblxuICogc3lzdGVtLW9yZy1vbmx5IHBlcm1pc3Npb24ocykgKyBhbiBNRkEtZ3JhZGUgaHVtYW4gc2Vzc2lvbi4gUmV0dXJucyB0aGUgY2hhaW5cbiAqIGFzIGFuIGFycmF5LCB3aGljaCBFeHByZXNzIGZsYXR0ZW5zOlxuICpcbiAqIGBgYHRzXG4gKiByb3V0ZXIucG9zdCgnL3JlcXVlc3RzLzppZC9hcHByb3ZlJywgcmVxdWlyZUF1dGgsIHJlcXVpcmVTeXN0ZW1PcmdQZXJtaXNzaW9uKCdwbHVnaW5zOm1vZGVyYXRlJyksXG4gKiAgIHJlcXVpcmVTdGVwVXAsIGF1ZGl0ZWQoJ3BsdWdpbi5yZXF1ZXN0LmFwcHJvdmUnKSwgaGFuZGxlcik7XG4gKiBgYGBcbiAqXG4gKiBUaHJvd3MgYXQgcm91dGUtZGVmaW5pdGlvbiB0aW1lIHdoZW4gaGFuZGVkIGEgcGVybWlzc2lvbiB0aGF0IGlzIE5PVFxuICogc3lzdGVtLW9yZy1vbmx5IOKAlCBhIHRlbmFudCBwZXJtaXNzaW9uIGJlaGluZCB0aGlzIGdhdGUgd291bGQgYmUgdW5yZWFjaGFibGVcbiAqIGZvciBldmVyeSB0ZW5hbnQsIHdoaWNoIGlzIGFsd2F5cyBhIHdpcmluZyBtaXN0YWtlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVxdWlyZVN5c3RlbU9yZ1Blcm1pc3Npb24oLi4ucGVybWlzc2lvbnM6IFBlcm1pc3Npb25bXSk6IFJlcXVlc3RIYW5kbGVyW10ge1xuICBpZiAocGVybWlzc2lvbnMubGVuZ3RoID09PSAwKSB0aHJvdyBuZXcgRXJyb3IoJ3JlcXVpcmVTeXN0ZW1PcmdQZXJtaXNzaW9uIG5lZWRzIGF0IGxlYXN0IG9uZSBwZXJtaXNzaW9uJyk7XG4gIGNvbnN0IHRlbmFudCA9IHBlcm1pc3Npb25zLmZpbHRlcigocCkgPT4gIWlzU3lzdGVtT3JnT25seVBlcm1pc3Npb24ocCkpO1xuICBpZiAodGVuYW50Lmxlbmd0aCA+IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYHJlcXVpcmVTeXN0ZW1PcmdQZXJtaXNzaW9uIG9ubHkgdGFrZXMgc3lzdGVtLW9yZy1vbmx5IHBlcm1pc3Npb25zOyBnb3QgJHt0ZW5hbnQuam9pbignLCAnKX1gKTtcbiAgfVxuICByZXR1cm4gW1xuICAgIHJlcXVpcmVTeXN0ZW1PcmcsXG4gICAgcmVxdWlyZVBlcm1pc3Npb24oLi4ucGVybWlzc2lvbnMpLFxuICAgIHJlcXVpcmVBc3N1cmFuY2UoeyBtaW5Bc3N1cmFuY2U6IDIgfSksXG4gIF0gYXMgUmVxdWVzdEhhbmRsZXJbXTtcbn1cbiJdfQ==
@@ -5,8 +5,11 @@ export { requireAssurance, refuseWeakSession, refuseForOrgAdminAssurance, requir
5
5
  export { userHasPermission, setAuthzDenialAuditor, recordAuthzDenial, requirePermission, requireAllPermissions, requirePermissionOrService, requireServicePrincipal, requireInternalService, isSystemAdmin, hasScope, requireSystemAdmin, requireFeature, type AuthzDenialInfo, } from './permission-gates.js';
6
6
  export { isSystemOrgId, SYSTEM_ORG_ID, SYSTEM_ORG_SLUG, } from './system-org.js';
7
7
  export { serviceNameOf, isServiceTokenDenied, signServiceToken, getServiceAuthHeader, isServicePrincipal, isServiceAccountPrincipal, isServicePrincipalNamed, verifyServicePrincipal, } from './service-tokens.js';
8
- export { requireSystemOrg, requireEcosystemPermission } from './ecosystem-guard.js';
8
+ export { requireSystemOrg, requireSystemOrgPermission } from './ecosystem-guard.js';
9
9
  export { mongoSanitize, MAX_SANITIZE_DEPTH, } from './mongo-sanitize.js';
10
10
  export { proposable, ASK_PROVENANCE_REFUSED_COUNTER, } from './ask-provenance.js';
11
11
  export { requireStepUp, type StepUpMethod, STRONG_STEP_UP_METHODS, } from './step-up.js';
12
- export { tagRouteGate, getRouteGates, audited, buildRouteTable, isWriteMethod, summarizeRouteTable, type RouteTableEntry, } from './route-table.js';
12
+ export { tagRouteGate, getRouteGates, audited, dynamicAuthz, buildRouteTable, isWriteMethod, summarizeRouteTable, DYNAMIC_PRINCIPALS, type DynamicPrincipal, type RouteTableEntry, } from './route-table.js';
13
+ export { armDeferredQuotaCheck, runDeferredQuotaCheck, } from './deferred-quota-check.js';
14
+ export { ON_BEHALF_HEADER, ON_BEHALF_CALLERS, onBehalfHeaders, onBehalfCaller, type OnBehalfSubject, } from './on-behalf.js';
15
+ export { QUOTA_EXEMPT_ROUTES, isQuotaExemptRoute, type QuotaExemptRoute, } from './quota-exempt-routes.js';
@@ -7,9 +7,12 @@ export { requireAssurance, refuseWeakSession, refuseForOrgAdminAssurance, requir
7
7
  export { userHasPermission, setAuthzDenialAuditor, recordAuthzDenial, requirePermission, requireAllPermissions, requirePermissionOrService, requireServicePrincipal, requireInternalService, isSystemAdmin, hasScope, requireSystemAdmin, requireFeature, } from './permission-gates.js';
8
8
  export { isSystemOrgId, SYSTEM_ORG_ID, SYSTEM_ORG_SLUG, } from './system-org.js';
9
9
  export { serviceNameOf, isServiceTokenDenied, signServiceToken, getServiceAuthHeader, isServicePrincipal, isServiceAccountPrincipal, isServicePrincipalNamed, verifyServicePrincipal, } from './service-tokens.js';
10
- export { requireSystemOrg, requireEcosystemPermission } from './ecosystem-guard.js';
10
+ export { requireSystemOrg, requireSystemOrgPermission } from './ecosystem-guard.js';
11
11
  export { mongoSanitize, MAX_SANITIZE_DEPTH, } from './mongo-sanitize.js';
12
12
  export { proposable, ASK_PROVENANCE_REFUSED_COUNTER, } from './ask-provenance.js';
13
13
  export { requireStepUp, STRONG_STEP_UP_METHODS, } from './step-up.js';
14
- export { tagRouteGate, getRouteGates, audited, buildRouteTable, isWriteMethod, summarizeRouteTable, } from './route-table.js';
15
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbWlkZGxld2FyZS9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwrQ0FBK0M7QUFDL0Msc0NBQXNDO0FBRXRDLE9BQU8sRUFDTCxhQUFhLEVBQ2IsaUJBQWlCLEVBQ2pCLHNCQUFzQixHQUN2QixNQUFNLGlCQUFpQixDQUFDO0FBQ3pCLE9BQU8sRUFDTCxXQUFXLEdBQ1osTUFBTSxXQUFXLENBQUM7QUFDbkIsT0FBTyxFQUNMLHVCQUF1QixFQUN2QixvQkFBb0IsR0FDckIsTUFBTSxpQkFBaUIsQ0FBQztBQUN6QixPQUFPLEVBQ0wsZ0JBQWdCLEVBQ2hCLGlCQUFpQixFQUNqQiwwQkFBMEIsRUFDMUIsd0JBQXdCLEdBRXpCLE1BQU0sZ0JBQWdCLENBQUM7QUFDeEIsT0FBTyxFQUNMLGlCQUFpQixFQUNqQixxQkFBcUIsRUFDckIsaUJBQWlCLEVBQ2pCLGlCQUFpQixFQUNqQixxQkFBcUIsRUFDckIsMEJBQTBCLEVBQzFCLHVCQUF1QixFQUN2QixzQkFBc0IsRUFDdEIsYUFBYSxFQUNiLFFBQVEsRUFDUixrQkFBa0IsRUFDbEIsY0FBYyxHQUVmLE1BQU0sdUJBQXVCLENBQUM7QUFDL0IsT0FBTyxFQUNMLGFBQWEsRUFDYixhQUFhLEVBQ2IsZUFBZSxHQUNoQixNQUFNLGlCQUFpQixDQUFDO0FBQ3pCLE9BQU8sRUFDTCxhQUFhLEVBQ2Isb0JBQW9CLEVBQ3BCLGdCQUFnQixFQUNoQixvQkFBb0IsRUFDcEIsa0JBQWtCLEVBQ2xCLHlCQUF5QixFQUN6Qix1QkFBdUIsRUFDdkIsc0JBQXNCLEdBQ3ZCLE1BQU0scUJBQXFCLENBQUM7QUFDN0IsT0FBTyxFQUFFLGdCQUFnQixFQUFFLDBCQUEwQixFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDcEYsT0FBTyxFQUNMLGFBQWEsRUFDYixrQkFBa0IsR0FDbkIsTUFBTSxxQkFBcUIsQ0FBQztBQUM3QixPQUFPLEVBQ0wsVUFBVSxFQUNWLDhCQUE4QixHQUMvQixNQUFNLHFCQUFxQixDQUFDO0FBQzdCLE9BQU8sRUFDTCxhQUFhLEVBRWIsc0JBQXNCLEdBQ3ZCLE1BQU0sY0FBYyxDQUFDO0FBQ3RCLE9BQU8sRUFDTCxZQUFZLEVBQ1osYUFBYSxFQUNiLE9BQU8sRUFDUCxlQUFlLEVBQ2YsYUFBYSxFQUNiLG1CQUFtQixHQUVwQixNQUFNLGtCQUFrQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbmV4cG9ydCB7XG4gIHZlcmlmeVVzZXJKd3QsXG4gIHZlcmlmeUJlYXJlclRva2VuLFxuICBoYXNWYWxpZElkZW50aXR5Q2xhaW1zLFxufSBmcm9tICcuL2p3dC12ZXJpZnkuanMnO1xuZXhwb3J0IHtcbiAgcmVxdWlyZUF1dGgsXG59IGZyb20gJy4vYXV0aC5qcyc7XG5leHBvcnQge1xuICBzZXRUb2tlblJldm9jYXRpb25TdG9yZSxcbiAgaXNBY2Nlc3NUb2tlblJldm9rZWQsXG59IGZyb20gJy4vcmV2b2NhdGlvbi5qcyc7XG5leHBvcnQge1xuICByZXF1aXJlQXNzdXJhbmNlLFxuICByZWZ1c2VXZWFrU2Vzc2lvbixcbiAgcmVmdXNlRm9yT3JnQWRtaW5Bc3N1cmFuY2UsXG4gIHJlcXVpcmVPcmdBZG1pbkFzc3VyYW5jZSxcbiAgdHlwZSBBc3N1cmFuY2VPcHRpb25zLFxufSBmcm9tICcuL2Fzc3VyYW5jZS5qcyc7XG5leHBvcnQge1xuICB1c2VySGFzUGVybWlzc2lvbixcbiAgc2V0QXV0aHpEZW5pYWxBdWRpdG9yLFxuICByZWNvcmRBdXRoekRlbmlhbCxcbiAgcmVxdWlyZVBlcm1pc3Npb24sXG4gIHJlcXVpcmVBbGxQZXJtaXNzaW9ucyxcbiAgcmVxdWlyZVBlcm1pc3Npb25PclNlcnZpY2UsXG4gIHJlcXVpcmVTZXJ2aWNlUHJpbmNpcGFsLFxuICByZXF1aXJlSW50ZXJuYWxTZXJ2aWNlLFxuICBpc1N5c3RlbUFkbWluLFxuICBoYXNTY29wZSxcbiAgcmVxdWlyZVN5c3RlbUFkbWluLFxuICByZXF1aXJlRmVhdHVyZSxcbiAgdHlwZSBBdXRoekRlbmlhbEluZm8sXG59IGZyb20gJy4vcGVybWlzc2lvbi1nYXRlcy5qcyc7XG5leHBvcnQge1xuICBpc1N5c3RlbU9yZ0lkLFxuICBTWVNURU1fT1JHX0lELFxuICBTWVNURU1fT1JHX1NMVUcsXG59IGZyb20gJy4vc3lzdGVtLW9yZy5qcyc7XG5leHBvcnQge1xuICBzZXJ2aWNlTmFtZU9mLFxuICBpc1NlcnZpY2VUb2tlbkRlbmllZCxcbiAgc2lnblNlcnZpY2VUb2tlbixcbiAgZ2V0U2VydmljZUF1dGhIZWFkZXIsXG4gIGlzU2VydmljZVByaW5jaXBhbCxcbiAgaXNTZXJ2aWNlQWNjb3VudFByaW5jaXBhbCxcbiAgaXNTZXJ2aWNlUHJpbmNpcGFsTmFtZWQsXG4gIHZlcmlmeVNlcnZpY2VQcmluY2lwYWwsXG59IGZyb20gJy4vc2VydmljZS10b2tlbnMuanMnO1xuZXhwb3J0IHsgcmVxdWlyZVN5c3RlbU9yZywgcmVxdWlyZUVjb3N5c3RlbVBlcm1pc3Npb24gfSBmcm9tICcuL2Vjb3N5c3RlbS1ndWFyZC5qcyc7XG5leHBvcnQge1xuICBtb25nb1Nhbml0aXplLFxuICBNQVhfU0FOSVRJWkVfREVQVEgsXG59IGZyb20gJy4vbW9uZ28tc2FuaXRpemUuanMnO1xuZXhwb3J0IHtcbiAgcHJvcG9zYWJsZSxcbiAgQVNLX1BST1ZFTkFOQ0VfUkVGVVNFRF9DT1VOVEVSLFxufSBmcm9tICcuL2Fzay1wcm92ZW5hbmNlLmpzJztcbmV4cG9ydCB7XG4gIHJlcXVpcmVTdGVwVXAsXG4gIHR5cGUgU3RlcFVwTWV0aG9kLFxuICBTVFJPTkdfU1RFUF9VUF9NRVRIT0RTLFxufSBmcm9tICcuL3N0ZXAtdXAuanMnO1xuZXhwb3J0IHtcbiAgdGFnUm91dGVHYXRlLFxuICBnZXRSb3V0ZUdhdGVzLFxuICBhdWRpdGVkLFxuICBidWlsZFJvdXRlVGFibGUsXG4gIGlzV3JpdGVNZXRob2QsXG4gIHN1bW1hcml6ZVJvdXRlVGFibGUsXG4gIHR5cGUgUm91dGVUYWJsZUVudHJ5LFxufSBmcm9tICcuL3JvdXRlLXRhYmxlLmpzJztcbiJdfQ==
14
+ export { tagRouteGate, getRouteGates, audited, dynamicAuthz, buildRouteTable, isWriteMethod, summarizeRouteTable, DYNAMIC_PRINCIPALS, } from './route-table.js';
15
+ export { armDeferredQuotaCheck, runDeferredQuotaCheck, } from './deferred-quota-check.js';
16
+ export { ON_BEHALF_HEADER, ON_BEHALF_CALLERS, onBehalfHeaders, onBehalfCaller, } from './on-behalf.js';
17
+ export { QUOTA_EXEMPT_ROUTES, isQuotaExemptRoute, } from './quota-exempt-routes.js';
18
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbWlkZGxld2FyZS9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwrQ0FBK0M7QUFDL0Msc0NBQXNDO0FBRXRDLE9BQU8sRUFDTCxhQUFhLEVBQ2IsaUJBQWlCLEVBQ2pCLHNCQUFzQixHQUN2QixNQUFNLGlCQUFpQixDQUFDO0FBQ3pCLE9BQU8sRUFDTCxXQUFXLEdBQ1osTUFBTSxXQUFXLENBQUM7QUFDbkIsT0FBTyxFQUNMLHVCQUF1QixFQUN2QixvQkFBb0IsR0FDckIsTUFBTSxpQkFBaUIsQ0FBQztBQUN6QixPQUFPLEVBQ0wsZ0JBQWdCLEVBQ2hCLGlCQUFpQixFQUNqQiwwQkFBMEIsRUFDMUIsd0JBQXdCLEdBRXpCLE1BQU0sZ0JBQWdCLENBQUM7QUFDeEIsT0FBTyxFQUNMLGlCQUFpQixFQUNqQixxQkFBcUIsRUFDckIsaUJBQWlCLEVBQ2pCLGlCQUFpQixFQUNqQixxQkFBcUIsRUFDckIsMEJBQTBCLEVBQzFCLHVCQUF1QixFQUN2QixzQkFBc0IsRUFDdEIsYUFBYSxFQUNiLFFBQVEsRUFDUixrQkFBa0IsRUFDbEIsY0FBYyxHQUVmLE1BQU0sdUJBQXVCLENBQUM7QUFDL0IsT0FBTyxFQUNMLGFBQWEsRUFDYixhQUFhLEVBQ2IsZUFBZSxHQUNoQixNQUFNLGlCQUFpQixDQUFDO0FBQ3pCLE9BQU8sRUFDTCxhQUFhLEVBQ2Isb0JBQW9CLEVBQ3BCLGdCQUFnQixFQUNoQixvQkFBb0IsRUFDcEIsa0JBQWtCLEVBQ2xCLHlCQUF5QixFQUN6Qix1QkFBdUIsRUFDdkIsc0JBQXNCLEdBQ3ZCLE1BQU0scUJBQXFCLENBQUM7QUFDN0IsT0FBTyxFQUFFLGdCQUFnQixFQUFFLDBCQUEwQixFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDcEYsT0FBTyxFQUNMLGFBQWEsRUFDYixrQkFBa0IsR0FDbkIsTUFBTSxxQkFBcUIsQ0FBQztBQUM3QixPQUFPLEVBQ0wsVUFBVSxFQUNWLDhCQUE4QixHQUMvQixNQUFNLHFCQUFxQixDQUFDO0FBQzdCLE9BQU8sRUFDTCxhQUFhLEVBRWIsc0JBQXNCLEdBQ3ZCLE1BQU0sY0FBYyxDQUFDO0FBQ3RCLE9BQU8sRUFDTCxZQUFZLEVBQ1osYUFBYSxFQUNiLE9BQU8sRUFDUCxZQUFZLEVBQ1osZUFBZSxFQUNmLGFBQWEsRUFDYixtQkFBbUIsRUFDbkIsa0JBQWtCLEdBR25CLE1BQU0sa0JBQWtCLENBQUM7QUFDMUIsT0FBTyxFQUNMLHFCQUFxQixFQUNyQixxQkFBcUIsR0FDdEIsTUFBTSwyQkFBMkIsQ0FBQztBQUNuQyxPQUFPLEVBQ0wsZ0JBQWdCLEVBQ2hCLGlCQUFpQixFQUNqQixlQUFlLEVBQ2YsY0FBYyxHQUVmLE1BQU0sZ0JBQWdCLENBQUM7QUFDeEIsT0FBTyxFQUNMLG1CQUFtQixFQUNuQixrQkFBa0IsR0FFbkIsTUFBTSwwQkFBMEIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDI2IFBpcGVsaW5lIEJ1aWxkZXIgQ29udHJpYnV0b3JzXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuXG5leHBvcnQge1xuICB2ZXJpZnlVc2VySnd0LFxuICB2ZXJpZnlCZWFyZXJUb2tlbixcbiAgaGFzVmFsaWRJZGVudGl0eUNsYWltcyxcbn0gZnJvbSAnLi9qd3QtdmVyaWZ5LmpzJztcbmV4cG9ydCB7XG4gIHJlcXVpcmVBdXRoLFxufSBmcm9tICcuL2F1dGguanMnO1xuZXhwb3J0IHtcbiAgc2V0VG9rZW5SZXZvY2F0aW9uU3RvcmUsXG4gIGlzQWNjZXNzVG9rZW5SZXZva2VkLFxufSBmcm9tICcuL3Jldm9jYXRpb24uanMnO1xuZXhwb3J0IHtcbiAgcmVxdWlyZUFzc3VyYW5jZSxcbiAgcmVmdXNlV2Vha1Nlc3Npb24sXG4gIHJlZnVzZUZvck9yZ0FkbWluQXNzdXJhbmNlLFxuICByZXF1aXJlT3JnQWRtaW5Bc3N1cmFuY2UsXG4gIHR5cGUgQXNzdXJhbmNlT3B0aW9ucyxcbn0gZnJvbSAnLi9hc3N1cmFuY2UuanMnO1xuZXhwb3J0IHtcbiAgdXNlckhhc1Blcm1pc3Npb24sXG4gIHNldEF1dGh6RGVuaWFsQXVkaXRvcixcbiAgcmVjb3JkQXV0aHpEZW5pYWwsXG4gIHJlcXVpcmVQZXJtaXNzaW9uLFxuICByZXF1aXJlQWxsUGVybWlzc2lvbnMsXG4gIHJlcXVpcmVQZXJtaXNzaW9uT3JTZXJ2aWNlLFxuICByZXF1aXJlU2VydmljZVByaW5jaXBhbCxcbiAgcmVxdWlyZUludGVybmFsU2VydmljZSxcbiAgaXNTeXN0ZW1BZG1pbixcbiAgaGFzU2NvcGUsXG4gIHJlcXVpcmVTeXN0ZW1BZG1pbixcbiAgcmVxdWlyZUZlYXR1cmUsXG4gIHR5cGUgQXV0aHpEZW5pYWxJbmZvLFxufSBmcm9tICcuL3Blcm1pc3Npb24tZ2F0ZXMuanMnO1xuZXhwb3J0IHtcbiAgaXNTeXN0ZW1PcmdJZCxcbiAgU1lTVEVNX09SR19JRCxcbiAgU1lTVEVNX09SR19TTFVHLFxufSBmcm9tICcuL3N5c3RlbS1vcmcuanMnO1xuZXhwb3J0IHtcbiAgc2VydmljZU5hbWVPZixcbiAgaXNTZXJ2aWNlVG9rZW5EZW5pZWQsXG4gIHNpZ25TZXJ2aWNlVG9rZW4sXG4gIGdldFNlcnZpY2VBdXRoSGVhZGVyLFxuICBpc1NlcnZpY2VQcmluY2lwYWwsXG4gIGlzU2VydmljZUFjY291bnRQcmluY2lwYWwsXG4gIGlzU2VydmljZVByaW5jaXBhbE5hbWVkLFxuICB2ZXJpZnlTZXJ2aWNlUHJpbmNpcGFsLFxufSBmcm9tICcuL3NlcnZpY2UtdG9rZW5zLmpzJztcbmV4cG9ydCB7IHJlcXVpcmVTeXN0ZW1PcmcsIHJlcXVpcmVTeXN0ZW1PcmdQZXJtaXNzaW9uIH0gZnJvbSAnLi9lY29zeXN0ZW0tZ3VhcmQuanMnO1xuZXhwb3J0IHtcbiAgbW9uZ29TYW5pdGl6ZSxcbiAgTUFYX1NBTklUSVpFX0RFUFRILFxufSBmcm9tICcuL21vbmdvLXNhbml0aXplLmpzJztcbmV4cG9ydCB7XG4gIHByb3Bvc2FibGUsXG4gIEFTS19QUk9WRU5BTkNFX1JFRlVTRURfQ09VTlRFUixcbn0gZnJvbSAnLi9hc2stcHJvdmVuYW5jZS5qcyc7XG5leHBvcnQge1xuICByZXF1aXJlU3RlcFVwLFxuICB0eXBlIFN0ZXBVcE1ldGhvZCxcbiAgU1RST05HX1NURVBfVVBfTUVUSE9EUyxcbn0gZnJvbSAnLi9zdGVwLXVwLmpzJztcbmV4cG9ydCB7XG4gIHRhZ1JvdXRlR2F0ZSxcbiAgZ2V0Um91dGVHYXRlcyxcbiAgYXVkaXRlZCxcbiAgZHluYW1pY0F1dGh6LFxuICBidWlsZFJvdXRlVGFibGUsXG4gIGlzV3JpdGVNZXRob2QsXG4gIHN1bW1hcml6ZVJvdXRlVGFibGUsXG4gIERZTkFNSUNfUFJJTkNJUEFMUyxcbiAgdHlwZSBEeW5hbWljUHJpbmNpcGFsLFxuICB0eXBlIFJvdXRlVGFibGVFbnRyeSxcbn0gZnJvbSAnLi9yb3V0ZS10YWJsZS5qcyc7XG5leHBvcnQge1xuICBhcm1EZWZlcnJlZFF1b3RhQ2hlY2ssXG4gIHJ1bkRlZmVycmVkUXVvdGFDaGVjayxcbn0gZnJvbSAnLi9kZWZlcnJlZC1xdW90YS1jaGVjay5qcyc7XG5leHBvcnQge1xuICBPTl9CRUhBTEZfSEVBREVSLFxuICBPTl9CRUhBTEZfQ0FMTEVSUyxcbiAgb25CZWhhbGZIZWFkZXJzLFxuICBvbkJlaGFsZkNhbGxlcixcbiAgdHlwZSBPbkJlaGFsZlN1YmplY3QsXG59IGZyb20gJy4vb24tYmVoYWxmLmpzJztcbmV4cG9ydCB7XG4gIFFVT1RBX0VYRU1QVF9ST1VURVMsXG4gIGlzUXVvdGFFeGVtcHRSb3V0ZSxcbiAgdHlwZSBRdW90YUV4ZW1wdFJvdXRlLFxufSBmcm9tICcuL3F1b3RhLWV4ZW1wdC1yb3V0ZXMuanMnO1xuIl19
@@ -0,0 +1,37 @@
1
+ import type { Request } from 'express';
2
+ /** The header carrying the signed on-behalf marker (lower-case, as Node reads it). */
3
+ export declare const ON_BEHALF_HEADER = "x-pb-on-behalf";
4
+ /**
5
+ * Services whose on-behalf marker is honoured: the ones that forward a user's
6
+ * token as a matter of design. A marker signed by any other service — valid
7
+ * signature or not — is ignored, so a compromised peer that never forwards user
8
+ * tokens cannot start waiving its tenants' meters.
9
+ */
10
+ export declare const ON_BEHALF_CALLERS: readonly string[];
11
+ /** Who a marker vouches for. Defaults to the ambient request's verified principal. */
12
+ export interface OnBehalfSubject {
13
+ /** The user (`sub`) whose token rides the same request. */
14
+ sub: string;
15
+ /** Their active org. */
16
+ organizationId: string;
17
+ }
18
+ /**
19
+ * Headers to add beside a forwarded user `Authorization` so the peer does not
20
+ * bill the hop a second time. Mint per call (the marker expires in 120 s).
21
+ *
22
+ * The subject defaults to the ambient audit context's VERIFIED principal (the
23
+ * inbound request this call serves). Returns `{}` — the hop is billed normally,
24
+ * the safe direction — when there is no user principal to vouch for, or when
25
+ * this process cannot sign (no service key).
26
+ */
27
+ export declare function onBehalfHeaders(subject?: OnBehalfSubject): Record<string, string>;
28
+ /**
29
+ * The internal service that vouched for this request with a VALID on-behalf
30
+ * marker, else `undefined`. Requires the request to be authenticated (`req.user`
31
+ * set by requireAuth) — the marker is only meaningful against a verified user.
32
+ *
33
+ * Every rejection of a PRESENT header is counted on
34
+ * `quota_on_behalf_rejected_total{reason}`: a forged header from a user lands
35
+ * there as `invalid` (no service key signs it), and the request is billed.
36
+ */
37
+ export declare function onBehalfCaller(req: Request): string | undefined;
@@ -0,0 +1,143 @@
1
+ // Copyright 2026 Pipeline Builder Contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ /**
4
+ * ON-BEHALF calls: a service forwarding the end user's own bearer token to a
5
+ * peer, as part of a request that was ALREADY metered where it arrived.
6
+ *
7
+ * The ask agent acts strictly as the calling user — its tools forward the
8
+ * user's token so the peer's tenancy, permission and compliance gates apply as
9
+ * if the user had called them — and pipeline's confirm-placeholder-plugins does
10
+ * the same against the plugin service. Each of those hops is a USER request to
11
+ * the peer, so the peer's `apiCalls` meter billed it: one agent turn was 10-20
12
+ * apiCalls on top of the turn itself (which is metered, and AI-reserved).
13
+ *
14
+ * The marker that waives that second charge has to be something the USER CANNOT
15
+ * PRODUCE, or any member could stop paying for API calls by setting a header.
16
+ * So it is a SIGNED SERVICE TOKEN (the calling service's own ES256 key, the same
17
+ * key material `requireAuth` trusts for service principals), carried in
18
+ * {@link ON_BEHALF_HEADER} beside the user's untouched `Authorization`:
19
+ *
20
+ * - `type: 'on_behalf'` — never `access`, so the marker is useless as a bearer
21
+ * token anywhere (`requireAuth` and `verifyServicePrincipal` both demand
22
+ * `type: 'access'`);
23
+ * - `obo` + `organizationId` — BOUND to the user and org it vouches for, and
24
+ * honoured only when both equal the request's verified `req.user`;
25
+ * - the signer must be on {@link ON_BEHALF_CALLERS} — a service that forwards
26
+ * user tokens by design — and not on the service-token denylist;
27
+ * - 120 s TTL, minted per outbound call.
28
+ *
29
+ * What a valid marker changes is narrow: the apiCalls/automationCalls METER and
30
+ * CHECK skip the request (`callQuotaExemption`). Tenancy, permissions, audit and
31
+ * every reservation-gated quota (aiCalls, pipelines, plugins) apply exactly as
32
+ * before — an on-behalf `/generate` still reserves its own aiCalls slot.
33
+ */
34
+ import { randomUUID } from 'crypto';
35
+ import { issuerAudienceOptions } from './jwt-verify.js';
36
+ import { isServiceTokenDenied, serviceNameOf } from './service-tokens.js';
37
+ import { currentAuditContext } from '../services/audit-context.js';
38
+ import { isServiceKid, signServiceJwt, verifyServiceJwt } from '../services/service-keys.js';
39
+ import { decodeJwtHeader } from '../utils/jwk.js';
40
+ import { createLogger } from '../utils/logger.js';
41
+ import { emitCounter } from '../utils/metric-emitter.js';
42
+ const logger = createLogger('on-behalf');
43
+ /** The header carrying the signed on-behalf marker (lower-case, as Node reads it). */
44
+ export const ON_BEHALF_HEADER = 'x-pb-on-behalf';
45
+ /**
46
+ * Services whose on-behalf marker is honoured: the ones that forward a user's
47
+ * token as a matter of design. A marker signed by any other service — valid
48
+ * signature or not — is ignored, so a compromised peer that never forwards user
49
+ * tokens cannot start waiving its tenants' meters.
50
+ */
51
+ export const ON_BEHALF_CALLERS = ['ask', 'pipeline'];
52
+ /** Marker lifetime. Minted per outbound call, so it only has to outlive one hop. */
53
+ const ON_BEHALF_TTL_SECONDS = 120;
54
+ /** The `type` claim that makes the marker unusable as an access token. */
55
+ const ON_BEHALF_TOKEN_TYPE = 'on_behalf';
56
+ /**
57
+ * Headers to add beside a forwarded user `Authorization` so the peer does not
58
+ * bill the hop a second time. Mint per call (the marker expires in 120 s).
59
+ *
60
+ * The subject defaults to the ambient audit context's VERIFIED principal (the
61
+ * inbound request this call serves). Returns `{}` — the hop is billed normally,
62
+ * the safe direction — when there is no user principal to vouch for, or when
63
+ * this process cannot sign (no service key).
64
+ */
65
+ export function onBehalfHeaders(subject) {
66
+ const principal = subject ?? ambientSubject();
67
+ if (!principal)
68
+ return {};
69
+ try {
70
+ const token = signServiceJwt({
71
+ type: ON_BEHALF_TOKEN_TYPE,
72
+ principalType: 'service',
73
+ obo: principal.sub,
74
+ organizationId: principal.organizationId,
75
+ jti: randomUUID(),
76
+ }, { serviceName: process.env.SERVICE_NAME || 'api', expiresInSeconds: ON_BEHALF_TTL_SECONDS, ...issuerAudienceOptions() });
77
+ return { [ON_BEHALF_HEADER]: token };
78
+ }
79
+ catch (err) {
80
+ logger.debug('On-behalf marker not minted; the peer will meter the hop', { error: String(err) });
81
+ return {};
82
+ }
83
+ }
84
+ function ambientSubject() {
85
+ const user = currentAuditContext()?.principal?.();
86
+ if (!user || user.principalType === 'service' || !user.sub || !user.organizationId)
87
+ return undefined;
88
+ return { sub: user.sub, organizationId: user.organizationId };
89
+ }
90
+ /** Memo per request: the meter (on `finish`) and the check (in requireAuth) both ask. */
91
+ const verdicts = new WeakMap();
92
+ /**
93
+ * The internal service that vouched for this request with a VALID on-behalf
94
+ * marker, else `undefined`. Requires the request to be authenticated (`req.user`
95
+ * set by requireAuth) — the marker is only meaningful against a verified user.
96
+ *
97
+ * Every rejection of a PRESENT header is counted on
98
+ * `quota_on_behalf_rejected_total{reason}`: a forged header from a user lands
99
+ * there as `invalid` (no service key signs it), and the request is billed.
100
+ */
101
+ export function onBehalfCaller(req) {
102
+ const memo = verdicts.get(req);
103
+ if (memo !== undefined)
104
+ return memo ?? undefined;
105
+ const verdict = verifyMarker(req);
106
+ verdicts.set(req, verdict);
107
+ return verdict ?? undefined;
108
+ }
109
+ function verifyMarker(req) {
110
+ const raw = req.headers?.[ON_BEHALF_HEADER];
111
+ const token = Array.isArray(raw) ? raw[0] : raw;
112
+ if (!token)
113
+ return null;
114
+ const reject = (reason) => {
115
+ emitCounter('quota_on_behalf_rejected_total', { reason });
116
+ return null;
117
+ };
118
+ const user = req.user;
119
+ if (!user?.sub || !user.organizationId)
120
+ return reject('unauthenticated');
121
+ try {
122
+ const header = decodeJwtHeader(token);
123
+ if (!header?.kid || !isServiceKid(header.kid))
124
+ return reject('invalid');
125
+ const claims = verifyServiceJwt(token, { kid: header.kid, ...issuerAudienceOptions() });
126
+ if (claims.type !== ON_BEHALF_TOKEN_TYPE || claims.principalType !== 'service')
127
+ return reject('invalid');
128
+ const caller = serviceNameOf(claims);
129
+ if (!caller || isServiceTokenDenied(claims))
130
+ return reject('denied');
131
+ if (!ON_BEHALF_CALLERS.includes(caller))
132
+ return reject('caller');
133
+ if (claims.obo !== user.sub)
134
+ return reject('subject');
135
+ if (String(claims.organizationId ?? '').toLowerCase() !== user.organizationId.toLowerCase())
136
+ return reject('org');
137
+ return caller;
138
+ }
139
+ catch {
140
+ return reject('invalid');
141
+ }
142
+ }
143
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib24tYmVoYWxmLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL21pZGRsZXdhcmUvb24tYmVoYWxmLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFFdEM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQThCRztBQUVILE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxRQUFRLENBQUM7QUFFcEMsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDeEQsT0FBTyxFQUFFLG9CQUFvQixFQUFFLGFBQWEsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQzFFLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQ25FLE9BQU8sRUFBRSxZQUFZLEVBQUUsY0FBYyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDN0YsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ2xELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNsRCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFFekQsTUFBTSxNQUFNLEdBQUcsWUFBWSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0FBRXpDLHNGQUFzRjtBQUN0RixNQUFNLENBQUMsTUFBTSxnQkFBZ0IsR0FBRyxnQkFBZ0IsQ0FBQztBQUVqRDs7Ozs7R0FLRztBQUNILE1BQU0sQ0FBQyxNQUFNLGlCQUFpQixHQUFzQixDQUFDLEtBQUssRUFBRSxVQUFVLENBQUMsQ0FBQztBQUV4RSxvRkFBb0Y7QUFDcEYsTUFBTSxxQkFBcUIsR0FBRyxHQUFHLENBQUM7QUFFbEMsMEVBQTBFO0FBQzFFLE1BQU0sb0JBQW9CLEdBQUcsV0FBVyxDQUFDO0FBVXpDOzs7Ozs7OztHQVFHO0FBQ0gsTUFBTSxVQUFVLGVBQWUsQ0FBQyxPQUF5QjtJQUN2RCxNQUFN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ZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuLyoqXG4gKiBPTi1CRUhBTEYgY2FsbHM6IGEgc2VydmljZSBmb3J3YXJkaW5nIHRoZSBlbmQgdXNlcidzIG93biBiZWFyZXIgdG9rZW4gdG8gYVxuICogcGVlciwgYXMgcGFydCBvZiBhIHJlcXVlc3QgdGhhdCB3YXMgQUxSRUFEWSBtZXRlcmVkIHdoZXJlIGl0IGFycml2ZWQuXG4gKlxuICogVGhlIGFzayBhZ2VudCBhY3RzIHN0cmljdGx5IGFzIHRoZSBjYWxsaW5nIHVzZXIg4oCUIGl0cyB0b29scyBmb3J3YXJkIHRoZVxuICogdXNlcidzIHRva2VuIHNvIHRoZSBwZWVyJ3MgdGVuYW5jeSwgcGVybWlzc2lvbiBhbmQgY29tcGxpYW5jZSBnYXRlcyBhcHBseSBhc1xuICogaWYgdGhlIHVzZXIgaGFkIGNhbGxlZCB0aGVtIOKAlCBhbmQgcGlwZWxpbmUncyBjb25maXJtLXBsYWNlaG9sZGVyLXBsdWdpbnMgZG9lc1xuICogdGhlIHNhbWUgYWdhaW5zdCB0aGUgcGx1Z2luIHNlcnZpY2UuIEVhY2ggb2YgdGhvc2UgaG9wcyBpcyBhIFVTRVIgcmVxdWVzdCB0b1xuICogdGhlIHBlZXIsIHNvIHRoZSBwZWVyJ3MgYGFwaUNhbGxzYCBtZXRlciBiaWxsZWQgaXQ6IG9uZSBhZ2VudCB0dXJuIHdhcyAxMC0yMFxuICogYXBpQ2FsbHMgb24gdG9wIG9mIHRoZSB0dXJuIGl0c2VsZiAod2hpY2ggaXMgbWV0ZXJlZCwgYW5kIEFJLXJlc2VydmVkKS5cbiAqXG4gKiBUaGUgbWFya2VyIHRoYXQgd2FpdmVzIHRoYXQgc2Vjb25kIGNoYXJnZSBoYXMgdG8gYmUgc29tZXRoaW5nIHRoZSBVU0VSIENBTk5PVFxuICogUFJPRFVDRSwgb3IgYW55IG1lbWJlciBjb3VsZCBzdG9wIHBheWluZyBmb3IgQVBJIGNhbGxzIGJ5IHNldHRpbmcgYSBoZWFkZXIuXG4gKiBTbyBpdCBpcyBhIFNJR05FRCBTRVJWSUNFIFRPS0VOICh0aGUgY2FsbGluZyBzZXJ2aWNlJ3Mgb3duIEVTMjU2IGtleSwgdGhlIHNhbWVcbiAqIGtleSBtYXRlcmlhbCBgcmVxdWlyZUF1dGhgIHRydXN0cyBmb3Igc2VydmljZSBwcmluY2lwYWxzKSwgY2FycmllZCBpblxuICoge0BsaW5rIE9OX0JFSEFMRl9IRUFERVJ9IGJlc2lkZSB0aGUgdXNlcidzIHVudG91Y2hlZCBgQXV0aG9yaXphdGlvbmA6XG4gKlxuICogIC0gYHR5cGU6ICdvbl9iZWhhbGYnYCDigJQgbmV2ZXIgYGFjY2Vzc2AsIHNvIHRoZSBtYXJrZXIgaXMgdXNlbGVzcyBhcyBhIGJlYXJlclxuICogICAgdG9rZW4gYW55d2hlcmUgKGByZXF1aXJlQXV0aGAgYW5kIGB2ZXJpZnlTZXJ2aWNlUHJpbmNpcGFsYCBib3RoIGRlbWFuZFxuICogICAgYHR5cGU6ICdhY2Nlc3MnYCk7XG4gKiAgLSBgb2JvYCArIGBvcmdhbml6YXRpb25JZGAg4oCUIEJPVU5EIHRvIHRoZSB1c2VyIGFuZCBvcmcgaXQgdm91Y2hlcyBmb3IsIGFuZFxuICogICAgaG9ub3VyZWQgb25seSB3aGVuIGJvdGggZXF1YWwgdGhlIHJlcXVlc3QncyB2ZXJpZmllZCBgcmVxLnVzZXJgO1xuICogIC0gdGhlIHNpZ25lciBtdXN0IGJlIG9uIHtAbGluayBPTl9CRUhBTEZfQ0FMTEVSU30g4oCUIGEgc2VydmljZSB0aGF0IGZvcndhcmRzXG4gKiAgICB1c2VyIHRva2VucyBieSBkZXNpZ24g4oCUIGFuZCBub3Qgb24gdGhlIHNlcnZpY2UtdG9rZW4gZGVueWxpc3Q7XG4gKiAgLSAxMjAgcyBUVEwsIG1pbnRlZCBwZXIgb3V0Ym91bmQgY2FsbC5cbiAqXG4gKiBXaGF0IGEgdmFsaWQgbWFya2VyIGNoYW5nZXMgaXMgbmFycm93OiB0aGUgYXBpQ2FsbHMvYXV0b21hdGlvbkNhbGxzIE1FVEVSIGFuZFxuICogQ0hFQ0sgc2tpcCB0aGUgcmVxdWVzdCAoYGNhbGxRdW90YUV4ZW1wdGlvbmApLiBUZW5hbmN5LCBwZXJtaXNzaW9ucywgYXVkaXQgYW5kXG4gKiBldmVyeSByZXNlcnZhdGlvbi1nYXRlZCBxdW90YSAoYWlDYWxscywgcGlwZWxpbmVzLCBwbHVnaW5zKSBhcHBseSBleGFjdGx5IGFzXG4gKiBiZWZvcmUg4oCUIGFuIG9uLWJlaGFsZiBgL2dlbmVyYXRlYCBzdGlsbCByZXNlcnZlcyBpdHMgb3duIGFpQ2FsbHMgc2xvdC5cbiAqL1xuXG5pbXBvcnQgeyByYW5kb21VVUlEIH0gZnJvbSAnY3J5cHRvJztcbmltcG9ydCB0eXBlIHsgUmVxdWVzdCB9IGZyb20gJ2V4cHJlc3MnO1xuaW1wb3J0IHsgaXNzdWVyQXVkaWVuY2VPcHRpb25zIH0gZnJvbSAnLi9qd3QtdmVyaWZ5LmpzJztcbmltcG9ydCB7IGlzU2VydmljZVRva2VuRGVuaWVkLCBzZXJ2aWNlTmFtZU9mIH0gZnJvbSAnLi9zZXJ2aWNlLXRva2Vucy5qcyc7XG5pbXBvcnQgeyBjdXJyZW50QXVkaXRDb250ZXh0IH0gZnJvbSAnLi4vc2VydmljZXMvYXVkaXQtY29udGV4dC5qcyc7XG5pbXBvcnQgeyBpc1NlcnZpY2VLaWQsIHNpZ25TZXJ2aWNlSnd0LCB2ZXJpZnlTZXJ2aWNlSnd0IH0gZnJvbSAnLi4vc2VydmljZXMvc2VydmljZS1rZXlzLmpzJztcbmltcG9ydCB7IGRlY29kZUp3dEhlYWRlciB9IGZyb20gJy4uL3V0aWxzL2p3ay5qcyc7XG5pbXBvcnQgeyBjcmVhdGVMb2dnZXIgfSBmcm9tICcuLi91dGlscy9sb2dnZXIuanMnO1xuaW1wb3J0IHsgZW1pdENvdW50ZXIgfSBmcm9tICcuLi91dGlscy9tZXRyaWMtZW1pdHRlci5qcyc7XG5cbmNvbnN0IGxvZ2dlciA9IGNyZWF0ZUxvZ2dlcignb24tYmVoYWxmJyk7XG5cbi8qKiBUaGUgaGVhZGVyIGNhcnJ5aW5nIHRoZSBzaWduZWQgb24tYmVoYWxmIG1hcmtlciAobG93ZXItY2FzZSwgYXMgTm9kZSByZWFkcyBpdCkuICovXG5leHBvcnQgY29uc3QgT05fQkVIQUxGX0hFQURFUiA9ICd4LXBiLW9uLWJlaGFsZic7XG5cbi8qKlxuICogU2VydmljZXMgd2hvc2Ugb24tYmVoYWxmIG1hcmtlciBpcyBob25vdXJlZDogdGhlIG9uZXMgdGhhdCBmb3J3YXJkIGEgdXNlcidzXG4gKiB0b2tlbiBhcyBhIG1hdHRlciBvZiBkZXNpZ24uIEEgbWFya2VyIHNpZ25lZCBieSBhbnkgb3RoZXIgc2VydmljZSDigJQgdmFsaWRcbiAqIHNpZ25hdHVyZSBvciBub3Qg4oCUIGlzIGlnbm9yZWQsIHNvIGEgY29tcHJvbWlzZWQgcGVlciB0aGF0IG5ldmVyIGZvcndhcmRzIHVzZXJcbiAqIHRva2VucyBjYW5ub3Qgc3RhcnQgd2FpdmluZyBpdHMgdGVuYW50cycgbWV0ZXJzLlxuICovXG5leHBvcnQgY29uc3QgT05fQkVIQUxGX0NBTExFUlM6IHJlYWRvbmx5IHN0cmluZ1tdID0gWydhc2snLCAncGlwZWxpbmUnXTtcblxuLyoqIE1hcmtlciBsaWZldGltZS4gTWludGVkIHBlciBvdXRib3VuZCBjYWxsLCBzbyBpdCBvbmx5IGhhcyB0byBvdXRsaXZlIG9uZSBob3AuICovXG5jb25zdCBPTl9CRUhBTEZfVFRMX1NFQ09ORFMgPSAxMjA7XG5cbi8qKiBUaGUgYHR5cGVgIGNsYWltIHRoYXQgbWFrZXMgdGhlIG1hcmtlciB1bnVzYWJsZSBhcyBhbiBhY2Nlc3MgdG9rZW4uICovXG5jb25zdCBPTl9CRUhBTEZfVE9LRU5fVFlQRSA9ICdvbl9iZWhhbGYnO1xuXG4vKiogV2hvIGEgbWFya2VyIHZvdWNoZXMgZm9yLiBEZWZhdWx0cyB0byB0aGUgYW1iaWVudCByZXF1ZXN0J3MgdmVyaWZpZWQgcHJpbmNpcGFsLiAqL1xuZXhwb3J0IGludGVyZmFjZSBPbkJlaGFsZlN1YmplY3Qge1xuICAvKiogVGhlIHVzZXIgKGBzdWJgKSB3aG9zZSB0b2tlbiByaWRlcyB0aGUgc2FtZSByZXF1ZXN0LiAqL1xuICBzdWI6IHN0cmluZztcbiAgLyoqIFRoZWlyIGFjdGl2ZSBvcmcuICovXG4gIG9yZ2FuaXphdGlvbklkOiBzdHJpbmc7XG59XG5cbi8qKlxuICogSGVhZGVycyB0byBhZGQgYmVzaWRlIGEgZm9yd2FyZGVkIHVzZXIgYEF1dGhvcml6YXRpb25gIHNvIHRoZSBwZWVyIGRvZXMgbm90XG4gKiBiaWxsIHRoZSBob3AgYSBzZWNvbmQgdGltZS4gTWludCBwZXIgY2FsbCAodGhlIG1hcmtlciBleHBpcmVzIGluIDEyMCBzKS5cbiAqXG4gKiBUaGUgc3ViamVjdCBkZWZhdWx0cyB0byB0aGUgYW1iaWVudCBhdWRpdCBjb250ZXh0J3MgVkVSSUZJRUQgcHJpbmNpcGFsICh0aGVcbiAqIGluYm91bmQgcmVxdWVzdCB0aGlzIGNhbGwgc2VydmVzKS4gUmV0dXJucyBge31gIOKAlCB0aGUgaG9wIGlzIGJpbGxlZCBub3JtYWxseSxcbiAqIHRoZSBzYWZlIGRpcmVjdGlvbiDigJQgd2hlbiB0aGVyZSBpcyBubyB1c2VyIHByaW5jaXBhbCB0byB2b3VjaCBmb3IsIG9yIHdoZW5cbiAqIHRoaXMgcHJvY2VzcyBjYW5ub3Qgc2lnbiAobm8gc2VydmljZSBrZXkpLlxuICovXG5leHBvcnQgZnVuY3Rpb24gb25CZWhhbGZIZWFkZXJzKHN1YmplY3Q/OiBPbkJlaGFsZlN1YmplY3QpOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+IHtcbiAgY29uc3QgcHJpbmNpcGFsID0gc3ViamVjdCA/PyBhbWJpZW50U3ViamVjdCgpO1xuICBpZiAoIXByaW5jaXBhbCkgcmV0dXJuIHt9O1xuICB0cnkge1xuICAgIGNvbnN0IHRva2VuID0gc2lnblNlcnZpY2VKd3QoXG4gICAgICB7XG4gICAgICAgIHR5cGU6IE9OX0JFSEFMRl9UT0tFTl9UWVBFLFxuICAgICAgICBwcmluY2lwYWxUeXBlOiAnc2VydmljZScsXG4gICAgICAgIG9ibzogcHJpbmNpcGFsLnN1YixcbiAgICAgICAgb3JnYW5pemF0aW9uSWQ6IHByaW5jaXBhbC5vcmdhbml6YXRpb25JZCxcbiAgICAgICAganRpOiByYW5kb21VVUlEKCksXG4gICAgICB9LFxuICAgICAgeyBzZXJ2aWNlTmFtZTogcHJvY2Vzcy5lbnYuU0VSVklDRV9OQU1FIHx8ICdhcGknLCBleHBpcmVzSW5TZWNvbmRzOiBPTl9CRUhBTEZfVFRMX1NFQ09ORFMsIC4uLmlzc3VlckF1ZGllbmNlT3B0aW9ucygpIH0sXG4gICAgKTtcbiAgICByZXR1cm4geyBbT05fQkVIQUxGX0hFQURFUl06IHRva2VuIH07XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIGxvZ2dlci5kZWJ1ZygnT24tYmVoYWxmIG1hcmtlciBub3QgbWludGVkOyB0aGUgcGVlciB3aWxsIG1ldGVyIHRoZSBob3AnLCB7IGVycm9yOiBTdHJpbmcoZXJyKSB9KTtcbiAgICByZXR1cm4ge307XG4gIH1cbn1cblxuZnVuY3Rpb24gYW1iaWVudFN1YmplY3QoKTogT25CZWhhbGZTdWJqZWN0IHwgdW5kZWZpbmVkIHtcbiAgY29uc3QgdXNlciA9IGN1cnJlbnRBdWRpdENvbnRleHQoKT8ucHJpbmNpcGFsPy4oKTtcbiAgaWYgKCF1c2VyIHx8IHVzZXIucHJpbmNpcGFsVHlwZSA9PT0gJ3NlcnZpY2UnIHx8ICF1c2VyLnN1YiB8fCAhdXNlci5vcmdhbml6YXRpb25JZCkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgcmV0dXJuIHsgc3ViOiB1c2VyLnN1Yiwgb3JnYW5pemF0aW9uSWQ6IHVzZXIub3JnYW5pemF0aW9uSWQgfTtcbn1cblxuLyoqIE1lbW8gcGVyIHJlcXVlc3Q6IHRoZSBtZXRlciAob24gYGZpbmlzaGApIGFuZCB0aGUgY2hlY2sgKGluIHJlcXVpcmVBdXRoKSBib3RoIGFzay4gKi9cbmNvbnN0IHZlcmRpY3RzID0gbmV3IFdlYWtNYXA8UmVxdWVzdCwgc3RyaW5nIHwgbnVsbD4oKTtcblxuLyoqXG4gKiBUaGUgaW50ZXJuYWwgc2VydmljZSB0aGF0IHZvdWNoZWQgZm9yIHRoaXMgcmVxdWVzdCB3aXRoIGEgVkFMSUQgb24tYmVoYWxmXG4gKiBtYXJrZXIsIGVsc2UgYHVuZGVmaW5lZGAuIFJlcXVpcmVzIHRoZSByZXF1ZXN0IHRvIGJlIGF1dGhlbnRpY2F0ZWQgKGByZXEudXNlcmBcbiAqIHNldCBieSByZXF1aXJlQXV0aCkg4oCUIHRoZSBtYXJrZXIgaXMgb25seSBtZWFuaW5nZnVsIGFnYWluc3QgYSB2ZXJpZmllZCB1c2VyLlxuICpcbiAqIEV2ZXJ5IHJlamVjdGlvbiBvZiBhIFBSRVNFTlQgaGVhZGVyIGlzIGNvdW50ZWQgb25cbiAqIGBxdW90YV9vbl9iZWhhbGZfcmVqZWN0ZWRfdG90YWx7cmVhc29ufWA6IGEgZm9yZ2VkIGhlYWRlciBmcm9tIGEgdXNlciBsYW5kc1xuICogdGhlcmUgYXMgYGludmFsaWRgIChubyBzZXJ2aWNlIGtleSBzaWducyBpdCksIGFuZCB0aGUgcmVxdWVzdCBpcyBiaWxsZWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBvbkJlaGFsZkNhbGxlcihyZXE6IFJlcXVlc3QpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICBjb25zdCBtZW1vID0gdmVyZGljdHMuZ2V0KHJlcSk7XG4gIGlmIChtZW1vICE9PSB1bmRlZmluZWQpIHJldHVybiBtZW1vID8/IHVuZGVmaW5lZDtcbiAgY29uc3QgdmVyZGljdCA9IHZlcmlmeU1hcmtlcihyZXEpO1xuICB2ZXJkaWN0cy5zZXQocmVxLCB2ZXJkaWN0KTtcbiAgcmV0dXJuIHZlcmRpY3QgPz8gdW5kZWZpbmVkO1xufVxuXG5mdW5jdGlvbiB2ZXJpZnlNYXJrZXIocmVxOiBSZXF1ZXN0KTogc3RyaW5nIHwgbnVsbCB7XG4gIGNvbnN0IHJhdyA9IHJlcS5oZWFkZXJzPy5bT05fQkVIQUxGX0hFQURFUl07XG4gIGNvbnN0IHRva2VuID0gQXJyYXkuaXNBcnJheShyYXcpID8gcmF3WzBdIDogcmF3O1xuICBpZiAoIXRva2VuKSByZXR1cm4gbnVsbDtcbiAgY29uc3QgcmVqZWN0ID0gKHJlYXNvbjogc3RyaW5nKTogbnVsbCA9PiB7XG4gICAgZW1pdENvdW50ZXIoJ3F1b3RhX29uX2JlaGFsZl9yZWplY3RlZF90b3RhbCcsIHsgcmVhc29uIH0pO1xuICAgIHJldHVybiBudWxsO1xuICB9O1xuICBjb25zdCB1c2VyID0gcmVxLnVzZXI7XG4gIGlmICghdXNlcj8uc3ViIHx8ICF1c2VyLm9yZ2FuaXphdGlvbklkKSByZXR1cm4gcmVqZWN0KCd1bmF1dGhlbnRpY2F0ZWQnKTtcbiAgdHJ5IHtcbiAgICBjb25zdCBoZWFkZXIgPSBkZWNvZGVKd3RIZWFkZXIodG9rZW4pO1xuICAgIGlmICghaGVhZGVyPy5raWQgfHwgIWlzU2VydmljZUtpZChoZWFkZXIua2lkKSkgcmV0dXJuIHJlamVjdCgnaW52YWxpZCcpO1xuICAgIGNvbnN0IGNsYWltcyA9IHZlcmlmeVNlcnZpY2VKd3Q8eyB0eXBlPzogc3RyaW5nOyBwcmluY2lwYWxUeXBlPzogc3RyaW5nOyBzdWI/OiBzdHJpbmc7IG9ibz86IHN0cmluZzsgb3JnYW5pemF0aW9uSWQ/OiBzdHJpbmcgfT4oXG4gICAgICB0b2tlbiwgeyBraWQ6IGhlYWRlci5raWQsIC4uLmlzc3VlckF1ZGllbmNlT3B0aW9ucygpIH0sXG4gICAgKTtcbiAgICBpZiAoY2xhaW1zLnR5cGUgIT09IE9OX0JFSEFMRl9UT0tFTl9UWVBFIHx8IGNsYWltcy5wcmluY2lwYWxUeXBlICE9PSAnc2VydmljZScpIHJldHVybiByZWplY3QoJ2ludmFsaWQnKTtcbiAgICBjb25zdCBjYWxsZXIgPSBzZXJ2aWNlTmFtZU9mKGNsYWltcyk7XG4gICAgaWYgKCFjYWxsZXIgfHwgaXNTZXJ2aWNlVG9rZW5EZW5pZWQoY2xhaW1zKSkgcmV0dXJuIHJlamVjdCgnZGVuaWVkJyk7XG4gICAgaWYgKCFPTl9CRUhBTEZfQ0FMTEVSUy5pbmNsdWRlcyhjYWxsZXIpKSByZXR1cm4gcmVqZWN0KCdjYWxsZXInKTtcbiAgICBpZiAoY2xhaW1zLm9ibyAhPT0gdXNlci5zdWIpIHJldHVybiByZWplY3QoJ3N1YmplY3QnKTtcbiAgICBpZiAoU3RyaW5nKGNsYWltcy5vcmdhbml6YXRpb25JZCA/PyAnJykudG9Mb3dlckNhc2UoKSAhPT0gdXNlci5vcmdhbml6YXRpb25JZC50b0xvd2VyQ2FzZSgpKSByZXR1cm4gcmVqZWN0KCdvcmcnKTtcbiAgICByZXR1cm4gY2FsbGVyO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gcmVqZWN0KCdpbnZhbGlkJyk7XG4gIH1cbn1cbiJdfQ==
@@ -3,6 +3,7 @@
3
3
  * `authz.denied` audit sink they report refusals to.
4
4
  */
5
5
  import type { Request, Response, NextFunction } from 'express';
6
+ import { type AuditAuthBlock } from '../services/audit-context.js';
6
7
  import { type Permission } from '../types/permissions.js';
7
8
  /**
8
9
  * Whether the request's user holds `permission`. Superadmins implicitly hold
@@ -26,6 +27,16 @@ export interface AuthzDenialInfo {
26
27
  path: string;
27
28
  /** What was required: the missing permission(s), or 'system-admin'. */
28
29
  required: string;
30
+ /** Client ip (`req.ip`, proxy-resolved). */
31
+ ip?: string;
32
+ /** Sanitized, length-capped User-Agent. */
33
+ userAgent?: string;
34
+ /** The request's correlation id (the ambient audit context's, else a valid `X-Request-Id`). */
35
+ requestId?: string;
36
+ /** The real sysadmin behind an impersonation token, from the verified token. */
37
+ impersonatorId?: string;
38
+ /** The credential that was refused (key id, session, scope, …) — the `_auth` block. */
39
+ auth?: AuditAuthBlock;
29
40
  }
30
41
  /**
31
42
  * Register (or clear, with `undefined`) the process-wide authorization-denial
@@ -3,6 +3,7 @@
3
3
  import { tagRouteGate } from './route-table.js';
4
4
  import { isServicePrincipal, serviceNameOf } from './service-tokens.js';
5
5
  import { HttpStatus } from '../constants/http-status.js';
6
+ import { auditAuthBlock, currentAuditContext, sanitizeCorrelationId, sanitizeUserAgent } from '../services/audit-context.js';
6
7
  import { serviceIdentity } from '../services/service-keys.js';
7
8
  import { ErrorCode } from '../types/error-codes.js';
8
9
  import { hasPermission } from '../types/permissions.js';
@@ -60,6 +61,11 @@ export function recordAuthzDenial(req, required) {
60
61
  // query param, and this path is persisted verbatim into the audit log.
61
62
  path: (req.originalUrl || req.url).split('?')[0],
62
63
  required,
64
+ ip: req.ip,
65
+ userAgent: sanitizeUserAgent(req.headers?.['user-agent']),
66
+ requestId: currentAuditContext()?.requestId ?? sanitizeCorrelationId(req.headers?.['x-request-id']),
67
+ impersonatorId: req.user?.impersonatorId,
68
+ auth: auditAuthBlock(req.user),
63
69
  });
64
70
  }
65
71
  catch {
@@ -257,4 +263,4 @@ export function requireFeature(feature) {
257
263
  next();
258
264
  }, { kind: 'feature', feature });
259
265
  }
260
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGVybWlzc2lvbi1nYXRlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9taWRkbGV3YXJlL3Blcm1pc3Npb24tZ2F0ZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQVF0QyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDaEQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLGFBQWEsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3hFLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUN6RCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDOUQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ3BELE9BQU8sRUFBbUIsYUFBYSxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDekUsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ2xELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUN6RCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFFakQsTUFBTSxNQUFNLEdBQUcsWUFBWSxDQUFDLGlCQUFpQixDQUFDLENBQUM7QUFDL0M7Ozs7R0FJRztBQUNILE1BQU0sVUFBVSxpQkFBaUIsQ0FBQyxHQUFZLEVBQUUsVUFBc0I7SUFDcEUsT0FBTyxhQUFhLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxXQUFXLEVBQUUsVUFBVSxFQUFFLEdBQUcsQ0FBQyxJQUFJLEVBQUUsWUFBWSxDQUFDLENBQUM7QUFDbEYsQ0FBQztBQW9CRDs7Ozs7OztHQU9HO0FBQ0gsSUFBSSxrQkFBaUUsQ0FBQztBQUV0RTs7O0dBR0c7QUFDSCxNQUFNLFVBQVUscUJBQXFCLENBQUMsRUFBaUQ7SUFDckYsa0JBQWtCLEdBQUcsRUFBRSxDQUFDO0FBQzFCLENBQUM7QUFF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QUMsSUFBSSxDQUFDLFlBQVksS0FBSyxJQUFJO1lBQUUsT0FBTyxJQUFJLEVBQUUsQ0FBQztRQUVsRCxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsUUFBUSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7WUFDMUMsNERBQTREO1lBQzVELDJEQUEyRDtZQUMzRCxzRUFBc0U7WUFDdEUsaUJBQWlCLENBQUMsR0FBRyxFQUFFLFdBQVcsT0FBTyxFQUFFLENBQUMsQ0FBQztZQUM3QyxPQUFPLFNBQVMsQ0FDZCxHQUFHLEVBQUUsVUFBVSxDQUFDLFNBQVMsRUFDekIsd0NBQXdDLE9BQU8sR0FBRyxFQUNsRCxTQUFTLENBQUMsd0JBQXdCLENBQ25DLENBQUM7UUFDSixDQUFDO1FBRUQsSUFBSSxFQUFFLENBQUM7SUFDVCxDQUFDLEVBQUUsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxDQUFDLENBQUM7QUFDbkMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDI2IFBpcGVsaW5lIEJ1aWxkZXIgQ29udHJpYnV0b3JzXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuXG4vKipcbiAqIEF1dGhvcml6YXRpb24gZ2F0ZXMg4oCUIHBlcm1pc3Npb25zLCBzeXN0ZW0gYWRtaW4sIGZlYXR1cmVzIOKAlCBhbmQgdGhlXG4gKiBgYXV0aHouZGVuaWVkYCBhdWRpdCBzaW5rIHRoZXkgcmVwb3J0IHJlZnVzYWxzIHRvLlxuICovXG5cbmltcG9ydCB0eXBlIHsgUmVxdWVzdCwgUmVzcG9uc2UsIE5leHRGdW5jdGlvbiB9IGZyb20gJ2V4cHJlc3MnO1xuaW1wb3J0IHsgdGFnUm91dGVHYXRlIH0gZnJvbSAnLi9yb3V0ZS10YWJsZS5qcyc7XG5pbXBvcnQgeyBpc1NlcnZpY2VQcmluY2lwYWwsIHNlcnZpY2VOYW1lT2YgfSBmcm9tICcuL3NlcnZpY2UtdG9rZW5zLmpzJztcbmltcG9ydCB7IEh0dHBTdGF0dXMgfSBmcm9tICcuLi9jb25zdGFudHMvaHR0cC1zdGF0dXMuanMnO1xuaW1wb3J0IHsgc2VydmljZUlkZW50aXR5IH0gZnJvbSAnLi4vc2VydmljZXMvc2VydmljZS1rZXlzLmpzJztcbmltcG9ydCB7IEVycm9yQ29kZSB9IGZyb20gJy4uL3R5cGVzL2Vycm9yLWNvZGVzLmpzJztcbmltcG9ydCB7IHR5cGUgUGVybWlzc2lvbiwgaGFzUGVybWlzc2lvbiB9IGZyb20gJy4uL3R5cGVzL3Blcm1pc3Npb25zLmpzJztcbmltcG9ydCB7IGNyZWF0ZUxvZ2dlciB9IGZyb20gJy4uL3V0aWxzL2xvZ2dlci5qcyc7XG5pbXBvcnQgeyBlbWl0Q291bnRlciB9IGZyb20gJy4uL3V0aWxzL21ldHJpYy1lbWl0dGVyLmpzJztcbmltcG9ydCB7IHNlbmRFcnJvciB9IGZyb20gJy4uL3V0aWxzL3Jlc3BvbnNlLmpzJztcblxuY29uc3QgbG9nZ2VyID0gY3JlYXRlTG9nZ2VyKCdhdXRoLW1pZGRsZXdhcmUnKTtcbi8qKlxuICogV2hldGhlciB0aGUgcmVxdWVzdCdzIHVzZXIgaG9sZHMgYHBlcm1pc3Npb25gLiBTdXBlcmFkbWlucyBpbXBsaWNpdGx5IGhvbGRcbiAqIGV2ZXJ5IHBlcm1pc3Npb24uIFJlYWRzIHRoZSByZXNvbHZlZCBgcGVybWlzc2lvbnNgIGNsYWltIChzZXQgYXQgdG9rZW4gaXNzdWUsXG4gKiBvciByZS1kZXJpdmVkIHBlciByZXF1ZXN0IGJ5IHRoZSBwbGF0Zm9ybSkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1c2VySGFzUGVybWlzc2lvbihyZXE6IFJlcXVlc3QsIHBlcm1pc3Npb246IFBlcm1pc3Npb24pOiBib29sZWFuIHtcbiAgcmV0dXJuIGhhc1Blcm1pc3Npb24ocmVxLnVzZXI/LnBlcm1pc3Npb25zLCBwZXJtaXNzaW9uLCByZXEudXNlcj8uaXNTdXBlckFkbWluKTtcbn1cblxuLyoqXG4gKiBDb250ZXh0IHBhc3NlZCB0byBhIHJlZ2lzdGVyZWQgYXV0aG9yaXphdGlvbi1kZW5pYWwgYXVkaXRvciB3aGVuIGFcbiAqIHN0YXRlLWNoYW5naW5nIHJlcXVlc3QgaXMgcmVqZWN0ZWQgYnkgYHJlcXVpcmVQZXJtaXNzaW9uYCAvXG4gKiBgcmVxdWlyZVN5c3RlbUFkbWluYC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBdXRoekRlbmlhbEluZm8ge1xuICAvKiogVGhlIGRlbmllZCB1c2VyJ3MgaWQgKGBzdWJgKSwgaWYgYXV0aGVudGljYXRlZC4gKi9cbiAgYWN0b3JJZD86IHN0cmluZztcbiAgYWN0b3JFbWFpbD86IHN0cmluZztcbiAgLyoqIFRoZSB1c2VyJ3MgYWN0aXZlIG9yZyBhdCBkZW5pYWwgdGltZS4gKi9cbiAgb3JnSWQ/OiBzdHJpbmc7XG4gIC8qKiBIVFRQIG1ldGhvZCArIHBhdGggb2YgdGhlIHJlamVjdGVkIHJlcXVlc3QuICovXG4gIG1ldGhvZDogc3RyaW5nO1xuICBwYXRoOiBzdHJpbmc7XG4gIC8qKiBXaGF0IHdhcyByZXF1aXJlZDogdGhlIG1pc3NpbmcgcGVybWlzc2lvbihzKSwgb3IgJ3N5c3RlbS1hZG1pbicuICovXG4gIHJlcXVpcmVkOiBzdHJpbmc7XG59XG5cbi8qKlxuICogT3B0aW9uYWwgc2luayBmb3IgZGVuaWVkLWF1dGhvcml6YXRpb24gZXZlbnRzLiBMZWZ0IHVuc2V0IGJ5IGRlZmF1bHQgc29cbiAqIGFwaS1jb3JlIHN0YXlzIGRlY291cGxlZCBmcm9tIGFueSBhdWRpdCB0cmFuc3BvcnQg4oCUIGEgc2VydmljZSByZWdpc3RlcnMgb25lXG4gKiBhdCBib290ICh0eXBpY2FsbHkgZm9yd2FyZGluZyB0byBpdHMgYFJlbW90ZUF1ZGl0Q2xpZW50YCBhcyBhblxuICogYGF1dGh6LmRlbmllZGAgZXZlbnQsIG9yLCBvbiBwbGF0Zm9ybSwgdG8gdGhlIGxvY2FsIGBhdWRpdCgpYCBoZWxwZXIpLlxuICogTVVTVCBiZSBiZXN0LWVmZm9ydDogaXQgaXMgaW52b2tlZCBpbnNpZGUgdGhlIHJlcXVlc3QgcGF0aCwgc28gaXQgbXVzdCBuZXZlclxuICogdGhyb3cgb3IgYmxvY2sgKHRoZSBnYXRlIHdyYXBzIHRoZSBjYWxsIGluIHRyeS9jYXRjaCByZWdhcmRsZXNzKS5cbiAqL1xubGV0IGF1dGh6RGVuaWFsQXVkaXRvcjogKChpbmZvOiBBdXRoekRlbmlhbEluZm8pID0+IHZvaWQpIHwgdW5kZWZpbmVkO1xuXG4vKipcbiAqIFJlZ2lzdGVyIChvciBjbGVhciwgd2l0aCBgdW5kZWZpbmVkYCkgdGhlIHByb2Nlc3Mtd2lkZSBhdXRob3JpemF0aW9uLWRlbmlhbFxuICogYXVkaXRvci4gSWRlbXBvdGVudDsgdGhlIGxhc3QgcmVnaXN0cmF0aW9uIHdpbnMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZXRBdXRoekRlbmlhbEF1ZGl0b3IoZm46ICgoaW5mbzogQXV0aHpEZW5pYWxJbmZvKSA9PiB2b2lkKSB8IHVuZGVmaW5lZCk6IHZvaWQge1xuICBhdXRoekRlbmlhbEF1ZGl0b3IgPSBmbjtcbn1cblxuLyoqXG4gKiBFbWl0IGEgZGVuaWFsIGV2ZW50LCBiZXN0LWVmZm9ydC4gT25seSBmaXJlcyBmb3Igc3RhdGUtY2hhbmdpbmcgKG5vbi1HRVQsXG4gKiBub24tSEVBRC9PUFRJT05TKSByZXF1ZXN0cyDigJQgYSByZWplY3RlZCBHRVQgaXMgbG93LXNpZ25hbCBwcm9iaW5nIG5vaXNlIGFuZFxuICogd291bGQgYW1wbGlmeSBhdWRpdCB2b2x1bWUgdW5kZXIgYSBzY2FuLiBOZXZlciB0aHJvd3MuXG4gKlxuICogVGhlIHBlcm1pc3Npb24gZ2F0ZXMgaGVyZSBjYWxsIGl0IHRoZW1zZWx2ZXMuIEV4cG9ydCBpdCBmb3IgZGF0YS1kcml2ZW4gY2hlY2tzXG4gKiBhIHJvdXRlIG1ha2VzIGlubGluZSAoY3Jvc3Mtb3JnIGFjY2Vzcywgc2VydmljZS1vbmx5IGVuZHBvaW50cyksIHNvIHRob3NlIDQwM3NcbiAqIHJlYWNoIHRoZSBzYW1lIGBhdXRoei5kZW5pZWRgIHRyYWlsLiBgcmVxdWlyZWRgIG5hbWVzIHdoYXQgd2FzIG1pc3NpbmcuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWNvcmRBdXRoekRlbmlhbChyZXE6IFJlcXVlc3QsIHJlcXVpcmVkOiBzdHJpbmcpOiB2b2lkIHtcbiAgY29uc3QgYXVkaXRvciA9IGF1dGh6RGVuaWFsQXVkaXRvcjtcbiAgaWYgKCFhdWRpdG9yKSByZXR1cm47XG4gIGNvbnN0IG1ldGhvZCA9IHJlcS5tZXRob2QudG9VcHBlckNhc2UoKTtcbiAgaWYgKG1ldGhvZCA9PT0gJ0dFVCcgfHwgbWV0aG9kID09PSAnSEVBRCcgfHwgbWV0aG9kID09PSAnT1BUSU9OUycpIHJldHVybjtcbiAgdHJ5IHtcbiAgICBhdWRpdG9yKHtcbiAgICAgIGFjdG9ySWQ6IHJlcS51c2VyPy5zdWIsXG4gICAgICBhY3RvckVtYWlsOiByZXEudXNlcj8uZW1haWwsXG4gICAgICBvcmdJZDogcmVxLnVzZXI/Lm9yZ2FuaXphdGlvbklkLFxuICAgICAgbWV0aG9kLFxuICAgICAgLy8gU3RyaXAgdGhlIHF1ZXJ5IHN0cmluZyDigJQgYSBkZW5pZWQgcmVxdWVzdCBtYXkgY2FycnkgYSB0b2tlbi9zZWNyZXQgYXMgYVxuICAgICAgLy8gcXVlcnkgcGFyYW0sIGFuZCB0aGlzIHBhdGggaXMgcGVyc2lzdGVkIHZlcmJhdGltIGludG8gdGhlIGF1ZGl0IGxvZy5cbiAgICAgIHBhdGg6IChyZXEub3JpZ2luYWxVcmwgfHwgcmVxLnVybCkuc3BsaXQoJz8nKVswXSxcbiAgICAgIHJlcXVpcmVkLFxuICAgIH0pO1xuICB9IGNhdGNoIHtcbiAgICAvLyBCZXN0LWVmZm9ydCDigJQgYSBicm9rZW4gYXVkaXRvciBtdXN0IG5ldmVyIGJyZWFrIHRoZSBhdXRoIGdhdGUuXG4gIH1cbn1cblxuLyoqIFRoZSBzaGFyZWQgZ2F0ZSBwcmVhbWJsZTogYW5zd2VyIDQwMSBhbmQgcmV0dXJuIGZhbHNlIHdoZW4gdW5hdXRoZW50aWNhdGVkLiAqL1xuZnVuY3Rpb24gcmVxdWlyZVVzZXIocmVxOiBSZXF1ZXN0LCByZXM6IFJlc3BvbnNlKTogcmVxIGlzIFJlcXVlc3QgJiB7IHVzZXI6IE5vbk51bGxhYmxlPFJlcXVlc3RbJ3VzZXInXT4gfSB7XG4gIGlmIChyZXEudXNlcikgcmV0dXJuIHRydWU7XG4gIHNlbmRFcnJvcihyZXMsIEh0dHBTdGF0dXMuVU5BVVRIT1JJWkVELCAnQXV0aGVudGljYXRpb24gcmVxdWlyZWQnLCBFcnJvckNvZGUuVU5BVVRIT1JJWkVEKTtcbiAgcmV0dXJuIGZhbHNlO1xufVxuXG4vKiogQXVkaXQgKyBhbnN3ZXIgYSBwZXJtaXNzaW9uIHJlZnVzYWwgKGBtaXNzaW5nYCBkZWZhdWx0cyB0byBldmVyeSByZXF1aXJlZCBwZXJtaXNzaW9uKS4gKi9cbmZ1bmN0aW9uIGRlbnlQZXJtaXNzaW9uKHJlcTogUmVxdWVzdCwgcmVzOiBSZXNwb25zZSwgcGVybWlzc2lvbnM6IFBlcm1pc3Npb25bXSwgbW9kZTogJ29yJyB8ICdhbmQnLCBtaXNzaW5nOiBQZXJtaXNzaW9uW10gPSBwZXJtaXNzaW9ucyk6IHZvaWQge1xuICByZWNvcmRBdXRoekRlbmlhbChyZXEsIHBlcm1pc3Npb25zLmpvaW4oYCAke21vZGV9IGApKTtcbiAgc2VuZEVycm9yKFxuICAgIHJlcywgSHR0cFN0YXR1cy5GT1JCSURERU4sXG4gICAgYE1pc3NpbmcgcmVxdWlyZWQgcGVybWlzc2lvbjogJHttaXNzaW5nLmpvaW4oYCAke21vZGV9IGApfWAsXG4gICAgRXJyb3JDb2RlLklOU1VGRklDSUVOVF9QRVJNSVNTSU9OUyxcbiAgKTtcbn1cblxuLyoqXG4gKiBSZXF1aXJlcyB0aGF0IHRoZSB1c2VyIGhvbGQgQVQgTEVBU1QgT05FIG9mIHRoZSBnaXZlbiBwZXJtaXNzaW9ucyAob3IgYmUgYVxuICogc3VwZXJhZG1pbikuIFVzZSBhZnRlciByZXF1aXJlQXV0aC4gTWlycm9ycyBgcmVxdWlyZVJvbGVgJ3MgYW55LW9mIHNlbWFudGljcztcbiAqIHBhc3MgYSBzaW5nbGUgcGVybWlzc2lvbiBmb3IgYSBzcGVjaWZpYyBhY3Rpb24sIG9yIHNldmVyYWwgd2hlbiBhbnkgb25lIG9mXG4gKiB0aGVtIHNob3VsZCBncmFudCBhY2Nlc3MuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXF1aXJlUGVybWlzc2lvbiguLi5wZXJtaXNzaW9uczogUGVybWlzc2lvbltdKSB7XG4gIHJldHVybiB0YWdSb3V0ZUdhdGUoKHJlcTogUmVxdWVzdCwgcmVzOiBSZXNwb25zZSwgbmV4dDogTmV4dEZ1bmN0aW9uKTogdm9pZCA9PiB7XG4gICAgaWYgKCFyZXF1aXJlVXNlcihyZXEsIHJlcykpIHJldHVybjtcbiAgICAvLyB1c2VySGFzUGVybWlzc2lvbiDihpIgaGFzUGVybWlzc2lvbiBhbHJlYWR5IGdyYW50cyBzdXBlcmFkbWlucyBldmVyeVxuICAgIC8vIHBlcm1pc3Npb24sIHNvIHRoaXMgc2luZ2xlIGNoZWNrIGNvdmVycyBib3RoIHRoZSBzdXBlcmFkbWluIGJ5cGFzcyBhbmRcbiAgICAvLyB0aGUgYW55LW9mIG1lbWJlcnNoaXAgdGVzdCB3aXRob3V0IHJlLWlubGluaW5nIGVpdGhlci5cbiAgICBpZiAocGVybWlzc2lvbnMuc29tZSgocCkgPT4gdXNlckhhc1Blcm1pc3Npb24ocmVxLCBwKSkpIHJldHVybiBuZXh0KCk7XG4gICAgZGVueVBlcm1pc3Npb24ocmVxLCByZXMsIHBlcm1pc3Npb25zLCAnb3InKTtcbiAgfSwgeyBraW5kOiAncGVybWlzc2lvbicsIG1vZGU6ICdhbnknLCBwZXJtaXNzaW9ucyB9KTtcbn1cblxuLyoqXG4gKiBSZXF1aXJlcyB0aGF0IHRoZSB1c2VyIGhvbGQgRVZFUlkgb25lIG9mIHRoZSBnaXZlbiBwZXJtaXNzaW9ucyAob3IgYmUgYVxuICogc3VwZXJhZG1pbikg4oCUIHRoZSBBTkQgY291bnRlcnBhcnQgdG8gYHJlcXVpcmVQZXJtaXNzaW9uYCdzIGFueS1vZi4gVXNlIGZvciBhXG4gKiBzZW5zaXRpdmUgYWN0aW9uIHRoYXQgbGVnaXRpbWF0ZWx5IGRlbWFuZHMgdHdvIGRpc3RpbmN0IGNhcGFiaWxpdGllcyBhdCBvbmNlXG4gKiAoZS5nLiBhIGNyb3NzLXN1cmZhY2Ugb3BlcmF0aW9uKSwgc28gdGhlIGd1YXJhbnRlZSBpcyBleHBsaWNpdCByYXRoZXIgdGhhblxuICogYXBwcm94aW1hdGVkIGJ5IGNoYWluaW5nIHR3byBgcmVxdWlyZVBlcm1pc3Npb25gIGdhdGVzLiBTdXBlcmFkbWlucyBieXBhc3NcbiAqICh0aGV5IGltcGxpY2l0bHkgaG9sZCBldmVyeSBwZXJtaXNzaW9uKS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlcXVpcmVBbGxQZXJtaXNzaW9ucyguLi5wZXJtaXNzaW9uczogUGVybWlzc2lvbltdKSB7XG4gIHJldHVybiB0YWdSb3V0ZUdhdGUoKHJlcTogUmVxdWVzdCwgcmVzOiBSZXNwb25zZSwgbmV4dDogTmV4dEZ1bmN0aW9uKTogdm9pZCA9PiB7XG4gICAgaWYgKCFyZXF1aXJlVXNlcihyZXEsIHJlcykpIHJldHVybjtcbiAgICBjb25zdCBtaXNzaW5nID0gcGVybWlzc2lvbnMuZmlsdGVyKChwKSA9PiAhdXNlckhhc1Blcm1pc3Npb24ocmVxLCBwKSk7XG4gICAgaWYgKG1pc3NpbmcubGVuZ3RoID09PSAwKSByZXR1cm4gbmV4dCgpO1xuICAgIGRlbnlQZXJtaXNzaW9uKHJlcSwgcmVzLCBwZXJtaXNzaW9ucywgJ2FuZCcsIG1pc3NpbmcpO1xuICB9LCB7IGtpbmQ6ICdwZXJtaXNzaW9uJywgbW9kZTogJ2FsbCcsIHBlcm1pc3Npb25zIH0pO1xufVxuXG4vKipcbiAqIExpa2Uge0BsaW5rIHJlcXVpcmVQZXJtaXNzaW9ufSAoYW55LW9mKSBidXQgQUxTTyBhZG1pdHMgYW4gaW50ZXJuYWwgc2VydmljZVxuICogcHJpbmNpcGFsIChgcHJpbmNpcGFsVHlwZTogJ3NlcnZpY2UnYCkuIEZvciBSRUFEIGVuZHBvaW50cyB0aGF0IEJPVEhcbiAqIGludGVyYWN0aXZlIHVzZXJzIOKAlCB3aG8gbXVzdCBob2xkIG9uZSBvZiB0aGUgYDpyZWFkYCBjYXBhYmlsaXRpZXMg4oCUIEFORFxuICogc2VydmljZS10by1zZXJ2aWNlIGNhbGxlcnMgbGVnaXRpbWF0ZWx5IGhpdDsgc2VydmljZSB0b2tlbnMgY2Fycnkgbm9cbiAqIHBlcm1pc3Npb24gY2xhaW1zICh0aGV5J3JlIGxlYXN0LXByaXZpbGVnZSBgcm9sZTptZW1iZXJgKSwgc28gYSBwbGFpblxuICogYHJlcXVpcmVQZXJtaXNzaW9uYCB3b3VsZCB3cm9uZ2x5IDQwMyB0aGVtLiBTdXBlcmFkbWlucyBwYXNzIHZpYVxuICogYHVzZXJIYXNQZXJtaXNzaW9uYCdzIGltcGxpY2l0LWFsbC4gVXNlIG9ubHkgd2hlcmUgYSBzZXJ2aWNlIGNhbGxlciBpcyBhIGtub3duLFxuICogaW50ZW5kZWQgY29uc3VtZXIgb2YgdGhlIHJvdXRlICh2ZXJpZnkgdGhlIGNhbGxlcnMpOyBwcmVmZXIgcGxhaW5cbiAqIGByZXF1aXJlUGVybWlzc2lvbmAgZm9yIHB1cmVseSB1c2VyLWZhY2luZyByZWFkcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlcXVpcmVQZXJtaXNzaW9uT3JTZXJ2aWNlKC4uLnBlcm1pc3Npb25zOiBQZXJtaXNzaW9uW10pIHtcbiAgcmV0dXJuIHRhZ1JvdXRlR2F0ZSgocmVxOiBSZXF1ZXN0LCByZXM6IFJlc3BvbnNlLCBuZXh0OiBOZXh0RnVuY3Rpb24pOiB2b2lkID0+IHtcbiAgICBpZiAoIXJlcXVpcmVVc2VyKHJlcSwgcmVzKSkgcmV0dXJuO1xuICAgIGlmIChpc1NlcnZpY2VQcmluY2lwYWwocmVxKSB8fCBwZXJtaXNzaW9ucy5zb21lKChwKSA9PiB1c2VySGFzUGVybWlzc2lvbihyZXEsIHApKSkgcmV0dXJuIG5leHQoKTtcbiAgICBkZW55UGVybWlzc2lvbihyZXEsIHJlcywgcGVybWlzc2lvbnMsICdvcicpO1xuICB9LCB7IGtpbmQ6ICdwZXJtaXNzaW9uJywgbW9kZTogJ2FueScsIHBlcm1pc3Npb25zLCBhbGxvd1NlcnZpY2U6IHRydWUgfSk7XG59XG5cbi8qKlxuICogR2F0ZSBhbiBlbmRwb2ludCB0byBpbnRlcm5hbCBzZXJ2aWNlLXRvLXNlcnZpY2UgY2FsbGVycyBvbmx5IChhXG4gKiBgcHJpbmNpcGFsVHlwZTogJ3NlcnZpY2UnYCBwcmluY2lwYWwgbWludGVkIHZpYSB7QGxpbmsgc2lnblNlcnZpY2VUb2tlbn0gLyBgZ2V0U2VydmljZUF1dGhIZWFkZXJgKS5cbiAqIFJlamVjdHMgYW55IHVzZXIgdG9rZW4uIEZvciBOT04tdXNlci1mYWNpbmcgZW5kcG9pbnRzIOKAlCBlbnRpdHktZXZlbnQgaW5nZXN0LFxuICogYXV0by1zdWJzY3JpYmUsIGFuZCBzaW1pbGFyIHBlZXItc2VydmljZSBob29rcyDigJQgdGhhdCBhIGJyb3dzZXIgbXVzdCBuZXZlclxuICogcmVhY2guIENvbXBvc2UgYWZ0ZXIgYHJlcXVpcmVBdXRoYCBzbyBgcmVxLnVzZXJgIGlzIHBvcHVsYXRlZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlcXVpcmVTZXJ2aWNlUHJpbmNpcGFsKHJlcTogUmVxdWVzdCwgcmVzOiBSZXNwb25zZSwgbmV4dDogTmV4dEZ1bmN0aW9uKTogdm9pZCB7XG4gIGlmICghaXNTZXJ2aWNlUHJpbmNpcGFsKHJlcSkpIHtcbiAgICAvLyA0MDMgKG5vdCA0MDApIOKAlCB0aGlzIGlzIGFuIGF1dGhvcml6YXRpb24gcmVmdXNhbDsgc3RhdHVzIG11c3QgbWF0Y2ggdGhlXG4gICAgLy8gSU5TVUZGSUNJRU5UX1BFUk1JU1NJT05TIGNvZGUgYW5kIHRoZSBzaWJsaW5nIGdhdGVzIChyZXF1aXJlUGVybWlzc2lvbiwgZXRjLikuXG4gICAgcmV0dXJuIHNlbmRFcnJvcihyZXMsIEh0dHBTdGF0dXMuRk9SQklEREVOLCAnSW50ZXJuYWwgc2VydmljZSBjYWxscyBvbmx5JywgRXJyb3JDb2RlLklOU1VGRklDSUVOVF9QRVJNSVNTSU9OUyk7XG4gIH1cbiAgbmV4dCgpO1xufVxudGFnUm91dGVHYXRlKHJlcXVpcmVTZXJ2aWNlUHJpbmNpcGFsLCB7IGtpbmQ6ICdzZXJ2aWNlUHJpbmNpcGFsJyB9KTtcblxuLyoqXG4gKiBUSEUgZ2F0ZSBmb3IgYW4gSU5URVJOQUwgcm91dGUg4oCUIHRoZSBvbmUgZXZlcnkgYC9pbnRlcm5hbC8qYCBwYXRoLCB0aGVcbiAqIHF1b3RhIHVzYWdlIGNvdW50ZXJzLCB0aGUgZW50aXR5LWV2ZW50IGluZ2VzdCBhbmQgdGhlIGF1ZGl0IGluZ2VzdCBnbyB0aHJvdWdoLlxuICpcbiAqIFR3byBydWxlcywgYm90aCBmYWlsLWNsb3NlZDpcbiAqXG4gKiAgMS4gKipObyB1c2VyIHRva2VuLCBldmVyLioqIE5vdCBhIG1lbWJlcidzLCBub3QgYSBzdXBlcmFkbWluJ3MsIG5vdCBhXG4gKiAgICAgc2VydmljZS1hY2NvdW50IGtleSdzLiBBbiBpbnRlcm5hbCByb3V0ZSBpcyBhIHBlZXItc2VydmljZSBBUEkgc3VyZmFjZSwgc29cbiAqICAgICBcImEgc3VmZmljaWVudGx5IHByaXZpbGVnZWQgaHVtYW5cIiBpcyBub3QgYW4gYWNjZXB0YWJsZSBjYWxsZXIg4oCUIHRoYXRcbiAqICAgICBlcXVpdmFsZW5jZSBpcyBleGFjdGx5IGhvdyBhIGJyb3dzZXItcmVhY2hhYmxlIHBhdGggYmVjb21lcyBhIHRlbmFudFxuICogICAgIGJvdW5kYXJ5IGJ1Zy4gYHJlcXVpcmVTZXJ2aWNlUHJpbmNpcGFsYCBhbHJlYWR5IHJlZnVzZWQgdXNlcnM7IHRoaXMgYWxzb1xuICogICAgIGNsb3NlcyB0aGUgYHx8IGlzU3lzdGVtQWRtaW4ocmVxKWAgZXNjYXBlIGhhdGNoZXMgdGhhdCBoYWQgZ3Jvd24gYXJvdW5kXG4gKiAgICAgdGhlIGluZGl2aWR1YWwgaW50ZXJuYWwgcm91dGVzLlxuICogIDIuICoqT25seSB0aGUgTkFNRUQgY2FsbGVycy4qKiBgY2FsbGVyc2AgbGlzdHMgdGhlIHNlcnZpY2VzIHRoYXQgbGVnaXRpbWF0ZWx5XG4gKiAgICAgY2FsbCB0aGlzIHJvdXRlLCBhbmQgdGhlIG5hbWUgaXMgY3J5cHRvZ3JhcGhpY2FsbHkgYm91bmQgdG8gdGhlIHNpZ25pbmdcbiAqICAgICBrZXkgKGBzZXJ2aWNlcy9zZXJ2aWNlLWtleXMudHNgKSwgc28gdGhpcyBpcyBhbiBpZGVudGl0eSBjaGVjayByYXRoZXIgdGhhblxuICogICAgIGEgY2xhaW0gY2hlY2suIEl0IGlzIHRoZSBzYW1lIGFsbG93LWxpc3QgdGhlIG1lc2ggcG9saWN5IG5hbWVzLCBhdCB0aGVcbiAqICAgICBsYXllciB0aGF0IGFsc28gaG9sZHMgaW4gZG9ja2VyIGNvbXBvc2UsIHdoZXJlIHRoZXJlIGlzIG5vIG1lc2ggYXQgYWxsIOKAlFxuICogICAgIHRoZSBJc3RpbyBgQXV0aG9yaXphdGlvblBvbGljeWAgaXMgZGVmZW5jZSBpbiBkZXB0aCBvbiB0b3AsIG5ldmVyIHRoZVxuICogICAgIGVuZm9yY2VtZW50LlxuICpcbiAqIENvbXBvc2UgYWZ0ZXIgYHJlcXVpcmVBdXRoYCBzbyBgcmVxLnVzZXJgIGlzIHBvcHVsYXRlZC4gUmVmdXNhbHMgYXJlIGNvdW50ZWRcbiAqIChgaW50ZXJuYWxfcm91dGVfcmVmdXNlZF90b3RhbGApIGFuZCBhdWRpdGVkIHRocm91Z2ggdGhlIHNoYXJlZCBgYXV0aHouZGVuaWVkYFxuICogc2luay5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlcXVpcmVJbnRlcm5hbFNlcnZpY2Uob3B0aW9uczogeyBjYWxsZXJzOiByZWFkb25seSBzdHJpbmdbXSB9KSB7XG4gIGNvbnN0IGFsbG93ZWQgPSBuZXcgU2V0KG9wdGlvbnMuY2FsbGVycyk7XG4gIHJldHVybiB0YWdSb3V0ZUdhdGUoKHJlcTogUmVxdWVzdCwgcmVzOiBSZXNwb25zZSwgbmV4dDogTmV4dEZ1bmN0aW9uKTogdm9pZCA9PiB7XG4gICAgY29uc3QgcmVmdXNlID0gKHJlYXNvbjogJ3VuYXV0aGVudGljYXRlZCcgfCAndXNlcl90b2tlbicgfCAnd3JvbmdfY2FsbGVyJyk6IHZvaWQgPT4ge1xuICAgICAgZW1pdENvdW50ZXIoJ2ludGVybmFsX3JvdXRlX3JlZnVzZWRfdG90YWwnLCB7XG4gICAgICAgIHNlcnZpY2U6IHNlcnZpY2VJZGVudGl0eSgpLFxuICAgICAgICByb3V0ZTogcmVxLnJvdXRlPy5wYXRoID8gYCR7cmVxLm1ldGhvZH0gJHtyZXEuYmFzZVVybH0ke3JlcS5yb3V0ZS5wYXRofWAgOiBgJHtyZXEubWV0aG9kfSAkeyhyZXEub3JpZ2luYWxVcmwgfHwgcmVxLnVybCkuc3BsaXQoJz8nKVswXX1gLFxuICAgICAgICByZWFzb24sXG4gICAgICAgIGNhbGxlcjogc2VydmljZU5hbWVPZihyZXEudXNlcikgPz8gJ25vbmUnLFxuICAgICAgfSk7XG4gICAgICByZWNvcmRBdXRoekRlbmlhbChyZXEsIGBpbnRlcm5hbC1zZXJ2aWNlICgke29wdGlvbnMuY2FsbGVycy5qb2luKCcsICcpfSlgKTtcbiAgICAgIGlmIChyZWFzb24gPT09ICd1bmF1dGhlbnRpY2F0ZWQnKSB7XG4gICAgICAgIHJldHVybiBzZW5kRXJyb3IocmVzLCBIdHRwU3RhdHVzLlVOQVVUSE9SSVpFRCwgJ0F1dGhlbnRpY2F0aW9uIHJlcXVpcmVkJywgRXJyb3JDb2RlLlVOQVVUSE9SSVpFRCk7XG4gICAgICB9XG4gICAgICBsb2dnZXIud2FybignUmVmdXNlZCBhbiBpbnRlcm5hbCByb3V0ZScsIHsgcmVhc29uLCBwYXRoOiAocmVxLm9yaWdpbmFsVXJsIHx8IHJlcS51cmwpLnNwbGl0KCc/JylbMF0sIGNhbGxlcjogc2VydmljZU5hbWVPZihyZXEudXNlcikgfSk7XG4gICAgICByZXR1cm4gc2VuZEVycm9yKHJlcywgSHR0cFN0YXR1cy5GT1JCSURERU4sICdJbnRlcm5hbCBzZXJ2aWNlIGNhbGxzIG9ubHknLCBFcnJvckNvZGUuSU5TVUZGSUNJRU5UX1BFUk1JU1NJT05TKTtcbiAgICB9O1xuXG4gICAgaWYgKCFyZXEudXNlcikgcmV0dXJuIHJlZnVzZSgndW5hdXRoZW50aWNhdGVkJyk7XG4gICAgaWYgKCFpc1NlcnZpY2VQcmluY2lwYWwocmVxKSkgcmV0dXJuIHJlZnVzZSgndXNlcl90b2tlbicpO1xuICAgIGNvbnN0IGNhbGxlciA9IHNlcnZpY2VOYW1lT2YocmVxLnVzZXIpO1xuICAgIGlmICghY2FsbGVyIHx8ICFhbGxvd2VkLmhhcyhjYWxsZXIpKSByZXR1cm4gcmVmdXNlKCd3cm9uZ19jYWxsZXInKTtcbiAgICBuZXh0KCk7XG4gIH0sIHsga2luZDogJ3NlcnZpY2VQcmluY2lwYWwnIH0sIHsga2luZDogJ2ludGVybmFsU2VydmljZScsIGNhbGxlcnM6IFsuLi5vcHRpb25zLmNhbGxlcnNdIH0pO1xufVxuXG4vKipcbiAqIENoZWNrIGlmIHRoZSByZXF1ZXN0IGlzIGZyb20gYSBzeXN0ZW0gYWRtaW4uXG4gKlxuICogQXV0aG9yaXR5IGlzIGdyYW50ZWQgc29sZWx5IGJ5IHRoZSB1c2VyLWxldmVsIGBpc1N1cGVyQWRtaW5gIGZsYWcgY2FycmllZFxuICogaW4gdGhlIEpXVCDigJQgbmV2ZXIgYnkgbWVtYmVyc2hpcCBpbiB0aGUgd2VsbC1rbm93biAnc3lzdGVtJyBvcmcsIHdoaWNoIHdvdWxkXG4gKiBjb25mbGF0ZSBhIFBpcGVsaW5lIEJ1aWxkZXIgb3BlcmF0b3Igd2l0aCBhIGN1c3RvbWVyIHRlbmFudCBhbmQgbGV0IGFueVxuICogd3JpdGUgdGhhdCBjcmVhdGVkIGEgJ3N5c3RlbSctbmFtZWQgb3JnIHF1aWV0bHkgZ3JhbnQgY3Jvc3Mtb3JnIGF1dGhvcml0eS4gVGhlIGBzeXN0ZW1gIG9yZyBzdGlsbCBleGlzdHMgYXMgYSAqY29udGVudCBob2xkZXIqIGZvciBzaGFyZWRcbiAqIHNhbXBsZSBkYXRhOyBpdCBjb25mZXJzIG5vIHByaXZpbGVnZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzU3lzdGVtQWRtaW4ocmVxOiBSZXF1ZXN0KTogYm9vbGVhbiB7XG4gIHJldHVybiByZXEudXNlcj8uaXNTdXBlckFkbWluID09PSB0cnVlO1xufVxuXG4vKipcbiAqIFdoZXRoZXIgdGhlIHJlcXVlc3QncyB0b2tlbiBjYXJyaWVzIGEgc3BlY2lmaWMgY2FwYWJpbGl0eSBgc2NvcGVgIChlLmcuXG4gKiBgJ3JlcG9ydGluZzppbmdlc3QnYCkuIFVzZWQgdG8gZ2F0ZSBlbmRwb2ludHMgdGhhdCBhY2NlcHQgYSBuYXJyb3cgbWFjaGluZVxuICogaWRlbnRpdHkg4oCUIGEgbm9ybWFsIGludGVyYWN0aXZlIHVzZXIgdG9rZW4gaGFzIG5vIGBzY29wZWAgYW5kIHJldHVybnMgZmFsc2UuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBoYXNTY29wZShyZXE6IFJlcXVlc3QsIHNjb3BlOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgcmV0dXJuIHJlcS51c2VyPy5zY29wZSA9PT0gc2NvcGU7XG59XG5cbi8qKiBSZXF1aXJlcyBhIHN5c3RlbSBhZG1pbiDigJQgZ3JhbnRlZCBzb2xlbHkgYnkgdGhlIGBpc1N1cGVyQWRtaW5gIHRva2VuIGNsYWltLlxuICogIFVzZSBhZnRlciByZXF1aXJlQXV0aC4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXF1aXJlU3lzdGVtQWRtaW4oXG4gIHJlcTogUmVxdWVzdCxcbiAgcmVzOiBSZXNwb25zZSxcbiAgbmV4dDogTmV4dEZ1bmN0aW9uLFxuKTogdm9pZCB7XG4gIGlmICghaXNTeXN0ZW1BZG1pbihyZXEpKSB7XG4gICAgcmVjb3JkQXV0aHpEZW5pYWwocmVxLCAnc3lzdGVtLWFkbWluJyk7XG4gICAgcmV0dXJuIHNlbmRFcnJvcihcbiAgICAgIHJlcywgSHR0cFN0YXR1cy5GT1JCSURERU4sXG4gICAgICAnQWNjZXNzIGRlbmllZC4gT25seSBzeXN0ZW0gYWRtaW5pc3RyYXRvcnMgY2FuIHBlcmZvcm0gdGhpcyBhY3Rpb24uJyxcbiAgICAgIEVycm9yQ29kZS5JTlNVRkZJQ0lFTlRfUEVSTUlTU0lPTlMsXG4gICAgKTtcbiAgfVxuICBuZXh0KCk7XG59XG50YWdSb3V0ZUdhdGUocmVxdWlyZVN5c3RlbUFkbWluLCB7IGtpbmQ6ICdzeXN0ZW1BZG1pbicgfSk7XG5cbi8qKlxuICogUmVxdWlyZSBhIHNwZWNpZmljIGZlYXR1cmUgZmxhZy4gVXNlIGFmdGVyIHJlcXVpcmVBdXRoLlxuICogQ2hlY2tzIHRoZSBgZmVhdHVyZXNgIGFycmF5IGluIHRoZSBKV1QgcGF5bG9hZCAoc2V0IGF0IHRva2VuIGlzc3VhbmNlKS5cbiAqIFN5c2FkbWlucyAoaXNTdXBlckFkbWluKSBieXBhc3Mg4oCUIHRoZXkgYWx3YXlzIGhhdmUgZXZlcnkgZmVhdHVyZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlcXVpcmVGZWF0dXJlKGZlYXR1cmU6IHN0cmluZykge1xuICByZXR1cm4gdGFnUm91dGVHYXRlKChyZXE6IFJlcXVlc3QsIHJlczogUmVzcG9uc2UsIG5leHQ6IE5leHRGdW5jdGlvbik6IHZvaWQgPT4ge1xuICAgIGlmICghcmVxdWlyZVVzZXIocmVxLCByZXMpKSByZXR1cm47XG5cbiAgICAvLyBTeXNhZG1pbnMgZ2V0IGFsbCBmZWF0dXJlczsgdGhlIGBmZWF0dXJlc2AgYXJyYXkgb24gdGhlaXIgdG9rZW4gaXNcbiAgICAvLyBwb3B1bGF0ZWQgd2l0aCBldmVyeSBmbGFnIGF0IGlzc3VhbmNlIHRpbWUgYnV0IHRoZSBieXBhc3MgaGVyZSBrZWVwc1xuICAgIC8vIHRoZSBydWxlIGV4cGxpY2l0IGFuZCBzdXJ2aXZlcyBhIHRva2VuIGlzc3VlZCBiZWZvcmUgYSBuZXcgZmVhdHVyZVxuICAgIC8vIGZsYWcgd2FzIGFkZGVkLlxuICAgIGlmIChyZXEudXNlci5pc1N1cGVyQWRtaW4gPT09IHRydWUpIHJldHVybiBuZXh0KCk7XG5cbiAgICBpZiAoIXJlcS51c2VyLmZlYXR1cmVzPy5pbmNsdWRlcyhmZWF0dXJlKSkge1xuICAgICAgLy8gUm91dGUgZmVhdHVyZS1nYXRlIGRlbmlhbHMgdGhyb3VnaCB0aGUgc2FtZSBhdWRpdCBzaW5rIGFzXG4gICAgICAvLyByZXF1aXJlUGVybWlzc2lvbiAvIHJlcXVpcmVTeXN0ZW1BZG1pbiBzbyBhIHByb2JlIGZvciBhblxuICAgICAgLy8gdW5lbnRpdGxlZCBjYXBhYmlsaXR5IGxlYXZlcyBhIHRyYWlsIChzdGF0ZS1jaGFuZ2luZyBtZXRob2RzIG9ubHkpLlxuICAgICAgcmVjb3JkQXV0aHpEZW5pYWwocmVxLCBgZmVhdHVyZToke2ZlYXR1cmV9YCk7XG4gICAgICByZXR1cm4gc2VuZEVycm9yKFxuICAgICAgICByZXMsIEh0dHBTdGF0dXMuRk9SQklEREVOLFxuICAgICAgICBgVGhpcyBmZWF0dXJlIHJlcXVpcmVzIGEgaGlnaGVyIHBsYW4gKCR7ZmVhdHVyZX0pYCxcbiAgICAgICAgRXJyb3JDb2RlLklOU1VGRklDSUVOVF9QRVJNSVNTSU9OUyxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgbmV4dCgpO1xuICB9LCB7IGtpbmQ6ICdmZWF0dXJlJywgZmVhdHVyZSB9KTtcbn1cblxuIl19
266
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGVybWlzc2lvbi1nYXRlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9taWRkbGV3YXJlL3Blcm1pc3Npb24tZ2F0ZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQVF0QyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDaEQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLGFBQWEsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3hFLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUN6RCxPQUFPLEVBQUUsY0FBYyxFQUFFLG1CQUFtQixFQUFFLHFCQUFxQixFQUFFLGlCQUFpQixFQUF1QixNQUFNLDhCQUE4QixDQUFDO0FBQ2xKLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUM5RCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDcEQsT0FBTyxFQUFtQixhQUFhLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUN6RSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDbEQsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ3pELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUVqRCxNQUFNLE1BQU0sR0FBRyxZQUFZLENBQUMsaUJBQWlCLENBQUMsQ0FBQztBQUMvQzs7OztHQUlHO0FBQ0gsTUFBTSxVQUFVLGlCQUFpQixDQUFDLEdBQVksRUFBRSxVQUFzQjtJQUNwRSxPQUFPLGFBQWEsQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLFdBQVcsRUFBRSxVQUFVLEVBQUUsR0FBRyxDQUFDLElBQUksRUFBRSxZQUFZLENBQUMsQ0FBQztBQUNsRixDQUFDO0FBOEJEOzs7Ozs7O0dBT0c7QUFDSCxJQUFJLGtCQUFpRSxDQUFDO0FBRXRFOzs7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QVMsQ0FBQyx3QkFBd0IsQ0FDbkMsQ0FBQztJQUNKLENBQUM7SUFDRCxJQUFJLEVBQUUsQ0FBQztBQUNULENBQUM7QUFDRCxZQUFZLENBQUMsa0JBQWtCLEVBQUUsRUFBRSxJQUFJLEVBQUUsYUFBYSxFQUFFLENBQUMsQ0FBQztBQUUxRDs7OztHQUlHO0FBQ0gsTUFBTSxVQUFVLGNBQWMsQ0FBQyxPQUFlO0lBQzVDLE9BQU8sWUFBWSxDQUFDLENBQUMsR0FBWSxFQUFFLEdBQWEsRUFBRSxJQUFrQixFQUFRLEVBQUU7UUFDNUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDO1lBQUUsT0FBTztRQUVuQyxxRUFBcUU7UUFDckUsdUVBQXVFO1FBQ3ZFLHFFQUFxRTtRQUNyRSxrQkFBa0I7UUFDbEIsSUFBSSxHQUFHLENBQUMsSUFBSSxDQUFDLFlBQVksS0FBSyxJQUFJO1lBQUUsT0FBTyxJQUFJLEVBQUUsQ0FBQztRQUVsRCxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsUUFBUSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7WUFDMUMsNERBQTREO1lBQzVELDJEQUEyRDtZQUMzRCxzRUFBc0U7WUFDdEUsaUJBQWlCLENBQUMsR0FBRyxFQUFFLFdBQVcsT0FBTyxFQUFFLENBQUMsQ0FBQztZQUM3QyxPQUFPLFNBQVMsQ0FDZCxHQUFHLEVBQUUsVUFBVSxDQUFDLFNBQVMsRUFDekIsd0NBQXdDLE9BQU8sR0FBRyxFQUNsRCxTQUFTLENBQUMsd0JBQXdCLENBQ25DLENBQUM7UUFDSixDQUFDO1FBRUQsSUFBSSxFQUFFLENBQUM7SUFDVCxDQUFDLEVBQUUsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxDQUFDLENBQUM7QUFDbkMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDI2IFBpcGVsaW5lIEJ1aWxkZXIgQ29udHJpYnV0b3JzXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuXG4vKipcbiAqIEF1dGhvcml6YXRpb24gZ2F0ZXMg4oCUIHBlcm1pc3Npb25zLCBzeXN0ZW0gYWRtaW4sIGZlYXR1cmVzIOKAlCBhbmQgdGhlXG4gKiBgYXV0aHouZGVuaWVkYCBhdWRpdCBzaW5rIHRoZXkgcmVwb3J0IHJlZnVzYWxzIHRvLlxuICovXG5cbmltcG9ydCB0eXBlIHsgUmVxdWVzdCwgUmVzcG9uc2UsIE5leHRGdW5jdGlvbiB9IGZyb20gJ2V4cHJlc3MnO1xuaW1wb3J0IHsgdGFnUm91dGVHYXRlIH0gZnJvbSAnLi9yb3V0ZS10YWJsZS5qcyc7XG5pbXBvcnQgeyBpc1NlcnZpY2VQcmluY2lwYWwsIHNlcnZpY2VOYW1lT2YgfSBmcm9tICcuL3NlcnZpY2UtdG9rZW5zLmpzJztcbmltcG9ydCB7IEh0dHBTdGF0dXMgfSBmcm9tICcuLi9jb25zdGFudHMvaHR0cC1zdGF0dXMuanMnO1xuaW1wb3J0IHsgYXVkaXRBdXRoQmxvY2ssIGN1cnJlbnRBdWRpdENvbnRleHQsIHNhbml0aXplQ29ycmVsYXRpb25JZCwgc2FuaXRpemVVc2VyQWdlbnQsIHR5cGUgQXVkaXRBdXRoQmxvY2sgfSBmcm9tICcuLi9zZXJ2aWNlcy9hdWRpdC1jb250ZXh0LmpzJztcbmltcG9ydCB7IHNlcnZpY2VJZGVudGl0eSB9IGZyb20gJy4uL3NlcnZpY2VzL3NlcnZpY2Uta2V5cy5qcyc7XG5pbXBvcnQgeyBFcnJvckNvZGUgfSBmcm9tICcuLi90eXBlcy9lcnJvci1jb2Rlcy5qcyc7XG5pbXBvcnQgeyB0eXBlIFBlcm1pc3Npb24sIGhhc1Blcm1pc3Npb24gfSBmcm9tICcuLi90eXBlcy9wZXJtaXNzaW9ucy5qcyc7XG5pbXBvcnQgeyBjcmVhdGVMb2dnZXIgfSBmcm9tICcuLi91dGlscy9sb2dnZXIuanMnO1xuaW1wb3J0IHsgZW1pdENvdW50ZXIgfSBmcm9tICcuLi91dGlscy9tZXRyaWMtZW1pdHRlci5qcyc7XG5pbXBvcnQgeyBzZW5kRXJyb3IgfSBmcm9tICcuLi91dGlscy9yZXNwb25zZS5qcyc7XG5cbmNvbnN0IGxvZ2dlciA9IGNyZWF0ZUxvZ2dlcignYXV0aC1taWRkbGV3YXJlJyk7XG4vKipcbiAqIFdoZXRoZXIgdGhlIHJlcXVlc3QncyB1c2VyIGhvbGRzIGBwZXJtaXNzaW9uYC4gU3VwZXJhZG1pbnMgaW1wbGljaXRseSBob2xkXG4gKiBldmVyeSBwZXJtaXNzaW9uLiBSZWFkcyB0aGUgcmVzb2x2ZWQgYHBlcm1pc3Npb25zYCBjbGFpbSAoc2V0IGF0IHRva2VuIGlzc3VlLFxuICogb3IgcmUtZGVyaXZlZCBwZXIgcmVxdWVzdCBieSB0aGUgcGxhdGZvcm0pLlxuICovXG5leHBvcnQgZnVuY3Rpb24gdXNlckhhc1Blcm1pc3Npb24ocmVxOiBSZXF1ZXN0LCBwZXJtaXNzaW9uOiBQZXJtaXNzaW9uKTogYm9vbGVhbiB7XG4gIHJldHVybiBoYXNQZXJtaXNzaW9uKHJlcS51c2VyPy5wZXJtaXNzaW9ucywgcGVybWlzc2lvbiwgcmVxLnVzZXI/LmlzU3VwZXJBZG1pbik7XG59XG5cbi8qKlxuICogQ29udGV4dCBwYXNzZWQgdG8gYSByZWdpc3RlcmVkIGF1dGhvcml6YXRpb24tZGVuaWFsIGF1ZGl0b3Igd2hlbiBhXG4gKiBzdGF0ZS1jaGFuZ2luZyByZXF1ZXN0IGlzIHJlamVjdGVkIGJ5IGByZXF1aXJlUGVybWlzc2lvbmAgL1xuICogYHJlcXVpcmVTeXN0ZW1BZG1pbmAuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQXV0aHpEZW5pYWxJbmZvIHtcbiAgLyoqIFRoZSBkZW5pZWQgdXNlcidzIGlkIChgc3ViYCksIGlmIGF1dGhlbnRpY2F0ZWQuICovXG4gIGFjdG9ySWQ/OiBzdHJpbmc7XG4gIGFjdG9yRW1haWw/OiBzdHJpbmc7XG4gIC8qKiBUaGUgdXNlcidzIGFjdGl2ZSBvcmcgYXQgZGVuaWFsIHRpbWUuICovXG4gIG9yZ0lkPzogc3RyaW5nO1xuICAvKiogSFRUUCBtZXRob2QgKyBwYXRoIG9mIHRoZSByZWplY3RlZCByZXF1ZXN0LiAqL1xuICBtZXRob2Q6IHN0cmluZztcbiAgcGF0aDogc3RyaW5nO1xuICAvKiogV2hhdCB3YXMgcmVxdWlyZWQ6IHRoZSBtaXNzaW5nIHBlcm1pc3Npb24ocyksIG9yICdzeXN0ZW0tYWRtaW4nLiAqL1xuICByZXF1aXJlZDogc3RyaW5nO1xuICAvKiogQ2xpZW50IGlwIChgcmVxLmlwYCwgcHJveHktcmVzb2x2ZWQpLiAqL1xuICBpcD86IHN0cmluZztcbiAgLyoqIFNhbml0aXplZCwgbGVuZ3RoLWNhcHBlZCBVc2VyLUFnZW50LiAqL1xuICB1c2VyQWdlbnQ/OiBzdHJpbmc7XG4gIC8qKiBUaGUgcmVxdWVzdCdzIGNvcnJlbGF0aW9uIGlkICh0aGUgYW1iaWVudCBhdWRpdCBjb250ZXh0J3MsIGVsc2UgYSB2YWxpZCBgWC1SZXF1ZXN0LUlkYCkuICovXG4gIHJlcXVlc3RJZD86IHN0cmluZztcbiAgLyoqIFRoZSByZWFsIHN5c2FkbWluIGJlaGluZCBhbiBpbXBlcnNvbmF0aW9uIHRva2VuLCBmcm9tIHRoZSB2ZXJpZmllZCB0b2tlbi4gKi9cbiAgaW1wZXJzb25hdG9ySWQ/OiBzdHJpbmc7XG4gIC8qKiBUaGUgY3JlZGVudGlhbCB0aGF0IHdhcyByZWZ1c2VkIChrZXkgaWQsIHNlc3Npb24sIHNjb3BlLCDigKYpIOKAlCB0aGUgYF9hdXRoYCBibG9jay4gKi9cbiAgYXV0aD86IEF1ZGl0QXV0aEJsb2NrO1xufVxuXG4vKipcbiAqIE9wdGlvbmFsIHNpbmsgZm9yIGRlbmllZC1hdXRob3JpemF0aW9uIGV2ZW50cy4gTGVmdCB1bnNldCBieSBkZWZhdWx0IHNvXG4gKiBhcGktY29yZSBzdGF5cyBkZWNvdXBsZWQgZnJvbSBhbnkgYXVkaXQgdHJhbnNwb3J0IOKAlCBhIHNlcnZpY2UgcmVnaXN0ZXJzIG9uZVxuICogYXQgYm9vdCAodHlwaWNhbGx5IGZvcndhcmRpbmcgdG8gaXRzIGBSZW1vdGVBdWRpdENsaWVudGAgYXMgYW5cbiAqIGBhdXRoei5kZW5pZWRgIGV2ZW50LCBvciwgb24gcGxhdGZvcm0sIHRvIHRoZSBsb2NhbCBgYXVkaXQoKWAgaGVscGVyKS5cbiAqIE1VU1QgYmUgYmVzdC1lZmZvcnQ6IGl0IGlzIGludm9rZWQgaW5zaWRlIHRoZSByZXF1ZXN0IHBhdGgsIHNvIGl0IG11c3QgbmV2ZXJcbiAqIHRocm93IG9yIGJsb2NrICh0aGUgZ2F0ZSB3cmFwcyB0aGUgY2FsbCBpbiB0cnkvY2F0Y2ggcmVnYXJkbGVzcykuXG4gKi9cbmxldCBhdXRoekRlbmlhbEF1ZGl0b3I6ICgoaW5mbzogQXV0aHpEZW5pYWxJbmZvKSA9PiB2b2lkKSB8IHVuZGVmaW5lZDtcblxuLyoqXG4gKiBSZWdpc3RlciAob3IgY2xlYXIsIHdpdGggYHVuZGVmaW5lZGApIHRoZSBwcm9jZXNzLXdpZGUgYXV0aG9yaXphdGlvbi1kZW5pYWxcbiAqIGF1ZGl0b3IuIElkZW1wb3RlbnQ7IHRoZSBsYXN0IHJlZ2lzdHJhdGlvbiB3aW5zLlxuICovXG5leHBvcnQgZnVuY3Rpb24gc2V0QXV0aHpEZW5pYWxBdWRpdG9yKGZuOiAoKGluZm86IEF1dGh6RGVuaWFsSW5mbykgPT4gdm9pZCkgfCB1bmRlZmluZWQpOiB2b2lkIHtcbiAgYXV0aHpEZW5pYWxBdWRpdG9yID0gZm47XG59XG5cbi8qKlxuICogRW1pdCBhIGRlbmlhbCBldmVudCwgYmVzdC1lZmZvcnQuIE9ubHkgZmlyZXMgZm9yIHN0YXRlLWNoYW5naW5nIChub24tR0VULFxuICogbm9uLUhFQUQvT1BUSU9OUykgcmVxdWVzdHMg4oCUIGEgcmVqZWN0ZWQgR0VUIGlzIGxvdy1zaWduYWwgcHJvYmluZyBub2lzZSBhbmRcbiAqIHdvdWxkIGFtcGxpZnkgYXVkaXQgdm9sdW1lIHVuZGVyIGEgc2Nhbi4gTmV2ZXIgdGhyb3dzLlxuICpcbiAqIFRoZSBwZXJtaXNzaW9uIGdhdGVzIGhlcmUgY2FsbCBpdCB0aGVtc2VsdmVzLiBFeHBvcnQgaXQgZm9yIGRhdGEtZHJpdmVuIGNoZWNrc1xuICogYSByb3V0ZSBtYWtlcyBpbmxpbmUgKGNyb3NzLW9yZyBhY2Nlc3MsIHNlcnZpY2Utb25seSBlbmRwb2ludHMpLCBzbyB0aG9zZSA0MDNzXG4gKiByZWFjaCB0aGUgc2FtZSBgYXV0aHouZGVuaWVkYCB0cmFpbC4gYHJlcXVpcmVkYCBuYW1lcyB3aGF0IHdhcyBtaXNzaW5nLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVjb3JkQXV0aHpEZW5pYWwocmVxOiBSZXF1ZXN0LCByZXF1aXJlZDogc3RyaW5nKTogdm9pZCB7XG4gIGNvbnN0IGF1ZGl0b3IgPSBhdXRoekRlbmlhbEF1ZGl0b3I7XG4gIGlmICghYXVkaXRvcikgcmV0dXJuO1xuICBjb25zdCBtZXRob2QgPSByZXEubWV0aG9kLnRvVXBwZXJDYXNlKCk7XG4gIGlmIChtZXRob2QgPT09ICdHRVQnIHx8IG1ldGhvZCA9PT0gJ0hFQUQnIHx8IG1ldGhvZCA9PT0gJ09QVElPTlMnKSByZXR1cm47XG4gIHRyeSB7XG4gICAgYXVkaXRvcih7XG4gICAgICBhY3RvcklkOiByZXEudXNlcj8uc3ViLFxuICAgICAgYWN0b3JFbWFpbDogcmVxLnVzZXI/LmVtYWlsLFxuICAgICAgb3JnSWQ6IHJlcS51c2VyPy5vcmdhbml6YXRpb25JZCxcbiAgICAgIG1ldGhvZCxcbiAgICAgIC8vIFN0cmlwIHRoZSBxdWVyeSBzdHJpbmcg4oCUIGEgZGVuaWVkIHJlcXVlc3QgbWF5IGNhcnJ5IGEgdG9rZW4vc2VjcmV0IGFzIGFcbiAgICAgIC8vIHF1ZXJ5IHBhcmFtLCBhbmQgdGhpcyBwYXRoIGlzIHBlcnNpc3RlZCB2ZXJiYXRpbSBpbnRvIHRoZSBhdWRpdCBsb2cuXG4gICAgICBwYXRoOiAocmVxLm9yaWdpbmFsVXJsIHx8IHJlcS51cmwpLnNwbGl0KCc/JylbMF0sXG4gICAgICByZXF1aXJlZCxcbiAgICAgIGlwOiByZXEuaXAsXG4gICAgICB1c2VyQWdlbnQ6IHNhbml0aXplVXNlckFnZW50KHJlcS5oZWFkZXJzPy5bJ3VzZXItYWdlbnQnXSksXG4gICAgICByZXF1ZXN0SWQ6IGN1cnJlbnRBdWRpdENvbnRleHQoKT8ucmVxdWVzdElkID8/IHNhbml0aXplQ29ycmVsYXRpb25JZChyZXEuaGVhZGVycz8uWyd4LXJlcXVlc3QtaWQnXSksXG4gICAgICBpbXBlcnNvbmF0b3JJZDogcmVxLnVzZXI/LmltcGVyc29uYXRvcklkLFxuICAgICAgYXV0aDogYXVkaXRBdXRoQmxvY2socmVxLnVzZXIpLFxuICAgIH0pO1xuICB9IGNhdGNoIHtcbiAgICAvLyBCZXN0LWVmZm9ydCDigJQgYSBicm9rZW4gYXVkaXRvciBtdXN0IG5ldmVyIGJyZWFrIHRoZSBhdXRoIGdhdGUuXG4gIH1cbn1cblxuLyoqIFRoZSBzaGFyZWQgZ2F0ZSBwcmVhbWJsZTogYW5zd2VyIDQwMSBhbmQgcmV0dXJuIGZhbHNlIHdoZW4gdW5hdXRoZW50aWNhdGVkLiAqL1xuZnVuY3Rpb24gcmVxdWlyZVVzZXIocmVxOiBSZXF1ZXN0LCByZXM6IFJlc3BvbnNlKTogcmVxIGlzIFJlcXVlc3QgJiB7IHVzZXI6IE5vbk51bGxhYmxlPFJlcXVlc3RbJ3VzZXInXT4gfSB7XG4gIGlmIChyZXEudXNlcikgcmV0dXJuIHRydWU7XG4gIHNlbmRFcnJvcihyZXMsIEh0dHBTdGF0dXMuVU5BVVRIT1JJWkVELCAnQXV0aGVudGljYXRpb24gcmVxdWlyZWQnLCBFcnJvckNvZGUuVU5BVVRIT1JJWkVEKTtcbiAgcmV0dXJuIGZhbHNlO1xufVxuXG4vKiogQXVkaXQgKyBhbnN3ZXIgYSBwZXJtaXNzaW9uIHJlZnVzYWwgKGBtaXNzaW5nYCBkZWZhdWx0cyB0byBldmVyeSByZXF1aXJlZCBwZXJtaXNzaW9uKS4gKi9cbmZ1bmN0aW9uIGRlbnlQZXJtaXNzaW9uKHJlcTogUmVxdWVzdCwgcmVzOiBSZXNwb25zZSwgcGVybWlzc2lvbnM6IFBlcm1pc3Npb25bXSwgbW9kZTogJ29yJyB8ICdhbmQnLCBtaXNzaW5nOiBQZXJtaXNzaW9uW10gPSBwZXJtaXNzaW9ucyk6IHZvaWQge1xuICByZWNvcmRBdXRoekRlbmlhbChyZXEsIHBlcm1pc3Npb25zLmpvaW4oYCAke21vZGV9IGApKTtcbiAgc2VuZEVycm9yKFxuICAgIHJlcywgSHR0cFN0YXR1cy5GT1JCSURERU4sXG4gICAgYE1pc3NpbmcgcmVxdWlyZWQgcGVybWlzc2lvbjogJHttaXNzaW5nLmpvaW4oYCAke21vZGV9IGApfWAsXG4gICAgRXJyb3JDb2RlLklOU1VGRklDSUVOVF9QRVJNSVNTSU9OUyxcbiAgKTtcbn1cblxuLyoqXG4gKiBSZXF1aXJlcyB0aGF0IHRoZSB1c2VyIGhvbGQgQVQgTEVBU1QgT05FIG9mIHRoZSBnaXZlbiBwZXJtaXNzaW9ucyAob3IgYmUgYVxuICogc3VwZXJhZG1pbikuIFVzZSBhZnRlciByZXF1aXJlQXV0aC4gTWlycm9ycyBgcmVxdWlyZVJvbGVgJ3MgYW55LW9mIHNlbWFudGljcztcbiAqIHBhc3MgYSBzaW5nbGUgcGVybWlzc2lvbiBmb3IgYSBzcGVjaWZpYyBhY3Rpb24sIG9yIHNldmVyYWwgd2hlbiBhbnkgb25lIG9mXG4gKiB0aGVtIHNob3VsZCBncmFudCBhY2Nlc3MuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXF1aXJlUGVybWlzc2lvbiguLi5wZXJtaXNzaW9uczogUGVybWlzc2lvbltdKSB7XG4gIHJldHVybiB0YWdSb3V0ZUdhdGUoKHJlcTogUmVxdWVzdCwgcmVzOiBSZXNwb25zZSwgbmV4dDogTmV4dEZ1bmN0aW9uKTogdm9pZCA9PiB7XG4gICAgaWYgKCFyZXF1aXJlVXNlcihyZXEsIHJlcykpIHJldHVybjtcbiAgICAvLyB1c2VySGFzUGVybWlzc2lvbiDihpIgaGFzUGVybWlzc2lvbiBhbHJlYWR5IGdyYW50cyBzdXBlcmFkbWlucyBldmVyeVxuICAgIC8vIHBlcm1pc3Npb24sIHNvIHRoaXMgc2luZ2xlIGNoZWNrIGNvdmVycyBib3RoIHRoZSBzdXBlcmFkbWluIGJ5cGFzcyBhbmRcbiAgICAvLyB0aGUgYW55LW9mIG1lbWJlcnNoaXAgdGVzdCB3aXRob3V0IHJlLWlubGluaW5nIGVpdGhlci5cbiAgICBpZiAocGVybWlzc2lvbnMuc29tZSgocCkgPT4gdXNlckhhc1Blcm1pc3Npb24ocmVxLCBwKSkpIHJldHVybiBuZXh0KCk7XG4gICAgZGVueVBlcm1pc3Npb24ocmVxLCByZXMsIHBlcm1pc3Npb25zLCAnb3InKTtcbiAgfSwgeyBraW5kOiAncGVybWlzc2lvbicsIG1vZGU6ICdhbnknLCBwZXJtaXNzaW9ucyB9KTtcbn1cblxuLyoqXG4gKiBSZXF1aXJlcyB0aGF0IHRoZSB1c2VyIGhvbGQgRVZFUlkgb25lIG9mIHRoZSBnaXZlbiBwZXJtaXNzaW9ucyAob3IgYmUgYVxuICogc3VwZXJhZG1pbikg4oCUIHRoZSBBTkQgY291bnRlcnBhcnQgdG8gYHJlcXVpcmVQZXJtaXNzaW9uYCdzIGFueS1vZi4gVXNlIGZvciBhXG4gKiBzZW5zaXRpdmUgYWN0aW9uIHRoYXQgbGVnaXRpbWF0ZWx5IGRlbWFuZHMgdHdvIGRpc3RpbmN0IGNhcGFiaWxpdGllcyBhdCBvbmNlXG4gKiAoZS5nLiBhIGNyb3NzLXN1cmZhY2Ugb3BlcmF0aW9uKSwgc28gdGhlIGd1YXJhbnRlZSBpcyBleHBsaWNpdCByYXRoZXIgdGhhblxuICogYXBwcm94aW1hdGVkIGJ5IGNoYWluaW5nIHR3byBgcmVxdWlyZVBlcm1pc3Npb25gIGdhdGVzLiBTdXBlcmFkbWlucyBieXBhc3NcbiAqICh0aGV5IGltcGxpY2l0bHkgaG9sZCBldmVyeSBwZXJtaXNzaW9uKS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlcXVpcmVBbGxQZXJtaXNzaW9ucyguLi5wZXJtaXNzaW9uczogUGVybWlzc2lvbltdKSB7XG4gIHJldHVybiB0YWdSb3V0ZUdhdGUoKHJlcTogUmVxdWVzdCwgcmVzOiBSZXNwb25zZSwgbmV4dDogTmV4dEZ1bmN0aW9uKTogdm9pZCA9PiB7XG4gICAgaWYgKCFyZXF1aXJlVXNlcihyZXEsIHJlcykpIHJldHVybjtcbiAgICBjb25zdCBtaXNzaW5nID0gcGVybWlzc2lvbnMuZmlsdGVyKChwKSA9PiAhdXNlckhhc1Blcm1pc3Npb24ocmVxLCBwKSk7XG4gICAgaWYgKG1pc3NpbmcubGVuZ3RoID09PSAwKSByZXR1cm4gbmV4dCgpO1xuICAgIGRlbnlQZXJtaXNzaW9uKHJlcSwgcmVzLCBwZXJtaXNzaW9ucywgJ2FuZCcsIG1pc3NpbmcpO1xuICB9LCB7IGtpbmQ6ICdwZXJtaXNzaW9uJywgbW9kZTogJ2FsbCcsIHBlcm1pc3Npb25zIH0pO1xufVxuXG4vKipcbiAqIExpa2Uge0BsaW5rIHJlcXVpcmVQZXJtaXNzaW9ufSAoYW55LW9mKSBidXQgQUxTTyBhZG1pdHMgYW4gaW50ZXJuYWwgc2VydmljZVxuICogcHJpbmNpcGFsIChgcHJpbmNpcGFsVHlwZTogJ3NlcnZpY2UnYCkuIEZvciBSRUFEIGVuZHBvaW50cyB0aGF0IEJPVEhcbiAqIGludGVyYWN0aXZlIHVzZXJzIOKAlCB3aG8gbXVzdCBob2xkIG9uZSBvZiB0aGUgYDpyZWFkYCBjYXBhYmlsaXRpZXMg4oCUIEFORFxuICogc2VydmljZS10by1zZXJ2aWNlIGNhbGxlcnMgbGVnaXRpbWF0ZWx5IGhpdDsgc2VydmljZSB0b2tlbnMgY2Fycnkgbm9cbiAqIHBlcm1pc3Npb24gY2xhaW1zICh0aGV5J3JlIGxlYXN0LXByaXZpbGVnZSBgcm9sZTptZW1iZXJgKSwgc28gYSBwbGFpblxuICogYHJlcXVpcmVQZXJtaXNzaW9uYCB3b3VsZCB3cm9uZ2x5IDQwMyB0aGVtLiBTdXBlcmFkbWlucyBwYXNzIHZpYVxuICogYHVzZXJIYXNQZXJtaXNzaW9uYCdzIGltcGxpY2l0LWFsbC4gVXNlIG9ubHkgd2hlcmUgYSBzZXJ2aWNlIGNhbGxlciBpcyBhIGtub3duLFxuICogaW50ZW5kZWQgY29uc3VtZXIgb2YgdGhlIHJvdXRlICh2ZXJpZnkgdGhlIGNhbGxlcnMpOyBwcmVmZXIgcGxhaW5cbiAqIGByZXF1aXJlUGVybWlzc2lvbmAgZm9yIHB1cmVseSB1c2VyLWZhY2luZyByZWFkcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlcXVpcmVQZXJtaXNzaW9uT3JTZXJ2aWNlKC4uLnBlcm1pc3Npb25zOiBQZXJtaXNzaW9uW10pIHtcbiAgcmV0dXJuIHRhZ1JvdXRlR2F0ZSgocmVxOiBSZXF1ZXN0LCByZXM6IFJlc3BvbnNlLCBuZXh0OiBOZXh0RnVuY3Rpb24pOiB2b2lkID0+IHtcbiAgICBpZiAoIXJlcXVpcmVVc2VyKHJlcSwgcmVzKSkgcmV0dXJuO1xuICAgIGlmIChpc1NlcnZpY2VQcmluY2lwYWwocmVxKSB8fCBwZXJtaXNzaW9ucy5zb21lKChwKSA9PiB1c2VySGFzUGVybWlzc2lvbihyZXEsIHApKSkgcmV0dXJuIG5leHQoKTtcbiAgICBkZW55UGVybWlzc2lvbihyZXEsIHJlcywgcGVybWlzc2lvbnMsICdvcicpO1xuICB9LCB7IGtpbmQ6ICdwZXJtaXNzaW9uJywgbW9kZTogJ2FueScsIHBlcm1pc3Npb25zLCBhbGxvd1NlcnZpY2U6IHRydWUgfSk7XG59XG5cbi8qKlxuICogR2F0ZSBhbiBlbmRwb2ludCB0byBpbnRlcm5hbCBzZXJ2aWNlLXRvLXNlcnZpY2UgY2FsbGVycyBvbmx5IChhXG4gKiBgcHJpbmNpcGFsVHlwZTogJ3NlcnZpY2UnYCBwcmluY2lwYWwgbWludGVkIHZpYSB7QGxpbmsgc2lnblNlcnZpY2VUb2tlbn0gLyBgZ2V0U2VydmljZUF1dGhIZWFkZXJgKS5cbiAqIFJlamVjdHMgYW55IHVzZXIgdG9rZW4uIEZvciBOT04tdXNlci1mYWNpbmcgZW5kcG9pbnRzIOKAlCBlbnRpdHktZXZlbnQgaW5nZXN0LFxuICogYXV0by1zdWJzY3JpYmUsIGFuZCBzaW1pbGFyIHBlZXItc2VydmljZSBob29rcyDigJQgdGhhdCBhIGJyb3dzZXIgbXVzdCBuZXZlclxuICogcmVhY2guIENvbXBvc2UgYWZ0ZXIgYHJlcXVpcmVBdXRoYCBzbyBgcmVxLnVzZXJgIGlzIHBvcHVsYXRlZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlcXVpcmVTZXJ2aWNlUHJpbmNpcGFsKHJlcTogUmVxdWVzdCwgcmVzOiBSZXNwb25zZSwgbmV4dDogTmV4dEZ1bmN0aW9uKTogdm9pZCB7XG4gIGlmICghaXNTZXJ2aWNlUHJpbmNpcGFsKHJlcSkpIHtcbiAgICAvLyA0MDMgKG5vdCA0MDApIOKAlCB0aGlzIGlzIGFuIGF1dGhvcml6YXRpb24gcmVmdXNhbDsgc3RhdHVzIG11c3QgbWF0Y2ggdGhlXG4gICAgLy8gSU5TVUZGSUNJRU5UX1BFUk1JU1NJT05TIGNvZGUgYW5kIHRoZSBzaWJsaW5nIGdhdGVzIChyZXF1aXJlUGVybWlzc2lvbiwgZXRjLikuXG4gICAgcmV0dXJuIHNlbmRFcnJvcihyZXMsIEh0dHBTdGF0dXMuRk9SQklEREVOLCAnSW50ZXJuYWwgc2VydmljZSBjYWxscyBvbmx5JywgRXJyb3JDb2RlLklOU1VGRklDSUVOVF9QRVJNSVNTSU9OUyk7XG4gIH1cbiAgbmV4dCgpO1xufVxudGFnUm91dGVHYXRlKHJlcXVpcmVTZXJ2aWNlUHJpbmNpcGFsLCB7IGtpbmQ6ICdzZXJ2aWNlUHJpbmNpcGFsJyB9KTtcblxuLyoqXG4gKiBUSEUgZ2F0ZSBmb3IgYW4gSU5URVJOQUwgcm91dGUg4oCUIHRoZSBvbmUgZXZlcnkgYC9pbnRlcm5hbC8qYCBwYXRoLCB0aGVcbiAqIHF1b3RhIHVzYWdlIGNvdW50ZXJzLCB0aGUgZW50aXR5LWV2ZW50IGluZ2VzdCBhbmQgdGhlIGF1ZGl0IGluZ2VzdCBnbyB0aHJvdWdoLlxuICpcbiAqIFR3byBydWxlcywgYm90aCBmYWlsLWNsb3NlZDpcbiAqXG4gKiAgMS4gKipObyB1c2VyIHRva2VuLCBldmVyLioqIE5vdCBhIG1lbWJlcidzLCBub3QgYSBzdXBlcmFkbWluJ3MsIG5vdCBhXG4gKiAgICAgc2VydmljZS1hY2NvdW50IGtleSdzLiBBbiBpbnRlcm5hbCByb3V0ZSBpcyBhIHBlZXItc2VydmljZSBBUEkgc3VyZmFjZSwgc29cbiAqICAgICBcImEgc3VmZmljaWVudGx5IHByaXZpbGVnZWQgaHVtYW5cIiBpcyBub3QgYW4gYWNjZXB0YWJsZSBjYWxsZXIg4oCUIHRoYXRcbiAqICAgICBlcXVpdmFsZW5jZSBpcyBleGFjdGx5IGhvdyBhIGJyb3dzZXItcmVhY2hhYmxlIHBhdGggYmVjb21lcyBhIHRlbmFudFxuICogICAgIGJvdW5kYXJ5IGJ1Zy4gYHJlcXVpcmVTZXJ2aWNlUHJpbmNpcGFsYCBhbHJlYWR5IHJlZnVzZWQgdXNlcnM7IHRoaXMgYWxzb1xuICogICAgIGNsb3NlcyB0aGUgYHx8IGlzU3lzdGVtQWRtaW4ocmVxKWAgZXNjYXBlIGhhdGNoZXMgdGhhdCBoYWQgZ3Jvd24gYXJvdW5kXG4gKiAgICAgdGhlIGluZGl2aWR1YWwgaW50ZXJuYWwgcm91dGVzLlxuICogIDIuICoqT25seSB0aGUgTkFNRUQgY2FsbGVycy4qKiBgY2FsbGVyc2AgbGlzdHMgdGhlIHNlcnZpY2VzIHRoYXQgbGVnaXRpbWF0ZWx5XG4gKiAgICAgY2FsbCB0aGlzIHJvdXRlLCBhbmQgdGhlIG5hbWUgaXMgY3J5cHRvZ3JhcGhpY2FsbHkgYm91bmQgdG8gdGhlIHNpZ25pbmdcbiAqICAgICBrZXkgKGBzZXJ2aWNlcy9zZXJ2aWNlLWtleXMudHNgKSwgc28gdGhpcyBpcyBhbiBpZGVudGl0eSBjaGVjayByYXRoZXIgdGhhblxuICogICAgIGEgY2xhaW0gY2hlY2suIEl0IGlzIHRoZSBzYW1lIGFsbG93LWxpc3QgdGhlIG1lc2ggcG9saWN5IG5hbWVzLCBhdCB0aGVcbiAqICAgICBsYXllciB0aGF0IGFsc28gaG9sZHMgaW4gZG9ja2VyIGNvbXBvc2UsIHdoZXJlIHRoZXJlIGlzIG5vIG1lc2ggYXQgYWxsIOKAlFxuICogICAgIHRoZSBJc3RpbyBgQXV0aG9yaXphdGlvblBvbGljeWAgaXMgZGVmZW5jZSBpbiBkZXB0aCBvbiB0b3AsIG5ldmVyIHRoZVxuICogICAgIGVuZm9yY2VtZW50LlxuICpcbiAqIENvbXBvc2UgYWZ0ZXIgYHJlcXVpcmVBdXRoYCBzbyBgcmVxLnVzZXJgIGlzIHBvcHVsYXRlZC4gUmVmdXNhbHMgYXJlIGNvdW50ZWRcbiAqIChgaW50ZXJuYWxfcm91dGVfcmVmdXNlZF90b3RhbGApIGFuZCBhdWRpdGVkIHRocm91Z2ggdGhlIHNoYXJlZCBgYXV0aHouZGVuaWVkYFxuICogc2luay5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlcXVpcmVJbnRlcm5hbFNlcnZpY2Uob3B0aW9uczogeyBjYWxsZXJzOiByZWFkb25seSBzdHJpbmdbXSB9KSB7XG4gIGNvbnN0IGFsbG93ZWQgPSBuZXcgU2V0KG9wdGlvbnMuY2FsbGVycyk7XG4gIHJldHVybiB0YWdSb3V0ZUdhdGUoKHJlcTogUmVxdWVzdCwgcmVzOiBSZXNwb25zZSwgbmV4dDogTmV4dEZ1bmN0aW9uKTogdm9pZCA9PiB7XG4gICAgY29uc3QgcmVmdXNlID0gKHJlYXNvbjogJ3VuYXV0aGVudGljYXRlZCcgfCAndXNlcl90b2tlbicgfCAnd3JvbmdfY2FsbGVyJyk6IHZvaWQgPT4ge1xuICAgICAgZW1pdENvdW50ZXIoJ2ludGVybmFsX3JvdXRlX3JlZnVzZWRfdG90YWwnLCB7XG4gICAgICAgIHNlcnZpY2U6IHNlcnZpY2VJZGVudGl0eSgpLFxuICAgICAgICByb3V0ZTogcmVxLnJvdXRlPy5wYXRoID8gYCR7cmVxLm1ldGhvZH0gJHtyZXEuYmFzZVVybH0ke3JlcS5yb3V0ZS5wYXRofWAgOiBgJHtyZXEubWV0aG9kfSAkeyhyZXEub3JpZ2luYWxVcmwgfHwgcmVxLnVybCkuc3BsaXQoJz8nKVswXX1gLFxuICAgICAgICByZWFzb24sXG4gICAgICAgIGNhbGxlcjogc2VydmljZU5hbWVPZihyZXEudXNlcikgPz8gJ25vbmUnLFxuICAgICAgfSk7XG4gICAgICByZWNvcmRBdXRoekRlbmlhbChyZXEsIGBpbnRlcm5hbC1zZXJ2aWNlICgke29wdGlvbnMuY2FsbGVycy5qb2luKCcsICcpfSlgKTtcbiAgICAgIGlmIChyZWFzb24gPT09ICd1bmF1dGhlbnRpY2F0ZWQnKSB7XG4gICAgICAgIHJldHVybiBzZW5kRXJyb3IocmVzLCBIdHRwU3RhdHVzLlVOQVVUSE9SSVpFRCwgJ0F1dGhlbnRpY2F0aW9uIHJlcXVpcmVkJywgRXJyb3JDb2RlLlVOQVVUSE9SSVpFRCk7XG4gICAgICB9XG4gICAgICBsb2dnZXIud2FybignUmVmdXNlZCBhbiBpbnRlcm5hbCByb3V0ZScsIHsgcmVhc29uLCBwYXRoOiAocmVxLm9yaWdpbmFsVXJsIHx8IHJlcS51cmwpLnNwbGl0KCc/JylbMF0sIGNhbGxlcjogc2VydmljZU5hbWVPZihyZXEudXNlcikgfSk7XG4gICAgICByZXR1cm4gc2VuZEVycm9yKHJlcywgSHR0cFN0YXR1cy5GT1JCSURERU4sICdJbnRlcm5hbCBzZXJ2aWNlIGNhbGxzIG9ubHknLCBFcnJvckNvZGUuSU5TVUZGSUNJRU5UX1BFUk1JU1NJT05TKTtcbiAgICB9O1xuXG4gICAgaWYgKCFyZXEudXNlcikgcmV0dXJuIHJlZnVzZSgndW5hdXRoZW50aWNhdGVkJyk7XG4gICAgaWYgKCFpc1NlcnZpY2VQcmluY2lwYWwocmVxKSkgcmV0dXJuIHJlZnVzZSgndXNlcl90b2tlbicpO1xuICAgIGNvbnN0IGNhbGxlciA9IHNlcnZpY2VOYW1lT2YocmVxLnVzZXIpO1xuICAgIGlmICghY2FsbGVyIHx8ICFhbGxvd2VkLmhhcyhjYWxsZXIpKSByZXR1cm4gcmVmdXNlKCd3cm9uZ19jYWxsZXInKTtcbiAgICBuZXh0KCk7XG4gIH0sIHsga2luZDogJ3NlcnZpY2VQcmluY2lwYWwnIH0sIHsga2luZDogJ2ludGVybmFsU2VydmljZScsIGNhbGxlcnM6IFsuLi5vcHRpb25zLmNhbGxlcnNdIH0pO1xufVxuXG4vKipcbiAqIENoZWNrIGlmIHRoZSByZXF1ZXN0IGlzIGZyb20gYSBzeXN0ZW0gYWRtaW4uXG4gKlxuICogQXV0aG9yaXR5IGlzIGdyYW50ZWQgc29sZWx5IGJ5IHRoZSB1c2VyLWxldmVsIGBpc1N1cGVyQWRtaW5gIGZsYWcgY2FycmllZFxuICogaW4gdGhlIEpXVCDigJQgbmV2ZXIgYnkgbWVtYmVyc2hpcCBpbiB0aGUgd2VsbC1rbm93biAnc3lzdGVtJyBvcmcsIHdoaWNoIHdvdWxkXG4gKiBjb25mbGF0ZSBhIFBpcGVsaW5lIEJ1aWxkZXIgb3BlcmF0b3Igd2l0aCBhIGN1c3RvbWVyIHRlbmFudCBhbmQgbGV0IGFueVxuICogd3JpdGUgdGhhdCBjcmVhdGVkIGEgJ3N5c3RlbSctbmFtZWQgb3JnIHF1aWV0bHkgZ3JhbnQgY3Jvc3Mtb3JnIGF1dGhvcml0eS4gVGhlIGBzeXN0ZW1gIG9yZyBzdGlsbCBleGlzdHMgYXMgYSAqY29udGVudCBob2xkZXIqIGZvciBzaGFyZWRcbiAqIHNhbXBsZSBkYXRhOyBpdCBjb25mZXJzIG5vIHByaXZpbGVnZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzU3lzdGVtQWRtaW4ocmVxOiBSZXF1ZXN0KTogYm9vbGVhbiB7XG4gIHJldHVybiByZXEudXNlcj8uaXNTdXBlckFkbWluID09PSB0cnVlO1xufVxuXG4vKipcbiAqIFdoZXRoZXIgdGhlIHJlcXVlc3QncyB0b2tlbiBjYXJyaWVzIGEgc3BlY2lmaWMgY2FwYWJpbGl0eSBgc2NvcGVgIChlLmcuXG4gKiBgJ3JlcG9ydGluZzppbmdlc3QnYCkuIFVzZWQgdG8gZ2F0ZSBlbmRwb2ludHMgdGhhdCBhY2NlcHQgYSBuYXJyb3cgbWFjaGluZVxuICogaWRlbnRpdHkg4oCUIGEgbm9ybWFsIGludGVyYWN0aXZlIHVzZXIgdG9rZW4gaGFzIG5vIGBzY29wZWAgYW5kIHJldHVybnMgZmFsc2UuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBoYXNTY29wZShyZXE6IFJlcXVlc3QsIHNjb3BlOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgcmV0dXJuIHJlcS51c2VyPy5zY29wZSA9PT0gc2NvcGU7XG59XG5cbi8qKiBSZXF1aXJlcyBhIHN5c3RlbSBhZG1pbiDigJQgZ3JhbnRlZCBzb2xlbHkgYnkgdGhlIGBpc1N1cGVyQWRtaW5gIHRva2VuIGNsYWltLlxuICogIFVzZSBhZnRlciByZXF1aXJlQXV0aC4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXF1aXJlU3lzdGVtQWRtaW4oXG4gIHJlcTogUmVxdWVzdCxcbiAgcmVzOiBSZXNwb25zZSxcbiAgbmV4dDogTmV4dEZ1bmN0aW9uLFxuKTogdm9pZCB7XG4gIGlmICghaXNTeXN0ZW1BZG1pbihyZXEpKSB7XG4gICAgcmVjb3JkQXV0aHpEZW5pYWwocmVxLCAnc3lzdGVtLWFkbWluJyk7XG4gICAgcmV0dXJuIHNlbmRFcnJvcihcbiAgICAgIHJlcywgSHR0cFN0YXR1cy5GT1JCSURERU4sXG4gICAgICAnQWNjZXNzIGRlbmllZC4gT25seSBzeXN0ZW0gYWRtaW5pc3RyYXRvcnMgY2FuIHBlcmZvcm0gdGhpcyBhY3Rpb24uJyxcbiAgICAgIEVycm9yQ29kZS5JTlNVRkZJQ0lFTlRfUEVSTUlTU0lPTlMsXG4gICAgKTtcbiAgfVxuICBuZXh0KCk7XG59XG50YWdSb3V0ZUdhdGUocmVxdWlyZVN5c3RlbUFkbWluLCB7IGtpbmQ6ICdzeXN0ZW1BZG1pbicgfSk7XG5cbi8qKlxuICogUmVxdWlyZSBhIHNwZWNpZmljIGZlYXR1cmUgZmxhZy4gVXNlIGFmdGVyIHJlcXVpcmVBdXRoLlxuICogQ2hlY2tzIHRoZSBgZmVhdHVyZXNgIGFycmF5IGluIHRoZSBKV1QgcGF5bG9hZCAoc2V0IGF0IHRva2VuIGlzc3VhbmNlKS5cbiAqIFN5c2FkbWlucyAoaXNTdXBlckFkbWluKSBieXBhc3Mg4oCUIHRoZXkgYWx3YXlzIGhhdmUgZXZlcnkgZmVhdHVyZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlcXVpcmVGZWF0dXJlKGZlYXR1cmU6IHN0cmluZykge1xuICByZXR1cm4gdGFnUm91dGVHYXRlKChyZXE6IFJlcXVlc3QsIHJlczogUmVzcG9uc2UsIG5leHQ6IE5leHRGdW5jdGlvbik6IHZvaWQgPT4ge1xuICAgIGlmICghcmVxdWlyZVVzZXIocmVxLCByZXMpKSByZXR1cm47XG5cbiAgICAvLyBTeXNhZG1pbnMgZ2V0IGFsbCBmZWF0dXJlczsgdGhlIGBmZWF0dXJlc2AgYXJyYXkgb24gdGhlaXIgdG9rZW4gaXNcbiAgICAvLyBwb3B1bGF0ZWQgd2l0aCBldmVyeSBmbGFnIGF0IGlzc3VhbmNlIHRpbWUgYnV0IHRoZSBieXBhc3MgaGVyZSBrZWVwc1xuICAgIC8vIHRoZSBydWxlIGV4cGxpY2l0IGFuZCBzdXJ2aXZlcyBhIHRva2VuIGlzc3VlZCBiZWZvcmUgYSBuZXcgZmVhdHVyZVxuICAgIC8vIGZsYWcgd2FzIGFkZGVkLlxuICAgIGlmIChyZXEudXNlci5pc1N1cGVyQWRtaW4gPT09IHRydWUpIHJldHVybiBuZXh0KCk7XG5cbiAgICBpZiAoIXJlcS51c2VyLmZlYXR1cmVzPy5pbmNsdWRlcyhmZWF0dXJlKSkge1xuICAgICAgLy8gUm91dGUgZmVhdHVyZS1nYXRlIGRlbmlhbHMgdGhyb3VnaCB0aGUgc2FtZSBhdWRpdCBzaW5rIGFzXG4gICAgICAvLyByZXF1aXJlUGVybWlzc2lvbiAvIHJlcXVpcmVTeXN0ZW1BZG1pbiBzbyBhIHByb2JlIGZvciBhblxuICAgICAgLy8gdW5lbnRpdGxlZCBjYXBhYmlsaXR5IGxlYXZlcyBhIHRyYWlsIChzdGF0ZS1jaGFuZ2luZyBtZXRob2RzIG9ubHkpLlxuICAgICAgcmVjb3JkQXV0aHpEZW5pYWwocmVxLCBgZmVhdHVyZToke2ZlYXR1cmV9YCk7XG4gICAgICByZXR1cm4gc2VuZEVycm9yKFxuICAgICAgICByZXMsIEh0dHBTdGF0dXMuRk9SQklEREVOLFxuICAgICAgICBgVGhpcyBmZWF0dXJlIHJlcXVpcmVzIGEgaGlnaGVyIHBsYW4gKCR7ZmVhdHVyZX0pYCxcbiAgICAgICAgRXJyb3JDb2RlLklOU1VGRklDSUVOVF9QRVJNSVNTSU9OUyxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgbmV4dCgpO1xuICB9LCB7IGtpbmQ6ICdmZWF0dXJlJywgZmVhdHVyZSB9KTtcbn1cblxuIl19
@@ -0,0 +1,36 @@
1
+ /**
2
+ * The routes that never spend `apiCalls` (or `automationCalls`), fleet-wide.
3
+ *
4
+ * Every service meters and gates its authenticated user surface on `apiCalls`
5
+ * (`meterQuotaOnSuccess` + `checkQuota`, mounted at the app-routes level). A few
6
+ * reads are made BY THE CONSOLE ITSELF, on every page load or on a timer, not by
7
+ * a person doing something — metering them would burn an idle tab's org budget
8
+ * all day, and gating them would make a quota-exhausted org's console unable to
9
+ * render the very banner that says so. This list is that carve-out, and it is
10
+ * deliberately short: each entry names its caller and why it is free.
11
+ *
12
+ * ONE list, read in three places, so they cannot drift:
13
+ * - `meterQuotaOnSuccess` skips a matching request (no increment);
14
+ * - `checkQuota` skips a matching request (never 429s);
15
+ * - `buildRouteTable` marks the route `quota.exempt`, and the quota coverage
16
+ * check (api-core testing) treats it as covered.
17
+ *
18
+ * Each `path` is matched against BOTH the concrete request path
19
+ * (`/organization/64f…/seat-usage`) and the route-table pattern
20
+ * (`/organization/:id/seat-usage`), so a `:param` segment is written as
21
+ * `[^/]+`. Paths are service-local (nginx strips `/api`).
22
+ *
23
+ * The quota service itself is not on the list because it meters nothing: its
24
+ * reads (`GET /quotas`, which QuotaBanner polls every 60s) never cost a call.
25
+ * Documented in docs/quotas.md ("Exempt routes").
26
+ */
27
+ export interface QuotaExemptRoute {
28
+ method: 'GET' | 'POST';
29
+ /** Anchored pattern over the service-local path. */
30
+ path: RegExp;
31
+ /** Who calls it, and why it must be free. */
32
+ reason: string;
33
+ }
34
+ export declare const QUOTA_EXEMPT_ROUTES: readonly QuotaExemptRoute[];
35
+ /** Whether `method` + `path` (a request path or a route-table pattern) is quota-exempt. */
36
+ export declare function isQuotaExemptRoute(method: string | undefined, path: string): boolean;