@decaf-ts/for-nest 0.0.2 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/dist/for-nest.cjs +549 -15
  2. package/dist/for-nest.esm.cjs +549 -14
  3. package/lib/RepoFactory.cjs +27 -0
  4. package/lib/RepoFactory.d.ts +6 -0
  5. package/lib/core-module.cjs +27 -7
  6. package/lib/core-module.d.ts +7 -2
  7. package/lib/decoration.cjs +123 -0
  8. package/lib/decoration.d.ts +1 -0
  9. package/lib/decorators/ApiProperty.cjs +63 -0
  10. package/lib/decorators/ApiProperty.d.ts +27 -0
  11. package/lib/decorators/helpers.cjs +140 -0
  12. package/lib/decorators/helpers.d.ts +8 -0
  13. package/lib/decorators/index.cjs +19 -0
  14. package/lib/decorators/index.d.ts +2 -0
  15. package/lib/esm/RepoFactory.d.ts +6 -0
  16. package/lib/esm/RepoFactory.js +24 -0
  17. package/lib/esm/core-module.d.ts +7 -2
  18. package/lib/esm/core-module.js +27 -7
  19. package/lib/esm/decoration.d.ts +1 -0
  20. package/lib/esm/decoration.js +121 -0
  21. package/lib/esm/decorators/ApiProperty.d.ts +27 -0
  22. package/lib/esm/decorators/ApiProperty.js +57 -0
  23. package/lib/esm/decorators/helpers.d.ts +8 -0
  24. package/lib/esm/decorators/helpers.js +132 -0
  25. package/lib/esm/decorators/index.d.ts +2 -0
  26. package/lib/esm/decorators/index.js +3 -0
  27. package/lib/esm/index.d.ts +7 -2
  28. package/lib/esm/index.js +8 -3
  29. package/lib/esm/model-module.d.ts +8 -0
  30. package/lib/esm/model-module.js +199 -0
  31. package/lib/esm/module.d.ts +1 -1
  32. package/lib/esm/module.js +11 -3
  33. package/lib/esm/types.d.ts +1 -0
  34. package/lib/esm/types.js +1 -1
  35. package/lib/esm/utils.d.ts +2 -0
  36. package/lib/esm/utils.js +11 -0
  37. package/lib/index.cjs +8 -3
  38. package/lib/index.d.ts +7 -2
  39. package/lib/model-module.cjs +202 -0
  40. package/lib/model-module.d.ts +8 -0
  41. package/lib/module.cjs +11 -3
  42. package/lib/module.d.ts +1 -1
  43. package/lib/types.cjs +1 -1
  44. package/lib/types.d.ts +1 -0
  45. package/lib/utils.cjs +14 -0
  46. package/lib/utils.d.ts +2 -0
  47. package/package.json +4 -2
@@ -1,19 +1,344 @@
1
- import { Metadata } from '@decaf-ts/decoration';
1
+ import { Decoration, DecorationKeys, Metadata } from '@decaf-ts/decoration';
2
+ import { InjectablesKeys } from '@decaf-ts/injectable-decorators';
3
+ import { Injectable, Scope, Inject, Global, Module, Post, Body, Get, Param, Put, Delete, Controller } from '@nestjs/common';
4
+ import { ValidationKeys, Model } from '@decaf-ts/decorator-validation';
5
+ import { getTypeIsArrayTuple as getTypeIsArrayTuple$1 } from '@nestjs/swagger/dist/decorators/helpers';
6
+ import { getEnumValues, getEnumType } from '@nestjs/swagger/dist/utils/enum.utils';
7
+ import { DECORATORS } from '@nestjs/swagger/dist/constants';
8
+ import { METHOD_METADATA } from '@nestjs/common/constants';
9
+ import { isConstructor } from '@nestjs/common/utils/shared.utils';
10
+ import { pickBy, negate, isUndefined, isArray } from 'lodash';
11
+ import { METADATA_FACTORY_NAME } from '@nestjs/swagger/dist/plugin/plugin-constants';
12
+ import { PersistenceKeys, Repository, Adapter } from '@decaf-ts/core';
2
13
  import { __decorate, __param, __metadata } from 'tslib';
3
- import { Global, Module, Inject, Scope } from '@nestjs/common';
4
14
  import { ModuleRef } from '@nestjs/core';
5
- import { LoggedClass } from '@decaf-ts/logging/lib/LoggedClass';
15
+ import { Logging, toKebabCase, LoggedClass } from '@decaf-ts/logging';
16
+ import { ApiOperation, ApiBody, ApiCreatedResponse, ApiBadRequestResponse, ApiUnprocessableEntityResponse, getSchemaPath, ApiParam, ApiOkResponse, ApiNotFoundResponse, ApiTags, ApiExtraModels } from '@nestjs/swagger';
17
+ import { InternalError } from '@decaf-ts/db-decorators';
18
+
19
+ /* eslint-disable @typescript-eslint/no-unsafe-function-type */
20
+ function createMethodDecorator(metakey, metadata, { overrideExisting } = { overrideExisting: true }) {
21
+ return (target, key, descriptor) => {
22
+ if (typeof metadata === "object") {
23
+ const prevValue = Reflect.getMetadata(metakey, descriptor.value);
24
+ if (prevValue && !overrideExisting) {
25
+ return descriptor;
26
+ }
27
+ Reflect.defineMetadata(metakey, { ...prevValue, ...metadata }, descriptor.value);
28
+ return descriptor;
29
+ }
30
+ Reflect.defineMetadata(metakey, metadata, descriptor.value);
31
+ return descriptor;
32
+ };
33
+ }
34
+ function createClassDecorator(metakey, metadata = []) {
35
+ return (target) => {
36
+ const prevValue = Reflect.getMetadata(metakey, target) || [];
37
+ Reflect.defineMetadata(metakey, [...prevValue, ...metadata], target);
38
+ return target;
39
+ };
40
+ }
41
+ function createPropertyDecorator(metakey, metadata, overrideExisting = true) {
42
+ return (target, propertyKey) => {
43
+ const properties = Reflect.getMetadata(DECORATORS.API_MODEL_PROPERTIES_ARRAY, target) || [];
44
+ const key = `:${propertyKey}`;
45
+ if (!properties.includes(key)) {
46
+ Reflect.defineMetadata(DECORATORS.API_MODEL_PROPERTIES_ARRAY, [...properties, `:${propertyKey}`], target);
47
+ }
48
+ const existingMetadata = Reflect.getMetadata(metakey, target, propertyKey);
49
+ if (existingMetadata) {
50
+ const newMetadata = pickBy(metadata, negate(isUndefined));
51
+ const metadataToSave = overrideExisting
52
+ ? {
53
+ ...existingMetadata,
54
+ ...newMetadata,
55
+ }
56
+ : {
57
+ ...newMetadata,
58
+ ...existingMetadata,
59
+ };
60
+ Reflect.defineMetadata(metakey, metadataToSave, target, propertyKey);
61
+ }
62
+ else {
63
+ const type =
64
+ // @ts-expect-error nest js override
65
+ target?.constructor?.[METADATA_FACTORY_NAME]?.()[propertyKey]?.type ??
66
+ Reflect.getMetadata("design:type", target, propertyKey);
67
+ Reflect.defineMetadata(metakey, {
68
+ type,
69
+ ...pickBy(metadata, negate(isUndefined)),
70
+ }, target, propertyKey);
71
+ }
72
+ };
73
+ }
74
+ function createMixedDecorator(metakey, metadata) {
75
+ return (target, key, descriptor) => {
76
+ if (descriptor) {
77
+ let metadatas;
78
+ if (Array.isArray(metadata)) {
79
+ const previousMetadata = Reflect.getMetadata(metakey, descriptor.value) || [];
80
+ metadatas = [...previousMetadata, ...metadata];
81
+ }
82
+ else {
83
+ const previousMetadata = Reflect.getMetadata(metakey, descriptor.value) || {};
84
+ metadatas = { ...previousMetadata, ...metadata };
85
+ }
86
+ Reflect.defineMetadata(metakey, metadatas, descriptor.value);
87
+ return descriptor;
88
+ }
89
+ let metadatas;
90
+ if (Array.isArray(metadata)) {
91
+ const previousMetadata = Reflect.getMetadata(metakey, target) || [];
92
+ metadatas = [...previousMetadata, ...metadata];
93
+ }
94
+ else {
95
+ const previousMetadata = Reflect.getMetadata(metakey, target) || {};
96
+ metadatas = Object.assign(Object.assign({}, previousMetadata), metadata);
97
+ }
98
+ Reflect.defineMetadata(metakey, metadatas, target);
99
+ return target;
100
+ };
101
+ }
102
+ function createParamDecorator(metadata, initial) {
103
+ return (target, key, descriptor) => {
104
+ const paramOptions = {
105
+ ...initial,
106
+ ...pickBy(metadata, negate(isUndefined)),
107
+ };
108
+ if (descriptor) {
109
+ const parameters = Reflect.getMetadata(DECORATORS.API_PARAMETERS, descriptor.value) || [];
110
+ Reflect.defineMetadata(DECORATORS.API_PARAMETERS, [...parameters, paramOptions], descriptor.value);
111
+ return descriptor;
112
+ }
113
+ if (typeof target === "object") {
114
+ return target;
115
+ }
116
+ const propertyKeys = Object.getOwnPropertyNames(target.prototype);
117
+ for (const propertyKey of propertyKeys) {
118
+ if (isConstructor(propertyKey)) {
119
+ continue;
120
+ }
121
+ const methodDescriptor = Object.getOwnPropertyDescriptor(target.prototype, propertyKey);
122
+ if (!methodDescriptor) {
123
+ continue;
124
+ }
125
+ const isApiMethod = Reflect.hasMetadata(METHOD_METADATA, methodDescriptor.value);
126
+ if (!isApiMethod) {
127
+ continue;
128
+ }
129
+ const parameters = Reflect.getMetadata(DECORATORS.API_PARAMETERS, methodDescriptor.value) || [];
130
+ Reflect.defineMetadata(DECORATORS.API_PARAMETERS, [...parameters, paramOptions], methodDescriptor.value);
131
+ }
132
+ };
133
+ }
134
+ function getTypeIsArrayTuple(input, isArrayFlag) {
135
+ if (!input) {
136
+ return [input, isArrayFlag];
137
+ }
138
+ if (isArrayFlag) {
139
+ return [input, isArrayFlag];
140
+ }
141
+ const isInputArray = isArray(input);
142
+ const type = isInputArray ? input[0] : input;
143
+ return [type, isInputArray];
144
+ }
145
+
146
+ const isEnumArray = (opts) => (opts.isArray && "enum" in opts && opts.enum !== undefined);
147
+ /**
148
+ * @publicApi
149
+ */
150
+ function ApiProperty(options = {}) {
151
+ return createApiPropertyDecorator(options);
152
+ }
153
+ function createApiPropertyDecorator(options = {}, overrideExisting = true) {
154
+ const [type, isArray] = getTypeIsArrayTuple$1(options.type, options.isArray);
155
+ options = {
156
+ ...options,
157
+ type,
158
+ isArray,
159
+ };
160
+ if (isEnumArray(options)) {
161
+ options.type = "array";
162
+ const enumValues = getEnumValues(options.enum);
163
+ options.items = {
164
+ type: getEnumType(enumValues),
165
+ enum: enumValues,
166
+ };
167
+ // @ts-expect-error nest swagger override
168
+ delete options.enum;
169
+ }
170
+ else if ("enum" in options && options.enum !== undefined) {
171
+ const enumValues = getEnumValues(options.enum);
172
+ options.enum = enumValues;
173
+ options.type = getEnumType(enumValues);
174
+ }
175
+ if (Array.isArray(options.type)) {
176
+ options.type = "array";
177
+ options.items = {
178
+ type: "array",
179
+ items: {
180
+ type: options.type[0],
181
+ },
182
+ };
183
+ }
184
+ return createPropertyDecorator(DECORATORS.API_MODEL_PROPERTIES, options, overrideExisting);
185
+ }
186
+ function ApiPropertyOptional(options = {}) {
187
+ return ApiProperty({
188
+ ...options,
189
+ required: false,
190
+ });
191
+ }
192
+ function ApiResponseProperty(options = {}) {
193
+ return ApiProperty({
194
+ readOnly: true,
195
+ ...options,
196
+ });
197
+ }
198
+
199
+ Decoration.for(InjectablesKeys.INJECTABLE)
200
+ .extend({
201
+ decorator: function nestInjectable(category, cfg) {
202
+ return Injectable({
203
+ scope: cfg.singleton ? Scope.DEFAULT : Scope.REQUEST,
204
+ durable: cfg.singleton ? undefined : true,
205
+ });
206
+ },
207
+ })
208
+ .apply();
209
+ Decoration.for(InjectablesKeys.INJECT)
210
+ .extend({
211
+ decorator: function nestInject(category,
212
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
213
+ cfg) {
214
+ return function innerNestInject(target, propertyKey, descriptor) {
215
+ return Inject(category || target)(target, propertyKey, descriptor);
216
+ };
217
+ },
218
+ })
219
+ .apply();
220
+ Decoration.for(ValidationKeys.REQUIRED)
221
+ .extend(ApiProperty({
222
+ required: true,
223
+ }))
224
+ .apply();
225
+ Decoration.for(ValidationKeys.MAX)
226
+ .extend({
227
+ decorator: function maxDec(max) {
228
+ return ApiProperty({ maximum: max });
229
+ },
230
+ })
231
+ .apply();
232
+ Decoration.for(ValidationKeys.MIN)
233
+ .extend({
234
+ decorator: function minDec(min) {
235
+ return ApiProperty({ minimum: min });
236
+ },
237
+ })
238
+ .apply();
239
+ Decoration.for(ValidationKeys.MAX_LENGTH)
240
+ .extend({
241
+ decorator: function maxLengthDec(max) {
242
+ return ApiProperty({ maxLength: max });
243
+ },
244
+ })
245
+ .apply();
246
+ Decoration.for(ValidationKeys.MIN_LENGTH)
247
+ .extend({
248
+ decorator: function minLengthDec(min) {
249
+ return ApiProperty({ minLength: min });
250
+ },
251
+ })
252
+ .apply();
253
+ //
254
+ // Decoration.for(ValidationKeys.TYPE)
255
+ // .extend({
256
+ // decorator: function typeDec(type: (string | (() => string))[] | string | (() => string)) {
257
+ // return ApiProperty({ type: type as any });
258
+ // },
259
+ // })
260
+ // .apply();
261
+ //
262
+ // Decoration.for(ValidationKeys.DATE)
263
+ // .extend({
264
+ // decorator: function dateDec() {
265
+ // return ApiProperty({ type: Date });
266
+ // },
267
+ // })
268
+ // .apply();
269
+ Decoration.for(ValidationKeys.LIST)
270
+ .extend({
271
+ decorator: function listDec(clazz) {
272
+ const c = Array.isArray(clazz) ? clazz[0] : clazz;
273
+ return ApiProperty({ type: [c] });
274
+ },
275
+ })
276
+ .apply();
277
+ //
278
+ // Decoration.for(ValidationKeys.OPTION)
279
+ // .extend({
280
+ // decorator: function optionDec(options: string[] | Record<string, any>) {
281
+ // const opts = Array.isArray(options) ? options : Object.values(options);
282
+ // return ApiProperty({ enum: opts });
283
+ // },
284
+ // })
285
+ // .apply();
286
+ Decoration.for(ValidationKeys.PATTERN)
287
+ .extend({
288
+ decorator: function patternDec(pat) {
289
+ return ApiProperty({
290
+ pattern: typeof pat === "string" ? pat : pat.source,
291
+ });
292
+ },
293
+ })
294
+ .apply();
295
+ Decoration.for(PersistenceKeys.COLUMN)
296
+ .extend({
297
+ decorator: function columnDec(name) {
298
+ return ApiProperty({
299
+ name: name,
300
+ });
301
+ },
302
+ })
303
+ .apply();
304
+ Decoration.for(DecorationKeys.DESCRIPTION)
305
+ .extend({
306
+ decorator: function descriptionDec(description) {
307
+ return ApiProperty({
308
+ description: description,
309
+ });
310
+ },
311
+ })
312
+ .apply();
6
313
 
7
314
  const DECAF_MODULE_OPTIONS = "DecafModuleOptions";
8
315
  const DECAF_ADAPTER_ID = "DecafAdapter";
9
316
 
10
317
  var DecafCoreModule_1;
11
- let DecafCoreModule = DecafCoreModule_1 = class DecafCoreModule extends LoggedClass {
318
+ let DecafCoreModule = class DecafCoreModule {
319
+ static { DecafCoreModule_1 = this; }
320
+ static { this._adapterInstance = null; }
321
+ static get log() {
322
+ if (!this._logger)
323
+ this._logger = Logging.for(DecafCoreModule_1);
324
+ return this._logger;
325
+ }
12
326
  constructor(options, moduleRef) {
13
- super();
14
327
  this.options = options;
15
328
  this.moduleRef = moduleRef;
16
329
  }
330
+ static async createAdapter(options) {
331
+ if (!this._adapterInstance) {
332
+ const log = this.log.for(this.createAdapter);
333
+ log.info("Creating adapter instance...");
334
+ this._adapterInstance = new options.adapter(options.conf, options.alias);
335
+ log.info("Adapter instance created successfully!");
336
+ }
337
+ return this._adapterInstance;
338
+ }
339
+ static getAdapterInstance() {
340
+ return this._adapterInstance;
341
+ }
17
342
  static forRoot(options) {
18
343
  const typeOrmModuleOptions = {
19
344
  provide: DECAF_MODULE_OPTIONS,
@@ -21,7 +346,7 @@ let DecafCoreModule = DecafCoreModule_1 = class DecafCoreModule extends LoggedCl
21
346
  };
22
347
  const adapter = {
23
348
  useFactory: async (opts) => {
24
- return new opts.adapter(opts.conf, opts.alias);
349
+ return DecafCoreModule_1.createAdapter(opts);
25
350
  },
26
351
  provide: DECAF_ADAPTER_ID,
27
352
  durable: true,
@@ -37,15 +362,17 @@ let DecafCoreModule = DecafCoreModule_1 = class DecafCoreModule extends LoggedCl
37
362
  };
38
363
  }
39
364
  async onApplicationShutdown() {
365
+ const log = DecafCoreModule_1.log.for(this.onApplicationShutdown);
40
366
  const adapter = this.moduleRef.get(DECAF_ADAPTER_ID);
41
367
  try {
42
368
  if (adapter) {
43
- this.log.info("Shutting down");
369
+ log.info("Shutting down");
44
370
  await adapter.shutdown();
371
+ DecafCoreModule_1._adapterInstance = null;
45
372
  }
46
373
  }
47
374
  catch (e) {
48
- this.log.error(`Failed to shutdown application`, e);
375
+ log.error(`Failed to shutdown application`, e);
49
376
  }
50
377
  }
51
378
  };
@@ -56,15 +383,215 @@ DecafCoreModule = DecafCoreModule_1 = __decorate([
56
383
  __metadata("design:paramtypes", [Object, ModuleRef])
57
384
  ], DecafCoreModule);
58
385
 
386
+ let RepoFactory = class RepoFactory {
387
+ for(model) {
388
+ model = typeof model === "string" ? Model.get(model) : model;
389
+ if (!model) {
390
+ throw new InternalError(`Failed to find repository for ${model}`);
391
+ }
392
+ return Repository.forModel(model);
393
+ }
394
+ };
395
+ RepoFactory = __decorate([
396
+ Injectable()
397
+ ], RepoFactory);
398
+
399
+ var DecafModelModule_1;
400
+ let DecafModelModule = class DecafModelModule {
401
+ static { DecafModelModule_1 = this; }
402
+ static get log() {
403
+ if (!this._logger)
404
+ this._logger = Logging.for(DecafModelModule_1);
405
+ return this._logger;
406
+ }
407
+ static toModelController(ModelClazz) {
408
+ const log = this.log.for(this.toModelController);
409
+ const tableName = Repository.table(ModelClazz);
410
+ const routePath = toKebabCase(tableName);
411
+ const modelClazzName = ModelClazz.name;
412
+ log.debug(`Creating controller for model: ${modelClazzName}`);
413
+ let DynamicModelController = class DynamicModelController extends LoggedClass {
414
+ constructor(repoFactory) {
415
+ super();
416
+ this.repoFactory = repoFactory;
417
+ log.info(`Registering dynamic controller for model: ${modelClazzName} route: /${routePath}`);
418
+ try {
419
+ this.repo = this.repoFactory.for(ModelClazz.name);
420
+ this.pk = this.repo.pk;
421
+ }
422
+ catch (e) {
423
+ this.log.error(`Failed to initialize repository for model "${ModelClazz.name}".`, e);
424
+ }
425
+ }
426
+ async create(data) {
427
+ const log = this.log.for(this.create);
428
+ log.verbose(`creating new ${modelClazzName}`);
429
+ let created;
430
+ try {
431
+ created = await this.repo.create(data);
432
+ }
433
+ catch (e) {
434
+ log.error(`Failed to create new ${modelClazzName}`, e);
435
+ throw e;
436
+ }
437
+ log.info(`created new ${modelClazzName} with id ${created[this.pk]}`);
438
+ return created;
439
+ }
440
+ async read(id) {
441
+ const log = this.log.for(this.read);
442
+ let read;
443
+ try {
444
+ log.debug(`reading ${modelClazzName} with ${this.pk} ${id}`);
445
+ read = await this.repo.read(id);
446
+ }
447
+ catch (e) {
448
+ log.error(`Failed to read ${modelClazzName} with id ${id}`, e);
449
+ throw e;
450
+ }
451
+ log.info(`read ${modelClazzName} with id ${read[this.pk]}`);
452
+ return read;
453
+ }
454
+ async update(data) {
455
+ const log = this.log.for(this.update);
456
+ let updated;
457
+ try {
458
+ log.info(`updating ${modelClazzName} with ${this.pk} ${data[this.pk]}`);
459
+ updated = await this.repo.create(data);
460
+ }
461
+ catch (e) {
462
+ throw e;
463
+ }
464
+ return updated;
465
+ }
466
+ async delete(id) {
467
+ const log = this.log.for(this.delete);
468
+ let read;
469
+ try {
470
+ log.debug(`deleting ${modelClazzName} with ${this.pk} ${id}`);
471
+ read = await this.repo.read(id);
472
+ }
473
+ catch (e) {
474
+ log.error(`Failed to delete ${modelClazzName} with id ${id}`, e);
475
+ throw e;
476
+ }
477
+ log.info(`deleted ${modelClazzName} with id ${read[this.pk]}`);
478
+ return read;
479
+ }
480
+ };
481
+ __decorate([
482
+ Post(),
483
+ ApiOperation({ summary: `Create a new ${modelClazzName}.` }),
484
+ ApiBody({
485
+ description: `Payload for ${modelClazzName}`,
486
+ schema: { $ref: getSchemaPath(ModelClazz) },
487
+ }),
488
+ ApiCreatedResponse({
489
+ description: `${modelClazzName} created successfully.`,
490
+ }),
491
+ ApiBadRequestResponse({ description: "Payload validation failed." }),
492
+ ApiUnprocessableEntityResponse({
493
+ description: "Repository rejected the provided payload.",
494
+ }),
495
+ __param(0, Body()),
496
+ __metadata("design:type", Function),
497
+ __metadata("design:paramtypes", [Object]),
498
+ __metadata("design:returntype", Promise)
499
+ ], DynamicModelController.prototype, "create", null);
500
+ __decorate([
501
+ Get(":id"),
502
+ ApiOperation({ summary: `Retrieve a ${modelClazzName} record by id.` }),
503
+ ApiParam({ name: "id", description: "Primary key" }),
504
+ ApiOkResponse({
505
+ description: `${modelClazzName} retrieved successfully.`,
506
+ }),
507
+ ApiNotFoundResponse({
508
+ description: `No ${modelClazzName} record matches the provided identifier.`,
509
+ }),
510
+ __param(0, Param("id")),
511
+ __metadata("design:type", Function),
512
+ __metadata("design:paramtypes", [String]),
513
+ __metadata("design:returntype", Promise)
514
+ ], DynamicModelController.prototype, "read", null);
515
+ __decorate([
516
+ Put(":id"),
517
+ ApiOperation({
518
+ summary: `Replace an existing ${modelClazzName} record with a new payload.`,
519
+ }),
520
+ ApiBody({
521
+ description: `Payload for replace a existing record of ${modelClazzName}`,
522
+ schema: { $ref: getSchemaPath(ModelClazz) },
523
+ }),
524
+ ApiOkResponse({
525
+ description: `${ModelClazz} record replaced successfully.`,
526
+ }),
527
+ ApiNotFoundResponse({
528
+ description: `No ${modelClazzName} record matches the provided identifier.`,
529
+ }),
530
+ ApiBadRequestResponse({ description: "Payload validation failed." }),
531
+ __param(0, Body()),
532
+ __metadata("design:type", Function),
533
+ __metadata("design:paramtypes", [Model]),
534
+ __metadata("design:returntype", Promise)
535
+ ], DynamicModelController.prototype, "update", null);
536
+ __decorate([
537
+ Delete(":id"),
538
+ ApiOperation({ summary: `Delete a ${modelClazzName} record by id.` }),
539
+ ApiParam({
540
+ name: "id",
541
+ description: `Primary key value of the ${modelClazzName} record to delete.`,
542
+ }),
543
+ ApiOkResponse({
544
+ description: `${modelClazzName} record deleted successfully.`,
545
+ }),
546
+ ApiNotFoundResponse({
547
+ description: `No ${modelClazzName} record matches the provided identifier.`,
548
+ }),
549
+ __param(0, Param("id")),
550
+ __metadata("design:type", Function),
551
+ __metadata("design:paramtypes", [String]),
552
+ __metadata("design:returntype", Promise)
553
+ ], DynamicModelController.prototype, "delete", null);
554
+ DynamicModelController = __decorate([
555
+ Controller(routePath),
556
+ ApiTags(modelClazzName),
557
+ ApiExtraModels(ModelClazz),
558
+ __metadata("design:paramtypes", [RepoFactory])
559
+ ], DynamicModelController);
560
+ return DynamicModelController;
561
+ }
562
+ static forRoot(flavour) {
563
+ const log = this.log.for(this.forRoot);
564
+ log.info(`Generating controllers for flavour...`);
565
+ const trackedModels = Adapter.models(flavour);
566
+ const controllers = trackedModels.map(this.toModelController.bind(this));
567
+ log.info(`Generated ${controllers.length} controllers`);
568
+ return {
569
+ module: DecafModelModule_1,
570
+ controllers,
571
+ providers: [RepoFactory],
572
+ };
573
+ }
574
+ };
575
+ DecafModelModule = DecafModelModule_1 = __decorate([
576
+ Module({})
577
+ ], DecafModelModule);
578
+
59
579
  var DecafModule_1;
60
580
  /**
61
581
  * @publicApi
62
582
  */
63
583
  let DecafModule = DecafModule_1 = class DecafModule {
64
- static forRoot(options) {
584
+ static async forRootAsync(options) {
585
+ const { autoControllers } = options;
586
+ const adapter = await DecafCoreModule.createAdapter(options);
587
+ const flavour = adapter.flavour;
588
+ const imports = [DecafCoreModule.forRoot(options)];
589
+ if (autoControllers) {
590
+ imports.push(DecafModelModule.forRoot(flavour));
591
+ }
65
592
  return {
66
593
  module: DecafModule_1,
67
- imports: [DecafCoreModule.forRoot(options)],
594
+ imports: imports,
68
595
  };
69
596
  }
70
597
  };
@@ -72,8 +599,16 @@ DecafModule = DecafModule_1 = __decorate([
72
599
  Module({})
73
600
  ], DecafModule);
74
601
 
602
+ function repoForModel(model) {
603
+ const m = Model.get(model);
604
+ if (!m)
605
+ throw new InternalError(`Failed to find repository for ${model}`);
606
+ const repo = Repository.forModel(m);
607
+ return repo;
608
+ }
609
+
75
610
  /**
76
- * @module ts-workspace
611
+ * @module for-nest
77
612
  * @description This module serves as the main entry point for the ts-workspace library. It aggregates and exports
78
613
  * functionality from various submodules and utilities within the project.
79
614
  *
@@ -99,9 +634,9 @@ DecafModule = DecafModule_1 = __decorate([
99
634
  * @constant
100
635
  * @type {string}
101
636
  */
102
- const VERSION = "0.0.1";
637
+ const VERSION = "0.0.4";
103
638
  const PACKAGE_NAME = "##PACKAGE_NAME##";
104
639
  Metadata.registerLibrary(PACKAGE_NAME, VERSION);
105
640
 
106
- export { DECAF_ADAPTER_ID, DECAF_MODULE_OPTIONS, DecafModule, PACKAGE_NAME, VERSION };
107
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9yLW5lc3QuZXNtLmNqcyIsInNvdXJjZXMiOlsiLi4vc3JjL2NvbnN0YW50cy50cyIsIi4uL3NyYy9jb3JlLW1vZHVsZS50cyIsIi4uL3NyYy9tb2R1bGUudHMiLCIuLi9zcmMvaW5kZXgudHMiXSwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGNvbnN0IERFQ0FGX01PRFVMRV9PUFRJT05TID0gXCJEZWNhZk1vZHVsZU9wdGlvbnNcIjtcbmV4cG9ydCBjb25zdCBERUNBRl9BREFQVEVSX0lEID0gXCJEZWNhZkFkYXB0ZXJcIjtcbiIsImltcG9ydCB7XG4gIER5bmFtaWNNb2R1bGUsXG4gIEdsb2JhbCxcbiAgSW5qZWN0LFxuICBNb2R1bGUsXG4gIE9uQXBwbGljYXRpb25TaHV0ZG93bixcbiAgU2NvcGUsXG59IGZyb20gXCJAbmVzdGpzL2NvbW1vblwiO1xuaW1wb3J0IHsgTW9kdWxlUmVmIH0gZnJvbSBcIkBuZXN0anMvY29yZVwiO1xuaW1wb3J0IHR5cGUgeyBEZWNhZk1vZHVsZU9wdGlvbnMgfSBmcm9tIFwiLi90eXBlc1wiO1xuaW1wb3J0IHsgREVDQUZfQURBUFRFUl9JRCwgREVDQUZfTU9EVUxFX09QVElPTlMgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IEZhY3RvcnlQcm92aWRlciB9IGZyb20gXCJAbmVzdGpzL2NvbW1vbi9pbnRlcmZhY2VzL21vZHVsZXMvcHJvdmlkZXIuaW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBBZGFwdGVyIH0gZnJvbSBcIkBkZWNhZi10cy9jb3JlXCI7XG5pbXBvcnQgeyBMb2dnZWRDbGFzcyB9IGZyb20gXCJAZGVjYWYtdHMvbG9nZ2luZy9saWIvTG9nZ2VkQ2xhc3NcIjtcblxuQEdsb2JhbCgpXG5ATW9kdWxlKHt9KVxuZXhwb3J0IGNsYXNzIERlY2FmQ29yZU1vZHVsZTxcbiAgICBDT05GLFxuICAgIEFEQVBURVIgZXh0ZW5kcyBBZGFwdGVyPENPTkYsIGFueSwgYW55LCBhbnksIGFueT4sXG4gID5cbiAgZXh0ZW5kcyBMb2dnZWRDbGFzc1xuICBpbXBsZW1lbnRzIE9uQXBwbGljYXRpb25TaHV0ZG93blxue1xuICBjb25zdHJ1Y3RvcihcbiAgICBASW5qZWN0KERFQ0FGX01PRFVMRV9PUFRJT05TKVxuICAgIHByaXZhdGUgcmVhZG9ubHkgb3B0aW9uczogRGVjYWZNb2R1bGVPcHRpb25zPENPTkYsIEFEQVBURVI+LFxuICAgIHByaXZhdGUgcmVhZG9ubHkgbW9kdWxlUmVmOiBNb2R1bGVSZWZcbiAgKSB7XG4gICAgc3VwZXIoKTtcbiAgfVxuXG4gIHN0YXRpYyBmb3JSb290KG9wdGlvbnM6IERlY2FmTW9kdWxlT3B0aW9ucyk6IER5bmFtaWNNb2R1bGUge1xuICAgIGNvbnN0IHR5cGVPcm1Nb2R1bGVPcHRpb25zID0ge1xuICAgICAgcHJvdmlkZTogREVDQUZfTU9EVUxFX09QVElPTlMsXG4gICAgICB1c2VWYWx1ZTogb3B0aW9ucyxcbiAgICB9O1xuXG4gICAgY29uc3QgYWRhcHRlcjogRmFjdG9yeVByb3ZpZGVyPGFueT4gPSB7XG4gICAgICB1c2VGYWN0b3J5OiBhc3luYyAob3B0czogRGVjYWZNb2R1bGVPcHRpb25zKSA9PiB7XG4gICAgICAgIHJldHVybiBuZXcgb3B0cy5hZGFwdGVyKG9wdHMuY29uZiwgb3B0cy5hbGlhcyk7XG4gICAgICB9LFxuICAgICAgcHJvdmlkZTogREVDQUZfQURBUFRFUl9JRCxcbiAgICAgIGR1cmFibGU6IHRydWUsXG4gICAgICBzY29wZTogU2NvcGUuREVGQVVMVCxcbiAgICAgIGluamVjdDogW0RFQ0FGX01PRFVMRV9PUFRJT05TXSxcbiAgICB9O1xuXG4gICAgY29uc3QgcHJvdmlkZXJzID0gW2FkYXB0ZXIsIHR5cGVPcm1Nb2R1bGVPcHRpb25zXTtcbiAgICBjb25zdCBleHBvcnRzID0gW2FkYXB0ZXJdO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIG1vZHVsZTogRGVjYWZDb3JlTW9kdWxlLFxuICAgICAgcHJvdmlkZXJzLFxuICAgICAgZXhwb3J0cyxcbiAgICB9O1xuICB9XG5cbiAgYXN5bmMgb25BcHBsaWNhdGlvblNodXRkb3duKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGFkYXB0ZXIgPSB0aGlzLm1vZHVsZVJlZi5nZXQ8QURBUFRFUj4oREVDQUZfQURBUFRFUl9JRCk7XG4gICAgdHJ5IHtcbiAgICAgIGlmIChhZGFwdGVyKSB7XG4gICAgICAgIHRoaXMubG9nLmluZm8oXCJTaHV0dGluZyBkb3duXCIpO1xuICAgICAgICBhd2FpdCBhZGFwdGVyLnNodXRkb3duKCk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgdGhpcy5sb2cuZXJyb3IoYEZhaWxlZCB0byBzaHV0ZG93biBhcHBsaWNhdGlvbmAsIGUgYXMgRXJyb3IpO1xuICAgIH1cbiAgfVxufVxuIiwiaW1wb3J0IHsgRHluYW1pY01vZHVsZSwgTW9kdWxlIH0gZnJvbSBcIkBuZXN0anMvY29tbW9uXCI7XG5pbXBvcnQgeyBEZWNhZk1vZHVsZU9wdGlvbnMgfSBmcm9tIFwiLi90eXBlc1wiO1xuaW1wb3J0IHsgRGVjYWZDb3JlTW9kdWxlIH0gZnJvbSBcIi4vY29yZS1tb2R1bGVcIjtcblxuLyoqXG4gKiBAcHVibGljQXBpXG4gKi9cbkBNb2R1bGUoe30pXG5leHBvcnQgY2xhc3MgRGVjYWZNb2R1bGUge1xuICBzdGF0aWMgZm9yUm9vdChvcHRpb25zOiBEZWNhZk1vZHVsZU9wdGlvbnMpOiBEeW5hbWljTW9kdWxlIHtcbiAgICByZXR1cm4ge1xuICAgICAgbW9kdWxlOiBEZWNhZk1vZHVsZSxcbiAgICAgIGltcG9ydHM6IFtEZWNhZkNvcmVNb2R1bGUuZm9yUm9vdChvcHRpb25zKV0sXG4gICAgfTtcbiAgfVxufVxuIiwiLyoqXG4gKiBAbW9kdWxlIHRzLXdvcmtzcGFjZVxuICogQGRlc2NyaXB0aW9uIFRoaXMgbW9kdWxlIHNlcnZlcyBhcyB0aGUgbWFpbiBlbnRyeSBwb2ludCBmb3IgdGhlIHRzLXdvcmtzcGFjZSBsaWJyYXJ5LiBJdCBhZ2dyZWdhdGVzIGFuZCBleHBvcnRzXG4gKiBmdW5jdGlvbmFsaXR5IGZyb20gdmFyaW91cyBzdWJtb2R1bGVzIGFuZCB1dGlsaXRpZXMgd2l0aGluIHRoZSBwcm9qZWN0LlxuICpcbiAqIFRoZSBtb2R1bGUgaW5jbHVkZXM6XG4gKiAxLiBVdGlsaXR5IGZ1bmN0aW9ucyBhbmQgdHlwZXMgZnJvbSB0aGUgXCIuL3V0aWxzXCIgZGlyZWN0b3J5OlxuICogICAgLSBUaGVzZSBsaWtlbHkgY29udGFpbiBoZWxwZXIgZnVuY3Rpb25zLCBjb21tb24gdHlwZXMsIGFuZCBzaGFyZWQgZnVuY3Rpb25hbGl0eSB1c2VkIHRocm91Z2hvdXQgdGhlIHByb2plY3QuXG4gKiAgICAtIE1heSBpbmNsdWRlIG9wZXJhdGlvbnMgZm9yIGRhdGEgbWFuaXB1bGF0aW9uLCB0eXBlIGNoZWNraW5nLCBvciBvdGhlciBnZW5lcmFsLXB1cnBvc2UgdXRpbGl0aWVzLlxuICpcbiAqIDIuIEEgbmFtZXNwYWNlIGFuZCByZWxhdGVkIHR5cGVzIGZyb20gdGhlIFwiLi9uYW1lc3BhY2VcIiBkaXJlY3Rvcnk6XG4gKiAgICAtIFRoaXMgY291bGQgY29udGFpbiBkb21haW4tc3BlY2lmaWMgY29kZSBvciBhIGNvbGxlY3Rpb24gb2YgcmVsYXRlZCBmdW5jdGlvbmFsaXR5LlxuICogICAgLSBNaWdodCBpbmNsdWRlIGludGVyZmFjZXMsIHR5cGVzLCBvciBjbGFzc2VzIHRoYXQgcmVwcmVzZW50IGNvcmUgY29uY2VwdHMgaW4gdGhlIGxpYnJhcnkuXG4gKlxuICogMy4gQSBWRVJTSU9OIGNvbnN0YW50OlxuICogICAgLSBSZXByZXNlbnRzIHRoZSBjdXJyZW50IHZlcnNpb24gb2YgdGhlIG1vZHVsZS5cbiAqICAgIC0gVXNlZnVsIGZvciB2ZXJzaW9uIGNoZWNraW5nIGFuZCBjb21wYXRpYmlsaXR5IHB1cnBvc2VzLlxuICpcbiAqIFRoaXMgc3RydWN0dXJlIHByb3ZpZGVzIGEgY2xlYW4gYW5kIG9yZ2FuaXplZCBleHBvcnQgb2YgdGhlIG1vZHVsZSdzIGZ1bmN0aW9uYWxpdHksIGFsbG93aW5nIGNvbnN1bWVyc1xuICogdG8gZWFzaWx5IGltcG9ydCBhbmQgdXNlIHNwZWNpZmljIHBhcnRzIG9mIHRoZSBsaWJyYXJ5IGFzIG5lZWRlZC5cbiAqL1xuXG5pbXBvcnQgeyBNZXRhZGF0YSB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdGlvblwiO1xuXG5leHBvcnQgKiBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL21vZHVsZVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vdHlwZXNcIjtcblxuLyoqXG4gKiBSZXByZXNlbnRzIHRoZSBjdXJyZW50IHZlcnNpb24gb2YgdGhlIHRzLXdvcmtzcGFjZSBtb2R1bGUuXG4gKiBUaGUgYWN0dWFsIHZlcnNpb24gbnVtYmVyIGlzIHJlcGxhY2VkIGR1cmluZyB0aGUgYnVpbGQgcHJvY2Vzcy5cbiAqIEBjb25zdGFudFxuICogQHR5cGUge3N0cmluZ31cbiAqL1xuZXhwb3J0IGNvbnN0IFZFUlNJT04gPSBcIiMjVkVSU0lPTiMjXCI7XG5leHBvcnQgY29uc3QgUEFDS0FHRV9OQU1FID0gXCIjI1BBQ0tBR0VfTkFNRSMjXCI7XG5cbk1ldGFkYXRhLnJlZ2lzdGVyTGlicmFyeShQQUNLQUdFX05BTUUsIFZFUlNJT04pO1xuIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFPLE1BQU0sb0JBQW9CLEdBQUc7QUFDN0IsTUFBTSxnQkFBZ0IsR0FBRzs7O0FDZ0J6QixJQUFNLGVBQWUsR0FBQSxpQkFBQSxHQUFyQixNQUFNLGVBSVgsU0FBUSxXQUFXLENBQUE7SUFHbkIsV0FFbUIsQ0FBQSxPQUEwQyxFQUMxQyxTQUFvQixFQUFBO0FBRXJDLFFBQUEsS0FBSyxFQUFFO1FBSFUsSUFBTyxDQUFBLE9BQUEsR0FBUCxPQUFPO1FBQ1AsSUFBUyxDQUFBLFNBQUEsR0FBVCxTQUFTOztJQUs1QixPQUFPLE9BQU8sQ0FBQyxPQUEyQixFQUFBO0FBQ3hDLFFBQUEsTUFBTSxvQkFBb0IsR0FBRztBQUMzQixZQUFBLE9BQU8sRUFBRSxvQkFBb0I7QUFDN0IsWUFBQSxRQUFRLEVBQUUsT0FBTztTQUNsQjtBQUVELFFBQUEsTUFBTSxPQUFPLEdBQXlCO0FBQ3BDLFlBQUEsVUFBVSxFQUFFLE9BQU8sSUFBd0IsS0FBSTtBQUM3QyxnQkFBQSxPQUFPLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUM7YUFDL0M7QUFDRCxZQUFBLE9BQU8sRUFBRSxnQkFBZ0I7QUFDekIsWUFBQSxPQUFPLEVBQUUsSUFBSTtZQUNiLEtBQUssRUFBRSxLQUFLLENBQUMsT0FBTztZQUNwQixNQUFNLEVBQUUsQ0FBQyxvQkFBb0IsQ0FBQztTQUMvQjtBQUVELFFBQUEsTUFBTSxTQUFTLEdBQUcsQ0FBQyxPQUFPLEVBQUUsb0JBQW9CLENBQUM7QUFDakQsUUFBQSxNQUFNLE9BQU8sR0FBRyxDQUFDLE9BQU8sQ0FBQztRQUV6QixPQUFPO0FBQ0wsWUFBQSxNQUFNLEVBQUUsaUJBQWU7WUFDdkIsU0FBUztZQUNULE9BQU87U0FDUjs7QUFHSCxJQUFBLE1BQU0scUJBQXFCLEdBQUE7UUFDekIsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQVUsZ0JBQWdCLENBQUM7QUFDN0QsUUFBQSxJQUFJO1lBQ0YsSUFBSSxPQUFPLEVBQUU7QUFDWCxnQkFBQSxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUM7QUFDOUIsZ0JBQUEsTUFBTSxPQUFPLENBQUMsUUFBUSxFQUFFOzs7UUFFMUIsT0FBTyxDQUFVLEVBQUU7WUFDbkIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBZ0MsOEJBQUEsQ0FBQSxFQUFFLENBQVUsQ0FBQzs7O0NBR2pFO0FBcERZLGVBQWUsR0FBQSxpQkFBQSxHQUFBLFVBQUEsQ0FBQTtBQUYzQixJQUFBLE1BQU0sRUFBRTtJQUNSLE1BQU0sQ0FBQyxFQUFFLENBQUM7QUFTTixJQUFBLE9BQUEsQ0FBQSxDQUFBLEVBQUEsTUFBTSxDQUFDLG9CQUFvQixDQUFDLENBQUE7NkNBRUQsU0FBUyxDQUFBO0FBVjVCLENBQUEsRUFBQSxlQUFlLENBb0QzQjs7O0FDakVEOztBQUVHO0FBRVUsSUFBQSxXQUFXLEdBQWpCLGFBQUEsR0FBQSxNQUFNLFdBQVcsQ0FBQTtJQUN0QixPQUFPLE9BQU8sQ0FBQyxPQUEyQixFQUFBO1FBQ3hDLE9BQU87QUFDTCxZQUFBLE1BQU0sRUFBRSxhQUFXO1lBQ25CLE9BQU8sRUFBRSxDQUFDLGVBQWUsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUM7U0FDNUM7OztBQUxRLFdBQVcsR0FBQSxhQUFBLEdBQUEsVUFBQSxDQUFBO0lBRHZCLE1BQU0sQ0FBQyxFQUFFO0FBQ0csQ0FBQSxFQUFBLFdBQVcsQ0FPdkI7O0FDZkQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBb0JHO0FBUUg7Ozs7O0FBS0c7QUFDSSxNQUFNLE9BQU8sR0FBRztBQUNoQixNQUFNLFlBQVksR0FBRztBQUU1QixRQUFRLENBQUMsZUFBZSxDQUFDLFlBQVksRUFBRSxPQUFPLENBQUM7Ozs7In0=
641
+ export { ApiProperty, ApiPropertyOptional, ApiResponseProperty, DECAF_ADAPTER_ID, DECAF_MODULE_OPTIONS, DecafModule, PACKAGE_NAME, RepoFactory, VERSION, createApiPropertyDecorator, createClassDecorator, createMethodDecorator, createMixedDecorator, createParamDecorator, createPropertyDecorator, getTypeIsArrayTuple, repoForModel };
642
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9yLW5lc3QuZXNtLmNqcyIsInNvdXJjZXMiOlsiLi4vc3JjL2RlY29yYXRvcnMvaGVscGVycy50cyIsIi4uL3NyYy9kZWNvcmF0b3JzL0FwaVByb3BlcnR5LnRzIiwiLi4vc3JjL2RlY29yYXRpb24udHMiLCIuLi9zcmMvY29uc3RhbnRzLnRzIiwiLi4vc3JjL2NvcmUtbW9kdWxlLnRzIiwiLi4vc3JjL1JlcG9GYWN0b3J5LnRzIiwiLi4vc3JjL21vZGVsLW1vZHVsZS50cyIsIi4uL3NyYy9tb2R1bGUudHMiLCIuLi9zcmMvdXRpbHMudHMiLCIuLi9zcmMvaW5kZXgudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVuc2FmZS1mdW5jdGlvbi10eXBlICovXG5cbmltcG9ydCB7IE1FVEhPRF9NRVRBREFUQSB9IGZyb20gXCJAbmVzdGpzL2NvbW1vbi9jb25zdGFudHNcIjtcbmltcG9ydCB7IGlzQ29uc3RydWN0b3IgfSBmcm9tIFwiQG5lc3Rqcy9jb21tb24vdXRpbHMvc2hhcmVkLnV0aWxzXCI7XG5pbXBvcnQgeyBpc0FycmF5LCBpc1VuZGVmaW5lZCwgbmVnYXRlLCBwaWNrQnkgfSBmcm9tIFwibG9kYXNoXCI7XG5pbXBvcnQgeyBNRVRBREFUQV9GQUNUT1JZX05BTUUgfSBmcm9tIFwiQG5lc3Rqcy9zd2FnZ2VyL2Rpc3QvcGx1Z2luL3BsdWdpbi1jb25zdGFudHNcIjtcbmltcG9ydCB7IERFQ09SQVRPUlMgfSBmcm9tIFwiQG5lc3Rqcy9zd2FnZ2VyL2Rpc3QvY29uc3RhbnRzXCI7XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVNZXRob2REZWNvcmF0b3I8VCA9IGFueT4oXG4gIG1ldGFrZXk6IHN0cmluZyxcbiAgbWV0YWRhdGE6IFQsXG4gIHsgb3ZlcnJpZGVFeGlzdGluZyB9ID0geyBvdmVycmlkZUV4aXN0aW5nOiB0cnVlIH1cbik6IE1ldGhvZERlY29yYXRvciB7XG4gIHJldHVybiAoXG4gICAgdGFyZ2V0OiBvYmplY3QsXG4gICAga2V5OiBzdHJpbmcgfCBzeW1ib2wsXG4gICAgZGVzY3JpcHRvcjogUHJvcGVydHlEZXNjcmlwdG9yXG4gICkgPT4ge1xuICAgIGlmICh0eXBlb2YgbWV0YWRhdGEgPT09IFwib2JqZWN0XCIpIHtcbiAgICAgIGNvbnN0IHByZXZWYWx1ZSA9IFJlZmxlY3QuZ2V0TWV0YWRhdGEobWV0YWtleSwgZGVzY3JpcHRvci52YWx1ZSk7XG4gICAgICBpZiAocHJldlZhbHVlICYmICFvdmVycmlkZUV4aXN0aW5nKSB7XG4gICAgICAgIHJldHVybiBkZXNjcmlwdG9yO1xuICAgICAgfVxuICAgICAgUmVmbGVjdC5kZWZpbmVNZXRhZGF0YShcbiAgICAgICAgbWV0YWtleSxcbiAgICAgICAgeyAuLi5wcmV2VmFsdWUsIC4uLm1ldGFkYXRhIH0sXG4gICAgICAgIGRlc2NyaXB0b3IudmFsdWVcbiAgICAgICk7XG4gICAgICByZXR1cm4gZGVzY3JpcHRvcjtcbiAgICB9XG4gICAgUmVmbGVjdC5kZWZpbmVNZXRhZGF0YShtZXRha2V5LCBtZXRhZGF0YSwgZGVzY3JpcHRvci52YWx1ZSk7XG4gICAgcmV0dXJuIGRlc2NyaXB0b3I7XG4gIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVDbGFzc0RlY29yYXRvcjxUIGV4dGVuZHMgQXJyYXk8YW55PiA9IGFueT4oXG4gIG1ldGFrZXk6IHN0cmluZyxcbiAgbWV0YWRhdGE6IFQgPSBbXSBhcyB1bmtub3duIGFzIFRcbik6IENsYXNzRGVjb3JhdG9yIHtcbiAgcmV0dXJuICh0YXJnZXQpID0+IHtcbiAgICBjb25zdCBwcmV2VmFsdWUgPSBSZWZsZWN0LmdldE1ldGFkYXRhKG1ldGFrZXksIHRhcmdldCkgfHwgW107XG4gICAgUmVmbGVjdC5kZWZpbmVNZXRhZGF0YShtZXRha2V5LCBbLi4ucHJldlZhbHVlLCAuLi5tZXRhZGF0YV0sIHRhcmdldCk7XG4gICAgcmV0dXJuIHRhcmdldDtcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVByb3BlcnR5RGVjb3JhdG9yPFQgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0gYW55PihcbiAgbWV0YWtleTogc3RyaW5nLFxuICBtZXRhZGF0YTogVCxcbiAgb3ZlcnJpZGVFeGlzdGluZyA9IHRydWVcbik6IFByb3BlcnR5RGVjb3JhdG9yIHtcbiAgcmV0dXJuICh0YXJnZXQ6IG9iamVjdCwgcHJvcGVydHlLZXk/OiBhbnkpID0+IHtcbiAgICBjb25zdCBwcm9wZXJ0aWVzID1cbiAgICAgIFJlZmxlY3QuZ2V0TWV0YWRhdGEoREVDT1JBVE9SUy5BUElfTU9ERUxfUFJPUEVSVElFU19BUlJBWSwgdGFyZ2V0KSB8fCBbXTtcblxuICAgIGNvbnN0IGtleSA9IGA6JHtwcm9wZXJ0eUtleX1gO1xuICAgIGlmICghcHJvcGVydGllcy5pbmNsdWRlcyhrZXkpKSB7XG4gICAgICBSZWZsZWN0LmRlZmluZU1ldGFkYXRhKFxuICAgICAgICBERUNPUkFUT1JTLkFQSV9NT0RFTF9QUk9QRVJUSUVTX0FSUkFZLFxuICAgICAgICBbLi4ucHJvcGVydGllcywgYDoke3Byb3BlcnR5S2V5fWBdLFxuICAgICAgICB0YXJnZXRcbiAgICAgICk7XG4gICAgfVxuICAgIGNvbnN0IGV4aXN0aW5nTWV0YWRhdGEgPSBSZWZsZWN0LmdldE1ldGFkYXRhKG1ldGFrZXksIHRhcmdldCwgcHJvcGVydHlLZXkpO1xuICAgIGlmIChleGlzdGluZ01ldGFkYXRhKSB7XG4gICAgICBjb25zdCBuZXdNZXRhZGF0YSA9IHBpY2tCeShtZXRhZGF0YSwgbmVnYXRlKGlzVW5kZWZpbmVkKSk7XG4gICAgICBjb25zdCBtZXRhZGF0YVRvU2F2ZSA9IG92ZXJyaWRlRXhpc3RpbmdcbiAgICAgICAgPyB7XG4gICAgICAgICAgICAuLi5leGlzdGluZ01ldGFkYXRhLFxuICAgICAgICAgICAgLi4ubmV3TWV0YWRhdGEsXG4gICAgICAgICAgfVxuICAgICAgICA6IHtcbiAgICAgICAgICAgIC4uLm5ld01ldGFkYXRhLFxuICAgICAgICAgICAgLi4uZXhpc3RpbmdNZXRhZGF0YSxcbiAgICAgICAgICB9O1xuXG4gICAgICBSZWZsZWN0LmRlZmluZU1ldGFkYXRhKG1ldGFrZXksIG1ldGFkYXRhVG9TYXZlLCB0YXJnZXQsIHByb3BlcnR5S2V5KTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgdHlwZSA9XG4gICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgbmVzdCBqcyBvdmVycmlkZVxuICAgICAgICB0YXJnZXQ/LmNvbnN0cnVjdG9yPy5bTUVUQURBVEFfRkFDVE9SWV9OQU1FXT8uKClbcHJvcGVydHlLZXldPy50eXBlID8/XG4gICAgICAgIFJlZmxlY3QuZ2V0TWV0YWRhdGEoXCJkZXNpZ246dHlwZVwiLCB0YXJnZXQsIHByb3BlcnR5S2V5KTtcblxuICAgICAgUmVmbGVjdC5kZWZpbmVNZXRhZGF0YShcbiAgICAgICAgbWV0YWtleSxcbiAgICAgICAge1xuICAgICAgICAgIHR5cGUsXG4gICAgICAgICAgLi4ucGlja0J5KG1ldGFkYXRhLCBuZWdhdGUoaXNVbmRlZmluZWQpKSxcbiAgICAgICAgfSxcbiAgICAgICAgdGFyZ2V0LFxuICAgICAgICBwcm9wZXJ0eUtleVxuICAgICAgKTtcbiAgICB9XG4gIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVNaXhlZERlY29yYXRvcjxUID0gYW55PihcbiAgbWV0YWtleTogc3RyaW5nLFxuICBtZXRhZGF0YTogVFxuKTogTWV0aG9kRGVjb3JhdG9yICYgQ2xhc3NEZWNvcmF0b3Ige1xuICByZXR1cm4gKFxuICAgIHRhcmdldDogb2JqZWN0LFxuICAgIGtleT86IHN0cmluZyB8IHN5bWJvbCxcbiAgICBkZXNjcmlwdG9yPzogVHlwZWRQcm9wZXJ0eURlc2NyaXB0b3I8YW55PlxuICApOiBhbnkgPT4ge1xuICAgIGlmIChkZXNjcmlwdG9yKSB7XG4gICAgICBsZXQgbWV0YWRhdGFzOiBhbnk7XG4gICAgICBpZiAoQXJyYXkuaXNBcnJheShtZXRhZGF0YSkpIHtcbiAgICAgICAgY29uc3QgcHJldmlvdXNNZXRhZGF0YSA9XG4gICAgICAgICAgUmVmbGVjdC5nZXRNZXRhZGF0YShtZXRha2V5LCBkZXNjcmlwdG9yLnZhbHVlKSB8fCBbXTtcbiAgICAgICAgbWV0YWRhdGFzID0gWy4uLnByZXZpb3VzTWV0YWRhdGEsIC4uLm1ldGFkYXRhXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IHByZXZpb3VzTWV0YWRhdGEgPVxuICAgICAgICAgIFJlZmxlY3QuZ2V0TWV0YWRhdGEobWV0YWtleSwgZGVzY3JpcHRvci52YWx1ZSkgfHwge307XG4gICAgICAgIG1ldGFkYXRhcyA9IHsgLi4ucHJldmlvdXNNZXRhZGF0YSwgLi4ubWV0YWRhdGEgfTtcbiAgICAgIH1cbiAgICAgIFJlZmxlY3QuZGVmaW5lTWV0YWRhdGEobWV0YWtleSwgbWV0YWRhdGFzLCBkZXNjcmlwdG9yLnZhbHVlKTtcbiAgICAgIHJldHVybiBkZXNjcmlwdG9yO1xuICAgIH1cblxuICAgIGxldCBtZXRhZGF0YXM6IGFueTtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShtZXRhZGF0YSkpIHtcbiAgICAgIGNvbnN0IHByZXZpb3VzTWV0YWRhdGEgPSBSZWZsZWN0LmdldE1ldGFkYXRhKG1ldGFrZXksIHRhcmdldCkgfHwgW107XG4gICAgICBtZXRhZGF0YXMgPSBbLi4ucHJldmlvdXNNZXRhZGF0YSwgLi4ubWV0YWRhdGFdO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBwcmV2aW91c01ldGFkYXRhID0gUmVmbGVjdC5nZXRNZXRhZGF0YShtZXRha2V5LCB0YXJnZXQpIHx8IHt9O1xuICAgICAgbWV0YWRhdGFzID0gT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHt9LCBwcmV2aW91c01ldGFkYXRhKSwgbWV0YWRhdGEpO1xuICAgIH1cbiAgICBSZWZsZWN0LmRlZmluZU1ldGFkYXRhKG1ldGFrZXksIG1ldGFkYXRhcywgdGFyZ2V0KTtcbiAgICByZXR1cm4gdGFyZ2V0O1xuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlUGFyYW1EZWNvcmF0b3I8VCBleHRlbmRzIFJlY29yZDxzdHJpbmcsIGFueT4gPSBhbnk+KFxuICBtZXRhZGF0YTogVCxcbiAgaW5pdGlhbDogUGFydGlhbDxUPlxuKTogTWV0aG9kRGVjb3JhdG9yICYgQ2xhc3NEZWNvcmF0b3Ige1xuICByZXR1cm4gKFxuICAgIHRhcmdldDogb2JqZWN0IHwgRnVuY3Rpb24sXG4gICAga2V5Pzogc3RyaW5nIHwgc3ltYm9sLFxuICAgIGRlc2NyaXB0b3I/OiBUeXBlZFByb3BlcnR5RGVzY3JpcHRvcjxhbnk+XG4gICk6IGFueSA9PiB7XG4gICAgY29uc3QgcGFyYW1PcHRpb25zID0ge1xuICAgICAgLi4uaW5pdGlhbCxcbiAgICAgIC4uLnBpY2tCeShtZXRhZGF0YSwgbmVnYXRlKGlzVW5kZWZpbmVkKSksXG4gICAgfTtcblxuICAgIGlmIChkZXNjcmlwdG9yKSB7XG4gICAgICBjb25zdCBwYXJhbWV0ZXJzID1cbiAgICAgICAgUmVmbGVjdC5nZXRNZXRhZGF0YShERUNPUkFUT1JTLkFQSV9QQVJBTUVURVJTLCBkZXNjcmlwdG9yLnZhbHVlKSB8fCBbXTtcbiAgICAgIFJlZmxlY3QuZGVmaW5lTWV0YWRhdGEoXG4gICAgICAgIERFQ09SQVRPUlMuQVBJX1BBUkFNRVRFUlMsXG4gICAgICAgIFsuLi5wYXJhbWV0ZXJzLCBwYXJhbU9wdGlvbnNdLFxuICAgICAgICBkZXNjcmlwdG9yLnZhbHVlXG4gICAgICApO1xuICAgICAgcmV0dXJuIGRlc2NyaXB0b3I7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiB0YXJnZXQgPT09IFwib2JqZWN0XCIpIHtcbiAgICAgIHJldHVybiB0YXJnZXQ7XG4gICAgfVxuXG4gICAgY29uc3QgcHJvcGVydHlLZXlzID0gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXModGFyZ2V0LnByb3RvdHlwZSk7XG5cbiAgICBmb3IgKGNvbnN0IHByb3BlcnR5S2V5IG9mIHByb3BlcnR5S2V5cykge1xuICAgICAgaWYgKGlzQ29uc3RydWN0b3IocHJvcGVydHlLZXkpKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBtZXRob2REZXNjcmlwdG9yID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihcbiAgICAgICAgdGFyZ2V0LnByb3RvdHlwZSxcbiAgICAgICAgcHJvcGVydHlLZXlcbiAgICAgICk7XG5cbiAgICAgIGlmICghbWV0aG9kRGVzY3JpcHRvcikge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgaXNBcGlNZXRob2QgPSBSZWZsZWN0Lmhhc01ldGFkYXRhKFxuICAgICAgICBNRVRIT0RfTUVUQURBVEEsXG4gICAgICAgIG1ldGhvZERlc2NyaXB0b3IudmFsdWVcbiAgICAgICk7XG5cbiAgICAgIGlmICghaXNBcGlNZXRob2QpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHBhcmFtZXRlcnMgPVxuICAgICAgICBSZWZsZWN0LmdldE1ldGFkYXRhKFxuICAgICAgICAgIERFQ09SQVRPUlMuQVBJX1BBUkFNRVRFUlMsXG4gICAgICAgICAgbWV0aG9kRGVzY3JpcHRvci52YWx1ZVxuICAgICAgICApIHx8IFtdO1xuICAgICAgUmVmbGVjdC5kZWZpbmVNZXRhZGF0YShcbiAgICAgICAgREVDT1JBVE9SUy5BUElfUEFSQU1FVEVSUyxcbiAgICAgICAgWy4uLnBhcmFtZXRlcnMsIHBhcmFtT3B0aW9uc10sXG4gICAgICAgIG1ldGhvZERlc2NyaXB0b3IudmFsdWVcbiAgICAgICk7XG4gICAgfVxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0VHlwZUlzQXJyYXlUdXBsZShcbiAgaW5wdXQ6IEZ1bmN0aW9uIHwgW0Z1bmN0aW9uXSB8IHVuZGVmaW5lZCB8IHN0cmluZyB8IFJlY29yZDxzdHJpbmcsIGFueT4sXG4gIGlzQXJyYXlGbGFnOiBib29sZWFuXG4pOiBbRnVuY3Rpb24gfCB1bmRlZmluZWQsIGJvb2xlYW5dIHtcbiAgaWYgKCFpbnB1dCkge1xuICAgIHJldHVybiBbaW5wdXQgYXMgdW5kZWZpbmVkLCBpc0FycmF5RmxhZ107XG4gIH1cbiAgaWYgKGlzQXJyYXlGbGFnKSB7XG4gICAgcmV0dXJuIFtpbnB1dCBhcyBGdW5jdGlvbiwgaXNBcnJheUZsYWddO1xuICB9XG4gIGNvbnN0IGlzSW5wdXRBcnJheSA9IGlzQXJyYXkoaW5wdXQpO1xuICBjb25zdCB0eXBlID0gaXNJbnB1dEFycmF5ID8gaW5wdXRbMF0gOiBpbnB1dDtcbiAgcmV0dXJuIFt0eXBlIGFzIEZ1bmN0aW9uLCBpc0lucHV0QXJyYXldO1xufVxuIiwiaW1wb3J0IHsgVHlwZSB9IGZyb20gXCJAbmVzdGpzL2NvbW1vblwiO1xuaW1wb3J0IHtcbiAgRW51bUFsbG93ZWRUeXBlcyxcbiAgU2NoZW1hT2JqZWN0TWV0YWRhdGEsXG59IGZyb20gXCJAbmVzdGpzL3N3YWdnZXIvZGlzdC9pbnRlcmZhY2VzL3NjaGVtYS1vYmplY3QtbWV0YWRhdGEuaW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBFbnVtU2NoZW1hQXR0cmlidXRlcyB9IGZyb20gXCJAbmVzdGpzL3N3YWdnZXIvZGlzdC9pbnRlcmZhY2VzL2VudW0tc2NoZW1hLWF0dHJpYnV0ZXMuaW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBnZXRUeXBlSXNBcnJheVR1cGxlIH0gZnJvbSBcIkBuZXN0anMvc3dhZ2dlci9kaXN0L2RlY29yYXRvcnMvaGVscGVyc1wiO1xuaW1wb3J0IHtcbiAgZ2V0RW51bVR5cGUsXG4gIGdldEVudW1WYWx1ZXMsXG59IGZyb20gXCJAbmVzdGpzL3N3YWdnZXIvZGlzdC91dGlscy9lbnVtLnV0aWxzXCI7XG5pbXBvcnQgeyBERUNPUkFUT1JTIH0gZnJvbSBcIkBuZXN0anMvc3dhZ2dlci9kaXN0L2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgY3JlYXRlUHJvcGVydHlEZWNvcmF0b3IgfSBmcm9tIFwiLi9oZWxwZXJzXCI7XG5cbmV4cG9ydCB0eXBlIEFwaVByb3BlcnR5Q29tbW9uT3B0aW9ucyA9IFNjaGVtYU9iamVjdE1ldGFkYXRhICYge1xuICBcIngtZW51bU5hbWVzXCI/OiBzdHJpbmdbXTtcbiAgLyoqXG4gICAqIExhenkgZnVuY3Rpb24gcmV0dXJuaW5nIHRoZSB0eXBlIGZvciB3aGljaCB0aGUgZGVjb3JhdGVkIHByb3BlcnR5XG4gICAqIGNhbiBiZSB1c2VkIGFzIGFuIGlkXG4gICAqXG4gICAqIFVzZSB0b2dldGhlciB3aXRoIEBBcGlEZWZhdWx0R2V0dGVyIG9uIHRoZSBnZXR0ZXIgcm91dGUgb2YgdGhlIHR5cGVcbiAgICogdG8gZ2VuZXJhdGUgT3BlbkFQSSBsaW5rIG9iamVjdHNcbiAgICpcbiAgICogQHNlZSBbU3dhZ2dlciBsaW5rIG9iamVjdHNdKGh0dHBzOi8vc3dhZ2dlci5pby9kb2NzL3NwZWNpZmljYXRpb24vbGlua3MvKVxuICAgKi9cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnNhZmUtZnVuY3Rpb24tdHlwZVxuICBsaW5rPzogKCkgPT4gVHlwZTx1bmtub3duPiB8IEZ1bmN0aW9uO1xufTtcblxuZXhwb3J0IHR5cGUgQXBpUHJvcGVydHlPcHRpb25zID1cbiAgfCBBcGlQcm9wZXJ0eUNvbW1vbk9wdGlvbnNcbiAgfCAoQXBpUHJvcGVydHlDb21tb25PcHRpb25zICYge1xuICAgICAgZW51bU5hbWU6IHN0cmluZztcbiAgICAgIGVudW1TY2hlbWE/OiBFbnVtU2NoZW1hQXR0cmlidXRlcztcbiAgICB9KTtcblxuY29uc3QgaXNFbnVtQXJyYXkgPSAoXG4gIG9wdHM6IEFwaVByb3BlcnR5T3B0aW9uc1xuKTogb3B0cyBpcyB7XG4gIGlzQXJyYXk6IHRydWU7XG4gIGVudW06IEVudW1BbGxvd2VkVHlwZXM7XG4gIHR5cGU6IGFueTtcbiAgaXRlbXM6IGFueTtcbn0gPT4gKG9wdHMuaXNBcnJheSAmJiBcImVudW1cIiBpbiBvcHRzICYmIG9wdHMuZW51bSAhPT0gdW5kZWZpbmVkKSBhcyBib29sZWFuO1xuXG4vKipcbiAqIEBwdWJsaWNBcGlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIEFwaVByb3BlcnR5KFxuICBvcHRpb25zOiBBcGlQcm9wZXJ0eU9wdGlvbnMgPSB7fVxuKTogUHJvcGVydHlEZWNvcmF0b3Ige1xuICByZXR1cm4gY3JlYXRlQXBpUHJvcGVydHlEZWNvcmF0b3Iob3B0aW9ucyk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVBcGlQcm9wZXJ0eURlY29yYXRvcihcbiAgb3B0aW9uczogQXBpUHJvcGVydHlPcHRpb25zID0ge30sXG4gIG92ZXJyaWRlRXhpc3RpbmcgPSB0cnVlXG4pOiBQcm9wZXJ0eURlY29yYXRvciB7XG4gIGNvbnN0IFt0eXBlLCBpc0FycmF5XSA9IGdldFR5cGVJc0FycmF5VHVwbGUoXG4gICAgb3B0aW9ucy50eXBlLFxuICAgIG9wdGlvbnMuaXNBcnJheSBhcyBib29sZWFuXG4gICk7XG4gIG9wdGlvbnMgPSB7XG4gICAgLi4ub3B0aW9ucyxcbiAgICB0eXBlLFxuICAgIGlzQXJyYXksXG4gIH0gYXMgQXBpUHJvcGVydHlPcHRpb25zO1xuXG4gIGlmIChpc0VudW1BcnJheShvcHRpb25zKSkge1xuICAgIG9wdGlvbnMudHlwZSA9IFwiYXJyYXlcIjtcblxuICAgIGNvbnN0IGVudW1WYWx1ZXMgPSBnZXRFbnVtVmFsdWVzKG9wdGlvbnMuZW51bSk7XG4gICAgb3B0aW9ucy5pdGVtcyA9IHtcbiAgICAgIHR5cGU6IGdldEVudW1UeXBlKGVudW1WYWx1ZXMpLFxuICAgICAgZW51bTogZW51bVZhbHVlcyxcbiAgICB9O1xuICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgbmVzdCBzd2FnZ2VyIG92ZXJyaWRlXG4gICAgZGVsZXRlIG9wdGlvbnMuZW51bTtcbiAgfSBlbHNlIGlmIChcImVudW1cIiBpbiBvcHRpb25zICYmIG9wdGlvbnMuZW51bSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgY29uc3QgZW51bVZhbHVlcyA9IGdldEVudW1WYWx1ZXMob3B0aW9ucy5lbnVtKTtcblxuICAgIG9wdGlvbnMuZW51bSA9IGVudW1WYWx1ZXM7XG4gICAgb3B0aW9ucy50eXBlID0gZ2V0RW51bVR5cGUoZW51bVZhbHVlcyk7XG4gIH1cblxuICBpZiAoQXJyYXkuaXNBcnJheShvcHRpb25zLnR5cGUpKSB7XG4gICAgb3B0aW9ucy50eXBlID0gXCJhcnJheVwiO1xuICAgIG9wdGlvbnMuaXRlbXMgPSB7XG4gICAgICB0eXBlOiBcImFycmF5XCIsXG4gICAgICBpdGVtczoge1xuICAgICAgICB0eXBlOiBvcHRpb25zLnR5cGVbMF0sXG4gICAgICB9LFxuICAgIH07XG4gIH1cblxuICByZXR1cm4gY3JlYXRlUHJvcGVydHlEZWNvcmF0b3IoXG4gICAgREVDT1JBVE9SUy5BUElfTU9ERUxfUFJPUEVSVElFUyxcbiAgICBvcHRpb25zLFxuICAgIG92ZXJyaWRlRXhpc3RpbmdcbiAgKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIEFwaVByb3BlcnR5T3B0aW9uYWwoXG4gIG9wdGlvbnM6IEFwaVByb3BlcnR5T3B0aW9ucyA9IHt9XG4pOiBQcm9wZXJ0eURlY29yYXRvciB7XG4gIHJldHVybiBBcGlQcm9wZXJ0eSh7XG4gICAgLi4ub3B0aW9ucyxcbiAgICByZXF1aXJlZDogZmFsc2UsXG4gIH0gYXMgQXBpUHJvcGVydHlPcHRpb25zKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIEFwaVJlc3BvbnNlUHJvcGVydHkoXG4gIG9wdGlvbnM6IFBpY2s8XG4gICAgQXBpUHJvcGVydHlPcHRpb25zLFxuICAgIFwidHlwZVwiIHwgXCJleGFtcGxlXCIgfCBcImZvcm1hdFwiIHwgXCJkZXByZWNhdGVkXCIgfCBcImVudW1cIlxuICA+ID0ge31cbik6IFByb3BlcnR5RGVjb3JhdG9yIHtcbiAgcmV0dXJuIEFwaVByb3BlcnR5KHtcbiAgICByZWFkT25seTogdHJ1ZSxcbiAgICAuLi5vcHRpb25zLFxuICB9IGFzIEFwaVByb3BlcnR5T3B0aW9ucyk7XG59XG4iLCJpbXBvcnQge1xuICBJbmplY3RhYmxlQ29uZmlnLFxuICBJbmplY3RhYmxlc0tleXMsXG4gIEluamVjdE9wdGlvbnMsXG59IGZyb20gXCJAZGVjYWYtdHMvaW5qZWN0YWJsZS1kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBJbmplY3QsIEluamVjdGFibGUsIFNjb3BlIH0gZnJvbSBcIkBuZXN0anMvY29tbW9uXCI7XG5pbXBvcnQgeyBDb25zdHJ1Y3RvciwgRGVjb3JhdGlvbiwgRGVjb3JhdGlvbktleXMgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRpb25cIjtcbmltcG9ydCB7IFZhbGlkYXRpb25LZXlzIH0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgQXBpUHJvcGVydHkgfSBmcm9tIFwiLi9kZWNvcmF0b3JzL0FwaVByb3BlcnR5XCI7XG5pbXBvcnQgeyBQZXJzaXN0ZW5jZUtleXMgfSBmcm9tIFwiQGRlY2FmLXRzL2NvcmVcIjtcblxuRGVjb3JhdGlvbi5mb3IoSW5qZWN0YWJsZXNLZXlzLklOSkVDVEFCTEUpXG4gIC5leHRlbmQoe1xuICAgIGRlY29yYXRvcjogZnVuY3Rpb24gbmVzdEluamVjdGFibGUoXG4gICAgICBjYXRlZ29yeTogc3RyaW5nIHwgQ29uc3RydWN0b3IsXG4gICAgICBjZmc6IEluamVjdGFibGVDb25maWdcbiAgICApIHtcbiAgICAgIHJldHVybiBJbmplY3RhYmxlKHtcbiAgICAgICAgc2NvcGU6IGNmZy5zaW5nbGV0b24gPyBTY29wZS5ERUZBVUxUIDogU2NvcGUuUkVRVUVTVCxcbiAgICAgICAgZHVyYWJsZTogY2ZnLnNpbmdsZXRvbiA/IHVuZGVmaW5lZCA6IHRydWUsXG4gICAgICB9KTtcbiAgICB9LFxuICB9KVxuICAuYXBwbHkoKTtcblxuRGVjb3JhdGlvbi5mb3IoSW5qZWN0YWJsZXNLZXlzLklOSkVDVClcbiAgLmV4dGVuZCh7XG4gICAgZGVjb3JhdG9yOiBmdW5jdGlvbiBuZXN0SW5qZWN0KFxuICAgICAgY2F0ZWdvcnk6IHN5bWJvbCB8IHN0cmluZyB8IENvbnN0cnVjdG9yLFxuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICAgICAgY2ZnOiBJbmplY3RPcHRpb25zXG4gICAgKSB7XG4gICAgICByZXR1cm4gZnVuY3Rpb24gaW5uZXJOZXN0SW5qZWN0KFxuICAgICAgICB0YXJnZXQ6IG9iamVjdCxcbiAgICAgICAgcHJvcGVydHlLZXk/OiBhbnksXG4gICAgICAgIGRlc2NyaXB0b3I/OiBhbnlcbiAgICAgICkge1xuICAgICAgICByZXR1cm4gSW5qZWN0KGNhdGVnb3J5IHx8ICh0YXJnZXQgYXMgQ29uc3RydWN0b3IpKShcbiAgICAgICAgICB0YXJnZXQsXG4gICAgICAgICAgcHJvcGVydHlLZXksXG4gICAgICAgICAgZGVzY3JpcHRvclxuICAgICAgICApO1xuICAgICAgfTtcbiAgICB9LFxuICB9KVxuICAuYXBwbHkoKTtcblxuRGVjb3JhdGlvbi5mb3IoVmFsaWRhdGlvbktleXMuUkVRVUlSRUQpXG4gIC5leHRlbmQoXG4gICAgQXBpUHJvcGVydHkoe1xuICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgfSlcbiAgKVxuICAuYXBwbHkoKTtcblxuRGVjb3JhdGlvbi5mb3IoVmFsaWRhdGlvbktleXMuTUFYKVxuICAuZXh0ZW5kKHtcbiAgICBkZWNvcmF0b3I6IGZ1bmN0aW9uIG1heERlYyhtYXg6IG51bWJlcikge1xuICAgICAgcmV0dXJuIEFwaVByb3BlcnR5KHsgbWF4aW11bTogbWF4IH0pO1xuICAgIH0sXG4gIH0pXG4gIC5hcHBseSgpO1xuXG5EZWNvcmF0aW9uLmZvcihWYWxpZGF0aW9uS2V5cy5NSU4pXG4gIC5leHRlbmQoe1xuICAgIGRlY29yYXRvcjogZnVuY3Rpb24gbWluRGVjKG1pbjogbnVtYmVyKSB7XG4gICAgICByZXR1cm4gQXBpUHJvcGVydHkoeyBtaW5pbXVtOiBtaW4gfSk7XG4gICAgfSxcbiAgfSlcbiAgLmFwcGx5KCk7XG5cbkRlY29yYXRpb24uZm9yKFZhbGlkYXRpb25LZXlzLk1BWF9MRU5HVEgpXG4gIC5leHRlbmQoe1xuICAgIGRlY29yYXRvcjogZnVuY3Rpb24gbWF4TGVuZ3RoRGVjKG1heDogbnVtYmVyKSB7XG4gICAgICByZXR1cm4gQXBpUHJvcGVydHkoeyBtYXhMZW5ndGg6IG1heCB9KTtcbiAgICB9LFxuICB9KVxuICAuYXBwbHkoKTtcblxuRGVjb3JhdGlvbi5mb3IoVmFsaWRhdGlvbktleXMuTUlOX0xFTkdUSClcbiAgLmV4dGVuZCh7XG4gICAgZGVjb3JhdG9yOiBmdW5jdGlvbiBtaW5MZW5ndGhEZWMobWluOiBudW1iZXIpIHtcbiAgICAgIHJldHVybiBBcGlQcm9wZXJ0eSh7IG1pbkxlbmd0aDogbWluIH0pO1xuICAgIH0sXG4gIH0pXG4gIC5hcHBseSgpO1xuLy9cbi8vIERlY29yYXRpb24uZm9yKFZhbGlkYXRpb25LZXlzLlRZUEUpXG4vLyAgIC5leHRlbmQoe1xuLy8gICAgIGRlY29yYXRvcjogZnVuY3Rpb24gdHlwZURlYyh0eXBlOiAoc3RyaW5nIHwgKCgpID0+IHN0cmluZykpW10gfCBzdHJpbmcgfCAoKCkgPT4gc3RyaW5nKSkge1xuLy8gICAgICAgcmV0dXJuIEFwaVByb3BlcnR5KHsgdHlwZTogdHlwZSBhcyBhbnkgfSk7XG4vLyAgICAgfSxcbi8vICAgfSlcbi8vICAgLmFwcGx5KCk7XG4vL1xuLy8gRGVjb3JhdGlvbi5mb3IoVmFsaWRhdGlvbktleXMuREFURSlcbi8vICAgLmV4dGVuZCh7XG4vLyAgICAgZGVjb3JhdG9yOiBmdW5jdGlvbiBkYXRlRGVjKCkge1xuLy8gICAgICAgcmV0dXJuIEFwaVByb3BlcnR5KHsgdHlwZTogRGF0ZSB9KTtcbi8vICAgICB9LFxuLy8gICB9KVxuLy8gICAuYXBwbHkoKTtcblxuRGVjb3JhdGlvbi5mb3IoVmFsaWRhdGlvbktleXMuTElTVClcbiAgLmV4dGVuZCh7XG4gICAgZGVjb3JhdG9yOiBmdW5jdGlvbiBsaXN0RGVjKFxuICAgICAgY2xheno6XG4gICAgICAgIHwgQ29uc3RydWN0b3I8YW55PlxuICAgICAgICB8ICgoKSA9PiBDb25zdHJ1Y3Rvcjxhbnk+KVxuICAgICAgICB8IChDb25zdHJ1Y3Rvcjxhbnk+IHwgKCgpID0+IENvbnN0cnVjdG9yPGFueT4pKVtdXG4gICAgKSB7XG4gICAgICBjb25zdCBjID0gQXJyYXkuaXNBcnJheShjbGF6eikgPyBjbGF6elswXSA6IGNsYXp6O1xuICAgICAgcmV0dXJuIEFwaVByb3BlcnR5KHsgdHlwZTogW2NdIH0pO1xuICAgIH0sXG4gIH0pXG4gIC5hcHBseSgpO1xuXG4vL1xuLy8gRGVjb3JhdGlvbi5mb3IoVmFsaWRhdGlvbktleXMuT1BUSU9OKVxuLy8gICAuZXh0ZW5kKHtcbi8vICAgICBkZWNvcmF0b3I6IGZ1bmN0aW9uIG9wdGlvbkRlYyhvcHRpb25zOiBzdHJpbmdbXSB8IFJlY29yZDxzdHJpbmcsIGFueT4pIHtcbi8vICAgICAgIGNvbnN0IG9wdHMgPSBBcnJheS5pc0FycmF5KG9wdGlvbnMpID8gb3B0aW9ucyA6IE9iamVjdC52YWx1ZXMob3B0aW9ucyk7XG4vLyAgICAgICByZXR1cm4gQXBpUHJvcGVydHkoeyBlbnVtOiBvcHRzIH0pO1xuLy8gICAgIH0sXG4vLyAgIH0pXG4vLyAgIC5hcHBseSgpO1xuXG5EZWNvcmF0aW9uLmZvcihWYWxpZGF0aW9uS2V5cy5QQVRURVJOKVxuICAuZXh0ZW5kKHtcbiAgICBkZWNvcmF0b3I6IGZ1bmN0aW9uIHBhdHRlcm5EZWMocGF0OiBSZWdFeHAgfCBzdHJpbmcpIHtcbiAgICAgIHJldHVybiBBcGlQcm9wZXJ0eSh7XG4gICAgICAgIHBhdHRlcm46IHR5cGVvZiBwYXQgPT09IFwic3RyaW5nXCIgPyBwYXQgOiBwYXQuc291cmNlLFxuICAgICAgfSk7XG4gICAgfSxcbiAgfSlcbiAgLmFwcGx5KCk7XG5cbkRlY29yYXRpb24uZm9yKFBlcnNpc3RlbmNlS2V5cy5DT0xVTU4pXG4gIC5leHRlbmQoe1xuICAgIGRlY29yYXRvcjogZnVuY3Rpb24gY29sdW1uRGVjKG5hbWU6IHN0cmluZykge1xuICAgICAgcmV0dXJuIEFwaVByb3BlcnR5KHtcbiAgICAgICAgbmFtZTogbmFtZSxcbiAgICAgIH0pO1xuICAgIH0sXG4gIH0pXG4gIC5hcHBseSgpO1xuXG5EZWNvcmF0aW9uLmZvcihEZWNvcmF0aW9uS2V5cy5ERVNDUklQVElPTilcbiAgLmV4dGVuZCh7XG4gICAgZGVjb3JhdG9yOiBmdW5jdGlvbiBkZXNjcmlwdGlvbkRlYyhkZXNjcmlwdGlvbjogc3RyaW5nKSB7XG4gICAgICByZXR1cm4gQXBpUHJvcGVydHkoe1xuICAgICAgICBkZXNjcmlwdGlvbjogZGVzY3JpcHRpb24sXG4gICAgICB9KTtcbiAgICB9LFxuICB9KVxuICAuYXBwbHkoKTtcbiIsImV4cG9ydCBjb25zdCBERUNBRl9NT0RVTEVfT1BUSU9OUyA9IFwiRGVjYWZNb2R1bGVPcHRpb25zXCI7XG5leHBvcnQgY29uc3QgREVDQUZfQURBUFRFUl9JRCA9IFwiRGVjYWZBZGFwdGVyXCI7XG4iLCJpbXBvcnQge1xuICBEeW5hbWljTW9kdWxlLFxuICBHbG9iYWwsXG4gIEluamVjdCxcbiAgTW9kdWxlLFxuICBPbkFwcGxpY2F0aW9uU2h1dGRvd24sXG4gIFNjb3BlLFxufSBmcm9tIFwiQG5lc3Rqcy9jb21tb25cIjtcbmltcG9ydCB7IE1vZHVsZVJlZiB9IGZyb20gXCJAbmVzdGpzL2NvcmVcIjtcbmltcG9ydCB0eXBlIHsgRGVjYWZNb2R1bGVPcHRpb25zIH0gZnJvbSBcIi4vdHlwZXNcIjtcbmltcG9ydCB7IERFQ0FGX0FEQVBURVJfSUQsIERFQ0FGX01PRFVMRV9PUFRJT05TIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBGYWN0b3J5UHJvdmlkZXIgfSBmcm9tIFwiQG5lc3Rqcy9jb21tb24vaW50ZXJmYWNlcy9tb2R1bGVzL3Byb3ZpZGVyLmludGVyZmFjZVwiO1xuaW1wb3J0IHsgQWRhcHRlciB9IGZyb20gXCJAZGVjYWYtdHMvY29yZVwiO1xuaW1wb3J0IHsgTG9nZ2VyLCBMb2dnaW5nIH0gZnJvbSBcIkBkZWNhZi10cy9sb2dnaW5nXCI7XG5cbkBHbG9iYWwoKVxuQE1vZHVsZSh7fSlcbmV4cG9ydCBjbGFzcyBEZWNhZkNvcmVNb2R1bGU8XG4gIENPTkYsXG4gIEFEQVBURVIgZXh0ZW5kcyBBZGFwdGVyPENPTkYsIGFueSwgYW55LCBhbnksIGFueT4sXG4+IGltcGxlbWVudHMgT25BcHBsaWNhdGlvblNodXRkb3duXG57XG4gIHByaXZhdGUgc3RhdGljIF9sb2dnZXI6IExvZ2dlcjtcbiAgcHJpdmF0ZSBzdGF0aWMgX2FkYXB0ZXJJbnN0YW5jZTogQWRhcHRlcjxhbnksIGFueSwgYW55LCBhbnksIGFueT4gfCBudWxsID1cbiAgICBudWxsO1xuXG4gIHByb3RlY3RlZCBzdGF0aWMgZ2V0IGxvZygpOiBMb2dnZXIge1xuICAgIGlmICghdGhpcy5fbG9nZ2VyKSB0aGlzLl9sb2dnZXIgPSBMb2dnaW5nLmZvcihEZWNhZkNvcmVNb2R1bGUpO1xuICAgIHJldHVybiB0aGlzLl9sb2dnZXI7XG4gIH1cblxuICBjb25zdHJ1Y3RvcihcbiAgICBASW5qZWN0KERFQ0FGX01PRFVMRV9PUFRJT05TKVxuICAgIHByaXZhdGUgcmVhZG9ubHkgb3B0aW9uczogRGVjYWZNb2R1bGVPcHRpb25zPENPTkYsIEFEQVBURVI+LFxuICAgIHByaXZhdGUgcmVhZG9ubHkgbW9kdWxlUmVmOiBNb2R1bGVSZWZcbiAgKSB7fVxuXG4gIHN0YXRpYyBhc3luYyBjcmVhdGVBZGFwdGVyKFxuICAgIG9wdGlvbnM6IERlY2FmTW9kdWxlT3B0aW9uc1xuICApOiBQcm9taXNlPEFkYXB0ZXI8YW55LCBhbnksIGFueSwgYW55LCBhbnk+PiB7XG4gICAgaWYgKCF0aGlzLl9hZGFwdGVySW5zdGFuY2UpIHtcbiAgICAgIGNvbnN0IGxvZyA9IHRoaXMubG9nLmZvcih0aGlzLmNyZWF0ZUFkYXB0ZXIpO1xuICAgICAgbG9nLmluZm8oXCJDcmVhdGluZyBhZGFwdGVyIGluc3RhbmNlLi4uXCIpO1xuICAgICAgdGhpcy5fYWRhcHRlckluc3RhbmNlID0gbmV3IG9wdGlvbnMuYWRhcHRlcihvcHRpb25zLmNvbmYsIG9wdGlvbnMuYWxpYXMpO1xuICAgICAgbG9nLmluZm8oXCJBZGFwdGVyIGluc3RhbmNlIGNyZWF0ZWQgc3VjY2Vzc2Z1bGx5IVwiKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX2FkYXB0ZXJJbnN0YW5jZTtcbiAgfVxuXG4gIHN0YXRpYyBnZXRBZGFwdGVySW5zdGFuY2UoKTogQWRhcHRlcjxhbnksIGFueSwgYW55LCBhbnksIGFueT4gfCBudWxsIHtcbiAgICByZXR1cm4gdGhpcy5fYWRhcHRlckluc3RhbmNlO1xuICB9XG5cbiAgc3RhdGljIGZvclJvb3Qob3B0aW9uczogRGVjYWZNb2R1bGVPcHRpb25zKTogRHluYW1pY01vZHVsZSB7XG4gICAgY29uc3QgdHlwZU9ybU1vZHVsZU9wdGlvbnMgPSB7XG4gICAgICBwcm92aWRlOiBERUNBRl9NT0RVTEVfT1BUSU9OUyxcbiAgICAgIHVzZVZhbHVlOiBvcHRpb25zLFxuICAgIH07XG5cbiAgICBjb25zdCBhZGFwdGVyOiBGYWN0b3J5UHJvdmlkZXI8YW55PiA9IHtcbiAgICAgIHVzZUZhY3Rvcnk6IGFzeW5jIChvcHRzOiBEZWNhZk1vZHVsZU9wdGlvbnMpID0+IHtcbiAgICAgICAgcmV0dXJuIERlY2FmQ29yZU1vZHVsZS5jcmVhdGVBZGFwdGVyKG9wdHMpO1xuICAgICAgfSxcbiAgICAgIHByb3ZpZGU6IERFQ0FGX0FEQVBURVJfSUQsXG4gICAgICBkdXJhYmxlOiB0cnVlLFxuICAgICAgc2NvcGU6IFNjb3BlLkRFRkFVTFQsXG4gICAgICBpbmplY3Q6IFtERUNBRl9NT0RVTEVfT1BUSU9OU10sXG4gICAgfTtcblxuICAgIGNvbnN0IHByb3ZpZGVycyA9IFthZGFwdGVyLCB0eXBlT3JtTW9kdWxlT3B0aW9uc107XG4gICAgY29uc3QgZXhwb3J0cyA9IFthZGFwdGVyXTtcblxuICAgIHJldHVybiB7XG4gICAgICBtb2R1bGU6IERlY2FmQ29yZU1vZHVsZSxcbiAgICAgIHByb3ZpZGVycyxcbiAgICAgIGV4cG9ydHMsXG4gICAgfTtcbiAgfVxuXG4gIGFzeW5jIG9uQXBwbGljYXRpb25TaHV0ZG93bigpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBsb2cgPSBEZWNhZkNvcmVNb2R1bGUubG9nLmZvcih0aGlzLm9uQXBwbGljYXRpb25TaHV0ZG93bik7XG4gICAgY29uc3QgYWRhcHRlciA9IHRoaXMubW9kdWxlUmVmLmdldDxBREFQVEVSPihERUNBRl9BREFQVEVSX0lEKTtcbiAgICB0cnkge1xuICAgICAgaWYgKGFkYXB0ZXIpIHtcbiAgICAgICAgbG9nLmluZm8oXCJTaHV0dGluZyBkb3duXCIpO1xuICAgICAgICBhd2FpdCBhZGFwdGVyLnNodXRkb3duKCk7XG4gICAgICAgIERlY2FmQ29yZU1vZHVsZS5fYWRhcHRlckluc3RhbmNlID0gbnVsbDtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlOiB1bmtub3duKSB7XG4gICAgICBsb2cuZXJyb3IoYEZhaWxlZCB0byBzaHV0ZG93biBhcHBsaWNhdGlvbmAsIGUgYXMgRXJyb3IpO1xuICAgIH1cbiAgfVxufVxuIiwiaW1wb3J0IHsgTW9kZWwgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBJbnRlcm5hbEVycm9yIH0gZnJvbSBcIkBkZWNhZi10cy9kYi1kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBSZXBvLCBSZXBvc2l0b3J5IH0gZnJvbSBcIkBkZWNhZi10cy9jb3JlXCI7XG5pbXBvcnQgeyBDb25zdHJ1Y3RvciB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdGlvblwiO1xuaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gXCJAbmVzdGpzL2NvbW1vblwiO1xuXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgUmVwb0ZhY3Rvcnkge1xuICBmb3I8TSBleHRlbmRzIE1vZGVsPihtb2RlbDogc3RyaW5nIHwgQ29uc3RydWN0b3I8TT4pOiBSZXBvPE0+IHtcbiAgICBtb2RlbCA9IHR5cGVvZiBtb2RlbCA9PT0gXCJzdHJpbmdcIiA/IChNb2RlbC5nZXQobW9kZWwpIGFzIGFueSkgOiBtb2RlbDtcbiAgICBpZiAoIW1vZGVsKSB7XG4gICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihgRmFpbGVkIHRvIGZpbmQgcmVwb3NpdG9yeSBmb3IgJHttb2RlbH1gKTtcbiAgICB9XG4gICAgcmV0dXJuIFJlcG9zaXRvcnkuZm9yTW9kZWwobW9kZWwgYXMgQ29uc3RydWN0b3I8TT4pO1xuICB9XG59XG4iLCJpbXBvcnQge1xuICBCb2R5LFxuICBDb250cm9sbGVyLFxuICBEZWxldGUsXG4gIER5bmFtaWNNb2R1bGUsXG4gIEdldCxcbiAgTW9kdWxlLFxuICBQYXJhbSxcbiAgUG9zdCxcbiAgUHV0LFxufSBmcm9tIFwiQG5lc3Rqcy9jb21tb25cIjtcbmltcG9ydCB7XG4gIEFwaUJhZFJlcXVlc3RSZXNwb25zZSxcbiAgQXBpQm9keSxcbiAgQXBpQ3JlYXRlZFJlc3BvbnNlLFxuICBBcGlFeHRyYU1vZGVscyxcbiAgQXBpTm90Rm91bmRSZXNwb25zZSxcbiAgQXBpT2tSZXNwb25zZSxcbiAgQXBpT3BlcmF0aW9uLFxuICBBcGlQYXJhbSxcbiAgQXBpVGFncyxcbiAgQXBpVW5wcm9jZXNzYWJsZUVudGl0eVJlc3BvbnNlLFxuICBnZXRTY2hlbWFQYXRoLFxufSBmcm9tIFwiQG5lc3Rqcy9zd2FnZ2VyXCI7XG5pbXBvcnQgeyBBZGFwdGVyLCBSZXBvLCBSZXBvc2l0b3J5IH0gZnJvbSBcIkBkZWNhZi10cy9jb3JlXCI7XG5pbXBvcnQgeyBNb2RlbCwgTW9kZWxDb25zdHJ1Y3RvciB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7IExvZ2dlZENsYXNzLCBMb2dnZXIsIExvZ2dpbmcsIHRvS2ViYWJDYXNlIH0gZnJvbSBcIkBkZWNhZi10cy9sb2dnaW5nXCI7XG5pbXBvcnQgeyBSZXBvRmFjdG9yeSB9IGZyb20gXCIuL1JlcG9GYWN0b3J5XCI7XG5cbkBNb2R1bGUoe30pXG5leHBvcnQgY2xhc3MgRGVjYWZNb2RlbE1vZHVsZSB7XG4gIHByaXZhdGUgc3RhdGljIF9sb2dnZXI6IExvZ2dlcjtcblxuICBwcm90ZWN0ZWQgc3RhdGljIGdldCBsb2coKTogTG9nZ2VyIHtcbiAgICBpZiAoIXRoaXMuX2xvZ2dlcikgdGhpcy5fbG9nZ2VyID0gTG9nZ2luZy5mb3IoRGVjYWZNb2RlbE1vZHVsZSk7XG4gICAgcmV0dXJuIHRoaXMuX2xvZ2dlcjtcbiAgfVxuXG4gIHByaXZhdGUgc3RhdGljIHRvTW9kZWxDb250cm9sbGVyPFQgZXh0ZW5kcyBNb2RlbDxhbnk+PihcbiAgICBNb2RlbENsYXp6OiBNb2RlbENvbnN0cnVjdG9yPGFueT5cbiAgKSB7XG4gICAgY29uc3QgbG9nID0gdGhpcy5sb2cuZm9yKHRoaXMudG9Nb2RlbENvbnRyb2xsZXIpO1xuICAgIGNvbnN0IHRhYmxlTmFtZSA9IFJlcG9zaXRvcnkudGFibGUoTW9kZWxDbGF6eik7XG4gICAgY29uc3Qgcm91dGVQYXRoID0gdG9LZWJhYkNhc2UodGFibGVOYW1lKTtcbiAgICBjb25zdCBtb2RlbENsYXp6TmFtZSA9IE1vZGVsQ2xhenoubmFtZTtcblxuICAgIGxvZy5kZWJ1ZyhgQ3JlYXRpbmcgY29udHJvbGxlciBmb3IgbW9kZWw6ICR7bW9kZWxDbGF6ek5hbWV9YCk7XG5cbiAgICBAQ29udHJvbGxlcihyb3V0ZVBhdGgpXG4gICAgQEFwaVRhZ3MobW9kZWxDbGF6ek5hbWUpXG4gICAgQEFwaUV4dHJhTW9kZWxzKE1vZGVsQ2xhenopXG4gICAgY2xhc3MgRHluYW1pY01vZGVsQ29udHJvbGxlciBleHRlbmRzIExvZ2dlZENsYXNzIHtcbiAgICAgIC8vIHByaXZhdGUgcmVhZG9ubHkgcmVwbyA9IHRoaXMucmVwb0ZhY3RvcnkuZm9yKE1vZGVsQ2xhenopO1xuICAgICAgcHJpdmF0ZSByZWFkb25seSBwayE6IHN0cmluZztcbiAgICAgIHByaXZhdGUgcmVhZG9ubHkgcmVwbyE6IFJlcG88VD47IC8vUmVwb3NpdG9yeTxNb2RlbDxhbnk+LCBhbnksIGFueSwgYW55LCBhbnk+O1xuXG4gICAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IHJlcG9GYWN0b3J5OiBSZXBvRmFjdG9yeSkge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICBsb2cuaW5mbyhcbiAgICAgICAgICBgUmVnaXN0ZXJpbmcgZHluYW1pYyBjb250cm9sbGVyIGZvciBtb2RlbDogJHttb2RlbENsYXp6TmFtZX0gcm91dGU6IC8ke3JvdXRlUGF0aH1gXG4gICAgICAgICk7XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICB0aGlzLnJlcG8gPSB0aGlzLnJlcG9GYWN0b3J5LmZvcihNb2RlbENsYXp6Lm5hbWUpO1xuICAgICAgICAgIHRoaXMucGsgPSB0aGlzLnJlcG8ucGsgYXMgc3RyaW5nO1xuICAgICAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgICAgICB0aGlzLmxvZy5lcnJvcihcbiAgICAgICAgICAgIGBGYWlsZWQgdG8gaW5pdGlhbGl6ZSByZXBvc2l0b3J5IGZvciBtb2RlbCBcIiR7TW9kZWxDbGF6ei5uYW1lfVwiLmAsXG4gICAgICAgICAgICBlXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBAUG9zdCgpXG4gICAgICBAQXBpT3BlcmF0aW9uKHsgc3VtbWFyeTogYENyZWF0ZSBhIG5ldyAke21vZGVsQ2xhenpOYW1lfS5gIH0pXG4gICAgICBAQXBpQm9keSh7XG4gICAgICAgIGRlc2NyaXB0aW9uOiBgUGF5bG9hZCBmb3IgJHttb2RlbENsYXp6TmFtZX1gLFxuICAgICAgICBzY2hlbWE6IHsgJHJlZjogZ2V0U2NoZW1hUGF0aChNb2RlbENsYXp6KSB9LFxuICAgICAgfSlcbiAgICAgIEBBcGlDcmVhdGVkUmVzcG9uc2Uoe1xuICAgICAgICBkZXNjcmlwdGlvbjogYCR7bW9kZWxDbGF6ek5hbWV9IGNyZWF0ZWQgc3VjY2Vzc2Z1bGx5LmAsXG4gICAgICB9KVxuICAgICAgQEFwaUJhZFJlcXVlc3RSZXNwb25zZSh7IGRlc2NyaXB0aW9uOiBcIlBheWxvYWQgdmFsaWRhdGlvbiBmYWlsZWQuXCIgfSlcbiAgICAgIEBBcGlVbnByb2Nlc3NhYmxlRW50aXR5UmVzcG9uc2Uoe1xuICAgICAgICBkZXNjcmlwdGlvbjogXCJSZXBvc2l0b3J5IHJlamVjdGVkIHRoZSBwcm92aWRlZCBwYXlsb2FkLlwiLFxuICAgICAgfSlcbiAgICAgIGFzeW5jIGNyZWF0ZShAQm9keSgpIGRhdGE6IFQpOiBQcm9taXNlPE1vZGVsPGFueT4+IHtcbiAgICAgICAgY29uc3QgbG9nID0gdGhpcy5sb2cuZm9yKHRoaXMuY3JlYXRlKTtcbiAgICAgICAgbG9nLnZlcmJvc2UoYGNyZWF0aW5nIG5ldyAke21vZGVsQ2xhenpOYW1lfWApO1xuICAgICAgICBsZXQgY3JlYXRlZDogTW9kZWw7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY3JlYXRlZCA9IGF3YWl0IHRoaXMucmVwby5jcmVhdGUoZGF0YSk7XG4gICAgICAgIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICAgICAgICBsb2cuZXJyb3IoYEZhaWxlZCB0byBjcmVhdGUgbmV3ICR7bW9kZWxDbGF6ek5hbWV9YCwgZSBhcyBFcnJvcik7XG4gICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgfVxuICAgICAgICBsb2cuaW5mbyhgY3JlYXRlZCBuZXcgJHttb2RlbENsYXp6TmFtZX0gd2l0aCBpZCAke2NyZWF0ZWRbdGhpcy5wa119YCk7XG4gICAgICAgIHJldHVybiBjcmVhdGVkO1xuICAgICAgfVxuXG4gICAgICBAR2V0KFwiOmlkXCIpXG4gICAgICBAQXBpT3BlcmF0aW9uKHsgc3VtbWFyeTogYFJldHJpZXZlIGEgJHttb2RlbENsYXp6TmFtZX0gcmVjb3JkIGJ5IGlkLmAgfSlcbiAgICAgIEBBcGlQYXJhbSh7IG5hbWU6IFwiaWRcIiwgZGVzY3JpcHRpb246IFwiUHJpbWFyeSBrZXlcIiB9KVxuICAgICAgQEFwaU9rUmVzcG9uc2Uoe1xuICAgICAgICBkZXNjcmlwdGlvbjogYCR7bW9kZWxDbGF6ek5hbWV9IHJldHJpZXZlZCBzdWNjZXNzZnVsbHkuYCxcbiAgICAgIH0pXG4gICAgICBAQXBpTm90Rm91bmRSZXNwb25zZSh7XG4gICAgICAgIGRlc2NyaXB0aW9uOiBgTm8gJHttb2RlbENsYXp6TmFtZX0gcmVjb3JkIG1hdGNoZXMgdGhlIHByb3ZpZGVkIGlkZW50aWZpZXIuYCxcbiAgICAgIH0pXG4gICAgICBhc3luYyByZWFkKEBQYXJhbShcImlkXCIpIGlkOiBzdHJpbmcpIHtcbiAgICAgICAgY29uc3QgbG9nID0gdGhpcy5sb2cuZm9yKHRoaXMucmVhZCk7XG4gICAgICAgIGxldCByZWFkOiBNb2RlbDtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBsb2cuZGVidWcoYHJlYWRpbmcgJHttb2RlbENsYXp6TmFtZX0gd2l0aCAke3RoaXMucGt9ICR7aWR9YCk7XG4gICAgICAgICAgcmVhZCA9IGF3YWl0IHRoaXMucmVwby5yZWFkKGlkKTtcbiAgICAgICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgICAgIGxvZy5lcnJvcihcbiAgICAgICAgICAgIGBGYWlsZWQgdG8gcmVhZCAke21vZGVsQ2xhenpOYW1lfSB3aXRoIGlkICR7aWR9YCxcbiAgICAgICAgICAgIGUgYXMgRXJyb3JcbiAgICAgICAgICApO1xuICAgICAgICAgIHRocm93IGU7XG4gICAgICAgIH1cblxuICAgICAgICBsb2cuaW5mbyhgcmVhZCAke21vZGVsQ2xhenpOYW1lfSB3aXRoIGlkICR7cmVhZFt0aGlzLnBrXX1gKTtcbiAgICAgICAgcmV0dXJuIHJlYWQ7XG4gICAgICB9XG5cbiAgICAgIEBQdXQoXCI6aWRcIilcbiAgICAgIEBBcGlPcGVyYXRpb24oe1xuICAgICAgICBzdW1tYXJ5OiBgUmVwbGFjZSBhbiBleGlzdGluZyAke21vZGVsQ2xhenpOYW1lfSByZWNvcmQgd2l0aCBhIG5ldyBwYXlsb2FkLmAsXG4gICAgICB9KVxuICAgICAgQEFwaUJvZHkoe1xuICAgICAgICBkZXNjcmlwdGlvbjogYFBheWxvYWQgZm9yIHJlcGxhY2UgYSBleGlzdGluZyByZWNvcmQgb2YgJHttb2RlbENsYXp6TmFtZX1gLFxuICAgICAgICBzY2hlbWE6IHsgJHJlZjogZ2V0U2NoZW1hUGF0aChNb2RlbENsYXp6KSB9LFxuICAgICAgfSlcbiAgICAgIEBBcGlPa1Jlc3BvbnNlKHtcbiAgICAgICAgZGVzY3JpcHRpb246IGAke01vZGVsQ2xhenp9IHJlY29yZCByZXBsYWNlZCBzdWNjZXNzZnVsbHkuYCxcbiAgICAgIH0pXG4gICAgICBAQXBpTm90Rm91bmRSZXNwb25zZSh7XG4gICAgICAgIGRlc2NyaXB0aW9uOiBgTm8gJHttb2RlbENsYXp6TmFtZX0gcmVjb3JkIG1hdGNoZXMgdGhlIHByb3ZpZGVkIGlkZW50aWZpZXIuYCxcbiAgICAgIH0pXG4gICAgICBAQXBpQmFkUmVxdWVzdFJlc3BvbnNlKHsgZGVzY3JpcHRpb246IFwiUGF5bG9hZCB2YWxpZGF0aW9uIGZhaWxlZC5cIiB9KVxuICAgICAgYXN5bmMgdXBkYXRlKEBCb2R5KCkgZGF0YTogTW9kZWw8YW55Pikge1xuICAgICAgICBjb25zdCBsb2cgPSB0aGlzLmxvZy5mb3IodGhpcy51cGRhdGUpO1xuICAgICAgICBsZXQgdXBkYXRlZDogTW9kZWw7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgbG9nLmluZm8oXG4gICAgICAgICAgICBgdXBkYXRpbmcgJHttb2RlbENsYXp6TmFtZX0gd2l0aCAke3RoaXMucGt9ICR7ZGF0YVt0aGlzLnBrXX1gXG4gICAgICAgICAgKTtcbiAgICAgICAgICB1cGRhdGVkID0gYXdhaXQgdGhpcy5yZXBvLmNyZWF0ZShkYXRhKTtcbiAgICAgICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgICAgIHRocm93IGU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHVwZGF0ZWQ7XG4gICAgICB9XG5cbiAgICAgIEBEZWxldGUoXCI6aWRcIilcbiAgICAgIEBBcGlPcGVyYXRpb24oeyBzdW1tYXJ5OiBgRGVsZXRlIGEgJHttb2RlbENsYXp6TmFtZX0gcmVjb3JkIGJ5IGlkLmAgfSlcbiAgICAgIEBBcGlQYXJhbSh7XG4gICAgICAgIG5hbWU6IFwiaWRcIixcbiAgICAgICAgZGVzY3JpcHRpb246IGBQcmltYXJ5IGtleSB2YWx1ZSBvZiB0aGUgJHttb2RlbENsYXp6TmFtZX0gcmVjb3JkIHRvIGRlbGV0ZS5gLFxuICAgICAgfSlcbiAgICAgIEBBcGlPa1Jlc3BvbnNlKHtcbiAgICAgICAgZGVzY3JpcHRpb246IGAke21vZGVsQ2xhenpOYW1lfSByZWNvcmQgZGVsZXRlZCBzdWNjZXNzZnVsbHkuYCxcbiAgICAgIH0pXG4gICAgICBAQXBpTm90Rm91bmRSZXNwb25zZSh7XG4gICAgICAgIGRlc2NyaXB0aW9uOiBgTm8gJHttb2RlbENsYXp6TmFtZX0gcmVjb3JkIG1hdGNoZXMgdGhlIHByb3ZpZGVkIGlkZW50aWZpZXIuYCxcbiAgICAgIH0pXG4gICAgICBhc3luYyBkZWxldGUoQFBhcmFtKFwiaWRcIikgaWQ6IHN0cmluZykge1xuICAgICAgICBjb25zdCBsb2cgPSB0aGlzLmxvZy5mb3IodGhpcy5kZWxldGUpO1xuICAgICAgICBsZXQgcmVhZDogTW9kZWw7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgbG9nLmRlYnVnKFxuICAgICAgICAgICAgYGRlbGV0aW5nICR7bW9kZWxDbGF6ek5hbWV9IHdpdGggJHt0aGlzLnBrIGFzIHN0cmluZ30gJHtpZH1gXG4gICAgICAgICAgKTtcbiAgICAgICAgICByZWFkID0gYXdhaXQgdGhpcy5yZXBvLnJlYWQoaWQpO1xuICAgICAgICB9IGNhdGNoIChlOiB1bmtub3duKSB7XG4gICAgICAgICAgbG9nLmVycm9yKFxuICAgICAgICAgICAgYEZhaWxlZCB0byBkZWxldGUgJHttb2RlbENsYXp6TmFtZX0gd2l0aCBpZCAke2lkfWAsXG4gICAgICAgICAgICBlIGFzIEVycm9yXG4gICAgICAgICAgKTtcbiAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICB9XG4gICAgICAgIGxvZy5pbmZvKGBkZWxldGVkICR7bW9kZWxDbGF6ek5hbWV9IHdpdGggaWQgJHtyZWFkW3RoaXMucGtdfWApO1xuICAgICAgICByZXR1cm4gcmVhZDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gRHluYW1pY01vZGVsQ29udHJvbGxlcjtcbiAgfVxuXG4gIHN0YXRpYyBmb3JSb290KGZsYXZvdXI6IHN0cmluZyk6IER5bmFtaWNNb2R1bGUge1xuICAgIGNvbnN0IGxvZyA9IHRoaXMubG9nLmZvcih0aGlzLmZvclJvb3QpO1xuICAgIGxvZy5pbmZvKGBHZW5lcmF0aW5nIGNvbnRyb2xsZXJzIGZvciBmbGF2b3VyLi4uYCk7XG5cbiAgICBjb25zdCB0cmFja2VkTW9kZWxzID0gQWRhcHRlci5tb2RlbHMoZmxhdm91cik7XG4gICAgY29uc3QgY29udHJvbGxlcnMgPSB0cmFja2VkTW9kZWxzLm1hcCh0aGlzLnRvTW9kZWxDb250cm9sbGVyLmJpbmQodGhpcykpO1xuXG4gICAgbG9nLmluZm8oYEdlbmVyYXRlZCAke2NvbnRyb2xsZXJzLmxlbmd0aH0gY29udHJvbGxlcnNgKTtcblxuICAgIHJldHVybiB7XG4gICAgICBtb2R1bGU6IERlY2FmTW9kZWxNb2R1bGUsXG4gICAgICBjb250cm9sbGVycyxcbiAgICAgIHByb3ZpZGVyczogW1JlcG9GYWN0b3J5XSxcbiAgICB9O1xuICB9XG59XG4iLCJpbXBvcnQgeyBEeW5hbWljTW9kdWxlLCBGb3J3YXJkUmVmZXJlbmNlLCBNb2R1bGUsIFR5cGUgfSBmcm9tIFwiQG5lc3Rqcy9jb21tb25cIjtcbmltcG9ydCB7IERlY2FmTW9kdWxlT3B0aW9ucyB9IGZyb20gXCIuL3R5cGVzXCI7XG5pbXBvcnQgeyBEZWNhZkNvcmVNb2R1bGUgfSBmcm9tIFwiLi9jb3JlLW1vZHVsZVwiO1xuaW1wb3J0IHsgRGVjYWZNb2RlbE1vZHVsZSB9IGZyb20gXCIuL21vZGVsLW1vZHVsZVwiO1xuXG4vKipcbiAqIEBwdWJsaWNBcGlcbiAqL1xuQE1vZHVsZSh7fSlcbmV4cG9ydCBjbGFzcyBEZWNhZk1vZHVsZSB7XG4gIHN0YXRpYyBhc3luYyBmb3JSb290QXN5bmMoXG4gICAgb3B0aW9uczogRGVjYWZNb2R1bGVPcHRpb25zXG4gICk6IFByb21pc2U8RHluYW1pY01vZHVsZT4ge1xuICAgIGNvbnN0IHsgYXV0b0NvbnRyb2xsZXJzIH0gPSBvcHRpb25zO1xuXG4gICAgY29uc3QgYWRhcHRlciA9IGF3YWl0IERlY2FmQ29yZU1vZHVsZS5jcmVhdGVBZGFwdGVyKG9wdGlvbnMpO1xuICAgIGNvbnN0IGZsYXZvdXIgPSBhZGFwdGVyLmZsYXZvdXI7XG5cbiAgICBjb25zdCBpbXBvcnRzOlxuICAgICAgfCAoXG4gICAgICAgICAgfCBEeW5hbWljTW9kdWxlXG4gICAgICAgICAgfCBUeXBlPGFueT5cbiAgICAgICAgICB8IFByb21pc2U8RHluYW1pY01vZHVsZT5cbiAgICAgICAgICB8IEZvcndhcmRSZWZlcmVuY2U8YW55PlxuICAgICAgICApW11cbiAgICAgIHwgdW5kZWZpbmVkID0gW0RlY2FmQ29yZU1vZHVsZS5mb3JSb290KG9wdGlvbnMpXTtcblxuICAgIGlmIChhdXRvQ29udHJvbGxlcnMpIHtcbiAgICAgIGltcG9ydHMucHVzaChEZWNhZk1vZGVsTW9kdWxlLmZvclJvb3QoZmxhdm91cikpO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBtb2R1bGU6IERlY2FmTW9kdWxlLFxuICAgICAgaW1wb3J0czogaW1wb3J0cyxcbiAgICB9O1xuICB9XG59XG4iLCJpbXBvcnQge01vZGVsfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQge0ludGVybmFsRXJyb3J9IGZyb20gXCJAZGVjYWYtdHMvZGItZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHtSZXBvc2l0b3J5fSBmcm9tIFwiQGRlY2FmLXRzL2NvcmVcIjtcblxuZXhwb3J0IGZ1bmN0aW9uIHJlcG9Gb3JNb2RlbChtb2RlbDogc3RyaW5nKSB7XG5cdGNvbnN0IG0gPSBNb2RlbC5nZXQobW9kZWwpO1xuXHRpZiAoIW0pXG5cdFx0dGhyb3cgbmV3IEludGVybmFsRXJyb3IoYEZhaWxlZCB0byBmaW5kIHJlcG9zaXRvcnkgZm9yICR7bW9kZWx9YClcblx0Y29uc3QgcmVwbyA9IFJlcG9zaXRvcnkuZm9yTW9kZWwobSk7XG5cdHJldHVybiByZXBvO1xufSIsIi8qKlxuICogQG1vZHVsZSBmb3ItbmVzdFxuICogQGRlc2NyaXB0aW9uIFRoaXMgbW9kdWxlIHNlcnZlcyBhcyB0aGUgbWFpbiBlbnRyeSBwb2ludCBmb3IgdGhlIHRzLXdvcmtzcGFjZSBsaWJyYXJ5LiBJdCBhZ2dyZWdhdGVzIGFuZCBleHBvcnRzXG4gKiBmdW5jdGlvbmFsaXR5IGZyb20gdmFyaW91cyBzdWJtb2R1bGVzIGFuZCB1dGlsaXRpZXMgd2l0aGluIHRoZSBwcm9qZWN0LlxuICpcbiAqIFRoZSBtb2R1bGUgaW5jbHVkZXM6XG4gKiAxLiBVdGlsaXR5IGZ1bmN0aW9ucyBhbmQgdHlwZXMgZnJvbSB0aGUgXCIuL3V0aWxzXCIgZGlyZWN0b3J5OlxuICogICAgLSBUaGVzZSBsaWtlbHkgY29udGFpbiBoZWxwZXIgZnVuY3Rpb25zLCBjb21tb24gdHlwZXMsIGFuZCBzaGFyZWQgZnVuY3Rpb25hbGl0eSB1c2VkIHRocm91Z2hvdXQgdGhlIHByb2plY3QuXG4gKiAgICAtIE1heSBpbmNsdWRlIG9wZXJhdGlvbnMgZm9yIGRhdGEgbWFuaXB1bGF0aW9uLCB0eXBlIGNoZWNraW5nLCBvciBvdGhlciBnZW5lcmFsLXB1cnBvc2UgdXRpbGl0aWVzLlxuICpcbiAqIDIuIEEgbmFtZXNwYWNlIGFuZCByZWxhdGVkIHR5cGVzIGZyb20gdGhlIFwiLi9uYW1lc3BhY2VcIiBkaXJlY3Rvcnk6XG4gKiAgICAtIFRoaXMgY291bGQgY29udGFpbiBkb21haW4tc3BlY2lmaWMgY29kZSBvciBhIGNvbGxlY3Rpb24gb2YgcmVsYXRlZCBmdW5jdGlvbmFsaXR5LlxuICogICAgLSBNaWdodCBpbmNsdWRlIGludGVyZmFjZXMsIHR5cGVzLCBvciBjbGFzc2VzIHRoYXQgcmVwcmVzZW50IGNvcmUgY29uY2VwdHMgaW4gdGhlIGxpYnJhcnkuXG4gKlxuICogMy4gQSBWRVJTSU9OIGNvbnN0YW50OlxuICogICAgLSBSZXByZXNlbnRzIHRoZSBjdXJyZW50IHZlcnNpb24gb2YgdGhlIG1vZHVsZS5cbiAqICAgIC0gVXNlZnVsIGZvciB2ZXJzaW9uIGNoZWNraW5nIGFuZCBjb21wYXRpYmlsaXR5IHB1cnBvc2VzLlxuICpcbiAqIFRoaXMgc3RydWN0dXJlIHByb3ZpZGVzIGEgY2xlYW4gYW5kIG9yZ2FuaXplZCBleHBvcnQgb2YgdGhlIG1vZHVsZSdzIGZ1bmN0aW9uYWxpdHksIGFsbG93aW5nIGNvbnN1bWVyc1xuICogdG8gZWFzaWx5IGltcG9ydCBhbmQgdXNlIHNwZWNpZmljIHBhcnRzIG9mIHRoZSBsaWJyYXJ5IGFzIG5lZWRlZC5cbiAqL1xuXG5pbXBvcnQgeyBNZXRhZGF0YSB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdGlvblwiO1xuaW1wb3J0IFwiLi9kZWNvcmF0aW9uXCI7XG5cbmV4cG9ydCAqIGZyb20gXCIuL2RlY29yYXRvcnNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2NvbnN0YW50c1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vZGVjb3JhdGlvblwiO1xuZXhwb3J0ICogZnJvbSBcIi4vbW9kdWxlXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9SZXBvRmFjdG9yeVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vdHlwZXNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3V0aWxzXCI7XG5cbi8qKlxuICogUmVwcmVzZW50cyB0aGUgY3VycmVudCB2ZXJzaW9uIG9mIHRoZSB0cy13b3Jrc3BhY2UgbW9kdWxlLlxuICogVGhlIGFjdHVhbCB2ZXJzaW9uIG51bWJlciBpcyByZXBsYWNlZCBkdXJpbmcgdGhlIGJ1aWxkIHByb2Nlc3MuXG4gKiBAY29uc3RhbnRcbiAqIEB0eXBlIHtzdHJpbmd9XG4gKi9cbmV4cG9ydCBjb25zdCBWRVJTSU9OID0gXCIjI1ZFUlNJT04jI1wiO1xuZXhwb3J0IGNvbnN0IFBBQ0tBR0VfTkFNRSA9IFwiIyNQQUNLQUdFX05BTUUjI1wiO1xuXG5NZXRhZGF0YS5yZWdpc3RlckxpYnJhcnkoUEFDS0FHRV9OQU1FLCBWRVJTSU9OKTtcbiJdLCJuYW1lcyI6WyJnZXRUeXBlSXNBcnJheVR1cGxlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQVFnQixTQUFBLHFCQUFxQixDQUNuQyxPQUFlLEVBQ2YsUUFBVyxFQUNYLEVBQUUsZ0JBQWdCLEVBQUUsR0FBRyxFQUFFLGdCQUFnQixFQUFFLElBQUksRUFBRSxFQUFBO0FBRWpELElBQUEsT0FBTyxDQUNMLE1BQWMsRUFDZCxHQUFvQixFQUNwQixVQUE4QixLQUM1QjtBQUNGLFFBQUEsSUFBSSxPQUFPLFFBQVEsS0FBSyxRQUFRLEVBQUU7QUFDaEMsWUFBQSxNQUFNLFNBQVMsR0FBRyxPQUFPLENBQUMsV0FBVyxDQUFDLE9BQU8sRUFBRSxVQUFVLENBQUMsS0FBSyxDQUFDO0FBQ2hFLFlBQUEsSUFBSSxTQUFTLElBQUksQ0FBQyxnQkFBZ0IsRUFBRTtBQUNsQyxnQkFBQSxPQUFPLFVBQVU7O0FBRW5CLFlBQUEsT0FBTyxDQUFDLGNBQWMsQ0FDcEIsT0FBTyxFQUNQLEVBQUUsR0FBRyxTQUFTLEVBQUUsR0FBRyxRQUFRLEVBQUUsRUFDN0IsVUFBVSxDQUFDLEtBQUssQ0FDakI7QUFDRCxZQUFBLE9BQU8sVUFBVTs7UUFFbkIsT0FBTyxDQUFDLGNBQWMsQ0FBQyxPQUFPLEVBQUUsUUFBUSxFQUFFLFVBQVUsQ0FBQyxLQUFLLENBQUM7QUFDM0QsUUFBQSxPQUFPLFVBQVU7QUFDbkIsS0FBQztBQUNIO1NBRWdCLG9CQUFvQixDQUNsQyxPQUFlLEVBQ2YsV0FBYyxFQUFrQixFQUFBO0lBRWhDLE9BQU8sQ0FBQyxNQUFNLEtBQUk7QUFDaEIsUUFBQSxNQUFNLFNBQVMsR0FBRyxPQUFPLENBQUMsV0FBVyxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMs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