@decaf-ts/for-nest 0.0.5 → 0.0.7

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 (138) hide show
  1. package/dist/for-nest.cjs +2 -1213
  2. package/dist/for-nest.cjs.map +1 -0
  3. package/dist/for-nest.js +2 -0
  4. package/dist/for-nest.js.map +1 -0
  5. package/lib/RepoFactory.cjs +1 -1
  6. package/lib/RepoFactory.js.map +1 -0
  7. package/lib/cli-module.cjs +1 -1
  8. package/lib/cli-module.d.ts +1 -29
  9. package/lib/cli-module.js.map +1 -0
  10. package/lib/constants.cjs +1 -1
  11. package/lib/constants.js.map +1 -0
  12. package/lib/core-module.cjs +1 -1
  13. package/lib/core-module.js.map +1 -0
  14. package/lib/decoration.cjs +1 -1
  15. package/lib/decoration.js.map +1 -0
  16. package/lib/decorators/ApiProperty.cjs +1 -1
  17. package/lib/decorators/ApiProperty.js.map +1 -0
  18. package/lib/decorators/helpers.cjs +1 -1
  19. package/lib/decorators/helpers.js.map +1 -0
  20. package/lib/decorators/index.cjs +1 -1
  21. package/lib/decorators/index.js.map +1 -0
  22. package/lib/decorators.cjs +33 -0
  23. package/lib/decorators.d.ts +10 -0
  24. package/lib/decorators.js.map +1 -0
  25. package/lib/esm/RepoFactory.js +1 -1
  26. package/lib/esm/RepoFactory.js.map +1 -0
  27. package/lib/esm/cli-module.d.ts +1 -29
  28. package/lib/esm/cli-module.js +1 -1
  29. package/lib/esm/cli-module.js.map +1 -0
  30. package/lib/esm/constants.js +1 -1
  31. package/lib/esm/constants.js.map +1 -0
  32. package/lib/esm/core-module.js +1 -1
  33. package/lib/esm/core-module.js.map +1 -0
  34. package/lib/esm/decoration.js +1 -1
  35. package/lib/esm/decoration.js.map +1 -0
  36. package/lib/esm/decorators/ApiProperty.js +1 -1
  37. package/lib/esm/decorators/ApiProperty.js.map +1 -0
  38. package/lib/esm/decorators/helpers.js +1 -1
  39. package/lib/esm/decorators/helpers.js.map +1 -0
  40. package/lib/esm/decorators/index.js +1 -1
  41. package/lib/esm/decorators/index.js.map +1 -0
  42. package/lib/esm/decorators.d.ts +10 -0
  43. package/lib/esm/decorators.js +29 -0
  44. package/lib/esm/decorators.js.map +1 -0
  45. package/lib/esm/factory/NestBootstraper.d.ts +7 -8
  46. package/lib/esm/factory/NestBootstraper.js +9 -9
  47. package/lib/esm/factory/NestBootstraper.js.map +1 -0
  48. package/lib/esm/factory/errors/cors.js +1 -1
  49. package/lib/esm/factory/errors/cors.js.map +1 -0
  50. package/lib/esm/factory/errors/index.js +1 -1
  51. package/lib/esm/factory/errors/index.js.map +1 -0
  52. package/lib/esm/factory/exceptions/AuthorizationExceptionFilter.js +2 -2
  53. package/lib/esm/factory/exceptions/AuthorizationExceptionFilter.js.map +1 -0
  54. package/lib/esm/factory/exceptions/ConflictExceptionFilter.js +3 -3
  55. package/lib/esm/factory/exceptions/ConflictExceptionFilter.js.map +1 -0
  56. package/lib/esm/factory/exceptions/GlobalExceptionFilter.js +7 -3
  57. package/lib/esm/factory/exceptions/GlobalExceptionFilter.js.map +1 -0
  58. package/lib/esm/factory/exceptions/HttpExceptionFilter.js +3 -3
  59. package/lib/esm/factory/exceptions/HttpExceptionFilter.js.map +1 -0
  60. package/lib/esm/factory/exceptions/HttpResponseError.d.ts +0 -1
  61. package/lib/esm/factory/exceptions/HttpResponseError.js +4 -2
  62. package/lib/esm/factory/exceptions/HttpResponseError.js.map +1 -0
  63. package/lib/esm/factory/exceptions/NotFoundExceptionFilter.js +2 -2
  64. package/lib/esm/factory/exceptions/NotFoundExceptionFilter.js.map +1 -0
  65. package/lib/esm/factory/exceptions/ValidationExceptionFilter.js +3 -3
  66. package/lib/esm/factory/exceptions/ValidationExceptionFilter.js.map +1 -0
  67. package/lib/esm/factory/exceptions/index.d.ts +1 -0
  68. package/lib/esm/factory/exceptions/index.js +2 -1
  69. package/lib/esm/factory/exceptions/index.js.map +1 -0
  70. package/lib/esm/factory/index.js +1 -1
  71. package/lib/esm/factory/index.js.map +1 -0
  72. package/lib/esm/factory/openapi/SwaggerBuilder.js +1 -1
  73. package/lib/esm/factory/openapi/SwaggerBuilder.js.map +1 -0
  74. package/lib/esm/factory/openapi/SwaggerCustomUI.js +1 -1
  75. package/lib/esm/factory/openapi/SwaggerCustomUI.js.map +1 -0
  76. package/lib/esm/factory/openapi/constants.js +1 -1
  77. package/lib/esm/factory/openapi/constants.js.map +1 -0
  78. package/lib/esm/factory/openapi/index.js +1 -1
  79. package/lib/esm/factory/openapi/index.js.map +1 -0
  80. package/lib/esm/index.d.ts +1 -1
  81. package/lib/esm/index.js +3 -3
  82. package/lib/esm/index.js.map +1 -0
  83. package/lib/esm/model-module.js +37 -6
  84. package/lib/esm/model-module.js.map +1 -0
  85. package/lib/esm/module.js +1 -1
  86. package/lib/esm/module.js.map +1 -0
  87. package/lib/esm/types.js +1 -1
  88. package/lib/esm/types.js.map +1 -0
  89. package/lib/esm/utils.js +1 -1
  90. package/lib/esm/utils.js.map +1 -0
  91. package/lib/factory/NestBootstraper.cjs +9 -9
  92. package/lib/factory/NestBootstraper.d.ts +7 -8
  93. package/lib/factory/NestBootstraper.js.map +1 -0
  94. package/lib/factory/errors/cors.cjs +1 -1
  95. package/lib/factory/errors/cors.js.map +1 -0
  96. package/lib/factory/errors/index.cjs +1 -1
  97. package/lib/factory/errors/index.js.map +1 -0
  98. package/lib/factory/exceptions/AuthorizationExceptionFilter.cjs +1 -1
  99. package/lib/factory/exceptions/AuthorizationExceptionFilter.js.map +1 -0
  100. package/lib/factory/exceptions/ConflictExceptionFilter.cjs +2 -2
  101. package/lib/factory/exceptions/ConflictExceptionFilter.js.map +1 -0
  102. package/lib/factory/exceptions/GlobalExceptionFilter.cjs +6 -2
  103. package/lib/factory/exceptions/GlobalExceptionFilter.js.map +1 -0
  104. package/lib/factory/exceptions/HttpExceptionFilter.cjs +2 -2
  105. package/lib/factory/exceptions/HttpExceptionFilter.js.map +1 -0
  106. package/lib/factory/exceptions/HttpResponseError.cjs +4 -2
  107. package/lib/factory/exceptions/HttpResponseError.d.ts +0 -1
  108. package/lib/factory/exceptions/HttpResponseError.js.map +1 -0
  109. package/lib/factory/exceptions/NotFoundExceptionFilter.cjs +1 -1
  110. package/lib/factory/exceptions/NotFoundExceptionFilter.js.map +1 -0
  111. package/lib/factory/exceptions/ValidationExceptionFilter.cjs +2 -2
  112. package/lib/factory/exceptions/ValidationExceptionFilter.js.map +1 -0
  113. package/lib/factory/exceptions/index.cjs +2 -1
  114. package/lib/factory/exceptions/index.d.ts +1 -0
  115. package/lib/factory/exceptions/index.js.map +1 -0
  116. package/lib/factory/index.cjs +1 -1
  117. package/lib/factory/index.js.map +1 -0
  118. package/lib/factory/openapi/SwaggerBuilder.cjs +1 -1
  119. package/lib/factory/openapi/SwaggerBuilder.js.map +1 -0
  120. package/lib/factory/openapi/SwaggerCustomUI.cjs +1 -1
  121. package/lib/factory/openapi/SwaggerCustomUI.js.map +1 -0
  122. package/lib/factory/openapi/constants.cjs +1 -1
  123. package/lib/factory/openapi/constants.js.map +1 -0
  124. package/lib/factory/openapi/index.cjs +1 -1
  125. package/lib/factory/openapi/index.js.map +1 -0
  126. package/lib/index.cjs +3 -3
  127. package/lib/index.d.ts +1 -1
  128. package/lib/index.js.map +1 -0
  129. package/lib/model-module.cjs +36 -5
  130. package/lib/model-module.js.map +1 -0
  131. package/lib/module.cjs +1 -1
  132. package/lib/module.js.map +1 -0
  133. package/lib/types.cjs +1 -1
  134. package/lib/types.js.map +1 -0
  135. package/lib/utils.cjs +1 -1
  136. package/lib/utils.js.map +1 -0
  137. package/package.json +8 -49
  138. package/dist/for-nest.esm.cjs +0 -1185
package/dist/for-nest.cjs CHANGED
@@ -1,1213 +1,2 @@
1
- (function (global, factory) {
2
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@decaf-ts/decoration'), require('@decaf-ts/injectable-decorators'), require('@nestjs/common'), require('@decaf-ts/decorator-validation'), require('@nestjs/swagger/dist/decorators/helpers'), require('@nestjs/swagger/dist/utils/enum.utils'), require('@nestjs/swagger/dist/constants'), require('@nestjs/common/constants'), require('@nestjs/common/utils/shared.utils'), require('lodash'), require('@nestjs/swagger/dist/plugin/plugin-constants'), require('@decaf-ts/core'), require('tslib'), require('@nestjs/core'), require('@decaf-ts/logging'), require('@nestjs/swagger'), require('@decaf-ts/db-decorators'), require('fs'), require('path')) :
3
- typeof define === 'function' && define.amd ? define(['exports', '@decaf-ts/decoration', '@decaf-ts/injectable-decorators', '@nestjs/common', '@decaf-ts/decorator-validation', '@nestjs/swagger/dist/decorators/helpers', '@nestjs/swagger/dist/utils/enum.utils', '@nestjs/swagger/dist/constants', '@nestjs/common/constants', '@nestjs/common/utils/shared.utils', 'lodash', '@nestjs/swagger/dist/plugin/plugin-constants', '@decaf-ts/core', 'tslib', '@nestjs/core', '@decaf-ts/logging', '@nestjs/swagger', '@decaf-ts/db-decorators', 'fs', 'path'], factory) :
4
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["for-nest"] = {}, global.decoration, global.injectableDecorators, global.common, global.decoratorValidation, global.helpers, global.enum_utils, global.constants, global.constants$1, global.shared_utils, global.lodash, global.pluginConstants, global.core, global.tslib, global.core$1, global.logging, global.swagger, global.dbDecorators, global.fs, global.path));
5
- })(this, (function (exports, decoration, injectableDecorators, common, decoratorValidation, helpers, enum_utils, constants, constants$1, shared_utils, lodash, pluginConstants, core, tslib, core$1, logging, swagger, dbDecorators, fs, path) { 'use strict';
6
-
7
- function _interopNamespaceDefault(e) {
8
- var n = Object.create(null);
9
- if (e) {
10
- Object.keys(e).forEach(function (k) {
11
- if (k !== 'default') {
12
- var d = Object.getOwnPropertyDescriptor(e, k);
13
- Object.defineProperty(n, k, d.get ? d : {
14
- enumerable: true,
15
- get: function () { return e[k]; }
16
- });
17
- }
18
- });
19
- }
20
- n.default = e;
21
- return Object.freeze(n);
22
- }
23
-
24
- var path__namespace = /*#__PURE__*/_interopNamespaceDefault(path);
25
-
26
- /* eslint-disable @typescript-eslint/no-unsafe-function-type */
27
- function createMethodDecorator(metakey, metadata, { overrideExisting } = { overrideExisting: true }) {
28
- return (target, key, descriptor) => {
29
- if (typeof metadata === "object") {
30
- const prevValue = Reflect.getMetadata(metakey, descriptor.value);
31
- if (prevValue && !overrideExisting) {
32
- return descriptor;
33
- }
34
- Reflect.defineMetadata(metakey, { ...prevValue, ...metadata }, descriptor.value);
35
- return descriptor;
36
- }
37
- Reflect.defineMetadata(metakey, metadata, descriptor.value);
38
- return descriptor;
39
- };
40
- }
41
- function createClassDecorator(metakey, metadata = []) {
42
- return (target) => {
43
- const prevValue = Reflect.getMetadata(metakey, target) || [];
44
- Reflect.defineMetadata(metakey, [...prevValue, ...metadata], target);
45
- return target;
46
- };
47
- }
48
- function createPropertyDecorator(metakey, metadata, overrideExisting = true) {
49
- return (target, propertyKey) => {
50
- const properties = Reflect.getMetadata(constants.DECORATORS.API_MODEL_PROPERTIES_ARRAY, target) || [];
51
- const key = `:${propertyKey}`;
52
- if (!properties.includes(key)) {
53
- Reflect.defineMetadata(constants.DECORATORS.API_MODEL_PROPERTIES_ARRAY, [...properties, `:${propertyKey}`], target);
54
- }
55
- const existingMetadata = Reflect.getMetadata(metakey, target, propertyKey);
56
- if (existingMetadata) {
57
- const newMetadata = lodash.pickBy(metadata, lodash.negate(lodash.isUndefined));
58
- const metadataToSave = overrideExisting
59
- ? {
60
- ...existingMetadata,
61
- ...newMetadata,
62
- }
63
- : {
64
- ...newMetadata,
65
- ...existingMetadata,
66
- };
67
- Reflect.defineMetadata(metakey, metadataToSave, target, propertyKey);
68
- }
69
- else {
70
- const type =
71
- // @ts-expect-error nest js override
72
- target?.constructor?.[pluginConstants.METADATA_FACTORY_NAME]?.()[propertyKey]?.type ??
73
- Reflect.getMetadata("design:type", target, propertyKey);
74
- Reflect.defineMetadata(metakey, {
75
- type,
76
- ...lodash.pickBy(metadata, lodash.negate(lodash.isUndefined)),
77
- }, target, propertyKey);
78
- }
79
- };
80
- }
81
- function createMixedDecorator(metakey, metadata) {
82
- return (target, key, descriptor) => {
83
- if (descriptor) {
84
- let metadatas;
85
- if (Array.isArray(metadata)) {
86
- const previousMetadata = Reflect.getMetadata(metakey, descriptor.value) || [];
87
- metadatas = [...previousMetadata, ...metadata];
88
- }
89
- else {
90
- const previousMetadata = Reflect.getMetadata(metakey, descriptor.value) || {};
91
- metadatas = { ...previousMetadata, ...metadata };
92
- }
93
- Reflect.defineMetadata(metakey, metadatas, descriptor.value);
94
- return descriptor;
95
- }
96
- let metadatas;
97
- if (Array.isArray(metadata)) {
98
- const previousMetadata = Reflect.getMetadata(metakey, target) || [];
99
- metadatas = [...previousMetadata, ...metadata];
100
- }
101
- else {
102
- const previousMetadata = Reflect.getMetadata(metakey, target) || {};
103
- metadatas = Object.assign(Object.assign({}, previousMetadata), metadata);
104
- }
105
- Reflect.defineMetadata(metakey, metadatas, target);
106
- return target;
107
- };
108
- }
109
- function createParamDecorator(metadata, initial) {
110
- return (target, key, descriptor) => {
111
- const paramOptions = {
112
- ...initial,
113
- ...lodash.pickBy(metadata, lodash.negate(lodash.isUndefined)),
114
- };
115
- if (descriptor) {
116
- const parameters = Reflect.getMetadata(constants.DECORATORS.API_PARAMETERS, descriptor.value) || [];
117
- Reflect.defineMetadata(constants.DECORATORS.API_PARAMETERS, [...parameters, paramOptions], descriptor.value);
118
- return descriptor;
119
- }
120
- if (typeof target === "object") {
121
- return target;
122
- }
123
- const propertyKeys = Object.getOwnPropertyNames(target.prototype);
124
- for (const propertyKey of propertyKeys) {
125
- if (shared_utils.isConstructor(propertyKey)) {
126
- continue;
127
- }
128
- const methodDescriptor = Object.getOwnPropertyDescriptor(target.prototype, propertyKey);
129
- if (!methodDescriptor) {
130
- continue;
131
- }
132
- const isApiMethod = Reflect.hasMetadata(constants$1.METHOD_METADATA, methodDescriptor.value);
133
- if (!isApiMethod) {
134
- continue;
135
- }
136
- const parameters = Reflect.getMetadata(constants.DECORATORS.API_PARAMETERS, methodDescriptor.value) || [];
137
- Reflect.defineMetadata(constants.DECORATORS.API_PARAMETERS, [...parameters, paramOptions], methodDescriptor.value);
138
- }
139
- };
140
- }
141
- function getTypeIsArrayTuple(input, isArrayFlag) {
142
- if (!input) {
143
- return [input, isArrayFlag];
144
- }
145
- if (isArrayFlag) {
146
- return [input, isArrayFlag];
147
- }
148
- const isInputArray = lodash.isArray(input);
149
- const type = isInputArray ? input[0] : input;
150
- return [type, isInputArray];
151
- }
152
-
153
- const isEnumArray = (opts) => (opts.isArray && "enum" in opts && opts.enum !== undefined);
154
- /**
155
- * @publicApi
156
- */
157
- function ApiProperty(options = {}) {
158
- return createApiPropertyDecorator(options);
159
- }
160
- function createApiPropertyDecorator(options = {}, overrideExisting = true) {
161
- const [type, isArray] = helpers.getTypeIsArrayTuple(options.type, options.isArray);
162
- options = {
163
- ...options,
164
- type,
165
- isArray,
166
- };
167
- if (isEnumArray(options)) {
168
- options.type = "array";
169
- const enumValues = enum_utils.getEnumValues(options.enum);
170
- options.items = {
171
- type: enum_utils.getEnumType(enumValues),
172
- enum: enumValues,
173
- };
174
- // @ts-expect-error nest swagger override
175
- delete options.enum;
176
- }
177
- else if ("enum" in options && options.enum !== undefined) {
178
- const enumValues = enum_utils.getEnumValues(options.enum);
179
- options.enum = enumValues;
180
- options.type = enum_utils.getEnumType(enumValues);
181
- }
182
- if (Array.isArray(options.type)) {
183
- options.type = "array";
184
- options.items = {
185
- type: "array",
186
- items: {
187
- type: options.type[0],
188
- },
189
- };
190
- }
191
- return createPropertyDecorator(constants.DECORATORS.API_MODEL_PROPERTIES, options, overrideExisting);
192
- }
193
- function ApiPropertyOptional(options = {}) {
194
- return ApiProperty({
195
- ...options,
196
- required: false,
197
- });
198
- }
199
- function ApiResponseProperty(options = {}) {
200
- return ApiProperty({
201
- readOnly: true,
202
- ...options,
203
- });
204
- }
205
-
206
- decoration.Decoration.for(injectableDecorators.InjectablesKeys.INJECTABLE)
207
- .extend({
208
- decorator: function nestInjectable(category, cfg) {
209
- return common.Injectable({
210
- scope: cfg.singleton ? common.Scope.DEFAULT : common.Scope.REQUEST,
211
- durable: cfg.singleton ? undefined : true,
212
- });
213
- },
214
- })
215
- .apply();
216
- decoration.Decoration.for(injectableDecorators.InjectablesKeys.INJECT)
217
- .extend({
218
- decorator: function nestInject(category,
219
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
220
- cfg) {
221
- return function innerNestInject(target, propertyKey, descriptor) {
222
- return common.Inject(category || target)(target, propertyKey, descriptor);
223
- };
224
- },
225
- })
226
- .apply();
227
- decoration.Decoration.for(decoratorValidation.ValidationKeys.REQUIRED)
228
- .extend(ApiProperty({
229
- required: true,
230
- }))
231
- .apply();
232
- decoration.Decoration.for(decoratorValidation.ValidationKeys.MAX)
233
- .extend({
234
- decorator: function maxDec(max) {
235
- return ApiProperty({ maximum: max });
236
- },
237
- })
238
- .apply();
239
- decoration.Decoration.for(decoratorValidation.ValidationKeys.MIN)
240
- .extend({
241
- decorator: function minDec(min) {
242
- return ApiProperty({ minimum: min });
243
- },
244
- })
245
- .apply();
246
- decoration.Decoration.for(decoratorValidation.ValidationKeys.MAX_LENGTH)
247
- .extend({
248
- decorator: function maxLengthDec(max) {
249
- return ApiProperty({ maxLength: max });
250
- },
251
- })
252
- .apply();
253
- decoration.Decoration.for(decoratorValidation.ValidationKeys.MIN_LENGTH)
254
- .extend({
255
- decorator: function minLengthDec(min) {
256
- return ApiProperty({ minLength: min });
257
- },
258
- })
259
- .apply();
260
- //
261
- // Decoration.for(ValidationKeys.TYPE)
262
- // .extend({
263
- // decorator: function typeDec(type: (string | (() => string))[] | string | (() => string)) {
264
- // return ApiProperty({ type: type as any });
265
- // },
266
- // })
267
- // .apply();
268
- //
269
- // Decoration.for(ValidationKeys.DATE)
270
- // .extend({
271
- // decorator: function dateDec() {
272
- // return ApiProperty({ type: Date });
273
- // },
274
- // })
275
- // .apply();
276
- decoration.Decoration.for(decoratorValidation.ValidationKeys.LIST)
277
- .extend({
278
- decorator: function listDec(clazz) {
279
- const c = Array.isArray(clazz) ? clazz[0] : clazz;
280
- return ApiProperty({ type: [c] });
281
- },
282
- })
283
- .apply();
284
- //
285
- // Decoration.for(ValidationKeys.OPTION)
286
- // .extend({
287
- // decorator: function optionDec(options: string[] | Record<string, any>) {
288
- // const opts = Array.isArray(options) ? options : Object.values(options);
289
- // return ApiProperty({ enum: opts });
290
- // },
291
- // })
292
- // .apply();
293
- decoration.Decoration.for(decoratorValidation.ValidationKeys.PATTERN)
294
- .extend({
295
- decorator: function patternDec(pat) {
296
- return ApiProperty({
297
- pattern: typeof pat === "string" ? pat : pat.source,
298
- });
299
- },
300
- })
301
- .apply();
302
- decoration.Decoration.for(core.PersistenceKeys.COLUMN)
303
- .extend({
304
- decorator: function columnDec(name) {
305
- return ApiProperty({
306
- name: name,
307
- });
308
- },
309
- })
310
- .apply();
311
- decoration.Decoration.for(decoration.DecorationKeys.DESCRIPTION)
312
- .extend({
313
- decorator: function descriptionDec(description) {
314
- return ApiProperty({
315
- description: description,
316
- });
317
- },
318
- })
319
- .apply();
320
-
321
- const DECAF_MODULE_OPTIONS = "DecafModuleOptions";
322
- const DECAF_ADAPTER_ID = "DecafAdapter";
323
-
324
- var DecafCoreModule_1;
325
- let DecafCoreModule = class DecafCoreModule {
326
- static { DecafCoreModule_1 = this; }
327
- static { this._adapterInstance = null; }
328
- static get log() {
329
- if (!this._logger)
330
- this._logger = logging.Logging.for(DecafCoreModule_1);
331
- return this._logger;
332
- }
333
- constructor(options, moduleRef) {
334
- this.options = options;
335
- this.moduleRef = moduleRef;
336
- }
337
- static async createAdapter(options) {
338
- if (!this._adapterInstance) {
339
- const log = this.log.for(this.createAdapter);
340
- log.info("Creating adapter instance...");
341
- this._adapterInstance = new options.adapter(options.conf, options.alias);
342
- log.info("Adapter instance created successfully!");
343
- }
344
- return this._adapterInstance;
345
- }
346
- static getAdapterInstance() {
347
- return this._adapterInstance;
348
- }
349
- static forRoot(options) {
350
- const typeOrmModuleOptions = {
351
- provide: DECAF_MODULE_OPTIONS,
352
- useValue: options,
353
- };
354
- const adapter = {
355
- useFactory: async (opts) => {
356
- return DecafCoreModule_1.createAdapter(opts);
357
- },
358
- provide: DECAF_ADAPTER_ID,
359
- durable: true,
360
- scope: common.Scope.DEFAULT,
361
- inject: [DECAF_MODULE_OPTIONS],
362
- };
363
- const providers = [adapter, typeOrmModuleOptions];
364
- const exports = [adapter];
365
- return {
366
- module: DecafCoreModule_1,
367
- providers,
368
- exports,
369
- };
370
- }
371
- async onApplicationShutdown() {
372
- const log = DecafCoreModule_1.log.for(this.onApplicationShutdown);
373
- const adapter = this.moduleRef.get(DECAF_ADAPTER_ID);
374
- try {
375
- if (adapter) {
376
- log.info("Shutting down");
377
- await adapter.shutdown();
378
- DecafCoreModule_1._adapterInstance = null;
379
- }
380
- }
381
- catch (e) {
382
- log.error(`Failed to shutdown application`, e);
383
- }
384
- }
385
- };
386
- DecafCoreModule = DecafCoreModule_1 = tslib.__decorate([
387
- common.Global(),
388
- common.Module({}),
389
- tslib.__param(0, common.Inject(DECAF_MODULE_OPTIONS)),
390
- tslib.__metadata("design:paramtypes", [Object, core$1.ModuleRef])
391
- ], DecafCoreModule);
392
-
393
- exports.RepoFactory = class RepoFactory {
394
- for(model) {
395
- model = typeof model === "string" ? decoratorValidation.Model.get(model) : model;
396
- if (!model) {
397
- throw new dbDecorators.InternalError(`Failed to find repository for ${model}`);
398
- }
399
- return core.Repository.forModel(model);
400
- }
401
- };
402
- exports.RepoFactory = tslib.__decorate([
403
- common.Injectable()
404
- ], exports.RepoFactory);
405
-
406
- var DecafModelModule_1;
407
- let DecafModelModule = class DecafModelModule {
408
- static { DecafModelModule_1 = this; }
409
- static get log() {
410
- if (!this._logger)
411
- this._logger = logging.Logging.for(DecafModelModule_1);
412
- return this._logger;
413
- }
414
- static toModelController(ModelClazz) {
415
- const log = this.log.for(this.toModelController);
416
- const tableName = core.Repository.table(ModelClazz);
417
- const routePath = logging.toKebabCase(tableName);
418
- const modelClazzName = ModelClazz.name;
419
- log.debug(`Creating controller for model: ${modelClazzName}`);
420
- let DynamicModelController = class DynamicModelController extends logging.LoggedClass {
421
- constructor(repoFactory) {
422
- super();
423
- this.repoFactory = repoFactory;
424
- log.info(`Registering dynamic controller for model: ${modelClazzName} route: /${routePath}`);
425
- try {
426
- this.repo = this.repoFactory.for(ModelClazz.name);
427
- this.pk = this.repo.pk;
428
- }
429
- catch (e) {
430
- this.log.error(`Failed to initialize repository for model "${ModelClazz.name}".`, e);
431
- }
432
- }
433
- async create(data) {
434
- const log = this.log.for(this.create);
435
- log.verbose(`creating new ${modelClazzName}`);
436
- let created;
437
- try {
438
- created = await this.repo.create(data);
439
- }
440
- catch (e) {
441
- log.error(`Failed to create new ${modelClazzName}`, e);
442
- throw e;
443
- }
444
- log.info(`created new ${modelClazzName} with id ${created[this.pk]}`);
445
- return created;
446
- }
447
- async read(id) {
448
- const log = this.log.for(this.read);
449
- let read;
450
- try {
451
- log.debug(`reading ${modelClazzName} with ${this.pk} ${id}`);
452
- read = await this.repo.read(id);
453
- }
454
- catch (e) {
455
- log.error(`Failed to read ${modelClazzName} with id ${id}`, e);
456
- throw e;
457
- }
458
- log.info(`read ${modelClazzName} with id ${read[this.pk]}`);
459
- return read;
460
- }
461
- async update(data) {
462
- const log = this.log.for(this.update);
463
- let updated;
464
- try {
465
- log.info(`updating ${modelClazzName} with ${this.pk} ${data[this.pk]}`);
466
- updated = await this.repo.create(data);
467
- }
468
- catch (e) {
469
- throw e;
470
- }
471
- return updated;
472
- }
473
- async delete(id) {
474
- const log = this.log.for(this.delete);
475
- let read;
476
- try {
477
- log.debug(`deleting ${modelClazzName} with ${this.pk} ${id}`);
478
- read = await this.repo.read(id);
479
- }
480
- catch (e) {
481
- log.error(`Failed to delete ${modelClazzName} with id ${id}`, e);
482
- throw e;
483
- }
484
- log.info(`deleted ${modelClazzName} with id ${read[this.pk]}`);
485
- return read;
486
- }
487
- };
488
- tslib.__decorate([
489
- common.Post(),
490
- swagger.ApiOperation({ summary: `Create a new ${modelClazzName}.` }),
491
- swagger.ApiBody({
492
- description: `Payload for ${modelClazzName}`,
493
- schema: { $ref: swagger.getSchemaPath(ModelClazz) },
494
- }),
495
- swagger.ApiCreatedResponse({
496
- description: `${modelClazzName} created successfully.`,
497
- }),
498
- swagger.ApiBadRequestResponse({ description: "Payload validation failed." }),
499
- swagger.ApiUnprocessableEntityResponse({
500
- description: "Repository rejected the provided payload.",
501
- }),
502
- tslib.__param(0, common.Body()),
503
- tslib.__metadata("design:type", Function),
504
- tslib.__metadata("design:paramtypes", [Object]),
505
- tslib.__metadata("design:returntype", Promise)
506
- ], DynamicModelController.prototype, "create", null);
507
- tslib.__decorate([
508
- common.Get(":id"),
509
- swagger.ApiOperation({ summary: `Retrieve a ${modelClazzName} record by id.` }),
510
- swagger.ApiParam({ name: "id", description: "Primary key" }),
511
- swagger.ApiOkResponse({
512
- description: `${modelClazzName} retrieved successfully.`,
513
- }),
514
- swagger.ApiNotFoundResponse({
515
- description: `No ${modelClazzName} record matches the provided identifier.`,
516
- }),
517
- tslib.__param(0, common.Param("id")),
518
- tslib.__metadata("design:type", Function),
519
- tslib.__metadata("design:paramtypes", [String]),
520
- tslib.__metadata("design:returntype", Promise)
521
- ], DynamicModelController.prototype, "read", null);
522
- tslib.__decorate([
523
- common.Put(":id"),
524
- swagger.ApiOperation({
525
- summary: `Replace an existing ${modelClazzName} record with a new payload.`,
526
- }),
527
- swagger.ApiBody({
528
- description: `Payload for replace a existing record of ${modelClazzName}`,
529
- schema: { $ref: swagger.getSchemaPath(ModelClazz) },
530
- }),
531
- swagger.ApiOkResponse({
532
- description: `${ModelClazz} record replaced successfully.`,
533
- }),
534
- swagger.ApiNotFoundResponse({
535
- description: `No ${modelClazzName} record matches the provided identifier.`,
536
- }),
537
- swagger.ApiBadRequestResponse({ description: "Payload validation failed." }),
538
- tslib.__param(0, common.Body()),
539
- tslib.__metadata("design:type", Function),
540
- tslib.__metadata("design:paramtypes", [decoratorValidation.Model]),
541
- tslib.__metadata("design:returntype", Promise)
542
- ], DynamicModelController.prototype, "update", null);
543
- tslib.__decorate([
544
- common.Delete(":id"),
545
- swagger.ApiOperation({ summary: `Delete a ${modelClazzName} record by id.` }),
546
- swagger.ApiParam({
547
- name: "id",
548
- description: `Primary key value of the ${modelClazzName} record to delete.`,
549
- }),
550
- swagger.ApiOkResponse({
551
- description: `${modelClazzName} record deleted successfully.`,
552
- }),
553
- swagger.ApiNotFoundResponse({
554
- description: `No ${modelClazzName} record matches the provided identifier.`,
555
- }),
556
- tslib.__param(0, common.Param("id")),
557
- tslib.__metadata("design:type", Function),
558
- tslib.__metadata("design:paramtypes", [String]),
559
- tslib.__metadata("design:returntype", Promise)
560
- ], DynamicModelController.prototype, "delete", null);
561
- DynamicModelController = tslib.__decorate([
562
- common.Controller(routePath),
563
- swagger.ApiTags(modelClazzName),
564
- swagger.ApiExtraModels(ModelClazz),
565
- tslib.__metadata("design:paramtypes", [exports.RepoFactory])
566
- ], DynamicModelController);
567
- return DynamicModelController;
568
- }
569
- static forRoot(flavour) {
570
- const log = this.log.for(this.forRoot);
571
- log.info(`Generating controllers for flavour...`);
572
- const trackedModels = core.Adapter.models(flavour);
573
- const controllers = trackedModels.map(this.toModelController.bind(this));
574
- log.info(`Generated ${controllers.length} controllers`);
575
- return {
576
- module: DecafModelModule_1,
577
- controllers,
578
- providers: [exports.RepoFactory],
579
- };
580
- }
581
- };
582
- DecafModelModule = DecafModelModule_1 = tslib.__decorate([
583
- common.Module({})
584
- ], DecafModelModule);
585
-
586
- var DecafModule_1;
587
- /**
588
- * @publicApi
589
- */
590
- exports.DecafModule = DecafModule_1 = class DecafModule {
591
- static async forRootAsync(options) {
592
- const { autoControllers } = options;
593
- const adapter = await DecafCoreModule.createAdapter(options);
594
- const flavour = adapter.flavour;
595
- const imports = [DecafCoreModule.forRoot(options)];
596
- if (autoControllers) {
597
- imports.push(DecafModelModule.forRoot(flavour));
598
- }
599
- return {
600
- module: DecafModule_1,
601
- imports: imports,
602
- };
603
- }
604
- };
605
- exports.DecafModule = DecafModule_1 = tslib.__decorate([
606
- common.Module({})
607
- ], exports.DecafModule);
608
-
609
- function repoForModel(model) {
610
- const m = decoratorValidation.Model.get(model);
611
- if (!m)
612
- throw new dbDecorators.InternalError(`Failed to find repository for ${model}`);
613
- const repo = core.Repository.forModel(m);
614
- return repo;
615
- }
616
-
617
- class CorsError extends core.ForbiddenError {
618
- constructor(msg) {
619
- super(msg, CorsError.name);
620
- }
621
- }
622
-
623
- class HttpResponseError {
624
- constructor(request, responseError) {
625
- const status = responseError?.status ?? common.HttpStatus.INTERNAL_SERVER_ERROR;
626
- const message = responseError?.message ?? "Internal Server Error";
627
- const error = (responseError?.error ?? common.HttpStatus[status] ?? "HTTP_EXCEPTION")
628
- .toString()
629
- .toUpperCase();
630
- Object.assign(this, {
631
- status,
632
- message,
633
- error,
634
- timestamp: new Date().toISOString(),
635
- path: request.url,
636
- method: request.method,
637
- });
638
- }
639
- }
640
-
641
- class AuthorizationError extends Error {
642
- constructor(message = "Unauthorized") {
643
- super(message);
644
- this.name = "AuthorizationError";
645
- this.status = 401;
646
- this.code = "UNAUTHORIZED";
647
- Object.setPrototypeOf(this, AuthorizationError.prototype);
648
- }
649
- }
650
- exports.AuthorizationExceptionFilter = class AuthorizationExceptionFilter {
651
- catch(exception, host) {
652
- const ctx = host.switchToHttp();
653
- const request = ctx.getRequest();
654
- const response = ctx.getResponse();
655
- const httpResponseError = new HttpResponseError(request, {
656
- error: "UNAUTHORIZED",
657
- status: common.HttpStatus.UNAUTHORIZED,
658
- message: exception.message,
659
- });
660
- response.status(common.HttpStatus.UNAUTHORIZED).json(httpResponseError);
661
- }
662
- };
663
- exports.AuthorizationExceptionFilter = tslib.__decorate([
664
- common.Catch(AuthorizationError)
665
- ], exports.AuthorizationExceptionFilter);
666
-
667
- class ConflictError extends Error {
668
- constructor(message = "Conflict") {
669
- super(message);
670
- this.name = "ConflictError";
671
- this.status = 409;
672
- this.code = "CONFLICT";
673
- Object.setPrototypeOf(this, ConflictError.prototype);
674
- }
675
- }
676
- exports.ConflictExceptionFilter = class ConflictExceptionFilter {
677
- catch(exception, host) {
678
- const ctx = host.switchToHttp();
679
- const response = ctx.getResponse();
680
- const request = ctx.getRequest();
681
- const httpResponseError = new HttpResponseError(request, {
682
- status: common.HttpStatus.CONFLICT,
683
- message: exception.message,
684
- error: "CONFLICT"
685
- });
686
- response.status(httpResponseError.status).json(httpResponseError);
687
- }
688
- };
689
- exports.ConflictExceptionFilter = tslib.__decorate([
690
- common.Catch(ConflictError)
691
- ], exports.ConflictExceptionFilter);
692
-
693
- exports.GlobalExceptionFilter = class GlobalExceptionFilter {
694
- catch(exception, host) {
695
- const ctx = host.switchToHttp();
696
- const request = ctx.getRequest();
697
- const response = ctx.getResponse();
698
- let status = common.HttpStatus.INTERNAL_SERVER_ERROR;
699
- let message = "Internal Server Error";
700
- let error;
701
- if (exception instanceof common.HttpException) {
702
- const res = exception.getResponse();
703
- status = exception.getStatus();
704
- message = (res?.message || exception.message) ?? message;
705
- error = res?.error ?? exception.name;
706
- }
707
- else if (exception instanceof Error) {
708
- message = exception.message;
709
- error = exception.name;
710
- }
711
- const httpResponseError = new HttpResponseError(request, { status, message, error });
712
- response.status(httpResponseError.status).json(httpResponseError);
713
- }
714
- };
715
- exports.GlobalExceptionFilter = tslib.__decorate([
716
- common.Catch()
717
- ], exports.GlobalExceptionFilter);
718
-
719
- exports.HttpExceptionFilter = class HttpExceptionFilter {
720
- catch(exception, host) {
721
- const ctx = host.switchToHttp();
722
- const response = ctx.getResponse();
723
- const request = ctx.getRequest();
724
- const status = exception.getStatus();
725
- const httpResponseError = new HttpResponseError(request, {
726
- status,
727
- message: exception.message,
728
- error: exception.name
729
- });
730
- response.status(httpResponseError.status).json(httpResponseError);
731
- }
732
- };
733
- exports.HttpExceptionFilter = tslib.__decorate([
734
- common.Catch(common.HttpException)
735
- ], exports.HttpExceptionFilter);
736
-
737
- class NotFoundError extends Error {
738
- constructor(message = "Resource not found") {
739
- super(message);
740
- this.name = "NotFoundError";
741
- this.status = 404;
742
- this.code = "NOT_FOUND";
743
- Object.setPrototypeOf(this, NotFoundError.prototype);
744
- }
745
- }
746
- exports.NotFoundExceptionFilter = class NotFoundExceptionFilter {
747
- catch(exception, host) {
748
- const ctx = host.switchToHttp();
749
- const response = ctx.getResponse();
750
- const request = ctx.getRequest();
751
- const httpResponseError = new HttpResponseError(request, {
752
- status: common.HttpStatus.NOT_FOUND,
753
- message: exception.message,
754
- error: "NOT_FOUND",
755
- });
756
- response.status(httpResponseError.status).json(httpResponseError);
757
- }
758
- };
759
- exports.NotFoundExceptionFilter = tslib.__decorate([
760
- common.Catch(NotFoundError)
761
- ], exports.NotFoundExceptionFilter);
762
-
763
- class ValidationError extends Error {
764
- constructor(message = "Validation failed") {
765
- super(message);
766
- this.name = "ValidationError";
767
- this.status = 422;
768
- this.code = "VALIDATION_ERROR";
769
- Object.setPrototypeOf(this, ValidationError.prototype);
770
- }
771
- }
772
- exports.ValidationExceptionFilter = class ValidationExceptionFilter {
773
- catch(exception, host) {
774
- const ctx = host.switchToHttp();
775
- const response = ctx.getResponse();
776
- const request = ctx.getRequest();
777
- const httpResponseError = new HttpResponseError(request, {
778
- status: common.HttpStatus.UNPROCESSABLE_ENTITY,
779
- message: exception.message,
780
- error: "VALIDATION_ERROR"
781
- });
782
- response.status(httpResponseError.status).json(httpResponseError);
783
- }
784
- };
785
- exports.ValidationExceptionFilter = tslib.__decorate([
786
- common.Catch(ValidationError)
787
- ], exports.ValidationExceptionFilter);
788
-
789
- const SWAGGER_UI_CONSTANTS = {
790
- path: "docs",
791
- auth: {
792
- type: "http",
793
- scheme: "bearer",
794
- bearerFormat: "JWT",
795
- name: "Authorization",
796
- description: "Enter JWT token",
797
- in: "header",
798
- },
799
- topbarBgColor: "#000000",
800
- };
801
-
802
- class SwaggerCustomUI {
803
- // private readonly assetsPath: string = path.join(
804
- // __dirname,
805
- // "..",
806
- // "..",
807
- // "workdocs",
808
- // "assets"
809
- // );
810
- constructor(options) {
811
- this.options = {
812
- ...options,
813
- };
814
- }
815
- customCSS() {
816
- let css = "";
817
- if (this.options.topbarIconPath) {
818
- const img = this.b64(this.options.topbarIconPath);
819
- css += `.topbar-wrapper { content: url('data:image/png;base64,${img}'); width: 200px; height: auto; }\n`;
820
- }
821
- return (css +
822
- `
823
- .topbar-wrapper svg { visibility: hidden; }
824
- .swagger-ui .topbar { background-color: ${this.options.topbarBgColor || SWAGGER_UI_CONSTANTS.topbarBgColor}; }
825
- `);
826
- }
827
- getCustomOptions() {
828
- const favicon = {};
829
- if (this.options.faviconPath) {
830
- favicon["customfavIcon"] = this.b64(this.options.faviconPath, true);
831
- }
832
- return {
833
- customSiteTitle: this.options.title,
834
- ...favicon,
835
- customCss: this.customCSS(),
836
- swaggerOptions: {
837
- persistAuthorization: this.options.persistAuthorization,
838
- },
839
- jsonDocumentUrl: this.options.path
840
- ? `${this.options.path}/spec.json`
841
- : undefined,
842
- yamlDocumentUrl: this.options.path
843
- ? `${this.options.path}/spec.yaml`
844
- : undefined,
845
- };
846
- }
847
- b64(file, img = false) {
848
- const filePath = path__namespace.join(this.options.assetsPath || "", file);
849
- const b64 = fs.readFileSync(filePath, { encoding: "base64" });
850
- return img ? "data:image/png;base64," + b64 : b64;
851
- }
852
- }
853
-
854
- class SwaggerBuilder {
855
- constructor(app, options) {
856
- this.app = app;
857
- this.options = options;
858
- }
859
- createDocument() {
860
- const description = this.options.path
861
- ? this.options.description +
862
- "" +
863
- `<br><br><a href="${this.options.path}/spec.json">OpenAPI JSON Spec</a> | ` +
864
- `<a href="${this.options.path}/spec.yaml">OpenAPI YAML Spec</a>`
865
- : this.options.description;
866
- const config = new swagger.DocumentBuilder()
867
- .setTitle(this.options.title)
868
- .setDescription(description)
869
- .setVersion(this.options.version || "0.0.1")
870
- .addBearerAuth(this.options.auth || SWAGGER_UI_CONSTANTS.auth)
871
- .build();
872
- return swagger.SwaggerModule.createDocument(this.app, config, {
873
- extraModels: this.options.extraModels || [],
874
- });
875
- }
876
- setupSwagger() {
877
- const document = this.createDocument();
878
- const swaggerUI = new SwaggerCustomUI({
879
- title: this.options.title,
880
- path: this.options.path || SWAGGER_UI_CONSTANTS.path,
881
- persistAuthorization: this.options.persistAuthorization ?? true,
882
- assetsPath: this.options.assetsPath,
883
- faviconPath: this.options.faviconFilePath,
884
- topbarIconPath: this.options.topbarIconFilePath,
885
- topbarBgColor: this.options.topbarBgColor,
886
- });
887
- swagger.SwaggerModule.setup(this.options.path || SWAGGER_UI_CONSTANTS.path, this.app, document, {
888
- ...swaggerUI.getCustomOptions(),
889
- });
890
- }
891
- }
892
-
893
- /**
894
- * @description
895
- * A fluent, static bootstrap class for initializing and configuring a NestJS application.
896
- *
897
- * @summary
898
- * The `NestBootstraper` class provides a chainable API for configuring
899
- * a NestJS application instance. It includes built-in methods for enabling
900
- * CORS, Helmet security, Swagger documentation, global pipes, filters,
901
- * interceptors, and starting the server.
902
- *
903
- * This class promotes consistency and reduces repetitive setup code
904
- * across multiple NestJS projects.
905
- *
906
- * @example
907
- * ```ts
908
- * import { NestFactory } from "@nestjs/core";
909
- * import { AppModule } from "./app.module";
910
- * import { MyLogger } from "./MyLogger";
911
- * import { NestBootstraper } from "@decaf-ts/for-nest";
912
- *
913
- * async function bootstrap() {
914
- * const app = await NestFactory.create(AppModule);
915
- *
916
- * await NestBootstraper
917
- * .initialize(app)
918
- * .enableLogger(new MyLogger())
919
- * .enableCors(["http://localhost:4200"])
920
- * .useHelmet()
921
- * .setupSwagger({
922
- * title: "OpenAPI by TradeMark™",
923
- * description: "TradeMark™ API documentation",
924
- * version: "1.0.0",
925
- * path: "api",
926
- * persistAuthorization: true,
927
- * topbarBgColor: "#2C3E50",
928
- * topbarIconPath: "/assets/logo.svg",
929
- * faviconPath: "/assets/favicon.ico"
930
- * })
931
- * .useGlobalFilters()
932
- * .useGlobalPipes(...)
933
- * .useGlobalInterceptors(...)
934
- * .start(3000);
935
- * }
936
- *
937
- * bootstrap();
938
- * ```
939
- * @class
940
- */
941
- class NestBootstraper {
942
- /**
943
- * @description
944
- * Returns the current logger instance, creating a default one if not set.
945
- *
946
- * @summary
947
- * Ensures that a valid `Logger` instance is always available
948
- * for logging bootstrap-related messages.
949
- *
950
- * @return {Logger} The active logger instance.
951
- */
952
- static get logger() {
953
- if (!this._logger) {
954
- // fallback
955
- this._logger = new common.Logger("NestBootstrap");
956
- }
957
- return this._logger;
958
- }
959
- /**
960
- * @description
961
- * Initializes the bootstrapper with a given NestJS application.
962
- *
963
- * @summary
964
- * Binds the provided NestJS app instance to the bootstrapper, enabling
965
- * chained configuration methods.
966
- *
967
- * @param {INestApplication} app - The NestJS application instance to initialize.
968
- * @return {typeof NestBootstraper} Returns the class for chaining configuration methods.
969
- */
970
- static initialize(app) {
971
- this.app = app;
972
- return this;
973
- }
974
- /**
975
- * @description
976
- * Enables or replaces the global logger for the NestJS application.
977
- *
978
- * @summary
979
- * If a custom logger is provided, it replaces the default logger. Otherwise,
980
- * a new logger named `"NestBootstrap"` is used. This logger is also registered
981
- * with the NestJS application.
982
- *
983
- * @param {Logger} [customLogger] - Optional custom logger instance.
984
- * @return {typeof NestBootstraper} Returns the class for chaining.
985
- */
986
- static enableLogger(customLogger) {
987
- this._logger = customLogger || new common.Logger("NestBootstrap");
988
- this.app.useLogger(this._logger);
989
- return this;
990
- }
991
- /**
992
- * @description
993
- * Enables Cross-Origin Resource Sharing (CORS) for the application.
994
- *
995
- * @summary
996
- * Allows defining either a wildcard origin (`"*"`) or a list of allowed origins.
997
- * Automatically accepts local development requests and those without origin headers.
998
- * Throws a `CorsError` for unauthorized origins.
999
- *
1000
- * @param {'*' | string[]} [origins=[]] - List of allowed origins or `"*"` to allow all.
1001
- * @param {string[]} [allowMethods=['GET', 'POST', 'PUT', 'DELETE']] - Allowed HTTP methods.
1002
- * @return {typeof NestBootstraper} Returns the class for chaining configuration.
1003
- *
1004
- */
1005
- static enableCors(origins = [], allowMethods = ["GET", "POST", "PUT", "DELETE"]) {
1006
- const allowedOrigins = origins === "*" ? "*" : origins.map((o) => o.trim().toLowerCase());
1007
- const corsOptions = {
1008
- origin: (origin, callback) => {
1009
- // Allow request without origin...
1010
- if (!origin)
1011
- return callback(null, true);
1012
- if (allowedOrigins === "*" ||
1013
- (Array.isArray(allowedOrigins) &&
1014
- allowedOrigins.includes(origin.toLowerCase()))) {
1015
- return callback(null, true);
1016
- }
1017
- callback(new CorsError(`Origin ${origin} not allowed`));
1018
- },
1019
- credentials: true,
1020
- methods: allowMethods.join(","),
1021
- };
1022
- this.app.enableCors(corsOptions);
1023
- return this;
1024
- }
1025
- /**
1026
- * @description
1027
- * Applies the Helmet middleware for enhanced security.
1028
- *
1029
- * @summary
1030
- * Dynamically loads the `helmet` package if available and registers it
1031
- * as middleware to improve HTTP header security. If not installed, logs a warning
1032
- * and continues execution without throwing errors.
1033
- *
1034
- * @param {Record<string, any>} [options] - Optional configuration passed to Helmet.
1035
- * @return {typeof NestBootstraper} Returns the class for chaining configuration.
1036
- */
1037
- static useHelmet(options) {
1038
- try {
1039
- // eslint-disable-next-line @typescript-eslint/no-require-imports
1040
- const helmet = require("helmet"); // Dynamic import to avoid hard dependency
1041
- this.app.use(helmet(options));
1042
- this.logger.log("Helmet middleware enabled successfully.");
1043
- }
1044
- catch (e) {
1045
- this.logger.warn("Helmet not installed. Skipping middleware.");
1046
- }
1047
- return this;
1048
- }
1049
- /**
1050
- * @description
1051
- * Configures and initializes Swagger UI for API documentation.
1052
- *
1053
- * @summary
1054
- * Uses the `SwaggerBuilder` utility to configure API documentation
1055
- * with detailed customization for title, version, paths, and colors.
1056
- * Swagger is automatically exposed at the configured path.
1057
- *
1058
- * @param {SwaggerSetupOptions} options - Swagger configuration options.
1059
- * @return {typeof NestBootstraper} Returns the class for chaining configuration.
1060
- */
1061
- static setupSwagger(options) {
1062
- const swagger = new SwaggerBuilder(this.app, {
1063
- title: options.title,
1064
- description: options.description,
1065
- version: options.version,
1066
- path: options.path || "api",
1067
- persistAuthorization: options.persistAuthorization ?? true,
1068
- assetsPath: options.assetsPath,
1069
- faviconFilePath: options.faviconPath,
1070
- topbarIconFilePath: options.topbarIconPath,
1071
- topbarBgColor: options.topbarBgColor,
1072
- });
1073
- swagger.setupSwagger();
1074
- return this;
1075
- }
1076
- /**
1077
- * @description
1078
- * Registers one or more global validation pipes.
1079
- *
1080
- * @summary
1081
- * Enables request payload validation and transformation globally across
1082
- * the entire NestJS application. Multiple pipes can be chained together
1083
- * for modular input validation.
1084
- *
1085
- * @param {...PipeTransform[]} pipes - Pipe instances to register globally.
1086
- * @return {typeof NestBootstraper} Returns the class for chaining.
1087
- */
1088
- static useGlobalPipes(...pipes) {
1089
- if (pipes.length > 0)
1090
- this.app.useGlobalPipes(...pipes);
1091
- return this;
1092
- }
1093
- /**
1094
- * @description
1095
- * Registers one or more global exception filters.
1096
- *
1097
- * @summary
1098
- * If no filters are provided, it automatically registers a default
1099
- * set of standard exception filters for common error types like
1100
- * `HttpException`, `ValidationException`, `ConflictException`, and others.
1101
- *
1102
- * @param {...ExceptionFilter[]} filters - Optional filters to apply globally.
1103
- * @return {typeof NestBootstraper} Returns the class for chaining configuration.
1104
- */
1105
- static useGlobalFilters(...filters) {
1106
- const defaultFilters = [
1107
- new exports.HttpExceptionFilter(),
1108
- new exports.ValidationExceptionFilter(),
1109
- new exports.NotFoundExceptionFilter(),
1110
- new exports.ConflictExceptionFilter(),
1111
- new exports.AuthorizationExceptionFilter(),
1112
- new exports.GlobalExceptionFilter(),
1113
- ];
1114
- this.app.useGlobalFilters(...(filters.length > 0 ? filters : defaultFilters));
1115
- return this;
1116
- }
1117
- /**
1118
- * @description
1119
- * Registers global interceptors for request and response transformation.
1120
- *
1121
- * @summary
1122
- * Interceptors allow advanced request/response manipulation such as
1123
- * serialization, logging, or transformation. Multiple interceptors
1124
- * can be added for modular configuration.
1125
- *
1126
- * @param {...NestInterceptor[]} interceptors - Interceptor instances to register.
1127
- * @return {typeof NestBootstraper} Returns the class for chaining configuration.
1128
- */
1129
- static useGlobalInterceptors(...interceptors) {
1130
- if (interceptors.length > 0)
1131
- this.app.useGlobalInterceptors(...interceptors);
1132
- return this;
1133
- }
1134
- /**
1135
- * @description
1136
- * Starts the NestJS application and binds it to the given port and host.
1137
- *
1138
- * @summary
1139
- * Listens on the specified port and optionally a host. Once started,
1140
- * logs the application URL for easy access. The startup process resolves
1141
- * once the application is successfully running.
1142
- *
1143
- * @param {number} [port=3000] - Port number to listen on.
1144
- * @param {string} [host] - Optional host or IP address to bind to.
1145
- * @param {boolean} [log=true] - Whether to log the application URL upon startup.
1146
- * @return {Promise<void>} Resolves once the application starts successfully.
1147
- */
1148
- static async start(port = Number(process.env.PORT) || 3000, host = undefined, log = true) {
1149
- this.app.listen(port, host).then(async () => {
1150
- if (log) {
1151
- const url = await this.app.getUrl();
1152
- this.logger.log(`🚀 Application is running at: ${url}`);
1153
- }
1154
- });
1155
- }
1156
- }
1157
-
1158
- /**
1159
- * @module for-nest
1160
- * @description This module serves as the main entry point for the ts-workspace library. It aggregates and exports
1161
- * functionality from various submodules and utilities within the project.
1162
- *
1163
- * The module includes:
1164
- * 1. Utility functions and types from the "./utils" directory:
1165
- * - These likely contain helper functions, common types, and shared functionality used throughout the project.
1166
- * - May include operations for data manipulation, type checking, or other general-purpose utilities.
1167
- *
1168
- * 2. A namespace and related types from the "./namespace" directory:
1169
- * - This could contain domain-specific code or a collection of related functionality.
1170
- * - Might include interfaces, types, or classes that represent core concepts in the library.
1171
- *
1172
- * 3. A VERSION constant:
1173
- * - Represents the current version of the module.
1174
- * - Useful for version checking and compatibility purposes.
1175
- *
1176
- * This structure provides a clean and organized export of the module's functionality, allowing consumers
1177
- * to easily import and use specific parts of the library as needed.
1178
- */
1179
- /**
1180
- * Represents the current version of the ts-workspace module.
1181
- * The actual version number is replaced during the build process.
1182
- * @constant
1183
- * @type {string}
1184
- */
1185
- const VERSION = "0.0.5";
1186
- const PACKAGE_NAME = "##PACKAGE_NAME##";
1187
- decoration.Metadata.registerLibrary(PACKAGE_NAME, VERSION);
1188
-
1189
- exports.ApiProperty = ApiProperty;
1190
- exports.ApiPropertyOptional = ApiPropertyOptional;
1191
- exports.ApiResponseProperty = ApiResponseProperty;
1192
- exports.AuthorizationError = AuthorizationError;
1193
- exports.ConflictError = ConflictError;
1194
- exports.CorsError = CorsError;
1195
- exports.DECAF_ADAPTER_ID = DECAF_ADAPTER_ID;
1196
- exports.DECAF_MODULE_OPTIONS = DECAF_MODULE_OPTIONS;
1197
- exports.NestBootstraper = NestBootstraper;
1198
- exports.NotFoundError = NotFoundError;
1199
- exports.PACKAGE_NAME = PACKAGE_NAME;
1200
- exports.SwaggerBuilder = SwaggerBuilder;
1201
- exports.VERSION = VERSION;
1202
- exports.ValidationError = ValidationError;
1203
- exports.createApiPropertyDecorator = createApiPropertyDecorator;
1204
- exports.createClassDecorator = createClassDecorator;
1205
- exports.createMethodDecorator = createMethodDecorator;
1206
- exports.createMixedDecorator = createMixedDecorator;
1207
- exports.createParamDecorator = createParamDecorator;
1208
- exports.createPropertyDecorator = createPropertyDecorator;
1209
- exports.getTypeIsArrayTuple = getTypeIsArrayTuple;
1210
- exports.repoForModel = repoForModel;
1211
-
1212
- }));
1213
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9yLW5lc3QuY2pzIiwic291cmNlcyI6WyIuLi9zcmMvZGVjb3JhdG9ycy9oZWxwZXJzLnRzIiwiLi4vc3JjL2RlY29yYXRvcnMvQXBpUHJvcGVydHkudHMiLCIuLi9zcmMvZGVjb3JhdGlvbi50cyIsIi4uL3NyYy9jb25zdGFudHMudHMiLCIuLi9zcmMvY29yZS1tb2R1bGUudHMiLCIuLi9zcmMvUmVwb0ZhY3RvcnkudHMiLCIuLi9zcmMvbW9kZWwtbW9kdWxlLnRzIiwiLi4vc3JjL21vZHVsZS50cyIsIi4uL3NyYy91dGlscy50cyIsIi4uL3NyYy9mYWN0b3J5L2Vycm9ycy9jb3JzLnRzIiwiLi4vc3JjL2ZhY3RvcnkvZXhjZXB0aW9ucy9IdHRwUmVzcG9uc2VFcnJvci50cyIsIi4uL3NyYy9mYWN0b3J5L2V4Y2VwdGlvbnMvQXV0aG9yaXphdGlvbkV4Y2VwdGlvbkZpbHRlci50cyIsIi4uL3NyYy9mYWN0b3J5L2V4Y2VwdGlvbnMvQ29uZmxpY3RFeGNlcHRpb25GaWx0ZXIudHMiLCIuLi9zcmMvZmFjdG9yeS9leGNlcHRpb25zL0dsb2JhbEV4Y2VwdGlvbkZpbHRlci50cyIsIi4uL3NyYy9mYWN0b3J5L2V4Y2VwdGlvbnMvSHR0cEV4Y2VwdGlvbkZpbHRlci50cyIsIi4uL3NyYy9mYWN0b3J5L2V4Y2VwdGlvbnMvTm90Rm91bmRFeGNlcHRpb25GaWx0ZXIudHMiLCIuLi9zcmMvZmFjdG9yeS9leGNlcHRpb25zL1ZhbGlkYXRpb25FeGNlcHRpb25GaWx0ZXIudHMiLCIuLi9zcmMvZmFjdG9yeS9vcGVuYXBpL2NvbnN0YW50cy50cyIsIi4uL3NyYy9mYWN0b3J5L29wZW5hcGkvU3dhZ2dlckN1c3RvbVVJLnRzIiwiLi4vc3JjL2ZhY3Rvcnkvb3BlbmFwaS9Td2FnZ2VyQnVpbGRlci50cyIsIi4uL3NyYy9mYWN0b3J5L05lc3RCb290c3RyYXBlci50cyIsIi4uL3NyYy9pbmRleC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW5zYWZlLWZ1bmN0aW9uLXR5cGUgKi9cblxuaW1wb3J0IHsgTUVUSE9EX01FVEFEQVRBIH0gZnJvbSBcIkBuZXN0anMvY29tbW9uL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgaXNDb25zdHJ1Y3RvciB9IGZyb20gXCJAbmVzdGpzL2NvbW1vbi91dGlscy9zaGFyZWQudXRpbHNcIjtcbmltcG9ydCB7IGlzQXJyYXksIGlzVW5kZWZpbmVkLCBuZWdhdGUsIHBpY2tCeSB9IGZyb20gXCJsb2Rhc2hcIjtcbmltcG9ydCB7IE1FVEFEQVRBX0ZBQ1RPUllfTkFNRSB9IGZyb20gXCJAbmVzdGpzL3N3YWdnZXIvZGlzdC9wbHVnaW4vcGx1Z2luLWNvbnN0YW50c1wiO1xuaW1wb3J0IHsgREVDT1JBVE9SUyB9IGZyb20gXCJAbmVzdGpzL3N3YWdnZXIvZGlzdC9jb25zdGFudHNcIjtcblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZU1ldGhvZERlY29yYXRvcjxUID0gYW55PihcbiAgbWV0YWtleTogc3RyaW5nLFxuICBtZXRhZGF0YTogVCxcbiAgeyBvdmVycmlkZUV4aXN0aW5nIH0gPSB7IG92ZXJyaWRlRXhpc3Rpbmc6IHRydWUgfVxuKTogTWV0aG9kRGVjb3JhdG9yIHtcbiAgcmV0dXJuIChcbiAgICB0YXJnZXQ6IG9iamVjdCxcbiAgICBrZXk6IHN0cmluZyB8IHN5bWJvbCxcbiAgICBkZXNjcmlwdG9yOiBQcm9wZXJ0eURlc2NyaXB0b3JcbiAgKSA9PiB7XG4gICAgaWYgKHR5cGVvZiBtZXRhZGF0YSA9PT0gXCJvYmplY3RcIikge1xuICAgICAgY29uc3QgcHJldlZhbHVlID0gUmVmbGVjdC5nZXRNZXRhZGF0YShtZXRha2V5LCBkZXNjcmlwdG9yLnZhbHVlKTtcbiAgICAgIGlmIChwcmV2VmFsdWUgJiYgIW92ZXJyaWRlRXhpc3RpbmcpIHtcbiAgICAgICAgcmV0dXJuIGRlc2NyaXB0b3I7XG4gICAgICB9XG4gICAgICBSZWZsZWN0LmRlZmluZU1ldGFkYXRhKFxuICAgICAgICBtZXRha2V5LFxuICAgICAgICB7IC4uLnByZXZWYWx1ZSwgLi4ubWV0YWRhdGEgfSxcbiAgICAgICAgZGVzY3JpcHRvci52YWx1ZVxuICAgICAgKTtcbiAgICAgIHJldHVybiBkZXNjcmlwdG9yO1xuICAgIH1cbiAgICBSZWZsZWN0LmRlZmluZU1ldGFkYXRhKG1ldGFrZXksIG1ldGFkYXRhLCBkZXNjcmlwdG9yLnZhbHVlKTtcbiAgICByZXR1cm4gZGVzY3JpcHRvcjtcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUNsYXNzRGVjb3JhdG9yPFQgZXh0ZW5kcyBBcnJheTxhbnk+ID0gYW55PihcbiAgbWV0YWtleTogc3RyaW5nLFxuICBtZXRhZGF0YTogVCA9IFtdIGFzIHVua25vd24gYXMgVFxuKTogQ2xhc3NEZWNvcmF0b3Ige1xuICByZXR1cm4gKHRhcmdldCkgPT4ge1xuICAgIGNvbnN0IHByZXZWYWx1ZSA9IFJlZmxlY3QuZ2V0TWV0YWRhdGEobWV0YWtleSwgdGFyZ2V0KSB8fCBbXTtcbiAgICBSZWZsZWN0LmRlZmluZU1ldGFkYXRhKG1ldGFrZXksIFsuLi5wcmV2VmFsdWUsIC4uLm1ldGFkYXRhXSwgdGFyZ2V0KTtcbiAgICByZXR1cm4gdGFyZ2V0O1xuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlUHJvcGVydHlEZWNvcmF0b3I8VCBleHRlbmRzIFJlY29yZDxzdHJpbmcsIGFueT4gPSBhbnk+KFxuICBtZXRha2V5OiBzdHJpbmcsXG4gIG1ldGFkYXRhOiBULFxuICBvdmVycmlkZUV4aXN0aW5nID0gdHJ1ZVxuKTogUHJvcGVydHlEZWNvcmF0b3Ige1xuICByZXR1cm4gKHRhcmdldDogb2JqZWN0LCBwcm9wZXJ0eUtleT86IGFueSkgPT4ge1xuICAgIGNvbnN0IHByb3BlcnRpZXMgPVxuICAgICAgUmVmbGVjdC5nZXRNZXRhZGF0YShERUNPUkFUT1JTLkFQSV9NT0RFTF9QUk9QRVJUSUVTX0FSUkFZLCB0YXJnZXQpIHx8IFtdO1xuXG4gICAgY29uc3Qga2V5ID0gYDoke3Byb3BlcnR5S2V5fWA7XG4gICAgaWYgKCFwcm9wZXJ0aWVzLmluY2x1ZGVzKGtleSkpIHtcbiAgICAgIFJlZmxlY3QuZGVmaW5lTWV0YWRhdGEoXG4gICAgICAgIERFQ09SQVRPUlMuQVBJX01PREVMX1BST1BFUlRJRVNfQVJSQVksXG4gICAgICAgIFsuLi5wcm9wZXJ0aWVzLCBgOiR7cHJvcGVydHlLZXl9YF0sXG4gICAgICAgIHRhcmdldFxuICAgICAgKTtcbiAgICB9XG4gICAgY29uc3QgZXhpc3RpbmdNZXRhZGF0YSA9IFJlZmxlY3QuZ2V0TWV0YWRhdGEobWV0YWtleSwgdGFyZ2V0LCBwcm9wZXJ0eUtleSk7XG4gICAgaWYgKGV4aXN0aW5nTWV0YWRhdGEpIHtcbiAgICAgIGNvbnN0IG5ld01ldGFkYXRhID0gcGlja0J5KG1ldGFkYXRhLCBuZWdhdGUoaXNVbmRlZmluZWQpKTtcbiAgICAgIGNvbnN0IG1ldGFkYXRhVG9TYXZlID0gb3ZlcnJpZGVFeGlzdGluZ1xuICAgICAgICA/IHtcbiAgICAgICAgICAgIC4uLmV4aXN0aW5nTWV0YWRhdGEsXG4gICAgICAgICAgICAuLi5uZXdNZXRhZGF0YSxcbiAgICAgICAgICB9XG4gICAgICAgIDoge1xuICAgICAgICAgICAgLi4ubmV3TWV0YWRhdGEsXG4gICAgICAgICAgICAuLi5leGlzdGluZ01ldGFkYXRhLFxuICAgICAgICAgIH07XG5cbiAgICAgIFJlZmxlY3QuZGVmaW5lTWV0YWRhdGEobWV0YWtleSwgbWV0YWRhdGFUb1NhdmUsIHRhcmdldCwgcHJvcGVydHlLZXkpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCB0eXBlID1cbiAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvciBuZXN0IGpzIG92ZXJyaWRlXG4gICAgICAgIHRhcmdldD8uY29uc3RydWN0b3I/LltNRVRBREFUQV9GQUNUT1JZX05BTUVdPy4oKVtwcm9wZXJ0eUtleV0/LnR5cGUgPz9cbiAgICAgICAgUmVmbGVjdC5nZXRNZXRhZGF0YShcImRlc2lnbjp0eXBlXCIsIHRhcmdldCwgcHJvcGVydHlLZXkpO1xuXG4gICAgICBSZWZsZWN0LmRlZmluZU1ldGFkYXRhKFxuICAgICAgICBtZXRha2V5LFxuICAgICAgICB7XG4gICAgICAgICAgdHlwZSxcbiAgICAgICAgICAuLi5waWNrQnkobWV0YWRhdGEsIG5lZ2F0ZShpc1VuZGVmaW5lZCkpLFxuICAgICAgICB9LFxuICAgICAgICB0YXJnZXQsXG4gICAgICAgIHByb3BlcnR5S2V5XG4gICAgICApO1xuICAgIH1cbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZU1peGVkRGVjb3JhdG9yPFQgPSBhbnk+KFxuICBtZXRha2V5OiBzdHJpbmcsXG4gIG1ldGFkYXRhOiBUXG4pOiBNZXRob2REZWNvcmF0b3IgJiBDbGFzc0RlY29yYXRvciB7XG4gIHJldHVybiAoXG4gICAgdGFyZ2V0OiBvYmplY3QsXG4gICAga2V5Pzogc3RyaW5nIHwgc3ltYm9sLFxuICAgIGRlc2NyaXB0b3I/OiBUeXBlZFByb3BlcnR5RGVzY3JpcHRvcjxhbnk+XG4gICk6IGFueSA9PiB7XG4gICAgaWYgKGRlc2NyaXB0b3IpIHtcbiAgICAgIGxldCBtZXRhZGF0YXM6IGFueTtcbiAgICAgIGlmIChBcnJheS5pc0FycmF5KG1ldGFkYXRhKSkge1xuICAgICAgICBjb25zdCBwcmV2aW91c01ldGFkYXRhID1cbiAgICAgICAgICBSZWZsZWN0LmdldE1ldGFkYXRhKG1ldGFrZXksIGRlc2NyaXB0b3IudmFsdWUpIHx8IFtdO1xuICAgICAgICBtZXRhZGF0YXMgPSBbLi4ucHJldmlvdXNNZXRhZGF0YSwgLi4ubWV0YWRhdGFdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgcHJldmlvdXNNZXRhZGF0YSA9XG4gICAgICAgICAgUmVmbGVjdC5nZXRNZXRhZGF0YShtZXRha2V5LCBkZXNjcmlwdG9yLnZhbHVlKSB8fCB7fTtcbiAgICAgICAgbWV0YWRhdGFzID0geyAuLi5wcmV2aW91c01ldGFkYXRhLCAuLi5tZXRhZGF0YSB9O1xuICAgICAgfVxuICAgICAgUmVmbGVjdC5kZWZpbmVNZXRhZGF0YShtZXRha2V5LCBtZXRhZGF0YXMsIGRlc2NyaXB0b3IudmFsdWUpO1xuICAgICAgcmV0dXJuIGRlc2NyaXB0b3I7XG4gICAgfVxuXG4gICAgbGV0IG1ldGFkYXRhczogYW55O1xuICAgIGlmIChBcnJheS5pc0FycmF5KG1ldGFkYXRhKSkge1xuICAgICAgY29uc3QgcHJldmlvdXNNZXRhZGF0YSA9IFJlZmxlY3QuZ2V0TWV0YWRhdGEobWV0YWtleSwgdGFyZ2V0KSB8fCBbXTtcbiAgICAgIG1ldGFkYXRhcyA9IFsuLi5wcmV2aW91c01ldGFkYXRhLCAuLi5tZXRhZGF0YV07XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IHByZXZpb3VzTWV0YWRhdGEgPSBSZWZsZWN0LmdldE1ldGFkYXRhKG1ldGFrZXksIHRhcmdldCkgfHwge307XG4gICAgICBtZXRhZGF0YXMgPSBPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oe30sIHByZXZpb3VzTWV0YWRhdGEpLCBtZXRhZGF0YSk7XG4gICAgfVxuICAgIFJlZmxlY3QuZGVmaW5lTWV0YWRhdGEobWV0YWtleSwgbWV0YWRhdGFzLCB0YXJnZXQpO1xuICAgIHJldHVybiB0YXJnZXQ7XG4gIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVQYXJhbURlY29yYXRvcjxUIGV4dGVuZHMgUmVjb3JkPHN0cmluZywgYW55PiA9IGFueT4oXG4gIG1ldGFkYXRhOiBULFxuICBpbml0aWFsOiBQYXJ0aWFsPFQ+XG4pOiBNZXRob2REZWNvcmF0b3IgJiBDbGFzc0RlY29yYXRvciB7XG4gIHJldHVybiAoXG4gICAgdGFyZ2V0OiBvYmplY3QgfCBGdW5jdGlvbixcbiAgICBrZXk/OiBzdHJpbmcgfCBzeW1ib2wsXG4gICAgZGVzY3JpcHRvcj86IFR5cGVkUHJvcGVydHlEZXNjcmlwdG9yPGFueT5cbiAgKTogYW55ID0+IHtcbiAgICBjb25zdCBwYXJhbU9wdGlvbnMgPSB7XG4gICAgICAuLi5pbml0aWFsLFxuICAgICAgLi4ucGlja0J5KG1ldGFkYXRhLCBuZWdhdGUoaXNVbmRlZmluZWQpKSxcbiAgICB9O1xuXG4gICAgaWYgKGRlc2NyaXB0b3IpIHtcbiAgICAgIGNvbnN0IHBhcmFtZXRlcnMgPVxuICAgICAgICBSZWZsZWN0LmdldE1ldGFkYXRhKERFQ09SQVRPUlMuQVBJX1BBUkFNRVRFUlMsIGRlc2NyaXB0b3IudmFsdWUpIHx8IFtdO1xuICAgICAgUmVmbGVjdC5kZWZpbmVNZXRhZGF0YShcbiAgICAgICAgREVDT1JBVE9SUy5BUElfUEFSQU1FVEVSUyxcbiAgICAgICAgWy4uLnBhcmFtZXRlcnMsIHBhcmFtT3B0aW9uc10sXG4gICAgICAgIGRlc2NyaXB0b3IudmFsdWVcbiAgICAgICk7XG4gICAgICByZXR1cm4gZGVzY3JpcHRvcjtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIHRhcmdldCA9PT0gXCJvYmplY3RcIikge1xuICAgICAgcmV0dXJuIHRhcmdldDtcbiAgICB9XG5cbiAgICBjb25zdCBwcm9wZXJ0eUtleXMgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyh0YXJnZXQucHJvdG90eXBlKTtcblxuICAgIGZvciAoY29uc3QgcHJvcGVydHlLZXkgb2YgcHJvcGVydHlLZXlzKSB7XG4gICAgICBpZiAoaXNDb25zdHJ1Y3Rvcihwcm9wZXJ0eUtleSkpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG1ldGhvZERlc2NyaXB0b3IgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKFxuICAgICAgICB0YXJnZXQucHJvdG90eXBlLFxuICAgICAgICBwcm9wZXJ0eUtleVxuICAgICAgKTtcblxuICAgICAgaWYgKCFtZXRob2REZXNjcmlwdG9yKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBpc0FwaU1ldGhvZCA9IFJlZmxlY3QuaGFzTWV0YWRhdGEoXG4gICAgICAgIE1FVEhPRF9NRVRBREFUQSxcbiAgICAgICAgbWV0aG9kRGVzY3JpcHRvci52YWx1ZVxuICAgICAgKTtcblxuICAgICAgaWYgKCFpc0FwaU1ldGhvZCkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgcGFyYW1ldGVycyA9XG4gICAgICAgIFJlZmxlY3QuZ2V0TWV0YWRhdGEoXG4gICAgICAgICAgREVDT1JBVE9SUy5BUElfUEFSQU1FVEVSUyxcbiAgICAgICAgICBtZXRob2REZXNjcmlwdG9yLnZhbHVlXG4gICAgICAgICkgfHwgW107XG4gICAgICBSZWZsZWN0LmRlZmluZU1ldGFkYXRhKFxuICAgICAgICBERUNPUkFUT1JTLkFQSV9QQVJBTUVURVJTLFxuICAgICAgICBbLi4ucGFyYW1ldGVycywgcGFyYW1PcHRpb25zXSxcbiAgICAgICAgbWV0aG9kRGVzY3JpcHRvci52YWx1ZVxuICAgICAgKTtcbiAgICB9XG4gIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRUeXBlSXNBcnJheVR1cGxlKFxuICBpbnB1dDogRnVuY3Rpb24gfCBbRnVuY3Rpb25dIHwgdW5kZWZpbmVkIHwgc3RyaW5nIHwgUmVjb3JkPHN0cmluZywgYW55PixcbiAgaXNBcnJheUZsYWc6IGJvb2xlYW5cbik6IFtGdW5jdGlvbiB8IHVuZGVmaW5lZCwgYm9vbGVhbl0ge1xuICBpZiAoIWlucHV0KSB7XG4gICAgcmV0dXJuIFtpbnB1dCBhcyB1bmRlZmluZWQsIGlzQXJyYXlGbGFnXTtcbiAgfVxuICBpZiAoaXNBcnJheUZsYWcpIHtcbiAgICByZXR1cm4gW2lucHV0IGFzIEZ1bmN0aW9uLCBpc0FycmF5RmxhZ107XG4gIH1cbiAgY29uc3QgaXNJbnB1dEFycmF5ID0gaXNBcnJheShpbnB1dCk7XG4gIGNvbnN0IHR5cGUgPSBpc0lucHV0QXJyYXkgPyBpbnB1dFswXSA6IGlucHV0O1xuICByZXR1cm4gW3R5cGUgYXMgRnVuY3Rpb24sIGlzSW5wdXRBcnJheV07XG59XG4iLCJpbXBvcnQgeyBUeXBlIH0gZnJvbSBcIkBuZXN0anMvY29tbW9uXCI7XG5pbXBvcnQge1xuICBFbnVtQWxsb3dlZFR5cGVzLFxuICBTY2hlbWFPYmplY3RNZXRhZGF0YSxcbn0gZnJvbSBcIkBuZXN0anMvc3dhZ2dlci9kaXN0L2ludGVyZmFjZXMvc2NoZW1hLW9iamVjdC1tZXRhZGF0YS5pbnRlcmZhY2VcIjtcbmltcG9ydCB7IEVudW1TY2hlbWFBdHRyaWJ1dGVzIH0gZnJvbSBcIkBuZXN0anMvc3dhZ2dlci9kaXN0L2ludGVyZmFjZXMvZW51bS1zY2hlbWEtYXR0cmlidXRlcy5pbnRlcmZhY2VcIjtcbmltcG9ydCB7IGdldFR5cGVJc0FycmF5VHVwbGUgfSBmcm9tIFwiQG5lc3Rqcy9zd2FnZ2VyL2Rpc3QvZGVjb3JhdG9ycy9oZWxwZXJzXCI7XG5pbXBvcnQge1xuICBnZXRFbnVtVHlwZSxcbiAgZ2V0RW51bVZhbHVlcyxcbn0gZnJvbSBcIkBuZXN0anMvc3dhZ2dlci9kaXN0L3V0aWxzL2VudW0udXRpbHNcIjtcbmltcG9ydCB7IERFQ09SQVRPUlMgfSBmcm9tIFwiQG5lc3Rqcy9zd2FnZ2VyL2Rpc3QvY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBjcmVhdGVQcm9wZXJ0eURlY29yYXRvciB9IGZyb20gXCIuL2hlbHBlcnNcIjtcblxuZXhwb3J0IHR5cGUgQXBpUHJvcGVydHlDb21tb25PcHRpb25zID0gU2NoZW1hT2JqZWN0TWV0YWRhdGEgJiB7XG4gIFwieC1lbnVtTmFtZXNcIj86IHN0cmluZ1tdO1xuICAvKipcbiAgICogTGF6eSBmdW5jdGlvbiByZXR1cm5pbmcgdGhlIHR5cGUgZm9yIHdoaWNoIHRoZSBkZWNvcmF0ZWQgcHJvcGVydHlcbiAgICogY2FuIGJlIHVzZWQgYXMgYW4gaWRcbiAgICpcbiAgICogVXNlIHRvZ2V0aGVyIHdpdGggQEFwaURlZmF1bHRHZXR0ZXIgb24gdGhlIGdldHRlciByb3V0ZSBvZiB0aGUgdHlwZVxuICAgKiB0byBnZW5lcmF0ZSBPcGVuQVBJIGxpbmsgb2JqZWN0c1xuICAgKlxuICAgKiBAc2VlIFtTd2FnZ2VyIGxpbmsgb2JqZWN0c10oaHR0cHM6Ly9zd2FnZ2VyLmlvL2RvY3Mvc3BlY2lmaWNhdGlvbi9saW5rcy8pXG4gICAqL1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVuc2FmZS1mdW5jdGlvbi10eXBlXG4gIGxpbms/OiAoKSA9PiBUeXBlPHVua25vd24+IHwgRnVuY3Rpb247XG59O1xuXG5leHBvcnQgdHlwZSBBcGlQcm9wZXJ0eU9wdGlvbnMgPVxuICB8IEFwaVByb3BlcnR5Q29tbW9uT3B0aW9uc1xuICB8IChBcGlQcm9wZXJ0eUNvbW1vbk9wdGlvbnMgJiB7XG4gICAgICBlbnVtTmFtZTogc3RyaW5nO1xuICAgICAgZW51bVNjaGVtYT86IEVudW1TY2hlbWFBdHRyaWJ1dGVzO1xuICAgIH0pO1xuXG5jb25zdCBpc0VudW1BcnJheSA9IChcbiAgb3B0czogQXBpUHJvcGVydHlPcHRpb25zXG4pOiBvcHRzIGlzIHtcbiAgaXNBcnJheTogdHJ1ZTtcbiAgZW51bTogRW51bUFsbG93ZWRUeXBlcztcbiAgdHlwZTogYW55O1xuICBpdGVtczogYW55O1xufSA9PiAob3B0cy5pc0FycmF5ICYmIFwiZW51bVwiIGluIG9wdHMgJiYgb3B0cy5lbnVtICE9PSB1bmRlZmluZWQpIGFzIGJvb2xlYW47XG5cbi8qKlxuICogQHB1YmxpY0FwaVxuICovXG5leHBvcnQgZnVuY3Rpb24gQXBpUHJvcGVydHkoXG4gIG9wdGlvbnM6IEFwaVByb3BlcnR5T3B0aW9ucyA9IHt9XG4pOiBQcm9wZXJ0eURlY29yYXRvciB7XG4gIHJldHVybiBjcmVhdGVBcGlQcm9wZXJ0eURlY29yYXRvcihvcHRpb25zKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUFwaVByb3BlcnR5RGVjb3JhdG9yKFxuICBvcHRpb25zOiBBcGlQcm9wZXJ0eU9wdGlvbnMgPSB7fSxcbiAgb3ZlcnJpZGVFeGlzdGluZyA9IHRydWVcbik6IFByb3BlcnR5RGVjb3JhdG9yIHtcbiAgY29uc3QgW3R5cGUsIGlzQXJyYXldID0gZ2V0VHlwZUlzQXJyYXlUdXBsZShcbiAgICBvcHRpb25zLnR5cGUsXG4gICAgb3B0aW9ucy5pc0FycmF5IGFzIGJvb2xlYW5cbiAgKTtcbiAgb3B0aW9ucyA9IHtcbiAgICAuLi5vcHRpb25zLFxuICAgIHR5cGUsXG4gICAgaXNBcnJheSxcbiAgfSBhcyBBcGlQcm9wZXJ0eU9wdGlvbnM7XG5cbiAgaWYgKGlzRW51bUFycmF5KG9wdGlvbnMpKSB7XG4gICAgb3B0aW9ucy50eXBlID0gXCJhcnJheVwiO1xuXG4gICAgY29uc3QgZW51bVZhbHVlcyA9IGdldEVudW1WYWx1ZXMob3B0aW9ucy5lbnVtKTtcbiAgICBvcHRpb25zLml0ZW1zID0ge1xuICAgICAgdHlwZTogZ2V0RW51bVR5cGUoZW51bVZhbHVlcyksXG4gICAgICBlbnVtOiBlbnVtVmFsdWVzLFxuICAgIH07XG4gICAgLy8gQHRzLWV4cGVjdC1lcnJvciBuZXN0IHN3YWdnZXIgb3ZlcnJpZGVcbiAgICBkZWxldGUgb3B0aW9ucy5lbnVtO1xuICB9IGVsc2UgaWYgKFwiZW51bVwiIGluIG9wdGlvbnMgJiYgb3B0aW9ucy5lbnVtICE9PSB1bmRlZmluZWQpIHtcbiAgICBjb25zdCBlbnVtVmFsdWVzID0gZ2V0RW51bVZhbHVlcyhvcHRpb25zLmVudW0pO1xuXG4gICAgb3B0aW9ucy5lbnVtID0gZW51bVZhbHVlcztcbiAgICBvcHRpb25zLnR5cGUgPSBnZXRFbnVtVHlwZShlbnVtVmFsdWVzKTtcbiAgfVxuXG4gIGlmIChBcnJheS5pc0FycmF5KG9wdGlvbnMudHlwZSkpIHtcbiAgICBvcHRpb25zLnR5cGUgPSBcImFycmF5XCI7XG4gICAgb3B0aW9ucy5pdGVtcyA9IHtcbiAgICAgIHR5cGU6IFwiYXJyYXlcIixcbiAgICAgIGl0ZW1zOiB7XG4gICAgICAgIHR5cGU6IG9wdGlvbnMudHlwZVswXSxcbiAgICAgIH0sXG4gICAgfTtcbiAgfVxuXG4gIHJldHVybiBjcmVhdGVQcm9wZXJ0eURlY29yYXRvcihcbiAgICBERUNPUkFUT1JTLkFQSV9NT0RFTF9QUk9QRVJUSUVTLFxuICAgIG9wdGlvbnMsXG4gICAgb3ZlcnJpZGVFeGlzdGluZ1xuICApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gQXBpUHJvcGVydHlPcHRpb25hbChcbiAgb3B0aW9uczogQXBpUHJvcGVydHlPcHRpb25zID0ge31cbik6IFByb3BlcnR5RGVjb3JhdG9yIHtcbiAgcmV0dXJuIEFwaVByb3BlcnR5KHtcbiAgICAuLi5vcHRpb25zLFxuICAgIHJlcXVpcmVkOiBmYWxzZSxcbiAgfSBhcyBBcGlQcm9wZXJ0eU9wdGlvbnMpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gQXBpUmVzcG9uc2VQcm9wZXJ0eShcbiAgb3B0aW9uczogUGljazxcbiAgICBBcGlQcm9wZXJ0eU9wdGlvbnMsXG4gICAgXCJ0eXBlXCIgfCBcImV4YW1wbGVcIiB8IFwiZm9ybWF0XCIgfCBcImRlcHJlY2F0ZWRcIiB8IFwiZW51bVwiXG4gID4gPSB7fVxuKTogUHJvcGVydHlEZWNvcmF0b3Ige1xuICByZXR1cm4gQXBpUHJvcGVydHkoe1xuICAgIHJlYWRPbmx5OiB0cnVlLFxuICAgIC4uLm9wdGlvbnMsXG4gIH0gYXMgQXBpUHJvcGVydHlPcHRpb25zKTtcbn1cbiIsImltcG9ydCB7XG4gIEluamVjdGFibGVDb25maWcsXG4gIEluamVjdGFibGVzS2V5cyxcbiAgSW5qZWN0T3B0aW9ucyxcbn0gZnJvbSBcIkBkZWNhZi10cy9pbmplY3RhYmxlLWRlY29yYXRvcnNcIjtcbmltcG9ydCB7IEluamVjdCwgSW5qZWN0YWJsZSwgU2NvcGUgfSBmcm9tIFwiQG5lc3Rqcy9jb21tb25cIjtcbmltcG9ydCB7IENvbnN0cnVjdG9yLCBEZWNvcmF0aW9uLCBEZWNvcmF0aW9uS2V5cyB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdGlvblwiO1xuaW1wb3J0IHsgVmFsaWRhdGlvbktleXMgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBBcGlQcm9wZXJ0eSB9IGZyb20gXCIuL2RlY29yYXRvcnMvQXBpUHJvcGVydHlcIjtcbmltcG9ydCB7IFBlcnNpc3RlbmNlS2V5cyB9IGZyb20gXCJAZGVjYWYtdHMvY29yZVwiO1xuXG5EZWNvcmF0aW9uLmZvcihJbmplY3RhYmxlc0tleXMuSU5KRUNUQUJMRSlcbiAgLmV4dGVuZCh7XG4gICAgZGVjb3JhdG9yOiBmdW5jdGlvbiBuZXN0SW5qZWN0YWJsZShcbiAgICAgIGNhdGVnb3J5OiBzdHJpbmcgfCBDb25zdHJ1Y3RvcixcbiAgICAgIGNmZzogSW5qZWN0YWJsZUNvbmZpZ1xuICAgICkge1xuICAgICAgcmV0dXJuIEluamVjdGFibGUoe1xuICAgICAgICBzY29wZTogY2ZnLnNpbmdsZXRvbiA/IFNjb3BlLkRFRkFVTFQgOiBTY29wZS5SRVFVRVNULFxuICAgICAgICBkdXJhYmxlOiBjZmcuc2luZ2xldG9uID8gdW5kZWZpbmVkIDogdHJ1ZSxcbiAgICAgIH0pO1xuICAgIH0sXG4gIH0pXG4gIC5hcHBseSgpO1xuXG5EZWNvcmF0aW9uLmZvcihJbmplY3RhYmxlc0tleXMuSU5KRUNUKVxuICAuZXh0ZW5kKHtcbiAgICBkZWNvcmF0b3I6IGZ1bmN0aW9uIG5lc3RJbmplY3QoXG4gICAgICBjYXRlZ29yeTogc3ltYm9sIHwgc3RyaW5nIHwgQ29uc3RydWN0b3IsXG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gICAgICBjZmc6IEluamVjdE9wdGlvbnNcbiAgICApIHtcbiAgICAgIHJldHVybiBmdW5jdGlvbiBpbm5lck5lc3RJbmplY3QoXG4gICAgICAgIHRhcmdldDogb2JqZWN0LFxuICAgICAgICBwcm9wZXJ0eUtleT86IGFueSxcbiAgICAgICAgZGVzY3JpcHRvcj86IGFueVxuICAgICAgKSB7XG4gICAgICAgIHJldHVybiBJbmplY3QoY2F0ZWdvcnkgfHwgKHRhcmdldCBhcyBDb25zdHJ1Y3RvcikpKFxuICAgICAgICAgIHRhcmdldCxcbiAgICAgICAgICBwcm9wZXJ0eUtleSxcbiAgICAgICAgICBkZXNjcmlwdG9yXG4gICAgICAgICk7XG4gICAgICB9O1xuICAgIH0sXG4gIH0pXG4gIC5hcHBseSgpO1xuXG5EZWNvcmF0aW9uLmZvcihWYWxpZGF0aW9uS2V5cy5SRVFVSVJFRClcbiAgLmV4dGVuZChcbiAgICBBcGlQcm9wZXJ0eSh7XG4gICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICB9KVxuICApXG4gIC5hcHBseSgpO1xuXG5EZWNvcmF0aW9uLmZvcihWYWxpZGF0aW9uS2V5cy5NQVgpXG4gIC5leHRlbmQoe1xuICAgIGRlY29yYXRvcjogZnVuY3Rpb24gbWF4RGVjKG1heDogbnVtYmVyKSB7XG4gICAgICByZXR1cm4gQXBpUHJvcGVydHkoeyBtYXhpbXVtOiBtYXggfSk7XG4gICAgfSxcbiAgfSlcbiAgLmFwcGx5KCk7XG5cbkRlY29yYXRpb24uZm9yKFZhbGlkYXRpb25LZXlzLk1JTilcbiAgLmV4dGVuZCh7XG4gICAgZGVjb3JhdG9yOiBmdW5jdGlvbiBtaW5EZWMobWluOiBudW1iZXIpIHtcbiAgICAgIHJldHVybiBBcGlQcm9wZXJ0eSh7IG1pbmltdW06IG1pbiB9KTtcbiAgICB9LFxuICB9KVxuICAuYXBwbHkoKTtcblxuRGVjb3JhdGlvbi5mb3IoVmFsaWRhdGlvbktleXMuTUFYX0xFTkdUSClcbiAgLmV4dGVuZCh7XG4gICAgZGVjb3JhdG9yOiBmdW5jdGlvbiBtYXhMZW5ndGhEZWMobWF4OiBudW1iZXIpIHtcbiAgICAgIHJldHVybiBBcGlQcm9wZXJ0eSh7IG1heExlbmd0aDogbWF4IH0pO1xuICAgIH0sXG4gIH0pXG4gIC5hcHBseSgpO1xuXG5EZWNvcmF0aW9uLmZvcihWYWxpZGF0aW9uS2V5cy5NSU5fTEVOR1RIKVxuICAuZXh0ZW5kKHtcbiAgICBkZWNvcmF0b3I6IGZ1bmN0aW9uIG1pbkxlbmd0aERlYyhtaW46IG51bWJlcikge1xuICAgICAgcmV0dXJuIEFwaVByb3BlcnR5KHsgbWluTGVuZ3RoOiBtaW4gfSk7XG4gICAgfSxcbiAgfSlcbiAgLmFwcGx5KCk7XG4vL1xuLy8gRGVjb3JhdGlvbi5mb3IoVmFsaWRhdGlvbktleXMuVFlQRSlcbi8vICAgLmV4dGVuZCh7XG4vLyAgICAgZGVjb3JhdG9yOiBmdW5jdGlvbiB0eXBlRGVjKHR5cGU6IChzdHJpbmcgfCAoKCkgPT4gc3RyaW5nKSlbXSB8IHN0cmluZyB8ICgoKSA9PiBzdHJpbmcpKSB7XG4vLyAgICAgICByZXR1cm4gQXBpUHJvcGVydHkoeyB0eXBlOiB0eXBlIGFzIGFueSB9KTtcbi8vICAgICB9LFxuLy8gICB9KVxuLy8gICAuYXBwbHkoKTtcbi8vXG4vLyBEZWNvcmF0aW9uLmZvcihWYWxpZGF0aW9uS2V5cy5EQVRFKVxuLy8gICAuZXh0ZW5kKHtcbi8vICAgICBkZWNvcmF0b3I6IGZ1bmN0aW9uIGRhdGVEZWMoKSB7XG4vLyAgICAgICByZXR1cm4gQXBpUHJvcGVydHkoeyB0eXBlOiBEYXRlIH0pO1xuLy8gICAgIH0sXG4vLyAgIH0pXG4vLyAgIC5hcHBseSgpO1xuXG5EZWNvcmF0aW9uLmZvcihWYWxpZGF0aW9uS2V5cy5MSVNUKVxuICAuZXh0ZW5kKHtcbiAgICBkZWNvcmF0b3I6IGZ1bmN0aW9uIGxpc3REZWMoXG4gICAgICBjbGF6ejpcbiAgICAgICAgfCBDb25zdHJ1Y3Rvcjxhbnk+XG4gICAgICAgIHwgKCgpID0+IENvbnN0cnVjdG9yPGFueT4pXG4gICAgICAgIHwgKENvbnN0cnVjdG9yPGFueT4gfCAoKCkgPT4gQ29uc3RydWN0b3I8YW55PikpW11cbiAgICApIHtcbiAgICAgIGNvbnN0IGMgPSBBcnJheS5pc0FycmF5KGNsYXp6KSA/IGNsYXp6WzBdIDogY2xheno7XG4gICAgICByZXR1cm4gQXBpUHJvcGVydHkoeyB0eXBlOiBbY10gfSk7XG4gICAgfSxcbiAgfSlcbiAgLmFwcGx5KCk7XG5cbi8vXG4vLyBEZWNvcmF0aW9uLmZvcihWYWxpZGF0aW9uS2V5cy5PUFRJT04pXG4vLyAgIC5leHRlbmQoe1xuLy8gICAgIGRlY29yYXRvcjogZnVuY3Rpb24gb3B0aW9uRGVjKG9wdGlvbnM6IHN0cmluZ1tdIHwgUmVjb3JkPHN0cmluZywgYW55Pikge1xuLy8gICAgICAgY29uc3Qgb3B0cyA9IEFycmF5LmlzQXJyYXkob3B0aW9ucykgPyBvcHRpb25zIDogT2JqZWN0LnZhbHVlcyhvcHRpb25zKTtcbi8vICAgICAgIHJldHVybiBBcGlQcm9wZXJ0eSh7IGVudW06IG9wdHMgfSk7XG4vLyAgICAgfSxcbi8vICAgfSlcbi8vICAgLmFwcGx5KCk7XG5cbkRlY29yYXRpb24uZm9yKFZhbGlkYXRpb25LZXlzLlBBVFRFUk4pXG4gIC5leHRlbmQoe1xuICAgIGRlY29yYXRvcjogZnVuY3Rpb24gcGF0dGVybkRlYyhwYXQ6IFJlZ0V4cCB8IHN0cmluZykge1xuICAgICAgcmV0dXJuIEFwaVByb3BlcnR5KHtcbiAgICAgICAgcGF0dGVybjogdHlwZW9mIHBhdCA9PT0gXCJzdHJpbmdcIiA/IHBhdCA6IHBhdC5zb3VyY2UsXG4gICAgICB9KTtcbiAgICB9LFxuICB9KVxuICAuYXBwbHkoKTtcblxuRGVjb3JhdGlvbi5mb3IoUGVyc2lzdGVuY2VLZXlzLkNPTFVNTilcbiAgLmV4dGVuZCh7XG4gICAgZGVjb3JhdG9yOiBmdW5jdGlvbiBjb2x1bW5EZWMobmFtZTogc3RyaW5nKSB7XG4gICAgICByZXR1cm4gQXBpUHJvcGVydHkoe1xuICAgICAgICBuYW1lOiBuYW1lLFxuICAgICAgfSk7XG4gICAgfSxcbiAgfSlcbiAgLmFwcGx5KCk7XG5cbkRlY29yYXRpb24uZm9yKERlY29yYXRpb25LZXlzLkRFU0NSSVBUSU9OKVxuICAuZXh0ZW5kKHtcbiAgICBkZWNvcmF0b3I6IGZ1bmN0aW9uIGRlc2NyaXB0aW9uRGVjKGRlc2NyaXB0aW9uOiBzdHJpbmcpIHtcbiAgICAgIHJldHVybiBBcGlQcm9wZXJ0eSh7XG4gICAgICAgIGRlc2NyaXB0aW9uOiBkZXNjcmlwdGlvbixcbiAgICAgIH0pO1xuICAgIH0sXG4gIH0pXG4gIC5hcHBseSgpO1xuIiwiZXhwb3J0IGNvbnN0IERFQ0FGX01PRFVMRV9PUFRJT05TID0gXCJEZWNhZk1vZHVsZU9wdGlvbnNcIjtcbmV4cG9ydCBjb25zdCBERUNBRl9BREFQVEVSX0lEID0gXCJEZWNhZkFkYXB0ZXJcIjtcbiIsImltcG9ydCB7XG4gIER5bmFtaWNNb2R1bGUsXG4gIEdsb2JhbCxcbiAgSW5qZWN0LFxuICBNb2R1bGUsXG4gIE9uQXBwbGljYXRpb25TaHV0ZG93bixcbiAgU2NvcGUsXG59IGZyb20gXCJAbmVzdGpzL2NvbW1vblwiO1xuaW1wb3J0IHsgTW9kdWxlUmVmIH0gZnJvbSBcIkBuZXN0anMvY29yZVwiO1xuaW1wb3J0IHR5cGUgeyBEZWNhZk1vZHVsZU9wdGlvbnMgfSBmcm9tIFwiLi90eXBlc1wiO1xuaW1wb3J0IHsgREVDQUZfQURBUFRFUl9JRCwgREVDQUZfTU9EVUxFX09QVElPTlMgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IEZhY3RvcnlQcm92aWRlciB9IGZyb20gXCJAbmVzdGpzL2NvbW1vbi9pbnRlcmZhY2VzL21vZHVsZXMvcHJvdmlkZXIuaW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBBZGFwdGVyIH0gZnJvbSBcIkBkZWNhZi10cy9jb3JlXCI7XG5pbXBvcnQgeyBMb2dnZXIsIExvZ2dpbmcgfSBmcm9tIFwiQGRlY2FmLXRzL2xvZ2dpbmdcIjtcblxuQEdsb2JhbCgpXG5ATW9kdWxlKHt9KVxuZXhwb3J0IGNsYXNzIERlY2FmQ29yZU1vZHVsZTxcbiAgQ09ORixcbiAgQURBUFRFUiBleHRlbmRzIEFkYXB0ZXI8Q09ORiwgYW55LCBhbnksIGFueSwgYW55Pixcbj4gaW1wbGVtZW50cyBPbkFwcGxpY2F0aW9uU2h1dGRvd25cbntcbiAgcHJpdmF0ZSBzdGF0aWMgX2xvZ2dlcjogTG9nZ2VyO1xuICBwcml2YXRlIHN0YXRpYyBfYWRhcHRlckluc3RhbmNlOiBBZGFwdGVyPGFueSwgYW55LCBhbnksIGFueSwgYW55PiB8IG51bGwgPVxuICAgIG51bGw7XG5cbiAgcHJvdGVjdGVkIHN0YXRpYyBnZXQgbG9nKCk6IExvZ2dlciB7XG4gICAgaWYgKCF0aGlzLl9sb2dnZXIpIHRoaXMuX2xvZ2dlciA9IExvZ2dpbmcuZm9yKERlY2FmQ29yZU1vZHVsZSk7XG4gICAgcmV0dXJuIHRoaXMuX2xvZ2dlcjtcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKFxuICAgIEBJbmplY3QoREVDQUZfTU9EVUxFX09QVElPTlMpXG4gICAgcHJpdmF0ZSByZWFkb25seSBvcHRpb25zOiBEZWNhZk1vZHVsZU9wdGlvbnM8Q09ORiwgQURBUFRFUj4sXG4gICAgcHJpdmF0ZSByZWFkb25seSBtb2R1bGVSZWY6IE1vZHVsZVJlZlxuICApIHt9XG5cbiAgc3RhdGljIGFzeW5jIGNyZWF0ZUFkYXB0ZXIoXG4gICAgb3B0aW9uczogRGVjYWZNb2R1bGVPcHRpb25zXG4gICk6IFByb21pc2U8QWRhcHRlcjxhbnksIGFueSwgYW55LCBhbnksIGFueT4+IHtcbiAgICBpZiAoIXRoaXMuX2FkYXB0ZXJJbnN0YW5jZSkge1xuICAgICAgY29uc3QgbG9nID0gdGhpcy5sb2cuZm9yKHRoaXMuY3JlYXRlQWRhcHRlcik7XG4gICAgICBsb2cuaW5mbyhcIkNyZWF0aW5nIGFkYXB0ZXIgaW5zdGFuY2UuLi5cIik7XG4gICAgICB0aGlzLl9hZGFwdGVySW5zdGFuY2UgPSBuZXcgb3B0aW9ucy5hZGFwdGVyKG9wdGlvbnMuY29uZiwgb3B0aW9ucy5hbGlhcyk7XG4gICAgICBsb2cuaW5mbyhcIkFkYXB0ZXIgaW5zdGFuY2UgY3JlYXRlZCBzdWNjZXNzZnVsbHkhXCIpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fYWRhcHRlckluc3RhbmNlO1xuICB9XG5cbiAgc3RhdGljIGdldEFkYXB0ZXJJbnN0YW5jZSgpOiBBZGFwdGVyPGFueSwgYW55LCBhbnksIGFueSwgYW55PiB8IG51bGwge1xuICAgIHJldHVybiB0aGlzLl9hZGFwdGVySW5zdGFuY2U7XG4gIH1cblxuICBzdGF0aWMgZm9yUm9vdChvcHRpb25zOiBEZWNhZk1vZHVsZU9wdGlvbnMpOiBEeW5hbWljTW9kdWxlIHtcbiAgICBjb25zdCB0eXBlT3JtTW9kdWxlT3B0aW9ucyA9IHtcbiAgICAgIHByb3ZpZGU6IERFQ0FGX01PRFVMRV9PUFRJT05TLFxuICAgICAgdXNlVmFsdWU6IG9wdGlvbnMsXG4gICAgfTtcblxuICAgIGNvbnN0IGFkYXB0ZXI6IEZhY3RvcnlQcm92aWRlcjxhbnk+ID0ge1xuICAgICAgdXNlRmFjdG9yeTogYXN5bmMgKG9wdHM6IERlY2FmTW9kdWxlT3B0aW9ucykgPT4ge1xuICAgICAgICByZXR1cm4gRGVjYWZDb3JlTW9kdWxlLmNyZWF0ZUFkYXB0ZXIob3B0cyk7XG4gICAgICB9LFxuICAgICAgcHJvdmlkZTogREVDQUZfQURBUFRFUl9JRCxcbiAgICAgIGR1cmFibGU6IHRydWUsXG4gICAgICBzY29wZTogU2NvcGUuREVGQVVMVCxcbiAgICAgIGluamVjdDogW0RFQ0FGX01PRFVMRV9PUFRJT05TXSxcbiAgICB9O1xuXG4gICAgY29uc3QgcHJvdmlkZXJzID0gW2FkYXB0ZXIsIHR5cGVPcm1Nb2R1bGVPcHRpb25zXTtcbiAgICBjb25zdCBleHBvcnRzID0gW2FkYXB0ZXJdO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIG1vZHVsZTogRGVjYWZDb3JlTW9kdWxlLFxuICAgICAgcHJvdmlkZXJzLFxuICAgICAgZXhwb3J0cyxcbiAgICB9O1xuICB9XG5cbiAgYXN5bmMgb25BcHBsaWNhdGlvblNodXRkb3duKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGxvZyA9IERlY2FmQ29yZU1vZHVsZS5sb2cuZm9yKHRoaXMub25BcHBsaWNhdGlvblNodXRkb3duKTtcbiAgICBjb25zdCBhZGFwdGVyID0gdGhpcy5tb2R1bGVSZWYuZ2V0PEFEQVBURVI+KERFQ0FGX0FEQVBURVJfSUQpO1xuICAgIHRyeSB7XG4gICAgICBpZiAoYWRhcHRlcikge1xuICAgICAgICBsb2cuaW5mbyhcIlNodXR0aW5nIGRvd25cIik7XG4gICAgICAgIGF3YWl0IGFkYXB0ZXIuc2h1dGRvd24oKTtcbiAgICAgICAgRGVjYWZDb3JlTW9kdWxlLl9hZGFwdGVySW5zdGFuY2UgPSBudWxsO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICAgIGxvZy5lcnJvcihgRmFpbGVkIHRvIHNodXRkb3duIGFwcGxpY2F0aW9uYCwgZSBhcyBFcnJvcik7XG4gICAgfVxuICB9XG59XG4iLCJpbXBvcnQgeyBNb2RlbCB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7IEludGVybmFsRXJyb3IgfSBmcm9tIFwiQGRlY2FmLXRzL2RiLWRlY29yYXRvcnNcIjtcbmltcG9ydCB7IFJlcG8sIFJlcG9zaXRvcnkgfSBmcm9tIFwiQGRlY2FmLXRzL2NvcmVcIjtcbmltcG9ydCB7IENvbnN0cnVjdG9yIH0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0aW9uXCI7XG5pbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSBcIkBuZXN0anMvY29tbW9uXCI7XG5cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBSZXBvRmFjdG9yeSB7XG4gIGZvcjxNIGV4dGVuZHMgTW9kZWw+KG1vZGVsOiBzdHJpbmcgfCBDb25zdHJ1Y3RvcjxNPik6IFJlcG88TT4ge1xuICAgIG1vZGVsID0gdHlwZW9mIG1vZGVsID09PSBcInN0cmluZ1wiID8gKE1vZGVsLmdldChtb2RlbCkgYXMgYW55KSA6IG1vZGVsO1xuICAgIGlmICghbW9kZWwpIHtcbiAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKGBGYWlsZWQgdG8gZmluZCByZXBvc2l0b3J5IGZvciAke21vZGVsfWApO1xuICAgIH1cbiAgICByZXR1cm4gUmVwb3NpdG9yeS5mb3JNb2RlbChtb2RlbCBhcyBDb25zdHJ1Y3RvcjxNPik7XG4gIH1cbn1cbiIsImltcG9ydCB7XG4gIEJvZHksXG4gIENvbnRyb2xsZXIsXG4gIERlbGV0ZSxcbiAgRHluYW1pY01vZHVsZSxcbiAgR2V0LFxuICBNb2R1bGUsXG4gIFBhcmFtLFxuICBQb3N0LFxuICBQdXQsXG59IGZyb20gXCJAbmVzdGpzL2NvbW1vblwiO1xuaW1wb3J0IHtcbiAgQXBpQmFkUmVxdWVzdFJlc3BvbnNlLFxuICBBcGlCb2R5LFxuICBBcGlDcmVhdGVkUmVzcG9uc2UsXG4gIEFwaUV4dHJhTW9kZWxzLFxuICBBcGlOb3RGb3VuZFJlc3BvbnNlLFxuICBBcGlPa1Jlc3BvbnNlLFxuICBBcGlPcGVyYXRpb24sXG4gIEFwaVBhcmFtLFxuICBBcGlUYWdzLFxuICBBcGlVbnByb2Nlc3NhYmxlRW50aXR5UmVzcG9uc2UsXG4gIGdldFNjaGVtYVBhdGgsXG59IGZyb20gXCJAbmVzdGpzL3N3YWdnZXJcIjtcbmltcG9ydCB7IEFkYXB0ZXIsIFJlcG8sIFJlcG9zaXRvcnkgfSBmcm9tIFwiQGRlY2FmLXRzL2NvcmVcIjtcbmltcG9ydCB7IE1vZGVsLCBNb2RlbENvbnN0cnVjdG9yIH0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgTG9nZ2VkQ2xhc3MsIExvZ2dlciwgTG9nZ2luZywgdG9LZWJhYkNhc2UgfSBmcm9tIFwiQGRlY2FmLXRzL2xvZ2dpbmdcIjtcbmltcG9ydCB7IFJlcG9GYWN0b3J5IH0gZnJvbSBcIi4vUmVwb0ZhY3RvcnlcIjtcblxuQE1vZHVsZSh7fSlcbmV4cG9ydCBjbGFzcyBEZWNhZk1vZGVsTW9kdWxlIHtcbiAgcHJpdmF0ZSBzdGF0aWMgX2xvZ2dlcjogTG9nZ2VyO1xuXG4gIHByb3RlY3RlZCBzdGF0aWMgZ2V0IGxvZygpOiBMb2dnZXIge1xuICAgIGlmICghdGhpcy5fbG9nZ2VyKSB0aGlzLl9sb2dnZXIgPSBMb2dnaW5nLmZvcihEZWNhZk1vZGVsTW9kdWxlKTtcbiAgICByZXR1cm4gdGhpcy5fbG9nZ2VyO1xuICB9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgdG9Nb2RlbENvbnRyb2xsZXI8VCBleHRlbmRzIE1vZGVsPGFueT4+KFxuICAgIE1vZGVsQ2xheno6IE1vZGVsQ29uc3RydWN0b3I8YW55PlxuICApIHtcbiAgICBjb25zdCBsb2cgPSB0aGlzLmxvZy5mb3IodGhpcy50b01vZGVsQ29udHJvbGxlcik7XG4gICAgY29uc3QgdGFibGVOYW1lID0gUmVwb3NpdG9yeS50YWJsZShNb2RlbENsYXp6KTtcbiAgICBjb25zdCByb3V0ZVBhdGggPSB0b0tlYmFiQ2FzZSh0YWJsZU5hbWUpO1xuICAgIGNvbnN0IG1vZGVsQ2xhenpOYW1lID0gTW9kZWxDbGF6ei5uYW1lO1xuXG4gICAgbG9nLmRlYnVnKGBDcmVhdGluZyBjb250cm9sbGVyIGZvciBtb2RlbDogJHttb2RlbENsYXp6TmFtZX1gKTtcblxuICAgIEBDb250cm9sbGVyKHJvdXRlUGF0aClcbiAgICBAQXBpVGFncyhtb2RlbENsYXp6TmFtZSlcbiAgICBAQXBpRXh0cmFNb2RlbHMoTW9kZWxDbGF6eilcbiAgICBjbGFzcyBEeW5hbWljTW9kZWxDb250cm9sbGVyIGV4dGVuZHMgTG9nZ2VkQ2xhc3Mge1xuICAgICAgLy8gcHJpdmF0ZSByZWFkb25seSByZXBvID0gdGhpcy5yZXBvRmFjdG9yeS5mb3IoTW9kZWxDbGF6eik7XG4gICAgICBwcml2YXRlIHJlYWRvbmx5IHBrITogc3RyaW5nO1xuICAgICAgcHJpdmF0ZSByZWFkb25seSByZXBvITogUmVwbzxUPjsgLy9SZXBvc2l0b3J5PE1vZGVsPGFueT4sIGFueSwgYW55LCBhbnksIGFueT47XG5cbiAgICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVhZG9ubHkgcmVwb0ZhY3Rvcnk6IFJlcG9GYWN0b3J5KSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIGxvZy5pbmZvKFxuICAgICAgICAgIGBSZWdpc3RlcmluZyBkeW5hbWljIGNvbnRyb2xsZXIgZm9yIG1vZGVsOiAke21vZGVsQ2xhenpOYW1lfSByb3V0ZTogLyR7cm91dGVQYXRofWBcbiAgICAgICAgKTtcblxuICAgICAgICB0cnkge1xuICAgICAgICAgIHRoaXMucmVwbyA9IHRoaXMucmVwb0ZhY3RvcnkuZm9yKE1vZGVsQ2xhenoubmFtZSk7XG4gICAgICAgICAgdGhpcy5wayA9IHRoaXMucmVwby5wayBhcyBzdHJpbmc7XG4gICAgICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgICAgIHRoaXMubG9nLmVycm9yKFxuICAgICAgICAgICAgYEZhaWxlZCB0byBpbml0aWFsaXplIHJlcG9zaXRvcnkgZm9yIG1vZGVsIFwiJHtNb2RlbENsYXp6Lm5hbWV9XCIuYCxcbiAgICAgICAgICAgIGVcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIEBQb3N0KClcbiAgICAgIEBBcGlPcGVyYXRpb24oeyBzdW1tYXJ5OiBgQ3JlYXRlIGEgbmV3ICR7bW9kZWxDbGF6ek5hbWV9LmAgfSlcbiAgICAgIEBBcGlCb2R5KHtcbiAgICAgICAgZGVzY3JpcHRpb246IGBQYXlsb2FkIGZvciAke21vZGVsQ2xhenpOYW1lfWAsXG4gICAgICAgIHNjaGVtYTogeyAkcmVmOiBnZXRTY2hlbWFQYXRoKE1vZGVsQ2xhenopIH0sXG4gICAgICB9KVxuICAgICAgQEFwaUNyZWF0ZWRSZXNwb25zZSh7XG4gICAgICAgIGRlc2NyaXB0aW9uOiBgJHttb2RlbENsYXp6TmFtZX0gY3JlYXRlZCBzdWNjZXNzZnVsbHkuYCxcbiAgICAgIH0pXG4gICAgICBAQXBpQmFkUmVxdWVzdFJlc3BvbnNlKHsgZGVzY3JpcHRpb246IFwiUGF5bG9hZCB2YWxpZGF0aW9uIGZhaWxlZC5cIiB9KVxuICAgICAgQEFwaVVucHJvY2Vzc2FibGVFbnRpdHlSZXNwb25zZSh7XG4gICAgICAgIGRlc2NyaXB0aW9uOiBcIlJlcG9zaXRvcnkgcmVqZWN0ZWQgdGhlIHByb3ZpZGVkIHBheWxvYWQuXCIsXG4gICAgICB9KVxuICAgICAgYXN5bmMgY3JlYXRlKEBCb2R5KCkgZGF0YTogVCk6IFByb21pc2U8TW9kZWw8YW55Pj4ge1xuICAgICAgICBjb25zdCBsb2cgPSB0aGlzLmxvZy5mb3IodGhpcy5jcmVhdGUpO1xuICAgICAgICBsb2cudmVyYm9zZShgY3JlYXRpbmcgbmV3ICR7bW9kZWxDbGF6ek5hbWV9YCk7XG4gICAgICAgIGxldCBjcmVhdGVkOiBNb2RlbDtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjcmVhdGVkID0gYXdhaXQgdGhpcy5yZXBvLmNyZWF0ZShkYXRhKTtcbiAgICAgICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgICAgIGxvZy5lcnJvcihgRmFpbGVkIHRvIGNyZWF0ZSBuZXcgJHttb2RlbENsYXp6TmFtZX1gLCBlIGFzIEVycm9yKTtcbiAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICB9XG4gICAgICAgIGxvZy5pbmZvKGBjcmVhdGVkIG5ldyAke21vZGVsQ2xhenpOYW1lfSB3aXRoIGlkICR7Y3JlYXRlZFt0aGlzLnBrXX1gKTtcbiAgICAgICAgcmV0dXJuIGNyZWF0ZWQ7XG4gICAgICB9XG5cbiAgICAgIEBHZXQoXCI6aWRcIilcbiAgICAgIEBBcGlPcGVyYXRpb24oeyBzdW1tYXJ5OiBgUmV0cmlldmUgYSAke21vZGVsQ2xhenpOYW1lfSByZWNvcmQgYnkgaWQuYCB9KVxuICAgICAgQEFwaVBhcmFtKHsgbmFtZTogXCJpZFwiLCBkZXNjcmlwdGlvbjogXCJQcmltYXJ5IGtleVwiIH0pXG4gICAgICBAQXBpT2tSZXNwb25zZSh7XG4gICAgICAgIGRlc2NyaXB0aW9uOiBgJHttb2RlbENsYXp6TmFtZX0gcmV0cmlldmVkIHN1Y2Nlc3NmdWxseS5gLFxuICAgICAgfSlcbiAgICAgIEBBcGlOb3RGb3VuZFJlc3BvbnNlKHtcbiAgICAgICAgZGVzY3JpcHRpb246IGBObyAke21vZGVsQ2xhenpOYW1lfSByZWNvcmQgbWF0Y2hlcyB0aGUgcHJvdmlkZWQgaWRlbnRpZmllci5gLFxuICAgICAgfSlcbiAgICAgIGFzeW5jIHJlYWQoQFBhcmFtKFwiaWRcIikgaWQ6IHN0cmluZykge1xuICAgICAgICBjb25zdCBsb2cgPSB0aGlzLmxvZy5mb3IodGhpcy5yZWFkKTtcbiAgICAgICAgbGV0IHJlYWQ6IE1vZGVsO1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGxvZy5kZWJ1ZyhgcmVhZGluZyAke21vZGVsQ2xhenpOYW1lfSB3aXRoICR7dGhpcy5wa30gJHtpZH1gKTtcbiAgICAgICAgICByZWFkID0gYXdhaXQgdGhpcy5yZXBvLnJlYWQoaWQpO1xuICAgICAgICB9IGNhdGNoIChlOiB1bmtub3duKSB7XG4gICAgICAgICAgbG9nLmVycm9yKFxuICAgICAgICAgICAgYEZhaWxlZCB0byByZWFkICR7bW9kZWxDbGF6ek5hbWV9IHdpdGggaWQgJHtpZH1gLFxuICAgICAgICAgICAgZSBhcyBFcnJvclxuICAgICAgICAgICk7XG4gICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxvZy5pbmZvKGByZWFkICR7bW9kZWxDbGF6ek5hbWV9IHdpdGggaWQgJHtyZWFkW3RoaXMucGtdfWApO1xuICAgICAgICByZXR1cm4gcmVhZDtcbiAgICAgIH1cblxuICAgICAgQFB1dChcIjppZFwiKVxuICAgICAgQEFwaU9wZXJhdGlvbih7XG4gICAgICAgIHN1bW1hcnk6IGBSZXBsYWNlIGFuIGV4aXN0aW5nICR7bW9kZWxDbGF6ek5hbWV9IHJlY29yZCB3aXRoIGEgbmV3IHBheWxvYWQuYCxcbiAgICAgIH0pXG4gICAgICBAQXBpQm9keSh7XG4gICAgICAgIGRlc2NyaXB0aW9uOiBgUGF5bG9hZCBmb3IgcmVwbGFjZSBhIGV4aXN0aW5nIHJlY29yZCBvZiAke21vZGVsQ2xhenpOYW1lfWAsXG4gICAgICAgIHNjaGVtYTogeyAkcmVmOiBnZXRTY2hlbWFQYXRoKE1vZGVsQ2xhenopIH0sXG4gICAgICB9KVxuICAgICAgQEFwaU9rUmVzcG9uc2Uoe1xuICAgICAgICBkZXNjcmlwdGlvbjogYCR7TW9kZWxDbGF6en0gcmVjb3JkIHJlcGxhY2VkIHN1Y2Nlc3NmdWxseS5gLFxuICAgICAgfSlcbiAgICAgIEBBcGlOb3RGb3VuZFJlc3BvbnNlKHtcbiAgICAgICAgZGVzY3JpcHRpb246IGBObyAke21vZGVsQ2xhenpOYW1lfSByZWNvcmQgbWF0Y2hlcyB0aGUgcHJvdmlkZWQgaWRlbnRpZmllci5gLFxuICAgICAgfSlcbiAgICAgIEBBcGlCYWRSZXF1ZXN0UmVzcG9uc2UoeyBkZXNjcmlwdGlvbjogXCJQYXlsb2FkIHZhbGlkYXRpb24gZmFpbGVkLlwiIH0pXG4gICAgICBhc3luYyB1cGRhdGUoQEJvZHkoKSBkYXRhOiBNb2RlbDxhbnk+KSB7XG4gICAgICAgIGNvbnN0IGxvZyA9IHRoaXMubG9nLmZvcih0aGlzLnVwZGF0ZSk7XG4gICAgICAgIGxldCB1cGRhdGVkOiBNb2RlbDtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBsb2cuaW5mbyhcbiAgICAgICAgICAgIGB1cGRhdGluZyAke21vZGVsQ2xhenpOYW1lfSB3aXRoICR7dGhpcy5wa30gJHtkYXRhW3RoaXMucGtdfWBcbiAgICAgICAgICApO1xuICAgICAgICAgIHVwZGF0ZWQgPSBhd2FpdCB0aGlzLnJlcG8uY3JlYXRlKGRhdGEpO1xuICAgICAgICB9IGNhdGNoIChlOiB1bmtub3duKSB7XG4gICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdXBkYXRlZDtcbiAgICAgIH1cblxuICAgICAgQERlbGV0ZShcIjppZFwiKVxuICAgICAgQEFwaU9wZXJhdGlvbih7IHN1bW1hcnk6IGBEZWxldGUgYSAke21vZGVsQ2xhenpOYW1lfSByZWNvcmQgYnkgaWQuYCB9KVxuICAgICAgQEFwaVBhcmFtKHtcbiAgICAgICAgbmFtZTogXCJpZFwiLFxuICAgICAgICBkZXNjcmlwdGlvbjogYFByaW1hcnkga2V5IHZhbHVlIG9mIHRoZSAke21vZGVsQ2xhenpOYW1lfSByZWNvcmQgdG8gZGVsZXRlLmAsXG4gICAgICB9KVxuICAgICAgQEFwaU9rUmVzcG9uc2Uoe1xuICAgICAgICBkZXNjcmlwdGlvbjogYCR7bW9kZWxDbGF6ek5hbWV9IHJlY29yZCBkZWxldGVkIHN1Y2Nlc3NmdWxseS5gLFxuICAgICAgfSlcbiAgICAgIEBBcGlOb3RGb3VuZFJlc3BvbnNlKHtcbiAgICAgICAgZGVzY3JpcHRpb246IGBObyAke21vZGVsQ2xhenpOYW1lfSByZWNvcmQgbWF0Y2hlcyB0aGUgcHJvdmlkZWQgaWRlbnRpZmllci5gLFxuICAgICAgfSlcbiAgICAgIGFzeW5jIGRlbGV0ZShAUGFyYW0oXCJpZFwiKSBpZDogc3RyaW5nKSB7XG4gICAgICAgIGNvbnN0IGxvZyA9IHRoaXMubG9nLmZvcih0aGlzLmRlbGV0ZSk7XG4gICAgICAgIGxldCByZWFkOiBNb2RlbDtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBsb2cuZGVidWcoXG4gICAgICAgICAgICBgZGVsZXRpbmcgJHttb2RlbENsYXp6TmFtZX0gd2l0aCAke3RoaXMucGsgYXMgc3RyaW5nfSAke2lkfWBcbiAgICAgICAgICApO1xuICAgICAgICAgIHJlYWQgPSBhd2FpdCB0aGlzLnJlcG8ucmVhZChpZCk7XG4gICAgICAgIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICAgICAgICBsb2cuZXJyb3IoXG4gICAgICAgICAgICBgRmFpbGVkIHRvIGRlbGV0ZSAke21vZGVsQ2xhenpOYW1lfSB3aXRoIGlkICR7aWR9YCxcbiAgICAgICAgICAgIGUgYXMgRXJyb3JcbiAgICAgICAgICApO1xuICAgICAgICAgIHRocm93IGU7XG4gICAgICAgIH1cbiAgICAgICAgbG9nLmluZm8oYGRlbGV0ZWQgJHttb2RlbENsYXp6TmFtZX0gd2l0aCBpZCAke3JlYWRbdGhpcy5wa119YCk7XG4gICAgICAgIHJldHVybiByZWFkO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBEeW5hbWljTW9kZWxDb250cm9sbGVyO1xuICB9XG5cbiAgc3RhdGljIGZvclJvb3QoZmxhdm91cjogc3RyaW5nKTogRHluYW1pY01vZHVsZSB7XG4gICAgY29uc3QgbG9nID0gdGhpcy5sb2cuZm9yKHRoaXMuZm9yUm9vdCk7XG4gICAgbG9nLmluZm8oYEdlbmVyYXRpbmcgY29udHJvbGxlcnMgZm9yIGZsYXZvdXIuLi5gKTtcblxuICAgIGNvbnN0IHRyYWNrZWRNb2RlbHMgPSBBZGFwdGVyLm1vZGVscyhmbGF2b3VyKTtcbiAgICBjb25zdCBjb250cm9sbGVycyA9IHRyYWNrZWRNb2RlbHMubWFwKHRoaXMudG9Nb2RlbENvbnRyb2xsZXIuYmluZCh0aGlzKSk7XG5cbiAgICBsb2cuaW5mbyhgR2VuZXJhdGVkICR7Y29udHJvbGxlcnMubGVuZ3RofSBjb250cm9sbGVyc2ApO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIG1vZHVsZTogRGVjYWZNb2RlbE1vZHVsZSxcbiAgICAgIGNvbnRyb2xsZXJzLFxuICAgICAgcHJvdmlkZXJzOiBbUmVwb0ZhY3RvcnldLFxuICAgIH07XG4gIH1cbn1cbiIsImltcG9ydCB7IER5bmFtaWNNb2R1bGUsIEZvcndhcmRSZWZlcmVuY2UsIE1vZHVsZSwgVHlwZSB9IGZyb20gXCJAbmVzdGpzL2NvbW1vblwiO1xuaW1wb3J0IHsgRGVjYWZNb2R1bGVPcHRpb25zIH0gZnJvbSBcIi4vdHlwZXNcIjtcbmltcG9ydCB7IERlY2FmQ29yZU1vZHVsZSB9IGZyb20gXCIuL2NvcmUtbW9kdWxlXCI7XG5pbXBvcnQgeyBEZWNhZk1vZGVsTW9kdWxlIH0gZnJvbSBcIi4vbW9kZWwtbW9kdWxlXCI7XG5cbi8qKlxuICogQHB1YmxpY0FwaVxuICovXG5ATW9kdWxlKHt9KVxuZXhwb3J0IGNsYXNzIERlY2FmTW9kdWxlIHtcbiAgc3RhdGljIGFzeW5jIGZvclJvb3RBc3luYyhcbiAgICBvcHRpb25zOiBEZWNhZk1vZHVsZU9wdGlvbnNcbiAgKTogUHJvbWlzZTxEeW5hbWljTW9kdWxlPiB7XG4gICAgY29uc3QgeyBhdXRvQ29udHJvbGxlcnMgfSA9IG9wdGlvbnM7XG5cbiAgICBjb25zdCBhZGFwdGVyID0gYXdhaXQgRGVjYWZDb3JlTW9kdWxlLmNyZWF0ZUFkYXB0ZXIob3B0aW9ucyk7XG4gICAgY29uc3QgZmxhdm91ciA9IGFkYXB0ZXIuZmxhdm91cjtcblxuICAgIGNvbnN0IGltcG9ydHM6XG4gICAgICB8IChcbiAgICAgICAgICB8IER5bmFtaWNNb2R1bGVcbiAgICAgICAgICB8IFR5cGU8YW55PlxuICAgICAgICAgIHwgUHJvbWlzZTxEeW5hbWljTW9kdWxlPlxuICAgICAgICAgIHwgRm9yd2FyZFJlZmVyZW5jZTxhbnk+XG4gICAgICAgIClbXVxuICAgICAgfCB1bmRlZmluZWQgPSBbRGVjYWZDb3JlTW9kdWxlLmZvclJvb3Qob3B0aW9ucyldO1xuXG4gICAgaWYgKGF1dG9Db250cm9sbGVycykge1xuICAgICAgaW1wb3J0cy5wdXNoKERlY2FmTW9kZWxNb2R1bGUuZm9yUm9vdChmbGF2b3VyKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIG1vZHVsZTogRGVjYWZNb2R1bGUsXG4gICAgICBpbXBvcnRzOiBpbXBvcnRzLFxuICAgIH07XG4gIH1cbn1cbiIsImltcG9ydCB7TW9kZWx9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7SW50ZXJuYWxFcnJvcn0gZnJvbSBcIkBkZWNhZi10cy9kYi1kZWNvcmF0b3JzXCI7XG5pbXBvcnQge1JlcG9zaXRvcnl9IGZyb20gXCJAZGVjYWYtdHMvY29yZVwiO1xuXG5leHBvcnQgZnVuY3Rpb24gcmVwb0Zvck1vZGVsKG1vZGVsOiBzdHJpbmcpIHtcblx0Y29uc3QgbSA9IE1vZGVsLmdldChtb2RlbCk7XG5cdGlmICghbSlcblx0XHR0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihgRmFpbGVkIHRvIGZpbmQgcmVwb3NpdG9yeSBmb3IgJHttb2RlbH1gKVxuXHRjb25zdCByZXBvID0gUmVwb3NpdG9yeS5mb3JNb2RlbChtKTtcblx0cmV0dXJuIHJlcG87XG59IiwiaW1wb3J0IHtDb25uZWN0aW9uRXJyb3IsIEZvcmJpZGRlbkVycm9yfSBmcm9tIFwiQGRlY2FmLXRzL2NvcmVcIjtcblxuZXhwb3J0IGNsYXNzIENvcnNFcnJvciBleHRlbmRzIEZvcmJpZGRlbkVycm9yIHtcblx0Y29uc3RydWN0b3IobXNnOiBzdHJpbmcgfCBFcnJvcikge1xuXHRcdHN1cGVyKG1zZywgQ29yc0Vycm9yLm5hbWUpO1xuXHR9XG59IiwiaW1wb3J0IHsgUmVxdWVzdCB9IGZyb20gXCJleHByZXNzXCI7XG5pbXBvcnQgeyBIdHRwU3RhdHVzIH0gZnJvbSBcIkBuZXN0anMvY29tbW9uXCI7XG5cbmV4cG9ydCBjbGFzcyBIdHRwUmVzcG9uc2VFcnJvciB7XG5cdHN0YXR1cyE6IG51bWJlcjtcblx0ZXJyb3IhOiBzdHJpbmc7XG5cdG1lc3NhZ2UhOiBzdHJpbmc7XG5cdHRpbWVzdGFtcCE6IHN0cmluZztcblx0cGF0aCE6IHN0cmluZztcblx0bWV0aG9kITogc3RyaW5nO1xuXG5cdGNvbnN0cnVjdG9yKFxuXHRcdHJlcXVlc3Q6IFJlcXVlc3QsXG5cdFx0cmVzcG9uc2VFcnJvcj86IHsgc3RhdHVzPzogbnVtYmVyOyBtZXNzYWdlPzogc3RyaW5nOyBlcnJvcj86IHN0cmluZyB9XG5cdCkge1xuXHRcdGNvbnN0IHN0YXR1cyA9IHJlc3BvbnNlRXJyb3I/LnN0YXR1cyA/PyBIdHRwU3RhdHVzLklOVEVSTkFMX1NFUlZFUl9FUlJPUjtcblx0XHRjb25zdCBtZXNzYWdlID0gcmVzcG9uc2VFcnJvcj8ubWVzc2FnZSA/PyBcIkludGVybmFsIFNlcnZlciBFcnJvclwiO1xuXHRcdGNvbnN0IGVycm9yID0gKHJlc3BvbnNlRXJyb3I/LmVycm9yID8/IEh0dHBTdGF0dXNbc3RhdHVzXSA/PyBcIkhUVFBfRVhDRVBUSU9OXCIpXG5cdFx0XHQudG9TdHJpbmcoKVxuXHRcdFx0LnRvVXBwZXJDYXNlKCk7XG5cblx0XHRPYmplY3QuYXNzaWduKHRoaXMsIHtcblx0XHRcdHN0YXR1cyxcblx0XHRcdG1lc3NhZ2UsXG5cdFx0XHRlcnJvcixcblx0XHRcdHRpbWVzdGFtcDogbmV3IERhdGUoKS50b0lTT1N0cmluZygpLFxuXHRcdFx0cGF0aDogcmVxdWVzdC51cmwsXG5cdFx0XHRtZXRob2Q6IHJlcXVlc3QubWV0aG9kLFxuXHRcdH0pO1xuXHR9XG59XG4iLCJpbXBvcnQge0FyZ3VtZW50c0hvc3QsIENhdGNoLCBFeGNlcHRpb25GaWx0ZXIsIEh0dHBTdGF0dXN9IGZyb20gXCJAbmVzdGpzL2NvbW1vblwiO1xuaW1wb3J0IHtSZXF1ZXN0LCBSZXNwb25zZX0gZnJvbSBcImV4cHJlc3NcIjtcbmltcG9ydCB7SHR0cFJlc3BvbnNlRXJyb3J9IGZyb20gXCIuL0h0dHBSZXNwb25zZUVycm9yXCI7XG5cbmV4cG9ydCBjbGFzcyBBdXRob3JpemF0aW9uRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gICAgcmVhZG9ubHkgc3RhdHVzOiBudW1iZXI7XG4gICAgcmVhZG9ubHkgY29kZTogc3RyaW5nO1xuXG4gICAgY29uc3RydWN0b3IobWVzc2FnZSA9IFwiVW5hdXRob3JpemVkXCIpIHtcbiAgICAgICAgc3VwZXIobWVzc2FnZSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiQXV0aG9yaXphdGlvbkVycm9yXCI7XG4gICAgICAgIHRoaXMuc3RhdHVzID0gNDAxO1xuICAgICAgICB0aGlzLmNvZGUgPSBcIlVOQVVUSE9SSVpFRFwiO1xuICAgICAgICBPYmplY3Quc2V0UHJvdG90eXBlT2YodGhpcywgQXV0aG9yaXphdGlvbkVycm9yLnByb3RvdHlwZSk7XG4gICAgfVxufVxuXG5AQ2F0Y2goQXV0aG9yaXphdGlvbkVycm9yKVxuZXhwb3J0IGNsYXNzIEF1dGhvcml6YXRpb25FeGNlcHRpb25GaWx0ZXIgaW1wbGVtZW50cyBFeGNlcHRpb25GaWx0ZXIge1xuICAgIGNhdGNoKGV4Y2VwdGlvbjogQXV0aG9yaXphdGlvbkVycm9yLCBob3N0OiBBcmd1bWVudHNIb3N0KSB7XG4gICAgICAgIGNvbnN0IGN0eCA9IGhvc3Quc3dpdGNoVG9IdHRwKCk7XG4gICAgICAgIGNvbnN0IHJlcXVlc3QgPSBjdHguZ2V0UmVxdWVzdDxSZXF1ZXN0PigpO1xuICAgICAgICBjb25zdCByZXNwb25zZSA9IGN0eC5nZXRSZXNwb25zZTxSZXNwb25zZT4oKTtcblxuICAgICAgICBjb25zdCBodHRwUmVzcG9uc2VFcnJvciA9IG5ldyBIdHRwUmVzcG9uc2VFcnJvcihyZXF1ZXN0LCB7XG4gICAgICAgICAgICBlcnJvcjogXCJVTkFVVEhPUklaRURcIixcbiAgICAgICAgICAgIHN0YXR1czogSHR0cFN0YXR1cy5VTkFVVEhPUklaRUQsXG4gICAgICAgICAgICBtZXNzYWdlOiBleGNlcHRpb24ubWVzc2FnZSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmVzcG9uc2Uuc3RhdHVzKEh0dHBTdGF0dXMuVU5BVVRIT1JJWkVEKS5qc29uKGh0dHBSZXNwb25zZUVycm9yKTtcbiAgICB9XG59XG4iLCJpbXBvcnQge0FyZ3VtZW50c0hvc3QsIENhdGNoLCBFeGNlcHRpb25GaWx0ZXIsIEh0dHBTdGF0dXN9IGZyb20gXCJAbmVzdGpzL2NvbW1vblwiO1xuaW1wb3J0IHtSZXF1ZXN0LCBSZXNwb25zZX0gZnJvbSBcImV4cHJlc3NcIjtcbmltcG9ydCB7SHR0cFJlc3BvbnNlRXJyb3J9IGZyb20gXCIuL0h0dHBSZXNwb25zZUVycm9yXCI7XG5cbmV4cG9ydCBjbGFzcyBDb25mbGljdEVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICAgIHJlYWRvbmx5IHN0YXR1czogbnVtYmVyO1xuICAgIHJlYWRvbmx5IGNvZGU6IHN0cmluZztcblxuICAgIGNvbnN0cnVjdG9yKG1lc3NhZ2UgPSBcIkNvbmZsaWN0XCIpIHtcbiAgICAgICAgc3VwZXIobWVzc2FnZSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiQ29uZmxpY3RFcnJvclwiO1xuICAgICAgICB0aGlzLnN0YXR1cyA9IDQwOTtcbiAgICAgICAgdGhpcy5jb2RlID0gXCJDT05GTElDVFwiO1xuXG4gICAgICAgIE9iamVjdC5zZXRQcm90b3R5cGVPZih0aGlzLCBDb25mbGljdEVycm9yLnByb3RvdHlwZSk7XG4gICAgfVxufVxuXG5AQ2F0Y2goQ29uZmxpY3RFcnJvcilcbmV4cG9ydCBjbGFzcyBDb25mbGljdEV4Y2VwdGlvbkZpbHRlciBpbXBsZW1lbnRzIEV4Y2VwdGlvbkZpbHRlciB7XG4gICAgY2F0Y2goZXhjZXB0aW9uOiBDb25mbGljdEVycm9yLCBob3N0OiBBcmd1bWVudHNIb3N0KSB7XG4gICAgICAgIGNvbnN0IGN0eCA9IGhvc3Quc3dpdGNoVG9IdHRwKCk7XG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gY3R4LmdldFJlc3BvbnNlPFJlc3BvbnNlPigpO1xuICAgICAgICBjb25zdCByZXF1ZXN0ID0gY3R4LmdldFJlcXVlc3Q8UmVxdWVzdD4oKTtcblxuICAgICAgICBjb25zdCBodHRwUmVzcG9uc2VFcnJvciA9IG5ldyBIdHRwUmVzcG9uc2VFcnJvcihyZXF1ZXN0LCB7XG4gICAgICAgICAgICBzdGF0dXM6IEh0dHBTdGF0dXMuQ09ORkxJQ1QsXG4gICAgICAgICAgICBtZXNzYWdlOiBleGNlcHRpb24ubWVzc2FnZSxcbiAgICAgICAgICAgIGVycm9yOiBcIkNPTkZMSUNUXCJcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmVzcG9uc2Uuc3RhdHVzKGh0dHBSZXNwb25zZUVycm9yLnN0YXR1cykuanNvbihodHRwUmVzcG9uc2VFcnJvcik7XG4gICAgfVxufVxuIiwiaW1wb3J0IHtBcmd1bWVudHNIb3N0LCBDYXRjaCwgRXhjZXB0aW9uRmlsdGVyLCBIdHRwRXhjZXB0aW9uLCBIdHRwU3RhdHVzfSBmcm9tIFwiQG5lc3Rqcy9jb21tb25cIjtcbmltcG9ydCB7UmVxdWVzdCwgUmVzcG9uc2V9IGZyb20gXCJleHByZXNzXCI7XG5pbXBvcnQge0h0dHBSZXNwb25zZUVycm9yfSBmcm9tIFwiLi9IdHRwUmVzcG9uc2VFcnJvclwiO1xuXG5AQ2F0Y2goKVxuZXhwb3J0IGNsYXNzIEdsb2JhbEV4Y2VwdGlvbkZpbHRlciBpbXBsZW1lbnRzIEV4Y2VwdGlvbkZpbHRlciB7XG4gICAgY2F0Y2goZXhjZXB0aW9uOiB1bmtub3duLCBob3N0OiBBcmd1bWVudHNIb3N0KSB7XG4gICAgICAgIGNvbnN0IGN0eCA9IGhvc3Quc3dpdGNoVG9IdHRwKCk7XG4gICAgICAgIGNvbnN0IHJlcXVlc3QgPSBjdHguZ2V0UmVxdWVzdDxSZXF1ZXN0PigpO1xuICAgICAgICBjb25zdCByZXNwb25zZSA9IGN0eC5nZXRSZXNwb25zZTxSZXNwb25zZT4oKTtcblxuICAgICAgICBsZXQgc3RhdHVzID0gSHR0cFN0YXR1cy5JTlRFUk5BTF9TRVJWRVJfRVJST1I7XG4gICAgICAgIGxldCBtZXNzYWdlID0gXCJJbnRlcm5hbCBTZXJ2ZXIgRXJyb3JcIjtcbiAgICAgICAgbGV0IGVycm9yOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgICAgICAgaWYgKGV4Y2VwdGlvbiBpbnN0YW5jZW9mIEh0dHBFeGNlcHRpb24pIHtcbiAgICAgICAgICAgIGNvbnN0IHJlczogYW55ID0gZXhjZXB0aW9uLmdldFJlc3BvbnNlKCk7XG4gICAgICAgICAgICBzdGF0dXMgPSBleGNlcHRpb24uZ2V0U3RhdHVzKCk7XG4gICAgICAgICAgICBtZXNzYWdlID0gKHJlcz8ubWVzc2FnZSB8fCBleGNlcHRpb24ubWVzc2FnZSkgPz8gbWVzc2FnZTtcbiAgICAgICAgICAgIGVycm9yID0gcmVzPy5lcnJvciA/PyBleGNlcHRpb24ubmFtZTtcbiAgICAgICAgfSBlbHNlIGlmIChleGNlcHRpb24gaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICAgICAgbWVzc2FnZSA9IGV4Y2VwdGlvbi5tZXNzYWdlO1xuICAgICAgICAgICAgZXJyb3IgPSBleGNlcHRpb24ubmFtZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGh0dHBSZXNwb25zZUVycm9yID0gbmV3IEh0dHBSZXNwb25zZUVycm9yKHJlcXVlc3QsIHtzdGF0dXMsIG1lc3NhZ2UsIGVycm9yfSk7XG4gICAgICAgIHJlc3BvbnNlLnN0YXR1cyhodHRwUmVzcG9uc2VFcnJvci5zdGF0dXMpLmpzb24oaHR0cFJlc3BvbnNlRXJyb3IpO1xuICAgIH1cbn1cbiIsImltcG9ydCB7QXJndW1lbnRzSG9zdCwgQ2F0Y2gsIEV4Y2VwdGlvbkZpbHRlciwgSHR0cEV4Y2VwdGlvbn0gZnJvbSBcIkBuZXN0anMvY29tbW9uXCI7XG5pbXBvcnQge1JlcXVlc3QsIFJlc3BvbnNlfSBmcm9tIFwiZXhwcmVzc1wiO1xuaW1wb3J0IHtIdHRwUmVzcG9uc2VFcnJvcn0gZnJvbSBcIi4vSHR0cFJlc3BvbnNlRXJyb3JcIjtcblxuQENhdGNoKEh0dHBFeGNlcHRpb24pXG5leHBvcnQgY2xhc3MgSHR0cEV4Y2VwdGlvbkZpbHRlciBpbXBsZW1lbnRzIEV4Y2VwdGlvbkZpbHRlciB7XG4gICAgY2F0Y2goZXhjZXB0aW9uOiBIdHRwRXhjZXB0aW9uLCBob3N0OiBBcmd1bWVudHNIb3N0KSB7XG4gICAgICAgIGNvbnN0IGN0eCA9IGhvc3Quc3dpdGNoVG9IdHRwKCk7XG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gY3R4LmdldFJlc3BvbnNlPFJlc3BvbnNlPigpO1xuICAgICAgICBjb25zdCByZXF1ZXN0ID0gY3R4LmdldFJlcXVlc3Q8UmVxdWVzdD4oKTtcbiAgICAgICAgY29uc3Qgc3RhdHVzID0gZXhjZXB0aW9uLmdldFN0YXR1cygpO1xuXG4gICAgICAgIGNvbnN0IGh0dHBSZXNwb25zZUVycm9yID0gbmV3IEh0dHBSZXNwb25zZUVycm9yKHJlcXVlc3QsIHtcbiAgICAgICAgICAgIHN0YXR1cyxcbiAgICAgICAgICAgIG1lc3NhZ2U6IGV4Y2VwdGlvbi5tZXNzYWdlLFxuICAgICAgICAgICAgZXJyb3I6IGV4Y2VwdGlvbi5uYW1lXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJlc3BvbnNlLnN0YXR1cyhodHRwUmVzcG9uc2VFcnJvci5zdGF0dXMpLmpzb24oaHR0cFJlc3BvbnNlRXJyb3IpO1xuICAgIH1cbn1cbiIsImltcG9ydCB7IEFyZ3VtZW50c0hvc3QsIENhdGNoLCBFeGNlcHRpb25GaWx0ZXIsIEh0dHBTdGF0dXMgfSBmcm9tIFwiQG5lc3Rqcy9jb21tb25cIjtcbmltcG9ydCB7IFJlcXVlc3QsIFJlc3BvbnNlIH0gZnJvbSBcImV4cHJlc3NcIjtcbmltcG9ydCB7IEh0dHBSZXNwb25zZUVycm9yIH0gZnJvbSBcIi4vSHR0cFJlc3BvbnNlRXJyb3JcIjtcblxuZXhwb3J0IGNsYXNzIE5vdEZvdW5kRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG5cdHJlYWRvbmx5IHN0YXR1czogbnVtYmVyO1xuXHRyZWFkb25seSBjb2RlOiBzdHJpbmc7XG5cblx0Y29uc3RydWN0b3IobWVzc2FnZSA9IFwiUmVzb3VyY2Ugbm90IGZvdW5kXCIpIHtcblx0XHRzdXBlcihtZXNzYWdlKTtcblx0XHR0aGlzLm5hbWUgPSBcIk5vdEZvdW5kRXJyb3JcIjtcblx0XHR0aGlzLnN0YXR1cyA9IDQwNDtcblx0XHR0aGlzLmNvZGUgPSBcIk5PVF9GT1VORFwiO1xuXG5cdFx0T2JqZWN0LnNldFByb3RvdHlwZU9mKHRoaXMsIE5vdEZvdW5kRXJyb3IucHJvdG90eXBlKTtcblx0fVxufVxuXG5AQ2F0Y2goTm90Rm91bmRFcnJvcilcbmV4cG9ydCBjbGFzcyBOb3RGb3VuZEV4Y2VwdGlvbkZpbHRlciBpbXBsZW1lbnRzIEV4Y2VwdGlvbkZpbHRlciB7XG5cdGNhdGNoKGV4Y2VwdGlvbjogTm90Rm91bmRFcnJvciwgaG9zdDogQXJndW1lbnRzSG9zdCkge1xuXHRcdGNvbnN0IGN0eCA9IGhvc3Quc3dpdGNoVG9IdHRwKCk7XG5cdFx0Y29uc3QgcmVzcG9uc2UgPSBjdHguZ2V0UmVzcG9uc2U8UmVzcG9uc2U+KCk7XG5cdFx0Y29uc3QgcmVxdWVzdCA9IGN0eC5nZXRSZXF1ZXN0PFJlcXVlc3Q+KCk7XG5cblx0XHRjb25zdCBodHRwUmVzcG9uc2VFcnJvciA9IG5ldyBIdHRwUmVzcG9uc2VFcnJvcihyZXF1ZXN0LCB7XG5cdFx0XHRzdGF0dXM6IEh0dHBTdGF0dXMuTk9UX0ZPVU5ELFxuXHRcdFx0bWVzc2FnZTogZXhjZXB0aW9uLm1lc3NhZ2UsXG5cdFx0XHRlcnJvcjogXCJOT1RfRk9VTkRcIixcblx0XHR9KTtcblxuXHRcdHJlc3BvbnNlLnN0YXR1cyhodHRwUmVzcG9uc2VFcnJvci5zdGF0dXMpLmpzb24oaHR0cFJlc3BvbnNlRXJyb3IpO1xuXHR9XG59XG4iLCJpbXBvcnQge0FyZ3VtZW50c0hvc3QsIENhdGNoLCBFeGNlcHRpb25GaWx0ZXIsIEh0dHBTdGF0dXN9IGZyb20gXCJAbmVzdGpzL2NvbW1vblwiO1xuaW1wb3J0IHtSZXF1ZXN0LCBSZXNwb25zZX0gZnJvbSBcImV4cHJlc3NcIjtcbmltcG9ydCB7SHR0cFJlc3BvbnNlRXJyb3J9IGZyb20gXCIuL0h0dHBSZXNwb25zZUVycm9yXCI7XG5cbmV4cG9ydCBjbGFzcyBWYWxpZGF0aW9uRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gICAgcmVhZG9ubHkgc3RhdHVzOiBudW1iZXI7XG4gICAgcmVhZG9ubHkgY29kZTogc3RyaW5nO1xuXG4gICAgY29uc3RydWN0b3IobWVzc2FnZSA9IFwiVmFsaWRhdGlvbiBmYWlsZWRcIikge1xuICAgICAgICBzdXBlcihtZXNzYWdlKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJWYWxpZGF0aW9uRXJyb3JcIjtcbiAgICAgICAgdGhpcy5zdGF0dXMgPSA0MjI7XG4gICAgICAgIHRoaXMuY29kZSA9IFwiVkFMSURBVElPTl9FUlJPUlwiO1xuXG4gICAgICAgIE9iamVjdC5zZXRQcm90b3R5cGVPZih0aGlzLCBWYWxpZGF0aW9uRXJyb3IucHJvdG90eXBlKTtcbiAgICB9XG59XG5cbkBDYXRjaChWYWxpZGF0aW9uRXJyb3IpXG5leHBvcnQgY2xhc3MgVmFsaWRhdGlvbkV4Y2VwdGlvbkZpbHRlciBpbXBsZW1lbnRzIEV4Y2VwdGlvbkZpbHRlciB7XG4gICAgY2F0Y2goZXhjZXB0aW9uOiBWYWxpZGF0aW9uRXJyb3IsIGhvc3Q6IEFyZ3VtZW50c0hvc3QpIHtcbiAgICAgICAgY29uc3QgY3R4ID0gaG9zdC5zd2l0Y2hUb0h0dHAoKTtcbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBjdHguZ2V0UmVzcG9uc2U8UmVzcG9uc2U+KCk7XG4gICAgICAgIGNvbnN0IHJlcXVlc3QgPSBjdHguZ2V0UmVxdWVzdDxSZXF1ZXN0PigpO1xuXG4gICAgICAgIGNvbnN0IGh0dHBSZXNwb25zZUVycm9yID0gbmV3IEh0dHBSZXNwb25zZUVycm9yKHJlcXVlc3QsIHtcbiAgICAgICAgICAgIHN0YXR1czogSHR0cFN0YXR1cy5VTlBST0NFU1NBQkxFX0VOVElUWSxcbiAgICAgICAgICAgIG1lc3NhZ2U6IGV4Y2VwdGlvbi5tZXNzYWdlLFxuICAgICAgICAgICAgZXJyb3I6IFwiVkFMSURBVElPTl9FUlJPUlwiXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJlc3BvbnNlLnN0YXR1cyhodHRwUmVzcG9uc2VFcnJvci5zdGF0dXMpLmpzb24oaHR0cFJlc3BvbnNlRXJyb3IpO1xuICAgIH1cbn1cbiIsImltcG9ydCB7IFNlY3VyaXR5U2NoZW1lT2JqZWN0IH0gZnJvbSBcIkBuZXN0anMvc3dhZ2dlci9kaXN0L2ludGVyZmFjZXMvb3Blbi1hcGktc3BlYy5pbnRlcmZhY2VcIjtcbmltcG9ydCB7IENvbnN0cnVjdG9yIH0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0aW9uXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgU3dhZ2dlck9wdGlvbnMge1xuICB0aXRsZTogc3RyaW5nO1xuICBkZXNjcmlwdGlvbjogc3RyaW5nO1xuICB2ZXJzaW9uPzogc3RyaW5nO1xuICBhc3NldHNQYXRoPzogc3RyaW5nO1xuICBmYXZpY29uRmlsZVBhdGg/OiBzdHJpbmc7XG4gIHRvcGJhckljb25GaWxlUGF0aD86IHN0cmluZztcbiAgcGVyc2lzdEF1dGhvcml6YXRpb24/OiBib29sZWFuO1xuICBwYXRoOiBzdHJpbmc7XG4gIGF1dGg/OiBTZWN1cml0eVNjaGVtZU9iamVjdDtcbiAgdG9wYmFyQmdDb2xvcj86IHN0cmluZztcbiAgZXh0cmFNb2RlbHM/OiBDb25zdHJ1Y3RvcltdO1xufVxuXG5leHBvcnQgY29uc3QgU1dBR0dFUl9VSV9DT05TVEFOVFM6IFN3YWdnZXJPcHRpb25zID0ge1xuICB0aXRsZTogXCJTd2FnZ2VyIHwgT3BlbkFQSSBTcGVjaWZpY2F0aW9uIChPQVMpXCIsXG4gIGRlc2NyaXB0aW9uOiBcIlN0YW5kYXJkaXplZCBmb3JtYXQgZm9yIGRlc2NyaWJpbmcgUkVTVGZ1bCBBUElzXCIsXG4gIHZlcnNpb246IFwiMC4wLjFcIixcbiAgcGF0aDogXCJkb2NzXCIsXG4gIGZhdmljb25GaWxlUGF0aDogXCJcIixcbiAgdG9wYmFySWNvbkZpbGVQYXRoOiBcIlwiLFxuICBhdXRoOiB7XG4gICAgdHlwZTogXCJodHRwXCIsXG4gICAgc2NoZW1lOiBcImJlYXJlclwiLFxuICAgIGJlYXJlckZvcm1hdDogXCJKV1RcIixcbiAgICBuYW1lOiBcIkF1dGhvcml6YXRpb25cIixcbiAgICBkZXNjcmlwdGlvbjogXCJFbnRlciBKV1QgdG9rZW5cIixcbiAgICBpbjogXCJoZWFkZXJcIixcbiAgfSxcbiAgcGVyc2lzdEF1dGhvcml6YXRpb246IHRydWUsXG4gIHRvcGJhckJnQ29sb3I6IFwiIzAwMDAwMFwiLFxufTtcbiIsImltcG9ydCB7IFNXQUdHRVJfVUlfQ09OU1RBTlRTIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyByZWFkRmlsZVN5bmMgfSBmcm9tIFwiZnNcIjtcbmltcG9ydCAqIGFzIHBhdGggZnJvbSBcInBhdGhcIjtcblxuZXhwb3J0IGludGVyZmFjZSBTd2FnZ2VyVUlPcHRpb25zIHtcbiAgdGl0bGU/OiBzdHJpbmc7XG4gIHBhdGg/OiBzdHJpbmc7XG4gIHBlcnNpc3RBdXRob3JpemF0aW9uOiBib29sZWFuO1xuICBhc3NldHNQYXRoPzogc3RyaW5nO1xuICBmYXZpY29uUGF0aD86IHN0cmluZztcbiAgdG9wYmFySWNvblBhdGg/OiBzdHJpbmc7XG4gIHRvcGJhckJnQ29sb3I/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBjbGFzcyBTd2FnZ2VyQ3VzdG9tVUkge1xuICByZWFkb25seSBvcHRpb25zOiBTd2FnZ2VyVUlPcHRpb25zO1xuICAvLyBwcml2YXRlIHJlYWRvbmx5IGFzc2V0c1BhdGg6IHN0cmluZyA9IHBhdGguam9pbihcbiAgLy8gICBfX2Rpcm5hbWUsXG4gIC8vICAgXCIuLlwiLFxuICAvLyAgIFwiLi5cIixcbiAgLy8gICBcIndvcmtkb2NzXCIsXG4gIC8vICAgXCJhc3NldHNcIlxuICAvLyApO1xuXG4gIGNvbnN0cnVjdG9yKG9wdGlvbnM6IFN3YWdnZXJVSU9wdGlvbnMpIHtcbiAgICB0aGlzLm9wdGlvbnMgPSB7XG4gICAgICAuLi5vcHRpb25zLFxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIGN1c3RvbUNTUygpIHtcbiAgICBsZXQgY3NzID0gXCJcIjtcbiAgICBpZiAodGhpcy5vcHRpb25zLnRvcGJhckljb25QYXRoKSB7XG4gICAgICBjb25zdCBpbWcgPSB0aGlzLmI2NCh0aGlzLm9wdGlvbnMudG9wYmFySWNvblBhdGgpO1xuICAgICAgY3NzICs9IGAudG9wYmFyLXdyYXBwZXIgeyBjb250ZW50OiB1cmwoJ2RhdGE6aW1hZ2UvcG5nO2Jhc2U2NCwke2ltZ30nKTsgd2lkdGg6IDIwMHB4OyBoZWlnaHQ6IGF1dG87IH1cXG5gO1xuICAgIH1cbiAgICByZXR1cm4gKFxuICAgICAgY3NzICtcbiAgICAgIGBcbiAgICAgICAgLnRvcGJhci13cmFwcGVyIHN2ZyB7IHZpc2liaWxpdHk6IGhpZGRlbjsgfVxuICAgICAgICAuc3dhZ2dlci11aSAudG9wYmFyIHsgYmFja2dyb3VuZC1jb2xvcjogJHt0aGlzLm9wdGlvbnMudG9wYmFyQmdDb2xvciB8fCBTV0FHR0VSX1VJX0NPTlNUQU5UUy50b3BiYXJCZ0NvbG9yfTsgfVxuICAgICAgYFxuICAgICk7XG4gIH1cblxuICBnZXRDdXN0b21PcHRpb25zKCkge1xuICAgIGNvbnN0IGZhdmljb246IFJlY29yZDxzdHJpbmcsIGFueT4gPSB7fTtcbiAgICBpZiAodGhpcy5vcHRpb25zLmZhdmljb25QYXRoKSB7XG4gICAgICBmYXZpY29uW1wiY3VzdG9tZmF2SWNvblwiXSA9IHRoaXMuYjY0KHRoaXMub3B0aW9ucy5mYXZpY29uUGF0aCwgdHJ1ZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGN1c3RvbVNpdGVUaXRsZTogdGhpcy5vcHRpb25zLnRpdGxlLFxuICAgICAgLi4uZmF2aWNvbixcbiAgICAgIGN1c3RvbUNzczogdGhpcy5jdXN0b21DU1MoKSxcbiAgICAgIHN3YWdnZXJPcHRpb25zOiB7XG4gICAgICAgIHBlcnNpc3RBdXRob3JpemF0aW9uOiB0aGlzLm9wdGlvbnMucGVyc2lzdEF1dGhvcml6YXRpb24sXG4gICAgICB9LFxuICAgICAganNvbkRvY3VtZW50VXJsOiB0aGlzLm9wdGlvbnMucGF0aFxuICAgICAgICA/IGAke3RoaXMub3B0aW9ucy5wYXRofS9zcGVjLmpzb25gXG4gICAgICAgIDogdW5kZWZpbmVkLFxuICAgICAgeWFtbERvY3VtZW50VXJsOiB0aGlzLm9wdGlvbnMucGF0aFxuICAgICAgICA/IGAke3RoaXMub3B0aW9ucy5wYXRofS9zcGVjLnlhbWxgXG4gICAgICAgIDogdW5kZWZpbmVkLFxuICAgIH07XG4gIH1cblxuICBiNjQoZmlsZTogc3RyaW5nLCBpbWc6IGJvb2xlYW4gPSBmYWxzZSkge1xuICAgIGNvbnN0IGZpbGVQYXRoID0gcGF0aC5qb2luKHRoaXMub3B0aW9ucy5hc3NldHNQYXRoIHx8IFwiXCIsIGZpbGUpO1xuICAgIGNvbnN0IGI2NCA9IHJlYWRGaWxlU3luYyhmaWxlUGF0aCwgeyBlbmNvZGluZzogXCJiYXNlNjRcIiB9KTtcbiAgICByZXR1cm4gaW1nID8gXCJkYXRhOmltYWdlL3BuZztiYXNlNjQsXCIgKyBiNjQgOiBiNjQ7XG4gIH1cbn1cbiIsImltcG9ydCB7IElOZXN0QXBwbGljYXRpb24gfSBmcm9tIFwiQG5lc3Rqcy9jb21tb25cIjtcbmltcG9ydCB7IERvY3VtZW50QnVpbGRlciwgU3dhZ2dlck1vZHVsZSB9IGZyb20gXCJAbmVzdGpzL3N3YWdnZXJcIjtcbmltcG9ydCB7IFN3YWdnZXJDdXN0b21VSSB9IGZyb20gXCIuL1N3YWdnZXJDdXN0b21VSVwiO1xuaW1wb3J0IHsgU1dBR0dFUl9VSV9DT05TVEFOVFMsIFN3YWdnZXJPcHRpb25zIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5cbmV4cG9ydCBjbGFzcyBTd2FnZ2VyQnVpbGRlciB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgYXBwOiBJTmVzdEFwcGxpY2F0aW9uLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgb3B0aW9uczogU3dhZ2dlck9wdGlvbnNcbiAgKSB7fVxuXG4gIHByaXZhdGUgY3JlYXRlRG9jdW1lbnQoKSB7XG4gICAgY29uc3QgZGVzY3JpcHRpb24gPSB0aGlzLm9wdGlvbnMucGF0aFxuICAgICAgPyB0aGlzLm9wdGlvbnMuZGVzY3JpcHRpb24gK1xuICAgICAgICBcIlwiICtcbiAgICAgICAgYDxicj48YnI+PGEgaHJlZj1cIiR7dGhpcy5vcHRpb25zLnBhdGh9L3NwZWMuanNvblwiPk9wZW5BUEkgSlNPTiBTcGVjPC9hPiB8IGAgK1xuICAgICAgICBgPGEgaHJlZj1cIiR7dGhpcy5vcHRpb25zLnBhdGh9L3NwZWMueWFtbFwiPk9wZW5BUEkgWUFNTCBTcGVjPC9hPmBcbiAgICAgIDogdGhpcy5vcHRpb25zLmRlc2NyaXB0aW9uO1xuXG4gICAgY29uc3QgY29uZmlnID0gbmV3IERvY3VtZW50QnVpbGRlcigpXG4gICAgICAuc2V0VGl0bGUodGhpcy5vcHRpb25zLnRpdGxlKVxuICAgICAgLnNldERlc2NyaXB0aW9uKGRlc2NyaXB0aW9uKVxuICAgICAgLnNldFZlcnNpb24odGhpcy5vcHRpb25zLnZlcnNpb24gfHwgXCIwLjAuMVwiKVxuICAgICAgLmFkZEJlYXJlckF1dGgodGhpcy5vcHRpb25zLmF1dGggfHwgU1dBR0dFUl9VSV9DT05TVEFOVFMuYXV0aClcbiAgICAgIC5idWlsZCgpO1xuXG4gICAgcmV0dXJuIFN3YWdnZXJNb2R1bGUuY3JlYXRlRG9jdW1lbnQodGhpcy5hcHAsIGNvbmZpZywge1xuICAgICAgZXh0cmFNb2RlbHM6IHRoaXMub3B0aW9ucy5leHRyYU1vZGVscyB8fCBbXSxcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBzZXR1cFN3YWdnZXIoKSB7XG4gICAgY29uc3QgZG9jdW1lbnQgPSB0aGlzLmNyZWF0ZURvY3VtZW50KCk7XG4gICAgY29uc3Qgc3dhZ2dlclVJID0gbmV3IFN3YWdnZXJDdXN0b21VSSh7XG4gICAgICB0aXRsZTogdGhpcy5vcHRpb25zLnRpdGxlLFxuICAgICAgcGF0aDogdGhpcy5vcHRpb25zLnBhdGggfHwgU1dBR0dFUl9VSV9DT05TVEFOVFMucGF0aCxcbiAgICAgIHBlcnNpc3RBdXRob3JpemF0aW9uOiB0aGlzLm9wdGlvbnMucGVyc2lzdEF1dGhvcml6YXRpb24gPz8gdHJ1ZSxcbiAgICAgIGFzc2V0c1BhdGg6IHRoaXMub3B0aW9ucy5hc3NldHNQYXRoLFxuICAgICAgZmF2aWNvblBhdGg6IHRoaXMub3B0aW9ucy5mYXZpY29uRmlsZVBhdGgsXG4gICAgICB0b3BiYXJJY29uUGF0aDogdGhpcy5vcHRpb25zLnRvcGJhckljb25GaWxlUGF0aCxcbiAgICAgIHRvcGJhckJnQ29sb3I6IHRoaXMub3B0aW9ucy50b3BiYXJCZ0NvbG9yLFxuICAgIH0pO1xuICAgIFN3YWdnZXJNb2R1bGUuc2V0dXAoXG4gICAgICB0aGlzLm9wdGlvbnMucGF0aCB8fCBTV0FHR0VSX1VJX0NPTlNUQU5UUy5wYXRoLFxuICAgICAgdGhpcy5hcHAsXG4gICAgICBkb2N1bWVudCxcbiAgICAgIHtcbiAgICAgICAgLi4uc3dhZ2dlclVJLmdldEN1c3RvbU9wdGlvbnMoKSxcbiAgICAgIH1cbiAgICApO1xuICB9XG5cbiAgLy8gcHJpdmF0ZSBnZXRWZXJzaW9uKCkge1xuICAvLyAgIC8vIGNvbnN0IHBhY2thZ2VKc29uID0gcGF0aC5qb2luKF9fZGlybmFtZSwgXCIuLlwiLCBcIi4uXCIsIFwicGFja2FnZS5qc29uXCIpO1xuICAvLyAgIC8vIGNvbnN0IHt2ZXJzaW9ufSA9IHJlcXVpcmUocGFja2FnZUpzb24pO1xuICAvLyAgIHJldHVybiBcInZlcnNpb25cIjtcbiAgLy8gfVxufVxuIiwiaW1wb3J0IHtcbiAgRXhjZXB0aW9uRmlsdGVyLFxuICBJTmVzdEFwcGxpY2F0aW9uLFxuICBMb2dnZXIsXG4gIE5lc3RJbnRlcmNlcHRvcixcbiAgUGlwZVRyYW5zZm9ybSxcbn0gZnJvbSBcIkBuZXN0anMvY29tbW9uXCI7XG5pbXBvcnQge1xuICBBdXRob3JpemF0aW9uRXhjZXB0aW9uRmlsdGVyLFxuICBDb25mbGljdEV4Y2VwdGlvbkZpbHRlcixcbiAgR2xvYmFsRXhjZXB0aW9uRmlsdGVyLFxuICBIdHRwRXhjZXB0aW9uRmlsdGVyLFxuICBOb3RGb3VuZEV4Y2VwdGlvbkZpbHRlcixcbiAgVmFsaWRhdGlvbkV4Y2VwdGlvbkZpbHRlcixcbn0gZnJvbSBcIi4vZXhjZXB0aW9uc1wiO1xuaW1wb3J0IHsgU3dhZ2dlckJ1aWxkZXIgfSBmcm9tIFwiLi9vcGVuYXBpXCI7XG5pbXBvcnQgeyBDb3JzT3B0aW9ucyB9IGZyb20gXCJAbmVzdGpzL2NvbW1vbi9pbnRlcmZhY2VzL2V4dGVybmFsL2NvcnMtb3B0aW9ucy5pbnRlcmZhY2VcIjtcbmltcG9ydCB7IENvcnNFcnJvciB9IGZyb20gXCIuL2Vycm9yc1wiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvblxuICogRGVmaW5lcyBhbGwgY3VzdG9taXphYmxlIHBhcmFtZXRlcnMgZm9yIFN3YWdnZXIgc2V0dXAuXG4gKlxuICogQHN1bW1hcnlcbiAqIFRoaXMgaW50ZXJmYWNlIGFsbG93cyBkZXZlbG9wZXJzIHRvIGN1c3RvbWl6ZSBob3cgU3dhZ2dlciBVSSBpcyBjb25maWd1cmVkXG4gKiB3aXRoaW4gdGhlIE5lc3RKUyBhcHBsaWNhdGlvbi4gSXQgaW5jbHVkZXMgcGFyYW1ldGVycyBmb3IgdGl0bGVzLCBwYXRocyxcbiAqIGNvbG9yIHNjaGVtZXMsIGFuZCBhc3NldCBwYXRocyB0byB0YWlsb3IgdGhlIEFQSSBkb2N1bWVudGF0aW9uIGV4cGVyaWVuY2UuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHRpdGxlIC0gVGl0bGUgZGlzcGxheWVkIGluIFN3YWdnZXIgVUkuXG4gKiBAcGFyYW0ge3N0cmluZ30gZGVzY3JpcHRpb24gLSBEZXNjcmlwdGlvbiBzaG93biBiZWxvdyB0aGUgdGl0bGUuXG4gKiBAcGFyYW0ge3N0cmluZ30gdmVyc2lvbiAtIEFQSSB2ZXJzaW9uIGRpc3BsYXllZCBpbiB0aGUgZG9jdW1lbnRhdGlvbi5cbiAqIEBwYXJhbSB7c3RyaW5nfSBbcGF0aF0gLSBPcHRpb25hbCBwYXRoIHdoZXJlIFN3YWdnZXIgd2lsbCBiZSBhdmFpbGFibGUuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtwZXJzaXN0QXV0aG9yaXphdGlvbl0gLSBXaGV0aGVyIGF1dGhvcml6YXRpb24gdG9rZW5zIHBlcnNpc3QgYWNyb3NzIHJlbG9hZHMuXG4gKiBAcGFyYW0ge3N0cmluZ30gW2Fzc2V0c1BhdGhdIC0gUGF0aCB0byBjdXN0b20gYXNzZXRzIGZvciBTd2FnZ2VyIFVJLlxuICogQHBhcmFtIHtzdHJpbmd9IFt0b3BiYXJCZ0NvbG9yXSAtIEN1c3RvbSBiYWNrZ3JvdW5kIGNvbG9yIGZvciB0aGUgU3dhZ2dlciB0b3AgYmFyLlxuICogQHBhcmFtIHtzdHJpbmd9IFt0b3BiYXJJY29uUGF0aF0gLSBQYXRoIHRvIGEgY3VzdG9tIGljb24gZGlzcGxheWVkIGluIHRoZSB0b3AgYmFyLlxuICogQHBhcmFtIHtzdHJpbmd9IFtmYXZpY29uUGF0aF0gLSBQYXRoIHRvIGEgY3VzdG9tIGZhdmljb24uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU3dhZ2dlclNldHVwT3B0aW9ucyB7XG4gIHRpdGxlOiBzdHJpbmc7XG4gIGRlc2NyaXB0aW9uOiBzdHJpbmc7XG4gIHZlcnNpb246IHN0cmluZztcbiAgcGF0aD86IHN0cmluZztcbiAgcGVyc2lzdEF1dGhvcml6YXRpb24/OiBib29sZWFuO1xuICBhc3NldHNQYXRoPzogc3RyaW5nO1xuICB0b3BiYXJCZ0NvbG9yPzogc3RyaW5nO1xuICB0b3BiYXJJY29uUGF0aD86IHN0cmluZztcbiAgZmF2aWNvblBhdGg/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uXG4gKiBBIGZsdWVudCwgc3RhdGljIGJvb3RzdHJhcCBjbGFzcyBmb3IgaW5pdGlhbGl6aW5nIGFuZCBjb25maWd1cmluZyBhIE5lc3RKUyBhcHBsaWNhdGlvbi5cbiAqXG4gKiBAc3VtbWFyeVxuICogVGhlIGBOZXN0Qm9vdHN0cmFwZXJgIGNsYXNzIHByb3ZpZGVzIGEgY2hhaW5hYmxlIEFQSSBmb3IgY29uZmlndXJpbmdcbiAqIGEgTmVzdEpTIGFwcGxpY2F0aW9uIGluc3RhbmNlLiBJdCBpbmNsdWRlcyBidWlsdC1pbiBtZXRob2RzIGZvciBlbmFibGluZ1xuICogQ09SUywgSGVsbWV0IHNlY3VyaXR5LCBTd2FnZ2VyIGRvY3VtZW50YXRpb24sIGdsb2JhbCBwaXBlcywgZmlsdGVycyxcbiAqIGludGVyY2VwdG9ycywgYW5kIHN0YXJ0aW5nIHRoZSBzZXJ2ZXIuXG4gKlxuICogVGhpcyBjbGFzcyBwcm9tb3RlcyBjb25zaXN0ZW5jeSBhbmQgcmVkdWNlcyByZXBldGl0aXZlIHNldHVwIGNvZGVcbiAqIGFjcm9zcyBtdWx0aXBsZSBOZXN0SlMgcHJvamVjdHMuXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHRzXG4gKiBpbXBvcnQgeyBOZXN0RmFjdG9yeSB9IGZyb20gXCJAbmVzdGpzL2NvcmVcIjtcbiAqIGltcG9ydCB7IEFwcE1vZHVsZSB9IGZyb20gXCIuL2FwcC5tb2R1bGVcIjtcbiAqIGltcG9ydCB7IE15TG9nZ2VyIH0gZnJvbSBcIi4vTXlMb2dnZXJcIjtcbiAqIGltcG9ydCB7IE5lc3RCb290c3RyYXBlciB9IGZyb20gXCJAZGVjYWYtdHMvZm9yLW5lc3RcIjtcbiAqXG4gKiBhc3luYyBmdW5jdGlvbiBib290c3RyYXAoKSB7XG4gKiAgIGNvbnN0IGFwcCA9IGF3YWl0IE5lc3RGYWN0b3J5LmNyZWF0ZShBcHBNb2R1bGUpO1xuICpcbiAqICAgYXdhaXQgTmVzdEJvb3RzdHJhcGVyXG4gKiAgICAgLmluaXRpYWxpemUoYXBwKVxuICogICAgIC5lbmFibGVMb2dnZXIobmV3IE15TG9nZ2VyKCkpXG4gKiAgICAgLmVuYWJsZUNvcnMoW1wiaHR0cDovL2xvY2FsaG9zdDo0MjAwXCJdKVxuICogICAgIC51c2VIZWxtZXQoKVxuICogICAgIC5zZXR1cFN3YWdnZXIoe1xuICogICAgICAgdGl0bGU6IFwiT3BlbkFQSSBieSBUcmFkZU1hcmvihKJcIixcbiAqICAgICAgIGRlc2NyaXB0aW9uOiBcIlRyYWRlTWFya+KEoiBBUEkgZG9jdW1lbnRhdGlvblwiLFxuICogICAgICAgdmVyc2lvbjogXCIxLjAuMFwiLFxuICogICAgICAgcGF0aDogXCJhcGlcIixcbiAqICAgICAgIHBlcnNpc3RBdXRob3JpemF0aW9uOiB0cnVlLFxuICogICAgICAgdG9wYmFyQmdDb2xvcjogXCIjMkMzRTUwXCIsXG4gKiAgICAgICB0b3BiYXJJY29uUGF0aDogXCIvYXNzZXRzL2xvZ28uc3ZnXCIsXG4gKiAgICAgICBmYXZpY29uUGF0aDogXCIvYXNzZXRzL2Zhdmljb24uaWNvXCJcbiAqICAgICB9KVxuICogICAgIC51c2VHbG9iYWxGaWx0ZXJzKClcbiAqICAgICAudXNlR2xvYmFsUGlwZXMoLi4uKVxuICogICAgIC51c2VHbG9iYWxJbnRlcmNlcHRvcnMoLi4uKVxuICogICAgIC5zdGFydCgzMDAwKTtcbiAqIH1cbiAqXG4gKiBib290c3RyYXAoKTtcbiAqIGBgYFxuICogQGNsYXNzXG4gKi9cbmV4cG9ydCBjbGFzcyBOZXN0Qm9vdHN0cmFwZXIge1xuICBwcml2YXRlIHN0YXRpYyBhcHA6IElOZXN0QXBwbGljYXRpb247XG4gIHByaXZhdGUgc3RhdGljIF9sb2dnZXI6IExvZ2dlcjtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqIFJldHVybnMgdGhlIGN1cnJlbnQgbG9nZ2VyIGluc3RhbmNlLCBjcmVhdGluZyBhIGRlZmF1bHQgb25lIGlmIG5vdCBzZXQuXG4gICAqXG4gICAqIEBzdW1tYXJ5XG4gICAqIEVuc3VyZXMgdGhhdCBhIHZhbGlkIGBMb2dnZXJgIGluc3RhbmNlIGlzIGFsd2F5cyBhdmFpbGFibGVcbiAgICogZm9yIGxvZ2dpbmcgYm9vdHN0cmFwLXJlbGF0ZWQgbWVzc2FnZXMuXG4gICAqXG4gICAqIEByZXR1cm4ge0xvZ2dlcn0gVGhlIGFjdGl2ZSBsb2dnZXIgaW5zdGFuY2UuXG4gICAqL1xuICBwcml2YXRlIHN0YXRpYyBnZXQgbG9nZ2VyKCk6IExvZ2dlciB7XG4gICAgaWYgKCF0aGlzLl9sb2dnZXIpIHtcbiAgICAgIC8vIGZhbGxiYWNrXG4gICAgICB0aGlzLl9sb2dnZXIgPSBuZXcgTG9nZ2VyKFwiTmVzdEJvb3RzdHJhcFwiKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX2xvZ2dlcjtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogSW5pdGlhbGl6ZXMgdGhlIGJvb3RzdHJhcHBlciB3aXRoIGEgZ2l2ZW4gTmVzdEpTIGFwcGxpY2F0aW9uLlxuICAgKlxuICAgKiBAc3VtbWFyeVxuICAgKiBCaW5kcyB0aGUgcHJvdmlkZWQgTmVzdEpTIGFwcCBpbnN0YW5jZSB0byB0aGUgYm9vdHN0cmFwcGVyLCBlbmFibGluZ1xuICAgKiBjaGFpbmVkIGNvbmZpZ3VyYXRpb24gbWV0aG9kcy5cbiAgICpcbiAgICogQHBhcmFtIHtJTmVzdEFwcGxpY2F0aW9ufSBhcHAgLSBUaGUgTmVzdEpTIGFwcGxpY2F0aW9uIGluc3RhbmNlIHRvIGluaXRpYWxpemUuXG4gICAqIEByZXR1cm4ge3R5cGVvZiBOZXN0Qm9vdHN0cmFwZXJ9IFJldHVybnMgdGhlIGNsYXNzIGZvciBjaGFpbmluZyBjb25maWd1cmF0aW9uIG1ldGhvZHMuXG4gICAqL1xuICBzdGF0aWMgaW5pdGlhbGl6ZShhcHA6IElOZXN0QXBwbGljYXRpb24pIHtcbiAgICB0aGlzLmFwcCA9IGFwcDtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogRW5hYmxlcyBvciByZXBsYWNlcyB0aGUgZ2xvYmFsIGxvZ2dlciBmb3IgdGhlIE5lc3RKUyBhcHBsaWNhdGlvbi5cbiAgICpcbiAgICogQHN1bW1hcnlcbiAgICogSWYgYSBjdXN0b20gbG9nZ2VyIGlzIHByb3ZpZGVkLCBpdCByZXBsYWNlcyB0aGUgZGVmYXVsdCBsb2dnZXIuIE90aGVyd2lzZSxcbiAgICogYSBuZXcgbG9nZ2VyIG5hbWVkIGBcIk5lc3RCb290c3RyYXBcImAgaXMgdXNlZC4gVGhpcyBsb2dnZXIgaXMgYWxzbyByZWdpc3RlcmVkXG4gICAqIHdpdGggdGhlIE5lc3RKUyBhcHBsaWNhdGlvbi5cbiAgICpcbiAgICogQHBhcmFtIHtMb2dnZXJ9IFtjdXN0b21Mb2dnZXJdIC0gT3B0aW9uYWwgY3VzdG9tIGxvZ2dlciBpbnN0YW5jZS5cbiAgICogQHJldHVybiB7dHlwZW9mIE5lc3RCb290c3RyYXBlcn0gUmV0dXJucyB0aGUgY2xhc3MgZm9yIGNoYWluaW5nLlxuICAgKi9cbiAgc3RhdGljIGVuYWJsZUxvZ2dlcihjdXN0b21Mb2dnZXI/OiBMb2dnZXIpIHtcbiAgICB0aGlzLl9sb2dnZXIgPSBjdXN0b21Mb2dnZXIgfHwgbmV3IExvZ2dlcihcIk5lc3RCb290c3RyYXBcIik7XG4gICAgdGhpcy5hcHAudXNlTG9nZ2VyKHRoaXMuX2xvZ2dlcik7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqIEVuYWJsZXMgQ3Jvc3MtT3JpZ2luIFJlc291cmNlIFNoYXJpbmcgKENPUlMpIGZvciB0aGUgYXBwbGljYXRpb24uXG4gICAqXG4gICAqIEBzdW1tYXJ5XG4gICAqIEFsbG93cyBkZWZpbmluZyBlaXRoZXIgYSB3aWxkY2FyZCBvcmlnaW4gKGBcIipcImApIG9yIGEgbGlzdCBvZiBhbGxvd2VkIG9yaWdpbnMuXG4gICAqIEF1dG9tYXRpY2FsbHkgYWNjZXB0cyBsb2NhbCBkZXZlbG9wbWVudCByZXF1ZXN0cyBhbmQgdGhvc2Ugd2l0aG91dCBvcmlnaW4gaGVhZGVycy5cbiAgICogVGhyb3dzIGEgYENvcnNFcnJvcmAgZm9yIHVuYXV0aG9yaXplZCBvcmlnaW5zLlxuICAgKlxuICAgKiBAcGFyYW0geycqJyB8IHN0cmluZ1tdfSBbb3JpZ2lucz1bXV0gLSBMaXN0IG9mIGFsbG93ZWQgb3JpZ2lucyBvciBgXCIqXCJgIHRvIGFsbG93IGFsbC5cbiAgICogQHBhcmFtIHtzdHJpbmdbXX0gW2FsbG93TWV0aG9kcz1bJ0dFVCcsICdQT1NUJywgJ1BVVCcsICdERUxFVEUnXV0gLSBBbGxvd2VkIEhUVFAgbWV0aG9kcy5cbiAgICogQHJldHVybiB7dHlwZW9mIE5lc3RCb290c3RyYXBlcn0gUmV0dXJucyB0aGUgY2xhc3MgZm9yIGNoYWluaW5nIGNvbmZpZ3VyYXRpb24uXG4gICAqXG4gICAqL1xuICBzdGF0aWMgZW5hYmxlQ29ycyhcbiAgICBvcmlnaW5zOiBcIipcIiB8IHN0cmluZ1tdID0gW10sXG4gICAgYWxsb3dNZXRob2RzOiBzdHJpbmdbXSA9IFtcIkdFVFwiLCBcIlBPU1RcIiwgXCJQVVRcIiwgXCJERUxFVEVcIl1cbiAgKSB7XG4gICAgY29uc3QgYWxsb3dlZE9yaWdpbnMgPVxuICAgICAgb3JpZ2lucyA9PT0gXCIqXCIgPyBcIipcIiA6IG9yaWdpbnMubWFwKChvKSA9PiBvLnRyaW0oKS50b0xvd2VyQ2FzZSgpKTtcblxuICAgIGNvbnN0IGNvcnNPcHRpb25zOiBDb3JzT3B0aW9ucyA9IHtcbiAgICAgIG9yaWdpbjogKG9yaWdpbiwgY2FsbGJhY2spID0+IHtcbiAgICAgICAgLy8gQWxsb3cgcmVxdWVzdCB3aXRob3V0IG9yaWdpbi4uLlxuICAgICAgICBpZiAoIW9yaWdpbikgcmV0dXJuIGNhbGxiYWNrKG51bGwsIHRydWUpO1xuXG4gICAgICAgIGlmIChcbiAgICAgICAgICBhbGxvd2VkT3JpZ2lucyA9PT0gXCIqXCIgfHxcbiAgICAgICAgICAoQXJyYXkuaXNBcnJheShhbGxvd2VkT3JpZ2lucykgJiZcbiAgICAgICAgICAgIGFsbG93ZWRPcmlnaW5zLmluY2x1ZGVzKG9yaWdpbi50b0xvd2VyQ2FzZSgpKSlcbiAgICAgICAgKSB7XG4gICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKG51bGwsIHRydWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgY2FsbGJhY2sobmV3IENvcnNFcnJvcihgT3JpZ2luICR7b3JpZ2lufSBub3QgYWxsb3dlZGApKTtcbiAgICAgIH0sXG4gICAgICBjcmVkZW50aWFsczogdHJ1ZSxcbiAgICAgIG1ldGhvZHM6IGFsbG93TWV0aG9kcy5qb2luKFwiLFwiKSxcbiAgICB9O1xuXG4gICAgdGhpcy5hcHAuZW5hYmxlQ29ycyhjb3JzT3B0aW9ucyk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqIEFwcGxpZXMgdGhlIEhlbG1ldCBtaWRkbGV3YXJlIGZvciBlbmhhbmNlZCBzZWN1cml0eS5cbiAgICpcbiAgICogQHN1bW1hcnlcbiAgICogRHluYW1pY2FsbHkgbG9hZHMgdGhlIGBoZWxtZXRgIHBhY2thZ2UgaWYgYXZhaWxhYmxlIGFuZCByZWdpc3RlcnMgaXRcbiAgICogYXMgbWlkZGxld2FyZSB0byBpbXByb3ZlIEhUVFAgaGVhZGVyIHNlY3VyaXR5LiBJZiBub3QgaW5zdGFsbGVkLCBsb2dzIGEgd2FybmluZ1xuICAgKiBhbmQgY29udGludWVzIGV4ZWN1dGlvbiB3aXRob3V0IHRocm93aW5nIGVycm9ycy5cbiAgICpcbiAgICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCBhbnk+fSBbb3B0aW9uc10gLSBPcHRpb25hbCBjb25maWd1cmF0aW9uIHBhc3NlZCB0byBIZWxtZXQuXG4gICAqIEByZXR1cm4ge3R5cGVvZiBOZXN0Qm9vdHN0cmFwZXJ9IFJldHVybnMgdGhlIGNsYXNzIGZvciBjaGFpbmluZyBjb25maWd1cmF0aW9uLlxuICAgKi9cbiAgc3RhdGljIHVzZUhlbG1ldChvcHRpb25zPzogUmVjb3JkPHN0cmluZywgYW55Pikge1xuICAgIHRyeSB7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXJlcXVpcmUtaW1wb3J0c1xuICAgICAgY29uc3QgaGVsbWV0ID0gcmVxdWlyZShcImhlbG1ldFwiKTsgLy8gRHluYW1pYyBpbXBvcnQgdG8gYXZvaWQgaGFyZCBkZXBlbmRlbmN5XG4gICAgICB0aGlzLmFwcC51c2UoaGVsbWV0KG9wdGlvbnMpKTtcbiAgICAgIHRoaXMubG9nZ2VyLmxvZyhcIkhlbG1ldCBtaWRkbGV3YXJlIGVuYWJsZWQgc3VjY2Vzc2Z1bGx5LlwiKTtcbiAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgIHRoaXMubG9nZ2VyLndhcm4oXCJIZWxtZXQgbm90IGluc3RhbGxlZC4gU2tpcHBpbmcgbWlkZGxld2FyZS5cIik7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqIENvbmZpZ3VyZXMgYW5kIGluaXRpYWxpemVzIFN3YWdnZXIgVUkgZm9yIEFQSSBkb2N1bWVudGF0aW9uLlxuICAgKlxuICAgKiBAc3VtbWFyeVxuICAgKiBVc2VzIHRoZSBgU3dhZ2dlckJ1aWxkZXJgIHV0aWxpdHkgdG8gY29uZmlndXJlIEFQSSBkb2N1bWVudGF0aW9uXG4gICAqIHdpdGggZGV0YWlsZWQgY3VzdG9taXphdGlvbiBmb3IgdGl0bGUsIHZlcnNpb24sIHBhdGhzLCBhbmQgY29sb3JzLlxuICAgKiBTd2FnZ2VyIGlzIGF1dG9tYXRpY2FsbHkgZXhwb3NlZCBhdCB0aGUgY29uZmlndXJlZCBwYXRoLlxuICAgKlxuICAgKiBAcGFyYW0ge1N3YWdnZXJTZXR1cE9wdGlvbnN9IG9wdGlvbnMgLSBTd2FnZ2VyIGNvbmZpZ3VyYXRpb24gb3B0aW9ucy5cbiAgICogQHJldHVybiB7dHlwZW9mIE5lc3RCb290c3RyYXBlcn0gUmV0dXJucyB0aGUgY2xhc3MgZm9yIGNoYWluaW5nIGNvbmZpZ3VyYXRpb24uXG4gICAqL1xuICBzdGF0aWMgc2V0dXBTd2FnZ2VyKG9wdGlvbnM6IFN3YWdnZXJTZXR1cE9wdGlvbnMpIHtcbiAgICBjb25zdCBzd2FnZ2VyID0gbmV3IFN3YWdnZXJCdWlsZGVyKHRoaXMuYXBwLCB7XG4gICAgICB0aXRsZTogb3B0aW9ucy50aXRsZSxcbiAgICAgIGRlc2NyaXB0aW9uOiBvcHRpb25zLmRlc2NyaXB0aW9uLFxuICAgICAgdmVyc2lvbjogb3B0aW9ucy52ZXJzaW9uLFxuICAgICAgcGF0aDogb3B0aW9ucy5wYXRoIHx8IFwiYXBpXCIsXG4gICAgICBwZXJzaXN0QXV0aG9yaXphdGlvbjogb3B0aW9ucy5wZXJzaXN0QXV0aG9yaXphdGlvbiA/PyB0cnVlLFxuICAgICAgYXNzZXRzUGF0aDogb3B0aW9ucy5hc3NldHNQYXRoLFxuICAgICAgZmF2aWNvbkZpbGVQYXRoOiBvcHRpb25zLmZhdmljb25QYXRoLFxuICAgICAgdG9wYmFySWNvbkZpbGVQYXRoOiBvcHRpb25zLnRvcGJhckljb25QYXRoLFxuICAgICAgdG9wYmFyQmdDb2xvcjogb3B0aW9ucy50b3BiYXJCZ0NvbG9yLFxuICAgIH0pO1xuICAgIHN3YWdnZXIuc2V0dXBTd2FnZ2VyKCk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqIFJlZ2lzdGVycyBvbmUgb3IgbW9yZSBnbG9iYWwgdmFsaWRhdGlvbiBwaXBlcy5cbiAgICpcbiAgICogQHN1bW1hcnlcbiAgICogRW5hYmxlcyByZXF1ZXN0IHBheWxvYWQgdmFsaWRhdGlvbiBhbmQgdHJhbnNmb3JtYXRpb24gZ2xvYmFsbHkgYWNyb3NzXG4gICAqIHRoZSBlbnRpcmUgTmVzdEpTIGFwcGxpY2F0aW9uLiBNdWx0aXBsZSBwaXBlcyBjYW4gYmUgY2hhaW5lZCB0b2dldGhlclxuICAgKiBmb3IgbW9kdWxhciBpbnB1dCB2YWxpZGF0aW9uLlxuICAgKlxuICAgKiBAcGFyYW0gey4uLlBpcGVUcmFuc2Zvcm1bXX0gcGlwZXMgLSBQaXBlIGluc3RhbmNlcyB0byByZWdpc3RlciBnbG9iYWxseS5cbiAgICogQHJldHVybiB7dHlwZW9mIE5lc3RCb290c3RyYXBlcn0gUmV0dXJucyB0aGUgY2xhc3MgZm9yIGNoYWluaW5nLlxuICAgKi9cbiAgc3RhdGljIHVzZUdsb2JhbFBpcGVzKC4uLnBpcGVzOiBQaXBlVHJhbnNmb3JtW10pIHtcbiAgICBpZiAocGlwZXMubGVuZ3RoID4gMCkgdGhpcy5hcHAudXNlR2xvYmFsUGlwZXMoLi4ucGlwZXMpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiBSZWdpc3RlcnMgb25lIG9yIG1vcmUgZ2xvYmFsIGV4Y2VwdGlvbiBmaWx0ZXJzLlxuICAgKlxuICAgKiBAc3VtbWFyeVxuICAgKiBJZiBubyBmaWx0ZXJzIGFyZSBwcm92aWRlZCwgaXQgYXV0b21hdGljYWxseSByZWdpc3RlcnMgYSBkZWZhdWx0XG4gICAqIHNldCBvZiBzdGFuZGFyZCBleGNlcHRpb24gZmlsdGVycyBmb3IgY29tbW9uIGVycm9yIHR5cGVzIGxpa2VcbiAgICogYEh0dHBFeGNlcHRpb25gLCBgVmFsaWRhdGlvbkV4Y2VwdGlvbmAsIGBDb25mbGljdEV4Y2VwdGlvbmAsIGFuZCBvdGhlcnMuXG4gICAqXG4gICAqIEBwYXJhbSB7Li4uRXhjZXB0aW9uRmlsdGVyW119IGZpbHRlcnMgLSBPcHRpb25hbCBmaWx0ZXJzIHRvIGFwcGx5IGdsb2JhbGx5LlxuICAgKiBAcmV0dXJuIHt0eXBlb2YgTmVzdEJvb3RzdHJhcGVyfSBSZXR1cm5zIHRoZSBjbGFzcyBmb3IgY2hhaW5pbmcgY29uZmlndXJhdGlvbi5cbiAgICovXG4gIHN0YXRpYyB1c2VHbG9iYWxGaWx0ZXJzKC4uLmZpbHRlcnM6IGFueVtdKSB7XG4gICAgY29uc3QgZGVmYXVsdEZpbHRlcnMgPSBbXG4gICAgICBuZXcgSHR0cEV4Y2VwdGlvbkZpbHRlcigpLFxuICAgICAgbmV3IFZhbGlkYXRpb25FeGNlcHRpb25GaWx0ZXIoKSxcbiAgICAgIG5ldyBOb3RGb3VuZEV4Y2VwdGlvbkZpbHRlcigpLFxuICAgICAgbmV3IENvbmZsaWN0RXhjZXB0aW9uRmlsdGVyKCksXG4gICAgICBuZXcgQXV0aG9yaXphdGlvbkV4Y2VwdGlvbkZpbHRlcigpLFxuICAgICAgbmV3IEdsb2JhbEV4Y2VwdGlvbkZpbHRlcigpLFxuICAgIF07XG5cbiAgICB0aGlzLmFwcC51c2VHbG9iYWxGaWx0ZXJzKFxuICAgICAgLi4uKGZpbHRlcnMubGVuZ3RoID4gMCA/IGZpbHRlcnMgOiBkZWZhdWx0RmlsdGVycylcbiAgICApO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiBSZWdpc3RlcnMgZ2xvYmFsIGludGVyY2VwdG9ycyBmb3IgcmVxdWVzdCBhbmQgcmVzcG9uc2UgdHJhbnNmb3JtYXRpb24uXG4gICAqXG4gICAqIEBzdW1tYXJ5XG4gICAqIEludGVyY2VwdG9ycyBhbGxvdyBhZHZhbmNlZCByZXF1ZXN0L3Jlc3BvbnNlIG1hbmlwdWxhdGlvbiBzdWNoIGFzXG4gICAqIHNlcmlhbGl6YXRpb24sIGxvZ2dpbmcsIG9yIHRyYW5zZm9ybWF0aW9uLiBNdWx0aXBsZSBpbnRlcmNlcHRvcnNcbiAgICogY2FuIGJlIGFkZGVkIGZvciBtb2R1bGFyIGNvbmZpZ3VyYXRpb24uXG4gICAqXG4gICAqIEBwYXJhbSB7Li4uTmVzdEludGVyY2VwdG9yW119IGludGVyY2VwdG9ycyAtIEludGVyY2VwdG9yIGluc3RhbmNlcyB0byByZWdpc3Rlci5cbiAgICogQHJldHVybiB7dHlwZW9mIE5lc3RCb290c3RyYXBlcn0gUmV0dXJucyB0aGUgY2xhc3MgZm9yIGNoYWluaW5nIGNvbmZpZ3VyYXRpb24uXG4gICAqL1xuICBzdGF0aWMgdXNlR2xvYmFsSW50ZXJjZXB0b3JzKC4uLmludGVyY2VwdG9yczogTmVzdEludGVyY2VwdG9yW10pIHtcbiAgICBpZiAoaW50ZXJjZXB0b3JzLmxlbmd0aCA+IDApXG4gICAgICB0aGlzLmFwcC51c2VHbG9iYWxJbnRlcmNlcHRvcnMoLi4uaW50ZXJjZXB0b3JzKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogU3RhcnRzIHRoZSBOZXN0SlMgYXBwbGljYXRpb24gYW5kIGJpbmRzIGl0IHRvIHRoZSBnaXZlbiBwb3J0IGFuZCBob3N0LlxuICAgKlxuICAgKiBAc3VtbWFyeVxuICAgKiBMaXN0ZW5zIG9uIHRoZSBzcGVjaWZpZWQgcG9ydCBhbmQgb3B0aW9uYWxseSBhIGhvc3QuIE9uY2Ugc3RhcnRlZCxcbiAgICogbG9ncyB0aGUgYXBwbGljYXRpb24gVVJMIGZvciBlYXN5IGFjY2Vzcy4gVGhlIHN0YXJ0dXAgcHJvY2VzcyByZXNvbHZlc1xuICAgKiBvbmNlIHRoZSBhcHBsaWNhdGlvbiBpcyBzdWNjZXNzZnVsbHkgcnVubmluZy5cbiAgICpcbiAgICogQHBhcmFtIHtudW1iZXJ9IFtwb3J0PTMwMDBdIC0gUG9ydCBudW1iZXIgdG8gbGlzdGVuIG9uLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gW2hvc3RdIC0gT3B0aW9uYWwgaG9zdCBvciBJUCBhZGRyZXNzIHRvIGJpbmQgdG8uXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gW2xvZz10cnVlXSAtIFdoZXRoZXIgdG8gbG9nIHRoZSBhcHBsaWNhdGlvbiBVUkwgdXBvbiBzdGFydHVwLlxuICAgKiBAcmV0dXJuIHtQcm9taXNlPHZvaWQ+fSBSZXNvbHZlcyBvbmNlIHRoZSBhcHBsaWNhdGlvbiBzdGFydHMgc3VjY2Vzc2Z1bGx5LlxuICAgKi9cbiAgc3RhdGljIGFzeW5jIHN0YXJ0KFxuICAgIHBvcnQ6IG51bWJlciA9IE51bWJlcihwcm9jZXNzLmVudi5QT1JUKSB8fCAzMDAwLFxuICAgIGhvc3Q6IHN0cmluZyB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZCxcbiAgICBsb2c6IGJvb2xlYW4gPSB0cnVlXG4gICkge1xuICAgIHRoaXMuYXBwLmxpc3Rlbihwb3J0LCBob3N0IGFzIGFueSkudGhlbihhc3luYyAoKSA9PiB7XG4gICAgICBpZiAobG9nKSB7XG4gICAgICAgIGNvbnN0IHVybCA9IGF3YWl0IHRoaXMuYXBwLmdldFVybCgpO1xuICAgICAgICB0aGlzLmxvZ2dlci5sb2coYPCfmoAgQXBwbGljYXRpb24gaXMgcnVubmluZyBhdDogJHt1cmx9YCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbn1cbiIsIi8qKlxuICogQG1vZHVsZSBmb3ItbmVzdFxuICogQGRlc2NyaXB0aW9uIFRoaXMgbW9kdWxlIHNlcnZlcyBhcyB0aGUgbWFpbiBlbnRyeSBwb2ludCBmb3IgdGhlIHRzLXdvcmtzcGFjZSBsaWJyYXJ5LiBJdCBhZ2dyZWdhdGVzIGFuZCBleHBvcnRzXG4gKiBmdW5jdGlvbmFsaXR5IGZyb20gdmFyaW91cyBzdWJtb2R1bGVzIGFuZCB1dGlsaXRpZXMgd2l0aGluIHRoZSBwcm9qZWN0LlxuICpcbiAqIFRoZSBtb2R1bGUgaW5jbHVkZXM6XG4gKiAxLiBVdGlsaXR5IGZ1bmN0aW9ucyBhbmQgdHlwZXMgZnJvbSB0aGUgXCIuL3V0aWxzXCIgZGlyZWN0b3J5OlxuICogICAgLSBUaGVzZSBsaWtlbHkgY29udGFpbiBoZWxwZXIgZnVuY3Rpb25zLCBjb21tb24gdHlwZXMsIGFuZCBzaGFyZWQgZnVuY3Rpb25hbGl0eSB1c2VkIHRocm91Z2hvdXQgdGhlIHByb2plY3QuXG4gKiAgICAtIE1heSBpbmNsdWRlIG9wZXJhdGlvbnMgZm9yIGRhdGEgbWFuaXB1bGF0aW9uLCB0eXBlIGNoZWNraW5nLCBvciBvdGhlciBnZW5lcmFsLXB1cnBvc2UgdXRpbGl0aWVzLlxuICpcbiAqIDIuIEEgbmFtZXNwYWNlIGFuZCByZWxhdGVkIHR5cGVzIGZyb20gdGhlIFwiLi9uYW1lc3BhY2VcIiBkaXJlY3Rvcnk6XG4gKiAgICAtIFRoaXMgY291bGQgY29udGFpbiBkb21haW4tc3BlY2lmaWMgY29kZSBvciBhIGNvbGxlY3Rpb24gb2YgcmVsYXRlZCBmdW5jdGlvbmFsaXR5LlxuICogICAgLSBNaWdodCBpbmNsdWRlIGludGVyZmFjZXMsIHR5cGVzLCBvciBjbGFzc2VzIHRoYXQgcmVwcmVzZW50IGNvcmUgY29uY2VwdHMgaW4gdGhlIGxpYnJhcnkuXG4gKlxuICogMy4gQSBWRVJTSU9OIGNvbnN0YW50OlxuICogICAgLSBSZXByZXNlbnRzIHRoZSBjdXJyZW50IHZlcnNpb24gb2YgdGhlIG1vZHVsZS5cbiAqICAgIC0gVXNlZnVsIGZvciB2ZXJzaW9uIGNoZWNraW5nIGFuZCBjb21wYXRpYmlsaXR5IHB1cnBvc2VzLlxuICpcbiAqIFRoaXMgc3RydWN0dXJlIHByb3ZpZGVzIGEgY2xlYW4gYW5kIG9yZ2FuaXplZCBleHBvcnQgb2YgdGhlIG1vZHVsZSdzIGZ1bmN0aW9uYWxpdHksIGFsbG93aW5nIGNvbnN1bWVyc1xuICogdG8gZWFzaWx5IGltcG9ydCBhbmQgdXNlIHNwZWNpZmljIHBhcnRzIG9mIHRoZSBsaWJyYXJ5IGFzIG5lZWRlZC5cbiAqL1xuXG5pbXBvcnQgeyBNZXRhZGF0YSB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdGlvblwiO1xuaW1wb3J0IFwiLi9kZWNvcmF0aW9uXCI7XG5cbmV4cG9ydCAqIGZyb20gXCIuL2RlY29yYXRvcnNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2NvbnN0YW50c1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vZGVjb3JhdGlvblwiO1xuZXhwb3J0ICogZnJvbSBcIi4vbW9kdWxlXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9SZXBvRmFjdG9yeVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vdHlwZXNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3V0aWxzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9mYWN0b3J5XCI7XG5cbi8qKlxuICogUmVwcmVzZW50cyB0aGUgY3VycmVudCB2ZXJzaW9uIG9mIHRoZSB0cy13b3Jrc3BhY2UgbW9kdWxlLlxuICogVGhlIGFjdHVhbCB2ZXJzaW9uIG51bWJlciBpcyByZXBsYWNlZCBkdXJpbmcgdGhlIGJ1aWxkIHByb2Nlc3MuXG4gKiBAY29uc3RhbnRcbiAqIEB0eXBlIHtzdHJpbmd9XG4gKi9cbmV4cG9ydCBjb25zdCBWRVJTSU9OID0gXCIjI1ZFUlNJT04jI1wiO1xuZXhwb3J0IGNvbnN0IFBBQ0tBR0VfTkFNRSA9IFwiIyNQQUNLQUdFX05BTUUjI1wiO1xuXG5NZXRhZGF0YS5yZWdpc3RlckxpYnJhcnkoUEFDS0FHRV9OQU1FLCBWRVJTSU9OKTtcbiJdLCJuYW1lcyI6WyJERUNPUkFUT1JTIiwicGlja0J5IiwibmVnYXRlIiwiaXNVbmRlZmluZWQiLCJNRVRBREFUQV9GQUNUT1JZX05BTUUiLCJpc0NvbnN0cnVjdG9yIiwiTUVUSE9EX01FVEFEQVRBIiwiaXNBcnJheSIsImdldFR5cGVJc0FycmF5VHVwbGUiLCJnZXRFbnVtVmFsdWVzIiwiZ2V0RW51bVR5cGUiLCJEZWNvcmF0aW9uIiwiSW5qZWN0YWJsZXNLZXlzIiwiSW5qZWN0YWJsZSIsIlNjb3BlIiwiSW5qZWN0IiwiVmFsaWRhdGlvbktleXMiLCJQZXJzaXN0ZW5jZUtleXMiLCJEZWNvcmF0aW9uS2V5cyIsIkxvZ2dpbmciLCJfX2RlY29yYXRlIiwiR2xvYmFsIiwiTW9kdWxlIiwiX19wYXJhbSIsIk1vZHVsZVJlZiIsIlJlcG9GYWN0b3J5IiwiTW9kZWwiLCJJbnRlcm5hbEVycm9yIiwiUmVwb3NpdG9yeSIsInRvS2ViYWJDYXNlIiwiTG9nZ2VkQ2xhc3MiLCJQb3N0IiwiQXBpT3BlcmF0aW9uIiwiQXBpQm9keSIsImdldFNjaGVtYVBhdGgiLCJBcGlDcmVhdGVkUmVzcG9uc2UiLCJBcGlCYWRSZXF1ZXN0UmVzcG9uc2UiLCJBcGlVbnByb2Nlc3NhYmxlRW50aXR5UmVzcG9uc2UiLCJCb2R5IiwiR2V0IiwiQXBpUGFyYW0iLCJBcGlPa1Jlc3BvbnNlIiwiQXBpTm90Rm91bmRSZXNwb25zZSIsIlBhcmFtIiwiUHV0IiwiRGVsZXRlIiwiQ29udHJvbGxlciIsIkFwaVRhZ3MiLCJBcGlFeHRyYU1vZGVscyIsIkFkYXB0ZXIiLCJEZWNhZk1vZHVsZSIsIkZvcmJpZGRlbkVycm9yIiwiSHR0cFN0YXR1cyIsIkF1dGhvcml6YXRpb25FeGNlcHRpb25GaWx0ZXIiLCJDYXRjaCIsIkNvbmZsaWN0RXhjZXB0aW9uRmlsdGVyIiwiR2xvYmFsRXhjZXB0aW9uRmlsdGVyIiwiSHR0cEV4Y2VwdGlvbiIsIkh0dHBFeGNlcHRpb25GaWx0ZXIiLCJOb3RGb3VuZEV4Y2VwdGlvbkZpbHRlciIsIlZhbGlkYXRpb25FeGNlcHRpb25GaWx0ZXIiLCJwYXRoIiwicmVhZEZpbGVTeW5jIiwiRG9jdW1lbnRCdWlsZGVyIiwiU3dhZ2dlck1vZHVsZSIsIkxvZ2dlciIsIk1ldGFkYXRhIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0lBQUE7SUFRZ0IsU0FBQSxxQkFBcUIsQ0FDbkMsT0FBZSxFQUNmLFFBQVcsRUFDWCxFQUFFLGdCQUFnQixFQUFFLEdBQUcsRUFBRSxnQkFBZ0IsRUFBRSxJQUFJLEVBQUUsRUFBQTtJQUVqRCxJQUFBLE9BQU8sQ0FDTCxNQUFjLEVBQ2QsR0FBb0IsRUFDcEIsVUFBOEIsS0FDNUI7SUFDRixRQUFBLElBQUksT0FBTyxRQUFRLEtBQUssUUFBUSxFQUFFO0lBQ2hDLFlBQUEsTUFBTSxTQUFTLEdBQUcsT0FBTyxDQUFDLFdBQVcsQ0FBQyxPQUFPLEVBQUUsVUFBVSxDQUFDLEtBQUssQ0FBQztJQUNoRSxZQUFBLElBQUksU0FBUyxJQUFJLENBQUMsZ0JBQWdCLEVBQUU7SUFDbEMsZ0JBQUEsT0FBTyxVQUFVOztJQUVuQixZQUFBLE9BQU8sQ0FBQyxjQUFjLENBQ3BCLE9BQU8sRUFDUCxFQUFFLEdBQUcsU0FBUyxFQUFFLEdBQUcsUUFBUSxFQUFFLEVBQzdCLFVBQVUsQ0FBQyxLQUFLLENBQ2pCO0lBQ0QsWUFBQSxPQUFPLFVBQVU7O1lBRW5CLE9BQU8sQ0FBQyxjQUFjLENBQUMsT0FBTyxFQUFFLFFBQVEsRUFBRSxVQUFVLENBQUMsS0FBSyxDQUFDO0lBQzNELFFBQUEsT0FBTyxVQUFVO0lBQ25CLEtBQUM7SUFDSDthQUVnQixvQkFBb0IsQ0FDbEMsT0FBZSxFQUNmLFdBQWMsRUFBa0IsRUFBQTtRQUVoQyxPQUFPLENBQUMsTUFBTSxLQUFJO0lBQ2hCLFFBQUEsTUFBTSxTQUFTLEdBQUcsT0FBTyxDQUFDLFdBQVcsQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLElBQUksRUFBRTtJQUM1RCxRQUFBLE9BQU8sQ0FBQyxjQUFjLENBQUMsT0FBTyxFQUFFLENBQUMsR0FBRyxTQUFTLEVBQUUsR0FBRyxRQUFRLENBQUMsRUFBRSxNQUFNLENBQUM7SUFDcEUsUUFBQSxPQUFPLE1BQU07SUFDZixLQUFDO0lBQ0g7SUFFTSxTQUFVLHVCQUF1QixDQUNyQyxPQUFlLEVBQ2YsUUFBVyxFQUNYLGdCQUFnQixHQUFHLElBQUksRUFBQTtJQUV2QixJQUFBLE9BQU8sQ0FBQyxNQUFjLEVBQUUsV0FBaUIsS0FBSTtJQUMzQyxRQUFBLE1BQU0sVUFBVSxHQUNkLE9BQU8sQ0FBQyxXQUFXLENBQUNBLG9CQUFVLENBQUMsMEJBQTBCLEVBQUUsTUFBTSxDQUFDLElBQUksRUFBRTtJQUUxRSxRQUFBLE1BQU0sR0FBRyxHQUFHLENBQUksQ0FBQSxFQUFBLFdBQVcsRUFBRTtZQUM3QixJQUFJLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsRUFBRTtJQUM3QixZQUFBLE9BQU8sQ0FBQyxjQUFjLENBQ3BCQSxvQkFBVSxDQUFDLDBCQUEwQixFQUNyQyxDQUFDLEdBQUcsVUFBVSxFQUFFLElBQUksV0FBVyxDQUFBLENBQUUsQ0FBQyxFQUNsQyxNQUFNLENBQ1A7O0lBRUgsUUFBQSxNQUFNLGdCQUFnQixHQUFHLE9BQU8sQ0FBQyxXQUFXLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxXQUFXLENBQUM7WUFDMUUsSUFBSSxnQkFBZ0IsRUFBRTtnQkFDcEIsTUFBTSxXQUFXLEdBQUdDLGFBQU0sQ0FBQyxRQUFRLEVBQUVDLGFBQU0sQ0FBQ0Msa0JBQVcsQ0FBQyxDQUFDO2dCQUN6RCxNQUFNLGNBQWMsR0FBRztJQUNyQixrQkFBRTtJQUNFLG9CQUFBLEdBQUcsZ0JBQWdCO0lBQ25CLG9CQUFBLEdBQUcsV0FBVztJQUNmO0lBQ0gsa0JBQUU7SUFDRSxvQkFBQSxHQUFHLFdBQVc7SUFDZCxvQkFBQSxHQUFHLGdCQUFnQjtxQkFDcEI7Z0JBRUwsT0FBTyxDQUFDLGNBQWMsQ0FBQyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sRUFBRSxXQUFXLENBQUM7O2lCQUMvRDtJQUNMLFlBQUEsTUFBTSxJQUFJOztJQUVSLFlBQUEsTUFBTSxFQUFFLFdBQVcsR0FBR0MscUNBQXFCLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxFQUFFLElBQUk7b0JBQ25FLE9BQU8sQ0FBQyxXQUFXLENBQUMsYUFBYSxFQUFFLE1BQU0sRUFBRSxXQUFXLENBQUM7SUFFekQsWUFBQSxPQUFPLENBQUMsY0FBYyxDQUNwQixPQUFPLEVBQ1A7b0JBQ0UsSUFBSTtvQkFDSixHQUFHSCxhQUFNLENBQUMsUUFBUSxFQUFFQyxhQUFNLENBQUNDLGtCQUFXLENBQUMsQ0FBQztJQUN6QyxhQUFBLEVBQ0QsTUFBTSxFQUNOLFdBQVcsQ0FDWjs7SUFFTCxLQUFDO0lBQ0g7SUFFZ0IsU0FBQSxvQkFBb0IsQ0FDbEMsT0FBZSxFQUNmLFFBQVcsRUFBQTtJQUVYLElBQUEsT0FBTyxDQUNMLE1BQWMsRUFDZCxHQUFxQixFQUNyQixVQUF5QyxLQUNsQztZQUNQLElBQUksVUFBVSxFQUFFO0lBQ2QsWUFBQSxJQUFJLFNBQWM7SUFDbEIsWUFBQSxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLEVBQUU7SUFDM0IsZ0JBQUEsTUFBTSxnQkFBZ0IsR0FDcEIsT0FBTyxDQUFDLFdBQVcsQ0FBQyxPQUFPLEVBQUUsVUFBVSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUU7b0JBQ3RELFNBQVMsR0FBRyxDQUFDLEdBQUcsZ0JBQWdCLEVBQUUsR0FBRyxRQUFRLENBQUM7O3FCQUN6QztJQUNMLGdCQUFBLE1BQU0sZ0JBQWdCLEdBQ3BCLE9BQU8sQ0FBQyxXQUFXLENBQUMsT0FBTyxFQUFFLFVBQVUsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFO29CQUN0RCxTQUFTLEdBQUcsRUFBRSxHQUFHLGdCQUFnQixFQUFFLEdBQUcsUUFBUSxFQUFFOztnQkFFbEQsT0FBTyxDQUFDLGNBQWMsQ0FBQyxPQUFPLEVBQUUsU0FBUyxFQUFFLFVBQVUsQ0FBQyxLQUFLLENBQUM7SUFDNUQsWUFBQSxPQUFPLFVBQVU7O0lBR25CLFFBQUEsSUFBSSxTQUFjO0lBQ2xCLFFBQUEsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxFQUFFO0lBQzNCLFlBQUEsTUFBTSxnQkFBZ0IsR0FBRyxPQUFPLENBQUMsV0FBVyxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsSUFBSSxFQUFFO2dCQUNuRSxTQUFTLEdBQUcsQ0FBQyxHQUFHLGdCQUFnQixFQUFFLEdBQUcsUUFBUSxDQUFDOztpQkFDekM7SUFDTCxZQUFBLE1BQU0sZ0JBQWdCLEdBQUcsT0FBTyxDQUFDLFdBQVcsQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLElBQUksRUFBRTtJQUNuRSxZQUFBLFNBQVMsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLGdCQUFnQixDQUFDLEVBQUUsUUFBUSxDQUFDOztZQUUxRSxPQUFPLENBQUMsY0FBYyxDQUFDLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxDQUFDO0lBQ2xELFFBQUEsT0FBTyxNQUFNO0lBQ2YsS0FBQztJQUNIO0lBRWdCLFNBQUEsb0JBQW9CLENBQ2xDLFFBQVcsRUFDWCxPQUFtQixFQUFBO0lBRW5CLElBQUEsT0FBTyxDQUNMLE1BQXlCLEVBQ3pCLEdBQXFCLEVBQ3JCLFVBQXlDLEtBQ2xDO0lBQ1AsUUFBQSxNQUFNLFlBQVksR0FBRztJQUNuQixZQUFBLEdBQUcsT0FBTztnQkFDVixHQUFHRixhQUFNLENBQUMsUUFBUSxFQUFFQyxhQUFNLENBQUNDLGtCQUFXLENBQUMsQ0FBQzthQUN6QztZQUVELElBQUksVUFBVSxFQUFFO0lBQ2QsWUFBQSxNQUFNLFVBQVUsR0FDZCxPQUFPLENBQUMsV0FBVyxDQUFDSCxvQkFBVSxDQUFDLGNBQWMsRUFBRSxVQUFVLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRTtJQUN4RSxZQUFBLE9BQU8sQ0FBQyxjQUFjLENBQ3BCQSxvQkFBVSxDQUFDLGNBQWMsRUFDekIsQ0FBQyxHQUFHLFVBQVUsRUFBRSxZQUFZLENBQUMsRUFDN0IsVUFBVSxDQUFDLEtBQUssQ0FDakI7SUFDRCxZQUFBLE9BQU8sVUFBVTs7SUFHbkIsUUFBQSxJQUFJLE9BQU8sTUFBTSxLQUFLLFFBQVEsRUFBRTtJQUM5QixZQUFBLE9BQU8sTUFBTTs7WUFHZixNQUFNLFlBQVksR0FBRyxNQUFNLENBQUMsbUJBQW1CLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQztJQUVqRSxRQUFBLEtBQUssTUFBTSxXQUFXLElBQUksWUFBWSxFQUFFO0lBQ3RDLFlBQUEsSUFBSUssMEJBQWEsQ0FBQyxXQUFXLENBQUMsRUFBRTtvQkFDOUI7O0lBR0YsWUFBQSxNQUFNLGdCQUFnQixHQUFHLE1BQU0sQ0FBQyx3QkFBd0IsQ0FDdEQsTUFBTSxDQUFDLFNBQVMsRUFDaEIsV0FBVyxDQUNaO2dCQUVELElBQUksQ0FBQyxnQkFBZ0IsRUFBRTtvQkFDckI7O0lBR0YsWUFBQSxNQUFNLFdBQVcsR0FBRyxPQUFPLENBQUMsV0FBVyxDQUNyQ0MsMkJBQWUsRUFDZixnQkFBZ0IsQ0FBQyxLQUFLLENBQ3ZCO2dCQUVELElBQUksQ0FBQyxXQUFXLEVBQUU7b0JBQ2hCOztJQUdGLFlBQUEsTUFBTSxVQUFVLEdBQ2QsT0FBTyxDQUFDLFdBQVcsQ0FDakJOLG9CQUFVLENBQUMsY0FBYyxFQUN6QixnQkFBZ0IsQ0FBQyxLQUFLLENBQ3ZCLElBQUksRUFBRTtJQUNULFlBQUEsT0FBTyxDQUFDLGNBQWMsQ0FDcEJBLG9CQUFVLENBQUMsY0FBYyxFQUN6QixDQUFDLEdBQUcsVUFBVSxFQUFFLFlBQVksQ0FBQyxFQUM3QixnQkFBZ0IsQ0FBQyxLQUFLLENBQ3ZCOztJQUVMLEtBQUM7SUFDSDtJQUVnQixTQUFBLG1CQUFtQixDQUNqQyxLQUF1RSxFQUN2RSxXQUFvQixFQUFBO1FBRXBCLElBQUksQ0FBQyxLQUFLLEVBQUU7SUFDVixRQUFBLE9BQU8sQ0FBQyxLQUFrQixFQUFFLFdBQVcsQ0FBQzs7UUFFMUMsSUFBSSxXQUFXLEVBQUU7SUFDZixRQUFBLE9BQU8sQ0FBQyxLQUFpQixFQUFFLFdBQVcsQ0FBQzs7SUFFekMsSUFBQSxNQUFNLFlBQVksR0FBR08sY0FBTyxDQUFDLEtBQUssQ0FBQztJQUNuQyxJQUFBLE1BQU0sSUFBSSxHQUFHLFlBQVksR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSztJQUM1QyxJQUFBLE9BQU8sQ0FBQyxJQUFnQixFQUFFLFlBQVksQ0FBQztJQUN6Qzs7SUNsTEEsTUFBTSxXQUFXLEdBQUcsQ0FDbEIsSUFBd0IsTUFNcEIsSUFBSSxDQUFDLE9BQU8sSUFBSSxNQUFNLElBQUksSUFBSSxJQUFJLElBQUksQ0FBQyxJQUFJLEtBQUssU0FBUyxDQUFZO0lBRTNFOztJQUVHO0lBQ2EsU0FBQSxXQUFXLENBQ3pCLE9BQUEsR0FBOEIsRUFBRSxFQUFBO0lBRWhDLElBQUEsT0FBTywwQkFBMEIsQ0FBQyxPQUFPLENBQUM7SUFDNUM7SUFFTSxTQUFVLDBCQUEwQixDQUN4QyxPQUFBLEdBQThCLEVBQUUsRUFDaEMsZ0JBQWdCLEdBQUcsSUFBSSxFQUFBO0lBRXZCLElBQUEsTUFBTSxDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsR0FBR0MsMkJBQW1CLENBQ3pDLE9BQU8sQ0FBQyxJQUFJLEVBQ1osT0FBTyxDQUFDLE9BQWtCLENBQzNCO0lBQ0QsSUFBQSxPQUFPLEdBQUc7SUFDUixRQUFBLEdBQUcsT0FBTztZQUNWLElBQUk7WUFDSixPQUFPO1NBQ2M7SUFFdkIsSUFBQSxJQUFJLFdBQVcsQ0FBQyxPQUFPLENBQUMsRUFBRTtJQUN4QixRQUFBLE9BQU8sQ0FBQyxJQUFJLEdBQUcsT0FBTztZQUV0QixNQUFNLFVBQVUsR0FBR0Msd0JBQWEsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDO1lBQzlDLE9BQU8sQ0FBQyxLQUFLLEdBQUc7SUFDZCxZQUFBLElBQUksRUFBRUMsc0JBQVcsQ0FBQyxVQUFVLENBQUM7SUFDN0IsWUFBQSxJQUFJLEVBQUUsVUFBVTthQUNqQjs7WUFFRCxPQUFPLE9BQU8sQ0FBQyxJQUFJOzthQUNkLElBQUksTUFBTSxJQUFJLE9BQU8sSUFBSSxPQUFPLENBQUMsSUFBSSxLQUFLLFNBQVMsRUFBRTtZQUMxRCxNQUFNLFVBQVUsR0FBR0Qsd0JBQWEsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDO0lBRTlDLFFBQUEsT0FBTyxDQUFDLElBQUksR0FBRyxVQUFVO0lBQ3pCLFFBQUEsT0FBTyxDQUFDLElBQUksR0FBR0Msc0JBQVcsQ0FBQyxVQUFVLENBQUM7O1FBR3hDLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUU7SUFDL0IsUUFBQSxPQUFPLENBQUMsSUFBSSxHQUFHLE9BQU87WUFDdEIsT0FBTyxDQUFDLEtBQUssR0FBRztJQUNkLFlBQUEsSUFBSSxFQUFFLE9BQU87SUFDYixZQUFBLEtBQUssRUFBRTtJQUNMLGdCQUFBLElBQUksRUFBRSxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztJQUN0QixhQUFBO2FBQ0Y7O1FBR0gsT0FBTyx1QkFBdUIsQ0FDNUJWLG9CQUFVLENBQUMsb0JBQW9CLEVBQy9CLE9BQU8sRUFDUCxnQkFBZ0IsQ0FDakI7SUFDSDtJQUVnQixTQUFBLG1CQUFtQixDQUNqQyxPQUFBLEdBQThCLEVBQUUsRUFBQTtJQUVoQyxJQUFBLE9BQU8sV0FBVyxDQUFDO0lBQ2pCLFFBQUEsR0FBRyxPQUFPO0lBQ1YsUUFBQSxRQUFRLEVBQUUsS0FBSztJQUNNLEtBQUEsQ0FBQztJQUMxQjtJQUVnQixTQUFBLG1CQUFtQixDQUNqQyxPQUFBLEdBR0ksRUFBRSxFQUFBO0lBRU4sSUFBQSxPQUFPLFdBQVcsQ0FBQztJQUNqQixRQUFBLFFBQVEsRUFBRSxJQUFJO0lBQ2QsUUFBQSxHQUFHLE9BQU87SUFDVyxLQUFBLENBQUM7SUFDMUI7O0FDOUdBVyx5QkFBVSxDQUFDLEdBQUcsQ0FBQ0Msb0NBQWUsQ0FBQyxVQUFVO0lBQ3RDLEtBQUEsTUFBTSxDQUFDO0lBQ04sSUFBQSxTQUFTLEVBQUUsU0FBUyxjQUFjLENBQ2hDLFFBQThCLEVBQzlCLEdBQXFCLEVBQUE7SUFFckIsUUFBQSxPQUFPQyxpQkFBVSxDQUFDO0lBQ2hCLFlBQUEsS0FBSyxFQUFFLEdBQUcsQ0FBQyxTQUFTLEdBQUdDLFlBQUssQ0FBQyxPQUFPLEdBQUdBLFlBQUssQ0FBQyxPQUFPO2dCQUNwRCxPQUFPLEVBQUUsR0FBRyxDQUFDLFNBQVMsR0FBRyxTQUFTLEdBQUcsSUFBSTtJQUMxQyxTQUFBLENBQUM7U0FDSDtLQUNGO0lBQ0EsS0FBQSxLQUFLLEVBQUU7QUFFVkgseUJBQVUsQ0FBQyxHQUFHLENBQUNDLG9DQUFlLENBQUMsTUFBTTtJQUNsQyxLQUFBLE1BQU0sQ0FBQztJQUNOLElBQUEsU0FBUyxFQUFFLFNBQVMsVUFBVSxDQUM1QixRQUF1Qzs7UUFFdkMsR0FBa0IsRUFBQTtJQUVsQixRQUFBLE9BQU8sU0FBUyxlQUFlLENBQzdCLE1BQWMsRUFDZCxXQUFpQixFQUNqQixVQUFnQixFQUFBO0lBRWhCLFlBQUEsT0FBT0csYUFBTSxDQUFDLFFBQVEsSUFBSyxNQUFzQixDQUFDLENBQ2hELE1BQU0sRUFDTixXQUFXLEVBQ1gsVUFBVSxDQUNYO0lBQ0gsU0FBQztTQUNGO0tBQ0Y7SUFDQSxLQUFBLEtBQUssRUFBRTtBQUVWSix5QkFBVSxDQUFDLEdBQUcsQ0FBQ0ssa0NBQWMsQ0FBQyxRQUFRO1NBQ25DLE1BQU0sQ0FDTCxXQUFXLENBQUM7SUFDVixJQUFBLFFBQVEsRUFBRSxJQUFJO0lBQ2YsQ0FBQSxDQUFDO0lBRUgsS0FBQSxLQUFLLEVBQUU7QUFFVkwseUJBQVUsQ0FBQyxHQUFHLENBQUNLLGtDQUFjLENBQUMsR0FBRztJQUM5QixLQUFBLE1BQU0sQ0FBQztJQUNOLElBQUEsU0FBUyxFQUFFLFNBQVMsTUFBTSxDQUFDLEdBQVcsRUFBQTtZQUNwQyxPQUFPLFdBQVcsQ0FBQyxFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsQ0FBQztTQUNyQztLQUNGO0lBQ0EsS0FBQSxLQUFLLEVBQUU7QUFFVkwseUJBQVUsQ0FBQyxHQUFHLENBQUNLLGtDQUFjLENBQUMsR0FBRztJQUM5QixLQUFBLE1BQU0sQ0FBQztJQUNOLElBQUEsU0FBUyxFQUFFLFNBQVMsTUFBTSxDQUFDLEdBQVcsRUFBQTtZQUNwQyxPQUFPLFdBQVcsQ0FBQyxFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsQ0FBQztTQUNyQztLQUNGO0lBQ0EsS0FBQSxLQUFLLEVBQUU7QUFFVkwseUJBQVUsQ0FBQyxHQUFHLENBQUNLLGtDQUFjLENBQUMsVUFBVTtJQUNyQyxLQUFBLE1BQU0sQ0FBQztJQUNOLElBQUEsU0FBUyxFQUFFLFNBQVMsWUFBWSxDQUFDLEdBQVcsRUFBQTtZQUMxQyxPQUFPLFdBQVcsQ0FBQyxFQUFFLFNBQVMsRUFBRSxHQUFHLEVBQUUsQ0FBQztTQUN2QztLQUNGO0lBQ0EsS0FBQSxLQUFLLEVBQUU7QUFFVkwseUJBQVUsQ0FBQyxHQUFHLENBQUNLLGtDQUFjLENBQUMsVUFBVTtJQUNyQyxLQUFBLE1BQU0sQ0FBQztJQUNOLElBQUEsU0FBUyxFQUFFLFNBQVMsWUFBWSxDQUFDLEdBQVcsRUFBQTtZQUMxQyxPQUFPLFdBQVcsQ0FBQyxFQUFFLFNBQVMsRUFBRSxHQUFHLEVBQUUsQ0FBQztTQUN2QztLQUNGO0lBQ0EsS0FBQSxLQUFLLEVBQUU7SUFDVjtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtBQUVBTCx5QkFBVSxDQUFDLEdBQUcsQ0FBQ0ssa0NBQWMsQ0FBQyxJQUFJO0lBQy9CLEtBQUEsTUFBTSxDQUFDO0lBQ04sSUFBQSxTQUFTLEVBQUUsU0FBUyxPQUFPLENBQ3pCLEtBR21ELEVBQUE7SUFFbkQsUUFBQSxNQUFNLENBQUMsR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLO1lBQ2pELE9BQU8sV0FBVyxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztTQUNsQztLQUNGO0lBQ0EsS0FBQSxLQUFLLEVBQUU7SUFFVjtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7QUFFQUwseUJBQVUsQ0FBQyxHQUFHLENBQUNLLGtDQUFjLENBQUMsT0FBTztJQUNsQyxLQUFBLE1BQU0sQ0FBQztJQUNOLElBQUEsU0FBUyxFQUFFLFNBQVMsVUFBVSxDQUFDLEdBQW9CLEVBQUE7SUFDakQsUUFBQSxPQUFPLFdBQVcsQ0FBQztJQUNqQixZQUFBLE9BQU8sRUFBRSxPQUFPLEdBQUcsS0FBSyxRQUFRLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQyxNQUFNO0lBQ3BELFNBQUEsQ0FBQztTQUNIO0tBQ0Y7SUFDQSxLQUFBLEtBQUssRUFBRTtBQUVWTCx5QkFBVSxDQUFDLEdBQUcsQ0FBQ00sb0JBQWUsQ0FBQyxNQUFNO0lBQ2xDLEtBQUEsTUFBTSxDQUFDO0lBQ04sSUFBQSxTQUFTLEVBQUUsU0FBUyxTQUFTLENBQUMsSUFBWSxFQUFBO0lBQ3hDLFFBQUEsT0FBTyxXQUFXLENBQUM7SUFDakIsWUFBQSxJQUFJLEVBQUUsSUFBSTtJQUNYLFNBQUEsQ0FBQztTQUNIO0tBQ0Y7SUFDQSxLQUFBLEtBQUssRUFBRTtBQUVWTix5QkFBVSxDQUFDLEdBQUcsQ0FBQ08seUJBQWMsQ0FBQyxXQUFXO0lBQ3RDLEtBQUEsTUFBTSxDQUFDO0lBQ04sSUFBQSxTQUFTLEVBQUUsU0FBUyxjQUFjLENBQUMsV0FBbUIsRUFBQTtJQUNwRCxRQUFBLE9BQU8sV0FBVyxDQUFDO0lBQ2pCLFlBQUEsV0FBVyxFQUFFLFdBQVc7SUFDekIsU0FBQSxDQUFDO1NBQ0g7S0FDRjtJQUNBLEtBQUEsS0FBSyxFQUFFOztBQzNKSCxVQUFNLG9CQUFvQixHQUFHO0FBQzdCLFVBQU0sZ0JBQWdCLEdBQUc7OztJQ2dCekIsSUFBTSxlQUFlLEdBQXJCLE1BQU0sZUFBZSxDQUFBOztpQkFNWCxJQUFnQixDQUFBLGdCQUFBLEdBQzdCLElBRDZCLENBQ3hCO0lBRUcsSUFBQSxXQUFXLEdBQUcsR0FBQTtZQUN0QixJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU87Z0JBQUUsSUFBSSxDQUFDLE9BQU8sR0FBR0MsZUFBTyxDQUFDLEdBQUcsQ0FBQyxpQkFBZSxDQUFDO1lBQzlELE9BQU8sSUFBSSxDQUFDLE9BQU87O1FBR3JCLFdBRW1CLENBQUEsT0FBMEMsRUFDMUMsU0FBb0IsRUFBQTtZQURwQixJQUFPLENBQUEsT0FBQSxHQUFQLE9BQU87WUFDUCxJQUFTLENBQUEsU0FBQSxHQUFULFNBQVM7O0lBRzVCLElBQUEsYUFBYSxhQUFhLENBQ3hCLE9BQTJCLEVBQUE7SUFFM0IsUUFBQSxJQUFJLENBQUMsSUFBSSxDQUFDLGdCQUFnQixFQUFFO0lBQzFCLFlBQUEsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQztJQUM1QyxZQUFBLEdBQUcsQ0FBQyxJQUFJLENBQUMsOEJBQThCLENBQUM7SUFDeEMsWUFBQSxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSxPQUFPLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLEtBQUssQ0FBQztJQUN4RSxZQUFBLEdBQUcsQ0FBQyxJQUFJLENBQUMsd0NBQXdDLENBQUM7O1lBRXBELE9BQU8sSUFBSSxDQUFDLGdCQUFnQjs7SUFHOUIsSUFBQSxPQUFPLGtCQUFrQixHQUFBO1lBQ3ZCLE9BQU8sSUFBSSxDQUFDLGdCQUFnQjs7UUFHOUIsT0FBTyxPQUFPLENBQUMsT0FBMkIsRUFBQTtJQUN4QyxRQUFBLE1BQU0sb0JBQW9CLEdBQUc7SUFDM0IsWUFBQSxPQUFPLEVBQUUsb0JBQW9CO0lBQzdCLFlBQUEsUUFBUSxFQUFFLE9BQU87YUFDbEI7SUFFRCxRQUFBLE1BQU0sT0FBTyxHQUF5QjtJQUNwQyxZQUFBLFVBQVUsRUFBRSxPQUFPLElBQXdCLEtBQUk7SUFDN0MsZ0JBQUEsT0FBTyxpQkFBZSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUM7aUJBQzNDO0lBQ0QsWUFBQSxPQUFPLEVBQUUsZ0JBQWdCO0lBQ3pCLFlBQUEsT0FBTyxFQUFFLElBQUk7Z0JBQ2IsS0FBSyxFQUFFTCxZQUFLLENBQUMsT0FBTztnQkFDcEIsTUFBTSxFQUFFLENBQUMsb0JBQW9CLENBQUM7YUFDL0I7SUFFRCxRQUFBLE1BQU0sU0FBUyxHQUFHLENBQUMsT0FBTyxFQUFFLG9CQUFvQixDQUFDO0lBQ2pELFFBQUEsTUFBTSxPQUFPLEdBQUcsQ0FBQyxPQUFPLENBQUM7WUFFekIsT0FBTztJQUNMLFlBQUEsTUFBTSxFQUFFLGlCQUFlO2dCQUN2QixTQUFTO2dCQUNULE9BQU87YUFDUjs7SUFHSCxJQUFBLE1BQU0scUJBQXFCLEdBQUE7SUFDekIsUUFBQSxNQUFNLEdBQUcsR0FBRyxpQkFBZSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLHFCQUFxQixDQUFDO1lBQy9ELE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFVLGdCQUFnQixDQUFDO0lBQzdELFFBQUEsSUFBSTtnQkFDRixJQUFJLE9BQU8sRUFBRTtJQUNYLGdCQUFBLEdBQUcsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDO0lBQ3pCLGdCQUFBLE1BQU0sT0FBTyxDQUFDLFFBQVEsRUFBRTtJQUN4QixnQkFBQSxpQkFBZSxDQUFDLGdCQUFnQixHQUFHLElBQUk7OztZQUV6QyxPQUFPLENBQVUsRUFBRTtJQUNuQixZQUFBLEdBQUcsQ0FBQyxLQUFLLENBQUMsZ0NBQWdDLEVBQUUsQ0FBVSxDQUFDOzs7O0lBeEVoRCxlQUFlLEdBQUEsaUJBQUEsR0FBQU0sZ0JBQUEsQ0FBQTtJQUYzQixJQUFBQyxhQUFNLEVBQUU7UUFDUkMsYUFBTSxDQUFDLEVBQUUsQ0FBQztJQWdCTixJQUFBQyxhQUFBLENBQUEsQ0FBQSxFQUFBUixhQUFNLENBQUMsb0JBQW9CLENBQUMsQ0FBQTt1REFFRFMsZ0JBQVMsQ0FBQTtJQWpCNUIsQ0FBQSxFQUFBLGVBQWUsQ0EyRTNCOztBQ3JGWUMsdUJBQVcsR0FBakIsTUFBTSxXQUFXLENBQUE7SUFDdEIsSUFBQSxHQUFHLENBQWtCLEtBQThCLEVBQUE7SUFDakQsUUFBQSxLQUFLLEdBQUcsT0FBTyxLQUFLLEtBQUssUUFBUSxHQUFJQyx5QkFBSyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQVMsR0FBRyxLQUFLO1lBQ3JFLElBQUksQ0FBQyxLQUFLLEVBQUU7SUFDVixZQUFBLE1BQU0sSUFBSUMsMEJBQWEsQ0FBQyxpQ0FBaUMsS0FBSyxDQUFBLENBQUUsQ0FBQzs7SUFFbkUsUUFBQSxPQUFPQyxlQUFVLENBQUMsUUFBUSxDQUFDLEtBQXVCLENBQUM7OztBQU4xQ0gsdUJBQVcsR0FBQUwsZ0JBQUEsQ0FBQTtJQUR2QixJQUFBUCxpQkFBVTtJQUNFLENBQUEsRUFBQVksbUJBQVcsQ0FRdkI7OztJQ2VNLElBQU0sZ0JBQWdCLEdBQXRCLE1BQU0sZ0JBQWdCLENBQUE7O0lBR2pCLElBQUEsV0FBVyxHQUFHLEdBQUE7WUFDdEIsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPO2dCQUFFLElBQUksQ0FBQyxPQUFPLEdBQUdOLGVBQU8sQ0FBQyxHQUFHLENBQUMsa0JBQWdCLENBQUM7WUFDL0QsT0FBTyxJQUFJLENBQUMsT0FBTzs7SUFHTixJQUFQLE9BQU8saUJBQWlCLENBQzlCLFVBQWlDLEVBQUE7SUFFakMsUUFBQSxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUM7WUFDaEQsTUFBTSxTQUFTLEdBQUdTLGVBQVUsQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDO0lBQzlDLFFBQUEsTUFBTSxTQUFTLEdBQUdDLG1CQUFXLENBQUMsU0FBUyxDQUFDO0lBQ3hDLFFBQUEsTUFBTSxjQUFjLEdBQUcsVUFBVSxDQUFDLElBQUk7SUFFdEMsUUFBQSxHQUFHLENBQUMsS0FBSyxDQUFDLGtDQUFrQyxjQUFjLENBQUEsQ0FBRSxDQUFDO0lBRTdELFFBQUEsSUFHTSxzQkFBc0IsR0FINUIsTUFHTSxzQkFBdUIsU0FBUUMsbUJBQVcsQ0FBQTtJQUs5QyxZQUFBLFdBQUEsQ0FBNkIsV0FBd0IsRUFBQTtJQUNuRCxnQkFBQSxLQUFLLEVBQUU7b0JBRG9CLElBQVcsQ0FBQSxXQUFBLEdBQVgsV0FBVztvQkFFdEMsR0FBRyxDQUFDLElBQUksQ0FDTixDQUFBLDBDQUFBLEVBQTZDLGNBQWMsQ0FBWSxTQUFBLEVBQUEsU0FBUyxDQUFFLENBQUEsQ0FDbkY7SUFFRCxnQkFBQSxJQUFJO0lBQ0Ysb0JBQUEsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDO3dCQUNqRCxJQUFJLENBQUMsRUFBRSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBWTs7b0JBQ2hDLE9BQU8sQ0FBTSxFQUFFO0lBQ2Ysb0JBQUEsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQ1osQ0FBQSwyQ0FBQSxFQUE4QyxVQUFVLENBQUMsSUFBSSxDQUFBLEVBQUEsQ0FBSSxFQUNqRSxDQUFDLENBQ0Y7OztJQWlCQyxZQUFOLE1BQU0sTUFBTSxDQUFTLElBQU8sRUFBQTtJQUMxQixnQkFBQSxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDO0lBQ3JDLGdCQUFBLEdBQUcsQ0FBQyxPQUFPLENBQUMsZ0JBQWdCLGNBQWMsQ0FBQSxDQUFFLENBQUM7SUFDN0MsZ0JBQUEsSUFBSSxPQUFjO0lBQ2xCLGdCQUFBLElBQUk7d0JBQ0YsT0FBTyxHQUFHLE1BQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDOztvQkFDdEMsT0FBTyxDQUFVLEVBQUU7d0JBQ25CLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQSxxQkFBQSxFQUF3QixjQUFjLENBQUUsQ0FBQSxFQUFFLENBQVUsQ0FBQztJQUMvRCxvQkFBQSxNQUFNLENBQUM7O0lBRVQsZ0JBQUEsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFBLFlBQUEsRUFBZSxjQUFjLENBQVksU0FBQSxFQUFBLE9BQU8sQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUEsQ0FBRSxDQUFDO0lBQ3JFLGdCQUFBLE9BQU8sT0FBTzs7SUFZVixZQUFOLE1BQU0sSUFBSSxDQUFjLEVBQVUsRUFBQTtJQUNoQyxnQkFBQSxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO0lBQ25DLGdCQUFBLElBQUksSUFBVztJQUNmLGdCQUFBLElBQUk7SUFDRixvQkFBQSxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUEsUUFBQSxFQUFXLGNBQWMsQ0FBQSxNQUFBLEVBQVMsSUFBSSxDQUFDLEVBQUUsQ0FBQSxDQUFBLEVBQUksRUFBRSxDQUFBLENBQUUsQ0FBQzt3QkFDNUQsSUFBSSxHQUFHLE1BQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDOztvQkFDL0IsT0FBTyxDQUFVLEVBQUU7d0JBQ25CLEdBQUcsQ0FBQyxLQUFLLENBQ1AsQ0FBa0IsZUFBQSxFQUFBLGNBQWMsQ0FBWSxTQUFBLEVBQUEsRUFBRSxDQUFFLENBQUEsRUFDaEQsQ0FBVSxDQUNYO0lBQ0Qsb0JBQUEsTUFBTSxDQUFDOztJQUdULGdCQUFBLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQSxLQUFBLEVBQVEsY0FBYyxDQUFZLFNBQUEsRUFBQSxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFBLENBQUUsQ0FBQztJQUMzRCxnQkFBQSxPQUFPLElBQUk7O0lBa0JQLFlBQU4sTUFBTSxNQUFNLENBQVMsSUFBZ0IsRUFBQTtJQUNuQyxnQkFBQSxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDO0lBQ3JDLGdCQUFBLElBQUksT0FBYztJQUNsQixnQkFBQSxJQUFJO0lBQ0Ysb0JBQUEsR0FBRyxDQUFDLElBQUksQ0FDTixZQUFZLGNBQWMsQ0FBQSxNQUFBLEVBQVMsSUFBSSxDQUFDLEVBQUUsQ0FBSSxDQUFBLEVBQUEsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQSxDQUFFLENBQzlEO3dCQUNELE9BQU8sR0FBRyxNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQzs7b0JBQ3RDLE9BQU8sQ0FBVSxFQUFFO0lBQ25CLG9CQUFBLE1BQU0sQ0FBQzs7SUFFVCxnQkFBQSxPQUFPLE9BQU87O0lBZVYsWUFBTixNQUFNLE1BQU0sQ0FBYyxFQUFVLEVBQUE7SUFDbEMsZ0JBQUEsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQztJQUNyQyxnQkFBQSxJQUFJLElBQVc7SUFDZixnQkFBQSxJQUFJO0lBQ0Ysb0JBQUEsR0FBRyxDQUFDLEtBQUssQ0FDUCxDQUFBLFNBQUEsRUFBWSxjQUFjLENBQUEsTUFBQSxFQUFTLElBQUksQ0FBQyxFQUFZLENBQUEsQ0FBQSxFQUFJLEVBQUUsQ0FBQSxDQUFFLENBQzdEO3dCQUNELElBQUksR0FBRyxNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQzs7b0JBQy9CLE9BQU8sQ0FBVSxFQUFFO3dCQUNuQixHQUFHLENBQUMsS0FBSyxDQUNQLENBQW9CLGlCQUFBLEVBQUEsY0FBYyxDQUFZLFNBQUEsRUFBQSxFQUFFLENBQUUsQ0FBQSxFQUNsRCxDQUFVLENBQ1g7SUFDRCxvQkFBQSxNQUFNLENBQUM7O0lBRVQsZ0JBQUEsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFBLFFBQUEsRUFBVyxjQUFjLENBQVksU0FBQSxFQUFBLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUEsQ0FBRSxDQUFDO0lBQzlELGdCQUFBLE9BQU8sSUFBSTs7YUFFZDtJQXBHTyxRQUFBVixnQkFBQSxDQUFBO0lBYkwsWUFBQVcsV0FBSSxFQUFFO2dCQUNOQyxvQkFBWSxDQUFDLEVBQUUsT0FBTyxFQUFFLGdCQUFnQixjQUFjLENBQUEsQ0FBQSxDQUFHLEVBQUUsQ0FBQztJQUM1RCxZQUFBQyxlQUFPLENBQUM7b0JBQ1AsV0FBVyxFQUFFLENBQWUsWUFBQSxFQUFBLGNBQWMsQ0FBRSxDQUFBO29CQUM1QyxNQUFNLEVBQUUsRUFBRSxJQUFJLEVBQUVDLHFCQUFhLENBQUMsVUFBVSxDQUFDLEVBQUU7aUJBQzVDLENBQUM7SUFDRCxZQUFBQywwQkFBa0IsQ0FBQztvQkFDbEIsV0FBVyxFQUFFLENBQUcsRUFBQSxjQUFjLENBQXdCLHNCQUFBLENBQUE7aUJBQ3ZELENBQUM7SUFDRCxZQUFBQyw2QkFBcUIsQ0FBQyxFQUFFLFdBQVcsRUFBRSw0QkFBNEIsRUFBRSxDQUFDO0lBQ3BFLFlBQUFDLHNDQUE4QixDQUFDO0lBQzlCLGdCQUFBLFdBQVcsRUFBRSwyQ0FBMkM7aUJBQ3pELENBQUM7Z0JBQ1lkLGFBQUEsQ0FBQSxDQUFBLEVBQUFlLFdBQUksRUFBRSxDQUFBOzs7O0lBWW5CLFNBQUEsRUFBQSxzQkFBQSxDQUFBLFNBQUEsRUFBQSxRQUFBLEVBQUEsSUFBQSxDQUFBO0lBV0ssUUFBQWxCLGdCQUFBLENBQUE7Z0JBVExtQixVQUFHLENBQUMsS0FBSyxDQUFDO2dCQUNWUCxvQkFBWSxDQUFDLEVBQUUsT0FBTyxFQUFFLGNBQWMsY0FBYyxDQUFBLGNBQUEsQ0FBZ0IsRUFBRSxDQUFDO2dCQUN2RVEsZ0JBQVEsQ0FBQyxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFFLGFBQWEsRUFBRSxDQUFDO0lBQ3BELFlBQUFDLHFCQUFhLENBQUM7b0JBQ2IsV0FBVyxFQUFFLENBQUcsRUFBQSxjQUFjLENBQTBCLHdCQUFBLENBQUE7aUJBQ3pELENBQUM7SUFDRCxZQUFBQywyQkFBbUIsQ0FBQztvQkFDbkIsV0FBVyxFQUFFLENBQU0sR0FBQSxFQUFBLGNBQWMsQ0FBMEMsd0NBQUEsQ0FBQTtpQkFDNUUsQ0FBQztJQUNVLFlBQUFuQixhQUFBLENBQUEsQ0FBQSxFQUFBb0IsWUFBSyxDQUFDLElBQUksQ0FBQyxDQUFBOzs7O0lBZ0J0QixTQUFBLEVBQUEsc0JBQUEsQ0FBQSxTQUFBLEVBQUEsTUFBQSxFQUFBLElBQUEsQ0FBQTtJQWlCSyxRQUFBdkIsZ0JBQUEsQ0FBQTtnQkFmTHdCLFVBQUcsQ0FBQyxLQUFLLENBQUM7SUFDVixZQUFBWixvQkFBWSxDQUFDO29CQUNaLE9BQU8sRUFBRSxDQUF1QixvQkFBQSxFQUFBLGNBQWMsQ0FBNkIsMkJBQUEsQ0FBQTtpQkFDNUUsQ0FBQztJQUNELFlBQUFDLGVBQU8sQ0FBQztvQkFDUCxXQUFXLEVBQUUsQ0FBNEMseUNBQUEsRUFBQSxjQUFjLENBQUUsQ0FBQTtvQkFDekUsTUFBTSxFQUFFLEVBQUUsSUFBSSxFQUFFQyxxQkFBYSxDQUFDLFVBQVUsQ0FBQyxFQUFFO2lCQUM1QyxDQUFDO0lBQ0QsWUFBQU8scUJBQWEsQ0FBQztvQkFDYixXQUFXLEVBQUUsQ0FBRyxFQUFBLFVBQVUsQ0FBZ0MsOEJBQUEsQ0FBQTtpQkFDM0QsQ0FBQztJQUNELFlBQUFDLDJCQUFtQixDQUFDO29CQUNuQixXQUFXLEVBQUUsQ0FBTSxHQUFBLEVBQUEsY0FBYyxDQUEwQyx3Q0FBQSxDQUFBO2lCQUM1RSxDQUFDO0lBQ0QsWUFBQU4sNkJBQXFCLENBQUMsRUFBRSxXQUFXLEVBQUUsNEJBQTRCLEVBQUUsQ0FBQztnQkFDdkRiLGFBQUEsQ0FBQSxDQUFBLEVBQUFlLFdBQUksRUFBRSxDQUFBOzt1REFBT1oseUJBQUssQ0FBQSxDQUFBOztJQVkvQixTQUFBLEVBQUEsc0JBQUEsQ0FBQSxTQUFBLEVBQUEsUUFBQSxFQUFBLElBQUEsQ0FBQTtJQWNLLFFBQUFOLGdCQUFBLENBQUE7Z0JBWkx5QixhQUFNLENBQUMsS0FBSyxDQUFDO2dCQUNiYixvQkFBWSxDQUFDLEVBQUUsT0FBTyxFQUFFLFlBQVksY0FBYyxDQUFBLGNBQUEsQ0FBZ0IsRUFBRSxDQUFDO0lBQ3JFLFlBQUFRLGdCQUFRLENBQUM7SUFDUixnQkFBQSxJQUFJLEVBQUUsSUFBSTtvQkFDVixXQUFXLEVBQUUsQ0FBNEIseUJBQUEsRUFBQSxjQUFjLENBQW9CLGtCQUFBLENBQUE7aUJBQzVFLENBQUM7SUFDRCxZQUFBQyxxQkFBYSxDQUFDO29CQUNiLFdBQVcsRUFBRSxDQUFHLEVBQUEsY0FBYyxDQUErQiw2QkFBQSxDQUFBO2lCQUM5RCxDQUFDO0lBQ0QsWUFBQUMsMkJBQW1CLENBQUM7b0JBQ25CLFdBQVcsRUFBRSxDQUFNLEdBQUEsRUFBQSxjQUFjLENBQTBDLHdDQUFBLENBQUE7aUJBQzVFLENBQUM7SUFDWSxZQUFBbkIsYUFBQSxDQUFBLENBQUEsRUFBQW9CLFlBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQTs7OztJQWlCeEIsU0FBQSxFQUFBLHNCQUFBLENBQUEsU0FBQSxFQUFBLFFBQUEsRUFBQSxJQUFBLENBQUE7WUF0SUcsc0JBQXNCLEdBQUF2QixnQkFBQSxDQUFBO2dCQUgzQjBCLGlCQUFVLENBQUMsU0FBUyxDQUFDO2dCQUNyQkMsZUFBTyxDQUFDLGNBQWMsQ0FBQztnQkFDdkJDLHNCQUFjLENBQUMsVUFBVSxDQUFDO3VEQU1pQnZCLG1CQUFXLENBQUE7SUFMakQsU0FBQSxFQUFBLHNCQUFzQixDQXVJM0I7SUFFRCxRQUFBLE9BQU8sc0JBQXNCOztRQUcvQixPQUFPLE9BQU8sQ0FBQyxPQUFlLEVBQUE7SUFDNUIsUUFBQSxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDO0lBQ3RDLFFBQUEsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFBLHFDQUFBLENBQXVDLENBQUM7WUFFakQsTUFBTSxhQUFhLEdBQUd3QixZQUFPLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQztJQUM3QyxRQUFBLE1BQU0sV0FBVyxHQUFHLGFBQWEsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUV4RSxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUEsVUFBQSxFQUFhLFdBQVcsQ0FBQyxNQUFNLENBQWMsWUFBQSxDQUFBLENBQUM7WUFFdkQsT0FBTztJQUNMLFlBQUEsTUFBTSxFQUFFLGtCQUFnQjtnQkFDeEIsV0FBVztnQkFDWCxTQUFTLEVBQUUsQ0FBQ3hCLG1CQUFXLENBQUM7YUFDekI7O0tBRUo7SUFoTFksZ0JBQWdCLEdBQUEsa0JBQUEsR0FBQUwsZ0JBQUEsQ0FBQTtRQUQ1QkUsYUFBTSxDQUFDLEVBQUU7SUFDRyxDQUFBLEVBQUEsZ0JBQWdCLENBZ0w1Qjs7O0lDek1EOztJQUVHO0FBRVU0Qix1QkFBVyxHQUFqQixhQUFBLEdBQUEsTUFBTSxXQUFXLENBQUE7SUFDdEIsSUFBQSxhQUFhLFlBQVksQ0FDdkIsT0FBMkIsRUFBQTtJQUUzQixRQUFBLE1BQU0sRUFBRSxlQUFlLEVBQUUsR0FBRyxPQUFPO1lBRW5DLE1BQU0sT0FBTyxHQUFHLE1BQU0sZUFBZSxDQUFDLGFBQWEsQ0FBQyxPQUFPLENBQUM7SUFDNUQsUUFBQSxNQUFNLE9BQU8sR0FBRyxPQUFPLENBQUMsT0FBTztZQUUvQixNQUFNLE9BQU8sR0FPRyxDQUFDLGVBQWUsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUM7WUFFbEQsSUFBSSxlQUFlLEVBQUU7Z0JBQ25CLE9BQU8sQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDOztZQUdqRCxPQUFPO0lBQ0wsWUFBQSxNQUFNLEVBQUUsYUFBVztJQUNuQixZQUFBLE9BQU8sRUFBRSxPQUFPO2FBQ2pCOzs7QUF6QlFBLHVCQUFXLEdBQUEsYUFBQSxHQUFBOUIsZ0JBQUEsQ0FBQTtRQUR2QkUsYUFBTSxDQUFDLEVBQUU7SUFDRyxDQUFBLEVBQUE0QixtQkFBVyxDQTJCdkI7O0lDaENLLFNBQVUsWUFBWSxDQUFDLEtBQWEsRUFBQTtRQUN6QyxNQUFNLENBQUMsR0FBR3hCLHlCQUFLLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQztJQUMxQixJQUFBLElBQUksQ0FBQyxDQUFDO0lBQ0wsUUFBQSxNQUFNLElBQUlDLDBCQUFhLENBQUMsaUNBQWlDLEtBQUssQ0FBQSxDQUFFLENBQUM7UUFDbEUsTUFBTSxJQUFJLEdBQUdDLGVBQVUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO0lBQ25DLElBQUEsT0FBTyxJQUFJO0lBQ1o7O0lDUk0sTUFBTyxTQUFVLFNBQVF1QixtQkFBYyxDQUFBO0lBQzVDLElBQUEsV0FBQSxDQUFZLEdBQW1CLEVBQUE7SUFDOUIsUUFBQSxLQUFLLENBQUMsR0FBRyxFQUFFLFNBQVMsQ0FBQyxJQUFJLENBQUM7O0lBRTNCOztVQ0hZLGlCQUFpQixDQUFBO1FBUTdCLFdBQ0MsQ0FBQSxPQUFnQixFQUNoQixhQUFxRSxFQUFBO1lBRXJFLE1BQU0sTUFBTSxHQUFHLGFBQWEsRUFBRSxNQUFNLElBQUlDLGlCQUFVLENBQUMscUJBQXFCO0lBQ3hFLFFBQUEsTUFBTSxPQUFPLEdBQUcsYUFBYSxFQUFFLE9BQU8sSUFBSSx1QkFBdUI7SUFDakUsUUFBQSxNQUFNLEtBQUssR0FBRyxDQUFDLGFBQWEsRUFBRSxLQUFLLElBQUlBLGlCQUFVLENBQUMsTUFBTSxDQUFDLElBQUksZ0JBQWdCO0lBQzNFLGFBQUEsUUFBUTtJQUNSLGFBQUEsV0FBVyxFQUFFO0lBRWYsUUFBQSxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRTtnQkFDbkIsTUFBTTtnQkFDTixPQUFPO2dCQUNQLEtBQUs7SUFDTCxZQUFBLFNBQVMsRUFBRSxJQUFJLElBQUksRUFBRSxDQUFDLFdBQVcsRUFBRTtnQkFDbkMsSUFBSSxFQUFFLE9BQU8sQ0FBQyxHQUFHO2dCQUNqQixNQUFNLEVBQUUsT0FBTyxDQUFDLE1BQU07SUFDdEIsU0FBQSxDQUFDOztJQUVIOztJQzFCSyxNQUFPLGtCQUFtQixTQUFRLEtBQUssQ0FBQTtRQUl6QyxXQUFZLENBQUEsT0FBTyxHQUFHLGNBQWMsRUFBQTtZQUNoQyxLQUFLLENBQUMsT0FBTyxDQUFDO0lBQ2QsUUFBQSxJQUFJLENBQUMsSUFBSSxHQUFHLG9CQUFvQjtJQUNoQyxRQUFBLElBQUksQ0FBQyxNQUFNLEdBQUcsR0FBRztJQUNqQixRQUFBLElBQUksQ0FBQyxJQUFJLEdBQUcsY0FBYztZQUMxQixNQUFNLENBQUMsY0FBYyxDQUFDLElBQUksRUFBRSxrQkFBa0IsQ0FBQyxTQUFTLENBQUM7O0lBRWhFO0FBR1lDLHdDQUE0QixHQUFsQyxNQUFNLDRCQUE0QixDQUFBO1FBQ3JDLEtBQUssQ0FBQyxTQUE2QixFQUFFLElBQW1CLEVBQUE7SUFDcEQsUUFBQSxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsWUFBWSxFQUFFO0lBQy9CLFFBQUEsTUFBTSxPQUFPLEdBQUcsR0FBRyxDQUFDLFVBQVUsRUFBVztJQUN6QyxRQUFBLE1BQU0sUUFBUSxHQUFHLEdBQUcsQ0FBQyxXQUFXLEVBQVk7SUFFNUMsUUFBQSxNQUFNLGlCQUFpQixHQUFHLElBQUksaUJBQWlCLENBQUMsT0FBTyxFQUFFO0lBQ3JELFlBQUEsS0FBSyxFQUFFLGNBQWM7Z0JBQ3JCLE1BQU0sRUFBRUQsaUJBQVUsQ0FBQyxZQUFZO2dCQUMvQixPQUFPLEVBQUUsU0FBUyxDQUFDLE9BQU87SUFDN0IsU0FBQSxDQUFDO0lBRUYsUUFBQSxRQUFRLENBQUMsTUFBTSxDQUFDQSxpQkFBVSxDQUFDLFlBQVksQ0FBQyxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQzs7O0FBWjNEQyx3Q0FBNEIsR0FBQWpDLGdCQUFBLENBQUE7UUFEeENrQyxZQUFLLENBQUMsa0JBQWtCO0lBQ1osQ0FBQSxFQUFBRCxvQ0FBNEIsQ0FjeEM7O0lDNUJLLE1BQU8sYUFBYyxTQUFRLEtBQUssQ0FBQTtRQUlwQyxXQUFZLENBQUEsT0FBTyxHQUFHLFVBQVUsRUFBQTtZQUM1QixLQUFLLENBQUMsT0FBTyxDQUFDO0lBQ2QsUUFBQSxJQUFJLENBQUMsSUFBSSxHQUFHLGVBQWU7SUFDM0IsUUFBQSxJQUFJLENBQUMsTUFBTSxHQUFHLEdBQUc7SUFDakIsUUFBQSxJQUFJLENBQUMsSUFBSSxHQUFHLFVBQVU7WUFFdEIsTUFBTSxDQUFDLGNBQWMsQ0FBQyxJQUFJLEVBQUUsYUFBYSxDQUFDLFNBQVMsQ0FBQzs7SUFFM0Q7QUFHWUUsbUNBQXVCLEdBQTdCLE1BQU0sdUJBQXVCLENBQUE7UUFDaEMsS0FBSyxDQUFDLFNBQXdCLEVBQUUsSUFBbUIsRUFBQTtJQUMvQyxRQUFBLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxZQUFZLEVBQUU7SUFDL0IsUUFBQSxNQUFNLFFBQVEsR0FBRyxHQUFHLENBQUMsV0FBVyxFQUFZO0lBQzVDLFFBQUEsTUFBTSxPQUFPLEdBQUcsR0FBRyxDQUFDLFVBQVUsRUFBVztJQUV6QyxRQUFBLE1BQU0saUJBQWlCLEdBQUcsSUFBSSxpQkFBaUIsQ0FBQyxPQUFPLEVBQUU7Z0JBQ3JELE1BQU0sRUFBRUgsaUJBQVUsQ0FBQyxRQUFRO2dCQUMzQixPQUFPLEVBQUUsU0FBUyxDQUFDLE9BQU87SUFDMUIsWUFBQSxLQUFLLEVBQUU7SUFDVixTQUFBLENBQUM7SUFFRixRQUFBLFFBQVEsQ0FBQyxNQUFNLENBQUMsaUJBQWlCLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDOzs7QUFaNURHLG1DQUF1QixHQUFBbkMsZ0JBQUEsQ0FBQTtRQURuQ2tDLFlBQUssQ0FBQyxhQUFhO0lBQ1AsQ0FBQSxFQUFBQywrQkFBdUIsQ0FjbkM7O0FDNUJZQyxpQ0FBcUIsR0FBM0IsTUFBTSxxQkFBcUIsQ0FBQTtRQUM5QixLQUFLLENBQUMsU0FBa0IsRUFBRSxJQUFtQixFQUFBO0lBQ3pDLFFBQUEsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLFlBQVksRUFBRTtJQUMvQixRQUFBLE1BQU0sT0FBTyxHQUFHLEdBQUcsQ0FBQyxVQUFVLEVBQVc7SUFDekMsUUFBQSxNQUFNLFFBQVEsR0FBRyxHQUFHLENBQUMsV0FBVyxFQUFZO0lBRTVDLFFBQUEsSUFBSSxNQUFNLEdBQUdKLGlCQUFVLENBQUMscUJBQXFCO1lBQzdDLElBQUksT0FBTyxHQUFHLHVCQUF1QjtJQUNyQyxRQUFBLElBQUksS0FBeUI7SUFFN0IsUUFBQSxJQUFJLFNBQVMsWUFBWUssb0JBQWEsRUFBRTtJQUNwQyxZQUFBLE1BQU0sR0FBRyxHQUFRLFNBQVMsQ0FBQyxXQUFXLEVBQUU7SUFDeEMsWUFBQSxNQUFNLEdBQUcsU0FBUyxDQUFDLFNBQVMsRUFBRTtJQUM5QixZQUFBLE9BQU8sR0FBRyxDQUFDLEdBQUcsRUFBRSxPQUFPLElBQUksU0FBUyxDQUFDLE9BQU8sS0FBSyxPQUFPO2dCQUN4RCxLQUFLLEdBQUcsR0FBRyxFQUFFLEtBQUssSUFBSSxTQUFTLENBQUMsSUFBSTs7SUFDakMsYUFBQSxJQUFJLFNBQVMsWUFBWSxLQUFLLEVBQUU7SUFDbkMsWUFBQSxPQUFPLEdBQUcsU0FBUyxDQUFDLE9BQU87SUFDM0IsWUFBQSxLQUFLLEdBQUcsU0FBUyxDQUFDLElBQUk7O0lBRzFCLFFBQUEsTUFBTSxpQkFBaUIsR0FBRyxJQUFJLGlCQUFpQixDQUFDLE9BQU8sRUFBRSxFQUFDLE1BQU0sRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFDLENBQUM7SUFDbEYsUUFBQSxRQUFRLENBQUMsTUFBTSxDQUFDLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQzs7O0FBckI1REQsaUNBQXFCLEdBQUFwQyxnQkFBQSxDQUFBO0lBRGpDLElBQUFrQyxZQUFLO0lBQ08sQ0FBQSxFQUFBRSw2QkFBcUIsQ0F1QmpDOztBQ3ZCWUUsK0JBQW1CLEdBQXpCLE1BQU0sbUJBQW1CLENBQUE7UUFDNUIsS0FBSyxDQUFDLFNBQXdCLEVBQUUsSUFBbUIsRUFBQTtJQUMvQyxRQUFBLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxZQUFZLEVBQUU7SUFDL0IsUUFBQSxNQUFNLFFBQVEsR0FBRyxHQUFHLENBQUMsV0FBVyxFQUFZO0lBQzVDLFFBQUEsTUFBTSxPQUFPLEdBQUcsR0FBRyxDQUFDLFVBQVUsRUFBVztJQUN6QyxRQUFBLE1BQU0sTUFBTSxHQUFHLFNBQVMsQ0FBQyxTQUFTLEVBQUU7SUFFcEMsUUFBQSxNQUFNLGlCQUFpQixHQUFHLElBQUksaUJBQWlCLENBQUMsT0FBTyxFQUFFO2dCQUNyRCxNQUFNO2dCQUNOLE9BQU8sRUFBRSxTQUFTLENBQUMsT0FBTztnQkFDMUIsS0FBSyxFQUFFLFNBQVMsQ0FBQztJQUNwQixTQUFBLENBQUM7SUFFRixRQUFBLFFBQVEsQ0FBQyxNQUFNLENBQUMsaUJBQWlCLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDOzs7QUFiNURBLCtCQUFtQixHQUFBdEMsZ0JBQUEsQ0FBQTtRQUQvQmtDLFlBQUssQ0FBQ0csb0JBQWE7SUFDUCxDQUFBLEVBQUFDLDJCQUFtQixDQWUvQjs7SUNoQkssTUFBTyxhQUFjLFNBQVEsS0FBSyxDQUFBO1FBSXZDLFdBQVksQ0FBQSxPQUFPLEdBQUcsb0JBQW9CLEVBQUE7WUFDekMsS0FBSyxDQUFDLE9BQU8sQ0FBQztJQUNkLFFBQUEsSUFBSSxDQUFDLElBQUksR0FBRyxlQUFlO0lBQzNCLFFBQUEsSUFBSSxDQUFDLE1BQU0sR0FBRyxHQUFHO0lBQ2pCLFFBQUEsSUFBSSxDQUFDLElBQUksR0FBRyxXQUFXO1lBRXZCLE1BQU0sQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFFLGFBQWEsQ0FBQyxTQUFTLENBQUM7O0lBRXJEO0FBR1lDLG1DQUF1QixHQUE3QixNQUFNLHVCQUF1QixDQUFBO1FBQ25DLEtBQUssQ0FBQyxTQUF3QixFQUFFLElBQW1CLEVBQUE7SUFDbEQsUUFBQSxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsWUFBWSxFQUFFO0lBQy9CLFFBQUEsTUFBTSxRQUFRLEdBQUcsR0FBRyxDQUFDLFdBQVcsRUFBWTtJQUM1QyxRQUFBLE1BQU0sT0FBTyxHQUFHLEdBQUcsQ0FBQyxVQUFVLEVBQVc7SUFFekMsUUFBQSxNQUFNLGlCQUFpQixHQUFHLElBQUksaUJBQWlCLENBQUMsT0FBTyxFQUFFO2dCQUN4RCxNQUFNLEVBQUVQLGlCQUFVLENBQUMsU0FBUztnQkFDNUIsT0FBTyxFQUFFLFNBQVMsQ0FBQyxPQUFPO0lBQzFCLFlBQUEsS0FBSyxFQUFFLFdBQVc7SUFDbEIsU0FBQSxDQUFDO0lBRUYsUUFBQSxRQUFRLENBQUMsTUFBTSxDQUFDLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQzs7O0FBWnRETyxtQ0FBdUIsR0FBQXZDLGdCQUFBLENBQUE7UUFEbkNrQyxZQUFLLENBQUMsYUFBYTtJQUNQLENBQUEsRUFBQUssK0JBQXVCLENBY25DOztJQzdCSyxNQUFPLGVBQWdCLFNBQVEsS0FBSyxDQUFBO1FBSXRDLFdBQVksQ0FBQSxPQUFPLEdBQUcsbUJBQW1CLEVBQUE7WUFDckMsS0FBSyxDQUFDLE9BQU8sQ0FBQztJQUNkLFFBQUEsSUFBSSxDQUFDLElBQUksR0FBRyxpQkFBaUI7SUFDN0IsUUFBQSxJQUFJLENBQUMsTUFBTSxHQUFHLEdBQUc7SUFDakIsUUFBQSxJQUFJLENBQUMsSUFBSSxHQUFHLGtCQUFrQjtZQUU5QixNQUFNLENBQUMsY0FBYyxDQUFDLElBQUksRUFBRSxlQUFlLENBQUMsU0FBUyxDQUFDOztJQUU3RDtBQUdZQyxxQ0FBeUIsR0FBL0IsTUFBTSx5QkFBeUIsQ0FBQTtRQUNsQyxLQUFLLENBQUMsU0FBMEIsRUFBRSxJQUFtQixFQUFBO0lBQ2pELFFBQUEsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLFlBQVksRUFBRTtJQUMvQixRQUFBLE1BQU0sUUFBUSxHQUFHLEdBQUcsQ0FBQyxXQUFXLEVBQVk7SUFDNUMsUUFBQSxNQUFNLE9BQU8sR0FBRyxHQUFHLENBQUMsVUFBVSxFQUFXO0lBRXpDLFFBQUEsTUFBTSxpQkFBaUIsR0FBRyxJQUFJLGlCQUFpQixDQUFDLE9BQU8sRUFBRTtnQkFDckQsTUFBTSxFQUFFUixpQkFBVSxDQUFDLG9CQUFvQjtnQkFDdkMsT0FBTyxFQUFFLFNBQVMsQ0FBQyxPQUFPO0lBQzFCLFlBQUEsS0FBSyxFQUFFO0lBQ1YsU0FBQSxDQUFDO0lBRUYsUUFBQSxRQUFRLENBQUMsTUFBTSxDQUFDLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQzs7O0FBWjVEUSxxQ0FBeUIsR0FBQXhDLGdCQUFBLENBQUE7UUFEckNrQyxZQUFLLENBQUMsZUFBZTtJQUNULENBQUEsRUFBQU0saUNBQXlCLENBY3JDOztJQ2hCTSxNQUFNLG9CQUFvQixHQUFtQjtJQUNsRCxJQUdBLElBQUksRUFBRSxNQUFNO0lBQ1osSUFFQSxJQUFJLEVBQUU7SUFDSixRQUFBLElBQUksRUFBRSxNQUFNO0lBQ1osUUFBQSxNQUFNLEVBQUUsUUFBUTtJQUNoQixRQUFBLFlBQVksRUFBRSxLQUFLO0lBQ25CLFFBQUEsSUFBSSxFQUFFLGVBQWU7SUFDckIsUUFBQSxXQUFXLEVBQUUsaUJBQWlCO0lBQzlCLFFBQUEsRUFBRSxFQUFFLFFBQVE7SUFDYixLQUFBO0lBQ0QsSUFDQSxhQUFhLEVBQUUsU0FBUztLQUN6Qjs7VUNwQlksZUFBZSxDQUFBOzs7Ozs7OztJQVUxQixJQUFBLFdBQUEsQ0FBWSxPQUF5QixFQUFBO1lBQ25DLElBQUksQ0FBQyxPQUFPLEdBQUc7SUFDYixZQUFBLEdBQUcsT0FBTzthQUNYOztRQUdLLFNBQVMsR0FBQTtZQUNmLElBQUksR0FBRyxHQUFHLEVBQUU7SUFDWixRQUFBLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxjQUFjLEVBQUU7SUFDL0IsWUFBQSxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDO0lBQ2pELFlBQUEsR0FBRyxJQUFJLENBQUEsc0RBQUEsRUFBeUQsR0FBRyxDQUFBLG1DQUFBLENBQXFDOztJQUUxRyxRQUFBLFFBQ0UsR0FBRztJQUNILFlBQUE7O0FBRTRDLGdEQUFBLEVBQUEsSUFBSSxDQUFDLE9BQU8sQ0FBQyxhQUFhLElBQUksb0JBQW9CLENBQUMsYUFBYSxDQUFBO0FBQzNHLE1BQUEsQ0FBQTs7UUFJTCxnQkFBZ0IsR0FBQTtZQUNkLE1BQU0sT0FBTyxHQUF3QixFQUFFO0lBQ3ZDLFFBQUEsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLFdBQVcsRUFBRTtJQUM1QixZQUFBLE9BQU8sQ0FBQyxlQUFlLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyxFQUFFLElBQUksQ0FBQzs7WUFHckUsT0FBTztJQUNMLFlBQUEsZUFBZSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSztJQUNuQyxZQUFBLEdBQUcsT0FBTztJQUNWLFlBQUEsU0FBUyxFQUFFLElBQUksQ0FBQyxTQUFTLEVBQUU7SUFDM0IsWUFBQSxjQUFjLEVBQUU7SUFDZCxnQkFBQSxvQkFBb0IsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLG9CQUFvQjtJQUN4RCxhQUFBO0lBQ0QsWUFBQSxlQUFlLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQztJQUM1QixrQkFBRSxDQUFHLEVBQUEsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQVksVUFBQTtJQUNsQyxrQkFBRSxTQUFTO0lBQ2IsWUFBQSxlQUFlLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQztJQUM1QixrQkFBRSxDQUFHLEVBQUEsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQVksVUFBQTtJQUNsQyxrQkFBRSxTQUFTO2FBQ2Q7O0lBR0gsSUFBQSxHQUFHLENBQUMsSUFBWSxFQUFFLEdBQUEsR0FBZSxLQUFLLEVBQUE7SUFDcEMsUUFBQSxNQUFNLFFBQVEsR0FBR0MsZUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsSUFBSSxFQUFFLEVBQUUsSUFBSSxDQUFDO0lBQy9ELFFBQUEsTUFBTSxHQUFHLEdBQUdDLGVBQVksQ0FBQyxRQUFRLEVBQUUsRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLENBQUM7WUFDMUQsT0FBTyxHQUFHLEdBQUcsd0JBQXdCLEdBQUcsR0FBRyxHQUFHLEdBQUc7O0lBRXBEOztVQ25FWSxjQUFjLENBQUE7UUFDekIsV0FDbUIsQ0FBQSxHQUFxQixFQUNyQixPQUF1QixFQUFBO1lBRHZCLElBQUcsQ0FBQSxHQUFBLEdBQUgsR0FBRztZQUNILElBQU8sQ0FBQSxPQUFBLEdBQVAsT0FBTzs7UUFHbEIsY0FBYyxHQUFBO0lBQ3BCLFFBQUEsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQztJQUMvQixjQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsV0FBVztvQkFDeEIsRUFBRTtJQUNGLGdCQUFBLENBQUEsaUJBQUEsRUFBb0IsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQXNDLG9DQUFBLENBQUE7SUFDM0UsZ0JBQUEsQ0FBQSxTQUFBLEVBQVksSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQW1DLGlDQUFBO0lBQ2xFLGNBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXO0lBRTVCLFFBQUEsTUFBTSxNQUFNLEdBQUcsSUFBSUMsdUJBQWU7SUFDL0IsYUFBQSxRQUFRLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLO2lCQUMzQixjQUFjLENBQUMsV0FBVztpQkFDMUIsVUFBVSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxJQUFJLE9BQU87aUJBQzFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksSUFBSSxvQkFBb0IsQ0FBQyxJQUFJO0lBQzVELGFBQUEsS0FBSyxFQUFFO1lBRVYsT0FBT0MscUJBQWEsQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxNQUFNLEVBQUU7SUFDcEQsWUFBQSxXQUFXLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXLElBQUksRUFBRTtJQUM1QyxTQUFBLENBQUM7O1FBR0csWUFBWSxHQUFBO0lBQ2pCLFFBQUEsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLGNBQWMsRUFBRTtJQUN0QyxRQUFBLE1BQU0sU0FBUyxHQUFHLElBQUksZUFBZSxDQUFDO0lBQ3BDLFlBQUEsS0FBSyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSztnQkFDekIsSUFBSSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxJQUFJLG9CQUFvQixDQUFDLElBQUk7SUFDcEQsWUFBQSxvQkFBb0IsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLG9CQUFvQixJQUFJLElBQUk7SUFDL0QsWUFBQSxVQUFVLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVO0lBQ25DLFlBQUEsV0FBVyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsZUFBZTtJQUN6QyxZQUFBLGNBQWMsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLGtCQUFrQjtJQUMvQyxZQUFBLGFBQWEsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLGFBQWE7SUFDMUMsU0FBQSxDQUFDO0lBQ0YsUUFBQUEscUJBQWEsQ0FBQyxLQUFLLENBQ2pCLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxJQUFJLG9CQUFvQixDQUFDLElBQUksRUFDOUMsSUFBSSxDQUFDLEdBQUcsRUFDUixRQUFRLEVBQ1I7Z0JBQ0UsR0FBRyxTQUFTLENBQUMsZ0JBQWdCLEVBQUU7SUFDaEMsU0FBQSxDQUNGOztJQVFKOztJQ1BEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztJQStDRztVQUNVLGVBQWUsQ0FBQTtJQUkxQjs7Ozs7Ozs7O0lBU0c7SUFDSyxJQUFBLFdBQVcsTUFBTSxHQUFBO0lBQ3ZCLFFBQUEsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUU7O2dCQUVqQixJQUFJLENBQUMsT0FBTyxHQUFHLElBQUlDLGFBQU0sQ0FBQyxlQUFlLENBQUM7O1lBRTVDLE9BQU8sSUFBSSxDQUFDLE9BQU87O0lBR3JCOzs7Ozs7Ozs7O0lBVUc7UUFDSCxPQUFPLFVBQVUsQ0FBQyxHQUFxQixFQUFBO0lBQ3JDLFFBQUEsSUFBSSxDQUFDLEdBQUcsR0FBRyxHQUFHO0lBQ2QsUUFBQSxPQUFPLElBQUk7O0lBR2I7Ozs7Ozs7Ozs7O0lBV0c7UUFDSCxPQUFPLFlBQVksQ0FBQyxZQUFxQixFQUFBO1lBQ3ZDLElBQUksQ0FBQyxPQUFPLEdBQUcsWUFBWSxJQUFJLElBQUlBLGFBQU0sQ0FBQyxlQUFlLENBQUM7WUFDMUQsSUFBSSxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQztJQUNoQyxRQUFBLE9BQU8sSUFBSTs7SUFHYjs7Ozs7Ozs7Ozs7OztJQWFHO0lBQ0gsSUFBQSxPQUFPLFVBQVUsQ0FDZixPQUFBLEdBQTBCLEVBQUUsRUFDNUIsWUFBQSxHQUF5QixDQUFDLEtBQUssRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLFFBQVEsQ0FBQyxFQUFBO0lBRXpELFFBQUEsTUFBTSxjQUFjLEdBQ2xCLE9BQU8sS0FBSyxHQUFHLEdBQUcsR0FBRyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLFdBQVcsRUFBRSxDQUFDO0lBRXBFLFFBQUEsTUFBTSxXQUFXLEdBQWdCO0lBQy9CLFlBQUEsTUFBTSxFQUFFLENBQUMsTUFBTSxFQUFFLFFBQVEsS0FBSTs7SUFFM0IsZ0JBQUEsSUFBSSxDQUFDLE1BQU07SUFBRSxvQkFBQSxPQUFPLFFBQVEsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDO29CQUV4QyxJQUNFLGNBQWMsS0FBSyxHQUFHO0lBQ3RCLHFCQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDOzRCQUM1QixjQUFjLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDLEVBQ2hEO0lBQ0Esb0JBQUEsT0FBTyxRQUFRLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQzs7b0JBRzdCLFFBQVEsQ0FBQyxJQUFJLFNBQVMsQ0FBQyxVQUFVLE1BQU0sQ0FBQSxZQUFBLENBQWMsQ0FBQyxDQUFDO2lCQUN4RDtJQUNELFlBQUEsV0FBVyxFQUFFLElBQUk7SUFDakIsWUFBQSxPQUFPLEVBQUUsWUFBWSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUM7YUFDaEM7SUFFRCxRQUFBLElBQUksQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLFdBQVcsQ0FBQztJQUNoQyxRQUFBLE9BQU8sSUFBSTs7SUFHYjs7Ozs7Ozs7Ozs7SUFXRztRQUNILE9BQU8sU0FBUyxDQUFDLE9BQTZCLEVBQUE7SUFDNUMsUUFBQSxJQUFJOztnQkFFRixNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBQ2pDLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUM3QixZQUFBLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLHlDQUF5QyxDQUFDOztZQUMxRCxPQUFPLENBQU0sRUFBRTtJQUNmLFlBQUEsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsNENBQTRDLENBQUM7O0lBR2hFLFFBQUEsT0FBTyxJQUFJOztJQUdiOzs7Ozs7Ozs7OztJQVdHO1FBQ0gsT0FBTyxZQUFZLENBQUMsT0FBNEIsRUFBQTtZQUM5QyxNQUFNLE9BQU8sR0FBRyxJQUFJLGNBQWMsQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFO2dCQUMzQyxLQUFLLEVBQUUsT0FBTyxDQUFDLEtBQUs7Z0JBQ3BCLFdBQVcsRUFBRSxPQUFPLENBQUMsV0FBVztnQkFDaEMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxPQUFPO0lBQ3hCLFlBQUEsSUFBSSxFQUFFLE9BQU8sQ0FBQyxJQUFJLElBQUksS0FBSztJQUMzQixZQUFBLG9CQUFvQixFQUFFLE9BQU8sQ0FBQyxvQkFBb0IsSUFBSSxJQUFJO2dCQUMxRCxVQUFVLEVBQUUsT0FBTyxDQUFDLFVBQVU7Z0JBQzlCLGVBQWUsRUFBRSxPQUFPLENBQUMsV0FBVztnQkFDcEMsa0JBQWtCLEVBQUUsT0FBTyxDQUFDLGNBQWM7Z0JBQzFDLGFBQWEsRUFBRSxPQUFPLENBQUMsYUFBYTtJQUNyQyxTQUFBLENBQUM7WUFDRixPQUFPLENBQUMsWUFBWSxFQUFFO0lBQ3RCLFFBQUEsT0FBTyxJQUFJOztJQUdiOzs7Ozs7Ozs7OztJQVdHO0lBQ0gsSUFBQSxPQUFPLGNBQWMsQ0FBQyxHQUFHLEtBQXNCLEVBQUE7SUFDN0MsUUFBQSxJQUFJLEtBQUssQ0FBQyxNQUFNLEdBQUcsQ0FBQztnQkFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLGNBQWMsQ0FBQyxHQUFHLEtBQUssQ0FBQztJQUN2RCxRQUFBLE9BQU8sSUFBSTs7SUFHYjs7Ozs7Ozs7Ozs7SUFXRztJQUNILElBQUEsT0FBTyxnQkFBZ0IsQ0FBQyxHQUFHLE9BQWMsRUFBQTtJQUN2QyxRQUFBLE1BQU0sY0FBYyxHQUFHO0lBQ3JCLFlBQUEsSUFBSVAsMkJBQW1CLEVBQUU7SUFDekIsWUFBQSxJQUFJRSxpQ0FBeUIsRUFBRTtJQUMvQixZQUFBLElBQUlELCtCQUF1QixFQUFFO0lBQzdCLFlBQUEsSUFBSUosK0JBQXVCLEVBQUU7SUFDN0IsWUFBQSxJQUFJRixvQ0FBNEIsRUFBRTtJQUNsQyxZQUFBLElBQUlHLDZCQUFxQixFQUFFO2FBQzVCO1lBRUQsSUFBSSxDQUFDLEdBQUcsQ0FBQyxnQkFBZ0IsQ0FDdkIsSUFBSSxPQUFPLENBQUMsTUFBTSxHQUFHLENBQUMsR0FBRyxPQUFPLEdBQUcsY0FBYyxDQUFDLENBQ25EO0lBQ0QsUUFBQSxPQUFPLElBQUk7O0lBR2I7Ozs7Ozs7Ozs7O0lBV0c7SUFDSCxJQUFBLE9BQU8scUJBQXFCLENBQUMsR0FBRyxZQUErQixFQUFBO0lBQzdELFFBQUEsSUFBSSxZQUFZLENBQUMsTUFBTSxHQUFHLENBQUM7Z0JBQ3pCLElBQUksQ0FBQyxHQUFHLENBQUMscUJBQXFCLENBQUMsR0FBRyxZQUFZLENBQUM7SUFDakQsUUFBQSxPQUFPLElBQUk7O0lBR2I7Ozs7Ozs7Ozs7Ozs7SUFhRztRQUNILGFBQWEsS0FBSyxDQUNoQixJQUFlLEdBQUEsTUFBTSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSSxFQUMvQyxJQUEyQixHQUFBLFNBQVMsRUFDcEMsR0FBQSxHQUFlLElBQUksRUFBQTtJQUVuQixRQUFBLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxJQUFXLENBQUMsQ0FBQyxJQUFJLENBQUMsWUFBVztnQkFDakQsSUFBSSxHQUFHLEVBQUU7b0JBQ1AsTUFBTSxHQUFHLEdBQUcsTUFBTSxJQUFJLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBRTtvQkFDbkMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBaUMsOEJBQUEsRUFBQSxHQUFHLENBQUUsQ0FBQSxDQUFDOztJQUUzRCxTQUFDLENBQUM7O0lBRUw7O0lDcFZEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7OztJQW9CRztJQWNIOzs7OztJQUtHO0FBQ0ksVUFBTSxPQUFPLEdBQUc7QUFDaEIsVUFBTSxZQUFZLEdBQUc7QUFFNUJVLHVCQUFRLENBQUMsZUFBZSxDQUFDLFlBQVksRUFBRSxPQUFPLENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OyJ9
1
+ var t,e;t=this,e=function(t,e,o,s,r,a,i,n,c,p,d,l,u,h,g,m,y,f,E,_,A){"use strict";function R(t){if(t&&t.__esModule)return t;var e=Object.create(null);return t&&Object.keys(t).forEach(o=>{if("default"!==o){var s=Object.getOwnPropertyDescriptor(t,o);Object.defineProperty(e,o,s.get?s:{enumerable:!0,get:()=>t[o]})}}),e.default=t,Object.freeze(e)}var b=R(A);function w(t={}){return((t={},e=!0)=>{const[o,s]=a.getTypeIsArrayTuple(t.type,t.isArray);if((r=t={...t,type:o,isArray:s}).isArray&&"enum"in r&&void 0!==r.enum){t.type="array";const e=i.getEnumValues(t.enum);t.items={type:i.getEnumType(e),enum:e},delete t.enum}else if("enum"in t&&void 0!==t.enum){const e=i.getEnumValues(t.enum);t.enum=e,t.type=i.getEnumType(e)}var r;return Array.isArray(t.type)&&(t.type="array",t.items={type:"array",items:{type:t.type[0]}}),((t,e,o=!0)=>(s,r)=>{const a=Reflect.getMetadata(n.DECORATORS.API_MODEL_PROPERTIES_ARRAY,s)||[],i=":"+r;a.includes(i)||Reflect.defineMetadata(n.DECORATORS.API_MODEL_PROPERTIES_ARRAY,[...a,":"+r],s);const c=Reflect.getMetadata(t,s,r);if(c){const a=d.pickBy(e,d.negate(d.isUndefined)),i=o?{...c,...a}:{...a,...c};Reflect.defineMetadata(t,i,s,r)}else{const o=s?.constructor?.[l.METADATA_FACTORY_NAME]?.()[r]?.type??Reflect.getMetadata("design:type",s,r);Reflect.defineMetadata(t,{type:o,...d.pickBy(e,d.negate(d.isUndefined))},s,r)}})(n.DECORATORS.API_MODEL_PROPERTIES,t,e)})(t)}function O(t,o){const{handler:s,args:r}=e.Metadata.get(t,m.OperationKeys.REFLECT+m.OperationKeys.BLOCK)||{};return!!s&&(s(...r,o)??!1)}function T(t,e,o){const r={GET:[m.OperationKeys.READ,s.Get],POST:[m.OperationKeys.CREATE,s.Post],PUT:[m.OperationKeys.UPDATE,s.Put],PATCH:[m.OperationKeys.UPDATE,s.Patch],DELETE:[m.OperationKeys.DELETE,s.Delete]},[a,i]=r[e];return O(t,a)?g.apply(h.ApiExcludeEndpoint()):g.apply(i(o))}e.Decoration.for(o.InjectablesKeys.INJECTABLE).extend({decorator:(t,e)=>s.Injectable({scope:e.singleton?s.Scope.DEFAULT:s.Scope.REQUEST,durable:!e.singleton||void 0})}).apply(),e.Decoration.for(o.InjectablesKeys.INJECT).extend({decorator:(t,e)=>(e,o,r)=>s.Inject(t||e)(e,o,r)}).apply(),e.Decoration.for(r.ValidationKeys.REQUIRED).extend(w({required:!0})).apply(),e.Decoration.for(r.ValidationKeys.MAX).extend({decorator:t=>w({maximum:t})}).apply(),e.Decoration.for(r.ValidationKeys.MIN).extend({decorator:t=>w({minimum:t})}).apply(),e.Decoration.for(r.ValidationKeys.MAX_LENGTH).extend({decorator:t=>w({maxLength:t})}).apply(),e.Decoration.for(r.ValidationKeys.MIN_LENGTH).extend({decorator:t=>w({minLength:t})}).apply(),e.Decoration.for(r.ValidationKeys.LIST).extend({decorator:t=>w({type:[Array.isArray(t)?t[0]:t]})}).apply(),e.Decoration.for(r.ValidationKeys.PATTERN).extend({decorator:t=>w({pattern:"string"==typeof t?t:t.source})}).apply(),e.Decoration.for(u.PersistenceKeys.COLUMN).extend({decorator:t=>w({name:t})}).apply(),e.Decoration.for(e.DecorationKeys.DESCRIPTION).extend({decorator:t=>w({description:t})}).apply();const P="DecafModuleOptions",F="DecafAdapter";var C;let S=class{static{C=this}static{this._adapterInstance=null}static get log(){return this._logger||(this._logger=E.Logging.for(C)),this._logger}constructor(t,e){this.options=t,this.moduleRef=e}static async createAdapter(t){if(!this._adapterInstance){const e=this.log.for(this.createAdapter);e.info("Creating adapter instance..."),this._adapterInstance=new t.adapter(t.conf,t.alias),e.info("Adapter instance created successfully!")}return this._adapterInstance}static getAdapterInstance(){return this._adapterInstance}static forRoot(t){const e={provide:P,useValue:t},o={useFactory:async t=>C.createAdapter(t),provide:F,durable:!0,scope:s.Scope.DEFAULT,inject:[P]};return{module:C,providers:[o,e],exports:[o]}}async onApplicationShutdown(){const t=C.log.for(this.onApplicationShutdown),e=this.moduleRef.get(F);try{e&&(t.info("Shutting down"),await e.shutdown(),C._adapterInstance=null)}catch(e){t.error("Failed to shutdown application",e)}}};var I;S=C=y.__decorate([s.Global(),s.Module({}),y.__param(0,s.Inject(P)),y.__metadata("design:paramtypes",[Object,f.ModuleRef])],S),t.RepoFactory=class{for(t){if(!(t="string"==typeof t?r.Model.get(t):t))throw new m.InternalError("Failed to find repository for "+t);return u.Repository.forModel(t)}},t.RepoFactory=y.__decorate([s.Injectable()],t.RepoFactory);let D=class{static{I=this}static get log(){return this._logger||(this._logger=E.Logging.for(I)),this._logger}static toModelController(e){const o=this.log.for(this.toModelController),a=u.Repository.table(e),i=E.toKebabCase(a),n=e.name;o.debug("Creating controller for model: "+n);let c=class extends E.LoggedClass{constructor(t){super(),this.repoFactory=t,o.info(`Registering dynamic controller for model: ${n} route: /${i}`);try{this.repo=this.repoFactory.for(e.name),this.pk=this.repo.pk}catch(t){this.log.error(`Failed to initialize repository for model "${e.name}".`,t)}}async create(t){const e=this.log.for(this.create);let o;e.verbose("creating new "+n);try{o=await this.repo.create(t)}catch(t){throw e.error("Failed to create new "+n,t),t}return e.info(`created new ${n} with id ${o[this.pk]}`),o}async read(t){const e=this.log.for(this.read);let o;try{e.debug(`reading ${n} with ${this.pk} ${t}`),o=await this.repo.read(t)}catch(o){throw e.error(`Failed to read ${n} with id ${t}`,o),o}return e.info(`read ${n} with id ${o[this.pk]}`),o}async query(t){const e=this.log.for(this.read);let o;try{e.debug(`Querying ${n} using method "${t}"`),o=await this.repo[t]()}catch(o){throw e.error(`Failed to query ${n} using method "${t}"`,o),o}return e.info(`Successfully queried ${n} using method "${t}"`),o}async update(t){const e=this.log.for(this.update);let o;try{e.info(`updating ${n} with ${this.pk} ${t[this.pk]}`),o=await this.repo.create(t)}catch(t){throw e.error(t),t}return o}async delete(t){const e=this.log.for(this.delete);let o;try{e.debug(`deleting ${n} with ${this.pk} ${t}`),o=await this.repo.read(t)}catch(o){throw e.error(`Failed to delete ${n} with id ${t}`,o),o}return e.info(`deleted ${n} with id ${o[this.pk]}`),o}};return y.__decorate([T(e,"POST"),h.ApiOperation({summary:`Create a new ${n}.`}),h.ApiBody({description:"Payload for "+n,schema:{$ref:h.getSchemaPath(e)}}),h.ApiCreatedResponse({description:n+" created successfully."}),h.ApiBadRequestResponse({description:"Payload validation failed."}),h.ApiUnprocessableEntityResponse({description:"Repository rejected the provided payload."}),y.__param(0,s.Body()),y.__metadata("design:type",Function),y.__metadata("design:paramtypes",[Object]),y.__metadata("design:returntype",Promise)],c.prototype,"create",null),y.__decorate([T(e,"GET",":id"),h.ApiOperation({summary:`Retrieve a ${n} record by id.`}),h.ApiParam({name:"id",description:"Primary key"}),h.ApiOkResponse({description:n+" retrieved successfully."}),h.ApiNotFoundResponse({description:`No ${n} record matches the provided identifier.`}),y.__param(0,s.Param("id")),y.__metadata("design:type",Function),y.__metadata("design:paramtypes",[String]),y.__metadata("design:returntype",Promise)],c.prototype,"read",null),y.__decorate([T(e,"GET","query/:method"),h.ApiOperation({summary:`Retrieve ${n} records by query.`}),h.ApiParam({name:"method",description:"Query method to be called"}),h.ApiOkResponse({description:n+" retrieved successfully."}),h.ApiNotFoundResponse({description:`No ${n} records matches the query.`}),y.__param(0,s.Param("method")),y.__metadata("design:type",Function),y.__metadata("design:paramtypes",[String]),y.__metadata("design:returntype",Promise)],c.prototype,"query",null),y.__decorate([T(e,"PUT",":id"),h.ApiOperation({summary:`Replace an existing ${n} record with a new payload.`}),h.ApiBody({description:"Payload for replace a existing record of "+n,schema:{$ref:h.getSchemaPath(e)}}),h.ApiOkResponse({description:e+" record replaced successfully."}),h.ApiNotFoundResponse({description:`No ${n} record matches the provided identifier.`}),h.ApiBadRequestResponse({description:"Payload validation failed."}),y.__param(0,s.Body()),y.__metadata("design:type",Function),y.__metadata("design:paramtypes",[r.Model]),y.__metadata("design:returntype",Promise)],c.prototype,"update",null),y.__decorate([T(e,"DELETE",":id"),h.ApiOperation({summary:`Delete a ${n} record by id.`}),h.ApiParam({name:"id",description:`Primary key value of the ${n} record to delete.`}),h.ApiOkResponse({description:n+" record deleted successfully."}),h.ApiNotFoundResponse({description:`No ${n} record matches the provided identifier.`}),y.__param(0,s.Param("id")),y.__metadata("design:type",Function),y.__metadata("design:paramtypes",[String]),y.__metadata("design:returntype",Promise)],c.prototype,"delete",null),c=y.__decorate([s.Controller(i),h.ApiTags(n),h.ApiExtraModels(e),y.__metadata("design:paramtypes",[t.RepoFactory])],c),c}static forRoot(e){const o=this.log.for(this.forRoot);o.info("Generating controllers for flavour...");const s=u.Adapter.models(e).map(this.toModelController.bind(this));return o.info(`Generated ${s.length} controllers`),{module:I,controllers:s,providers:[t.RepoFactory]}}};var j;D=I=y.__decorate([s.Module({})],D),t.DecafModule=j=class{static async forRootAsync(t){const{autoControllers:e}=t,o=(await S.createAdapter(t)).flavour,s=[S.forRoot(t)];return e&&s.push(D.forRoot(o)),{module:j,imports:s}}},t.DecafModule=j=y.__decorate([s.Module({})],t.DecafModule);class x extends u.ForbiddenError{constructor(t){super(t,x.name)}}class N{constructor(t,e){const o=e?.status??s.HttpStatus.INTERNAL_SERVER_ERROR,r=e?.message??"Internal Server Error",a=(e?.error??s.HttpStatus[o]??"HTTP_EXCEPTION").toString().toUpperCase();Object.assign(this,{status:o,message:r,error:a,timestamp:(new Date).toISOString(),path:t.url,method:t.method})}}class v extends Error{constructor(t="Unauthorized"){super(t),this.name="AuthorizationError",this.status=401,this.code="UNAUTHORIZED",Object.setPrototypeOf(this,v.prototype)}}t.AuthorizationExceptionFilter=class{catch(t,e){const o=e.switchToHttp(),r=o.getRequest(),a=o.getResponse(),i=new N(r,{error:"UNAUTHORIZED",status:s.HttpStatus.UNAUTHORIZED,message:t.message});a.status(s.HttpStatus.UNAUTHORIZED).json(i)}},t.AuthorizationExceptionFilter=y.__decorate([s.Catch(v)],t.AuthorizationExceptionFilter);class M extends Error{constructor(t="Conflict"){super(t),this.name="ConflictError",this.status=409,this.code="CONFLICT",Object.setPrototypeOf(this,M.prototype)}}t.ConflictExceptionFilter=class{catch(t,e){const o=e.switchToHttp(),r=o.getResponse(),a=o.getRequest(),i=new N(a,{status:s.HttpStatus.CONFLICT,message:t.message,error:"CONFLICT"});r.status(i.status).json(i)}},t.ConflictExceptionFilter=y.__decorate([s.Catch(M)],t.ConflictExceptionFilter),t.GlobalExceptionFilter=class{catch(t,e){const o=e.switchToHttp(),r=o.getRequest(),a=o.getResponse();let i,n=s.HttpStatus.INTERNAL_SERVER_ERROR,c="Internal Server Error";if(t instanceof s.HttpException){const e=t.getResponse();n=t.getStatus(),c=(e?.message||t.message)??c,i=e?.error??t.name}else t instanceof Error&&(c=t.message,i=t.name);const p=new N(r,{status:n,message:c,error:i});a.status(p.status).json(p)}},t.GlobalExceptionFilter=y.__decorate([s.Catch()],t.GlobalExceptionFilter),t.HttpExceptionFilter=class{catch(t,e){const o=e.switchToHttp(),s=o.getResponse(),r=o.getRequest(),a=t.getStatus(),i=new N(r,{status:a,message:t.message,error:t.name});s.status(i.status).json(i)}},t.HttpExceptionFilter=y.__decorate([s.Catch(s.HttpException)],t.HttpExceptionFilter);class $ extends Error{constructor(t="Resource not found"){super(t),this.name="NotFoundError",this.status=404,this.code="NOT_FOUND",Object.setPrototypeOf(this,$.prototype)}}t.NotFoundExceptionFilter=class{catch(t,e){const o=e.switchToHttp(),r=o.getResponse(),a=o.getRequest(),i=new N(a,{status:s.HttpStatus.NOT_FOUND,message:t.message,error:"NOT_FOUND"});r.status(i.status).json(i)}},t.NotFoundExceptionFilter=y.__decorate([s.Catch($)],t.NotFoundExceptionFilter);class L extends Error{constructor(t="Validation failed"){super(t),this.name="ValidationError",this.status=422,this.code="VALIDATION_ERROR",Object.setPrototypeOf(this,L.prototype)}}t.ValidationExceptionFilter=class{catch(t,e){const o=e.switchToHttp(),r=o.getResponse(),a=o.getRequest(),i=new N(a,{status:s.HttpStatus.UNPROCESSABLE_ENTITY,message:t.message,error:"VALIDATION_ERROR"});r.status(i.status).json(i)}},t.ValidationExceptionFilter=y.__decorate([s.Catch(L)],t.ValidationExceptionFilter);const q={title:"Swagger | OpenAPI Specification (OAS)",description:"Standardized format for describing RESTful APIs",version:"0.0.1",path:"docs",faviconFilePath:"",topbarIconFilePath:"",auth:{type:"http",scheme:"bearer",bearerFormat:"JWT",name:"Authorization",description:"Enter JWT token",in:"header"},persistAuthorization:!0,topbarBgColor:"#000000"};class H{constructor(t){this.options={...t}}customCSS(){let t="";return this.options.topbarIconPath&&(t+=`.topbar-wrapper { content: url('data:image/png;base64,${this.b64(this.options.topbarIconPath)}'); width: 200px; height: auto; }\n`),t+`\n .topbar-wrapper svg { visibility: hidden; }\n .swagger-ui .topbar { background-color: ${this.options.topbarBgColor||q.topbarBgColor}; }\n `}getCustomOptions(){const t={};return this.options.faviconPath&&(t.customfavIcon=this.b64(this.options.faviconPath,!0)),{customSiteTitle:this.options.title,...t,customCss:this.customCSS(),swaggerOptions:{persistAuthorization:this.options.persistAuthorization},jsonDocumentUrl:this.options.path?this.options.path+"/spec.json":void 0,yamlDocumentUrl:this.options.path?this.options.path+"/spec.yaml":void 0}}b64(t,e=!1){const o=b.join(this.options.assetsPath||"",t),s=_.readFileSync(o,{encoding:"base64"});return e?"data:image/png;base64,"+s:s}}class U{constructor(t,e){this.app=t,this.options=e}createDocument(){const t=this.options.path?this.options.description+""+`<br><br><a href="${this.options.path}/spec.json">OpenAPI JSON Spec</a> | `+`<a href="${this.options.path}/spec.yaml">OpenAPI YAML Spec</a>`:this.options.description,e=(new h.DocumentBuilder).setTitle(this.options.title).setDescription(t).setVersion(this.options.version||"0.0.1").addBearerAuth(this.options.auth||q.auth).build();return h.SwaggerModule.createDocument(this.app,e,{extraModels:this.options.extraModels||[]})}setupSwagger(){const t=this.createDocument(),e=new H({title:this.options.title,path:this.options.path||q.path,persistAuthorization:this.options.persistAuthorization??!0,assetsPath:this.options.assetsPath,faviconPath:this.options.faviconFilePath,topbarIconPath:this.options.topbarIconFilePath,topbarBgColor:this.options.topbarBgColor});h.SwaggerModule.setup(this.options.path||q.path,this.app,t,{...e.getCustomOptions()})}}const B="##VERSION##",V="##PACKAGE_NAME##";e.Metadata.registerLibrary(V,B),t.ApiOperationFromModel=T,t.AuthorizationError=v,t.ConflictError=M,t.CorsError=x,t.DECAF_ADAPTER_ID=F,t.DECAF_MODULE_OPTIONS=P,t.HttpResponseError=N,t.NestBootstraper=class{static get logger(){return this._logger||(this._logger=new s.Logger("NestBootstrap")),this._logger}static initialize(t){return this.app=t,this}static enableLogger(t){return this._logger=t||new s.Logger("NestBootstrap"),this.app.useLogger(this._logger),this}static enableCors(t=[],e=["GET","POST","PUT","DELETE"]){const o="*"===t?"*":t.map(t=>t.trim().toLowerCase()),s={origin:(t,e)=>t?"*"===o||Array.isArray(o)&&o.includes(t.toLowerCase())?e(null,!0):void e(new x(`Origin ${t} not allowed`)):e(null,!0),credentials:!0,methods:e.join(",")};return this.app.enableCors(s),this}static useHelmet(t){try{const e=require("helmet");this.app.use(e(t)),this.logger.log("Helmet middleware enabled successfully.")}catch(t){this.logger.warn("Helmet not installed. Skipping middleware.")}return this}static setupSwagger(t){return new U(this.app,{title:t.title,description:t.description,version:t.version,path:t.path||"api",persistAuthorization:t.persistAuthorization??!0,assetsPath:t.assetsPath,faviconFilePath:t.faviconPath,topbarIconFilePath:t.topbarIconPath,topbarBgColor:t.topbarBgColor}).setupSwagger(),this}static useGlobalPipes(...t){return t.length>0&&this.app.useGlobalPipes(...t),this}static useGlobalFilters(...e){const o=[new t.HttpExceptionFilter,new t.ValidationExceptionFilter,new t.NotFoundExceptionFilter,new t.ConflictExceptionFilter,new t.AuthorizationExceptionFilter,new t.GlobalExceptionFilter];return this.app.useGlobalFilters(...e.length>0?e:o),this}static useGlobalInterceptors(...t){return t.length>0&&this.app.useGlobalInterceptors(...t),this}static async start(t=Number(process.env.PORT)||3e3,e=void 0,o=!0){this.app.listen(t,e).then(async()=>{if(o){const t=await this.app.getUrl();this.logger.log("\ud83d\ude80 Application is running at: "+t)}})}},t.NotFoundError=$,t.PACKAGE_NAME=V,t.SwaggerBuilder=U,t.VERSION=B,t.ValidationError=L,t.isOperationBlocked=O,t.repoForModel=t=>{const e=r.Model.get(t);if(!e)throw new m.InternalError("Failed to find repository for "+t);return u.Repository.forModel(e)}},"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("@decaf-ts/decoration"),require("@decaf-ts/injectable-decorators"),require("@nestjs/common"),require("@decaf-ts/decorator-validation"),require("@nestjs/swagger/dist/decorators/helpers"),require("@nestjs/swagger/dist/utils/enum.utils"),require("@nestjs/swagger/dist/constants"),require("@nestjs/common/constants"),require("@nestjs/common/utils/shared.utils"),require("lodash"),require("@nestjs/swagger/dist/plugin/plugin-constants"),require("@decaf-ts/core"),require("@nestjs/swagger"),require("@decaf-ts/reflection"),require("@decaf-ts/db-decorators"),require("tslib"),require("@nestjs/core"),require("@decaf-ts/logging"),require("fs"),require("path")):"function"==typeof define&&define.amd?define(["exports","@decaf-ts/decoration","@decaf-ts/injectable-decorators","@nestjs/common","@decaf-ts/decorator-validation","@nestjs/swagger/dist/decorators/helpers","@nestjs/swagger/dist/utils/enum.utils","@nestjs/swagger/dist/constants","@nestjs/common/constants","@nestjs/common/utils/shared.utils","lodash","@nestjs/swagger/dist/plugin/plugin-constants","@decaf-ts/core","@nestjs/swagger","@decaf-ts/reflection","@decaf-ts/db-decorators","tslib","@nestjs/core","@decaf-ts/logging","fs","path"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self)["for-nest"]={},t.decafTsDecoration,t.decafTsInjectableDecorators,t.nestjsCommon,t.decafTsDecoratorValidation,t.helpers,t.enum_utils,t.constants,0,0,t.lodash,t.pluginConstants,t.decafTsCore,t.nestjsSwagger,t.decafTsReflection,t.decafTsDbDecorators,t.tslib,t.nestjsCore,t.decafTsLogging,t.fs,t.path);
2
+ //# sourceMappingURL=for-nest.cjs.map