@decaf-ts/core 0.5.1 → 0.5.2
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/LICENSE.md +21 -157
- package/README.md +652 -15
- package/dist/core.cjs +2110 -132
- package/dist/core.esm.cjs +2111 -133
- package/lib/esm/identity/decorators.d.ts +52 -7
- package/lib/esm/identity/decorators.js +53 -8
- package/lib/esm/identity/utils.d.ts +19 -0
- package/lib/esm/identity/utils.js +20 -1
- package/lib/esm/index.d.ts +9 -2
- package/lib/esm/index.js +10 -3
- package/lib/esm/interfaces/ErrorParser.d.ts +12 -0
- package/lib/esm/interfaces/ErrorParser.js +1 -1
- package/lib/esm/interfaces/Executor.d.ts +13 -0
- package/lib/esm/interfaces/Executor.js +1 -1
- package/lib/esm/interfaces/Observable.d.ts +27 -0
- package/lib/esm/interfaces/Observable.js +1 -1
- package/lib/esm/interfaces/Observer.d.ts +12 -0
- package/lib/esm/interfaces/Observer.js +1 -1
- package/lib/esm/interfaces/Paginatable.d.ts +15 -0
- package/lib/esm/interfaces/Paginatable.js +1 -1
- package/lib/esm/interfaces/Queriable.d.ts +34 -9
- package/lib/esm/interfaces/Queriable.js +1 -1
- package/lib/esm/interfaces/RawExecutor.d.ts +14 -0
- package/lib/esm/interfaces/RawExecutor.js +1 -1
- package/lib/esm/interfaces/SequenceOptions.d.ts +52 -0
- package/lib/esm/interfaces/SequenceOptions.js +19 -1
- package/lib/esm/model/BaseModel.d.ts +31 -0
- package/lib/esm/model/BaseModel.js +24 -1
- package/lib/esm/model/construction.d.ts +433 -0
- package/lib/esm/model/construction.js +441 -2
- package/lib/esm/model/decorators.d.ts +159 -29
- package/lib/esm/model/decorators.js +160 -30
- package/lib/esm/model/types.d.ts +9 -0
- package/lib/esm/model/types.js +1 -1
- package/lib/esm/persistence/Adapter.d.ts +358 -17
- package/lib/esm/persistence/Adapter.js +287 -19
- package/lib/esm/persistence/Dispatch.d.ts +114 -1
- package/lib/esm/persistence/Dispatch.js +102 -4
- package/lib/esm/persistence/ObserverHandler.d.ts +95 -0
- package/lib/esm/persistence/ObserverHandler.js +96 -1
- package/lib/esm/persistence/Sequence.d.ts +89 -0
- package/lib/esm/persistence/Sequence.js +70 -1
- package/lib/esm/persistence/constants.d.ts +22 -0
- package/lib/esm/persistence/constants.js +23 -1
- package/lib/esm/persistence/decorators.d.ts +10 -0
- package/lib/esm/persistence/decorators.js +11 -1
- package/lib/esm/persistence/errors.d.ts +23 -0
- package/lib/esm/persistence/errors.js +24 -1
- package/lib/esm/persistence/types.d.ts +18 -0
- package/lib/esm/persistence/types.js +1 -1
- package/lib/esm/query/Condition.d.ts +78 -31
- package/lib/esm/query/Condition.js +132 -53
- package/lib/esm/query/Paginator.d.ts +56 -0
- package/lib/esm/query/Paginator.js +57 -1
- package/lib/esm/query/Statement.d.ts +51 -0
- package/lib/esm/query/Statement.js +52 -1
- package/lib/esm/query/constants.d.ts +25 -0
- package/lib/esm/query/constants.js +26 -1
- package/lib/esm/query/errors.d.ts +14 -0
- package/lib/esm/query/errors.js +15 -1
- package/lib/esm/query/options.d.ts +21 -3
- package/lib/esm/query/options.js +1 -1
- package/lib/esm/query/selectors.d.ts +26 -0
- package/lib/esm/query/selectors.js +1 -1
- package/lib/esm/ram/RamAdapter.d.ts +311 -0
- package/lib/esm/ram/RamAdapter.js +312 -1
- package/lib/esm/ram/RamContext.d.ts +16 -1
- package/lib/esm/ram/RamContext.js +18 -3
- package/lib/esm/ram/RamPaginator.d.ts +43 -0
- package/lib/esm/ram/RamPaginator.js +54 -2
- package/lib/esm/ram/RamSequence.d.ts +61 -0
- package/lib/esm/ram/RamSequence.js +63 -2
- package/lib/esm/ram/RamStatement.d.ts +74 -0
- package/lib/esm/ram/RamStatement.js +75 -1
- package/lib/esm/ram/constants.d.ts +8 -0
- package/lib/esm/ram/constants.js +9 -1
- package/lib/esm/ram/handlers.d.ts +19 -0
- package/lib/esm/ram/handlers.js +20 -1
- package/lib/esm/ram/model/RamSequence.d.ts +25 -0
- package/lib/esm/ram/model/RamSequence.js +19 -1
- package/lib/esm/ram/types.d.ts +42 -0
- package/lib/esm/ram/types.js +1 -1
- package/lib/esm/repository/Repository.d.ts +363 -8
- package/lib/esm/repository/Repository.js +361 -16
- package/lib/esm/repository/constants.d.ts +25 -0
- package/lib/esm/repository/constants.js +26 -1
- package/lib/esm/repository/decorators.d.ts +27 -0
- package/lib/esm/repository/decorators.js +28 -1
- package/lib/esm/repository/errors.d.ts +12 -5
- package/lib/esm/repository/errors.js +13 -6
- package/lib/esm/repository/injectables.d.ts +18 -0
- package/lib/esm/repository/injectables.js +19 -1
- package/lib/esm/repository/types.d.ts +15 -0
- package/lib/esm/repository/types.js +1 -1
- package/lib/esm/repository/utils.d.ts +11 -0
- package/lib/esm/repository/utils.js +12 -1
- package/lib/esm/utils/decorators.d.ts +8 -0
- package/lib/esm/utils/decorators.js +9 -1
- package/lib/esm/utils/errors.d.ts +46 -0
- package/lib/esm/utils/errors.js +47 -1
- package/lib/identity/decorators.cjs +53 -8
- package/lib/identity/decorators.d.ts +52 -7
- package/lib/identity/utils.cjs +20 -1
- package/lib/identity/utils.d.ts +19 -0
- package/lib/index.cjs +10 -3
- package/lib/index.d.ts +9 -2
- package/lib/interfaces/ErrorParser.cjs +1 -1
- package/lib/interfaces/ErrorParser.d.ts +12 -0
- package/lib/interfaces/Executor.cjs +1 -1
- package/lib/interfaces/Executor.d.ts +13 -0
- package/lib/interfaces/Observable.cjs +1 -1
- package/lib/interfaces/Observable.d.ts +27 -0
- package/lib/interfaces/Observer.cjs +1 -1
- package/lib/interfaces/Observer.d.ts +12 -0
- package/lib/interfaces/Paginatable.cjs +1 -1
- package/lib/interfaces/Paginatable.d.ts +15 -0
- package/lib/interfaces/Queriable.cjs +1 -1
- package/lib/interfaces/Queriable.d.ts +34 -9
- package/lib/interfaces/RawExecutor.cjs +1 -1
- package/lib/interfaces/RawExecutor.d.ts +14 -0
- package/lib/interfaces/SequenceOptions.cjs +19 -1
- package/lib/interfaces/SequenceOptions.d.ts +52 -0
- package/lib/model/BaseModel.cjs +24 -1
- package/lib/model/BaseModel.d.ts +31 -0
- package/lib/model/construction.cjs +441 -2
- package/lib/model/construction.d.ts +433 -0
- package/lib/model/decorators.cjs +160 -30
- package/lib/model/decorators.d.ts +159 -29
- package/lib/model/types.cjs +1 -1
- package/lib/model/types.d.ts +9 -0
- package/lib/persistence/Adapter.cjs +287 -19
- package/lib/persistence/Adapter.d.ts +358 -17
- package/lib/persistence/Dispatch.cjs +102 -4
- package/lib/persistence/Dispatch.d.ts +114 -1
- package/lib/persistence/ObserverHandler.cjs +96 -1
- package/lib/persistence/ObserverHandler.d.ts +95 -0
- package/lib/persistence/Sequence.cjs +70 -1
- package/lib/persistence/Sequence.d.ts +89 -0
- package/lib/persistence/constants.cjs +23 -1
- package/lib/persistence/constants.d.ts +22 -0
- package/lib/persistence/decorators.cjs +11 -1
- package/lib/persistence/decorators.d.ts +10 -0
- package/lib/persistence/errors.cjs +24 -1
- package/lib/persistence/errors.d.ts +23 -0
- package/lib/persistence/types.cjs +1 -1
- package/lib/persistence/types.d.ts +18 -0
- package/lib/query/Condition.cjs +132 -53
- package/lib/query/Condition.d.ts +78 -31
- package/lib/query/Paginator.cjs +57 -1
- package/lib/query/Paginator.d.ts +56 -0
- package/lib/query/Statement.cjs +52 -1
- package/lib/query/Statement.d.ts +51 -0
- package/lib/query/constants.cjs +26 -1
- package/lib/query/constants.d.ts +25 -0
- package/lib/query/errors.cjs +15 -1
- package/lib/query/errors.d.ts +14 -0
- package/lib/query/options.cjs +1 -1
- package/lib/query/options.d.ts +21 -3
- package/lib/query/selectors.cjs +1 -1
- package/lib/query/selectors.d.ts +26 -0
- package/lib/ram/RamAdapter.cjs +312 -1
- package/lib/ram/RamAdapter.d.ts +311 -0
- package/lib/ram/RamContext.cjs +18 -3
- package/lib/ram/RamContext.d.ts +16 -1
- package/lib/ram/RamPaginator.cjs +54 -2
- package/lib/ram/RamPaginator.d.ts +43 -0
- package/lib/ram/RamSequence.cjs +63 -2
- package/lib/ram/RamSequence.d.ts +61 -0
- package/lib/ram/RamStatement.cjs +75 -1
- package/lib/ram/RamStatement.d.ts +74 -0
- package/lib/ram/constants.cjs +9 -1
- package/lib/ram/constants.d.ts +8 -0
- package/lib/ram/handlers.cjs +20 -1
- package/lib/ram/handlers.d.ts +19 -0
- package/lib/ram/model/RamSequence.cjs +19 -1
- package/lib/ram/model/RamSequence.d.ts +25 -0
- package/lib/ram/types.cjs +1 -1
- package/lib/ram/types.d.ts +42 -0
- package/lib/repository/Repository.cjs +360 -15
- package/lib/repository/Repository.d.ts +363 -8
- package/lib/repository/constants.cjs +26 -1
- package/lib/repository/constants.d.ts +25 -0
- package/lib/repository/decorators.cjs +28 -1
- package/lib/repository/decorators.d.ts +27 -0
- package/lib/repository/errors.cjs +13 -6
- package/lib/repository/errors.d.ts +12 -5
- package/lib/repository/injectables.cjs +19 -1
- package/lib/repository/injectables.d.ts +18 -0
- package/lib/repository/types.cjs +1 -1
- package/lib/repository/types.d.ts +15 -0
- package/lib/repository/utils.cjs +12 -1
- package/lib/repository/utils.d.ts +11 -0
- package/lib/utils/decorators.cjs +9 -1
- package/lib/utils/decorators.d.ts +8 -0
- package/lib/utils/errors.cjs +47 -1
- package/lib/utils/errors.d.ts +46 -0
- package/package.json +5 -5
@@ -16,6 +16,47 @@ const Repository_1 = require("./../repository/Repository.cjs");
|
|
16
16
|
const db_decorators_1 = require("@decaf-ts/db-decorators");
|
17
17
|
const constants_1 = require("./../persistence/constants.cjs");
|
18
18
|
const constants_2 = require("./../repository/constants.cjs");
|
19
|
+
/**
|
20
|
+
* @description Creates or updates a model instance
|
21
|
+
* @summary Determines whether to create a new model or update an existing one based on the presence of a primary key
|
22
|
+
* @template M - The model type extending Model
|
23
|
+
* @template F - The repository flags type
|
24
|
+
* @param {M} model - The model instance to create or update
|
25
|
+
* @param {Context<F>} context - The context for the operation
|
26
|
+
* @param {Repo<M, F, Context<F>>} [repository] - Optional repository to use for the operation
|
27
|
+
* @return {Promise<M>} A promise that resolves to the created or updated model
|
28
|
+
* @function createOrUpdate
|
29
|
+
* @memberOf module:core
|
30
|
+
* @mermaid
|
31
|
+
* sequenceDiagram
|
32
|
+
* participant Caller
|
33
|
+
* participant createOrUpdate
|
34
|
+
* participant Repository
|
35
|
+
* participant Model
|
36
|
+
*
|
37
|
+
* Caller->>createOrUpdate: model, context, repository?
|
38
|
+
* alt repository not provided
|
39
|
+
* createOrUpdate->>Model: get(model.constructor.name)
|
40
|
+
* Model-->>createOrUpdate: constructor
|
41
|
+
* createOrUpdate->>Repository: forModel(constructor)
|
42
|
+
* Repository-->>createOrUpdate: repository
|
43
|
+
* end
|
44
|
+
*
|
45
|
+
* alt primary key undefined
|
46
|
+
* createOrUpdate->>Repository: create(model, context)
|
47
|
+
* Repository-->>createOrUpdate: created model
|
48
|
+
* else primary key defined
|
49
|
+
* createOrUpdate->>Repository: update(model, context)
|
50
|
+
* alt update successful
|
51
|
+
* Repository-->>createOrUpdate: updated model
|
52
|
+
* else NotFoundError
|
53
|
+
* createOrUpdate->>Repository: create(model, context)
|
54
|
+
* Repository-->>createOrUpdate: created model
|
55
|
+
* end
|
56
|
+
* end
|
57
|
+
*
|
58
|
+
* createOrUpdate-->>Caller: model
|
59
|
+
*/
|
19
60
|
async function createOrUpdate(model, context, repository) {
|
20
61
|
if (!repository) {
|
21
62
|
const constructor = decorator_validation_1.Model.get(model.constructor.name);
|
@@ -36,6 +77,56 @@ async function createOrUpdate(model, context, repository) {
|
|
36
77
|
}
|
37
78
|
}
|
38
79
|
}
|
80
|
+
/**
|
81
|
+
* @description Handles one-to-one relationship creation
|
82
|
+
* @summary Processes a one-to-one relationship when creating a model, either by referencing an existing model or creating a new one
|
83
|
+
* @template M - The model type extending Model
|
84
|
+
* @template R - The repository type extending Repo<M, F, C>
|
85
|
+
* @template V - The relations metadata type extending RelationsMetadata
|
86
|
+
* @template F - The repository flags type
|
87
|
+
* @template C - The context type extending Context<F>
|
88
|
+
* @param {R} this - The repository instance
|
89
|
+
* @param {Context<F>} context - The context for the operation
|
90
|
+
* @param {V} data - The relations metadata
|
91
|
+
* @param {string} key - The property key of the relationship
|
92
|
+
* @param {M} model - The model instance
|
93
|
+
* @return {Promise<void>} A promise that resolves when the operation is complete
|
94
|
+
* @function oneToOneOnCreate
|
95
|
+
* @memberOf module:core
|
96
|
+
* @mermaid
|
97
|
+
* sequenceDiagram
|
98
|
+
* participant Caller
|
99
|
+
* participant oneToOneOnCreate
|
100
|
+
* participant repositoryFromTypeMetadata
|
101
|
+
* participant Model
|
102
|
+
* participant Repository
|
103
|
+
* participant cacheModelForPopulate
|
104
|
+
*
|
105
|
+
* Caller->>oneToOneOnCreate: this, context, data, key, model
|
106
|
+
* oneToOneOnCreate->>oneToOneOnCreate: check if propertyValue exists
|
107
|
+
*
|
108
|
+
* alt propertyValue is not an object
|
109
|
+
* oneToOneOnCreate->>repositoryFromTypeMetadata: model, key
|
110
|
+
* repositoryFromTypeMetadata-->>oneToOneOnCreate: innerRepo
|
111
|
+
* oneToOneOnCreate->>innerRepo: read(propertyValue)
|
112
|
+
* innerRepo-->>oneToOneOnCreate: read
|
113
|
+
* oneToOneOnCreate->>cacheModelForPopulate: context, model, key, propertyValue, read
|
114
|
+
* oneToOneOnCreate->>oneToOneOnCreate: set model[key] = propertyValue
|
115
|
+
* else propertyValue is an object
|
116
|
+
* oneToOneOnCreate->>Model: get(data.class)
|
117
|
+
* Model-->>oneToOneOnCreate: constructor
|
118
|
+
* oneToOneOnCreate->>Repository: forModel(constructor)
|
119
|
+
* Repository-->>oneToOneOnCreate: repo
|
120
|
+
* oneToOneOnCreate->>repo: create(propertyValue)
|
121
|
+
* repo-->>oneToOneOnCreate: created
|
122
|
+
* oneToOneOnCreate->>findPrimaryKey: created
|
123
|
+
* findPrimaryKey-->>oneToOneOnCreate: pk
|
124
|
+
* oneToOneOnCreate->>cacheModelForPopulate: context, model, key, created[pk], created
|
125
|
+
* oneToOneOnCreate->>oneToOneOnCreate: set model[key] = created[pk]
|
126
|
+
* end
|
127
|
+
*
|
128
|
+
* oneToOneOnCreate-->>Caller: void
|
129
|
+
*/
|
39
130
|
async function oneToOneOnCreate(context, data, key, model) {
|
40
131
|
const propertyValue = model[key];
|
41
132
|
if (!propertyValue)
|
@@ -56,6 +147,53 @@ async function oneToOneOnCreate(context, data, key, model) {
|
|
56
147
|
await cacheModelForPopulate(context, model, key, created[pk], created);
|
57
148
|
model[key] = created[pk];
|
58
149
|
}
|
150
|
+
/**
|
151
|
+
* @description Handles one-to-one relationship updates
|
152
|
+
* @summary Processes a one-to-one relationship when updating a model, either by referencing an existing model or updating the related model
|
153
|
+
* @template M - The model type extending Model
|
154
|
+
* @template R - The repository type extending Repo<M, F, C>
|
155
|
+
* @template V - The relations metadata type extending RelationsMetadata
|
156
|
+
* @template F - The repository flags type
|
157
|
+
* @template C - The context type extending Context<F>
|
158
|
+
* @param {R} this - The repository instance
|
159
|
+
* @param {Context<F>} context - The context for the operation
|
160
|
+
* @param {V} data - The relations metadata
|
161
|
+
* @param key - The property key of the relationship
|
162
|
+
* @param {M} model - The model instance
|
163
|
+
* @return {Promise<void>} A promise that resolves when the operation is complete
|
164
|
+
* @function oneToOneOnUpdate
|
165
|
+
* @memberOf module:core
|
166
|
+
* @mermaid
|
167
|
+
* sequenceDiagram
|
168
|
+
* participant Caller
|
169
|
+
* participant oneToOneOnUpdate
|
170
|
+
* participant repositoryFromTypeMetadata
|
171
|
+
* participant createOrUpdate
|
172
|
+
* participant findPrimaryKey
|
173
|
+
* participant cacheModelForPopulate
|
174
|
+
*
|
175
|
+
* Caller->>oneToOneOnUpdate: this, context, data, key, model
|
176
|
+
* oneToOneOnUpdate->>oneToOneOnUpdate: check if propertyValue exists
|
177
|
+
* oneToOneOnUpdate->>oneToOneOnUpdate: check if cascade.update is CASCADE
|
178
|
+
*
|
179
|
+
* alt propertyValue is not an object
|
180
|
+
* oneToOneOnUpdate->>repositoryFromTypeMetadata: model, key
|
181
|
+
* repositoryFromTypeMetadata-->>oneToOneOnUpdate: innerRepo
|
182
|
+
* oneToOneOnUpdate->>innerRepo: read(propertyValue)
|
183
|
+
* innerRepo-->>oneToOneOnUpdate: read
|
184
|
+
* oneToOneOnUpdate->>cacheModelForPopulate: context, model, key, propertyValue, read
|
185
|
+
* oneToOneOnUpdate->>oneToOneOnUpdate: set model[key] = propertyValue
|
186
|
+
* else propertyValue is an object
|
187
|
+
* oneToOneOnUpdate->>createOrUpdate: model[key], context
|
188
|
+
* createOrUpdate-->>oneToOneOnUpdate: updated
|
189
|
+
* oneToOneOnUpdate->>findPrimaryKey: updated
|
190
|
+
* findPrimaryKey-->>oneToOneOnUpdate: pk
|
191
|
+
* oneToOneOnUpdate->>cacheModelForPopulate: context, model, key, updated[pk], updated
|
192
|
+
* oneToOneOnUpdate->>oneToOneOnUpdate: set model[key] = updated[pk]
|
193
|
+
* end
|
194
|
+
*
|
195
|
+
* oneToOneOnUpdate-->>Caller: void
|
196
|
+
*/
|
59
197
|
async function oneToOneOnUpdate(context, data, key, model) {
|
60
198
|
const propertyValue = model[key];
|
61
199
|
if (!propertyValue)
|
@@ -74,6 +212,47 @@ async function oneToOneOnUpdate(context, data, key, model) {
|
|
74
212
|
await cacheModelForPopulate(context, model, key, updated[pk], updated);
|
75
213
|
model[key] = updated[pk];
|
76
214
|
}
|
215
|
+
/**
|
216
|
+
* @description Handles one-to-one relationship deletion
|
217
|
+
* @summary Processes a one-to-one relationship when deleting a model, deleting the related model if cascade is enabled
|
218
|
+
* @template M - The model type extending Model
|
219
|
+
* @template R - The repository type extending Repo<M, F, C>
|
220
|
+
* @template V - The relations metadata type extending RelationsMetadata
|
221
|
+
* @template F - The repository flags type
|
222
|
+
* @template C - The context type extending Context<F>
|
223
|
+
* @param {R} this - The repository instance
|
224
|
+
* @param {Context<F>} context - The context for the operation
|
225
|
+
* @param {V} data - The relations metadata
|
226
|
+
* @param key - The property key of the relationship
|
227
|
+
* @param {M} model - The model instance
|
228
|
+
* @return {Promise<void>} A promise that resolves when the operation is complete
|
229
|
+
* @function oneToOneOnDelete
|
230
|
+
* @memberOf module:core
|
231
|
+
* @mermaid
|
232
|
+
* sequenceDiagram
|
233
|
+
* participant Caller
|
234
|
+
* participant oneToOneOnDelete
|
235
|
+
* participant repositoryFromTypeMetadata
|
236
|
+
* participant cacheModelForPopulate
|
237
|
+
*
|
238
|
+
* Caller->>oneToOneOnDelete: this, context, data, key, model
|
239
|
+
* oneToOneOnDelete->>oneToOneOnDelete: check if propertyValue exists
|
240
|
+
* oneToOneOnDelete->>oneToOneOnDelete: check if cascade.update is CASCADE
|
241
|
+
*
|
242
|
+
* oneToOneOnDelete->>repositoryFromTypeMetadata: model, key
|
243
|
+
* repositoryFromTypeMetadata-->>oneToOneOnDelete: innerRepo
|
244
|
+
*
|
245
|
+
* alt propertyValue is not a Model instance
|
246
|
+
* oneToOneOnDelete->>innerRepo: delete(model[key], context)
|
247
|
+
* innerRepo-->>oneToOneOnDelete: deleted
|
248
|
+
* else propertyValue is a Model instance
|
249
|
+
* oneToOneOnDelete->>innerRepo: delete(model[key][innerRepo.pk], context)
|
250
|
+
* innerRepo-->>oneToOneOnDelete: deleted
|
251
|
+
* end
|
252
|
+
*
|
253
|
+
* oneToOneOnDelete->>cacheModelForPopulate: context, model, key, deleted[innerRepo.pk], deleted
|
254
|
+
* oneToOneOnDelete-->>Caller: void
|
255
|
+
*/
|
77
256
|
async function oneToOneOnDelete(context, data, key, model) {
|
78
257
|
const propertyValue = model[key];
|
79
258
|
if (!propertyValue)
|
@@ -88,6 +267,60 @@ async function oneToOneOnDelete(context, data, key, model) {
|
|
88
267
|
deleted = await innerRepo.delete(model[key][innerRepo.pk], context);
|
89
268
|
await cacheModelForPopulate(context, model, key, deleted[innerRepo.pk], deleted);
|
90
269
|
}
|
270
|
+
/**
|
271
|
+
* @description Handles one-to-many relationship creation
|
272
|
+
* @summary Processes a one-to-many relationship when creating a model, either by referencing existing models or creating new ones
|
273
|
+
* @template M - The model type extending Model
|
274
|
+
* @template R - The repository type extending Repo<M, F, C>
|
275
|
+
* @template V - The relations metadata type extending RelationsMetadata
|
276
|
+
* @template F - The repository flags type
|
277
|
+
* @template C - The context type extending Context<F>
|
278
|
+
* @param {R} this - The repository instance
|
279
|
+
* @param {Context<F>} context - The context for the operation
|
280
|
+
* @param {V} data - The relations metadata
|
281
|
+
* @param key - The property key of the relationship
|
282
|
+
* @param {M} model - The model instance
|
283
|
+
* @return {Promise<void>} A promise that resolves when the operation is complete
|
284
|
+
* @function oneToManyOnCreate
|
285
|
+
* @memberOf module:core
|
286
|
+
* @mermaid
|
287
|
+
* sequenceDiagram
|
288
|
+
* participant Caller
|
289
|
+
* participant oneToManyOnCreate
|
290
|
+
* participant repositoryFromTypeMetadata
|
291
|
+
* participant createOrUpdate
|
292
|
+
* participant findPrimaryKey
|
293
|
+
* participant cacheModelForPopulate
|
294
|
+
*
|
295
|
+
* Caller->>oneToManyOnCreate: this, context, data, key, model
|
296
|
+
* oneToManyOnCreate->>oneToManyOnCreate: check if propertyValues exists and has length
|
297
|
+
* oneToManyOnCreate->>oneToManyOnCreate: check if all elements have same type
|
298
|
+
* oneToManyOnCreate->>oneToManyOnCreate: create uniqueValues set
|
299
|
+
*
|
300
|
+
* alt arrayType is not "object"
|
301
|
+
* oneToManyOnCreate->>repositoryFromTypeMetadata: model, key
|
302
|
+
* repositoryFromTypeMetadata-->>oneToManyOnCreate: repo
|
303
|
+
* loop for each id in uniqueValues
|
304
|
+
* oneToManyOnCreate->>repo: read(id)
|
305
|
+
* repo-->>oneToManyOnCreate: read
|
306
|
+
* oneToManyOnCreate->>cacheModelForPopulate: context, model, key, id, read
|
307
|
+
* end
|
308
|
+
* oneToManyOnCreate->>oneToManyOnCreate: set model[key] = [...uniqueValues]
|
309
|
+
* else arrayType is "object"
|
310
|
+
* oneToManyOnCreate->>findPrimaryKey: propertyValues[0]
|
311
|
+
* findPrimaryKey-->>oneToManyOnCreate: pkName
|
312
|
+
* oneToManyOnCreate->>oneToManyOnCreate: create result set
|
313
|
+
* loop for each m in propertyValues
|
314
|
+
* oneToManyOnCreate->>createOrUpdate: m, context
|
315
|
+
* createOrUpdate-->>oneToManyOnCreate: record
|
316
|
+
* oneToManyOnCreate->>cacheModelForPopulate: context, model, key, record[pkName], record
|
317
|
+
* oneToManyOnCreate->>oneToManyOnCreate: add record[pkName] to result
|
318
|
+
* end
|
319
|
+
* oneToManyOnCreate->>oneToManyOnCreate: set model[key] = [...result]
|
320
|
+
* end
|
321
|
+
*
|
322
|
+
* oneToManyOnCreate-->>Caller: void
|
323
|
+
*/
|
91
324
|
async function oneToManyOnCreate(context, data, key, model) {
|
92
325
|
const propertyValues = model[key];
|
93
326
|
if (!propertyValues || !propertyValues.length)
|
@@ -114,6 +347,38 @@ async function oneToManyOnCreate(context, data, key, model) {
|
|
114
347
|
}
|
115
348
|
model[key] = [...result];
|
116
349
|
}
|
350
|
+
/**
|
351
|
+
* @description Handles one-to-many relationship updates
|
352
|
+
* @summary Processes a one-to-many relationship when updating a model, delegating to oneToManyOnCreate if cascade update is enabled
|
353
|
+
* @template M - The model type extending Model
|
354
|
+
* @template R - The repository type extending Repo<M, F, C>
|
355
|
+
* @template V - The relations metadata type extending RelationsMetadata
|
356
|
+
* @template F - The repository flags type
|
357
|
+
* @template C - The context type extending Context<F>
|
358
|
+
* @param {R} this - The repository instance
|
359
|
+
* @param {Context<F>} context - The context for the operation
|
360
|
+
* @param {V} data - The relations metadata
|
361
|
+
* @param key - The property key of the relationship
|
362
|
+
* @param {M} model - The model instance
|
363
|
+
* @return {Promise<void>} A promise that resolves when the operation is complete
|
364
|
+
* @function oneToManyOnUpdate
|
365
|
+
* @memberOf module:core
|
366
|
+
* @mermaid
|
367
|
+
* sequenceDiagram
|
368
|
+
* participant Caller
|
369
|
+
* participant oneToManyOnUpdate
|
370
|
+
* participant oneToManyOnCreate
|
371
|
+
*
|
372
|
+
* Caller->>oneToManyOnUpdate: this, context, data, key, model
|
373
|
+
* oneToManyOnUpdate->>oneToManyOnUpdate: check if cascade.update is CASCADE
|
374
|
+
*
|
375
|
+
* alt cascade.update is CASCADE
|
376
|
+
* oneToManyOnUpdate->>oneToManyOnCreate: apply(this, [context, data, key, model])
|
377
|
+
* oneToManyOnCreate-->>oneToManyOnUpdate: void
|
378
|
+
* end
|
379
|
+
*
|
380
|
+
* oneToManyOnUpdate-->>Caller: void
|
381
|
+
*/
|
117
382
|
async function oneToManyOnUpdate(context, data, key, model) {
|
118
383
|
const { cascade } = data;
|
119
384
|
if (cascade.update !== constants_2.Cascade.CASCADE)
|
@@ -125,6 +390,54 @@ async function oneToManyOnUpdate(context, data, key, model) {
|
|
125
390
|
model,
|
126
391
|
]);
|
127
392
|
}
|
393
|
+
/**
|
394
|
+
* @description Handles one-to-many relationship deletion
|
395
|
+
* @summary Processes a one-to-many relationship when deleting a model, deleting all related models if cascade delete is enabled
|
396
|
+
* @template M - The model type extending Model
|
397
|
+
* @template R - The repository type extending Repo<M, F, C>
|
398
|
+
* @template V - The relations metadata type extending RelationsMetadata
|
399
|
+
* @template F - The repository flags type
|
400
|
+
* @template C - The context type extending Context<F>
|
401
|
+
* @param {R} this - The repository instance
|
402
|
+
* @param {Context<F>} context - The context for the operation
|
403
|
+
* @param {V} data - The relations metadata
|
404
|
+
* @param key - The property key of the relationship
|
405
|
+
* @param {M} model - The model instance
|
406
|
+
* @return {Promise<void>} A promise that resolves when the operation is complete
|
407
|
+
* @function oneToManyOnDelete
|
408
|
+
* @memberOf module:core
|
409
|
+
* @mermaid
|
410
|
+
* sequenceDiagram
|
411
|
+
* participant Caller
|
412
|
+
* participant oneToManyOnDelete
|
413
|
+
* participant Repository
|
414
|
+
* participant repositoryFromTypeMetadata
|
415
|
+
* participant cacheModelForPopulate
|
416
|
+
*
|
417
|
+
* Caller->>oneToManyOnDelete: this, context, data, key, model
|
418
|
+
* oneToManyOnDelete->>oneToManyOnDelete: check if cascade.delete is CASCADE
|
419
|
+
* oneToManyOnDelete->>oneToManyOnDelete: check if values exists and has length
|
420
|
+
* oneToManyOnDelete->>oneToManyOnDelete: check if all elements have same type
|
421
|
+
*
|
422
|
+
* alt isInstantiated (arrayType is "object")
|
423
|
+
* oneToManyOnDelete->>Repository: forModel(values[0])
|
424
|
+
* Repository-->>oneToManyOnDelete: repo
|
425
|
+
* else not instantiated
|
426
|
+
* oneToManyOnDelete->>repositoryFromTypeMetadata: model, key
|
427
|
+
* repositoryFromTypeMetadata-->>oneToManyOnDelete: repo
|
428
|
+
* end
|
429
|
+
*
|
430
|
+
* oneToManyOnDelete->>oneToManyOnDelete: create uniqueValues set
|
431
|
+
*
|
432
|
+
* loop for each id in uniqueValues
|
433
|
+
* oneToManyOnDelete->>repo: delete(id, context)
|
434
|
+
* repo-->>oneToManyOnDelete: deleted
|
435
|
+
* oneToManyOnDelete->>cacheModelForPopulate: context, model, key, id, deleted
|
436
|
+
* end
|
437
|
+
*
|
438
|
+
* oneToManyOnDelete->>oneToManyOnDelete: set model[key] = [...uniqueValues]
|
439
|
+
* oneToManyOnDelete-->>Caller: void
|
440
|
+
*/
|
128
441
|
async function oneToManyOnDelete(context, data, key, model) {
|
129
442
|
if (data.cascade.delete !== constants_2.Cascade.CASCADE)
|
130
443
|
return;
|
@@ -137,7 +450,7 @@ async function oneToManyOnDelete(context, data, key, model) {
|
|
137
450
|
throw new db_decorators_1.InternalError(`Invalid operation. All elements of property ${key} must match the same type.`);
|
138
451
|
const isInstantiated = arrayType === "object";
|
139
452
|
const repo = isInstantiated
|
140
|
-
? Repository_1.Repository.forModel(values[0])
|
453
|
+
? Repository_1.Repository.forModel(values[0], this.adapter.alias)
|
141
454
|
: repositoryFromTypeMetadata(model, key);
|
142
455
|
const uniqueValues = new Set([
|
143
456
|
...(isInstantiated
|
@@ -150,13 +463,91 @@ async function oneToManyOnDelete(context, data, key, model) {
|
|
150
463
|
}
|
151
464
|
model[key] = [...uniqueValues];
|
152
465
|
}
|
466
|
+
/**
|
467
|
+
* @description Generates a key for caching populated model relationships
|
468
|
+
* @summary Creates a unique key for storing and retrieving populated model relationships in the cache
|
469
|
+
* @param {string} tableName - The name of the table or model
|
470
|
+
* @param {string} fieldName - The name of the field or property
|
471
|
+
* @param {string|number} id - The identifier of the related model
|
472
|
+
* @return {string} A dot-separated string that uniquely identifies the relationship
|
473
|
+
* @function getPopulateKey
|
474
|
+
* @memberOf module:core
|
475
|
+
*/
|
153
476
|
function getPopulateKey(tableName, fieldName, id) {
|
154
477
|
return [constants_1.PersistenceKeys.POPULATE, tableName, fieldName, id].join(".");
|
155
478
|
}
|
479
|
+
/**
|
480
|
+
* @description Caches a model for later population
|
481
|
+
* @summary Stores a model in the context cache for efficient retrieval during relationship population
|
482
|
+
* @template M - The model type extending Model
|
483
|
+
* @template F - The repository flags type
|
484
|
+
* @param {Context<F>} context - The context for the operation
|
485
|
+
* @param {M} parentModel - The parent model that contains the relationship
|
486
|
+
* @param propertyKey - The property key of the relationship
|
487
|
+
* @param {string | number} pkValue - The primary key value of the related model
|
488
|
+
* @param {any} cacheValue - The model instance to cache
|
489
|
+
* @return {Promise<any>} A promise that resolves with the result of the cache operation
|
490
|
+
* @function cacheModelForPopulate
|
491
|
+
* @memberOf module:core
|
492
|
+
*/
|
156
493
|
async function cacheModelForPopulate(context, parentModel, propertyKey, pkValue, cacheValue) {
|
157
494
|
const cacheKey = getPopulateKey(parentModel.constructor.name, propertyKey, pkValue);
|
158
495
|
return context.accumulate({ [cacheKey]: cacheValue });
|
159
496
|
}
|
497
|
+
/**
|
498
|
+
* @description Populates a model's relationship
|
499
|
+
* @summary Retrieves and attaches related models to a model's relationship property
|
500
|
+
* @template M - The model type extending Model
|
501
|
+
* @template R - The repository type extending Repo<M, F, C>
|
502
|
+
* @template V - The relations metadata type extending RelationsMetadata
|
503
|
+
* @template F - The repository flags type
|
504
|
+
* @template C - The context type extending Context<F>
|
505
|
+
* @param {R} this - The repository instance
|
506
|
+
* @param {Context<F>} context - The context for the operation
|
507
|
+
* @param {V} data - The relations metadata
|
508
|
+
* @param key - The property key of the relationship
|
509
|
+
* @param {M} model - The model instance
|
510
|
+
* @return {Promise<void>} A promise that resolves when the operation is complete
|
511
|
+
* @function populate
|
512
|
+
* @memberOf module:core
|
513
|
+
* @mermaid
|
514
|
+
* sequenceDiagram
|
515
|
+
* participant Caller
|
516
|
+
* participant populate
|
517
|
+
* participant fetchPopulateValues
|
518
|
+
* participant getPopulateKey
|
519
|
+
* participant Context
|
520
|
+
* participant repositoryFromTypeMetadata
|
521
|
+
*
|
522
|
+
* Caller->>populate: this, context, data, key, model
|
523
|
+
* populate->>populate: check if data.populate is true
|
524
|
+
* populate->>populate: get nested value and check if it exists
|
525
|
+
*
|
526
|
+
* populate->>fetchPopulateValues: context, model, key, isArr ? nested : [nested]
|
527
|
+
*
|
528
|
+
* fetchPopulateValues->>fetchPopulateValues: initialize variables
|
529
|
+
*
|
530
|
+
* loop for each proKeyValue in propKeyValues
|
531
|
+
* fetchPopulateValues->>getPopulateKey: model.constructor.name, propName, proKeyValue
|
532
|
+
* getPopulateKey-->>fetchPopulateValues: cacheKey
|
533
|
+
*
|
534
|
+
* alt try to get from cache
|
535
|
+
* fetchPopulateValues->>Context: get(cacheKey)
|
536
|
+
* Context-->>fetchPopulateValues: val
|
537
|
+
* else catch error
|
538
|
+
* fetchPopulateValues->>repositoryFromTypeMetadata: model, propName
|
539
|
+
* repositoryFromTypeMetadata-->>fetchPopulateValues: repo
|
540
|
+
* fetchPopulateValues->>repo: read(proKeyValue)
|
541
|
+
* repo-->>fetchPopulateValues: val
|
542
|
+
* end
|
543
|
+
*
|
544
|
+
* fetchPopulateValues->>fetchPopulateValues: add val to results
|
545
|
+
* end
|
546
|
+
*
|
547
|
+
* fetchPopulateValues-->>populate: results
|
548
|
+
* populate->>populate: set model[key] = isArr ? res : res[0]
|
549
|
+
* populate-->>Caller: void
|
550
|
+
*/
|
160
551
|
async function populate(context, data, key, model) {
|
161
552
|
if (!data.populate)
|
162
553
|
return;
|
@@ -187,6 +578,12 @@ async function populate(context, data, key, model) {
|
|
187
578
|
const res = await fetchPopulateValues(context, model, key, isArr ? nested : [nested]);
|
188
579
|
model[key] = isArr ? res : res[0];
|
189
580
|
}
|
581
|
+
/**
|
582
|
+
* @description List of common JavaScript types
|
583
|
+
* @summary An array of strings representing common JavaScript types that are not custom model types
|
584
|
+
* @const commomTypes
|
585
|
+
* @memberOf module:core
|
586
|
+
*/
|
190
587
|
const commomTypes = [
|
191
588
|
"array",
|
192
589
|
"string",
|
@@ -199,6 +596,48 @@ const commomTypes = [
|
|
199
596
|
"null",
|
200
597
|
"bigint",
|
201
598
|
];
|
599
|
+
/**
|
600
|
+
* @description Retrieves a repository for a model property based on its type metadata
|
601
|
+
* @summary Examines a model property's type metadata to determine the appropriate repository for related models
|
602
|
+
* @template M - The model type extending Model
|
603
|
+
* @param {any} model - The model instance containing the property
|
604
|
+
* @param propertyKey - The property key to examine
|
605
|
+
* @return {Repo<M>} A repository for the model type associated with the property
|
606
|
+
* @function repositoryFromTypeMetadata
|
607
|
+
* @memberOf module:core
|
608
|
+
* @mermaid
|
609
|
+
* sequenceDiagram
|
610
|
+
* participant Caller
|
611
|
+
* participant repositoryFromTypeMetadata
|
612
|
+
* participant Reflect
|
613
|
+
* participant Validation
|
614
|
+
* participant Model
|
615
|
+
* participant Repository
|
616
|
+
*
|
617
|
+
* Caller->>repositoryFromTypeMetadata: model, propertyKey
|
618
|
+
*
|
619
|
+
* repositoryFromTypeMetadata->>Validation: key(Array.isArray(model[propertyKey]) ? ValidationKeys.LIST : ValidationKeys.TYPE)
|
620
|
+
* Validation-->>repositoryFromTypeMetadata: validationKey
|
621
|
+
*
|
622
|
+
* repositoryFromTypeMetadata->>Reflect: getMetadata(validationKey, model, propertyKey)
|
623
|
+
* Reflect-->>repositoryFromTypeMetadata: types
|
624
|
+
*
|
625
|
+
* repositoryFromTypeMetadata->>repositoryFromTypeMetadata: determine customTypes based on property type
|
626
|
+
* repositoryFromTypeMetadata->>repositoryFromTypeMetadata: check if types and customTypes exist
|
627
|
+
*
|
628
|
+
* repositoryFromTypeMetadata->>repositoryFromTypeMetadata: create allowedTypes array
|
629
|
+
* repositoryFromTypeMetadata->>repositoryFromTypeMetadata: find constructorName not in commomTypes
|
630
|
+
* repositoryFromTypeMetadata->>repositoryFromTypeMetadata: check if constructorName exists
|
631
|
+
*
|
632
|
+
* repositoryFromTypeMetadata->>Model: get(constructorName)
|
633
|
+
* Model-->>repositoryFromTypeMetadata: constructor
|
634
|
+
* repositoryFromTypeMetadata->>repositoryFromTypeMetadata: check if constructor exists
|
635
|
+
*
|
636
|
+
* repositoryFromTypeMetadata->>Repository: forModel(constructor)
|
637
|
+
* Repository-->>repositoryFromTypeMetadata: repo
|
638
|
+
*
|
639
|
+
* repositoryFromTypeMetadata-->>Caller: repo
|
640
|
+
*/
|
202
641
|
function repositoryFromTypeMetadata(model, propertyKey) {
|
203
642
|
const types = Reflect.getMetadata(decorator_validation_1.Validation.key(Array.isArray(model[propertyKey])
|
204
643
|
? decorator_validation_1.ValidationKeys.LIST
|
@@ -219,4 +658,4 @@ function repositoryFromTypeMetadata(model, propertyKey) {
|
|
219
658
|
throw new db_decorators_1.InternalError(`No registered model found for ${constructorName}`);
|
220
659
|
return Repository_1.Repository.forModel(constructor);
|
221
660
|
}
|
222
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uc3RydWN0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL21vZGVsL2NvbnN0cnVjdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQW1CQSx3Q0EwQkM7QUFFRCw0Q0FnQ0M7QUFFRCw0Q0FtQ0M7QUFFRCw0Q0FnQ0M7QUFFRCw4Q0EwQ0M7QUFFRCw4Q0FxQkM7QUFFRCw4Q0FzQ0M7QUFFRCx3Q0FNQztBQUVELHNEQWdCQztBQUVELDRCQWdEQztBQWVELGdFQW9DQztBQWhZRCx5RUFNd0M7QUFDeEMsK0RBQTREO0FBRTVELDJEQUtpQztBQUNqQyw4REFBMkQ7QUFDM0QsNkRBQWtEO0FBRzNDLEtBQUssVUFBVSxjQUFjLENBSWxDLEtBQVEsRUFDUixPQUFtQixFQUNuQixVQUFtQztJQUVuQyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDaEIsTUFBTSxXQUFXLEdBQUcsNEJBQUssQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN0RCxJQUFJLENBQUMsV0FBVztZQUNkLE1BQU0sSUFBSSw2QkFBYSxDQUFDLHdCQUF3QixLQUFLLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7UUFDNUUsVUFBVSxHQUFHLHVCQUFVLENBQUMsUUFBUSxDQUM5QixXQUE2QyxDQUM5QyxDQUFDO0lBQ0osQ0FBQztJQUNELElBQUksT0FBTyxLQUFLLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQyxLQUFLLFdBQVc7UUFDN0MsT0FBTyxVQUFVLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxPQUFPLENBQUMsQ0FBQztTQUN0QyxDQUFDO1FBQ0osSUFBSSxDQUFDO1lBQ0gsT0FBTyxVQUFVLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxPQUFPLENBQUMsQ0FBQztRQUMzQyxDQUFDO1FBQUMsT0FBTyxDQUFNLEVBQUUsQ0FBQztZQUNoQixJQUFJLENBQUMsQ0FBQyxDQUFDLFlB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QUNiLENBQUMsQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDO0lBQ3RCLElBQUksQ0FBQyxLQUFLLElBQUksQ0FBQyxXQUFXO1FBQ3hCLE1BQU0sSUFBSSw2QkFBYSxDQUNyQixnREFBZ0QsV0FBcUIsRUFBRSxDQUN4RSxDQUFDO0lBRUosTUFBTSxZQUFZLEdBQWEsS0FBSyxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUM7UUFDdkQsQ0FBQyxDQUFDLENBQUMsR0FBRyxXQUFXLENBQUM7UUFDbEIsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUM7SUFDbEIsTUFBTSxlQUFlLEdBQUcsWUFBWSxDQUFDLElBQUksQ0FDdkMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQ25ELENBQUM7SUFDRixJQUFJLENBQUMsZUFBZTtRQUNsQixNQUFNLElBQUksNkJBQWEsQ0FDckIsZ0JBQWdCLFdBQXFCLHlDQUF5QyxDQUMvRSxDQUFDO0lBQ0osTUFBTSxXQUFXLEdBQStCLDRCQUFLLENBQUMsR0FBRyxDQUFDLGVBQWUsQ0FBQyxDQUFDO0lBQzNFLElBQUksQ0FBQyxXQUFXO1FBQ2QsTUFBTSxJQUFJLDZCQUFhLENBQUMsaUNBQWlDLGVBQWUsRUFBRSxDQUFDLENBQUM7SUFFOUUsT0FBTyx1QkFBVSxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMsQ0FBQztBQUMxQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ29uc3RydWN0b3IsXG4gIE1vZGVsLFxuICBNb2RlbENvbnN0cnVjdG9yLFxuICBWYWxpZGF0aW9uLFxuICBWYWxpZGF0aW9uS2V5cyxcbn0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgUmVwbywgUmVwb3NpdG9yeSB9IGZyb20gXCIuLi9yZXBvc2l0b3J5L1JlcG9zaXRvcnlcIjtcbmltcG9ydCB7IFJlbGF0aW9uc01ldGFkYXRhIH0gZnJvbSBcIi4vdHlwZXNcIjtcbmltcG9ydCB7XG4gIGZpbmRQcmltYXJ5S2V5LFxuICBJbnRlcm5hbEVycm9yLFxuICBOb3RGb3VuZEVycm9yLFxuICBSZXBvc2l0b3J5RmxhZ3MsXG59IGZyb20gXCJAZGVjYWYtdHMvZGItZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHsgUGVyc2lzdGVuY2VLZXlzIH0gZnJvbSBcIi4uL3BlcnNpc3RlbmNlL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgQ2FzY2FkZSB9IGZyb20gXCIuLi9yZXBvc2l0b3J5L2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgQ29udGV4dCB9IGZyb20gXCJAZGVjYWYtdHMvZGItZGVjb3JhdG9yc1wiO1xuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gY3JlYXRlT3JVcGRhdGU8XG4gIE0gZXh0ZW5kcyBNb2RlbCxcbiAgRiBleHRlbmRzIFJlcG9zaXRvcnlGbGFncyxcbj4oXG4gIG1vZGVsOiBNLFxuICBjb250ZXh0OiBDb250ZXh0PEY+LFxuICByZXBvc2l0b3J5PzogUmVwbzxNLCBGLCBDb250ZXh0PEY+PlxuKTogUHJvbWlzZTxNPiB7XG4gIGlmICghcmVwb3NpdG9yeSkge1xuICAgIGNvbnN0IGNvbnN0cnVjdG9yID0gTW9kZWwuZ2V0KG1vZGVsLmNvbnN0cnVjdG9yLm5hbWUpO1xuICAgIGlmICghY29uc3RydWN0b3IpXG4gICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihgQ291bGQgbm90IGZpbmQgbW9kZWwgJHttb2RlbC5jb25zdHJ1Y3Rvci5uYW1lfWApO1xuICAgIHJlcG9zaXRvcnkgPSBSZXBvc2l0b3J5LmZvck1vZGVsPE0sIFJlcG88TT4+KFxuICAgICAgY29uc3RydWN0b3IgYXMgdW5rbm93biBhcyBNb2RlbENvbnN0cnVjdG9yPE0+XG4gICAgKTtcbiAgfVxuICBpZiAodHlwZW9mIG1vZGVsW3JlcG9zaXRvcnkucGtdID09PSBcInVuZGVmaW5lZFwiKVxuICAgIHJldHVybiByZXBvc2l0b3J5LmNyZWF0ZShtb2RlbCwgY29udGV4dCk7XG4gIGVsc2Uge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gcmVwb3NpdG9yeS51cGRhdGUobW9kZWwsIGNvbnRleHQpO1xuICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgaWYgKCEoZSBpbnN0YW5jZW9mIE5vdEZvdW5kRXJyb3IpKSB0aHJvdyBlO1xuICAgICAgcmV0dXJuIHJlcG9zaXRvcnkuY3JlYXRlKG1vZGVsLCBjb250ZXh0KTtcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIG9uZVRvT25lT25DcmVhdGU8XG4gIE0gZXh0ZW5kcyBNb2RlbCxcbiAgUiBleHRlbmRzIFJlcG88TSwgRiwgQz4sXG4gIFYgZXh0ZW5kcyBSZWxhdGlvbnNNZXRhZGF0YSxcbiAgRiBleHRlbmRzIFJlcG9zaXRvcnlGbGFncyxcbiAgQyBleHRlbmRzIENvbnRleHQ8Rj4sXG4+KFxuICB0aGlzOiBSLFxuICBjb250ZXh0OiBDb250ZXh0PEY+LFxuICBkYXRhOiBWLFxuICBrZXk6IGtleW9mIE0sXG4gIG1vZGVsOiBNXG4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgcHJvcGVydHlWYWx1ZTogYW55ID0gbW9kZWxba2V5XTtcbiAgaWYgKCFwcm9wZXJ0eVZhbHVlKSByZXR1cm47XG5cbiAgaWYgKHR5cGVvZiBwcm9wZXJ0eVZhbHVlICE9PSBcIm9iamVjdFwiKSB7XG4gICAgY29uc3QgaW5uZXJSZXBvID0gcmVwb3NpdG9yeUZyb21UeXBlTWV0YWRhdGEobW9kZWwsIGtleSk7XG4gICAgY29uc3QgcmVhZCA9IGF3YWl0IGlubmVyUmVwby5yZWFkKHByb3BlcnR5VmFsdWUpO1xuICAgIGF3YWl0IGNhY2hlTW9kZWxGb3JQb3B1bGF0ZShjb250ZXh0LCBtb2RlbCwga2V5LCBwcm9wZXJ0eVZhbHVlLCByZWFkKTtcbiAgICAobW9kZWwgYXMgYW55KVtrZXldID0gcHJvcGVydHlWYWx1ZTtcbiAgICByZXR1cm47XG4gIH1cblxuICBjb25zdCBjb25zdHJ1Y3RvciA9IE1vZGVsLmdldChkYXRhLmNsYXNzKTtcbiAgaWYgKCFjb25zdHJ1Y3RvcilcbiAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihgQ291bGQgbm90IGZpbmQgbW9kZWwgJHtkYXRhLmNsYXNzfWApO1xuICBjb25zdCByZXBvOiBSZXBvPGFueT4gPSBSZXBvc2l0b3J5LmZvck1vZGVsKGNvbnN0cnVjdG9yKTtcbiAgY29uc3QgY3JlYXRlZCA9IGF3YWl0IHJlcG8uY3JlYXRlKHByb3BlcnR5VmFsdWUpO1xuICBjb25zdCBwayA9IGZpbmRQcmltYXJ5S2V5KGNyZWF0ZWQpLmlkO1xuICBhd2FpdCBjYWNoZU1vZGVsRm9yUG9wdWxhdGUoY29udGV4dCwgbW9kZWwsIGtleSwgY3JlYXRlZFtwa10sIGNyZWF0ZWQpO1xuICAobW9kZWwgYXMgYW55KVtrZXldID0gY3JlYXRlZFtwa107XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBvbmVUb09uZU9uVXBkYXRlPFxuICBNIGV4dGVuZHMgTW9kZWwsXG4gIFIgZXh0ZW5kcyBSZXBvPE0sIEYsIEM+LFxuICBWIGV4dGVuZHMgUmVsYXRpb25zTWV0YWRhdGEsXG4gIEYgZXh0ZW5kcyBSZXBvc2l0b3J5RmxhZ3MsXG4gIEMgZXh0ZW5kcyBDb250ZXh0PEY+LFxuPihcbiAgdGhpczogUixcbiAgY29udGV4dDogQ29udGV4dDxGPixcbiAgZGF0YTogVixcbiAga2V5OiBrZXlvZiBNLFxuICBtb2RlbDogTVxuKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IHByb3BlcnR5VmFsdWU6IGFueSA9IG1vZGVsW2tleV07XG4gIGlmICghcHJvcGVydHlWYWx1ZSkgcmV0dXJuO1xuICBpZiAoZGF0YS5jYXNjYWRlLnVwZGF0ZSAhPT0gQ2FzY2FkZS5DQVNDQURFKSByZXR1cm47XG5cbiAgaWYgKHR5cGVvZiBwcm9wZXJ0eVZhbHVlICE9PSBcIm9iamVjdFwiKSB7XG4gICAgY29uc3QgaW5uZXJSZXBvID0gcmVwb3NpdG9yeUZyb21UeXBlTWV0YWRhdGEobW9kZWwsIGtleSk7XG4gICAgY29uc3QgcmVhZCA9IGF3YWl0IGlubmVyUmVwby5yZWFkKHByb3BlcnR5VmFsdWUpO1xuICAgIGF3YWl0IGNhY2hlTW9kZWxGb3JQb3B1bGF0ZShjb250ZXh0LCBtb2RlbCwga2V5LCBwcm9wZXJ0eVZhbHVlLCByZWFkKTtcbiAgICAobW9kZWwgYXMgYW55KVtrZXldID0gcHJvcGVydHlWYWx1ZTtcbiAgICByZXR1cm47XG4gIH1cblxuICBjb25zdCB1cGRhdGVkID0gYXdhaXQgY3JlYXRlT3JVcGRhdGUobW9kZWxba2V5XSBhcyBNLCBjb250ZXh0KTtcbiAgY29uc3QgcGsgPSBmaW5kUHJpbWFyeUtleSh1cGRhdGVkKS5pZDtcbiAgYXdhaXQgY2FjaGVNb2RlbEZvclBvcHVsYXRlKFxuICAgIGNvbnRleHQsXG4gICAgbW9kZWwsXG4gICAga2V5LFxuICAgIHVwZGF0ZWRbcGtdIGFzIHN0cmluZyxcbiAgICB1cGRhdGVkXG4gICk7XG4gIG1vZGVsW2tleV0gPSB1cGRhdGVkW3BrXTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIG9uZVRvT25lT25EZWxldGU8XG4gIE0gZXh0ZW5kcyBNb2RlbCxcbiAgUiBleHRlbmRzIFJlcG88TSwgRiwgQz4sXG4gIFYgZXh0ZW5kcyBSZWxhdGlvbnNNZXRhZGF0YSxcbiAgRiBleHRlbmRzIFJlcG9zaXRvcnlGbGFncyxcbiAgQyBleHRlbmRzIENvbnRleHQ8Rj4sXG4+KFxuICB0aGlzOiBSLFxuICBjb250ZXh0OiBDb250ZXh0PEY+LFxuICBkYXRhOiBWLFxuICBrZXk6IGtleW9mIE0sXG4gIG1vZGVsOiBNXG4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgcHJvcGVydHlWYWx1ZTogYW55ID0gbW9kZWxba2V5XTtcbiAgaWYgKCFwcm9wZXJ0eVZhbHVlKSByZXR1cm47XG4gIGlmIChkYXRhLmNhc2NhZGUudXBkYXRlICE9PSBDYXNjYWRlLkNBU0NBREUpIHJldHVybjtcbiAgY29uc3QgaW5uZXJSZXBvOiBSZXBvPE0+ID0gcmVwb3NpdG9yeUZyb21UeXBlTWV0YWRhdGEobW9kZWwsIGtleSk7XG4gIGxldCBkZWxldGVkOiBNO1xuICBpZiAoIShwcm9wZXJ0eVZhbHVlIGluc3RhbmNlb2YgTW9kZWwpKVxuICAgIGRlbGV0ZWQgPSBhd2FpdCBpbm5lclJlcG8uZGVsZXRlKG1vZGVsW2tleV0gYXMgc3RyaW5nLCBjb250ZXh0KTtcbiAgZWxzZVxuICAgIGRlbGV0ZWQgPSBhd2FpdCBpbm5lclJlcG8uZGVsZXRlKFxuICAgICAgKG1vZGVsW2tleV0gYXMgTSlbaW5uZXJSZXBvLnBrIGFzIGtleW9mIE1dIGFzIHN0cmluZyxcbiAgICAgIGNvbnRleHRcbiAgICApO1xuICBhd2FpdCBjYWNoZU1vZGVsRm9yUG9wdWxhdGUoXG4gICAgY29udGV4dCxcbiAgICBtb2RlbCxcbiAgICBrZXksXG4gICAgZGVsZXRlZFtpbm5lclJlcG8ucGtdIGFzIHN0cmluZyxcbiAgICBkZWxldGVkXG4gICk7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBvbmVUb01hbnlPbkNyZWF0ZTxcbiAgTSBleHRlbmRzIE1vZGVsLFxuICBSIGV4dGVuZHMgUmVwbzxNLCBGLCBDPixcbiAgViBleHRlbmRzIFJlbGF0aW9uc01ldGFkYXRhLFxuICBGIGV4dGVuZHMgUmVwb3NpdG9yeUZsYWdzLFxuICBDIGV4dGVuZHMgQ29udGV4dDxGPixcbj4oXG4gIHRoaXM6IFIsXG4gIGNvbnRleHQ6IENvbnRleHQ8Rj4sXG4gIGRhdGE6IFYsXG4gIGtleToga2V5b2YgTSxcbiAgbW9kZWw6IE1cbik6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCBwcm9wZXJ0eVZhbHVlczogYW55ID0gbW9kZWxba2V5XTtcbiAgaWYgKCFwcm9wZXJ0eVZhbHVlcyB8fCAhcHJvcGVydHlWYWx1ZXMubGVuZ3RoKSByZXR1cm47XG4gIGNvbnN0IGFycmF5VHlwZSA9IHR5cGVvZiBwcm9wZXJ0eVZhbHVlc1swXTtcbiAgaWYgKCFwcm9wZXJ0eVZhbHVlcy5ldmVyeSgoaXRlbTogYW55KSA9PiB0eXBlb2YgaXRlbSA9PT0gYXJyYXlUeXBlKSlcbiAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcbiAgICAgIGBJbnZhbGlkIG9wZXJhdGlvbi4gQWxsIGVsZW1lbnRzIG9mIHByb3BlcnR5ICR7a2V5IGFzIHN0cmluZ30gbXVzdCBtYXRjaCB0aGUgc2FtZSB0eXBlLmBcbiAgICApO1xuICBjb25zdCB1bmlxdWVWYWx1ZXMgPSBuZXcgU2V0KFsuLi5wcm9wZXJ0eVZhbHVlc10pO1xuICBpZiAoYXJyYXlUeXBlICE9PSBcIm9iamVjdFwiKSB7XG4gICAgY29uc3QgcmVwbyA9IHJlcG9zaXRvcnlGcm9tVHlwZU1ldGFkYXRhKG1vZGVsLCBrZXkpO1xuICAgIGZvciAoY29uc3QgaWQgb2YgdW5pcXVlVmFsdWVzKSB7XG4gICAgICBjb25zdCByZWFkID0gYXdhaXQgcmVwby5yZWFkKGlkKTtcbiAgICAgIGF3YWl0IGNhY2hlTW9kZWxGb3JQb3B1bGF0ZShjb250ZXh0LCBtb2RlbCwga2V5LCBpZCwgcmVhZCk7XG4gICAgfVxuICAgIChtb2RlbCBhcyBhbnkpW2tleV0gPSBbLi4udW5pcXVlVmFsdWVzXTtcbiAgICByZXR1cm47XG4gIH1cblxuICBjb25zdCBwa05hbWUgPSBmaW5kUHJpbWFyeUtleShwcm9wZXJ0eVZhbHVlc1swXSkuaWQ7XG5cbiAgY29uc3QgcmVzdWx0OiBTZXQ8c3RyaW5nPiA9IG5ldyBTZXQoKTtcblxuICBmb3IgKGNvbnN0IG0gb2YgcHJvcGVydHlWYWx1ZXMpIHtcbiAgICBjb25zdCByZWNvcmQgPSBhd2FpdCBjcmVhdGVPclVwZGF0ZShtLCBjb250ZXh0KTtcbiAgICBhd2FpdCBjYWNoZU1vZGVsRm9yUG9wdWxhdGUoY29udGV4dCwgbW9kZWwsIGtleSwgcmVjb3JkW3BrTmFtZV0sIHJlY29yZCk7XG4gICAgcmVzdWx0LmFkZChyZWNvcmRbcGtOYW1lXSk7XG4gIH1cblxuICAobW9kZWwgYXMgYW55KVtrZXldID0gWy4uLnJlc3VsdF07XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBvbmVUb01hbnlPblVwZGF0ZTxcbiAgTSBleHRlbmRzIE1vZGVsLFxuICBSIGV4dGVuZHMgUmVwbzxNLCBGLCBDPixcbiAgViBleHRlbmRzIFJlbGF0aW9uc01ldGFkYXRhLFxuICBGIGV4dGVuZHMgUmVwb3NpdG9yeUZsYWdzLFxuICBDIGV4dGVuZHMgQ29udGV4dDxGPixcbj4oXG4gIHRoaXM6IFIsXG4gIGNvbnRleHQ6IENvbnRleHQ8Rj4sXG4gIGRhdGE6IFYsXG4gIGtleToga2V5b2YgTSxcbiAgbW9kZWw6IE1cbik6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCB7IGNhc2NhZGUgfSA9IGRhdGE7XG4gIGlmIChjYXNjYWRlLnVwZGF0ZSAhPT0gQ2FzY2FkZS5DQVNDQURFKSByZXR1cm47XG4gIHJldHVybiBvbmVUb01hbnlPbkNyZWF0ZS5hcHBseSh0aGlzIGFzIGFueSwgW1xuICAgIGNvbnRleHQsXG4gICAgZGF0YSxcbiAgICBrZXkgYXMga2V5b2YgTW9kZWwsXG4gICAgbW9kZWwsXG4gIF0pO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gb25lVG9NYW55T25EZWxldGU8XG4gIE0gZXh0ZW5kcyBNb2RlbCxcbiAgUiBleHRlbmRzIFJlcG88TSwgRiwgQz4sXG4gIFYgZXh0ZW5kcyBSZWxhdGlvbnNNZXRhZGF0YSxcbiAgRiBleHRlbmRzIFJlcG9zaXRvcnlGbGFncyxcbiAgQyBleHRlbmRzIENvbnRleHQ8Rj4sXG4+KFxuICB0aGlzOiBSLFxuICBjb250ZXh0OiBDb250ZXh0PEY+LFxuICBkYXRhOiBWLFxuICBrZXk6IGtleW9mIE0sXG4gIG1vZGVsOiBNXG4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgaWYgKGRhdGEuY2FzY2FkZS5kZWxldGUgIT09IENhc2NhZGUuQ0FTQ0FERSkgcmV0dXJuO1xuICBjb25zdCB2YWx1ZXMgPSBtb2RlbFtrZXldIGFzIGFueTtcbiAgaWYgKCF2YWx1ZXMgfHwgIXZhbHVlcy5sZW5ndGgpIHJldHVybjtcbiAgY29uc3QgYXJyYXlUeXBlID0gdHlwZW9mIHZhbHVlc1swXTtcbiAgY29uc3QgYXJlQWxsU2FtZVR5cGUgPSB2YWx1ZXMuZXZlcnkoKGl0ZW06IGFueSkgPT4gdHlwZW9mIGl0ZW0gPT09IGFycmF5VHlwZSk7XG4gIGlmICghYXJlQWxsU2FtZVR5cGUpXG4gICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXG4gICAgICBgSW52YWxpZCBvcGVyYXRpb24uIEFsbCBlbGVtZW50cyBvZiBwcm9wZXJ0eSAke2tleSBhcyBzdHJpbmd9IG11c3QgbWF0Y2ggdGhlIHNhbWUgdHlwZS5gXG4gICAgKTtcbiAgY29uc3QgaXNJbnN0YW50aWF0ZWQgPSBhcnJheVR5cGUgPT09IFwib2JqZWN0XCI7XG4gIGNvbnN0IHJlcG8gPSBpc0luc3RhbnRpYXRlZFxuICAgID8gUmVwb3NpdG9yeS5mb3JNb2RlbCh2YWx1ZXNbMF0pXG4gICAgOiByZXBvc2l0b3J5RnJvbVR5cGVNZXRhZGF0YShtb2RlbCwga2V5KTtcblxuICBjb25zdCB1bmlxdWVWYWx1ZXMgPSBuZXcgU2V0KFtcbiAgICAuLi4oaXNJbnN0YW50aWF0ZWRcbiAgICAgID8gdmFsdWVzLm1hcCgodjogUmVjb3JkPHN0cmluZywgYW55PikgPT4gdltyZXBvLnBrIGFzIHN0cmluZ10pXG4gICAgICA6IHZhbHVlcyksXG4gIF0pO1xuXG4gIGZvciAoY29uc3QgaWQgb2YgdW5pcXVlVmFsdWVzLnZhbHVlcygpKSB7XG4gICAgY29uc3QgZGVsZXRlZCA9IGF3YWl0IHJlcG8uZGVsZXRlKGlkLCBjb250ZXh0KTtcbiAgICBhd2FpdCBjYWNoZU1vZGVsRm9yUG9wdWxhdGUoY29udGV4dCwgbW9kZWwsIGtleSwgaWQsIGRlbGV0ZWQpO1xuICB9XG4gIChtb2RlbCBhcyBhbnkpW2tleV0gPSBbLi4udW5pcXVlVmFsdWVzXTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFBvcHVsYXRlS2V5KFxuICB0YWJsZU5hbWU6IHN0cmluZyxcbiAgZmllbGROYW1lOiBzdHJpbmcsXG4gIGlkOiBzdHJpbmcgfCBudW1iZXJcbikge1xuICByZXR1cm4gW1BlcnNpc3RlbmNlS2V5cy5QT1BVTEFURSwgdGFibGVOYW1lLCBmaWVsZE5hbWUsIGlkXS5qb2luKFwiLlwiKTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNhY2hlTW9kZWxGb3JQb3B1bGF0ZTxcbiAgTSBleHRlbmRzIE1vZGVsLFxuICBGIGV4dGVuZHMgUmVwb3NpdG9yeUZsYWdzLFxuPihcbiAgY29udGV4dDogQ29udGV4dDxGPixcbiAgcGFyZW50TW9kZWw6IE0sXG4gIHByb3BlcnR5S2V5OiBrZXlvZiBNIHwgc3RyaW5nLFxuICBwa1ZhbHVlOiBzdHJpbmcgfCBudW1iZXIsXG4gIGNhY2hlVmFsdWU6IGFueVxuKSB7XG4gIGNvbnN0IGNhY2hlS2V5ID0gZ2V0UG9wdWxhdGVLZXkoXG4gICAgcGFyZW50TW9kZWwuY29uc3RydWN0b3IubmFtZSxcbiAgICBwcm9wZXJ0eUtleSBhcyBzdHJpbmcsXG4gICAgcGtWYWx1ZVxuICApO1xuICByZXR1cm4gY29udGV4dC5hY2N1bXVsYXRlKHsgW2NhY2hlS2V5XTogY2FjaGVWYWx1ZSB9KTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHBvcHVsYXRlPFxuICBNIGV4dGVuZHMgTW9kZWwsXG4gIFIgZXh0ZW5kcyBSZXBvPE0sIEYsIEM+LFxuICBWIGV4dGVuZHMgUmVsYXRpb25zTWV0YWRhdGEsXG4gIEYgZXh0ZW5kcyBSZXBvc2l0b3J5RmxhZ3MsXG4gIEMgZXh0ZW5kcyBDb250ZXh0PEY+LFxuPihcbiAgdGhpczogUixcbiAgY29udGV4dDogQ29udGV4dDxGPixcbiAgZGF0YTogVixcbiAga2V5OiBrZXlvZiBNLFxuICBtb2RlbDogTVxuKTogUHJvbWlzZTx2b2lkPiB7XG4gIGlmICghZGF0YS5wb3B1bGF0ZSkgcmV0dXJuO1xuICBjb25zdCBuZXN0ZWQ6IGFueSA9IG1vZGVsW2tleV07XG4gIGNvbnN0IGlzQXJyID0gQXJyYXkuaXNBcnJheShuZXN0ZWQpO1xuICBpZiAodHlwZW9mIG5lc3RlZCA9PT0gXCJ1bmRlZmluZWRcIiB8fCAoaXNBcnIgJiYgbmVzdGVkLmxlbmd0aCA9PT0gMCkpIHJldHVybjtcblxuICBhc3luYyBmdW5jdGlvbiBmZXRjaFBvcHVsYXRlVmFsdWVzKFxuICAgIGM6IENvbnRleHQ8Rj4sXG4gICAgbW9kZWw6IE0sXG4gICAgcHJvcE5hbWU6IHN0cmluZyxcbiAgICBwcm9wS2V5VmFsdWVzOiBhbnlbXVxuICApIHtcbiAgICBsZXQgY2FjaGVLZXk6IHN0cmluZztcbiAgICBsZXQgdmFsOiBhbnk7XG4gICAgY29uc3QgcmVzdWx0czogTVtdID0gW107XG4gICAgZm9yIChjb25zdCBwcm9LZXlWYWx1ZSBvZiBwcm9wS2V5VmFsdWVzKSB7XG4gICAgICBjYWNoZUtleSA9IGdldFBvcHVsYXRlS2V5KG1vZGVsLmNvbnN0cnVjdG9yLm5hbWUsIHByb3BOYW1lLCBwcm9LZXlWYWx1ZSk7XG4gICAgICB0cnkge1xuICAgICAgICB2YWwgPSBhd2FpdCBjLmdldChjYWNoZUtleSBhcyBhbnkpO1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gICAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgICAgY29uc3QgcmVwbyA9IHJlcG9zaXRvcnlGcm9tVHlwZU1ldGFkYXRhKG1vZGVsLCBwcm9wTmFtZSk7XG4gICAgICAgIGlmICghcmVwbykgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXCJDb3VsZCBub3QgZmluZCByZXBvXCIpO1xuICAgICAgICB2YWwgPSBhd2FpdCByZXBvLnJlYWQocHJvS2V5VmFsdWUpO1xuICAgICAgfVxuICAgICAgcmVzdWx0cy5wdXNoKHZhbCk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHRzO1xuICB9XG4gIGNvbnN0IHJlcyA9IGF3YWl0IGZldGNoUG9wdWxhdGVWYWx1ZXMoXG4gICAgY29udGV4dCxcbiAgICBtb2RlbCxcbiAgICBrZXkgYXMgc3RyaW5nLFxuICAgIGlzQXJyID8gbmVzdGVkIDogW25lc3RlZF1cbiAgKTtcbiAgKG1vZGVsIGFzIGFueSlba2V5XSA9IGlzQXJyID8gcmVzIDogcmVzWzBdO1xufVxuXG5jb25zdCBjb21tb21UeXBlcyA9IFtcbiAgXCJhcnJheVwiLFxuICBcInN0cmluZ1wiLFxuICBcIm51bWJlclwiLFxuICBcImJvb2xlYW5cIixcbiAgXCJzeW1ib2xcIixcbiAgXCJmdW5jdGlvblwiLFxuICBcIm9iamVjdFwiLFxuICBcInVuZGVmaW5lZFwiLFxuICBcIm51bGxcIixcbiAgXCJiaWdpbnRcIixcbl07XG5cbmV4cG9ydCBmdW5jdGlvbiByZXBvc2l0b3J5RnJvbVR5cGVNZXRhZGF0YTxNIGV4dGVuZHMgTW9kZWw+KFxuICBtb2RlbDogYW55LFxuICBwcm9wZXJ0eUtleTogc3RyaW5nIHwga2V5b2YgTVxuKTogUmVwbzxNPiB7XG4gIGNvbnN0IHR5cGVzID0gUmVmbGVjdC5nZXRNZXRhZGF0YShcbiAgICBWYWxpZGF0aW9uLmtleShcbiAgICAgIEFycmF5LmlzQXJyYXkobW9kZWxbcHJvcGVydHlLZXldKVxuICAgICAgICA/IFZhbGlkYXRpb25LZXlzLkxJU1RcbiAgICAgICAgOiBWYWxpZGF0aW9uS2V5cy5UWVBFXG4gICAgKSxcbiAgICBtb2RlbCxcbiAgICBwcm9wZXJ0eUtleSBhcyBzdHJpbmdcbiAgKTtcbiAgY29uc3QgY3VzdG9tVHlwZXM6IGFueSA9IEFycmF5LmlzQXJyYXkobW9kZWxbcHJvcGVydHlLZXldKVxuICAgID8gdHlwZXMuY2xhenpcbiAgICA6IHR5cGVzLmN1c3RvbVR5cGVzO1xuICBpZiAoIXR5cGVzIHx8ICFjdXN0b21UeXBlcylcbiAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcbiAgICAgIGBGYWlsZWQgdG8gZmluZCB0eXBlcyBkZWNvcmF0b3JzIGZvciBwcm9wZXJ0eSAke3Byb3BlcnR5S2V5IGFzIHN0cmluZ31gXG4gICAgKTtcblxuICBjb25zdCBhbGxvd2VkVHlwZXM6IHN0cmluZ1tdID0gQXJyYXkuaXNBcnJheShjdXN0b21UeXBlcylcbiAgICA/IFsuLi5jdXN0b21UeXBlc11cbiAgICA6IFtjdXN0b21UeXBlc107XG4gIGNvbnN0IGNvbnN0cnVjdG9yTmFtZSA9IGFsbG93ZWRUeXBlcy5maW5kKFxuICAgICh0KSA9PiAhY29tbW9tVHlwZXMuaW5jbHVkZXMoYCR7dH1gLnRvTG93ZXJDYXNlKCkpXG4gICk7XG4gIGlmICghY29uc3RydWN0b3JOYW1lKVxuICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFxuICAgICAgYFByb3BlcnR5IGtleSAke3Byb3BlcnR5S2V5IGFzIHN0cmluZ30gZG9lcyBub3QgaGF2ZSBhIHZhbGlkIGNvbnN0cnVjdG9yIHR5cGVgXG4gICAgKTtcbiAgY29uc3QgY29uc3RydWN0b3I6IENvbnN0cnVjdG9yPE0+IHwgdW5kZWZpbmVkID0gTW9kZWwuZ2V0KGNvbnN0cnVjdG9yTmFtZSk7XG4gIGlmICghY29uc3RydWN0b3IpXG4gICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoYE5vIHJlZ2lzdGVyZWQgbW9kZWwgZm91bmQgZm9yICR7Y29uc3RydWN0b3JOYW1lfWApO1xuXG4gIHJldHVybiBSZXBvc2l0b3J5LmZvck1vZGVsKGNvbnN0cnVjdG9yKTtcbn1cbiJdfQ==
|
661
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uc3RydWN0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL21vZGVsL2NvbnN0cnVjdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQTREQSx3Q0EwQkM7QUFvREQsNENBZ0NDO0FBaURELDRDQW1DQztBQTJDRCw0Q0FnQ0M7QUF3REQsOENBMENDO0FBa0NELDhDQXFCQztBQWtERCw4Q0FzQ0M7QUFZRCx3Q0FNQztBQWdCRCxzREFnQkM7QUF3REQsNEJBZ0RDO0FBK0RELGdFQW9DQztBQXZ6QkQseUVBTXdDO0FBQ3hDLCtEQUE0RDtBQUU1RCwyREFLaUM7QUFDakMsOERBQTJEO0FBQzNELDZEQUFrRDtBQUdsRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXdDRztBQUNJLEtBQUssVUFBVSxjQUFjLENBSWxDLEtBQVEsRUFDUixPQUFtQixFQUNuQixVQUFtQztJQUVuQyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDaEIsTUFBTSxXQUFXLEdBQUcsNEJBQUssQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN0RCxJQUFJLENBQUMsV0FBVztZQUNkLE1BQU0sSUFBSSw2QkFBYSxDQUFDLHdCQUF3QixLQUFLLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7UUFDNUUsVUFBVSxHQUFHLHVCQUFVLENBQUMsUUFBUSxDQUM5QixXQUE2QyxDQUM5QyxDQUFDO0lBQ0osQ0FBQztJQUNELElBQUksT0FBTyxLQUFLLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQyxLQUFLLFdBQVc7UUFDN0MsT0FBTyxVQUFVLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxPQUFPLENBQUMsQ0FBQztTQUN0QyxDQUFDO1FBQ0osSUFBSSxDQUFDO1lBQ0gsT0FBTyxVQUFVLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxPQUFPLENBQUMsQ0FBQztRQUMz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Q0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FDbkQsQ0FBQztJQUNGLElBQUksQ0FBQyxlQUFlO1FBQ2xCLE1BQU0sSUFBSSw2QkFBYSxDQUNyQixnQkFBZ0IsV0FBcUIseUNBQXlDLENBQy9FLENBQUM7SUFDSixNQUFNLFdBQVcsR0FBK0IsNEJBQUssQ0FBQyxHQUFHLENBQUMsZUFBZSxDQUFDLENBQUM7SUFDM0UsSUFBSSxDQUFDLFdBQVc7UUFDZCxNQUFNLElBQUksNkJBQWEsQ0FBQyxpQ0FBaUMsZUFBZSxFQUFFLENBQUMsQ0FBQztJQUU5RSxPQUFPLHVCQUFVLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0FBQzFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBDb25zdHJ1Y3RvcixcbiAgTW9kZWwsXG4gIE1vZGVsQ29uc3RydWN0b3IsXG4gIFZhbGlkYXRpb24sXG4gIFZhbGlkYXRpb25LZXlzLFxufSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBSZXBvLCBSZXBvc2l0b3J5IH0gZnJvbSBcIi4uL3JlcG9zaXRvcnkvUmVwb3NpdG9yeVwiO1xuaW1wb3J0IHsgUmVsYXRpb25zTWV0YWRhdGEgfSBmcm9tIFwiLi90eXBlc1wiO1xuaW1wb3J0IHtcbiAgZmluZFByaW1hcnlLZXksXG4gIEludGVybmFsRXJyb3IsXG4gIE5vdEZvdW5kRXJyb3IsXG4gIFJlcG9zaXRvcnlGbGFncyxcbn0gZnJvbSBcIkBkZWNhZi10cy9kYi1kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBQZXJzaXN0ZW5jZUtleXMgfSBmcm9tIFwiLi4vcGVyc2lzdGVuY2UvY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBDYXNjYWRlIH0gZnJvbSBcIi4uL3JlcG9zaXRvcnkvY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBDb250ZXh0IH0gZnJvbSBcIkBkZWNhZi10cy9kYi1kZWNvcmF0b3JzXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIENyZWF0ZXMgb3IgdXBkYXRlcyBhIG1vZGVsIGluc3RhbmNlXG4gKiBAc3VtbWFyeSBEZXRlcm1pbmVzIHdoZXRoZXIgdG8gY3JlYXRlIGEgbmV3IG1vZGVsIG9yIHVwZGF0ZSBhbiBleGlzdGluZyBvbmUgYmFzZWQgb24gdGhlIHByZXNlbmNlIG9mIGEgcHJpbWFyeSBrZXlcbiAqIEB0ZW1wbGF0ZSBNIC0gVGhlIG1vZGVsIHR5cGUgZXh0ZW5kaW5nIE1vZGVsXG4gKiBAdGVtcGxhdGUgRiAtIFRoZSByZXBvc2l0b3J5IGZsYWdzIHR5cGVcbiAqIEBwYXJhbSB7TX0gbW9kZWwgLSBUaGUgbW9kZWwgaW5zdGFuY2UgdG8gY3JlYXRlIG9yIHVwZGF0ZVxuICogQHBhcmFtIHtDb250ZXh0PEY+fSBjb250ZXh0IC0gVGhlIGNvbnRleHQgZm9yIHRoZSBvcGVyYXRpb25cbiAqIEBwYXJhbSB7UmVwbzxNLCBGLCBDb250ZXh0PEY+Pn0gW3JlcG9zaXRvcnldIC0gT3B0aW9uYWwgcmVwb3NpdG9yeSB0byB1c2UgZm9yIHRoZSBvcGVyYXRpb25cbiAqIEByZXR1cm4ge1Byb21pc2U8TT59IEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIHRoZSBjcmVhdGVkIG9yIHVwZGF0ZWQgbW9kZWxcbiAqIEBmdW5jdGlvbiBjcmVhdGVPclVwZGF0ZVxuICogQG1lbWJlck9mIG1vZHVsZTpjb3JlXG4gKiBAbWVybWFpZFxuICogc2VxdWVuY2VEaWFncmFtXG4gKiAgIHBhcnRpY2lwYW50IENhbGxlclxuICogICBwYXJ0aWNpcGFudCBjcmVhdGVPclVwZGF0ZVxuICogICBwYXJ0aWNpcGFudCBSZXBvc2l0b3J5XG4gKiAgIHBhcnRpY2lwYW50IE1vZGVsXG4gKlxuICogICBDYWxsZXItPj5jcmVhdGVPclVwZGF0ZTogbW9kZWwsIGNvbnRleHQsIHJlcG9zaXRvcnk/XG4gKiAgIGFsdCByZXBvc2l0b3J5IG5vdCBwcm92aWRlZFxuICogICAgIGNyZWF0ZU9yVXBkYXRlLT4+TW9kZWw6IGdldChtb2RlbC5jb25zdHJ1Y3Rvci5uYW1lKVxuICogICAgIE1vZGVsLS0+PmNyZWF0ZU9yVXBkYXRlOiBjb25zdHJ1Y3RvclxuICogICAgIGNyZWF0ZU9yVXBkYXRlLT4+UmVwb3NpdG9yeTogZm9yTW9kZWwoY29uc3RydWN0b3IpXG4gKiAgICAgUmVwb3NpdG9yeS0tPj5jcmVhdGVPclVwZGF0ZTogcmVwb3NpdG9yeVxuICogICBlbmRcbiAqXG4gKiAgIGFsdCBwcmltYXJ5IGtleSB1bmRlZmluZWRcbiAqICAgICBjcmVhdGVPclVwZGF0ZS0+PlJlcG9zaXRvcnk6IGNyZWF0ZShtb2RlbCwgY29udGV4dClcbiAqICAgICBSZXBvc2l0b3J5LS0+PmNyZWF0ZU9yVXBkYXRlOiBjcmVhdGVkIG1vZGVsXG4gKiAgIGVsc2UgcHJpbWFyeSBrZXkgZGVmaW5lZFxuICogICAgIGNyZWF0ZU9yVXBkYXRlLT4+UmVwb3NpdG9yeTogdXBkYXRlKG1vZGVsLCBjb250ZXh0KVxuICogICAgIGFsdCB1cGRhdGUgc3VjY2Vzc2Z1bFxuICogICAgICAgUmVwb3NpdG9yeS0tPj5jcmVhdGVPclVwZGF0ZTogdXBkYXRlZCBtb2RlbFxuICogICAgIGVsc2UgTm90Rm91bmRFcnJvclxuICogICAgICAgY3JlYXRlT3JVcGRhdGUtPj5SZXBvc2l0b3J5OiBjcmVhdGUobW9kZWwsIGNvbnRleHQpXG4gKiAgICAgICBSZXBvc2l0b3J5LS0+PmNyZWF0ZU9yVXBkYXRlOiBjcmVhdGVkIG1vZGVsXG4gKiAgICAgZW5kXG4gKiAgIGVuZFxuICpcbiAqICAgY3JlYXRlT3JVcGRhdGUtLT4+Q2FsbGVyOiBtb2RlbFxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gY3JlYXRlT3JVcGRhdGU8XG4gIE0gZXh0ZW5kcyBNb2RlbCxcbiAgRiBleHRlbmRzIFJlcG9zaXRvcnlGbGFncyxcbj4oXG4gIG1vZGVsOiBNLFxuICBjb250ZXh0OiBDb250ZXh0PEY+LFxuICByZXBvc2l0b3J5PzogUmVwbzxNLCBGLCBDb250ZXh0PEY+PlxuKTogUHJvbWlzZTxNPiB7XG4gIGlmICghcmVwb3NpdG9yeSkge1xuICAgIGNvbnN0IGNvbnN0cnVjdG9yID0gTW9kZWwuZ2V0KG1vZGVsLmNvbnN0cnVjdG9yLm5hbWUpO1xuICAgIGlmICghY29uc3RydWN0b3IpXG4gICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihgQ291bGQgbm90IGZpbmQgbW9kZWwgJHttb2RlbC5jb25zdHJ1Y3Rvci5uYW1lfWApO1xuICAgIHJlcG9zaXRvcnkgPSBSZXBvc2l0b3J5LmZvck1vZGVsPE0sIFJlcG88TT4+KFxuICAgICAgY29uc3RydWN0b3IgYXMgdW5rbm93biBhcyBNb2RlbENvbnN0cnVjdG9yPE0+XG4gICAgKTtcbiAgfVxuICBpZiAodHlwZW9mIG1vZGVsW3JlcG9zaXRvcnkucGtdID09PSBcInVuZGVmaW5lZFwiKVxuICAgIHJldHVybiByZXBvc2l0b3J5LmNyZWF0ZShtb2RlbCwgY29udGV4dCk7XG4gIGVsc2Uge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gcmVwb3NpdG9yeS51cGRhdGUobW9kZWwsIGNvbnRleHQpO1xuICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgaWYgKCEoZSBpbnN0YW5jZW9mIE5vdEZvdW5kRXJyb3IpKSB0aHJvdyBlO1xuICAgICAgcmV0dXJuIHJlcG9zaXRvcnkuY3JlYXRlKG1vZGVsLCBjb250ZXh0KTtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gSGFuZGxlcyBvbmUtdG8tb25lIHJlbGF0aW9uc2hpcCBjcmVhdGlvblxuICogQHN1bW1hcnkgUHJvY2Vzc2VzIGEgb25lLXRvLW9uZSByZWxhdGlvbnNoaXAgd2hlbiBjcmVhdGluZyBhIG1vZGVsLCBlaXRoZXIgYnkgcmVmZXJlbmNpbmcgYW4gZXhpc3RpbmcgbW9kZWwgb3IgY3JlYXRpbmcgYSBuZXcgb25lXG4gKiBAdGVtcGxhdGUgTSAtIFRoZSBtb2RlbCB0eXBlIGV4dGVuZGluZyBNb2RlbFxuICogQHRlbXBsYXRlIFIgLSBUaGUgcmVwb3NpdG9yeSB0eXBlIGV4dGVuZGluZyBSZXBvPE0sIEYsIEM+XG4gKiBAdGVtcGxhdGUgViAtIFRoZSByZWxhdGlvbnMgbWV0YWRhdGEgdHlwZSBleHRlbmRpbmcgUmVsYXRpb25zTWV0YWRhdGFcbiAqIEB0ZW1wbGF0ZSBGIC0gVGhlIHJlcG9zaXRvcnkgZmxhZ3MgdHlwZVxuICogQHRlbXBsYXRlIEMgLSBUaGUgY29udGV4dCB0eXBlIGV4dGVuZGluZyBDb250ZXh0PEY+XG4gKiBAcGFyYW0ge1J9IHRoaXMgLSBUaGUgcmVwb3NpdG9yeSBpbnN0YW5jZVxuICogQHBhcmFtIHtDb250ZXh0PEY+fSBjb250ZXh0IC0gVGhlIGNvbnRleHQgZm9yIHRoZSBvcGVyYXRpb25cbiAqIEBwYXJhbSB7Vn0gZGF0YSAtIFRoZSByZWxhdGlvbnMgbWV0YWRhdGFcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgLSBUaGUgcHJvcGVydHkga2V5IG9mIHRoZSByZWxhdGlvbnNoaXBcbiAqIEBwYXJhbSB7TX0gbW9kZWwgLSBUaGUgbW9kZWwgaW5zdGFuY2VcbiAqIEByZXR1cm4ge1Byb21pc2U8dm9pZD59IEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdoZW4gdGhlIG9wZXJhdGlvbiBpcyBjb21wbGV0ZVxuICogQGZ1bmN0aW9uIG9uZVRvT25lT25DcmVhdGVcbiAqIEBtZW1iZXJPZiBtb2R1bGU6Y29yZVxuICogQG1lcm1haWRcbiAqIHNlcXVlbmNlRGlhZ3JhbVxuICogICBwYXJ0aWNpcGFudCBDYWxsZXJcbiAqICAgcGFydGljaXBhbnQgb25lVG9PbmVPbkNyZWF0ZVxuICogICBwYXJ0aWNpcGFudCByZXBvc2l0b3J5RnJvbVR5cGVNZXRhZGF0YVxuICogICBwYXJ0aWNpcGFudCBNb2RlbFxuICogICBwYXJ0aWNpcGFudCBSZXBvc2l0b3J5XG4gKiAgIHBhcnRpY2lwYW50IGNhY2hlTW9kZWxGb3JQb3B1bGF0ZVxuICpcbiAqICAgQ2FsbGVyLT4+b25lVG9PbmVPbkNyZWF0ZTogdGhpcywgY29udGV4dCwgZGF0YSwga2V5LCBtb2RlbFxuICogICBvbmVUb09uZU9uQ3JlYXRlLT4+b25lVG9PbmVPbkNyZWF0ZTogY2hlY2sgaWYgcHJvcGVydHlWYWx1ZSBleGlzdHNcbiAqXG4gKiAgIGFsdCBwcm9wZXJ0eVZhbHVlIGlzIG5vdCBhbiBvYmplY3RcbiAqICAgICBvbmVUb09uZU9uQ3JlYXRlLT4+cmVwb3NpdG9yeUZyb21UeXBlTWV0YWRhdGE6IG1vZGVsLCBrZXlcbiAqICAgICByZXBvc2l0b3J5RnJvbVR5cGVNZXRhZGF0YS0tPj5vbmVUb09uZU9uQ3JlYXRlOiBpbm5lclJlcG9cbiAqICAgICBvbmVUb09uZU9uQ3JlYXRlLT4+aW5uZXJSZXBvOiByZWFkKHByb3BlcnR5VmFsdWUpXG4gKiAgICAgaW5uZXJSZXBvLS0+Pm9uZVRvT25lT25DcmVhdGU6IHJlYWRcbiAqICAgICBvbmVUb09uZU9uQ3JlYXRlLT4+Y2FjaGVNb2RlbEZvclBvcHVsYXRlOiBjb250ZXh0LCBtb2RlbCwga2V5LCBwcm9wZXJ0eVZhbHVlLCByZWFkXG4gKiAgICAgb25lVG9PbmVPbkNyZWF0ZS0+Pm9uZVRvT25lT25DcmVhdGU6IHNldCBtb2RlbFtrZXldID0gcHJvcGVydHlWYWx1ZVxuICogICBlbHNlIHByb3BlcnR5VmFsdWUgaXMgYW4gb2JqZWN0XG4gKiAgICAgb25lVG9PbmVPbkNyZWF0ZS0+Pk1vZGVsOiBnZXQoZGF0YS5jbGFzcylcbiAqICAgICBNb2RlbC0tPj5vbmVUb09uZU9uQ3JlYXRlOiBjb25zdHJ1Y3RvclxuICogICAgIG9uZVRvT25lT25DcmVhdGUtPj5SZXBvc2l0b3J5OiBmb3JNb2RlbChjb25zdHJ1Y3RvcilcbiAqICAgICBSZXBvc2l0b3J5LS0+Pm9uZVRvT25lT25DcmVhdGU6IHJlcG9cbiAqICAgICBvbmVUb09uZU9uQ3JlYXRlLT4+cmVwbzogY3JlYXRlKHByb3BlcnR5VmFsdWUpXG4gKiAgICAgcmVwby0tPj5vbmVUb09uZU9uQ3JlYXRlOiBjcmVhdGVkXG4gKiAgICAgb25lVG9PbmVPbkNyZWF0ZS0+PmZpbmRQcmltYXJ5S2V5OiBjcmVhdGVkXG4gKiAgICAgZmluZFByaW1hcnlLZXktLT4+b25lVG9PbmVPbkNyZWF0ZTogcGtcbiAqICAgICBvbmVUb09uZU9uQ3JlYXRlLT4+Y2FjaGVNb2RlbEZvclBvcHVsYXRlOiBjb250ZXh0LCBtb2RlbCwga2V5LCBjcmVhdGVkW3BrXSwgY3JlYXRlZFxuICogICAgIG9uZVRvT25lT25DcmVhdGUtPj5vbmVUb09uZU9uQ3JlYXRlOiBzZXQgbW9kZWxba2V5XSA9IGNyZWF0ZWRbcGtdXG4gKiAgIGVuZFxuICpcbiAqICAgb25lVG9PbmVPbkNyZWF0ZS0tPj5DYWxsZXI6IHZvaWRcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIG9uZVRvT25lT25DcmVhdGU8XG4gIE0gZXh0ZW5kcyBNb2RlbCxcbiAgUiBleHRlbmRzIFJlcG88TSwgRiwgQz4sXG4gIFYgZXh0ZW5kcyBSZWxhdGlvbnNNZXRhZGF0YSxcbiAgRiBleHRlbmRzIFJlcG9zaXRvcnlGbGFncyxcbiAgQyBleHRlbmRzIENvbnRleHQ8Rj4sXG4+KFxuICB0aGlzOiBSLFxuICBjb250ZXh0OiBDb250ZXh0PEY+LFxuICBkYXRhOiBWLFxuICBrZXk6IGtleW9mIE0sXG4gIG1vZGVsOiBNXG4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgcHJvcGVydHlWYWx1ZTogYW55ID0gbW9kZWxba2V5XTtcbiAgaWYgKCFwcm9wZXJ0eVZhbHVlKSByZXR1cm47XG5cbiAgaWYgKHR5cGVvZiBwcm9wZXJ0eVZhbHVlICE9PSBcIm9iamVjdFwiKSB7XG4gICAgY29uc3QgaW5uZXJSZXBvID0gcmVwb3NpdG9yeUZyb21UeXBlTWV0YWRhdGEobW9kZWwsIGtleSk7XG4gICAgY29uc3QgcmVhZCA9IGF3YWl0IGlubmVyUmVwby5yZWFkKHByb3BlcnR5VmFsdWUpO1xuICAgIGF3YWl0IGNhY2hlTW9kZWxGb3JQb3B1bGF0ZShjb250ZXh0LCBtb2RlbCwga2V5LCBwcm9wZXJ0eVZhbHVlLCByZWFkKTtcbiAgICAobW9kZWwgYXMgYW55KVtrZXldID0gcHJvcGVydHlWYWx1ZTtcbiAgICByZXR1cm47XG4gIH1cblxuICBjb25zdCBjb25zdHJ1Y3RvciA9IE1vZGVsLmdldChkYXRhLmNsYXNzKTtcbiAgaWYgKCFjb25zdHJ1Y3RvcilcbiAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihgQ291bGQgbm90IGZpbmQgbW9kZWwgJHtkYXRhLmNsYXNzfWApO1xuICBjb25zdCByZXBvOiBSZXBvPGFueT4gPSBSZXBvc2l0b3J5LmZvck1vZGVsKGNvbnN0cnVjdG9yKTtcbiAgY29uc3QgY3JlYXRlZCA9IGF3YWl0IHJlcG8uY3JlYXRlKHByb3BlcnR5VmFsdWUpO1xuICBjb25zdCBwayA9IGZpbmRQcmltYXJ5S2V5KGNyZWF0ZWQpLmlkO1xuICBhd2FpdCBjYWNoZU1vZGVsRm9yUG9wdWxhdGUoY29udGV4dCwgbW9kZWwsIGtleSwgY3JlYXRlZFtwa10sIGNyZWF0ZWQpO1xuICAobW9kZWwgYXMgYW55KVtrZXldID0gY3JlYXRlZFtwa107XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEhhbmRsZXMgb25lLXRvLW9uZSByZWxhdGlvbnNoaXAgdXBkYXRlc1xuICogQHN1bW1hcnkgUHJvY2Vzc2VzIGEgb25lLXRvLW9uZSByZWxhdGlvbnNoaXAgd2hlbiB1cGRhdGluZyBhIG1vZGVsLCBlaXRoZXIgYnkgcmVmZXJlbmNpbmcgYW4gZXhpc3RpbmcgbW9kZWwgb3IgdXBkYXRpbmcgdGhlIHJlbGF0ZWQgbW9kZWxcbiAqIEB0ZW1wbGF0ZSBNIC0gVGhlIG1vZGVsIHR5cGUgZXh0ZW5kaW5nIE1vZGVsXG4gKiBAdGVtcGxhdGUgUiAtIFRoZSByZXBvc2l0b3J5IHR5cGUgZXh0ZW5kaW5nIFJlcG88TSwgRiwgQz5cbiAqIEB0ZW1wbGF0ZSBWIC0gVGhlIHJlbGF0aW9ucyBtZXRhZGF0YSB0eXBlIGV4dGVuZGluZyBSZWxhdGlvbnNNZXRhZGF0YVxuICogQHRlbXBsYXRlIEYgLSBUaGUgcmVwb3NpdG9yeSBmbGFncyB0eXBlXG4gKiBAdGVtcGxhdGUgQyAtIFRoZSBjb250ZXh0IHR5cGUgZXh0ZW5kaW5nIENvbnRleHQ8Rj5cbiAqIEBwYXJhbSB7Un0gdGhpcyAtIFRoZSByZXBvc2l0b3J5IGluc3RhbmNlXG4gKiBAcGFyYW0ge0NvbnRleHQ8Rj59IGNvbnRleHQgLSBUaGUgY29udGV4dCBmb3IgdGhlIG9wZXJhdGlvblxuICogQHBhcmFtIHtWfSBkYXRhIC0gVGhlIHJlbGF0aW9ucyBtZXRhZGF0YVxuICogQHBhcmFtIGtleSAtIFRoZSBwcm9wZXJ0eSBrZXkgb2YgdGhlIHJlbGF0aW9uc2hpcFxuICogQHBhcmFtIHtNfSBtb2RlbCAtIFRoZSBtb2RlbCBpbnN0YW5jZVxuICogQHJldHVybiB7UHJvbWlzZTx2b2lkPn0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiB0aGUgb3BlcmF0aW9uIGlzIGNvbXBsZXRlXG4gKiBAZnVuY3Rpb24gb25lVG9PbmVPblVwZGF0ZVxuICogQG1lbWJlck9mIG1vZHVsZTpjb3JlXG4gKiBAbWVybWFpZFxuICogc2VxdWVuY2VEaWFncmFtXG4gKiAgIHBhcnRpY2lwYW50IENhbGxlclxuICogICBwYXJ0aWNpcGFudCBvbmVUb09uZU9uVXBkYXRlXG4gKiAgIHBhcnRpY2lwYW50IHJlcG9zaXRvcnlGcm9tVHlwZU1ldGFkYXRhXG4gKiAgIHBhcnRpY2lwYW50IGNyZWF0ZU9yVXBkYXRlXG4gKiAgIHBhcnRpY2lwYW50IGZpbmRQcmltYXJ5S2V5XG4gKiAgIHBhcnRpY2lwYW50IGNhY2hlTW9kZWxGb3JQb3B1bGF0ZVxuICpcbiAqICAgQ2FsbGVyLT4+b25lVG9PbmVPblVwZGF0ZTogdGhpcywgY29udGV4dCwgZGF0YSwga2V5LCBtb2RlbFxuICogICBvbmVUb09uZU9uVXBkYXRlLT4+b25lVG9PbmVPblVwZGF0ZTogY2hlY2sgaWYgcHJvcGVydHlWYWx1ZSBleGlzdHNcbiAqICAgb25lVG9PbmVPblVwZGF0ZS0+Pm9uZVRvT25lT25VcGRhdGU6IGNoZWNrIGlmIGNhc2NhZGUudXBkYXRlIGlzIENBU0NBREVcbiAqXG4gKiAgIGFsdCBwcm9wZXJ0eVZhbHVlIGlzIG5vdCBhbiBvYmplY3RcbiAqICAgICBvbmVUb09uZU9uVXBkYXRlLT4+cmVwb3NpdG9yeUZyb21UeXBlTWV0YWRhdGE6IG1vZGVsLCBrZXlcbiAqICAgICByZXBvc2l0b3J5RnJvbVR5cGVNZXRhZGF0YS0tPj5vbmVUb09uZU9uVXBkYXRlOiBpbm5lclJlcG9cbiAqICAgICBvbmVUb09uZU9uVXBkYXRlLT4+aW5uZXJSZXBvOiByZWFkKHByb3BlcnR5VmFsdWUpXG4gKiAgICAgaW5uZXJSZXBvLS0+Pm9uZVRvT25lT25VcGRhdGU6IHJlYWRcbiAqICAgICBvbmVUb09uZU9uVXBkYXRlLT4+Y2FjaGVNb2RlbEZvclBvcHVsYXRlOiBjb250ZXh0LCBtb2RlbCwga2V5LCBwcm9wZXJ0eVZhbHVlLCByZWFkXG4gKiAgICAgb25lVG9PbmVPblVwZGF0ZS0+Pm9uZVRvT25lT25VcGRhdGU6IHNldCBtb2RlbFtrZXldID0gcHJvcGVydHlWYWx1ZVxuICogICBlbHNlIHByb3BlcnR5VmFsdWUgaXMgYW4gb2JqZWN0XG4gKiAgICAgb25lVG9PbmVPblVwZGF0ZS0+PmNyZWF0ZU9yVXBkYXRlOiBtb2RlbFtrZXldLCBjb250ZXh0XG4gKiAgICAgY3JlYXRlT3JVcGRhdGUtLT4+b25lVG9PbmVPblVwZGF0ZTogdXBkYXRlZFxuICogICAgIG9uZVRvT25lT25VcGRhdGUtPj5maW5kUHJpbWFyeUtleTogdXBkYXRlZFxuICogICAgIGZpbmRQcmltYXJ5S2V5LS0+Pm9uZVRvT25lT25VcGRhdGU6IHBrXG4gKiAgICAgb25lVG9PbmVPblVwZGF0ZS0+PmNhY2hlTW9kZWxGb3JQb3B1bGF0ZTogY29udGV4dCwgbW9kZWwsIGtleSwgdXBkYXRlZFtwa10sIHVwZGF0ZWRcbiAqICAgICBvbmVUb09uZU9uVXBkYXRlLT4+b25lVG9PbmVPblVwZGF0ZTogc2V0IG1vZGVsW2tleV0gPSB1cGRhdGVkW3BrXVxuICogICBlbmRcbiAqXG4gKiAgIG9uZVRvT25lT25VcGRhdGUtLT4+Q2FsbGVyOiB2b2lkXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBvbmVUb09uZU9uVXBkYXRlPFxuICBNIGV4dGVuZHMgTW9kZWwsXG4gIFIgZXh0ZW5kcyBSZXBvPE0sIEYsIEM+LFxuICBWIGV4dGVuZHMgUmVsYXRpb25zTWV0YWRhdGEsXG4gIEYgZXh0ZW5kcyBSZXBvc2l0b3J5RmxhZ3MsXG4gIEMgZXh0ZW5kcyBDb250ZXh0PEY+LFxuPihcbiAgdGhpczogUixcbiAgY29udGV4dDogQ29udGV4dDxGPixcbiAgZGF0YTogVixcbiAga2V5OiBrZXlvZiBNLFxuICBtb2RlbDogTVxuKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IHByb3BlcnR5VmFsdWU6IGFueSA9IG1vZGVsW2tleV07XG4gIGlmICghcHJvcGVydHlWYWx1ZSkgcmV0dXJuO1xuICBpZiAoZGF0YS5jYXNjYWRlLnVwZGF0ZSAhPT0gQ2FzY2FkZS5DQVNDQURFKSByZXR1cm47XG5cbiAgaWYgKHR5cGVvZiBwcm9wZXJ0eVZhbHVlICE9PSBcIm9iamVjdFwiKSB7XG4gICAgY29uc3QgaW5uZXJSZXBvID0gcmVwb3NpdG9yeUZyb21UeXBlTWV0YWRhdGEobW9kZWwsIGtleSk7XG4gICAgY29uc3QgcmVhZCA9IGF3YWl0IGlubmVyUmVwby5yZWFkKHByb3BlcnR5VmFsdWUpO1xuICAgIGF3YWl0IGNhY2hlTW9kZWxGb3JQb3B1bGF0ZShjb250ZXh0LCBtb2RlbCwga2V5LCBwcm9wZXJ0eVZhbHVlLCByZWFkKTtcbiAgICAobW9kZWwgYXMgYW55KVtrZXldID0gcHJvcGVydHlWYWx1ZTtcbiAgICByZXR1cm47XG4gIH1cblxuICBjb25zdCB1cGRhdGVkID0gYXdhaXQgY3JlYXRlT3JVcGRhdGUobW9kZWxba2V5XSBhcyBNLCBjb250ZXh0KTtcbiAgY29uc3QgcGsgPSBmaW5kUHJpbWFyeUtleSh1cGRhdGVkKS5pZDtcbiAgYXdhaXQgY2FjaGVNb2RlbEZvclBvcHVsYXRlKFxuICAgIGNvbnRleHQsXG4gICAgbW9kZWwsXG4gICAga2V5LFxuICAgIHVwZGF0ZWRbcGtdIGFzIHN0cmluZyxcbiAgICB1cGRhdGVkXG4gICk7XG4gIG1vZGVsW2tleV0gPSB1cGRhdGVkW3BrXTtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gSGFuZGxlcyBvbmUtdG8tb25lIHJlbGF0aW9uc2hpcCBkZWxldGlvblxuICogQHN1bW1hcnkgUHJvY2Vzc2VzIGEgb25lLXRvLW9uZSByZWxhdGlvbnNoaXAgd2hlbiBkZWxldGluZyBhIG1vZGVsLCBkZWxldGluZyB0aGUgcmVsYXRlZCBtb2RlbCBpZiBjYXNjYWRlIGlzIGVuYWJsZWRcbiAqIEB0ZW1wbGF0ZSBNIC0gVGhlIG1vZGVsIHR5cGUgZXh0ZW5kaW5nIE1vZGVsXG4gKiBAdGVtcGxhdGUgUiAtIFRoZSByZXBvc2l0b3J5IHR5cGUgZXh0ZW5kaW5nIFJlcG88TSwgRiwgQz5cbiAqIEB0ZW1wbGF0ZSBWIC0gVGhlIHJlbGF0aW9ucyBtZXRhZGF0YSB0eXBlIGV4dGVuZGluZyBSZWxhdGlvbnNNZXRhZGF0YVxuICogQHRlbXBsYXRlIEYgLSBUaGUgcmVwb3NpdG9yeSBmbGFncyB0eXBlXG4gKiBAdGVtcGxhdGUgQyAtIFRoZSBjb250ZXh0IHR5cGUgZXh0ZW5kaW5nIENvbnRleHQ8Rj5cbiAqIEBwYXJhbSB7Un0gdGhpcyAtIFRoZSByZXBvc2l0b3J5IGluc3RhbmNlXG4gKiBAcGFyYW0ge0NvbnRleHQ8Rj59IGNvbnRleHQgLSBUaGUgY29udGV4dCBmb3IgdGhlIG9wZXJhdGlvblxuICogQHBhcmFtIHtWfSBkYXRhIC0gVGhlIHJlbGF0aW9ucyBtZXRhZGF0YVxuICogQHBhcmFtIGtleSAtIFRoZSBwcm9wZXJ0eSBrZXkgb2YgdGhlIHJlbGF0aW9uc2hpcFxuICogQHBhcmFtIHtNfSBtb2RlbCAtIFRoZSBtb2RlbCBpbnN0YW5jZVxuICogQHJldHVybiB7UHJvbWlzZTx2b2lkPn0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiB0aGUgb3BlcmF0aW9uIGlzIGNvbXBsZXRlXG4gKiBAZnVuY3Rpb24gb25lVG9PbmVPbkRlbGV0ZVxuICogQG1lbWJlck9mIG1vZHVsZTpjb3JlXG4gKiBAbWVybWFpZFxuICogc2VxdWVuY2VEaWFncmFtXG4gKiAgIHBhcnRpY2lwYW50IENhbGxlclxuICogICBwYXJ0aWNpcGFudCBvbmVUb09uZU9uRGVsZXRlXG4gKiAgIHBhcnRpY2lwYW50IHJlcG9zaXRvcnlGcm9tVHlwZU1ldGFkYXRhXG4gKiAgIHBhcnRpY2lwYW50IGNhY2hlTW9kZWxGb3JQb3B1bGF0ZVxuICpcbiAqICAgQ2FsbGVyLT4+b25lVG9PbmVPbkRlbGV0ZTogdGhpcywgY29udGV4dCwgZGF0YSwga2V5LCBtb2RlbFxuICogICBvbmVUb09uZU9uRGVsZXRlLT4+b25lVG9PbmVPbkRlbGV0ZTogY2hlY2sgaWYgcHJvcGVydHlWYWx1ZSBleGlzdHNcbiAqICAgb25lVG9PbmVPbkRlbGV0ZS0+Pm9uZVRvT25lT25EZWxldGU6IGNoZWNrIGlmIGNhc2NhZGUudXBkYXRlIGlzIENBU0NBREVcbiAqXG4gKiAgIG9uZVRvT25lT25EZWxldGUtPj5yZXBvc2l0b3J5RnJvbVR5cGVNZXRhZGF0YTogbW9kZWwsIGtleVxuICogICByZXBvc2l0b3J5RnJvbVR5cGVNZXRhZGF0YS0tPj5vbmVUb09uZU9uRGVsZXRlOiBpbm5lclJlcG9cbiAqXG4gKiAgIGFsdCBwcm9wZXJ0eVZhbHVlIGlzIG5vdCBhIE1vZGVsIGluc3RhbmNlXG4gKiAgICAgb25lVG9PbmVPbkRlbGV0ZS0+PmlubmVyUmVwbzogZGVsZXRlKG1vZGVsW2tleV0sIGNvbnRleHQpXG4gKiAgICAgaW5uZXJSZXBvLS0+Pm9uZVRvT25lT25EZWxldGU6IGRlbGV0ZWRcbiAqICAgZWxzZSBwcm9wZXJ0eVZhbHVlIGlzIGEgTW9kZWwgaW5zdGFuY2VcbiAqICAgICBvbmVUb09uZU9uRGVsZXRlLT4+aW5uZXJSZXBvOiBkZWxldGUobW9kZWxba2V5XVtpbm5lclJlcG8ucGtdLCBjb250ZXh0KVxuICogICAgIGlubmVyUmVwby0tPj5vbmVUb09uZU9uRGVsZXRlOiBkZWxldGVkXG4gKiAgIGVuZFxuICpcbiAqICAgb25lVG9PbmVPbkRlbGV0ZS0+PmNhY2hlTW9kZWxGb3JQb3B1bGF0ZTogY29udGV4dCwgbW9kZWwsIGtleSwgZGVsZXRlZFtpbm5lclJlcG8ucGtdLCBkZWxldGVkXG4gKiAgIG9uZVRvT25lT25EZWxldGUtLT4+Q2FsbGVyOiB2b2lkXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBvbmVUb09uZU9uRGVsZXRlPFxuICBNIGV4dGVuZHMgTW9kZWwsXG4gIFIgZXh0ZW5kcyBSZXBvPE0sIEYsIEM+LFxuICBWIGV4dGVuZHMgUmVsYXRpb25zTWV0YWRhdGEsXG4gIEYgZXh0ZW5kcyBSZXBvc2l0b3J5RmxhZ3MsXG4gIEMgZXh0ZW5kcyBDb250ZXh0PEY+LFxuPihcbiAgdGhpczogUixcbiAgY29udGV4dDogQ29udGV4dDxGPixcbiAgZGF0YTogVixcbiAga2V5OiBrZXlvZiBNLFxuICBtb2RlbDogTVxuKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IHByb3BlcnR5VmFsdWU6IGFueSA9IG1vZGVsW2tleV07XG4gIGlmICghcHJvcGVydHlWYWx1ZSkgcmV0dXJuO1xuICBpZiAoZGF0YS5jYXNjYWRlLnVwZGF0ZSAhPT0gQ2FzY2FkZS5DQVNDQURFKSByZXR1cm47XG4gIGNvbnN0IGlubmVyUmVwbzogUmVwbzxNPiA9IHJlcG9zaXRvcnlGcm9tVHlwZU1ldGFkYXRhKG1vZGVsLCBrZXkpO1xuICBsZXQgZGVsZXRlZDogTTtcbiAgaWYgKCEocHJvcGVydHlWYWx1ZSBpbnN0YW5jZW9mIE1vZGVsKSlcbiAgICBkZWxldGVkID0gYXdhaXQgaW5uZXJSZXBvLmRlbGV0ZShtb2RlbFtrZXldIGFzIHN0cmluZywgY29udGV4dCk7XG4gIGVsc2VcbiAgICBkZWxldGVkID0gYXdhaXQgaW5uZXJSZXBvLmRlbGV0ZShcbiAgICAgIChtb2RlbFtrZXldIGFzIE0pW2lubmVyUmVwby5wayBhcyBrZXlvZiBNXSBhcyBzdHJpbmcsXG4gICAgICBjb250ZXh0XG4gICAgKTtcbiAgYXdhaXQgY2FjaGVNb2RlbEZvclBvcHVsYXRlKFxuICAgIGNvbnRleHQsXG4gICAgbW9kZWwsXG4gICAga2V5LFxuICAgIGRlbGV0ZWRbaW5uZXJSZXBvLnBrXSBhcyBzdHJpbmcsXG4gICAgZGVsZXRlZFxuICApO1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBIYW5kbGVzIG9uZS10by1tYW55IHJlbGF0aW9uc2hpcCBjcmVhdGlvblxuICogQHN1bW1hcnkgUHJvY2Vzc2VzIGEgb25lLXRvLW1hbnkgcmVsYXRpb25zaGlwIHdoZW4gY3JlYXRpbmcgYSBtb2RlbCwgZWl0aGVyIGJ5IHJlZmVyZW5jaW5nIGV4aXN0aW5nIG1vZGVscyBvciBjcmVhdGluZyBuZXcgb25lc1xuICogQHRlbXBsYXRlIE0gLSBUaGUgbW9kZWwgdHlwZSBleHRlbmRpbmcgTW9kZWxcbiAqIEB0ZW1wbGF0ZSBSIC0gVGhlIHJlcG9zaXRvcnkgdHlwZSBleHRlbmRpbmcgUmVwbzxNLCBGLCBDPlxuICogQHRlbXBsYXRlIFYgLSBUaGUgcmVsYXRpb25zIG1ldGFkYXRhIHR5cGUgZXh0ZW5kaW5nIFJlbGF0aW9uc01ldGFkYXRhXG4gKiBAdGVtcGxhdGUgRiAtIFRoZSByZXBvc2l0b3J5IGZsYWdzIHR5cGVcbiAqIEB0ZW1wbGF0ZSBDIC0gVGhlIGNvbnRleHQgdHlwZSBleHRlbmRpbmcgQ29udGV4dDxGPlxuICogQHBhcmFtIHtSfSB0aGlzIC0gVGhlIHJlcG9zaXRvcnkgaW5zdGFuY2VcbiAqIEBwYXJhbSB7Q29udGV4dDxGPn0gY29udGV4dCAtIFRoZSBjb250ZXh0IGZvciB0aGUgb3BlcmF0aW9uXG4gKiBAcGFyYW0ge1Z9IGRhdGEgLSBUaGUgcmVsYXRpb25zIG1ldGFkYXRhXG4gKiBAcGFyYW0ga2V5IC0gVGhlIHByb3BlcnR5IGtleSBvZiB0aGUgcmVsYXRpb25zaGlwXG4gKiBAcGFyYW0ge019IG1vZGVsIC0gVGhlIG1vZGVsIGluc3RhbmNlXG4gKiBAcmV0dXJuIHtQcm9taXNlPHZvaWQ+fSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIHRoZSBvcGVyYXRpb24gaXMgY29tcGxldGVcbiAqIEBmdW5jdGlvbiBvbmVUb01hbnlPbkNyZWF0ZVxuICogQG1lbWJlck9mIG1vZHVsZTpjb3JlXG4gKiBAbWVybWFpZFxuICogc2VxdWVuY2VEaWFncmFtXG4gKiAgIHBhcnRpY2lwYW50IENhbGxlclxuICogICBwYXJ0aWNpcGFudCBvbmVUb01hbnlPbkNyZWF0ZVxuICogICBwYXJ0aWNpcGFudCByZXBvc2l0b3J5RnJvbVR5cGVNZXRhZGF0YVxuICogICBwYXJ0aWNpcGFudCBjcmVhdGVPclVwZGF0ZVxuICogICBwYXJ0aWNpcGFudCBmaW5kUHJpbWFyeUtleVxuICogICBwYXJ0aWNpcGFudCBjYWNoZU1vZGVsRm9yUG9wdWxhdGVcbiAqXG4gKiAgIENhbGxlci0+Pm9uZVRvTWFueU9uQ3JlYXRlOiB0aGlzLCBjb250ZXh0LCBkYXRhLCBrZXksIG1vZGVsXG4gKiAgIG9uZVRvTWFueU9uQ3JlYXRlLT4+b25lVG9NYW55T25DcmVhdGU6IGNoZWNrIGlmIHByb3BlcnR5VmFsdWVzIGV4aXN0cyBhbmQgaGFzIGxlbmd0aFxuICogICBvbmVUb01hbnlPbkNyZWF0ZS0+Pm9uZVRvTWFueU9uQ3JlYXRlOiBjaGVjayBpZiBhbGwgZWxlbWVudHMgaGF2ZSBzYW1lIHR5cGVcbiAqICAgb25lVG9NYW55T25DcmVhdGUtPj5vbmVUb01hbnlPbkNyZWF0ZTogY3JlYXRlIHVuaXF1ZVZhbHVlcyBzZXRcbiAqXG4gKiAgIGFsdCBhcnJheVR5cGUgaXMgbm90IFwib2JqZWN0XCJcbiAqICAgICBvbmVUb01hbnlPbkNyZWF0ZS0+PnJlcG9zaXRvcnlGcm9tVHlwZU1ldGFkYXRhOiBtb2RlbCwga2V5XG4gKiAgICAgcmVwb3NpdG9yeUZyb21UeXBlTWV0YWRhdGEtLT4+b25lVG9NYW55T25DcmVhdGU6IHJlcG9cbiAqICAgICBsb29wIGZvciBlYWNoIGlkIGluIHVuaXF1ZVZhbHVlc1xuICogICAgICAgb25lVG9NYW55T25DcmVhdGUtPj5yZXBvOiByZWFkKGlkKVxuICogICAgICAgcmVwby0tPj5vbmVUb01hbnlPbkNyZWF0ZTogcmVhZFxuICogICAgICAgb25lVG9NYW55T25DcmVhdGUtPj5jYWNoZU1vZGVsRm9yUG9wdWxhdGU6IGNvbnRleHQsIG1vZGVsLCBrZXksIGlkLCByZWFkXG4gKiAgICAgZW5kXG4gKiAgICAgb25lVG9NYW55T25DcmVhdGUtPj5vbmVUb01hbnlPbkNyZWF0ZTogc2V0IG1vZGVsW2tleV0gPSBbLi4udW5pcXVlVmFsdWVzXVxuICogICBlbHNlIGFycmF5VHlwZSBpcyBcIm9iamVjdFwiXG4gKiAgICAgb25lVG9NYW55T25DcmVhdGUtPj5maW5kUHJpbWFyeUtleTogcHJvcGVydHlWYWx1ZXNbMF1cbiAqICAgICBmaW5kUHJpbWFyeUtleS0tPj5vbmVUb01hbnlPbkNyZWF0ZTogcGtOYW1lXG4gKiAgICAgb25lVG9NYW55T25DcmVhdGUtPj5vbmVUb01hbnlPbkNyZWF0ZTogY3JlYXRlIHJlc3VsdCBzZXRcbiAqICAgICBsb29wIGZvciBlYWNoIG0gaW4gcHJvcGVydHlWYWx1ZXNcbiAqICAgICAgIG9uZVRvTWFueU9uQ3JlYXRlLT4+Y3JlYXRlT3JVcGRhdGU6IG0sIGNvbnRleHRcbiAqICAgICAgIGNyZWF0ZU9yVXBkYXRlLS0+Pm9uZVRvTWFueU9uQ3JlYXRlOiByZWNvcmRcbiAqICAgICAgIG9uZVRvTWFueU9uQ3JlYXRlLT4+Y2FjaGVNb2RlbEZvclBvcHVsYXRlOiBjb250ZXh0LCBtb2RlbCwga2V5LCByZWNvcmRbcGtOYW1lXSwgcmVjb3JkXG4gKiAgICAgICBvbmVUb01hbnlPbkNyZWF0ZS0+Pm9uZVRvTWFueU9uQ3JlYXRlOiBhZGQgcmVjb3JkW3BrTmFtZV0gdG8gcmVzdWx0XG4gKiAgICAgZW5kXG4gKiAgICAgb25lVG9NYW55T25DcmVhdGUtPj5vbmVUb01hbnlPbkNyZWF0ZTogc2V0IG1vZGVsW2tleV0gPSBbLi4ucmVzdWx0XVxuICogICBlbmRcbiAqXG4gKiAgIG9uZVRvTWFueU9uQ3JlYXRlLS0+PkNhbGxlcjogdm9pZFxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gb25lVG9NYW55T25DcmVhdGU8XG4gIE0gZXh0ZW5kcyBNb2RlbCxcbiAgUiBleHRlbmRzIFJlcG88TSwgRiwgQz4sXG4gIFYgZXh0ZW5kcyBSZWxhdGlvbnNNZXRhZGF0YSxcbiAgRiBleHRlbmRzIFJlcG9zaXRvcnlGbGFncyxcbiAgQyBleHRlbmRzIENvbnRleHQ8Rj4sXG4+KFxuICB0aGlzOiBSLFxuICBjb250ZXh0OiBDb250ZXh0PEY+LFxuICBkYXRhOiBWLFxuICBrZXk6IGtleW9mIE0sXG4gIG1vZGVsOiBNXG4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgcHJvcGVydHlWYWx1ZXM6IGFueSA9IG1vZGVsW2tleV07XG4gIGlmICghcHJvcGVydHlWYWx1ZXMgfHwgIXByb3BlcnR5VmFsdWVzLmxlbmd0aCkgcmV0dXJuO1xuICBjb25zdCBhcnJheVR5cGUgPSB0eXBlb2YgcHJvcGVydHlWYWx1ZXNbMF07XG4gIGlmICghcHJvcGVydHlWYWx1ZXMuZXZlcnkoKGl0ZW06IGFueSkgPT4gdHlwZW9mIGl0ZW0gPT09IGFycmF5VHlwZSkpXG4gICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXG4gICAgICBgSW52YWxpZCBvcGVyYXRpb24uIEFsbCBlbGVtZW50cyBvZiBwcm9wZXJ0eSAke2tleSBhcyBzdHJpbmd9IG11c3QgbWF0Y2ggdGhlIHNhbWUgdHlwZS5gXG4gICAgKTtcbiAgY29uc3QgdW5pcXVlVmFsdWVzID0gbmV3IFNldChbLi4ucHJvcGVydHlWYWx1ZXNdKTtcbiAgaWYgKGFycmF5VHlwZSAhPT0gXCJvYmplY3RcIikge1xuICAgIGNvbnN0IHJlcG8gPSByZXBvc2l0b3J5RnJvbVR5cGVNZXRhZGF0YShtb2RlbCwga2V5KTtcbiAgICBmb3IgKGNvbnN0IGlkIG9mIHVuaXF1ZVZhbHVlcykge1xuICAgICAgY29uc3QgcmVhZCA9IGF3YWl0IHJlcG8ucmVhZChpZCk7XG4gICAgICBhd2FpdCBjYWNoZU1vZGVsRm9yUG9wdWxhdGUoY29udGV4dCwgbW9kZWwsIGtleSwgaWQsIHJlYWQpO1xuICAgIH1cbiAgICAobW9kZWwgYXMgYW55KVtrZXldID0gWy4uLnVuaXF1ZVZhbHVlc107XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgY29uc3QgcGtOYW1lID0gZmluZFByaW1hcnlLZXkocHJvcGVydHlWYWx1ZXNbMF0pLmlkO1xuXG4gIGNvbnN0IHJlc3VsdDogU2V0PHN0cmluZz4gPSBuZXcgU2V0KCk7XG5cbiAgZm9yIChjb25zdCBtIG9mIHByb3BlcnR5VmFsdWVzKSB7XG4gICAgY29uc3QgcmVjb3JkID0gYXdhaXQgY3JlYXRlT3JVcGRhdGUobSwgY29udGV4dCk7XG4gICAgYXdhaXQgY2FjaGVNb2RlbEZvclBvcHVsYXRlKGNvbnRleHQsIG1vZGVsLCBrZXksIHJlY29yZFtwa05hbWVdLCByZWNvcmQpO1xuICAgIHJlc3VsdC5hZGQocmVjb3JkW3BrTmFtZV0pO1xuICB9XG5cbiAgKG1vZGVsIGFzIGFueSlba2V5XSA9IFsuLi5yZXN1bHRdO1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBIYW5kbGVzIG9uZS10by1tYW55IHJlbGF0aW9uc2hpcCB1cGRhdGVzXG4gKiBAc3VtbWFyeSBQcm9jZXNzZXMgYSBvbmUtdG8tbWFueSByZWxhdGlvbnNoaXAgd2hlbiB1cGRhdGluZyBhIG1vZGVsLCBkZWxlZ2F0aW5nIHRvIG9uZVRvTWFueU9uQ3JlYXRlIGlmIGNhc2NhZGUgdXBkYXRlIGlzIGVuYWJsZWRcbiAqIEB0ZW1wbGF0ZSBNIC0gVGhlIG1vZGVsIHR5cGUgZXh0ZW5kaW5nIE1vZGVsXG4gKiBAdGVtcGxhdGUgUiAtIFRoZSByZXBvc2l0b3J5IHR5cGUgZXh0ZW5kaW5nIFJlcG88TSwgRiwgQz5cbiAqIEB0ZW1wbGF0ZSBWIC0gVGhlIHJlbGF0aW9ucyBtZXRhZGF0YSB0eXBlIGV4dGVuZGluZyBSZWxhdGlvbnNNZXRhZGF0YVxuICogQHRlbXBsYXRlIEYgLSBUaGUgcmVwb3NpdG9yeSBmbGFncyB0eXBlXG4gKiBAdGVtcGxhdGUgQyAtIFRoZSBjb250ZXh0IHR5cGUgZXh0ZW5kaW5nIENvbnRleHQ8Rj5cbiAqIEBwYXJhbSB7Un0gdGhpcyAtIFRoZSByZXBvc2l0b3J5IGluc3RhbmNlXG4gKiBAcGFyYW0ge0NvbnRleHQ8Rj59IGNvbnRleHQgLSBUaGUgY29udGV4dCBmb3IgdGhlIG9wZXJhdGlvblxuICogQHBhcmFtIHtWfSBkYXRhIC0gVGhlIHJlbGF0aW9ucyBtZXRhZGF0YVxuICogQHBhcmFtIGtleSAtIFRoZSBwcm9wZXJ0eSBrZXkgb2YgdGhlIHJlbGF0aW9uc2hpcFxuICogQHBhcmFtIHtNfSBtb2RlbCAtIFRoZSBtb2RlbCBpbnN0YW5jZVxuICogQHJldHVybiB7UHJvbWlzZTx2b2lkPn0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiB0aGUgb3BlcmF0aW9uIGlzIGNvbXBsZXRlXG4gKiBAZnVuY3Rpb24gb25lVG9NYW55T25VcGRhdGVcbiAqIEBtZW1iZXJPZiBtb2R1bGU6Y29yZVxuICogQG1lcm1haWRcbiAqIHNlcXVlbmNlRGlhZ3JhbVxuICogICBwYXJ0aWNpcGFudCBDYWxsZXJcbiAqICAgcGFydGljaXBhbnQgb25lVG9NYW55T25VcGRhdGVcbiAqICAgcGFydGljaXBhbnQgb25lVG9NYW55T25DcmVhdGVcbiAqXG4gKiAgIENhbGxlci0+Pm9uZVRvTWFueU9uVXBkYXRlOiB0aGlzLCBjb250ZXh0LCBkYXRhLCBrZXksIG1vZGVsXG4gKiAgIG9uZVRvTWFueU9uVXBkYXRlLT4+b25lVG9NYW55T25VcGRhdGU6IGNoZWNrIGlmIGNhc2NhZGUudXBkYXRlIGlzIENBU0NBREVcbiAqXG4gKiAgIGFsdCBjYXNjYWRlLnVwZGF0ZSBpcyBDQVNDQURFXG4gKiAgICAgb25lVG9NYW55T25VcGRhdGUtPj5vbmVUb01hbnlPbkNyZWF0ZTogYXBwbHkodGhpcywgW2NvbnRleHQsIGRhdGEsIGtleSwgbW9kZWxdKVxuICogICAgIG9uZVRvTWFueU9uQ3JlYXRlLS0+Pm9uZVRvTWFueU9uVXBkYXRlOiB2b2lkXG4gKiAgIGVuZFxuICpcbiAqICAgb25lVG9NYW55T25VcGRhdGUtLT4+Q2FsbGVyOiB2b2lkXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBvbmVUb01hbnlPblVwZGF0ZTxcbiAgTSBleHRlbmRzIE1vZGVsLFxuICBSIGV4dGVuZHMgUmVwbzxNLCBGLCBDPixcbiAgViBleHRlbmRzIFJlbGF0aW9uc01ldGFkYXRhLFxuICBGIGV4dGVuZHMgUmVwb3NpdG9yeUZsYWdzLFxuICBDIGV4dGVuZHMgQ29udGV4dDxGPixcbj4oXG4gIHRoaXM6IFIsXG4gIGNvbnRleHQ6IENvbnRleHQ8Rj4sXG4gIGRhdGE6IFYsXG4gIGtleToga2V5b2YgTSxcbiAgbW9kZWw6IE1cbik6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCB7IGNhc2NhZGUgfSA9IGRhdGE7XG4gIGlmIChjYXNjYWRlLnVwZGF0ZSAhPT0gQ2FzY2FkZS5DQVNDQURFKSByZXR1cm47XG4gIHJldHVybiBvbmVUb01hbnlPbkNyZWF0ZS5hcHBseSh0aGlzIGFzIGFueSwgW1xuICAgIGNvbnRleHQsXG4gICAgZGF0YSxcbiAgICBrZXkgYXMga2V5b2YgTW9kZWwsXG4gICAgbW9kZWwsXG4gIF0pO1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBIYW5kbGVzIG9uZS10by1tYW55IHJlbGF0aW9uc2hpcCBkZWxldGlvblxuICogQHN1bW1hcnkgUHJvY2Vzc2VzIGEgb25lLXRvLW1hbnkgcmVsYXRpb25zaGlwIHdoZW4gZGVsZXRpbmcgYSBtb2RlbCwgZGVsZXRpbmcgYWxsIHJlbGF0ZWQgbW9kZWxzIGlmIGNhc2NhZGUgZGVsZXRlIGlzIGVuYWJsZWRcbiAqIEB0ZW1wbGF0ZSBNIC0gVGhlIG1vZGVsIHR5cGUgZXh0ZW5kaW5nIE1vZGVsXG4gKiBAdGVtcGxhdGUgUiAtIFRoZSByZXBvc2l0b3J5IHR5cGUgZXh0ZW5kaW5nIFJlcG88TSwgRiwgQz5cbiAqIEB0ZW1wbGF0ZSBWIC0gVGhlIHJlbGF0aW9ucyBtZXRhZGF0YSB0eXBlIGV4dGVuZGluZyBSZWxhdGlvbnNNZXRhZGF0YVxuICogQHRlbXBsYXRlIEYgLSBUaGUgcmVwb3NpdG9yeSBmbGFncyB0eXBlXG4gKiBAdGVtcGxhdGUgQyAtIFRoZSBjb250ZXh0IHR5cGUgZXh0ZW5kaW5nIENvbnRleHQ8Rj5cbiAqIEBwYXJhbSB7Un0gdGhpcyAtIFRoZSByZXBvc2l0b3J5IGluc3RhbmNlXG4gKiBAcGFyYW0ge0NvbnRleHQ8Rj59IGNvbnRleHQgLSBUaGUgY29udGV4dCBmb3IgdGhlIG9wZXJhdGlvblxuICogQHBhcmFtIHtWfSBkYXRhIC0gVGhlIHJlbGF0aW9ucyBtZXRhZGF0YVxuICogQHBhcmFtIGtleSAtIFRoZSBwcm9wZXJ0eSBrZXkgb2YgdGhlIHJlbGF0aW9uc2hpcFxuICogQHBhcmFtIHtNfSBtb2RlbCAtIFRoZSBtb2RlbCBpbnN0YW5jZVxuICogQHJldHVybiB7UHJvbWlzZTx2b2lkPn0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiB0aGUgb3BlcmF0aW9uIGlzIGNvbXBsZXRlXG4gKiBAZnVuY3Rpb24gb25lVG9NYW55T25EZWxldGVcbiAqIEBtZW1iZXJPZiBtb2R1bGU6Y29yZVxuICogQG1lcm1haWRcbiAqIHNlcXVlbmNlRGlhZ3JhbVxuICogICBwYXJ0aWNpcGFudCBDYWxsZXJcbiAqICAgcGFydGljaXBhbnQgb25lVG9NYW55T25EZWxldGVcbiAqICAgcGFydGljaXBhbnQgUmVwb3NpdG9yeVxuICogICBwYXJ0aWNpcGFudCByZXBvc2l0b3J5RnJvbVR5cGVNZXRhZGF0YVxuICogICBwYXJ0aWNpcGFudCBjYWNoZU1vZGVsRm9yUG9wdWxhdGVcbiAqXG4gKiAgIENhbGxlci0+Pm9uZVRvTWFueU9uRGVsZXRlOiB0aGlzLCBjb250ZXh0LCBkYXRhLCBrZXksIG1vZGVsXG4gKiAgIG9uZVRvTWFueU9uRGVsZXRlLT4+b25lVG9NYW55T25EZWxldGU6IGNoZWNrIGlmIGNhc2NhZGUuZGVsZXRlIGlzIENBU0NBREVcbiAqICAgb25lVG9NYW55T25EZWxldGUtPj5vbmVUb01hbnlPbkRlbGV0ZTogY2hlY2sgaWYgdmFsdWVzIGV4aXN0cyBhbmQgaGFzIGxlbmd0aFxuICogICBvbmVUb01hbnlPbkRlbGV0ZS0+Pm9uZVRvTWFueU9uRGVsZXRlOiBjaGVjayBpZiBhbGwgZWxlbWVudHMgaGF2ZSBzYW1lIHR5cGVcbiAqXG4gKiAgIGFsdCBpc0luc3RhbnRpYXRlZCAoYXJyYXlUeXBlIGlzIFwib2JqZWN0XCIpXG4gKiAgICAgb25lVG9NYW55T25EZWxldGUtPj5SZXBvc2l0b3J5OiBmb3JNb2RlbCh2YWx1ZXNbMF0pXG4gKiAgICAgUmVwb3NpdG9yeS0tPj5vbmVUb01hbnlPbkRlbGV0ZTogcmVwb1xuICogICBlbHNlIG5vdCBpbnN0YW50aWF0ZWRcbiAqICAgICBvbmVUb01hbnlPbkRlbGV0ZS0+PnJlcG9zaXRvcnlGcm9tVHlwZU1ldGFkYXRhOiBtb2RlbCwga2V5XG4gKiAgICAgcmVwb3NpdG9yeUZyb21UeXBlTWV0YWRhdGEtLT4+b25lVG9NYW55T25EZWxldGU6IHJlcG9cbiAqICAgZW5kXG4gKlxuICogICBvbmVUb01hbnlPbkRlbGV0ZS0+Pm9uZVRvTWFueU9uRGVsZXRlOiBjcmVhdGUgdW5pcXVlVmFsdWVzIHNldFxuICpcbiAqICAgbG9vcCBmb3IgZWFjaCBpZCBpbiB1bmlxdWVWYWx1ZXNcbiAqICAgICBvbmVUb01hbnlPbkRlbGV0ZS0+PnJlcG86IGRlbGV0ZShpZCwgY29udGV4dClcbiAqICAgICByZXBvLS0+Pm9uZVRvTWFueU9uRGVsZXRlOiBkZWxldGVkXG4gKiAgICAgb25lVG9NYW55T25EZWxldGUtPj5jYWNoZU1vZGVsRm9yUG9wdWxhdGU6IGNvbnRleHQsIG1vZGVsLCBrZXksIGlkLCBkZWxldGVkXG4gKiAgIGVuZFxuICpcbiAqICAgb25lVG9NYW55T25EZWxldGUtPj5vbmVUb01hbnlPbkRlbGV0ZTogc2V0IG1vZGVsW2tleV0gPSBbLi4udW5pcXVlVmFsdWVzXVxuICogICBvbmVUb01hbnlPbkRlbGV0ZS0tPj5DYWxsZXI6IHZvaWRcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIG9uZVRvTWFueU9uRGVsZXRlPFxuICBNIGV4dGVuZHMgTW9kZWwsXG4gIFIgZXh0ZW5kcyBSZXBvPE0sIEYsIEM+LFxuICBWIGV4dGVuZHMgUmVsYXRpb25zTWV0YWRhdGEsXG4gIEYgZXh0ZW5kcyBSZXBvc2l0b3J5RmxhZ3MsXG4gIEMgZXh0ZW5kcyBDb250ZXh0PEY+LFxuPihcbiAgdGhpczogUixcbiAgY29udGV4dDogQ29udGV4dDxGPixcbiAgZGF0YTogVixcbiAga2V5OiBrZXlvZiBNLFxuICBtb2RlbDogTVxuKTogUHJvbWlzZTx2b2lkPiB7XG4gIGlmIChkYXRhLmNhc2NhZGUuZGVsZXRlICE9PSBDYXNjYWRlLkNBU0NBREUpIHJldHVybjtcbiAgY29uc3QgdmFsdWVzID0gbW9kZWxba2V5XSBhcyBhbnk7XG4gIGlmICghdmFsdWVzIHx8ICF2YWx1ZXMubGVuZ3RoKSByZXR1cm47XG4gIGNvbnN0IGFycmF5VHlwZSA9IHR5cGVvZiB2YWx1ZXNbMF07XG4gIGNvbnN0IGFyZUFsbFNhbWVUeXBlID0gdmFsdWVzLmV2ZXJ5KChpdGVtOiBhbnkpID0+IHR5cGVvZiBpdGVtID09PSBhcnJheVR5cGUpO1xuICBpZiAoIWFyZUFsbFNhbWVUeXBlKVxuICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFxuICAgICAgYEludmFsaWQgb3BlcmF0aW9uLiBBbGwgZWxlbWVudHMgb2YgcHJvcGVydHkgJHtrZXkgYXMgc3RyaW5nfSBtdXN0IG1hdGNoIHRoZSBzYW1lIHR5cGUuYFxuICAgICk7XG4gIGNvbnN0IGlzSW5zdGFudGlhdGVkID0gYXJyYXlUeXBlID09PSBcIm9iamVjdFwiO1xuICBjb25zdCByZXBvID0gaXNJbnN0YW50aWF0ZWRcbiAgICA/IFJlcG9zaXRvcnkuZm9yTW9kZWwodmFsdWVzWzBdLHRoaXMuYWRhcHRlci5hbGlhcylcbiAgICA6IHJlcG9zaXRvcnlGcm9tVHlwZU1ldGFkYXRhKG1vZGVsLCBrZXkpO1xuXG4gIGNvbnN0IHVuaXF1ZVZhbHVlcyA9IG5ldyBTZXQoW1xuICAgIC4uLihpc0luc3RhbnRpYXRlZFxuICAgICAgPyB2YWx1ZXMubWFwKCh2OiBSZWNvcmQ8c3RyaW5nLCBhbnk+KSA9PiB2W3JlcG8ucGsgYXMgc3RyaW5nXSlcbiAgICAgIDogdmFsdWVzKSxcbiAgXSk7XG5cbiAgZm9yIChjb25zdCBpZCBvZiB1bmlxdWVWYWx1ZXMudmFsdWVzKCkpIHtcbiAgICBjb25zdCBkZWxldGVkID0gYXdhaXQgcmVwby5kZWxldGUoaWQsIGNvbnRleHQpO1xuICAgIGF3YWl0IGNhY2hlTW9kZWxGb3JQb3B1bGF0ZShjb250ZXh0LCBtb2RlbCwga2V5LCBpZCwgZGVsZXRlZCk7XG4gIH1cbiAgKG1vZGVsIGFzIGFueSlba2V5XSA9IFsuLi51bmlxdWVWYWx1ZXNdO1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBHZW5lcmF0ZXMgYSBrZXkgZm9yIGNhY2hpbmcgcG9wdWxhdGVkIG1vZGVsIHJlbGF0aW9uc2hpcHNcbiAqIEBzdW1tYXJ5IENyZWF0ZXMgYSB1bmlxdWUga2V5IGZvciBzdG9yaW5nIGFuZCByZXRyaWV2aW5nIHBvcHVsYXRlZCBtb2RlbCByZWxhdGlvbnNoaXBzIGluIHRoZSBjYWNoZVxuICogQHBhcmFtIHtzdHJpbmd9IHRhYmxlTmFtZSAtIFRoZSBuYW1lIG9mIHRoZSB0YWJsZSBvciBtb2RlbFxuICogQHBhcmFtIHtzdHJpbmd9IGZpZWxkTmFtZSAtIFRoZSBuYW1lIG9mIHRoZSBmaWVsZCBvciBwcm9wZXJ0eVxuICogQHBhcmFtIHtzdHJpbmd8bnVtYmVyfSBpZCAtIFRoZSBpZGVudGlmaWVyIG9mIHRoZSByZWxhdGVkIG1vZGVsXG4gKiBAcmV0dXJuIHtzdHJpbmd9IEEgZG90LXNlcGFyYXRlZCBzdHJpbmcgdGhhdCB1bmlxdWVseSBpZGVudGlmaWVzIHRoZSByZWxhdGlvbnNoaXBcbiAqIEBmdW5jdGlvbiBnZXRQb3B1bGF0ZUtleVxuICogQG1lbWJlck9mIG1vZHVsZTpjb3JlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRQb3B1bGF0ZUtleShcbiAgdGFibGVOYW1lOiBzdHJpbmcsXG4gIGZpZWxkTmFtZTogc3RyaW5nLFxuICBpZDogc3RyaW5nIHwgbnVtYmVyXG4pIHtcbiAgcmV0dXJuIFtQZXJzaXN0ZW5jZUtleXMuUE9QVUxBVEUsIHRhYmxlTmFtZSwgZmllbGROYW1lLCBpZF0uam9pbihcIi5cIik7XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIENhY2hlcyBhIG1vZGVsIGZvciBsYXRlciBwb3B1bGF0aW9uXG4gKiBAc3VtbWFyeSBTdG9yZXMgYSBtb2RlbCBpbiB0aGUgY29udGV4dCBjYWNoZSBmb3IgZWZmaWNpZW50IHJldHJpZXZhbCBkdXJpbmcgcmVsYXRpb25zaGlwIHBvcHVsYXRpb25cbiAqIEB0ZW1wbGF0ZSBNIC0gVGhlIG1vZGVsIHR5cGUgZXh0ZW5kaW5nIE1vZGVsXG4gKiBAdGVtcGxhdGUgRiAtIFRoZSByZXBvc2l0b3J5IGZsYWdzIHR5cGVcbiAqIEBwYXJhbSB7Q29udGV4dDxGPn0gY29udGV4dCAtIFRoZSBjb250ZXh0IGZvciB0aGUgb3BlcmF0aW9uXG4gKiBAcGFyYW0ge019IHBhcmVudE1vZGVsIC0gVGhlIHBhcmVudCBtb2RlbCB0aGF0IGNvbnRhaW5zIHRoZSByZWxhdGlvbnNoaXBcbiAqIEBwYXJhbSBwcm9wZXJ0eUtleSAtIFRoZSBwcm9wZXJ0eSBrZXkgb2YgdGhlIHJlbGF0aW9uc2hpcFxuICogQHBhcmFtIHtzdHJpbmcgfCBudW1iZXJ9IHBrVmFsdWUgLSBUaGUgcHJpbWFyeSBrZXkgdmFsdWUgb2YgdGhlIHJlbGF0ZWQgbW9kZWxcbiAqIEBwYXJhbSB7YW55fSBjYWNoZVZhbHVlIC0gVGhlIG1vZGVsIGluc3RhbmNlIHRvIGNhY2hlXG4gKiBAcmV0dXJuIHtQcm9taXNlPGFueT59IEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdpdGggdGhlIHJlc3VsdCBvZiB0aGUgY2FjaGUgb3BlcmF0aW9uXG4gKiBAZnVuY3Rpb24gY2FjaGVNb2RlbEZvclBvcHVsYXRlXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmNvcmVcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNhY2hlTW9kZWxGb3JQb3B1bGF0ZTxcbiAgTSBleHRlbmRzIE1vZGVsLFxuICBGIGV4dGVuZHMgUmVwb3NpdG9yeUZsYWdzLFxuPihcbiAgY29udGV4dDogQ29udGV4dDxGPixcbiAgcGFyZW50TW9kZWw6IE0sXG4gIHByb3BlcnR5S2V5OiBrZXlvZiBNIHwgc3RyaW5nLFxuICBwa1ZhbHVlOiBzdHJpbmcgfCBudW1iZXIsXG4gIGNhY2hlVmFsdWU6IGFueVxuKSB7XG4gIGNvbnN0IGNhY2hlS2V5ID0gZ2V0UG9wdWxhdGVLZXkoXG4gICAgcGFyZW50TW9kZWwuY29uc3RydWN0b3IubmFtZSxcbiAgICBwcm9wZXJ0eUtleSBhcyBzdHJpbmcsXG4gICAgcGtWYWx1ZVxuICApO1xuICByZXR1cm4gY29udGV4dC5hY2N1bXVsYXRlKHsgW2NhY2hlS2V5XTogY2FjaGVWYWx1ZSB9KTtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gUG9wdWxhdGVzIGEgbW9kZWwncyByZWxhdGlvbnNoaXBcbiAqIEBzdW1tYXJ5IFJldHJpZXZlcyBhbmQgYXR0YWNoZXMgcmVsYXRlZCBtb2RlbHMgdG8gYSBtb2RlbCdzIHJlbGF0aW9uc2hpcCBwcm9wZXJ0eVxuICogQHRlbXBsYXRlIE0gLSBUaGUgbW9kZWwgdHlwZSBleHRlbmRpbmcgTW9kZWxcbiAqIEB0ZW1wbGF0ZSBSIC0gVGhlIHJlcG9zaXRvcnkgdHlwZSBleHRlbmRpbmcgUmVwbzxNLCBGLCBDPlxuICogQHRlbXBsYXRlIFYgLSBUaGUgcmVsYXRpb25zIG1ldGFkYXRhIHR5cGUgZXh0ZW5kaW5nIFJlbGF0aW9uc01ldGFkYXRhXG4gKiBAdGVtcGxhdGUgRiAtIFRoZSByZXBvc2l0b3J5IGZsYWdzIHR5cGVcbiAqIEB0ZW1wbGF0ZSBDIC0gVGhlIGNvbnRleHQgdHlwZSBleHRlbmRpbmcgQ29udGV4dDxGPlxuICogQHBhcmFtIHtSfSB0aGlzIC0gVGhlIHJlcG9zaXRvcnkgaW5zdGFuY2VcbiAqIEBwYXJhbSB7Q29udGV4dDxGPn0gY29udGV4dCAtIFRoZSBjb250ZXh0IGZvciB0aGUgb3BlcmF0aW9uXG4gKiBAcGFyYW0ge1Z9IGRhdGEgLSBUaGUgcmVsYXRpb25zIG1ldGFkYXRhXG4gKiBAcGFyYW0ga2V5IC0gVGhlIHByb3BlcnR5IGtleSBvZiB0aGUgcmVsYXRpb25zaGlwXG4gKiBAcGFyYW0ge019IG1vZGVsIC0gVGhlIG1vZGVsIGluc3RhbmNlXG4gKiBAcmV0dXJuIHtQcm9taXNlPHZvaWQ+fSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIHRoZSBvcGVyYXRpb24gaXMgY29tcGxldGVcbiAqIEBmdW5jdGlvbiBwb3B1bGF0ZVxuICogQG1lbWJlck9mIG1vZHVsZTpjb3JlXG4gKiBAbWVybWFpZFxuICogc2VxdWVuY2VEaWFncmFtXG4gKiAgIHBhcnRpY2lwYW50IENhbGxlclxuICogICBwYXJ0aWNpcGFudCBwb3B1bGF0ZVxuICogICBwYXJ0aWNpcGFudCBmZXRjaFBvcHVsYXRlVmFsdWVzXG4gKiAgIHBhcnRpY2lwYW50IGdldFBvcHVsYXRlS2V5XG4gKiAgIHBhcnRpY2lwYW50IENvbnRleHRcbiAqICAgcGFydGljaXBhbnQgcmVwb3NpdG9yeUZyb21UeXBlTWV0YWRhdGFcbiAqXG4gKiAgIENhbGxlci0+PnBvcHVsYXRlOiB0aGlzLCBjb250ZXh0LCBkYXRhLCBrZXksIG1vZGVsXG4gKiAgIHBvcHVsYXRlLT4+cG9wdWxhdGU6IGNoZWNrIGlmIGRhdGEucG9wdWxhdGUgaXMgdHJ1ZVxuICogICBwb3B1bGF0ZS0+PnBvcHVsYXRlOiBnZXQgbmVzdGVkIHZhbHVlIGFuZCBjaGVjayBpZiBpdCBleGlzdHNcbiAqXG4gKiAgIHBvcHVsYXRlLT4+ZmV0Y2hQb3B1bGF0ZVZhbHVlczogY29udGV4dCwgbW9kZWwsIGtleSwgaXNBcnIgPyBuZXN0ZWQgOiBbbmVzdGVkXVxuICpcbiAqICAgZmV0Y2hQb3B1bGF0ZVZhbHVlcy0+PmZldGNoUG9wdWxhdGVWYWx1ZXM6IGluaXRpYWxpemUgdmFyaWFibGVzXG4gKlxuICogICBsb29wIGZvciBlYWNoIHByb0tleVZhbHVlIGluIHByb3BLZXlWYWx1ZXNcbiAqICAgICBmZXRjaFBvcHVsYXRlVmFsdWVzLT4+Z2V0UG9wdWxhdGVLZXk6IG1vZGVsLmNvbnN0cnVjdG9yLm5hbWUsIHByb3BOYW1lLCBwcm9LZXlWYWx1ZVxuICogICAgIGdldFBvcHVsYXRlS2V5LS0+PmZldGNoUG9wdWxhdGVWYWx1ZXM6IGNhY2hlS2V5XG4gKlxuICogICAgIGFsdCB0cnkgdG8gZ2V0IGZyb20gY2FjaGVcbiAqICAgICAgIGZldGNoUG9wdWxhdGVWYWx1ZXMtPj5Db250ZXh0OiBnZXQoY2FjaGVLZXkpXG4gKiAgICAgICBDb250ZXh0LS0+PmZldGNoUG9wdWxhdGVWYWx1ZXM6IHZhbFxuICogICAgIGVsc2UgY2F0Y2ggZXJyb3JcbiAqICAgICAgIGZldGNoUG9wdWxhdGVWYWx1ZXMtPj5yZXBvc2l0b3J5RnJvbVR5cGVNZXRhZGF0YTogbW9kZWwsIHByb3BOYW1lXG4gKiAgICAgICByZXBvc2l0b3J5RnJvbVR5cGVNZXRhZGF0YS0tPj5mZXRjaFBvcHVsYXRlVmFsdWVzOiByZXBvXG4gKiAgICAgICBmZXRjaFBvcHVsYXRlVmFsdWVzLT4+cmVwbzogcmVhZChwcm9LZXlWYWx1ZSlcbiAqICAgICAgIHJlcG8tLT4+ZmV0Y2hQb3B1bGF0ZVZhbHVlczogdmFsXG4gKiAgICAgZW5kXG4gKlxuICogICAgIGZldGNoUG9wdWxhdGVWYWx1ZXMtPj5mZXRjaFBvcHVsYXRlVmFsdWVzOiBhZGQgdmFsIHRvIHJlc3VsdHNcbiAqICAgZW5kXG4gKlxuICogICBmZXRjaFBvcHVsYXRlVmFsdWVzLS0+PnBvcHVsYXRlOiByZXN1bHRzXG4gKiAgIHBvcHVsYXRlLT4+cG9wdWxhdGU6IHNldCBtb2RlbFtrZXldID0gaXNBcnIgPyByZXMgOiByZXNbMF1cbiAqICAgcG9wdWxhdGUtLT4+Q2FsbGVyOiB2b2lkXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBwb3B1bGF0ZTxcbiAgTSBleHRlbmRzIE1vZGVsLFxuICBSIGV4dGVuZHMgUmVwbzxNLCBGLCBDPixcbiAgViBleHRlbmRzIFJlbGF0aW9uc01ldGFkYXRhLFxuICBGIGV4dGVuZHMgUmVwb3NpdG9yeUZsYWdzLFxuICBDIGV4dGVuZHMgQ29udGV4dDxGPixcbj4oXG4gIHRoaXM6IFIsXG4gIGNvbnRleHQ6IENvbnRleHQ8Rj4sXG4gIGRhdGE6IFYsXG4gIGtleToga2V5b2YgTSxcbiAgbW9kZWw6IE1cbik6IFByb21pc2U8dm9pZD4ge1xuICBpZiAoIWRhdGEucG9wdWxhdGUpIHJldHVybjtcbiAgY29uc3QgbmVzdGVkOiBhbnkgPSBtb2RlbFtrZXldO1xuICBjb25zdCBpc0FyciA9IEFycmF5LmlzQXJyYXkobmVzdGVkKTtcbiAgaWYgKHR5cGVvZiBuZXN0ZWQgPT09IFwidW5kZWZpbmVkXCIgfHwgKGlzQXJyICYmIG5lc3RlZC5sZW5ndGggPT09IDApKSByZXR1cm47XG5cbiAgYXN5bmMgZnVuY3Rpb24gZmV0Y2hQb3B1bGF0ZVZhbHVlcyhcbiAgICBjOiBDb250ZXh0PEY+LFxuICAgIG1vZGVsOiBNLFxuICAgIHByb3BOYW1lOiBzdHJpbmcsXG4gICAgcHJvcEtleVZhbHVlczogYW55W11cbiAgKSB7XG4gICAgbGV0IGNhY2hlS2V5OiBzdHJpbmc7XG4gICAgbGV0IHZhbDogYW55O1xuICAgIGNvbnN0IHJlc3VsdHM6IE1bXSA9IFtdO1xuICAgIGZvciAoY29uc3QgcHJvS2V5VmFsdWUgb2YgcHJvcEtleVZhbHVlcykge1xuICAgICAgY2FjaGVLZXkgPSBnZXRQb3B1bGF0ZUtleShtb2RlbC5jb25zdHJ1Y3Rvci5uYW1lLCBwcm9wTmFtZSwgcHJvS2V5VmFsdWUpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgdmFsID0gYXdhaXQgYy5nZXQoY2FjaGVLZXkgYXMgYW55KTtcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICAgICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICAgIGNvbnN0IHJlcG8gPSByZXBvc2l0b3J5RnJvbVR5cGVNZXRhZGF0YShtb2RlbCwgcHJvcE5hbWUpO1xuICAgICAgICBpZiAoIXJlcG8pIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFwiQ291bGQgbm90IGZpbmQgcmVwb1wiKTtcbiAgICAgICAgdmFsID0gYXdhaXQgcmVwby5yZWFkKHByb0tleVZhbHVlKTtcbiAgICAgIH1cbiAgICAgIHJlc3VsdHMucHVzaCh2YWwpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0cztcbiAgfVxuICBjb25zdCByZXMgPSBhd2FpdCBmZXRjaFBvcHVsYXRlVmFsdWVzKFxuICAgIGNvbnRleHQsXG4gICAgbW9kZWwsXG4gICAga2V5IGFzIHN0cmluZyxcbiAgICBpc0FyciA/IG5lc3RlZCA6IFtuZXN0ZWRdXG4gICk7XG4gIChtb2RlbCBhcyBhbnkpW2tleV0gPSBpc0FyciA/IHJlcyA6IHJlc1swXTtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gTGlzdCBvZiBjb21tb24gSmF2YVNjcmlwdCB0eXBlc1xuICogQHN1bW1hcnkgQW4gYXJyYXkgb2Ygc3RyaW5ncyByZXByZXNlbnRpbmcgY29tbW9uIEphdmFTY3JpcHQgdHlwZXMgdGhhdCBhcmUgbm90IGN1c3RvbSBtb2RlbCB0eXBlc1xuICogQGNvbnN0IGNvbW1vbVR5cGVzXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmNvcmVcbiAqL1xuY29uc3QgY29tbW9tVHlwZXMgPSBbXG4gIFwiYXJyYXlcIixcbiAgXCJzdHJpbmdcIixcbiAgXCJudW1iZXJcIixcbiAgXCJib29sZWFuXCIsXG4gIFwic3ltYm9sXCIsXG4gIFwiZnVuY3Rpb25cIixcbiAgXCJvYmplY3RcIixcbiAgXCJ1bmRlZmluZWRcIixcbiAgXCJudWxsXCIsXG4gIFwiYmlnaW50XCIsXG5dO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBSZXRyaWV2ZXMgYSByZXBvc2l0b3J5IGZvciBhIG1vZGVsIHByb3BlcnR5IGJhc2VkIG9uIGl0cyB0eXBlIG1ldGFkYXRhXG4gKiBAc3VtbWFyeSBFeGFtaW5lcyBhIG1vZGVsIHByb3BlcnR5J3MgdHlwZSBtZXRhZGF0YSB0byBkZXRlcm1pbmUgdGhlIGFwcHJvcHJpYXRlIHJlcG9zaXRvcnkgZm9yIHJlbGF0ZWQgbW9kZWxzXG4gKiBAdGVtcGxhdGUgTSAtIFRoZSBtb2RlbCB0eXBlIGV4dGVuZGluZyBNb2RlbFxuICogQHBhcmFtIHthbnl9IG1vZGVsIC0gVGhlIG1vZGVsIGluc3RhbmNlIGNvbnRhaW5pbmcgdGhlIHByb3BlcnR5XG4gKiBAcGFyYW0gcHJvcGVydHlLZXkgLSBUaGUgcHJvcGVydHkga2V5IHRvIGV4YW1pbmVcbiAqIEByZXR1cm4ge1JlcG88TT59IEEgcmVwb3NpdG9yeSBmb3IgdGhlIG1vZGVsIHR5cGUgYXNzb2NpYXRlZCB3aXRoIHRoZSBwcm9wZXJ0eVxuICogQGZ1bmN0aW9uIHJlcG9zaXRvcnlGcm9tVHlwZU1ldGFkYXRhXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmNvcmVcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgQ2FsbGVyXG4gKiAgIHBhcnRpY2lwYW50IHJlcG9zaXRvcnlGcm9tVHlwZU1ldGFkYXRhXG4gKiAgIHBhcnRpY2lwYW50IFJlZmxlY3RcbiAqICAgcGFydGljaXBhbnQgVmFsaWRhdGlvblxuICogICBwYXJ0aWNpcGFudCBNb2RlbFxuICogICBwYXJ0aWNpcGFudCBSZXBvc2l0b3J5XG4gKlxuICogICBDYWxsZXItPj5yZXBvc2l0b3J5RnJvbVR5cGVNZXRhZGF0YTogbW9kZWwsIHByb3BlcnR5S2V5XG4gKlxuICogICByZXBvc2l0b3J5RnJvbVR5cGVNZXRhZGF0YS0+PlZhbGlkYXRpb246IGtleShBcnJheS5pc0FycmF5KG1vZGVsW3Byb3BlcnR5S2V5XSkgPyBWYWxpZGF0aW9uS2V5cy5MSVNUIDogVmFsaWRhdGlvbktleXMuVFlQRSlcbiAqICAgVmFsaWRhdGlvbi0tPj5yZXBvc2l0b3J5RnJvbVR5cGVNZXRhZGF0YTogdmFsaWRhdGlvbktleVxuICpcbiAqICAgcmVwb3NpdG9yeUZyb21UeXBlTWV0YWRhdGEtPj5SZWZsZWN0OiBnZXRNZXRhZGF0YSh2YWxpZGF0aW9uS2V5LCBtb2RlbCwgcHJvcGVydHlLZXkpXG4gKiAgIFJlZmxlY3QtLT4+cmVwb3NpdG9yeUZyb21UeXBlTWV0YWRhdGE6IHR5cGVzXG4gKlxuICogICByZXBvc2l0b3J5RnJvbVR5cGVNZXRhZGF0YS0+PnJlcG9zaXRvcnlGcm9tVHlwZU1ldGFkYXRhOiBkZXRlcm1pbmUgY3VzdG9tVHlwZXMgYmFzZWQgb24gcHJvcGVydHkgdHlwZVxuICogICByZXBvc2l0b3J5RnJvbVR5cGVNZXRhZGF0YS0+PnJlcG9zaXRvcnlGcm9tVHlwZU1ldGFkYXRhOiBjaGVjayBpZiB0eXBlcyBhbmQgY3VzdG9tVHlwZXMgZXhpc3RcbiAqXG4gKiAgIHJlcG9zaXRvcnlGcm9tVHlwZU1ldGFkYXRhLT4+cmVwb3NpdG9yeUZyb21UeXBlTWV0YWRhdGE6IGNyZWF0ZSBhbGxvd2VkVHlwZXMgYXJyYXlcbiAqICAgcmVwb3NpdG9yeUZyb21UeXBlTWV0YWRhdGEtPj5yZXBvc2l0b3J5RnJvbVR5cGVNZXRhZGF0YTogZmluZCBjb25zdHJ1Y3Rvck5hbWUgbm90IGluIGNvbW1vbVR5cGVzXG4gKiAgIHJlcG9zaXRvcnlGcm9tVHlwZU1ldGFkYXRhLT4+cmVwb3NpdG9yeUZyb21UeXBlTWV0YWRhdGE6IGNoZWNrIGlmIGNvbnN0cnVjdG9yTmFtZSBleGlzdHNcbiAqXG4gKiAgIHJlcG9zaXRvcnlGcm9tVHlwZU1ldGFkYXRhLT4+TW9kZWw6IGdldChjb25zdHJ1Y3Rvck5hbWUpXG4gKiAgIE1vZGVsLS0+PnJlcG9zaXRvcnlGcm9tVHlwZU1ldGFkYXRhOiBjb25zdHJ1Y3RvclxuICogICByZXBvc2l0b3J5RnJvbVR5cGVNZXRhZGF0YS0+PnJlcG9zaXRvcnlGcm9tVHlwZU1ldGFkYXRhOiBjaGVjayBpZiBjb25zdHJ1Y3RvciBleGlzdHNcbiAqXG4gKiAgIHJlcG9zaXRvcnlGcm9tVHlwZU1ldGFkYXRhLT4+UmVwb3NpdG9yeTogZm9yTW9kZWwoY29uc3RydWN0b3IpXG4gKiAgIFJlcG9zaXRvcnktLT4+cmVwb3NpdG9yeUZyb21UeXBlTWV0YWRhdGE6IHJlcG9cbiAqXG4gKiAgIHJlcG9zaXRvcnlGcm9tVHlwZU1ldGFkYXRhLS0+PkNhbGxlcjogcmVwb1xuICovXG5leHBvcnQgZnVuY3Rpb24gcmVwb3NpdG9yeUZyb21UeXBlTWV0YWRhdGE8TSBleHRlbmRzIE1vZGVsPihcbiAgbW9kZWw6IGFueSxcbiAgcHJvcGVydHlLZXk6IHN0cmluZyB8IGtleW9mIE1cbik6IFJlcG88TT4ge1xuICBjb25zdCB0eXBlcyA9IFJlZmxlY3QuZ2V0TWV0YWRhdGEoXG4gICAgVmFsaWRhdGlvbi5rZXkoXG4gICAgICBBcnJheS5pc0FycmF5KG1vZGVsW3Byb3BlcnR5S2V5XSlcbiAgICAgICAgPyBWYWxpZGF0aW9uS2V5cy5MSVNUXG4gICAgICAgIDogVmFsaWRhdGlvbktleXMuVFlQRVxuICAgICksXG4gICAgbW9kZWwsXG4gICAgcHJvcGVydHlLZXkgYXMgc3RyaW5nXG4gICk7XG4gIGNvbnN0IGN1c3RvbVR5cGVzOiBhbnkgPSBBcnJheS5pc0FycmF5KG1vZGVsW3Byb3BlcnR5S2V5XSlcbiAgICA/IHR5cGVzLmNsYXp6XG4gICAgOiB0eXBlcy5jdXN0b21UeXBlcztcbiAgaWYgKCF0eXBlcyB8fCAhY3VzdG9tVHlwZXMpXG4gICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXG4gICAgICBgRmFpbGVkIHRvIGZpbmQgdHlwZXMgZGVjb3JhdG9ycyBmb3IgcHJvcGVydHkgJHtwcm9wZXJ0eUtleSBhcyBzdHJpbmd9YFxuICAgICk7XG5cbiAgY29uc3QgYWxsb3dlZFR5cGVzOiBzdHJpbmdbXSA9IEFycmF5LmlzQXJyYXkoY3VzdG9tVHlwZXMpXG4gICAgPyBbLi4uY3VzdG9tVHlwZXNdXG4gICAgOiBbY3VzdG9tVHlwZXNdO1xuICBjb25zdCBjb25zdHJ1Y3Rvck5hbWUgPSBhbGxvd2VkVHlwZXMuZmluZChcbiAgICAodCkgPT4gIWNvbW1vbVR5cGVzLmluY2x1ZGVzKGAke3R9YC50b0xvd2VyQ2FzZSgpKVxuICApO1xuICBpZiAoIWNvbnN0cnVjdG9yTmFtZSlcbiAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcbiAgICAgIGBQcm9wZXJ0eSBrZXkgJHtwcm9wZXJ0eUtleSBhcyBzdHJpbmd9IGRvZXMgbm90IGhhdmUgYSB2YWxpZCBjb25zdHJ1Y3RvciB0eXBlYFxuICAgICk7XG4gIGNvbnN0IGNvbnN0cnVjdG9yOiBDb25zdHJ1Y3RvcjxNPiB8IHVuZGVmaW5lZCA9IE1vZGVsLmdldChjb25zdHJ1Y3Rvck5hbWUpO1xuICBpZiAoIWNvbnN0cnVjdG9yKVxuICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKGBObyByZWdpc3RlcmVkIG1vZGVsIGZvdW5kIGZvciAke2NvbnN0cnVjdG9yTmFtZX1gKTtcblxuICByZXR1cm4gUmVwb3NpdG9yeS5mb3JNb2RlbChjb25zdHJ1Y3Rvcik7XG59XG5cbiJdfQ==
|