@angular/compiler 16.2.0-next.2 → 16.2.0-next.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/esm2022/src/compiler.mjs +3 -3
  2. package/esm2022/src/jit_compiler_facade.mjs +6 -2
  3. package/esm2022/src/output/abstract_emitter.mjs +4 -1
  4. package/esm2022/src/output/output_ast.mjs +22 -1
  5. package/esm2022/src/render3/partial/class_metadata.mjs +1 -1
  6. package/esm2022/src/render3/partial/directive.mjs +1 -1
  7. package/esm2022/src/render3/partial/factory.mjs +1 -1
  8. package/esm2022/src/render3/partial/injectable.mjs +1 -1
  9. package/esm2022/src/render3/partial/injector.mjs +1 -1
  10. package/esm2022/src/render3/partial/ng_module.mjs +1 -1
  11. package/esm2022/src/render3/partial/pipe.mjs +1 -1
  12. package/esm2022/src/render3/r3_ast.mjs +109 -1
  13. package/esm2022/src/render3/r3_deferred_blocks.mjs +156 -0
  14. package/esm2022/src/render3/r3_deferred_triggers.mjs +275 -0
  15. package/esm2022/src/render3/r3_template_transform.mjs +40 -12
  16. package/esm2022/src/render3/view/t2_binder.mjs +61 -6
  17. package/esm2022/src/render3/view/template.mjs +17 -3
  18. package/esm2022/src/template/pipeline/ir/src/enums.mjs +21 -9
  19. package/esm2022/src/template/pipeline/ir/src/expression.mjs +4 -1
  20. package/esm2022/src/template/pipeline/ir/src/ops/update.mjs +42 -1
  21. package/esm2022/src/template/pipeline/src/emit.mjs +8 -6
  22. package/esm2022/src/template/pipeline/src/ingest.mjs +25 -3
  23. package/esm2022/src/template/pipeline/src/instruction.mjs +35 -8
  24. package/esm2022/src/template/pipeline/src/phases/attribute_extraction.mjs +2 -1
  25. package/esm2022/src/template/pipeline/src/phases/chaining.mjs +11 -1
  26. package/esm2022/src/template/pipeline/src/phases/naming.mjs +38 -9
  27. package/esm2022/src/template/pipeline/src/phases/property_ordering.mjs +82 -0
  28. package/esm2022/src/template/pipeline/src/phases/reify.mjs +10 -1
  29. package/esm2022/src/template/pipeline/src/phases/var_counting.mjs +13 -8
  30. package/esm2022/src/template_parser/binding_parser.mjs +4 -4
  31. package/esm2022/src/util.mjs +2 -8
  32. package/esm2022/src/version.mjs +1 -1
  33. package/fesm2022/compiler.mjs +1322 -454
  34. package/fesm2022/compiler.mjs.map +1 -1
  35. package/fesm2022/testing.mjs +1 -1
  36. package/index.d.ts +120 -2
  37. package/package.json +2 -2
  38. package/testing/index.d.ts +1 -1
@@ -0,0 +1,275 @@
1
+ /**
2
+ * @license
3
+ * Copyright Google LLC 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 { Lexer, TokenType } from '../expression_parser/lexer';
10
+ import { ParseError, ParseSourceSpan } from '../parse_util';
11
+ import * as t from './r3_ast';
12
+ /** Pattern for a timing value in a trigger. */
13
+ const TIME_PATTERN = /^\d+(ms|s)?$/;
14
+ /** Pattern for a separator between keywords in a trigger expression. */
15
+ const SEPARATOR_PATTERN = /^\s$/;
16
+ /** Pairs of characters that form syntax that is comma-delimited. */
17
+ const COMMA_DELIMITED_SYNTAX = new Map([
18
+ [chars.$LBRACE, chars.$RBRACE],
19
+ [chars.$LBRACKET, chars.$RBRACKET],
20
+ [chars.$LPAREN, chars.$RPAREN], // Function calls
21
+ ]);
22
+ /** Possible types of `on` triggers. */
23
+ var OnTriggerType;
24
+ (function (OnTriggerType) {
25
+ OnTriggerType["IDLE"] = "idle";
26
+ OnTriggerType["TIMER"] = "timer";
27
+ OnTriggerType["INTERACTION"] = "interaction";
28
+ OnTriggerType["IMMEDIATE"] = "immediate";
29
+ OnTriggerType["HOVER"] = "hover";
30
+ OnTriggerType["VIEWPORT"] = "viewport";
31
+ })(OnTriggerType || (OnTriggerType = {}));
32
+ /** Parses a `when` deferred trigger. */
33
+ export function parseWhenTrigger({ expression, sourceSpan }, bindingParser, errors) {
34
+ const whenIndex = expression.indexOf('when');
35
+ // This is here just to be safe, we shouldn't enter this function
36
+ // in the first place if a block doesn't have the "when" keyword.
37
+ if (whenIndex === -1) {
38
+ errors.push(new ParseError(sourceSpan, `Could not find "when" keyword in expression`));
39
+ return null;
40
+ }
41
+ const start = getTriggerParametersStart(expression, whenIndex + 1);
42
+ const parsed = bindingParser.parseBinding(expression.slice(start), false, sourceSpan, sourceSpan.start.offset + start);
43
+ return new t.BoundDeferredTrigger(parsed, sourceSpan);
44
+ }
45
+ /** Parses an `on` trigger */
46
+ export function parseOnTrigger({ expression, sourceSpan }, errors) {
47
+ const onIndex = expression.indexOf('on');
48
+ // This is here just to be safe, we shouldn't enter this function
49
+ // in the first place if a block doesn't have the "on" keyword.
50
+ if (onIndex === -1) {
51
+ errors.push(new ParseError(sourceSpan, `Could not find "on" keyword in expression`));
52
+ return [];
53
+ }
54
+ const start = getTriggerParametersStart(expression, onIndex + 1);
55
+ return new OnTriggerParser(expression, start, sourceSpan, errors).parse();
56
+ }
57
+ class OnTriggerParser {
58
+ constructor(expression, start, span, errors) {
59
+ this.expression = expression;
60
+ this.start = start;
61
+ this.span = span;
62
+ this.errors = errors;
63
+ this.index = 0;
64
+ this.triggers = [];
65
+ this.tokens = new Lexer().tokenize(expression.slice(start));
66
+ }
67
+ parse() {
68
+ while (this.tokens.length > 0 && this.index < this.tokens.length) {
69
+ const token = this.token();
70
+ if (!token.isIdentifier()) {
71
+ this.unexpectedToken(token);
72
+ break;
73
+ }
74
+ // An identifier immediately followed by a comma or the end of
75
+ // the expression cannot have parameters so we can exit early.
76
+ if (this.isFollowedByOrLast(chars.$COMMA)) {
77
+ this.consumeTrigger(token, []);
78
+ this.advance();
79
+ }
80
+ else if (this.isFollowedByOrLast(chars.$LPAREN)) {
81
+ this.advance(); // Advance to the opening paren.
82
+ const prevErrors = this.errors.length;
83
+ const parameters = this.consumeParameters();
84
+ if (this.errors.length !== prevErrors) {
85
+ break;
86
+ }
87
+ this.consumeTrigger(token, parameters);
88
+ this.advance(); // Advance past the closing paren.
89
+ }
90
+ else if (this.index < this.tokens.length - 1) {
91
+ this.unexpectedToken(this.tokens[this.index + 1]);
92
+ }
93
+ this.advance();
94
+ }
95
+ return this.triggers;
96
+ }
97
+ advance() {
98
+ this.index++;
99
+ }
100
+ isFollowedByOrLast(char) {
101
+ if (this.index === this.tokens.length - 1) {
102
+ return true;
103
+ }
104
+ return this.tokens[this.index + 1].isCharacter(char);
105
+ }
106
+ token() {
107
+ return this.tokens[Math.min(this.index, this.tokens.length - 1)];
108
+ }
109
+ consumeTrigger(identifier, parameters) {
110
+ const startSpan = this.span.start.moveBy(this.start + identifier.index - this.tokens[0].index);
111
+ const endSpan = startSpan.moveBy(this.token().end - identifier.index);
112
+ const sourceSpan = new ParseSourceSpan(startSpan, endSpan);
113
+ try {
114
+ switch (identifier.toString()) {
115
+ case OnTriggerType.IDLE:
116
+ this.triggers.push(createIdleTrigger(parameters, sourceSpan));
117
+ break;
118
+ case OnTriggerType.TIMER:
119
+ this.triggers.push(createTimerTrigger(parameters, sourceSpan));
120
+ break;
121
+ case OnTriggerType.INTERACTION:
122
+ this.triggers.push(createInteractionTrigger(parameters, sourceSpan));
123
+ break;
124
+ case OnTriggerType.IMMEDIATE:
125
+ this.triggers.push(createImmediateTrigger(parameters, sourceSpan));
126
+ break;
127
+ case OnTriggerType.HOVER:
128
+ this.triggers.push(createHoverTrigger(parameters, sourceSpan));
129
+ break;
130
+ case OnTriggerType.VIEWPORT:
131
+ this.triggers.push(createViewportTrigger(parameters, sourceSpan));
132
+ break;
133
+ default:
134
+ throw new Error(`Unrecognized trigger type "${identifier}"`);
135
+ }
136
+ }
137
+ catch (e) {
138
+ this.error(identifier, e.message);
139
+ }
140
+ }
141
+ consumeParameters() {
142
+ const parameters = [];
143
+ if (!this.token().isCharacter(chars.$LPAREN)) {
144
+ this.unexpectedToken(this.token());
145
+ return parameters;
146
+ }
147
+ this.advance();
148
+ const commaDelimStack = [];
149
+ let current = '';
150
+ while (this.index < this.tokens.length) {
151
+ const token = this.token();
152
+ // Stop parsing if we've hit the end character and we're outside of a comma-delimited syntax.
153
+ // Note that we don't need to account for strings here since the lexer already parsed them
154
+ // into string tokens.
155
+ if (token.isCharacter(chars.$RPAREN) && commaDelimStack.length === 0) {
156
+ if (current.length) {
157
+ parameters.push(current);
158
+ }
159
+ break;
160
+ }
161
+ // In the `on` microsyntax "top-level" commas (e.g. ones outside of an parameters) separate
162
+ // the different triggers (e.g. `on idle,timer(500)`). This is problematic, because the
163
+ // function-like syntax also implies that multiple parameters can be passed into the
164
+ // individual trigger (e.g. `on foo(a, b)`). To avoid tripping up the parser with commas that
165
+ // are part of other sorts of syntax (object literals, arrays), we treat anything inside
166
+ // a comma-delimited syntax block as plain text.
167
+ if (token.type === TokenType.Character && COMMA_DELIMITED_SYNTAX.has(token.numValue)) {
168
+ commaDelimStack.push(COMMA_DELIMITED_SYNTAX.get(token.numValue));
169
+ }
170
+ if (commaDelimStack.length > 0 &&
171
+ token.isCharacter(commaDelimStack[commaDelimStack.length - 1])) {
172
+ commaDelimStack.pop();
173
+ }
174
+ // If we hit a comma outside of a comma-delimited syntax, it means
175
+ // that we're at the top level and we're starting a new parameter.
176
+ if (commaDelimStack.length === 0 && token.isCharacter(chars.$COMMA) && current.length > 0) {
177
+ parameters.push(current);
178
+ current = '';
179
+ this.advance();
180
+ continue;
181
+ }
182
+ // Otherwise treat the token as a plain text character in the current parameter.
183
+ current += this.tokenText();
184
+ this.advance();
185
+ }
186
+ if (!this.token().isCharacter(chars.$RPAREN) || commaDelimStack.length > 0) {
187
+ this.error(this.token(), 'Unexpected end of expression');
188
+ }
189
+ if (this.index < this.tokens.length - 1 &&
190
+ !this.tokens[this.index + 1].isCharacter(chars.$COMMA)) {
191
+ this.unexpectedToken(this.tokens[this.index + 1]);
192
+ }
193
+ return parameters;
194
+ }
195
+ tokenText() {
196
+ // Tokens have a toString already which we could use, but for string tokens it omits the quotes.
197
+ // Eventually we could expose this information on the token directly.
198
+ return this.expression.slice(this.start + this.token().index, this.start + this.token().end);
199
+ }
200
+ error(token, message) {
201
+ const newStart = this.span.start.moveBy(this.start + token.index);
202
+ const newEnd = newStart.moveBy(token.end - token.index);
203
+ this.errors.push(new ParseError(new ParseSourceSpan(newStart, newEnd), message));
204
+ }
205
+ unexpectedToken(token) {
206
+ this.error(token, `Unexpected token "${token}"`);
207
+ }
208
+ }
209
+ function createIdleTrigger(parameters, sourceSpan) {
210
+ if (parameters.length > 0) {
211
+ throw new Error(`"${OnTriggerType.IDLE}" trigger cannot have parameters`);
212
+ }
213
+ return new t.IdleDeferredTrigger(sourceSpan);
214
+ }
215
+ function createTimerTrigger(parameters, sourceSpan) {
216
+ if (parameters.length !== 1) {
217
+ throw new Error(`"${OnTriggerType.TIMER}" trigger must have exactly one parameter`);
218
+ }
219
+ const delay = parseDeferredTime(parameters[0]);
220
+ if (delay === null) {
221
+ throw new Error(`Could not parse time value of trigger "${OnTriggerType.TIMER}"`);
222
+ }
223
+ return new t.TimerDeferredTrigger(delay, sourceSpan);
224
+ }
225
+ function createInteractionTrigger(parameters, sourceSpan) {
226
+ if (parameters.length > 1) {
227
+ throw new Error(`"${OnTriggerType.INTERACTION}" trigger can only have zero or one parameters`);
228
+ }
229
+ return new t.InteractionDeferredTrigger(parameters[0] ?? null, sourceSpan);
230
+ }
231
+ function createImmediateTrigger(parameters, sourceSpan) {
232
+ if (parameters.length > 0) {
233
+ throw new Error(`"${OnTriggerType.IMMEDIATE}" trigger cannot have parameters`);
234
+ }
235
+ return new t.ImmediateDeferredTrigger(sourceSpan);
236
+ }
237
+ function createHoverTrigger(parameters, sourceSpan) {
238
+ if (parameters.length > 0) {
239
+ throw new Error(`"${OnTriggerType.HOVER}" trigger cannot have parameters`);
240
+ }
241
+ return new t.HoverDeferredTrigger(sourceSpan);
242
+ }
243
+ function createViewportTrigger(parameters, sourceSpan) {
244
+ // TODO: the RFC has some more potential parameters for `viewport`.
245
+ if (parameters.length > 1) {
246
+ throw new Error(`"${OnTriggerType.VIEWPORT}" trigger can only have zero or one parameters`);
247
+ }
248
+ return new t.ViewportDeferredTrigger(parameters[0] ?? null, sourceSpan);
249
+ }
250
+ /** Gets the index within an expression at which the trigger parameters start. */
251
+ export function getTriggerParametersStart(value, startPosition = 0) {
252
+ let hasFoundSeparator = false;
253
+ for (let i = startPosition; i < value.length; i++) {
254
+ if (SEPARATOR_PATTERN.test(value[i])) {
255
+ hasFoundSeparator = true;
256
+ }
257
+ else if (hasFoundSeparator) {
258
+ return i;
259
+ }
260
+ }
261
+ return -1;
262
+ }
263
+ /**
264
+ * Parses a time expression from a deferred trigger to
265
+ * milliseconds. Returns null if it cannot be parsed.
266
+ */
267
+ export function parseDeferredTime(value) {
268
+ const match = value.match(TIME_PATTERN);
269
+ if (!match) {
270
+ return null;
271
+ }
272
+ const [time, units] = match;
273
+ return parseInt(time) * (units === 's' ? 1000 : 1);
274
+ }
275
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicjNfZGVmZXJyZWRfdHJpZ2dlcnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9jb21waWxlci9zcmMvcmVuZGVyMy9yM19kZWZlcnJlZF90cmlnZ2Vycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7O0dBTUc7QUFFSCxPQUFPLEtBQUssS0FBSyxNQUFNLFVBQVUsQ0FBQztBQUNsQyxPQUFPLEVBQUMsS0FBSyxFQUFTLFNBQVMsRUFBQyxNQUFNLDRCQUE0QixDQUFDO0FBRW5FLE9BQU8sRUFBQyxVQUFVLEVBQUUsZUFBZSxFQUFDLE1BQU0sZUFBZSxDQUFDO0FBRzFELE9BQU8sS0FBSyxDQUFDLE1BQU0sVUFBVSxDQUFDO0FBRTlCLCtDQUErQztBQUMvQyxNQUFNLFlBQVksR0FBRyxjQUFjLENBQUM7QUFFcEMsd0VBQXdFO0FBQ3hFLE1BQU0saUJBQWlCLEdBQUcsTUFBTSxDQUFDO0FBRWpDLG9FQUFvRTtBQUNwRSxNQUFNLHNCQUFzQixHQUFHLElBQUksR0FBRyxDQUFDO0lBQ3JDLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxLQUFLLENBQUMsT0FBTyxDQUFDO0lBQzlCLENBQUMsS0FBSyxDQUFDLFNBQVMsRUFBRSxLQUFLLENBQUMsU0FBUyxDQUFDO0lBQ2xDLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxLQUFLLENBQUMsT0FBTyxDQUFDLEVBQU8saUJBQWlCO0NBQ3ZELENBQUMsQ0FBQztBQUVILHVDQUF1QztBQUN2QyxJQUFLLGFBT0o7QUFQRCxXQUFLLGFBQWE7SUFDaEIsOEJBQWEsQ0FBQTtJQUNiLGdDQUFlLENBQUE7SUFDZiw0Q0FBMkIsQ0FBQTtJQUMzQix3Q0FBdUIsQ0FBQTtJQUN2QixnQ0FBZSxDQUFBO0lBQ2Ysc0NBQXFCLENBQUE7QUFDdkIsQ0FBQyxFQVBJLGFBQWEsS0FBYixhQUFhLFFBT2pCO0FBRUQsd0NBQXdDO0FBQ3hDLE1BQU0sVUFBVSxnQkFBZ0IsQ0FDNUIsRUFBQyxVQUFVLEVBQUUsVUFBVSxFQUFzQixFQUFFLGFBQTRCLEVBQzNFLE1BQW9CO0lBQ3RCLE1BQU0sU0FBUyxHQUFHLFVBQVUsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUM7SUFFN0MsaUVBQWlFO0lBQ2pFLGlFQUFpRTtJQUNqRSxJQUFJLFNBQVMsS0FBSyxDQUFDLENBQUMsRUFBRTtRQUNwQixNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksVUFBVSxDQUFDLFVBQVUsRUFBRSw2Q0FBNkMsQ0FBQyxDQUFDLENBQUM7UUFDdkYsT0FBTyxJQUFJLENBQUM7S0FDYjtJQUVELE1BQU0sS0FBSyxHQUFHLHlCQUF5QixDQUFDLFVBQVUsRUFBRSxTQUFTLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFDbkUsTUFBTSxNQUFNLEdBQUcsYUFBYSxDQUFDLFlBQVksQ0FDckMsVUFBVSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsRUFBRSxLQUFLLEVBQUUsVUFBVSxFQUFFLFVBQVUsQ0FBQyxLQUFLLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQyxDQUFDO0lBRWpGLE9BQU8sSUFBSSxDQUFDLENBQUMsb0JBQW9CLENBQUMsTUFBTSxFQUFFLFVBQVUsQ0FBQyxDQUFDO0FBQ3hELENBQUM7QUFFRCw2QkFBNkI7QUFDN0IsTUFBTSxVQUFVLGNBQWMsQ0FDMUIsRUFBQyxVQUFVLEVBQUUsVUFBVSxFQUFzQixFQUFFLE1BQW9CO0lBQ3JFLE1BQU0sT0FBTyxHQUFHLFVBQVUsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7SUFFekMsaUVBQWlFO0lBQ2pFLCtEQUErRDtJQUMvRCxJQUFJLE9BQU8sS0FBSyxDQUFDLENBQUMsRUFBRTtRQUNsQixNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksVUFBVSxDQUFDLFVBQVUsRUFBRSwyQ0FBMkMsQ0FBQyxDQUFDLENBQUM7UUFDckYsT0FBTyxFQUFFLENBQUM7S0FDWDtJQUVELE1BQU0sS0FBSyxHQUFHLHlCQUF5QixDQUFDLFVBQVUsRUFBRSxPQUFPLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFDakUsT0FBTyxJQUFJLGVBQWUsQ0FBQyxVQUFVLEVBQUUsS0FBSyxFQUFFLFVBQVUsRUFBRSxNQUFNLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztBQUM1RSxDQUFDO0FBRUQsTUFBTSxlQUFlO0lBS25CLFlBQ1ksVUFBa0IsRUFBVSxLQUFhLEVBQVUsSUFBcUIsRUFDeEUsTUFBb0I7UUFEcEIsZUFBVSxHQUFWLFVBQVUsQ0FBUTtRQUFVLFVBQUssR0FBTCxLQUFLLENBQVE7UUFBVSxTQUFJLEdBQUosSUFBSSxDQUFpQjtRQUN4RSxXQUFNLEdBQU4sTUFBTSxDQUFjO1FBTnhCLFVBQUssR0FBRyxDQUFDLENBQUM7UUFFVixhQUFRLEdBQXdCLEVBQUUsQ0FBQztRQUt6QyxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksS0FBSyxFQUFFLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztJQUM5RCxDQUFDO0lBRUQsS0FBSztRQUNILE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUU7WUFDaEUsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBRTNCLElBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxFQUFFLEVBQUU7Z0JBQ3pCLElBQUksQ0FBQyxlQUFlLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBQzVCLE1BQU07YUFDUDtZQUVELDhEQUE4RDtZQUM5RCw4REFBOEQ7WUFDOUQsSUFBSSxJQUFJLENBQUMsa0JBQWtCLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxFQUFFO2dCQUN6QyxJQUFJLENBQUMsY0FBYyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztnQkFDL0IsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO2FBQ2hCO2lCQUFNLElBQUksSUFBSSxDQUFDLGtCQUFrQixDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsRUFBRTtnQkFDakQsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUUsZ0NBQWdDO2dCQUNqRCxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQztnQkFDdEMsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7Z0JBQzVDLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEtBQUssVUFBVSxFQUFFO29CQUNyQyxNQUFNO2lCQUNQO2dCQUNELElBQUksQ0FBQyxjQUFjLENBQUMsS0FBSyxFQUFFLFVBQVUsQ0FBQyxDQUFDO2dCQUN2QyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBRSxrQ0FBa0M7YUFDcEQ7aUJBQU0sSUFBSSxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtnQkFDOUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQzthQUNuRDtZQUVELElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztTQUNoQjtRQUVELE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQztJQUN2QixDQUFDO0lBRU8sT0FBTztRQUNiLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUNmLENBQUM7SUFFTyxrQkFBa0IsQ0FBQyxJQUFZO1FBQ3JDLElBQUksSUFBSSxDQUFDLEtBQUssS0FBSyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7WUFDekMsT0FBTyxJQUFJLENBQUM7U0FDYjtRQUVELE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUN2RCxDQUFDO0lBRU8sS0FBSztRQUNYLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNuRSxDQUFDO0lBRU8sY0FBYyxDQUFDLFVBQWlCLEVBQUUsVUFBb0I7UUFDNUQsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLEdBQUcsVUFBVSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQy9GLE1BQU0sT0FBTyxHQUFHLFNBQVMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDLEdBQUcsR0FBRyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDdEUsTUFBTSxVQUFVLEdBQUcsSUFBSSxlQUFlLENBQUMsU0FBUyxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBRTNELElBQUk7WUFDRixRQUFRLFVBQVUsQ0FBQyxRQUFRLEVBQUUsRUFBRTtnQkFDN0IsS0FBSyxhQUFhLENBQUMsSUFBSTtvQkFDckIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsVUFBVSxFQUFFLFVBQVUsQ0FBQyxDQUFDLENBQUM7b0JBQzlELE1BQU07Z0JBRVIsS0FBSyxhQUFhLENBQUMsS0FBSztvQkFDdEIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsVUFBVSxFQUFFLFVBQVUsQ0FBQyxDQUFDLENBQUM7b0JBQy9ELE1BQU07Z0JBRVIsS0FBSyxhQUFhLENBQUMsV0FBVztvQkFDNUIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsd0JBQXdCLENBQUMsVUFBVSxFQUFFLFVBQVUsQ0FBQyxDQUFDLENBQUM7b0JBQ3JFLE1BQU07Z0JBRVIsS0FBSyxhQUFhLENBQUMsU0FBUztvQkFDMUIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsc0JBQXNCLENBQUMsVUFBVSxFQUFFLFVBQVUsQ0FBQyxDQUFDLENBQUM7b0JBQ25FLE1BQU07Z0JBRVIsS0FBSyxhQUFhLENBQUMsS0FBSztvQkFDdEIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsVUFBVSxFQUFFLFVBQVUsQ0FBQyxDQUFDLENBQUM7b0JBQy9ELE1BQU07Z0JBRVIsS0FBSyxhQUFhLENBQUMsUUFBUTtvQkFDekIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMscUJBQXFCLENBQUMsVUFBVSxFQUFFLFVBQVUsQ0FBQyxDQUFDLENBQUM7b0JBQ2xFLE1BQU07Z0JBRVI7b0JBQ0UsTUFBTSxJQUFJLEtBQUssQ0FBQyw4QkFBOEIsVUFBVSxHQUFHLENBQUMsQ0FBQzthQUNoRTtTQUNGO1FBQUMsT0FBTyxDQUFDLEVBQUU7WUFDVixJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsRUFBRyxDQUFXLENBQUMsT0FBTyxDQUFDLENBQUM7U0FDOUM7SUFDSCxDQUFDO0lBRU8saUJBQWlCO1FBQ3ZCLE1BQU0sVUFBVSxHQUFhLEVBQUUsQ0FBQztRQUVoQyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLEVBQUU7WUFDNUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQztZQUNuQyxPQUFPLFVBQVUsQ0FBQztTQUNuQjtRQUVELElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUVmLE1BQU0sZUFBZSxHQUFhLEVBQUUsQ0FBQztRQUNyQyxJQUFJLE9BQU8sR0FBRyxFQUFFLENBQUM7UUFFakIsT0FBTyxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFO1lBQ3RDLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUUzQiw2RkFBNkY7WUFDN0YsMEZBQTBGO1lBQzFGLHNCQUFzQjtZQUN0QixJQUFJLEtBQUssQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLGVBQWUsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFO2dCQUNwRSxJQUFJLE9BQU8sQ0FBQyxNQUFNLEVBQUU7b0JBQ2xCLFVBQVUsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7aUJBQzFCO2dCQUNELE1BQU07YUFDUDtZQUVELDJGQUEyRjtZQUMzRix1RkFBdUY7WUFDdkYsb0ZBQW9GO1lBQ3BGLDZGQUE2RjtZQUM3Rix3RkFBd0Y7WUFDeEYsZ0RBQWdEO1lBQ2hELElBQUksS0FBSyxDQUFDLElBQUksS0FBSyxTQUFTLENBQUMsU0FBUyxJQUFJLHNCQUFzQixDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLEVBQUU7Z0JBQ3BGLGVBQWUsQ0FBQyxJQUFJLENBQUMsc0JBQXNCLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUUsQ0FBQyxDQUFDO2FBQ25FO1lBRUQsSUFBSSxlQUFlLENBQUMsTUFBTSxHQUFHLENBQUM7Z0JBQzFCLEtBQUssQ0FBQyxXQUFXLENBQUMsZUFBZSxDQUFDLGVBQWUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRTtnQkFDbEUsZUFBZSxDQUFDLEdBQUcsRUFBRSxDQUFDO2FBQ3ZCO1lBRUQsa0VBQWtFO1lBQ2xFLGtFQUFrRTtZQUNsRSxJQUFJLGVBQWUsQ0FBQyxNQUFNLEtBQUssQ0FBQyxJQUFJLEtBQUssQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxJQUFJLE9BQU8sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO2dCQUN6RixVQUFVLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO2dCQUN6QixPQUFPLEdBQUcsRUFBRSxDQUFDO2dCQUNiLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztnQkFDZixTQUFTO2FBQ1Y7WUFFRCxnRkFBZ0Y7WUFDaEYsT0FBTyxJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUM1QixJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7U0FDaEI7UUFFRCxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksZUFBZSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7WUFDMUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLEVBQUUsOEJBQThCLENBQUMsQ0FBQztTQUMxRDtRQUVELElBQUksSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDO1lBQ25DLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLEVBQUU7WUFDMUQsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztTQUNuRDtRQUVELE9BQU8sVUFBVSxDQUFDO0lBQ3BCLENBQUM7SUFFTyxTQUFTO1FBQ2YsZ0dBQWdHO1FBQ2hHLHFFQUFxRTtRQUNyRSxPQUFPLElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUMvRixDQUFDO0lBRU8sS0FBSyxDQUFDLEtBQVksRUFBRSxPQUFlO1FBQ3pDLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNsRSxNQUFNLE1BQU0sR0FBRyxRQUFRLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxHQUFHLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3hELElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksVUFBVSxDQUFDLElBQUksZUFBZSxDQUFDLFFBQVEsRUFBRSxNQUFNLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDO0lBQ25GLENBQUM7SUFFTyxlQUFlLENBQUMsS0FBWTtRQUNsQyxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxxQkFBcUIsS0FBSyxHQUFHLENBQUMsQ0FBQztJQUNuRCxDQUFDO0NBQ0Y7QUFFRCxTQUFTLGlCQUFpQixDQUN0QixVQUFvQixFQUFFLFVBQTJCO0lBQ25ELElBQUksVUFBVSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7UUFDekIsTUFBTSxJQUFJLEtBQUssQ0FBQyxJQUFJLGFBQWEsQ0FBQyxJQUFJLGtDQUFrQyxDQUFDLENBQUM7S0FDM0U7SUFFRCxPQUFPLElBQUksQ0FBQyxDQUFDLG1CQUFtQixDQUFDLFVBQVUsQ0FBQyxDQUFDO0FBQy9DLENBQUM7QUFFRCxTQUFTLGtCQUFrQixDQUFDLFVBQW9CLEVBQUUsVUFBMkI7SUFDM0UsSUFBSSxVQUFVLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTtRQUMzQixNQUFNLElBQUksS0FBSyxDQUFDLElBQUksYUFBYSxDQUFDLEtBQUssMkNBQTJDLENBQUMsQ0FBQztLQUNyRjtJQUVELE1BQU0sS0FBSyxHQUFHLGlCQUFpQixDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBRS9DLElBQUksS0FBSyxLQUFLLElBQUksRUFBRTtRQUNsQixNQUFNLElBQUksS0FBSyxDQUFDLDBDQUEwQyxhQUFhLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQztLQUNuRjtJQUVELE9BQU8sSUFBSSxDQUFDLENBQUMsb0JBQW9CLENBQUMsS0FBSyxFQUFFLFVBQVUsQ0FBQyxDQUFDO0FBQ3ZELENBQUM7QUFFRCxTQUFTLHdCQUF3QixDQUM3QixVQUFvQixFQUFFLFVBQTJCO0lBQ25ELElBQUksVUFBVSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7UUFDekIsTUFBTSxJQUFJLEtBQUssQ0FBQyxJQUFJLGFBQWEsQ0FBQyxXQUFXLGdEQUFnRCxDQUFDLENBQUM7S0FDaEc7SUFFRCxPQUFPLElBQUksQ0FBQyxDQUFDLDBCQUEwQixDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFJLEVBQUUsVUFBVSxDQUFDLENBQUM7QUFDN0UsQ0FBQztBQUVELFNBQVMsc0JBQXNCLENBQzNCLFVBQW9CLEVBQUUsVUFBMkI7SUFDbkQsSUFBSSxVQUFVLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtRQUN6QixNQUFNLElBQUksS0FBSyxDQUFDLElBQUksYUFBYSxDQUFDLFNBQVMsa0NBQWtDLENBQUMsQ0FBQztLQUNoRjtJQUVELE9BQU8sSUFBSSxDQUFDLENBQUMsd0JBQXdCLENBQUMsVUFBVSxDQUFDLENBQUM7QUFDcEQsQ0FBQztBQUVELFNBQVMsa0JBQWtCLENBQ3ZCLFVBQW9CLEVBQUUsVUFBMkI7SUFDbkQsSUFBSSxVQUFVLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtRQUN6QixNQUFNLElBQUksS0FBSyxDQUFDLElBQUksYUFBYSxDQUFDLEtBQUssa0NBQWtDLENBQUMsQ0FBQztLQUM1RTtJQUVELE9BQU8sSUFBSSxDQUFDLENBQUMsb0JBQW9CLENBQUMsVUFBVSxDQUFDLENBQUM7QUFDaEQsQ0FBQztBQUVELFNBQVMscUJBQXFCLENBQzFCLFVBQW9CLEVBQUUsVUFBMkI7SUFDbkQsbUVBQW1FO0lBQ25FLElBQUksVUFBVSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7UUFDekIsTUFBTSxJQUFJLEtBQUssQ0FBQyxJQUFJLGFBQWEsQ0FBQyxRQUFRLGdEQUFnRCxDQUFDLENBQUM7S0FDN0Y7SUFFRCxPQUFPLElBQUksQ0FBQyxDQUFDLHVCQUF1QixDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFJLEVBQUUsVUFBVSxDQUFDLENBQUM7QUFDMUUsQ0FBQztBQUVELGlGQUFpRjtBQUNqRixNQUFNLFVBQVUseUJBQXlCLENBQUMsS0FBYSxFQUFFLGFBQWEsR0FBRyxDQUFDO0lBQ3hFLElBQUksaUJBQWlCLEdBQUcsS0FBSyxDQUFDO0lBRTlCLEtBQUssSUFBSSxDQUFDLEdBQUcsYUFBYSxFQUFFLENBQUMsR0FBRyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO1FBQ2pELElBQUksaUJBQWlCLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFO1lBQ3BDLGlCQUFpQixHQUFHLElBQUksQ0FBQztTQUMxQjthQUFNLElBQUksaUJBQWlCLEVBQUU7WUFDNUIsT0FBTyxDQUFDLENBQUM7U0FDVjtLQUNGO0lBRUQsT0FBTyxDQUFDLENBQUMsQ0FBQztBQUNaLENBQUM7QUFFRDs7O0dBR0c7QUFDSCxNQUFNLFVBQVUsaUJBQWlCLENBQUMsS0FBYTtJQUM3QyxNQUFNLEtBQUssR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxDQUFDO0lBRXhDLElBQUksQ0FBQyxLQUFLLEVBQUU7UUFDVixPQUFPLElBQUksQ0FBQztLQUNiO0lBRUQsTUFBTSxDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsR0FBRyxLQUFLLENBQUM7SUFDNUIsT0FBTyxRQUFRLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLEtBQUssR0FBRyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3JELENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgR29vZ2xlIExMQyBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vYW5ndWxhci5pby9saWNlbnNlXG4gKi9cblxuaW1wb3J0ICogYXMgY2hhcnMgZnJvbSAnLi4vY2hhcnMnO1xuaW1wb3J0IHtMZXhlciwgVG9rZW4sIFRva2VuVHlwZX0gZnJvbSAnLi4vZXhwcmVzc2lvbl9wYXJzZXIvbGV4ZXInO1xuaW1wb3J0ICogYXMgaHRtbCBmcm9tICcuLi9tbF9wYXJzZXIvYXN0JztcbmltcG9ydCB7UGFyc2VFcnJvciwgUGFyc2VTb3VyY2VTcGFufSBmcm9tICcuLi9wYXJzZV91dGlsJztcbmltcG9ydCB7QmluZGluZ1BhcnNlcn0gZnJvbSAnLi4vdGVtcGxhdGVfcGFyc2VyL2JpbmRpbmdfcGFyc2VyJztcblxuaW1wb3J0ICogYXMgdCBmcm9tICcuL3IzX2FzdCc7XG5cbi8qKiBQYXR0ZXJuIGZvciBhIHRpbWluZyB2YWx1ZSBpbiBhIHRyaWdnZXIuICovXG5jb25zdCBUSU1FX1BBVFRFUk4gPSAvXlxcZCsobXN8cyk/JC87XG5cbi8qKiBQYXR0ZXJuIGZvciBhIHNlcGFyYXRvciBiZXR3ZWVuIGtleXdvcmRzIGluIGEgdHJpZ2dlciBleHByZXNzaW9uLiAqL1xuY29uc3QgU0VQQVJBVE9SX1BBVFRFUk4gPSAvXlxccyQvO1xuXG4vKiogUGFpcnMgb2YgY2hhcmFjdGVycyB0aGF0IGZvcm0gc3ludGF4IHRoYXQgaXMgY29tbWEtZGVsaW1pdGVkLiAqL1xuY29uc3QgQ09NTUFfREVMSU1JVEVEX1NZTlRBWCA9IG5ldyBNYXAoW1xuICBbY2hhcnMuJExCUkFDRSwgY2hhcnMuJFJCUkFDRV0sICAgICAgLy8gT2JqZWN0IGxpdGVyYWxzXG4gIFtjaGFycy4kTEJSQUNLRVQsIGNoYXJzLiRSQlJBQ0tFVF0sICAvLyBBcnJheSBsaXRlcmFsc1xuICBbY2hhcnMuJExQQVJFTiwgY2hhcnMuJFJQQVJFTl0sICAgICAgLy8gRnVuY3Rpb24gY2FsbHNcbl0pO1xuXG4vKiogUG9zc2libGUgdHlwZXMgb2YgYG9uYCB0cmlnZ2Vycy4gKi9cbmVudW0gT25UcmlnZ2VyVHlwZSB7XG4gIElETEUgPSAnaWRsZScsXG4gIFRJTUVSID0gJ3RpbWVyJyxcbiAgSU5URVJBQ1RJT04gPSAnaW50ZXJhY3Rpb24nLFxuICBJTU1FRElBVEUgPSAnaW1tZWRpYXRlJyxcbiAgSE9WRVIgPSAnaG92ZXInLFxuICBWSUVXUE9SVCA9ICd2aWV3cG9ydCcsXG59XG5cbi8qKiBQYXJzZXMgYSBgd2hlbmAgZGVmZXJyZWQgdHJpZ2dlci4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZVdoZW5UcmlnZ2VyKFxuICAgIHtleHByZXNzaW9uLCBzb3VyY2VTcGFufTogaHRtbC5CbG9ja1BhcmFtZXRlciwgYmluZGluZ1BhcnNlcjogQmluZGluZ1BhcnNlcixcbiAgICBlcnJvcnM6IFBhcnNlRXJyb3JbXSk6IHQuQm91bmREZWZlcnJlZFRyaWdnZXJ8bnVsbCB7XG4gIGNvbnN0IHdoZW5JbmRleCA9IGV4cHJlc3Npb24uaW5kZXhPZignd2hlbicpO1xuXG4gIC8vIFRoaXMgaXMgaGVyZSBqdXN0IHRvIGJlIHNhZmUsIHdlIHNob3VsZG4ndCBlbnRlciB0aGlzIGZ1bmN0aW9uXG4gIC8vIGluIHRoZSBmaXJzdCBwbGFjZSBpZiBhIGJsb2NrIGRvZXNuJ3QgaGF2ZSB0aGUgXCJ3aGVuXCIga2V5d29yZC5cbiAgaWYgKHdoZW5JbmRleCA9PT0gLTEpIHtcbiAgICBlcnJvcnMucHVzaChuZXcgUGFyc2VFcnJvcihzb3VyY2VTcGFuLCBgQ291bGQgbm90IGZpbmQgXCJ3aGVuXCIga2V5d29yZCBpbiBleHByZXNzaW9uYCkpO1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgY29uc3Qgc3RhcnQgPSBnZXRUcmlnZ2VyUGFyYW1ldGVyc1N0YXJ0KGV4cHJlc3Npb24sIHdoZW5JbmRleCArIDEpO1xuICBjb25zdCBwYXJzZWQgPSBiaW5kaW5nUGFyc2VyLnBhcnNlQmluZGluZyhcbiAgICAgIGV4cHJlc3Npb24uc2xpY2Uoc3RhcnQpLCBmYWxzZSwgc291cmNlU3Bhbiwgc291cmNlU3Bhbi5zdGFydC5vZmZzZXQgKyBzdGFydCk7XG5cbiAgcmV0dXJuIG5ldyB0LkJvdW5kRGVmZXJyZWRUcmlnZ2VyKHBhcnNlZCwgc291cmNlU3Bhbik7XG59XG5cbi8qKiBQYXJzZXMgYW4gYG9uYCB0cmlnZ2VyICovXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VPblRyaWdnZXIoXG4gICAge2V4cHJlc3Npb24sIHNvdXJjZVNwYW59OiBodG1sLkJsb2NrUGFyYW1ldGVyLCBlcnJvcnM6IFBhcnNlRXJyb3JbXSk6IHQuRGVmZXJyZWRUcmlnZ2VyW10ge1xuICBjb25zdCBvbkluZGV4ID0gZXhwcmVzc2lvbi5pbmRleE9mKCdvbicpO1xuXG4gIC8vIFRoaXMgaXMgaGVyZSBqdXN0IHRvIGJlIHNhZmUsIHdlIHNob3VsZG4ndCBlbnRlciB0aGlzIGZ1bmN0aW9uXG4gIC8vIGluIHRoZSBmaXJzdCBwbGFjZSBpZiBhIGJsb2NrIGRvZXNuJ3QgaGF2ZSB0aGUgXCJvblwiIGtleXdvcmQuXG4gIGlmIChvbkluZGV4ID09PSAtMSkge1xuICAgIGVycm9ycy5wdXNoKG5ldyBQYXJzZUVycm9yKHNvdXJjZVNwYW4sIGBDb3VsZCBub3QgZmluZCBcIm9uXCIga2V5d29yZCBpbiBleHByZXNzaW9uYCkpO1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIGNvbnN0IHN0YXJ0ID0gZ2V0VHJpZ2dlclBhcmFtZXRlcnNTdGFydChleHByZXNzaW9uLCBvbkluZGV4ICsgMSk7XG4gIHJldHVybiBuZXcgT25UcmlnZ2VyUGFyc2VyKGV4cHJlc3Npb24sIHN0YXJ0LCBzb3VyY2VTcGFuLCBlcnJvcnMpLnBhcnNlKCk7XG59XG5cbmNsYXNzIE9uVHJpZ2dlclBhcnNlciB7XG4gIHByaXZhdGUgaW5kZXggPSAwO1xuICBwcml2YXRlIHRva2VuczogVG9rZW5bXTtcbiAgcHJpdmF0ZSB0cmlnZ2VyczogdC5EZWZlcnJlZFRyaWdnZXJbXSA9IFtdO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgICAgcHJpdmF0ZSBleHByZXNzaW9uOiBzdHJpbmcsIHByaXZhdGUgc3RhcnQ6IG51bWJlciwgcHJpdmF0ZSBzcGFuOiBQYXJzZVNvdXJjZVNwYW4sXG4gICAgICBwcml2YXRlIGVycm9yczogUGFyc2VFcnJvcltdKSB7XG4gICAgdGhpcy50b2tlbnMgPSBuZXcgTGV4ZXIoKS50b2tlbml6ZShleHByZXNzaW9uLnNsaWNlKHN0YXJ0KSk7XG4gIH1cblxuICBwYXJzZSgpOiB0LkRlZmVycmVkVHJpZ2dlcltdIHtcbiAgICB3aGlsZSAodGhpcy50b2tlbnMubGVuZ3RoID4gMCAmJiB0aGlzLmluZGV4IDwgdGhpcy50b2tlbnMubGVuZ3RoKSB7XG4gICAgICBjb25zdCB0b2tlbiA9IHRoaXMudG9rZW4oKTtcblxuICAgICAgaWYgKCF0b2tlbi5pc0lkZW50aWZpZXIoKSkge1xuICAgICAgICB0aGlzLnVuZXhwZWN0ZWRUb2tlbih0b2tlbik7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICAvLyBBbiBpZGVudGlmaWVyIGltbWVkaWF0ZWx5IGZvbGxvd2VkIGJ5IGEgY29tbWEgb3IgdGhlIGVuZCBvZlxuICAgICAgLy8gdGhlIGV4cHJlc3Npb24gY2Fubm90IGhhdmUgcGFyYW1ldGVycyBzbyB3ZSBjYW4gZXhpdCBlYXJseS5cbiAgICAgIGlmICh0aGlzLmlzRm9sbG93ZWRCeU9yTGFzdChjaGFycy4kQ09NTUEpKSB7XG4gICAgICAgIHRoaXMuY29uc3VtZVRyaWdnZXIodG9rZW4sIFtdKTtcbiAgICAgICAgdGhpcy5hZHZhbmNlKCk7XG4gICAgICB9IGVsc2UgaWYgKHRoaXMuaXNGb2xsb3dlZEJ5T3JMYXN0KGNoYXJzLiRMUEFSRU4pKSB7XG4gICAgICAgIHRoaXMuYWR2YW5jZSgpOyAgLy8gQWR2YW5jZSB0byB0aGUgb3BlbmluZyBwYXJlbi5cbiAgICAgICAgY29uc3QgcHJldkVycm9ycyA9IHRoaXMuZXJyb3JzLmxlbmd0aDtcbiAgICAgICAgY29uc3QgcGFyYW1ldGVycyA9IHRoaXMuY29uc3VtZVBhcmFtZXRlcnMoKTtcbiAgICAgICAgaWYgKHRoaXMuZXJyb3JzLmxlbmd0aCAhPT0gcHJldkVycm9ycykge1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuY29uc3VtZVRyaWdnZXIodG9rZW4sIHBhcmFtZXRlcnMpO1xuICAgICAgICB0aGlzLmFkdmFuY2UoKTsgIC8vIEFkdmFuY2UgcGFzdCB0aGUgY2xvc2luZyBwYXJlbi5cbiAgICAgIH0gZWxzZSBpZiAodGhpcy5pbmRleCA8IHRoaXMudG9rZW5zLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgdGhpcy51bmV4cGVjdGVkVG9rZW4odGhpcy50b2tlbnNbdGhpcy5pbmRleCArIDFdKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5hZHZhbmNlKCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMudHJpZ2dlcnM7XG4gIH1cblxuICBwcml2YXRlIGFkdmFuY2UoKSB7XG4gICAgdGhpcy5pbmRleCsrO1xuICB9XG5cbiAgcHJpdmF0ZSBpc0ZvbGxvd2VkQnlPckxhc3QoY2hhcjogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgaWYgKHRoaXMuaW5kZXggPT09IHRoaXMudG9rZW5zLmxlbmd0aCAtIDEpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLnRva2Vuc1t0aGlzLmluZGV4ICsgMV0uaXNDaGFyYWN0ZXIoY2hhcik7XG4gIH1cblxuICBwcml2YXRlIHRva2VuKCk6IFRva2VuIHtcbiAgICByZXR1cm4gdGhpcy50b2tlbnNbTWF0aC5taW4odGhpcy5pbmRleCwgdGhpcy50b2tlbnMubGVuZ3RoIC0gMSldO1xuICB9XG5cbiAgcHJpdmF0ZSBjb25zdW1lVHJpZ2dlcihpZGVudGlmaWVyOiBUb2tlbiwgcGFyYW1ldGVyczogc3RyaW5nW10pIHtcbiAgICBjb25zdCBzdGFydFNwYW4gPSB0aGlzLnNwYW4uc3RhcnQubW92ZUJ5KHRoaXMuc3RhcnQgKyBpZGVudGlmaWVyLmluZGV4IC0gdGhpcy50b2tlbnNbMF0uaW5kZXgpO1xuICAgIGNvbnN0IGVuZFNwYW4gPSBzdGFydFNwYW4ubW92ZUJ5KHRoaXMudG9rZW4oKS5lbmQgLSBpZGVudGlmaWVyLmluZGV4KTtcbiAgICBjb25zdCBzb3VyY2VTcGFuID0gbmV3IFBhcnNlU291cmNlU3BhbihzdGFydFNwYW4sIGVuZFNwYW4pO1xuXG4gICAgdHJ5IHtcbiAgICAgIHN3aXRjaCAoaWRlbnRpZmllci50b1N0cmluZygpKSB7XG4gICAgICAgIGNhc2UgT25UcmlnZ2VyVHlwZS5JRExFOlxuICAgICAgICAgIHRoaXMudHJpZ2dlcnMucHVzaChjcmVhdGVJZGxlVHJpZ2dlcihwYXJhbWV0ZXJzLCBzb3VyY2VTcGFuKSk7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSBPblRyaWdnZXJUeXBlLlRJTUVSOlxuICAgICAgICAgIHRoaXMudHJpZ2dlcnMucHVzaChjcmVhdGVUaW1lclRyaWdnZXIocGFyYW1ldGVycywgc291cmNlU3BhbikpO1xuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgT25UcmlnZ2VyVHlwZS5JTlRFUkFDVElPTjpcbiAgICAgICAgICB0aGlzLnRyaWdnZXJzLnB1c2goY3JlYXRlSW50ZXJhY3Rpb25UcmlnZ2VyKHBhcmFtZXRlcnMsIHNvdXJjZVNwYW4pKTtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIE9uVHJpZ2dlclR5cGUuSU1NRURJQVRFOlxuICAgICAgICAgIHRoaXMudHJpZ2dlcnMucHVzaChjcmVhdGVJbW1lZGlhdGVUcmlnZ2VyKHBhcmFtZXRlcnMsIHNvdXJjZVNwYW4pKTtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIE9uVHJpZ2dlclR5cGUuSE9WRVI6XG4gICAgICAgICAgdGhpcy50cmlnZ2Vycy5wdXNoKGNyZWF0ZUhvdmVyVHJpZ2dlcihwYXJhbWV0ZXJzLCBzb3VyY2VTcGFuKSk7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSBPblRyaWdnZXJUeXBlLlZJRVdQT1JUOlxuICAgICAgICAgIHRoaXMudHJpZ2dlcnMucHVzaChjcmVhdGVWaWV3cG9ydFRyaWdnZXIocGFyYW1ldGVycywgc291cmNlU3BhbikpO1xuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbnJlY29nbml6ZWQgdHJpZ2dlciB0eXBlIFwiJHtpZGVudGlmaWVyfVwiYCk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgdGhpcy5lcnJvcihpZGVudGlmaWVyLCAoZSBhcyBFcnJvcikubWVzc2FnZSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBjb25zdW1lUGFyYW1ldGVycygpOiBzdHJpbmdbXSB7XG4gICAgY29uc3QgcGFyYW1ldGVyczogc3RyaW5nW10gPSBbXTtcblxuICAgIGlmICghdGhpcy50b2tlbigpLmlzQ2hhcmFjdGVyKGNoYXJzLiRMUEFSRU4pKSB7XG4gICAgICB0aGlzLnVuZXhwZWN0ZWRUb2tlbih0aGlzLnRva2VuKCkpO1xuICAgICAgcmV0dXJuIHBhcmFtZXRlcnM7XG4gICAgfVxuXG4gICAgdGhpcy5hZHZhbmNlKCk7XG5cbiAgICBjb25zdCBjb21tYURlbGltU3RhY2s6IG51bWJlcltdID0gW107XG4gICAgbGV0IGN1cnJlbnQgPSAnJztcblxuICAgIHdoaWxlICh0aGlzLmluZGV4IDwgdGhpcy50b2tlbnMubGVuZ3RoKSB7XG4gICAgICBjb25zdCB0b2tlbiA9IHRoaXMudG9rZW4oKTtcblxuICAgICAgLy8gU3RvcCBwYXJzaW5nIGlmIHdlJ3ZlIGhpdCB0aGUgZW5kIGNoYXJhY3RlciBhbmQgd2UncmUgb3V0c2lkZSBvZiBhIGNvbW1hLWRlbGltaXRlZCBzeW50YXguXG4gICAgICAvLyBOb3RlIHRoYXQgd2UgZG9uJ3QgbmVlZCB0byBhY2NvdW50IGZvciBzdHJpbmdzIGhlcmUgc2luY2UgdGhlIGxleGVyIGFscmVhZHkgcGFyc2VkIHRoZW1cbiAgICAgIC8vIGludG8gc3RyaW5nIHRva2Vucy5cbiAgICAgIGlmICh0b2tlbi5pc0NoYXJhY3RlcihjaGFycy4kUlBBUkVOKSAmJiBjb21tYURlbGltU3RhY2subGVuZ3RoID09PSAwKSB7XG4gICAgICAgIGlmIChjdXJyZW50Lmxlbmd0aCkge1xuICAgICAgICAgIHBhcmFtZXRlcnMucHVzaChjdXJyZW50KTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgLy8gSW4gdGhlIGBvbmAgbWljcm9zeW50YXggXCJ0b3AtbGV2ZWxcIiBjb21tYXMgKGUuZy4gb25lcyBvdXRzaWRlIG9mIGFuIHBhcmFtZXRlcnMpIHNlcGFyYXRlXG4gICAgICAvLyB0aGUgZGlmZmVyZW50IHRyaWdnZXJzIChlLmcuIGBvbiBpZGxlLHRpbWVyKDUwMClgKS4gVGhpcyBpcyBwcm9ibGVtYXRpYywgYmVjYXVzZSB0aGVcbiAgICAgIC8vIGZ1bmN0aW9uLWxpa2Ugc3ludGF4IGFsc28gaW1wbGllcyB0aGF0IG11bHRpcGxlIHBhcmFtZXRlcnMgY2FuIGJlIHBhc3NlZCBpbnRvIHRoZVxuICAgICAgLy8gaW5kaXZpZHVhbCB0cmlnZ2VyIChlLmcuIGBvbiBmb28oYSwgYilgKS4gVG8gYXZvaWQgdHJpcHBpbmcgdXAgdGhlIHBhcnNlciB3aXRoIGNvbW1hcyB0aGF0XG4gICAgICAvLyBhcmUgcGFydCBvZiBvdGhlciBzb3J0cyBvZiBzeW50YXggKG9iamVjdCBsaXRlcmFscywgYXJyYXlzKSwgd2UgdHJlYXQgYW55dGhpbmcgaW5zaWRlXG4gICAgICAvLyBhIGNvbW1hLWRlbGltaXRlZCBzeW50YXggYmxvY2sgYXMgcGxhaW4gdGV4dC5cbiAgICAgIGlmICh0b2tlbi50eXBlID09PSBUb2tlblR5cGUuQ2hhcmFjdGVyICYmIENPTU1BX0RFTElNSVRFRF9TWU5UQVguaGFzKHRva2VuLm51bVZhbHVlKSkge1xuICAgICAgICBjb21tYURlbGltU3RhY2sucHVzaChDT01NQV9ERUxJTUlURURfU1lOVEFYLmdldCh0b2tlbi5udW1WYWx1ZSkhKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGNvbW1hRGVsaW1TdGFjay5sZW5ndGggPiAwICYmXG4gICAgICAgICAgdG9rZW4uaXNDaGFyYWN0ZXIoY29tbWFEZWxpbVN0YWNrW2NvbW1hRGVsaW1TdGFjay5sZW5ndGggLSAxXSkpIHtcbiAgICAgICAgY29tbWFEZWxpbVN0YWNrLnBvcCgpO1xuICAgICAgfVxuXG4gICAgICAvLyBJZiB3ZSBoaXQgYSBjb21tYSBvdXRzaWRlIG9mIGEgY29tbWEtZGVsaW1pdGVkIHN5bnRheCwgaXQgbWVhbnNcbiAgICAgIC8vIHRoYXQgd2UncmUgYXQgdGhlIHRvcCBsZXZlbCBhbmQgd2UncmUgc3RhcnRpbmcgYSBuZXcgcGFyYW1ldGVyLlxuICAgICAgaWYgKGNvbW1hRGVsaW1TdGFjay5sZW5ndGggPT09IDAgJiYgdG9rZW4uaXNDaGFyYWN0ZXIoY2hhcnMuJENPTU1BKSAmJiBjdXJyZW50Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgcGFyYW1ldGVycy5wdXNoKGN1cnJlbnQpO1xuICAgICAgICBjdXJyZW50ID0gJyc7XG4gICAgICAgIHRoaXMuYWR2YW5jZSgpO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgLy8gT3RoZXJ3aXNlIHRyZWF0IHRoZSB0b2tlbiBhcyBhIHBsYWluIHRleHQgY2hhcmFjdGVyIGluIHRoZSBjdXJyZW50IHBhcmFtZXRlci5cbiAgICAgIGN1cnJlbnQgKz0gdGhpcy50b2tlblRleHQoKTtcbiAgICAgIHRoaXMuYWR2YW5jZSgpO1xuICAgIH1cblxuICAgIGlmICghdGhpcy50b2tlbigpLmlzQ2hhcmFjdGVyKGNoYXJzLiRSUEFSRU4pIHx8IGNvbW1hRGVsaW1TdGFjay5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLmVycm9yKHRoaXMudG9rZW4oKSwgJ1VuZXhwZWN0ZWQgZW5kIG9mIGV4cHJlc3Npb24nKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5pbmRleCA8IHRoaXMudG9rZW5zLmxlbmd0aCAtIDEgJiZcbiAgICAgICAgIXRoaXMudG9rZW5zW3RoaXMuaW5kZXggKyAxXS5pc0NoYXJhY3RlcihjaGFycy4kQ09NTUEpKSB7XG4gICAgICB0aGlzLnVuZXhwZWN0ZWRUb2tlbih0aGlzLnRva2Vuc1t0aGlzLmluZGV4ICsgMV0pO1xuICAgIH1cblxuICAgIHJldHVybiBwYXJhbWV0ZXJzO1xuICB9XG5cbiAgcHJpdmF0ZSB0b2tlblRleHQoKTogc3RyaW5nIHtcbiAgICAvLyBUb2tlbnMgaGF2ZSBhIHRvU3RyaW5nIGFscmVhZHkgd2hpY2ggd2UgY291bGQgdXNlLCBidXQgZm9yIHN0cmluZyB0b2tlbnMgaXQgb21pdHMgdGhlIHF1b3Rlcy5cbiAgICAvLyBFdmVudHVhbGx5IHdlIGNvdWxkIGV4cG9zZSB0aGlzIGluZm9ybWF0aW9uIG9uIHRoZSB0b2tlbiBkaXJlY3RseS5cbiAgICByZXR1cm4gdGhpcy5leHByZXNzaW9uLnNsaWNlKHRoaXMuc3RhcnQgKyB0aGlzLnRva2VuKCkuaW5kZXgsIHRoaXMuc3RhcnQgKyB0aGlzLnRva2VuKCkuZW5kKTtcbiAgfVxuXG4gIHByaXZhdGUgZXJyb3IodG9rZW46IFRva2VuLCBtZXNzYWdlOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBuZXdTdGFydCA9IHRoaXMuc3Bhbi5zdGFydC5tb3ZlQnkodGhpcy5zdGFydCArIHRva2VuLmluZGV4KTtcbiAgICBjb25zdCBuZXdFbmQgPSBuZXdTdGFydC5tb3ZlQnkodG9rZW4uZW5kIC0gdG9rZW4uaW5kZXgpO1xuICAgIHRoaXMuZXJyb3JzLnB1c2gobmV3IFBhcnNlRXJyb3IobmV3IFBhcnNlU291cmNlU3BhbihuZXdTdGFydCwgbmV3RW5kKSwgbWVzc2FnZSkpO1xuICB9XG5cbiAgcHJpdmF0ZSB1bmV4cGVjdGVkVG9rZW4odG9rZW46IFRva2VuKSB7XG4gICAgdGhpcy5lcnJvcih0b2tlbiwgYFVuZXhwZWN0ZWQgdG9rZW4gXCIke3Rva2VufVwiYCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gY3JlYXRlSWRsZVRyaWdnZXIoXG4gICAgcGFyYW1ldGVyczogc3RyaW5nW10sIHNvdXJjZVNwYW46IFBhcnNlU291cmNlU3Bhbik6IHQuSWRsZURlZmVycmVkVHJpZ2dlciB7XG4gIGlmIChwYXJhbWV0ZXJzLmxlbmd0aCA+IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYFwiJHtPblRyaWdnZXJUeXBlLklETEV9XCIgdHJpZ2dlciBjYW5ub3QgaGF2ZSBwYXJhbWV0ZXJzYCk7XG4gIH1cblxuICByZXR1cm4gbmV3IHQuSWRsZURlZmVycmVkVHJpZ2dlcihzb3VyY2VTcGFuKTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlVGltZXJUcmlnZ2VyKHBhcmFtZXRlcnM6IHN0cmluZ1tdLCBzb3VyY2VTcGFuOiBQYXJzZVNvdXJjZVNwYW4pIHtcbiAgaWYgKHBhcmFtZXRlcnMubGVuZ3RoICE9PSAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBcIiR7T25UcmlnZ2VyVHlwZS5USU1FUn1cIiB0cmlnZ2VyIG11c3QgaGF2ZSBleGFjdGx5IG9uZSBwYXJhbWV0ZXJgKTtcbiAgfVxuXG4gIGNvbnN0IGRlbGF5ID0gcGFyc2VEZWZlcnJlZFRpbWUocGFyYW1ldGVyc1swXSk7XG5cbiAgaWYgKGRlbGF5ID09PSBudWxsKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBDb3VsZCBub3QgcGFyc2UgdGltZSB2YWx1ZSBvZiB0cmlnZ2VyIFwiJHtPblRyaWdnZXJUeXBlLlRJTUVSfVwiYCk7XG4gIH1cblxuICByZXR1cm4gbmV3IHQuVGltZXJEZWZlcnJlZFRyaWdnZXIoZGVsYXksIHNvdXJjZVNwYW4pO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVJbnRlcmFjdGlvblRyaWdnZXIoXG4gICAgcGFyYW1ldGVyczogc3RyaW5nW10sIHNvdXJjZVNwYW46IFBhcnNlU291cmNlU3Bhbik6IHQuSW50ZXJhY3Rpb25EZWZlcnJlZFRyaWdnZXIge1xuICBpZiAocGFyYW1ldGVycy5sZW5ndGggPiAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBcIiR7T25UcmlnZ2VyVHlwZS5JTlRFUkFDVElPTn1cIiB0cmlnZ2VyIGNhbiBvbmx5IGhhdmUgemVybyBvciBvbmUgcGFyYW1ldGVyc2ApO1xuICB9XG5cbiAgcmV0dXJuIG5ldyB0LkludGVyYWN0aW9uRGVmZXJyZWRUcmlnZ2VyKHBhcmFtZXRlcnNbMF0gPz8gbnVsbCwgc291cmNlU3Bhbik7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUltbWVkaWF0ZVRyaWdnZXIoXG4gICAgcGFyYW1ldGVyczogc3RyaW5nW10sIHNvdXJjZVNwYW46IFBhcnNlU291cmNlU3Bhbik6IHQuSW1tZWRpYXRlRGVmZXJyZWRUcmlnZ2VyIHtcbiAgaWYgKHBhcmFtZXRlcnMubGVuZ3RoID4gMCkge1xuICAgIHRocm93IG5ldyBFcnJvcihgXCIke09uVHJpZ2dlclR5cGUuSU1NRURJQVRFfVwiIHRyaWdnZXIgY2Fubm90IGhhdmUgcGFyYW1ldGVyc2ApO1xuICB9XG5cbiAgcmV0dXJuIG5ldyB0LkltbWVkaWF0ZURlZmVycmVkVHJpZ2dlcihzb3VyY2VTcGFuKTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlSG92ZXJUcmlnZ2VyKFxuICAgIHBhcmFtZXRlcnM6IHN0cmluZ1tdLCBzb3VyY2VTcGFuOiBQYXJzZVNvdXJjZVNwYW4pOiB0LkhvdmVyRGVmZXJyZWRUcmlnZ2VyIHtcbiAgaWYgKHBhcmFtZXRlcnMubGVuZ3RoID4gMCkge1xuICAgIHRocm93IG5ldyBFcnJvcihgXCIke09uVHJpZ2dlclR5cGUuSE9WRVJ9XCIgdHJpZ2dlciBjYW5ub3QgaGF2ZSBwYXJhbWV0ZXJzYCk7XG4gIH1cblxuICByZXR1cm4gbmV3IHQuSG92ZXJEZWZlcnJlZFRyaWdnZXIoc291cmNlU3Bhbik7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZVZpZXdwb3J0VHJpZ2dlcihcbiAgICBwYXJhbWV0ZXJzOiBzdHJpbmdbXSwgc291cmNlU3BhbjogUGFyc2VTb3VyY2VTcGFuKTogdC5WaWV3cG9ydERlZmVycmVkVHJpZ2dlciB7XG4gIC8vIFRPRE86IHRoZSBSRkMgaGFzIHNvbWUgbW9yZSBwb3RlbnRpYWwgcGFyYW1ldGVycyBmb3IgYHZpZXdwb3J0YC5cbiAgaWYgKHBhcmFtZXRlcnMubGVuZ3RoID4gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgXCIke09uVHJpZ2dlclR5cGUuVklFV1BPUlR9XCIgdHJpZ2dlciBjYW4gb25seSBoYXZlIHplcm8gb3Igb25lIHBhcmFtZXRlcnNgKTtcbiAgfVxuXG4gIHJldHVybiBuZXcgdC5WaWV3cG9ydERlZmVycmVkVHJpZ2dlcihwYXJhbWV0ZXJzWzBdID8/IG51bGwsIHNvdXJjZVNwYW4pO1xufVxuXG4vKiogR2V0cyB0aGUgaW5kZXggd2l0aGluIGFuIGV4cHJlc3Npb24gYXQgd2hpY2ggdGhlIHRyaWdnZXIgcGFyYW1ldGVycyBzdGFydC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRUcmlnZ2VyUGFyYW1ldGVyc1N0YXJ0KHZhbHVlOiBzdHJpbmcsIHN0YXJ0UG9zaXRpb24gPSAwKTogbnVtYmVyIHtcbiAgbGV0IGhhc0ZvdW5kU2VwYXJhdG9yID0gZmFsc2U7XG5cbiAgZm9yIChsZXQgaSA9IHN0YXJ0UG9zaXRpb247IGkgPCB2YWx1ZS5sZW5ndGg7IGkrKykge1xuICAgIGlmIChTRVBBUkFUT1JfUEFUVEVSTi50ZXN0KHZhbHVlW2ldKSkge1xuICAgICAgaGFzRm91bmRTZXBhcmF0b3IgPSB0cnVlO1xuICAgIH0gZWxzZSBpZiAoaGFzRm91bmRTZXBhcmF0b3IpIHtcbiAgICAgIHJldHVybiBpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiAtMTtcbn1cblxuLyoqXG4gKiBQYXJzZXMgYSB0aW1lIGV4cHJlc3Npb24gZnJvbSBhIGRlZmVycmVkIHRyaWdnZXIgdG9cbiAqIG1pbGxpc2Vjb25kcy4gUmV0dXJucyBudWxsIGlmIGl0IGNhbm5vdCBiZSBwYXJzZWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZURlZmVycmVkVGltZSh2YWx1ZTogc3RyaW5nKTogbnVtYmVyfG51bGwge1xuICBjb25zdCBtYXRjaCA9IHZhbHVlLm1hdGNoKFRJTUVfUEFUVEVSTik7XG5cbiAgaWYgKCFtYXRjaCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgY29uc3QgW3RpbWUsIHVuaXRzXSA9IG1hdGNoO1xuICByZXR1cm4gcGFyc2VJbnQodGltZSkgKiAodW5pdHMgPT09ICdzJyA/IDEwMDAgOiAxKTtcbn1cbiJdfQ==