/** * @license * Copyright Google LLC All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ (function (factory) { if (typeof module === "object" && typeof module.exports === "object") { var v = factory(require, exports); if (v !== undefined) module.exports = v; } else if (typeof define === "function" && define.amd) { define("@angular/compiler/src/expression_parser/parser", ["require", "exports", "tslib", "@angular/compiler/src/chars", "@angular/compiler/src/ml_parser/interpolation_config", "@angular/compiler/src/expression_parser/ast", "@angular/compiler/src/expression_parser/lexer"], factory); } })(function (require, exports) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports._ParseAST = exports.IvyParser = exports.Parser = exports.TemplateBindingParseResult = exports.SplitInterpolation = void 0; var tslib_1 = require("tslib"); var chars = require("@angular/compiler/src/chars"); var interpolation_config_1 = require("@angular/compiler/src/ml_parser/interpolation_config"); var ast_1 = require("@angular/compiler/src/expression_parser/ast"); var lexer_1 = require("@angular/compiler/src/expression_parser/lexer"); var SplitInterpolation = /** @class */ (function () { function SplitInterpolation(strings, expressions, offsets) { this.strings = strings; this.expressions = expressions; this.offsets = offsets; } return SplitInterpolation; }()); exports.SplitInterpolation = SplitInterpolation; var TemplateBindingParseResult = /** @class */ (function () { function TemplateBindingParseResult(templateBindings, warnings, errors) { this.templateBindings = templateBindings; this.warnings = warnings; this.errors = errors; } return TemplateBindingParseResult; }()); exports.TemplateBindingParseResult = TemplateBindingParseResult; var Parser = /** @class */ (function () { function Parser(_lexer) { this._lexer = _lexer; this.errors = []; this.simpleExpressionChecker = SimpleExpressionChecker; } Parser.prototype.parseAction = function (input, location, absoluteOffset, interpolationConfig) { if (interpolationConfig === void 0) { interpolationConfig = interpolation_config_1.DEFAULT_INTERPOLATION_CONFIG; } this._checkNoInterpolation(input, location, interpolationConfig); var sourceToLex = this._stripComments(input); var tokens = this._lexer.tokenize(this._stripComments(input)); var ast = new _ParseAST(input, location, absoluteOffset, tokens, sourceToLex.length, true, this.errors, input.length - sourceToLex.length) .parseChain(); return new ast_1.ASTWithSource(ast, input, location, absoluteOffset, this.errors); }; Parser.prototype.parseBinding = function (input, location, absoluteOffset, interpolationConfig) { if (interpolationConfig === void 0) { interpolationConfig = interpolation_config_1.DEFAULT_INTERPOLATION_CONFIG; } var ast = this._parseBindingAst(input, location, absoluteOffset, interpolationConfig); return new ast_1.ASTWithSource(ast, input, location, absoluteOffset, this.errors); }; Parser.prototype.checkSimpleExpression = function (ast) { var checker = new this.simpleExpressionChecker(); ast.visit(checker); return checker.errors; }; Parser.prototype.parseSimpleBinding = function (input, location, absoluteOffset, interpolationConfig) { if (interpolationConfig === void 0) { interpolationConfig = interpolation_config_1.DEFAULT_INTERPOLATION_CONFIG; } var ast = this._parseBindingAst(input, location, absoluteOffset, interpolationConfig); var errors = this.checkSimpleExpression(ast); if (errors.length > 0) { this._reportError("Host binding expression cannot contain " + errors.join(' '), input, location); } return new ast_1.ASTWithSource(ast, input, location, absoluteOffset, this.errors); }; Parser.prototype._reportError = function (message, input, errLocation, ctxLocation) { this.errors.push(new ast_1.ParserError(message, input, errLocation, ctxLocation)); }; Parser.prototype._parseBindingAst = function (input, location, absoluteOffset, interpolationConfig) { // Quotes expressions use 3rd-party expression language. We don't want to use // our lexer or parser for that, so we check for that ahead of time. var quote = this._parseQuote(input, location, absoluteOffset); if (quote != null) { return quote; } this._checkNoInterpolation(input, location, interpolationConfig); var sourceToLex = this._stripComments(input); var tokens = this._lexer.tokenize(sourceToLex); return new _ParseAST(input, location, absoluteOffset, tokens, sourceToLex.length, false, this.errors, input.length - sourceToLex.length) .parseChain(); }; Parser.prototype._parseQuote = function (input, location, absoluteOffset) { if (input == null) return null; var prefixSeparatorIndex = input.indexOf(':'); if (prefixSeparatorIndex == -1) return null; var prefix = input.substring(0, prefixSeparatorIndex).trim(); if (!lexer_1.isIdentifier(prefix)) return null; var uninterpretedExpression = input.substring(prefixSeparatorIndex + 1); var span = new ast_1.ParseSpan(0, input.length); return new ast_1.Quote(span, span.toAbsolute(absoluteOffset), prefix, uninterpretedExpression, location); }; /** * Parse microsyntax template expression and return a list of bindings or * parsing errors in case the given expression is invalid. * * For example, * ``` *
* ^ ^ absoluteValueOffset for `templateValue` * absoluteKeyOffset for `templateKey` * ``` * contains three bindings: * 1. ngFor -> null * 2. item -> NgForOfContext.$implicit * 3. ngForOf -> items * * This is apparent from the de-sugared template: * ``` * * ``` * * @param templateKey name of directive, without the * prefix. For example: ngIf, ngFor * @param templateValue RHS of the microsyntax attribute * @param templateUrl template filename if it's external, component filename if it's inline * @param absoluteKeyOffset start of the `templateKey` * @param absoluteValueOffset start of the `templateValue` */ Parser.prototype.parseTemplateBindings = function (templateKey, templateValue, templateUrl, absoluteKeyOffset, absoluteValueOffset) { var tokens = this._lexer.tokenize(templateValue); var parser = new _ParseAST(templateValue, templateUrl, absoluteValueOffset, tokens, templateValue.length, false /* parseAction */, this.errors, 0 /* relative offset */); return parser.parseTemplateBindings({ source: templateKey, span: new ast_1.AbsoluteSourceSpan(absoluteKeyOffset, absoluteKeyOffset + templateKey.length), }); }; Parser.prototype.parseInterpolation = function (input, location, absoluteOffset, interpolationConfig) { if (interpolationConfig === void 0) { interpolationConfig = interpolation_config_1.DEFAULT_INTERPOLATION_CONFIG; } var _a = this.splitInterpolation(input, location, interpolationConfig), strings = _a.strings, expressions = _a.expressions, offsets = _a.offsets; if (expressions.length === 0) return null; var expressionNodes = []; for (var i = 0; i < expressions.length; ++i) { var expressionText = expressions[i].text; var sourceToLex = this._stripComments(expressionText); var tokens = this._lexer.tokenize(sourceToLex); var ast = new _ParseAST(input, location, absoluteOffset, tokens, sourceToLex.length, false, this.errors, offsets[i] + (expressionText.length - sourceToLex.length)) .parseChain(); expressionNodes.push(ast); } return this.createInterpolationAst(strings.map(function (s) { return s.text; }), expressionNodes, input, location, absoluteOffset); }; /** * Similar to `parseInterpolation`, but treats the provided string as a single expression * element that would normally appear within the interpolation prefix and suffix (`{{` and `}}`). * This is used for parsing the switch expression in ICUs. */ Parser.prototype.parseInterpolationExpression = function (expression, location, absoluteOffset) { var sourceToLex = this._stripComments(expression); var tokens = this._lexer.tokenize(sourceToLex); var ast = new _ParseAST(expression, location, absoluteOffset, tokens, sourceToLex.length, /* parseAction */ false, this.errors, 0) .parseChain(); var strings = ['', '']; // The prefix and suffix strings are both empty return this.createInterpolationAst(strings, [ast], expression, location, absoluteOffset); }; Parser.prototype.createInterpolationAst = function (strings, expressions, input, location, absoluteOffset) { var span = new ast_1.ParseSpan(0, input.length); var interpolation = new ast_1.Interpolation(span, span.toAbsolute(absoluteOffset), strings, expressions); return new ast_1.ASTWithSource(interpolation, input, location, absoluteOffset, this.errors); }; /** * Splits a string of text into "raw" text segments and expressions present in interpolations in * the string. * Returns `null` if there are no interpolations, otherwise a * `SplitInterpolation` with splits that look like * ... */ Parser.prototype.splitInterpolation = function (input, location, interpolationConfig) { if (interpolationConfig === void 0) { interpolationConfig = interpolation_config_1.DEFAULT_INTERPOLATION_CONFIG; } var strings = []; var expressions = []; var offsets = []; var i = 0; var atInterpolation = false; var extendLastString = false; var interpStart = interpolationConfig.start, interpEnd = interpolationConfig.end; while (i < input.length) { if (!atInterpolation) { // parse until starting {{ var start = i; i = input.indexOf(interpStart, i); if (i === -1) { i = input.length; } var text = input.substring(start, i); strings.push({ text: text, start: start, end: i }); atInterpolation = true; } else { // parse from starting {{ to ending }} while ignoring content inside quotes. var fullStart = i; var exprStart = fullStart + interpStart.length; var exprEnd = this._getInterpolationEndIndex(input, interpEnd, exprStart); if (exprEnd === -1) { // Could not find the end of the interpolation; do not parse an expression. // Instead we should extend the content on the last raw string. atInterpolation = false; extendLastString = true; break; } var fullEnd = exprEnd + interpEnd.length; var text = input.substring(exprStart, exprEnd); if (text.trim().length === 0) { this._reportError('Blank expressions are not allowed in interpolated strings', input, "at column " + i + " in", location); } expressions.push({ text: text, start: fullStart, end: fullEnd }); offsets.push(exprStart); i = fullEnd; atInterpolation = false; } } if (!atInterpolation) { // If we are now at a text section, add the remaining content as a raw string. if (extendLastString) { var piece = strings[strings.length - 1]; piece.text += input.substring(i); piece.end = input.length; } else { strings.push({ text: input.substring(i), start: i, end: input.length }); } } return new SplitInterpolation(strings, expressions, offsets); }; Parser.prototype.wrapLiteralPrimitive = function (input, location, absoluteOffset) { var span = new ast_1.ParseSpan(0, input == null ? 0 : input.length); return new ast_1.ASTWithSource(new ast_1.LiteralPrimitive(span, span.toAbsolute(absoluteOffset), input), input, location, absoluteOffset, this.errors); }; Parser.prototype._stripComments = function (input) { var i = this._commentStart(input); return i != null ? input.substring(0, i).trim() : input; }; Parser.prototype._commentStart = function (input) { var outerQuote = null; for (var i = 0; i < input.length - 1; i++) { var char = input.charCodeAt(i); var nextChar = input.charCodeAt(i + 1); if (char === chars.$SLASH && nextChar == chars.$SLASH && outerQuote == null) return i; if (outerQuote === char) { outerQuote = null; } else if (outerQuote == null && chars.isQuote(char)) { outerQuote = char; } } return null; }; Parser.prototype._checkNoInterpolation = function (input, location, _a) { var e_1, _b; var start = _a.start, end = _a.end; var startIndex = -1; var endIndex = -1; try { for (var _c = tslib_1.__values(this._forEachUnquotedChar(input, 0)), _d = _c.next(); !_d.done; _d = _c.next()) { var charIndex = _d.value; if (startIndex === -1) { if (input.startsWith(start)) { startIndex = charIndex; } } else { endIndex = this._getInterpolationEndIndex(input, end, charIndex); if (endIndex > -1) { break; } } } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (_d && !_d.done && (_b = _c.return)) _b.call(_c); } finally { if (e_1) throw e_1.error; } } if (startIndex > -1 && endIndex > -1) { this._reportError("Got interpolation (" + start + end + ") where expression was expected", input, "at column " + startIndex + " in", location); } }; /** * Finds the index of the end of an interpolation expression * while ignoring comments and quoted content. */ Parser.prototype._getInterpolationEndIndex = function (input, expressionEnd, start) { var e_2, _a; try { for (var _b = tslib_1.__values(this._forEachUnquotedChar(input, start)), _c = _b.next(); !_c.done; _c = _b.next()) { var charIndex = _c.value; if (input.startsWith(expressionEnd, charIndex)) { return charIndex; } // Nothing else in the expression matters after we've // hit a comment so look directly for the end token. if (input.startsWith('//', charIndex)) { return input.indexOf(expressionEnd, charIndex); } } } catch (e_2_1) { e_2 = { error: e_2_1 }; } finally { try { if (_c && !_c.done && (_a = _b.return)) _a.call(_b); } finally { if (e_2) throw e_2.error; } } return -1; }; /** * Generator used to iterate over the character indexes of a string that are outside of quotes. * @param input String to loop through. * @param start Index within the string at which to start. */ Parser.prototype._forEachUnquotedChar = function (input, start) { var currentQuote, escapeCount, i, char; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: currentQuote = null; escapeCount = 0; i = start; _a.label = 1; case 1: if (!(i < input.length)) return [3 /*break*/, 6]; char = input[i]; if (!(chars.isQuote(input.charCodeAt(i)) && (currentQuote === null || currentQuote === char) && escapeCount % 2 === 0)) return [3 /*break*/, 2]; currentQuote = currentQuote === null ? char : null; return [3 /*break*/, 4]; case 2: if (!(currentQuote === null)) return [3 /*break*/, 4]; return [4 /*yield*/, i]; case 3: _a.sent(); _a.label = 4; case 4: escapeCount = char === '\\' ? escapeCount + 1 : 0; _a.label = 5; case 5: i++; return [3 /*break*/, 1]; case 6: return [2 /*return*/]; } }); }; return Parser; }()); exports.Parser = Parser; var IvyParser = /** @class */ (function (_super) { tslib_1.__extends(IvyParser, _super); function IvyParser() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.simpleExpressionChecker = IvySimpleExpressionChecker; return _this; } return IvyParser; }(Parser)); exports.IvyParser = IvyParser; /** Describes a stateful context an expression parser is in. */ var ParseContextFlags; (function (ParseContextFlags) { ParseContextFlags[ParseContextFlags["None"] = 0] = "None"; /** * A Writable context is one in which a value may be written to an lvalue. * For example, after we see a property access, we may expect a write to the * property via the "=" operator. * prop * ^ possible "=" after */ ParseContextFlags[ParseContextFlags["Writable"] = 1] = "Writable"; })(ParseContextFlags || (ParseContextFlags = {})); var _ParseAST = /** @class */ (function () { function _ParseAST(input, location, absoluteOffset, tokens, inputLength, parseAction, errors, offset) { this.input = input; this.location = location; this.absoluteOffset = absoluteOffset; this.tokens = tokens; this.inputLength = inputLength; this.parseAction = parseAction; this.errors = errors; this.offset = offset; this.rparensExpected = 0; this.rbracketsExpected = 0; this.rbracesExpected = 0; this.context = ParseContextFlags.None; // Cache of expression start and input indeces to the absolute source span they map to, used to // prevent creating superfluous source spans in `sourceSpan`. // A serial of the expression start and input index is used for mapping because both are stateful // and may change for subsequent expressions visited by the parser. this.sourceSpanCache = new Map(); this.index = 0; } _ParseAST.prototype.peek = function (offset) { var i = this.index + offset; return i < this.tokens.length ? this.tokens[i] : lexer_1.EOF; }; Object.defineProperty(_ParseAST.prototype, "next", { get: function () { return this.peek(0); }, enumerable: false, configurable: true }); Object.defineProperty(_ParseAST.prototype, "atEOF", { /** Whether all the parser input has been processed. */ get: function () { return this.index >= this.tokens.length; }, enumerable: false, configurable: true }); Object.defineProperty(_ParseAST.prototype, "inputIndex", { /** * Index of the next token to be processed, or the end of the last token if all have been * processed. */ get: function () { return this.atEOF ? this.currentEndIndex : this.next.index + this.offset; }, enumerable: false, configurable: true }); Object.defineProperty(_ParseAST.prototype, "currentEndIndex", { /** * End index of the last processed token, or the start of the first token if none have been * processed. */ get: function () { if (this.index > 0) { var curToken = this.peek(-1); return curToken.end + this.offset; } // No tokens have been processed yet; return the next token's start or the length of the input // if there is no token. if (this.tokens.length === 0) { return this.inputLength + this.offset; } return this.next.index + this.offset; }, enumerable: false, configurable: true }); Object.defineProperty(_ParseAST.prototype, "currentAbsoluteOffset", { /** * Returns the absolute offset of the start of the current token. */ get: function () { return this.absoluteOffset + this.inputIndex; }, enumerable: false, configurable: true }); /** * Retrieve a `ParseSpan` from `start` to the current position (or to `artificialEndIndex` if * provided). * * @param start Position from which the `ParseSpan` will start. * @param artificialEndIndex Optional ending index to be used if provided (and if greater than the * natural ending index) */ _ParseAST.prototype.span = function (start, artificialEndIndex) { var endIndex = this.currentEndIndex; if (artificialEndIndex !== undefined && artificialEndIndex > this.currentEndIndex) { endIndex = artificialEndIndex; } // In some unusual parsing scenarios (like when certain tokens are missing and an `EmptyExpr` is // being created), the current token may already be advanced beyond the `currentEndIndex`. This // appears to be a deep-seated parser bug. // // As a workaround for now, swap the start and end indices to ensure a valid `ParseSpan`. // TODO(alxhub): fix the bug upstream in the parser state, and remove this workaround. if (start > endIndex) { var tmp = endIndex; endIndex = start; start = tmp; } return new ast_1.ParseSpan(start, endIndex); }; _ParseAST.prototype.sourceSpan = function (start, artificialEndIndex) { var serial = start + "@" + this.inputIndex + ":" + artificialEndIndex; if (!this.sourceSpanCache.has(serial)) { this.sourceSpanCache.set(serial, this.span(start, artificialEndIndex).toAbsolute(this.absoluteOffset)); } return this.sourceSpanCache.get(serial); }; _ParseAST.prototype.advance = function () { this.index++; }; /** * Executes a callback in the provided context. */ _ParseAST.prototype.withContext = function (context, cb) { this.context |= context; var ret = cb(); this.context ^= context; return ret; }; _ParseAST.prototype.consumeOptionalCharacter = function (code) { if (this.next.isCharacter(code)) { this.advance(); return true; } else { return false; } }; _ParseAST.prototype.peekKeywordLet = function () { return this.next.isKeywordLet(); }; _ParseAST.prototype.peekKeywordAs = function () { return this.next.isKeywordAs(); }; /** * Consumes an expected character, otherwise emits an error about the missing expected character * and skips over the token stream until reaching a recoverable point. * * See `this.error` and `this.skip` for more details. */ _ParseAST.prototype.expectCharacter = function (code) { if (this.consumeOptionalCharacter(code)) return; this.error("Missing expected " + String.fromCharCode(code)); }; _ParseAST.prototype.consumeOptionalOperator = function (op) { if (this.next.isOperator(op)) { this.advance(); return true; } else { return false; } }; _ParseAST.prototype.expectOperator = function (operator) { if (this.consumeOptionalOperator(operator)) return; this.error("Missing expected operator " + operator); }; _ParseAST.prototype.prettyPrintToken = function (tok) { return tok === lexer_1.EOF ? 'end of input' : "token " + tok; }; _ParseAST.prototype.expectIdentifierOrKeyword = function () { var n = this.next; if (!n.isIdentifier() && !n.isKeyword()) { if (n.isPrivateIdentifier()) { this._reportErrorForPrivateIdentifier(n, 'expected identifier or keyword'); } else { this.error("Unexpected " + this.prettyPrintToken(n) + ", expected identifier or keyword"); } return null; } this.advance(); return n.toString(); }; _ParseAST.prototype.expectIdentifierOrKeywordOrString = function () { var n = this.next; if (!n.isIdentifier() && !n.isKeyword() && !n.isString()) { if (n.isPrivateIdentifier()) { this._reportErrorForPrivateIdentifier(n, 'expected identifier, keyword or string'); } else { this.error("Unexpected " + this.prettyPrintToken(n) + ", expected identifier, keyword, or string"); } return ''; } this.advance(); return n.toString(); }; _ParseAST.prototype.parseChain = function () { var exprs = []; var start = this.inputIndex; while (this.index < this.tokens.length) { var expr = this.parsePipe(); exprs.push(expr); if (this.consumeOptionalCharacter(chars.$SEMICOLON)) { if (!this.parseAction) { this.error('Binding expression cannot contain chained expression'); } while (this.consumeOptionalCharacter(chars.$SEMICOLON)) { } // read all semicolons } else if (this.index < this.tokens.length) { this.error("Unexpected token '" + this.next + "'"); } } if (exprs.length == 0) { // We have no expressions so create an empty expression that spans the entire input length var artificialStart = this.offset; var artificialEnd = this.offset + this.inputLength; return new ast_1.EmptyExpr(this.span(artificialStart, artificialEnd), this.sourceSpan(artificialStart, artificialEnd)); } if (exprs.length == 1) return exprs[0]; return new ast_1.Chain(this.span(start), this.sourceSpan(start), exprs); }; _ParseAST.prototype.parsePipe = function () { var start = this.inputIndex; var result = this.parseExpression(); if (this.consumeOptionalOperator('|')) { if (this.parseAction) { this.error('Cannot have a pipe in an action expression'); } do { var nameStart = this.inputIndex; var nameId = this.expectIdentifierOrKeyword(); var nameSpan = void 0; var fullSpanEnd = undefined; if (nameId !== null) { nameSpan = this.sourceSpan(nameStart); } else { // No valid identifier was found, so we'll assume an empty pipe name (''). nameId = ''; // However, there may have been whitespace present between the pipe character and the next // token in the sequence (or the end of input). We want to track this whitespace so that // the `BindingPipe` we produce covers not just the pipe character, but any trailing // whitespace beyond it. Another way of thinking about this is that the zero-length name // is assumed to be at the end of any whitespace beyond the pipe character. // // Therefore, we push the end of the `ParseSpan` for this pipe all the way up to the // beginning of the next token, or until the end of input if the next token is EOF. fullSpanEnd = this.next.index !== -1 ? this.next.index : this.inputLength + this.offset; // The `nameSpan` for an empty pipe name is zero-length at the end of any whitespace // beyond the pipe character. nameSpan = new ast_1.ParseSpan(fullSpanEnd, fullSpanEnd).toAbsolute(this.absoluteOffset); } var args = []; while (this.consumeOptionalCharacter(chars.$COLON)) { args.push(this.parseExpression()); // If there are additional expressions beyond the name, then the artificial end for the // name is no longer relevant. } result = new ast_1.BindingPipe(this.span(start), this.sourceSpan(start, fullSpanEnd), result, nameId, args, nameSpan); } while (this.consumeOptionalOperator('|')); } return result; }; _ParseAST.prototype.parseExpression = function () { return this.parseConditional(); }; _ParseAST.prototype.parseConditional = function () { var start = this.inputIndex; var result = this.parseLogicalOr(); if (this.consumeOptionalOperator('?')) { var yes = this.parsePipe(); var no = void 0; if (!this.consumeOptionalCharacter(chars.$COLON)) { var end = this.inputIndex; var expression = this.input.substring(start, end); this.error("Conditional expression " + expression + " requires all 3 expressions"); no = new ast_1.EmptyExpr(this.span(start), this.sourceSpan(start)); } else { no = this.parsePipe(); } return new ast_1.Conditional(this.span(start), this.sourceSpan(start), result, yes, no); } else { return result; } }; _ParseAST.prototype.parseLogicalOr = function () { // '||' var start = this.inputIndex; var result = this.parseLogicalAnd(); while (this.consumeOptionalOperator('||')) { var right = this.parseLogicalAnd(); result = new ast_1.Binary(this.span(start), this.sourceSpan(start), '||', result, right); } return result; }; _ParseAST.prototype.parseLogicalAnd = function () { // '&&' var start = this.inputIndex; var result = this.parseNullishCoalescing(); while (this.consumeOptionalOperator('&&')) { var right = this.parseNullishCoalescing(); result = new ast_1.Binary(this.span(start), this.sourceSpan(start), '&&', result, right); } return result; }; _ParseAST.prototype.parseNullishCoalescing = function () { // '??' var start = this.inputIndex; var result = this.parseEquality(); while (this.consumeOptionalOperator('??')) { var right = this.parseEquality(); result = new ast_1.Binary(this.span(start), this.sourceSpan(start), '??', result, right); } return result; }; _ParseAST.prototype.parseEquality = function () { // '==','!=','===','!==' var start = this.inputIndex; var result = this.parseRelational(); while (this.next.type == lexer_1.TokenType.Operator) { var operator = this.next.strValue; switch (operator) { case '==': case '===': case '!=': case '!==': this.advance(); var right = this.parseRelational(); result = new ast_1.Binary(this.span(start), this.sourceSpan(start), operator, result, right); continue; } break; } return result; }; _ParseAST.prototype.parseRelational = function () { // '<', '>', '<=', '>=' var start = this.inputIndex; var result = this.parseAdditive(); while (this.next.type == lexer_1.TokenType.Operator) { var operator = this.next.strValue; switch (operator) { case '<': case '>': case '<=': case '>=': this.advance(); var right = this.parseAdditive(); result = new ast_1.Binary(this.span(start), this.sourceSpan(start), operator, result, right); continue; } break; } return result; }; _ParseAST.prototype.parseAdditive = function () { // '+', '-' var start = this.inputIndex; var result = this.parseMultiplicative(); while (this.next.type == lexer_1.TokenType.Operator) { var operator = this.next.strValue; switch (operator) { case '+': case '-': this.advance(); var right = this.parseMultiplicative(); result = new ast_1.Binary(this.span(start), this.sourceSpan(start), operator, result, right); continue; } break; } return result; }; _ParseAST.prototype.parseMultiplicative = function () { // '*', '%', '/' var start = this.inputIndex; var result = this.parsePrefix(); while (this.next.type == lexer_1.TokenType.Operator) { var operator = this.next.strValue; switch (operator) { case '*': case '%': case '/': this.advance(); var right = this.parsePrefix(); result = new ast_1.Binary(this.span(start), this.sourceSpan(start), operator, result, right); continue; } break; } return result; }; _ParseAST.prototype.parsePrefix = function () { if (this.next.type == lexer_1.TokenType.Operator) { var start = this.inputIndex; var operator = this.next.strValue; var result = void 0; switch (operator) { case '+': this.advance(); result = this.parsePrefix(); return ast_1.Unary.createPlus(this.span(start), this.sourceSpan(start), result); case '-': this.advance(); result = this.parsePrefix(); return ast_1.Unary.createMinus(this.span(start), this.sourceSpan(start), result); case '!': this.advance(); result = this.parsePrefix(); return new ast_1.PrefixNot(this.span(start), this.sourceSpan(start), result); } } return this.parseCallChain(); }; _ParseAST.prototype.parseCallChain = function () { var start = this.inputIndex; var result = this.parsePrimary(); while (true) { if (this.consumeOptionalCharacter(chars.$PERIOD)) { result = this.parseAccessMemberOrMethodCall(result, start, false); } else if (this.consumeOptionalOperator('?.')) { result = this.consumeOptionalCharacter(chars.$LBRACKET) ? this.parseKeyedReadOrWrite(result, start, true) : this.parseAccessMemberOrMethodCall(result, start, true); } else if (this.consumeOptionalCharacter(chars.$LBRACKET)) { result = this.parseKeyedReadOrWrite(result, start, false); } else if (this.consumeOptionalCharacter(chars.$LPAREN)) { this.rparensExpected++; var args = this.parseCallArguments(); this.rparensExpected--; this.expectCharacter(chars.$RPAREN); result = new ast_1.FunctionCall(this.span(start), this.sourceSpan(start), result, args); } else if (this.consumeOptionalOperator('!')) { result = new ast_1.NonNullAssert(this.span(start), this.sourceSpan(start), result); } else { return result; } } }; _ParseAST.prototype.parsePrimary = function () { var start = this.inputIndex; if (this.consumeOptionalCharacter(chars.$LPAREN)) { this.rparensExpected++; var result = this.parsePipe(); this.rparensExpected--; this.expectCharacter(chars.$RPAREN); return result; } else if (this.next.isKeywordNull()) { this.advance(); return new ast_1.LiteralPrimitive(this.span(start), this.sourceSpan(start), null); } else if (this.next.isKeywordUndefined()) { this.advance(); return new ast_1.LiteralPrimitive(this.span(start), this.sourceSpan(start), void 0); } else if (this.next.isKeywordTrue()) { this.advance(); return new ast_1.LiteralPrimitive(this.span(start), this.sourceSpan(start), true); } else if (this.next.isKeywordFalse()) { this.advance(); return new ast_1.LiteralPrimitive(this.span(start), this.sourceSpan(start), false); } else if (this.next.isKeywordThis()) { this.advance(); return new ast_1.ThisReceiver(this.span(start), this.sourceSpan(start)); } else if (this.consumeOptionalCharacter(chars.$LBRACKET)) { this.rbracketsExpected++; var elements = this.parseExpressionList(chars.$RBRACKET); this.rbracketsExpected--; this.expectCharacter(chars.$RBRACKET); return new ast_1.LiteralArray(this.span(start), this.sourceSpan(start), elements); } else if (this.next.isCharacter(chars.$LBRACE)) { return this.parseLiteralMap(); } else if (this.next.isIdentifier()) { return this.parseAccessMemberOrMethodCall(new ast_1.ImplicitReceiver(this.span(start), this.sourceSpan(start)), start, false); } else if (this.next.isNumber()) { var value = this.next.toNumber(); this.advance(); return new ast_1.LiteralPrimitive(this.span(start), this.sourceSpan(start), value); } else if (this.next.isString()) { var literalValue = this.next.toString(); this.advance(); return new ast_1.LiteralPrimitive(this.span(start), this.sourceSpan(start), literalValue); } else if (this.next.isPrivateIdentifier()) { this._reportErrorForPrivateIdentifier(this.next, null); return new ast_1.EmptyExpr(this.span(start), this.sourceSpan(start)); } else if (this.index >= this.tokens.length) { this.error("Unexpected end of expression: " + this.input); return new ast_1.EmptyExpr(this.span(start), this.sourceSpan(start)); } else { this.error("Unexpected token " + this.next); return new ast_1.EmptyExpr(this.span(start), this.sourceSpan(start)); } }; _ParseAST.prototype.parseExpressionList = function (terminator) { var result = []; do { if (!this.next.isCharacter(terminator)) { result.push(this.parsePipe()); } else { break; } } while (this.consumeOptionalCharacter(chars.$COMMA)); return result; }; _ParseAST.prototype.parseLiteralMap = function () { var keys = []; var values = []; var start = this.inputIndex; this.expectCharacter(chars.$LBRACE); if (!this.consumeOptionalCharacter(chars.$RBRACE)) { this.rbracesExpected++; do { var keyStart = this.inputIndex; var quoted = this.next.isString(); var key = this.expectIdentifierOrKeywordOrString(); keys.push({ key: key, quoted: quoted }); // Properties with quoted keys can't use the shorthand syntax. if (quoted) { this.expectCharacter(chars.$COLON); values.push(this.parsePipe()); } else if (this.consumeOptionalCharacter(chars.$COLON)) { values.push(this.parsePipe()); } else { var span = this.span(keyStart); var sourceSpan = this.sourceSpan(keyStart); values.push(new ast_1.PropertyRead(span, sourceSpan, sourceSpan, new ast_1.ImplicitReceiver(span, sourceSpan), key)); } } while (this.consumeOptionalCharacter(chars.$COMMA)); this.rbracesExpected--; this.expectCharacter(chars.$RBRACE); } return new ast_1.LiteralMap(this.span(start), this.sourceSpan(start), keys, values); }; _ParseAST.prototype.parseAccessMemberOrMethodCall = function (receiver, start, isSafe) { var _this = this; var nameStart = this.inputIndex; var id = this.withContext(ParseContextFlags.Writable, function () { var _a; var id = (_a = _this.expectIdentifierOrKeyword()) !== null && _a !== void 0 ? _a : ''; if (id.length === 0) { _this.error("Expected identifier for property access", receiver.span.end); } return id; }); var nameSpan = this.sourceSpan(nameStart); if (this.consumeOptionalCharacter(chars.$LPAREN)) { var argumentStart = this.inputIndex; this.rparensExpected++; var args = this.parseCallArguments(); var argumentSpan = this.span(argumentStart, this.inputIndex).toAbsolute(this.absoluteOffset); this.expectCharacter(chars.$RPAREN); this.rparensExpected--; var span = this.span(start); var sourceSpan = this.sourceSpan(start); return isSafe ? new ast_1.SafeMethodCall(span, sourceSpan, nameSpan, receiver, id, args, argumentSpan) : new ast_1.MethodCall(span, sourceSpan, nameSpan, receiver, id, args, argumentSpan); } else { if (isSafe) { if (this.consumeOptionalOperator('=')) { this.error('The \'?.\' operator cannot be used in the assignment'); return new ast_1.EmptyExpr(this.span(start), this.sourceSpan(start)); } else { return new ast_1.SafePropertyRead(this.span(start), this.sourceSpan(start), nameSpan, receiver, id); } } else { if (this.consumeOptionalOperator('=')) { if (!this.parseAction) { this.error('Bindings cannot contain assignments'); return new ast_1.EmptyExpr(this.span(start), this.sourceSpan(start)); } var value = this.parseConditional(); return new ast_1.PropertyWrite(this.span(start), this.sourceSpan(start), nameSpan, receiver, id, value); } else { return new ast_1.PropertyRead(this.span(start), this.sourceSpan(start), nameSpan, receiver, id); } } } }; _ParseAST.prototype.parseCallArguments = function () { if (this.next.isCharacter(chars.$RPAREN)) return []; var positionals = []; do { positionals.push(this.parsePipe()); } while (this.consumeOptionalCharacter(chars.$COMMA)); return positionals; }; /** * Parses an identifier, a keyword, a string with an optional `-` in between, * and returns the string along with its absolute source span. */ _ParseAST.prototype.expectTemplateBindingKey = function () { var result = ''; var operatorFound = false; var start = this.currentAbsoluteOffset; do { result += this.expectIdentifierOrKeywordOrString(); operatorFound = this.consumeOptionalOperator('-'); if (operatorFound) { result += '-'; } } while (operatorFound); return { source: result, span: new ast_1.AbsoluteSourceSpan(start, start + result.length), }; }; /** * Parse microsyntax template expression and return a list of bindings or * parsing errors in case the given expression is invalid. * * For example, * ``` *
* ``` * contains five bindings: * 1. ngFor -> null * 2. item -> NgForOfContext.$implicit * 3. ngForOf -> items * 4. i -> NgForOfContext.index * 5. ngForTrackBy -> func * * For a full description of the microsyntax grammar, see * https://gist.github.com/mhevery/d3530294cff2e4a1b3fe15ff75d08855 * * @param templateKey name of the microsyntax directive, like ngIf, ngFor, * without the *, along with its absolute span. */ _ParseAST.prototype.parseTemplateBindings = function (templateKey) { var bindings = []; // The first binding is for the template key itself // In *ngFor="let item of items", key = "ngFor", value = null // In *ngIf="cond | pipe", key = "ngIf", value = "cond | pipe" bindings.push.apply(bindings, tslib_1.__spreadArray([], tslib_1.__read(this.parseDirectiveKeywordBindings(templateKey)))); while (this.index < this.tokens.length) { // If it starts with 'let', then this must be variable declaration var letBinding = this.parseLetBinding(); if (letBinding) { bindings.push(letBinding); } else { // Two possible cases here, either `value "as" key` or // "directive-keyword expression". We don't know which case, but both // "value" and "directive-keyword" are template binding key, so consume // the key first. var key = this.expectTemplateBindingKey(); // Peek at the next token, if it is "as" then this must be variable // declaration. var binding = this.parseAsBinding(key); if (binding) { bindings.push(binding); } else { // Otherwise the key must be a directive keyword, like "of". Transform // the key to actual key. Eg. of -> ngForOf, trackBy -> ngForTrackBy key.source = templateKey.source + key.source.charAt(0).toUpperCase() + key.source.substring(1); bindings.push.apply(bindings, tslib_1.__spreadArray([], tslib_1.__read(this.parseDirectiveKeywordBindings(key)))); } } this.consumeStatementTerminator(); } return new TemplateBindingParseResult(bindings, [] /* warnings */, this.errors); }; _ParseAST.prototype.parseKeyedReadOrWrite = function (receiver, start, isSafe) { var _this = this; return this.withContext(ParseContextFlags.Writable, function () { _this.rbracketsExpected++; var key = _this.parsePipe(); if (key instanceof ast_1.EmptyExpr) { _this.error("Key access cannot be empty"); } _this.rbracketsExpected--; _this.expectCharacter(chars.$RBRACKET); if (_this.consumeOptionalOperator('=')) { if (isSafe) { _this.error('The \'?.\' operator cannot be used in the assignment'); } else { var value = _this.parseConditional(); return new ast_1.KeyedWrite(_this.span(start), _this.sourceSpan(start), receiver, key, value); } } else { return isSafe ? new ast_1.SafeKeyedRead(_this.span(start), _this.sourceSpan(start), receiver, key) : new ast_1.KeyedRead(_this.span(start), _this.sourceSpan(start), receiver, key); } return new ast_1.EmptyExpr(_this.span(start), _this.sourceSpan(start)); }); }; /** * Parse a directive keyword, followed by a mandatory expression. * For example, "of items", "trackBy: func". * The bindings are: ngForOf -> items, ngForTrackBy -> func * There could be an optional "as" binding that follows the expression. * For example, * ``` * *ngFor="let item of items | slice:0:1 as collection". * ^^ ^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^ * keyword bound target optional 'as' binding * ``` * * @param key binding key, for example, ngFor, ngIf, ngForOf, along with its * absolute span. */ _ParseAST.prototype.parseDirectiveKeywordBindings = function (key) { var bindings = []; this.consumeOptionalCharacter(chars.$COLON); // trackBy: trackByFunction var value = this.getDirectiveBoundTarget(); var spanEnd = this.currentAbsoluteOffset; // The binding could optionally be followed by "as". For example, // *ngIf="cond | pipe as x". In this case, the key in the "as" binding // is "x" and the value is the template key itself ("ngIf"). Note that the // 'key' in the current context now becomes the "value" in the next binding. var asBinding = this.parseAsBinding(key); if (!asBinding) { this.consumeStatementTerminator(); spanEnd = this.currentAbsoluteOffset; } var sourceSpan = new ast_1.AbsoluteSourceSpan(key.span.start, spanEnd); bindings.push(new ast_1.ExpressionBinding(sourceSpan, key, value)); if (asBinding) { bindings.push(asBinding); } return bindings; }; /** * Return the expression AST for the bound target of a directive keyword * binding. For example, * ``` * *ngIf="condition | pipe" * ^^^^^^^^^^^^^^^^ bound target for "ngIf" * *ngFor="let item of items" * ^^^^^ bound target for "ngForOf" * ``` */ _ParseAST.prototype.getDirectiveBoundTarget = function () { if (this.next === lexer_1.EOF || this.peekKeywordAs() || this.peekKeywordLet()) { return null; } var ast = this.parsePipe(); // example: "condition | async" var _a = ast.span, start = _a.start, end = _a.end; var value = this.input.substring(start, end); return new ast_1.ASTWithSource(ast, value, this.location, this.absoluteOffset + start, this.errors); }; /** * Return the binding for a variable declared using `as`. Note that the order * of the key-value pair in this declaration is reversed. For example, * ``` * *ngFor="let item of items; index as i" * ^^^^^ ^ * value key * ``` * * @param value name of the value in the declaration, "ngIf" in the example * above, along with its absolute span. */ _ParseAST.prototype.parseAsBinding = function (value) { if (!this.peekKeywordAs()) { return null; } this.advance(); // consume the 'as' keyword var key = this.expectTemplateBindingKey(); this.consumeStatementTerminator(); var sourceSpan = new ast_1.AbsoluteSourceSpan(value.span.start, this.currentAbsoluteOffset); return new ast_1.VariableBinding(sourceSpan, key, value); }; /** * Return the binding for a variable declared using `let`. For example, * ``` * *ngFor="let item of items; let i=index;" * ^^^^^^^^ ^^^^^^^^^^^ * ``` * In the first binding, `item` is bound to `NgForOfContext.$implicit`. * In the second binding, `i` is bound to `NgForOfContext.index`. */ _ParseAST.prototype.parseLetBinding = function () { if (!this.peekKeywordLet()) { return null; } var spanStart = this.currentAbsoluteOffset; this.advance(); // consume the 'let' keyword var key = this.expectTemplateBindingKey(); var value = null; if (this.consumeOptionalOperator('=')) { value = this.expectTemplateBindingKey(); } this.consumeStatementTerminator(); var sourceSpan = new ast_1.AbsoluteSourceSpan(spanStart, this.currentAbsoluteOffset); return new ast_1.VariableBinding(sourceSpan, key, value); }; /** * Consume the optional statement terminator: semicolon or comma. */ _ParseAST.prototype.consumeStatementTerminator = function () { this.consumeOptionalCharacter(chars.$SEMICOLON) || this.consumeOptionalCharacter(chars.$COMMA); }; /** * Records an error and skips over the token stream until reaching a recoverable point. See * `this.skip` for more details on token skipping. */ _ParseAST.prototype.error = function (message, index) { if (index === void 0) { index = null; } this.errors.push(new ast_1.ParserError(message, this.input, this.locationText(index), this.location)); this.skip(); }; _ParseAST.prototype.locationText = function (index) { if (index === void 0) { index = null; } if (index == null) index = this.index; return (index < this.tokens.length) ? "at column " + (this.tokens[index].index + 1) + " in" : "at the end of the expression"; }; /** * Records an error for an unexpected private identifier being discovered. * @param token Token representing a private identifier. * @param extraMessage Optional additional message being appended to the error. */ _ParseAST.prototype._reportErrorForPrivateIdentifier = function (token, extraMessage) { var errorMessage = "Private identifiers are not supported. Unexpected private identifier: " + token; if (extraMessage !== null) { errorMessage += ", " + extraMessage; } this.error(errorMessage); }; /** * Error recovery should skip tokens until it encounters a recovery point. * * The following are treated as unconditional recovery points: * - end of input * - ';' (parseChain() is always the root production, and it expects a ';') * - '|' (since pipes may be chained and each pipe expression may be treated independently) * * The following are conditional recovery points: * - ')', '}', ']' if one of calling productions is expecting one of these symbols * - This allows skip() to recover from errors such as '(a.) + 1' allowing more of the AST to * be retained (it doesn't skip any tokens as the ')' is retained because of the '(' begins * an '(' ')' production). * The recovery points of grouping symbols must be conditional as they must be skipped if * none of the calling productions are not expecting the closing token else we will never * make progress in the case of an extraneous group closing symbol (such as a stray ')'). * That is, we skip a closing symbol if we are not in a grouping production. * - '=' in a `Writable` context * - In this context, we are able to recover after seeing the `=` operator, which * signals the presence of an independent rvalue expression following the `=` operator. * * If a production expects one of these token it increments the corresponding nesting count, * and then decrements it just prior to checking if the token is in the input. */ _ParseAST.prototype.skip = function () { var n = this.next; while (this.index < this.tokens.length && !n.isCharacter(chars.$SEMICOLON) && !n.isOperator('|') && (this.rparensExpected <= 0 || !n.isCharacter(chars.$RPAREN)) && (this.rbracesExpected <= 0 || !n.isCharacter(chars.$RBRACE)) && (this.rbracketsExpected <= 0 || !n.isCharacter(chars.$RBRACKET)) && (!(this.context & ParseContextFlags.Writable) || !n.isOperator('='))) { if (this.next.isError()) { this.errors.push(new ast_1.ParserError(this.next.toString(), this.input, this.locationText(), this.location)); } this.advance(); n = this.next; } }; return _ParseAST; }()); exports._ParseAST = _ParseAST; var SimpleExpressionChecker = /** @class */ (function () { function SimpleExpressionChecker() { this.errors = []; } SimpleExpressionChecker.prototype.visitImplicitReceiver = function (ast, context) { }; SimpleExpressionChecker.prototype.visitThisReceiver = function (ast, context) { }; SimpleExpressionChecker.prototype.visitInterpolation = function (ast, context) { }; SimpleExpressionChecker.prototype.visitLiteralPrimitive = function (ast, context) { }; SimpleExpressionChecker.prototype.visitPropertyRead = function (ast, context) { }; SimpleExpressionChecker.prototype.visitPropertyWrite = function (ast, context) { }; SimpleExpressionChecker.prototype.visitSafePropertyRead = function (ast, context) { }; SimpleExpressionChecker.prototype.visitMethodCall = function (ast, context) { }; SimpleExpressionChecker.prototype.visitSafeMethodCall = function (ast, context) { }; SimpleExpressionChecker.prototype.visitFunctionCall = function (ast, context) { }; SimpleExpressionChecker.prototype.visitLiteralArray = function (ast, context) { this.visitAll(ast.expressions, context); }; SimpleExpressionChecker.prototype.visitLiteralMap = function (ast, context) { this.visitAll(ast.values, context); }; SimpleExpressionChecker.prototype.visitUnary = function (ast, context) { }; SimpleExpressionChecker.prototype.visitBinary = function (ast, context) { }; SimpleExpressionChecker.prototype.visitPrefixNot = function (ast, context) { }; SimpleExpressionChecker.prototype.visitNonNullAssert = function (ast, context) { }; SimpleExpressionChecker.prototype.visitConditional = function (ast, context) { }; SimpleExpressionChecker.prototype.visitPipe = function (ast, context) { this.errors.push('pipes'); }; SimpleExpressionChecker.prototype.visitKeyedRead = function (ast, context) { }; SimpleExpressionChecker.prototype.visitKeyedWrite = function (ast, context) { }; SimpleExpressionChecker.prototype.visitAll = function (asts, context) { var _this = this; return asts.map(function (node) { return node.visit(_this, context); }); }; SimpleExpressionChecker.prototype.visitChain = function (ast, context) { }; SimpleExpressionChecker.prototype.visitQuote = function (ast, context) { }; SimpleExpressionChecker.prototype.visitSafeKeyedRead = function (ast, context) { }; return SimpleExpressionChecker; }()); /** * This class implements SimpleExpressionChecker used in View Engine and performs more strict checks * to make sure host bindings do not contain pipes. In View Engine, having pipes in host bindings is * not supported as well, but in some cases (like `!(value | async)`) the error is not triggered at * compile time. In order to preserve View Engine behavior, more strict checks are introduced for * Ivy mode only. */ var IvySimpleExpressionChecker = /** @class */ (function (_super) { tslib_1.__extends(IvySimpleExpressionChecker, _super); function IvySimpleExpressionChecker() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.errors = []; return _this; } IvySimpleExpressionChecker.prototype.visitPipe = function () { this.errors.push('pipes'); }; return IvySimpleExpressionChecker; }(ast_1.RecursiveAstVisitor)); }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFyc2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvY29tcGlsZXIvc3JjL2V4cHJlc3Npb25fcGFyc2VyL3BhcnNlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7O0dBTUc7Ozs7Ozs7Ozs7Ozs7O0lBRUgsbURBQWtDO0lBQ2xDLDZGQUFvRztJQUVwRyxtRUFBMmdCO0lBQzNnQix1RUFBbUU7SUFPbkU7UUFDRSw0QkFDVyxPQUE2QixFQUFTLFdBQWlDLEVBQ3ZFLE9BQWlCO1lBRGpCLFlBQU8sR0FBUCxPQUFPLENBQXNCO1lBQVMsZ0JBQVcsR0FBWCxXQUFXLENBQXNCO1lBQ3ZFLFlBQU8sR0FBUCxPQUFPLENBQVU7UUFBRyxDQUFDO1FBQ2xDLHlCQUFDO0lBQUQsQ0FBQyxBQUpELElBSUM7SUFKWSxnREFBa0I7SUFNL0I7UUFDRSxvQ0FDVyxnQkFBbUMsRUFBUyxRQUFrQixFQUM5RCxNQUFxQjtZQURyQixxQkFBZ0IsR0FBaEIsZ0JBQWdCLENBQW1CO1lBQVMsYUFBUSxHQUFSLFFBQVEsQ0FBVTtZQUM5RCxXQUFNLEdBQU4sTUFBTSxDQUFlO1FBQUcsQ0FBQztRQUN0QyxpQ0FBQztJQUFELENBQUMsQUFKRCxJQUlDO0lBSlksZ0VBQTBCO0lBTXZDO1FBR0UsZ0JBQW9CLE1BQWE7WUFBYixXQUFNLEdBQU4sTUFBTSxDQUFPO1lBRnpCLFdBQU0sR0FBa0IsRUFBRSxDQUFDO1lBSW5DLDRCQUF1QixHQUFHLHVCQUF1QixDQUFDO1FBRmQsQ0FBQztRQUlyQyw0QkFBVyxHQUFYLFVBQ0ksS0FBYSxFQUFFLFFBQWdCLEVBQUUsY0FBc0IsRUFDdkQsbUJBQXVFO1lBQXZFLG9DQUFBLEVBQUEsc0JBQTJDLG1EQUE0QjtZQUN6RSxJQUFJLENBQUMscUJBQXFCLENBQUMsS0FBSyxFQUFFLFFBQVEsRUFBRSxtQkFBbUIsQ0FBQyxDQUFDO1lBQ2pFLElBQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDL0MsSUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1lBQ2hFLElBQU0sR0FBRyxHQUFHLElBQUksU0FBUyxDQUNULEtBQUssRUFBRSxRQUFRLEVBQUUsY0FBYyxFQUFFLE1BQU0sRUFBRSxXQUFXLENBQUMsTUFBTSxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsTUFBTSxFQUM5RSxLQUFLLENBQUMsTUFBTSxHQUFHLFdBQVcsQ0FBQyxNQUFNLENBQUM7aUJBQ2pDLFVBQVUsRUFBRSxDQUFDO1lBQzlCLE9BQU8sSUFBSSxtQkFBYSxDQUFDLEdBQUcsRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLGNBQWMsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDOUUsQ0FBQztRQUVELDZCQUFZLEdBQVosVUFDSSxLQUFhLEVBQUUsUUFBZ0IsRUFBRSxjQUFzQixFQUN2RCxtQkFBdUU7WUFBdkUsb0NBQUEsRUFBQSxzQkFBMkMsbURBQTRCO1lBQ3pFLElBQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLLEVBQUUsUUFBUSxFQUFFLGNBQWMsRUFBRSxtQkFBbUIsQ0FBQyxDQUFDO1lBQ3hGLE9BQU8sSUFBSSxtQkFBYSxDQUFDLEdBQUcsRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLGNBQWMsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDOUUsQ0FBQztRQUVPLHNDQUFxQixHQUE3QixVQUE4QixHQUFRO1lBQ3BDLElBQU0sT0FBTyxHQUFHLElBQUksSUFBSSxDQUFDLHVCQUF1QixFQUFFLENBQUM7WUFDbkQsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUNuQixPQUFPLE9BQU8sQ0FBQyxNQUFNLENBQUM7UUFDeEIsQ0FBQztRQUVELG1DQUFrQixHQUFsQixVQUNJLEtBQWEsRUFBRSxRQUFnQixFQUFFLGNBQXNCLEVBQ3ZELG1CQUF1RTtZQUF2RSxvQ0FBQSxFQUFBLHNCQUEyQyxtREFBNEI7WUFDekUsSUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEtBQUssRUFBRSxRQUFRLEVBQUUsY0FBYyxFQUFFLG1CQUFtQixDQUFDLENBQUM7WUFDeEYsSUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLHFCQUFxQixDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQy9DLElBQUksTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7Z0JBQ3JCLElBQUksQ0FBQyxZQUFZLENBQ2IsNENBQTBDLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFHLEVBQUUsS0FBSyxFQUFFLFFBQVEsQ0FBQyxDQUFDO2FBQ3BGO1lBQ0QsT0FBTyxJQUFJLG1CQUFhLENBQUMsR0FBRyxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsY0FBYyxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUM5RSxDQUFDO1FBRU8sNkJBQVksR0FBcEIsVUFBcUIsT0FBZSxFQUFFLEtBQWEsRUFBRSxXQUFtQixFQUFFLFdBQW9CO1lBQzVGLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksaUJBQVcsQ0FBQyxPQUFPLEVBQUUsS0FBSyxFQUFFLFdBQVcsRUFBRSxXQUFXLENBQUMsQ0FBQyxDQUFDO1FBQzlFLENBQUM7UUFFTyxpQ0FBZ0IsR0FBeEIsVUFDSSxLQUFhLEVBQUUsUUFBZ0IsRUFBRSxjQUFzQixFQUN2RCxtQkFBd0M7WUFDMUMsNkVBQTZFO1lBQzdFLG9FQUFvRTtZQUNwRSxJQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssRUFBRSxRQUFRLEVBQUUsY0FBYyxDQUFDLENBQUM7WUFFaEUsSUFBSSxLQUFLLElBQUksSUFBSSxFQUFFO2dCQUNqQixPQUFPLEtBQUssQ0FBQzthQUNkO1lBRUQsSUFBSSxDQUFDLHFCQUFxQixDQUFDLEtBQUssRUFBRSxRQUFRLEVBQUUsbUJBQW1CLENBQUMsQ0FBQztZQUNqRSxJQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQy9DLElBQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1lBQ2pELE9BQU8sSUFBSSxTQUFTLENBQ1QsS0FBSyxFQUFFLFFBQVEsRUFBRSxjQUFjLEVBQUUsTUFBTSxFQUFFLFdBQVcsQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxNQUFNLEVBQy9FLEtBQUssQ0FBQyxNQUFNLEdBQUcsV0FBVyxDQUFDLE1BQU0sQ0FBQztpQkFDeEMsVUFBVSxFQUFFLENBQUM7UUFDcEIsQ0FBQztRQUVPLDRCQUFXLEdBQW5CLFVBQW9CLEtBQWtCLEVBQUUsUUFBZ0IsRUFBRSxjQUFzQjtZQUM5RSxJQUFJLEtBQUssSUFBSSxJQUFJO2dCQUFFLE9BQU8sSUFBSSxDQUFDO1lBQy9CLElBQU0sb0JBQW9CLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUNoRCxJQUFJLG9CQUFvQixJQUFJLENBQUMsQ0FBQztnQkFBRSxPQUFPLElBQUksQ0FBQztZQUM1QyxJQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUMsRUFBRSxvQkFBb0IsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDO1lBQy9ELElBQUksQ0FBQyxvQkFBWSxDQUFDLE1BQU0sQ0FBQztnQkFBRSxPQUFPLElBQUksQ0FBQztZQUN2QyxJQUFNLHVCQUF1QixHQUFHLEtBQUssQ0FBQyxTQUFTLENBQUMsb0JBQW9CLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFDMUUsSUFBTSxJQUFJLEdBQUcsSUFBSSxlQUFTLENBQUMsQ0FBQyxFQUFFLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUM1QyxPQUFPLElBQUksV0FBSyxDQUNaLElBQUksRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLGNBQWMsQ0FBQyxFQUFFLE1BQU0sRUFBRSx1QkFBdUIsRUFBRSxRQUFRLENBQUMsQ0FBQztRQUN4RixDQUFDO1FBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7V0F5Qkc7UUFDSCxzQ0FBcUIsR0FBckIsVUFDSSxXQUFtQixFQUFFLGFBQXFCLEVBQUUsV0FBbUIsRUFBRSxpQkFBeUIsRUFDMUYsbUJBQTJCO1lBQzdCLElBQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1lBQ25ELElBQU0sTUFBTSxHQUFHLElBQUksU0FBUyxDQUN4QixhQUFhLEVBQUUsV0FBVyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sRUFBRSxhQUFhLENBQUMsTUFBTSxFQUM3RSxLQUFLLENBQUMsaUJBQWlCLEVBQUUsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMscUJBQXFCLENBQUMsQ0FBQztZQUNuRSxPQUFPLE1BQU0sQ0FBQyxxQkFBcUIsQ0FBQztnQkFDbEMsTUFBTSxFQUFFLFdBQVc7Z0JBQ25CLElBQUksRUFBRSxJQUFJLHdCQUFrQixDQUFDLGlCQUFpQixFQUFFLGlCQUFpQixHQUFHLFdBQVcsQ0FBQyxNQUFNLENBQUM7YUFDeEYsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztRQUVELG1DQUFrQixHQUFsQixVQUNJLEtBQWEsRUFBRSxRQUFnQixFQUFFLGNBQXNCLEVBQ3ZELG1CQUF1RTtZQUF2RSxvQ0FBQSxFQUFBLHNCQUEyQyxtREFBNEI7WUFDbkUsSUFBQSxLQUNGLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxLQUFLLEVBQUUsUUFBUSxFQUFFLG1CQUFtQixDQUFDLEVBRDFELE9BQU8sYUFBQSxFQUFFLFdBQVcsaUJBQUEsRUFBRSxPQUFPLGFBQzZCLENBQUM7WUFDbEUsSUFBSSxXQUFXLENBQUMsTUFBTSxLQUFLLENBQUM7Z0JBQUUsT0FBTyxJQUFJLENBQUM7WUFFMUMsSUFBTSxlQUFlLEdBQVUsRUFBRSxDQUFDO1lBRWxDLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxXQUFXLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxFQUFFO2dCQUMzQyxJQUFNLGNBQWMsR0FBRyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO2dCQUMzQyxJQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLGNBQWMsQ0FBQyxDQUFDO2dCQUN4RCxJQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMsQ0FBQztnQkFDakQsSUFBTSxHQUFHLEdBQUcsSUFBSSxTQUFTLENBQ1QsS0FBSyxFQUFFLFFBQVEsRUFBRSxjQUFjLEVBQUUsTUFBTSxFQUFFLFdBQVcsQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUNsRSxJQUFJLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLGNBQWMsQ0FBQyxNQUFNLEdBQUcsV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDO3FCQUN0RSxVQUFVLEVBQUUsQ0FBQztnQkFDOUIsZUFBZSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQzthQUMzQjtZQUVELE9BQU8sSUFBSSxDQUFDLHNCQUFzQixDQUM5QixPQUFPLENBQUMsR0FBRyxDQUFDLFVBQUEsQ0FBQyxJQUFJLE9BQUEsQ0FBQyxDQUFDLElBQUksRUFBTixDQUFNLENBQUMsRUFBRSxlQUFlLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxjQUFjLENBQUMsQ0FBQztRQUNsRixDQUFDO1FBRUQ7Ozs7V0FJRztRQUNILDZDQUE0QixHQUE1QixVQUE2QixVQUFrQixFQUFFLFFBQWdCLEVBQUUsY0FBc0I7WUFFdkYsSUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUNwRCxJQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMsQ0FBQztZQUNqRCxJQUFNLEdBQUcsR0FBRyxJQUFJLFNBQVMsQ0FDVCxVQUFVLEVBQUUsUUFBUSxFQUFFLGNBQWMsRUFBRSxNQUFNLEVBQUUsV0FBVyxDQUFDLE1BQU07WUFDaEUsaUJBQWlCLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO2lCQUN2QyxVQUFVLEVBQUUsQ0FBQztZQUM5QixJQUFNLE9BQU8sR0FBRyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFFLCtDQUErQztZQUMxRSxPQUFPLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLGNBQWMsQ0FBQyxDQUFDO1FBQzNGLENBQUM7UUFFTyx1Q0FBc0IsR0FBOUIsVUFDSSxPQUFpQixFQUFFLFdBQWtCLEVBQUUsS0FBYSxFQUFFLFFBQWdCLEVBQ3RFLGNBQXNCO1lBQ3hCLElBQU0sSUFBSSxHQUFHLElBQUksZUFBUyxDQUFDLENBQUMsRUFBRSxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDNUMsSUFBTSxhQUFhLEdBQ2YsSUFBSSxtQkFBYSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLGNBQWMsQ0FBQyxFQUFFLE9BQU8sRUFBRSxXQUFXLENBQUMsQ0FBQztZQUNuRixPQUFPLElBQUksbUJBQWEsQ0FBQyxhQUFhLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxjQUFjLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3hGLENBQUM7UUFFRDs7Ozs7O1dBTUc7UUFDSCxtQ0FBa0IsR0FBbEIsVUFDSSxLQUFhLEVBQUUsUUFBZ0IsRUFDL0IsbUJBQXVFO1lBQXZFLG9DQUFBLEVBQUEsc0JBQTJDLG1EQUE0QjtZQUN6RSxJQUFNLE9BQU8sR0FBeUIsRUFBRSxDQUFDO1lBQ3pDLElBQU0sV0FBVyxHQUF5QixFQUFFLENBQUM7WUFDN0MsSUFBTSxPQUFPLEdBQWEsRUFBRSxDQUFDO1lBQzdCLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUNWLElBQUksZUFBZSxHQUFHLEtBQUssQ0FBQztZQUM1QixJQUFJLGdCQUFnQixHQUFHLEtBQUssQ0FBQztZQUN4QixJQUFPLFdBQVcsR0FBb0IsbUJBQW1CLE1BQXZDLEVBQU8sU0FBUyxHQUFJLG1CQUFtQixJQUF2QixDQUF3QjtZQUMvRCxPQUFPLENBQUMsR0FBRyxLQUFLLENBQUMsTUFBTSxFQUFFO2dCQUN2QixJQUFJLENBQUMsZUFBZSxFQUFFO29CQUNwQiwwQkFBMEI7b0JBQzFCLElBQU0sS0FBSyxHQUFHLENBQUMsQ0FBQztvQkFDaEIsQ0FBQyxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQyxDQUFDO29CQUNsQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRTt3QkFDWixDQUFDLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQztxQkFDbEI7b0JBQ0QsSUFBTSxJQUFJLEdBQUcsS0FBSyxDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUM7b0JBQ3ZDLE9BQU8sQ0FBQyxJQUFJLENBQUMsRUFBQyxJQUFJLE1BQUEsRUFBRSxLQUFLLE9BQUEsRUFBRSxHQUFHLEVBQUUsQ0FBQyxFQUFDLENBQUMsQ0FBQztvQkFFcEMsZUFBZSxHQUFHLElBQUksQ0FBQztpQkFDeEI7cUJBQU07b0JBQ0wsNEVBQTRFO29CQUM1RSxJQUFNLFNBQVMsR0FBRyxDQUFDLENBQUM7b0JBQ3BCLElBQU0sU0FBUyxHQUFHLFNBQVMsR0FBRyxXQUFXLENBQUMsTUFBTSxDQUFDO29CQUNqRCxJQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMseUJBQXlCLENBQUMsS0FBSyxFQUFFLFNBQVMsRUFBRSxTQUFTLENBQUMsQ0FBQztvQkFDNUUsSUFBSSxPQUFPLEtBQUssQ0FBQyxDQUFDLEVBQUU7d0JBQ2xCLDJFQUEyRTt3QkFDM0UsK0RBQStEO3dCQUMvRCxlQUFlLEdBQUcsS0FBSyxDQUFDO3dCQUN4QixnQkFBZ0IsR0FBRyxJQUFJLENBQUM7d0JBQ3hCLE1BQU07cUJBQ1A7b0JBQ0QsSUFBTSxPQUFPLEdBQUcsT0FBTyxHQUFHLFNBQVMsQ0FBQyxNQUFNLENBQUM7b0JBRTNDLElBQU0sSUFBSSxHQUFHLEtBQUssQ0FBQyxTQUFTLENBQUMsU0FBUyxFQUFFLE9BQU8sQ0FBQyxDQUFDO29CQUNqRCxJQUFJLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFO3dCQUM1QixJQUFJLENBQUMsWUFBWSxDQUNiLDJEQUEyRCxFQUFFLEtBQUssRUFDbEUsZUFBYSxDQUFDLFFBQUssRUFBRSxRQUFRLENBQUMsQ0FBQztxQkFDcEM7b0JBQ0QsV0FBVyxDQUFDLElBQUksQ0FBQyxFQUFDLElBQUksTUFBQSxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLE9BQU8sRUFBQyxDQUFDLENBQUM7b0JBQ3pELE9BQU8sQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7b0JBRXhCLENBQUMsR0FBRyxPQUFPLENBQUM7b0JBQ1osZUFBZSxHQUFHLEtBQUssQ0FBQztpQkFDekI7YUFDRjtZQUNELElBQUksQ0FBQyxlQUFlLEVBQUU7Z0JBQ3BCLDhFQUE4RTtnQkFDOUUsSUFBSSxnQkFBZ0IsRUFBRTtvQkFDcEIsSUFBTSxLQUFLLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUM7b0JBQzFDLEtBQUssQ0FBQyxJQUFJLElBQUksS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQztvQkFDakMsS0FBSyxDQUFDLEdBQUcsR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDO2lCQUMxQjtxQkFBTTtvQkFDTCxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsS0FBSyxDQUFDLE1BQU0sRUFBQyxDQUFDLENBQUM7aUJBQ3ZFO2FBQ0Y7WUFDRCxPQUFPLElBQUksa0JBQWtCLENBQUMsT0FBTyxFQUFFLFdBQVcsRUFBRSxPQUFPLENBQUMsQ0FBQztRQUMvRCxDQUFDO1FBRUQscUNBQW9CLEdBQXBCLFVBQXFCLEtBQWtCLEVBQUUsUUFBZ0IsRUFBRSxjQUFzQjtZQUUvRSxJQUFNLElBQUksR0FBRyxJQUFJLGVBQVMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxJQUFJLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDaEUsT0FBTyxJQUFJLG1CQUFhLENBQ3BCLElBQUksc0JBQWdCLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsY0FBYyxDQUFDLEVBQUUsS0FBSyxDQUFDLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFDbkYsY0FBYyxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNuQyxDQUFDO1FBRU8sK0JBQWMsR0FBdEIsVUFBdUIsS0FBYTtZQUNsQyxJQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3BDLE9BQU8sQ0FBQyxJQUFJLElBQUksQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQztRQUMxRCxDQUFDO1FBRU8sOEJBQWEsR0FBckIsVUFBc0IsS0FBYTtZQUNqQyxJQUFJLFVBQVUsR0FBZ0IsSUFBSSxDQUFDO1lBQ25DLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxLQUFLLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRTtnQkFDekMsSUFBTSxJQUFJLEdBQUcsS0FBSyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDakMsSUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLFVBQVUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7Z0JBRXpDLElBQUksSUFBSSxLQUFLLEtBQUssQ0FBQyxNQUFNLElBQUksUUFBUSxJQUFJLEtBQUssQ0FBQyxNQUFNLElBQUksVUFBVSxJQUFJLElBQUk7b0JBQUUsT0FBTyxDQUFDLENBQUM7Z0JBRXRGLElBQUksVUFBVSxLQUFLLElBQUksRUFBRTtvQkFDdkIsVUFBVSxHQUFHLElBQUksQ0FBQztpQkFDbkI7cUJBQU0sSUFBSSxVQUFVLElBQUksSUFBSSxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUU7b0JBQ3BELFVBQVUsR0FBRyxJQUFJLENBQUM7aUJBQ25CO2FBQ0Y7WUFDRCxPQUFPLElBQUksQ0FBQztRQUNkLENBQUM7UUFFTyxzQ0FBcUIsR0FBN0IsVUFBOEIsS0FBYSxFQUFFLFFBQWdCLEVBQUUsRUFBaUM7O2dCQUFoQyxLQUFLLFdBQUEsRUFBRSxHQUFHLFNBQUE7WUFFeEUsSUFBSSxVQUFVLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFDcEIsSUFBSSxRQUFRLEdBQUcsQ0FBQyxDQUFDLENBQUM7O2dCQUVsQixLQUF3QixJQUFBLEtBQUEsaUJBQUEsSUFBSSxDQUFDLG9CQUFvQixDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQSxnQkFBQSw0QkFBRTtvQkFBeEQsSUFBTSxTQUFTLFdBQUE7b0JBQ2xCLElBQUksVUFBVSxLQUFLLENBQUMsQ0FBQyxFQUFFO3dCQUNyQixJQUFJLEtBQUssQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLEVBQUU7NEJBQzNCLFVBQVUsR0FBRyxTQUFTLENBQUM7eUJBQ3hCO3FCQUNGO3lCQUFNO3dCQUNMLFFBQVEsR0FBRyxJQUFJLENBQUMseUJBQXlCLENBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxTQUFTLENBQUMsQ0FBQzt3QkFDakUsSUFBSSxRQUFRLEdBQUcsQ0FBQyxDQUFDLEVBQUU7NEJBQ2pCLE1BQU07eUJBQ1A7cUJBQ0Y7aUJBQ0Y7Ozs7Ozs7OztZQUVELElBQUksVUFBVSxHQUFHLENBQUMsQ0FBQyxJQUFJLFFBQVEsR0FBRyxDQUFDLENBQUMsRUFBRTtnQkFDcEMsSUFBSSxDQUFDLFlBQVksQ0FDYix3QkFBc0IsS0FBSyxHQUFHLEdBQUcsb0NBQWlDLEVBQUUsS0FBSyxFQUN6RSxlQUFhLFVBQVUsUUFBSyxFQUFFLFFBQVEsQ0FBQyxDQUFDO2FBQzdDO1FBQ0gsQ0FBQztRQUVEOzs7V0FHRztRQUNLLDBDQUF5QixHQUFqQyxVQUFrQyxLQUFhLEVBQUUsYUFBcUIsRUFBRSxLQUFhOzs7Z0JBQ25GLEtBQXdCLElBQUEsS0FBQSxpQkFBQSxJQUFJLENBQUMsb0JBQW9CLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFBLGdCQUFBLDRCQUFFO29CQUE1RCxJQUFNLFNBQVMsV0FBQTtvQkFDbEIsSUFBSSxLQUFLLENBQUMsVUFBVSxDQUFDLGFBQWEsRUFBRSxTQUFTLENBQUMsRUFBRTt3QkFDOUMsT0FBTyxTQUFTLENBQUM7cUJBQ2xCO29CQUVELHFEQUFxRDtvQkFDckQsb0RBQW9EO29CQUNwRCxJQUFJLEtBQUssQ0FBQyxVQUFVLENBQUMsSUFBSSxFQUFFLFNBQVMsQ0FBQyxFQUFFO3dCQUNyQyxPQUFPLEtBQUssQ0FBQyxPQUFPLENBQUMsYUFBYSxFQUFFLFNBQVMsQ0FBQyxDQUFDO3FCQUNoRDtpQkFDRjs7Ozs7Ozs7O1lBRUQsT0FBTyxDQUFDLENBQUMsQ0FBQztRQUNaLENBQUM7UUFFRDs7OztXQUlHO1FBQ08scUNBQW9CLEdBQTlCLFVBQStCLEtBQWEsRUFBRSxLQUFhOzs7Ozt3QkFDckQsWUFBWSxHQUFnQixJQUFJLENBQUM7d0JBQ2pDLFdBQVcsR0FBRyxDQUFDLENBQUM7d0JBQ1gsQ0FBQyxHQUFHLEtBQUs7Ozs2QkFBRSxDQUFBLENBQUMsR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFBO3dCQUM1QixJQUFJLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDOzZCQUdsQixDQUFBLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsWUFBWSxLQUFLLElBQUksSUFBSSxZQUFZLEtBQUssSUFBSSxDQUFDOzRCQUN0RixXQUFXLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQSxFQURyQix3QkFDcUI7d0JBQ3ZCLFlBQVksR0FBRyxZQUFZLEtBQUssSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQzs7OzZCQUMxQyxDQUFBLFlBQVksS0FBSyxJQUFJLENBQUEsRUFBckIsd0JBQXFCO3dCQUM5QixxQkFBTSxDQUFDLEVBQUE7O3dCQUFQLFNBQU8sQ0FBQzs7O3dCQUVWLFdBQVcsR0FBRyxJQUFJLEtBQUssSUFBSSxDQUFDLENBQUMsQ0FBQyxXQUFXLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7Ozt3QkFWZCxDQUFDLEVBQUUsQ0FBQTs7Ozs7U0FZMUM7UUFDSCxhQUFDO0lBQUQsQ0FBQyxBQS9VRCxJQStVQztJQS9VWSx3QkFBTTtJQWlWbkI7UUFBK0IscUNBQU07UUFBckM7WUFBQSxxRUFFQztZQURVLDZCQUF1QixHQUFHLDBCQUEwQixDQUFDOztRQUNoRSxDQUFDO1FBQUQsZ0JBQUM7SUFBRCxDQUFDLEFBRkQsQ0FBK0IsTUFBTSxHQUVwQztJQUZZLDhCQUFTO0lBSXRCLCtEQUErRDtJQUMvRCxJQUFLLGlCQVVKO0lBVkQsV0FBSyxpQkFBaUI7UUFDcEIseURBQVEsQ0FBQTtRQUNSOzs7Ozs7V0FNRztRQUNILGlFQUFZLENBQUE7SUFDZCxDQUFDLEVBVkksaUJBQWlCLEtBQWpCLGlCQUFpQixRQVVyQjtJQUVEO1FBY0UsbUJBQ1csS0FBYSxFQUFTLFFBQWdCLEVBQVMsY0FBc0IsRUFDckUsTUFBZSxFQUFTLFdBQW1CLEVBQVMsV0FBb0IsRUFDdkUsTUFBcUIsRUFBVSxNQUFjO1lBRjlDLFVBQUssR0FBTCxLQUFLLENBQVE7WUFBUyxhQUFRLEdBQVIsUUFBUSxDQUFRO1lBQVMsbUJBQWMsR0FBZCxjQUFjLENBQVE7WUFDckUsV0FBTSxHQUFOLE1BQU0sQ0FBUztZQUFTLGdCQUFXLEdBQVgsV0FBVyxDQUFRO1lBQVMsZ0JBQVcsR0FBWCxXQUFXLENBQVM7WUFDdkUsV0FBTSxHQUFOLE1BQU0sQ0FBZTtZQUFVLFdBQU0sR0FBTixNQUFNLENBQVE7WUFoQmpELG9CQUFlLEdBQUcsQ0FBQyxDQUFDO1lBQ3BCLHNCQUFpQixHQUFHLENBQUMsQ0FBQztZQUN0QixvQkFBZSxHQUFHLENBQUMsQ0FBQztZQUNwQixZQUFPLEdBQUcsaUJBQWlCLENBQUMsSUFBSSxDQUFDO1lBRXpDLCtGQUErRjtZQUMvRiw2REFBNkQ7WUFDN0QsaUdBQWlHO1lBQ2pHLG1FQUFtRTtZQUMzRCxvQkFBZSxHQUFHLElBQUksR0FBRyxFQUE4QixDQUFDO1lBRWhFLFVBQUssR0FBVyxDQUFDLENBQUM7UUFLMEMsQ0FBQztRQUU3RCx3QkFBSSxHQUFKLFVBQUssTUFBYztZQUNqQixJQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxHQUFHLE1BQU0sQ0FBQztZQUM5QixPQUFPLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsV0FBRyxDQUFDO1FBQ3ZELENBQUM7UUFFRCxzQkFBSSwyQkFBSTtpQkFBUjtnQkFDRSxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDdEIsQ0FBQzs7O1dBQUE7UUFHRCxzQkFBSSw0QkFBSztZQURULHVEQUF1RDtpQkFDdkQ7Z0JBQ0UsT0FBTyxJQUFJLENBQUMsS0FBSyxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDO1lBQzFDLENBQUM7OztXQUFBO1FBTUQsc0JBQUksaUNBQVU7WUFKZDs7O2VBR0c7aUJBQ0g7Z0JBQ0UsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDO1lBQzNFLENBQUM7OztXQUFBO1FBTUQsc0JBQUksc0NBQWU7WUFKbkI7OztlQUdHO2lCQUNIO2dCQUNFLElBQUksSUFBSSxDQUFDLEtBQUssR0FBRyxDQUFDLEVBQUU7b0JBQ2xCLElBQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztvQkFDL0IsT0FBTyxRQUFRLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUM7aUJBQ25DO2dCQUNELDhGQUE4RjtnQkFDOUYsd0JBQXdCO2dCQUN4QixJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTtvQkFDNUIsT0FBTyxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUM7aUJBQ3ZDO2dCQUNELE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztZQUN2QyxDQUFDOzs7V0FBQTtRQUtELHNCQUFJLDRDQUFxQjtZQUh6Qjs7ZUFFRztpQkFDSDtnQkFDRSxPQUFPLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQztZQUMvQyxDQUFDOzs7V0FBQTtRQUVEOzs7Ozs7O1dBT0c7UUFDSCx3QkFBSSxHQUFKLFVBQUssS0FBYSxFQUFFLGtCQUEyQjtZQUM3QyxJQUFJLFFBQVEsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDO1lBQ3BDLElBQUksa0JBQWtCLEtBQUssU0FBUyxJQUFJLGtCQUFrQixHQUFHLElBQUksQ0FBQyxlQUFlLEVBQUU7Z0JBQ2pGLFFBQVEsR0FBRyxrQkFBa0IsQ0FBQzthQUMvQjtZQUVELGdHQUFnRztZQUNoRywrRkFBK0Y7WUFDL0YsMENBQTBDO1lBQzFDLEVBQUU7WUFDRix5RkFBeUY7WUFDekYsc0ZBQXNGO1lBQ3RGLElBQUksS0FBSyxHQUFHLFFBQVEsRUFBRTtnQkFDcEIsSUFBTSxHQUFHLEdBQUcsUUFBUSxDQUFDO2dCQUNyQixRQUFRLEdBQUcsS0FBSyxDQUFDO2dCQUNqQixLQUFLLEdBQUcsR0FBRyxDQUFDO2FBQ2I7WUFFRCxPQUFPLElBQUksZUFBUyxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUMsQ0FBQztRQUN4QyxDQUFDO1FBRUQsOEJBQVUsR0FBVixVQUFXLEtBQWEsRUFBRSxrQkFBMkI7WUFDbkQsSUFBTSxNQUFNLEdBQU0sS0FBSyxTQUFJLElBQUksQ0FBQyxVQUFVLFNBQUksa0JBQW9CLENBQUM7WUFDbkUsSUFBSSxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxFQUFFO2dCQUNyQyxJQUFJLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FDcEIsTUFBTSxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLGtCQUFrQixDQUFDLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDO2FBQ25GO1lBQ0QsT0FBTyxJQUFJLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUUsQ0FBQztRQUMzQyxDQUFDO1FBRUQsMkJBQU8sR0FBUDtZQUNFLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNmLENBQUM7UUFFRDs7V0FFRztRQUNLLCtCQUFXLEdBQW5CLFVBQXVCLE9BQTBCLEVBQUUsRUFBVztZQUM1RCxJQUFJLENBQUMsT0FBTyxJQUFJLE9BQU8sQ0FBQztZQUN4QixJQUFNLEdBQUcsR0FBRyxFQUFFLEVBQUUsQ0FBQztZQUNqQixJQUFJLENBQUMsT0FBTyxJQUFJLE9BQU8sQ0FBQztZQUN4QixPQUFPLEdBQUcsQ0FBQztRQUNiLENBQUM7UUFFRCw0Q0FBd0IsR0FBeEIsVUFBeUIsSUFBWTtZQUNuQyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxFQUFFO2dCQUMvQixJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7Z0JBQ2YsT0FBTyxJQUFJLENBQUM7YUFDYjtpQkFBTTtnQkFDTCxPQUFPLEtBQUssQ0FBQzthQUNkO1FBQ0gsQ0FBQztRQUVELGtDQUFjLEdBQWQ7WUFDRSxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDbEMsQ0FBQztRQUNELGlDQUFhLEdBQWI7WUFDRSxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDakMsQ0FBQztRQUVEOzs7OztXQUtHO1FBQ0gsbUNBQWUsR0FBZixVQUFnQixJQUFZO1lBQzFCLElBQUksSUFBSSxDQUFDLHdCQUF3QixDQUFDLElBQUksQ0FBQztnQkFBRSxPQUFPO1lBQ2hELElBQUksQ0FBQyxLQUFLLENBQUMsc0JBQW9CLE1BQU0sQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFHLENBQUMsQ0FBQztRQUM5RCxDQUFDO1FBRUQsMkNBQXVCLEdBQXZCLFVBQXdCLEVBQVU7WUFDaEMsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUMsRUFBRTtnQkFDNUIsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO2dCQUNmLE9BQU8sSUFBSSxDQUFDO2FBQ2I7aUJBQU07Z0JBQ0wsT0FBTyxLQUFLLENBQUM7YUFDZDtRQUNILENBQUM7UUFFRCxrQ0FBYyxHQUFkLFVBQWUsUUFBZ0I7WUFDN0IsSUFBSSxJQUFJLENBQUMsdUJBQXVCLENBQUMsUUFBUSxDQUFDO2dCQUFFLE9BQU87WUFDbkQsSUFBSSxDQUFDLEtBQUssQ0FBQywrQkFBNkIsUUFBVSxDQUFDLENBQUM7UUFDdEQsQ0FBQztRQUVELG9DQUFnQixHQUFoQixVQUFpQixHQUFVO1lBQ3pCLE9BQU8sR0FBRyxLQUFLLFdBQUcsQ0FBQyxDQUFDLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQyxXQUFTLEdBQUssQ0FBQztRQUN2RCxDQUFDO1FBRUQsNkNBQXlCLEdBQXpCO1lBQ0UsSUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQztZQUNwQixJQUFJLENBQUMsQ0FBQyxDQUFDLFlBQVksRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLFNBQVMsRUFBRSxFQUFFO2dCQUN2QyxJQUFJLENBQUMsQ0FBQyxtQkFBbUIsRUFBRSxFQUFFO29CQUMzQixJQUFJLENBQUMsZ0NBQWdDLENBQUMsQ0FBQyxFQUFFLGdDQUFnQyxDQUFDLENBQUM7aUJBQzVFO3FCQUFNO29CQUNMLElBQUksQ0FBQyxLQUFLLENBQUMsZ0JBQWMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxxQ0FBa0MsQ0FBQyxDQUFDO2lCQUN0RjtnQkFDRCxPQUFPLElBQUksQ0FBQzthQUNiO1lBQ0QsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ2YsT0FBTyxDQUFDLENBQUMsUUFBUSxFQUFZLENBQUM7UUFDaEMsQ0FBQztRQUVELHFEQUFpQyxHQUFqQztZQUNFLElBQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUM7WUFDcEIsSUFBSSxDQUFDLENBQUMsQ0FBQyxZQUFZLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxRQUFRLEVBQUUsRUFBRTtnQkFDeEQsSUFBSSxDQUFDLENBQUMsbUJBQW1CLEVBQUUsRUFBRTtvQkFDM0IsSUFBSSxDQUFDLGdDQUFnQyxDQUFDLENBQUMsRUFBRSx3Q0FBd0MsQ0FBQyxDQUFDO2lCQUNwRjtxQkFBTTtvQkFDTCxJQUFJLENBQUMsS0FBSyxDQUNOLGdCQUFjLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsOENBQTJDLENBQUMsQ0FBQztpQkFDeEY7Z0JBQ0QsT0FBTyxFQUFFLENBQUM7YUFDWDtZQUNELElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNmLE9BQU8sQ0FBQyxDQUFDLFFBQVEsRUFBWSxDQUFDO1FBQ2hDLENBQUM7UUFFRCw4QkFBVSxHQUFWO1lBQ0UsSUFBTSxLQUFLLEdBQVUsRUFBRSxDQUFDO1lBQ3hCLElBQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUM7WUFDOUIsT0FBTyxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFO2dCQUN0QyxJQUFNLElBQUksR0FBRyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7Z0JBQzlCLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBRWpCLElBQUksSUFBSSxDQUFDLHdCQUF3QixDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsRUFBRTtvQkFDbkQsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUU7d0JBQ3JCLElBQUksQ0FBQyxLQUFLLENBQUMsc0RBQXNELENBQUMsQ0FBQztxQkFDcEU7b0JBQ0QsT0FBTyxJQUFJLENBQUMsd0JBQXdCLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxFQUFFO3FCQUN2RCxDQUFFLHNCQUFzQjtpQkFDMUI7cUJBQU0sSUFBSSxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFO29CQUMxQyxJQUFJLENBQUMsS0FBSyxDQUFDLHVCQUFxQixJQUFJLENBQUMsSUFBSSxNQUFHLENBQUMsQ0FBQztpQkFDL0M7YUFDRjtZQUNELElBQUksS0FBSyxDQUFDLE1BQU0sSUFBSSxDQUFDLEVBQUU7Z0JBQ3JCLDBGQUEwRjtnQkFDMUYsSUFBTSxlQUFlLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztnQkFDcEMsSUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDO2dCQUNyRCxPQUFPLElBQUksZUFBUyxDQUNoQixJQUFJLENBQUMsSUFBSSxDQUFDLGVBQWUsRUFBRSxhQUFhLENBQUMsRUFDekMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxlQUFlLEVBQUUsYUFBYSxDQUFDLENBQUMsQ0FBQzthQUN0RDtZQUNELElBQUksS0FBSyxDQUFDLE1BQU0sSUFBSSxDQUFDO2dCQUFFLE9BQU8sS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3ZDLE9BQU8sSUFBSSxXQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ3BFLENBQUM7UUFFRCw2QkFBUyxHQUFUO1lBQ0UsSUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQztZQUM5QixJQUFJLE1BQU0sR0FBRyxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7WUFDcEMsSUFBSSxJQUFJLENBQUMsdUJBQXVCLENBQUMsR0FBRyxDQUFDLEVBQUU7Z0JBQ3JDLElBQUksSUFBSSxDQUFDLFdBQVcsRUFBRTtvQkFDcEIsSUFBSSxDQUFDLEtBQUssQ0FBQyw0Q0FBNEMsQ0FBQyxDQUFDO2lCQUMxRDtnQkFFRCxHQUFHO29CQUNELElBQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUM7b0JBQ2xDLElBQUksTUFBTSxHQUFHLElBQUksQ0FBQyx5QkFBeUIsRUFBRSxDQUFDO29CQUM5QyxJQUFJLFFBQVEsU0FBb0IsQ0FBQztvQkFDakMsSUFBSSxXQUFXLEdBQXFCLFNBQVMsQ0FBQztvQkFDOUMsSUFBSSxNQUFNLEtBQUssSUFBSSxFQUFFO3dCQUNuQixRQUFRLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMsQ0FBQztxQkFDdkM7eUJBQU07d0JBQ0wsMEVBQTBFO3dCQUMxRSxNQUFNLEdBQUcsRUFBRSxDQUFDO3dCQUVaLDBGQUEwRjt3QkFDMUYsd0ZBQXdGO3dCQUN4RixvRkFBb0Y7d0JBQ3BGLHdGQUF3Rjt3QkFDeEYsMkVBQTJFO3dCQUMzRSxFQUFFO3dCQUNGLG9GQUFvRjt3QkFDcEYsbUZBQW1GO3dCQUNuRixXQUFXLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUM7d0JBRXhGLG9GQUFvRjt3QkFDcEYsNkJBQTZCO3dCQUM3QixRQUFRLEdBQUcsSUFBSSxlQUFTLENBQUMsV0FBVyxFQUFFLFdBQVcsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUM7cUJBQ3BGO29CQUVELElBQU0sSUFBSSxHQUFVLEVBQUUsQ0FBQztvQkFDdkIsT0FBTyxJQUFJLENBQUMsd0JBQXdCLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxFQUFFO3dCQUNsRCxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQyxDQUFDO3dCQUVsQyx1RkFBdUY7d0JBQ3ZGLDhCQUE4QjtxQkFDL0I7b0JBQ0QsTUFBTSxHQUFHLElBQUksaUJBQVcsQ0FDcEIsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssRUFBRSxXQUFXLENBQUMsRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxRQUFRLENBQUMsQ0FBQztpQkFDNUYsUUFBUSxJQUFJLENBQUMsdUJBQXVCLENBQUMsR0FBRyxDQUFDLEVBQUU7YUFDN0M7WUFFRCxPQUFPLE1BQU0sQ0FBQztRQUNoQixDQUFDO1FBRUQsbUNBQWUsR0FBZjtZQUNFLE9BQU8sSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7UUFDakMsQ0FBQztRQUVELG9DQUFnQixHQUFoQjtZQUNFLElBQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUM7WUFDOUIsSUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO1lBRXJDLElBQUksSUFBSSxDQUFDLHVCQUF1QixDQUFDLEdBQUcsQ0FBQyxFQUFFO2dCQUNyQyxJQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7Z0JBQzdCLElBQUksRUFBRSxTQUFLLENBQUM7Z0JBQ1osSUFBSSxDQUFDLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLEVBQUU7b0JBQ2hELElBQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUM7b0JBQzVCLElBQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLEtBQUssRUFBRSxHQUFHLENBQUMsQ0FBQztvQkFDcEQsSUFBSSxDQUFDLEtBQUssQ0FBQyw0QkFBMEIsVUFBVSxnQ0FBNkIsQ0FBQyxDQUFDO29CQUM5RSxFQUFFLEdBQUcsSUFBSSxlQUFTLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7aUJBQzlEO3FCQUFNO29CQUNMLEVBQUUsR0FBRyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7aUJBQ3ZCO2dCQUNELE9BQU8sSUFBSSxpQkFBVyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFLEVBQUUsQ0FBQyxDQUFDO2FBQ25GO2lCQUFNO2dCQUNMLE9BQU8sTUFBTSxDQUFDO2FBQ2Y7UUFDSCxDQUFDO1FBRUQsa0NBQWMsR0FBZDtZQUNFLE9BQU87WUFDUCxJQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDO1lBQzlCLElBQUksTUFBTSxHQUFHLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztZQUNwQyxPQUFPLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxJQUFJLENBQUMsRUFBRTtnQkFDekMsSUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO2dCQUNyQyxNQUFNLEdBQUcsSUFBSSxZQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsS0FBSyxDQUFDLENBQUM7YUFDcEY7WUFDRCxPQUFPLE1BQU0sQ0FBQztRQUNoQixDQUFDO1FBRUQsbUNBQWUsR0FBZjtZQUNFLE9BQU87WUFDUCxJQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDO1lBQzlCLElBQUksTUFBTSxHQUFHLElBQUksQ0FBQyxzQkFBc0IsRUFBRSxDQUFDO1lBQzNDLE9BQU8sSUFBSSxDQUFDLHVCQUF1QixDQUFDLElBQUksQ0FBQyxFQUFFO2dCQUN6QyxJQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsc0JBQXNCLEVBQUUsQ0FBQztnQkFDNUMsTUFBTSxHQUFHLElBQUksWUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLEtBQUssQ0FBQyxDQUFDO2FBQ3BGO1lBQ0QsT0FBTyxNQUFNLENBQUM7UUFDaEIsQ0FBQztRQUVELDBDQUFzQixHQUF0QjtZQUNFLE9BQU87WUFDUCxJQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDO1lBQzlCLElBQUksTUFBTSxHQUFHLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztZQUNsQyxPQUFPLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxJQUFJLENBQUMsRUFBRTtnQkFDekMsSUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO2dCQUNuQyxNQUFNLEdBQUcsSUFBSSxZQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsS0FBSyxDQUFDLENBQUM7YUFDcEY7WUFDRCxPQUFPLE1BQU0sQ0FBQztRQUNoQixDQUFDO1FBRUQsaUNBQWEsR0FBYjtZQUNFLHdCQUF3QjtZQUN4QixJQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDO1lBQzlCLElBQUksTUFBTSxHQUFHLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztZQUNwQyxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxJQUFJLGlCQUFTLENBQUMsUUFBUSxFQUFFO2dCQUMzQyxJQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQztnQkFDcEMsUUFBUSxRQUFRLEVBQUU7b0JBQ2hCLEtBQUssSUFBSSxDQUFDO29CQUNWLEtBQUssS0FBSyxDQUFDO29CQUNYLEtBQUssSUFBSSxDQUFDO29CQUNWLEtBQUssS0FBSzt3QkFDUixJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7d0JBQ2YsSUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO3dCQUNyQyxNQUFNLEdBQUcsSUFBSSxZQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsS0FBSyxDQUFDLENBQUM7d0JBQ3ZGLFNBQVM7aUJBQ1o7Z0JBQ0QsTUFBTTthQUNQO1lBQ0QsT0FBTyxNQUFNLENBQUM7UUFDaEIsQ0FBQztRQUVELG1DQUFlLEdBQWY7WUFDRSx1QkFBdUI7WUFDdkIsSUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQztZQUM5QixJQUFJLE1BQU0sR0FBRyxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7WUFDbEMsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSSxpQkFBUyxDQUFDLFFBQVEsRUFBRTtnQkFDM0MsSUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUM7Z0JBQ3BDLFFBQVEsUUFBUSxFQUFFO29CQUNoQixLQUFLLEdBQUcsQ0FBQztvQkFDVCxLQUFLLEdBQUcsQ0FBQztvQkFDVCxLQUFLLElBQUksQ0FBQztvQkFDVixLQUFLLElBQUk7d0JBQ1AsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO3dCQUNmLElBQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQzt3QkFDbkMsTUFBTSxHQUFHLElBQUksWUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLEtBQUssQ0FBQyxDQUFDO3dCQUN2RixTQUFTO2lCQUNaO2dCQUNELE1BQU07YUFDUDtZQUNELE9BQU8sTUFBTSxDQUFDO1FBQ2hCLENBQUM7UUFFRCxpQ0FBYSxHQUFiO1lBQ0UsV0FBVztZQUNYLElBQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUM7WUFDOUIsSUFBSSxNQUFNLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixFQUFFLENBQUM7WUFDeEMsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSSxpQkFBUyxDQUFDLFFBQVEsRUFBRTtnQkFDM0MsSUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUM7Z0JBQ3BDLFFBQVEsUUFBUSxFQUFFO29CQUNoQixLQUFLLEdBQUcsQ0FBQztvQkFDVCxLQUFLLEdBQUc7d0JBQ04sSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO3dCQUNmLElBQUksS0FBSyxHQUFHLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO3dCQUN2QyxNQUFNLEdBQUcsSUFBSSxZQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsS0FBSyxDQUFDLENBQUM7d0JBQ3ZGLFNBQVM7aUJBQ1o7Z0JBQ0QsTUFBTTthQUNQO1lBQ0QsT0FBTyxNQUFNLENBQUM7UUFDaEIsQ0FBQztRQUVELHVDQUFtQixHQUFuQjtZQUNFLGdCQUFnQjtZQUNoQixJQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDO1lBQzlCLElBQUksTUFBTSxHQUFHLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUNoQyxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxJQUFJLGlCQUFTLENBQUMsUUFBUSxFQUFFO2dCQUMzQyxJQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQztnQkFDcEMsUUFBUSxRQUFRLEVBQUU7b0JBQ2hCLEtBQUssR0FBRyxDQUFDO29CQUNULEtBQUssR0FBRyxDQUFDO29CQUNULEtBQUssR0FBRzt3QkFDTixJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7d0JBQ2YsSUFBSSxLQUFLLEdBQUcsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO3dCQUMvQixNQUFNLEdBQUcsSUFBSSxZQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsS0FBSyxDQUFDLENBQUM7d0JBQ3ZGLFNBQVM7aUJBQ1o7Z0JBQ0QsTUFBTTthQUNQO1lBQ0QsT0FBTyxNQUFNLENBQUM7UUFDaEIsQ0FBQztRQUVELCtCQUFXLEdBQVg7WUFDRSxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxJQUFJLGlCQUFTLENBQUMsUUFBUSxFQUFFO2dCQUN4QyxJQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDO2dCQUM5QixJQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQztnQkFDcEMsSUFBSSxNQUFNLFNBQUssQ0FBQztnQkFDaEIsUUFBUSxRQUFRLEVBQUU7b0JBQ2hCLEtBQUssR0FBRzt3QkFDTixJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7d0JBQ2YsTUFBTSxHQUFHLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQzt3QkFDNUIsT0FBTyxXQUFLLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQztvQkFDNUUsS0FBSyxHQUFHO3dCQUNOLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQzt3QkFDZixNQUFNLEdBQUcsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO3dCQUM1QixPQUFPLFdBQUssQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDO29CQUM3RSxLQUFLLEdBQUc7d0JBQ04sSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO3dCQUNmLE1BQU0sR0FBRyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7d0JBQzVCLE9BQU8sSUFBSSxlQUFTLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDO2lCQUMxRTthQUNGO1lBQ0QsT0FBTyxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7UUFDL0IsQ0FBQztRQUVELGtDQUFjLEdBQWQ7WUFDRSxJQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDO1lBQzlCLElBQUksTUFBTSxHQUFHLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztZQUNqQyxPQUFPLElBQUksRUFBRTtnQkFDWCxJQUFJLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLEVBQUU7b0JBQ2hELE1BQU0sR0FBRyxJQUFJLENBQUMsNkJBQTZCLENBQUMsTUFBTSxFQUFFLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztpQkFFbkU7cUJBQU0sSUFBSSxJQUFJLENBQUMsdUJBQXVCLENBQUMsSUFBSSxDQUFDLEVBQUU7b0JBQzdDLE1BQU0sR0FBRyxJQUFJLENBQUMsd0JBQXdCLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7d0JBQ3JELElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUM7d0JBQ2pELElBQUksQ0FBQyw2QkFBNkIsQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFDO2lCQUM3RDtxQkFBTSxJQUFJLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLEVBQUU7b0JBQ3pELE1BQU0sR0FBRyxJQUFJLENBQUMscUJBQXFCLENBQUMsTUFBTSxFQUFFLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztpQkFDM0Q7cUJBQU0sSUFBSSxJQUFJLENBQUMsd0JBQXdCLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxFQUFFO29CQUN2RCxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7b0JBQ3ZCLElBQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO29CQUN2QyxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7b0JBQ3ZCLElBQUksQ0FBQyxlQUFlLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO29CQUNwQyxNQUFNLEdBQUcsSUFBSSxrQkFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsRUFBRSxNQUFNLEVBQUUsSUFBSSxDQUFDLENBQUM7aUJBRW5GO3FCQUFNLElBQUksSUFBSSxDQUFDLHVCQUF1QixDQUFDLEdBQUcsQ0FBQyxFQUFFO29CQUM1QyxNQUFNLEdBQUcsSUFBSSxtQkFBYSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQztpQkFFOUU7cUJBQU07b0JBQ0wsT0FBTyxNQUFNLENBQUM7aUJBQ2Y7YUFDRjtRQUNILENBQUM7UUFFRCxnQ0FBWSxHQUFaO1lBQ0UsSUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQztZQUM5QixJQUFJLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLEVBQUU7Z0JBQ2hELElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztnQkFDdkIsSUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO2dCQUNoQyxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7Z0JBQ3ZCLElBQUksQ0FBQyxlQUFlLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO2dCQUNwQyxPQUFPLE1BQU0sQ0FBQzthQUVmO2lCQUFNLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLEVBQUUsRUFBRTtnQkFDcEMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO2dCQUNmLE9BQU8sSUFBSSxzQkFBZ0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7YUFFN0U7aUJBQU0sSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLGtCQUFrQixFQUFFLEVBQUU7Z0JBQ3pDLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztnQkFDZixPQUFPLElBQUksc0JBQWdCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUM7YUFFL0U7aUJBQU0sSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsRUFBRSxFQUFFO2dCQUNwQyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7Z0JBQ2YsT0FBTyxJQUFJLHNCQUFnQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQzthQUU3RTtpQkFBTSxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsY0FBYyxFQUFFLEVBQUU7Z0JBQ3JDLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztnQkFDZixPQUFPLElBQUksc0JBQWdCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO2FBRTlFO2lCQUFNLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLEVBQUUsRUFBRTtnQkFDcEMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO2dCQUNmLE9BQU8sSUFBSSxrQkFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO2FBQ25FO2lCQUFNLElBQUksSUFBSSxDQUFDLHdCQUF3QixDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsRUFBRTtnQkFDekQsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7Z0JBQ3pCLElBQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUM7Z0JBQzNELElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO2dCQUN6QixJQUFJLENBQUMsZUFBZSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQztnQkFDdEMsT0FBTyxJQUFJLGtCQUFZLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxFQUFFLFFBQVEsQ0FBQyxDQUFDO2FBRTdFO2lCQUFNLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxFQUFFO2dCQUMvQyxPQUFPLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQzthQUUvQjtpQkFBTSxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLEVBQUU7Z0JBQ25DLE9BQU8sSUFBSSxDQUFDLDZCQUE2QixDQUNyQyxJQUFJLHNCQUFnQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQzthQUVuRjtpQkFBTSxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLEVBQUU7Z0JBQy9CLElBQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7Z0JBQ25DLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztnQkFDZixPQUFPLElBQUksc0JBQWdCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO2FBRTlFO2lCQUFNLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsRUFBRTtnQkFDL0IsSUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztnQkFDMUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO2dCQUNmLE9BQU8sSUFBSSxzQkFBZ0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLEVBQUUsWUFBWSxDQUFDLENBQUM7YUFFckY7aUJBQU0sSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLG1CQUFtQixFQUFFLEVBQUU7Z0JBQzFDLElBQUksQ0FBQyxnQ0FBZ0MsQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO2dCQUN2RCxPQUFPLElBQUksZUFBUyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO2FBRWhFO2lCQUFNLElBQUksSUFBSSxDQUFDLEtBQUssSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRTtnQkFDM0MsSUFBSSxDQUFDLEtBQUssQ0FBQyxtQ0FBaUMsSUFBSSxDQUFDLEtBQU8sQ0FBQyxDQUFDO2dCQUMxRCxPQUFPLElBQUksZUFBUyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO2FBQ2hFO2lCQUFNO2dCQUNMLElBQUksQ0FBQyxLQUFLLENBQUMsc0JBQW9CLElBQUksQ0FBQyxJQUFNLENBQUMsQ0FBQztnQkFDNUMsT0FBTyxJQUFJLGVBQVMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQzthQUNoRTtRQUNILENBQUM7UUFFRCx1Q0FBbUIsR0FBbkIsVUFBb0IsVUFBa0I7WUFDcEMsSUFBTSxNQUFNLEdBQVUsRUFBRSxDQUFDO1lBRXpCLEdBQUc7Z0JBQ0QsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLFVBQVUsQ0FBQyxFQUFFO29CQUN0QyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFDO2lCQUMvQjtxQkFBTTtvQkFDTCxNQUFNO2lCQUNQO2FBQ0YsUUFBUSxJQUFJLENBQUMsd0JBQXdCLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxFQUFFO1lBQ3RELE9BQU8sTUFBTSxDQUFDO1FBQ2hCLENBQUM7UUFFRCxtQ0FBZSxHQUFmO1lBQ0UsSUFBTSxJQUFJLEdBQW9CLEVBQUUsQ0FBQztZQUNqQyxJQUFNLE1BQU0sR0FBVSxFQUFFLENBQUM7WUFDekIsSUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQztZQUM5QixJQUFJLENBQUMsZUFBZSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUNwQyxJQUFJLENBQUMsSUFBSSxDQUFDLHdCQUF3QixDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsRUFBRTtnQkFDakQsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO2dCQUN2QixHQUFHO29CQUNELElBQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUM7b0JBQ2pDLElBQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7b0JBQ3BDLElBQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxpQ0FBaUMsRUFBRSxDQUFDO29CQUNyRCxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUMsR0FBRyxLQUFBLEVBQUUsTUFBTSxRQUFBLEVBQUMsQ0FBQyxDQUFDO29CQUV6Qiw4REFBOEQ7b0JBQzlELElBQUksTUFBTSxFQUFFO3dCQUNWLElBQUksQ0FBQyxlQUFlLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDO3dCQUNuQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFDO3FCQUMvQjt5QkFBTSxJQUFJLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLEVBQUU7d0JBQ3RELE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUM7cUJBQy9CO3lCQUFNO3dCQUNMLElBQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7d0JBQ2pDLElBQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUM7d0JBQzdDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxrQkFBWSxDQUN4QixJQUFJLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxJQUFJLHNCQUFnQixDQUFDLElBQUksRUFBRSxVQUFVLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDO3FCQUNqRjtpQkFDRixRQUFRLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLEVBQUU7Z0JBQ3RELElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztnQkFDdkIsSUFBSSxDQUFDLGVBQWUsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7YUFDckM7WUFDRCxPQUFPLElBQUksZ0JBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLEVBQUUsSUFBSSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQ2hGLENBQUM7UUFFRCxpREFBNkIsR0FBN0IsVUFBOEIsUUFBYSxFQUFFLEtBQWEsRUFBRSxNQUFlO1lBQTNFLGlCQWtEQztZQWpEQyxJQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDO1lBQ2xDLElBQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsaUJBQWlCLENBQUMsUUFBUSxFQUFFOztnQkFDdEQsSUFBTSxFQUFFLEdBQUcsTUFBQSxLQUFJLENBQUMseUJBQXlCLEVBQUUsbUNBQUksRUFBRSxDQUFDO2dCQUNsRCxJQUFJLEVBQUUsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFO29CQUNuQixLQUFJLENBQUMsS0FBSyxDQUFDLHlDQUF5QyxFQUFFLFFBQVEsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7aUJBQzFFO2dCQUNELE9BQU8sRUFBRSxDQUFDO1lBQ1osQ0FBQyxDQUFDLENBQUM7WUFDSCxJQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBRTVDLElBQUksSUFBSSxDQUFDLHdCQUF3QixDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsRUFBRTtnQkFDaEQsSUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQztnQkFDdEMsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO2dCQUN2QixJQUFNLElBQUksR0FBRyxJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztnQkFDdkMsSUFBTSxZQUFZLEdBQ2QsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUM7Z0JBRTlFLElBQUksQ0FBQyxlQUFlLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO2dCQUNwQyxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7Z0JBQ3ZCLElBQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBQzlCLElBQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBQzFDLE9BQU8sTUFBTSxDQUFDLENBQUM7b0JBQ1gsSUFBSSxvQkFBYyxDQUFDLElBQUksRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLFlBQVksQ0FBQyxDQUFDLENBQUM7b0JBQ2xGLElBQUksZ0JBQVUsQ0FBQyxJQUFJLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsRUFBRSxFQUFFLElBQUksRUFBRSxZQUFZLENBQUMsQ0FBQzthQUVsRjtpQkFBTTtnQkFDTCxJQUFJLE1BQU0sRUFBRTtvQkFDVixJQUFJLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxHQUFHLENBQUMsRUFBRTt3QkFDckMsSUFBSSxDQUFDLEtBQUssQ0FBQyxzREFBc0QsQ0FBQyxDQUFDO3dCQUNuRSxPQUFPLElBQUksZUFBUyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO3FCQUNoRTt5QkFBTTt3QkFDTCxPQUFPLElBQUksc0JBQWdCLENBQ3ZCLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLEVBQUUsQ0FBQyxDQUFDO3FCQUN2RTtpQkFDRjtxQkFBTTtvQkFDTCxJQUFJLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxHQUFHLENBQUMsRUFBRTt3QkFDckMsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUU7NEJBQ3JCLElBQUksQ0FBQyxLQUFLLENBQUMscUNBQXFDLENBQUMsQ0FBQzs0QkFDbEQsT0FBTyxJQUFJLGVBQVMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQzt5QkFDaEU7d0JBRUQsSUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7d0JBQ3RDLE9BQU8sSUFBSSxtQkFBYSxDQUNwQixJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxFQUFFLEVBQUUsS0FBSyxDQUFDLENBQUM7cUJBQzlFO3lCQUFNO3dCQUNMLE9BQU8sSUFBSSxrQkFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLEVBQUUsQ0FBQyxDQUFDO3FCQUMzRjtpQkFDRjthQUNGO1FBQ0gsQ0FBQztRQUVELHNDQUFrQixHQUFsQjtZQUNFLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQztnQkFBRSxPQUFPLEVBQUUsQ0FBQztZQUNwRCxJQUFNLFdBQVcsR0FBVSxFQUFFLENBQUM7WUFDOUIsR0FBRztnQkFDRCxXQUFXLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFDO2FBQ3BDLFFBQVEsSUFBSSxDQUFDLHdCQUF3QixDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsRUFBRTtZQUN0RCxPQUFPLFdBQTRCLENBQUM7UUFDdEMsQ0FBQztRQUVEOzs7V0FHRztRQUNILDRDQUF3QixHQUF4QjtZQUNFLElBQUksTUFBTSxHQUFHLEVBQUUsQ0FBQztZQUNoQixJQUFJLGFBQWEsR0FBRyxLQUFLLENBQUM7WUFDMUIsSUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLHFCQUFxQixDQUFDO1lBQ3pDLEdBQUc7Z0JBQ0QsTUFBTSxJQUFJLElBQUksQ0FBQyxpQ0FBaUMsRUFBRSxDQUFDO2dCQUNuRCxhQUFhLEdBQUcsSUFBSSxDQUFDLHVCQUF1QixDQUFDLEdBQUcsQ0FBQyxDQUFDO2dCQUNsRCxJQUFJLGFBQWEsRUFBRTtvQkFDakIsTUFBTSxJQUFJLEdBQUcsQ0FBQztpQkFDZjthQUNGLFFBQVEsYUFBYSxFQUFFO1lBQ3hCLE9BQU87Z0JBQ0wsTUFBTSxFQUFFLE1BQU07Z0JBQ2QsSUFBSSxFQUFFLElBQUksd0JBQWtCLENBQUMsS0FBSyxFQUFFLEtBQUssR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDO2FBQzNELENBQUM7UUFDSixDQUFDO1FBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O1dBb0JHO1FBQ0gseUNBQXFCLEdBQXJCLFVBQXNCLFdBQXNDO1lBQzFELElBQU0sUUFBUSxHQUFzQixFQUFFLENBQUM7WUFFdkMsbURBQW1EO1lBQ25ELDZEQUE2RDtZQUM3RCw4REFBOEQ7WUFDOUQsUUFBUSxDQUFDLElBQUksT0FBYixRQUFRLDJDQUFTLElBQUksQ0FBQyw2QkFBNkIsQ0FBQyxXQUFXLENBQUMsSUFBRTtZQUVsRSxPQUFPLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUU7Z0JBQ3RDLGtFQUFrRTtnQkFDbEUsSUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO2dCQUMxQyxJQUFJLFVBQVUsRUFBRTtvQkFDZCxRQUFRLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO2lCQUMzQjtxQkFBTTtvQkFDTCxzREFBc0Q7b0JBQ3RELHFFQUFxRTtvQkFDckUsdUVBQXVFO29CQUN2RSxpQkFBaUI7b0JBQ2pCLElBQU0sR0FBRyxHQUFHLElBQUksQ0FBQyx3QkFBd0IsRUFBRSxDQUFDO29CQUM1QyxtRUFBbUU7b0JBQ25FLGVBQWU7b0JBQ2YsSUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxHQUFHLENBQUMsQ0FBQztvQkFDekMsSUFBSSxPQUFPLEVBQUU7d0JBQ1gsUUFBUSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztxQkFDeEI7eUJBQU07d0JBQ0wsc0VBQXNFO3dCQUN0RSxvRUFBb0U7d0JBQ3BFLEdBQUcsQ0FBQyxNQUFNOzRCQUNOLFdBQVcsQ0FBQyxNQUFNLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsV0FBVyxFQUFFLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUM7d0JBQ3RGLFFBQVEsQ0FBQyxJQUFJLE9BQWIsUUFBUSwyQ0FBUyxJQUFJLENBQUMsNkJBQTZCLENBQUMsR0FBRyxDQUFDLElBQUU7cUJBQzNEO2lCQUNGO2dCQUNELElBQUksQ0FBQywwQkFBMEIsRUFBRSxDQUFDO2FBQ25DO1lBRUQsT0FBTyxJQUFJLDBCQUEwQixDQUFDLFFBQVEsRUFBRSxFQUFFLENBQUMsY0FBYyxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNsRixDQUFDO1FBRUQseUNBQXFCLEdBQXJCLFVBQXNCLFFBQWEsRUFBRSxLQUFhLEVBQUUsTUFBZTtZQUFuRSxpQkF1QkM7WUF0QkMsT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDLGlCQUFpQixDQUFDLFFBQVEsRUFBRTtnQkFDbEQsS0FBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7Z0JBQ3pCLElBQU0sR0FBRyxHQUFHLEtBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztnQkFDN0IsSUFBSSxHQUFHLFlBQVksZUFBUyxFQUFFO29CQUM1QixLQUFJLENBQUMsS0FBSyxDQUFDLDRCQUE0QixDQUFDLENBQUM7aUJBQzFDO2dCQUNELEtBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO2dCQUN6QixLQUFJLENBQUMsZUFBZSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQztnQkFDdEMsSUFBSSxLQUFJLENBQUMsdUJBQXVCLENBQUMsR0FBRyxDQUFDLEVBQUU7b0JBQ3JDLElBQUksTUFBTSxFQUFFO3dCQUNWLEtBQUksQ0FBQyxLQUFLLENBQUMsc0RBQXNELENBQUMsQ0FBQztxQkFDcEU7eUJBQU07d0JBQ0wsSUFBTSxLQUFLLEdBQUcsS0FBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7d0JBQ3RDLE9BQU8sSUFBSSxnQkFBVSxDQUFDLEtBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsS0FBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsRUFBRSxRQUFRLEVBQUUsR0FBRyxFQUFFLEtBQUssQ0FBQyxDQUFDO3FCQUN2RjtpQkFDRjtxQkFBTTtvQkFDTCxPQUFPLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxtQkFBYSxDQUFDLEtBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsS0FBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsRUFBRSxRQUFRLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQzt3QkFDNUUsSUFBSSxlQUFTLENBQUMsS0FBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxLQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxFQUFFLFFBQVEsRUFBRSxHQUFHLENBQUMsQ0FBQztpQkFDeEY7Z0JBRUQsT0FBTyxJQUFJLGVBQVMsQ0FBQyxLQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLEtBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztZQUNqRSxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUM7UUFFRDs7Ozs7Ozs7Ozs7Ozs7V0FjRztRQUNLLGlEQUE2QixHQUFyQyxVQUFzQyxHQUE4QjtZQUNsRSxJQUFNLFFBQVEsR0FBc0IsRUFBRSxDQUFDO1lBQ3ZDLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBRSwyQkFBMkI7WUFDekUsSUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLHVCQUF1QixFQUFFLENBQUM7WUFDN0MsSUFBSSxPQUFPLEdBQUcsSUFBSSxDQUFDLHFCQUFxQixDQUFDO1lBQ3pDLGlFQUFpRTtZQUNqRSxzRUFBc0U7WUFDdEUsMEVBQTBFO1lBQzFFLDRFQUE0RTtZQUM1RSxJQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQzNDLElBQUksQ0FBQyxTQUFTLEVBQUU7Z0JBQ2QsSUFBSSxDQUFDLDBCQUEwQixFQUFFLENBQUM7Z0JBQ2xDLE9BQU8sR0FBRyxJQUFJLENBQUMscUJBQXFCLENBQUM7YUFDdEM7WUFDRCxJQUFNLFVBQVUsR0FBRyxJQUFJLHdCQUFrQixDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxDQUFDO1lBQ25FLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSx1QkFBaUIsQ0FBQyxVQUFVLEVBQUUsR0FBRyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUM7WUFDN0QsSUFBSSxTQUFTLEVBQUU7Z0JBQ2IsUUFBUSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQzthQUMxQjtZQUNELE9BQU8sUUFBUSxDQUFDO1FBQ2xCLENBQUM7UUFFRDs7Ozs7Ozs7O1dBU0c7UUFDSywyQ0FBdUIsR0FBL0I7WUFDRSxJQUFJLElBQUksQ0FBQyxJQUFJLEtBQUssV0FBRyxJQUFJLElBQUksQ0FBQyxhQUFhLEVBQUUsSUFBSSxJQUFJLENBQUMsY0FBYyxFQUFFLEVBQUU7Z0JBQ3RFLE9BQU8sSUFBSSxDQUFDO2FBQ2I7WUFDRCxJQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBRSwrQkFBK0I7WUFDeEQsSUFBQSxLQUFlLEdBQUcsQ0FBQyxJQUFJLEVBQXRCLEtBQUssV0FBQSxFQUFFLEdBQUcsU0FBWSxDQUFDO1lBQzlCLElBQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLEtBQUssRUFBRSxHQUFHLENBQUMsQ0FBQztZQUMvQyxPQUFPLElBQUksbUJBQWEsQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLGNBQWMsR0FBRyxLQUFLLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ2hHLENBQUM7UUFFRDs7Ozs7Ozs7Ozs7V0FXRztRQUNLLGtDQUFjLEdBQXRCLFVBQXVCLEtBQWdDO1lBQ3JELElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxFQUFFLEVBQUU7Z0JBQ3pCLE9BQU8sSUFBSSxDQUFDO2FBQ2I7WUFDRCxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBRSwyQkFBMkI7WUFDNUMsSUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLHdCQUF3QixFQUFFLENBQUM7WUFDNUMsSUFBSSxDQUFDLDBCQUEwQixFQUFFLENBQUM7WUFDbEMsSUFBTSxVQUFVLEdBQUcsSUFBSSx3QkFBa0IsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMscUJBQXFCLENBQUMsQ0FBQztZQUN4RixPQUFPLElBQUkscUJBQWUsQ0FBQyxVQUFVLEVBQUUsR0FBRyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ3JELENBQUM7UUFFRDs7Ozs7Ozs7V0FRRztRQUNLLG1DQUFlLEdBQXZCO1lBQ0UsSUFBSSxDQUFDLElBQUksQ0FBQyxjQUFjLEVBQUUsRUFBRTtnQkFDMUIsT0FBTyxJQUFJLENBQUM7YUFDYjtZQUNELElBQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxxQkFBcUIsQ0FBQztZQUM3QyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBRSw0QkFBNEI7WUFDN0MsSUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLHdCQUF3QixFQUFFLENBQUM7WUFDNUMsSUFBSSxLQUFLLEdBQW1DLElBQUksQ0FBQztZQUNqRCxJQUFJLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxHQUFHLENBQUMsRUFBRTtnQkFDckMsS0FBSyxHQUFHLElBQUksQ0FBQyx3QkFBd0IsRUFBRSxDQUFDO2FBQ3pDO1lBQ0QsSUFBSSxDQUFDLDBCQUEwQixFQUFFLENBQUM7WUFDbEMsSUFBTSxVQUFVLEdBQUcsSUFBSSx3QkFBa0IsQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLHFCQUFxQixDQUFDLENBQUM7WUFDakYsT0FBTyxJQUFJLHFCQUFlLENBQUMsVUFBVSxFQUFFLEdBQUcsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUNyRCxDQUFDO1FBRUQ7O1dBRUc7UUFDSyw4Q0FBMEIsR0FBbEM7WUFDRSxJQUFJLENBQUMsd0JBQXdCLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxJQUFJLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDakcsQ0FBQztRQUVEOzs7V0FHRztRQUNILHlCQUFLLEdBQUwsVUFBTSxPQUFlLEVBQUUsS0FBeUI7WUFBekIsc0JBQUEsRUFBQSxZQUF5QjtZQUM5QyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLGlCQUFXLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztZQUNoRyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDZCxDQUFDO1FBRU8sZ0NBQVksR0FBcEIsVUFBcUIsS0FBeUI7WUFBekIsc0JBQUEsRUFBQSxZQUF5QjtZQUM1QyxJQUFJLEtBQUssSUFBSSxJQUFJO2dCQUFFLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDO1lBQ3RDLE9BQU8sQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsZ0JBQWEsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxTQUFLLENBQUMsQ0FBQztnQkFDaEQsOEJBQThCLENBQUM7UUFDdkUsQ0FBQztRQUVEOzs7O1dBSUc7UUFDSyxvREFBZ0MsR0FBeEMsVUFBeUMsS0FBWSxFQUFFLFlBQXlCO1lBQzlFLElBQUksWUFBWSxHQUNaLDJFQUF5RSxLQUFPLENBQUM7WUFDckYsSUFBSSxZQUFZLEtBQUssSUFBSSxFQUFFO2dCQUN6QixZQUFZLElBQUksT0FBSyxZQUFjLENBQUM7YUFDckM7WUFDRCxJQUFJLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQzNCLENBQUM7UUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7V0F1Qkc7UUFDSyx3QkFBSSxHQUFaO1lBQ0UsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQztZQUNsQixPQUFPLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLElBQUksQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUM7Z0JBQ25FLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxlQUFlLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7Z0JBQ2xGLENBQUMsSUFBSSxDQUFDLGVBQWUsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztnQkFDNUQsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUM7Z0JBQ2hFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLEdBQUcsaUJBQWlCLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUU7Z0JBQzNFLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsRUFBRTtvQkFDdkIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQ1osSUFBSSxpQkFBVyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFHLEVBQUUsSUFBSSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsWUFBWSxFQUFFLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7aUJBQzdGO2dCQUNELElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztnQkFDZixDQUFDLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQzthQUNmO1FBQ0gsQ0FBQztRQUNILGdCQUFDO0lBQUQsQ0FBQyxBQXA1QkQsSUFvNUJDO0lBcDVCWSw4QkFBUztJQXM1QnRCO1FBQUE7WUFDRSxXQUFNLEdBQWEsRUFBRSxDQUFDO1FBeUR4QixDQUFDO1FBdkRDLHVEQUFxQixHQUFyQixVQUFzQixHQUFxQixFQUFFLE9BQVksSUFBRyxDQUFDO1FBRTdELG1EQUFpQixHQUFqQixVQUFrQixHQUFpQixFQUFFLE9BQVksSUFBRyxDQUFDO1FBRXJELG9EQUFrQixHQUFsQixVQUFtQixHQUFrQixFQUFFLE9BQVksSUFBRyxDQUFDO1FBRXZELHVEQUFxQixHQUFyQixVQUFzQixHQUFxQixFQUFFLE9BQVksSUFBRyxDQUFDO1FBRTdELG1EQUFpQixHQUFqQixVQUFrQixHQUFpQixFQUFFLE9BQVksSUFBRyxDQUFDO1FBRXJELG9EQUFrQixHQUFsQixVQUFtQixHQUFrQixFQUFFLE9BQVksSUFBRyxDQUFDO1FBRXZELHVEQUFxQixHQUFyQixVQUFzQixHQUFxQixFQUFFLE9BQVksSUFBRyxDQUFDO1FBRTdELGlEQUFlLEdBQWYsVUFBZ0IsR0FBZSxFQUFFLE9BQVksSUFBRyxDQUFDO1FBRWpELHFEQUFtQixHQUFuQixVQUFvQixHQUFtQixFQUFFLE9BQVksSUFBRyxDQUFDO1FBRXpELG1EQUFpQixHQUFqQixVQUFrQixHQUFpQixFQUFFLE9BQVksSUFBRyxDQUFDO1FBRXJELG1EQUFpQixHQUFqQixVQUFrQixHQUFpQixFQUFFLE9BQVk7WUFDL0MsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsV0FBVyxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQzFDLENBQUM7UUFFRCxpREFBZSxHQUFmLFVBQWdCLEdBQWUsRUFBRSxPQUFZO1lBQzNDLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBRSxPQUFPLENBQUMsQ0FBQztRQUNyQyxDQUFDO1FBRUQsNENBQVUsR0FBVixVQUFXLEdBQVUsRUFBRSxPQUFZLElBQUcsQ0FBQztRQUV2Qyw2Q0FBVyxHQUFYLFVBQVksR0FBVyxFQUFFLE9BQVksSUFBRyxDQUFDO1FBRXpDLGdEQUFjLEdBQWQsVUFBZSxHQUFjLEVBQUUsT0FBWSxJQUFHLENBQUM7UUFFL0Msb0RBQWtCLEdBQWxCLFVBQW1CLEdBQWtCLEVBQUUsT0FBWSxJQUFHLENBQUM7UUFFdkQsa0RBQWdCLEdBQWhCLFVBQWlCLEdBQWdCLEVBQUUsT0FBWSxJQUFHLENBQUM7UUFFbkQsMkNBQVMsR0FBVCxVQUFVLEdBQWdCLEVBQUUsT0FBWTtZQUN0QyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUM1QixDQUFDO1FBRUQsZ0RBQWMsR0FBZCxVQUFlLEdBQWMsRUFBRSxPQUFZLElBQUcsQ0FBQztRQUUvQyxpREFBZSxHQUFmLFVBQWdCLEdBQWUsRUFBRSxPQUFZLElBQUcsQ0FBQztRQUVqRCwwQ0FBUSxHQUFSLFVBQVMsSUFBVyxFQUFFLE9BQVk7WUFBbEMsaUJBRUM7WUFEQyxPQUFPLElBQUksQ0FBQyxHQUFHLENBQUMsVUFBQSxJQUFJLElBQUksT0FBQSxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUksRUFBRSxPQUFPLENBQUMsRUFBekIsQ0FBeUIsQ0FBQyxDQUFDO1FBQ3JELENBQUM7UUFFRCw0Q0FBVSxHQUFWLFVBQVcsR0FBVSxFQUFFLE9BQVksSUFBRyxDQUFDO1FBRXZDLDRDQUFVLEdBQVYsVUFBVyxHQUFVLEVBQUUsT0FBWSxJQUFHLENBQUM7UUFFdkMsb0RBQWtCLEdBQWxCLFVBQW1CLEdBQWtCLEVBQUUsT0FBWSxJQUFHLENBQUM7UUFDekQsOEJBQUM7SUFBRCxDQUFDLEFBMURELElBMERDO0lBRUQ7Ozs7OztPQU1HO0lBQ0g7UUFBeUMsc0RBQW1CO1FBQTVEO1lBQUEscUVBTUM7WUFMQyxZQUFNLEdBQWEsRUFBRSxDQUFDOztRQUt4QixDQUFDO1FBSFUsOENBQVMsR0FBbEI7WUFDRSxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUM1QixDQUFDO1FBQ0gsaUNBQUM7SUFBRCxDQUFDLEFBTkQsQ0FBeUMseUJBQW1CLEdBTTNEIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IEdvb2dsZSBMTEMgQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2FuZ3VsYXIuaW8vbGljZW5zZVxuICovXG5cbmltcG9ydCAqIGFzIGNoYXJzIGZyb20gJy4uL2NoYXJzJztcbmltcG9ydCB7REVGQVVMVF9JTlRFUlBPTEFUSU9OX0NPTkZJRywgSW50ZXJwb2xhdGlvbkNvbmZpZ30gZnJvbSAnLi4vbWxfcGFyc2VyL2ludGVycG9sYXRpb25fY29uZmlnJztcblxuaW1wb3J0IHtBYnNvbHV0ZVNvdXJjZVNwYW4sIEFTVCwgQXN0VmlzaXRvciwgQVNUV2l0aFNvdXJjZSwgQmluYXJ5LCBCaW5kaW5nUGlwZSwgQ2hhaW4sIENvbmRpdGlvbmFsLCBFbXB0eUV4cHIsIEV4cHJlc3Npb25CaW5kaW5nLCBGdW5jdGlvbkNhbGwsIEltcGxpY2l0UmVjZWl2ZXIsIEludGVycG9sYXRpb24sIEtleWVkUmVhZCwgS2V5ZWRXcml0ZSwgTGl0ZXJhbEFycmF5LCBMaXRlcmFsTWFwLCBMaXRlcmFsTWFwS2V5LCBMaXRlcmFsUHJpbWl0aXZlLCBNZXRob2RDYWxsLCBOb25OdWxsQXNzZXJ0LCBQYXJzZXJFcnJvciwgUGFyc2VTcGFuLCBQcmVmaXhOb3QsIFByb3BlcnR5UmVhZCwgUHJvcGVydHlXcml0ZSwgUXVvdGUsIFJlY3Vyc2l2ZUFzdFZpc2l0b3IsIFNhZmVLZXllZFJlYWQsIFNhZmVNZXRob2RDYWxsLCBTYWZlUHJvcGVydHlSZWFkLCBUZW1wbGF0ZUJpbmRpbmcsIFRlbXBsYXRlQmluZGluZ0lkZW50aWZpZXIsIFRoaXNSZWNlaXZlciwgVW5hcnksIFZhcmlhYmxlQmluZGluZ30gZnJvbSAnLi9hc3QnO1xuaW1wb3J0IHtFT0YsIGlzSWRlbnRpZmllciwgTGV4ZXIsIFRva2VuLCBUb2tlblR5cGV9IGZyb20gJy4vbGV4ZXInO1xuXG5leHBvcnQgaW50ZXJmYWNlIEludGVycG9sYXRpb25QaWVjZSB7XG4gIHRleHQ6IHN0cmluZztcbiAgc3RhcnQ6IG51bWJlcjtcbiAgZW5kOiBudW1iZXI7XG59XG5leHBvcnQgY2xhc3MgU3BsaXRJbnRlcnBvbGF0aW9uIHtcbiAgY29uc3RydWN0b3IoXG4gICAgICBwdWJsaWMgc3RyaW5nczogSW50ZXJwb2xhdGlvblBpZWNlW10sIHB1YmxpYyBleHByZXNzaW9uczogSW50ZXJwb2xhdGlvblBpZWNlW10sXG4gICAgICBwdWJsaWMgb2Zmc2V0czogbnVtYmVyW10pIHt9XG59XG5cbmV4cG9ydCBjbGFzcyBUZW1wbGF0ZUJpbmRpbmdQYXJzZVJlc3VsdCB7XG4gIGNvbnN0cnVjdG9yKFxuICAgICAgcHVibGljIHRlbXBsYXRlQmluZGluZ3M6IFRlbXBsYXRlQmluZGluZ1tdLCBwdWJsaWMgd2FybmluZ3M6IHN0cmluZ1tdLFxuICAgICAgcHVibGljIGVycm9yczogUGFyc2VyRXJyb3JbXSkge31cbn1cblxuZXhwb3J0IGNsYXNzIFBhcnNlciB7XG4gIHByaXZhdGUgZXJyb3JzOiBQYXJzZXJFcnJvcltdID0gW107XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBfbGV4ZXI6IExleGVyKSB7fVxuXG4gIHNpbXBsZUV4cHJlc3Npb25DaGVja2VyID0gU2ltcGxlRXhwcmVzc2lvbkNoZWNrZXI7XG5cbiAgcGFyc2VBY3Rpb24oXG4gICAgICBpbnB1dDogc3RyaW5nLCBsb2NhdGlvbjogc3RyaW5nLCBhYnNvbHV0ZU9mZnNldDogbnVtYmVyLFxuICAgICAgaW50ZXJwb2xhdGlvbkNvbmZpZzogSW50ZXJwb2xhdGlvbkNvbmZpZyA9IERFRkFVTFRfSU5URVJQT0xBVElPTl9DT05GSUcpOiBBU1RXaXRoU291cmNlIHtcbiAgICB0aGlzLl9jaGVja05vSW50ZXJwb2xhdGlvbihpbnB1dCwgbG9jYXRpb24sIGludGVycG9sYXRpb25Db25maWcpO1xuICAgIGNvbnN0IHNvdXJjZVRvTGV4ID0gdGhpcy5fc3RyaXBDb21tZW50cyhpbnB1dCk7XG4gICAgY29uc3QgdG9rZW5zID0gdGhpcy5fbGV4ZXIudG9rZW5pemUodGhpcy5fc3RyaXBDb21tZW50cyhpbnB1dCkpO1xuICAgIGNvbnN0IGFzdCA9IG5ldyBfUGFyc2VBU1QoXG4gICAgICAgICAgICAgICAgICAgIGlucHV0LCBsb2NhdGlvbiwgYWJzb2x1dGVPZmZzZXQsIHRva2Vucywgc291cmNlVG9MZXgubGVuZ3RoLCB0cnVlLCB0aGlzLmVycm9ycyxcbiAgICAgICAgICAgICAgICAgICAgaW5wdXQubGVuZ3RoIC0gc291cmNlVG9MZXgubGVuZ3RoKVxuICAgICAgICAgICAgICAgICAgICAucGFyc2VDaGFpbigpO1xuICAgIHJldHVybiBuZXcgQVNUV2l0aFNvdXJjZShhc3QsIGlucHV0LCBsb2NhdGlvbiwgYWJzb2x1dGVPZmZzZXQsIHRoaXMuZXJyb3JzKTtcbiAgfVxuXG4gIHBhcnNlQmluZGluZyhcbiAgICAgIGlucHV0OiBzdHJpbmcsIGxvY2F0aW9uOiBzdHJpbmcsIGFic29sdXRlT2Zmc2V0OiBudW1iZXIsXG4gICAgICBpbnRlcnBvbGF0aW9uQ29uZmlnOiBJbnRlcnBvbGF0aW9uQ29uZmlnID0gREVGQVVMVF9JTlRFUlBPTEFUSU9OX0NPTkZJRyk6IEFTVFdpdGhTb3VyY2Uge1xuICAgIGNvbnN0IGFzdCA9IHRoaXMuX3BhcnNlQmluZGluZ0FzdChpbnB1dCwgbG9jYXRpb24sIGFic29sdXRlT2Zmc2V0LCBpbnRlcnBvbGF0aW9uQ29uZmlnKTtcbiAgICByZXR1cm4gbmV3IEFTVFdpdGhTb3VyY2UoYXN0LCBpbnB1dCwgbG9jYXRpb24sIGFic29sdXRlT2Zmc2V0LCB0aGlzLmVycm9ycyk7XG4gIH1cblxuICBwcml2YXRlIGNoZWNrU2ltcGxlRXhwcmVzc2lvbihhc3Q6IEFTVCk6IHN0cmluZ1tdIHtcbiAgICBjb25zdCBjaGVja2VyID0gbmV3IHRoaXMuc2ltcGxlRXhwcmVzc2lvbkNoZWNrZXIoKTtcbiAgICBhc3QudmlzaXQoY2hlY2tlcik7XG4gICAgcmV0dXJuIGNoZWNrZXIuZXJyb3JzO1xuICB9XG5cbiAgcGFyc2VTaW1wbGVCaW5kaW5nKFxuICAgICAgaW5wdXQ6IHN0cmluZywgbG9jYXRpb246IHN0cmluZywgYWJzb2x1dGVPZmZzZXQ6IG51bWJlcixcbiAgICAgIGludGVycG9sYXRpb25Db25maWc6IEludGVycG9sYXRpb25Db25maWcgPSBERUZBVUxUX0lOVEVSUE9MQVRJT05fQ09ORklHKTogQVNUV2l0aFNvdXJjZSB7XG4gICAgY29uc3QgYXN0ID0gdGhpcy5fcGFyc2VCaW5kaW5nQXN0KGlucHV0LCBsb2NhdGlvbiwgYWJzb2x1dGVPZmZzZXQsIGludGVycG9sYXRpb25Db25maWcpO1xuICAgIGNvbnN0IGVycm9ycyA9IHRoaXMuY2hlY2tTaW1wbGVFeHByZXNzaW9uKGFzdCk7XG4gICAgaWYgKGVycm9ycy5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLl9yZXBvcnRFcnJvcihcbiAgICAgICAgICBgSG9zdCBiaW5kaW5nIGV4cHJlc3Npb24gY2Fubm90IGNvbnRhaW4gJHtlcnJvcnMuam9pbignICcpfWAsIGlucHV0LCBsb2NhdGlvbik7XG4gICAgfVxuICAgIHJldHVybiBuZXcgQVNUV2l0aFNvdXJjZShhc3QsIGlucHV0LCBsb2NhdGlvbiwgYWJzb2x1dGVPZmZzZXQsIHRoaXMuZXJyb3JzKTtcbiAgfVxuXG4gIHByaXZhdGUgX3JlcG9ydEVycm9yKG1lc3NhZ2U6IHN0cmluZywgaW5wdXQ6IHN0cmluZywgZXJyTG9jYXRpb246IHN0cmluZywgY3R4TG9jYXRpb24/OiBzdHJpbmcpIHtcbiAgICB0aGlzLmVycm9ycy5wdXNoKG5ldyBQYXJzZXJFcnJvcihtZXNzYWdlLCBpbnB1dCwgZXJyTG9jYXRpb24sIGN0eExvY2F0aW9uKSk7XG4gIH1cblxuICBwcml2YXRlIF9wYXJzZUJpbmRpbmdBc3QoXG4gICAgICBpbnB1dDogc3RyaW5nLCBsb2NhdGlvbjogc3RyaW5nLCBhYnNvbHV0ZU9mZnNldDogbnVtYmVyLFxuICAgICAgaW50ZXJwb2xhdGlvbkNvbmZpZzogSW50ZXJwb2xhdGlvbkNvbmZpZyk6IEFTVCB7XG4gICAgLy8gUXVvdGVzIGV4cHJlc3Npb25zIHVzZSAzcmQtcGFydHkgZXhwcmVzc2lvbiBsYW5ndWFnZS4gV2UgZG9uJ3Qgd2FudCB0byB1c2VcbiAgICAvLyBvdXIgbGV4ZXIgb3IgcGFyc2VyIGZvciB0aGF0LCBzbyB3ZSBjaGVjayBmb3IgdGhhdCBhaGVhZCBvZiB0aW1lLlxuICAgIGNvbnN0IHF1b3RlID0gdGhpcy5fcGFyc2VRdW90ZShpbnB1dCwgbG9jYXRpb24sIGFic29sdXRlT2Zmc2V0KTtcblxuICAgIGlmIChxdW90ZSAhPSBudWxsKSB7XG4gICAgICByZXR1cm4gcXVvdGU7XG4gICAgfVxuXG4gICAgdGhpcy5fY2hlY2tOb0ludGVycG9sYXRpb24oaW5wdXQsIGxvY2F0aW9uLCBpbnRlcnBvbGF0aW9uQ29uZmlnKTtcbiAgICBjb25zdCBzb3VyY2VUb0xleCA9IHRoaXMuX3N0cmlwQ29tbWVudHMoaW5wdXQpO1xuICAgIGNvbnN0IHRva2VucyA9IHRoaXMuX2xleGVyLnRva2VuaXplKHNvdXJjZVRvTGV4KTtcbiAgICByZXR1cm4gbmV3IF9QYXJzZUFTVChcbiAgICAgICAgICAgICAgIGlucHV0LCBsb2NhdGlvbiwgYWJzb2x1dGVPZmZzZXQsIHRva2Vucywgc291cmNlVG9MZXgubGVuZ3RoLCBmYWxzZSwgdGhpcy5lcnJvcnMsXG4gICAgICAgICAgICAgICBpbnB1dC5sZW5ndGggLSBzb3VyY2VUb0xleC5sZW5ndGgpXG4gICAgICAgIC5wYXJzZUNoYWluKCk7XG4gIH1cblxuICBwcml2YXRlIF9wYXJzZVF1b3RlKGlucHV0OiBzdHJpbmd8bnVsbCwgbG9jYXRpb246IHN0cmluZywgYWJzb2x1dGVPZmZzZXQ6IG51bWJlcik6IEFTVHxudWxsIHtcbiAgICBpZiAoaW5wdXQgPT0gbnVsbCkgcmV0dXJuIG51bGw7XG4gICAgY29uc3QgcHJlZml4U2VwYXJhdG9ySW5kZXggPSBpbnB1dC5pbmRleE9mKCc6Jyk7XG4gICAgaWYgKHByZWZpeFNlcGFyYXRvckluZGV4ID09IC0xKSByZXR1cm4gbnVsbDtcbiAgICBjb25zdCBwcmVmaXggPSBpbnB1dC5zdWJzdHJpbmcoMCwgcHJlZml4U2VwYXJhdG9ySW5kZXgpLnRyaW0oKTtcbiAgICBpZiAoIWlzSWRlbnRpZmllcihwcmVmaXgpKSByZXR1cm4gbnVsbDtcbiAgICBjb25zdCB1bmludGVycHJldGVkRXhwcmVzc2lvbiA9IGlucHV0LnN1YnN0cmluZyhwcmVmaXhTZXBhcmF0b3JJbmRleCArIDEpO1xuICAgIGNvbnN0IHNwYW4gPSBuZXcgUGFyc2VTcGFuKDAsIGlucHV0Lmxlbmd0aCk7XG4gICAgcmV0dXJuIG5ldyBRdW90ZShcbiAgICAgICAgc3Bhbiwgc3Bhbi50b0Fic29sdXRlKGFic29sdXRlT2Zmc2V0KSwgcHJlZml4LCB1bmludGVycHJldGVkRXhwcmVzc2lvbiwgbG9jYXRpb24pO1xuICB9XG5cbiAgLyoqXG4gICAqIFBhcnNlIG1pY3Jvc3ludGF4IHRlbXBsYXRlIGV4cHJlc3Npb24gYW5kIHJldHVybiBhIGxpc3Qgb2YgYmluZGluZ3Mgb3JcbiAgICogcGFyc2luZyBlcnJvcnMgaW4gY2FzZSB0aGUgZ2l2ZW4gZXhwcmVzc2lvbiBpcyBpbnZhbGlkLlxuICAgKlxuICAgKiBGb3IgZXhhbXBsZSxcbiAgICogYGBgXG4gICAqICAgPGRpdiAqbmdGb3I9XCJsZXQgaXRlbSBvZiBpdGVtc1wiPlxuICAgKiAgICAgICAgIF4gICAgICBeIGFic29sdXRlVmFsdWVPZmZzZXQgZm9yIGB0ZW1wbGF0ZVZhbHVlYFxuICAgKiAgICAgICAgIGFic29sdXRlS2V5T2Zmc2V0IGZvciBgdGVtcGxhdGVLZXlgXG4gICAqIGBgYFxuICAgKiBjb250YWlucyB0aHJlZSBiaW5kaW5nczpcbiAgICogMS4gbmdGb3IgLT4gbnVsbFxuICAgKiAyLiBpdGVtIC0+IE5nRm9yT2ZDb250ZXh0LiRpbXBsaWNpdFxuICAgKiAzLiBuZ0Zvck9mIC0+IGl0ZW1zXG4gICAqXG4gICAqIFRoaXMgaXMgYXBwYXJlbnQgZnJvbSB0aGUgZGUtc3VnYXJlZCB0ZW1wbGF0ZTpcbiAgICogYGBgXG4gICAqICAgPG5nLXRlbXBsYXRlIG5nRm9yIGxldC1pdGVtIFtuZ0Zvck9mXT1cIml0ZW1zXCI+XG4gICAqIGBgYFxuICAgKlxuICAgKiBAcGFyYW0gdGVtcGxhdGVLZXkgbmFtZSBvZiBkaXJlY3RpdmUsIHdpdGhvdXQgdGhlICogcHJlZml4LiBGb3IgZXhhbXBsZTogbmdJZiwgbmdGb3JcbiAgICogQHBhcmFtIHRlbXBsYXRlVmFsdWUgUkhTIG9mIHRoZSBtaWNyb3N5bnRheCBhdHRyaWJ1dGVcbiAgICogQHBhcmFtIHRlbXBsYXRlVXJsIHRlbXBsYXRlIGZpbGVuYW1lIGlmIGl0J3MgZXh0ZXJuYWwsIGNvbXBvbmVudCBmaWxlbmFtZSBpZiBpdCdzIGlubGluZVxuICAgKiBAcGFyYW0gYWJzb2x1dGVLZXlPZmZzZXQgc3RhcnQgb2YgdGhlIGB0ZW1wbGF0ZUtleWBcbiAgICogQHBhcmFtIGFic29sdXRlVmFsdWVPZmZzZXQgc3RhcnQgb2YgdGhlIGB0ZW1wbGF0ZVZhbHVlYFxuICAgKi9cbiAgcGFyc2VUZW1wbGF0ZUJpbmRpbmdzKFxuICAgICAgdGVtcGxhdGVLZXk6IHN0cmluZywgdGVtcGxhdGVWYWx1ZTogc3RyaW5nLCB0ZW1wbGF0ZVVybDogc3RyaW5nLCBhYnNvbHV0ZUtleU9mZnNldDogbnVtYmVyLFxuICAgICAgYWJzb2x1dGVWYWx1ZU9mZnNldDogbnVtYmVyKTogVGVtcGxhdGVCaW5kaW5nUGFyc2VSZXN1bHQge1xuICAgIGNvbnN0IHRva2VucyA9IHRoaXMuX2xleGVyLnRva2VuaXplKHRlbXBsYXRlVmFsdWUpO1xuICAgIGNvbnN0IHBhcnNlciA9IG5ldyBfUGFyc2VBU1QoXG4gICAgICAgIHRlbXBsYXRlVmFsdWUsIHRlbXBsYXRlVXJsLCBhYnNvbHV0ZVZhbHVlT2Zmc2V0LCB0b2tlbnMsIHRlbXBsYXRlVmFsdWUubGVuZ3RoLFxuICAgICAgICBmYWxzZSAvKiBwYXJzZUFjdGlvbiAqLywgdGhpcy5lcnJvcnMsIDAgLyogcmVsYXRpdmUgb2Zmc2V0ICovKTtcbiAgICByZXR1cm4gcGFyc2VyLnBhcnNlVGVtcGxhdGVCaW5kaW5ncyh7XG4gICAgICBzb3VyY2U6IHRlbXBsYXRlS2V5LFxuICAgICAgc3BhbjogbmV3IEFic29sdXRlU291cmNlU3BhbihhYnNvbHV0ZUtleU9mZnNldCwgYWJzb2x1dGVLZXlPZmZzZXQgKyB0ZW1wbGF0ZUtleS5sZW5ndGgpLFxuICAgIH0pO1xuICB9XG5cbiAgcGFyc2VJbnRlcnBvbGF0aW9uKFxuICAgICAgaW5wdXQ6IHN0cmluZywgbG9jYXRpb246IHN0cmluZywgYWJzb2x1dGVPZmZzZXQ6IG51bWJlcixcbiAgICAgIGludGVycG9sYXRpb25Db25maWc6IEludGVycG9sYXRpb25Db25maWcgPSBERUZBVUxUX0lOVEVSUE9MQVRJT05fQ09ORklHKTogQVNUV2l0aFNvdXJjZXxudWxsIHtcbiAgICBjb25zdCB7c3RyaW5ncywgZXhwcmVzc2lvbnMsIG9mZnNldHN9ID1cbiAgICAgICAgdGhpcy5zcGxpdEludGVycG9sYXRpb24oaW5wdXQsIGxvY2F0aW9uLCBpbnRlcnBvbGF0aW9uQ29uZmlnKTtcbiAgICBpZiAoZXhwcmVzc2lvbnMubGVuZ3RoID09PSAwKSByZXR1cm4gbnVsbDtcblxuICAgIGNvbnN0IGV4cHJlc3Npb25Ob2RlczogQVNUW10gPSBbXTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZXhwcmVzc2lvbnMubGVuZ3RoOyArK2kpIHtcbiAgICAgIGNvbnN0IGV4cHJlc3Npb25UZXh0ID0gZXhwcmVzc2lvbnNbaV0udGV4dDtcbiAgICAgIGNvbnN0IHNvdXJjZVRvTGV4ID0gdGhpcy5fc3RyaXBDb21tZW50cyhleHByZXNzaW9uVGV4dCk7XG4gICAgICBjb25zdCB0b2tlbnMgPSB0aGlzLl9sZXhlci50b2tlbml6ZShzb3VyY2VUb0xleCk7XG4gICAgICBjb25zdCBhc3QgPSBuZXcgX1BhcnNlQVNUKFxuICAgICAgICAgICAgICAgICAgICAgIGlucHV0LCBsb2NhdGlvbiwgYWJzb2x1dGVPZmZzZXQsIHRva2Vucywgc291cmNlVG9MZXgubGVuZ3RoLCBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVycm9ycywgb2Zmc2V0c1tpXSArIChleHByZXNzaW9uVGV4dC5sZW5ndGggLSBzb3VyY2VUb0xleC5sZW5ndGgpKVxuICAgICAgICAgICAgICAgICAgICAgIC5wYXJzZUNoYWluKCk7XG4gICAgICBleHByZXNzaW9uTm9kZXMucHVzaChhc3QpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmNyZWF0ZUludGVycG9sYXRpb25Bc3QoXG4gICAgICAgIHN0cmluZ3MubWFwKHMgPT4gcy50ZXh0KSwgZXhwcmVzc2lvbk5vZGVzLCBpbnB1dCwgbG9jYXRpb24sIGFic29sdXRlT2Zmc2V0KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTaW1pbGFyIHRvIGBwYXJzZUludGVycG9sYXRpb25gLCBidXQgdHJlYXRzIHRoZSBwcm92aWRlZCBzdHJpbmcgYXMgYSBzaW5nbGUgZXhwcmVzc2lvblxuICAgKiBlbGVtZW50IHRoYXQgd291bGQgbm9ybWFsbHkgYXBwZWFyIHdpdGhpbiB0aGUgaW50ZXJwb2xhdGlvbiBwcmVmaXggYW5kIHN1ZmZpeCAoYHt7YCBhbmQgYH19YCkuXG4gICAqIFRoaXMgaXMgdXNlZCBmb3IgcGFyc2luZyB0aGUgc3dpdGNoIGV4cHJlc3Npb24gaW4gSUNVcy5cbiAgICovXG4gIHBhcnNlSW50ZXJwb2xhdGlvbkV4cHJlc3Npb24oZXhwcmVzc2lvbjogc3RyaW5nLCBsb2NhdGlvbjogc3RyaW5nLCBhYnNvbHV0ZU9mZnNldDogbnVtYmVyKTpcbiAgICAgIEFTVFdpdGhTb3VyY2Uge1xuICAgIGNvbnN0IHNvdXJjZVRvTGV4ID0gdGhpcy5fc3RyaXBDb21tZW50cyhleHByZXNzaW9uKTtcbiAgICBjb25zdCB0b2tlbnMgPSB0aGlzLl9sZXhlci50b2tlbml6ZShzb3VyY2VUb0xleCk7XG4gICAgY29uc3QgYXN0ID0gbmV3IF9QYXJzZUFTVChcbiAgICAgICAgICAgICAgICAgICAgZXhwcmVzc2lvbiwgbG9jYXRpb24sIGFic29sdXRlT2Zmc2V0LCB0b2tlbnMsIHNvdXJjZVRvTGV4Lmxlbmd0aCxcbiAgICAgICAgICAgICAgICAgICAgLyogcGFyc2VBY3Rpb24gKi8gZmFsc2UsIHRoaXMuZXJyb3JzLCAwKVxuICAgICAgICAgICAgICAgICAgICAucGFyc2VDaGFpbigpO1xuICAgIGNvbnN0IHN0cmluZ3MgPSBbJycsICcnXTsgIC8vIFRoZSBwcmVmaXggYW5kIHN1ZmZpeCBzdHJpbmdzIGFyZSBib3RoIGVtcHR5XG4gICAgcmV0dXJuIHRoaXMuY3JlYXRlSW50ZXJwb2xhdGlvbkFzdChzdHJpbmdzLCBbYXN0XSwgZXhwcmVzc2lvbiwgbG9jYXRpb24sIGFic29sdXRlT2Zmc2V0KTtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlSW50ZXJwb2xhdGlvbkFzdChcbiAgICAgIHN0cmluZ3M6IHN0cmluZ1tdLCBleHByZXNzaW9uczogQVNUW10sIGlucHV0OiBzdHJpbmcsIGxvY2F0aW9uOiBzdHJpbmcsXG4gICAgICBhYnNvbHV0ZU9mZnNldDogbnVtYmVyKTogQVNUV2l0aFNvdXJjZSB7XG4gICAgY29uc3Qgc3BhbiA9IG5ldyBQYXJzZVNwYW4oMCwgaW5wdXQubGVuZ3RoKTtcbiAgICBjb25zdCBpbnRlcnBvbGF0aW9uID1cbiAgICAgICAgbmV3IEludGVycG9sYXRpb24oc3Bhbiwgc3Bhbi50b0Fic29sdXRlKGFic29sdXRlT2Zmc2V0KSwgc3RyaW5ncywgZXhwcmVzc2lvbnMpO1xuICAgIHJldHVybiBuZXcgQVNUV2l0aFNvdXJjZShpbnRlcnBvbGF0aW9uLCBpbnB1dCwgbG9jYXRpb24sIGFic29sdXRlT2Zmc2V0LCB0aGlzLmVycm9ycyk7XG4gIH1cblxuICAvKipcbiAgICogU3BsaXRzIGEgc3RyaW5nIG9mIHRleHQgaW50byBcInJhd1wiIHRleHQgc2VnbWVudHMgYW5kIGV4cHJlc3Npb25zIHByZXNlbnQgaW4gaW50ZXJwb2xhdGlvbnMgaW5cbiAgICogdGhlIHN0cmluZy5cbiAgICogUmV0dXJucyBgbnVsbGAgaWYgdGhlcmUgYXJlIG5vIGludGVycG9sYXRpb25zLCBvdGhlcndpc2UgYVxuICAgKiBgU3BsaXRJbnRlcnBvbGF0aW9uYCB3aXRoIHNwbGl0cyB0aGF0IGxvb2sgbGlrZVxuICAgKiAgIDxyYXcgdGV4dD4gPGV4cHJlc3Npb24+IDxyYXcgdGV4dD4gLi4uIDxyYXcgdGV4dD4gPGV4cHJlc3Npb24+IDxyYXcgdGV4dD5cbiAgICovXG4gIHNwbGl0SW50ZXJwb2xhdGlvbihcbiAgICAgIGlucHV0OiBzdHJpbmcsIGxvY2F0aW9uOiBzdHJpbmcsXG4gICAgICBpbnRlcnBvbGF0aW9uQ29uZmlnOiBJbnRlcnBvbGF0aW9uQ29uZmlnID0gREVGQVVMVF9JTlRFUlBPTEFUSU9OX0NPTkZJRyk6IFNwbGl0SW50ZXJwb2xhdGlvbiB7XG4gICAgY29uc3Qgc3RyaW5nczogSW50ZXJwb2xhdGlvblBpZWNlW10gPSBbXTtcbiAgICBjb25zdCBleHByZXNzaW9uczogSW50ZXJwb2xhdGlvblBpZWNlW10gPSBbXTtcbiAgICBjb25zdCBvZmZzZXRzOiBudW1iZXJbXSA9IFtdO1xuICAgIGxldCBpID0gMDtcbiAgICBsZXQgYXRJbnRlcnBvbGF0aW9uID0gZmFsc2U7XG4gICAgbGV0IGV4dGVuZExhc3RTdHJpbmcgPSBmYWxzZTtcbiAgICBsZXQge3N0YXJ0OiBpbnRlcnBTdGFydCwgZW5kOiBpbnRlcnBFbmR9ID0gaW50ZXJwb2xhdGlvbkNvbmZpZztcbiAgICB3aGlsZSAoaSA8IGlucHV0Lmxlbmd0aCkge1xuICAgICAgaWYgKCFhdEludGVycG9sYXRpb24pIHtcbiAgICAgICAgLy8gcGFyc2UgdW50aWwgc3RhcnRpbmcge3tcbiAgICAgICAgY29uc3Qgc3RhcnQgPSBpO1xuICAgICAgICBpID0gaW5wdXQuaW5kZXhPZihpbnRlcnBTdGFydCwgaSk7XG4gICAgICAgIGlmIChpID09PSAtMSkge1xuICAgICAgICAgIGkgPSBpbnB1dC5sZW5ndGg7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdGV4dCA9IGlucHV0LnN1YnN0cmluZyhzdGFydCwgaSk7XG4gICAgICAgIHN0cmluZ3MucHVzaCh7dGV4dCwgc3RhcnQsIGVuZDogaX0pO1xuXG4gICAgICAgIGF0SW50ZXJwb2xhdGlvbiA9IHRydWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBwYXJzZSBmcm9tIHN0YXJ0aW5nIHt7IHRvIGVuZGluZyB9fSB3aGlsZSBpZ25vcmluZyBjb250ZW50IGluc2lkZSBxdW90ZXMuXG4gICAgICAgIGNvbnN0IGZ1bGxTdGFydCA9IGk7XG4gICAgICAgIGNvbnN0IGV4cHJTdGFydCA9IGZ1bGxTdGFydCArIGludGVycFN0YXJ0Lmxlbmd0aDtcbiAgICAgICAgY29uc3QgZXhwckVuZCA9IHRoaXMuX2dldEludGVycG9sYXRpb25FbmRJbmRleChpbnB1dCwgaW50ZXJwRW5kLCBleHByU3RhcnQpO1xuICAgICAgICBpZiAoZXhwckVuZCA9PT0gLTEpIHtcbiAgICAgICAgICAvLyBDb3VsZCBub3QgZmluZCB0aGUgZW5kIG9mIHRoZSBpbnRlcnBvbGF0aW9uOyBkbyBub3QgcGFyc2UgYW4gZXhwcmVzc2lvbi5cbiAgICAgICAgICAvLyBJbnN0ZWFkIHdlIHNob3VsZCBleHRlbmQgdGhlIGNvbnRlbnQgb24gdGhlIGxhc3QgcmF3IHN0cmluZy5cbiAgICAgICAgICBhdEludGVycG9sYXRpb24gPSBmYWxzZTtcbiAgICAgICAgICBleHRlbmRMYXN0U3RyaW5nID0gdHJ1ZTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBmdWxsRW5kID0gZXhwckVuZCArIGludGVycEVuZC5sZW5ndGg7XG5cbiAgICAgICAgY29uc3QgdGV4dCA9IGlucHV0LnN1YnN0cmluZyhleHByU3RhcnQsIGV4cHJFbmQpO1xuICAgICAgICBpZiAodGV4dC50cmltKCkubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgdGhpcy5fcmVwb3J0RXJyb3IoXG4gICAgICAgICAgICAgICdCbGFuayBleHByZXNzaW9ucyBhcmUgbm90IGFsbG93ZWQgaW4gaW50ZXJwb2xhdGVkIHN0cmluZ3MnLCBpbnB1dCxcbiAgICAgICAgICAgICAgYGF0IGNvbHVtbiAke2l9IGluYCwgbG9jYXRpb24pO1xuICAgICAgICB9XG4gICAgICAgIGV4cHJlc3Npb25zLnB1c2goe3RleHQsIHN0YXJ0OiBmdWxsU3RhcnQsIGVuZDogZnVsbEVuZH0pO1xuICAgICAgICBvZmZzZXRzLnB1c2goZXhwclN0YXJ0KTtcblxuICAgICAgICBpID0gZnVsbEVuZDtcbiAgICAgICAgYXRJbnRlcnBvbGF0aW9uID0gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuICAgIGlmICghYXRJbnRlcnBvbGF0aW9uKSB7XG4gICAgICAvLyBJZiB3ZSBhcmUgbm93IGF0IGEgdGV4dCBzZWN0aW9uLCBhZGQgdGhlIHJlbWFpbmluZyBjb250ZW50IGFzIGEgcmF3IHN0cmluZy5cbiAgICAgIGlmIChleHRlbmRMYXN0U3RyaW5nKSB7XG4gICAgICAgIGNvbnN0IHBpZWNlID0gc3RyaW5nc1tzdHJpbmdzLmxlbmd0aCAtIDFdO1xuICAgICAgICBwaWVjZS50ZXh0ICs9IGlucHV0LnN1YnN0cmluZyhpKTtcbiAgICAgICAgcGllY2UuZW5kID0gaW5wdXQubGVuZ3RoO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3RyaW5ncy5wdXNoKHt0ZXh0OiBpbnB1dC5zdWJzdHJpbmcoaSksIHN0YXJ0OiBpLCBlbmQ6IGlucHV0Lmxlbmd0aH0pO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbmV3IFNwbGl0SW50ZXJwb2xhdGlvbihzdHJpbmdzLCBleHByZXNzaW9ucywgb2Zmc2V0cyk7XG4gIH1cblxuICB3cmFwTGl0ZXJhbFByaW1pdGl2ZShpbnB1dDogc3RyaW5nfG51bGwsIGxvY2F0aW9uOiBzdHJpbmcsIGFic29sdXRlT2Zmc2V0OiBudW1iZXIpOlxuICAgICAgQVNUV2l0aFNvdXJjZSB7XG4gICAgY29uc3Qgc3BhbiA9IG5ldyBQYXJzZVNwYW4oMCwgaW5wdXQgPT0gbnVsbCA/IDAgOiBpbnB1dC5sZW5ndGgpO1xuICAgIHJldHVybiBuZXcgQVNUV2l0aFNvdXJjZShcbiAgICAgICAgbmV3IExpdGVyYWxQcmltaXRpdmUoc3Bhbiwgc3Bhbi50b0Fic29sdXRlKGFic29sdXRlT2Zmc2V0KSwgaW5wdXQpLCBpbnB1dCwgbG9jYXRpb24sXG4gICAgICAgIGFic29sdXRlT2Zmc2V0LCB0aGlzLmVycm9ycyk7XG4gIH1cblxuICBwcml2YXRlIF9zdHJpcENvbW1lbnRzKGlucHV0OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGNvbnN0IGkgPSB0aGlzLl9jb21tZW50U3RhcnQoaW5wdXQpO1xuICAgIHJldHVybiBpICE9IG51bGwgPyBpbnB1dC5zdWJzdHJpbmcoMCwgaSkudHJpbSgpIDogaW5wdXQ7XG4gIH1cblxuICBwcml2YXRlIF9jb21tZW50U3RhcnQoaW5wdXQ6IHN0cmluZyk6IG51bWJlcnxudWxsIHtcbiAgICBsZXQgb3V0ZXJRdW90ZTogbnVtYmVyfG51bGwgPSBudWxsO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW5wdXQubGVuZ3RoIC0gMTsgaSsrKSB7XG4gICAgICBjb25zdCBjaGFyID0gaW5wdXQuY2hhckNvZGVBdChpKTtcbiAgICAgIGNvbnN0IG5leHRDaGFyID0gaW5wdXQuY2hhckNvZGVBdChpICsgMSk7XG5cbiAgICAgIGlmIChjaGFyID09PSBjaGFycy4kU0xBU0ggJiYgbmV4dENoYXIgPT0gY2hhcnMuJFNMQVNIICYmIG91dGVyUXVvdGUgPT0gbnVsbCkgcmV0dXJuIGk7XG5cbiAgICAgIGlmIChvdXRlclF1b3RlID09PSBjaGFyKSB7XG4gICAgICAgIG91dGVyUXVvdGUgPSBudWxsO1xuICAgICAgfSBlbHNlIGlmIChvdXRlclF1b3RlID09IG51bGwgJiYgY2hhcnMuaXNRdW90ZShjaGFyKSkge1xuICAgICAgICBvdXRlclF1b3RlID0gY2hhcjtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBwcml2YXRlIF9jaGVja05vSW50ZXJwb2xhdGlvbihpbnB1dDogc3RyaW5nLCBsb2NhdGlvbjogc3RyaW5nLCB7c3RhcnQsIGVuZH06IEludGVycG9sYXRpb25Db25maWcpOlxuICAgICAgdm9pZCB7XG4gICAgbGV0IHN0YXJ0SW5kZXggPSAtMTtcbiAgICBsZXQgZW5kSW5kZXggPSAtMTtcblxuICAgIGZvciAoY29uc3QgY2hhckluZGV4IG9mIHRoaXMuX2ZvckVhY2hVbnF1b3RlZENoYXIoaW5wdXQsIDApKSB7XG4gICAgICBpZiAoc3RhcnRJbmRleCA9PT0gLTEpIHtcbiAgICAgICAgaWYgKGlucHV0LnN0YXJ0c1dpdGgoc3RhcnQpKSB7XG4gICAgICAgICAgc3RhcnRJbmRleCA9IGNoYXJJbmRleDtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZW5kSW5kZXggPSB0aGlzLl9nZXRJbnRlcnBvbGF0aW9uRW5kSW5kZXgoaW5wdXQsIGVuZCwgY2hhckluZGV4KTtcbiAgICAgICAgaWYgKGVuZEluZGV4ID4gLTEpIHtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChzdGFydEluZGV4ID4gLTEgJiYgZW5kSW5kZXggPiAtMSkge1xuICAgICAgdGhpcy5fcmVwb3J0RXJyb3IoXG4gICAgICAgICAgYEdvdCBpbnRlcnBvbGF0aW9uICgke3N0YXJ0fSR7ZW5kfSkgd2hlcmUgZXhwcmVzc2lvbiB3YXMgZXhwZWN0ZWRgLCBpbnB1dCxcbiAgICAgICAgICBgYXQgY29sdW1uICR7c3RhcnRJbmRleH0gaW5gLCBsb2NhdGlvbik7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEZpbmRzIHRoZSBpbmRleCBvZiB0aGUgZW5kIG9mIGFuIGludGVycG9sYXRpb24gZXhwcmVzc2lvblxuICAgKiB3aGlsZSBpZ25vcmluZyBjb21tZW50cyBhbmQgcXVvdGVkIGNvbnRlbnQuXG4gICAqL1xuICBwcml2YXRlIF9nZXRJbnRlcnBvbGF0aW9uRW5kSW5kZXgoaW5wdXQ6IHN0cmluZywgZXhwcmVzc2lvbkVuZDogc3RyaW5nLCBzdGFydDogbnVtYmVyKTogbnVtYmVyIHtcbiAgICBmb3IgKGNvbnN0IGNoYXJJbmRleCBvZiB0aGlzLl9mb3JFYWNoVW5xdW90ZWRDaGFyKGlucHV0LCBzdGFydCkpIHtcbiAgICAgIGlmIChpbnB1dC5zdGFydHNXaXRoKGV4cHJlc3Npb25FbmQsIGNoYXJJbmRleCkpIHtcbiAgICAgICAgcmV0dXJuIGNoYXJJbmRleDtcbiAgICAgIH1cblxuICAgICAgLy8gTm90aGluZyBlbHNlIGluIHRoZSBleHByZXNzaW9uIG1hdHRlcnMgYWZ0ZXIgd2UndmVcbiAgICAgIC8vIGhpdCBhIGNvbW1lbnQgc28gbG9vayBkaXJlY3RseSBmb3IgdGhlIGVuZCB0b2tlbi5cbiAgICAgIGlmIChpbnB1dC5zdGFydHNXaXRoKCcvLycsIGNoYXJJbmRleCkpIHtcbiAgICAgICAgcmV0dXJuIGlucHV0LmluZGV4T2YoZXhwcmVzc2lvbkVuZCwgY2hhckluZGV4KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gLTE7XG4gIH1cblxuICAvKipcbiAgICogR2VuZXJhdG9yIHVzZWQgdG8gaXRlcmF0ZSBvdmVyIHRoZSBjaGFyYWN0ZXIgaW5kZXhlcyBvZiBhIHN0cmluZyB0aGF0IGFyZSBvdXRzaWRlIG9mIHF1b3Rlcy5cbiAgICogQHBhcmFtIGlucHV0IFN0cmluZyB0byBsb29wIHRocm91Z2guXG4gICAqIEBwYXJhbSBzdGFydCBJbmRleCB3aXRoaW4gdGhlIHN0cmluZyBhdCB3aGljaCB0byBzdGFydC5cbiAgICovXG4gIHByaXZhdGUgKiBfZm9yRWFjaFVucXVvdGVkQ2hhcihpbnB1dDogc3RyaW5nLCBzdGFydDogbnVtYmVyKSB7XG4gICAgbGV0IGN1cnJlbnRRdW90ZTogc3RyaW5nfG51bGwgPSBudWxsO1xuICAgIGxldCBlc2NhcGVDb3VudCA9IDA7XG4gICAgZm9yIChsZXQgaSA9IHN0YXJ0OyBpIDwgaW5wdXQubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IGNoYXIgPSBpbnB1dFtpXTtcbiAgICAgIC8vIFNraXAgdGhlIGNoYXJhY3RlcnMgaW5zaWRlIHF1b3Rlcy4gTm90ZSB0aGF0IHdlIG9ubHkgY2FyZSBhYm91dCB0aGUgb3V0ZXItbW9zdFxuICAgICAgLy8gcXVvdGVzIG1hdGNoaW5nIHVwIGFuZCB3ZSBuZWVkIHRvIGFjY291bnQgZm9yIGVzY2FwZSBjaGFyYWN0ZXJzLlxuICAgICAgaWYgKGNoYXJzLmlzUXVvdGUoaW5wdXQuY2hhckNvZGVBdChpKSkgJiYgKGN1cnJlbnRRdW90ZSA9PT0gbnVsbCB8fCBjdXJyZW50UXVvdGUgPT09IGNoYXIpICYmXG4gICAgICAgICAgZXNjYXBlQ291bnQgJSAyID09PSAwKSB7XG4gICAgICAgIGN1cnJlbnRRdW90ZSA9IGN1cnJlbnRRdW90ZSA9PT0gbnVsbCA/IGNoYXIgOiBudWxsO1xuICAgICAgfSBlbHNlIGlmIChjdXJyZW50UXVvdGUgPT09IG51bGwpIHtcbiAgICAgICAgeWllbGQgaTtcbiAgICAgIH1cbiAgICAgIGVzY2FwZUNvdW50ID0gY2hhciA9PT0gJ1xcXFwnID8gZXNjYXBlQ291bnQgKyAxIDogMDtcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIEl2eVBhcnNlciBleHRlbmRzIFBhcnNlciB7XG4gIG92ZXJyaWRlIHNpbXBsZUV4cHJlc3Npb25DaGVja2VyID0gSXZ5U2ltcGxlRXhwcmVzc2lvbkNoZWNrZXI7XG59XG5cbi8qKiBEZXNjcmliZXMgYSBzdGF0ZWZ1bCBjb250ZXh0IGFuIGV4cHJlc3Npb24gcGFyc2VyIGlzIGluLiAqL1xuZW51bSBQYXJzZUNvbnRleHRGbGFncyB7XG4gIE5vbmUgPSAwLFxuICAvKipcbiAgICogQSBXcml0YWJsZSBjb250ZXh0IGlzIG9uZSBpbiB3aGljaCBhIHZhbHVlIG1heSBiZSB3cml0dGVuIHRvIGFuIGx2YWx1ZS5cbiAgICogRm9yIGV4YW1wbGUsIGFmdGVyIHdlIHNlZSBhIHByb3BlcnR5IGFjY2Vzcywgd2UgbWF5IGV4cGVjdCBhIHdyaXRlIHRvIHRoZVxuICAgKiBwcm9wZXJ0eSB2aWEgdGhlIFwiPVwiIG9wZXJhdG9yLlxuICAgKiAgIHByb3BcbiAgICogICAgICAgIF4gcG9zc2libGUgXCI9XCIgYWZ0ZXJcbiAgICovXG4gIFdyaXRhYmxlID0gMSxcbn1cblxuZXhwb3J0IGNsYXNzIF9QYXJzZUFTVCB7XG4gIHByaXZhdGUgcnBhcmVuc0V4cGVjdGVkID0gMDtcbiAgcHJpdmF0ZSByYnJhY2tldHNFeHBlY3RlZCA9IDA7XG4gIHByaXZhdGUgcmJyYWNlc0V4cGVjdGVkID0gMDtcbiAgcHJpdmF0ZSBjb250ZXh0ID0gUGFyc2VDb250ZXh0RmxhZ3MuTm9uZTtcblxuICAvLyBDYWNoZSBvZiBleHByZXNzaW9uIHN0YXJ0IGFuZCBpbnB1dCBpbmRlY2VzIHRvIHRoZSBhYnNvbHV0ZSBzb3VyY2Ugc3BhbiB0aGV5IG1hcCB0bywgdXNlZCB0b1xuICAvLyBwcmV2ZW50IGNyZWF0aW5nIHN1cGVyZmx1b3VzIHNvdXJjZSBzcGFucyBpbiBgc291cmNlU3BhbmAuXG4gIC8vIEEgc2VyaWFsIG9mIHRoZSBleHByZXNzaW9uIHN0YXJ0IGFuZCBpbnB1dCBpbmRleCBpcyB1c2VkIGZvciBtYXBwaW5nIGJlY2F1c2UgYm90aCBhcmUgc3RhdGVmdWxcbiAgLy8gYW5kIG1heSBjaGFuZ2UgZm9yIHN1YnNlcXVlbnQgZXhwcmVzc2lvbnMgdmlzaXRlZCBieSB0aGUgcGFyc2VyLlxuICBwcml2YXRlIHNvdXJjZVNwYW5DYWNoZSA9IG5ldyBNYXA8c3RyaW5nLCBBYnNvbHV0ZVNvdXJjZVNwYW4+KCk7XG5cbiAgaW5kZXg6IG51bWJlciA9IDA7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgICBwdWJsaWMgaW5wdXQ6IHN0cmluZywgcHVibGljIGxvY2F0aW9uOiBzdHJpbmcsIHB1YmxpYyBhYnNvbHV0ZU9mZnNldDogbnVtYmVyLFxuICAgICAgcHVibGljIHRva2VuczogVG9rZW5bXSwgcHVibGljIGlucHV0TGVuZ3RoOiBudW1iZXIsIHB1YmxpYyBwYXJzZUFjdGlvbjogYm9vbGVhbixcbiAgICAgIHByaXZhdGUgZXJyb3JzOiBQYXJzZXJFcnJvcltdLCBwcml2YXRlIG9mZnNldDogbnVtYmVyKSB7fVxuXG4gIHBlZWsob2Zmc2V0OiBudW1iZXIpOiBUb2tlbiB7XG4gICAgY29uc3QgaSA9IHRoaXMuaW5kZXggKyBvZmZzZXQ7XG4gICAgcmV0dXJuIGkgPCB0aGlzLnRva2Vucy5sZW5ndGggPyB0aGlzLnRva2Vuc1tpXSA6IEVPRjtcbiAgfVxuXG4gIGdldCBuZXh0KCk6IFRva2VuIHtcbiAgICByZXR1cm4gdGhpcy5wZWVrKDApO1xuICB9XG5cbiAgLyoqIFdoZXRoZXIgYWxsIHRoZSBwYXJzZXIgaW5wdXQgaGFzIGJlZW4gcHJvY2Vzc2VkLiAqL1xuICBnZXQgYXRFT0YoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuaW5kZXggPj0gdGhpcy50b2tlbnMubGVuZ3RoO1xuICB9XG5cbiAgLyoqXG4gICAqIEluZGV4IG9mIHRoZSBuZXh0IHRva2VuIHRvIGJlIHByb2Nlc3NlZCwgb3IgdGhlIGVuZCBvZiB0aGUgbGFzdCB0b2tlbiBpZiBhbGwgaGF2ZSBiZWVuXG4gICAqIHByb2Nlc3NlZC5cbiAgICovXG4gIGdldCBpbnB1dEluZGV4KCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuYXRFT0YgPyB0aGlzLmN1cnJlbnRFbmRJbmRleCA6IHRoaXMubmV4dC5pbmRleCArIHRoaXMub2Zmc2V0O1xuICB9XG5cbiAgLyoqXG4gICAqIEVuZCBpbmRleCBvZiB0aGUgbGFzdCBwcm9jZXNzZWQgdG9rZW4sIG9yIHRoZSBzdGFydCBvZiB0aGUgZmlyc3QgdG9rZW4gaWYgbm9uZSBoYXZlIGJlZW5cbiAgICogcHJvY2Vzc2VkLlxuICAgKi9cbiAgZ2V0IGN1cnJlbnRFbmRJbmRleCgpOiBudW1iZXIge1xuICAgIGlmICh0aGlzLmluZGV4ID4gMCkge1xuICAgICAgY29uc3QgY3VyVG9rZW4gPSB0aGlzLnBlZWsoLTEpO1xuICAgICAgcmV0dXJuIGN1clRva2VuLmVuZCArIHRoaXMub2Zmc2V0O1xuICAgIH1cbiAgICAvLyBObyB0b2tlbnMgaGF2ZSBiZWVuIHByb2Nlc3NlZCB5ZXQ7IHJldHVybiB0aGUgbmV4dCB0b2tlbidzIHN0YXJ0IG9yIHRoZSBsZW5ndGggb2YgdGhlIGlucHV0XG4gICAgLy8gaWYgdGhlcmUgaXMgbm8gdG9rZW4uXG4gICAgaWYgKHRoaXMudG9rZW5zLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIHRoaXMuaW5wdXRMZW5ndGggKyB0aGlzLm9mZnNldDtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMubmV4dC5pbmRleCArIHRoaXMub2Zmc2V0O1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIGFic29sdXRlIG9mZnNldCBvZiB0aGUgc3RhcnQgb2YgdGhlIGN1cnJlbnQgdG9rZW4uXG4gICAqL1xuICBnZXQgY3VycmVudEFic29sdXRlT2Zmc2V0KCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuYWJzb2x1dGVPZmZzZXQgKyB0aGlzLmlucHV0SW5kZXg7XG4gIH1cblxuICAvKipcbiAgICogUmV0cmlldmUgYSBgUGFyc2VTcGFuYCBmcm9tIGBzdGFydGAgdG8gdGhlIGN1cnJlbnQgcG9zaXRpb24gKG9yIHRvIGBhcnRpZmljaWFsRW5kSW5kZXhgIGlmXG4gICAqIHByb3ZpZGVkKS5cbiAgICpcbiAgICogQHBhcmFtIHN0YXJ0IFBvc2l0aW9uIGZyb20gd2hpY2ggdGhlIGBQYXJzZVNwYW5gIHdpbGwgc3RhcnQuXG4gICAqIEBwYXJhbSBhcnRpZmljaWFsRW5kSW5kZXggT3B0aW9uYWwgZW5kaW5nIGluZGV4IHRvIGJlIHVzZWQgaWYgcHJvdmlkZWQgKGFuZCBpZiBncmVhdGVyIHRoYW4gdGhlXG4gICAqICAgICBuYXR1cmFsIGVuZGluZyBpbmRleClcbiAgICovXG4gIHNwYW4oc3RhcnQ6IG51bWJlciwgYXJ0aWZpY2lhbEVuZEluZGV4PzogbnVtYmVyKTogUGFyc2VTcGFuIHtcbiAgICBsZXQgZW5kSW5kZXggPSB0aGlzLmN1cnJlbnRFbmRJbmRleDtcbiAgICBpZiAoYXJ0aWZpY2lhbEVuZEluZGV4ICE9PSB1bmRlZmluZWQgJiYgYXJ0aWZpY2lhbEVuZEluZGV4ID4gdGhpcy5jdXJyZW50RW5kSW5kZXgpIHtcbiAgICAgIGVuZEluZGV4ID0gYXJ0aWZpY2lhbEVuZEluZGV4O1xuICAgIH1cblxuICAgIC8vIEluIHNvbWUgdW51c3VhbCBwYXJzaW5nIHNjZW5hcmlvcyAobGlrZSB3aGVuIGNlcnRhaW4gdG9rZW5zIGFyZSBtaXNzaW5nIGFuZCBhbiBgRW1wdHlFeHByYCBpc1xuICAgIC8vIGJlaW5nIGNyZWF0ZWQpLCB0aGUgY3VycmVudCB0b2tlbiBtYXkgYWxyZWFkeSBiZSBhZHZhbmNlZCBiZXlvbmQgdGhlIGBjdXJyZW50RW5kSW5kZXhgLiBUaGlzXG4gICAgLy8gYXBwZWFycyB0byBiZSBhIGRlZXAtc2VhdGVkIHBhcnNlciBidWcuXG4gICAgLy9cbiAgICAvLyBBcyBhIHdvcmthcm91bmQgZm9yIG5vdywgc3dhcCB0aGUgc3RhcnQgYW5kIGVuZCBpbmRpY2VzIHRvIGVuc3VyZSBhIHZhbGlkIGBQYXJzZVNwYW5gLlxuICAgIC8vIFRPRE8oYWx4aHViKTogZml4IHRoZSBidWcgdXBzdHJlYW0gaW4gdGhlIHBhcnNlciBzdGF0ZSwgYW5kIHJlbW92ZSB0aGlzIHdvcmthcm91bmQuXG4gICAgaWYgKHN0YXJ0ID4gZW5kSW5kZXgpIHtcbiAgICAgIGNvbnN0IHRtcCA9IGVuZEluZGV4O1xuICAgICAgZW5kSW5kZXggPSBzdGFydDtcbiAgICAgIHN0YXJ0ID0gdG1wO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgUGFyc2VTcGFuKHN0YXJ0LCBlbmRJbmRleCk7XG4gIH1cblxuICBzb3VyY2VTcGFuKHN0YXJ0OiBudW1iZXIsIGFydGlmaWNpYWxFbmRJbmRleD86IG51bWJlcik6IEFic29sdXRlU291cmNlU3BhbiB7XG4gICAgY29uc3Qgc2VyaWFsID0gYCR7c3RhcnR9QCR7dGhpcy5pbnB1dEluZGV4fToke2FydGlmaWNpYWxFbmRJbmRleH1gO1xuICAgIGlmICghdGhpcy5zb3VyY2VTcGFuQ2FjaGUuaGFzKHNlcmlhbCkpIHtcbiAgICAgIHRoaXMuc291cmNlU3BhbkNhY2hlLnNldChcbiAgICAgICAgICBzZXJpYWwsIHRoaXMuc3BhbihzdGFydCwgYXJ0aWZpY2lhbEVuZEluZGV4KS50b0Fic29sdXRlKHRoaXMuYWJzb2x1dGVPZmZzZXQpKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuc291cmNlU3BhbkNhY2hlLmdldChzZXJpYWwpITtcbiAgfVxuXG4gIGFkdmFuY2UoKSB7XG4gICAgdGhpcy5pbmRleCsrO1xuICB9XG5cbiAgLyoqXG4gICAqIEV4ZWN1dGVzIGEgY2FsbGJhY2sgaW4gdGhlIHByb3ZpZGVkIGNvbnRleHQuXG4gICAqL1xuICBwcml2YXRlIHdpdGhDb250ZXh0PFQ+KGNvbnRleHQ6IFBhcnNlQ29udGV4dEZsYWdzLCBjYjogKCkgPT4gVCk6IFQge1xuICAgIHRoaXMuY29udGV4dCB8PSBjb250ZXh0O1xuICAgIGNvbnN0IHJldCA9IGNiKCk7XG4gICAgdGhpcy5jb250ZXh0IF49IGNvbnRleHQ7XG4gICAgcmV0dXJuIHJldDtcbiAgfVxuXG4gIGNvbnN1bWVPcHRpb25hbENoYXJhY3Rlcihjb2RlOiBudW1iZXIpOiBib29sZWFuIHtcbiAgICBpZiAodGhpcy5uZXh0LmlzQ2hhcmFjdGVyKGNvZGUpKSB7XG4gICAgICB0aGlzLmFkdmFuY2UoKTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgcGVla0tleXdvcmRMZXQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMubmV4dC5pc0tleXdvcmRMZXQoKTtcbiAgfVxuICBwZWVrS2V5d29yZEFzKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLm5leHQuaXNLZXl3b3JkQXMoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb25zdW1lcyBhbiBleHBlY3RlZCBjaGFyYWN0ZXIsIG90aGVyd2lzZSBlbWl0cyBhbiBlcnJvciBhYm91dCB0aGUgbWlzc2luZyBleHBlY3RlZCBjaGFyYWN0ZXJcbiAgICogYW5kIHNraXBzIG92ZXIgdGhlIHRva2VuIHN0cmVhbSB1bnRpbCByZWFjaGluZyBhIHJlY292ZXJhYmxlIHBvaW50LlxuICAgKlxuICAgKiBTZWUgYHRoaXMuZXJyb3JgIGFuZCBgdGhpcy5za2lwYCBmb3IgbW9yZSBkZXRhaWxzLlxuICAgKi9cbiAgZXhwZWN0Q2hhcmFjdGVyKGNvZGU6IG51bWJlcikge1xuICAgIGlmICh0aGlzLmNvbnN1bWVPcHRpb25hbENoYXJhY3Rlcihjb2RlKSkgcmV0dXJuO1xuICAgIHRoaXMuZXJyb3IoYE1pc3NpbmcgZXhwZWN0ZWQgJHtTdHJpbmcuZnJvbUNoYXJDb2RlKGNvZGUpfWApO1xuICB9XG5cbiAgY29uc3VtZU9wdGlvbmFsT3BlcmF0b3Iob3A6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGlmICh0aGlzLm5leHQuaXNPcGVyYXRvcihvcCkpIHtcbiAgICAgIHRoaXMuYWR2YW5jZSgpO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICBleHBlY3RPcGVyYXRvcihvcGVyYXRvcjogc3RyaW5nKSB7XG4gICAgaWYgKHRoaXMuY29uc3VtZU9wdGlvbmFsT3BlcmF0b3Iob3BlcmF0b3IpKSByZXR1cm47XG4gICAgdGhpcy5lcnJvcihgTWlzc2luZyBleHBlY3RlZCBvcGVyYXRvciAke29wZXJhdG9yfWApO1xuICB9XG5cbiAgcHJldHR5UHJpbnRUb2tlbih0b2s6IFRva2VuKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdG9rID09PSBFT0YgPyAnZW5kIG9mIGlucHV0JyA6IGB0b2tlbiAke3Rva31gO1xuICB9XG5cbiAgZXhwZWN0SWRlbnRpZmllck9yS2V5d29yZCgpOiBzdHJpbmd8bnVsbCB7XG4gICAgY29uc3QgbiA9IHRoaXMubmV4dDtcbiAgICBpZiAoIW4uaXNJZGVudGlmaWVyKCkgJiYgIW4uaXNLZXl3b3JkKCkpIHtcbiAgICAgIGlmIChuLmlzUHJpdmF0ZUlkZW50aWZpZXIoKSkge1xuICAgICAgICB0aGlzLl9yZXBvcnRFcnJvckZvclByaXZhdGVJZGVudGlmaWVyKG4sICdleHBlY3RlZCBpZGVudGlmaWVyIG9yIGtleXdvcmQnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuZXJyb3IoYFVuZXhwZWN0ZWQgJHt0aGlzLnByZXR0eVByaW50VG9rZW4obil9LCBleHBlY3RlZCBpZGVudGlmaWVyIG9yIGtleXdvcmRgKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICB0aGlzLmFkdmFuY2UoKTtcbiAgICByZXR1cm4gbi50b1N0cmluZygpIGFzIHN0cmluZztcbiAgfVxuXG4gIGV4cGVjdElkZW50aWZpZXJPcktleXdvcmRPclN0cmluZygpOiBzdHJpbmcge1xuICAgIGNvbnN0IG4gPSB0aGlzLm5leHQ7XG4gICAgaWYgKCFuLmlzSWRlbnRpZmllcigpICYmICFuLmlzS2V5d29yZCgpICYmICFuLmlzU3RyaW5nKCkpIHtcbiAgICAgIGlmIChuLmlzUHJpdmF0ZUlkZW50aWZpZXIoKSkge1xuICAgICAgICB0aGlzLl9yZXBvcnRFcnJvckZvclByaXZhdGVJZGVudGlmaWVyKG4sICdleHBlY3RlZCBpZGVudGlmaWVyLCBrZXl3b3JkIG9yIHN0cmluZycpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5lcnJvcihcbiAgICAgICAgICAgIGBVbmV4cGVjdGVkICR7dGhpcy5wcmV0dHlQcmludFRva2VuKG4pfSwgZXhwZWN0ZWQgaWRlbnRpZmllciwga2V5d29yZCwgb3Igc3RyaW5nYCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gJyc7XG4gICAgfVxuICAgIHRoaXMuYWR2YW5jZSgpO1xuICAgIHJldHVybiBuLnRvU3RyaW5nKCkgYXMgc3RyaW5nO1xuICB9XG5cbiAgcGFyc2VDaGFpbigpOiBBU1Qge1xuICAgIGNvbnN0IGV4cHJzOiBBU1RbXSA9IFtdO1xuICAgIGNvbnN0IHN0YXJ0ID0gdGhpcy5pbnB1dEluZGV4O1xuICAgIHdoaWxlICh0aGlzLmluZGV4IDwgdGhpcy50b2tlbnMubGVuZ3RoKSB7XG4gICAgICBjb25zdCBleHByID0gdGhpcy5wYXJzZVBpcGUoKTtcbiAgICAgIGV4cHJzLnB1c2goZXhwcik7XG5cbiAgICAgIGlmICh0aGlzLmNvbnN1bWVPcHRpb25hbENoYXJhY3RlcihjaGFycy4kU0VNSUNPTE9OKSkge1xuICAgICAgICBpZiAoIXRoaXMucGFyc2VBY3Rpb24pIHtcbiAgICAgICAgICB0aGlzLmVycm9yKCdCaW5kaW5nIGV4cHJlc3Npb24gY2Fubm90IGNvbnRhaW4gY2hhaW5lZCBleHByZXNzaW9uJyk7XG4gICAgICAgIH1cbiAgICAgICAgd2hpbGUgKHRoaXMuY29uc3VtZU9wdGlvbmFsQ2hhcmFjdGVyKGNoYXJzLiRTRU1JQ09MT04pKSB7XG4gICAgICAgIH0gIC8vIHJlYWQgYWxsIHNlbWljb2xvbnNcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5pbmRleCA8IHRoaXMudG9rZW5zLmxlbmd0aCkge1xuICAgICAgICB0aGlzLmVycm9yKGBVbmV4cGVjdGVkIHRva2VuICcke3RoaXMubmV4dH0nYCk7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChleHBycy5sZW5ndGggPT0gMCkge1xuICAgICAgLy8gV2UgaGF2ZSBubyBleHByZXNzaW9ucyBzbyBjcmVhdGUgYW4gZW1wdHkgZXhwcmVzc2lvbiB0aGF0IHNwYW5zIHRoZSBlbnRpcmUgaW5wdXQgbGVuZ3RoXG4gICAgICBjb25zdCBhcnRpZmljaWFsU3RhcnQgPSB0aGlzLm9mZnNldDtcbiAgICAgIGNvbnN0IGFydGlmaWNpYWxFbmQgPSB0aGlzLm9mZnNldCArIHRoaXMuaW5wdXRMZW5ndGg7XG4gICAgICByZXR1cm4gbmV3IEVtcHR5RXhwcihcbiAgICAgICAgICB0aGlzLnNwYW4oYXJ0aWZpY2lhbFN0YXJ0LCBhcnRpZmljaWFsRW5kKSxcbiAgICAgICAgICB0aGlzLnNvdXJjZVNwYW4oYXJ0aWZpY2lhbFN0YXJ0LCBhcnRpZmljaWFsRW5kKSk7XG4gICAgfVxuICAgIGlmIChleHBycy5sZW5ndGggPT0gMSkgcmV0dXJuIGV4cHJzWzBdO1xuICAgIHJldHVybiBuZXcgQ2hhaW4odGhpcy5zcGFuKHN0YXJ0KSwgdGhpcy5zb3VyY2VTcGFuKHN0YXJ0KSwgZXhwcnMpO1xuICB9XG5cbiAgcGFyc2VQaXBlKCk6IEFTVCB7XG4gICAgY29uc3Qgc3RhcnQgPSB0aGlzLmlucHV0SW5kZXg7XG4gICAgbGV0IHJlc3VsdCA9IHRoaXMucGFyc2VFeHByZXNzaW9uKCk7XG4gICAgaWYgKHRoaXMuY29uc3VtZU9wdGlvbmFsT3BlcmF0b3IoJ3wnKSkge1xuICAgICAgaWYgKHRoaXMucGFyc2VBY3Rpb24pIHtcbiAgICAgICAgdGhpcy5lcnJvcignQ2Fubm90IGhhdmUgYSBwaXBlIGluIGFuIGFjdGlvbiBleHByZXNzaW9uJyk7XG4gICAgICB9XG5cbiAgICAgIGRvIHtcbiAgICAgICAgY29uc3QgbmFtZVN0YXJ0ID0gdGhpcy5pbnB1dEluZGV4O1xuICAgICAgICBsZXQgbmFtZUlkID0gdGhpcy5leHBlY3RJZGVudGlmaWVyT3JLZXl3b3JkKCk7XG4gICAgICAgIGxldCBuYW1lU3BhbjogQWJzb2x1dGVTb3VyY2VTcGFuO1xuICAgICAgICBsZXQgZnVsbFNwYW5FbmQ6IG51bWJlcnx1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG4gICAgICAgIGlmIChuYW1lSWQgIT09IG51bGwpIHtcbiAgICAgICAgICBuYW1lU3BhbiA9IHRoaXMuc291cmNlU3BhbihuYW1lU3RhcnQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIE5vIHZhbGlkIGlkZW50aWZpZXIgd2FzIGZvdW5kLCBzbyB3ZSdsbCBhc3N1bWUgYW4gZW1wdHkgcGlwZSBuYW1lICgnJykuXG4gICAgICAgICAgbmFtZUlkID0gJyc7XG5cbiAgICAgICAgICAvLyBIb3dldmVyLCB0aGVyZSBtYXkgaGF2ZSBiZWVuIHdoaXRlc3BhY2UgcHJlc2VudCBiZXR3ZWVuIHRoZSBwaXBlIGNoYXJhY3RlciBhbmQgdGhlIG5leHRcbiAgICAgICAgICAvLyB0b2tlbiBpbiB0aGUgc2VxdWVuY2UgKG9yIHRoZSBlbmQgb2YgaW5wdXQpLiBXZSB3YW50IHRvIHRyYWNrIHRoaXMgd2hpdGVzcGFjZSBzbyB0aGF0XG4gICAgICAgICAgLy8gdGhlIGBCaW5kaW5nUGlwZWAgd2UgcHJvZHVjZSBjb3ZlcnMgbm90IGp1c3QgdGhlIHBpcGUgY2hhcmFjdGVyLCBidXQgYW55IHRyYWlsaW5nXG4gICAgICAgICAgLy8gd2hpdGVzcGFjZSBiZXlvbmQgaXQuIEFub3RoZXIgd2F5IG9mIHRoaW5raW5nIGFib3V0IHRoaXMgaXMgdGhhdCB0aGUgemVyby1sZW5ndGggbmFtZVxuICAgICAgICAgIC8vIGlzIGFzc3VtZWQgdG8gYmUgYXQgdGhlIGVuZCBvZiBhbnkgd2hpdGVzcGFjZSBiZXlvbmQgdGhlIHBpcGUgY2hhcmFjdGVyLlxuICAgICAgICAgIC8vXG4gICAgICAgICAgLy8gVGhlcmVmb3JlLCB3ZSBwdXNoIHRoZSBlbmQgb2YgdGhlIGBQYXJzZVNwYW5gIGZvciB0aGlzIHBpcGUgYWxsIHRoZSB3YXkgdXAgdG8gdGhlXG4gICAgICAgICAgLy8gYmVnaW5uaW5nIG9mIHRoZSBuZXh0IHRva2VuLCBvciB1bnRpbCB0aGUgZW5kIG9mIGlucHV0IGlmIHRoZSBuZXh0IHRva2VuIGlzIEVPRi5cbiAgICAgICAgICBmdWxsU3BhbkVuZCA9IHRoaXMubmV4dC5pbmRleCAhPT0gLTEgPyB0aGlzLm5leHQuaW5kZXggOiB0aGlzLmlucHV0TGVuZ3RoICsgdGhpcy5vZmZzZXQ7XG5cbiAgICAgICAgICAvLyBUaGUgYG5hbWVTcGFuYCBmb3IgYW4gZW1wdHkgcGlwZSBuYW1lIGlzIHplcm8tbGVuZ3RoIGF0IHRoZSBlbmQgb2YgYW55IHdoaXRlc3BhY2VcbiAgICAgICAgICAvLyBiZXlvbmQgdGhlIHBpcGUgY2hhcmFjdGVyLlxuICAgICAgICAgIG5hbWVTcGFuID0gbmV3IFBhcnNlU3BhbihmdWxsU3BhbkVuZCwgZnVsbFNwYW5FbmQpLnRvQWJzb2x1dGUodGhpcy5hYnNvbHV0ZU9mZnNldCk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBhcmdzOiBBU1RbXSA9IFtdO1xuICAgICAgICB3aGlsZSAodGhpcy5jb25zdW1lT3B0aW9uYWxDaGFyYWN0ZXIoY2hhcnMuJENPTE9OKSkge1xuICAgICAgICAgIGFyZ3MucHVzaCh0aGlzLnBhcnNlRXhwcmVzc2lvbigpKTtcblxuICAgICAgICAgIC8vIElmIHRoZXJlIGFyZSBhZGRpdGlvbmFsIGV4cHJlc3Npb25zIGJleW9uZCB0aGUgbmFtZSwgdGhlbiB0aGUgYXJ0aWZpY2lhbCBlbmQgZm9yIHRoZVxuICAgICAgICAgIC8vIG5hbWUgaXMgbm8gbG9uZ2VyIHJlbGV2YW50LlxuICAgICAgICB9XG4gICAgICAgIHJlc3VsdCA9IG5ldyBCaW5kaW5nUGlwZShcbiAgICAgICAgICAgIHRoaXMuc3BhbihzdGFydCksIHRoaXMuc291cmNlU3BhbihzdGFydCwgZnVsbFNwYW5FbmQpLCByZXN1bHQsIG5hbWVJZCwgYXJncywgbmFtZVNwYW4pO1xuICAgICAgfSB3aGlsZSAodGhpcy5jb25zdW1lT3B0aW9uYWxPcGVyYXRvcignfCcpKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgcGFyc2VFeHByZXNzaW9uKCk6IEFTVCB7XG4gICAgcmV0dXJuIHRoaXMucGFyc2VDb25kaXRpb25hbCgpO1xuICB9XG5cbiAgcGFyc2VDb25kaXRpb25hbCgpOiBBU1Qge1xuICAgIGNvbnN0IHN0YXJ0ID0gdGhpcy5pbnB1dEluZGV4O1xuICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMucGFyc2VMb2dpY2FsT3IoKTtcblxuICAgIGlmICh0aGlzLmNvbnN1bWVPcHRpb25hbE9wZXJhdG9yKCc/JykpIHtcbiAgICAgIGNvbnN0IHllcyA9IHRoaXMucGFyc2VQaXBlKCk7XG4gICAgICBsZXQgbm86IEFTVDtcbiAgICAgIGlmICghdGhpcy5jb25zdW1lT3B0aW9uYWxDaGFyYWN0ZXIoY2hhcnMuJENPTE9OKSkge1xuICAgICAgICBjb25zdCBlbmQgPSB0aGlzLmlucHV0SW5kZXg7XG4gICAgICAgIGNvbnN0IGV4cHJlc3Npb24gPSB0aGlzLmlucHV0LnN1YnN0cmluZyhzdGFydCwgZW5kKTtcbiAgICAgICAgdGhpcy5lcnJvcihgQ29uZGl0aW9uYWwgZXhwcmVzc2lvbiAke2V4cHJlc3Npb259IHJlcXVpcmVzIGFsbCAzIGV4cHJlc3Npb25zYCk7XG4gICAgICAgIG5vID0gbmV3IEVtcHR5RXhwcih0aGlzLnNwYW4oc3RhcnQpLCB0aGlzLnNvdXJjZVNwYW4oc3RhcnQpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG5vID0gdGhpcy5wYXJzZVBpcGUoKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBuZXcgQ29uZGl0aW9uYWwodGhpcy5zcGFuKHN0YXJ0KSwgdGhpcy5zb3VyY2VTcGFuKHN0YXJ0KSwgcmVzdWx0LCB5ZXMsIG5vKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG4gIH1cblxuICBwYXJzZUxvZ2ljYWxPcigpOiBBU1Qge1xuICAgIC8vICd8fCdcbiAgICBjb25zdCBzdGFydCA9IHRoaXMuaW5wdXRJbmRleDtcbiAgICBsZXQgcmVzdWx0ID0gdGhpcy5wYXJzZUxvZ2ljYWxBbmQoKTtcbiAgICB3aGlsZSAodGhpcy5jb25zdW1lT3B0aW9uYWxPcGVyYXRvcignfHwnKSkge1xuICAgICAgY29uc3QgcmlnaHQgPSB0aGlzLnBhcnNlTG9naWNhbEFuZCgpO1xuICAgICAgcmVzdWx0ID0gbmV3IEJpbmFyeSh0aGlzLnNwYW4oc3RhcnQpLCB0aGlzLnNvdXJjZVNwYW4oc3RhcnQpLCAnfHwnLCByZXN1bHQsIHJpZ2h0KTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIHBhcnNlTG9naWNhbEFuZCgpOiBBU1Qge1xuICAgIC8vICcmJidcbiAgICBjb25zdCBzdGFydCA9IHRoaXMuaW5wdXRJbmRleDtcbiAgICBsZXQgcmVzdWx0ID0gdGhpcy5wYXJzZU51bGxpc2hDb2FsZXNjaW5nKCk7XG4gICAgd2hpbGUgKHRoaXMuY29uc3VtZU9wdGlvbmFsT3BlcmF0b3IoJyYmJykpIHtcbiAgICAgIGNvbnN0IHJpZ2h0ID0gdGhpcy5wYXJzZU51bGxpc2hDb2FsZXNjaW5nKCk7XG4gICAgICByZXN1bHQgPSBuZXcgQmluYXJ5KHRoaXMuc3BhbihzdGFydCksIHRoaXMuc291cmNlU3BhbihzdGFydCksICcmJicsIHJlc3VsdCwgcmlnaHQpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgcGFyc2VOdWxsaXNoQ29hbGVzY2luZygpOiBBU1Qge1xuICAgIC8vICc/PydcbiAgICBjb25zdCBzdGFydCA9IHRoaXMuaW5wdXRJbmRleDtcbiAgICBsZXQgcmVzdWx0ID0gdGhpcy5wYXJzZUVxdWFsaXR5KCk7XG4gICAgd2hpbGUgKHRoaXMuY29uc3VtZU9wdGlvbmFsT3BlcmF0b3IoJz8/JykpIHtcbiAgICAgIGNvbnN0IHJpZ2h0ID0gdGhpcy5wYXJzZUVxdWFsaXR5KCk7XG4gICAgICByZXN1bHQgPSBuZXcgQmluYXJ5KHRoaXMuc3BhbihzdGFydCksIHRoaXMuc291cmNlU3BhbihzdGFydCksICc/PycsIHJlc3VsdCwgcmlnaHQpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgcGFyc2VFcXVhbGl0eSgpOiBBU1Qge1xuICAgIC8vICc9PScsJyE9JywnPT09JywnIT09J1xuICAgIGNvbnN0IHN0YXJ0ID0gdGhpcy5pbnB1dEluZGV4O1xuICAgIGxldCByZXN1bHQgPSB0aGlzLnBhcnNlUmVsYXRpb25hbCgpO1xuICAgIHdoaWxlICh0aGlzLm5leHQudHlwZSA9PSBUb2tlblR5cGUuT3BlcmF0b3IpIHtcbiAgICAgIGNvbnN0IG9wZXJhdG9yID0gdGhpcy5uZXh0LnN0clZhbHVlO1xuICAgICAgc3dpdGNoIChvcGVyYXRvcikge1xuICAgICAgICBjYXNlICc9PSc6XG4gICAgICAgIGNhc2UgJz09PSc6XG4gICAgICAgIGNhc2UgJyE9JzpcbiAgICAgICAgY2FzZSAnIT09JzpcbiAgICAgICAgICB0aGlzLmFkdmFuY2UoKTtcbiAgICAgICAgICBjb25zdCByaWdodCA9IHRoaXMucGFyc2VSZWxhdGlvbmFsKCk7XG4gICAgICAgICAgcmVzdWx0ID0gbmV3IEJpbmFyeSh0aGlzLnNwYW4oc3RhcnQpLCB0aGlzLnNvdXJjZVNwYW4oc3RhcnQpLCBvcGVyYXRvciwgcmVzdWx0LCByaWdodCk7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBicmVhaztcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIHBhcnNlUmVsYXRpb25hbCgpOiBBU1Qge1xuICAgIC8vICc8JywgJz4nLCAnPD0nLCAnPj0nXG4gICAgY29uc3Qgc3RhcnQgPSB0aGlzLmlucHV0SW5kZXg7XG4gICAgbGV0IHJlc3VsdCA9IHRoaXMucGFyc2VBZGRpdGl2ZSgpO1xuICAgIHdoaWxlICh0aGlzLm5leHQudHlwZSA9PSBUb2tlblR5cGUuT3BlcmF0b3IpIHtcbiAgICAgIGNvbnN0IG9wZXJhdG9yID0gdGhpcy5uZXh0LnN0clZhbHVlO1xuICAgICAgc3dpdGNoIChvcGVyYXRvcikge1xuICAgICAgICBjYXNlICc8JzpcbiAgICAgICAgY2FzZSAnPic6XG4gICAgICAgIGNhc2UgJzw9JzpcbiAgICAgICAgY2FzZSAnPj0nOlxuICAgICAgICAgIHRoaXMuYWR2YW5jZSgpO1xuICAgICAgICAgIGNvbnN0IHJpZ2h0ID0gdGhpcy5wYXJzZUFkZGl0aXZlKCk7XG4gICAgICAgICAgcmVzdWx0ID0gbmV3IEJpbmFyeSh0aGlzLnNwYW4oc3RhcnQpLCB0aGlzLnNvdXJjZVNwYW4oc3RhcnQpLCBvcGVyYXRvciwgcmVzdWx0LCByaWdodCk7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBicmVhaztcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIHBhcnNlQWRkaXRpdmUoKTogQVNUIHtcbiAgICAvLyAnKycsICctJ1xuICAgIGNvbnN0IHN0YXJ0ID0gdGhpcy5pbnB1dEluZGV4O1xuICAgIGxldCByZXN1bHQgPSB0aGlzLnBhcnNlTXVsdGlwbGljYXRpdmUoKTtcbiAgICB3aGlsZSAodGhpcy5uZXh0LnR5cGUgPT0gVG9rZW5UeXBlLk9wZXJhdG9yKSB7XG4gICAgICBjb25zdCBvcGVyYXRvciA9IHRoaXMubmV4dC5zdHJWYWx1ZTtcbiAgICAgIHN3aXRjaCAob3BlcmF0b3IpIHtcbiAgICAgICAgY2FzZSAnKyc6XG4gICAgICAgIGNhc2UgJy0nOlxuICAgICAgICAgIHRoaXMuYWR2YW5jZSgpO1xuICAgICAgICAgIGxldCByaWdodCA9IHRoaXMucGFyc2VNdWx0aXBsaWNhdGl2ZSgpO1xuICAgICAgICAgIHJlc3VsdCA9IG5ldyBCaW5hcnkodGhpcy5zcGFuKHN0YXJ0KSwgdGhpcy5zb3VyY2VTcGFuKHN0YXJ0KSwgb3BlcmF0b3IsIHJlc3VsdCwgcmlnaHQpO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgYnJlYWs7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBwYXJzZU11bHRpcGxpY2F0aXZlKCk6IEFTVCB7XG4gICAgLy8gJyonLCAnJScsICcvJ1xuICAgIGNvbnN0IHN0YXJ0ID0gdGhpcy5pbnB1dEluZGV4O1xuICAgIGxldCByZXN1bHQgPSB0aGlzLnBhcnNlUHJlZml4KCk7XG4gICAgd2hpbGUgKHRoaXMubmV4dC50eXBlID09IFRva2VuVHlwZS5PcGVyYXRvcikge1xuICAgICAgY29uc3Qgb3BlcmF0b3IgPSB0aGlzLm5leHQuc3RyVmFsdWU7XG4gICAgICBzd2l0Y2ggKG9wZXJhdG9yKSB7XG4gICAgICAgIGNhc2UgJyonOlxuICAgICAgICBjYXNlICclJzpcbiAgICAgICAgY2FzZSAnLyc6XG4gICAgICAgICAgdGhpcy5hZHZhbmNlKCk7XG4gICAgICAgICAgbGV0IHJpZ2h0ID0gdGhpcy5wYXJzZVByZWZpeCgpO1xuICAgICAgICAgIHJlc3VsdCA9IG5ldyBCaW5hcnkodGhpcy5zcGFuKHN0YXJ0KSwgdGhpcy5zb3VyY2VTcGFuKHN0YXJ0KSwgb3BlcmF0b3IsIHJlc3VsdCwgcmlnaHQpO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgYnJlYWs7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBwYXJzZVByZWZpeCgpOiBBU1Qge1xuICAgIGlmICh0aGlzLm5leHQudHlwZSA9PSBUb2tlblR5cGUuT3BlcmF0b3IpIHtcbiAgICAgIGNvbnN0IHN0YXJ0ID0gdGhpcy5pbnB1dEluZGV4O1xuICAgICAgY29uc3Qgb3BlcmF0b3IgPSB0aGlzLm5leHQuc3RyVmFsdWU7XG4gICAgICBsZXQgcmVzdWx0OiBBU1Q7XG4gICAgICBzd2l0Y2ggKG9wZXJhdG9yKSB7XG4gICAgICAgIGNhc2UgJysnOlxuICAgICAgICAgIHRoaXMuYWR2YW5jZSgpO1xuICAgICAgICAgIHJlc3VsdCA9IHRoaXMucGFyc2VQcmVmaXgoKTtcbiAgICAgICAgICByZXR1cm4gVW5hcnkuY3JlYXRlUGx1cyh0aGlzLnNwYW4oc3RhcnQpLCB0aGlzLnNvdXJjZVNwYW4oc3RhcnQpLCByZXN1bHQpO1xuICAgICAgICBjYXNlICctJzpcbiAgICAgICAgICB0aGlzLmFkdmFuY2UoKTtcbiAgICAgICAgICByZXN1bHQgPSB0aGlzLnBhcnNlUHJlZml4KCk7XG4gICAgICAgICAgcmV0dXJuIFVuYXJ5LmNyZWF0ZU1pbnVzKHRoaXMuc3BhbihzdGFydCksIHRoaXMuc291cmNlU3BhbihzdGFydCksIHJlc3VsdCk7XG4gICAgICAgIGNhc2UgJyEnOlxuICAgICAgICAgIHRoaXMuYWR2YW5jZSgpO1xuICAgICAgICAgIHJlc3VsdCA9IHRoaXMucGFyc2VQcmVmaXgoKTtcbiAgICAgICAgICByZXR1cm4gbmV3IFByZWZpeE5vdCh0aGlzLnNwYW4oc3RhcnQpLCB0aGlzLnNvdXJjZVNwYW4oc3RhcnQpLCByZXN1bHQpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdGhpcy5wYXJzZUNhbGxDaGFpbigpO1xuICB9XG5cbiAgcGFyc2VDYWxsQ2hhaW4oKTogQVNUIHtcbiAgICBjb25zdCBzdGFydCA9IHRoaXMuaW5wdXRJbmRleDtcbiAgICBsZXQgcmVzdWx0ID0gdGhpcy5wYXJzZVByaW1hcnkoKTtcbiAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgaWYgKHRoaXMuY29uc3VtZU9wdGlvbmFsQ2hhcmFjdGVyKGNoYXJzLiRQRVJJT0QpKSB7XG4gICAgICAgIHJlc3VsdCA9IHRoaXMucGFyc2VBY2Nlc3NNZW1iZXJPck1ldGhvZENhbGwocmVzdWx0LCBzdGFydCwgZmFsc2UpO1xuXG4gICAgICB9IGVsc2UgaWYgKHRoaXMuY29uc3VtZU9wdGlvbmFsT3BlcmF0b3IoJz8uJykpIHtcbiAgICAgICAgcmVzdWx0ID0gdGhpcy5jb25zdW1lT3B0aW9uYWxDaGFyYWN0ZXIoY2hhcnMuJExCUkFDS0VUKSA/XG4gICAgICAgICAgICB0aGlzLnBhcnNlS2V5ZWRSZWFkT3JXcml0ZShyZXN1bHQsIHN0YXJ0LCB0cnVlKSA6XG4gICAgICAgICAgICB0aGlzLnBhcnNlQWNjZXNzTWVtYmVyT3JNZXRob2RDYWxsKHJlc3VsdCwgc3RhcnQsIHRydWUpO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLmNvbnN1bWVPcHRpb25hbENoYXJhY3RlcihjaGFycy4kTEJSQUNLRVQpKSB7XG4gICAgICAgIHJlc3VsdCA9IHRoaXMucGFyc2VLZXllZFJlYWRPcldyaXRlKHJlc3VsdCwgc3RhcnQsIGZhbHNlKTtcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5jb25zdW1lT3B0aW9uYWxDaGFyYWN0ZXIoY2hhcnMuJExQQVJFTikpIHtcbiAgICAgICAgdGhpcy5ycGFyZW5zRXhwZWN0ZWQrKztcbiAgICAgICAgY29uc3QgYXJncyA9IHRoaXMucGFyc2VDYWxsQXJndW1lbnRzKCk7XG4gICAgICAgIHRoaXMucnBhcmVuc0V4cGVjdGVkLS07XG4gICAgICAgIHRoaXMuZXhwZWN0Q2hhcmFjdGVyKGNoYXJzLiRSUEFSRU4pO1xuICAgICAgICByZXN1bHQgPSBuZXcgRnVuY3Rpb25DYWxsKHRoaXMuc3BhbihzdGFydCksIHRoaXMuc291cmNlU3BhbihzdGFydCksIHJlc3VsdCwgYXJncyk7XG5cbiAgICAgIH0gZWxzZSBpZiAodGhpcy5jb25zdW1lT3B0aW9uYWxPcGVyYXRvcignIScpKSB7XG4gICAgICAgIHJlc3VsdCA9IG5ldyBOb25OdWxsQXNzZXJ0KHRoaXMuc3BhbihzdGFydCksIHRoaXMuc291cmNlU3BhbihzdGFydCksIHJlc3VsdCk7XG5cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcGFyc2VQcmltYXJ5KCk6IEFTVCB7XG4gICAgY29uc3Qgc3RhcnQgPSB0aGlzLmlucHV0SW5kZXg7XG4gICAgaWYgKHRoaXMuY29uc3VtZU9wdGlvbmFsQ2hhcmFjdGVyKGNoYXJzLiRMUEFSRU4pKSB7XG4gICAgICB0aGlzLnJwYXJlbnNFeHBlY3RlZCsrO1xuICAgICAgY29uc3QgcmVzdWx0ID0gdGhpcy5wYXJzZVBpcGUoKTtcbiAgICAgIHRoaXMucnBhcmVuc0V4cGVjdGVkLS07XG4gICAgICB0aGlzLmV4cGVjdENoYXJhY3RlcihjaGFycy4kUlBBUkVOKTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG5cbiAgICB9IGVsc2UgaWYgKHRoaXMubmV4dC5pc0tleXdvcmROdWxsKCkpIHtcbiAgICAgIHRoaXMuYWR2YW5jZSgpO1xuICAgICAgcmV0dXJuIG5ldyBMaXRlcmFsUHJpbWl0aXZlKHRoaXMuc3BhbihzdGFydCksIHRoaXMuc291cmNlU3BhbihzdGFydCksIG51bGwpO1xuXG4gICAgfSBlbHNlIGlmICh0aGlzLm5leHQuaXNLZXl3b3JkVW5kZWZpbmVkKCkpIHtcbiAgICAgIHRoaXMuYWR2YW5jZSgpO1xuICAgICAgcmV0dXJuIG5ldyBMaXRlcmFsUHJpbWl0aXZlKHRoaXMuc3BhbihzdGFydCksIHRoaXMuc291cmNlU3BhbihzdGFydCksIHZvaWQgMCk7XG5cbiAgICB9IGVsc2UgaWYgKHRoaXMubmV4dC5pc0tleXdvcmRUcnVlKCkpIHtcbiAgICAgIHRoaXMuYWR2YW5jZSgpO1xuICAgICAgcmV0dXJuIG5ldyBMaXRlcmFsUHJpbWl0aXZlKHRoaXMuc3BhbihzdGFydCksIHRoaXMuc291cmNlU3BhbihzdGFydCksIHRydWUpO1xuXG4gICAgfSBlbHNlIGlmICh0aGlzLm5leHQuaXNLZXl3b3JkRmFsc2UoKSkge1xuICAgICAgdGhpcy5hZHZhbmNlKCk7XG4gICAgICByZXR1cm4gbmV3IExpdGVyYWxQcmltaXRpdmUodGhpcy5zcGFuKHN0YXJ0KSwgdGhpcy5zb3VyY2VTcGFuKHN0YXJ0KSwgZmFsc2UpO1xuXG4gICAgfSBlbHNlIGlmICh0aGlzLm5leHQuaXNLZXl3b3JkVGhpcygpKSB7XG4gICAgICB0aGlzLmFkdmFuY2UoKTtcbiAgICAgIHJldHVybiBuZXcgVGhpc1JlY2VpdmVyKHRoaXMuc3BhbihzdGFydCksIHRoaXMuc291cmNlU3BhbihzdGFydCkpO1xuICAgIH0gZWxzZSBpZiAodGhpcy5jb25zdW1lT3B0aW9uYWxDaGFyYWN0ZXIoY2hhcnMuJExCUkFDS0VUKSkge1xuICAgICAgdGhpcy5yYnJhY2tldHNFeHBlY3RlZCsrO1xuICAgICAgY29uc3QgZWxlbWVudHMgPSB0aGlzLnBhcnNlRXhwcmVzc2lvbkxpc3QoY2hhcnMuJFJCUkFDS0VUKTtcbiAgICAgIHRoaXMucmJyYWNrZXRzRXhwZWN0ZWQtLTtcbiAgICAgIHRoaXMuZXhwZWN0Q2hhcmFjdGVyKGNoYXJzLiRSQlJBQ0tFVCk7XG4gICAgICByZXR1cm4gbmV3IExpdGVyYWxBcnJheSh0aGlzLnNwYW4oc3RhcnQpLCB0aGlzLnNvdXJjZVNwYW4oc3RhcnQpLCBlbGVtZW50cyk7XG5cbiAgICB9IGVsc2UgaWYgKHRoaXMubmV4dC5pc0NoYXJhY3RlcihjaGFycy4kTEJSQUNFKSkge1xuICAgICAgcmV0dXJuIHRoaXMucGFyc2VMaXRlcmFsTWFwKCk7XG5cbiAgICB9IGVsc2UgaWYgKHRoaXMubmV4dC5pc0lkZW50aWZpZXIoKSkge1xuICAgICAgcmV0dXJuIHRoaXMucGFyc2VBY2Nlc3NNZW1iZXJPck1ldGhvZENhbGwoXG4gICAgICAgICAgbmV3IEltcGxpY2l0UmVjZWl2ZXIodGhpcy5zcGFuKHN0YXJ0KSwgdGhpcy5zb3VyY2VTcGFuKHN0YXJ0KSksIHN0YXJ0LCBmYWxzZSk7XG5cbiAgICB9IGVsc2UgaWYgKHRoaXMubmV4dC5pc051bWJlcigpKSB7XG4gICAgICBjb25zdCB2YWx1ZSA9IHRoaXMubmV4dC50b051bWJlcigpO1xuICAgICAgdGhpcy5hZHZhbmNlKCk7XG4gICAgICByZXR1cm4gbmV3IExpdGVyYWxQcmltaXRpdmUodGhpcy5zcGFuKHN0YXJ0KSwgdGhpcy5zb3VyY2VTcGFuKHN0YXJ0KSwgdmFsdWUpO1xuXG4gICAgfSBlbHNlIGlmICh0aGlzLm5leHQuaXNTdHJpbmcoKSkge1xuICAgICAgY29uc3QgbGl0ZXJhbFZhbHVlID0gdGhpcy5uZXh0LnRvU3RyaW5nKCk7XG4gICAgICB0aGlzLmFkdmFuY2UoKTtcbiAgICAgIHJldHVybiBuZXcgTGl0ZXJhbFByaW1pdGl2ZSh0aGlzLnNwYW4oc3RhcnQpLCB0aGlzLnNvdXJjZVNwYW4oc3RhcnQpLCBsaXRlcmFsVmFsdWUpO1xuXG4gICAgfSBlbHNlIGlmICh0aGlzLm5leHQuaXNQcml2YXRlSWRlbnRpZmllcigpKSB7XG4gICAgICB0aGlzLl9yZXBvcnRFcnJvckZvclByaXZhdGVJZGVudGlmaWVyKHRoaXMubmV4dCwgbnVsbCk7XG4gICAgICByZXR1cm4gbmV3IEVtcHR5RXhwcih0aGlzLnNwYW4oc3RhcnQpLCB0aGlzLnNvdXJjZVNwYW4oc3RhcnQpKTtcblxuICAgIH0gZWxzZSBpZiAodGhpcy5pbmRleCA+PSB0aGlzLnRva2Vucy5sZW5ndGgpIHtcbiAgICAgIHRoaXMuZXJyb3IoYFVuZXhwZWN0ZWQgZW5kIG9mIGV4cHJlc3Npb246ICR7dGhpcy5pbnB1dH1gKTtcbiAgICAgIHJldHVybiBuZXcgRW1wdHlFeHByKHRoaXMuc3BhbihzdGFydCksIHRoaXMuc291cmNlU3BhbihzdGFydCkpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmVycm9yKGBVbmV4cGVjdGVkIHRva2VuICR7dGhpcy5uZXh0fWApO1xuICAgICAgcmV0dXJuIG5ldyBFbXB0eUV4cHIodGhpcy5zcGFuKHN0YXJ0KSwgdGhpcy5zb3VyY2VTcGFuKHN0YXJ0KSk7XG4gICAgfVxuICB9XG5cbiAgcGFyc2VFeHByZXNzaW9uTGlzdCh0ZXJtaW5hdG9yOiBudW1iZXIpOiBBU1RbXSB7XG4gICAgY29uc3QgcmVzdWx0OiBBU1RbXSA9IFtdO1xuXG4gICAgZG8ge1xuICAgICAgaWYgKCF0aGlzLm5leHQuaXNDaGFyYWN0ZXIodGVybWluYXRvcikpIHtcbiAgICAgICAgcmVzdWx0LnB1c2godGhpcy5wYXJzZVBpcGUoKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9IHdoaWxlICh0aGlzLmNvbnN1bWVPcHRpb25hbENoYXJhY3RlcihjaGFycy4kQ09NTUEpKTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgcGFyc2VMaXRlcmFsTWFwKCk6IExpdGVyYWxNYXAge1xuICAgIGNvbnN0IGtleXM6IExpdGVyYWxNYXBLZXlbXSA9IFtdO1xuICAgIGNvbnN0IHZhbHVlczogQVNUW10gPSBbXTtcbiAgICBjb25zdCBzdGFydCA9IHRoaXMuaW5wdXRJbmRleDtcbiAgICB0aGlzLmV4cGVjdENoYXJhY3RlcihjaGFycy4kTEJSQUNFKTtcbiAgICBpZiAoIXRoaXMuY29uc3VtZU9wdGlvbmFsQ2hhcmFjdGVyKGNoYXJzLiRSQlJBQ0UpKSB7XG4gICAgICB0aGlzLnJicmFjZXNFeHBlY3RlZCsrO1xuICAgICAgZG8ge1xuICAgICAgICBjb25zdCBrZXlTdGFydCA9IHRoaXMuaW5wdXRJbmRleDtcbiAgICAgICAgY29uc3QgcXVvdGVkID0gdGhpcy5uZXh0LmlzU3RyaW5nKCk7XG4gICAgICAgIGNvbnN0IGtleSA9IHRoaXMuZXhwZWN0SWRlbnRpZmllck9yS2V5d29yZE9yU3RyaW5nKCk7XG4gICAgICAgIGtleXMucHVzaCh7a2V5LCBxdW90ZWR9KTtcblxuICAgICAgICAvLyBQcm9wZXJ0aWVzIHdpdGggcXVvdGVkIGtleXMgY2FuJ3QgdXNlIHRoZSBzaG9ydGhhbmQgc3ludGF4LlxuICAgICAgICBpZiAocXVvdGVkKSB7XG4gICAgICAgICAgdGhpcy5leHBlY3RDaGFyYWN0ZXIoY2hhcnMuJENPTE9OKTtcbiAgICAgICAgICB2YWx1ZXMucHVzaCh0aGlzLnBhcnNlUGlwZSgpKTtcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLmNvbnN1bWVPcHRpb25hbENoYXJhY3RlcihjaGFycy4kQ09MT04pKSB7XG4gICAgICAgICAgdmFsdWVzLnB1c2godGhpcy5wYXJzZVBpcGUoKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc3Qgc3BhbiA9IHRoaXMuc3BhbihrZXlTdGFydCk7XG4gICAgICAgICAgY29uc3Qgc291cmNlU3BhbiA9IHRoaXMuc291cmNlU3BhbihrZXlTdGFydCk7XG4gICAgICAgICAgdmFsdWVzLnB1c2gobmV3IFByb3BlcnR5UmVhZChcbiAgICAgICAgICAgICAgc3Bhbiwgc291cmNlU3Bhbiwgc291cmNlU3BhbiwgbmV3IEltcGxpY2l0UmVjZWl2ZXIoc3Bhbiwgc291cmNlU3BhbiksIGtleSkpO1xuICAgICAgICB9XG4gICAgICB9IHdoaWxlICh0aGlzLmNvbnN1bWVPcHRpb25hbENoYXJhY3RlcihjaGFycy4kQ09NTUEpKTtcbiAgICAgIHRoaXMucmJyYWNlc0V4cGVjdGVkLS07XG4gICAgICB0aGlzLmV4cGVjdENoYXJhY3RlcihjaGFycy4kUkJSQUNFKTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBMaXRlcmFsTWFwKHRoaXMuc3BhbihzdGFydCksIHRoaXMuc291cmNlU3BhbihzdGFydCksIGtleXMsIHZhbHVlcyk7XG4gIH1cblxuICBwYXJzZUFjY2Vzc01lbWJlck9yTWV0aG9kQ2FsbChyZWNlaXZlcjogQVNULCBzdGFydDogbnVtYmVyLCBpc1NhZmU6IGJvb2xlYW4pOiBBU1Qge1xuICAgIGNvbnN0IG5hbWVTdGFydCA9IHRoaXMuaW5wdXRJbmRleDtcbiAgICBjb25zdCBpZCA9IHRoaXMud2l0aENvbnRleHQoUGFyc2VDb250ZXh0RmxhZ3MuV3JpdGFibGUsICgpID0+IHtcbiAgICAgIGNvbnN0IGlkID0gdGhpcy5leHBlY3RJZGVudGlmaWVyT3JLZXl3b3JkKCkgPz8gJyc7XG4gICAgICBpZiAoaWQubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHRoaXMuZXJyb3IoYEV4cGVjdGVkIGlkZW50aWZpZXIgZm9yIHByb3BlcnR5IGFjY2Vzc2AsIHJlY2VpdmVyLnNwYW4uZW5kKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBpZDtcbiAgICB9KTtcbiAgICBjb25zdCBuYW1lU3BhbiA9IHRoaXMuc291cmNlU3BhbihuYW1lU3RhcnQpO1xuXG4gICAgaWYgKHRoaXMuY29uc3VtZU9wdGlvbmFsQ2hhcmFjdGVyKGNoYXJzLiRMUEFSRU4pKSB7XG4gICAgICBjb25zdCBhcmd1bWVudFN0YXJ0ID0gdGhpcy5pbnB1dEluZGV4O1xuICAgICAgdGhpcy5ycGFyZW5zRXhwZWN0ZWQrKztcbiAgICAgIGNvbnN0IGFyZ3MgPSB0aGlzLnBhcnNlQ2FsbEFyZ3VtZW50cygpO1xuICAgICAgY29uc3QgYXJndW1lbnRTcGFuID1cbiAgICAgICAgICB0aGlzLnNwYW4oYXJndW1lbnRTdGFydCwgdGhpcy5pbnB1dEluZGV4KS50b0Fic29sdXRlKHRoaXMuYWJzb2x1dGVPZmZzZXQpO1xuXG4gICAgICB0aGlzLmV4cGVjdENoYXJhY3RlcihjaGFycy4kUlBBUkVOKTtcbiAgICAgIHRoaXMucnBhcmVuc0V4cGVjdGVkLS07XG4gICAgICBjb25zdCBzcGFuID0gdGhpcy5zcGFuKHN0YXJ0KTtcbiAgICAgIGNvbnN0IHNvdXJjZVNwYW4gPSB0aGlzLnNvdXJjZVNwYW4oc3RhcnQpO1xuICAgICAgcmV0dXJuIGlzU2FmZSA/XG4gICAgICAgICAgbmV3IFNhZmVNZXRob2RDYWxsKHNwYW4sIHNvdXJjZVNwYW4sIG5hbWVTcGFuLCByZWNlaXZlciwgaWQsIGFyZ3MsIGFyZ3VtZW50U3BhbikgOlxuICAgICAgICAgIG5ldyBNZXRob2RDYWxsKHNwYW4sIHNvdXJjZVNwYW4sIG5hbWVTcGFuLCByZWNlaXZlciwgaWQsIGFyZ3MsIGFyZ3VtZW50U3Bhbik7XG5cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKGlzU2FmZSkge1xuICAgICAgICBpZiAodGhpcy5jb25zdW1lT3B0aW9uYWxPcGVyYXRvcignPScpKSB7XG4gICAgICAgICAgdGhpcy5lcnJvcignVGhlIFxcJz8uXFwnIG9wZXJhdG9yIGNhbm5vdCBiZSB1c2VkIGluIHRoZSBhc3NpZ25tZW50Jyk7XG4gICAgICAgICAgcmV0dXJuIG5ldyBFbXB0eUV4cHIodGhpcy5zcGFuKHN0YXJ0KSwgdGhpcy5zb3VyY2VTcGFuKHN0YXJ0KSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIG5ldyBTYWZlUHJvcGVydHlSZWFkKFxuICAgICAgICAgICAgICB0aGlzLnNwYW4oc3RhcnQpLCB0aGlzLnNvdXJjZVNwYW4oc3RhcnQpLCBuYW1lU3BhbiwgcmVjZWl2ZXIsIGlkKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKHRoaXMuY29uc3VtZU9wdGlvbmFsT3BlcmF0b3IoJz0nKSkge1xuICAgICAgICAgIGlmICghdGhpcy5wYXJzZUFjdGlvbikge1xuICAgICAgICAgICAgdGhpcy5lcnJvcignQmluZGluZ3MgY2Fubm90IGNvbnRhaW4gYXNzaWdubWVudHMnKTtcbiAgICAgICAgICAgIHJldHVybiBuZXcgRW1wdHlFeHByKHRoaXMuc3BhbihzdGFydCksIHRoaXMuc291cmNlU3BhbihzdGFydCkpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IHZhbHVlID0gdGhpcy5wYXJzZUNvbmRpdGlvbmFsKCk7XG4gICAgICAgICAgcmV0dXJuIG5ldyBQcm9wZXJ0eVdyaXRlKFxuICAgICAgICAgICAgICB0aGlzLnNwYW4oc3RhcnQpLCB0aGlzLnNvdXJjZVNwYW4oc3RhcnQpLCBuYW1lU3BhbiwgcmVjZWl2ZXIsIGlkLCB2YWx1ZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIG5ldyBQcm9wZXJ0eVJlYWQodGhpcy5zcGFuKHN0YXJ0KSwgdGhpcy5zb3VyY2VTcGFuKHN0YXJ0KSwgbmFtZVNwYW4sIHJlY2VpdmVyLCBpZCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwYXJzZUNhbGxBcmd1bWVudHMoKTogQmluZGluZ1BpcGVbXSB7XG4gICAgaWYgKHRoaXMubmV4dC5pc0NoYXJhY3RlcihjaGFycy4kUlBBUkVOKSkgcmV0dXJuIFtdO1xuICAgIGNvbnN0IHBvc2l0aW9uYWxzOiBBU1RbXSA9IFtdO1xuICAgIGRvIHtcbiAgICAgIHBvc2l0aW9uYWxzLnB1c2godGhpcy5wYXJzZVBpcGUoKSk7XG4gICAgfSB3aGlsZSAodGhpcy5jb25zdW1lT3B0aW9uYWxDaGFyYWN0ZXIoY2hhcnMuJENPTU1BKSk7XG4gICAgcmV0dXJuIHBvc2l0aW9uYWxzIGFzIEJpbmRpbmdQaXBlW107XG4gIH1cblxuICAvKipcbiAgICogUGFyc2VzIGFuIGlkZW50aWZpZXIsIGEga2V5d29yZCwgYSBzdHJpbmcgd2l0aCBhbiBvcHRpb25hbCBgLWAgaW4gYmV0d2VlbixcbiAgICogYW5kIHJldHVybnMgdGhlIHN0cmluZyBhbG9uZyB3aXRoIGl0cyBhYnNvbHV0ZSBzb3VyY2Ugc3Bhbi5cbiAgICovXG4gIGV4cGVjdFRlbXBsYXRlQmluZGluZ0tleSgpOiBUZW1wbGF0ZUJpbmRpbmdJZGVudGlmaWVyIHtcbiAgICBsZXQgcmVzdWx0ID0gJyc7XG4gICAgbGV0IG9wZXJhdG9yRm91bmQgPSBmYWxzZTtcbiAgICBjb25zdCBzdGFydCA9IHRoaXMuY3VycmVudEFic29sdXRlT2Zmc2V0O1xuICAgIGRvIHtcbiAgICAgIHJlc3VsdCArPSB0aGlzLmV4cGVjdElkZW50aWZpZXJPcktleXdvcmRPclN0cmluZygpO1xuICAgICAgb3BlcmF0b3JGb3VuZCA9IHRoaXMuY29uc3VtZU9wdGlvbmFsT3BlcmF0b3IoJy0nKTtcbiAgICAgIGlmIChvcGVyYXRvckZvdW5kKSB7XG4gICAgICAgIHJlc3VsdCArPSAnLSc7XG4gICAgICB9XG4gICAgfSB3aGlsZSAob3BlcmF0b3JGb3VuZCk7XG4gICAgcmV0dXJuIHtcbiAgICAgIHNvdXJjZTogcmVzdWx0LFxuICAgICAgc3BhbjogbmV3IEFic29sdXRlU291cmNlU3BhbihzdGFydCwgc3RhcnQgKyByZXN1bHQubGVuZ3RoKSxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFBhcnNlIG1pY3Jvc3ludGF4IHRlbXBsYXRlIGV4cHJlc3Npb24gYW5kIHJldHVybiBhIGxpc3Qgb2YgYmluZGluZ3Mgb3JcbiAgICogcGFyc2luZyBlcnJvcnMgaW4gY2FzZSB0aGUgZ2l2ZW4gZXhwcmVzc2lvbiBpcyBpbnZhbGlkLlxuICAgKlxuICAgKiBGb3IgZXhhbXBsZSxcbiAgICogYGBgXG4gICAqICAgPGRpdiAqbmdGb3I9XCJsZXQgaXRlbSBvZiBpdGVtczsgaW5kZXggYXMgaTsgdHJhY2tCeTogZnVuY1wiPlxuICAgKiBgYGBcbiAgICogY29udGFpbnMgZml2ZSBiaW5kaW5nczpcbiAgICogMS4gbmdGb3IgLT4gbnVsbFxuICAgKiAyLiBpdGVtIC0+IE5nRm9yT2ZDb250ZXh0LiRpbXBsaWNpdFxuICAgKiAzLiBuZ0Zvck9mIC0+IGl0ZW1zXG4gICAqIDQuIGkgLT4gTmdGb3JPZkNvbnRleHQuaW5kZXhcbiAgICogNS4gbmdGb3JUcmFja0J5IC0+IGZ1bmNcbiAgICpcbiAgICogRm9yIGEgZnVsbCBkZXNjcmlwdGlvbiBvZiB0aGUgbWljcm9zeW50YXggZ3JhbW1hciwgc2VlXG4gICAqIGh0dHBzOi8vZ2lzdC5naXRodWIuY29tL21oZXZlcnkvZDM1MzAyOTRjZmYyZTRhMWIzZmUxNWZmNzVkMDg4NTVcbiAgICpcbiAgICogQHBhcmFtIHRlbXBsYXRlS2V5IG5hbWUgb2YgdGhlIG1pY3Jvc3ludGF4IGRpcmVjdGl2ZSwgbGlrZSBuZ0lmLCBuZ0ZvcixcbiAgICogd2l0aG91dCB0aGUgKiwgYWxvbmcgd2l0aCBpdHMgYWJzb2x1dGUgc3Bhbi5cbiAgICovXG4gIHBhcnNlVGVtcGxhdGVCaW5kaW5ncyh0ZW1wbGF0ZUtleTogVGVtcGxhdGVCaW5kaW5nSWRlbnRpZmllcik6IFRlbXBsYXRlQmluZGluZ1BhcnNlUmVzdWx0IHtcbiAgICBjb25zdCBiaW5kaW5nczogVGVtcGxhdGVCaW5kaW5nW10gPSBbXTtcblxuICAgIC8vIFRoZSBmaXJzdCBiaW5kaW5nIGlzIGZvciB0aGUgdGVtcGxhdGUga2V5IGl0c2VsZlxuICAgIC8vIEluICpuZ0Zvcj1cImxldCBpdGVtIG9mIGl0ZW1zXCIsIGtleSA9IFwibmdGb3JcIiwgdmFsdWUgPSBudWxsXG4gICAgLy8gSW4gKm5nSWY9XCJjb25kIHwgcGlwZVwiLCBrZXkgPSBcIm5nSWZcIiwgdmFsdWUgPSBcImNvbmQgfCBwaXBlXCJcbiAgICBiaW5kaW5ncy5wdXNoKC4uLnRoaXMucGFyc2VEaXJlY3RpdmVLZXl3b3JkQmluZGluZ3ModGVtcGxhdGVLZXkpKTtcblxuICAgIHdoaWxlICh0aGlzLmluZGV4IDwgdGhpcy50b2tlbnMubGVuZ3RoKSB7XG4gICAgICAvLyBJZiBpdCBzdGFydHMgd2l0aCAnbGV0JywgdGhlbiB0aGlzIG11c3QgYmUgdmFyaWFibGUgZGVjbGFyYXRpb25cbiAgICAgIGNvbnN0IGxldEJpbmRpbmcgPSB0aGlzLnBhcnNlTGV0QmluZGluZygpO1xuICAgICAgaWYgKGxldEJpbmRpbmcpIHtcbiAgICAgICAgYmluZGluZ3MucHVzaChsZXRCaW5kaW5nKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIFR3byBwb3NzaWJsZSBjYXNlcyBoZXJlLCBlaXRoZXIgYHZhbHVlIFwiYXNcIiBrZXlgIG9yXG4gICAgICAgIC8vIFwiZGlyZWN0aXZlLWtleXdvcmQgZXhwcmVzc2lvblwiLiBXZSBkb24ndCBrbm93IHdoaWNoIGNhc2UsIGJ1dCBib3RoXG4gICAgICAgIC8vIFwidmFsdWVcIiBhbmQgXCJkaXJlY3RpdmUta2V5d29yZFwiIGFyZSB0ZW1wbGF0ZSBiaW5kaW5nIGtleSwgc28gY29uc3VtZVxuICAgICAgICAvLyB0aGUga2V5IGZpcnN0LlxuICAgICAgICBjb25zdCBrZXkgPSB0aGlzLmV4cGVjdFRlbXBsYXRlQmluZGluZ0tleSgpO1xuICAgICAgICAvLyBQZWVrIGF0IHRoZSBuZXh0IHRva2VuLCBpZiBpdCBpcyBcImFzXCIgdGhlbiB0aGlzIG11c3QgYmUgdmFyaWFibGVcbiAgICAgICAgLy8gZGVjbGFyYXRpb24uXG4gICAgICAgIGNvbnN0IGJpbmRpbmcgPSB0aGlzLnBhcnNlQXNCaW5kaW5nKGtleSk7XG4gICAgICAgIGlmIChiaW5kaW5nKSB7XG4gICAgICAgICAgYmluZGluZ3MucHVzaChiaW5kaW5nKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBPdGhlcndpc2UgdGhlIGtleSBtdXN0IGJlIGEgZGlyZWN0aXZlIGtleXdvcmQsIGxpa2UgXCJvZlwiLiBUcmFuc2Zvcm1cbiAgICAgICAgICAvLyB0aGUga2V5IHRvIGFjdHVhbCBrZXkuIEVnLiBvZiAtPiBuZ0Zvck9mLCB0cmFja0J5IC0+IG5nRm9yVHJhY2tCeVxuICAgICAgICAgIGtleS5zb3VyY2UgPVxuICAgICAgICAgICAgICB0ZW1wbGF0ZUtleS5zb3VyY2UgKyBrZXkuc291cmNlLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpICsga2V5LnNvdXJjZS5zdWJzdHJpbmcoMSk7XG4gICAgICAgICAgYmluZGluZ3MucHVzaCguLi50aGlzLnBhcnNlRGlyZWN0aXZlS2V5d29yZEJpbmRpbmdzKGtleSkpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICB0aGlzLmNvbnN1bWVTdGF0ZW1lbnRUZXJtaW5hdG9yKCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBUZW1wbGF0ZUJpbmRpbmdQYXJzZVJlc3VsdChiaW5kaW5ncywgW10gLyogd2FybmluZ3MgKi8sIHRoaXMuZXJyb3JzKTtcbiAgfVxuXG4gIHBhcnNlS2V5ZWRSZWFkT3JXcml0ZShyZWNlaXZlcjogQVNULCBzdGFydDogbnVtYmVyLCBpc1NhZmU6IGJvb2xlYW4pOiBBU1Qge1xuICAgIHJldHVybiB0aGlzLndpdGhDb250ZXh0KFBhcnNlQ29udGV4dEZsYWdzLldyaXRhYmxlLCAoKSA9PiB7XG4gICAgICB0aGlzLnJicmFja2V0c0V4cGVjdGVkKys7XG4gICAgICBjb25zdCBrZXkgPSB0aGlzLnBhcnNlUGlwZSgpO1xuICAgICAgaWYgKGtleSBpbnN0YW5jZW9mIEVtcHR5RXhwcikge1xuICAgICAgICB0aGlzLmVycm9yKGBLZXkgYWNjZXNzIGNhbm5vdCBiZSBlbXB0eWApO1xuICAgICAgfVxuICAgICAgdGhpcy5yYnJhY2tldHNFeHBlY3RlZC0tO1xuICAgICAgdGhpcy5leHBlY3RDaGFyYWN0ZXIoY2hhcnMuJFJCUkFDS0VUKTtcbiAgICAgIGlmICh0aGlzLmNvbnN1bWVPcHRpb25hbE9wZXJhdG9yKCc9JykpIHtcbiAgICAgICAgaWYgKGlzU2FmZSkge1xuICAgICAgICAgIHRoaXMuZXJyb3IoJ1RoZSBcXCc/LlxcJyBvcGVyYXRvciBjYW5ub3QgYmUgdXNlZCBpbiB0aGUgYXNzaWdubWVudCcpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnN0IHZhbHVlID0gdGhpcy5wYXJzZUNvbmRpdGlvbmFsKCk7XG4gICAgICAgICAgcmV0dXJuIG5ldyBLZXllZFdyaXRlKHRoaXMuc3BhbihzdGFydCksIHRoaXMuc291cmNlU3BhbihzdGFydCksIHJlY2VpdmVyLCBrZXksIHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGlzU2FmZSA/IG5ldyBTYWZlS2V5ZWRSZWFkKHRoaXMuc3BhbihzdGFydCksIHRoaXMuc291cmNlU3BhbihzdGFydCksIHJlY2VpdmVyLCBrZXkpIDpcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBLZXllZFJlYWQodGhpcy5zcGFuKHN0YXJ0KSwgdGhpcy5zb3VyY2VTcGFuKHN0YXJ0KSwgcmVjZWl2ZXIsIGtleSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBuZXcgRW1wdHlFeHByKHRoaXMuc3BhbihzdGFydCksIHRoaXMuc291cmNlU3BhbihzdGFydCkpO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFBhcnNlIGEgZGlyZWN0aXZlIGtleXdvcmQsIGZvbGxvd2VkIGJ5IGEgbWFuZGF0b3J5IGV4cHJlc3Npb24uXG4gICAqIEZvciBleGFtcGxlLCBcIm9mIGl0ZW1zXCIsIFwidHJhY2tCeTogZnVuY1wiLlxuICAgKiBUaGUgYmluZGluZ3MgYXJlOiBuZ0Zvck9mIC0+IGl0ZW1zLCBuZ0ZvclRyYWNrQnkgLT4gZnVuY1xuICAgKiBUaGVyZSBjb3VsZCBiZSBhbiBvcHRpb25hbCBcImFzXCIgYmluZGluZyB0aGF0IGZvbGxvd3MgdGhlIGV4cHJlc3Npb24uXG4gICAqIEZvciBleGFtcGxlLFxuICAgKiBgYGBcbiAgICogICAqbmdGb3I9XCJsZXQgaXRlbSBvZiBpdGVtcyB8IHNsaWNlOjA6MSBhcyBjb2xsZWN0aW9uXCIuXG4gICAqICAgICAgICAgICAgICAgICAgICBeXiBeXl5eXl5eXl5eXl5eXl5eXiBeXl5eXl5eXl5eXl5eXG4gICAqICAgICAgICAgICAgICAga2V5d29yZCAgICBib3VuZCB0YXJnZXQgICBvcHRpb25hbCAnYXMnIGJpbmRpbmdcbiAgICogYGBgXG4gICAqXG4gICAqIEBwYXJhbSBrZXkgYmluZGluZyBrZXksIGZvciBleGFtcGxlLCBuZ0ZvciwgbmdJZiwgbmdGb3JPZiwgYWxvbmcgd2l0aCBpdHNcbiAgICogYWJzb2x1dGUgc3Bhbi5cbiAgICovXG4gIHByaXZhdGUgcGFyc2VEaXJlY3RpdmVLZXl3b3JkQmluZGluZ3Moa2V5OiBUZW1wbGF0ZUJpbmRpbmdJZGVudGlmaWVyKTogVGVtcGxhdGVCaW5kaW5nW10ge1xuICAgIGNvbnN0IGJpbmRpbmdzOiBUZW1wbGF0ZUJpbmRpbmdbXSA9IFtdO1xuICAgIHRoaXMuY29uc3VtZU9wdGlvbmFsQ2hhcmFjdGVyKGNoYXJzLiRDT0xPTik7ICAvLyB0cmFja0J5OiB0cmFja0J5RnVuY3Rpb25cbiAgICBjb25zdCB2YWx1ZSA9IHRoaXMuZ2V0RGlyZWN0aXZlQm91bmRUYXJnZXQoKTtcbiAgICBsZXQgc3BhbkVuZCA9IHRoaXMuY3VycmVudEFic29sdXRlT2Zmc2V0O1xuICAgIC8vIFRoZSBiaW5kaW5nIGNvdWxkIG9wdGlvbmFsbHkgYmUgZm9sbG93ZWQgYnkgXCJhc1wiLiBGb3IgZXhhbXBsZSxcbiAgICAvLyAqbmdJZj1cImNvbmQgfCBwaXBlIGFzIHhcIi4gSW4gdGhpcyBjYXNlLCB0aGUga2V5IGluIHRoZSBcImFzXCIgYmluZGluZ1xuICAgIC8vIGlzIFwieFwiIGFuZCB0aGUgdmFsdWUgaXMgdGhlIHRlbXBsYXRlIGtleSBpdHNlbGYgKFwibmdJZlwiKS4gTm90ZSB0aGF0IHRoZVxuICAgIC8vICdrZXknIGluIHRoZSBjdXJyZW50IGNvbnRleHQgbm93IGJlY29tZXMgdGhlIFwidmFsdWVcIiBpbiB0aGUgbmV4dCBiaW5kaW5nLlxuICAgIGNvbnN0IGFzQmluZGluZyA9IHRoaXMucGFyc2VBc0JpbmRpbmcoa2V5KTtcbiAgICBpZiAoIWFzQmluZGluZykge1xuICAgICAgdGhpcy5jb25zdW1lU3RhdGVtZW50VGVybWluYXRvcigpO1xuICAgICAgc3BhbkVuZCA9IHRoaXMuY3VycmVudEFic29sdXRlT2Zmc2V0O1xuICAgIH1cbiAgICBjb25zdCBzb3VyY2VTcGFuID0gbmV3IEFic29sdXRlU291cmNlU3BhbihrZXkuc3Bhbi5zdGFydCwgc3BhbkVuZCk7XG4gICAgYmluZGluZ3MucHVzaChuZXcgRXhwcmVzc2lvbkJpbmRpbmcoc291cmNlU3Bhbiwga2V5LCB2YWx1ZSkpO1xuICAgIGlmIChhc0JpbmRpbmcpIHtcbiAgICAgIGJpbmRpbmdzLnB1c2goYXNCaW5kaW5nKTtcbiAgICB9XG4gICAgcmV0dXJuIGJpbmRpbmdzO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybiB0aGUgZXhwcmVzc2lvbiBBU1QgZm9yIHRoZSBib3VuZCB0YXJnZXQgb2YgYSBkaXJlY3RpdmUga2V5d29yZFxuICAgKiBiaW5kaW5nLiBGb3IgZXhhbXBsZSxcbiAgICogYGBgXG4gICAqICAgKm5nSWY9XCJjb25kaXRpb24gfCBwaXBlXCJcbiAgICogICAgICAgICAgXl5eXl5eXl5eXl5eXl5eXiBib3VuZCB0YXJnZXQgZm9yIFwibmdJZlwiXG4gICAqICAgKm5nRm9yPVwibGV0IGl0ZW0gb2YgaXRlbXNcIlxuICAgKiAgICAgICAgICAgICAgICAgICAgICAgXl5eXl4gYm91bmQgdGFyZ2V0IGZvciBcIm5nRm9yT2ZcIlxuICAgKiBgYGBcbiAgICovXG4gIHByaXZhdGUgZ2V0RGlyZWN0aXZlQm91bmRUYXJnZXQoKTogQVNUV2l0aFNvdXJjZXxudWxsIHtcbiAgICBpZiAodGhpcy5uZXh0ID09PSBFT0YgfHwgdGhpcy5wZWVrS2V5d29yZEFzKCkgfHwgdGhpcy5wZWVrS2V5d29yZExldCgpKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgY29uc3QgYXN0ID0gdGhpcy5wYXJzZVBpcGUoKTsgIC8vIGV4YW1wbGU6IFwiY29uZGl0aW9uIHwgYXN5bmNcIlxuICAgIGNvbnN0IHtzdGFydCwgZW5kfSA9IGFzdC5zcGFuO1xuICAgIGNvbnN0IHZhbHVlID0gdGhpcy5pbnB1dC5zdWJzdHJpbmcoc3RhcnQsIGVuZCk7XG4gICAgcmV0dXJuIG5ldyBBU1RXaXRoU291cmNlKGFzdCwgdmFsdWUsIHRoaXMubG9jYXRpb24sIHRoaXMuYWJzb2x1dGVPZmZzZXQgKyBzdGFydCwgdGhpcy5lcnJvcnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybiB0aGUgYmluZGluZyBmb3IgYSB2YXJpYWJsZSBkZWNsYXJlZCB1c2luZyBgYXNgLiBOb3RlIHRoYXQgdGhlIG9yZGVyXG4gICAqIG9mIHRoZSBrZXktdmFsdWUgcGFpciBpbiB0aGlzIGRlY2xhcmF0aW9uIGlzIHJldmVyc2VkLiBGb3IgZXhhbXBsZSxcbiAgICogYGBgXG4gICAqICAgKm5nRm9yPVwibGV0IGl0ZW0gb2YgaXRlbXM7IGluZGV4IGFzIGlcIlxuICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF5eXl5eICAgIF5cbiAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSAgICBrZXlcbiAgICogYGBgXG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZSBuYW1lIG9mIHRoZSB2YWx1ZSBpbiB0aGUgZGVjbGFyYXRpb24sIFwibmdJZlwiIGluIHRoZSBleGFtcGxlXG4gICAqIGFib3ZlLCBhbG9uZyB3aXRoIGl0cyBhYnNvbHV0ZSBzcGFuLlxuICAgKi9cbiAgcHJpdmF0ZSBwYXJzZUFzQmluZGluZyh2YWx1ZTogVGVtcGxhdGVCaW5kaW5nSWRlbnRpZmllcik6IFRlbXBsYXRlQmluZGluZ3xudWxsIHtcbiAgICBpZiAoIXRoaXMucGVla0tleXdvcmRBcygpKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgdGhpcy5hZHZhbmNlKCk7ICAvLyBjb25zdW1lIHRoZSAnYXMnIGtleXdvcmRcbiAgICBjb25zdCBrZXkgPSB0aGlzLmV4cGVjdFRlbXBsYXRlQmluZGluZ0tleSgpO1xuICAgIHRoaXMuY29uc3VtZVN0YXRlbWVudFRlcm1pbmF0b3IoKTtcbiAgICBjb25zdCBzb3VyY2VTcGFuID0gbmV3IEFic29sdXRlU291cmNlU3Bhbih2YWx1ZS5zcGFuLnN0YXJ0LCB0aGlzLmN1cnJlbnRBYnNvbHV0ZU9mZnNldCk7XG4gICAgcmV0dXJuIG5ldyBWYXJpYWJsZUJpbmRpbmcoc291cmNlU3Bhbiwga2V5LCB2YWx1ZSk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIHRoZSBiaW5kaW5nIGZvciBhIHZhcmlhYmxlIGRlY2xhcmVkIHVzaW5nIGBsZXRgLiBGb3IgZXhhbXBsZSxcbiAgICogYGBgXG4gICAqICAgKm5nRm9yPVwibGV0IGl0ZW0gb2YgaXRlbXM7IGxldCBpPWluZGV4O1wiXG4gICAqICAgICAgICAgICBeXl5eXl5eXiAgICAgICAgICAgXl5eXl5eXl5eXl5cbiAgICogYGBgXG4gICAqIEluIHRoZSBmaXJzdCBiaW5kaW5nLCBgaXRlbWAgaXMgYm91bmQgdG8gYE5nRm9yT2ZDb250ZXh0LiRpbXBsaWNpdGAuXG4gICAqIEluIHRoZSBzZWNvbmQgYmluZGluZywgYGlgIGlzIGJvdW5kIHRvIGBOZ0Zvck9mQ29udGV4dC5pbmRleGAuXG4gICAqL1xuICBwcml2YXRlIHBhcnNlTGV0QmluZGluZygpOiBUZW1wbGF0ZUJpbmRpbmd8bnVsbCB7XG4gICAgaWYgKCF0aGlzLnBlZWtLZXl3b3JkTGV0KCkpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICBjb25zdCBzcGFuU3RhcnQgPSB0aGlzLmN1cnJlbnRBYnNvbHV0ZU9mZnNldDtcbiAgICB0aGlzLmFkdmFuY2UoKTsgIC8vIGNvbnN1bWUgdGhlICdsZXQnIGtleXdvcmRcbiAgICBjb25zdCBrZXkgPSB0aGlzLmV4cGVjdFRlbXBsYXRlQmluZGluZ0tleSgpO1xuICAgIGxldCB2YWx1ZTogVGVtcGxhdGVCaW5kaW5nSWRlbnRpZmllcnxudWxsID0gbnVsbDtcbiAgICBpZiAodGhpcy5jb25zdW1lT3B0aW9uYWxPcGVyYXRvcignPScpKSB7XG4gICAgICB2YWx1ZSA9IHRoaXMuZXhwZWN0VGVtcGxhdGVCaW5kaW5nS2V5KCk7XG4gICAgfVxuICAgIHRoaXMuY29uc3VtZVN0YXRlbWVudFRlcm1pbmF0b3IoKTtcbiAgICBjb25zdCBzb3VyY2VTcGFuID0gbmV3IEFic29sdXRlU291cmNlU3BhbihzcGFuU3RhcnQsIHRoaXMuY3VycmVudEFic29sdXRlT2Zmc2V0KTtcbiAgICByZXR1cm4gbmV3IFZhcmlhYmxlQmluZGluZyhzb3VyY2VTcGFuLCBrZXksIHZhbHVlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb25zdW1lIHRoZSBvcHRpb25hbCBzdGF0ZW1lbnQgdGVybWluYXRvcjogc2VtaWNvbG9uIG9yIGNvbW1hLlxuICAgKi9cbiAgcHJpdmF0ZSBjb25zdW1lU3RhdGVtZW50VGVybWluYXRvcigpIHtcbiAgICB0aGlzLmNvbnN1bWVPcHRpb25hbENoYXJhY3RlcihjaGFycy4kU0VNSUNPTE9OKSB8fCB0aGlzLmNvbnN1bWVPcHRpb25hbENoYXJhY3RlcihjaGFycy4kQ09NTUEpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlY29yZHMgYW4gZXJyb3IgYW5kIHNraXBzIG92ZXIgdGhlIHRva2VuIHN0cmVhbSB1bnRpbCByZWFjaGluZyBhIHJlY292ZXJhYmxlIHBvaW50LiBTZWVcbiAgICogYHRoaXMuc2tpcGAgZm9yIG1vcmUgZGV0YWlscyBvbiB0b2tlbiBza2lwcGluZy5cbiAgICovXG4gIGVycm9yKG1lc3NhZ2U6IHN0cmluZywgaW5kZXg6IG51bWJlcnxudWxsID0gbnVsbCkge1xuICAgIHRoaXMuZXJyb3JzLnB1c2gobmV3IFBhcnNlckVycm9yKG1lc3NhZ2UsIHRoaXMuaW5wdXQsIHRoaXMubG9jYXRpb25UZXh0KGluZGV4KSwgdGhpcy5sb2NhdGlvbikpO1xuICAgIHRoaXMuc2tpcCgpO1xuICB9XG5cbiAgcHJpdmF0ZSBsb2NhdGlvblRleHQoaW5kZXg6IG51bWJlcnxudWxsID0gbnVsbCkge1xuICAgIGlmIChpbmRleCA9PSBudWxsKSBpbmRleCA9IHRoaXMuaW5kZXg7XG4gICAgcmV0dXJuIChpbmRleCA8IHRoaXMudG9rZW5zLmxlbmd0aCkgPyBgYXQgY29sdW1uICR7dGhpcy50b2tlbnNbaW5kZXhdLmluZGV4ICsgMX0gaW5gIDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGBhdCB0aGUgZW5kIG9mIHRoZSBleHByZXNzaW9uYDtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWNvcmRzIGFuIGVycm9yIGZvciBhbiB1bmV4cGVjdGVkIHByaXZhdGUgaWRlbnRpZmllciBiZWluZyBkaXNjb3ZlcmVkLlxuICAgKiBAcGFyYW0gdG9rZW4gVG9rZW4gcmVwcmVzZW50aW5nIGEgcHJpdmF0ZSBpZGVudGlmaWVyLlxuICAgKiBAcGFyYW0gZXh0cmFNZXNzYWdlIE9wdGlvbmFsIGFkZGl0aW9uYWwgbWVzc2FnZSBiZWluZyBhcHBlbmRlZCB0byB0aGUgZXJyb3IuXG4gICAqL1xuICBwcml2YXRlIF9yZXBvcnRFcnJvckZvclByaXZhdGVJZGVudGlmaWVyKHRva2VuOiBUb2tlbiwgZXh0cmFNZXNzYWdlOiBzdHJpbmd8bnVsbCkge1xuICAgIGxldCBlcnJvck1lc3NhZ2UgPVxuICAgICAgICBgUHJpdmF0ZSBpZGVudGlmaWVycyBhcmUgbm90IHN1cHBvcnRlZC4gVW5leHBlY3RlZCBwcml2YXRlIGlkZW50aWZpZXI6ICR7dG9rZW59YDtcbiAgICBpZiAoZXh0cmFNZXNzYWdlICE9PSBudWxsKSB7XG4gICAgICBlcnJvck1lc3NhZ2UgKz0gYCwgJHtleHRyYU1lc3NhZ2V9YDtcbiAgICB9XG4gICAgdGhpcy5lcnJvcihlcnJvck1lc3NhZ2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIEVycm9yIHJlY292ZXJ5IHNob3VsZCBza2lwIHRva2VucyB1bnRpbCBpdCBlbmNvdW50ZXJzIGEgcmVjb3ZlcnkgcG9pbnQuXG4gICAqXG4gICAqIFRoZSBmb2xsb3dpbmcgYXJlIHRyZWF0ZWQgYXMgdW5jb25kaXRpb25hbCByZWNvdmVyeSBwb2ludHM6XG4gICAqICAgLSBlbmQgb2YgaW5wdXRcbiAgICogICAtICc7JyAocGFyc2VDaGFpbigpIGlzIGFsd2F5cyB0aGUgcm9vdCBwcm9kdWN0aW9uLCBhbmQgaXQgZXhwZWN0cyBhICc7JylcbiAgICogICAtICd8JyAoc2luY2UgcGlwZXMgbWF5IGJlIGNoYWluZWQgYW5kIGVhY2ggcGlwZSBleHByZXNzaW9uIG1heSBiZSB0cmVhdGVkIGluZGVwZW5kZW50bHkpXG4gICAqXG4gICAqIFRoZSBmb2xsb3dpbmcgYXJlIGNvbmRpdGlvbmFsIHJlY292ZXJ5IHBvaW50czpcbiAgICogICAtICcpJywgJ30nLCAnXScgaWYgb25lIG9mIGNhbGxpbmcgcHJvZHVjdGlvbnMgaXMgZXhwZWN0aW5nIG9uZSBvZiB0aGVzZSBzeW1ib2xzXG4gICAqICAgICAtIFRoaXMgYWxsb3dzIHNraXAoKSB0byByZWNvdmVyIGZyb20gZXJyb3JzIHN1Y2ggYXMgJyhhLikgKyAxJyBhbGxvd2luZyBtb3JlIG9mIHRoZSBBU1QgdG9cbiAgICogICAgICAgYmUgcmV0YWluZWQgKGl0IGRvZXNuJ3Qgc2tpcCBhbnkgdG9rZW5zIGFzIHRoZSAnKScgaXMgcmV0YWluZWQgYmVjYXVzZSBvZiB0aGUgJygnIGJlZ2luc1xuICAgKiAgICAgICBhbiAnKCcgPGV4cHI+ICcpJyBwcm9kdWN0aW9uKS5cbiAgICogICAgICAgVGhlIHJlY292ZXJ5IHBvaW50cyBvZiBncm91cGluZyBzeW1ib2xzIG11c3QgYmUgY29uZGl0aW9uYWwgYXMgdGhleSBtdXN0IGJlIHNraXBwZWQgaWZcbiAgICogICAgICAgbm9uZSBvZiB0aGUgY2FsbGluZyBwcm9kdWN0aW9ucyBhcmUgbm90IGV4cGVjdGluZyB0aGUgY2xvc2luZyB0b2tlbiBlbHNlIHdlIHdpbGwgbmV2ZXJcbiAgICogICAgICAgbWFrZSBwcm9ncmVzcyBpbiB0aGUgY2FzZSBvZiBhbiBleHRyYW5lb3VzIGdyb3VwIGNsb3Npbmcgc3ltYm9sIChzdWNoIGFzIGEgc3RyYXkgJyknKS5cbiAgICogICAgICAgVGhhdCBpcywgd2Ugc2tpcCBhIGNsb3Npbmcgc3ltYm9sIGlmIHdlIGFyZSBub3QgaW4gYSBncm91cGluZyBwcm9kdWN0aW9uLlxuICAgKiAgIC0gJz0nIGluIGEgYFdyaXRhYmxlYCBjb250ZXh0XG4gICAqICAgICAtIEluIHRoaXMgY29udGV4dCwgd2UgYXJlIGFibGUgdG8gcmVjb3ZlciBhZnRlciBzZWVpbmcgdGhlIGA9YCBvcGVyYXRvciwgd2hpY2hcbiAgICogICAgICAgc2lnbmFscyB0aGUgcHJlc2VuY2Ugb2YgYW4gaW5kZXBlbmRlbnQgcnZhbHVlIGV4cHJlc3Npb24gZm9sbG93aW5nIHRoZSBgPWAgb3BlcmF0b3IuXG4gICAqXG4gICAqIElmIGEgcHJvZHVjdGlvbiBleHBlY3RzIG9uZSBvZiB0aGVzZSB0b2tlbiBpdCBpbmNyZW1lbnRzIHRoZSBjb3JyZXNwb25kaW5nIG5lc3RpbmcgY291bnQsXG4gICAqIGFuZCB0aGVuIGRlY3JlbWVudHMgaXQganVzdCBwcmlvciB0byBjaGVja2luZyBpZiB0aGUgdG9rZW4gaXMgaW4gdGhlIGlucHV0LlxuICAgKi9cbiAgcHJpdmF0ZSBza2lwKCkge1xuICAgIGxldCBuID0gdGhpcy5uZXh0O1xuICAgIHdoaWxlICh0aGlzLmluZGV4IDwgdGhpcy50b2tlbnMubGVuZ3RoICYmICFuLmlzQ2hhcmFjdGVyKGNoYXJzLiRTRU1JQ09MT04pICYmXG4gICAgICAgICAgICFuLmlzT3BlcmF0b3IoJ3wnKSAmJiAodGhpcy5ycGFyZW5zRXhwZWN0ZWQgPD0gMCB8fCAhbi5pc0NoYXJhY3RlcihjaGFycy4kUlBBUkVOKSkgJiZcbiAgICAgICAgICAgKHRoaXMucmJyYWNlc0V4cGVjdGVkIDw9IDAgfHwgIW4uaXNDaGFyYWN0ZXIoY2hhcnMuJFJCUkFDRSkpICYmXG4gICAgICAgICAgICh0aGlzLnJicmFja2V0c0V4cGVjdGVkIDw9IDAgfHwgIW4uaXNDaGFyYWN0ZXIoY2hhcnMuJFJCUkFDS0VUKSkgJiZcbiAgICAgICAgICAgKCEodGhpcy5jb250ZXh0ICYgUGFyc2VDb250ZXh0RmxhZ3MuV3JpdGFibGUpIHx8ICFuLmlzT3BlcmF0b3IoJz0nKSkpIHtcbiAgICAgIGlmICh0aGlzLm5leHQuaXNFcnJvcigpKSB7XG4gICAgICAgIHRoaXMuZXJyb3JzLnB1c2goXG4gICAgICAgICAgICBuZXcgUGFyc2VyRXJyb3IodGhpcy5uZXh0LnRvU3RyaW5nKCkhLCB0aGlzLmlucHV0LCB0aGlzLmxvY2F0aW9uVGV4dCgpLCB0aGlzLmxvY2F0aW9uKSk7XG4gICAgICB9XG4gICAgICB0aGlzLmFkdmFuY2UoKTtcbiAgICAgIG4gPSB0aGlzLm5leHQ7XG4gICAgfVxuICB9XG59XG5cbmNsYXNzIFNpbXBsZUV4cHJlc3Npb25DaGVja2VyIGltcGxlbWVudHMgQXN0VmlzaXRvciB7XG4gIGVycm9yczogc3RyaW5nW10gPSBbXTtcblxuICB2aXNpdEltcGxpY2l0UmVjZWl2ZXIoYXN0OiBJbXBsaWNpdFJlY2VpdmVyLCBjb250ZXh0OiBhbnkpIHt9XG5cbiAgdmlzaXRUaGlzUmVjZWl2ZXIoYXN0OiBUaGlzUmVjZWl2ZXIsIGNvbnRleHQ6IGFueSkge31cblxuICB2aXNpdEludGVycG9sYXRpb24oYXN0OiBJbnRlcnBvbGF0aW9uLCBjb250ZXh0OiBhbnkpIHt9XG5cbiAgdmlzaXRMaXRlcmFsUHJpbWl0aXZlKGFzdDogTGl0ZXJhbFByaW1pdGl2ZSwgY29udGV4dDogYW55KSB7fVxuXG4gIHZpc2l0UHJvcGVydHlSZWFkKGFzdDogUHJvcGVydHlSZWFkLCBjb250ZXh0OiBhbnkpIHt9XG5cbiAgdmlzaXRQcm9wZXJ0eVdyaXRlKGFzdDogUHJvcGVydHlXcml0ZSwgY29udGV4dDogYW55KSB7fVxuXG4gIHZpc2l0U2FmZVByb3BlcnR5UmVhZChhc3Q6IFNhZmVQcm9wZXJ0eVJlYWQsIGNvbnRleHQ6IGFueSkge31cblxuICB2aXNpdE1ldGhvZENhbGwoYXN0OiBNZXRob2RDYWxsLCBjb250ZXh0OiBhbnkpIHt9XG5cbiAgdmlzaXRTYWZlTWV0aG9kQ2FsbChhc3Q6IFNhZmVNZXRob2RDYWxsLCBjb250ZXh0OiBhbnkpIHt9XG5cbiAgdmlzaXRGdW5jdGlvbkNhbGwoYXN0OiBGdW5jdGlvbkNhbGwsIGNvbnRleHQ6IGFueSkge31cblxuICB2aXNpdExpdGVyYWxBcnJheShhc3Q6IExpdGVyYWxBcnJheSwgY29udGV4dDogYW55KSB7XG4gICAgdGhpcy52aXNpdEFsbChhc3QuZXhwcmVzc2lvbnMsIGNvbnRleHQpO1xuICB9XG5cbiAgdmlzaXRMaXRlcmFsTWFwKGFzdDogTGl0ZXJhbE1hcCwgY29udGV4dDogYW55KSB7XG4gICAgdGhpcy52aXNpdEFsbChhc3QudmFsdWVzLCBjb250ZXh0KTtcbiAgfVxuXG4gIHZpc2l0VW5hcnkoYXN0OiBVbmFyeSwgY29udGV4dDogYW55KSB7fVxuXG4gIHZpc2l0QmluYXJ5KGFzdDogQmluYXJ5LCBjb250ZXh0OiBhbnkpIHt9XG5cbiAgdmlzaXRQcmVmaXhOb3QoYXN0OiBQcmVmaXhOb3QsIGNvbnRleHQ6IGFueSkge31cblxuICB2aXNpdE5vbk51bGxBc3NlcnQoYXN0OiBOb25OdWxsQXNzZXJ0LCBjb250ZXh0OiBhbnkpIHt9XG5cbiAgdmlzaXRDb25kaXRpb25hbChhc3Q6IENvbmRpdGlvbmFsLCBjb250ZXh0OiBhbnkpIHt9XG5cbiAgdmlzaXRQaXBlKGFzdDogQmluZGluZ1BpcGUsIGNvbnRleHQ6IGFueSkge1xuICAgIHRoaXMuZXJyb3JzLnB1c2goJ3BpcGVzJyk7XG4gIH1cblxuICB2aXNpdEtleWVkUmVhZChhc3Q6IEtleWVkUmVhZCwgY29udGV4dDogYW55KSB7fVxuXG4gIHZpc2l0S2V5ZWRXcml0ZShhc3Q6IEtleWVkV3JpdGUsIGNvbnRleHQ6IGFueSkge31cblxuICB2aXNpdEFsbChhc3RzOiBhbnlbXSwgY29udGV4dDogYW55KTogYW55W10ge1xuICAgIHJldHVybiBhc3RzLm1hcChub2RlID0+IG5vZGUudmlzaXQodGhpcywgY29udGV4dCkpO1xuICB9XG5cbiAgdmlzaXRDaGFpbihhc3Q6IENoYWluLCBjb250ZXh0OiBhbnkpIHt9XG5cbiAgdmlzaXRRdW90ZShhc3Q6IFF1b3RlLCBjb250ZXh0OiBhbnkpIHt9XG5cbiAgdmlzaXRTYWZlS2V5ZWRSZWFkKGFzdDogU2FmZUtleWVkUmVhZCwgY29udGV4dDogYW55KSB7fVxufVxuXG4vKipcbiAqIFRoaXMgY2xhc3MgaW1wbGVtZW50cyBTaW1wbGVFeHByZXNzaW9uQ2hlY2tlciB1c2VkIGluIFZpZXcgRW5naW5lIGFuZCBwZXJmb3JtcyBtb3JlIHN0cmljdCBjaGVja3NcbiAqIHRvIG1ha2Ugc3VyZSBob3N0IGJpbmRpbmdzIGRvIG5vdCBjb250YWluIHBpcGVzLiBJbiBWaWV3IEVuZ2luZSwgaGF2aW5nIHBpcGVzIGluIGhvc3QgYmluZGluZ3MgaXNcbiAqIG5vdCBzdXBwb3J0ZWQgYXMgd2VsbCwgYnV0IGluIHNvbWUgY2FzZXMgKGxpa2UgYCEodmFsdWUgfCBhc3luYylgKSB0aGUgZXJyb3IgaXMgbm90IHRyaWdnZXJlZCBhdFxuICogY29tcGlsZSB0aW1lLiBJbiBvcmRlciB0byBwcmVzZXJ2ZSBWaWV3IEVuZ2luZSBiZWhhdmlvciwgbW9yZSBzdHJpY3QgY2hlY2tzIGFyZSBpbnRyb2R1Y2VkIGZvclxuICogSXZ5IG1vZGUgb25seS5cbiAqL1xuY2xhc3MgSXZ5U2ltcGxlRXhwcmVzc2lvbkNoZWNrZXIgZXh0ZW5kcyBSZWN1cnNpdmVBc3RWaXNpdG9yIGltcGxlbWVudHMgU2ltcGxlRXhwcmVzc2lvbkNoZWNrZXIge1xuICBlcnJvcnM6IHN0cmluZ1tdID0gW107XG5cbiAgb3ZlcnJpZGUgdmlzaXRQaXBlKCkge1xuICAgIHRoaXMuZXJyb3JzLnB1c2goJ3BpcGVzJyk7XG4gIH1cbn1cbiJdfQ==