@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.
Files changed (197) hide show
  1. package/LICENSE.md +21 -157
  2. package/README.md +652 -15
  3. package/dist/core.cjs +2110 -132
  4. package/dist/core.esm.cjs +2111 -133
  5. package/lib/esm/identity/decorators.d.ts +52 -7
  6. package/lib/esm/identity/decorators.js +53 -8
  7. package/lib/esm/identity/utils.d.ts +19 -0
  8. package/lib/esm/identity/utils.js +20 -1
  9. package/lib/esm/index.d.ts +9 -2
  10. package/lib/esm/index.js +10 -3
  11. package/lib/esm/interfaces/ErrorParser.d.ts +12 -0
  12. package/lib/esm/interfaces/ErrorParser.js +1 -1
  13. package/lib/esm/interfaces/Executor.d.ts +13 -0
  14. package/lib/esm/interfaces/Executor.js +1 -1
  15. package/lib/esm/interfaces/Observable.d.ts +27 -0
  16. package/lib/esm/interfaces/Observable.js +1 -1
  17. package/lib/esm/interfaces/Observer.d.ts +12 -0
  18. package/lib/esm/interfaces/Observer.js +1 -1
  19. package/lib/esm/interfaces/Paginatable.d.ts +15 -0
  20. package/lib/esm/interfaces/Paginatable.js +1 -1
  21. package/lib/esm/interfaces/Queriable.d.ts +34 -9
  22. package/lib/esm/interfaces/Queriable.js +1 -1
  23. package/lib/esm/interfaces/RawExecutor.d.ts +14 -0
  24. package/lib/esm/interfaces/RawExecutor.js +1 -1
  25. package/lib/esm/interfaces/SequenceOptions.d.ts +52 -0
  26. package/lib/esm/interfaces/SequenceOptions.js +19 -1
  27. package/lib/esm/model/BaseModel.d.ts +31 -0
  28. package/lib/esm/model/BaseModel.js +24 -1
  29. package/lib/esm/model/construction.d.ts +433 -0
  30. package/lib/esm/model/construction.js +441 -2
  31. package/lib/esm/model/decorators.d.ts +159 -29
  32. package/lib/esm/model/decorators.js +160 -30
  33. package/lib/esm/model/types.d.ts +9 -0
  34. package/lib/esm/model/types.js +1 -1
  35. package/lib/esm/persistence/Adapter.d.ts +358 -17
  36. package/lib/esm/persistence/Adapter.js +287 -19
  37. package/lib/esm/persistence/Dispatch.d.ts +114 -1
  38. package/lib/esm/persistence/Dispatch.js +102 -4
  39. package/lib/esm/persistence/ObserverHandler.d.ts +95 -0
  40. package/lib/esm/persistence/ObserverHandler.js +96 -1
  41. package/lib/esm/persistence/Sequence.d.ts +89 -0
  42. package/lib/esm/persistence/Sequence.js +70 -1
  43. package/lib/esm/persistence/constants.d.ts +22 -0
  44. package/lib/esm/persistence/constants.js +23 -1
  45. package/lib/esm/persistence/decorators.d.ts +10 -0
  46. package/lib/esm/persistence/decorators.js +11 -1
  47. package/lib/esm/persistence/errors.d.ts +23 -0
  48. package/lib/esm/persistence/errors.js +24 -1
  49. package/lib/esm/persistence/types.d.ts +18 -0
  50. package/lib/esm/persistence/types.js +1 -1
  51. package/lib/esm/query/Condition.d.ts +78 -31
  52. package/lib/esm/query/Condition.js +132 -53
  53. package/lib/esm/query/Paginator.d.ts +56 -0
  54. package/lib/esm/query/Paginator.js +57 -1
  55. package/lib/esm/query/Statement.d.ts +51 -0
  56. package/lib/esm/query/Statement.js +52 -1
  57. package/lib/esm/query/constants.d.ts +25 -0
  58. package/lib/esm/query/constants.js +26 -1
  59. package/lib/esm/query/errors.d.ts +14 -0
  60. package/lib/esm/query/errors.js +15 -1
  61. package/lib/esm/query/options.d.ts +21 -3
  62. package/lib/esm/query/options.js +1 -1
  63. package/lib/esm/query/selectors.d.ts +26 -0
  64. package/lib/esm/query/selectors.js +1 -1
  65. package/lib/esm/ram/RamAdapter.d.ts +311 -0
  66. package/lib/esm/ram/RamAdapter.js +312 -1
  67. package/lib/esm/ram/RamContext.d.ts +16 -1
  68. package/lib/esm/ram/RamContext.js +18 -3
  69. package/lib/esm/ram/RamPaginator.d.ts +43 -0
  70. package/lib/esm/ram/RamPaginator.js +54 -2
  71. package/lib/esm/ram/RamSequence.d.ts +61 -0
  72. package/lib/esm/ram/RamSequence.js +63 -2
  73. package/lib/esm/ram/RamStatement.d.ts +74 -0
  74. package/lib/esm/ram/RamStatement.js +75 -1
  75. package/lib/esm/ram/constants.d.ts +8 -0
  76. package/lib/esm/ram/constants.js +9 -1
  77. package/lib/esm/ram/handlers.d.ts +19 -0
  78. package/lib/esm/ram/handlers.js +20 -1
  79. package/lib/esm/ram/model/RamSequence.d.ts +25 -0
  80. package/lib/esm/ram/model/RamSequence.js +19 -1
  81. package/lib/esm/ram/types.d.ts +42 -0
  82. package/lib/esm/ram/types.js +1 -1
  83. package/lib/esm/repository/Repository.d.ts +363 -8
  84. package/lib/esm/repository/Repository.js +361 -16
  85. package/lib/esm/repository/constants.d.ts +25 -0
  86. package/lib/esm/repository/constants.js +26 -1
  87. package/lib/esm/repository/decorators.d.ts +27 -0
  88. package/lib/esm/repository/decorators.js +28 -1
  89. package/lib/esm/repository/errors.d.ts +12 -5
  90. package/lib/esm/repository/errors.js +13 -6
  91. package/lib/esm/repository/injectables.d.ts +18 -0
  92. package/lib/esm/repository/injectables.js +19 -1
  93. package/lib/esm/repository/types.d.ts +15 -0
  94. package/lib/esm/repository/types.js +1 -1
  95. package/lib/esm/repository/utils.d.ts +11 -0
  96. package/lib/esm/repository/utils.js +12 -1
  97. package/lib/esm/utils/decorators.d.ts +8 -0
  98. package/lib/esm/utils/decorators.js +9 -1
  99. package/lib/esm/utils/errors.d.ts +46 -0
  100. package/lib/esm/utils/errors.js +47 -1
  101. package/lib/identity/decorators.cjs +53 -8
  102. package/lib/identity/decorators.d.ts +52 -7
  103. package/lib/identity/utils.cjs +20 -1
  104. package/lib/identity/utils.d.ts +19 -0
  105. package/lib/index.cjs +10 -3
  106. package/lib/index.d.ts +9 -2
  107. package/lib/interfaces/ErrorParser.cjs +1 -1
  108. package/lib/interfaces/ErrorParser.d.ts +12 -0
  109. package/lib/interfaces/Executor.cjs +1 -1
  110. package/lib/interfaces/Executor.d.ts +13 -0
  111. package/lib/interfaces/Observable.cjs +1 -1
  112. package/lib/interfaces/Observable.d.ts +27 -0
  113. package/lib/interfaces/Observer.cjs +1 -1
  114. package/lib/interfaces/Observer.d.ts +12 -0
  115. package/lib/interfaces/Paginatable.cjs +1 -1
  116. package/lib/interfaces/Paginatable.d.ts +15 -0
  117. package/lib/interfaces/Queriable.cjs +1 -1
  118. package/lib/interfaces/Queriable.d.ts +34 -9
  119. package/lib/interfaces/RawExecutor.cjs +1 -1
  120. package/lib/interfaces/RawExecutor.d.ts +14 -0
  121. package/lib/interfaces/SequenceOptions.cjs +19 -1
  122. package/lib/interfaces/SequenceOptions.d.ts +52 -0
  123. package/lib/model/BaseModel.cjs +24 -1
  124. package/lib/model/BaseModel.d.ts +31 -0
  125. package/lib/model/construction.cjs +441 -2
  126. package/lib/model/construction.d.ts +433 -0
  127. package/lib/model/decorators.cjs +160 -30
  128. package/lib/model/decorators.d.ts +159 -29
  129. package/lib/model/types.cjs +1 -1
  130. package/lib/model/types.d.ts +9 -0
  131. package/lib/persistence/Adapter.cjs +287 -19
  132. package/lib/persistence/Adapter.d.ts +358 -17
  133. package/lib/persistence/Dispatch.cjs +102 -4
  134. package/lib/persistence/Dispatch.d.ts +114 -1
  135. package/lib/persistence/ObserverHandler.cjs +96 -1
  136. package/lib/persistence/ObserverHandler.d.ts +95 -0
  137. package/lib/persistence/Sequence.cjs +70 -1
  138. package/lib/persistence/Sequence.d.ts +89 -0
  139. package/lib/persistence/constants.cjs +23 -1
  140. package/lib/persistence/constants.d.ts +22 -0
  141. package/lib/persistence/decorators.cjs +11 -1
  142. package/lib/persistence/decorators.d.ts +10 -0
  143. package/lib/persistence/errors.cjs +24 -1
  144. package/lib/persistence/errors.d.ts +23 -0
  145. package/lib/persistence/types.cjs +1 -1
  146. package/lib/persistence/types.d.ts +18 -0
  147. package/lib/query/Condition.cjs +132 -53
  148. package/lib/query/Condition.d.ts +78 -31
  149. package/lib/query/Paginator.cjs +57 -1
  150. package/lib/query/Paginator.d.ts +56 -0
  151. package/lib/query/Statement.cjs +52 -1
  152. package/lib/query/Statement.d.ts +51 -0
  153. package/lib/query/constants.cjs +26 -1
  154. package/lib/query/constants.d.ts +25 -0
  155. package/lib/query/errors.cjs +15 -1
  156. package/lib/query/errors.d.ts +14 -0
  157. package/lib/query/options.cjs +1 -1
  158. package/lib/query/options.d.ts +21 -3
  159. package/lib/query/selectors.cjs +1 -1
  160. package/lib/query/selectors.d.ts +26 -0
  161. package/lib/ram/RamAdapter.cjs +312 -1
  162. package/lib/ram/RamAdapter.d.ts +311 -0
  163. package/lib/ram/RamContext.cjs +18 -3
  164. package/lib/ram/RamContext.d.ts +16 -1
  165. package/lib/ram/RamPaginator.cjs +54 -2
  166. package/lib/ram/RamPaginator.d.ts +43 -0
  167. package/lib/ram/RamSequence.cjs +63 -2
  168. package/lib/ram/RamSequence.d.ts +61 -0
  169. package/lib/ram/RamStatement.cjs +75 -1
  170. package/lib/ram/RamStatement.d.ts +74 -0
  171. package/lib/ram/constants.cjs +9 -1
  172. package/lib/ram/constants.d.ts +8 -0
  173. package/lib/ram/handlers.cjs +20 -1
  174. package/lib/ram/handlers.d.ts +19 -0
  175. package/lib/ram/model/RamSequence.cjs +19 -1
  176. package/lib/ram/model/RamSequence.d.ts +25 -0
  177. package/lib/ram/types.cjs +1 -1
  178. package/lib/ram/types.d.ts +42 -0
  179. package/lib/repository/Repository.cjs +360 -15
  180. package/lib/repository/Repository.d.ts +363 -8
  181. package/lib/repository/constants.cjs +26 -1
  182. package/lib/repository/constants.d.ts +25 -0
  183. package/lib/repository/decorators.cjs +28 -1
  184. package/lib/repository/decorators.d.ts +27 -0
  185. package/lib/repository/errors.cjs +13 -6
  186. package/lib/repository/errors.d.ts +12 -5
  187. package/lib/repository/injectables.cjs +19 -1
  188. package/lib/repository/injectables.d.ts +18 -0
  189. package/lib/repository/types.cjs +1 -1
  190. package/lib/repository/types.d.ts +15 -0
  191. package/lib/repository/utils.cjs +12 -1
  192. package/lib/repository/utils.d.ts +11 -0
  193. package/lib/utils/decorators.cjs +9 -1
  194. package/lib/utils/decorators.d.ts +8 -0
  195. package/lib/utils/errors.cjs +47 -1
  196. package/lib/utils/errors.d.ts +46 -0
  197. package/package.json +5 -5
package/dist/core.esm.cjs CHANGED
@@ -1,46 +1,101 @@
1
1
  import { inject, injectable, InjectableRegistryImp, Injectables } from '@decaf-ts/injectable-decorators';
2
- import { BaseError, InternalError, OperationKeys, BulkCrudOperationKeys, Context, DefaultRepositoryFlags, modelToTransient, NotFoundError, DBKeys, Repository as Repository$1, wrapMethodWithContext, enforceDBDecorators, ValidationError, findPrimaryKey, ConflictError, onCreateUpdate, onCreate, onUpdate, onDelete, afterAny, readonly, timestamp, DBOperations } from '@decaf-ts/db-decorators';
2
+ import { BaseError, InternalError, OperationKeys, BulkCrudOperationKeys, Context, DefaultRepositoryFlags, modelToTransient, NotFoundError, DBKeys, Repository as Repository$1, wrapMethodWithContext, enforceDBDecorators, ValidationError, findPrimaryKey, DefaultSeparator, ConflictError, onCreateUpdate, onCreate, onUpdate, onDelete, afterAny, readonly, timestamp, DBOperations } from '@decaf-ts/db-decorators';
3
3
  import { apply, metadata, Reflection } from '@decaf-ts/reflection';
4
4
  import { __decorate, __metadata } from 'tslib';
5
5
  import { Decoration, DefaultFlavour, Model, sf, required, Validation, ValidationKeys, propMetadata, prop, type, list } from '@decaf-ts/decorator-validation';
6
6
  import { Logging } from '@decaf-ts/logging';
7
7
 
8
+ /**
9
+ * @description Enumeration of possible sort directions.
10
+ * @summary Defines the available sort directions for ordering query results.
11
+ * @enum {string}
12
+ * @readonly
13
+ * @memberOf module:core
14
+ */
8
15
  var OrderDirection;
9
16
  (function (OrderDirection) {
17
+ /** Ascending order (A to Z, 0 to 9) */
10
18
  OrderDirection["ASC"] = "asc";
19
+ /** Descending order (Z to A, 9 to 0) */
11
20
  OrderDirection["DSC"] = "desc";
12
21
  })(OrderDirection || (OrderDirection = {}));
22
+ /**
23
+ * @description Enumeration of cascade operation types.
24
+ * @summary Defines the available cascade behaviors for entity relationships.
25
+ * @enum {string}
26
+ * @readonly
27
+ * @memberOf module:core
28
+ */
13
29
  var Cascade;
14
30
  (function (Cascade) {
31
+ /** Perform cascade operation on related entities */
15
32
  Cascade["CASCADE"] = "cascade";
33
+ /** Do not perform cascade operation on related entities */
16
34
  Cascade["NONE"] = "none";
17
35
  })(Cascade || (Cascade = {}));
36
+ /**
37
+ * @description Default cascade configuration for entity relationships.
38
+ * @summary Provides the default cascade behavior where updates cascade but deletes do not.
39
+ * @type {CascadeMetadata}
40
+ * @const DefaultCascade
41
+ * @memberOf module:core
42
+ */
18
43
  const DefaultCascade = {
19
44
  update: Cascade.CASCADE,
20
45
  delete: Cascade.NONE,
21
46
  };
22
47
 
48
+ /**
49
+ * @description Persistence-related constant keys
50
+ * @summary Enum containing string constants used throughout the persistence layer for metadata, relations, and other persistence-related operations
51
+ * @enum {string}
52
+ * @readonly
53
+ * @memberOf module:core
54
+ */
23
55
  var PersistenceKeys;
24
56
  (function (PersistenceKeys) {
57
+ /** @description Key for index metadata */
25
58
  PersistenceKeys["INDEX"] = "index";
59
+ /** @description Key for unique constraint metadata */
26
60
  PersistenceKeys["UNIQUE"] = "unique";
61
+ /** @description Key for adapter metadata */
27
62
  PersistenceKeys["ADAPTER"] = "adapter";
63
+ /** @description Template for injectable adapter names */
28
64
  PersistenceKeys["INJECTABLE"] = "decaf_{0}_adapter_for_{1}";
65
+ /** @description Key for table name metadata */
29
66
  PersistenceKeys["TABLE"] = "table";
67
+ /** @description Key for column name metadata */
30
68
  PersistenceKeys["COLUMN"] = "column";
69
+ /** @description Key for general metadata storage */
31
70
  PersistenceKeys["METADATA"] = "__metadata";
71
+ /** @description Key for relations metadata storage */
32
72
  PersistenceKeys["RELATIONS"] = "__relations";
73
+ /** @description Key for clause sequence metadata */
33
74
  PersistenceKeys["CLAUSE_SEQUENCE"] = "clause-sequence";
34
75
  // Ownership
76
+ /** @description Key for created-by ownership metadata */
35
77
  PersistenceKeys["CREATED_BY"] = "ownership.created-by";
78
+ /** @description Key for updated-by ownership metadata */
36
79
  PersistenceKeys["UPDATED_BY"] = "ownership.updated-by";
37
80
  // Relations
81
+ /** @description Key for one-to-one relation metadata */
38
82
  PersistenceKeys["ONE_TO_ONE"] = "relations.one-to-one";
83
+ /** @description Key for one-to-many relation metadata */
39
84
  PersistenceKeys["ONE_TO_MANY"] = "relations.one-to-many";
85
+ /** @description Key for many-to-one relation metadata */
40
86
  PersistenceKeys["MANY_TO_ONE"] = "relations.many-to-one";
87
+ /** @description Key for populate metadata */
41
88
  PersistenceKeys["POPULATE"] = "populate";
42
89
  })(PersistenceKeys || (PersistenceKeys = {}));
43
90
 
91
+ /**
92
+ * @description Creates a decorator that makes a method non-configurable
93
+ * @summary This decorator prevents a method from being overridden by making it non-configurable.
94
+ * It throws an error if used on anything other than a method.
95
+ * @return {Function} A decorator function that can be applied to methods
96
+ * @function final
97
+ * @category Method Decorators
98
+ */
44
99
  function final() {
45
100
  return (target, propertyKey, descriptor) => {
46
101
  if (!descriptor)
@@ -52,36 +107,176 @@ function final() {
52
107
  };
53
108
  }
54
109
 
110
+ /**
111
+ * @description Error thrown when a user is not authorized to perform an action
112
+ * @summary This error is thrown when a user attempts to access a resource or perform an action without proper authentication
113
+ * @param {string|Error} msg - The error message or Error object
114
+ * @class AuthorizationError
115
+ * @category Errors
116
+ * @example
117
+ * ```typescript
118
+ * // Example of throwing an AuthorizationError
119
+ * if (!user.isAuthenticated()) {
120
+ * throw new AuthorizationError('User not authenticated');
121
+ * }
122
+ * ```
123
+ */
55
124
  class AuthorizationError extends BaseError {
56
125
  constructor(msg) {
57
126
  super(AuthorizationError.name, msg, 401);
58
127
  }
59
128
  }
129
+ /**
130
+ * @description Error thrown when a user is forbidden from accessing a resource
131
+ * @summary This error is thrown when an authenticated user attempts to access a resource or perform an action they don't have permission for
132
+ * @param {string|Error} msg - The error message or Error object
133
+ * @return {void}
134
+ * @class ForbiddenError
135
+ * @category Errors
136
+ * @example
137
+ * ```typescript
138
+ * // Example of throwing a ForbiddenError
139
+ * if (!user.hasPermission('admin')) {
140
+ * throw new ForbiddenError('User does not have admin permissions');
141
+ * }
142
+ * ```
143
+ */
60
144
  class ForbiddenError extends BaseError {
61
145
  constructor(msg) {
62
146
  super(ForbiddenError.name, msg, 403);
63
147
  }
64
148
  }
149
+ /**
150
+ * @description Error thrown when a connection to a service fails
151
+ * @summary This error is thrown when the application fails to establish a connection to a required service or resource
152
+ * @param {string|Error} msg - The error message or Error object
153
+ * @return {void}
154
+ * @class ConnectionError
155
+ * @category Errors
156
+ * @example
157
+ * ```typescript
158
+ * // Example of throwing a ConnectionError
159
+ * try {
160
+ * await database.connect();
161
+ * } catch (error) {
162
+ * throw new ConnectionError('Failed to connect to database');
163
+ * }
164
+ * ```
165
+ */
65
166
  class ConnectionError extends BaseError {
66
167
  constructor(msg) {
67
168
  super(ConnectionError.name, msg, 503);
68
169
  }
69
170
  }
70
171
 
172
+ /**
173
+ * @description Error thrown when an unsupported operation is attempted
174
+ * @summary This error is thrown when an operation is requested that is not supported by the current
175
+ * persistence adapter or configuration. It extends the BaseError class and sets a 500 status code.
176
+ * @param {string|Error} msg - The error message or an Error object to wrap
177
+ * @class UnsupportedError
178
+ * @example
179
+ * ```typescript
180
+ * // Throwing an UnsupportedError
181
+ * if (!adapter.supportsTransactions()) {
182
+ * throw new UnsupportedError('Transactions are not supported by this adapter');
183
+ * }
184
+ *
185
+ * // Catching an UnsupportedError
186
+ * try {
187
+ * await adapter.beginTransaction();
188
+ * } catch (error) {
189
+ * if (error instanceof UnsupportedError) {
190
+ * console.error('Operation not supported:', error.message);
191
+ * }
192
+ * }
193
+ * ```
194
+ */
71
195
  class UnsupportedError extends BaseError {
72
196
  constructor(msg) {
73
197
  super(UnsupportedError.name, msg, 500);
74
198
  }
75
199
  }
76
200
 
201
+ /**
202
+ * @description Dispatches database operation events to observers
203
+ * @summary The Dispatch class implements the Observable interface and is responsible for intercepting
204
+ * database operations from an Adapter and notifying observers when changes occur. It uses proxies to
205
+ * wrap the adapter's CRUD methods and automatically trigger observer updates after operations complete.
206
+ * @template Y - The native database driver type
207
+ * @param {void} - No constructor parameters
208
+ * @class Dispatch
209
+ * @example
210
+ * ```typescript
211
+ * // Creating and using a Dispatch instance
212
+ * const dispatch = new Dispatch<PostgresDriver>();
213
+ *
214
+ * // Connect it to an adapter
215
+ * const adapter = new PostgresAdapter(connection);
216
+ * dispatch.observe(adapter);
217
+ *
218
+ * // Now any CRUD operations on the adapter will automatically
219
+ * // trigger observer notifications
220
+ * await adapter.create('users', 123, userModel);
221
+ * // Observers will be notified about the creation
222
+ *
223
+ * // When done, you can disconnect
224
+ * dispatch.unObserve(adapter);
225
+ * ```
226
+ */
77
227
  class Dispatch {
228
+ /**
229
+ * @description Accessor for the logger
230
+ * @summary Gets or initializes the logger for this dispatch instance
231
+ * @return {Logger} The logger instance
232
+ */
78
233
  get log() {
79
234
  if (!this.logger)
80
235
  this.logger = Logging.for(this).for(this.adapter);
81
236
  return this.logger;
82
237
  }
238
+ /**
239
+ * @description Creates a new Dispatch instance
240
+ * @summary Initializes a new Dispatch instance without any adapter
241
+ */
83
242
  constructor() { }
84
- initialize() {
243
+ /**
244
+ * @description Initializes the dispatch by proxying adapter methods
245
+ * @summary Sets up proxies on the adapter's CRUD methods to intercept operations and notify observers.
246
+ * This method is called automatically when an adapter is observed.
247
+ * @return {Promise<void>} A promise that resolves when initialization is complete
248
+ * @mermaid
249
+ * sequenceDiagram
250
+ * participant Dispatch
251
+ * participant Adapter
252
+ * participant Proxy
253
+ *
254
+ * Dispatch->>Dispatch: initialize()
255
+ * Dispatch->>Dispatch: Check if adapter exists
256
+ * alt No adapter
257
+ * Dispatch-->>Dispatch: Throw InternalError
258
+ * end
259
+ *
260
+ * loop For each CRUD method
261
+ * Dispatch->>Adapter: Check if method exists
262
+ * alt Method doesn't exist
263
+ * Dispatch-->>Dispatch: Throw InternalError
264
+ * end
265
+ *
266
+ * Dispatch->>Adapter: Get property descriptor
267
+ * loop While descriptor not found
268
+ * Dispatch->>Adapter: Check prototype chain
269
+ * end
270
+ *
271
+ * alt Descriptor not found or not writable
272
+ * Dispatch->>Dispatch: Log error and continue
273
+ * else Descriptor found and writable
274
+ * Dispatch->>Proxy: Create proxy for method
275
+ * Dispatch->>Adapter: Replace method with proxy
276
+ * end
277
+ * end
278
+ */
279
+ async initialize() {
85
280
  if (!this.adapter)
86
281
  throw new InternalError(`No adapter observed for dispatch`);
87
282
  const adapter = this.adapter;
@@ -133,20 +328,47 @@ class Dispatch {
133
328
  });
134
329
  });
135
330
  }
331
+ /**
332
+ * @description Closes the dispatch
333
+ * @summary Performs any necessary cleanup when the dispatch is no longer needed
334
+ * @return {Promise<void>} A promise that resolves when closing is complete
335
+ */
336
+ async close() {
337
+ // to nothing in this instance but may be required for closing connections
338
+ }
339
+ /**
340
+ * @description Starts observing an adapter
341
+ * @summary Connects this dispatch to an adapter to monitor its operations
342
+ * @param {Adapter<Y, any, any, any>} observer - The adapter to observe
343
+ * @return {void}
344
+ */
136
345
  observe(observer) {
137
346
  if (!(observer instanceof Adapter))
138
347
  throw new UnsupportedError("Only Adapters can be observed by dispatch");
139
348
  this.adapter = observer;
140
349
  this.native = observer.native;
141
350
  this.models = Adapter.models(this.adapter.alias);
142
- this.initialize();
143
- this.log.verbose(`Dispatch initialized for ${this.adapter.alias} adapter`);
351
+ this.initialize().then(() => this.log.verbose(`Dispatch initialized for ${this.adapter.alias} adapter`));
144
352
  }
353
+ /**
354
+ * @description Stops observing an adapter
355
+ * @summary Disconnects this dispatch from an adapter
356
+ * @param {Observer} observer - The adapter to stop observing
357
+ * @return {void}
358
+ */
145
359
  unObserve(observer) {
146
360
  if (this.adapter !== observer)
147
361
  throw new UnsupportedError("Only the adapter that was used to observe can be unobserved");
148
362
  this.adapter = undefined;
149
363
  }
364
+ /**
365
+ * @description Updates observers about a database event
366
+ * @summary Notifies observers about a change in the database
367
+ * @param {string} table - The name of the table where the change occurred
368
+ * @param {OperationKeys|BulkCrudOperationKeys|string} event - The type of operation that occurred
369
+ * @param {EventIds} id - The identifier(s) of the affected record(s)
370
+ * @return {Promise<void>} A promise that resolves when all observers have been notified
371
+ */
150
372
  async updateObservers(table, event, id) {
151
373
  if (!this.adapter)
152
374
  throw new InternalError(`No adapter observed for dispatch`);
@@ -159,25 +381,120 @@ class Dispatch {
159
381
  }
160
382
  }
161
383
 
384
+ /**
385
+ * @description Manages a collection of observers for database events
386
+ * @summary The ObserverHandler class implements the Observable interface and provides a centralized
387
+ * way to manage multiple observers. It allows registering observers with optional filters to control
388
+ * which events they receive notifications for, and handles the process of notifying all relevant
389
+ * observers when database events occur.
390
+ * @class ObserverHandler
391
+ * @example
392
+ * ```typescript
393
+ * // Create an observer handler
394
+ * const handler = new ObserverHandler();
395
+ *
396
+ * // Register an observer
397
+ * const myObserver = {
398
+ * refresh: async (table, event, id) => {
399
+ * console.log(`Change in ${table}: ${event} for ID ${id}`);
400
+ * }
401
+ * };
402
+ *
403
+ * // Add observer with a filter for only user table events
404
+ * handler.observe(myObserver, (table, event, id) => table === 'users');
405
+ *
406
+ * // Notify observers about an event
407
+ * await handler.updateObservers(logger, 'users', 'CREATE', 123);
408
+ *
409
+ * // Remove an observer when no longer needed
410
+ * handler.unObserve(myObserver);
411
+ * ```
412
+ */
162
413
  class ObserverHandler {
163
414
  constructor() {
415
+ /**
416
+ * @description Collection of registered observers
417
+ * @summary Array of observer objects along with their optional filters
418
+ */
164
419
  this.observers = [];
165
420
  }
421
+ /**
422
+ * @description Gets the number of registered observers
423
+ * @summary Returns the count of observers currently registered with this handler
424
+ * @return {number} The number of registered observers
425
+ */
166
426
  count() {
167
427
  return this.observers.length;
168
428
  }
429
+ /**
430
+ * @description Registers a new observer
431
+ * @summary Adds an observer to the collection with an optional filter function
432
+ * @param {Observer} observer - The observer to register
433
+ * @param {ObserverFilter} [filter] - Optional filter function to determine which events the observer receives
434
+ * @return {void}
435
+ */
169
436
  observe(observer, filter) {
170
437
  const index = this.observers.map((o) => o.observer).indexOf(observer);
171
438
  if (index !== -1)
172
439
  throw new InternalError("Observer already registered");
173
440
  this.observers.push({ observer: observer, filter: filter });
174
441
  }
442
+ /**
443
+ * @description Unregisters an observer
444
+ * @summary Removes an observer from the collection
445
+ * @param {Observer} observer - The observer to unregister
446
+ * @return {void}
447
+ */
175
448
  unObserve(observer) {
176
449
  const index = this.observers.map((o) => o.observer).indexOf(observer);
177
450
  if (index === -1)
178
451
  throw new InternalError("Failed to find Observer");
179
452
  this.observers.splice(index, 1);
180
453
  }
454
+ /**
455
+ * @description Notifies all relevant observers about a database event
456
+ * @summary Filters observers based on their filter functions and calls refresh on each matching observer
457
+ * @param {Logger} log - Logger for recording notification activities
458
+ * @param {string} table - The name of the table where the event occurred
459
+ * @param {OperationKeys|BulkCrudOperationKeys|string} event - The type of operation that occurred
460
+ * @param {EventIds} id - The identifier(s) of the affected record(s)
461
+ * @param {...any[]} args - Additional arguments to pass to the observers
462
+ * @return {Promise<void>} A promise that resolves when all observers have been notified
463
+ * @mermaid
464
+ * sequenceDiagram
465
+ * participant Client
466
+ * participant ObserverHandler
467
+ * participant Observer
468
+ *
469
+ * Client->>ObserverHandler: updateObservers(log, table, event, id, ...args)
470
+ *
471
+ * ObserverHandler->>ObserverHandler: Filter observers
472
+ *
473
+ * loop For each observer with matching filter
474
+ * alt Observer has filter
475
+ * ObserverHandler->>Observer: Apply filter(table, event, id)
476
+ * alt Filter throws error
477
+ * ObserverHandler->>Logger: Log error
478
+ * ObserverHandler-->>ObserverHandler: Skip observer
479
+ * else Filter returns true
480
+ * ObserverHandler->>Observer: refresh(table, event, id, ...args)
481
+ * else Filter returns false
482
+ * ObserverHandler-->>ObserverHandler: Skip observer
483
+ * end
484
+ * else No filter
485
+ * ObserverHandler->>Observer: refresh(table, event, id, ...args)
486
+ * end
487
+ * end
488
+ *
489
+ * ObserverHandler->>ObserverHandler: Process results
490
+ * loop For each result
491
+ * alt Result is rejected
492
+ * ObserverHandler->>Logger: Log error
493
+ * end
494
+ * end
495
+ *
496
+ * ObserverHandler-->>Client: Return
497
+ */
181
498
  async updateObservers(log, table, event, id, ...args) {
182
499
  const results = await Promise.allSettled(this.observers
183
500
  .filter((o) => {
@@ -211,40 +528,146 @@ Decoration.setFlavourResolver((obj) => {
211
528
  }
212
529
  });
213
530
  /**
214
- * @summary Abstract Decaf-ts Persistence Adapter Class
215
- * @description Offers the base implementation for all Adapter Classes
216
- * and manages them various registered {@link Adapter}s
531
+ * @description Abstract base class for database adapters
532
+ * @summary Provides the foundation for all database adapters in the persistence layer. This class
533
+ * implements several interfaces to provide a consistent API for database operations, observer
534
+ * pattern support, and error handling. It manages adapter registration, CRUD operations, and
535
+ * observer notifications.
536
+ * @template Y - The underlying database driver type
537
+ * @template Q - The query object type used by the adapter
538
+ * @template F - The repository flags type
539
+ * @template C - The context type
540
+ * @param {Y} _native - The underlying database driver instance
541
+ * @param {string} flavour - The identifier for this adapter type
542
+ * @param {string} [_alias] - Optional alternative name for this adapter
543
+ * @class Adapter
544
+ * @example
545
+ * ```typescript
546
+ * // Implementing a concrete adapter
547
+ * class PostgresAdapter extends Adapter<pg.Client, pg.Query, PostgresFlags, PostgresContext> {
548
+ * constructor(client: pg.Client) {
549
+ * super(client, 'postgres');
550
+ * }
217
551
  *
218
- * @typedef Y the underlying persistence object type or the required config to set it up
219
- * @typedef Q The query object the adapter uses
552
+ * async initialize() {
553
+ * // Set up the adapter
554
+ * await this.native.connect();
555
+ * }
220
556
  *
221
- * @param {Y} native the underlying persistence object
222
- * @param {string} flavour the under witch the persistence adapter should be stored
557
+ * async create(tableName, id, model) {
558
+ * // Implementation for creating records
559
+ * const columns = Object.keys(model).join(', ');
560
+ * const values = Object.values(model);
561
+ * const placeholders = values.map((_, i) => `$${i+1}`).join(', ');
223
562
  *
224
- * @class Adapter
225
- * @implements RawExecutor
226
- * @implements Observable
563
+ * const query = `INSERT INTO ${tableName} (${columns}) VALUES (${placeholders}) RETURNING *`;
564
+ * const result = await this.native.query(query, values);
565
+ * return result.rows[0];
566
+ * }
567
+ *
568
+ * // Other required method implementations...
569
+ * }
570
+ *
571
+ * // Using the adapter
572
+ * const pgClient = new pg.Client(connectionString);
573
+ * const adapter = new PostgresAdapter(pgClient);
574
+ * await adapter.initialize();
575
+ *
576
+ * // Set as the default adapter
577
+ * Adapter.setCurrent('postgres');
578
+ *
579
+ * // Perform operations
580
+ * const user = await adapter.create('users', 1, { name: 'John', email: 'john@example.com' });
581
+ * ```
582
+ * @mermaid
583
+ * classDiagram
584
+ * class Adapter {
585
+ * +Y native
586
+ * +string flavour
587
+ * +string alias
588
+ * +create(tableName, id, model)
589
+ * +read(tableName, id)
590
+ * +update(tableName, id, model)
591
+ * +delete(tableName, id)
592
+ * +observe(observer, filter)
593
+ * +unObserve(observer)
594
+ * +static current
595
+ * +static get(flavour)
596
+ * +static setCurrent(flavour)
597
+ * }
598
+ *
599
+ * class RawExecutor {
600
+ * +raw(query)
601
+ * }
602
+ *
603
+ * class Observable {
604
+ * +observe(observer, filter)
605
+ * +unObserve(observer)
606
+ * +updateObservers(table, event, id)
607
+ * }
608
+ *
609
+ * class Observer {
610
+ * +refresh(table, event, id)
611
+ * }
612
+ *
613
+ * class ErrorParser {
614
+ * +parseError(err)
615
+ * }
616
+ *
617
+ * Adapter --|> RawExecutor
618
+ * Adapter --|> Observable
619
+ * Adapter --|> Observer
620
+ * Adapter --|> ErrorParser
227
621
  */
228
622
  class Adapter {
229
623
  static { this._cache = {}; }
624
+ /**
625
+ * @description Logger accessor
626
+ * @summary Gets or initializes the logger for this adapter instance
627
+ * @return {Logger} The logger instance
628
+ */
230
629
  get log() {
231
630
  if (!this.logger)
232
631
  this.logger = Logging.for(this);
233
632
  return this.logger;
234
633
  }
634
+ /**
635
+ * @description Gets the native database driver
636
+ * @summary Provides access to the underlying database driver instance
637
+ * @return {Y} The native database driver
638
+ */
235
639
  get native() {
236
640
  return this._native;
237
641
  }
642
+ /**
643
+ * @description Gets the adapter's alias or flavor name
644
+ * @summary Returns the alias if set, otherwise returns the flavor name
645
+ * @return {string} The adapter's identifier
646
+ */
238
647
  get alias() {
239
648
  return this._alias || this.flavour;
240
649
  }
650
+ /**
651
+ * @description Gets the repository constructor for this adapter
652
+ * @summary Returns the constructor for creating repositories that work with this adapter
653
+ * @template M - The model type
654
+ * @return {Constructor<Repository<M, Q, Adapter<Y, Q, F, C>, F, C>>} The repository constructor
655
+ */
241
656
  repository() {
242
657
  return Repository;
243
658
  }
659
+ /**
660
+ * @description Creates a new adapter instance
661
+ * @summary Initializes the adapter with the native driver and registers it in the adapter cache
662
+ */
244
663
  constructor(_native, flavour, _alias) {
245
664
  this._native = _native;
246
665
  this.flavour = flavour;
247
666
  this._alias = _alias;
667
+ /**
668
+ * @description The context constructor for this adapter
669
+ * @summary Reference to the context class constructor used by this adapter
670
+ */
248
671
  this.Context = (Context);
249
672
  if (this.flavour in Adapter._cache)
250
673
  throw new InternalError(`${this.alias} persistence adapter ${this._alias ? `(${this.flavour}) ` : ""} already registered`);
@@ -255,15 +678,42 @@ class Adapter {
255
678
  Adapter._current = this;
256
679
  }
257
680
  }
681
+ /**
682
+ * @description Creates a new dispatch instance
683
+ * @summary Factory method that creates a dispatch instance for this adapter
684
+ * @return {Dispatch<Y>} A new dispatch instance
685
+ */
258
686
  Dispatch() {
259
687
  return new Dispatch();
260
688
  }
689
+ /**
690
+ * @description Creates a new observer handler
691
+ * @summary Factory method that creates an observer handler for this adapter
692
+ * @return {ObserverHandler} A new observer handler instance
693
+ */
261
694
  ObserverHandler() {
262
695
  return new ObserverHandler();
263
696
  }
697
+ /**
698
+ * @description Checks if an attribute name is reserved
699
+ * @summary Determines if a given attribute name is reserved and cannot be used as a column name
700
+ * @param {string} attr - The attribute name to check
701
+ * @return {boolean} True if the attribute is reserved, false otherwise
702
+ */
264
703
  isReserved(attr) {
265
704
  return !attr;
266
705
  }
706
+ /**
707
+ * @description Creates repository flags for an operation
708
+ * @summary Generates a set of flags that describe a database operation, combining default flags with overrides
709
+ * @template F - The Repository Flags type
710
+ * @template M - The model type
711
+ * @param {OperationKeys} operation - The type of operation being performed
712
+ * @param {Constructor<M>} model - The model constructor
713
+ * @param {Partial<F>} flags - Custom flag overrides
714
+ * @param {...any[]} args - Additional arguments
715
+ * @return {F} The complete set of flags
716
+ */
267
717
  flags(operation, model, flags,
268
718
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
269
719
  ...args) {
@@ -274,12 +724,32 @@ class Adapter {
274
724
  operation: operation,
275
725
  });
276
726
  }
727
+ /**
728
+ * @description Creates a context for a database operation
729
+ * @summary Generates a context object that describes a database operation, used for tracking and auditing
730
+ * @template F - The Repository flags type
731
+ * @template M - The model type
732
+ * @param {OperationKeys.CREATE|OperationKeys.READ|OperationKeys.UPDATE|OperationKeys.DELETE} operation - The type of operation
733
+ * @param {Partial<F>} overrides - Custom flag overrides
734
+ * @param {Constructor<M>} model - The model constructor
735
+ * @param {...any[]} args - Additional arguments
736
+ * @return {Promise<C>} A promise that resolves to the context object
737
+ */
277
738
  async context(operation, overrides, model, ...args) {
278
739
  this.log
279
740
  .for(this.context)
280
- .debug(`Creating new context for ${operation} operation on ${model.name} model with flags: ${JSON.stringify(overrides)}`);
281
- return new this.Context(this.flags(operation, model, overrides, ...args));
741
+ .debug(`Creating new context for ${operation} operation on ${model.name} model with flag overrides: ${JSON.stringify(overrides)}`);
742
+ return new this.Context().accumulate(this.flags(operation, model, overrides, ...args));
282
743
  }
744
+ /**
745
+ * @description Prepares a model for persistence
746
+ * @summary Converts a model instance into a format suitable for database storage,
747
+ * handling column mapping and separating transient properties
748
+ * @template M - The model type
749
+ * @param {M} model - The model instance to prepare
750
+ * @param pk - The primary key property name
751
+ * @return The prepared data
752
+ */
283
753
  prepare(model, pk) {
284
754
  const log = this.log.for(this.prepare);
285
755
  log.silly(`Preparing model ${model.constructor.name} before persisting`);
@@ -308,6 +778,18 @@ class Adapter {
308
778
  transient: split.transient,
309
779
  };
310
780
  }
781
+ /**
782
+ * @description Converts database data back into a model instance
783
+ * @summary Reconstructs a model instance from database data, handling column mapping
784
+ * and reattaching transient properties
785
+ * @template M - The model type
786
+ * @param obj - The database record
787
+ * @param {string|Constructor<M>} clazz - The model class or name
788
+ * @param pk - The primary key property name
789
+ * @param {string|number|bigint} id - The primary key value
790
+ * @param [transient] - Transient properties to reattach
791
+ * @return {M} The reconstructed model instance
792
+ */
311
793
  revert(obj, clazz, pk, id, transient) {
312
794
  const log = this.log.for(this.revert);
313
795
  const ob = {};
@@ -340,6 +822,15 @@ class Adapter {
340
822
  }
341
823
  return result;
342
824
  }
825
+ /**
826
+ * @description Creates multiple records in the database
827
+ * @summary Inserts multiple records with the given IDs and data into the specified table
828
+ * @param {string} tableName - The name of the table to insert into
829
+ * @param id - The identifiers for the new records
830
+ * @param model - The data to insert for each record
831
+ * @param {...any[]} args - Additional arguments specific to the adapter implementation
832
+ * @return A promise that resolves to an array of created records
833
+ */
343
834
  async createAll(tableName, id, model, ...args) {
344
835
  if (id.length !== model.length)
345
836
  throw new InternalError("Ids and models must have the same length");
@@ -348,12 +839,29 @@ class Adapter {
348
839
  log.debug(`pks: ${id}`);
349
840
  return Promise.all(id.map((i, count) => this.create(tableName, i, model[count], ...args)));
350
841
  }
842
+ /**
843
+ * @description Retrieves multiple records from the database
844
+ * @summary Fetches multiple records with the given IDs from the specified table
845
+ * @param {string} tableName - The name of the table to read from
846
+ * @param id - The identifiers of the records to retrieve
847
+ * @param {...any[]} args - Additional arguments specific to the adapter implementation
848
+ * @return A promise that resolves to an array of retrieved records
849
+ */
351
850
  async readAll(tableName, id, ...args) {
352
851
  const log = this.log.for(this.readAll);
353
852
  log.verbose(`Reading ${id.length} entries ${tableName} table`);
354
853
  log.debug(`pks: ${id}`);
355
854
  return Promise.all(id.map((i) => this.read(tableName, i, ...args)));
356
855
  }
856
+ /**
857
+ * @description Updates multiple records in the database
858
+ * @summary Modifies multiple existing records with the given IDs in the specified table
859
+ * @param {string} tableName - The name of the table to update
860
+ * @param {string[]|number[]} id - The identifiers of the records to update
861
+ * @param model - The new data for each record
862
+ * @param {...any[]} args - Additional arguments specific to the adapter implementation
863
+ * @return A promise that resolves to an array of updated records
864
+ */
357
865
  async updateAll(tableName, id, model, ...args) {
358
866
  if (id.length !== model.length)
359
867
  throw new InternalError("Ids and models must have the same length");
@@ -362,6 +870,14 @@ class Adapter {
362
870
  log.debug(`pks: ${id}`);
363
871
  return Promise.all(id.map((i, count) => this.update(tableName, i, model[count], ...args)));
364
872
  }
873
+ /**
874
+ * @description Deletes multiple records from the database
875
+ * @summary Removes multiple records with the given IDs from the specified table
876
+ * @param {string} tableName - The name of the table to delete from
877
+ * @param id - The identifiers of the records to delete
878
+ * @param {...any[]} args - Additional arguments specific to the adapter implementation
879
+ * @return A promise that resolves to an array of deleted records
880
+ */
365
881
  async deleteAll(tableName, id, ...args) {
366
882
  const log = this.log.for(this.createAll);
367
883
  log.verbose(`Deleting ${id.length} entries ${tableName} table`);
@@ -369,8 +885,12 @@ class Adapter {
369
885
  return Promise.all(id.map((i) => this.delete(tableName, i, ...args)));
370
886
  }
371
887
  /**
372
- *
373
- * @see {Observable#observe}
888
+ * @description Registers an observer for database events
889
+ * @summary Adds an observer to be notified about database changes. The observer can optionally
890
+ * provide a filter function to receive only specific events.
891
+ * @param {Observer} observer - The observer to register
892
+ * @param {ObserverFilter} [filter] - Optional filter function to determine which events the observer receives
893
+ * @return {void}
374
894
  */
375
895
  observe(observer, filter) {
376
896
  if (!this.observerHandler)
@@ -389,10 +909,10 @@ class Adapter {
389
909
  }
390
910
  }
391
911
  /**
392
- * @summary Unregisters an {@link Observer}
393
- * @param {Observer} observer
394
- *
395
- * @see {Observable#unObserve}
912
+ * @description Unregisters an observer
913
+ * @summary Removes a previously registered observer so it no longer receives database event notifications
914
+ * @param {Observer} observer - The observer to unregister
915
+ * @return {void}
396
916
  */
397
917
  unObserve(observer) {
398
918
  if (!this.observerHandler)
@@ -402,6 +922,16 @@ class Adapter {
402
922
  .for(this.unObserve)
403
923
  .verbose(`Observer ${observer.toString()} removed`);
404
924
  }
925
+ /**
926
+ * @description Notifies all observers about a database event
927
+ * @summary Sends notifications to all registered observers about a change in the database,
928
+ * filtering based on each observer's filter function
929
+ * @param {string} table - The name of the table where the change occurred
930
+ * @param {OperationKeys|BulkCrudOperationKeys|string} event - The type of operation that occurred
931
+ * @param {EventIds} id - The identifier(s) of the affected record(s)
932
+ * @param {...any[]} args - Additional arguments to pass to the observers
933
+ * @return {Promise<void>} A promise that resolves when all observers have been notified
934
+ */
405
935
  async updateObservers(table, event, id, ...args) {
406
936
  if (!this.observerHandler)
407
937
  throw new InternalError("ObserverHandler not initialized. Did you register any observables?");
@@ -409,35 +939,90 @@ class Adapter {
409
939
  log.verbose(`Updating ${this.observerHandler.count()} observers for adapter ${this.alias}`);
410
940
  await this.observerHandler.updateObservers(this.log, table, event, id, ...args);
411
941
  }
942
+ /**
943
+ * @description Refreshes data based on a database event
944
+ * @summary Implementation of the Observer interface method that delegates to updateObservers
945
+ * @param {string} table - The name of the table where the change occurred
946
+ * @param {OperationKeys|BulkCrudOperationKeys|string} event - The type of operation that occurred
947
+ * @param {EventIds} id - The identifier(s) of the affected record(s)
948
+ * @param {...any[]} args - Additional arguments related to the event
949
+ * @return {Promise<void>} A promise that resolves when the refresh is complete
950
+ */
412
951
  async refresh(table, event, id, ...args) {
413
952
  return this.updateObservers(table, event, id, ...args);
414
953
  }
954
+ /**
955
+ * @description Gets a string representation of the adapter
956
+ * @summary Returns a human-readable string identifying this adapter
957
+ * @return {string} A string representation of the adapter
958
+ */
415
959
  toString() {
416
960
  return `${this.flavour} persistence Adapter`;
417
961
  }
962
+ /**
963
+ * @description Gets the adapter flavor associated with a model
964
+ * @summary Retrieves the adapter flavor that should be used for a specific model class
965
+ * @template M - The model type
966
+ * @param {Constructor<M>} model - The model constructor
967
+ * @return {string} The adapter flavor name
968
+ */
418
969
  static flavourOf(model) {
419
970
  return (Reflect.getMetadata(this.key(PersistenceKeys.ADAPTER), model) ||
420
971
  this.current.flavour);
421
972
  }
973
+ /**
974
+ * @description Gets the current default adapter
975
+ * @summary Retrieves the adapter that is currently set as the default for operations
976
+ * @return {Adapter<any, any, any, any>} The current adapter
977
+ */
422
978
  static get current() {
423
979
  if (!Adapter._current)
424
980
  throw new InternalError(`No persistence flavour set. Please initialize your adapter`);
425
981
  return Adapter._current;
426
982
  }
983
+ /**
984
+ * @description Gets an adapter by flavor
985
+ * @summary Retrieves a registered adapter by its flavor name
986
+ * @template Y - The database driver type
987
+ * @template Q - The query type
988
+ * @template C - The context type
989
+ * @template F - The repository flags type
990
+ * @param {string} flavour - The flavor name of the adapter to retrieve
991
+ * @return {Adapter<Y, Q, F, C> | undefined} The adapter instance or undefined if not found
992
+ */
427
993
  static get(flavour) {
428
994
  if (flavour in this._cache)
429
995
  return this._cache[flavour];
430
996
  throw new InternalError(`No Adapter registered under ${flavour}.`);
431
997
  }
998
+ /**
999
+ * @description Sets the current default adapter
1000
+ * @summary Changes which adapter is used as the default for operations
1001
+ * @param {string} flavour - The flavor name of the adapter to set as current
1002
+ * @return {void}
1003
+ */
432
1004
  static setCurrent(flavour) {
433
1005
  const adapter = Adapter.get(flavour);
434
1006
  if (!adapter)
435
1007
  throw new NotFoundError(`No persistence flavour ${flavour} registered`);
436
1008
  this._current = adapter;
437
1009
  }
1010
+ /**
1011
+ * @description Creates a metadata key
1012
+ * @summary Generates a standardized metadata key for persistence-related metadata
1013
+ * @param {string} key - The base key name
1014
+ * @return {string} The formatted metadata key
1015
+ */
438
1016
  static key(key) {
439
1017
  return Repository.key(key);
440
1018
  }
1019
+ /**
1020
+ * @description Gets all models associated with an adapter flavor
1021
+ * @summary Retrieves all model constructors that are configured to use a specific adapter flavor
1022
+ * @template M - The model type
1023
+ * @param {string} flavour - The adapter flavor to find models for
1024
+ * @return An array of model constructors
1025
+ */
441
1026
  static models(flavour) {
442
1027
  try {
443
1028
  const registry = Model.getRegistry();
@@ -483,6 +1068,15 @@ __decorate([
483
1068
  __metadata("design:returntype", void 0)
484
1069
  ], Adapter.prototype, "unObserve", null);
485
1070
 
1071
+ /**
1072
+ * @description Gets the table name for a model
1073
+ * @summary Retrieves the table name associated with a model by checking metadata or falling back to the constructor name
1074
+ * @template M - Type that extends Model
1075
+ * @param {M | Constructor<M>} model - The model instance or constructor to get the table name for
1076
+ * @return {string} The table name for the model
1077
+ * @function getTableName
1078
+ * @memberOf module:core
1079
+ */
486
1080
  function getTableName(model) {
487
1081
  const obj = model instanceof Model ? model.constructor : model;
488
1082
  const metadata = Reflect.getOwnMetadata(Adapter.key(PersistenceKeys.TABLE), obj);
@@ -494,22 +1088,101 @@ function getTableName(model) {
494
1088
  }
495
1089
  return model.name;
496
1090
  }
1091
+ /**
1092
+ * @description Generates a sequence name for a model
1093
+ * @summary Creates a standardized sequence name by combining the table name with additional arguments
1094
+ * @template M - Type that extends Model
1095
+ * @param {M | Constructor<M>} model - The model instance or constructor to generate the sequence name for
1096
+ * @param {...string} args - Additional string arguments to append to the sequence name
1097
+ * @return {string} The generated sequence name
1098
+ * @function sequenceNameForModel
1099
+ * @memberOf module:core
1100
+ */
497
1101
  function sequenceNameForModel(model, ...args) {
498
1102
  return [getTableName(model), ...args].join("_");
499
1103
  }
500
1104
 
1105
+ /**
1106
+ * @description Abstract base class for sequence generation
1107
+ * @summary Provides a framework for generating sequential values (like primary keys) in the persistence layer.
1108
+ * Implementations of this class handle the specifics of how sequences are stored and incremented in different
1109
+ * database systems.
1110
+ * @param {SequenceOptions} options - Configuration options for the sequence generator
1111
+ * @class Sequence
1112
+ * @example
1113
+ * ```typescript
1114
+ * // Example implementation for a specific database
1115
+ * class PostgresSequence extends Sequence {
1116
+ * constructor(options: SequenceOptions) {
1117
+ * super(options);
1118
+ * }
1119
+ *
1120
+ * async next(): Promise<number> {
1121
+ * // Implementation to get next value from PostgreSQL sequence
1122
+ * const result = await this.options.executor.raw(`SELECT nextval('${this.options.name}')`);
1123
+ * return parseInt(result.rows[0].nextval);
1124
+ * }
1125
+ *
1126
+ * async current(): Promise<number> {
1127
+ * // Implementation to get current value from PostgreSQL sequence
1128
+ * const result = await this.options.executor.raw(`SELECT currval('${this.options.name}')`);
1129
+ * return parseInt(result.rows[0].currval);
1130
+ * }
1131
+ *
1132
+ * async range(count: number): Promise<number[]> {
1133
+ * // Implementation to get a range of values
1134
+ * const values: number[] = [];
1135
+ * for (let i = 0; i < count; i++) {
1136
+ * values.push(await this.next());
1137
+ * }
1138
+ * return values;
1139
+ * }
1140
+ * }
1141
+ *
1142
+ * // Usage
1143
+ * const sequence = new PostgresSequence({
1144
+ * name: 'user_id_seq',
1145
+ * executor: dbExecutor
1146
+ * });
1147
+ *
1148
+ * const nextId = await sequence.next();
1149
+ * ```
1150
+ */
501
1151
  class Sequence {
1152
+ /**
1153
+ * @description Accessor for the logger instance
1154
+ * @summary Gets or initializes the logger for this sequence
1155
+ * @return {Logger} The logger instance
1156
+ */
502
1157
  get log() {
503
1158
  if (!this.logger)
504
1159
  this.logger = Logging.for(this);
505
1160
  return this.logger;
506
1161
  }
1162
+ /**
1163
+ * @description Creates a new sequence instance
1164
+ * @summary Protected constructor that initializes the sequence with the provided options
1165
+ */
507
1166
  constructor(options) {
508
1167
  this.options = options;
509
1168
  }
1169
+ /**
1170
+ * @description Gets the primary key sequence name for a model
1171
+ * @summary Utility method that returns the standardized sequence name for a model's primary key
1172
+ * @template M - The model type
1173
+ * @param {M|Constructor<M>} model - The model instance or constructor
1174
+ * @return {string} The sequence name for the model's primary key
1175
+ */
510
1176
  static pk(model) {
511
1177
  return sequenceNameForModel(model, "pk");
512
1178
  }
1179
+ /**
1180
+ * @description Parses a sequence value to the appropriate type
1181
+ * @summary Converts a sequence value to the specified type (Number or BigInt)
1182
+ * @param {"Number"|"BigInt"|undefined} type - The target type to convert to
1183
+ * @param {string|number|bigint} value - The value to convert
1184
+ * @return {string|number|bigint} The converted value
1185
+ */
513
1186
  static parseValue(type, value) {
514
1187
  switch (type) {
515
1188
  case "Number":
@@ -526,27 +1199,112 @@ class Sequence {
526
1199
  }
527
1200
  }
528
1201
 
1202
+ /**
1203
+ * @description Specifies which persistence adapter flavor a model should use
1204
+ * @summary This decorator applies metadata to a model class to indicate which persistence adapter flavor
1205
+ * should be used when performing database operations on instances of the model. The flavor is a string
1206
+ * identifier that corresponds to a registered adapter configuration.
1207
+ * @param {string} flavour - The identifier of the adapter flavor to use
1208
+ * @return {Function} A decorator function that can be applied to a model class
1209
+ * @function uses
1210
+ * @category Class Decorators
1211
+ */
529
1212
  function uses(flavour) {
530
1213
  return apply(metadata(Adapter.key(PersistenceKeys.ADAPTER), flavour));
531
1214
  }
532
1215
 
1216
+ /**
1217
+ * @description Core repository implementation for database operations on models on a table by table way.
1218
+ * @summary Provides CRUD operations, querying capabilities, and observer pattern implementation for model persistence.
1219
+ * @template M - The model type that extends Model.
1220
+ * @template Q - The query type used by the adapter.
1221
+ * @template A - The adapter type for database operations.
1222
+ * @template F - The repository flags type.
1223
+ * @template C - The context type for operations.
1224
+ * @param {A} [adapter] - Optional adapter instance for database operations.
1225
+ * @param {Constructor<M>} [clazz] - Optional constructor for the model class.
1226
+ * @param {...any[]} [args] - Additional arguments for repository initialization.
1227
+ * @class Repository
1228
+ * @example
1229
+ * // Creating a repository for User model
1230
+ * const userRepo = Repository.forModel(User);
1231
+ *
1232
+ * // Using the repository for CRUD operations
1233
+ * const user = await userRepo.create(new User({ name: 'John' }));
1234
+ * const retrievedUser = await userRepo.read(user.id);
1235
+ * user.name = 'Jane';
1236
+ * await userRepo.update(user);
1237
+ * await userRepo.delete(user.id);
1238
+ *
1239
+ * // Querying with conditions
1240
+ * const users = await userRepo
1241
+ * .select()
1242
+ * .where({ name: 'Jane' })
1243
+ * .orderBy('createdAt', OrderDirection.DSC)
1244
+ * .limit(10)
1245
+ * .execute();
1246
+ * @mermaid
1247
+ * sequenceDiagram
1248
+ * participant C as Client Code
1249
+ * participant R as Repository
1250
+ * participant A as Adapter
1251
+ * participant DB as Database
1252
+ * participant O as Observers
1253
+ *
1254
+ * C->>+R: create(model)
1255
+ * R->>R: createPrefix(model)
1256
+ * R->>+A: prepare(model)
1257
+ * A-->>-R: prepared data
1258
+ * R->>+A: create(table, id, record)
1259
+ * A->>+DB: Insert Operation
1260
+ * DB-->>-A: Result
1261
+ * A-->>-R: record
1262
+ * R->>+A: revert(record)
1263
+ * A-->>-R: model instance
1264
+ * R->>R: createSuffix(model)
1265
+ * R->>+O: updateObservers(table, CREATE, id)
1266
+ * O-->>-R: Notification complete
1267
+ * R-->>-C: created model
1268
+ */
533
1269
  class Repository extends Repository$1 {
534
1270
  static { this._cache = {}; }
1271
+ /**
1272
+ * @description Logger instance for this repository.
1273
+ * @summary Provides access to the logger for this repository instance.
1274
+ * @return {Logger} The logger instance.
1275
+ */
535
1276
  get log() {
536
1277
  if (!this.logger)
537
1278
  this.logger = Logging.for(this);
538
1279
  return this.logger;
539
1280
  }
1281
+ /**
1282
+ * @description Adapter for database operations.
1283
+ * @summary Provides access to the adapter instance for this repository.
1284
+ * @template A - The adapter type.
1285
+ * @return {A} The adapter instance.
1286
+ * @throws {InternalError} If no adapter is found.
1287
+ */
540
1288
  get adapter() {
541
1289
  if (!this._adapter)
542
1290
  throw new InternalError(`No adapter found for this repository. did you use the @uses decorator or pass it in the constructor?`);
543
1291
  return this._adapter;
544
1292
  }
1293
+ /**
1294
+ * @description Table name for this repository's model.
1295
+ * @summary Gets the database table name associated with this repository's model.
1296
+ * @return {string} The table name.
1297
+ */
545
1298
  get tableName() {
546
1299
  if (!this._tableName)
547
1300
  this._tableName = Repository.table(this.class);
548
1301
  return this._tableName;
549
1302
  }
1303
+ /**
1304
+ * @description Primary key properties for this repository's model.
1305
+ * @summary Gets the sequence options containing primary key information.
1306
+ * @return {SequenceOptions} The primary key properties.
1307
+ */
550
1308
  get pkProps() {
551
1309
  return super.pkProps;
552
1310
  }
@@ -557,7 +1315,7 @@ class Repository extends Repository$1 {
557
1315
  if (adapter)
558
1316
  this._adapter = adapter;
559
1317
  if (clazz) {
560
- Repository.register(clazz, this);
1318
+ Repository.register(clazz, this, this.adapter.alias);
561
1319
  if (adapter) {
562
1320
  const flavour = Reflect.getMetadata(Adapter.key(PersistenceKeys.ADAPTER), clazz);
563
1321
  if (flavour && flavour !== adapter.flavour)
@@ -570,6 +1328,12 @@ class Repository extends Repository$1 {
570
1328
  wrapMethodWithContext(this, this[name + "Prefix"], m, this[name + "Suffix"]);
571
1329
  });
572
1330
  }
1331
+ /**
1332
+ * @description Creates a proxy with overridden repository flags.
1333
+ * @summary Returns a proxy of this repository with the specified flags overridden.
1334
+ * @param {Partial<F>} flags - The flags to override.
1335
+ * @return {Repository} A proxy of this repository with overridden flags.
1336
+ */
573
1337
  override(flags) {
574
1338
  this.log
575
1339
  .for(this.override)
@@ -583,9 +1347,23 @@ class Repository extends Repository$1 {
583
1347
  },
584
1348
  });
585
1349
  }
1350
+ /**
1351
+ * @description Creates a new observer handler.
1352
+ * @summary Factory method for creating an observer handler instance.
1353
+ * @return {ObserverHandler} A new observer handler instance.
1354
+ */
586
1355
  ObserverHandler() {
587
1356
  return new ObserverHandler();
588
1357
  }
1358
+ /**
1359
+ * @description Prepares a model for creation.
1360
+ * @summary Validates the model and prepares it for creation in the database.
1361
+ * @template M - The model type.
1362
+ * @param {M} model - The model to create.
1363
+ * @param {...any[]} args - Additional arguments.
1364
+ * @return The prepared model and context arguments.
1365
+ * @throws {ValidationError} If the model fails validation.
1366
+ */
589
1367
  async createPrefix(model, ...args) {
590
1368
  const contextArgs = await Context.args(OperationKeys.CREATE, this.class, args, this.adapter, this._overrides || {});
591
1369
  model = new this.class(model);
@@ -595,6 +1373,13 @@ class Repository extends Repository$1 {
595
1373
  throw new ValidationError(errors.toString());
596
1374
  return [model, ...contextArgs.args];
597
1375
  }
1376
+ /**
1377
+ * @description Creates a model in the database.
1378
+ * @summary Persists a model instance to the database.
1379
+ * @param {M} model - The model to create.
1380
+ * @param {...any[]} args - Additional arguments.
1381
+ * @return {Promise<M>} The created model with updated properties.
1382
+ */
598
1383
  async create(model, ...args) {
599
1384
  // eslint-disable-next-line prefer-const
600
1385
  let { record, id, transient } = this.adapter.prepare(model, this.pk);
@@ -604,9 +1389,23 @@ class Repository extends Repository$1 {
604
1389
  c = args[args.length - 1];
605
1390
  return this.adapter.revert(record, this.class, this.pk, id, c && c.get("rebuildWithTransient") ? transient : undefined);
606
1391
  }
1392
+ /**
1393
+ * @description Post-creation hook.
1394
+ * @summary Executes after a model is created to perform additional operations.
1395
+ * @param {M} model - The created model.
1396
+ * @param {C} context - The operation context.
1397
+ * @return {Promise<M>} The processed model.
1398
+ */
607
1399
  async createSuffix(model, context) {
608
1400
  return super.createSuffix(model, context);
609
1401
  }
1402
+ /**
1403
+ * @description Creates multiple models in the database.
1404
+ * @summary Persists multiple model instances to the database in a batch operation.
1405
+ * @param {M[]} models - The models to create.
1406
+ * @param {...any[]} args - Additional arguments.
1407
+ * @return {Promise<M[]>} The created models with updated properties.
1408
+ */
610
1409
  async createAll(models, ...args) {
611
1410
  if (!models.length)
612
1411
  return models;
@@ -616,6 +1415,14 @@ class Repository extends Repository$1 {
616
1415
  records = await this.adapter.createAll(this.tableName, ids, records, ...args);
617
1416
  return records.map((r, i) => this.adapter.revert(r, this.class, this.pk, ids[i]));
618
1417
  }
1418
+ /**
1419
+ * @description Prepares multiple models for creation.
1420
+ * @summary Validates multiple models and prepares them for creation in the database.
1421
+ * @param {M[]} models - The models to create.
1422
+ * @param {...any[]} args - Additional arguments.
1423
+ * @return The prepared models and context arguments.
1424
+ * @throws {ValidationError} If any model fails validation.
1425
+ */
619
1426
  async createAllPrefix(models, ...args) {
620
1427
  const contextArgs = await Context.args(OperationKeys.CREATE, this.class, args, this.adapter, this._overrides || {});
621
1428
  if (!models.length)
@@ -647,6 +1454,13 @@ class Repository extends Repository$1 {
647
1454
  throw new ValidationError(errors);
648
1455
  return [models, ...contextArgs.args];
649
1456
  }
1457
+ /**
1458
+ * @description Prepares for reading a model by ID.
1459
+ * @summary Prepares the context and enforces decorators before reading a model.
1460
+ * @param {string} key - The primary key of the model to read.
1461
+ * @param {...any[]} args - Additional arguments.
1462
+ * @return The key and context arguments.
1463
+ */
650
1464
  async readPrefix(key, ...args) {
651
1465
  const contextArgs = await Context.args(OperationKeys.READ, this.class, args, this.adapter, this._overrides || {});
652
1466
  const model = new this.class();
@@ -654,10 +1468,24 @@ class Repository extends Repository$1 {
654
1468
  await enforceDBDecorators(this, contextArgs.context, model, OperationKeys.READ, OperationKeys.ON);
655
1469
  return [key, ...contextArgs.args];
656
1470
  }
1471
+ /**
1472
+ * @description Reads a model from the database by ID.
1473
+ * @summary Retrieves a model instance from the database using its primary key.
1474
+ * @param {string|number|bigint} id - The primary key of the model to read.
1475
+ * @param {...any[]} args - Additional arguments.
1476
+ * @return {Promise<M>} The retrieved model instance.
1477
+ */
657
1478
  async read(id, ...args) {
658
1479
  const m = await this.adapter.read(this.tableName, id, ...args);
659
1480
  return this.adapter.revert(m, this.class, this.pk, id);
660
1481
  }
1482
+ /**
1483
+ * @description Prepares for reading multiple models by IDs.
1484
+ * @summary Prepares the context and enforces decorators before reading multiple models.
1485
+ * @param {string[]|number[]} keys - The primary keys of the models to read.
1486
+ * @param {...any[]} args - Additional arguments.
1487
+ * @return The keys and context arguments.
1488
+ */
661
1489
  async readAllPrefix(keys, ...args) {
662
1490
  const contextArgs = await Context.args(OperationKeys.READ, this.class, args, this.adapter, this._overrides || {});
663
1491
  await Promise.all(keys.map(async (k) => {
@@ -667,16 +1495,39 @@ class Repository extends Repository$1 {
667
1495
  }));
668
1496
  return [keys, ...contextArgs.args];
669
1497
  }
1498
+ /**
1499
+ * @description Reads multiple models from the database by IDs.
1500
+ * @summary Retrieves multiple model instances from the database using their primary keys.
1501
+ * @param {string[]|number[]} keys - The primary keys of the models to read.
1502
+ * @param {...any[]} args - Additional arguments.
1503
+ * @return {Promise<M[]>} The retrieved model instances.
1504
+ */
670
1505
  async readAll(keys, ...args) {
671
1506
  const records = await this.adapter.readAll(this.tableName, keys, ...args);
672
1507
  return records.map((r, i) => this.adapter.revert(r, this.class, this.pk, keys[i]));
673
1508
  }
1509
+ /**
1510
+ * @description Updates a model in the database.
1511
+ * @summary Persists changes to an existing model instance in the database.
1512
+ * @param {M} model - The model to update.
1513
+ * @param {...any[]} args - Additional arguments.
1514
+ * @return {Promise<M>} The updated model with refreshed properties.
1515
+ */
674
1516
  async update(model, ...args) {
675
1517
  // eslint-disable-next-line prefer-const
676
1518
  let { record, id, transient } = this.adapter.prepare(model, this.pk);
677
1519
  record = await this.adapter.update(this.tableName, id, record, ...args);
678
1520
  return this.adapter.revert(record, this.class, this.pk, id, transient);
679
1521
  }
1522
+ /**
1523
+ * @description Prepares a model for update.
1524
+ * @summary Validates the model and prepares it for update in the database.
1525
+ * @param {M} model - The model to update.
1526
+ * @param {...any[]} args - Additional arguments.
1527
+ * @return The prepared model and context arguments.
1528
+ * @throws {InternalError} If the model has no primary key value.
1529
+ * @throws {ValidationError} If the model fails validation.
1530
+ */
680
1531
  async updatePrefix(model, ...args) {
681
1532
  const contextArgs = await Context.args(OperationKeys.UPDATE, this.class, args, this.adapter, this._overrides || {});
682
1533
  const pk = model[this.pk];
@@ -694,11 +1545,27 @@ class Repository extends Repository$1 {
694
1545
  }
695
1546
  return [model, ...contextArgs.args];
696
1547
  }
1548
+ /**
1549
+ * @description Updates multiple models in the database.
1550
+ * @summary Persists changes to multiple existing model instances in the database in a batch operation.
1551
+ * @param {M[]} models - The models to update.
1552
+ * @param {...any[]} args - Additional arguments.
1553
+ * @return {Promise<M[]>} The updated models with refreshed properties.
1554
+ */
697
1555
  async updateAll(models, ...args) {
698
1556
  const records = models.map((m) => this.adapter.prepare(m, this.pk));
699
1557
  const updated = await this.adapter.updateAll(this.tableName, records.map((r) => r.id), records.map((r) => r.record), ...args);
700
1558
  return updated.map((u, i) => this.adapter.revert(u, this.class, this.pk, records[i].id));
701
1559
  }
1560
+ /**
1561
+ * @description Prepares multiple models for update.
1562
+ * @summary Validates multiple models and prepares them for update in the database.
1563
+ * @param {M[]} models - The models to update.
1564
+ * @param {...any[]} args - Additional arguments.
1565
+ * @return {Promise<any[]>} The prepared models and context arguments.
1566
+ * @throws {InternalError} If any model has no primary key value.
1567
+ * @throws {ValidationError} If any model fails validation.
1568
+ */
702
1569
  async updateAllPrefix(models, ...args) {
703
1570
  const contextArgs = await Context.args(OperationKeys.UPDATE, this.class, args, this.adapter, this._overrides || {});
704
1571
  const ids = models.map((m) => {
@@ -737,16 +1604,37 @@ class Repository extends Repository$1 {
737
1604
  });
738
1605
  return [models, ...contextArgs.args];
739
1606
  }
1607
+ /**
1608
+ * @description Prepares for deleting a model by ID.
1609
+ * @summary Prepares the context and enforces decorators before deleting a model.
1610
+ * @param {any} key - The primary key of the model to delete.
1611
+ * @param {...any[]} args - Additional arguments.
1612
+ * @return The key and context arguments.
1613
+ */
740
1614
  async deletePrefix(key, ...args) {
741
1615
  const contextArgs = await Context.args(OperationKeys.DELETE, this.class, args, this.adapter, this._overrides || {});
742
1616
  const model = await this.read(key, ...contextArgs.args);
743
1617
  await enforceDBDecorators(this, contextArgs.context, model, OperationKeys.DELETE, OperationKeys.ON);
744
1618
  return [key, ...contextArgs.args];
745
1619
  }
1620
+ /**
1621
+ * @description Deletes a model from the database by ID.
1622
+ * @summary Removes a model instance from the database using its primary key.
1623
+ * @param {string|number|bigint} id - The primary key of the model to delete.
1624
+ * @param {...any[]} args - Additional arguments.
1625
+ * @return {Promise<M>} The deleted model instance.
1626
+ */
746
1627
  async delete(id, ...args) {
747
1628
  const m = await this.adapter.delete(this.tableName, id, ...args);
748
1629
  return this.adapter.revert(m, this.class, this.pk, id);
749
1630
  }
1631
+ /**
1632
+ * @description Prepares for deleting multiple models by IDs.
1633
+ * @summary Prepares the context and enforces decorators before deleting multiple models.
1634
+ * @param {string[]|number[]} keys - The primary keys of the models to delete.
1635
+ * @param {...any[]} args - Additional arguments.
1636
+ * @return The keys and context arguments.
1637
+ */
750
1638
  async deleteAllPrefix(keys, ...args) {
751
1639
  const contextArgs = await Context.args(OperationKeys.DELETE, this.class, args, this.adapter, this._overrides || {});
752
1640
  const models = await this.readAll(keys, ...contextArgs.args);
@@ -755,16 +1643,40 @@ class Repository extends Repository$1 {
755
1643
  }));
756
1644
  return [keys, ...contextArgs.args];
757
1645
  }
1646
+ /**
1647
+ * @description Deletes multiple models from the database by IDs.
1648
+ * @summary Removes multiple model instances from the database using their primary keys.
1649
+ * @param {string[]|number[]} keys - The primary keys of the models to delete.
1650
+ * @param {...any[]} args - Additional arguments.
1651
+ * @return {Promise<M[]>} The deleted model instances.
1652
+ */
758
1653
  async deleteAll(keys, ...args) {
759
1654
  const results = await this.adapter.deleteAll(this.tableName, keys, ...args);
760
1655
  return results.map((r, i) => this.adapter.revert(r, this.class, this.pk, keys[i]));
761
1656
  }
1657
+ /**
1658
+ * @description Implementation of the select method.
1659
+ * @summary Creates a query builder for the model with optional field selection.
1660
+ * @template S - The array type of select selectors.
1661
+ * @param [selector] - Optional fields to select.
1662
+ * @return A query builder.
1663
+ */
762
1664
  select(selector) {
763
1665
  return this.adapter
764
1666
  .Statement()
765
1667
  .select(selector)
766
1668
  .from(this.class);
767
1669
  }
1670
+ /**
1671
+ * @description Executes a query with the specified conditions and options.
1672
+ * @summary Provides a simplified way to query the database with common query parameters.
1673
+ * @param {Condition<M>} condition - The condition to filter records.
1674
+ * @param orderBy - The field to order results by.
1675
+ * @param {OrderDirection} [order=OrderDirection.ASC] - The sort direction.
1676
+ * @param {number} [limit] - Optional maximum number of results to return.
1677
+ * @param {number} [skip] - Optional number of results to skip.
1678
+ * @return {Promise<M[]>} The query results as model instances.
1679
+ */
768
1680
  async query(condition, orderBy, order = OrderDirection.ASC, limit, skip) {
769
1681
  const sort = [orderBy, order];
770
1682
  const query = this.select().where(condition).orderBy(sort);
@@ -775,7 +1687,11 @@ class Repository extends Repository$1 {
775
1687
  return query.execute();
776
1688
  }
777
1689
  /**
778
- *
1690
+ * @description Registers an observer for this repository.
1691
+ * @summary Adds an observer that will be notified of changes to models in this repository.
1692
+ * @param {Observer} observer - The observer to register.
1693
+ * @param {ObserverFilter} [filter] - Optional filter to limit which events the observer receives.
1694
+ * @return {void}
779
1695
  * @see {Observable#observe}
780
1696
  */
781
1697
  observe(observer, filter) {
@@ -792,9 +1708,11 @@ class Repository extends Repository$1 {
792
1708
  log.verbose(`Registered new observer ${observer.toString()}`);
793
1709
  }
794
1710
  /**
795
- * @summary Unregisters an {@link Observer}
796
- * @param {Observer} observer
797
- *
1711
+ * @description Unregisters an observer from this repository.
1712
+ * @summary Removes an observer so it will no longer receive notifications of changes.
1713
+ * @param {Observer} observer - The observer to unregister.
1714
+ * @return {void}
1715
+ * @throws {InternalError} If the observer handler is not initialized.
798
1716
  * @see {Observable#unObserve}
799
1717
  */
800
1718
  unObserve(observer) {
@@ -810,6 +1728,16 @@ class Repository extends Repository$1 {
810
1728
  this.log.verbose(`No longer observing adapter ${this.adapter.flavour}`);
811
1729
  }
812
1730
  }
1731
+ /**
1732
+ * @description Notifies all observers of an event.
1733
+ * @summary Updates all registered observers with information about a database event.
1734
+ * @param {string} table - The table name where the event occurred.
1735
+ * @param {OperationKeys|BulkCrudOperationKeys|string} event - The type of event that occurred.
1736
+ * @param {EventIds} id - The ID or IDs of the affected records.
1737
+ * @param {...any[]} args - Additional arguments.
1738
+ * @return {Promise<void>} A promise that resolves when all observers have been notified.
1739
+ * @throws {InternalError} If the observer handler is not initialized.
1740
+ */
813
1741
  async updateObservers(table, event, id, ...args) {
814
1742
  if (!this.observerHandler)
815
1743
  throw new InternalError("ObserverHandler not initialized. Did you register any observables?");
@@ -820,13 +1748,34 @@ class Repository extends Repository$1 {
820
1748
  ? id.map((i) => Sequence.parseValue(this.pkProps.type, i))
821
1749
  : Sequence.parseValue(this.pkProps.type, id), ...args);
822
1750
  }
1751
+ /**
1752
+ * @description Alias for updateObservers.
1753
+ * @summary Notifies all observers of an event (alias for updateObservers).
1754
+ * @param {string} table - The table name where the event occurred.
1755
+ * @param {OperationKeys|BulkCrudOperationKeys|string} event - The type of event that occurred.
1756
+ * @param {EventIds} id - The ID or IDs of the affected records.
1757
+ * @param {...any[]} args - Additional arguments.
1758
+ * @return {Promise<void>} A promise that resolves when all observers have been notified.
1759
+ */
823
1760
  async refresh(table, event, id, ...args) {
824
1761
  return this.updateObservers(table, event, id, ...args);
825
1762
  }
826
- static forModel(model, defaultFlavour, ...args) {
1763
+ /**
1764
+ * @description Creates or retrieves a repository for a model.
1765
+ * @summary Factory method that returns a repository instance for the specified model.
1766
+ * @template M - The model type that extends Model.
1767
+ * @template R - The repository type that extends Repo<M>.
1768
+ * @param {Constructor<M>} model - The model constructor.
1769
+ * @param {string} [defaultFlavour] - Optional default adapter flavour if not specified on the model.
1770
+ * @param {...any[]} [args] - Additional arguments to pass to the repository constructor.
1771
+ * @return {R} A repository instance for the model.
1772
+ * @throws {InternalError} If no adapter is registered for the flavour.
1773
+ */
1774
+ static forModel(model, alias, ...args) {
827
1775
  let repo;
1776
+ const _alias = alias || Reflect.getMetadata(Adapter.key(PersistenceKeys.ADAPTER), model);
828
1777
  try {
829
- repo = this.get(model);
1778
+ repo = this.get(model, _alias);
830
1779
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
831
1780
  }
832
1781
  catch (e) {
@@ -834,10 +1783,10 @@ class Repository extends Repository$1 {
834
1783
  }
835
1784
  if (repo instanceof Repository)
836
1785
  return repo;
837
- const flavour = Reflect.getMetadata(Adapter.key(PersistenceKeys.ADAPTER), model) ||
1786
+ const flavour = alias ||
1787
+ Reflect.getMetadata(Adapter.key(PersistenceKeys.ADAPTER), model) ||
838
1788
  (repo &&
839
- Reflect.getMetadata(Adapter.key(PersistenceKeys.ADAPTER), repo)) ||
840
- defaultFlavour;
1789
+ Reflect.getMetadata(Adapter.key(PersistenceKeys.ADAPTER), repo));
841
1790
  const adapter = flavour
842
1791
  ? Adapter.get(flavour)
843
1792
  : undefined;
@@ -846,18 +1795,47 @@ class Repository extends Repository$1 {
846
1795
  repo = repo || adapter.repository();
847
1796
  return new repo(adapter, model, ...args);
848
1797
  }
849
- static get(model) {
850
- const name = Repository.table(model);
1798
+ /**
1799
+ * @description Retrieves a repository for a model from the cache.
1800
+ * @summary Gets a repository constructor or instance for the specified model from the internal cache.
1801
+ * @template M - The model type that extends Model.
1802
+ * @param {Constructor<M>} model - The model constructor.
1803
+ * @return {Constructor<Repo<M>> | Repo<M>} The repository constructor or instance.
1804
+ * @throws {InternalError} If no repository is registered for the model.
1805
+ */
1806
+ static get(model, alias) {
1807
+ let name = Repository.table(model);
1808
+ if (alias) {
1809
+ name = [name, alias].join(DefaultSeparator);
1810
+ }
851
1811
  if (name in this._cache)
852
1812
  return this._cache[name];
853
1813
  throw new InternalError(`Could not find repository registered under ${name}`);
854
1814
  }
855
- static register(model, repo) {
856
- const name = Repository.table(model);
1815
+ /**
1816
+ * @description Registers a repository for a model.
1817
+ * @summary Associates a repository constructor or instance with a model in the internal cache.
1818
+ * @template M - The model type that extends Model.
1819
+ * @param {Constructor<M>} model - The model constructor.
1820
+ * @param {Constructor<Repo<M>> | Repo<M>} repo - The repository constructor or instance.
1821
+ * @throws {InternalError} If a repository is already registered for the model.
1822
+ */
1823
+ static register(model, repo, alias) {
1824
+ let name = Repository.table(model);
1825
+ if (alias) {
1826
+ name = [name, alias].join(DefaultSeparator);
1827
+ }
857
1828
  if (name in this._cache)
858
1829
  throw new InternalError(`${name} already registered as a repository`);
859
1830
  this._cache[name] = repo;
860
1831
  }
1832
+ /**
1833
+ * @description Sets metadata on a model instance.
1834
+ * @summary Attaches metadata to a model instance using a non-enumerable property.
1835
+ * @template M - The model type that extends Model.
1836
+ * @param {M} model - The model instance.
1837
+ * @param {any} metadata - The metadata to attach to the model.
1838
+ */
861
1839
  static setMetadata(model, metadata) {
862
1840
  Object.defineProperty(model, PersistenceKeys.METADATA, {
863
1841
  enumerable: false,
@@ -866,15 +1844,36 @@ class Repository extends Repository$1 {
866
1844
  value: metadata,
867
1845
  });
868
1846
  }
1847
+ /**
1848
+ * @description Gets metadata from a model instance.
1849
+ * @summary Retrieves previously attached metadata from a model instance.
1850
+ * @template M - The model type that extends Model.
1851
+ * @param {M} model - The model instance.
1852
+ * @return {any} The metadata or undefined if not found.
1853
+ */
869
1854
  static getMetadata(model) {
870
1855
  const descriptor = Object.getOwnPropertyDescriptor(model, PersistenceKeys.METADATA);
871
1856
  return descriptor ? descriptor.value : undefined;
872
1857
  }
1858
+ /**
1859
+ * @description Removes metadata from a model instance.
1860
+ * @summary Deletes the metadata property from a model instance.
1861
+ * @template M - The model type that extends Model.
1862
+ * @param {M} model - The model instance.
1863
+ */
873
1864
  static removeMetadata(model) {
874
1865
  const descriptor = Object.getOwnPropertyDescriptor(model, PersistenceKeys.METADATA);
875
1866
  if (descriptor)
876
1867
  delete model[PersistenceKeys.METADATA];
877
1868
  }
1869
+ /**
1870
+ * @description Gets sequence options for a model's primary key.
1871
+ * @summary Retrieves the sequence configuration for a model's primary key from metadata.
1872
+ * @template M - The model type that extends Model.
1873
+ * @param {M} model - The model instance.
1874
+ * @return {SequenceOptions} The sequence options for the model's primary key.
1875
+ * @throws {InternalError} If no sequence options are defined for the model.
1876
+ */
878
1877
  static getSequenceOptions(model) {
879
1878
  const pk = findPrimaryKey(model).id;
880
1879
  const metadata = Reflect.getMetadata(Repository.key(DBKeys.ID), model, pk);
@@ -882,6 +1881,13 @@ class Repository extends Repository$1 {
882
1881
  throw new InternalError("No sequence options defined for model. did you use the @pk decorator?");
883
1882
  return metadata;
884
1883
  }
1884
+ /**
1885
+ * @description Gets all indexes defined on a model.
1886
+ * @summary Retrieves all index metadata from a model's property decorators.
1887
+ * @template M - The model type that extends Model.
1888
+ * @param {M | Constructor<M>} model - The model instance or constructor.
1889
+ * @return {Record<string, Record<string, IndexMetadata>>} A nested record of property names to index metadata.
1890
+ */
885
1891
  static indexes(model) {
886
1892
  const indexDecorators = Reflection.getAllPropertyDecorators(model instanceof Model ? model : new model(), DBKeys.REFLECT);
887
1893
  return Object.entries(indexDecorators || {}).reduce((accum, [k, val]) => {
@@ -896,6 +1902,13 @@ class Repository extends Repository$1 {
896
1902
  return accum;
897
1903
  }, {});
898
1904
  }
1905
+ /**
1906
+ * @description Gets all relation properties defined on a model.
1907
+ * @summary Retrieves the names of all properties marked as relations in the model hierarchy.
1908
+ * @template M - The model type that extends Model.
1909
+ * @param {M | Constructor<M>} model - The model instance or constructor.
1910
+ * @return {string[]} An array of property names that are relations.
1911
+ */
899
1912
  static relations(model) {
900
1913
  const result = [];
901
1914
  let prototype = model instanceof Model
@@ -910,9 +1923,24 @@ class Repository extends Repository$1 {
910
1923
  }
911
1924
  return result;
912
1925
  }
1926
+ /**
1927
+ * @description Gets the table name for a model.
1928
+ * @summary Retrieves the database table name associated with a model.
1929
+ * @template M - The model type that extends Model.
1930
+ * @param {M | Constructor<M>} model - The model instance or constructor.
1931
+ * @return {string} The table name for the model.
1932
+ */
913
1933
  static table(model) {
914
1934
  return getTableName(model);
915
1935
  }
1936
+ /**
1937
+ * @description Gets the column name for a model attribute.
1938
+ * @summary Retrieves the database column name for a model property.
1939
+ * @template M - The model type that extends Model.
1940
+ * @param {M} model - The model instance.
1941
+ * @param {string} attribute - The attribute/property name.
1942
+ * @return {string} The column name for the attribute.
1943
+ */
916
1944
  static column(model, attribute) {
917
1945
  const metadata = Reflect.getMetadata(Adapter.key(PersistenceKeys.COLUMN), model, attribute);
918
1946
  return metadata ? metadata : attribute;
@@ -931,6 +1959,33 @@ __decorate([
931
1959
  __metadata("design:returntype", void 0)
932
1960
  ], Repository.prototype, "unObserve", null);
933
1961
 
1962
+ /**
1963
+ * @description Repository decorator for model classes.
1964
+ * @summary Creates and registers a repository for a model class. Can be used as both a property decorator and a class decorator.
1965
+ * @template T - The model type that extends Model.
1966
+ * @param {Constructor<T>} model - The constructor of the model class.
1967
+ * @param {string} [nameOverride] - Optional name override for the repository.
1968
+ * @return {any} - The decorator function.
1969
+ * @function repository
1970
+ * @mermaid
1971
+ * sequenceDiagram
1972
+ * participant C as Client Code
1973
+ * participant D as Decorator
1974
+ * participant R as Repository
1975
+ * participant M as Metadata
1976
+ *
1977
+ * C->>D: Apply @repository(Model)
1978
+ * alt Property Decorator
1979
+ * D->>D: Check if propertyKey exists
1980
+ * D->>+C: Return inject(name) decorator
1981
+ * else Class Decorator
1982
+ * D->>M: Set repository metadata on model
1983
+ * D->>R: Register model with Repository
1984
+ * D->>+C: Return injectable decorator with config
1985
+ * C->>C: Define DBKeys.CLASS property
1986
+ * end
1987
+ * @category Decorators
1988
+ */
934
1989
  function repository(model, nameOverride) {
935
1990
  return ((original, propertyKey) => {
936
1991
  if (propertyKey) {
@@ -950,12 +2005,19 @@ function repository(model, nameOverride) {
950
2005
  }
951
2006
 
952
2007
  /**
953
- * @summary Represents a failure in observer communication
954
- *
955
- * @param {string} msg the error message
956
- *
2008
+ * @description Error thrown when observer communication fails.
2009
+ * @summary Represents a failure in observer communication between repositories.
2010
+ * @param {string|Error} msg - The error message or Error object.
957
2011
  * @class ObserverError
958
- * @extends BaseError
2012
+ * @category Errors
2013
+ * @example
2014
+ * try {
2015
+ * // Some repository observer operation
2016
+ * } catch (error) {
2017
+ * if (error instanceof ObserverError) {
2018
+ * console.error('Observer communication failed:', error.message);
2019
+ * }
2020
+ * }
959
2021
  */
960
2022
  class ObserverError extends BaseError {
961
2023
  constructor(msg) {
@@ -963,6 +2025,17 @@ class ObserverError extends BaseError {
963
2025
  }
964
2026
  }
965
2027
 
2028
+ /**
2029
+ * @description Generates a unique injectable name for a repository.
2030
+ * @summary Creates a standardized name for repository injectables based on model and adapter flavour.
2031
+ * @template T - The model type that extends Model.
2032
+ * @param {Constructor<T> | T} model - The model constructor or instance.
2033
+ * @param {string} [flavour] - Optional adapter flavour. If not provided, it will be retrieved from the model metadata.
2034
+ * @return {string} The generated injectable name.
2035
+ * @throws {InternalError} If no flavour is provided and none can be retrieved from the model.
2036
+ * @function generateInjectableNameForRepository
2037
+ * @memberOf module:core
2038
+ */
966
2039
  function generateInjectableNameForRepository(model, flavour) {
967
2040
  if (!flavour) {
968
2041
  const key = Adapter.key(PersistenceKeys.ADAPTER);
@@ -973,10 +2046,28 @@ function generateInjectableNameForRepository(model, flavour) {
973
2046
  return sf(PersistenceKeys.INJECTABLE, flavour, Repository.table(model));
974
2047
  }
975
2048
 
2049
+ /**
2050
+ * @description Registry for injectable repositories.
2051
+ * @summary Extends the base injectable registry to provide automatic repository resolution for models.
2052
+ * @param {void} - No constructor parameters required.
2053
+ * @class InjectablesRegistry
2054
+ * @example
2055
+ * const registry = new InjectablesRegistry();
2056
+ * const userRepo = registry.get<UserRepository>('User');
2057
+ * // If UserRepository exists, it will be returned
2058
+ * // If not, but User model exists, a repository will be created for it
2059
+ */
976
2060
  class InjectablesRegistry extends InjectableRegistryImp {
977
2061
  constructor() {
978
2062
  super();
979
2063
  }
2064
+ /**
2065
+ * @description Gets an injectable by name with repository auto-resolution.
2066
+ * @summary Extends the base get method to automatically resolve repositories for models when not found directly.
2067
+ * @template T - The type of injectable to return.
2068
+ * @param {string} name - The name of the injectable to retrieve.
2069
+ * @return {T | undefined} - The injectable instance or undefined if not found.
2070
+ */
980
2071
  get(name) {
981
2072
  let injectable = super.get(name);
982
2073
  if (!injectable)
@@ -1000,18 +2091,36 @@ class InjectablesRegistry extends InjectableRegistryImp {
1000
2091
  }
1001
2092
  }
1002
2093
 
2094
+ /**
2095
+ * @description Default options for sequences
2096
+ * @summary Provides a standard configuration for number sequences starting at 0 and incrementing by 1
2097
+ * @const DefaultSequenceOptions
2098
+ * @memberOf module:core
2099
+ */
1003
2100
  const DefaultSequenceOptions = {
1004
2101
  type: "Number",
1005
2102
  startWith: 0,
1006
2103
  incrementBy: 1,
1007
2104
  cycle: false,
1008
2105
  };
2106
+ /**
2107
+ * @description Predefined options for numeric sequences
2108
+ * @summary Configuration for standard number sequences starting at 0 and incrementing by 1
2109
+ * @const NumericSequence
2110
+ * @memberOf module:core
2111
+ */
1009
2112
  const NumericSequence = {
1010
2113
  type: "Number",
1011
2114
  startWith: 0,
1012
2115
  incrementBy: 1,
1013
2116
  cycle: false,
1014
2117
  };
2118
+ /**
2119
+ * @description Predefined options for BigInt sequences
2120
+ * @summary Configuration for BigInt sequences starting at 0 and incrementing by 1
2121
+ * @const BigIntSequence
2122
+ * @memberOf module:core
2123
+ */
1015
2124
  const BigIntSequence = {
1016
2125
  type: "BigInt",
1017
2126
  startWith: 0,
@@ -1019,31 +2128,70 @@ const BigIntSequence = {
1019
2128
  cycle: false,
1020
2129
  };
1021
2130
 
2131
+ /**
2132
+ * @description Comparison operators for query conditions
2133
+ * @summary Enum defining the available operators for comparing values in database queries
2134
+ * @enum {string}
2135
+ * @readonly
2136
+ * @memberOf module:core
2137
+ */
1022
2138
  var Operator;
1023
2139
  (function (Operator) {
2140
+ /** Equal comparison (=) */
1024
2141
  Operator["EQUAL"] = "EQUAL";
2142
+ /** Not equal comparison (!=) */
1025
2143
  Operator["DIFFERENT"] = "DIFFERENT";
2144
+ /** Greater than comparison (>) */
1026
2145
  Operator["BIGGER"] = "BIGGER";
2146
+ /** Greater than or equal comparison (>=) */
1027
2147
  Operator["BIGGER_EQ"] = "BIGGER_EQ";
2148
+ /** Less than comparison (<) */
1028
2149
  Operator["SMALLER"] = "SMALLER";
2150
+ /** Less than or equal comparison (<=) */
1029
2151
  Operator["SMALLER_EQ"] = "SMALLER_EQ";
1030
2152
  // BETWEEN = "BETWEEN",
2153
+ /** Negation operator (NOT) */
1031
2154
  Operator["NOT"] = "NOT";
2155
+ /** Inclusion operator (IN) */
1032
2156
  Operator["IN"] = "IN";
1033
2157
  // IS = "IS",
2158
+ /** Regular expression matching */
1034
2159
  Operator["REGEXP"] = "REGEXP";
1035
2160
  })(Operator || (Operator = {}));
2161
+ /**
2162
+ * @description Logical operators for combining query conditions
2163
+ * @summary Enum defining the available operators for grouping multiple conditions in database queries
2164
+ * @enum {string}
2165
+ * @readonly
2166
+ * @memberOf module:core
2167
+ */
1036
2168
  var GroupOperator;
1037
2169
  (function (GroupOperator) {
2170
+ /** Logical AND operator - all conditions must be true */
1038
2171
  GroupOperator["AND"] = "AND";
2172
+ /** Logical OR operator - at least one condition must be true */
1039
2173
  GroupOperator["OR"] = "OR";
1040
2174
  })(GroupOperator || (GroupOperator = {}));
1041
2175
 
2176
+ /**
2177
+ * @description Error thrown during query operations
2178
+ * @summary Represents errors that occur during query building or execution
2179
+ * @param {string | Error} msg - The error message or Error object
2180
+ * @class QueryError
2181
+ * @category Errors
2182
+ */
1042
2183
  class QueryError extends BaseError {
1043
2184
  constructor(msg) {
1044
2185
  super(QueryError.name, msg, 500);
1045
2186
  }
1046
2187
  }
2188
+ /**
2189
+ * @description Error thrown during pagination operations
2190
+ * @summary Represents errors that occur during pagination setup or execution
2191
+ * @param {string | Error} msg - The error message or Error object
2192
+ * @class PagingError
2193
+ * @category Errors
2194
+ */
1047
2195
  class PagingError extends BaseError {
1048
2196
  constructor(msg) {
1049
2197
  super(PagingError.name, msg, 500);
@@ -1051,14 +2199,27 @@ class PagingError extends BaseError {
1051
2199
  }
1052
2200
 
1053
2201
  /**
1054
- * @summary Condition Class
1055
- * @description Represents a logical condition
2202
+ * @description Represents a logical condition for database queries
2203
+ * @summary A class that encapsulates query conditions with support for complex logical operations.
2204
+ * This class allows for building and combining query conditions using logical operators (AND, OR, NOT)
2205
+ * and comparison operators (equals, not equals, greater than, etc.).
2206
+ * @template M - The model type this condition operates on
2207
+ * @param {string | Condition<M>} attr1 - The attribute name or a nested condition
2208
+ * @param {Operator | GroupOperator} operator - The operator to use for the condition
2209
+ * @param {any} comparison - The value to compare against or another condition
2210
+ * @class Condition
2211
+ * @example
2212
+ * // Create a simple condition
2213
+ * const nameCondition = Condition.attribute("name").eq("John");
1056
2214
  *
1057
- * @param {string | Condition} attr1
1058
- * @param {Operator | GroupOperator} operator
1059
- * @param {string | Condition} comparison
2215
+ * // Create a complex condition
2216
+ * const complexCondition = Condition.attribute("age").gt(18)
2217
+ * .and(Condition.attribute("status").eq("active"));
1060
2218
  *
1061
- * @class Condition
2219
+ * // Use the builder pattern
2220
+ * const userQuery = Condition.builder()
2221
+ * .attribute("email").regexp(".*@example.com")
2222
+ * .and(Condition.attribute("lastLogin").gt(new Date("2023-01-01")));
1062
2223
  */
1063
2224
  class Condition extends Model {
1064
2225
  constructor(attr1, operator, comparison) {
@@ -1071,28 +2232,37 @@ class Condition extends Model {
1071
2232
  this.comparison = comparison;
1072
2233
  }
1073
2234
  /**
1074
- * @summary Joins 2 {@link Condition}s on an {@link Operator#AND} operation
1075
- * @param {Condition} condition
2235
+ * @description Combines this condition with another using logical AND
2236
+ * @summary Joins two conditions with an AND operator, requiring both to be true
2237
+ * @param {Condition<M>} condition - The condition to combine with this one
2238
+ * @return {Condition<M>} A new condition representing the AND operation
1076
2239
  */
1077
2240
  and(condition) {
1078
2241
  return Condition.and(this, condition);
1079
2242
  }
1080
2243
  /**
1081
- * @summary Joins 2 {@link Condition}s on an {@link Operator#OR} operation
1082
- * @param {Condition} condition
2244
+ * @description Combines this condition with another using logical OR
2245
+ * @summary Joins two conditions with an OR operator, requiring at least one to be true
2246
+ * @param {Condition<M>} condition - The condition to combine with this one
2247
+ * @return {Condition<M>} A new condition representing the OR operation
1083
2248
  */
1084
2249
  or(condition) {
1085
2250
  return Condition.or(this, condition);
1086
2251
  }
1087
2252
  /**
1088
- * @summary excludes a valut from the result
1089
- * @param val
2253
+ * @description Creates a negation condition
2254
+ * @summary Excludes a value from the result by applying a NOT operator
2255
+ * @param {any} val - The value to negate
2256
+ * @return {Condition<M>} A new condition representing the NOT operation
1090
2257
  */
1091
2258
  not(val) {
1092
2259
  return new Condition(this, Operator.NOT, val);
1093
2260
  }
1094
2261
  /**
1095
- * @inheritDoc
2262
+ * @description Validates the condition and checks for errors
2263
+ * @summary Extends the base validation to ensure the condition is properly formed
2264
+ * @param {...string[]} exceptions - Fields to exclude from validation
2265
+ * @return {ModelErrorDefinition | undefined} Error definition if validation fails, undefined otherwise
1096
2266
  */
1097
2267
  hasErrors(...exceptions) {
1098
2268
  const errors = super.hasErrors(...exceptions);
@@ -1138,46 +2308,65 @@ class Condition extends Model {
1138
2308
  }
1139
2309
  }
1140
2310
  /**
1141
- * @summary Joins 2 {@link Condition}s on an {@link Operator#AND} operation
1142
- * @param {Condition} condition1
1143
- * @param {Condition} condition2
2311
+ * @description Creates a new condition that combines two conditions with logical AND
2312
+ * @summary Static method that joins two conditions with an AND operator, requiring both to be true
2313
+ * @template M - The model type this condition operates on
2314
+ * @param {Condition<M>} condition1 - The first condition
2315
+ * @param {Condition<M>} condition2 - The second condition
2316
+ * @return {Condition<M>} A new condition representing the AND operation
1144
2317
  */
1145
2318
  static and(condition1, condition2) {
1146
2319
  return Condition.group(condition1, GroupOperator.AND, condition2);
1147
2320
  }
1148
2321
  /**
1149
- * @summary Joins 2 {@link Condition}s on an {@link Operator#OR} operation
1150
- * @param {Condition} condition1
1151
- * @param {Condition} condition2
2322
+ * @description Creates a new condition that combines two conditions with logical OR
2323
+ * @summary Static method that joins two conditions with an OR operator, requiring at least one to be true
2324
+ * @template M - The model type this condition operates on
2325
+ * @param {Condition<M>} condition1 - The first condition
2326
+ * @param {Condition<M>} condition2 - The second condition
2327
+ * @return {Condition<M>} A new condition representing the OR operation
1152
2328
  */
1153
2329
  static or(condition1, condition2) {
1154
2330
  return Condition.group(condition1, GroupOperator.OR, condition2);
1155
2331
  }
1156
2332
  /**
1157
- * @summary Groups 2 {@link Condition}s by the specified {@link GroupOperator}
1158
- * @param {Condition} condition1
1159
- * @param {GroupOperator} operator
1160
- * @param {Condition} condition2
2333
+ * @description Creates a new condition that groups two conditions with a specified operator
2334
+ * @summary Private static method that combines two conditions using the specified group operator
2335
+ * @template M - The model type this condition operates on
2336
+ * @param {Condition<M>} condition1 - The first condition
2337
+ * @param {GroupOperator} operator - The group operator to use (AND, OR)
2338
+ * @param {Condition<M>} condition2 - The second condition
2339
+ * @return {Condition<M>} A new condition representing the grouped operation
1161
2340
  */
1162
2341
  static group(condition1, operator, condition2) {
1163
2342
  return new Condition(condition1, operator, condition2);
1164
2343
  }
2344
+ /**
2345
+ * @description Creates a condition builder for a specific model attribute
2346
+ * @summary Static method that initializes a condition builder with the specified attribute
2347
+ * @template M - The model type this condition operates on
2348
+ * @param attr - The model attribute to build a condition for
2349
+ * @return {AttributeOption<M>} A condition builder initialized with the attribute
2350
+ */
1165
2351
  static attribute(attr) {
1166
2352
  return new Condition.Builder().attribute(attr);
1167
2353
  }
2354
+ /**
2355
+ * @description Alias for the attribute method
2356
+ * @summary Shorthand method that initializes a condition builder with the specified attribute
2357
+ * @template M - The model type this condition operates on
2358
+ * @param attr - The model attribute to build a condition for
2359
+ * @return {AttributeOption<M>} A condition builder initialized with the attribute
2360
+ */
1168
2361
  static attr(attr) {
1169
2362
  return this.attribute(attr);
1170
2363
  }
1171
2364
  /**
1172
- * @summary Condition Builder Class
1173
- * @description provides a simple API to build {@link Condition}s
1174
- *
2365
+ * @description Provides a fluent API to build query conditions
2366
+ * @summary A builder class that simplifies the creation of database query conditions
2367
+ * with a chainable interface for setting attributes and operators
2368
+ * @template M - The model type this condition builder operates on
1175
2369
  * @class ConditionBuilder
1176
- * @implements Builder
1177
- * @implements AttributeOption
1178
- *
1179
- * @category Query
1180
- * @subcategory Conditions
1181
2370
  */
1182
2371
  static { this.Builder = class ConditionBuilder {
1183
2372
  constructor() {
@@ -1186,71 +2375,102 @@ class Condition extends Model {
1186
2375
  this.comparison = undefined;
1187
2376
  }
1188
2377
  /**
1189
- * @inheritDoc
2378
+ * @description Sets the attribute for the condition
2379
+ * @summary Specifies which model attribute the condition will operate on
2380
+ * @param attr - The model attribute to use in the condition
2381
+ * @return {AttributeOption<M>} This builder instance for method chaining
1190
2382
  */
1191
2383
  attribute(attr) {
1192
2384
  this.attr1 = attr;
1193
2385
  return this;
1194
2386
  }
2387
+ /**
2388
+ * @description Alias for the attribute method
2389
+ * @summary Shorthand method to specify which model attribute the condition will operate on
2390
+ * @param attr - The model attribute to use in the condition
2391
+ * @return {AttributeOption<M>} This builder instance for method chaining
2392
+ */
1195
2393
  attr(attr) {
1196
2394
  return this.attribute(attr);
1197
2395
  }
1198
2396
  /**
1199
- * @summary Creates an Equality Comparison
1200
- * @param {any} val
2397
+ * @description Creates an equality condition
2398
+ * @summary Builds a condition that checks if the attribute equals the specified value
2399
+ * @param {any} val - The value to compare the attribute against
2400
+ * @return {Condition<M>} A new condition representing the equality comparison
1201
2401
  */
1202
2402
  eq(val) {
1203
2403
  return this.setOp(Operator.EQUAL, val);
1204
2404
  }
1205
2405
  /**
1206
- * @summary Creates a Different Comparison
1207
- * @param {any} val
2406
+ * @description Creates an inequality condition
2407
+ * @summary Builds a condition that checks if the attribute is different from the specified value
2408
+ * @param {any} val - The value to compare the attribute against
2409
+ * @return {Condition<M>} A new condition representing the inequality comparison
1208
2410
  */
1209
2411
  dif(val) {
1210
2412
  return this.setOp(Operator.DIFFERENT, val);
1211
2413
  }
1212
2414
  /**
1213
- * @summary Creates a Greater Than Comparison
1214
- * @param {any} val
2415
+ * @description Creates a greater than condition
2416
+ * @summary Builds a condition that checks if the attribute is greater than the specified value
2417
+ * @param {any} val - The value to compare the attribute against
2418
+ * @return {Condition<M>} A new condition representing the greater than comparison
1215
2419
  */
1216
2420
  gt(val) {
1217
2421
  return this.setOp(Operator.BIGGER, val);
1218
2422
  }
1219
2423
  /**
1220
- * @summary Creates a Lower Than Comparison
1221
- * @param {any} val
2424
+ * @description Creates a less than condition
2425
+ * @summary Builds a condition that checks if the attribute is less than the specified value
2426
+ * @param {any} val - The value to compare the attribute against
2427
+ * @return {Condition<M>} A new condition representing the less than comparison
1222
2428
  */
1223
2429
  lt(val) {
1224
2430
  return this.setOp(Operator.SMALLER, val);
1225
2431
  }
1226
2432
  /**
1227
- * @summary Creates a Greater or Equal to Comparison
1228
- * @param {any} val
2433
+ * @description Creates a greater than or equal to condition
2434
+ * @summary Builds a condition that checks if the attribute is greater than or equal to the specified value
2435
+ * @param {any} val - The value to compare the attribute against
2436
+ * @return {Condition<M>} A new condition representing the greater than or equal comparison
1229
2437
  */
1230
2438
  gte(val) {
1231
2439
  return this.setOp(Operator.BIGGER_EQ, val);
1232
2440
  }
1233
2441
  /**
1234
- * @summary Creates a Lower or Equal to Comparison
1235
- * @param {any} val
2442
+ * @description Creates a less than or equal to condition
2443
+ * @summary Builds a condition that checks if the attribute is less than or equal to the specified value
2444
+ * @param {any} val - The value to compare the attribute against
2445
+ * @return {Condition<M>} A new condition representing the less than or equal comparison
1236
2446
  */
1237
2447
  lte(val) {
1238
2448
  return this.setOp(Operator.SMALLER_EQ, val);
1239
2449
  }
2450
+ /**
2451
+ * @description Creates an inclusion condition
2452
+ * @summary Builds a condition that checks if the attribute value is included in the specified array
2453
+ * @param {any[]} arr - The array of values to check against
2454
+ * @return {Condition<M>} A new condition representing the inclusion comparison
2455
+ */
1240
2456
  in(arr) {
1241
2457
  return this.setOp(Operator.IN, arr);
1242
2458
  }
1243
2459
  /**
1244
- * @summary Creates a Regexpo Comparison
1245
- * @param {any} val
2460
+ * @description Creates a regular expression condition
2461
+ * @summary Builds a condition that checks if the attribute matches the specified regular expression pattern
2462
+ * @param {any} val - The regular expression pattern to match against
2463
+ * @return {Condition<M>} A new condition representing the regular expression comparison
1246
2464
  */
1247
2465
  regexp(val) {
1248
2466
  return this.setOp(Operator.REGEXP, new RegExp(val).source);
1249
2467
  }
1250
2468
  /**
1251
- * @summary Creates an {@link Operator} based Comparison
1252
- * @param {Operator} op
1253
- * @param {any} val
2469
+ * @description Sets the operator and comparison value for the condition
2470
+ * @summary Private method that configures the condition with the specified operator and value
2471
+ * @param {Operator} op - The operator to use for the condition
2472
+ * @param {any} val - The value to compare against
2473
+ * @return {Condition<M>} A new condition with the specified operator and value
1254
2474
  */
1255
2475
  setOp(op, val) {
1256
2476
  this.operator = op;
@@ -1258,9 +2478,10 @@ class Condition extends Model {
1258
2478
  return this.build();
1259
2479
  }
1260
2480
  /**
1261
- * @summary Builds the Database Object
1262
- * @throws {QueryError} if it fails to build the {@link Condition}
1263
- * @private
2481
+ * @description Constructs a Condition instance from the builder's state
2482
+ * @summary Finalizes the condition building process by creating a new Condition instance
2483
+ * @throws {QueryError} If the condition cannot be built due to invalid parameters
2484
+ * @return {Condition<M>} A new condition instance with the configured attributes
1264
2485
  */
1265
2486
  build() {
1266
2487
  try {
@@ -1271,6 +2492,12 @@ class Condition extends Model {
1271
2492
  }
1272
2493
  }
1273
2494
  }; }
2495
+ /**
2496
+ * @description Creates a new condition builder
2497
+ * @summary Factory method that returns a new instance of the condition builder
2498
+ * @template M - The model type this condition builder will operate on
2499
+ * @return {ConditionBuilderOption<M>} A new condition builder instance
2500
+ */
1274
2501
  static builder() {
1275
2502
  return new Condition.Builder();
1276
2503
  }
@@ -1288,6 +2515,47 @@ __decorate([
1288
2515
  __metadata("design:type", Object)
1289
2516
  ], Condition.prototype, "comparison", void 0);
1290
2517
 
2518
+ /**
2519
+ * @description Creates or updates a model instance
2520
+ * @summary Determines whether to create a new model or update an existing one based on the presence of a primary key
2521
+ * @template M - The model type extending Model
2522
+ * @template F - The repository flags type
2523
+ * @param {M} model - The model instance to create or update
2524
+ * @param {Context<F>} context - The context for the operation
2525
+ * @param {Repo<M, F, Context<F>>} [repository] - Optional repository to use for the operation
2526
+ * @return {Promise<M>} A promise that resolves to the created or updated model
2527
+ * @function createOrUpdate
2528
+ * @memberOf module:core
2529
+ * @mermaid
2530
+ * sequenceDiagram
2531
+ * participant Caller
2532
+ * participant createOrUpdate
2533
+ * participant Repository
2534
+ * participant Model
2535
+ *
2536
+ * Caller->>createOrUpdate: model, context, repository?
2537
+ * alt repository not provided
2538
+ * createOrUpdate->>Model: get(model.constructor.name)
2539
+ * Model-->>createOrUpdate: constructor
2540
+ * createOrUpdate->>Repository: forModel(constructor)
2541
+ * Repository-->>createOrUpdate: repository
2542
+ * end
2543
+ *
2544
+ * alt primary key undefined
2545
+ * createOrUpdate->>Repository: create(model, context)
2546
+ * Repository-->>createOrUpdate: created model
2547
+ * else primary key defined
2548
+ * createOrUpdate->>Repository: update(model, context)
2549
+ * alt update successful
2550
+ * Repository-->>createOrUpdate: updated model
2551
+ * else NotFoundError
2552
+ * createOrUpdate->>Repository: create(model, context)
2553
+ * Repository-->>createOrUpdate: created model
2554
+ * end
2555
+ * end
2556
+ *
2557
+ * createOrUpdate-->>Caller: model
2558
+ */
1291
2559
  async function createOrUpdate(model, context, repository) {
1292
2560
  if (!repository) {
1293
2561
  const constructor = Model.get(model.constructor.name);
@@ -1308,6 +2576,56 @@ async function createOrUpdate(model, context, repository) {
1308
2576
  }
1309
2577
  }
1310
2578
  }
2579
+ /**
2580
+ * @description Handles one-to-one relationship creation
2581
+ * @summary Processes a one-to-one relationship when creating a model, either by referencing an existing model or creating a new one
2582
+ * @template M - The model type extending Model
2583
+ * @template R - The repository type extending Repo<M, F, C>
2584
+ * @template V - The relations metadata type extending RelationsMetadata
2585
+ * @template F - The repository flags type
2586
+ * @template C - The context type extending Context<F>
2587
+ * @param {R} this - The repository instance
2588
+ * @param {Context<F>} context - The context for the operation
2589
+ * @param {V} data - The relations metadata
2590
+ * @param {string} key - The property key of the relationship
2591
+ * @param {M} model - The model instance
2592
+ * @return {Promise<void>} A promise that resolves when the operation is complete
2593
+ * @function oneToOneOnCreate
2594
+ * @memberOf module:core
2595
+ * @mermaid
2596
+ * sequenceDiagram
2597
+ * participant Caller
2598
+ * participant oneToOneOnCreate
2599
+ * participant repositoryFromTypeMetadata
2600
+ * participant Model
2601
+ * participant Repository
2602
+ * participant cacheModelForPopulate
2603
+ *
2604
+ * Caller->>oneToOneOnCreate: this, context, data, key, model
2605
+ * oneToOneOnCreate->>oneToOneOnCreate: check if propertyValue exists
2606
+ *
2607
+ * alt propertyValue is not an object
2608
+ * oneToOneOnCreate->>repositoryFromTypeMetadata: model, key
2609
+ * repositoryFromTypeMetadata-->>oneToOneOnCreate: innerRepo
2610
+ * oneToOneOnCreate->>innerRepo: read(propertyValue)
2611
+ * innerRepo-->>oneToOneOnCreate: read
2612
+ * oneToOneOnCreate->>cacheModelForPopulate: context, model, key, propertyValue, read
2613
+ * oneToOneOnCreate->>oneToOneOnCreate: set model[key] = propertyValue
2614
+ * else propertyValue is an object
2615
+ * oneToOneOnCreate->>Model: get(data.class)
2616
+ * Model-->>oneToOneOnCreate: constructor
2617
+ * oneToOneOnCreate->>Repository: forModel(constructor)
2618
+ * Repository-->>oneToOneOnCreate: repo
2619
+ * oneToOneOnCreate->>repo: create(propertyValue)
2620
+ * repo-->>oneToOneOnCreate: created
2621
+ * oneToOneOnCreate->>findPrimaryKey: created
2622
+ * findPrimaryKey-->>oneToOneOnCreate: pk
2623
+ * oneToOneOnCreate->>cacheModelForPopulate: context, model, key, created[pk], created
2624
+ * oneToOneOnCreate->>oneToOneOnCreate: set model[key] = created[pk]
2625
+ * end
2626
+ *
2627
+ * oneToOneOnCreate-->>Caller: void
2628
+ */
1311
2629
  async function oneToOneOnCreate(context, data, key, model) {
1312
2630
  const propertyValue = model[key];
1313
2631
  if (!propertyValue)
@@ -1328,6 +2646,53 @@ async function oneToOneOnCreate(context, data, key, model) {
1328
2646
  await cacheModelForPopulate(context, model, key, created[pk], created);
1329
2647
  model[key] = created[pk];
1330
2648
  }
2649
+ /**
2650
+ * @description Handles one-to-one relationship updates
2651
+ * @summary Processes a one-to-one relationship when updating a model, either by referencing an existing model or updating the related model
2652
+ * @template M - The model type extending Model
2653
+ * @template R - The repository type extending Repo<M, F, C>
2654
+ * @template V - The relations metadata type extending RelationsMetadata
2655
+ * @template F - The repository flags type
2656
+ * @template C - The context type extending Context<F>
2657
+ * @param {R} this - The repository instance
2658
+ * @param {Context<F>} context - The context for the operation
2659
+ * @param {V} data - The relations metadata
2660
+ * @param key - The property key of the relationship
2661
+ * @param {M} model - The model instance
2662
+ * @return {Promise<void>} A promise that resolves when the operation is complete
2663
+ * @function oneToOneOnUpdate
2664
+ * @memberOf module:core
2665
+ * @mermaid
2666
+ * sequenceDiagram
2667
+ * participant Caller
2668
+ * participant oneToOneOnUpdate
2669
+ * participant repositoryFromTypeMetadata
2670
+ * participant createOrUpdate
2671
+ * participant findPrimaryKey
2672
+ * participant cacheModelForPopulate
2673
+ *
2674
+ * Caller->>oneToOneOnUpdate: this, context, data, key, model
2675
+ * oneToOneOnUpdate->>oneToOneOnUpdate: check if propertyValue exists
2676
+ * oneToOneOnUpdate->>oneToOneOnUpdate: check if cascade.update is CASCADE
2677
+ *
2678
+ * alt propertyValue is not an object
2679
+ * oneToOneOnUpdate->>repositoryFromTypeMetadata: model, key
2680
+ * repositoryFromTypeMetadata-->>oneToOneOnUpdate: innerRepo
2681
+ * oneToOneOnUpdate->>innerRepo: read(propertyValue)
2682
+ * innerRepo-->>oneToOneOnUpdate: read
2683
+ * oneToOneOnUpdate->>cacheModelForPopulate: context, model, key, propertyValue, read
2684
+ * oneToOneOnUpdate->>oneToOneOnUpdate: set model[key] = propertyValue
2685
+ * else propertyValue is an object
2686
+ * oneToOneOnUpdate->>createOrUpdate: model[key], context
2687
+ * createOrUpdate-->>oneToOneOnUpdate: updated
2688
+ * oneToOneOnUpdate->>findPrimaryKey: updated
2689
+ * findPrimaryKey-->>oneToOneOnUpdate: pk
2690
+ * oneToOneOnUpdate->>cacheModelForPopulate: context, model, key, updated[pk], updated
2691
+ * oneToOneOnUpdate->>oneToOneOnUpdate: set model[key] = updated[pk]
2692
+ * end
2693
+ *
2694
+ * oneToOneOnUpdate-->>Caller: void
2695
+ */
1331
2696
  async function oneToOneOnUpdate(context, data, key, model) {
1332
2697
  const propertyValue = model[key];
1333
2698
  if (!propertyValue)
@@ -1346,6 +2711,47 @@ async function oneToOneOnUpdate(context, data, key, model) {
1346
2711
  await cacheModelForPopulate(context, model, key, updated[pk], updated);
1347
2712
  model[key] = updated[pk];
1348
2713
  }
2714
+ /**
2715
+ * @description Handles one-to-one relationship deletion
2716
+ * @summary Processes a one-to-one relationship when deleting a model, deleting the related model if cascade is enabled
2717
+ * @template M - The model type extending Model
2718
+ * @template R - The repository type extending Repo<M, F, C>
2719
+ * @template V - The relations metadata type extending RelationsMetadata
2720
+ * @template F - The repository flags type
2721
+ * @template C - The context type extending Context<F>
2722
+ * @param {R} this - The repository instance
2723
+ * @param {Context<F>} context - The context for the operation
2724
+ * @param {V} data - The relations metadata
2725
+ * @param key - The property key of the relationship
2726
+ * @param {M} model - The model instance
2727
+ * @return {Promise<void>} A promise that resolves when the operation is complete
2728
+ * @function oneToOneOnDelete
2729
+ * @memberOf module:core
2730
+ * @mermaid
2731
+ * sequenceDiagram
2732
+ * participant Caller
2733
+ * participant oneToOneOnDelete
2734
+ * participant repositoryFromTypeMetadata
2735
+ * participant cacheModelForPopulate
2736
+ *
2737
+ * Caller->>oneToOneOnDelete: this, context, data, key, model
2738
+ * oneToOneOnDelete->>oneToOneOnDelete: check if propertyValue exists
2739
+ * oneToOneOnDelete->>oneToOneOnDelete: check if cascade.update is CASCADE
2740
+ *
2741
+ * oneToOneOnDelete->>repositoryFromTypeMetadata: model, key
2742
+ * repositoryFromTypeMetadata-->>oneToOneOnDelete: innerRepo
2743
+ *
2744
+ * alt propertyValue is not a Model instance
2745
+ * oneToOneOnDelete->>innerRepo: delete(model[key], context)
2746
+ * innerRepo-->>oneToOneOnDelete: deleted
2747
+ * else propertyValue is a Model instance
2748
+ * oneToOneOnDelete->>innerRepo: delete(model[key][innerRepo.pk], context)
2749
+ * innerRepo-->>oneToOneOnDelete: deleted
2750
+ * end
2751
+ *
2752
+ * oneToOneOnDelete->>cacheModelForPopulate: context, model, key, deleted[innerRepo.pk], deleted
2753
+ * oneToOneOnDelete-->>Caller: void
2754
+ */
1349
2755
  async function oneToOneOnDelete(context, data, key, model) {
1350
2756
  const propertyValue = model[key];
1351
2757
  if (!propertyValue)
@@ -1360,6 +2766,60 @@ async function oneToOneOnDelete(context, data, key, model) {
1360
2766
  deleted = await innerRepo.delete(model[key][innerRepo.pk], context);
1361
2767
  await cacheModelForPopulate(context, model, key, deleted[innerRepo.pk], deleted);
1362
2768
  }
2769
+ /**
2770
+ * @description Handles one-to-many relationship creation
2771
+ * @summary Processes a one-to-many relationship when creating a model, either by referencing existing models or creating new ones
2772
+ * @template M - The model type extending Model
2773
+ * @template R - The repository type extending Repo<M, F, C>
2774
+ * @template V - The relations metadata type extending RelationsMetadata
2775
+ * @template F - The repository flags type
2776
+ * @template C - The context type extending Context<F>
2777
+ * @param {R} this - The repository instance
2778
+ * @param {Context<F>} context - The context for the operation
2779
+ * @param {V} data - The relations metadata
2780
+ * @param key - The property key of the relationship
2781
+ * @param {M} model - The model instance
2782
+ * @return {Promise<void>} A promise that resolves when the operation is complete
2783
+ * @function oneToManyOnCreate
2784
+ * @memberOf module:core
2785
+ * @mermaid
2786
+ * sequenceDiagram
2787
+ * participant Caller
2788
+ * participant oneToManyOnCreate
2789
+ * participant repositoryFromTypeMetadata
2790
+ * participant createOrUpdate
2791
+ * participant findPrimaryKey
2792
+ * participant cacheModelForPopulate
2793
+ *
2794
+ * Caller->>oneToManyOnCreate: this, context, data, key, model
2795
+ * oneToManyOnCreate->>oneToManyOnCreate: check if propertyValues exists and has length
2796
+ * oneToManyOnCreate->>oneToManyOnCreate: check if all elements have same type
2797
+ * oneToManyOnCreate->>oneToManyOnCreate: create uniqueValues set
2798
+ *
2799
+ * alt arrayType is not "object"
2800
+ * oneToManyOnCreate->>repositoryFromTypeMetadata: model, key
2801
+ * repositoryFromTypeMetadata-->>oneToManyOnCreate: repo
2802
+ * loop for each id in uniqueValues
2803
+ * oneToManyOnCreate->>repo: read(id)
2804
+ * repo-->>oneToManyOnCreate: read
2805
+ * oneToManyOnCreate->>cacheModelForPopulate: context, model, key, id, read
2806
+ * end
2807
+ * oneToManyOnCreate->>oneToManyOnCreate: set model[key] = [...uniqueValues]
2808
+ * else arrayType is "object"
2809
+ * oneToManyOnCreate->>findPrimaryKey: propertyValues[0]
2810
+ * findPrimaryKey-->>oneToManyOnCreate: pkName
2811
+ * oneToManyOnCreate->>oneToManyOnCreate: create result set
2812
+ * loop for each m in propertyValues
2813
+ * oneToManyOnCreate->>createOrUpdate: m, context
2814
+ * createOrUpdate-->>oneToManyOnCreate: record
2815
+ * oneToManyOnCreate->>cacheModelForPopulate: context, model, key, record[pkName], record
2816
+ * oneToManyOnCreate->>oneToManyOnCreate: add record[pkName] to result
2817
+ * end
2818
+ * oneToManyOnCreate->>oneToManyOnCreate: set model[key] = [...result]
2819
+ * end
2820
+ *
2821
+ * oneToManyOnCreate-->>Caller: void
2822
+ */
1363
2823
  async function oneToManyOnCreate(context, data, key, model) {
1364
2824
  const propertyValues = model[key];
1365
2825
  if (!propertyValues || !propertyValues.length)
@@ -1386,6 +2846,38 @@ async function oneToManyOnCreate(context, data, key, model) {
1386
2846
  }
1387
2847
  model[key] = [...result];
1388
2848
  }
2849
+ /**
2850
+ * @description Handles one-to-many relationship updates
2851
+ * @summary Processes a one-to-many relationship when updating a model, delegating to oneToManyOnCreate if cascade update is enabled
2852
+ * @template M - The model type extending Model
2853
+ * @template R - The repository type extending Repo<M, F, C>
2854
+ * @template V - The relations metadata type extending RelationsMetadata
2855
+ * @template F - The repository flags type
2856
+ * @template C - The context type extending Context<F>
2857
+ * @param {R} this - The repository instance
2858
+ * @param {Context<F>} context - The context for the operation
2859
+ * @param {V} data - The relations metadata
2860
+ * @param key - The property key of the relationship
2861
+ * @param {M} model - The model instance
2862
+ * @return {Promise<void>} A promise that resolves when the operation is complete
2863
+ * @function oneToManyOnUpdate
2864
+ * @memberOf module:core
2865
+ * @mermaid
2866
+ * sequenceDiagram
2867
+ * participant Caller
2868
+ * participant oneToManyOnUpdate
2869
+ * participant oneToManyOnCreate
2870
+ *
2871
+ * Caller->>oneToManyOnUpdate: this, context, data, key, model
2872
+ * oneToManyOnUpdate->>oneToManyOnUpdate: check if cascade.update is CASCADE
2873
+ *
2874
+ * alt cascade.update is CASCADE
2875
+ * oneToManyOnUpdate->>oneToManyOnCreate: apply(this, [context, data, key, model])
2876
+ * oneToManyOnCreate-->>oneToManyOnUpdate: void
2877
+ * end
2878
+ *
2879
+ * oneToManyOnUpdate-->>Caller: void
2880
+ */
1389
2881
  async function oneToManyOnUpdate(context, data, key, model) {
1390
2882
  const { cascade } = data;
1391
2883
  if (cascade.update !== Cascade.CASCADE)
@@ -1397,6 +2889,54 @@ async function oneToManyOnUpdate(context, data, key, model) {
1397
2889
  model,
1398
2890
  ]);
1399
2891
  }
2892
+ /**
2893
+ * @description Handles one-to-many relationship deletion
2894
+ * @summary Processes a one-to-many relationship when deleting a model, deleting all related models if cascade delete is enabled
2895
+ * @template M - The model type extending Model
2896
+ * @template R - The repository type extending Repo<M, F, C>
2897
+ * @template V - The relations metadata type extending RelationsMetadata
2898
+ * @template F - The repository flags type
2899
+ * @template C - The context type extending Context<F>
2900
+ * @param {R} this - The repository instance
2901
+ * @param {Context<F>} context - The context for the operation
2902
+ * @param {V} data - The relations metadata
2903
+ * @param key - The property key of the relationship
2904
+ * @param {M} model - The model instance
2905
+ * @return {Promise<void>} A promise that resolves when the operation is complete
2906
+ * @function oneToManyOnDelete
2907
+ * @memberOf module:core
2908
+ * @mermaid
2909
+ * sequenceDiagram
2910
+ * participant Caller
2911
+ * participant oneToManyOnDelete
2912
+ * participant Repository
2913
+ * participant repositoryFromTypeMetadata
2914
+ * participant cacheModelForPopulate
2915
+ *
2916
+ * Caller->>oneToManyOnDelete: this, context, data, key, model
2917
+ * oneToManyOnDelete->>oneToManyOnDelete: check if cascade.delete is CASCADE
2918
+ * oneToManyOnDelete->>oneToManyOnDelete: check if values exists and has length
2919
+ * oneToManyOnDelete->>oneToManyOnDelete: check if all elements have same type
2920
+ *
2921
+ * alt isInstantiated (arrayType is "object")
2922
+ * oneToManyOnDelete->>Repository: forModel(values[0])
2923
+ * Repository-->>oneToManyOnDelete: repo
2924
+ * else not instantiated
2925
+ * oneToManyOnDelete->>repositoryFromTypeMetadata: model, key
2926
+ * repositoryFromTypeMetadata-->>oneToManyOnDelete: repo
2927
+ * end
2928
+ *
2929
+ * oneToManyOnDelete->>oneToManyOnDelete: create uniqueValues set
2930
+ *
2931
+ * loop for each id in uniqueValues
2932
+ * oneToManyOnDelete->>repo: delete(id, context)
2933
+ * repo-->>oneToManyOnDelete: deleted
2934
+ * oneToManyOnDelete->>cacheModelForPopulate: context, model, key, id, deleted
2935
+ * end
2936
+ *
2937
+ * oneToManyOnDelete->>oneToManyOnDelete: set model[key] = [...uniqueValues]
2938
+ * oneToManyOnDelete-->>Caller: void
2939
+ */
1400
2940
  async function oneToManyOnDelete(context, data, key, model) {
1401
2941
  if (data.cascade.delete !== Cascade.CASCADE)
1402
2942
  return;
@@ -1409,7 +2949,7 @@ async function oneToManyOnDelete(context, data, key, model) {
1409
2949
  throw new InternalError(`Invalid operation. All elements of property ${key} must match the same type.`);
1410
2950
  const isInstantiated = arrayType === "object";
1411
2951
  const repo = isInstantiated
1412
- ? Repository.forModel(values[0])
2952
+ ? Repository.forModel(values[0], this.adapter.alias)
1413
2953
  : repositoryFromTypeMetadata(model, key);
1414
2954
  const uniqueValues = new Set([
1415
2955
  ...(isInstantiated
@@ -1422,13 +2962,91 @@ async function oneToManyOnDelete(context, data, key, model) {
1422
2962
  }
1423
2963
  model[key] = [...uniqueValues];
1424
2964
  }
2965
+ /**
2966
+ * @description Generates a key for caching populated model relationships
2967
+ * @summary Creates a unique key for storing and retrieving populated model relationships in the cache
2968
+ * @param {string} tableName - The name of the table or model
2969
+ * @param {string} fieldName - The name of the field or property
2970
+ * @param {string|number} id - The identifier of the related model
2971
+ * @return {string} A dot-separated string that uniquely identifies the relationship
2972
+ * @function getPopulateKey
2973
+ * @memberOf module:core
2974
+ */
1425
2975
  function getPopulateKey(tableName, fieldName, id) {
1426
2976
  return [PersistenceKeys.POPULATE, tableName, fieldName, id].join(".");
1427
2977
  }
2978
+ /**
2979
+ * @description Caches a model for later population
2980
+ * @summary Stores a model in the context cache for efficient retrieval during relationship population
2981
+ * @template M - The model type extending Model
2982
+ * @template F - The repository flags type
2983
+ * @param {Context<F>} context - The context for the operation
2984
+ * @param {M} parentModel - The parent model that contains the relationship
2985
+ * @param propertyKey - The property key of the relationship
2986
+ * @param {string | number} pkValue - The primary key value of the related model
2987
+ * @param {any} cacheValue - The model instance to cache
2988
+ * @return {Promise<any>} A promise that resolves with the result of the cache operation
2989
+ * @function cacheModelForPopulate
2990
+ * @memberOf module:core
2991
+ */
1428
2992
  async function cacheModelForPopulate(context, parentModel, propertyKey, pkValue, cacheValue) {
1429
2993
  const cacheKey = getPopulateKey(parentModel.constructor.name, propertyKey, pkValue);
1430
2994
  return context.accumulate({ [cacheKey]: cacheValue });
1431
2995
  }
2996
+ /**
2997
+ * @description Populates a model's relationship
2998
+ * @summary Retrieves and attaches related models to a model's relationship property
2999
+ * @template M - The model type extending Model
3000
+ * @template R - The repository type extending Repo<M, F, C>
3001
+ * @template V - The relations metadata type extending RelationsMetadata
3002
+ * @template F - The repository flags type
3003
+ * @template C - The context type extending Context<F>
3004
+ * @param {R} this - The repository instance
3005
+ * @param {Context<F>} context - The context for the operation
3006
+ * @param {V} data - The relations metadata
3007
+ * @param key - The property key of the relationship
3008
+ * @param {M} model - The model instance
3009
+ * @return {Promise<void>} A promise that resolves when the operation is complete
3010
+ * @function populate
3011
+ * @memberOf module:core
3012
+ * @mermaid
3013
+ * sequenceDiagram
3014
+ * participant Caller
3015
+ * participant populate
3016
+ * participant fetchPopulateValues
3017
+ * participant getPopulateKey
3018
+ * participant Context
3019
+ * participant repositoryFromTypeMetadata
3020
+ *
3021
+ * Caller->>populate: this, context, data, key, model
3022
+ * populate->>populate: check if data.populate is true
3023
+ * populate->>populate: get nested value and check if it exists
3024
+ *
3025
+ * populate->>fetchPopulateValues: context, model, key, isArr ? nested : [nested]
3026
+ *
3027
+ * fetchPopulateValues->>fetchPopulateValues: initialize variables
3028
+ *
3029
+ * loop for each proKeyValue in propKeyValues
3030
+ * fetchPopulateValues->>getPopulateKey: model.constructor.name, propName, proKeyValue
3031
+ * getPopulateKey-->>fetchPopulateValues: cacheKey
3032
+ *
3033
+ * alt try to get from cache
3034
+ * fetchPopulateValues->>Context: get(cacheKey)
3035
+ * Context-->>fetchPopulateValues: val
3036
+ * else catch error
3037
+ * fetchPopulateValues->>repositoryFromTypeMetadata: model, propName
3038
+ * repositoryFromTypeMetadata-->>fetchPopulateValues: repo
3039
+ * fetchPopulateValues->>repo: read(proKeyValue)
3040
+ * repo-->>fetchPopulateValues: val
3041
+ * end
3042
+ *
3043
+ * fetchPopulateValues->>fetchPopulateValues: add val to results
3044
+ * end
3045
+ *
3046
+ * fetchPopulateValues-->>populate: results
3047
+ * populate->>populate: set model[key] = isArr ? res : res[0]
3048
+ * populate-->>Caller: void
3049
+ */
1432
3050
  async function populate(context, data, key, model) {
1433
3051
  if (!data.populate)
1434
3052
  return;
@@ -1459,6 +3077,12 @@ async function populate(context, data, key, model) {
1459
3077
  const res = await fetchPopulateValues(context, model, key, isArr ? nested : [nested]);
1460
3078
  model[key] = isArr ? res : res[0];
1461
3079
  }
3080
+ /**
3081
+ * @description List of common JavaScript types
3082
+ * @summary An array of strings representing common JavaScript types that are not custom model types
3083
+ * @const commomTypes
3084
+ * @memberOf module:core
3085
+ */
1462
3086
  const commomTypes = [
1463
3087
  "array",
1464
3088
  "string",
@@ -1471,6 +3095,48 @@ const commomTypes = [
1471
3095
  "null",
1472
3096
  "bigint",
1473
3097
  ];
3098
+ /**
3099
+ * @description Retrieves a repository for a model property based on its type metadata
3100
+ * @summary Examines a model property's type metadata to determine the appropriate repository for related models
3101
+ * @template M - The model type extending Model
3102
+ * @param {any} model - The model instance containing the property
3103
+ * @param propertyKey - The property key to examine
3104
+ * @return {Repo<M>} A repository for the model type associated with the property
3105
+ * @function repositoryFromTypeMetadata
3106
+ * @memberOf module:core
3107
+ * @mermaid
3108
+ * sequenceDiagram
3109
+ * participant Caller
3110
+ * participant repositoryFromTypeMetadata
3111
+ * participant Reflect
3112
+ * participant Validation
3113
+ * participant Model
3114
+ * participant Repository
3115
+ *
3116
+ * Caller->>repositoryFromTypeMetadata: model, propertyKey
3117
+ *
3118
+ * repositoryFromTypeMetadata->>Validation: key(Array.isArray(model[propertyKey]) ? ValidationKeys.LIST : ValidationKeys.TYPE)
3119
+ * Validation-->>repositoryFromTypeMetadata: validationKey
3120
+ *
3121
+ * repositoryFromTypeMetadata->>Reflect: getMetadata(validationKey, model, propertyKey)
3122
+ * Reflect-->>repositoryFromTypeMetadata: types
3123
+ *
3124
+ * repositoryFromTypeMetadata->>repositoryFromTypeMetadata: determine customTypes based on property type
3125
+ * repositoryFromTypeMetadata->>repositoryFromTypeMetadata: check if types and customTypes exist
3126
+ *
3127
+ * repositoryFromTypeMetadata->>repositoryFromTypeMetadata: create allowedTypes array
3128
+ * repositoryFromTypeMetadata->>repositoryFromTypeMetadata: find constructorName not in commomTypes
3129
+ * repositoryFromTypeMetadata->>repositoryFromTypeMetadata: check if constructorName exists
3130
+ *
3131
+ * repositoryFromTypeMetadata->>Model: get(constructorName)
3132
+ * Model-->>repositoryFromTypeMetadata: constructor
3133
+ * repositoryFromTypeMetadata->>repositoryFromTypeMetadata: check if constructor exists
3134
+ *
3135
+ * repositoryFromTypeMetadata->>Repository: forModel(constructor)
3136
+ * Repository-->>repositoryFromTypeMetadata: repo
3137
+ *
3138
+ * repositoryFromTypeMetadata-->>Caller: repo
3139
+ */
1474
3140
  function repositoryFromTypeMetadata(model, propertyKey) {
1475
3141
  const types = Reflect.getMetadata(Validation.key(Array.isArray(model[propertyKey])
1476
3142
  ? ValidationKeys.LIST
@@ -1492,21 +3158,36 @@ function repositoryFromTypeMetadata(model, propertyKey) {
1492
3158
  return Repository.forModel(constructor);
1493
3159
  }
1494
3160
 
3161
+ /**
3162
+ * @description Specifies the database table name for a model
3163
+ * @summary Decorator that sets the table name for a model class in the database
3164
+ * @param {string} tableName - The name of the table in the database
3165
+ * @return {Function} A decorator function that can be applied to a class
3166
+ * @function table
3167
+ * @category Class Decorators
3168
+ */
1495
3169
  function table(tableName) {
1496
3170
  return metadata(Adapter.key(PersistenceKeys.TABLE), tableName);
1497
3171
  }
3172
+ /**
3173
+ * @description Specifies the database column name for a model property
3174
+ * @summary Decorator that maps a model property to a specific column name in the database
3175
+ * @param {string} columnName - The name of the column in the database
3176
+ * @return {Function} A decorator function that can be applied to a class property
3177
+ * @function column
3178
+ * @category Property Decorators
3179
+ */
1498
3180
  function column(columnName) {
1499
3181
  return propMetadata(Adapter.key(PersistenceKeys.COLUMN), columnName);
1500
3182
  }
1501
3183
  /**
1502
- * @summary Index Decorator
1503
- * @description properties decorated will the index in the
1504
- * DB for performance in queries
1505
- *
1506
- * @param {OrderDirection[]} [directions]
1507
- * @param {string[]} [compositions]
1508
- *
3184
+ * @description Creates an index on a model property for improved query performance
3185
+ * @summary Decorator that marks a property to be indexed in the database, optionally with specific directions and compositions
3186
+ * @param {OrderDirection[]} [directions] - Optional array of sort directions for the index
3187
+ * @param {string[]} [compositions] - Optional array of property names to create a composite index
3188
+ * @return {Function} A decorator function that can be applied to a class property
1509
3189
  * @function index
3190
+ * @category Property Decorators
1510
3191
  */
1511
3192
  function index(directions, compositions) {
1512
3193
  return propMetadata(Repository.key(`${PersistenceKeys.INDEX}${compositions && compositions.length ? `.${compositions.join(".")}` : ""}`), {
@@ -1514,6 +3195,23 @@ function index(directions, compositions) {
1514
3195
  compositions: compositions,
1515
3196
  });
1516
3197
  }
3198
+ /**
3199
+ * @description Enforces uniqueness constraint during model creation and update
3200
+ * @summary Internal function used by the unique decorator to check if a property value already exists in the database
3201
+ * @template M - The model type extending Model
3202
+ * @template R - The repository type extending Repo<M, F, C>
3203
+ * @template V - The metadata type
3204
+ * @template F - The repository flags type
3205
+ * @template C - The context type extending Context<F>
3206
+ * @param {R} this - The repository instance
3207
+ * @param {Context<F>} context - The context for the operation
3208
+ * @param {V} data - The metadata for the property
3209
+ * @param key - The property key to check for uniqueness
3210
+ * @param {M} model - The model instance being created or updated
3211
+ * @return {Promise<void>} A promise that resolves when the check is complete or rejects with a ConflictError
3212
+ * @function uniqueOnCreateUpdate
3213
+ * @memberOf module:core
3214
+ */
1517
3215
  async function uniqueOnCreateUpdate(context, data, key, model) {
1518
3216
  if (!model[key])
1519
3217
  return;
@@ -1524,16 +3222,40 @@ async function uniqueOnCreateUpdate(context, data, key, model) {
1524
3222
  throw new ConflictError(`model already exists with property ${key} equal to ${JSON.stringify(model[key], undefined, 2)}`);
1525
3223
  }
1526
3224
  /**
1527
- * @summary Unique Decorator
1528
- * @description Tags a property as unique.
1529
- * No other elements in that table can have the same property value
1530
- *
3225
+ * @description Tags a property as unique
3226
+ * @summary Decorator that ensures a property value is unique across all instances of a model in the database
3227
+ * @return {Function} A decorator function that can be applied to a class property
1531
3228
  * @function unique
1532
- *
3229
+ * @category Property Decorators
3230
+ * @example
3231
+ * ```typescript
3232
+ * class User extends BaseModel {
3233
+ * @unique()
3234
+ * @required()
3235
+ * username!: string;
3236
+ * }
3237
+ * ```
1533
3238
  */
1534
3239
  function unique() {
1535
3240
  return apply(onCreateUpdate(uniqueOnCreateUpdate), propMetadata(Repository.key(PersistenceKeys.UNIQUE), {}));
1536
3241
  }
3242
+ /**
3243
+ * @description Handles user identification for ownership tracking
3244
+ * @summary Internal function used by the createdBy and updatedBy decorators to set ownership information
3245
+ * @template M - The model type extending Model
3246
+ * @template R - The repository type extending Repo<M, F, C>
3247
+ * @template V - The relations metadata type extending RelationsMetadata
3248
+ * @template F - The repository flags type
3249
+ * @template C - The context type extending Context<F>
3250
+ * @param {R} this - The repository instance
3251
+ * @param {Context<F>} context - The context for the operation
3252
+ * @param {V} data - The metadata for the property
3253
+ * @param key - The property key to store the user identifier
3254
+ * @param {M} model - The model instance being created or updated
3255
+ * @return {Promise<void>} A promise that rejects with an AuthorizationError if user identification is not supported
3256
+ * @function createdByOnCreateUpdate
3257
+ * @memberOf module:core
3258
+ */
1537
3259
  async function createdByOnCreateUpdate(
1538
3260
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
1539
3261
  context,
@@ -1545,12 +3267,40 @@ key,
1545
3267
  model) {
1546
3268
  throw new AuthorizationError("This adapter does not support user identification");
1547
3269
  }
3270
+ /**
3271
+ * @description Tracks the creator of a model instance
3272
+ * @summary Decorator that marks a property to store the identifier of the user who created the model instance
3273
+ * @return {Function} A decorator function that can be applied to a class property
3274
+ * @function createdBy
3275
+ * @category Property Decorators
3276
+ * @example
3277
+ * ```typescript
3278
+ * class Document extends BaseModel {
3279
+ * @createdBy()
3280
+ * creator!: string;
3281
+ * }
3282
+ * ```
3283
+ */
1548
3284
  function createdBy() {
1549
3285
  const key = Repository.key(PersistenceKeys.CREATED_BY);
1550
3286
  return Decoration.for(key)
1551
3287
  .define(onCreate(createdByOnCreateUpdate), propMetadata(key, {}))
1552
3288
  .apply();
1553
3289
  }
3290
+ /**
3291
+ * @description Tracks the last updater of a model instance
3292
+ * @summary Decorator that marks a property to store the identifier of the user who last updated the model instance
3293
+ * @return {Function} A decorator function that can be applied to a class property
3294
+ * @function updatedBy
3295
+ * @category Property Decorators
3296
+ * @example
3297
+ * ```typescript
3298
+ * class Document extends BaseModel {
3299
+ * @updatedBy()
3300
+ * lastEditor!: string;
3301
+ * }
3302
+ * ```
3303
+ */
1554
3304
  function updatedBy() {
1555
3305
  const key = Repository.key(PersistenceKeys.UPDATED_BY);
1556
3306
  return Decoration.for(key)
@@ -1558,15 +3308,27 @@ function updatedBy() {
1558
3308
  .apply();
1559
3309
  }
1560
3310
  /**
1561
- * @summary One To One relation Decorators
1562
- *
1563
- * @param {Constructor<any>} clazz the {@link Sequence}
1564
- * @param {CascadeMetadata} [cascadeOptions]
1565
- * @param {boolean} populate If true, replaces the specified key in the document with the corresponding record from the database
1566
- *
3311
+ * @description Defines a one-to-one relationship between models
3312
+ * @summary Decorator that establishes a one-to-one relationship between the current model and another model
3313
+ * @template M - The related model type extending Model
3314
+ * @param {Constructor<M>} clazz - The constructor of the related model class
3315
+ * @param {CascadeMetadata} [cascadeOptions=DefaultCascade] - Options for cascading operations (create, update, delete)
3316
+ * @param {boolean} [populate=true] - If true, automatically populates the relationship when the model is retrieved
3317
+ * @return {Function} A decorator function that can be applied to a class property
1567
3318
  * @function oneToOne
3319
+ * @category Property Decorators
3320
+ * @example
3321
+ * ```typescript
3322
+ * class User extends BaseModel {
3323
+ * @oneToOne(Profile)
3324
+ * profile!: string | Profile;
3325
+ * }
1568
3326
  *
1569
- *
3327
+ * class Profile extends BaseModel {
3328
+ * @required()
3329
+ * bio!: string;
3330
+ * }
3331
+ * ```
1570
3332
  * @see oneToMany
1571
3333
  * @see manyToOne
1572
3334
  */
@@ -1583,13 +3345,30 @@ function oneToOne(clazz, cascadeOptions = DefaultCascade, populate$1 = true) {
1583
3345
  .apply();
1584
3346
  }
1585
3347
  /**
1586
- * @summary One To Many relation Decorators
1587
- *
1588
- * @param {Constructor<any>} clazz the {@link Sequence} to use.
1589
- * @param {CascadeMetadata} [cascadeOptions]
1590
- *
3348
+ * @description Defines a one-to-many relationship between models
3349
+ * @summary Decorator that establishes a one-to-many relationship between the current model and multiple instances of another model
3350
+ * @template M - The related model type extending Model
3351
+ * @param {Constructor<M>} clazz - The constructor of the related model class
3352
+ * @param {CascadeMetadata} [cascadeOptions=DefaultCascade] - Options for cascading operations (create, update, delete)
3353
+ * @param {boolean} [populate=true] - If true, automatically populates the relationship when the model is retrieved
3354
+ * @return {Function} A decorator function that can be applied to a class property
1591
3355
  * @function oneToMany
3356
+ * @category Property Decorators
3357
+ * @example
3358
+ * ```typescript
3359
+ * class Author extends BaseModel {
3360
+ * @required()
3361
+ * name!: string;
1592
3362
  *
3363
+ * @oneToMany(Book)
3364
+ * books!: string[] | Book[];
3365
+ * }
3366
+ *
3367
+ * class Book extends BaseModel {
3368
+ * @required()
3369
+ * title!: string;
3370
+ * }
3371
+ * ```
1593
3372
  * @see oneToOne
1594
3373
  * @see manyToOne
1595
3374
  */
@@ -1608,13 +3387,30 @@ function oneToMany(clazz, cascadeOptions = DefaultCascade, populate$1 = true) {
1608
3387
  .apply();
1609
3388
  }
1610
3389
  /**
1611
- * @summary Many To One relation Decorators
1612
- *
1613
- * @param {Constructor<any>} clazz the {@link Sequence} to use. Defaults to {@link NoneSequence}
1614
- * @param {CascadeMetadata} [cascadeOptions]
1615
- *
3390
+ * @description Defines a many-to-one relationship between models
3391
+ * @summary Decorator that establishes a many-to-one relationship between multiple instances of the current model and another model
3392
+ * @template M - The related model type extending Model
3393
+ * @param {Constructor<M>} clazz - The constructor of the related model class
3394
+ * @param {CascadeMetadata} [cascadeOptions=DefaultCascade] - Options for cascading operations (create, update, delete)
3395
+ * @param {boolean} [populate=true] - If true, automatically populates the relationship when the model is retrieved
3396
+ * @return {Function} A decorator function that can be applied to a class property
1616
3397
  * @function manyToOne
3398
+ * @category Property Decorators
3399
+ * @example
3400
+ * ```typescript
3401
+ * class Book extends BaseModel {
3402
+ * @required()
3403
+ * title!: string;
1617
3404
  *
3405
+ * @manyToOne(Author)
3406
+ * author!: string | Author;
3407
+ * }
3408
+ *
3409
+ * class Author extends BaseModel {
3410
+ * @required()
3411
+ * name!: string;
3412
+ * }
3413
+ * ```
1618
3414
  * @see oneToMany
1619
3415
  * @see oneToOne
1620
3416
  */
@@ -1636,6 +3432,42 @@ function manyToOne(clazz, cascadeOptions = DefaultCascade, populate = true) {
1636
3432
  .apply();
1637
3433
  }
1638
3434
 
3435
+ /**
3436
+ * @description Callback function for primary key creation
3437
+ * @summary Handles the creation of primary key values for models using sequences
3438
+ * @template M - Type that extends Model
3439
+ * @template R - Type that extends Repo<M, F, C>
3440
+ * @template V - Type that extends SequenceOptions
3441
+ * @template F - Type that extends RepositoryFlags
3442
+ * @template C - Type that extends Context<F>
3443
+ * @param {Context<F>} context - The execution context
3444
+ * @param {V} data - The sequence options
3445
+ * @param key - The property key to set as primary key
3446
+ * @param {M} model - The model instance
3447
+ * @return {Promise<void>} A promise that resolves when the primary key is set
3448
+ * @function pkOnCreate
3449
+ * @category Property Decorators
3450
+ * @mermaid
3451
+ * sequenceDiagram
3452
+ * participant Model
3453
+ * participant pkOnCreate
3454
+ * participant Adapter
3455
+ * participant Sequence
3456
+ *
3457
+ * Model->>pkOnCreate: Call with model instance
3458
+ * Note over pkOnCreate: Check if key already exists
3459
+ * alt Key exists or no type specified
3460
+ * pkOnCreate-->>Model: Return early
3461
+ * else Key needs to be created
3462
+ * pkOnCreate->>pkOnCreate: Generate sequence name if not provided
3463
+ * pkOnCreate->>Adapter: Request Sequence(data)
3464
+ * Adapter->>Sequence: Create sequence
3465
+ * Sequence-->>pkOnCreate: Return sequence
3466
+ * pkOnCreate->>Sequence: Call next()
3467
+ * Sequence-->>pkOnCreate: Return next value
3468
+ * pkOnCreate->>Model: Set primary key value
3469
+ * end
3470
+ */
1639
3471
  async function pkOnCreate(context, data, key, model) {
1640
3472
  if (!data.type || model[key]) {
1641
3473
  return;
@@ -1661,15 +3493,24 @@ async function pkOnCreate(context, data, key, model) {
1661
3493
  setPrimaryKeyValue(model, key, next);
1662
3494
  }
1663
3495
  /**
1664
- * @summary Primary Key Decorator
1665
- * @description Marks the property as the {@link Model}s primary key.
1666
- * Also marks the property as {@link unique} as {@required} and ensures the index is created properly according to the provided {@link Sequence}
1667
- *
3496
+ * @description Primary Key Decorator
3497
+ * @summary Marks a property as the model's primary key with automatic sequence generation
3498
+ * This decorator combines multiple behaviors: it marks the property as unique, required,
3499
+ * and ensures the index is created properly according to the provided sequence options.
3500
+ * @param {Omit<SequenceOptions, "cycle" | "startWith" | "incrementBy">} opts - Options for the sequence generation
3501
+ * @return {PropertyDecorator} A property decorator that can be applied to model properties
1668
3502
  * @function pk
3503
+ * @category Property Decorators
3504
+ * @example
3505
+ * ```typescript
3506
+ * class User extends BaseModel {
3507
+ * @pk()
3508
+ * id!: string;
1669
3509
  *
1670
- * @see unique
1671
- * @see required
1672
- * @see on
3510
+ * @required()
3511
+ * username!: string;
3512
+ * }
3513
+ * ```
1673
3514
  */
1674
3515
  function pk(opts = DefaultSequenceOptions) {
1675
3516
  opts = Object.assign({}, DefaultSequenceOptions, opts);
@@ -1681,6 +3522,29 @@ function pk(opts = DefaultSequenceOptions) {
1681
3522
  .apply();
1682
3523
  }
1683
3524
 
3525
+ /**
3526
+ * @description Base model class for all domain models
3527
+ * @summary An abstract base class that extends the Model class from decorator-validation and adds timestamp functionality.
3528
+ * All domain models in the application should extend this class to inherit common properties and behaviors.
3529
+ * @param {ModelArg<BaseModel>} arg - Optional initialization data for the model
3530
+ * @class BaseModel
3531
+ * @example
3532
+ * ```typescript
3533
+ * class User extends BaseModel {
3534
+ * @required()
3535
+ * username!: string;
3536
+ *
3537
+ * @email()
3538
+ * email!: string;
3539
+ *
3540
+ * constructor(data?: ModelArg<User>) {
3541
+ * super(data);
3542
+ * }
3543
+ * }
3544
+ *
3545
+ * const user = new User({ username: 'john', email: 'john@example.com' });
3546
+ * ```
3547
+ */
1684
3548
  class BaseModel extends Model {
1685
3549
  constructor(arg) {
1686
3550
  super(arg);
@@ -1695,6 +3559,62 @@ __decorate([
1695
3559
  __metadata("design:type", Date)
1696
3560
  ], BaseModel.prototype, "updatedOn", void 0);
1697
3561
 
3562
+ /**
3563
+ * @description Handles pagination for database queries
3564
+ * @summary Provides functionality for navigating through paginated query results
3565
+ *
3566
+ * This abstract class manages the state and navigation of paginated database query results.
3567
+ * It tracks the current page, total pages, and record count, and provides methods for
3568
+ * moving between pages.
3569
+ *
3570
+ * @template M - The model type this paginator operates on
3571
+ * @template R - The return type of the paginated query (defaults to M[])
3572
+ * @template Q - The query type (defaults to any)
3573
+ * @param {Adapter<any, Q, any, any>} adapter - The database adapter to use for executing queries
3574
+ * @param {Q} query - The query to paginate
3575
+ * @param {number} size - The number of records per page
3576
+ * @param {Constructor<M>} clazz - The constructor for the model type
3577
+ * @class Paginator
3578
+ * @example
3579
+ * // Create a paginator for a user query
3580
+ * const userQuery = db.select().from(User);
3581
+ * const paginator = await userQuery.paginate(10); // 10 users per page
3582
+ *
3583
+ * // Get the first page of results
3584
+ * const firstPage = await paginator.page(1);
3585
+ *
3586
+ * // Navigate to the next page
3587
+ * const secondPage = await paginator.next();
3588
+ *
3589
+ * // Get information about the pagination
3590
+ * console.log(`Page ${paginator.current} of ${paginator.total}, ${paginator.count} total records`);
3591
+ *
3592
+ * @mermaid
3593
+ * sequenceDiagram
3594
+ * participant Client
3595
+ * participant Paginator
3596
+ * participant Adapter
3597
+ * participant Database
3598
+ *
3599
+ * Client->>Paginator: new Paginator(adapter, query, size, clazz)
3600
+ * Client->>Paginator: page(1)
3601
+ * Paginator->>Paginator: validatePage(1)
3602
+ * Paginator->>Paginator: prepare(query)
3603
+ * Paginator->>Adapter: execute query with pagination
3604
+ * Adapter->>Database: execute query
3605
+ * Database-->>Adapter: return results
3606
+ * Adapter-->>Paginator: return results
3607
+ * Paginator-->>Client: return page results
3608
+ *
3609
+ * Client->>Paginator: next()
3610
+ * Paginator->>Paginator: page(current + 1)
3611
+ * Paginator->>Paginator: validatePage(current + 1)
3612
+ * Paginator->>Adapter: execute query with pagination
3613
+ * Adapter->>Database: execute query
3614
+ * Database-->>Adapter: return results
3615
+ * Adapter-->>Paginator: return results
3616
+ * Paginator-->>Client: return page results
3617
+ */
1698
3618
  class Paginator {
1699
3619
  get current() {
1700
3620
  return this._currentPage;
@@ -1732,6 +3652,57 @@ class Paginator {
1732
3652
  }
1733
3653
 
1734
3654
  var _a, _b, _c, _d;
3655
+ /**
3656
+ * @description Base class for database query statements
3657
+ * @summary Provides a foundation for building and executing database queries
3658
+ *
3659
+ * This abstract class implements the query builder pattern for constructing
3660
+ * database queries. It supports various query operations like select, from,
3661
+ * where, orderBy, groupBy, limit, and offset. It also provides methods for
3662
+ * executing queries and handling pagination.
3663
+ *
3664
+ * @template Q - The query type specific to the database adapter
3665
+ * @template M - The model type this statement operates on
3666
+ * @template R - The return type of the query
3667
+ * @param {Adapter<any, Q, any, any>} adapter - The database adapter to use for executing queries
3668
+ * @class Statement
3669
+ * @example
3670
+ * // Create a statement to query users
3671
+ * const statement = new SQLStatement(adapter);
3672
+ * const users = await statement
3673
+ * .select()
3674
+ * .from(User)
3675
+ * .where(Condition.attribute("status").eq("active"))
3676
+ * .orderBy(["createdAt", "DESC"])
3677
+ * .limit(10)
3678
+ * .execute();
3679
+ *
3680
+ * // Use pagination
3681
+ * const paginator = await statement
3682
+ * .select()
3683
+ * .from(User)
3684
+ * .paginate(20); // 20 users per page
3685
+ *
3686
+ * @mermaid
3687
+ * sequenceDiagram
3688
+ * participant Client
3689
+ * participant Statement
3690
+ * participant Adapter
3691
+ * participant Database
3692
+ *
3693
+ * Client->>Statement: select()
3694
+ * Client->>Statement: from(Model)
3695
+ * Client->>Statement: where(condition)
3696
+ * Client->>Statement: orderBy([field, direction])
3697
+ * Client->>Statement: limit(value)
3698
+ * Client->>Statement: execute()
3699
+ * Statement->>Statement: build()
3700
+ * Statement->>Adapter: raw(query)
3701
+ * Adapter->>Database: execute query
3702
+ * Database-->>Adapter: return results
3703
+ * Adapter-->>Statement: return processed results
3704
+ * Statement-->>Client: return final results
3705
+ */
1735
3706
  class Statement {
1736
3707
  constructor(adapter) {
1737
3708
  this.adapter = adapter;
@@ -1881,15 +3852,22 @@ __decorate([
1881
3852
  __metadata("design:returntype", Promise)
1882
3853
  ], Statement.prototype, "execute", null);
1883
3854
 
3855
+ /**
3856
+ * @module core
3857
+ * @description Core module for the Decaf TypeScript framework
3858
+ * @summary This module provides the foundational components of the Decaf framework, including identity management,
3859
+ * model definitions, repository patterns, persistence layer, query building, and utility functions.
3860
+ * It exports functionality from various submodules and sets up the injectable registry for repository decorators.
3861
+ */
1884
3862
  // overrides the previous Injectables registry to enable the @repository decorator
1885
3863
  Injectables.setRegistry(new InjectablesRegistry());
1886
3864
  /**
1887
- * @summary stores the current package version
1888
- * @description this is how you should document a constant
3865
+ * @description Stores the current package version
3866
+ * @summary A constant representing the version of the core package
1889
3867
  * @const VERSION
1890
3868
  * @memberOf module:core
1891
3869
  */
1892
3870
  const VERSION = "0.5.1";
1893
3871
 
1894
3872
  export { Adapter, AuthorizationError, BaseModel, BigIntSequence, Cascade, Condition, ConnectionError, DefaultCascade, DefaultSequenceOptions, Dispatch, ForbiddenError, GroupOperator, InjectablesRegistry, NumericSequence, ObserverError, ObserverHandler, Operator, OrderDirection, Paginator, PagingError, PersistenceKeys, QueryError, Repository, Sequence, Statement, UnsupportedError, VERSION, cacheModelForPopulate, column, createOrUpdate, createdBy, createdByOnCreateUpdate, final, generateInjectableNameForRepository, getPopulateKey, getTableName, index, manyToOne, oneToMany, oneToManyOnCreate, oneToManyOnDelete, oneToManyOnUpdate, oneToOne, oneToOneOnCreate, oneToOneOnDelete, oneToOneOnUpdate, pk, pkOnCreate, populate, repository, repositoryFromTypeMetadata, sequenceNameForModel, table, unique, uniqueOnCreateUpdate, updatedBy, uses };
1895
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29yZS5lc20uY2pzIiwic291cmNlcyI6WyIuLi9zcmMvcmVwb3NpdG9yeS9jb25zdGFudHMudHMiLCIuLi9zcmMvcGVyc2lzdGVuY2UvY29uc3RhbnRzLnRzIiwiLi4vc3JjL3V0aWxzL2RlY29yYXRvcnMudHMiLCIuLi9zcmMvdXRpbHMvZXJyb3JzLnRzIiwiLi4vc3JjL3BlcnNpc3RlbmNlL2Vycm9ycy50cyIsIi4uL3NyYy9wZXJzaXN0ZW5jZS9EaXNwYXRjaC50cyIsIi4uL3NyYy9wZXJzaXN0ZW5jZS9PYnNlcnZlckhhbmRsZXIudHMiLCIuLi9zcmMvcGVyc2lzdGVuY2UvQWRhcHRlci50cyIsIi4uL3NyYy9pZGVudGl0eS91dGlscy50cyIsIi4uL3NyYy9wZXJzaXN0ZW5jZS9TZXF1ZW5jZS50cyIsIi4uL3NyYy9wZXJzaXN0ZW5jZS9kZWNvcmF0b3JzLnRzIiwiLi4vc3JjL3JlcG9zaXRvcnkvUmVwb3NpdG9yeS50cyIsIi4uL3NyYy9yZXBvc2l0b3J5L2RlY29yYXRvcnMudHMiLCIuLi9zcmMvcmVwb3NpdG9yeS9lcnJvcnMudHMiLCIuLi9zcmMvcmVwb3NpdG9yeS91dGlscy50cyIsIi4uL3NyYy9yZXBvc2l0b3J5L2luamVjdGFibGVzLnRzIiwiLi4vc3JjL2ludGVyZmFjZXMvU2VxdWVuY2VPcHRpb25zLnRzIiwiLi4vc3JjL3F1ZXJ5L2NvbnN0YW50cy50cyIsIi4uL3NyYy9xdWVyeS9lcnJvcnMudHMiLCIuLi9zcmMvcXVlcnkvQ29uZGl0aW9uLnRzIiwiLi4vc3JjL21vZGVsL2NvbnN0cnVjdGlvbi50cyIsIi4uL3NyYy9tb2RlbC9kZWNvcmF0b3JzLnRzIiwiLi4vc3JjL2lkZW50aXR5L2RlY29yYXRvcnMudHMiLCIuLi9zcmMvbW9kZWwvQmFzZU1vZGVsLnRzIiwiLi4vc3JjL3F1ZXJ5L1BhZ2luYXRvci50cyIsIi4uL3NyYy9xdWVyeS9TdGF0ZW1lbnQudHMiLCIuLi9zcmMvaW5kZXgudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ2FzY2FkZU1ldGFkYXRhIH0gZnJvbSBcIi4vdHlwZXNcIjtcblxuZXhwb3J0IGVudW0gT3JkZXJEaXJlY3Rpb24ge1xuICBBU0MgPSBcImFzY1wiLFxuXG4gIERTQyA9IFwiZGVzY1wiLFxufVxuXG5leHBvcnQgZW51bSBDYXNjYWRlIHtcbiAgQ0FTQ0FERSA9IFwiY2FzY2FkZVwiLFxuICBOT05FID0gXCJub25lXCIsXG59XG5cbmV4cG9ydCBjb25zdCBEZWZhdWx0Q2FzY2FkZTogQ2FzY2FkZU1ldGFkYXRhID0ge1xuICB1cGRhdGU6IENhc2NhZGUuQ0FTQ0FERSxcbiAgZGVsZXRlOiBDYXNjYWRlLk5PTkUsXG59O1xuIiwiZXhwb3J0IGVudW0gUGVyc2lzdGVuY2VLZXlzIHtcbiAgSU5ERVggPSBcImluZGV4XCIsXG4gIFVOSVFVRSA9IFwidW5pcXVlXCIsXG4gIEFEQVBURVIgPSBcImFkYXB0ZXJcIixcbiAgSU5KRUNUQUJMRSA9IFwiZGVjYWZfezB9X2FkYXB0ZXJfZm9yX3sxfVwiLFxuICBUQUJMRSA9IFwidGFibGVcIixcbiAgQ09MVU1OID0gXCJjb2x1bW5cIixcbiAgTUVUQURBVEEgPSBcIl9fbWV0YWRhdGFcIixcbiAgUkVMQVRJT05TID0gXCJfX3JlbGF0aW9uc1wiLFxuICBDTEFVU0VfU0VRVUVOQ0UgPSBcImNsYXVzZS1zZXF1ZW5jZVwiLFxuICAvLyBPd25lcnNoaXBcbiAgQ1JFQVRFRF9CWSA9IFwib3duZXJzaGlwLmNyZWF0ZWQtYnlcIixcbiAgVVBEQVRFRF9CWSA9IFwib3duZXJzaGlwLnVwZGF0ZWQtYnlcIixcbiAgLy8gUmVsYXRpb25zXG4gIE9ORV9UT19PTkUgPSBcInJlbGF0aW9ucy5vbmUtdG8tb25lXCIsXG4gIE9ORV9UT19NQU5ZID0gXCJyZWxhdGlvbnMub25lLXRvLW1hbnlcIixcbiAgTUFOWV9UT19PTkUgPSBcInJlbGF0aW9ucy5tYW55LXRvLW9uZVwiLFxuICBQT1BVTEFURSA9IFwicG9wdWxhdGVcIixcbn1cbiIsImV4cG9ydCBmdW5jdGlvbiBmaW5hbCgpIHtcbiAgcmV0dXJuIChcbiAgICB0YXJnZXQ6IG9iamVjdCxcbiAgICBwcm9wZXJ0eUtleT86IGFueSxcbiAgICBkZXNjcmlwdG9yPzogUHJvcGVydHlEZXNjcmlwdG9yXG4gICkgPT4ge1xuICAgIGlmICghZGVzY3JpcHRvcilcbiAgICAgIHRocm93IG5ldyBFcnJvcihcImZpbmFsIGRlY29yYXRvciBjYW4gb25seSBiZSB1c2VkIG9uIG1ldGhvZHNcIik7XG4gICAgaWYgKGRlc2NyaXB0b3I/LmNvbmZpZ3VyYWJsZSkge1xuICAgICAgZGVzY3JpcHRvci5jb25maWd1cmFibGUgPSBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIGRlc2NyaXB0b3I7XG4gIH07XG59XG4iLCJpbXBvcnQgeyBCYXNlRXJyb3IgfSBmcm9tIFwiQGRlY2FmLXRzL2RiLWRlY29yYXRvcnNcIjtcblxuZXhwb3J0IGNsYXNzIEF1dGhvcml6YXRpb25FcnJvciBleHRlbmRzIEJhc2VFcnJvciB7XG4gIGNvbnN0cnVjdG9yKG1zZzogc3RyaW5nIHwgRXJyb3IpIHtcbiAgICBzdXBlcihBdXRob3JpemF0aW9uRXJyb3IubmFtZSwgbXNnLCA0MDEpO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBGb3JiaWRkZW5FcnJvciBleHRlbmRzIEJhc2VFcnJvciB7XG4gIGNvbnN0cnVjdG9yKG1zZzogc3RyaW5nIHwgRXJyb3IpIHtcbiAgICBzdXBlcihGb3JiaWRkZW5FcnJvci5uYW1lLCBtc2csIDQwMyk7XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIENvbm5lY3Rpb25FcnJvciBleHRlbmRzIEJhc2VFcnJvciB7XG4gIGNvbnN0cnVjdG9yKG1zZzogc3RyaW5nIHwgRXJyb3IpIHtcbiAgICBzdXBlcihDb25uZWN0aW9uRXJyb3IubmFtZSwgbXNnLCA1MDMpO1xuICB9XG59XG4iLCJpbXBvcnQgeyBCYXNlRXJyb3IgfSBmcm9tIFwiQGRlY2FmLXRzL2RiLWRlY29yYXRvcnNcIjtcblxuZXhwb3J0IGNsYXNzIFVuc3VwcG9ydGVkRXJyb3IgZXh0ZW5kcyBCYXNlRXJyb3Ige1xuICBjb25zdHJ1Y3Rvcihtc2c6IHN0cmluZyB8IEVycm9yKSB7XG4gICAgc3VwZXIoVW5zdXBwb3J0ZWRFcnJvci5uYW1lLCBtc2csIDUwMCk7XG4gIH1cbn1cbiIsImltcG9ydCB7XG4gIEludGVybmFsRXJyb3IsXG4gIE9wZXJhdGlvbktleXMsXG4gIEJ1bGtDcnVkT3BlcmF0aW9uS2V5cyxcbn0gZnJvbSBcIkBkZWNhZi10cy9kYi1kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBNb2RlbENvbnN0cnVjdG9yIH0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgT2JzZXJ2ZXIgfSBmcm9tIFwiLi4vaW50ZXJmYWNlc1wiO1xuaW1wb3J0IHsgQWRhcHRlciB9IGZyb20gXCIuL0FkYXB0ZXJcIjtcbmltcG9ydCB7IFVuc3VwcG9ydGVkRXJyb3IgfSBmcm9tIFwiLi9lcnJvcnNcIjtcbmltcG9ydCB7IExvZ2dlciwgTG9nZ2luZyB9IGZyb20gXCJAZGVjYWYtdHMvbG9nZ2luZ1wiO1xuaW1wb3J0IHsgRXZlbnRJZHMgfSBmcm9tIFwiLi90eXBlc1wiO1xuXG5leHBvcnQgY2xhc3MgRGlzcGF0Y2g8WT4gaW1wbGVtZW50cyBPYnNlcnZhYmxlIHtcbiAgcHJvdGVjdGVkIGFkYXB0ZXI/OiBBZGFwdGVyPFksIGFueSwgYW55LCBhbnk+O1xuICBwcm90ZWN0ZWQgbmF0aXZlPzogWTtcbiAgcHJvdGVjdGVkIG1vZGVscyE6IE1vZGVsQ29uc3RydWN0b3I8YW55PltdO1xuXG4gIHByaXZhdGUgbG9nZ2VyITogTG9nZ2VyO1xuXG4gIHByb3RlY3RlZCBnZXQgbG9nKCkge1xuICAgIGlmICghdGhpcy5sb2dnZXIpXG4gICAgICB0aGlzLmxvZ2dlciA9IExvZ2dpbmcuZm9yKHRoaXMgYXMgYW55KS5mb3IodGhpcy5hZGFwdGVyIGFzIGFueSk7XG4gICAgcmV0dXJuIHRoaXMubG9nZ2VyO1xuICB9XG5cbiAgY29uc3RydWN0b3IoKSB7fVxuXG4gIHByb3RlY3RlZCBpbml0aWFsaXplKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5hZGFwdGVyKVxuICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoYE5vIGFkYXB0ZXIgb2JzZXJ2ZWQgZm9yIGRpc3BhdGNoYCk7XG4gICAgY29uc3QgYWRhcHRlciA9IHRoaXMuYWRhcHRlciBhcyBBZGFwdGVyPFksIGFueSwgYW55LCBhbnk+O1xuICAgIChcbiAgICAgIFtcbiAgICAgICAgT3BlcmF0aW9uS2V5cy5DUkVBVEUsXG4gICAgICAgIE9wZXJhdGlvbktleXMuVVBEQVRFLFxuICAgICAgICBPcGVyYXRpb25LZXlzLkRFTEVURSxcbiAgICAgICAgQnVsa0NydWRPcGVyYXRpb25LZXlzLkNSRUFURV9BTEwsXG4gICAgICAgIEJ1bGtDcnVkT3BlcmF0aW9uS2V5cy5VUERBVEVfQUxMLFxuICAgICAgICBCdWxrQ3J1ZE9wZXJhdGlvbktleXMuREVMRVRFX0FMTCxcbiAgICAgIF0gYXMgKGtleW9mIEFkYXB0ZXI8WSwgYW55LCBhbnksIGFueT4pW11cbiAgICApLmZvckVhY2goKG1ldGhvZCkgPT4ge1xuICAgICAgaWYgKCFhZGFwdGVyW21ldGhvZF0pXG4gICAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFxuICAgICAgICAgIGBNZXRob2QgJHttZXRob2R9IG5vdCBmb3VuZCBpbiAke2FkYXB0ZXIuYWxpYXN9IGFkYXB0ZXIgdG8gYmluZCBPYnNlcnZhYmxlcyBEaXNwYXRjaGBcbiAgICAgICAgKTtcblxuICAgICAgbGV0IGRlc2NyaXB0b3IgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKGFkYXB0ZXIsIG1ldGhvZCk7XG4gICAgICBsZXQgcHJvdG86IGFueSA9IGFkYXB0ZXI7XG4gICAgICB3aGlsZSAoIWRlc2NyaXB0b3IgJiYgcHJvdG8gIT09IE9iamVjdC5wcm90b3R5cGUpIHtcbiAgICAgICAgcHJvdG8gPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YocHJvdG8pO1xuICAgICAgICBkZXNjcmlwdG9yID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihwcm90bywgbWV0aG9kKTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFkZXNjcmlwdG9yIHx8ICFkZXNjcmlwdG9yLndyaXRhYmxlKSB7XG4gICAgICAgIHRoaXMubG9nLmVycm9yKFxuICAgICAgICAgIGBDb3VsZCBub3QgZmluZCBtZXRob2QgJHttZXRob2R9IHRvIGJpbmQgT2JzZXJ2YWJsZXMgRGlzcGF0Y2hgXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGZ1bmN0aW9uIGJ1bGtUb1NpbmdsZShtZXRob2Q6IHN0cmluZykge1xuICAgICAgICBzd2l0Y2ggKG1ldGhvZCkge1xuICAgICAgICAgIGNhc2UgQnVsa0NydWRPcGVyYXRpb25LZXlzLkNSRUFURV9BTEw6XG4gICAgICAgICAgICByZXR1cm4gT3BlcmF0aW9uS2V5cy5DUkVBVEU7XG4gICAgICAgICAgY2FzZSBCdWxrQ3J1ZE9wZXJhdGlvbktleXMuVVBEQVRFX0FMTDpcbiAgICAgICAgICAgIHJldHVybiBPcGVyYXRpb25LZXlzLlVQREFURTtcbiAgICAgICAgICBjYXNlIEJ1bGtDcnVkT3BlcmF0aW9uS2V5cy5ERUxFVEVfQUxMOlxuICAgICAgICAgICAgcmV0dXJuIE9wZXJhdGlvbktleXMuREVMRVRFO1xuICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICByZXR1cm4gbWV0aG9kO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICAvLyBAdHMtZXhwZWN0LWVycm9yIGJlY2F1c2UgdGhlcmUgYXJlIHJlYWQgb25seSBwcm9wZXJ0aWVzXG4gICAgICBhZGFwdGVyW21ldGhvZF0gPSBuZXcgUHJveHkoYWRhcHRlclttZXRob2RdLCB7XG4gICAgICAgIGFwcGx5OiBhc3luYyAodGFyZ2V0OiBhbnksIHRoaXNBcmcsIGFyZ0FycmF5OiBhbnlbXSkgPT4ge1xuICAgICAgICAgIGNvbnN0IFt0YWJsZU5hbWUsIGlkc10gPSBhcmdBcnJheTtcbiAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0YXJnZXQuYXBwbHkodGhpc0FyZywgYXJnQXJyYXkpO1xuICAgICAgICAgIHRoaXMudXBkYXRlT2JzZXJ2ZXJzKHRhYmxlTmFtZSwgYnVsa1RvU2luZ2xlKG1ldGhvZCksIGlkcyBhcyBFdmVudElkcylcbiAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgdGhpcy5sb2cudmVyYm9zZShcbiAgICAgICAgICAgICAgICBgT2JzZXJ2ZXIgcmVmcmVzaCBkaXNwYXRjaGVkIGJ5ICR7bWV0aG9kfSBmb3IgJHt0YWJsZU5hbWV9YFxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICB0aGlzLmxvZy5kZWJ1ZyhgcGtzOiAke2lkc31gKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuY2F0Y2goKGU6IHVua25vd24pID0+XG4gICAgICAgICAgICAgIHRoaXMubG9nLmVycm9yKFxuICAgICAgICAgICAgICAgIGBGYWlsZWQgdG8gZGlzcGF0Y2ggb2JzZXJ2ZXIgcmVmcmVzaCBmb3IgJHttZXRob2R9IG9uICR7dGFibGVOYW1lfTogJHtlfWBcbiAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBvYnNlcnZlKG9ic2VydmVyOiBBZGFwdGVyPFksIGFueSwgYW55LCBhbnk+KTogdm9pZCB7XG4gICAgaWYgKCEob2JzZXJ2ZXIgaW5zdGFuY2VvZiBBZGFwdGVyKSlcbiAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZEVycm9yKFwiT25seSBBZGFwdGVycyBjYW4gYmUgb2JzZXJ2ZWQgYnkgZGlzcGF0Y2hcIik7XG4gICAgdGhpcy5hZGFwdGVyID0gb2JzZXJ2ZXI7XG4gICAgdGhpcy5uYXRpdmUgPSBvYnNlcnZlci5uYXRpdmU7XG4gICAgdGhpcy5tb2RlbHMgPSBBZGFwdGVyLm1vZGVscyh0aGlzLmFkYXB0ZXIuYWxpYXMpO1xuICAgIHRoaXMuaW5pdGlhbGl6ZSgpO1xuICAgIHRoaXMubG9nLnZlcmJvc2UoYERpc3BhdGNoIGluaXRpYWxpemVkIGZvciAke3RoaXMuYWRhcHRlci5hbGlhc30gYWRhcHRlcmApO1xuICB9XG5cbiAgdW5PYnNlcnZlKG9ic2VydmVyOiBPYnNlcnZlcik6IHZvaWQge1xuICAgIGlmICh0aGlzLmFkYXB0ZXIgIT09IG9ic2VydmVyKVxuICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkRXJyb3IoXG4gICAgICAgIFwiT25seSB0aGUgYWRhcHRlciB0aGF0IHdhcyB1c2VkIHRvIG9ic2VydmUgY2FuIGJlIHVub2JzZXJ2ZWRcIlxuICAgICAgKTtcbiAgICB0aGlzLmFkYXB0ZXIgPSB1bmRlZmluZWQ7XG4gIH1cblxuICBhc3luYyB1cGRhdGVPYnNlcnZlcnMoXG4gICAgdGFibGU6IHN0cmluZyxcbiAgICBldmVudDogT3BlcmF0aW9uS2V5cyB8IEJ1bGtDcnVkT3BlcmF0aW9uS2V5cyB8IHN0cmluZyxcbiAgICBpZDogRXZlbnRJZHNcbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKCF0aGlzLmFkYXB0ZXIpXG4gICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihgTm8gYWRhcHRlciBvYnNlcnZlZCBmb3IgZGlzcGF0Y2hgKTtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5hZGFwdGVyLnJlZnJlc2godGFibGUsIGV2ZW50LCBpZCk7XG4gICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoYEZhaWxlZCB0byByZWZyZXNoIGRpc3BhdGNoOiAke2V9YCk7XG4gICAgfVxuICB9XG59XG4iLCJpbXBvcnQgeyBPYnNlcnZhYmxlLCBPYnNlcnZlciB9IGZyb20gXCIuLi9pbnRlcmZhY2VzXCI7XG5pbXBvcnQgeyBFdmVudElkcywgT2JzZXJ2ZXJGaWx0ZXIgfSBmcm9tIFwiLi90eXBlc1wiO1xuaW1wb3J0IHtcbiAgQnVsa0NydWRPcGVyYXRpb25LZXlzLFxuICBJbnRlcm5hbEVycm9yLFxuICBPcGVyYXRpb25LZXlzLFxufSBmcm9tIFwiQGRlY2FmLXRzL2RiLWRlY29yYXRvcnNcIjtcbmltcG9ydCB7IExvZ2dlciB9IGZyb20gXCJAZGVjYWYtdHMvbG9nZ2luZ1wiO1xuXG5leHBvcnQgY2xhc3MgT2JzZXJ2ZXJIYW5kbGVyIGltcGxlbWVudHMgT2JzZXJ2YWJsZSB7XG4gIHByb3RlY3RlZCByZWFkb25seSBvYnNlcnZlcnM6IHtcbiAgICBvYnNlcnZlcjogT2JzZXJ2ZXI7XG4gICAgZmlsdGVyPzogT2JzZXJ2ZXJGaWx0ZXI7XG4gIH1bXSA9IFtdO1xuXG4gIGNvdW50KCkge1xuICAgIHJldHVybiB0aGlzLm9ic2VydmVycy5sZW5ndGg7XG4gIH1cblxuICBvYnNlcnZlKG9ic2VydmVyOiBPYnNlcnZlciwgZmlsdGVyPzogT2JzZXJ2ZXJGaWx0ZXIpOiB2b2lkIHtcbiAgICBjb25zdCBpbmRleCA9IHRoaXMub2JzZXJ2ZXJzLm1hcCgobykgPT4gby5vYnNlcnZlcikuaW5kZXhPZihvYnNlcnZlcik7XG4gICAgaWYgKGluZGV4ICE9PSAtMSkgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXCJPYnNlcnZlciBhbHJlYWR5IHJlZ2lzdGVyZWRcIik7XG4gICAgdGhpcy5vYnNlcnZlcnMucHVzaCh7IG9ic2VydmVyOiBvYnNlcnZlciwgZmlsdGVyOiBmaWx0ZXIgfSk7XG4gIH1cblxuICB1bk9ic2VydmUob2JzZXJ2ZXI6IE9ic2VydmVyKTogdm9pZCB7XG4gICAgY29uc3QgaW5kZXggPSB0aGlzLm9ic2VydmVycy5tYXAoKG8pID0+IG8ub2JzZXJ2ZXIpLmluZGV4T2Yob2JzZXJ2ZXIpO1xuICAgIGlmIChpbmRleCA9PT0gLTEpIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFwiRmFpbGVkIHRvIGZpbmQgT2JzZXJ2ZXJcIik7XG4gICAgdGhpcy5vYnNlcnZlcnMuc3BsaWNlKGluZGV4LCAxKTtcbiAgfVxuXG4gIGFzeW5jIHVwZGF0ZU9ic2VydmVycyhcbiAgICBsb2c6IExvZ2dlcixcbiAgICB0YWJsZTogc3RyaW5nLFxuICAgIGV2ZW50OiBPcGVyYXRpb25LZXlzIHwgQnVsa0NydWRPcGVyYXRpb25LZXlzIHwgc3RyaW5nLFxuICAgIGlkOiBFdmVudElkcyxcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCByZXN1bHRzID0gYXdhaXQgUHJvbWlzZS5hbGxTZXR0bGVkKFxuICAgICAgdGhpcy5vYnNlcnZlcnNcbiAgICAgICAgLmZpbHRlcigobykgPT4ge1xuICAgICAgICAgIGNvbnN0IHsgZmlsdGVyIH0gPSBvO1xuICAgICAgICAgIGlmICghZmlsdGVyKSByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgcmV0dXJuIGZpbHRlcih0YWJsZSwgZXZlbnQsIGlkKTtcbiAgICAgICAgICB9IGNhdGNoIChlOiB1bmtub3duKSB7XG4gICAgICAgICAgICBsb2cuZXJyb3IoXG4gICAgICAgICAgICAgIGBGYWlsZWQgdG8gZmlsdGVyIG9ic2VydmVyICR7by5vYnNlcnZlci50b1N0cmluZygpfTogJHtlfWBcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgICAubWFwKChvKSA9PiBvLm9ic2VydmVyLnJlZnJlc2godGFibGUsIGV2ZW50LCBpZCwgLi4uYXJncykpXG4gICAgKTtcbiAgICByZXN1bHRzLmZvckVhY2goKHJlc3VsdCwgaSkgPT4ge1xuICAgICAgaWYgKHJlc3VsdC5zdGF0dXMgPT09IFwicmVqZWN0ZWRcIilcbiAgICAgICAgbG9nLmVycm9yKFxuICAgICAgICAgIGBGYWlsZWQgdG8gdXBkYXRlIG9ic2VydmFibGUgJHt0aGlzLm9ic2VydmVyc1tpXS50b1N0cmluZygpfTogJHtyZXN1bHQucmVhc29ufWBcbiAgICAgICAgKTtcbiAgICB9KTtcbiAgfVxufVxuIiwiaW1wb3J0IHtcbiAgQmFzZUVycm9yLFxuICBEQktleXMsXG4gIEludGVybmFsRXJyb3IsXG4gIE5vdEZvdW5kRXJyb3IsXG4gIENvbnRleHQsXG4gIE9wZXJhdGlvbktleXMsXG4gIFJlcG9zaXRvcnlGbGFncyxcbiAgRGVmYXVsdFJlcG9zaXRvcnlGbGFncyxcbiAgQ29udGV4dHVhbCxcbiAgQnVsa0NydWRPcGVyYXRpb25LZXlzLFxuICBtb2RlbFRvVHJhbnNpZW50LFxufSBmcm9tIFwiQGRlY2FmLXRzL2RiLWRlY29yYXRvcnNcIjtcbmltcG9ydCB7IHR5cGUgT2JzZXJ2ZXIgfSBmcm9tIFwiLi4vaW50ZXJmYWNlcy9PYnNlcnZlclwiO1xuaW1wb3J0IHtcbiAgdHlwZSBDb25zdHJ1Y3RvcixcbiAgRGVjb3JhdGlvbixcbiAgRGVmYXVsdEZsYXZvdXIsXG4gIE1vZGVsLFxuICBNb2RlbENvbnN0cnVjdG9yLFxuICBNb2RlbFJlZ2lzdHJ5LFxufSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBTZXF1ZW5jZU9wdGlvbnMgfSBmcm9tIFwiLi4vaW50ZXJmYWNlcy9TZXF1ZW5jZU9wdGlvbnNcIjtcbmltcG9ydCB7IFJhd0V4ZWN1dG9yIH0gZnJvbSBcIi4uL2ludGVyZmFjZXMvUmF3RXhlY3V0b3JcIjtcbmltcG9ydCB7IE9ic2VydmFibGUgfSBmcm9tIFwiLi4vaW50ZXJmYWNlcy9PYnNlcnZhYmxlXCI7XG5pbXBvcnQgeyBQZXJzaXN0ZW5jZUtleXMgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IFJlcG9zaXRvcnkgfSBmcm9tIFwiLi4vcmVwb3NpdG9yeS9SZXBvc2l0b3J5XCI7XG5pbXBvcnQgeyBTZXF1ZW5jZSB9IGZyb20gXCIuL1NlcXVlbmNlXCI7XG5pbXBvcnQgeyBFcnJvclBhcnNlciB9IGZyb20gXCIuLi9pbnRlcmZhY2VzXCI7XG5pbXBvcnQgeyBTdGF0ZW1lbnQgfSBmcm9tIFwiLi4vcXVlcnkvU3RhdGVtZW50XCI7XG5pbXBvcnQgeyBMb2dnZXIsIExvZ2dpbmcgfSBmcm9tIFwiQGRlY2FmLXRzL2xvZ2dpbmdcIjtcbmltcG9ydCB7IGZpbmFsIH0gZnJvbSBcIi4uL3V0aWxzXCI7XG5pbXBvcnQgeyBEaXNwYXRjaCB9IGZyb20gXCIuL0Rpc3BhdGNoXCI7XG5pbXBvcnQgeyB0eXBlIEV2ZW50SWRzLCB0eXBlIE9ic2VydmVyRmlsdGVyIH0gZnJvbSBcIi4vdHlwZXNcIjtcbmltcG9ydCB7IE9ic2VydmVySGFuZGxlciB9IGZyb20gXCIuL09ic2VydmVySGFuZGxlclwiO1xuXG5EZWNvcmF0aW9uLnNldEZsYXZvdXJSZXNvbHZlcigob2JqOiBvYmplY3QpID0+IHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gKFxuICAgICAgQWRhcHRlci5mbGF2b3VyT2YoTW9kZWwuaXNNb2RlbChvYmopID8gb2JqLmNvbnN0cnVjdG9yIDogKG9iaiBhcyBhbnkpKSB8fFxuICAgICAgRGVmYXVsdEZsYXZvdXJcbiAgICApO1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgIHJldHVybiBEZWZhdWx0Rmxhdm91cjtcbiAgfVxufSk7XG5cbi8qKlxuICogQHN1bW1hcnkgQWJzdHJhY3QgRGVjYWYtdHMgUGVyc2lzdGVuY2UgQWRhcHRlciBDbGFzc1xuICogQGRlc2NyaXB0aW9uIE9mZmVycyB0aGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBmb3IgYWxsIEFkYXB0ZXIgQ2xhc3Nlc1xuICogYW5kIG1hbmFnZXMgdGhlbSB2YXJpb3VzIHJlZ2lzdGVyZWQge0BsaW5rIEFkYXB0ZXJ9c1xuICpcbiAqIEB0eXBlZGVmIFkgdGhlIHVuZGVybHlpbmcgcGVyc2lzdGVuY2Ugb2JqZWN0IHR5cGUgb3IgdGhlIHJlcXVpcmVkIGNvbmZpZyB0byBzZXQgaXQgdXBcbiAqIEB0eXBlZGVmIFEgVGhlIHF1ZXJ5IG9iamVjdCB0aGUgYWRhcHRlciB1c2VzXG4gKlxuICogQHBhcmFtIHtZfSBuYXRpdmUgdGhlIHVuZGVybHlpbmcgcGVyc2lzdGVuY2Ugb2JqZWN0XG4gKiBAcGFyYW0ge3N0cmluZ30gZmxhdm91ciB0aGUgdW5kZXIgd2l0Y2ggdGhlIHBlcnNpc3RlbmNlIGFkYXB0ZXIgc2hvdWxkIGJlIHN0b3JlZFxuICpcbiAqIEBjbGFzcyBBZGFwdGVyXG4gKiBAaW1wbGVtZW50cyBSYXdFeGVjdXRvclxuICogQGltcGxlbWVudHMgT2JzZXJ2YWJsZVxuICovXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgQWRhcHRlcjxcbiAgICBZLFxuICAgIFEsXG4gICAgRiBleHRlbmRzIFJlcG9zaXRvcnlGbGFncyxcbiAgICBDIGV4dGVuZHMgQ29udGV4dDxGPixcbiAgPlxuICBpbXBsZW1lbnRzIFJhd0V4ZWN1dG9yPFE+LCBDb250ZXh0dWFsPEYsIEM+LCBPYnNlcnZhYmxlLCBPYnNlcnZlciwgRXJyb3JQYXJzZXJcbntcbiAgcHJpdmF0ZSBzdGF0aWMgX2N1cnJlbnQ6IEFkYXB0ZXI8YW55LCBhbnksIGFueSwgYW55PjtcbiAgcHJpdmF0ZSBzdGF0aWMgX2NhY2hlOiBSZWNvcmQ8c3RyaW5nLCBBZGFwdGVyPGFueSwgYW55LCBhbnksIGFueT4+ID0ge307XG5cbiAgcHJpdmF0ZSBsb2dnZXIhOiBMb2dnZXI7XG5cbiAgcHJvdGVjdGVkIGRpc3BhdGNoPzogRGlzcGF0Y2g8WT47XG5cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IG9ic2VydmVySGFuZGxlcj86IE9ic2VydmVySGFuZGxlcjtcblxuICBwcm90ZWN0ZWQgZ2V0IGxvZygpIHtcbiAgICBpZiAoIXRoaXMubG9nZ2VyKSB0aGlzLmxvZ2dlciA9IExvZ2dpbmcuZm9yKHRoaXMgYXMgYW55KTtcbiAgICByZXR1cm4gdGhpcy5sb2dnZXI7XG4gIH1cblxuICBnZXQgbmF0aXZlKCkge1xuICAgIHJldHVybiB0aGlzLl9uYXRpdmU7XG4gIH1cblxuICBnZXQgYWxpYXMoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2FsaWFzIHx8IHRoaXMuZmxhdm91cjtcbiAgfVxuXG4gIHJlcG9zaXRvcnk8TSBleHRlbmRzIE1vZGVsPigpOiBDb25zdHJ1Y3RvcjxcbiAgICBSZXBvc2l0b3J5PE0sIFEsIEFkYXB0ZXI8WSwgUSwgRiwgQz4sIEYsIEM+XG4gID4ge1xuICAgIHJldHVybiBSZXBvc2l0b3J5O1xuICB9XG5cbiAgcHJvdGVjdGVkIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgX25hdGl2ZTogWSxcbiAgICByZWFkb25seSBmbGF2b3VyOiBzdHJpbmcsXG4gICAgcHJpdmF0ZSByZWFkb25seSBfYWxpYXM/OiBzdHJpbmdcbiAgKSB7XG4gICAgaWYgKHRoaXMuZmxhdm91ciBpbiBBZGFwdGVyLl9jYWNoZSlcbiAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFxuICAgICAgICBgJHt0aGlzLmFsaWFzfSBwZXJzaXN0ZW5jZSBhZGFwdGVyICR7dGhpcy5fYWxpYXMgPyBgKCR7dGhpcy5mbGF2b3VyfSkgYCA6IFwiXCJ9IGFscmVhZHkgcmVnaXN0ZXJlZGBcbiAgICAgICk7XG4gICAgQWRhcHRlci5fY2FjaGVbdGhpcy5hbGlhc10gPSB0aGlzO1xuICAgIHRoaXMubG9nLmluZm8oXG4gICAgICBgQ3JlYXRlZCAke3RoaXMuYWxpYXN9IHBlcnNpc3RlbmNlIGFkYXB0ZXIgJHt0aGlzLl9hbGlhcyA/IGAoJHt0aGlzLmZsYXZvdXJ9KSBgIDogXCJcIn0gcGVyc2lzdGVuY2UgYWRhcHRlcmBcbiAgICApO1xuICAgIGlmICghQWRhcHRlci5fY3VycmVudCkge1xuICAgICAgdGhpcy5sb2cudmVyYm9zZShgRGVmaW5lZCAke3RoaXMuYWxpYXN9IHBlcnNpc3RlbmNlIGFkYXB0ZXIgYXMgY3VycmVudGApO1xuICAgICAgQWRhcHRlci5fY3VycmVudCA9IHRoaXM7XG4gICAgfVxuICB9XG5cbiAgYWJzdHJhY3QgU3RhdGVtZW50PE0gZXh0ZW5kcyBNb2RlbD4oKTogU3RhdGVtZW50PFEsIE0sIGFueT47XG5cbiAgcHJvdGVjdGVkIERpc3BhdGNoKCk6IERpc3BhdGNoPFk+IHtcbiAgICByZXR1cm4gbmV3IERpc3BhdGNoKCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgT2JzZXJ2ZXJIYW5kbGVyKCkge1xuICAgIHJldHVybiBuZXcgT2JzZXJ2ZXJIYW5kbGVyKCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgaXNSZXNlcnZlZChhdHRyOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gIWF0dHI7XG4gIH1cblxuICBhYnN0cmFjdCBwYXJzZUVycm9yKGVycjogRXJyb3IpOiBCYXNlRXJyb3I7XG5cbiAgYWJzdHJhY3QgaW5pdGlhbGl6ZSguLi5hcmdzOiBhbnlbXSk6IFByb21pc2U8dm9pZD47XG5cbiAgYWJzdHJhY3QgU2VxdWVuY2Uob3B0aW9uczogU2VxdWVuY2VPcHRpb25zKTogUHJvbWlzZTxTZXF1ZW5jZT47XG5cbiAgcHJvdGVjdGVkIGZsYWdzPE0gZXh0ZW5kcyBNb2RlbD4oXG4gICAgb3BlcmF0aW9uOiBPcGVyYXRpb25LZXlzLFxuICAgIG1vZGVsOiBDb25zdHJ1Y3RvcjxNPixcbiAgICBmbGFnczogUGFydGlhbDxGPixcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gICAgLi4uYXJnczogYW55W11cbiAgKTogRiB7XG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIERlZmF1bHRSZXBvc2l0b3J5RmxhZ3MsIGZsYWdzLCB7XG4gICAgICBhZmZlY3RlZFRhYmxlczogUmVwb3NpdG9yeS50YWJsZShtb2RlbCksXG4gICAgICB3cml0ZU9wZXJhdGlvbjogb3BlcmF0aW9uICE9PSBPcGVyYXRpb25LZXlzLlJFQUQsXG4gICAgICB0aW1lc3RhbXA6IG5ldyBEYXRlKCksXG4gICAgICBvcGVyYXRpb246IG9wZXJhdGlvbixcbiAgICB9KSBhcyBGO1xuICB9XG5cbiAgcHJvdGVjdGVkIENvbnRleHQ6IENvbnN0cnVjdG9yPEM+ID0gQ29udGV4dDxGPiBhcyBhbnk7XG5cbiAgQGZpbmFsKClcbiAgYXN5bmMgY29udGV4dDxNIGV4dGVuZHMgTW9kZWw+KFxuICAgIG9wZXJhdGlvbjpcbiAgICAgIHwgT3BlcmF0aW9uS2V5cy5DUkVBVEVcbiAgICAgIHwgT3BlcmF0aW9uS2V5cy5SRUFEXG4gICAgICB8IE9wZXJhdGlvbktleXMuVVBEQVRFXG4gICAgICB8IE9wZXJhdGlvbktleXMuREVMRVRFLFxuICAgIG92ZXJyaWRlczogUGFydGlhbDxGPixcbiAgICBtb2RlbDogQ29uc3RydWN0b3I8TT4sXG4gICAgLi4uYXJnczogYW55W11cbiAgKTogUHJvbWlzZTxDPiB7XG4gICAgdGhpcy5sb2dcbiAgICAgIC5mb3IodGhpcy5jb250ZXh0KVxuICAgICAgLmRlYnVnKFxuICAgICAgICBgQ3JlYXRpbmcgbmV3IGNvbnRleHQgZm9yICR7b3BlcmF0aW9ufSBvcGVyYXRpb24gb24gJHttb2RlbC5uYW1lfSBtb2RlbCB3aXRoIGZsYWdzOiAke0pTT04uc3RyaW5naWZ5KG92ZXJyaWRlcyl9YFxuICAgICAgKTtcbiAgICByZXR1cm4gbmV3IHRoaXMuQ29udGV4dChcbiAgICAgIHRoaXMuZmxhZ3Mob3BlcmF0aW9uLCBtb2RlbCwgb3ZlcnJpZGVzLCAuLi5hcmdzKVxuICAgICkgYXMgdW5rbm93biBhcyBDO1xuICB9XG5cbiAgcHJlcGFyZTxNIGV4dGVuZHMgTW9kZWw+KFxuICAgIG1vZGVsOiBNLFxuICAgIHBrOiBrZXlvZiBNXG4gICk6IHtcbiAgICByZWNvcmQ6IFJlY29yZDxzdHJpbmcsIGFueT47XG4gICAgaWQ6IHN0cmluZztcbiAgICB0cmFuc2llbnQ/OiBSZWNvcmQ8c3RyaW5nLCBhbnk+O1xuICB9IHtcbiAgICBjb25zdCBsb2cgPSB0aGlzLmxvZy5mb3IodGhpcy5wcmVwYXJlKTtcbiAgICBsb2cuc2lsbHkoYFByZXBhcmluZyBtb2RlbCAke21vZGVsLmNvbnN0cnVjdG9yLm5hbWV9IGJlZm9yZSBwZXJzaXN0aW5nYCk7XG4gICAgY29uc3Qgc3BsaXQgPSBtb2RlbFRvVHJhbnNpZW50KG1vZGVsKTtcbiAgICBjb25zdCByZXN1bHQgPSBPYmplY3QuZW50cmllcyhzcGxpdC5tb2RlbCkucmVkdWNlKFxuICAgICAgKGFjY3VtOiBSZWNvcmQ8c3RyaW5nLCBhbnk+LCBba2V5LCB2YWxdKSA9PiB7XG4gICAgICAgIGlmICh0eXBlb2YgdmFsID09PSBcInVuZGVmaW5lZFwiKSByZXR1cm4gYWNjdW07XG4gICAgICAgIGNvbnN0IG1hcHBlZFByb3AgPSBSZXBvc2l0b3J5LmNvbHVtbihtb2RlbCwga2V5KTtcbiAgICAgICAgaWYgKHRoaXMuaXNSZXNlcnZlZChtYXBwZWRQcm9wKSlcbiAgICAgICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihgUHJvcGVydHkgbmFtZSAke21hcHBlZFByb3B9IGlzIHJlc2VydmVkYCk7XG4gICAgICAgIGFjY3VtW21hcHBlZFByb3BdID0gdmFsO1xuICAgICAgICByZXR1cm4gYWNjdW07XG4gICAgICB9LFxuICAgICAge31cbiAgICApO1xuICAgIGlmICgobW9kZWwgYXMgYW55KVtQZXJzaXN0ZW5jZUtleXMuTUVUQURBVEFdKSB7XG4gICAgICBsb2cuc2lsbHkoXG4gICAgICAgIGBQYXNzaW5nIGFsb25nIHBlcnNpc3RlbmNlIG1ldGFkYXRhIGZvciAkeyhtb2RlbCBhcyBhbnkpW1BlcnNpc3RlbmNlS2V5cy5NRVRBREFUQV19YFxuICAgICAgKTtcbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShyZXN1bHQsIFBlcnNpc3RlbmNlS2V5cy5NRVRBREFUQSwge1xuICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgd3JpdGFibGU6IGZhbHNlLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgIHZhbHVlOiAobW9kZWwgYXMgYW55KVtQZXJzaXN0ZW5jZUtleXMuTUVUQURBVEFdLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIHJlY29yZDogcmVzdWx0LFxuICAgICAgaWQ6IG1vZGVsW3BrXSBhcyBzdHJpbmcsXG4gICAgICB0cmFuc2llbnQ6IHNwbGl0LnRyYW5zaWVudCxcbiAgICB9O1xuICB9XG5cbiAgcmV2ZXJ0PE0gZXh0ZW5kcyBNb2RlbD4oXG4gICAgb2JqOiBSZWNvcmQ8c3RyaW5nLCBhbnk+LFxuICAgIGNsYXp6OiBzdHJpbmcgfCBDb25zdHJ1Y3RvcjxNPixcbiAgICBwazoga2V5b2YgTSxcbiAgICBpZDogc3RyaW5nIHwgbnVtYmVyIHwgYmlnaW50LFxuICAgIHRyYW5zaWVudD86IFJlY29yZDxzdHJpbmcsIGFueT5cbiAgKTogTSB7XG4gICAgY29uc3QgbG9nID0gdGhpcy5sb2cuZm9yKHRoaXMucmV2ZXJ0KTtcbiAgICBjb25zdCBvYjogUmVjb3JkPHN0cmluZywgYW55PiA9IHt9O1xuICAgIG9iW3BrIGFzIHN0cmluZ10gPSBpZDtcbiAgICBjb25zdCBtID0gKFxuICAgICAgdHlwZW9mIGNsYXp6ID09PSBcInN0cmluZ1wiID8gTW9kZWwuYnVpbGQob2IsIGNsYXp6KSA6IG5ldyBjbGF6eihvYilcbiAgICApIGFzIE07XG4gICAgbG9nLnNpbGx5KGBSZWJ1aWxkaW5nIG1vZGVsICR7bS5jb25zdHJ1Y3Rvci5uYW1lfSBpZCAke2lkfWApO1xuICAgIGNvbnN0IG1ldGFkYXRhID0gb2JqW1BlcnNpc3RlbmNlS2V5cy5NRVRBREFUQV07XG4gICAgY29uc3QgcmVzdWx0ID0gT2JqZWN0LmtleXMobSkucmVkdWNlKChhY2N1bTogTSwga2V5KSA9PiB7XG4gICAgICBpZiAoa2V5ID09PSBwaykgcmV0dXJuIGFjY3VtO1xuICAgICAgKGFjY3VtIGFzIFJlY29yZDxzdHJpbmcsIGFueT4pW2tleV0gPSBvYmpbUmVwb3NpdG9yeS5jb2x1bW4oYWNjdW0sIGtleSldO1xuICAgICAgcmV0dXJuIGFjY3VtO1xuICAgIH0sIG0pO1xuXG4gICAgaWYgKHRyYW5zaWVudCkge1xuICAgICAgbG9nLnZlcmJvc2UoXG4gICAgICAgIGByZS1hZGRpbmcgdHJhbnNpZW50IHByb3BlcnRpZXM6ICR7T2JqZWN0LmtleXModHJhbnNpZW50KS5qb2luKFwiLCBcIil9YFxuICAgICAgKTtcbiAgICAgIE9iamVjdC5lbnRyaWVzKHRyYW5zaWVudCkuZm9yRWFjaCgoW2tleSwgdmFsXSkgPT4ge1xuICAgICAgICBpZiAoa2V5IGluIHJlc3VsdClcbiAgICAgICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcbiAgICAgICAgICAgIGBUcmFuc2llbnQgcHJvcGVydHkgJHtrZXl9IGFscmVhZHkgZXhpc3RzIG9uIG1vZGVsICR7bS5jb25zdHJ1Y3Rvci5uYW1lfS4gc2hvdWxkIGJlIGltcG9zc2libGVgXG4gICAgICAgICAgKTtcbiAgICAgICAgcmVzdWx0W2tleSBhcyBrZXlvZiBNXSA9IHZhbDtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmIChtZXRhZGF0YSkge1xuICAgICAgbG9nLnNpbGx5KFxuICAgICAgICBgUGFzc2luZyBhbG9uZyAke3RoaXMuZmxhdm91cn0gcGVyc2lzdGVuY2UgbWV0YWRhdGEgZm9yICR7bS5jb25zdHJ1Y3Rvci5uYW1lfSBpZCAke2lkfTogJHttZXRhZGF0YX1gXG4gICAgICApO1xuICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHJlc3VsdCwgUGVyc2lzdGVuY2VLZXlzLk1FVEFEQVRBLCB7XG4gICAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgICBjb25maWd1cmFibGU6IGZhbHNlLFxuICAgICAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgICAgIHZhbHVlOiBtZXRhZGF0YSxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBhYnN0cmFjdCBjcmVhdGUoXG4gICAgdGFibGVOYW1lOiBzdHJpbmcsXG4gICAgaWQ6IHN0cmluZyB8IG51bWJlcixcbiAgICBtb2RlbDogUmVjb3JkPHN0cmluZywgYW55PixcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApOiBQcm9taXNlPFJlY29yZDxzdHJpbmcsIGFueT4+O1xuXG4gIGFzeW5jIGNyZWF0ZUFsbChcbiAgICB0YWJsZU5hbWU6IHN0cmluZyxcbiAgICBpZDogKHN0cmluZyB8IG51bWJlcilbXSxcbiAgICBtb2RlbDogUmVjb3JkPHN0cmluZywgYW55PltdLFxuICAgIC4uLmFyZ3M6IGFueVtdXG4gICk6IFByb21pc2U8UmVjb3JkPHN0cmluZywgYW55PltdPiB7XG4gICAgaWYgKGlkLmxlbmd0aCAhPT0gbW9kZWwubGVuZ3RoKVxuICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXCJJZHMgYW5kIG1vZGVscyBtdXN0IGhhdmUgdGhlIHNhbWUgbGVuZ3RoXCIpO1xuICAgIGNvbnN0IGxvZyA9IHRoaXMubG9nLmZvcih0aGlzLmNyZWF0ZUFsbCk7XG4gICAgbG9nLnZlcmJvc2UoYENyZWF0aW5nICR7aWQubGVuZ3RofSBlbnRyaWVzICR7dGFibGVOYW1lfSB0YWJsZWApO1xuICAgIGxvZy5kZWJ1ZyhgcGtzOiAke2lkfWApO1xuICAgIHJldHVybiBQcm9taXNlLmFsbChcbiAgICAgIGlkLm1hcCgoaSwgY291bnQpID0+IHRoaXMuY3JlYXRlKHRhYmxlTmFtZSwgaSwgbW9kZWxbY291bnRdLCAuLi5hcmdzKSlcbiAgICApO1xuICB9XG5cbiAgYWJzdHJhY3QgcmVhZChcbiAgICB0YWJsZU5hbWU6IHN0cmluZyxcbiAgICBpZDogc3RyaW5nIHwgbnVtYmVyIHwgYmlnaW50LFxuICAgIC4uLmFyZ3M6IGFueVtdXG4gICk6IFByb21pc2U8UmVjb3JkPHN0cmluZywgYW55Pj47XG5cbiAgYXN5bmMgcmVhZEFsbChcbiAgICB0YWJsZU5hbWU6IHN0cmluZyxcbiAgICBpZDogKHN0cmluZyB8IG51bWJlciB8IGJpZ2ludClbXSxcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApOiBQcm9taXNlPFJlY29yZDxzdHJpbmcsIGFueT5bXT4ge1xuICAgIGNvbnN0IGxvZyA9IHRoaXMubG9nLmZvcih0aGlzLnJlYWRBbGwpO1xuICAgIGxvZy52ZXJib3NlKGBSZWFkaW5nICR7aWQubGVuZ3RofSBlbnRyaWVzICR7dGFibGVOYW1lfSB0YWJsZWApO1xuICAgIGxvZy5kZWJ1ZyhgcGtzOiAke2lkfWApO1xuICAgIHJldHVybiBQcm9taXNlLmFsbChpZC5tYXAoKGkpID0+IHRoaXMucmVhZCh0YWJsZU5hbWUsIGksIC4uLmFyZ3MpKSk7XG4gIH1cblxuICBhYnN0cmFjdCB1cGRhdGUoXG4gICAgdGFibGVOYW1lOiBzdHJpbmcsXG4gICAgaWQ6IHN0cmluZyB8IG51bWJlcixcbiAgICBtb2RlbDogUmVjb3JkPHN0cmluZywgYW55PixcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApOiBQcm9taXNlPFJlY29yZDxzdHJpbmcsIGFueT4+O1xuXG4gIGFzeW5jIHVwZGF0ZUFsbChcbiAgICB0YWJsZU5hbWU6IHN0cmluZyxcbiAgICBpZDogc3RyaW5nW10gfCBudW1iZXJbXSxcbiAgICBtb2RlbDogUmVjb3JkPHN0cmluZywgYW55PltdLFxuICAgIC4uLmFyZ3M6IGFueVtdXG4gICk6IFByb21pc2U8UmVjb3JkPHN0cmluZywgYW55PltdPiB7XG4gICAgaWYgKGlkLmxlbmd0aCAhPT0gbW9kZWwubGVuZ3RoKVxuICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXCJJZHMgYW5kIG1vZGVscyBtdXN0IGhhdmUgdGhlIHNhbWUgbGVuZ3RoXCIpO1xuICAgIGNvbnN0IGxvZyA9IHRoaXMubG9nLmZvcih0aGlzLnVwZGF0ZUFsbCk7XG4gICAgbG9nLnZlcmJvc2UoYFVwZGF0aW5nICR7aWQubGVuZ3RofSBlbnRyaWVzICR7dGFibGVOYW1lfSB0YWJsZWApO1xuICAgIGxvZy5kZWJ1ZyhgcGtzOiAke2lkfWApO1xuICAgIHJldHVybiBQcm9taXNlLmFsbChcbiAgICAgIGlkLm1hcCgoaSwgY291bnQpID0+IHRoaXMudXBkYXRlKHRhYmxlTmFtZSwgaSwgbW9kZWxbY291bnRdLCAuLi5hcmdzKSlcbiAgICApO1xuICB9XG5cbiAgYWJzdHJhY3QgZGVsZXRlKFxuICAgIHRhYmxlTmFtZTogc3RyaW5nLFxuICAgIGlkOiBzdHJpbmcgfCBudW1iZXIgfCBiaWdpbnQsXG4gICAgLi4uYXJnczogYW55W11cbiAgKTogUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+PjtcblxuICBhc3luYyBkZWxldGVBbGwoXG4gICAgdGFibGVOYW1lOiBzdHJpbmcsXG4gICAgaWQ6IChzdHJpbmcgfCBudW1iZXIgfCBiaWdpbnQpW10sXG4gICAgLi4uYXJnczogYW55W11cbiAgKTogUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+W10+IHtcbiAgICBjb25zdCBsb2cgPSB0aGlzLmxvZy5mb3IodGhpcy5jcmVhdGVBbGwpO1xuICAgIGxvZy52ZXJib3NlKGBEZWxldGluZyAke2lkLmxlbmd0aH0gZW50cmllcyAke3RhYmxlTmFtZX0gdGFibGVgKTtcbiAgICBsb2cuZGVidWcoYHBrczogJHtpZH1gKTtcbiAgICByZXR1cm4gUHJvbWlzZS5hbGwoaWQubWFwKChpKSA9PiB0aGlzLmRlbGV0ZSh0YWJsZU5hbWUsIGksIC4uLmFyZ3MpKSk7XG4gIH1cblxuICBhYnN0cmFjdCByYXc8Uj4ocmF3SW5wdXQ6IFEsIC4uLmFyZ3M6IGFueVtdKTogUHJvbWlzZTxSPjtcblxuICAvKipcbiAgICpcbiAgICogQHNlZSB7T2JzZXJ2YWJsZSNvYnNlcnZlfVxuICAgKi9cbiAgQGZpbmFsKClcbiAgb2JzZXJ2ZShvYnNlcnZlcjogT2JzZXJ2ZXIsIGZpbHRlcj86IE9ic2VydmVyRmlsdGVyKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLm9ic2VydmVySGFuZGxlcilcbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCBcIm9ic2VydmVySGFuZGxlclwiLCB7XG4gICAgICAgIHZhbHVlOiB0aGlzLk9ic2VydmVySGFuZGxlcigpLFxuICAgICAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgICB9KTtcbiAgICB0aGlzLm9ic2VydmVySGFuZGxlciEub2JzZXJ2ZShvYnNlcnZlciwgZmlsdGVyKTtcbiAgICB0aGlzLmxvZ1xuICAgICAgLmZvcih0aGlzLm9ic2VydmUpXG4gICAgICAudmVyYm9zZShgUmVnaXN0ZXJpbmcgbmV3IG9ic2VydmVyICR7b2JzZXJ2ZXIudG9TdHJpbmcoKX1gKTtcbiAgICBpZiAoIXRoaXMuZGlzcGF0Y2gpIHtcbiAgICAgIHRoaXMubG9nLmZvcih0aGlzLm9ic2VydmUpLmluZm8oYENyZWF0aW5nIGRpc3BhdGNoIGZvciAke3RoaXMuYWxpYXN9YCk7XG4gICAgICB0aGlzLmRpc3BhdGNoID0gdGhpcy5EaXNwYXRjaCgpO1xuICAgICAgdGhpcy5kaXNwYXRjaC5vYnNlcnZlKHRoaXMpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBVbnJlZ2lzdGVycyBhbiB7QGxpbmsgT2JzZXJ2ZXJ9XG4gICAqIEBwYXJhbSB7T2JzZXJ2ZXJ9IG9ic2VydmVyXG4gICAqXG4gICAqIEBzZWUge09ic2VydmFibGUjdW5PYnNlcnZlfVxuICAgKi9cbiAgQGZpbmFsKClcbiAgdW5PYnNlcnZlKG9ic2VydmVyOiBPYnNlcnZlcik6IHZvaWQge1xuICAgIGlmICghdGhpcy5vYnNlcnZlckhhbmRsZXIpXG4gICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcbiAgICAgICAgXCJPYnNlcnZlckhhbmRsZXIgbm90IGluaXRpYWxpemVkLiBEaWQgeW91IHJlZ2lzdGVyIGFueSBvYnNlcnZhYmxlcz9cIlxuICAgICAgKTtcbiAgICB0aGlzLm9ic2VydmVySGFuZGxlci51bk9ic2VydmUob2JzZXJ2ZXIpO1xuICAgIHRoaXMubG9nXG4gICAgICAuZm9yKHRoaXMudW5PYnNlcnZlKVxuICAgICAgLnZlcmJvc2UoYE9ic2VydmVyICR7b2JzZXJ2ZXIudG9TdHJpbmcoKX0gcmVtb3ZlZGApO1xuICB9XG5cbiAgYXN5bmMgdXBkYXRlT2JzZXJ2ZXJzKFxuICAgIHRhYmxlOiBzdHJpbmcsXG4gICAgZXZlbnQ6IE9wZXJhdGlvbktleXMgfCBCdWxrQ3J1ZE9wZXJhdGlvbktleXMgfCBzdHJpbmcsXG4gICAgaWQ6IEV2ZW50SWRzLFxuICAgIC4uLmFyZ3M6IGFueVtdXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICghdGhpcy5vYnNlcnZlckhhbmRsZXIpXG4gICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcbiAgICAgICAgXCJPYnNlcnZlckhhbmRsZXIgbm90IGluaXRpYWxpemVkLiBEaWQgeW91IHJlZ2lzdGVyIGFueSBvYnNlcnZhYmxlcz9cIlxuICAgICAgKTtcbiAgICBjb25zdCBsb2cgPSB0aGlzLmxvZy5mb3IodGhpcy51cGRhdGVPYnNlcnZlcnMpO1xuICAgIGxvZy52ZXJib3NlKFxuICAgICAgYFVwZGF0aW5nICR7dGhpcy5vYnNlcnZlckhhbmRsZXIuY291bnQoKX0gb2JzZXJ2ZXJzIGZvciBhZGFwdGVyICR7dGhpcy5hbGlhc31gXG4gICAgKTtcbiAgICBhd2FpdCB0aGlzLm9ic2VydmVySGFuZGxlci51cGRhdGVPYnNlcnZlcnMoXG4gICAgICB0aGlzLmxvZyxcbiAgICAgIHRhYmxlLFxuICAgICAgZXZlbnQsXG4gICAgICBpZCxcbiAgICAgIC4uLmFyZ3NcbiAgICApO1xuICB9XG5cbiAgYXN5bmMgcmVmcmVzaChcbiAgICB0YWJsZTogc3RyaW5nLFxuICAgIGV2ZW50OiBPcGVyYXRpb25LZXlzIHwgQnVsa0NydWRPcGVyYXRpb25LZXlzIHwgc3RyaW5nLFxuICAgIGlkOiBFdmVudElkcyxcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApIHtcbiAgICByZXR1cm4gdGhpcy51cGRhdGVPYnNlcnZlcnModGFibGUsIGV2ZW50LCBpZCwgLi4uYXJncyk7XG4gIH1cblxuICB0b1N0cmluZygpIHtcbiAgICByZXR1cm4gYCR7dGhpcy5mbGF2b3VyfSBwZXJzaXN0ZW5jZSBBZGFwdGVyYDtcbiAgfVxuXG4gIHN0YXRpYyBmbGF2b3VyT2Y8TSBleHRlbmRzIE1vZGVsPihtb2RlbDogQ29uc3RydWN0b3I8TT4pOiBzdHJpbmcge1xuICAgIHJldHVybiAoXG4gICAgICBSZWZsZWN0LmdldE1ldGFkYXRhKHRoaXMua2V5KFBlcnNpc3RlbmNlS2V5cy5BREFQVEVSKSwgbW9kZWwpIHx8XG4gICAgICB0aGlzLmN1cnJlbnQuZmxhdm91clxuICAgICk7XG4gIH1cblxuICBzdGF0aWMgZ2V0IGN1cnJlbnQoKSB7XG4gICAgaWYgKCFBZGFwdGVyLl9jdXJyZW50KVxuICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXG4gICAgICAgIGBObyBwZXJzaXN0ZW5jZSBmbGF2b3VyIHNldC4gUGxlYXNlIGluaXRpYWxpemUgeW91ciBhZGFwdGVyYFxuICAgICAgKTtcbiAgICByZXR1cm4gQWRhcHRlci5fY3VycmVudDtcbiAgfVxuXG4gIHN0YXRpYyBnZXQ8WSwgUSwgQyBleHRlbmRzIENvbnRleHQ8Rj4sIEYgZXh0ZW5kcyBSZXBvc2l0b3J5RmxhZ3M+KFxuICAgIGZsYXZvdXI6IGFueVxuICApOiBBZGFwdGVyPFksIFEsIEYsIEM+IHwgdW5kZWZpbmVkIHtcbiAgICBpZiAoZmxhdm91ciBpbiB0aGlzLl9jYWNoZSkgcmV0dXJuIHRoaXMuX2NhY2hlW2ZsYXZvdXJdO1xuICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKGBObyBBZGFwdGVyIHJlZ2lzdGVyZWQgdW5kZXIgJHtmbGF2b3VyfS5gKTtcbiAgfVxuXG4gIHN0YXRpYyBzZXRDdXJyZW50KGZsYXZvdXI6IHN0cmluZykge1xuICAgIGNvbnN0IGFkYXB0ZXIgPSBBZGFwdGVyLmdldChmbGF2b3VyKTtcbiAgICBpZiAoIWFkYXB0ZXIpXG4gICAgICB0aHJvdyBuZXcgTm90Rm91bmRFcnJvcihgTm8gcGVyc2lzdGVuY2UgZmxhdm91ciAke2ZsYXZvdXJ9IHJlZ2lzdGVyZWRgKTtcbiAgICB0aGlzLl9jdXJyZW50ID0gYWRhcHRlcjtcbiAgfVxuXG4gIHN0YXRpYyBrZXkoa2V5OiBzdHJpbmcpIHtcbiAgICByZXR1cm4gUmVwb3NpdG9yeS5rZXkoa2V5KTtcbiAgfVxuXG4gIHN0YXRpYyBtb2RlbHM8TSBleHRlbmRzIE1vZGVsPihmbGF2b3VyOiBzdHJpbmcpIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVnaXN0cnkgPSAoTW9kZWwgYXMgYW55KS5nZXRSZWdpc3RyeSgpIGFzIE1vZGVsUmVnaXN0cnk8YW55PjtcbiAgICAgIGNvbnN0IGNhY2hlID0gKFxuICAgICAgICByZWdpc3RyeSBhcyB1bmtub3duIGFzIHsgY2FjaGU6IFJlY29yZDxzdHJpbmcsIE1vZGVsQ29uc3RydWN0b3I8YW55Pj4gfVxuICAgICAgKS5jYWNoZTtcbiAgICAgIGNvbnN0IG1hbmFnZWRNb2RlbHM6IE1vZGVsQ29uc3RydWN0b3I8YW55PltdID0gT2JqZWN0LnZhbHVlcyhjYWNoZSlcbiAgICAgICAgLm1hcCgobTogTW9kZWxDb25zdHJ1Y3RvcjxNPikgPT4ge1xuICAgICAgICAgIGxldCBmID0gUmVmbGVjdC5nZXRNZXRhZGF0YShcbiAgICAgICAgICAgIEFkYXB0ZXIua2V5KFBlcnNpc3RlbmNlS2V5cy5BREFQVEVSKSxcbiAgICAgICAgICAgIG0gYXMgTW9kZWxDb25zdHJ1Y3Rvcjxhbnk+XG4gICAgICAgICAgKTtcbiAgICAgICAgICBpZiAoZiAmJiBmID09PSBmbGF2b3VyKSByZXR1cm4gbTtcbiAgICAgICAgICBpZiAoIWYpIHtcbiAgICAgICAgICAgIGNvbnN0IHJlcG8gPSBSZWZsZWN0LmdldE1ldGFkYXRhKFxuICAgICAgICAgICAgICBSZXBvc2l0b3J5LmtleShEQktleXMuUkVQT1NJVE9SWSksXG4gICAgICAgICAgICAgIG0gYXMgTW9kZWxDb25zdHJ1Y3Rvcjxhbnk+XG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgaWYgKCFyZXBvKSByZXR1cm47XG4gICAgICAgICAgICBjb25zdCByZXBvc2l0b3J5ID0gUmVwb3NpdG9yeS5mb3JNb2RlbChtKTtcblxuICAgICAgICAgICAgZiA9IFJlZmxlY3QuZ2V0TWV0YWRhdGEoXG4gICAgICAgICAgICAgIEFkYXB0ZXIua2V5KFBlcnNpc3RlbmNlS2V5cy5BREFQVEVSKSxcbiAgICAgICAgICAgICAgcmVwb3NpdG9yeVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHJldHVybiBmO1xuICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICAgICAgLmZpbHRlcigobSkgPT4gISFtKTtcbiAgICAgIHJldHVybiBtYW5hZ2VkTW9kZWxzO1xuICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoZSk7XG4gICAgfVxuICB9XG59XG4iLCJpbXBvcnQgeyBDb25zdHJ1Y3RvciwgTW9kZWwgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBBZGFwdGVyIH0gZnJvbSBcIi4uL3BlcnNpc3RlbmNlL0FkYXB0ZXJcIjtcbmltcG9ydCB7IFBlcnNpc3RlbmNlS2V5cyB9IGZyb20gXCIuLi9wZXJzaXN0ZW5jZS9jb25zdGFudHNcIjtcblxuZXhwb3J0IGZ1bmN0aW9uIGdldFRhYmxlTmFtZTxNIGV4dGVuZHMgTW9kZWw+KFxuICBtb2RlbDogTSB8IENvbnN0cnVjdG9yPE0+XG4pOiBzdHJpbmcge1xuICBjb25zdCBvYmogPSBtb2RlbCBpbnN0YW5jZW9mIE1vZGVsID8gbW9kZWwuY29uc3RydWN0b3IgOiBtb2RlbDtcblxuICBjb25zdCBtZXRhZGF0YSA9IFJlZmxlY3QuZ2V0T3duTWV0YWRhdGEoXG4gICAgQWRhcHRlci5rZXkoUGVyc2lzdGVuY2VLZXlzLlRBQkxFKSxcbiAgICBvYmpcbiAgKTtcbiAgaWYgKG1ldGFkYXRhKSB7XG4gICAgcmV0dXJuIG1ldGFkYXRhO1xuICB9XG4gIGlmIChtb2RlbCBpbnN0YW5jZW9mIE1vZGVsKSB7XG4gICAgcmV0dXJuIG1vZGVsLmNvbnN0cnVjdG9yLm5hbWU7XG4gIH1cbiAgcmV0dXJuIG1vZGVsLm5hbWU7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzZXF1ZW5jZU5hbWVGb3JNb2RlbDxNIGV4dGVuZHMgTW9kZWw+KFxuICBtb2RlbDogTSB8IENvbnN0cnVjdG9yPE0+LFxuICAuLi5hcmdzOiBzdHJpbmdbXVxuKSB7XG4gIHJldHVybiBbZ2V0VGFibGVOYW1lKG1vZGVsKSwgLi4uYXJnc10uam9pbihcIl9cIik7XG59XG4iLCJpbXBvcnQgeyBDb25zdHJ1Y3RvciwgTW9kZWwgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBzZXF1ZW5jZU5hbWVGb3JNb2RlbCB9IGZyb20gXCIuLi9pZGVudGl0eS91dGlsc1wiO1xuaW1wb3J0IHsgU2VxdWVuY2VPcHRpb25zIH0gZnJvbSBcIi4uL2ludGVyZmFjZXMvU2VxdWVuY2VPcHRpb25zXCI7XG5pbXBvcnQgeyBJbnRlcm5hbEVycm9yIH0gZnJvbSBcIkBkZWNhZi10cy9kYi1kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBMb2dnZXIsIExvZ2dpbmcgfSBmcm9tIFwiQGRlY2FmLXRzL2xvZ2dpbmdcIjtcblxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIFNlcXVlbmNlIHtcbiAgcHJpdmF0ZSBsb2dnZXIhOiBMb2dnZXI7XG5cbiAgcHJvdGVjdGVkIGdldCBsb2coKSB7XG4gICAgaWYgKCF0aGlzLmxvZ2dlcikgdGhpcy5sb2dnZXIgPSBMb2dnaW5nLmZvcih0aGlzIGFzIGFueSk7XG4gICAgcmV0dXJuIHRoaXMubG9nZ2VyO1xuICB9XG5cbiAgcHJvdGVjdGVkIGNvbnN0cnVjdG9yKHByb3RlY3RlZCByZWFkb25seSBvcHRpb25zOiBTZXF1ZW5jZU9wdGlvbnMpIHt9XG5cbiAgYWJzdHJhY3QgbmV4dCgpOiBQcm9taXNlPHN0cmluZyB8IG51bWJlciB8IGJpZ2ludD47XG4gIGFic3RyYWN0IGN1cnJlbnQoKTogUHJvbWlzZTxzdHJpbmcgfCBudW1iZXIgfCBiaWdpbnQ+O1xuICBhYnN0cmFjdCByYW5nZShjb3VudDogbnVtYmVyKTogUHJvbWlzZTwobnVtYmVyIHwgc3RyaW5nIHwgYmlnaW50KVtdPjtcblxuICBzdGF0aWMgcGs8TSBleHRlbmRzIE1vZGVsPihtb2RlbDogTSB8IENvbnN0cnVjdG9yPE0+KSB7XG4gICAgcmV0dXJuIHNlcXVlbmNlTmFtZUZvck1vZGVsKG1vZGVsLCBcInBrXCIpO1xuICB9XG5cbiAgc3RhdGljIHBhcnNlVmFsdWUoXG4gICAgdHlwZTogXCJOdW1iZXJcIiB8IFwiQmlnSW50XCIgfCB1bmRlZmluZWQsXG4gICAgdmFsdWU6IHN0cmluZyB8IG51bWJlciB8IGJpZ2ludFxuICApOiBzdHJpbmcgfCBudW1iZXIgfCBiaWdpbnQge1xuICAgIHN3aXRjaCAodHlwZSkge1xuICAgICAgY2FzZSBcIk51bWJlclwiOlxuICAgICAgICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiXG4gICAgICAgICAgPyBwYXJzZUludCh2YWx1ZSlcbiAgICAgICAgICA6IHR5cGVvZiB2YWx1ZSA9PT0gXCJudW1iZXJcIlxuICAgICAgICAgICAgPyB2YWx1ZVxuICAgICAgICAgICAgOiBCaWdJbnQodmFsdWUpO1xuICAgICAgY2FzZSBcIkJpZ0ludFwiOlxuICAgICAgICByZXR1cm4gQmlnSW50KHZhbHVlKTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFwiU2hvdWxkIG5ldmVyIGhhcHBlblwiKTtcbiAgICB9XG4gIH1cbn1cbiIsImltcG9ydCB7IGFwcGx5LCBtZXRhZGF0YSB9IGZyb20gXCJAZGVjYWYtdHMvcmVmbGVjdGlvblwiO1xuaW1wb3J0IHsgUGVyc2lzdGVuY2VLZXlzIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBBZGFwdGVyIH0gZnJvbSBcIi4vQWRhcHRlclwiO1xuXG5leHBvcnQgZnVuY3Rpb24gdXNlcyhmbGF2b3VyOiBzdHJpbmcpIHtcbiAgcmV0dXJuIGFwcGx5KG1ldGFkYXRhKEFkYXB0ZXIua2V5KFBlcnNpc3RlbmNlS2V5cy5BREFQVEVSKSwgZmxhdm91cikpO1xufVxuIiwiaW1wb3J0IHtcbiAgQnVsa0NydWRPcGVyYXRpb25LZXlzLFxuICBDb250ZXh0LFxuICBEQktleXMsXG4gIGVuZm9yY2VEQkRlY29yYXRvcnMsXG4gIGZpbmRQcmltYXJ5S2V5LFxuICBJbnRlcm5hbEVycm9yLFxuICBJUmVwb3NpdG9yeSxcbiAgT3BlcmF0aW9uS2V5cyxcbiAgUmVwb3NpdG9yeSBhcyBSZXAsXG4gIFJlcG9zaXRvcnlGbGFncyxcbiAgVmFsaWRhdGlvbkVycm9yLFxuICB3cmFwTWV0aG9kV2l0aENvbnRleHQsXG59IGZyb20gXCJAZGVjYWYtdHMvZGItZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZSB9IGZyb20gXCIuLi9pbnRlcmZhY2VzL09ic2VydmFibGVcIjtcbmltcG9ydCB7IHR5cGUgT2JzZXJ2ZXIgfSBmcm9tIFwiLi4vaW50ZXJmYWNlcy9PYnNlcnZlclwiO1xuaW1wb3J0IHsgQWRhcHRlciB9IGZyb20gXCIuLi9wZXJzaXN0ZW5jZS9BZGFwdGVyXCI7XG5pbXBvcnQgeyBDb25zdHJ1Y3RvciwgTW9kZWwgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBQZXJzaXN0ZW5jZUtleXMgfSBmcm9tIFwiLi4vcGVyc2lzdGVuY2UvY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBPcmRlckRpcmVjdGlvbiB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgU2VxdWVuY2VPcHRpb25zIH0gZnJvbSBcIi4uL2ludGVyZmFjZXMvU2VxdWVuY2VPcHRpb25zXCI7XG5pbXBvcnQgeyBRdWVyaWFibGUgfSBmcm9tIFwiLi4vaW50ZXJmYWNlcy9RdWVyaWFibGVcIjtcbmltcG9ydCB7IFJlZmxlY3Rpb24gfSBmcm9tIFwiQGRlY2FmLXRzL3JlZmxlY3Rpb25cIjtcbmltcG9ydCB7IEluZGV4TWV0YWRhdGEgfSBmcm9tIFwiLi90eXBlc1wiO1xuaW1wb3J0IHsgU2VxdWVuY2UgfSBmcm9tIFwiLi4vcGVyc2lzdGVuY2UvU2VxdWVuY2VcIjtcbmltcG9ydCB7IENvbmRpdGlvbiB9IGZyb20gXCIuLi9xdWVyeS9Db25kaXRpb25cIjtcbmltcG9ydCB7IFdoZXJlT3B0aW9uIH0gZnJvbSBcIi4uL3F1ZXJ5L29wdGlvbnNcIjtcbmltcG9ydCB7IE9yZGVyQnlTZWxlY3RvciwgU2VsZWN0U2VsZWN0b3IgfSBmcm9tIFwiLi4vcXVlcnkvc2VsZWN0b3JzXCI7XG5pbXBvcnQgeyBnZXRUYWJsZU5hbWUgfSBmcm9tIFwiLi4vaWRlbnRpdHkvdXRpbHNcIjtcbmltcG9ydCB7IHVzZXMgfSBmcm9tIFwiLi4vcGVyc2lzdGVuY2UvZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHsgTG9nZ2VyLCBMb2dnaW5nIH0gZnJvbSBcIkBkZWNhZi10cy9sb2dnaW5nXCI7XG5pbXBvcnQgeyBPYnNlcnZlckhhbmRsZXIgfSBmcm9tIFwiLi4vcGVyc2lzdGVuY2UvT2JzZXJ2ZXJIYW5kbGVyXCI7XG5pbXBvcnQgeyBmaW5hbCB9IGZyb20gXCIuLi91dGlsc1wiO1xuaW1wb3J0IHR5cGUgeyBFdmVudElkcywgT2JzZXJ2ZXJGaWx0ZXIgfSBmcm9tIFwiLi4vcGVyc2lzdGVuY2VcIjtcblxuZXhwb3J0IHR5cGUgUmVwbzxcbiAgTSBleHRlbmRzIE1vZGVsLFxuICBGIGV4dGVuZHMgUmVwb3NpdG9yeUZsYWdzID0gYW55LFxuICBDIGV4dGVuZHMgQ29udGV4dDxGPiA9IGFueSxcbiAgUSA9IGFueSxcbiAgQSBleHRlbmRzIEFkYXB0ZXI8YW55LCBRLCBGLCBDPiA9IGFueSxcbj4gPSBSZXBvc2l0b3J5PE0sIFEsIEEsIEYsIEM+O1xuXG5leHBvcnQgY2xhc3MgUmVwb3NpdG9yeTxcbiAgICBNIGV4dGVuZHMgTW9kZWwsXG4gICAgUSxcbiAgICBBIGV4dGVuZHMgQWRhcHRlcjxhbnksIFEsIEYsIEM+LFxuICAgIEYgZXh0ZW5kcyBSZXBvc2l0b3J5RmxhZ3MgPSBSZXBvc2l0b3J5RmxhZ3MsXG4gICAgQyBleHRlbmRzIENvbnRleHQ8Rj4gPSBDb250ZXh0PEY+LFxuICA+XG4gIGV4dGVuZHMgUmVwPE0sIEYsIEM+XG4gIGltcGxlbWVudHMgT2JzZXJ2YWJsZSwgT2JzZXJ2ZXIsIFF1ZXJpYWJsZTxNPiwgSVJlcG9zaXRvcnk8TSwgRiwgQz5cbntcbiAgcHJpdmF0ZSBzdGF0aWMgX2NhY2hlOiBSZWNvcmQ8XG4gICAgc3RyaW5nLFxuICAgIENvbnN0cnVjdG9yPFJlcG88TW9kZWw+PiB8IFJlcG88TW9kZWw+XG4gID4gPSB7fTtcblxuICBwcm90ZWN0ZWQgb2JzZXJ2ZXJzOiBPYnNlcnZlcltdID0gW107XG5cbiAgcHJvdGVjdGVkIG9ic2VydmVySGFuZGxlcj86IE9ic2VydmVySGFuZGxlcjtcblxuICBwcml2YXRlIHJlYWRvbmx5IF9hZGFwdGVyITogQTtcbiAgcHJpdmF0ZSBfdGFibGVOYW1lITogc3RyaW5nO1xuICBwcml2YXRlIF9vdmVycmlkZXM/OiBQYXJ0aWFsPEY+O1xuXG4gIHByaXZhdGUgbG9nZ2VyITogTG9nZ2VyO1xuXG4gIGdldCBsb2coKSB7XG4gICAgaWYgKCF0aGlzLmxvZ2dlcikgdGhpcy5sb2dnZXIgPSBMb2dnaW5nLmZvcih0aGlzIGFzIGFueSk7XG4gICAgcmV0dXJuIHRoaXMubG9nZ2VyO1xuICB9XG5cbiAgcHJvdGVjdGVkIGdldCBhZGFwdGVyKCk6IEEge1xuICAgIGlmICghdGhpcy5fYWRhcHRlcilcbiAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFxuICAgICAgICBgTm8gYWRhcHRlciBmb3VuZCBmb3IgdGhpcyByZXBvc2l0b3J5LiBkaWQgeW91IHVzZSB0aGUgQHVzZXMgZGVjb3JhdG9yIG9yIHBhc3MgaXQgaW4gdGhlIGNvbnN0cnVjdG9yP2BcbiAgICAgICk7XG4gICAgcmV0dXJuIHRoaXMuX2FkYXB0ZXI7XG4gIH1cblxuICBwcm90ZWN0ZWQgZ2V0IHRhYmxlTmFtZSgpIHtcbiAgICBpZiAoIXRoaXMuX3RhYmxlTmFtZSkgdGhpcy5fdGFibGVOYW1lID0gUmVwb3NpdG9yeS50YWJsZSh0aGlzLmNsYXNzKTtcbiAgICByZXR1cm4gdGhpcy5fdGFibGVOYW1lO1xuICB9XG5cbiAgcHJvdGVjdGVkIG92ZXJyaWRlIGdldCBwa1Byb3BzKCk6IFNlcXVlbmNlT3B0aW9ucyB7XG4gICAgcmV0dXJuIHN1cGVyLnBrUHJvcHM7XG4gIH1cblxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gIGNvbnN0cnVjdG9yKGFkYXB0ZXI/OiBBLCBjbGF6ej86IENvbnN0cnVjdG9yPE0+LCAuLi5hcmdzOiBhbnlbXSkge1xuICAgIHN1cGVyKGNsYXp6KTtcbiAgICBpZiAoYWRhcHRlcikgdGhpcy5fYWRhcHRlciA9IGFkYXB0ZXI7XG4gICAgaWYgKGNsYXp6KSB7XG4gICAgICBSZXBvc2l0b3J5LnJlZ2lzdGVyKGNsYXp6LCB0aGlzKTtcbiAgICAgIGlmIChhZGFwdGVyKSB7XG4gICAgICAgIGNvbnN0IGZsYXZvdXIgPSBSZWZsZWN0LmdldE1ldGFkYXRhKFxuICAgICAgICAgIEFkYXB0ZXIua2V5KFBlcnNpc3RlbmNlS2V5cy5BREFQVEVSKSxcbiAgICAgICAgICBjbGF6elxuICAgICAgICApO1xuICAgICAgICBpZiAoZmxhdm91ciAmJiBmbGF2b3VyICE9PSBhZGFwdGVyLmZsYXZvdXIpXG4gICAgICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXCJJbmNvbXBhdGlibGUgZmxhdm91cnNcIik7XG4gICAgICAgIHVzZXMoYWRhcHRlci5mbGF2b3VyKShjbGF6eik7XG4gICAgICB9XG4gICAgfVxuICAgIFt0aGlzLmNyZWF0ZUFsbCwgdGhpcy5yZWFkQWxsLCB0aGlzLnVwZGF0ZUFsbCwgdGhpcy5kZWxldGVBbGxdLmZvckVhY2goXG4gICAgICAobSkgPT4ge1xuICAgICAgICBjb25zdCBuYW1lID0gbS5uYW1lO1xuICAgICAgICB3cmFwTWV0aG9kV2l0aENvbnRleHQoXG4gICAgICAgICAgdGhpcyxcbiAgICAgICAgICAodGhpcyBhcyBhbnkpW25hbWUgKyBcIlByZWZpeFwiXSxcbiAgICAgICAgICBtLFxuICAgICAgICAgICh0aGlzIGFzIGFueSlbbmFtZSArIFwiU3VmZml4XCJdXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgKTtcbiAgfVxuXG4gIG92ZXJyaWRlKGZsYWdzOiBQYXJ0aWFsPEY+KSB7XG4gICAgdGhpcy5sb2dcbiAgICAgIC5mb3IodGhpcy5vdmVycmlkZSlcbiAgICAgIC5kZWJ1ZyhgT3ZlcnJpZGluZyByZXBvc2l0b3J5IGZsYWdzIHdpdGggJHtKU09OLnN0cmluZ2lmeShmbGFncyl9YCk7XG4gICAgcmV0dXJuIG5ldyBQcm94eSh0aGlzLCB7XG4gICAgICBnZXQ6ICh0YXJnZXQ6IHR5cGVvZiB0aGlzLCBwOiBzdHJpbmcgfCBzeW1ib2wsIHJlY2VpdmVyOiBhbnkpID0+IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gUmVmbGVjdC5nZXQodGFyZ2V0LCBwLCByZWNlaXZlcik7XG4gICAgICAgIGlmIChwICE9PSBcIl9vdmVycmlkZXNcIikgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIHJlc3VsdCwgZmxhZ3MpO1xuICAgICAgfSxcbiAgICB9KTtcbiAgfVxuXG4gIHByb3RlY3RlZCBPYnNlcnZlckhhbmRsZXIoKSB7XG4gICAgcmV0dXJuIG5ldyBPYnNlcnZlckhhbmRsZXIoKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBvdmVycmlkZSBhc3luYyBjcmVhdGVQcmVmaXgoXG4gICAgbW9kZWw6IE0sXG4gICAgLi4uYXJnczogYW55W11cbiAgKTogUHJvbWlzZTxbTSwgLi4uYW55W11dPiB7XG4gICAgY29uc3QgY29udGV4dEFyZ3MgPSBhd2FpdCBDb250ZXh0LmFyZ3M8TSwgQywgRj4oXG4gICAgICBPcGVyYXRpb25LZXlzLkNSRUFURSxcbiAgICAgIHRoaXMuY2xhc3MsXG4gICAgICBhcmdzLFxuICAgICAgdGhpcy5hZGFwdGVyLFxuICAgICAgdGhpcy5fb3ZlcnJpZGVzIHx8IHt9XG4gICAgKTtcbiAgICBtb2RlbCA9IG5ldyB0aGlzLmNsYXNzKG1vZGVsKTtcbiAgICBhd2FpdCBlbmZvcmNlREJEZWNvcmF0b3JzKFxuICAgICAgdGhpcyxcbiAgICAgIGNvbnRleHRBcmdzLmNvbnRleHQsXG4gICAgICBtb2RlbCxcbiAgICAgIE9wZXJhdGlvbktleXMuQ1JFQVRFLFxuICAgICAgT3BlcmF0aW9uS2V5cy5PTlxuICAgICk7XG5cbiAgICBjb25zdCBlcnJvcnMgPSBtb2RlbC5oYXNFcnJvcnMoXG4gICAgICAuLi4oY29udGV4dEFyZ3MuY29udGV4dC5nZXQoXCJpZ25vcmVkVmFsaWRhdGlvblByb3BlcnRpZXNcIikgfHwgW10pXG4gICAgKTtcbiAgICBpZiAoZXJyb3JzKSB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKGVycm9ycy50b1N0cmluZygpKTtcblxuICAgIHJldHVybiBbbW9kZWwsIC4uLmNvbnRleHRBcmdzLmFyZ3NdO1xuICB9XG5cbiAgYXN5bmMgY3JlYXRlKG1vZGVsOiBNLCAuLi5hcmdzOiBhbnlbXSk6IFByb21pc2U8TT4ge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBwcmVmZXItY29uc3RcbiAgICBsZXQgeyByZWNvcmQsIGlkLCB0cmFuc2llbnQgfSA9IHRoaXMuYWRhcHRlci5wcmVwYXJlKG1vZGVsLCB0aGlzLnBrKTtcbiAgICByZWNvcmQgPSBhd2FpdCB0aGlzLmFkYXB0ZXIuY3JlYXRlKHRoaXMudGFibGVOYW1lLCBpZCwgcmVjb3JkLCAuLi5hcmdzKTtcbiAgICBsZXQgYzogQyB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcbiAgICBpZiAoYXJncy5sZW5ndGgpIGMgPSBhcmdzW2FyZ3MubGVuZ3RoIC0gMV0gYXMgQztcbiAgICByZXR1cm4gdGhpcy5hZGFwdGVyLnJldmVydDxNPihcbiAgICAgIHJlY29yZCxcbiAgICAgIHRoaXMuY2xhc3MsXG4gICAgICB0aGlzLnBrLFxuICAgICAgaWQsXG4gICAgICBjICYmIGMuZ2V0KFwicmVidWlsZFdpdGhUcmFuc2llbnRcIikgPyB0cmFuc2llbnQgOiB1bmRlZmluZWRcbiAgICApO1xuICB9XG5cbiAgb3ZlcnJpZGUgYXN5bmMgY3JlYXRlU3VmZml4KG1vZGVsOiBNLCBjb250ZXh0OiBDKTogUHJvbWlzZTxNPiB7XG4gICAgcmV0dXJuIHN1cGVyLmNyZWF0ZVN1ZmZpeChtb2RlbCwgY29udGV4dCk7XG4gIH1cblxuICBvdmVycmlkZSBhc3luYyBjcmVhdGVBbGwobW9kZWxzOiBNW10sIC4uLmFyZ3M6IGFueVtdKTogUHJvbWlzZTxNW10+IHtcbiAgICBpZiAoIW1vZGVscy5sZW5ndGgpIHJldHVybiBtb2RlbHM7XG4gICAgY29uc3QgcHJlcGFyZWQgPSBtb2RlbHMubWFwKChtKSA9PiB0aGlzLmFkYXB0ZXIucHJlcGFyZShtLCB0aGlzLnBrKSk7XG4gICAgY29uc3QgaWRzID0gcHJlcGFyZWQubWFwKChwKSA9PiBwLmlkKTtcbiAgICBsZXQgcmVjb3JkcyA9IHByZXBhcmVkLm1hcCgocCkgPT4gcC5yZWNvcmQpO1xuICAgIHJlY29yZHMgPSBhd2FpdCB0aGlzLmFkYXB0ZXIuY3JlYXRlQWxsKFxuICAgICAgdGhpcy50YWJsZU5hbWUsXG4gICAgICBpZHMgYXMgKHN0cmluZyB8IG51bWJlcilbXSxcbiAgICAgIHJlY29yZHMsXG4gICAgICAuLi5hcmdzXG4gICAgKTtcbiAgICByZXR1cm4gcmVjb3Jkcy5tYXAoKHIsIGkpID0+XG4gICAgICB0aGlzLmFkYXB0ZXIucmV2ZXJ0KHIsIHRoaXMuY2xhc3MsIHRoaXMucGssIGlkc1tpXSBhcyBzdHJpbmcgfCBudW1iZXIpXG4gICAgKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBvdmVycmlkZSBhc3luYyBjcmVhdGVBbGxQcmVmaXgobW9kZWxzOiBNW10sIC4uLmFyZ3M6IGFueVtdKSB7XG4gICAgY29uc3QgY29udGV4dEFyZ3MgPSBhd2FpdCBDb250ZXh0LmFyZ3MoXG4gICAgICBPcGVyYXRpb25LZXlzLkNSRUFURSxcbiAgICAgIHRoaXMuY2xhc3MsXG4gICAgICBhcmdzLFxuICAgICAgdGhpcy5hZGFwdGVyLFxuICAgICAgdGhpcy5fb3ZlcnJpZGVzIHx8IHt9XG4gICAgKTtcbiAgICBpZiAoIW1vZGVscy5sZW5ndGgpIHJldHVybiBbbW9kZWxzLCAuLi5jb250ZXh0QXJncy5hcmdzXTtcbiAgICBjb25zdCBvcHRzID0gUmVwb3NpdG9yeS5nZXRTZXF1ZW5jZU9wdGlvbnMobW9kZWxzWzBdKTtcbiAgICBsZXQgaWRzOiAoc3RyaW5nIHwgbnVtYmVyIHwgYmlnaW50IHwgdW5kZWZpbmVkKVtdID0gW107XG4gICAgaWYgKG9wdHMudHlwZSkge1xuICAgICAgaWYgKCFvcHRzLm5hbWUpIG9wdHMubmFtZSA9IFNlcXVlbmNlLnBrKG1vZGVsc1swXSk7XG4gICAgICBpZHMgPSBhd2FpdCAoYXdhaXQgdGhpcy5hZGFwdGVyLlNlcXVlbmNlKG9wdHMpKS5yYW5nZShtb2RlbHMubGVuZ3RoKTtcbiAgICB9XG5cbiAgICBtb2RlbHMgPSBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIG1vZGVscy5tYXAoYXN5bmMgKG0sIGkpID0+IHtcbiAgICAgICAgbSA9IG5ldyB0aGlzLmNsYXNzKG0pO1xuICAgICAgICBtW3RoaXMucGtdID0gaWRzW2ldIGFzIE1ba2V5b2YgTV07XG4gICAgICAgIGF3YWl0IGVuZm9yY2VEQkRlY29yYXRvcnMoXG4gICAgICAgICAgdGhpcyxcbiAgICAgICAgICBjb250ZXh0QXJncy5jb250ZXh0LFxuICAgICAgICAgIG0sXG4gICAgICAgICAgT3BlcmF0aW9uS2V5cy5DUkVBVEUsXG4gICAgICAgICAgT3BlcmF0aW9uS2V5cy5PTlxuICAgICAgICApO1xuICAgICAgICByZXR1cm4gbTtcbiAgICAgIH0pXG4gICAgKTtcbiAgICBjb25zdCBlcnJvcnMgPSBtb2RlbHNcbiAgICAgIC5tYXAoKG0pID0+XG4gICAgICAgIG0uaGFzRXJyb3JzKFxuICAgICAgICAgIC4uLihjb250ZXh0QXJncy5jb250ZXh0LmdldChcImlnbm9yZWRWYWxpZGF0aW9uUHJvcGVydGllc1wiKSB8fCBbXSlcbiAgICAgICAgKVxuICAgICAgKVxuICAgICAgLnJlZHVjZSgoYWNjdW06IHN0cmluZyB8IHVuZGVmaW5lZCwgZSwgaSkgPT4ge1xuICAgICAgICBpZiAoZSlcbiAgICAgICAgICBhY2N1bSA9XG4gICAgICAgICAgICB0eXBlb2YgYWNjdW0gPT09IFwic3RyaW5nXCJcbiAgICAgICAgICAgICAgPyBhY2N1bSArIGBcXG4gLSAke2l9OiAke2UudG9TdHJpbmcoKX1gXG4gICAgICAgICAgICAgIDogYCAtICR7aX06ICR7ZS50b1N0cmluZygpfWA7XG4gICAgICAgIHJldHVybiBhY2N1bTtcbiAgICAgIH0sIHVuZGVmaW5lZCk7XG4gICAgaWYgKGVycm9ycykgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcihlcnJvcnMpO1xuICAgIHJldHVybiBbbW9kZWxzLCAuLi5jb250ZXh0QXJncy5hcmdzXTtcbiAgfVxuXG4gIHByb3RlY3RlZCBvdmVycmlkZSBhc3luYyByZWFkUHJlZml4KGtleTogc3RyaW5nLCAuLi5hcmdzOiBhbnlbXSkge1xuICAgIGNvbnN0IGNvbnRleHRBcmdzID0gYXdhaXQgQ29udGV4dC5hcmdzKFxuICAgICAgT3BlcmF0aW9uS2V5cy5SRUFELFxuICAgICAgdGhpcy5jbGFzcyxcbiAgICAgIGFyZ3MsXG4gICAgICB0aGlzLmFkYXB0ZXIsXG4gICAgICB0aGlzLl9vdmVycmlkZXMgfHwge31cbiAgICApO1xuICAgIGNvbnN0IG1vZGVsOiBNID0gbmV3IHRoaXMuY2xhc3MoKTtcbiAgICBtb2RlbFt0aGlzLnBrXSA9IGtleSBhcyBNW2tleW9mIE1dO1xuICAgIGF3YWl0IGVuZm9yY2VEQkRlY29yYXRvcnMoXG4gICAgICB0aGlzLFxuICAgICAgY29udGV4dEFyZ3MuY29udGV4dCxcbiAgICAgIG1vZGVsLFxuICAgICAgT3BlcmF0aW9uS2V5cy5SRUFELFxuICAgICAgT3BlcmF0aW9uS2V5cy5PTlxuICAgICk7XG4gICAgcmV0dXJuIFtrZXksIC4uLmNvbnRleHRBcmdzLmFyZ3NdO1xuICB9XG5cbiAgYXN5bmMgcmVhZChpZDogc3RyaW5nIHwgbnVtYmVyIHwgYmlnaW50LCAuLi5hcmdzOiBhbnlbXSk6IFByb21pc2U8TT4ge1xuICAgIGNvbnN0IG0gPSBhd2FpdCB0aGlzLmFkYXB0ZXIucmVhZCh0aGlzLnRhYmxlTmFtZSwgaWQsIC4uLmFyZ3MpO1xuICAgIHJldHVybiB0aGlzLmFkYXB0ZXIucmV2ZXJ0PE0+KG0sIHRoaXMuY2xhc3MsIHRoaXMucGssIGlkKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBvdmVycmlkZSBhc3luYyByZWFkQWxsUHJlZml4KFxuICAgIGtleXM6IHN0cmluZ1tdIHwgbnVtYmVyW10sXG4gICAgLi4uYXJnczogYW55W11cbiAgKSB7XG4gICAgY29uc3QgY29udGV4dEFyZ3MgPSBhd2FpdCBDb250ZXh0LmFyZ3MoXG4gICAgICBPcGVyYXRpb25LZXlzLlJFQUQsXG4gICAgICB0aGlzLmNsYXNzLFxuICAgICAgYXJncyxcbiAgICAgIHRoaXMuYWRhcHRlcixcbiAgICAgIHRoaXMuX292ZXJyaWRlcyB8fCB7fVxuICAgICk7XG4gICAgYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICBrZXlzLm1hcChhc3luYyAoaykgPT4ge1xuICAgICAgICBjb25zdCBtID0gbmV3IHRoaXMuY2xhc3MoKTtcbiAgICAgICAgbVt0aGlzLnBrXSA9IGsgYXMgTVtrZXlvZiBNXTtcbiAgICAgICAgcmV0dXJuIGVuZm9yY2VEQkRlY29yYXRvcnMoXG4gICAgICAgICAgdGhpcyxcbiAgICAgICAgICBjb250ZXh0QXJncy5jb250ZXh0LFxuICAgICAgICAgIG0sXG4gICAgICAgICAgT3BlcmF0aW9uS2V5cy5SRUFELFxuICAgICAgICAgIE9wZXJhdGlvbktleXMuT05cbiAgICAgICAgKTtcbiAgICAgIH0pXG4gICAgKTtcbiAgICByZXR1cm4gW2tleXMsIC4uLmNvbnRleHRBcmdzLmFyZ3NdO1xuICB9XG5cbiAgb3ZlcnJpZGUgYXN5bmMgcmVhZEFsbChcbiAgICBrZXlzOiBzdHJpbmdbXSB8IG51bWJlcltdLFxuICAgIC4uLmFyZ3M6IGFueVtdXG4gICk6IFByb21pc2U8TVtdPiB7XG4gICAgY29uc3QgcmVjb3JkcyA9IGF3YWl0IHRoaXMuYWRhcHRlci5yZWFkQWxsKHRoaXMudGFibGVOYW1lLCBrZXlzLCAuLi5hcmdzKTtcbiAgICByZXR1cm4gcmVjb3Jkcy5tYXAoKHIsIGkpID0+XG4gICAgICB0aGlzLmFkYXB0ZXIucmV2ZXJ0KHIsIHRoaXMuY2xhc3MsIHRoaXMucGssIGtleXNbaV0pXG4gICAgKTtcbiAgfVxuXG4gIGFzeW5jIHVwZGF0ZShtb2RlbDogTSwgLi4uYXJnczogYW55W10pOiBQcm9taXNlPE0+IHtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcHJlZmVyLWNvbnN0XG4gICAgbGV0IHsgcmVjb3JkLCBpZCwgdHJhbnNpZW50IH0gPSB0aGlzLmFkYXB0ZXIucHJlcGFyZShtb2RlbCwgdGhpcy5wayk7XG4gICAgcmVjb3JkID0gYXdhaXQgdGhpcy5hZGFwdGVyLnVwZGF0ZSh0aGlzLnRhYmxlTmFtZSwgaWQsIHJlY29yZCwgLi4uYXJncyk7XG4gICAgcmV0dXJuIHRoaXMuYWRhcHRlci5yZXZlcnQ8TT4ocmVjb3JkLCB0aGlzLmNsYXNzLCB0aGlzLnBrLCBpZCwgdHJhbnNpZW50KTtcbiAgfVxuXG4gIHByb3RlY3RlZCBvdmVycmlkZSBhc3luYyB1cGRhdGVQcmVmaXgoXG4gICAgbW9kZWw6IE0sXG4gICAgLi4uYXJnczogYW55W11cbiAgKTogUHJvbWlzZTxbTSwgLi4uYXJnczogYW55W11dPiB7XG4gICAgY29uc3QgY29udGV4dEFyZ3MgPSBhd2FpdCBDb250ZXh0LmFyZ3MoXG4gICAgICBPcGVyYXRpb25LZXlzLlVQREFURSxcbiAgICAgIHRoaXMuY2xhc3MsXG4gICAgICBhcmdzLFxuICAgICAgdGhpcy5hZGFwdGVyLFxuICAgICAgdGhpcy5fb3ZlcnJpZGVzIHx8IHt9XG4gICAgKTtcbiAgICBjb25zdCBwayA9IG1vZGVsW3RoaXMucGtdIGFzIHN0cmluZztcbiAgICBpZiAoIXBrKVxuICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXG4gICAgICAgIGBObyB2YWx1ZSBmb3IgdGhlIElkIGlzIGRlZmluZWQgdW5kZXIgdGhlIHByb3BlcnR5ICR7dGhpcy5wayBhcyBzdHJpbmd9YFxuICAgICAgKTtcbiAgICBjb25zdCBvbGRNb2RlbCA9IGF3YWl0IHRoaXMucmVhZChwaywgLi4uY29udGV4dEFyZ3MuYXJncyk7XG4gICAgbW9kZWwgPSB0aGlzLm1lcmdlKG9sZE1vZGVsLCBtb2RlbCk7XG4gICAgYXdhaXQgZW5mb3JjZURCRGVjb3JhdG9ycyhcbiAgICAgIHRoaXMsXG4gICAgICBjb250ZXh0QXJncy5jb250ZXh0LFxuICAgICAgbW9kZWwsXG4gICAgICBPcGVyYXRpb25LZXlzLlVQREFURSxcbiAgICAgIE9wZXJhdGlvbktleXMuT04sXG4gICAgICBvbGRNb2RlbFxuICAgICk7XG5cbiAgICBjb25zdCBlcnJvcnMgPSBtb2RlbC5oYXNFcnJvcnMoXG4gICAgICBvbGRNb2RlbCxcbiAgICAgIC4uLlJlcG9zaXRvcnkucmVsYXRpb25zKHRoaXMuY2xhc3MpLFxuICAgICAgLi4uKGNvbnRleHRBcmdzLmNvbnRleHQuZ2V0KFwiaWdub3JlZFZhbGlkYXRpb25Qcm9wZXJ0aWVzXCIpIHx8IFtdKVxuICAgICk7XG4gICAgaWYgKGVycm9ycykgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcihlcnJvcnMudG9TdHJpbmcoKSk7XG4gICAgaWYgKFJlcG9zaXRvcnkuZ2V0TWV0YWRhdGEob2xkTW9kZWwpKSB7XG4gICAgICBpZiAoIVJlcG9zaXRvcnkuZ2V0TWV0YWRhdGEobW9kZWwpKVxuICAgICAgICBSZXBvc2l0b3J5LnNldE1ldGFkYXRhKG1vZGVsLCBSZXBvc2l0b3J5LmdldE1ldGFkYXRhKG9sZE1vZGVsKSk7XG4gICAgfVxuICAgIHJldHVybiBbbW9kZWwsIC4uLmNvbnRleHRBcmdzLmFyZ3NdO1xuICB9XG5cbiAgb3ZlcnJpZGUgYXN5bmMgdXBkYXRlQWxsKG1vZGVsczogTVtdLCAuLi5hcmdzOiBhbnlbXSk6IFByb21pc2U8TVtdPiB7XG4gICAgY29uc3QgcmVjb3JkcyA9IG1vZGVscy5tYXAoKG0pID0+IHRoaXMuYWRhcHRlci5wcmVwYXJlKG0sIHRoaXMucGspKTtcbiAgICBjb25zdCB1cGRhdGVkID0gYXdhaXQgdGhpcy5hZGFwdGVyLnVwZGF0ZUFsbChcbiAgICAgIHRoaXMudGFibGVOYW1lLFxuICAgICAgcmVjb3Jkcy5tYXAoKHIpID0+IHIuaWQpLFxuICAgICAgcmVjb3Jkcy5tYXAoKHIpID0+IHIucmVjb3JkKSxcbiAgICAgIC4uLmFyZ3NcbiAgICApO1xuICAgIHJldHVybiB1cGRhdGVkLm1hcCgodSwgaSkgPT5cbiAgICAgIHRoaXMuYWRhcHRlci5yZXZlcnQodSwgdGhpcy5jbGFzcywgdGhpcy5waywgcmVjb3Jkc1tpXS5pZClcbiAgICApO1xuICB9XG5cbiAgcHJvdGVjdGVkIG92ZXJyaWRlIGFzeW5jIHVwZGF0ZUFsbFByZWZpeChcbiAgICBtb2RlbHM6IE1bXSxcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApOiBQcm9taXNlPGFueVtdPiB7XG4gICAgY29uc3QgY29udGV4dEFyZ3MgPSBhd2FpdCBDb250ZXh0LmFyZ3MoXG4gICAgICBPcGVyYXRpb25LZXlzLlVQREFURSxcbiAgICAgIHRoaXMuY2xhc3MsXG4gICAgICBhcmdzLFxuICAgICAgdGhpcy5hZGFwdGVyLFxuICAgICAgdGhpcy5fb3ZlcnJpZGVzIHx8IHt9XG4gICAgKTtcbiAgICBjb25zdCBpZHMgPSBtb2RlbHMubWFwKChtKSA9PiB7XG4gICAgICBjb25zdCBpZCA9IG1bdGhpcy5wa10gYXMgc3RyaW5nO1xuICAgICAgaWYgKCFpZCkgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXCJtaXNzaW5nIGlkIG9uIHVwZGF0ZSBvcGVyYXRpb25cIik7XG4gICAgICByZXR1cm4gaWQ7XG4gICAgfSk7XG4gICAgY29uc3Qgb2xkTW9kZWxzID0gYXdhaXQgdGhpcy5yZWFkQWxsKGlkcywgLi4uY29udGV4dEFyZ3MuYXJncyk7XG4gICAgbW9kZWxzID0gbW9kZWxzLm1hcCgobSwgaSkgPT4ge1xuICAgICAgbSA9IHRoaXMubWVyZ2Uob2xkTW9kZWxzW2ldLCBtKTtcbiAgICAgIGlmIChSZXBvc2l0b3J5LmdldE1ldGFkYXRhKG9sZE1vZGVsc1tpXSkpIHtcbiAgICAgICAgaWYgKCFSZXBvc2l0b3J5LmdldE1ldGFkYXRhKG0pKVxuICAgICAgICAgIFJlcG9zaXRvcnkuc2V0TWV0YWRhdGEobSwgUmVwb3NpdG9yeS5nZXRNZXRhZGF0YShvbGRNb2RlbHNbaV0pKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBtO1xuICAgIH0pO1xuICAgIGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgbW9kZWxzLm1hcCgobSwgaSkgPT5cbiAgICAgICAgZW5mb3JjZURCRGVjb3JhdG9ycyhcbiAgICAgICAgICB0aGlzLFxuICAgICAgICAgIGNvbnRleHRBcmdzLmNvbnRleHQsXG4gICAgICAgICAgbSxcbiAgICAgICAgICBPcGVyYXRpb25LZXlzLlVQREFURSxcbiAgICAgICAgICBPcGVyYXRpb25LZXlzLk9OLFxuICAgICAgICAgIG9sZE1vZGVsc1tpXVxuICAgICAgICApXG4gICAgICApXG4gICAgKTtcblxuICAgIGNvbnN0IGVycm9ycyA9IG1vZGVsc1xuICAgICAgLm1hcCgobSwgaSkgPT5cbiAgICAgICAgbS5oYXNFcnJvcnMoXG4gICAgICAgICAgb2xkTW9kZWxzW2ldLFxuICAgICAgICAgIG0sXG4gICAgICAgICAgLi4uKGNvbnRleHRBcmdzLmNvbnRleHQuZ2V0KFwiaWdub3JlZFZhbGlkYXRpb25Qcm9wZXJ0aWVzXCIpIHx8IFtdKVxuICAgICAgICApXG4gICAgICApXG4gICAgICAucmVkdWNlKChhY2N1bTogc3RyaW5nIHwgdW5kZWZpbmVkLCBlLCBpKSA9PiB7XG4gICAgICAgIGlmIChlKVxuICAgICAgICAgIGFjY3VtID1cbiAgICAgICAgICAgIHR5cGVvZiBhY2N1bSA9PT0gXCJzdHJpbmdcIlxuICAgICAgICAgICAgICA/IGFjY3VtICsgYFxcbiAtICR7aX06ICR7ZS50b1N0cmluZygpfWBcbiAgICAgICAgICAgICAgOiBgIC0gJHtpfTogJHtlLnRvU3RyaW5nKCl9YDtcbiAgICAgICAgcmV0dXJuIGFjY3VtO1xuICAgICAgfSwgdW5kZWZpbmVkKTtcbiAgICBpZiAoZXJyb3JzKSB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKGVycm9ycyk7XG5cbiAgICBtb2RlbHMuZm9yRWFjaCgobSwgaSkgPT4ge1xuICAgICAgaWYgKFJlcG9zaXRvcnkuZ2V0TWV0YWRhdGEob2xkTW9kZWxzW2ldKSkge1xuICAgICAgICBpZiAoIVJlcG9zaXRvcnkuZ2V0TWV0YWRhdGEobSkpXG4gICAgICAgICAgUmVwb3NpdG9yeS5zZXRNZXRhZGF0YShtLCBSZXBvc2l0b3J5LmdldE1ldGFkYXRhKG9sZE1vZGVsc1tpXSkpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBbbW9kZWxzLCAuLi5jb250ZXh0QXJncy5hcmdzXTtcbiAgfVxuXG4gIHByb3RlY3RlZCBvdmVycmlkZSBhc3luYyBkZWxldGVQcmVmaXgoa2V5OiBhbnksIC4uLmFyZ3M6IGFueVtdKSB7XG4gICAgY29uc3QgY29udGV4dEFyZ3MgPSBhd2FpdCBDb250ZXh0LmFyZ3MoXG4gICAgICBPcGVyYXRpb25LZXlzLkRFTEVURSxcbiAgICAgIHRoaXMuY2xhc3MsXG4gICAgICBhcmdzLFxuICAgICAgdGhpcy5hZGFwdGVyLFxuICAgICAgdGhpcy5fb3ZlcnJpZGVzIHx8IHt9XG4gICAgKTtcbiAgICBjb25zdCBtb2RlbCA9IGF3YWl0IHRoaXMucmVhZChrZXksIC4uLmNvbnRleHRBcmdzLmFyZ3MpO1xuICAgIGF3YWl0IGVuZm9yY2VEQkRlY29yYXRvcnMoXG4gICAgICB0aGlzLFxuICAgICAgY29udGV4dEFyZ3MuY29udGV4dCxcbiAgICAgIG1vZGVsLFxuICAgICAgT3BlcmF0aW9uS2V5cy5ERUxFVEUsXG4gICAgICBPcGVyYXRpb25LZXlzLk9OXG4gICAgKTtcbiAgICByZXR1cm4gW2tleSwgLi4uY29udGV4dEFyZ3MuYXJnc107XG4gIH1cblxuICBhc3luYyBkZWxldGUoaWQ6IHN0cmluZyB8IG51bWJlciB8IGJpZ2ludCwgLi4uYXJnczogYW55W10pOiBQcm9taXNlPE0+IHtcbiAgICBjb25zdCBtID0gYXdhaXQgdGhpcy5hZGFwdGVyLmRlbGV0ZSh0aGlzLnRhYmxlTmFtZSwgaWQsIC4uLmFyZ3MpO1xuICAgIHJldHVybiB0aGlzLmFkYXB0ZXIucmV2ZXJ0PE0+KG0sIHRoaXMuY2xhc3MsIHRoaXMucGssIGlkKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBvdmVycmlkZSBhc3luYyBkZWxldGVBbGxQcmVmaXgoXG4gICAga2V5czogc3RyaW5nW10gfCBudW1iZXJbXSxcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApIHtcbiAgICBjb25zdCBjb250ZXh0QXJncyA9IGF3YWl0IENvbnRleHQuYXJncyhcbiAgICAgIE9wZXJhdGlvbktleXMuREVMRVRFLFxuICAgICAgdGhpcy5jbGFzcyxcbiAgICAgIGFyZ3MsXG4gICAgICB0aGlzLmFkYXB0ZXIsXG4gICAgICB0aGlzLl9vdmVycmlkZXMgfHwge31cbiAgICApO1xuICAgIGNvbnN0IG1vZGVscyA9IGF3YWl0IHRoaXMucmVhZEFsbChrZXlzLCAuLi5jb250ZXh0QXJncy5hcmdzKTtcbiAgICBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIG1vZGVscy5tYXAoYXN5bmMgKG0pID0+IHtcbiAgICAgICAgcmV0dXJuIGVuZm9yY2VEQkRlY29yYXRvcnMoXG4gICAgICAgICAgdGhpcyxcbiAgICAgICAgICBjb250ZXh0QXJncy5jb250ZXh0LFxuICAgICAgICAgIG0sXG4gICAgICAgICAgT3BlcmF0aW9uS2V5cy5ERUxFVEUsXG4gICAgICAgICAgT3BlcmF0aW9uS2V5cy5PTlxuICAgICAgICApO1xuICAgICAgfSlcbiAgICApO1xuICAgIHJldHVybiBba2V5cywgLi4uY29udGV4dEFyZ3MuYXJnc107XG4gIH1cblxuICBvdmVycmlkZSBhc3luYyBkZWxldGVBbGwoXG4gICAga2V5czogc3RyaW5nW10gfCBudW1iZXJbXSxcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApOiBQcm9taXNlPE1bXT4ge1xuICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCB0aGlzLmFkYXB0ZXIuZGVsZXRlQWxsKHRoaXMudGFibGVOYW1lLCBrZXlzLCAuLi5hcmdzKTtcbiAgICByZXR1cm4gcmVzdWx0cy5tYXAoKHIsIGkpID0+XG4gICAgICB0aGlzLmFkYXB0ZXIucmV2ZXJ0KHIsIHRoaXMuY2xhc3MsIHRoaXMucGssIGtleXNbaV0pXG4gICAgKTtcbiAgfVxuICBzZWxlY3Q8XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICAgIFMgZXh0ZW5kcyByZWFkb25seSBTZWxlY3RTZWxlY3RvcjxNPltdLFxuICA+KCk6IFdoZXJlT3B0aW9uPE0sIE1bXT47XG4gIHNlbGVjdDxTIGV4dGVuZHMgcmVhZG9ubHkgU2VsZWN0U2VsZWN0b3I8TT5bXT4oXG4gICAgc2VsZWN0b3I6IHJlYWRvbmx5IFsuLi5TXVxuICApOiBXaGVyZU9wdGlvbjxNLCBQaWNrPE0sIFNbbnVtYmVyXT5bXT47XG4gIHNlbGVjdDxTIGV4dGVuZHMgcmVhZG9ubHkgU2VsZWN0U2VsZWN0b3I8TT5bXT4oXG4gICAgc2VsZWN0b3I/OiByZWFkb25seSBbLi4uU11cbiAgKTogV2hlcmVPcHRpb248TSwgTVtdPiB8IFdoZXJlT3B0aW9uPE0sIFBpY2s8TSwgU1tudW1iZXJdPltdPiB7XG4gICAgcmV0dXJuIHRoaXMuYWRhcHRlclxuICAgICAgLlN0YXRlbWVudDxNPigpXG4gICAgICAuc2VsZWN0KHNlbGVjdG9yIGFzIHJlYWRvbmx5IFsuLi5TXSlcbiAgICAgIC5mcm9tKHRoaXMuY2xhc3MpO1xuICB9XG5cbiAgYXN5bmMgcXVlcnkoXG4gICAgY29uZGl0aW9uOiBDb25kaXRpb248TT4sXG4gICAgb3JkZXJCeToga2V5b2YgTSxcbiAgICBvcmRlcjogT3JkZXJEaXJlY3Rpb24gPSBPcmRlckRpcmVjdGlvbi5BU0MsXG4gICAgbGltaXQ/OiBudW1iZXIsXG4gICAgc2tpcD86IG51bWJlclxuICApOiBQcm9taXNlPE1bXT4ge1xuICAgIGNvbnN0IHNvcnQ6IE9yZGVyQnlTZWxlY3RvcjxNPiA9IFtvcmRlckJ5LCBvcmRlciBhcyBPcmRlckRpcmVjdGlvbl07XG4gICAgY29uc3QgcXVlcnkgPSB0aGlzLnNlbGVjdCgpLndoZXJlKGNvbmRpdGlvbikub3JkZXJCeShzb3J0KTtcbiAgICBpZiAobGltaXQpIHF1ZXJ5LmxpbWl0KGxpbWl0KTtcbiAgICBpZiAoc2tpcCkgcXVlcnkub2Zmc2V0KHNraXApO1xuICAgIHJldHVybiBxdWVyeS5leGVjdXRlKCk7XG4gIH1cblxuICAvKipcbiAgICpcbiAgICogQHNlZSB7T2JzZXJ2YWJsZSNvYnNlcnZlfVxuICAgKi9cbiAgQGZpbmFsKClcbiAgb2JzZXJ2ZShvYnNlcnZlcjogT2JzZXJ2ZXIsIGZpbHRlcj86IE9ic2VydmVyRmlsdGVyKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLm9ic2VydmVySGFuZGxlcilcbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCBcIm9ic2VydmVySGFuZGxlclwiLCB7XG4gICAgICAgIHZhbHVlOiB0aGlzLk9ic2VydmVySGFuZGxlcigpLFxuICAgICAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgICB9KTtcbiAgICBjb25zdCBsb2cgPSB0aGlzLmxvZy5mb3IodGhpcy5vYnNlcnZlKTtcbiAgICBjb25zdCB0YWJsZU5hbWUgPSBSZXBvc2l0b3J5LnRhYmxlKHRoaXMuY2xhc3MpO1xuICAgIHRoaXMuYWRhcHRlci5vYnNlcnZlKHRoaXMsICh0YWJsZTogc3RyaW5nKSA9PiB0YWJsZU5hbWUgPT09IHRhYmxlKTtcbiAgICBsb2cudmVyYm9zZShcbiAgICAgIGBub3cgb2JzZXJ2aW5nICR7dGhpcy5hZGFwdGVyfSBmaWx0ZXJpbmcgb24gdGFibGUgPT09ICR7dGFibGVOYW1lfWBcbiAgICApO1xuICAgIHRoaXMub2JzZXJ2ZXJIYW5kbGVyIS5vYnNlcnZlKG9ic2VydmVyLCBmaWx0ZXIpO1xuICAgIGxvZy52ZXJib3NlKGBSZWdpc3RlcmVkIG5ldyBvYnNlcnZlciAke29ic2VydmVyLnRvU3RyaW5nKCl9YCk7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgVW5yZWdpc3RlcnMgYW4ge0BsaW5rIE9ic2VydmVyfVxuICAgKiBAcGFyYW0ge09ic2VydmVyfSBvYnNlcnZlclxuICAgKlxuICAgKiBAc2VlIHtPYnNlcnZhYmxlI3VuT2JzZXJ2ZX1cbiAgICovXG4gIEBmaW5hbCgpXG4gIHVuT2JzZXJ2ZShvYnNlcnZlcjogT2JzZXJ2ZXIpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMub2JzZXJ2ZXJIYW5kbGVyKVxuICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXG4gICAgICAgIFwiT2JzZXJ2ZXJIYW5kbGVyIG5vdCBpbml0aWFsaXplZC4gRGlkIHlvdSByZWdpc3RlciBhbnkgb2JzZXJ2YWJsZXM/XCJcbiAgICAgICk7XG4gICAgdGhpcy5vYnNlcnZlckhhbmRsZXIudW5PYnNlcnZlKG9ic2VydmVyKTtcbiAgICB0aGlzLmxvZ1xuICAgICAgLmZvcih0aGlzLnVuT2JzZXJ2ZSlcbiAgICAgIC52ZXJib3NlKGBPYnNlcnZlciAke29ic2VydmVyLnRvU3RyaW5nKCl9IHJlbW92ZWRgKTtcbiAgICBpZiAoIXRoaXMub2JzZXJ2ZXJIYW5kbGVyLmNvdW50KCkpIHtcbiAgICAgIHRoaXMubG9nLnZlcmJvc2UoXG4gICAgICAgIGBObyBtb3JlIG9ic2VydmVycyByZWdpc3RlcmVkIGZvciAke3RoaXMuYWRhcHRlcn0sIHVuc3Vic2NyaWJpbmdgXG4gICAgICApO1xuICAgICAgdGhpcy5hZGFwdGVyLnVuT2JzZXJ2ZSh0aGlzKTtcbiAgICAgIHRoaXMubG9nLnZlcmJvc2UoYE5vIGxvbmdlciBvYnNlcnZpbmcgYWRhcHRlciAke3RoaXMuYWRhcHRlci5mbGF2b3VyfWApO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIHVwZGF0ZU9ic2VydmVycyhcbiAgICB0YWJsZTogc3RyaW5nLFxuICAgIGV2ZW50OiBPcGVyYXRpb25LZXlzIHwgQnVsa0NydWRPcGVyYXRpb25LZXlzIHwgc3RyaW5nLFxuICAgIGlkOiBFdmVudElkcyxcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAoIXRoaXMub2JzZXJ2ZXJIYW5kbGVyKVxuICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXG4gICAgICAgIFwiT2JzZXJ2ZXJIYW5kbGVyIG5vdCBpbml0aWFsaXplZC4gRGlkIHlvdSByZWdpc3RlciBhbnkgb2JzZXJ2YWJsZXM/XCJcbiAgICAgICk7XG4gICAgdGhpcy5sb2dcbiAgICAgIC5mb3IodGhpcy51cGRhdGVPYnNlcnZlcnMpXG4gICAgICAudmVyYm9zZShcbiAgICAgICAgYFVwZGF0aW5nICR7dGhpcy5vYnNlcnZlckhhbmRsZXIuY291bnQoKX0gb2JzZXJ2ZXJzIGZvciAke3RoaXN9YFxuICAgICAgKTtcbiAgICBhd2FpdCB0aGlzLm9ic2VydmVySGFuZGxlci51cGRhdGVPYnNlcnZlcnMoXG4gICAgICB0aGlzLmxvZyxcbiAgICAgIHRhYmxlLFxuICAgICAgZXZlbnQsXG4gICAgICBBcnJheS5pc0FycmF5KGlkKVxuICAgICAgICA/IGlkLm1hcCgoaSkgPT4gU2VxdWVuY2UucGFyc2VWYWx1ZSh0aGlzLnBrUHJvcHMudHlwZSwgaSkgYXMgc3RyaW5nKVxuICAgICAgICA6IChTZXF1ZW5jZS5wYXJzZVZhbHVlKHRoaXMucGtQcm9wcy50eXBlLCBpZCkgYXMgc3RyaW5nKSxcbiAgICAgIC4uLmFyZ3NcbiAgICApO1xuICB9XG5cbiAgYXN5bmMgcmVmcmVzaChcbiAgICB0YWJsZTogc3RyaW5nLFxuICAgIGV2ZW50OiBPcGVyYXRpb25LZXlzIHwgQnVsa0NydWRPcGVyYXRpb25LZXlzIHwgc3RyaW5nLFxuICAgIGlkOiBFdmVudElkcyxcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApIHtcbiAgICByZXR1cm4gdGhpcy51cGRhdGVPYnNlcnZlcnModGFibGUsIGV2ZW50LCBpZCwgLi4uYXJncyk7XG4gIH1cblxuICBzdGF0aWMgZm9yTW9kZWw8TSBleHRlbmRzIE1vZGVsLCBSIGV4dGVuZHMgUmVwbzxNPj4oXG4gICAgbW9kZWw6IENvbnN0cnVjdG9yPE0+LFxuICAgIGRlZmF1bHRGbGF2b3VyPzogc3RyaW5nLFxuICAgIC4uLmFyZ3M6IGFueVtdXG4gICk6IFIge1xuICAgIGxldCByZXBvOiBSIHwgQ29uc3RydWN0b3I8Uj4gfCB1bmRlZmluZWQ7XG4gICAgdHJ5IHtcbiAgICAgIHJlcG8gPSB0aGlzLmdldChtb2RlbCkgYXMgQ29uc3RydWN0b3I8Uj4gfCBSO1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgcmVwbyA9IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBpZiAocmVwbyBpbnN0YW5jZW9mIFJlcG9zaXRvcnkpIHJldHVybiByZXBvIGFzIFI7XG5cbiAgICBjb25zdCBmbGF2b3VyOiBzdHJpbmcgfCB1bmRlZmluZWQgPVxuICAgICAgUmVmbGVjdC5nZXRNZXRhZGF0YShBZGFwdGVyLmtleShQZXJzaXN0ZW5jZUtleXMuQURBUFRFUiksIG1vZGVsKSB8fFxuICAgICAgKHJlcG8gJiZcbiAgICAgICAgUmVmbGVjdC5nZXRNZXRhZGF0YShBZGFwdGVyLmtleShQZXJzaXN0ZW5jZUtleXMuQURBUFRFUiksIHJlcG8pKSB8fFxuICAgICAgZGVmYXVsdEZsYXZvdXI7XG4gICAgY29uc3QgYWRhcHRlcjogQWRhcHRlcjxhbnksIGFueSwgYW55LCBhbnk+IHwgdW5kZWZpbmVkID0gZmxhdm91clxuICAgICAgPyBBZGFwdGVyLmdldChmbGF2b3VyKVxuICAgICAgOiB1bmRlZmluZWQ7XG5cbiAgICBpZiAoIWFkYXB0ZXIpXG4gICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcbiAgICAgICAgYE5vIHJlZ2lzdGVyZWQgcGVyc2lzdGVuY2UgYWRhcHRlciBmb3VuZCBmbGF2b3VyICR7Zmxhdm91cn1gXG4gICAgICApO1xuXG4gICAgcmVwbyA9IHJlcG8gfHwgKGFkYXB0ZXIucmVwb3NpdG9yeSgpIGFzIENvbnN0cnVjdG9yPFI+KTtcbiAgICByZXR1cm4gbmV3IHJlcG8oYWRhcHRlciwgbW9kZWwsIC4uLmFyZ3MpIGFzIFI7XG4gIH1cblxuICBwcml2YXRlIHN0YXRpYyBnZXQ8TSBleHRlbmRzIE1vZGVsPihcbiAgICBtb2RlbDogQ29uc3RydWN0b3I8TT5cbiAgKTogQ29uc3RydWN0b3I8UmVwbzxNPj4gfCBSZXBvPE0+IHtcbiAgICBjb25zdCBuYW1lID0gUmVwb3NpdG9yeS50YWJsZShtb2RlbCk7XG4gICAgaWYgKG5hbWUgaW4gdGhpcy5fY2FjaGUpXG4gICAgICByZXR1cm4gdGhpcy5fY2FjaGVbbmFtZV0gYXMgdW5rbm93biBhcyBDb25zdHJ1Y3RvcjxSZXBvPE0+PiB8IFJlcG88TT47XG4gICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXG4gICAgICBgQ291bGQgbm90IGZpbmQgcmVwb3NpdG9yeSByZWdpc3RlcmVkIHVuZGVyICR7bmFtZX1gXG4gICAgKTtcbiAgfVxuXG4gIHN0YXRpYyByZWdpc3RlcjxNIGV4dGVuZHMgTW9kZWw+KFxuICAgIG1vZGVsOiBDb25zdHJ1Y3RvcjxNPixcbiAgICByZXBvOiBDb25zdHJ1Y3RvcjxSZXBvPE0+PiB8IFJlcG88TT5cbiAgKSB7XG4gICAgY29uc3QgbmFtZSA9IFJlcG9zaXRvcnkudGFibGUobW9kZWwpO1xuICAgIGlmIChuYW1lIGluIHRoaXMuX2NhY2hlKVxuICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoYCR7bmFtZX0gYWxyZWFkeSByZWdpc3RlcmVkIGFzIGEgcmVwb3NpdG9yeWApO1xuICAgIHRoaXMuX2NhY2hlW25hbWVdID0gcmVwbyBhcyBhbnk7XG4gIH1cblxuICBzdGF0aWMgc2V0TWV0YWRhdGE8TSBleHRlbmRzIE1vZGVsPihtb2RlbDogTSwgbWV0YWRhdGE6IGFueSkge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShtb2RlbCwgUGVyc2lzdGVuY2VLZXlzLk1FVEFEQVRBLCB7XG4gICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICAgIHZhbHVlOiBtZXRhZGF0YSxcbiAgICB9KTtcbiAgfVxuXG4gIHN0YXRpYyBnZXRNZXRhZGF0YTxNIGV4dGVuZHMgTW9kZWw+KG1vZGVsOiBNKSB7XG4gICAgY29uc3QgZGVzY3JpcHRvciA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoXG4gICAgICBtb2RlbCxcbiAgICAgIFBlcnNpc3RlbmNlS2V5cy5NRVRBREFUQVxuICAgICk7XG4gICAgcmV0dXJuIGRlc2NyaXB0b3IgPyBkZXNjcmlwdG9yLnZhbHVlIDogdW5kZWZpbmVkO1xuICB9XG5cbiAgc3RhdGljIHJlbW92ZU1ldGFkYXRhPE0gZXh0ZW5kcyBNb2RlbD4obW9kZWw6IE0pIHtcbiAgICBjb25zdCBkZXNjcmlwdG9yID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihcbiAgICAgIG1vZGVsLFxuICAgICAgUGVyc2lzdGVuY2VLZXlzLk1FVEFEQVRBXG4gICAgKTtcbiAgICBpZiAoZGVzY3JpcHRvcikgZGVsZXRlIChtb2RlbCBhcyBhbnkpW1BlcnNpc3RlbmNlS2V5cy5NRVRBREFUQV07XG4gIH1cblxuICBzdGF0aWMgZ2V0U2VxdWVuY2VPcHRpb25zPE0gZXh0ZW5kcyBNb2RlbD4obW9kZWw6IE0pIHtcbiAgICBjb25zdCBwayA9IGZpbmRQcmltYXJ5S2V5KG1vZGVsKS5pZDtcbiAgICBjb25zdCBtZXRhZGF0YSA9IFJlZmxlY3QuZ2V0TWV0YWRhdGEoXG4gICAgICBSZXBvc2l0b3J5LmtleShEQktleXMuSUQpLFxuICAgICAgbW9kZWwsXG4gICAgICBwayBhcyBzdHJpbmdcbiAgICApO1xuICAgIGlmICghbWV0YWRhdGEpXG4gICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcbiAgICAgICAgXCJObyBzZXF1ZW5jZSBvcHRpb25zIGRlZmluZWQgZm9yIG1vZGVsLiBkaWQgeW91IHVzZSB0aGUgQHBrIGRlY29yYXRvcj9cIlxuICAgICAgKTtcbiAgICByZXR1cm4gbWV0YWRhdGEgYXMgU2VxdWVuY2VPcHRpb25zO1xuICB9XG5cbiAgc3RhdGljIGluZGV4ZXM8TSBleHRlbmRzIE1vZGVsPihtb2RlbDogTSB8IENvbnN0cnVjdG9yPE0+KSB7XG4gICAgY29uc3QgaW5kZXhEZWNvcmF0b3JzID0gUmVmbGVjdGlvbi5nZXRBbGxQcm9wZXJ0eURlY29yYXRvcnMoXG4gICAgICBtb2RlbCBpbnN0YW5jZW9mIE1vZGVsID8gbW9kZWwgOiBuZXcgbW9kZWwoKSxcbiAgICAgIERCS2V5cy5SRUZMRUNUXG4gICAgKTtcbiAgICByZXR1cm4gT2JqZWN0LmVudHJpZXMoaW5kZXhEZWNvcmF0b3JzIHx8IHt9KS5yZWR1Y2UoXG4gICAgICAoYWNjdW06IFJlY29yZDxzdHJpbmcsIFJlY29yZDxzdHJpbmcsIEluZGV4TWV0YWRhdGE+PiwgW2ssIHZhbF0pID0+IHtcbiAgICAgICAgY29uc3QgZGVjcyA9IHZhbC5maWx0ZXIoKHYpID0+IHYua2V5LnN0YXJ0c1dpdGgoUGVyc2lzdGVuY2VLZXlzLklOREVYKSk7XG4gICAgICAgIGlmIChkZWNzICYmIGRlY3MubGVuZ3RoKSB7XG4gICAgICAgICAgZm9yIChjb25zdCBkZWMgb2YgZGVjcykge1xuICAgICAgICAgICAgY29uc3QgeyBrZXksIHByb3BzIH0gPSBkZWM7XG4gICAgICAgICAgICBhY2N1bVtrXSA9IGFjY3VtW2tdIHx8IHt9O1xuICAgICAgICAgICAgYWNjdW1ba11ba2V5XSA9IHByb3BzIGFzIEluZGV4TWV0YWRhdGE7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBhY2N1bTtcbiAgICAgIH0sXG4gICAgICB7fVxuICAgICk7XG4gIH1cblxuICBzdGF0aWMgcmVsYXRpb25zPE0gZXh0ZW5kcyBNb2RlbD4obW9kZWw6IE0gfCBDb25zdHJ1Y3RvcjxNPikge1xuICAgIGNvbnN0IHJlc3VsdDogc3RyaW5nW10gPSBbXTtcbiAgICBsZXQgcHJvdG90eXBlID1cbiAgICAgIG1vZGVsIGluc3RhbmNlb2YgTW9kZWxcbiAgICAgICAgPyBPYmplY3QuZ2V0UHJvdG90eXBlT2YobW9kZWwpXG4gICAgICAgIDogKG1vZGVsIGFzIGFueSkucHJvdG90eXBlO1xuICAgIHdoaWxlIChwcm90b3R5cGUgIT0gbnVsbCkge1xuICAgICAgY29uc3QgcHJvcHM6IHN0cmluZ1tdID0gcHJvdG90eXBlW1BlcnNpc3RlbmNlS2V5cy5SRUxBVElPTlNdO1xuICAgICAgaWYgKHByb3BzKSB7XG4gICAgICAgIHJlc3VsdC5wdXNoKC4uLnByb3BzKTtcbiAgICAgIH1cbiAgICAgIHByb3RvdHlwZSA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihwcm90b3R5cGUpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgc3RhdGljIHRhYmxlPE0gZXh0ZW5kcyBNb2RlbD4obW9kZWw6IE0gfCBDb25zdHJ1Y3RvcjxNPikge1xuICAgIHJldHVybiBnZXRUYWJsZU5hbWUobW9kZWwpO1xuICB9XG5cbiAgc3RhdGljIGNvbHVtbjxNIGV4dGVuZHMgTW9kZWw+KG1vZGVsOiBNLCBhdHRyaWJ1dGU6IHN0cmluZykge1xuICAgIGNvbnN0IG1ldGFkYXRhID0gUmVmbGVjdC5nZXRNZXRhZGF0YShcbiAgICAgIEFkYXB0ZXIua2V5KFBlcnNpc3RlbmNlS2V5cy5DT0xVTU4pLFxuICAgICAgbW9kZWwsXG4gICAgICBhdHRyaWJ1dGVcbiAgICApO1xuICAgIHJldHVybiBtZXRhZGF0YSA/IG1ldGFkYXRhIDogYXR0cmlidXRlO1xuICB9XG59XG4iLCJpbXBvcnQgeyBpbmplY3QsIGluamVjdGFibGUgfSBmcm9tIFwiQGRlY2FmLXRzL2luamVjdGFibGUtZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHsgREJLZXlzLCBJUmVwb3NpdG9yeSB9IGZyb20gXCJAZGVjYWYtdHMvZGItZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHsgbWV0YWRhdGEgfSBmcm9tIFwiQGRlY2FmLXRzL3JlZmxlY3Rpb25cIjtcbmltcG9ydCB7IENvbnN0cnVjdG9yLCBNb2RlbCB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7IFJlcG9zaXRvcnkgfSBmcm9tIFwiLi9SZXBvc2l0b3J5XCI7XG5cbmV4cG9ydCBmdW5jdGlvbiByZXBvc2l0b3J5PFQgZXh0ZW5kcyBNb2RlbD4oXG4gIG1vZGVsOiBDb25zdHJ1Y3RvcjxUPixcbiAgbmFtZU92ZXJyaWRlPzogc3RyaW5nXG4pOiBhbnkge1xuICByZXR1cm4gKChvcmlnaW5hbDogYW55LCBwcm9wZXJ0eUtleT86IGFueSkgPT4ge1xuICAgIGlmIChwcm9wZXJ0eUtleSkge1xuICAgICAgcmV0dXJuIGluamVjdChuYW1lT3ZlcnJpZGUgfHwgbW9kZWwubmFtZSkob3JpZ2luYWwsIHByb3BlcnR5S2V5KTtcbiAgICB9XG5cbiAgICBtZXRhZGF0YShcbiAgICAgIFJlcG9zaXRvcnkua2V5KERCS2V5cy5SRVBPU0lUT1JZKSxcbiAgICAgIG5hbWVPdmVycmlkZSB8fCBvcmlnaW5hbC5uYW1lXG4gICAgKShtb2RlbCk7XG4gICAgUmVwb3NpdG9yeS5yZWdpc3Rlcihtb2RlbCwgb3JpZ2luYWwpO1xuICAgIHJldHVybiBpbmplY3RhYmxlKFxuICAgICAgbmFtZU92ZXJyaWRlIHx8IG9yaWdpbmFsLm5hbWUsXG4gICAgICB0cnVlLFxuICAgICAgKGluc3RhbmNlOiBJUmVwb3NpdG9yeTxUPikgPT4ge1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoaW5zdGFuY2UsIERCS2V5cy5DTEFTUywge1xuICAgICAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgICAgIGNvbmZpZ3VyYWJsZTogZmFsc2UsXG4gICAgICAgICAgd3JpdGFibGU6IGZhbHNlLFxuICAgICAgICAgIHZhbHVlOiBtb2RlbCxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgKShvcmlnaW5hbCk7XG4gIH0pIGFzIGFueTtcbn1cbiIsImltcG9ydCB7IEJhc2VFcnJvciB9IGZyb20gXCJAZGVjYWYtdHMvZGItZGVjb3JhdG9yc1wiO1xuXG4vKipcbiAqIEBzdW1tYXJ5IFJlcHJlc2VudHMgYSBmYWlsdXJlIGluIG9ic2VydmVyIGNvbW11bmljYXRpb25cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gbXNnIHRoZSBlcnJvciBtZXNzYWdlXG4gKlxuICogQGNsYXNzIE9ic2VydmVyRXJyb3JcbiAqIEBleHRlbmRzIEJhc2VFcnJvclxuICovXG5leHBvcnQgY2xhc3MgT2JzZXJ2ZXJFcnJvciBleHRlbmRzIEJhc2VFcnJvciB7XG4gIGNvbnN0cnVjdG9yKG1zZzogc3RyaW5nIHwgRXJyb3IpIHtcbiAgICBzdXBlcihPYnNlcnZlckVycm9yLm5hbWUsIG1zZywgNTAwKTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgSW50ZXJuYWxFcnJvciB9IGZyb20gXCJAZGVjYWYtdHMvZGItZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHsgQ29uc3RydWN0b3IsIHNmIH0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgQWRhcHRlciB9IGZyb20gXCIuLi9wZXJzaXN0ZW5jZS9BZGFwdGVyXCI7XG5pbXBvcnQgeyBQZXJzaXN0ZW5jZUtleXMgfSBmcm9tIFwiLi4vcGVyc2lzdGVuY2UvY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBNb2RlbCB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7IFJlcG9zaXRvcnkgfSBmcm9tIFwiLi9SZXBvc2l0b3J5XCI7XG5cbmV4cG9ydCBmdW5jdGlvbiBnZW5lcmF0ZUluamVjdGFibGVOYW1lRm9yUmVwb3NpdG9yeTxUIGV4dGVuZHMgTW9kZWw+KFxuICBtb2RlbDogQ29uc3RydWN0b3I8VD4gfCBULFxuICBmbGF2b3VyPzogc3RyaW5nXG4pIHtcbiAgaWYgKCFmbGF2b3VyKSB7XG4gICAgY29uc3Qga2V5ID0gQWRhcHRlci5rZXkoUGVyc2lzdGVuY2VLZXlzLkFEQVBURVIpO1xuICAgIGZsYXZvdXIgPSBSZWZsZWN0LmdldE1ldGFkYXRhKFxuICAgICAga2V5LFxuICAgICAgbW9kZWwgaW5zdGFuY2VvZiBNb2RlbCA/IG1vZGVsLmNvbnN0cnVjdG9yIDogbW9kZWxcbiAgICApO1xuICAgIGlmICghZmxhdm91cilcbiAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFxuICAgICAgICBgQ291bGQgbm90IHJldHJpZXZlIGZsYXZvdXIgZnJvbSBtb2RlbCAke21vZGVsIGluc3RhbmNlb2YgTW9kZWwgPyBtb2RlbC5jb25zdHJ1Y3Rvci5uYW1lIDogbW9kZWwubmFtZX1gXG4gICAgICApO1xuICB9XG4gIHJldHVybiBzZihQZXJzaXN0ZW5jZUtleXMuSU5KRUNUQUJMRSwgZmxhdm91ciwgUmVwb3NpdG9yeS50YWJsZShtb2RlbCkpO1xufVxuIiwiaW1wb3J0IHtcbiAgSW5qZWN0YWJsZVJlZ2lzdHJ5SW1wLFxuICBJbmplY3RhYmxlcyxcbn0gZnJvbSBcIkBkZWNhZi10cy9pbmplY3RhYmxlLWRlY29yYXRvcnNcIjtcbmltcG9ydCB7IFJlcG9zaXRvcnkgfSBmcm9tIFwiLi9SZXBvc2l0b3J5XCI7XG5pbXBvcnQgeyBNb2RlbCwgTW9kZWxDb25zdHJ1Y3RvciB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7IGdlbmVyYXRlSW5qZWN0YWJsZU5hbWVGb3JSZXBvc2l0b3J5IH0gZnJvbSBcIi4vdXRpbHNcIjtcbmltcG9ydCB7IFBlcnNpc3RlbmNlS2V5cyB9IGZyb20gXCIuLi9wZXJzaXN0ZW5jZS9jb25zdGFudHNcIjtcbmltcG9ydCB7IEFkYXB0ZXIgfSBmcm9tIFwiLi4vcGVyc2lzdGVuY2UvQWRhcHRlclwiO1xuXG5leHBvcnQgY2xhc3MgSW5qZWN0YWJsZXNSZWdpc3RyeSBleHRlbmRzIEluamVjdGFibGVSZWdpc3RyeUltcCB7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCk7XG4gIH1cblxuICBvdmVycmlkZSBnZXQ8VD4obmFtZTogc3RyaW5nKTogVCB8IHVuZGVmaW5lZCB7XG4gICAgbGV0IGluamVjdGFibGUgPSBzdXBlci5nZXQobmFtZSk7XG4gICAgaWYgKCFpbmplY3RhYmxlKVxuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgbSA9IE1vZGVsLmdldChuYW1lKTtcbiAgICAgICAgaWYgKG0pIGluamVjdGFibGUgPSBSZXBvc2l0b3J5LmZvck1vZGVsKG0pO1xuICAgICAgICBpZiAoaW5qZWN0YWJsZSkge1xuICAgICAgICAgIGlmIChpbmplY3RhYmxlIGluc3RhbmNlb2YgUmVwb3NpdG9yeSkgcmV0dXJuIGluamVjdGFibGUgYXMgVDtcbiAgICAgICAgICBjb25zdCBmbGF2b3VyID1cbiAgICAgICAgICAgIFJlZmxlY3QuZ2V0TWV0YWRhdGEoXG4gICAgICAgICAgICAgIEFkYXB0ZXIua2V5KFBlcnNpc3RlbmNlS2V5cy5BREFQVEVSKSxcbiAgICAgICAgICAgICAgaW5qZWN0YWJsZS5jb25zdHJ1Y3RvclxuICAgICAgICAgICAgKSB8fFxuICAgICAgICAgICAgUmVmbGVjdC5nZXRNZXRhZGF0YShcbiAgICAgICAgICAgICAgQWRhcHRlci5rZXkoUGVyc2lzdGVuY2VLZXlzLkFEQVBURVIpLFxuICAgICAgICAgICAgICBtIGFzIE1vZGVsQ29uc3RydWN0b3I8YW55PlxuICAgICAgICAgICAgKTtcbiAgICAgICAgICBJbmplY3RhYmxlcy5yZWdpc3RlcihcbiAgICAgICAgICAgIGluamVjdGFibGUsXG4gICAgICAgICAgICBnZW5lcmF0ZUluamVjdGFibGVOYW1lRm9yUmVwb3NpdG9yeShcbiAgICAgICAgICAgICAgbSBhcyBNb2RlbENvbnN0cnVjdG9yPGFueT4sXG4gICAgICAgICAgICAgIGZsYXZvdXJcbiAgICAgICAgICAgIClcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgIHJldHVybiBpbmplY3RhYmxlIGFzIFQgfCB1bmRlZmluZWQ7XG4gIH1cbn1cbiIsImV4cG9ydCBpbnRlcmZhY2UgU2VxdWVuY2VPcHRpb25zIHtcbiAgbmFtZT86IHN0cmluZztcbiAgdHlwZTogXCJOdW1iZXJcIiB8IFwiQmlnSW50XCIgfCB1bmRlZmluZWQ7XG4gIHN0YXJ0V2l0aDogbnVtYmVyO1xuICBpbmNyZW1lbnRCeTogbnVtYmVyO1xuICBtaW5WYWx1ZT86IG51bWJlcjtcbiAgbWF4VmFsdWU/OiBudW1iZXI7XG4gIGN5Y2xlOiBib29sZWFuO1xufVxuXG5leHBvcnQgY29uc3QgRGVmYXVsdFNlcXVlbmNlT3B0aW9uczogU2VxdWVuY2VPcHRpb25zID0ge1xuICB0eXBlOiBcIk51bWJlclwiLFxuICBzdGFydFdpdGg6IDAsXG4gIGluY3JlbWVudEJ5OiAxLFxuICBjeWNsZTogZmFsc2UsXG59O1xuXG5leHBvcnQgY29uc3QgTnVtZXJpY1NlcXVlbmNlOiBTZXF1ZW5jZU9wdGlvbnMgPSB7XG4gIHR5cGU6IFwiTnVtYmVyXCIsXG4gIHN0YXJ0V2l0aDogMCxcbiAgaW5jcmVtZW50Qnk6IDEsXG4gIGN5Y2xlOiBmYWxzZSxcbn07XG5cbmV4cG9ydCBjb25zdCBCaWdJbnRTZXF1ZW5jZTogU2VxdWVuY2VPcHRpb25zID0ge1xuICB0eXBlOiBcIkJpZ0ludFwiLFxuICBzdGFydFdpdGg6IDAsXG4gIGluY3JlbWVudEJ5OiAxLFxuICBjeWNsZTogZmFsc2UsXG59O1xuIiwiZXhwb3J0IGVudW0gT3BlcmF0b3Ige1xuICBFUVVBTCA9IFwiRVFVQUxcIixcbiAgRElGRkVSRU5UID0gXCJESUZGRVJFTlRcIixcbiAgQklHR0VSID0gXCJCSUdHRVJcIixcbiAgQklHR0VSX0VRID0gXCJCSUdHRVJfRVFcIixcbiAgU01BTExFUiA9IFwiU01BTExFUlwiLFxuICBTTUFMTEVSX0VRID0gXCJTTUFMTEVSX0VRXCIsXG4gIC8vIEJFVFdFRU4gPSBcIkJFVFdFRU5cIixcbiAgTk9UID0gXCJOT1RcIixcbiAgSU4gPSBcIklOXCIsXG4gIC8vIElTID0gXCJJU1wiLFxuICBSRUdFWFAgPSBcIlJFR0VYUFwiLFxufVxuXG5leHBvcnQgZW51bSBHcm91cE9wZXJhdG9yIHtcbiAgQU5EID0gXCJBTkRcIixcbiAgT1IgPSBcIk9SXCIsXG59XG4iLCJpbXBvcnQgeyBCYXNlRXJyb3IgfSBmcm9tIFwiQGRlY2FmLXRzL2RiLWRlY29yYXRvcnNcIjtcblxuZXhwb3J0IGNsYXNzIFF1ZXJ5RXJyb3IgZXh0ZW5kcyBCYXNlRXJyb3Ige1xuICBjb25zdHJ1Y3Rvcihtc2c6IHN0cmluZyB8IEVycm9yKSB7XG4gICAgc3VwZXIoUXVlcnlFcnJvci5uYW1lLCBtc2csIDUwMCk7XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIFBhZ2luZ0Vycm9yIGV4dGVuZHMgQmFzZUVycm9yIHtcbiAgY29uc3RydWN0b3IobXNnOiBzdHJpbmcgfCBFcnJvcikge1xuICAgIHN1cGVyKFBhZ2luZ0Vycm9yLm5hbWUsIG1zZywgNTAwKTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgQXR0cmlidXRlT3B0aW9uLCBDb25kaXRpb25CdWlsZGVyT3B0aW9uIH0gZnJvbSBcIi4vb3B0aW9uc1wiO1xuaW1wb3J0IHtcbiAgTW9kZWwsXG4gIE1vZGVsRXJyb3JEZWZpbml0aW9uLFxuICByZXF1aXJlZCxcbn0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgR3JvdXBPcGVyYXRvciwgT3BlcmF0b3IgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IFF1ZXJ5RXJyb3IgfSBmcm9tIFwiLi9lcnJvcnNcIjtcblxuLyoqXG4gKiBAc3VtbWFyeSBDb25kaXRpb24gQ2xhc3NcbiAqIEBkZXNjcmlwdGlvbiBSZXByZXNlbnRzIGEgbG9naWNhbCBjb25kaXRpb25cbiAqXG4gKiBAcGFyYW0ge3N0cmluZyB8IENvbmRpdGlvbn0gYXR0cjFcbiAqIEBwYXJhbSB7T3BlcmF0b3IgfCBHcm91cE9wZXJhdG9yfSBvcGVyYXRvclxuICogQHBhcmFtIHtzdHJpbmcgfCBDb25kaXRpb259IGNvbXBhcmlzb25cbiAqXG4gKiBAY2xhc3MgQ29uZGl0aW9uXG4gKi9cbmV4cG9ydCBjbGFzcyBDb25kaXRpb248TSBleHRlbmRzIE1vZGVsPiBleHRlbmRzIE1vZGVsIHtcbiAgQHJlcXVpcmVkKClcbiAgcHJvdGVjdGVkIGF0dHIxPzogc3RyaW5nIHwgQ29uZGl0aW9uPE0+ID0gdW5kZWZpbmVkO1xuICBAcmVxdWlyZWQoKVxuICBwcm90ZWN0ZWQgb3BlcmF0b3I/OiBPcGVyYXRvciB8IEdyb3VwT3BlcmF0b3IgPSB1bmRlZmluZWQ7XG4gIEByZXF1aXJlZCgpXG4gIHByb3RlY3RlZCBjb21wYXJpc29uPzogYW55ID0gdW5kZWZpbmVkO1xuXG4gIHByaXZhdGUgY29uc3RydWN0b3IoXG4gICAgYXR0cjE6IHN0cmluZyB8IENvbmRpdGlvbjxNPixcbiAgICBvcGVyYXRvcjogT3BlcmF0b3IgfCBHcm91cE9wZXJhdG9yLFxuICAgIGNvbXBhcmlzb246IGFueVxuICApIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMuYXR0cjEgPSBhdHRyMTtcbiAgICB0aGlzLm9wZXJhdG9yID0gb3BlcmF0b3I7XG4gICAgdGhpcy5jb21wYXJpc29uID0gY29tcGFyaXNvbjtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBKb2lucyAyIHtAbGluayBDb25kaXRpb259cyBvbiBhbiB7QGxpbmsgT3BlcmF0b3IjQU5EfSBvcGVyYXRpb25cbiAgICogQHBhcmFtIHtDb25kaXRpb259IGNvbmRpdGlvblxuICAgKi9cbiAgYW5kKGNvbmRpdGlvbjogQ29uZGl0aW9uPE0+KTogQ29uZGl0aW9uPE0+IHtcbiAgICByZXR1cm4gQ29uZGl0aW9uLmFuZCh0aGlzLCBjb25kaXRpb24pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IEpvaW5zIDIge0BsaW5rIENvbmRpdGlvbn1zIG9uIGFuIHtAbGluayBPcGVyYXRvciNPUn0gb3BlcmF0aW9uXG4gICAqIEBwYXJhbSB7Q29uZGl0aW9ufSBjb25kaXRpb25cbiAgICovXG4gIG9yKGNvbmRpdGlvbjogQ29uZGl0aW9uPE0+KTogQ29uZGl0aW9uPE0+IHtcbiAgICByZXR1cm4gQ29uZGl0aW9uLm9yKHRoaXMsIGNvbmRpdGlvbik7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgZXhjbHVkZXMgYSB2YWx1dCBmcm9tIHRoZSByZXN1bHRcbiAgICogQHBhcmFtIHZhbFxuICAgKi9cbiAgbm90KHZhbDogYW55KTogQ29uZGl0aW9uPE0+IHtcbiAgICByZXR1cm4gbmV3IENvbmRpdGlvbih0aGlzLCBPcGVyYXRvci5OT1QsIHZhbCk7XG4gIH1cblxuICAvKipcbiAgICogQGluaGVyaXREb2NcbiAgICovXG4gIG92ZXJyaWRlIGhhc0Vycm9ycyhcbiAgICAuLi5leGNlcHRpb25zOiBzdHJpbmdbXVxuICApOiBNb2RlbEVycm9yRGVmaW5pdGlvbiB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgZXJyb3JzID0gc3VwZXIuaGFzRXJyb3JzKC4uLmV4Y2VwdGlvbnMpO1xuICAgIGlmIChlcnJvcnMpIHJldHVybiBlcnJvcnM7XG5cbiAgICBjb25zdCBpbnZhbGlkT3BNZXNzYWdlID0gYEludmFsaWQgb3BlcmF0b3IgJHt0aGlzLm9wZXJhdG9yfX1gO1xuXG4gICAgaWYgKHR5cGVvZiB0aGlzLmF0dHIxID09PSBcInN0cmluZ1wiKSB7XG4gICAgICBpZiAodGhpcy5jb21wYXJpc29uIGluc3RhbmNlb2YgQ29uZGl0aW9uKVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGNvbXBhcmlzb246IHtcbiAgICAgICAgICAgIGNvbmRpdGlvbjogXCJCb3RoIHNpZGVzIG9mIHRoZSBjb21wYXJpc29uIG11c3QgYmUgb2YgdGhlIHNhbWUgdHlwZVwiLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0gYXMgTW9kZWxFcnJvckRlZmluaXRpb247XG4gICAgICBpZiAoT2JqZWN0LnZhbHVlcyhPcGVyYXRvcikuaW5kZXhPZih0aGlzLm9wZXJhdG9yIGFzIE9wZXJhdG9yKSA9PT0gLTEpXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgb3BlcmF0b3I6IHtcbiAgICAgICAgICAgIGNvbmRpdGlvbjogaW52YWxpZE9wTWVzc2FnZSxcbiAgICAgICAgICB9LFxuICAgICAgICB9IGFzIE1vZGVsRXJyb3JEZWZpbml0aW9uO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmF0dHIxIGluc3RhbmNlb2YgQ29uZGl0aW9uKSB7XG4gICAgICBpZiAoXG4gICAgICAgICEodGhpcy5jb21wYXJpc29uIGluc3RhbmNlb2YgQ29uZGl0aW9uKSAmJlxuICAgICAgICB0aGlzLm9wZXJhdG9yICE9PSBPcGVyYXRvci5OT1RcbiAgICAgIClcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBjb21wYXJpc29uOiB7XG4gICAgICAgICAgICBjb25kaXRpb246IGludmFsaWRPcE1lc3NhZ2UsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSBhcyBNb2RlbEVycm9yRGVmaW5pdGlvbjtcbiAgICAgIGlmIChcbiAgICAgICAgT2JqZWN0LnZhbHVlcyhHcm91cE9wZXJhdG9yKS5pbmRleE9mKHRoaXMub3BlcmF0b3IgYXMgR3JvdXBPcGVyYXRvcikgPT09XG4gICAgICAgICAgLTEgJiZcbiAgICAgICAgdGhpcy5vcGVyYXRvciAhPT0gT3BlcmF0b3IuTk9UXG4gICAgICApXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgb3BlcmF0b3I6IHtcbiAgICAgICAgICAgIGNvbmRpdGlvbjogaW52YWxpZE9wTWVzc2FnZSxcbiAgICAgICAgICB9LFxuICAgICAgICB9IGFzIE1vZGVsRXJyb3JEZWZpbml0aW9uO1xuICAgICAgLy8gaWYgKHRoaXMub3BlcmF0b3IgIT09IE9wZXJhdG9yLk5PVCAmJiB0eXBlb2YgdGhpcy5hdHRyMS5hdHRyMSAhPT0gXCJzdHJpbmdcIilcbiAgICAgIC8vICAgICByZXR1cm4ge1xuICAgICAgLy8gICAgICAgICBhdHRyMToge1xuICAgICAgLy8gICAgICAgICAgICAgY29uZGl0aW9uOiBzdHJpbmdGb3JtYXQoXCJQYXJlbnQgY29uZGl0aW9uIGF0dHJpYnV0ZSBtdXN0IGJlIGEgc3RyaW5nXCIpXG4gICAgICAvLyAgICAgICAgIH1cbiAgICAgIC8vICAgICB9IGFzIE1vZGVsRXJyb3JEZWZpbml0aW9uXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IEpvaW5zIDIge0BsaW5rIENvbmRpdGlvbn1zIG9uIGFuIHtAbGluayBPcGVyYXRvciNBTkR9IG9wZXJhdGlvblxuICAgKiBAcGFyYW0ge0NvbmRpdGlvbn0gY29uZGl0aW9uMVxuICAgKiBAcGFyYW0ge0NvbmRpdGlvbn0gY29uZGl0aW9uMlxuICAgKi9cbiAgc3RhdGljIGFuZDxNIGV4dGVuZHMgTW9kZWw+KFxuICAgIGNvbmRpdGlvbjE6IENvbmRpdGlvbjxNPixcbiAgICBjb25kaXRpb24yOiBDb25kaXRpb248TT5cbiAgKTogQ29uZGl0aW9uPE0+IHtcbiAgICByZXR1cm4gQ29uZGl0aW9uLmdyb3VwKGNvbmRpdGlvbjEsIEdyb3VwT3BlcmF0b3IuQU5ELCBjb25kaXRpb24yKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBKb2lucyAyIHtAbGluayBDb25kaXRpb259cyBvbiBhbiB7QGxpbmsgT3BlcmF0b3IjT1J9IG9wZXJhdGlvblxuICAgKiBAcGFyYW0ge0NvbmRpdGlvbn0gY29uZGl0aW9uMVxuICAgKiBAcGFyYW0ge0NvbmRpdGlvbn0gY29uZGl0aW9uMlxuICAgKi9cbiAgc3RhdGljIG9yPE0gZXh0ZW5kcyBNb2RlbD4oXG4gICAgY29uZGl0aW9uMTogQ29uZGl0aW9uPE0+LFxuICAgIGNvbmRpdGlvbjI6IENvbmRpdGlvbjxNPlxuICApOiBDb25kaXRpb248TT4ge1xuICAgIHJldHVybiBDb25kaXRpb24uZ3JvdXAoY29uZGl0aW9uMSwgR3JvdXBPcGVyYXRvci5PUiwgY29uZGl0aW9uMik7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgR3JvdXBzIDIge0BsaW5rIENvbmRpdGlvbn1zIGJ5IHRoZSBzcGVjaWZpZWQge0BsaW5rIEdyb3VwT3BlcmF0b3J9XG4gICAqIEBwYXJhbSB7Q29uZGl0aW9ufSBjb25kaXRpb24xXG4gICAqIEBwYXJhbSB7R3JvdXBPcGVyYXRvcn0gb3BlcmF0b3JcbiAgICogQHBhcmFtIHtDb25kaXRpb259IGNvbmRpdGlvbjJcbiAgICovXG4gIHByaXZhdGUgc3RhdGljIGdyb3VwPE0gZXh0ZW5kcyBNb2RlbD4oXG4gICAgY29uZGl0aW9uMTogQ29uZGl0aW9uPE0+LFxuICAgIG9wZXJhdG9yOiBHcm91cE9wZXJhdG9yLFxuICAgIGNvbmRpdGlvbjI6IENvbmRpdGlvbjxNPlxuICApOiBDb25kaXRpb248TT4ge1xuICAgIHJldHVybiBuZXcgQ29uZGl0aW9uKGNvbmRpdGlvbjEsIG9wZXJhdG9yLCBjb25kaXRpb24yKTtcbiAgfVxuXG4gIHN0YXRpYyBhdHRyaWJ1dGU8TSBleHRlbmRzIE1vZGVsPihhdHRyOiBrZXlvZiBNKSB7XG4gICAgcmV0dXJuIG5ldyBDb25kaXRpb24uQnVpbGRlcjxNPigpLmF0dHJpYnV0ZShhdHRyKTtcbiAgfVxuXG4gIHN0YXRpYyBhdHRyPE0gZXh0ZW5kcyBNb2RlbD4oYXR0cjoga2V5b2YgTSkge1xuICAgIHJldHVybiB0aGlzLmF0dHJpYnV0ZShhdHRyKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBDb25kaXRpb24gQnVpbGRlciBDbGFzc1xuICAgKiBAZGVzY3JpcHRpb24gcHJvdmlkZXMgYSBzaW1wbGUgQVBJIHRvIGJ1aWxkIHtAbGluayBDb25kaXRpb259c1xuICAgKlxuICAgKiBAY2xhc3MgQ29uZGl0aW9uQnVpbGRlclxuICAgKiBAaW1wbGVtZW50cyBCdWlsZGVyXG4gICAqIEBpbXBsZW1lbnRzIEF0dHJpYnV0ZU9wdGlvblxuICAgKlxuICAgKiBAY2F0ZWdvcnkgUXVlcnlcbiAgICogQHN1YmNhdGVnb3J5IENvbmRpdGlvbnNcbiAgICovXG4gIHByaXZhdGUgc3RhdGljIEJ1aWxkZXIgPSBjbGFzcyBDb25kaXRpb25CdWlsZGVyPE0gZXh0ZW5kcyBNb2RlbD5cbiAgICBpbXBsZW1lbnRzIENvbmRpdGlvbkJ1aWxkZXJPcHRpb248TT4sIEF0dHJpYnV0ZU9wdGlvbjxNPlxuICB7XG4gICAgYXR0cjE/OiBrZXlvZiBNIHwgQ29uZGl0aW9uPE0+ID0gdW5kZWZpbmVkO1xuICAgIG9wZXJhdG9yPzogT3BlcmF0b3IgfCBHcm91cE9wZXJhdG9yID0gdW5kZWZpbmVkO1xuICAgIGNvbXBhcmlzb24/OiBhbnkgPSB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBAaW5oZXJpdERvY1xuICAgICAqL1xuICAgIGF0dHJpYnV0ZShhdHRyOiBrZXlvZiBNKTogQXR0cmlidXRlT3B0aW9uPE0+IHtcbiAgICAgIHRoaXMuYXR0cjEgPSBhdHRyO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgYXR0cihhdHRyOiBrZXlvZiBNKSB7XG4gICAgICByZXR1cm4gdGhpcy5hdHRyaWJ1dGUoYXR0cik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHN1bW1hcnkgQ3JlYXRlcyBhbiBFcXVhbGl0eSBDb21wYXJpc29uXG4gICAgICogQHBhcmFtIHthbnl9IHZhbFxuICAgICAqL1xuICAgIGVxKHZhbDogYW55KSB7XG4gICAgICByZXR1cm4gdGhpcy5zZXRPcChPcGVyYXRvci5FUVVBTCwgdmFsKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAc3VtbWFyeSBDcmVhdGVzIGEgRGlmZmVyZW50IENvbXBhcmlzb25cbiAgICAgKiBAcGFyYW0ge2FueX0gdmFsXG4gICAgICovXG4gICAgZGlmKHZhbDogYW55KSB7XG4gICAgICByZXR1cm4gdGhpcy5zZXRPcChPcGVyYXRvci5ESUZGRVJFTlQsIHZhbCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHN1bW1hcnkgQ3JlYXRlcyBhIEdyZWF0ZXIgVGhhbiBDb21wYXJpc29uXG4gICAgICogQHBhcmFtIHthbnl9IHZhbFxuICAgICAqL1xuICAgIGd0KHZhbDogYW55KSB7XG4gICAgICByZXR1cm4gdGhpcy5zZXRPcChPcGVyYXRvci5CSUdHRVIsIHZhbCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHN1bW1hcnkgQ3JlYXRlcyBhIExvd2VyIFRoYW4gQ29tcGFyaXNvblxuICAgICAqIEBwYXJhbSB7YW55fSB2YWxcbiAgICAgKi9cbiAgICBsdCh2YWw6IGFueSkge1xuICAgICAgcmV0dXJuIHRoaXMuc2V0T3AoT3BlcmF0b3IuU01BTExFUiwgdmFsKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAc3VtbWFyeSBDcmVhdGVzIGEgR3JlYXRlciBvciBFcXVhbCB0byBDb21wYXJpc29uXG4gICAgICogQHBhcmFtIHthbnl9IHZhbFxuICAgICAqL1xuICAgIGd0ZSh2YWw6IGFueSkge1xuICAgICAgcmV0dXJuIHRoaXMuc2V0T3AoT3BlcmF0b3IuQklHR0VSX0VRLCB2YWwpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBzdW1tYXJ5IENyZWF0ZXMgYSBMb3dlciBvciBFcXVhbCB0byBDb21wYXJpc29uXG4gICAgICogQHBhcmFtIHthbnl9IHZhbFxuICAgICAqL1xuICAgIGx0ZSh2YWw6IGFueSkge1xuICAgICAgcmV0dXJuIHRoaXMuc2V0T3AoT3BlcmF0b3IuU01BTExFUl9FUSwgdmFsKTtcbiAgICB9XG5cbiAgICBpbihhcnI6IGFueVtdKSB7XG4gICAgICByZXR1cm4gdGhpcy5zZXRPcChPcGVyYXRvci5JTiwgYXJyKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAc3VtbWFyeSBDcmVhdGVzIGEgUmVnZXhwbyBDb21wYXJpc29uXG4gICAgICogQHBhcmFtIHthbnl9IHZhbFxuICAgICAqL1xuICAgIHJlZ2V4cCh2YWw6IGFueSkge1xuICAgICAgcmV0dXJuIHRoaXMuc2V0T3AoT3BlcmF0b3IuUkVHRVhQLCBuZXcgUmVnRXhwKHZhbCkuc291cmNlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAc3VtbWFyeSBDcmVhdGVzIGFuIHtAbGluayBPcGVyYXRvcn0gYmFzZWQgQ29tcGFyaXNvblxuICAgICAqIEBwYXJhbSB7T3BlcmF0b3J9IG9wXG4gICAgICogQHBhcmFtIHthbnl9IHZhbFxuICAgICAqL1xuICAgIHByaXZhdGUgc2V0T3Aob3A6IE9wZXJhdG9yLCB2YWw6IGFueSkge1xuICAgICAgdGhpcy5vcGVyYXRvciA9IG9wO1xuICAgICAgdGhpcy5jb21wYXJpc29uID0gdmFsO1xuICAgICAgcmV0dXJuIHRoaXMuYnVpbGQoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAc3VtbWFyeSBCdWlsZHMgdGhlIERhdGFiYXNlIE9iamVjdFxuICAgICAqIEB0aHJvd3Mge1F1ZXJ5RXJyb3J9IGlmIGl0IGZhaWxzIHRvIGJ1aWxkIHRoZSB7QGxpbmsgQ29uZGl0aW9ufVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgcHJpdmF0ZSBidWlsZCgpOiBDb25kaXRpb248TT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIG5ldyBDb25kaXRpb24oXG4gICAgICAgICAgdGhpcy5hdHRyMSBhcyBzdHJpbmcgfCBDb25kaXRpb248TT4sXG4gICAgICAgICAgdGhpcy5vcGVyYXRvciBhcyBPcGVyYXRvcixcbiAgICAgICAgICB0aGlzLmNvbXBhcmlzb24gYXMgYW55XG4gICAgICAgICk7XG4gICAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgICAgdGhyb3cgbmV3IFF1ZXJ5RXJyb3IoZSk7XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIHN0YXRpYyBidWlsZGVyPE0gZXh0ZW5kcyBNb2RlbD4oKTogQ29uZGl0aW9uQnVpbGRlck9wdGlvbjxNPiB7XG4gICAgcmV0dXJuIG5ldyBDb25kaXRpb24uQnVpbGRlcjxNPigpO1xuICB9XG59XG4iLCJpbXBvcnQge1xuICBDb25zdHJ1Y3RvcixcbiAgTW9kZWwsXG4gIE1vZGVsQ29uc3RydWN0b3IsXG4gIFZhbGlkYXRpb24sXG4gIFZhbGlkYXRpb25LZXlzLFxufSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBSZXBvLCBSZXBvc2l0b3J5IH0gZnJvbSBcIi4uL3JlcG9zaXRvcnkvUmVwb3NpdG9yeVwiO1xuaW1wb3J0IHsgUmVsYXRpb25zTWV0YWRhdGEgfSBmcm9tIFwiLi90eXBlc1wiO1xuaW1wb3J0IHtcbiAgZmluZFByaW1hcnlLZXksXG4gIEludGVybmFsRXJyb3IsXG4gIE5vdEZvdW5kRXJyb3IsXG4gIFJlcG9zaXRvcnlGbGFncyxcbn0gZnJvbSBcIkBkZWNhZi10cy9kYi1kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBQZXJzaXN0ZW5jZUtleXMgfSBmcm9tIFwiLi4vcGVyc2lzdGVuY2UvY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBDYXNjYWRlIH0gZnJvbSBcIi4uL3JlcG9zaXRvcnkvY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBDb250ZXh0IH0gZnJvbSBcIkBkZWNhZi10cy9kYi1kZWNvcmF0b3JzXCI7XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjcmVhdGVPclVwZGF0ZTxcbiAgTSBleHRlbmRzIE1vZGVsLFxuICBGIGV4dGVuZHMgUmVwb3NpdG9yeUZsYWdzLFxuPihcbiAgbW9kZWw6IE0sXG4gIGNvbnRleHQ6IENvbnRleHQ8Rj4sXG4gIHJlcG9zaXRvcnk/OiBSZXBvPE0sIEYsIENvbnRleHQ8Rj4+XG4pOiBQcm9taXNlPE0+IHtcbiAgaWYgKCFyZXBvc2l0b3J5KSB7XG4gICAgY29uc3QgY29uc3RydWN0b3IgPSBNb2RlbC5nZXQobW9kZWwuY29uc3RydWN0b3IubmFtZSk7XG4gICAgaWYgKCFjb25zdHJ1Y3RvcilcbiAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKGBDb3VsZCBub3QgZmluZCBtb2RlbCAke21vZGVsLmNvbnN0cnVjdG9yLm5hbWV9YCk7XG4gICAgcmVwb3NpdG9yeSA9IFJlcG9zaXRvcnkuZm9yTW9kZWw8TSwgUmVwbzxNPj4oXG4gICAgICBjb25zdHJ1Y3RvciBhcyB1bmtub3duIGFzIE1vZGVsQ29uc3RydWN0b3I8TT5cbiAgICApO1xuICB9XG4gIGlmICh0eXBlb2YgbW9kZWxbcmVwb3NpdG9yeS5wa10gPT09IFwidW5kZWZpbmVkXCIpXG4gICAgcmV0dXJuIHJlcG9zaXRvcnkuY3JlYXRlKG1vZGVsLCBjb250ZXh0KTtcbiAgZWxzZSB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiByZXBvc2l0b3J5LnVwZGF0ZShtb2RlbCwgY29udGV4dCk7XG4gICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICBpZiAoIShlIGluc3RhbmNlb2YgTm90Rm91bmRFcnJvcikpIHRocm93IGU7XG4gICAgICByZXR1cm4gcmVwb3NpdG9yeS5jcmVhdGUobW9kZWwsIGNvbnRleHQpO1xuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gb25lVG9PbmVPbkNyZWF0ZTxcbiAgTSBleHRlbmRzIE1vZGVsLFxuICBSIGV4dGVuZHMgUmVwbzxNLCBGLCBDPixcbiAgViBleHRlbmRzIFJlbGF0aW9uc01ldGFkYXRhLFxuICBGIGV4dGVuZHMgUmVwb3NpdG9yeUZsYWdzLFxuICBDIGV4dGVuZHMgQ29udGV4dDxGPixcbj4oXG4gIHRoaXM6IFIsXG4gIGNvbnRleHQ6IENvbnRleHQ8Rj4sXG4gIGRhdGE6IFYsXG4gIGtleToga2V5b2YgTSxcbiAgbW9kZWw6IE1cbik6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCBwcm9wZXJ0eVZhbHVlOiBhbnkgPSBtb2RlbFtrZXldO1xuICBpZiAoIXByb3BlcnR5VmFsdWUpIHJldHVybjtcblxuICBpZiAodHlwZW9mIHByb3BlcnR5VmFsdWUgIT09IFwib2JqZWN0XCIpIHtcbiAgICBjb25zdCBpbm5lclJlcG8gPSByZXBvc2l0b3J5RnJvbVR5cGVNZXRhZGF0YShtb2RlbCwga2V5KTtcbiAgICBjb25zdCByZWFkID0gYXdhaXQgaW5uZXJSZXBvLnJlYWQocHJvcGVydHlWYWx1ZSk7XG4gICAgYXdhaXQgY2FjaGVNb2RlbEZvclBvcHVsYXRlKGNvbnRleHQsIG1vZGVsLCBrZXksIHByb3BlcnR5VmFsdWUsIHJlYWQpO1xuICAgIChtb2RlbCBhcyBhbnkpW2tleV0gPSBwcm9wZXJ0eVZhbHVlO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGNvbnN0IGNvbnN0cnVjdG9yID0gTW9kZWwuZ2V0KGRhdGEuY2xhc3MpO1xuICBpZiAoIWNvbnN0cnVjdG9yKVxuICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKGBDb3VsZCBub3QgZmluZCBtb2RlbCAke2RhdGEuY2xhc3N9YCk7XG4gIGNvbnN0IHJlcG86IFJlcG88YW55PiA9IFJlcG9zaXRvcnkuZm9yTW9kZWwoY29uc3RydWN0b3IpO1xuICBjb25zdCBjcmVhdGVkID0gYXdhaXQgcmVwby5jcmVhdGUocHJvcGVydHlWYWx1ZSk7XG4gIGNvbnN0IHBrID0gZmluZFByaW1hcnlLZXkoY3JlYXRlZCkuaWQ7XG4gIGF3YWl0IGNhY2hlTW9kZWxGb3JQb3B1bGF0ZShjb250ZXh0LCBtb2RlbCwga2V5LCBjcmVhdGVkW3BrXSwgY3JlYXRlZCk7XG4gIChtb2RlbCBhcyBhbnkpW2tleV0gPSBjcmVhdGVkW3BrXTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIG9uZVRvT25lT25VcGRhdGU8XG4gIE0gZXh0ZW5kcyBNb2RlbCxcbiAgUiBleHRlbmRzIFJlcG88TSwgRiwgQz4sXG4gIFYgZXh0ZW5kcyBSZWxhdGlvbnNNZXRhZGF0YSxcbiAgRiBleHRlbmRzIFJlcG9zaXRvcnlGbGFncyxcbiAgQyBleHRlbmRzIENvbnRleHQ8Rj4sXG4+KFxuICB0aGlzOiBSLFxuICBjb250ZXh0OiBDb250ZXh0PEY+LFxuICBkYXRhOiBWLFxuICBrZXk6IGtleW9mIE0sXG4gIG1vZGVsOiBNXG4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgcHJvcGVydHlWYWx1ZTogYW55ID0gbW9kZWxba2V5XTtcbiAgaWYgKCFwcm9wZXJ0eVZhbHVlKSByZXR1cm47XG4gIGlmIChkYXRhLmNhc2NhZGUudXBkYXRlICE9PSBDYXNjYWRlLkNBU0NBREUpIHJldHVybjtcblxuICBpZiAodHlwZW9mIHByb3BlcnR5VmFsdWUgIT09IFwib2JqZWN0XCIpIHtcbiAgICBjb25zdCBpbm5lclJlcG8gPSByZXBvc2l0b3J5RnJvbVR5cGVNZXRhZGF0YShtb2RlbCwga2V5KTtcbiAgICBjb25zdCByZWFkID0gYXdhaXQgaW5uZXJSZXBvLnJlYWQocHJvcGVydHlWYWx1ZSk7XG4gICAgYXdhaXQgY2FjaGVNb2RlbEZvclBvcHVsYXRlKGNvbnRleHQsIG1vZGVsLCBrZXksIHByb3BlcnR5VmFsdWUsIHJlYWQpO1xuICAgIChtb2RlbCBhcyBhbnkpW2tleV0gPSBwcm9wZXJ0eVZhbHVlO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGNvbnN0IHVwZGF0ZWQgPSBhd2FpdCBjcmVhdGVPclVwZGF0ZShtb2RlbFtrZXldIGFzIE0sIGNvbnRleHQpO1xuICBjb25zdCBwayA9IGZpbmRQcmltYXJ5S2V5KHVwZGF0ZWQpLmlkO1xuICBhd2FpdCBjYWNoZU1vZGVsRm9yUG9wdWxhdGUoXG4gICAgY29udGV4dCxcbiAgICBtb2RlbCxcbiAgICBrZXksXG4gICAgdXBkYXRlZFtwa10gYXMgc3RyaW5nLFxuICAgIHVwZGF0ZWRcbiAgKTtcbiAgbW9kZWxba2V5XSA9IHVwZGF0ZWRbcGtdO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gb25lVG9PbmVPbkRlbGV0ZTxcbiAgTSBleHRlbmRzIE1vZGVsLFxuICBSIGV4dGVuZHMgUmVwbzxNLCBGLCBDPixcbiAgViBleHRlbmRzIFJlbGF0aW9uc01ldGFkYXRhLFxuICBGIGV4dGVuZHMgUmVwb3NpdG9yeUZsYWdzLFxuICBDIGV4dGVuZHMgQ29udGV4dDxGPixcbj4oXG4gIHRoaXM6IFIsXG4gIGNvbnRleHQ6IENvbnRleHQ8Rj4sXG4gIGRhdGE6IFYsXG4gIGtleToga2V5b2YgTSxcbiAgbW9kZWw6IE1cbik6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCBwcm9wZXJ0eVZhbHVlOiBhbnkgPSBtb2RlbFtrZXldO1xuICBpZiAoIXByb3BlcnR5VmFsdWUpIHJldHVybjtcbiAgaWYgKGRhdGEuY2FzY2FkZS51cGRhdGUgIT09IENhc2NhZGUuQ0FTQ0FERSkgcmV0dXJuO1xuICBjb25zdCBpbm5lclJlcG86IFJlcG88TT4gPSByZXBvc2l0b3J5RnJvbVR5cGVNZXRhZGF0YShtb2RlbCwga2V5KTtcbiAgbGV0IGRlbGV0ZWQ6IE07XG4gIGlmICghKHByb3BlcnR5VmFsdWUgaW5zdGFuY2VvZiBNb2RlbCkpXG4gICAgZGVsZXRlZCA9IGF3YWl0IGlubmVyUmVwby5kZWxldGUobW9kZWxba2V5XSBhcyBzdHJpbmcsIGNvbnRleHQpO1xuICBlbHNlXG4gICAgZGVsZXRlZCA9IGF3YWl0IGlubmVyUmVwby5kZWxldGUoXG4gICAgICAobW9kZWxba2V5XSBhcyBNKVtpbm5lclJlcG8ucGsgYXMga2V5b2YgTV0gYXMgc3RyaW5nLFxuICAgICAgY29udGV4dFxuICAgICk7XG4gIGF3YWl0IGNhY2hlTW9kZWxGb3JQb3B1bGF0ZShcbiAgICBjb250ZXh0LFxuICAgIG1vZGVsLFxuICAgIGtleSxcbiAgICBkZWxldGVkW2lubmVyUmVwby5wa10gYXMgc3RyaW5nLFxuICAgIGRlbGV0ZWRcbiAgKTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIG9uZVRvTWFueU9uQ3JlYXRlPFxuICBNIGV4dGVuZHMgTW9kZWwsXG4gIFIgZXh0ZW5kcyBSZXBvPE0sIEYsIEM+LFxuICBWIGV4dGVuZHMgUmVsYXRpb25zTWV0YWRhdGEsXG4gIEYgZXh0ZW5kcyBSZXBvc2l0b3J5RmxhZ3MsXG4gIEMgZXh0ZW5kcyBDb250ZXh0PEY+LFxuPihcbiAgdGhpczogUixcbiAgY29udGV4dDogQ29udGV4dDxGPixcbiAgZGF0YTogVixcbiAga2V5OiBrZXlvZiBNLFxuICBtb2RlbDogTVxuKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IHByb3BlcnR5VmFsdWVzOiBhbnkgPSBtb2RlbFtrZXldO1xuICBpZiAoIXByb3BlcnR5VmFsdWVzIHx8ICFwcm9wZXJ0eVZhbHVlcy5sZW5ndGgpIHJldHVybjtcbiAgY29uc3QgYXJyYXlUeXBlID0gdHlwZW9mIHByb3BlcnR5VmFsdWVzWzBdO1xuICBpZiAoIXByb3BlcnR5VmFsdWVzLmV2ZXJ5KChpdGVtOiBhbnkpID0+IHR5cGVvZiBpdGVtID09PSBhcnJheVR5cGUpKVxuICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFxuICAgICAgYEludmFsaWQgb3BlcmF0aW9uLiBBbGwgZWxlbWVudHMgb2YgcHJvcGVydHkgJHtrZXkgYXMgc3RyaW5nfSBtdXN0IG1hdGNoIHRoZSBzYW1lIHR5cGUuYFxuICAgICk7XG4gIGNvbnN0IHVuaXF1ZVZhbHVlcyA9IG5ldyBTZXQoWy4uLnByb3BlcnR5VmFsdWVzXSk7XG4gIGlmIChhcnJheVR5cGUgIT09IFwib2JqZWN0XCIpIHtcbiAgICBjb25zdCByZXBvID0gcmVwb3NpdG9yeUZyb21UeXBlTWV0YWRhdGEobW9kZWwsIGtleSk7XG4gICAgZm9yIChjb25zdCBpZCBvZiB1bmlxdWVWYWx1ZXMpIHtcbiAgICAgIGNvbnN0IHJlYWQgPSBhd2FpdCByZXBvLnJlYWQoaWQpO1xuICAgICAgYXdhaXQgY2FjaGVNb2RlbEZvclBvcHVsYXRlKGNvbnRleHQsIG1vZGVsLCBrZXksIGlkLCByZWFkKTtcbiAgICB9XG4gICAgKG1vZGVsIGFzIGFueSlba2V5XSA9IFsuLi51bmlxdWVWYWx1ZXNdO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGNvbnN0IHBrTmFtZSA9IGZpbmRQcmltYXJ5S2V5KHByb3BlcnR5VmFsdWVzWzBdKS5pZDtcblxuICBjb25zdCByZXN1bHQ6IFNldDxzdHJpbmc+ID0gbmV3IFNldCgpO1xuXG4gIGZvciAoY29uc3QgbSBvZiBwcm9wZXJ0eVZhbHVlcykge1xuICAgIGNvbnN0IHJlY29yZCA9IGF3YWl0IGNyZWF0ZU9yVXBkYXRlKG0sIGNvbnRleHQpO1xuICAgIGF3YWl0IGNhY2hlTW9kZWxGb3JQb3B1bGF0ZShjb250ZXh0LCBtb2RlbCwga2V5LCByZWNvcmRbcGtOYW1lXSwgcmVjb3JkKTtcbiAgICByZXN1bHQuYWRkKHJlY29yZFtwa05hbWVdKTtcbiAgfVxuXG4gIChtb2RlbCBhcyBhbnkpW2tleV0gPSBbLi4ucmVzdWx0XTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIG9uZVRvTWFueU9uVXBkYXRlPFxuICBNIGV4dGVuZHMgTW9kZWwsXG4gIFIgZXh0ZW5kcyBSZXBvPE0sIEYsIEM+LFxuICBWIGV4dGVuZHMgUmVsYXRpb25zTWV0YWRhdGEsXG4gIEYgZXh0ZW5kcyBSZXBvc2l0b3J5RmxhZ3MsXG4gIEMgZXh0ZW5kcyBDb250ZXh0PEY+LFxuPihcbiAgdGhpczogUixcbiAgY29udGV4dDogQ29udGV4dDxGPixcbiAgZGF0YTogVixcbiAga2V5OiBrZXlvZiBNLFxuICBtb2RlbDogTVxuKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IHsgY2FzY2FkZSB9ID0gZGF0YTtcbiAgaWYgKGNhc2NhZGUudXBkYXRlICE9PSBDYXNjYWRlLkNBU0NBREUpIHJldHVybjtcbiAgcmV0dXJuIG9uZVRvTWFueU9uQ3JlYXRlLmFwcGx5KHRoaXMgYXMgYW55LCBbXG4gICAgY29udGV4dCxcbiAgICBkYXRhLFxuICAgIGtleSBhcyBrZXlvZiBNb2RlbCxcbiAgICBtb2RlbCxcbiAgXSk7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBvbmVUb01hbnlPbkRlbGV0ZTxcbiAgTSBleHRlbmRzIE1vZGVsLFxuICBSIGV4dGVuZHMgUmVwbzxNLCBGLCBDPixcbiAgViBleHRlbmRzIFJlbGF0aW9uc01ldGFkYXRhLFxuICBGIGV4dGVuZHMgUmVwb3NpdG9yeUZsYWdzLFxuICBDIGV4dGVuZHMgQ29udGV4dDxGPixcbj4oXG4gIHRoaXM6IFIsXG4gIGNvbnRleHQ6IENvbnRleHQ8Rj4sXG4gIGRhdGE6IFYsXG4gIGtleToga2V5b2YgTSxcbiAgbW9kZWw6IE1cbik6IFByb21pc2U8dm9pZD4ge1xuICBpZiAoZGF0YS5jYXNjYWRlLmRlbGV0ZSAhPT0gQ2FzY2FkZS5DQVNDQURFKSByZXR1cm47XG4gIGNvbnN0IHZhbHVlcyA9IG1vZGVsW2tleV0gYXMgYW55O1xuICBpZiAoIXZhbHVlcyB8fCAhdmFsdWVzLmxlbmd0aCkgcmV0dXJuO1xuICBjb25zdCBhcnJheVR5cGUgPSB0eXBlb2YgdmFsdWVzWzBdO1xuICBjb25zdCBhcmVBbGxTYW1lVHlwZSA9IHZhbHVlcy5ldmVyeSgoaXRlbTogYW55KSA9PiB0eXBlb2YgaXRlbSA9PT0gYXJyYXlUeXBlKTtcbiAgaWYgKCFhcmVBbGxTYW1lVHlwZSlcbiAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcbiAgICAgIGBJbnZhbGlkIG9wZXJhdGlvbi4gQWxsIGVsZW1lbnRzIG9mIHByb3BlcnR5ICR7a2V5IGFzIHN0cmluZ30gbXVzdCBtYXRjaCB0aGUgc2FtZSB0eXBlLmBcbiAgICApO1xuICBjb25zdCBpc0luc3RhbnRpYXRlZCA9IGFycmF5VHlwZSA9PT0gXCJvYmplY3RcIjtcbiAgY29uc3QgcmVwbyA9IGlzSW5zdGFudGlhdGVkXG4gICAgPyBSZXBvc2l0b3J5LmZvck1vZGVsKHZhbHVlc1swXSlcbiAgICA6IHJlcG9zaXRvcnlGcm9tVHlwZU1ldGFkYXRhKG1vZGVsLCBrZXkpO1xuXG4gIGNvbnN0IHVuaXF1ZVZhbHVlcyA9IG5ldyBTZXQoW1xuICAgIC4uLihpc0luc3RhbnRpYXRlZFxuICAgICAgPyB2YWx1ZXMubWFwKCh2OiBSZWNvcmQ8c3RyaW5nLCBhbnk+KSA9PiB2W3JlcG8ucGsgYXMgc3RyaW5nXSlcbiAgICAgIDogdmFsdWVzKSxcbiAgXSk7XG5cbiAgZm9yIChjb25zdCBpZCBvZiB1bmlxdWVWYWx1ZXMudmFsdWVzKCkpIHtcbiAgICBjb25zdCBkZWxldGVkID0gYXdhaXQgcmVwby5kZWxldGUoaWQsIGNvbnRleHQpO1xuICAgIGF3YWl0IGNhY2hlTW9kZWxGb3JQb3B1bGF0ZShjb250ZXh0LCBtb2RlbCwga2V5LCBpZCwgZGVsZXRlZCk7XG4gIH1cbiAgKG1vZGVsIGFzIGFueSlba2V5XSA9IFsuLi51bmlxdWVWYWx1ZXNdO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0UG9wdWxhdGVLZXkoXG4gIHRhYmxlTmFtZTogc3RyaW5nLFxuICBmaWVsZE5hbWU6IHN0cmluZyxcbiAgaWQ6IHN0cmluZyB8IG51bWJlclxuKSB7XG4gIHJldHVybiBbUGVyc2lzdGVuY2VLZXlzLlBPUFVMQVRFLCB0YWJsZU5hbWUsIGZpZWxkTmFtZSwgaWRdLmpvaW4oXCIuXCIpO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gY2FjaGVNb2RlbEZvclBvcHVsYXRlPFxuICBNIGV4dGVuZHMgTW9kZWwsXG4gIEYgZXh0ZW5kcyBSZXBvc2l0b3J5RmxhZ3MsXG4+KFxuICBjb250ZXh0OiBDb250ZXh0PEY+LFxuICBwYXJlbnRNb2RlbDogTSxcbiAgcHJvcGVydHlLZXk6IGtleW9mIE0gfCBzdHJpbmcsXG4gIHBrVmFsdWU6IHN0cmluZyB8IG51bWJlcixcbiAgY2FjaGVWYWx1ZTogYW55XG4pIHtcbiAgY29uc3QgY2FjaGVLZXkgPSBnZXRQb3B1bGF0ZUtleShcbiAgICBwYXJlbnRNb2RlbC5jb25zdHJ1Y3Rvci5uYW1lLFxuICAgIHByb3BlcnR5S2V5IGFzIHN0cmluZyxcbiAgICBwa1ZhbHVlXG4gICk7XG4gIHJldHVybiBjb250ZXh0LmFjY3VtdWxhdGUoeyBbY2FjaGVLZXldOiBjYWNoZVZhbHVlIH0pO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcG9wdWxhdGU8XG4gIE0gZXh0ZW5kcyBNb2RlbCxcbiAgUiBleHRlbmRzIFJlcG88TSwgRiwgQz4sXG4gIFYgZXh0ZW5kcyBSZWxhdGlvbnNNZXRhZGF0YSxcbiAgRiBleHRlbmRzIFJlcG9zaXRvcnlGbGFncyxcbiAgQyBleHRlbmRzIENvbnRleHQ8Rj4sXG4+KFxuICB0aGlzOiBSLFxuICBjb250ZXh0OiBDb250ZXh0PEY+LFxuICBkYXRhOiBWLFxuICBrZXk6IGtleW9mIE0sXG4gIG1vZGVsOiBNXG4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgaWYgKCFkYXRhLnBvcHVsYXRlKSByZXR1cm47XG4gIGNvbnN0IG5lc3RlZDogYW55ID0gbW9kZWxba2V5XTtcbiAgY29uc3QgaXNBcnIgPSBBcnJheS5pc0FycmF5KG5lc3RlZCk7XG4gIGlmICh0eXBlb2YgbmVzdGVkID09PSBcInVuZGVmaW5lZFwiIHx8IChpc0FyciAmJiBuZXN0ZWQubGVuZ3RoID09PSAwKSkgcmV0dXJuO1xuXG4gIGFzeW5jIGZ1bmN0aW9uIGZldGNoUG9wdWxhdGVWYWx1ZXMoXG4gICAgYzogQ29udGV4dDxGPixcbiAgICBtb2RlbDogTSxcbiAgICBwcm9wTmFtZTogc3RyaW5nLFxuICAgIHByb3BLZXlWYWx1ZXM6IGFueVtdXG4gICkge1xuICAgIGxldCBjYWNoZUtleTogc3RyaW5nO1xuICAgIGxldCB2YWw6IGFueTtcbiAgICBjb25zdCByZXN1bHRzOiBNW10gPSBbXTtcbiAgICBmb3IgKGNvbnN0IHByb0tleVZhbHVlIG9mIHByb3BLZXlWYWx1ZXMpIHtcbiAgICAgIGNhY2hlS2V5ID0gZ2V0UG9wdWxhdGVLZXkobW9kZWwuY29uc3RydWN0b3IubmFtZSwgcHJvcE5hbWUsIHByb0tleVZhbHVlKTtcbiAgICAgIHRyeSB7XG4gICAgICAgIHZhbCA9IGF3YWl0IGMuZ2V0KGNhY2hlS2V5IGFzIGFueSk7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgICBjb25zdCByZXBvID0gcmVwb3NpdG9yeUZyb21UeXBlTWV0YWRhdGEobW9kZWwsIHByb3BOYW1lKTtcbiAgICAgICAgaWYgKCFyZXBvKSB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcIkNvdWxkIG5vdCBmaW5kIHJlcG9cIik7XG4gICAgICAgIHZhbCA9IGF3YWl0IHJlcG8ucmVhZChwcm9LZXlWYWx1ZSk7XG4gICAgICB9XG4gICAgICByZXN1bHRzLnB1c2godmFsKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdHM7XG4gIH1cbiAgY29uc3QgcmVzID0gYXdhaXQgZmV0Y2hQb3B1bGF0ZVZhbHVlcyhcbiAgICBjb250ZXh0LFxuICAgIG1vZGVsLFxuICAgIGtleSBhcyBzdHJpbmcsXG4gICAgaXNBcnIgPyBuZXN0ZWQgOiBbbmVzdGVkXVxuICApO1xuICAobW9kZWwgYXMgYW55KVtrZXldID0gaXNBcnIgPyByZXMgOiByZXNbMF07XG59XG5cbmNvbnN0IGNvbW1vbVR5cGVzID0gW1xuICBcImFycmF5XCIsXG4gIFwic3RyaW5nXCIsXG4gIFwibnVtYmVyXCIsXG4gIFwiYm9vbGVhblwiLFxuICBcInN5bWJvbFwiLFxuICBcImZ1bmN0aW9uXCIsXG4gIFwib2JqZWN0XCIsXG4gIFwidW5kZWZpbmVkXCIsXG4gIFwibnVsbFwiLFxuICBcImJpZ2ludFwiLFxuXTtcblxuZXhwb3J0IGZ1bmN0aW9uIHJlcG9zaXRvcnlGcm9tVHlwZU1ldGFkYXRhPE0gZXh0ZW5kcyBNb2RlbD4oXG4gIG1vZGVsOiBhbnksXG4gIHByb3BlcnR5S2V5OiBzdHJpbmcgfCBrZXlvZiBNXG4pOiBSZXBvPE0+IHtcbiAgY29uc3QgdHlwZXMgPSBSZWZsZWN0LmdldE1ldGFkYXRhKFxuICAgIFZhbGlkYXRpb24ua2V5KFxuICAgICAgQXJyYXkuaXNBcnJheShtb2RlbFtwcm9wZXJ0eUtleV0pXG4gICAgICAgID8gVmFsaWRhdGlvbktleXMuTElTVFxuICAgICAgICA6IFZhbGlkYXRpb25LZXlzLlRZUEVcbiAgICApLFxuICAgIG1vZGVsLFxuICAgIHByb3BlcnR5S2V5IGFzIHN0cmluZ1xuICApO1xuICBjb25zdCBjdXN0b21UeXBlczogYW55ID0gQXJyYXkuaXNBcnJheShtb2RlbFtwcm9wZXJ0eUtleV0pXG4gICAgPyB0eXBlcy5jbGF6elxuICAgIDogdHlwZXMuY3VzdG9tVHlwZXM7XG4gIGlmICghdHlwZXMgfHwgIWN1c3RvbVR5cGVzKVxuICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFxuICAgICAgYEZhaWxlZCB0byBmaW5kIHR5cGVzIGRlY29yYXRvcnMgZm9yIHByb3BlcnR5ICR7cHJvcGVydHlLZXkgYXMgc3RyaW5nfWBcbiAgICApO1xuXG4gIGNvbnN0IGFsbG93ZWRUeXBlczogc3RyaW5nW10gPSBBcnJheS5pc0FycmF5KGN1c3RvbVR5cGVzKVxuICAgID8gWy4uLmN1c3RvbVR5cGVzXVxuICAgIDogW2N1c3RvbVR5cGVzXTtcbiAgY29uc3QgY29uc3RydWN0b3JOYW1lID0gYWxsb3dlZFR5cGVzLmZpbmQoXG4gICAgKHQpID0+ICFjb21tb21UeXBlcy5pbmNsdWRlcyhgJHt0fWAudG9Mb3dlckNhc2UoKSlcbiAgKTtcbiAgaWYgKCFjb25zdHJ1Y3Rvck5hbWUpXG4gICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXG4gICAgICBgUHJvcGVydHkga2V5ICR7cHJvcGVydHlLZXkgYXMgc3RyaW5nfSBkb2VzIG5vdCBoYXZlIGEgdmFsaWQgY29uc3RydWN0b3IgdHlwZWBcbiAgICApO1xuICBjb25zdCBjb25zdHJ1Y3RvcjogQ29uc3RydWN0b3I8TT4gfCB1bmRlZmluZWQgPSBNb2RlbC5nZXQoY29uc3RydWN0b3JOYW1lKTtcbiAgaWYgKCFjb25zdHJ1Y3RvcilcbiAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihgTm8gcmVnaXN0ZXJlZCBtb2RlbCBmb3VuZCBmb3IgJHtjb25zdHJ1Y3Rvck5hbWV9YCk7XG5cbiAgcmV0dXJuIFJlcG9zaXRvcnkuZm9yTW9kZWwoY29uc3RydWN0b3IpO1xufVxuIiwiaW1wb3J0IHtcbiAgQ29uZmxpY3RFcnJvcixcbiAgb25DcmVhdGUsXG4gIG9uQ3JlYXRlVXBkYXRlLFxuICBvbkRlbGV0ZSxcbiAgb25VcGRhdGUsXG4gIGFmdGVyQW55LFxuICBSZXBvc2l0b3J5RmxhZ3MsXG4gIENvbnRleHQsXG59IGZyb20gXCJAZGVjYWYtdHMvZGItZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHsgYXBwbHksIG1ldGFkYXRhIH0gZnJvbSBcIkBkZWNhZi10cy9yZWZsZWN0aW9uXCI7XG5pbXBvcnQgeyBQZXJzaXN0ZW5jZUtleXMgfSBmcm9tIFwiLi4vcGVyc2lzdGVuY2UvY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBDYXNjYWRlTWV0YWRhdGEsIEluZGV4TWV0YWRhdGEgfSBmcm9tIFwiLi4vcmVwb3NpdG9yeS90eXBlc1wiO1xuaW1wb3J0IHsgRGVmYXVsdENhc2NhZGUsIE9yZGVyRGlyZWN0aW9uIH0gZnJvbSBcIi4uL3JlcG9zaXRvcnkvY29uc3RhbnRzXCI7XG5pbXBvcnQge1xuICBDb25zdHJ1Y3RvcixcbiAgRGVjb3JhdGlvbixcbiAgbGlzdCxcbiAgTW9kZWwsXG4gIHByb3AsXG4gIHByb3BNZXRhZGF0YSxcbiAgdHlwZSxcbn0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgQWRhcHRlciB9IGZyb20gXCIuLi9wZXJzaXN0ZW5jZS9BZGFwdGVyXCI7XG5pbXBvcnQgeyBSZXBvLCBSZXBvc2l0b3J5IH0gZnJvbSBcIi4uL3JlcG9zaXRvcnkvUmVwb3NpdG9yeVwiO1xuaW1wb3J0IHsgQ29uZGl0aW9uIH0gZnJvbSBcIi4uL3F1ZXJ5L0NvbmRpdGlvblwiO1xuaW1wb3J0IHsgUmVsYXRpb25zTWV0YWRhdGEgfSBmcm9tIFwiLi90eXBlc1wiO1xuaW1wb3J0IHtcbiAgb25lVG9NYW55T25DcmVhdGUsXG4gIG9uZVRvTWFueU9uRGVsZXRlLFxuICBvbmVUb01hbnlPblVwZGF0ZSxcbiAgb25lVG9PbmVPbkNyZWF0ZSxcbiAgb25lVG9PbmVPbkRlbGV0ZSxcbiAgb25lVG9PbmVPblVwZGF0ZSxcbiAgcG9wdWxhdGUgYXMgcG9wLFxufSBmcm9tIFwiLi9jb25zdHJ1Y3Rpb25cIjtcbmltcG9ydCB7IEF1dGhvcml6YXRpb25FcnJvciB9IGZyb20gXCIuLi91dGlsc1wiO1xuXG5leHBvcnQgZnVuY3Rpb24gdGFibGUodGFibGVOYW1lOiBzdHJpbmcpIHtcbiAgcmV0dXJuIG1ldGFkYXRhKEFkYXB0ZXIua2V5KFBlcnNpc3RlbmNlS2V5cy5UQUJMRSksIHRhYmxlTmFtZSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjb2x1bW4oY29sdW1uTmFtZTogc3RyaW5nKSB7XG4gIHJldHVybiBwcm9wTWV0YWRhdGEoQWRhcHRlci5rZXkoUGVyc2lzdGVuY2VLZXlzLkNPTFVNTiksIGNvbHVtbk5hbWUpO1xufVxuXG4vKipcbiAqIEBzdW1tYXJ5IEluZGV4IERlY29yYXRvclxuICogQGRlc2NyaXB0aW9uIHByb3BlcnRpZXMgZGVjb3JhdGVkIHdpbGwgdGhlIGluZGV4IGluIHRoZVxuICogREIgZm9yIHBlcmZvcm1hbmNlIGluIHF1ZXJpZXNcbiAqXG4gKiBAcGFyYW0ge09yZGVyRGlyZWN0aW9uW119IFtkaXJlY3Rpb25zXVxuICogQHBhcmFtIHtzdHJpbmdbXX0gW2NvbXBvc2l0aW9uc11cbiAqXG4gKiBAZnVuY3Rpb24gaW5kZXhcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGluZGV4KGRpcmVjdGlvbnM/OiBPcmRlckRpcmVjdGlvbltdLCBjb21wb3NpdGlvbnM/OiBzdHJpbmdbXSkge1xuICByZXR1cm4gcHJvcE1ldGFkYXRhKFxuICAgIFJlcG9zaXRvcnkua2V5KFxuICAgICAgYCR7UGVyc2lzdGVuY2VLZXlzLklOREVYfSR7Y29tcG9zaXRpb25zICYmIGNvbXBvc2l0aW9ucy5sZW5ndGggPyBgLiR7Y29tcG9zaXRpb25zLmpvaW4oXCIuXCIpfWAgOiBcIlwifWBcbiAgICApLFxuICAgIHtcbiAgICAgIGRpcmVjdGlvbnM6IGRpcmVjdGlvbnMsXG4gICAgICBjb21wb3NpdGlvbnM6IGNvbXBvc2l0aW9ucyxcbiAgICB9IGFzIEluZGV4TWV0YWRhdGFcbiAgKTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHVuaXF1ZU9uQ3JlYXRlVXBkYXRlPFxuICBNIGV4dGVuZHMgTW9kZWwsXG4gIFIgZXh0ZW5kcyBSZXBvPE0sIEYsIEM+LFxuICBWIGV4dGVuZHMgb2JqZWN0LFxuICBGIGV4dGVuZHMgUmVwb3NpdG9yeUZsYWdzLFxuICBDIGV4dGVuZHMgQ29udGV4dDxGPixcbj4oXG4gIHRoaXM6IFIsXG4gIGNvbnRleHQ6IENvbnRleHQ8Rj4sXG4gIGRhdGE6IFYsXG4gIGtleToga2V5b2YgTSxcbiAgbW9kZWw6IE1cbik6IFByb21pc2U8dm9pZD4ge1xuICBpZiAoIShtb2RlbCBhcyBhbnkpW2tleV0pIHJldHVybjtcbiAgY29uc3QgZXhpc3RpbmcgPSBhd2FpdCB0aGlzLnNlbGVjdCgpXG4gICAgLndoZXJlKENvbmRpdGlvbi5hdHRyaWJ1dGUoa2V5KS5lcShtb2RlbFtrZXldKSlcbiAgICAuZXhlY3V0ZSgpO1xuICBpZiAoZXhpc3RpbmcubGVuZ3RoKVxuICAgIHRocm93IG5ldyBDb25mbGljdEVycm9yKFxuICAgICAgYG1vZGVsIGFscmVhZHkgZXhpc3RzIHdpdGggcHJvcGVydHkgJHtrZXkgYXMgc3RyaW5nfSBlcXVhbCB0byAke0pTT04uc3RyaW5naWZ5KChtb2RlbCBhcyBhbnkpW2tleV0sIHVuZGVmaW5lZCwgMil9YFxuICAgICk7XG59XG5cbi8qKlxuICogQHN1bW1hcnkgVW5pcXVlIERlY29yYXRvclxuICogQGRlc2NyaXB0aW9uIFRhZ3MgYSBwcm9wZXJ0eSBhcyB1bmlxdWUuXG4gKiAgTm8gb3RoZXIgZWxlbWVudHMgaW4gdGhhdCB0YWJsZSBjYW4gaGF2ZSB0aGUgc2FtZSBwcm9wZXJ0eSB2YWx1ZVxuICpcbiAqIEBmdW5jdGlvbiB1bmlxdWVcbiAqXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1bmlxdWUoKSB7XG4gIHJldHVybiBhcHBseShcbiAgICBvbkNyZWF0ZVVwZGF0ZSh1bmlxdWVPbkNyZWF0ZVVwZGF0ZSksXG4gICAgcHJvcE1ldGFkYXRhKFJlcG9zaXRvcnkua2V5KFBlcnNpc3RlbmNlS2V5cy5VTklRVUUpLCB7fSlcbiAgKTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNyZWF0ZWRCeU9uQ3JlYXRlVXBkYXRlPFxuICBNIGV4dGVuZHMgTW9kZWwsXG4gIFIgZXh0ZW5kcyBSZXBvPE0sIEYsIEM+LFxuICBWIGV4dGVuZHMgUmVsYXRpb25zTWV0YWRhdGEsXG4gIEYgZXh0ZW5kcyBSZXBvc2l0b3J5RmxhZ3MsXG4gIEMgZXh0ZW5kcyBDb250ZXh0PEY+LFxuPihcbiAgdGhpczogUixcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICBjb250ZXh0OiBDb250ZXh0PEY+LFxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gIGRhdGE6IFYsXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAga2V5OiBrZXlvZiBNLFxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gIG1vZGVsOiBNXG4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgdGhyb3cgbmV3IEF1dGhvcml6YXRpb25FcnJvcihcbiAgICBcIlRoaXMgYWRhcHRlciBkb2VzIG5vdCBzdXBwb3J0IHVzZXIgaWRlbnRpZmljYXRpb25cIlxuICApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlZEJ5KCkge1xuICBjb25zdCBrZXkgPSBSZXBvc2l0b3J5LmtleShQZXJzaXN0ZW5jZUtleXMuQ1JFQVRFRF9CWSk7XG4gIHJldHVybiBEZWNvcmF0aW9uLmZvcihrZXkpXG4gICAgLmRlZmluZShvbkNyZWF0ZShjcmVhdGVkQnlPbkNyZWF0ZVVwZGF0ZSksIHByb3BNZXRhZGF0YShrZXksIHt9KSlcbiAgICAuYXBwbHkoKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHVwZGF0ZWRCeSgpIHtcbiAgY29uc3Qga2V5ID0gUmVwb3NpdG9yeS5rZXkoUGVyc2lzdGVuY2VLZXlzLlVQREFURURfQlkpO1xuICByZXR1cm4gRGVjb3JhdGlvbi5mb3Ioa2V5KVxuICAgIC5kZWZpbmUob25DcmVhdGVVcGRhdGUoY3JlYXRlZEJ5T25DcmVhdGVVcGRhdGUpLCBwcm9wTWV0YWRhdGEoa2V5LCB7fSkpXG4gICAgLmFwcGx5KCk7XG59XG5cbi8qKlxuICogQHN1bW1hcnkgT25lIFRvIE9uZSByZWxhdGlvbiBEZWNvcmF0b3JzXG4gKlxuICogQHBhcmFtIHtDb25zdHJ1Y3Rvcjxhbnk+fSBjbGF6eiB0aGUge0BsaW5rIFNlcXVlbmNlfVxuICogQHBhcmFtIHtDYXNjYWRlTWV0YWRhdGF9IFtjYXNjYWRlT3B0aW9uc11cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gcG9wdWxhdGUgSWYgdHJ1ZSwgcmVwbGFjZXMgdGhlIHNwZWNpZmllZCBrZXkgaW4gdGhlIGRvY3VtZW50IHdpdGggdGhlIGNvcnJlc3BvbmRpbmcgcmVjb3JkIGZyb20gdGhlIGRhdGFiYXNlXG4gKlxuICogQGZ1bmN0aW9uIG9uZVRvT25lXG4gKlxuICpcbiAqIEBzZWUgb25lVG9NYW55XG4gKiBAc2VlIG1hbnlUb09uZVxuICovXG5leHBvcnQgZnVuY3Rpb24gb25lVG9PbmU8TSBleHRlbmRzIE1vZGVsPihcbiAgY2xheno6IENvbnN0cnVjdG9yPE0+LFxuICBjYXNjYWRlT3B0aW9uczogQ2FzY2FkZU1ldGFkYXRhID0gRGVmYXVsdENhc2NhZGUsXG4gIHBvcHVsYXRlOiBib29sZWFuID0gdHJ1ZVxuKSB7XG4gIE1vZGVsLnJlZ2lzdGVyKGNsYXp6KTtcbiAgY29uc3QgbWV0YWRhdGE6IFJlbGF0aW9uc01ldGFkYXRhID0ge1xuICAgIGNsYXNzOiBjbGF6ei5uYW1lLFxuICAgIGNhc2NhZGU6IGNhc2NhZGVPcHRpb25zLFxuICAgIHBvcHVsYXRlOiBwb3B1bGF0ZSxcbiAgfTtcbiAgY29uc3Qga2V5ID0gUmVwb3NpdG9yeS5rZXkoUGVyc2lzdGVuY2VLZXlzLk9ORV9UT19PTkUpO1xuICByZXR1cm4gRGVjb3JhdGlvbi5mb3Ioa2V5KVxuICAgIC5kZWZpbmUoXG4gICAgICBwcm9wKFBlcnNpc3RlbmNlS2V5cy5SRUxBVElPTlMpLFxuICAgICAgdHlwZShbY2xhenoubmFtZSwgU3RyaW5nLm5hbWUsIE51bWJlci5uYW1lLCBCaWdJbnQubmFtZV0pLFxuICAgICAgb25DcmVhdGUob25lVG9PbmVPbkNyZWF0ZSwgbWV0YWRhdGEpLFxuICAgICAgb25VcGRhdGUob25lVG9PbmVPblVwZGF0ZSwgbWV0YWRhdGEpLFxuICAgICAgb25EZWxldGUob25lVG9PbmVPbkRlbGV0ZSwgbWV0YWRhdGEpLFxuICAgICAgYWZ0ZXJBbnkocG9wLCBtZXRhZGF0YSksXG4gICAgICBwcm9wTWV0YWRhdGEoa2V5LCBtZXRhZGF0YSlcbiAgICApXG4gICAgLmFwcGx5KCk7XG59XG5cbi8qKlxuICogQHN1bW1hcnkgT25lIFRvIE1hbnkgcmVsYXRpb24gRGVjb3JhdG9yc1xuICpcbiAqIEBwYXJhbSB7Q29uc3RydWN0b3I8YW55Pn0gY2xhenogdGhlIHtAbGluayBTZXF1ZW5jZX0gdG8gdXNlLlxuICogQHBhcmFtIHtDYXNjYWRlTWV0YWRhdGF9IFtjYXNjYWRlT3B0aW9uc11cbiAqXG4gKiBAZnVuY3Rpb24gb25lVG9NYW55XG4gKlxuICogQHNlZSBvbmVUb09uZVxuICogQHNlZSBtYW55VG9PbmVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG9uZVRvTWFueTxNIGV4dGVuZHMgTW9kZWw+KFxuICBjbGF6ejogQ29uc3RydWN0b3I8TT4sXG4gIGNhc2NhZGVPcHRpb25zOiBDYXNjYWRlTWV0YWRhdGEgPSBEZWZhdWx0Q2FzY2FkZSxcbiAgcG9wdWxhdGU6IGJvb2xlYW4gPSB0cnVlXG4pIHtcbiAgTW9kZWwucmVnaXN0ZXIoY2xhenopO1xuICBjb25zdCBtZXRhZGF0YTogUmVsYXRpb25zTWV0YWRhdGEgPSB7XG4gICAgY2xhc3M6IGNsYXp6Lm5hbWUsXG4gICAgY2FzY2FkZTogY2FzY2FkZU9wdGlvbnMsXG4gICAgcG9wdWxhdGU6IHBvcHVsYXRlLFxuICB9O1xuICBjb25zdCBrZXkgPSBSZXBvc2l0b3J5LmtleShQZXJzaXN0ZW5jZUtleXMuT05FX1RPX01BTlkpO1xuICByZXR1cm4gRGVjb3JhdGlvbi5mb3Ioa2V5KVxuICAgIC5kZWZpbmUoXG4gICAgICBwcm9wKFBlcnNpc3RlbmNlS2V5cy5SRUxBVElPTlMpLFxuICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvciBwdXJwb3NlZnVsIG92ZXJyaWRlXG4gICAgICBsaXN0KFtjbGF6eiwgU3RyaW5nLCBOdW1iZXIsIEJpZ0ludF0pLFxuICAgICAgb25DcmVhdGUob25lVG9NYW55T25DcmVhdGUsIG1ldGFkYXRhKSxcbiAgICAgIG9uVXBkYXRlKG9uZVRvTWFueU9uVXBkYXRlLCBtZXRhZGF0YSksXG4gICAgICBvbkRlbGV0ZShvbmVUb01hbnlPbkRlbGV0ZSwgbWV0YWRhdGEpLFxuICAgICAgYWZ0ZXJBbnkocG9wLCBtZXRhZGF0YSksXG4gICAgICBwcm9wTWV0YWRhdGEoa2V5LCBtZXRhZGF0YSlcbiAgICApXG4gICAgLmFwcGx5KCk7XG59XG5cbi8qKlxuICogQHN1bW1hcnkgTWFueSBUbyBPbmUgcmVsYXRpb24gRGVjb3JhdG9yc1xuICpcbiAqIEBwYXJhbSB7Q29uc3RydWN0b3I8YW55Pn0gY2xhenogdGhlIHtAbGluayBTZXF1ZW5jZX0gdG8gdXNlLiBEZWZhdWx0cyB0byB7QGxpbmsgTm9uZVNlcXVlbmNlfVxuICogQHBhcmFtIHtDYXNjYWRlTWV0YWRhdGF9IFtjYXNjYWRlT3B0aW9uc11cbiAqXG4gKiBAZnVuY3Rpb24gbWFueVRvT25lXG4gKlxuICogQHNlZSBvbmVUb01hbnlcbiAqIEBzZWUgb25lVG9PbmVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1hbnlUb09uZTxNIGV4dGVuZHMgTW9kZWw+KFxuICBjbGF6ejogQ29uc3RydWN0b3I8TT4sXG4gIGNhc2NhZGVPcHRpb25zOiBDYXNjYWRlTWV0YWRhdGEgPSBEZWZhdWx0Q2FzY2FkZSxcbiAgcG9wdWxhdGUgPSB0cnVlXG4pIHtcbiAgTW9kZWwucmVnaXN0ZXIoY2xhenopO1xuICBjb25zdCBtZXRhZGF0YTogUmVsYXRpb25zTWV0YWRhdGEgPSB7XG4gICAgY2xhc3M6IGNsYXp6Lm5hbWUsXG4gICAgY2FzY2FkZTogY2FzY2FkZU9wdGlvbnMsXG4gICAgcG9wdWxhdGU6IHBvcHVsYXRlLFxuICB9O1xuICBjb25zdCBrZXkgPSBSZXBvc2l0b3J5LmtleShQZXJzaXN0ZW5jZUtleXMuTUFOWV9UT19PTkUpO1xuICByZXR1cm4gRGVjb3JhdGlvbi5mb3Ioa2V5KVxuICAgIC5kZWZpbmUoXG4gICAgICBwcm9wKFBlcnNpc3RlbmNlS2V5cy5SRUxBVElPTlMpLFxuICAgICAgdHlwZShbY2xhenoubmFtZSwgU3RyaW5nLm5hbWUsIE51bWJlci5uYW1lLCBCaWdJbnQubmFtZV0pLFxuICAgICAgLy8gb25DcmVhdGUob25lVG9NYW55T25DcmVhdGUsIG1ldGFkYXRhKSxcbiAgICAgIC8vIG9uVXBkYXRlKG9uZVRvTWFueU9uVXBkYXRlLCBtZXRhZGF0YSksXG4gICAgICAvLyBvbkRlbGV0ZShvbmVUb01hbnlPbkRlbGV0ZSwgbWV0YWRhdGEpLFxuICAgICAgLy8gYWZ0ZXJBbGwocG9wdWxhdGUsIG1ldGFkYXRhKSxcbiAgICAgIHByb3BNZXRhZGF0YShrZXksIG1ldGFkYXRhKVxuICAgIClcbiAgICAuYXBwbHkoKTtcbn1cbiIsImltcG9ydCB7XG4gIERlY29yYXRpb24sXG4gIE1vZGVsLFxuICBwcm9wTWV0YWRhdGEsXG4gIHJlcXVpcmVkLFxufSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQge1xuICBEZWZhdWx0U2VxdWVuY2VPcHRpb25zLFxuICBTZXF1ZW5jZU9wdGlvbnMsXG59IGZyb20gXCIuLi9pbnRlcmZhY2VzL1NlcXVlbmNlT3B0aW9uc1wiO1xuaW1wb3J0IHtcbiAgREJLZXlzLFxuICBJbnRlcm5hbEVycm9yLFxuICBvbkNyZWF0ZSxcbiAgcmVhZG9ubHksXG4gIFJlcG9zaXRvcnlGbGFncyxcbn0gZnJvbSBcIkBkZWNhZi10cy9kYi1kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBSZXBvLCBSZXBvc2l0b3J5IH0gZnJvbSBcIi4uL3JlcG9zaXRvcnkvUmVwb3NpdG9yeVwiO1xuaW1wb3J0IHsgaW5kZXggfSBmcm9tIFwiLi4vbW9kZWwvZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHsgc2VxdWVuY2VOYW1lRm9yTW9kZWwgfSBmcm9tIFwiLi91dGlsc1wiO1xuaW1wb3J0IHsgU2VxdWVuY2UgfSBmcm9tIFwiLi4vcGVyc2lzdGVuY2UvU2VxdWVuY2VcIjtcbmltcG9ydCB7IENvbnRleHQgfSBmcm9tIFwiQGRlY2FmLXRzL2RiLWRlY29yYXRvcnNcIjtcbmltcG9ydCB7IE9yZGVyRGlyZWN0aW9uIH0gZnJvbSBcIi4uL3JlcG9zaXRvcnlcIjtcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHBrT25DcmVhdGU8XG4gIE0gZXh0ZW5kcyBNb2RlbCxcbiAgUiBleHRlbmRzIFJlcG88TSwgRiwgQz4sXG4gIFYgZXh0ZW5kcyBTZXF1ZW5jZU9wdGlvbnMsXG4gIEYgZXh0ZW5kcyBSZXBvc2l0b3J5RmxhZ3MsXG4gIEMgZXh0ZW5kcyBDb250ZXh0PEY+LFxuPihcbiAgdGhpczogUixcbiAgY29udGV4dDogQ29udGV4dDxGPixcbiAgZGF0YTogVixcbiAga2V5OiBrZXlvZiBNLFxuICBtb2RlbDogTVxuKTogUHJvbWlzZTx2b2lkPiB7XG4gIGlmICghZGF0YS50eXBlIHx8IG1vZGVsW2tleV0pIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBjb25zdCBzZXRQcmltYXJ5S2V5VmFsdWUgPSBmdW5jdGlvbiA8TSBleHRlbmRzIE1vZGVsPihcbiAgICB0YXJnZXQ6IE0sXG4gICAgcHJvcGVydHlLZXk6IHN0cmluZyxcbiAgICB2YWx1ZTogc3RyaW5nIHwgbnVtYmVyIHwgYmlnaW50XG4gICkge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIHByb3BlcnR5S2V5LCB7XG4gICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgd3JpdGFibGU6IGZhbHNlLFxuICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgdmFsdWU6IHZhbHVlLFxuICAgIH0pO1xuICB9O1xuICBpZiAoIWRhdGEubmFtZSkgZGF0YS5uYW1lID0gc2VxdWVuY2VOYW1lRm9yTW9kZWwobW9kZWwsIFwicGtcIik7XG4gIGxldCBzZXF1ZW5jZTogU2VxdWVuY2U7XG4gIHRyeSB7XG4gICAgc2VxdWVuY2UgPSBhd2FpdCB0aGlzLmFkYXB0ZXIuU2VxdWVuY2UoZGF0YSk7XG4gIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFxuICAgICAgYEZhaWxlZCB0byBpbnN0YW50aWF0ZSBTZXF1ZW5jZSAke2RhdGEubmFtZX06ICR7ZX1gXG4gICAgKTtcbiAgfVxuXG4gIGNvbnN0IG5leHQgPSBhd2FpdCBzZXF1ZW5jZS5uZXh0KCk7XG4gIHNldFByaW1hcnlLZXlWYWx1ZShtb2RlbCwga2V5IGFzIHN0cmluZywgbmV4dCk7XG59XG5cbi8qKlxuICogQHN1bW1hcnkgUHJpbWFyeSBLZXkgRGVjb3JhdG9yXG4gKiBAZGVzY3JpcHRpb24gTWFya3MgdGhlIHByb3BlcnR5IGFzIHRoZSB7QGxpbmsgTW9kZWx9cyBwcmltYXJ5IGtleS5cbiAqICBBbHNvIG1hcmtzIHRoZSBwcm9wZXJ0eSBhcyB7QGxpbmsgdW5pcXVlfSBhcyB7QHJlcXVpcmVkfSBhbmQgZW5zdXJlcyB0aGUgaW5kZXggaXMgY3JlYXRlZCBwcm9wZXJseSBhY2NvcmRpbmcgdG8gdGhlIHByb3ZpZGVkIHtAbGluayBTZXF1ZW5jZX1cbiAqXG4gKiBAZnVuY3Rpb24gcGtcbiAqXG4gKiBAc2VlIHVuaXF1ZVxuICogQHNlZSByZXF1aXJlZFxuICogQHNlZSBvblxuICovXG5leHBvcnQgZnVuY3Rpb24gcGsoXG4gIG9wdHM6IE9taXQ8XG4gICAgU2VxdWVuY2VPcHRpb25zLFxuICAgIFwiY3ljbGVcIiB8IFwic3RhcnRXaXRoXCIgfCBcImluY3JlbWVudEJ5XCJcbiAgPiA9IERlZmF1bHRTZXF1ZW5jZU9wdGlvbnNcbikge1xuICBvcHRzID0gT2JqZWN0LmFzc2lnbih7fSwgRGVmYXVsdFNlcXVlbmNlT3B0aW9ucywgb3B0cykgYXMgU2VxdWVuY2VPcHRpb25zO1xuICBjb25zdCBrZXkgPSBSZXBvc2l0b3J5LmtleShEQktleXMuSUQpO1xuICByZXR1cm4gRGVjb3JhdGlvbi5mb3Ioa2V5KVxuICAgIC5kZWZpbmUoXG4gICAgICBpbmRleChbT3JkZXJEaXJlY3Rpb24uQVNDLCBPcmRlckRpcmVjdGlvbi5EU0NdKSxcbiAgICAgIHJlcXVpcmVkKCksXG4gICAgICByZWFkb25seSgpLFxuICAgICAgLy8gdHlwZShbU3RyaW5nLm5hbWUsIE51bWJlci5uYW1lLCBCaWdJbnQubmFtZV0pLFxuICAgICAgcHJvcE1ldGFkYXRhKGtleSwgb3B0cyBhcyBTZXF1ZW5jZU9wdGlvbnMpLFxuICAgICAgb25DcmVhdGUocGtPbkNyZWF0ZSwgb3B0cyBhcyBTZXF1ZW5jZU9wdGlvbnMpXG4gICAgKVxuICAgIC5hcHBseSgpO1xufVxuIiwiaW1wb3J0IHsgREJPcGVyYXRpb25zLCB0aW1lc3RhbXAgfSBmcm9tIFwiQGRlY2FmLXRzL2RiLWRlY29yYXRvcnNcIjtcbmltcG9ydCB7IE1vZGVsQXJnLCBNb2RlbCB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcblxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIEJhc2VNb2RlbCBleHRlbmRzIE1vZGVsIHtcbiAgQHRpbWVzdGFtcChEQk9wZXJhdGlvbnMuQ1JFQVRFKVxuICBjcmVhdGVkT24hOiBEYXRlO1xuICBAdGltZXN0YW1wKClcbiAgdXBkYXRlZE9uITogRGF0ZTtcblxuICBwcm90ZWN0ZWQgY29uc3RydWN0b3IoYXJnPzogTW9kZWxBcmc8QmFzZU1vZGVsPikge1xuICAgIHN1cGVyKGFyZyk7XG4gIH1cbn1cbiIsImltcG9ydCB7IFBhZ2luZ0Vycm9yIH0gZnJvbSBcIi4vZXJyb3JzXCI7XG5pbXBvcnQgeyBBZGFwdGVyIH0gZnJvbSBcIi4uL3BlcnNpc3RlbmNlXCI7XG5pbXBvcnQgeyBDb25zdHJ1Y3RvciwgTW9kZWwgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBQYWdpbmF0b3I8TSBleHRlbmRzIE1vZGVsLCBSID0gTVtdLCBRID0gYW55PiB7XG4gIHByb3RlY3RlZCBfY3VycmVudFBhZ2UhOiBudW1iZXI7XG4gIHByb3RlY3RlZCBfdG90YWxQYWdlcyE6IG51bWJlcjtcbiAgcHJvdGVjdGVkIF9yZWNvcmRDb3VudCE6IG51bWJlcjtcbiAgcHJvdGVjdGVkIGxpbWl0ITogbnVtYmVyO1xuXG4gIHByaXZhdGUgX3N0YXRlbWVudD86IFE7XG5cbiAgZ2V0IGN1cnJlbnQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2N1cnJlbnRQYWdlO1xuICB9XG5cbiAgZ2V0IHRvdGFsKCkge1xuICAgIHJldHVybiB0aGlzLl90b3RhbFBhZ2VzO1xuICB9XG5cbiAgZ2V0IGNvdW50KCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuX3JlY29yZENvdW50O1xuICB9XG5cbiAgcHJvdGVjdGVkIGdldCBzdGF0ZW1lbnQoKSB7XG4gICAgaWYgKCF0aGlzLl9zdGF0ZW1lbnQpIHRoaXMuX3N0YXRlbWVudCA9IHRoaXMucHJlcGFyZSh0aGlzLnF1ZXJ5KTtcbiAgICByZXR1cm4gdGhpcy5fc3RhdGVtZW50O1xuICB9XG5cbiAgcHJvdGVjdGVkIGNvbnN0cnVjdG9yKFxuICAgIHByb3RlY3RlZCByZWFkb25seSBhZGFwdGVyOiBBZGFwdGVyPGFueSwgUSwgYW55LCBhbnk+LFxuICAgIHByb3RlY3RlZCByZWFkb25seSBxdWVyeTogUSxcbiAgICByZWFkb25seSBzaXplOiBudW1iZXIsXG4gICAgcHJvdGVjdGVkIHJlYWRvbmx5IGNsYXp6OiBDb25zdHJ1Y3RvcjxNPlxuICApIHt9XG5cbiAgcHJvdGVjdGVkIGFic3RyYWN0IHByZXBhcmUocmF3U3RhdGVtZW50OiBRKTogUTtcblxuICBhc3luYyBuZXh0KCkge1xuICAgIHJldHVybiB0aGlzLnBhZ2UodGhpcy5jdXJyZW50ICsgMSk7XG4gIH1cblxuICBhc3luYyBwcmV2aW91cygpIHtcbiAgICByZXR1cm4gdGhpcy5wYWdlKHRoaXMuY3VycmVudCAtIDEpO1xuICB9XG5cbiAgcHJvdGVjdGVkIHZhbGlkYXRlUGFnZShwYWdlOiBudW1iZXIpIHtcbiAgICBpZiAocGFnZSA8IDEgfHwgIU51bWJlci5pc0ludGVnZXIocGFnZSkpXG4gICAgICB0aHJvdyBuZXcgUGFnaW5nRXJyb3IoXG4gICAgICAgIFwiUGFnZSBudW1iZXIgY2Fubm90IGJlIHVuZGVyIDEgYW5kIG11c3QgYmUgYW4gaW50ZWdlclwiXG4gICAgICApO1xuICAgIGlmICh0eXBlb2YgdGhpcy5fdG90YWxQYWdlcyAhPT0gXCJ1bmRlZmluZWRcIiAmJiBwYWdlID4gdGhpcy5fdG90YWxQYWdlcylcbiAgICAgIHRocm93IG5ldyBQYWdpbmdFcnJvcihcbiAgICAgICAgYE9ubHkgJHt0aGlzLl90b3RhbFBhZ2VzfSBhcmUgYXZhaWxhYmxlLiBDYW5ub3QgZ28gdG8gcGFnZSAke3BhZ2V9YFxuICAgICAgKTtcbiAgICByZXR1cm4gcGFnZTtcbiAgfVxuXG4gIGFic3RyYWN0IHBhZ2UocGFnZT86IG51bWJlcik6IFByb21pc2U8UltdPjtcbn1cbiIsImltcG9ydCB7IHR5cGUgQ29uc3RydWN0b3IsIE1vZGVsIH0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHR5cGUgeyBFeGVjdXRvciwgUmF3RXhlY3V0b3IgfSBmcm9tIFwiLi4vaW50ZXJmYWNlc1wiO1xuaW1wb3J0IHR5cGUge1xuICBGcm9tU2VsZWN0b3IsXG4gIEdyb3VwQnlTZWxlY3RvcixcbiAgT3JkZXJCeVNlbGVjdG9yLFxuICBTZWxlY3RTZWxlY3Rvcixcbn0gZnJvbSBcIi4vc2VsZWN0b3JzXCI7XG5pbXBvcnQgeyBDb25kaXRpb24gfSBmcm9tIFwiLi9Db25kaXRpb25cIjtcbmltcG9ydCB7IGZpbmRQcmltYXJ5S2V5LCBJbnRlcm5hbEVycm9yIH0gZnJvbSBcIkBkZWNhZi10cy9kYi1kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBmaW5hbCB9IGZyb20gXCIuLi91dGlscy9kZWNvcmF0b3JzXCI7XG5pbXBvcnQgdHlwZSB7XG4gIENvdW50T3B0aW9uLFxuICBEaXN0aW5jdE9wdGlvbixcbiAgTGltaXRPcHRpb24sXG4gIE1heE9wdGlvbixcbiAgTWluT3B0aW9uLFxuICBPZmZzZXRPcHRpb24sXG4gIE9yZGVyQW5kR3JvdXBPcHRpb24sXG4gIFNlbGVjdE9wdGlvbixcbiAgV2hlcmVPcHRpb24sXG59IGZyb20gXCIuL29wdGlvbnNcIjtcbmltcG9ydCB7IFBhZ2luYXRhYmxlIH0gZnJvbSBcIi4uL2ludGVyZmFjZXMvUGFnaW5hdGFibGVcIjtcbmltcG9ydCB7IFBhZ2luYXRvciB9IGZyb20gXCIuL1BhZ2luYXRvclwiO1xuaW1wb3J0IHsgQWRhcHRlciB9IGZyb20gXCIuLi9wZXJzaXN0ZW5jZVwiO1xuaW1wb3J0IHsgUXVlcnlFcnJvciB9IGZyb20gXCIuL2Vycm9yc1wiO1xuXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgU3RhdGVtZW50PFEsIE0gZXh0ZW5kcyBNb2RlbCwgUj5cbiAgaW1wbGVtZW50cyBFeGVjdXRvcjxSPiwgUmF3RXhlY3V0b3I8UT4sIFBhZ2luYXRhYmxlPE0sIFIsIFE+XG57XG4gIHByb3RlY3RlZCByZWFkb25seSBzZWxlY3RTZWxlY3Rvcj86IFNlbGVjdFNlbGVjdG9yPE0+W107XG4gIHByb3RlY3RlZCBkaXN0aW5jdFNlbGVjdG9yPzogU2VsZWN0U2VsZWN0b3I8TT47XG4gIHByb3RlY3RlZCBtYXhTZWxlY3Rvcj86IFNlbGVjdFNlbGVjdG9yPE0+O1xuICBwcm90ZWN0ZWQgbWluU2VsZWN0b3I/OiBTZWxlY3RTZWxlY3RvcjxNPjtcbiAgcHJvdGVjdGVkIGNvdW50U2VsZWN0b3I/OiBTZWxlY3RTZWxlY3RvcjxNPjtcbiAgcHJvdGVjdGVkIGZyb21TZWxlY3RvciE6IENvbnN0cnVjdG9yPE0+O1xuICBwcm90ZWN0ZWQgd2hlcmVDb25kaXRpb24/OiBDb25kaXRpb248TT47XG4gIHByb3RlY3RlZCBvcmRlckJ5U2VsZWN0b3I/OiBPcmRlckJ5U2VsZWN0b3I8TT47XG4gIHByb3RlY3RlZCBncm91cEJ5U2VsZWN0b3I/OiBHcm91cEJ5U2VsZWN0b3I8TT47XG4gIHByb3RlY3RlZCBsaW1pdFNlbGVjdG9yPzogbnVtYmVyO1xuICBwcm90ZWN0ZWQgb2Zmc2V0U2VsZWN0b3I/OiBudW1iZXI7XG5cbiAgcHJvdGVjdGVkIGNvbnN0cnVjdG9yKHByb3RlY3RlZCBhZGFwdGVyOiBBZGFwdGVyPGFueSwgUSwgYW55LCBhbnk+KSB7fVxuXG4gIHNlbGVjdDxcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gICAgUyBleHRlbmRzIHJlYWRvbmx5IFNlbGVjdFNlbGVjdG9yPE0+W10sXG4gID4oKTogU2VsZWN0T3B0aW9uPE0sIE1bXT47XG4gIHNlbGVjdDxTIGV4dGVuZHMgcmVhZG9ubHkgU2VsZWN0U2VsZWN0b3I8TT5bXT4oXG4gICAgc2VsZWN0b3I6IHJlYWRvbmx5IFsuLi5TXVxuICApOiBTZWxlY3RPcHRpb248TSwgUGljazxNLCBTW251bWJlcl0+W10+O1xuXG4gIEBmaW5hbCgpXG4gIHNlbGVjdDxTIGV4dGVuZHMgcmVhZG9ubHkgU2VsZWN0U2VsZWN0b3I8TT5bXT4oXG4gICAgc2VsZWN0b3I/OiByZWFkb25seSBbLi4uU11cbiAgKTogU2VsZWN0T3B0aW9uPE0sIE1bXT4gfCBTZWxlY3RPcHRpb248TSwgUGljazxNLCBTW251bWJlcl0+W10+IHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgXCJzZWxlY3RTZWxlY3RvclwiLCB7XG4gICAgICB2YWx1ZTogc2VsZWN0b3IsXG4gICAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgfSk7XG4gICAgcmV0dXJuIHRoaXMgYXMgU2VsZWN0T3B0aW9uPE0sIE1bXT4gfCBTZWxlY3RPcHRpb248TSwgUGljazxNLCBTW251bWJlcl0+W10+O1xuICB9XG5cbiAgQGZpbmFsKClcbiAgZGlzdGluY3Q8UyBleHRlbmRzIFNlbGVjdFNlbGVjdG9yPE0+PihcbiAgICBzZWxlY3RvcjogU1xuICApOiBEaXN0aW5jdE9wdGlvbjxNLCBNW1NdW10+IHtcbiAgICB0aGlzLmRpc3RpbmN0U2VsZWN0b3IgPSBzZWxlY3RvcjtcbiAgICByZXR1cm4gdGhpcyBhcyBEaXN0aW5jdE9wdGlvbjxNLCBNW1NdW10+O1xuICB9XG5cbiAgQGZpbmFsKClcbiAgbWF4PFMgZXh0ZW5kcyBTZWxlY3RTZWxlY3RvcjxNPj4oc2VsZWN0b3I6IFMpOiBNYXhPcHRpb248TSwgTVtTXT4ge1xuICAgIHRoaXMubWF4U2VsZWN0b3IgPSBzZWxlY3RvcjtcbiAgICByZXR1cm4gdGhpcyBhcyBNYXhPcHRpb248TSwgTVtTXT47XG4gIH1cblxuICBAZmluYWwoKVxuICBtaW48UyBleHRlbmRzIFNlbGVjdFNlbGVjdG9yPE0+PihzZWxlY3RvcjogUyk6IE1pbk9wdGlvbjxNLCBNW1NdPiB7XG4gICAgdGhpcy5taW5TZWxlY3RvciA9IHNlbGVjdG9yO1xuICAgIHJldHVybiB0aGlzIGFzIE1pbk9wdGlvbjxNLCBNW1NdPjtcbiAgfVxuXG4gIEBmaW5hbCgpXG4gIGNvdW50PFMgZXh0ZW5kcyBTZWxlY3RTZWxlY3RvcjxNPj4oc2VsZWN0b3I/OiBTKTogQ291bnRPcHRpb248TSwgbnVtYmVyPiB7XG4gICAgdGhpcy5jb3VudFNlbGVjdG9yID0gc2VsZWN0b3I7XG4gICAgcmV0dXJuIHRoaXMgYXMgQ291bnRPcHRpb248TSwgbnVtYmVyPjtcbiAgfVxuXG4gIEBmaW5hbCgpXG4gIHB1YmxpYyBmcm9tKHNlbGVjdG9yOiBGcm9tU2VsZWN0b3I8TT4pOiBXaGVyZU9wdGlvbjxNLCBSPiB7XG4gICAgdGhpcy5mcm9tU2VsZWN0b3IgPSAoXG4gICAgICB0eXBlb2Ygc2VsZWN0b3IgPT09IFwic3RyaW5nXCIgPyBNb2RlbC5nZXQoc2VsZWN0b3IpIDogc2VsZWN0b3JcbiAgICApIGFzIENvbnN0cnVjdG9yPE0+O1xuICAgIGlmICghdGhpcy5mcm9tU2VsZWN0b3IpXG4gICAgICB0aHJvdyBuZXcgUXVlcnlFcnJvcihgQ291bGQgbm90IGZpbmQgc2VsZWN0b3IgbW9kZWw6ICR7c2VsZWN0b3J9YCk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBAZmluYWwoKVxuICBwdWJsaWMgd2hlcmUoY29uZGl0aW9uOiBDb25kaXRpb248TT4pOiBPcmRlckFuZEdyb3VwT3B0aW9uPE0sIFI+IHtcbiAgICB0aGlzLndoZXJlQ29uZGl0aW9uID0gY29uZGl0aW9uO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgQGZpbmFsKClcbiAgcHVibGljIG9yZGVyQnkoXG4gICAgc2VsZWN0b3I6IE9yZGVyQnlTZWxlY3RvcjxNPlxuICApOiBMaW1pdE9wdGlvbjxNLCBSPiAmIE9mZnNldE9wdGlvbjxSPiB7XG4gICAgdGhpcy5vcmRlckJ5U2VsZWN0b3IgPSBzZWxlY3RvcjtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIEBmaW5hbCgpXG4gIHB1YmxpYyBncm91cEJ5KHNlbGVjdG9yOiBHcm91cEJ5U2VsZWN0b3I8TT4pOiBMaW1pdE9wdGlvbjxNLCBSPiB7XG4gICAgdGhpcy5ncm91cEJ5U2VsZWN0b3IgPSBzZWxlY3RvcjtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIEBmaW5hbCgpXG4gIHB1YmxpYyBsaW1pdCh2YWx1ZTogbnVtYmVyKTogT2Zmc2V0T3B0aW9uPFI+IHtcbiAgICB0aGlzLmxpbWl0U2VsZWN0b3IgPSB2YWx1ZTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIEBmaW5hbCgpXG4gIHB1YmxpYyBvZmZzZXQodmFsdWU6IG51bWJlcik6IEV4ZWN1dG9yPFI+IHtcbiAgICB0aGlzLm9mZnNldFNlbGVjdG9yID0gdmFsdWU7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBAZmluYWwoKVxuICBhc3luYyBleGVjdXRlKCk6IFByb21pc2U8Uj4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBxdWVyeTogUSA9IHRoaXMuYnVpbGQoKTtcbiAgICAgIHJldHVybiAoYXdhaXQgdGhpcy5yYXcocXVlcnkpKSBhcyBSO1xuICAgIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKGUgYXMgRXJyb3IpO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIHJhdzxSPihyYXdJbnB1dDogUSk6IFByb21pc2U8Uj4ge1xuICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCB0aGlzLmFkYXB0ZXIucmF3PFI+KHJhd0lucHV0KTtcbiAgICBpZiAoIXRoaXMuc2VsZWN0U2VsZWN0b3IpIHJldHVybiByZXN1bHRzO1xuICAgIGNvbnN0IHBrQXR0ciA9IGZpbmRQcmltYXJ5S2V5KFxuICAgICAgbmV3ICh0aGlzLmZyb21TZWxlY3RvciBhcyBDb25zdHJ1Y3RvcjxNPikoKVxuICAgICkuaWQ7XG5cbiAgICBjb25zdCBwcm9jZXNzb3IgPSBmdW5jdGlvbiByZWNvcmRQcm9jZXNzb3IoXG4gICAgICB0aGlzOiBTdGF0ZW1lbnQ8USwgTSwgUj4sXG4gICAgICByOiBhbnlcbiAgICApIHtcbiAgICAgIGNvbnN0IGlkID0gcltwa0F0dHJdO1xuICAgICAgcmV0dXJuIHRoaXMuYWRhcHRlci5yZXZlcnQoXG4gICAgICAgIHIsXG4gICAgICAgIHRoaXMuZnJvbVNlbGVjdG9yIGFzIENvbnN0cnVjdG9yPGFueT4sXG4gICAgICAgIHBrQXR0cixcbiAgICAgICAgaWRcbiAgICAgICkgYXMgYW55O1xuICAgIH0uYmluZCh0aGlzIGFzIGFueSk7XG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheShyZXN1bHRzKSkgcmV0dXJuIHJlc3VsdHMubWFwKHByb2Nlc3NvcikgYXMgUjtcbiAgICByZXR1cm4gcHJvY2Vzc29yKHJlc3VsdHMpIGFzIFI7XG4gIH1cblxuICBwcm90ZWN0ZWQgYWJzdHJhY3QgYnVpbGQoKTogUTtcbiAgcHJvdGVjdGVkIGFic3RyYWN0IHBhcnNlQ29uZGl0aW9uKGNvbmRpdGlvbjogQ29uZGl0aW9uPE0+KTogUTtcbiAgYWJzdHJhY3QgcGFnaW5hdGUoc2l6ZTogbnVtYmVyKTogUHJvbWlzZTxQYWdpbmF0b3I8TSwgUiwgUT4+O1xufVxuIiwiaW1wb3J0IHsgSW5qZWN0YWJsZXNSZWdpc3RyeSB9IGZyb20gXCIuL3JlcG9zaXRvcnlcIjtcbmltcG9ydCB7IEluamVjdGFibGVzIH0gZnJvbSBcIkBkZWNhZi10cy9pbmplY3RhYmxlLWRlY29yYXRvcnNcIjtcblxuLy8gb3ZlcnJpZGVzIHRoZSBwcmV2aW91cyBJbmplY3RhYmxlcyByZWdpc3RyeSB0byBlbmFibGUgdGhlIEByZXBvc2l0b3J5IGRlY29yYXRvclxuSW5qZWN0YWJsZXMuc2V0UmVnaXN0cnkobmV3IEluamVjdGFibGVzUmVnaXN0cnkoKSk7XG5cbmV4cG9ydCAqIGZyb20gXCIuL2lkZW50aXR5XCI7XG5leHBvcnQgKiBmcm9tIFwiLi9pbnRlcmZhY2VzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9tb2RlbFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vcXVlcnlcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3JlcG9zaXRvcnlcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3V0aWxzXCI7XG4vL2xlZnQgdG8gbGFzdCBvbiBwdXJwb3NlXG5leHBvcnQgKiBmcm9tIFwiLi9wZXJzaXN0ZW5jZVwiO1xuXG4vKipcbiAqIEBzdW1tYXJ5IHN0b3JlcyB0aGUgY3VycmVudCBwYWNrYWdlIHZlcnNpb25cbiAqIEBkZXNjcmlwdGlvbiB0aGlzIGlzIGhvdyB5b3Ugc2hvdWxkIGRvY3VtZW50IGEgY29uc3RhbnRcbiAqIEBjb25zdCBWRVJTSU9OXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmNvcmVcbiAqL1xuZXhwb3J0IGNvbnN0IFZFUlNJT04gPSBcIiMjVkVSU0lPTiMjXCI7XG4iXSwibmFtZXMiOlsiUmVwIiwicG9wdWxhdGUiLCJwb3AiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7SUFFWTtBQUFaLENBQUEsVUFBWSxjQUFjLEVBQUE7QUFDeEIsSUFBQSxjQUFBLENBQUEsS0FBQSxDQUFBLEdBQUEsS0FBVztBQUVYLElBQUEsY0FBQSxDQUFBLEtBQUEsQ0FBQSxHQUFBLE1BQVk7QUFDZCxDQUFDLEVBSlcsY0FBYyxLQUFkLGNBQWMsR0FJekIsRUFBQSxDQUFBLENBQUE7SUFFVztBQUFaLENBQUEsVUFBWSxPQUFPLEVBQUE7QUFDakIsSUFBQSxPQUFBLENBQUEsU0FBQSxDQUFBLEdBQUEsU0FBbUI7QUFDbkIsSUFBQSxPQUFBLENBQUEsTUFBQSxDQUFBLEdBQUEsTUFBYTtBQUNmLENBQUMsRUFIVyxPQUFPLEtBQVAsT0FBTyxHQUdsQixFQUFBLENBQUEsQ0FBQTtBQUVZLE1BQUEsY0FBYyxHQUFvQjtJQUM3QyxNQUFNLEVBQUUsT0FBTyxDQUFDLE9BQU87SUFDdkIsTUFBTSxFQUFFLE9BQU8sQ0FBQyxJQUFJOzs7SUNmVjtBQUFaLENBQUEsVUFBWSxlQUFlLEVBQUE7QUFDekIsSUFBQSxlQUFBLENBQUEsT0FBQSxDQUFBLEdBQUEsT0FBZTtBQUNmLElBQUEsZUFBQSxDQUFBLFFBQUEsQ0FBQSxHQUFBLFFBQWlCO0FBQ2pCLElBQUEsZUFBQSxDQUFBLFNBQUEsQ0FBQSxHQUFBLFNBQW1CO0FBQ25CLElBQUEsZUFBQSxDQUFBLFlBQUEsQ0FBQSxHQUFBLDJCQUF3QztBQUN4QyxJQUFBLGVBQUEsQ0FBQSxPQUFBLENBQUEsR0FBQSxPQUFlO0FBQ2YsSUFBQSxlQUFB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
3873
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29yZS5lc20uY2pzIiwic291cmNlcyI6WyIuLi9zcmMvcmVwb3NpdG9yeS9jb25zdGFudHMudHMiLCIuLi9zcmMvcGVyc2lzdGVuY2UvY29uc3RhbnRzLnRzIiwiLi4vc3JjL3V0aWxzL2RlY29yYXRvcnMudHMiLCIuLi9zcmMvdXRpbHMvZXJyb3JzLnRzIiwiLi4vc3JjL3BlcnNpc3RlbmNlL2Vycm9ycy50cyIsIi4uL3NyYy9wZXJzaXN0ZW5jZS9EaXNwYXRjaC50cyIsIi4uL3NyYy9wZXJzaXN0ZW5jZS9PYnNlcnZlckhhbmRsZXIudHMiLCIuLi9zcmMvcGVyc2lzdGVuY2UvQWRhcHRlci50cyIsIi4uL3NyYy9pZGVudGl0eS91dGlscy50cyIsIi4uL3NyYy9wZXJzaXN0ZW5jZS9TZXF1ZW5jZS50cyIsIi4uL3NyYy9wZXJzaXN0ZW5jZS9kZWNvcmF0b3JzLnRzIiwiLi4vc3JjL3JlcG9zaXRvcnkvUmVwb3NpdG9yeS50cyIsIi4uL3NyYy9yZXBvc2l0b3J5L2RlY29yYXRvcnMudHMiLCIuLi9zcmMvcmVwb3NpdG9yeS9lcnJvcnMudHMiLCIuLi9zcmMvcmVwb3NpdG9yeS91dGlscy50cyIsIi4uL3NyYy9yZXBvc2l0b3J5L2luamVjdGFibGVzLnRzIiwiLi4vc3JjL2ludGVyZmFjZXMvU2VxdWVuY2VPcHRpb25zLnRzIiwiLi4vc3JjL3F1ZXJ5L2NvbnN0YW50cy50cyIsIi4uL3NyYy9xdWVyeS9lcnJvcnMudHMiLCIuLi9zcmMvcXVlcnkvQ29uZGl0aW9uLnRzIiwiLi4vc3JjL21vZGVsL2NvbnN0cnVjdGlvbi50cyIsIi4uL3NyYy9tb2RlbC9kZWNvcmF0b3JzLnRzIiwiLi4vc3JjL2lkZW50aXR5L2RlY29yYXRvcnMudHMiLCIuLi9zcmMvbW9kZWwvQmFzZU1vZGVsLnRzIiwiLi4vc3JjL3F1ZXJ5L1BhZ2luYXRvci50cyIsIi4uL3NyYy9xdWVyeS9TdGF0ZW1lbnQudHMiLCIuLi9zcmMvaW5kZXgudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ2FzY2FkZU1ldGFkYXRhIH0gZnJvbSBcIi4vdHlwZXNcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gRW51bWVyYXRpb24gb2YgcG9zc2libGUgc29ydCBkaXJlY3Rpb25zLlxuICogQHN1bW1hcnkgRGVmaW5lcyB0aGUgYXZhaWxhYmxlIHNvcnQgZGlyZWN0aW9ucyBmb3Igb3JkZXJpbmcgcXVlcnkgcmVzdWx0cy5cbiAqIEBlbnVtIHtzdHJpbmd9XG4gKiBAcmVhZG9ubHlcbiAqIEBtZW1iZXJPZiBtb2R1bGU6Y29yZVxuICovXG5leHBvcnQgZW51bSBPcmRlckRpcmVjdGlvbiB7XG4gIC8qKiBBc2NlbmRpbmcgb3JkZXIgKEEgdG8gWiwgMCB0byA5KSAqL1xuICBBU0MgPSBcImFzY1wiLFxuXG4gIC8qKiBEZXNjZW5kaW5nIG9yZGVyIChaIHRvIEEsIDkgdG8gMCkgKi9cbiAgRFNDID0gXCJkZXNjXCIsXG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEVudW1lcmF0aW9uIG9mIGNhc2NhZGUgb3BlcmF0aW9uIHR5cGVzLlxuICogQHN1bW1hcnkgRGVmaW5lcyB0aGUgYXZhaWxhYmxlIGNhc2NhZGUgYmVoYXZpb3JzIGZvciBlbnRpdHkgcmVsYXRpb25zaGlwcy5cbiAqIEBlbnVtIHtzdHJpbmd9XG4gKiBAcmVhZG9ubHlcbiAqIEBtZW1iZXJPZiBtb2R1bGU6Y29yZVxuICovXG5leHBvcnQgZW51bSBDYXNjYWRlIHtcbiAgLyoqIFBlcmZvcm0gY2FzY2FkZSBvcGVyYXRpb24gb24gcmVsYXRlZCBlbnRpdGllcyAqL1xuICBDQVNDQURFID0gXCJjYXNjYWRlXCIsXG4gIC8qKiBEbyBub3QgcGVyZm9ybSBjYXNjYWRlIG9wZXJhdGlvbiBvbiByZWxhdGVkIGVudGl0aWVzICovXG4gIE5PTkUgPSBcIm5vbmVcIixcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gRGVmYXVsdCBjYXNjYWRlIGNvbmZpZ3VyYXRpb24gZm9yIGVudGl0eSByZWxhdGlvbnNoaXBzLlxuICogQHN1bW1hcnkgUHJvdmlkZXMgdGhlIGRlZmF1bHQgY2FzY2FkZSBiZWhhdmlvciB3aGVyZSB1cGRhdGVzIGNhc2NhZGUgYnV0IGRlbGV0ZXMgZG8gbm90LlxuICogQHR5cGUge0Nhc2NhZGVNZXRhZGF0YX1cbiAqIEBjb25zdCBEZWZhdWx0Q2FzY2FkZVxuICogQG1lbWJlck9mIG1vZHVsZTpjb3JlXG4gKi9cbmV4cG9ydCBjb25zdCBEZWZhdWx0Q2FzY2FkZTogQ2FzY2FkZU1ldGFkYXRhID0ge1xuICB1cGRhdGU6IENhc2NhZGUuQ0FTQ0FERSxcbiAgZGVsZXRlOiBDYXNjYWRlLk5PTkUsXG59O1xuIiwiLyoqXG4gKiBAZGVzY3JpcHRpb24gUGVyc2lzdGVuY2UtcmVsYXRlZCBjb25zdGFudCBrZXlzXG4gKiBAc3VtbWFyeSBFbnVtIGNvbnRhaW5pbmcgc3RyaW5nIGNvbnN0YW50cyB1c2VkIHRocm91Z2hvdXQgdGhlIHBlcnNpc3RlbmNlIGxheWVyIGZvciBtZXRhZGF0YSwgcmVsYXRpb25zLCBhbmQgb3RoZXIgcGVyc2lzdGVuY2UtcmVsYXRlZCBvcGVyYXRpb25zXG4gKiBAZW51bSB7c3RyaW5nfVxuICogQHJlYWRvbmx5XG4gKiBAbWVtYmVyT2YgbW9kdWxlOmNvcmVcbiAqL1xuZXhwb3J0IGVudW0gUGVyc2lzdGVuY2VLZXlzIHtcbiAgLyoqIEBkZXNjcmlwdGlvbiBLZXkgZm9yIGluZGV4IG1ldGFkYXRhICovXG4gIElOREVYID0gXCJpbmRleFwiLFxuXG4gIC8qKiBAZGVzY3JpcHRpb24gS2V5IGZvciB1bmlxdWUgY29uc3RyYWludCBtZXRhZGF0YSAqL1xuICBVTklRVUUgPSBcInVuaXF1ZVwiLFxuXG4gIC8qKiBAZGVzY3JpcHRpb24gS2V5IGZvciBhZGFwdGVyIG1ldGFkYXRhICovXG4gIEFEQVBURVIgPSBcImFkYXB0ZXJcIixcblxuICAvKiogQGRlc2NyaXB0aW9uIFRlbXBsYXRlIGZvciBpbmplY3RhYmxlIGFkYXB0ZXIgbmFtZXMgKi9cbiAgSU5KRUNUQUJMRSA9IFwiZGVjYWZfezB9X2FkYXB0ZXJfZm9yX3sxfVwiLFxuXG4gIC8qKiBAZGVzY3JpcHRpb24gS2V5IGZvciB0YWJsZSBuYW1lIG1ldGFkYXRhICovXG4gIFRBQkxFID0gXCJ0YWJsZVwiLFxuXG4gIC8qKiBAZGVzY3JpcHRpb24gS2V5IGZvciBjb2x1bW4gbmFtZSBtZXRhZGF0YSAqL1xuICBDT0xVTU4gPSBcImNvbHVtblwiLFxuXG4gIC8qKiBAZGVzY3JpcHRpb24gS2V5IGZvciBnZW5lcmFsIG1ldGFkYXRhIHN0b3JhZ2UgKi9cbiAgTUVUQURBVEEgPSBcIl9fbWV0YWRhdGFcIixcblxuICAvKiogQGRlc2NyaXB0aW9uIEtleSBmb3IgcmVsYXRpb25zIG1ldGFkYXRhIHN0b3JhZ2UgKi9cbiAgUkVMQVRJT05TID0gXCJfX3JlbGF0aW9uc1wiLFxuXG4gIC8qKiBAZGVzY3JpcHRpb24gS2V5IGZvciBjbGF1c2Ugc2VxdWVuY2UgbWV0YWRhdGEgKi9cbiAgQ0xBVVNFX1NFUVVFTkNFID0gXCJjbGF1c2Utc2VxdWVuY2VcIixcblxuICAvLyBPd25lcnNoaXBcbiAgLyoqIEBkZXNjcmlwdGlvbiBLZXkgZm9yIGNyZWF0ZWQtYnkgb3duZXJzaGlwIG1ldGFkYXRhICovXG4gIENSRUFURURfQlkgPSBcIm93bmVyc2hpcC5jcmVhdGVkLWJ5XCIsXG5cbiAgLyoqIEBkZXNjcmlwdGlvbiBLZXkgZm9yIHVwZGF0ZWQtYnkgb3duZXJzaGlwIG1ldGFkYXRhICovXG4gIFVQREFURURfQlkgPSBcIm93bmVyc2hpcC51cGRhdGVkLWJ5XCIsXG5cbiAgLy8gUmVsYXRpb25zXG4gIC8qKiBAZGVzY3JpcHRpb24gS2V5IGZvciBvbmUtdG8tb25lIHJlbGF0aW9uIG1ldGFkYXRhICovXG4gIE9ORV9UT19PTkUgPSBcInJlbGF0aW9ucy5vbmUtdG8tb25lXCIsXG5cbiAgLyoqIEBkZXNjcmlwdGlvbiBLZXkgZm9yIG9uZS10by1tYW55IHJlbGF0aW9uIG1ldGFkYXRhICovXG4gIE9ORV9UT19NQU5ZID0gXCJyZWxhdGlvbnMub25lLXRvLW1hbnlcIixcblxuICAvKiogQGRlc2NyaXB0aW9uIEtleSBmb3IgbWFueS10by1vbmUgcmVsYXRpb24gbWV0YWRhdGEgKi9cbiAgTUFOWV9UT19PTkUgPSBcInJlbGF0aW9ucy5tYW55LXRvLW9uZVwiLFxuXG4gIC8qKiBAZGVzY3JpcHRpb24gS2V5IGZvciBwb3B1bGF0ZSBtZXRhZGF0YSAqL1xuICBQT1BVTEFURSA9IFwicG9wdWxhdGVcIixcbn1cbiIsIi8qKlxuICogQGRlc2NyaXB0aW9uIENyZWF0ZXMgYSBkZWNvcmF0b3IgdGhhdCBtYWtlcyBhIG1ldGhvZCBub24tY29uZmlndXJhYmxlXG4gKiBAc3VtbWFyeSBUaGlzIGRlY29yYXRvciBwcmV2ZW50cyBhIG1ldGhvZCBmcm9tIGJlaW5nIG92ZXJyaWRkZW4gYnkgbWFraW5nIGl0IG5vbi1jb25maWd1cmFibGUuXG4gKiBJdCB0aHJvd3MgYW4gZXJyb3IgaWYgdXNlZCBvbiBhbnl0aGluZyBvdGhlciB0aGFuIGEgbWV0aG9kLlxuICogQHJldHVybiB7RnVuY3Rpb259IEEgZGVjb3JhdG9yIGZ1bmN0aW9uIHRoYXQgY2FuIGJlIGFwcGxpZWQgdG8gbWV0aG9kc1xuICogQGZ1bmN0aW9uIGZpbmFsXG4gKiBAY2F0ZWdvcnkgTWV0aG9kIERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZpbmFsKCkge1xuICByZXR1cm4gKFxuICAgIHRhcmdldDogb2JqZWN0LFxuICAgIHByb3BlcnR5S2V5PzogYW55LFxuICAgIGRlc2NyaXB0b3I/OiBQcm9wZXJ0eURlc2NyaXB0b3JcbiAgKSA9PiB7XG4gICAgaWYgKCFkZXNjcmlwdG9yKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiZmluYWwgZGVjb3JhdG9yIGNhbiBvbmx5IGJlIHVzZWQgb24gbWV0aG9kc1wiKTtcbiAgICBpZiAoZGVzY3JpcHRvcj8uY29uZmlndXJhYmxlKSB7XG4gICAgICBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gZGVzY3JpcHRvcjtcbiAgfTtcbn1cbiIsImltcG9ydCB7IEJhc2VFcnJvciB9IGZyb20gXCJAZGVjYWYtdHMvZGItZGVjb3JhdG9yc1wiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBFcnJvciB0aHJvd24gd2hlbiBhIHVzZXIgaXMgbm90IGF1dGhvcml6ZWQgdG8gcGVyZm9ybSBhbiBhY3Rpb25cbiAqIEBzdW1tYXJ5IFRoaXMgZXJyb3IgaXMgdGhyb3duIHdoZW4gYSB1c2VyIGF0dGVtcHRzIHRvIGFjY2VzcyBhIHJlc291cmNlIG9yIHBlcmZvcm0gYW4gYWN0aW9uIHdpdGhvdXQgcHJvcGVyIGF1dGhlbnRpY2F0aW9uXG4gKiBAcGFyYW0ge3N0cmluZ3xFcnJvcn0gbXNnIC0gVGhlIGVycm9yIG1lc3NhZ2Ugb3IgRXJyb3Igb2JqZWN0XG4gKiBAY2xhc3MgQXV0aG9yaXphdGlvbkVycm9yXG4gKiBAY2F0ZWdvcnkgRXJyb3JzXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogLy8gRXhhbXBsZSBvZiB0aHJvd2luZyBhbiBBdXRob3JpemF0aW9uRXJyb3JcbiAqIGlmICghdXNlci5pc0F1dGhlbnRpY2F0ZWQoKSkge1xuICogICB0aHJvdyBuZXcgQXV0aG9yaXphdGlvbkVycm9yKCdVc2VyIG5vdCBhdXRoZW50aWNhdGVkJyk7XG4gKiB9XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGNsYXNzIEF1dGhvcml6YXRpb25FcnJvciBleHRlbmRzIEJhc2VFcnJvciB7XG4gIGNvbnN0cnVjdG9yKG1zZzogc3RyaW5nIHwgRXJyb3IpIHtcbiAgICBzdXBlcihBdXRob3JpemF0aW9uRXJyb3IubmFtZSwgbXNnLCA0MDEpO1xuICB9XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEVycm9yIHRocm93biB3aGVuIGEgdXNlciBpcyBmb3JiaWRkZW4gZnJvbSBhY2Nlc3NpbmcgYSByZXNvdXJjZVxuICogQHN1bW1hcnkgVGhpcyBlcnJvciBpcyB0aHJvd24gd2hlbiBhbiBhdXRoZW50aWNhdGVkIHVzZXIgYXR0ZW1wdHMgdG8gYWNjZXNzIGEgcmVzb3VyY2Ugb3IgcGVyZm9ybSBhbiBhY3Rpb24gdGhleSBkb24ndCBoYXZlIHBlcm1pc3Npb24gZm9yXG4gKiBAcGFyYW0ge3N0cmluZ3xFcnJvcn0gbXNnIC0gVGhlIGVycm9yIG1lc3NhZ2Ugb3IgRXJyb3Igb2JqZWN0XG4gKiBAcmV0dXJuIHt2b2lkfVxuICogQGNsYXNzIEZvcmJpZGRlbkVycm9yXG4gKiBAY2F0ZWdvcnkgRXJyb3JzXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogLy8gRXhhbXBsZSBvZiB0aHJvd2luZyBhIEZvcmJpZGRlbkVycm9yXG4gKiBpZiAoIXVzZXIuaGFzUGVybWlzc2lvbignYWRtaW4nKSkge1xuICogICB0aHJvdyBuZXcgRm9yYmlkZGVuRXJyb3IoJ1VzZXIgZG9lcyBub3QgaGF2ZSBhZG1pbiBwZXJtaXNzaW9ucycpO1xuICogfVxuICogYGBgXG4gKi9cbmV4cG9ydCBjbGFzcyBGb3JiaWRkZW5FcnJvciBleHRlbmRzIEJhc2VFcnJvciB7XG4gIGNvbnN0cnVjdG9yKG1zZzogc3RyaW5nIHwgRXJyb3IpIHtcbiAgICBzdXBlcihGb3JiaWRkZW5FcnJvci5uYW1lLCBtc2csIDQwMyk7XG4gIH1cbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gRXJyb3IgdGhyb3duIHdoZW4gYSBjb25uZWN0aW9uIHRvIGEgc2VydmljZSBmYWlsc1xuICogQHN1bW1hcnkgVGhpcyBlcnJvciBpcyB0aHJvd24gd2hlbiB0aGUgYXBwbGljYXRpb24gZmFpbHMgdG8gZXN0YWJsaXNoIGEgY29ubmVjdGlvbiB0byBhIHJlcXVpcmVkIHNlcnZpY2Ugb3IgcmVzb3VyY2VcbiAqIEBwYXJhbSB7c3RyaW5nfEVycm9yfSBtc2cgLSBUaGUgZXJyb3IgbWVzc2FnZSBvciBFcnJvciBvYmplY3RcbiAqIEByZXR1cm4ge3ZvaWR9XG4gKiBAY2xhc3MgQ29ubmVjdGlvbkVycm9yXG4gKiBAY2F0ZWdvcnkgRXJyb3JzXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogLy8gRXhhbXBsZSBvZiB0aHJvd2luZyBhIENvbm5lY3Rpb25FcnJvclxuICogdHJ5IHtcbiAqICAgYXdhaXQgZGF0YWJhc2UuY29ubmVjdCgpO1xuICogfSBjYXRjaCAoZXJyb3IpIHtcbiAqICAgdGhyb3cgbmV3IENvbm5lY3Rpb25FcnJvcignRmFpbGVkIHRvIGNvbm5lY3QgdG8gZGF0YWJhc2UnKTtcbiAqIH1cbiAqIGBgYFxuICovXG5leHBvcnQgY2xhc3MgQ29ubmVjdGlvbkVycm9yIGV4dGVuZHMgQmFzZUVycm9yIHtcbiAgY29uc3RydWN0b3IobXNnOiBzdHJpbmcgfCBFcnJvcikge1xuICAgIHN1cGVyKENvbm5lY3Rpb25FcnJvci5uYW1lLCBtc2csIDUwMyk7XG4gIH1cbn1cbiIsImltcG9ydCB7IEJhc2VFcnJvciB9IGZyb20gXCJAZGVjYWYtdHMvZGItZGVjb3JhdG9yc1wiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBFcnJvciB0aHJvd24gd2hlbiBhbiB1bnN1cHBvcnRlZCBvcGVyYXRpb24gaXMgYXR0ZW1wdGVkXG4gKiBAc3VtbWFyeSBUaGlzIGVycm9yIGlzIHRocm93biB3aGVuIGFuIG9wZXJhdGlvbiBpcyByZXF1ZXN0ZWQgdGhhdCBpcyBub3Qgc3VwcG9ydGVkIGJ5IHRoZSBjdXJyZW50XG4gKiBwZXJzaXN0ZW5jZSBhZGFwdGVyIG9yIGNvbmZpZ3VyYXRpb24uIEl0IGV4dGVuZHMgdGhlIEJhc2VFcnJvciBjbGFzcyBhbmQgc2V0cyBhIDUwMCBzdGF0dXMgY29kZS5cbiAqIEBwYXJhbSB7c3RyaW5nfEVycm9yfSBtc2cgLSBUaGUgZXJyb3IgbWVzc2FnZSBvciBhbiBFcnJvciBvYmplY3QgdG8gd3JhcFxuICogQGNsYXNzIFVuc3VwcG9ydGVkRXJyb3JcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiAvLyBUaHJvd2luZyBhbiBVbnN1cHBvcnRlZEVycm9yXG4gKiBpZiAoIWFkYXB0ZXIuc3VwcG9ydHNUcmFuc2FjdGlvbnMoKSkge1xuICogICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRFcnJvcignVHJhbnNhY3Rpb25zIGFyZSBub3Qgc3VwcG9ydGVkIGJ5IHRoaXMgYWRhcHRlcicpO1xuICogfVxuICogXG4gKiAvLyBDYXRjaGluZyBhbiBVbnN1cHBvcnRlZEVycm9yXG4gKiB0cnkge1xuICogICBhd2FpdCBhZGFwdGVyLmJlZ2luVHJhbnNhY3Rpb24oKTtcbiAqIH0gY2F0Y2ggKGVycm9yKSB7XG4gKiAgIGlmIChlcnJvciBpbnN0YW5jZW9mIFVuc3VwcG9ydGVkRXJyb3IpIHtcbiAqICAgICBjb25zb2xlLmVycm9yKCdPcGVyYXRpb24gbm90IHN1cHBvcnRlZDonLCBlcnJvci5tZXNzYWdlKTtcbiAqICAgfVxuICogfVxuICogYGBgXG4gKi9cbmV4cG9ydCBjbGFzcyBVbnN1cHBvcnRlZEVycm9yIGV4dGVuZHMgQmFzZUVycm9yIHtcbiAgY29uc3RydWN0b3IobXNnOiBzdHJpbmcgfCBFcnJvcikge1xuICAgIHN1cGVyKFVuc3VwcG9ydGVkRXJyb3IubmFtZSwgbXNnLCA1MDApO1xuICB9XG59XG4iLCJpbXBvcnQge1xuICBJbnRlcm5hbEVycm9yLFxuICBPcGVyYXRpb25LZXlzLFxuICBCdWxrQ3J1ZE9wZXJhdGlvbktleXMsXG59IGZyb20gXCJAZGVjYWYtdHMvZGItZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHsgTW9kZWxDb25zdHJ1Y3RvciB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7IE9ic2VydmFibGUsIE9ic2VydmVyIH0gZnJvbSBcIi4uL2ludGVyZmFjZXNcIjtcbmltcG9ydCB7IEFkYXB0ZXIgfSBmcm9tIFwiLi9BZGFwdGVyXCI7XG5pbXBvcnQgeyBVbnN1cHBvcnRlZEVycm9yIH0gZnJvbSBcIi4vZXJyb3JzXCI7XG5pbXBvcnQgeyBMb2dnZXIsIExvZ2dpbmcgfSBmcm9tIFwiQGRlY2FmLXRzL2xvZ2dpbmdcIjtcbmltcG9ydCB7IEV2ZW50SWRzIH0gZnJvbSBcIi4vdHlwZXNcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gRGlzcGF0Y2hlcyBkYXRhYmFzZSBvcGVyYXRpb24gZXZlbnRzIHRvIG9ic2VydmVyc1xuICogQHN1bW1hcnkgVGhlIERpc3BhdGNoIGNsYXNzIGltcGxlbWVudHMgdGhlIE9ic2VydmFibGUgaW50ZXJmYWNlIGFuZCBpcyByZXNwb25zaWJsZSBmb3IgaW50ZXJjZXB0aW5nXG4gKiBkYXRhYmFzZSBvcGVyYXRpb25zIGZyb20gYW4gQWRhcHRlciBhbmQgbm90aWZ5aW5nIG9ic2VydmVycyB3aGVuIGNoYW5nZXMgb2NjdXIuIEl0IHVzZXMgcHJveGllcyB0b1xuICogd3JhcCB0aGUgYWRhcHRlcidzIENSVUQgbWV0aG9kcyBhbmQgYXV0b21hdGljYWxseSB0cmlnZ2VyIG9ic2VydmVyIHVwZGF0ZXMgYWZ0ZXIgb3BlcmF0aW9ucyBjb21wbGV0ZS5cbiAqIEB0ZW1wbGF0ZSBZIC0gVGhlIG5hdGl2ZSBkYXRhYmFzZSBkcml2ZXIgdHlwZVxuICogQHBhcmFtIHt2b2lkfSAtIE5vIGNvbnN0cnVjdG9yIHBhcmFtZXRlcnNcbiAqIEBjbGFzcyBEaXNwYXRjaFxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIC8vIENyZWF0aW5nIGFuZCB1c2luZyBhIERpc3BhdGNoIGluc3RhbmNlXG4gKiBjb25zdCBkaXNwYXRjaCA9IG5ldyBEaXNwYXRjaDxQb3N0Z3Jlc0RyaXZlcj4oKTtcbiAqXG4gKiAvLyBDb25uZWN0IGl0IHRvIGFuIGFkYXB0ZXJcbiAqIGNvbnN0IGFkYXB0ZXIgPSBuZXcgUG9zdGdyZXNBZGFwdGVyKGNvbm5lY3Rpb24pO1xuICogZGlzcGF0Y2gub2JzZXJ2ZShhZGFwdGVyKTtcbiAqXG4gKiAvLyBOb3cgYW55IENSVUQgb3BlcmF0aW9ucyBvbiB0aGUgYWRhcHRlciB3aWxsIGF1dG9tYXRpY2FsbHlcbiAqIC8vIHRyaWdnZXIgb2JzZXJ2ZXIgbm90aWZpY2F0aW9uc1xuICogYXdhaXQgYWRhcHRlci5jcmVhdGUoJ3VzZXJzJywgMTIzLCB1c2VyTW9kZWwpO1xuICogLy8gT2JzZXJ2ZXJzIHdpbGwgYmUgbm90aWZpZWQgYWJvdXQgdGhlIGNyZWF0aW9uXG4gKlxuICogLy8gV2hlbiBkb25lLCB5b3UgY2FuIGRpc2Nvbm5lY3RcbiAqIGRpc3BhdGNoLnVuT2JzZXJ2ZShhZGFwdGVyKTtcbiAqIGBgYFxuICovXG5leHBvcnQgY2xhc3MgRGlzcGF0Y2g8WT4gaW1wbGVtZW50cyBPYnNlcnZhYmxlIHtcbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBUaGUgYWRhcHRlciBiZWluZyBvYnNlcnZlZFxuICAgKiBAc3VtbWFyeSBSZWZlcmVuY2UgdG8gdGhlIGRhdGFiYXNlIGFkYXB0ZXIgd2hvc2Ugb3BlcmF0aW9ucyBhcmUgYmVpbmcgbW9uaXRvcmVkXG4gICAqL1xuICBwcm90ZWN0ZWQgYWRhcHRlcj86IEFkYXB0ZXI8WSwgYW55LCBhbnksIGFueT47XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBUaGUgbmF0aXZlIGRhdGFiYXNlIGRyaXZlclxuICAgKiBAc3VtbWFyeSBSZWZlcmVuY2UgdG8gdGhlIHVuZGVybHlpbmcgZGF0YWJhc2UgZHJpdmVyIGZyb20gdGhlIGFkYXB0ZXJcbiAgICovXG4gIHByb3RlY3RlZCBuYXRpdmU/OiBZO1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gTGlzdCBvZiBtb2RlbCBjb25zdHJ1Y3RvcnNcbiAgICogQHN1bW1hcnkgQXJyYXkgb2YgbW9kZWwgY29uc3RydWN0b3JzIHRoYXQgYXJlIHJlZ2lzdGVyZWQgd2l0aCB0aGUgYWRhcHRlclxuICAgKi9cbiAgcHJvdGVjdGVkIG1vZGVscyE6IE1vZGVsQ29uc3RydWN0b3I8YW55PltdO1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gTG9nZ2VyIGluc3RhbmNlXG4gICAqIEBzdW1tYXJ5IExvZ2dlciBmb3IgcmVjb3JkaW5nIGRpc3BhdGNoIGFjdGl2aXRpZXNcbiAgICovXG4gIHByaXZhdGUgbG9nZ2VyITogTG9nZ2VyO1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQWNjZXNzb3IgZm9yIHRoZSBsb2dnZXJcbiAgICogQHN1bW1hcnkgR2V0cyBvciBpbml0aWFsaXplcyB0aGUgbG9nZ2VyIGZvciB0aGlzIGRpc3BhdGNoIGluc3RhbmNlXG4gICAqIEByZXR1cm4ge0xvZ2dlcn0gVGhlIGxvZ2dlciBpbnN0YW5jZVxuICAgKi9cbiAgcHJvdGVjdGVkIGdldCBsb2coKSB7XG4gICAgaWYgKCF0aGlzLmxvZ2dlcilcbiAgICAgIHRoaXMubG9nZ2VyID0gTG9nZ2luZy5mb3IodGhpcyBhcyBhbnkpLmZvcih0aGlzLmFkYXB0ZXIgYXMgYW55KTtcbiAgICByZXR1cm4gdGhpcy5sb2dnZXI7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENyZWF0ZXMgYSBuZXcgRGlzcGF0Y2ggaW5zdGFuY2VcbiAgICogQHN1bW1hcnkgSW5pdGlhbGl6ZXMgYSBuZXcgRGlzcGF0Y2ggaW5zdGFuY2Ugd2l0aG91dCBhbnkgYWRhcHRlclxuICAgKi9cbiAgY29uc3RydWN0b3IoKSB7fVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gSW5pdGlhbGl6ZXMgdGhlIGRpc3BhdGNoIGJ5IHByb3h5aW5nIGFkYXB0ZXIgbWV0aG9kc1xuICAgKiBAc3VtbWFyeSBTZXRzIHVwIHByb3hpZXMgb24gdGhlIGFkYXB0ZXIncyBDUlVEIG1ldGhvZHMgdG8gaW50ZXJjZXB0IG9wZXJhdGlvbnMgYW5kIG5vdGlmeSBvYnNlcnZlcnMuXG4gICAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBhdXRvbWF0aWNhbGx5IHdoZW4gYW4gYWRhcHRlciBpcyBvYnNlcnZlZC5cbiAgICogQHJldHVybiB7UHJvbWlzZTx2b2lkPn0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiBpbml0aWFsaXphdGlvbiBpcyBjb21wbGV0ZVxuICAgKiBAbWVybWFpZFxuICAgKiBzZXF1ZW5jZURpYWdyYW1cbiAgICogICBwYXJ0aWNpcGFudCBEaXNwYXRjaFxuICAgKiAgIHBhcnRpY2lwYW50IEFkYXB0ZXJcbiAgICogICBwYXJ0aWNpcGFudCBQcm94eVxuICAgKlxuICAgKiAgIERpc3BhdGNoLT4+RGlzcGF0Y2g6IGluaXRpYWxpemUoKVxuICAgKiAgIERpc3BhdGNoLT4+RGlzcGF0Y2g6IENoZWNrIGlmIGFkYXB0ZXIgZXhpc3RzXG4gICAqICAgYWx0IE5vIGFkYXB0ZXJcbiAgICogICAgIERpc3BhdGNoLS0+PkRpc3BhdGNoOiBUaHJvdyBJbnRlcm5hbEVycm9yXG4gICAqICAgZW5kXG4gICAqXG4gICAqICAgbG9vcCBGb3IgZWFjaCBDUlVEIG1ldGhvZFxuICAgKiAgICAgRGlzcGF0Y2gtPj5BZGFwdGVyOiBDaGVjayBpZiBtZXRob2QgZXhpc3RzXG4gICAqICAgICBhbHQgTWV0aG9kIGRvZXNuJ3QgZXhpc3RcbiAgICogICAgICAgRGlzcGF0Y2gtLT4+RGlzcGF0Y2g6IFRocm93IEludGVybmFsRXJyb3JcbiAgICogICAgIGVuZFxuICAgKlxuICAgKiAgICAgRGlzcGF0Y2gtPj5BZGFwdGVyOiBHZXQgcHJvcGVydHkgZGVzY3JpcHRvclxuICAgKiAgICAgbG9vcCBXaGlsZSBkZXNjcmlwdG9yIG5vdCBmb3VuZFxuICAgKiAgICAgICBEaXNwYXRjaC0+PkFkYXB0ZXI6IENoZWNrIHByb3RvdHlwZSBjaGFpblxuICAgKiAgICAgZW5kXG4gICAqXG4gICAqICAgICBhbHQgRGVzY3JpcHRvciBub3QgZm91bmQgb3Igbm90IHdyaXRhYmxlXG4gICAqICAgICAgIERpc3BhdGNoLT4+RGlzcGF0Y2g6IExvZyBlcnJvciBhbmQgY29udGludWVcbiAgICogICAgIGVsc2UgRGVzY3JpcHRvciBmb3VuZCBhbmQgd3JpdGFibGVcbiAgICogICAgICAgRGlzcGF0Y2gtPj5Qcm94eTogQ3JlYXRlIHByb3h5IGZvciBtZXRob2RcbiAgICogICAgICAgRGlzcGF0Y2gtPj5BZGFwdGVyOiBSZXBsYWNlIG1ldGhvZCB3aXRoIHByb3h5XG4gICAqICAgICBlbmRcbiAgICogICBlbmRcbiAgICovXG4gIHByb3RlY3RlZCBhc3luYyBpbml0aWFsaXplKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICghdGhpcy5hZGFwdGVyKVxuICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoYE5vIGFkYXB0ZXIgb2JzZXJ2ZWQgZm9yIGRpc3BhdGNoYCk7XG4gICAgY29uc3QgYWRhcHRlciA9IHRoaXMuYWRhcHRlciBhcyBBZGFwdGVyPFksIGFueSwgYW55LCBhbnk+O1xuICAgIChcbiAgICAgIFtcbiAgICAgICAgT3BlcmF0aW9uS2V5cy5DUkVBVEUsXG4gICAgICAgIE9wZXJhdGlvbktleXMuVVBEQVRFLFxuICAgICAgICBPcGVyYXRpb25LZXlzLkRFTEVURSxcbiAgICAgICAgQnVsa0NydWRPcGVyYXRpb25LZXlzLkNSRUFURV9BTEwsXG4gICAgICAgIEJ1bGtDcnVkT3BlcmF0aW9uS2V5cy5VUERBVEVfQUxMLFxuICAgICAgICBCdWxrQ3J1ZE9wZXJhdGlvbktleXMuREVMRVRFX0FMTCxcbiAgICAgIF0gYXMgKGtleW9mIEFkYXB0ZXI8WSwgYW55LCBhbnksIGFueT4pW11cbiAgICApLmZvckVhY2goKG1ldGhvZCkgPT4ge1xuICAgICAgaWYgKCFhZGFwdGVyW21ldGhvZF0pXG4gICAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFxuICAgICAgICAgIGBNZXRob2QgJHttZXRob2R9IG5vdCBmb3VuZCBpbiAke2FkYXB0ZXIuYWxpYXN9IGFkYXB0ZXIgdG8gYmluZCBPYnNlcnZhYmxlcyBEaXNwYXRjaGBcbiAgICAgICAgKTtcblxuICAgICAgbGV0IGRlc2NyaXB0b3IgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKGFkYXB0ZXIsIG1ldGhvZCk7XG4gICAgICBsZXQgcHJvdG86IGFueSA9IGFkYXB0ZXI7XG4gICAgICB3aGlsZSAoIWRlc2NyaXB0b3IgJiYgcHJvdG8gIT09IE9iamVjdC5wcm90b3R5cGUpIHtcbiAgICAgICAgcHJvdG8gPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YocHJvdG8pO1xuICAgICAgICBkZXNjcmlwdG9yID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihwcm90bywgbWV0aG9kKTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFkZXNjcmlwdG9yIHx8ICFkZXNjcmlwdG9yLndyaXRhYmxlKSB7XG4gICAgICAgIHRoaXMubG9nLmVycm9yKFxuICAgICAgICAgIGBDb3VsZCBub3QgZmluZCBtZXRob2QgJHttZXRob2R9IHRvIGJpbmQgT2JzZXJ2YWJsZXMgRGlzcGF0Y2hgXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGZ1bmN0aW9uIGJ1bGtUb1NpbmdsZShtZXRob2Q6IHN0cmluZykge1xuICAgICAgICBzd2l0Y2ggKG1ldGhvZCkge1xuICAgICAgICAgIGNhc2UgQnVsa0NydWRPcGVyYXRpb25LZXlzLkNSRUFURV9BTEw6XG4gICAgICAgICAgICByZXR1cm4gT3BlcmF0aW9uS2V5cy5DUkVBVEU7XG4gICAgICAgICAgY2FzZSBCdWxrQ3J1ZE9wZXJhdGlvbktleXMuVVBEQVRFX0FMTDpcbiAgICAgICAgICAgIHJldHVybiBPcGVyYXRpb25LZXlzLlVQREFURTtcbiAgICAgICAgICBjYXNlIEJ1bGtDcnVkT3BlcmF0aW9uS2V5cy5ERUxFVEVfQUxMOlxuICAgICAgICAgICAgcmV0dXJuIE9wZXJhdGlvbktleXMuREVMRVRFO1xuICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICByZXR1cm4gbWV0aG9kO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICAvLyBAdHMtZXhwZWN0LWVycm9yIGJlY2F1c2UgdGhlcmUgYXJlIHJlYWQgb25seSBwcm9wZXJ0aWVzXG4gICAgICBhZGFwdGVyW21ldGhvZF0gPSBuZXcgUHJveHkoYWRhcHRlclttZXRob2RdLCB7XG4gICAgICAgIGFwcGx5OiBhc3luYyAodGFyZ2V0OiBhbnksIHRoaXNBcmcsIGFyZ0FycmF5OiBhbnlbXSkgPT4ge1xuICAgICAgICAgIGNvbnN0IFt0YWJsZU5hbWUsIGlkc10gPSBhcmdBcnJheTtcbiAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0YXJnZXQuYXBwbHkodGhpc0FyZywgYXJnQXJyYXkpO1xuICAgICAgICAgIHRoaXMudXBkYXRlT2JzZXJ2ZXJzKHRhYmxlTmFtZSwgYnVsa1RvU2luZ2xlKG1ldGhvZCksIGlkcyBhcyBFdmVudElkcylcbiAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgdGhpcy5sb2cudmVyYm9zZShcbiAgICAgICAgICAgICAgICBgT2JzZXJ2ZXIgcmVmcmVzaCBkaXNwYXRjaGVkIGJ5ICR7bWV0aG9kfSBmb3IgJHt0YWJsZU5hbWV9YFxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICB0aGlzLmxvZy5kZWJ1ZyhgcGtzOiAke2lkc31gKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuY2F0Y2goKGU6IHVua25vd24pID0+XG4gICAgICAgICAgICAgIHRoaXMubG9nLmVycm9yKFxuICAgICAgICAgICAgICAgIGBGYWlsZWQgdG8gZGlzcGF0Y2ggb2JzZXJ2ZXIgcmVmcmVzaCBmb3IgJHttZXRob2R9IG9uICR7dGFibGVOYW1lfTogJHtlfWBcbiAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENsb3NlcyB0aGUgZGlzcGF0Y2hcbiAgICogQHN1bW1hcnkgUGVyZm9ybXMgYW55IG5lY2Vzc2FyeSBjbGVhbnVwIHdoZW4gdGhlIGRpc3BhdGNoIGlzIG5vIGxvbmdlciBuZWVkZWRcbiAgICogQHJldHVybiB7UHJvbWlzZTx2b2lkPn0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiBjbG9zaW5nIGlzIGNvbXBsZXRlXG4gICAqL1xuICBhc3luYyBjbG9zZSgpIHtcbiAgICAvLyB0byBub3RoaW5nIGluIHRoaXMgaW5zdGFuY2UgYnV0IG1heSBiZSByZXF1aXJlZCBmb3IgY2xvc2luZyBjb25uZWN0aW9uc1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBTdGFydHMgb2JzZXJ2aW5nIGFuIGFkYXB0ZXJcbiAgICogQHN1bW1hcnkgQ29ubmVjdHMgdGhpcyBkaXNwYXRjaCB0byBhbiBhZGFwdGVyIHRvIG1vbml0b3IgaXRzIG9wZXJhdGlvbnNcbiAgICogQHBhcmFtIHtBZGFwdGVyPFksIGFueSwgYW55LCBhbnk+fSBvYnNlcnZlciAtIFRoZSBhZGFwdGVyIHRvIG9ic2VydmVcbiAgICogQHJldHVybiB7dm9pZH1cbiAgICovXG4gIG9ic2VydmUob2JzZXJ2ZXI6IEFkYXB0ZXI8WSwgYW55LCBhbnksIGFueT4pOiB2b2lkIHtcbiAgICBpZiAoIShvYnNlcnZlciBpbnN0YW5jZW9mIEFkYXB0ZXIpKVxuICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkRXJyb3IoXCJPbmx5IEFkYXB0ZXJzIGNhbiBiZSBvYnNlcnZlZCBieSBkaXNwYXRjaFwiKTtcbiAgICB0aGlzLmFkYXB0ZXIgPSBvYnNlcnZlcjtcbiAgICB0aGlzLm5hdGl2ZSA9IG9ic2VydmVyLm5hdGl2ZTtcbiAgICB0aGlzLm1vZGVscyA9IEFkYXB0ZXIubW9kZWxzKHRoaXMuYWRhcHRlci5hbGlhcyk7XG4gICAgdGhpcy5pbml0aWFsaXplKCkudGhlbigoKSA9PlxuICAgICAgdGhpcy5sb2cudmVyYm9zZShcbiAgICAgICAgYERpc3BhdGNoIGluaXRpYWxpemVkIGZvciAke3RoaXMuYWRhcHRlciEuYWxpYXN9IGFkYXB0ZXJgXG4gICAgICApXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gU3RvcHMgb2JzZXJ2aW5nIGFuIGFkYXB0ZXJcbiAgICogQHN1bW1hcnkgRGlzY29ubmVjdHMgdGhpcyBkaXNwYXRjaCBmcm9tIGFuIGFkYXB0ZXJcbiAgICogQHBhcmFtIHtPYnNlcnZlcn0gb2JzZXJ2ZXIgLSBUaGUgYWRhcHRlciB0byBzdG9wIG9ic2VydmluZ1xuICAgKiBAcmV0dXJuIHt2b2lkfVxuICAgKi9cbiAgdW5PYnNlcnZlKG9ic2VydmVyOiBPYnNlcnZlcik6IHZvaWQge1xuICAgIGlmICh0aGlzLmFkYXB0ZXIgIT09IG9ic2VydmVyKVxuICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkRXJyb3IoXG4gICAgICAgIFwiT25seSB0aGUgYWRhcHRlciB0aGF0IHdhcyB1c2VkIHRvIG9ic2VydmUgY2FuIGJlIHVub2JzZXJ2ZWRcIlxuICAgICAgKTtcbiAgICB0aGlzLmFkYXB0ZXIgPSB1bmRlZmluZWQ7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFVwZGF0ZXMgb2JzZXJ2ZXJzIGFib3V0IGEgZGF0YWJhc2UgZXZlbnRcbiAgICogQHN1bW1hcnkgTm90aWZpZXMgb2JzZXJ2ZXJzIGFib3V0IGEgY2hhbmdlIGluIHRoZSBkYXRhYmFzZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gdGFibGUgLSBUaGUgbmFtZSBvZiB0aGUgdGFibGUgd2hlcmUgdGhlIGNoYW5nZSBvY2N1cnJlZFxuICAgKiBAcGFyYW0ge09wZXJhdGlvbktleXN8QnVsa0NydWRPcGVyYXRpb25LZXlzfHN0cmluZ30gZXZlbnQgLSBUaGUgdHlwZSBvZiBvcGVyYXRpb24gdGhhdCBvY2N1cnJlZFxuICAgKiBAcGFyYW0ge0V2ZW50SWRzfSBpZCAtIFRoZSBpZGVudGlmaWVyKHMpIG9mIHRoZSBhZmZlY3RlZCByZWNvcmQocylcbiAgICogQHJldHVybiB7UHJvbWlzZTx2b2lkPn0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiBhbGwgb2JzZXJ2ZXJzIGhhdmUgYmVlbiBub3RpZmllZFxuICAgKi9cbiAgYXN5bmMgdXBkYXRlT2JzZXJ2ZXJzKFxuICAgIHRhYmxlOiBzdHJpbmcsXG4gICAgZXZlbnQ6IE9wZXJhdGlvbktleXMgfCBCdWxrQ3J1ZE9wZXJhdGlvbktleXMgfCBzdHJpbmcsXG4gICAgaWQ6IEV2ZW50SWRzXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICghdGhpcy5hZGFwdGVyKVxuICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoYE5vIGFkYXB0ZXIgb2JzZXJ2ZWQgZm9yIGRpc3BhdGNoYCk7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMuYWRhcHRlci5yZWZyZXNoKHRhYmxlLCBldmVudCwgaWQpO1xuICAgIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKGBGYWlsZWQgdG8gcmVmcmVzaCBkaXNwYXRjaDogJHtlfWApO1xuICAgIH1cbiAgfVxufVxuIiwiaW1wb3J0IHsgT2JzZXJ2YWJsZSwgT2JzZXJ2ZXIgfSBmcm9tIFwiLi4vaW50ZXJmYWNlc1wiO1xuaW1wb3J0IHsgRXZlbnRJZHMsIE9ic2VydmVyRmlsdGVyIH0gZnJvbSBcIi4vdHlwZXNcIjtcbmltcG9ydCB7XG4gIEJ1bGtDcnVkT3BlcmF0aW9uS2V5cyxcbiAgSW50ZXJuYWxFcnJvcixcbiAgT3BlcmF0aW9uS2V5cyxcbn0gZnJvbSBcIkBkZWNhZi10cy9kYi1kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBMb2dnZXIgfSBmcm9tIFwiQGRlY2FmLXRzL2xvZ2dpbmdcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gTWFuYWdlcyBhIGNvbGxlY3Rpb24gb2Ygb2JzZXJ2ZXJzIGZvciBkYXRhYmFzZSBldmVudHNcbiAqIEBzdW1tYXJ5IFRoZSBPYnNlcnZlckhhbmRsZXIgY2xhc3MgaW1wbGVtZW50cyB0aGUgT2JzZXJ2YWJsZSBpbnRlcmZhY2UgYW5kIHByb3ZpZGVzIGEgY2VudHJhbGl6ZWRcbiAqIHdheSB0byBtYW5hZ2UgbXVsdGlwbGUgb2JzZXJ2ZXJzLiBJdCBhbGxvd3MgcmVnaXN0ZXJpbmcgb2JzZXJ2ZXJzIHdpdGggb3B0aW9uYWwgZmlsdGVycyB0byBjb250cm9sXG4gKiB3aGljaCBldmVudHMgdGhleSByZWNlaXZlIG5vdGlmaWNhdGlvbnMgZm9yLCBhbmQgaGFuZGxlcyB0aGUgcHJvY2VzcyBvZiBub3RpZnlpbmcgYWxsIHJlbGV2YW50XG4gKiBvYnNlcnZlcnMgd2hlbiBkYXRhYmFzZSBldmVudHMgb2NjdXIuXG4gKiBAY2xhc3MgT2JzZXJ2ZXJIYW5kbGVyXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogLy8gQ3JlYXRlIGFuIG9ic2VydmVyIGhhbmRsZXJcbiAqIGNvbnN0IGhhbmRsZXIgPSBuZXcgT2JzZXJ2ZXJIYW5kbGVyKCk7XG4gKiBcbiAqIC8vIFJlZ2lzdGVyIGFuIG9ic2VydmVyXG4gKiBjb25zdCBteU9ic2VydmVyID0ge1xuICogICByZWZyZXNoOiBhc3luYyAodGFibGUsIGV2ZW50LCBpZCkgPT4ge1xuICogICAgIGNvbnNvbGUubG9nKGBDaGFuZ2UgaW4gJHt0YWJsZX06ICR7ZXZlbnR9IGZvciBJRCAke2lkfWApO1xuICogICB9XG4gKiB9O1xuICogXG4gKiAvLyBBZGQgb2JzZXJ2ZXIgd2l0aCBhIGZpbHRlciBmb3Igb25seSB1c2VyIHRhYmxlIGV2ZW50c1xuICogaGFuZGxlci5vYnNlcnZlKG15T2JzZXJ2ZXIsICh0YWJsZSwgZXZlbnQsIGlkKSA9PiB0YWJsZSA9PT0gJ3VzZXJzJyk7XG4gKiBcbiAqIC8vIE5vdGlmeSBvYnNlcnZlcnMgYWJvdXQgYW4gZXZlbnRcbiAqIGF3YWl0IGhhbmRsZXIudXBkYXRlT2JzZXJ2ZXJzKGxvZ2dlciwgJ3VzZXJzJywgJ0NSRUFURScsIDEyMyk7XG4gKiBcbiAqIC8vIFJlbW92ZSBhbiBvYnNlcnZlciB3aGVuIG5vIGxvbmdlciBuZWVkZWRcbiAqIGhhbmRsZXIudW5PYnNlcnZlKG15T2JzZXJ2ZXIpO1xuICogYGBgXG4gKi9cbmV4cG9ydCBjbGFzcyBPYnNlcnZlckhhbmRsZXIgaW1wbGVtZW50cyBPYnNlcnZhYmxlIHtcbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDb2xsZWN0aW9uIG9mIHJlZ2lzdGVyZWQgb2JzZXJ2ZXJzXG4gICAqIEBzdW1tYXJ5IEFycmF5IG9mIG9ic2VydmVyIG9iamVjdHMgYWxvbmcgd2l0aCB0aGVpciBvcHRpb25hbCBmaWx0ZXJzXG4gICAqL1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgb2JzZXJ2ZXJzOiB7XG4gICAgb2JzZXJ2ZXI6IE9ic2VydmVyO1xuICAgIGZpbHRlcj86IE9ic2VydmVyRmlsdGVyO1xuICB9W10gPSBbXTtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEdldHMgdGhlIG51bWJlciBvZiByZWdpc3RlcmVkIG9ic2VydmVyc1xuICAgKiBAc3VtbWFyeSBSZXR1cm5zIHRoZSBjb3VudCBvZiBvYnNlcnZlcnMgY3VycmVudGx5IHJlZ2lzdGVyZWQgd2l0aCB0aGlzIGhhbmRsZXJcbiAgICogQHJldHVybiB7bnVtYmVyfSBUaGUgbnVtYmVyIG9mIHJlZ2lzdGVyZWQgb2JzZXJ2ZXJzXG4gICAqL1xuICBjb3VudCgpIHtcbiAgICByZXR1cm4gdGhpcy5vYnNlcnZlcnMubGVuZ3RoO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZWdpc3RlcnMgYSBuZXcgb2JzZXJ2ZXJcbiAgICogQHN1bW1hcnkgQWRkcyBhbiBvYnNlcnZlciB0byB0aGUgY29sbGVjdGlvbiB3aXRoIGFuIG9wdGlvbmFsIGZpbHRlciBmdW5jdGlvblxuICAgKiBAcGFyYW0ge09ic2VydmVyfSBvYnNlcnZlciAtIFRoZSBvYnNlcnZlciB0byByZWdpc3RlclxuICAgKiBAcGFyYW0ge09ic2VydmVyRmlsdGVyfSBbZmlsdGVyXSAtIE9wdGlvbmFsIGZpbHRlciBmdW5jdGlvbiB0byBkZXRlcm1pbmUgd2hpY2ggZXZlbnRzIHRoZSBvYnNlcnZlciByZWNlaXZlc1xuICAgKiBAcmV0dXJuIHt2b2lkfVxuICAgKi9cbiAgb2JzZXJ2ZShvYnNlcnZlcjogT2JzZXJ2ZXIsIGZpbHRlcj86IE9ic2VydmVyRmlsdGVyKTogdm9pZCB7XG4gICAgY29uc3QgaW5kZXggPSB0aGlzLm9ic2VydmVycy5tYXAoKG8pID0+IG8ub2JzZXJ2ZXIpLmluZGV4T2Yob2JzZXJ2ZXIpO1xuICAgIGlmIChpbmRleCAhPT0gLTEpIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFwiT2JzZXJ2ZXIgYWxyZWFkeSByZWdpc3RlcmVkXCIpO1xuICAgIHRoaXMub2JzZXJ2ZXJzLnB1c2goeyBvYnNlcnZlcjogb2JzZXJ2ZXIsIGZpbHRlcjogZmlsdGVyIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBVbnJlZ2lzdGVycyBhbiBvYnNlcnZlclxuICAgKiBAc3VtbWFyeSBSZW1vdmVzIGFuIG9ic2VydmVyIGZyb20gdGhlIGNvbGxlY3Rpb25cbiAgICogQHBhcmFtIHtPYnNlcnZlcn0gb2JzZXJ2ZXIgLSBUaGUgb2JzZXJ2ZXIgdG8gdW5yZWdpc3RlclxuICAgKiBAcmV0dXJuIHt2b2lkfVxuICAgKi9cbiAgdW5PYnNlcnZlKG9ic2VydmVyOiBPYnNlcnZlcik6IHZvaWQge1xuICAgIGNvbnN0IGluZGV4ID0gdGhpcy5vYnNlcnZlcnMubWFwKChvKSA9PiBvLm9ic2VydmVyKS5pbmRleE9mKG9ic2VydmVyKTtcbiAgICBpZiAoaW5kZXggPT09IC0xKSB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcIkZhaWxlZCB0byBmaW5kIE9ic2VydmVyXCIpO1xuICAgIHRoaXMub2JzZXJ2ZXJzLnNwbGljZShpbmRleCwgMSk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIE5vdGlmaWVzIGFsbCByZWxldmFudCBvYnNlcnZlcnMgYWJvdXQgYSBkYXRhYmFzZSBldmVudFxuICAgKiBAc3VtbWFyeSBGaWx0ZXJzIG9ic2VydmVycyBiYXNlZCBvbiB0aGVpciBmaWx0ZXIgZnVuY3Rpb25zIGFuZCBjYWxscyByZWZyZXNoIG9uIGVhY2ggbWF0Y2hpbmcgb2JzZXJ2ZXJcbiAgICogQHBhcmFtIHtMb2dnZXJ9IGxvZyAtIExvZ2dlciBmb3IgcmVjb3JkaW5nIG5vdGlmaWNhdGlvbiBhY3Rpdml0aWVzXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0YWJsZSAtIFRoZSBuYW1lIG9mIHRoZSB0YWJsZSB3aGVyZSB0aGUgZXZlbnQgb2NjdXJyZWRcbiAgICogQHBhcmFtIHtPcGVyYXRpb25LZXlzfEJ1bGtDcnVkT3BlcmF0aW9uS2V5c3xzdHJpbmd9IGV2ZW50IC0gVGhlIHR5cGUgb2Ygb3BlcmF0aW9uIHRoYXQgb2NjdXJyZWRcbiAgICogQHBhcmFtIHtFdmVudElkc30gaWQgLSBUaGUgaWRlbnRpZmllcihzKSBvZiB0aGUgYWZmZWN0ZWQgcmVjb3JkKHMpXG4gICAqIEBwYXJhbSB7Li4uYW55W119IGFyZ3MgLSBBZGRpdGlvbmFsIGFyZ3VtZW50cyB0byBwYXNzIHRvIHRoZSBvYnNlcnZlcnNcbiAgICogQHJldHVybiB7UHJvbWlzZTx2b2lkPn0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiBhbGwgb2JzZXJ2ZXJzIGhhdmUgYmVlbiBub3RpZmllZFxuICAgKiBAbWVybWFpZFxuICAgKiBzZXF1ZW5jZURpYWdyYW1cbiAgICogICBwYXJ0aWNpcGFudCBDbGllbnRcbiAgICogICBwYXJ0aWNpcGFudCBPYnNlcnZlckhhbmRsZXJcbiAgICogICBwYXJ0aWNpcGFudCBPYnNlcnZlclxuICAgKiAgIFxuICAgKiAgIENsaWVudC0+Pk9ic2VydmVySGFuZGxlcjogdXBkYXRlT2JzZXJ2ZXJzKGxvZywgdGFibGUsIGV2ZW50LCBpZCwgLi4uYXJncylcbiAgICogICBcbiAgICogICBPYnNlcnZlckhhbmRsZXItPj5PYnNlcnZlckhhbmRsZXI6IEZpbHRlciBvYnNlcnZlcnNcbiAgICogICBcbiAgICogICBsb29wIEZvciBlYWNoIG9ic2VydmVyIHdpdGggbWF0Y2hpbmcgZmlsdGVyXG4gICAqICAgICBhbHQgT2JzZXJ2ZXIgaGFzIGZpbHRlclxuICAgKiAgICAgICBPYnNlcnZlckhhbmRsZXItPj5PYnNlcnZlcjogQXBwbHkgZmlsdGVyKHRhYmxlLCBldmVudCwgaWQpXG4gICAqICAgICAgIGFsdCBGaWx0ZXIgdGhyb3dzIGVycm9yXG4gICAqICAgICAgICAgT2JzZXJ2ZXJIYW5kbGVyLT4+TG9nZ2VyOiBMb2cgZXJyb3JcbiAgICogICAgICAgICBPYnNlcnZlckhhbmRsZXItLT4+T2JzZXJ2ZXJIYW5kbGVyOiBTa2lwIG9ic2VydmVyXG4gICAqICAgICAgIGVsc2UgRmlsdGVyIHJldHVybnMgdHJ1ZVxuICAgKiAgICAgICAgIE9ic2VydmVySGFuZGxlci0+Pk9ic2VydmVyOiByZWZyZXNoKHRhYmxlLCBldmVudCwgaWQsIC4uLmFyZ3MpXG4gICAqICAgICAgIGVsc2UgRmlsdGVyIHJldHVybnMgZmFsc2VcbiAgICogICAgICAgICBPYnNlcnZlckhhbmRsZXItLT4+T2JzZXJ2ZXJIYW5kbGVyOiBTa2lwIG9ic2VydmVyXG4gICAqICAgICAgIGVuZFxuICAgKiAgICAgZWxzZSBObyBmaWx0ZXJcbiAgICogICAgICAgT2JzZXJ2ZXJIYW5kbGVyLT4+T2JzZXJ2ZXI6IHJlZnJlc2godGFibGUsIGV2ZW50LCBpZCwgLi4uYXJncylcbiAgICogICAgIGVuZFxuICAgKiAgIGVuZFxuICAgKiAgIFxuICAgKiAgIE9ic2VydmVySGFuZGxlci0+Pk9ic2VydmVySGFuZGxlcjogUHJvY2VzcyByZXN1bHRzXG4gICAqICAgbG9vcCBGb3IgZWFjaCByZXN1bHRcbiAgICogICAgIGFsdCBSZXN1bHQgaXMgcmVqZWN0ZWRcbiAgICogICAgICAgT2JzZXJ2ZXJIYW5kbGVyLT4+TG9nZ2VyOiBMb2cgZXJyb3JcbiAgICogICAgIGVuZFxuICAgKiAgIGVuZFxuICAgKiAgIFxuICAgKiAgIE9ic2VydmVySGFuZGxlci0tPj5DbGllbnQ6IFJldHVyblxuICAgKi9cbiAgYXN5bmMgdXBkYXRlT2JzZXJ2ZXJzKFxuICAgIGxvZzogTG9nZ2VyLFxuICAgIHRhYmxlOiBzdHJpbmcsXG4gICAgZXZlbnQ6IE9wZXJhdGlvbktleXMgfCBCdWxrQ3J1ZE9wZXJhdGlvbktleXMgfCBzdHJpbmcsXG4gICAgaWQ6IEV2ZW50SWRzLFxuICAgIC4uLmFyZ3M6IGFueVtdXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBQcm9taXNlLmFsbFNldHRsZWQoXG4gICAgICB0aGlzLm9ic2VydmVyc1xuICAgICAgICAuZmlsdGVyKChvKSA9PiB7XG4gICAgICAgICAgY29uc3QgeyBmaWx0ZXIgfSA9IG87XG4gICAgICAgICAgaWYgKCFmaWx0ZXIpIHJldHVybiB0cnVlO1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXR1cm4gZmlsdGVyKHRhYmxlLCBldmVudCwgaWQpO1xuICAgICAgICAgIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICAgICAgICAgIGxvZy5lcnJvcihcbiAgICAgICAgICAgICAgYEZhaWxlZCB0byBmaWx0ZXIgb2JzZXJ2ZXIgJHtvLm9ic2VydmVyLnRvU3RyaW5nKCl9OiAke2V9YFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICAgIC5tYXAoKG8pID0+IG8ub2JzZXJ2ZXIucmVmcmVzaCh0YWJsZSwgZXZlbnQsIGlkLCAuLi5hcmdzKSlcbiAgICApO1xuICAgIHJlc3VsdHMuZm9yRWFjaCgocmVzdWx0LCBpKSA9PiB7XG4gICAgICBpZiAocmVzdWx0LnN0YXR1cyA9PT0gXCJyZWplY3RlZFwiKVxuICAgICAgICBsb2cuZXJyb3IoXG4gICAgICAgICAgYEZhaWxlZCB0byB1cGRhdGUgb2JzZXJ2YWJsZSAke3RoaXMub2JzZXJ2ZXJzW2ldLnRvU3RyaW5nKCl9OiAke3Jlc3VsdC5yZWFzb259YFxuICAgICAgICApO1xuICAgIH0pO1xuICB9XG59XG4iLCJpbXBvcnQge1xuICBCYXNlRXJyb3IsXG4gIERCS2V5cyxcbiAgSW50ZXJuYWxFcnJvcixcbiAgTm90Rm91bmRFcnJvcixcbiAgQ29udGV4dCxcbiAgT3BlcmF0aW9uS2V5cyxcbiAgUmVwb3NpdG9yeUZsYWdzLFxuICBEZWZhdWx0UmVwb3NpdG9yeUZsYWdzLFxuICBDb250ZXh0dWFsLFxuICBCdWxrQ3J1ZE9wZXJhdGlvbktleXMsXG4gIG1vZGVsVG9UcmFuc2llbnQsXG59IGZyb20gXCJAZGVjYWYtdHMvZGItZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHsgdHlwZSBPYnNlcnZlciB9IGZyb20gXCIuLi9pbnRlcmZhY2VzL09ic2VydmVyXCI7XG5pbXBvcnQge1xuICB0eXBlIENvbnN0cnVjdG9yLFxuICBEZWNvcmF0aW9uLFxuICBEZWZhdWx0Rmxhdm91cixcbiAgTW9kZWwsXG4gIE1vZGVsQ29uc3RydWN0b3IsXG4gIE1vZGVsUmVnaXN0cnksXG59IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7IFNlcXVlbmNlT3B0aW9ucyB9IGZyb20gXCIuLi9pbnRlcmZhY2VzL1NlcXVlbmNlT3B0aW9uc1wiO1xuaW1wb3J0IHsgUmF3RXhlY3V0b3IgfSBmcm9tIFwiLi4vaW50ZXJmYWNlcy9SYXdFeGVjdXRvclwiO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZSB9IGZyb20gXCIuLi9pbnRlcmZhY2VzL09ic2VydmFibGVcIjtcbmltcG9ydCB7IFBlcnNpc3RlbmNlS2V5cyB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgUmVwb3NpdG9yeSB9IGZyb20gXCIuLi9yZXBvc2l0b3J5L1JlcG9zaXRvcnlcIjtcbmltcG9ydCB7IFNlcXVlbmNlIH0gZnJvbSBcIi4vU2VxdWVuY2VcIjtcbmltcG9ydCB7IEVycm9yUGFyc2VyIH0gZnJvbSBcIi4uL2ludGVyZmFjZXNcIjtcbmltcG9ydCB7IFN0YXRlbWVudCB9IGZyb20gXCIuLi9xdWVyeS9TdGF0ZW1lbnRcIjtcbmltcG9ydCB7IExvZ2dlciwgTG9nZ2luZyB9IGZyb20gXCJAZGVjYWYtdHMvbG9nZ2luZ1wiO1xuaW1wb3J0IHsgZmluYWwgfSBmcm9tIFwiLi4vdXRpbHNcIjtcbmltcG9ydCB7IERpc3BhdGNoIH0gZnJvbSBcIi4vRGlzcGF0Y2hcIjtcbmltcG9ydCB7IHR5cGUgRXZlbnRJZHMsIHR5cGUgT2JzZXJ2ZXJGaWx0ZXIgfSBmcm9tIFwiLi90eXBlc1wiO1xuaW1wb3J0IHsgT2JzZXJ2ZXJIYW5kbGVyIH0gZnJvbSBcIi4vT2JzZXJ2ZXJIYW5kbGVyXCI7XG5cbkRlY29yYXRpb24uc2V0Rmxhdm91clJlc29sdmVyKChvYmo6IG9iamVjdCkgPT4ge1xuICB0cnkge1xuICAgIHJldHVybiAoXG4gICAgICBBZGFwdGVyLmZsYXZvdXJPZihNb2RlbC5pc01vZGVsKG9iaikgPyBvYmouY29uc3RydWN0b3IgOiAob2JqIGFzIGFueSkpIHx8XG4gICAgICBEZWZhdWx0Rmxhdm91clxuICAgICk7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICB9IGNhdGNoIChlOiB1bmtub3duKSB7XG4gICAgcmV0dXJuIERlZmF1bHRGbGF2b3VyO1xuICB9XG59KTtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gQWJzdHJhY3QgYmFzZSBjbGFzcyBmb3IgZGF0YWJhc2UgYWRhcHRlcnNcbiAqIEBzdW1tYXJ5IFByb3ZpZGVzIHRoZSBmb3VuZGF0aW9uIGZvciBhbGwgZGF0YWJhc2UgYWRhcHRlcnMgaW4gdGhlIHBlcnNpc3RlbmNlIGxheWVyLiBUaGlzIGNsYXNzXG4gKiBpbXBsZW1lbnRzIHNldmVyYWwgaW50ZXJmYWNlcyB0byBwcm92aWRlIGEgY29uc2lzdGVudCBBUEkgZm9yIGRhdGFiYXNlIG9wZXJhdGlvbnMsIG9ic2VydmVyXG4gKiBwYXR0ZXJuIHN1cHBvcnQsIGFuZCBlcnJvciBoYW5kbGluZy4gSXQgbWFuYWdlcyBhZGFwdGVyIHJlZ2lzdHJhdGlvbiwgQ1JVRCBvcGVyYXRpb25zLCBhbmRcbiAqIG9ic2VydmVyIG5vdGlmaWNhdGlvbnMuXG4gKiBAdGVtcGxhdGUgWSAtIFRoZSB1bmRlcmx5aW5nIGRhdGFiYXNlIGRyaXZlciB0eXBlXG4gKiBAdGVtcGxhdGUgUSAtIFRoZSBxdWVyeSBvYmplY3QgdHlwZSB1c2VkIGJ5IHRoZSBhZGFwdGVyXG4gKiBAdGVtcGxhdGUgRiAtIFRoZSByZXBvc2l0b3J5IGZsYWdzIHR5cGVcbiAqIEB0ZW1wbGF0ZSBDIC0gVGhlIGNvbnRleHQgdHlwZVxuICogQHBhcmFtIHtZfSBfbmF0aXZlIC0gVGhlIHVuZGVybHlpbmcgZGF0YWJhc2UgZHJpdmVyIGluc3RhbmNlXG4gKiBAcGFyYW0ge3N0cmluZ30gZmxhdm91ciAtIFRoZSBpZGVudGlmaWVyIGZvciB0aGlzIGFkYXB0ZXIgdHlwZVxuICogQHBhcmFtIHtzdHJpbmd9IFtfYWxpYXNdIC0gT3B0aW9uYWwgYWx0ZXJuYXRpdmUgbmFtZSBmb3IgdGhpcyBhZGFwdGVyXG4gKiBAY2xhc3MgQWRhcHRlclxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIC8vIEltcGxlbWVudGluZyBhIGNvbmNyZXRlIGFkYXB0ZXJcbiAqIGNsYXNzIFBvc3RncmVzQWRhcHRlciBleHRlbmRzIEFkYXB0ZXI8cGcuQ2xpZW50LCBwZy5RdWVyeSwgUG9zdGdyZXNGbGFncywgUG9zdGdyZXNDb250ZXh0PiB7XG4gKiAgIGNvbnN0cnVjdG9yKGNsaWVudDogcGcuQ2xpZW50KSB7XG4gKiAgICAgc3VwZXIoY2xpZW50LCAncG9zdGdyZXMnKTtcbiAqICAgfVxuICpcbiAqICAgYXN5bmMgaW5pdGlhbGl6ZSgpIHtcbiAqICAgICAvLyBTZXQgdXAgdGhlIGFkYXB0ZXJcbiAqICAgICBhd2FpdCB0aGlzLm5hdGl2ZS5jb25uZWN0KCk7XG4gKiAgIH1cbiAqXG4gKiAgIGFzeW5jIGNyZWF0ZSh0YWJsZU5hbWUsIGlkLCBtb2RlbCkge1xuICogICAgIC8vIEltcGxlbWVudGF0aW9uIGZvciBjcmVhdGluZyByZWNvcmRzXG4gKiAgICAgY29uc3QgY29sdW1ucyA9IE9iamVjdC5rZXlzKG1vZGVsKS5qb2luKCcsICcpO1xuICogICAgIGNvbnN0IHZhbHVlcyA9IE9iamVjdC52YWx1ZXMobW9kZWwpO1xuICogICAgIGNvbnN0IHBsYWNlaG9sZGVycyA9IHZhbHVlcy5tYXAoKF8sIGkpID0+IGAkJHtpKzF9YCkuam9pbignLCAnKTtcbiAqXG4gKiAgICAgY29uc3QgcXVlcnkgPSBgSU5TRVJUIElOVE8gJHt0YWJsZU5hbWV9ICgke2NvbHVtbnN9KSBWQUxVRVMgKCR7cGxhY2Vob2xkZXJzfSkgUkVUVVJOSU5HICpgO1xuICogICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMubmF0aXZlLnF1ZXJ5KHF1ZXJ5LCB2YWx1ZXMpO1xuICogICAgIHJldHVybiByZXN1bHQucm93c1swXTtcbiAqICAgfVxuICpcbiAqICAgLy8gT3RoZXIgcmVxdWlyZWQgbWV0aG9kIGltcGxlbWVudGF0aW9ucy4uLlxuICogfVxuICpcbiAqIC8vIFVzaW5nIHRoZSBhZGFwdGVyXG4gKiBjb25zdCBwZ0NsaWVudCA9IG5ldyBwZy5DbGllbnQoY29ubmVjdGlvblN0cmluZyk7XG4gKiBjb25zdCBhZGFwdGVyID0gbmV3IFBvc3RncmVzQWRhcHRlcihwZ0NsaWVudCk7XG4gKiBhd2FpdCBhZGFwdGVyLmluaXRpYWxpemUoKTtcbiAqXG4gKiAvLyBTZXQgYXMgdGhlIGRlZmF1bHQgYWRhcHRlclxuICogQWRhcHRlci5zZXRDdXJyZW50KCdwb3N0Z3JlcycpO1xuICpcbiAqIC8vIFBlcmZvcm0gb3BlcmF0aW9uc1xuICogY29uc3QgdXNlciA9IGF3YWl0IGFkYXB0ZXIuY3JlYXRlKCd1c2VycycsIDEsIHsgbmFtZTogJ0pvaG4nLCBlbWFpbDogJ2pvaG5AZXhhbXBsZS5jb20nIH0pO1xuICogYGBgXG4gKiBAbWVybWFpZFxuICogY2xhc3NEaWFncmFtXG4gKiAgIGNsYXNzIEFkYXB0ZXIge1xuICogICAgICtZIG5hdGl2ZVxuICogICAgICtzdHJpbmcgZmxhdm91clxuICogICAgICtzdHJpbmcgYWxpYXNcbiAqICAgICArY3JlYXRlKHRhYmxlTmFtZSwgaWQsIG1vZGVsKVxuICogICAgICtyZWFkKHRhYmxlTmFtZSwgaWQpXG4gKiAgICAgK3VwZGF0ZSh0YWJsZU5hbWUsIGlkLCBtb2RlbClcbiAqICAgICArZGVsZXRlKHRhYmxlTmFtZSwgaWQpXG4gKiAgICAgK29ic2VydmUob2JzZXJ2ZXIsIGZpbHRlcilcbiAqICAgICArdW5PYnNlcnZlKG9ic2VydmVyKVxuICogICAgICtzdGF0aWMgY3VycmVudFxuICogICAgICtzdGF0aWMgZ2V0KGZsYXZvdXIpXG4gKiAgICAgK3N0YXRpYyBzZXRDdXJyZW50KGZsYXZvdXIpXG4gKiAgIH1cbiAqXG4gKiAgIGNsYXNzIFJhd0V4ZWN1dG9yIHtcbiAqICAgICArcmF3KHF1ZXJ5KVxuICogICB9XG4gKlxuICogICBjbGFzcyBPYnNlcnZhYmxlIHtcbiAqICAgICArb2JzZXJ2ZShvYnNlcnZlciwgZmlsdGVyKVxuICogICAgICt1bk9ic2VydmUob2JzZXJ2ZXIpXG4gKiAgICAgK3VwZGF0ZU9ic2VydmVycyh0YWJsZSwgZXZlbnQsIGlkKVxuICogICB9XG4gKlxuICogICBjbGFzcyBPYnNlcnZlciB7XG4gKiAgICAgK3JlZnJlc2godGFibGUsIGV2ZW50LCBpZClcbiAqICAgfVxuICpcbiAqICAgY2xhc3MgRXJyb3JQYXJzZXIge1xuICogICAgICtwYXJzZUVycm9yKGVycilcbiAqICAgfVxuICpcbiAqICAgQWRhcHRlciAtLXw+IFJhd0V4ZWN1dG9yXG4gKiAgIEFkYXB0ZXIgLS18PiBPYnNlcnZhYmxlXG4gKiAgIEFkYXB0ZXIgLS18PiBPYnNlcnZlclxuICogICBBZGFwdGVyIC0tfD4gRXJyb3JQYXJzZXJcbiAqL1xuZXhwb3J0IGFic3RyYWN0IGNsYXNzIEFkYXB0ZXI8XG4gICAgWSxcbiAgICBRLFxuICAgIEYgZXh0ZW5kcyBSZXBvc2l0b3J5RmxhZ3MsXG4gICAgQyBleHRlbmRzIENvbnRleHQ8Rj4sXG4gID5cbiAgaW1wbGVtZW50cyBSYXdFeGVjdXRvcjxRPiwgQ29udGV4dHVhbDxGLCBDPiwgT2JzZXJ2YWJsZSwgT2JzZXJ2ZXIsIEVycm9yUGFyc2VyXG57XG4gIHByaXZhdGUgc3RhdGljIF9jdXJyZW50OiBBZGFwdGVyPGFueSwgYW55LCBhbnksIGFueT47XG4gIHByaXZhdGUgc3RhdGljIF9jYWNoZTogUmVjb3JkPHN0cmluZywgQWRhcHRlcjxhbnksIGFueSwgYW55LCBhbnk+PiA9IHt9O1xuXG4gIHByaXZhdGUgbG9nZ2VyITogTG9nZ2VyO1xuXG4gIHByb3RlY3RlZCBkaXNwYXRjaD86IERpc3BhdGNoPFk+O1xuXG4gIHByb3RlY3RlZCByZWFkb25seSBvYnNlcnZlckhhbmRsZXI/OiBPYnNlcnZlckhhbmRsZXI7XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBMb2dnZXIgYWNjZXNzb3JcbiAgICogQHN1bW1hcnkgR2V0cyBvciBpbml0aWFsaXplcyB0aGUgbG9nZ2VyIGZvciB0aGlzIGFkYXB0ZXIgaW5zdGFuY2VcbiAgICogQHJldHVybiB7TG9nZ2VyfSBUaGUgbG9nZ2VyIGluc3RhbmNlXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0IGxvZygpIHtcbiAgICBpZiAoIXRoaXMubG9nZ2VyKSB0aGlzLmxvZ2dlciA9IExvZ2dpbmcuZm9yKHRoaXMgYXMgYW55KTtcbiAgICByZXR1cm4gdGhpcy5sb2dnZXI7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEdldHMgdGhlIG5hdGl2ZSBkYXRhYmFzZSBkcml2ZXJcbiAgICogQHN1bW1hcnkgUHJvdmlkZXMgYWNjZXNzIHRvIHRoZSB1bmRlcmx5aW5nIGRhdGFiYXNlIGRyaXZlciBpbnN0YW5jZVxuICAgKiBAcmV0dXJuIHtZfSBUaGUgbmF0aXZlIGRhdGFiYXNlIGRyaXZlclxuICAgKi9cbiAgZ2V0IG5hdGl2ZSgpIHtcbiAgICByZXR1cm4gdGhpcy5fbmF0aXZlO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBHZXRzIHRoZSBhZGFwdGVyJ3MgYWxpYXMgb3IgZmxhdm9yIG5hbWVcbiAgICogQHN1bW1hcnkgUmV0dXJucyB0aGUgYWxpYXMgaWYgc2V0LCBvdGhlcndpc2UgcmV0dXJucyB0aGUgZmxhdm9yIG5hbWVcbiAgICogQHJldHVybiB7c3RyaW5nfSBUaGUgYWRhcHRlcidzIGlkZW50aWZpZXJcbiAgICovXG4gIGdldCBhbGlhcygpIHtcbiAgICByZXR1cm4gdGhpcy5fYWxpYXMgfHwgdGhpcy5mbGF2b3VyO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBHZXRzIHRoZSByZXBvc2l0b3J5IGNvbnN0cnVjdG9yIGZvciB0aGlzIGFkYXB0ZXJcbiAgICogQHN1bW1hcnkgUmV0dXJucyB0aGUgY29uc3RydWN0b3IgZm9yIGNyZWF0aW5nIHJlcG9zaXRvcmllcyB0aGF0IHdvcmsgd2l0aCB0aGlzIGFkYXB0ZXJcbiAgICogQHRlbXBsYXRlIE0gLSBUaGUgbW9kZWwgdHlwZVxuICAgKiBAcmV0dXJuIHtDb25zdHJ1Y3RvcjxSZXBvc2l0b3J5PE0sIFEsIEFkYXB0ZXI8WSwgUSwgRiwgQz4sIEYsIEM+Pn0gVGhlIHJlcG9zaXRvcnkgY29uc3RydWN0b3JcbiAgICovXG4gIHJlcG9zaXRvcnk8TSBleHRlbmRzIE1vZGVsPigpOiBDb25zdHJ1Y3RvcjxcbiAgICBSZXBvc2l0b3J5PE0sIFEsIEFkYXB0ZXI8WSwgUSwgRiwgQz4sIEYsIEM+XG4gID4ge1xuICAgIHJldHVybiBSZXBvc2l0b3J5O1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDcmVhdGVzIGEgbmV3IGFkYXB0ZXIgaW5zdGFuY2VcbiAgICogQHN1bW1hcnkgSW5pdGlhbGl6ZXMgdGhlIGFkYXB0ZXIgd2l0aCB0aGUgbmF0aXZlIGRyaXZlciBhbmQgcmVnaXN0ZXJzIGl0IGluIHRoZSBhZGFwdGVyIGNhY2hlXG4gICAqL1xuICBwcm90ZWN0ZWQgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSBfbmF0aXZlOiBZLFxuICAgIHJlYWRvbmx5IGZsYXZvdXI6IHN0cmluZyxcbiAgICBwcml2YXRlIHJlYWRvbmx5IF9hbGlhcz86IHN0cmluZ1xuICApIHtcbiAgICBpZiAodGhpcy5mbGF2b3VyIGluIEFkYXB0ZXIuX2NhY2hlKVxuICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXG4gICAgICAgIGAke3RoaXMuYWxpYXN9IHBlcnNpc3RlbmNlIGFkYXB0ZXIgJHt0aGlzLl9hbGlhcyA/IGAoJHt0aGlzLmZsYXZvdXJ9KSBgIDogXCJcIn0gYWxyZWFkeSByZWdpc3RlcmVkYFxuICAgICAgKTtcbiAgICBBZGFwdGVyLl9jYWNoZVt0aGlzLmFsaWFzXSA9IHRoaXM7XG4gICAgdGhpcy5sb2cuaW5mbyhcbiAgICAgIGBDcmVhdGVkICR7dGhpcy5hbGlhc30gcGVyc2lzdGVuY2UgYWRhcHRlciAke3RoaXMuX2FsaWFzID8gYCgke3RoaXMuZmxhdm91cn0pIGAgOiBcIlwifSBwZXJzaXN0ZW5jZSBhZGFwdGVyYFxuICAgICk7XG4gICAgaWYgKCFBZGFwdGVyLl9jdXJyZW50KSB7XG4gICAgICB0aGlzLmxvZy52ZXJib3NlKGBEZWZpbmVkICR7dGhpcy5hbGlhc30gcGVyc2lzdGVuY2UgYWRhcHRlciBhcyBjdXJyZW50YCk7XG4gICAgICBBZGFwdGVyLl9jdXJyZW50ID0gdGhpcztcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENyZWF0ZXMgYSBuZXcgc3RhdGVtZW50IGJ1aWxkZXIgZm9yIGEgbW9kZWxcbiAgICogQHN1bW1hcnkgUmV0dXJucyBhIHN0YXRlbWVudCBidWlsZGVyIHRoYXQgY2FuIGJlIHVzZWQgdG8gY29uc3RydWN0IHF1ZXJpZXMgZm9yIGEgc3BlY2lmaWMgbW9kZWxcbiAgICogQHRlbXBsYXRlIE0gLSBUaGUgbW9kZWwgdHlwZVxuICAgKiBAcmV0dXJuIHtTdGF0ZW1lbnR9IEEgc3RhdGVtZW50IGJ1aWxkZXIgZm9yIHRoZSBtb2RlbFxuICAgKi9cbiAgYWJzdHJhY3QgU3RhdGVtZW50PE0gZXh0ZW5kcyBNb2RlbD4oKTogU3RhdGVtZW50PFEsIE0sIGFueT47XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDcmVhdGVzIGEgbmV3IGRpc3BhdGNoIGluc3RhbmNlXG4gICAqIEBzdW1tYXJ5IEZhY3RvcnkgbWV0aG9kIHRoYXQgY3JlYXRlcyBhIGRpc3BhdGNoIGluc3RhbmNlIGZvciB0aGlzIGFkYXB0ZXJcbiAgICogQHJldHVybiB7RGlzcGF0Y2g8WT59IEEgbmV3IGRpc3BhdGNoIGluc3RhbmNlXG4gICAqL1xuICBwcm90ZWN0ZWQgRGlzcGF0Y2goKTogRGlzcGF0Y2g8WT4ge1xuICAgIHJldHVybiBuZXcgRGlzcGF0Y2goKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ3JlYXRlcyBhIG5ldyBvYnNlcnZlciBoYW5kbGVyXG4gICAqIEBzdW1tYXJ5IEZhY3RvcnkgbWV0aG9kIHRoYXQgY3JlYXRlcyBhbiBvYnNlcnZlciBoYW5kbGVyIGZvciB0aGlzIGFkYXB0ZXJcbiAgICogQHJldHVybiB7T2JzZXJ2ZXJIYW5kbGVyfSBBIG5ldyBvYnNlcnZlciBoYW5kbGVyIGluc3RhbmNlXG4gICAqL1xuICBwcm90ZWN0ZWQgT2JzZXJ2ZXJIYW5kbGVyKCkge1xuICAgIHJldHVybiBuZXcgT2JzZXJ2ZXJIYW5kbGVyKCk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENoZWNrcyBpZiBhbiBhdHRyaWJ1dGUgbmFtZSBpcyByZXNlcnZlZFxuICAgKiBAc3VtbWFyeSBEZXRlcm1pbmVzIGlmIGEgZ2l2ZW4gYXR0cmlidXRlIG5hbWUgaXMgcmVzZXJ2ZWQgYW5kIGNhbm5vdCBiZSB1c2VkIGFzIGEgY29sdW1uIG5hbWVcbiAgICogQHBhcmFtIHtzdHJpbmd9IGF0dHIgLSBUaGUgYXR0cmlidXRlIG5hbWUgdG8gY2hlY2tcbiAgICogQHJldHVybiB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGUgYXR0cmlidXRlIGlzIHJlc2VydmVkLCBmYWxzZSBvdGhlcndpc2VcbiAgICovXG4gIHByb3RlY3RlZCBpc1Jlc2VydmVkKGF0dHI6IHN0cmluZykge1xuICAgIHJldHVybiAhYXR0cjtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUGFyc2VzIGEgZGF0YWJhc2UgZXJyb3IgaW50byBhIHN0YW5kYXJkaXplZCBlcnJvclxuICAgKiBAc3VtbWFyeSBDb252ZXJ0cyBkYXRhYmFzZS1zcGVjaWZpYyBlcnJvcnMgaW50byBzdGFuZGFyZGl6ZWQgYXBwbGljYXRpb24gZXJyb3JzXG4gICAqIEBwYXJhbSB7RXJyb3J9IGVyciAtIFRoZSBvcmlnaW5hbCBkYXRhYmFzZSBlcnJvclxuICAgKiBAcmV0dXJuIHtCYXNlRXJyb3J9IEEgc3RhbmRhcmRpemVkIGVycm9yXG4gICAqL1xuICBhYnN0cmFjdCBwYXJzZUVycm9yKGVycjogRXJyb3IpOiBCYXNlRXJyb3I7XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBJbml0aWFsaXplcyB0aGUgYWRhcHRlclxuICAgKiBAc3VtbWFyeSBQZXJmb3JtcyBhbnkgbmVjZXNzYXJ5IHNldHVwIGZvciB0aGUgYWRhcHRlciwgc3VjaCBhcyBlc3RhYmxpc2hpbmcgY29ubmVjdGlvbnNcbiAgICogQHBhcmFtIHsuLi5hbnlbXX0gYXJncyAtIEluaXRpYWxpemF0aW9uIGFyZ3VtZW50c1xuICAgKiBAcmV0dXJuIHtQcm9taXNlPHZvaWQ+fSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIGluaXRpYWxpemF0aW9uIGlzIGNvbXBsZXRlXG4gICAqL1xuICBhYnN0cmFjdCBpbml0aWFsaXplKC4uLmFyZ3M6IGFueVtdKTogUHJvbWlzZTx2b2lkPjtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENyZWF0ZXMgYSBzZXF1ZW5jZSBnZW5lcmF0b3JcbiAgICogQHN1bW1hcnkgRmFjdG9yeSBtZXRob2QgdGhhdCBjcmVhdGVzIGEgc2VxdWVuY2UgZ2VuZXJhdG9yIGZvciBnZW5lcmF0aW5nIHNlcXVlbnRpYWwgdmFsdWVzXG4gICAqIEBwYXJhbSB7U2VxdWVuY2VPcHRpb25zfSBvcHRpb25zIC0gQ29uZmlndXJhdGlvbiBvcHRpb25zIGZvciB0aGUgc2VxdWVuY2VcbiAgICogQHJldHVybiB7UHJvbWlzZTxTZXF1ZW5jZT59IEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIGEgbmV3IHNlcXVlbmNlIGluc3RhbmNlXG4gICAqL1xuICBhYnN0cmFjdCBTZXF1ZW5jZShvcHRpb25zOiBTZXF1ZW5jZU9wdGlvbnMpOiBQcm9taXNlPFNlcXVlbmNlPjtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENyZWF0ZXMgcmVwb3NpdG9yeSBmbGFncyBmb3IgYW4gb3BlcmF0aW9uXG4gICAqIEBzdW1tYXJ5IEdlbmVyYXRlcyBhIHNldCBvZiBmbGFncyB0aGF0IGRlc2NyaWJlIGEgZGF0YWJhc2Ugb3BlcmF0aW9uLCBjb21iaW5pbmcgZGVmYXVsdCBmbGFncyB3aXRoIG92ZXJyaWRlc1xuICAgKiBAdGVtcGxhdGUgRiAtIFRoZSBSZXBvc2l0b3J5IEZsYWdzIHR5cGVcbiAgICogQHRlbXBsYXRlIE0gLSBUaGUgbW9kZWwgdHlwZVxuICAgKiBAcGFyYW0ge09wZXJhdGlvbktleXN9IG9wZXJhdGlvbiAtIFRoZSB0eXBlIG9mIG9wZXJhdGlvbiBiZWluZyBwZXJmb3JtZWRcbiAgICogQHBhcmFtIHtDb25zdHJ1Y3RvcjxNPn0gbW9kZWwgLSBUaGUgbW9kZWwgY29uc3RydWN0b3JcbiAgICogQHBhcmFtIHtQYXJ0aWFsPEY+fSBmbGFncyAtIEN1c3RvbSBmbGFnIG92ZXJyaWRlc1xuICAgKiBAcGFyYW0gey4uLmFueVtdfSBhcmdzIC0gQWRkaXRpb25hbCBhcmd1bWVudHNcbiAgICogQHJldHVybiB7Rn0gVGhlIGNvbXBsZXRlIHNldCBvZiBmbGFnc1xuICAgKi9cbiAgcHJvdGVjdGVkIGZsYWdzPE0gZXh0ZW5kcyBNb2RlbD4oXG4gICAgb3BlcmF0aW9uOiBPcGVyYXRpb25LZXlzLFxuICAgIG1vZGVsOiBDb25zdHJ1Y3RvcjxNPixcbiAgICBmbGFnczogUGFydGlhbDxGPixcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gICAgLi4uYXJnczogYW55W11cbiAgKTogRiB7XG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIERlZmF1bHRSZXBvc2l0b3J5RmxhZ3MsIGZsYWdzLCB7XG4gICAgICBhZmZlY3RlZFRhYmxlczogUmVwb3NpdG9yeS50YWJsZShtb2RlbCksXG4gICAgICB3cml0ZU9wZXJhdGlvbjogb3BlcmF0aW9uICE9PSBPcGVyYXRpb25LZXlzLlJFQUQsXG4gICAgICB0aW1lc3RhbXA6IG5ldyBEYXRlKCksXG4gICAgICBvcGVyYXRpb246IG9wZXJhdGlvbixcbiAgICB9KSBhcyBGO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBUaGUgY29udGV4dCBjb25zdHJ1Y3RvciBmb3IgdGhpcyBhZGFwdGVyXG4gICAqIEBzdW1tYXJ5IFJlZmVyZW5jZSB0byB0aGUgY29udGV4dCBjbGFzcyBjb25zdHJ1Y3RvciB1c2VkIGJ5IHRoaXMgYWRhcHRlclxuICAgKi9cbiAgcHJvdGVjdGVkIENvbnRleHQgPSBDb250ZXh0PEY+O1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ3JlYXRlcyBhIGNvbnRleHQgZm9yIGEgZGF0YWJhc2Ugb3BlcmF0aW9uXG4gICAqIEBzdW1tYXJ5IEdlbmVyYXRlcyBhIGNvbnRleHQgb2JqZWN0IHRoYXQgZGVzY3JpYmVzIGEgZGF0YWJhc2Ugb3BlcmF0aW9uLCB1c2VkIGZvciB0cmFja2luZyBhbmQgYXVkaXRpbmdcbiAgICogQHRlbXBsYXRlIEYgLSBUaGUgUmVwb3NpdG9yeSBmbGFncyB0eXBlXG4gICAqIEB0ZW1wbGF0ZSBNIC0gVGhlIG1vZGVsIHR5cGVcbiAgICogQHBhcmFtIHtPcGVyYXRpb25LZXlzLkNSRUFURXxPcGVyYXRpb25LZXlzLlJFQUR8T3BlcmF0aW9uS2V5cy5VUERBVEV8T3BlcmF0aW9uS2V5cy5ERUxFVEV9IG9wZXJhdGlvbiAtIFRoZSB0eXBlIG9mIG9wZXJhdGlvblxuICAgKiBAcGFyYW0ge1BhcnRpYWw8Rj59IG92ZXJyaWRlcyAtIEN1c3RvbSBmbGFnIG92ZXJyaWRlc1xuICAgKiBAcGFyYW0ge0NvbnN0cnVjdG9yPE0+fSBtb2RlbCAtIFRoZSBtb2RlbCBjb25zdHJ1Y3RvclxuICAgKiBAcGFyYW0gey4uLmFueVtdfSBhcmdzIC0gQWRkaXRpb25hbCBhcmd1bWVudHNcbiAgICogQHJldHVybiB7UHJvbWlzZTxDPn0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gdGhlIGNvbnRleHQgb2JqZWN0XG4gICAqL1xuICBAZmluYWwoKVxuICBhc3luYyBjb250ZXh0PE0gZXh0ZW5kcyBNb2RlbD4oXG4gICAgb3BlcmF0aW9uOlxuICAgICAgfCBPcGVyYXRpb25LZXlzLkNSRUFURVxuICAgICAgfCBPcGVyYXRpb25LZXlzLlJFQURcbiAgICAgIHwgT3BlcmF0aW9uS2V5cy5VUERBVEVcbiAgICAgIHwgT3BlcmF0aW9uS2V5cy5ERUxFVEUsXG4gICAgb3ZlcnJpZGVzOiBQYXJ0aWFsPEY+LFxuICAgIG1vZGVsOiBDb25zdHJ1Y3RvcjxNPixcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApOiBQcm9taXNlPEM+IHtcbiAgICB0aGlzLmxvZ1xuICAgICAgLmZvcih0aGlzLmNvbnRleHQpXG4gICAgICAuZGVidWcoXG4gICAgICAgIGBDcmVhdGluZyBuZXcgY29udGV4dCBmb3IgJHtvcGVyYXRpb259IG9wZXJhdGlvbiBvbiAke21vZGVsLm5hbWV9IG1vZGVsIHdpdGggZmxhZyBvdmVycmlkZXM6ICR7SlNPTi5zdHJpbmdpZnkob3ZlcnJpZGVzKX1gXG4gICAgICApO1xuICAgIHJldHVybiBuZXcgdGhpcy5Db250ZXh0KCkuYWNjdW11bGF0ZShcbiAgICAgIHRoaXMuZmxhZ3Mob3BlcmF0aW9uLCBtb2RlbCwgb3ZlcnJpZGVzLCAuLi5hcmdzKVxuICAgICkgYXMgdW5rbm93biBhcyBDO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBQcmVwYXJlcyBhIG1vZGVsIGZvciBwZXJzaXN0ZW5jZVxuICAgKiBAc3VtbWFyeSBDb252ZXJ0cyBhIG1vZGVsIGluc3RhbmNlIGludG8gYSBmb3JtYXQgc3VpdGFibGUgZm9yIGRhdGFiYXNlIHN0b3JhZ2UsXG4gICAqIGhhbmRsaW5nIGNvbHVtbiBtYXBwaW5nIGFuZCBzZXBhcmF0aW5nIHRyYW5zaWVudCBwcm9wZXJ0aWVzXG4gICAqIEB0ZW1wbGF0ZSBNIC0gVGhlIG1vZGVsIHR5cGVcbiAgICogQHBhcmFtIHtNfSBtb2RlbCAtIFRoZSBtb2RlbCBpbnN0YW5jZSB0byBwcmVwYXJlXG4gICAqIEBwYXJhbSBwayAtIFRoZSBwcmltYXJ5IGtleSBwcm9wZXJ0eSBuYW1lXG4gICAqIEByZXR1cm4gVGhlIHByZXBhcmVkIGRhdGFcbiAgICovXG4gIHByZXBhcmU8TSBleHRlbmRzIE1vZGVsPihcbiAgICBtb2RlbDogTSxcbiAgICBwazoga2V5b2YgTVxuICApOiB7XG4gICAgcmVjb3JkOiBSZWNvcmQ8c3RyaW5nLCBhbnk+O1xuICAgIGlkOiBzdHJpbmc7XG4gICAgdHJhbnNpZW50PzogUmVjb3JkPHN0cmluZywgYW55PjtcbiAgfSB7XG4gICAgY29uc3QgbG9nID0gdGhpcy5sb2cuZm9yKHRoaXMucHJlcGFyZSk7XG4gICAgbG9nLnNpbGx5KGBQcmVwYXJpbmcgbW9kZWwgJHttb2RlbC5jb25zdHJ1Y3Rvci5uYW1lfSBiZWZvcmUgcGVyc2lzdGluZ2ApO1xuICAgIGNvbnN0IHNwbGl0ID0gbW9kZWxUb1RyYW5zaWVudChtb2RlbCk7XG4gICAgY29uc3QgcmVzdWx0ID0gT2JqZWN0LmVudHJpZXMoc3BsaXQubW9kZWwpLnJlZHVjZShcbiAgICAgIChhY2N1bTogUmVjb3JkPHN0cmluZywgYW55PiwgW2tleSwgdmFsXSkgPT4ge1xuICAgICAgICBpZiAodHlwZW9mIHZhbCA9PT0gXCJ1bmRlZmluZWRcIikgcmV0dXJuIGFjY3VtO1xuICAgICAgICBjb25zdCBtYXBwZWRQcm9wID0gUmVwb3NpdG9yeS5jb2x1bW4obW9kZWwsIGtleSk7XG4gICAgICAgIGlmICh0aGlzLmlzUmVzZXJ2ZWQobWFwcGVkUHJvcCkpXG4gICAgICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoYFByb3BlcnR5IG5hbWUgJHttYXBwZWRQcm9wfSBpcyByZXNlcnZlZGApO1xuICAgICAgICBhY2N1bVttYXBwZWRQcm9wXSA9IHZhbDtcbiAgICAgICAgcmV0dXJuIGFjY3VtO1xuICAgICAgfSxcbiAgICAgIHt9XG4gICAgKTtcbiAgICBpZiAoKG1vZGVsIGFzIGFueSlbUGVyc2lzdGVuY2VLZXlzLk1FVEFEQVRBXSkge1xuICAgICAgbG9nLnNpbGx5KFxuICAgICAgICBgUGFzc2luZyBhbG9uZyBwZXJzaXN0ZW5jZSBtZXRhZGF0YSBmb3IgJHsobW9kZWwgYXMgYW55KVtQZXJzaXN0ZW5jZUtleXMuTUVUQURBVEFdfWBcbiAgICAgICk7XG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkocmVzdWx0LCBQZXJzaXN0ZW5jZUtleXMuTUVUQURBVEEsIHtcbiAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICB2YWx1ZTogKG1vZGVsIGFzIGFueSlbUGVyc2lzdGVuY2VLZXlzLk1FVEFEQVRBXSxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICByZWNvcmQ6IHJlc3VsdCxcbiAgICAgIGlkOiBtb2RlbFtwa10gYXMgc3RyaW5nLFxuICAgICAgdHJhbnNpZW50OiBzcGxpdC50cmFuc2llbnQsXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ29udmVydHMgZGF0YWJhc2UgZGF0YSBiYWNrIGludG8gYSBtb2RlbCBpbnN0YW5jZVxuICAgKiBAc3VtbWFyeSBSZWNvbnN0cnVjdHMgYSBtb2RlbCBpbnN0YW5jZSBmcm9tIGRhdGFiYXNlIGRhdGEsIGhhbmRsaW5nIGNvbHVtbiBtYXBwaW5nXG4gICAqIGFuZCByZWF0dGFjaGluZyB0cmFuc2llbnQgcHJvcGVydGllc1xuICAgKiBAdGVtcGxhdGUgTSAtIFRoZSBtb2RlbCB0eXBlXG4gICAqIEBwYXJhbSBvYmogLSBUaGUgZGF0YWJhc2UgcmVjb3JkXG4gICAqIEBwYXJhbSB7c3RyaW5nfENvbnN0cnVjdG9yPE0+fSBjbGF6eiAtIFRoZSBtb2RlbCBjbGFzcyBvciBuYW1lXG4gICAqIEBwYXJhbSBwayAtIFRoZSBwcmltYXJ5IGtleSBwcm9wZXJ0eSBuYW1lXG4gICAqIEBwYXJhbSB7c3RyaW5nfG51bWJlcnxiaWdpbnR9IGlkIC0gVGhlIHByaW1hcnkga2V5IHZhbHVlXG4gICAqIEBwYXJhbSBbdHJhbnNpZW50XSAtIFRyYW5zaWVudCBwcm9wZXJ0aWVzIHRvIHJlYXR0YWNoXG4gICAqIEByZXR1cm4ge019IFRoZSByZWNvbnN0cnVjdGVkIG1vZGVsIGluc3RhbmNlXG4gICAqL1xuICByZXZlcnQ8TSBleHRlbmRzIE1vZGVsPihcbiAgICBvYmo6IFJlY29yZDxzdHJpbmcsIGFueT4sXG4gICAgY2xheno6IHN0cmluZyB8IENvbnN0cnVjdG9yPE0+LFxuICAgIHBrOiBrZXlvZiBNLFxuICAgIGlkOiBzdHJpbmcgfCBudW1iZXIgfCBiaWdpbnQsXG4gICAgdHJhbnNpZW50PzogUmVjb3JkPHN0cmluZywgYW55PlxuICApOiBNIHtcbiAgICBjb25zdCBsb2cgPSB0aGlzLmxvZy5mb3IodGhpcy5yZXZlcnQpO1xuICAgIGNvbnN0IG9iOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0ge307XG4gICAgb2JbcGsgYXMgc3RyaW5nXSA9IGlkO1xuICAgIGNvbnN0IG0gPSAoXG4gICAgICB0eXBlb2YgY2xhenogPT09IFwic3RyaW5nXCIgPyBNb2RlbC5idWlsZChvYiwgY2xhenopIDogbmV3IGNsYXp6KG9iKVxuICAgICkgYXMgTTtcbiAgICBsb2cuc2lsbHkoYFJlYnVpbGRpbmcgbW9kZWwgJHttLmNvbnN0cnVjdG9yLm5hbWV9IGlkICR7aWR9YCk7XG4gICAgY29uc3QgbWV0YWRhdGEgPSBvYmpbUGVyc2lzdGVuY2VLZXlzLk1FVEFEQVRBXTtcbiAgICBjb25zdCByZXN1bHQgPSBPYmplY3Qua2V5cyhtKS5yZWR1Y2UoKGFjY3VtOiBNLCBrZXkpID0+IHtcbiAgICAgIGlmIChrZXkgPT09IHBrKSByZXR1cm4gYWNjdW07XG4gICAgICAoYWNjdW0gYXMgUmVjb3JkPHN0cmluZywgYW55Pilba2V5XSA9IG9ialtSZXBvc2l0b3J5LmNvbHVtbihhY2N1bSwga2V5KV07XG4gICAgICByZXR1cm4gYWNjdW07XG4gICAgfSwgbSk7XG5cbiAgICBpZiAodHJhbnNpZW50KSB7XG4gICAgICBsb2cudmVyYm9zZShcbiAgICAgICAgYHJlLWFkZGluZyB0cmFuc2llbnQgcHJvcGVydGllczogJHtPYmplY3Qua2V5cyh0cmFuc2llbnQpLmpvaW4oXCIsIFwiKX1gXG4gICAgICApO1xuICAgICAgT2JqZWN0LmVudHJpZXModHJhbnNpZW50KS5mb3JFYWNoKChba2V5LCB2YWxdKSA9PiB7XG4gICAgICAgIGlmIChrZXkgaW4gcmVzdWx0KVxuICAgICAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFxuICAgICAgICAgICAgYFRyYW5zaWVudCBwcm9wZXJ0eSAke2tleX0gYWxyZWFkeSBleGlzdHMgb24gbW9kZWwgJHttLmNvbnN0cnVjdG9yLm5hbWV9LiBzaG91bGQgYmUgaW1wb3NzaWJsZWBcbiAgICAgICAgICApO1xuICAgICAgICByZXN1bHRba2V5IGFzIGtleW9mIE1dID0gdmFsO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKG1ldGFkYXRhKSB7XG4gICAgICBsb2cuc2lsbHkoXG4gICAgICAgIGBQYXNzaW5nIGFsb25nICR7dGhpcy5mbGF2b3VyfSBwZXJzaXN0ZW5jZSBtZXRhZGF0YSBmb3IgJHttLmNvbnN0cnVjdG9yLm5hbWV9IGlkICR7aWR9OiAke21ldGFkYXRhfWBcbiAgICAgICk7XG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkocmVzdWx0LCBQZXJzaXN0ZW5jZUtleXMuTUVUQURBVEEsIHtcbiAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogZmFsc2UsXG4gICAgICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICAgICAgdmFsdWU6IG1ldGFkYXRhLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ3JlYXRlcyBhIG5ldyByZWNvcmQgaW4gdGhlIGRhdGFiYXNlXG4gICAqIEBzdW1tYXJ5IEluc2VydHMgYSBuZXcgcmVjb3JkIHdpdGggdGhlIGdpdmVuIElEIGFuZCBkYXRhIGludG8gdGhlIHNwZWNpZmllZCB0YWJsZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gdGFibGVOYW1lIC0gVGhlIG5hbWUgb2YgdGhlIHRhYmxlIHRvIGluc2VydCBpbnRvXG4gICAqIEBwYXJhbSB7c3RyaW5nfG51bWJlcn0gaWQgLSBUaGUgaWRlbnRpZmllciBmb3IgdGhlIG5ldyByZWNvcmRcbiAgICogQHBhcmFtIG1vZGVsIC0gVGhlIGRhdGEgdG8gaW5zZXJ0XG4gICAqIEBwYXJhbSB7YW55W119IGFyZ3MgLSBBZGRpdGlvbmFsIGFyZ3VtZW50cyBzcGVjaWZpYyB0byB0aGUgYWRhcHRlciBpbXBsZW1lbnRhdGlvblxuICAgKiBAcmV0dXJuIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIHRoZSBjcmVhdGVkIHJlY29yZFxuICAgKi9cbiAgYWJzdHJhY3QgY3JlYXRlKFxuICAgIHRhYmxlTmFtZTogc3RyaW5nLFxuICAgIGlkOiBzdHJpbmcgfCBudW1iZXIsXG4gICAgbW9kZWw6IFJlY29yZDxzdHJpbmcsIGFueT4sXG4gICAgLi4uYXJnczogYW55W11cbiAgKTogUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+PjtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENyZWF0ZXMgbXVsdGlwbGUgcmVjb3JkcyBpbiB0aGUgZGF0YWJhc2VcbiAgICogQHN1bW1hcnkgSW5zZXJ0cyBtdWx0aXBsZSByZWNvcmRzIHdpdGggdGhlIGdpdmVuIElEcyBhbmQgZGF0YSBpbnRvIHRoZSBzcGVjaWZpZWQgdGFibGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IHRhYmxlTmFtZSAtIFRoZSBuYW1lIG9mIHRoZSB0YWJsZSB0byBpbnNlcnQgaW50b1xuICAgKiBAcGFyYW0gaWQgLSBUaGUgaWRlbnRpZmllcnMgZm9yIHRoZSBuZXcgcmVjb3Jkc1xuICAgKiBAcGFyYW0gbW9kZWwgLSBUaGUgZGF0YSB0byBpbnNlcnQgZm9yIGVhY2ggcmVjb3JkXG4gICAqIEBwYXJhbSB7Li4uYW55W119IGFyZ3MgLSBBZGRpdGlvbmFsIGFyZ3VtZW50cyBzcGVjaWZpYyB0byB0aGUgYWRhcHRlciBpbXBsZW1lbnRhdGlvblxuICAgKiBAcmV0dXJuIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIGFuIGFycmF5IG9mIGNyZWF0ZWQgcmVjb3Jkc1xuICAgKi9cbiAgYXN5bmMgY3JlYXRlQWxsKFxuICAgIHRhYmxlTmFtZTogc3RyaW5nLFxuICAgIGlkOiAoc3RyaW5nIHwgbnVtYmVyKVtdLFxuICAgIG1vZGVsOiBSZWNvcmQ8c3RyaW5nLCBhbnk+W10sXG4gICAgLi4uYXJnczogYW55W11cbiAgKTogUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+W10+IHtcbiAgICBpZiAoaWQubGVuZ3RoICE9PSBtb2RlbC5sZW5ndGgpXG4gICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcIklkcyBhbmQgbW9kZWxzIG11c3QgaGF2ZSB0aGUgc2FtZSBsZW5ndGhcIik7XG4gICAgY29uc3QgbG9nID0gdGhpcy5sb2cuZm9yKHRoaXMuY3JlYXRlQWxsKTtcbiAgICBsb2cudmVyYm9zZShgQ3JlYXRpbmcgJHtpZC5sZW5ndGh9IGVudHJpZXMgJHt0YWJsZU5hbWV9IHRhYmxlYCk7XG4gICAgbG9nLmRlYnVnKGBwa3M6ICR7aWR9YCk7XG4gICAgcmV0dXJuIFByb21pc2UuYWxsKFxuICAgICAgaWQubWFwKChpLCBjb3VudCkgPT4gdGhpcy5jcmVhdGUodGFibGVOYW1lLCBpLCBtb2RlbFtjb3VudF0sIC4uLmFyZ3MpKVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJldHJpZXZlcyBhIHJlY29yZCBmcm9tIHRoZSBkYXRhYmFzZVxuICAgKiBAc3VtbWFyeSBGZXRjaGVzIGEgcmVjb3JkIHdpdGggdGhlIGdpdmVuIElEIGZyb20gdGhlIHNwZWNpZmllZCB0YWJsZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gdGFibGVOYW1lIC0gVGhlIG5hbWUgb2YgdGhlIHRhYmxlIHRvIHJlYWQgZnJvbVxuICAgKiBAcGFyYW0ge3N0cmluZ3xudW1iZXJ8YmlnaW50fSBpZCAtIFRoZSBpZGVudGlmaWVyIG9mIHRoZSByZWNvcmQgdG8gcmV0cmlldmVcbiAgICogQHBhcmFtIHsuLi5hbnlbXX0gYXJncyAtIEFkZGl0aW9uYWwgYXJndW1lbnRzIHNwZWNpZmljIHRvIHRoZSBhZGFwdGVyIGltcGxlbWVudGF0aW9uXG4gICAqIEByZXR1cm4gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gdGhlIHJldHJpZXZlZCByZWNvcmRcbiAgICovXG4gIGFic3RyYWN0IHJlYWQoXG4gICAgdGFibGVOYW1lOiBzdHJpbmcsXG4gICAgaWQ6IHN0cmluZyB8IG51bWJlciB8IGJpZ2ludCxcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApOiBQcm9taXNlPFJlY29yZDxzdHJpbmcsIGFueT4+O1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmV0cmlldmVzIG11bHRpcGxlIHJlY29yZHMgZnJvbSB0aGUgZGF0YWJhc2VcbiAgICogQHN1bW1hcnkgRmV0Y2hlcyBtdWx0aXBsZSByZWNvcmRzIHdpdGggdGhlIGdpdmVuIElEcyBmcm9tIHRoZSBzcGVjaWZpZWQgdGFibGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IHRhYmxlTmFtZSAtIFRoZSBuYW1lIG9mIHRoZSB0YWJsZSB0byByZWFkIGZyb21cbiAgICogQHBhcmFtIGlkIC0gVGhlIGlkZW50aWZpZXJzIG9mIHRoZSByZWNvcmRzIHRvIHJldHJpZXZlXG4gICAqIEBwYXJhbSB7Li4uYW55W119IGFyZ3MgLSBBZGRpdGlvbmFsIGFyZ3VtZW50cyBzcGVjaWZpYyB0byB0aGUgYWRhcHRlciBpbXBsZW1lbnRhdGlvblxuICAgKiBAcmV0dXJuIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIGFuIGFycmF5IG9mIHJldHJpZXZlZCByZWNvcmRzXG4gICAqL1xuICBhc3luYyByZWFkQWxsKFxuICAgIHRhYmxlTmFtZTogc3RyaW5nLFxuICAgIGlkOiAoc3RyaW5nIHwgbnVtYmVyIHwgYmlnaW50KVtdLFxuICAgIC4uLmFyZ3M6IGFueVtdXG4gICk6IFByb21pc2U8UmVjb3JkPHN0cmluZywgYW55PltdPiB7XG4gICAgY29uc3QgbG9nID0gdGhpcy5sb2cuZm9yKHRoaXMucmVhZEFsbCk7XG4gICAgbG9nLnZlcmJvc2UoYFJlYWRpbmcgJHtpZC5sZW5ndGh9IGVudHJpZXMgJHt0YWJsZU5hbWV9IHRhYmxlYCk7XG4gICAgbG9nLmRlYnVnKGBwa3M6ICR7aWR9YCk7XG4gICAgcmV0dXJuIFByb21pc2UuYWxsKGlkLm1hcCgoaSkgPT4gdGhpcy5yZWFkKHRhYmxlTmFtZSwgaSwgLi4uYXJncykpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gVXBkYXRlcyBhIHJlY29yZCBpbiB0aGUgZGF0YWJhc2VcbiAgICogQHN1bW1hcnkgTW9kaWZpZXMgYW4gZXhpc3RpbmcgcmVjb3JkIHdpdGggdGhlIGdpdmVuIElEIGluIHRoZSBzcGVjaWZpZWQgdGFibGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IHRhYmxlTmFtZSAtIFRoZSBuYW1lIG9mIHRoZSB0YWJsZSB0byB1cGRhdGVcbiAgICogQHBhcmFtIHtzdHJpbmd8bnVtYmVyfSBpZCAtIFRoZSBpZGVudGlmaWVyIG9mIHRoZSByZWNvcmQgdG8gdXBkYXRlXG4gICAqIEBwYXJhbSAgbW9kZWwgLSBUaGUgbmV3IGRhdGEgZm9yIHRoZSByZWNvcmRcbiAgICogQHBhcmFtIHsuLi5hbnlbXX0gYXJncyAtIEFkZGl0aW9uYWwgYXJndW1lbnRzIHNwZWNpZmljIHRvIHRoZSBhZGFwdGVyIGltcGxlbWVudGF0aW9uXG4gICAqIEByZXR1cm4gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gdGhlIHVwZGF0ZWQgcmVjb3JkXG4gICAqL1xuICBhYnN0cmFjdCB1cGRhdGUoXG4gICAgdGFibGVOYW1lOiBzdHJpbmcsXG4gICAgaWQ6IHN0cmluZyB8IG51bWJlcixcbiAgICBtb2RlbDogUmVjb3JkPHN0cmluZywgYW55PixcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApOiBQcm9taXNlPFJlY29yZDxzdHJpbmcsIGFueT4+O1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gVXBkYXRlcyBtdWx0aXBsZSByZWNvcmRzIGluIHRoZSBkYXRhYmFzZVxuICAgKiBAc3VtbWFyeSBNb2RpZmllcyBtdWx0aXBsZSBleGlzdGluZyByZWNvcmRzIHdpdGggdGhlIGdpdmVuIElEcyBpbiB0aGUgc3BlY2lmaWVkIHRhYmxlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0YWJsZU5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgdGFibGUgdG8gdXBkYXRlXG4gICAqIEBwYXJhbSB7c3RyaW5nW118bnVtYmVyW119IGlkIC0gVGhlIGlkZW50aWZpZXJzIG9mIHRoZSByZWNvcmRzIHRvIHVwZGF0ZVxuICAgKiBAcGFyYW0gbW9kZWwgLSBUaGUgbmV3IGRhdGEgZm9yIGVhY2ggcmVjb3JkXG4gICAqIEBwYXJhbSB7Li4uYW55W119IGFyZ3MgLSBBZGRpdGlvbmFsIGFyZ3VtZW50cyBzcGVjaWZpYyB0byB0aGUgYWRhcHRlciBpbXBsZW1lbnRhdGlvblxuICAgKiBAcmV0dXJuIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIGFuIGFycmF5IG9mIHVwZGF0ZWQgcmVjb3Jkc1xuICAgKi9cbiAgYXN5bmMgdXBkYXRlQWxsKFxuICAgIHRhYmxlTmFtZTogc3RyaW5nLFxuICAgIGlkOiBzdHJpbmdbXSB8IG51bWJlcltdLFxuICAgIG1vZGVsOiBSZWNvcmQ8c3RyaW5nLCBhbnk+W10sXG4gICAgLi4uYXJnczogYW55W11cbiAgKTogUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+W10+IHtcbiAgICBpZiAoaWQubGVuZ3RoICE9PSBtb2RlbC5sZW5ndGgpXG4gICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcIklkcyBhbmQgbW9kZWxzIG11c3QgaGF2ZSB0aGUgc2FtZSBsZW5ndGhcIik7XG4gICAgY29uc3QgbG9nID0gdGhpcy5sb2cuZm9yKHRoaXMudXBkYXRlQWxsKTtcbiAgICBsb2cudmVyYm9zZShgVXBkYXRpbmcgJHtpZC5sZW5ndGh9IGVudHJpZXMgJHt0YWJsZU5hbWV9IHRhYmxlYCk7XG4gICAgbG9nLmRlYnVnKGBwa3M6ICR7aWR9YCk7XG4gICAgcmV0dXJuIFByb21pc2UuYWxsKFxuICAgICAgaWQubWFwKChpLCBjb3VudCkgPT4gdGhpcy51cGRhdGUodGFibGVOYW1lLCBpLCBtb2RlbFtjb3VudF0sIC4uLmFyZ3MpKVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIERlbGV0ZXMgYSByZWNvcmQgZnJvbSB0aGUgZGF0YWJhc2VcbiAgICogQHN1bW1hcnkgUmVtb3ZlcyBhIHJlY29yZCB3aXRoIHRoZSBnaXZlbiBJRCBmcm9tIHRoZSBzcGVjaWZpZWQgdGFibGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IHRhYmxlTmFtZSAtIFRoZSBuYW1lIG9mIHRoZSB0YWJsZSB0byBkZWxldGUgZnJvbVxuICAgKiBAcGFyYW0ge3N0cmluZ3xudW1iZXJ8YmlnaW50fSBpZCAtIFRoZSBpZGVudGlmaWVyIG9mIHRoZSByZWNvcmQgdG8gZGVsZXRlXG4gICAqIEBwYXJhbSB7Li4uYW55W119IGFyZ3MgLSBBZGRpdGlvbmFsIGFyZ3VtZW50cyBzcGVjaWZpYyB0byB0aGUgYWRhcHRlciBpbXBsZW1lbnRhdGlvblxuICAgKiBAcmV0dXJuIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIHRoZSBkZWxldGVkIHJlY29yZFxuICAgKi9cbiAgYWJzdHJhY3QgZGVsZXRlKFxuICAgIHRhYmxlTmFtZTogc3RyaW5nLFxuICAgIGlkOiBzdHJpbmcgfCBudW1iZXIgfCBiaWdpbnQsXG4gICAgLi4uYXJnczogYW55W11cbiAgKTogUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+PjtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIERlbGV0ZXMgbXVsdGlwbGUgcmVjb3JkcyBmcm9tIHRoZSBkYXRhYmFzZVxuICAgKiBAc3VtbWFyeSBSZW1vdmVzIG11bHRpcGxlIHJlY29yZHMgd2l0aCB0aGUgZ2l2ZW4gSURzIGZyb20gdGhlIHNwZWNpZmllZCB0YWJsZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gdGFibGVOYW1lIC0gVGhlIG5hbWUgb2YgdGhlIHRhYmxlIHRvIGRlbGV0ZSBmcm9tXG4gICAqIEBwYXJhbSBpZCAtIFRoZSBpZGVudGlmaWVycyBvZiB0aGUgcmVjb3JkcyB0byBkZWxldGVcbiAgICogQHBhcmFtIHsuLi5hbnlbXX0gYXJncyAtIEFkZGl0aW9uYWwgYXJndW1lbnRzIHNwZWNpZmljIHRvIHRoZSBhZGFwdGVyIGltcGxlbWVudGF0aW9uXG4gICAqIEByZXR1cm4gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gYW4gYXJyYXkgb2YgZGVsZXRlZCByZWNvcmRzXG4gICAqL1xuICBhc3luYyBkZWxldGVBbGwoXG4gICAgdGFibGVOYW1lOiBzdHJpbmcsXG4gICAgaWQ6IChzdHJpbmcgfCBudW1iZXIgfCBiaWdpbnQpW10sXG4gICAgLi4uYXJnczogYW55W11cbiAgKTogUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+W10+IHtcbiAgICBjb25zdCBsb2cgPSB0aGlzLmxvZy5mb3IodGhpcy5jcmVhdGVBbGwpO1xuICAgIGxvZy52ZXJib3NlKGBEZWxldGluZyAke2lkLmxlbmd0aH0gZW50cmllcyAke3RhYmxlTmFtZX0gdGFibGVgKTtcbiAgICBsb2cuZGVidWcoYHBrczogJHtpZH1gKTtcbiAgICByZXR1cm4gUHJvbWlzZS5hbGwoaWQubWFwKChpKSA9PiB0aGlzLmRlbGV0ZSh0YWJsZU5hbWUsIGksIC4uLmFyZ3MpKSk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEV4ZWN1dGVzIGEgcmF3IHF1ZXJ5IGFnYWluc3QgdGhlIGRhdGFiYXNlXG4gICAqIEBzdW1tYXJ5IEFsbG93cyBleGVjdXRpbmcgZGF0YWJhc2Utc3BlY2lmaWMgcXVlcmllcyBkaXJlY3RseVxuICAgKiBAdGVtcGxhdGUgUSAtIFRoZSByYXcgcXVlcnkgdHlwZVxuICAgKiBAdGVtcGxhdGUgUiAtIFRoZSByZXR1cm4gdHlwZSBvZiB0aGUgcXVlcnlcbiAgICogQHBhcmFtIHtRfSByYXdJbnB1dCAtIFRoZSBxdWVyeSB0byBleGVjdXRlXG4gICAqIEBwYXJhbSB7Li4uYW55W119IGFyZ3MgLSBBZGRpdGlvbmFsIGFyZ3VtZW50cyBzcGVjaWZpYyB0byB0aGUgYWRhcHRlciBpbXBsZW1lbnRhdGlvblxuICAgKiBAcmV0dXJuIHtQcm9taXNlPFI+fSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byB0aGUgcXVlcnkgcmVzdWx0XG4gICAqL1xuICBhYnN0cmFjdCByYXc8Uj4ocmF3SW5wdXQ6IFEsIC4uLmFyZ3M6IGFueVtdKTogUHJvbWlzZTxSPjtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJlZ2lzdGVycyBhbiBvYnNlcnZlciBmb3IgZGF0YWJhc2UgZXZlbnRzXG4gICAqIEBzdW1tYXJ5IEFkZHMgYW4gb2JzZXJ2ZXIgdG8gYmUgbm90aWZpZWQgYWJvdXQgZGF0YWJhc2UgY2hhbmdlcy4gVGhlIG9ic2VydmVyIGNhbiBvcHRpb25hbGx5XG4gICAqIHByb3ZpZGUgYSBmaWx0ZXIgZnVuY3Rpb24gdG8gcmVjZWl2ZSBvbmx5IHNwZWNpZmljIGV2ZW50cy5cbiAgICogQHBhcmFtIHtPYnNlcnZlcn0gb2JzZXJ2ZXIgLSBUaGUgb2JzZXJ2ZXIgdG8gcmVnaXN0ZXJcbiAgICogQHBhcmFtIHtPYnNlcnZlckZpbHRlcn0gW2ZpbHRlcl0gLSBPcHRpb25hbCBmaWx0ZXIgZnVuY3Rpb24gdG8gZGV0ZXJtaW5lIHdoaWNoIGV2ZW50cyB0aGUgb2JzZXJ2ZXIgcmVjZWl2ZXNcbiAgICogQHJldHVybiB7dm9pZH1cbiAgICovXG4gIEBmaW5hbCgpXG4gIG9ic2VydmUob2JzZXJ2ZXI6IE9ic2VydmVyLCBmaWx0ZXI/OiBPYnNlcnZlckZpbHRlcik6IHZvaWQge1xuICAgIGlmICghdGhpcy5vYnNlcnZlckhhbmRsZXIpXG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgXCJvYnNlcnZlckhhbmRsZXJcIiwge1xuICAgICAgICB2YWx1ZTogdGhpcy5PYnNlcnZlckhhbmRsZXIoKSxcbiAgICAgICAgd3JpdGFibGU6IGZhbHNlLFxuICAgICAgfSk7XG4gICAgdGhpcy5vYnNlcnZlckhhbmRsZXIhLm9ic2VydmUob2JzZXJ2ZXIsIGZpbHRlcik7XG4gICAgdGhpcy5sb2dcbiAgICAgIC5mb3IodGhpcy5vYnNlcnZlKVxuICAgICAgLnZlcmJvc2UoYFJlZ2lzdGVyaW5nIG5ldyBvYnNlcnZlciAke29ic2VydmVyLnRvU3RyaW5nKCl9YCk7XG4gICAgaWYgKCF0aGlzLmRpc3BhdGNoKSB7XG4gICAgICB0aGlzLmxvZy5mb3IodGhpcy5vYnNlcnZlKS5pbmZvKGBDcmVhdGluZyBkaXNwYXRjaCBmb3IgJHt0aGlzLmFsaWFzfWApO1xuICAgICAgdGhpcy5kaXNwYXRjaCA9IHRoaXMuRGlzcGF0Y2goKTtcbiAgICAgIHRoaXMuZGlzcGF0Y2gub2JzZXJ2ZSh0aGlzKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFVucmVnaXN0ZXJzIGFuIG9ic2VydmVyXG4gICAqIEBzdW1tYXJ5IFJlbW92ZXMgYSBwcmV2aW91c2x5IHJlZ2lzdGVyZWQgb2JzZXJ2ZXIgc28gaXQgbm8gbG9uZ2VyIHJlY2VpdmVzIGRhdGFiYXNlIGV2ZW50IG5vdGlmaWNhdGlvbnNcbiAgICogQHBhcmFtIHtPYnNlcnZlcn0gb2JzZXJ2ZXIgLSBUaGUgb2JzZXJ2ZXIgdG8gdW5yZWdpc3RlclxuICAgKiBAcmV0dXJuIHt2b2lkfVxuICAgKi9cbiAgQGZpbmFsKClcbiAgdW5PYnNlcnZlKG9ic2VydmVyOiBPYnNlcnZlcik6IHZvaWQge1xuICAgIGlmICghdGhpcy5vYnNlcnZlckhhbmRsZXIpXG4gICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcbiAgICAgICAgXCJPYnNlcnZlckhhbmRsZXIgbm90IGluaXRpYWxpemVkLiBEaWQgeW91IHJlZ2lzdGVyIGFueSBvYnNlcnZhYmxlcz9cIlxuICAgICAgKTtcbiAgICB0aGlzLm9ic2VydmVySGFuZGxlci51bk9ic2VydmUob2JzZXJ2ZXIpO1xuICAgIHRoaXMubG9nXG4gICAgICAuZm9yKHRoaXMudW5PYnNlcnZlKVxuICAgICAgLnZlcmJvc2UoYE9ic2VydmVyICR7b2JzZXJ2ZXIudG9TdHJpbmcoKX0gcmVtb3ZlZGApO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBOb3RpZmllcyBhbGwgb2JzZXJ2ZXJzIGFib3V0IGEgZGF0YWJhc2UgZXZlbnRcbiAgICogQHN1bW1hcnkgU2VuZHMgbm90aWZpY2F0aW9ucyB0byBhbGwgcmVnaXN0ZXJlZCBvYnNlcnZlcnMgYWJvdXQgYSBjaGFuZ2UgaW4gdGhlIGRhdGFiYXNlLFxuICAgKiBmaWx0ZXJpbmcgYmFzZWQgb24gZWFjaCBvYnNlcnZlcidzIGZpbHRlciBmdW5jdGlvblxuICAgKiBAcGFyYW0ge3N0cmluZ30gdGFibGUgLSBUaGUgbmFtZSBvZiB0aGUgdGFibGUgd2hlcmUgdGhlIGNoYW5nZSBvY2N1cnJlZFxuICAgKiBAcGFyYW0ge09wZXJhdGlvbktleXN8QnVsa0NydWRPcGVyYXRpb25LZXlzfHN0cmluZ30gZXZlbnQgLSBUaGUgdHlwZSBvZiBvcGVyYXRpb24gdGhhdCBvY2N1cnJlZFxuICAgKiBAcGFyYW0ge0V2ZW50SWRzfSBpZCAtIFRoZSBpZGVudGlmaWVyKHMpIG9mIHRoZSBhZmZlY3RlZCByZWNvcmQocylcbiAgICogQHBhcmFtIHsuLi5hbnlbXX0gYXJncyAtIEFkZGl0aW9uYWwgYXJndW1lbnRzIHRvIHBhc3MgdG8gdGhlIG9ic2VydmVyc1xuICAgKiBAcmV0dXJuIHtQcm9taXNlPHZvaWQ+fSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIGFsbCBvYnNlcnZlcnMgaGF2ZSBiZWVuIG5vdGlmaWVkXG4gICAqL1xuICBhc3luYyB1cGRhdGVPYnNlcnZlcnMoXG4gICAgdGFibGU6IHN0cmluZyxcbiAgICBldmVudDogT3BlcmF0aW9uS2V5cyB8IEJ1bGtDcnVkT3BlcmF0aW9uS2V5cyB8IHN0cmluZyxcbiAgICBpZDogRXZlbnRJZHMsXG4gICAgLi4uYXJnczogYW55W11cbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKCF0aGlzLm9ic2VydmVySGFuZGxlcilcbiAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFxuICAgICAgICBcIk9ic2VydmVySGFuZGxlciBub3QgaW5pdGlhbGl6ZWQuIERpZCB5b3UgcmVnaXN0ZXIgYW55IG9ic2VydmFibGVzP1wiXG4gICAgICApO1xuICAgIGNvbnN0IGxvZyA9IHRoaXMubG9nLmZvcih0aGlzLnVwZGF0ZU9ic2VydmVycyk7XG4gICAgbG9nLnZlcmJvc2UoXG4gICAgICBgVXBkYXRpbmcgJHt0aGlzLm9ic2VydmVySGFuZGxlci5jb3VudCgpfSBvYnNlcnZlcnMgZm9yIGFkYXB0ZXIgJHt0aGlzLmFsaWFzfWBcbiAgICApO1xuICAgIGF3YWl0IHRoaXMub2JzZXJ2ZXJIYW5kbGVyLnVwZGF0ZU9ic2VydmVycyhcbiAgICAgIHRoaXMubG9nLFxuICAgICAgdGFibGUsXG4gICAgICBldmVudCxcbiAgICAgIGlkLFxuICAgICAgLi4uYXJnc1xuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJlZnJlc2hlcyBkYXRhIGJhc2VkIG9uIGEgZGF0YWJhc2UgZXZlbnRcbiAgICogQHN1bW1hcnkgSW1wbGVtZW50YXRpb24gb2YgdGhlIE9ic2VydmVyIGludGVyZmFjZSBtZXRob2QgdGhhdCBkZWxlZ2F0ZXMgdG8gdXBkYXRlT2JzZXJ2ZXJzXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0YWJsZSAtIFRoZSBuYW1lIG9mIHRoZSB0YWJsZSB3aGVyZSB0aGUgY2hhbmdlIG9jY3VycmVkXG4gICAqIEBwYXJhbSB7T3BlcmF0aW9uS2V5c3xCdWxrQ3J1ZE9wZXJhdGlvbktleXN8c3RyaW5nfSBldmVudCAtIFRoZSB0eXBlIG9mIG9wZXJhdGlvbiB0aGF0IG9jY3VycmVkXG4gICAqIEBwYXJhbSB7RXZlbnRJZHN9IGlkIC0gVGhlIGlkZW50aWZpZXIocykgb2YgdGhlIGFmZmVjdGVkIHJlY29yZChzKVxuICAgKiBAcGFyYW0gey4uLmFueVtdfSBhcmdzIC0gQWRkaXRpb25hbCBhcmd1bWVudHMgcmVsYXRlZCB0byB0aGUgZXZlbnRcbiAgICogQHJldHVybiB7UHJvbWlzZTx2b2lkPn0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiB0aGUgcmVmcmVzaCBpcyBjb21wbGV0ZVxuICAgKi9cbiAgYXN5bmMgcmVmcmVzaChcbiAgICB0YWJsZTogc3RyaW5nLFxuICAgIGV2ZW50OiBPcGVyYXRpb25LZXlzIHwgQnVsa0NydWRPcGVyYXRpb25LZXlzIHwgc3RyaW5nLFxuICAgIGlkOiBFdmVudElkcyxcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApIHtcbiAgICByZXR1cm4gdGhpcy51cGRhdGVPYnNlcnZlcnModGFibGUsIGV2ZW50LCBpZCwgLi4uYXJncyk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEdldHMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIGFkYXB0ZXJcbiAgICogQHN1bW1hcnkgUmV0dXJucyBhIGh1bWFuLXJlYWRhYmxlIHN0cmluZyBpZGVudGlmeWluZyB0aGlzIGFkYXB0ZXJcbiAgICogQHJldHVybiB7c3RyaW5nfSBBIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgYWRhcHRlclxuICAgKi9cbiAgdG9TdHJpbmcoKSB7XG4gICAgcmV0dXJuIGAke3RoaXMuZmxhdm91cn0gcGVyc2lzdGVuY2UgQWRhcHRlcmA7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEdldHMgdGhlIGFkYXB0ZXIgZmxhdm9yIGFzc29jaWF0ZWQgd2l0aCBhIG1vZGVsXG4gICAqIEBzdW1tYXJ5IFJldHJpZXZlcyB0aGUgYWRhcHRlciBmbGF2b3IgdGhhdCBzaG91bGQgYmUgdXNlZCBmb3IgYSBzcGVjaWZpYyBtb2RlbCBjbGFzc1xuICAgKiBAdGVtcGxhdGUgTSAtIFRoZSBtb2RlbCB0eXBlXG4gICAqIEBwYXJhbSB7Q29uc3RydWN0b3I8TT59IG1vZGVsIC0gVGhlIG1vZGVsIGNvbnN0cnVjdG9yXG4gICAqIEByZXR1cm4ge3N0cmluZ30gVGhlIGFkYXB0ZXIgZmxhdm9yIG5hbWVcbiAgICovXG4gIHN0YXRpYyBmbGF2b3VyT2Y8TSBleHRlbmRzIE1vZGVsPihtb2RlbDogQ29uc3RydWN0b3I8TT4pOiBzdHJpbmcge1xuICAgIHJldHVybiAoXG4gICAgICBSZWZsZWN0LmdldE1ldGFkYXRhKHRoaXMua2V5KFBlcnNpc3RlbmNlS2V5cy5BREFQVEVSKSwgbW9kZWwpIHx8XG4gICAgICB0aGlzLmN1cnJlbnQuZmxhdm91clxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEdldHMgdGhlIGN1cnJlbnQgZGVmYXVsdCBhZGFwdGVyXG4gICAqIEBzdW1tYXJ5IFJldHJpZXZlcyB0aGUgYWRhcHRlciB0aGF0IGlzIGN1cnJlbnRseSBzZXQgYXMgdGhlIGRlZmF1bHQgZm9yIG9wZXJhdGlvbnNcbiAgICogQHJldHVybiB7QWRhcHRlcjxhbnksIGFueSwgYW55LCBhbnk+fSBUaGUgY3VycmVudCBhZGFwdGVyXG4gICAqL1xuICBzdGF0aWMgZ2V0IGN1cnJlbnQoKSB7XG4gICAgaWYgKCFBZGFwdGVyLl9jdXJyZW50KVxuICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXG4gICAgICAgIGBObyBwZXJzaXN0ZW5jZSBmbGF2b3VyIHNldC4gUGxlYXNlIGluaXRpYWxpemUgeW91ciBhZGFwdGVyYFxuICAgICAgKTtcbiAgICByZXR1cm4gQWRhcHRlci5fY3VycmVudDtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gR2V0cyBhbiBhZGFwdGVyIGJ5IGZsYXZvclxuICAgKiBAc3VtbWFyeSBSZXRyaWV2ZXMgYSByZWdpc3RlcmVkIGFkYXB0ZXIgYnkgaXRzIGZsYXZvciBuYW1lXG4gICAqIEB0ZW1wbGF0ZSBZIC0gVGhlIGRhdGFiYXNlIGRyaXZlciB0eXBlXG4gICAqIEB0ZW1wbGF0ZSBRIC0gVGhlIHF1ZXJ5IHR5cGVcbiAgICogQHRlbXBsYXRlIEMgLSBUaGUgY29udGV4dCB0eXBlXG4gICAqIEB0ZW1wbGF0ZSBGIC0gVGhlIHJlcG9zaXRvcnkgZmxhZ3MgdHlwZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gZmxhdm91ciAtIFRoZSBmbGF2b3IgbmFtZSBvZiB0aGUgYWRhcHRlciB0byByZXRyaWV2ZVxuICAgKiBAcmV0dXJuIHtBZGFwdGVyPFksIFEsIEYsIEM+IHwgdW5kZWZpbmVkfSBUaGUgYWRhcHRlciBpbnN0YW5jZSBvciB1bmRlZmluZWQgaWYgbm90IGZvdW5kXG4gICAqL1xuICBzdGF0aWMgZ2V0PFksIFEsIEMgZXh0ZW5kcyBDb250ZXh0PEY+LCBGIGV4dGVuZHMgUmVwb3NpdG9yeUZsYWdzPihcbiAgICBmbGF2b3VyOiBhbnlcbiAgKTogQWRhcHRlcjxZLCBRLCBGLCBDPiB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKGZsYXZvdXIgaW4gdGhpcy5fY2FjaGUpIHJldHVybiB0aGlzLl9jYWNoZVtmbGF2b3VyXTtcbiAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihgTm8gQWRhcHRlciByZWdpc3RlcmVkIHVuZGVyICR7Zmxhdm91cn0uYCk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFNldHMgdGhlIGN1cnJlbnQgZGVmYXVsdCBhZGFwdGVyXG4gICAqIEBzdW1tYXJ5IENoYW5nZXMgd2hpY2ggYWRhcHRlciBpcyB1c2VkIGFzIHRoZSBkZWZhdWx0IGZvciBvcGVyYXRpb25zXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBmbGF2b3VyIC0gVGhlIGZsYXZvciBuYW1lIG9mIHRoZSBhZGFwdGVyIHRvIHNldCBhcyBjdXJyZW50XG4gICAqIEByZXR1cm4ge3ZvaWR9XG4gICAqL1xuICBzdGF0aWMgc2V0Q3VycmVudChmbGF2b3VyOiBzdHJpbmcpIHtcbiAgICBjb25zdCBhZGFwdGVyID0gQWRhcHRlci5nZXQoZmxhdm91cik7XG4gICAgaWYgKCFhZGFwdGVyKVxuICAgICAgdGhyb3cgbmV3IE5vdEZvdW5kRXJyb3IoYE5vIHBlcnNpc3RlbmNlIGZsYXZvdXIgJHtmbGF2b3VyfSByZWdpc3RlcmVkYCk7XG4gICAgdGhpcy5fY3VycmVudCA9IGFkYXB0ZXI7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENyZWF0ZXMgYSBtZXRhZGF0YSBrZXlcbiAgICogQHN1bW1hcnkgR2VuZXJhdGVzIGEgc3RhbmRhcmRpemVkIG1ldGFkYXRhIGtleSBmb3IgcGVyc2lzdGVuY2UtcmVsYXRlZCBtZXRhZGF0YVxuICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IC0gVGhlIGJhc2Uga2V5IG5hbWVcbiAgICogQHJldHVybiB7c3RyaW5nfSBUaGUgZm9ybWF0dGVkIG1ldGFkYXRhIGtleVxuICAgKi9cbiAgc3RhdGljIGtleShrZXk6IHN0cmluZykge1xuICAgIHJldHVybiBSZXBvc2l0b3J5LmtleShrZXkpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBHZXRzIGFsbCBtb2RlbHMgYXNzb2NpYXRlZCB3aXRoIGFuIGFkYXB0ZXIgZmxhdm9yXG4gICAqIEBzdW1tYXJ5IFJldHJpZXZlcyBhbGwgbW9kZWwgY29uc3RydWN0b3JzIHRoYXQgYXJlIGNvbmZpZ3VyZWQgdG8gdXNlIGEgc3BlY2lmaWMgYWRhcHRlciBmbGF2b3JcbiAgICogQHRlbXBsYXRlIE0gLSBUaGUgbW9kZWwgdHlwZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gZmxhdm91ciAtIFRoZSBhZGFwdGVyIGZsYXZvciB0byBmaW5kIG1vZGVscyBmb3JcbiAgICogQHJldHVybiBBbiBhcnJheSBvZiBtb2RlbCBjb25zdHJ1Y3RvcnNcbiAgICovXG4gIHN0YXRpYyBtb2RlbHM8TSBleHRlbmRzIE1vZGVsPihmbGF2b3VyOiBzdHJpbmcpIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVnaXN0cnkgPSAoTW9kZWwgYXMgYW55KS5nZXRSZWdpc3RyeSgpIGFzIE1vZGVsUmVnaXN0cnk8YW55PjtcbiAgICAgIGNvbnN0IGNhY2hlID0gKFxuICAgICAgICByZWdpc3RyeSBhcyB1bmtub3duIGFzIHsgY2FjaGU6IFJlY29yZDxzdHJpbmcsIE1vZGVsQ29uc3RydWN0b3I8YW55Pj4gfVxuICAgICAgKS5jYWNoZTtcbiAgICAgIGNvbnN0IG1hbmFnZWRNb2RlbHM6IE1vZGVsQ29uc3RydWN0b3I8YW55PltdID0gT2JqZWN0LnZhbHVlcyhjYWNoZSlcbiAgICAgICAgLm1hcCgobTogTW9kZWxDb25zdHJ1Y3RvcjxNPikgPT4ge1xuICAgICAgICAgIGxldCBmID0gUmVmbGVjdC5nZXRNZXRhZGF0YShcbiAgICAgICAgICAgIEFkYXB0ZXIua2V5KFBlcnNpc3RlbmNlS2V5cy5BREFQVEVSKSxcbiAgICAgICAgICAgIG0gYXMgTW9kZWxDb25zdHJ1Y3Rvcjxhbnk+XG4gICAgICAgICAgKTtcbiAgICAgICAgICBpZiAoZiAmJiBmID09PSBmbGF2b3VyKSByZXR1cm4gbTtcbiAgICAgICAgICBpZiAoIWYpIHtcbiAgICAgICAgICAgIGNvbnN0IHJlcG8gPSBSZWZsZWN0LmdldE1ldGFkYXRhKFxuICAgICAgICAgICAgICBSZXBvc2l0b3J5LmtleShEQktleXMuUkVQT1NJVE9SWSksXG4gICAgICAgICAgICAgIG0gYXMgTW9kZWxDb25zdHJ1Y3Rvcjxhbnk+XG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgaWYgKCFyZXBvKSByZXR1cm47XG4gICAgICAgICAgICBjb25zdCByZXBvc2l0b3J5ID0gUmVwb3NpdG9yeS5mb3JNb2RlbChtKTtcblxuICAgICAgICAgICAgZiA9IFJlZmxlY3QuZ2V0TWV0YWRhdGEoXG4gICAgICAgICAgICAgIEFkYXB0ZXIua2V5KFBlcnNpc3RlbmNlS2V5cy5BREFQVEVSKSxcbiAgICAgICAgICAgICAgcmVwb3NpdG9yeVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHJldHVybiBmO1xuICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICAgICAgLmZpbHRlcigobSkgPT4gISFtKTtcbiAgICAgIHJldHVybiBtYW5hZ2VkTW9kZWxzO1xuICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoZSk7XG4gICAgfVxuICB9XG59XG4iLCJpbXBvcnQgeyBDb25zdHJ1Y3RvciwgTW9kZWwgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBBZGFwdGVyIH0gZnJvbSBcIi4uL3BlcnNpc3RlbmNlL0FkYXB0ZXJcIjtcbmltcG9ydCB7IFBlcnNpc3RlbmNlS2V5cyB9IGZyb20gXCIuLi9wZXJzaXN0ZW5jZS9jb25zdGFudHNcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gR2V0cyB0aGUgdGFibGUgbmFtZSBmb3IgYSBtb2RlbFxuICogQHN1bW1hcnkgUmV0cmlldmVzIHRoZSB0YWJsZSBuYW1lIGFzc29jaWF0ZWQgd2l0aCBhIG1vZGVsIGJ5IGNoZWNraW5nIG1ldGFkYXRhIG9yIGZhbGxpbmcgYmFjayB0byB0aGUgY29uc3RydWN0b3IgbmFtZVxuICogQHRlbXBsYXRlIE0gLSBUeXBlIHRoYXQgZXh0ZW5kcyBNb2RlbFxuICogQHBhcmFtIHtNIHwgQ29uc3RydWN0b3I8TT59IG1vZGVsIC0gVGhlIG1vZGVsIGluc3RhbmNlIG9yIGNvbnN0cnVjdG9yIHRvIGdldCB0aGUgdGFibGUgbmFtZSBmb3JcbiAqIEByZXR1cm4ge3N0cmluZ30gVGhlIHRhYmxlIG5hbWUgZm9yIHRoZSBtb2RlbFxuICogQGZ1bmN0aW9uIGdldFRhYmxlTmFtZVxuICogQG1lbWJlck9mIG1vZHVsZTpjb3JlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRUYWJsZU5hbWU8TSBleHRlbmRzIE1vZGVsPihcbiAgbW9kZWw6IE0gfCBDb25zdHJ1Y3RvcjxNPlxuKTogc3RyaW5nIHtcbiAgY29uc3Qgb2JqID0gbW9kZWwgaW5zdGFuY2VvZiBNb2RlbCA/IG1vZGVsLmNvbnN0cnVjdG9yIDogbW9kZWw7XG5cbiAgY29uc3QgbWV0YWRhdGEgPSBSZWZsZWN0LmdldE93bk1ldGFkYXRhKFxuICAgIEFkYXB0ZXIua2V5KFBlcnNpc3RlbmNlS2V5cy5UQUJMRSksXG4gICAgb2JqXG4gICk7XG4gIGlmIChtZXRhZGF0YSkge1xuICAgIHJldHVybiBtZXRhZGF0YTtcbiAgfVxuICBpZiAobW9kZWwgaW5zdGFuY2VvZiBNb2RlbCkge1xuICAgIHJldHVybiBtb2RlbC5jb25zdHJ1Y3Rvci5uYW1lO1xuICB9XG4gIHJldHVybiBtb2RlbC5uYW1lO1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBHZW5lcmF0ZXMgYSBzZXF1ZW5jZSBuYW1lIGZvciBhIG1vZGVsXG4gKiBAc3VtbWFyeSBDcmVhdGVzIGEgc3RhbmRhcmRpemVkIHNlcXVlbmNlIG5hbWUgYnkgY29tYmluaW5nIHRoZSB0YWJsZSBuYW1lIHdpdGggYWRkaXRpb25hbCBhcmd1bWVudHNcbiAqIEB0ZW1wbGF0ZSBNIC0gVHlwZSB0aGF0IGV4dGVuZHMgTW9kZWxcbiAqIEBwYXJhbSB7TSB8IENvbnN0cnVjdG9yPE0+fSBtb2RlbCAtIFRoZSBtb2RlbCBpbnN0YW5jZSBvciBjb25zdHJ1Y3RvciB0byBnZW5lcmF0ZSB0aGUgc2VxdWVuY2UgbmFtZSBmb3JcbiAqIEBwYXJhbSB7Li4uc3RyaW5nfSBhcmdzIC0gQWRkaXRpb25hbCBzdHJpbmcgYXJndW1lbnRzIHRvIGFwcGVuZCB0byB0aGUgc2VxdWVuY2UgbmFtZVxuICogQHJldHVybiB7c3RyaW5nfSBUaGUgZ2VuZXJhdGVkIHNlcXVlbmNlIG5hbWVcbiAqIEBmdW5jdGlvbiBzZXF1ZW5jZU5hbWVGb3JNb2RlbFxuICogQG1lbWJlck9mIG1vZHVsZTpjb3JlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZXF1ZW5jZU5hbWVGb3JNb2RlbDxNIGV4dGVuZHMgTW9kZWw+KFxuICBtb2RlbDogTSB8IENvbnN0cnVjdG9yPE0+LFxuICAuLi5hcmdzOiBzdHJpbmdbXVxuKSB7XG4gIHJldHVybiBbZ2V0VGFibGVOYW1lKG1vZGVsKSwgLi4uYXJnc10uam9pbihcIl9cIik7XG59XG4iLCJpbXBvcnQgeyBDb25zdHJ1Y3RvciwgTW9kZWwgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBzZXF1ZW5jZU5hbWVGb3JNb2RlbCB9IGZyb20gXCIuLi9pZGVudGl0eS91dGlsc1wiO1xuaW1wb3J0IHsgU2VxdWVuY2VPcHRpb25zIH0gZnJvbSBcIi4uL2ludGVyZmFjZXMvU2VxdWVuY2VPcHRpb25zXCI7XG5pbXBvcnQgeyBJbnRlcm5hbEVycm9yIH0gZnJvbSBcIkBkZWNhZi10cy9kYi1kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBMb2dnZXIsIExvZ2dpbmcgfSBmcm9tIFwiQGRlY2FmLXRzL2xvZ2dpbmdcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gQWJzdHJhY3QgYmFzZSBjbGFzcyBmb3Igc2VxdWVuY2UgZ2VuZXJhdGlvblxuICogQHN1bW1hcnkgUHJvdmlkZXMgYSBmcmFtZXdvcmsgZm9yIGdlbmVyYXRpbmcgc2VxdWVudGlhbCB2YWx1ZXMgKGxpa2UgcHJpbWFyeSBrZXlzKSBpbiB0aGUgcGVyc2lzdGVuY2UgbGF5ZXIuXG4gKiBJbXBsZW1lbnRhdGlvbnMgb2YgdGhpcyBjbGFzcyBoYW5kbGUgdGhlIHNwZWNpZmljcyBvZiBob3cgc2VxdWVuY2VzIGFyZSBzdG9yZWQgYW5kIGluY3JlbWVudGVkIGluIGRpZmZlcmVudFxuICogZGF0YWJhc2Ugc3lzdGVtcy5cbiAqIEBwYXJhbSB7U2VxdWVuY2VPcHRpb25zfSBvcHRpb25zIC0gQ29uZmlndXJhdGlvbiBvcHRpb25zIGZvciB0aGUgc2VxdWVuY2UgZ2VuZXJhdG9yXG4gKiBAY2xhc3MgU2VxdWVuY2VcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiAvLyBFeGFtcGxlIGltcGxlbWVudGF0aW9uIGZvciBhIHNwZWNpZmljIGRhdGFiYXNlXG4gKiBjbGFzcyBQb3N0Z3Jlc1NlcXVlbmNlIGV4dGVuZHMgU2VxdWVuY2Uge1xuICogICBjb25zdHJ1Y3RvcihvcHRpb25zOiBTZXF1ZW5jZU9wdGlvbnMpIHtcbiAqICAgICBzdXBlcihvcHRpb25zKTtcbiAqICAgfVxuICpcbiAqICAgYXN5bmMgbmV4dCgpOiBQcm9taXNlPG51bWJlcj4ge1xuICogICAgIC8vIEltcGxlbWVudGF0aW9uIHRvIGdldCBuZXh0IHZhbHVlIGZyb20gUG9zdGdyZVNRTCBzZXF1ZW5jZVxuICogICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMub3B0aW9ucy5leGVjdXRvci5yYXcoYFNFTEVDVCBuZXh0dmFsKCcke3RoaXMub3B0aW9ucy5uYW1lfScpYCk7XG4gKiAgICAgcmV0dXJuIHBhcnNlSW50KHJlc3VsdC5yb3dzWzBdLm5leHR2YWwpO1xuICogICB9XG4gKlxuICogICBhc3luYyBjdXJyZW50KCk6IFByb21pc2U8bnVtYmVyPiB7XG4gKiAgICAgLy8gSW1wbGVtZW50YXRpb24gdG8gZ2V0IGN1cnJlbnQgdmFsdWUgZnJvbSBQb3N0Z3JlU1FMIHNlcXVlbmNlXG4gKiAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5vcHRpb25zLmV4ZWN1dG9yLnJhdyhgU0VMRUNUIGN1cnJ2YWwoJyR7dGhpcy5vcHRpb25zLm5hbWV9JylgKTtcbiAqICAgICByZXR1cm4gcGFyc2VJbnQocmVzdWx0LnJvd3NbMF0uY3VycnZhbCk7XG4gKiAgIH1cbiAqXG4gKiAgIGFzeW5jIHJhbmdlKGNvdW50OiBudW1iZXIpOiBQcm9taXNlPG51bWJlcltdPiB7XG4gKiAgICAgLy8gSW1wbGVtZW50YXRpb24gdG8gZ2V0IGEgcmFuZ2Ugb2YgdmFsdWVzXG4gKiAgICAgY29uc3QgdmFsdWVzOiBudW1iZXJbXSA9IFtdO1xuICogICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY291bnQ7IGkrKykge1xuICogICAgICAgdmFsdWVzLnB1c2goYXdhaXQgdGhpcy5uZXh0KCkpO1xuICogICAgIH1cbiAqICAgICByZXR1cm4gdmFsdWVzO1xuICogICB9XG4gKiB9XG4gKlxuICogLy8gVXNhZ2VcbiAqIGNvbnN0IHNlcXVlbmNlID0gbmV3IFBvc3RncmVzU2VxdWVuY2Uoe1xuICogICBuYW1lOiAndXNlcl9pZF9zZXEnLFxuICogICBleGVjdXRvcjogZGJFeGVjdXRvclxuICogfSk7XG4gKlxuICogY29uc3QgbmV4dElkID0gYXdhaXQgc2VxdWVuY2UubmV4dCgpO1xuICogYGBgXG4gKi9cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBTZXF1ZW5jZSB7XG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gTG9nZ2VyIGluc3RhbmNlIGZvciB0aGlzIHNlcXVlbmNlXG4gICAqIEBzdW1tYXJ5IExhemlseSBpbml0aWFsaXplZCBsb2dnZXIgZm9yIHRoZSBzZXF1ZW5jZSBpbnN0YW5jZVxuICAgKi9cbiAgcHJpdmF0ZSBsb2dnZXIhOiBMb2dnZXI7XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBBY2Nlc3NvciBmb3IgdGhlIGxvZ2dlciBpbnN0YW5jZVxuICAgKiBAc3VtbWFyeSBHZXRzIG9yIGluaXRpYWxpemVzIHRoZSBsb2dnZXIgZm9yIHRoaXMgc2VxdWVuY2VcbiAgICogQHJldHVybiB7TG9nZ2VyfSBUaGUgbG9nZ2VyIGluc3RhbmNlXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0IGxvZygpIHtcbiAgICBpZiAoIXRoaXMubG9nZ2VyKSB0aGlzLmxvZ2dlciA9IExvZ2dpbmcuZm9yKHRoaXMgYXMgYW55KTtcbiAgICByZXR1cm4gdGhpcy5sb2dnZXI7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENyZWF0ZXMgYSBuZXcgc2VxdWVuY2UgaW5zdGFuY2VcbiAgICogQHN1bW1hcnkgUHJvdGVjdGVkIGNvbnN0cnVjdG9yIHRoYXQgaW5pdGlhbGl6ZXMgdGhlIHNlcXVlbmNlIHdpdGggdGhlIHByb3ZpZGVkIG9wdGlvbnNcbiAgICovXG4gIHByb3RlY3RlZCBjb25zdHJ1Y3Rvcihwcm90ZWN0ZWQgcmVhZG9ubHkgb3B0aW9uczogU2VxdWVuY2VPcHRpb25zKSB7fVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gR2V0cyB0aGUgbmV4dCB2YWx1ZSBpbiB0aGUgc2VxdWVuY2VcbiAgICogQHN1bW1hcnkgUmV0cmlldmVzIHRoZSBuZXh0IHZhbHVlIGZyb20gdGhlIHNlcXVlbmNlLCBpbmNyZW1lbnRpbmcgaXQgaW4gdGhlIHByb2Nlc3NcbiAgICogQHJldHVybiBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byB0aGUgbmV4dCB2YWx1ZSBpbiB0aGUgc2VxdWVuY2VcbiAgICovXG4gIGFic3RyYWN0IG5leHQoKTogUHJvbWlzZTxzdHJpbmcgfCBudW1iZXIgfCBiaWdpbnQ+O1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gR2V0cyB0aGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgc2VxdWVuY2VcbiAgICogQHN1bW1hcnkgUmV0cmlldmVzIHRoZSBjdXJyZW50IHZhbHVlIG9mIHRoZSBzZXF1ZW5jZSB3aXRob3V0IGluY3JlbWVudGluZyBpdFxuICAgKiBAcmV0dXJuIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIHRoZSBjdXJyZW50IHZhbHVlIGluIHRoZSBzZXF1ZW5jZVxuICAgKi9cbiAgYWJzdHJhY3QgY3VycmVudCgpOiBQcm9taXNlPHN0cmluZyB8IG51bWJlciB8IGJpZ2ludD47XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBHZXRzIGEgcmFuZ2Ugb2Ygc2VxdWVudGlhbCB2YWx1ZXNcbiAgICogQHN1bW1hcnkgUmV0cmlldmVzIG11bHRpcGxlIHNlcXVlbnRpYWwgdmFsdWVzIGF0IG9uY2UsIHdoaWNoIGNhbiBiZSBtb3JlIGVmZmljaWVudCB0aGFuIGNhbGxpbmcgbmV4dCgpIG11bHRpcGxlIHRpbWVzXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBjb3VudCAtIFRoZSBudW1iZXIgb2Ygc2VxdWVudGlhbCB2YWx1ZXMgdG8gcmV0cmlldmVcbiAgICogQHJldHVybiBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhbiBhcnJheSBvZiBzZXF1ZW50aWFsIHZhbHVlc1xuICAgKi9cbiAgYWJzdHJhY3QgcmFuZ2UoY291bnQ6IG51bWJlcik6IFByb21pc2U8KG51bWJlciB8IHN0cmluZyB8IGJpZ2ludClbXT47XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBHZXRzIHRoZSBwcmltYXJ5IGtleSBzZXF1ZW5jZSBuYW1lIGZvciBhIG1vZGVsXG4gICAqIEBzdW1tYXJ5IFV0aWxpdHkgbWV0aG9kIHRoYXQgcmV0dXJucyB0aGUgc3RhbmRhcmRpemVkIHNlcXVlbmNlIG5hbWUgZm9yIGEgbW9kZWwncyBwcmltYXJ5IGtleVxuICAgKiBAdGVtcGxhdGUgTSAtIFRoZSBtb2RlbCB0eXBlXG4gICAqIEBwYXJhbSB7TXxDb25zdHJ1Y3RvcjxNPn0gbW9kZWwgLSBUaGUgbW9kZWwgaW5zdGFuY2Ugb3IgY29uc3RydWN0b3JcbiAgICogQHJldHVybiB7c3RyaW5nfSBUaGUgc2VxdWVuY2UgbmFtZSBmb3IgdGhlIG1vZGVsJ3MgcHJpbWFyeSBrZXlcbiAgICovXG4gIHN0YXRpYyBwazxNIGV4dGVuZHMgTW9kZWw+KG1vZGVsOiBNIHwgQ29uc3RydWN0b3I8TT4pIHtcbiAgICByZXR1cm4gc2VxdWVuY2VOYW1lRm9yTW9kZWwobW9kZWwsIFwicGtcIik7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFBhcnNlcyBhIHNlcXVlbmNlIHZhbHVlIHRvIHRoZSBhcHByb3ByaWF0ZSB0eXBlXG4gICAqIEBzdW1tYXJ5IENvbnZlcnRzIGEgc2VxdWVuY2UgdmFsdWUgdG8gdGhlIHNwZWNpZmllZCB0eXBlIChOdW1iZXIgb3IgQmlnSW50KVxuICAgKiBAcGFyYW0ge1wiTnVtYmVyXCJ8XCJCaWdJbnRcInx1bmRlZmluZWR9IHR5cGUgLSBUaGUgdGFyZ2V0IHR5cGUgdG8gY29udmVydCB0b1xuICAgKiBAcGFyYW0ge3N0cmluZ3xudW1iZXJ8YmlnaW50fSB2YWx1ZSAtIFRoZSB2YWx1ZSB0byBjb252ZXJ0XG4gICAqIEByZXR1cm4ge3N0cmluZ3xudW1iZXJ8YmlnaW50fSBUaGUgY29udmVydGVkIHZhbHVlXG4gICAqL1xuICBzdGF0aWMgcGFyc2VWYWx1ZShcbiAgICB0eXBlOiBcIk51bWJlclwiIHwgXCJCaWdJbnRcIiB8IHVuZGVmaW5lZCxcbiAgICB2YWx1ZTogc3RyaW5nIHwgbnVtYmVyIHwgYmlnaW50XG4gICk6IHN0cmluZyB8IG51bWJlciB8IGJpZ2ludCB7XG4gICAgc3dpdGNoICh0eXBlKSB7XG4gICAgICBjYXNlIFwiTnVtYmVyXCI6XG4gICAgICAgIHJldHVybiB0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCJcbiAgICAgICAgICA/IHBhcnNlSW50KHZhbHVlKVxuICAgICAgICAgIDogdHlwZW9mIHZhbHVlID09PSBcIm51bWJlclwiXG4gICAgICAgICAgICA/IHZhbHVlXG4gICAgICAgICAgICA6IEJpZ0ludCh2YWx1ZSk7XG4gICAgICBjYXNlIFwiQmlnSW50XCI6XG4gICAgICAgIHJldHVybiBCaWdJbnQodmFsdWUpO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXCJTaG91bGQgbmV2ZXIgaGFwcGVuXCIpO1xuICAgIH1cbiAgfVxufVxuIiwiaW1wb3J0IHsgYXBwbHksIG1ldGFkYXRhIH0gZnJvbSBcIkBkZWNhZi10cy9yZWZsZWN0aW9uXCI7XG5pbXBvcnQgeyBQZXJzaXN0ZW5jZUtleXMgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IEFkYXB0ZXIgfSBmcm9tIFwiLi9BZGFwdGVyXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIFNwZWNpZmllcyB3aGljaCBwZXJzaXN0ZW5jZSBhZGFwdGVyIGZsYXZvciBhIG1vZGVsIHNob3VsZCB1c2VcbiAqIEBzdW1tYXJ5IFRoaXMgZGVjb3JhdG9yIGFwcGxpZXMgbWV0YWRhdGEgdG8gYSBtb2RlbCBjbGFzcyB0byBpbmRpY2F0ZSB3aGljaCBwZXJzaXN0ZW5jZSBhZGFwdGVyIGZsYXZvclxuICogc2hvdWxkIGJlIHVzZWQgd2hlbiBwZXJmb3JtaW5nIGRhdGFiYXNlIG9wZXJhdGlvbnMgb24gaW5zdGFuY2VzIG9mIHRoZSBtb2RlbC4gVGhlIGZsYXZvciBpcyBhIHN0cmluZ1xuICogaWRlbnRpZmllciB0aGF0IGNvcnJlc3BvbmRzIHRvIGEgcmVnaXN0ZXJlZCBhZGFwdGVyIGNvbmZpZ3VyYXRpb24uXG4gKiBAcGFyYW0ge3N0cmluZ30gZmxhdm91ciAtIFRoZSBpZGVudGlmaWVyIG9mIHRoZSBhZGFwdGVyIGZsYXZvciB0byB1c2VcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufSBBIGRlY29yYXRvciBmdW5jdGlvbiB0aGF0IGNhbiBiZSBhcHBsaWVkIHRvIGEgbW9kZWwgY2xhc3NcbiAqIEBmdW5jdGlvbiB1c2VzXG4gKiBAY2F0ZWdvcnkgQ2xhc3MgRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gdXNlcyhmbGF2b3VyOiBzdHJpbmcpIHtcbiAgcmV0dXJuIGFwcGx5KG1ldGFkYXRhKEFkYXB0ZXIua2V5KFBlcnNpc3RlbmNlS2V5cy5BREFQVEVSKSwgZmxhdm91cikpO1xufVxuIiwiaW1wb3J0IHtcbiAgQnVsa0NydWRPcGVyYXRpb25LZXlzLFxuICBDb250ZXh0LFxuICBEQktleXMsXG4gIERlZmF1bHRTZXBhcmF0b3IsXG4gIGVuZm9yY2VEQkRlY29yYXRvcnMsXG4gIGZpbmRQcmltYXJ5S2V5LFxuICBJbnRlcm5hbEVycm9yLFxuICBJUmVwb3NpdG9yeSxcbiAgT3BlcmF0aW9uS2V5cyxcbiAgUmVwb3NpdG9yeSBhcyBSZXAsXG4gIFJlcG9zaXRvcnlGbGFncyxcbiAgVmFsaWRhdGlvbkVycm9yLFxuICB3cmFwTWV0aG9kV2l0aENvbnRleHQsXG59IGZyb20gXCJAZGVjYWYtdHMvZGItZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZSB9IGZyb20gXCIuLi9pbnRlcmZhY2VzL09ic2VydmFibGVcIjtcbmltcG9ydCB7IHR5cGUgT2JzZXJ2ZXIgfSBmcm9tIFwiLi4vaW50ZXJmYWNlcy9PYnNlcnZlclwiO1xuaW1wb3J0IHsgQWRhcHRlciB9IGZyb20gXCIuLi9wZXJzaXN0ZW5jZS9BZGFwdGVyXCI7XG5pbXBvcnQgeyBDb25zdHJ1Y3RvciwgTW9kZWwgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBQZXJzaXN0ZW5jZUtleXMgfSBmcm9tIFwiLi4vcGVyc2lzdGVuY2UvY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBPcmRlckRpcmVjdGlvbiB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgU2VxdWVuY2VPcHRpb25zIH0gZnJvbSBcIi4uL2ludGVyZmFjZXMvU2VxdWVuY2VPcHRpb25zXCI7XG5pbXBvcnQgeyBRdWVyaWFibGUgfSBmcm9tIFwiLi4vaW50ZXJmYWNlcy9RdWVyaWFibGVcIjtcbmltcG9ydCB7IFJlZmxlY3Rpb24gfSBmcm9tIFwiQGRlY2FmLXRzL3JlZmxlY3Rpb25cIjtcbmltcG9ydCB7IEluZGV4TWV0YWRhdGEgfSBmcm9tIFwiLi90eXBlc1wiO1xuaW1wb3J0IHsgU2VxdWVuY2UgfSBmcm9tIFwiLi4vcGVyc2lzdGVuY2UvU2VxdWVuY2VcIjtcbmltcG9ydCB7IENvbmRpdGlvbiB9IGZyb20gXCIuLi9xdWVyeS9Db25kaXRpb25cIjtcbmltcG9ydCB7IFdoZXJlT3B0aW9uIH0gZnJvbSBcIi4uL3F1ZXJ5L29wdGlvbnNcIjtcbmltcG9ydCB7IE9yZGVyQnlTZWxlY3RvciwgU2VsZWN0U2VsZWN0b3IgfSBmcm9tIFwiLi4vcXVlcnkvc2VsZWN0b3JzXCI7XG5pbXBvcnQgeyBnZXRUYWJsZU5hbWUgfSBmcm9tIFwiLi4vaWRlbnRpdHkvdXRpbHNcIjtcbmltcG9ydCB7IHVzZXMgfSBmcm9tIFwiLi4vcGVyc2lzdGVuY2UvZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHsgTG9nZ2VyLCBMb2dnaW5nIH0gZnJvbSBcIkBkZWNhZi10cy9sb2dnaW5nXCI7XG5pbXBvcnQgeyBPYnNlcnZlckhhbmRsZXIgfSBmcm9tIFwiLi4vcGVyc2lzdGVuY2UvT2JzZXJ2ZXJIYW5kbGVyXCI7XG5pbXBvcnQgeyBmaW5hbCB9IGZyb20gXCIuLi91dGlsc1wiO1xuaW1wb3J0IHR5cGUgeyBFdmVudElkcywgT2JzZXJ2ZXJGaWx0ZXIgfSBmcm9tIFwiLi4vcGVyc2lzdGVuY2VcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gVHlwZSBhbGlhcyBmb3IgUmVwb3NpdG9yeSBjbGFzcyB3aXRoIHNpbXBsaWZpZWQgZ2VuZXJpYyBwYXJhbWV0ZXJzLlxuICogQHN1bW1hcnkgUHJvdmlkZXMgYSBtb3JlIGNvbmNpc2Ugd2F5IHRvIHJlZmVyZW5jZSB0aGUgUmVwb3NpdG9yeSBjbGFzcyB3aXRoIGl0cyBnZW5lcmljIHBhcmFtZXRlcnMuXG4gKiBAdGVtcGxhdGUgTSAtIFRoZSBtb2RlbCB0eXBlIHRoYXQgZXh0ZW5kcyBNb2RlbC5cbiAqIEB0ZW1wbGF0ZSBGIC0gVGhlIHJlcG9zaXRvcnkgZmxhZ3MgdHlwZS5cbiAqIEB0ZW1wbGF0ZSBDIC0gVGhlIGNvbnRleHQgdHlwZS5cbiAqIEB0ZW1wbGF0ZSBRIC0gVGhlIHF1ZXJ5IHR5cGUuXG4gKiBAdGVtcGxhdGUgQSAtIFRoZSBhZGFwdGVyIHR5cGUuXG4gKiBAdHlwZWRlZiBSZXBvXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmNvcmVcbiAqL1xuZXhwb3J0IHR5cGUgUmVwbzxcbiAgTSBleHRlbmRzIE1vZGVsLFxuICBGIGV4dGVuZHMgUmVwb3NpdG9yeUZsYWdzID0gYW55LFxuICBDIGV4dGVuZHMgQ29udGV4dDxGPiA9IGFueSxcbiAgUSA9IGFueSxcbiAgQSBleHRlbmRzIEFkYXB0ZXI8YW55LCBRLCBGLCBDPiA9IGFueSxcbj4gPSBSZXBvc2l0b3J5PE0sIFEsIEEsIEYsIEM+O1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBDb3JlIHJlcG9zaXRvcnkgaW1wbGVtZW50YXRpb24gZm9yIGRhdGFiYXNlIG9wZXJhdGlvbnMgb24gbW9kZWxzIG9uIGEgdGFibGUgYnkgdGFibGUgd2F5LlxuICogQHN1bW1hcnkgUHJvdmlkZXMgQ1JVRCBvcGVyYXRpb25zLCBxdWVyeWluZyBjYXBhYmlsaXRpZXMsIGFuZCBvYnNlcnZlciBwYXR0ZXJuIGltcGxlbWVudGF0aW9uIGZvciBtb2RlbCBwZXJzaXN0ZW5jZS5cbiAqIEB0ZW1wbGF0ZSBNIC0gVGhlIG1vZGVsIHR5cGUgdGhhdCBleHRlbmRzIE1vZGVsLlxuICogQHRlbXBsYXRlIFEgLSBUaGUgcXVlcnkgdHlwZSB1c2VkIGJ5IHRoZSBhZGFwdGVyLlxuICogQHRlbXBsYXRlIEEgLSBUaGUgYWRhcHRlciB0eXBlIGZvciBkYXRhYmFzZSBvcGVyYXRpb25zLlxuICogQHRlbXBsYXRlIEYgLSBUaGUgcmVwb3NpdG9yeSBmbGFncyB0eXBlLlxuICogQHRlbXBsYXRlIEMgLSBUaGUgY29udGV4dCB0eXBlIGZvciBvcGVyYXRpb25zLlxuICogQHBhcmFtIHtBfSBbYWRhcHRlcl0gLSBPcHRpb25hbCBhZGFwdGVyIGluc3RhbmNlIGZvciBkYXRhYmFzZSBvcGVyYXRpb25zLlxuICogQHBhcmFtIHtDb25zdHJ1Y3RvcjxNPn0gW2NsYXp6XSAtIE9wdGlvbmFsIGNvbnN0cnVjdG9yIGZvciB0aGUgbW9kZWwgY2xhc3MuXG4gKiBAcGFyYW0gey4uLmFueVtdfSBbYXJnc10gLSBBZGRpdGlvbmFsIGFyZ3VtZW50cyBmb3IgcmVwb3NpdG9yeSBpbml0aWFsaXphdGlvbi5cbiAqIEBjbGFzcyBSZXBvc2l0b3J5XG4gKiBAZXhhbXBsZVxuICogLy8gQ3JlYXRpbmcgYSByZXBvc2l0b3J5IGZvciBVc2VyIG1vZGVsXG4gKiBjb25zdCB1c2VyUmVwbyA9IFJlcG9zaXRvcnkuZm9yTW9kZWwoVXNlcik7XG4gKlxuICogLy8gVXNpbmcgdGhlIHJlcG9zaXRvcnkgZm9yIENSVUQgb3BlcmF0aW9uc1xuICogY29uc3QgdXNlciA9IGF3YWl0IHVzZXJSZXBvLmNyZWF0ZShuZXcgVXNlcih7IG5hbWU6ICdKb2huJyB9KSk7XG4gKiBjb25zdCByZXRyaWV2ZWRVc2VyID0gYXdhaXQgdXNlclJlcG8ucmVhZCh1c2VyLmlkKTtcbiAqIHVzZXIubmFtZSA9ICdKYW5lJztcbiAqIGF3YWl0IHVzZXJSZXBvLnVwZGF0ZSh1c2VyKTtcbiAqIGF3YWl0IHVzZXJSZXBvLmRlbGV0ZSh1c2VyLmlkKTtcbiAqXG4gKiAvLyBRdWVyeWluZyB3aXRoIGNvbmRpdGlvbnNcbiAqIGNvbnN0IHVzZXJzID0gYXdhaXQgdXNlclJlcG9cbiAqICAgLnNlbGVjdCgpXG4gKiAgIC53aGVyZSh7IG5hbWU6ICdKYW5lJyB9KVxuICogICAub3JkZXJCeSgnY3JlYXRlZEF0JywgT3JkZXJEaXJlY3Rpb24uRFNDKVxuICogICAubGltaXQoMTApXG4gKiAgIC5leGVjdXRlKCk7XG4gKiBAbWVybWFpZFxuICogc2VxdWVuY2VEaWFncmFtXG4gKiAgIHBhcnRpY2lwYW50IEMgYXMgQ2xpZW50IENvZGVcbiAqICAgcGFydGljaXBhbnQgUiBhcyBSZXBvc2l0b3J5XG4gKiAgIHBhcnRpY2lwYW50IEEgYXMgQWRhcHRlclxuICogICBwYXJ0aWNpcGFudCBEQiBhcyBEYXRhYmFzZVxuICogICBwYXJ0aWNpcGFudCBPIGFzIE9ic2VydmVyc1xuICpcbiAqICAgQy0+PitSOiBjcmVhdGUobW9kZWwpXG4gKiAgIFItPj5SOiBjcmVhdGVQcmVmaXgobW9kZWwpXG4gKiAgIFItPj4rQTogcHJlcGFyZShtb2RlbClcbiAqICAgQS0tPj4tUjogcHJlcGFyZWQgZGF0YVxuICogICBSLT4+K0E6IGNyZWF0ZSh0YWJsZSwgaWQsIHJlY29yZClcbiAqICAgQS0+PitEQjogSW5zZXJ0IE9wZXJhdGlvblxuICogICBEQi0tPj4tQTogUmVzdWx0XG4gKiAgIEEtLT4+LVI6IHJlY29yZFxuICogICBSLT4+K0E6IHJldmVydChyZWNvcmQpXG4gKiAgIEEtLT4+LVI6IG1vZGVsIGluc3RhbmNlXG4gKiAgIFItPj5SOiBjcmVhdGVTdWZmaXgobW9kZWwpXG4gKiAgIFItPj4rTzogdXBkYXRlT2JzZXJ2ZXJzKHRhYmxlLCBDUkVBVEUsIGlkKVxuICogICBPLS0+Pi1SOiBOb3RpZmljYXRpb24gY29tcGxldGVcbiAqICAgUi0tPj4tQzogY3JlYXRlZCBtb2RlbFxuICovXG5leHBvcnQgY2xhc3MgUmVwb3NpdG9yeTxcbiAgICBNIGV4dGVuZHMgTW9kZWwsXG4gICAgUSxcbiAgICBBIGV4dGVuZHMgQWRhcHRlcjxhbnksIFEsIEYsIEM+LFxuICAgIEYgZXh0ZW5kcyBSZXBvc2l0b3J5RmxhZ3MgPSBSZXBvc2l0b3J5RmxhZ3MsXG4gICAgQyBleHRlbmRzIENvbnRleHQ8Rj4gPSBDb250ZXh0PEY+LFxuICA+XG4gIGV4dGVuZHMgUmVwPE0sIEYsIEM+XG4gIGltcGxlbWVudHMgT2JzZXJ2YWJsZSwgT2JzZXJ2ZXIsIFF1ZXJpYWJsZTxNPiwgSVJlcG9zaXRvcnk8TSwgRiwgQz5cbntcbiAgcHJpdmF0ZSBzdGF0aWMgX2NhY2hlOiBSZWNvcmQ8XG4gICAgc3RyaW5nLFxuICAgIENvbnN0cnVjdG9yPFJlcG88TW9kZWw+PiB8IFJlcG88TW9kZWw+XG4gID4gPSB7fTtcblxuICBwcm90ZWN0ZWQgb2JzZXJ2ZXJzOiBPYnNlcnZlcltdID0gW107XG5cbiAgcHJvdGVjdGVkIG9ic2VydmVySGFuZGxlcj86IE9ic2VydmVySGFuZGxlcjtcblxuICBwcml2YXRlIHJlYWRvbmx5IF9hZGFwdGVyITogQTtcbiAgcHJpdmF0ZSBfdGFibGVOYW1lITogc3RyaW5nO1xuICBwcml2YXRlIF9vdmVycmlkZXM/OiBQYXJ0aWFsPEY+O1xuXG4gIHByaXZhdGUgbG9nZ2VyITogTG9nZ2VyO1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gTG9nZ2VyIGluc3RhbmNlIGZvciB0aGlzIHJlcG9zaXRvcnkuXG4gICAqIEBzdW1tYXJ5IFByb3ZpZGVzIGFjY2VzcyB0byB0aGUgbG9nZ2VyIGZvciB0aGlzIHJlcG9zaXRvcnkgaW5zdGFuY2UuXG4gICAqIEByZXR1cm4ge0xvZ2dlcn0gVGhlIGxvZ2dlciBpbnN0YW5jZS5cbiAgICovXG4gIGdldCBsb2coKTogTG9nZ2VyIHtcbiAgICBpZiAoIXRoaXMubG9nZ2VyKSB0aGlzLmxvZ2dlciA9IExvZ2dpbmcuZm9yKHRoaXMgYXMgYW55KTtcbiAgICByZXR1cm4gdGhpcy5sb2dnZXI7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEFkYXB0ZXIgZm9yIGRhdGFiYXNlIG9wZXJhdGlvbnMuXG4gICAqIEBzdW1tYXJ5IFByb3ZpZGVzIGFjY2VzcyB0byB0aGUgYWRhcHRlciBpbnN0YW5jZSBmb3IgdGhpcyByZXBvc2l0b3J5LlxuICAgKiBAdGVtcGxhdGUgQSAtIFRoZSBhZGFwdGVyIHR5cGUuXG4gICAqIEByZXR1cm4ge0F9IFRoZSBhZGFwdGVyIGluc3RhbmNlLlxuICAgKiBAdGhyb3dzIHtJbnRlcm5hbEVycm9yfSBJZiBubyBhZGFwdGVyIGlzIGZvdW5kLlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldCBhZGFwdGVyKCk6IEEge1xuICAgIGlmICghdGhpcy5fYWRhcHRlcilcbiAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFxuICAgICAgICBgTm8gYWRhcHRlciBmb3VuZCBmb3IgdGhpcyByZXBvc2l0b3J5LiBkaWQgeW91IHVzZSB0aGUgQHVzZXMgZGVjb3JhdG9yIG9yIHBhc3MgaXQgaW4gdGhlIGNvbnN0cnVjdG9yP2BcbiAgICAgICk7XG4gICAgcmV0dXJuIHRoaXMuX2FkYXB0ZXI7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFRhYmxlIG5hbWUgZm9yIHRoaXMgcmVwb3NpdG9yeSdzIG1vZGVsLlxuICAgKiBAc3VtbWFyeSBHZXRzIHRoZSBkYXRhYmFzZSB0YWJsZSBuYW1lIGFzc29jaWF0ZWQgd2l0aCB0aGlzIHJlcG9zaXRvcnkncyBtb2RlbC5cbiAgICogQHJldHVybiB7c3RyaW5nfSBUaGUgdGFibGUgbmFtZS5cbiAgICovXG4gIHByb3RlY3RlZCBnZXQgdGFibGVOYW1lKCk6IHN0cmluZyB7XG4gICAgaWYgKCF0aGlzLl90YWJsZU5hbWUpIHRoaXMuX3RhYmxlTmFtZSA9IFJlcG9zaXRvcnkudGFibGUodGhpcy5jbGFzcyk7XG4gICAgcmV0dXJuIHRoaXMuX3RhYmxlTmFtZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUHJpbWFyeSBrZXkgcHJvcGVydGllcyBmb3IgdGhpcyByZXBvc2l0b3J5J3MgbW9kZWwuXG4gICAqIEBzdW1tYXJ5IEdldHMgdGhlIHNlcXVlbmNlIG9wdGlvbnMgY29udGFpbmluZyBwcmltYXJ5IGtleSBpbmZvcm1hdGlvbi5cbiAgICogQHJldHVybiB7U2VxdWVuY2VPcHRpb25zfSBUaGUgcHJpbWFyeSBrZXkgcHJvcGVydGllcy5cbiAgICovXG4gIHByb3RlY3RlZCBvdmVycmlkZSBnZXQgcGtQcm9wcygpOiBTZXF1ZW5jZU9wdGlvbnMge1xuICAgIHJldHVybiBzdXBlci5wa1Byb3BzO1xuICB9XG5cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICBjb25zdHJ1Y3RvcihhZGFwdGVyPzogQSwgY2xheno/OiBDb25zdHJ1Y3RvcjxNPiwgLi4uYXJnczogYW55W10pIHtcbiAgICBzdXBlcihjbGF6eik7XG4gICAgaWYgKGFkYXB0ZXIpIHRoaXMuX2FkYXB0ZXIgPSBhZGFwdGVyO1xuICAgIGlmIChjbGF6eikge1xuICAgICAgUmVwb3NpdG9yeS5yZWdpc3RlcihjbGF6eiwgdGhpcywgdGhpcy5hZGFwdGVyLmFsaWFzKTtcbiAgICAgIGlmIChhZGFwdGVyKSB7XG4gICAgICAgIGNvbnN0IGZsYXZvdXIgPSBSZWZsZWN0LmdldE1ldGFkYXRhKFxuICAgICAgICAgIEFkYXB0ZXIua2V5KFBlcnNpc3RlbmNlS2V5cy5BREFQVEVSKSxcbiAgICAgICAgICBjbGF6elxuICAgICAgICApO1xuICAgICAgICBpZiAoZmxhdm91ciAmJiBmbGF2b3VyICE9PSBhZGFwdGVyLmZsYXZvdXIpXG4gICAgICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXCJJbmNvbXBhdGlibGUgZmxhdm91cnNcIik7XG4gICAgICAgIHVzZXMoYWRhcHRlci5mbGF2b3VyKShjbGF6eik7XG4gICAgICB9XG4gICAgfVxuICAgIFt0aGlzLmNyZWF0ZUFsbCwgdGhpcy5yZWFkQWxsLCB0aGlzLnVwZGF0ZUFsbCwgdGhpcy5kZWxldGVBbGxdLmZvckVhY2goXG4gICAgICAobSkgPT4ge1xuICAgICAgICBjb25zdCBuYW1lID0gbS5uYW1lO1xuICAgICAgICB3cmFwTWV0aG9kV2l0aENvbnRleHQoXG4gICAgICAgICAgdGhpcyxcbiAgICAgICAgICAodGhpcyBhcyBhbnkpW25hbWUgKyBcIlByZWZpeFwiXSxcbiAgICAgICAgICBtLFxuICAgICAgICAgICh0aGlzIGFzIGFueSlbbmFtZSArIFwiU3VmZml4XCJdXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ3JlYXRlcyBhIHByb3h5IHdpdGggb3ZlcnJpZGRlbiByZXBvc2l0b3J5IGZsYWdzLlxuICAgKiBAc3VtbWFyeSBSZXR1cm5zIGEgcHJveHkgb2YgdGhpcyByZXBvc2l0b3J5IHdpdGggdGhlIHNwZWNpZmllZCBmbGFncyBvdmVycmlkZGVuLlxuICAgKiBAcGFyYW0ge1BhcnRpYWw8Rj59IGZsYWdzIC0gVGhlIGZsYWdzIHRvIG92ZXJyaWRlLlxuICAgKiBAcmV0dXJuIHtSZXBvc2l0b3J5fSBBIHByb3h5IG9mIHRoaXMgcmVwb3NpdG9yeSB3aXRoIG92ZXJyaWRkZW4gZmxhZ3MuXG4gICAqL1xuICBvdmVycmlkZShmbGFnczogUGFydGlhbDxGPik6IFJlcG9zaXRvcnk8TSwgUSwgQSwgRiwgQz4ge1xuICAgIHRoaXMubG9nXG4gICAgICAuZm9yKHRoaXMub3ZlcnJpZGUpXG4gICAgICAuZGVidWcoYE92ZXJyaWRpbmcgcmVwb3NpdG9yeSBmbGFncyB3aXRoICR7SlNPTi5zdHJpbmdpZnkoZmxhZ3MpfWApO1xuICAgIHJldHVybiBuZXcgUHJveHkodGhpcywge1xuICAgICAgZ2V0OiAodGFyZ2V0OiB0eXBlb2YgdGhpcywgcDogc3RyaW5nIHwgc3ltYm9sLCByZWNlaXZlcjogYW55KSA9PiB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IFJlZmxlY3QuZ2V0KHRhcmdldCwgcCwgcmVjZWl2ZXIpO1xuICAgICAgICBpZiAocCAhPT0gXCJfb3ZlcnJpZGVzXCIpIHJldHVybiByZXN1bHQ7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCByZXN1bHQsIGZsYWdzKTtcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENyZWF0ZXMgYSBuZXcgb2JzZXJ2ZXIgaGFuZGxlci5cbiAgICogQHN1bW1hcnkgRmFjdG9yeSBtZXRob2QgZm9yIGNyZWF0aW5nIGFuIG9ic2VydmVyIGhhbmRsZXIgaW5zdGFuY2UuXG4gICAqIEByZXR1cm4ge09ic2VydmVySGFuZGxlcn0gQSBuZXcgb2JzZXJ2ZXIgaGFuZGxlciBpbnN0YW5jZS5cbiAgICovXG4gIHByb3RlY3RlZCBPYnNlcnZlckhhbmRsZXIoKTogT2JzZXJ2ZXJIYW5kbGVyIHtcbiAgICByZXR1cm4gbmV3IE9ic2VydmVySGFuZGxlcigpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBQcmVwYXJlcyBhIG1vZGVsIGZvciBjcmVhdGlvbi5cbiAgICogQHN1bW1hcnkgVmFsaWRhdGVzIHRoZSBtb2RlbCBhbmQgcHJlcGFyZXMgaXQgZm9yIGNyZWF0aW9uIGluIHRoZSBkYXRhYmFzZS5cbiAgICogQHRlbXBsYXRlIE0gLSBUaGUgbW9kZWwgdHlwZS5cbiAgICogQHBhcmFtIHtNfSBtb2RlbCAtIFRoZSBtb2RlbCB0byBjcmVhdGUuXG4gICAqIEBwYXJhbSB7Li4uYW55W119IGFyZ3MgLSBBZGRpdGlvbmFsIGFyZ3VtZW50cy5cbiAgICogQHJldHVybiBUaGUgcHJlcGFyZWQgbW9kZWwgYW5kIGNvbnRleHQgYXJndW1lbnRzLlxuICAgKiBAdGhyb3dzIHtWYWxpZGF0aW9uRXJyb3J9IElmIHRoZSBtb2RlbCBmYWlscyB2YWxpZGF0aW9uLlxuICAgKi9cbiAgcHJvdGVjdGVkIG92ZXJyaWRlIGFzeW5jIGNyZWF0ZVByZWZpeChcbiAgICBtb2RlbDogTSxcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApOiBQcm9taXNlPFtNLCAuLi5hbnlbXV0+IHtcbiAgICBjb25zdCBjb250ZXh0QXJncyA9IGF3YWl0IENvbnRleHQuYXJnczxNLCBDLCBGPihcbiAgICAgIE9wZXJhdGlvbktleXMuQ1JFQVRFLFxuICAgICAgdGhpcy5jbGFzcyxcbiAgICAgIGFyZ3MsXG4gICAgICB0aGlzLmFkYXB0ZXIsXG4gICAgICB0aGlzLl9vdmVycmlkZXMgfHwge31cbiAgICApO1xuICAgIG1vZGVsID0gbmV3IHRoaXMuY2xhc3MobW9kZWwpO1xuICAgIGF3YWl0IGVuZm9yY2VEQkRlY29yYXRvcnMoXG4gICAgICB0aGlzLFxuICAgICAgY29udGV4dEFyZ3MuY29udGV4dCxcbiAgICAgIG1vZGVsLFxuICAgICAgT3BlcmF0aW9uS2V5cy5DUkVBVEUsXG4gICAgICBPcGVyYXRpb25LZXlzLk9OXG4gICAgKTtcblxuICAgIGNvbnN0IGVycm9ycyA9IG1vZGVsLmhhc0Vycm9ycyhcbiAgICAgIC4uLihjb250ZXh0QXJncy5jb250ZXh0LmdldChcImlnbm9yZWRWYWxpZGF0aW9uUHJvcGVydGllc1wiKSB8fCBbXSlcbiAgICApO1xuICAgIGlmIChlcnJvcnMpIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoZXJyb3JzLnRvU3RyaW5nKCkpO1xuXG4gICAgcmV0dXJuIFttb2RlbCwgLi4uY29udGV4dEFyZ3MuYXJnc107XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENyZWF0ZXMgYSBtb2RlbCBpbiB0aGUgZGF0YWJhc2UuXG4gICAqIEBzdW1tYXJ5IFBlcnNpc3RzIGEgbW9kZWwgaW5zdGFuY2UgdG8gdGhlIGRhdGFiYXNlLlxuICAgKiBAcGFyYW0ge019IG1vZGVsIC0gVGhlIG1vZGVsIHRvIGNyZWF0ZS5cbiAgICogQHBhcmFtIHsuLi5hbnlbXX0gYXJncyAtIEFkZGl0aW9uYWwgYXJndW1lbnRzLlxuICAgKiBAcmV0dXJuIHtQcm9taXNlPE0+fSBUaGUgY3JlYXRlZCBtb2RlbCB3aXRoIHVwZGF0ZWQgcHJvcGVydGllcy5cbiAgICovXG4gIGFzeW5jIGNyZWF0ZShtb2RlbDogTSwgLi4uYXJnczogYW55W10pOiBQcm9taXNlPE0+IHtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcHJlZmVyLWNvbnN0XG4gICAgbGV0IHsgcmVjb3JkLCBpZCwgdHJhbnNpZW50IH0gPSB0aGlzLmFkYXB0ZXIucHJlcGFyZShtb2RlbCwgdGhpcy5wayk7XG4gICAgcmVjb3JkID0gYXdhaXQgdGhpcy5hZGFwdGVyLmNyZWF0ZSh0aGlzLnRhYmxlTmFtZSwgaWQsIHJlY29yZCwgLi4uYXJncyk7XG4gICAgbGV0IGM6IEMgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG4gICAgaWYgKGFyZ3MubGVuZ3RoKSBjID0gYXJnc1thcmdzLmxlbmd0aCAtIDFdIGFzIEM7XG4gICAgcmV0dXJuIHRoaXMuYWRhcHRlci5yZXZlcnQ8TT4oXG4gICAgICByZWNvcmQsXG4gICAgICB0aGlzLmNsYXNzLFxuICAgICAgdGhpcy5wayxcbiAgICAgIGlkLFxuICAgICAgYyAmJiBjLmdldChcInJlYnVpbGRXaXRoVHJhbnNpZW50XCIpID8gdHJhbnNpZW50IDogdW5kZWZpbmVkXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUG9zdC1jcmVhdGlvbiBob29rLlxuICAgKiBAc3VtbWFyeSBFeGVjdXRlcyBhZnRlciBhIG1vZGVsIGlzIGNyZWF0ZWQgdG8gcGVyZm9ybSBhZGRpdGlvbmFsIG9wZXJhdGlvbnMuXG4gICAqIEBwYXJhbSB7TX0gbW9kZWwgLSBUaGUgY3JlYXRlZCBtb2RlbC5cbiAgICogQHBhcmFtIHtDfSBjb250ZXh0IC0gVGhlIG9wZXJhdGlvbiBjb250ZXh0LlxuICAgKiBAcmV0dXJuIHtQcm9taXNlPE0+fSBUaGUgcHJvY2Vzc2VkIG1vZGVsLlxuICAgKi9cbiAgb3ZlcnJpZGUgYXN5bmMgY3JlYXRlU3VmZml4KG1vZGVsOiBNLCBjb250ZXh0OiBDKTogUHJvbWlzZTxNPiB7XG4gICAgcmV0dXJuIHN1cGVyLmNyZWF0ZVN1ZmZpeChtb2RlbCwgY29udGV4dCk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENyZWF0ZXMgbXVsdGlwbGUgbW9kZWxzIGluIHRoZSBkYXRhYmFzZS5cbiAgICogQHN1bW1hcnkgUGVyc2lzdHMgbXVsdGlwbGUgbW9kZWwgaW5zdGFuY2VzIHRvIHRoZSBkYXRhYmFzZSBpbiBhIGJhdGNoIG9wZXJhdGlvbi5cbiAgICogQHBhcmFtIHtNW119IG1vZGVscyAtIFRoZSBtb2RlbHMgdG8gY3JlYXRlLlxuICAgKiBAcGFyYW0gey4uLmFueVtdfSBhcmdzIC0gQWRkaXRpb25hbCBhcmd1bWVudHMuXG4gICAqIEByZXR1cm4ge1Byb21pc2U8TVtdPn0gVGhlIGNyZWF0ZWQgbW9kZWxzIHdpdGggdXBkYXRlZCBwcm9wZXJ0aWVzLlxuICAgKi9cbiAgb3ZlcnJpZGUgYXN5bmMgY3JlYXRlQWxsKG1vZGVsczogTVtdLCAuLi5hcmdzOiBhbnlbXSk6IFByb21pc2U8TVtdPiB7XG4gICAgaWYgKCFtb2RlbHMubGVuZ3RoKSByZXR1cm4gbW9kZWxzO1xuICAgIGNvbnN0IHByZXBhcmVkID0gbW9kZWxzLm1hcCgobSkgPT4gdGhpcy5hZGFwdGVyLnByZXBhcmUobSwgdGhpcy5waykpO1xuICAgIGNvbnN0IGlkcyA9IHByZXBhcmVkLm1hcCgocCkgPT4gcC5pZCk7XG4gICAgbGV0IHJlY29yZHMgPSBwcmVwYXJlZC5tYXAoKHApID0+IHAucmVjb3JkKTtcbiAgICByZWNvcmRzID0gYXdhaXQgdGhpcy5hZGFwdGVyLmNyZWF0ZUFsbChcbiAgICAgIHRoaXMudGFibGVOYW1lLFxuICAgICAgaWRzIGFzIChzdHJpbmcgfCBudW1iZXIpW10sXG4gICAgICByZWNvcmRzLFxuICAgICAgLi4uYXJnc1xuICAgICk7XG4gICAgcmV0dXJuIHJlY29yZHMubWFwKChyLCBpKSA9PlxuICAgICAgdGhpcy5hZGFwdGVyLnJldmVydChyLCB0aGlzLmNsYXNzLCB0aGlzLnBrLCBpZHNbaV0gYXMgc3RyaW5nIHwgbnVtYmVyKVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFByZXBhcmVzIG11bHRpcGxlIG1vZGVscyBmb3IgY3JlYXRpb24uXG4gICAqIEBzdW1tYXJ5IFZhbGlkYXRlcyBtdWx0aXBsZSBtb2RlbHMgYW5kIHByZXBhcmVzIHRoZW0gZm9yIGNyZWF0aW9uIGluIHRoZSBkYXRhYmFzZS5cbiAgICogQHBhcmFtIHtNW119IG1vZGVscyAtIFRoZSBtb2RlbHMgdG8gY3JlYXRlLlxuICAgKiBAcGFyYW0gey4uLmFueVtdfSBhcmdzIC0gQWRkaXRpb25hbCBhcmd1bWVudHMuXG4gICAqIEByZXR1cm4gVGhlIHByZXBhcmVkIG1vZGVscyBhbmQgY29udGV4dCBhcmd1bWVudHMuXG4gICAqIEB0aHJvd3Mge1ZhbGlkYXRpb25FcnJvcn0gSWYgYW55IG1vZGVsIGZhaWxzIHZhbGlkYXRpb24uXG4gICAqL1xuICBwcm90ZWN0ZWQgb3ZlcnJpZGUgYXN5bmMgY3JlYXRlQWxsUHJlZml4KG1vZGVsczogTVtdLCAuLi5hcmdzOiBhbnlbXSkge1xuICAgIGNvbnN0IGNvbnRleHRBcmdzID0gYXdhaXQgQ29udGV4dC5hcmdzKFxuICAgICAgT3BlcmF0aW9uS2V5cy5DUkVBVEUsXG4gICAgICB0aGlzLmNsYXNzLFxuICAgICAgYXJncyxcbiAgICAgIHRoaXMuYWRhcHRlcixcbiAgICAgIHRoaXMuX292ZXJyaWRlcyB8fCB7fVxuICAgICk7XG4gICAgaWYgKCFtb2RlbHMubGVuZ3RoKSByZXR1cm4gW21vZGVscywgLi4uY29udGV4dEFyZ3MuYXJnc107XG4gICAgY29uc3Qgb3B0cyA9IFJlcG9zaXRvcnkuZ2V0U2VxdWVuY2VPcHRpb25zKG1vZGVsc1swXSk7XG4gICAgbGV0IGlkczogKHN0cmluZyB8IG51bWJlciB8IGJpZ2ludCB8IHVuZGVmaW5lZClbXSA9IFtdO1xuICAgIGlmIChvcHRzLnR5cGUpIHtcbiAgICAgIGlmICghb3B0cy5uYW1lKSBvcHRzLm5hbWUgPSBTZXF1ZW5jZS5wayhtb2RlbHNbMF0pO1xuICAgICAgaWRzID0gYXdhaXQgKGF3YWl0IHRoaXMuYWRhcHRlci5TZXF1ZW5jZShvcHRzKSkucmFuZ2UobW9kZWxzLmxlbmd0aCk7XG4gICAgfVxuXG4gICAgbW9kZWxzID0gYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICBtb2RlbHMubWFwKGFzeW5jIChtLCBpKSA9PiB7XG4gICAgICAgIG0gPSBuZXcgdGhpcy5jbGFzcyhtKTtcbiAgICAgICAgbVt0aGlzLnBrXSA9IGlkc1tpXSBhcyBNW2tleW9mIE1dO1xuICAgICAgICBhd2FpdCBlbmZvcmNlREJEZWNvcmF0b3JzKFxuICAgICAgICAgIHRoaXMsXG4gICAgICAgICAgY29udGV4dEFyZ3MuY29udGV4dCxcbiAgICAgICAgICBtLFxuICAgICAgICAgIE9wZXJhdGlvbktleXMuQ1JFQVRFLFxuICAgICAgICAgIE9wZXJhdGlvbktleXMuT05cbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuIG07XG4gICAgICB9KVxuICAgICk7XG4gICAgY29uc3QgZXJyb3JzID0gbW9kZWxzXG4gICAgICAubWFwKChtKSA9PlxuICAgICAgICBtLmhhc0Vycm9ycyhcbiAgICAgICAgICAuLi4oY29udGV4dEFyZ3MuY29udGV4dC5nZXQoXCJpZ25vcmVkVmFsaWRhdGlvblByb3BlcnRpZXNcIikgfHwgW10pXG4gICAgICAgIClcbiAgICAgIClcbiAgICAgIC5yZWR1Y2UoKGFjY3VtOiBzdHJpbmcgfCB1bmRlZmluZWQsIGUsIGkpID0+IHtcbiAgICAgICAgaWYgKGUpXG4gICAgICAgICAgYWNjdW0gPVxuICAgICAgICAgICAgdHlwZW9mIGFjY3VtID09PSBcInN0cmluZ1wiXG4gICAgICAgICAgICAgID8gYWNjdW0gKyBgXFxuIC0gJHtpfTogJHtlLnRvU3RyaW5nKCl9YFxuICAgICAgICAgICAgICA6IGAgLSAke2l9OiAke2UudG9TdHJpbmcoKX1gO1xuICAgICAgICByZXR1cm4gYWNjdW07XG4gICAgICB9LCB1bmRlZmluZWQpO1xuICAgIGlmIChlcnJvcnMpIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoZXJyb3JzKTtcbiAgICByZXR1cm4gW21vZGVscywgLi4uY29udGV4dEFyZ3MuYXJnc107XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFByZXBhcmVzIGZvciByZWFkaW5nIGEgbW9kZWwgYnkgSUQuXG4gICAqIEBzdW1tYXJ5IFByZXBhcmVzIHRoZSBjb250ZXh0IGFuZCBlbmZvcmNlcyBkZWNvcmF0b3JzIGJlZm9yZSByZWFkaW5nIGEgbW9kZWwuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgLSBUaGUgcHJpbWFyeSBrZXkgb2YgdGhlIG1vZGVsIHRvIHJlYWQuXG4gICAqIEBwYXJhbSB7Li4uYW55W119IGFyZ3MgLSBBZGRpdGlvbmFsIGFyZ3VtZW50cy5cbiAgICogQHJldHVybiBUaGUga2V5IGFuZCBjb250ZXh0IGFyZ3VtZW50cy5cbiAgICovXG4gIHByb3RlY3RlZCBvdmVycmlkZSBhc3luYyByZWFkUHJlZml4KGtleTogc3RyaW5nLCAuLi5hcmdzOiBhbnlbXSkge1xuICAgIGNvbnN0IGNvbnRleHRBcmdzID0gYXdhaXQgQ29udGV4dC5hcmdzKFxuICAgICAgT3BlcmF0aW9uS2V5cy5SRUFELFxuICAgICAgdGhpcy5jbGFzcyxcbiAgICAgIGFyZ3MsXG4gICAgICB0aGlzLmFkYXB0ZXIsXG4gICAgICB0aGlzLl9vdmVycmlkZXMgfHwge31cbiAgICApO1xuICAgIGNvbnN0IG1vZGVsOiBNID0gbmV3IHRoaXMuY2xhc3MoKTtcbiAgICBtb2RlbFt0aGlzLnBrXSA9IGtleSBhcyBNW2tleW9mIE1dO1xuICAgIGF3YWl0IGVuZm9yY2VEQkRlY29yYXRvcnMoXG4gICAgICB0aGlzLFxuICAgICAgY29udGV4dEFyZ3MuY29udGV4dCxcbiAgICAgIG1vZGVsLFxuICAgICAgT3BlcmF0aW9uS2V5cy5SRUFELFxuICAgICAgT3BlcmF0aW9uS2V5cy5PTlxuICAgICk7XG4gICAgcmV0dXJuIFtrZXksIC4uLmNvbnRleHRBcmdzLmFyZ3NdO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZWFkcyBhIG1vZGVsIGZyb20gdGhlIGRhdGFiYXNlIGJ5IElELlxuICAgKiBAc3VtbWFyeSBSZXRyaWV2ZXMgYSBtb2RlbCBpbnN0YW5jZSBmcm9tIHRoZSBkYXRhYmFzZSB1c2luZyBpdHMgcHJpbWFyeSBrZXkuXG4gICAqIEBwYXJhbSB7c3RyaW5nfG51bWJlcnxiaWdpbnR9IGlkIC0gVGhlIHByaW1hcnkga2V5IG9mIHRoZSBtb2RlbCB0byByZWFkLlxuICAgKiBAcGFyYW0gey4uLmFueVtdfSBhcmdzIC0gQWRkaXRpb25hbCBhcmd1bWVudHMuXG4gICAqIEByZXR1cm4ge1Byb21pc2U8TT59IFRoZSByZXRyaWV2ZWQgbW9kZWwgaW5zdGFuY2UuXG4gICAqL1xuICBhc3luYyByZWFkKGlkOiBzdHJpbmcgfCBudW1iZXIgfCBiaWdpbnQsIC4uLmFyZ3M6IGFueVtdKTogUHJvbWlzZTxNPiB7XG4gICAgY29uc3QgbSA9IGF3YWl0IHRoaXMuYWRhcHRlci5yZWFkKHRoaXMudGFibGVOYW1lLCBpZCwgLi4uYXJncyk7XG4gICAgcmV0dXJuIHRoaXMuYWRhcHRlci5yZXZlcnQ8TT4obSwgdGhpcy5jbGFzcywgdGhpcy5waywgaWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBQcmVwYXJlcyBmb3IgcmVhZGluZyBtdWx0aXBsZSBtb2RlbHMgYnkgSURzLlxuICAgKiBAc3VtbWFyeSBQcmVwYXJlcyB0aGUgY29udGV4dCBhbmQgZW5mb3JjZXMgZGVjb3JhdG9ycyBiZWZvcmUgcmVhZGluZyBtdWx0aXBsZSBtb2RlbHMuXG4gICAqIEBwYXJhbSB7c3RyaW5nW118bnVtYmVyW119IGtleXMgLSBUaGUgcHJpbWFyeSBrZXlzIG9mIHRoZSBtb2RlbHMgdG8gcmVhZC5cbiAgICogQHBhcmFtIHsuLi5hbnlbXX0gYXJncyAtIEFkZGl0aW9uYWwgYXJndW1lbnRzLlxuICAgKiBAcmV0dXJuIFRoZSBrZXlzIGFuZCBjb250ZXh0IGFyZ3VtZW50cy5cbiAgICovXG4gIHByb3RlY3RlZCBvdmVycmlkZSBhc3luYyByZWFkQWxsUHJlZml4KFxuICAgIGtleXM6IHN0cmluZ1tdIHwgbnVtYmVyW10sXG4gICAgLi4uYXJnczogYW55W11cbiAgKSB7XG4gICAgY29uc3QgY29udGV4dEFyZ3MgPSBhd2FpdCBDb250ZXh0LmFyZ3MoXG4gICAgICBPcGVyYXRpb25LZXlzLlJFQUQsXG4gICAgICB0aGlzLmNsYXNzLFxuICAgICAgYXJncyxcbiAgICAgIHRoaXMuYWRhcHRlcixcbiAgICAgIHRoaXMuX292ZXJyaWRlcyB8fCB7fVxuICAgICk7XG4gICAgYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICBrZXlzLm1hcChhc3luYyAoaykgPT4ge1xuICAgICAgICBjb25zdCBtID0gbmV3IHRoaXMuY2xhc3MoKTtcbiAgICAgICAgbVt0aGlzLnBrXSA9IGsgYXMgTVtrZXlvZiBNXTtcbiAgICAgICAgcmV0dXJuIGVuZm9yY2VEQkRlY29yYXRvcnMoXG4gICAgICAgICAgdGhpcyxcbiAgICAgICAgICBjb250ZXh0QXJncy5jb250ZXh0LFxuICAgICAgICAgIG0sXG4gICAgICAgICAgT3BlcmF0aW9uS2V5cy5SRUFELFxuICAgICAgICAgIE9wZXJhdGlvbktleXMuT05cbiAgICAgICAgKTtcbiAgICAgIH0pXG4gICAgKTtcbiAgICByZXR1cm4gW2tleXMsIC4uLmNvbnRleHRBcmdzLmFyZ3NdO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZWFkcyBtdWx0aXBsZSBtb2RlbHMgZnJvbSB0aGUgZGF0YWJhc2UgYnkgSURzLlxuICAgKiBAc3VtbWFyeSBSZXRyaWV2ZXMgbXVsdGlwbGUgbW9kZWwgaW5zdGFuY2VzIGZyb20gdGhlIGRhdGFiYXNlIHVzaW5nIHRoZWlyIHByaW1hcnkga2V5cy5cbiAgICogQHBhcmFtIHtzdHJpbmdbXXxudW1iZXJbXX0ga2V5cyAtIFRoZSBwcmltYXJ5IGtleXMgb2YgdGhlIG1vZGVscyB0byByZWFkLlxuICAgKiBAcGFyYW0gey4uLmFueVtdfSBhcmdzIC0gQWRkaXRpb25hbCBhcmd1bWVudHMuXG4gICAqIEByZXR1cm4ge1Byb21pc2U8TVtdPn0gVGhlIHJldHJpZXZlZCBtb2RlbCBpbnN0YW5jZXMuXG4gICAqL1xuICBvdmVycmlkZSBhc3luYyByZWFkQWxsKFxuICAgIGtleXM6IHN0cmluZ1tdIHwgbnVtYmVyW10sXG4gICAgLi4uYXJnczogYW55W11cbiAgKTogUHJvbWlzZTxNW10+IHtcbiAgICBjb25zdCByZWNvcmRzID0gYXdhaXQgdGhpcy5hZGFwdGVyLnJlYWRBbGwodGhpcy50YWJsZU5hbWUsIGtleXMsIC4uLmFyZ3MpO1xuICAgIHJldHVybiByZWNvcmRzLm1hcCgociwgaSkgPT5cbiAgICAgIHRoaXMuYWRhcHRlci5yZXZlcnQociwgdGhpcy5jbGFzcywgdGhpcy5waywga2V5c1tpXSlcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBVcGRhdGVzIGEgbW9kZWwgaW4gdGhlIGRhdGFiYXNlLlxuICAgKiBAc3VtbWFyeSBQZXJzaXN0cyBjaGFuZ2VzIHRvIGFuIGV4aXN0aW5nIG1vZGVsIGluc3RhbmNlIGluIHRoZSBkYXRhYmFzZS5cbiAgICogQHBhcmFtIHtNfSBtb2RlbCAtIFRoZSBtb2RlbCB0byB1cGRhdGUuXG4gICAqIEBwYXJhbSB7Li4uYW55W119IGFyZ3MgLSBBZGRpdGlvbmFsIGFyZ3VtZW50cy5cbiAgICogQHJldHVybiB7UHJvbWlzZTxNPn0gVGhlIHVwZGF0ZWQgbW9kZWwgd2l0aCByZWZyZXNoZWQgcHJvcGVydGllcy5cbiAgICovXG4gIGFzeW5jIHVwZGF0ZShtb2RlbDogTSwgLi4uYXJnczogYW55W10pOiBQcm9taXNlPE0+IHtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcHJlZmVyLWNvbnN0XG4gICAgbGV0IHsgcmVjb3JkLCBpZCwgdHJhbnNpZW50IH0gPSB0aGlzLmFkYXB0ZXIucHJlcGFyZShtb2RlbCwgdGhpcy5wayk7XG4gICAgcmVjb3JkID0gYXdhaXQgdGhpcy5hZGFwdGVyLnVwZGF0ZSh0aGlzLnRhYmxlTmFtZSwgaWQsIHJlY29yZCwgLi4uYXJncyk7XG4gICAgcmV0dXJuIHRoaXMuYWRhcHRlci5yZXZlcnQ8TT4ocmVjb3JkLCB0aGlzLmNsYXNzLCB0aGlzLnBrLCBpZCwgdHJhbnNpZW50KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUHJlcGFyZXMgYSBtb2RlbCBmb3IgdXBkYXRlLlxuICAgKiBAc3VtbWFyeSBWYWxpZGF0ZXMgdGhlIG1vZGVsIGFuZCBwcmVwYXJlcyBpdCBmb3IgdXBkYXRlIGluIHRoZSBkYXRhYmFzZS5cbiAgICogQHBhcmFtIHtNfSBtb2RlbCAtIFRoZSBtb2RlbCB0byB1cGRhdGUuXG4gICAqIEBwYXJhbSB7Li4uYW55W119IGFyZ3MgLSBBZGRpdGlvbmFsIGFyZ3VtZW50cy5cbiAgICogQHJldHVybiBUaGUgcHJlcGFyZWQgbW9kZWwgYW5kIGNvbnRleHQgYXJndW1lbnRzLlxuICAgKiBAdGhyb3dzIHtJbnRlcm5hbEVycm9yfSBJZiB0aGUgbW9kZWwgaGFzIG5vIHByaW1hcnkga2V5IHZhbHVlLlxuICAgKiBAdGhyb3dzIHtWYWxpZGF0aW9uRXJyb3J9IElmIHRoZSBtb2RlbCBmYWlscyB2YWxpZGF0aW9uLlxuICAgKi9cbiAgcHJvdGVjdGVkIG92ZXJyaWRlIGFzeW5jIHVwZGF0ZVByZWZpeChcbiAgICBtb2RlbDogTSxcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApOiBQcm9taXNlPFtNLCAuLi5hcmdzOiBhbnlbXV0+IHtcbiAgICBjb25zdCBjb250ZXh0QXJncyA9IGF3YWl0IENvbnRleHQuYXJncyhcbiAgICAgIE9wZXJhdGlvbktleXMuVVBEQVRFLFxuICAgICAgdGhpcy5jbGFzcyxcbiAgICAgIGFyZ3MsXG4gICAgICB0aGlzLmFkYXB0ZXIsXG4gICAgICB0aGlzLl9vdmVycmlkZXMgfHwge31cbiAgICApO1xuICAgIGNvbnN0IHBrID0gbW9kZWxbdGhpcy5wa10gYXMgc3RyaW5nO1xuICAgIGlmICghcGspXG4gICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcbiAgICAgICAgYE5vIHZhbHVlIGZvciB0aGUgSWQgaXMgZGVmaW5lZCB1bmRlciB0aGUgcHJvcGVydHkgJHt0aGlzLnBrIGFzIHN0cmluZ31gXG4gICAgICApO1xuICAgIGNvbnN0IG9sZE1vZGVsID0gYXdhaXQgdGhpcy5yZWFkKHBrLCAuLi5jb250ZXh0QXJncy5hcmdzKTtcbiAgICBtb2RlbCA9IHRoaXMubWVyZ2Uob2xkTW9kZWwsIG1vZGVsKTtcbiAgICBhd2FpdCBlbmZvcmNlREJEZWNvcmF0b3JzKFxuICAgICAgdGhpcyxcbiAgICAgIGNvbnRleHRBcmdzLmNvbnRleHQsXG4gICAgICBtb2RlbCxcbiAgICAgIE9wZXJhdGlvbktleXMuVVBEQVRFLFxuICAgICAgT3BlcmF0aW9uS2V5cy5PTixcbiAgICAgIG9sZE1vZGVsXG4gICAgKTtcblxuICAgIGNvbnN0IGVycm9ycyA9IG1vZGVsLmhhc0Vycm9ycyhcbiAgICAgIG9sZE1vZGVsLFxuICAgICAgLi4uUmVwb3NpdG9yeS5yZWxhdGlvbnModGhpcy5jbGFzcyksXG4gICAgICAuLi4oY29udGV4dEFyZ3MuY29udGV4dC5nZXQoXCJpZ25vcmVkVmFsaWRhdGlvblByb3BlcnRpZXNcIikgfHwgW10pXG4gICAgKTtcbiAgICBpZiAoZXJyb3JzKSB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKGVycm9ycy50b1N0cmluZygpKTtcbiAgICBpZiAoUmVwb3NpdG9yeS5nZXRNZXRhZGF0YShvbGRNb2RlbCkpIHtcbiAgICAgIGlmICghUmVwb3NpdG9yeS5nZXRNZXRhZGF0YShtb2RlbCkpXG4gICAgICAgIFJlcG9zaXRvcnkuc2V0TWV0YWRhdGEobW9kZWwsIFJlcG9zaXRvcnkuZ2V0TWV0YWRhdGEob2xkTW9kZWwpKTtcbiAgICB9XG4gICAgcmV0dXJuIFttb2RlbCwgLi4uY29udGV4dEFyZ3MuYXJnc107XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFVwZGF0ZXMgbXVsdGlwbGUgbW9kZWxzIGluIHRoZSBkYXRhYmFzZS5cbiAgICogQHN1bW1hcnkgUGVyc2lzdHMgY2hhbmdlcyB0byBtdWx0aXBsZSBleGlzdGluZyBtb2RlbCBpbnN0YW5jZXMgaW4gdGhlIGRhdGFiYXNlIGluIGEgYmF0Y2ggb3BlcmF0aW9uLlxuICAgKiBAcGFyYW0ge01bXX0gbW9kZWxzIC0gVGhlIG1vZGVscyB0byB1cGRhdGUuXG4gICAqIEBwYXJhbSB7Li4uYW55W119IGFyZ3MgLSBBZGRpdGlvbmFsIGFyZ3VtZW50cy5cbiAgICogQHJldHVybiB7UHJvbWlzZTxNW10+fSBUaGUgdXBkYXRlZCBtb2RlbHMgd2l0aCByZWZyZXNoZWQgcHJvcGVydGllcy5cbiAgICovXG4gIG92ZXJyaWRlIGFzeW5jIHVwZGF0ZUFsbChtb2RlbHM6IE1bXSwgLi4uYXJnczogYW55W10pOiBQcm9taXNlPE1bXT4ge1xuICAgIGNvbnN0IHJlY29yZHMgPSBtb2RlbHMubWFwKChtKSA9PiB0aGlzLmFkYXB0ZXIucHJlcGFyZShtLCB0aGlzLnBrKSk7XG4gICAgY29uc3QgdXBkYXRlZCA9IGF3YWl0IHRoaXMuYWRhcHRlci51cGRhdGVBbGwoXG4gICAgICB0aGlzLnRhYmxlTmFtZSxcbiAgICAgIHJlY29yZHMubWFwKChyKSA9PiByLmlkKSxcbiAgICAgIHJlY29yZHMubWFwKChyKSA9PiByLnJlY29yZCksXG4gICAgICAuLi5hcmdzXG4gICAgKTtcbiAgICByZXR1cm4gdXBkYXRlZC5tYXAoKHUsIGkpID0+XG4gICAgICB0aGlzLmFkYXB0ZXIucmV2ZXJ0KHUsIHRoaXMuY2xhc3MsIHRoaXMucGssIHJlY29yZHNbaV0uaWQpXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUHJlcGFyZXMgbXVsdGlwbGUgbW9kZWxzIGZvciB1cGRhdGUuXG4gICAqIEBzdW1tYXJ5IFZhbGlkYXRlcyBtdWx0aXBsZSBtb2RlbHMgYW5kIHByZXBhcmVzIHRoZW0gZm9yIHVwZGF0ZSBpbiB0aGUgZGF0YWJhc2UuXG4gICAqIEBwYXJhbSB7TVtdfSBtb2RlbHMgLSBUaGUgbW9kZWxzIHRvIHVwZGF0ZS5cbiAgICogQHBhcmFtIHsuLi5hbnlbXX0gYXJncyAtIEFkZGl0aW9uYWwgYXJndW1lbnRzLlxuICAgKiBAcmV0dXJuIHtQcm9taXNlPGFueVtdPn0gVGhlIHByZXBhcmVkIG1vZGVscyBhbmQgY29udGV4dCBhcmd1bWVudHMuXG4gICAqIEB0aHJvd3Mge0ludGVybmFsRXJyb3J9IElmIGFueSBtb2RlbCBoYXMgbm8gcHJpbWFyeSBrZXkgdmFsdWUuXG4gICAqIEB0aHJvd3Mge1ZhbGlkYXRpb25FcnJvcn0gSWYgYW55IG1vZGVsIGZhaWxzIHZhbGlkYXRpb24uXG4gICAqL1xuICBwcm90ZWN0ZWQgb3ZlcnJpZGUgYXN5bmMgdXBkYXRlQWxsUHJlZml4KFxuICAgIG1vZGVsczogTVtdLFxuICAgIC4uLmFyZ3M6IGFueVtdXG4gICk6IFByb21pc2U8YW55W10+IHtcbiAgICBjb25zdCBjb250ZXh0QXJncyA9IGF3YWl0IENvbnRleHQuYXJncyhcbiAgICAgIE9wZXJhdGlvbktleXMuVVBEQVRFLFxuICAgICAgdGhpcy5jbGFzcyxcbiAgICAgIGFyZ3MsXG4gICAgICB0aGlzLmFkYXB0ZXIsXG4gICAgICB0aGlzLl9vdmVycmlkZXMgfHwge31cbiAgICApO1xuICAgIGNvbnN0IGlkcyA9IG1vZGVscy5tYXAoKG0pID0+IHtcbiAgICAgIGNvbnN0IGlkID0gbVt0aGlzLnBrXSBhcyBzdHJpbmc7XG4gICAgICBpZiAoIWlkKSB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcIm1pc3NpbmcgaWQgb24gdXBkYXRlIG9wZXJhdGlvblwiKTtcbiAgICAgIHJldHVybiBpZDtcbiAgICB9KTtcbiAgICBjb25zdCBvbGRNb2RlbHMgPSBhd2FpdCB0aGlzLnJlYWRBbGwoaWRzLCAuLi5jb250ZXh0QXJncy5hcmdzKTtcbiAgICBtb2RlbHMgPSBtb2RlbHMubWFwKChtLCBpKSA9PiB7XG4gICAgICBtID0gdGhpcy5tZXJnZShvbGRNb2RlbHNbaV0sIG0pO1xuICAgICAgaWYgKFJlcG9zaXRvcnkuZ2V0TWV0YWRhdGEob2xkTW9kZWxzW2ldKSkge1xuICAgICAgICBpZiAoIVJlcG9zaXRvcnkuZ2V0TWV0YWRhdGEobSkpXG4gICAgICAgICAgUmVwb3NpdG9yeS5zZXRNZXRhZGF0YShtLCBSZXBvc2l0b3J5LmdldE1ldGFkYXRhKG9sZE1vZGVsc1tpXSkpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG07XG4gICAgfSk7XG4gICAgYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICBtb2RlbHMubWFwKChtLCBpKSA9PlxuICAgICAgICBlbmZvcmNlREJEZWNvcmF0b3JzKFxuICAgICAgICAgIHRoaXMsXG4gICAgICAgICAgY29udGV4dEFyZ3MuY29udGV4dCxcbiAgICAgICAgICBtLFxuICAgICAgICAgIE9wZXJhdGlvbktleXMuVVBEQVRFLFxuICAgICAgICAgIE9wZXJhdGlvbktleXMuT04sXG4gICAgICAgICAgb2xkTW9kZWxzW2ldXG4gICAgICAgIClcbiAgICAgIClcbiAgICApO1xuXG4gICAgY29uc3QgZXJyb3JzID0gbW9kZWxzXG4gICAgICAubWFwKChtLCBpKSA9PlxuICAgICAgICBtLmhhc0Vycm9ycyhcbiAgICAgICAgICBvbGRNb2RlbHNbaV0sXG4gICAgICAgICAgbSxcbiAgICAgICAgICAuLi4oY29udGV4dEFyZ3MuY29udGV4dC5nZXQoXCJpZ25vcmVkVmFsaWRhdGlvblByb3BlcnRpZXNcIikgfHwgW10pXG4gICAgICAgIClcbiAgICAgIClcbiAgICAgIC5yZWR1Y2UoKGFjY3VtOiBzdHJpbmcgfCB1bmRlZmluZWQsIGUsIGkpID0+IHtcbiAgICAgICAgaWYgKGUpXG4gICAgICAgICAgYWNjdW0gPVxuICAgICAgICAgICAgdHlwZW9mIGFjY3VtID09PSBcInN0cmluZ1wiXG4gICAgICAgICAgICAgID8gYWNjdW0gKyBgXFxuIC0gJHtpfTogJHtlLnRvU3RyaW5nKCl9YFxuICAgICAgICAgICAgICA6IGAgLSAke2l9OiAke2UudG9TdHJpbmcoKX1gO1xuICAgICAgICByZXR1cm4gYWNjdW07XG4gICAgICB9LCB1bmRlZmluZWQpO1xuICAgIGlmIChlcnJvcnMpIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoZXJyb3JzKTtcblxuICAgIG1vZGVscy5mb3JFYWNoKChtLCBpKSA9PiB7XG4gICAgICBpZiAoUmVwb3NpdG9yeS5nZXRNZXRhZGF0YShvbGRNb2RlbHNbaV0pKSB7XG4gICAgICAgIGlmICghUmVwb3NpdG9yeS5nZXRNZXRhZGF0YShtKSlcbiAgICAgICAgICBSZXBvc2l0b3J5LnNldE1ldGFkYXRhKG0sIFJlcG9zaXRvcnkuZ2V0TWV0YWRhdGEob2xkTW9kZWxzW2ldKSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIFttb2RlbHMsIC4uLmNvbnRleHRBcmdzLmFyZ3NdO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBQcmVwYXJlcyBmb3IgZGVsZXRpbmcgYSBtb2RlbCBieSBJRC5cbiAgICogQHN1bW1hcnkgUHJlcGFyZXMgdGhlIGNvbnRleHQgYW5kIGVuZm9yY2VzIGRlY29yYXRvcnMgYmVmb3JlIGRlbGV0aW5nIGEgbW9kZWwuXG4gICAqIEBwYXJhbSB7YW55fSBrZXkgLSBUaGUgcHJpbWFyeSBrZXkgb2YgdGhlIG1vZGVsIHRvIGRlbGV0ZS5cbiAgICogQHBhcmFtIHsuLi5hbnlbXX0gYXJncyAtIEFkZGl0aW9uYWwgYXJndW1lbnRzLlxuICAgKiBAcmV0dXJuIFRoZSBrZXkgYW5kIGNvbnRleHQgYXJndW1lbnRzLlxuICAgKi9cbiAgcHJvdGVjdGVkIG92ZXJyaWRlIGFzeW5jIGRlbGV0ZVByZWZpeChrZXk6IGFueSwgLi4uYXJnczogYW55W10pIHtcbiAgICBjb25zdCBjb250ZXh0QXJncyA9IGF3YWl0IENvbnRleHQuYXJncyhcbiAgICAgIE9wZXJhdGlvbktleXMuREVMRVRFLFxuICAgICAgdGhpcy5jbGFzcyxcbiAgICAgIGFyZ3MsXG4gICAgICB0aGlzLmFkYXB0ZXIsXG4gICAgICB0aGlzLl9vdmVycmlkZXMgfHwge31cbiAgICApO1xuICAgIGNvbnN0IG1vZGVsID0gYXdhaXQgdGhpcy5yZWFkKGtleSwgLi4uY29udGV4dEFyZ3MuYXJncyk7XG4gICAgYXdhaXQgZW5mb3JjZURCRGVjb3JhdG9ycyhcbiAgICAgIHRoaXMsXG4gICAgICBjb250ZXh0QXJncy5jb250ZXh0LFxuICAgICAgbW9kZWwsXG4gICAgICBPcGVyYXRpb25LZXlzLkRFTEVURSxcbiAgICAgIE9wZXJhdGlvbktleXMuT05cbiAgICApO1xuICAgIHJldHVybiBba2V5LCAuLi5jb250ZXh0QXJncy5hcmdzXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gRGVsZXRlcyBhIG1vZGVsIGZyb20gdGhlIGRhdGFiYXNlIGJ5IElELlxuICAgKiBAc3VtbWFyeSBSZW1vdmVzIGEgbW9kZWwgaW5zdGFuY2UgZnJvbSB0aGUgZGF0YWJhc2UgdXNpbmcgaXRzIHByaW1hcnkga2V5LlxuICAgKiBAcGFyYW0ge3N0cmluZ3xudW1iZXJ8YmlnaW50fSBpZCAtIFRoZSBwcmltYXJ5IGtleSBvZiB0aGUgbW9kZWwgdG8gZGVsZXRlLlxuICAgKiBAcGFyYW0gey4uLmFueVtdfSBhcmdzIC0gQWRkaXRpb25hbCBhcmd1bWVudHMuXG4gICAqIEByZXR1cm4ge1Byb21pc2U8TT59IFRoZSBkZWxldGVkIG1vZGVsIGluc3RhbmNlLlxuICAgKi9cbiAgYXN5bmMgZGVsZXRlKGlkOiBzdHJpbmcgfCBudW1iZXIgfCBiaWdpbnQsIC4uLmFyZ3M6IGFueVtdKTogUHJvbWlzZTxNPiB7XG4gICAgY29uc3QgbSA9IGF3YWl0IHRoaXMuYWRhcHRlci5kZWxldGUodGhpcy50YWJsZU5hbWUsIGlkLCAuLi5hcmdzKTtcbiAgICByZXR1cm4gdGhpcy5hZGFwdGVyLnJldmVydDxNPihtLCB0aGlzLmNsYXNzLCB0aGlzLnBrLCBpZCk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFByZXBhcmVzIGZvciBkZWxldGluZyBtdWx0aXBsZSBtb2RlbHMgYnkgSURzLlxuICAgKiBAc3VtbWFyeSBQcmVwYXJlcyB0aGUgY29udGV4dCBhbmQgZW5mb3JjZXMgZGVjb3JhdG9ycyBiZWZvcmUgZGVsZXRpbmcgbXVsdGlwbGUgbW9kZWxzLlxuICAgKiBAcGFyYW0ge3N0cmluZ1tdfG51bWJlcltdfSBrZXlzIC0gVGhlIHByaW1hcnkga2V5cyBvZiB0aGUgbW9kZWxzIHRvIGRlbGV0ZS5cbiAgICogQHBhcmFtIHsuLi5hbnlbXX0gYXJncyAtIEFkZGl0aW9uYWwgYXJndW1lbnRzLlxuICAgKiBAcmV0dXJuIFRoZSBrZXlzIGFuZCBjb250ZXh0IGFyZ3VtZW50cy5cbiAgICovXG4gIHByb3RlY3RlZCBvdmVycmlkZSBhc3luYyBkZWxldGVBbGxQcmVmaXgoXG4gICAga2V5czogc3RyaW5nW10gfCBudW1iZXJbXSxcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApIHtcbiAgICBjb25zdCBjb250ZXh0QXJncyA9IGF3YWl0IENvbnRleHQuYXJncyhcbiAgICAgIE9wZXJhdGlvbktleXMuREVMRVRFLFxuICAgICAgdGhpcy5jbGFzcyxcbiAgICAgIGFyZ3MsXG4gICAgICB0aGlzLmFkYXB0ZXIsXG4gICAgICB0aGlzLl9vdmVycmlkZXMgfHwge31cbiAgICApO1xuICAgIGNvbnN0IG1vZGVscyA9IGF3YWl0IHRoaXMucmVhZEFsbChrZXlzLCAuLi5jb250ZXh0QXJncy5hcmdzKTtcbiAgICBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIG1vZGVscy5tYXAoYXN5bmMgKG0pID0+IHtcbiAgICAgICAgcmV0dXJuIGVuZm9yY2VEQkRlY29yYXRvcnMoXG4gICAgICAgICAgdGhpcyxcbiAgICAgICAgICBjb250ZXh0QXJncy5jb250ZXh0LFxuICAgICAgICAgIG0sXG4gICAgICAgICAgT3BlcmF0aW9uS2V5cy5ERUxFVEUsXG4gICAgICAgICAgT3BlcmF0aW9uS2V5cy5PTlxuICAgICAgICApO1xuICAgICAgfSlcbiAgICApO1xuICAgIHJldHVybiBba2V5cywgLi4uY29udGV4dEFyZ3MuYXJnc107XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIERlbGV0ZXMgbXVsdGlwbGUgbW9kZWxzIGZyb20gdGhlIGRhdGFiYXNlIGJ5IElEcy5cbiAgICogQHN1bW1hcnkgUmVtb3ZlcyBtdWx0aXBsZSBtb2RlbCBpbnN0YW5jZXMgZnJvbSB0aGUgZGF0YWJhc2UgdXNpbmcgdGhlaXIgcHJpbWFyeSBrZXlzLlxuICAgKiBAcGFyYW0ge3N0cmluZ1tdfG51bWJlcltdfSBrZXlzIC0gVGhlIHByaW1hcnkga2V5cyBvZiB0aGUgbW9kZWxzIHRvIGRlbGV0ZS5cbiAgICogQHBhcmFtIHsuLi5hbnlbXX0gYXJncyAtIEFkZGl0aW9uYWwgYXJndW1lbnRzLlxuICAgKiBAcmV0dXJuIHtQcm9taXNlPE1bXT59IFRoZSBkZWxldGVkIG1vZGVsIGluc3RhbmNlcy5cbiAgICovXG4gIG92ZXJyaWRlIGFzeW5jIGRlbGV0ZUFsbChcbiAgICBrZXlzOiBzdHJpbmdbXSB8IG51bWJlcltdLFxuICAgIC4uLmFyZ3M6IGFueVtdXG4gICk6IFByb21pc2U8TVtdPiB7XG4gICAgY29uc3QgcmVzdWx0cyA9IGF3YWl0IHRoaXMuYWRhcHRlci5kZWxldGVBbGwodGhpcy50YWJsZU5hbWUsIGtleXMsIC4uLmFyZ3MpO1xuICAgIHJldHVybiByZXN1bHRzLm1hcCgociwgaSkgPT5cbiAgICAgIHRoaXMuYWRhcHRlci5yZXZlcnQociwgdGhpcy5jbGFzcywgdGhpcy5waywga2V5c1tpXSlcbiAgICApO1xuICB9XG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ3JlYXRlcyBhIHNlbGVjdCBxdWVyeSB3aXRob3V0IHNwZWNpZnlpbmcgZmllbGRzLlxuICAgKiBAc3VtbWFyeSBTdGFydHMgYnVpbGRpbmcgYSBxdWVyeSB0aGF0IHdpbGwgcmV0dXJuIGFsbCBmaWVsZHMgb2YgdGhlIG1vZGVsLlxuICAgKiBAdGVtcGxhdGUgUyAtIFRoZSBhcnJheSB0eXBlIG9mIHNlbGVjdCBzZWxlY3RvcnMuXG4gICAqIEByZXR1cm4gQSBxdWVyeSBidWlsZGVyIGZvciB0aGUgbW9kZWwuXG4gICAqL1xuICBzZWxlY3Q8XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICAgIFMgZXh0ZW5kcyByZWFkb25seSBTZWxlY3RTZWxlY3RvcjxNPltdLFxuICA+KCk6IFdoZXJlT3B0aW9uPE0sIE1bXT47XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDcmVhdGVzIGEgc2VsZWN0IHF1ZXJ5IHdpdGggc3BlY2lmaWMgZmllbGRzLlxuICAgKiBAc3VtbWFyeSBTdGFydHMgYnVpbGRpbmcgYSBxdWVyeSB0aGF0IHdpbGwgcmV0dXJuIG9ubHkgdGhlIHNwZWNpZmllZCBmaWVsZHMgb2YgdGhlIG1vZGVsLlxuICAgKiBAdGVtcGxhdGUgUyAtIFRoZSBhcnJheSB0eXBlIG9mIHNlbGVjdCBzZWxlY3RvcnMuXG4gICAqIEBwYXJhbSBzZWxlY3RvciAtIFRoZSBmaWVsZHMgdG8gc2VsZWN0LlxuICAgKiBAcmV0dXJuIEEgcXVlcnkgYnVpbGRlciBmb3IgdGhlIHNlbGVjdGVkIGZpZWxkcy5cbiAgICovXG4gIHNlbGVjdDxTIGV4dGVuZHMgcmVhZG9ubHkgU2VsZWN0U2VsZWN0b3I8TT5bXT4oXG4gICAgc2VsZWN0b3I6IHJlYWRvbmx5IFsuLi5TXVxuICApOiBXaGVyZU9wdGlvbjxNLCBQaWNrPE0sIFNbbnVtYmVyXT5bXT47XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgc2VsZWN0IG1ldGhvZC5cbiAgICogQHN1bW1hcnkgQ3JlYXRlcyBhIHF1ZXJ5IGJ1aWxkZXIgZm9yIHRoZSBtb2RlbCB3aXRoIG9wdGlvbmFsIGZpZWxkIHNlbGVjdGlvbi5cbiAgICogQHRlbXBsYXRlIFMgLSBUaGUgYXJyYXkgdHlwZSBvZiBzZWxlY3Qgc2VsZWN0b3JzLlxuICAgKiBAcGFyYW0gW3NlbGVjdG9yXSAtIE9wdGlvbmFsIGZpZWxkcyB0byBzZWxlY3QuXG4gICAqIEByZXR1cm4gQSBxdWVyeSBidWlsZGVyLlxuICAgKi9cbiAgc2VsZWN0PFMgZXh0ZW5kcyByZWFkb25seSBTZWxlY3RTZWxlY3RvcjxNPltdPihcbiAgICBzZWxlY3Rvcj86IHJlYWRvbmx5IFsuLi5TXVxuICApOiBXaGVyZU9wdGlvbjxNLCBNW10+IHwgV2hlcmVPcHRpb248TSwgUGljazxNLCBTW251bWJlcl0+W10+IHtcbiAgICByZXR1cm4gdGhpcy5hZGFwdGVyXG4gICAgICAuU3RhdGVtZW50PE0+KClcbiAgICAgIC5zZWxlY3Qoc2VsZWN0b3IgYXMgcmVhZG9ubHkgWy4uLlNdKVxuICAgICAgLmZyb20odGhpcy5jbGFzcyk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEV4ZWN1dGVzIGEgcXVlcnkgd2l0aCB0aGUgc3BlY2lmaWVkIGNvbmRpdGlvbnMgYW5kIG9wdGlvbnMuXG4gICAqIEBzdW1tYXJ5IFByb3ZpZGVzIGEgc2ltcGxpZmllZCB3YXkgdG8gcXVlcnkgdGhlIGRhdGFiYXNlIHdpdGggY29tbW9uIHF1ZXJ5IHBhcmFtZXRlcnMuXG4gICAqIEBwYXJhbSB7Q29uZGl0aW9uPE0+fSBjb25kaXRpb24gLSBUaGUgY29uZGl0aW9uIHRvIGZpbHRlciByZWNvcmRzLlxuICAgKiBAcGFyYW0gb3JkZXJCeSAtIFRoZSBmaWVsZCB0byBvcmRlciByZXN1bHRzIGJ5LlxuICAgKiBAcGFyYW0ge09yZGVyRGlyZWN0aW9ufSBbb3JkZXI9T3JkZXJEaXJlY3Rpb24uQVNDXSAtIFRoZSBzb3J0IGRpcmVjdGlvbi5cbiAgICogQHBhcmFtIHtudW1iZXJ9IFtsaW1pdF0gLSBPcHRpb25hbCBtYXhpbXVtIG51bWJlciBvZiByZXN1bHRzIHRvIHJldHVybi5cbiAgICogQHBhcmFtIHtudW1iZXJ9IFtza2lwXSAtIE9wdGlvbmFsIG51bWJlciBvZiByZXN1bHRzIHRvIHNraXAuXG4gICAqIEByZXR1cm4ge1Byb21pc2U8TVtdPn0gVGhlIHF1ZXJ5IHJlc3VsdHMgYXMgbW9kZWwgaW5zdGFuY2VzLlxuICAgKi9cbiAgYXN5bmMgcXVlcnkoXG4gICAgY29uZGl0aW9uOiBDb25kaXRpb248TT4sXG4gICAgb3JkZXJCeToga2V5b2YgTSxcbiAgICBvcmRlcjogT3JkZXJEaXJlY3Rpb24gPSBPcmRlckRpcmVjdGlvbi5BU0MsXG4gICAgbGltaXQ/OiBudW1iZXIsXG4gICAgc2tpcD86IG51bWJlclxuICApOiBQcm9taXNlPE1bXT4ge1xuICAgIGNvbnN0IHNvcnQ6IE9yZGVyQnlTZWxlY3RvcjxNPiA9IFtvcmRlckJ5LCBvcmRlciBhcyBPcmRlckRpcmVjdGlvbl07XG4gICAgY29uc3QgcXVlcnkgPSB0aGlzLnNlbGVjdCgpLndoZXJlKGNvbmRpdGlvbikub3JkZXJCeShzb3J0KTtcbiAgICBpZiAobGltaXQpIHF1ZXJ5LmxpbWl0KGxpbWl0KTtcbiAgICBpZiAoc2tpcCkgcXVlcnkub2Zmc2V0KHNraXApO1xuICAgIHJldHVybiBxdWVyeS5leGVjdXRlKCk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJlZ2lzdGVycyBhbiBvYnNlcnZlciBmb3IgdGhpcyByZXBvc2l0b3J5LlxuICAgKiBAc3VtbWFyeSBBZGRzIGFuIG9ic2VydmVyIHRoYXQgd2lsbCBiZSBub3RpZmllZCBvZiBjaGFuZ2VzIHRvIG1vZGVscyBpbiB0aGlzIHJlcG9zaXRvcnkuXG4gICAqIEBwYXJhbSB7T2JzZXJ2ZXJ9IG9ic2VydmVyIC0gVGhlIG9ic2VydmVyIHRvIHJlZ2lzdGVyLlxuICAgKiBAcGFyYW0ge09ic2VydmVyRmlsdGVyfSBbZmlsdGVyXSAtIE9wdGlvbmFsIGZpbHRlciB0byBsaW1pdCB3aGljaCBldmVudHMgdGhlIG9ic2VydmVyIHJlY2VpdmVzLlxuICAgKiBAcmV0dXJuIHt2b2lkfVxuICAgKiBAc2VlIHtPYnNlcnZhYmxlI29ic2VydmV9XG4gICAqL1xuICBAZmluYWwoKVxuICBvYnNlcnZlKG9ic2VydmVyOiBPYnNlcnZlciwgZmlsdGVyPzogT2JzZXJ2ZXJGaWx0ZXIpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMub2JzZXJ2ZXJIYW5kbGVyKVxuICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsIFwib2JzZXJ2ZXJIYW5kbGVyXCIsIHtcbiAgICAgICAgdmFsdWU6IHRoaXMuT2JzZXJ2ZXJIYW5kbGVyKCksXG4gICAgICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICAgIH0pO1xuICAgIGNvbnN0IGxvZyA9IHRoaXMubG9nLmZvcih0aGlzLm9ic2VydmUpO1xuICAgIGNvbnN0IHRhYmxlTmFtZSA9IFJlcG9zaXRvcnkudGFibGUodGhpcy5jbGFzcyk7XG4gICAgdGhpcy5hZGFwdGVyLm9ic2VydmUodGhpcywgKHRhYmxlOiBzdHJpbmcpID0+IHRhYmxlTmFtZSA9PT0gdGFibGUpO1xuICAgIGxvZy52ZXJib3NlKFxuICAgICAgYG5vdyBvYnNlcnZpbmcgJHt0aGlzLmFkYXB0ZXJ9IGZpbHRlcmluZyBvbiB0YWJsZSA9PT0gJHt0YWJsZU5hbWV9YFxuICAgICk7XG4gICAgdGhpcy5vYnNlcnZlckhhbmRsZXIhLm9ic2VydmUob2JzZXJ2ZXIsIGZpbHRlcik7XG4gICAgbG9nLnZlcmJvc2UoYFJlZ2lzdGVyZWQgbmV3IG9ic2VydmVyICR7b2JzZXJ2ZXIudG9TdHJpbmcoKX1gKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gVW5yZWdpc3RlcnMgYW4gb2JzZXJ2ZXIgZnJvbSB0aGlzIHJlcG9zaXRvcnkuXG4gICAqIEBzdW1tYXJ5IFJlbW92ZXMgYW4gb2JzZXJ2ZXIgc28gaXQgd2lsbCBubyBsb25nZXIgcmVjZWl2ZSBub3RpZmljYXRpb25zIG9mIGNoYW5nZXMuXG4gICAqIEBwYXJhbSB7T2JzZXJ2ZXJ9IG9ic2VydmVyIC0gVGhlIG9ic2VydmVyIHRvIHVucmVnaXN0ZXIuXG4gICAqIEByZXR1cm4ge3ZvaWR9XG4gICAqIEB0aHJvd3Mge0ludGVybmFsRXJyb3J9IElmIHRoZSBvYnNlcnZlciBoYW5kbGVyIGlzIG5vdCBpbml0aWFsaXplZC5cbiAgICogQHNlZSB7T2JzZXJ2YWJsZSN1bk9ic2VydmV9XG4gICAqL1xuICBAZmluYWwoKVxuICB1bk9ic2VydmUob2JzZXJ2ZXI6IE9ic2VydmVyKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLm9ic2VydmVySGFuZGxlcilcbiAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFxuICAgICAgICBcIk9ic2VydmVySGFuZGxlciBub3QgaW5pdGlhbGl6ZWQuIERpZCB5b3UgcmVnaXN0ZXIgYW55IG9ic2VydmFibGVzP1wiXG4gICAgICApO1xuICAgIHRoaXMub2JzZXJ2ZXJIYW5kbGVyLnVuT2JzZXJ2ZShvYnNlcnZlcik7XG4gICAgdGhpcy5sb2dcbiAgICAgIC5mb3IodGhpcy51bk9ic2VydmUpXG4gICAgICAudmVyYm9zZShgT2JzZXJ2ZXIgJHtvYnNlcnZlci50b1N0cmluZygpfSByZW1vdmVkYCk7XG4gICAgaWYgKCF0aGlzLm9ic2VydmVySGFuZGxlci5jb3VudCgpKSB7XG4gICAgICB0aGlzLmxvZy52ZXJib3NlKFxuICAgICAgICBgTm8gbW9yZSBvYnNlcnZlcnMgcmVnaXN0ZXJlZCBmb3IgJHt0aGlzLmFkYXB0ZXJ9LCB1bnN1YnNjcmliaW5nYFxuICAgICAgKTtcbiAgICAgIHRoaXMuYWRhcHRlci51bk9ic2VydmUodGhpcyk7XG4gICAgICB0aGlzLmxvZy52ZXJib3NlKGBObyBsb25nZXIgb2JzZXJ2aW5nIGFkYXB0ZXIgJHt0aGlzLmFkYXB0ZXIuZmxhdm91cn1gKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIE5vdGlmaWVzIGFsbCBvYnNlcnZlcnMgb2YgYW4gZXZlbnQuXG4gICAqIEBzdW1tYXJ5IFVwZGF0ZXMgYWxsIHJlZ2lzdGVyZWQgb2JzZXJ2ZXJzIHdpdGggaW5mb3JtYXRpb24gYWJvdXQgYSBkYXRhYmFzZSBldmVudC5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHRhYmxlIC0gVGhlIHRhYmxlIG5hbWUgd2hlcmUgdGhlIGV2ZW50IG9jY3VycmVkLlxuICAgKiBAcGFyYW0ge09wZXJhdGlvbktleXN8QnVsa0NydWRPcGVyYXRpb25LZXlzfHN0cmluZ30gZXZlbnQgLSBUaGUgdHlwZSBvZiBldmVudCB0aGF0IG9jY3VycmVkLlxuICAgKiBAcGFyYW0ge0V2ZW50SWRzfSBpZCAtIFRoZSBJRCBvciBJRHMgb2YgdGhlIGFmZmVjdGVkIHJlY29yZHMuXG4gICAqIEBwYXJhbSB7Li4uYW55W119IGFyZ3MgLSBBZGRpdGlvbmFsIGFyZ3VtZW50cy5cbiAgICogQHJldHVybiB7UHJvbWlzZTx2b2lkPn0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiBhbGwgb2JzZXJ2ZXJzIGhhdmUgYmVlbiBub3RpZmllZC5cbiAgICogQHRocm93cyB7SW50ZXJuYWxFcnJvcn0gSWYgdGhlIG9ic2VydmVyIGhhbmRsZXIgaXMgbm90IGluaXRpYWxpemVkLlxuICAgKi9cbiAgYXN5bmMgdXBkYXRlT2JzZXJ2ZXJzKFxuICAgIHRhYmxlOiBzdHJpbmcsXG4gICAgZXZlbnQ6IE9wZXJhdGlvbktleXMgfCBCdWxrQ3J1ZE9wZXJhdGlvbktleXMgfCBzdHJpbmcsXG4gICAgaWQ6IEV2ZW50SWRzLFxuICAgIC4uLmFyZ3M6IGFueVtdXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICghdGhpcy5vYnNlcnZlckhhbmRsZXIpXG4gICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcbiAgICAgICAgXCJPYnNlcnZlckhhbmRsZXIgbm90IGluaXRpYWxpemVkLiBEaWQgeW91IHJlZ2lzdGVyIGFueSBvYnNlcnZhYmxlcz9cIlxuICAgICAgKTtcbiAgICB0aGlzLmxvZ1xuICAgICAgLmZvcih0aGlzLnVwZGF0ZU9ic2VydmVycylcbiAgICAgIC52ZXJib3NlKFxuICAgICAgICBgVXBkYXRpbmcgJHt0aGlzLm9ic2VydmVySGFuZGxlci5jb3VudCgpfSBvYnNlcnZlcnMgZm9yICR7dGhpc31gXG4gICAgICApO1xuICAgIGF3YWl0IHRoaXMub2JzZXJ2ZXJIYW5kbGVyLnVwZGF0ZU9ic2VydmVycyhcbiAgICAgIHRoaXMubG9nLFxuICAgICAgdGFibGUsXG4gICAgICBldmVudCxcbiAgICAgIEFycmF5LmlzQXJyYXkoaWQpXG4gICAgICAgID8gaWQubWFwKChpKSA9PiBTZXF1ZW5jZS5wYXJzZVZhbHVlKHRoaXMucGtQcm9wcy50eXBlLCBpKSBhcyBzdHJpbmcpXG4gICAgICAgIDogKFNlcXVlbmNlLnBhcnNlVmFsdWUodGhpcy5wa1Byb3BzLnR5cGUsIGlkKSBhcyBzdHJpbmcpLFxuICAgICAgLi4uYXJnc1xuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEFsaWFzIGZvciB1cGRhdGVPYnNlcnZlcnMuXG4gICAqIEBzdW1tYXJ5IE5vdGlmaWVzIGFsbCBvYnNlcnZlcnMgb2YgYW4gZXZlbnQgKGFsaWFzIGZvciB1cGRhdGVPYnNlcnZlcnMpLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdGFibGUgLSBUaGUgdGFibGUgbmFtZSB3aGVyZSB0aGUgZXZlbnQgb2NjdXJyZWQuXG4gICAqIEBwYXJhbSB7T3BlcmF0aW9uS2V5c3xCdWxrQ3J1ZE9wZXJhdGlvbktleXN8c3RyaW5nfSBldmVudCAtIFRoZSB0eXBlIG9mIGV2ZW50IHRoYXQgb2NjdXJyZWQuXG4gICAqIEBwYXJhbSB7RXZlbnRJZHN9IGlkIC0gVGhlIElEIG9yIElEcyBvZiB0aGUgYWZmZWN0ZWQgcmVjb3Jkcy5cbiAgICogQHBhcmFtIHsuLi5hbnlbXX0gYXJncyAtIEFkZGl0aW9uYWwgYXJndW1lbnRzLlxuICAgKiBAcmV0dXJuIHtQcm9taXNlPHZvaWQ+fSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIGFsbCBvYnNlcnZlcnMgaGF2ZSBiZWVuIG5vdGlmaWVkLlxuICAgKi9cbiAgYXN5bmMgcmVmcmVzaChcbiAgICB0YWJsZTogc3RyaW5nLFxuICAgIGV2ZW50OiBPcGVyYXRpb25LZXlzIHwgQnVsa0NydWRPcGVyYXRpb25LZXlzIHwgc3RyaW5nLFxuICAgIGlkOiBFdmVudElkcyxcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApIHtcbiAgICByZXR1cm4gdGhpcy51cGRhdGVPYnNlcnZlcnModGFibGUsIGV2ZW50LCBpZCwgLi4uYXJncyk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENyZWF0ZXMgb3IgcmV0cmlldmVzIGEgcmVwb3NpdG9yeSBmb3IgYSBtb2RlbC5cbiAgICogQHN1bW1hcnkgRmFjdG9yeSBtZXRob2QgdGhhdCByZXR1cm5zIGEgcmVwb3NpdG9yeSBpbnN0YW5jZSBmb3IgdGhlIHNwZWNpZmllZCBtb2RlbC5cbiAgICogQHRlbXBsYXRlIE0gLSBUaGUgbW9kZWwgdHlwZSB0aGF0IGV4dGVuZHMgTW9kZWwuXG4gICAqIEB0ZW1wbGF0ZSBSIC0gVGhlIHJlcG9zaXRvcnkgdHlwZSB0aGF0IGV4dGVuZHMgUmVwbzxNPi5cbiAgICogQHBhcmFtIHtDb25zdHJ1Y3RvcjxNPn0gbW9kZWwgLSBUaGUgbW9kZWwgY29uc3RydWN0b3IuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbZGVmYXVsdEZsYXZvdXJdIC0gT3B0aW9uYWwgZGVmYXVsdCBhZGFwdGVyIGZsYXZvdXIgaWYgbm90IHNwZWNpZmllZCBvbiB0aGUgbW9kZWwuXG4gICAqIEBwYXJhbSB7Li4uYW55W119IFthcmdzXSAtIEFkZGl0aW9uYWwgYXJndW1lbnRzIHRvIHBhc3MgdG8gdGhlIHJlcG9zaXRvcnkgY29uc3RydWN0b3IuXG4gICAqIEByZXR1cm4ge1J9IEEgcmVwb3NpdG9yeSBpbnN0YW5jZSBmb3IgdGhlIG1vZGVsLlxuICAgKiBAdGhyb3dzIHtJbnRlcm5hbEVycm9yfSBJZiBubyBhZGFwdGVyIGlzIHJlZ2lzdGVyZWQgZm9yIHRoZSBmbGF2b3VyLlxuICAgKi9cbiAgc3RhdGljIGZvck1vZGVsPE0gZXh0ZW5kcyBNb2RlbCwgUiBleHRlbmRzIFJlcG88TT4+KFxuICAgIG1vZGVsOiBDb25zdHJ1Y3RvcjxNPixcbiAgICBhbGlhcz86IHN0cmluZyxcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApOiBSIHtcbiAgICBsZXQgcmVwbzogUiB8IENvbnN0cnVjdG9yPFI+IHwgdW5kZWZpbmVkO1xuXG4gICAgY29uc3QgX2FsaWFzOiBzdHJpbmcgfCB1bmRlZmluZWQgPSBhbGlhcyB8fCBSZWZsZWN0LmdldE1ldGFkYXRhKEFkYXB0ZXIua2V5KFBlcnNpc3RlbmNlS2V5cy5BREFQVEVSKSwgbW9kZWwpIDtcbiAgICB0cnkge1xuICAgICAgcmVwbyA9IHRoaXMuZ2V0KG1vZGVsLF9hbGlhcykgYXMgQ29uc3RydWN0b3I8Uj4gfCBSO1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgcmVwbyA9IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBpZiAocmVwbyBpbnN0YW5jZW9mIFJlcG9zaXRvcnkpIHJldHVybiByZXBvIGFzIFI7XG5cbiAgICBjb25zdCBmbGF2b3VyOiBzdHJpbmcgfCB1bmRlZmluZWQgPVxuICAgICAgYWxpYXMgfHxcbiAgICAgIFJlZmxlY3QuZ2V0TWV0YWRhdGEoQWRhcHRlci5rZXkoUGVyc2lzdGVuY2VLZXlzLkFEQVBURVIpLCBtb2RlbCkgfHxcbiAgICAgIChyZXBvICYmXG4gICAgICAgIFJlZmxlY3QuZ2V0TWV0YWRhdGEoQWRhcHRlci5rZXkoUGVyc2lzdGVuY2VLZXlzLkFEQVBURVIpLCByZXBvKSk7XG4gICAgY29uc3QgYWRhcHRlcjogQWRhcHRlcjxhbnksIGFueSwgYW55LCBhbnk+IHwgdW5kZWZpbmVkID0gZmxhdm91clxuICAgICAgPyBBZGFwdGVyLmdldChmbGF2b3VyKVxuICAgICAgOiB1bmRlZmluZWQ7XG5cbiAgICBpZiAoIWFkYXB0ZXIpXG4gICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcbiAgICAgICAgYE5vIHJlZ2lzdGVyZWQgcGVyc2lzdGVuY2UgYWRhcHRlciBmb3VuZCBmbGF2b3VyICR7Zmxhdm91cn1gXG4gICAgICApO1xuXG4gICAgcmVwbyA9IHJlcG8gfHwgKGFkYXB0ZXIucmVwb3NpdG9yeSgpIGFzIENvbnN0cnVjdG9yPFI+KTtcbiAgICByZXR1cm4gbmV3IHJlcG8oYWRhcHRlciwgbW9kZWwsIC4uLmFyZ3MpIGFzIFI7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJldHJpZXZlcyBhIHJlcG9zaXRvcnkgZm9yIGEgbW9kZWwgZnJvbSB0aGUgY2FjaGUuXG4gICAqIEBzdW1tYXJ5IEdldHMgYSByZXBvc2l0b3J5IGNvbnN0cnVjdG9yIG9yIGluc3RhbmNlIGZvciB0aGUgc3BlY2lmaWVkIG1vZGVsIGZyb20gdGhlIGludGVybmFsIGNhY2hlLlxuICAgKiBAdGVtcGxhdGUgTSAtIFRoZSBtb2RlbCB0eXBlIHRoYXQgZXh0ZW5kcyBNb2RlbC5cbiAgICogQHBhcmFtIHtDb25zdHJ1Y3RvcjxNPn0gbW9kZWwgLSBUaGUgbW9kZWwgY29uc3RydWN0b3IuXG4gICAqIEByZXR1cm4ge0NvbnN0cnVjdG9yPFJlcG88TT4+IHwgUmVwbzxNPn0gVGhlIHJlcG9zaXRvcnkgY29uc3RydWN0b3Igb3IgaW5zdGFuY2UuXG4gICAqIEB0aHJvd3Mge0ludGVybmFsRXJyb3J9IElmIG5vIHJlcG9zaXRvcnkgaXMgcmVnaXN0ZXJlZCBmb3IgdGhlIG1vZGVsLlxuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgZ2V0PE0gZXh0ZW5kcyBNb2RlbD4oXG4gICAgbW9kZWw6IENvbnN0cnVjdG9yPE0+LFxuICAgIGFsaWFzID86IHN0cmluZ1xuICApOiBDb25zdHJ1Y3RvcjxSZXBvPE0+PiB8IFJlcG88TT4ge1xuICAgIGxldCBuYW1lID0gUmVwb3NpdG9yeS50YWJsZShtb2RlbCk7XG4gICAgaWYgKGFsaWFzKSB7XG4gICAgICBuYW1lID0gW25hbWUsIGFsaWFzXS5qb2luKERlZmF1bHRTZXBhcmF0b3IpXG4gICAgfVxuICAgIGlmIChuYW1lIGluIHRoaXMuX2NhY2hlKVxuICAgICAgcmV0dXJuIHRoaXMuX2NhY2hlW25hbWVdIGFzIHVua25vd24gYXMgQ29uc3RydWN0b3I8UmVwbzxNPj4gfCBSZXBvPE0+O1xuICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFxuICAgICAgYENvdWxkIG5vdCBmaW5kIHJlcG9zaXRvcnkgcmVnaXN0ZXJlZCB1bmRlciAke25hbWV9YFxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJlZ2lzdGVycyBhIHJlcG9zaXRvcnkgZm9yIGEgbW9kZWwuXG4gICAqIEBzdW1tYXJ5IEFzc29jaWF0ZXMgYSByZXBvc2l0b3J5IGNvbnN0cnVjdG9yIG9yIGluc3RhbmNlIHdpdGggYSBtb2RlbCBpbiB0aGUgaW50ZXJuYWwgY2FjaGUuXG4gICAqIEB0ZW1wbGF0ZSBNIC0gVGhlIG1vZGVsIHR5cGUgdGhhdCBleHRlbmRzIE1vZGVsLlxuICAgKiBAcGFyYW0ge0NvbnN0cnVjdG9yPE0+fSBtb2RlbCAtIFRoZSBtb2RlbCBjb25zdHJ1Y3Rvci5cbiAgICogQHBhcmFtIHtDb25zdHJ1Y3RvcjxSZXBvPE0+PiB8IFJlcG88TT59IHJlcG8gLSBUaGUgcmVwb3NpdG9yeSBjb25zdHJ1Y3RvciBvciBpbnN0YW5jZS5cbiAgICogQHRocm93cyB7SW50ZXJuYWxFcnJvcn0gSWYgYSByZXBvc2l0b3J5IGlzIGFscmVhZHkgcmVnaXN0ZXJlZCBmb3IgdGhlIG1vZGVsLlxuICAgKi9cbiAgc3RhdGljIHJlZ2lzdGVyPE0gZXh0ZW5kcyBNb2RlbD4oXG4gICAgbW9kZWw6IENvbnN0cnVjdG9yPE0+LFxuICAgIHJlcG86IENvbnN0cnVjdG9yPFJlcG88TT4+IHwgUmVwbzxNPixcbiAgICBhbGlhcyA/OiBzdHJpbmdcbiAgKSB7XG4gICAgbGV0IG5hbWUgPSBSZXBvc2l0b3J5LnRhYmxlKG1vZGVsKTtcbiAgICBpZiAoYWxpYXMpIHtcbiAgICAgIG5hbWUgPSBbbmFtZSwgYWxpYXNdLmpvaW4oRGVmYXVsdFNlcGFyYXRvcilcbiAgICB9XG4gICAgaWYgKG5hbWUgaW4gdGhpcy5fY2FjaGUpXG4gICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihgJHtuYW1lfSBhbHJlYWR5IHJlZ2lzdGVyZWQgYXMgYSByZXBvc2l0b3J5YCk7XG4gICAgdGhpcy5fY2FjaGVbbmFtZV0gPSByZXBvIGFzIGFueTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gU2V0cyBtZXRhZGF0YSBvbiBhIG1vZGVsIGluc3RhbmNlLlxuICAgKiBAc3VtbWFyeSBBdHRhY2hlcyBtZXRhZGF0YSB0byBhIG1vZGVsIGluc3RhbmNlIHVzaW5nIGEgbm9uLWVudW1lcmFibGUgcHJvcGVydHkuXG4gICAqIEB0ZW1wbGF0ZSBNIC0gVGhlIG1vZGVsIHR5cGUgdGhhdCBleHRlbmRzIE1vZGVsLlxuICAgKiBAcGFyYW0ge019IG1vZGVsIC0gVGhlIG1vZGVsIGluc3RhbmNlLlxuICAgKiBAcGFyYW0ge2FueX0gbWV0YWRhdGEgLSBUaGUgbWV0YWRhdGEgdG8gYXR0YWNoIHRvIHRoZSBtb2RlbC5cbiAgICovXG4gIHN0YXRpYyBzZXRNZXRhZGF0YTxNIGV4dGVuZHMgTW9kZWw+KG1vZGVsOiBNLCBtZXRhZGF0YTogYW55KSB7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG1vZGVsLCBQZXJzaXN0ZW5jZUtleXMuTUVUQURBVEEsIHtcbiAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgd3JpdGFibGU6IGZhbHNlLFxuICAgICAgdmFsdWU6IG1ldGFkYXRhLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBHZXRzIG1ldGFkYXRhIGZyb20gYSBtb2RlbCBpbnN0YW5jZS5cbiAgICogQHN1bW1hcnkgUmV0cmlldmVzIHByZXZpb3VzbHkgYXR0YWNoZWQgbWV0YWRhdGEgZnJvbSBhIG1vZGVsIGluc3RhbmNlLlxuICAgKiBAdGVtcGxhdGUgTSAtIFRoZSBtb2RlbCB0eXBlIHRoYXQgZXh0ZW5kcyBNb2RlbC5cbiAgICogQHBhcmFtIHtNfSBtb2RlbCAtIFRoZSBtb2RlbCBpbnN0YW5jZS5cbiAgICogQHJldHVybiB7YW55fSBUaGUgbWV0YWRhdGEgb3IgdW5kZWZpbmVkIGlmIG5vdCBmb3VuZC5cbiAgICovXG4gIHN0YXRpYyBnZXRNZXRhZGF0YTxNIGV4dGVuZHMgTW9kZWw+KG1vZGVsOiBNKSB7XG4gICAgY29uc3QgZGVzY3JpcHRvciA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoXG4gICAgICBtb2RlbCxcbiAgICAgIFBlcnNpc3RlbmNlS2V5cy5NRVRBREFUQVxuICAgICk7XG4gICAgcmV0dXJuIGRlc2NyaXB0b3IgPyBkZXNjcmlwdG9yLnZhbHVlIDogdW5kZWZpbmVkO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZW1vdmVzIG1ldGFkYXRhIGZyb20gYSBtb2RlbCBpbnN0YW5jZS5cbiAgICogQHN1bW1hcnkgRGVsZXRlcyB0aGUgbWV0YWRhdGEgcHJvcGVydHkgZnJvbSBhIG1vZGVsIGluc3RhbmNlLlxuICAgKiBAdGVtcGxhdGUgTSAtIFRoZSBtb2RlbCB0eXBlIHRoYXQgZXh0ZW5kcyBNb2RlbC5cbiAgICogQHBhcmFtIHtNfSBtb2RlbCAtIFRoZSBtb2RlbCBpbnN0YW5jZS5cbiAgICovXG4gIHN0YXRpYyByZW1vdmVNZXRhZGF0YTxNIGV4dGVuZHMgTW9kZWw+KG1vZGVsOiBNKSB7XG4gICAgY29uc3QgZGVzY3JpcHRvciA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoXG4gICAgICBtb2RlbCxcbiAgICAgIFBlcnNpc3RlbmNlS2V5cy5NRVRBREFUQVxuICAgICk7XG4gICAgaWYgKGRlc2NyaXB0b3IpIGRlbGV0ZSAobW9kZWwgYXMgYW55KVtQZXJzaXN0ZW5jZUtleXMuTUVUQURBVEFdO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBHZXRzIHNlcXVlbmNlIG9wdGlvbnMgZm9yIGEgbW9kZWwncyBwcmltYXJ5IGtleS5cbiAgICogQHN1bW1hcnkgUmV0cmlldmVzIHRoZSBzZXF1ZW5jZSBjb25maWd1cmF0aW9uIGZvciBhIG1vZGVsJ3MgcHJpbWFyeSBrZXkgZnJvbSBtZXRhZGF0YS5cbiAgICogQHRlbXBsYXRlIE0gLSBUaGUgbW9kZWwgdHlwZSB0aGF0IGV4dGVuZHMgTW9kZWwuXG4gICAqIEBwYXJhbSB7TX0gbW9kZWwgLSBUaGUgbW9kZWwgaW5zdGFuY2UuXG4gICAqIEByZXR1cm4ge1NlcXVlbmNlT3B0aW9uc30gVGhlIHNlcXVlbmNlIG9wdGlvbnMgZm9yIHRoZSBtb2RlbCdzIHByaW1hcnkga2V5LlxuICAgKiBAdGhyb3dzIHtJbnRlcm5hbEVycm9yfSBJZiBubyBzZXF1ZW5jZSBvcHRpb25zIGFyZSBkZWZpbmVkIGZvciB0aGUgbW9kZWwuXG4gICAqL1xuICBzdGF0aWMgZ2V0U2VxdWVuY2VPcHRpb25zPE0gZXh0ZW5kcyBNb2RlbD4obW9kZWw6IE0pIHtcbiAgICBjb25zdCBwayA9IGZpbmRQcmltYXJ5S2V5KG1vZGVsKS5pZDtcbiAgICBjb25zdCBtZXRhZGF0YSA9IFJlZmxlY3QuZ2V0TWV0YWRhdGEoXG4gICAgICBSZXBvc2l0b3J5LmtleShEQktleXMuSUQpLFxuICAgICAgbW9kZWwsXG4gICAgICBwayBhcyBzdHJpbmdcbiAgICApO1xuICAgIGlmICghbWV0YWRhdGEpXG4gICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcbiAgICAgICAgXCJObyBzZXF1ZW5jZSBvcHRpb25zIGRlZmluZWQgZm9yIG1vZGVsLiBkaWQgeW91IHVzZSB0aGUgQHBrIGRlY29yYXRvcj9cIlxuICAgICAgKTtcbiAgICByZXR1cm4gbWV0YWRhdGEgYXMgU2VxdWVuY2VPcHRpb25zO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBHZXRzIGFsbCBpbmRleGVzIGRlZmluZWQgb24gYSBtb2RlbC5cbiAgICogQHN1bW1hcnkgUmV0cmlldmVzIGFsbCBpbmRleCBtZXRhZGF0YSBmcm9tIGEgbW9kZWwncyBwcm9wZXJ0eSBkZWNvcmF0b3JzLlxuICAgKiBAdGVtcGxhdGUgTSAtIFRoZSBtb2RlbCB0eXBlIHRoYXQgZXh0ZW5kcyBNb2RlbC5cbiAgICogQHBhcmFtIHtNIHwgQ29uc3RydWN0b3I8TT59IG1vZGVsIC0gVGhlIG1vZGVsIGluc3RhbmNlIG9yIGNvbnN0cnVjdG9yLlxuICAgKiBAcmV0dXJuIHtSZWNvcmQ8c3RyaW5nLCBSZWNvcmQ8c3RyaW5nLCBJbmRleE1ldGFkYXRhPj59IEEgbmVzdGVkIHJlY29yZCBvZiBwcm9wZXJ0eSBuYW1lcyB0byBpbmRleCBtZXRhZGF0YS5cbiAgICovXG4gIHN0YXRpYyBpbmRleGVzPE0gZXh0ZW5kcyBNb2RlbD4obW9kZWw6IE0gfCBDb25zdHJ1Y3RvcjxNPikge1xuICAgIGNvbnN0IGluZGV4RGVjb3JhdG9ycyA9IFJlZmxlY3Rpb24uZ2V0QWxsUHJvcGVydHlEZWNvcmF0b3JzKFxuICAgICAgbW9kZWwgaW5zdGFuY2VvZiBNb2RlbCA/IG1vZGVsIDogbmV3IG1vZGVsKCksXG4gICAgICBEQktleXMuUkVGTEVDVFxuICAgICk7XG4gICAgcmV0dXJuIE9iamVjdC5lbnRyaWVzKGluZGV4RGVjb3JhdG9ycyB8fCB7fSkucmVkdWNlKFxuICAgICAgKGFjY3VtOiBSZWNvcmQ8c3RyaW5nLCBSZWNvcmQ8c3RyaW5nLCBJbmRleE1ldGFkYXRhPj4sIFtrLCB2YWxdKSA9PiB7XG4gICAgICAgIGNvbnN0IGRlY3MgPSB2YWwuZmlsdGVyKCh2KSA9PiB2LmtleS5zdGFydHNXaXRoKFBlcnNpc3RlbmNlS2V5cy5JTkRFWCkpO1xuICAgICAgICBpZiAoZGVjcyAmJiBkZWNzLmxlbmd0aCkge1xuICAgICAgICAgIGZvciAoY29uc3QgZGVjIG9mIGRlY3MpIHtcbiAgICAgICAgICAgIGNvbnN0IHsga2V5LCBwcm9wcyB9ID0gZGVjO1xuICAgICAgICAgICAgYWNjdW1ba10gPSBhY2N1bVtrXSB8fCB7fTtcbiAgICAgICAgICAgIGFjY3VtW2tdW2tleV0gPSBwcm9wcyBhcyBJbmRleE1ldGFkYXRhO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYWNjdW07XG4gICAgICB9LFxuICAgICAge31cbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBHZXRzIGFsbCByZWxhdGlvbiBwcm9wZXJ0aWVzIGRlZmluZWQgb24gYSBtb2RlbC5cbiAgICogQHN1bW1hcnkgUmV0cmlldmVzIHRoZSBuYW1lcyBvZiBhbGwgcHJvcGVydGllcyBtYXJrZWQgYXMgcmVsYXRpb25zIGluIHRoZSBtb2RlbCBoaWVyYXJjaHkuXG4gICAqIEB0ZW1wbGF0ZSBNIC0gVGhlIG1vZGVsIHR5cGUgdGhhdCBleHRlbmRzIE1vZGVsLlxuICAgKiBAcGFyYW0ge00gfCBDb25zdHJ1Y3RvcjxNPn0gbW9kZWwgLSBUaGUgbW9kZWwgaW5zdGFuY2Ugb3IgY29uc3RydWN0b3IuXG4gICAqIEByZXR1cm4ge3N0cmluZ1tdfSBBbiBhcnJheSBvZiBwcm9wZXJ0eSBuYW1lcyB0aGF0IGFyZSByZWxhdGlvbnMuXG4gICAqL1xuICBzdGF0aWMgcmVsYXRpb25zPE0gZXh0ZW5kcyBNb2RlbD4obW9kZWw6IE0gfCBDb25zdHJ1Y3RvcjxNPik6IHN0cmluZ1tdIHtcbiAgICBjb25zdCByZXN1bHQ6IHN0cmluZ1tdID0gW107XG4gICAgbGV0IHByb3RvdHlwZSA9XG4gICAgICBtb2RlbCBpbnN0YW5jZW9mIE1vZGVsXG4gICAgICAgID8gT2JqZWN0LmdldFByb3RvdHlwZU9mKG1vZGVsKVxuICAgICAgICA6IChtb2RlbCBhcyBhbnkpLnByb3RvdHlwZTtcbiAgICB3aGlsZSAocHJvdG90eXBlICE9IG51bGwpIHtcbiAgICAgIGNvbnN0IHByb3BzOiBzdHJpbmdbXSA9IHByb3RvdHlwZVtQZXJzaXN0ZW5jZUtleXMuUkVMQVRJT05TXTtcbiAgICAgIGlmIChwcm9wcykge1xuICAgICAgICByZXN1bHQucHVzaCguLi5wcm9wcyk7XG4gICAgICB9XG4gICAgICBwcm90b3R5cGUgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YocHJvdG90eXBlKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gR2V0cyB0aGUgdGFibGUgbmFtZSBmb3IgYSBtb2RlbC5cbiAgICogQHN1bW1hcnkgUmV0cmlldmVzIHRoZSBkYXRhYmFzZSB0YWJsZSBuYW1lIGFzc29jaWF0ZWQgd2l0aCBhIG1vZGVsLlxuICAgKiBAdGVtcGxhdGUgTSAtIFRoZSBtb2RlbCB0eXBlIHRoYXQgZXh0ZW5kcyBNb2RlbC5cbiAgICogQHBhcmFtIHtNIHwgQ29uc3RydWN0b3I8TT59IG1vZGVsIC0gVGhlIG1vZGVsIGluc3RhbmNlIG9yIGNvbnN0cnVjdG9yLlxuICAgKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSB0YWJsZSBuYW1lIGZvciB0aGUgbW9kZWwuXG4gICAqL1xuICBzdGF0aWMgdGFibGU8TSBleHRlbmRzIE1vZGVsPihtb2RlbDogTSB8IENvbnN0cnVjdG9yPE0+KTogc3RyaW5nIHtcbiAgICByZXR1cm4gZ2V0VGFibGVOYW1lKG1vZGVsKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gR2V0cyB0aGUgY29sdW1uIG5hbWUgZm9yIGEgbW9kZWwgYXR0cmlidXRlLlxuICAgKiBAc3VtbWFyeSBSZXRyaWV2ZXMgdGhlIGRhdGFiYXNlIGNvbHVtbiBuYW1lIGZvciBhIG1vZGVsIHByb3BlcnR5LlxuICAgKiBAdGVtcGxhdGUgTSAtIFRoZSBtb2RlbCB0eXBlIHRoYXQgZXh0ZW5kcyBNb2RlbC5cbiAgICogQHBhcmFtIHtNfSBtb2RlbCAtIFRoZSBtb2RlbCBpbnN0YW5jZS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGF0dHJpYnV0ZSAtIFRoZSBhdHRyaWJ1dGUvcHJvcGVydHkgbmFtZS5cbiAgICogQHJldHVybiB7c3RyaW5nfSBUaGUgY29sdW1uIG5hbWUgZm9yIHRoZSBhdHRyaWJ1dGUuXG4gICAqL1xuICBzdGF0aWMgY29sdW1uPE0gZXh0ZW5kcyBNb2RlbD4obW9kZWw6IE0sIGF0dHJpYnV0ZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBjb25zdCBtZXRhZGF0YSA9IFJlZmxlY3QuZ2V0TWV0YWRhdGEoXG4gICAgICBBZGFwdGVyLmtleShQZXJzaXN0ZW5jZUtleXMuQ09MVU1OKSxcbiAgICAgIG1vZGVsLFxuICAgICAgYXR0cmlidXRlXG4gICAgKTtcbiAgICByZXR1cm4gbWV0YWRhdGEgPyBtZXRhZGF0YSA6IGF0dHJpYnV0ZTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgaW5qZWN0LCBpbmplY3RhYmxlIH0gZnJvbSBcIkBkZWNhZi10cy9pbmplY3RhYmxlLWRlY29yYXRvcnNcIjtcbmltcG9ydCB7IERCS2V5cywgSVJlcG9zaXRvcnkgfSBmcm9tIFwiQGRlY2FmLXRzL2RiLWRlY29yYXRvcnNcIjtcbmltcG9ydCB7IG1ldGFkYXRhIH0gZnJvbSBcIkBkZWNhZi10cy9yZWZsZWN0aW9uXCI7XG5pbXBvcnQgeyBDb25zdHJ1Y3RvciwgTW9kZWwgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBSZXBvc2l0b3J5IH0gZnJvbSBcIi4vUmVwb3NpdG9yeVwiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBSZXBvc2l0b3J5IGRlY29yYXRvciBmb3IgbW9kZWwgY2xhc3Nlcy5cbiAqIEBzdW1tYXJ5IENyZWF0ZXMgYW5kIHJlZ2lzdGVycyBhIHJlcG9zaXRvcnkgZm9yIGEgbW9kZWwgY2xhc3MuIENhbiBiZSB1c2VkIGFzIGJvdGggYSBwcm9wZXJ0eSBkZWNvcmF0b3IgYW5kIGEgY2xhc3MgZGVjb3JhdG9yLlxuICogQHRlbXBsYXRlIFQgLSBUaGUgbW9kZWwgdHlwZSB0aGF0IGV4dGVuZHMgTW9kZWwuXG4gKiBAcGFyYW0ge0NvbnN0cnVjdG9yPFQ+fSBtb2RlbCAtIFRoZSBjb25zdHJ1Y3RvciBvZiB0aGUgbW9kZWwgY2xhc3MuXG4gKiBAcGFyYW0ge3N0cmluZ30gW25hbWVPdmVycmlkZV0gLSBPcHRpb25hbCBuYW1lIG92ZXJyaWRlIGZvciB0aGUgcmVwb3NpdG9yeS5cbiAqIEByZXR1cm4ge2FueX0gLSBUaGUgZGVjb3JhdG9yIGZ1bmN0aW9uLlxuICogQGZ1bmN0aW9uIHJlcG9zaXRvcnlcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgQyBhcyBDbGllbnQgQ29kZVxuICogICBwYXJ0aWNpcGFudCBEIGFzIERlY29yYXRvclxuICogICBwYXJ0aWNpcGFudCBSIGFzIFJlcG9zaXRvcnlcbiAqICAgcGFydGljaXBhbnQgTSBhcyBNZXRhZGF0YVxuICpcbiAqICAgQy0+PkQ6IEFwcGx5IEByZXBvc2l0b3J5KE1vZGVsKVxuICogICBhbHQgUHJvcGVydHkgRGVjb3JhdG9yXG4gKiAgICAgRC0+PkQ6IENoZWNrIGlmIHByb3BlcnR5S2V5IGV4aXN0c1xuICogICAgIEQtPj4rQzogUmV0dXJuIGluamVjdChuYW1lKSBkZWNvcmF0b3JcbiAqICAgZWxzZSBDbGFzcyBEZWNvcmF0b3JcbiAqICAgICBELT4+TTogU2V0IHJlcG9zaXRvcnkgbWV0YWRhdGEgb24gbW9kZWxcbiAqICAgICBELT4+UjogUmVnaXN0ZXIgbW9kZWwgd2l0aCBSZXBvc2l0b3J5XG4gKiAgICAgRC0+PitDOiBSZXR1cm4gaW5qZWN0YWJsZSBkZWNvcmF0b3Igd2l0aCBjb25maWdcbiAqICAgICBDLT4+QzogRGVmaW5lIERCS2V5cy5DTEFTUyBwcm9wZXJ0eVxuICogICBlbmRcbiAqIEBjYXRlZ29yeSBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXBvc2l0b3J5PFQgZXh0ZW5kcyBNb2RlbD4oXG4gIG1vZGVsOiBDb25zdHJ1Y3RvcjxUPixcbiAgbmFtZU92ZXJyaWRlPzogc3RyaW5nXG4pOiBhbnkge1xuICByZXR1cm4gKChvcmlnaW5hbDogYW55LCBwcm9wZXJ0eUtleT86IGFueSkgPT4ge1xuICAgIGlmIChwcm9wZXJ0eUtleSkge1xuICAgICAgcmV0dXJuIGluamVjdChuYW1lT3ZlcnJpZGUgfHwgbW9kZWwubmFtZSkob3JpZ2luYWwsIHByb3BlcnR5S2V5KTtcbiAgICB9XG5cbiAgICBtZXRhZGF0YShcbiAgICAgIFJlcG9zaXRvcnkua2V5KERCS2V5cy5SRVBPU0lUT1JZKSxcbiAgICAgIG5hbWVPdmVycmlkZSB8fCBvcmlnaW5hbC5uYW1lXG4gICAgKShtb2RlbCk7XG4gICAgUmVwb3NpdG9yeS5yZWdpc3Rlcihtb2RlbCwgb3JpZ2luYWwpO1xuICAgIHJldHVybiBpbmplY3RhYmxlKFxuICAgICAgbmFtZU92ZXJyaWRlIHx8IG9yaWdpbmFsLm5hbWUsXG4gICAgICB0cnVlLFxuICAgICAgKGluc3RhbmNlOiBJUmVwb3NpdG9yeTxUPikgPT4ge1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoaW5zdGFuY2UsIERCS2V5cy5DTEFTUywge1xuICAgICAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgICAgIGNvbmZpZ3VyYWJsZTogZmFsc2UsXG4gICAgICAgICAgd3JpdGFibGU6IGZhbHNlLFxuICAgICAgICAgIHZhbHVlOiBtb2RlbCxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgKShvcmlnaW5hbCk7XG4gIH0pIGFzIGFueTtcbn1cbiIsImltcG9ydCB7IEJhc2VFcnJvciB9IGZyb20gXCJAZGVjYWYtdHMvZGItZGVjb3JhdG9yc1wiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBFcnJvciB0aHJvd24gd2hlbiBvYnNlcnZlciBjb21tdW5pY2F0aW9uIGZhaWxzLlxuICogQHN1bW1hcnkgUmVwcmVzZW50cyBhIGZhaWx1cmUgaW4gb2JzZXJ2ZXIgY29tbXVuaWNhdGlvbiBiZXR3ZWVuIHJlcG9zaXRvcmllcy5cbiAqIEBwYXJhbSB7c3RyaW5nfEVycm9yfSBtc2cgLSBUaGUgZXJyb3IgbWVzc2FnZSBvciBFcnJvciBvYmplY3QuXG4gKiBAY2xhc3MgT2JzZXJ2ZXJFcnJvclxuICogQGNhdGVnb3J5IEVycm9yc1xuICogQGV4YW1wbGVcbiAqIHRyeSB7XG4gKiAgIC8vIFNvbWUgcmVwb3NpdG9yeSBvYnNlcnZlciBvcGVyYXRpb25cbiAqIH0gY2F0Y2ggKGVycm9yKSB7XG4gKiAgIGlmIChlcnJvciBpbnN0YW5jZW9mIE9ic2VydmVyRXJyb3IpIHtcbiAqICAgICBjb25zb2xlLmVycm9yKCdPYnNlcnZlciBjb21tdW5pY2F0aW9uIGZhaWxlZDonLCBlcnJvci5tZXNzYWdlKTtcbiAqICAgfVxuICogfVxuICovXG5leHBvcnQgY2xhc3MgT2JzZXJ2ZXJFcnJvciBleHRlbmRzIEJhc2VFcnJvciB7XG4gIGNvbnN0cnVjdG9yKG1zZzogc3RyaW5nIHwgRXJyb3IpIHtcbiAgICBzdXBlcihPYnNlcnZlckVycm9yLm5hbWUsIG1zZywgNTAwKTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgSW50ZXJuYWxFcnJvciB9IGZyb20gXCJAZGVjYWYtdHMvZGItZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHsgQ29uc3RydWN0b3IsIHNmIH0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgQWRhcHRlciB9IGZyb20gXCIuLi9wZXJzaXN0ZW5jZS9BZGFwdGVyXCI7XG5pbXBvcnQgeyBQZXJzaXN0ZW5jZUtleXMgfSBmcm9tIFwiLi4vcGVyc2lzdGVuY2UvY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBNb2RlbCB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7IFJlcG9zaXRvcnkgfSBmcm9tIFwiLi9SZXBvc2l0b3J5XCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEdlbmVyYXRlcyBhIHVuaXF1ZSBpbmplY3RhYmxlIG5hbWUgZm9yIGEgcmVwb3NpdG9yeS5cbiAqIEBzdW1tYXJ5IENyZWF0ZXMgYSBzdGFuZGFyZGl6ZWQgbmFtZSBmb3IgcmVwb3NpdG9yeSBpbmplY3RhYmxlcyBiYXNlZCBvbiBtb2RlbCBhbmQgYWRhcHRlciBmbGF2b3VyLlxuICogQHRlbXBsYXRlIFQgLSBUaGUgbW9kZWwgdHlwZSB0aGF0IGV4dGVuZHMgTW9kZWwuXG4gKiBAcGFyYW0ge0NvbnN0cnVjdG9yPFQ+IHwgVH0gbW9kZWwgLSBUaGUgbW9kZWwgY29uc3RydWN0b3Igb3IgaW5zdGFuY2UuXG4gKiBAcGFyYW0ge3N0cmluZ30gW2ZsYXZvdXJdIC0gT3B0aW9uYWwgYWRhcHRlciBmbGF2b3VyLiBJZiBub3QgcHJvdmlkZWQsIGl0IHdpbGwgYmUgcmV0cmlldmVkIGZyb20gdGhlIG1vZGVsIG1ldGFkYXRhLlxuICogQHJldHVybiB7c3RyaW5nfSBUaGUgZ2VuZXJhdGVkIGluamVjdGFibGUgbmFtZS5cbiAqIEB0aHJvd3Mge0ludGVybmFsRXJyb3J9IElmIG5vIGZsYXZvdXIgaXMgcHJvdmlkZWQgYW5kIG5vbmUgY2FuIGJlIHJldHJpZXZlZCBmcm9tIHRoZSBtb2RlbC5cbiAqIEBmdW5jdGlvbiBnZW5lcmF0ZUluamVjdGFibGVOYW1lRm9yUmVwb3NpdG9yeVxuICogQG1lbWJlck9mIG1vZHVsZTpjb3JlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZW5lcmF0ZUluamVjdGFibGVOYW1lRm9yUmVwb3NpdG9yeTxUIGV4dGVuZHMgTW9kZWw+KFxuICBtb2RlbDogQ29uc3RydWN0b3I8VD4gfCBULFxuICBmbGF2b3VyPzogc3RyaW5nXG4pOiBzdHJpbmcge1xuICBpZiAoIWZsYXZvdXIpIHtcbiAgICBjb25zdCBrZXkgPSBBZGFwdGVyLmtleShQZXJzaXN0ZW5jZUtleXMuQURBUFRFUik7XG4gICAgZmxhdm91ciA9IFJlZmxlY3QuZ2V0TWV0YWRhdGEoXG4gICAgICBrZXksXG4gICAgICBtb2RlbCBpbnN0YW5jZW9mIE1vZGVsID8gbW9kZWwuY29uc3RydWN0b3IgOiBtb2RlbFxuICAgICk7XG4gICAgaWYgKCFmbGF2b3VyKVxuICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXG4gICAgICAgIGBDb3VsZCBub3QgcmV0cmlldmUgZmxhdm91ciBmcm9tIG1vZGVsICR7bW9kZWwgaW5zdGFuY2VvZiBNb2RlbCA/IG1vZGVsLmNvbnN0cnVjdG9yLm5hbWUgOiBtb2RlbC5uYW1lfWBcbiAgICAgICk7XG4gIH1cbiAgcmV0dXJuIHNmKFBlcnNpc3RlbmNlS2V5cy5JTkpFQ1RBQkxFLCBmbGF2b3VyLCBSZXBvc2l0b3J5LnRhYmxlKG1vZGVsKSk7XG59XG4iLCJpbXBvcnQge1xuICBJbmplY3RhYmxlUmVnaXN0cnlJbXAsXG4gIEluamVjdGFibGVzLFxufSBmcm9tIFwiQGRlY2FmLXRzL2luamVjdGFibGUtZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHsgUmVwb3NpdG9yeSB9IGZyb20gXCIuL1JlcG9zaXRvcnlcIjtcbmltcG9ydCB7IE1vZGVsLCBNb2RlbENvbnN0cnVjdG9yIH0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgZ2VuZXJhdGVJbmplY3RhYmxlTmFtZUZvclJlcG9zaXRvcnkgfSBmcm9tIFwiLi91dGlsc1wiO1xuaW1wb3J0IHsgUGVyc2lzdGVuY2VLZXlzIH0gZnJvbSBcIi4uL3BlcnNpc3RlbmNlL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgQWRhcHRlciB9IGZyb20gXCIuLi9wZXJzaXN0ZW5jZS9BZGFwdGVyXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIFJlZ2lzdHJ5IGZvciBpbmplY3RhYmxlIHJlcG9zaXRvcmllcy5cbiAqIEBzdW1tYXJ5IEV4dGVuZHMgdGhlIGJhc2UgaW5qZWN0YWJsZSByZWdpc3RyeSB0byBwcm92aWRlIGF1dG9tYXRpYyByZXBvc2l0b3J5IHJlc29sdXRpb24gZm9yIG1vZGVscy5cbiAqIEBwYXJhbSB7dm9pZH0gLSBObyBjb25zdHJ1Y3RvciBwYXJhbWV0ZXJzIHJlcXVpcmVkLlxuICogQGNsYXNzIEluamVjdGFibGVzUmVnaXN0cnlcbiAqIEBleGFtcGxlXG4gKiBjb25zdCByZWdpc3RyeSA9IG5ldyBJbmplY3RhYmxlc1JlZ2lzdHJ5KCk7XG4gKiBjb25zdCB1c2VyUmVwbyA9IHJlZ2lzdHJ5LmdldDxVc2VyUmVwb3NpdG9yeT4oJ1VzZXInKTtcbiAqIC8vIElmIFVzZXJSZXBvc2l0b3J5IGV4aXN0cywgaXQgd2lsbCBiZSByZXR1cm5lZFxuICogLy8gSWYgbm90LCBidXQgVXNlciBtb2RlbCBleGlzdHMsIGEgcmVwb3NpdG9yeSB3aWxsIGJlIGNyZWF0ZWQgZm9yIGl0XG4gKi9cbmV4cG9ydCBjbGFzcyBJbmplY3RhYmxlc1JlZ2lzdHJ5IGV4dGVuZHMgSW5qZWN0YWJsZVJlZ2lzdHJ5SW1wIHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gR2V0cyBhbiBpbmplY3RhYmxlIGJ5IG5hbWUgd2l0aCByZXBvc2l0b3J5IGF1dG8tcmVzb2x1dGlvbi5cbiAgICogQHN1bW1hcnkgRXh0ZW5kcyB0aGUgYmFzZSBnZXQgbWV0aG9kIHRvIGF1dG9tYXRpY2FsbHkgcmVzb2x2ZSByZXBvc2l0b3JpZXMgZm9yIG1vZGVscyB3aGVuIG5vdCBmb3VuZCBkaXJlY3RseS5cbiAgICogQHRlbXBsYXRlIFQgLSBUaGUgdHlwZSBvZiBpbmplY3RhYmxlIHRvIHJldHVybi5cbiAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgaW5qZWN0YWJsZSB0byByZXRyaWV2ZS5cbiAgICogQHJldHVybiB7VCB8IHVuZGVmaW5lZH0gLSBUaGUgaW5qZWN0YWJsZSBpbnN0YW5jZSBvciB1bmRlZmluZWQgaWYgbm90IGZvdW5kLlxuICAgKi9cbiAgb3ZlcnJpZGUgZ2V0PFQ+KG5hbWU6IHN0cmluZyk6IFQgfCB1bmRlZmluZWQge1xuICAgIGxldCBpbmplY3RhYmxlID0gc3VwZXIuZ2V0KG5hbWUpO1xuICAgIGlmICghaW5qZWN0YWJsZSlcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IG0gPSBNb2RlbC5nZXQobmFtZSk7XG4gICAgICAgIGlmIChtKSBpbmplY3RhYmxlID0gUmVwb3NpdG9yeS5mb3JNb2RlbChtKTtcbiAgICAgICAgaWYgKGluamVjdGFibGUpIHtcbiAgICAgICAgICBpZiAoaW5qZWN0YWJsZSBpbnN0YW5jZW9mIFJlcG9zaXRvcnkpIHJldHVybiBpbmplY3RhYmxlIGFzIFQ7XG4gICAgICAgICAgY29uc3QgZmxhdm91ciA9XG4gICAgICAgICAgICBSZWZsZWN0LmdldE1ldGFkYXRhKFxuICAgICAgICAgICAgICBBZGFwdGVyLmtleShQZXJzaXN0ZW5jZUtleXMuQURBUFRFUiksXG4gICAgICAgICAgICAgIGluamVjdGFibGUuY29uc3RydWN0b3JcbiAgICAgICAgICAgICkgfHxcbiAgICAgICAgICAgIFJlZmxlY3QuZ2V0TWV0YWRhdGEoXG4gICAgICAgICAgICAgIEFkYXB0ZXIua2V5KFBlcnNpc3RlbmNlS2V5cy5BREFQVEVSKSxcbiAgICAgICAgICAgICAgbSBhcyBNb2RlbENvbnN0cnVjdG9yPGFueT5cbiAgICAgICAgICAgICk7XG4gICAgICAgICAgSW5qZWN0YWJsZXMucmVnaXN0ZXIoXG4gICAgICAgICAgICBpbmplY3RhYmxlLFxuICAgICAgICAgICAgZ2VuZXJhdGVJbmplY3RhYmxlTmFtZUZvclJlcG9zaXRvcnkoXG4gICAgICAgICAgICAgIG0gYXMgTW9kZWxDb25zdHJ1Y3Rvcjxhbnk+LFxuICAgICAgICAgICAgICBmbGF2b3VyXG4gICAgICAgICAgICApXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gICAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICByZXR1cm4gaW5qZWN0YWJsZSBhcyBUIHwgdW5kZWZpbmVkO1xuICB9XG59XG4iLCIvKipcbiAqIEBkZXNjcmlwdGlvbiBJbnRlcmZhY2UgZm9yIHNlcXVlbmNlIGNvbmZpZ3VyYXRpb24gb3B0aW9uc1xuICogQHN1bW1hcnkgRGVmaW5lcyB0aGUgY29uZmlndXJhdGlvbiBvcHRpb25zIGZvciBjcmVhdGluZyBhbmQgbWFuYWdpbmcgc2VxdWVuY2VzXG4gKiBAaW50ZXJmYWNlIFNlcXVlbmNlT3B0aW9uc1xuICogQG1lbWJlck9mIG1vZHVsZTpjb3JlXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU2VxdWVuY2VPcHRpb25zIHtcbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBPcHRpb25hbCBuYW1lIGZvciB0aGUgc2VxdWVuY2VcbiAgICogQHN1bW1hcnkgQSB1bmlxdWUgaWRlbnRpZmllciBmb3IgdGhlIHNlcXVlbmNlXG4gICAqL1xuICBuYW1lPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gVGhlIGRhdGEgdHlwZSBvZiB0aGUgc2VxdWVuY2VcbiAgICogQHN1bW1hcnkgU3BlY2lmaWVzIHdoZXRoZXIgdGhlIHNlcXVlbmNlIGdlbmVyYXRlcyBOdW1iZXIgb3IgQmlnSW50IHZhbHVlc1xuICAgKi9cbiAgdHlwZTogXCJOdW1iZXJcIiB8IFwiQmlnSW50XCIgfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBUaGUgaW5pdGlhbCB2YWx1ZSBvZiB0aGUgc2VxdWVuY2VcbiAgICogQHN1bW1hcnkgVGhlIHZhbHVlIHRoYXQgdGhlIHNlcXVlbmNlIHN0YXJ0cyB3aXRoXG4gICAqL1xuICBzdGFydFdpdGg6IG51bWJlcjtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFRoZSBpbmNyZW1lbnQgdmFsdWUgZm9yIGVhY2ggc3RlcCBpbiB0aGUgc2VxdWVuY2VcbiAgICogQHN1bW1hcnkgVGhlIGFtb3VudCBieSB3aGljaCB0aGUgc2VxdWVuY2UgaW5jcmVhc2VzIHdpdGggZWFjaCBjYWxsXG4gICAqL1xuICBpbmNyZW1lbnRCeTogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gT3B0aW9uYWwgbWluaW11bSB2YWx1ZSBmb3IgdGhlIHNlcXVlbmNlXG4gICAqIEBzdW1tYXJ5IFRoZSBsb3dlc3QgdmFsdWUgdGhhdCB0aGUgc2VxdWVuY2UgY2FuIGdlbmVyYXRlXG4gICAqL1xuICBtaW5WYWx1ZT86IG51bWJlcjtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIE9wdGlvbmFsIG1heGltdW0gdmFsdWUgZm9yIHRoZSBzZXF1ZW5jZVxuICAgKiBAc3VtbWFyeSBUaGUgaGlnaGVzdCB2YWx1ZSB0aGF0IHRoZSBzZXF1ZW5jZSBjYW4gZ2VuZXJhdGVcbiAgICovXG4gIG1heFZhbHVlPzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gV2hldGhlciB0aGUgc2VxdWVuY2Ugc2hvdWxkIGN5Y2xlIHdoZW4gcmVhY2hpbmcgaXRzIGxpbWl0c1xuICAgKiBAc3VtbWFyeSBJZiB0cnVlLCB0aGUgc2VxdWVuY2Ugd2lsbCByZXN0YXJ0IGZyb20gbWluVmFsdWUgd2hlbiByZWFjaGluZyBtYXhWYWx1ZVxuICAgKi9cbiAgY3ljbGU6IGJvb2xlYW47XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIERlZmF1bHQgb3B0aW9ucyBmb3Igc2VxdWVuY2VzXG4gKiBAc3VtbWFyeSBQcm92aWRlcyBhIHN0YW5kYXJkIGNvbmZpZ3VyYXRpb24gZm9yIG51bWJlciBzZXF1ZW5jZXMgc3RhcnRpbmcgYXQgMCBhbmQgaW5jcmVtZW50aW5nIGJ5IDFcbiAqIEBjb25zdCBEZWZhdWx0U2VxdWVuY2VPcHRpb25zXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmNvcmVcbiAqL1xuZXhwb3J0IGNvbnN0IERlZmF1bHRTZXF1ZW5jZU9wdGlvbnM6IFNlcXVlbmNlT3B0aW9ucyA9IHtcbiAgdHlwZTogXCJOdW1iZXJcIixcbiAgc3RhcnRXaXRoOiAwLFxuICBpbmNyZW1lbnRCeTogMSxcbiAgY3ljbGU6IGZhbHNlLFxufTtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gUHJlZGVmaW5lZCBvcHRpb25zIGZvciBudW1lcmljIHNlcXVlbmNlc1xuICogQHN1bW1hcnkgQ29uZmlndXJhdGlvbiBmb3Igc3RhbmRhcmQgbnVtYmVyIHNlcXVlbmNlcyBzdGFydGluZyBhdCAwIGFuZCBpbmNyZW1lbnRpbmcgYnkgMVxuICogQGNvbnN0IE51bWVyaWNTZXF1ZW5jZVxuICogQG1lbWJlck9mIG1vZHVsZTpjb3JlXG4gKi9cbmV4cG9ydCBjb25zdCBOdW1lcmljU2VxdWVuY2U6IFNlcXVlbmNlT3B0aW9ucyA9IHtcbiAgdHlwZTogXCJOdW1iZXJcIixcbiAgc3RhcnRXaXRoOiAwLFxuICBpbmNyZW1lbnRCeTogMSxcbiAgY3ljbGU6IGZhbHNlLFxufTtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gUHJlZGVmaW5lZCBvcHRpb25zIGZvciBCaWdJbnQgc2VxdWVuY2VzXG4gKiBAc3VtbWFyeSBDb25maWd1cmF0aW9uIGZvciBCaWdJbnQgc2VxdWVuY2VzIHN0YXJ0aW5nIGF0IDAgYW5kIGluY3JlbWVudGluZyBieSAxXG4gKiBAY29uc3QgQmlnSW50U2VxdWVuY2VcbiAqIEBtZW1iZXJPZiBtb2R1bGU6Y29yZVxuICovXG5leHBvcnQgY29uc3QgQmlnSW50U2VxdWVuY2U6IFNlcXVlbmNlT3B0aW9ucyA9IHtcbiAgdHlwZTogXCJCaWdJbnRcIixcbiAgc3RhcnRXaXRoOiAwLFxuICBpbmNyZW1lbnRCeTogMSxcbiAgY3ljbGU6IGZhbHNlLFxufTtcbiIsIi8qKlxuICogQGRlc2NyaXB0aW9uIENvbXBhcmlzb24gb3BlcmF0b3JzIGZvciBxdWVyeSBjb25kaXRpb25zXG4gKiBAc3VtbWFyeSBFbnVtIGRlZmluaW5nIHRoZSBhdmFpbGFibGUgb3BlcmF0b3JzIGZvciBjb21wYXJpbmcgdmFsdWVzIGluIGRhdGFiYXNlIHF1ZXJpZXNcbiAqIEBlbnVtIHtzdHJpbmd9XG4gKiBAcmVhZG9ubHlcbiAqIEBtZW1iZXJPZiBtb2R1bGU6Y29yZVxuICovXG5leHBvcnQgZW51bSBPcGVyYXRvciB7XG4gIC8qKiBFcXVhbCBjb21wYXJpc29uICg9KSAqL1xuICBFUVVBTCA9IFwiRVFVQUxcIixcbiAgLyoqIE5vdCBlcXVhbCBjb21wYXJpc29uICghPSkgKi9cbiAgRElGRkVSRU5UID0gXCJESUZGRVJFTlRcIixcbiAgLyoqIEdyZWF0ZXIgdGhhbiBjb21wYXJpc29uICg+KSAqL1xuICBCSUdHRVIgPSBcIkJJR0dFUlwiLFxuICAvKiogR3JlYXRlciB0aGFuIG9yIGVxdWFsIGNvbXBhcmlzb24gKD49KSAqL1xuICBCSUdHRVJfRVEgPSBcIkJJR0dFUl9FUVwiLFxuICAvKiogTGVzcyB0aGFuIGNvbXBhcmlzb24gKDwpICovXG4gIFNNQUxMRVIgPSBcIlNNQUxMRVJcIixcbiAgLyoqIExlc3MgdGhhbiBvciBlcXVhbCBjb21wYXJpc29uICg8PSkgKi9cbiAgU01BTExFUl9FUSA9IFwiU01BTExFUl9FUVwiLFxuICAvLyBCRVRXRUVOID0gXCJCRVRXRUVOXCIsXG4gIC8qKiBOZWdhdGlvbiBvcGVyYXRvciAoTk9UKSAqL1xuICBOT1QgPSBcIk5PVFwiLFxuICAvKiogSW5jbHVzaW9uIG9wZXJhdG9yIChJTikgKi9cbiAgSU4gPSBcIklOXCIsXG4gIC8vIElTID0gXCJJU1wiLFxuICAvKiogUmVndWxhciBleHByZXNzaW9uIG1hdGNoaW5nICovXG4gIFJFR0VYUCA9IFwiUkVHRVhQXCIsXG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIExvZ2ljYWwgb3BlcmF0b3JzIGZvciBjb21iaW5pbmcgcXVlcnkgY29uZGl0aW9uc1xuICogQHN1bW1hcnkgRW51bSBkZWZpbmluZyB0aGUgYXZhaWxhYmxlIG9wZXJhdG9ycyBmb3IgZ3JvdXBpbmcgbXVsdGlwbGUgY29uZGl0aW9ucyBpbiBkYXRhYmFzZSBxdWVyaWVzXG4gKiBAZW51bSB7c3RyaW5nfVxuICogQHJlYWRvbmx5XG4gKiBAbWVtYmVyT2YgbW9kdWxlOmNvcmVcbiAqL1xuZXhwb3J0IGVudW0gR3JvdXBPcGVyYXRvciB7XG4gIC8qKiBMb2dpY2FsIEFORCBvcGVyYXRvciAtIGFsbCBjb25kaXRpb25zIG11c3QgYmUgdHJ1ZSAqL1xuICBBTkQgPSBcIkFORFwiLFxuICAvKiogTG9naWNhbCBPUiBvcGVyYXRvciAtIGF0IGxlYXN0IG9uZSBjb25kaXRpb24gbXVzdCBiZSB0cnVlICovXG4gIE9SID0gXCJPUlwiLFxufVxuIiwiaW1wb3J0IHsgQmFzZUVycm9yIH0gZnJvbSBcIkBkZWNhZi10cy9kYi1kZWNvcmF0b3JzXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEVycm9yIHRocm93biBkdXJpbmcgcXVlcnkgb3BlcmF0aW9uc1xuICogQHN1bW1hcnkgUmVwcmVzZW50cyBlcnJvcnMgdGhhdCBvY2N1ciBkdXJpbmcgcXVlcnkgYnVpbGRpbmcgb3IgZXhlY3V0aW9uXG4gKiBAcGFyYW0ge3N0cmluZyB8IEVycm9yfSBtc2cgLSBUaGUgZXJyb3IgbWVzc2FnZSBvciBFcnJvciBvYmplY3RcbiAqIEBjbGFzcyBRdWVyeUVycm9yXG4gKiBAY2F0ZWdvcnkgRXJyb3JzXG4gKi9cbmV4cG9ydCBjbGFzcyBRdWVyeUVycm9yIGV4dGVuZHMgQmFzZUVycm9yIHtcbiAgY29uc3RydWN0b3IobXNnOiBzdHJpbmcgfCBFcnJvcikge1xuICAgIHN1cGVyKFF1ZXJ5RXJyb3IubmFtZSwgbXNnLCA1MDApO1xuICB9XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEVycm9yIHRocm93biBkdXJpbmcgcGFnaW5hdGlvbiBvcGVyYXRpb25zXG4gKiBAc3VtbWFyeSBSZXByZXNlbnRzIGVycm9ycyB0aGF0IG9jY3VyIGR1cmluZyBwYWdpbmF0aW9uIHNldHVwIG9yIGV4ZWN1dGlvblxuICogQHBhcmFtIHtzdHJpbmcgfCBFcnJvcn0gbXNnIC0gVGhlIGVycm9yIG1lc3NhZ2Ugb3IgRXJyb3Igb2JqZWN0XG4gKiBAY2xhc3MgUGFnaW5nRXJyb3JcbiAqIEBjYXRlZ29yeSBFcnJvcnNcbiAqL1xuZXhwb3J0IGNsYXNzIFBhZ2luZ0Vycm9yIGV4dGVuZHMgQmFzZUVycm9yIHtcbiAgY29uc3RydWN0b3IobXNnOiBzdHJpbmcgfCBFcnJvcikge1xuICAgIHN1cGVyKFBhZ2luZ0Vycm9yLm5hbWUsIG1zZywgNTAwKTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgQXR0cmlidXRlT3B0aW9uLCBDb25kaXRpb25CdWlsZGVyT3B0aW9uIH0gZnJvbSBcIi4vb3B0aW9uc1wiO1xuaW1wb3J0IHtcbiAgTW9kZWwsXG4gIE1vZGVsRXJyb3JEZWZpbml0aW9uLFxuICByZXF1aXJlZCxcbn0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgR3JvdXBPcGVyYXRvciwgT3BlcmF0b3IgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IFF1ZXJ5RXJyb3IgfSBmcm9tIFwiLi9lcnJvcnNcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gUmVwcmVzZW50cyBhIGxvZ2ljYWwgY29uZGl0aW9uIGZvciBkYXRhYmFzZSBxdWVyaWVzXG4gKiBAc3VtbWFyeSBBIGNsYXNzIHRoYXQgZW5jYXBzdWxhdGVzIHF1ZXJ5IGNvbmRpdGlvbnMgd2l0aCBzdXBwb3J0IGZvciBjb21wbGV4IGxvZ2ljYWwgb3BlcmF0aW9ucy5cbiAqIFRoaXMgY2xhc3MgYWxsb3dzIGZvciBidWlsZGluZyBhbmQgY29tYmluaW5nIHF1ZXJ5IGNvbmRpdGlvbnMgdXNpbmcgbG9naWNhbCBvcGVyYXRvcnMgKEFORCwgT1IsIE5PVClcbiAqIGFuZCBjb21wYXJpc29uIG9wZXJhdG9ycyAoZXF1YWxzLCBub3QgZXF1YWxzLCBncmVhdGVyIHRoYW4sIGV0Yy4pLlxuICogQHRlbXBsYXRlIE0gLSBUaGUgbW9kZWwgdHlwZSB0aGlzIGNvbmRpdGlvbiBvcGVyYXRlcyBvblxuICogQHBhcmFtIHtzdHJpbmcgfCBDb25kaXRpb248TT59IGF0dHIxIC0gVGhlIGF0dHJpYnV0ZSBuYW1lIG9yIGEgbmVzdGVkIGNvbmRpdGlvblxuICogQHBhcmFtIHtPcGVyYXRvciB8IEdyb3VwT3BlcmF0b3J9IG9wZXJhdG9yIC0gVGhlIG9wZXJhdG9yIHRvIHVzZSBmb3IgdGhlIGNvbmRpdGlvblxuICogQHBhcmFtIHthbnl9IGNvbXBhcmlzb24gLSBUaGUgdmFsdWUgdG8gY29tcGFyZSBhZ2FpbnN0IG9yIGFub3RoZXIgY29uZGl0aW9uXG4gKiBAY2xhc3MgQ29uZGl0aW9uXG4gKiBAZXhhbXBsZVxuICogLy8gQ3JlYXRlIGEgc2ltcGxlIGNvbmRpdGlvblxuICogY29uc3QgbmFtZUNvbmRpdGlvbiA9IENvbmRpdGlvbi5hdHRyaWJ1dGUoXCJuYW1lXCIpLmVxKFwiSm9oblwiKTtcbiAqXG4gKiAvLyBDcmVhdGUgYSBjb21wbGV4IGNvbmRpdGlvblxuICogY29uc3QgY29tcGxleENvbmRpdGlvbiA9IENvbmRpdGlvbi5hdHRyaWJ1dGUoXCJhZ2VcIikuZ3QoMTgpXG4gKiAgIC5hbmQoQ29uZGl0aW9uLmF0dHJpYnV0ZShcInN0YXR1c1wiKS5lcShcImFjdGl2ZVwiKSk7XG4gKlxuICogLy8gVXNlIHRoZSBidWlsZGVyIHBhdHRlcm5cbiAqIGNvbnN0IHVzZXJRdWVyeSA9IENvbmRpdGlvbi5idWlsZGVyKClcbiAqICAgLmF0dHJpYnV0ZShcImVtYWlsXCIpLnJlZ2V4cChcIi4qQGV4YW1wbGUuY29tXCIpXG4gKiAgIC5hbmQoQ29uZGl0aW9uLmF0dHJpYnV0ZShcImxhc3RMb2dpblwiKS5ndChuZXcgRGF0ZShcIjIwMjMtMDEtMDFcIikpKTtcbiAqL1xuZXhwb3J0IGNsYXNzIENvbmRpdGlvbjxNIGV4dGVuZHMgTW9kZWw+IGV4dGVuZHMgTW9kZWwge1xuICBAcmVxdWlyZWQoKVxuICBwcm90ZWN0ZWQgYXR0cjE/OiBzdHJpbmcgfCBDb25kaXRpb248TT4gPSB1bmRlZmluZWQ7XG4gIEByZXF1aXJlZCgpXG4gIHByb3RlY3RlZCBvcGVyYXRvcj86IE9wZXJhdG9yIHwgR3JvdXBPcGVyYXRvciA9IHVuZGVmaW5lZDtcbiAgQHJlcXVpcmVkKClcbiAgcHJvdGVjdGVkIGNvbXBhcmlzb24/OiBhbnkgPSB1bmRlZmluZWQ7XG5cbiAgcHJpdmF0ZSBjb25zdHJ1Y3RvcihcbiAgICBhdHRyMTogc3RyaW5nIHwgQ29uZGl0aW9uPE0+LFxuICAgIG9wZXJhdG9yOiBPcGVyYXRvciB8IEdyb3VwT3BlcmF0b3IsXG4gICAgY29tcGFyaXNvbjogYW55XG4gICkge1xuICAgIHN1cGVyKCk7XG4gICAgdGhpcy5hdHRyMSA9IGF0dHIxO1xuICAgIHRoaXMub3BlcmF0b3IgPSBvcGVyYXRvcjtcbiAgICB0aGlzLmNvbXBhcmlzb24gPSBjb21wYXJpc29uO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDb21iaW5lcyB0aGlzIGNvbmRpdGlvbiB3aXRoIGFub3RoZXIgdXNpbmcgbG9naWNhbCBBTkRcbiAgICogQHN1bW1hcnkgSm9pbnMgdHdvIGNvbmRpdGlvbnMgd2l0aCBhbiBBTkQgb3BlcmF0b3IsIHJlcXVpcmluZyBib3RoIHRvIGJlIHRydWVcbiAgICogQHBhcmFtIHtDb25kaXRpb248TT59IGNvbmRpdGlvbiAtIFRoZSBjb25kaXRpb24gdG8gY29tYmluZSB3aXRoIHRoaXMgb25lXG4gICAqIEByZXR1cm4ge0NvbmRpdGlvbjxNPn0gQSBuZXcgY29uZGl0aW9uIHJlcHJlc2VudGluZyB0aGUgQU5EIG9wZXJhdGlvblxuICAgKi9cbiAgYW5kKGNvbmRpdGlvbjogQ29uZGl0aW9uPE0+KTogQ29uZGl0aW9uPE0+IHtcbiAgICByZXR1cm4gQ29uZGl0aW9uLmFuZCh0aGlzLCBjb25kaXRpb24pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDb21iaW5lcyB0aGlzIGNvbmRpdGlvbiB3aXRoIGFub3RoZXIgdXNpbmcgbG9naWNhbCBPUlxuICAgKiBAc3VtbWFyeSBKb2lucyB0d28gY29uZGl0aW9ucyB3aXRoIGFuIE9SIG9wZXJhdG9yLCByZXF1aXJpbmcgYXQgbGVhc3Qgb25lIHRvIGJlIHRydWVcbiAgICogQHBhcmFtIHtDb25kaXRpb248TT59IGNvbmRpdGlvbiAtIFRoZSBjb25kaXRpb24gdG8gY29tYmluZSB3aXRoIHRoaXMgb25lXG4gICAqIEByZXR1cm4ge0NvbmRpdGlvbjxNPn0gQSBuZXcgY29uZGl0aW9uIHJlcHJlc2VudGluZyB0aGUgT1Igb3BlcmF0aW9uXG4gICAqL1xuICBvcihjb25kaXRpb246IENvbmRpdGlvbjxNPik6IENvbmRpdGlvbjxNPiB7XG4gICAgcmV0dXJuIENvbmRpdGlvbi5vcih0aGlzLCBjb25kaXRpb24pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDcmVhdGVzIGEgbmVnYXRpb24gY29uZGl0aW9uXG4gICAqIEBzdW1tYXJ5IEV4Y2x1ZGVzIGEgdmFsdWUgZnJvbSB0aGUgcmVzdWx0IGJ5IGFwcGx5aW5nIGEgTk9UIG9wZXJhdG9yXG4gICAqIEBwYXJhbSB7YW55fSB2YWwgLSBUaGUgdmFsdWUgdG8gbmVnYXRlXG4gICAqIEByZXR1cm4ge0NvbmRpdGlvbjxNPn0gQSBuZXcgY29uZGl0aW9uIHJlcHJlc2VudGluZyB0aGUgTk9UIG9wZXJhdGlvblxuICAgKi9cbiAgbm90KHZhbDogYW55KTogQ29uZGl0aW9uPE0+IHtcbiAgICByZXR1cm4gbmV3IENvbmRpdGlvbih0aGlzLCBPcGVyYXRvci5OT1QsIHZhbCk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFZhbGlkYXRlcyB0aGUgY29uZGl0aW9uIGFuZCBjaGVja3MgZm9yIGVycm9yc1xuICAgKiBAc3VtbWFyeSBFeHRlbmRzIHRoZSBiYXNlIHZhbGlkYXRpb24gdG8gZW5zdXJlIHRoZSBjb25kaXRpb24gaXMgcHJvcGVybHkgZm9ybWVkXG4gICAqIEBwYXJhbSB7Li4uc3RyaW5nW119IGV4Y2VwdGlvbnMgLSBGaWVsZHMgdG8gZXhjbHVkZSBmcm9tIHZhbGlkYXRpb25cbiAgICogQHJldHVybiB7TW9kZWxFcnJvckRlZmluaXRpb24gfCB1bmRlZmluZWR9IEVycm9yIGRlZmluaXRpb24gaWYgdmFsaWRhdGlvbiBmYWlscywgdW5kZWZpbmVkIG90aGVyd2lzZVxuICAgKi9cbiAgb3ZlcnJpZGUgaGFzRXJyb3JzKFxuICAgIC4uLmV4Y2VwdGlvbnM6IHN0cmluZ1tdXG4gICk6IE1vZGVsRXJyb3JEZWZpbml0aW9uIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCBlcnJvcnMgPSBzdXBlci5oYXNFcnJvcnMoLi4uZXhjZXB0aW9ucyk7XG4gICAgaWYgKGVycm9ycykgcmV0dXJuIGVycm9ycztcblxuICAgIGNvbnN0IGludmFsaWRPcE1lc3NhZ2UgPSBgSW52YWxpZCBvcGVyYXRvciAke3RoaXMub3BlcmF0b3J9fWA7XG5cbiAgICBpZiAodHlwZW9mIHRoaXMuYXR0cjEgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgIGlmICh0aGlzLmNvbXBhcmlzb24gaW5zdGFuY2VvZiBDb25kaXRpb24pXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgY29tcGFyaXNvbjoge1xuICAgICAgICAgICAgY29uZGl0aW9uOiBcIkJvdGggc2lkZXMgb2YgdGhlIGNvbXBhcmlzb24gbXVzdCBiZSBvZiB0aGUgc2FtZSB0eXBlXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSBhcyBNb2RlbEVycm9yRGVmaW5pdGlvbjtcbiAgICAgIGlmIChPYmplY3QudmFsdWVzKE9wZXJhdG9yKS5pbmRleE9mKHRoaXMub3BlcmF0b3IgYXMgT3BlcmF0b3IpID09PSAtMSlcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBvcGVyYXRvcjoge1xuICAgICAgICAgICAgY29uZGl0aW9uOiBpbnZhbGlkT3BNZXNzYWdlLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0gYXMgTW9kZWxFcnJvckRlZmluaXRpb247XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuYXR0cjEgaW5zdGFuY2VvZiBDb25kaXRpb24pIHtcbiAgICAgIGlmIChcbiAgICAgICAgISh0aGlzLmNvbXBhcmlzb24gaW5zdGFuY2VvZiBDb25kaXRpb24pICYmXG4gICAgICAgIHRoaXMub3BlcmF0b3IgIT09IE9wZXJhdG9yLk5PVFxuICAgICAgKVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGNvbXBhcmlzb246IHtcbiAgICAgICAgICAgIGNvbmRpdGlvbjogaW52YWxpZE9wTWVzc2FnZSxcbiAgICAgICAgICB9LFxuICAgICAgICB9IGFzIE1vZGVsRXJyb3JEZWZpbml0aW9uO1xuICAgICAgaWYgKFxuICAgICAgICBPYmplY3QudmFsdWVzKEdyb3VwT3BlcmF0b3IpLmluZGV4T2YodGhpcy5vcGVyYXRvciBhcyBHcm91cE9wZXJhdG9yKSA9PT1cbiAgICAgICAgICAtMSAmJlxuICAgICAgICB0aGlzLm9wZXJhdG9yICE9PSBPcGVyYXRvci5OT1RcbiAgICAgIClcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBvcGVyYXRvcjoge1xuICAgICAgICAgICAgY29uZGl0aW9uOiBpbnZhbGlkT3BNZXNzYWdlLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0gYXMgTW9kZWxFcnJvckRlZmluaXRpb247XG4gICAgICAvLyBpZiAodGhpcy5vcGVyYXRvciAhPT0gT3BlcmF0b3IuTk9UICYmIHR5cGVvZiB0aGlzLmF0dHIxLmF0dHIxICE9PSBcInN0cmluZ1wiKVxuICAgICAgLy8gICAgIHJldHVybiB7XG4gICAgICAvLyAgICAgICAgIGF0dHIxOiB7XG4gICAgICAvLyAgICAgICAgICAgICBjb25kaXRpb246IHN0cmluZ0Zvcm1hdChcIlBhcmVudCBjb25kaXRpb24gYXR0cmlidXRlIG11c3QgYmUgYSBzdHJpbmdcIilcbiAgICAgIC8vICAgICAgICAgfVxuICAgICAgLy8gICAgIH0gYXMgTW9kZWxFcnJvckRlZmluaXRpb25cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENyZWF0ZXMgYSBuZXcgY29uZGl0aW9uIHRoYXQgY29tYmluZXMgdHdvIGNvbmRpdGlvbnMgd2l0aCBsb2dpY2FsIEFORFxuICAgKiBAc3VtbWFyeSBTdGF0aWMgbWV0aG9kIHRoYXQgam9pbnMgdHdvIGNvbmRpdGlvbnMgd2l0aCBhbiBBTkQgb3BlcmF0b3IsIHJlcXVpcmluZyBib3RoIHRvIGJlIHRydWVcbiAgICogQHRlbXBsYXRlIE0gLSBUaGUgbW9kZWwgdHlwZSB0aGlzIGNvbmRpdGlvbiBvcGVyYXRlcyBvblxuICAgKiBAcGFyYW0ge0NvbmRpdGlvbjxNPn0gY29uZGl0aW9uMSAtIFRoZSBmaXJzdCBjb25kaXRpb25cbiAgICogQHBhcmFtIHtDb25kaXRpb248TT59IGNvbmRpdGlvbjIgLSBUaGUgc2Vjb25kIGNvbmRpdGlvblxuICAgKiBAcmV0dXJuIHtDb25kaXRpb248TT59IEEgbmV3IGNvbmRpdGlvbiByZXByZXNlbnRpbmcgdGhlIEFORCBvcGVyYXRpb25cbiAgICovXG4gIHN0YXRpYyBhbmQ8TSBleHRlbmRzIE1vZGVsPihcbiAgICBjb25kaXRpb24xOiBDb25kaXRpb248TT4sXG4gICAgY29uZGl0aW9uMjogQ29uZGl0aW9uPE0+XG4gICk6IENvbmRpdGlvbjxNPiB7XG4gICAgcmV0dXJuIENvbmRpdGlvbi5ncm91cChjb25kaXRpb24xLCBHcm91cE9wZXJhdG9yLkFORCwgY29uZGl0aW9uMik7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENyZWF0ZXMgYSBuZXcgY29uZGl0aW9uIHRoYXQgY29tYmluZXMgdHdvIGNvbmRpdGlvbnMgd2l0aCBsb2dpY2FsIE9SXG4gICAqIEBzdW1tYXJ5IFN0YXRpYyBtZXRob2QgdGhhdCBqb2lucyB0d28gY29uZGl0aW9ucyB3aXRoIGFuIE9SIG9wZXJhdG9yLCByZXF1aXJpbmcgYXQgbGVhc3Qgb25lIHRvIGJlIHRydWVcbiAgICogQHRlbXBsYXRlIE0gLSBUaGUgbW9kZWwgdHlwZSB0aGlzIGNvbmRpdGlvbiBvcGVyYXRlcyBvblxuICAgKiBAcGFyYW0ge0NvbmRpdGlvbjxNPn0gY29uZGl0aW9uMSAtIFRoZSBmaXJzdCBjb25kaXRpb25cbiAgICogQHBhcmFtIHtDb25kaXRpb248TT59IGNvbmRpdGlvbjIgLSBUaGUgc2Vjb25kIGNvbmRpdGlvblxuICAgKiBAcmV0dXJuIHtDb25kaXRpb248TT59IEEgbmV3IGNvbmRpdGlvbiByZXByZXNlbnRpbmcgdGhlIE9SIG9wZXJhdGlvblxuICAgKi9cbiAgc3RhdGljIG9yPE0gZXh0ZW5kcyBNb2RlbD4oXG4gICAgY29uZGl0aW9uMTogQ29uZGl0aW9uPE0+LFxuICAgIGNvbmRpdGlvbjI6IENvbmRpdGlvbjxNPlxuICApOiBDb25kaXRpb248TT4ge1xuICAgIHJldHVybiBDb25kaXRpb24uZ3JvdXAoY29uZGl0aW9uMSwgR3JvdXBPcGVyYXRvci5PUiwgY29uZGl0aW9uMik7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENyZWF0ZXMgYSBuZXcgY29uZGl0aW9uIHRoYXQgZ3JvdXBzIHR3byBjb25kaXRpb25zIHdpdGggYSBzcGVjaWZpZWQgb3BlcmF0b3JcbiAgICogQHN1bW1hcnkgUHJpdmF0ZSBzdGF0aWMgbWV0aG9kIHRoYXQgY29tYmluZXMgdHdvIGNvbmRpdGlvbnMgdXNpbmcgdGhlIHNwZWNpZmllZCBncm91cCBvcGVyYXRvclxuICAgKiBAdGVtcGxhdGUgTSAtIFRoZSBtb2RlbCB0eXBlIHRoaXMgY29uZGl0aW9uIG9wZXJhdGVzIG9uXG4gICAqIEBwYXJhbSB7Q29uZGl0aW9uPE0+fSBjb25kaXRpb24xIC0gVGhlIGZpcnN0IGNvbmRpdGlvblxuICAgKiBAcGFyYW0ge0dyb3VwT3BlcmF0b3J9IG9wZXJhdG9yIC0gVGhlIGdyb3VwIG9wZXJhdG9yIHRvIHVzZSAoQU5ELCBPUilcbiAgICogQHBhcmFtIHtDb25kaXRpb248TT59IGNvbmRpdGlvbjIgLSBUaGUgc2Vjb25kIGNvbmRpdGlvblxuICAgKiBAcmV0dXJuIHtDb25kaXRpb248TT59IEEgbmV3IGNvbmRpdGlvbiByZXByZXNlbnRpbmcgdGhlIGdyb3VwZWQgb3BlcmF0aW9uXG4gICAqL1xuICBwcml2YXRlIHN0YXRpYyBncm91cDxNIGV4dGVuZHMgTW9kZWw+KFxuICAgIGNvbmRpdGlvbjE6IENvbmRpdGlvbjxNPixcbiAgICBvcGVyYXRvcjogR3JvdXBPcGVyYXRvcixcbiAgICBjb25kaXRpb24yOiBDb25kaXRpb248TT5cbiAgKTogQ29uZGl0aW9uPE0+IHtcbiAgICByZXR1cm4gbmV3IENvbmRpdGlvbihjb25kaXRpb24xLCBvcGVyYXRvciwgY29uZGl0aW9uMik7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENyZWF0ZXMgYSBjb25kaXRpb24gYnVpbGRlciBmb3IgYSBzcGVjaWZpYyBtb2RlbCBhdHRyaWJ1dGVcbiAgICogQHN1bW1hcnkgU3RhdGljIG1ldGhvZCB0aGF0IGluaXRpYWxpemVzIGEgY29uZGl0aW9uIGJ1aWxkZXIgd2l0aCB0aGUgc3BlY2lmaWVkIGF0dHJpYnV0ZVxuICAgKiBAdGVtcGxhdGUgTSAtIFRoZSBtb2RlbCB0eXBlIHRoaXMgY29uZGl0aW9uIG9wZXJhdGVzIG9uXG4gICAqIEBwYXJhbSBhdHRyIC0gVGhlIG1vZGVsIGF0dHJpYnV0ZSB0byBidWlsZCBhIGNvbmRpdGlvbiBmb3JcbiAgICogQHJldHVybiB7QXR0cmlidXRlT3B0aW9uPE0+fSBBIGNvbmRpdGlvbiBidWlsZGVyIGluaXRpYWxpemVkIHdpdGggdGhlIGF0dHJpYnV0ZVxuICAgKi9cbiAgc3RhdGljIGF0dHJpYnV0ZTxNIGV4dGVuZHMgTW9kZWw+KGF0dHI6IGtleW9mIE0pIHtcbiAgICByZXR1cm4gbmV3IENvbmRpdGlvbi5CdWlsZGVyPE0+KCkuYXR0cmlidXRlKGF0dHIpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBBbGlhcyBmb3IgdGhlIGF0dHJpYnV0ZSBtZXRob2RcbiAgICogQHN1bW1hcnkgU2hvcnRoYW5kIG1ldGhvZCB0aGF0IGluaXRpYWxpemVzIGEgY29uZGl0aW9uIGJ1aWxkZXIgd2l0aCB0aGUgc3BlY2lmaWVkIGF0dHJpYnV0ZVxuICAgKiBAdGVtcGxhdGUgTSAtIFRoZSBtb2RlbCB0eXBlIHRoaXMgY29uZGl0aW9uIG9wZXJhdGVzIG9uXG4gICAqIEBwYXJhbSBhdHRyIC0gVGhlIG1vZGVsIGF0dHJpYnV0ZSB0byBidWlsZCBhIGNvbmRpdGlvbiBmb3JcbiAgICogQHJldHVybiB7QXR0cmlidXRlT3B0aW9uPE0+fSBBIGNvbmRpdGlvbiBidWlsZGVyIGluaXRpYWxpemVkIHdpdGggdGhlIGF0dHJpYnV0ZVxuICAgKi9cbiAgc3RhdGljIGF0dHI8TSBleHRlbmRzIE1vZGVsPihhdHRyOiBrZXlvZiBNKSB7XG4gICAgcmV0dXJuIHRoaXMuYXR0cmlidXRlKGF0dHIpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBQcm92aWRlcyBhIGZsdWVudCBBUEkgdG8gYnVpbGQgcXVlcnkgY29uZGl0aW9uc1xuICAgKiBAc3VtbWFyeSBBIGJ1aWxkZXIgY2xhc3MgdGhhdCBzaW1wbGlmaWVzIHRoZSBjcmVhdGlvbiBvZiBkYXRhYmFzZSBxdWVyeSBjb25kaXRpb25zXG4gICAqIHdpdGggYSBjaGFpbmFibGUgaW50ZXJmYWNlIGZvciBzZXR0aW5nIGF0dHJpYnV0ZXMgYW5kIG9wZXJhdG9yc1xuICAgKiBAdGVtcGxhdGUgTSAtIFRoZSBtb2RlbCB0eXBlIHRoaXMgY29uZGl0aW9uIGJ1aWxkZXIgb3BlcmF0ZXMgb25cbiAgICogQGNsYXNzIENvbmRpdGlvbkJ1aWxkZXJcbiAgICovXG4gIHByaXZhdGUgc3RhdGljIEJ1aWxkZXIgPSBjbGFzcyBDb25kaXRpb25CdWlsZGVyPE0gZXh0ZW5kcyBNb2RlbD5cbiAgICBpbXBsZW1lbnRzIENvbmRpdGlvbkJ1aWxkZXJPcHRpb248TT4sIEF0dHJpYnV0ZU9wdGlvbjxNPlxuICB7XG4gICAgYXR0cjE/OiBrZXlvZiBNIHwgQ29uZGl0aW9uPE0+ID0gdW5kZWZpbmVkO1xuICAgIG9wZXJhdG9yPzogT3BlcmF0b3IgfCBHcm91cE9wZXJhdG9yID0gdW5kZWZpbmVkO1xuICAgIGNvbXBhcmlzb24/OiBhbnkgPSB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBAZGVzY3JpcHRpb24gU2V0cyB0aGUgYXR0cmlidXRlIGZvciB0aGUgY29uZGl0aW9uXG4gICAgICogQHN1bW1hcnkgU3BlY2lmaWVzIHdoaWNoIG1vZGVsIGF0dHJpYnV0ZSB0aGUgY29uZGl0aW9uIHdpbGwgb3BlcmF0ZSBvblxuICAgICAqIEBwYXJhbSBhdHRyIC0gVGhlIG1vZGVsIGF0dHJpYnV0ZSB0byB1c2UgaW4gdGhlIGNvbmRpdGlvblxuICAgICAqIEByZXR1cm4ge0F0dHJpYnV0ZU9wdGlvbjxNPn0gVGhpcyBidWlsZGVyIGluc3RhbmNlIGZvciBtZXRob2QgY2hhaW5pbmdcbiAgICAgKi9cbiAgICBhdHRyaWJ1dGUoYXR0cjoga2V5b2YgTSk6IEF0dHJpYnV0ZU9wdGlvbjxNPiB7XG4gICAgICB0aGlzLmF0dHIxID0gYXR0cjtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBkZXNjcmlwdGlvbiBBbGlhcyBmb3IgdGhlIGF0dHJpYnV0ZSBtZXRob2RcbiAgICAgKiBAc3VtbWFyeSBTaG9ydGhhbmQgbWV0aG9kIHRvIHNwZWNpZnkgd2hpY2ggbW9kZWwgYXR0cmlidXRlIHRoZSBjb25kaXRpb24gd2lsbCBvcGVyYXRlIG9uXG4gICAgICogQHBhcmFtIGF0dHIgLSBUaGUgbW9kZWwgYXR0cmlidXRlIHRvIHVzZSBpbiB0aGUgY29uZGl0aW9uXG4gICAgICogQHJldHVybiB7QXR0cmlidXRlT3B0aW9uPE0+fSBUaGlzIGJ1aWxkZXIgaW5zdGFuY2UgZm9yIG1ldGhvZCBjaGFpbmluZ1xuICAgICAqL1xuICAgIGF0dHIoYXR0cjoga2V5b2YgTSkge1xuICAgICAgcmV0dXJuIHRoaXMuYXR0cmlidXRlKGF0dHIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBkZXNjcmlwdGlvbiBDcmVhdGVzIGFuIGVxdWFsaXR5IGNvbmRpdGlvblxuICAgICAqIEBzdW1tYXJ5IEJ1aWxkcyBhIGNvbmRpdGlvbiB0aGF0IGNoZWNrcyBpZiB0aGUgYXR0cmlidXRlIGVxdWFscyB0aGUgc3BlY2lmaWVkIHZhbHVlXG4gICAgICogQHBhcmFtIHthbnl9IHZhbCAtIFRoZSB2YWx1ZSB0byBjb21wYXJlIHRoZSBhdHRyaWJ1dGUgYWdhaW5zdFxuICAgICAqIEByZXR1cm4ge0NvbmRpdGlvbjxNPn0gQSBuZXcgY29uZGl0aW9uIHJlcHJlc2VudGluZyB0aGUgZXF1YWxpdHkgY29tcGFyaXNvblxuICAgICAqL1xuICAgIGVxKHZhbDogYW55KSB7XG4gICAgICByZXR1cm4gdGhpcy5zZXRPcChPcGVyYXRvci5FUVVBTCwgdmFsKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAZGVzY3JpcHRpb24gQ3JlYXRlcyBhbiBpbmVxdWFsaXR5IGNvbmRpdGlvblxuICAgICAqIEBzdW1tYXJ5IEJ1aWxkcyBhIGNvbmRpdGlvbiB0aGF0IGNoZWNrcyBpZiB0aGUgYXR0cmlidXRlIGlzIGRpZmZlcmVudCBmcm9tIHRoZSBzcGVjaWZpZWQgdmFsdWVcbiAgICAgKiBAcGFyYW0ge2FueX0gdmFsIC0gVGhlIHZhbHVlIHRvIGNvbXBhcmUgdGhlIGF0dHJpYnV0ZSBhZ2FpbnN0XG4gICAgICogQHJldHVybiB7Q29uZGl0aW9uPE0+fSBBIG5ldyBjb25kaXRpb24gcmVwcmVzZW50aW5nIHRoZSBpbmVxdWFsaXR5IGNvbXBhcmlzb25cbiAgICAgKi9cbiAgICBkaWYodmFsOiBhbnkpIHtcbiAgICAgIHJldHVybiB0aGlzLnNldE9wKE9wZXJhdG9yLkRJRkZFUkVOVCwgdmFsKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAZGVzY3JpcHRpb24gQ3JlYXRlcyBhIGdyZWF0ZXIgdGhhbiBjb25kaXRpb25cbiAgICAgKiBAc3VtbWFyeSBCdWlsZHMgYSBjb25kaXRpb24gdGhhdCBjaGVja3MgaWYgdGhlIGF0dHJpYnV0ZSBpcyBncmVhdGVyIHRoYW4gdGhlIHNwZWNpZmllZCB2YWx1ZVxuICAgICAqIEBwYXJhbSB7YW55fSB2YWwgLSBUaGUgdmFsdWUgdG8gY29tcGFyZSB0aGUgYXR0cmlidXRlIGFnYWluc3RcbiAgICAgKiBAcmV0dXJuIHtDb25kaXRpb248TT59IEEgbmV3IGNvbmRpdGlvbiByZXByZXNlbnRpbmcgdGhlIGdyZWF0ZXIgdGhhbiBjb21wYXJpc29uXG4gICAgICovXG4gICAgZ3QodmFsOiBhbnkpIHtcbiAgICAgIHJldHVybiB0aGlzLnNldE9wKE9wZXJhdG9yLkJJR0dFUiwgdmFsKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAZGVzY3JpcHRpb24gQ3JlYXRlcyBhIGxlc3MgdGhhbiBjb25kaXRpb25cbiAgICAgKiBAc3VtbWFyeSBCdWlsZHMgYSBjb25kaXRpb24gdGhhdCBjaGVja3MgaWYgdGhlIGF0dHJpYnV0ZSBpcyBsZXNzIHRoYW4gdGhlIHNwZWNpZmllZCB2YWx1ZVxuICAgICAqIEBwYXJhbSB7YW55fSB2YWwgLSBUaGUgdmFsdWUgdG8gY29tcGFyZSB0aGUgYXR0cmlidXRlIGFnYWluc3RcbiAgICAgKiBAcmV0dXJuIHtDb25kaXRpb248TT59IEEgbmV3IGNvbmRpdGlvbiByZXByZXNlbnRpbmcgdGhlIGxlc3MgdGhhbiBjb21wYXJpc29uXG4gICAgICovXG4gICAgbHQodmFsOiBhbnkpIHtcbiAgICAgIHJldHVybiB0aGlzLnNldE9wKE9wZXJhdG9yLlNNQUxMRVIsIHZhbCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGRlc2NyaXB0aW9uIENyZWF0ZXMgYSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gY29uZGl0aW9uXG4gICAgICogQHN1bW1hcnkgQnVpbGRzIGEgY29uZGl0aW9uIHRoYXQgY2hlY2tzIGlmIHRoZSBhdHRyaWJ1dGUgaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIHRoZSBzcGVjaWZpZWQgdmFsdWVcbiAgICAgKiBAcGFyYW0ge2FueX0gdmFsIC0gVGhlIHZhbHVlIHRvIGNvbXBhcmUgdGhlIGF0dHJpYnV0ZSBhZ2FpbnN0XG4gICAgICogQHJldHVybiB7Q29uZGl0aW9uPE0+fSBBIG5ldyBjb25kaXRpb24gcmVwcmVzZW50aW5nIHRoZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgY29tcGFyaXNvblxuICAgICAqL1xuICAgIGd0ZSh2YWw6IGFueSkge1xuICAgICAgcmV0dXJuIHRoaXMuc2V0T3AoT3BlcmF0b3IuQklHR0VSX0VRLCB2YWwpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBkZXNjcmlwdGlvbiBDcmVhdGVzIGEgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIGNvbmRpdGlvblxuICAgICAqIEBzdW1tYXJ5IEJ1aWxkcyBhIGNvbmRpdGlvbiB0aGF0IGNoZWNrcyBpZiB0aGUgYXR0cmlidXRlIGlzIGxlc3MgdGhhbiBvciBlcXVhbCB0byB0aGUgc3BlY2lmaWVkIHZhbHVlXG4gICAgICogQHBhcmFtIHthbnl9IHZhbCAtIFRoZSB2YWx1ZSB0byBjb21wYXJlIHRoZSBhdHRyaWJ1dGUgYWdhaW5zdFxuICAgICAqIEByZXR1cm4ge0NvbmRpdGlvbjxNPn0gQSBuZXcgY29uZGl0aW9uIHJlcHJlc2VudGluZyB0aGUgbGVzcyB0aGFuIG9yIGVxdWFsIGNvbXBhcmlzb25cbiAgICAgKi9cbiAgICBsdGUodmFsOiBhbnkpIHtcbiAgICAgIHJldHVybiB0aGlzLnNldE9wKE9wZXJhdG9yLlNNQUxMRVJfRVEsIHZhbCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGRlc2NyaXB0aW9uIENyZWF0ZXMgYW4gaW5jbHVzaW9uIGNvbmRpdGlvblxuICAgICAqIEBzdW1tYXJ5IEJ1aWxkcyBhIGNvbmRpdGlvbiB0aGF0IGNoZWNrcyBpZiB0aGUgYXR0cmlidXRlIHZhbHVlIGlzIGluY2x1ZGVkIGluIHRoZSBzcGVjaWZpZWQgYXJyYXlcbiAgICAgKiBAcGFyYW0ge2FueVtdfSBhcnIgLSBUaGUgYXJyYXkgb2YgdmFsdWVzIHRvIGNoZWNrIGFnYWluc3RcbiAgICAgKiBAcmV0dXJuIHtDb25kaXRpb248TT59IEEgbmV3IGNvbmRpdGlvbiByZXByZXNlbnRpbmcgdGhlIGluY2x1c2lvbiBjb21wYXJpc29uXG4gICAgICovXG4gICAgaW4oYXJyOiBhbnlbXSkge1xuICAgICAgcmV0dXJuIHRoaXMuc2V0T3AoT3BlcmF0b3IuSU4sIGFycik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGRlc2NyaXB0aW9uIENyZWF0ZXMgYSByZWd1bGFyIGV4cHJlc3Npb24gY29uZGl0aW9uXG4gICAgICogQHN1bW1hcnkgQnVpbGRzIGEgY29uZGl0aW9uIHRoYXQgY2hlY2tzIGlmIHRoZSBhdHRyaWJ1dGUgbWF0Y2hlcyB0aGUgc3BlY2lmaWVkIHJlZ3VsYXIgZXhwcmVzc2lvbiBwYXR0ZXJuXG4gICAgICogQHBhcmFtIHthbnl9IHZhbCAtIFRoZSByZWd1bGFyIGV4cHJlc3Npb24gcGF0dGVybiB0byBtYXRjaCBhZ2FpbnN0XG4gICAgICogQHJldHVybiB7Q29uZGl0aW9uPE0+fSBBIG5ldyBjb25kaXRpb24gcmVwcmVzZW50aW5nIHRoZSByZWd1bGFyIGV4cHJlc3Npb24gY29tcGFyaXNvblxuICAgICAqL1xuICAgIHJlZ2V4cCh2YWw6IGFueSkge1xuICAgICAgcmV0dXJuIHRoaXMuc2V0T3AoT3BlcmF0b3IuUkVHRVhQLCBuZXcgUmVnRXhwKHZhbCkuc291cmNlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAZGVzY3JpcHRpb24gU2V0cyB0aGUgb3BlcmF0b3IgYW5kIGNvbXBhcmlzb24gdmFsdWUgZm9yIHRoZSBjb25kaXRpb25cbiAgICAgKiBAc3VtbWFyeSBQcml2YXRlIG1ldGhvZCB0aGF0IGNvbmZpZ3VyZXMgdGhlIGNvbmRpdGlvbiB3aXRoIHRoZSBzcGVjaWZpZWQgb3BlcmF0b3IgYW5kIHZhbHVlXG4gICAgICogQHBhcmFtIHtPcGVyYXRvcn0gb3AgLSBUaGUgb3BlcmF0b3IgdG8gdXNlIGZvciB0aGUgY29uZGl0aW9uXG4gICAgICogQHBhcmFtIHthbnl9IHZhbCAtIFRoZSB2YWx1ZSB0byBjb21wYXJlIGFnYWluc3RcbiAgICAgKiBAcmV0dXJuIHtDb25kaXRpb248TT59IEEgbmV3IGNvbmRpdGlvbiB3aXRoIHRoZSBzcGVjaWZpZWQgb3BlcmF0b3IgYW5kIHZhbHVlXG4gICAgICovXG4gICAgcHJpdmF0ZSBzZXRPcChvcDogT3BlcmF0b3IsIHZhbDogYW55KSB7XG4gICAgICB0aGlzLm9wZXJhdG9yID0gb3A7XG4gICAgICB0aGlzLmNvbXBhcmlzb24gPSB2YWw7XG4gICAgICByZXR1cm4gdGhpcy5idWlsZCgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBkZXNjcmlwdGlvbiBDb25zdHJ1Y3RzIGEgQ29uZGl0aW9uIGluc3RhbmNlIGZyb20gdGhlIGJ1aWxkZXIncyBzdGF0ZVxuICAgICAqIEBzdW1tYXJ5IEZpbmFsaXplcyB0aGUgY29uZGl0aW9uIGJ1aWxkaW5nIHByb2Nlc3MgYnkgY3JlYXRpbmcgYSBuZXcgQ29uZGl0aW9uIGluc3RhbmNlXG4gICAgICogQHRocm93cyB7UXVlcnlFcnJvcn0gSWYgdGhlIGNvbmRpdGlvbiBjYW5ub3QgYmUgYnVpbHQgZHVlIHRvIGludmFsaWQgcGFyYW1ldGVyc1xuICAgICAqIEByZXR1cm4ge0NvbmRpdGlvbjxNPn0gQSBuZXcgY29uZGl0aW9uIGluc3RhbmNlIHdpdGggdGhlIGNvbmZpZ3VyZWQgYXR0cmlidXRlc1xuICAgICAqL1xuICAgIHByaXZhdGUgYnVpbGQoKTogQ29uZGl0aW9uPE0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBuZXcgQ29uZGl0aW9uKFxuICAgICAgICAgIHRoaXMuYXR0cjEgYXMgc3RyaW5nIHwgQ29uZGl0aW9uPE0+LFxuICAgICAgICAgIHRoaXMub3BlcmF0b3IgYXMgT3BlcmF0b3IsXG4gICAgICAgICAgdGhpcy5jb21wYXJpc29uIGFzIGFueVxuICAgICAgICApO1xuICAgICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICAgIHRocm93IG5ldyBRdWVyeUVycm9yKGUpO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENyZWF0ZXMgYSBuZXcgY29uZGl0aW9uIGJ1aWxkZXJcbiAgICogQHN1bW1hcnkgRmFjdG9yeSBtZXRob2QgdGhhdCByZXR1cm5zIGEgbmV3IGluc3RhbmNlIG9mIHRoZSBjb25kaXRpb24gYnVpbGRlclxuICAgKiBAdGVtcGxhdGUgTSAtIFRoZSBtb2RlbCB0eXBlIHRoaXMgY29uZGl0aW9uIGJ1aWxkZXIgd2lsbCBvcGVyYXRlIG9uXG4gICAqIEByZXR1cm4ge0NvbmRpdGlvbkJ1aWxkZXJPcHRpb248TT59IEEgbmV3IGNvbmRpdGlvbiBidWlsZGVyIGluc3RhbmNlXG4gICAqL1xuICBzdGF0aWMgYnVpbGRlcjxNIGV4dGVuZHMgTW9kZWw+KCk6IENvbmRpdGlvbkJ1aWxkZXJPcHRpb248TT4ge1xuICAgIHJldHVybiBuZXcgQ29uZGl0aW9uLkJ1aWxkZXI8TT4oKTtcbiAgfVxufVxuIiwiaW1wb3J0IHtcbiAgQ29uc3RydWN0b3IsXG4gIE1vZGVsLFxuICBNb2RlbENvbnN0cnVjdG9yLFxuICBWYWxpZGF0aW9uLFxuICBWYWxpZGF0aW9uS2V5cyxcbn0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgUmVwbywgUmVwb3NpdG9yeSB9IGZyb20gXCIuLi9yZXBvc2l0b3J5L1JlcG9zaXRvcnlcIjtcbmltcG9ydCB7IFJlbGF0aW9uc01ldGFkYXRhIH0gZnJvbSBcIi4vdHlwZXNcIjtcbmltcG9ydCB7XG4gIGZpbmRQcmltYXJ5S2V5LFxuICBJbnRlcm5hbEVycm9yLFxuICBOb3RGb3VuZEVycm9yLFxuICBSZXBvc2l0b3J5RmxhZ3MsXG59IGZyb20gXCJAZGVjYWYtdHMvZGItZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHsgUGVyc2lzdGVuY2VLZXlzIH0gZnJvbSBcIi4uL3BlcnNpc3RlbmNlL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgQ2FzY2FkZSB9IGZyb20gXCIuLi9yZXBvc2l0b3J5L2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgQ29udGV4dCB9IGZyb20gXCJAZGVjYWYtdHMvZGItZGVjb3JhdG9yc1wiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBDcmVhdGVzIG9yIHVwZGF0ZXMgYSBtb2RlbCBpbnN0YW5jZVxuICogQHN1bW1hcnkgRGV0ZXJtaW5lcyB3aGV0aGVyIHRvIGNyZWF0ZSBhIG5ldyBtb2RlbCBvciB1cGRhdGUgYW4gZXhpc3Rpbmcgb25lIGJhc2VkIG9uIHRoZSBwcmVzZW5jZSBvZiBhIHByaW1hcnkga2V5XG4gKiBAdGVtcGxhdGUgTSAtIFRoZSBtb2RlbCB0eXBlIGV4dGVuZGluZyBNb2RlbFxuICogQHRlbXBsYXRlIEYgLSBUaGUgcmVwb3NpdG9yeSBmbGFncyB0eXBlXG4gKiBAcGFyYW0ge019IG1vZGVsIC0gVGhlIG1vZGVsIGluc3RhbmNlIHRvIGNyZWF0ZSBvciB1cGRhdGVcbiAqIEBwYXJhbSB7Q29udGV4dDxGPn0gY29udGV4dCAtIFRoZSBjb250ZXh0IGZvciB0aGUgb3BlcmF0aW9uXG4gKiBAcGFyYW0ge1JlcG88TSwgRiwgQ29udGV4dDxGPj59IFtyZXBvc2l0b3J5XSAtIE9wdGlvbmFsIHJlcG9zaXRvcnkgdG8gdXNlIGZvciB0aGUgb3BlcmF0aW9uXG4gKiBAcmV0dXJuIHtQcm9taXNlPE0+fSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byB0aGUgY3JlYXRlZCBvciB1cGRhdGVkIG1vZGVsXG4gKiBAZnVuY3Rpb24gY3JlYXRlT3JVcGRhdGVcbiAqIEBtZW1iZXJPZiBtb2R1bGU6Y29yZVxuICogQG1lcm1haWRcbiAqIHNlcXVlbmNlRGlhZ3JhbVxuICogICBwYXJ0aWNpcGFudCBDYWxsZXJcbiAqICAgcGFydGljaXBhbnQgY3JlYXRlT3JVcGRhdGVcbiAqICAgcGFydGljaXBhbnQgUmVwb3NpdG9yeVxuICogICBwYXJ0aWNpcGFudCBNb2RlbFxuICpcbiAqICAgQ2FsbGVyLT4+Y3JlYXRlT3JVcGRhdGU6IG1vZGVsLCBjb250ZXh0LCByZXBvc2l0b3J5P1xuICogICBhbHQgcmVwb3NpdG9yeSBub3QgcHJvdmlkZWRcbiAqICAgICBjcmVhdGVPclVwZGF0ZS0+Pk1vZGVsOiBnZXQobW9kZWwuY29uc3RydWN0b3IubmFtZSlcbiAqICAgICBNb2RlbC0tPj5jcmVhdGVPclVwZGF0ZTogY29uc3RydWN0b3JcbiAqICAgICBjcmVhdGVPclVwZGF0ZS0+PlJlcG9zaXRvcnk6IGZvck1vZGVsKGNvbnN0cnVjdG9yKVxuICogICAgIFJlcG9zaXRvcnktLT4+Y3JlYXRlT3JVcGRhdGU6IHJlcG9zaXRvcnlcbiAqICAgZW5kXG4gKlxuICogICBhbHQgcHJpbWFyeSBrZXkgdW5kZWZpbmVkXG4gKiAgICAgY3JlYXRlT3JVcGRhdGUtPj5SZXBvc2l0b3J5OiBjcmVhdGUobW9kZWwsIGNvbnRleHQpXG4gKiAgICAgUmVwb3NpdG9yeS0tPj5jcmVhdGVPclVwZGF0ZTogY3JlYXRlZCBtb2RlbFxuICogICBlbHNlIHByaW1hcnkga2V5IGRlZmluZWRcbiAqICAgICBjcmVhdGVPclVwZGF0ZS0+PlJlcG9zaXRvcnk6IHVwZGF0ZShtb2RlbCwgY29udGV4dClcbiAqICAgICBhbHQgdXBkYXRlIHN1Y2Nlc3NmdWxcbiAqICAgICAgIFJlcG9zaXRvcnktLT4+Y3JlYXRlT3JVcGRhdGU6IHVwZGF0ZWQgbW9kZWxcbiAqICAgICBlbHNlIE5vdEZvdW5kRXJyb3JcbiAqICAgICAgIGNyZWF0ZU9yVXBkYXRlLT4+UmVwb3NpdG9yeTogY3JlYXRlKG1vZGVsLCBjb250ZXh0KVxuICogICAgICAgUmVwb3NpdG9yeS0tPj5jcmVhdGVPclVwZGF0ZTogY3JlYXRlZCBtb2RlbFxuICogICAgIGVuZFxuICogICBlbmRcbiAqXG4gKiAgIGNyZWF0ZU9yVXBkYXRlLS0+PkNhbGxlcjogbW9kZWxcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNyZWF0ZU9yVXBkYXRlPFxuICBNIGV4dGVuZHMgTW9kZWwsXG4gIEYgZXh0ZW5kcyBSZXBvc2l0b3J5RmxhZ3MsXG4+KFxuICBtb2RlbDogTSxcbiAgY29udGV4dDogQ29udGV4dDxGPixcbiAgcmVwb3NpdG9yeT86IFJlcG88TSwgRiwgQ29udGV4dDxGPj5cbik6IFByb21pc2U8TT4ge1xuICBpZiAoIXJlcG9zaXRvcnkpIHtcbiAgICBjb25zdCBjb25zdHJ1Y3RvciA9IE1vZGVsLmdldChtb2RlbC5jb25zdHJ1Y3Rvci5uYW1lKTtcbiAgICBpZiAoIWNvbnN0cnVjdG9yKVxuICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoYENvdWxkIG5vdCBmaW5kIG1vZGVsICR7bW9kZWwuY29uc3RydWN0b3IubmFtZX1gKTtcbiAgICByZXBvc2l0b3J5ID0gUmVwb3NpdG9yeS5mb3JNb2RlbDxNLCBSZXBvPE0+PihcbiAgICAgIGNvbnN0cnVjdG9yIGFzIHVua25vd24gYXMgTW9kZWxDb25zdHJ1Y3RvcjxNPlxuICAgICk7XG4gIH1cbiAgaWYgKHR5cGVvZiBtb2RlbFtyZXBvc2l0b3J5LnBrXSA9PT0gXCJ1bmRlZmluZWRcIilcbiAgICByZXR1cm4gcmVwb3NpdG9yeS5jcmVhdGUobW9kZWwsIGNvbnRleHQpO1xuICBlbHNlIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIHJlcG9zaXRvcnkudXBkYXRlKG1vZGVsLCBjb250ZXh0KTtcbiAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgIGlmICghKGUgaW5zdGFuY2VvZiBOb3RGb3VuZEVycm9yKSkgdGhyb3cgZTtcbiAgICAgIHJldHVybiByZXBvc2l0b3J5LmNyZWF0ZShtb2RlbCwgY29udGV4dCk7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEhhbmRsZXMgb25lLXRvLW9uZSByZWxhdGlvbnNoaXAgY3JlYXRpb25cbiAqIEBzdW1tYXJ5IFByb2Nlc3NlcyBhIG9uZS10by1vbmUgcmVsYXRpb25zaGlwIHdoZW4gY3JlYXRpbmcgYSBtb2RlbCwgZWl0aGVyIGJ5IHJlZmVyZW5jaW5nIGFuIGV4aXN0aW5nIG1vZGVsIG9yIGNyZWF0aW5nIGEgbmV3IG9uZVxuICogQHRlbXBsYXRlIE0gLSBUaGUgbW9kZWwgdHlwZSBleHRlbmRpbmcgTW9kZWxcbiAqIEB0ZW1wbGF0ZSBSIC0gVGhlIHJlcG9zaXRvcnkgdHlwZSBleHRlbmRpbmcgUmVwbzxNLCBGLCBDPlxuICogQHRlbXBsYXRlIFYgLSBUaGUgcmVsYXRpb25zIG1ldGFkYXRhIHR5cGUgZXh0ZW5kaW5nIFJlbGF0aW9uc01ldGFkYXRhXG4gKiBAdGVtcGxhdGUgRiAtIFRoZSByZXBvc2l0b3J5IGZsYWdzIHR5cGVcbiAqIEB0ZW1wbGF0ZSBDIC0gVGhlIGNvbnRleHQgdHlwZSBleHRlbmRpbmcgQ29udGV4dDxGPlxuICogQHBhcmFtIHtSfSB0aGlzIC0gVGhlIHJlcG9zaXRvcnkgaW5zdGFuY2VcbiAqIEBwYXJhbSB7Q29udGV4dDxGPn0gY29udGV4dCAtIFRoZSBjb250ZXh0IGZvciB0aGUgb3BlcmF0aW9uXG4gKiBAcGFyYW0ge1Z9IGRhdGEgLSBUaGUgcmVsYXRpb25zIG1ldGFkYXRhXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IC0gVGhlIHByb3BlcnR5IGtleSBvZiB0aGUgcmVsYXRpb25zaGlwXG4gKiBAcGFyYW0ge019IG1vZGVsIC0gVGhlIG1vZGVsIGluc3RhbmNlXG4gKiBAcmV0dXJuIHtQcm9taXNlPHZvaWQ+fSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIHRoZSBvcGVyYXRpb24gaXMgY29tcGxldGVcbiAqIEBmdW5jdGlvbiBvbmVUb09uZU9uQ3JlYXRlXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmNvcmVcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgQ2FsbGVyXG4gKiAgIHBhcnRpY2lwYW50IG9uZVRvT25lT25DcmVhdGVcbiAqICAgcGFydGljaXBhbnQgcmVwb3NpdG9yeUZyb21UeXBlTWV0YWRhdGFcbiAqICAgcGFydGljaXBhbnQgTW9kZWxcbiAqICAgcGFydGljaXBhbnQgUmVwb3NpdG9yeVxuICogICBwYXJ0aWNpcGFudCBjYWNoZU1vZGVsRm9yUG9wdWxhdGVcbiAqXG4gKiAgIENhbGxlci0+Pm9uZVRvT25lT25DcmVhdGU6IHRoaXMsIGNvbnRleHQsIGRhdGEsIGtleSwgbW9kZWxcbiAqICAgb25lVG9PbmVPbkNyZWF0ZS0+Pm9uZVRvT25lT25DcmVhdGU6IGNoZWNrIGlmIHByb3BlcnR5VmFsdWUgZXhpc3RzXG4gKlxuICogICBhbHQgcHJvcGVydHlWYWx1ZSBpcyBub3QgYW4gb2JqZWN0XG4gKiAgICAgb25lVG9PbmVPbkNyZWF0ZS0+PnJlcG9zaXRvcnlGcm9tVHlwZU1ldGFkYXRhOiBtb2RlbCwga2V5XG4gKiAgICAgcmVwb3NpdG9yeUZyb21UeXBlTWV0YWRhdGEtLT4+b25lVG9PbmVPbkNyZWF0ZTogaW5uZXJSZXBvXG4gKiAgICAgb25lVG9PbmVPbkNyZWF0ZS0+PmlubmVyUmVwbzogcmVhZChwcm9wZXJ0eVZhbHVlKVxuICogICAgIGlubmVyUmVwby0tPj5vbmVUb09uZU9uQ3JlYXRlOiByZWFkXG4gKiAgICAgb25lVG9PbmVPbkNyZWF0ZS0+PmNhY2hlTW9kZWxGb3JQb3B1bGF0ZTogY29udGV4dCwgbW9kZWwsIGtleSwgcHJvcGVydHlWYWx1ZSwgcmVhZFxuICogICAgIG9uZVRvT25lT25DcmVhdGUtPj5vbmVUb09uZU9uQ3JlYXRlOiBzZXQgbW9kZWxba2V5XSA9IHByb3BlcnR5VmFsdWVcbiAqICAgZWxzZSBwcm9wZXJ0eVZhbHVlIGlzIGFuIG9iamVjdFxuICogICAgIG9uZVRvT25lT25DcmVhdGUtPj5Nb2RlbDogZ2V0KGRhdGEuY2xhc3MpXG4gKiAgICAgTW9kZWwtLT4+b25lVG9PbmVPbkNyZWF0ZTogY29uc3RydWN0b3JcbiAqICAgICBvbmVUb09uZU9uQ3JlYXRlLT4+UmVwb3NpdG9yeTogZm9yTW9kZWwoY29uc3RydWN0b3IpXG4gKiAgICAgUmVwb3NpdG9yeS0tPj5vbmVUb09uZU9uQ3JlYXRlOiByZXBvXG4gKiAgICAgb25lVG9PbmVPbkNyZWF0ZS0+PnJlcG86IGNyZWF0ZShwcm9wZXJ0eVZhbHVlKVxuICogICAgIHJlcG8tLT4+b25lVG9PbmVPbkNyZWF0ZTogY3JlYXRlZFxuICogICAgIG9uZVRvT25lT25DcmVhdGUtPj5maW5kUHJpbWFyeUtleTogY3JlYXRlZFxuICogICAgIGZpbmRQcmltYXJ5S2V5LS0+Pm9uZVRvT25lT25DcmVhdGU6IHBrXG4gKiAgICAgb25lVG9PbmVPbkNyZWF0ZS0+PmNhY2hlTW9kZWxGb3JQb3B1bGF0ZTogY29udGV4dCwgbW9kZWwsIGtleSwgY3JlYXRlZFtwa10sIGNyZWF0ZWRcbiAqICAgICBvbmVUb09uZU9uQ3JlYXRlLT4+b25lVG9PbmVPbkNyZWF0ZTogc2V0IG1vZGVsW2tleV0gPSBjcmVhdGVkW3BrXVxuICogICBlbmRcbiAqXG4gKiAgIG9uZVRvT25lT25DcmVhdGUtLT4+Q2FsbGVyOiB2b2lkXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBvbmVUb09uZU9uQ3JlYXRlPFxuICBNIGV4dGVuZHMgTW9kZWwsXG4gIFIgZXh0ZW5kcyBSZXBvPE0sIEYsIEM+LFxuICBWIGV4dGVuZHMgUmVsYXRpb25zTWV0YWRhdGEsXG4gIEYgZXh0ZW5kcyBSZXBvc2l0b3J5RmxhZ3MsXG4gIEMgZXh0ZW5kcyBDb250ZXh0PEY+LFxuPihcbiAgdGhpczogUixcbiAgY29udGV4dDogQ29udGV4dDxGPixcbiAgZGF0YTogVixcbiAga2V5OiBrZXlvZiBNLFxuICBtb2RlbDogTVxuKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IHByb3BlcnR5VmFsdWU6IGFueSA9IG1vZGVsW2tleV07XG4gIGlmICghcHJvcGVydHlWYWx1ZSkgcmV0dXJuO1xuXG4gIGlmICh0eXBlb2YgcHJvcGVydHlWYWx1ZSAhPT0gXCJvYmplY3RcIikge1xuICAgIGNvbnN0IGlubmVyUmVwbyA9IHJlcG9zaXRvcnlGcm9tVHlwZU1ldGFkYXRhKG1vZGVsLCBrZXkpO1xuICAgIGNvbnN0IHJlYWQgPSBhd2FpdCBpbm5lclJlcG8ucmVhZChwcm9wZXJ0eVZhbHVlKTtcbiAgICBhd2FpdCBjYWNoZU1vZGVsRm9yUG9wdWxhdGUoY29udGV4dCwgbW9kZWwsIGtleSwgcHJvcGVydHlWYWx1ZSwgcmVhZCk7XG4gICAgKG1vZGVsIGFzIGFueSlba2V5XSA9IHByb3BlcnR5VmFsdWU7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgY29uc3QgY29uc3RydWN0b3IgPSBNb2RlbC5nZXQoZGF0YS5jbGFzcyk7XG4gIGlmICghY29uc3RydWN0b3IpXG4gICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoYENvdWxkIG5vdCBmaW5kIG1vZGVsICR7ZGF0YS5jbGFzc31gKTtcbiAgY29uc3QgcmVwbzogUmVwbzxhbnk+ID0gUmVwb3NpdG9yeS5mb3JNb2RlbChjb25zdHJ1Y3Rvcik7XG4gIGNvbnN0IGNyZWF0ZWQgPSBhd2FpdCByZXBvLmNyZWF0ZShwcm9wZXJ0eVZhbHVlKTtcbiAgY29uc3QgcGsgPSBmaW5kUHJpbWFyeUtleShjcmVhdGVkKS5pZDtcbiAgYXdhaXQgY2FjaGVNb2RlbEZvclBvcHVsYXRlKGNvbnRleHQsIG1vZGVsLCBrZXksIGNyZWF0ZWRbcGtdLCBjcmVhdGVkKTtcbiAgKG1vZGVsIGFzIGFueSlba2V5XSA9IGNyZWF0ZWRbcGtdO1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBIYW5kbGVzIG9uZS10by1vbmUgcmVsYXRpb25zaGlwIHVwZGF0ZXNcbiAqIEBzdW1tYXJ5IFByb2Nlc3NlcyBhIG9uZS10by1vbmUgcmVsYXRpb25zaGlwIHdoZW4gdXBkYXRpbmcgYSBtb2RlbCwgZWl0aGVyIGJ5IHJlZmVyZW5jaW5nIGFuIGV4aXN0aW5nIG1vZGVsIG9yIHVwZGF0aW5nIHRoZSByZWxhdGVkIG1vZGVsXG4gKiBAdGVtcGxhdGUgTSAtIFRoZSBtb2RlbCB0eXBlIGV4dGVuZGluZyBNb2RlbFxuICogQHRlbXBsYXRlIFIgLSBUaGUgcmVwb3NpdG9yeSB0eXBlIGV4dGVuZGluZyBSZXBvPE0sIEYsIEM+XG4gKiBAdGVtcGxhdGUgViAtIFRoZSByZWxhdGlvbnMgbWV0YWRhdGEgdHlwZSBleHRlbmRpbmcgUmVsYXRpb25zTWV0YWRhdGFcbiAqIEB0ZW1wbGF0ZSBGIC0gVGhlIHJlcG9zaXRvcnkgZmxhZ3MgdHlwZVxuICogQHRlbXBsYXRlIEMgLSBUaGUgY29udGV4dCB0eXBlIGV4dGVuZGluZyBDb250ZXh0PEY+XG4gKiBAcGFyYW0ge1J9IHRoaXMgLSBUaGUgcmVwb3NpdG9yeSBpbnN0YW5jZVxuICogQHBhcmFtIHtDb250ZXh0PEY+fSBjb250ZXh0IC0gVGhlIGNvbnRleHQgZm9yIHRoZSBvcGVyYXRpb25cbiAqIEBwYXJhbSB7Vn0gZGF0YSAtIFRoZSByZWxhdGlvbnMgbWV0YWRhdGFcbiAqIEBwYXJhbSBrZXkgLSBUaGUgcHJvcGVydHkga2V5IG9mIHRoZSByZWxhdGlvbnNoaXBcbiAqIEBwYXJhbSB7TX0gbW9kZWwgLSBUaGUgbW9kZWwgaW5zdGFuY2VcbiAqIEByZXR1cm4ge1Byb21pc2U8dm9pZD59IEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdoZW4gdGhlIG9wZXJhdGlvbiBpcyBjb21wbGV0ZVxuICogQGZ1bmN0aW9uIG9uZVRvT25lT25VcGRhdGVcbiAqIEBtZW1iZXJPZiBtb2R1bGU6Y29yZVxuICogQG1lcm1haWRcbiAqIHNlcXVlbmNlRGlhZ3JhbVxuICogICBwYXJ0aWNpcGFudCBDYWxsZXJcbiAqICAgcGFydGljaXBhbnQgb25lVG9PbmVPblVwZGF0ZVxuICogICBwYXJ0aWNpcGFudCByZXBvc2l0b3J5RnJvbVR5cGVNZXRhZGF0YVxuICogICBwYXJ0aWNpcGFudCBjcmVhdGVPclVwZGF0ZVxuICogICBwYXJ0aWNpcGFudCBmaW5kUHJpbWFyeUtleVxuICogICBwYXJ0aWNpcGFudCBjYWNoZU1vZGVsRm9yUG9wdWxhdGVcbiAqXG4gKiAgIENhbGxlci0+Pm9uZVRvT25lT25VcGRhdGU6IHRoaXMsIGNvbnRleHQsIGRhdGEsIGtleSwgbW9kZWxcbiAqICAgb25lVG9PbmVPblVwZGF0ZS0+Pm9uZVRvT25lT25VcGRhdGU6IGNoZWNrIGlmIHByb3BlcnR5VmFsdWUgZXhpc3RzXG4gKiAgIG9uZVRvT25lT25VcGRhdGUtPj5vbmVUb09uZU9uVXBkYXRlOiBjaGVjayBpZiBjYXNjYWRlLnVwZGF0ZSBpcyBDQVNDQURFXG4gKlxuICogICBhbHQgcHJvcGVydHlWYWx1ZSBpcyBub3QgYW4gb2JqZWN0XG4gKiAgICAgb25lVG9PbmVPblVwZGF0ZS0+PnJlcG9zaXRvcnlGcm9tVHlwZU1ldGFkYXRhOiBtb2RlbCwga2V5XG4gKiAgICAgcmVwb3NpdG9yeUZyb21UeXBlTWV0YWRhdGEtLT4+b25lVG9PbmVPblVwZGF0ZTogaW5uZXJSZXBvXG4gKiAgICAgb25lVG9PbmVPblVwZGF0ZS0+PmlubmVyUmVwbzogcmVhZChwcm9wZXJ0eVZhbHVlKVxuICogICAgIGlubmVyUmVwby0tPj5vbmVUb09uZU9uVXBkYXRlOiByZWFkXG4gKiAgICAgb25lVG9PbmVPblVwZGF0ZS0+PmNhY2hlTW9kZWxGb3JQb3B1bGF0ZTogY29udGV4dCwgbW9kZWwsIGtleSwgcHJvcGVydHlWYWx1ZSwgcmVhZFxuICogICAgIG9uZVRvT25lT25VcGRhdGUtPj5vbmVUb09uZU9uVXBkYXRlOiBzZXQgbW9kZWxba2V5XSA9IHByb3BlcnR5VmFsdWVcbiAqICAgZWxzZSBwcm9wZXJ0eVZhbHVlIGlzIGFuIG9iamVjdFxuICogICAgIG9uZVRvT25lT25VcGRhdGUtPj5jcmVhdGVPclVwZGF0ZTogbW9kZWxba2V5XSwgY29udGV4dFxuICogICAgIGNyZWF0ZU9yVXBkYXRlLS0+Pm9uZVRvT25lT25VcGRhdGU6IHVwZGF0ZWRcbiAqICAgICBvbmVUb09uZU9uVXBkYXRlLT4+ZmluZFByaW1hcnlLZXk6IHVwZGF0ZWRcbiAqICAgICBmaW5kUHJpbWFyeUtleS0tPj5vbmVUb09uZU9uVXBkYXRlOiBwa1xuICogICAgIG9uZVRvT25lT25VcGRhdGUtPj5jYWNoZU1vZGVsRm9yUG9wdWxhdGU6IGNvbnRleHQsIG1vZGVsLCBrZXksIHVwZGF0ZWRbcGtdLCB1cGRhdGVkXG4gKiAgICAgb25lVG9PbmVPblVwZGF0ZS0+Pm9uZVRvT25lT25VcGRhdGU6IHNldCBtb2RlbFtrZXldID0gdXBkYXRlZFtwa11cbiAqICAgZW5kXG4gKlxuICogICBvbmVUb09uZU9uVXBkYXRlLS0+PkNhbGxlcjogdm9pZFxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gb25lVG9PbmVPblVwZGF0ZTxcbiAgTSBleHRlbmRzIE1vZGVsLFxuICBSIGV4dGVuZHMgUmVwbzxNLCBGLCBDPixcbiAgViBleHRlbmRzIFJlbGF0aW9uc01ldGFkYXRhLFxuICBGIGV4dGVuZHMgUmVwb3NpdG9yeUZsYWdzLFxuICBDIGV4dGVuZHMgQ29udGV4dDxGPixcbj4oXG4gIHRoaXM6IFIsXG4gIGNvbnRleHQ6IENvbnRleHQ8Rj4sXG4gIGRhdGE6IFYsXG4gIGtleToga2V5b2YgTSxcbiAgbW9kZWw6IE1cbik6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCBwcm9wZXJ0eVZhbHVlOiBhbnkgPSBtb2RlbFtrZXldO1xuICBpZiAoIXByb3BlcnR5VmFsdWUpIHJldHVybjtcbiAgaWYgKGRhdGEuY2FzY2FkZS51cGRhdGUgIT09IENhc2NhZGUuQ0FTQ0FERSkgcmV0dXJuO1xuXG4gIGlmICh0eXBlb2YgcHJvcGVydHlWYWx1ZSAhPT0gXCJvYmplY3RcIikge1xuICAgIGNvbnN0IGlubmVyUmVwbyA9IHJlcG9zaXRvcnlGcm9tVHlwZU1ldGFkYXRhKG1vZGVsLCBrZXkpO1xuICAgIGNvbnN0IHJlYWQgPSBhd2FpdCBpbm5lclJlcG8ucmVhZChwcm9wZXJ0eVZhbHVlKTtcbiAgICBhd2FpdCBjYWNoZU1vZGVsRm9yUG9wdWxhdGUoY29udGV4dCwgbW9kZWwsIGtleSwgcHJvcGVydHlWYWx1ZSwgcmVhZCk7XG4gICAgKG1vZGVsIGFzIGFueSlba2V5XSA9IHByb3BlcnR5VmFsdWU7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgY29uc3QgdXBkYXRlZCA9IGF3YWl0IGNyZWF0ZU9yVXBkYXRlKG1vZGVsW2tleV0gYXMgTSwgY29udGV4dCk7XG4gIGNvbnN0IHBrID0gZmluZFByaW1hcnlLZXkodXBkYXRlZCkuaWQ7XG4gIGF3YWl0IGNhY2hlTW9kZWxGb3JQb3B1bGF0ZShcbiAgICBjb250ZXh0LFxuICAgIG1vZGVsLFxuICAgIGtleSxcbiAgICB1cGRhdGVkW3BrXSBhcyBzdHJpbmcsXG4gICAgdXBkYXRlZFxuICApO1xuICBtb2RlbFtrZXldID0gdXBkYXRlZFtwa107XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEhhbmRsZXMgb25lLXRvLW9uZSByZWxhdGlvbnNoaXAgZGVsZXRpb25cbiAqIEBzdW1tYXJ5IFByb2Nlc3NlcyBhIG9uZS10by1vbmUgcmVsYXRpb25zaGlwIHdoZW4gZGVsZXRpbmcgYSBtb2RlbCwgZGVsZXRpbmcgdGhlIHJlbGF0ZWQgbW9kZWwgaWYgY2FzY2FkZSBpcyBlbmFibGVkXG4gKiBAdGVtcGxhdGUgTSAtIFRoZSBtb2RlbCB0eXBlIGV4dGVuZGluZyBNb2RlbFxuICogQHRlbXBsYXRlIFIgLSBUaGUgcmVwb3NpdG9yeSB0eXBlIGV4dGVuZGluZyBSZXBvPE0sIEYsIEM+XG4gKiBAdGVtcGxhdGUgViAtIFRoZSByZWxhdGlvbnMgbWV0YWRhdGEgdHlwZSBleHRlbmRpbmcgUmVsYXRpb25zTWV0YWRhdGFcbiAqIEB0ZW1wbGF0ZSBGIC0gVGhlIHJlcG9zaXRvcnkgZmxhZ3MgdHlwZVxuICogQHRlbXBsYXRlIEMgLSBUaGUgY29udGV4dCB0eXBlIGV4dGVuZGluZyBDb250ZXh0PEY+XG4gKiBAcGFyYW0ge1J9IHRoaXMgLSBUaGUgcmVwb3NpdG9yeSBpbnN0YW5jZVxuICogQHBhcmFtIHtDb250ZXh0PEY+fSBjb250ZXh0IC0gVGhlIGNvbnRleHQgZm9yIHRoZSBvcGVyYXRpb25cbiAqIEBwYXJhbSB7Vn0gZGF0YSAtIFRoZSByZWxhdGlvbnMgbWV0YWRhdGFcbiAqIEBwYXJhbSBrZXkgLSBUaGUgcHJvcGVydHkga2V5IG9mIHRoZSByZWxhdGlvbnNoaXBcbiAqIEBwYXJhbSB7TX0gbW9kZWwgLSBUaGUgbW9kZWwgaW5zdGFuY2VcbiAqIEByZXR1cm4ge1Byb21pc2U8dm9pZD59IEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdoZW4gdGhlIG9wZXJhdGlvbiBpcyBjb21wbGV0ZVxuICogQGZ1bmN0aW9uIG9uZVRvT25lT25EZWxldGVcbiAqIEBtZW1iZXJPZiBtb2R1bGU6Y29yZVxuICogQG1lcm1haWRcbiAqIHNlcXVlbmNlRGlhZ3JhbVxuICogICBwYXJ0aWNpcGFudCBDYWxsZXJcbiAqICAgcGFydGljaXBhbnQgb25lVG9PbmVPbkRlbGV0ZVxuICogICBwYXJ0aWNpcGFudCByZXBvc2l0b3J5RnJvbVR5cGVNZXRhZGF0YVxuICogICBwYXJ0aWNpcGFudCBjYWNoZU1vZGVsRm9yUG9wdWxhdGVcbiAqXG4gKiAgIENhbGxlci0+Pm9uZVRvT25lT25EZWxldGU6IHRoaXMsIGNvbnRleHQsIGRhdGEsIGtleSwgbW9kZWxcbiAqICAgb25lVG9PbmVPbkRlbGV0ZS0+Pm9uZVRvT25lT25EZWxldGU6IGNoZWNrIGlmIHByb3BlcnR5VmFsdWUgZXhpc3RzXG4gKiAgIG9uZVRvT25lT25EZWxldGUtPj5vbmVUb09uZU9uRGVsZXRlOiBjaGVjayBpZiBjYXNjYWRlLnVwZGF0ZSBpcyBDQVNDQURFXG4gKlxuICogICBvbmVUb09uZU9uRGVsZXRlLT4+cmVwb3NpdG9yeUZyb21UeXBlTWV0YWRhdGE6IG1vZGVsLCBrZXlcbiAqICAgcmVwb3NpdG9yeUZyb21UeXBlTWV0YWRhdGEtLT4+b25lVG9PbmVPbkRlbGV0ZTogaW5uZXJSZXBvXG4gKlxuICogICBhbHQgcHJvcGVydHlWYWx1ZSBpcyBub3QgYSBNb2RlbCBpbnN0YW5jZVxuICogICAgIG9uZVRvT25lT25EZWxldGUtPj5pbm5lclJlcG86IGRlbGV0ZShtb2RlbFtrZXldLCBjb250ZXh0KVxuICogICAgIGlubmVyUmVwby0tPj5vbmVUb09uZU9uRGVsZXRlOiBkZWxldGVkXG4gKiAgIGVsc2UgcHJvcGVydHlWYWx1ZSBpcyBhIE1vZGVsIGluc3RhbmNlXG4gKiAgICAgb25lVG9PbmVPbkRlbGV0ZS0+PmlubmVyUmVwbzogZGVsZXRlKG1vZGVsW2tleV1baW5uZXJSZXBvLnBrXSwgY29udGV4dClcbiAqICAgICBpbm5lclJlcG8tLT4+b25lVG9PbmVPbkRlbGV0ZTogZGVsZXRlZFxuICogICBlbmRcbiAqXG4gKiAgIG9uZVRvT25lT25EZWxldGUtPj5jYWNoZU1vZGVsRm9yUG9wdWxhdGU6IGNvbnRleHQsIG1vZGVsLCBrZXksIGRlbGV0ZWRbaW5uZXJSZXBvLnBrXSwgZGVsZXRlZFxuICogICBvbmVUb09uZU9uRGVsZXRlLS0+PkNhbGxlcjogdm9pZFxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gb25lVG9PbmVPbkRlbGV0ZTxcbiAgTSBleHRlbmRzIE1vZGVsLFxuICBSIGV4dGVuZHMgUmVwbzxNLCBGLCBDPixcbiAgViBleHRlbmRzIFJlbGF0aW9uc01ldGFkYXRhLFxuICBGIGV4dGVuZHMgUmVwb3NpdG9yeUZsYWdzLFxuICBDIGV4dGVuZHMgQ29udGV4dDxGPixcbj4oXG4gIHRoaXM6IFIsXG4gIGNvbnRleHQ6IENvbnRleHQ8Rj4sXG4gIGRhdGE6IFYsXG4gIGtleToga2V5b2YgTSxcbiAgbW9kZWw6IE1cbik6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCBwcm9wZXJ0eVZhbHVlOiBhbnkgPSBtb2RlbFtrZXldO1xuICBpZiAoIXByb3BlcnR5VmFsdWUpIHJldHVybjtcbiAgaWYgKGRhdGEuY2FzY2FkZS51cGRhdGUgIT09IENhc2NhZGUuQ0FTQ0FERSkgcmV0dXJuO1xuICBjb25zdCBpbm5lclJlcG86IFJlcG88TT4gPSByZXBvc2l0b3J5RnJvbVR5cGVNZXRhZGF0YShtb2RlbCwga2V5KTtcbiAgbGV0IGRlbGV0ZWQ6IE07XG4gIGlmICghKHByb3BlcnR5VmFsdWUgaW5zdGFuY2VvZiBNb2RlbCkpXG4gICAgZGVsZXRlZCA9IGF3YWl0IGlubmVyUmVwby5kZWxldGUobW9kZWxba2V5XSBhcyBzdHJpbmcsIGNvbnRleHQpO1xuICBlbHNlXG4gICAgZGVsZXRlZCA9IGF3YWl0IGlubmVyUmVwby5kZWxldGUoXG4gICAgICAobW9kZWxba2V5XSBhcyBNKVtpbm5lclJlcG8ucGsgYXMga2V5b2YgTV0gYXMgc3RyaW5nLFxuICAgICAgY29udGV4dFxuICAgICk7XG4gIGF3YWl0IGNhY2hlTW9kZWxGb3JQb3B1bGF0ZShcbiAgICBjb250ZXh0LFxuICAgIG1vZGVsLFxuICAgIGtleSxcbiAgICBkZWxldGVkW2lubmVyUmVwby5wa10gYXMgc3RyaW5nLFxuICAgIGRlbGV0ZWRcbiAgKTtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gSGFuZGxlcyBvbmUtdG8tbWFueSByZWxhdGlvbnNoaXAgY3JlYXRpb25cbiAqIEBzdW1tYXJ5IFByb2Nlc3NlcyBhIG9uZS10by1tYW55IHJlbGF0aW9uc2hpcCB3aGVuIGNyZWF0aW5nIGEgbW9kZWwsIGVpdGhlciBieSByZWZlcmVuY2luZyBleGlzdGluZyBtb2RlbHMgb3IgY3JlYXRpbmcgbmV3IG9uZXNcbiAqIEB0ZW1wbGF0ZSBNIC0gVGhlIG1vZGVsIHR5cGUgZXh0ZW5kaW5nIE1vZGVsXG4gKiBAdGVtcGxhdGUgUiAtIFRoZSByZXBvc2l0b3J5IHR5cGUgZXh0ZW5kaW5nIFJlcG88TSwgRiwgQz5cbiAqIEB0ZW1wbGF0ZSBWIC0gVGhlIHJlbGF0aW9ucyBtZXRhZGF0YSB0eXBlIGV4dGVuZGluZyBSZWxhdGlvbnNNZXRhZGF0YVxuICogQHRlbXBsYXRlIEYgLSBUaGUgcmVwb3NpdG9yeSBmbGFncyB0eXBlXG4gKiBAdGVtcGxhdGUgQyAtIFRoZSBjb250ZXh0IHR5cGUgZXh0ZW5kaW5nIENvbnRleHQ8Rj5cbiAqIEBwYXJhbSB7Un0gdGhpcyAtIFRoZSByZXBvc2l0b3J5IGluc3RhbmNlXG4gKiBAcGFyYW0ge0NvbnRleHQ8Rj59IGNvbnRleHQgLSBUaGUgY29udGV4dCBmb3IgdGhlIG9wZXJhdGlvblxuICogQHBhcmFtIHtWfSBkYXRhIC0gVGhlIHJlbGF0aW9ucyBtZXRhZGF0YVxuICogQHBhcmFtIGtleSAtIFRoZSBwcm9wZXJ0eSBrZXkgb2YgdGhlIHJlbGF0aW9uc2hpcFxuICogQHBhcmFtIHtNfSBtb2RlbCAtIFRoZSBtb2RlbCBpbnN0YW5jZVxuICogQHJldHVybiB7UHJvbWlzZTx2b2lkPn0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiB0aGUgb3BlcmF0aW9uIGlzIGNvbXBsZXRlXG4gKiBAZnVuY3Rpb24gb25lVG9NYW55T25DcmVhdGVcbiAqIEBtZW1iZXJPZiBtb2R1bGU6Y29yZVxuICogQG1lcm1haWRcbiAqIHNlcXVlbmNlRGlhZ3JhbVxuICogICBwYXJ0aWNpcGFudCBDYWxsZXJcbiAqICAgcGFydGljaXBhbnQgb25lVG9NYW55T25DcmVhdGVcbiAqICAgcGFydGljaXBhbnQgcmVwb3NpdG9yeUZyb21UeXBlTWV0YWRhdGFcbiAqICAgcGFydGljaXBhbnQgY3JlYXRlT3JVcGRhdGVcbiAqICAgcGFydGljaXBhbnQgZmluZFByaW1hcnlLZXlcbiAqICAgcGFydGljaXBhbnQgY2FjaGVNb2RlbEZvclBvcHVsYXRlXG4gKlxuICogICBDYWxsZXItPj5vbmVUb01hbnlPbkNyZWF0ZTogdGhpcywgY29udGV4dCwgZGF0YSwga2V5LCBtb2RlbFxuICogICBvbmVUb01hbnlPbkNyZWF0ZS0+Pm9uZVRvTWFueU9uQ3JlYXRlOiBjaGVjayBpZiBwcm9wZXJ0eVZhbHVlcyBleGlzdHMgYW5kIGhhcyBsZW5ndGhcbiAqICAgb25lVG9NYW55T25DcmVhdGUtPj5vbmVUb01hbnlPbkNyZWF0ZTogY2hlY2sgaWYgYWxsIGVsZW1lbnRzIGhhdmUgc2FtZSB0eXBlXG4gKiAgIG9uZVRvTWFueU9uQ3JlYXRlLT4+b25lVG9NYW55T25DcmVhdGU6IGNyZWF0ZSB1bmlxdWVWYWx1ZXMgc2V0XG4gKlxuICogICBhbHQgYXJyYXlUeXBlIGlzIG5vdCBcIm9iamVjdFwiXG4gKiAgICAgb25lVG9NYW55T25DcmVhdGUtPj5yZXBvc2l0b3J5RnJvbVR5cGVNZXRhZGF0YTogbW9kZWwsIGtleVxuICogICAgIHJlcG9zaXRvcnlGcm9tVHlwZU1ldGFkYXRhLS0+Pm9uZVRvTWFueU9uQ3JlYXRlOiByZXBvXG4gKiAgICAgbG9vcCBmb3IgZWFjaCBpZCBpbiB1bmlxdWVWYWx1ZXNcbiAqICAgICAgIG9uZVRvTWFueU9uQ3JlYXRlLT4+cmVwbzogcmVhZChpZClcbiAqICAgICAgIHJlcG8tLT4+b25lVG9NYW55T25DcmVhdGU6IHJlYWRcbiAqICAgICAgIG9uZVRvTWFueU9uQ3JlYXRlLT4+Y2FjaGVNb2RlbEZvclBvcHVsYXRlOiBjb250ZXh0LCBtb2RlbCwga2V5LCBpZCwgcmVhZFxuICogICAgIGVuZFxuICogICAgIG9uZVRvTWFueU9uQ3JlYXRlLT4+b25lVG9NYW55T25DcmVhdGU6IHNldCBtb2RlbFtrZXldID0gWy4uLnVuaXF1ZVZhbHVlc11cbiAqICAgZWxzZSBhcnJheVR5cGUgaXMgXCJvYmplY3RcIlxuICogICAgIG9uZVRvTWFueU9uQ3JlYXRlLT4+ZmluZFByaW1hcnlLZXk6IHByb3BlcnR5VmFsdWVzWzBdXG4gKiAgICAgZmluZFByaW1hcnlLZXktLT4+b25lVG9NYW55T25DcmVhdGU6IHBrTmFtZVxuICogICAgIG9uZVRvTWFueU9uQ3JlYXRlLT4+b25lVG9NYW55T25DcmVhdGU6IGNyZWF0ZSByZXN1bHQgc2V0XG4gKiAgICAgbG9vcCBmb3IgZWFjaCBtIGluIHByb3BlcnR5VmFsdWVzXG4gKiAgICAgICBvbmVUb01hbnlPbkNyZWF0ZS0+PmNyZWF0ZU9yVXBkYXRlOiBtLCBjb250ZXh0XG4gKiAgICAgICBjcmVhdGVPclVwZGF0ZS0tPj5vbmVUb01hbnlPbkNyZWF0ZTogcmVjb3JkXG4gKiAgICAgICBvbmVUb01hbnlPbkNyZWF0ZS0+PmNhY2hlTW9kZWxGb3JQb3B1bGF0ZTogY29udGV4dCwgbW9kZWwsIGtleSwgcmVjb3JkW3BrTmFtZV0sIHJlY29yZFxuICogICAgICAgb25lVG9NYW55T25DcmVhdGUtPj5vbmVUb01hbnlPbkNyZWF0ZTogYWRkIHJlY29yZFtwa05hbWVdIHRvIHJlc3VsdFxuICogICAgIGVuZFxuICogICAgIG9uZVRvTWFueU9uQ3JlYXRlLT4+b25lVG9NYW55T25DcmVhdGU6IHNldCBtb2RlbFtrZXldID0gWy4uLnJlc3VsdF1cbiAqICAgZW5kXG4gKlxuICogICBvbmVUb01hbnlPbkNyZWF0ZS0tPj5DYWxsZXI6IHZvaWRcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIG9uZVRvTWFueU9uQ3JlYXRlPFxuICBNIGV4dGVuZHMgTW9kZWwsXG4gIFIgZXh0ZW5kcyBSZXBvPE0sIEYsIEM+LFxuICBWIGV4dGVuZHMgUmVsYXRpb25zTWV0YWRhdGEsXG4gIEYgZXh0ZW5kcyBSZXBvc2l0b3J5RmxhZ3MsXG4gIEMgZXh0ZW5kcyBDb250ZXh0PEY+LFxuPihcbiAgdGhpczogUixcbiAgY29udGV4dDogQ29udGV4dDxGPixcbiAgZGF0YTogVixcbiAga2V5OiBrZXlvZiBNLFxuICBtb2RlbDogTVxuKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IHByb3BlcnR5VmFsdWVzOiBhbnkgPSBtb2RlbFtrZXldO1xuICBpZiAoIXByb3BlcnR5VmFsdWVzIHx8ICFwcm9wZXJ0eVZhbHVlcy5sZW5ndGgpIHJldHVybjtcbiAgY29uc3QgYXJyYXlUeXBlID0gdHlwZW9mIHByb3BlcnR5VmFsdWVzWzBdO1xuICBpZiAoIXByb3BlcnR5VmFsdWVzLmV2ZXJ5KChpdGVtOiBhbnkpID0+IHR5cGVvZiBpdGVtID09PSBhcnJheVR5cGUpKVxuICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFxuICAgICAgYEludmFsaWQgb3BlcmF0aW9uLiBBbGwgZWxlbWVudHMgb2YgcHJvcGVydHkgJHtrZXkgYXMgc3RyaW5nfSBtdXN0IG1hdGNoIHRoZSBzYW1lIHR5cGUuYFxuICAgICk7XG4gIGNvbnN0IHVuaXF1ZVZhbHVlcyA9IG5ldyBTZXQoWy4uLnByb3BlcnR5VmFsdWVzXSk7XG4gIGlmIChhcnJheVR5cGUgIT09IFwib2JqZWN0XCIpIHtcbiAgICBjb25zdCByZXBvID0gcmVwb3NpdG9yeUZyb21UeXBlTWV0YWRhdGEobW9kZWwsIGtleSk7XG4gICAgZm9yIChjb25zdCBpZCBvZiB1bmlxdWVWYWx1ZXMpIHtcbiAgICAgIGNvbnN0IHJlYWQgPSBhd2FpdCByZXBvLnJlYWQoaWQpO1xuICAgICAgYXdhaXQgY2FjaGVNb2RlbEZvclBvcHVsYXRlKGNvbnRleHQsIG1vZGVsLCBrZXksIGlkLCByZWFkKTtcbiAgICB9XG4gICAgKG1vZGVsIGFzIGFueSlba2V5XSA9IFsuLi51bmlxdWVWYWx1ZXNdO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGNvbnN0IHBrTmFtZSA9IGZpbmRQcmltYXJ5S2V5KHByb3BlcnR5VmFsdWVzWzBdKS5pZDtcblxuICBjb25zdCByZXN1bHQ6IFNldDxzdHJpbmc+ID0gbmV3IFNldCgpO1xuXG4gIGZvciAoY29uc3QgbSBvZiBwcm9wZXJ0eVZhbHVlcykge1xuICAgIGNvbnN0IHJlY29yZCA9IGF3YWl0IGNyZWF0ZU9yVXBkYXRlKG0sIGNvbnRleHQpO1xuICAgIGF3YWl0IGNhY2hlTW9kZWxGb3JQb3B1bGF0ZShjb250ZXh0LCBtb2RlbCwga2V5LCByZWNvcmRbcGtOYW1lXSwgcmVjb3JkKTtcbiAgICByZXN1bHQuYWRkKHJlY29yZFtwa05hbWVdKTtcbiAgfVxuXG4gIChtb2RlbCBhcyBhbnkpW2tleV0gPSBbLi4ucmVzdWx0XTtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gSGFuZGxlcyBvbmUtdG8tbWFueSByZWxhdGlvbnNoaXAgdXBkYXRlc1xuICogQHN1bW1hcnkgUHJvY2Vzc2VzIGEgb25lLXRvLW1hbnkgcmVsYXRpb25zaGlwIHdoZW4gdXBkYXRpbmcgYSBtb2RlbCwgZGVsZWdhdGluZyB0byBvbmVUb01hbnlPbkNyZWF0ZSBpZiBjYXNjYWRlIHVwZGF0ZSBpcyBlbmFibGVkXG4gKiBAdGVtcGxhdGUgTSAtIFRoZSBtb2RlbCB0eXBlIGV4dGVuZGluZyBNb2RlbFxuICogQHRlbXBsYXRlIFIgLSBUaGUgcmVwb3NpdG9yeSB0eXBlIGV4dGVuZGluZyBSZXBvPE0sIEYsIEM+XG4gKiBAdGVtcGxhdGUgViAtIFRoZSByZWxhdGlvbnMgbWV0YWRhdGEgdHlwZSBleHRlbmRpbmcgUmVsYXRpb25zTWV0YWRhdGFcbiAqIEB0ZW1wbGF0ZSBGIC0gVGhlIHJlcG9zaXRvcnkgZmxhZ3MgdHlwZVxuICogQHRlbXBsYXRlIEMgLSBUaGUgY29udGV4dCB0eXBlIGV4dGVuZGluZyBDb250ZXh0PEY+XG4gKiBAcGFyYW0ge1J9IHRoaXMgLSBUaGUgcmVwb3NpdG9yeSBpbnN0YW5jZVxuICogQHBhcmFtIHtDb250ZXh0PEY+fSBjb250ZXh0IC0gVGhlIGNvbnRleHQgZm9yIHRoZSBvcGVyYXRpb25cbiAqIEBwYXJhbSB7Vn0gZGF0YSAtIFRoZSByZWxhdGlvbnMgbWV0YWRhdGFcbiAqIEBwYXJhbSBrZXkgLSBUaGUgcHJvcGVydHkga2V5IG9mIHRoZSByZWxhdGlvbnNoaXBcbiAqIEBwYXJhbSB7TX0gbW9kZWwgLSBUaGUgbW9kZWwgaW5zdGFuY2VcbiAqIEByZXR1cm4ge1Byb21pc2U8dm9pZD59IEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdoZW4gdGhlIG9wZXJhdGlvbiBpcyBjb21wbGV0ZVxuICogQGZ1bmN0aW9uIG9uZVRvTWFueU9uVXBkYXRlXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmNvcmVcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgQ2FsbGVyXG4gKiAgIHBhcnRpY2lwYW50IG9uZVRvTWFueU9uVXBkYXRlXG4gKiAgIHBhcnRpY2lwYW50IG9uZVRvTWFueU9uQ3JlYXRlXG4gKlxuICogICBDYWxsZXItPj5vbmVUb01hbnlPblVwZGF0ZTogdGhpcywgY29udGV4dCwgZGF0YSwga2V5LCBtb2RlbFxuICogICBvbmVUb01hbnlPblVwZGF0ZS0+Pm9uZVRvTWFueU9uVXBkYXRlOiBjaGVjayBpZiBjYXNjYWRlLnVwZGF0ZSBpcyBDQVNDQURFXG4gKlxuICogICBhbHQgY2FzY2FkZS51cGRhdGUgaXMgQ0FTQ0FERVxuICogICAgIG9uZVRvTWFueU9uVXBkYXRlLT4+b25lVG9NYW55T25DcmVhdGU6IGFwcGx5KHRoaXMsIFtjb250ZXh0LCBkYXRhLCBrZXksIG1vZGVsXSlcbiAqICAgICBvbmVUb01hbnlPbkNyZWF0ZS0tPj5vbmVUb01hbnlPblVwZGF0ZTogdm9pZFxuICogICBlbmRcbiAqXG4gKiAgIG9uZVRvTWFueU9uVXBkYXRlLS0+PkNhbGxlcjogdm9pZFxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gb25lVG9NYW55T25VcGRhdGU8XG4gIE0gZXh0ZW5kcyBNb2RlbCxcbiAgUiBleHRlbmRzIFJlcG88TSwgRiwgQz4sXG4gIFYgZXh0ZW5kcyBSZWxhdGlvbnNNZXRhZGF0YSxcbiAgRiBleHRlbmRzIFJlcG9zaXRvcnlGbGFncyxcbiAgQyBleHRlbmRzIENvbnRleHQ8Rj4sXG4+KFxuICB0aGlzOiBSLFxuICBjb250ZXh0OiBDb250ZXh0PEY+LFxuICBkYXRhOiBWLFxuICBrZXk6IGtleW9mIE0sXG4gIG1vZGVsOiBNXG4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgeyBjYXNjYWRlIH0gPSBkYXRhO1xuICBpZiAoY2FzY2FkZS51cGRhdGUgIT09IENhc2NhZGUuQ0FTQ0FERSkgcmV0dXJuO1xuICByZXR1cm4gb25lVG9NYW55T25DcmVhdGUuYXBwbHkodGhpcyBhcyBhbnksIFtcbiAgICBjb250ZXh0LFxuICAgIGRhdGEsXG4gICAga2V5IGFzIGtleW9mIE1vZGVsLFxuICAgIG1vZGVsLFxuICBdKTtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gSGFuZGxlcyBvbmUtdG8tbWFueSByZWxhdGlvbnNoaXAgZGVsZXRpb25cbiAqIEBzdW1tYXJ5IFByb2Nlc3NlcyBhIG9uZS10by1tYW55IHJlbGF0aW9uc2hpcCB3aGVuIGRlbGV0aW5nIGEgbW9kZWwsIGRlbGV0aW5nIGFsbCByZWxhdGVkIG1vZGVscyBpZiBjYXNjYWRlIGRlbGV0ZSBpcyBlbmFibGVkXG4gKiBAdGVtcGxhdGUgTSAtIFRoZSBtb2RlbCB0eXBlIGV4dGVuZGluZyBNb2RlbFxuICogQHRlbXBsYXRlIFIgLSBUaGUgcmVwb3NpdG9yeSB0eXBlIGV4dGVuZGluZyBSZXBvPE0sIEYsIEM+XG4gKiBAdGVtcGxhdGUgViAtIFRoZSByZWxhdGlvbnMgbWV0YWRhdGEgdHlwZSBleHRlbmRpbmcgUmVsYXRpb25zTWV0YWRhdGFcbiAqIEB0ZW1wbGF0ZSBGIC0gVGhlIHJlcG9zaXRvcnkgZmxhZ3MgdHlwZVxuICogQHRlbXBsYXRlIEMgLSBUaGUgY29udGV4dCB0eXBlIGV4dGVuZGluZyBDb250ZXh0PEY+XG4gKiBAcGFyYW0ge1J9IHRoaXMgLSBUaGUgcmVwb3NpdG9yeSBpbnN0YW5jZVxuICogQHBhcmFtIHtDb250ZXh0PEY+fSBjb250ZXh0IC0gVGhlIGNvbnRleHQgZm9yIHRoZSBvcGVyYXRpb25cbiAqIEBwYXJhbSB7Vn0gZGF0YSAtIFRoZSByZWxhdGlvbnMgbWV0YWRhdGFcbiAqIEBwYXJhbSBrZXkgLSBUaGUgcHJvcGVydHkga2V5IG9mIHRoZSByZWxhdGlvbnNoaXBcbiAqIEBwYXJhbSB7TX0gbW9kZWwgLSBUaGUgbW9kZWwgaW5zdGFuY2VcbiAqIEByZXR1cm4ge1Byb21pc2U8dm9pZD59IEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdoZW4gdGhlIG9wZXJhdGlvbiBpcyBjb21wbGV0ZVxuICogQGZ1bmN0aW9uIG9uZVRvTWFueU9uRGVsZXRlXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmNvcmVcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgQ2FsbGVyXG4gKiAgIHBhcnRpY2lwYW50IG9uZVRvTWFueU9uRGVsZXRlXG4gKiAgIHBhcnRpY2lwYW50IFJlcG9zaXRvcnlcbiAqICAgcGFydGljaXBhbnQgcmVwb3NpdG9yeUZyb21UeXBlTWV0YWRhdGFcbiAqICAgcGFydGljaXBhbnQgY2FjaGVNb2RlbEZvclBvcHVsYXRlXG4gKlxuICogICBDYWxsZXItPj5vbmVUb01hbnlPbkRlbGV0ZTogdGhpcywgY29udGV4dCwgZGF0YSwga2V5LCBtb2RlbFxuICogICBvbmVUb01hbnlPbkRlbGV0ZS0+Pm9uZVRvTWFueU9uRGVsZXRlOiBjaGVjayBpZiBjYXNjYWRlLmRlbGV0ZSBpcyBDQVNDQURFXG4gKiAgIG9uZVRvTWFueU9uRGVsZXRlLT4+b25lVG9NYW55T25EZWxldGU6IGNoZWNrIGlmIHZhbHVlcyBleGlzdHMgYW5kIGhhcyBsZW5ndGhcbiAqICAgb25lVG9NYW55T25EZWxldGUtPj5vbmVUb01hbnlPbkRlbGV0ZTogY2hlY2sgaWYgYWxsIGVsZW1lbnRzIGhhdmUgc2FtZSB0eXBlXG4gKlxuICogICBhbHQgaXNJbnN0YW50aWF0ZWQgKGFycmF5VHlwZSBpcyBcIm9iamVjdFwiKVxuICogICAgIG9uZVRvTWFueU9uRGVsZXRlLT4+UmVwb3NpdG9yeTogZm9yTW9kZWwodmFsdWVzWzBdKVxuICogICAgIFJlcG9zaXRvcnktLT4+b25lVG9NYW55T25EZWxldGU6IHJlcG9cbiAqICAgZWxzZSBub3QgaW5zdGFudGlhdGVkXG4gKiAgICAgb25lVG9NYW55T25EZWxldGUtPj5yZXBvc2l0b3J5RnJvbVR5cGVNZXRhZGF0YTogbW9kZWwsIGtleVxuICogICAgIHJlcG9zaXRvcnlGcm9tVHlwZU1ldGFkYXRhLS0+Pm9uZVRvTWFueU9uRGVsZXRlOiByZXBvXG4gKiAgIGVuZFxuICpcbiAqICAgb25lVG9NYW55T25EZWxldGUtPj5vbmVUb01hbnlPbkRlbGV0ZTogY3JlYXRlIHVuaXF1ZVZhbHVlcyBzZXRcbiAqXG4gKiAgIGxvb3AgZm9yIGVhY2ggaWQgaW4gdW5pcXVlVmFsdWVzXG4gKiAgICAgb25lVG9NYW55T25EZWxldGUtPj5yZXBvOiBkZWxldGUoaWQsIGNvbnRleHQpXG4gKiAgICAgcmVwby0tPj5vbmVUb01hbnlPbkRlbGV0ZTogZGVsZXRlZFxuICogICAgIG9uZVRvTWFueU9uRGVsZXRlLT4+Y2FjaGVNb2RlbEZvclBvcHVsYXRlOiBjb250ZXh0LCBtb2RlbCwga2V5LCBpZCwgZGVsZXRlZFxuICogICBlbmRcbiAqXG4gKiAgIG9uZVRvTWFueU9uRGVsZXRlLT4+b25lVG9NYW55T25EZWxldGU6IHNldCBtb2RlbFtrZXldID0gWy4uLnVuaXF1ZVZhbHVlc11cbiAqICAgb25lVG9NYW55T25EZWxldGUtLT4+Q2FsbGVyOiB2b2lkXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBvbmVUb01hbnlPbkRlbGV0ZTxcbiAgTSBleHRlbmRzIE1vZGVsLFxuICBSIGV4dGVuZHMgUmVwbzxNLCBGLCBDPixcbiAgViBleHRlbmRzIFJlbGF0aW9uc01ldGFkYXRhLFxuICBGIGV4dGVuZHMgUmVwb3NpdG9yeUZsYWdzLFxuICBDIGV4dGVuZHMgQ29udGV4dDxGPixcbj4oXG4gIHRoaXM6IFIsXG4gIGNvbnRleHQ6IENvbnRleHQ8Rj4sXG4gIGRhdGE6IFYsXG4gIGtleToga2V5b2YgTSxcbiAgbW9kZWw6IE1cbik6IFByb21pc2U8dm9pZD4ge1xuICBpZiAoZGF0YS5jYXNjYWRlLmRlbGV0ZSAhPT0gQ2FzY2FkZS5DQVNDQURFKSByZXR1cm47XG4gIGNvbnN0IHZhbHVlcyA9IG1vZGVsW2tleV0gYXMgYW55O1xuICBpZiAoIXZhbHVlcyB8fCAhdmFsdWVzLmxlbmd0aCkgcmV0dXJuO1xuICBjb25zdCBhcnJheVR5cGUgPSB0eXBlb2YgdmFsdWVzWzBdO1xuICBjb25zdCBhcmVBbGxTYW1lVHlwZSA9IHZhbHVlcy5ldmVyeSgoaXRlbTogYW55KSA9PiB0eXBlb2YgaXRlbSA9PT0gYXJyYXlUeXBlKTtcbiAgaWYgKCFhcmVBbGxTYW1lVHlwZSlcbiAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcbiAgICAgIGBJbnZhbGlkIG9wZXJhdGlvbi4gQWxsIGVsZW1lbnRzIG9mIHByb3BlcnR5ICR7a2V5IGFzIHN0cmluZ30gbXVzdCBtYXRjaCB0aGUgc2FtZSB0eXBlLmBcbiAgICApO1xuICBjb25zdCBpc0luc3RhbnRpYXRlZCA9IGFycmF5VHlwZSA9PT0gXCJvYmplY3RcIjtcbiAgY29uc3QgcmVwbyA9IGlzSW5zdGFudGlhdGVkXG4gICAgPyBSZXBvc2l0b3J5LmZvck1vZGVsKHZhbHVlc1swXSx0aGlzLmFkYXB0ZXIuYWxpYXMpXG4gICAgOiByZXBvc2l0b3J5RnJvbVR5cGVNZXRhZGF0YShtb2RlbCwga2V5KTtcblxuICBjb25zdCB1bmlxdWVWYWx1ZXMgPSBuZXcgU2V0KFtcbiAgICAuLi4oaXNJbnN0YW50aWF0ZWRcbiAgICAgID8gdmFsdWVzLm1hcCgodjogUmVjb3JkPHN0cmluZywgYW55PikgPT4gdltyZXBvLnBrIGFzIHN0cmluZ10pXG4gICAgICA6IHZhbHVlcyksXG4gIF0pO1xuXG4gIGZvciAoY29uc3QgaWQgb2YgdW5pcXVlVmFsdWVzLnZhbHVlcygpKSB7XG4gICAgY29uc3QgZGVsZXRlZCA9IGF3YWl0IHJlcG8uZGVsZXRlKGlkLCBjb250ZXh0KTtcbiAgICBhd2FpdCBjYWNoZU1vZGVsRm9yUG9wdWxhdGUoY29udGV4dCwgbW9kZWwsIGtleSwgaWQsIGRlbGV0ZWQpO1xuICB9XG4gIChtb2RlbCBhcyBhbnkpW2tleV0gPSBbLi4udW5pcXVlVmFsdWVzXTtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gR2VuZXJhdGVzIGEga2V5IGZvciBjYWNoaW5nIHBvcHVsYXRlZCBtb2RlbCByZWxhdGlvbnNoaXBzXG4gKiBAc3VtbWFyeSBDcmVhdGVzIGEgdW5pcXVlIGtleSBmb3Igc3RvcmluZyBhbmQgcmV0cmlldmluZyBwb3B1bGF0ZWQgbW9kZWwgcmVsYXRpb25zaGlwcyBpbiB0aGUgY2FjaGVcbiAqIEBwYXJhbSB7c3RyaW5nfSB0YWJsZU5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgdGFibGUgb3IgbW9kZWxcbiAqIEBwYXJhbSB7c3RyaW5nfSBmaWVsZE5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgZmllbGQgb3IgcHJvcGVydHlcbiAqIEBwYXJhbSB7c3RyaW5nfG51bWJlcn0gaWQgLSBUaGUgaWRlbnRpZmllciBvZiB0aGUgcmVsYXRlZCBtb2RlbFxuICogQHJldHVybiB7c3RyaW5nfSBBIGRvdC1zZXBhcmF0ZWQgc3RyaW5nIHRoYXQgdW5pcXVlbHkgaWRlbnRpZmllcyB0aGUgcmVsYXRpb25zaGlwXG4gKiBAZnVuY3Rpb24gZ2V0UG9wdWxhdGVLZXlcbiAqIEBtZW1iZXJPZiBtb2R1bGU6Y29yZVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0UG9wdWxhdGVLZXkoXG4gIHRhYmxlTmFtZTogc3RyaW5nLFxuICBmaWVsZE5hbWU6IHN0cmluZyxcbiAgaWQ6IHN0cmluZyB8IG51bWJlclxuKSB7XG4gIHJldHVybiBbUGVyc2lzdGVuY2VLZXlzLlBPUFVMQVRFLCB0YWJsZU5hbWUsIGZpZWxkTmFtZSwgaWRdLmpvaW4oXCIuXCIpO1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBDYWNoZXMgYSBtb2RlbCBmb3IgbGF0ZXIgcG9wdWxhdGlvblxuICogQHN1bW1hcnkgU3RvcmVzIGEgbW9kZWwgaW4gdGhlIGNvbnRleHQgY2FjaGUgZm9yIGVmZmljaWVudCByZXRyaWV2YWwgZHVyaW5nIHJlbGF0aW9uc2hpcCBwb3B1bGF0aW9uXG4gKiBAdGVtcGxhdGUgTSAtIFRoZSBtb2RlbCB0eXBlIGV4dGVuZGluZyBNb2RlbFxuICogQHRlbXBsYXRlIEYgLSBUaGUgcmVwb3NpdG9yeSBmbGFncyB0eXBlXG4gKiBAcGFyYW0ge0NvbnRleHQ8Rj59IGNvbnRleHQgLSBUaGUgY29udGV4dCBmb3IgdGhlIG9wZXJhdGlvblxuICogQHBhcmFtIHtNfSBwYXJlbnRNb2RlbCAtIFRoZSBwYXJlbnQgbW9kZWwgdGhhdCBjb250YWlucyB0aGUgcmVsYXRpb25zaGlwXG4gKiBAcGFyYW0gcHJvcGVydHlLZXkgLSBUaGUgcHJvcGVydHkga2V5IG9mIHRoZSByZWxhdGlvbnNoaXBcbiAqIEBwYXJhbSB7c3RyaW5nIHwgbnVtYmVyfSBwa1ZhbHVlIC0gVGhlIHByaW1hcnkga2V5IHZhbHVlIG9mIHRoZSByZWxhdGVkIG1vZGVsXG4gKiBAcGFyYW0ge2FueX0gY2FjaGVWYWx1ZSAtIFRoZSBtb2RlbCBpbnN0YW5jZSB0byBjYWNoZVxuICogQHJldHVybiB7UHJvbWlzZTxhbnk+fSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aXRoIHRoZSByZXN1bHQgb2YgdGhlIGNhY2hlIG9wZXJhdGlvblxuICogQGZ1bmN0aW9uIGNhY2hlTW9kZWxGb3JQb3B1bGF0ZVxuICogQG1lbWJlck9mIG1vZHVsZTpjb3JlXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjYWNoZU1vZGVsRm9yUG9wdWxhdGU8XG4gIE0gZXh0ZW5kcyBNb2RlbCxcbiAgRiBleHRlbmRzIFJlcG9zaXRvcnlGbGFncyxcbj4oXG4gIGNvbnRleHQ6IENvbnRleHQ8Rj4sXG4gIHBhcmVudE1vZGVsOiBNLFxuICBwcm9wZXJ0eUtleToga2V5b2YgTSB8IHN0cmluZyxcbiAgcGtWYWx1ZTogc3RyaW5nIHwgbnVtYmVyLFxuICBjYWNoZVZhbHVlOiBhbnlcbikge1xuICBjb25zdCBjYWNoZUtleSA9IGdldFBvcHVsYXRlS2V5KFxuICAgIHBhcmVudE1vZGVsLmNvbnN0cnVjdG9yLm5hbWUsXG4gICAgcHJvcGVydHlLZXkgYXMgc3RyaW5nLFxuICAgIHBrVmFsdWVcbiAgKTtcbiAgcmV0dXJuIGNvbnRleHQuYWNjdW11bGF0ZSh7IFtjYWNoZUtleV06IGNhY2hlVmFsdWUgfSk7XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIFBvcHVsYXRlcyBhIG1vZGVsJ3MgcmVsYXRpb25zaGlwXG4gKiBAc3VtbWFyeSBSZXRyaWV2ZXMgYW5kIGF0dGFjaGVzIHJlbGF0ZWQgbW9kZWxzIHRvIGEgbW9kZWwncyByZWxhdGlvbnNoaXAgcHJvcGVydHlcbiAqIEB0ZW1wbGF0ZSBNIC0gVGhlIG1vZGVsIHR5cGUgZXh0ZW5kaW5nIE1vZGVsXG4gKiBAdGVtcGxhdGUgUiAtIFRoZSByZXBvc2l0b3J5IHR5cGUgZXh0ZW5kaW5nIFJlcG88TSwgRiwgQz5cbiAqIEB0ZW1wbGF0ZSBWIC0gVGhlIHJlbGF0aW9ucyBtZXRhZGF0YSB0eXBlIGV4dGVuZGluZyBSZWxhdGlvbnNNZXRhZGF0YVxuICogQHRlbXBsYXRlIEYgLSBUaGUgcmVwb3NpdG9yeSBmbGFncyB0eXBlXG4gKiBAdGVtcGxhdGUgQyAtIFRoZSBjb250ZXh0IHR5cGUgZXh0ZW5kaW5nIENvbnRleHQ8Rj5cbiAqIEBwYXJhbSB7Un0gdGhpcyAtIFRoZSByZXBvc2l0b3J5IGluc3RhbmNlXG4gKiBAcGFyYW0ge0NvbnRleHQ8Rj59IGNvbnRleHQgLSBUaGUgY29udGV4dCBmb3IgdGhlIG9wZXJhdGlvblxuICogQHBhcmFtIHtWfSBkYXRhIC0gVGhlIHJlbGF0aW9ucyBtZXRhZGF0YVxuICogQHBhcmFtIGtleSAtIFRoZSBwcm9wZXJ0eSBrZXkgb2YgdGhlIHJlbGF0aW9uc2hpcFxuICogQHBhcmFtIHtNfSBtb2RlbCAtIFRoZSBtb2RlbCBpbnN0YW5jZVxuICogQHJldHVybiB7UHJvbWlzZTx2b2lkPn0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiB0aGUgb3BlcmF0aW9uIGlzIGNvbXBsZXRlXG4gKiBAZnVuY3Rpb24gcG9wdWxhdGVcbiAqIEBtZW1iZXJPZiBtb2R1bGU6Y29yZVxuICogQG1lcm1haWRcbiAqIHNlcXVlbmNlRGlhZ3JhbVxuICogICBwYXJ0aWNpcGFudCBDYWxsZXJcbiAqICAgcGFydGljaXBhbnQgcG9wdWxhdGVcbiAqICAgcGFydGljaXBhbnQgZmV0Y2hQb3B1bGF0ZVZhbHVlc1xuICogICBwYXJ0aWNpcGFudCBnZXRQb3B1bGF0ZUtleVxuICogICBwYXJ0aWNpcGFudCBDb250ZXh0XG4gKiAgIHBhcnRpY2lwYW50IHJlcG9zaXRvcnlGcm9tVHlwZU1ldGFkYXRhXG4gKlxuICogICBDYWxsZXItPj5wb3B1bGF0ZTogdGhpcywgY29udGV4dCwgZGF0YSwga2V5LCBtb2RlbFxuICogICBwb3B1bGF0ZS0+PnBvcHVsYXRlOiBjaGVjayBpZiBkYXRhLnBvcHVsYXRlIGlzIHRydWVcbiAqICAgcG9wdWxhdGUtPj5wb3B1bGF0ZTogZ2V0IG5lc3RlZCB2YWx1ZSBhbmQgY2hlY2sgaWYgaXQgZXhpc3RzXG4gKlxuICogICBwb3B1bGF0ZS0+PmZldGNoUG9wdWxhdGVWYWx1ZXM6IGNvbnRleHQsIG1vZGVsLCBrZXksIGlzQXJyID8gbmVzdGVkIDogW25lc3RlZF1cbiAqXG4gKiAgIGZldGNoUG9wdWxhdGVWYWx1ZXMtPj5mZXRjaFBvcHVsYXRlVmFsdWVzOiBpbml0aWFsaXplIHZhcmlhYmxlc1xuICpcbiAqICAgbG9vcCBmb3IgZWFjaCBwcm9LZXlWYWx1ZSBpbiBwcm9wS2V5VmFsdWVzXG4gKiAgICAgZmV0Y2hQb3B1bGF0ZVZhbHVlcy0+PmdldFBvcHVsYXRlS2V5OiBtb2RlbC5jb25zdHJ1Y3Rvci5uYW1lLCBwcm9wTmFtZSwgcHJvS2V5VmFsdWVcbiAqICAgICBnZXRQb3B1bGF0ZUtleS0tPj5mZXRjaFBvcHVsYXRlVmFsdWVzOiBjYWNoZUtleVxuICpcbiAqICAgICBhbHQgdHJ5IHRvIGdldCBmcm9tIGNhY2hlXG4gKiAgICAgICBmZXRjaFBvcHVsYXRlVmFsdWVzLT4+Q29udGV4dDogZ2V0KGNhY2hlS2V5KVxuICogICAgICAgQ29udGV4dC0tPj5mZXRjaFBvcHVsYXRlVmFsdWVzOiB2YWxcbiAqICAgICBlbHNlIGNhdGNoIGVycm9yXG4gKiAgICAgICBmZXRjaFBvcHVsYXRlVmFsdWVzLT4+cmVwb3NpdG9yeUZyb21UeXBlTWV0YWRhdGE6IG1vZGVsLCBwcm9wTmFtZVxuICogICAgICAgcmVwb3NpdG9yeUZyb21UeXBlTWV0YWRhdGEtLT4+ZmV0Y2hQb3B1bGF0ZVZhbHVlczogcmVwb1xuICogICAgICAgZmV0Y2hQb3B1bGF0ZVZhbHVlcy0+PnJlcG86IHJlYWQocHJvS2V5VmFsdWUpXG4gKiAgICAgICByZXBvLS0+PmZldGNoUG9wdWxhdGVWYWx1ZXM6IHZhbFxuICogICAgIGVuZFxuICpcbiAqICAgICBmZXRjaFBvcHVsYXRlVmFsdWVzLT4+ZmV0Y2hQb3B1bGF0ZVZhbHVlczogYWRkIHZhbCB0byByZXN1bHRzXG4gKiAgIGVuZFxuICpcbiAqICAgZmV0Y2hQb3B1bGF0ZVZhbHVlcy0tPj5wb3B1bGF0ZTogcmVzdWx0c1xuICogICBwb3B1bGF0ZS0+PnBvcHVsYXRlOiBzZXQgbW9kZWxba2V5XSA9IGlzQXJyID8gcmVzIDogcmVzWzBdXG4gKiAgIHBvcHVsYXRlLS0+PkNhbGxlcjogdm9pZFxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcG9wdWxhdGU8XG4gIE0gZXh0ZW5kcyBNb2RlbCxcbiAgUiBleHRlbmRzIFJlcG88TSwgRiwgQz4sXG4gIFYgZXh0ZW5kcyBSZWxhdGlvbnNNZXRhZGF0YSxcbiAgRiBleHRlbmRzIFJlcG9zaXRvcnlGbGFncyxcbiAgQyBleHRlbmRzIENvbnRleHQ8Rj4sXG4+KFxuICB0aGlzOiBSLFxuICBjb250ZXh0OiBDb250ZXh0PEY+LFxuICBkYXRhOiBWLFxuICBrZXk6IGtleW9mIE0sXG4gIG1vZGVsOiBNXG4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgaWYgKCFkYXRhLnBvcHVsYXRlKSByZXR1cm47XG4gIGNvbnN0IG5lc3RlZDogYW55ID0gbW9kZWxba2V5XTtcbiAgY29uc3QgaXNBcnIgPSBBcnJheS5pc0FycmF5KG5lc3RlZCk7XG4gIGlmICh0eXBlb2YgbmVzdGVkID09PSBcInVuZGVmaW5lZFwiIHx8IChpc0FyciAmJiBuZXN0ZWQubGVuZ3RoID09PSAwKSkgcmV0dXJuO1xuXG4gIGFzeW5jIGZ1bmN0aW9uIGZldGNoUG9wdWxhdGVWYWx1ZXMoXG4gICAgYzogQ29udGV4dDxGPixcbiAgICBtb2RlbDogTSxcbiAgICBwcm9wTmFtZTogc3RyaW5nLFxuICAgIHByb3BLZXlWYWx1ZXM6IGFueVtdXG4gICkge1xuICAgIGxldCBjYWNoZUtleTogc3RyaW5nO1xuICAgIGxldCB2YWw6IGFueTtcbiAgICBjb25zdCByZXN1bHRzOiBNW10gPSBbXTtcbiAgICBmb3IgKGNvbnN0IHByb0tleVZhbHVlIG9mIHByb3BLZXlWYWx1ZXMpIHtcbiAgICAgIGNhY2hlS2V5ID0gZ2V0UG9wdWxhdGVLZXkobW9kZWwuY29uc3RydWN0b3IubmFtZSwgcHJvcE5hbWUsIHByb0tleVZhbHVlKTtcbiAgICAgIHRyeSB7XG4gICAgICAgIHZhbCA9IGF3YWl0IGMuZ2V0KGNhY2hlS2V5IGFzIGFueSk7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgICBjb25zdCByZXBvID0gcmVwb3NpdG9yeUZyb21UeXBlTWV0YWRhdGEobW9kZWwsIHByb3BOYW1lKTtcbiAgICAgICAgaWYgKCFyZXBvKSB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcIkNvdWxkIG5vdCBmaW5kIHJlcG9cIik7XG4gICAgICAgIHZhbCA9IGF3YWl0IHJlcG8ucmVhZChwcm9LZXlWYWx1ZSk7XG4gICAgICB9XG4gICAgICByZXN1bHRzLnB1c2godmFsKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdHM7XG4gIH1cbiAgY29uc3QgcmVzID0gYXdhaXQgZmV0Y2hQb3B1bGF0ZVZhbHVlcyhcbiAgICBjb250ZXh0LFxuICAgIG1vZGVsLFxuICAgIGtleSBhcyBzdHJpbmcsXG4gICAgaXNBcnIgPyBuZXN0ZWQgOiBbbmVzdGVkXVxuICApO1xuICAobW9kZWwgYXMgYW55KVtrZXldID0gaXNBcnIgPyByZXMgOiByZXNbMF07XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIExpc3Qgb2YgY29tbW9uIEphdmFTY3JpcHQgdHlwZXNcbiAqIEBzdW1tYXJ5IEFuIGFycmF5IG9mIHN0cmluZ3MgcmVwcmVzZW50aW5nIGNvbW1vbiBKYXZhU2NyaXB0IHR5cGVzIHRoYXQgYXJlIG5vdCBjdXN0b20gbW9kZWwgdHlwZXNcbiAqIEBjb25zdCBjb21tb21UeXBlc1xuICogQG1lbWJlck9mIG1vZHVsZTpjb3JlXG4gKi9cbmNvbnN0IGNvbW1vbVR5cGVzID0gW1xuICBcImFycmF5XCIsXG4gIFwic3RyaW5nXCIsXG4gIFwibnVtYmVyXCIsXG4gIFwiYm9vbGVhblwiLFxuICBcInN5bWJvbFwiLFxuICBcImZ1bmN0aW9uXCIsXG4gIFwib2JqZWN0XCIsXG4gIFwidW5kZWZpbmVkXCIsXG4gIFwibnVsbFwiLFxuICBcImJpZ2ludFwiLFxuXTtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gUmV0cmlldmVzIGEgcmVwb3NpdG9yeSBmb3IgYSBtb2RlbCBwcm9wZXJ0eSBiYXNlZCBvbiBpdHMgdHlwZSBtZXRhZGF0YVxuICogQHN1bW1hcnkgRXhhbWluZXMgYSBtb2RlbCBwcm9wZXJ0eSdzIHR5cGUgbWV0YWRhdGEgdG8gZGV0ZXJtaW5lIHRoZSBhcHByb3ByaWF0ZSByZXBvc2l0b3J5IGZvciByZWxhdGVkIG1vZGVsc1xuICogQHRlbXBsYXRlIE0gLSBUaGUgbW9kZWwgdHlwZSBleHRlbmRpbmcgTW9kZWxcbiAqIEBwYXJhbSB7YW55fSBtb2RlbCAtIFRoZSBtb2RlbCBpbnN0YW5jZSBjb250YWluaW5nIHRoZSBwcm9wZXJ0eVxuICogQHBhcmFtIHByb3BlcnR5S2V5IC0gVGhlIHByb3BlcnR5IGtleSB0byBleGFtaW5lXG4gKiBAcmV0dXJuIHtSZXBvPE0+fSBBIHJlcG9zaXRvcnkgZm9yIHRoZSBtb2RlbCB0eXBlIGFzc29jaWF0ZWQgd2l0aCB0aGUgcHJvcGVydHlcbiAqIEBmdW5jdGlvbiByZXBvc2l0b3J5RnJvbVR5cGVNZXRhZGF0YVxuICogQG1lbWJlck9mIG1vZHVsZTpjb3JlXG4gKiBAbWVybWFpZFxuICogc2VxdWVuY2VEaWFncmFtXG4gKiAgIHBhcnRpY2lwYW50IENhbGxlclxuICogICBwYXJ0aWNpcGFudCByZXBvc2l0b3J5RnJvbVR5cGVNZXRhZGF0YVxuICogICBwYXJ0aWNpcGFudCBSZWZsZWN0XG4gKiAgIHBhcnRpY2lwYW50IFZhbGlkYXRpb25cbiAqICAgcGFydGljaXBhbnQgTW9kZWxcbiAqICAgcGFydGljaXBhbnQgUmVwb3NpdG9yeVxuICpcbiAqICAgQ2FsbGVyLT4+cmVwb3NpdG9yeUZyb21UeXBlTWV0YWRhdGE6IG1vZGVsLCBwcm9wZXJ0eUtleVxuICpcbiAqICAgcmVwb3NpdG9yeUZyb21UeXBlTWV0YWRhdGEtPj5WYWxpZGF0aW9uOiBrZXkoQXJyYXkuaXNBcnJheShtb2RlbFtwcm9wZXJ0eUtleV0pID8gVmFsaWRhdGlvbktleXMuTElTVCA6IFZhbGlkYXRpb25LZXlzLlRZUEUpXG4gKiAgIFZhbGlkYXRpb24tLT4+cmVwb3NpdG9yeUZyb21UeXBlTWV0YWRhdGE6IHZhbGlkYXRpb25LZXlcbiAqXG4gKiAgIHJlcG9zaXRvcnlGcm9tVHlwZU1ldGFkYXRhLT4+UmVmbGVjdDogZ2V0TWV0YWRhdGEodmFsaWRhdGlvbktleSwgbW9kZWwsIHByb3BlcnR5S2V5KVxuICogICBSZWZsZWN0LS0+PnJlcG9zaXRvcnlGcm9tVHlwZU1ldGFkYXRhOiB0eXBlc1xuICpcbiAqICAgcmVwb3NpdG9yeUZyb21UeXBlTWV0YWRhdGEtPj5yZXBvc2l0b3J5RnJvbVR5cGVNZXRhZGF0YTogZGV0ZXJtaW5lIGN1c3RvbVR5cGVzIGJhc2VkIG9uIHByb3BlcnR5IHR5cGVcbiAqICAgcmVwb3NpdG9yeUZyb21UeXBlTWV0YWRhdGEtPj5yZXBvc2l0b3J5RnJvbVR5cGVNZXRhZGF0YTogY2hlY2sgaWYgdHlwZXMgYW5kIGN1c3RvbVR5cGVzIGV4aXN0XG4gKlxuICogICByZXBvc2l0b3J5RnJvbVR5cGVNZXRhZGF0YS0+PnJlcG9zaXRvcnlGcm9tVHlwZU1ldGFkYXRhOiBjcmVhdGUgYWxsb3dlZFR5cGVzIGFycmF5XG4gKiAgIHJlcG9zaXRvcnlGcm9tVHlwZU1ldGFkYXRhLT4+cmVwb3NpdG9yeUZyb21UeXBlTWV0YWRhdGE6IGZpbmQgY29uc3RydWN0b3JOYW1lIG5vdCBpbiBjb21tb21UeXBlc1xuICogICByZXBvc2l0b3J5RnJvbVR5cGVNZXRhZGF0YS0+PnJlcG9zaXRvcnlGcm9tVHlwZU1ldGFkYXRhOiBjaGVjayBpZiBjb25zdHJ1Y3Rvck5hbWUgZXhpc3RzXG4gKlxuICogICByZXBvc2l0b3J5RnJvbVR5cGVNZXRhZGF0YS0+Pk1vZGVsOiBnZXQoY29uc3RydWN0b3JOYW1lKVxuICogICBNb2RlbC0tPj5yZXBvc2l0b3J5RnJvbVR5cGVNZXRhZGF0YTogY29uc3RydWN0b3JcbiAqICAgcmVwb3NpdG9yeUZyb21UeXBlTWV0YWRhdGEtPj5yZXBvc2l0b3J5RnJvbVR5cGVNZXRhZGF0YTogY2hlY2sgaWYgY29uc3RydWN0b3IgZXhpc3RzXG4gKlxuICogICByZXBvc2l0b3J5RnJvbVR5cGVNZXRhZGF0YS0+PlJlcG9zaXRvcnk6IGZvck1vZGVsKGNvbnN0cnVjdG9yKVxuICogICBSZXBvc2l0b3J5LS0+PnJlcG9zaXRvcnlGcm9tVHlwZU1ldGFkYXRhOiByZXBvXG4gKlxuICogICByZXBvc2l0b3J5RnJvbVR5cGVNZXRhZGF0YS0tPj5DYWxsZXI6IHJlcG9cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlcG9zaXRvcnlGcm9tVHlwZU1ldGFkYXRhPE0gZXh0ZW5kcyBNb2RlbD4oXG4gIG1vZGVsOiBhbnksXG4gIHByb3BlcnR5S2V5OiBzdHJpbmcgfCBrZXlvZiBNXG4pOiBSZXBvPE0+IHtcbiAgY29uc3QgdHlwZXMgPSBSZWZsZWN0LmdldE1ldGFkYXRhKFxuICAgIFZhbGlkYXRpb24ua2V5KFxuICAgICAgQXJyYXkuaXNBcnJheShtb2RlbFtwcm9wZXJ0eUtleV0pXG4gICAgICAgID8gVmFsaWRhdGlvbktleXMuTElTVFxuICAgICAgICA6IFZhbGlkYXRpb25LZXlzLlRZUEVcbiAgICApLFxuICAgIG1vZGVsLFxuICAgIHByb3BlcnR5S2V5IGFzIHN0cmluZ1xuICApO1xuICBjb25zdCBjdXN0b21UeXBlczogYW55ID0gQXJyYXkuaXNBcnJheShtb2RlbFtwcm9wZXJ0eUtleV0pXG4gICAgPyB0eXBlcy5jbGF6elxuICAgIDogdHlwZXMuY3VzdG9tVHlwZXM7XG4gIGlmICghdHlwZXMgfHwgIWN1c3RvbVR5cGVzKVxuICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFxuICAgICAgYEZhaWxlZCB0byBmaW5kIHR5cGVzIGRlY29yYXRvcnMgZm9yIHByb3BlcnR5ICR7cHJvcGVydHlLZXkgYXMgc3RyaW5nfWBcbiAgICApO1xuXG4gIGNvbnN0IGFsbG93ZWRUeXBlczogc3RyaW5nW10gPSBBcnJheS5pc0FycmF5KGN1c3RvbVR5cGVzKVxuICAgID8gWy4uLmN1c3RvbVR5cGVzXVxuICAgIDogW2N1c3RvbVR5cGVzXTtcbiAgY29uc3QgY29uc3RydWN0b3JOYW1lID0gYWxsb3dlZFR5cGVzLmZpbmQoXG4gICAgKHQpID0+ICFjb21tb21UeXBlcy5pbmNsdWRlcyhgJHt0fWAudG9Mb3dlckNhc2UoKSlcbiAgKTtcbiAgaWYgKCFjb25zdHJ1Y3Rvck5hbWUpXG4gICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXG4gICAgICBgUHJvcGVydHkga2V5ICR7cHJvcGVydHlLZXkgYXMgc3RyaW5nfSBkb2VzIG5vdCBoYXZlIGEgdmFsaWQgY29uc3RydWN0b3IgdHlwZWBcbiAgICApO1xuICBjb25zdCBjb25zdHJ1Y3RvcjogQ29uc3RydWN0b3I8TT4gfCB1bmRlZmluZWQgPSBNb2RlbC5nZXQoY29uc3RydWN0b3JOYW1lKTtcbiAgaWYgKCFjb25zdHJ1Y3RvcilcbiAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihgTm8gcmVnaXN0ZXJlZCBtb2RlbCBmb3VuZCBmb3IgJHtjb25zdHJ1Y3Rvck5hbWV9YCk7XG5cbiAgcmV0dXJuIFJlcG9zaXRvcnkuZm9yTW9kZWwoY29uc3RydWN0b3IpO1xufVxuXG4iLCJpbXBvcnQge1xuICBDb25mbGljdEVycm9yLFxuICBvbkNyZWF0ZSxcbiAgb25DcmVhdGVVcGRhdGUsXG4gIG9uRGVsZXRlLFxuICBvblVwZGF0ZSxcbiAgYWZ0ZXJBbnksXG4gIFJlcG9zaXRvcnlGbGFncyxcbiAgQ29udGV4dCxcbn0gZnJvbSBcIkBkZWNhZi10cy9kYi1kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBhcHBseSwgbWV0YWRhdGEgfSBmcm9tIFwiQGRlY2FmLXRzL3JlZmxlY3Rpb25cIjtcbmltcG9ydCB7IFBlcnNpc3RlbmNlS2V5cyB9IGZyb20gXCIuLi9wZXJzaXN0ZW5jZS9jb25zdGFudHNcIjtcbmltcG9ydCB7IENhc2NhZGVNZXRhZGF0YSwgSW5kZXhNZXRhZGF0YSB9IGZyb20gXCIuLi9yZXBvc2l0b3J5L3R5cGVzXCI7XG5pbXBvcnQgeyBEZWZhdWx0Q2FzY2FkZSwgT3JkZXJEaXJlY3Rpb24gfSBmcm9tIFwiLi4vcmVwb3NpdG9yeS9jb25zdGFudHNcIjtcbmltcG9ydCB7XG4gIENvbnN0cnVjdG9yLFxuICBEZWNvcmF0aW9uLFxuICBsaXN0LFxuICBNb2RlbCxcbiAgcHJvcCxcbiAgcHJvcE1ldGFkYXRhLFxuICB0eXBlLFxufSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBBZGFwdGVyIH0gZnJvbSBcIi4uL3BlcnNpc3RlbmNlL0FkYXB0ZXJcIjtcbmltcG9ydCB7IFJlcG8sIFJlcG9zaXRvcnkgfSBmcm9tIFwiLi4vcmVwb3NpdG9yeS9SZXBvc2l0b3J5XCI7XG5pbXBvcnQgeyBDb25kaXRpb24gfSBmcm9tIFwiLi4vcXVlcnkvQ29uZGl0aW9uXCI7XG5pbXBvcnQgeyBSZWxhdGlvbnNNZXRhZGF0YSB9IGZyb20gXCIuL3R5cGVzXCI7XG5pbXBvcnQge1xuICBvbmVUb01hbnlPbkNyZWF0ZSxcbiAgb25lVG9NYW55T25EZWxldGUsXG4gIG9uZVRvTWFueU9uVXBkYXRlLFxuICBvbmVUb09uZU9uQ3JlYXRlLFxuICBvbmVUb09uZU9uRGVsZXRlLFxuICBvbmVUb09uZU9uVXBkYXRlLFxuICBwb3B1bGF0ZSBhcyBwb3AsXG59IGZyb20gXCIuL2NvbnN0cnVjdGlvblwiO1xuaW1wb3J0IHsgQXV0aG9yaXphdGlvbkVycm9yIH0gZnJvbSBcIi4uL3V0aWxzXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIFNwZWNpZmllcyB0aGUgZGF0YWJhc2UgdGFibGUgbmFtZSBmb3IgYSBtb2RlbFxuICogQHN1bW1hcnkgRGVjb3JhdG9yIHRoYXQgc2V0cyB0aGUgdGFibGUgbmFtZSBmb3IgYSBtb2RlbCBjbGFzcyBpbiB0aGUgZGF0YWJhc2VcbiAqIEBwYXJhbSB7c3RyaW5nfSB0YWJsZU5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgdGFibGUgaW4gdGhlIGRhdGFiYXNlXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn0gQSBkZWNvcmF0b3IgZnVuY3Rpb24gdGhhdCBjYW4gYmUgYXBwbGllZCB0byBhIGNsYXNzXG4gKiBAZnVuY3Rpb24gdGFibGVcbiAqIEBjYXRlZ29yeSBDbGFzcyBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0YWJsZSh0YWJsZU5hbWU6IHN0cmluZykge1xuICByZXR1cm4gbWV0YWRhdGEoQWRhcHRlci5rZXkoUGVyc2lzdGVuY2VLZXlzLlRBQkxFKSwgdGFibGVOYW1lKTtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gU3BlY2lmaWVzIHRoZSBkYXRhYmFzZSBjb2x1bW4gbmFtZSBmb3IgYSBtb2RlbCBwcm9wZXJ0eVxuICogQHN1bW1hcnkgRGVjb3JhdG9yIHRoYXQgbWFwcyBhIG1vZGVsIHByb3BlcnR5IHRvIGEgc3BlY2lmaWMgY29sdW1uIG5hbWUgaW4gdGhlIGRhdGFiYXNlXG4gKiBAcGFyYW0ge3N0cmluZ30gY29sdW1uTmFtZSAtIFRoZSBuYW1lIG9mIHRoZSBjb2x1bW4gaW4gdGhlIGRhdGFiYXNlXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn0gQSBkZWNvcmF0b3IgZnVuY3Rpb24gdGhhdCBjYW4gYmUgYXBwbGllZCB0byBhIGNsYXNzIHByb3BlcnR5XG4gKiBAZnVuY3Rpb24gY29sdW1uXG4gKiBAY2F0ZWdvcnkgUHJvcGVydHkgRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gY29sdW1uKGNvbHVtbk5hbWU6IHN0cmluZykge1xuICByZXR1cm4gcHJvcE1ldGFkYXRhKEFkYXB0ZXIua2V5KFBlcnNpc3RlbmNlS2V5cy5DT0xVTU4pLCBjb2x1bW5OYW1lKTtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gQ3JlYXRlcyBhbiBpbmRleCBvbiBhIG1vZGVsIHByb3BlcnR5IGZvciBpbXByb3ZlZCBxdWVyeSBwZXJmb3JtYW5jZVxuICogQHN1bW1hcnkgRGVjb3JhdG9yIHRoYXQgbWFya3MgYSBwcm9wZXJ0eSB0byBiZSBpbmRleGVkIGluIHRoZSBkYXRhYmFzZSwgb3B0aW9uYWxseSB3aXRoIHNwZWNpZmljIGRpcmVjdGlvbnMgYW5kIGNvbXBvc2l0aW9uc1xuICogQHBhcmFtIHtPcmRlckRpcmVjdGlvbltdfSBbZGlyZWN0aW9uc10gLSBPcHRpb25hbCBhcnJheSBvZiBzb3J0IGRpcmVjdGlvbnMgZm9yIHRoZSBpbmRleFxuICogQHBhcmFtIHtzdHJpbmdbXX0gW2NvbXBvc2l0aW9uc10gLSBPcHRpb25hbCBhcnJheSBvZiBwcm9wZXJ0eSBuYW1lcyB0byBjcmVhdGUgYSBjb21wb3NpdGUgaW5kZXhcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufSBBIGRlY29yYXRvciBmdW5jdGlvbiB0aGF0IGNhbiBiZSBhcHBsaWVkIHRvIGEgY2xhc3MgcHJvcGVydHlcbiAqIEBmdW5jdGlvbiBpbmRleFxuICogQGNhdGVnb3J5IFByb3BlcnR5IERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGluZGV4KGRpcmVjdGlvbnM/OiBPcmRlckRpcmVjdGlvbltdLCBjb21wb3NpdGlvbnM/OiBzdHJpbmdbXSkge1xuICByZXR1cm4gcHJvcE1ldGFkYXRhKFxuICAgIFJlcG9zaXRvcnkua2V5KFxuICAgICAgYCR7UGVyc2lzdGVuY2VLZXlzLklOREVYfSR7Y29tcG9zaXRpb25zICYmIGNvbXBvc2l0aW9ucy5sZW5ndGggPyBgLiR7Y29tcG9zaXRpb25zLmpvaW4oXCIuXCIpfWAgOiBcIlwifWBcbiAgICApLFxuICAgIHtcbiAgICAgIGRpcmVjdGlvbnM6IGRpcmVjdGlvbnMsXG4gICAgICBjb21wb3NpdGlvbnM6IGNvbXBvc2l0aW9ucyxcbiAgICB9IGFzIEluZGV4TWV0YWRhdGFcbiAgKTtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gRW5mb3JjZXMgdW5pcXVlbmVzcyBjb25zdHJhaW50IGR1cmluZyBtb2RlbCBjcmVhdGlvbiBhbmQgdXBkYXRlXG4gKiBAc3VtbWFyeSBJbnRlcm5hbCBmdW5jdGlvbiB1c2VkIGJ5IHRoZSB1bmlxdWUgZGVjb3JhdG9yIHRvIGNoZWNrIGlmIGEgcHJvcGVydHkgdmFsdWUgYWxyZWFkeSBleGlzdHMgaW4gdGhlIGRhdGFiYXNlXG4gKiBAdGVtcGxhdGUgTSAtIFRoZSBtb2RlbCB0eXBlIGV4dGVuZGluZyBNb2RlbFxuICogQHRlbXBsYXRlIFIgLSBUaGUgcmVwb3NpdG9yeSB0eXBlIGV4dGVuZGluZyBSZXBvPE0sIEYsIEM+XG4gKiBAdGVtcGxhdGUgViAtIFRoZSBtZXRhZGF0YSB0eXBlXG4gKiBAdGVtcGxhdGUgRiAtIFRoZSByZXBvc2l0b3J5IGZsYWdzIHR5cGVcbiAqIEB0ZW1wbGF0ZSBDIC0gVGhlIGNvbnRleHQgdHlwZSBleHRlbmRpbmcgQ29udGV4dDxGPlxuICogQHBhcmFtIHtSfSB0aGlzIC0gVGhlIHJlcG9zaXRvcnkgaW5zdGFuY2VcbiAqIEBwYXJhbSB7Q29udGV4dDxGPn0gY29udGV4dCAtIFRoZSBjb250ZXh0IGZvciB0aGUgb3BlcmF0aW9uXG4gKiBAcGFyYW0ge1Z9IGRhdGEgLSBUaGUgbWV0YWRhdGEgZm9yIHRoZSBwcm9wZXJ0eVxuICogQHBhcmFtIGtleSAtIFRoZSBwcm9wZXJ0eSBrZXkgdG8gY2hlY2sgZm9yIHVuaXF1ZW5lc3NcbiAqIEBwYXJhbSB7TX0gbW9kZWwgLSBUaGUgbW9kZWwgaW5zdGFuY2UgYmVpbmcgY3JlYXRlZCBvciB1cGRhdGVkXG4gKiBAcmV0dXJuIHtQcm9taXNlPHZvaWQ+fSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIHRoZSBjaGVjayBpcyBjb21wbGV0ZSBvciByZWplY3RzIHdpdGggYSBDb25mbGljdEVycm9yXG4gKiBAZnVuY3Rpb24gdW5pcXVlT25DcmVhdGVVcGRhdGVcbiAqIEBtZW1iZXJPZiBtb2R1bGU6Y29yZVxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gdW5pcXVlT25DcmVhdGVVcGRhdGU8XG4gIE0gZXh0ZW5kcyBNb2RlbCxcbiAgUiBleHRlbmRzIFJlcG88TSwgRiwgQz4sXG4gIFYgZXh0ZW5kcyBvYmplY3QsXG4gIEYgZXh0ZW5kcyBSZXBvc2l0b3J5RmxhZ3MsXG4gIEMgZXh0ZW5kcyBDb250ZXh0PEY+LFxuPihcbiAgdGhpczogUixcbiAgY29udGV4dDogQ29udGV4dDxGPixcbiAgZGF0YTogVixcbiAga2V5OiBrZXlvZiBNLFxuICBtb2RlbDogTVxuKTogUHJvbWlzZTx2b2lkPiB7XG4gIGlmICghKG1vZGVsIGFzIGFueSlba2V5XSkgcmV0dXJuO1xuICBjb25zdCBleGlzdGluZyA9IGF3YWl0IHRoaXMuc2VsZWN0KClcbiAgICAud2hlcmUoQ29uZGl0aW9uLmF0dHJpYnV0ZShrZXkpLmVxKG1vZGVsW2tleV0pKVxuICAgIC5leGVjdXRlKCk7XG4gIGlmIChleGlzdGluZy5sZW5ndGgpXG4gICAgdGhyb3cgbmV3IENvbmZsaWN0RXJyb3IoXG4gICAgICBgbW9kZWwgYWxyZWFkeSBleGlzdHMgd2l0aCBwcm9wZXJ0eSAke2tleSBhcyBzdHJpbmd9IGVxdWFsIHRvICR7SlNPTi5zdHJpbmdpZnkoKG1vZGVsIGFzIGFueSlba2V5XSwgdW5kZWZpbmVkLCAyKX1gXG4gICAgKTtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gVGFncyBhIHByb3BlcnR5IGFzIHVuaXF1ZVxuICogQHN1bW1hcnkgRGVjb3JhdG9yIHRoYXQgZW5zdXJlcyBhIHByb3BlcnR5IHZhbHVlIGlzIHVuaXF1ZSBhY3Jvc3MgYWxsIGluc3RhbmNlcyBvZiBhIG1vZGVsIGluIHRoZSBkYXRhYmFzZVxuICogQHJldHVybiB7RnVuY3Rpb259IEEgZGVjb3JhdG9yIGZ1bmN0aW9uIHRoYXQgY2FuIGJlIGFwcGxpZWQgdG8gYSBjbGFzcyBwcm9wZXJ0eVxuICogQGZ1bmN0aW9uIHVuaXF1ZVxuICogQGNhdGVnb3J5IFByb3BlcnR5IERlY29yYXRvcnNcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjbGFzcyBVc2VyIGV4dGVuZHMgQmFzZU1vZGVsIHtcbiAqICAgQHVuaXF1ZSgpXG4gKiAgIEByZXF1aXJlZCgpXG4gKiAgIHVzZXJuYW1lITogc3RyaW5nO1xuICogfVxuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1bmlxdWUoKSB7XG4gIHJldHVybiBhcHBseShcbiAgICBvbkNyZWF0ZVVwZGF0ZSh1bmlxdWVPbkNyZWF0ZVVwZGF0ZSksXG4gICAgcHJvcE1ldGFkYXRhKFJlcG9zaXRvcnkua2V5KFBlcnNpc3RlbmNlS2V5cy5VTklRVUUpLCB7fSlcbiAgKTtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gSGFuZGxlcyB1c2VyIGlkZW50aWZpY2F0aW9uIGZvciBvd25lcnNoaXAgdHJhY2tpbmdcbiAqIEBzdW1tYXJ5IEludGVybmFsIGZ1bmN0aW9uIHVzZWQgYnkgdGhlIGNyZWF0ZWRCeSBhbmQgdXBkYXRlZEJ5IGRlY29yYXRvcnMgdG8gc2V0IG93bmVyc2hpcCBpbmZvcm1hdGlvblxuICogQHRlbXBsYXRlIE0gLSBUaGUgbW9kZWwgdHlwZSBleHRlbmRpbmcgTW9kZWxcbiAqIEB0ZW1wbGF0ZSBSIC0gVGhlIHJlcG9zaXRvcnkgdHlwZSBleHRlbmRpbmcgUmVwbzxNLCBGLCBDPlxuICogQHRlbXBsYXRlIFYgLSBUaGUgcmVsYXRpb25zIG1ldGFkYXRhIHR5cGUgZXh0ZW5kaW5nIFJlbGF0aW9uc01ldGFkYXRhXG4gKiBAdGVtcGxhdGUgRiAtIFRoZSByZXBvc2l0b3J5IGZsYWdzIHR5cGVcbiAqIEB0ZW1wbGF0ZSBDIC0gVGhlIGNvbnRleHQgdHlwZSBleHRlbmRpbmcgQ29udGV4dDxGPlxuICogQHBhcmFtIHtSfSB0aGlzIC0gVGhlIHJlcG9zaXRvcnkgaW5zdGFuY2VcbiAqIEBwYXJhbSB7Q29udGV4dDxGPn0gY29udGV4dCAtIFRoZSBjb250ZXh0IGZvciB0aGUgb3BlcmF0aW9uXG4gKiBAcGFyYW0ge1Z9IGRhdGEgLSBUaGUgbWV0YWRhdGEgZm9yIHRoZSBwcm9wZXJ0eVxuICogQHBhcmFtIGtleSAtIFRoZSBwcm9wZXJ0eSBrZXkgdG8gc3RvcmUgdGhlIHVzZXIgaWRlbnRpZmllclxuICogQHBhcmFtIHtNfSBtb2RlbCAtIFRoZSBtb2RlbCBpbnN0YW5jZSBiZWluZyBjcmVhdGVkIG9yIHVwZGF0ZWRcbiAqIEByZXR1cm4ge1Byb21pc2U8dm9pZD59IEEgcHJvbWlzZSB0aGF0IHJlamVjdHMgd2l0aCBhbiBBdXRob3JpemF0aW9uRXJyb3IgaWYgdXNlciBpZGVudGlmaWNhdGlvbiBpcyBub3Qgc3VwcG9ydGVkXG4gKiBAZnVuY3Rpb24gY3JlYXRlZEJ5T25DcmVhdGVVcGRhdGVcbiAqIEBtZW1iZXJPZiBtb2R1bGU6Y29yZVxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gY3JlYXRlZEJ5T25DcmVhdGVVcGRhdGU8XG4gIE0gZXh0ZW5kcyBNb2RlbCxcbiAgUiBleHRlbmRzIFJlcG88TSwgRiwgQz4sXG4gIFYgZXh0ZW5kcyBSZWxhdGlvbnNNZXRhZGF0YSxcbiAgRiBleHRlbmRzIFJlcG9zaXRvcnlGbGFncyxcbiAgQyBleHRlbmRzIENvbnRleHQ8Rj4sXG4+KFxuICB0aGlzOiBSLFxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gIGNvbnRleHQ6IENvbnRleHQ8Rj4sXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgZGF0YTogVixcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICBrZXk6IGtleW9mIE0sXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgbW9kZWw6IE1cbik6IFByb21pc2U8dm9pZD4ge1xuICB0aHJvdyBuZXcgQXV0aG9yaXphdGlvbkVycm9yKFxuICAgIFwiVGhpcyBhZGFwdGVyIGRvZXMgbm90IHN1cHBvcnQgdXNlciBpZGVudGlmaWNhdGlvblwiXG4gICk7XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIFRyYWNrcyB0aGUgY3JlYXRvciBvZiBhIG1vZGVsIGluc3RhbmNlXG4gKiBAc3VtbWFyeSBEZWNvcmF0b3IgdGhhdCBtYXJrcyBhIHByb3BlcnR5IHRvIHN0b3JlIHRoZSBpZGVudGlmaWVyIG9mIHRoZSB1c2VyIHdobyBjcmVhdGVkIHRoZSBtb2RlbCBpbnN0YW5jZVxuICogQHJldHVybiB7RnVuY3Rpb259IEEgZGVjb3JhdG9yIGZ1bmN0aW9uIHRoYXQgY2FuIGJlIGFwcGxpZWQgdG8gYSBjbGFzcyBwcm9wZXJ0eVxuICogQGZ1bmN0aW9uIGNyZWF0ZWRCeVxuICogQGNhdGVnb3J5IFByb3BlcnR5IERlY29yYXRvcnNcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjbGFzcyBEb2N1bWVudCBleHRlbmRzIEJhc2VNb2RlbCB7XG4gKiAgIEBjcmVhdGVkQnkoKVxuICogICBjcmVhdG9yITogc3RyaW5nO1xuICogfVxuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVkQnkoKSB7XG4gIGNvbnN0IGtleSA9IFJlcG9zaXRvcnkua2V5KFBlcnNpc3RlbmNlS2V5cy5DUkVBVEVEX0JZKTtcbiAgcmV0dXJuIERlY29yYXRpb24uZm9yKGtleSlcbiAgICAuZGVmaW5lKG9uQ3JlYXRlKGNyZWF0ZWRCeU9uQ3JlYXRlVXBkYXRlKSwgcHJvcE1ldGFkYXRhKGtleSwge30pKVxuICAgIC5hcHBseSgpO1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBUcmFja3MgdGhlIGxhc3QgdXBkYXRlciBvZiBhIG1vZGVsIGluc3RhbmNlXG4gKiBAc3VtbWFyeSBEZWNvcmF0b3IgdGhhdCBtYXJrcyBhIHByb3BlcnR5IHRvIHN0b3JlIHRoZSBpZGVudGlmaWVyIG9mIHRoZSB1c2VyIHdobyBsYXN0IHVwZGF0ZWQgdGhlIG1vZGVsIGluc3RhbmNlXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn0gQSBkZWNvcmF0b3IgZnVuY3Rpb24gdGhhdCBjYW4gYmUgYXBwbGllZCB0byBhIGNsYXNzIHByb3BlcnR5XG4gKiBAZnVuY3Rpb24gdXBkYXRlZEJ5XG4gKiBAY2F0ZWdvcnkgUHJvcGVydHkgRGVjb3JhdG9yc1xuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNsYXNzIERvY3VtZW50IGV4dGVuZHMgQmFzZU1vZGVsIHtcbiAqICAgQHVwZGF0ZWRCeSgpXG4gKiAgIGxhc3RFZGl0b3IhOiBzdHJpbmc7XG4gKiB9XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHVwZGF0ZWRCeSgpIHtcbiAgY29uc3Qga2V5ID0gUmVwb3NpdG9yeS5rZXkoUGVyc2lzdGVuY2VLZXlzLlVQREFURURfQlkpO1xuICByZXR1cm4gRGVjb3JhdGlvbi5mb3Ioa2V5KVxuICAgIC5kZWZpbmUob25DcmVhdGVVcGRhdGUoY3JlYXRlZEJ5T25DcmVhdGVVcGRhdGUpLCBwcm9wTWV0YWRhdGEoa2V5LCB7fSkpXG4gICAgLmFwcGx5KCk7XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIERlZmluZXMgYSBvbmUtdG8tb25lIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIG1vZGVsc1xuICogQHN1bW1hcnkgRGVjb3JhdG9yIHRoYXQgZXN0YWJsaXNoZXMgYSBvbmUtdG8tb25lIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHRoZSBjdXJyZW50IG1vZGVsIGFuZCBhbm90aGVyIG1vZGVsXG4gKiBAdGVtcGxhdGUgTSAtIFRoZSByZWxhdGVkIG1vZGVsIHR5cGUgZXh0ZW5kaW5nIE1vZGVsXG4gKiBAcGFyYW0ge0NvbnN0cnVjdG9yPE0+fSBjbGF6eiAtIFRoZSBjb25zdHJ1Y3RvciBvZiB0aGUgcmVsYXRlZCBtb2RlbCBjbGFzc1xuICogQHBhcmFtIHtDYXNjYWRlTWV0YWRhdGF9IFtjYXNjYWRlT3B0aW9ucz1EZWZhdWx0Q2FzY2FkZV0gLSBPcHRpb25zIGZvciBjYXNjYWRpbmcgb3BlcmF0aW9ucyAoY3JlYXRlLCB1cGRhdGUsIGRlbGV0ZSlcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW3BvcHVsYXRlPXRydWVdIC0gSWYgdHJ1ZSwgYXV0b21hdGljYWxseSBwb3B1bGF0ZXMgdGhlIHJlbGF0aW9uc2hpcCB3aGVuIHRoZSBtb2RlbCBpcyByZXRyaWV2ZWRcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufSBBIGRlY29yYXRvciBmdW5jdGlvbiB0aGF0IGNhbiBiZSBhcHBsaWVkIHRvIGEgY2xhc3MgcHJvcGVydHlcbiAqIEBmdW5jdGlvbiBvbmVUb09uZVxuICogQGNhdGVnb3J5IFByb3BlcnR5IERlY29yYXRvcnNcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjbGFzcyBVc2VyIGV4dGVuZHMgQmFzZU1vZGVsIHtcbiAqICAgQG9uZVRvT25lKFByb2ZpbGUpXG4gKiAgIHByb2ZpbGUhOiBzdHJpbmcgfCBQcm9maWxlO1xuICogfVxuICpcbiAqIGNsYXNzIFByb2ZpbGUgZXh0ZW5kcyBCYXNlTW9kZWwge1xuICogICBAcmVxdWlyZWQoKVxuICogICBiaW8hOiBzdHJpbmc7XG4gKiB9XG4gKiBgYGBcbiAqIEBzZWUgb25lVG9NYW55XG4gKiBAc2VlIG1hbnlUb09uZVxuICovXG5leHBvcnQgZnVuY3Rpb24gb25lVG9PbmU8TSBleHRlbmRzIE1vZGVsPihcbiAgY2xheno6IENvbnN0cnVjdG9yPE0+LFxuICBjYXNjYWRlT3B0aW9uczogQ2FzY2FkZU1ldGFkYXRhID0gRGVmYXVsdENhc2NhZGUsXG4gIHBvcHVsYXRlOiBib29sZWFuID0gdHJ1ZVxuKSB7XG4gIE1vZGVsLnJlZ2lzdGVyKGNsYXp6KTtcbiAgY29uc3QgbWV0YWRhdGE6IFJlbGF0aW9uc01ldGFkYXRhID0ge1xuICAgIGNsYXNzOiBjbGF6ei5uYW1lLFxuICAgIGNhc2NhZGU6IGNhc2NhZGVPcHRpb25zLFxuICAgIHBvcHVsYXRlOiBwb3B1bGF0ZSxcbiAgfTtcbiAgY29uc3Qga2V5ID0gUmVwb3NpdG9yeS5rZXkoUGVyc2lzdGVuY2VLZXlzLk9ORV9UT19PTkUpO1xuICByZXR1cm4gRGVjb3JhdGlvbi5mb3Ioa2V5KVxuICAgIC5kZWZpbmUoXG4gICAgICBwcm9wKFBlcnNpc3RlbmNlS2V5cy5SRUxBVElPTlMpLFxuICAgICAgdHlwZShbY2xhenoubmFtZSwgU3RyaW5nLm5hbWUsIE51bWJlci5uYW1lLCBCaWdJbnQubmFtZV0pLFxuICAgICAgb25DcmVhdGUob25lVG9PbmVPbkNyZWF0ZSwgbWV0YWRhdGEpLFxuICAgICAgb25VcGRhdGUob25lVG9PbmVPblVwZGF0ZSwgbWV0YWRhdGEpLFxuICAgICAgb25EZWxldGUob25lVG9PbmVPbkRlbGV0ZSwgbWV0YWRhdGEpLFxuICAgICAgYWZ0ZXJBbnkocG9wLCBtZXRhZGF0YSksXG4gICAgICBwcm9wTWV0YWRhdGEoa2V5LCBtZXRhZGF0YSlcbiAgICApXG4gICAgLmFwcGx5KCk7XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIERlZmluZXMgYSBvbmUtdG8tbWFueSByZWxhdGlvbnNoaXAgYmV0d2VlbiBtb2RlbHNcbiAqIEBzdW1tYXJ5IERlY29yYXRvciB0aGF0IGVzdGFibGlzaGVzIGEgb25lLXRvLW1hbnkgcmVsYXRpb25zaGlwIGJldHdlZW4gdGhlIGN1cnJlbnQgbW9kZWwgYW5kIG11bHRpcGxlIGluc3RhbmNlcyBvZiBhbm90aGVyIG1vZGVsXG4gKiBAdGVtcGxhdGUgTSAtIFRoZSByZWxhdGVkIG1vZGVsIHR5cGUgZXh0ZW5kaW5nIE1vZGVsXG4gKiBAcGFyYW0ge0NvbnN0cnVjdG9yPE0+fSBjbGF6eiAtIFRoZSBjb25zdHJ1Y3RvciBvZiB0aGUgcmVsYXRlZCBtb2RlbCBjbGFzc1xuICogQHBhcmFtIHtDYXNjYWRlTWV0YWRhdGF9IFtjYXNjYWRlT3B0aW9ucz1EZWZhdWx0Q2FzY2FkZV0gLSBPcHRpb25zIGZvciBjYXNjYWRpbmcgb3BlcmF0aW9ucyAoY3JlYXRlLCB1cGRhdGUsIGRlbGV0ZSlcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW3BvcHVsYXRlPXRydWVdIC0gSWYgdHJ1ZSwgYXV0b21hdGljYWxseSBwb3B1bGF0ZXMgdGhlIHJlbGF0aW9uc2hpcCB3aGVuIHRoZSBtb2RlbCBpcyByZXRyaWV2ZWRcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufSBBIGRlY29yYXRvciBmdW5jdGlvbiB0aGF0IGNhbiBiZSBhcHBsaWVkIHRvIGEgY2xhc3MgcHJvcGVydHlcbiAqIEBmdW5jdGlvbiBvbmVUb01hbnlcbiAqIEBjYXRlZ29yeSBQcm9wZXJ0eSBEZWNvcmF0b3JzXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY2xhc3MgQXV0aG9yIGV4dGVuZHMgQmFzZU1vZGVsIHtcbiAqICAgQHJlcXVpcmVkKClcbiAqICAgbmFtZSE6IHN0cmluZztcbiAqXG4gKiAgIEBvbmVUb01hbnkoQm9vaylcbiAqICAgYm9va3MhOiBzdHJpbmdbXSB8IEJvb2tbXTtcbiAqIH1cbiAqXG4gKiBjbGFzcyBCb29rIGV4dGVuZHMgQmFzZU1vZGVsIHtcbiAqICAgQHJlcXVpcmVkKClcbiAqICAgdGl0bGUhOiBzdHJpbmc7XG4gKiB9XG4gKiBgYGBcbiAqIEBzZWUgb25lVG9PbmVcbiAqIEBzZWUgbWFueVRvT25lXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBvbmVUb01hbnk8TSBleHRlbmRzIE1vZGVsPihcbiAgY2xheno6IENvbnN0cnVjdG9yPE0+LFxuICBjYXNjYWRlT3B0aW9uczogQ2FzY2FkZU1ldGFkYXRhID0gRGVmYXVsdENhc2NhZGUsXG4gIHBvcHVsYXRlOiBib29sZWFuID0gdHJ1ZVxuKSB7XG4gIE1vZGVsLnJlZ2lzdGVyKGNsYXp6KTtcbiAgY29uc3QgbWV0YWRhdGE6IFJlbGF0aW9uc01ldGFkYXRhID0ge1xuICAgIGNsYXNzOiBjbGF6ei5uYW1lLFxuICAgIGNhc2NhZGU6IGNhc2NhZGVPcHRpb25zLFxuICAgIHBvcHVsYXRlOiBwb3B1bGF0ZSxcbiAgfTtcbiAgY29uc3Qga2V5ID0gUmVwb3NpdG9yeS5rZXkoUGVyc2lzdGVuY2VLZXlzLk9ORV9UT19NQU5ZKTtcbiAgcmV0dXJuIERlY29yYXRpb24uZm9yKGtleSlcbiAgICAuZGVmaW5lKFxuICAgICAgcHJvcChQZXJzaXN0ZW5jZUtleXMuUkVMQVRJT05TKSxcbiAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgcHVycG9zZWZ1bCBvdmVycmlkZVxuICAgICAgbGlzdChbY2xhenosIFN0cmluZywgTnVtYmVyLCBCaWdJbnRdKSxcbiAgICAgIG9uQ3JlYXRlKG9uZVRvTWFueU9uQ3JlYXRlLCBtZXRhZGF0YSksXG4gICAgICBvblVwZGF0ZShvbmVUb01hbnlPblVwZGF0ZSwgbWV0YWRhdGEpLFxuICAgICAgb25EZWxldGUob25lVG9NYW55T25EZWxldGUsIG1ldGFkYXRhKSxcbiAgICAgIGFmdGVyQW55KHBvcCwgbWV0YWRhdGEpLFxuICAgICAgcHJvcE1ldGFkYXRhKGtleSwgbWV0YWRhdGEpXG4gICAgKVxuICAgIC5hcHBseSgpO1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBEZWZpbmVzIGEgbWFueS10by1vbmUgcmVsYXRpb25zaGlwIGJldHdlZW4gbW9kZWxzXG4gKiBAc3VtbWFyeSBEZWNvcmF0b3IgdGhhdCBlc3RhYmxpc2hlcyBhIG1hbnktdG8tb25lIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIG11bHRpcGxlIGluc3RhbmNlcyBvZiB0aGUgY3VycmVudCBtb2RlbCBhbmQgYW5vdGhlciBtb2RlbFxuICogQHRlbXBsYXRlIE0gLSBUaGUgcmVsYXRlZCBtb2RlbCB0eXBlIGV4dGVuZGluZyBNb2RlbFxuICogQHBhcmFtIHtDb25zdHJ1Y3RvcjxNPn0gY2xhenogLSBUaGUgY29uc3RydWN0b3Igb2YgdGhlIHJlbGF0ZWQgbW9kZWwgY2xhc3NcbiAqIEBwYXJhbSB7Q2FzY2FkZU1ldGFkYXRhfSBbY2FzY2FkZU9wdGlvbnM9RGVmYXVsdENhc2NhZGVdIC0gT3B0aW9ucyBmb3IgY2FzY2FkaW5nIG9wZXJhdGlvbnMgKGNyZWF0ZSwgdXBkYXRlLCBkZWxldGUpXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtwb3B1bGF0ZT10cnVlXSAtIElmIHRydWUsIGF1dG9tYXRpY2FsbHkgcG9wdWxhdGVzIHRoZSByZWxhdGlvbnNoaXAgd2hlbiB0aGUgbW9kZWwgaXMgcmV0cmlldmVkXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn0gQSBkZWNvcmF0b3IgZnVuY3Rpb24gdGhhdCBjYW4gYmUgYXBwbGllZCB0byBhIGNsYXNzIHByb3BlcnR5XG4gKiBAZnVuY3Rpb24gbWFueVRvT25lXG4gKiBAY2F0ZWdvcnkgUHJvcGVydHkgRGVjb3JhdG9yc1xuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNsYXNzIEJvb2sgZXh0ZW5kcyBCYXNlTW9kZWwge1xuICogICBAcmVxdWlyZWQoKVxuICogICB0aXRsZSE6IHN0cmluZztcbiAqXG4gKiAgIEBtYW55VG9PbmUoQXV0aG9yKVxuICogICBhdXRob3IhOiBzdHJpbmcgfCBBdXRob3I7XG4gKiB9XG4gKlxuICogY2xhc3MgQXV0aG9yIGV4dGVuZHMgQmFzZU1vZGVsIHtcbiAqICAgQHJlcXVpcmVkKClcbiAqICAgbmFtZSE6IHN0cmluZztcbiAqIH1cbiAqIGBgYFxuICogQHNlZSBvbmVUb01hbnlcbiAqIEBzZWUgb25lVG9PbmVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1hbnlUb09uZTxNIGV4dGVuZHMgTW9kZWw+KFxuICBjbGF6ejogQ29uc3RydWN0b3I8TT4sXG4gIGNhc2NhZGVPcHRpb25zOiBDYXNjYWRlTWV0YWRhdGEgPSBEZWZhdWx0Q2FzY2FkZSxcbiAgcG9wdWxhdGUgPSB0cnVlXG4pIHtcbiAgTW9kZWwucmVnaXN0ZXIoY2xhenopO1xuICBjb25zdCBtZXRhZGF0YTogUmVsYXRpb25zTWV0YWRhdGEgPSB7XG4gICAgY2xhc3M6IGNsYXp6Lm5hbWUsXG4gICAgY2FzY2FkZTogY2FzY2FkZU9wdGlvbnMsXG4gICAgcG9wdWxhdGU6IHBvcHVsYXRlLFxuICB9O1xuICBjb25zdCBrZXkgPSBSZXBvc2l0b3J5LmtleShQZXJzaXN0ZW5jZUtleXMuTUFOWV9UT19PTkUpO1xuICByZXR1cm4gRGVjb3JhdGlvbi5mb3Ioa2V5KVxuICAgIC5kZWZpbmUoXG4gICAgICBwcm9wKFBlcnNpc3RlbmNlS2V5cy5SRUxBVElPTlMpLFxuICAgICAgdHlwZShbY2xhenoubmFtZSwgU3RyaW5nLm5hbWUsIE51bWJlci5uYW1lLCBCaWdJbnQubmFtZV0pLFxuICAgICAgLy8gb25DcmVhdGUob25lVG9NYW55T25DcmVhdGUsIG1ldGFkYXRhKSxcbiAgICAgIC8vIG9uVXBkYXRlKG9uZVRvTWFueU9uVXBkYXRlLCBtZXRhZGF0YSksXG4gICAgICAvLyBvbkRlbGV0ZShvbmVUb01hbnlPbkRlbGV0ZSwgbWV0YWRhdGEpLFxuICAgICAgLy8gYWZ0ZXJBbGwocG9wdWxhdGUsIG1ldGFkYXRhKSxcbiAgICAgIHByb3BNZXRhZGF0YShrZXksIG1ldGFkYXRhKVxuICAgIClcbiAgICAuYXBwbHkoKTtcbn1cbiIsImltcG9ydCB7XG4gIERlY29yYXRpb24sXG4gIE1vZGVsLFxuICBwcm9wTWV0YWRhdGEsXG4gIHJlcXVpcmVkLFxufSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQge1xuICBEZWZhdWx0U2VxdWVuY2VPcHRpb25zLFxuICBTZXF1ZW5jZU9wdGlvbnMsXG59IGZyb20gXCIuLi9pbnRlcmZhY2VzL1NlcXVlbmNlT3B0aW9uc1wiO1xuaW1wb3J0IHtcbiAgREJLZXlzLFxuICBJbnRlcm5hbEVycm9yLFxuICBvbkNyZWF0ZSxcbiAgcmVhZG9ubHksXG4gIFJlcG9zaXRvcnlGbGFncyxcbn0gZnJvbSBcIkBkZWNhZi10cy9kYi1kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBSZXBvLCBSZXBvc2l0b3J5IH0gZnJvbSBcIi4uL3JlcG9zaXRvcnkvUmVwb3NpdG9yeVwiO1xuaW1wb3J0IHsgaW5kZXggfSBmcm9tIFwiLi4vbW9kZWwvZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHsgc2VxdWVuY2VOYW1lRm9yTW9kZWwgfSBmcm9tIFwiLi91dGlsc1wiO1xuaW1wb3J0IHsgU2VxdWVuY2UgfSBmcm9tIFwiLi4vcGVyc2lzdGVuY2UvU2VxdWVuY2VcIjtcbmltcG9ydCB7IENvbnRleHQgfSBmcm9tIFwiQGRlY2FmLXRzL2RiLWRlY29yYXRvcnNcIjtcbmltcG9ydCB7IE9yZGVyRGlyZWN0aW9uIH0gZnJvbSBcIi4uL3JlcG9zaXRvcnlcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gQ2FsbGJhY2sgZnVuY3Rpb24gZm9yIHByaW1hcnkga2V5IGNyZWF0aW9uXG4gKiBAc3VtbWFyeSBIYW5kbGVzIHRoZSBjcmVhdGlvbiBvZiBwcmltYXJ5IGtleSB2YWx1ZXMgZm9yIG1vZGVscyB1c2luZyBzZXF1ZW5jZXNcbiAqIEB0ZW1wbGF0ZSBNIC0gVHlwZSB0aGF0IGV4dGVuZHMgTW9kZWxcbiAqIEB0ZW1wbGF0ZSBSIC0gVHlwZSB0aGF0IGV4dGVuZHMgUmVwbzxNLCBGLCBDPlxuICogQHRlbXBsYXRlIFYgLSBUeXBlIHRoYXQgZXh0ZW5kcyBTZXF1ZW5jZU9wdGlvbnNcbiAqIEB0ZW1wbGF0ZSBGIC0gVHlwZSB0aGF0IGV4dGVuZHMgUmVwb3NpdG9yeUZsYWdzXG4gKiBAdGVtcGxhdGUgQyAtIFR5cGUgdGhhdCBleHRlbmRzIENvbnRleHQ8Rj5cbiAqIEBwYXJhbSB7Q29udGV4dDxGPn0gY29udGV4dCAtIFRoZSBleGVjdXRpb24gY29udGV4dFxuICogQHBhcmFtIHtWfSBkYXRhIC0gVGhlIHNlcXVlbmNlIG9wdGlvbnNcbiAqIEBwYXJhbSBrZXkgLSBUaGUgcHJvcGVydHkga2V5IHRvIHNldCBhcyBwcmltYXJ5IGtleVxuICogQHBhcmFtIHtNfSBtb2RlbCAtIFRoZSBtb2RlbCBpbnN0YW5jZVxuICogQHJldHVybiB7UHJvbWlzZTx2b2lkPn0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiB0aGUgcHJpbWFyeSBrZXkgaXMgc2V0XG4gKiBAZnVuY3Rpb24gcGtPbkNyZWF0ZVxuICogQGNhdGVnb3J5IFByb3BlcnR5IERlY29yYXRvcnNcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgTW9kZWxcbiAqICAgcGFydGljaXBhbnQgcGtPbkNyZWF0ZVxuICogICBwYXJ0aWNpcGFudCBBZGFwdGVyXG4gKiAgIHBhcnRpY2lwYW50IFNlcXVlbmNlXG4gKlxuICogICBNb2RlbC0+PnBrT25DcmVhdGU6IENhbGwgd2l0aCBtb2RlbCBpbnN0YW5jZVxuICogICBOb3RlIG92ZXIgcGtPbkNyZWF0ZTogQ2hlY2sgaWYga2V5IGFscmVhZHkgZXhpc3RzXG4gKiAgIGFsdCBLZXkgZXhpc3RzIG9yIG5vIHR5cGUgc3BlY2lmaWVkXG4gKiAgICAgcGtPbkNyZWF0ZS0tPj5Nb2RlbDogUmV0dXJuIGVhcmx5XG4gKiAgIGVsc2UgS2V5IG5lZWRzIHRvIGJlIGNyZWF0ZWRcbiAqICAgICBwa09uQ3JlYXRlLT4+cGtPbkNyZWF0ZTogR2VuZXJhdGUgc2VxdWVuY2UgbmFtZSBpZiBub3QgcHJvdmlkZWRcbiAqICAgICBwa09uQ3JlYXRlLT4+QWRhcHRlcjogUmVxdWVzdCBTZXF1ZW5jZShkYXRhKVxuICogICAgIEFkYXB0ZXItPj5TZXF1ZW5jZTogQ3JlYXRlIHNlcXVlbmNlXG4gKiAgICAgU2VxdWVuY2UtLT4+cGtPbkNyZWF0ZTogUmV0dXJuIHNlcXVlbmNlXG4gKiAgICAgcGtPbkNyZWF0ZS0+PlNlcXVlbmNlOiBDYWxsIG5leHQoKVxuICogICAgIFNlcXVlbmNlLS0+PnBrT25DcmVhdGU6IFJldHVybiBuZXh0IHZhbHVlXG4gKiAgICAgcGtPbkNyZWF0ZS0+Pk1vZGVsOiBTZXQgcHJpbWFyeSBrZXkgdmFsdWVcbiAqICAgZW5kXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBwa09uQ3JlYXRlPFxuICBNIGV4dGVuZHMgTW9kZWwsXG4gIFIgZXh0ZW5kcyBSZXBvPE0sIEYsIEM+LFxuICBWIGV4dGVuZHMgU2VxdWVuY2VPcHRpb25zLFxuICBGIGV4dGVuZHMgUmVwb3NpdG9yeUZsYWdzLFxuICBDIGV4dGVuZHMgQ29udGV4dDxGPixcbj4oXG4gIHRoaXM6IFIsXG4gIGNvbnRleHQ6IENvbnRleHQ8Rj4sXG4gIGRhdGE6IFYsXG4gIGtleToga2V5b2YgTSxcbiAgbW9kZWw6IE1cbik6IFByb21pc2U8dm9pZD4ge1xuICBpZiAoIWRhdGEudHlwZSB8fCBtb2RlbFtrZXldKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgY29uc3Qgc2V0UHJpbWFyeUtleVZhbHVlID0gZnVuY3Rpb24gPE0gZXh0ZW5kcyBNb2RlbD4oXG4gICAgdGFyZ2V0OiBNLFxuICAgIHByb3BlcnR5S2V5OiBzdHJpbmcsXG4gICAgdmFsdWU6IHN0cmluZyB8IG51bWJlciB8IGJpZ2ludFxuICApIHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBwcm9wZXJ0eUtleSwge1xuICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgIHZhbHVlOiB2YWx1ZSxcbiAgICB9KTtcbiAgfTtcbiAgaWYgKCFkYXRhLm5hbWUpIGRhdGEubmFtZSA9IHNlcXVlbmNlTmFtZUZvck1vZGVsKG1vZGVsLCBcInBrXCIpO1xuICBsZXQgc2VxdWVuY2U6IFNlcXVlbmNlO1xuICB0cnkge1xuICAgIHNlcXVlbmNlID0gYXdhaXQgdGhpcy5hZGFwdGVyLlNlcXVlbmNlKGRhdGEpO1xuICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcbiAgICAgIGBGYWlsZWQgdG8gaW5zdGFudGlhdGUgU2VxdWVuY2UgJHtkYXRhLm5hbWV9OiAke2V9YFxuICAgICk7XG4gIH1cblxuICBjb25zdCBuZXh0ID0gYXdhaXQgc2VxdWVuY2UubmV4dCgpO1xuICBzZXRQcmltYXJ5S2V5VmFsdWUobW9kZWwsIGtleSBhcyBzdHJpbmcsIG5leHQpO1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBQcmltYXJ5IEtleSBEZWNvcmF0b3JcbiAqIEBzdW1tYXJ5IE1hcmtzIGEgcHJvcGVydHkgYXMgdGhlIG1vZGVsJ3MgcHJpbWFyeSBrZXkgd2l0aCBhdXRvbWF0aWMgc2VxdWVuY2UgZ2VuZXJhdGlvblxuICogVGhpcyBkZWNvcmF0b3IgY29tYmluZXMgbXVsdGlwbGUgYmVoYXZpb3JzOiBpdCBtYXJrcyB0aGUgcHJvcGVydHkgYXMgdW5pcXVlLCByZXF1aXJlZCxcbiAqIGFuZCBlbnN1cmVzIHRoZSBpbmRleCBpcyBjcmVhdGVkIHByb3Blcmx5IGFjY29yZGluZyB0byB0aGUgcHJvdmlkZWQgc2VxdWVuY2Ugb3B0aW9ucy5cbiAqIEBwYXJhbSB7T21pdDxTZXF1ZW5jZU9wdGlvbnMsIFwiY3ljbGVcIiB8IFwic3RhcnRXaXRoXCIgfCBcImluY3JlbWVudEJ5XCI+fSBvcHRzIC0gT3B0aW9ucyBmb3IgdGhlIHNlcXVlbmNlIGdlbmVyYXRpb25cbiAqIEByZXR1cm4ge1Byb3BlcnR5RGVjb3JhdG9yfSBBIHByb3BlcnR5IGRlY29yYXRvciB0aGF0IGNhbiBiZSBhcHBsaWVkIHRvIG1vZGVsIHByb3BlcnRpZXNcbiAqIEBmdW5jdGlvbiBwa1xuICogQGNhdGVnb3J5IFByb3BlcnR5IERlY29yYXRvcnNcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjbGFzcyBVc2VyIGV4dGVuZHMgQmFzZU1vZGVsIHtcbiAqICAgQHBrKClcbiAqICAgaWQhOiBzdHJpbmc7XG4gKlxuICogICBAcmVxdWlyZWQoKVxuICogICB1c2VybmFtZSE6IHN0cmluZztcbiAqIH1cbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gcGsoXG4gIG9wdHM6IE9taXQ8XG4gICAgU2VxdWVuY2VPcHRpb25zLFxuICAgIFwiY3ljbGVcIiB8IFwic3RhcnRXaXRoXCIgfCBcImluY3JlbWVudEJ5XCJcbiAgPiA9IERlZmF1bHRTZXF1ZW5jZU9wdGlvbnNcbikge1xuICBvcHRzID0gT2JqZWN0LmFzc2lnbih7fSwgRGVmYXVsdFNlcXVlbmNlT3B0aW9ucywgb3B0cykgYXMgU2VxdWVuY2VPcHRpb25zO1xuICBjb25zdCBrZXkgPSBSZXBvc2l0b3J5LmtleShEQktleXMuSUQpO1xuICByZXR1cm4gRGVjb3JhdGlvbi5mb3Ioa2V5KVxuICAgIC5kZWZpbmUoXG4gICAgICBpbmRleChbT3JkZXJEaXJlY3Rpb24uQVNDLCBPcmRlckRpcmVjdGlvbi5EU0NdKSxcbiAgICAgIHJlcXVpcmVkKCksXG4gICAgICByZWFkb25seSgpLFxuICAgICAgLy8gdHlwZShbU3RyaW5nLm5hbWUsIE51bWJlci5uYW1lLCBCaWdJbnQubmFtZV0pLFxuICAgICAgcHJvcE1ldGFkYXRhKGtleSwgb3B0cyBhcyBTZXF1ZW5jZU9wdGlvbnMpLFxuICAgICAgb25DcmVhdGUocGtPbkNyZWF0ZSwgb3B0cyBhcyBTZXF1ZW5jZU9wdGlvbnMpXG4gICAgKVxuICAgIC5hcHBseSgpO1xufVxuIiwiaW1wb3J0IHsgREJPcGVyYXRpb25zLCB0aW1lc3RhbXAgfSBmcm9tIFwiQGRlY2FmLXRzL2RiLWRlY29yYXRvcnNcIjtcbmltcG9ydCB7IE1vZGVsQXJnLCBNb2RlbCB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gQmFzZSBtb2RlbCBjbGFzcyBmb3IgYWxsIGRvbWFpbiBtb2RlbHNcbiAqIEBzdW1tYXJ5IEFuIGFic3RyYWN0IGJhc2UgY2xhc3MgdGhhdCBleHRlbmRzIHRoZSBNb2RlbCBjbGFzcyBmcm9tIGRlY29yYXRvci12YWxpZGF0aW9uIGFuZCBhZGRzIHRpbWVzdGFtcCBmdW5jdGlvbmFsaXR5LlxuICogQWxsIGRvbWFpbiBtb2RlbHMgaW4gdGhlIGFwcGxpY2F0aW9uIHNob3VsZCBleHRlbmQgdGhpcyBjbGFzcyB0byBpbmhlcml0IGNvbW1vbiBwcm9wZXJ0aWVzIGFuZCBiZWhhdmlvcnMuXG4gKiBAcGFyYW0ge01vZGVsQXJnPEJhc2VNb2RlbD59IGFyZyAtIE9wdGlvbmFsIGluaXRpYWxpemF0aW9uIGRhdGEgZm9yIHRoZSBtb2RlbFxuICogQGNsYXNzIEJhc2VNb2RlbFxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNsYXNzIFVzZXIgZXh0ZW5kcyBCYXNlTW9kZWwge1xuICogICBAcmVxdWlyZWQoKVxuICogICB1c2VybmFtZSE6IHN0cmluZztcbiAqICAgXG4gKiAgIEBlbWFpbCgpXG4gKiAgIGVtYWlsITogc3RyaW5nO1xuICogICBcbiAqICAgY29uc3RydWN0b3IoZGF0YT86IE1vZGVsQXJnPFVzZXI+KSB7XG4gKiAgICAgc3VwZXIoZGF0YSk7XG4gKiAgIH1cbiAqIH1cbiAqIFxuICogY29uc3QgdXNlciA9IG5ldyBVc2VyKHsgdXNlcm5hbWU6ICdqb2huJywgZW1haWw6ICdqb2huQGV4YW1wbGUuY29tJyB9KTtcbiAqIGBgYFxuICovXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgQmFzZU1vZGVsIGV4dGVuZHMgTW9kZWwge1xuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENyZWF0aW9uIHRpbWVzdGFtcCBmb3IgdGhlIG1vZGVsXG4gICAqIEBzdW1tYXJ5IEF1dG9tYXRpY2FsbHkgc2V0IHRvIHRoZSBjdXJyZW50IGRhdGUgYW5kIHRpbWUgd2hlbiB0aGUgbW9kZWwgaXMgY3JlYXRlZFxuICAgKi9cbiAgQHRpbWVzdGFtcChEQk9wZXJhdGlvbnMuQ1JFQVRFKVxuICBjcmVhdGVkT24hOiBEYXRlO1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gTGFzdCB1cGRhdGUgdGltZXN0YW1wIGZvciB0aGUgbW9kZWxcbiAgICogQHN1bW1hcnkgQXV0b21hdGljYWxseSB1cGRhdGVkIHRvIHRoZSBjdXJyZW50IGRhdGUgYW5kIHRpbWUgd2hlbmV2ZXIgdGhlIG1vZGVsIGlzIG1vZGlmaWVkXG4gICAqL1xuICBAdGltZXN0YW1wKClcbiAgdXBkYXRlZE9uITogRGF0ZTtcblxuICBwcm90ZWN0ZWQgY29uc3RydWN0b3IoYXJnPzogTW9kZWxBcmc8QmFzZU1vZGVsPikge1xuICAgIHN1cGVyKGFyZyk7XG4gIH1cbn1cbiIsImltcG9ydCB7IFBhZ2luZ0Vycm9yIH0gZnJvbSBcIi4vZXJyb3JzXCI7XG5pbXBvcnQgeyBBZGFwdGVyIH0gZnJvbSBcIi4uL3BlcnNpc3RlbmNlXCI7XG5pbXBvcnQgeyBDb25zdHJ1Y3RvciwgTW9kZWwgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEhhbmRsZXMgcGFnaW5hdGlvbiBmb3IgZGF0YWJhc2UgcXVlcmllc1xuICogQHN1bW1hcnkgUHJvdmlkZXMgZnVuY3Rpb25hbGl0eSBmb3IgbmF2aWdhdGluZyB0aHJvdWdoIHBhZ2luYXRlZCBxdWVyeSByZXN1bHRzXG4gKiBcbiAqIFRoaXMgYWJzdHJhY3QgY2xhc3MgbWFuYWdlcyB0aGUgc3RhdGUgYW5kIG5hdmlnYXRpb24gb2YgcGFnaW5hdGVkIGRhdGFiYXNlIHF1ZXJ5IHJlc3VsdHMuXG4gKiBJdCB0cmFja3MgdGhlIGN1cnJlbnQgcGFnZSwgdG90YWwgcGFnZXMsIGFuZCByZWNvcmQgY291bnQsIGFuZCBwcm92aWRlcyBtZXRob2RzIGZvclxuICogbW92aW5nIGJldHdlZW4gcGFnZXMuXG4gKiBcbiAqIEB0ZW1wbGF0ZSBNIC0gVGhlIG1vZGVsIHR5cGUgdGhpcyBwYWdpbmF0b3Igb3BlcmF0ZXMgb25cbiAqIEB0ZW1wbGF0ZSBSIC0gVGhlIHJldHVybiB0eXBlIG9mIHRoZSBwYWdpbmF0ZWQgcXVlcnkgKGRlZmF1bHRzIHRvIE1bXSlcbiAqIEB0ZW1wbGF0ZSBRIC0gVGhlIHF1ZXJ5IHR5cGUgKGRlZmF1bHRzIHRvIGFueSlcbiAqIEBwYXJhbSB7QWRhcHRlcjxhbnksIFEsIGFueSwgYW55Pn0gYWRhcHRlciAtIFRoZSBkYXRhYmFzZSBhZGFwdGVyIHRvIHVzZSBmb3IgZXhlY3V0aW5nIHF1ZXJpZXNcbiAqIEBwYXJhbSB7UX0gcXVlcnkgLSBUaGUgcXVlcnkgdG8gcGFnaW5hdGVcbiAqIEBwYXJhbSB7bnVtYmVyfSBzaXplIC0gVGhlIG51bWJlciBvZiByZWNvcmRzIHBlciBwYWdlXG4gKiBAcGFyYW0ge0NvbnN0cnVjdG9yPE0+fSBjbGF6eiAtIFRoZSBjb25zdHJ1Y3RvciBmb3IgdGhlIG1vZGVsIHR5cGVcbiAqIEBjbGFzcyBQYWdpbmF0b3JcbiAqIEBleGFtcGxlXG4gKiAvLyBDcmVhdGUgYSBwYWdpbmF0b3IgZm9yIGEgdXNlciBxdWVyeVxuICogY29uc3QgdXNlclF1ZXJ5ID0gZGIuc2VsZWN0KCkuZnJvbShVc2VyKTtcbiAqIGNvbnN0IHBhZ2luYXRvciA9IGF3YWl0IHVzZXJRdWVyeS5wYWdpbmF0ZSgxMCk7IC8vIDEwIHVzZXJzIHBlciBwYWdlXG4gKiBcbiAqIC8vIEdldCB0aGUgZmlyc3QgcGFnZSBvZiByZXN1bHRzXG4gKiBjb25zdCBmaXJzdFBhZ2UgPSBhd2FpdCBwYWdpbmF0b3IucGFnZSgxKTtcbiAqIFxuICogLy8gTmF2aWdhdGUgdG8gdGhlIG5leHQgcGFnZVxuICogY29uc3Qgc2Vjb25kUGFnZSA9IGF3YWl0IHBhZ2luYXRvci5uZXh0KCk7XG4gKiBcbiAqIC8vIEdldCBpbmZvcm1hdGlvbiBhYm91dCB0aGUgcGFnaW5hdGlvblxuICogY29uc29sZS5sb2coYFBhZ2UgJHtwYWdpbmF0b3IuY3VycmVudH0gb2YgJHtwYWdpbmF0b3IudG90YWx9LCAke3BhZ2luYXRvci5jb3VudH0gdG90YWwgcmVjb3Jkc2ApO1xuICogXG4gKiBAbWVybWFpZFxuICogc2VxdWVuY2VEaWFncmFtXG4gKiAgIHBhcnRpY2lwYW50IENsaWVudFxuICogICBwYXJ0aWNpcGFudCBQYWdpbmF0b3JcbiAqICAgcGFydGljaXBhbnQgQWRhcHRlclxuICogICBwYXJ0aWNpcGFudCBEYXRhYmFzZVxuICogICBcbiAqICAgQ2xpZW50LT4+UGFnaW5hdG9yOiBuZXcgUGFnaW5hdG9yKGFkYXB0ZXIsIHF1ZXJ5LCBzaXplLCBjbGF6eilcbiAqICAgQ2xpZW50LT4+UGFnaW5hdG9yOiBwYWdlKDEpXG4gKiAgIFBhZ2luYXRvci0+PlBhZ2luYXRvcjogdmFsaWRhdGVQYWdlKDEpXG4gKiAgIFBhZ2luYXRvci0+PlBhZ2luYXRvcjogcHJlcGFyZShxdWVyeSlcbiAqICAgUGFnaW5hdG9yLT4+QWRhcHRlcjogZXhlY3V0ZSBxdWVyeSB3aXRoIHBhZ2luYXRpb25cbiAqICAgQWRhcHRlci0+PkRhdGFiYXNlOiBleGVjdXRlIHF1ZXJ5XG4gKiAgIERhdGFiYXNlLS0+PkFkYXB0ZXI6IHJldHVybiByZXN1bHRzXG4gKiAgIEFkYXB0ZXItLT4+UGFnaW5hdG9yOiByZXR1cm4gcmVzdWx0c1xuICogICBQYWdpbmF0b3ItLT4+Q2xpZW50OiByZXR1cm4gcGFnZSByZXN1bHRzXG4gKiAgIFxuICogICBDbGllbnQtPj5QYWdpbmF0b3I6IG5leHQoKVxuICogICBQYWdpbmF0b3ItPj5QYWdpbmF0b3I6IHBhZ2UoY3VycmVudCArIDEpXG4gKiAgIFBhZ2luYXRvci0+PlBhZ2luYXRvcjogdmFsaWRhdGVQYWdlKGN1cnJlbnQgKyAxKVxuICogICBQYWdpbmF0b3ItPj5BZGFwdGVyOiBleGVjdXRlIHF1ZXJ5IHdpdGggcGFnaW5hdGlvblxuICogICBBZGFwdGVyLT4+RGF0YWJhc2U6IGV4ZWN1dGUgcXVlcnlcbiAqICAgRGF0YWJhc2UtLT4+QWRhcHRlcjogcmV0dXJuIHJlc3VsdHNcbiAqICAgQWRhcHRlci0tPj5QYWdpbmF0b3I6IHJldHVybiByZXN1bHRzXG4gKiAgIFBhZ2luYXRvci0tPj5DbGllbnQ6IHJldHVybiBwYWdlIHJlc3VsdHNcbiAqL1xuZXhwb3J0IGFic3RyYWN0IGNsYXNzIFBhZ2luYXRvcjxNIGV4dGVuZHMgTW9kZWwsIFIgPSBNW10sIFEgPSBhbnk+IHtcbiAgcHJvdGVjdGVkIF9jdXJyZW50UGFnZSE6IG51bWJlcjtcbiAgcHJvdGVjdGVkIF90b3RhbFBhZ2VzITogbnVtYmVyO1xuICBwcm90ZWN0ZWQgX3JlY29yZENvdW50ITogbnVtYmVyO1xuICBwcm90ZWN0ZWQgbGltaXQhOiBudW1iZXI7XG5cbiAgcHJpdmF0ZSBfc3RhdGVtZW50PzogUTtcblxuICBnZXQgY3VycmVudCgpIHtcbiAgICByZXR1cm4gdGhpcy5fY3VycmVudFBhZ2U7XG4gIH1cblxuICBnZXQgdG90YWwoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3RvdGFsUGFnZXM7XG4gIH1cblxuICBnZXQgY291bnQoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5fcmVjb3JkQ291bnQ7XG4gIH1cblxuICBwcm90ZWN0ZWQgZ2V0IHN0YXRlbWVudCgpIHtcbiAgICBpZiAoIXRoaXMuX3N0YXRlbWVudCkgdGhpcy5fc3RhdGVtZW50ID0gdGhpcy5wcmVwYXJlKHRoaXMucXVlcnkpO1xuICAgIHJldHVybiB0aGlzLl9zdGF0ZW1lbnQ7XG4gIH1cblxuICBwcm90ZWN0ZWQgY29uc3RydWN0b3IoXG4gICAgcHJvdGVjdGVkIHJlYWRvbmx5IGFkYXB0ZXI6IEFkYXB0ZXI8YW55LCBRLCBhbnksIGFueT4sXG4gICAgcHJvdGVjdGVkIHJlYWRvbmx5IHF1ZXJ5OiBRLFxuICAgIHJlYWRvbmx5IHNpemU6IG51bWJlcixcbiAgICBwcm90ZWN0ZWQgcmVhZG9ubHkgY2xheno6IENvbnN0cnVjdG9yPE0+XG4gICkge31cblxuICBwcm90ZWN0ZWQgYWJzdHJhY3QgcHJlcGFyZShyYXdTdGF0ZW1lbnQ6IFEpOiBRO1xuXG4gIGFzeW5jIG5leHQoKSB7XG4gICAgcmV0dXJuIHRoaXMucGFnZSh0aGlzLmN1cnJlbnQgKyAxKTtcbiAgfVxuXG4gIGFzeW5jIHByZXZpb3VzKCkge1xuICAgIHJldHVybiB0aGlzLnBhZ2UodGhpcy5jdXJyZW50IC0gMSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgdmFsaWRhdGVQYWdlKHBhZ2U6IG51bWJlcikge1xuICAgIGlmIChwYWdlIDwgMSB8fCAhTnVtYmVyLmlzSW50ZWdlcihwYWdlKSlcbiAgICAgIHRocm93IG5ldyBQYWdpbmdFcnJvcihcbiAgICAgICAgXCJQYWdlIG51bWJlciBjYW5ub3QgYmUgdW5kZXIgMSBhbmQgbXVzdCBiZSBhbiBpbnRlZ2VyXCJcbiAgICAgICk7XG4gICAgaWYgKHR5cGVvZiB0aGlzLl90b3RhbFBhZ2VzICE9PSBcInVuZGVmaW5lZFwiICYmIHBhZ2UgPiB0aGlzLl90b3RhbFBhZ2VzKVxuICAgICAgdGhyb3cgbmV3IFBhZ2luZ0Vycm9yKFxuICAgICAgICBgT25seSAke3RoaXMuX3RvdGFsUGFnZXN9IGFyZSBhdmFpbGFibGUuIENhbm5vdCBnbyB0byBwYWdlICR7cGFnZX1gXG4gICAgICApO1xuICAgIHJldHVybiBwYWdlO1xuICB9XG5cbiAgYWJzdHJhY3QgcGFnZShwYWdlPzogbnVtYmVyKTogUHJvbWlzZTxSW10+O1xufVxuIiwiaW1wb3J0IHsgdHlwZSBDb25zdHJ1Y3RvciwgTW9kZWwgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgdHlwZSB7IEV4ZWN1dG9yLCBSYXdFeGVjdXRvciB9IGZyb20gXCIuLi9pbnRlcmZhY2VzXCI7XG5pbXBvcnQgdHlwZSB7XG4gIEZyb21TZWxlY3RvcixcbiAgR3JvdXBCeVNlbGVjdG9yLFxuICBPcmRlckJ5U2VsZWN0b3IsXG4gIFNlbGVjdFNlbGVjdG9yLFxufSBmcm9tIFwiLi9zZWxlY3RvcnNcIjtcbmltcG9ydCB7IENvbmRpdGlvbiB9IGZyb20gXCIuL0NvbmRpdGlvblwiO1xuaW1wb3J0IHsgZmluZFByaW1hcnlLZXksIEludGVybmFsRXJyb3IgfSBmcm9tIFwiQGRlY2FmLXRzL2RiLWRlY29yYXRvcnNcIjtcbmltcG9ydCB7IGZpbmFsIH0gZnJvbSBcIi4uL3V0aWxzL2RlY29yYXRvcnNcIjtcbmltcG9ydCB0eXBlIHtcbiAgQ291bnRPcHRpb24sXG4gIERpc3RpbmN0T3B0aW9uLFxuICBMaW1pdE9wdGlvbixcbiAgTWF4T3B0aW9uLFxuICBNaW5PcHRpb24sXG4gIE9mZnNldE9wdGlvbixcbiAgT3JkZXJBbmRHcm91cE9wdGlvbixcbiAgU2VsZWN0T3B0aW9uLFxuICBXaGVyZU9wdGlvbixcbn0gZnJvbSBcIi4vb3B0aW9uc1wiO1xuaW1wb3J0IHsgUGFnaW5hdGFibGUgfSBmcm9tIFwiLi4vaW50ZXJmYWNlcy9QYWdpbmF0YWJsZVwiO1xuaW1wb3J0IHsgUGFnaW5hdG9yIH0gZnJvbSBcIi4vUGFnaW5hdG9yXCI7XG5pbXBvcnQgeyBBZGFwdGVyIH0gZnJvbSBcIi4uL3BlcnNpc3RlbmNlXCI7XG5pbXBvcnQgeyBRdWVyeUVycm9yIH0gZnJvbSBcIi4vZXJyb3JzXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEJhc2UgY2xhc3MgZm9yIGRhdGFiYXNlIHF1ZXJ5IHN0YXRlbWVudHNcbiAqIEBzdW1tYXJ5IFByb3ZpZGVzIGEgZm91bmRhdGlvbiBmb3IgYnVpbGRpbmcgYW5kIGV4ZWN1dGluZyBkYXRhYmFzZSBxdWVyaWVzXG4gKiBcbiAqIFRoaXMgYWJzdHJhY3QgY2xhc3MgaW1wbGVtZW50cyB0aGUgcXVlcnkgYnVpbGRlciBwYXR0ZXJuIGZvciBjb25zdHJ1Y3RpbmdcbiAqIGRhdGFiYXNlIHF1ZXJpZXMuIEl0IHN1cHBvcnRzIHZhcmlvdXMgcXVlcnkgb3BlcmF0aW9ucyBsaWtlIHNlbGVjdCwgZnJvbSxcbiAqIHdoZXJlLCBvcmRlckJ5LCBncm91cEJ5LCBsaW1pdCwgYW5kIG9mZnNldC4gSXQgYWxzbyBwcm92aWRlcyBtZXRob2RzIGZvclxuICogZXhlY3V0aW5nIHF1ZXJpZXMgYW5kIGhhbmRsaW5nIHBhZ2luYXRpb24uXG4gKiBcbiAqIEB0ZW1wbGF0ZSBRIC0gVGhlIHF1ZXJ5IHR5cGUgc3BlY2lmaWMgdG8gdGhlIGRhdGFiYXNlIGFkYXB0ZXJcbiAqIEB0ZW1wbGF0ZSBNIC0gVGhlIG1vZGVsIHR5cGUgdGhpcyBzdGF0ZW1lbnQgb3BlcmF0ZXMgb25cbiAqIEB0ZW1wbGF0ZSBSIC0gVGhlIHJldHVybiB0eXBlIG9mIHRoZSBxdWVyeVxuICogQHBhcmFtIHtBZGFwdGVyPGFueSwgUSwgYW55LCBhbnk+fSBhZGFwdGVyIC0gVGhlIGRhdGFiYXNlIGFkYXB0ZXIgdG8gdXNlIGZvciBleGVjdXRpbmcgcXVlcmllc1xuICogQGNsYXNzIFN0YXRlbWVudFxuICogQGV4YW1wbGVcbiAqIC8vIENyZWF0ZSBhIHN0YXRlbWVudCB0byBxdWVyeSB1c2Vyc1xuICogY29uc3Qgc3RhdGVtZW50ID0gbmV3IFNRTFN0YXRlbWVudChhZGFwdGVyKTtcbiAqIGNvbnN0IHVzZXJzID0gYXdhaXQgc3RhdGVtZW50XG4gKiAgIC5zZWxlY3QoKVxuICogICAuZnJvbShVc2VyKVxuICogICAud2hlcmUoQ29uZGl0aW9uLmF0dHJpYnV0ZShcInN0YXR1c1wiKS5lcShcImFjdGl2ZVwiKSlcbiAqICAgLm9yZGVyQnkoW1wiY3JlYXRlZEF0XCIsIFwiREVTQ1wiXSlcbiAqICAgLmxpbWl0KDEwKVxuICogICAuZXhlY3V0ZSgpO1xuICogXG4gKiAvLyBVc2UgcGFnaW5hdGlvblxuICogY29uc3QgcGFnaW5hdG9yID0gYXdhaXQgc3RhdGVtZW50XG4gKiAgIC5zZWxlY3QoKVxuICogICAuZnJvbShVc2VyKVxuICogICAucGFnaW5hdGUoMjApOyAvLyAyMCB1c2VycyBwZXIgcGFnZVxuICogXG4gKiBAbWVybWFpZFxuICogc2VxdWVuY2VEaWFncmFtXG4gKiAgIHBhcnRpY2lwYW50IENsaWVudFxuICogICBwYXJ0aWNpcGFudCBTdGF0ZW1lbnRcbiAqICAgcGFydGljaXBhbnQgQWRhcHRlclxuICogICBwYXJ0aWNpcGFudCBEYXRhYmFzZVxuICogICBcbiAqICAgQ2xpZW50LT4+U3RhdGVtZW50OiBzZWxlY3QoKVxuICogICBDbGllbnQtPj5TdGF0ZW1lbnQ6IGZyb20oTW9kZWwpXG4gKiAgIENsaWVudC0+PlN0YXRlbWVudDogd2hlcmUoY29uZGl0aW9uKVxuICogICBDbGllbnQtPj5TdGF0ZW1lbnQ6IG9yZGVyQnkoW2ZpZWxkLCBkaXJlY3Rpb25dKVxuICogICBDbGllbnQtPj5TdGF0ZW1lbnQ6IGxpbWl0KHZhbHVlKVxuICogICBDbGllbnQtPj5TdGF0ZW1lbnQ6IGV4ZWN1dGUoKVxuICogICBTdGF0ZW1lbnQtPj5TdGF0ZW1lbnQ6IGJ1aWxkKClcbiAqICAgU3RhdGVtZW50LT4+QWRhcHRlcjogcmF3KHF1ZXJ5KVxuICogICBBZGFwdGVyLT4+RGF0YWJhc2U6IGV4ZWN1dGUgcXVlcnlcbiAqICAgRGF0YWJhc2UtLT4+QWRhcHRlcjogcmV0dXJuIHJlc3VsdHNcbiAqICAgQWRhcHRlci0tPj5TdGF0ZW1lbnQ6IHJldHVybiBwcm9jZXNzZWQgcmVzdWx0c1xuICogICBTdGF0ZW1lbnQtLT4+Q2xpZW50OiByZXR1cm4gZmluYWwgcmVzdWx0c1xuICovXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgU3RhdGVtZW50PFEsIE0gZXh0ZW5kcyBNb2RlbCwgUj5cbiAgaW1wbGVtZW50cyBFeGVjdXRvcjxSPiwgUmF3RXhlY3V0b3I8UT4sIFBhZ2luYXRhYmxlPE0sIFIsIFE+XG57XG4gIHByb3RlY3RlZCByZWFkb25seSBzZWxlY3RTZWxlY3Rvcj86IFNlbGVjdFNlbGVjdG9yPE0+W107XG4gIHByb3RlY3RlZCBkaXN0aW5jdFNlbGVjdG9yPzogU2VsZWN0U2VsZWN0b3I8TT47XG4gIHByb3RlY3RlZCBtYXhTZWxlY3Rvcj86IFNlbGVjdFNlbGVjdG9yPE0+O1xuICBwcm90ZWN0ZWQgbWluU2VsZWN0b3I/OiBTZWxlY3RTZWxlY3RvcjxNPjtcbiAgcHJvdGVjdGVkIGNvdW50U2VsZWN0b3I/OiBTZWxlY3RTZWxlY3RvcjxNPjtcbiAgcHJvdGVjdGVkIGZyb21TZWxlY3RvciE6IENvbnN0cnVjdG9yPE0+O1xuICBwcm90ZWN0ZWQgd2hlcmVDb25kaXRpb24/OiBDb25kaXRpb248TT47XG4gIHByb3RlY3RlZCBvcmRlckJ5U2VsZWN0b3I/OiBPcmRlckJ5U2VsZWN0b3I8TT47XG4gIHByb3RlY3RlZCBncm91cEJ5U2VsZWN0b3I/OiBHcm91cEJ5U2VsZWN0b3I8TT47XG4gIHByb3RlY3RlZCBsaW1pdFNlbGVjdG9yPzogbnVtYmVyO1xuICBwcm90ZWN0ZWQgb2Zmc2V0U2VsZWN0b3I/OiBudW1iZXI7XG5cbiAgcHJvdGVjdGVkIGNvbnN0cnVjdG9yKHByb3RlY3RlZCBhZGFwdGVyOiBBZGFwdGVyPGFueSwgUSwgYW55LCBhbnk+KSB7fVxuXG4gIHNlbGVjdDxcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gICAgUyBleHRlbmRzIHJlYWRvbmx5IFNlbGVjdFNlbGVjdG9yPE0+W10sXG4gID4oKTogU2VsZWN0T3B0aW9uPE0sIE1bXT47XG4gIHNlbGVjdDxTIGV4dGVuZHMgcmVhZG9ubHkgU2VsZWN0U2VsZWN0b3I8TT5bXT4oXG4gICAgc2VsZWN0b3I6IHJlYWRvbmx5IFsuLi5TXVxuICApOiBTZWxlY3RPcHRpb248TSwgUGljazxNLCBTW251bWJlcl0+W10+O1xuXG4gIEBmaW5hbCgpXG4gIHNlbGVjdDxTIGV4dGVuZHMgcmVhZG9ubHkgU2VsZWN0U2VsZWN0b3I8TT5bXT4oXG4gICAgc2VsZWN0b3I/OiByZWFkb25seSBbLi4uU11cbiAgKTogU2VsZWN0T3B0aW9uPE0sIE1bXT4gfCBTZWxlY3RPcHRpb248TSwgUGljazxNLCBTW251bWJlcl0+W10+IHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgXCJzZWxlY3RTZWxlY3RvclwiLCB7XG4gICAgICB2YWx1ZTogc2VsZWN0b3IsXG4gICAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgfSk7XG4gICAgcmV0dXJuIHRoaXMgYXMgU2VsZWN0T3B0aW9uPE0sIE1bXT4gfCBTZWxlY3RPcHRpb248TSwgUGljazxNLCBTW251bWJlcl0+W10+O1xuICB9XG5cbiAgQGZpbmFsKClcbiAgZGlzdGluY3Q8UyBleHRlbmRzIFNlbGVjdFNlbGVjdG9yPE0+PihcbiAgICBzZWxlY3RvcjogU1xuICApOiBEaXN0aW5jdE9wdGlvbjxNLCBNW1NdW10+IHtcbiAgICB0aGlzLmRpc3RpbmN0U2VsZWN0b3IgPSBzZWxlY3RvcjtcbiAgICByZXR1cm4gdGhpcyBhcyBEaXN0aW5jdE9wdGlvbjxNLCBNW1NdW10+O1xuICB9XG5cbiAgQGZpbmFsKClcbiAgbWF4PFMgZXh0ZW5kcyBTZWxlY3RTZWxlY3RvcjxNPj4oc2VsZWN0b3I6IFMpOiBNYXhPcHRpb248TSwgTVtTXT4ge1xuICAgIHRoaXMubWF4U2VsZWN0b3IgPSBzZWxlY3RvcjtcbiAgICByZXR1cm4gdGhpcyBhcyBNYXhPcHRpb248TSwgTVtTXT47XG4gIH1cblxuICBAZmluYWwoKVxuICBtaW48UyBleHRlbmRzIFNlbGVjdFNlbGVjdG9yPE0+PihzZWxlY3RvcjogUyk6IE1pbk9wdGlvbjxNLCBNW1NdPiB7XG4gICAgdGhpcy5taW5TZWxlY3RvciA9IHNlbGVjdG9yO1xuICAgIHJldHVybiB0aGlzIGFzIE1pbk9wdGlvbjxNLCBNW1NdPjtcbiAgfVxuXG4gIEBmaW5hbCgpXG4gIGNvdW50PFMgZXh0ZW5kcyBTZWxlY3RTZWxlY3RvcjxNPj4oc2VsZWN0b3I/OiBTKTogQ291bnRPcHRpb248TSwgbnVtYmVyPiB7XG4gICAgdGhpcy5jb3VudFNlbGVjdG9yID0gc2VsZWN0b3I7XG4gICAgcmV0dXJuIHRoaXMgYXMgQ291bnRPcHRpb248TSwgbnVtYmVyPjtcbiAgfVxuXG4gIEBmaW5hbCgpXG4gIHB1YmxpYyBmcm9tKHNlbGVjdG9yOiBGcm9tU2VsZWN0b3I8TT4pOiBXaGVyZU9wdGlvbjxNLCBSPiB7XG4gICAgdGhpcy5mcm9tU2VsZWN0b3IgPSAoXG4gICAgICB0eXBlb2Ygc2VsZWN0b3IgPT09IFwic3RyaW5nXCIgPyBNb2RlbC5nZXQoc2VsZWN0b3IpIDogc2VsZWN0b3JcbiAgICApIGFzIENvbnN0cnVjdG9yPE0+O1xuICAgIGlmICghdGhpcy5mcm9tU2VsZWN0b3IpXG4gICAgICB0aHJvdyBuZXcgUXVlcnlFcnJvcihgQ291bGQgbm90IGZpbmQgc2VsZWN0b3IgbW9kZWw6ICR7c2VsZWN0b3J9YCk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBAZmluYWwoKVxuICBwdWJsaWMgd2hlcmUoY29uZGl0aW9uOiBDb25kaXRpb248TT4pOiBPcmRlckFuZEdyb3VwT3B0aW9uPE0sIFI+IHtcbiAgICB0aGlzLndoZXJlQ29uZGl0aW9uID0gY29uZGl0aW9uO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgQGZpbmFsKClcbiAgcHVibGljIG9yZGVyQnkoXG4gICAgc2VsZWN0b3I6IE9yZGVyQnlTZWxlY3RvcjxNPlxuICApOiBMaW1pdE9wdGlvbjxNLCBSPiAmIE9mZnNldE9wdGlvbjxSPiB7XG4gICAgdGhpcy5vcmRlckJ5U2VsZWN0b3IgPSBzZWxlY3RvcjtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIEBmaW5hbCgpXG4gIHB1YmxpYyBncm91cEJ5KHNlbGVjdG9yOiBHcm91cEJ5U2VsZWN0b3I8TT4pOiBMaW1pdE9wdGlvbjxNLCBSPiB7XG4gICAgdGhpcy5ncm91cEJ5U2VsZWN0b3IgPSBzZWxlY3RvcjtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIEBmaW5hbCgpXG4gIHB1YmxpYyBsaW1pdCh2YWx1ZTogbnVtYmVyKTogT2Zmc2V0T3B0aW9uPFI+IHtcbiAgICB0aGlzLmxpbWl0U2VsZWN0b3IgPSB2YWx1ZTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIEBmaW5hbCgpXG4gIHB1YmxpYyBvZmZzZXQodmFsdWU6IG51bWJlcik6IEV4ZWN1dG9yPFI+IHtcbiAgICB0aGlzLm9mZnNldFNlbGVjdG9yID0gdmFsdWU7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBAZmluYWwoKVxuICBhc3luYyBleGVjdXRlKCk6IFByb21pc2U8Uj4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBxdWVyeTogUSA9IHRoaXMuYnVpbGQoKTtcbiAgICAgIHJldHVybiAoYXdhaXQgdGhpcy5yYXcocXVlcnkpKSBhcyBSO1xuICAgIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKGUgYXMgRXJyb3IpO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIHJhdzxSPihyYXdJbnB1dDogUSk6IFByb21pc2U8Uj4ge1xuICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCB0aGlzLmFkYXB0ZXIucmF3PFI+KHJhd0lucHV0KTtcbiAgICBpZiAoIXRoaXMuc2VsZWN0U2VsZWN0b3IpIHJldHVybiByZXN1bHRzO1xuICAgIGNvbnN0IHBrQXR0ciA9IGZpbmRQcmltYXJ5S2V5KFxuICAgICAgbmV3ICh0aGlzLmZyb21TZWxlY3RvciBhcyBDb25zdHJ1Y3RvcjxNPikoKVxuICAgICkuaWQ7XG5cbiAgICBjb25zdCBwcm9jZXNzb3IgPSBmdW5jdGlvbiByZWNvcmRQcm9jZXNzb3IoXG4gICAgICB0aGlzOiBTdGF0ZW1lbnQ8USwgTSwgUj4sXG4gICAgICByOiBhbnlcbiAgICApIHtcbiAgICAgIGNvbnN0IGlkID0gcltwa0F0dHJdO1xuICAgICAgcmV0dXJuIHRoaXMuYWRhcHRlci5yZXZlcnQoXG4gICAgICAgIHIsXG4gICAgICAgIHRoaXMuZnJvbVNlbGVjdG9yIGFzIENvbnN0cnVjdG9yPGFueT4sXG4gICAgICAgIHBrQXR0cixcbiAgICAgICAgaWRcbiAgICAgICkgYXMgYW55O1xuICAgIH0uYmluZCh0aGlzIGFzIGFueSk7XG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheShyZXN1bHRzKSkgcmV0dXJuIHJlc3VsdHMubWFwKHByb2Nlc3NvcikgYXMgUjtcbiAgICByZXR1cm4gcHJvY2Vzc29yKHJlc3VsdHMpIGFzIFI7XG4gIH1cblxuICBwcm90ZWN0ZWQgYWJzdHJhY3QgYnVpbGQoKTogUTtcbiAgcHJvdGVjdGVkIGFic3RyYWN0IHBhcnNlQ29uZGl0aW9uKGNvbmRpdGlvbjogQ29uZGl0aW9uPE0+KTogUTtcbiAgYWJzdHJhY3QgcGFnaW5hdGUoc2l6ZTogbnVtYmVyKTogUHJvbWlzZTxQYWdpbmF0b3I8TSwgUiwgUT4+O1xufVxuIiwiLyoqXG4gKiBAbW9kdWxlIGNvcmVcbiAqIEBkZXNjcmlwdGlvbiBDb3JlIG1vZHVsZSBmb3IgdGhlIERlY2FmIFR5cGVTY3JpcHQgZnJhbWV3b3JrXG4gKiBAc3VtbWFyeSBUaGlzIG1vZHVsZSBwcm92aWRlcyB0aGUgZm91bmRhdGlvbmFsIGNvbXBvbmVudHMgb2YgdGhlIERlY2FmIGZyYW1ld29yaywgaW5jbHVkaW5nIGlkZW50aXR5IG1hbmFnZW1lbnQsIFxuICogbW9kZWwgZGVmaW5pdGlvbnMsIHJlcG9zaXRvcnkgcGF0dGVybnMsIHBlcnNpc3RlbmNlIGxheWVyLCBxdWVyeSBidWlsZGluZywgYW5kIHV0aWxpdHkgZnVuY3Rpb25zLlxuICogSXQgZXhwb3J0cyBmdW5jdGlvbmFsaXR5IGZyb20gdmFyaW91cyBzdWJtb2R1bGVzIGFuZCBzZXRzIHVwIHRoZSBpbmplY3RhYmxlIHJlZ2lzdHJ5IGZvciByZXBvc2l0b3J5IGRlY29yYXRvcnMuXG4gKi9cblxuaW1wb3J0IHsgSW5qZWN0YWJsZXNSZWdpc3RyeSB9IGZyb20gXCIuL3JlcG9zaXRvcnlcIjtcbmltcG9ydCB7IEluamVjdGFibGVzIH0gZnJvbSBcIkBkZWNhZi10cy9pbmplY3RhYmxlLWRlY29yYXRvcnNcIjtcblxuLy8gb3ZlcnJpZGVzIHRoZSBwcmV2aW91cyBJbmplY3RhYmxlcyByZWdpc3RyeSB0byBlbmFibGUgdGhlIEByZXBvc2l0b3J5IGRlY29yYXRvclxuSW5qZWN0YWJsZXMuc2V0UmVnaXN0cnkobmV3IEluamVjdGFibGVzUmVnaXN0cnkoKSk7XG5cbmV4cG9ydCAqIGZyb20gXCIuL2lkZW50aXR5XCI7XG5leHBvcnQgKiBmcm9tIFwiLi9pbnRlcmZhY2VzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9tb2RlbFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vcXVlcnlcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3JlcG9zaXRvcnlcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3V0aWxzXCI7XG4vL2xlZnQgdG8gbGFzdCBvbiBwdXJwb3NlXG5leHBvcnQgKiBmcm9tIFwiLi9wZXJzaXN0ZW5jZVwiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBTdG9yZXMgdGhlIGN1cnJlbnQgcGFja2FnZSB2ZXJzaW9uXG4gKiBAc3VtbWFyeSBBIGNvbnN0YW50IHJlcHJlc2VudGluZyB0aGUgdmVyc2lvbiBvZiB0aGUgY29yZSBwYWNrYWdlXG4gKiBAY29uc3QgVkVSU0lPTlxuICogQG1lbWJlck9mIG1vZHVsZTpjb3JlXG4gKi9cbmV4cG9ydCBjb25zdCBWRVJTSU9OID0gXCIjI1ZFUlNJT04jI1wiO1xuIl0sIm5hbWVzIjpbIlJlcCIsInBvcHVsYXRlIiwicG9wIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBRUE7Ozs7OztBQU1HO0lBQ1M7QUFBWixDQUFBLFVBQVksY0FBYyxFQUFBOztBQUV4QixJQUFBLGNBQUEsQ0FBQSxLQUFBLENBQUEsR0FBQSxLQUFXOztBQUdYLElBQUEsY0FBQSxDQUFBLEtBQUEsQ0FBQSxHQUFBLE1BQVk7QUFDZCxDQUFDLEVBTlcsY0FBYyxLQUFkLGNBQWMsR0FNekIsRUFBQSxDQUFBLENBQUE7QUFFRDs7Ozs7O0FBTUc7SUFDUztBQUFaLENBQUEsVUFBWSxPQUFPLEVBQUE7O0FBRWpCLElBQUEsT0FBQSxDQUFBLFNBQUEsQ0FBQSxHQUFBLFNBQW1COztBQUVuQixJQUFBLE9BQUEsQ0FBQSxNQUFBLENBQUEsR0FBQSxNQUFhO0FBQ2YsQ0FBQyxFQUxXLE9BQU8sS0FBUCxPQUFPLEdBS2xCLEVBQUEsQ0FBQSxDQUFBO0FBRUQ7Ozs7OztBQU1HO0FBQ1UsTUFBQSxjQUFjLEdBQW9CO0lBQzdDLE1BQU0sRUFBRSxPQUFPLENBQUMsT0FBTztJQUN2QixNQUFNLEVBQUUsT0FBTyxDQUFDLElBQUk7OztBQ3hDdEI7Ozs7OztBQU1HO0lBQ1M7QUFBWixDQUFBLFVBQVksZUFBZSxFQUFBOztBQUV6QixJQUFBLGVBQUEsQ0FBQSxPQUFBLENBQUEsR0FBQSxPQUFlOztBQUdmLElBQUEsZUFBQSxDQUFBLFFBQUEsQ0FBQSxHQUFBLFFBQWlCOztBQUdqQixJQUFBLGVBQUEsQ0FBQSxTQUFBLENBQUEsR0FBQSxTQUFtQjs7QUFHbkIsSUFBQSxlQUFBLENBQUEsWUFBQSxDQUFBLEdBQUEsMkJBQXdDOztBQUd4QyxJQUFBLGVBQUEsQ0FBQSxPQUFBLENBQUEsR0FBQSxPQUFlOztBQUdmLElB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