@auscope/angular2parse 2.0.3 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm2020/auscope-angular2parse.mjs +5 -0
- package/esm2020/lib/angular/compiler/assertions.mjs +45 -0
- package/esm2020/lib/angular/compiler/ast.mjs +393 -0
- package/esm2020/lib/angular/compiler/chars.mjs +78 -0
- package/esm2020/lib/angular/compiler/interpolation-config.mjs +24 -0
- package/esm2020/lib/angular/compiler/lexer.mjs +344 -0
- package/esm2020/lib/angular/compiler/parser.mjs +721 -0
- package/esm2020/lib/angular/compiler.mjs +7 -0
- package/esm2020/lib/angular/facade/lang.mjs +85 -0
- package/esm2020/lib/angular/facade.mjs +2 -0
- package/esm2020/lib/angular.mjs +3 -0
- package/esm2020/lib/module.mjs +18 -0
- package/esm2020/lib/parse.mjs +66 -0
- package/esm2020/lib/util/binary-operations.mjs +18 -0
- package/esm2020/lib/util/lang.mjs +13 -0
- package/esm2020/lib/util.mjs +3 -0
- package/esm2020/lib/visitors/parse-visitor-compiler.mjs +96 -0
- package/esm2020/lib/visitors/parse-visitor-resolver.mjs +141 -0
- package/esm2020/lib/visitors.mjs +3 -0
- package/esm2020/public-api.mjs +6 -0
- package/fesm2015/auscope-angular2parse.mjs +2035 -0
- package/fesm2015/auscope-angular2parse.mjs.map +1 -0
- package/fesm2020/auscope-angular2parse.mjs +2033 -0
- package/fesm2020/auscope-angular2parse.mjs.map +1 -0
- package/index.d.ts +5 -0
- package/lib/angular/compiler/assertions.d.ts +9 -0
- package/lib/angular/compiler/ast.d.ts +242 -0
- package/lib/angular/compiler/chars.d.ts +69 -0
- package/lib/angular/compiler/interpolation-config.d.ts +14 -0
- package/lib/angular/compiler/lexer.d.ts +44 -0
- package/lib/angular/compiler/parser.d.ts +92 -0
- package/{projects/angular2parse/src/lib/angular/compiler.ts → lib/angular/compiler.d.ts} +1 -1
- package/lib/angular/facade/lang.d.ts +44 -0
- package/lib/angular/facade.d.ts +1 -0
- package/{projects/angular2parse/src/lib/angular.ts → lib/angular.d.ts} +1 -1
- package/lib/module.d.ts +9 -0
- package/lib/parse.d.ts +21 -0
- package/lib/util/binary-operations.d.ts +1 -0
- package/lib/util/lang.d.ts +4 -0
- package/{projects/angular2parse/src/lib/util.ts → lib/util.d.ts} +1 -1
- package/lib/visitors/parse-visitor-compiler.d.ts +23 -0
- package/lib/visitors/parse-visitor-resolver.d.ts +25 -0
- package/lib/visitors.d.ts +2 -0
- package/package.json +41 -38
- package/public-api.d.ts +2 -0
- package/.editorconfig +0 -13
- package/angular.json +0 -27
- package/projects/angular2parse/README.md +0 -49
- package/projects/angular2parse/ng-package.json +0 -7
- package/projects/angular2parse/package.json +0 -18
- package/projects/angular2parse/src/lib/angular/compiler/assertions.ts +0 -49
- package/projects/angular2parse/src/lib/angular/compiler/ast.ts +0 -393
- package/projects/angular2parse/src/lib/angular/compiler/chars.ts +0 -89
- package/projects/angular2parse/src/lib/angular/compiler/interpolation-config.ts +0 -25
- package/projects/angular2parse/src/lib/angular/compiler/lexer.ts +0 -383
- package/projects/angular2parse/src/lib/angular/compiler/parser.ts +0 -811
- package/projects/angular2parse/src/lib/angular/facade/lang.ts +0 -124
- package/projects/angular2parse/src/lib/angular/facade.ts +0 -1
- package/projects/angular2parse/src/lib/module.ts +0 -12
- package/projects/angular2parse/src/lib/parse.ts +0 -78
- package/projects/angular2parse/src/lib/util/binary-operations.ts +0 -17
- package/projects/angular2parse/src/lib/util/lang.ts +0 -15
- package/projects/angular2parse/src/lib/visitors/parse-visitor-compiler.ts +0 -149
- package/projects/angular2parse/src/lib/visitors/parse-visitor-resolver.ts +0 -208
- package/projects/angular2parse/src/lib/visitors.ts +0 -2
- package/projects/angular2parse/src/public-api.ts +0 -5
- package/projects/angular2parse/tsconfig.lib.json +0 -20
- package/projects/angular2parse/tsconfig.lib.prod.json +0 -9
- package/target/npmlist.json +0 -1
- package/tsconfig.json +0 -32
|
@@ -0,0 +1,721 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright Google Inc. All Rights Reserved.
|
|
4
|
+
*
|
|
5
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
6
|
+
* found in the LICENSE file at https://angular.io/license
|
|
7
|
+
*/
|
|
8
|
+
import * as chars from './chars';
|
|
9
|
+
import { escapeRegExp, isBlank, isPresent } from '../facade/lang';
|
|
10
|
+
import { DEFAULT_INTERPOLATION_CONFIG } from './interpolation-config';
|
|
11
|
+
import { ASTWithSource, Binary, BindingPipe, Chain, Conditional, EmptyExpr, FunctionCall, ImplicitReceiver, Interpolation, KeyedRead, KeyedWrite, LiteralArray, LiteralMap, LiteralPrimitive, MethodCall, ParseSpan, ParserError, PrefixNot, PropertyRead, PropertyWrite, Quote, SafeMethodCall, SafePropertyRead, TemplateBinding } from './ast';
|
|
12
|
+
import { EOF, TokenType, isIdentifier, isQuote } from './lexer';
|
|
13
|
+
export class SplitInterpolation {
|
|
14
|
+
constructor(strings, expressions, offsets) {
|
|
15
|
+
this.strings = strings;
|
|
16
|
+
this.expressions = expressions;
|
|
17
|
+
this.offsets = offsets;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export class TemplateBindingParseResult {
|
|
21
|
+
constructor(templateBindings, warnings, errors) {
|
|
22
|
+
this.templateBindings = templateBindings;
|
|
23
|
+
this.warnings = warnings;
|
|
24
|
+
this.errors = errors;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function _createInterpolateRegExp(config) {
|
|
28
|
+
const pattern = escapeRegExp(config.start) + '([\\s\\S]*?)' + escapeRegExp(config.end);
|
|
29
|
+
return new RegExp(pattern, 'g');
|
|
30
|
+
}
|
|
31
|
+
export class Parser {
|
|
32
|
+
constructor(_lexer) {
|
|
33
|
+
this._lexer = _lexer;
|
|
34
|
+
this.errors = [];
|
|
35
|
+
}
|
|
36
|
+
parseAction(input, location, interpolationConfig = DEFAULT_INTERPOLATION_CONFIG) {
|
|
37
|
+
this._checkNoInterpolation(input, location, interpolationConfig);
|
|
38
|
+
const sourceToLex = this._stripComments(input);
|
|
39
|
+
const tokens = this._lexer.tokenize(this._stripComments(input));
|
|
40
|
+
const ast = new _ParseAST(input, location, tokens, sourceToLex.length, true, this.errors, input.length - sourceToLex.length)
|
|
41
|
+
.parseChain();
|
|
42
|
+
return new ASTWithSource(ast, input, location, this.errors);
|
|
43
|
+
}
|
|
44
|
+
parseBinding(input, location, interpolationConfig = DEFAULT_INTERPOLATION_CONFIG) {
|
|
45
|
+
const ast = this._parseBindingAst(input, location, interpolationConfig);
|
|
46
|
+
return new ASTWithSource(ast, input, location, this.errors);
|
|
47
|
+
}
|
|
48
|
+
parseSimpleBinding(input, location, interpolationConfig = DEFAULT_INTERPOLATION_CONFIG) {
|
|
49
|
+
const ast = this._parseBindingAst(input, location, interpolationConfig);
|
|
50
|
+
const errors = SimpleExpressionChecker.check(ast);
|
|
51
|
+
if (errors.length > 0) {
|
|
52
|
+
this._reportError(`Host binding expression cannot contain ${errors.join(' ')}`, input, location);
|
|
53
|
+
}
|
|
54
|
+
return new ASTWithSource(ast, input, location, this.errors);
|
|
55
|
+
}
|
|
56
|
+
_reportError(message, input, errLocation, ctxLocation) {
|
|
57
|
+
this.errors.push(new ParserError(message, input, errLocation, ctxLocation));
|
|
58
|
+
}
|
|
59
|
+
_parseBindingAst(input, location, interpolationConfig) {
|
|
60
|
+
// Quotes expressions use 3rd-party expression language. We don't want to use
|
|
61
|
+
// our lexer or parser for that, so we check for that ahead of time.
|
|
62
|
+
const quote = this._parseQuote(input, location);
|
|
63
|
+
if (isPresent(quote)) {
|
|
64
|
+
return quote;
|
|
65
|
+
}
|
|
66
|
+
this._checkNoInterpolation(input, location, interpolationConfig);
|
|
67
|
+
const sourceToLex = this._stripComments(input);
|
|
68
|
+
const tokens = this._lexer.tokenize(sourceToLex);
|
|
69
|
+
return new _ParseAST(input, location, tokens, sourceToLex.length, false, this.errors, input.length - sourceToLex.length)
|
|
70
|
+
.parseChain();
|
|
71
|
+
}
|
|
72
|
+
_parseQuote(input, location) {
|
|
73
|
+
if (isBlank(input))
|
|
74
|
+
return null;
|
|
75
|
+
const prefixSeparatorIndex = input.indexOf(':');
|
|
76
|
+
if (prefixSeparatorIndex == -1)
|
|
77
|
+
return null;
|
|
78
|
+
const prefix = input.substring(0, prefixSeparatorIndex).trim();
|
|
79
|
+
if (!isIdentifier(prefix))
|
|
80
|
+
return null;
|
|
81
|
+
const uninterpretedExpression = input.substring(prefixSeparatorIndex + 1);
|
|
82
|
+
return new Quote(new ParseSpan(0, input.length), prefix, uninterpretedExpression, location);
|
|
83
|
+
}
|
|
84
|
+
parseTemplateBindings(prefixToken, input, location) {
|
|
85
|
+
const tokens = this._lexer.tokenize(input);
|
|
86
|
+
if (prefixToken) {
|
|
87
|
+
// Prefix the tokens with the tokens from prefixToken but have them take no space (0 index).
|
|
88
|
+
const prefixTokens = this._lexer.tokenize(prefixToken).map(t => {
|
|
89
|
+
t.index = 0;
|
|
90
|
+
return t;
|
|
91
|
+
});
|
|
92
|
+
tokens.unshift(...prefixTokens);
|
|
93
|
+
}
|
|
94
|
+
return new _ParseAST(input, location, tokens, input.length, false, this.errors, 0)
|
|
95
|
+
.parseTemplateBindings();
|
|
96
|
+
}
|
|
97
|
+
parseInterpolation(input, location, interpolationConfig = DEFAULT_INTERPOLATION_CONFIG) {
|
|
98
|
+
const split = this.splitInterpolation(input, location, interpolationConfig);
|
|
99
|
+
if (split == null)
|
|
100
|
+
return null;
|
|
101
|
+
const expressions = [];
|
|
102
|
+
for (let i = 0; i < split.expressions.length; ++i) {
|
|
103
|
+
const expressionText = split.expressions[i];
|
|
104
|
+
const sourceToLex = this._stripComments(expressionText);
|
|
105
|
+
const tokens = this._lexer.tokenize(this._stripComments(split.expressions[i]));
|
|
106
|
+
const ast = new _ParseAST(input, location, tokens, sourceToLex.length, false, this.errors, split.offsets[i] + (expressionText.length - sourceToLex.length))
|
|
107
|
+
.parseChain();
|
|
108
|
+
expressions.push(ast);
|
|
109
|
+
}
|
|
110
|
+
return new ASTWithSource(new Interpolation(new ParseSpan(0, isBlank(input) ? 0 : input.length), split.strings, expressions), input, location, this.errors);
|
|
111
|
+
}
|
|
112
|
+
splitInterpolation(input, location, interpolationConfig = DEFAULT_INTERPOLATION_CONFIG) {
|
|
113
|
+
const regexp = _createInterpolateRegExp(interpolationConfig);
|
|
114
|
+
const parts = input.split(regexp);
|
|
115
|
+
if (parts.length <= 1) {
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
const strings = [];
|
|
119
|
+
const expressions = [];
|
|
120
|
+
const offsets = [];
|
|
121
|
+
let offset = 0;
|
|
122
|
+
for (let i = 0; i < parts.length; i++) {
|
|
123
|
+
const part = parts[i];
|
|
124
|
+
if (i % 2 === 0) {
|
|
125
|
+
// fixed string
|
|
126
|
+
strings.push(part);
|
|
127
|
+
offset += part.length;
|
|
128
|
+
}
|
|
129
|
+
else if (part.trim().length > 0) {
|
|
130
|
+
offset += interpolationConfig.start.length;
|
|
131
|
+
expressions.push(part);
|
|
132
|
+
offsets.push(offset);
|
|
133
|
+
offset += part.length + interpolationConfig.end.length;
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
this._reportError('Blank expressions are not allowed in interpolated strings', input, `at column ${this._findInterpolationErrorColumn(parts, i, interpolationConfig)} in`, location);
|
|
137
|
+
expressions.push('$implict');
|
|
138
|
+
offsets.push(offset);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return new SplitInterpolation(strings, expressions, offsets);
|
|
142
|
+
}
|
|
143
|
+
wrapLiteralPrimitive(input, location) {
|
|
144
|
+
return new ASTWithSource(new LiteralPrimitive(new ParseSpan(0, isBlank(input) ? 0 : input.length), input), input, location, this.errors);
|
|
145
|
+
}
|
|
146
|
+
_stripComments(input) {
|
|
147
|
+
const i = this._commentStart(input);
|
|
148
|
+
return isPresent(i) ? input.substring(0, i).trim() : input;
|
|
149
|
+
}
|
|
150
|
+
_commentStart(input) {
|
|
151
|
+
let outerQuote = null;
|
|
152
|
+
for (let i = 0; i < input.length - 1; i++) {
|
|
153
|
+
const char = input.charCodeAt(i);
|
|
154
|
+
const nextChar = input.charCodeAt(i + 1);
|
|
155
|
+
if (char === chars.$SLASH && nextChar == chars.$SLASH && isBlank(outerQuote))
|
|
156
|
+
return i;
|
|
157
|
+
if (outerQuote === char) {
|
|
158
|
+
outerQuote = null;
|
|
159
|
+
}
|
|
160
|
+
else if (isBlank(outerQuote) && isQuote(char)) {
|
|
161
|
+
outerQuote = char;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return null;
|
|
165
|
+
}
|
|
166
|
+
_checkNoInterpolation(input, location, interpolationConfig) {
|
|
167
|
+
const regexp = _createInterpolateRegExp(interpolationConfig);
|
|
168
|
+
const parts = input.split(regexp);
|
|
169
|
+
if (parts.length > 1) {
|
|
170
|
+
this._reportError(`Got interpolation (${interpolationConfig.start}${interpolationConfig.end}) where expression was expected`, input, `at column ${this._findInterpolationErrorColumn(parts, 1, interpolationConfig)} in`, location);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
_findInterpolationErrorColumn(parts, partInErrIdx, interpolationConfig) {
|
|
174
|
+
let errLocation = '';
|
|
175
|
+
for (let j = 0; j < partInErrIdx; j++) {
|
|
176
|
+
errLocation += j % 2 === 0 ?
|
|
177
|
+
parts[j] :
|
|
178
|
+
`${interpolationConfig.start}${parts[j]}${interpolationConfig.end}`;
|
|
179
|
+
}
|
|
180
|
+
return errLocation.length;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
export class _ParseAST {
|
|
184
|
+
constructor(input, location, tokens, inputLength, parseAction, errors, offset) {
|
|
185
|
+
this.input = input;
|
|
186
|
+
this.location = location;
|
|
187
|
+
this.tokens = tokens;
|
|
188
|
+
this.inputLength = inputLength;
|
|
189
|
+
this.parseAction = parseAction;
|
|
190
|
+
this.errors = errors;
|
|
191
|
+
this.offset = offset;
|
|
192
|
+
this.rparensExpected = 0;
|
|
193
|
+
this.rbracketsExpected = 0;
|
|
194
|
+
this.rbracesExpected = 0;
|
|
195
|
+
this.index = 0;
|
|
196
|
+
}
|
|
197
|
+
peek(offset) {
|
|
198
|
+
const i = this.index + offset;
|
|
199
|
+
return i < this.tokens.length ? this.tokens[i] : EOF;
|
|
200
|
+
}
|
|
201
|
+
get next() { return this.peek(0); }
|
|
202
|
+
get inputIndex() {
|
|
203
|
+
return (this.index < this.tokens.length) ? this.next.index + this.offset :
|
|
204
|
+
this.inputLength + this.offset;
|
|
205
|
+
}
|
|
206
|
+
span(start) { return new ParseSpan(start, this.inputIndex); }
|
|
207
|
+
advance() { this.index++; }
|
|
208
|
+
optionalCharacter(code) {
|
|
209
|
+
if (this.next.isCharacter(code)) {
|
|
210
|
+
this.advance();
|
|
211
|
+
return true;
|
|
212
|
+
}
|
|
213
|
+
else {
|
|
214
|
+
return false;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
peekKeywordLet() { return this.next.isKeywordLet(); }
|
|
218
|
+
expectCharacter(code) {
|
|
219
|
+
if (this.optionalCharacter(code))
|
|
220
|
+
return;
|
|
221
|
+
this.error(`Missing expected ${String.fromCharCode(code)}`);
|
|
222
|
+
}
|
|
223
|
+
optionalOperator(op) {
|
|
224
|
+
if (this.next.isOperator(op)) {
|
|
225
|
+
this.advance();
|
|
226
|
+
return true;
|
|
227
|
+
}
|
|
228
|
+
else {
|
|
229
|
+
return false;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
expectOperator(operator) {
|
|
233
|
+
if (this.optionalOperator(operator))
|
|
234
|
+
return;
|
|
235
|
+
this.error(`Missing expected operator ${operator}`);
|
|
236
|
+
}
|
|
237
|
+
expectIdentifierOrKeyword() {
|
|
238
|
+
const n = this.next;
|
|
239
|
+
if (!n.isIdentifier() && !n.isKeyword()) {
|
|
240
|
+
this.error(`Unexpected token ${n}, expected identifier or keyword`);
|
|
241
|
+
return '';
|
|
242
|
+
}
|
|
243
|
+
this.advance();
|
|
244
|
+
return n.toString();
|
|
245
|
+
}
|
|
246
|
+
expectIdentifierOrKeywordOrString() {
|
|
247
|
+
const n = this.next;
|
|
248
|
+
if (!n.isIdentifier() && !n.isKeyword() && !n.isString()) {
|
|
249
|
+
this.error(`Unexpected token ${n}, expected identifier, keyword, or string`);
|
|
250
|
+
return '';
|
|
251
|
+
}
|
|
252
|
+
this.advance();
|
|
253
|
+
return n.toString();
|
|
254
|
+
}
|
|
255
|
+
parseChain() {
|
|
256
|
+
const exprs = [];
|
|
257
|
+
const start = this.inputIndex;
|
|
258
|
+
while (this.index < this.tokens.length) {
|
|
259
|
+
const expr = this.parsePipe();
|
|
260
|
+
exprs.push(expr);
|
|
261
|
+
if (this.optionalCharacter(chars.$SEMICOLON)) {
|
|
262
|
+
if (!this.parseAction) {
|
|
263
|
+
this.error('Binding expression cannot contain chained expression');
|
|
264
|
+
}
|
|
265
|
+
while (this.optionalCharacter(chars.$SEMICOLON)) {
|
|
266
|
+
} // read all semicolons
|
|
267
|
+
}
|
|
268
|
+
else if (this.index < this.tokens.length) {
|
|
269
|
+
this.error(`Unexpected token '${this.next}'`);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
if (exprs.length == 0)
|
|
273
|
+
return new EmptyExpr(this.span(start));
|
|
274
|
+
if (exprs.length == 1)
|
|
275
|
+
return exprs[0];
|
|
276
|
+
return new Chain(this.span(start), exprs);
|
|
277
|
+
}
|
|
278
|
+
parsePipe() {
|
|
279
|
+
let result = this.parseExpression();
|
|
280
|
+
if (this.optionalOperator('|')) {
|
|
281
|
+
if (this.parseAction) {
|
|
282
|
+
this.error('Cannot have a pipe in an action expression');
|
|
283
|
+
}
|
|
284
|
+
do {
|
|
285
|
+
const name = this.expectIdentifierOrKeyword();
|
|
286
|
+
const args = [];
|
|
287
|
+
while (this.optionalCharacter(chars.$COLON)) {
|
|
288
|
+
args.push(this.parseExpression());
|
|
289
|
+
}
|
|
290
|
+
result = new BindingPipe(this.span(result.span.start), result, name, args);
|
|
291
|
+
} while (this.optionalOperator('|'));
|
|
292
|
+
}
|
|
293
|
+
return result;
|
|
294
|
+
}
|
|
295
|
+
parseExpression() { return this.parseConditional(); }
|
|
296
|
+
parseConditional() {
|
|
297
|
+
const start = this.inputIndex;
|
|
298
|
+
const result = this.parseLogicalOr();
|
|
299
|
+
if (this.optionalOperator('?')) {
|
|
300
|
+
const yes = this.parsePipe();
|
|
301
|
+
let no;
|
|
302
|
+
if (!this.optionalCharacter(chars.$COLON)) {
|
|
303
|
+
const end = this.inputIndex;
|
|
304
|
+
const expression = this.input.substring(start, end);
|
|
305
|
+
this.error(`Conditional expression ${expression} requires all 3 expressions`);
|
|
306
|
+
no = new EmptyExpr(this.span(start));
|
|
307
|
+
}
|
|
308
|
+
else {
|
|
309
|
+
no = this.parsePipe();
|
|
310
|
+
}
|
|
311
|
+
return new Conditional(this.span(start), result, yes, no);
|
|
312
|
+
}
|
|
313
|
+
else {
|
|
314
|
+
return result;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
parseLogicalOr() {
|
|
318
|
+
// '||'
|
|
319
|
+
let result = this.parseLogicalAnd();
|
|
320
|
+
while (this.optionalOperator('||')) {
|
|
321
|
+
const right = this.parseLogicalAnd();
|
|
322
|
+
result = new Binary(this.span(result.span.start), '||', result, right);
|
|
323
|
+
}
|
|
324
|
+
return result;
|
|
325
|
+
}
|
|
326
|
+
parseLogicalAnd() {
|
|
327
|
+
// '&&'
|
|
328
|
+
let result = this.parseEquality();
|
|
329
|
+
while (this.optionalOperator('&&')) {
|
|
330
|
+
const right = this.parseEquality();
|
|
331
|
+
result = new Binary(this.span(result.span.start), '&&', result, right);
|
|
332
|
+
}
|
|
333
|
+
return result;
|
|
334
|
+
}
|
|
335
|
+
parseEquality() {
|
|
336
|
+
// '==','!=','===','!=='
|
|
337
|
+
let result = this.parseRelational();
|
|
338
|
+
while (this.next.type == TokenType.Operator) {
|
|
339
|
+
const operator = this.next.strValue;
|
|
340
|
+
switch (operator) {
|
|
341
|
+
case '==':
|
|
342
|
+
case '===':
|
|
343
|
+
case '!=':
|
|
344
|
+
case '!==':
|
|
345
|
+
this.advance();
|
|
346
|
+
const right = this.parseRelational();
|
|
347
|
+
result = new Binary(this.span(result.span.start), operator, result, right);
|
|
348
|
+
continue;
|
|
349
|
+
}
|
|
350
|
+
break;
|
|
351
|
+
}
|
|
352
|
+
return result;
|
|
353
|
+
}
|
|
354
|
+
parseRelational() {
|
|
355
|
+
// '<', '>', '<=', '>='
|
|
356
|
+
let result = this.parseAdditive();
|
|
357
|
+
while (this.next.type == TokenType.Operator) {
|
|
358
|
+
const operator = this.next.strValue;
|
|
359
|
+
switch (operator) {
|
|
360
|
+
case '<':
|
|
361
|
+
case '>':
|
|
362
|
+
case '<=':
|
|
363
|
+
case '>=':
|
|
364
|
+
this.advance();
|
|
365
|
+
const right = this.parseAdditive();
|
|
366
|
+
result = new Binary(this.span(result.span.start), operator, result, right);
|
|
367
|
+
continue;
|
|
368
|
+
}
|
|
369
|
+
break;
|
|
370
|
+
}
|
|
371
|
+
return result;
|
|
372
|
+
}
|
|
373
|
+
parseAdditive() {
|
|
374
|
+
// '+', '-'
|
|
375
|
+
let result = this.parseMultiplicative();
|
|
376
|
+
while (this.next.type == TokenType.Operator) {
|
|
377
|
+
const operator = this.next.strValue;
|
|
378
|
+
switch (operator) {
|
|
379
|
+
case '+':
|
|
380
|
+
case '-':
|
|
381
|
+
this.advance();
|
|
382
|
+
let right = this.parseMultiplicative();
|
|
383
|
+
result = new Binary(this.span(result.span.start), operator, result, right);
|
|
384
|
+
continue;
|
|
385
|
+
}
|
|
386
|
+
break;
|
|
387
|
+
}
|
|
388
|
+
return result;
|
|
389
|
+
}
|
|
390
|
+
parseMultiplicative() {
|
|
391
|
+
// '*', '%', '/'
|
|
392
|
+
let result = this.parsePrefix();
|
|
393
|
+
while (this.next.type == TokenType.Operator) {
|
|
394
|
+
const operator = this.next.strValue;
|
|
395
|
+
switch (operator) {
|
|
396
|
+
case '*':
|
|
397
|
+
case '%':
|
|
398
|
+
case '/':
|
|
399
|
+
this.advance();
|
|
400
|
+
let right = this.parsePrefix();
|
|
401
|
+
result = new Binary(this.span(result.span.start), operator, result, right);
|
|
402
|
+
continue;
|
|
403
|
+
}
|
|
404
|
+
break;
|
|
405
|
+
}
|
|
406
|
+
return result;
|
|
407
|
+
}
|
|
408
|
+
parsePrefix() {
|
|
409
|
+
if (this.next.type == TokenType.Operator) {
|
|
410
|
+
const start = this.inputIndex;
|
|
411
|
+
const operator = this.next.strValue;
|
|
412
|
+
let result;
|
|
413
|
+
switch (operator) {
|
|
414
|
+
case '+':
|
|
415
|
+
this.advance();
|
|
416
|
+
return this.parsePrefix();
|
|
417
|
+
case '-':
|
|
418
|
+
this.advance();
|
|
419
|
+
result = this.parsePrefix();
|
|
420
|
+
return new Binary(this.span(start), operator, new LiteralPrimitive(new ParseSpan(start, start), 0), result);
|
|
421
|
+
case '!':
|
|
422
|
+
this.advance();
|
|
423
|
+
result = this.parsePrefix();
|
|
424
|
+
return new PrefixNot(this.span(start), result);
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
return this.parseCallChain();
|
|
428
|
+
}
|
|
429
|
+
parseCallChain() {
|
|
430
|
+
let result = this.parsePrimary();
|
|
431
|
+
while (true) {
|
|
432
|
+
if (this.optionalCharacter(chars.$PERIOD)) {
|
|
433
|
+
result = this.parseAccessMemberOrMethodCall(result, false);
|
|
434
|
+
}
|
|
435
|
+
else if (this.optionalOperator('?.')) {
|
|
436
|
+
result = this.parseAccessMemberOrMethodCall(result, true);
|
|
437
|
+
}
|
|
438
|
+
else if (this.optionalCharacter(chars.$LBRACKET)) {
|
|
439
|
+
this.rbracketsExpected++;
|
|
440
|
+
const key = this.parsePipe();
|
|
441
|
+
this.rbracketsExpected--;
|
|
442
|
+
this.expectCharacter(chars.$RBRACKET);
|
|
443
|
+
if (this.optionalOperator('=')) {
|
|
444
|
+
const value = this.parseConditional();
|
|
445
|
+
result = new KeyedWrite(this.span(result.span.start), result, key, value);
|
|
446
|
+
}
|
|
447
|
+
else {
|
|
448
|
+
result = new KeyedRead(this.span(result.span.start), result, key);
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
else if (this.optionalCharacter(chars.$LPAREN)) {
|
|
452
|
+
this.rparensExpected++;
|
|
453
|
+
const args = this.parseCallArguments();
|
|
454
|
+
this.rparensExpected--;
|
|
455
|
+
this.expectCharacter(chars.$RPAREN);
|
|
456
|
+
result = new FunctionCall(this.span(result.span.start), result, args);
|
|
457
|
+
}
|
|
458
|
+
else {
|
|
459
|
+
return result;
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
parsePrimary() {
|
|
464
|
+
const start = this.inputIndex;
|
|
465
|
+
if (this.optionalCharacter(chars.$LPAREN)) {
|
|
466
|
+
this.rparensExpected++;
|
|
467
|
+
const result = this.parsePipe();
|
|
468
|
+
this.rparensExpected--;
|
|
469
|
+
this.expectCharacter(chars.$RPAREN);
|
|
470
|
+
return result;
|
|
471
|
+
}
|
|
472
|
+
else if (this.next.isKeywordNull()) {
|
|
473
|
+
this.advance();
|
|
474
|
+
return new LiteralPrimitive(this.span(start), null);
|
|
475
|
+
}
|
|
476
|
+
else if (this.next.isKeywordUndefined()) {
|
|
477
|
+
this.advance();
|
|
478
|
+
return new LiteralPrimitive(this.span(start), void 0);
|
|
479
|
+
}
|
|
480
|
+
else if (this.next.isKeywordTrue()) {
|
|
481
|
+
this.advance();
|
|
482
|
+
return new LiteralPrimitive(this.span(start), true);
|
|
483
|
+
}
|
|
484
|
+
else if (this.next.isKeywordFalse()) {
|
|
485
|
+
this.advance();
|
|
486
|
+
return new LiteralPrimitive(this.span(start), false);
|
|
487
|
+
}
|
|
488
|
+
else if (this.next.isKeywordThis()) {
|
|
489
|
+
this.advance();
|
|
490
|
+
return new ImplicitReceiver(this.span(start));
|
|
491
|
+
}
|
|
492
|
+
else if (this.optionalCharacter(chars.$LBRACKET)) {
|
|
493
|
+
this.rbracketsExpected++;
|
|
494
|
+
const elements = this.parseExpressionList(chars.$RBRACKET);
|
|
495
|
+
this.rbracketsExpected--;
|
|
496
|
+
this.expectCharacter(chars.$RBRACKET);
|
|
497
|
+
return new LiteralArray(this.span(start), elements);
|
|
498
|
+
}
|
|
499
|
+
else if (this.next.isCharacter(chars.$LBRACE)) {
|
|
500
|
+
return this.parseLiteralMap();
|
|
501
|
+
}
|
|
502
|
+
else if (this.next.isIdentifier()) {
|
|
503
|
+
return this.parseAccessMemberOrMethodCall(new ImplicitReceiver(this.span(start)), false);
|
|
504
|
+
}
|
|
505
|
+
else if (this.next.isNumber()) {
|
|
506
|
+
const value = this.next.toNumber();
|
|
507
|
+
this.advance();
|
|
508
|
+
return new LiteralPrimitive(this.span(start), value);
|
|
509
|
+
}
|
|
510
|
+
else if (this.next.isString()) {
|
|
511
|
+
const literalValue = this.next.toString();
|
|
512
|
+
this.advance();
|
|
513
|
+
return new LiteralPrimitive(this.span(start), literalValue);
|
|
514
|
+
}
|
|
515
|
+
else if (this.index >= this.tokens.length) {
|
|
516
|
+
this.error(`Unexpected end of expression: ${this.input}`);
|
|
517
|
+
return new EmptyExpr(this.span(start));
|
|
518
|
+
}
|
|
519
|
+
else {
|
|
520
|
+
this.error(`Unexpected token ${this.next}`);
|
|
521
|
+
return new EmptyExpr(this.span(start));
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
parseExpressionList(terminator) {
|
|
525
|
+
const result = [];
|
|
526
|
+
if (!this.next.isCharacter(terminator)) {
|
|
527
|
+
do {
|
|
528
|
+
result.push(this.parsePipe());
|
|
529
|
+
} while (this.optionalCharacter(chars.$COMMA));
|
|
530
|
+
}
|
|
531
|
+
return result;
|
|
532
|
+
}
|
|
533
|
+
parseLiteralMap() {
|
|
534
|
+
const keys = [];
|
|
535
|
+
const values = [];
|
|
536
|
+
const start = this.inputIndex;
|
|
537
|
+
this.expectCharacter(chars.$LBRACE);
|
|
538
|
+
if (!this.optionalCharacter(chars.$RBRACE)) {
|
|
539
|
+
this.rbracesExpected++;
|
|
540
|
+
do {
|
|
541
|
+
const key = this.expectIdentifierOrKeywordOrString();
|
|
542
|
+
keys.push(key);
|
|
543
|
+
this.expectCharacter(chars.$COLON);
|
|
544
|
+
values.push(this.parsePipe());
|
|
545
|
+
} while (this.optionalCharacter(chars.$COMMA));
|
|
546
|
+
this.rbracesExpected--;
|
|
547
|
+
this.expectCharacter(chars.$RBRACE);
|
|
548
|
+
}
|
|
549
|
+
return new LiteralMap(this.span(start), keys, values);
|
|
550
|
+
}
|
|
551
|
+
parseAccessMemberOrMethodCall(receiver, isSafe = false) {
|
|
552
|
+
const start = receiver.span.start;
|
|
553
|
+
const id = this.expectIdentifierOrKeyword();
|
|
554
|
+
if (this.optionalCharacter(chars.$LPAREN)) {
|
|
555
|
+
this.rparensExpected++;
|
|
556
|
+
const args = this.parseCallArguments();
|
|
557
|
+
this.expectCharacter(chars.$RPAREN);
|
|
558
|
+
this.rparensExpected--;
|
|
559
|
+
const span = this.span(start);
|
|
560
|
+
return isSafe ? new SafeMethodCall(span, receiver, id, args) :
|
|
561
|
+
new MethodCall(span, receiver, id, args);
|
|
562
|
+
}
|
|
563
|
+
else {
|
|
564
|
+
if (isSafe) {
|
|
565
|
+
if (this.optionalOperator('=')) {
|
|
566
|
+
this.error('The \'?.\' operator cannot be used in the assignment');
|
|
567
|
+
return new EmptyExpr(this.span(start));
|
|
568
|
+
}
|
|
569
|
+
else {
|
|
570
|
+
return new SafePropertyRead(this.span(start), receiver, id);
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
else {
|
|
574
|
+
if (this.optionalOperator('=')) {
|
|
575
|
+
if (!this.parseAction) {
|
|
576
|
+
this.error('Bindings cannot contain assignments');
|
|
577
|
+
return new EmptyExpr(this.span(start));
|
|
578
|
+
}
|
|
579
|
+
const value = this.parseConditional();
|
|
580
|
+
return new PropertyWrite(this.span(start), receiver, id, value);
|
|
581
|
+
}
|
|
582
|
+
else {
|
|
583
|
+
return new PropertyRead(this.span(start), receiver, id);
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
parseCallArguments() {
|
|
589
|
+
if (this.next.isCharacter(chars.$RPAREN))
|
|
590
|
+
return [];
|
|
591
|
+
const positionals = [];
|
|
592
|
+
do {
|
|
593
|
+
positionals.push(this.parsePipe());
|
|
594
|
+
} while (this.optionalCharacter(chars.$COMMA));
|
|
595
|
+
return positionals;
|
|
596
|
+
}
|
|
597
|
+
/**
|
|
598
|
+
* An identifier, a keyword, a string with an optional `-` inbetween.
|
|
599
|
+
*/
|
|
600
|
+
expectTemplateBindingKey() {
|
|
601
|
+
let result = '';
|
|
602
|
+
let operatorFound = false;
|
|
603
|
+
do {
|
|
604
|
+
result += this.expectIdentifierOrKeywordOrString();
|
|
605
|
+
operatorFound = this.optionalOperator('-');
|
|
606
|
+
if (operatorFound) {
|
|
607
|
+
result += '-';
|
|
608
|
+
}
|
|
609
|
+
} while (operatorFound);
|
|
610
|
+
return result.toString();
|
|
611
|
+
}
|
|
612
|
+
parseTemplateBindings() {
|
|
613
|
+
const bindings = [];
|
|
614
|
+
let prefix = null;
|
|
615
|
+
const warnings = [];
|
|
616
|
+
while (this.index < this.tokens.length) {
|
|
617
|
+
const start = this.inputIndex;
|
|
618
|
+
const keyIsVar = this.peekKeywordLet();
|
|
619
|
+
if (keyIsVar) {
|
|
620
|
+
this.advance();
|
|
621
|
+
}
|
|
622
|
+
let key = this.expectTemplateBindingKey();
|
|
623
|
+
if (!keyIsVar) {
|
|
624
|
+
if (prefix == null) {
|
|
625
|
+
prefix = key;
|
|
626
|
+
}
|
|
627
|
+
else {
|
|
628
|
+
key = prefix + key[0].toUpperCase() + key.substring(1);
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
this.optionalCharacter(chars.$COLON);
|
|
632
|
+
let name = null;
|
|
633
|
+
let expression = null;
|
|
634
|
+
if (keyIsVar) {
|
|
635
|
+
if (this.optionalOperator('=')) {
|
|
636
|
+
name = this.expectTemplateBindingKey();
|
|
637
|
+
}
|
|
638
|
+
else {
|
|
639
|
+
name = '\$implicit';
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
else if (this.next !== EOF && !this.peekKeywordLet()) {
|
|
643
|
+
const start = this.inputIndex;
|
|
644
|
+
const ast = this.parsePipe();
|
|
645
|
+
const source = this.input.substring(start - this.offset, this.inputIndex - this.offset);
|
|
646
|
+
expression = new ASTWithSource(ast, source, this.location, this.errors);
|
|
647
|
+
}
|
|
648
|
+
bindings.push(new TemplateBinding(this.span(start), key, keyIsVar, name, expression));
|
|
649
|
+
if (!this.optionalCharacter(chars.$SEMICOLON)) {
|
|
650
|
+
this.optionalCharacter(chars.$COMMA);
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
return new TemplateBindingParseResult(bindings, warnings, this.errors);
|
|
654
|
+
}
|
|
655
|
+
error(message, index = null) {
|
|
656
|
+
this.errors.push(new ParserError(message, this.input, this.locationText(index), this.location));
|
|
657
|
+
this.skip();
|
|
658
|
+
}
|
|
659
|
+
locationText(index = null) {
|
|
660
|
+
if (isBlank(index))
|
|
661
|
+
index = this.index;
|
|
662
|
+
return (index < this.tokens.length) ? `at column ${this.tokens[index].index + 1} in` :
|
|
663
|
+
`at the end of the expression`;
|
|
664
|
+
}
|
|
665
|
+
// Error recovery should skip tokens until it encounters a recovery point. skip() treats
|
|
666
|
+
// the end of input and a ';' as unconditionally a recovery point. It also treats ')',
|
|
667
|
+
// '}' and ']' as conditional recovery points if one of calling productions is expecting
|
|
668
|
+
// one of these symbols. This allows skip() to recover from errors such as '(a.) + 1' allowing
|
|
669
|
+
// more of the AST to be retained (it doesn't skip any tokens as the ')' is retained because
|
|
670
|
+
// of the '(' begins an '(' <expr> ')' production). The recovery points of grouping symbols
|
|
671
|
+
// must be conditional as they must be skipped if none of the calling productions are not
|
|
672
|
+
// expecting the closing token else we will never make progress in the case of an
|
|
673
|
+
// extraneous group closing symbol (such as a stray ')'). This is not the case for ';' because
|
|
674
|
+
// parseChain() is always the root production and it expects a ';'.
|
|
675
|
+
// If a production expects one of these token it increments the corresponding nesting count,
|
|
676
|
+
// and then decrements it just prior to checking if the token is in the input.
|
|
677
|
+
skip() {
|
|
678
|
+
let n = this.next;
|
|
679
|
+
while (this.index < this.tokens.length && !n.isCharacter(chars.$SEMICOLON) &&
|
|
680
|
+
(this.rparensExpected <= 0 || !n.isCharacter(chars.$RPAREN)) &&
|
|
681
|
+
(this.rbracesExpected <= 0 || !n.isCharacter(chars.$RBRACE)) &&
|
|
682
|
+
(this.rbracketsExpected <= 0 || !n.isCharacter(chars.$RBRACKET))) {
|
|
683
|
+
if (this.next.isError()) {
|
|
684
|
+
this.errors.push(new ParserError(this.next.toString(), this.input, this.locationText(), this.location));
|
|
685
|
+
}
|
|
686
|
+
this.advance();
|
|
687
|
+
n = this.next;
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
class SimpleExpressionChecker {
|
|
692
|
+
constructor() {
|
|
693
|
+
this.errors = [];
|
|
694
|
+
}
|
|
695
|
+
static check(ast) {
|
|
696
|
+
const s = new SimpleExpressionChecker();
|
|
697
|
+
ast.visit(s);
|
|
698
|
+
return s.errors;
|
|
699
|
+
}
|
|
700
|
+
visitImplicitReceiver(ast, context) { }
|
|
701
|
+
visitInterpolation(ast, context) { }
|
|
702
|
+
visitLiteralPrimitive(ast, context) { }
|
|
703
|
+
visitPropertyRead(ast, context) { }
|
|
704
|
+
visitPropertyWrite(ast, context) { }
|
|
705
|
+
visitSafePropertyRead(ast, context) { }
|
|
706
|
+
visitMethodCall(ast, context) { }
|
|
707
|
+
visitSafeMethodCall(ast, context) { }
|
|
708
|
+
visitFunctionCall(ast, context) { }
|
|
709
|
+
visitLiteralArray(ast, context) { this.visitAll(ast.expressions); }
|
|
710
|
+
visitLiteralMap(ast, context) { this.visitAll(ast.values); }
|
|
711
|
+
visitBinary(ast, context) { }
|
|
712
|
+
visitPrefixNot(ast, context) { }
|
|
713
|
+
visitConditional(ast, context) { }
|
|
714
|
+
visitPipe(ast, context) { this.errors.push('pipes'); }
|
|
715
|
+
visitKeyedRead(ast, context) { }
|
|
716
|
+
visitKeyedWrite(ast, context) { }
|
|
717
|
+
visitAll(asts) { return asts.map(node => node.visit(this)); }
|
|
718
|
+
visitChain(ast, context) { }
|
|
719
|
+
visitQuote(ast, context) { }
|
|
720
|
+
}
|
|
721
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFyc2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYW5ndWxhcjJwYXJzZS9zcmMvbGliL2FuZ3VsYXIvY29tcGlsZXIvcGFyc2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7R0FNRztBQUVILE9BQU8sS0FBSyxLQUFLLE1BQU0sU0FBUyxDQUFDO0FBQ2pDLE9BQU8sRUFBQyxZQUFZLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBQyxNQUFNLGdCQUFnQixDQUFDO0FBQ2hFLE9BQU8sRUFBQyw0QkFBNEIsRUFBc0IsTUFBTSx3QkFBd0IsQ0FBQztBQUV6RixPQUFPLEVBQU0sYUFBYSxFQUFjLE1BQU0sRUFBRSxXQUFXLEVBQUUsS0FBSyxFQUFFLFdBQVcsRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLGdCQUFnQixFQUFFLGFBQWEsRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUFFLFlBQVksRUFBRSxVQUFVLEVBQUUsZ0JBQWdCLEVBQUUsVUFBVSxFQUFFLFNBQVMsRUFBRSxXQUFXLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxhQUFhLEVBQUUsS0FBSyxFQUFFLGNBQWMsRUFBRSxnQkFBZ0IsRUFBRSxlQUFlLEVBQUMsTUFBTSxPQUFPLENBQUM7QUFDalcsT0FBTyxFQUFDLEdBQUcsRUFBZ0IsU0FBUyxFQUFFLFlBQVksRUFBRSxPQUFPLEVBQUMsTUFBTSxTQUFTLENBQUM7QUFHNUUsTUFBTSxPQUFPLGtCQUFrQjtJQUMzQixZQUFtQixPQUFpQixFQUFTLFdBQXFCLEVBQVMsT0FBaUI7UUFBekUsWUFBTyxHQUFQLE9BQU8sQ0FBVTtRQUFTLGdCQUFXLEdBQVgsV0FBVyxDQUFVO1FBQVMsWUFBTyxHQUFQLE9BQU8sQ0FBVTtJQUFHLENBQUM7Q0FDbkc7QUFFRCxNQUFNLE9BQU8sMEJBQTBCO0lBQ25DLFlBQ1csZ0JBQW1DLEVBQVMsUUFBa0IsRUFDOUQsTUFBcUI7UUFEckIscUJBQWdC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R0FBZSxFQUFFLE9BQVksSUFBRyxDQUFDO0lBRWpELFFBQVEsQ0FBQyxJQUFXLElBQVcsT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUUzRSxVQUFVLENBQUMsR0FBVSxFQUFFLE9BQVksSUFBRyxDQUFDO0lBRXZDLFVBQVUsQ0FBQyxHQUFVLEVBQUUsT0FBWSxJQUFHLENBQUM7Q0FDMUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcclxuICogQGxpY2Vuc2VcclxuICogQ29weXJpZ2h0IEdvb2dsZSBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXHJcbiAqXHJcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXHJcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9hbmd1bGFyLmlvL2xpY2Vuc2VcclxuICovXHJcblxyXG5pbXBvcnQgKiBhcyBjaGFycyBmcm9tICcuL2NoYXJzJztcclxuaW1wb3J0IHtlc2NhcGVSZWdFeHAsIGlzQmxhbmssIGlzUHJlc2VudH0gZnJvbSAnLi4vZmFjYWRlL2xhbmcnO1xyXG5pbXBvcnQge0RFRkFVTFRfSU5URVJQT0xBVElPTl9DT05GSUcsIEludGVycG9sYXRpb25Db25maWd9IGZyb20gJy4vaW50ZXJwb2xhdGlvbi1jb25maWcnO1xyXG5cclxuaW1wb3J0IHtBU1QsIEFTVFdpdGhTb3VyY2UsIEFzdFZpc2l0b3IsIEJpbmFyeSwgQmluZGluZ1BpcGUsIENoYWluLCBDb25kaXRpb25hbCwgRW1wdHlFeHByLCBGdW5jdGlvbkNhbGwsIEltcGxpY2l0UmVjZWl2ZXIsIEludGVycG9sYXRpb24sIEtleWVkUmVhZCwgS2V5ZWRXcml0ZSwgTGl0ZXJhbEFycmF5LCBMaXRlcmFsTWFwLCBMaXRlcmFsUHJpbWl0aXZlLCBNZXRob2RDYWxsLCBQYXJzZVNwYW4sIFBhcnNlckVycm9yLCBQcmVmaXhOb3QsIFByb3BlcnR5UmVhZCwgUHJvcGVydHlXcml0ZSwgUXVvdGUsIFNhZmVNZXRob2RDYWxsLCBTYWZlUHJvcGVydHlSZWFkLCBUZW1wbGF0ZUJpbmRpbmd9IGZyb20gJy4vYXN0JztcclxuaW1wb3J0IHtFT0YsIExleGVyLCBUb2tlbiwgVG9rZW5UeXBlLCBpc0lkZW50aWZpZXIsIGlzUXVvdGV9IGZyb20gJy4vbGV4ZXInO1xyXG5cclxuXHJcbmV4cG9ydCBjbGFzcyBTcGxpdEludGVycG9sYXRpb24ge1xyXG4gICAgY29uc3RydWN0b3IocHVibGljIHN0cmluZ3M6IHN0cmluZ1tdLCBwdWJsaWMgZXhwcmVzc2lvbnM6IHN0cmluZ1tdLCBwdWJsaWMgb2Zmc2V0czogbnVtYmVyW10pIHt9XHJcbn1cclxuXHJcbmV4cG9ydCBjbGFzcyBUZW1wbGF0ZUJpbmRpbmdQYXJzZVJlc3VsdCB7XHJcbiAgICBjb25zdHJ1Y3RvcihcclxuICAgICAgICBwdWJsaWMgdGVtcGxhdGVCaW5kaW5nczogVGVtcGxhdGVCaW5kaW5nW10sIHB1YmxpYyB3YXJuaW5nczogc3RyaW5nW10sXHJcbiAgICAgICAgcHVibGljIGVycm9yczogUGFyc2VyRXJyb3JbXSkge31cclxufVxyXG5cclxuZnVuY3Rpb24gX2NyZWF0ZUludGVycG9sYXRlUmVnRXhwKGNvbmZpZzogSW50ZXJwb2xhdGlvbkNvbmZpZyk6IFJlZ0V4cCB7XHJcbiAgICBjb25zdCBwYXR0ZXJuID0gZXNjYXBlUmVnRXhwKGNvbmZpZy5zdGFydCkgKyAnKFtcXFxcc1xcXFxTXSo/KScgKyBlc2NhcGVSZWdFeHAoY29uZmlnLmVuZCk7XHJcbiAgICByZXR1cm4gbmV3IFJlZ0V4cChwYXR0ZXJuLCAnZycpO1xyXG59XHJcblxyXG5leHBvcnQgY2xhc3MgUGFyc2VyIHtcclxuICAgIHByaXZhdGUgZXJyb3JzOiBQYXJzZXJFcnJvcltdID0gW107XHJcblxyXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBfbGV4ZXI6IExleGVyKSB7fVxyXG5cclxuICAgIHBhcnNlQWN0aW9uKFxyXG4gICAgICAgIGlucHV0OiBzdHJpbmcsIGxvY2F0aW9uOiBhbnksXHJcbiAgICAgICAgaW50ZXJwb2xhdGlvbkNvbmZpZzogSW50ZXJwb2xhdGlvbkNvbmZpZyA9IERFRkFVTFRfSU5URVJQT0xBVElPTl9DT05GSUcpOiBBU1RXaXRoU291cmNlIHtcclxuICAgICAgICB0aGlzLl9jaGVja05vSW50ZXJwb2xhdGlvbihpbnB1dCwgbG9jYXRpb24sIGludGVycG9sYXRpb25Db25maWcpO1xyXG4gICAgICAgIGNvbnN0IHNvdXJjZVRvTGV4ID0gdGhpcy5fc3RyaXBDb21tZW50cyhpbnB1dCk7XHJcbiAgICAgICAgY29uc3QgdG9rZW5zID0gdGhpcy5fbGV4ZXIudG9rZW5pemUodGhpcy5fc3RyaXBDb21tZW50cyhpbnB1dCkpO1xyXG4gICAgICAgIGNvbnN0IGFzdCA9IG5ldyBfUGFyc2VBU1QoXHJcbiAgICAgICAgICAgIGlucHV0LCBsb2NhdGlvbiwgdG9rZW5zLCBzb3VyY2VUb0xleC5sZW5ndGgsIHRydWUsIHRoaXMuZXJyb3JzLFxyXG4gICAgICAgICAgICBpbnB1dC5sZW5ndGggLSBzb3VyY2VUb0xleC5sZW5ndGgpXHJcbiAgICAgICAgICAgIC5wYXJzZUNoYWluKCk7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBBU1RXaXRoU291cmNlKGFzdCwgaW5wdXQsIGxvY2F0aW9uLCB0aGlzLmVycm9ycyk7XHJcbiAgICB9XHJcblxyXG4gICAgcGFyc2VCaW5kaW5nKFxyXG4gICAgICAgIGlucHV0OiBzdHJpbmcsIGxvY2F0aW9uOiBhbnksXHJcbiAgICAgICAgaW50ZXJwb2xhdGlvbkNvbmZpZzogSW50ZXJwb2xhdGlvbkNvbmZpZyA9IERFRkFVTFRfSU5URVJQT0xBVElPTl9DT05GSUcpOiBBU1RXaXRoU291cmNlIHtcclxuICAgICAgICBjb25zdCBhc3QgPSB0aGlzLl9wYXJzZUJpbmRpbmdBc3QoaW5wdXQsIGxvY2F0aW9uLCBpbnRlcnBvbGF0aW9uQ29uZmlnKTtcclxuICAgICAgICByZXR1cm4gbmV3IEFTVFdpdGhTb3VyY2UoYXN0LCBpbnB1dCwgbG9jYXRpb24sIHRoaXMuZXJyb3JzKTtcclxuICAgIH1cclxuXHJcbiAgICBwYXJzZVNpbXBsZUJpbmRpbmcoXHJcbiAgICAgICAgaW5wdXQ6IHN0cmluZywgbG9jYXRpb246IHN0cmluZyxcclxuICAgICAgICBpbnRlcnBvbGF0aW9uQ29uZmlnOiBJbnRlcnBvbGF0aW9uQ29uZmlnID0gREVGQVVMVF9JTlRFUlBPTEFUSU9OX0NPTkZJRyk6IEFTVFdpdGhTb3VyY2Uge1xyXG4gICAgICAgIGNvbnN0IGFzdCA9IHRoaXMuX3BhcnNlQmluZGluZ0FzdChpbnB1dCwgbG9jYXRpb24sIGludGVycG9sYXRpb25Db25maWcpO1xyXG4gICAgICAgIGNvbnN0IGVycm9ycyA9IFNpbXBsZUV4cHJlc3Npb25DaGVja2VyLmNoZWNrKGFzdCk7XHJcbiAgICAgICAgaWYgKGVycm9ycy5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX3JlcG9ydEVycm9yKFxyXG4gICAgICAgICAgICAgICAgYEhvc3QgYmluZGluZyBleHByZXNzaW9uIGNhbm5vdCBjb250YWluICR7ZXJyb3JzLmpvaW4oJyAnKX1gLCBpbnB1dCwgbG9jYXRpb24pO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gbmV3IEFTVFdpdGhTb3VyY2UoYXN0LCBpbnB1dCwgbG9jYXRpb24sIHRoaXMuZXJyb3JzKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9yZXBvcnRFcnJvcihtZXNzYWdlOiBzdHJpbmcsIGlucHV0OiBzdHJpbmcsIGVyckxvY2F0aW9uOiBzdHJpbmcsIGN0eExvY2F0aW9uPzogYW55KSB7XHJcbiAgICAgICAgdGhpcy5lcnJvcnMucHVzaChuZXcgUGFyc2VyRXJyb3IobWVzc2FnZSwgaW5wdXQsIGVyckxvY2F0aW9uLCBjdHhMb2NhdGlvbikpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX3BhcnNlQmluZGluZ0FzdChcclxuICAgICAgICBpbnB1dDogc3RyaW5nLCBsb2NhdGlvbjogc3RyaW5nLCBpbnRlcnBvbGF0aW9uQ29uZmlnOiBJbnRlcnBvbGF0aW9uQ29uZmlnKTogQVNUIHtcclxuICAgICAgICAvLyBRdW90ZXMgZXhwcmVzc2lvbnMgdXNlIDNyZC1wYXJ0eSBleHByZXNzaW9uIGxhbmd1YWdlLiBXZSBkb24ndCB3YW50IHRvIHVzZVxyXG4gICAgICAgIC8vIG91ciBsZXhlciBvciBwYXJzZXIgZm9yIHRoYXQsIHNvIHdlIGNoZWNrIGZvciB0aGF0IGFoZWFkIG9mIHRpbWUuXHJcbiAgICAgICAgY29uc3QgcXVvdGUgPSB0aGlzLl9wYXJzZVF1b3RlKGlucHV0LCBsb2NhdGlvbik7XHJcblxyXG4gICAgICAgIGlmIChpc1ByZXNlbnQocXVvdGUpKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBxdW90ZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuX2NoZWNrTm9JbnRlcnBvbGF0aW9uKGlucHV0LCBsb2NhdGlvbiwgaW50ZXJwb2xhdGlvbkNvbmZpZyk7XHJcbiAgICAgICAgY29uc3Qgc291cmNlVG9MZXggPSB0aGlzLl9zdHJpcENvbW1lbnRzKGlucHV0KTtcclxuICAgICAgICBjb25zdCB0b2tlbnMgPSB0aGlzLl9sZXhlci50b2tlbml6ZShzb3VyY2VUb0xleCk7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBfUGFyc2VBU1QoXHJcbiAgICAgICAgICAgIGlucHV0LCBsb2NhdGlvbiwgdG9rZW5zLCBzb3VyY2VUb0xleC5sZW5ndGgsIGZhbHNlLCB0aGlzLmVycm9ycyxcclxuICAgICAgICAgICAgaW5wdXQubGVuZ3RoIC0gc291cmNlVG9MZXgubGVuZ3RoKVxyXG4gICAgICAgICAgICAucGFyc2VDaGFpbigpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX3BhcnNlUXVvdGUoaW5wdXQ6IHN0cmluZywgbG9jYXRpb246IGFueSk6IEFTVCB7XHJcbiAgICAgICAgaWYgKGlzQmxhbmsoaW5wdXQpKSByZXR1cm4gbnVsbDtcclxuICAgICAgICBjb25zdCBwcmVmaXhTZXBhcmF0b3JJbmRleCA9IGlucHV0LmluZGV4T2YoJzonKTtcclxuICAgICAgICBpZiAocHJlZml4U2VwYXJhdG9ySW5kZXggPT0gLTEpIHJldHVybiBudWxsO1xyXG4gICAgICAgIGNvbnN0IHByZWZpeCA9IGlucHV0LnN1YnN0cmluZygwLCBwcmVmaXhTZXBhcmF0b3JJbmRleCkudHJpbSgpO1xyXG4gICAgICAgIGlmICghaXNJZGVudGlmaWVyKHByZWZpeCkpIHJldHVybiBudWxsO1xyXG4gICAgICAgIGNvbnN0IHVuaW50ZXJwcmV0ZWRFeHByZXNzaW9uID0gaW5wdXQuc3Vic3RyaW5nKHByZWZpeFNlcGFyYXRvckluZGV4ICsgMSk7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBRdW90ZShuZXcgUGFyc2VTcGFuKDAsIGlucHV0Lmxlbmd0aCksIHByZWZpeCwgdW5pbnRlcnByZXRlZEV4cHJlc3Npb24sIGxvY2F0aW9uKTtcclxuICAgIH1cclxuXHJcbiAgICBwYXJzZVRlbXBsYXRlQmluZGluZ3MocHJlZml4VG9rZW46IHN0cmluZywgaW5wdXQ6IHN0cmluZywgbG9jYXRpb246IGFueSk6XHJcbiAgICBUZW1wbGF0ZUJpbmRpbmdQYXJzZVJlc3VsdCB7XHJcbiAgICAgICAgY29uc3QgdG9rZW5zID0gdGhpcy5fbGV4ZXIudG9rZW5pemUoaW5wdXQpO1xyXG4gICAgICAgIGlmIChwcmVmaXhUb2tlbikge1xyXG4gICAgICAgICAgICAvLyBQcmVmaXggdGhlIHRva2VucyB3aXRoIHRoZSB0b2tlbnMgZnJvbSBwcmVmaXhUb2tlbiBidXQgaGF2ZSB0aGVtIHRha2Ugbm8gc3BhY2UgKDAgaW5kZXgpLlxyXG4gICAgICAgICAgICBjb25zdCBwcmVmaXhUb2tlbnMgPSB0aGlzLl9sZXhlci50b2tlbml6ZShwcmVmaXhUb2tlbikubWFwKHQgPT4ge1xyXG4gICAgICAgICAgICAgICAgdC5pbmRleCA9IDA7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdDtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIHRva2Vucy51bnNoaWZ0KC4uLnByZWZpeFRva2Vucyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBuZXcgX1BhcnNlQVNUKGlucHV0LCBsb2NhdGlvbiwgdG9rZW5zLCBpbnB1dC5sZW5ndGgsIGZhbHNlLCB0aGlzLmVycm9ycywgMClcclxuICAgICAgICAgICAgLnBhcnNlVGVtcGxhdGVCaW5kaW5ncygpO1xyXG4gICAgfVxyXG5cclxuICAgIHBhcnNlSW50ZXJwb2xhdGlvbihcclxuICAgICAgICBpbnB1dDogc3RyaW5nLCBsb2NhdGlvbjogYW55LFxyXG4gICAgICAgIGludGVycG9sYXRpb25Db25maWc6IEludGVycG9sYXRpb25Db25maWcgPSBERUZBVUxUX0lOVEVSUE9MQVRJT05fQ09ORklHKTogQVNUV2l0aFNvdXJjZSB7XHJcbiAgICAgICAgY29uc3Qgc3BsaXQgPSB0aGlzLnNwbGl0SW50ZXJwb2xhdGlvbihpbnB1dCwgbG9jYXRpb24sIGludGVycG9sYXRpb25Db25maWcpO1xyXG4gICAgICAgIGlmIChzcGxpdCA9PSBudWxsKSByZXR1cm4gbnVsbDtcclxuXHJcbiAgICAgICAgY29uc3QgZXhwcmVzc2lvbnM6IEFTVFtdID0gW107XHJcblxyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc3BsaXQuZXhwcmVzc2lvbnMubGVuZ3RoOyArK2kpIHtcclxuICAgICAgICAgICAgY29uc3QgZXhwcmVzc2lvblRleHQgPSBzcGxpdC5leHByZXNzaW9uc1tpXTtcclxuICAgICAgICAgICAgY29uc3Qgc291cmNlVG9MZXggPSB0aGlzLl9zdHJpcENvbW1lbnRzKGV4cHJlc3Npb25UZXh0KTtcclxuICAgICAgICAgICAgY29uc3QgdG9rZW5zID0gdGhpcy5fbGV4ZXIudG9rZW5pemUodGhpcy5fc3RyaXBDb21tZW50cyhzcGxpdC5leHByZXNzaW9uc1tpXSkpO1xyXG4gICAgICAgICAgICBjb25zdCBhc3QgPSBuZXcgX1BhcnNlQVNUKFxyXG4gICAgICAgICAgICAgICAgaW5wdXQsIGxvY2F0aW9uLCB0b2tlbnMsIHNvdXJjZVRvTGV4Lmxlbmd0aCwgZmFsc2UsIHRoaXMuZXJyb3JzLFxyXG4gICAgICAgICAgICAgICAgc3BsaXQub2Zmc2V0c1tpXSArIChleHByZXNzaW9uVGV4dC5sZW5ndGggLSBzb3VyY2VUb0xleC5sZW5ndGgpKVxyXG4gICAgICAgICAgICAgICAgLnBhcnNlQ2hhaW4oKTtcclxuICAgICAgICAgICAgZXhwcmVzc2lvbnMucHVzaChhc3QpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIG5ldyBBU1RXaXRoU291cmNlKFxyXG4gICAgICAgICAgICBuZXcgSW50ZXJwb2xhdGlvbihcclxuICAgICAgICAgICAgICAgIG5ldyBQYXJzZVNwYW4oMCwgaXNCbGFuayhpbnB1dCkgPyAwIDogaW5wdXQubGVuZ3RoKSwgc3BsaXQuc3RyaW5ncywgZXhwcmVzc2lvbnMpLFxyXG4gICAgICAgICAgICBpbnB1dCwgbG9jYXRpb24sIHRoaXMuZXJyb3JzKTtcclxuICAgIH1cclxuXHJcbiAgICBzcGxpdEludGVycG9sYXRpb24oXHJcbiAgICAgICAgaW5wdXQ6IHN0cmluZywgbG9jYXRpb246IHN0cmluZyxcclxuICAgICAgICBpbnRlcnBvbGF0aW9uQ29uZmlnOiBJbnRlcnBvbGF0aW9uQ29uZmlnID0gREVGQVVMVF9JTlRFUlBPTEFUSU9OX0NPTkZJRyk6IFNwbGl0SW50ZXJwb2xhdGlvbiB7XHJcbiAgICAgICAgY29uc3QgcmVnZXhwID0gX2NyZWF0ZUludGVycG9sYXRlUmVnRXhwKGludGVycG9sYXRpb25Db25maWcpO1xyXG4gICAgICAgIGNvbnN0IHBhcnRzID0gaW5wdXQuc3BsaXQocmVnZXhwKTtcclxuICAgICAgICBpZiAocGFydHMubGVuZ3RoIDw9IDEpIHtcclxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnN0IHN0cmluZ3M6IHN0cmluZ1tdID0gW107XHJcbiAgICAgICAgY29uc3QgZXhwcmVzc2lvbnM6IHN0cmluZ1tdID0gW107XHJcbiAgICAgICAgY29uc3Qgb2Zmc2V0czogbnVtYmVyW10gPSBbXTtcclxuICAgICAgICBsZXQgb2Zmc2V0ID0gMDtcclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHBhcnRzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHBhcnQ6IHN0cmluZyA9IHBhcnRzW2ldO1xyXG4gICAgICAgICAgICBpZiAoaSAlIDIgPT09IDApIHtcclxuICAgICAgICAgICAgICAgIC8vIGZpeGVkIHN0cmluZ1xyXG4gICAgICAgICAgICAgICAgc3RyaW5ncy5wdXNoKHBhcnQpO1xyXG4gICAgICAgICAgICAgICAgb2Zmc2V0ICs9IHBhcnQubGVuZ3RoO1xyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKHBhcnQudHJpbSgpLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgICAgIG9mZnNldCArPSBpbnRlcnBvbGF0aW9uQ29uZmlnLnN0YXJ0Lmxlbmd0aDtcclxuICAgICAgICAgICAgICAgIGV4cHJlc3Npb25zLnB1c2gocGFydCk7XHJcbiAgICAgICAgICAgICAgICBvZmZzZXRzLnB1c2gob2Zmc2V0KTtcclxuICAgICAgICAgICAgICAgIG9mZnNldCArPSBwYXJ0Lmxlbmd0aCArIGludGVycG9sYXRpb25Db25maWcuZW5kLmxlbmd0aDtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX3JlcG9ydEVycm9yKFxyXG4gICAgICAgICAgICAgICAgICAgICdCbGFuayBleHByZXNzaW9ucyBhcmUgbm90IGFsbG93ZWQgaW4gaW50ZXJwb2xhdGVkIHN0cmluZ3MnLCBpbnB1dCxcclxuICAgICAgICAgICAgICAgICAgICBgYXQgY29sdW1uICR7dGhpcy5fZmluZEludGVycG9sYXRpb25FcnJvckNvbHVtbihwYXJ0cywgaSwgaW50ZXJwb2xhdGlvbkNvbmZpZyl9IGluYCxcclxuICAgICAgICAgICAgICAgICAgICBsb2NhdGlvbik7XHJcbiAgICAgICAgICAgICAgICBleHByZXNzaW9ucy5wdXNoKCckaW1wbGljdCcpO1xyXG4gICAgICAgICAgICAgICAgb2Zmc2V0cy5wdXNoKG9mZnNldCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIG5ldyBTcGxpdEludGVycG9sYXRpb24oc3RyaW5ncywgZXhwcmVzc2lvbnMsIG9mZnNldHMpO1xyXG4gICAgfVxyXG5cclxuICAgIHdyYXBMaXRlcmFsUHJpbWl0aXZlKGlucHV0OiBzdHJpbmcsIGxvY2F0aW9uOiBhbnkpOiBBU1RXaXRoU291cmNlIHtcclxuICAgICAgICByZXR1cm4gbmV3IEFTVFdpdGhTb3VyY2UoXHJcbiAgICAgICAgICAgIG5ldyBMaXRlcmFsUHJpbWl0aXZlKG5ldyBQYXJzZVNwYW4oMCwgaXNCbGFuayhpbnB1dCkgPyAwIDogaW5wdXQubGVuZ3RoKSwgaW5wdXQpLCBpbnB1dCxcclxuICAgICAgICAgICAgbG9jYXRpb24sIHRoaXMuZXJyb3JzKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9zdHJpcENvbW1lbnRzKGlucHV0OiBzdHJpbmcpOiBzdHJpbmcge1xyXG4gICAgICAgIGNvbnN0IGkgPSB0aGlzLl9jb21tZW50U3RhcnQoaW5wdXQpO1xyXG4gICAgICAgIHJldHVybiBpc1ByZXNlbnQoaSkgPyBpbnB1dC5zdWJzdHJpbmcoMCwgaSkudHJpbSgpIDogaW5wdXQ7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfY29tbWVudFN0YXJ0KGlucHV0OiBzdHJpbmcpOiBudW1iZXIge1xyXG4gICAgICAgIGxldCBvdXRlclF1b3RlOiBudW1iZXIgPSBudWxsO1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW5wdXQubGVuZ3RoIC0gMTsgaSsrKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGNoYXIgPSBpbnB1dC5jaGFyQ29kZUF0KGkpO1xyXG4gICAgICAgICAgICBjb25zdCBuZXh0Q2hhciA9IGlucHV0LmNoYXJDb2RlQXQoaSArIDEpO1xyXG5cclxuICAgICAgICAgICAgaWYgKGNoYXIgPT09IGNoYXJzLiRTTEFTSCAmJiBuZXh0Q2hhciA9PSBjaGFycy4kU0xBU0ggJiYgaXNCbGFuayhvdXRlclF1b3RlKSkgcmV0dXJuIGk7XHJcblxyXG4gICAgICAgICAgICBpZiAob3V0ZXJRdW90ZSA9PT0gY2hhcikge1xyXG4gICAgICAgICAgICAgICAgb3V0ZXJRdW90ZSA9IG51bGw7XHJcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNCbGFuayhvdXRlclF1b3RlKSAmJiBpc1F1b3RlKGNoYXIpKSB7XHJcbiAgICAgICAgICAgICAgICBvdXRlclF1b3RlID0gY2hhcjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9jaGVja05vSW50ZXJwb2xhdGlvbihcclxuICAgICAgICBpbnB1dDogc3RyaW5nLCBsb2NhdGlvbjogYW55LCBpbnRlcnBvbGF0aW9uQ29uZmlnOiBJbnRlcnBvbGF0aW9uQ29uZmlnKTogdm9pZCB7XHJcbiAgICAgICAgY29uc3QgcmVnZXhwID0gX2NyZWF0ZUludGVycG9sYXRlUmVnRXhwKGludGVycG9sYXRpb25Db25maWcpO1xyXG4gICAgICAgIGNvbnN0IHBhcnRzID0gaW5wdXQuc3BsaXQocmVnZXhwKTtcclxuICAgICAgICBpZiAocGFydHMubGVuZ3RoID4gMSkge1xyXG4gICAgICAgICAgICB0aGlzLl9yZXBvcnRFcnJvcihcclxuICAgICAgICAgICAgICAgIGBHb3QgaW50ZXJwb2xhdGlvbiAoJHtpbnRlcnBvbGF0aW9uQ29uZmlnLnN0YXJ0fSR7aW50ZXJwb2xhdGlvbkNvbmZpZy5lbmR9KSB3aGVyZSBleHByZXNzaW9uIHdhcyBleHBlY3RlZGAsXHJcbiAgICAgICAgICAgICAgICBpbnB1dCxcclxuICAgICAgICAgICAgICAgIGBhdCBjb2x1bW4gJHt0aGlzLl9maW5kSW50ZXJwb2xhdGlvbkVycm9yQ29sdW1uKHBhcnRzLCAxLCBpbnRlcnBvbGF0aW9uQ29uZmlnKX0gaW5gLFxyXG4gICAgICAgICAgICAgICAgbG9jYXRpb24pO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9maW5kSW50ZXJwb2xhdGlvbkVycm9yQ29sdW1uKFxyXG4gICAgICAgIHBhcnRzOiBzdHJpbmdbXSwgcGFydEluRXJySWR4OiBudW1iZXIsIGludGVycG9sYXRpb25Db25maWc6IEludGVycG9sYXRpb25Db25maWcpOiBudW1iZXIge1xyXG4gICAgICAgIGxldCBlcnJMb2NhdGlvbiA9ICcnO1xyXG4gICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgcGFydEluRXJySWR4OyBqKyspIHtcclxuICAgICAgICAgICAgZXJyTG9jYXRpb24gKz0gaiAlIDIgPT09IDAgP1xyXG4gICAgICAgICAgICAgICAgcGFydHNbal0gOlxyXG4gICAgICAgICAgICAgICAgYCR7aW50ZXJwb2xhdGlvbkNvbmZpZy5zdGFydH0ke3BhcnRzW2pdfSR7aW50ZXJwb2xhdGlvbkNvbmZpZy5lbmR9YDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBlcnJMb2NhdGlvbi5sZW5ndGg7XHJcbiAgICB9XHJcbn1cclxuXHJcbmV4cG9ydCBjbGFzcyBfUGFyc2VBU1Qge1xyXG4gICAgcHJpdmF0ZSBycGFyZW5zRXhwZWN0ZWQgPSAwO1xyXG4gICAgcHJpdmF0ZSByYnJhY2tldHNFeHBlY3RlZCA9IDA7XHJcbiAgICBwcml2YXRlIHJicmFjZXNFeHBlY3RlZCA9IDA7XHJcblxyXG4gICAgaW5kZXg6IG51bWJlciA9IDA7XHJcblxyXG4gICAgY29uc3RydWN0b3IoXHJcbiAgICAgICAgcHVibGljIGlucHV0OiBzdHJpbmcsIHB1YmxpYyBsb2NhdGlvbjogYW55LCBwdWJsaWMgdG9rZW5zOiBUb2tlbltdLFxyXG4gICAgICAgIHB1YmxpYyBpbnB1dExlbmd0aDogbnVtYmVyLCBwdWJsaWMgcGFyc2VBY3Rpb246IGJvb2xlYW4sIHByaXZhdGUgZXJyb3JzOiBQYXJzZXJFcnJvcltdLFxyXG4gICAgICAgIHByaXZhdGUgb2Zmc2V0OiBudW1iZXIpIHt9XHJcblxyXG4gICAgcGVlayhvZmZzZXQ6IG51bWJlcik6IFRva2VuIHtcclxuICAgICAgICBjb25zdCBpID0gdGhpcy5pbmRleCArIG9mZnNldDtcclxuICAgICAgICByZXR1cm4gaSA8IHRoaXMudG9rZW5zLmxlbmd0aCA/IHRoaXMudG9rZW5zW2ldIDogRU9GO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBuZXh0KCk6IFRva2VuIHsgcmV0dXJuIHRoaXMucGVlaygwKTsgfVxyXG5cclxuICAgIGdldCBpbnB1dEluZGV4KCk6IG51bWJlciB7XHJcbiAgICAgICAgcmV0dXJuICh0aGlzLmluZGV4IDwgdGhpcy50b2tlbnMubGVuZ3RoKSA/IHRoaXMubmV4dC5pbmRleCArIHRoaXMub2Zmc2V0IDpcclxuICAgICAgICAgICAgdGhpcy5pbnB1dExlbmd0aCArIHRoaXMub2Zmc2V0O1xyXG4gICAgfVxyXG5cclxuICAgIHNwYW4oc3RhcnQ6IG51bWJlcikgeyByZXR1cm4gbmV3IFBhcnNlU3BhbihzdGFydCwgdGhpcy5pbnB1dEluZGV4KTsgfVxyXG5cclxuICAgIGFkdmFuY2UoKSB7IHRoaXMuaW5kZXgrKzsgfVxyXG5cclxuICAgIG9wdGlvbmFsQ2hhcmFjdGVyKGNvZGU6IG51bWJlcik6IGJvb2xlYW4ge1xyXG4gICAgICAgIGlmICh0aGlzLm5leHQuaXNDaGFyYWN0ZXIoY29kZSkpIHtcclxuICAgICAgICAgICAgdGhpcy5hZHZhbmNlKCk7XHJcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcGVla0tleXdvcmRMZXQoKTogYm9vbGVhbiB7IHJldHVybiB0aGlzLm5leHQuaXNLZXl3b3JkTGV0KCk7IH1cclxuXHJcbiAgICBleHBlY3RDaGFyYWN0ZXIoY29kZTogbnVtYmVyKSB7XHJcbiAgICAgICAgaWYgKHRoaXMub3B0aW9uYWxDaGFyYWN0ZXIoY29kZSkpIHJldHVybjtcclxuICAgICAgICB0aGlzLmVycm9yKGBNaXNzaW5nIGV4cGVjdGVkICR7U3RyaW5nLmZyb21DaGFyQ29kZShjb2RlKX1gKTtcclxuICAgIH1cclxuXHJcbiAgICBvcHRpb25hbE9wZXJhdG9yKG9wOiBzdHJpbmcpOiBib29sZWFuIHtcclxuICAgICAgICBpZiAodGhpcy5uZXh0LmlzT3BlcmF0b3Iob3ApKSB7XHJcbiAgICAgICAgICAgIHRoaXMuYWR2YW5jZSgpO1xyXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGV4cGVjdE9wZXJhdG9yKG9wZXJhdG9yOiBzdHJpbmcpIHtcclxuICAgICAgICBpZiAodGhpcy5vcHRpb25hbE9wZXJhdG9yKG9wZXJhdG9yKSkgcmV0dXJuO1xyXG4gICAgICAgIHRoaXMuZXJyb3IoYE1pc3NpbmcgZXhwZWN0ZWQgb3BlcmF0b3IgJHtvcGVyYXRvcn1gKTtcclxuICAgIH1cclxuXHJcbiAgICBleHBlY3RJZGVudGlmaWVyT3JLZXl3b3JkKCk6IHN0cmluZyB7XHJcbiAgICAgICAgY29uc3QgbiA9IHRoaXMubmV4dDtcclxuICAgICAgICBpZiAoIW4uaXNJZGVudGlmaWVyKCkgJiYgIW4uaXNLZXl3b3JkKCkpIHtcclxuICAgICAgICAgICAgdGhpcy5lcnJvcihgVW5leHBlY3RlZCB0b2tlbiAke259LCBleHBlY3RlZCBpZGVudGlmaWVyIG9yIGtleXdvcmRgKTtcclxuICAgICAgICAgICAgcmV0dXJuICcnO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLmFkdmFuY2UoKTtcclxuICAgICAgICByZXR1cm4gbi50b1N0cmluZygpO1xyXG4gICAgfVxyXG5cclxuICAgIGV4cGVjdElkZW50aWZpZXJPcktleXdvcmRPclN0cmluZygpOiBzdHJpbmcge1xyXG4gICAgICAgIGNvbnN0IG4gPSB0aGlzLm5leHQ7XHJcbiAgICAgICAgaWYgKCFuLmlzSWRlbnRpZmllcigpICYmICFuLmlzS2V5d29yZCgpICYmICFuLmlzU3RyaW5nKCkpIHtcclxuICAgICAgICAgICAgdGhpcy5lcnJvcihgVW5leHBlY3RlZCB0b2tlbiAke259LCBleHBlY3RlZCBpZGVudGlmaWVyLCBrZXl3b3JkLCBvciBzdHJpbmdgKTtcclxuICAgICAgICAgICAgcmV0dXJuICcnO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLmFkdmFuY2UoKTtcclxuICAgICAgICByZXR1cm4gbi50b1N0cmluZygpO1xyXG4gICAgfVxyXG5cclxuICAgIHBhcnNlQ2hhaW4oKTogQVNUIHtcclxuICAgICAgICBjb25zdCBleHByczogQVNUW10gPSBbXTtcclxuICAgICAgICBjb25zdCBzdGFydCA9IHRoaXMuaW5wdXRJbmRleDtcclxuICAgICAgICB3aGlsZSAodGhpcy5pbmRleCA8IHRoaXMudG9rZW5zLmxlbmd0aCkge1xyXG4gICAgICAgICAgICBjb25zdCBleHByID0gdGhpcy5wYXJzZVBpcGUoKTtcclxuICAgICAgICAgICAgZXhwcnMucHVzaChleHByKTtcclxuXHJcbiAgICAgICAgICAgIGlmICh0aGlzLm9wdGlvbmFsQ2hhcmFjdGVyKGNoYXJzLiRTRU1JQ09MT04pKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMucGFyc2VBY3Rpb24pIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmVycm9yKCdCaW5kaW5nIGV4cHJlc3Npb24gY2Fubm90IGNvbnRhaW4gY2hhaW5lZCBleHByZXNzaW9uJyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB3aGlsZSAodGhpcy5vcHRpb25hbENoYXJhY3RlcihjaGFycy4kU0VNSUNPTE9OKSkge1xyXG4gICAgICAgICAgICAgICAgfSAgLy8gcmVhZCBhbGwgc2VtaWNvbG9uc1xyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMuaW5kZXggPCB0aGlzLnRva2Vucy5sZW5ndGgpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuZXJyb3IoYFVuZXhwZWN0ZWQgdG9rZW4gJyR7dGhpcy5uZXh0fSdgKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoZXhwcnMubGVuZ3RoID09IDApIHJldHVybiBuZXcgRW1wdHlFeHByKHRoaXMuc3BhbihzdGFydCkpO1xyXG4gICAgICAgIGlmIChleHBycy5sZW5ndGggPT0gMSkgcmV0dXJuIGV4cHJzWzBdO1xyXG4gICAgICAgIHJldHVybiBuZXcgQ2hhaW4odGhpcy5zcGFuKHN0YXJ0KSwgZXhwcnMpO1xyXG4gICAgfVxyXG5cclxuICAgIHBhcnNlUGlwZSgpOiBBU1Qge1xyXG4gICAgICAgIGxldCByZXN1bHQgPSB0aGlzLnBhcnNlRXhwcmVzc2lvbigpO1xyXG4gICAgICAgIGlmICh0aGlzLm9wdGlvbmFsT3BlcmF0b3IoJ3wnKSkge1xyXG4gICAgICAgICAgICBpZiAodGhpcy5wYXJzZUFjdGlvbikge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5lcnJvcignQ2Fubm90IGhhdmUgYSBwaXBlIGluIGFuIGFjdGlvbiBleHByZXNzaW9uJyk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGRvIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IG5hbWUgPSB0aGlzLmV4cGVjdElkZW50aWZpZXJPcktleXdvcmQoKTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGFyZ3M6IEFTVFtdID0gW107XHJcbiAgICAgICAgICAgICAgICB3aGlsZSAodGhpcy5vcHRpb25hbENoYXJhY3RlcihjaGFycy4kQ09MT04pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgYXJncy5wdXNoKHRoaXMucGFyc2VFeHByZXNzaW9uKCkpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gbmV3IEJpbmRpbmdQaXBlKHRoaXMuc3BhbihyZXN1bHQuc3Bhbi5zdGFydCksIHJlc3VsdCwgbmFtZSwgYXJncyk7XHJcbiAgICAgICAgICAgIH0gd2hpbGUgKHRoaXMub3B0aW9uYWxPcGVyYXRvcignfCcpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICB9XHJcblxyXG4gICAgcGFyc2VFeHByZXNzaW9uKCk6IEFTVCB7IHJldHVybiB0aGlzLnBhcnNlQ29uZGl0aW9uYWwoKTsgfVxyXG5cclxuICAgIHBhcnNlQ29uZGl0aW9uYWwoKTogQVNUIHtcclxuICAgICAgICBjb25zdCBzdGFydCA9IHRoaXMuaW5wdXRJbmRleDtcclxuICAgICAgICBjb25zdCByZXN1bHQgPSB0aGlzLnBhcnNlTG9naWNhbE9yKCk7XHJcblxyXG4gICAgICAgIGlmICh0aGlzLm9wdGlvbmFsT3BlcmF0b3IoJz8nKSkge1xyXG4gICAgICAgICAgICBjb25zdCB5ZXMgPSB0aGlzLnBhcnNlUGlwZSgpO1xyXG4gICAgICAgICAgICBsZXQgbm86IEFTVDtcclxuICAgICAgICAgICAgaWYgKCF0aGlzLm9wdGlvbmFsQ2hhcmFjdGVyKGNoYXJzLiRDT0xPTikpIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGVuZCA9IHRoaXMuaW5wdXRJbmRleDtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGV4cHJlc3Npb24gPSB0aGlzLmlucHV0LnN1YnN0cmluZyhzdGFydCwgZW5kKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuZXJyb3IoYENvbmRpdGlvbmFsIGV4cHJlc3Npb24gJHtleHByZXNzaW9ufSByZXF1aXJlcyBhbGwgMyBleHByZXNzaW9uc2ApO1xyXG4gICAgICAgICAgICAgICAgbm8gPSBuZXcgRW1wdHlFeHByKHRoaXMuc3BhbihzdGFydCkpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgbm8gPSB0aGlzLnBhcnNlUGlwZSgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiBuZXcgQ29uZGl0aW9uYWwodGhpcy5zcGFuKHN0YXJ0KSwgcmVzdWx0LCB5ZXMsIG5vKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwYXJzZUxvZ2ljYWxPcigpOiBBU1Qge1xyXG4gICAgICAgIC8vICd8fCdcclxuICAgICAgICBsZXQgcmVzdWx0ID0gdGhpcy5wYXJzZUxvZ2ljYWxBbmQoKTtcclxuICAgICAgICB3aGlsZSAodGhpcy5vcHRpb25hbE9wZXJhdG9yKCd8fCcpKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHJpZ2h0ID0gdGhpcy5wYXJzZUxvZ2ljYWxBbmQoKTtcclxuICAgICAgICAgICAgcmVzdWx0ID0gbmV3IEJpbmFyeSh0aGlzLnNwYW4ocmVzdWx0LnNwYW4uc3RhcnQpLCAnfHwnLCByZXN1bHQsIHJpZ2h0KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuICAgIH1cclxuXHJcbiAgICBwYXJzZUxvZ2ljYWxBbmQoKTogQVNUIHtcclxuICAgICAgICAvLyAnJiYnXHJcbiAgICAgICAgbGV0IHJlc3VsdCA9IHRoaXMucGFyc2VFcXVhbGl0eSgpO1xyXG4gICAgICAgIHdoaWxlICh0aGlzLm9wdGlvbmFsT3BlcmF0b3IoJyYmJykpIHtcclxuICAgICAgICAgICAgY29uc3QgcmlnaHQgPSB0aGlzLnBhcnNlRXF1YWxpdHkoKTtcclxuICAgICAgICAgICAgcmVzdWx0ID0gbmV3IEJpbmFyeSh0aGlzLnNwYW4ocmVzdWx0LnNwYW4uc3RhcnQpLCAnJiYnLCByZXN1bHQsIHJpZ2h0KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuICAgIH1cclxuXHJcbiAgICBwYXJzZUVxdWFsaXR5KCk6IEFTVCB7XHJcbiAgICAgICAgLy8gJz09JywnIT0nLCc9PT0nLCchPT0nXHJcbiAgICAgICAgbGV0IHJlc3VsdCA9IHRoaXMucGFyc2VSZWxhdGlvbmFsKCk7XHJcbiAgICAgICAgd2hpbGUgKHRoaXMubmV4dC50eXBlID09IFRva2VuVHlwZS5PcGVyYXRvcikge1xyXG4gICAgICAgICAgICBjb25zdCBvcGVyYXRvciA9IHRoaXMubmV4dC5zdHJWYWx1ZTtcclxuICAgICAgICAgICAgc3dpdGNoIChvcGVyYXRvcikge1xyXG4gICAgICAgICAgICAgICAgY2FzZSAnPT0nOlxyXG4gICAgICAgICAgICAgICAgY2FzZSAnPT09JzpcclxuICAgICAgICAgICAgICAgIGNhc2UgJyE9JzpcclxuICAgICAgICAgICAgICAgIGNhc2UgJyE9PSc6XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5hZHZhbmNlKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcmlnaHQgPSB0aGlzLnBhcnNlUmVsYXRpb25hbCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IG5ldyBCaW5hcnkodGhpcy5zcGFuKHJlc3VsdC5zcGFuLnN0YXJ0KSwgb3BlcmF0b3IsIHJlc3VsdCwgcmlnaHQpO1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgfVxyXG5cclxuICAgIHBhcnNlUmVsYXRpb25hbCgpOiBBU1Qge1xyXG4gICAgICAgIC8vICc8JywgJz4nLCAnPD0nLCAnPj0nXHJcbiAgICAgICAgbGV0IHJlc3VsdCA9IHRoaXMucGFyc2VBZGRpdGl2ZSgpO1xyXG4gICAgICAgIHdoaWxlICh0aGlzLm5leHQudHlwZSA9PSBUb2tlblR5cGUuT3BlcmF0b3IpIHtcclxuICAgICAgICAgICAgY29uc3Qgb3BlcmF0b3IgPSB0aGlzLm5leHQuc3RyVmFsdWU7XHJcbiAgICAgICAgICAgIHN3aXRjaCAob3BlcmF0b3IpIHtcclxuICAgICAgICAgICAgICAgIGNhc2UgJzwnOlxyXG4gICAgICAgICAgICAgICAgY2FzZSAnPic6XHJcbiAgICAgICAgICAgICAgICBjYXNlICc8PSc6XHJcbiAgICAgICAgICAgICAgICBjYXNlICc+PSc6XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5hZHZhbmNlKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcmlnaHQgPSB0aGlzLnBhcnNlQWRkaXRpdmUoKTtcclxuICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBuZXcgQmluYXJ5KHRoaXMuc3BhbihyZXN1bHQuc3Bhbi5zdGFydCksIG9wZXJhdG9yLCByZXN1bHQsIHJpZ2h0KTtcclxuICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBicmVhaztcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuICAgIH1cclxuXHJcbiAgICBwYXJzZUFkZGl0aXZlKCk6IEFTVCB7XHJcbiAgICAgICAgLy8gJysnLCAnLSdcclxuICAgICAgICBsZXQgcmVzdWx0ID0gdGhpcy5wYXJzZU11bHRpcGxpY2F0aXZlKCk7XHJcbiAgICAgICAgd2hpbGUgKHRoaXMubmV4dC50eXBlID09IFRva2VuVHlwZS5PcGVyYXRvcikge1xyXG4gICAgICAgICAgICBjb25zdCBvcGVyYXRvciA9IHRoaXMubmV4dC5zdHJWYWx1ZTtcclxuICAgICAgICAgICAgc3dpdGNoIChvcGVyYXRvcikge1xyXG4gICAgICAgICAgICAgICAgY2FzZSAnKyc6XHJcbiAgICAgICAgICAgICAgICBjYXNlICctJzpcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmFkdmFuY2UoKTtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgcmlnaHQgPSB0aGlzLnBhcnNlTXVsdGlwbGljYXRpdmUoKTtcclxuICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBuZXcgQmluYXJ5KHRoaXMuc3BhbihyZXN1bHQuc3Bhbi5zdGFydCksIG9wZXJhdG9yLCByZXN1bHQsIHJpZ2h0KTtcclxuICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBicmVhaztcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuICAgIH1cclxuXHJcbiAgICBwYXJzZU11bHRpcGxpY2F0aXZlKCk6IEFTVCB7XHJcbiAgICAgICAgLy8gJyonLCAnJScsICcvJ1xyXG4gICAgICAgIGxldCByZXN1bHQgPSB0aGlzLnBhcnNlUHJlZml4KCk7XHJcbiAgICAgICAgd2hpbGUgKHRoaXMubmV4dC50eXBlID09IFRva2VuVHlwZS5PcGVyYXRvcikge1xyXG4gICAgICAgICAgICBjb25zdCBvcGVyYXRvciA9IHRoaXMubmV4dC5zdHJWYWx1ZTtcclxuICAgICAgICAgICAgc3dpdGNoIChvcGVyYXRvcikge1xyXG4gICAgICAgICAgICAgICAgY2FzZSAnKic6XHJcbiAgICAgICAgICAgICAgICBjYXNlICclJzpcclxuICAgICAgICAgICAgICAgIGNhc2UgJy8nOlxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuYWR2YW5jZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCByaWdodCA9IHRoaXMucGFyc2VQcmVmaXgoKTtcclxuICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBuZXcgQmluYXJ5KHRoaXMuc3BhbihyZXN1bHQuc3Bhbi5zdGFydCksIG9wZXJhdG9yLCByZXN1bHQsIHJpZ2h0KTtcclxuICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBicmVhaztcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuICAgIH1cclxuXHJcbiAgICBwYXJzZVByZWZpeCgpOiBBU1Qge1xyXG4gICAgICAgIGlmICh0aGlzLm5leHQudHlwZSA9PSBUb2tlblR5cGUuT3BlcmF0b3IpIHtcclxuICAgICAgICAgICAgY29uc3Qgc3RhcnQgPSB0aGlzLmlucHV0SW5kZXg7XHJcbiAgICAgICAgICAgIGNvbnN0IG9wZXJhdG9yID0gdGhpcy5uZXh0LnN0clZhbHVlO1xyXG4gICAgICAgICAgICBsZXQgcmVzdWx0OiBBU1Q7XHJcbiAgICAgICAgICAgIHN3aXRjaCAob3BlcmF0b3IpIHtcclxuICAgICAgICAgICAgICAgIGNhc2UgJysnOlxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuYWR2YW5jZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnBhcnNlUHJlZml4KCk7XHJcbiAgICAgICAgICAgICAgICBjYXNlICctJzpcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmFkdmFuY2UoKTtcclxuICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSB0aGlzLnBhcnNlUHJlZml4KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBCaW5hcnkoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3BhbihzdGFydCksIG9wZXJhdG9yLCBuZXcgTGl0ZXJhbFByaW1pdGl2ZShuZXcgUGFyc2VTcGFuKHN0YXJ0LCBzdGFydCksIDApLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQpO1xyXG4gICAgICAgICAgICAgICAgY2FzZSAnISc6XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5hZHZhbmNlKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gdGhpcy5wYXJzZVByZWZpeCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgUHJlZml4Tm90KHRoaXMuc3BhbihzdGFydCksIHJlc3VsdCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHRoaXMucGFyc2VDYWxsQ2hhaW4oKTtcclxuICAgIH1cclxuXHJcbiAgICBwYXJzZUNhbGxDaGFpbigpOiBBU1Qge1xyXG4gICAgICAgIGxldCByZXN1bHQgPSB0aGlzLnBhcnNlUHJpbWFyeSgpO1xyXG4gICAgICAgIHdoaWxlICh0cnVlKSB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLm9wdGlvbmFsQ2hhcmFjdGVyKGNoYXJzLiRQRVJJT0QpKSB7XHJcbiAgICAgICAgICAgICAgICByZXN1bHQgPSB0aGlzLnBhcnNlQWNjZXNzTWVtYmVyT3JNZXRob2RDYWxsKHJlc3VsdCwgZmFsc2UpO1xyXG5cclxuICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLm9wdGlvbmFsT3BlcmF0b3IoJz8uJykpIHtcclxuICAgICAgICAgICAgICAgIHJlc3VsdCA9IHRoaXMucGFyc2VBY2Nlc3NNZW1iZXJPck1ldGhvZENhbGwocmVzdWx0LCB0cnVlKTtcclxuXHJcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5vcHRpb25hbENoYXJhY3RlcihjaGFycy4kTEJSQUNLRVQpKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnJicmFja2V0c0V4cGVjdGVkKys7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBrZXkgPSB0aGlzLnBhcnNlUGlwZSgpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5yYnJhY2tldHNFeHBlY3RlZC0tO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5leHBlY3RDaGFyYWN0ZXIoY2hhcnMuJFJCUkFDS0VUKTtcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLm9wdGlvbmFsT3BlcmF0b3IoJz0nKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gdGhpcy5wYXJzZUNvbmRpdGlvbmFsKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gbmV3IEtleWVkV3JpdGUodGhpcy5zcGFuKHJlc3VsdC5zcGFuLnN0YXJ0KSwgcmVzdWx0LCBrZXksIHZhbHVlKTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gbmV3IEtleWVkUmVhZCh0aGlzLnNwYW4ocmVzdWx0LnNwYW4uc3RhcnQpLCByZXN1bHQsIGtleSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMub3B0aW9uYWxDaGFyYWN0ZXIoY2hhcnMuJExQQVJFTikpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMucnBhcmVuc0V4cGVjdGVkKys7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBhcmdzID0gdGhpcy5wYXJzZUNhbGxBcmd1bWVudHMoKTtcclxuICAgICAgICAgICAgICAgIHRoaXMucnBhcmVuc0V4cGVjdGVkLS07XHJcbiAgICAgICAgICAgICAgICB0aGlzLmV4cGVjdENoYXJhY3RlcihjaGFycy4kUlBBUkVOKTtcclxuICAgICAgICAgICAgICAgIHJlc3VsdCA9IG5ldyBGdW5jdGlvbkNhbGwodGhpcy5zcGFuKHJlc3VsdC5zcGFuLnN0YXJ0KSwgcmVzdWx0LCBhcmdzKTtcclxuXHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHBhcnNlUHJpbWFyeSgpOiBBU1Qge1xyXG4gICAgICAgIGNvbnN0IHN0YXJ0ID0gdGhpcy5pbnB1dEluZGV4O1xyXG4gICAgICAgIGlmICh0aGlzLm9wdGlvbmFsQ2hhcmFjdGVyKGNoYXJzLiRMUEFSRU4pKSB7XHJcbiAgICAgICAgICAgIHRoaXMucnBhcmVuc0V4cGVjdGVkKys7XHJcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMucGFyc2VQaXBlKCk7XHJcbiAgICAgICAgICAgIHRoaXMucnBhcmVuc0V4cGVjdGVkLS07XHJcbiAgICAgICAgICAgIHRoaXMuZXhwZWN0Q2hhcmFjdGVyKGNoYXJzLiRSUEFSRU4pO1xyXG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG5cclxuICAgICAgICB9IGVsc2UgaWYgKHRoaXMubmV4dC5pc0tleXdvcmROdWxsKCkpIHtcclxuICAgICAgICAgICAgdGhpcy5hZHZhbmNlKCk7XHJcbiAgICAgICAgICAgIHJldHVybiBuZXcgTGl0ZXJhbFByaW1pdGl2ZSh0aGlzLnNwYW4oc3RhcnQpLCBudWxsKTtcclxuXHJcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLm5leHQuaXNLZXl3b3JkVW5kZWZpbmVkKCkpIHtcclxuICAgICAgICAgICAgdGhpcy5hZHZhbmNlKCk7XHJcbiAgICAgICAgICAgIHJldHVybiBuZXcgTGl0ZXJhbFByaW1pdGl2ZSh0aGlzLnNwYW4oc3RhcnQpLCB2b2lkIDApO1xyXG5cclxuICAgICAgICB9IGVsc2UgaWYgKHRoaXMubmV4dC5pc0tleXdvcmRUcnVlKCkpIHtcclxuICAgICAgICAgICAgdGhpcy5hZHZhbmNlKCk7XHJcbiAgICAgICAgICAgIHJldHVybiBuZXcgTGl0ZXJhbFByaW1pdGl2ZSh0aGlzLnNwYW4oc3RhcnQpLCB0cnVlKTtcclxuXHJcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLm5leHQuaXNLZXl3b3JkRmFsc2UoKSkge1xyXG4gICAgICAgICAgICB0aGlzLmFkdmFuY2UoKTtcclxuICAgICAgICAgICAgcmV0dXJuIG5ldyBMaXRlcmFsUHJpbWl0aXZlKHRoaXMuc3BhbihzdGFydCksIGZhbHNlKTtcclxuXHJcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLm5leHQuaXNLZXl3b3JkVGhpcygpKSB7XHJcbiAgICAgICAgICAgIHRoaXMuYWR2YW5jZSgpO1xyXG4gICAgICAgICAgICByZXR1cm4gbmV3IEltcGxpY2l0UmVjZWl2ZXIodGhpcy5zcGFuKHN0YXJ0KSk7XHJcblxyXG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5vcHRpb25hbENoYXJhY3RlcihjaGFycy4kTEJSQUNLRVQpKSB7XHJcbiAgICAgICAgICAgIHRoaXMucmJyYWNrZXRzRXhwZWN0ZWQrKztcclxuICAgICAgICAgICAgY29uc3QgZWxlbWVudHMgPSB0aGlzLnBhcnNlRXhwcmVzc2lvbkxpc3QoY2hhcnMuJFJCUkFDS0VUKTtcclxuICAgICAgICAgICAgdGhpcy5yYnJhY2tldHNFeHBlY3RlZC0tO1xyXG4gICAgICAgICAgICB0aGlzLmV4cGVjdENoYXJhY3RlcihjaGFycy4kUkJSQUNLRVQpO1xyXG4gICAgICAgICAgICByZXR1cm4gbmV3IExpdGVyYWxBcnJheSh0aGlzLnNwYW4oc3RhcnQpLCBlbGVtZW50cyk7XHJcblxyXG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5uZXh0LmlzQ2hhcmFjdGVyKGNoYXJzLiRMQlJBQ0UpKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnBhcnNlTGl0ZXJhbE1hcCgpO1xyXG5cclxuICAgICAgICB9IGVsc2UgaWYgKHRoaXMubmV4dC5pc0lkZW50aWZpZXIoKSkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5wYXJzZUFjY2Vzc01lbWJlck9yTWV0aG9kQ2FsbChuZXcgSW1wbGljaXRSZWNlaXZlcih0aGlzLnNwYW4oc3RhcnQpKSwgZmFsc2UpO1xyXG5cclxuICAgICAgICB9IGVsc2UgaWYgKHRoaXMubmV4dC5pc051bWJlcigpKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gdGhpcy5uZXh0LnRvTnVtYmVyKCk7XHJcbiAgICAgICAgICAgIHRoaXMuYWR2YW5jZSgpO1xyXG4gICAgICAgICAgICByZXR1cm4gbmV3IExpdGVyYWxQcmltaXRpdmUodGhpcy5zcGFuKHN0YXJ0KSwgdmFsdWUpO1xyXG5cclxuICAgICAgICB9IGVsc2UgaWYgKHRoaXMubmV4dC5pc1N0cmluZygpKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGxpdGVyYWxWYWx1ZSA9IHRoaXMubmV4dC50b1N0cmluZygpO1xyXG4gICAgICAgICAgICB0aGlzLmFkdmFuY2UoKTtcclxuICAgICAgICAgICAgcmV0dXJuIG5ldyBMaXRlcmFsUHJpbWl0aXZlKHRoaXMuc3BhbihzdGFydCksIGxpdGVyYWxWYWx1ZSk7XHJcblxyXG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5pbmRleCA+PSB0aGlzLnRva2Vucy5sZW5ndGgpIHtcclxuICAgICAgICAgICAgdGhpcy5lcnJvcihgVW5leHBlY3RlZCBlbmQgb2YgZXhwcmVzc2lvbjogJHt0aGlzLmlucHV0fWApO1xyXG4gICAgICAgICAgICByZXR1cm4gbmV3IEVtcHR5RXhwcih0aGlzLnNwYW4oc3RhcnQpKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLmVycm9yKGBVbmV4cGVjdGVkIHRva2VuICR7dGhpcy5uZXh0fWApO1xyXG4gICAgICAgICAgICByZXR1cm4gbmV3IEVtcHR5RXhwcih0aGlzLnNwYW4oc3RhcnQpKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcGFyc2VFeHByZXNzaW9uTGlzdCh0ZXJtaW5hdG9yOiBudW1iZXIpOiBBU1RbXSB7XHJcbiAgICAgICAgY29uc3QgcmVzdWx0OiBBU1RbXSA9IFtdO1xyXG4gICAgICAgIGlmICghdGhpcy5uZXh0LmlzQ2hhcmFjdGVyKHRlcm1pbmF0b3IpKSB7XHJcbiAgICAgICAgICAgIGRvIHtcclxuICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKHRoaXMucGFyc2VQaXBlKCkpO1xyXG4gICAgICAgICAgICB9IHdoaWxlICh0aGlzLm9wdGlvbmFsQ2hhcmFjdGVyKGNoYXJzLiRDT01NQSkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgfVxyXG5cclxuICAgIHBhcnNlTGl0ZXJhbE1hcCgpOiBMaXRlcmFsTWFwIHtcclxuICAgICAgICBjb25zdCBrZXlzOiBzdHJpbmdbXSA9IFtdO1xyXG4gICAgICAgIGNvbnN0IHZhbHVlczogQVNUW10gPSBbXTtcclxuICAgICAgICBjb25zdCBzdGFydCA9IHRoaXMuaW5wdXRJbmRleDtcclxuICAgICAgICB0aGlzLmV4cGVjdENoYXJhY3RlcihjaGFycy4kTEJSQUNFKTtcclxuICAgICAgICBpZiAoIXRoaXMub3B0aW9uYWxDaGFyYWN0ZXIoY2hhcnMuJFJCUkFDRSkpIHtcclxuICAgICAgICAgICAgdGhpcy5yYnJhY2VzRXhwZWN0ZWQrKztcclxuICAgICAgICAgICAgZG8ge1xyXG4gICAgICAgICAgICAgICAgY29uc3Qga2V5ID0gdGhpcy5leHBlY3RJZGVudGlmaWVyT3JLZXl3b3JkT3JTdHJpbmcoKTtcclxuICAgICAgICAgICAgICAgIGtleXMucHVzaChrZXkpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5leHBlY3RDaGFyYWN0ZXIoY2hhcnMuJENPTE9OKTtcclxuICAgICAgICAgICAgICAgIHZhbHVlcy5wdXNoKHRoaXMucGFyc2VQaXBlKCkpO1xyXG4gICAgICAgICAgICB9IHdoaWxlICh0aGlzLm9wdGlvbmFsQ2hhcmFjdGVyKGNoYXJzLiRDT01NQSkpO1xyXG4gICAgICAgICAgICB0aGlzLnJicmFjZXNFeHBlY3RlZC0tO1xyXG4gICAgICAgICAgICB0aGlzLmV4cGVjdENoYXJhY3RlcihjaGFycy4kUkJSQUNFKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIG5ldyBMaXRlcmFsTWFwKHRoaXMuc3BhbihzdGFydCksIGtleXMsIHZhbHVlcyk7XHJcbiAgICB9XHJcblxyXG4gICAgcGFyc2VBY2Nlc3NNZW1iZXJPck1ldGhvZENhbGwocmVjZWl2ZXI6IEFTVCwgaXNTYWZlOiBib29sZWFuID0gZmFsc2UpOiBBU1Qge1xyXG4gICAgICAgIGNvbnN0IHN0YXJ0ID0gcmVjZWl2ZXIuc3Bhbi5zdGFydDtcclxuICAgICAgICBjb25zdCBpZCA9IHRoaXMuZXhwZWN0SWRlbnRpZmllck9yS2V5d29yZCgpO1xyXG5cclxuICAgICAgICBpZiAodGhpcy5vcHRpb25hbENoYXJhY3RlcihjaGFycy4kTFBBUkVOKSkge1xyXG4gICAgICAgICAgICB0aGlzLnJwYXJlbnNFeHBlY3RlZCsrO1xyXG4gICAgICAgICAgICBjb25zdCBhcmdzID0gdGhpcy5wYXJzZUNhbGxBcmd1bWVudHMoKTtcclxuICAgICAgICAgICAgdGhpcy5leHBlY3RDaGFyYWN0ZXIoY2hhcnMuJFJQQVJFTik7XHJcbiAgICAgICAgICAgIHRoaXMucnBhcmVuc0V4cGVjdGVkLS07XHJcbiAgICAgICAgICAgIGNvbnN0IHNwYW4gPSB0aGlzLnNwYW4oc3RhcnQpO1xyXG4gICAgICAgICAgICByZXR1cm4gaXNTYWZlID8gbmV3IFNhZmVNZXRob2RDYWxsKHNwYW4sIHJlY2VpdmVyLCBpZCwgYXJncykgOlxyXG4gICAgICAgICAgICAgICAgbmV3IE1ldGhvZENhbGwoc3BhbiwgcmVjZWl2ZXIsIGlkLCBhcmdzKTtcclxuXHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgaWYgKGlzU2FmZSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMub3B0aW9uYWxPcGVyYXRvcignPScpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lcnJvcignVGhlIFxcJz8uXFwnIG9wZXJhdG9yIGNhbm5vdCBiZSB1c2VkIGluIHRoZSBhc3NpZ25tZW50Jyk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBFbXB0eUV4cHIodGhpcy5zcGFuKHN0YXJ0KSk7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgU2FmZVByb3BlcnR5UmVhZCh0aGlzLnNwYW4oc3RhcnQpLCByZWNlaXZlciwgaWQpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMub3B0aW9uYWxPcGVyYXRvcignPScpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCF0aGlzLnBhcnNlQWN0aW9uKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZXJyb3IoJ0JpbmRpbmdzIGNhbm5vdCBjb250YWluIGFzc2lnbm1lbnRzJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgRW1wdHlFeHByKHRoaXMuc3BhbihzdGFydCkpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSB0aGlzLnBhcnNlQ29uZGl0aW9uYWwoKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFByb3BlcnR5V3JpdGUodGhpcy5zcGFuKHN0YXJ0KSwgcmVjZWl2ZXIsIGlkLCB2YWx1ZSk7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgUHJvcGVydHlSZWFkKHRoaXMuc3BhbihzdGFydCksIHJlY2VpdmVyLCBpZCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcGFyc2VDYWxsQXJndW1lbnRzKCk6IEJpbmRpbmdQaXBlW10ge1xyXG4gICAgICAgIGlmICh0aGlzLm5leHQuaXNDaGFyYWN0ZXIoY2hhcnMuJFJQQVJFTikpIHJldHVybiBbXTtcclxuICAgICAgICBjb25zdCBwb3NpdGlvbmFsczogQVNUW10gPSBbXTtcclxuICAgICAgICBkbyB7XHJcbiAgICAgICAgICAgIHBvc2l0aW9uYWxzLnB1c2godGhpcy5wYXJzZVBpcGUoKSk7XHJcbiAgICAgICAgfSB3aGlsZSAodGhpcy5vcHRpb25hbENoYXJhY3RlcihjaGFycy4kQ09NTUEpKTtcclxuICAgICAgICByZXR1cm4gcG9zaXRpb25hbHMgYXMgQmluZGluZ1BpcGVbXTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEFuIGlkZW50aWZpZXIsIGEga2V5d29yZCwgYSBzdHJpbmcgd2l0aCBhbiBvcHRpb25hbCBgLWAgaW5iZXR3ZWVuLlxyXG4gICAgICovXHJcbiAgICBleHBlY3RUZW1wbGF0ZUJpbmRpbmdLZXkoKTogc3RyaW5nIHtcclxuICAgICAgICBsZXQgcmVzdWx0ID0gJyc7XHJcbiAgICAgICAgbGV0IG9wZXJhdG9yRm91bmQgPSBmYWxzZTtcclxuICAgICAgICBkbyB7XHJcbiAgICAgICAgICAgIHJlc3VsdCArPSB0aGlzLmV4cGVjdElkZW50aWZpZXJPcktleXdvcmRPclN0cmluZygpO1xyXG4gICAgICAgICAgICBvcGVyYXRvckZvdW5kID0gdGhpcy5vcHRpb25hbE9wZXJhdG9yKCctJyk7XHJcbiAgICAgICAgICAgIGlmIChvcGVyYXRvckZvdW5kKSB7XHJcbiAgICAgICAgICAgICAgICByZXN1bHQgKz0gJy0nO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSB3aGlsZSAob3BlcmF0b3JGb3VuZCk7XHJcblxyXG4gICAgICAgIHJldHVybiByZXN1bHQudG9TdHJpbmcoKTtcclxuICAgIH1cclxuXHJcbiAgICBwYXJzZVRlbXBsYXRlQmluZGluZ3MoKTogVGVtcGxhdGVCaW5kaW5nUGFyc2VSZXN1bHQge1xyXG4gICAgICAgIGNvbnN0IGJpbmRpbmdzOiBUZW1wbGF0ZUJpbmRpbmdbXSA9IFtdO1xyXG4gICAgICAgIGxldCBwcmVmaXg6IHN0cmluZyA9IG51bGw7XHJcbiAgICAgICAgY29uc3Qgd2FybmluZ3M6IHN0cmluZ1tdID0gW107XHJcbiAgICAgICAgd2hpbGUgKHRoaXMuaW5kZXggPCB0aGlzLnRva2Vucy5sZW5ndGgpIHtcclxuICAgICAgICAgICAgY29uc3Qgc3RhcnQgPSB0aGlzLmlucHV0SW5kZXg7XHJcbiAgICAgICAgICAgIGNvbnN0IGtleUlzVmFyOiBib29sZWFuID0gdGhpcy5wZWVrS2V5d29yZExldCgpO1xyXG4gICAgICAgICAgICBpZiAoa2V5SXNWYXIpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuYWR2YW5jZSgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGxldCBrZXkgPSB0aGlzLmV4cGVjdFRlbXBsYXRlQmluZGluZ0tleSgpO1xyXG4gICAgICAgICAgICBpZiAoIWtleUlzVmFyKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAocHJlZml4ID09IG51bGwpIHtcclxuICAgICAgICAgICAgICAgICAgICBwcmVmaXggPSBrZXk7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIGtleSA9IHByZWZpeCArIGtleVswXS50b1VwcGVyQ2FzZSgpICsga2V5LnN1YnN0cmluZygxKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB0aGlzLm9wdGlvbmFsQ2hhcmFjdGVyKGNoYXJzLiRDT0xPTik7XHJcbiAgICAgICAgICAgIGxldCBuYW1lOiBzdHJpbmcgPSBudWxsO1xyXG4gICAgICAgICAgICBsZXQgZXhwcmVzc2lvbjogQVNUV2l0aFNvdXJjZSA9IG51bGw7XHJcbiAgICAgICAgICAgIGlmIChrZXlJc1Zhcikge1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMub3B0aW9uYWxPcGVyYXRvcignPScpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbmFtZSA9IHRoaXMuZXhwZWN0VGVtcGxhdGVCaW5kaW5nS2V5KCk7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIG5hbWUgPSAnXFwkaW1wbGljaXQnO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMubmV4dCAhPT0gRU9GICYmICF0aGlzLnBlZWtLZXl3b3JkTGV0KCkpIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHN0YXJ0ID0gdGhpcy5pbnB1dEluZGV4O1xyXG4gICAgICAgICAgICAgICAgY29uc3QgYXN0ID0gdGhpcy5wYXJzZVBpcGUoKTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHNvdXJjZSA9IHRoaXMuaW5wdXQuc3Vic3RyaW5nKHN0YXJ0IC0gdGhpcy5vZmZzZXQsIHRoaXMuaW5wdXRJbmRleCAtIHRoaXMub2Zmc2V0KTtcclxuICAgICAgICAgICAgICAgIGV4cHJlc3Npb24gPSBuZXcgQVNUV2l0aFNvdXJjZShhc3QsIHNvdXJjZSwgdGhpcy5sb2NhdGlvbiwgdGhpcy5lcnJvcnMpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGJpbmRpbmdzLnB1c2gobmV3IFRlbXBsYXRlQmluZGluZyh0aGlzLnNwYW4oc3RhcnQpLCBrZXksIGtleUlzVmFyLCBuYW1lLCBleHByZXNzaW9uKSk7XHJcbiAgICAgICAgICAgIGlmICghdGhpcy5vcHRpb25hbENoYXJhY3RlcihjaGFycy4kU0VNSUNPTE9OKSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5vcHRpb25hbENoYXJhY3RlcihjaGFycy4kQ09NTUEpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBuZXcgVGVtcGxhdGVCaW5kaW5nUGFyc2VSZXN1bHQoYmluZGluZ3MsIHdhcm5pbmdzLCB0aGlzLmVycm9ycyk7XHJcbiAgICB9XHJcblxyXG4gICAgZXJyb3IobWVzc2FnZTogc3RyaW5nLCBpbmRleDogbnVtYmVyID0gbnVsbCkge1xyXG4gICAgICAgIHRoaXMuZXJyb3JzLnB1c2gobmV3IFBhcnNlckVycm9yKG1lc3NhZ2UsIHRoaXMuaW5wdXQsIHRoaXMubG9jYXRpb25UZXh0KGluZGV4KSwgdGhpcy5sb2NhdGlvbikpO1xyXG4gICAgICAgIHRoaXMuc2tpcCgpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgbG9jYXRpb25UZXh0KGluZGV4OiBudW1iZXIgPSBudWxsKSB7XHJcbiAgICAgICAgaWYgKGlzQmxhbmsoaW5kZXgpKSBpbmRleCA9IHRoaXMuaW5kZXg7XHJcbiAgICAgICAgcmV0dXJuIChpbmRleCA8IHRoaXMudG9rZW5zLmxlbmd0aCkgPyBgYXQgY29sdW1uICR7dGhpcy50b2tlbnNbaW5kZXhdLmluZGV4ICsgMX0gaW5gIDpcclxuICAgICAgICAgICAgYGF0IHRoZSBlbmQgb2YgdGhlIGV4cHJlc3Npb25gO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIEVycm9yIHJlY292ZXJ5IHNob3VsZCBza2lwIHRva2VucyB1bnRpbCBpdCBlbmNvdW50ZXJzIGEgcmVjb3ZlcnkgcG9pbnQuIHNraXAoKSB0cmVhdHNcclxuICAgIC8vIHRoZSBlbmQgb2YgaW5wdXQgYW5kIGEgJzsnIGFzIHVuY29uZGl0aW9uYWxseSBhIHJlY292ZXJ5IHBvaW50LiBJdCBhbHNvIHRyZWF0cyAnKScsXHJcbiAgICAvLyAnfScgYW5kICddJyBhcyBjb25kaXRpb25hbCByZWNvdmVyeSBwb2ludHMgaWYgb25lIG9mIGNhbGxpbmcgcHJvZHVjdGlvbnMgaXMgZXhwZWN0aW5nXHJcbiAgICAvLyBvbmUgb2YgdGhlc2Ugc3ltYm9scy4gVGhpcyBhbGxvd3Mgc2tpcCgpIHRvIHJlY292ZXIgZnJvbSBlcnJvcnMgc3VjaCBhcyAnKGEuKSArIDEnIGFsbG93aW5nXHJcbiAgICAvLyBtb3JlIG9mIHRoZSBBU1QgdG8gYmUgcmV0YWluZWQgKGl0IGRvZXNuJ3Qgc2tpcCBhbnkgdG9rZW5zIGFzIHRoZSAnKScgaXMgcmV0YWluZWQgYmVjYXVzZVxyXG4gICAgLy8gb2YgdGhlICcoJyBiZWdpbnMgYW4gJygnIDxleHByPiAnKScgcHJvZHVjdGlvbikuIFRoZSByZWNvdmVyeSBwb2ludHMgb2YgZ3JvdXBpbmcgc3ltYm9sc1xyXG4gICAgLy8gbXVzdCBiZSBjb25kaXRpb25hbCBhcyB0aGV5IG11c3QgYmUgc2tpcHBlZCBpZiBub25lIG9mIHRoZSBjYWxsaW5nIHByb2R1Y3Rpb25zIGFyZSBub3RcclxuICAgIC8vIGV4cGVjdGluZyB0aGUgY2xvc2luZyB0b2tlbiBlbHNlIHdlIHdpbGwgbmV2ZXIgbWFrZSBwcm9ncmVzcyBpbiB0aGUgY2FzZSBvZiBhblxyXG4gICAgLy8gZXh0cmFuZW91cyBncm91cCBjbG9zaW5nIHN5bWJvbCAoc3VjaCBhcyBhIHN0cmF5ICcpJykuIFRoaXMgaXMgbm90IHRoZSBjYXNlIGZvciAnOycgYmVjYXVzZVxyXG4gICAgLy8gcGFyc2VDaGFpbigpIGlzIGFsd2F5cyB0aGUgcm9vdCBwcm9kdWN0aW9uIGFuZCBpdCBleHBlY3RzIGEgJzsnLlxyXG5cclxuICAgIC8vIElmIGEgcHJvZHVjdGlvbiBleHBlY3RzIG9uZSBvZiB0aGVzZSB0b2tlbiBpdCBpbmNyZW1lbnRzIHRoZSBjb3JyZXNwb25kaW5nIG5lc3RpbmcgY291bnQsXHJcbiAgICAvLyBhbmQgdGhlbiBkZWNyZW1lbnRzIGl0IGp1c3QgcHJpb3IgdG8gY2hlY2tpbmcgaWYgdGhlIHRva2VuIGlzIGluIHRoZSBpbnB1dC5cclxuICAgIHByaXZhdGUgc2tpcCgpIHtcclxuICAgICAgICBsZXQgbiA9IHRoaXMubmV4dDtcclxuICAgICAgICB3aGlsZSAodGhpcy5pbmRleCA8IHRoaXMudG9rZW5zLmxlbmd0aCAmJiAhbi5pc0NoYXJhY3RlcihjaGFycy4kU0VNSUNPTE9OKSAmJlxyXG4gICAgICAgICh0aGlzLnJwYXJlbnNFeHBlY3RlZCA8PSAwIHx8ICFuLmlzQ2hhcmFjdGVyKGNoYXJzLiRSUEFSRU4pKSAmJlxyXG4gICAgICAgICh0aGlzLnJicmFjZXNFeHBlY3RlZCA8PSAwIHx8ICFuLmlzQ2hhcmFjdGVyKGNoYXJzLiRSQlJBQ0UpKSAmJlxyXG4gICAgICAgICh0aGlzLnJicmFja2V0c0V4cGVjdGVkIDw9IDAgfHwgIW4uaXNDaGFyYWN0ZXIoY2hhcnMuJFJCUkFDS0VUKSkpIHtcclxuICAgICAgICAgICAgaWYgKHRoaXMubmV4dC5pc0Vycm9yKCkpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuZXJyb3JzLnB1c2goXHJcbiAgICAgICAgICAgICAgICAgICAgbmV3IFBhcnNlckVycm9yKHRoaXMubmV4dC50b1N0cmluZygpLCB0aGlzLmlucHV0LCB0aGlzLmxvY2F0aW9uVGV4dCgpLCB0aGlzLmxvY2F0aW9uKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdGhpcy5hZHZhbmNlKCk7XHJcbiAgICAgICAgICAgIG4gPSB0aGlzLm5leHQ7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59XHJcblxyXG5jbGFzcyBTaW1wbGVFeHByZXNzaW9uQ2hlY2tlciBpbXBsZW1lbnRzIEFzdFZpc2l0b3Ige1xyXG4gICAgc3RhdGljIGNoZWNrKGFzdDogQVNUKTogc3RyaW5nW10ge1xyXG4gICAgICAgIGNvbnN0IHMgPSBuZXcgU2ltcGxlRXhwcmVzc2lvbkNoZWNrZXIoKTtcclxuICAgICAgICBhc3QudmlzaXQocyk7XHJcbiAgICAgICAgcmV0dXJuIHMuZXJyb3JzO1xyXG4gICAgfVxyXG5cclxuICAgIGVycm9yczogc3RyaW5nW10gPSBbXTtcclxuXHJcbiAgICB2aXNpdEltcGxpY2l0UmVjZWl2ZXIoYXN0OiBJbXBsaWNpdFJlY2VpdmVyLCBjb250ZXh0OiBhbnkpIHt9XHJcblxyXG4gICAgdmlzaXRJbnRlcnBvbGF0aW9uKGFzdDogSW50ZXJwb2xhdGlvbiwgY29udGV4dDogYW55KSB7fVxyXG5cclxuICAgIHZpc2l0TGl0ZXJhbFByaW1pdGl2ZShhc3Q6IExpdGVyYWxQcmltaXRpdmUsIGNvbnRleHQ6IGFueSkge31cclxuXHJcbiAgICB2aXNpdFByb3BlcnR5UmVhZChhc3Q6IFByb3BlcnR5UmVhZCwgY29udGV4dDogYW55KSB7fVxyXG5cclxuICAgIHZpc2l0UHJvcGVydHlXcml0ZShhc3Q6IFByb3BlcnR5V3JpdGUsIGNvbnRleHQ6IGFueSkge31cclxuXHJcbiAgICB2aXNpdFNhZmVQcm9wZXJ0eVJlYWQoYXN0OiBTYWZlUHJvcGVydHlSZWFkLCBjb250ZXh0OiBhbnkpIHt9XHJcblxyXG4gICAgdmlzaXRNZXRob2RDYWxsKGFzdDogTWV0aG9kQ2FsbCwgY29udGV4dDogYW55KSB7fVxyXG5cclxuICAgIHZpc2l0U2FmZU1ldGhvZENhbGwoYXN0OiBTYWZlTWV0aG9kQ2FsbCwgY29udGV4dDogYW55KSB7fVxyXG5cclxuICAgIHZpc2l0RnVuY3Rpb25DYWxsKGFzdDogRnVuY3Rpb25DYWxsLCBjb250ZXh0OiBhbnkpIHt9XHJcblxyXG4gICAgdmlzaXRMaXRlcmFsQXJyYXkoYXN0OiBMaXRlcmFsQXJyYXksIGNvbnRleHQ6IGFueSkgeyB0aGlzLnZpc2l0QWxsKGFzdC5leHByZXNzaW9ucyk7IH1cclxuXHJcbiAgICB2aXNpdExpdGVyYWxNYXAoYXN0OiBMaXRlcmFsTWFwLCBjb250ZXh0OiBhbnkpIHsgdGhpcy52aXNpdEFsbChhc3QudmFsdWVzKTsgfVxyXG5cclxuICAgIHZpc2l0QmluYXJ5KGFzdDogQmluYXJ5LCBjb250ZXh0OiBhbnkpIHt9XHJcblxyXG4gICAgdmlzaXRQcmVmaXhOb3QoYXN0OiBQcmVmaXhOb3QsIGNvbnRleHQ6IGFueSkge31cclxuXHJcbiAgICB2aXNpdENvbmRpdGlvbmFsKGFzdDogQ29uZGl0aW9uYWwsIGNvbnRleHQ6IGFueSkge31cclxuXHJcbiAgICB2aXNpdFBpcGUoYXN0OiBCaW5kaW5nUGlwZSwgY29udGV4dDogYW55KSB7IHRoaXMuZXJyb3JzLnB1c2goJ3BpcGVzJyk7IH1cclxuXHJcbiAgICB2aXNpdEtleWVkUmVhZChhc3Q6IEtleWVkUmVhZCwgY29udGV4dDogYW55KSB7fVxyXG5cclxuICAgIHZpc2l0S2V5ZWRXcml0ZShhc3Q6IEtleWVkV3JpdGUsIGNvbnRleHQ6IGFueSkge31cclxuXHJcbiAgICB2aXNpdEFsbChhc3RzOiBhbnlbXSk6IGFueVtdIHsgcmV0dXJuIGFzdHMubWFwKG5vZGUgPT4gbm9kZS52aXNpdCh0aGlzKSk7IH1cclxuXHJcbiAgICB2aXNpdENoYWluKGFzdDogQ2hhaW4sIGNvbnRleHQ6IGFueSkge31cclxuXHJcbiAgICB2aXNpdFF1b3RlKGFzdDogUXVvdGUsIGNvbnRleHQ6IGFueSkge31cclxufSJdfQ==
|