@decaf-ts/for-typeorm 0.0.6

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 (109) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +93 -0
  3. package/dist/for-typeorm.cjs +2553 -0
  4. package/dist/for-typeorm.esm.cjs +2538 -0
  5. package/lib/TypeORMAdapter.cjs +1129 -0
  6. package/lib/TypeORMAdapter.d.ts +221 -0
  7. package/lib/TypeORMDispatch.cjs +134 -0
  8. package/lib/TypeORMDispatch.d.ts +87 -0
  9. package/lib/TypeORMEventSubscriber.cjs +96 -0
  10. package/lib/TypeORMEventSubscriber.d.ts +56 -0
  11. package/lib/TypeORMRepository.cjs +209 -0
  12. package/lib/TypeORMRepository.d.ts +125 -0
  13. package/lib/constants.cjs +43 -0
  14. package/lib/constants.d.ts +39 -0
  15. package/lib/errors.cjs +28 -0
  16. package/lib/errors.d.ts +21 -0
  17. package/lib/esm/TypeORMAdapter.d.ts +221 -0
  18. package/lib/esm/TypeORMAdapter.js +1124 -0
  19. package/lib/esm/TypeORMDispatch.d.ts +87 -0
  20. package/lib/esm/TypeORMDispatch.js +130 -0
  21. package/lib/esm/TypeORMEventSubscriber.d.ts +56 -0
  22. package/lib/esm/TypeORMEventSubscriber.js +93 -0
  23. package/lib/esm/TypeORMRepository.d.ts +125 -0
  24. package/lib/esm/TypeORMRepository.js +206 -0
  25. package/lib/esm/constants.d.ts +39 -0
  26. package/lib/esm/constants.js +40 -0
  27. package/lib/esm/errors.d.ts +21 -0
  28. package/lib/esm/errors.js +24 -0
  29. package/lib/esm/index.d.ts +22 -0
  30. package/lib/esm/index.js +25 -0
  31. package/lib/esm/indexes/generator.d.ts +50 -0
  32. package/lib/esm/indexes/generator.js +95 -0
  33. package/lib/esm/indexes/index.d.ts +1 -0
  34. package/lib/esm/indexes/index.js +2 -0
  35. package/lib/esm/overrides/Column.d.ts +74 -0
  36. package/lib/esm/overrides/Column.js +70 -0
  37. package/lib/esm/overrides/CreateDateColumn.d.ts +2 -0
  38. package/lib/esm/overrides/CreateDateColumn.js +9 -0
  39. package/lib/esm/overrides/Entity.d.ts +11 -0
  40. package/lib/esm/overrides/Entity.js +28 -0
  41. package/lib/esm/overrides/PrimaryColumn.d.ts +20 -0
  42. package/lib/esm/overrides/PrimaryColumn.js +53 -0
  43. package/lib/esm/overrides/PrimaryGeneratedColumn.d.ts +24 -0
  44. package/lib/esm/overrides/PrimaryGeneratedColumn.js +51 -0
  45. package/lib/esm/overrides/UpdateDateColumn.d.ts +2 -0
  46. package/lib/esm/overrides/UpdateDateColumn.js +9 -0
  47. package/lib/esm/overrides/utils.d.ts +2 -0
  48. package/lib/esm/overrides/utils.js +29 -0
  49. package/lib/esm/query/Paginator.d.ts +86 -0
  50. package/lib/esm/query/Paginator.js +124 -0
  51. package/lib/esm/query/Statement.d.ts +131 -0
  52. package/lib/esm/query/Statement.js +242 -0
  53. package/lib/esm/query/constants.d.ts +52 -0
  54. package/lib/esm/query/constants.js +74 -0
  55. package/lib/esm/query/index.d.ts +4 -0
  56. package/lib/esm/query/index.js +5 -0
  57. package/lib/esm/query/translate.d.ts +34 -0
  58. package/lib/esm/query/translate.js +42 -0
  59. package/lib/esm/raw/postgres.d.ts +36 -0
  60. package/lib/esm/raw/postgres.js +2 -0
  61. package/lib/esm/sequences/Sequence.d.ts +67 -0
  62. package/lib/esm/sequences/Sequence.js +117 -0
  63. package/lib/esm/sequences/index.d.ts +1 -0
  64. package/lib/esm/sequences/index.js +2 -0
  65. package/lib/esm/types.d.ts +67 -0
  66. package/lib/esm/types.js +28 -0
  67. package/lib/esm/utils.d.ts +16 -0
  68. package/lib/esm/utils.js +29 -0
  69. package/lib/index.cjs +42 -0
  70. package/lib/index.d.ts +22 -0
  71. package/lib/indexes/generator.cjs +98 -0
  72. package/lib/indexes/generator.d.ts +50 -0
  73. package/lib/indexes/index.cjs +18 -0
  74. package/lib/indexes/index.d.ts +1 -0
  75. package/lib/overrides/Column.cjs +73 -0
  76. package/lib/overrides/Column.d.ts +74 -0
  77. package/lib/overrides/CreateDateColumn.cjs +12 -0
  78. package/lib/overrides/CreateDateColumn.d.ts +2 -0
  79. package/lib/overrides/Entity.cjs +31 -0
  80. package/lib/overrides/Entity.d.ts +11 -0
  81. package/lib/overrides/PrimaryColumn.cjs +56 -0
  82. package/lib/overrides/PrimaryColumn.d.ts +20 -0
  83. package/lib/overrides/PrimaryGeneratedColumn.cjs +54 -0
  84. package/lib/overrides/PrimaryGeneratedColumn.d.ts +24 -0
  85. package/lib/overrides/UpdateDateColumn.cjs +12 -0
  86. package/lib/overrides/UpdateDateColumn.d.ts +2 -0
  87. package/lib/overrides/utils.cjs +32 -0
  88. package/lib/overrides/utils.d.ts +2 -0
  89. package/lib/query/Paginator.cjs +128 -0
  90. package/lib/query/Paginator.d.ts +86 -0
  91. package/lib/query/Statement.cjs +246 -0
  92. package/lib/query/Statement.d.ts +131 -0
  93. package/lib/query/constants.cjs +77 -0
  94. package/lib/query/constants.d.ts +52 -0
  95. package/lib/query/index.cjs +21 -0
  96. package/lib/query/index.d.ts +4 -0
  97. package/lib/query/translate.cjs +45 -0
  98. package/lib/query/translate.d.ts +34 -0
  99. package/lib/raw/postgres.cjs +3 -0
  100. package/lib/raw/postgres.d.ts +36 -0
  101. package/lib/sequences/Sequence.cjs +121 -0
  102. package/lib/sequences/Sequence.d.ts +67 -0
  103. package/lib/sequences/index.cjs +18 -0
  104. package/lib/sequences/index.d.ts +1 -0
  105. package/lib/types.cjs +31 -0
  106. package/lib/types.d.ts +67 -0
  107. package/lib/utils.cjs +32 -0
  108. package/lib/utils.d.ts +16 -0
  109. package/package.json +128 -0
@@ -0,0 +1,1129 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.TypeORMAdapter = void 0;
13
+ exports.createdByOnPostgresCreateUpdate = createdByOnPostgresCreateUpdate;
14
+ const core_1 = require("@decaf-ts/core");
15
+ const constants_1 = require("./constants.cjs");
16
+ const db_decorators_1 = require("@decaf-ts/db-decorators");
17
+ require("reflect-metadata");
18
+ const decorator_validation_1 = require("@decaf-ts/decorator-validation");
19
+ const errors_1 = require("./errors.cjs");
20
+ const query_1 = require("./query/index.cjs");
21
+ const sequences_1 = require("./sequences/index.cjs");
22
+ const indexes_1 = require("./indexes/index.cjs");
23
+ const reflection_1 = require("@decaf-ts/reflection");
24
+ const TypeORMRepository_1 = require("./TypeORMRepository.cjs");
25
+ const logging_1 = require("@decaf-ts/logging");
26
+ const TypeORMDispatch_1 = require("./TypeORMDispatch.cjs");
27
+ const utils_1 = require("./utils.cjs");
28
+ const typeorm_1 = require("typeorm");
29
+ const Column_1 = require("./overrides/Column.cjs");
30
+ const UpdateDateColumn_1 = require("./overrides/UpdateDateColumn.cjs");
31
+ const CreateDateColumn_1 = require("./overrides/CreateDateColumn.cjs");
32
+ const PrimaryGeneratedColumn_1 = require("./overrides/PrimaryGeneratedColumn.cjs");
33
+ const PrimaryColumn_1 = require("./overrides/PrimaryColumn.cjs");
34
+ const Entity_1 = require("./overrides/Entity.cjs");
35
+ async function createdByOnPostgresCreateUpdate(context, data, key, model) {
36
+ try {
37
+ const user = context.get("user");
38
+ model[key] = user;
39
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
40
+ }
41
+ catch (e) {
42
+ throw new db_decorators_1.InternalError("No User found in context. Please provide a user in the context");
43
+ }
44
+ }
45
+ /**
46
+ * @description Adapter for TypeORM-backed persistence operations.
47
+ * @summary Implements the Decaf.ts Adapter over a TypeORM DataSource, providing CRUD operations, query/statement factories, sequence management, error parsing, and decoration helpers.
48
+ * @template Y The native configuration type (TypeORM DataSourceOptions).
49
+ * @template F The repository flags type.
50
+ * @template C The context type.
51
+ * @param {DataSourceOptions} scope The DataSource options for the adapter.
52
+ * @param {string} flavour The flavour of the adapter.
53
+ * @param {string} [alias] Optional alias for the adapter.
54
+ * @class TypeORMAdapter
55
+ * @example
56
+ * const adapter = new TypeORMAdapter({ type: 'postgres', /* ... *\/ });
57
+ * await adapter.initialize();
58
+ * const repo = new (adapter.repository<User>())(adapter, User);
59
+ * const created = await repo.create(new User({ name: 'Alice' }));
60
+ *
61
+ * @mermaid
62
+ * sequenceDiagram
63
+ * participant App
64
+ * participant Adapter as TypeORMAdapter
65
+ * participant Repo as TypeORMRepository
66
+ * participant DS as TypeORM DataSource
67
+ *
68
+ * App->>Adapter: new TypeORMAdapter(opts)
69
+ * Adapter->>DS: initialize()
70
+ * App->>Adapter: repository()
71
+ * Adapter-->>App: TypeORMRepository
72
+ * App->>Repo: create(model)
73
+ * Repo->>Adapter: prepare/create/revert
74
+ * Adapter-->>Repo: Model
75
+ * Repo-->>App: Model
76
+ */
77
+ class TypeORMAdapter extends core_1.Adapter {
78
+ get dataSource() {
79
+ if (!this._dataSource) {
80
+ const models = core_1.Adapter.models(this.flavour);
81
+ this._dataSource = new typeorm_1.DataSource(Object.assign(this.native, {
82
+ entities: models.map((c) => c[decorator_validation_1.ModelKeys.ANCHOR]),
83
+ }));
84
+ }
85
+ return this._dataSource;
86
+ }
87
+ // protected dataSou
88
+ constructor(options, alias) {
89
+ super(options, constants_1.TypeORMFlavour, alias);
90
+ }
91
+ async flags(operation, model, flags) {
92
+ const f = await super.flags(operation, model, flags);
93
+ const newObj = {
94
+ user: (await TypeORMAdapter.getCurrentUser(this.dataSource)),
95
+ };
96
+ const m = new model();
97
+ const exceptions = [];
98
+ if (operation === db_decorators_1.OperationKeys.CREATE) {
99
+ const pk = (0, db_decorators_1.findPrimaryKey)(m).id;
100
+ exceptions.push(pk);
101
+ }
102
+ if (operation === db_decorators_1.OperationKeys.CREATE ||
103
+ operation === db_decorators_1.OperationKeys.UPDATE) {
104
+ const decs = Object.keys(m).reduce((accum, key) => {
105
+ const decs = reflection_1.Reflection.getPropertyDecorators(decorator_validation_1.ValidationKeys.REFLECT, m, key, true);
106
+ const dec = decs.decorators.find((dec) => dec.key === db_decorators_1.DBKeys.TIMESTAMP &&
107
+ dec.props.operation.indexOf(operation) !== -1);
108
+ if (dec) {
109
+ accum[key] = dec.props;
110
+ }
111
+ return accum;
112
+ }, {});
113
+ exceptions.push(...Object.keys(decs));
114
+ }
115
+ newObj.ignoredValidationProperties = (f.ignoredValidationProperties ? f.ignoredValidationProperties : []).concat(...exceptions);
116
+ return Object.assign(f, newObj);
117
+ }
118
+ Dispatch() {
119
+ return new TypeORMDispatch_1.TypeORMDispatch();
120
+ }
121
+ repository() {
122
+ return TypeORMRepository_1.TypeORMRepository;
123
+ }
124
+ /**
125
+ * @description Creates a new Postgres statement for querying
126
+ * @summary Factory method that creates a new PostgresStatement instance for building queries
127
+ * @template M - The model type
128
+ * @return {TypeORMStatement<M, any>} A new PostgresStatement instance
129
+ */
130
+ Statement() {
131
+ return new query_1.TypeORMStatement(this);
132
+ }
133
+ /**
134
+ * @description Creates a new PostgreSQL sequence
135
+ * @summary Factory method that creates a new PostgreSQLSequence instance for managing sequences
136
+ * @param {SequenceOptions} options - The options for the sequence
137
+ * @return {Promise<Sequence>} A promise that resolves to a new Sequence instance
138
+ */
139
+ async Sequence(options) {
140
+ return new sequences_1.TypeORMSequence(options, this);
141
+ }
142
+ /**
143
+ * @description Initializes the adapter by creating indexes for all managed models
144
+ * @summary Sets up the necessary database indexes for all models managed by this adapter
145
+ * @return {Promise<void>} A promise that resolves when initialization is complete
146
+ */
147
+ async initialize() {
148
+ const ds = this.dataSource;
149
+ try {
150
+ await ds.initialize();
151
+ }
152
+ catch (e) {
153
+ throw this.parseError(e);
154
+ }
155
+ const log = this.log.for(this.initialize);
156
+ log.verbose(`${this.flavour} adapter initialized`);
157
+ }
158
+ /**
159
+ * @description Creates indexes for the given models
160
+ * @summary Abstract method that must be implemented to create database indexes for the specified models
161
+ * @template M - The model type
162
+ * @param {...Constructor<M>} models - The model constructors to create indexes for
163
+ * @return {Promise<void>} A promise that resolves when all indexes are created
164
+ */
165
+ async index(...models) {
166
+ const indexes = (0, indexes_1.generateIndexes)(models);
167
+ try {
168
+ await this.dataSource.query("BEGIN");
169
+ for (const index of indexes) {
170
+ await this.dataSource.query(index.query, index.values);
171
+ }
172
+ await this.dataSource.query("COMMIT");
173
+ }
174
+ catch (e) {
175
+ await this.dataSource.query("ROLLBACK");
176
+ throw this.parseError(e);
177
+ }
178
+ }
179
+ /**
180
+ * @description Executes a raw SQL query against the database
181
+ * @summary Abstract method that must be implemented to execute raw SQL queries
182
+ * @template R - The result type
183
+ * @param {TypeORMQuery} q - The query to execute
184
+ * @return {Promise<R>} A promise that resolves to the query result
185
+ */
186
+ async raw(q) {
187
+ const log = this.log.for(this.raw);
188
+ try {
189
+ if (!this.dataSource.isInitialized)
190
+ await this.dataSource.initialize();
191
+ }
192
+ catch (e) {
193
+ throw this.parseError(e);
194
+ }
195
+ try {
196
+ const { query, values } = q;
197
+ log.debug(`executing query: ${query.getSql()}`);
198
+ const response = await this.dataSource.query(query, values);
199
+ return response;
200
+ }
201
+ catch (e) {
202
+ throw this.parseError(e);
203
+ }
204
+ }
205
+ prepare(model, pk, child = false) {
206
+ const prepared = super.prepare(model, pk);
207
+ prepared.record = Object.entries(prepared.record).reduce((accum, [key, value]) => {
208
+ if (key === core_1.PersistenceKeys.METADATA || this.isReserved(key))
209
+ return accum;
210
+ if (value === undefined) {
211
+ return accum;
212
+ }
213
+ if (value instanceof Date) {
214
+ value = new Date(value.getTime());
215
+ }
216
+ else if (decorator_validation_1.Model.isModel(value)) {
217
+ value = this.prepare(value, (0, db_decorators_1.findPrimaryKey)(value).id, true).record;
218
+ }
219
+ else {
220
+ switch (typeof value) {
221
+ case "string":
222
+ value = `${value}`;
223
+ break;
224
+ default:
225
+ //do nothing;
226
+ }
227
+ }
228
+ accum[key] = value;
229
+ return accum;
230
+ }, {});
231
+ const constr = decorator_validation_1.Model.get(model.constructor.name);
232
+ if (!constr)
233
+ throw new db_decorators_1.InternalError(`Model ${model.constructor.name} not found in registry`);
234
+ const result = child
235
+ ? new constr[decorator_validation_1.ModelKeys.ANCHOR]()
236
+ : new constr();
237
+ if (child)
238
+ Object.defineProperty(result, "constructor", {
239
+ configurable: false,
240
+ enumerable: false,
241
+ value: constr[decorator_validation_1.ModelKeys.ANCHOR],
242
+ writable: false,
243
+ });
244
+ Object.entries(prepared.record).forEach(([key, val]) => (result[key] = val));
245
+ prepared.record = result;
246
+ return prepared;
247
+ }
248
+ revert(obj, clazz, pk, id, transient) {
249
+ const log = this.log.for(this.revert);
250
+ if (transient) {
251
+ log.verbose(`re-adding transient properties: ${Object.keys(transient).join(", ")}`);
252
+ Object.entries(transient).forEach(([key, val]) => {
253
+ if (key in obj)
254
+ throw new db_decorators_1.InternalError(`Transient property ${key} already exists on model ${typeof clazz === "string" ? clazz : clazz.name}. should be impossible`);
255
+ obj[key] = val;
256
+ });
257
+ }
258
+ return new clazz(obj);
259
+ }
260
+ /**
261
+ * @description Creates a new record in the database
262
+ * @summary Abstract method that must be implemented to create a new record
263
+ * @param {string} tableName - The name of the table
264
+ * @param {string|number} id - The ID of the record
265
+ * @param {Record<string, any>} model - The model to create
266
+ * @param {...any[]} args - Additional arguments
267
+ * @return {Promise<Record<string, any>>} A promise that resolves to the created record
268
+ */
269
+ async create(tableName, id, model,
270
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
271
+ ...args) {
272
+ const m = tableName;
273
+ try {
274
+ const repo = this.dataSource.getRepository(m);
275
+ return await repo.save(model);
276
+ }
277
+ catch (e) {
278
+ throw this.parseError(e);
279
+ }
280
+ }
281
+ /**
282
+ * @description Reads a record from the database
283
+ * @summary Abstract method that must be implemented to read a record
284
+ * @param {string} tableName - The name of the table
285
+ * @param {string|number} id - The ID of the record
286
+ * @param {string} pk - primary key colum
287
+ * @return {Promise<Record<string, any>>} A promise that resolves to the read record
288
+ */
289
+ async read(tableName, id, pk) {
290
+ const m = tableName;
291
+ let result;
292
+ try {
293
+ const repo = this.dataSource.getRepository(m);
294
+ const q = {
295
+ where: {
296
+ [pk]: id,
297
+ },
298
+ };
299
+ result = (await repo.findOne(q));
300
+ }
301
+ catch (e) {
302
+ throw this.parseError(e);
303
+ }
304
+ if (!result)
305
+ throw new db_decorators_1.NotFoundError(`Record with id: ${id} not found in table ${typeof tableName === "string" ? tableName : core_1.Repository.table(tableName)}`);
306
+ return result;
307
+ }
308
+ /**
309
+ * @description Updates a record in the database
310
+ * @summary Abstract method that must be implemented to update a record
311
+ * @param {string} tableName - The name of the table
312
+ * @param {string|number} id - The ID of the record
313
+ * @param {Record<string, any>} model - The model to update
314
+ * @param {string} pk - Additional arguments
315
+ * @return A promise that resolves to the updated record
316
+ */
317
+ async update(tableName, id, model,
318
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
319
+ ...args) {
320
+ const m = tableName;
321
+ try {
322
+ const repo = this.dataSource.getRepository(m);
323
+ return repo.save(model);
324
+ }
325
+ catch (e) {
326
+ throw this.parseError(e);
327
+ }
328
+ }
329
+ /**
330
+ * @description Deletes a record from the database
331
+ * @summary Abstract method that must be implemented to delete a record
332
+ * @param {string} tableName - The name of the table
333
+ * @param {string|number} id - The ID of the record
334
+ * @param {string} pk - Additional arguments
335
+ * @return A promise that resolves to the deleted record
336
+ */
337
+ async delete(tableName, id, pk,
338
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
339
+ ...args) {
340
+ const m = tableName;
341
+ try {
342
+ const repo = this.dataSource.getRepository(m);
343
+ const model = await this.read(tableName, id, pk);
344
+ const res = await repo.delete(id);
345
+ return model;
346
+ }
347
+ catch (e) {
348
+ throw this.parseError(e);
349
+ }
350
+ }
351
+ async createAll(tableName, id, model,
352
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
353
+ ...args) {
354
+ const m = tableName;
355
+ try {
356
+ const repo = this.dataSource.getRepository(m);
357
+ const result = await repo.insert(model);
358
+ return this.readAll(tableName, result.identifiers.map((id) => id.id), "id");
359
+ }
360
+ catch (e) {
361
+ throw this.parseError(e);
362
+ }
363
+ }
364
+ async readAll(tableName, id, pk,
365
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
366
+ ...args) {
367
+ if (!id.length)
368
+ return [];
369
+ const m = tableName;
370
+ try {
371
+ const repo = this.dataSource.getRepository(m);
372
+ return repo.findBy({ [pk]: (0, typeorm_1.In)(id) });
373
+ }
374
+ catch (e) {
375
+ throw this.parseError(e);
376
+ }
377
+ }
378
+ async updateAll(tableName, ids, model, pk, ...args) {
379
+ const result = [];
380
+ for (const m of model) {
381
+ result.push(await this.update(tableName, m[pk], m, ...args));
382
+ }
383
+ return result;
384
+ }
385
+ async deleteAll(tableName, ids, pk,
386
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
387
+ ...args) {
388
+ if (!ids.length)
389
+ return [];
390
+ const m = tableName;
391
+ try {
392
+ const repo = this.dataSource.getRepository(m);
393
+ const models = await this.readAll(tableName, ids, pk);
394
+ await repo.delete(ids);
395
+ return models;
396
+ }
397
+ catch (e) {
398
+ throw this.parseError(e);
399
+ }
400
+ }
401
+ /**
402
+ * @description Parses an error and converts it to a BaseError
403
+ * @summary Converts various error types to appropriate BaseError subtypes
404
+ * @param {Error|string} err - The error to parse
405
+ * @param {string} [reason] - Optional reason for the error
406
+ * @return {BaseError} The parsed error as a BaseError
407
+ */
408
+ parseError(err, reason) {
409
+ return TypeORMAdapter.parseError(err, reason);
410
+ }
411
+ /**
412
+ * @description Checks if an attribute is reserved
413
+ * @summary Determines if an attribute name is reserved in PostgreSQL
414
+ * @param {string} attr - The attribute name to check
415
+ * @return {boolean} True if the attribute is reserved, false otherwise
416
+ */
417
+ isReserved(attr) {
418
+ return !!attr.match(constants_1.reservedAttributes);
419
+ }
420
+ /**
421
+ * @description Static method to parse an error and convert it to a BaseError
422
+ * @summary Converts various error types to appropriate BaseError subtypes based on PostgreSQL error codes and messages
423
+ * @param {Error|string} err - The error to parse
424
+ * @param {string} [reason] - Optional reason for the error
425
+ * @return {BaseError} The parsed error as a BaseError
426
+ * @mermaid
427
+ * sequenceDiagram
428
+ * participant Caller
429
+ * participant parseError
430
+ * participant ErrorTypes
431
+ *
432
+ * Caller->>parseError: err, reason
433
+ * Note over parseError: Check if err is already a BaseError
434
+ * alt err is BaseError
435
+ * parseError-->>Caller: return err
436
+ * else err is string
437
+ * Note over parseError: Extract code from string
438
+ * alt code matches "duplicate key|already exists"
439
+ * parseError->>ErrorTypes: new ConflictError(code)
440
+ * ErrorTypes-->>Caller: ConflictError
441
+ * else code matches "does not exist|not found"
442
+ * parseError->>ErrorTypes: new NotFoundError(code)
443
+ * ErrorTypes-->>Caller: NotFoundError
444
+ * end
445
+ * else err has code property
446
+ * Note over parseError: Extract code and reason
447
+ * else
448
+ * Note over parseError: Use err.message as code
449
+ * end
450
+ *
451
+ * Note over parseError: Switch on PostgreSQL error code
452
+ * alt code is 23505 (unique_violation)
453
+ * parseError->>ErrorTypes: new ConflictError(reason)
454
+ * ErrorTypes-->>Caller: ConflictError
455
+ * else code is 23503 (foreign_key_violation)
456
+ * parseError->>ErrorTypes: new ConflictError(reason)
457
+ * ErrorTypes-->>Caller: ConflictError
458
+ * else code is 42P01 (undefined_table)
459
+ * parseError->>ErrorTypes: new NotFoundError(reason)
460
+ * ErrorTypes-->>Caller: NotFoundError
461
+ * else code is 42703 (undefined_column)
462
+ * parseError->>ErrorTypes: new NotFoundError(reason)
463
+ * ErrorTypes-->>Caller: NotFoundError
464
+ * else code is 42P07 (duplicate_table)
465
+ * parseError->>ErrorTypes: new ConflictError(reason)
466
+ * ErrorTypes-->>Caller: ConflictError
467
+ * else code is 42P16 (invalid_table_definition)
468
+ * parseError->>ErrorTypes: new IndexError(err)
469
+ * ErrorTypes-->>Caller: IndexError
470
+ * else code matches "ECONNREFUSED"
471
+ * parseError->>ErrorTypes: new ConnectionError(err)
472
+ * ErrorTypes-->>Caller: ConnectionError
473
+ * else
474
+ * parseError->>ErrorTypes: new InternalError(err)
475
+ * ErrorTypes-->>Caller: InternalError
476
+ * end
477
+ */
478
+ static parseError(err, reason) {
479
+ if (err instanceof db_decorators_1.BaseError)
480
+ return err;
481
+ const code = typeof err === "string" ? err : err.message;
482
+ if (code.match(/duplicate key|already exists/g))
483
+ return new db_decorators_1.ConflictError(code);
484
+ if (code.match(/does not exist|not found/g))
485
+ return new db_decorators_1.NotFoundError(code);
486
+ // PostgreSQL error codes: https://www.postgresql.org/docs/current/errcodes-appendix.html
487
+ switch (code.toString()) {
488
+ // Integrity constraint violations
489
+ case "23505": // unique_violation
490
+ case "23503": // foreign_key_violation
491
+ case "42P07": // duplicate_table
492
+ return new db_decorators_1.ConflictError(reason);
493
+ // Object not found errors
494
+ case "42P01": // undefined_table
495
+ case "42703": // undefined_column
496
+ return new db_decorators_1.NotFoundError(reason);
497
+ // Invalid object definition
498
+ case "42P16": // invalid_table_definition
499
+ return new errors_1.IndexError(err);
500
+ // Connection errors
501
+ default:
502
+ if (code.toString().match(/ECONNREFUSED/g))
503
+ return new core_1.ConnectionError(err);
504
+ return new db_decorators_1.InternalError(err);
505
+ }
506
+ }
507
+ static async connect(config) {
508
+ const con = new typeorm_1.DataSource(config);
509
+ if (!con.isInitialized)
510
+ await con.initialize();
511
+ return con;
512
+ }
513
+ static async createDatabase(dataSource, dbName) {
514
+ const log = logging_1.Logging.for(this.createDatabase);
515
+ log.verbose(`Creating database ${dbName}`);
516
+ try {
517
+ await dataSource.query(`CREATE DATABASE ${dbName}`);
518
+ log.info(`Created database ${dbName}`);
519
+ }
520
+ catch (e) {
521
+ throw this.parseError(e);
522
+ }
523
+ }
524
+ static async createNotifyFunction(dataSource, user) {
525
+ const log = logging_1.Logging.for(this.createNotifyFunction);
526
+ log.verbose(`Creating notify function`);
527
+ try {
528
+ await dataSource.query(`CREATE OR REPLACE FUNCTION notify_table_changes()
529
+ RETURNS trigger AS $$
530
+ BEGIN
531
+ PERFORM pg_notify(
532
+ 'table_changes',
533
+ json_build_object(
534
+ 'table', TG_TABLE_NAME,
535
+ 'action', TG_OP,
536
+ 'data', row_to_json(NEW),
537
+ 'old_data', row_to_json(OLD)
538
+ )::text
539
+ );
540
+ RETURN NEW;
541
+ END;
542
+ $$ LANGUAGE plpgsql SECURITY DEFINER
543
+ ;`);
544
+ await dataSource.query(`ALTER FUNCTION notify_table_changes() OWNER TO ${user};`);
545
+ await dataSource.query(`
546
+ GRANT EXECUTE ON FUNCTION notify_table_changes() TO public;
547
+ `);
548
+ log.info(`Created notify function`);
549
+ }
550
+ catch (e) {
551
+ throw this.parseError(e);
552
+ }
553
+ }
554
+ static async deleteDatabase(dataSource, dbName, user) {
555
+ try {
556
+ if (user)
557
+ await dataSource.query(`DROP OWNED BY ${user} CASCADE;`);
558
+ await dataSource.query(`DROP DATABASE ${dbName}`);
559
+ }
560
+ catch (e) {
561
+ throw this.parseError(e);
562
+ }
563
+ }
564
+ static async createUser(dataSource, dbName, user, password) {
565
+ try {
566
+ await dataSource.query(`CREATE USER ${user} WITH PASSWORD '${password}'`);
567
+ await dataSource.query(`GRANT CONNECT ON DATABASE ${dbName} TO ${user}`);
568
+ await dataSource.query(`GRANT USAGE ON SCHEMA public TO ${user}`);
569
+ await dataSource.query(`GRANT CREATE ON SCHEMA public TO ${user}`);
570
+ await dataSource.query(`GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO ${user}`);
571
+ await dataSource.query(`GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO ${user}`);
572
+ await dataSource.query(`GRANT ALL PRIVILEGES ON ALL FUNCTIONS IN SCHEMA public TO ${user}`);
573
+ await dataSource.query(`ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL PRIVILEGES ON TABLES TO ${user}`);
574
+ await dataSource.query(`ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL PRIVILEGES ON SEQUENCES TO ${user}`);
575
+ }
576
+ catch (e) {
577
+ throw this.parseError(e);
578
+ }
579
+ }
580
+ static async deleteUser(client, user, admin) {
581
+ try {
582
+ await client.query(`REASSIGN OWNED BY ${user} TO ${admin}`);
583
+ await client.query(`REVOKE ALL ON ALL TABLES IN SCHEMA public FROM ${user}`);
584
+ await client.query(`REVOKE ALL ON SCHEMA public FROM ${user}`);
585
+ await client.query(`REVOKE ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public FROM ${user}`);
586
+ await client.query(`REVOKE ALL PRIVILEGES ON ALL FUNCTIONS IN SCHEMA public FROM ${user}`);
587
+ await client.query(`ALTER DEFAULT PRIVILEGES FOR ROLE ${admin} IN SCHEMA public REVOKE ALL ON TABLES FROM ${user}`);
588
+ await client.query(`ALTER DEFAULT PRIVILEGES FOR ROLE ${admin} IN SCHEMA public REVOKE ALL ON SEQUENCES FROM ${user};`);
589
+ await client.query(`ALTER DEFAULT PRIVILEGES FOR ROLE ${admin} IN SCHEMA public REVOKE ALL ON FUNCTIONS FROM ${user}`);
590
+ await client.query(`DROP OWNED BY ${user} CASCADE`);
591
+ await client.query(`DROP USER IF EXISTS "${user}"`);
592
+ }
593
+ catch (e) {
594
+ throw this.parseError(e);
595
+ }
596
+ }
597
+ static parseTypeToPostgres(type, isPk, isFk = false) {
598
+ switch (type.toLowerCase()) {
599
+ case "string":
600
+ return isPk ? "TEXT PRIMARY KEY" : isFk ? "TEXT" : "VARCHAR";
601
+ case "number":
602
+ return isPk ? "SERIAL PRIMARY KEY" : "INTEGER";
603
+ case "boolean":
604
+ return "BOOLEAN";
605
+ case "date":
606
+ return "TIMESTAMP";
607
+ case "bigint":
608
+ return isPk ? "BIGINT PRIMARY KEY" : "BIGINT";
609
+ default: {
610
+ const m = decorator_validation_1.Model.get(type);
611
+ if (m) {
612
+ const mm = new m();
613
+ const type = reflection_1.Reflection.getTypeFromDecorator(mm, (0, db_decorators_1.findPrimaryKey)(mm).id);
614
+ return {
615
+ model: m,
616
+ pkType: type,
617
+ };
618
+ }
619
+ throw new db_decorators_1.InternalError(`Unsupported type: ${type}`);
620
+ }
621
+ }
622
+ }
623
+ static parseValidationToPostgres(prop, type, isPk, key, options) {
624
+ switch (key) {
625
+ case decorator_validation_1.ValidationKeys.REQUIRED:
626
+ return "NOT NULL";
627
+ case decorator_validation_1.ValidationKeys.MAX_LENGTH:
628
+ if (isPk || !options || type.toLowerCase() !== "string") {
629
+ return "";
630
+ }
631
+ return `(${options[decorator_validation_1.ValidationKeys.MAX_LENGTH]})`;
632
+ case decorator_validation_1.ValidationKeys.MIN_LENGTH:
633
+ return `CONSTRAINT ${prop}_min_length_check CHECK (LENGTH(${prop}) >= ${options[decorator_validation_1.ValidationKeys.MIN_LENGTH]})`;
634
+ case decorator_validation_1.ValidationKeys.PATTERN:
635
+ case decorator_validation_1.ValidationKeys.URL:
636
+ case decorator_validation_1.ValidationKeys.EMAIL:
637
+ return `CONSTRAINT ${prop}_pattern_check CHECK (${prop} ~ '${(0, utils_1.convertJsRegexToPostgres)(options[decorator_validation_1.ValidationKeys.PATTERN])}')`;
638
+ case decorator_validation_1.ValidationKeys.TYPE:
639
+ case decorator_validation_1.ValidationKeys.DATE:
640
+ return "";
641
+ case decorator_validation_1.ValidationKeys.MIN:
642
+ return `CONSTRAINT ${prop}_${key}_check CHECK (${prop} >= ${options[decorator_validation_1.ValidationKeys.MIN]})`;
643
+ case decorator_validation_1.ValidationKeys.MAX:
644
+ return `CONSTRAINT ${prop}_${key}_check CHECK (${prop} <= ${options[decorator_validation_1.ValidationKeys.MAX]})`;
645
+ case decorator_validation_1.ValidationKeys.PASSWORD:
646
+ default:
647
+ throw new db_decorators_1.InternalError(`Unsupported type: ${key}`);
648
+ }
649
+ }
650
+ static parseRelationsToPostgres(prop, clazz, pk, key, options) {
651
+ const tableName = core_1.Repository.table(clazz);
652
+ const { cascade } = options;
653
+ const cascadeStr = `${cascade.update ? " ON UPDATE CASCADE" : ""}${cascade.delete ? " ON DELETE CASCADE" : ""}`;
654
+ switch (`relations${key}`) {
655
+ case core_1.PersistenceKeys.ONE_TO_ONE:
656
+ return `FOREIGN KEY (${prop}) REFERENCES ${tableName}(${pk})${cascadeStr}`;
657
+ default:
658
+ throw new db_decorators_1.InternalError(`Unsupported operation: ${key}`);
659
+ }
660
+ }
661
+ static async createTable(client, model) {
662
+ const result = {};
663
+ const m = new model({});
664
+ const tableName = core_1.Repository.table(model);
665
+ const { id } = (0, db_decorators_1.findPrimaryKey)(m);
666
+ let isPk, column;
667
+ const properties = Object.getOwnPropertyNames(m);
668
+ for (const prop of properties) {
669
+ if (typeof this[prop] === "function" ||
670
+ prop.toString().startsWith("_") ||
671
+ prop === "constructor") {
672
+ continue;
673
+ }
674
+ isPk = prop === id;
675
+ column = core_1.Repository.column(m, prop.toString());
676
+ const allDecs = reflection_1.Reflection.getPropertyDecorators(decorator_validation_1.ValidationKeys.REFLECT, m, prop.toString(), false, true);
677
+ const decoratorData = allDecs.decorators.reduce((accum, el) => {
678
+ const { key, props } = el;
679
+ if (key === decorator_validation_1.ModelKeys.TYPE && !accum[decorator_validation_1.ValidationKeys.TYPE]) {
680
+ accum[decorator_validation_1.ValidationKeys.TYPE] = {
681
+ customTypes: [props.name],
682
+ message: decorator_validation_1.DEFAULT_ERROR_MESSAGES.TYPE,
683
+ description: "defines the accepted types for the attribute",
684
+ };
685
+ }
686
+ else if (key !== decorator_validation_1.ValidationKeys.TYPE) {
687
+ // do nothing. we can only support basis ctypes at this time
688
+ accum[key] = props;
689
+ }
690
+ return accum;
691
+ }, {});
692
+ const dbDecs = reflection_1.Reflection.getPropertyDecorators(core_1.Repository.key("relations"), m, prop.toString(), true, true);
693
+ const query = [];
694
+ const constraints = [];
695
+ const foreignKeys = [];
696
+ let typeData = undefined;
697
+ let childClass = undefined;
698
+ let childPk;
699
+ if (Object.keys(decoratorData).length) {
700
+ typeData = decoratorData[decorator_validation_1.ValidationKeys.TYPE];
701
+ if (!typeData) {
702
+ throw new Error(`Missing type information`);
703
+ }
704
+ let parsedType = this.parseTypeToPostgres(typeof typeData.customTypes[0] === "function"
705
+ ? typeData.customTypes[0]()
706
+ : typeData.customTypes[0], isPk);
707
+ if (typeof parsedType === "string") {
708
+ parsedType = { model: parsedType };
709
+ }
710
+ let typeStr = parsedType.model;
711
+ if (typeof typeStr !== "string") {
712
+ if (Array.isArray(typeStr)) {
713
+ console.log(typeStr);
714
+ }
715
+ // continue;
716
+ // const res: Record<string, PostgresTableSpec> = await this.createTable(pool, typeStr);
717
+ try {
718
+ childClass = parsedType.model;
719
+ const m = new childClass();
720
+ childPk = (0, db_decorators_1.findPrimaryKey)(m);
721
+ typeStr = this.parseTypeToPostgres(parsedType.pkType, false, true);
722
+ await this.createTable(client, childClass);
723
+ }
724
+ catch (e) {
725
+ if (!(e instanceof db_decorators_1.ConflictError))
726
+ throw e;
727
+ }
728
+ }
729
+ let tp = Array.isArray(typeData.customTypes)
730
+ ? typeData.customTypes[0]
731
+ : typeData.customTypes;
732
+ tp = typeof tp === "function" && !tp.name ? tp() : tp;
733
+ const validationStr = this.parseValidationToPostgres(column, tp, isPk, decorator_validation_1.ValidationKeys.MAX_LENGTH, decoratorData[decorator_validation_1.ValidationKeys.MAX_LENGTH] || {
734
+ [decorator_validation_1.ValidationKeys.MAX_LENGTH]: 255,
735
+ });
736
+ const q = `${column} ${typeStr}${validationStr}`;
737
+ if (isPk) {
738
+ query.unshift(q);
739
+ }
740
+ else {
741
+ query.push(q);
742
+ }
743
+ for (const [key, props] of Object.entries(decoratorData).filter(([k]) => ![decorator_validation_1.ValidationKeys.TYPE, decorator_validation_1.ValidationKeys.MAX_LENGTH].includes(k))) {
744
+ const validation = this.parseValidationToPostgres(column, tp, isPk, key, props);
745
+ if (validation.startsWith("CONSTRAINT")) {
746
+ constraints.push(validation);
747
+ }
748
+ else {
749
+ if (validation) {
750
+ query.push(validation);
751
+ }
752
+ }
753
+ }
754
+ }
755
+ // TODO ignore for now. this leaves foreign keys out
756
+ // eslint-disable-next-line no-constant-binary-expression
757
+ if (false || (dbDecs && dbDecs.decorators.length)) {
758
+ if (!typeData)
759
+ throw new Error(`Missing type information`);
760
+ for (const decorator of dbDecs.decorators) {
761
+ const { key, props } = decorator;
762
+ const validation = this.parseRelationsToPostgres(column, childClass, childPk.id, key, props);
763
+ if (validation.startsWith("FOREIGN")) {
764
+ foreignKeys.push(validation);
765
+ }
766
+ else {
767
+ throw new db_decorators_1.InternalError(`Unsupported relation: ${key}`);
768
+ }
769
+ }
770
+ }
771
+ result[prop.toString()] = {
772
+ query: query.join(" "),
773
+ values: [],
774
+ primaryKey: isPk,
775
+ constraints: constraints,
776
+ foreignKeys: foreignKeys,
777
+ };
778
+ }
779
+ const values = Object.values(result);
780
+ const query = values.map((r) => r.query).join(",\n");
781
+ const constraints = values
782
+ .filter((c) => !!c.constraints.length)
783
+ .map((r) => r.constraints)
784
+ .join(",\n");
785
+ const foreignKeys = values
786
+ .filter((c) => !!c.foreignKeys.length)
787
+ .map((r) => r.foreignKeys)
788
+ .join(",\n");
789
+ const vals = [query, constraints];
790
+ if (foreignKeys) {
791
+ vals.push(foreignKeys);
792
+ }
793
+ const queryString = `CREATE TABLE ${tableName} (${vals.filter((v) => !!v).join(",\n")})`;
794
+ try {
795
+ await client.query(queryString);
796
+ await client.query(`CREATE TRIGGER notify_changes_${tableName}
797
+ AFTER INSERT OR UPDATE OR DELETE ON ${tableName}
798
+ FOR EACH ROW
799
+ EXECUTE FUNCTION notify_table_changes();`);
800
+ }
801
+ catch (e) {
802
+ throw this.parseError(e);
803
+ }
804
+ return result;
805
+ }
806
+ static async getCurrentUser(client) {
807
+ const queryString = `SELECT CURRENT_USER;`;
808
+ try {
809
+ const result = await client.query(queryString);
810
+ return result[0].current_user;
811
+ }
812
+ catch (e) {
813
+ throw this.parseError(e);
814
+ }
815
+ }
816
+ static decoration() {
817
+ // @table() => @Entity()
818
+ const tableKey = core_1.Adapter.key(core_1.PersistenceKeys.TABLE);
819
+ decorator_validation_1.Decoration.flavouredAs(constants_1.TypeORMFlavour)
820
+ .for(tableKey)
821
+ .extend((original) => (0, Entity_1.Entity)()(original[decorator_validation_1.ModelKeys.ANCHOR] || original))
822
+ .apply();
823
+ // @pk() => @PrimaryGeneratedColumn() | @PrimaryColumn()
824
+ const pkKey = core_1.Repository.key(db_decorators_1.DBKeys.ID);
825
+ function pkDec(options) {
826
+ const decorators = [
827
+ (0, decorator_validation_1.required)(),
828
+ (0, db_decorators_1.readonly)(),
829
+ (0, decorator_validation_1.propMetadata)(pkKey, options),
830
+ ];
831
+ if (options.type)
832
+ decorators.push((0, PrimaryGeneratedColumn_1.PrimaryGeneratedColumn)());
833
+ else
834
+ decorators.push((0, PrimaryColumn_1.PrimaryColumn)({ unique: true }));
835
+ return (0, reflection_1.apply)(...decorators);
836
+ }
837
+ decorator_validation_1.Decoration.flavouredAs(constants_1.TypeORMFlavour)
838
+ .for(pkKey)
839
+ .define({
840
+ decorator: pkDec,
841
+ })
842
+ .apply();
843
+ // @column("columnName") => @Column({name: "columnName"})
844
+ const columnKey = core_1.Adapter.key(core_1.PersistenceKeys.COLUMN);
845
+ decorator_validation_1.Decoration.flavouredAs(constants_1.TypeORMFlavour)
846
+ .for(columnKey)
847
+ .extend({
848
+ decorator: function columm(name) {
849
+ return function column(obj, prop) {
850
+ return (0, Column_1.Column)({
851
+ name: name || prop,
852
+ nullable: true,
853
+ })(obj, prop);
854
+ };
855
+ },
856
+ transform: (args) => {
857
+ const columnName = args[1];
858
+ return [columnName];
859
+ },
860
+ })
861
+ .apply();
862
+ // @unique => @Column({unique: true})
863
+ const uniqueKey = core_1.Adapter.key(core_1.PersistenceKeys.UNIQUE);
864
+ decorator_validation_1.Decoration.flavouredAs(constants_1.TypeORMFlavour)
865
+ .for(uniqueKey)
866
+ .define((0, decorator_validation_1.propMetadata)(uniqueKey, {}))
867
+ .extend((0, Column_1.Column)({ unique: true }))
868
+ .apply();
869
+ // @required => @Column({ nullable: false })
870
+ const requiredKey = decorator_validation_1.Validation.key(decorator_validation_1.ValidationKeys.REQUIRED);
871
+ decorator_validation_1.Decoration.flavouredAs(constants_1.TypeORMFlavour)
872
+ .for(requiredKey)
873
+ .extend((0, Column_1.Column)({ nullable: false }))
874
+ .apply();
875
+ // @version => @VersionColumn()
876
+ const versionKey = core_1.Repository.key(db_decorators_1.DBKeys.VERSION);
877
+ decorator_validation_1.Decoration.flavouredAs(constants_1.TypeORMFlavour)
878
+ .for(versionKey)
879
+ .define((0, decorator_validation_1.type)(Number.name), (0, typeorm_1.VersionColumn)())
880
+ .apply();
881
+ function ValidationUpdateKey(key) {
882
+ return db_decorators_1.UpdateValidationKeys.REFLECT + key;
883
+ }
884
+ // @timestamp(op) => @CreateDateColumn() || @UpdateDateColumn()
885
+ const timestampKey = ValidationUpdateKey(db_decorators_1.DBKeys.TIMESTAMP);
886
+ function ts(operation, format) {
887
+ const decorators = [
888
+ (0, decorator_validation_1.date)(format, db_decorators_1.DEFAULT_ERROR_MESSAGES.TIMESTAMP.DATE),
889
+ (0, decorator_validation_1.required)(db_decorators_1.DEFAULT_ERROR_MESSAGES.TIMESTAMP.REQUIRED),
890
+ (0, decorator_validation_1.propMetadata)(decorator_validation_1.Validation.key(db_decorators_1.DBKeys.TIMESTAMP), {
891
+ operation: operation,
892
+ format: format,
893
+ }),
894
+ ];
895
+ if (operation.indexOf(db_decorators_1.OperationKeys.UPDATE) !== -1)
896
+ decorators.push((0, decorator_validation_1.propMetadata)(timestampKey, {
897
+ message: db_decorators_1.DEFAULT_ERROR_MESSAGES.TIMESTAMP.INVALID,
898
+ }));
899
+ else
900
+ decorators.push((0, db_decorators_1.readonly)());
901
+ return (0, reflection_1.apply)(...decorators);
902
+ }
903
+ decorator_validation_1.Decoration.flavouredAs(constants_1.TypeORMFlavour)
904
+ .for(timestampKey)
905
+ .define({
906
+ decorator: ts,
907
+ })
908
+ .extend({
909
+ decorator: function timestamp(...ops) {
910
+ return function timestamp(obj, prop) {
911
+ if (ops.indexOf(db_decorators_1.OperationKeys.UPDATE) !== -1)
912
+ return (0, UpdateDateColumn_1.UpdateDateColumn)()(obj, prop);
913
+ return (0, CreateDateColumn_1.CreateDateColumn)()(obj, prop);
914
+ };
915
+ },
916
+ transform: (args) => {
917
+ return args[0];
918
+ },
919
+ })
920
+ .apply();
921
+ // @oneToOne(clazz) => @OneToOne(() => clazz)
922
+ const oneToOneKey = core_1.Repository.key(core_1.PersistenceKeys.ONE_TO_ONE);
923
+ decorator_validation_1.Decoration.flavouredAs(constants_1.TypeORMFlavour)
924
+ .for(oneToOneKey)
925
+ .define({
926
+ decorator: function oneToOne(clazz, cascade, populate) {
927
+ const metadata = {
928
+ class: (clazz.name ? clazz.name : clazz),
929
+ cascade: cascade,
930
+ populate: populate,
931
+ };
932
+ const ormMeta = {
933
+ cascade: cascade.update === core_1.Cascade.CASCADE ||
934
+ cascade.delete === core_1.Cascade.CASCADE,
935
+ onDelete: cascade.delete ? "CASCADE" : "DEFAULT",
936
+ onUpdate: cascade.update ? "CASCADE" : "DEFAULT",
937
+ nullable: true,
938
+ eager: populate,
939
+ };
940
+ return (0, reflection_1.apply)((0, decorator_validation_1.prop)(core_1.PersistenceKeys.RELATIONS), (0, decorator_validation_1.type)([
941
+ (typeof clazz === "function" && !clazz.name
942
+ ? clazz
943
+ : clazz.name),
944
+ String.name,
945
+ Number.name,
946
+ BigInt.name,
947
+ ]), (0, decorator_validation_1.propMetadata)(oneToOneKey, metadata), (0, typeorm_1.OneToOne)(() => {
948
+ if (!clazz.name)
949
+ clazz = clazz();
950
+ if (!clazz[decorator_validation_1.ModelKeys.ANCHOR])
951
+ throw new db_decorators_1.InternalError("Original Model not found in constructor");
952
+ return clazz[decorator_validation_1.ModelKeys.ANCHOR];
953
+ }, (model) => {
954
+ const pk = (0, db_decorators_1.findPrimaryKey)(new clazz()).id;
955
+ return model[pk];
956
+ }, ormMeta), (0, typeorm_1.JoinColumn)());
957
+ },
958
+ })
959
+ .apply();
960
+ // @oneToMany(clazz) => @OneToMany(() => clazz)
961
+ const oneToManyKey = core_1.Repository.key(core_1.PersistenceKeys.ONE_TO_MANY);
962
+ decorator_validation_1.Decoration.flavouredAs(constants_1.TypeORMFlavour)
963
+ .for(oneToManyKey)
964
+ .define({
965
+ decorator: function oneToMany(clazz, cascade, populate) {
966
+ const metadata = {
967
+ class: (clazz.name ? clazz.name : clazz),
968
+ cascade: cascade,
969
+ populate: populate,
970
+ };
971
+ return (0, reflection_1.apply)((0, decorator_validation_1.prop)(core_1.PersistenceKeys.RELATIONS), (0, decorator_validation_1.list)(clazz), (0, decorator_validation_1.propMetadata)(oneToManyKey, metadata), function OneToManyWrapper(obj, prop) {
972
+ const ormMeta = {
973
+ cascade: cascade.update === core_1.Cascade.CASCADE ||
974
+ cascade.delete === core_1.Cascade.CASCADE,
975
+ onDelete: cascade.delete ? "CASCADE" : "DEFAULT",
976
+ onUpdate: cascade.update ? "CASCADE" : "DEFAULT",
977
+ nullable: true,
978
+ eager: populate,
979
+ };
980
+ return (0, typeorm_1.OneToMany)(() => {
981
+ if (!clazz.name)
982
+ clazz = clazz();
983
+ if (!clazz[decorator_validation_1.ModelKeys.ANCHOR])
984
+ throw new db_decorators_1.InternalError("Original Model not found in constructor");
985
+ return clazz[decorator_validation_1.ModelKeys.ANCHOR];
986
+ }, (model) => {
987
+ if (!clazz.name)
988
+ clazz = clazz();
989
+ const m = new clazz();
990
+ const crossRelationKey = Object.keys(m).find((k) => {
991
+ const decs = reflection_1.Reflection.getPropertyDecorators(core_1.Repository.key(core_1.PersistenceKeys.MANY_TO_ONE), m, k, true);
992
+ if (!decs || !decs.decorators || !decs.decorators.length)
993
+ return false;
994
+ const designType = Reflect.getMetadata(decorator_validation_1.ModelKeys.TYPE, m, k);
995
+ if (!designType)
996
+ throw new db_decorators_1.InternalError(`No Type Definition found for ${k} in ${m.constructor.name}`);
997
+ return designType.name === obj.constructor.name;
998
+ });
999
+ if (!crossRelationKey)
1000
+ throw new db_decorators_1.InternalError(`Cross relation not found. Did you use @manyToOne on the ${clazz.name}?`);
1001
+ return model[crossRelationKey];
1002
+ }, ormMeta)(obj, prop);
1003
+ });
1004
+ },
1005
+ })
1006
+ .apply();
1007
+ // @manyToOne(clazz) => @ManyToOne(() => clazz)
1008
+ const manyToOneKey = core_1.Repository.key(core_1.PersistenceKeys.MANY_TO_ONE);
1009
+ decorator_validation_1.Decoration.flavouredAs(constants_1.TypeORMFlavour)
1010
+ .for(manyToOneKey)
1011
+ .define({
1012
+ decorator: function manyToOne(clazz, cascade, populate) {
1013
+ const metadata = {
1014
+ class: (clazz.name ? clazz.name : clazz),
1015
+ cascade: cascade,
1016
+ populate: populate,
1017
+ };
1018
+ const ormMeta = {
1019
+ cascade: cascade.update === core_1.Cascade.CASCADE ||
1020
+ cascade.delete === core_1.Cascade.CASCADE,
1021
+ onDelete: cascade.delete ? "CASCADE" : "DEFAULT",
1022
+ onUpdate: cascade.update ? "CASCADE" : "DEFAULT",
1023
+ nullable: true,
1024
+ eager: populate,
1025
+ };
1026
+ return (0, reflection_1.apply)((0, decorator_validation_1.prop)(core_1.PersistenceKeys.RELATIONS), (0, decorator_validation_1.type)([
1027
+ (typeof clazz === "function" && !clazz.name
1028
+ ? clazz
1029
+ : clazz.name),
1030
+ String.name,
1031
+ Number.name,
1032
+ BigInt.name,
1033
+ ]), (0, decorator_validation_1.propMetadata)(manyToOneKey, metadata), function ManyToOneWrapper(obj, prop) {
1034
+ return (0, typeorm_1.ManyToOne)(() => {
1035
+ if (!clazz.name)
1036
+ clazz = clazz();
1037
+ if (!clazz[decorator_validation_1.ModelKeys.ANCHOR])
1038
+ throw new db_decorators_1.InternalError("Original Model not found in constructor");
1039
+ return clazz[decorator_validation_1.ModelKeys.ANCHOR];
1040
+ }, (model) => {
1041
+ if (!clazz.name)
1042
+ clazz = clazz();
1043
+ const m = new clazz();
1044
+ const crossRelationKey = Object.keys(m).find((k) => {
1045
+ const decs = reflection_1.Reflection.getPropertyDecorators(core_1.Repository.key(core_1.PersistenceKeys.ONE_TO_MANY), m, k, true);
1046
+ if (!decs || !decs.decorators || !decs.decorators.length)
1047
+ return false;
1048
+ const listDec = Reflect.getMetadata(decorator_validation_1.Validation.key(decorator_validation_1.ValidationKeys.LIST), m, k);
1049
+ if (!listDec)
1050
+ throw new db_decorators_1.InternalError(`No Type Definition found for ${k} in ${m.constructor.name}`);
1051
+ const name = listDec.clazz[0]().name;
1052
+ return name === obj.constructor.name;
1053
+ });
1054
+ if (!crossRelationKey)
1055
+ throw new db_decorators_1.InternalError(`Cross relation not found. Did you use @manyToOne on the ${clazz.name}?`);
1056
+ return model[crossRelationKey];
1057
+ })(obj, prop);
1058
+ });
1059
+ },
1060
+ })
1061
+ .apply();
1062
+ // @manyToMany(clazz) => @ManyToMany(() => clazz)
1063
+ const manyToManyKey = core_1.Repository.key(core_1.PersistenceKeys.MANY_TO_MANY);
1064
+ decorator_validation_1.Decoration.flavouredAs(constants_1.TypeORMFlavour)
1065
+ .for(manyToManyKey)
1066
+ .define({
1067
+ decorator: function manyToMany(clazz, cascade, populate) {
1068
+ const metadata = {
1069
+ class: clazz.name,
1070
+ cascade: cascade,
1071
+ populate: populate,
1072
+ };
1073
+ const ormMeta = {
1074
+ cascade: cascade.update === core_1.Cascade.CASCADE ||
1075
+ cascade.delete === core_1.Cascade.CASCADE,
1076
+ onDelete: cascade.delete ? "CASCADE" : "DEFAULT",
1077
+ onUpdate: cascade.update ? "CASCADE" : "DEFAULT",
1078
+ nullable: true,
1079
+ eager: populate,
1080
+ };
1081
+ return (0, reflection_1.apply)((0, decorator_validation_1.prop)(core_1.PersistenceKeys.RELATIONS), (0, decorator_validation_1.list)(clazz), (0, decorator_validation_1.propMetadata)(manyToManyKey, metadata), (0, typeorm_1.ManyToMany)(() => {
1082
+ if (!clazz.name)
1083
+ clazz = clazz();
1084
+ if (!clazz[decorator_validation_1.ModelKeys.ANCHOR])
1085
+ throw new db_decorators_1.InternalError("Original Model not found in constructor");
1086
+ return clazz[decorator_validation_1.ModelKeys.ANCHOR];
1087
+ }, (model) => {
1088
+ if (!clazz.name)
1089
+ clazz = clazz();
1090
+ const pk = (0, db_decorators_1.findPrimaryKey)(new clazz()).id;
1091
+ return model[pk];
1092
+ }, ormMeta), (0, typeorm_1.JoinTable)());
1093
+ },
1094
+ })
1095
+ .apply();
1096
+ }
1097
+ }
1098
+ exports.TypeORMAdapter = TypeORMAdapter;
1099
+ __decorate([
1100
+ (0, core_1.final)(),
1101
+ __metadata("design:type", Function),
1102
+ __metadata("design:paramtypes", []),
1103
+ __metadata("design:returntype", TypeORMDispatch_1.TypeORMDispatch)
1104
+ ], TypeORMAdapter.prototype, "Dispatch", null);
1105
+ __decorate([
1106
+ (0, core_1.final)(),
1107
+ __metadata("design:type", Function),
1108
+ __metadata("design:paramtypes", []),
1109
+ __metadata("design:returntype", Object)
1110
+ ], TypeORMAdapter.prototype, "repository", null);
1111
+ __decorate([
1112
+ (0, core_1.final)(),
1113
+ __metadata("design:type", Function),
1114
+ __metadata("design:paramtypes", []),
1115
+ __metadata("design:returntype", query_1.TypeORMStatement)
1116
+ ], TypeORMAdapter.prototype, "Statement", null);
1117
+ __decorate([
1118
+ (0, core_1.final)(),
1119
+ __metadata("design:type", Function),
1120
+ __metadata("design:paramtypes", [Object]),
1121
+ __metadata("design:returntype", Promise)
1122
+ ], TypeORMAdapter.prototype, "Sequence", null);
1123
+ __decorate([
1124
+ (0, core_1.final)(),
1125
+ __metadata("design:type", Function),
1126
+ __metadata("design:paramtypes", [Object]),
1127
+ __metadata("design:returntype", Promise)
1128
+ ], TypeORMAdapter.prototype, "index", null);
1129
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVHlwZU9STUFkYXB0ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvVHlwZU9STUFkYXB0ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7O0FBa0ZBLDBFQW9CQztBQXRHRCx5Q0FXd0I7QUFDeEIsK0NBQWlFO0FBQ2pFLDJEQVlpQztBQUNqQyw0QkFBMEI7QUFDMUIseUVBcUJ3QztBQUN4Qyx5Q0FBc0M7QUFDdEMsNkNBQTJDO0FBQzNDLHFEQUE4QztBQUM5QyxpREFBNEM7QUFFNUMscURBQXlEO0FBQ3pELCtEQUF3RDtBQUN4RCwrQ0FBNEM7QUFDNUMsMkRBQW9EO0FBQ3BELHVDQUFtRDtBQUNuRCxxQ0FjaUI7QUFFakIsbURBQTRDO0FBQzVDLHVFQUFnRTtBQUNoRSx1RUFBZ0U7QUFDaEUsbUZBQTRFO0FBQzVFLGlFQUEwRDtBQUMxRCxtREFBNEM7QUFFckMsS0FBSyxVQUFVLCtCQUErQixDQU1uRCxPQUE4QixFQUM5QixJQUFPLEVBQ1AsR0FBWSxFQUNaLEtBQVE7SUFFUixJQUFJLENBQUM7UUFDSCxNQUFNLElBQUksR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ2pDLEtBQUssQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFxQixDQUFDO1FBQ25DLDZEQUE2RDtJQUMvRCxDQUFDO0lBQUMsT0FBTyxDQUFVLEVBQUUsQ0FBQztRQUNwQixNQUFNLElBQUksNkJBQWEsQ0FDckIsZ0VBQWdFLENBQ2pFLENBQUM7SUFDSixDQUFDO0FBQ0gsQ0FBQztBQUVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBK0JHO0FBQ0gsTUFBYSxjQUFlLFNBQVEsY0FLbkM7SUFHQyxJQUFJLFVBQVU7UUFDWixJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQ3RCLE1BQU0sTUFBTSxHQUFHLGNBQU8sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQzVDLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxvQkFBVSxDQUMvQixNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUU7Z0JBQ3pCLFFBQVEsRUFBRSxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsZ0NBQVMsQ0FBQyxNQUF3QixDQUFDLENBQUM7YUFDbkUsQ0FBQyxDQUNILENBQUM7UUFDSixDQUFDO1FBQ0QsT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDO0lBQzFCLENBQUM7SUFDRCxvQkFBb0I7SUFFcEIsWUFBWSxPQUEwQixFQUFFLEtBQWM7UUFDcEQsS0FBSyxDQUFDLE9BQU8sRUFBRSwwQkFBYyxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQ3hDLENBQUM7SUFFa0IsS0FBSyxDQUFDLEtBQUssQ0FDNUIsU0FBd0IsRUFDeEIsS0FBcUIsRUFDckIsS0FBNEI7UUFFNUIsTUFBTSxDQUFDLEdBQUcsTUFBTSxLQUFLLENBQUMsS0FBSyxDQUFDLFNBQVMsRUFBRSxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDckQsTUFBTSxNQUFNLEdBQVE7WUFDbEIsSUFBSSxFQUFFLENBQUMsTUFBTSxjQUFjLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBVztTQUN2RSxDQUFDO1FBQ0YsTUFBTSxDQUFDLEdBQUcsSUFBSSxLQUFLLEVBQUUsQ0FBQztRQUV0QixNQUFNLFVBQVUsR0FBYSxFQUFFLENBQUM7UUFDaEMsSUFBSSxTQUFTLEtBQUssNkJBQWEsQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUN2QyxNQUFNLEVBQUUsR0FBRyxJQUFBLDhCQUFjLEVBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1lBQ2hDLFVBQVUsQ0FBQyxJQUFJLENBQUMsRUFBWSxDQUFDLENBQUM7UUFDaEMsQ0FBQztRQUVELElBQ0UsU0FBUyxLQUFLLDZCQUFhLENBQUMsTUFBTTtZQUNsQyxTQUFTLEtBQUssNkJBQWEsQ0FBQyxNQUFNLEVBQ2xDLENBQUM7WUFDRCxNQUFNLElBQUksR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEtBQTBCLEVBQUUsR0FBRyxFQUFFLEVBQUU7Z0JBQ3JFLE1BQU0sSUFBSSxHQUFHLHVCQUFVLENBQUMscUJBQXFCLENBQzNDLHFDQUFjLENBQUMsT0FBTyxFQUN0QixDQUFDLEVBQ0QsR0FBRyxFQUNILElBQUksQ0FDTCxDQUFDO2dCQUNGLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUM5QixDQUFDLEdBQVEsRUFBRSxFQUFFLENBQ1gsR0FBRyxDQUFDLEdBQUcsS0FBSyxzQkFBTSxDQUFDLFNBQVM7b0JBQzVCLEdBQUcsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FDaEQsQ0FBQztnQkFDRixJQUFJLEdBQUcsRUFBRSxDQUFDO29CQUNSLEtBQUssQ0FBQyxHQUFHLENBQUMsR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDO2dCQUN6QixDQUFDO2dCQUNELE9BQU8sS0FBSyxDQUFDO1lBQ2YsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBRVAsVUFBVSxDQUFDLElBQUksQ0FBQyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztRQUN4QyxDQUFDO1FBRUQsTUFBTSxDQUFDLDJCQUEyQixHQUFHLENBQ25DLENBQUMsQ0FBQywyQkFBMkIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLDJCQUEyQixDQUFDLENBQUMsQ0FBQyxFQUFFLENBQ25FLENBQUMsTUFBTSxDQUFDLEdBQUcsVUFBVSxDQUFDLENBQUM7UUFDeEIsT0FBTyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRSxNQUFNLENBQWlCLENBQUM7SUFDbEQsQ0FBQztJQUdrQixRQUFRO1FBQ3pCLE9BQU8sSUFBSSxpQ0FBZSxFQUFFLENBQUM7SUFDL0IsQ0FBQztJQUdRLFVBQVU7UUFDakIsT0FBTyxxQ0FBaUIsQ0FBQztJQUMzQixDQUFDO0lBRUQ7Ozs7O09BS0c7SUFFSCxTQUFTO1FBQ1AsT0FBTyxJQUFJLHdCQUFnQixDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3BDLENBQUM7SUFFRDs7Ozs7T0FLRztJQUVHLEFBQU4sS0FBSyxDQUFDLFFBQVEsQ0FBQyxPQUF3QjtRQUNyQyxPQUFPLElBQUksMkJBQWUsQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDNUMsQ0FBQztJQUVEOzs7O09BSUc7SUFDSCxLQUFLLENBQUMsVUFBVTtRQUNkLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUM7UUFDM0IsSUFBSSxDQUFDO1lBQ0gsTUFBTSxFQUFFLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDeEIsQ0FBQztRQUFDLE9BQU8sQ0FBVSxFQUFFLENBQUM7WUFDcEIsTUFBTSxJQUFJLENBQUMsVUFBVSxDQUFDLENBQVUsQ0FBQyxDQUFDO1FBQ3BDLENBQUM7UUFDRCxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDMUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxHQUFHLElBQUksQ0FBQyxPQUFPLHNCQUFzQixDQUFDLENBQUM7SUFDckQsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUVhLEFBQU4sS0FBSyxDQUFDLEtBQUssQ0FDbkIsR0FBRyxNQUF3QjtRQUUzQixNQUFNLE9BQU8sR0FBbUIsSUFBQSx5QkFBZSxFQUFDLE1BQU0sQ0FBQyxDQUFDO1FBRXhELElBQUksQ0FBQztZQUNILE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7WUFFckMsS0FBSyxNQUFNLEtBQUssSUFBSSxPQUFPLEVBQUUsQ0FBQztnQkFDNUIsTUFBTSxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUN6RCxDQUFDO1lBRUQsTUFBTSxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUN4QyxDQUFDO1FBQUMsT0FBTyxDQUFVLEVBQUUsQ0FBQztZQUNwQixNQUFNLElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBQ3hDLE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFVLENBQUMsQ0FBQztRQUNwQyxDQUFDO0lBQ0gsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNNLEtBQUssQ0FBQyxHQUFHLENBQUksQ0FBZTtRQUNuQyxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDbkMsSUFBSSxDQUFDO1lBQ0gsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsYUFBYTtnQkFBRSxNQUFNLElBQUksQ0FBQyxVQUFVLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDekUsQ0FBQztRQUFDLE9BQU8sQ0FBVSxFQUFFLENBQUM7WUFDcEIsTUFBTSxJQUFJLENBQUMsVUFBVSxDQUFDLENBQVUsQ0FBQyxDQUFDO1FBQ3BDLENBQUM7UUFDRCxJQUFJLENBQUM7WUFDSCxNQUFNLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQztZQUM1QixHQUFHLENBQUMsS0FBSyxDQUNQLG9CQUFxQixLQUE0QyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQzdFLENBQUM7WUFDRixNQUFNLFFBQVEsR0FBRyxNQUFNLElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxNQUFNLENBQUMsQ0FBQztZQUM1RCxPQUFPLFFBQWEsQ0FBQztRQUN2QixDQUFDO1FBQUMsT0FBTyxDQUFVLEVBQUUsQ0FBQztZQUNwQixNQUFNLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBVSxDQUFDLENBQUM7UUFDcEMsQ0FBQztJQUNILENBQUM7SUFFUSxPQUFPLENBQ2QsS0FBUSxFQUNSLEVBQVcsRUFDWCxLQUFLLEdBQUcsS0FBSztRQU1iLE1BQU0sUUFBUSxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBRTFDLFFBQVEsQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsTUFBTSxDQUN0RCxDQUFDLEtBQTBCLEVBQUUsQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLEVBQUUsRUFBRTtZQUMzQyxJQUFJLEdBQUcsS0FBSyxzQkFBZSxDQUFDLFFBQVEsSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQztnQkFDMUQsT0FBTyxLQUFLLENBQUM7WUFDZixJQUFJLEtBQUssS0FBSyxTQUFTLEVBQUUsQ0FBQztnQkFDeEIsT0FBTyxLQUFLLENBQUM7WUFDZixDQUFDO1lBRUQsSUFBSSxLQUFLLFlBQVksSUFBSSxFQUFFLENBQUM7Z0JBQzFCLEtBQUssR0FBRyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztZQUNwQyxDQUFDO2lCQUFNLElBQUksNEJBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztnQkFDaEMsS0FBSyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLElBQUEsOEJBQWMsRUFBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLEVBQUUsSUFBSSxDQUFDLENBQUMsTUFBTSxDQUFDO1lBQ3JFLENBQUM7aUJBQU0sQ0FBQztnQkFDTixRQUFRLE9BQU8sS0FBSyxFQUFFLENBQUM7b0JBQ3JCLEtBQUssUUFBUTt3QkFDWCxLQUFLLEdBQUcsR0FBRyxLQUFLLEVBQUUsQ0FBQzt3QkFDbkIsTUFBTTtvQkFDUixRQUFRO29CQUNSLGFBQWE7Z0JBQ2YsQ0FBQztZQUNILENBQUM7WUFDRCxLQUFLLENBQUMsR0FBRyxDQUFDLEdBQUcsS0FBSyxDQUFDO1lBQ25CLE9BQU8sS0FBSyxDQUFDO1FBQ2YsQ0FBQyxFQUNELEVBQUUsQ0FDSCxDQUFDO1FBQ0YsTUFBTSxNQUFNLEdBQWlDLDRCQUFLLENBQUMsR0FBRyxDQUNwRCxLQUFLLENBQUMsV0FBVyxDQUFDLElBQUksQ0FDdkIsQ0FBQztRQUNGLElBQUksQ0FBQyxNQUFNO1lBQ1QsTUFBTSxJQUFJLDZCQUFhLENBQ3JCLFNBQVMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxJQUFJLHdCQUF3QixDQUN4RCxDQUFDO1FBQ0osTUFBTSxNQUFNLEdBQUcsS0FBSztZQUNsQixDQUFDLENBQUMsSUFBSyxNQUFjLENBQUMsZ0NBQVMsQ0FBQyxNQUE2QixDQUFDLEVBQUU7WUFDaEUsQ0FBQyxDQUFDLElBQUksTUFBTSxFQUFFLENBQUM7UUFDakIsSUFBSSxLQUFLO1lBQ1AsTUFBTSxDQUFDLGNBQWMsQ0FBQyxNQUFNLEVBQUUsYUFBYSxFQUFFO2dCQUMzQyxZQUFZLEVBQUUsS0FBSztnQkFDbkIsVUFBVSxFQUFFLEtBQUs7Z0JBQ2pCLEtBQUssRUFBRyxNQUFjLENBQUMsZ0NBQVMsQ0FBQyxNQUE2QixDQUFDO2dCQUMvRCxRQUFRLEVBQUUsS0FBSzthQUNoQixDQUFDLENBQUM7UUFDTCxNQUFNLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxPQUFPLENBQ3JDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDLEdBQTBCLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FDM0QsQ0FBQztRQUNGLFFBQVEsQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDO1FBQ3pCLE9BQU8sUUFBUSxDQUFDO0lBQ2xCLENBQUM7SUFFUSxNQUFNLENBQ2IsR0FBd0IsRUFDeEIsS0FBOEIsRUFDOUIsRUFBVyxFQUNYLEVBQTRCLEVBQzVCLFNBQStCO1FBRS9CLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUN0QyxJQUFJLFNBQVMsRUFBRSxDQUFDO1lBQ2QsR0FBRyxDQUFDLE9BQU8sQ0FDVCxtQ0FBbUMsTUFBTSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FDdkUsQ0FBQztZQUNGLE1BQU0sQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLEVBQUUsRUFBRTtnQkFDL0MsSUFBSSxHQUFHLElBQUksR0FBRztvQkFDWixNQUFNLElBQUksNkJBQWEsQ0FDckIsc0JBQXNCLEdBQUcsNEJBQTRCLE9BQU8sS0FBSyxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsSUFBSSx3QkFBd0IsQ0FDNUgsQ0FBQztnQkFDSCxHQUFTLENBQUMsR0FBYyxDQUFDLEdBQUcsR0FBRyxDQUFDO1lBQ25DLENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztRQUVELE9BQU8sSUFBSyxLQUF3QixDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQzVDLENBQUM7SUFFRDs7Ozs7Ozs7T0FRRztJQUNNLEtBQUssQ0FBQyxNQUFNLENBQ25CLFNBQWlCLEVBQ2pCLEVBQW1CLEVBQ25CLEtBQTBCO0lBQzFCLDZEQUE2RDtJQUM3RCxHQUFHLElBQVc7UUFFZCxNQUFNLENBQUMsR0FBdUIsU0FBMEMsQ0FBQztRQUN6RSxJQUFJLENBQUM7WUFDSCxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUM5QyxPQUFPLE1BQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNoQyxDQUFDO1FBQUMsT0FBTyxDQUFVLEVBQUUsQ0FBQztZQUNwQixNQUFNLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBVSxDQUFDLENBQUM7UUFDcEMsQ0FBQztJQUNILENBQUM7SUFFRDs7Ozs7OztPQU9HO0lBQ00sS0FBSyxDQUFDLElBQUksQ0FDakIsU0FBaUIsRUFDakIsRUFBbUIsRUFDbkIsRUFBVTtRQUVWLE1BQU0sQ0FBQyxHQUF1QixTQUEwQyxDQUFDO1FBQ3pFLElBQUksTUFBVyxDQUFDO1FBQ2hCLElBQUksQ0FBQztZQUNILE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzlDLE1BQU0sQ0FBQyxHQUFtQjtnQkFDeEIsS0FBSyxFQUFFO29CQUNMLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRTtpQkFDVDthQUNGLENBQUM7WUFDRixNQUFNLEdBQUcsQ0FBQyxNQUFNLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQXdCLENBQUM7UUFDMUQsQ0FBQztRQUFDLE9BQU8sQ0FBVSxFQUFFLENBQUM7WUFDcEIsTUFBTSxJQUFJLENBQUMsVUFBVSxDQUFDLENBQVUsQ0FBQyxDQUFDO1FBQ3BDLENBQUM7UUFDRCxJQUFJLENBQUMsTUFBTTtZQUNULE1BQU0sSUFBSSw2QkFBYSxDQUNyQixtQkFBbUIsRUFBRSx1QkFBdUIsT0FBTyxTQUFTLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLGlCQUFVLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQ3RILENBQUM7UUFDSixPQUFPLE1BQU0sQ0FBQztJQUNoQixDQUFDO0lBRUQ7Ozs7Ozs7O09BUUc7SUFDTSxLQUFLLENBQUMsTUFBTSxDQUNuQixTQUFpQixFQUNqQixFQUFtQixFQUNuQixLQUEwQjtJQUMxQiw2REFBNkQ7SUFDN0QsR0FBRyxJQUFXO1FBRWQsTUFBTSxDQUFDLEdBQXVCLFNBQTBDLENBQUM7UUFDekUsSUFBSSxDQUFDO1lBQ0gsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDOUMsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzFCLENBQUM7UUFBQyxPQUFPLENBQVUsRUFBRSxDQUFDO1lBQ3BCLE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFVLENBQUMsQ0FBQztRQUNwQyxDQUFDO0lBQ0gsQ0FBQztJQUVEOzs7Ozs7O09BT0c7SUFDTSxLQUFLLENBQUMsTUFBTSxDQUNuQixTQUFpQixFQUNqQixFQUFtQixFQUNuQixFQUFVO0lBQ1YsNkRBQTZEO0lBQzdELEdBQUcsSUFBVztRQUVkLE1BQU0sQ0FBQyxHQUF1QixTQUEwQyxDQUFDO1FBQ3pFLElBQUksQ0FBQztZQUNILE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzlDLE1BQU0sS0FBSyxHQUFHLE1BQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBQ2pELE1BQU0sR0FBRyxHQUFHLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUNsQyxPQUFPLEtBQUssQ0FBQztRQUNmLENBQUM7UUFBQyxPQUFPLENBQVUsRUFBRSxDQUFDO1lBQ3BCLE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFVLENBQUMsQ0FBQztRQUNwQyxDQUFDO0lBQ0gsQ0FBQztJQUVRLEtBQUssQ0FBQyxTQUFTLENBQ3RCLFNBQWlCLEVBQ2pCLEVBQXVCLEVBQ3ZCLEtBQTRCO0lBQzVCLDZEQUE2RDtJQUM3RCxHQUFHLElBQVc7UUFFZCxNQUFNLENBQUMsR0FBdUIsU0FBMEMsQ0FBQztRQUN6RSxJQUFJLENBQUM7WUFDSCxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUM5QyxNQUFNLE1BQU0sR0FBaUIsTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3RELE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FDakIsU0FBUyxFQUNULE1BQU0sQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQ3JDLElBQUksQ0FDTCxDQUFDO1FBQ0osQ0FBQztRQUFDLE9BQU8sQ0FBVSxFQUFFLENBQUM7WUFDcEIsTUFBTSxJQUFJLENBQUMsVUFBVSxDQUFDLENBQVUsQ0FBQyxDQUFDO1FBQ3BDLENBQUM7SUFDSCxDQUFDO0lBRVEsS0FBSyxDQUFDLE9BQU8sQ0FDcEIsU0FBaUIsRUFDakIsRUFBZ0MsRUFDaEMsRUFBVTtJQUNWLDZEQUE2RDtJQUM3RCxHQUFHLElBQVc7UUFFZCxJQUFJLENBQUMsRUFBRSxDQUFDLE1BQU07WUFBRSxPQUFPLEVBQUUsQ0FBQztRQUUxQixNQUFNLENBQUMsR0FBdUIsU0FBMEMsQ0FBQztRQUN6RSxJQUFJLENBQUM7WUFDSCxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUM5QyxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLElBQUEsWUFBRSxFQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUN2QyxDQUFDO1FBQUMsT0FBTyxDQUFVLEVBQUUsQ0FBQztZQUNwQixNQUFNLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBVSxDQUFDLENBQUM7UUFDcEMsQ0FBQztJQUNILENBQUM7SUFFUSxLQUFLLENBQUMsU0FBUyxDQUN0QixTQUFpQixFQUNqQixHQUF3QixFQUN4QixLQUE0QixFQUM1QixFQUFVLEVBQ1YsR0FBRyxJQUFXO1FBRWQsTUFBTSxNQUFNLEdBQUcsRUFBRSxDQUFDO1FBQ2xCLEtBQUssTUFBTSxDQUFDLElBQUksS0FBSyxFQUFFLENBQUM7WUFDdEIsTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDO1FBQy9ELENBQUM7UUFDRCxPQUFPLE1BQU0sQ0FBQztJQUNoQixDQUFDO0lBRVEsS0FBSyxDQUFDLFNBQVMsQ0FDdEIsU0FBaUIsRUFDakIsR0FBaUMsRUFDakMsRUFBVTtJQUNWLDZEQUE2RDtJQUM3RCxHQUFHLElBQVc7UUFFZCxJQUFJLENBQUMsR0FBRyxDQUFDLE1BQU07WUFBRSxPQUFPLEVBQUUsQ0FBQztRQUMzQixNQUFNLENBQUMsR0FBdUIsU0FBMEMsQ0FBQztRQUN6RSxJQUFJLENBQUM7WUFDSCxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUM5QyxNQUFNLE1BQU0sR0FBRyxNQUFNLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUN0RCxNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDdkIsT0FBTyxNQUFNLENBQUM7UUFDaEIsQ0FBQztRQUFDLE9BQU8sQ0FBVSxFQUFFLENBQUM7WUFDcEIsTUFBTSxJQUFJLENBQUMsVUFBVSxDQUFDLENBQVUsQ0FBQyxDQUFDO1FBQ3BDLENBQUM7SUFDSCxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0gsVUFBVSxDQUFDLEdBQW1CLEVBQUUsTUFBZTtRQUM3QyxPQUFPLGNBQWMsQ0FBQyxVQUFVLENBQUMsR0FBRyxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBQ2hELENBQUM7SUFFRDs7Ozs7T0FLRztJQUNnQixVQUFVLENBQUMsSUFBWTtRQUN4QyxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLDhCQUFrQixDQUFDLENBQUM7SUFDMUMsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7T0F5REc7SUFDTyxNQUFNLENBQUMsVUFBVSxDQUFDLEdBQW1CLEVBQUUsTUFBZTtRQUM5RCxJQUFJLEdBQUcsWUFBWSx5QkFBUztZQUFFLE9BQU8sR0FBVSxDQUFDO1FBQ2hELE1BQU0sSUFBSSxHQUFXLE9BQU8sR0FBRyxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDO1FBRWpFLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQywrQkFBK0IsQ0FBQztZQUM3QyxPQUFPLElBQUksNkJBQWEsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNqQyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsMkJBQTJCLENBQUM7WUFBRSxPQUFPLElBQUksNkJBQWEsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUU1RSx5RkFBeUY7UUFDekYsUUFBUSxJQUFJLENBQUMsUUFBUSxFQUFFLEVBQUUsQ0FBQztZQUN4QixrQ0FBa0M7WUFDbEMsS0FBSyxPQUFPLENBQUMsQ0FBQyxtQkFBbUI7WUFDakMsS0FBSyxPQUFPLENBQUMsQ0FBQyx3QkFBd0I7WUFDdEMsS0FBSyxPQUFPLEVBQUUsa0JBQWtCO2dCQUM5QixPQUFPLElBQUksNkJBQWEsQ0FBQyxNQUFnQixDQUFDLENBQUM7WUFFN0MsMEJBQTBCO1lBQzFCLEtBQUssT0FBTyxDQUFDLENBQUMsa0JBQWtCO1lBQ2hDLEtBQUssT0FBTyxFQUFFLG1CQUFtQjtnQkFDL0IsT0FBTyxJQUFJLDZCQUFhLENBQUMsTUFBZ0IsQ0FBQyxDQUFDO1lBRTdDLDRCQUE0QjtZQUM1QixLQUFLLE9BQU8sRUFBRSwyQkFBMkI7Z0JBQ3ZDLE9BQU8sSUFBSSxtQkFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBRTdCLG9CQUFvQjtZQUNwQjtnQkFDRSxJQUFJLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQyxLQUFLLENBQUMsZUFBZSxDQUFDO29CQUN4QyxPQUFPLElBQUksc0JBQWUsQ0FBQyxHQUFHLENBQUMsQ0FBQztnQkFDbEMsT0FBTyxJQUFJLDZCQUFhLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDbEMsQ0FBQztJQUNILENBQUM7SUFFRCxNQUFNLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxNQUF5QjtRQUM1QyxNQUFNLEdBQUcsR0FBRyxJQUFJLG9CQUFVLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDbkMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxhQUFhO1lBQUUsTUFBTSxHQUFHLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDL0MsT0FBTyxHQUFHLENBQUM7SUFDYixDQUFDO0lBRUQsTUFBTSxDQUFDLEtBQUssQ0FBQyxjQUFjLENBQ3pCLFVBQXNCLEVBQ3RCLE1BQWM7UUFFZCxNQUFNLEdBQUcsR0FBRyxpQkFBTyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUM7UUFDN0MsR0FBRyxDQUFDLE9BQU8sQ0FBQyxxQkFBcUIsTUFBTSxFQUFFLENBQUMsQ0FBQztRQUMzQyxJQUFJLENBQUM7WUFDSCxNQUFNLFVBQVUsQ0FBQyxLQUFLLENBQUMsbUJBQW1CLE1BQU0sRUFBRSxDQUFDLENBQUM7WUFDcEQsR0FBRyxDQUFDLElBQUksQ0FBQyxvQkFBb0IsTUFBTSxFQUFFLENBQUMsQ0FBQztRQUN6QyxDQUFDO1FBQUMsT0FBTyxDQUFVLEVBQUUsQ0FBQztZQUNwQixNQUFNLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBVSxDQUFDLENBQUM7UUFDcEMsQ0FBQztJQUNILENBQUM7SUFFRCxNQUFNLENBQUMsS0FBSyxDQUFDLG9CQUFvQixDQUMvQixVQUFzQixFQUN0QixJQUFZO1FBRVosTUFBTSxHQUFHLEdBQUcsaUJBQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLG9CQUFvQixDQUFDLENBQUM7UUFDbkQsR0FBRyxDQUFDLE9BQU8sQ0FBQywwQkFBMEIsQ0FBQyxDQUFDO1FBQ3hDLElBQUksQ0FBQztZQUNILE1BQU0sVUFBVSxDQUFDLEtBQUssQ0FDcEI7Ozs7Ozs7Ozs7Ozs7OztFQWVOLENBQ0ssQ0FBQztZQUNGLE1BQU0sVUFBVSxDQUFDLEtBQUssQ0FDcEIsa0RBQWtELElBQUksR0FBRyxDQUMxRCxDQUFDO1lBQ0YsTUFBTSxVQUFVLENBQUMsS0FBSyxDQUFDOztTQUVwQixDQUFDLENBQUM7WUFDTCxHQUFHLENBQUMsSUFBSSxDQUFDLHlCQUF5QixDQUFDLENBQUM7UUFDdEMsQ0FBQztRQUFDLE9BQU8sQ0FBVSxFQUFFLENBQUM7WUFDcEIsTUFBTSxJQUFJLENBQUMsVUFBVSxDQUFDLENBQVUsQ0FBQyxDQUFDO1FBQ3BDLENBQUM7SUFDSCxDQUFDO0lBRUQsTUFBTSxDQUFDLEtBQUssQ0FBQyxjQUFjLENBQ3pCLFVBQXNCLEVBQ3RCLE1BQWMsRUFDZCxJQUFhO1FBRWIsSUFBSSxDQUFDO1lBQ0gsSUFBSSxJQUFJO2dCQUFFLE1BQU0sVUFBVSxDQUFDLEtBQUssQ0FBQyxpQkFBaUIsSUFBSSxXQUFXLENBQUMsQ0FBQztZQUNuRSxNQUFNLFVBQVUsQ0FBQyxLQUFLLENBQUMsaUJBQWlCLE1BQU0sRUFBRSxDQUFDLENBQUM7UUFDcEQsQ0FBQztRQUFDLE9BQU8sQ0FBVSxFQUFFLENBQUM7WUFDcEIsTUFBTSxJQUFJLENBQUMsVUFBVSxDQUFDLENBQVUsQ0FBQyxDQUFDO1FBQ3BDLENBQUM7SUFDSCxDQUFDO0lBRUQsTUFBTSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQ3JCLFVBQXNCLEVBQ3RCLE1BQWMsRUFDZCxJQUFZLEVBQ1osUUFBZ0I7UUFFaEIsSUFBSSxDQUFDO1lBQ0gsTUFBTSxVQUFVLENBQUMsS0FBSyxDQUFDLGVBQWUsSUFBSSxtQkFBbUIsUUFBUSxHQUFHLENBQUMsQ0FBQztZQUMxRSxNQUFNLFVBQVUsQ0FBQyxLQUFLLENBQUMsNkJBQTZCLE1BQU0sT0FBTyxJQUFJLEVBQUUsQ0FBQyxDQUFDO1lBRXpFLE1BQU0sVUFBVSxDQUFDLEtBQUssQ0FBQyxtQ0FBbUMsSUFBSSxFQUFFLENBQUMsQ0FBQztZQUNsRSxNQUFNLFVBQVUsQ0FBQyxLQUFLLENBQUMsb0NBQW9DLElBQUksRUFBRSxDQUFDLENBQUM7WUFDbkUsTUFBTSxVQUFVLENBQUMsS0FBSyxDQUNwQiwwREFBMEQsSUFBSSxFQUFFLENBQ2pFLENBQUM7WUFDRixNQUFNLFVBQVUsQ0FBQyxLQUFLLENBQ3BCLDZEQUE2RCxJQUFJLEVBQUUsQ0FDcEUsQ0FBQztZQUNGLE1BQU0sVUFBVSxDQUFDLEtBQUssQ0FDcEIsNkRBQTZELElBQUksRUFBRSxDQUNwRSxDQUFDO1lBQ0YsTUFBTSxVQUFVLENBQUMsS0FBSyxDQUNwQiwrRUFBK0UsSUFBSSxFQUFFLENBQ3RGLENBQUM7WUFDRixNQUFNLFVBQVUsQ0FBQyxLQUFLLENBQ3BCLGtGQUFrRixJQUFJLEVBQUUsQ0FDekYsQ0FBQztRQUNKLENBQUM7UUFBQyxPQUFPLENBQVUsRUFBRSxDQUFDO1lBQ3BCLE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFVLENBQUMsQ0FBQztRQUNwQyxDQUFDO0lBQ0gsQ0FBQztJQUVELE1BQU0sQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUNyQixNQUFrQixFQUNsQixJQUFZLEVBQ1osS0FBYTtRQUViLElBQUksQ0FBQztZQUNILE1BQU0sTUFBTSxDQUFDLEtBQUssQ0FBQyxxQkFBcUIsSUFBSSxPQUFPLEtBQUssRUFBRSxDQUFDLENBQUM7WUFDNUQsTUFBTSxNQUFNLENBQUMsS0FBSyxDQUNoQixrREFBa0QsSUFBSSxFQUFFLENBQ3pELENBQUM7WUFDRixNQUFNLE1BQU0sQ0FBQyxLQUFLLENBQUMsb0NBQW9DLElBQUksRUFBRSxDQUFDLENBQUM7WUFDL0QsTUFBTSxNQUFNLENBQUMsS0FBSyxDQUNoQixnRUFBZ0UsSUFBSSxFQUFFLENBQ3ZFLENBQUM7WUFDRixNQUFNLE1BQU0sQ0FBQyxLQUFLLENBQ2hCLGdFQUFnRSxJQUFJLEVBQUUsQ0FDdkUsQ0FBQztZQUNGLE1BQU0sTUFBTSxDQUFDLEtBQUssQ0FDaEIscUNBQXFDLEtBQUssK0NBQStDLElBQUksRUFBRSxDQUNoRyxDQUFDO1lBQ0YsTUFBTSxNQUFNLENBQUMsS0FBSyxDQUNoQixxQ0FBcUMsS0FBSyxrREFBa0QsSUFBSSxHQUFHLENBQ3BHLENBQUM7WUFDRixNQUFNLE1BQU0sQ0FBQyxLQUFLLENBQ2hCLHFDQUFxQyxLQUFLLGtEQUFrRCxJQUFJLEVBQUUsQ0FDbkcsQ0FBQztZQUNGLE1BQU0sTUFBTSxDQUFDLEtBQUssQ0FBQyxpQkFBaUIsSUFBSSxVQUFVLENBQUMsQ0FBQztZQUNwRCxNQUFNLE1BQU0sQ0FBQyxLQUFLLENBQUMsd0JBQXdCLElBQUksR0FBRyxDQUFDLENBQUM7UUFDdEQsQ0FBQztRQUFDLE9BQU8sQ0FBVSxFQUFFLENBQUM7WUFDcEIsTUFBTSxJQUFJLENBQUMsVUFBVSxDQUFDLENBQVUsQ0FBQyxDQUFDO1FBQ3BDLENBQUM7SUFDSCxDQUFDO0lBRU8sTUFBTSxDQUFDLG1CQUFtQixDQUNoQyxJQUFZLEVBQ1osSUFBYSxFQUNiLElBQUksR0FBRyxLQUFLO1FBRVosUUFBUSxJQUFJLENBQUMsV0FBVyxFQUFFLEVBQUUsQ0FBQztZQUMzQixLQUFLLFFBQVE7Z0JBQ1gsT0FBTyxJQUFJLENBQUMsQ0FBQyxDQUFDLGtCQUFrQixDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO1lBQy9ELEtBQUssUUFBUTtnQkFDWCxPQUFPLElBQUksQ0FBQyxDQUFDLENBQUMsb0JBQW9CLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztZQUNqRCxLQUFLLFNBQVM7Z0JBQ1osT0FBTyxTQUFTLENBQUM7WUFDbkIsS0FBSyxNQUFNO2dCQUNULE9BQU8sV0FBVyxDQUFDO1lBQ3JCLEtBQUssUUFBUTtnQkFDWCxPQUFPLElBQUksQ0FBQyxDQUFDLENBQUMsb0JBQW9CLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQztZQUNoRCxPQUFPLENBQUMsQ0FBQyxDQUFDO2dCQUNSLE1BQU0sQ0FBQyxHQUFHLDRCQUFLLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUMxQixJQUFJLENBQUMsRUFBRSxDQUFDO29CQUNOLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUM7b0JBQ25CLE1BQU0sSUFBSSxHQUFHLHVCQUFVLENBQUMsb0JBQW9CLENBQzFDLEVBQUUsRUFDRixJQUFBLDhCQUFjLEVBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUN0QixDQUFDO29CQUNGLE9BQU87d0JBQ0wsS0FBSyxFQUFFLENBQUM7d0JBQ1IsTUFBTSxFQUFFLElBQUk7cUJBQ2IsQ0FBQztnQkFDSixDQUFDO2dCQUNELE1BQU0sSUFBSSw2QkFBYSxDQUFDLHFCQUFxQixJQUFJLEVBQUUsQ0FBQyxDQUFDO1lBQ3ZELENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztJQUVPLE1BQU0sQ0FBQyx5QkFBeUIsQ0FDdEMsSUFBWSxFQUNaLElBQVksRUFDWixJQUFhLEVBQ2IsR0FBVyxFQUNYLE9BQXlCO1FBRXpCLFFBQVEsR0FBRyxFQUFFLENBQUM7WUFDWixLQUFLLHFDQUFjLENBQUMsUUFBUTtnQkFDMUIsT0FBTyxVQUFVLENBQUM7WUFDcEIsS0FBSyxxQ0FBYyxDQUFDLFVBQVU7Z0JBQzVCLElBQUksSUFBSSxJQUFJLENBQUMsT0FBTyxJQUFJLElBQUksQ0FBQyxXQUFXLEVBQUUsS0FBSyxRQUFRLEVBQUUsQ0FBQztvQkFDeEQsT0FBTyxFQUFFLENBQUM7Z0JBQ1osQ0FBQztnQkFDRCxPQUFPLElBQUssT0FBcUMsQ0FBQyxxQ0FBYyxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUM7WUFDbEYsS0FBSyxxQ0FBYyxDQUFDLFVBQVU7Z0JBQzVCLE9BQU8sY0FBYyxJQUFJLG1DQUFtQyxJQUFJLFFBQVMsT0FBcUMsQ0FBQyxxQ0FBYyxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUM7WUFDL0ksS0FBSyxxQ0FBYyxDQUFDLE9BQU8sQ0FBQztZQUM1QixLQUFLLHFDQUFjLENBQUMsR0FBRyxDQUFDO1lBQ3hCLEtBQUsscUNBQWMsQ0FBQyxLQUFLO2dCQUN2QixPQUFPLGNBQWMsSUFBSSx5QkFBeUIsSUFBSSxPQUFPLElBQUEsZ0NBQXdCLEVBQUUsT0FBbUMsQ0FBQyxxQ0FBYyxDQUFDLE9BQU8sQ0FBVyxDQUFDLElBQUksQ0FBQztZQUNwSyxLQUFLLHFDQUFjLENBQUMsSUFBSSxDQUFDO1lBQ3pCLEtBQUsscUNBQWMsQ0FBQyxJQUFJO2dCQUN0QixPQUFPLEVBQUUsQ0FBQztZQUNaLEtBQUsscUNBQWMsQ0FBQyxHQUFHO2dCQUNyQixPQUFPLGNBQWMsSUFBSSxJQUFJLEdBQUcsaUJBQWlCLElBQUksT0FBUSxPQUErQixDQUFDLHFDQUFjLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQztZQUN0SCxLQUFLLHFDQUFjLENBQUMsR0FBRztnQkFDckIsT0FBTyxjQUFjLElBQUksSUFBSSxHQUFHLGlCQUFpQixJQUFJLE9BQVEsT0FBK0IsQ0FBQyxxQ0FBYyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUM7WUFDdEgsS0FBSyxxQ0FBYyxDQUFDLFFBQVEsQ0FBQztZQUM3QjtnQkFDRSxNQUFNLElBQUksNkJBQWEsQ0FBQyxxQkFBcUIsR0FBRyxFQUFFLENBQUMsQ0FBQztRQUN4RCxDQUFDO0lBQ0gsQ0FBQztJQUVPLE1BQU0sQ0FBQyx3QkFBd0IsQ0FDckMsSUFBWSxFQUNaLEtBQXlCLEVBQ3pCLEVBQVUsRUFDVixHQUFvQixFQUNwQixPQUEwQjtRQUUxQixNQUFNLFNBQVMsR0FBRyxpQkFBVSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUMxQyxNQUFNLEVBQUUsT0FBTyxFQUFFLEdBQUcsT0FBTyxDQUFDO1FBQzVCLE1BQU0sVUFBVSxHQUFHLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsb0JBQW9CLENBQUMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUM7UUFDaEgsUUFBUSxZQUFZLEdBQUcsRUFBRSxFQUFFLENBQUM7WUFDMUIsS0FBSyxzQkFBZSxDQUFDLFVBQVU7Z0JBQzdCLE9BQU8sZ0JBQWdCLElBQUksZ0JBQWdCLFNBQVMsSUFBSSxFQUFFLElBQUksVUFBVSxFQUFFLENBQUM7WUFDN0U7Z0JBQ0UsTUFBTSxJQUFJLDZCQUFhLENBQUMsMEJBQTBCLEdBQUcsRUFBRSxDQUFDLENBQUM7UUFDN0QsQ0FBQztJQUNILENBQUM7SUFFRCxNQUFNLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FDdEIsTUFBa0IsRUFDbEIsS0FBcUI7UUFFckIsTUFBTSxNQUFNLEdBQXFDLEVBQUUsQ0FBQztRQUNwRCxNQUFNLENBQUMsR0FBRyxJQUFJLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUN4QixNQUFNLFNBQVMsR0FBRyxpQkFBVSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUMxQyxNQUFNLEVBQUUsRUFBRSxFQUFFLEdBQUcsSUFBQSw4QkFBYyxFQUFDLENBQUMsQ0FBQyxDQUFDO1FBRWpDLElBQUksSUFBYSxFQUFFLE1BQWMsQ0FBQztRQUNsQyxNQUFNLFVBQVUsR0FBRyxNQUFNLENBQUMsbUJBQW1CLENBQUMsQ0FBQyxDQUFnQixDQUFDO1FBQ2hFLEtBQUssTUFBTSxJQUFJLElBQUksVUFBVSxFQUFFLENBQUM7WUFDOUIsSUFDRSxPQUFRLElBQVksQ0FBQyxJQUFJLENBQUMsS0FBSyxVQUFVO2dCQUN6QyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQztnQkFDL0IsSUFBSSxLQUFLLGFBQWEsRUFDdEIsQ0FBQztnQkFDRCxTQUFTO1lBQ1gsQ0FBQztZQUVELElBQUksR0FBRyxJQUFJLEtBQUssRUFBRSxDQUFDO1lBQ25CLE1BQU0sR0FBRyxpQkFBVSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUM7WUFFL0MsTUFBTSxPQUFPLEdBQUcsdUJBQVUsQ0FBQyxxQkFBcUIsQ0FDOUMscUNBQWMsQ0FBQyxPQUFPLEVBQ3RCLENBQUMsRUFDRCxJQUFJLENBQUMsUUFBUSxFQUFFLEVBQ2YsS0FBSyxFQUNMLElBQUksQ0FDTCxDQUFDO1lBRUYsTUFBTSxhQUFhLEdBQUcsT0FBTyxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQzdDLENBQUMsS0FBMEIsRUFBRSxFQUFFLEVBQUUsRUFBRTtnQkFDakMsTUFBTSxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFFLENBQUM7Z0JBQzFCLElBQUksR0FBRyxLQUFLLGdDQUFTLENBQUMsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLHFDQUFjLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztvQkFDMUQsS0FBSyxDQUFDLHFDQUFjLENBQUMsSUFBSSxDQUFDLEdBQUc7d0JBQzNCLFdBQVcsRUFBRSxDQUFDLEtBQUssQ0FBQyxJQUFjLENBQUM7d0JBQ25DLE9BQU8sRUFBRSw2Q0FBc0IsQ0FBQyxJQUFJO3dCQUNwQyxXQUFXLEVBQUUsOENBQThDO3FCQUM1RCxDQUFDO2dCQUNKLENBQUM7cUJBQU0sSUFBSSxHQUFHLEtBQUsscUNBQWMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztvQkFDdkMsNERBQTREO29CQUM1RCxLQUFLLENBQUMsR0FBRyxDQUFDLEdBQUcsS0FBSyxDQUFDO2dCQUNyQixDQUFDO2dCQUNELE9BQU8sS0FBSyxDQUFDO1lBQ2YsQ0FBQyxFQUNELEVBQUUsQ0FDSCxDQUFDO1lBRUYsTUFBTSxNQUFNLEdBQUcsdUJBQVUsQ0FBQyxxQkFBcUIsQ0FDN0MsaUJBQVUsQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLEVBQzNCLENBQUMsRUFDRCxJQUFJLENBQUMsUUFBUSxFQUFFLEVBQ2YsSUFBSSxFQUNKLElBQUksQ0FDTCxDQUFDO1lBRUYsTUFBTSxLQUFLLEdBQWEsRUFBRSxDQUFDO1lBQzNCLE1BQU0sV0FBVyxHQUFhLEVBQUUsQ0FBQztZQUNqQyxNQUFNLFdBQVcsR0FBYSxFQUFFLENBQUM7WUFDakMsSUFBSSxRQUFRLEdBQTZCLFNBQVMsQ0FBQztZQUNuRCxJQUFJLFVBQVUsR0FBbUMsU0FBUyxDQUFDO1lBQzNELElBQUksT0FBWSxDQUFDO1lBRWpCLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQztnQkFDdEMsUUFBUSxHQUFHLGFBQWEsQ0FBQyxxQ0FBYyxDQUFDLElBQUksQ0FBaUIsQ0FBQztnQkFFOUQsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO29CQUNkLE1BQU0sSUFBSSxLQUFLLENBQUMsMEJBQTBCLENBQUMsQ0FBQztnQkFDOUMsQ0FBQztnQkFFRCxJQUFJLFVBQVUsR0FHWixJQUFJLENBQUMsbUJBQW1CLENBQ3RCLE9BQVEsUUFBUSxDQUFDLFdBQXFCLENBQUMsQ0FBQyxDQUFDLEtBQUssVUFBVTtvQkFDdEQsQ0FBQyxDQUFFLFFBQVEsQ0FBQyxXQUFtQixDQUFDLENBQUMsQ0FBQyxFQUFFO29CQUNwQyxDQUFDLENBQUUsUUFBUSxDQUFDLFdBQW1CLENBQUMsQ0FBQyxDQUFDLEVBQ3BDLElBQUksQ0FDTCxDQUFDO2dCQUNKLElBQUksT0FBTyxVQUFVLEtBQUssUUFBUSxFQUFFLENBQUM7b0JBQ25DLFVBQVUsR0FBRyxFQUFFLEtBQUssRUFBRSxVQUFVLEVBQUUsQ0FBQztnQkFDckMsQ0FBQztnQkFDRCxJQUFJLE9BQU8sR0FHVCxVQUFVLENBQUMsS0FFZ0QsQ0FBQztnQkFFOUQsSUFBSSxPQUFPLE9BQU8sS0FBSyxRQUFRLEVBQUUsQ0FBQztvQkFDaEMsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7d0JBQzNCLE9BQU8sQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUM7b0JBQ3ZCLENBQUM7b0JBRUQsWUFBWTtvQkFDWix3RkFBd0Y7b0JBQ3hGLElBQUksQ0FBQzt3QkFDSCxVQUFVLEdBQUcsVUFBVSxDQUFDLEtBQTJCLENBQUM7d0JBQ3BELE1BQU0sQ0FBQyxHQUFHLElBQUksVUFBVSxFQUFFLENBQUM7d0JBQzNCLE9BQU8sR0FBRyxJQUFBLDhCQUFjLEVBQUMsQ0FBQyxDQUFDLENBQUM7d0JBQzVCLE9BQU8sR0FBRyxJQUFJLENBQUMsbUJBQW1CLENBQ2hDLFVBQVUsQ0FBQyxNQUFnQixFQUMzQixLQUFLLEVBQ0wsSUFBSSxDQUNMLENBQUM7d0JBQ0YsTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDLE1BQU0sRUFBRSxVQUFVLENBQUMsQ0FBQztvQkFDN0MsQ0FBQztvQkFBQyxPQUFPLENBQVUsRUFBRSxDQUFDO3dCQUNwQixJQUFJLENBQUMsQ0FBQyxDQUFDLFlBQVksNkJBQWEsQ0FBQzs0QkFBRSxNQUFNLENBQUMsQ0FBQztvQkFDN0MsQ0FBQztnQkFDSCxDQUFDO2dCQUVELElBQUksRUFBRSxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQztvQkFDMUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDO29CQUN6QixDQUFDLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQztnQkFDekIsRUFBRSxHQUFHLE9BQU8sRUFBRSxLQUFLLFVBQVUsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7Z0JBQ3RELE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyx5QkFBeUIsQ0FDbEQsTUFBTSxFQUNOLEVBQVMsRUFDVCxJQUFJLEVBQ0oscUNBQWMsQ0FBQyxVQUFVLEVBQ3hCLGFBQWEsQ0FDWixxQ0FBYyxDQUFDLFVBQVUsQ0FDSSxJQUFJO29CQUNqQyxDQUFDLHFDQUFjLENBQUMsVUFBVSxDQUFDLEVBQUUsR0FBRztpQkFDakMsQ0FDRixDQUFDO2dCQUVGLE1BQU0sQ0FBQyxHQUFHLEdBQUcsTUFBTSxJQUFJLE9BQU8sR0FBRyxhQUFhLEVBQUUsQ0FBQztnQkFFakQsSUFBSSxJQUFJLEVBQUUsQ0FBQztvQkFDVCxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUNuQixDQUFDO3FCQUFNLENBQUM7b0JBQ04sS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDaEIsQ0FBQztnQkFFRCxLQUFLLE1BQU0sQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLElBQUksTUFBTSxDQUFDLE9BQU8sQ0FBQyxhQUFhLENBQUMsQ0FBQyxNQUFNLENBQzdELENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQ04sQ0FBQyxDQUFDLHFDQUFjLENBQUMsSUFBSSxFQUFFLHFDQUFjLENBQUMsVUFBVSxDQUFDLENBQUMsUUFBUSxDQUFDLENBQVEsQ0FBQyxDQUN2RSxFQUFFLENBQUM7b0JBQ0YsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLHlCQUF5QixDQUMvQyxNQUFNLEVBQ04sRUFBUyxFQUNULElBQUksRUFDSixHQUFHLEVBQ0gsS0FBSyxDQUNOLENBQUM7b0JBQ0YsSUFBSSxVQUFVLENBQUMsVUFBVSxDQUFDLFlBQVksQ0FBQyxFQUFFLENBQUM7d0JBQ3hDLFdBQVcsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7b0JBQy9CLENBQUM7eUJBQU0sQ0FBQzt3QkFDTixJQUFJLFVBQVUsRUFBRSxDQUFDOzRCQUNmLEtBQUssQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7d0JBQ3pCLENBQUM7b0JBQ0gsQ0FBQztnQkFDSCxDQUFDO1lBQ0gsQ0FBQztZQUVELG9EQUFvRDtZQUNwRCx5REFBeUQ7WUFDekQsSUFBSSxLQUFLLElBQUksQ0FBQyxNQUFNLElBQUksTUFBTSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDO2dCQUNsRCxJQUFJLENBQUMsUUFBUTtvQkFBRSxNQUFNLElBQUksS0FBSyxDQUFDLDBCQUEwQixDQUFDLENBQUM7Z0JBQzNELEtBQUssTUFBTSxTQUFTLElBQUksTUFBTSxDQUFDLFVBQVUsRUFBRSxDQUFDO29CQUMxQyxNQUFNLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxHQUFHLFNBQVMsQ0FBQztvQkFDakMsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLHdCQUF3QixDQUM5QyxNQUFNLEVBQ04sVUFBZ0MsRUFDaEMsT0FBTyxDQUFDLEVBQUUsRUFDVixHQUFzQixFQUN0QixLQUFxQyxDQUN0QyxDQUFDO29CQUNGLElBQUksVUFBVSxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO3dCQUNyQyxXQUFXLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO29CQUMvQixDQUFDO3lCQUFNLENBQUM7d0JBQ04sTUFBTSxJQUFJLDZCQUFhLENBQUMseUJBQXlCLEdBQUcsRUFBRSxDQUFDLENBQUM7b0JBQzFELENBQUM7Z0JBQ0gsQ0FBQztZQUNILENBQUM7WUFFRCxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDLEdBQUc7Z0JBQ3hCLEtBQUssRUFBRSxLQUFLLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQztnQkFDdEIsTUFBTSxFQUFFLEVBQUU7Z0JBQ1YsVUFBVSxFQUFFLElBQUk7Z0JBQ2hCLFdBQVcsRUFBRSxXQUFXO2dCQUN4QixXQUFXLEVBQUUsV0FBVzthQUN6QixDQUFDO1FBQ0osQ0FBQztRQUVELE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDckMsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNyRCxNQUFNLFdBQVcsR0FBRyxNQUFNO2FBQ3ZCLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDO2FBQ3JDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQzthQUN6QixJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDZixNQUFNLFdBQVcsR0FBRyxNQUFNO2FBQ3ZCLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDO2FBQ3JDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQzthQUN6QixJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDZixNQUFNLElBQUksR0FBRyxDQUFDLEtBQUssRUFBRSxXQUFXLENBQUMsQ0FBQztRQUNsQyxJQUFJLFdBQVcsRUFBRSxDQUFDO1lBQ2hCLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDekIsQ0FBQztRQUNELE1BQU0sV0FBVyxHQUFHLGdCQUFnQixTQUFTLEtBQUssSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDO1FBQ3pGLElBQUksQ0FBQztZQUNILE1BQU0sTUFBTSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsQ0FBQztZQUNoQyxNQUFNLE1BQU0sQ0FBQyxLQUFLLENBQ2hCLGlDQUFpQyxTQUFTO3NDQUNaLFNBQVM7OzZDQUVGLENBQ3RDLENBQUM7UUFDSixDQUFDO1FBQUMsT0FBTyxDQUFVLEVBQUUsQ0FBQztZQUNwQixNQUFNLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBVSxDQUFDLENBQUM7UUFDcEMsQ0FBQztRQUNELE9BQU8sTUFBTSxDQUFDO0lBQ2hCLENBQUM7SUFFRCxNQUFNLENBQUMsS0FBSyxDQUFDLGNBQWMsQ0FBQyxNQUFrQjtRQUM1QyxNQUFNLFdBQVcsR0FBRyxzQkFBc0IsQ0FBQztRQUMzQyxJQUFJLENBQUM7WUFDSCxNQUFNLE1BQU0sR0FBRyxNQUFNLE1BQU0sQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLENBQUM7WUFDL0MsT0FBTyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDO1FBQ2hDLENBQUM7UUFBQyxPQUFPLENBQVUsRUFBRSxDQUFDO1lBQ3BCLE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFVLENBQUMsQ0FBQztRQUNwQyxDQUFDO0lBQ0gsQ0FBQztJQUVELE1BQU0sQ0FBQyxVQUFVO1FBQ2Ysd0JBQXdCO1FBQ3hCLE1BQU0sUUFBUSxHQUFHLGNBQU8sQ0FBQyxHQUFHLENBQUMsc0JBQWUsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNwRCxpQ0FBVSxDQUFDLFdBQVcsQ0FBQywwQkFBYyxDQUFDO2FBQ25DLEdBQUcsQ0FBQyxRQUFRLENBQUM7YUFDYixNQUFNLENBQUMsQ0FBQyxRQUFhLEVBQUUsRUFBRSxDQUN4QixJQUFBLGVBQU0sR0FBRSxDQUFDLFFBQVEsQ0FBQyxnQ0FBUyxDQUFDLE1BQU0sQ0FBQyxJQUFJLFFBQVEsQ0FBQyxDQUNqRDthQUNBLEtBQUssRUFBRSxDQUFDO1FBRVgsd0RBQXdEO1FBQ3hELE1BQU0sS0FBSyxHQUFHLGlCQUFVLENBQUMsR0FBRyxDQUFDLHNCQUFNLENBQUMsRUFBRSxDQUFDLENBQUM7UUFFeEMsU0FBUyxLQUFLLENBQUMsT0FBd0I7WUFDckMsTUFBTSxVQUFVLEdBQVU7Z0JBQ3hCLElBQUEsK0JBQVEsR0FBRTtnQkFDVixJQUFBLHdCQUFRLEdBQUU7Z0JBQ1YsSUFBQSxtQ0FBWSxFQUFDLEtBQUssRUFBRSxPQUFPLENBQUM7YUFDN0IsQ0FBQztZQUNGLElBQUksT0FBTyxDQUFDLElBQUk7Z0JBQUUsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFBLCtDQUFzQixHQUFFLENBQUMsQ0FBQzs7Z0JBQ3ZELFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBQSw2QkFBYSxFQUFDLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQztZQUN0RCxPQUFPLElBQUEsa0JBQUssRUFBQyxHQUFHLFVBQVUsQ0FBQyxDQUFDO1FBQzlCLENBQUM7UUFFRCxpQ0FBVSxDQUFDLFdBQVcsQ0FBQywwQkFBYyxDQUFDO2FBQ25DLEdBQUcsQ0FBQyxLQUFLLENBQUM7YUFDVixNQUFNLENBQUM7WUFDTixTQUFTLEVBQUUsS0FBSztTQUNqQixDQUFDO2FBQ0QsS0FBSyxFQUFFLENBQUM7UUFFWCx5REFBeUQ7UUFDekQsTUFBTSxTQUFTLEdBQUcsY0FBTyxDQUFDLEdBQUcsQ0FBQyxzQkFBZSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3RELGlDQUFVLENBQUMsV0FBVyxDQUFDLDBCQUFjLENBQUM7YUFDbkMsR0FBRyxDQUFDLFNBQVMsQ0FBQzthQUNkLE1BQU0sQ0FBQztZQUNOLFNBQVMsRUFBRSxTQUFTLE1BQU0sQ0FBQyxJQUFZO2dCQUNyQyxPQUFPLFNBQVMsTUFBTSxDQUFDLEdBQVEsRUFBRSxJQUFTO29CQUN4QyxPQUFPLElBQUEsZUFBTSxFQUFDO3dCQUNaLElBQUksRUFBRSxJQUFJLElBQUksSUFBSTt3QkFDbEIsUUFBUSxFQUFFLElBQUk7cUJBQ2YsQ0FBQyxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQztnQkFDaEIsQ0FBQyxDQUFDO1lBQ0osQ0FBQztZQUNELFNBQVMsRUFBRSxDQUFDLElBQVcsRUFBRSxFQUFFO2dCQUN6QixNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQzNCLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUN0QixDQUFDO1NBQ0YsQ0FBQzthQUNELEtBQUssRUFBRSxDQUFDO1FBRVgscUNBQXFDO1FBQ3JDLE1BQU0sU0FBUyxHQUFHLGNBQU8sQ0FBQyxHQUFHLENBQUMsc0JBQWUsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUN0RCxpQ0FBVSxDQUFDLFdBQVcsQ0FBQywwQkFBYyxDQUFDO2FBQ25DLEdBQUcsQ0FBQyxTQUFTLENBQUM7YUFDZCxNQUFNLENBQUMsSUFBQSxtQ0FBWSxFQUFDLFNBQVMsRUFBRSxFQUFFLENBQUMsQ0FBQzthQUNuQyxNQUFNLENBQUMsSUFBQSxlQUFNLEVBQUMsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQzthQUNoQyxLQUFLLEVBQUUsQ0FBQztRQUVYLDRDQUE0QztRQUM1QyxNQUFNLFdBQVcsR0FBRyxpQ0FBVSxDQUFDLEdBQUcsQ0FBQyxxQ0FBYyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQzVELGlDQUFVLENBQUMsV0FBVyxDQUFDLDBCQUFjLENBQUM7YUFDbkMsR0FBRyxDQUFDLFdBQVcsQ0FBQzthQUNoQixNQUFNLENBQUMsSUFBQSxlQUFNLEVBQUMsRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQzthQUNuQyxLQUFLLEVBQUUsQ0FBQztRQUVYLCtCQUErQjtRQUMvQixNQUFNLFVBQVUsR0FBRyxpQkFBVSxDQUFDLEdBQUcsQ0FBQyxzQkFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ2xELGlDQUFVLENBQUMsV0FBVyxDQUFDLDBCQUFjLENBQUM7YUFDbkMsR0FBRyxDQUFDLFVBQVUsQ0FBQzthQUNmLE1BQU0sQ0FBQyxJQUFBLDJCQUFJLEVBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxFQUFFLElBQUEsdUJBQWEsR0FBRSxDQUFDO2FBQzFDLEtBQUssRUFBRSxDQUFDO1FBRVgsU0FBUyxtQkFBbUIsQ0FBQyxHQUFXO1lBQ3RDLE9BQU8sb0NBQW9CLENBQUMsT0FBTyxHQUFHLEdBQUcsQ0FBQztRQUM1QyxDQUFDO1FBRUQsK0RBQStEO1FBQy9ELE1BQU0sWUFBWSxHQUFHLG1CQUFtQixDQUFDLHNCQUFNLENBQUMsU0FBUyxDQUFDLENBQUM7UUFFM0QsU0FBUyxFQUFFLENBQUMsU0FBMEIsRUFBRSxNQUFjO1lBQ3BELE1BQU0sVUFBVSxHQUFVO2dCQUN4QixJQUFBLDJCQUFJLEVBQUMsTUFBTSxFQUFFLHNDQUF5QixDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUM7Z0JBQ3RELElBQUEsK0JBQVEsRUFBQyxzQ0FBeUIsQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDO2dCQUN0RCxJQUFBLG1DQUFZLEVBQUMsaUNBQVUsQ0FBQyxHQUFHLENBQUMsc0JBQU0sQ0FBQyxTQUFTLENBQUMsRUFBRTtvQkFDN0MsU0FBUyxFQUFFLFNBQVM7b0JBQ3BCLE1BQU0sRUFBRSxNQUFNO2lCQUNmLENBQUM7YUFDSCxDQUFDO1lBQ0YsSUFBSSxTQUFTLENBQUMsT0FBTyxDQUFDLDZCQUFhLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUNoRCxVQUFVLENBQUMsSUFBSSxDQUNiLElBQUEsbUNBQVksRUFBQyxZQUFZLEVBQUU7b0JBQ3pCLE9BQU8sRUFBRSxzQ0FBeUIsQ0FBQyxTQUFTLENBQUMsT0FBTztpQkFDckQsQ0FBQyxDQUNILENBQUM7O2dCQUNDLFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBQSx3QkFBUSxHQUFFLENBQUMsQ0FBQztZQUNqQyxPQUFPLElBQUEsa0JBQUssRUFBQyxHQUFHLFVBQVUsQ0FBQyxDQUFDO1FBQzlCLENBQUM7UUFFRCxpQ0FBVSxDQUFDLFdBQVcsQ0FBQywwQkFBYyxDQUFDO2FBQ25DLEdBQUcsQ0FBQyxZQUFZLENBQUM7YUFDakIsTUFBTSxDQUFDO1lBQ04sU0FBUyxFQUFFLEVBQUU7U0FDZCxDQUFDO2FBQ0QsTUFBTSxDQUFDO1lBQ04sU0FBUyxFQUFFLFNBQVMsU0FBUyxDQUFDLEdBQUcsR0FBb0I7Z0JBQ25ELE9BQU8sU0FBUyxTQUFTLENBQUMsR0FBUSxFQUFFLElBQVM7b0JBQzNDLElBQUksR0FBRyxDQUFDLE9BQU8sQ0FBQyw2QkFBYSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQzt3QkFDMUMsT0FBTyxJQUFBLG1DQUFnQixHQUFFLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDO29CQUN2QyxPQUFPLElBQUEsbUNBQWdCLEdBQUUsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLENBQUM7Z0JBQ3ZDLENBQUMsQ0FBQztZQUNKLENBQUM7WUFDRCxTQUFTLEVBQUUsQ0FBQyxJQUFXLEVBQUUsRUFBRTtnQkFDekIsT0FBTyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDakIsQ0FBQztTQUNGLENBQUM7YUFDRCxLQUFLLEVBQUUsQ0FBQztRQUVYLDZDQUE2QztRQUM3QyxNQUFNLFdBQVcsR0FBRyxpQkFBVSxDQUFDLEdBQUcsQ0FBQyxzQkFBZSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQy9ELGlDQUFVLENBQUMsV0FBVyxDQUFDLDBCQUFjLENBQUM7YUFDbkMsR0FBRyxDQUFDLFdBQVcsQ0FBQzthQUNoQixNQUFNLENBQUM7WUFDTixTQUFTLEVBQUUsU0FBUyxRQUFRLENBQzFCLEtBQWtELEVBQ2xELE9BQXdCLEVBQ3hCLFFBQWlCO2dCQUVqQixNQUFNLFFBQVEsR0FBc0I7b0JBQ2xDLEtBQUssRUFBRSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBVztvQkFDbEQsT0FBTyxFQUFFLE9BQU87b0JBQ2hCLFFBQVEsRUFBRSxRQUFRO2lCQUNuQixDQUFDO2dCQUNGLE1BQU0sT0FBTyxHQUFvQjtvQkFDL0IsT0FBTyxFQUNMLE9BQU8sQ0FBQyxNQUFNLEtBQUssY0FBTyxDQUFDLE9BQU87d0JBQ2xDLE9BQU8sQ0FBQyxNQUFNLEtBQUssY0FBTyxDQUFDLE9BQU87b0JBQ3BDLFFBQVEsRUFBRSxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLFNBQVM7b0JBQ2hELFFBQVEsRUFBRSxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLFNBQVM7b0JBQ2hELFFBQVEsRUFBRSxJQUFJO29CQUNkLEtBQUssRUFBRSxRQUFRO2lCQUNoQixDQUFDO2dCQUNGLE9BQU8sSUFBQSxrQkFBSyxFQUNWLElBQUEsMkJBQUksRUFBQyxzQkFBZSxDQUFDLFNBQVMsQ0FBQyxFQUMvQixJQUFBLDJCQUFJLEVBQUM7b0JBQ0gsQ0FBQyxPQUFPLEtBQUssS0FBSyxVQUFVLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSTt3QkFDekMsQ0FBQyxDQUFDLEtBQUs7d0JBQ1AsQ0FBQyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQVE7b0JBQ3RCLE1BQU0sQ0FBQyxJQUFJO29CQUNYLE1BQU0sQ0FBQyxJQUFJO29CQUNYLE1BQU0sQ0FBQyxJQUFJO2lCQUNaLENBQUMsRUFDRixJQUFBLG1DQUFZLEVBQUMsV0FBVyxFQUFFLFFBQVEsQ0FBQyxFQUNuQyxJQUFBLGtCQUFRLEVBQ04sR0FBRyxFQUFFO29CQUNILElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSTt3QkFBRSxLQUFLLEdBQUksS0FBYSxFQUFFLENBQUM7b0JBQzFDLElBQUksQ0FBQyxLQUFLLENBQUMsZ0NBQVMsQ0FBQyxNQUE0QixDQUFDO3dCQUNoRCxNQUFNLElBQUksNkJBQWEsQ0FDckIseUNBQXlDLENBQzFDLENBQUM7b0JBQ0osT0FBTyxLQUFLLENBQUMsZ0NBQVMsQ0FBQyxNQUE0QixDQUFDLENBQUM7Z0JBQ3ZELENBQUMsRUFDRCxDQUFDLEtBQVUsRUFBRSxFQUFFO29CQUNiLE1BQU0sRUFBRSxHQUFHLElBQUEsOEJBQWMsRUFBQyxJQUFLLEtBQTBCLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQztvQkFDaEUsT0FBTyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUM7Z0JBQ25CLENBQUMsRUFDRCxPQUFPLENBQ1IsRUFDRCxJQUFBLG9CQUFVLEdBQUUsQ0FDYixDQUFDO1lBQ0osQ0FBQztTQUNGLENBQUM7YUFDRCxLQUFLLEVBQUUsQ0FBQztRQUVYLCtDQUErQztRQUMvQyxNQUFNLFlBQVksR0FBRyxpQkFBVSxDQUFDLEdBQUcsQ0FBQyxzQkFBZSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQ2pFLGlDQUFVLENBQUMsV0FBVyxDQUFDLDBCQUFjLENBQUM7YUFDbkMsR0FBRyxDQUFDLFlBQVksQ0FBQzthQUNqQixNQUFNLENBQUM7WUFDTixTQUFTLEVBQUUsU0FBUyxTQUFTLENBQzNCLEtBQWtELEVBQ2xELE9BQXdCLEVBQ3hCLFFBQWlCO2dCQUVqQixNQUFNLFFBQVEsR0FBc0I7b0JBQ2xDLEtBQUssRUFBRSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBVztvQkFDbEQsT0FBTyxFQUFFLE9BQU87b0JBQ2hCLFFBQVEsRUFBRSxRQUFRO2lCQUNuQixDQUFDO2dCQUNGLE9BQU8sSUFBQSxrQkFBSyxFQUNWLElBQUEsMkJBQUksRUFBQyxzQkFBZSxDQUFDLFNBQVMsQ0FBQyxFQUMvQixJQUFBLDJCQUFJLEVBQUMsS0FBSyxDQUFDLEVBQ1gsSUFBQSxtQ0FBWSxFQUFDLFlBQVksRUFBRSxRQUFRLENBQUMsRUFDcEMsU0FBUyxnQkFBZ0IsQ0FBQyxHQUFRLEVBQUUsSUFBUztvQkFDM0MsTUFBTSxPQUFPLEdBQW9CO3dCQUMvQixPQUFPLEVBQ0wsT0FBTyxDQUFDLE1BQU0sS0FBSyxjQUFPLENBQUMsT0FBTzs0QkFDbEMsT0FBTyxDQUFDLE1BQU0sS0FBSyxjQUFPLENBQUMsT0FBTzt3QkFDcEMsUUFBUSxFQUFFLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsU0FBUzt3QkFDaEQsUUFBUSxFQUFFLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsU0FBUzt3QkFDaEQsUUFBUSxFQUFFLElBQUk7d0JBQ2QsS0FBSyxFQUFFLFFBQVE7cUJBQ2hCLENBQUM7b0JBQ0YsT0FBTyxJQUFBLG1CQUFTLEVBQ2QsR0FBRyxFQUFFO3dCQUNILElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSTs0QkFBRSxLQUFLLEdBQUksS0FBYSxFQUFFLENBQUM7d0JBQzFDLElBQUksQ0FBQyxLQUFLLENBQUMsZ0NBQVMsQ0FBQyxNQUE0QixDQUFDOzRCQUNoRCxNQUFNLElBQUksNkJBQWEsQ0FDckIseUNBQXlDLENBQzFDLENBQUM7d0JBQ0osT0FBTyxLQUFLLENBQUMsZ0NBQVMsQ0FBQyxNQUE0QixDQUFDLENBQUM7b0JBQ3ZELENBQUMsRUFDRCxDQUFDLEtBQVUsRUFBRSxFQUFFO3dCQUNiLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSTs0QkFBRSxLQUFLLEdBQUksS0FBYSxFQUFFLENBQUM7d0JBQzFDLE1BQU0sQ0FBQyxHQUFHLElBQUssS0FBMEIsRUFBRSxDQUFDO3dCQUM1QyxNQUFNLGdCQUFnQixHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUU7NEJBQ2pELE1BQU0sSUFBSSxHQUFHLHVCQUFVLENBQUMscUJBQXFCLENBQzNDLGlCQUFVLENBQUMsR0FBRyxDQUFDLHNCQUFlLENBQUMsV0FBVyxDQUFDLEVBQzNDLENBQUMsRUFDRCxDQUFDLEVBQ0QsSUFBSSxDQUNMLENBQUM7NEJBQ0YsSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU07Z0NBQ3RELE9BQU8sS0FBSyxDQUFDOzRCQUNmLE1BQU0sVUFBVSxHQUFHLE9BQU8sQ0FBQyxXQUFXLENBQ3BDLGdDQUFTLENBQUMsSUFBSSxFQUNkLENBQUMsRUFDRCxDQUFDLENBQ0YsQ0FBQzs0QkFDRixJQUFJLENBQUMsVUFBVTtnQ0FDYixNQUFNLElBQUksNkJBQWEsQ0FDckIsZ0NBQWdDLENBQUMsT0FBTyxDQUFDLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRSxDQUM3RCxDQUFDOzRCQUNKLE9BQU8sVUFBVSxDQUFDLElBQUksS0FBSyxHQUFHLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQzt3QkFDbEQsQ0FBQyxDQUFDLENBQUM7d0JBQ0gsSUFBSSxDQUFDLGdCQUFnQjs0QkFDbkIsTUFBTSxJQUFJLDZCQUFhLENBQ3JCLDJEQUEyRCxLQUFLLENBQUMsSUFBSSxHQUFHLENBQ3pFLENBQUM7d0JBQ0osT0FBTyxLQUFLLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztvQkFDakMsQ0FBQyxFQUNELE9BQU8sQ0FDUixDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQztnQkFDZixDQUFDLENBQ0YsQ0FBQztZQUNKLENBQUM7U0FDRixDQUFDO2FBQ0QsS0FBSyxFQUFFLENBQUM7UUFFWCwrQ0FBK0M7UUFDL0MsTUFBTSxZQUFZLEdBQUcsaUJBQVUsQ0FBQyxHQUFHLENBQUMsc0JBQWUsQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUNqRSxpQ0FBVSxDQUFDLFdBQVcsQ0FBQywwQkFBYyxDQUFDO2FBQ25DLEdBQUcsQ0FBQyxZQUFZLENBQUM7YUFDakIsTUFBTSxDQUFDO1lBQ04sU0FBUyxFQUFFLFNBQVMsU0FBUyxDQUMzQixLQUFrRCxFQUNsRCxPQUF3QixFQUN4QixRQUFpQjtnQkFFakIsTUFBTSxRQUFRLEdBQXNCO29CQUNsQyxLQUFLLEVBQUUsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQVc7b0JBQ2xELE9BQU8sRUFBRSxPQUFPO29CQUNoQixRQUFRLEVBQUUsUUFBUTtpQkFDbkIsQ0FBQztnQkFDRixNQUFNLE9BQU8sR0FBb0I7b0JBQy9CLE9BQU8sRUFDTCxPQUFPLENBQUMsTUFBTSxLQUFLLGNBQU8sQ0FBQyxPQUFPO3dCQUNsQyxPQUFPLENBQUMsTUFBTSxLQUFLLGNBQU8sQ0FBQyxPQUFPO29CQUNwQyxRQUFRLEVBQUUsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxTQUFTO29CQUNoRCxRQUFRLEVBQUUsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxTQUFTO29CQUNoRCxRQUFRLEVBQUUsSUFBSTtvQkFDZCxLQUFLLEVBQUUsUUFBUTtpQkFDaEIsQ0FBQztnQkFDRixPQUFPLElBQUEsa0JBQUssRUFDVixJQUFBLDJCQUFJLEVBQUMsc0JBQWUsQ0FBQyxTQUFTLENBQUMsRUFDL0IsSUFBQSwyQkFBSSxFQUFDO29CQUNILENBQUMsT0FBTyxLQUFLLEtBQUssVUFBVSxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUk7d0JBQ3pDLENBQUMsQ0FBQyxLQUFLO3dCQUNQLENBQUMsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFRO29CQUN0QixNQUFNLENBQUMsSUFBSTtvQkFDWCxNQUFNLENBQUMsSUFBSTtvQkFDWCxNQUFNLENBQUMsSUFBSTtpQkFDWixDQUFDLEVBQ0YsSUFBQSxtQ0FBWSxFQUFDLFlBQVksRUFBRSxRQUFRLENBQUMsRUFDcEMsU0FBUyxnQkFBZ0IsQ0FBQyxHQUFRLEVBQUUsSUFBUztvQkFDM0MsT0FBTyxJQUFBLG1CQUFTLEVBQ2QsR0FBRyxFQUFFO3dCQUNILElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSTs0QkFBRSxLQUFLLEdBQUksS0FBYSxFQUFFLENBQUM7d0JBQzFDLElBQUksQ0FBQyxLQUFLLENBQUMsZ0NBQVMsQ0FBQyxNQUE0QixDQUFDOzRCQUNoRCxNQUFNLElBQUksNkJBQWEsQ0FDckIseUNBQXlDLENBQzFDLENBQUM7d0JBQ0osT0FBTyxLQUFLLENBQUMsZ0NBQVMsQ0FBQyxNQUE0QixDQUFDLENBQUM7b0JBQ3ZELENBQUMsRUFDRCxDQUFDLEtBQVUsRUFBRSxFQUFFO3dCQUNiLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSTs0QkFBRSxLQUFLLEdBQUksS0FBYSxFQUFFLENBQUM7d0JBQzFDLE1BQU0sQ0FBQyxHQUFHLElBQUssS0FBMEIsRUFBRSxDQUFDO3dCQUM1QyxNQUFNLGdCQUFnQixHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUU7NEJBQ2pELE1BQU0sSUFBSSxHQUFHLHVCQUFVLENBQUMscUJBQXFCLENBQzNDLGlCQUFVLENBQUMsR0FBRyxDQUFDLHNCQUFlLENBQUMsV0FBVyxDQUFDLEVBQzNDLENBQUMsRUFDRCxDQUFDLEVBQ0QsSUFBSSxDQUNMLENBQUM7NEJBQ0YsSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU07Z0NBQ3RELE9BQU8sS0FBSyxDQUFDOzRCQUNmLE1BQU0sT0FBTyxHQUFHLE9BQU8sQ0FBQyxXQUFXLENBQ2pDLGlDQUFVLENBQUMsR0FBRyxDQUFDLHFDQUFjLENBQUMsSUFBSSxDQUFDLEVBQ25DLENBQUMsRUFDRCxDQUFDLENBQ0YsQ0FBQzs0QkFDRixJQUFJLENBQUMsT0FBTztnQ0FDVixNQUFNLElBQUksNkJBQWEsQ0FDckIsZ0NBQWdDLENBQUMsT0FBTyxDQUFDLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRSxDQUM3RCxDQUFDOzRCQUNKLE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUM7NEJBQ3JDLE9BQU8sSUFBSSxLQUFLLEdBQUcsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDO3dCQUN2QyxDQUFDLENBQUMsQ0FBQzt3QkFDSCxJQUFJLENBQUMsZ0JBQWdCOzRCQUNuQixNQUFNLElBQUksNkJBQWEsQ0FDckIsMkRBQTJELEtBQUssQ0FBQyxJQUFJLEdBQUcsQ0FDekUsQ0FBQzt3QkFDSixPQUFPLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO29CQUNqQyxDQUFDLENBQ0YsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLENBQUM7Z0JBQ2YsQ0FBQyxDQUNGLENBQUM7WUFDSixDQUFDO1NBQ0YsQ0FBQzthQUNELEtBQUssRUFBRSxDQUFDO1FBRVgsaURBQWlEO1FBQ2pELE1BQU0sYUFBYSxHQUFHLGlCQUFVLENBQUMsR0FBRyxDQUFDLHNCQUFlLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDbkUsaUNBQVUsQ0FBQyxXQUFXLENBQUMsMEJBQWMsQ0FBQzthQUNuQyxHQUFHLENBQUMsYUFBYSxDQUFDO2FBQ2xCLE1BQU0sQ0FBQztZQUNOLFNBQVMsRUFBRSxTQUFTLFVBQVUsQ0FDNUIsS0FBa0QsRUFDbEQsT0FBd0IsRUFDeEIsUUFBaUI7Z0JBRWpCLE1BQU0sUUFBUSxHQUFzQjtvQkFDbEMsS0FBSyxFQUFFLEtBQUssQ0FBQyxJQUFJO29CQUNqQixPQUFPLEVBQUUsT0FBTztvQkFDaEIsUUFBUSxFQUFFLFFBQVE7aUJBQ25CLENBQUM7Z0JBQ0YsTUFBTSxPQUFPLEdBQW9CO29CQUMvQixPQUFPLEVBQ0wsT0FBTyxDQUFDLE1BQU0sS0FBSyxjQUFPLENBQUMsT0FBTzt3QkFDbEMsT0FBTyxDQUFDLE1BQU0sS0FBSyxjQUFPLENBQUMsT0FBTztvQkFDcEMsUUFBUSxFQUFFLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsU0FBUztvQkFDaEQsUUFBUSxFQUFFLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsU0FBUztvQkFDaEQsUUFBUSxFQUFFLElBQUk7b0JBQ2QsS0FBSyxFQUFFLFFBQVE7aUJBQ2hCLENBQUM7Z0JBQ0YsT0FBTyxJQUFBLGtCQUFLLEVBQ1YsSUFBQSwyQkFBSSxFQUFDLHNCQUFlLENBQUMsU0FBUyxDQUFDLEVBQy9CLElBQUEsMkJBQUksRUFBQyxLQUFLLENBQUMsRUFDWCxJQUFBLG1DQUFZLEVBQUMsYUFBYSxFQUFFLFFBQVEsQ0FBQyxFQUNyQyxJQUFBLG9CQUFVLEVBQ1IsR0FBRyxFQUFFO29CQUNILElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSTt3QkFBRSxLQUFLLEdBQUksS0FBYSxFQUFFLENBQUM7b0JBQzFDLElBQUksQ0FBQyxLQUFLLENBQUMsZ0NBQVMsQ0FBQyxNQUE0QixDQUFDO3dCQUNoRCxNQUFNLElBQUksNkJBQWEsQ0FDckIseUNBQXlDLENBQzFDLENBQUM7b0JBQ0osT0FBTyxLQUFLLENBQUMsZ0NBQVMsQ0FBQyxNQUE0QixDQUFDLENBQUM7Z0JBQ3ZELENBQUMsRUFDRCxDQUFDLEtBQVUsRUFBRSxFQUFFO29CQUNiLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSTt3QkFBRSxLQUFLLEdBQUksS0FBYSxFQUFFLENBQUM7b0JBQzFDLE1BQU0sRUFBRSxHQUFHLElBQUEsOEJBQWMsRUFBQyxJQUFLLEtBQTBCLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQztvQkFDaEUsT0FBTyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUM7Z0JBQ25CLENBQUMsRUFDRCxPQUFPLENBQ1IsRUFDRCxJQUFBLG1CQUFTLEdBQUUsQ0FDWixDQUFDO1lBQ0osQ0FBQztTQUNGLENBQUM7YUFDRCxLQUFLLEVBQUUsQ0FBQztJQUNiLENBQUM7Q0FDRjtBQXAyQ0Qsd0NBbzJDQztBQTF4Q29CO0lBRGxCLElBQUEsWUFBSyxHQUFFOzs7b0NBQ3VCLGlDQUFlOzhDQUU3QztBQUdRO0lBRFIsSUFBQSxZQUFLLEdBQUU7Ozs7Z0RBR1A7QUFTRDtJQURDLElBQUEsWUFBSyxHQUFFOzs7b0NBQ3NCLHdCQUFnQjsrQ0FFN0M7QUFTSztJQURMLElBQUEsWUFBSyxHQUFFOzs7OzhDQUdQO0FBMEJlO0lBRGYsSUFBQSxZQUFLLEdBQUU7Ozs7MkNBa0JQIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQWRhcHRlcixcbiAgQ2FzY2FkZSxcbiAgQ2FzY2FkZU1ldGFkYXRhLFxuICBDb25uZWN0aW9uRXJyb3IsXG4gIGZpbmFsLFxuICBQZXJzaXN0ZW5jZUtleXMsXG4gIFJlbGF0aW9uc01ldGFkYXRhLFxuICBSZXBvc2l0b3J5LFxuICBTZXF1ZW5jZSxcbiAgdHlwZSBTZXF1ZW5jZU9wdGlvbnMsXG59IGZyb20gXCJAZGVjYWYtdHMvY29yZVwiO1xuaW1wb3J0IHsgcmVzZXJ2ZWRBdHRyaWJ1dGVzLCBUeXBlT1JNRmxhdm91ciB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuaW1wb3J0IHtcbiAgQmFzZUVycm9yLFxuICBDb25mbGljdEVycm9yLFxuICBDb250ZXh0LFxuICBEQktleXMsXG4gIERFRkFVTFRfRVJST1JfTUVTU0FHRVMgYXMgREJfREVGQVVMVF9FUlJPUl9NRVNTQUdFUyxcbiAgZmluZFByaW1hcnlLZXksXG4gIEludGVybmFsRXJyb3IsXG4gIE5vdEZvdW5kRXJyb3IsXG4gIE9wZXJhdGlvbktleXMsXG4gIHJlYWRvbmx5LFxuICBVcGRhdGVWYWxpZGF0aW9uS2V5cyxcbn0gZnJvbSBcIkBkZWNhZi10cy9kYi1kZWNvcmF0b3JzXCI7XG5pbXBvcnQgXCJyZWZsZWN0LW1ldGFkYXRhXCI7XG5pbXBvcnQge1xuICB0eXBlIENvbnN0cnVjdG9yLFxuICBkYXRlLFxuICBEZWNvcmF0aW9uLFxuICBERUZBVUxUX0VSUk9SX01FU1NBR0VTLFxuICBsaXN0LFxuICBNYXhMZW5ndGhWYWxpZGF0b3JPcHRpb25zLFxuICBNYXhWYWxpZGF0b3JPcHRpb25zLFxuICBNaW5MZW5ndGhWYWxpZGF0b3JPcHRpb25zLFxuICBNaW5WYWxpZGF0b3JPcHRpb25zLFxuICBNb2RlbCxcbiAgTW9kZWxLZXlzLFxuICBQYXR0ZXJuVmFsaWRhdG9yT3B0aW9ucyxcbiAgcHJvcCxcbiAgcHJvcE1ldGFkYXRhLFxuICByZXF1aXJlZCxcbiAgdHlwZSxcbiAgVHlwZU1ldGFkYXRhLFxuICBWYWxpZGF0aW9uLFxuICBWYWxpZGF0aW9uS2V5cyxcbiAgVmFsaWRhdG9yT3B0aW9ucyxcbn0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgSW5kZXhFcnJvciB9IGZyb20gXCIuL2Vycm9yc1wiO1xuaW1wb3J0IHsgVHlwZU9STVN0YXRlbWVudCB9IGZyb20gXCIuL3F1ZXJ5XCI7XG5pbXBvcnQgeyBUeXBlT1JNU2VxdWVuY2UgfSBmcm9tIFwiLi9zZXF1ZW5jZXNcIjtcbmltcG9ydCB7IGdlbmVyYXRlSW5kZXhlcyB9IGZyb20gXCIuL2luZGV4ZXNcIjtcbmltcG9ydCB7IFR5cGVPUk1GbGFncywgVHlwZU9STVF1ZXJ5LCBUeXBlT1JNVGFibGVTcGVjIH0gZnJvbSBcIi4vdHlwZXNcIjtcbmltcG9ydCB7IGFwcGx5LCBSZWZsZWN0aW9uIH0gZnJvbSBcIkBkZWNhZi10cy9yZWZsZWN0aW9uXCI7XG5pbXBvcnQgeyBUeXBlT1JNUmVwb3NpdG9yeSB9IGZyb20gXCIuL1R5cGVPUk1SZXBvc2l0b3J5XCI7XG5pbXBvcnQgeyBMb2dnaW5nIH0gZnJvbSBcIkBkZWNhZi10cy9sb2dnaW5nXCI7XG5pbXBvcnQgeyBUeXBlT1JNRGlzcGF0Y2ggfSBmcm9tIFwiLi9UeXBlT1JNRGlzcGF0Y2hcIjtcbmltcG9ydCB7IGNvbnZlcnRKc1JlZ2V4VG9Qb3N0Z3JlcyB9IGZyb20gXCIuL3V0aWxzXCI7XG5pbXBvcnQge1xuICBEYXRhU291cmNlLFxuICBGaW5kT25lT3B0aW9ucyxcbiAgSW4sXG4gIEluc2VydFJlc3VsdCxcbiAgUmVsYXRpb25PcHRpb25zLFxuICBPbmVUb09uZSxcbiAgSm9pbkNvbHVtbixcbiAgTWFueVRvTWFueSxcbiAgU2VsZWN0UXVlcnlCdWlsZGVyLFxuICBWZXJzaW9uQ29sdW1uLFxuICBPbmVUb01hbnksXG4gIE1hbnlUb09uZSxcbiAgSm9pblRhYmxlLFxufSBmcm9tIFwidHlwZW9ybVwiO1xuaW1wb3J0IHsgRGF0YVNvdXJjZU9wdGlvbnMgfSBmcm9tIFwidHlwZW9ybS9kYXRhLXNvdXJjZS9EYXRhU291cmNlT3B0aW9uc1wiO1xuaW1wb3J0IHsgQ29sdW1uIH0gZnJvbSBcIi4vb3ZlcnJpZGVzL0NvbHVtblwiO1xuaW1wb3J0IHsgVXBkYXRlRGF0ZUNvbHVtbiB9IGZyb20gXCIuL292ZXJyaWRlcy9VcGRhdGVEYXRlQ29sdW1uXCI7XG5pbXBvcnQgeyBDcmVhdGVEYXRlQ29sdW1uIH0gZnJvbSBcIi4vb3ZlcnJpZGVzL0NyZWF0ZURhdGVDb2x1bW5cIjtcbmltcG9ydCB7IFByaW1hcnlHZW5lcmF0ZWRDb2x1bW4gfSBmcm9tIFwiLi9vdmVycmlkZXMvUHJpbWFyeUdlbmVyYXRlZENvbHVtblwiO1xuaW1wb3J0IHsgUHJpbWFyeUNvbHVtbiB9IGZyb20gXCIuL292ZXJyaWRlcy9QcmltYXJ5Q29sdW1uXCI7XG5pbXBvcnQgeyBFbnRpdHkgfSBmcm9tIFwiLi9vdmVycmlkZXMvRW50aXR5XCI7XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjcmVhdGVkQnlPblBvc3RncmVzQ3JlYXRlVXBkYXRlPFxuICBNIGV4dGVuZHMgTW9kZWwsXG4gIFIgZXh0ZW5kcyBUeXBlT1JNUmVwb3NpdG9yeTxNPixcbiAgViBleHRlbmRzIFJlbGF0aW9uc01ldGFkYXRhLFxuPihcbiAgdGhpczogUixcbiAgY29udGV4dDogQ29udGV4dDxUeXBlT1JNRmxhZ3M+LFxuICBkYXRhOiBWLFxuICBrZXk6IGtleW9mIE0sXG4gIG1vZGVsOiBNXG4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgdHJ5IHtcbiAgICBjb25zdCB1c2VyID0gY29udGV4dC5nZXQoXCJ1c2VyXCIpO1xuICAgIG1vZGVsW2tleV0gPSB1c2VyIGFzIE1bdHlwZW9mIGtleV07XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICB9IGNhdGNoIChlOiB1bmtub3duKSB7XG4gICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXG4gICAgICBcIk5vIFVzZXIgZm91bmQgaW4gY29udGV4dC4gUGxlYXNlIHByb3ZpZGUgYSB1c2VyIGluIHRoZSBjb250ZXh0XCJcbiAgICApO1xuICB9XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEFkYXB0ZXIgZm9yIFR5cGVPUk0tYmFja2VkIHBlcnNpc3RlbmNlIG9wZXJhdGlvbnMuXG4gKiBAc3VtbWFyeSBJbXBsZW1lbnRzIHRoZSBEZWNhZi50cyBBZGFwdGVyIG92ZXIgYSBUeXBlT1JNIERhdGFTb3VyY2UsIHByb3ZpZGluZyBDUlVEIG9wZXJhdGlvbnMsIHF1ZXJ5L3N0YXRlbWVudCBmYWN0b3JpZXMsIHNlcXVlbmNlIG1hbmFnZW1lbnQsIGVycm9yIHBhcnNpbmcsIGFuZCBkZWNvcmF0aW9uIGhlbHBlcnMuXG4gKiBAdGVtcGxhdGUgWSBUaGUgbmF0aXZlIGNvbmZpZ3VyYXRpb24gdHlwZSAoVHlwZU9STSBEYXRhU291cmNlT3B0aW9ucykuXG4gKiBAdGVtcGxhdGUgRiBUaGUgcmVwb3NpdG9yeSBmbGFncyB0eXBlLlxuICogQHRlbXBsYXRlIEMgVGhlIGNvbnRleHQgdHlwZS5cbiAqIEBwYXJhbSB7RGF0YVNvdXJjZU9wdGlvbnN9IHNjb3BlIFRoZSBEYXRhU291cmNlIG9wdGlvbnMgZm9yIHRoZSBhZGFwdGVyLlxuICogQHBhcmFtIHtzdHJpbmd9IGZsYXZvdXIgVGhlIGZsYXZvdXIgb2YgdGhlIGFkYXB0ZXIuXG4gKiBAcGFyYW0ge3N0cmluZ30gW2FsaWFzXSBPcHRpb25hbCBhbGlhcyBmb3IgdGhlIGFkYXB0ZXIuXG4gKiBAY2xhc3MgVHlwZU9STUFkYXB0ZXJcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBhZGFwdGVyID0gbmV3IFR5cGVPUk1BZGFwdGVyKHsgdHlwZTogJ3Bvc3RncmVzJywgLyogLi4uICpcXC8gfSk7XG4gKiBhd2FpdCBhZGFwdGVyLmluaXRpYWxpemUoKTtcbiAqIGNvbnN0IHJlcG8gPSBuZXcgKGFkYXB0ZXIucmVwb3NpdG9yeTxVc2VyPigpKShhZGFwdGVyLCBVc2VyKTtcbiAqIGNvbnN0IGNyZWF0ZWQgPSBhd2FpdCByZXBvLmNyZWF0ZShuZXcgVXNlcih7IG5hbWU6ICdBbGljZScgfSkpO1xuICpcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgQXBwXG4gKiAgIHBhcnRpY2lwYW50IEFkYXB0ZXIgYXMgVHlwZU9STUFkYXB0ZXJcbiAqICAgcGFydGljaXBhbnQgUmVwbyBhcyBUeXBlT1JNUmVwb3NpdG9yeVxuICogICBwYXJ0aWNpcGFudCBEUyBhcyBUeXBlT1JNIERhdGFTb3VyY2VcbiAqXG4gKiAgIEFwcC0+PkFkYXB0ZXI6IG5ldyBUeXBlT1JNQWRhcHRlcihvcHRzKVxuICogICBBZGFwdGVyLT4+RFM6IGluaXRpYWxpemUoKVxuICogICBBcHAtPj5BZGFwdGVyOiByZXBvc2l0b3J5KClcbiAqICAgQWRhcHRlci0tPj5BcHA6IFR5cGVPUk1SZXBvc2l0b3J5XG4gKiAgIEFwcC0+PlJlcG86IGNyZWF0ZShtb2RlbClcbiAqICAgUmVwby0+PkFkYXB0ZXI6IHByZXBhcmUvY3JlYXRlL3JldmVydFxuICogICBBZGFwdGVyLS0+PlJlcG86IE1vZGVsXG4gKiAgIFJlcG8tLT4+QXBwOiBNb2RlbFxuICovXG5leHBvcnQgY2xhc3MgVHlwZU9STUFkYXB0ZXIgZXh0ZW5kcyBBZGFwdGVyPFxuICBEYXRhU291cmNlT3B0aW9ucyxcbiAgVHlwZU9STVF1ZXJ5LFxuICBUeXBlT1JNRmxhZ3MsXG4gIENvbnRleHQ8VHlwZU9STUZsYWdzPlxuPiB7XG4gIHByaXZhdGUgX2RhdGFTb3VyY2U/OiBEYXRhU291cmNlO1xuXG4gIGdldCBkYXRhU291cmNlKCk6IERhdGFTb3VyY2Uge1xuICAgIGlmICghdGhpcy5fZGF0YVNvdXJjZSkge1xuICAgICAgY29uc3QgbW9kZWxzID0gQWRhcHRlci5tb2RlbHModGhpcy5mbGF2b3VyKTtcbiAgICAgIHRoaXMuX2RhdGFTb3VyY2UgPSBuZXcgRGF0YVNvdXJjZShcbiAgICAgICAgT2JqZWN0LmFzc2lnbih0aGlzLm5hdGl2ZSwge1xuICAgICAgICAgIGVudGl0aWVzOiBtb2RlbHMubWFwKChjKSA9PiBjW01vZGVsS2V5cy5BTkNIT1IgYXMga2V5b2YgdHlwZW9mIGNdKSxcbiAgICAgICAgfSlcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9kYXRhU291cmNlO1xuICB9XG4gIC8vIHByb3RlY3RlZCBkYXRhU291XG5cbiAgY29uc3RydWN0b3Iob3B0aW9uczogRGF0YVNvdXJjZU9wdGlvbnMsIGFsaWFzPzogc3RyaW5nKSB7XG4gICAgc3VwZXIob3B0aW9ucywgVHlwZU9STUZsYXZvdXIsIGFsaWFzKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBvdmVycmlkZSBhc3luYyBmbGFnczxNIGV4dGVuZHMgTW9kZWw+KFxuICAgIG9wZXJhdGlvbjogT3BlcmF0aW9uS2V5cyxcbiAgICBtb2RlbDogQ29uc3RydWN0b3I8TT4sXG4gICAgZmxhZ3M6IFBhcnRpYWw8VHlwZU9STUZsYWdzPlxuICApOiBQcm9taXNlPFR5cGVPUk1GbGFncz4ge1xuICAgIGNvbnN0IGYgPSBhd2FpdCBzdXBlci5mbGFncyhvcGVyYXRpb24sIG1vZGVsLCBmbGFncyk7XG4gICAgY29uc3QgbmV3T2JqOiBhbnkgPSB7XG4gICAgICB1c2VyOiAoYXdhaXQgVHlwZU9STUFkYXB0ZXIuZ2V0Q3VycmVudFVzZXIodGhpcy5kYXRhU291cmNlKSkgYXMgc3RyaW5nLFxuICAgIH07XG4gICAgY29uc3QgbSA9IG5ldyBtb2RlbCgpO1xuXG4gICAgY29uc3QgZXhjZXB0aW9uczogc3RyaW5nW10gPSBbXTtcbiAgICBpZiAob3BlcmF0aW9uID09PSBPcGVyYXRpb25LZXlzLkNSRUFURSkge1xuICAgICAgY29uc3QgcGsgPSBmaW5kUHJpbWFyeUtleShtKS5pZDtcbiAgICAgIGV4Y2VwdGlvbnMucHVzaChwayBhcyBzdHJpbmcpO1xuICAgIH1cblxuICAgIGlmIChcbiAgICAgIG9wZXJhdGlvbiA9PT0gT3BlcmF0aW9uS2V5cy5DUkVBVEUgfHxcbiAgICAgIG9wZXJhdGlvbiA9PT0gT3BlcmF0aW9uS2V5cy5VUERBVEVcbiAgICApIHtcbiAgICAgIGNvbnN0IGRlY3MgPSBPYmplY3Qua2V5cyhtKS5yZWR1Y2UoKGFjY3VtOiBSZWNvcmQ8c3RyaW5nLCBhbnk+LCBrZXkpID0+IHtcbiAgICAgICAgY29uc3QgZGVjcyA9IFJlZmxlY3Rpb24uZ2V0UHJvcGVydHlEZWNvcmF0b3JzKFxuICAgICAgICAgIFZhbGlkYXRpb25LZXlzLlJFRkxFQ1QsXG4gICAgICAgICAgbSxcbiAgICAgICAgICBrZXksXG4gICAgICAgICAgdHJ1ZVxuICAgICAgICApO1xuICAgICAgICBjb25zdCBkZWMgPSBkZWNzLmRlY29yYXRvcnMuZmluZChcbiAgICAgICAgICAoZGVjOiBhbnkpID0+XG4gICAgICAgICAgICBkZWMua2V5ID09PSBEQktleXMuVElNRVNUQU1QICYmXG4gICAgICAgICAgICBkZWMucHJvcHMub3BlcmF0aW9uLmluZGV4T2Yob3BlcmF0aW9uKSAhPT0gLTFcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKGRlYykge1xuICAgICAgICAgIGFjY3VtW2tleV0gPSBkZWMucHJvcHM7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGFjY3VtO1xuICAgICAgfSwge30pO1xuXG4gICAgICBleGNlcHRpb25zLnB1c2goLi4uT2JqZWN0LmtleXMoZGVjcykpO1xuICAgIH1cblxuICAgIG5ld09iai5pZ25vcmVkVmFsaWRhdGlvblByb3BlcnRpZXMgPSAoXG4gICAgICBmLmlnbm9yZWRWYWxpZGF0aW9uUHJvcGVydGllcyA/IGYuaWdub3JlZFZhbGlkYXRpb25Qcm9wZXJ0aWVzIDogW11cbiAgICApLmNvbmNhdCguLi5leGNlcHRpb25zKTtcbiAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihmLCBuZXdPYmopIGFzIFR5cGVPUk1GbGFncztcbiAgfVxuXG4gIEBmaW5hbCgpXG4gIHByb3RlY3RlZCBvdmVycmlkZSBEaXNwYXRjaCgpOiBUeXBlT1JNRGlzcGF0Y2gge1xuICAgIHJldHVybiBuZXcgVHlwZU9STURpc3BhdGNoKCk7XG4gIH1cblxuICBAZmluYWwoKVxuICBvdmVycmlkZSByZXBvc2l0b3J5PE0gZXh0ZW5kcyBNb2RlbD4oKTogQ29uc3RydWN0b3I8VHlwZU9STVJlcG9zaXRvcnk8TT4+IHtcbiAgICByZXR1cm4gVHlwZU9STVJlcG9zaXRvcnk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENyZWF0ZXMgYSBuZXcgUG9zdGdyZXMgc3RhdGVtZW50IGZvciBxdWVyeWluZ1xuICAgKiBAc3VtbWFyeSBGYWN0b3J5IG1ldGhvZCB0aGF0IGNyZWF0ZXMgYSBuZXcgUG9zdGdyZXNTdGF0ZW1lbnQgaW5zdGFuY2UgZm9yIGJ1aWxkaW5nIHF1ZXJpZXNcbiAgICogQHRlbXBsYXRlIE0gLSBUaGUgbW9kZWwgdHlwZVxuICAgKiBAcmV0dXJuIHtUeXBlT1JNU3RhdGVtZW50PE0sIGFueT59IEEgbmV3IFBvc3RncmVzU3RhdGVtZW50IGluc3RhbmNlXG4gICAqL1xuICBAZmluYWwoKVxuICBTdGF0ZW1lbnQ8TSBleHRlbmRzIE1vZGVsPigpOiBUeXBlT1JNU3RhdGVtZW50PE0sIGFueT4ge1xuICAgIHJldHVybiBuZXcgVHlwZU9STVN0YXRlbWVudCh0aGlzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ3JlYXRlcyBhIG5ldyBQb3N0Z3JlU1FMIHNlcXVlbmNlXG4gICAqIEBzdW1tYXJ5IEZhY3RvcnkgbWV0aG9kIHRoYXQgY3JlYXRlcyBhIG5ldyBQb3N0Z3JlU1FMU2VxdWVuY2UgaW5zdGFuY2UgZm9yIG1hbmFnaW5nIHNlcXVlbmNlc1xuICAgKiBAcGFyYW0ge1NlcXVlbmNlT3B0aW9uc30gb3B0aW9ucyAtIFRoZSBvcHRpb25zIGZvciB0aGUgc2VxdWVuY2VcbiAgICogQHJldHVybiB7UHJvbWlzZTxTZXF1ZW5jZT59IEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIGEgbmV3IFNlcXVlbmNlIGluc3RhbmNlXG4gICAqL1xuICBAZmluYWwoKVxuICBhc3luYyBTZXF1ZW5jZShvcHRpb25zOiBTZXF1ZW5jZU9wdGlvbnMpOiBQcm9taXNlPFNlcXVlbmNlPiB7XG4gICAgcmV0dXJuIG5ldyBUeXBlT1JNU2VxdWVuY2Uob3B0aW9ucywgdGhpcyk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEluaXRpYWxpemVzIHRoZSBhZGFwdGVyIGJ5IGNyZWF0aW5nIGluZGV4ZXMgZm9yIGFsbCBtYW5hZ2VkIG1vZGVsc1xuICAgKiBAc3VtbWFyeSBTZXRzIHVwIHRoZSBuZWNlc3NhcnkgZGF0YWJhc2UgaW5kZXhlcyBmb3IgYWxsIG1vZGVscyBtYW5hZ2VkIGJ5IHRoaXMgYWRhcHRlclxuICAgKiBAcmV0dXJuIHtQcm9taXNlPHZvaWQ+fSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIGluaXRpYWxpemF0aW9uIGlzIGNvbXBsZXRlXG4gICAqL1xuICBhc3luYyBpbml0aWFsaXplKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGRzID0gdGhpcy5kYXRhU291cmNlO1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBkcy5pbml0aWFsaXplKCk7XG4gICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgdGhyb3cgdGhpcy5wYXJzZUVycm9yKGUgYXMgRXJyb3IpO1xuICAgIH1cbiAgICBjb25zdCBsb2cgPSB0aGlzLmxvZy5mb3IodGhpcy5pbml0aWFsaXplKTtcbiAgICBsb2cudmVyYm9zZShgJHt0aGlzLmZsYXZvdXJ9IGFkYXB0ZXIgaW5pdGlhbGl6ZWRgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ3JlYXRlcyBpbmRleGVzIGZvciB0aGUgZ2l2ZW4gbW9kZWxzXG4gICAqIEBzdW1tYXJ5IEFic3RyYWN0IG1ldGhvZCB0aGF0IG11c3QgYmUgaW1wbGVtZW50ZWQgdG8gY3JlYXRlIGRhdGFiYXNlIGluZGV4ZXMgZm9yIHRoZSBzcGVjaWZpZWQgbW9kZWxzXG4gICAqIEB0ZW1wbGF0ZSBNIC0gVGhlIG1vZGVsIHR5cGVcbiAgICogQHBhcmFtIHsuLi5Db25zdHJ1Y3RvcjxNPn0gbW9kZWxzIC0gVGhlIG1vZGVsIGNvbnN0cnVjdG9ycyB0byBjcmVhdGUgaW5kZXhlcyBmb3JcbiAgICogQHJldHVybiB7UHJvbWlzZTx2b2lkPn0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiBhbGwgaW5kZXhlcyBhcmUgY3JlYXRlZFxuICAgKi9cbiAgQGZpbmFsKClcbiAgcHJvdGVjdGVkIGFzeW5jIGluZGV4PE0gZXh0ZW5kcyBNb2RlbD4oXG4gICAgLi4ubW9kZWxzOiBDb25zdHJ1Y3RvcjxNPltdXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGluZGV4ZXM6IFR5cGVPUk1RdWVyeVtdID0gZ2VuZXJhdGVJbmRleGVzKG1vZGVscyk7XG5cbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5kYXRhU291cmNlLnF1ZXJ5KFwiQkVHSU5cIik7XG5cbiAgICAgIGZvciAoY29uc3QgaW5kZXggb2YgaW5kZXhlcykge1xuICAgICAgICBhd2FpdCB0aGlzLmRhdGFTb3VyY2UucXVlcnkoaW5kZXgucXVlcnksIGluZGV4LnZhbHVlcyk7XG4gICAgICB9XG5cbiAgICAgIGF3YWl0IHRoaXMuZGF0YVNvdXJjZS5xdWVyeShcIkNPTU1JVFwiKTtcbiAgICB9IGNhdGNoIChlOiB1bmtub3duKSB7XG4gICAgICBhd2FpdCB0aGlzLmRhdGFTb3VyY2UucXVlcnkoXCJST0xMQkFDS1wiKTtcbiAgICAgIHRocm93IHRoaXMucGFyc2VFcnJvcihlIGFzIEVycm9yKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEV4ZWN1dGVzIGEgcmF3IFNRTCBxdWVyeSBhZ2FpbnN0IHRoZSBkYXRhYmFzZVxuICAgKiBAc3VtbWFyeSBBYnN0cmFjdCBtZXRob2QgdGhhdCBtdXN0IGJlIGltcGxlbWVudGVkIHRvIGV4ZWN1dGUgcmF3IFNRTCBxdWVyaWVzXG4gICAqIEB0ZW1wbGF0ZSBSIC0gVGhlIHJlc3VsdCB0eXBlXG4gICAqIEBwYXJhbSB7VHlwZU9STVF1ZXJ5fSBxIC0gVGhlIHF1ZXJ5IHRvIGV4ZWN1dGVcbiAgICogQHJldHVybiB7UHJvbWlzZTxSPn0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gdGhlIHF1ZXJ5IHJlc3VsdFxuICAgKi9cbiAgb3ZlcnJpZGUgYXN5bmMgcmF3PFI+KHE6IFR5cGVPUk1RdWVyeSk6IFByb21pc2U8Uj4ge1xuICAgIGNvbnN0IGxvZyA9IHRoaXMubG9nLmZvcih0aGlzLnJhdyk7XG4gICAgdHJ5IHtcbiAgICAgIGlmICghdGhpcy5kYXRhU291cmNlLmlzSW5pdGlhbGl6ZWQpIGF3YWl0IHRoaXMuZGF0YVNvdXJjZS5pbml0aWFsaXplKCk7XG4gICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgdGhyb3cgdGhpcy5wYXJzZUVycm9yKGUgYXMgRXJyb3IpO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgY29uc3QgeyBxdWVyeSwgdmFsdWVzIH0gPSBxO1xuICAgICAgbG9nLmRlYnVnKFxuICAgICAgICBgZXhlY3V0aW5nIHF1ZXJ5OiAkeyhxdWVyeSBhcyB1bmtub3duIGFzIFNlbGVjdFF1ZXJ5QnVpbGRlcjxhbnk+KS5nZXRTcWwoKX1gXG4gICAgICApO1xuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLmRhdGFTb3VyY2UucXVlcnkocXVlcnksIHZhbHVlcyk7XG4gICAgICByZXR1cm4gcmVzcG9uc2UgYXMgUjtcbiAgICB9IGNhdGNoIChlOiB1bmtub3duKSB7XG4gICAgICB0aHJvdyB0aGlzLnBhcnNlRXJyb3IoZSBhcyBFcnJvcik7XG4gICAgfVxuICB9XG5cbiAgb3ZlcnJpZGUgcHJlcGFyZTxNIGV4dGVuZHMgTW9kZWw+KFxuICAgIG1vZGVsOiBNLFxuICAgIHBrOiBrZXlvZiBNLFxuICAgIGNoaWxkID0gZmFsc2VcbiAgKToge1xuICAgIHJlY29yZDogUmVjb3JkPHN0cmluZywgYW55PjtcbiAgICBpZDogc3RyaW5nO1xuICAgIHRyYW5zaWVudD86IFJlY29yZDxzdHJpbmcsIGFueT47XG4gIH0ge1xuICAgIGNvbnN0IHByZXBhcmVkID0gc3VwZXIucHJlcGFyZShtb2RlbCwgcGspO1xuXG4gICAgcHJlcGFyZWQucmVjb3JkID0gT2JqZWN0LmVudHJpZXMocHJlcGFyZWQucmVjb3JkKS5yZWR1Y2UoXG4gICAgICAoYWNjdW06IFJlY29yZDxzdHJpbmcsIGFueT4sIFtrZXksIHZhbHVlXSkgPT4ge1xuICAgICAgICBpZiAoa2V5ID09PSBQZXJzaXN0ZW5jZUtleXMuTUVUQURBVEEgfHwgdGhpcy5pc1Jlc2VydmVkKGtleSkpXG4gICAgICAgICAgcmV0dXJuIGFjY3VtO1xuICAgICAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHJldHVybiBhY2N1bTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIERhdGUpIHtcbiAgICAgICAgICB2YWx1ZSA9IG5ldyBEYXRlKHZhbHVlLmdldFRpbWUoKSk7XG4gICAgICAgIH0gZWxzZSBpZiAoTW9kZWwuaXNNb2RlbCh2YWx1ZSkpIHtcbiAgICAgICAgICB2YWx1ZSA9IHRoaXMucHJlcGFyZSh2YWx1ZSwgZmluZFByaW1hcnlLZXkodmFsdWUpLmlkLCB0cnVlKS5yZWNvcmQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc3dpdGNoICh0eXBlb2YgdmFsdWUpIHtcbiAgICAgICAgICAgIGNhc2UgXCJzdHJpbmdcIjpcbiAgICAgICAgICAgICAgdmFsdWUgPSBgJHt2YWx1ZX1gO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAvL2RvIG5vdGhpbmc7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGFjY3VtW2tleV0gPSB2YWx1ZTtcbiAgICAgICAgcmV0dXJuIGFjY3VtO1xuICAgICAgfSxcbiAgICAgIHt9XG4gICAgKTtcbiAgICBjb25zdCBjb25zdHI6IENvbnN0cnVjdG9yPGFueT4gfCB1bmRlZmluZWQgPSBNb2RlbC5nZXQoXG4gICAgICBtb2RlbC5jb25zdHJ1Y3Rvci5uYW1lXG4gICAgKTtcbiAgICBpZiAoIWNvbnN0cilcbiAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFxuICAgICAgICBgTW9kZWwgJHttb2RlbC5jb25zdHJ1Y3Rvci5uYW1lfSBub3QgZm91bmQgaW4gcmVnaXN0cnlgXG4gICAgICApO1xuICAgIGNvbnN0IHJlc3VsdCA9IGNoaWxkXG4gICAgICA/IG5ldyAoY29uc3RyIGFzIGFueSlbTW9kZWxLZXlzLkFOQ0hPUiBhcyBrZXlvZiB0eXBlb2YgY29uc3RyXSgpXG4gICAgICA6IG5ldyBjb25zdHIoKTtcbiAgICBpZiAoY2hpbGQpXG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkocmVzdWx0LCBcImNvbnN0cnVjdG9yXCIsIHtcbiAgICAgICAgY29uZmlndXJhYmxlOiBmYWxzZSxcbiAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgIHZhbHVlOiAoY29uc3RyIGFzIGFueSlbTW9kZWxLZXlzLkFOQ0hPUiBhcyBrZXlvZiB0eXBlb2YgY29uc3RyXSxcbiAgICAgICAgd3JpdGFibGU6IGZhbHNlLFxuICAgICAgfSk7XG4gICAgT2JqZWN0LmVudHJpZXMocHJlcGFyZWQucmVjb3JkKS5mb3JFYWNoKFxuICAgICAgKFtrZXksIHZhbF0pID0+IChyZXN1bHRba2V5IGFzIGtleW9mIHR5cGVvZiByZXN1bHRdID0gdmFsKVxuICAgICk7XG4gICAgcHJlcGFyZWQucmVjb3JkID0gcmVzdWx0O1xuICAgIHJldHVybiBwcmVwYXJlZDtcbiAgfVxuXG4gIG92ZXJyaWRlIHJldmVydDxNIGV4dGVuZHMgTW9kZWw+KFxuICAgIG9iajogUmVjb3JkPHN0cmluZywgYW55PixcbiAgICBjbGF6ejogc3RyaW5nIHwgQ29uc3RydWN0b3I8TT4sXG4gICAgcGs6IGtleW9mIE0sXG4gICAgaWQ6IHN0cmluZyB8IG51bWJlciB8IGJpZ2ludCxcbiAgICB0cmFuc2llbnQ/OiBSZWNvcmQ8c3RyaW5nLCBhbnk+XG4gICk6IE0ge1xuICAgIGNvbnN0IGxvZyA9IHRoaXMubG9nLmZvcih0aGlzLnJldmVydCk7XG4gICAgaWYgKHRyYW5zaWVudCkge1xuICAgICAgbG9nLnZlcmJvc2UoXG4gICAgICAgIGByZS1hZGRpbmcgdHJhbnNpZW50IHByb3BlcnRpZXM6ICR7T2JqZWN0LmtleXModHJhbnNpZW50KS5qb2luKFwiLCBcIil9YFxuICAgICAgKTtcbiAgICAgIE9iamVjdC5lbnRyaWVzKHRyYW5zaWVudCkuZm9yRWFjaCgoW2tleSwgdmFsXSkgPT4ge1xuICAgICAgICBpZiAoa2V5IGluIG9iailcbiAgICAgICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcbiAgICAgICAgICAgIGBUcmFuc2llbnQgcHJvcGVydHkgJHtrZXl9IGFscmVhZHkgZXhpc3RzIG9uIG1vZGVsICR7dHlwZW9mIGNsYXp6ID09PSBcInN0cmluZ1wiID8gY2xhenogOiBjbGF6ei5uYW1lfS4gc2hvdWxkIGJlIGltcG9zc2libGVgXG4gICAgICAgICAgKTtcbiAgICAgICAgKG9iaiBhcyBNKVtrZXkgYXMga2V5b2YgTV0gPSB2YWw7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IChjbGF6eiBhcyBDb25zdHJ1Y3RvcjxNPikob2JqKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ3JlYXRlcyBhIG5ldyByZWNvcmQgaW4gdGhlIGRhdGFiYXNlXG4gICAqIEBzdW1tYXJ5IEFic3RyYWN0IG1ldGhvZCB0aGF0IG11c3QgYmUgaW1wbGVtZW50ZWQgdG8gY3JlYXRlIGEgbmV3IHJlY29yZFxuICAgKiBAcGFyYW0ge3N0cmluZ30gdGFibGVOYW1lIC0gVGhlIG5hbWUgb2YgdGhlIHRhYmxlXG4gICAqIEBwYXJhbSB7c3RyaW5nfG51bWJlcn0gaWQgLSBUaGUgSUQgb2YgdGhlIHJlY29yZFxuICAgKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIGFueT59IG1vZGVsIC0gVGhlIG1vZGVsIHRvIGNyZWF0ZVxuICAgKiBAcGFyYW0gey4uLmFueVtdfSBhcmdzIC0gQWRkaXRpb25hbCBhcmd1bWVudHNcbiAgICogQHJldHVybiB7UHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+Pn0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gdGhlIGNyZWF0ZWQgcmVjb3JkXG4gICAqL1xuICBvdmVycmlkZSBhc3luYyBjcmVhdGUoXG4gICAgdGFibGVOYW1lOiBzdHJpbmcsXG4gICAgaWQ6IHN0cmluZyB8IG51bWJlcixcbiAgICBtb2RlbDogUmVjb3JkPHN0cmluZywgYW55PixcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gICAgLi4uYXJnczogYW55W11cbiAgKTogUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+PiB7XG4gICAgY29uc3QgbTogQ29uc3RydWN0b3I8TW9kZWw+ID0gdGFibGVOYW1lIGFzIHVua25vd24gYXMgQ29uc3RydWN0b3I8TW9kZWw+O1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXBvID0gdGhpcy5kYXRhU291cmNlLmdldFJlcG9zaXRvcnkobSk7XG4gICAgICByZXR1cm4gYXdhaXQgcmVwby5zYXZlKG1vZGVsKTtcbiAgICB9IGNhdGNoIChlOiB1bmtub3duKSB7XG4gICAgICB0aHJvdyB0aGlzLnBhcnNlRXJyb3IoZSBhcyBFcnJvcik7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZWFkcyBhIHJlY29yZCBmcm9tIHRoZSBkYXRhYmFzZVxuICAgKiBAc3VtbWFyeSBBYnN0cmFjdCBtZXRob2QgdGhhdCBtdXN0IGJlIGltcGxlbWVudGVkIHRvIHJlYWQgYSByZWNvcmRcbiAgICogQHBhcmFtIHtzdHJpbmd9IHRhYmxlTmFtZSAtIFRoZSBuYW1lIG9mIHRoZSB0YWJsZVxuICAgKiBAcGFyYW0ge3N0cmluZ3xudW1iZXJ9IGlkIC0gVGhlIElEIG9mIHRoZSByZWNvcmRcbiAgICogQHBhcmFtIHtzdHJpbmd9IHBrIC0gcHJpbWFyeSBrZXkgY29sdW1cbiAgICogQHJldHVybiB7UHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+Pn0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gdGhlIHJlYWQgcmVjb3JkXG4gICAqL1xuICBvdmVycmlkZSBhc3luYyByZWFkKFxuICAgIHRhYmxlTmFtZTogc3RyaW5nLFxuICAgIGlkOiBzdHJpbmcgfCBudW1iZXIsXG4gICAgcGs6IHN0cmluZ1xuICApOiBQcm9taXNlPFJlY29yZDxzdHJpbmcsIGFueT4+IHtcbiAgICBjb25zdCBtOiBDb25zdHJ1Y3RvcjxNb2RlbD4gPSB0YWJsZU5hbWUgYXMgdW5rbm93biBhcyBDb25zdHJ1Y3RvcjxNb2RlbD47XG4gICAgbGV0IHJlc3VsdDogYW55O1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXBvID0gdGhpcy5kYXRhU291cmNlLmdldFJlcG9zaXRvcnkobSk7XG4gICAgICBjb25zdCBxOiBGaW5kT25lT3B0aW9ucyA9IHtcbiAgICAgICAgd2hlcmU6IHtcbiAgICAgICAgICBbcGtdOiBpZCxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgICByZXN1bHQgPSAoYXdhaXQgcmVwby5maW5kT25lKHEpKSBhcyBSZWNvcmQ8c3RyaW5nLCBhbnk+O1xuICAgIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICAgIHRocm93IHRoaXMucGFyc2VFcnJvcihlIGFzIEVycm9yKTtcbiAgICB9XG4gICAgaWYgKCFyZXN1bHQpXG4gICAgICB0aHJvdyBuZXcgTm90Rm91bmRFcnJvcihcbiAgICAgICAgYFJlY29yZCB3aXRoIGlkOiAke2lkfSBub3QgZm91bmQgaW4gdGFibGUgJHt0eXBlb2YgdGFibGVOYW1lID09PSBcInN0cmluZ1wiID8gdGFibGVOYW1lIDogUmVwb3NpdG9yeS50YWJsZSh0YWJsZU5hbWUpfWBcbiAgICAgICk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gVXBkYXRlcyBhIHJlY29yZCBpbiB0aGUgZGF0YWJhc2VcbiAgICogQHN1bW1hcnkgQWJzdHJhY3QgbWV0aG9kIHRoYXQgbXVzdCBiZSBpbXBsZW1lbnRlZCB0byB1cGRhdGUgYSByZWNvcmRcbiAgICogQHBhcmFtIHtzdHJpbmd9IHRhYmxlTmFtZSAtIFRoZSBuYW1lIG9mIHRoZSB0YWJsZVxuICAgKiBAcGFyYW0ge3N0cmluZ3xudW1iZXJ9IGlkIC0gVGhlIElEIG9mIHRoZSByZWNvcmRcbiAgICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCBhbnk+fSBtb2RlbCAtIFRoZSBtb2RlbCB0byB1cGRhdGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IHBrIC0gQWRkaXRpb25hbCBhcmd1bWVudHNcbiAgICogQHJldHVybiBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byB0aGUgdXBkYXRlZCByZWNvcmRcbiAgICovXG4gIG92ZXJyaWRlIGFzeW5jIHVwZGF0ZShcbiAgICB0YWJsZU5hbWU6IHN0cmluZyxcbiAgICBpZDogc3RyaW5nIHwgbnVtYmVyLFxuICAgIG1vZGVsOiBSZWNvcmQ8c3RyaW5nLCBhbnk+LFxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApOiBQcm9taXNlPFJlY29yZDxzdHJpbmcsIGFueT4+IHtcbiAgICBjb25zdCBtOiBDb25zdHJ1Y3RvcjxNb2RlbD4gPSB0YWJsZU5hbWUgYXMgdW5rbm93biBhcyBDb25zdHJ1Y3RvcjxNb2RlbD47XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlcG8gPSB0aGlzLmRhdGFTb3VyY2UuZ2V0UmVwb3NpdG9yeShtKTtcbiAgICAgIHJldHVybiByZXBvLnNhdmUobW9kZWwpO1xuICAgIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICAgIHRocm93IHRoaXMucGFyc2VFcnJvcihlIGFzIEVycm9yKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIERlbGV0ZXMgYSByZWNvcmQgZnJvbSB0aGUgZGF0YWJhc2VcbiAgICogQHN1bW1hcnkgQWJzdHJhY3QgbWV0aG9kIHRoYXQgbXVzdCBiZSBpbXBsZW1lbnRlZCB0byBkZWxldGUgYSByZWNvcmRcbiAgICogQHBhcmFtIHtzdHJpbmd9IHRhYmxlTmFtZSAtIFRoZSBuYW1lIG9mIHRoZSB0YWJsZVxuICAgKiBAcGFyYW0ge3N0cmluZ3xudW1iZXJ9IGlkIC0gVGhlIElEIG9mIHRoZSByZWNvcmRcbiAgICogQHBhcmFtIHtzdHJpbmd9IHBrIC0gQWRkaXRpb25hbCBhcmd1bWVudHNcbiAgICogQHJldHVybiBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byB0aGUgZGVsZXRlZCByZWNvcmRcbiAgICovXG4gIG92ZXJyaWRlIGFzeW5jIGRlbGV0ZShcbiAgICB0YWJsZU5hbWU6IHN0cmluZyxcbiAgICBpZDogc3RyaW5nIHwgbnVtYmVyLFxuICAgIHBrOiBzdHJpbmcsXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICAgIC4uLmFyZ3M6IGFueVtdXG4gICk6IFByb21pc2U8UmVjb3JkPHN0cmluZywgYW55Pj4ge1xuICAgIGNvbnN0IG06IENvbnN0cnVjdG9yPE1vZGVsPiA9IHRhYmxlTmFtZSBhcyB1bmtub3duIGFzIENvbnN0cnVjdG9yPE1vZGVsPjtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVwbyA9IHRoaXMuZGF0YVNvdXJjZS5nZXRSZXBvc2l0b3J5KG0pO1xuICAgICAgY29uc3QgbW9kZWwgPSBhd2FpdCB0aGlzLnJlYWQodGFibGVOYW1lLCBpZCwgcGspO1xuICAgICAgY29uc3QgcmVzID0gYXdhaXQgcmVwby5kZWxldGUoaWQpO1xuICAgICAgcmV0dXJuIG1vZGVsO1xuICAgIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICAgIHRocm93IHRoaXMucGFyc2VFcnJvcihlIGFzIEVycm9yKTtcbiAgICB9XG4gIH1cblxuICBvdmVycmlkZSBhc3luYyBjcmVhdGVBbGwoXG4gICAgdGFibGVOYW1lOiBzdHJpbmcsXG4gICAgaWQ6IChzdHJpbmcgfCBudW1iZXIpW10sXG4gICAgbW9kZWw6IFJlY29yZDxzdHJpbmcsIGFueT5bXSxcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gICAgLi4uYXJnczogYW55W11cbiAgKTogUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+W10+IHtcbiAgICBjb25zdCBtOiBDb25zdHJ1Y3RvcjxNb2RlbD4gPSB0YWJsZU5hbWUgYXMgdW5rbm93biBhcyBDb25zdHJ1Y3RvcjxNb2RlbD47XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlcG8gPSB0aGlzLmRhdGFTb3VyY2UuZ2V0UmVwb3NpdG9yeShtKTtcbiAgICAgIGNvbnN0IHJlc3VsdDogSW5zZXJ0UmVzdWx0ID0gYXdhaXQgcmVwby5pbnNlcnQobW9kZWwpO1xuICAgICAgcmV0dXJuIHRoaXMucmVhZEFsbChcbiAgICAgICAgdGFibGVOYW1lLFxuICAgICAgICByZXN1bHQuaWRlbnRpZmllcnMubWFwKChpZCkgPT4gaWQuaWQpLFxuICAgICAgICBcImlkXCJcbiAgICAgICk7XG4gICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgdGhyb3cgdGhpcy5wYXJzZUVycm9yKGUgYXMgRXJyb3IpO1xuICAgIH1cbiAgfVxuXG4gIG92ZXJyaWRlIGFzeW5jIHJlYWRBbGwoXG4gICAgdGFibGVOYW1lOiBzdHJpbmcsXG4gICAgaWQ6IChzdHJpbmcgfCBudW1iZXIgfCBiaWdpbnQpW10sXG4gICAgcGs6IHN0cmluZyxcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gICAgLi4uYXJnczogYW55W11cbiAgKTogUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+W10+IHtcbiAgICBpZiAoIWlkLmxlbmd0aCkgcmV0dXJuIFtdO1xuXG4gICAgY29uc3QgbTogQ29uc3RydWN0b3I8TW9kZWw+ID0gdGFibGVOYW1lIGFzIHVua25vd24gYXMgQ29uc3RydWN0b3I8TW9kZWw+O1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXBvID0gdGhpcy5kYXRhU291cmNlLmdldFJlcG9zaXRvcnkobSk7XG4gICAgICByZXR1cm4gcmVwby5maW5kQnkoeyBbcGtdOiBJbihpZCkgfSk7XG4gICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgdGhyb3cgdGhpcy5wYXJzZUVycm9yKGUgYXMgRXJyb3IpO1xuICAgIH1cbiAgfVxuXG4gIG92ZXJyaWRlIGFzeW5jIHVwZGF0ZUFsbChcbiAgICB0YWJsZU5hbWU6IHN0cmluZyxcbiAgICBpZHM6IHN0cmluZ1tdIHwgbnVtYmVyW10sXG4gICAgbW9kZWw6IFJlY29yZDxzdHJpbmcsIGFueT5bXSxcbiAgICBwazogc3RyaW5nLFxuICAgIC4uLmFyZ3M6IGFueVtdXG4gICk6IFByb21pc2U8UmVjb3JkPHN0cmluZywgYW55PltdPiB7XG4gICAgY29uc3QgcmVzdWx0ID0gW107XG4gICAgZm9yIChjb25zdCBtIG9mIG1vZGVsKSB7XG4gICAgICByZXN1bHQucHVzaChhd2FpdCB0aGlzLnVwZGF0ZSh0YWJsZU5hbWUsIG1bcGtdLCBtLCAuLi5hcmdzKSk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBvdmVycmlkZSBhc3luYyBkZWxldGVBbGwoXG4gICAgdGFibGVOYW1lOiBzdHJpbmcsXG4gICAgaWRzOiAoc3RyaW5nIHwgbnVtYmVyIHwgYmlnaW50KVtdLFxuICAgIHBrOiBzdHJpbmcsXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICAgIC4uLmFyZ3M6IGFueVtdXG4gICk6IFByb21pc2U8UmVjb3JkPHN0cmluZywgYW55PltdPiB7XG4gICAgaWYgKCFpZHMubGVuZ3RoKSByZXR1cm4gW107XG4gICAgY29uc3QgbTogQ29uc3RydWN0b3I8TW9kZWw+ID0gdGFibGVOYW1lIGFzIHVua25vd24gYXMgQ29uc3RydWN0b3I8TW9kZWw+O1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXBvID0gdGhpcy5kYXRhU291cmNlLmdldFJlcG9zaXRvcnkobSk7XG4gICAgICBjb25zdCBtb2RlbHMgPSBhd2FpdCB0aGlzLnJlYWRBbGwodGFibGVOYW1lLCBpZHMsIHBrKTtcbiAgICAgIGF3YWl0IHJlcG8uZGVsZXRlKGlkcyk7XG4gICAgICByZXR1cm4gbW9kZWxzO1xuICAgIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICAgIHRocm93IHRoaXMucGFyc2VFcnJvcihlIGFzIEVycm9yKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFBhcnNlcyBhbiBlcnJvciBhbmQgY29udmVydHMgaXQgdG8gYSBCYXNlRXJyb3JcbiAgICogQHN1bW1hcnkgQ29udmVydHMgdmFyaW91cyBlcnJvciB0eXBlcyB0byBhcHByb3ByaWF0ZSBCYXNlRXJyb3Igc3VidHlwZXNcbiAgICogQHBhcmFtIHtFcnJvcnxzdHJpbmd9IGVyciAtIFRoZSBlcnJvciB0byBwYXJzZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gW3JlYXNvbl0gLSBPcHRpb25hbCByZWFzb24gZm9yIHRoZSBlcnJvclxuICAgKiBAcmV0dXJuIHtCYXNlRXJyb3J9IFRoZSBwYXJzZWQgZXJyb3IgYXMgYSBCYXNlRXJyb3JcbiAgICovXG4gIHBhcnNlRXJyb3IoZXJyOiBFcnJvciB8IHN0cmluZywgcmVhc29uPzogc3RyaW5nKTogQmFzZUVycm9yIHtcbiAgICByZXR1cm4gVHlwZU9STUFkYXB0ZXIucGFyc2VFcnJvcihlcnIsIHJlYXNvbik7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENoZWNrcyBpZiBhbiBhdHRyaWJ1dGUgaXMgcmVzZXJ2ZWRcbiAgICogQHN1bW1hcnkgRGV0ZXJtaW5lcyBpZiBhbiBhdHRyaWJ1dGUgbmFtZSBpcyByZXNlcnZlZCBpbiBQb3N0Z3JlU1FMXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBhdHRyIC0gVGhlIGF0dHJpYnV0ZSBuYW1lIHRvIGNoZWNrXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IFRydWUgaWYgdGhlIGF0dHJpYnV0ZSBpcyByZXNlcnZlZCwgZmFsc2Ugb3RoZXJ3aXNlXG4gICAqL1xuICBwcm90ZWN0ZWQgb3ZlcnJpZGUgaXNSZXNlcnZlZChhdHRyOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gISFhdHRyLm1hdGNoKHJlc2VydmVkQXR0cmlidXRlcyk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFN0YXRpYyBtZXRob2QgdG8gcGFyc2UgYW4gZXJyb3IgYW5kIGNvbnZlcnQgaXQgdG8gYSBCYXNlRXJyb3JcbiAgICogQHN1bW1hcnkgQ29udmVydHMgdmFyaW91cyBlcnJvciB0eXBlcyB0byBhcHByb3ByaWF0ZSBCYXNlRXJyb3Igc3VidHlwZXMgYmFzZWQgb24gUG9zdGdyZVNRTCBlcnJvciBjb2RlcyBhbmQgbWVzc2FnZXNcbiAgICogQHBhcmFtIHtFcnJvcnxzdHJpbmd9IGVyciAtIFRoZSBlcnJvciB0byBwYXJzZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gW3JlYXNvbl0gLSBPcHRpb25hbCByZWFzb24gZm9yIHRoZSBlcnJvclxuICAgKiBAcmV0dXJuIHtCYXNlRXJyb3J9IFRoZSBwYXJzZWQgZXJyb3IgYXMgYSBCYXNlRXJyb3JcbiAgICogQG1lcm1haWRcbiAgICogc2VxdWVuY2VEaWFncmFtXG4gICAqICAgcGFydGljaXBhbnQgQ2FsbGVyXG4gICAqICAgcGFydGljaXBhbnQgcGFyc2VFcnJvclxuICAgKiAgIHBhcnRpY2lwYW50IEVycm9yVHlwZXNcbiAgICpcbiAgICogICBDYWxsZXItPj5wYXJzZUVycm9yOiBlcnIsIHJlYXNvblxuICAgKiAgIE5vdGUgb3ZlciBwYXJzZUVycm9yOiBDaGVjayBpZiBlcnIgaXMgYWxyZWFkeSBhIEJhc2VFcnJvclxuICAgKiAgIGFsdCBlcnIgaXMgQmFzZUVycm9yXG4gICAqICAgICBwYXJzZUVycm9yLS0+PkNhbGxlcjogcmV0dXJuIGVyclxuICAgKiAgIGVsc2UgZXJyIGlzIHN0cmluZ1xuICAgKiAgICAgTm90ZSBvdmVyIHBhcnNlRXJyb3I6IEV4dHJhY3QgY29kZSBmcm9tIHN0cmluZ1xuICAgKiAgICAgYWx0IGNvZGUgbWF0Y2hlcyBcImR1cGxpY2F0ZSBrZXl8YWxyZWFkeSBleGlzdHNcIlxuICAgKiAgICAgICBwYXJzZUVycm9yLT4+RXJyb3JUeXBlczogbmV3IENvbmZsaWN0RXJyb3IoY29kZSlcbiAgICogICAgICAgRXJyb3JUeXBlcy0tPj5DYWxsZXI6IENvbmZsaWN0RXJyb3JcbiAgICogICAgIGVsc2UgY29kZSBtYXRjaGVzIFwiZG9lcyBub3QgZXhpc3R8bm90IGZvdW5kXCJcbiAgICogICAgICAgcGFyc2VFcnJvci0+PkVycm9yVHlwZXM6IG5ldyBOb3RGb3VuZEVycm9yKGNvZGUpXG4gICAqICAgICAgIEVycm9yVHlwZXMtLT4+Q2FsbGVyOiBOb3RGb3VuZEVycm9yXG4gICAqICAgICBlbmRcbiAgICogICBlbHNlIGVyciBoYXMgY29kZSBwcm9wZXJ0eVxuICAgKiAgICAgTm90ZSBvdmVyIHBhcnNlRXJyb3I6IEV4dHJhY3QgY29kZSBhbmQgcmVhc29uXG4gICAqICAgZWxzZVxuICAgKiAgICAgTm90ZSBvdmVyIHBhcnNlRXJyb3I6IFVzZSBlcnIubWVzc2FnZSBhcyBjb2RlXG4gICAqICAgZW5kXG4gICAqXG4gICAqICAgTm90ZSBvdmVyIHBhcnNlRXJyb3I6IFN3aXRjaCBvbiBQb3N0Z3JlU1FMIGVycm9yIGNvZGVcbiAgICogICBhbHQgY29kZSBpcyAyMzUwNSAodW5pcXVlX3Zpb2xhdGlvbilcbiAgICogICAgIHBhcnNlRXJyb3ItPj5FcnJvclR5cGVzOiBuZXcgQ29uZmxpY3RFcnJvcihyZWFzb24pXG4gICAqICAgICBFcnJvclR5cGVzLS0+PkNhbGxlcjogQ29uZmxpY3RFcnJvclxuICAgKiAgIGVsc2UgY29kZSBpcyAyMzUwMyAoZm9yZWlnbl9rZXlfdmlvbGF0aW9uKVxuICAgKiAgICAgcGFyc2VFcnJvci0+PkVycm9yVHlwZXM6IG5ldyBDb25mbGljdEVycm9yKHJlYXNvbilcbiAgICogICAgIEVycm9yVHlwZXMtLT4+Q2FsbGVyOiBDb25mbGljdEVycm9yXG4gICAqICAgZWxzZSBjb2RlIGlzIDQyUDAxICh1bmRlZmluZWRfdGFibGUpXG4gICAqICAgICBwYXJzZUVycm9yLT4+RXJyb3JUeXBlczogbmV3IE5vdEZvdW5kRXJyb3IocmVhc29uKVxuICAgKiAgICAgRXJyb3JUeXBlcy0tPj5DYWxsZXI6IE5vdEZvdW5kRXJyb3JcbiAgICogICBlbHNlIGNvZGUgaXMgNDI3MDMgKHVuZGVmaW5lZF9jb2x1bW4pXG4gICAqICAgICBwYXJzZUVycm9yLT4+RXJyb3JUeXBlczogbmV3IE5vdEZvdW5kRXJyb3IocmVhc29uKVxuICAgKiAgICAgRXJyb3JUeXBlcy0tPj5DYWxsZXI6IE5vdEZvdW5kRXJyb3JcbiAgICogICBlbHNlIGNvZGUgaXMgNDJQMDcgKGR1cGxpY2F0ZV90YWJsZSlcbiAgICogICAgIHBhcnNlRXJyb3ItPj5FcnJvclR5cGVzOiBuZXcgQ29uZmxpY3RFcnJvcihyZWFzb24pXG4gICAqICAgICBFcnJvclR5cGVzLS0+PkNhbGxlcjogQ29uZmxpY3RFcnJvclxuICAgKiAgIGVsc2UgY29kZSBpcyA0MlAxNiAoaW52YWxpZF90YWJsZV9kZWZpbml0aW9uKVxuICAgKiAgICAgcGFyc2VFcnJvci0+PkVycm9yVHlwZXM6IG5ldyBJbmRleEVycm9yKGVycilcbiAgICogICAgIEVycm9yVHlwZXMtLT4+Q2FsbGVyOiBJbmRleEVycm9yXG4gICAqICAgZWxzZSBjb2RlIG1hdGNoZXMgXCJFQ09OTlJFRlVTRURcIlxuICAgKiAgICAgcGFyc2VFcnJvci0+PkVycm9yVHlwZXM6IG5ldyBDb25uZWN0aW9uRXJyb3IoZXJyKVxuICAgKiAgICAgRXJyb3JUeXBlcy0tPj5DYWxsZXI6IENvbm5lY3Rpb25FcnJvclxuICAgKiAgIGVsc2VcbiAgICogICAgIHBhcnNlRXJyb3ItPj5FcnJvclR5cGVzOiBuZXcgSW50ZXJuYWxFcnJvcihlcnIpXG4gICAqICAgICBFcnJvclR5cGVzLS0+PkNhbGxlcjogSW50ZXJuYWxFcnJvclxuICAgKiAgIGVuZFxuICAgKi9cbiAgcHJvdGVjdGVkIHN0YXRpYyBwYXJzZUVycm9yKGVycjogRXJyb3IgfCBzdHJpbmcsIHJlYXNvbj86IHN0cmluZyk6IEJhc2VFcnJvciB7XG4gICAgaWYgKGVyciBpbnN0YW5jZW9mIEJhc2VFcnJvcikgcmV0dXJuIGVyciBhcyBhbnk7XG4gICAgY29uc3QgY29kZTogc3RyaW5nID0gdHlwZW9mIGVyciA9PT0gXCJzdHJpbmdcIiA/IGVyciA6IGVyci5tZXNzYWdlO1xuXG4gICAgaWYgKGNvZGUubWF0Y2goL2R1cGxpY2F0ZSBrZXl8YWxyZWFkeSBleGlzdHMvZykpXG4gICAgICByZXR1cm4gbmV3IENvbmZsaWN0RXJyb3IoY29kZSk7XG4gICAgaWYgKGNvZGUubWF0Y2goL2RvZXMgbm90IGV4aXN0fG5vdCBmb3VuZC9nKSkgcmV0dXJuIG5ldyBOb3RGb3VuZEVycm9yKGNvZGUpO1xuXG4gICAgLy8gUG9zdGdyZVNRTCBlcnJvciBjb2RlczogaHR0cHM6Ly93d3cucG9zdGdyZXNxbC5vcmcvZG9jcy9jdXJyZW50L2VycmNvZGVzLWFwcGVuZGl4Lmh0bWxcbiAgICBzd2l0Y2ggKGNvZGUudG9TdHJpbmcoKSkge1xuICAgICAgLy8gSW50ZWdyaXR5IGNvbnN0cmFpbnQgdmlvbGF0aW9uc1xuICAgICAgY2FzZSBcIjIzNTA1XCI6IC8vIHVuaXF1ZV92aW9sYXRpb25cbiAgICAgIGNhc2UgXCIyMzUwM1wiOiAvLyBmb3JlaWduX2tleV92aW9sYXRpb25cbiAgICAgIGNhc2UgXCI0MlAwN1wiOiAvLyBkdXBsaWNhdGVfdGFibGVcbiAgICAgICAgcmV0dXJuIG5ldyBDb25mbGljdEVycm9yKHJlYXNvbiBhcyBzdHJpbmcpO1xuXG4gICAgICAvLyBPYmplY3Qgbm90IGZvdW5kIGVycm9yc1xuICAgICAgY2FzZSBcIjQyUDAxXCI6IC8vIHVuZGVmaW5lZF90YWJsZVxuICAgICAgY2FzZSBcIjQyNzAzXCI6IC8vIHVuZGVmaW5lZF9jb2x1bW5cbiAgICAgICAgcmV0dXJuIG5ldyBOb3RGb3VuZEVycm9yKHJlYXNvbiBhcyBzdHJpbmcpO1xuXG4gICAgICAvLyBJbnZhbGlkIG9iamVjdCBkZWZpbml0aW9uXG4gICAgICBjYXNlIFwiNDJQMTZcIjogLy8gaW52YWxpZF90YWJsZV9kZWZpbml0aW9uXG4gICAgICAgIHJldHVybiBuZXcgSW5kZXhFcnJvcihlcnIpO1xuXG4gICAgICAvLyBDb25uZWN0aW9uIGVycm9yc1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgaWYgKGNvZGUudG9TdHJpbmcoKS5tYXRjaCgvRUNPTk5SRUZVU0VEL2cpKVxuICAgICAgICAgIHJldHVybiBuZXcgQ29ubmVjdGlvbkVycm9yKGVycik7XG4gICAgICAgIHJldHVybiBuZXcgSW50ZXJuYWxFcnJvcihlcnIpO1xuICAgIH1cbiAgfVxuXG4gIHN0YXRpYyBhc3luYyBjb25uZWN0KGNvbmZpZzogRGF0YVNvdXJjZU9wdGlvbnMpOiBQcm9taXNlPERhdGFTb3VyY2U+IHtcbiAgICBjb25zdCBjb24gPSBuZXcgRGF0YVNvdXJjZShjb25maWcpO1xuICAgIGlmICghY29uLmlzSW5pdGlhbGl6ZWQpIGF3YWl0IGNvbi5pbml0aWFsaXplKCk7XG4gICAgcmV0dXJuIGNvbjtcbiAgfVxuXG4gIHN0YXRpYyBhc3luYyBjcmVhdGVEYXRhYmFzZShcbiAgICBkYXRhU291cmNlOiBEYXRhU291cmNlLFxuICAgIGRiTmFtZTogc3RyaW5nXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGxvZyA9IExvZ2dpbmcuZm9yKHRoaXMuY3JlYXRlRGF0YWJhc2UpO1xuICAgIGxvZy52ZXJib3NlKGBDcmVhdGluZyBkYXRhYmFzZSAke2RiTmFtZX1gKTtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgZGF0YVNvdXJjZS5xdWVyeShgQ1JFQVRFIERBVEFCQVNFICR7ZGJOYW1lfWApO1xuICAgICAgbG9nLmluZm8oYENyZWF0ZWQgZGF0YWJhc2UgJHtkYk5hbWV9YCk7XG4gICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgdGhyb3cgdGhpcy5wYXJzZUVycm9yKGUgYXMgRXJyb3IpO1xuICAgIH1cbiAgfVxuXG4gIHN0YXRpYyBhc3luYyBjcmVhdGVOb3RpZnlGdW5jdGlvbihcbiAgICBkYXRhU291cmNlOiBEYXRhU291cmNlLFxuICAgIHVzZXI6IHN0cmluZ1xuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBsb2cgPSBMb2dnaW5nLmZvcih0aGlzLmNyZWF0ZU5vdGlmeUZ1bmN0aW9uKTtcbiAgICBsb2cudmVyYm9zZShgQ3JlYXRpbmcgbm90aWZ5IGZ1bmN0aW9uYCk7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IGRhdGFTb3VyY2UucXVlcnkoXG4gICAgICAgIGBDUkVBVEUgT1IgUkVQTEFDRSBGVU5DVElPTiBub3RpZnlfdGFibGVfY2hhbmdlcygpXG5SRVRVUk5TIHRyaWdnZXIgQVMgJCRcbkJFR0lOXG4gICAgUEVSRk9STSBwZ19ub3RpZnkoXG4gICAgICAgICd0YWJsZV9jaGFuZ2VzJyxcbiAgICAgICAganNvbl9idWlsZF9vYmplY3QoXG4gICAgICAgICAgICAndGFibGUnLCBUR19UQUJMRV9OQU1FLFxuICAgICAgICAgICAgJ2FjdGlvbicsIFRHX09QLFxuICAgICAgICAgICAgJ2RhdGEnLCByb3dfdG9fanNvbihORVcpLFxuICAgICAgICAgICAgJ29sZF9kYXRhJywgcm93X3RvX2pzb24oT0xEKVxuICAgICAgICApOjp0ZXh0XG4gICAgKTtcbiAgICBSRVRVUk4gTkVXO1xuRU5EO1xuJCQgTEFOR1VBR0UgcGxwZ3NxbCBTRUNVUklUWSBERUZJTkVSXG47YFxuICAgICAgKTtcbiAgICAgIGF3YWl0IGRhdGFTb3VyY2UucXVlcnkoXG4gICAgICAgIGBBTFRFUiBGVU5DVElPTiBub3RpZnlfdGFibGVfY2hhbmdlcygpIE9XTkVSIFRPICR7dXNlcn07YFxuICAgICAgKTtcbiAgICAgIGF3YWl0IGRhdGFTb3VyY2UucXVlcnkoYFxuICAgICAgICAgICAgR1JBTlQgRVhFQ1VURSBPTiBGVU5DVElPTiBub3RpZnlfdGFibGVfY2hhbmdlcygpIFRPIHB1YmxpYztcbiAgICAgICAgYCk7XG4gICAgICBsb2cuaW5mbyhgQ3JlYXRlZCBub3RpZnkgZnVuY3Rpb25gKTtcbiAgICB9IGNhdGNoIChlOiB1bmtub3duKSB7XG4gICAgICB0aHJvdyB0aGlzLnBhcnNlRXJyb3IoZSBhcyBFcnJvcik7XG4gICAgfVxuICB9XG5cbiAgc3RhdGljIGFzeW5jIGRlbGV0ZURhdGFiYXNlKFxuICAgIGRhdGFTb3VyY2U6IERhdGFTb3VyY2UsXG4gICAgZGJOYW1lOiBzdHJpbmcsXG4gICAgdXNlcj86IHN0cmluZ1xuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0cnkge1xuICAgICAgaWYgKHVzZXIpIGF3YWl0IGRhdGFTb3VyY2UucXVlcnkoYERST1AgT1dORUQgQlkgJHt1c2VyfSBDQVNDQURFO2ApO1xuICAgICAgYXdhaXQgZGF0YVNvdXJjZS5xdWVyeShgRFJPUCBEQVRBQkFTRSAke2RiTmFtZX1gKTtcbiAgICB9IGNhdGNoIChlOiB1bmtub3duKSB7XG4gICAgICB0aHJvdyB0aGlzLnBhcnNlRXJyb3IoZSBhcyBFcnJvcik7XG4gICAgfVxuICB9XG5cbiAgc3RhdGljIGFzeW5jIGNyZWF0ZVVzZXIoXG4gICAgZGF0YVNvdXJjZTogRGF0YVNvdXJjZSxcbiAgICBkYk5hbWU6IHN0cmluZyxcbiAgICB1c2VyOiBzdHJpbmcsXG4gICAgcGFzc3dvcmQ6IHN0cmluZ1xuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgZGF0YVNvdXJjZS5xdWVyeShgQ1JFQVRFIFVTRVIgJHt1c2VyfSBXSVRIIFBBU1NXT1JEICcke3Bhc3N3b3JkfSdgKTtcbiAgICAgIGF3YWl0IGRhdGFTb3VyY2UucXVlcnkoYEdSQU5UIENPTk5FQ1QgT04gREFUQUJBU0UgJHtkYk5hbWV9IFRPICR7dXNlcn1gKTtcblxuICAgICAgYXdhaXQgZGF0YVNvdXJjZS5xdWVyeShgR1JBTlQgVVNBR0UgT04gU0NIRU1BIHB1YmxpYyBUTyAke3VzZXJ9YCk7XG4gICAgICBhd2FpdCBkYXRhU291cmNlLnF1ZXJ5KGBHUkFOVCBDUkVBVEUgT04gU0NIRU1BIHB1YmxpYyBUTyAke3VzZXJ9YCk7XG4gICAgICBhd2FpdCBkYXRhU291cmNlLnF1ZXJ5KFxuICAgICAgICBgR1JBTlQgQUxMIFBSSVZJTEVHRVMgT04gQUxMIFRBQkxFUyBJTiBTQ0hFTUEgcHVibGljIFRPICR7dXNlcn1gXG4gICAgICApO1xuICAgICAgYXdhaXQgZGF0YVNvdXJjZS5xdWVyeShcbiAgICAgICAgYEdSQU5UIEFMTCBQUklWSUxFR0VTIE9OIEFMTCBTRVFVRU5DRVMgSU4gU0NIRU1BIHB1YmxpYyBUTyAke3VzZXJ9YFxuICAgICAgKTtcbiAgICAgIGF3YWl0IGRhdGFTb3VyY2UucXVlcnkoXG4gICAgICAgIGBHUkFOVCBBTEwgUFJJVklMRUdFUyBPTiBBTEwgRlVOQ1RJT05TIElOIFNDSEVNQSBwdWJsaWMgVE8gJHt1c2VyfWBcbiAgICAgICk7XG4gICAgICBhd2FpdCBkYXRhU291cmNlLnF1ZXJ5KFxuICAgICAgICBgQUxURVIgREVGQVVMVCBQUklWSUxFR0VTIElOIFNDSEVNQSBwdWJsaWMgR1JBTlQgQUxMIFBSSVZJTEVHRVMgT04gVEFCTEVTIFRPICR7dXNlcn1gXG4gICAgICApO1xuICAgICAgYXdhaXQgZGF0YVNvdXJjZS5xdWVyeShcbiAgICAgICAgYEFMVEVSIERFRkFVTFQgUFJJVklMRUdFUyBJTiBTQ0hFTUEgcHVibGljIEdSQU5UIEFMTCBQUklWSUxFR0VTIE9OIFNFUVVFTkNFUyBUTyAke3VzZXJ9YFxuICAgICAgKTtcbiAgICB9IGNhdGNoIChlOiB1bmtub3duKSB7XG4gICAgICB0aHJvdyB0aGlzLnBhcnNlRXJyb3IoZSBhcyBFcnJvcik7XG4gICAgfVxuICB9XG5cbiAgc3RhdGljIGFzeW5jIGRlbGV0ZVVzZXIoXG4gICAgY2xpZW50OiBEYXRhU291cmNlLFxuICAgIHVzZXI6IHN0cmluZyxcbiAgICBhZG1pbjogc3RyaW5nXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBjbGllbnQucXVlcnkoYFJFQVNTSUdOIE9XTkVEIEJZICR7dXNlcn0gVE8gJHthZG1pbn1gKTtcbiAgICAgIGF3YWl0IGNsaWVudC5xdWVyeShcbiAgICAgICAgYFJFVk9LRSBBTEwgT04gQUxMIFRBQkxFUyBJTiBTQ0hFTUEgcHVibGljIEZST00gJHt1c2VyfWBcbiAgICAgICk7XG4gICAgICBhd2FpdCBjbGllbnQucXVlcnkoYFJFVk9LRSBBTEwgT04gU0NIRU1BIHB1YmxpYyBGUk9NICR7dXNlcn1gKTtcbiAgICAgIGF3YWl0IGNsaWVudC5xdWVyeShcbiAgICAgICAgYFJFVk9LRSBBTEwgUFJJVklMRUdFUyBPTiBBTEwgU0VRVUVOQ0VTIElOIFNDSEVNQSBwdWJsaWMgRlJPTSAke3VzZXJ9YFxuICAgICAgKTtcbiAgICAgIGF3YWl0IGNsaWVudC5xdWVyeShcbiAgICAgICAgYFJFVk9LRSBBTEwgUFJJVklMRUdFUyBPTiBBTEwgRlVOQ1RJT05TIElOIFNDSEVNQSBwdWJsaWMgRlJPTSAke3VzZXJ9YFxuICAgICAgKTtcbiAgICAgIGF3YWl0IGNsaWVudC5xdWVyeShcbiAgICAgICAgYEFMVEVSIERFRkFVTFQgUFJJVklMRUdFUyBGT1IgUk9MRSAke2FkbWlufSBJTiBTQ0hFTUEgcHVibGljIFJFVk9LRSBBTEwgT04gVEFCTEVTIEZST00gJHt1c2VyfWBcbiAgICAgICk7XG4gICAgICBhd2FpdCBjbGllbnQucXVlcnkoXG4gICAgICAgIGBBTFRFUiBERUZBVUxUIFBSSVZJTEVHRVMgRk9SIFJPTEUgJHthZG1pbn0gSU4gU0NIRU1BIHB1YmxpYyBSRVZPS0UgQUxMIE9OIFNFUVVFTkNFUyBGUk9NICR7dXNlcn07YFxuICAgICAgKTtcbiAgICAgIGF3YWl0IGNsaWVudC5xdWVyeShcbiAgICAgICAgYEFMVEVSIERFRkFVTFQgUFJJVklMRUdFUyBGT1IgUk9MRSAke2FkbWlufSBJTiBTQ0hFTUEgcHVibGljIFJFVk9LRSBBTEwgT04gRlVOQ1RJT05TIEZST00gJHt1c2VyfWBcbiAgICAgICk7XG4gICAgICBhd2FpdCBjbGllbnQucXVlcnkoYERST1AgT1dORUQgQlkgJHt1c2VyfSBDQVNDQURFYCk7XG4gICAgICBhd2FpdCBjbGllbnQucXVlcnkoYERST1AgVVNFUiBJRiBFWElTVFMgXCIke3VzZXJ9XCJgKTtcbiAgICB9IGNhdGNoIChlOiB1bmtub3duKSB7XG4gICAgICB0aHJvdyB0aGlzLnBhcnNlRXJyb3IoZSBhcyBFcnJvcik7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgcGFyc2VUeXBlVG9Qb3N0Z3JlcyhcbiAgICB0eXBlOiBzdHJpbmcsXG4gICAgaXNQazogYm9vbGVhbixcbiAgICBpc0ZrID0gZmFsc2VcbiAgKSB7XG4gICAgc3dpdGNoICh0eXBlLnRvTG93ZXJDYXNlKCkpIHtcbiAgICAgIGNhc2UgXCJzdHJpbmdcIjpcbiAgICAgICAgcmV0dXJuIGlzUGsgPyBcIlRFWFQgUFJJTUFSWSBLRVlcIiA6IGlzRmsgPyBcIlRFWFRcIiA6IFwiVkFSQ0hBUlwiO1xuICAgICAgY2FzZSBcIm51bWJlclwiOlxuICAgICAgICByZXR1cm4gaXNQayA/IFwiU0VSSUFMIFBSSU1BUlkgS0VZXCIgOiBcIklOVEVHRVJcIjtcbiAgICAgIGNhc2UgXCJib29sZWFuXCI6XG4gICAgICAgIHJldHVybiBcIkJPT0xFQU5cIjtcbiAgICAgIGNhc2UgXCJkYXRlXCI6XG4gICAgICAgIHJldHVybiBcIlRJTUVTVEFNUFwiO1xuICAgICAgY2FzZSBcImJpZ2ludFwiOlxuICAgICAgICByZXR1cm4gaXNQayA/IFwiQklHSU5UIFBSSU1BUlkgS0VZXCIgOiBcIkJJR0lOVFwiO1xuICAgICAgZGVmYXVsdDoge1xuICAgICAgICBjb25zdCBtID0gTW9kZWwuZ2V0KHR5cGUpO1xuICAgICAgICBpZiAobSkge1xuICAgICAgICAgIGNvbnN0IG1tID0gbmV3IG0oKTtcbiAgICAgICAgICBjb25zdCB0eXBlID0gUmVmbGVjdGlvbi5nZXRUeXBlRnJvbURlY29yYXRvcihcbiAgICAgICAgICAgIG1tLFxuICAgICAgICAgICAgZmluZFByaW1hcnlLZXkobW0pLmlkXG4gICAgICAgICAgKTtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgbW9kZWw6IG0sXG4gICAgICAgICAgICBwa1R5cGU6IHR5cGUsXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihgVW5zdXBwb3J0ZWQgdHlwZTogJHt0eXBlfWApO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgc3RhdGljIHBhcnNlVmFsaWRhdGlvblRvUG9zdGdyZXMoXG4gICAgcHJvcDogc3RyaW5nLFxuICAgIHR5cGU6IHN0cmluZyxcbiAgICBpc1BrOiBib29sZWFuLFxuICAgIGtleTogc3RyaW5nLFxuICAgIG9wdGlvbnM6IFZhbGlkYXRvck9wdGlvbnNcbiAgKSB7XG4gICAgc3dpdGNoIChrZXkpIHtcbiAgICAgIGNhc2UgVmFsaWRhdGlvbktleXMuUkVRVUlSRUQ6XG4gICAgICAgIHJldHVybiBcIk5PVCBOVUxMXCI7XG4gICAgICBjYXNlIFZhbGlkYXRpb25LZXlzLk1BWF9MRU5HVEg6XG4gICAgICAgIGlmIChpc1BrIHx8ICFvcHRpb25zIHx8IHR5cGUudG9Mb3dlckNhc2UoKSAhPT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgIHJldHVybiBcIlwiO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBgKCR7KG9wdGlvbnMgYXMgTWF4TGVuZ3RoVmFsaWRhdG9yT3B0aW9ucylbVmFsaWRhdGlvbktleXMuTUFYX0xFTkdUSF19KWA7XG4gICAgICBjYXNlIFZhbGlkYXRpb25LZXlzLk1JTl9MRU5HVEg6XG4gICAgICAgIHJldHVybiBgQ09OU1RSQUlOVCAke3Byb3B9X21pbl9sZW5ndGhfY2hlY2sgQ0hFQ0sgKExFTkdUSCgke3Byb3B9KSA+PSAkeyhvcHRpb25zIGFzIE1pbkxlbmd0aFZhbGlkYXRvck9wdGlvbnMpW1ZhbGlkYXRpb25LZXlzLk1JTl9MRU5HVEhdfSlgO1xuICAgICAgY2FzZSBWYWxpZGF0aW9uS2V5cy5QQVRURVJOOlxuICAgICAgY2FzZSBWYWxpZGF0aW9uS2V5cy5VUkw6XG4gICAgICBjYXNlIFZhbGlkYXRpb25LZXlzLkVNQUlMOlxuICAgICAgICByZXR1cm4gYENPTlNUUkFJTlQgJHtwcm9wfV9wYXR0ZXJuX2NoZWNrIENIRUNLICgke3Byb3B9IH4gJyR7Y29udmVydEpzUmVnZXhUb1Bvc3RncmVzKChvcHRpb25zIGFzIFBhdHRlcm5WYWxpZGF0b3JPcHRpb25zKVtWYWxpZGF0aW9uS2V5cy5QQVRURVJOXSBhcyBzdHJpbmcpfScpYDtcbiAgICAgIGNhc2UgVmFsaWRhdGlvbktleXMuVFlQRTpcbiAgICAgIGNhc2UgVmFsaWRhdGlvbktleXMuREFURTpcbiAgICAgICAgcmV0dXJuIFwiXCI7XG4gICAgICBjYXNlIFZhbGlkYXRpb25LZXlzLk1JTjpcbiAgICAgICAgcmV0dXJuIGBDT05TVFJBSU5UICR7cHJvcH1fJHtrZXl9X2NoZWNrIENIRUNLICgke3Byb3B9ID49ICR7KG9wdGlvbnMgYXMgTWluVmFsaWRhdG9yT3B0aW9ucylbVmFsaWRhdGlvbktleXMuTUlOXX0pYDtcbiAgICAgIGNhc2UgVmFsaWRhdGlvbktleXMuTUFYOlxuICAgICAgICByZXR1cm4gYENPTlNUUkFJTlQgJHtwcm9wfV8ke2tleX1fY2hlY2sgQ0hFQ0sgKCR7cHJvcH0gPD0gJHsob3B0aW9ucyBhcyBNYXhWYWxpZGF0b3JPcHRpb25zKVtWYWxpZGF0aW9uS2V5cy5NQVhdfSlgO1xuICAgICAgY2FzZSBWYWxpZGF0aW9uS2V5cy5QQVNTV09SRDpcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKGBVbnN1cHBvcnRlZCB0eXBlOiAke2tleX1gKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHN0YXRpYyBwYXJzZVJlbGF0aW9uc1RvUG9zdGdyZXMoXG4gICAgcHJvcDogc3RyaW5nLFxuICAgIGNsYXp6OiBDb25zdHJ1Y3RvcjxNb2RlbD4sXG4gICAgcGs6IHN0cmluZyxcbiAgICBrZXk6IFBlcnNpc3RlbmNlS2V5cyxcbiAgICBvcHRpb25zOiBSZWxhdGlvbnNNZXRhZGF0YVxuICApIHtcbiAgICBjb25zdCB0YWJsZU5hbWUgPSBSZXBvc2l0b3J5LnRhYmxlKGNsYXp6KTtcbiAgICBjb25zdCB7IGNhc2NhZGUgfSA9IG9wdGlvbnM7XG4gICAgY29uc3QgY2FzY2FkZVN0ciA9IGAke2Nhc2NhZGUudXBkYXRlID8gXCIgT04gVVBEQVRFIENBU0NBREVcIiA6IFwiXCJ9JHtjYXNjYWRlLmRlbGV0ZSA/IFwiIE9OIERFTEVURSBDQVNDQURFXCIgOiBcIlwifWA7XG4gICAgc3dpdGNoIChgcmVsYXRpb25zJHtrZXl9YCkge1xuICAgICAgY2FzZSBQZXJzaXN0ZW5jZUtleXMuT05FX1RPX09ORTpcbiAgICAgICAgcmV0dXJuIGBGT1JFSUdOIEtFWSAoJHtwcm9wfSkgUkVGRVJFTkNFUyAke3RhYmxlTmFtZX0oJHtwa30pJHtjYXNjYWRlU3RyfWA7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihgVW5zdXBwb3J0ZWQgb3BlcmF0aW9uOiAke2tleX1gKTtcbiAgICB9XG4gIH1cblxuICBzdGF0aWMgYXN5bmMgY3JlYXRlVGFibGU8TSBleHRlbmRzIE1vZGVsPihcbiAgICBjbGllbnQ6IERhdGFTb3VyY2UsXG4gICAgbW9kZWw6IENvbnN0cnVjdG9yPE0+XG4gICk6IFByb21pc2U8UmVjb3JkPHN0cmluZywgVHlwZU9STVRhYmxlU3BlYz4+IHtcbiAgICBjb25zdCByZXN1bHQ6IFJlY29yZDxzdHJpbmcsIFR5cGVPUk1UYWJsZVNwZWM+ID0ge307XG4gICAgY29uc3QgbSA9IG5ldyBtb2RlbCh7fSk7XG4gICAgY29uc3QgdGFibGVOYW1lID0gUmVwb3NpdG9yeS50YWJsZShtb2RlbCk7XG4gICAgY29uc3QgeyBpZCB9ID0gZmluZFByaW1hcnlLZXkobSk7XG5cbiAgICBsZXQgaXNQazogYm9vbGVhbiwgY29sdW1uOiBzdHJpbmc7XG4gICAgY29uc3QgcHJvcGVydGllcyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKG0pIGFzIChrZXlvZiBNKVtdO1xuICAgIGZvciAoY29uc3QgcHJvcCBvZiBwcm9wZXJ0aWVzKSB7XG4gICAgICBpZiAoXG4gICAgICAgIHR5cGVvZiAodGhpcyBhcyBhbnkpW3Byb3BdID09PSBcImZ1bmN0aW9uXCIgfHxcbiAgICAgICAgcHJvcC50b1N0cmluZygpLnN0YXJ0c1dpdGgoXCJfXCIpIHx8XG4gICAgICAgIHByb3AgPT09IFwiY29uc3RydWN0b3JcIlxuICAgICAgKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBpc1BrID0gcHJvcCA9PT0gaWQ7XG4gICAgICBjb2x1bW4gPSBSZXBvc2l0b3J5LmNvbHVtbihtLCBwcm9wLnRvU3RyaW5nKCkpO1xuXG4gICAgICBjb25zdCBhbGxEZWNzID0gUmVmbGVjdGlvbi5nZXRQcm9wZXJ0eURlY29yYXRvcnMoXG4gICAgICAgIFZhbGlkYXRpb25LZXlzLlJFRkxFQ1QsXG4gICAgICAgIG0sXG4gICAgICAgIHByb3AudG9TdHJpbmcoKSxcbiAgICAgICAgZmFsc2UsXG4gICAgICAgIHRydWVcbiAgICAgICk7XG5cbiAgICAgIGNvbnN0IGRlY29yYXRvckRhdGEgPSBhbGxEZWNzLmRlY29yYXRvcnMucmVkdWNlKFxuICAgICAgICAoYWNjdW06IFJlY29yZDxzdHJpbmcsIGFueT4sIGVsKSA9PiB7XG4gICAgICAgICAgY29uc3QgeyBrZXksIHByb3BzIH0gPSBlbDtcbiAgICAgICAgICBpZiAoa2V5ID09PSBNb2RlbEtleXMuVFlQRSAmJiAhYWNjdW1bVmFsaWRhdGlvbktleXMuVFlQRV0pIHtcbiAgICAgICAgICAgIGFjY3VtW1ZhbGlkYXRpb25LZXlzLlRZUEVdID0ge1xuICAgICAgICAgICAgICBjdXN0b21UeXBlczogW3Byb3BzLm5hbWUgYXMgc3RyaW5nXSxcbiAgICAgICAgICAgICAgbWVzc2FnZTogREVGQVVMVF9FUlJPUl9NRVNTQUdFUy5UWVBFLFxuICAgICAgICAgICAgICBkZXNjcmlwdGlvbjogXCJkZWZpbmVzIHRoZSBhY2NlcHRlZCB0eXBlcyBmb3IgdGhlIGF0dHJpYnV0ZVwiLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9IGVsc2UgaWYgKGtleSAhPT0gVmFsaWRhdGlvbktleXMuVFlQRSkge1xuICAgICAgICAgICAgLy8gZG8gbm90aGluZy4gd2UgY2FuIG9ubHkgc3VwcG9ydCBiYXNpcyBjdHlwZXMgYXQgdGhpcyB0aW1lXG4gICAgICAgICAgICBhY2N1bVtrZXldID0gcHJvcHM7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBhY2N1bTtcbiAgICAgICAgfSxcbiAgICAgICAge31cbiAgICAgICk7XG5cbiAgICAgIGNvbnN0IGRiRGVjcyA9IFJlZmxlY3Rpb24uZ2V0UHJvcGVydHlEZWNvcmF0b3JzKFxuICAgICAgICBSZXBvc2l0b3J5LmtleShcInJlbGF0aW9uc1wiKSxcbiAgICAgICAgbSxcbiAgICAgICAgcHJvcC50b1N0cmluZygpLFxuICAgICAgICB0cnVlLFxuICAgICAgICB0cnVlXG4gICAgICApO1xuXG4gICAgICBjb25zdCBxdWVyeTogc3RyaW5nW10gPSBbXTtcbiAgICAgIGNvbnN0IGNvbnN0cmFpbnRzOiBzdHJpbmdbXSA9IFtdO1xuICAgICAgY29uc3QgZm9yZWlnbktleXM6IHN0cmluZ1tdID0gW107XG4gICAgICBsZXQgdHlwZURhdGE6IFR5cGVNZXRhZGF0YSB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcbiAgICAgIGxldCBjaGlsZENsYXNzOiBDb25zdHJ1Y3RvcjxNb2RlbD4gfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG4gICAgICBsZXQgY2hpbGRQazogYW55O1xuXG4gICAgICBpZiAoT2JqZWN0LmtleXMoZGVjb3JhdG9yRGF0YSkubGVuZ3RoKSB7XG4gICAgICAgIHR5cGVEYXRhID0gZGVjb3JhdG9yRGF0YVtWYWxpZGF0aW9uS2V5cy5UWVBFXSBhcyBUeXBlTWV0YWRhdGE7XG5cbiAgICAgICAgaWYgKCF0eXBlRGF0YSkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgTWlzc2luZyB0eXBlIGluZm9ybWF0aW9uYCk7XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgcGFyc2VkVHlwZTpcbiAgICAgICAgICB8IHN0cmluZ1xuICAgICAgICAgIHwgeyBtb2RlbDogQ29uc3RydWN0b3I8TW9kZWw+IHwgc3RyaW5nOyBwa1R5cGU/OiBzdHJpbmcgfSA9XG4gICAgICAgICAgdGhpcy5wYXJzZVR5cGVUb1Bvc3RncmVzKFxuICAgICAgICAgICAgdHlwZW9mICh0eXBlRGF0YS5jdXN0b21UeXBlcyBhcyBhbnlbXSlbMF0gPT09IFwiZnVuY3Rpb25cIlxuICAgICAgICAgICAgICA/ICh0eXBlRGF0YS5jdXN0b21UeXBlcyBhcyBhbnkpWzBdKClcbiAgICAgICAgICAgICAgOiAodHlwZURhdGEuY3VzdG9tVHlwZXMgYXMgYW55KVswXSxcbiAgICAgICAgICAgIGlzUGtcbiAgICAgICAgICApO1xuICAgICAgICBpZiAodHlwZW9mIHBhcnNlZFR5cGUgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgICBwYXJzZWRUeXBlID0geyBtb2RlbDogcGFyc2VkVHlwZSB9O1xuICAgICAgICB9XG4gICAgICAgIGxldCB0eXBlU3RyOlxuICAgICAgICAgIHwgc3RyaW5nXG4gICAgICAgICAgfCB7IG1vZGVsOiBDb25zdHJ1Y3RvcjxNb2RlbD4gfCBzdHJpbmc7IHBrVHlwZT86IHN0cmluZyB9ID1cbiAgICAgICAgICBwYXJzZWRUeXBlLm1vZGVsIGFzXG4gICAgICAgICAgICB8IHN0cmluZ1xuICAgICAgICAgICAgfCB7IG1vZGVsOiBDb25zdHJ1Y3RvcjxNb2RlbD4gfCBzdHJpbmc7IHBrVHlwZT86IHN0cmluZyB9O1xuXG4gICAgICAgIGlmICh0eXBlb2YgdHlwZVN0ciAhPT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KHR5cGVTdHIpKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyh0eXBlU3RyKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBjb250aW51ZTtcbiAgICAgICAgICAvLyBjb25zdCByZXM6IFJlY29yZDxzdHJpbmcsIFBvc3RncmVzVGFibGVTcGVjPiA9IGF3YWl0IHRoaXMuY3JlYXRlVGFibGUocG9vbCwgdHlwZVN0cik7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNoaWxkQ2xhc3MgPSBwYXJzZWRUeXBlLm1vZGVsIGFzIENvbnN0cnVjdG9yPE1vZGVsPjtcbiAgICAgICAgICAgIGNvbnN0IG0gPSBuZXcgY2hpbGRDbGFzcygpO1xuICAgICAgICAgICAgY2hpbGRQayA9IGZpbmRQcmltYXJ5S2V5KG0pO1xuICAgICAgICAgICAgdHlwZVN0ciA9IHRoaXMucGFyc2VUeXBlVG9Qb3N0Z3JlcyhcbiAgICAgICAgICAgICAgcGFyc2VkVHlwZS5wa1R5cGUgYXMgc3RyaW5nLFxuICAgICAgICAgICAgICBmYWxzZSxcbiAgICAgICAgICAgICAgdHJ1ZVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuY3JlYXRlVGFibGUoY2xpZW50LCBjaGlsZENsYXNzKTtcbiAgICAgICAgICB9IGNhdGNoIChlOiB1bmtub3duKSB7XG4gICAgICAgICAgICBpZiAoIShlIGluc3RhbmNlb2YgQ29uZmxpY3RFcnJvcikpIHRocm93IGU7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgbGV0IHRwID0gQXJyYXkuaXNBcnJheSh0eXBlRGF0YS5jdXN0b21UeXBlcylcbiAgICAgICAgICA/IHR5cGVEYXRhLmN1c3RvbVR5cGVzWzBdXG4gICAgICAgICAgOiB0eXBlRGF0YS5jdXN0b21UeXBlcztcbiAgICAgICAgdHAgPSB0eXBlb2YgdHAgPT09IFwiZnVuY3Rpb25cIiAmJiAhdHAubmFtZSA/IHRwKCkgOiB0cDtcbiAgICAgICAgY29uc3QgdmFsaWRhdGlvblN0ciA9IHRoaXMucGFyc2VWYWxpZGF0aW9uVG9Qb3N0Z3JlcyhcbiAgICAgICAgICBjb2x1bW4sXG4gICAgICAgICAgdHAgYXMgYW55LFxuICAgICAgICAgIGlzUGssXG4gICAgICAgICAgVmFsaWRhdGlvbktleXMuTUFYX0xFTkdUSCxcbiAgICAgICAgICAoZGVjb3JhdG9yRGF0YVtcbiAgICAgICAgICAgIFZhbGlkYXRpb25LZXlzLk1BWF9MRU5HVEhcbiAgICAgICAgICBdIGFzIE1heExlbmd0aFZhbGlkYXRvck9wdGlvbnMpIHx8IHtcbiAgICAgICAgICAgIFtWYWxpZGF0aW9uS2V5cy5NQVhfTEVOR1RIXTogMjU1LFxuICAgICAgICAgIH1cbiAgICAgICAgKTtcblxuICAgICAgICBjb25zdCBxID0gYCR7Y29sdW1ufSAke3R5cGVTdHJ9JHt2YWxpZGF0aW9uU3RyfWA7XG5cbiAgICAgICAgaWYgKGlzUGspIHtcbiAgICAgICAgICBxdWVyeS51bnNoaWZ0KHEpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHF1ZXJ5LnB1c2gocSk7XG4gICAgICAgIH1cblxuICAgICAgICBmb3IgKGNvbnN0IFtrZXksIHByb3BzXSBvZiBPYmplY3QuZW50cmllcyhkZWNvcmF0b3JEYXRhKS5maWx0ZXIoXG4gICAgICAgICAgKFtrXSkgPT5cbiAgICAgICAgICAgICFbVmFsaWRhdGlvbktleXMuVFlQRSwgVmFsaWRhdGlvbktleXMuTUFYX0xFTkdUSF0uaW5jbHVkZXMoayBhcyBhbnkpXG4gICAgICAgICkpIHtcbiAgICAgICAgICBjb25zdCB2YWxpZGF0aW9uID0gdGhpcy5wYXJzZVZhbGlkYXRpb25Ub1Bvc3RncmVzKFxuICAgICAgICAgICAgY29sdW1uLFxuICAgICAgICAgICAgdHAgYXMgYW55LFxuICAgICAgICAgICAgaXNQayxcbiAgICAgICAgICAgIGtleSxcbiAgICAgICAgICAgIHByb3BzXG4gICAgICAgICAgKTtcbiAgICAgICAgICBpZiAodmFsaWRhdGlvbi5zdGFydHNXaXRoKFwiQ09OU1RSQUlOVFwiKSkge1xuICAgICAgICAgICAgY29uc3RyYWludHMucHVzaCh2YWxpZGF0aW9uKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKHZhbGlkYXRpb24pIHtcbiAgICAgICAgICAgICAgcXVlcnkucHVzaCh2YWxpZGF0aW9uKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gVE9ETyBpZ25vcmUgZm9yIG5vdy4gdGhpcyBsZWF2ZXMgZm9yZWlnbiBrZXlzIG91dFxuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnN0YW50LWJpbmFyeS1leHByZXNzaW9uXG4gICAgICBpZiAoZmFsc2UgfHwgKGRiRGVjcyAmJiBkYkRlY3MuZGVjb3JhdG9ycy5sZW5ndGgpKSB7XG4gICAgICAgIGlmICghdHlwZURhdGEpIHRocm93IG5ldyBFcnJvcihgTWlzc2luZyB0eXBlIGluZm9ybWF0aW9uYCk7XG4gICAgICAgIGZvciAoY29uc3QgZGVjb3JhdG9yIG9mIGRiRGVjcy5kZWNvcmF0b3JzKSB7XG4gICAgICAgICAgY29uc3QgeyBrZXksIHByb3BzIH0gPSBkZWNvcmF0b3I7XG4gICAgICAgICAgY29uc3QgdmFsaWRhdGlvbiA9IHRoaXMucGFyc2VSZWxhdGlvbnNUb1Bvc3RncmVzKFxuICAgICAgICAgICAgY29sdW1uLFxuICAgICAgICAgICAgY2hpbGRDbGFzcyBhcyBDb25zdHJ1Y3RvcjxNb2RlbD4sXG4gICAgICAgICAgICBjaGlsZFBrLmlkLFxuICAgICAgICAgICAga2V5IGFzIFBlcnNpc3RlbmNlS2V5cyxcbiAgICAgICAgICAgIHByb3BzIGFzIHVua25vd24gYXMgUmVsYXRpb25zTWV0YWRhdGFcbiAgICAgICAgICApO1xuICAgICAgICAgIGlmICh2YWxpZGF0aW9uLnN0YXJ0c1dpdGgoXCJGT1JFSUdOXCIpKSB7XG4gICAgICAgICAgICBmb3JlaWduS2V5cy5wdXNoKHZhbGlkYXRpb24pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihgVW5zdXBwb3J0ZWQgcmVsYXRpb246ICR7a2V5fWApO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXN1bHRbcHJvcC50b1N0cmluZygpXSA9IHtcbiAgICAgICAgcXVlcnk6IHF1ZXJ5LmpvaW4oXCIgXCIpLFxuICAgICAgICB2YWx1ZXM6IFtdLFxuICAgICAgICBwcmltYXJ5S2V5OiBpc1BrLFxuICAgICAgICBjb25zdHJhaW50czogY29uc3RyYWludHMsXG4gICAgICAgIGZvcmVpZ25LZXlzOiBmb3JlaWduS2V5cyxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgY29uc3QgdmFsdWVzID0gT2JqZWN0LnZhbHVlcyhyZXN1bHQpO1xuICAgIGNvbnN0IHF1ZXJ5ID0gdmFsdWVzLm1hcCgocikgPT4gci5xdWVyeSkuam9pbihcIixcXG5cIik7XG4gICAgY29uc3QgY29uc3RyYWludHMgPSB2YWx1ZXNcbiAgICAgIC5maWx0ZXIoKGMpID0+ICEhYy5jb25zdHJhaW50cy5sZW5ndGgpXG4gICAgICAubWFwKChyKSA9PiByLmNvbnN0cmFpbnRzKVxuICAgICAgLmpvaW4oXCIsXFxuXCIpO1xuICAgIGNvbnN0IGZvcmVpZ25LZXlzID0gdmFsdWVzXG4gICAgICAuZmlsdGVyKChjKSA9PiAhIWMuZm9yZWlnbktleXMubGVuZ3RoKVxuICAgICAgLm1hcCgocikgPT4gci5mb3JlaWduS2V5cylcbiAgICAgIC5qb2luKFwiLFxcblwiKTtcbiAgICBjb25zdCB2YWxzID0gW3F1ZXJ5LCBjb25zdHJhaW50c107XG4gICAgaWYgKGZvcmVpZ25LZXlzKSB7XG4gICAgICB2YWxzLnB1c2goZm9yZWlnbktleXMpO1xuICAgIH1cbiAgICBjb25zdCBxdWVyeVN0cmluZyA9IGBDUkVBVEUgVEFCTEUgJHt0YWJsZU5hbWV9ICgke3ZhbHMuZmlsdGVyKCh2KSA9PiAhIXYpLmpvaW4oXCIsXFxuXCIpfSlgO1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBjbGllbnQucXVlcnkocXVlcnlTdHJpbmcpO1xuICAgICAgYXdhaXQgY2xpZW50LnF1ZXJ5KFxuICAgICAgICBgQ1JFQVRFIFRSSUdHRVIgbm90aWZ5X2NoYW5nZXNfJHt0YWJsZU5hbWV9XG5BRlRFUiBJTlNFUlQgT1IgVVBEQVRFIE9SIERFTEVURSBPTiAke3RhYmxlTmFtZX1cbiAgICBGT1IgRUFDSCBST1dcbiAgICBFWEVDVVRFIEZVTkNUSU9OIG5vdGlmeV90YWJsZV9jaGFuZ2VzKCk7YFxuICAgICAgKTtcbiAgICB9IGNhdGNoIChlOiB1bmtub3duKSB7XG4gICAgICB0aHJvdyB0aGlzLnBhcnNlRXJyb3IoZSBhcyBFcnJvcik7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBzdGF0aWMgYXN5bmMgZ2V0Q3VycmVudFVzZXIoY2xpZW50OiBEYXRhU291cmNlKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICBjb25zdCBxdWVyeVN0cmluZyA9IGBTRUxFQ1QgQ1VSUkVOVF9VU0VSO2A7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNsaWVudC5xdWVyeShxdWVyeVN0cmluZyk7XG4gICAgICByZXR1cm4gcmVzdWx0WzBdLmN1cnJlbnRfdXNlcjtcbiAgICB9IGNhdGNoIChlOiB1bmtub3duKSB7XG4gICAgICB0aHJvdyB0aGlzLnBhcnNlRXJyb3IoZSBhcyBFcnJvcik7XG4gICAgfVxuICB9XG5cbiAgc3RhdGljIGRlY29yYXRpb24oKSB7XG4gICAgLy8gQHRhYmxlKCkgPT4gQEVudGl0eSgpXG4gICAgY29uc3QgdGFibGVLZXkgPSBBZGFwdGVyLmtleShQZXJzaXN0ZW5jZUtleXMuVEFCTEUpO1xuICAgIERlY29yYXRpb24uZmxhdm91cmVkQXMoVHlwZU9STUZsYXZvdXIpXG4gICAgICAuZm9yKHRhYmxlS2V5KVxuICAgICAgLmV4dGVuZCgob3JpZ2luYWw6IGFueSkgPT5cbiAgICAgICAgRW50aXR5KCkob3JpZ2luYWxbTW9kZWxLZXlzLkFOQ0hPUl0gfHwgb3JpZ2luYWwpXG4gICAgICApXG4gICAgICAuYXBwbHkoKTtcblxuICAgIC8vIEBwaygpID0+IEBQcmltYXJ5R2VuZXJhdGVkQ29sdW1uKCkgfCBAUHJpbWFyeUNvbHVtbigpXG4gICAgY29uc3QgcGtLZXkgPSBSZXBvc2l0b3J5LmtleShEQktleXMuSUQpO1xuXG4gICAgZnVuY3Rpb24gcGtEZWMob3B0aW9uczogU2VxdWVuY2VPcHRpb25zKSB7XG4gICAgICBjb25zdCBkZWNvcmF0b3JzOiBhbnlbXSA9IFtcbiAgICAgICAgcmVxdWlyZWQoKSxcbiAgICAgICAgcmVhZG9ubHkoKSxcbiAgICAgICAgcHJvcE1ldGFkYXRhKHBrS2V5LCBvcHRpb25zKSxcbiAgICAgIF07XG4gICAgICBpZiAob3B0aW9ucy50eXBlKSBkZWNvcmF0b3JzLnB1c2goUHJpbWFyeUdlbmVyYXRlZENvbHVtbigpKTtcbiAgICAgIGVsc2UgZGVjb3JhdG9ycy5wdXNoKFByaW1hcnlDb2x1bW4oeyB1bmlxdWU6IHRydWUgfSkpO1xuICAgICAgcmV0dXJuIGFwcGx5KC4uLmRlY29yYXRvcnMpO1xuICAgIH1cblxuICAgIERlY29yYXRpb24uZmxhdm91cmVkQXMoVHlwZU9STUZsYXZvdXIpXG4gICAgICAuZm9yKHBrS2V5KVxuICAgICAgLmRlZmluZSh7XG4gICAgICAgIGRlY29yYXRvcjogcGtEZWMsXG4gICAgICB9KVxuICAgICAgLmFwcGx5KCk7XG5cbiAgICAvLyBAY29sdW1uKFwiY29sdW1uTmFtZVwiKSA9PiBAQ29sdW1uKHtuYW1lOiBcImNvbHVtbk5hbWVcIn0pXG4gICAgY29uc3QgY29sdW1uS2V5ID0gQWRhcHRlci5rZXkoUGVyc2lzdGVuY2VLZXlzLkNPTFVNTik7XG4gICAgRGVjb3JhdGlvbi5mbGF2b3VyZWRBcyhUeXBlT1JNRmxhdm91cilcbiAgICAgIC5mb3IoY29sdW1uS2V5KVxuICAgICAgLmV4dGVuZCh7XG4gICAgICAgIGRlY29yYXRvcjogZnVuY3Rpb24gY29sdW1tKG5hbWU6IHN0cmluZykge1xuICAgICAgICAgIHJldHVybiBmdW5jdGlvbiBjb2x1bW4ob2JqOiBhbnksIHByb3A6IGFueSkge1xuICAgICAgICAgICAgcmV0dXJuIENvbHVtbih7XG4gICAgICAgICAgICAgIG5hbWU6IG5hbWUgfHwgcHJvcCxcbiAgICAgICAgICAgICAgbnVsbGFibGU6IHRydWUsXG4gICAgICAgICAgICB9KShvYmosIHByb3ApO1xuICAgICAgICAgIH07XG4gICAgICAgIH0sXG4gICAgICAgIHRyYW5zZm9ybTogKGFyZ3M6IGFueVtdKSA9PiB7XG4gICAgICAgICAgY29uc3QgY29sdW1uTmFtZSA9IGFyZ3NbMV07XG4gICAgICAgICAgcmV0dXJuIFtjb2x1bW5OYW1lXTtcbiAgICAgICAgfSxcbiAgICAgIH0pXG4gICAgICAuYXBwbHkoKTtcblxuICAgIC8vIEB1bmlxdWUgPT4gQENvbHVtbih7dW5pcXVlOiB0cnVlfSlcbiAgICBjb25zdCB1bmlxdWVLZXkgPSBBZGFwdGVyLmtleShQZXJzaXN0ZW5jZUtleXMuVU5JUVVFKTtcbiAgICBEZWNvcmF0aW9uLmZsYXZvdXJlZEFzKFR5cGVPUk1GbGF2b3VyKVxuICAgICAgLmZvcih1bmlxdWVLZXkpXG4gICAgICAuZGVmaW5lKHByb3BNZXRhZGF0YSh1bmlxdWVLZXksIHt9KSlcbiAgICAgIC5leHRlbmQoQ29sdW1uKHsgdW5pcXVlOiB0cnVlIH0pKVxuICAgICAgLmFwcGx5KCk7XG5cbiAgICAvLyBAcmVxdWlyZWQgPT4gQENvbHVtbih7IG51bGxhYmxlOiBmYWxzZSB9KVxuICAgIGNvbnN0IHJlcXVpcmVkS2V5ID0gVmFsaWRhdGlvbi5rZXkoVmFsaWRhdGlvbktleXMuUkVRVUlSRUQpO1xuICAgIERlY29yYXRpb24uZmxhdm91cmVkQXMoVHlwZU9STUZsYXZvdXIpXG4gICAgICAuZm9yKHJlcXVpcmVkS2V5KVxuICAgICAgLmV4dGVuZChDb2x1bW4oeyBudWxsYWJsZTogZmFsc2UgfSkpXG4gICAgICAuYXBwbHkoKTtcblxuICAgIC8vIEB2ZXJzaW9uID0+IEBWZXJzaW9uQ29sdW1uKClcbiAgICBjb25zdCB2ZXJzaW9uS2V5ID0gUmVwb3NpdG9yeS5rZXkoREJLZXlzLlZFUlNJT04pO1xuICAgIERlY29yYXRpb24uZmxhdm91cmVkQXMoVHlwZU9STUZsYXZvdXIpXG4gICAgICAuZm9yKHZlcnNpb25LZXkpXG4gICAgICAuZGVmaW5lKHR5cGUoTnVtYmVyLm5hbWUpLCBWZXJzaW9uQ29sdW1uKCkpXG4gICAgICAuYXBwbHkoKTtcblxuICAgIGZ1bmN0aW9uIFZhbGlkYXRpb25VcGRhdGVLZXkoa2V5OiBzdHJpbmcpIHtcbiAgICAgIHJldHVybiBVcGRhdGVWYWxpZGF0aW9uS2V5cy5SRUZMRUNUICsga2V5O1xuICAgIH1cblxuICAgIC8vIEB0aW1lc3RhbXAob3ApID0+IEBDcmVhdGVEYXRlQ29sdW1uKCkgfHwgQFVwZGF0ZURhdGVDb2x1bW4oKVxuICAgIGNvbnN0IHRpbWVzdGFtcEtleSA9IFZhbGlkYXRpb25VcGRhdGVLZXkoREJLZXlzLlRJTUVTVEFNUCk7XG5cbiAgICBmdW5jdGlvbiB0cyhvcGVyYXRpb246IE9wZXJhdGlvbktleXNbXSwgZm9ybWF0OiBzdHJpbmcpIHtcbiAgICAgIGNvbnN0IGRlY29yYXRvcnM6IGFueVtdID0gW1xuICAgICAgICBkYXRlKGZvcm1hdCwgREJfREVGQVVMVF9FUlJPUl9NRVNTQUdFUy5USU1FU1RBTVAuREFURSksXG4gICAgICAgIHJlcXVpcmVkKERCX0RFRkFVTFRfRVJST1JfTUVTU0FHRVMuVElNRVNUQU1QLlJFUVVJUkVEKSxcbiAgICAgICAgcHJvcE1ldGFkYXRhKFZhbGlkYXRpb24ua2V5KERCS2V5cy5USU1FU1RBTVApLCB7XG4gICAgICAgICAgb3BlcmF0aW9uOiBvcGVyYXRpb24sXG4gICAgICAgICAgZm9ybWF0OiBmb3JtYXQsXG4gICAgICAgIH0pLFxuICAgICAgXTtcbiAgICAgIGlmIChvcGVyYXRpb24uaW5kZXhPZihPcGVyYXRpb25LZXlzLlVQREFURSkgIT09IC0xKVxuICAgICAgICBkZWNvcmF0b3JzLnB1c2goXG4gICAgICAgICAgcHJvcE1ldGFkYXRhKHRpbWVzdGFtcEtleSwge1xuICAgICAgICAgICAgbWVzc2FnZTogREJfREVGQVVMVF9FUlJPUl9NRVNTQUdFUy5USU1FU1RBTVAuSU5WQUxJRCxcbiAgICAgICAgICB9KVxuICAgICAgICApO1xuICAgICAgZWxzZSBkZWNvcmF0b3JzLnB1c2gocmVhZG9ubHkoKSk7XG4gICAgICByZXR1cm4gYXBwbHkoLi4uZGVjb3JhdG9ycyk7XG4gICAgfVxuXG4gICAgRGVjb3JhdGlvbi5mbGF2b3VyZWRBcyhUeXBlT1JNRmxhdm91cilcbiAgICAgIC5mb3IodGltZXN0YW1wS2V5KVxuICAgICAgLmRlZmluZSh7XG4gICAgICAgIGRlY29yYXRvcjogdHMsXG4gICAgICB9KVxuICAgICAgLmV4dGVuZCh7XG4gICAgICAgIGRlY29yYXRvcjogZnVuY3Rpb24gdGltZXN0YW1wKC4uLm9wczogT3BlcmF0aW9uS2V5c1tdKSB7XG4gICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIHRpbWVzdGFtcChvYmo6IGFueSwgcHJvcDogYW55KSB7XG4gICAgICAgICAgICBpZiAob3BzLmluZGV4T2YoT3BlcmF0aW9uS2V5cy5VUERBVEUpICE9PSAtMSlcbiAgICAgICAgICAgICAgcmV0dXJuIFVwZGF0ZURhdGVDb2x1bW4oKShvYmosIHByb3ApO1xuICAgICAgICAgICAgcmV0dXJuIENyZWF0ZURhdGVDb2x1bW4oKShvYmosIHByb3ApO1xuICAgICAgICAgIH07XG4gICAgICAgIH0sXG4gICAgICAgIHRyYW5zZm9ybTogKGFyZ3M6IGFueVtdKSA9PiB7XG4gICAgICAgICAgcmV0dXJuIGFyZ3NbMF07XG4gICAgICAgIH0sXG4gICAgICB9KVxuICAgICAgLmFwcGx5KCk7XG5cbiAgICAvLyBAb25lVG9PbmUoY2xhenopID0+IEBPbmVUb09uZSgoKSA9PiBjbGF6eilcbiAgICBjb25zdCBvbmVUb09uZUtleSA9IFJlcG9zaXRvcnkua2V5KFBlcnNpc3RlbmNlS2V5cy5PTkVfVE9fT05FKTtcbiAgICBEZWNvcmF0aW9uLmZsYXZvdXJlZEFzKFR5cGVPUk1GbGF2b3VyKVxuICAgICAgLmZvcihvbmVUb09uZUtleSlcbiAgICAgIC5kZWZpbmUoe1xuICAgICAgICBkZWNvcmF0b3I6IGZ1bmN0aW9uIG9uZVRvT25lKFxuICAgICAgICAgIGNsYXp6OiBDb25zdHJ1Y3Rvcjxhbnk+IHwgKCgpID0+IENvbnN0cnVjdG9yPGFueT4pLFxuICAgICAgICAgIGNhc2NhZGU6IENhc2NhZGVNZXRhZGF0YSxcbiAgICAgICAgICBwb3B1bGF0ZTogYm9vbGVhblxuICAgICAgICApIHtcbiAgICAgICAgICBjb25zdCBtZXRhZGF0YTogUmVsYXRpb25zTWV0YWRhdGEgPSB7XG4gICAgICAgICAgICBjbGFzczogKGNsYXp6Lm5hbWUgPyBjbGF6ei5uYW1lIDogY2xhenopIGFzIHN0cmluZyxcbiAgICAgICAgICAgIGNhc2NhZGU6IGNhc2NhZGUsXG4gICAgICAgICAgICBwb3B1bGF0ZTogcG9wdWxhdGUsXG4gICAgICAgICAgfTtcbiAgICAgICAgICBjb25zdCBvcm1NZXRhOiBSZWxhdGlvbk9wdGlvbnMgPSB7XG4gICAgICAgICAgICBjYXNjYWRlOlxuICAgICAgICAgICAgICBjYXNjYWRlLnVwZGF0ZSA9PT0gQ2FzY2FkZS5DQVNDQURFIHx8XG4gICAgICAgICAgICAgIGNhc2NhZGUuZGVsZXRlID09PSBDYXNjYWRlLkNBU0NBREUsXG4gICAgICAgICAgICBvbkRlbGV0ZTogY2FzY2FkZS5kZWxldGUgPyBcIkNBU0NBREVcIiA6IFwiREVGQVVMVFwiLFxuICAgICAgICAgICAgb25VcGRhdGU6IGNhc2NhZGUudXBkYXRlID8gXCJDQVNDQURFXCIgOiBcIkRFRkFVTFRcIixcbiAgICAgICAgICAgIG51bGxhYmxlOiB0cnVlLFxuICAgICAgICAgICAgZWFnZXI6IHBvcHVsYXRlLFxuICAgICAgICAgIH07XG4gICAgICAgICAgcmV0dXJuIGFwcGx5KFxuICAgICAgICAgICAgcHJvcChQZXJzaXN0ZW5jZUtleXMuUkVMQVRJT05TKSxcbiAgICAgICAgICAgIHR5cGUoW1xuICAgICAgICAgICAgICAodHlwZW9mIGNsYXp6ID09PSBcImZ1bmN0aW9uXCIgJiYgIWNsYXp6Lm5hbWVcbiAgICAgICAgICAgICAgICA/IGNsYXp6XG4gICAgICAgICAgICAgICAgOiBjbGF6ei5uYW1lKSBhcyBhbnksXG4gICAgICAgICAgICAgIFN0cmluZy5uYW1lLFxuICAgICAgICAgICAgICBOdW1iZXIubmFtZSxcbiAgICAgICAgICAgICAgQmlnSW50Lm5hbWUsXG4gICAgICAgICAgICBdKSxcbiAgICAgICAgICAgIHByb3BNZXRhZGF0YShvbmVUb09uZUtleSwgbWV0YWRhdGEpLFxuICAgICAgICAgICAgT25lVG9PbmUoXG4gICAgICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoIWNsYXp6Lm5hbWUpIGNsYXp6ID0gKGNsYXp6IGFzIGFueSkoKTtcbiAgICAgICAgICAgICAgICBpZiAoIWNsYXp6W01vZGVsS2V5cy5BTkNIT1IgYXMga2V5b2YgdHlwZW9mIGNsYXp6XSlcbiAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFxuICAgICAgICAgICAgICAgICAgICBcIk9yaWdpbmFsIE1vZGVsIG5vdCBmb3VuZCBpbiBjb25zdHJ1Y3RvclwiXG4gICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIHJldHVybiBjbGF6eltNb2RlbEtleXMuQU5DSE9SIGFzIGtleW9mIHR5cGVvZiBjbGF6el07XG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIChtb2RlbDogYW55KSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgcGsgPSBmaW5kUHJpbWFyeUtleShuZXcgKGNsYXp6IGFzIENvbnN0cnVjdG9yPGFueT4pKCkpLmlkO1xuICAgICAgICAgICAgICAgIHJldHVybiBtb2RlbFtwa107XG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIG9ybU1ldGFcbiAgICAgICAgICAgICksXG4gICAgICAgICAgICBKb2luQ29sdW1uKClcbiAgICAgICAgICApO1xuICAgICAgICB9LFxuICAgICAgfSlcbiAgICAgIC5hcHBseSgpO1xuXG4gICAgLy8gQG9uZVRvTWFueShjbGF6eikgPT4gQE9uZVRvTWFueSgoKSA9PiBjbGF6eilcbiAgICBjb25zdCBvbmVUb01hbnlLZXkgPSBSZXBvc2l0b3J5LmtleShQZXJzaXN0ZW5jZUtleXMuT05FX1RPX01BTlkpO1xuICAgIERlY29yYXRpb24uZmxhdm91cmVkQXMoVHlwZU9STUZsYXZvdXIpXG4gICAgICAuZm9yKG9uZVRvTWFueUtleSlcbiAgICAgIC5kZWZpbmUoe1xuICAgICAgICBkZWNvcmF0b3I6IGZ1bmN0aW9uIG9uZVRvTWFueShcbiAgICAgICAgICBjbGF6ejogQ29uc3RydWN0b3I8YW55PiB8ICgoKSA9PiBDb25zdHJ1Y3Rvcjxhbnk+KSxcbiAgICAgICAgICBjYXNjYWRlOiBDYXNjYWRlTWV0YWRhdGEsXG4gICAgICAgICAgcG9wdWxhdGU6IGJvb2xlYW5cbiAgICAgICAgKSB7XG4gICAgICAgICAgY29uc3QgbWV0YWRhdGE6IFJlbGF0aW9uc01ldGFkYXRhID0ge1xuICAgICAgICAgICAgY2xhc3M6IChjbGF6ei5uYW1lID8gY2xhenoubmFtZSA6IGNsYXp6KSBhcyBzdHJpbmcsXG4gICAgICAgICAgICBjYXNjYWRlOiBjYXNjYWRlLFxuICAgICAgICAgICAgcG9wdWxhdGU6IHBvcHVsYXRlLFxuICAgICAgICAgIH07XG4gICAgICAgICAgcmV0dXJuIGFwcGx5KFxuICAgICAgICAgICAgcHJvcChQZXJzaXN0ZW5jZUtleXMuUkVMQVRJT05TKSxcbiAgICAgICAgICAgIGxpc3QoY2xhenopLFxuICAgICAgICAgICAgcHJvcE1ldGFkYXRhKG9uZVRvTWFueUtleSwgbWV0YWRhdGEpLFxuICAgICAgICAgICAgZnVuY3Rpb24gT25lVG9NYW55V3JhcHBlcihvYmo6IGFueSwgcHJvcDogYW55KTogYW55IHtcbiAgICAgICAgICAgICAgY29uc3Qgb3JtTWV0YTogUmVsYXRpb25PcHRpb25zID0ge1xuICAgICAgICAgICAgICAgIGNhc2NhZGU6XG4gICAgICAgICAgICAgICAgICBjYXNjYWRlLnVwZGF0ZSA9PT0gQ2FzY2FkZS5DQVNDQURFIHx8XG4gICAgICAgICAgICAgICAgICBjYXNjYWRlLmRlbGV0ZSA9PT0gQ2FzY2FkZS5DQVNDQURFLFxuICAgICAgICAgICAgICAgIG9uRGVsZXRlOiBjYXNjYWRlLmRlbGV0ZSA/IFwiQ0FTQ0FERVwiIDogXCJERUZBVUxUXCIsXG4gICAgICAgICAgICAgICAgb25VcGRhdGU6IGNhc2NhZGUudXBkYXRlID8gXCJDQVNDQURFXCIgOiBcIkRFRkFVTFRcIixcbiAgICAgICAgICAgICAgICBudWxsYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBlYWdlcjogcG9wdWxhdGUsXG4gICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgIHJldHVybiBPbmVUb01hbnkoXG4gICAgICAgICAgICAgICAgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgaWYgKCFjbGF6ei5uYW1lKSBjbGF6eiA9IChjbGF6eiBhcyBhbnkpKCk7XG4gICAgICAgICAgICAgICAgICBpZiAoIWNsYXp6W01vZGVsS2V5cy5BTkNIT1IgYXMga2V5b2YgdHlwZW9mIGNsYXp6XSlcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgXCJPcmlnaW5hbCBNb2RlbCBub3QgZm91bmQgaW4gY29uc3RydWN0b3JcIlxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIGNsYXp6W01vZGVsS2V5cy5BTkNIT1IgYXMga2V5b2YgdHlwZW9mIGNsYXp6XTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIChtb2RlbDogYW55KSA9PiB7XG4gICAgICAgICAgICAgICAgICBpZiAoIWNsYXp6Lm5hbWUpIGNsYXp6ID0gKGNsYXp6IGFzIGFueSkoKTtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IG0gPSBuZXcgKGNsYXp6IGFzIENvbnN0cnVjdG9yPGFueT4pKCk7XG4gICAgICAgICAgICAgICAgICBjb25zdCBjcm9zc1JlbGF0aW9uS2V5ID0gT2JqZWN0LmtleXMobSkuZmluZCgoaykgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBkZWNzID0gUmVmbGVjdGlvbi5nZXRQcm9wZXJ0eURlY29yYXRvcnMoXG4gICAgICAgICAgICAgICAgICAgICAgUmVwb3NpdG9yeS5rZXkoUGVyc2lzdGVuY2VLZXlzLk1BTllfVE9fT05FKSxcbiAgICAgICAgICAgICAgICAgICAgICBtLFxuICAgICAgICAgICAgICAgICAgICAgIGssXG4gICAgICAgICAgICAgICAgICAgICAgdHJ1ZVxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICBpZiAoIWRlY3MgfHwgIWRlY3MuZGVjb3JhdG9ycyB8fCAhZGVjcy5kZWNvcmF0b3JzLmxlbmd0aClcbiAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGRlc2lnblR5cGUgPSBSZWZsZWN0LmdldE1ldGFkYXRhKFxuICAgICAgICAgICAgICAgICAgICAgIE1vZGVsS2V5cy5UWVBFLFxuICAgICAgICAgICAgICAgICAgICAgIG0sXG4gICAgICAgICAgICAgICAgICAgICAga1xuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICBpZiAoIWRlc2lnblR5cGUpXG4gICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICBgTm8gVHlwZSBEZWZpbml0aW9uIGZvdW5kIGZvciAke2t9IGluICR7bS5jb25zdHJ1Y3Rvci5uYW1lfWBcbiAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGVzaWduVHlwZS5uYW1lID09PSBvYmouY29uc3RydWN0b3IubmFtZTtcbiAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgaWYgKCFjcm9zc1JlbGF0aW9uS2V5KVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcbiAgICAgICAgICAgICAgICAgICAgICBgQ3Jvc3MgcmVsYXRpb24gbm90IGZvdW5kLiBEaWQgeW91IHVzZSBAbWFueVRvT25lIG9uIHRoZSAke2NsYXp6Lm5hbWV9P2BcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgIHJldHVybiBtb2RlbFtjcm9zc1JlbGF0aW9uS2V5XTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIG9ybU1ldGFcbiAgICAgICAgICAgICAgKShvYmosIHByb3ApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICk7XG4gICAgICAgIH0sXG4gICAgICB9KVxuICAgICAgLmFwcGx5KCk7XG5cbiAgICAvLyBAbWFueVRvT25lKGNsYXp6KSA9PiBATWFueVRvT25lKCgpID0+IGNsYXp6KVxuICAgIGNvbnN0IG1hbnlUb09uZUtleSA9IFJlcG9zaXRvcnkua2V5KFBlcnNpc3RlbmNlS2V5cy5NQU5ZX1RPX09ORSk7XG4gICAgRGVjb3JhdGlvbi5mbGF2b3VyZWRBcyhUeXBlT1JNRmxhdm91cilcbiAgICAgIC5mb3IobWFueVRvT25lS2V5KVxuICAgICAgLmRlZmluZSh7XG4gICAgICAgIGRlY29yYXRvcjogZnVuY3Rpb24gbWFueVRvT25lKFxuICAgICAgICAgIGNsYXp6OiBDb25zdHJ1Y3Rvcjxhbnk+IHwgKCgpID0+IENvbnN0cnVjdG9yPGFueT4pLFxuICAgICAgICAgIGNhc2NhZGU6IENhc2NhZGVNZXRhZGF0YSxcbiAgICAgICAgICBwb3B1bGF0ZTogYm9vbGVhblxuICAgICAgICApIHtcbiAgICAgICAgICBjb25zdCBtZXRhZGF0YTogUmVsYXRpb25zTWV0YWRhdGEgPSB7XG4gICAgICAgICAgICBjbGFzczogKGNsYXp6Lm5hbWUgPyBjbGF6ei5uYW1lIDogY2xhenopIGFzIHN0cmluZyxcbiAgICAgICAgICAgIGNhc2NhZGU6IGNhc2NhZGUsXG4gICAgICAgICAgICBwb3B1bGF0ZTogcG9wdWxhdGUsXG4gICAgICAgICAgfTtcbiAgICAgICAgICBjb25zdCBvcm1NZXRhOiBSZWxhdGlvbk9wdGlvbnMgPSB7XG4gICAgICAgICAgICBjYXNjYWRlOlxuICAgICAgICAgICAgICBjYXNjYWRlLnVwZGF0ZSA9PT0gQ2FzY2FkZS5DQVNDQURFIHx8XG4gICAgICAgICAgICAgIGNhc2NhZGUuZGVsZXRlID09PSBDYXNjYWRlLkNBU0NBREUsXG4gICAgICAgICAgICBvbkRlbGV0ZTogY2FzY2FkZS5kZWxldGUgPyBcIkNBU0NBREVcIiA6IFwiREVGQVVMVFwiLFxuICAgICAgICAgICAgb25VcGRhdGU6IGNhc2NhZGUudXBkYXRlID8gXCJDQVNDQURFXCIgOiBcIkRFRkFVTFRcIixcbiAgICAgICAgICAgIG51bGxhYmxlOiB0cnVlLFxuICAgICAgICAgICAgZWFnZXI6IHBvcHVsYXRlLFxuICAgICAgICAgIH07XG4gICAgICAgICAgcmV0dXJuIGFwcGx5KFxuICAgICAgICAgICAgcHJvcChQZXJzaXN0ZW5jZUtleXMuUkVMQVRJT05TKSxcbiAgICAgICAgICAgIHR5cGUoW1xuICAgICAgICAgICAgICAodHlwZW9mIGNsYXp6ID09PSBcImZ1bmN0aW9uXCIgJiYgIWNsYXp6Lm5hbWVcbiAgICAgICAgICAgICAgICA/IGNsYXp6XG4gICAgICAgICAgICAgICAgOiBjbGF6ei5uYW1lKSBhcyBhbnksXG4gICAgICAgICAgICAgIFN0cmluZy5uYW1lLFxuICAgICAgICAgICAgICBOdW1iZXIubmFtZSxcbiAgICAgICAgICAgICAgQmlnSW50Lm5hbWUsXG4gICAgICAgICAgICBdKSxcbiAgICAgICAgICAgIHByb3BNZXRhZGF0YShtYW55VG9PbmVLZXksIG1ldGFkYXRhKSxcbiAgICAgICAgICAgIGZ1bmN0aW9uIE1hbnlUb09uZVdyYXBwZXIob2JqOiBhbnksIHByb3A6IGFueSk6IGFueSB7XG4gICAgICAgICAgICAgIHJldHVybiBNYW55VG9PbmUoXG4gICAgICAgICAgICAgICAgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgaWYgKCFjbGF6ei5uYW1lKSBjbGF6eiA9IChjbGF6eiBhcyBhbnkpKCk7XG4gICAgICAgICAgICAgICAgICBpZiAoIWNsYXp6W01vZGVsS2V5cy5BTkNIT1IgYXMga2V5b2YgdHlwZW9mIGNsYXp6XSlcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgXCJPcmlnaW5hbCBNb2RlbCBub3QgZm91bmQgaW4gY29uc3RydWN0b3JcIlxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIGNsYXp6W01vZGVsS2V5cy5BTkNIT1IgYXMga2V5b2YgdHlwZW9mIGNsYXp6XTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIChtb2RlbDogYW55KSA9PiB7XG4gICAgICAgICAgICAgICAgICBpZiAoIWNsYXp6Lm5hbWUpIGNsYXp6ID0gKGNsYXp6IGFzIGFueSkoKTtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IG0gPSBuZXcgKGNsYXp6IGFzIENvbnN0cnVjdG9yPGFueT4pKCk7XG4gICAgICAgICAgICAgICAgICBjb25zdCBjcm9zc1JlbGF0aW9uS2V5ID0gT2JqZWN0LmtleXMobSkuZmluZCgoaykgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBkZWNzID0gUmVmbGVjdGlvbi5nZXRQcm9wZXJ0eURlY29yYXRvcnMoXG4gICAgICAgICAgICAgICAgICAgICAgUmVwb3NpdG9yeS5rZXkoUGVyc2lzdGVuY2VLZXlzLk9ORV9UT19NQU5ZKSxcbiAgICAgICAgICAgICAgICAgICAgICBtLFxuICAgICAgICAgICAgICAgICAgICAgIGssXG4gICAgICAgICAgICAgICAgICAgICAgdHJ1ZVxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICBpZiAoIWRlY3MgfHwgIWRlY3MuZGVjb3JhdG9ycyB8fCAhZGVjcy5kZWNvcmF0b3JzLmxlbmd0aClcbiAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGxpc3REZWMgPSBSZWZsZWN0LmdldE1ldGFkYXRhKFxuICAgICAgICAgICAgICAgICAgICAgIFZhbGlkYXRpb24ua2V5KFZhbGlkYXRpb25LZXlzLkxJU1QpLFxuICAgICAgICAgICAgICAgICAgICAgIG0sXG4gICAgICAgICAgICAgICAgICAgICAga1xuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICBpZiAoIWxpc3REZWMpXG4gICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICBgTm8gVHlwZSBEZWZpbml0aW9uIGZvdW5kIGZvciAke2t9IGluICR7bS5jb25zdHJ1Y3Rvci5uYW1lfWBcbiAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBuYW1lID0gbGlzdERlYy5jbGF6elswXSgpLm5hbWU7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBuYW1lID09PSBvYmouY29uc3RydWN0b3IubmFtZTtcbiAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgaWYgKCFjcm9zc1JlbGF0aW9uS2V5KVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcbiAgICAgICAgICAgICAgICAgICAgICBgQ3Jvc3MgcmVsYXRpb24gbm90IGZvdW5kLiBEaWQgeW91IHVzZSBAbWFueVRvT25lIG9uIHRoZSAke2NsYXp6Lm5hbWV9P2BcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgIHJldHVybiBtb2RlbFtjcm9zc1JlbGF0aW9uS2V5XTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICkob2JqLCBwcm9wKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICApO1xuICAgICAgICB9LFxuICAgICAgfSlcbiAgICAgIC5hcHBseSgpO1xuXG4gICAgLy8gQG1hbnlUb01hbnkoY2xhenopID0+IEBNYW55VG9NYW55KCgpID0+IGNsYXp6KVxuICAgIGNvbnN0IG1hbnlUb01hbnlLZXkgPSBSZXBvc2l0b3J5LmtleShQZXJzaXN0ZW5jZUtleXMuTUFOWV9UT19NQU5ZKTtcbiAgICBEZWNvcmF0aW9uLmZsYXZvdXJlZEFzKFR5cGVPUk1GbGF2b3VyKVxuICAgICAgLmZvcihtYW55VG9NYW55S2V5KVxuICAgICAgLmRlZmluZSh7XG4gICAgICAgIGRlY29yYXRvcjogZnVuY3Rpb24gbWFueVRvTWFueShcbiAgICAgICAgICBjbGF6ejogQ29uc3RydWN0b3I8YW55PiB8ICgoKSA9PiBDb25zdHJ1Y3Rvcjxhbnk+KSxcbiAgICAgICAgICBjYXNjYWRlOiBDYXNjYWRlTWV0YWRhdGEsXG4gICAgICAgICAgcG9wdWxhdGU6IGJvb2xlYW5cbiAgICAgICAgKSB7XG4gICAgICAgICAgY29uc3QgbWV0YWRhdGE6IFJlbGF0aW9uc01ldGFkYXRhID0ge1xuICAgICAgICAgICAgY2xhc3M6IGNsYXp6Lm5hbWUsXG4gICAgICAgICAgICBjYXNjYWRlOiBjYXNjYWRlLFxuICAgICAgICAgICAgcG9wdWxhdGU6IHBvcHVsYXRlLFxuICAgICAgICAgIH07XG4gICAgICAgICAgY29uc3Qgb3JtTWV0YTogUmVsYXRpb25PcHRpb25zID0ge1xuICAgICAgICAgICAgY2FzY2FkZTpcbiAgICAgICAgICAgICAgY2FzY2FkZS51cGRhdGUgPT09IENhc2NhZGUuQ0FTQ0FERSB8fFxuICAgICAgICAgICAgICBjYXNjYWRlLmRlbGV0ZSA9PT0gQ2FzY2FkZS5DQVNDQURFLFxuICAgICAgICAgICAgb25EZWxldGU6IGNhc2NhZGUuZGVsZXRlID8gXCJDQVNDQURFXCIgOiBcIkRFRkFVTFRcIixcbiAgICAgICAgICAgIG9uVXBkYXRlOiBjYXNjYWRlLnVwZGF0ZSA/IFwiQ0FTQ0FERVwiIDogXCJERUZBVUxUXCIsXG4gICAgICAgICAgICBudWxsYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgIGVhZ2VyOiBwb3B1bGF0ZSxcbiAgICAgICAgICB9O1xuICAgICAgICAgIHJldHVybiBhcHBseShcbiAgICAgICAgICAgIHByb3AoUGVyc2lzdGVuY2VLZXlzLlJFTEFUSU9OUyksXG4gICAgICAgICAgICBsaXN0KGNsYXp6KSxcbiAgICAgICAgICAgIHByb3BNZXRhZGF0YShtYW55VG9NYW55S2V5LCBtZXRhZGF0YSksXG4gICAgICAgICAgICBNYW55VG9NYW55KFxuICAgICAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKCFjbGF6ei5uYW1lKSBjbGF6eiA9IChjbGF6eiBhcyBhbnkpKCk7XG4gICAgICAgICAgICAgICAgaWYgKCFjbGF6eltNb2RlbEtleXMuQU5DSE9SIGFzIGtleW9mIHR5cGVvZiBjbGF6el0pXG4gICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcbiAgICAgICAgICAgICAgICAgICAgXCJPcmlnaW5hbCBNb2RlbCBub3QgZm91bmQgaW4gY29uc3RydWN0b3JcIlxuICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gY2xhenpbTW9kZWxLZXlzLkFOQ0hPUiBhcyBrZXlvZiB0eXBlb2YgY2xhenpdO1xuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAobW9kZWw6IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghY2xhenoubmFtZSkgY2xhenogPSAoY2xhenogYXMgYW55KSgpO1xuICAgICAgICAgICAgICAgIGNvbnN0IHBrID0gZmluZFByaW1hcnlLZXkobmV3IChjbGF6eiBhcyBDb25zdHJ1Y3Rvcjxhbnk+KSgpKS5pZDtcbiAgICAgICAgICAgICAgICByZXR1cm4gbW9kZWxbcGtdO1xuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBvcm1NZXRhXG4gICAgICAgICAgICApLFxuICAgICAgICAgICAgSm9pblRhYmxlKClcbiAgICAgICAgICApO1xuICAgICAgICB9LFxuICAgICAgfSlcbiAgICAgIC5hcHBseSgpO1xuICB9XG59XG4iXX0=