1 | ;
|
2 | /**
|
3 | * @license
|
4 | * Copyright Google LLC All Rights Reserved.
|
5 | *
|
6 | * Use of this source code is governed by an MIT-style license that can be
|
7 | * found in the LICENSE file at https://angular.io/license
|
8 | */
|
9 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
10 | if (k2 === undefined) k2 = k;
|
11 | var desc = Object.getOwnPropertyDescriptor(m, k);
|
12 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
13 | desc = { enumerable: true, get: function() { return m[k]; } };
|
14 | }
|
15 | Object.defineProperty(o, k2, desc);
|
16 | }) : (function(o, m, k, k2) {
|
17 | if (k2 === undefined) k2 = k;
|
18 | o[k2] = m[k];
|
19 | }));
|
20 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
21 | Object.defineProperty(o, "default", { enumerable: true, value: v });
|
22 | }) : function(o, v) {
|
23 | o["default"] = v;
|
24 | });
|
25 | var __importStar = (this && this.__importStar) || function (mod) {
|
26 | if (mod && mod.__esModule) return mod;
|
27 | var result = {};
|
28 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
29 | __setModuleDefault(result, mod);
|
30 | return result;
|
31 | };
|
32 | var __importDefault = (this && this.__importDefault) || function (mod) {
|
33 | return (mod && mod.__esModule) ? mod : { "default": mod };
|
34 | };
|
35 | Object.defineProperty(exports, "__esModule", { value: true });
|
36 | exports.CoreSchemaRegistry = exports.SchemaValidationException = void 0;
|
37 | const ajv_1 = __importDefault(require("ajv"));
|
38 | const ajv_formats_1 = __importDefault(require("ajv-formats"));
|
39 | const http = __importStar(require("http"));
|
40 | const https = __importStar(require("https"));
|
41 | const rxjs_1 = require("rxjs");
|
42 | const Url = __importStar(require("url"));
|
43 | const exception_1 = require("../../exception");
|
44 | const utils_1 = require("../../utils");
|
45 | const utils_2 = require("../utils");
|
46 | const utility_1 = require("./utility");
|
47 | const visitor_1 = require("./visitor");
|
48 | class SchemaValidationException extends exception_1.BaseException {
|
49 | constructor(errors, baseMessage = 'Schema validation failed with the following errors:') {
|
50 | if (!errors || errors.length === 0) {
|
51 | super('Schema validation failed.');
|
52 | this.errors = [];
|
53 | return;
|
54 | }
|
55 | const messages = SchemaValidationException.createMessages(errors);
|
56 | super(`${baseMessage}\n ${messages.join('\n ')}`);
|
57 | this.errors = errors;
|
58 | }
|
59 | static createMessages(errors) {
|
60 | if (!errors || errors.length === 0) {
|
61 | return [];
|
62 | }
|
63 | const messages = errors.map((err) => {
|
64 | let message = `Data path ${JSON.stringify(err.instancePath)} ${err.message}`;
|
65 | if (err.params) {
|
66 | switch (err.keyword) {
|
67 | case 'additionalProperties':
|
68 | message += `(${err.params.additionalProperty})`;
|
69 | break;
|
70 | case 'enum':
|
71 | message += `. Allowed values are: ${err.params.allowedValues
|
72 | ?.map((v) => `"${v}"`)
|
73 | .join(', ')}`;
|
74 | break;
|
75 | }
|
76 | }
|
77 | return message + '.';
|
78 | });
|
79 | return messages;
|
80 | }
|
81 | }
|
82 | exports.SchemaValidationException = SchemaValidationException;
|
83 | class CoreSchemaRegistry {
|
84 | constructor(formats = []) {
|
85 | this._uriCache = new Map();
|
86 | this._uriHandlers = new Set();
|
87 | this._pre = new utils_1.PartiallyOrderedSet();
|
88 | this._post = new utils_1.PartiallyOrderedSet();
|
89 | this._smartDefaultKeyword = false;
|
90 | this._sourceMap = new Map();
|
91 | this._ajv = new ajv_1.default({
|
92 | strict: false,
|
93 | loadSchema: (uri) => this._fetch(uri),
|
94 | passContext: true,
|
95 | });
|
96 | (0, ajv_formats_1.default)(this._ajv);
|
97 | for (const format of formats) {
|
98 | this.addFormat(format);
|
99 | }
|
100 | }
|
101 | async _fetch(uri) {
|
102 | const maybeSchema = this._uriCache.get(uri);
|
103 | if (maybeSchema) {
|
104 | return maybeSchema;
|
105 | }
|
106 | // Try all handlers, one after the other.
|
107 | for (const handler of this._uriHandlers) {
|
108 | let handlerResult = handler(uri);
|
109 | if (handlerResult === null || handlerResult === undefined) {
|
110 | continue;
|
111 | }
|
112 | if ((0, rxjs_1.isObservable)(handlerResult)) {
|
113 | handlerResult = (0, rxjs_1.lastValueFrom)(handlerResult);
|
114 | }
|
115 | const value = await handlerResult;
|
116 | this._uriCache.set(uri, value);
|
117 | return value;
|
118 | }
|
119 | // If none are found, handle using http client.
|
120 | return new Promise((resolve, reject) => {
|
121 | const url = new Url.URL(uri);
|
122 | const client = url.protocol === 'https:' ? https : http;
|
123 | client.get(url, (res) => {
|
124 | if (!res.statusCode || res.statusCode >= 300) {
|
125 | // Consume the rest of the data to free memory.
|
126 | res.resume();
|
127 | reject(new Error(`Request failed. Status Code: ${res.statusCode}`));
|
128 | }
|
129 | else {
|
130 | res.setEncoding('utf8');
|
131 | let data = '';
|
132 | res.on('data', (chunk) => {
|
133 | data += chunk;
|
134 | });
|
135 | res.on('end', () => {
|
136 | try {
|
137 | const json = JSON.parse(data);
|
138 | this._uriCache.set(uri, json);
|
139 | resolve(json);
|
140 | }
|
141 | catch (err) {
|
142 | reject(err);
|
143 | }
|
144 | });
|
145 | }
|
146 | });
|
147 | });
|
148 | }
|
149 | /**
|
150 | * Add a transformation step before the validation of any Json.
|
151 | * @param {JsonVisitor} visitor The visitor to transform every value.
|
152 | * @param {JsonVisitor[]} deps A list of other visitors to run before.
|
153 | */
|
154 | addPreTransform(visitor, deps) {
|
155 | this._pre.add(visitor, deps);
|
156 | }
|
157 | /**
|
158 | * Add a transformation step after the validation of any Json. The JSON will not be validated
|
159 | * after the POST, so if transformations are not compatible with the Schema it will not result
|
160 | * in an error.
|
161 | * @param {JsonVisitor} visitor The visitor to transform every value.
|
162 | * @param {JsonVisitor[]} deps A list of other visitors to run before.
|
163 | */
|
164 | addPostTransform(visitor, deps) {
|
165 | this._post.add(visitor, deps);
|
166 | }
|
167 | _resolver(ref, validate) {
|
168 | if (!validate || !ref) {
|
169 | return {};
|
170 | }
|
171 | const schema = validate.schemaEnv.root.schema;
|
172 | const id = typeof schema === 'object' ? schema.$id : null;
|
173 | let fullReference = ref;
|
174 | if (typeof id === 'string') {
|
175 | fullReference = Url.resolve(id, ref);
|
176 | if (ref.startsWith('#')) {
|
177 | fullReference = id + fullReference;
|
178 | }
|
179 | }
|
180 | const resolvedSchema = this._ajv.getSchema(fullReference);
|
181 | return {
|
182 | context: resolvedSchema?.schemaEnv.validate,
|
183 | schema: resolvedSchema?.schema,
|
184 | };
|
185 | }
|
186 | /**
|
187 | * Flatten the Schema, resolving and replacing all the refs. Makes it into a synchronous schema
|
188 | * that is also easier to traverse. Does not cache the result.
|
189 | *
|
190 | * Producing a flatten schema document does not in all cases produce a schema with identical behavior to the original.
|
191 | * See: https://json-schema.org/draft/2019-09/json-schema-core.html#rfc.appendix.B.2
|
192 | *
|
193 | * @param schema The schema or URI to flatten.
|
194 | * @returns An Observable of the flattened schema object.
|
195 | * @private since 11.2 without replacement.
|
196 | */
|
197 | async ɵflatten(schema) {
|
198 | this._ajv.removeSchema(schema);
|
199 | this._currentCompilationSchemaInfo = undefined;
|
200 | const validate = await this._ajv.compileAsync(schema);
|
201 | // eslint-disable-next-line @typescript-eslint/no-this-alias
|
202 | const self = this;
|
203 | function visitor(current, pointer, parentSchema, index) {
|
204 | if (current &&
|
205 | parentSchema &&
|
206 | index &&
|
207 | (0, utils_2.isJsonObject)(current) &&
|
208 | Object.prototype.hasOwnProperty.call(current, '$ref') &&
|
209 | typeof current['$ref'] == 'string') {
|
210 | const resolved = self._resolver(current['$ref'], validate);
|
211 | if (resolved.schema) {
|
212 | parentSchema[index] = resolved.schema;
|
213 | }
|
214 | }
|
215 | }
|
216 | const schemaCopy = (0, utils_1.deepCopy)(validate.schema);
|
217 | (0, visitor_1.visitJsonSchema)(schemaCopy, visitor);
|
218 | return schemaCopy;
|
219 | }
|
220 | /**
|
221 | * Compile and return a validation function for the Schema.
|
222 | *
|
223 | * @param schema The schema to validate. If a string, will fetch the schema before compiling it
|
224 | * (using schema as a URI).
|
225 | */
|
226 | async compile(schema) {
|
227 | const validate = await this._compile(schema);
|
228 | return (value, options) => validate(value, options);
|
229 | }
|
230 | async _compile(schema) {
|
231 | if (typeof schema === 'boolean') {
|
232 | return async (data) => ({ success: schema, data });
|
233 | }
|
234 | const schemaInfo = {
|
235 | smartDefaultRecord: new Map(),
|
236 | promptDefinitions: [],
|
237 | };
|
238 | this._ajv.removeSchema(schema);
|
239 | let validator;
|
240 | try {
|
241 | this._currentCompilationSchemaInfo = schemaInfo;
|
242 | validator = this._ajv.compile(schema);
|
243 | }
|
244 | catch (e) {
|
245 | // This should eventually be refactored so that we we handle race condition where the same schema is validated at the same time.
|
246 | if (!(e instanceof ajv_1.default.MissingRefError)) {
|
247 | throw e;
|
248 | }
|
249 | validator = await this._ajv.compileAsync(schema);
|
250 | }
|
251 | finally {
|
252 | this._currentCompilationSchemaInfo = undefined;
|
253 | }
|
254 | return async (data, options) => {
|
255 | const validationOptions = {
|
256 | withPrompts: true,
|
257 | applyPostTransforms: true,
|
258 | applyPreTransforms: true,
|
259 | ...options,
|
260 | };
|
261 | const validationContext = {
|
262 | promptFieldsWithValue: new Set(),
|
263 | };
|
264 | // Apply pre-validation transforms
|
265 | if (validationOptions.applyPreTransforms) {
|
266 | for (const visitor of this._pre.values()) {
|
267 | data = await (0, rxjs_1.lastValueFrom)((0, visitor_1.visitJson)(data, visitor, schema, this._resolver.bind(this), validator));
|
268 | }
|
269 | }
|
270 | // Apply smart defaults
|
271 | await this._applySmartDefaults(data, schemaInfo.smartDefaultRecord);
|
272 | // Apply prompts
|
273 | if (validationOptions.withPrompts) {
|
274 | const visitor = (value, pointer) => {
|
275 | if (value !== undefined) {
|
276 | validationContext.promptFieldsWithValue.add(pointer);
|
277 | }
|
278 | return value;
|
279 | };
|
280 | if (typeof schema === 'object') {
|
281 | await (0, rxjs_1.lastValueFrom)((0, visitor_1.visitJson)(data, visitor, schema, this._resolver.bind(this), validator));
|
282 | }
|
283 | const definitions = schemaInfo.promptDefinitions.filter((def) => !validationContext.promptFieldsWithValue.has(def.id));
|
284 | if (definitions.length > 0) {
|
285 | await this._applyPrompts(data, definitions);
|
286 | }
|
287 | }
|
288 | // Validate using ajv
|
289 | try {
|
290 | const success = await validator.call(validationContext, data);
|
291 | if (!success) {
|
292 | return { data, success, errors: validator.errors ?? [] };
|
293 | }
|
294 | }
|
295 | catch (error) {
|
296 | if (error instanceof ajv_1.default.ValidationError) {
|
297 | return { data, success: false, errors: error.errors };
|
298 | }
|
299 | throw error;
|
300 | }
|
301 | // Apply post-validation transforms
|
302 | if (validationOptions.applyPostTransforms) {
|
303 | for (const visitor of this._post.values()) {
|
304 | data = await (0, rxjs_1.lastValueFrom)((0, visitor_1.visitJson)(data, visitor, schema, this._resolver.bind(this), validator));
|
305 | }
|
306 | }
|
307 | return { data, success: true };
|
308 | };
|
309 | }
|
310 | addFormat(format) {
|
311 | this._ajv.addFormat(format.name, format.formatter);
|
312 | }
|
313 | addSmartDefaultProvider(source, provider) {
|
314 | if (this._sourceMap.has(source)) {
|
315 | throw new Error(source);
|
316 | }
|
317 | this._sourceMap.set(source, provider);
|
318 | if (!this._smartDefaultKeyword) {
|
319 | this._smartDefaultKeyword = true;
|
320 | this._ajv.addKeyword({
|
321 | keyword: '$default',
|
322 | errors: false,
|
323 | valid: true,
|
324 | compile: (schema, _parentSchema, it) => {
|
325 | const compilationSchemInfo = this._currentCompilationSchemaInfo;
|
326 | if (compilationSchemInfo === undefined) {
|
327 | return () => true;
|
328 | }
|
329 | // We cheat, heavily.
|
330 | const pathArray = this.normalizeDataPathArr(it);
|
331 | compilationSchemInfo.smartDefaultRecord.set(JSON.stringify(pathArray), schema);
|
332 | return () => true;
|
333 | },
|
334 | metaSchema: {
|
335 | type: 'object',
|
336 | properties: {
|
337 | '$source': { type: 'string' },
|
338 | },
|
339 | additionalProperties: true,
|
340 | required: ['$source'],
|
341 | },
|
342 | });
|
343 | }
|
344 | }
|
345 | registerUriHandler(handler) {
|
346 | this._uriHandlers.add(handler);
|
347 | }
|
348 | usePromptProvider(provider) {
|
349 | const isSetup = !!this._promptProvider;
|
350 | this._promptProvider = provider;
|
351 | if (isSetup) {
|
352 | return;
|
353 | }
|
354 | this._ajv.addKeyword({
|
355 | keyword: 'x-prompt',
|
356 | errors: false,
|
357 | valid: true,
|
358 | compile: (schema, parentSchema, it) => {
|
359 | const compilationSchemInfo = this._currentCompilationSchemaInfo;
|
360 | if (!compilationSchemInfo) {
|
361 | return () => true;
|
362 | }
|
363 | const path = '/' + this.normalizeDataPathArr(it).join('/');
|
364 | let type;
|
365 | let items;
|
366 | let message;
|
367 | if (typeof schema == 'string') {
|
368 | message = schema;
|
369 | }
|
370 | else {
|
371 | message = schema.message;
|
372 | type = schema.type;
|
373 | items = schema.items;
|
374 | }
|
375 | const propertyTypes = (0, utility_1.getTypesOfSchema)(parentSchema);
|
376 | if (!type) {
|
377 | if (propertyTypes.size === 1 && propertyTypes.has('boolean')) {
|
378 | type = 'confirmation';
|
379 | }
|
380 | else if (Array.isArray(parentSchema.enum)) {
|
381 | type = 'list';
|
382 | }
|
383 | else if (propertyTypes.size === 1 &&
|
384 | propertyTypes.has('array') &&
|
385 | parentSchema.items &&
|
386 | Array.isArray(parentSchema.items.enum)) {
|
387 | type = 'list';
|
388 | }
|
389 | else {
|
390 | type = 'input';
|
391 | }
|
392 | }
|
393 | let multiselect;
|
394 | if (type === 'list') {
|
395 | multiselect =
|
396 | schema.multiselect === undefined
|
397 | ? propertyTypes.size === 1 && propertyTypes.has('array')
|
398 | : schema.multiselect;
|
399 | const enumValues = multiselect
|
400 | ? parentSchema.items &&
|
401 | parentSchema.items.enum
|
402 | : parentSchema.enum;
|
403 | if (!items && Array.isArray(enumValues)) {
|
404 | items = [];
|
405 | for (const value of enumValues) {
|
406 | if (typeof value == 'string') {
|
407 | items.push(value);
|
408 | }
|
409 | else if (typeof value == 'object') {
|
410 | // Invalid
|
411 | }
|
412 | else {
|
413 | items.push({ label: value.toString(), value });
|
414 | }
|
415 | }
|
416 | }
|
417 | }
|
418 | const definition = {
|
419 | id: path,
|
420 | type,
|
421 | message,
|
422 | raw: schema,
|
423 | items,
|
424 | multiselect,
|
425 | propertyTypes,
|
426 | default: typeof parentSchema.default == 'object' &&
|
427 | parentSchema.default !== null &&
|
428 | !Array.isArray(parentSchema.default)
|
429 | ? undefined
|
430 | : parentSchema.default,
|
431 | async validator(data) {
|
432 | try {
|
433 | const result = await it.self.validate(parentSchema, data);
|
434 | // If the schema is sync then false will be returned on validation failure
|
435 | if (result) {
|
436 | return result;
|
437 | }
|
438 | else if (it.self.errors?.length) {
|
439 | // Validation errors will be present on the Ajv instance when sync
|
440 | return it.self.errors[0].message;
|
441 | }
|
442 | }
|
443 | catch (e) {
|
444 | const validationError = e;
|
445 | // If the schema is async then an error will be thrown on validation failure
|
446 | if (Array.isArray(validationError.errors) && validationError.errors.length) {
|
447 | return validationError.errors[0].message;
|
448 | }
|
449 | }
|
450 | return false;
|
451 | },
|
452 | };
|
453 | compilationSchemInfo.promptDefinitions.push(definition);
|
454 | return function () {
|
455 | // If 'this' is undefined in the call, then it defaults to the global
|
456 | // 'this'.
|
457 | if (this && this.promptFieldsWithValue) {
|
458 | this.promptFieldsWithValue.add(path);
|
459 | }
|
460 | return true;
|
461 | };
|
462 | },
|
463 | metaSchema: {
|
464 | oneOf: [
|
465 | { type: 'string' },
|
466 | {
|
467 | type: 'object',
|
468 | properties: {
|
469 | 'type': { type: 'string' },
|
470 | 'message': { type: 'string' },
|
471 | },
|
472 | additionalProperties: true,
|
473 | required: ['message'],
|
474 | },
|
475 | ],
|
476 | },
|
477 | });
|
478 | }
|
479 | async _applyPrompts(data, prompts) {
|
480 | const provider = this._promptProvider;
|
481 | if (!provider) {
|
482 | return;
|
483 | }
|
484 | const answers = await (0, rxjs_1.lastValueFrom)((0, rxjs_1.from)(provider(prompts)));
|
485 | for (const path in answers) {
|
486 | const pathFragments = path.split('/').slice(1);
|
487 | CoreSchemaRegistry._set(data, pathFragments, answers[path], null, undefined, true);
|
488 | }
|
489 | }
|
490 | static _set(
|
491 | // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
492 | data, fragments, value,
|
493 | // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
494 | parent = null, parentProperty, force) {
|
495 | for (let index = 0; index < fragments.length; index++) {
|
496 | const fragment = fragments[index];
|
497 | if (/^i\d+$/.test(fragment)) {
|
498 | if (!Array.isArray(data)) {
|
499 | return;
|
500 | }
|
501 | for (let dataIndex = 0; dataIndex < data.length; dataIndex++) {
|
502 | CoreSchemaRegistry._set(data[dataIndex], fragments.slice(index + 1), value, data, `${dataIndex}`);
|
503 | }
|
504 | return;
|
505 | }
|
506 | if (!data && parent !== null && parentProperty) {
|
507 | data = parent[parentProperty] = {};
|
508 | }
|
509 | parent = data;
|
510 | parentProperty = fragment;
|
511 | data = data[fragment];
|
512 | }
|
513 | if (parent && parentProperty && (force || parent[parentProperty] === undefined)) {
|
514 | parent[parentProperty] = value;
|
515 | }
|
516 | }
|
517 | async _applySmartDefaults(data, smartDefaults) {
|
518 | for (const [pointer, schema] of smartDefaults.entries()) {
|
519 | const fragments = JSON.parse(pointer);
|
520 | const source = this._sourceMap.get(schema.$source);
|
521 | if (!source) {
|
522 | continue;
|
523 | }
|
524 | let value = source(schema);
|
525 | if ((0, rxjs_1.isObservable)(value)) {
|
526 | value = (await (0, rxjs_1.lastValueFrom)(value));
|
527 | }
|
528 | CoreSchemaRegistry._set(data, fragments, value);
|
529 | }
|
530 | }
|
531 | useXDeprecatedProvider(onUsage) {
|
532 | this._ajv.addKeyword({
|
533 | keyword: 'x-deprecated',
|
534 | validate: (schema, _data, _parentSchema, dataCxt) => {
|
535 | if (schema) {
|
536 | onUsage(`Option "${dataCxt?.parentDataProperty}" is deprecated${typeof schema == 'string' ? ': ' + schema : '.'}`);
|
537 | }
|
538 | return true;
|
539 | },
|
540 | errors: false,
|
541 | });
|
542 | }
|
543 | normalizeDataPathArr(it) {
|
544 | return it.dataPathArr
|
545 | .slice(1, it.dataLevel + 1)
|
546 | .map((p) => (typeof p === 'number' ? p : p.str.replace(/"/g, '')));
|
547 | }
|
548 | }
|
549 | exports.CoreSchemaRegistry = CoreSchemaRegistry;
|
550 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVnaXN0cnkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9hbmd1bGFyX2RldmtpdC9jb3JlL3NyYy9qc29uL3NjaGVtYS9yZWdpc3RyeS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7Ozs7OztHQU1HOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUVILDhDQUEwRDtBQUMxRCw4REFBd0M7QUFDeEMsMkNBQTZCO0FBQzdCLDZDQUErQjtBQUMvQiwrQkFBcUU7QUFDckUseUNBQTJCO0FBQzNCLCtDQUFnRDtBQUNoRCx1Q0FBNEQ7QUFDNUQsb0NBQTBFO0FBZTFFLHVDQUE2QztBQUM3Qyx1Q0FBdUQ7QUFNdkQsTUFBYSx5QkFBMEIsU0FBUSx5QkFBYTtJQUcxRCxZQUNFLE1BQStCLEVBQy9CLFdBQVcsR0FBRyxxREFBcUQ7UUFFbkUsSUFBSSxDQUFDLE1BQU0sSUFBSSxNQUFNLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTtZQUNsQyxLQUFLLENBQUMsMkJBQTJCLENBQUMsQ0FBQztZQUNuQyxJQUFJLENBQUMsTUFBTSxHQUFHLEVBQUUsQ0FBQztZQUVqQixPQUFPO1NBQ1I7UUFFRCxNQUFNLFFBQVEsR0FBRyx5QkFBeUIsQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDbEUsS0FBSyxDQUFDLEdBQUcsV0FBVyxPQUFPLFFBQVEsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ3BELElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDO0lBQ3ZCLENBQUM7SUFFTSxNQUFNLENBQUMsY0FBYyxDQUFDLE1BQStCO1FBQzFELElBQUksQ0FBQyxNQUFNLElBQUksTUFBTSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUU7WUFDbEMsT0FBTyxFQUFFLENBQUM7U0FDWDtRQUVELE1BQU0sUUFBUSxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRTtZQUNsQyxJQUFJLE9BQU8sR0FBRyxhQUFhLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxJQUFJLEdBQUcsQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUM3RSxJQUFJLEdBQUcsQ0FBQyxNQUFNLEVBQUU7Z0JBQ2QsUUFBUSxHQUFHLENBQUMsT0FBTyxFQUFFO29CQUNuQixLQUFLLHNCQUFzQjt3QkFDekIsT0FBTyxJQUFJLElBQUksR0FBRyxDQUFDLE1BQU0sQ0FBQyxrQkFBa0IsR0FBRyxDQUFDO3dCQUNoRCxNQUFNO29CQUVSLEtBQUssTUFBTTt3QkFDVCxPQUFPLElBQUkseUJBQTBCLEdBQUcsQ0FBQyxNQUFNLENBQUMsYUFBc0M7NEJBQ3BGLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDOzZCQUNyQixJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQzt3QkFDaEIsTUFBTTtpQkFDVDthQUNGO1lBRUQsT0FBTyxPQUFPLEdBQUcsR0FBRyxDQUFDO1FBQ3ZCLENBQUMsQ0FBQyxDQUFDO1FBRUgsT0FBTyxRQUFRLENBQUM7SUFDbEIsQ0FBQztDQUNGO0FBN0NELDhEQTZDQztBQU9ELE1BQWEsa0JBQWtCO0lBYTdCLFlBQVksVUFBMEIsRUFBRTtRQVhoQyxjQUFTLEdBQUcsSUFBSSxHQUFHLEVBQXNCLENBQUM7UUFDMUMsaUJBQVksR0FBRyxJQUFJLEdBQUcsRUFBYyxDQUFDO1FBQ3JDLFNBQUksR0FBRyxJQUFJLDJCQUFtQixFQUFlLENBQUM7UUFDOUMsVUFBSyxHQUFHLElBQUksMkJBQW1CLEVBQWUsQ0FBQztRQUkvQyx5QkFBb0IsR0FBRyxLQUFLLENBQUM7UUFFN0IsZUFBVSxHQUFHLElBQUksR0FBRyxFQUFvQyxDQUFDO1FBRy9ELElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxhQUFHLENBQUM7WUFDbEIsTUFBTSxFQUFFLEtBQUs7WUFDYixVQUFVLEVBQUUsQ0FBQyxHQUFXLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDO1lBQzdDLFdBQVcsRUFBRSxJQUFJO1NBQ2xCLENBQUMsQ0FBQztRQUVILElBQUEscUJBQWEsRUFBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFekIsS0FBSyxNQUFNLE1BQU0sSUFBSSxPQUFPLEVBQUU7WUFDNUIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQztTQUN4QjtJQUNILENBQUM7SUFFTyxLQUFLLENBQUMsTUFBTSxDQUFDLEdBQVc7UUFDOUIsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7UUFFNUMsSUFBSSxXQUFXLEVBQUU7WUFDZixPQUFPLFdBQVcsQ0FBQztTQUNwQjtRQUVELHlDQUF5QztRQUN6QyxLQUFLLE1BQU0sT0FBTyxJQUFJLElBQUksQ0FBQyxZQUFZLEVBQUU7WUFDdkMsSUFBSSxhQUFhLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ2pDLElBQUksYUFBYSxLQUFLLElBQUksSUFBSSxhQUFhLEtBQUssU0FBUyxFQUFFO2dCQUN6RCxTQUFTO2FBQ1Y7WUFFRCxJQUFJLElBQUEsbUJBQVksRUFBQyxhQUFhLENBQUMsRUFBRTtnQkFDL0IsYUFBYSxHQUFHLElBQUEsb0JBQWEsRUFBQyxhQUFhLENBQUMsQ0FBQzthQUM5QztZQUVELE1BQU0sS0FBSyxHQUFHLE1BQU0sYUFBYSxDQUFDO1lBQ2xDLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUUvQixPQUFPLEtBQUssQ0FBQztTQUNkO1FBRUQsK0NBQStDO1FBQy9DLE9BQU8sSUFBSSxPQUFPLENBQWEsQ0FBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLEVBQUU7WUFDakQsTUFBTSxHQUFHLEdBQUcsSUFBSSxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQzdCLE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxRQUFRLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztZQUN4RCxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDLEdBQUcsRUFBRSxFQUFFO2dCQUN0QixJQUFJLENBQUMsR0FBRyxDQUFDLFVBQVUsSUFBSSxHQUFHLENBQUMsVUFBVSxJQUFJLEdBQUcsRUFBRTtvQkFDNUMsK0NBQStDO29CQUMvQyxHQUFHLENBQUMsTUFBTSxFQUFFLENBQUM7b0JBQ2IsTUFBTSxDQUFDLElBQUksS0FBSyxDQUFDLGdDQUFnQyxHQUFHLENBQUMsVUFBVSxFQUFFLENBQUMsQ0FBQyxDQUFDO2lCQUNyRTtxQkFBTTtvQkFDTCxHQUFHLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDO29CQUN4QixJQUFJLElBQUksR0FBRyxFQUFFLENBQUM7b0JBQ2QsR0FBRyxDQUFDLEVBQUUsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxLQUFLLEVBQUUsRUFBRTt3QkFDdkIsSUFBSSxJQUFJLEtBQUssQ0FBQztvQkFDaEIsQ0FBQyxDQUFDLENBQUM7b0JBQ0gsR0FBRyxDQUFDLEVBQUUsQ0FBQyxLQUFLLEVBQUUsR0FBRyxFQUFFO3dCQUNqQixJQUFJOzRCQUNGLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7NEJBQzlCLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQzs0QkFDOUIsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO3lCQUNmO3dCQUFDLE9BQU8sR0FBRyxFQUFFOzRCQUNaLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQzt5QkFDYjtvQkFDSCxDQUFDLENBQUMsQ0FBQztpQkFDSjtZQUNILENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILGVBQWUsQ0FBQyxPQUFvQixFQUFFLElBQW9CO1FBQ3hELElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsQ0FBQztJQUMvQixDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0gsZ0JBQWdCLENBQUMsT0FBb0IsRUFBRSxJQUFvQjtRQUN6RCxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDaEMsQ0FBQztJQUVTLFNBQVMsQ0FDakIsR0FBVyxFQUNYLFFBQTJCO1FBRTNCLElBQUksQ0FBQyxRQUFRLElBQUksQ0FBQyxHQUFHLEVBQUU7WUFDckIsT0FBTyxFQUFFLENBQUM7U0FDWDtRQUVELE1BQU0sTUFBTSxHQUFHLFFBQVEsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQztRQUM5QyxNQUFNLEVBQUUsR0FBRyxPQUFPLE1BQU0sS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztRQUUxRCxJQUFJLGFBQWEsR0FBRyxHQUFHLENBQUM7UUFDeEIsSUFBSSxPQUFPLEVBQUUsS0FBSyxRQUFRLEVBQUU7WUFDMUIsYUFBYSxHQUFHLEdBQUcsQ0FBQyxPQUFPLENBQUMsRUFBRSxFQUFFLEdBQUcsQ0FBQyxDQUFDO1lBRXJDLElBQUksR0FBRyxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsRUFBRTtnQkFDdkIsYUFBYSxHQUFHLEVBQUUsR0FBRyxhQUFhLENBQUM7YUFDcEM7U0FDRjtRQUVELE1BQU0sY0FBYyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBRTFELE9BQU87WUFDTCxPQUFPLEVBQUUsY0FBYyxFQUFFLFNBQVMsQ0FBQyxRQUFRO1lBQzNDLE1BQU0sRUFBRSxjQUFjLEVBQUUsTUFBb0I7U0FDN0MsQ0FBQztJQUNKLENBQUM7SUFFRDs7Ozs7Ozs7OztPQVVHO0lBQ0gsS0FBSyxDQUFDLFFBQVEsQ0FBQyxNQUFrQjtRQUMvQixJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUMvQixJQUFJLENBQUMsNkJBQTZCLEdBQUcsU0FBUyxDQUFDO1FBQy9DLE1BQU0sUUFBUSxHQUFHLE1BQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLENBQUM7UUFFdEQsNERBQTREO1FBQzVELE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQztRQUVsQixTQUFTLE9BQU8sQ0FDZCxPQUErQixFQUMvQixPQUFvQixFQUNwQixZQUFxQyxFQUNyQyxLQUFjO1lBRWQsSUFDRSxPQUFPO2dCQUNQLFlBQVk7Z0JBQ1osS0FBSztnQkFDTCxJQUFBLG9CQUFZLEVBQUMsT0FBTyxDQUFDO2dCQUNyQixNQUFNLENBQUMsU0FBUyxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQztnQkFDckQsT0FBTyxPQUFPLENBQUMsTUFBTSxDQUFDLElBQUksUUFBUSxFQUNsQztnQkFDQSxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsRUFBRSxRQUFRLENBQUMsQ0FBQztnQkFFM0QsSUFBSSxRQUFRLENBQUMsTUFBTSxFQUFFO29CQUNsQixZQUEyQixDQUFDLEtBQUssQ0FBQyxHQUFHLFFBQVEsQ0FBQyxNQUFNLENBQUM7aUJBQ3ZEO2FBQ0Y7UUFDSCxDQUFDO1FBRUQsTUFBTSxVQUFVLEdBQUcsSUFBQSxnQkFBUSxFQUFDLFFBQVEsQ0FBQyxNQUFvQixDQUFDLENBQUM7UUFDM0QsSUFBQSx5QkFBZSxFQUFDLFVBQVUsRUFBRSxPQUFPLENBQUMsQ0FBQztRQUVyQyxPQUFPLFVBQVUsQ0FBQztJQUNwQixDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSCxLQUFLLENBQUMsT0FBTyxDQUFDLE1BQWtCO1FBQzlCLE1BQU0sUUFBUSxHQUFHLE1BQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUU3QyxPQUFPLENBQUMsS0FBSyxFQUFFLE9BQU8sRUFBRSxFQUFFLENBQUMsUUFBUSxDQUFDLEtBQUssRUFBRSxPQUFPLENBQUMsQ0FBQztJQUN0RCxDQUFDO0lBRU8sS0FBSyxDQUFDLFFBQVEsQ0FDcEIsTUFBa0I7UUFJbEIsSUFBSSxPQUFPLE1BQU0sS0FBSyxTQUFTLEVBQUU7WUFDL0IsT0FBTyxLQUFLLEVBQUUsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1NBQ3BEO1FBRUQsTUFBTSxVQUFVLEdBQWU7WUFDN0Isa0JBQWtCLEVBQUUsSUFBSSxHQUFHLEVBQXNCO1lBQ2pELGlCQUFpQixFQUFFLEVBQUU7U0FDdEIsQ0FBQztRQUVGLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQy9CLElBQUksU0FBMkIsQ0FBQztRQUVoQyxJQUFJO1lBQ0YsSUFBSSxDQUFDLDZCQUE2QixHQUFHLFVBQVUsQ0FBQztZQUNoRCxTQUFTLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUM7U0FDdkM7UUFBQyxPQUFPLENBQUMsRUFBRTtZQUNWLGdJQUFnSTtZQUNoSSxJQUFJLENBQUMsQ0FBQyxDQUFDLFlBQVksYUFBRyxDQUFDLGVBQWUsQ0FBQyxFQUFFO2dCQUN2QyxNQUFNLENBQUMsQ0FBQzthQUNUO1lBRUQsU0FBUyxHQUFHLE1BQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLENBQUM7U0FDbEQ7Z0JBQVM7WUFDUixJQUFJLENBQUMsNkJBQTZCLEdBQUcsU0FBUyxDQUFDO1NBQ2hEO1FBRUQsT0FBTyxLQUFLLEVBQUUsSUFBZSxFQUFFLE9BQWdDLEVBQUUsRUFBRTtZQUNqRSxNQUFNLGlCQUFpQixHQUEyQjtnQkFDaEQsV0FBVyxFQUFFLElBQUk7Z0JBQ2pCLG1CQUFtQixFQUFFLElBQUk7Z0JBQ3pCLGtCQUFrQixFQUFFLElBQUk7Z0JBQ3hCLEdBQUcsT0FBTzthQUNYLENBQUM7WUFDRixNQUFNLGlCQUFpQixHQUFHO2dCQUN4QixxQkFBcUIsRUFBRSxJQUFJLEdBQUcsRUFBVTthQUN6QyxDQUFDO1lBRUYsa0NBQWtDO1lBQ2xDLElBQUksaUJBQWlCLENBQUMsa0JBQWtCLEVBQUU7Z0JBQ3hDLEtBQUssTUFBTSxPQUFPLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsRUFBRTtvQkFDeEMsSUFBSSxHQUFHLE1BQU0sSUFBQSxvQkFBYSxFQUN4QixJQUFBLG1CQUFTLEVBQUMsSUFBSSxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsU0FBUyxDQUFDLENBQ3ZFLENBQUM7aUJBQ0g7YUFDRjtZQUVELHVCQUF1QjtZQUN2QixNQUFNLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLEVBQUUsVUFBVSxDQUFDLGtCQUFrQixDQUFDLENBQUM7WUFFcEUsZ0JBQWdCO1lBQ2hCLElBQUksaUJBQWlCLENBQUMsV0FBVyxFQUFFO2dCQUNqQyxNQUFNLE9BQU8sR0FBZ0IsQ0FBQyxLQUFLLEVBQUUsT0FBTyxFQUFFLEVBQUU7b0JBQzlDLElBQUksS0FBSyxLQUFLLFNBQVMsRUFBRTt3QkFDdkIsaUJBQWlCLENBQUMscUJBQXFCLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDO3FCQUN0RDtvQkFFRCxPQUFPLEtBQUssQ0FBQztnQkFDZixDQUFDLENBQUM7Z0JBQ0YsSUFBSSxPQUFPLE1BQU0sS0FBSyxRQUFRLEVBQUU7b0JBQzlCLE1BQU0sSUFBQSxvQkFBYSxFQUNqQixJQUFBLG1CQUFTLEVBQUMsSUFBSSxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsU0FBUyxDQUFDLENBQ3ZFLENBQUM7aUJBQ0g7Z0JBRUQsTUFBTSxXQUFXLEdBQUcsVUFBVSxDQUFDLGlCQUFpQixDQUFDLE1BQU0sQ0FDckQsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLENBQUMsaUJBQWlCLENBQUMscUJBQXFCLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FDOUQsQ0FBQztnQkFFRixJQUFJLFdBQVcsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO29CQUMxQixNQUFNLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxFQUFFLFdBQVcsQ0FBQyxDQUFDO2lCQUM3QzthQUNGO1lBRUQscUJBQXFCO1lBQ3JCLElBQUk7Z0JBQ0YsTUFBTSxPQUFPLEdBQUcsTUFBTSxTQUFTLENBQUMsSUFBSSxDQUFDLGlCQUFpQixFQUFFLElBQUksQ0FBQyxDQUFDO2dCQUU5RCxJQUFJLENBQUMsT0FBTyxFQUFFO29CQUNaLE9BQU8sRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxTQUFTLENBQUMsTUFBTSxJQUFJLEVBQUUsRUFBRSxDQUFDO2lCQUMxRDthQUNGO1lBQUMsT0FBTyxLQUFLLEVBQUU7Z0JBQ2QsSUFBSSxLQUFLLFlBQVksYUFBRyxDQUFDLGVBQWUsRUFBRTtvQkFDeEMsT0FBTyxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUM7aUJBQ3ZEO2dCQUVELE1BQU0sS0FBSyxDQUFDO2FBQ2I7WUFFRCxtQ0FBbUM7WUFDbkMsSUFBSSxpQkFBaUIsQ0FBQyxtQkFBbUIsRUFBRTtnQkFDekMsS0FBSyxNQUFNLE9BQU8sSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRSxFQUFFO29CQUN6QyxJQUFJLEdBQUcsTUFBTSxJQUFBLG9CQUFhLEVBQ3hCLElBQUEsbUJBQVMsRUFBQyxJQUFJLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxTQUFTLENBQUMsQ0FDdkUsQ0FBQztpQkFDSDthQUNGO1lBRUQsT0FBTyxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLENBQUM7UUFDakMsQ0FBQyxDQUFDO0lBQ0osQ0FBQztJQUVELFNBQVMsQ0FBQyxNQUFvQjtRQUM1QixJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUNyRCxDQUFDO0lBRUQsdUJBQXVCLENBQUksTUFBYyxFQUFFLFFBQWlDO1FBQzFFLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLEVBQUU7WUFDL0IsTUFBTSxJQUFJLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQztTQUN6QjtRQUVELElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBRSxRQUErQyxDQUFDLENBQUM7UUFFN0UsSUFBSSxDQUFDLElBQUksQ0FBQyxvQkFBb0IsRUFBRTtZQUM5QixJQUFJLENBQUMsb0JBQW9CLEdBQUcsSUFBSSxDQUFDO1lBRWpDLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDO2dCQUNuQixPQUFPLEVBQUUsVUFBVTtnQkFDbkIsTUFBTSxFQUFFLEtBQUs7Z0JBQ2IsS0FBSyxFQUFFLElBQUk7Z0JBQ1gsT0FBTyxFQUFFLENBQUMsTUFBTSxFQUFFLGFBQWEsRUFBRSxFQUFFLEVBQUUsRUFBRTtvQkFDckMsTUFBTSxvQkFBb0IsR0FBRyxJQUFJLENBQUMsNkJBQTZCLENBQUM7b0JBQ2hFLElBQUksb0JBQW9CLEtBQUssU0FBUyxFQUFFO3dCQUN0QyxPQUFPLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQztxQkFDbkI7b0JBRUQscUJBQXFCO29CQUNyQixNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUMsRUFBRSxDQUFDLENBQUM7b0JBQ2hELG9CQUFvQixDQUFDLGtCQUFrQixDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDO29CQUUvRSxPQUFPLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQztnQkFDcEIsQ0FBQztnQkFDRCxVQUFVLEVBQUU7b0JBQ1YsSUFBSSxFQUFFLFFBQVE7b0JBQ2QsVUFBVSxFQUFFO3dCQUNWLFNBQVMsRUFBRSxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUU7cUJBQzlCO29CQUNELG9CQUFvQixFQUFFLElBQUk7b0JBQzFCLFFBQVEsRUFBRSxDQUFDLFNBQVMsQ0FBQztpQkFDdEI7YUFDRixDQUFDLENBQUM7U0FDSjtJQUNILENBQUM7SUFFRCxrQkFBa0IsQ0FBQyxPQUFtQjtRQUNwQyxJQUFJLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNqQyxDQUFDO0lBRUQsaUJBQWlCLENBQUMsUUFBd0I7UUFDeEMsTUFBTSxPQUFPLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUM7UUFFdkMsSUFBSSxDQUFDLGVBQWUsR0FBRyxRQUFRLENBQUM7UUFFaEMsSUFBSSxPQUFPLEVBQUU7WUFDWCxPQUFPO1NBQ1I7UUFFRCxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQztZQUNuQixPQUFPLEVBQUUsVUFBVTtZQUNuQixNQUFNLEVBQUUsS0FBSztZQUNiLEtBQUssRUFBRSxJQUFJO1lBQ1gsT0FBTyxFQUFFLENBQUMsTUFBTSxFQUFFLFlBQVksRUFBRSxFQUFFLEVBQUUsRUFBRTtnQkFDcEMsTUFBTSxvQkFBb0IsR0FBRyxJQUFJLENBQUMsNkJBQTZCLENBQUM7Z0JBQ2hFLElBQUksQ0FBQyxvQkFBb0IsRUFBRTtvQkFDekIsT0FBTyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUM7aUJBQ25CO2dCQUVELE1BQU0sSUFBSSxHQUFHLEdBQUcsR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO2dCQUUzRCxJQUFJLElBQXdCLENBQUM7Z0JBQzdCLElBQUksS0FBc0YsQ0FBQztnQkFDM0YsSUFBSSxPQUFlLENBQUM7Z0JBQ3BCLElBQUksT0FBTyxNQUFNLElBQUksUUFBUSxFQUFFO29CQUM3QixPQUFPLEdBQUcsTUFBTSxDQUFDO2lCQUNsQjtxQkFBTTtvQkFDTCxPQUFPLEdBQUcsTUFBTSxDQUFDLE9BQU8sQ0FBQztvQkFDekIsSUFBSSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUM7b0JBQ25CLEtBQUssR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDO2lCQUN0QjtnQkFFRCxNQUFNLGFBQWEsR0FBRyxJQUFBLDBCQUFnQixFQUFDLFlBQTBCLENBQUMsQ0FBQztnQkFDbkUsSUFBSSxDQUFDLElBQUksRUFBRTtvQkFDVCxJQUFJLGFBQWEsQ0FBQyxJQUFJLEtBQUssQ0FBQyxJQUFJLGFBQWEsQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLEVBQUU7d0JBQzVELElBQUksR0FBRyxjQUFjLENBQUM7cUJBQ3ZCO3lCQUFNLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBRSxZQUEyQixDQUFDLElBQUksQ0FBQyxFQUFFO3dCQUMzRCxJQUFJLEdBQUcsTUFBTSxDQUFDO3FCQUNmO3lCQUFNLElBQ0wsYUFBYSxDQUFDLElBQUksS0FBSyxDQUFDO3dCQUN4QixhQUFhLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQzt3QkFDekIsWUFBMkIsQ0FBQyxLQUFLO3dCQUNsQyxLQUFLLENBQUMsT0FBTyxDQUFHLFlBQTJCLENBQUMsS0FBb0IsQ0FBQyxJQUFJLENBQUMsRUFDdEU7d0JBQ0EsSUFBSSxHQUFHLE1BQU0sQ0FBQztxQkFDZjt5QkFBTTt3QkFDTCxJQUFJLEdBQUcsT0FBTyxDQUFDO3FCQUNoQjtpQkFDRjtnQkFFRCxJQUFJLFdBQVcsQ0FBQztnQkFDaEIsSUFBSSxJQUFJLEtBQUssTUFBTSxFQUFFO29CQUNuQixXQUFXO3dCQUNULE1BQU0sQ0FBQyxXQUFXLEtBQUssU0FBUzs0QkFDOUIsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxJQUFJLEtBQUssQ0FBQyxJQUFJLGFBQWEsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDOzRCQUN4RCxDQUFDLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQztvQkFFekIsTUFBTSxVQUFVLEdBQUcsV0FBVzt3QkFDNUIsQ0FBQyxDQUFFLFlBQTJCLENBQUMsS0FBSzs0QkFDaEMsWUFBMkIsQ0FBQyxLQUFvQixDQUFDLElBQUk7d0JBQ3pELENBQUMsQ0FBRSxZQUEyQixDQUFDLElBQUksQ0FBQztvQkFDdEMsSUFBSSxDQUFDLEtBQUssSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxFQUFFO3dCQUN2QyxLQUFLLEdBQUcsRUFBRSxDQUFDO3dCQUNYLEtBQUssTUFBTSxLQUFLLElBQUksVUFBVSxFQUFFOzRCQUM5QixJQUFJLE9BQU8sS0FBSyxJQUFJLFFBQVEsRUFBRTtnQ0FDNUIsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQzs2QkFDbkI7aUNBQU0sSUFBSSxPQUFPLEtBQUssSUFBSSxRQUFRLEVBQUU7Z0NBQ25DLFVBQVU7NkJBQ1g7aUNBQU07Z0NBQ0wsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLEtBQUssRUFBRSxLQUFLLENBQUMsUUFBUSxFQUFFLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQzs2QkFDaEQ7eUJBQ0Y7cUJBQ0Y7aUJBQ0Y7Z0JBRUQsTUFBTSxVQUFVLEdBQXFCO29CQUNuQyxFQUFFLEVBQUUsSUFBSTtvQkFDUixJQUFJO29CQUNKLE9BQU87b0JBQ1AsR0FBRyxFQUFFLE1BQU07b0JBQ1gsS0FBSztvQkFDTCxXQUFXO29CQUNYLGFBQWE7b0JBQ2IsT0FBTyxFQUNMLE9BQVEsWUFBMkIsQ0FBQyxPQUFPLElBQUksUUFBUTt3QkFDdEQsWUFBMkIsQ0FBQyxPQUFPLEtBQUssSUFBSTt3QkFDN0MsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFFLFlBQTJCLENBQUMsT0FBTyxDQUFDO3dCQUNsRCxDQUFDLENBQUMsU0FBUzt3QkFDWCxDQUFDLENBQUcsWUFBMkIsQ0FBQyxPQUFvQjtvQkFDeEQsS0FBSyxDQUFDLFNBQVMsQ0FBQyxJQUFlO3dCQUM3QixJQUFJOzRCQUNGLE1BQU0sTUFBTSxHQUFHLE1BQU0sRUFBRSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsWUFBWSxFQUFFLElBQUksQ0FBQyxDQUFDOzRCQUMxRCwwRUFBMEU7NEJBQzFFLElBQUksTUFBTSxFQUFFO2dDQUNWLE9BQU8sTUFBMEIsQ0FBQzs2QkFDbkM7aUNBQU0sSUFBSSxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxNQUFNLEVBQUU7Z0NBQ2pDLGtFQUFrRTtnQ0FDbEUsT0FBTyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFpQixDQUFDOzZCQUM1Qzt5QkFDRjt3QkFBQyxPQUFPLENBQUMsRUFBRTs0QkFDVixNQUFNLGVBQWUsR0FBRyxDQUF5QixDQUFDOzRCQUNsRCw0RUFBNEU7NEJBQzVFLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxlQUFlLENBQUMsTUFBTSxDQUFDLElBQUksZUFBZSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUU7Z0NBQzFFLE9BQU8sZUFBZSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUM7NkJBQzFDO3lCQUNGO3dCQUVELE9BQU8sS0FBSyxDQUFDO29CQUNmLENBQUM7aUJBQ0YsQ0FBQztnQkFFRixvQkFBb0IsQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7Z0JBRXhELE9BQU87b0JBQ0wscUVBQXFFO29CQUNyRSxVQUFVO29CQUNWLElBQUksSUFBSSxJQUFJLElBQUksQ0FBQyxxQkFBcUIsRUFBRTt3QkFDdEMsSUFBSSxDQUFDLHFCQUFxQixDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztxQkFDdEM7b0JBRUQsT0FBTyxJQUFJLENBQUM7Z0JBQ2QsQ0FBQyxDQUFDO1lBQ0osQ0FBQztZQUNELFVBQVUsRUFBRTtnQkFDVixLQUFLLEVBQUU7b0JBQ0wsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFO29CQUNsQjt3QkFDRSxJQUFJLEVBQUUsUUFBUTt3QkFDZCxVQUFVLEVBQUU7NEJBQ1YsTUFBTSxFQUFFLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRTs0QkFDMUIsU0FBUyxFQUFFLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRTt5QkFDOUI7d0JBQ0Qsb0JBQW9CLEVBQUUsSUFBSTt3QkFDMUIsUUFBUSxFQUFFLENBQUMsU0FBUyxDQUFDO3FCQUN0QjtpQkFDRjthQUNGO1NBQ0YsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVPLEtBQUssQ0FBQyxhQUFhLENBQUMsSUFBZSxFQUFFLE9BQWdDO1FBQzNFLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUM7UUFDdEMsSUFBSSxDQUFDLFFBQVEsRUFBRTtZQUNiLE9BQU87U0FDUjtRQUVELE1BQU0sT0FBTyxHQUFHLE1BQU0sSUFBQSxvQkFBYSxFQUFDLElBQUEsV0FBSSxFQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDN0QsS0FBSyxNQUFNLElBQUksSUFBSSxPQUFPLEVBQUU7WUFDMUIsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFFL0Msa0JBQWtCLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxhQUFhLEVBQUUsT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsSUFBSSxDQUFDLENBQUM7U0FDcEY7SUFDSCxDQUFDO0lBRU8sTUFBTSxDQUFDLElBQUk7SUFDakIsOERBQThEO0lBQzlELElBQVMsRUFDVCxTQUFtQixFQUNuQixLQUFjO0lBQ2QsOERBQThEO0lBQzlELFNBQWMsSUFBSSxFQUNsQixjQUF1QixFQUN2QixLQUFlO1FBRWYsS0FBSyxJQUFJLEtBQUssR0FBRyxDQUFDLEVBQUUsS0FBSyxHQUFHLFNBQVMsQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLEVBQUU7WUFDckQsTUFBTSxRQUFRLEdBQUcsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ2xDLElBQUksUUFBUSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRTtnQkFDM0IsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUU7b0JBQ3hCLE9BQU87aUJBQ1I7Z0JBRUQsS0FBSyxJQUFJLFNBQVMsR0FBRyxDQUFDLEVBQUUsU0FBUyxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUUsU0FBUyxFQUFFLEVBQUU7b0JBQzVELGtCQUFrQixDQUFDLElBQUksQ0FDckIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUNmLFNBQVMsQ0FBQyxLQUFLLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxFQUMxQixLQUFLLEVBQ0wsSUFBSSxFQUNKLEdBQUcsU0FBUyxFQUFFLENBQ2YsQ0FBQztpQkFDSDtnQkFFRCxPQUFPO2FBQ1I7WUFFRCxJQUFJLENBQUMsSUFBSSxJQUFJLE1BQU0sS0FBSyxJQUFJLElBQUksY0FBYyxFQUFFO2dCQUM5QyxJQUFJLEdBQUcsTUFBTSxDQUFDLGNBQWMsQ0FBQyxHQUFHLEVBQUUsQ0FBQzthQUNwQztZQUVELE1BQU0sR0FBRyxJQUFJLENBQUM7WUFDZCxjQUFjLEdBQUcsUUFBUSxDQUFDO1lBQzFCLElBQUksR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7U0FDdkI7UUFFRCxJQUFJLE1BQU0sSUFBSSxjQUFjLElBQUksQ0FBQyxLQUFLLElBQUksTUFBTSxDQUFDLGNBQWMsQ0FBQyxLQUFLLFNBQVMsQ0FBQyxFQUFFO1lBQy9FLE1BQU0sQ0FBQyxjQUFjLENBQUMsR0FBRyxLQUFLLENBQUM7U0FDaEM7SUFDSCxDQUFDO0lBRU8sS0FBSyxDQUFDLG1CQUFtQixDQUMvQixJQUFPLEVBQ1AsYUFBc0M7UUFFdEMsS0FBSyxNQUFNLENBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQyxJQUFJLGFBQWEsQ0FBQyxPQUFPLEVBQUUsRUFBRTtZQUN2RCxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ3RDLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxPQUFpQixDQUFDLENBQUM7WUFDN0QsSUFBSSxDQUFDLE1BQU0sRUFBRTtnQkFDWCxTQUFTO2FBQ1Y7WUFFRCxJQUFJLEtBQUssR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDM0IsSUFBSSxJQUFBLG1CQUFZLEVBQUMsS0FBSyxDQUFDLEVBQUU7Z0JBQ3ZCLEtBQUssR0FBRyxDQUFDLE1BQU0sSUFBQSxvQkFBYSxFQUFDLEtBQUssQ0FBQyxDQUFPLENBQUM7YUFDNUM7WUFFRCxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLFNBQVMsRUFBRSxLQUFLLENBQUMsQ0FBQztTQUNqRDtJQUNILENBQUM7SUFFRCxzQkFBc0IsQ0FBQyxPQUFrQztRQUN2RCxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQztZQUNuQixPQUFPLEVBQUUsY0FBYztZQUN2QixRQUFRLEVBQUUsQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLGFBQWEsRUFBRSxPQUFPLEVBQUUsRUFBRTtnQkFDbEQsSUFBSSxNQUFNLEVBQUU7b0JBQ1YsT0FBTyxDQUNMLFdBQVcsT0FBTyxFQUFFLGtCQUFrQixrQkFDcEMsT0FBTyxNQUFNLElBQUksUUFBUSxDQUFDLENBQUMsQ0FBQyxJQUFJLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUM5QyxFQUFFLENBQ0gsQ0FBQztpQkFDSDtnQkFFRCxPQUFPLElBQUksQ0FBQztZQUNkLENBQUM7WUFDRCxNQUFNLEVBQUUsS0FBSztTQUNkLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFTyxvQkFBb0IsQ0FBQyxFQUFnQjtRQUMzQyxPQUFPLEVBQUUsQ0FBQyxXQUFXO2FBQ2xCLEtBQUssQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLFNBQVMsR0FBRyxDQUFDLENBQUM7YUFDMUIsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3ZFLENBQUM7Q0FDRjtBQXBrQkQsZ0RBb2tCQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCBHb29nbGUgTExDIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9hbmd1bGFyLmlvL2xpY2Vuc2VcbiAqL1xuXG5pbXBvcnQgQWp2LCB7IFNjaGVtYU9iakN4dCwgVmFsaWRhdGVGdW5jdGlvbiB9IGZyb20gJ2Fqdic7XG5pbXBvcnQgYWp2QWRkRm9ybWF0cyBmcm9tICdhanYtZm9ybWF0cyc7XG5pbXBvcnQgKiBhcyBodHRwIGZyb20gJ2h0dHAnO1xuaW1wb3J0ICogYXMgaHR0cHMgZnJvbSAnaHR0cHMnO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgZnJvbSwgaXNPYnNlcnZhYmxlLCBsYXN0VmFsdWVGcm9tIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgKiBhcyBVcmwgZnJvbSAndXJsJztcbmltcG9ydCB7IEJhc2VFeGNlcHRpb24gfSBmcm9tICcuLi8uLi9leGNlcHRpb24nO1xuaW1wb3J0IHsgUGFydGlhbGx5T3JkZXJlZFNldCwgZGVlcENvcHkgfSBmcm9tICcuLi8uLi91dGlscyc7XG5pbXBvcnQgeyBKc29uQXJyYXksIEpzb25PYmplY3QsIEpzb25WYWx1ZSwgaXNKc29uT2JqZWN0IH0gZnJvbSAnLi4vdXRpbHMnO1xuaW1wb3J0IHtcbiAgSnNvblBvaW50ZXIsXG4gIEpzb25WaXNpdG9yLFxuICBQcm9tcHREZWZpbml0aW9uLFxuICBQcm9tcHRQcm92aWRlcixcbiAgU2NoZW1hRm9ybWF0LFxuICBTY2hlbWFSZWdpc3RyeSxcbiAgU2NoZW1hVmFsaWRhdG9yLFxuICBTY2hlbWFWYWxpZGF0b3JFcnJvcixcbiAgU2NoZW1hVmFsaWRhdG9yT3B0aW9ucyxcbiAgU2NoZW1hVmFsaWRhdG9yUmVzdWx0LFxuICBTbWFydERlZmF1bHRQcm92aWRlcixcbn0gZnJvbSAnLi9pbnRlcmZhY2UnO1xuaW1wb3J0IHsgSnNvblNjaGVtYSB9IGZyb20gJy4vc2NoZW1hJztcbmltcG9ydCB7IGdldFR5cGVzT2ZTY2hlbWEgfSBmcm9tICcuL3V0aWxpdHknO1xuaW1wb3J0IHsgdmlzaXRKc29uLCB2aXNpdEpzb25TY2hlbWEgfSBmcm9tICcuL3Zpc2l0b3InO1xuXG5leHBvcnQgdHlwZSBVcmlIYW5kbGVyID0gKFxuICB1cmk6IHN0cmluZyxcbikgPT4gT2JzZXJ2YWJsZTxKc29uT2JqZWN0PiB8IFByb21pc2U8SnNvbk9iamVjdD4gfCBudWxsIHwgdW5kZWZpbmVkO1xuXG5leHBvcnQgY2xhc3MgU2NoZW1hVmFsaWRhdGlvbkV4Y2VwdGlvbiBleHRlbmRzIEJhc2VFeGNlcHRpb24ge1xuICBwdWJsaWMgcmVhZG9ubHkgZXJyb3JzOiBTY2hlbWFWYWxpZGF0b3JFcnJvcltdO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIGVycm9ycz86IFNjaGVtYVZhbGlkYXRvckVycm9yW10sXG4gICAgYmFzZU1lc3NhZ2UgPSAnU2NoZW1hIHZhbGlkYXRpb24gZmFpbGVkIHdpdGggdGhlIGZvbGxvd2luZyBlcnJvcnM6JyxcbiAgKSB7XG4gICAgaWYgKCFlcnJvcnMgfHwgZXJyb3JzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgc3VwZXIoJ1NjaGVtYSB2YWxpZGF0aW9uIGZhaWxlZC4nKTtcbiAgICAgIHRoaXMuZXJyb3JzID0gW107XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBtZXNzYWdlcyA9IFNjaGVtYVZhbGlkYXRpb25FeGNlcHRpb24uY3JlYXRlTWVzc2FnZXMoZXJyb3JzKTtcbiAgICBzdXBlcihgJHtiYXNlTWVzc2FnZX1cXG4gICR7bWVzc2FnZXMuam9pbignXFxuICAnKX1gKTtcbiAgICB0aGlzLmVycm9ycyA9IGVycm9ycztcbiAgfVxuXG4gIHB1YmxpYyBzdGF0aWMgY3JlYXRlTWVzc2FnZXMoZXJyb3JzPzogU2NoZW1hVmFsaWRhdG9yRXJyb3JbXSk6IHN0cmluZ1tdIHtcbiAgICBpZiAoIWVycm9ycyB8fCBlcnJvcnMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuXG4gICAgY29uc3QgbWVzc2FnZXMgPSBlcnJvcnMubWFwKChlcnIpID0+IHtcbiAgICAgIGxldCBtZXNzYWdlID0gYERhdGEgcGF0aCAke0pTT04uc3RyaW5naWZ5KGVyci5pbnN0YW5jZVBhdGgpfSAke2Vyci5tZXNzYWdlfWA7XG4gICAgICBpZiAoZXJyLnBhcmFtcykge1xuICAgICAgICBzd2l0Y2ggKGVyci5rZXl3b3JkKSB7XG4gICAgICAgICAgY2FzZSAnYWRkaXRpb25hbFByb3BlcnRpZXMnOlxuICAgICAgICAgICAgbWVzc2FnZSArPSBgKCR7ZXJyLnBhcmFtcy5hZGRpdGlvbmFsUHJvcGVydHl9KWA7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgIGNhc2UgJ2VudW0nOlxuICAgICAgICAgICAgbWVzc2FnZSArPSBgLiBBbGxvd2VkIHZhbHVlcyBhcmU6ICR7KGVyci5wYXJhbXMuYWxsb3dlZFZhbHVlcyBhcyBzdHJpbmdbXSB8IHVuZGVmaW5lZClcbiAgICAgICAgICAgICAgPy5tYXAoKHYpID0+IGBcIiR7dn1cImApXG4gICAgICAgICAgICAgIC5qb2luKCcsICcpfWA7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gbWVzc2FnZSArICcuJztcbiAgICB9KTtcblxuICAgIHJldHVybiBtZXNzYWdlcztcbiAgfVxufVxuXG5pbnRlcmZhY2UgU2NoZW1hSW5mbyB7XG4gIHNtYXJ0RGVmYXVsdFJlY29yZDogTWFwPHN0cmluZywgSnNvbk9iamVjdD47XG4gIHByb21wdERlZmluaXRpb25zOiBBcnJheTxQcm9tcHREZWZpbml0aW9uPjtcbn1cblxuZXhwb3J0IGNsYXNzIENvcmVTY2hlbWFSZWdpc3RyeSBpbXBsZW1lbnRzIFNjaGVtYVJlZ2lzdHJ5IHtcbiAgcHJpdmF0ZSBfYWp2OiBBanY7XG4gIHByaXZhdGUgX3VyaUNhY2hlID0gbmV3IE1hcDxzdHJpbmcsIEpzb25PYmplY3Q+KCk7XG4gIHByaXZhdGUgX3VyaUhhbmRsZXJzID0gbmV3IFNldDxVcmlIYW5kbGVyPigpO1xuICBwcml2YXRlIF9wcmUgPSBuZXcgUGFydGlhbGx5T3JkZXJlZFNldDxKc29uVmlzaXRvcj4oKTtcbiAgcHJpdmF0ZSBfcG9zdCA9IG5ldyBQYXJ0aWFsbHlPcmRlcmVkU2V0PEpzb25WaXNpdG9yPigpO1xuXG4gIHByaXZhdGUgX2N1cnJlbnRDb21waWxhdGlvblNjaGVtYUluZm8/OiBTY2hlbWFJbmZvO1xuXG4gIHByaXZhdGUgX3NtYXJ0RGVmYXVsdEtleXdvcmQgPSBmYWxzZTtcbiAgcHJpdmF0ZSBfcHJvbXB0UHJvdmlkZXI/OiBQcm9tcHRQcm92aWRlcjtcbiAgcHJpdmF0ZSBfc291cmNlTWFwID0gbmV3IE1hcDxzdHJpbmcsIFNtYXJ0RGVmYXVsdFByb3ZpZGVyPHt9Pj4oKTtcblxuICBjb25zdHJ1Y3Rvcihmb3JtYXRzOiBTY2hlbWFGb3JtYXRbXSA9IFtdKSB7XG4gICAgdGhpcy5fYWp2ID0gbmV3IEFqdih7XG4gICAgICBzdHJpY3Q6IGZhbHNlLFxuICAgICAgbG9hZFNjaGVtYTogKHVyaTogc3RyaW5nKSA9PiB0aGlzLl9mZXRjaCh1cmkpLFxuICAgICAgcGFzc0NvbnRleHQ6IHRydWUsXG4gICAgfSk7XG5cbiAgICBhanZBZGRGb3JtYXRzKHRoaXMuX2Fqdik7XG5cbiAgICBmb3IgKGNvbnN0IGZvcm1hdCBvZiBmb3JtYXRzKSB7XG4gICAgICB0aGlzLmFkZEZvcm1hdChmb3JtYXQpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgX2ZldGNoKHVyaTogc3RyaW5nKTogUHJvbWlzZTxKc29uT2JqZWN0PiB7XG4gICAgY29uc3QgbWF5YmVTY2hlbWEgPSB0aGlzLl91cmlDYWNoZS5nZXQodXJpKTtcblxuICAgIGlmIChtYXliZVNjaGVtYSkge1xuICAgICAgcmV0dXJuIG1heWJlU2NoZW1hO1xuICAgIH1cblxuICAgIC8vIFRyeSBhbGwgaGFuZGxlcnMsIG9uZSBhZnRlciB0aGUgb3RoZXIuXG4gICAgZm9yIChjb25zdCBoYW5kbGVyIG9mIHRoaXMuX3VyaUhhbmRsZXJzKSB7XG4gICAgICBsZXQgaGFuZGxlclJlc3VsdCA9IGhhbmRsZXIodXJpKTtcbiAgICAgIGlmIChoYW5kbGVyUmVzdWx0ID09PSBudWxsIHx8IGhhbmRsZXJSZXN1bHQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGlzT2JzZXJ2YWJsZShoYW5kbGVyUmVzdWx0KSkge1xuICAgICAgICBoYW5kbGVyUmVzdWx0ID0gbGFzdFZhbHVlRnJvbShoYW5kbGVyUmVzdWx0KTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgdmFsdWUgPSBhd2FpdCBoYW5kbGVyUmVzdWx0O1xuICAgICAgdGhpcy5fdXJpQ2FjaGUuc2V0KHVyaSwgdmFsdWUpO1xuXG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuXG4gICAgLy8gSWYgbm9uZSBhcmUgZm91bmQsIGhhbmRsZSB1c2luZyBodHRwIGNsaWVudC5cbiAgICByZXR1cm4gbmV3IFByb21pc2U8SnNvbk9iamVjdD4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgY29uc3QgdXJsID0gbmV3IFVybC5VUkwodXJpKTtcbiAgICAgIGNvbnN0IGNsaWVudCA9IHVybC5wcm90b2NvbCA9PT0gJ2h0dHBzOicgPyBodHRwcyA6IGh0dHA7XG4gICAgICBjbGllbnQuZ2V0KHVybCwgKHJlcykgPT4ge1xuICAgICAgICBpZiAoIXJlcy5zdGF0dXNDb2RlIHx8IHJlcy5zdGF0dXNDb2RlID49IDMwMCkge1xuICAgICAgICAgIC8vIENvbnN1bWUgdGhlIHJlc3Qgb2YgdGhlIGRhdGEgdG8gZnJlZSBtZW1vcnkuXG4gICAgICAgICAgcmVzLnJlc3VtZSgpO1xuICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IoYFJlcXVlc3QgZmFpbGVkLiBTdGF0dXMgQ29kZTogJHtyZXMuc3RhdHVzQ29kZX1gKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzLnNldEVuY29kaW5nKCd1dGY4Jyk7XG4gICAgICAgICAgbGV0IGRhdGEgPSAnJztcbiAgICAgICAgICByZXMub24oJ2RhdGEnLCAoY2h1bmspID0+IHtcbiAgICAgICAgICAgIGRhdGEgKz0gY2h1bms7XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgcmVzLm9uKCdlbmQnLCAoKSA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICBjb25zdCBqc29uID0gSlNPTi5wYXJzZShkYXRhKTtcbiAgICAgICAgICAgICAgdGhpcy5fdXJpQ2FjaGUuc2V0KHVyaSwganNvbik7XG4gICAgICAgICAgICAgIHJlc29sdmUoanNvbik7XG4gICAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgcmVqZWN0KGVycik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZCBhIHRyYW5zZm9ybWF0aW9uIHN0ZXAgYmVmb3JlIHRoZSB2YWxpZGF0aW9uIG9mIGFueSBKc29uLlxuICAgKiBAcGFyYW0ge0pzb25WaXNpdG9yfSB2aXNpdG9yIFRoZSB2aXNpdG9yIHRvIHRyYW5zZm9ybSBldmVyeSB2YWx1ZS5cbiAgICogQHBhcmFtIHtKc29uVmlzaXRvcltdfSBkZXBzIEEgbGlzdCBvZiBvdGhlciB2aXNpdG9ycyB0byBydW4gYmVmb3JlLlxuICAgKi9cbiAgYWRkUHJlVHJhbnNmb3JtKHZpc2l0b3I6IEpzb25WaXNpdG9yLCBkZXBzPzogSnNvblZpc2l0b3JbXSkge1xuICAgIHRoaXMuX3ByZS5hZGQodmlzaXRvciwgZGVwcyk7XG4gIH1cblxuICAvKipcbiAgICogQWRkIGEgdHJhbnNmb3JtYXRpb24gc3RlcCBhZnRlciB0aGUgdmFsaWRhdGlvbiBvZiBhbnkgSnNvbi4gVGhlIEpTT04gd2lsbCBub3QgYmUgdmFsaWRhdGVkXG4gICAqIGFmdGVyIHRoZSBQT1NULCBzbyBpZiB0cmFuc2Zvcm1hdGlvbnMgYXJlIG5vdCBjb21wYXRpYmxlIHdpdGggdGhlIFNjaGVtYSBpdCB3aWxsIG5vdCByZXN1bHRcbiAgICogaW4gYW4gZXJyb3IuXG4gICAqIEBwYXJhbSB7SnNvblZpc2l0b3J9IHZpc2l0b3IgVGhlIHZpc2l0b3IgdG8gdHJhbnNmb3JtIGV2ZXJ5IHZhbHVlLlxuICAgKiBAcGFyYW0ge0pzb25WaXNpdG9yW119IGRlcHMgQSBsaXN0IG9mIG90aGVyIHZpc2l0b3JzIHRvIHJ1biBiZWZvcmUuXG4gICAqL1xuICBhZGRQb3N0VHJhbnNmb3JtKHZpc2l0b3I6IEpzb25WaXNpdG9yLCBkZXBzPzogSnNvblZpc2l0b3JbXSkge1xuICAgIHRoaXMuX3Bvc3QuYWRkKHZpc2l0b3IsIGRlcHMpO1xuICB9XG5cbiAgcHJvdGVjdGVkIF9yZXNvbHZlcihcbiAgICByZWY6IHN0cmluZyxcbiAgICB2YWxpZGF0ZT86IFZhbGlkYXRlRnVuY3Rpb24sXG4gICk6IHsgY29udGV4dD86IFZhbGlkYXRlRnVuY3Rpb247IHNjaGVtYT86IEpzb25PYmplY3QgfSB7XG4gICAgaWYgKCF2YWxpZGF0ZSB8fCAhcmVmKSB7XG4gICAgICByZXR1cm4ge307XG4gICAgfVxuXG4gICAgY29uc3Qgc2NoZW1hID0gdmFsaWRhdGUuc2NoZW1hRW52LnJvb3Quc2NoZW1hO1xuICAgIGNvbnN0IGlkID0gdHlwZW9mIHNjaGVtYSA9PT0gJ29iamVjdCcgPyBzY2hlbWEuJGlkIDogbnVsbDtcblxuICAgIGxldCBmdWxsUmVmZXJlbmNlID0gcmVmO1xuICAgIGlmICh0eXBlb2YgaWQgPT09ICdzdHJpbmcnKSB7XG4gICAgICBmdWxsUmVmZXJlbmNlID0gVXJsLnJlc29sdmUoaWQsIHJlZik7XG5cbiAgICAgIGlmIChyZWYuc3RhcnRzV2l0aCgnIycpKSB7XG4gICAgICAgIGZ1bGxSZWZlcmVuY2UgPSBpZCArIGZ1bGxSZWZlcmVuY2U7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgcmVzb2x2ZWRTY2hlbWEgPSB0aGlzLl9hanYuZ2V0U2NoZW1hKGZ1bGxSZWZlcmVuY2UpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGNvbnRleHQ6IHJlc29sdmVkU2NoZW1hPy5zY2hlbWFFbnYudmFsaWRhdGUsXG4gICAgICBzY2hlbWE6IHJlc29sdmVkU2NoZW1hPy5zY2hlbWEgYXMgSnNvbk9iamVjdCxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEZsYXR0ZW4gdGhlIFNjaGVtYSwgcmVzb2x2aW5nIGFuZCByZXBsYWNpbmcgYWxsIHRoZSByZWZzLiBNYWtlcyBpdCBpbnRvIGEgc3luY2hyb25vdXMgc2NoZW1hXG4gICAqIHRoYXQgaXMgYWxzbyBlYXNpZXIgdG8gdHJhdmVyc2UuIERvZXMgbm90IGNhY2hlIHRoZSByZXN1bHQuXG4gICAqXG4gICAqIFByb2R1Y2luZyBhIGZsYXR0ZW4gc2NoZW1hIGRvY3VtZW50IGRvZXMgbm90IGluIGFsbCBjYXNlcyBwcm9kdWNlIGEgc2NoZW1hIHdpdGggaWRlbnRpY2FsIGJlaGF2aW9yIHRvIHRoZSBvcmlnaW5hbC5cbiAgICogU2VlOiBodHRwczovL2pzb24tc2NoZW1hLm9yZy9kcmFmdC8yMDE5LTA5L2pzb24tc2NoZW1hLWNvcmUuaHRtbCNyZmMuYXBwZW5kaXguQi4yXG4gICAqXG4gICAqIEBwYXJhbSBzY2hlbWEgVGhlIHNjaGVtYSBvciBVUkkgdG8gZmxhdHRlbi5cbiAgICogQHJldHVybnMgQW4gT2JzZXJ2YWJsZSBvZiB0aGUgZmxhdHRlbmVkIHNjaGVtYSBvYmplY3QuXG4gICAqIEBwcml2YXRlIHNpbmNlIDExLjIgd2l0aG91dCByZXBsYWNlbWVudC5cbiAgICovXG4gIGFzeW5jIMm1ZmxhdHRlbihzY2hlbWE6IEpzb25PYmplY3QpOiBQcm9taXNlPEpzb25PYmplY3Q+IHtcbiAgICB0aGlzLl9hanYucmVtb3ZlU2NoZW1hKHNjaGVtYSk7XG4gICAgdGhpcy5fY3VycmVudENvbXBpbGF0aW9uU2NoZW1hSW5mbyA9IHVuZGVmaW5lZDtcbiAgICBjb25zdCB2YWxpZGF0ZSA9IGF3YWl0IHRoaXMuX2Fqdi5jb21waWxlQXN5bmMoc2NoZW1hKTtcblxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdGhpcy1hbGlhc1xuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuXG4gICAgZnVuY3Rpb24gdmlzaXRvcihcbiAgICAgIGN1cnJlbnQ6IEpzb25PYmplY3QgfCBKc29uQXJyYXksXG4gICAgICBwb2ludGVyOiBKc29uUG9pbnRlcixcbiAgICAgIHBhcmVudFNjaGVtYT86IEpzb25PYmplY3QgfCBKc29uQXJyYXksXG4gICAgICBpbmRleD86IHN0cmluZyxcbiAgICApIHtcbiAgICAgIGlmIChcbiAgICAgICAgY3VycmVudCAmJlxuICAgICAgICBwYXJlbnRTY2hlbWEgJiZcbiAgICAgICAgaW5kZXggJiZcbiAgICAgICAgaXNKc29uT2JqZWN0KGN1cnJlbnQpICYmXG4gICAgICAgIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChjdXJyZW50LCAnJHJlZicpICYmXG4gICAgICAgIHR5cGVvZiBjdXJyZW50WyckcmVmJ10gPT0gJ3N0cmluZydcbiAgICAgICkge1xuICAgICAgICBjb25zdCByZXNvbHZlZCA9IHNlbGYuX3Jlc29sdmVyKGN1cnJlbnRbJyRyZWYnXSwgdmFsaWRhdGUpO1xuXG4gICAgICAgIGlmIChyZXNvbHZlZC5zY2hlbWEpIHtcbiAgICAgICAgICAocGFyZW50U2NoZW1hIGFzIEpzb25PYmplY3QpW2luZGV4XSA9IHJlc29sdmVkLnNjaGVtYTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHNjaGVtYUNvcHkgPSBkZWVwQ29weSh2YWxpZGF0ZS5zY2hlbWEgYXMgSnNvbk9iamVjdCk7XG4gICAgdmlzaXRKc29uU2NoZW1hKHNjaGVtYUNvcHksIHZpc2l0b3IpO1xuXG4gICAgcmV0dXJuIHNjaGVtYUNvcHk7XG4gIH1cblxuICAvKipcbiAgICogQ29tcGlsZSBhbmQgcmV0dXJuIGEgdmFsaWRhdGlvbiBmdW5jdGlvbiBmb3IgdGhlIFNjaGVtYS5cbiAgICpcbiAgICogQHBhcmFtIHNjaGVtYSBUaGUgc2NoZW1hIHRvIHZhbGlkYXRlLiBJZiBhIHN0cmluZywgd2lsbCBmZXRjaCB0aGUgc2NoZW1hIGJlZm9yZSBjb21waWxpbmcgaXRcbiAgICogKHVzaW5nIHNjaGVtYSBhcyBhIFVSSSkuXG4gICAqL1xuICBhc3luYyBjb21waWxlKHNjaGVtYTogSnNvblNjaGVtYSk6IFByb21pc2U8U2NoZW1hVmFsaWRhdG9yPiB7XG4gICAgY29uc3QgdmFsaWRhdGUgPSBhd2FpdCB0aGlzLl9jb21waWxlKHNjaGVtYSk7XG5cbiAgICByZXR1cm4gKHZhbHVlLCBvcHRpb25zKSA9PiB2YWxpZGF0ZSh2YWx1ZSwgb3B0aW9ucyk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIF9jb21waWxlKFxuICAgIHNjaGVtYTogSnNvblNjaGVtYSxcbiAgKTogUHJvbWlzZTxcbiAgICAoZGF0YTogSnNvblZhbHVlLCBvcHRpb25zPzogU2NoZW1hVmFsaWRhdG9yT3B0aW9ucykgPT4gUHJvbWlzZTxTY2hlbWFWYWxpZGF0b3JSZXN1bHQ+XG4gID4ge1xuICAgIGlmICh0eXBlb2Ygc2NoZW1hID09PSAnYm9vbGVhbicpIHtcbiAgICAgIHJldHVybiBhc3luYyAoZGF0YSkgPT4gKHsgc3VjY2Vzczogc2NoZW1hLCBkYXRhIH0pO1xuICAgIH1cblxuICAgIGNvbnN0IHNjaGVtYUluZm86IFNjaGVtYUluZm8gPSB7XG4gICAgICBzbWFydERlZmF1bHRSZWNvcmQ6IG5ldyBNYXA8c3RyaW5nLCBKc29uT2JqZWN0PigpLFxuICAgICAgcHJvbXB0RGVmaW5pdGlvbnM6IFtdLFxuICAgIH07XG5cbiAgICB0aGlzLl9hanYucmVtb3ZlU2NoZW1hKHNjaGVtYSk7XG4gICAgbGV0IHZhbGlkYXRvcjogVmFsaWRhdGVGdW5jdGlvbjtcblxuICAgIHRyeSB7XG4gICAgICB0aGlzLl9jdXJyZW50Q29tcGlsYXRpb25TY2hlbWFJbmZvID0gc2NoZW1hSW5mbztcbiAgICAgIHZhbGlkYXRvciA9IHRoaXMuX2Fqdi5jb21waWxlKHNjaGVtYSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgLy8gVGhpcyBzaG91bGQgZXZlbnR1YWxseSBiZSByZWZhY3RvcmVkIHNvIHRoYXQgd2Ugd2UgaGFuZGxlIHJhY2UgY29uZGl0aW9uIHdoZXJlIHRoZSBzYW1lIHNjaGVtYSBpcyB2YWxpZGF0ZWQgYXQgdGhlIHNhbWUgdGltZS5cbiAgICAgIGlmICghKGUgaW5zdGFuY2VvZiBBanYuTWlzc2luZ1JlZkVycm9yKSkge1xuICAgICAgICB0aHJvdyBlO1xuICAgICAgfVxuXG4gICAgICB2YWxpZGF0b3IgPSBhd2FpdCB0aGlzLl9hanYuY29tcGlsZUFzeW5jKHNjaGVtYSk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHRoaXMuX2N1cnJlbnRDb21waWxhdGlvblNjaGVtYUluZm8gPSB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIGFzeW5jIChkYXRhOiBKc29uVmFsdWUsIG9wdGlvbnM/OiBTY2hlbWFWYWxpZGF0b3JPcHRpb25zKSA9PiB7XG4gICAgICBjb25zdCB2YWxpZGF0aW9uT3B0aW9uczogU2NoZW1hVmFsaWRhdG9yT3B0aW9ucyA9IHtcbiAgICAgICAgd2l0aFByb21wdHM6IHRydWUsXG4gICAgICAgIGFwcGx5UG9zdFRyYW5zZm9ybXM6IHRydWUsXG4gICAgICAgIGFwcGx5UHJlVHJhbnNmb3JtczogdHJ1ZSxcbiAgICAgICAgLi4ub3B0aW9ucyxcbiAgICAgIH07XG4gICAgICBjb25zdCB2YWxpZGF0aW9uQ29udGV4dCA9IHtcbiAgICAgICAgcHJvbXB0RmllbGRzV2l0aFZhbHVlOiBuZXcgU2V0PHN0cmluZz4oKSxcbiAgICAgIH07XG5cbiAgICAgIC8vIEFwcGx5IHByZS12YWxpZGF0aW9uIHRyYW5zZm9ybXNcbiAgICAgIGlmICh2YWxpZGF0aW9uT3B0aW9ucy5hcHBseVByZVRyYW5zZm9ybXMpIHtcbiAgICAgICAgZm9yIChjb25zdCB2aXNpdG9yIG9mIHRoaXMuX3ByZS52YWx1ZXMoKSkge1xuICAgICAgICAgIGRhdGEgPSBhd2FpdCBsYXN0VmFsdWVGcm9tKFxuICAgICAgICAgICAgdmlzaXRKc29uKGRhdGEsIHZpc2l0b3IsIHNjaGVtYSwgdGhpcy5fcmVzb2x2ZXIuYmluZCh0aGlzKSwgdmFsaWRhdG9yKSxcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIEFwcGx5IHNtYXJ0IGRlZmF1bHRzXG4gICAgICBhd2FpdCB0aGlzLl9hcHBseVNtYXJ0RGVmYXVsdHMoZGF0YSwgc2NoZW1hSW5mby5zbWFydERlZmF1bHRSZWNvcmQpO1xuXG4gICAgICAvLyBBcHBseSBwcm9tcHRzXG4gICAgICBpZiAodmFsaWRhdGlvbk9wdGlvbnMud2l0aFByb21wdHMpIHtcbiAgICAgICAgY29uc3QgdmlzaXRvcjogSnNvblZpc2l0b3IgPSAodmFsdWUsIHBvaW50ZXIpID0+IHtcbiAgICAgICAgICBpZiAodmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdmFsaWRhdGlvbkNvbnRleHQucHJvbXB0RmllbGRzV2l0aFZhbHVlLmFkZChwb2ludGVyKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH07XG4gICAgICAgIGlmICh0eXBlb2Ygc2NoZW1hID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgIGF3YWl0IGxhc3RWYWx1ZUZyb20oXG4gICAgICAgICAgICB2aXNpdEpzb24oZGF0YSwgdmlzaXRvciwgc2NoZW1hLCB0aGlzLl9yZXNvbHZlci5iaW5kKHRoaXMpLCB2YWxpZGF0b3IpLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBkZWZpbml0aW9ucyA9IHNjaGVtYUluZm8ucHJvbXB0RGVmaW5pdGlvbnMuZmlsdGVyKFxuICAgICAgICAgIChkZWYpID0+ICF2YWxpZGF0aW9uQ29udGV4dC5wcm9tcHRGaWVsZHNXaXRoVmFsdWUuaGFzKGRlZi5pZCksXG4gICAgICAgICk7XG5cbiAgICAgICAgaWYgKGRlZmluaXRpb25zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICBhd2FpdCB0aGlzLl9hcHBseVByb21wdHMoZGF0YSwgZGVmaW5pdGlvbnMpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIFZhbGlkYXRlIHVzaW5nIGFqdlxuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3Qgc3VjY2VzcyA9IGF3YWl0IHZhbGlkYXRvci5jYWxsKHZhbGlkYXRpb25Db250ZXh0LCBkYXRhKTtcblxuICAgICAgICBpZiAoIXN1Y2Nlc3MpIHtcbiAgICAgICAgICByZXR1cm4geyBkYXRhLCBzdWNjZXNzLCBlcnJvcnM6IHZhbGlkYXRvci5lcnJvcnMgPz8gW10gfTtcbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgQWp2LlZhbGlkYXRpb25FcnJvcikge1xuICAgICAgICAgIHJldHVybiB7IGRhdGEsIHN1Y2Nlc3M6IGZhbHNlLCBlcnJvcnM6IGVycm9yLmVycm9ycyB9O1xuICAgICAgICB9XG5cbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9XG5cbiAgICAgIC8vIEFwcGx5IHBvc3QtdmFsaWRhdGlvbiB0cmFuc2Zvcm1zXG4gICAgICBpZiAodmFsaWRhdGlvbk9wdGlvbnMuYXBwbHlQb3N0VHJhbnNmb3Jtcykge1xuICAgICAgICBmb3IgKGNvbnN0IHZpc2l0b3Igb2YgdGhpcy5fcG9zdC52YWx1ZXMoKSkge1xuICAgICAgICAgIGRhdGEgPSBhd2FpdCBsYXN0VmFsdWVGcm9tKFxuICAgICAgICAgICAgdmlzaXRKc29uKGRhdGEsIHZpc2l0b3IsIHNjaGVtYSwgdGhpcy5fcmVzb2x2ZXIuYmluZCh0aGlzKSwgdmFsaWRhdG9yKSxcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB7IGRhdGEsIHN1Y2Nlc3M6IHRydWUgfTtcbiAgICB9O1xuICB9XG5cbiAgYWRkRm9ybWF0KGZvcm1hdDogU2NoZW1hRm9ybWF0KTogdm9pZCB7XG4gICAgdGhpcy5fYWp2LmFkZEZvcm1hdChmb3JtYXQubmFtZSwgZm9ybWF0LmZvcm1hdHRlcik7XG4gIH1cblxuICBhZGRTbWFydERlZmF1bHRQcm92aWRlcjxUPihzb3VyY2U6IHN0cmluZywgcHJvdmlkZXI6IFNtYXJ0RGVmYXVsdFByb3ZpZGVyPFQ+KSB7XG4gICAgaWYgKHRoaXMuX3NvdXJjZU1hcC5oYXMoc291cmNlKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKHNvdXJjZSk7XG4gICAgfVxuXG4gICAgdGhpcy5fc291cmNlTWFwLnNldChzb3VyY2UsIHByb3ZpZGVyIGFzIHVua25vd24gYXMgU21hcnREZWZhdWx0UHJvdmlkZXI8e30+KTtcblxuICAgIGlmICghdGhpcy5fc21hcnREZWZhdWx0S2V5d29yZCkge1xuICAgICAgdGhpcy5fc21hcnREZWZhdWx0S2V5d29yZCA9IHRydWU7XG5cbiAgICAgIHRoaXMuX2Fqdi5hZGRLZXl3b3JkKHtcbiAgICAgICAga2V5d29yZDogJyRkZWZhdWx0JyxcbiAgICAgICAgZXJyb3JzOiBmYWxzZSxcbiAgICAgICAgdmFsaWQ6IHRydWUsXG4gICAgICAgIGNvbXBpbGU6IChzY2hlbWEsIF9wYXJlbnRTY2hlbWEsIGl0KSA9PiB7XG4gICAgICAgICAgY29uc3QgY29tcGlsYXRpb25TY2hlbUluZm8gPSB0aGlzLl9jdXJyZW50Q29tcGlsYXRpb25TY2hlbWFJbmZvO1xuICAgICAgICAgIGlmIChjb21waWxhdGlvblNjaGVtSW5mbyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gKCkgPT4gdHJ1ZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBXZSBjaGVhdCwgaGVhdmlseS5cbiAgICAgICAgICBjb25zdCBwYXRoQXJyYXkgPSB0aGlzLm5vcm1hbGl6ZURhdGFQYXRoQXJyKGl0KTtcbiAgICAgICAgICBjb21waWxhdGlvblNjaGVtSW5mby5zbWFydERlZmF1bHRSZWNvcmQuc2V0KEpTT04uc3RyaW5naWZ5KHBhdGhBcnJheSksIHNjaGVtYSk7XG5cbiAgICAgICAgICByZXR1cm4gKCkgPT4gdHJ1ZTtcbiAgICAgICAgfSxcbiAgICAgICAgbWV0YVNjaGVtYToge1xuICAgICAgICAgIHR5cGU6ICdvYmplY3QnLFxuICAgICAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgICAgICckc291cmNlJzogeyB0eXBlOiAnc3RyaW5nJyB9LFxuICAgICAgICAgIH0sXG4gICAgICAgICAgYWRkaXRpb25hbFByb3BlcnRpZXM6IHRydWUsXG4gICAgICAgICAgcmVxdWlyZWQ6IFsnJHNvdXJjZSddLFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgcmVnaXN0ZXJVcmlIYW5kbGVyKGhhbmRsZXI6IFVyaUhhbmRsZXIpIHtcbiAgICB0aGlzLl91cmlIYW5kbGVycy5hZGQoaGFuZGxlcik7XG4gIH1cblxuICB1c2VQcm9tcHRQcm92aWRlcihwcm92aWRlcjogUHJvbXB0UHJvdmlkZXIpIHtcbiAgICBjb25zdCBpc1NldHVwID0gISF0aGlzLl9wcm9tcHRQcm92aWRlcjtcblxuICAgIHRoaXMuX3Byb21wdFByb3ZpZGVyID0gcHJvdmlkZXI7XG5cbiAgICBpZiAoaXNTZXR1cCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuX2Fqdi5hZGRLZXl3b3JkKHtcbiAgICAgIGtleXdvcmQ6ICd4LXByb21wdCcsXG4gICAgICBlcnJvcnM6IGZhbHNlLFxuICAgICAgdmFsaWQ6IHRydWUsXG4gICAgICBjb21waWxlOiAoc2NoZW1hLCBwYXJlbnRTY2hlbWEsIGl0KSA9PiB7XG4gICAgICAgIGNvbnN0IGNvbXBpbGF0aW9uU2NoZW1JbmZvID0gdGhpcy5fY3VycmVudENvbXBpbGF0aW9uU2NoZW1hSW5mbztcbiAgICAgICAgaWYgKCFjb21waWxhdGlvblNjaGVtSW5mbykge1xuICAgICAgICAgIHJldHVybiAoKSA9PiB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcGF0aCA9ICcvJyArIHRoaXMubm9ybWFsaXplRGF0YVBhdGhBcnIoaXQpLmpvaW4oJy8nKTtcblxuICAgICAgICBsZXQgdHlwZTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgICAgICBsZXQgaXRlbXM6IEFycmF5PHN0cmluZyB8IHsgbGFiZWw6IHN0cmluZzsgdmFsdWU6IHN0cmluZyB8IG51bWJlciB8IGJvb2xlYW4gfT4gfCB1bmRlZmluZWQ7XG4gICAgICAgIGxldCBtZXNzYWdlOiBzdHJpbmc7XG4gICAgICAgIGlmICh0eXBlb2Ygc2NoZW1hID09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgbWVzc2FnZSA9IHNjaGVtYTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBtZXNzYWdlID0gc2NoZW1hLm1lc3NhZ2U7XG4gICAgICAgICAgdHlwZSA9IHNjaGVtYS50eXBlO1xuICAgICAgICAgIGl0ZW1zID0gc2NoZW1hLml0ZW1zO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcHJvcGVydHlUeXBlcyA9IGdldFR5cGVzT2ZTY2hlbWEocGFyZW50U2NoZW1hIGFzIEpzb25PYmplY3QpO1xuICAgICAgICBpZiAoIXR5cGUpIHtcbiAgICAgICAgICBpZiAocHJvcGVydHlUeXBlcy5zaXplID09PSAxICYmIHByb3BlcnR5VHlwZXMuaGFzKCdib29sZWFuJykpIHtcbiAgICAgICAgICAgIHR5cGUgPSAnY29uZmlybWF0aW9uJztcbiAgICAgICAgICB9IGVsc2UgaWYgKEFycmF5LmlzQXJyYXkoKHBhcmVudFNjaGVtYSBhcyBKc29uT2JqZWN0KS5lbnVtKSkge1xuICAgICAgICAgICAgdHlwZSA9ICdsaXN0JztcbiAgICAgICAgICB9IGVsc2UgaWYgKFxuICAgICAgICAgICAgcHJvcGVydHlUeXBlcy5zaXplID09PSAxICYmXG4gICAgICAgICAgICBwcm9wZXJ0eVR5cGVzLmhhcygnYXJyYXknKSAmJlxuICAgICAgICAgICAgKHBhcmVudFNjaGVtYSBhcyBKc29uT2JqZWN0KS5pdGVtcyAmJlxuICAgICAgICAgICAgQXJyYXkuaXNBcnJheSgoKHBhcmVudFNjaGVtYSBhcyBKc29uT2JqZWN0KS5pdGVtcyBhcyBKc29uT2JqZWN0KS5lbnVtKVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgdHlwZSA9ICdsaXN0JztcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdHlwZSA9ICdpbnB1dCc7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgbGV0IG11bHRpc2VsZWN0O1xuICAgICAgICBpZiAodHlwZSA9PT0gJ2xpc3QnKSB7XG4gICAgICAgICAgbXVsdGlzZWxlY3QgPVxuICAgICAgICAgICAgc2NoZW1hLm11bHRpc2VsZWN0ID09PSB1bmRlZmluZWRcbiAgICAgICAgICAgICAgPyBwcm9wZXJ0eVR5cGVzLnNpemUgPT09IDEgJiYgcHJvcGVydHlUeXBlcy5oYXMoJ2FycmF5JylcbiAgICAgICAgICAgICAgOiBzY2hlbWEubXVsdGlzZWxlY3Q7XG5cbiAgICAgICAgICBjb25zdCBlbnVtVmFsdWVzID0gbXVsdGlzZWxlY3RcbiAgICAgICAgICAgID8gKHBhcmVudFNjaGVtYSBhcyBKc29uT2JqZWN0KS5pdGVtcyAmJlxuICAgICAgICAgICAgICAoKHBhcmVudFNjaGVtYSBhcyBKc29uT2JqZWN0KS5pdGVtcyBhcyBKc29uT2JqZWN0KS5lbnVtXG4gICAgICAgICAgICA6IChwYXJlbnRTY2hlbWEgYXMgSnNvbk9iamVjdCkuZW51bTtcbiAgICAgICAgICBpZiAoIWl0ZW1zICYmIEFycmF5LmlzQXJyYXkoZW51bVZhbHVlcykpIHtcbiAgICAgICAgICAgIGl0ZW1zID0gW107XG4gICAgICAgICAgICBmb3IgKGNvbnN0IHZhbHVlIG9mIGVudW1WYWx1ZXMpIHtcbiAgICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgIGl0ZW1zLnB1c2godmFsdWUpO1xuICAgICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiB2YWx1ZSA9PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgICAgIC8vIEludmFsaWRcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpdGVtcy5wdXNoKHsgbGFiZWw6IHZhbHVlLnRvU3RyaW5nKCksIHZhbHVlIH0pO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZGVmaW5pdGlvbjogUHJvbXB0RGVmaW5pdGlvbiA9IHtcbiAgICAgICAgICBpZDogcGF0aCxcbiAgICAgICAgICB0eXBlLFxuICAgICAgICAgIG1lc3NhZ2UsXG4gICAgICAgICAgcmF3OiBzY2hlbWEsXG4gICAgICAgICAgaXRlbXMsXG4gICAgICAgICAgbXVsdGlzZWxlY3QsXG4gICAgICAgICAgcHJvcGVydHlUeXBlcyxcbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgdHlwZW9mIChwYXJlbnRTY2hlbWEgYXMgSnNvbk9iamVjdCkuZGVmYXVsdCA9PSAnb2JqZWN0JyAmJlxuICAgICAgICAgICAgKHBhcmVudFNjaGVtYSBhcyBKc29uT2JqZWN0KS5kZWZhdWx0ICE9PSBudWxsICYmXG4gICAgICAgICAgICAhQXJyYXkuaXNBcnJheSgocGFyZW50U2NoZW1hIGFzIEpzb25PYmplY3QpLmRlZmF1bHQpXG4gICAgICAgICAgICAgID8gdW5kZWZpbmVkXG4gICAgICAgICAgICAgIDogKChwYXJlbnRTY2hlbWEgYXMgSnNvbk9iamVjdCkuZGVmYXVsdCBhcyBzdHJpbmdbXSksXG4gICAgICAgICAgYXN5bmMgdmFsaWRhdG9yKGRhdGE6IEpzb25WYWx1ZSk6IFByb21pc2U8Ym9vbGVhbiB8IHN0cmluZz4ge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgaXQuc2VsZi52YWxpZGF0ZShwYXJlbnRTY2hlbWEsIGRhdGEpO1xuICAgICAgICAgICAgICAvLyBJZiB0aGUgc2NoZW1hIGlzIHN5bmMgdGhlbiBmYWxzZSB3aWxsIGJlIHJldHVybmVkIG9uIHZhbGlkYXRpb24gZmFpbHVyZVxuICAgICAgICAgICAgICBpZiAocmVzdWx0KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdCBhcyBib29sZWFuIHwgc3RyaW5nO1xuICAgICAgICAgICAgICB9IGVsc2UgaWYgKGl0LnNlbGYuZXJyb3JzPy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAvLyBWYWxpZGF0aW9uIGVycm9ycyB3aWxsIGJlIHByZXNlbnQgb24gdGhlIEFqdiBpbnN0YW5jZSB3aGVuIHN5bmNcbiAgICAgICAgICAgICAgICByZXR1cm4gaXQuc2VsZi5lcnJvcnNbMF0ubWVzc2FnZSBhcyBzdHJpbmc7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgY29uc3QgdmFsaWRhdGlvbkVycm9yID0gZSBhcyB7IGVycm9ycz86IEVycm9yW10gfTtcbiAgICAgICAgICAgICAgLy8gSWYgdGhlIHNjaGVtYSBpcyBhc3luYyB0aGVuIGFuIGVycm9yIHdpbGwgYmUgdGhyb3duIG9uIHZhbGlkYXRpb24gZmFpbHVyZVxuICAgICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWxpZGF0aW9uRXJyb3IuZXJyb3JzKSAmJiB2YWxpZGF0aW9uRXJyb3IuZXJyb3JzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB2YWxpZGF0aW9uRXJyb3IuZXJyb3JzWzBdLm1lc3NhZ2U7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgIH0sXG4gICAgICAgIH07XG5cbiAgICAgICAgY29tcGlsYXRpb25TY2hlbUluZm8ucHJvbXB0RGVmaW5pdGlvbnMucHVzaChkZWZpbml0aW9uKTtcblxuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKHRoaXM6IHsgcHJvbXB0RmllbGRzV2l0aFZhbHVlOiBTZXQ8c3RyaW5nPiB9KSB7XG4gICAgICAgICAgLy8gSWYgJ3RoaXMnIGlzIHVuZGVmaW5lZCBpbiB0aGUgY2FsbCwgdGhlbiBpdCBkZWZhdWx0cyB0byB0aGUgZ2xvYmFsXG4gICAgICAgICAgLy8gJ3RoaXMnLlxuICAgICAgICAgIGlmICh0aGlzICYmIHRoaXMucHJvbXB0RmllbGRzV2l0aFZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLnByb21wdEZpZWxkc1dpdGhWYWx1ZS5hZGQocGF0aCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH07XG4gICAgICB9LFxuICAgICAgbWV0YVNjaGVtYToge1xuICAgICAgICBvbmVPZjogW1xuICAgICAgICAgIHsgdHlwZTogJ3N0cmluZycgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICB0eXBlOiAnb2JqZWN0JyxcbiAgICAgICAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgICAgICAgJ3R5cGUnOiB7IHR5cGU6ICdzdHJpbmcnIH0sXG4gICAgICAgICAgICAgICdtZXNzYWdlJzogeyB0eXBlOiAnc3RyaW5nJyB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGFkZGl0aW9uYWxQcm9wZXJ0aWVzOiB0cnVlLFxuICAgICAgICAgICAgcmVxdWlyZWQ6IFsnbWVzc2FnZSddLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9LFxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBfYXBwbHlQcm9tcHRzKGRhdGE6IEpzb25WYWx1ZSwgcHJvbXB0czogQXJyYXk8UHJvbXB0RGVmaW5pdGlvbj4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBwcm92aWRlciA9IHRoaXMuX3Byb21wdFByb3ZpZGVyO1xuICAgIGlmICghcHJvdmlkZXIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBhbnN3ZXJzID0gYXdhaXQgbGFzdFZhbHVlRnJvbShmcm9tKHByb3ZpZGVyKHByb21wdHMpKSk7XG4gICAgZm9yIChjb25zdCBwYXRoIGluIGFuc3dlcnMpIHtcbiAgICAgIGNvbnN0IHBhdGhGcmFnbWVudHMgPSBwYXRoLnNwbGl0KCcvJykuc2xpY2UoMSk7XG5cbiAgICAgIENvcmVTY2hlbWFSZWdpc3RyeS5fc2V0KGRhdGEsIHBhdGhGcmFnbWVudHMsIGFuc3dlcnNbcGF0aF0sIG51bGwsIHVuZGVmaW5lZCwgdHJ1ZSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgX3NldChcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgIGRhdGE6IGFueSxcbiAgICBmcmFnbWVudHM6IHN0cmluZ1tdLFxuICAgIHZhbHVlOiB1bmtub3duLFxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gICAgcGFyZW50OiBhbnkgPSBudWxsLFxuICAgIHBhcmVudFByb3BlcnR5Pzogc3RyaW5nLFxuICAgIGZvcmNlPzogYm9vbGVhbixcbiAgKTogdm9pZCB7XG4gICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IGZyYWdtZW50cy5sZW5ndGg7IGluZGV4KyspIHtcbiAgICAgIGNvbnN0IGZyYWdtZW50ID0gZnJhZ21lbnRzW2luZGV4XTtcbiAgICAgIGlmICgvXmlcXGQrJC8udGVzdChmcmFnbWVudCkpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KGRhdGEpKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgZm9yIChsZXQgZGF0YUluZGV4ID0gMDsgZGF0YUluZGV4IDwgZGF0YS5sZW5ndGg7IGRhdGFJbmRleCsrKSB7XG4gICAgICAgICAgQ29yZVNjaGVtYVJlZ2lzdHJ5Ll9zZXQoXG4gICAgICAgICAgICBkYXRhW2RhdGFJbmRleF0sXG4gICAgICAgICAgICBmcmFnbWVudHMuc2xpY2UoaW5kZXggKyAxKSxcbiAgICAgICAgICAgIHZhbHVlLFxuICAgICAgICAgICAgZGF0YSxcbiAgICAgICAgICAgIGAke2RhdGFJbmRleH1gLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmICghZGF0YSAmJiBwYXJlbnQgIT09IG51bGwgJiYgcGFyZW50UHJvcGVydHkpIHtcbiAgICAgICAgZGF0YSA9IHBhcmVudFtwYXJlbnRQcm9wZXJ0eV0gPSB7fTtcbiAgICAgIH1cblxuICAgICAgcGFyZW50ID0gZGF0YTtcbiAgICAgIHBhcmVudFByb3BlcnR5ID0gZnJhZ21lbnQ7XG4gICAgICBkYXRhID0gZGF0YVtmcmFnbWVudF07XG4gICAgfVxuXG4gICAgaWYgKHBhcmVudCAmJiBwYXJlbnRQcm9wZXJ0eSAmJiAoZm9yY2UgfHwgcGFyZW50W3BhcmVudFByb3BlcnR5XSA9PT0gdW5kZWZpbmVkKSkge1xuICAgICAgcGFyZW50W3BhcmVudFByb3BlcnR5XSA9IHZhbHVlO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgX2FwcGx5U21hcnREZWZhdWx0czxUPihcbiAgICBkYXRhOiBULFxuICAgIHNtYXJ0RGVmYXVsdHM6IE1hcDxzdHJpbmcsIEpzb25PYmplY3Q+LFxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBmb3IgKGNvbnN0IFtwb2ludGVyLCBzY2hlbWFdIG9mIHNtYXJ0RGVmYXVsdHMuZW50cmllcygpKSB7XG4gICAgICBjb25zdCBmcmFnbWVudHMgPSBKU09OLnBhcnNlKHBvaW50ZXIpO1xuICAgICAgY29uc3Qgc291cmNlID0gdGhpcy5fc291cmNlTWFwLmdldChzY2hlbWEuJHNvdXJjZSBhcyBzdHJpbmcpO1xuICAgICAgaWYgKCFzb3VyY2UpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGxldCB2YWx1ZSA9IHNvdXJjZShzY2hlbWEpO1xuICAgICAgaWYgKGlzT2JzZXJ2YWJsZSh2YWx1ZSkpIHtcbiAgICAgICAgdmFsdWUgPSAoYXdhaXQgbGFzdFZhbHVlRnJvbSh2YWx1ZSkpIGFzIHt9O1xuICAgICAgfVxuXG4gICAgICBDb3JlU2NoZW1hUmVnaXN0cnkuX3NldChkYXRhLCBmcmFnbWVudHMsIHZhbHVlKTtcbiAgICB9XG4gIH1cblxuICB1c2VYRGVwcmVjYXRlZFByb3ZpZGVyKG9uVXNhZ2U6IChtZXNzYWdlOiBzdHJpbmcpID0+IHZvaWQpOiB2b2lkIHtcbiAgICB0aGlzLl9hanYuYWRkS2V5d29yZCh7XG4gICAgICBrZXl3b3JkOiAneC1kZXByZWNhdGVkJyxcbiAgICAgIHZhbGlkYXRlOiAoc2NoZW1hLCBfZGF0YSwgX3BhcmVudFNjaGVtYSwgZGF0YUN4dCkgPT4ge1xuICAgICAgICBpZiAoc2NoZW1hKSB7XG4gICAgICAgICAgb25Vc2FnZShcbiAgICAgICAgICAgIGBPcHRpb24gXCIke2RhdGFDeHQ/LnBhcmVudERhdGFQcm9wZXJ0eX1cIiBpcyBkZXByZWNhdGVkJHtcbiAgICAgICAgICAgICAgdHlwZW9mIHNjaGVtYSA9PSAnc3RyaW5nJyA/ICc6ICcgKyBzY2hlbWEgOiAnLidcbiAgICAgICAgICAgIH1gLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH0sXG4gICAgICBlcnJvcnM6IGZhbHNlLFxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBub3JtYWxpemVEYXRhUGF0aEFycihpdDogU2NoZW1hT2JqQ3h0KTogKG51bWJlciB8IHN0cmluZylbXSB7XG4gICAgcmV0dXJuIGl0LmRhdGFQYXRoQXJyXG4gICAgICAuc2xpY2UoMSwgaXQuZGF0YUxldmVsICsgMSlcbiAgICAgIC5tYXAoKHApID0+ICh0eXBlb2YgcCA9PT0gJ251bWJlcicgPyBwIDogcC5zdHIucmVwbGFjZSgvXCIvZywgJycpKSk7XG4gIH1cbn1cbiJdfQ== |
\ | No newline at end of file |