dynamodb-refresh-token-provider 0.4.6 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
  [![License](https://img.shields.io/npm/l/dynamodb-refresh-token-provider.svg)](https://github.com/gammarers-aws-sdk-modules/dynamodb-refresh-token-provider/blob/main/LICENSE)
5
5
  [![build](https://github.com/gammarers-aws-sdk-modules/dynamodb-refresh-token-provider/actions/workflows/build.yml/badge.svg)](https://github.com/gammarers-aws-sdk-modules/dynamodb-refresh-token-provider/actions/workflows/build.yml)
6
6
 
7
- TypeScript library that stores **opaque refresh tokens** in **Amazon DynamoDB** using AWS SDK for JavaScript v3. Tokens are persisted under a hash of the plaintext value; **issue**, **rotate** (with reuse detection via a transactional write), **revoke** (idempotent), and **revokeSession** (session-wide family revocation) are supported.
7
+ TypeScript library that stores **opaque refresh tokens** in **Amazon DynamoDB** using AWS SDK for JavaScript v3. Tokens are persisted under a hash of the plaintext value; **issue**, **rotate** (with reuse detection via a transactional write), **revoke** (idempotent), **revokeSession** (session-wide family revocation), and **revokeSubject** (subject-wide revocation across all sessions) are supported.
8
8
 
9
9
  ## Features
10
10
 
@@ -14,6 +14,7 @@ TypeScript library that stores **opaque refresh tokens** in **Amazon DynamoDB**
14
14
  - **Logical expiration** — `expiresAt` drives validation; `ttl` is for storage cleanup only.
15
15
  - **Rotation safety** — marks the old row as rotated and inserts the successor in one transaction; detects reuse and conflicting updates.
16
16
  - **Session revocation (OAuth 2.0 BCP)** — `revokeSession({ sessionId })` revokes all tokens for a session via a `sessionId` GSI; optional `revokeSessionOnReuse` cascades on reuse detection.
17
+ - **Subject revocation** — `revokeSubject({ subjectId })` revokes every token for a user across all sessions via a `subjectId` GSI (logout all devices, password change, account suspension).
17
18
  - **Structured errors** — `RefreshTokenError`, `RefreshTokenInvalidError`, `RefreshTokenExpiredError`, `RefreshTokenRevokedError`, `RefreshTokenReusedError` (with optional `subjectId` / `sessionId`), and `RefreshTokenRotateFailedError` for `instanceof` handling.
18
19
  - **Utilities** — `sha256hex` and `randomtoken` for hashing and token generation aligned with the store.
19
20
 
@@ -29,7 +30,7 @@ yarn add dynamodb-refresh-token-provider
29
30
 
30
31
  ## Usage
31
32
 
32
- Create a store with your table name, AWS region, and optional `StoreOptions`. Your DynamoDB table needs a **string partition key** named `pk`, **TTL enabled** on attribute `ttl` (see [DynamoDB TTL](#dynamodb-ttl)), and a **GSI** on `sessionId` for session revocation (see [Session GSI](#session-gsi)).
33
+ Create a store with your table name, AWS region, and optional `StoreOptions`. Your DynamoDB table needs a **string partition key** named `pk`, **TTL enabled** on attribute `ttl` (see [DynamoDB TTL](#dynamodb-ttl)), a **GSI** on `sessionId` for session revocation (see [Session GSI](#session-gsi)), and a **GSI** on `subjectId` for subject-wide revocation (see [Subject GSI](#subject-gsi)).
33
34
 
34
35
  ```typescript
35
36
  import {
@@ -42,10 +43,14 @@ import {
42
43
 
43
44
  const store = new DynamodbRefreshTokenProvider('your-refresh-token-table', 'us-east-1', {
44
45
  ttlDays: 60,
46
+ // ttlSeconds: 3600, // alternative to ttlDays; takes precedence when both are set
47
+ // tokenBytes: 32,
45
48
  pkPrefix: 'rt#',
49
+ // translateConfig: { marshallOptions: { removeUndefinedValues: true } },
46
50
  // Optional: revoke every token in the session when reuse is detected (OAuth 2.0 BCP)
47
51
  // revokeSessionOnReuse: true,
48
52
  // sessionIdIndexName: 'sessionId-index',
53
+ // subjectIdIndexName: 'subjectId-index',
49
54
  });
50
55
 
51
56
  // Issue a new refresh token for a subject/session
@@ -85,6 +90,9 @@ await store.revoke({ refreshToken: issued.refreshToken });
85
90
 
86
91
  // Revoke all tokens for a session (requires sessionId GSI)
87
92
  await store.revokeSession({ sessionId: 'session-456', subjectId: 'user-123' });
93
+
94
+ // Revoke all tokens for a subject across every session (requires subjectId GSI)
95
+ await store.revokeSubject({ subjectId: 'user-123' });
88
96
  ```
89
97
 
90
98
  ### DynamoDB TTL
@@ -96,7 +104,7 @@ Each item includes:
96
104
  | `expiresAt` | Logical expiration (Unix seconds); used by the library for validation. |
97
105
  | `ttl` | DynamoDB TTL attribute (Unix seconds); enable table TTL on this name for automatic deletion. |
98
106
 
99
- On **issue**, both are set to the same value. On **rotate**, the successor `Put` sets both to the new expiration; the previous row’s `ttl` is updated to its existing `expiresAt`. **Revoke** / **revokeSession** do not change `ttl` (the value from issue/rotate still applies).
107
+ On **issue**, both are set to the same value. On **rotate**, the successor `Put` sets both to the new expiration; the previous row’s `ttl` is updated to its existing `expiresAt`. **Revoke**, **revokeSession**, and **revokeSubject** do not change `ttl` (the value from issue/rotate still applies).
100
108
 
101
109
  Enable TTL on your table once (per table/region). The TTL attribute name must be **`ttl`**.
102
110
 
@@ -140,25 +148,54 @@ aws dynamodb update-table \
140
148
  }]'
141
149
  ```
142
150
 
151
+ ### Subject GSI
152
+
153
+ `revokeSubject` queries token rows by `subjectId` to revoke every refresh token for a user (e.g. logout all devices, password change, account suspension). Create a GSI whose **partition key** is the attribute **`subjectId`** (String). `KEYS_ONLY` projection is enough (base-table `pk` is always projected).
154
+
155
+ | Setting | Value |
156
+ |---------|--------|
157
+ | Index name | `subjectId-index` (override with `subjectIdIndexName`) |
158
+ | Partition key | `subjectId` (S) |
159
+ | Projection | `KEYS_ONLY` (or `ALL`) |
160
+
161
+ **AWS CLI** (example; adjust billing mode / capacity as needed)
162
+
163
+ ```bash
164
+ aws dynamodb update-table \
165
+ --table-name your-refresh-token-table \
166
+ --attribute-definitions AttributeName=subjectId,AttributeType=S \
167
+ --global-secondary-index-updates '[{
168
+ "Create": {
169
+ "IndexName": "subjectId-index",
170
+ "KeySchema": [{"AttributeName": "subjectId", "KeyType": "HASH"}],
171
+ "Projection": {"ProjectionType": "KEYS_ONLY"}
172
+ }
173
+ }]'
174
+ ```
175
+
143
176
  ## Options
144
177
 
145
178
  Constructor: `new DynamodbRefreshTokenProvider(tableName, region, options?)`.
146
179
 
147
180
  | Option | Type | Default | Description |
148
181
  |--------|------|---------|-------------|
149
- | `ttlDays` | `number` | `60` | Token lifetime in days; added to `now` when computing `expiresAt` and `ttl` (Unix seconds). |
182
+ | `ttlDays` | `number` | `60` | Token lifetime in days; added to `now` when computing `expiresAt` and `ttl` (Unix seconds). Ignored when `ttlSeconds` is set. |
183
+ | `ttlSeconds` | `number` | (none) | Token lifetime in seconds; takes precedence over `ttlDays` when both are set. |
184
+ | `tokenBytes` | `number` | `32` | Random byte length for generated refresh tokens (e.g. `32` → 256-bit). |
185
+ | `translateConfig` | `DocumentClientTranslateConfig` | (none) | Pass-through to `DynamoDBDocumentClient.from` (e.g. `marshallOptions.removeUndefinedValues`). |
150
186
  | `pkPrefix` | `string` | `'rt#'` | Partition key prefix; full `pk` is `prefix` + SHA-256 hex of the plaintext token. |
151
187
  | `consistentRead` | `boolean` | `true` | Use strongly consistent reads on `GetItem` when loading a token row. |
152
188
  | `endpoint` | `string` | (none) | Custom DynamoDB API endpoint (e.g. LocalStack or DynamoDB Local). |
153
189
  | `sessionIdIndexName` | `string` | `'sessionId-index'` | GSI name whose partition key is `sessionId` (required for `revokeSession`). |
190
+ | `subjectIdIndexName` | `string` | `'subjectId-index'` | GSI name whose partition key is `subjectId` (required for `revokeSubject`). |
154
191
  | `revokeSessionOnReuse` | `boolean` | `false` | When true, `rotate` calls `revokeSession` for the token’s session before throwing `RefreshTokenReusedError`. |
155
192
 
156
- `issue`, `rotate`, `revoke`, and `revokeSession` accept an optional `now?: Date` for testing or clock injection.
193
+ `issue`, `rotate`, `revoke`, `revokeSession`, and `revokeSubject` accept an optional `now?: Date` for testing or clock injection.
157
194
 
158
195
  ## Requirements
159
196
 
160
197
  - **Node.js** 20.0.0 or later.
161
- - A **DynamoDB table** with a string partition key **`pk`**, **TTL enabled** on attribute **`ttl`** (see [DynamoDB TTL](#dynamodb-ttl)), and a **GSI** on **`sessionId`** for session revocation (see [Session GSI](#session-gsi)).
198
+ - A **DynamoDB table** with a string partition key **`pk`**, **TTL enabled** on attribute **`ttl`** (see [DynamoDB TTL](#dynamodb-ttl)), a **GSI** on **`sessionId`** for session revocation (see [Session GSI](#session-gsi)), and a **GSI** on **`subjectId`** for subject-wide revocation (see [Subject GSI](#subject-gsi)).
162
199
  - **AWS credentials** and permissions for `PutItem`, `GetItem`, `UpdateItem`, `Query`, and `TransactWriteItems` on that table (and the configured `endpoint` if used).
163
200
 
164
201
  ## License
package/lib/index.d.ts CHANGED
@@ -1,13 +1,14 @@
1
1
  /**
2
2
  * Public API: refresh token store types, DynamoDB-backed implementation, structured errors, and crypto helpers.
3
3
  *
4
- * Enable DynamoDB TTL on attribute `ttl`, and a `sessionId` GSI for session revocation, when using
5
- * {@link DynamodbRefreshTokenProvider}.
4
+ * Enable DynamoDB TTL on attribute `ttl`, and GSIs on `sessionId` and `subjectId` for bulk
5
+ * revocation, when using {@link DynamodbRefreshTokenProvider}.
6
6
  */
7
- export type { RefreshTokenStore, IssueParams, IssueResult, RotateParams, RotateResult, RevokeParams, RevokeSessionParams, RevokeSessionResult, StoreOptions, TokenRecord, EpochSec, } from './types/index';
7
+ export type { RefreshTokenStore, IssueParams, IssueResult, RotateParams, RotateResult, RevokeParams, RevokeSessionParams, RevokeSessionResult, RevokeSubjectParams, RevokeSubjectResult, DocumentClientTranslateConfig, StoreOptions, TokenRecord, EpochSec, } from './types/index';
8
8
  /**
9
9
  * DynamoDB-backed {@link RefreshTokenStore} with rotation reuse detection and optional
10
- * session-wide revocation (`revokeSession` / `revokeSessionOnReuse`).
10
+ * session-wide revocation (`revokeSession` / `revokeSessionOnReuse`) and subject-wide
11
+ * revocation (`revokeSubject`).
11
12
  */
12
13
  export { DynamodbRefreshTokenProvider } from './stores/dynamodb';
13
14
  /**
package/lib/index.js CHANGED
@@ -3,7 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.randomtoken = exports.sha256hex = exports.RefreshTokenRotateFailedError = exports.RefreshTokenRevokedError = exports.RefreshTokenReusedError = exports.RefreshTokenInvalidError = exports.RefreshTokenExpiredError = exports.RefreshTokenError = exports.DynamodbRefreshTokenProvider = void 0;
4
4
  /**
5
5
  * DynamoDB-backed {@link RefreshTokenStore} with rotation reuse detection and optional
6
- * session-wide revocation (`revokeSession` / `revokeSessionOnReuse`).
6
+ * session-wide revocation (`revokeSession` / `revokeSessionOnReuse`) and subject-wide
7
+ * revocation (`revokeSubject`).
7
8
  */
8
9
  var dynamodb_1 = require("./stores/dynamodb");
9
10
  Object.defineProperty(exports, "DynamodbRefreshTokenProvider", { enumerable: true, get: function () { return dynamodb_1.DynamodbRefreshTokenProvider; } });
@@ -22,4 +23,4 @@ Object.defineProperty(exports, "RefreshTokenRotateFailedError", { enumerable: tr
22
23
  var hash_1 = require("./utils/hash");
23
24
  Object.defineProperty(exports, "sha256hex", { enumerable: true, get: function () { return hash_1.sha256hex; } });
24
25
  Object.defineProperty(exports, "randomtoken", { enumerable: true, get: function () { return hash_1.randomtoken; } });
25
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBb0JBOzs7R0FHRztBQUNILDhDQUFpRTtBQUF4RCx3SEFBQSw0QkFBNEIsT0FBQTtBQUVyQzs7O0dBR0c7QUFDSCxzRUFPdUM7QUFOckMseUhBQUEsaUJBQWlCLE9BQUE7QUFDakIsZ0lBQUEsd0JBQXdCLE9BQUE7QUFDeEIsZ0lBQUEsd0JBQXdCLE9BQUE7QUFDeEIsK0hBQUEsdUJBQXVCLE9BQUE7QUFDdkIsZ0lBQUEsd0JBQXdCLE9BQUE7QUFDeEIscUlBQUEsNkJBQTZCLE9BQUE7QUFHL0IseUVBQXlFO0FBQ3pFLHFDQUFzRDtBQUE3QyxpR0FBQSxTQUFTLE9BQUE7QUFBRSxtR0FBQSxXQUFXLE9BQUEiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFB1YmxpYyBBUEk6IHJlZnJlc2ggdG9rZW4gc3RvcmUgdHlwZXMsIER5bmFtb0RCLWJhY2tlZCBpbXBsZW1lbnRhdGlvbiwgc3RydWN0dXJlZCBlcnJvcnMsIGFuZCBjcnlwdG8gaGVscGVycy5cbiAqXG4gKiBFbmFibGUgRHluYW1vREIgVFRMIG9uIGF0dHJpYnV0ZSBgdHRsYCwgYW5kIGEgYHNlc3Npb25JZGAgR1NJIGZvciBzZXNzaW9uIHJldm9jYXRpb24sIHdoZW4gdXNpbmdcbiAqIHtAbGluayBEeW5hbW9kYlJlZnJlc2hUb2tlblByb3ZpZGVyfS5cbiAqL1xuZXhwb3J0IHR5cGUge1xuICBSZWZyZXNoVG9rZW5TdG9yZSxcbiAgSXNzdWVQYXJhbXMsXG4gIElzc3VlUmVzdWx0LFxuICBSb3RhdGVQYXJhbXMsXG4gIFJvdGF0ZVJlc3VsdCxcbiAgUmV2b2tlUGFyYW1zLFxuICBSZXZva2VTZXNzaW9uUGFyYW1zLFxuICBSZXZva2VTZXNzaW9uUmVzdWx0LFxuICBTdG9yZU9wdGlvbnMsXG4gIFRva2VuUmVjb3JkLFxuICBFcG9jaFNlYyxcbn0gZnJvbSAnLi90eXBlcy9pbmRleCc7XG5cbi8qKlxuICogRHluYW1vREItYmFja2VkIHtAbGluayBSZWZyZXNoVG9rZW5TdG9yZX0gd2l0aCByb3RhdGlvbiByZXVzZSBkZXRlY3Rpb24gYW5kIG9wdGlvbmFsXG4gKiBzZXNzaW9uLXdpZGUgcmV2b2NhdGlvbiAoYHJldm9rZVNlc3Npb25gIC8gYHJldm9rZVNlc3Npb25PblJldXNlYCkuXG4gKi9cbmV4cG9ydCB7IER5bmFtb2RiUmVmcmVzaFRva2VuUHJvdmlkZXIgfSBmcm9tICcuL3N0b3Jlcy9keW5hbW9kYic7XG5cbi8qKlxuICogU3RydWN0dXJlZCBlcnJvcnMgZm9yIGBpbnN0YW5jZW9mYCBoYW5kbGluZyBpbiBhdXRoIGZsb3dzLlxuICoge0BsaW5rIFJlZnJlc2hUb2tlblJldXNlZEVycm9yfSBtYXkgY2FycnkgYHN1YmplY3RJZGAgLyBgc2Vzc2lvbklkYCBmb3Igc2Vzc2lvbiByZXZva2UuXG4gKi9cbmV4cG9ydCB7XG4gIFJlZnJlc2hUb2tlbkVycm9yLFxuICBSZWZyZXNoVG9rZW5FeHBpcmVkRXJyb3IsXG4gIFJlZnJlc2hUb2tlbkludmFsaWRFcnJvcixcbiAgUmVmcmVzaFRva2VuUmV1c2VkRXJyb3IsXG4gIFJlZnJlc2hUb2tlblJldm9rZWRFcnJvcixcbiAgUmVmcmVzaFRva2VuUm90YXRlRmFpbGVkRXJyb3IsXG59IGZyb20gJy4vc3RvcmVzL3JlZnJlc2gtdG9rZW4tZXJyb3JzJztcblxuLyoqIFNIQS0yNTYgaGV4IGhhc2hpbmcgYW5kIGNyeXB0b2dyYXBoaWNhbGx5IHNlY3VyZSB0b2tlbiBnZW5lcmF0aW9uLiAqL1xuZXhwb3J0IHsgc2hhMjU2aGV4LCByYW5kb210b2tlbiB9IGZyb20gJy4vdXRpbHMvaGFzaCc7XG4iXX0=
26
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBdUJBOzs7O0dBSUc7QUFDSCw4Q0FBaUU7QUFBeEQsd0hBQUEsNEJBQTRCLE9BQUE7QUFFckM7OztHQUdHO0FBQ0gsc0VBT3VDO0FBTnJDLHlIQUFBLGlCQUFpQixPQUFBO0FBQ2pCLGdJQUFBLHdCQUF3QixPQUFBO0FBQ3hCLGdJQUFBLHdCQUF3QixPQUFBO0FBQ3hCLCtIQUFBLHVCQUF1QixPQUFBO0FBQ3ZCLGdJQUFBLHdCQUF3QixPQUFBO0FBQ3hCLHFJQUFBLDZCQUE2QixPQUFBO0FBRy9CLHlFQUF5RTtBQUN6RSxxQ0FBc0Q7QUFBN0MsaUdBQUEsU0FBUyxPQUFBO0FBQUUsbUdBQUEsV0FBVyxPQUFBIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBQdWJsaWMgQVBJOiByZWZyZXNoIHRva2VuIHN0b3JlIHR5cGVzLCBEeW5hbW9EQi1iYWNrZWQgaW1wbGVtZW50YXRpb24sIHN0cnVjdHVyZWQgZXJyb3JzLCBhbmQgY3J5cHRvIGhlbHBlcnMuXG4gKlxuICogRW5hYmxlIER5bmFtb0RCIFRUTCBvbiBhdHRyaWJ1dGUgYHR0bGAsIGFuZCBHU0lzIG9uIGBzZXNzaW9uSWRgIGFuZCBgc3ViamVjdElkYCBmb3IgYnVsa1xuICogcmV2b2NhdGlvbiwgd2hlbiB1c2luZyB7QGxpbmsgRHluYW1vZGJSZWZyZXNoVG9rZW5Qcm92aWRlcn0uXG4gKi9cbmV4cG9ydCB0eXBlIHtcbiAgUmVmcmVzaFRva2VuU3RvcmUsXG4gIElzc3VlUGFyYW1zLFxuICBJc3N1ZVJlc3VsdCxcbiAgUm90YXRlUGFyYW1zLFxuICBSb3RhdGVSZXN1bHQsXG4gIFJldm9rZVBhcmFtcyxcbiAgUmV2b2tlU2Vzc2lvblBhcmFtcyxcbiAgUmV2b2tlU2Vzc2lvblJlc3VsdCxcbiAgUmV2b2tlU3ViamVjdFBhcmFtcyxcbiAgUmV2b2tlU3ViamVjdFJlc3VsdCxcbiAgRG9jdW1lbnRDbGllbnRUcmFuc2xhdGVDb25maWcsXG4gIFN0b3JlT3B0aW9ucyxcbiAgVG9rZW5SZWNvcmQsXG4gIEVwb2NoU2VjLFxufSBmcm9tICcuL3R5cGVzL2luZGV4JztcblxuLyoqXG4gKiBEeW5hbW9EQi1iYWNrZWQge0BsaW5rIFJlZnJlc2hUb2tlblN0b3JlfSB3aXRoIHJvdGF0aW9uIHJldXNlIGRldGVjdGlvbiBhbmQgb3B0aW9uYWxcbiAqIHNlc3Npb24td2lkZSByZXZvY2F0aW9uIChgcmV2b2tlU2Vzc2lvbmAgLyBgcmV2b2tlU2Vzc2lvbk9uUmV1c2VgKSBhbmQgc3ViamVjdC13aWRlXG4gKiByZXZvY2F0aW9uIChgcmV2b2tlU3ViamVjdGApLlxuICovXG5leHBvcnQgeyBEeW5hbW9kYlJlZnJlc2hUb2tlblByb3ZpZGVyIH0gZnJvbSAnLi9zdG9yZXMvZHluYW1vZGInO1xuXG4vKipcbiAqIFN0cnVjdHVyZWQgZXJyb3JzIGZvciBgaW5zdGFuY2VvZmAgaGFuZGxpbmcgaW4gYXV0aCBmbG93cy5cbiAqIHtAbGluayBSZWZyZXNoVG9rZW5SZXVzZWRFcnJvcn0gbWF5IGNhcnJ5IGBzdWJqZWN0SWRgIC8gYHNlc3Npb25JZGAgZm9yIHNlc3Npb24gcmV2b2tlLlxuICovXG5leHBvcnQge1xuICBSZWZyZXNoVG9rZW5FcnJvcixcbiAgUmVmcmVzaFRva2VuRXhwaXJlZEVycm9yLFxuICBSZWZyZXNoVG9rZW5JbnZhbGlkRXJyb3IsXG4gIFJlZnJlc2hUb2tlblJldXNlZEVycm9yLFxuICBSZWZyZXNoVG9rZW5SZXZva2VkRXJyb3IsXG4gIFJlZnJlc2hUb2tlblJvdGF0ZUZhaWxlZEVycm9yLFxufSBmcm9tICcuL3N0b3Jlcy9yZWZyZXNoLXRva2VuLWVycm9ycyc7XG5cbi8qKiBTSEEtMjU2IGhleCBoYXNoaW5nIGFuZCBjcnlwdG9ncmFwaGljYWxseSBzZWN1cmUgdG9rZW4gZ2VuZXJhdGlvbi4gKi9cbmV4cG9ydCB7IHNoYTI1NmhleCwgcmFuZG9tdG9rZW4gfSBmcm9tICcuL3V0aWxzL2hhc2gnO1xuIl19
@@ -1,6 +1,6 @@
1
- import type { RefreshTokenStore, StoreOptions, TokenRecord, IssueParams, RotateParams, RevokeParams, RevokeSessionParams, RevokeSessionResult, IssueResult, RotateResult } from '../types/index';
1
+ import type { RefreshTokenStore, StoreOptions, DocumentClientTranslateConfig, TokenRecord, IssueParams, RotateParams, RevokeParams, RevokeSessionParams, RevokeSessionResult, RevokeSubjectParams, RevokeSubjectResult, IssueResult, RotateResult } from '../types/index';
2
2
  /** Re-exported types for consumers that import the DynamoDB store module. */
3
- export { RefreshTokenStore, StoreOptions, TokenRecord, IssueParams, RotateParams, RevokeParams, RevokeSessionParams, RevokeSessionResult, IssueResult, RotateResult, };
3
+ export { RefreshTokenStore, StoreOptions, DocumentClientTranslateConfig, TokenRecord, IssueParams, RotateParams, RevokeParams, RevokeSessionParams, RevokeSessionResult, RevokeSubjectParams, RevokeSubjectResult, IssueResult, RotateResult, };
4
4
  /**
5
5
  * {@link RefreshTokenStore} implementation backed by a single DynamoDB table.
6
6
  *
@@ -16,7 +16,7 @@ export declare class DynamodbRefreshTokenProvider implements RefreshTokenStore {
16
16
  private readonly options?;
17
17
  /** Lazily initialized and cached document client. */
18
18
  private ddb;
19
- /** Random byte length for generated refresh tokens (default 32 → 256-bit). */
19
+ /** Random byte length for generated refresh tokens. */
20
20
  private readonly tokenBytes;
21
21
  /**
22
22
  * @param tableName - DynamoDB table name for refresh token items.
@@ -71,6 +71,23 @@ export declare class DynamodbRefreshTokenProvider implements RefreshTokenStore {
71
71
  * @returns Count of rows updated with `revokedAt` in this call.
72
72
  */
73
73
  revokeSession: (params: RevokeSessionParams) => Promise<RevokeSessionResult>;
74
+ /**
75
+ * Sets `revokedAt` on every refresh token row for the given `subjectId` across all sessions.
76
+ *
77
+ * Queries the subject GSI (partition key `subjectId`; `KEYS_ONLY` is enough), then updates each
78
+ * base-table item. Missing items are skipped (idempotent). Paginate with `LastEvaluatedKey`.
79
+ *
80
+ * @param params - Subject id and optional clock.
81
+ * @returns Count of rows updated with `revokedAt` in this call.
82
+ */
83
+ revokeSubject: (params: RevokeSubjectParams) => Promise<RevokeSubjectResult>;
84
+ /**
85
+ * Queries a GSI and sets `revokedAt` on each matching base-table row.
86
+ *
87
+ * @param params - GSI query parameters and per-row update conditions.
88
+ * @returns Count of rows updated with `revokedAt` in this call.
89
+ */
90
+ private revokeTokenRowsByIndexQuery;
74
91
  /**
75
92
  * Handles refresh-token reuse detection: optionally cascades {@link DynamodbRefreshTokenProvider.revokeSession}
76
93
  * when {@link StoreOptions.revokeSessionOnReuse} is true, then throws {@link RefreshTokenReusedError}
@@ -108,12 +125,27 @@ export declare class DynamodbRefreshTokenProvider implements RefreshTokenStore {
108
125
  */
109
126
  private getPrimaryKey;
110
127
  /**
111
- * Computes logical expiration (`expiresAt` / `ttl`) as `nowSec` plus {@link StoreOptions.ttlDays}.
128
+ * Computes logical expiration (`expiresAt` / `ttl`) as `nowSec` plus configured lifetime.
112
129
  *
113
130
  * @param nowSec - Current time as Unix seconds.
114
- * @returns Expiration timestamp in Unix seconds (default lifetime: 60 days).
131
+ * @returns Expiration timestamp in Unix seconds.
115
132
  */
116
133
  private makeExpiresAt;
134
+ /**
135
+ * Resolves and validates {@link StoreOptions.tokenBytes}.
136
+ *
137
+ * @param tokenBytes - Optional byte length from store options.
138
+ * @returns Positive integer byte length.
139
+ * @throws {RangeError} When `tokenBytes` is not a positive integer.
140
+ */
141
+ private resolveTokenBytes;
142
+ /**
143
+ * Validates TTL-related store options at construction time.
144
+ *
145
+ * @param options - Store options from the constructor.
146
+ * @throws {RangeError} When `ttlSeconds` or `ttlDays` is not a positive number.
147
+ */
148
+ private validateTtlOptions;
117
149
  /**
118
150
  * Ensures the token is non-empty and matches the expected base64url length for `tokenBytes`.
119
151
  *
@@ -10,6 +10,12 @@ const time_1 = require("../utils/time");
10
10
  const DEFAULT_PRIMARY_KEY_PREFIX = 'rt#';
11
11
  /** Default GSI name for querying token rows by `sessionId`. */
12
12
  const DEFAULT_SESSION_ID_INDEX_NAME = 'sessionId-index';
13
+ /** Default GSI name for querying token rows by `subjectId`. */
14
+ const DEFAULT_SUBJECT_ID_INDEX_NAME = 'subjectId-index';
15
+ /** Default random byte length for generated refresh tokens (32 → 256-bit). */
16
+ const DEFAULT_TOKEN_BYTES = 32;
17
+ /** Default token lifetime in days when neither ttlSeconds nor ttlDays is set. */
18
+ const DEFAULT_TTL_DAYS = 60;
13
19
  /**
14
20
  * {@link RefreshTokenStore} implementation backed by a single DynamoDB table.
15
21
  *
@@ -31,8 +37,6 @@ class DynamodbRefreshTokenProvider {
31
37
  this.options = options;
32
38
  /** Lazily initialized and cached document client. */
33
39
  this.ddb = null;
34
- /** Random byte length for generated refresh tokens (default 32 → 256-bit). */
35
- this.tokenBytes = 32;
36
40
  /**
37
41
  * Inserts a new token record with `expiresAt` and matching `ttl`. Fails the put if `pk` already exists.
38
42
  *
@@ -205,10 +209,57 @@ class DynamodbRefreshTokenProvider {
205
209
  * @returns Count of rows updated with `revokedAt` in this call.
206
210
  */
207
211
  this.revokeSession = async (params) => {
208
- const ddb = this.getddb();
209
212
  const now = params.now ?? new Date();
210
213
  const nowSec = (0, time_1.epochsec)(now);
211
214
  const indexName = this.options?.sessionIdIndexName ?? DEFAULT_SESSION_ID_INDEX_NAME;
215
+ const revokedCount = await this.revokeTokenRowsByIndexQuery({
216
+ indexName,
217
+ keyConditionExpression: 'sessionId = :sessionId',
218
+ queryExpressionAttributeValues: {
219
+ ':sessionId': params.sessionId,
220
+ },
221
+ nowSec,
222
+ updateConditionExpression: params.subjectId
223
+ ? 'attribute_exists(pk) AND subjectId = :subjectId'
224
+ : 'attribute_exists(pk)',
225
+ updateExpressionAttributeValues: params.subjectId
226
+ ? { ':subjectId': params.subjectId }
227
+ : undefined,
228
+ });
229
+ return { revokedCount };
230
+ };
231
+ /**
232
+ * Sets `revokedAt` on every refresh token row for the given `subjectId` across all sessions.
233
+ *
234
+ * Queries the subject GSI (partition key `subjectId`; `KEYS_ONLY` is enough), then updates each
235
+ * base-table item. Missing items are skipped (idempotent). Paginate with `LastEvaluatedKey`.
236
+ *
237
+ * @param params - Subject id and optional clock.
238
+ * @returns Count of rows updated with `revokedAt` in this call.
239
+ */
240
+ this.revokeSubject = async (params) => {
241
+ const now = params.now ?? new Date();
242
+ const nowSec = (0, time_1.epochsec)(now);
243
+ const indexName = this.options?.subjectIdIndexName ?? DEFAULT_SUBJECT_ID_INDEX_NAME;
244
+ const revokedCount = await this.revokeTokenRowsByIndexQuery({
245
+ indexName,
246
+ keyConditionExpression: 'subjectId = :subjectId',
247
+ queryExpressionAttributeValues: {
248
+ ':subjectId': params.subjectId,
249
+ },
250
+ nowSec,
251
+ updateConditionExpression: 'attribute_exists(pk)',
252
+ });
253
+ return { revokedCount };
254
+ };
255
+ /**
256
+ * Queries a GSI and sets `revokedAt` on each matching base-table row.
257
+ *
258
+ * @param params - GSI query parameters and per-row update conditions.
259
+ * @returns Count of rows updated with `revokedAt` in this call.
260
+ */
261
+ this.revokeTokenRowsByIndexQuery = async (params) => {
262
+ const ddb = this.getddb();
212
263
  let revokedCount = 0;
213
264
  let exclusiveStartKey;
214
265
  /** Whether another Query page is available after the previous response. */
@@ -216,11 +267,9 @@ class DynamodbRefreshTokenProvider {
216
267
  do {
217
268
  const res = await ddb.send(new lib_dynamodb_1.QueryCommand({
218
269
  TableName: this.tableName,
219
- IndexName: indexName,
220
- KeyConditionExpression: 'sessionId = :sessionId',
221
- ExpressionAttributeValues: {
222
- ':sessionId': params.sessionId,
223
- },
270
+ IndexName: params.indexName,
271
+ KeyConditionExpression: params.keyConditionExpression,
272
+ ExpressionAttributeValues: params.queryExpressionAttributeValues,
224
273
  ProjectionExpression: 'pk',
225
274
  ExclusiveStartKey: exclusiveStartKey,
226
275
  }));
@@ -231,19 +280,15 @@ class DynamodbRefreshTokenProvider {
231
280
  continue;
232
281
  }
233
282
  const expressionAttributeValues = {
234
- ':now': nowSec,
283
+ ':now': params.nowSec,
284
+ ...params.updateExpressionAttributeValues,
235
285
  };
236
- let conditionExpression = 'attribute_exists(pk)';
237
- if (params.subjectId) {
238
- conditionExpression = 'attribute_exists(pk) AND subjectId = :subjectId';
239
- expressionAttributeValues[':subjectId'] = params.subjectId;
240
- }
241
286
  try {
242
287
  await ddb.send(new lib_dynamodb_1.UpdateCommand({
243
288
  TableName: this.tableName,
244
289
  Key: { pk },
245
290
  UpdateExpression: 'SET revokedAt = :now',
246
- ConditionExpression: conditionExpression,
291
+ ConditionExpression: params.updateConditionExpression,
247
292
  ExpressionAttributeValues: expressionAttributeValues,
248
293
  }));
249
294
  revokedCount += 1;
@@ -257,7 +302,7 @@ class DynamodbRefreshTokenProvider {
257
302
  }
258
303
  exclusiveStartKey = res.LastEvaluatedKey;
259
304
  } while (shouldContinuePaging());
260
- return { revokedCount };
305
+ return revokedCount;
261
306
  };
262
307
  /**
263
308
  * Handles refresh-token reuse detection: optionally cascades {@link DynamodbRefreshTokenProvider.revokeSession}
@@ -297,7 +342,7 @@ class DynamodbRefreshTokenProvider {
297
342
  return `https://dynamodb.${this.region}.amazonaws.com`;
298
343
  })(),
299
344
  });
300
- this.ddb = lib_dynamodb_1.DynamoDBDocumentClient.from(client);
345
+ this.ddb = lib_dynamodb_1.DynamoDBDocumentClient.from(client, this.options?.translateConfig);
301
346
  }
302
347
  return this.ddb;
303
348
  };
@@ -334,14 +379,48 @@ class DynamodbRefreshTokenProvider {
334
379
  return `${this.getPrimaryKeyPrefix()}${hash}`;
335
380
  };
336
381
  /**
337
- * Computes logical expiration (`expiresAt` / `ttl`) as `nowSec` plus {@link StoreOptions.ttlDays}.
382
+ * Computes logical expiration (`expiresAt` / `ttl`) as `nowSec` plus configured lifetime.
338
383
  *
339
384
  * @param nowSec - Current time as Unix seconds.
340
- * @returns Expiration timestamp in Unix seconds (default lifetime: 60 days).
385
+ * @returns Expiration timestamp in Unix seconds.
341
386
  */
342
387
  this.makeExpiresAt = (nowSec) => {
343
- return nowSec + (this.options?.ttlDays ?? 60) * 24 * 60 * 60;
388
+ const ttlSeconds = this.options?.ttlSeconds;
389
+ if (ttlSeconds !== undefined) {
390
+ return nowSec + ttlSeconds;
391
+ }
392
+ return nowSec + (this.options?.ttlDays ?? DEFAULT_TTL_DAYS) * 24 * 60 * 60;
393
+ };
394
+ /**
395
+ * Resolves and validates {@link StoreOptions.tokenBytes}.
396
+ *
397
+ * @param tokenBytes - Optional byte length from store options.
398
+ * @returns Positive integer byte length.
399
+ * @throws {RangeError} When `tokenBytes` is not a positive integer.
400
+ */
401
+ this.resolveTokenBytes = (tokenBytes) => {
402
+ const bytes = tokenBytes ?? DEFAULT_TOKEN_BYTES;
403
+ if (!Number.isInteger(bytes) || bytes < 1) {
404
+ throw new RangeError('tokenBytes must be a positive integer');
405
+ }
406
+ return bytes;
407
+ };
408
+ /**
409
+ * Validates TTL-related store options at construction time.
410
+ *
411
+ * @param options - Store options from the constructor.
412
+ * @throws {RangeError} When `ttlSeconds` or `ttlDays` is not a positive number.
413
+ */
414
+ this.validateTtlOptions = (options) => {
415
+ if (options?.ttlSeconds !== undefined && options.ttlSeconds <= 0) {
416
+ throw new RangeError('ttlSeconds must be a positive number');
417
+ }
418
+ if (options?.ttlDays !== undefined && options.ttlDays <= 0) {
419
+ throw new RangeError('ttlDays must be a positive number');
420
+ }
344
421
  };
422
+ this.tokenBytes = this.resolveTokenBytes(this.options?.tokenBytes);
423
+ this.validateTtlOptions(this.options);
345
424
  }
346
425
  /**
347
426
  * Ensures the token is non-empty and matches the expected base64url length for `tokenBytes`.
@@ -356,4 +435,4 @@ class DynamodbRefreshTokenProvider {
356
435
  }
357
436
  }
358
437
  exports.DynamodbRefreshTokenProvider = DynamodbRefreshTokenProvider;
359
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHluYW1vZGIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc3RvcmVzL2R5bmFtb2RiLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLDhEQUEwRDtBQUMxRCx3REFBMEk7QUFFMUksaUVBS2dDO0FBYWhDLHdDQUF1RDtBQUN2RCx3Q0FBeUM7QUFnQnpDLDREQUE0RDtBQUM1RCxNQUFNLDBCQUEwQixHQUFHLEtBQUssQ0FBQztBQUV6QywrREFBK0Q7QUFDL0QsTUFBTSw2QkFBNkIsR0FBRyxpQkFBaUIsQ0FBQztBQUV4RDs7Ozs7Ozs7R0FRRztBQUNILE1BQWEsNEJBQTRCO0lBT3ZDOzs7O09BSUc7SUFDSCxZQUNtQixTQUFpQixFQUNqQixNQUFjLEVBQ2QsT0FBc0I7UUFGdEIsY0FBUyxHQUFULFNBQVMsQ0FBUTtRQUNqQixXQUFNLEdBQU4sTUFBTSxDQUFRO1FBQ2QsWUFBTyxHQUFQLE9BQU8sQ0FBZTtRQWR6QyxxREFBcUQ7UUFDN0MsUUFBRyxHQUFrQyxJQUFJLENBQUM7UUFFbEQsOEVBQThFO1FBQzdELGVBQVUsR0FBRyxFQUFFLENBQUM7UUFhakM7Ozs7O1dBS0c7UUFDSSxVQUFLLEdBQUcsS0FBSyxFQUFFLE1BQW1CLEVBQXdCLEVBQUU7WUFDakUsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBRTFCLE1BQU0sR0FBRyxHQUFHLE1BQU0sQ0FBQyxHQUFHLElBQUksSUFBSSxJQUFJLEVBQUUsQ0FBQztZQUNyQyxNQUFNLE1BQU0sR0FBRyxJQUFBLGVBQVEsRUFBQyxHQUFHLENBQUMsQ0FBQztZQUM3QixNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBRTdDLE1BQU0sWUFBWSxHQUFHLElBQUEsa0JBQVcsRUFBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDbEQsTUFBTSxJQUFJLEdBQUcsSUFBQSxnQkFBUyxFQUFDLFlBQVksQ0FB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QUcsR0FBVyxFQUFFO1lBQ3pDLE9BQU8sR0FBRyxJQUFJLENBQUMsT0FBTyxFQUFFLFFBQVEsSUFBSSwwQkFBMEIsRUFBRSxDQUFDO1FBQ25FLENBQUMsQ0FBQztRQUVGOzs7OztXQUtHO1FBQ0ssa0JBQWEsR0FBRyxDQUFDLElBQVksRUFBVSxFQUFFO1lBQy9DLE9BQU8sR0FBRyxJQUFJLENBQUMsbUJBQW1CLEVBQUUsR0FBRyxJQUFJLEVBQUUsQ0FBQztRQUNoRCxDQUFDLENBQUM7UUFFRjs7Ozs7V0FLRztRQUNLLGtCQUFhLEdBQUcsQ0FBQyxNQUFjLEVBQVUsRUFBRTtZQUNqRCxPQUFPLE1BQU0sR0FBRyxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsT0FBTyxJQUFJLEVBQUUsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO1FBQy9ELENBQUMsQ0FBQztJQWpXQyxDQUFDO0lBbVdKOzs7OztPQUtHO0lBQ0ssb0JBQW9CLENBQUMsS0FBYTtRQUN4QyxJQUFJLENBQUMsS0FBSyxJQUFJLEtBQUssQ0FBQyxNQUFNLEtBQUssSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDO1lBQ2xFLE1BQU0sSUFBSSwrQ0FBd0IsRUFBRSxDQUFDO1FBQ3ZDLENBQUM7SUFDSCxDQUFDO0NBRUY7QUEvWEQsb0VBK1hDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRHluYW1vREJDbGllbnQgfSBmcm9tICdAYXdzLXNkay9jbGllbnQtZHluYW1vZGInO1xuaW1wb3J0IHsgRHluYW1vREJEb2N1bWVudENsaWVudCwgR2V0Q29tbWFuZCwgUHV0Q29tbWFuZCwgUXVlcnlDb21tYW5kLCBVcGRhdGVDb21tYW5kLCBUcmFuc2FjdFdyaXRlQ29tbWFuZCB9IGZyb20gJ0Bhd3Mtc2RrL2xpYi1keW5hbW9kYic7XG5cbmltcG9ydCB7XG4gIFJlZnJlc2hUb2tlbkV4cGlyZWRFcnJvcixcbiAgUmVmcmVzaFRva2VuSW52YWxpZEVycm9yLFxuICBSZWZyZXNoVG9rZW5SZXVzZWRFcnJvcixcbiAgUmVmcmVzaFRva2VuUmV2b2tlZEVycm9yLFxufSBmcm9tICcuL3JlZnJlc2gtdG9rZW4tZXJyb3JzJztcbmltcG9ydCB0eXBlIHtcbiAgUmVmcmVzaFRva2VuU3RvcmUsXG4gIFN0b3JlT3B0aW9ucyxcbiAgVG9rZW5SZWNvcmQsXG4gIElzc3VlUGFyYW1zLFxuICBSb3RhdGVQYXJhbXMsXG4gIFJldm9rZVBhcmFtcyxcbiAgUmV2b2tlU2Vzc2lvblBhcmFtcyxcbiAgUmV2b2tlU2Vzc2lvblJlc3VsdCxcbiAgSXNzdWVSZXN1bHQsXG4gIFJvdGF0ZVJlc3VsdCxcbn0gZnJvbSAnLi4vdHlwZXMvaW5kZXgnO1xuaW1wb3J0IHsgcmFuZG9tdG9rZW4sIHNoYTI1NmhleCB9IGZyb20gJy4uL3V0aWxzL2hhc2gnO1xuaW1wb3J0IHsgZXBvY2hzZWMgfSBmcm9tICcuLi91dGlscy90aW1lJztcblxuLyoqIFJlLWV4cG9ydGVkIHR5cGVzIGZvciBjb25zdW1lcnMgdGhhdCBpbXBvcnQgdGhlIER5bmFtb0RCIHN0b3JlIG1vZHVsZS4gKi9cbmV4cG9ydCB7XG4gIFJlZnJlc2hUb2tlblN0b3JlLFxuICBTdG9yZU9wdGlvbnMsXG4gIFRva2VuUmVjb3JkLFxuICBJc3N1ZVBhcmFtcyxcbiAgUm90YXRlUGFyYW1zLFxuICBSZXZva2VQYXJhbXMsXG4gIFJldm9rZVNlc3Npb25QYXJhbXMsXG4gIFJldm9rZVNlc3Npb25SZXN1bHQsXG4gIElzc3VlUmVzdWx0LFxuICBSb3RhdGVSZXN1bHQsXG59O1xuXG4vKiogRGVmYXVsdCBwYXJ0aXRpb24ga2V5IHByZWZpeCBmb3IgcmVmcmVzaCB0b2tlbiBpdGVtcy4gKi9cbmNvbnN0IERFRkFVTFRfUFJJTUFSWV9LRVlfUFJFRklYID0gJ3J0Iyc7XG5cbi8qKiBEZWZhdWx0IEdTSSBuYW1lIGZvciBxdWVyeWluZyB0b2tlbiByb3dzIGJ5IGBzZXNzaW9uSWRgLiAqL1xuY29uc3QgREVGQVVMVF9TRVNTSU9OX0lEX0lOREVYX05BTUUgPSAnc2Vzc2lvbklkLWluZGV4JztcblxuLyoqXG4gKiB7QGxpbmsgUmVmcmVzaFRva2VuU3RvcmV9IGltcGxlbWVudGF0aW9uIGJhY2tlZCBieSBhIHNpbmdsZSBEeW5hbW9EQiB0YWJsZS5cbiAqXG4gKiBJdGVtcyB1c2UgcGFydGl0aW9uIGtleSBgcGtgLCBsb2dpY2FsIGV4cGlyYXRpb24gYGV4cGlyZXNBdGAsIGFuZCBEeW5hbW9EQiBUVEwgYXR0cmlidXRlIGB0dGxgXG4gKiAoVW5peCBzZWNvbmRzKS4gRW5hYmxlIHRhYmxlIFRUTCBvbiBhdHRyaWJ1dGUgYHR0bGAgc28gZXhwaXJlZCBhbmQgcm90YXRlZCByb3dzIGFyZSByZW1vdmVkXG4gKiBhc3luY2hyb25vdXNseS4gU2Vzc2lvbi13aWRlIHJldm9jYXRpb24gcmVxdWlyZXMgYSBHU0kgd2hvc2UgcGFydGl0aW9uIGtleSBpcyBgc2Vzc2lvbklkYFxuICogKHNlZSB7QGxpbmsgU3RvcmVPcHRpb25zLnNlc3Npb25JZEluZGV4TmFtZX0pLiBUaGlzIGNsYXNzIG93bnMgdGhlIER5bmFtb0RCIGNsaWVudDsgY2FsbGVyc1xuICogc3VwcGx5IGB0YWJsZU5hbWVgLCBgcmVnaW9uYCwgYW5kIG9wdGlvbmFsIHtAbGluayBTdG9yZU9wdGlvbnN9LlxuICovXG5leHBvcnQgY2xhc3MgRHluYW1vZGJSZWZyZXNoVG9rZW5Qcm92aWRlciBpbXBsZW1lbnRzIFJlZnJlc2hUb2tlblN0b3JlIHtcbiAgLyoqIExhemlseSBpbml0aWFsaXplZCBhbmQgY2FjaGVkIGRvY3VtZW50IGNsaWVudC4gKi9cbiAgcHJpdmF0ZSBkZGI6IER5bmFtb0RCRG9jdW1lbnRDbGllbnQgfCBudWxsID0gbnVsbDtcblxuICAvKiogUmFuZG9tIGJ5dGUgbGVuZ3RoIGZvciBnZW5lcmF0ZWQgcmVmcmVzaCB0b2tlbnMgKGRlZmF1bHQgMzIg4oaSIDI1Ni1iaXQpLiAqL1xuICBwcml2YXRlIHJlYWRvbmx5IHRva2VuQnl0ZXMgPSAzMjtcblxuICAvKipcbiAgICogQHBhcmFtIHRhYmxlTmFtZSAtIER5bmFtb0RCIHRhYmxlIG5hbWUgZm9yIHJlZnJlc2ggdG9rZW4gaXRlbXMuXG4gICAqIEBwYXJhbSByZWdpb24gLSBBV1MgcmVnaW9uIGZvciB0aGUgRHluYW1vREIgY2xpZW50LlxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIFRva2VuIGxpZmV0aW1lLCBQSyBwcmVmaXgsIEdTSSBuYW1lLCByZXVzZSByZXZvY2F0aW9uLCBvciBjdXN0b20gZW5kcG9pbnQuXG4gICAqL1xuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlYWRvbmx5IHRhYmxlTmFtZTogc3RyaW5nLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgcmVnaW9uOiBzdHJpbmcsXG4gICAgcHJpdmF0ZSByZWFkb25seSBvcHRpb25zPzogU3RvcmVPcHRpb25zLFxuICApIHt9XG5cbiAgLyoqXG4gICAqIEluc2VydHMgYSBuZXcgdG9rZW4gcmVjb3JkIHdpdGggYGV4cGlyZXNBdGAgYW5kIG1hdGNoaW5nIGB0dGxgLiBGYWlscyB0aGUgcHV0IGlmIGBwa2AgYWxyZWFkeSBleGlzdHMuXG4gICAqXG4gICAqIEBwYXJhbSBwYXJhbXMgLSBTdWJqZWN0LCBzZXNzaW9uLCBhbmQgb3B0aW9uYWwgY2xvY2sgKGBub3dgKS5cbiAgICogQHJldHVybnMgUGxhaW50ZXh0IHJlZnJlc2ggdG9rZW4gYW5kIGV4cGlyYXRpb24gYXMgVW5peCBzZWNvbmRzLlxuICAgKi9cbiAgcHVibGljIGlzc3VlID0gYXN5bmMgKHBhcmFtczogSXNzdWVQYXJhbXMpOiBQcm9taXNlPElzc3VlUmVzdWx0PiA9PiB7XG4gICAgY29uc3QgZGRiID0gdGhpcy5nZXRkZGIoKTtcblxuICAgIGNvbnN0IG5vdyA9IHBhcmFtcy5ub3cgPz8gbmV3IERhdGUoKTtcbiAgICBjb25zdCBub3dTZWMgPSBlcG9jaHNlYyhub3cpO1xuICAgIGNvbnN0IGV4cGlyZXNBdCA9IHRoaXMubWFrZUV4cGlyZXNBdChub3dTZWMpO1xuXG4gICAgY29uc3QgcmVmcmVzaFRva2VuID0gcmFuZG9tdG9rZW4odGhpcy50b2tlbkJ5dGVzKTtcbiAgICBjb25zdCBoYXNoID0gc2hhMjU2aGV4KHJlZnJlc2hUb2tlbik7XG4gICAgY29uc3QgcGsgPSB0aGlzLmdldFByaW1hcnlLZXkoaGFzaCk7XG5cbiAgICBhd2FpdCBkZGIuc2VuZChcbiAgICAgIG5ldyBQdXRDb21tYW5kKHtcbiAgICAgICAgVGFibGVOYW1lOiB0aGlzLnRhYmxlTmFtZSxcbiAgICAgICAgSXRlbToge1xuICAgICAgICAgIHBrLFxuICAgICAgICAgIHN1YmplY3RJZDogcGFyYW1zLnN1YmplY3RJZCxcbiAgICAgICAgICBzZXNzaW9uSWQ6IHBhcmFtcy5zZXNzaW9uSWQsXG4gICAgICAgICAgY3JlYXRlZEF0OiBub3dTZWMsXG4gICAgICAgICAgZXhwaXJlc0F0LFxuICAgICAgICAgIHR0bDogZXhwaXJlc0F0LFxuICAgICAgICB9LFxuICAgICAgICBDb25kaXRpb25FeHByZXNzaW9uOiAnYXR0cmlidXRlX25vdF9leGlzdHMocGspJyxcbiAgICAgIH0pLFxuICAgICk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgcmVmcmVzaFRva2VuLFxuICAgICAgcmVmcmVzaFRva2VuRXhwaXJlc0F0OiBleHBpcmVzQXQsXG4gICAgfTtcbiAgfTtcblxuICAvKipcbiAgICogTWFya3MgdGhlIGN1cnJlbnQgdG9rZW4gYXMgcm90YXRlZCBhbmQgY3JlYXRlcyB0aGUgc3VjY2Vzc29yIHJvdyBpbiBvbmUgdHJhbnNhY3Rpb24uXG4gICAqXG4gICAqIFVwZGF0ZXMgdGhlIHByZXZpb3VzIHJvd+KAmXMgYHR0bGAgdG8gaXRzIGBleHBpcmVzQXRgIGFuZCBzZXRzIGB0dGxgIG9uIHRoZSBuZXcgUHV0IHRvIHRoZVxuICAgKiBzdWNjZXNzb3LigJlzIGV4cGlyYXRpb24gc28gRHluYW1vREIgY2FuIGRlbGV0ZSBib3RoIHdoZW4gYXBwcm9wcmlhdGUuXG4gICAqXG4gICAqIFdoZW4gcmV1c2UgaXMgZGV0ZWN0ZWQgYW5kIHtAbGluayBTdG9yZU9wdGlvbnMucmV2b2tlU2Vzc2lvbk9uUmV1c2V9IGlzIHRydWUsIGFsbCB0b2tlbnMgZm9yXG4gICAqIHRoZSBzYW1lIGBzZXNzaW9uSWRgIGFuZCBgc3ViamVjdElkYCBhcmUgcmV2b2tlZCB2aWEge0BsaW5rIER5bmFtb2RiUmVmcmVzaFRva2VuUHJvdmlkZXIucmV2b2tlU2Vzc2lvbn1cbiAgICogYmVmb3JlIHRocm93aW5nLlxuICAgKlxuICAgKiBAcGFyYW0gcGFyYW1zIC0gQ2xpZW50IHJlZnJlc2ggdG9rZW4gYW5kIG9wdGlvbmFsIGNsb2NrIChgbm93YCkuXG4gICAqIEByZXR1cm5zIFN1YmplY3QsIHNlc3Npb24sIG5ldyBwbGFpbnRleHQgdG9rZW4sIGFuZCBuZXcgZXhwaXJhdGlvbi5cbiAgICogQHRocm93cyB7QGxpbmsgUmVmcmVzaFRva2VuSW52YWxpZEVycm9yfSBXaGVuIHRoZSB0b2tlbiBmb3JtYXQgaXMgaW52YWxpZCBvciBubyByb3cgZXhpc3RzLlxuICAgKiBAdGhyb3dzIHtAbGluayBSZWZyZXNoVG9rZW5FeHBpcmVkRXJyb3J9IFdoZW4gYGV4cGlyZXNBdGAgaXMgbm90IGFmdGVyIGBub3dgLlxuICAgKiBAdGhyb3dzIHtAbGluayBSZWZyZXNoVG9rZW5SZXZva2VkRXJyb3J9IFdoZW4gdGhlIHRva2VuIHJvdyBoYXMgYHJldm9rZWRBdGAgc2V0LlxuICAgKiBAdGhyb3dzIHtAbGluayBSZWZyZXNoVG9rZW5SZXVzZWRFcnJvcn0gV2hlbiB0aGUgdG9rZW4gd2FzIGFscmVhZHkgcm90YXRlZCBvciB0aGUgdHJhbnNhY3Rpb25cbiAgICogICBpbmRpY2F0ZXMgcmV1c2UuIEluY2x1ZGVzIGBzdWJqZWN0SWRgIGFuZCBgc2Vzc2lvbklkYCBmcm9tIHRoZSBsb2FkZWQgcm93LlxuICAgKi9cbiAgcHVibGljIHJvdGF0ZSA9IGFzeW5jIChwYXJhbXM6IFJvdGF0ZVBhcmFtcyk6IFByb21pc2U8Um90YXRlUmVzdWx0PiA9PiB7XG4gICAgLy8gdmFsaWRhdGUgcmVmcmVzaCB0b2tlblxuICAgIHRoaXMudmFsaWRhdGVSZWZyZXNoVG9rZW4ocGFyYW1zLnJlZnJlc2hUb2tlbik7XG5cbiAgICBjb25zdCBkZGIgPSB0aGlzLmdldGRkYigpO1xuXG4gICAgY29uc3Qgbm93ID0gcGFyYW1zLm5vdyA/PyBuZXcgRGF0ZSgpO1xuICAgIGNvbnN0IG5vd1NlYyA9IGVwb2Noc2VjKG5vdyk7XG5cbiAgICBjb25zdCBjdXJyZW50SGFzaCA9IHNoYTI1NmhleChwYXJhbXMucmVmcmVzaFRva2VuKTtcbiAgICBjb25zdCBjdXJyZW50UGsgPSB0aGlzLmdldFByaW1hcnlLZXkoY3VycmVudEhhc2gpO1xuXG4gICAgY29uc3QgY3VycmVudCA9IGF3YWl0IHRoaXMuZ2V0VG9rZW5SZWNvcmQoY3VycmVudFBrKTtcbiAgICBpZiAoIWN1cnJlbnQpIHtcbiAgICAgIHRocm93IG5ldyBSZWZyZXNoVG9rZW5JbnZhbGlkRXJyb3IoKTtcbiAgICB9XG4gICAgaWYgKGN1cnJlbnQuZXhwaXJlc0F0IDw9IG5vd1NlYykge1xuICAgICAgdGhyb3cgbmV3IFJlZnJlc2hUb2tlbkV4cGlyZWRFcnJvcigpO1xuICAgIH1cbiAgICBpZiAoY3VycmVudC5yZXZva2VkQXQpIHtcbiAgICAgIHRocm93IG5ldyBSZWZyZXNoVG9rZW5SZXZva2VkRXJyb3IoKTtcbiAgICB9XG4gICAgaWYgKGN1cnJlbnQucm90YXRlZEF0KSB7XG4gICAgICBhd2FpdCB0aGlzLmhhbmRsZVJlZnJlc2hUb2tlblJldXNlKGN1cnJlbnQsIG5vdyk7XG4gICAgfVxuXG4gICAgY29uc3QgbmV4dFJlZnJlc2hUb2tlbkV4cGlyZXNBdCA9IHRoaXMubWFrZUV4cGlyZXNBdChub3dTZWMpO1xuICAgIGNvbnN0IG5leHRSZWZyZXNoVG9rZW4gPSByYW5kb210b2tlbih0aGlzLnRva2VuQnl0ZXMpO1xuICAgIGNvbnN0IG5leHRIYXNoID0gc2hhMjU2aGV4KG5leHRSZWZyZXNoVG9rZW4pO1xuICAgIGNvbnN0IG5leHRQayA9IHRoaXMuZ2V0UHJpbWFyeUtleShuZXh0SGFzaCk7XG5cbiAgICB0cnkge1xuICAgICAgYXdhaXQgZGRiLnNlbmQobmV3IFRyYW5zYWN0V3JpdGVDb21tYW5kKHtcbiAgICAgICAgVHJhbnNhY3RJdGVtczogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFVwZGF0ZToge1xuICAgICAgICAgICAgICBUYWJsZU5hbWU6IHRoaXMudGFibGVOYW1lLFxuICAgICAgICAgICAgICBLZXk6IHsgcGs6IGN1cnJlbnRQayB9LFxuICAgICAgICAgICAgICBVcGRhdGVFeHByZXNzaW9uOiAnU0VUIHJvdGF0ZWRBdCA9IDpub3csIHJlcGxhY2VkQnlQayA9IDpuZXh0UGssICN0dGwgPSA6dHRsJyxcbiAgICAgICAgICAgICAgQ29uZGl0aW9uRXhwcmVzc2lvbjogJ2F0dHJpYnV0ZV9leGlzdHMocGspIEFORCBhdHRyaWJ1dGVfbm90X2V4aXN0cyhyb3RhdGVkQXQpIEFORCBhdHRyaWJ1dGVfbm90X2V4aXN0cyhyZXZva2VkQXQpJyxcbiAgICAgICAgICAgICAgRXhwcmVzc2lvbkF0dHJpYnV0ZU5hbWVzOiB7XG4gICAgICAgICAgICAgICAgJyN0dGwnOiAndHRsJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlczoge1xuICAgICAgICAgICAgICAgICc6bm93Jzogbm93U2VjLFxuICAgICAgICAgICAgICAgICc6bmV4dFBrJzogbmV4dFBrLFxuICAgICAgICAgICAgICAgICc6dHRsJzogY3VycmVudC5leHBpcmVzQXQsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgUHV0OiB7XG4gICAgICAgICAgICAgIFRhYmxlTmFtZTogdGhpcy50YWJsZU5hbWUsXG4gICAgICAgICAgICAgIEl0ZW06IHtcbiAgICAgICAgICAgICAgICBwazogbmV4dFBrLFxuICAgICAgICAgICAgICAgIHN1YmplY3RJZDogY3VycmVudC5zdWJqZWN0SWQsXG4gICAgICAgICAgICAgICAgc2Vzc2lvbklkOiBjdXJyZW50LnNlc3Npb25JZCxcbiAgICAgICAgICAgICAgICBjcmVhdGVkQXQ6IG5vd1NlYyxcbiAgICAgICAgICAgICAgICBleHBpcmVzQXQ6IG5leHRSZWZyZXNoVG9rZW5FeHBpcmVzQXQsXG4gICAgICAgICAgICAgICAgdHRsOiBuZXh0UmVmcmVzaFRva2VuRXhwaXJlc0F0LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBDb25kaXRpb25FeHByZXNzaW9uOiAnYXR0cmlidXRlX25vdF9leGlzdHMocGspJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH0pKTtcblxuICAgIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBFcnJvciAmJiBlcnJvci5uYW1lID09PSAnVHJhbnNhY3Rpb25DYW5jZWxlZEV4Y2VwdGlvbicpIHtcbiAgICAgICAgLy8gVHJlYXQgY29uZGl0aW9uYWwgdHJhbnNhY3Rpb24gZmFpbHVyZSBhcyB0b2tlbiByZXVzZS5cbiAgICAgICAgYXdhaXQgdGhpcy5oYW5kbGVSZWZyZXNoVG9rZW5SZXVzZShjdXJyZW50LCBub3cpO1xuICAgICAgfVxuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIHN1YmplY3RJZDogY3VycmVudC5zdWJqZWN0SWQsXG4gICAgICBzZXNzaW9uSWQ6IGN1cnJlbnQuc2Vzc2lvbklkLFxuICAgICAgcmVmcmVzaFRva2VuOiBuZXh0UmVmcmVzaFRva2VuLFxuICAgICAgcmVmcmVzaFRva2VuRXhwaXJlc0F0OiBuZXh0UmVmcmVzaFRva2VuRXhwaXJlc0F0LFxuICAgIH07XG4gIH07XG5cbiAgLyoqXG4gICAqIFNldHMgYHJldm9rZWRBdGAgb24gdGhlIHRva2VuIHJvdy4gTWlzc2luZyBpdGVtcyBzdWNjZWVkIChpZGVtcG90ZW50IHJldm9rZSkuXG4gICAqXG4gICAqIERvZXMgbm90IHVwZGF0ZSBgdHRsYDsgZXhpc3RpbmcgYHR0bGAgZnJvbSBpc3N1ZS9yb3RhdGUgc3RpbGwgYXBwbGllcyBmb3IgRHluYW1vREIgY2xlYW51cC5cbiAgICpcbiAgICogQHBhcmFtIHBhcmFtcyAtIFJlZnJlc2ggdG9rZW4gYW5kIG9wdGlvbmFsIGNsb2NrIChgbm93YCkuXG4gICAqIEByZXR1cm5zIGB0cnVlYCBhZnRlciBhIHN1Y2Nlc3NmdWwgdXBkYXRlIG9yIG5vLW9wIHdoZW4gdGhlIGl0ZW0gaXMgYWJzZW50LlxuICAgKiBAdGhyb3dzIHtAbGluayBSZWZyZXNoVG9rZW5JbnZhbGlkRXJyb3J9IFdoZW4gdGhlIHRva2VuIHN0cmluZyBmb3JtYXQgaXMgaW52YWxpZC5cbiAgICovXG4gIHB1YmxpYyByZXZva2UgPSBhc3luYyAocGFyYW1zOiBSZXZva2VQYXJhbXMpOiBQcm9taXNlPHRydWU+ID0+IHtcbiAgICAvLyB2YWxpZGF0ZSByZWZyZXNoIHRva2VuXG4gICAgdGhpcy52YWxpZGF0ZVJlZnJlc2hUb2tlbihwYXJhbXMucmVmcmVzaFRva2VuKTtcblxuICAgIGNvbnN0IGRkYiA9IHRoaXMuZ2V0ZGRiKCk7XG5cbiAgICBjb25zdCBub3cgPSBwYXJhbXMubm93ID8/IG5ldyBEYXRlKCk7XG4gICAgY29uc3Qgbm93U2VjID0gZXBvY2hzZWMobm93KTtcblxuICAgIGNvbnN0IGhhc2ggPSBzaGEyNTZoZXgocGFyYW1zLnJlZnJlc2hUb2tlbik7XG4gICAgY29uc3QgcGsgPSB0aGlzLmdldFByaW1hcnlLZXkoaGFzaCk7XG5cbiAgICB0cnkge1xuICAgICAgYXdhaXQgZGRiLnNlbmQoXG4gICAgICAgIG5ldyBVcGRhdGVDb21tYW5kKHtcbiAgICAgICAgICBUYWJsZU5hbWU6IHRoaXMudGFibGVOYW1lLFxuICAgICAgICAgIEtleTogeyBwayB9LFxuICAgICAgICAgIFVwZGF0ZUV4cHJlc3Npb246ICdTRVQgcmV2b2tlZEF0ID0gOm5vdycsXG4gICAgICAgICAgQ29uZGl0aW9uRXhwcmVzc2lvbjogJ2F0dHJpYnV0ZV9leGlzdHMocGspJyxcbiAgICAgICAgICBFeHByZXNzaW9uQXR0cmlidXRlVmFsdWVzOiB7XG4gICAgICAgICAgICAnOm5vdyc6IG5vd1NlYyxcbiAgICAgICAgICB9LFxuICAgICAgICB9KSxcbiAgICAgICk7XG4gICAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICAgIC8vIE1pc3NpbmcgaXRlbTogdHJlYXQgYXMgc3VjY2VzcyAoaWRlbXBvdGVudCByZXZva2UpLlxuICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgRXJyb3IgJiYgZXJyb3IubmFtZSA9PT0gJ0NvbmRpdGlvbmFsQ2hlY2tGYWlsZWRFeGNlcHRpb24nKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9O1xuXG4gIC8qKlxuICAgKiBTZXRzIGByZXZva2VkQXRgIG9uIGV2ZXJ5IHRva2VuIHJvdyBmb3IgdGhlIGdpdmVuIGBzZXNzaW9uSWRgIChvcHRpb25hbGx5IGZpbHRlcmVkIGJ5IGBzdWJqZWN0SWRgKS5cbiAgICpcbiAgICogUXVlcmllcyB0aGUgc2Vzc2lvbiBHU0kgKHBhcnRpdGlvbiBrZXkgYHNlc3Npb25JZGA7IGBLRVlTX09OTFlgIGlzIGVub3VnaCksIHRoZW4gdXBkYXRlcyBlYWNoXG4gICAqIGJhc2UtdGFibGUgaXRlbS4gV2hlbiBgc3ViamVjdElkYCBpcyBzZXQsIGl0IGlzIHJlcXVpcmVkIGluIHRoZSBgVXBkYXRlSXRlbWAgY29uZGl0aW9uLlxuICAgKiBNaXNzaW5nIG9yIG5vbi1tYXRjaGluZyBpdGVtcyBhcmUgc2tpcHBlZCAoaWRlbXBvdGVudCkuIFBhZ2luYXRlIHdpdGggYExhc3RFdmFsdWF0ZWRLZXlgLlxuICAgKlxuICAgKiBAcGFyYW0gcGFyYW1zIC0gU2Vzc2lvbiBpZCwgb3B0aW9uYWwgc3ViamVjdCBmaWx0ZXIsIGFuZCBvcHRpb25hbCBjbG9jay5cbiAgICogQHJldHVybnMgQ291bnQgb2Ygcm93cyB1cGRhdGVkIHdpdGggYHJldm9rZWRBdGAgaW4gdGhpcyBjYWxsLlxuICAgKi9cbiAgcHVibGljIHJldm9rZVNlc3Npb24gPSBhc3luYyAocGFyYW1zOiBSZXZva2VTZXNzaW9uUGFyYW1zKTogUHJvbWlzZTxSZXZva2VTZXNzaW9uUmVzdWx0PiA9PiB7XG4gICAgY29uc3QgZGRiID0gdGhpcy5nZXRkZGIoKTtcblxuICAgIGNvbnN0IG5vdyA9IHBhcmFtcy5ub3cgPz8gbmV3IERhdGUoKTtcbiAgICBjb25zdCBub3dTZWMgPSBlcG9jaHNlYyhub3cpO1xuICAgIGNvbnN0IGluZGV4TmFtZSA9IHRoaXMub3B0aW9ucz8uc2Vzc2lvbklkSW5kZXhOYW1lID8/IERFRkFVTFRfU0VTU0lPTl9JRF9JTkRFWF9OQU1FO1xuXG4gICAgbGV0IHJldm9rZWRDb3VudCA9IDA7XG4gICAgbGV0IGV4Y2x1c2l2ZVN0YXJ0S2V5OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB8IHVuZGVmaW5lZDtcblxuICAgIC8qKiBXaGV0aGVyIGFub3RoZXIgUXVlcnkgcGFnZSBpcyBhdmFpbGFibGUgYWZ0ZXIgdGhlIHByZXZpb3VzIHJlc3BvbnNlLiAqL1xuICAgIGNvbnN0IHNob3VsZENvbnRpbnVlUGFnaW5nID0gKCk6IGJvb2xlYW4gPT4gZXhjbHVzaXZlU3RhcnRLZXkgIT09IHVuZGVmaW5lZDtcblxuICAgIGRvIHtcbiAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IGRkYi5zZW5kKFxuICAgICAgICBuZXcgUXVlcnlDb21tYW5kKHtcbiAgICAgICAgICBUYWJsZU5hbWU6IHRoaXMudGFibGVOYW1lLFxuICAgICAgICAgIEluZGV4TmFtZTogaW5kZXhOYW1lLFxuICAgICAgICAgIEtleUNvbmRpdGlvbkV4cHJlc3Npb246ICdzZXNzaW9uSWQgPSA6c2Vzc2lvbklkJyxcbiAgICAgICAgICBFeHByZXNzaW9uQXR0cmlidXRlVmFsdWVzOiB7XG4gICAgICAgICAgICAnOnNlc3Npb25JZCc6IHBhcmFtcy5zZXNzaW9uSWQsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBQcm9qZWN0aW9uRXhwcmVzc2lvbjogJ3BrJyxcbiAgICAgICAgICBFeGNsdXNpdmVTdGFydEtleTogZXhjbHVzaXZlU3RhcnRLZXksXG4gICAgICAgIH0pLFxuICAgICAgKTtcblxuICAgICAgY29uc3QgaXRlbXMgPSByZXMuSXRlbXMgPz8gW107XG4gICAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgaXRlbXMpIHtcbiAgICAgICAgY29uc3QgcGsgPSBpdGVtLnBrO1xuICAgICAgICBpZiAodHlwZW9mIHBrICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlczogUmVjb3JkPHN0cmluZywgc3RyaW5nIHwgbnVtYmVyPiA9IHtcbiAgICAgICAgICAnOm5vdyc6IG5vd1NlYyxcbiAgICAgICAgfTtcbiAgICAgICAgbGV0IGNvbmRpdGlvbkV4cHJlc3Npb24gPSAnYXR0cmlidXRlX2V4aXN0cyhwayknO1xuICAgICAgICBpZiAocGFyYW1zLnN1YmplY3RJZCkge1xuICAgICAgICAgIGNvbmRpdGlvbkV4cHJlc3Npb24gPSAnYXR0cmlidXRlX2V4aXN0cyhwaykgQU5EIHN1YmplY3RJZCA9IDpzdWJqZWN0SWQnO1xuICAgICAgICAgIGV4cHJlc3Npb25BdHRyaWJ1dGVWYWx1ZXNbJzpzdWJqZWN0SWQnXSA9IHBhcmFtcy5zdWJqZWN0SWQ7XG4gICAgICAgIH1cblxuICAgICAgICB0cnkge1xuICAgICAgICAgIGF3YWl0IGRkYi5zZW5kKFxuICAgICAgICAgICAgbmV3IFVwZGF0ZUNvbW1hbmQoe1xuICAgICAgICAgICAgICBUYWJsZU5hbWU6IHRoaXMudGFibGVOYW1lLFxuICAgICAgICAgICAgICBLZXk6IHsgcGsgfSxcbiAgICAgICAgICAgICAgVXBkYXRlRXhwcmVzc2lvbjogJ1NFVCByZXZva2VkQXQgPSA6bm93JyxcbiAgICAgICAgICAgICAgQ29uZGl0aW9uRXhwcmVzc2lvbjogY29uZGl0aW9uRXhwcmVzc2lvbixcbiAgICAgICAgICAgICAgRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlczogZXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICk7XG4gICAgICAgICAgcmV2b2tlZENvdW50ICs9IDE7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgRXJyb3IgJiYgZXJyb3IubmFtZSA9PT0gJ0NvbmRpdGlvbmFsQ2hlY2tGYWlsZWRFeGNlcHRpb24nKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgZXhjbHVzaXZlU3RhcnRLZXkgPSByZXMuTGFzdEV2YWx1YXRlZEtleSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB8IHVuZGVmaW5lZDtcbiAgICB9IHdoaWxlIChzaG91bGRDb250aW51ZVBhZ2luZygpKTtcblxuICAgIHJldHVybiB7IHJldm9rZWRDb3VudCB9O1xuICB9O1xuXG4gIC8qKlxuICAgKiBIYW5kbGVzIHJlZnJlc2gtdG9rZW4gcmV1c2UgZGV0ZWN0aW9uOiBvcHRpb25hbGx5IGNhc2NhZGVzIHtAbGluayBEeW5hbW9kYlJlZnJlc2hUb2tlblByb3ZpZGVyLnJldm9rZVNlc3Npb259XG4gICAqIHdoZW4ge0BsaW5rIFN0b3JlT3B0aW9ucy5yZXZva2VTZXNzaW9uT25SZXVzZX0gaXMgdHJ1ZSwgdGhlbiB0aHJvd3Mge0BsaW5rIFJlZnJlc2hUb2tlblJldXNlZEVycm9yfVxuICAgKiBwb3B1bGF0ZWQgd2l0aCBgc3ViamVjdElkYCAvIGBzZXNzaW9uSWRgIGZyb20gYGN1cnJlbnRgLlxuICAgKlxuICAgKiBAcGFyYW0gY3VycmVudCAtIFRva2VuIHJvdyB0aGF0IGluZGljYXRlZCByZXVzZSAoYHJvdGF0ZWRBdGAgc2V0IG9yIHRyYW5zYWN0aW9uIGNhbmNlbGVkKS5cbiAgICogQHBhcmFtIG5vdyAtIENsb2NrIHVzZWQgZm9yIGByZXZva2VkQXRgIHdoZW4gY2FzY2FkaW5nIHJldm9rZSBpcyBlbmFibGVkLlxuICAgKiBAdGhyb3dzIHtAbGluayBSZWZyZXNoVG9rZW5SZXVzZWRFcnJvcn0gQWx3YXlzIChyZXR1cm4gdHlwZSBpcyBgbmV2ZXJgKS5cbiAgICovXG4gIHByaXZhdGUgaGFuZGxlUmVmcmVzaFRva2VuUmV1c2UgPSBhc3luYyAoY3VycmVudDogVG9rZW5SZWNvcmQsIG5vdzogRGF0ZSk6IFByb21pc2U8bmV2ZXI+ID0+IHtcbiAgICBpZiAodGhpcy5vcHRpb25zPy5yZXZva2VTZXNzaW9uT25SZXVzZSkge1xuICAgICAgYXdhaXQgdGhpcy5yZXZva2VTZXNzaW9uKHtcbiAgICAgICAgc2Vzc2lvbklkOiBjdXJyZW50LnNlc3Npb25JZCxcbiAgICAgICAgc3ViamVjdElkOiBjdXJyZW50LnN1YmplY3RJZCxcbiAgICAgICAgbm93LFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgdGhyb3cgbmV3IFJlZnJlc2hUb2tlblJldXNlZEVycm9yKHVuZGVmaW5lZCwge1xuICAgICAgc3ViamVjdElkOiBjdXJyZW50LnN1YmplY3RJZCxcbiAgICAgIHNlc3Npb25JZDogY3VycmVudC5zZXNzaW9uSWQsXG4gICAgfSk7XG4gIH07XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIGNhY2hlZCB7QGxpbmsgRHluYW1vREJEb2N1bWVudENsaWVudH0sIGNyZWF0aW5nIGl0IG9uIGZpcnN0IHVzZS5cbiAgICpcbiAgICogQHJldHVybnMgRG9jdW1lbnQgY2xpZW50IGNvbmZpZ3VyZWQgZm9yIGByZWdpb25gIGFuZCBvcHRpb25hbCBgZW5kcG9pbnRgLlxuICAgKi9cbiAgcHJpdmF0ZSBnZXRkZGIgPSAoKTogRHluYW1vREJEb2N1bWVudENsaWVudCA9PiB7XG4gICAgaWYgKCF0aGlzLmRkYikge1xuICAgICAgY29uc3QgY2xpZW50ID0gbmV3IER5bmFtb0RCQ2xpZW50KHtcbiAgICAgICAgcmVnaW9uOiB0aGlzLnJlZ2lvbixcbiAgICAgICAgZW5kcG9pbnQ6ICgoKSA9PiB7XG4gICAgICAgICAgaWYgKHRoaXMub3B0aW9ucz8uZW5kcG9pbnQpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLm9wdGlvbnMuZW5kcG9pbnQ7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBgaHR0cHM6Ly9keW5hbW9kYi4ke3RoaXMucmVnaW9ufS5hbWF6b25hd3MuY29tYDtcbiAgICAgICAgfSkoKSxcbiAgICAgIH0pO1xuICAgICAgdGhpcy5kZGIgPSBEeW5hbW9EQkRvY3VtZW50Q2xpZW50LmZyb20oY2xpZW50KTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuZGRiO1xuICB9O1xuXG4gIC8qKlxuICAgKiBMb2FkcyBhIHRva2VuIHJvdyBieSBwYXJ0aXRpb24ga2V5LlxuICAgKlxuICAgKiBAcGFyYW0gcGsgLSBGdWxsIHBhcnRpdGlvbiBrZXkgKGBwcmVmaXhgICsgaGFzaCkuXG4gICAqIEByZXR1cm5zIFBhcnNlZCB7QGxpbmsgVG9rZW5SZWNvcmR9LCBvciBgbnVsbGAgaWYgdGhlIGl0ZW0gZG9lcyBub3QgZXhpc3QuXG4gICAqL1xuICBwcml2YXRlIGdldFRva2VuUmVjb3JkID0gYXN5bmMgKHBrOiBzdHJpbmcpOiBQcm9taXNlPFRva2VuUmVjb3JkIHwgbnVsbD4gPT4ge1xuICAgIGNvbnN0IGRkYiA9IHRoaXMuZ2V0ZGRiKCk7XG5cbiAgICBjb25zdCByZXMgPSBhd2FpdCBkZGIuc2VuZChcbiAgICAgIG5ldyBHZXRDb21tYW5kKHtcbiAgICAgICAgVGFibGVOYW1lOiB0aGlzLnRhYmxlTmFtZSxcbiAgICAgICAgS2V5OiB7IHBrIH0sXG4gICAgICAgIENvbnNpc3RlbnRSZWFkOiB0aGlzLm9wdGlvbnM/LmNvbnNpc3RlbnRSZWFkID8/IHRydWUsXG4gICAgICB9KSxcbiAgICApO1xuICAgIHJldHVybiAocmVzLkl0ZW0gYXMgVG9rZW5SZWNvcmQpID8/IG51bGw7XG4gIH07XG5cbiAgLyoqXG4gICAqIEVmZmVjdGl2ZSBwYXJ0aXRpb24ga2V5IHByZWZpeCBmcm9tIHtAbGluayBTdG9yZU9wdGlvbnN9IG9yIHtAbGluayBERUZBVUxUX1BSSU1BUllfS0VZX1BSRUZJWH0uXG4gICAqXG4gICAqIEByZXR1cm5zIFByZWZpeCBzdHJpbmcgKGUuZy4gYHJ0I2ApLlxuICAgKi9cbiAgcHJpdmF0ZSBnZXRQcmltYXJ5S2V5UHJlZml4ID0gKCk6IHN0cmluZyA9PiB7XG4gICAgcmV0dXJuIGAke3RoaXMub3B0aW9ucz8ucGtQcmVmaXggPz8gREVGQVVMVF9QUklNQVJZX0tFWV9QUkVGSVh9YDtcbiAgfTtcblxuICAvKipcbiAgICogQnVpbGRzIHRoZSBmdWxsIHBhcnRpdGlvbiBrZXkgZm9yIGEgdG9rZW4gaGFzaC5cbiAgICpcbiAgICogQHBhcmFtIGhhc2ggLSBTSEEtMjU2IGhleCBkaWdlc3Qgb2YgdGhlIHBsYWludGV4dCB0b2tlbi5cbiAgICogQHJldHVybnMgYHByZWZpeGAgKyBgaGFzaGAuXG4gICAqL1xuICBwcml2YXRlIGdldFByaW1hcnlLZXkgPSAoaGFzaDogc3RyaW5nKTogc3RyaW5nID0+IHtcbiAgICByZXR1cm4gYCR7dGhpcy5nZXRQcmltYXJ5S2V5UHJlZml4KCl9JHtoYXNofWA7XG4gIH07XG5cbiAgLyoqXG4gICAqIENvbXB1dGVzIGxvZ2ljYWwgZXhwaXJhdGlvbiAoYGV4cGlyZXNBdGAgLyBgdHRsYCkgYXMgYG5vd1NlY2AgcGx1cyB7QGxpbmsgU3RvcmVPcHRpb25zLnR0bERheXN9LlxuICAgKlxuICAgKiBAcGFyYW0gbm93U2VjIC0gQ3VycmVudCB0aW1lIGFzIFVuaXggc2Vjb25kcy5cbiAgICogQHJldHVybnMgRXhwaXJhdGlvbiB0aW1lc3RhbXAgaW4gVW5peCBzZWNvbmRzIChkZWZhdWx0IGxpZmV0aW1lOiA2MCBkYXlzKS5cbiAgICovXG4gIHByaXZhdGUgbWFrZUV4cGlyZXNBdCA9IChub3dTZWM6IG51bWJlcik6IG51bWJlciA9PiB7XG4gICAgcmV0dXJuIG5vd1NlYyArICh0aGlzLm9wdGlvbnM/LnR0bERheXMgPz8gNjApICogMjQgKiA2MCAqIDYwO1xuICB9O1xuXG4gIC8qKlxuICAgKiBFbnN1cmVzIHRoZSB0b2tlbiBpcyBub24tZW1wdHkgYW5kIG1hdGNoZXMgdGhlIGV4cGVjdGVkIGJhc2U2NHVybCBsZW5ndGggZm9yIGB0b2tlbkJ5dGVzYC5cbiAgICpcbiAgICogQHBhcmFtIHRva2VuIC0gUGxhaW50ZXh0IHJlZnJlc2ggdG9rZW4gZnJvbSB0aGUgY2xpZW50LlxuICAgKiBAdGhyb3dzIHtAbGluayBSZWZyZXNoVG9rZW5JbnZhbGlkRXJyb3J9IFdoZW4gdmFsaWRhdGlvbiBmYWlscy5cbiAgICovXG4gIHByaXZhdGUgdmFsaWRhdGVSZWZyZXNoVG9rZW4odG9rZW46IHN0cmluZyk6IHZvaWQge1xuICAgIGlmICghdG9rZW4gfHwgdG9rZW4ubGVuZ3RoICE9PSBNYXRoLmNlaWwodGhpcy50b2tlbkJ5dGVzICogOCAvIDYpKSB7XG4gICAgICB0aHJvdyBuZXcgUmVmcmVzaFRva2VuSW52YWxpZEVycm9yKCk7XG4gICAgfVxuICB9XG5cbn1cbiJdfQ==
438
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHluYW1vZGIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc3RvcmVzL2R5bmFtb2RiLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLDhEQUEwRDtBQUMxRCx3REFBMEk7QUFFMUksaUVBS2dDO0FBZ0JoQyx3Q0FBdUQ7QUFDdkQsd0NBQXlDO0FBbUJ6Qyw0REFBNEQ7QUFDNUQsTUFBTSwwQkFBMEIsR0FBRyxLQUFLLENBQUM7QUFFekMsK0RBQStEO0FBQy9ELE1BQU0sNkJBQTZCLEdBQUcsaUJBQWlCLENBQUM7QUFFeEQsK0RBQStEO0FBQy9ELE1BQU0sNkJBQTZCLEdBQUcsaUJBQWlCLENBQUM7QUFFeEQsOEVBQThFO0FBQzlFLE1BQU0sbUJBQW1CLEdBQUcsRUFBRSxDQUFDO0FBRS9CLGlGQUFpRjtBQUNqRixNQUFNLGdCQUFnQixHQUFHLEVBQUUsQ0FBQztBQUU1Qjs7Ozs7Ozs7R0FRRztBQUNILE1BQWEsNEJBQTRCO0lBT3ZDOzs7O09BSUc7SUFDSCxZQUNtQixTQUFpQixFQUNqQixNQUFjLEVBQ2QsT0FBc0I7UUFGdEIsY0FBUyxHQUFULFNBQVMsQ0FBUTtRQUNqQixXQUFNLEdBQU4sTUFBTSxDQUFRO1FBQ2QsWUFBTyxHQUFQLE9BQU8sQ0FBZTtRQWR6QyxxREFBcUQ7UUFDN0MsUUFBRyxHQUFrQyxJQUFJLENBQUM7UUFtQmxEOzs7OztXQUtHO1FBQ0ksVUFBSyxHQUFHLEtBQUssRUFBRSxNQUFtQixFQUF3QixFQUFFO1lBQ2pFLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUUxQixNQUFNLEdBQUcsR0FBRyxNQUFNLENBQUMsR0FBRyxJQUFJLElBQUksSUFBSSxFQUFFLENBQUM7WUFDckMsTUFBTSxNQUFNLEdBQUcsSUFBQSxlQUFRLEVBQUMsR0FBRyxDQUFDLENBQUM7WUFDN0IsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUU3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SyxTQUFTLElBQUksT0FBTyxDQUFDLFVBQVUsSUFBSSxDQUFDLEVBQUUsQ0FBQztnQkFDakUsTUFBTSxJQUFJLFVBQVUsQ0FBQyxzQ0FBc0MsQ0FBQyxDQUFDO1lBQy9ELENBQUM7WUFDRCxJQUFJLE9BQU8sRUFBRSxPQUFPLEtBQUssU0FBUyxJQUFJLE9BQU8sQ0FBQyxPQUFPLElBQUksQ0FBQyxFQUFFLENBQUM7Z0JBQzNELE1BQU0sSUFBSSxVQUFVLENBQUMsbUNBQW1DLENBQUMsQ0FBQztZQUM1RCxDQUFDO1FBQ0gsQ0FBQyxDQUFDO1FBMWJBLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFDbkUsSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUN4QyxDQUFDO0lBMGJEOzs7OztPQUtHO0lBQ0ssb0JBQW9CLENBQUMsS0FBYTtRQUN4QyxJQUFJLENBQUMsS0FBSyxJQUFJLEtBQUssQ0FBQyxNQUFNLEtBQUssSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDO1lBQ2xFLE1BQU0sSUFBSSwrQ0FBd0IsRUFBRSxDQUFDO1FBQ3ZDLENBQUM7SUFDSCxDQUFDO0NBRUY7QUF6ZEQsb0VBeWRDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRHluYW1vREJDbGllbnQgfSBmcm9tICdAYXdzLXNkay9jbGllbnQtZHluYW1vZGInO1xuaW1wb3J0IHsgRHluYW1vREJEb2N1bWVudENsaWVudCwgR2V0Q29tbWFuZCwgUHV0Q29tbWFuZCwgUXVlcnlDb21tYW5kLCBVcGRhdGVDb21tYW5kLCBUcmFuc2FjdFdyaXRlQ29tbWFuZCB9IGZyb20gJ0Bhd3Mtc2RrL2xpYi1keW5hbW9kYic7XG5cbmltcG9ydCB7XG4gIFJlZnJlc2hUb2tlbkV4cGlyZWRFcnJvcixcbiAgUmVmcmVzaFRva2VuSW52YWxpZEVycm9yLFxuICBSZWZyZXNoVG9rZW5SZXVzZWRFcnJvcixcbiAgUmVmcmVzaFRva2VuUmV2b2tlZEVycm9yLFxufSBmcm9tICcuL3JlZnJlc2gtdG9rZW4tZXJyb3JzJztcbmltcG9ydCB0eXBlIHtcbiAgUmVmcmVzaFRva2VuU3RvcmUsXG4gIFN0b3JlT3B0aW9ucyxcbiAgRG9jdW1lbnRDbGllbnRUcmFuc2xhdGVDb25maWcsXG4gIFRva2VuUmVjb3JkLFxuICBJc3N1ZVBhcmFtcyxcbiAgUm90YXRlUGFyYW1zLFxuICBSZXZva2VQYXJhbXMsXG4gIFJldm9rZVNlc3Npb25QYXJhbXMsXG4gIFJldm9rZVNlc3Npb25SZXN1bHQsXG4gIFJldm9rZVN1YmplY3RQYXJhbXMsXG4gIFJldm9rZVN1YmplY3RSZXN1bHQsXG4gIElzc3VlUmVzdWx0LFxuICBSb3RhdGVSZXN1bHQsXG59IGZyb20gJy4uL3R5cGVzL2luZGV4JztcbmltcG9ydCB7IHJhbmRvbXRva2VuLCBzaGEyNTZoZXggfSBmcm9tICcuLi91dGlscy9oYXNoJztcbmltcG9ydCB7IGVwb2Noc2VjIH0gZnJvbSAnLi4vdXRpbHMvdGltZSc7XG5cbi8qKiBSZS1leHBvcnRlZCB0eXBlcyBmb3IgY29uc3VtZXJzIHRoYXQgaW1wb3J0IHRoZSBEeW5hbW9EQiBzdG9yZSBtb2R1bGUuICovXG5leHBvcnQge1xuICBSZWZyZXNoVG9rZW5TdG9yZSxcbiAgU3RvcmVPcHRpb25zLFxuICBEb2N1bWVudENsaWVudFRyYW5zbGF0ZUNvbmZpZyxcbiAgVG9rZW5SZWNvcmQsXG4gIElzc3VlUGFyYW1zLFxuICBSb3RhdGVQYXJhbXMsXG4gIFJldm9rZVBhcmFtcyxcbiAgUmV2b2tlU2Vzc2lvblBhcmFtcyxcbiAgUmV2b2tlU2Vzc2lvblJlc3VsdCxcbiAgUmV2b2tlU3ViamVjdFBhcmFtcyxcbiAgUmV2b2tlU3ViamVjdFJlc3VsdCxcbiAgSXNzdWVSZXN1bHQsXG4gIFJvdGF0ZVJlc3VsdCxcbn07XG5cbi8qKiBEZWZhdWx0IHBhcnRpdGlvbiBrZXkgcHJlZml4IGZvciByZWZyZXNoIHRva2VuIGl0ZW1zLiAqL1xuY29uc3QgREVGQVVMVF9QUklNQVJZX0tFWV9QUkVGSVggPSAncnQjJztcblxuLyoqIERlZmF1bHQgR1NJIG5hbWUgZm9yIHF1ZXJ5aW5nIHRva2VuIHJvd3MgYnkgYHNlc3Npb25JZGAuICovXG5jb25zdCBERUZBVUxUX1NFU1NJT05fSURfSU5ERVhfTkFNRSA9ICdzZXNzaW9uSWQtaW5kZXgnO1xuXG4vKiogRGVmYXVsdCBHU0kgbmFtZSBmb3IgcXVlcnlpbmcgdG9rZW4gcm93cyBieSBgc3ViamVjdElkYC4gKi9cbmNvbnN0IERFRkFVTFRfU1VCSkVDVF9JRF9JTkRFWF9OQU1FID0gJ3N1YmplY3RJZC1pbmRleCc7XG5cbi8qKiBEZWZhdWx0IHJhbmRvbSBieXRlIGxlbmd0aCBmb3IgZ2VuZXJhdGVkIHJlZnJlc2ggdG9rZW5zICgzMiDihpIgMjU2LWJpdCkuICovXG5jb25zdCBERUZBVUxUX1RPS0VOX0JZVEVTID0gMzI7XG5cbi8qKiBEZWZhdWx0IHRva2VuIGxpZmV0aW1lIGluIGRheXMgd2hlbiBuZWl0aGVyIHR0bFNlY29uZHMgbm9yIHR0bERheXMgaXMgc2V0LiAqL1xuY29uc3QgREVGQVVMVF9UVExfREFZUyA9IDYwO1xuXG4vKipcbiAqIHtAbGluayBSZWZyZXNoVG9rZW5TdG9yZX0gaW1wbGVtZW50YXRpb24gYmFja2VkIGJ5IGEgc2luZ2xlIER5bmFtb0RCIHRhYmxlLlxuICpcbiAqIEl0ZW1zIHVzZSBwYXJ0aXRpb24ga2V5IGBwa2AsIGxvZ2ljYWwgZXhwaXJhdGlvbiBgZXhwaXJlc0F0YCwgYW5kIER5bmFtb0RCIFRUTCBhdHRyaWJ1dGUgYHR0bGBcbiAqIChVbml4IHNlY29uZHMpLiBFbmFibGUgdGFibGUgVFRMIG9uIGF0dHJpYnV0ZSBgdHRsYCBzbyBleHBpcmVkIGFuZCByb3RhdGVkIHJvd3MgYXJlIHJlbW92ZWRcbiAqIGFzeW5jaHJvbm91c2x5LiBTZXNzaW9uLXdpZGUgcmV2b2NhdGlvbiByZXF1aXJlcyBhIEdTSSB3aG9zZSBwYXJ0aXRpb24ga2V5IGlzIGBzZXNzaW9uSWRgXG4gKiAoc2VlIHtAbGluayBTdG9yZU9wdGlvbnMuc2Vzc2lvbklkSW5kZXhOYW1lfSkuIFRoaXMgY2xhc3Mgb3ducyB0aGUgRHluYW1vREIgY2xpZW50OyBjYWxsZXJzXG4gKiBzdXBwbHkgYHRhYmxlTmFtZWAsIGByZWdpb25gLCBhbmQgb3B0aW9uYWwge0BsaW5rIFN0b3JlT3B0aW9uc30uXG4gKi9cbmV4cG9ydCBjbGFzcyBEeW5hbW9kYlJlZnJlc2hUb2tlblByb3ZpZGVyIGltcGxlbWVudHMgUmVmcmVzaFRva2VuU3RvcmUge1xuICAvKiogTGF6aWx5IGluaXRpYWxpemVkIGFuZCBjYWNoZWQgZG9jdW1lbnQgY2xpZW50LiAqL1xuICBwcml2YXRlIGRkYjogRHluYW1vREJEb2N1bWVudENsaWVudCB8IG51bGwgPSBudWxsO1xuXG4gIC8qKiBSYW5kb20gYnl0ZSBsZW5ndGggZm9yIGdlbmVyYXRlZCByZWZyZXNoIHRva2Vucy4gKi9cbiAgcHJpdmF0ZSByZWFkb25seSB0b2tlbkJ5dGVzOiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB0YWJsZU5hbWUgLSBEeW5hbW9EQiB0YWJsZSBuYW1lIGZvciByZWZyZXNoIHRva2VuIGl0ZW1zLlxuICAgKiBAcGFyYW0gcmVnaW9uIC0gQVdTIHJlZ2lvbiBmb3IgdGhlIER5bmFtb0RCIGNsaWVudC5cbiAgICogQHBhcmFtIG9wdGlvbnMgLSBUb2tlbiBsaWZldGltZSwgUEsgcHJlZml4LCBHU0kgbmFtZSwgcmV1c2UgcmV2b2NhdGlvbiwgb3IgY3VzdG9tIGVuZHBvaW50LlxuICAgKi9cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSB0YWJsZU5hbWU6IHN0cmluZyxcbiAgICBwcml2YXRlIHJlYWRvbmx5IHJlZ2lvbjogc3RyaW5nLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgb3B0aW9ucz86IFN0b3JlT3B0aW9ucyxcbiAgKSB7XG4gICAgdGhpcy50b2tlbkJ5dGVzID0gdGhpcy5yZXNvbHZlVG9rZW5CeXRlcyh0aGlzLm9wdGlvbnM/LnRva2VuQnl0ZXMpO1xuICAgIHRoaXMudmFsaWRhdGVUdGxPcHRpb25zKHRoaXMub3B0aW9ucyk7XG4gIH1cblxuICAvKipcbiAgICogSW5zZXJ0cyBhIG5ldyB0b2tlbiByZWNvcmQgd2l0aCBgZXhwaXJlc0F0YCBhbmQgbWF0Y2hpbmcgYHR0bGAuIEZhaWxzIHRoZSBwdXQgaWYgYHBrYCBhbHJlYWR5IGV4aXN0cy5cbiAgICpcbiAgICogQHBhcmFtIHBhcmFtcyAtIFN1YmplY3QsIHNlc3Npb24sIGFuZCBvcHRpb25hbCBjbG9jayAoYG5vd2ApLlxuICAgKiBAcmV0dXJucyBQbGFpbnRleHQgcmVmcmVzaCB0b2tlbiBhbmQgZXhwaXJhdGlvbiBhcyBVbml4IHNlY29uZHMuXG4gICAqL1xuICBwdWJsaWMgaXNzdWUgPSBhc3luYyAocGFyYW1zOiBJc3N1ZVBhcmFtcyk6IFByb21pc2U8SXNzdWVSZXN1bHQ+ID0+IHtcbiAgICBjb25zdCBkZGIgPSB0aGlzLmdldGRkYigpO1xuXG4gICAgY29uc3Qgbm93ID0gcGFyYW1zLm5vdyA/PyBuZXcgRGF0ZSgpO1xuICAgIGNvbnN0IG5vd1NlYyA9IGVwb2Noc2VjKG5vdyk7XG4gICAgY29uc3QgZXhwaXJlc0F0ID0gdGhpcy5tYWtlRXhwaXJlc0F0KG5vd1NlYyk7XG5cbiAgICBjb25zdCByZWZyZXNoVG9rZW4gPSByYW5kb210b2tlbih0aGlzLnRva2VuQnl0ZXMpO1xuICAgIGNvbnN0IGhhc2ggPSBzaGEyNTZoZXgocmVmcmVzaFRva2VuKTtcbiAgICBjb25zdCBwayA9IHRoaXMuZ2V0UHJpbWFyeUtleShoYXNoKTtcblxuICAgIGF3YWl0IGRkYi5zZW5kKFxuICAgICAgbmV3IFB1dENvbW1hbmQoe1xuICAgICAgICBUYWJsZU5hbWU6IHRoaXMudGFibGVOYW1lLFxuICAgICAgICBJdGVtOiB7XG4gICAgICAgICAgcGssXG4gICAgICAgICAgc3ViamVjdElkOiBwYXJhbXMuc3ViamVjdElkLFxuICAgICAgICAgIHNlc3Npb25JZDogcGFyYW1zLnNlc3Npb25JZCxcbiAgICAgICAgICBjcmVhdGVkQXQ6IG5vd1NlYyxcbiAgICAgICAgICBleHBpcmVzQXQsXG4gICAgICAgICAgdHRsOiBleHBpcmVzQXQsXG4gICAgICAgIH0sXG4gICAgICAgIENvbmRpdGlvbkV4cHJlc3Npb246ICdhdHRyaWJ1dGVfbm90X2V4aXN0cyhwayknLFxuICAgICAgfSksXG4gICAgKTtcblxuICAgIHJldHVybiB7XG4gICAgICByZWZyZXNoVG9rZW4sXG4gICAgICByZWZyZXNoVG9rZW5FeHBpcmVzQXQ6IGV4cGlyZXNBdCxcbiAgICB9O1xuICB9O1xuXG4gIC8qKlxuICAgKiBNYXJrcyB0aGUgY3VycmVudCB0b2tlbiBhcyByb3RhdGVkIGFuZCBjcmVhdGVzIHRoZSBzdWNjZXNzb3Igcm93IGluIG9uZSB0cmFuc2FjdGlvbi5cbiAgICpcbiAgICogVXBkYXRlcyB0aGUgcHJldmlvdXMgcm934oCZcyBgdHRsYCB0byBpdHMgYGV4cGlyZXNBdGAgYW5kIHNldHMgYHR0bGAgb24gdGhlIG5ldyBQdXQgdG8gdGhlXG4gICAqIHN1Y2Nlc3NvcuKAmXMgZXhwaXJhdGlvbiBzbyBEeW5hbW9EQiBjYW4gZGVsZXRlIGJvdGggd2hlbiBhcHByb3ByaWF0ZS5cbiAgICpcbiAgICogV2hlbiByZXVzZSBpcyBkZXRlY3RlZCBhbmQge0BsaW5rIFN0b3JlT3B0aW9ucy5yZXZva2VTZXNzaW9uT25SZXVzZX0gaXMgdHJ1ZSwgYWxsIHRva2VucyBmb3JcbiAgICogdGhlIHNhbWUgYHNlc3Npb25JZGAgYW5kIGBzdWJqZWN0SWRgIGFyZSByZXZva2VkIHZpYSB7QGxpbmsgRHluYW1vZGJSZWZyZXNoVG9rZW5Qcm92aWRlci5yZXZva2VTZXNzaW9ufVxuICAgKiBiZWZvcmUgdGhyb3dpbmcuXG4gICAqXG4gICAqIEBwYXJhbSBwYXJhbXMgLSBDbGllbnQgcmVmcmVzaCB0b2tlbiBhbmQgb3B0aW9uYWwgY2xvY2sgKGBub3dgKS5cbiAgICogQHJldHVybnMgU3ViamVjdCwgc2Vzc2lvbiwgbmV3IHBsYWludGV4dCB0b2tlbiwgYW5kIG5ldyBleHBpcmF0aW9uLlxuICAgKiBAdGhyb3dzIHtAbGluayBSZWZyZXNoVG9rZW5JbnZhbGlkRXJyb3J9IFdoZW4gdGhlIHRva2VuIGZvcm1hdCBpcyBpbnZhbGlkIG9yIG5vIHJvdyBleGlzdHMuXG4gICAqIEB0aHJvd3Mge0BsaW5rIFJlZnJlc2hUb2tlbkV4cGlyZWRFcnJvcn0gV2hlbiBgZXhwaXJlc0F0YCBpcyBub3QgYWZ0ZXIgYG5vd2AuXG4gICAqIEB0aHJvd3Mge0BsaW5rIFJlZnJlc2hUb2tlblJldm9rZWRFcnJvcn0gV2hlbiB0aGUgdG9rZW4gcm93IGhhcyBgcmV2b2tlZEF0YCBzZXQuXG4gICAqIEB0aHJvd3Mge0BsaW5rIFJlZnJlc2hUb2tlblJldXNlZEVycm9yfSBXaGVuIHRoZSB0b2tlbiB3YXMgYWxyZWFkeSByb3RhdGVkIG9yIHRoZSB0cmFuc2FjdGlvblxuICAgKiAgIGluZGljYXRlcyByZXVzZS4gSW5jbHVkZXMgYHN1YmplY3RJZGAgYW5kIGBzZXNzaW9uSWRgIGZyb20gdGhlIGxvYWRlZCByb3cuXG4gICAqL1xuICBwdWJsaWMgcm90YXRlID0gYXN5bmMgKHBhcmFtczogUm90YXRlUGFyYW1zKTogUHJvbWlzZTxSb3RhdGVSZXN1bHQ+ID0+IHtcbiAgICAvLyB2YWxpZGF0ZSByZWZyZXNoIHRva2VuXG4gICAgdGhpcy52YWxpZGF0ZVJlZnJlc2hUb2tlbihwYXJhbXMucmVmcmVzaFRva2VuKTtcblxuICAgIGNvbnN0IGRkYiA9IHRoaXMuZ2V0ZGRiKCk7XG5cbiAgICBjb25zdCBub3cgPSBwYXJhbXMubm93ID8/IG5ldyBEYXRlKCk7XG4gICAgY29uc3Qgbm93U2VjID0gZXBvY2hzZWMobm93KTtcblxuICAgIGNvbnN0IGN1cnJlbnRIYXNoID0gc2hhMjU2aGV4KHBhcmFtcy5yZWZyZXNoVG9rZW4pO1xuICAgIGNvbnN0IGN1cnJlbnRQayA9IHRoaXMuZ2V0UHJpbWFyeUtleShjdXJyZW50SGFzaCk7XG5cbiAgICBjb25zdCBjdXJyZW50ID0gYXdhaXQgdGhpcy5nZXRUb2tlblJlY29yZChjdXJyZW50UGspO1xuICAgIGlmICghY3VycmVudCkge1xuICAgICAgdGhyb3cgbmV3IFJlZnJlc2hUb2tlbkludmFsaWRFcnJvcigpO1xuICAgIH1cbiAgICBpZiAoY3VycmVudC5leHBpcmVzQXQgPD0gbm93U2VjKSB7XG4gICAgICB0aHJvdyBuZXcgUmVmcmVzaFRva2VuRXhwaXJlZEVycm9yKCk7XG4gICAgfVxuICAgIGlmIChjdXJyZW50LnJldm9rZWRBdCkge1xuICAgICAgdGhyb3cgbmV3IFJlZnJlc2hUb2tlblJldm9rZWRFcnJvcigpO1xuICAgIH1cbiAgICBpZiAoY3VycmVudC5yb3RhdGVkQXQpIHtcbiAgICAgIGF3YWl0IHRoaXMuaGFuZGxlUmVmcmVzaFRva2VuUmV1c2UoY3VycmVudCwgbm93KTtcbiAgICB9XG5cbiAgICBjb25zdCBuZXh0UmVmcmVzaFRva2VuRXhwaXJlc0F0ID0gdGhpcy5tYWtlRXhwaXJlc0F0KG5vd1NlYyk7XG4gICAgY29uc3QgbmV4dFJlZnJlc2hUb2tlbiA9IHJhbmRvbXRva2VuKHRoaXMudG9rZW5CeXRlcyk7XG4gICAgY29uc3QgbmV4dEhhc2ggPSBzaGEyNTZoZXgobmV4dFJlZnJlc2hUb2tlbik7XG4gICAgY29uc3QgbmV4dFBrID0gdGhpcy5nZXRQcmltYXJ5S2V5KG5leHRIYXNoKTtcblxuICAgIHRyeSB7XG4gICAgICBhd2FpdCBkZGIuc2VuZChuZXcgVHJhbnNhY3RXcml0ZUNvbW1hbmQoe1xuICAgICAgICBUcmFuc2FjdEl0ZW1zOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgVXBkYXRlOiB7XG4gICAgICAgICAgICAgIFRhYmxlTmFtZTogdGhpcy50YWJsZU5hbWUsXG4gICAgICAgICAgICAgIEtleTogeyBwazogY3VycmVudFBrIH0sXG4gICAgICAgICAgICAgIFVwZGF0ZUV4cHJlc3Npb246ICdTRVQgcm90YXRlZEF0ID0gOm5vdywgcmVwbGFjZWRCeVBrID0gOm5leHRQaywgI3R0bCA9IDp0dGwnLFxuICAgICAgICAgICAgICBDb25kaXRpb25FeHByZXNzaW9uOiAnYXR0cmlidXRlX2V4aXN0cyhwaykgQU5EIGF0dHJpYnV0ZV9ub3RfZXhpc3RzKHJvdGF0ZWRBdCkgQU5EIGF0dHJpYnV0ZV9ub3RfZXhpc3RzKHJldm9rZWRBdCknLFxuICAgICAgICAgICAgICBFeHByZXNzaW9uQXR0cmlidXRlTmFtZXM6IHtcbiAgICAgICAgICAgICAgICAnI3R0bCc6ICd0dGwnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBFeHByZXNzaW9uQXR0cmlidXRlVmFsdWVzOiB7XG4gICAgICAgICAgICAgICAgJzpub3cnOiBub3dTZWMsXG4gICAgICAgICAgICAgICAgJzpuZXh0UGsnOiBuZXh0UGssXG4gICAgICAgICAgICAgICAgJzp0dGwnOiBjdXJyZW50LmV4cGlyZXNBdCxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBQdXQ6IHtcbiAgICAgICAgICAgICAgVGFibGVOYW1lOiB0aGlzLnRhYmxlTmFtZSxcbiAgICAgICAgICAgICAgSXRlbToge1xuICAgICAgICAgICAgICAgIHBrOiBuZXh0UGssXG4gICAgICAgICAgICAgICAgc3ViamVjdElkOiBjdXJyZW50LnN1YmplY3RJZCxcbiAgICAgICAgICAgICAgICBzZXNzaW9uSWQ6IGN1cnJlbnQuc2Vzc2lvbklkLFxuICAgICAgICAgICAgICAgIGNyZWF0ZWRBdDogbm93U2VjLFxuICAgICAgICAgICAgICAgIGV4cGlyZXNBdDogbmV4dFJlZnJlc2hUb2tlbkV4cGlyZXNBdCxcbiAgICAgICAgICAgICAgICB0dGw6IG5leHRSZWZyZXNoVG9rZW5FeHBpcmVzQXQsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIENvbmRpdGlvbkV4cHJlc3Npb246ICdhdHRyaWJ1dGVfbm90X2V4aXN0cyhwayknLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgfSkpO1xuXG4gICAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIEVycm9yICYmIGVycm9yLm5hbWUgPT09ICdUcmFuc2FjdGlvbkNhbmNlbGVkRXhjZXB0aW9uJykge1xuICAgICAgICAvLyBUcmVhdCBjb25kaXRpb25hbCB0cmFuc2FjdGlvbiBmYWlsdXJlIGFzIHRva2VuIHJldXNlLlxuICAgICAgICBhd2FpdCB0aGlzLmhhbmRsZVJlZnJlc2hUb2tlblJldXNlKGN1cnJlbnQsIG5vdyk7XG4gICAgICB9XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgc3ViamVjdElkOiBjdXJyZW50LnN1YmplY3RJZCxcbiAgICAgIHNlc3Npb25JZDogY3VycmVudC5zZXNzaW9uSWQsXG4gICAgICByZWZyZXNoVG9rZW46IG5leHRSZWZyZXNoVG9rZW4sXG4gICAgICByZWZyZXNoVG9rZW5FeHBpcmVzQXQ6IG5leHRSZWZyZXNoVG9rZW5FeHBpcmVzQXQsXG4gICAgfTtcbiAgfTtcblxuICAvKipcbiAgICogU2V0cyBgcmV2b2tlZEF0YCBvbiB0aGUgdG9rZW4gcm93LiBNaXNzaW5nIGl0ZW1zIHN1Y2NlZWQgKGlkZW1wb3RlbnQgcmV2b2tlKS5cbiAgICpcbiAgICogRG9lcyBub3QgdXBkYXRlIGB0dGxgOyBleGlzdGluZyBgdHRsYCBmcm9tIGlzc3VlL3JvdGF0ZSBzdGlsbCBhcHBsaWVzIGZvciBEeW5hbW9EQiBjbGVhbnVwLlxuICAgKlxuICAgKiBAcGFyYW0gcGFyYW1zIC0gUmVmcmVzaCB0b2tlbiBhbmQgb3B0aW9uYWwgY2xvY2sgKGBub3dgKS5cbiAgICogQHJldHVybnMgYHRydWVgIGFmdGVyIGEgc3VjY2Vzc2Z1bCB1cGRhdGUgb3Igbm8tb3Agd2hlbiB0aGUgaXRlbSBpcyBhYnNlbnQuXG4gICAqIEB0aHJvd3Mge0BsaW5rIFJlZnJlc2hUb2tlbkludmFsaWRFcnJvcn0gV2hlbiB0aGUgdG9rZW4gc3RyaW5nIGZvcm1hdCBpcyBpbnZhbGlkLlxuICAgKi9cbiAgcHVibGljIHJldm9rZSA9IGFzeW5jIChwYXJhbXM6IFJldm9rZVBhcmFtcyk6IFByb21pc2U8dHJ1ZT4gPT4ge1xuICAgIC8vIHZhbGlkYXRlIHJlZnJlc2ggdG9rZW5cbiAgICB0aGlzLnZhbGlkYXRlUmVmcmVzaFRva2VuKHBhcmFtcy5yZWZyZXNoVG9rZW4pO1xuXG4gICAgY29uc3QgZGRiID0gdGhpcy5nZXRkZGIoKTtcblxuICAgIGNvbnN0IG5vdyA9IHBhcmFtcy5ub3cgPz8gbmV3IERhdGUoKTtcbiAgICBjb25zdCBub3dTZWMgPSBlcG9jaHNlYyhub3cpO1xuXG4gICAgY29uc3QgaGFzaCA9IHNoYTI1NmhleChwYXJhbXMucmVmcmVzaFRva2VuKTtcbiAgICBjb25zdCBwayA9IHRoaXMuZ2V0UHJpbWFyeUtleShoYXNoKTtcblxuICAgIHRyeSB7XG4gICAgICBhd2FpdCBkZGIuc2VuZChcbiAgICAgICAgbmV3IFVwZGF0ZUNvbW1hbmQoe1xuICAgICAgICAgIFRhYmxlTmFtZTogdGhpcy50YWJsZU5hbWUsXG4gICAgICAgICAgS2V5OiB7IHBrIH0sXG4gICAgICAgICAgVXBkYXRlRXhwcmVzc2lvbjogJ1NFVCByZXZva2VkQXQgPSA6bm93JyxcbiAgICAgICAgICBDb25kaXRpb25FeHByZXNzaW9uOiAnYXR0cmlidXRlX2V4aXN0cyhwayknLFxuICAgICAgICAgIEV4cHJlc3Npb25BdHRyaWJ1dGVWYWx1ZXM6IHtcbiAgICAgICAgICAgICc6bm93Jzogbm93U2VjLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pLFxuICAgICAgKTtcbiAgICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgICAgLy8gTWlzc2luZyBpdGVtOiB0cmVhdCBhcyBzdWNjZXNzIChpZGVtcG90ZW50IHJldm9rZSkuXG4gICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBFcnJvciAmJiBlcnJvci5uYW1lID09PSAnQ29uZGl0aW9uYWxDaGVja0ZhaWxlZEV4Y2VwdGlvbicpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG4gIH07XG5cbiAgLyoqXG4gICAqIFNldHMgYHJldm9rZWRBdGAgb24gZXZlcnkgdG9rZW4gcm93IGZvciB0aGUgZ2l2ZW4gYHNlc3Npb25JZGAgKG9wdGlvbmFsbHkgZmlsdGVyZWQgYnkgYHN1YmplY3RJZGApLlxuICAgKlxuICAgKiBRdWVyaWVzIHRoZSBzZXNzaW9uIEdTSSAocGFydGl0aW9uIGtleSBgc2Vzc2lvbklkYDsgYEtFWVNfT05MWWAgaXMgZW5vdWdoKSwgdGhlbiB1cGRhdGVzIGVhY2hcbiAgICogYmFzZS10YWJsZSBpdGVtLiBXaGVuIGBzdWJqZWN0SWRgIGlzIHNldCwgaXQgaXMgcmVxdWlyZWQgaW4gdGhlIGBVcGRhdGVJdGVtYCBjb25kaXRpb24uXG4gICAqIE1pc3Npbmcgb3Igbm9uLW1hdGNoaW5nIGl0ZW1zIGFyZSBza2lwcGVkIChpZGVtcG90ZW50KS4gUGFnaW5hdGUgd2l0aCBgTGFzdEV2YWx1YXRlZEtleWAuXG4gICAqXG4gICAqIEBwYXJhbSBwYXJhbXMgLSBTZXNzaW9uIGlkLCBvcHRpb25hbCBzdWJqZWN0IGZpbHRlciwgYW5kIG9wdGlvbmFsIGNsb2NrLlxuICAgKiBAcmV0dXJucyBDb3VudCBvZiByb3dzIHVwZGF0ZWQgd2l0aCBgcmV2b2tlZEF0YCBpbiB0aGlzIGNhbGwuXG4gICAqL1xuICBwdWJsaWMgcmV2b2tlU2Vzc2lvbiA9IGFzeW5jIChwYXJhbXM6IFJldm9rZVNlc3Npb25QYXJhbXMpOiBQcm9taXNlPFJldm9rZVNlc3Npb25SZXN1bHQ+ID0+IHtcbiAgICBjb25zdCBub3cgPSBwYXJhbXMubm93ID8/IG5ldyBEYXRlKCk7XG4gICAgY29uc3Qgbm93U2VjID0gZXBvY2hzZWMobm93KTtcbiAgICBjb25zdCBpbmRleE5hbWUgPSB0aGlzLm9wdGlvbnM/LnNlc3Npb25JZEluZGV4TmFtZSA/PyBERUZBVUxUX1NFU1NJT05fSURfSU5ERVhfTkFNRTtcblxuICAgIGNvbnN0IHJldm9rZWRDb3VudCA9IGF3YWl0IHRoaXMucmV2b2tlVG9rZW5Sb3dzQnlJbmRleFF1ZXJ5KHtcbiAgICAgIGluZGV4TmFtZSxcbiAgICAgIGtleUNvbmRpdGlvbkV4cHJlc3Npb246ICdzZXNzaW9uSWQgPSA6c2Vzc2lvbklkJyxcbiAgICAgIHF1ZXJ5RXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlczoge1xuICAgICAgICAnOnNlc3Npb25JZCc6IHBhcmFtcy5zZXNzaW9uSWQsXG4gICAgICB9LFxuICAgICAgbm93U2VjLFxuICAgICAgdXBkYXRlQ29uZGl0aW9uRXhwcmVzc2lvbjogcGFyYW1zLnN1YmplY3RJZFxuICAgICAgICA/ICdhdHRyaWJ1dGVfZXhpc3RzKHBrKSBBTkQgc3ViamVjdElkID0gOnN1YmplY3RJZCdcbiAgICAgICAgOiAnYXR0cmlidXRlX2V4aXN0cyhwayknLFxuICAgICAgdXBkYXRlRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlczogcGFyYW1zLnN1YmplY3RJZFxuICAgICAgICA/IHsgJzpzdWJqZWN0SWQnOiBwYXJhbXMuc3ViamVjdElkIH1cbiAgICAgICAgOiB1bmRlZmluZWQsXG4gICAgfSk7XG5cbiAgICByZXR1cm4geyByZXZva2VkQ291bnQgfTtcbiAgfTtcblxuICAvKipcbiAgICogU2V0cyBgcmV2b2tlZEF0YCBvbiBldmVyeSByZWZyZXNoIHRva2VuIHJvdyBmb3IgdGhlIGdpdmVuIGBzdWJqZWN0SWRgIGFjcm9zcyBhbGwgc2Vzc2lvbnMuXG4gICAqXG4gICAqIFF1ZXJpZXMgdGhlIHN1YmplY3QgR1NJIChwYXJ0aXRpb24ga2V5IGBzdWJqZWN0SWRgOyBgS0VZU19PTkxZYCBpcyBlbm91Z2gpLCB0aGVuIHVwZGF0ZXMgZWFjaFxuICAgKiBiYXNlLXRhYmxlIGl0ZW0uIE1pc3NpbmcgaXRlbXMgYXJlIHNraXBwZWQgKGlkZW1wb3RlbnQpLiBQYWdpbmF0ZSB3aXRoIGBMYXN0RXZhbHVhdGVkS2V5YC5cbiAgICpcbiAgICogQHBhcmFtIHBhcmFtcyAtIFN1YmplY3QgaWQgYW5kIG9wdGlvbmFsIGNsb2NrLlxuICAgKiBAcmV0dXJucyBDb3VudCBvZiByb3dzIHVwZGF0ZWQgd2l0aCBgcmV2b2tlZEF0YCBpbiB0aGlzIGNhbGwuXG4gICAqL1xuICBwdWJsaWMgcmV2b2tlU3ViamVjdCA9IGFzeW5jIChwYXJhbXM6IFJldm9rZVN1YmplY3RQYXJhbXMpOiBQcm9taXNlPFJldm9rZVN1YmplY3RSZXN1bHQ+ID0+IHtcbiAgICBjb25zdCBub3cgPSBwYXJhbXMubm93ID8/IG5ldyBEYXRlKCk7XG4gICAgY29uc3Qgbm93U2VjID0gZXBvY2hzZWMobm93KTtcbiAgICBjb25zdCBpbmRleE5hbWUgPSB0aGlzLm9wdGlvbnM/LnN1YmplY3RJZEluZGV4TmFtZSA/PyBERUZBVUxUX1NVQkpFQ1RfSURfSU5ERVhfTkFNRTtcblxuICAgIGNvbnN0IHJldm9rZWRDb3VudCA9IGF3YWl0IHRoaXMucmV2b2tlVG9rZW5Sb3dzQnlJbmRleFF1ZXJ5KHtcbiAgICAgIGluZGV4TmFtZSxcbiAgICAgIGtleUNvbmRpdGlvbkV4cHJlc3Npb246ICdzdWJqZWN0SWQgPSA6c3ViamVjdElkJyxcbiAgICAgIHF1ZXJ5RXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlczoge1xuICAgICAgICAnOnN1YmplY3RJZCc6IHBhcmFtcy5zdWJqZWN0SWQsXG4gICAgICB9LFxuICAgICAgbm93U2VjLFxuICAgICAgdXBkYXRlQ29uZGl0aW9uRXhwcmVzc2lvbjogJ2F0dHJpYnV0ZV9leGlzdHMocGspJyxcbiAgICB9KTtcblxuICAgIHJldHVybiB7IHJldm9rZWRDb3VudCB9O1xuICB9O1xuXG4gIC8qKlxuICAgKiBRdWVyaWVzIGEgR1NJIGFuZCBzZXRzIGByZXZva2VkQXRgIG9uIGVhY2ggbWF0Y2hpbmcgYmFzZS10YWJsZSByb3cuXG4gICAqXG4gICAqIEBwYXJhbSBwYXJhbXMgLSBHU0kgcXVlcnkgcGFyYW1ldGVycyBhbmQgcGVyLXJvdyB1cGRhdGUgY29uZGl0aW9ucy5cbiAgICogQHJldHVybnMgQ291bnQgb2Ygcm93cyB1cGRhdGVkIHdpdGggYHJldm9rZWRBdGAgaW4gdGhpcyBjYWxsLlxuICAgKi9cbiAgcHJpdmF0ZSByZXZva2VUb2tlblJvd3NCeUluZGV4UXVlcnkgPSBhc3luYyAocGFyYW1zOiB7XG4gICAgaW5kZXhOYW1lOiBzdHJpbmc7XG4gICAga2V5Q29uZGl0aW9uRXhwcmVzc2lvbjogc3RyaW5nO1xuICAgIHF1ZXJ5RXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlczogUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcbiAgICBub3dTZWM6IG51bWJlcjtcbiAgICB1cGRhdGVDb25kaXRpb25FeHByZXNzaW9uOiBzdHJpbmc7XG4gICAgdXBkYXRlRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcz86IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG4gIH0pOiBQcm9taXNlPG51bWJlcj4gPT4ge1xuICAgIGNvbnN0IGRkYiA9IHRoaXMuZ2V0ZGRiKCk7XG5cbiAgICBsZXQgcmV2b2tlZENvdW50ID0gMDtcbiAgICBsZXQgZXhjbHVzaXZlU3RhcnRLZXk6IFJlY29yZDxzdHJpbmcsIHVua25vd24+IHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqIFdoZXRoZXIgYW5vdGhlciBRdWVyeSBwYWdlIGlzIGF2YWlsYWJsZSBhZnRlciB0aGUgcHJldmlvdXMgcmVzcG9uc2UuICovXG4gICAgY29uc3Qgc2hvdWxkQ29udGludWVQYWdpbmcgPSAoKTogYm9vbGVhbiA9PiBleGNsdXNpdmVTdGFydEtleSAhPT0gdW5kZWZpbmVkO1xuXG4gICAgZG8ge1xuICAgICAgY29uc3QgcmVzID0gYXdhaXQgZGRiLnNlbmQoXG4gICAgICAgIG5ldyBRdWVyeUNvbW1hbmQoe1xuICAgICAgICAgIFRhYmxlTmFtZTogdGhpcy50YWJsZU5hbWUsXG4gICAgICAgICAgSW5kZXhOYW1lOiBwYXJhbXMuaW5kZXhOYW1lLFxuICAgICAgICAgIEtleUNvbmRpdGlvbkV4cHJlc3Npb246IHBhcmFtcy5rZXlDb25kaXRpb25FeHByZXNzaW9uLFxuICAgICAgICAgIEV4cHJlc3Npb25BdHRyaWJ1dGVWYWx1ZXM6IHBhcmFtcy5xdWVyeUV4cHJlc3Npb25BdHRyaWJ1dGVWYWx1ZXMsXG4gICAgICAgICAgUHJvamVjdGlvbkV4cHJlc3Npb246ICdwaycsXG4gICAgICAgICAgRXhjbHVzaXZlU3RhcnRLZXk6IGV4Y2x1c2l2ZVN0YXJ0S2V5LFxuICAgICAgICB9KSxcbiAgICAgICk7XG5cbiAgICAgIGNvbnN0IGl0ZW1zID0gcmVzLkl0ZW1zID8/IFtdO1xuICAgICAgZm9yIChjb25zdCBpdGVtIG9mIGl0ZW1zKSB7XG4gICAgICAgIGNvbnN0IHBrID0gaXRlbS5waztcbiAgICAgICAgaWYgKHR5cGVvZiBwayAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGV4cHJlc3Npb25BdHRyaWJ1dGVWYWx1ZXM6IFJlY29yZDxzdHJpbmcsIHN0cmluZyB8IG51bWJlcj4gPSB7XG4gICAgICAgICAgJzpub3cnOiBwYXJhbXMubm93U2VjLFxuICAgICAgICAgIC4uLnBhcmFtcy51cGRhdGVFeHByZXNzaW9uQXR0cmlidXRlVmFsdWVzLFxuICAgICAgICB9O1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgYXdhaXQgZGRiLnNlbmQoXG4gICAgICAgICAgICBuZXcgVXBkYXRlQ29tbWFuZCh7XG4gICAgICAgICAgICAgIFRhYmxlTmFtZTogdGhpcy50YWJsZU5hbWUsXG4gICAgICAgICAgICAgIEtleTogeyBwayB9LFxuICAgICAgICAgICAgICBVcGRhdGVFeHByZXNzaW9uOiAnU0VUIHJldm9rZWRBdCA9IDpub3cnLFxuICAgICAgICAgICAgICBDb25kaXRpb25FeHByZXNzaW9uOiBwYXJhbXMudXBkYXRlQ29uZGl0aW9uRXhwcmVzc2lvbixcbiAgICAgICAgICAgICAgRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlczogZXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICk7XG4gICAgICAgICAgcmV2b2tlZENvdW50ICs9IDE7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgRXJyb3IgJiYgZXJyb3IubmFtZSA9PT0gJ0NvbmRpdGlvbmFsQ2hlY2tGYWlsZWRFeGNlcHRpb24nKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgZXhjbHVzaXZlU3RhcnRLZXkgPSByZXMuTGFzdEV2YWx1YXRlZEtleSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB8IHVuZGVmaW5lZDtcbiAgICB9IHdoaWxlIChzaG91bGRDb250aW51ZVBhZ2luZygpKTtcblxuICAgIHJldHVybiByZXZva2VkQ291bnQ7XG4gIH07XG5cbiAgLyoqXG4gICAqIEhhbmRsZXMgcmVmcmVzaC10b2tlbiByZXVzZSBkZXRlY3Rpb246IG9wdGlvbmFsbHkgY2FzY2FkZXMge0BsaW5rIER5bmFtb2RiUmVmcmVzaFRva2VuUHJvdmlkZXIucmV2b2tlU2Vzc2lvbn1cbiAgICogd2hlbiB7QGxpbmsgU3RvcmVPcHRpb25zLnJldm9rZVNlc3Npb25PblJldXNlfSBpcyB0cnVlLCB0aGVuIHRocm93cyB7QGxpbmsgUmVmcmVzaFRva2VuUmV1c2VkRXJyb3J9XG4gICAqIHBvcHVsYXRlZCB3aXRoIGBzdWJqZWN0SWRgIC8gYHNlc3Npb25JZGAgZnJvbSBgY3VycmVudGAuXG4gICAqXG4gICAqIEBwYXJhbSBjdXJyZW50IC0gVG9rZW4gcm93IHRoYXQgaW5kaWNhdGVkIHJldXNlIChgcm90YXRlZEF0YCBzZXQgb3IgdHJhbnNhY3Rpb24gY2FuY2VsZWQpLlxuICAgKiBAcGFyYW0gbm93IC0gQ2xvY2sgdXNlZCBmb3IgYHJldm9rZWRBdGAgd2hlbiBjYXNjYWRpbmcgcmV2b2tlIGlzIGVuYWJsZWQuXG4gICAqIEB0aHJvd3Mge0BsaW5rIFJlZnJlc2hUb2tlblJldXNlZEVycm9yfSBBbHdheXMgKHJldHVybiB0eXBlIGlzIGBuZXZlcmApLlxuICAgKi9cbiAgcHJpdmF0ZSBoYW5kbGVSZWZyZXNoVG9rZW5SZXVzZSA9IGFzeW5jIChjdXJyZW50OiBUb2tlblJlY29yZCwgbm93OiBEYXRlKTogUHJvbWlzZTxuZXZlcj4gPT4ge1xuICAgIGlmICh0aGlzLm9wdGlvbnM/LnJldm9rZVNlc3Npb25PblJldXNlKSB7XG4gICAgICBhd2FpdCB0aGlzLnJldm9rZVNlc3Npb24oe1xuICAgICAgICBzZXNzaW9uSWQ6IGN1cnJlbnQuc2Vzc2lvbklkLFxuICAgICAgICBzdWJqZWN0SWQ6IGN1cnJlbnQuc3ViamVjdElkLFxuICAgICAgICBub3csXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgUmVmcmVzaFRva2VuUmV1c2VkRXJyb3IodW5kZWZpbmVkLCB7XG4gICAgICBzdWJqZWN0SWQ6IGN1cnJlbnQuc3ViamVjdElkLFxuICAgICAgc2Vzc2lvbklkOiBjdXJyZW50LnNlc3Npb25JZCxcbiAgICB9KTtcbiAgfTtcblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgY2FjaGVkIHtAbGluayBEeW5hbW9EQkRvY3VtZW50Q2xpZW50fSwgY3JlYXRpbmcgaXQgb24gZmlyc3QgdXNlLlxuICAgKlxuICAgKiBAcmV0dXJucyBEb2N1bWVudCBjbGllbnQgY29uZmlndXJlZCBmb3IgYHJlZ2lvbmAgYW5kIG9wdGlvbmFsIGBlbmRwb2ludGAuXG4gICAqL1xuICBwcml2YXRlIGdldGRkYiA9ICgpOiBEeW5hbW9EQkRvY3VtZW50Q2xpZW50ID0+IHtcbiAgICBpZiAoIXRoaXMuZGRiKSB7XG4gICAgICBjb25zdCBjbGllbnQgPSBuZXcgRHluYW1vREJDbGllbnQoe1xuICAgICAgICByZWdpb246IHRoaXMucmVnaW9uLFxuICAgICAgICBlbmRwb2ludDogKCgpID0+IHtcbiAgICAgICAgICBpZiAodGhpcy5vcHRpb25zPy5lbmRwb2ludCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMub3B0aW9ucy5lbmRwb2ludDtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIGBodHRwczovL2R5bmFtb2RiLiR7dGhpcy5yZWdpb259LmFtYXpvbmF3cy5jb21gO1xuICAgICAgICB9KSgpLFxuICAgICAgfSk7XG4gICAgICB0aGlzLmRkYiA9IER5bmFtb0RCRG9jdW1lbnRDbGllbnQuZnJvbShjbGllbnQsIHRoaXMub3B0aW9ucz8udHJhbnNsYXRlQ29uZmlnKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuZGRiO1xuICB9O1xuXG4gIC8qKlxuICAgKiBMb2FkcyBhIHRva2VuIHJvdyBieSBwYXJ0aXRpb24ga2V5LlxuICAgKlxuICAgKiBAcGFyYW0gcGsgLSBGdWxsIHBhcnRpdGlvbiBrZXkgKGBwcmVmaXhgICsgaGFzaCkuXG4gICAqIEByZXR1cm5zIFBhcnNlZCB7QGxpbmsgVG9rZW5SZWNvcmR9LCBvciBgbnVsbGAgaWYgdGhlIGl0ZW0gZG9lcyBub3QgZXhpc3QuXG4gICAqL1xuICBwcml2YXRlIGdldFRva2VuUmVjb3JkID0gYXN5bmMgKHBrOiBzdHJpbmcpOiBQcm9taXNlPFRva2VuUmVjb3JkIHwgbnVsbD4gPT4ge1xuICAgIGNvbnN0IGRkYiA9IHRoaXMuZ2V0ZGRiKCk7XG5cbiAgICBjb25zdCByZXMgPSBhd2FpdCBkZGIuc2VuZChcbiAgICAgIG5ldyBHZXRDb21tYW5kKHtcbiAgICAgICAgVGFibGVOYW1lOiB0aGlzLnRhYmxlTmFtZSxcbiAgICAgICAgS2V5OiB7IHBrIH0sXG4gICAgICAgIENvbnNpc3RlbnRSZWFkOiB0aGlzLm9wdGlvbnM/LmNvbnNpc3RlbnRSZWFkID8/IHRydWUsXG4gICAgICB9KSxcbiAgICApO1xuICAgIHJldHVybiAocmVzLkl0ZW0gYXMgVG9rZW5SZWNvcmQpID8/IG51bGw7XG4gIH07XG5cbiAgLyoqXG4gICAqIEVmZmVjdGl2ZSBwYXJ0aXRpb24ga2V5IHByZWZpeCBmcm9tIHtAbGluayBTdG9yZU9wdGlvbnN9IG9yIHtAbGluayBERUZBVUxUX1BSSU1BUllfS0VZX1BSRUZJWH0uXG4gICAqXG4gICAqIEByZXR1cm5zIFByZWZpeCBzdHJpbmcgKGUuZy4gYHJ0I2ApLlxuICAgKi9cbiAgcHJpdmF0ZSBnZXRQcmltYXJ5S2V5UHJlZml4ID0gKCk6IHN0cmluZyA9PiB7XG4gICAgcmV0dXJuIGAke3RoaXMub3B0aW9ucz8ucGtQcmVmaXggPz8gREVGQVVMVF9QUklNQVJZX0tFWV9QUkVGSVh9YDtcbiAgfTtcblxuICAvKipcbiAgICogQnVpbGRzIHRoZSBmdWxsIHBhcnRpdGlvbiBrZXkgZm9yIGEgdG9rZW4gaGFzaC5cbiAgICpcbiAgICogQHBhcmFtIGhhc2ggLSBTSEEtMjU2IGhleCBkaWdlc3Qgb2YgdGhlIHBsYWludGV4dCB0b2tlbi5cbiAgICogQHJldHVybnMgYHByZWZpeGAgKyBgaGFzaGAuXG4gICAqL1xuICBwcml2YXRlIGdldFByaW1hcnlLZXkgPSAoaGFzaDogc3RyaW5nKTogc3RyaW5nID0+IHtcbiAgICByZXR1cm4gYCR7dGhpcy5nZXRQcmltYXJ5S2V5UHJlZml4KCl9JHtoYXNofWA7XG4gIH07XG5cbiAgLyoqXG4gICAqIENvbXB1dGVzIGxvZ2ljYWwgZXhwaXJhdGlvbiAoYGV4cGlyZXNBdGAgLyBgdHRsYCkgYXMgYG5vd1NlY2AgcGx1cyBjb25maWd1cmVkIGxpZmV0aW1lLlxuICAgKlxuICAgKiBAcGFyYW0gbm93U2VjIC0gQ3VycmVudCB0aW1lIGFzIFVuaXggc2Vjb25kcy5cbiAgICogQHJldHVybnMgRXhwaXJhdGlvbiB0aW1lc3RhbXAgaW4gVW5peCBzZWNvbmRzLlxuICAgKi9cbiAgcHJpdmF0ZSBtYWtlRXhwaXJlc0F0ID0gKG5vd1NlYzogbnVtYmVyKTogbnVtYmVyID0+IHtcbiAgICBjb25zdCB0dGxTZWNvbmRzID0gdGhpcy5vcHRpb25zPy50dGxTZWNvbmRzO1xuICAgIGlmICh0dGxTZWNvbmRzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBub3dTZWMgKyB0dGxTZWNvbmRzO1xuICAgIH1cbiAgICByZXR1cm4gbm93U2VjICsgKHRoaXMub3B0aW9ucz8udHRsRGF5cyA/PyBERUZBVUxUX1RUTF9EQVlTKSAqIDI0ICogNjAgKiA2MDtcbiAgfTtcblxuICAvKipcbiAgICogUmVzb2x2ZXMgYW5kIHZhbGlkYXRlcyB7QGxpbmsgU3RvcmVPcHRpb25zLnRva2VuQnl0ZXN9LlxuICAgKlxuICAgKiBAcGFyYW0gdG9rZW5CeXRlcyAtIE9wdGlvbmFsIGJ5dGUgbGVuZ3RoIGZyb20gc3RvcmUgb3B0aW9ucy5cbiAgICogQHJldHVybnMgUG9zaXRpdmUgaW50ZWdlciBieXRlIGxlbmd0aC5cbiAgICogQHRocm93cyB7UmFuZ2VFcnJvcn0gV2hlbiBgdG9rZW5CeXRlc2AgaXMgbm90IGEgcG9zaXRpdmUgaW50ZWdlci5cbiAgICovXG4gIHByaXZhdGUgcmVzb2x2ZVRva2VuQnl0ZXMgPSAodG9rZW5CeXRlcz86IG51bWJlcik6IG51bWJlciA9PiB7XG4gICAgY29uc3QgYnl0ZXMgPSB0b2tlbkJ5dGVzID8/IERFRkFVTFRfVE9LRU5fQllURVM7XG4gICAgaWYgKCFOdW1iZXIuaXNJbnRlZ2VyKGJ5dGVzKSB8fCBieXRlcyA8IDEpIHtcbiAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCd0b2tlbkJ5dGVzIG11c3QgYmUgYSBwb3NpdGl2ZSBpbnRlZ2VyJyk7XG4gICAgfVxuICAgIHJldHVybiBieXRlcztcbiAgfTtcblxuICAvKipcbiAgICogVmFsaWRhdGVzIFRUTC1yZWxhdGVkIHN0b3JlIG9wdGlvbnMgYXQgY29uc3RydWN0aW9uIHRpbWUuXG4gICAqXG4gICAqIEBwYXJhbSBvcHRpb25zIC0gU3RvcmUgb3B0aW9ucyBmcm9tIHRoZSBjb25zdHJ1Y3Rvci5cbiAgICogQHRocm93cyB7UmFuZ2VFcnJvcn0gV2hlbiBgdHRsU2Vjb25kc2Agb3IgYHR0bERheXNgIGlzIG5vdCBhIHBvc2l0aXZlIG51bWJlci5cbiAgICovXG4gIHByaXZhdGUgdmFsaWRhdGVUdGxPcHRpb25zID0gKG9wdGlvbnM/OiBTdG9yZU9wdGlvbnMpOiB2b2lkID0+IHtcbiAgICBpZiAob3B0aW9ucz8udHRsU2Vjb25kcyAhPT0gdW5kZWZpbmVkICYmIG9wdGlvbnMudHRsU2Vjb25kcyA8PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcigndHRsU2Vjb25kcyBtdXN0IGJlIGEgcG9zaXRpdmUgbnVtYmVyJyk7XG4gICAgfVxuICAgIGlmIChvcHRpb25zPy50dGxEYXlzICE9PSB1bmRlZmluZWQgJiYgb3B0aW9ucy50dGxEYXlzIDw9IDApIHtcbiAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCd0dGxEYXlzIG11c3QgYmUgYSBwb3NpdGl2ZSBudW1iZXInKTtcbiAgICB9XG4gIH07XG5cbiAgLyoqXG4gICAqIEVuc3VyZXMgdGhlIHRva2VuIGlzIG5vbi1lbXB0eSBhbmQgbWF0Y2hlcyB0aGUgZXhwZWN0ZWQgYmFzZTY0dXJsIGxlbmd0aCBmb3IgYHRva2VuQnl0ZXNgLlxuICAgKlxuICAgKiBAcGFyYW0gdG9rZW4gLSBQbGFpbnRleHQgcmVmcmVzaCB0b2tlbiBmcm9tIHRoZSBjbGllbnQuXG4gICAqIEB0aHJvd3Mge0BsaW5rIFJlZnJlc2hUb2tlbkludmFsaWRFcnJvcn0gV2hlbiB2YWxpZGF0aW9uIGZhaWxzLlxuICAgKi9cbiAgcHJpdmF0ZSB2YWxpZGF0ZVJlZnJlc2hUb2tlbih0b2tlbjogc3RyaW5nKTogdm9pZCB7XG4gICAgaWYgKCF0b2tlbiB8fCB0b2tlbi5sZW5ndGggIT09IE1hdGguY2VpbCh0aGlzLnRva2VuQnl0ZXMgKiA4IC8gNikpIHtcbiAgICAgIHRocm93IG5ldyBSZWZyZXNoVG9rZW5JbnZhbGlkRXJyb3IoKTtcbiAgICB9XG4gIH1cblxufVxuIl19
@@ -1,19 +1,45 @@
1
+ import type { marshallOptions, unmarshallOptions } from '@aws-sdk/lib-dynamodb';
1
2
  /** Unix timestamp in whole seconds. */
2
3
  export type EpochSec = number;
4
+ /**
5
+ * Pass-through to {@link DynamoDBDocumentClient.from} `translateConfig` (marshall / unmarshall options).
6
+ */
7
+ export type DocumentClientTranslateConfig = {
8
+ /** Options for marshalling JavaScript values to DynamoDB attribute values. */
9
+ marshallOptions?: marshallOptions;
10
+ /** Options for unmarshalling DynamoDB attribute values to JavaScript values. */
11
+ unmarshallOptions?: unmarshallOptions;
12
+ };
3
13
  /**
4
14
  * Configuration for the DynamoDB refresh token provider constructor.
5
15
  *
6
- * Token lifetime (`ttlDays`) drives both logical expiration (`expiresAt`) and the
7
- * DynamoDB TTL attribute (`ttl`) written on Put / Transact. Session revocation options
8
- * (`sessionIdIndexName`, `revokeSessionOnReuse`) require a GSI whose partition key is
9
- * `sessionId`.
16
+ * Token lifetime (`ttlDays` or `ttlSeconds`) drives both logical expiration (`expiresAt`) and the
17
+ * DynamoDB TTL attribute (`ttl`) written on Put / Transact. When both are set, `ttlSeconds` takes
18
+ * precedence. Session revocation options (`sessionIdIndexName`, `revokeSessionOnReuse`) require a
19
+ * GSI whose partition key is `sessionId`. Subject-wide revocation (`subjectIdIndexName`,
20
+ * {@link RefreshTokenStore.revokeSubject}) requires a GSI whose partition key is `subjectId`.
10
21
  */
11
22
  export type StoreOptions = {
12
23
  /**
13
24
  * Refresh token lifetime in days (added to `now` when computing `expiresAt` / `ttl`).
25
+ * Ignored when {@link StoreOptions.ttlSeconds} is set.
14
26
  * @defaultValue 60
15
27
  */
16
28
  ttlDays?: number;
29
+ /**
30
+ * Refresh token lifetime in seconds (added to `now` when computing `expiresAt` / `ttl`).
31
+ * Takes precedence over {@link StoreOptions.ttlDays} when both are set.
32
+ */
33
+ ttlSeconds?: number;
34
+ /**
35
+ * Number of random bytes used when generating opaque refresh tokens.
36
+ * @defaultValue 32
37
+ */
38
+ tokenBytes?: number;
39
+ /**
40
+ * Pass-through to {@link DynamoDBDocumentClient.from} `translateConfig` (e.g. `removeUndefinedValues`).
41
+ */
42
+ translateConfig?: DocumentClientTranslateConfig;
17
43
  /**
18
44
  * Partition key prefix for DynamoDB items; full `pk` is `prefix` + SHA-256 hex of the token.
19
45
  * @defaultValue `'rt#'`
@@ -35,6 +61,13 @@ export type StoreOptions = {
35
61
  * @defaultValue `'sessionId-index'`
36
62
  */
37
63
  sessionIdIndexName?: string;
64
+ /**
65
+ * DynamoDB GSI name whose partition key attribute is `subjectId` (String).
66
+ * Required for {@link RefreshTokenStore.revokeSubject} (e.g. logout all devices, password change).
67
+ * `KEYS_ONLY` projection is sufficient.
68
+ * @defaultValue `'subjectId-index'`
69
+ */
70
+ subjectIdIndexName?: string;
38
71
  /**
39
72
  * When true, {@link RefreshTokenStore.rotate} calls {@link RefreshTokenStore.revokeSession}
40
73
  * for the token’s `sessionId` and `subjectId` before throwing {@link RefreshTokenReusedError}.
@@ -102,6 +135,18 @@ export type RevokeSessionResult = {
102
135
  /** Number of token rows successfully updated with `revokedAt` in this call. */
103
136
  revokedCount: number;
104
137
  };
138
+ /** Parameters for {@link RefreshTokenStore.revokeSubject}. */
139
+ export type RevokeSubjectParams = {
140
+ /** Subject (user) whose refresh token rows should all be revoked across every session. */
141
+ subjectId: string;
142
+ /** Clock override for tests; defaults to `new Date()`. */
143
+ now?: Date;
144
+ };
145
+ /** Result of {@link RefreshTokenStore.revokeSubject}. */
146
+ export type RevokeSubjectResult = {
147
+ /** Number of token rows successfully updated with `revokedAt` in this call. */
148
+ revokedCount: number;
149
+ };
105
150
  /**
106
151
  * DynamoDB item shape for a stored refresh token (hash-keyed by `pk`).
107
152
  *
@@ -111,7 +156,7 @@ export type RevokeSessionResult = {
111
156
  export type TokenRecord = {
112
157
  /** Partition key: prefix + SHA-256 hex of the plaintext token. */
113
158
  pk: string;
114
- /** Subject (user) identifier; also used when cascading session revoke on reuse. */
159
+ /** Subject (user) identifier; partition key of the subject GSI used by {@link RefreshTokenStore.revokeSubject}. */
115
160
  subjectId: string;
116
161
  /**
117
162
  * Session identifier. Partition key of the session GSI used by
@@ -179,4 +224,13 @@ export interface RefreshTokenStore {
179
224
  * @returns Count of rows updated with `revokedAt`.
180
225
  */
181
226
  revokeSession(params: RevokeSessionParams): Promise<RevokeSessionResult>;
227
+ /**
228
+ * Sets `revokedAt` on every refresh token row for the given subject (logout all devices, password change, account suspension).
229
+ *
230
+ * Requires a DynamoDB GSI whose partition key is `subjectId` (see {@link StoreOptions.subjectIdIndexName}).
231
+ *
232
+ * @param params - Subject id and optional clock.
233
+ * @returns Count of rows updated with `revokedAt`.
234
+ */
235
+ revokeSubject(params: RevokeSubjectParams): Promise<RevokeSubjectResult>;
182
236
  }
@@ -1,3 +1,3 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdHlwZXMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsInNvdXJjZXNDb250ZW50IjpbIi8qKiBVbml4IHRpbWVzdGFtcCBpbiB3aG9sZSBzZWNvbmRzLiAqL1xuZXhwb3J0IHR5cGUgRXBvY2hTZWMgPSBudW1iZXI7XG5cbi8qKlxuICogQ29uZmlndXJhdGlvbiBmb3IgdGhlIER5bmFtb0RCIHJlZnJlc2ggdG9rZW4gcHJvdmlkZXIgY29uc3RydWN0b3IuXG4gKlxuICogVG9rZW4gbGlmZXRpbWUgKGB0dGxEYXlzYCkgZHJpdmVzIGJvdGggbG9naWNhbCBleHBpcmF0aW9uIChgZXhwaXJlc0F0YCkgYW5kIHRoZVxuICogRHluYW1vREIgVFRMIGF0dHJpYnV0ZSAoYHR0bGApIHdyaXR0ZW4gb24gUHV0IC8gVHJhbnNhY3QuIFNlc3Npb24gcmV2b2NhdGlvbiBvcHRpb25zXG4gKiAoYHNlc3Npb25JZEluZGV4TmFtZWAsIGByZXZva2VTZXNzaW9uT25SZXVzZWApIHJlcXVpcmUgYSBHU0kgd2hvc2UgcGFydGl0aW9uIGtleSBpc1xuICogYHNlc3Npb25JZGAuXG4gKi9cbmV4cG9ydCB0eXBlIFN0b3JlT3B0aW9ucyA9IHtcbiAgLyoqXG4gICAqIFJlZnJlc2ggdG9rZW4gbGlmZXRpbWUgaW4gZGF5cyAoYWRkZWQgdG8gYG5vd2Agd2hlbiBjb21wdXRpbmcgYGV4cGlyZXNBdGAgLyBgdHRsYCkuXG4gICAqIEBkZWZhdWx0VmFsdWUgNjBcbiAgICovXG4gIHR0bERheXM/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFBhcnRpdGlvbiBrZXkgcHJlZml4IGZvciBEeW5hbW9EQiBpdGVtczsgZnVsbCBgcGtgIGlzIGBwcmVmaXhgICsgU0hBLTI1NiBoZXggb2YgdGhlIHRva2VuLlxuICAgKiBAZGVmYXVsdFZhbHVlIGAncnQjJ2BcbiAgICovXG4gIHBrUHJlZml4Pzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIHVzZSBzdHJvbmdseSBjb25zaXN0ZW50IHJlYWRzIG9uIGBHZXRJdGVtYC5cbiAgICogQGRlZmF1bHRWYWx1ZSB0cnVlXG4gICAqL1xuICBjb25zaXN0ZW50UmVhZD86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIEN1c3RvbSBEeW5hbW9EQiBBUEkgZW5kcG9pbnQgKGUuZy4gTG9jYWxTdGFjayBvciBEeW5hbW9EQiBMb2NhbCkuXG4gICAqL1xuICBlbmRwb2ludD86IHN0cmluZztcblxuICAvKipcbiAgICogRHluYW1vREIgR1NJIG5hbWUgd2hvc2UgcGFydGl0aW9uIGtleSBhdHRyaWJ1dGUgaXMgYHNlc3Npb25JZGAgKFN0cmluZykuXG4gICAqIFJlcXVpcmVkIGZvciB7QGxpbmsgUmVmcmVzaFRva2VuU3RvcmUucmV2b2tlU2Vzc2lvbn0gYW5kIGZvciBgcmV2b2tlU2Vzc2lvbk9uUmV1c2VgLlxuICAgKiBgS0VZU19PTkxZYCBwcm9qZWN0aW9uIGlzIHN1ZmZpY2llbnQuXG4gICAqIEBkZWZhdWx0VmFsdWUgYCdzZXNzaW9uSWQtaW5kZXgnYFxuICAgKi9cbiAgc2Vzc2lvbklkSW5kZXhOYW1lPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBXaGVuIHRydWUsIHtAbGluayBSZWZyZXNoVG9rZW5TdG9yZS5yb3RhdGV9IGNhbGxzIHtAbGluayBSZWZyZXNoVG9rZW5TdG9yZS5yZXZva2VTZXNzaW9ufVxuICAgKiBmb3IgdGhlIHRva2Vu4oCZcyBgc2Vzc2lvbklkYCBhbmQgYHN1YmplY3RJZGAgYmVmb3JlIHRocm93aW5nIHtAbGluayBSZWZyZXNoVG9rZW5SZXVzZWRFcnJvcn0uXG4gICAqIEFsaWducyB3aXRoIE9BdXRoIDIuMCBCQ1AgcmVmcmVzaC10b2tlbiBmYW1pbHkgcmV2b2NhdGlvbiBvbiByZXVzZSBkZXRlY3Rpb24uXG4gICAqIEBkZWZhdWx0VmFsdWUgZmFsc2VcbiAgICovXG4gIHJldm9rZVNlc3Npb25PblJldXNlPzogYm9vbGVhbjtcbn07XG5cbi8qKiBQYXJhbWV0ZXJzIGZvciB7QGxpbmsgUmVmcmVzaFRva2VuU3RvcmUuaXNzdWV9LiAqL1xuZXhwb3J0IHR5cGUgSXNzdWVQYXJhbXMgPSB7XG4gIC8qKiBTdWJqZWN0ICh1c2VyKSBpZGVudGlmaWVyIHRvIGFzc29jaWF0ZSB3aXRoIHRoZSB0b2tlbi4gKi9cbiAgc3ViamVjdElkOiBzdHJpbmc7XG4gIC8qKiBTZXNzaW9uIGlkZW50aWZpZXIgdG8gYXNzb2NpYXRlIHdpdGggdGhlIHRva2VuLiAqL1xuICBzZXNzaW9uSWQ6IHN0cmluZztcbiAgLyoqIENsb2NrIG92ZXJyaWRlIGZvciB0ZXN0czsgZGVmYXVsdHMgdG8gYG5ldyBEYXRlKClgLiAqL1xuICBub3c/OiBEYXRlO1xufTtcblxuLyoqIFJlc3VsdCBvZiB7QGxpbmsgUmVmcmVzaFRva2VuU3RvcmUuaXNzdWV9LiAqL1xuZXhwb3J0IHR5cGUgSXNzdWVSZXN1bHQgPSB7XG4gIC8qKiBPcGFxdWUgcmVmcmVzaCB0b2tlbiBzdHJpbmcgKHBsYWludGV4dDsgb25seSBhIGhhc2ggaXMgc3RvcmVkIGF0IHJlc3QpLiAqL1xuICByZWZyZXNoVG9rZW46IHN0cmluZztcbiAgLyoqIExvZ2ljYWwgZXhwaXJhdGlvbiB0aW1lIGFzIFVuaXggc2Vjb25kcyAoc2FtZSB2YWx1ZSB3cml0dGVuIHRvIGBleHBpcmVzQXRgIC8gYHR0bGApLiAqL1xuICByZWZyZXNoVG9rZW5FeHBpcmVzQXQ6IEVwb2NoU2VjO1xufTtcblxuLyoqIFBhcmFtZXRlcnMgZm9yIHtAbGluayBSZWZyZXNoVG9rZW5TdG9yZS5yb3RhdGV9LiAqL1xuZXhwb3J0IHR5cGUgUm90YXRlUGFyYW1zID0ge1xuICAvKiogQ3VycmVudCByZWZyZXNoIHRva2VuIGZyb20gdGhlIGNsaWVudC4gKi9cbiAgcmVmcmVzaFRva2VuOiBzdHJpbmc7XG4gIC8qKiBDbG9jayBvdmVycmlkZSBmb3IgdGVzdHM7IGRlZmF1bHRzIHRvIGBuZXcgRGF0ZSgpYC4gKi9cbiAgbm93PzogRGF0ZTtcbn07XG5cbi8qKiBSZXN1bHQgb2Yge0BsaW5rIFJlZnJlc2hUb2tlblN0b3JlLnJvdGF0ZX0uICovXG5leHBvcnQgdHlwZSBSb3RhdGVSZXN1bHQgPSB7XG4gIC8qKiBTdWJqZWN0IGlkZW50aWZpZXIgZnJvbSB0aGUgcm90YXRlZCB0b2tlbiByb3cuICovXG4gIHN1YmplY3RJZDogc3RyaW5nO1xuICAvKiogU2Vzc2lvbiBpZGVudGlmaWVyIGZyb20gdGhlIHJvdGF0ZWQgdG9rZW4gcm93LiAqL1xuICBzZXNzaW9uSWQ6IHN0cmluZztcbiAgLyoqIE5ldyBvcGFxdWUgcmVmcmVzaCB0b2tlbiBhZnRlciByb3RhdGlvbi4gKi9cbiAgcmVmcmVzaFRva2VuOiBzdHJpbmc7XG4gIC8qKiBMb2dpY2FsIGV4cGlyYXRpb24gb2YgdGhlIG5ldyB0b2tlbiBhcyBVbml4IHNlY29uZHMuICovXG4gIHJlZnJlc2hUb2tlbkV4cGlyZXNBdDogRXBvY2hTZWM7XG59O1xuXG4vKiogUGFyYW1ldGVycyBmb3Ige0BsaW5rIFJlZnJlc2hUb2tlblN0b3JlLnJldm9rZX0uICovXG5leHBvcnQgdHlwZSBSZXZva2VQYXJhbXMgPSB7XG4gIC8qKiBSZWZyZXNoIHRva2VuIHRvIHJldm9rZS4gKi9cbiAgcmVmcmVzaFRva2VuOiBzdHJpbmc7XG4gIC8qKiBDbG9jayBvdmVycmlkZSBmb3IgdGVzdHM7IGRlZmF1bHRzIHRvIGBuZXcgRGF0ZSgpYC4gKi9cbiAgbm93PzogRGF0ZTtcbn07XG5cbi8qKiBQYXJhbWV0ZXJzIGZvciB7QGxpbmsgUmVmcmVzaFRva2VuU3RvcmUucmV2b2tlU2Vzc2lvbn0uICovXG5leHBvcnQgdHlwZSBSZXZva2VTZXNzaW9uUGFyYW1zID0ge1xuICAvKiogU2Vzc2lvbiB3aG9zZSByZWZyZXNoIHRva2VuIHJvd3Mgc2hvdWxkIGFsbCBiZSByZXZva2VkLiAqL1xuICBzZXNzaW9uSWQ6IHN0cmluZztcbiAgLyoqXG4gICAqIFdoZW4gc2V0LCBvbmx5IHJvd3MgbWF0Y2hpbmcgdGhpcyBzdWJqZWN0IGFyZSByZXZva2VkLlxuICAgKiBBcHBsaWVkIGFzIGFuIGBVcGRhdGVJdGVtYCBjb25kaXRpb24gb24gdGhlIGJhc2UgdGFibGUgKG5vdCBhIEdTSSBmaWx0ZXIpLCBzbyBhXG4gICAqIGBLRVlTX09OTFlgIHNlc3Npb24gR1NJIGlzIHN1ZmZpY2llbnQuXG4gICAqL1xuICBzdWJqZWN0SWQ/OiBzdHJpbmc7XG4gIC8qKiBDbG9jayBvdmVycmlkZSBmb3IgdGVzdHM7IGRlZmF1bHRzIHRvIGBuZXcgRGF0ZSgpYC4gKi9cbiAgbm93PzogRGF0ZTtcbn07XG5cbi8qKiBSZXN1bHQgb2Yge0BsaW5rIFJlZnJlc2hUb2tlblN0b3JlLnJldm9rZVNlc3Npb259LiAqL1xuZXhwb3J0IHR5cGUgUmV2b2tlU2Vzc2lvblJlc3VsdCA9IHtcbiAgLyoqIE51bWJlciBvZiB0b2tlbiByb3dzIHN1Y2Nlc3NmdWxseSB1cGRhdGVkIHdpdGggYHJldm9rZWRBdGAgaW4gdGhpcyBjYWxsLiAqL1xuICByZXZva2VkQ291bnQ6IG51bWJlcjtcbn07XG5cbi8qKlxuICogRHluYW1vREIgaXRlbSBzaGFwZSBmb3IgYSBzdG9yZWQgcmVmcmVzaCB0b2tlbiAoaGFzaC1rZXllZCBieSBgcGtgKS5cbiAqXG4gKiBgZXhwaXJlc0F0YCBpcyB1c2VkIGZvciBhcHBsaWNhdGlvbi1sZXZlbCB2YWxpZGF0aW9uOyBgdHRsYCBpcyB0aGUgRHluYW1vREIgVFRMXG4gKiBhdHRyaWJ1dGUgZm9yIGFzeW5jaHJvbm91cyBpdGVtIGRlbGV0aW9uIChlbmFibGUgVFRMIG9uIHRoZSB0YWJsZSBmb3IgYXR0cmlidXRlIGB0dGxgKS5cbiAqL1xuZXhwb3J0IHR5cGUgVG9rZW5SZWNvcmQgPSB7XG4gIC8qKiBQYXJ0aXRpb24ga2V5OiBwcmVmaXggKyBTSEEtMjU2IGhleCBvZiB0aGUgcGxhaW50ZXh0IHRva2VuLiAqL1xuICBwazogc3RyaW5nO1xuICAvKiogU3ViamVjdCAodXNlcikgaWRlbnRpZmllcjsgYWxzbyB1c2VkIHdoZW4gY2FzY2FkaW5nIHNlc3Npb24gcmV2b2tlIG9uIHJldXNlLiAqL1xuICBzdWJqZWN0SWQ6IHN0cmluZztcbiAgLyoqXG4gICAqIFNlc3Npb24gaWRlbnRpZmllci4gUGFydGl0aW9uIGtleSBvZiB0aGUgc2Vzc2lvbiBHU0kgdXNlZCBieVxuICAgKiB7QGxpbmsgUmVmcmVzaFRva2VuU3RvcmUucmV2b2tlU2Vzc2lvbn0uXG4gICAqL1xuICBzZXNzaW9uSWQ6IHN0cmluZztcbiAgLyoqIFJvdyBjcmVhdGlvbiB0aW1lIGFzIFVuaXggc2Vjb25kcy4gKi9cbiAgY3JlYXRlZEF0OiBFcG9jaFNlYztcbiAgLyoqIExvZ2ljYWwgZXhwaXJhdGlvbiB0aW1lIGFzIFVuaXggc2Vjb25kcy4gKi9cbiAgZXhwaXJlc0F0OiBFcG9jaFNlYztcbiAgLyoqXG4gICAqIER5bmFtb0RCIFRUTCBhdHRyaWJ1dGUgKFVuaXggc2Vjb25kcykuIFNldCBvbiB3cml0ZTsgdGFibGUgVFRMIG11c3QgdGFyZ2V0IHRoaXMgYXR0cmlidXRlIG5hbWUuXG4gICAqL1xuICB0dGw6IEVwb2NoU2VjO1xuICAvKiogVGltZSB0aGUgdG9rZW4gd2FzIHJvdGF0ZWQsIGlmIGFwcGxpY2FibGUuICovXG4gIHJvdGF0ZWRBdD86IEVwb2NoU2VjIHwgbnVsbDtcbiAgLyoqIFBhcnRpdGlvbiBrZXkgb2YgdGhlIHN1Y2Nlc3NvciB0b2tlbiBhZnRlciByb3RhdGlvbi4gKi9cbiAgcmVwbGFjZWRCeVBrPzogc3RyaW5nIHwgbnVsbDtcbiAgLyoqIFRpbWUgdGhlIHRva2VuIHdhcyByZXZva2VkLCBpZiBhcHBsaWNhYmxlLiAqL1xuICByZXZva2VkQXQ/OiBFcG9jaFNlYyB8IG51bGw7XG59O1xuXG4vKipcbiAqIFBlcnNpc3RlbmNlIGFic3RyYWN0aW9uIGZvciBvcGFxdWUgcmVmcmVzaCB0b2tlbnM6IGlzc3VlLCByb3RhdGUsIHJldm9rZSwgYW5kIHNlc3Npb24gcmV2b2tlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFJlZnJlc2hUb2tlblN0b3JlIHtcbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBuZXcgcmVmcmVzaCB0b2tlbiByb3cgYW5kIHJldHVybnMgdGhlIHBsYWludGV4dCB0b2tlbi5cbiAgICpcbiAgICogQHBhcmFtIHBhcmFtcyAtIFN1YmplY3QsIHNlc3Npb24sIGFuZCBvcHRpb25hbCBjbG9jay5cbiAgICogQHJldHVybnMgUGxhaW50ZXh0IHRva2VuIGFuZCBleHBpcmF0aW9uIGFzIFVuaXggc2Vjb25kcy5cbiAgICovXG4gIGlzc3VlKHBhcmFtczogSXNzdWVQYXJhbXMpOiBQcm9taXNlPElzc3VlUmVzdWx0PjtcblxuICAvKipcbiAgICogVmFsaWRhdGVzIHRoZSBjdXJyZW50IHRva2VuLCBtYXJrcyBpdCByb3RhdGVkLCBpbnNlcnRzIHRoZSBzdWNjZXNzb3Igcm93LCBhbmQgcmV0dXJucyB0aGUgbmV3IHRva2VuLlxuICAgKlxuICAgKiBXaGVuIHJldXNlIGlzIGRldGVjdGVkIGFuZCB7QGxpbmsgU3RvcmVPcHRpb25zLnJldm9rZVNlc3Npb25PblJldXNlfSBpcyBlbmFibGVkLCB0aGVcbiAgICogaW1wbGVtZW50YXRpb24gbWF5IHJldm9rZSB0aGUgd2hvbGUgc2Vzc2lvbiBiZWZvcmUgdGhyb3dpbmcuXG4gICAqXG4gICAqIEBwYXJhbSBwYXJhbXMgLSBDdXJyZW50IHRva2VuIGFuZCBvcHRpb25hbCBjbG9jay5cbiAgICogQHJldHVybnMgU3ViamVjdCwgc2Vzc2lvbiwgbmV3IHRva2VuLCBhbmQgbmV3IGV4cGlyYXRpb24uXG4gICAqIEB0aHJvd3Mge0BsaW5rIFJlZnJlc2hUb2tlbkludmFsaWRFcnJvcn0gV2hlbiB0aGUgdG9rZW4gaXMgaW52YWxpZCBvciBubyByb3cgZXhpc3RzLlxuICAgKiBAdGhyb3dzIHtAbGluayBSZWZyZXNoVG9rZW5FeHBpcmVkRXJyb3J9IFdoZW4gYGV4cGlyZXNBdGAgaXMgbm90IGFmdGVyIGBub3dgLlxuICAgKiBAdGhyb3dzIHtAbGluayBSZWZyZXNoVG9rZW5SZXZva2VkRXJyb3J9IFdoZW4gdGhlIHJvdyBoYXMgYHJldm9rZWRBdGAgc2V0LlxuICAgKiBAdGhyb3dzIHtAbGluayBSZWZyZXNoVG9rZW5SZXVzZWRFcnJvcn0gV2hlbiB0aGUgdG9rZW4gd2FzIGFscmVhZHkgcm90YXRlZCBvciB0aGUgdHJhbnNhY3Rpb25cbiAgICogICBmYWlsZWQgY29uZGl0aW9uYWxseS4gTWF5IGluY2x1ZGUgYHN1YmplY3RJZGAgLyBgc2Vzc2lvbklkYCBmcm9tIHRoZSBzdG9yZSByb3cuXG4gICAqL1xuICByb3RhdGUocGFyYW1zOiBSb3RhdGVQYXJhbXMpOiBQcm9taXNlPFJvdGF0ZVJlc3VsdD47XG5cbiAgLyoqXG4gICAqIFNldHMgYHJldm9rZWRBdGAgb24gdGhlIHRva2VuIHJvdy4gSWRlbXBvdGVudCBpZiB0aGUgcm93IGRvZXMgbm90IGV4aXN0LlxuICAgKlxuICAgKiBEb2VzIG5vdCBjaGFuZ2UgRHluYW1vREIgVFRMIChgdHRsYCk7IGNsZWFudXAgc3RpbGwgZm9sbG93cyB0aGUgdmFsdWUgZnJvbSBpc3N1ZS9yb3RhdGUuXG4gICAqXG4gICAqIEBwYXJhbSBwYXJhbXMgLSBUb2tlbiB0byByZXZva2UgYW5kIG9wdGlvbmFsIGNsb2NrLlxuICAgKiBAcmV0dXJucyBgdHJ1ZWAgYWZ0ZXIgYSBzdWNjZXNzZnVsIHVwZGF0ZSBvciBuby1vcCB3aGVuIHRoZSBpdGVtIGlzIGFic2VudC5cbiAgICogQHRocm93cyB7QGxpbmsgUmVmcmVzaFRva2VuSW52YWxpZEVycm9yfSBXaGVuIHRoZSB0b2tlbiBzdHJpbmcgZm9ybWF0IGlzIGludmFsaWQuXG4gICAqL1xuICByZXZva2UocGFyYW1zOiBSZXZva2VQYXJhbXMpOiBQcm9taXNlPHRydWU+O1xuXG4gIC8qKlxuICAgKiBTZXRzIGByZXZva2VkQXRgIG9uIGV2ZXJ5IHJlZnJlc2ggdG9rZW4gcm93IGZvciB0aGUgZ2l2ZW4gc2Vzc2lvbiAoT0F1dGggMi4wIEJDUCBmYW1pbHkgcmV2b2NhdGlvbikuXG4gICAqXG4gICAqIFJlcXVpcmVzIGEgRHluYW1vREIgR1NJIHdob3NlIHBhcnRpdGlvbiBrZXkgaXMgYHNlc3Npb25JZGAgKHNlZSB7QGxpbmsgU3RvcmVPcHRpb25zLnNlc3Npb25JZEluZGV4TmFtZX0pLlxuICAgKiBPcHRpb25hbCBgc3ViamVjdElkYCBpcyBlbmZvcmNlZCBvbiBlYWNoIGJhc2UtdGFibGUgdXBkYXRlIGNvbmRpdGlvbi5cbiAgICpcbiAgICogQHBhcmFtIHBhcmFtcyAtIFNlc3Npb24gaWQsIG9wdGlvbmFsIHN1YmplY3QgZmlsdGVyLCBhbmQgb3B0aW9uYWwgY2xvY2suXG4gICAqIEByZXR1cm5zIENvdW50IG9mIHJvd3MgdXBkYXRlZCB3aXRoIGByZXZva2VkQXRgLlxuICAgKi9cbiAgcmV2b2tlU2Vzc2lvbihwYXJhbXM6IFJldm9rZVNlc3Npb25QYXJhbXMpOiBQcm9taXNlPFJldm9rZVNlc3Npb25SZXN1bHQ+O1xufVxuIl19
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdHlwZXMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgbWFyc2hhbGxPcHRpb25zLCB1bm1hcnNoYWxsT3B0aW9ucyB9IGZyb20gJ0Bhd3Mtc2RrL2xpYi1keW5hbW9kYic7XG5cbi8qKiBVbml4IHRpbWVzdGFtcCBpbiB3aG9sZSBzZWNvbmRzLiAqL1xuZXhwb3J0IHR5cGUgRXBvY2hTZWMgPSBudW1iZXI7XG5cbi8qKlxuICogUGFzcy10aHJvdWdoIHRvIHtAbGluayBEeW5hbW9EQkRvY3VtZW50Q2xpZW50LmZyb219IGB0cmFuc2xhdGVDb25maWdgIChtYXJzaGFsbCAvIHVubWFyc2hhbGwgb3B0aW9ucykuXG4gKi9cbmV4cG9ydCB0eXBlIERvY3VtZW50Q2xpZW50VHJhbnNsYXRlQ29uZmlnID0ge1xuICAvKiogT3B0aW9ucyBmb3IgbWFyc2hhbGxpbmcgSmF2YVNjcmlwdCB2YWx1ZXMgdG8gRHluYW1vREIgYXR0cmlidXRlIHZhbHVlcy4gKi9cbiAgbWFyc2hhbGxPcHRpb25zPzogbWFyc2hhbGxPcHRpb25zO1xuICAvKiogT3B0aW9ucyBmb3IgdW5tYXJzaGFsbGluZyBEeW5hbW9EQiBhdHRyaWJ1dGUgdmFsdWVzIHRvIEphdmFTY3JpcHQgdmFsdWVzLiAqL1xuICB1bm1hcnNoYWxsT3B0aW9ucz86IHVubWFyc2hhbGxPcHRpb25zO1xufTtcblxuLyoqXG4gKiBDb25maWd1cmF0aW9uIGZvciB0aGUgRHluYW1vREIgcmVmcmVzaCB0b2tlbiBwcm92aWRlciBjb25zdHJ1Y3Rvci5cbiAqXG4gKiBUb2tlbiBsaWZldGltZSAoYHR0bERheXNgIG9yIGB0dGxTZWNvbmRzYCkgZHJpdmVzIGJvdGggbG9naWNhbCBleHBpcmF0aW9uIChgZXhwaXJlc0F0YCkgYW5kIHRoZVxuICogRHluYW1vREIgVFRMIGF0dHJpYnV0ZSAoYHR0bGApIHdyaXR0ZW4gb24gUHV0IC8gVHJhbnNhY3QuIFdoZW4gYm90aCBhcmUgc2V0LCBgdHRsU2Vjb25kc2AgdGFrZXNcbiAqIHByZWNlZGVuY2UuIFNlc3Npb24gcmV2b2NhdGlvbiBvcHRpb25zIChgc2Vzc2lvbklkSW5kZXhOYW1lYCwgYHJldm9rZVNlc3Npb25PblJldXNlYCkgcmVxdWlyZSBhXG4gKiBHU0kgd2hvc2UgcGFydGl0aW9uIGtleSBpcyBgc2Vzc2lvbklkYC4gU3ViamVjdC13aWRlIHJldm9jYXRpb24gKGBzdWJqZWN0SWRJbmRleE5hbWVgLFxuICoge0BsaW5rIFJlZnJlc2hUb2tlblN0b3JlLnJldm9rZVN1YmplY3R9KSByZXF1aXJlcyBhIEdTSSB3aG9zZSBwYXJ0aXRpb24ga2V5IGlzIGBzdWJqZWN0SWRgLlxuICovXG5leHBvcnQgdHlwZSBTdG9yZU9wdGlvbnMgPSB7XG4gIC8qKlxuICAgKiBSZWZyZXNoIHRva2VuIGxpZmV0aW1lIGluIGRheXMgKGFkZGVkIHRvIGBub3dgIHdoZW4gY29tcHV0aW5nIGBleHBpcmVzQXRgIC8gYHR0bGApLlxuICAgKiBJZ25vcmVkIHdoZW4ge0BsaW5rIFN0b3JlT3B0aW9ucy50dGxTZWNvbmRzfSBpcyBzZXQuXG4gICAqIEBkZWZhdWx0VmFsdWUgNjBcbiAgICovXG4gIHR0bERheXM/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFJlZnJlc2ggdG9rZW4gbGlmZXRpbWUgaW4gc2Vjb25kcyAoYWRkZWQgdG8gYG5vd2Agd2hlbiBjb21wdXRpbmcgYGV4cGlyZXNBdGAgLyBgdHRsYCkuXG4gICAqIFRha2VzIHByZWNlZGVuY2Ugb3ZlciB7QGxpbmsgU3RvcmVPcHRpb25zLnR0bERheXN9IHdoZW4gYm90aCBhcmUgc2V0LlxuICAgKi9cbiAgdHRsU2Vjb25kcz86IG51bWJlcjtcblxuICAvKipcbiAgICogTnVtYmVyIG9mIHJhbmRvbSBieXRlcyB1c2VkIHdoZW4gZ2VuZXJhdGluZyBvcGFxdWUgcmVmcmVzaCB0b2tlbnMuXG4gICAqIEBkZWZhdWx0VmFsdWUgMzJcbiAgICovXG4gIHRva2VuQnl0ZXM/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFBhc3MtdGhyb3VnaCB0byB7QGxpbmsgRHluYW1vREJEb2N1bWVudENsaWVudC5mcm9tfSBgdHJhbnNsYXRlQ29uZmlnYCAoZS5nLiBgcmVtb3ZlVW5kZWZpbmVkVmFsdWVzYCkuXG4gICAqL1xuICB0cmFuc2xhdGVDb25maWc/OiBEb2N1bWVudENsaWVudFRyYW5zbGF0ZUNvbmZpZztcblxuICAvKipcbiAgICogUGFydGl0aW9uIGtleSBwcmVmaXggZm9yIER5bmFtb0RCIGl0ZW1zOyBmdWxsIGBwa2AgaXMgYHByZWZpeGAgKyBTSEEtMjU2IGhleCBvZiB0aGUgdG9rZW4uXG4gICAqIEBkZWZhdWx0VmFsdWUgYCdydCMnYFxuICAgKi9cbiAgcGtQcmVmaXg/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdG8gdXNlIHN0cm9uZ2x5IGNvbnNpc3RlbnQgcmVhZHMgb24gYEdldEl0ZW1gLlxuICAgKiBAZGVmYXVsdFZhbHVlIHRydWVcbiAgICovXG4gIGNvbnNpc3RlbnRSZWFkPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogQ3VzdG9tIER5bmFtb0RCIEFQSSBlbmRwb2ludCAoZS5nLiBMb2NhbFN0YWNrIG9yIER5bmFtb0RCIExvY2FsKS5cbiAgICovXG4gIGVuZHBvaW50Pzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBEeW5hbW9EQiBHU0kgbmFtZSB3aG9zZSBwYXJ0aXRpb24ga2V5IGF0dHJpYnV0ZSBpcyBgc2Vzc2lvbklkYCAoU3RyaW5nKS5cbiAgICogUmVxdWlyZWQgZm9yIHtAbGluayBSZWZyZXNoVG9rZW5TdG9yZS5yZXZva2VTZXNzaW9ufSBhbmQgZm9yIGByZXZva2VTZXNzaW9uT25SZXVzZWAuXG4gICAqIGBLRVlTX09OTFlgIHByb2plY3Rpb24gaXMgc3VmZmljaWVudC5cbiAgICogQGRlZmF1bHRWYWx1ZSBgJ3Nlc3Npb25JZC1pbmRleCdgXG4gICAqL1xuICBzZXNzaW9uSWRJbmRleE5hbWU/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIER5bmFtb0RCIEdTSSBuYW1lIHdob3NlIHBhcnRpdGlvbiBrZXkgYXR0cmlidXRlIGlzIGBzdWJqZWN0SWRgIChTdHJpbmcpLlxuICAgKiBSZXF1aXJlZCBmb3Ige0BsaW5rIFJlZnJlc2hUb2tlblN0b3JlLnJldm9rZVN1YmplY3R9IChlLmcuIGxvZ291dCBhbGwgZGV2aWNlcywgcGFzc3dvcmQgY2hhbmdlKS5cbiAgICogYEtFWVNfT05MWWAgcHJvamVjdGlvbiBpcyBzdWZmaWNpZW50LlxuICAgKiBAZGVmYXVsdFZhbHVlIGAnc3ViamVjdElkLWluZGV4J2BcbiAgICovXG4gIHN1YmplY3RJZEluZGV4TmFtZT86IHN0cmluZztcblxuICAvKipcbiAgICogV2hlbiB0cnVlLCB7QGxpbmsgUmVmcmVzaFRva2VuU3RvcmUucm90YXRlfSBjYWxscyB7QGxpbmsgUmVmcmVzaFRva2VuU3RvcmUucmV2b2tlU2Vzc2lvbn1cbiAgICogZm9yIHRoZSB0b2tlbuKAmXMgYHNlc3Npb25JZGAgYW5kIGBzdWJqZWN0SWRgIGJlZm9yZSB0aHJvd2luZyB7QGxpbmsgUmVmcmVzaFRva2VuUmV1c2VkRXJyb3J9LlxuICAgKiBBbGlnbnMgd2l0aCBPQXV0aCAyLjAgQkNQIHJlZnJlc2gtdG9rZW4gZmFtaWx5IHJldm9jYXRpb24gb24gcmV1c2UgZGV0ZWN0aW9uLlxuICAgKiBAZGVmYXVsdFZhbHVlIGZhbHNlXG4gICAqL1xuICByZXZva2VTZXNzaW9uT25SZXVzZT86IGJvb2xlYW47XG59O1xuXG4vKiogUGFyYW1ldGVycyBmb3Ige0BsaW5rIFJlZnJlc2hUb2tlblN0b3JlLmlzc3VlfS4gKi9cbmV4cG9ydCB0eXBlIElzc3VlUGFyYW1zID0ge1xuICAvKiogU3ViamVjdCAodXNlcikgaWRlbnRpZmllciB0byBhc3NvY2lhdGUgd2l0aCB0aGUgdG9rZW4uICovXG4gIHN1YmplY3RJZDogc3RyaW5nO1xuICAvKiogU2Vzc2lvbiBpZGVudGlmaWVyIHRvIGFzc29jaWF0ZSB3aXRoIHRoZSB0b2tlbi4gKi9cbiAgc2Vzc2lvbklkOiBzdHJpbmc7XG4gIC8qKiBDbG9jayBvdmVycmlkZSBmb3IgdGVzdHM7IGRlZmF1bHRzIHRvIGBuZXcgRGF0ZSgpYC4gKi9cbiAgbm93PzogRGF0ZTtcbn07XG5cbi8qKiBSZXN1bHQgb2Yge0BsaW5rIFJlZnJlc2hUb2tlblN0b3JlLmlzc3VlfS4gKi9cbmV4cG9ydCB0eXBlIElzc3VlUmVzdWx0ID0ge1xuICAvKiogT3BhcXVlIHJlZnJlc2ggdG9rZW4gc3RyaW5nIChwbGFpbnRleHQ7IG9ubHkgYSBoYXNoIGlzIHN0b3JlZCBhdCByZXN0KS4gKi9cbiAgcmVmcmVzaFRva2VuOiBzdHJpbmc7XG4gIC8qKiBMb2dpY2FsIGV4cGlyYXRpb24gdGltZSBhcyBVbml4IHNlY29uZHMgKHNhbWUgdmFsdWUgd3JpdHRlbiB0byBgZXhwaXJlc0F0YCAvIGB0dGxgKS4gKi9cbiAgcmVmcmVzaFRva2VuRXhwaXJlc0F0OiBFcG9jaFNlYztcbn07XG5cbi8qKiBQYXJhbWV0ZXJzIGZvciB7QGxpbmsgUmVmcmVzaFRva2VuU3RvcmUucm90YXRlfS4gKi9cbmV4cG9ydCB0eXBlIFJvdGF0ZVBhcmFtcyA9IHtcbiAgLyoqIEN1cnJlbnQgcmVmcmVzaCB0b2tlbiBmcm9tIHRoZSBjbGllbnQuICovXG4gIHJlZnJlc2hUb2tlbjogc3RyaW5nO1xuICAvKiogQ2xvY2sgb3ZlcnJpZGUgZm9yIHRlc3RzOyBkZWZhdWx0cyB0byBgbmV3IERhdGUoKWAuICovXG4gIG5vdz86IERhdGU7XG59O1xuXG4vKiogUmVzdWx0IG9mIHtAbGluayBSZWZyZXNoVG9rZW5TdG9yZS5yb3RhdGV9LiAqL1xuZXhwb3J0IHR5cGUgUm90YXRlUmVzdWx0ID0ge1xuICAvKiogU3ViamVjdCBpZGVudGlmaWVyIGZyb20gdGhlIHJvdGF0ZWQgdG9rZW4gcm93LiAqL1xuICBzdWJqZWN0SWQ6IHN0cmluZztcbiAgLyoqIFNlc3Npb24gaWRlbnRpZmllciBmcm9tIHRoZSByb3RhdGVkIHRva2VuIHJvdy4gKi9cbiAgc2Vzc2lvbklkOiBzdHJpbmc7XG4gIC8qKiBOZXcgb3BhcXVlIHJlZnJlc2ggdG9rZW4gYWZ0ZXIgcm90YXRpb24uICovXG4gIHJlZnJlc2hUb2tlbjogc3RyaW5nO1xuICAvKiogTG9naWNhbCBleHBpcmF0aW9uIG9mIHRoZSBuZXcgdG9rZW4gYXMgVW5peCBzZWNvbmRzLiAqL1xuICByZWZyZXNoVG9rZW5FeHBpcmVzQXQ6IEVwb2NoU2VjO1xufTtcblxuLyoqIFBhcmFtZXRlcnMgZm9yIHtAbGluayBSZWZyZXNoVG9rZW5TdG9yZS5yZXZva2V9LiAqL1xuZXhwb3J0IHR5cGUgUmV2b2tlUGFyYW1zID0ge1xuICAvKiogUmVmcmVzaCB0b2tlbiB0byByZXZva2UuICovXG4gIHJlZnJlc2hUb2tlbjogc3RyaW5nO1xuICAvKiogQ2xvY2sgb3ZlcnJpZGUgZm9yIHRlc3RzOyBkZWZhdWx0cyB0byBgbmV3IERhdGUoKWAuICovXG4gIG5vdz86IERhdGU7XG59O1xuXG4vKiogUGFyYW1ldGVycyBmb3Ige0BsaW5rIFJlZnJlc2hUb2tlblN0b3JlLnJldm9rZVNlc3Npb259LiAqL1xuZXhwb3J0IHR5cGUgUmV2b2tlU2Vzc2lvblBhcmFtcyA9IHtcbiAgLyoqIFNlc3Npb24gd2hvc2UgcmVmcmVzaCB0b2tlbiByb3dzIHNob3VsZCBhbGwgYmUgcmV2b2tlZC4gKi9cbiAgc2Vzc2lvbklkOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBXaGVuIHNldCwgb25seSByb3dzIG1hdGNoaW5nIHRoaXMgc3ViamVjdCBhcmUgcmV2b2tlZC5cbiAgICogQXBwbGllZCBhcyBhbiBgVXBkYXRlSXRlbWAgY29uZGl0aW9uIG9uIHRoZSBiYXNlIHRhYmxlIChub3QgYSBHU0kgZmlsdGVyKSwgc28gYVxuICAgKiBgS0VZU19PTkxZYCBzZXNzaW9uIEdTSSBpcyBzdWZmaWNpZW50LlxuICAgKi9cbiAgc3ViamVjdElkPzogc3RyaW5nO1xuICAvKiogQ2xvY2sgb3ZlcnJpZGUgZm9yIHRlc3RzOyBkZWZhdWx0cyB0byBgbmV3IERhdGUoKWAuICovXG4gIG5vdz86IERhdGU7XG59O1xuXG4vKiogUmVzdWx0IG9mIHtAbGluayBSZWZyZXNoVG9rZW5TdG9yZS5yZXZva2VTZXNzaW9ufS4gKi9cbmV4cG9ydCB0eXBlIFJldm9rZVNlc3Npb25SZXN1bHQgPSB7XG4gIC8qKiBOdW1iZXIgb2YgdG9rZW4gcm93cyBzdWNjZXNzZnVsbHkgdXBkYXRlZCB3aXRoIGByZXZva2VkQXRgIGluIHRoaXMgY2FsbC4gKi9cbiAgcmV2b2tlZENvdW50OiBudW1iZXI7XG59O1xuXG4vKiogUGFyYW1ldGVycyBmb3Ige0BsaW5rIFJlZnJlc2hUb2tlblN0b3JlLnJldm9rZVN1YmplY3R9LiAqL1xuZXhwb3J0IHR5cGUgUmV2b2tlU3ViamVjdFBhcmFtcyA9IHtcbiAgLyoqIFN1YmplY3QgKHVzZXIpIHdob3NlIHJlZnJlc2ggdG9rZW4gcm93cyBzaG91bGQgYWxsIGJlIHJldm9rZWQgYWNyb3NzIGV2ZXJ5IHNlc3Npb24uICovXG4gIHN1YmplY3RJZDogc3RyaW5nO1xuICAvKiogQ2xvY2sgb3ZlcnJpZGUgZm9yIHRlc3RzOyBkZWZhdWx0cyB0byBgbmV3IERhdGUoKWAuICovXG4gIG5vdz86IERhdGU7XG59O1xuXG4vKiogUmVzdWx0IG9mIHtAbGluayBSZWZyZXNoVG9rZW5TdG9yZS5yZXZva2VTdWJqZWN0fS4gKi9cbmV4cG9ydCB0eXBlIFJldm9rZVN1YmplY3RSZXN1bHQgPSB7XG4gIC8qKiBOdW1iZXIgb2YgdG9rZW4gcm93cyBzdWNjZXNzZnVsbHkgdXBkYXRlZCB3aXRoIGByZXZva2VkQXRgIGluIHRoaXMgY2FsbC4gKi9cbiAgcmV2b2tlZENvdW50OiBudW1iZXI7XG59O1xuXG4vKipcbiAqIER5bmFtb0RCIGl0ZW0gc2hhcGUgZm9yIGEgc3RvcmVkIHJlZnJlc2ggdG9rZW4gKGhhc2gta2V5ZWQgYnkgYHBrYCkuXG4gKlxuICogYGV4cGlyZXNBdGAgaXMgdXNlZCBmb3IgYXBwbGljYXRpb24tbGV2ZWwgdmFsaWRhdGlvbjsgYHR0bGAgaXMgdGhlIER5bmFtb0RCIFRUTFxuICogYXR0cmlidXRlIGZvciBhc3luY2hyb25vdXMgaXRlbSBkZWxldGlvbiAoZW5hYmxlIFRUTCBvbiB0aGUgdGFibGUgZm9yIGF0dHJpYnV0ZSBgdHRsYCkuXG4gKi9cbmV4cG9ydCB0eXBlIFRva2VuUmVjb3JkID0ge1xuICAvKiogUGFydGl0aW9uIGtleTogcHJlZml4ICsgU0hBLTI1NiBoZXggb2YgdGhlIHBsYWludGV4dCB0b2tlbi4gKi9cbiAgcGs6IHN0cmluZztcbiAgLyoqIFN1YmplY3QgKHVzZXIpIGlkZW50aWZpZXI7IHBhcnRpdGlvbiBrZXkgb2YgdGhlIHN1YmplY3QgR1NJIHVzZWQgYnkge0BsaW5rIFJlZnJlc2hUb2tlblN0b3JlLnJldm9rZVN1YmplY3R9LiAqL1xuICBzdWJqZWN0SWQ6IHN0cmluZztcbiAgLyoqXG4gICAqIFNlc3Npb24gaWRlbnRpZmllci4gUGFydGl0aW9uIGtleSBvZiB0aGUgc2Vzc2lvbiBHU0kgdXNlZCBieVxuICAgKiB7QGxpbmsgUmVmcmVzaFRva2VuU3RvcmUucmV2b2tlU2Vzc2lvbn0uXG4gICAqL1xuICBzZXNzaW9uSWQ6IHN0cmluZztcbiAgLyoqIFJvdyBjcmVhdGlvbiB0aW1lIGFzIFVuaXggc2Vjb25kcy4gKi9cbiAgY3JlYXRlZEF0OiBFcG9jaFNlYztcbiAgLyoqIExvZ2ljYWwgZXhwaXJhdGlvbiB0aW1lIGFzIFVuaXggc2Vjb25kcy4gKi9cbiAgZXhwaXJlc0F0OiBFcG9jaFNlYztcbiAgLyoqXG4gICAqIER5bmFtb0RCIFRUTCBhdHRyaWJ1dGUgKFVuaXggc2Vjb25kcykuIFNldCBvbiB3cml0ZTsgdGFibGUgVFRMIG11c3QgdGFyZ2V0IHRoaXMgYXR0cmlidXRlIG5hbWUuXG4gICAqL1xuICB0dGw6IEVwb2NoU2VjO1xuICAvKiogVGltZSB0aGUgdG9rZW4gd2FzIHJvdGF0ZWQsIGlmIGFwcGxpY2FibGUuICovXG4gIHJvdGF0ZWRBdD86IEVwb2NoU2VjIHwgbnVsbDtcbiAgLyoqIFBhcnRpdGlvbiBrZXkgb2YgdGhlIHN1Y2Nlc3NvciB0b2tlbiBhZnRlciByb3RhdGlvbi4gKi9cbiAgcmVwbGFjZWRCeVBrPzogc3RyaW5nIHwgbnVsbDtcbiAgLyoqIFRpbWUgdGhlIHRva2VuIHdhcyByZXZva2VkLCBpZiBhcHBsaWNhYmxlLiAqL1xuICByZXZva2VkQXQ/OiBFcG9jaFNlYyB8IG51bGw7XG59O1xuXG4vKipcbiAqIFBlcnNpc3RlbmNlIGFic3RyYWN0aW9uIGZvciBvcGFxdWUgcmVmcmVzaCB0b2tlbnM6IGlzc3VlLCByb3RhdGUsIHJldm9rZSwgYW5kIHNlc3Npb24gcmV2b2tlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFJlZnJlc2hUb2tlblN0b3JlIHtcbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBuZXcgcmVmcmVzaCB0b2tlbiByb3cgYW5kIHJldHVybnMgdGhlIHBsYWludGV4dCB0b2tlbi5cbiAgICpcbiAgICogQHBhcmFtIHBhcmFtcyAtIFN1YmplY3QsIHNlc3Npb24sIGFuZCBvcHRpb25hbCBjbG9jay5cbiAgICogQHJldHVybnMgUGxhaW50ZXh0IHRva2VuIGFuZCBleHBpcmF0aW9uIGFzIFVuaXggc2Vjb25kcy5cbiAgICovXG4gIGlzc3VlKHBhcmFtczogSXNzdWVQYXJhbXMpOiBQcm9taXNlPElzc3VlUmVzdWx0PjtcblxuICAvKipcbiAgICogVmFsaWRhdGVzIHRoZSBjdXJyZW50IHRva2VuLCBtYXJrcyBpdCByb3RhdGVkLCBpbnNlcnRzIHRoZSBzdWNjZXNzb3Igcm93LCBhbmQgcmV0dXJucyB0aGUgbmV3IHRva2VuLlxuICAgKlxuICAgKiBXaGVuIHJldXNlIGlzIGRldGVjdGVkIGFuZCB7QGxpbmsgU3RvcmVPcHRpb25zLnJldm9rZVNlc3Npb25PblJldXNlfSBpcyBlbmFibGVkLCB0aGVcbiAgICogaW1wbGVtZW50YXRpb24gbWF5IHJldm9rZSB0aGUgd2hvbGUgc2Vzc2lvbiBiZWZvcmUgdGhyb3dpbmcuXG4gICAqXG4gICAqIEBwYXJhbSBwYXJhbXMgLSBDdXJyZW50IHRva2VuIGFuZCBvcHRpb25hbCBjbG9jay5cbiAgICogQHJldHVybnMgU3ViamVjdCwgc2Vzc2lvbiwgbmV3IHRva2VuLCBhbmQgbmV3IGV4cGlyYXRpb24uXG4gICAqIEB0aHJvd3Mge0BsaW5rIFJlZnJlc2hUb2tlbkludmFsaWRFcnJvcn0gV2hlbiB0aGUgdG9rZW4gaXMgaW52YWxpZCBvciBubyByb3cgZXhpc3RzLlxuICAgKiBAdGhyb3dzIHtAbGluayBSZWZyZXNoVG9rZW5FeHBpcmVkRXJyb3J9IFdoZW4gYGV4cGlyZXNBdGAgaXMgbm90IGFmdGVyIGBub3dgLlxuICAgKiBAdGhyb3dzIHtAbGluayBSZWZyZXNoVG9rZW5SZXZva2VkRXJyb3J9IFdoZW4gdGhlIHJvdyBoYXMgYHJldm9rZWRBdGAgc2V0LlxuICAgKiBAdGhyb3dzIHtAbGluayBSZWZyZXNoVG9rZW5SZXVzZWRFcnJvcn0gV2hlbiB0aGUgdG9rZW4gd2FzIGFscmVhZHkgcm90YXRlZCBvciB0aGUgdHJhbnNhY3Rpb25cbiAgICogICBmYWlsZWQgY29uZGl0aW9uYWxseS4gTWF5IGluY2x1ZGUgYHN1YmplY3RJZGAgLyBgc2Vzc2lvbklkYCBmcm9tIHRoZSBzdG9yZSByb3cuXG4gICAqL1xuICByb3RhdGUocGFyYW1zOiBSb3RhdGVQYXJhbXMpOiBQcm9taXNlPFJvdGF0ZVJlc3VsdD47XG5cbiAgLyoqXG4gICAqIFNldHMgYHJldm9rZWRBdGAgb24gdGhlIHRva2VuIHJvdy4gSWRlbXBvdGVudCBpZiB0aGUgcm93IGRvZXMgbm90IGV4aXN0LlxuICAgKlxuICAgKiBEb2VzIG5vdCBjaGFuZ2UgRHluYW1vREIgVFRMIChgdHRsYCk7IGNsZWFudXAgc3RpbGwgZm9sbG93cyB0aGUgdmFsdWUgZnJvbSBpc3N1ZS9yb3RhdGUuXG4gICAqXG4gICAqIEBwYXJhbSBwYXJhbXMgLSBUb2tlbiB0byByZXZva2UgYW5kIG9wdGlvbmFsIGNsb2NrLlxuICAgKiBAcmV0dXJucyBgdHJ1ZWAgYWZ0ZXIgYSBzdWNjZXNzZnVsIHVwZGF0ZSBvciBuby1vcCB3aGVuIHRoZSBpdGVtIGlzIGFic2VudC5cbiAgICogQHRocm93cyB7QGxpbmsgUmVmcmVzaFRva2VuSW52YWxpZEVycm9yfSBXaGVuIHRoZSB0b2tlbiBzdHJpbmcgZm9ybWF0IGlzIGludmFsaWQuXG4gICAqL1xuICByZXZva2UocGFyYW1zOiBSZXZva2VQYXJhbXMpOiBQcm9taXNlPHRydWU+O1xuXG4gIC8qKlxuICAgKiBTZXRzIGByZXZva2VkQXRgIG9uIGV2ZXJ5IHJlZnJlc2ggdG9rZW4gcm93IGZvciB0aGUgZ2l2ZW4gc2Vzc2lvbiAoT0F1dGggMi4wIEJDUCBmYW1pbHkgcmV2b2NhdGlvbikuXG4gICAqXG4gICAqIFJlcXVpcmVzIGEgRHluYW1vREIgR1NJIHdob3NlIHBhcnRpdGlvbiBrZXkgaXMgYHNlc3Npb25JZGAgKHNlZSB7QGxpbmsgU3RvcmVPcHRpb25zLnNlc3Npb25JZEluZGV4TmFtZX0pLlxuICAgKiBPcHRpb25hbCBgc3ViamVjdElkYCBpcyBlbmZvcmNlZCBvbiBlYWNoIGJhc2UtdGFibGUgdXBkYXRlIGNvbmRpdGlvbi5cbiAgICpcbiAgICogQHBhcmFtIHBhcmFtcyAtIFNlc3Npb24gaWQsIG9wdGlvbmFsIHN1YmplY3QgZmlsdGVyLCBhbmQgb3B0aW9uYWwgY2xvY2suXG4gICAqIEByZXR1cm5zIENvdW50IG9mIHJvd3MgdXBkYXRlZCB3aXRoIGByZXZva2VkQXRgLlxuICAgKi9cbiAgcmV2b2tlU2Vzc2lvbihwYXJhbXM6IFJldm9rZVNlc3Npb25QYXJhbXMpOiBQcm9taXNlPFJldm9rZVNlc3Npb25SZXN1bHQ+O1xuXG4gIC8qKlxuICAgKiBTZXRzIGByZXZva2VkQXRgIG9uIGV2ZXJ5IHJlZnJlc2ggdG9rZW4gcm93IGZvciB0aGUgZ2l2ZW4gc3ViamVjdCAobG9nb3V0IGFsbCBkZXZpY2VzLCBwYXNzd29yZCBjaGFuZ2UsIGFjY291bnQgc3VzcGVuc2lvbikuXG4gICAqXG4gICAqIFJlcXVpcmVzIGEgRHluYW1vREIgR1NJIHdob3NlIHBhcnRpdGlvbiBrZXkgaXMgYHN1YmplY3RJZGAgKHNlZSB7QGxpbmsgU3RvcmVPcHRpb25zLnN1YmplY3RJZEluZGV4TmFtZX0pLlxuICAgKlxuICAgKiBAcGFyYW0gcGFyYW1zIC0gU3ViamVjdCBpZCBhbmQgb3B0aW9uYWwgY2xvY2suXG4gICAqIEByZXR1cm5zIENvdW50IG9mIHJvd3MgdXBkYXRlZCB3aXRoIGByZXZva2VkQXRgLlxuICAgKi9cbiAgcmV2b2tlU3ViamVjdChwYXJhbXM6IFJldm9rZVN1YmplY3RQYXJhbXMpOiBQcm9taXNlPFJldm9rZVN1YmplY3RSZXN1bHQ+O1xufVxuIl19
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dynamodb-refresh-token-provider",
3
- "description": "TypeScript library that stores **opaque refresh tokens** in **Amazon DynamoDB** using AWS SDK for JavaScript v3. Tokens are persisted under a hash of the plaintext value; **issue**, **rotate** (with reuse detection via a transactional write), **revoke** (idempotent), and **revokeSession** (OAuth 2.0 BCP family revocation) are supported.",
3
+ "description": "TypeScript library that stores **opaque refresh tokens** in **Amazon DynamoDB** using AWS SDK for JavaScript v3. Tokens are persisted under a hash of the plaintext value; **issue**, **rotate** (with reuse detection via a transactional write), **revoke** (idempotent), **revokeSession** (OAuth 2.0 BCP family revocation), and **revokeSubject** (subject-wide revocation across all sessions) are supported.",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/gammarers-aws-sdk-modules/dynamodb-refresh-token-provider.git"
@@ -42,9 +42,9 @@
42
42
  "eslint": "^9",
43
43
  "eslint-import-resolver-typescript": "^4.4.5",
44
44
  "eslint-plugin-import": "^2.32.0",
45
- "jest": "^30.4.2",
45
+ "jest": "^30.5.0",
46
46
  "jest-junit": "^17",
47
- "projen": "^0.103.1",
47
+ "projen": "^0.103.11",
48
48
  "ts-jest": "^29.4.12",
49
49
  "ts-node": "^10.9.2",
50
50
  "typescript": "6.0.x"
@@ -67,7 +67,7 @@
67
67
  "publishConfig": {
68
68
  "access": "public"
69
69
  },
70
- "version": "0.4.6",
70
+ "version": "0.5.1",
71
71
  "jest": {
72
72
  "coverageProvider": "v8",
73
73
  "testMatch": [