package.esm2022.browser.src.dsl.animation_ast_builder.mjs Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of animations Show documentation
Show all versions of animations Show documentation
Angular - animations integration with web-animations
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import { AnimationMetadataType, AUTO_STYLE, style, } from '@angular/animations';
import { invalidDefinition, invalidKeyframes, invalidOffset, invalidParallelAnimation, invalidStagger, invalidState, invalidStyleValue, invalidTrigger, keyframeOffsetsOutOfOrder, keyframesMissingOffsets, } from '../error_helpers';
import { getOrSetDefaultValue } from '../render/shared';
import { extractStyleParams, NG_ANIMATING_SELECTOR, NG_TRIGGER_SELECTOR, normalizeAnimationEntry, resolveTiming, SUBSTITUTION_EXPR_START, validateStyleParams, visitDslNode, } from '../util';
import { pushUnrecognizedPropertiesWarning } from '../warning_helpers';
import { parseTransitionExpr } from './animation_transition_expr';
const SELF_TOKEN = ':self';
const SELF_TOKEN_REGEX = new RegExp(`s*${SELF_TOKEN}s*,?`, 'g');
/*
* [Validation]
* The visitor code below will traverse the animation AST generated by the animation verb functions
* (the output is a tree of objects) and attempt to perform a series of validations on the data. The
* following corner-cases will be validated:
*
* 1. Overlap of animations
* Given that a CSS property cannot be animated in more than one place at the same time, it's
* important that this behavior is detected and validated. The way in which this occurs is that
* each time a style property is examined, a string-map containing the property will be updated with
* the start and end times for when the property is used within an animation step.
*
* If there are two or more parallel animations that are currently running (these are invoked by the
* group()) on the same element then the validator will throw an error. Since the start/end timing
* values are collected for each property then if the current animation step is animating the same
* property and its timing values fall anywhere into the window of time that the property is
* currently being animated within then this is what causes an error.
*
* 2. Timing values
* The validator will validate to see if a timing value of `duration delay easing` or
* `durationNumber` is valid or not.
*
* (note that upon validation the code below will replace the timing data with an object containing
* {duration,delay,easing}.
*
* 3. Offset Validation
* Each of the style() calls are allowed to have an offset value when placed inside of keyframes().
* Offsets within keyframes() are considered valid when:
*
* - No offsets are used at all
* - Each style() entry contains an offset value
* - Each offset is between 0 and 1
* - Each offset is greater to or equal than the previous one
*
* Otherwise an error will be thrown.
*/
export function buildAnimationAst(driver, metadata, errors, warnings) {
return new AnimationAstBuilderVisitor(driver).build(metadata, errors, warnings);
}
const ROOT_SELECTOR = '';
export class AnimationAstBuilderVisitor {
constructor(_driver) {
this._driver = _driver;
}
build(metadata, errors, warnings) {
const context = new AnimationAstBuilderContext(errors);
this._resetContextStyleTimingState(context);
const ast = (visitDslNode(this, normalizeAnimationEntry(metadata), context));
if (typeof ngDevMode === 'undefined' || ngDevMode) {
if (context.unsupportedCSSPropertiesFound.size) {
pushUnrecognizedPropertiesWarning(warnings, [
...context.unsupportedCSSPropertiesFound.keys(),
]);
}
}
return ast;
}
_resetContextStyleTimingState(context) {
context.currentQuerySelector = ROOT_SELECTOR;
context.collectedStyles = new Map();
context.collectedStyles.set(ROOT_SELECTOR, new Map());
context.currentTime = 0;
}
visitTrigger(metadata, context) {
let queryCount = (context.queryCount = 0);
let depCount = (context.depCount = 0);
const states = [];
const transitions = [];
if (metadata.name.charAt(0) == '@') {
context.errors.push(invalidTrigger());
}
metadata.definitions.forEach((def) => {
this._resetContextStyleTimingState(context);
if (def.type == AnimationMetadataType.State) {
const stateDef = def;
const name = stateDef.name;
name
.toString()
.split(/\s*,\s*/)
.forEach((n) => {
stateDef.name = n;
states.push(this.visitState(stateDef, context));
});
stateDef.name = name;
}
else if (def.type == AnimationMetadataType.Transition) {
const transition = this.visitTransition(def, context);
queryCount += transition.queryCount;
depCount += transition.depCount;
transitions.push(transition);
}
else {
context.errors.push(invalidDefinition());
}
});
return {
type: AnimationMetadataType.Trigger,
name: metadata.name,
states,
transitions,
queryCount,
depCount,
options: null,
};
}
visitState(metadata, context) {
const styleAst = this.visitStyle(metadata.styles, context);
const astParams = (metadata.options && metadata.options.params) || null;
if (styleAst.containsDynamicStyles) {
const missingSubs = new Set();
const params = astParams || {};
styleAst.styles.forEach((style) => {
if (style instanceof Map) {
style.forEach((value) => {
extractStyleParams(value).forEach((sub) => {
if (!params.hasOwnProperty(sub)) {
missingSubs.add(sub);
}
});
});
}
});
if (missingSubs.size) {
context.errors.push(invalidState(metadata.name, [...missingSubs.values()]));
}
}
return {
type: AnimationMetadataType.State,
name: metadata.name,
style: styleAst,
options: astParams ? { params: astParams } : null,
};
}
visitTransition(metadata, context) {
context.queryCount = 0;
context.depCount = 0;
const animation = visitDslNode(this, normalizeAnimationEntry(metadata.animation), context);
const matchers = parseTransitionExpr(metadata.expr, context.errors);
return {
type: AnimationMetadataType.Transition,
matchers,
animation,
queryCount: context.queryCount,
depCount: context.depCount,
options: normalizeAnimationOptions(metadata.options),
};
}
visitSequence(metadata, context) {
return {
type: AnimationMetadataType.Sequence,
steps: metadata.steps.map((s) => visitDslNode(this, s, context)),
options: normalizeAnimationOptions(metadata.options),
};
}
visitGroup(metadata, context) {
const currentTime = context.currentTime;
let furthestTime = 0;
const steps = metadata.steps.map((step) => {
context.currentTime = currentTime;
const innerAst = visitDslNode(this, step, context);
furthestTime = Math.max(furthestTime, context.currentTime);
return innerAst;
});
context.currentTime = furthestTime;
return {
type: AnimationMetadataType.Group,
steps,
options: normalizeAnimationOptions(metadata.options),
};
}
visitAnimate(metadata, context) {
const timingAst = constructTimingAst(metadata.timings, context.errors);
context.currentAnimateTimings = timingAst;
let styleAst;
let styleMetadata = metadata.styles
? metadata.styles
: style({});
if (styleMetadata.type == AnimationMetadataType.Keyframes) {
styleAst = this.visitKeyframes(styleMetadata, context);
}
else {
let styleMetadata = metadata.styles;
let isEmpty = false;
if (!styleMetadata) {
isEmpty = true;
const newStyleData = {};
if (timingAst.easing) {
newStyleData['easing'] = timingAst.easing;
}
styleMetadata = style(newStyleData);
}
context.currentTime += timingAst.duration + timingAst.delay;
const _styleAst = this.visitStyle(styleMetadata, context);
_styleAst.isEmptyStep = isEmpty;
styleAst = _styleAst;
}
context.currentAnimateTimings = null;
return {
type: AnimationMetadataType.Animate,
timings: timingAst,
style: styleAst,
options: null,
};
}
visitStyle(metadata, context) {
const ast = this._makeStyleAst(metadata, context);
this._validateStyleAst(ast, context);
return ast;
}
_makeStyleAst(metadata, context) {
const styles = [];
const metadataStyles = Array.isArray(metadata.styles) ? metadata.styles : [metadata.styles];
for (let styleTuple of metadataStyles) {
if (typeof styleTuple === 'string') {
if (styleTuple === AUTO_STYLE) {
styles.push(styleTuple);
}
else {
context.errors.push(invalidStyleValue(styleTuple));
}
}
else {
styles.push(new Map(Object.entries(styleTuple)));
}
}
let containsDynamicStyles = false;
let collectedEasing = null;
styles.forEach((styleData) => {
if (styleData instanceof Map) {
if (styleData.has('easing')) {
collectedEasing = styleData.get('easing');
styleData.delete('easing');
}
if (!containsDynamicStyles) {
for (let value of styleData.values()) {
if (value.toString().indexOf(SUBSTITUTION_EXPR_START) >= 0) {
containsDynamicStyles = true;
break;
}
}
}
}
});
return {
type: AnimationMetadataType.Style,
styles,
easing: collectedEasing,
offset: metadata.offset,
containsDynamicStyles,
options: null,
};
}
_validateStyleAst(ast, context) {
const timings = context.currentAnimateTimings;
let endTime = context.currentTime;
let startTime = context.currentTime;
if (timings && startTime > 0) {
startTime -= timings.duration + timings.delay;
}
ast.styles.forEach((tuple) => {
if (typeof tuple === 'string')
return;
tuple.forEach((value, prop) => {
if (typeof ngDevMode === 'undefined' || ngDevMode) {
if (!this._driver.validateStyleProperty(prop)) {
tuple.delete(prop);
context.unsupportedCSSPropertiesFound.add(prop);
return;
}
}
// This is guaranteed to have a defined Map at this querySelector location making it
// safe to add the assertion here. It is set as a default empty map in prior methods.
const collectedStyles = context.collectedStyles.get(context.currentQuerySelector);
const collectedEntry = collectedStyles.get(prop);
let updateCollectedStyle = true;
if (collectedEntry) {
if (startTime != endTime &&
startTime >= collectedEntry.startTime &&
endTime <= collectedEntry.endTime) {
context.errors.push(invalidParallelAnimation(prop, collectedEntry.startTime, collectedEntry.endTime, startTime, endTime));
updateCollectedStyle = false;
}
// we always choose the smaller start time value since we
// want to have a record of the entire animation window where
// the style property is being animated in between
startTime = collectedEntry.startTime;
}
if (updateCollectedStyle) {
collectedStyles.set(prop, { startTime, endTime });
}
if (context.options) {
validateStyleParams(value, context.options, context.errors);
}
});
});
}
visitKeyframes(metadata, context) {
const ast = { type: AnimationMetadataType.Keyframes, styles: [], options: null };
if (!context.currentAnimateTimings) {
context.errors.push(invalidKeyframes());
return ast;
}
const MAX_KEYFRAME_OFFSET = 1;
let totalKeyframesWithOffsets = 0;
const offsets = [];
let offsetsOutOfOrder = false;
let keyframesOutOfRange = false;
let previousOffset = 0;
const keyframes = metadata.steps.map((styles) => {
const style = this._makeStyleAst(styles, context);
let offsetVal = style.offset != null ? style.offset : consumeOffset(style.styles);
let offset = 0;
if (offsetVal != null) {
totalKeyframesWithOffsets++;
offset = style.offset = offsetVal;
}
keyframesOutOfRange = keyframesOutOfRange || offset < 0 || offset > 1;
offsetsOutOfOrder = offsetsOutOfOrder || offset < previousOffset;
previousOffset = offset;
offsets.push(offset);
return style;
});
if (keyframesOutOfRange) {
context.errors.push(invalidOffset());
}
if (offsetsOutOfOrder) {
context.errors.push(keyframeOffsetsOutOfOrder());
}
const length = metadata.steps.length;
let generatedOffset = 0;
if (totalKeyframesWithOffsets > 0 && totalKeyframesWithOffsets < length) {
context.errors.push(keyframesMissingOffsets());
}
else if (totalKeyframesWithOffsets == 0) {
generatedOffset = MAX_KEYFRAME_OFFSET / (length - 1);
}
const limit = length - 1;
const currentTime = context.currentTime;
const currentAnimateTimings = context.currentAnimateTimings;
const animateDuration = currentAnimateTimings.duration;
keyframes.forEach((kf, i) => {
const offset = generatedOffset > 0 ? (i == limit ? 1 : generatedOffset * i) : offsets[i];
const durationUpToThisFrame = offset * animateDuration;
context.currentTime = currentTime + currentAnimateTimings.delay + durationUpToThisFrame;
currentAnimateTimings.duration = durationUpToThisFrame;
this._validateStyleAst(kf, context);
kf.offset = offset;
ast.styles.push(kf);
});
return ast;
}
visitReference(metadata, context) {
return {
type: AnimationMetadataType.Reference,
animation: visitDslNode(this, normalizeAnimationEntry(metadata.animation), context),
options: normalizeAnimationOptions(metadata.options),
};
}
visitAnimateChild(metadata, context) {
context.depCount++;
return {
type: AnimationMetadataType.AnimateChild,
options: normalizeAnimationOptions(metadata.options),
};
}
visitAnimateRef(metadata, context) {
return {
type: AnimationMetadataType.AnimateRef,
animation: this.visitReference(metadata.animation, context),
options: normalizeAnimationOptions(metadata.options),
};
}
visitQuery(metadata, context) {
const parentSelector = context.currentQuerySelector;
const options = (metadata.options || {});
context.queryCount++;
context.currentQuery = metadata;
const [selector, includeSelf] = normalizeSelector(metadata.selector);
context.currentQuerySelector = parentSelector.length
? parentSelector + ' ' + selector
: selector;
getOrSetDefaultValue(context.collectedStyles, context.currentQuerySelector, new Map());
const animation = visitDslNode(this, normalizeAnimationEntry(metadata.animation), context);
context.currentQuery = null;
context.currentQuerySelector = parentSelector;
return {
type: AnimationMetadataType.Query,
selector,
limit: options.limit || 0,
optional: !!options.optional,
includeSelf,
animation,
originalSelector: metadata.selector,
options: normalizeAnimationOptions(metadata.options),
};
}
visitStagger(metadata, context) {
if (!context.currentQuery) {
context.errors.push(invalidStagger());
}
const timings = metadata.timings === 'full'
? { duration: 0, delay: 0, easing: 'full' }
: resolveTiming(metadata.timings, context.errors, true);
return {
type: AnimationMetadataType.Stagger,
animation: visitDslNode(this, normalizeAnimationEntry(metadata.animation), context),
timings,
options: null,
};
}
}
function normalizeSelector(selector) {
const hasAmpersand = selector.split(/\s*,\s*/).find((token) => token == SELF_TOKEN)
? true
: false;
if (hasAmpersand) {
selector = selector.replace(SELF_TOKEN_REGEX, '');
}
// Note: the :enter and :leave aren't normalized here since those
// selectors are filled in at runtime during timeline building
selector = selector
.replace(/@\*/g, NG_TRIGGER_SELECTOR)
.replace(/@\w+/g, (match) => NG_TRIGGER_SELECTOR + '-' + match.slice(1))
.replace(/:animating/g, NG_ANIMATING_SELECTOR);
return [selector, hasAmpersand];
}
function normalizeParams(obj) {
return obj ? { ...obj } : null;
}
export class AnimationAstBuilderContext {
constructor(errors) {
this.errors = errors;
this.queryCount = 0;
this.depCount = 0;
this.currentTransition = null;
this.currentQuery = null;
this.currentQuerySelector = null;
this.currentAnimateTimings = null;
this.currentTime = 0;
this.collectedStyles = new Map();
this.options = null;
this.unsupportedCSSPropertiesFound = new Set();
}
}
function consumeOffset(styles) {
if (typeof styles == 'string')
return null;
let offset = null;
if (Array.isArray(styles)) {
styles.forEach((styleTuple) => {
if (styleTuple instanceof Map && styleTuple.has('offset')) {
const obj = styleTuple;
offset = parseFloat(obj.get('offset'));
obj.delete('offset');
}
});
}
else if (styles instanceof Map && styles.has('offset')) {
const obj = styles;
offset = parseFloat(obj.get('offset'));
obj.delete('offset');
}
return offset;
}
function constructTimingAst(value, errors) {
if (value.hasOwnProperty('duration')) {
return value;
}
if (typeof value == 'number') {
const duration = resolveTiming(value, errors).duration;
return makeTimingAst(duration, 0, '');
}
const strValue = value;
const isDynamic = strValue.split(/\s+/).some((v) => v.charAt(0) == '{' && v.charAt(1) == '{');
if (isDynamic) {
const ast = makeTimingAst(0, 0, '');
ast.dynamic = true;
ast.strValue = strValue;
return ast;
}
const timings = resolveTiming(strValue, errors);
return makeTimingAst(timings.duration, timings.delay, timings.easing);
}
function normalizeAnimationOptions(options) {
if (options) {
options = { ...options };
if (options['params']) {
options['params'] = normalizeParams(options['params']);
}
}
else {
options = {};
}
return options;
}
function makeTimingAst(duration, delay, easing) {
return { duration, delay, easing };
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYW5pbWF0aW9uX2FzdF9idWlsZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvYW5pbWF0aW9ucy9icm93c2VyL3NyYy9kc2wvYW5pbWF0aW9uX2FzdF9idWlsZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7R0FNRztBQUNILE9BQU8sRUFRTCxxQkFBcUIsRUFXckIsVUFBVSxFQUNWLEtBQUssR0FFTixNQUFNLHFCQUFxQixDQUFDO0FBRTdCLE9BQU8sRUFDTCxpQkFBaUIsRUFDakIsZ0JBQWdCLEVBQ2hCLGFBQWEsRUFDYix3QkFBd0IsRUFFeEIsY0FBYyxFQUNkLFlBQVksRUFDWixpQkFBaUIsRUFDakIsY0FBYyxFQUNkLHlCQUF5QixFQUN6Qix1QkFBdUIsR0FDeEIsTUFBTSxrQkFBa0IsQ0FBQztBQUUxQixPQUFPLEVBQUMsb0JBQW9CLEVBQUMsTUFBTSxrQkFBa0IsQ0FBQztBQUN0RCxPQUFPLEVBQ0wsa0JBQWtCLEVBQ2xCLHFCQUFxQixFQUNyQixtQkFBbUIsRUFDbkIsdUJBQXVCLEVBQ3ZCLGFBQWEsRUFDYix1QkFBdUIsRUFDdkIsbUJBQW1CLEVBQ25CLFlBQVksR0FDYixNQUFNLFNBQVMsQ0FBQztBQUNqQixPQUFPLEVBQUMsaUNBQWlDLEVBQUMsTUFBTSxvQkFBb0IsQ0FBQztBQXFCckUsT0FBTyxFQUFDLG1CQUFtQixFQUFDLE1BQU0sNkJBQTZCLENBQUM7QUFFaEUsTUFBTSxVQUFVLEdBQUcsT0FBTyxDQUFDO0FBQzNCLE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxNQUFNLENBQUMsS0FBSyxVQUFVLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQztBQUVoRTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FtQ0c7QUFDSCxNQUFNLFVBQVUsaUJBQWlCLENBQy9CLE1BQXVCLEVBQ3ZCLFFBQWlELEVBQ2pELE1BQWUsRUFDZixRQUFrQjtJ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QyxDQUFDO0FBQ25DLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgR29vZ2xlIExMQyBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vYW5ndWxhci5pby9saWNlbnNlXG4gKi9cbmltcG9ydCB7XG4gIEFuaW1hdGVUaW1pbmdzLFxuICBBbmltYXRpb25BbmltYXRlQ2hpbGRNZXRhZGF0YSxcbiAgQW5pbWF0aW9uQW5pbWF0ZU1ldGFkYXRhLFxuICBBbmltYXRpb25BbmltYXRlUmVmTWV0YWRhdGEsXG4gIEFuaW1hdGlvbkdyb3VwTWV0YWRhdGEsXG4gIEFuaW1hdGlvbktleWZyYW1lc1NlcXVlbmNlTWV0YWRhdGEsXG4gIEFuaW1hdGlvbk1ldGFkYXRhLFxuICBBbmltYXRpb25NZXRhZGF0YVR5cGUsXG4gIEFuaW1hdGlvbk9wdGlvbnMsXG4gIEFuaW1hdGlvblF1ZXJ5TWV0YWRhdGEsXG4gIEFuaW1hdGlvblF1ZXJ5T3B0aW9ucyxcbiAgQW5pbWF0aW9uUmVmZXJlbmNlTWV0YWRhdGEsXG4gIEFuaW1hdGlvblNlcXVlbmNlTWV0YWRhdGEsXG4gIEFuaW1hdGlvblN0YWdnZXJNZXRhZGF0YSxcbiAgQW5pbWF0aW9uU3RhdGVNZXRhZGF0YSxcbiAgQW5pbWF0aW9uU3R5bGVNZXRhZGF0YSxcbiAgQW5pbWF0aW9uVHJhbnNpdGlvbk1ldGFkYXRhLFxuICBBbmltYXRpb25UcmlnZ2VyTWV0YWRhdGEsXG4gIEFVVE9fU1RZTEUsXG4gIHN0eWxlLFxuICDJtVN0eWxlRGF0YU1hcCxcbn0gZnJvbSAnQGFuZ3VsYXIvYW5pbWF0aW9ucyc7XG5cbmltcG9ydCB7XG4gIGludmFsaWREZWZpbml0aW9uLFxuICBpbnZhbGlkS2V5ZnJhbWVzLFxuICBpbnZhbGlkT2Zmc2V0LFxuICBpbnZhbGlkUGFyYWxsZWxBbmltYXRpb24sXG4gIGludmFsaWRQcm9wZXJ0eSxcbiAgaW52YWxpZFN0YWdnZXIsXG4gIGludmFsaWRTdGF0ZSxcbiAgaW52YWxpZFN0eWxlVmFsdWUsXG4gIGludmFsaWRUcmlnZ2VyLFxuICBrZXlmcmFtZU9mZnNldHNPdXRPZk9yZGVyLFxuICBrZXlmcmFtZXNNaXNzaW5nT2Zmc2V0cyxcbn0gZnJvbSAnLi4vZXJyb3JfaGVscGVycyc7XG5pbXBvcnQge0FuaW1hdGlvbkRyaXZlcn0gZnJvbSAnLi4vcmVuZGVyL2FuaW1hdGlvbl9kcml2ZXInO1xuaW1wb3J0IHtnZXRPclNldERlZmF1bHRWYWx1ZX0gZnJvbSAnLi4vcmVuZGVyL3NoYXJlZCc7XG5pbXBvcnQge1xuICBleHRyYWN0U3R5bGVQYXJhbXMsXG4gIE5HX0FOSU1BVElOR19TRUxFQ1RPUixcbiAgTkdfVFJJR0dFUl9TRUxFQ1RPUixcbiAgbm9ybWFsaXplQW5pbWF0aW9uRW50cnksXG4gIHJlc29sdmVUaW1pbmcsXG4gIFNVQlNUSVRVVElPTl9FWFBSX1NUQVJULFxuICB2YWxpZGF0ZVN0eWxlUGFyYW1zLFxuICB2aXNpdERzbE5vZGUsXG59IGZyb20gJy4uL3V0aWwnO1xuaW1wb3J0IHtwdXNoVW5yZWNvZ25pemVkUHJvcGVydGllc1dhcm5pbmd9IGZyb20gJy4uL3dhcm5pbmdfaGVscGVycyc7XG5cbmltcG9ydCB7XG4gIEFuaW1hdGVBc3QsXG4gIEFuaW1hdGVDaGlsZEFzdCxcbiAgQW5pbWF0ZVJlZkFzdCxcbiAgQXN0LFxuICBEeW5hbWljVGltaW5nQXN0LFxuICBHcm91cEFzdCxcbiAgS2V5ZnJhbWVzQXN0LFxuICBRdWVyeUFzdCxcbiAgUmVmZXJlbmNlQXN0LFxuICBTZXF1ZW5jZUFzdCxcbiAgU3RhZ2dlckFzdCxcbiAgU3RhdGVBc3QsXG4gIFN0eWxlQXN0LFxuICBUaW1pbmdBc3QsXG4gIFRyYW5zaXRpb25Bc3QsXG4gIFRyaWdnZXJBc3QsXG59IGZyb20gJy4vYW5pbWF0aW9uX2FzdCc7XG5pbXBvcnQge0FuaW1hdGlvbkRzbFZpc2l0b3J9IGZyb20gJy4vYW5pbWF0aW9uX2RzbF92aXNpdG9yJztcbmltcG9ydCB7cGFyc2VUcmFuc2l0aW9uRXhwcn0gZnJvbSAnLi9hbmltYXRpb25fdHJhbnNpdGlvbl9leHByJztcblxuY29uc3QgU0VMRl9UT0tFTiA9ICc6c2VsZic7XG5jb25zdCBTRUxGX1RPS0VOX1JFR0VYID0gbmV3IFJlZ0V4cChgcyoke1NFTEZfVE9LRU59cyosP2AsICdnJyk7XG5cbi8qXG4gKiBbVmFsaWRhdGlvbl1cbiAqIFRoZSB2aXNpdG9yIGNvZGUgYmVsb3cgd2lsbCB0cmF2ZXJzZSB0aGUgYW5pbWF0aW9uIEFTVCBnZW5lcmF0ZWQgYnkgdGhlIGFuaW1hdGlvbiB2ZXJiIGZ1bmN0aW9uc1xuICogKHRoZSBvdXRwdXQgaXMgYSB0cmVlIG9mIG9iamVjdHMpIGFuZCBhdHRlbXB0IHRvIHBlcmZvcm0gYSBzZXJpZXMgb2YgdmFsaWRhdGlvbnMgb24gdGhlIGRhdGEuIFRoZVxuICogZm9sbG93aW5nIGNvcm5lci1jYXNlcyB3aWxsIGJlIHZhbGlkYXRlZDpcbiAqXG4gKiAxLiBPdmVybGFwIG9mIGFuaW1hdGlvbnNcbiAqIEdpdmVuIHRoYXQgYSBDU1MgcHJvcGVydHkgY2Fubm90IGJlIGFuaW1hdGVkIGluIG1vcmUgdGhhbiBvbmUgcGxhY2UgYXQgdGhlIHNhbWUgdGltZSwgaXQnc1xuICogaW1wb3J0YW50IHRoYXQgdGhpcyBiZWhhdmlvciBpcyBkZXRlY3RlZCBhbmQgdmFsaWRhdGVkLiBUaGUgd2F5IGluIHdoaWNoIHRoaXMgb2NjdXJzIGlzIHRoYXRcbiAqIGVhY2ggdGltZSBhIHN0eWxlIHByb3BlcnR5IGlzIGV4YW1pbmVkLCBhIHN0cmluZy1tYXAgY29udGFpbmluZyB0aGUgcHJvcGVydHkgd2lsbCBiZSB1cGRhdGVkIHdpdGhcbiAqIHRoZSBzdGFydCBhbmQgZW5kIHRpbWVzIGZvciB3aGVuIHRoZSBwcm9wZXJ0eSBpcyB1c2VkIHdpdGhpbiBhbiBhbmltYXRpb24gc3RlcC5cbiAqXG4gKiBJZiB0aGVyZSBhcmUgdHdvIG9yIG1vcmUgcGFyYWxsZWwgYW5pbWF0aW9ucyB0aGF0IGFyZSBjdXJyZW50bHkgcnVubmluZyAodGhlc2UgYXJlIGludm9rZWQgYnkgdGhlXG4gKiBncm91cCgpKSBvbiB0aGUgc2FtZSBlbGVtZW50IHRoZW4gdGhlIHZhbGlkYXRvciB3aWxsIHRocm93IGFuIGVycm9yLiBTaW5jZSB0aGUgc3RhcnQvZW5kIHRpbWluZ1xuICogdmFsdWVzIGFyZSBjb2xsZWN0ZWQgZm9yIGVhY2ggcHJvcGVydHkgdGhlbiBpZiB0aGUgY3VycmVudCBhbmltYXRpb24gc3RlcCBpcyBhbmltYXRpbmcgdGhlIHNhbWVcbiAqIHByb3BlcnR5IGFuZCBpdHMgdGltaW5nIHZhbHVlcyBmYWxsIGFueXdoZXJlIGludG8gdGhlIHdpbmRvdyBvZiB0aW1lIHRoYXQgdGhlIHByb3BlcnR5IGlzXG4gKiBjdXJyZW50bHkgYmVpbmcgYW5pbWF0ZWQgd2l0aGluIHRoZW4gdGhpcyBpcyB3aGF0IGNhdXNlcyBhbiBlcnJvci5cbiAqXG4gKiAyLiBUaW1pbmcgdmFsdWVzXG4gKiBUaGUgdmFsaWRhdG9yIHdpbGwgdmFsaWRhdGUgdG8gc2VlIGlmIGEgdGltaW5nIHZhbHVlIG9mIGBkdXJhdGlvbiBkZWxheSBlYXNpbmdgIG9yXG4gKiBgZHVyYXRpb25OdW1iZXJgIGlzIHZhbGlkIG9yIG5vdC5cbiAqXG4gKiAobm90ZSB0aGF0IHVwb24gdmFsaWRhdGlvbiB0aGUgY29kZSBiZWxvdyB3aWxsIHJlcGxhY2UgdGhlIHRpbWluZyBkYXRhIHdpdGggYW4gb2JqZWN0IGNvbnRhaW5pbmdcbiAqIHtkdXJhdGlvbixkZWxheSxlYXNpbmd9LlxuICpcbiAqIDMuIE9mZnNldCBWYWxpZGF0aW9uXG4gKiBFYWNoIG9mIHRoZSBzdHlsZSgpIGNhbGxzIGFyZSBhbGxvd2VkIHRvIGhhdmUgYW4gb2Zmc2V0IHZhbHVlIHdoZW4gcGxhY2VkIGluc2lkZSBvZiBrZXlmcmFtZXMoKS5cbiAqIE9mZnNldHMgd2l0aGluIGtleWZyYW1lcygpIGFyZSBjb25zaWRlcmVkIHZhbGlkIHdoZW46XG4gKlxuICogICAtIE5vIG9mZnNldHMgYXJlIHVzZWQgYXQgYWxsXG4gKiAgIC0gRWFjaCBzdHlsZSgpIGVudHJ5IGNvbnRhaW5zIGFuIG9mZnNldCB2YWx1ZVxuICogICAtIEVhY2ggb2Zmc2V0IGlzIGJldHdlZW4gMCBhbmQgMVxuICogICAtIEVhY2ggb2Zmc2V0IGlzIGdyZWF0ZXIgdG8gb3IgZXF1YWwgdGhhbiB0aGUgcHJldmlvdXMgb25lXG4gKlxuICogT3RoZXJ3aXNlIGFuIGVycm9yIHdpbGwgYmUgdGhyb3duLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRBbmltYXRpb25Bc3QoXG4gIGRyaXZlcjogQW5pbWF0aW9uRHJpdmVyLFxuICBtZXRhZGF0YTogQW5pbWF0aW9uTWV0YWRhdGEgfCBBbmltYXRpb25NZXRhZGF0YVtdLFxuICBlcnJvcnM6IEVycm9yW10sXG4gIHdhcm5pbmdzOiBzdHJpbmdbXSxcbik6IEFzdDxBbmltYXRpb25NZXRhZGF0YVR5cGU+IHtcbiAgcmV0dXJuIG5ldyBBbmltYXRpb25Bc3RCdWlsZGVyVmlzaXRvcihkcml2ZXIpLmJ1aWxkKG1ldGFkYXRhLCBlcnJvcnMsIHdhcm5pbmdzKTtcbn1cblxuY29uc3QgUk9PVF9TRUxFQ1RPUiA9ICcnO1xuXG5leHBvcnQgY2xhc3MgQW5pbWF0aW9uQXN0QnVpbGRlclZpc2l0b3IgaW1wbGVtZW50cyBBbmltYXRpb25Ec2xWaXNpdG9yIHtcbiAgY29uc3RydWN0b3IocHJpdmF0ZSBfZHJpdmVyOiBBbmltYXRpb25Ecml2ZXIpIHt9XG5cbiAgYnVpbGQoXG4gICAgbWV0YWRhdGE6IEFuaW1hdGlvbk1ldGFkYXRhIHwgQW5pbWF0aW9uTWV0YWRhdGFbXSxcbiAgICBlcnJvcnM6IEVycm9yW10sXG4gICAgd2FybmluZ3M6IHN0cmluZ1tdLFxuICApOiBBc3Q8QW5pbWF0aW9uTWV0YWRhdGFUeXBlPiB7XG4gICAgY29uc3QgY29udGV4dCA9IG5ldyBBbmltYXRpb25Bc3RCdWlsZGVyQ29udGV4dChlcnJvcnMpO1xuICAgIHRoaXMuX3Jlc2V0Q29udGV4dFN0eWxlVGltaW5nU3RhdGUoY29udGV4dCk7XG4gICAgY29uc3QgYXN0ID0gPEFzdDxBbmltYXRpb25NZXRhZGF0YVR5cGU+PihcbiAgICAgIHZpc2l0RHNsTm9kZSh0aGlzLCBub3JtYWxpemVBbmltYXRpb25FbnRyeShtZXRhZGF0YSksIGNvbnRleHQpXG4gICAgKTtcblxuICAgIGlmICh0eXBlb2YgbmdEZXZNb2RlID09PSAndW5kZWZpbmVkJyB8fCBuZ0Rldk1vZGUpIHtcbiAgICAgIGlmIChjb250ZXh0LnVuc3VwcG9ydGVkQ1NTUHJvcGVydGllc0ZvdW5kLnNpemUpIHtcbiAgICAgICAgcHVzaFVucmVjb2duaXplZFByb3BlcnRpZXNXYXJuaW5nKHdhcm5pbmdzLCBbXG4gICAgICAgICAgLi4uY29udGV4dC51bnN1cHBvcnRlZENTU1Byb3BlcnRpZXNGb3VuZC5rZXlzKCksXG4gICAgICAgIF0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBhc3Q7XG4gIH1cblxuICBwcml2YXRlIF9yZXNldENvbnRleHRTdHlsZVRpbWluZ1N0YXRlKGNvbnRleHQ6IEFuaW1hdGlvbkFzdEJ1aWxkZXJDb250ZXh0KSB7XG4gICAgY29udGV4dC5jdXJyZW50UXVlcnlTZWxlY3RvciA9IFJPT1RfU0VMRUNUT1I7XG4gICAgY29udGV4dC5jb2xsZWN0ZWRTdHlsZXMgPSBuZXcgTWFwPHN0cmluZywgTWFwPHN0cmluZywgU3R5bGVUaW1lVHVwbGU+PigpO1xuICAgIGNvbnRleHQuY29sbGVjdGVkU3R5bGVzLnNldChST09UX1NFTEVDVE9SLCBuZXcgTWFwKCkpO1xuICAgIGNvbnRleHQuY3VycmVudFRpbWUgPSAwO1xuICB9XG5cbiAgdmlzaXRUcmlnZ2VyKFxuICAgIG1ldGFkYXRhOiBBbmltYXRpb25UcmlnZ2VyTWV0YWRhdGEsXG4gICAgY29udGV4dDogQW5pbWF0aW9uQXN0QnVpbGRlckNvbnRleHQsXG4gICk6IFRyaWdnZXJBc3Qge1xuICAgIGxldCBxdWVyeUNvdW50ID0gKGNvbnRleHQucXVlcnlDb3VudCA9IDApO1xuICAgIGxldCBkZXBDb3VudCA9IChjb250ZXh0LmRlcENvdW50ID0gMCk7XG4gICAgY29uc3Qgc3RhdGVzOiBTdGF0ZUFzdFtdID0gW107XG4gICAgY29uc3QgdHJhbnNpdGlvbnM6IFRyYW5zaXRpb25Bc3RbXSA9IFtdO1xuICAgIGlmIChtZXRhZGF0YS5uYW1lLmNoYXJBdCgwKSA9PSAnQCcpIHtcbiAgICAgIGNvbnRleHQuZXJyb3JzLnB1c2goaW52YWxpZFRyaWdnZXIoKSk7XG4gICAgfVxuXG4gICAgbWV0YWRhdGEuZGVmaW5pdGlvbnMuZm9yRWFjaCgoZGVmKSA9PiB7XG4gICAgICB0aGlzLl9yZXNldENvbnRleHRTdHlsZVRpbWluZ1N0YXRlKGNvbnRleHQpO1xuICAgICAgaWYgKGRlZi50eXBlID09IEFuaW1hdGlvbk1ldGFkYXRhVHlwZS5TdGF0ZSkge1xuICAgICAgICBjb25zdCBzdGF0ZURlZiA9IGRlZiBhcyBBbmltYXRpb25TdGF0ZU1ldGFkYXRhO1xuICAgICAgICBjb25zdCBuYW1lID0gc3RhdGVEZWYubmFtZTtcbiAgICAgICAgbmFtZVxuICAgICAgICAgIC50b1N0cmluZygpXG4gICAgICAgICAgLnNwbGl0KC9cXHMqLFxccyovKVxuICAgICAgICAgIC5mb3JFYWNoKChuKSA9PiB7XG4gICAgICAgICAgICBzdGF0ZURlZi5uYW1lID0gbjtcbiAgICAgICAgICAgIHN0YXRlcy5wdXNoKHRoaXMudmlzaXRTdGF0ZShzdGF0ZURlZiwgY29udGV4dCkpO1xuICAgICAgICAgIH0pO1xuICAgICAgICBzdGF0ZURlZi5uYW1lID0gbmFtZTtcbiAgICAgIH0gZWxzZSBpZiAoZGVmLnR5cGUgPT0gQW5pbWF0aW9uTWV0YWRhdGFUeXBlLlRyYW5zaXRpb24pIHtcbiAgICAgICAgY29uc3QgdHJhbnNpdGlvbiA9IHRoaXMudmlzaXRUcmFuc2l0aW9uKGRlZiBhcyBBbmltYXRpb25UcmFuc2l0aW9uTWV0YWRhdGEsIGNvbnRleHQpO1xuICAgICAgICBxdWVyeUNvdW50ICs9IHRyYW5zaXRpb24ucXVlcnlDb3VudDtcbiAgICAgICAgZGVwQ291bnQgKz0gdHJhbnNpdGlvbi5kZXBDb3VudDtcbiAgICAgICAgdHJhbnNpdGlvbnMucHVzaCh0cmFuc2l0aW9uKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnRleHQuZXJyb3JzLnB1c2goaW52YWxpZERlZmluaXRpb24oKSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgdHlwZTogQW5pbWF0aW9uTWV0YWRhdGFUeXBlLlRyaWdnZXIsXG4gICAgICBuYW1lOiBtZXRhZGF0YS5uYW1lLFxuICAgICAgc3RhdGVzLFxuICAgICAgdHJhbnNpdGlvbnMsXG4gICAgICBxdWVyeUNvdW50LFxuICAgICAgZGVwQ291bnQsXG4gICAgICBvcHRpb25zOiBudWxsLFxuICAgIH07XG4gIH1cblxuICB2aXNpdFN0YXRlKG1ldGFkYXRhOiBBbmltYXRpb25TdGF0ZU1ldGFkYXRhLCBjb250ZXh0OiBBbmltYXRpb25Bc3RCdWlsZGVyQ29udGV4dCk6IFN0YXRlQXN0IHtcbiAgICBjb25zdCBzdHlsZUFzdCA9IHRoaXMudmlzaXRTdHlsZShtZXRhZGF0YS5zdHlsZXMsIGNvbnRleHQpO1xuICAgIGNvbnN0IGFzdFBhcmFtcyA9IChtZXRhZGF0YS5vcHRpb25zICYmIG1ldGFkYXRhLm9wdGlvbnMucGFyYW1zKSB8fCBudWxsO1xuICAgIGlmIChzdHlsZUFzdC5jb250YWluc0R5bmFtaWNTdHlsZXMpIHtcbiAgICAgIGNvbnN0IG1pc3NpbmdTdWJzID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gICAgICBjb25zdCBwYXJhbXMgPSBhc3RQYXJhbXMgfHwge307XG4gICAgICBzdHlsZUFzdC5zdHlsZXMuZm9yRWFjaCgoc3R5bGUpID0+IHtcbiAgICAgICAgaWYgKHN0eWxlIGluc3RhbmNlb2YgTWFwKSB7XG4gICAgICAgICAgc3R5bGUuZm9yRWFjaCgodmFsdWUpID0+IHtcbiAgICAgICAgICAgIGV4dHJhY3RTdHlsZVBhcmFtcyh2YWx1ZSkuZm9yRWFjaCgoc3ViKSA9PiB7XG4gICAgICAgICAgICAgIGlmICghcGFyYW1zLmhhc093blByb3BlcnR5KHN1YikpIHtcbiAgICAgICAgICAgICAgICBtaXNzaW5nU3Vicy5hZGQoc3ViKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgaWYgKG1pc3NpbmdTdWJzLnNpemUpIHtcbiAgICAgICAgY29udGV4dC5lcnJvcnMucHVzaChpbnZhbGlkU3RhdGUobWV0YWRhdGEubmFtZSwgWy4uLm1pc3NpbmdTdWJzLnZhbHVlcygpXSkpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICB0eXBlOiBBbmltYXRpb25NZXRhZGF0YVR5cGUuU3RhdGUsXG4gICAgICBuYW1lOiBtZXRhZGF0YS5uYW1lLFxuICAgICAgc3R5bGU6IHN0eWxlQXN0LFxuICAgICAgb3B0aW9uczogYXN0UGFyYW1zID8ge3BhcmFtczogYXN0UGFyYW1zfSA6IG51bGwsXG4gICAgfTtcbiAgfVxuXG4gIHZpc2l0VHJhbnNpdGlvbihcbiAgICBtZXRhZGF0YTogQW5pbWF0aW9uVHJhbnNpdGlvbk1ldGFkYXRhLFxuICAgIGNvbnRleHQ6IEFuaW1hdGlvbkFzdEJ1aWxkZXJDb250ZXh0LFxuICApOiBUcmFuc2l0aW9uQXN0IHtcbiAgICBjb250ZXh0LnF1ZXJ5Q291bnQgPSAwO1xuICAgIGNvbnRleHQuZGVwQ291bnQgPSAwO1xuICAgIGNvbnN0IGFuaW1hdGlvbiA9IHZpc2l0RHNsTm9kZSh0aGlzLCBub3JtYWxpemVBbmltYXRpb25FbnRyeShtZXRhZGF0YS5hbmltYXRpb24pLCBjb250ZXh0KTtcbiAgICBjb25zdCBtYXRjaGVycyA9IHBhcnNlVHJhbnNpdGlvbkV4cHIobWV0YWRhdGEuZXhwciwgY29udGV4dC5lcnJvcnMpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6IEFuaW1hdGlvbk1ldGFkYXRhVHlwZS5UcmFuc2l0aW9uLFxuICAgICAgbWF0Y2hlcnMsXG4gICAgICBhbmltYXRpb24sXG4gICAgICBxdWVyeUNvdW50OiBjb250ZXh0LnF1ZXJ5Q291bnQsXG4gICAgICBkZXBDb3VudDogY29udGV4dC5kZXBDb3VudCxcbiAgICAgIG9wdGlvbnM6IG5vcm1hbGl6ZUFuaW1hdGlvbk9wdGlvbnMobWV0YWRhdGEub3B0aW9ucyksXG4gICAgfTtcbiAgfVxuXG4gIHZpc2l0U2VxdWVuY2UoXG4gICAgbWV0YWRhdGE6IEFuaW1hdGlvblNlcXVlbmNlTWV0YWRhdGEsXG4gICAgY29udGV4dDogQW5pbWF0aW9uQXN0QnVpbGRlckNvbnRleHQsXG4gICk6IFNlcXVlbmNlQXN0IHtcbiAgICByZXR1cm4ge1xuICAgICAgdHlwZTogQW5pbWF0aW9uTWV0YWRhdGFUeXBlLlNlcXVlbmNlLFxuICAgICAgc3RlcHM6IG1ldGFkYXRhLnN0ZXBzLm1hcCgocykgPT4gdmlzaXREc2xOb2RlKHRoaXMsIHMsIGNvbnRleHQpKSxcbiAgICAgIG9wdGlvbnM6IG5vcm1hbGl6ZUFuaW1hdGlvbk9wdGlvbnMobWV0YWRhdGEub3B0aW9ucyksXG4gICAgfTtcbiAgfVxuXG4gIHZpc2l0R3JvdXAobWV0YWRhdGE6IEFuaW1hdGlvbkdyb3VwTWV0YWRhdGEsIGNvbnRleHQ6IEFuaW1hdGlvbkFzdEJ1aWxkZXJDb250ZXh0KTogR3JvdXBBc3Qge1xuICAgIGNvbnN0IGN1cnJlbnRUaW1lID0gY29udGV4dC5jdXJyZW50VGltZTtcbiAgICBsZXQgZnVydGhlc3RUaW1lID0gMDtcbiAgICBjb25zdCBzdGVwcyA9IG1ldGFkYXRhLnN0ZXBzLm1hcCgoc3RlcCkgPT4ge1xuICAgICAgY29udGV4dC5jdXJyZW50VGltZSA9IGN1cnJlbnRUaW1lO1xuICAgICAgY29uc3QgaW5uZXJBc3QgPSB2aXNpdERzbE5vZGUodGhpcywgc3RlcCwgY29udGV4dCk7XG4gICAgICBmdXJ0aGVzdFRpbWUgPSBNYXRoLm1heChmdXJ0aGVzdFRpbWUsIGNvbnRleHQuY3VycmVudFRpbWUpO1xuICAgICAgcmV0dXJuIGlubmVyQXN0O1xuICAgIH0pO1xuXG4gICAgY29udGV4dC5jdXJyZW50VGltZSA9IGZ1cnRoZXN0VGltZTtcbiAgICByZXR1cm4ge1xuICAgICAgdHlwZTogQW5pbWF0aW9uTWV0YWRhdGFUeXBlLkdyb3VwLFxuICAgICAgc3RlcHMsXG4gICAgICBvcHRpb25zOiBub3JtYWxpemVBbmltYXRpb25PcHRpb25zKG1ldGFkYXRhLm9wdGlvbnMpLFxuICAgIH07XG4gIH1cblxuICB2aXNpdEFuaW1hdGUoXG4gICAgbWV0YWRhdGE6IEFuaW1hdGlvbkFuaW1hdGVNZXRhZGF0YSxcbiAgICBjb250ZXh0OiBBbmltYXRpb25Bc3RCdWlsZGVyQ29udGV4dCxcbiAgKTogQW5pbWF0ZUFzdCB7XG4gICAgY29uc3QgdGltaW5nQXN0ID0gY29uc3RydWN0VGltaW5nQXN0KG1ldGFkYXRhLnRpbWluZ3MsIGNvbnRleHQuZXJyb3JzKTtcbiAgICBjb250ZXh0LmN1cnJlbnRBbmltYXRlVGltaW5ncyA9IHRpbWluZ0FzdDtcbiAgICBsZXQgc3R5bGVBc3Q6IFN0eWxlQXN0IHwgS2V5ZnJhbWVzQXN0O1xuICAgIGxldCBzdHlsZU1ldGFkYXRhOiBBbmltYXRpb25TdHlsZU1ldGFkYXRhIHwgQW5pbWF0aW9uS2V5ZnJhbWVzU2VxdWVuY2VNZXRhZGF0YSA9IG1ldGFkYXRhLnN0eWxlc1xuICAgICAgPyBtZXRhZGF0YS5zdHlsZXNcbiAgICAgIDogc3R5bGUoe30pO1xuICAgIGlmIChzdHlsZU1ldGFkYXRhLnR5cGUgPT0gQW5pbWF0aW9uTWV0YWRhdGFUeXBlLktleWZyYW1lcykge1xuICAgICAgc3R5bGVBc3QgPSB0aGlzLnZpc2l0S2V5ZnJhbWVzKHN0eWxlTWV0YWRhdGEgYXMgQW5pbWF0aW9uS2V5ZnJhbWVzU2VxdWVuY2VNZXRhZGF0YSwgY29udGV4dCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGxldCBzdHlsZU1ldGFkYXRhID0gbWV0YWRhdGEuc3R5bGVzIGFzIEFuaW1hdGlvblN0eWxlTWV0YWRhdGE7XG4gICAgICBsZXQgaXNFbXB0eSA9IGZhbHNlO1xuICAgICAgaWYgKCFzdHlsZU1ldGFkYXRhKSB7XG4gICAgICAgIGlzRW1wdHkgPSB0cnVlO1xuICAgICAgICBjb25zdCBuZXdTdHlsZURhdGE6IHtbcHJvcDogc3RyaW5nXTogc3RyaW5nIHwgbnVtYmVyfSA9IHt9O1xuICAgICAgICBpZiAodGltaW5nQXN0LmVhc2luZykge1xuICAgICAgICAgIG5ld1N0eWxlRGF0YVsnZWFzaW5nJ10gPSB0aW1pbmdBc3QuZWFzaW5nO1xuICAgICAgICB9XG4gICAgICAgIHN0eWxlTWV0YWRhdGEgPSBzdHlsZShuZXdTdHlsZURhdGEpO1xuICAgICAgfVxuICAgICAgY29udGV4dC5jdXJyZW50VGltZSArPSB0aW1pbmdBc3QuZHVyYXRpb24gKyB0aW1pbmdBc3QuZGVsYXk7XG4gICAgICBjb25zdCBfc3R5bGVBc3QgPSB0aGlzLnZpc2l0U3R5bGUoc3R5bGVNZXRhZGF0YSwgY29udGV4dCk7XG4gICAgICBfc3R5bGVBc3QuaXNFbXB0eVN0ZXAgPSBpc0VtcHR5O1xuICAgICAgc3R5bGVBc3QgPSBfc3R5bGVBc3Q7XG4gICAgfVxuXG4gICAgY29udGV4dC5jdXJyZW50QW5pbWF0ZVRpbWluZ3MgPSBudWxsO1xuICAgIHJldHVybiB7XG4gICAgICB0eXBlOiBBbmltYXRpb25NZXRhZGF0YVR5cGUuQW5pbWF0ZSxcbiAgICAgIHRpbWluZ3M6IHRpbWluZ0FzdCxcbiAgICAgIHN0eWxlOiBzdHlsZUFzdCxcbiAgICAgIG9wdGlvbnM6IG51bGwsXG4gICAgfTtcbiAgfVxuXG4gIHZpc2l0U3R5bGUobWV0YWRhdGE6IEFuaW1hdGlvblN0eWxlTWV0YWRhdGEsIGNvbnRleHQ6IEFuaW1hdGlvbkFzdEJ1aWxkZXJDb250ZXh0KTogU3R5bGVBc3Qge1xuICAgIGNvbnN0IGFzdCA9IHRoaXMuX21ha2VTdHlsZUFzdChtZXRhZGF0YSwgY29udGV4dCk7XG4gICAgdGhpcy5fdmFsaWRhdGVTdHlsZUFzdChhc3QsIGNvbnRleHQpO1xuICAgIHJldHVybiBhc3Q7XG4gIH1cblxuICBwcml2YXRlIF9tYWtlU3R5bGVBc3QoXG4gICAgbWV0YWRhdGE6IEFuaW1hdGlvblN0eWxlTWV0YWRhdGEsXG4gICAgY29udGV4dDogQW5pbWF0aW9uQXN0QnVpbGRlckNvbnRleHQsXG4gICk6IFN0eWxlQXN0IHtcbiAgICBjb25zdCBzdHlsZXM6IEFycmF5PMm1U3R5bGVEYXRhTWFwIHwgc3RyaW5nPiA9IFtdO1xuICAgIGNvbnN0IG1ldGFkYXRhU3R5bGVzID0gQXJyYXkuaXNBcnJheShtZXRhZGF0YS5zdHlsZXMpID8gbWV0YWRhdGEuc3R5bGVzIDogW21ldGFkYXRhLnN0eWxlc107XG5cbiAgICBmb3IgKGxldCBzdHlsZVR1cGxlIG9mIG1ldGFkYXRhU3R5bGVzKSB7XG4gICAgICBpZiAodHlwZW9mIHN0eWxlVHVwbGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIGlmIChzdHlsZVR1cGxlID09PSBBVVRPX1NUWUxFKSB7XG4gICAgICAgICAgc3R5bGVzLnB1c2goc3R5bGVUdXBsZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29udGV4dC5lcnJvcnMucHVzaChpbnZhbGlkU3R5bGVWYWx1ZShzdHlsZVR1cGxlKSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN0eWxlcy5wdXNoKG5ldyBNYXAoT2JqZWN0LmVudHJpZXMoc3R5bGVUdXBsZSkpKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBsZXQgY29udGFpbnNEeW5hbWljU3R5bGVzID0gZmFsc2U7XG4gICAgbGV0IGNvbGxlY3RlZEVhc2luZzogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG4gICAgc3R5bGVzLmZvckVhY2goKHN0eWxlRGF0YSkgPT4ge1xuICAgICAgaWYgKHN0eWxlRGF0YSBpbnN0YW5jZW9mIE1hcCkge1xuICAgICAgICBpZiAoc3R5bGVEYXRhLmhhcygnZWFzaW5nJykpIHtcbiAgICAgICAgICBjb2xsZWN0ZWRFYXNpbmcgPSBzdHlsZURhdGEuZ2V0KCdlYXNpbmcnKSBhcyBzdHJpbmc7XG4gICAgICAgICAgc3R5bGVEYXRhLmRlbGV0ZSgnZWFzaW5nJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFjb250YWluc0R5bmFtaWNTdHlsZXMpIHtcbiAgICAgICAgICBmb3IgKGxldCB2YWx1ZSBvZiBzdHlsZURhdGEudmFsdWVzKCkpIHtcbiAgICAgICAgICAgIGlmICh2YWx1ZSEudG9TdHJpbmcoKS5pbmRleE9mKFNVQlNUSVRVVElPTl9FWFBSX1NUQVJUKSA+PSAwKSB7XG4gICAgICAgICAgICAgIGNvbnRhaW5zRHluYW1pY1N0eWxlcyA9IHRydWU7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6IEFuaW1hdGlvbk1ldGFkYXRhVHlwZS5TdHlsZSxcbiAgICAgIHN0eWxlcyxcbiAgICAgIGVhc2luZzogY29sbGVjdGVkRWFzaW5nLFxuICAgICAgb2Zmc2V0OiBtZXRhZGF0YS5vZmZzZXQsXG4gICAgICBjb250YWluc0R5bmFtaWNTdHlsZXMsXG4gICAgICBvcHRpb25zOiBudWxsLFxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIF92YWxpZGF0ZVN0eWxlQXN0KGFzdDogU3R5bGVBc3QsIGNvbnRleHQ6IEFuaW1hdGlvbkFzdEJ1aWxkZXJDb250ZXh0KTogdm9pZCB7XG4gICAgY29uc3QgdGltaW5ncyA9IGNvbnRleHQuY3VycmVudEFuaW1hdGVUaW1pbmdzO1xuICAgIGxldCBlbmRUaW1lID0gY29udGV4dC5jdXJyZW50VGltZTtcbiAgICBsZXQgc3RhcnRUaW1lID0gY29udGV4dC5jdXJyZW50VGltZTtcbiAgICBpZiAodGltaW5ncyAmJiBzdGFydFRpbWUgPiAwKSB7XG4gICAgICBzdGFydFRpbWUgLT0gdGltaW5ncy5kdXJhdGlvbiArIHRpbWluZ3MuZGVsYXk7XG4gICAgfVxuXG4gICAgYXN0LnN0eWxlcy5mb3JFYWNoKCh0dXBsZSkgPT4ge1xuICAgICAgaWYgKHR5cGVvZiB0dXBsZSA9PT0gJ3N0cmluZycpIHJldHVybjtcblxuICAgICAgdHVwbGUuZm9yRWFjaCgodmFsdWUsIHByb3ApID0+IHtcbiAgICAgICAgaWYgKHR5cGVvZiBuZ0Rldk1vZGUgPT09ICd1bmRlZmluZWQnIHx8IG5nRGV2TW9kZSkge1xuICAgICAgICAgIGlmICghdGhpcy5fZHJpdmVyLnZhbGlkYXRlU3R5bGVQcm9wZXJ0eShwcm9wKSkge1xuICAgICAgICAgICAgdHVwbGUuZGVsZXRlKHByb3ApO1xuICAgICAgICAgICAgY29udGV4dC51bnN1cHBvcnRlZENTU1Byb3BlcnRpZXNGb3VuZC5hZGQocHJvcCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gVGhpcyBpcyBndWFyYW50ZWVkIHRvIGhhdmUgYSBkZWZpbmVkIE1hcCBhdCB0aGlzIHF1ZXJ5U2VsZWN0b3IgbG9jYXRpb24gbWFraW5nIGl0XG4gICAgICAgIC8vIHNhZmUgdG8gYWRkIHRoZSBhc3NlcnRpb24gaGVyZS4gSXQgaXMgc2V0IGFzIGEgZGVmYXVsdCBlbXB0eSBtYXAgaW4gcHJpb3IgbWV0aG9kcy5cbiAgICAgICAgY29uc3QgY29sbGVjdGVkU3R5bGVzID0gY29udGV4dC5jb2xsZWN0ZWRTdHlsZXMuZ2V0KGNvbnRleHQuY3VycmVudFF1ZXJ5U2VsZWN0b3IhKSE7XG4gICAgICAgIGNvbnN0IGNvbGxlY3RlZEVudHJ5ID0gY29sbGVjdGVkU3R5bGVzLmdldChwcm9wKTtcbiAgICAgICAgbGV0IHVwZGF0ZUNvbGxlY3RlZFN0eWxlID0gdHJ1ZTtcbiAgICAgICAgaWYgKGNvbGxlY3RlZEVudHJ5KSB7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgc3RhcnRUaW1lICE9IGVuZFRpbWUgJiZcbiAgICAgICAgICAgIHN0YXJ0VGltZSA+PSBjb2xsZWN0ZWRFbnRyeS5zdGFydFRpbWUgJiZcbiAgICAgICAgICAgIGVuZFRpbWUgPD0gY29sbGVjdGVkRW50cnkuZW5kVGltZVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgY29udGV4dC5lcnJvcnMucHVzaChcbiAgICAgICAgICAgICAgaW52YWxpZFBhcmFsbGVsQW5pbWF0aW9uKFxuICAgICAgICAgICAgICAgIHByb3AsXG4gICAgICAgICAgICAgICAgY29sbGVjdGVkRW50cnkuc3RhcnRUaW1lLFxuICAgICAgICAgICAgICAgIGNvbGxlY3RlZEVudHJ5LmVuZFRpbWUsXG4gICAgICAgICAgICAgICAgc3RhcnRUaW1lLFxuICAgICAgICAgICAgICAgIGVuZFRpbWUsXG4gICAgICAgICAgICAgICksXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgdXBkYXRlQ29sbGVjdGVkU3R5bGUgPSBmYWxzZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyB3ZSBhbHdheXMgY2hvb3NlIHRoZSBzbWFsbGVyIHN0YXJ0IHRpbWUgdmFsdWUgc2luY2Ugd2VcbiAgICAgICAgICAvLyB3YW50IHRvIGhhdmUgYSByZWNvcmQgb2YgdGhlIGVudGlyZSBhbmltYXRpb24gd2luZG93IHdoZXJlXG4gICAgICAgICAgLy8gdGhlIHN0eWxlIHByb3BlcnR5IGlzIGJlaW5nIGFuaW1hdGVkIGluIGJldHdlZW5cbiAgICAgICAgICBzdGFydFRpbWUgPSBjb2xsZWN0ZWRFbnRyeS5zdGFydFRpbWU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodXBkYXRlQ29sbGVjdGVkU3R5bGUpIHtcbiAgICAgICAgICBjb2xsZWN0ZWRTdHlsZXMuc2V0KHByb3AsIHtzdGFydFRpbWUsIGVuZFRpbWV9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjb250ZXh0Lm9wdGlvbnMpIHtcbiAgICAgICAgICB2YWxpZGF0ZVN0eWxlUGFyYW1zKHZhbHVlLCBjb250ZXh0Lm9wdGlvbnMsIGNvbnRleHQuZXJyb3JzKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICB2aXNpdEtleWZyYW1lcyhcbiAgICBtZXRhZGF0YTogQW5pbWF0aW9uS2V5ZnJhbWVzU2VxdWVuY2VNZXRhZGF0YSxcbiAgICBjb250ZXh0OiBBbmltYXRpb25Bc3RCdWlsZGVyQ29udGV4dCxcbiAgKTogS2V5ZnJhbWVzQXN0IHtcbiAgICBjb25zdCBhc3Q6IEtleWZyYW1lc0FzdCA9IHt0eXBlOiBBbmltYXRpb25NZXRhZGF0YVR5cGUuS2V5ZnJhbWVzLCBzdHlsZXM6IFtdLCBvcHRpb25zOiBudWxsfTtcbiAgICBpZiAoIWNvbnRleHQuY3VycmVudEFuaW1hdGVUaW1pbmdzKSB7XG4gICAgICBjb250ZXh0LmVycm9ycy5wdXNoKGludmFsaWRLZXlmcmFtZXMoKSk7XG4gICAgICByZXR1cm4gYXN0O1xuICAgIH1cblxuICAgIGNvbnN0IE1BWF9LRVlGUkFNRV9PRkZTRVQgPSAxO1xuXG4gICAgbGV0IHRvdGFsS2V5ZnJhbWVzV2l0aE9mZnNldHMgPSAwO1xuICAgIGNvbnN0IG9mZnNldHM6IG51bWJlcltdID0gW107XG4gICAgbGV0IG9mZnNldHNPdXRPZk9yZGVyID0gZmFsc2U7XG4gICAgbGV0IGtleWZyYW1lc091dE9mUmFuZ2UgPSBmYWxzZTtcbiAgICBsZXQgcHJldmlvdXNPZmZzZXQ6IG51bWJlciA9IDA7XG5cbiAgICBjb25zdCBrZXlmcmFtZXM6IFN0eWxlQXN0W10gPSBtZXRhZGF0YS5zdGVwcy5tYXAoKHN0eWxlcykgPT4ge1xuICAgICAgY29uc3Qgc3R5bGUgPSB0aGlzLl9tYWtlU3R5bGVBc3Qoc3R5bGVzLCBjb250ZXh0KTtcbiAgICAgIGxldCBvZmZzZXRWYWw6IG51bWJlciB8IG51bGwgPVxuICAgICAgICBzdHlsZS5vZmZzZXQgIT0gbnVsbCA/IHN0eWxlLm9mZnNldCA6IGNvbnN1bWVPZmZzZXQoc3R5bGUuc3R5bGVzKTtcbiAgICAgIGxldCBvZmZzZXQ6IG51bWJlciA9IDA7XG4gICAgICBpZiAob2Zmc2V0VmFsICE9IG51bGwpIHtcbiAgICAgICAgdG90YWxLZXlmcmFtZXNXaXRoT2Zmc2V0cysrO1xuICAgICAgICBvZmZzZXQgPSBzdHlsZS5vZmZzZXQgPSBvZmZzZXRWYWw7XG4gICAgICB9XG4gICAgICBrZXlmcmFtZXNPdXRPZlJhbmdlID0ga2V5ZnJhbWVzT3V0T2ZSYW5nZSB8fCBvZmZzZXQgPCAwIHx8IG9mZnNldCA+IDE7XG4gICAgICBvZmZzZXRzT3V0T2ZPcmRlciA9IG9mZnNldHNPdXRPZk9yZGVyIHx8IG9mZnNldCA8IHByZXZpb3VzT2Zmc2V0O1xuICAgICAgcHJldmlvdXNPZmZzZXQgPSBvZmZzZXQ7XG4gICAgICBvZmZzZXRzLnB1c2gob2Zmc2V0KTtcbiAgICAgIHJldHVybiBzdHlsZTtcbiAgICB9KTtcblxuICAgIGlmIChrZXlmcmFtZXNPdXRPZlJhbmdlKSB7XG4gICAgICBjb250ZXh0LmVycm9ycy5wdXNoKGludmFsaWRPZmZzZXQoKSk7XG4gICAgfVxuXG4gICAgaWYgKG9mZnNldHNPdXRPZk9yZGVyKSB7XG4gICAgICBjb250ZXh0LmVycm9ycy5wdXNoKGtleWZyYW1lT2Zmc2V0c091dE9mT3JkZXIoKSk7XG4gICAgfVxuXG4gICAgY29uc3QgbGVuZ3RoID0gbWV0YWRhdGEuc3RlcHMubGVuZ3RoO1xuICAgIGxldCBnZW5lcmF0ZWRPZmZzZXQgPSAwO1xuICAgIGlmICh0b3RhbEtleWZyYW1lc1dpdGhPZmZzZXRzID4gMCAmJiB0b3RhbEtleWZyYW1lc1dpdGhPZmZzZXRzIDwgbGVuZ3RoKSB7XG4gICAgICBjb250ZXh0LmVycm9ycy5wdXNoKGtleWZyYW1lc01pc3NpbmdPZmZzZXRzKCkpO1xuICAgIH0gZWxzZSBpZiAodG90YWxLZXlmcmFtZXNXaXRoT2Zmc2V0cyA9PSAwKSB7XG4gICAgICBnZW5lcmF0ZWRPZmZzZXQgPSBNQVhfS0VZRlJBTUVfT0ZGU0VUIC8gKGxlbmd0aCAtIDEpO1xuICAgIH1cblxuICAgIGNvbnN0IGxpbWl0ID0gbGVuZ3RoIC0gMTtcbiAgICBjb25zdCBjdXJyZW50VGltZSA9IGNvbnRleHQuY3VycmVudFRpbWU7XG4gICAgY29uc3QgY3VycmVudEFuaW1hdGVUaW1pbmdzID0gY29udGV4dC5jdXJyZW50QW5pbWF0ZVRpbWluZ3MhO1xuICAgIGNvbnN0IGFuaW1hdGVEdXJhdGlvbiA9IGN1cnJlbnRBbmltYXRlVGltaW5ncy5kdXJhdGlvbjtcbiAgICBrZXlmcmFtZXMuZm9yRWFjaCgoa2YsIGkpID0+IHtcbiAgICAgIGNvbnN0IG9mZnNldCA9IGdlbmVyYXRlZE9mZnNldCA+IDAgPyAoaSA9PSBsaW1pdCA/IDEgOiBnZW5lcmF0ZWRPZmZzZXQgKiBpKSA6IG9mZnNldHNbaV07XG4gICAgICBjb25zdCBkdXJhdGlvblVwVG9UaGlzRnJhbWUgPSBvZmZzZXQgKiBhbmltYXRlRHVyYXRpb247XG4gICAgICBjb250ZXh0LmN1cnJlbnRUaW1lID0gY3VycmVudFRpbWUgKyBjdXJyZW50QW5pbWF0ZVRpbWluZ3MuZGVsYXkgKyBkdXJhdGlvblVwVG9UaGlzRnJhbWU7XG4gICAgICBjdXJyZW50QW5pbWF0ZVRpbWluZ3MuZHVyYXRpb24gPSBkdXJhdGlvblVwVG9UaGlzRnJhbWU7XG4gICAgICB0aGlzLl92YWxpZGF0ZVN0eWxlQXN0KGtmLCBjb250ZXh0KTtcbiAgICAgIGtmLm9mZnNldCA9IG9mZnNldDtcblxuICAgICAgYXN0LnN0eWxlcy5wdXNoKGtmKTtcbiAgICB9KTtcblxuICAgIHJldHVybiBhc3Q7XG4gIH1cblxuICB2aXNpdFJlZmVyZW5jZShcbiAgICBtZXRhZGF0YTogQW5pbWF0aW9uUmVmZXJlbmNlTWV0YWRhdGEsXG4gICAgY29udGV4dDogQW5pbWF0aW9uQXN0QnVpbGRlckNvbnRleHQsXG4gICk6IFJlZmVyZW5jZUFzdCB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6IEFuaW1hdGlvbk1ldGFkYXRhVHlwZS5SZWZlcmVuY2UsXG4gICAgICBhbmltYXRpb246IHZpc2l0RHNsTm9kZSh0aGlzLCBub3JtYWxpemVBbmltYXRpb25FbnRyeShtZXRhZGF0YS5hbmltYXRpb24pLCBjb250ZXh0KSxcbiAgICAgIG9wdGlvbnM6IG5vcm1hbGl6ZUFuaW1hdGlvbk9wdGlvbnMobWV0YWRhdGEub3B0aW9ucyksXG4gICAgfTtcbiAgfVxuXG4gIHZpc2l0QW5pbWF0ZUNoaWxkKFxuICAgIG1ldGFkYXRhOiBBbmltYXRpb25BbmltYXRlQ2hpbGRNZXRhZGF0YSxcbiAgICBjb250ZXh0OiBBbmltYXRpb25Bc3RCdWlsZGVyQ29udGV4dCxcbiAgKTogQW5pbWF0ZUNoaWxkQXN0IHtcbiAgICBjb250ZXh0LmRlcENvdW50Kys7XG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6IEFuaW1hdGlvbk1ldGFkYXRhVHlwZS5BbmltYXRlQ2hpbGQsXG4gICAgICBvcHRpb25zOiBub3JtYWxpemVBbmltYXRpb25PcHRpb25zKG1ldGFkYXRhLm9wdGlvbnMpLFxuICAgIH07XG4gIH1cblxuICB2aXNpdEFuaW1hdGVSZWYoXG4gICAgbWV0YWRhdGE6IEFuaW1hdGlvbkFuaW1hdGVSZWZNZXRhZGF0YSxcbiAgICBjb250ZXh0OiBBbmltYXRpb25Bc3RCdWlsZGVyQ29udGV4dCxcbiAgKTogQW5pbWF0ZVJlZkFzdCB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6IEFuaW1hdGlvbk1ldGFkYXRhVHlwZS5BbmltYXRlUmVmLFxuICAgICAgYW5pbWF0aW9uOiB0aGlzLnZpc2l0UmVmZXJlbmNlKG1ldGFkYXRhLmFuaW1hdGlvbiwgY29udGV4dCksXG4gICAgICBvcHRpb25zOiBub3JtYWxpemVBbmltYXRpb25PcHRpb25zKG1ldGFkYXRhLm9wdGlvbnMpLFxuICAgIH07XG4gIH1cblxuICB2aXNpdFF1ZXJ5KG1ldGFkYXRhOiBBbmltYXRpb25RdWVyeU1ldGFkYXRhLCBjb250ZXh0OiBBbmltYXRpb25Bc3RCdWlsZGVyQ29udGV4dCk6IFF1ZXJ5QXN0IHtcbiAgICBjb25zdCBwYXJlbnRTZWxlY3RvciA9IGNvbnRleHQuY3VycmVudFF1ZXJ5U2VsZWN0b3IhO1xuICAgIGNvbnN0IG9wdGlvbnMgPSAobWV0YWRhdGEub3B0aW9ucyB8fCB7fSkgYXMgQW5pbWF0aW9uUXVlcnlPcHRpb25zO1xuXG4gICAgY29udGV4dC5xdWVyeUNvdW50Kys7XG4gICAgY29udGV4dC5jdXJyZW50UXVlcnkgPSBtZXRhZGF0YTtcbiAgICBjb25zdCBbc2VsZWN0b3IsIGluY2x1ZGVTZWxmXSA9IG5vcm1hbGl6ZVNlbGVjdG9yKG1ldGFkYXRhLnNlbGVjdG9yKTtcbiAgICBjb250ZXh0LmN1cnJlbnRRdWVyeVNlbGVjdG9yID0gcGFyZW50U2VsZWN0b3IubGVuZ3RoXG4gICAgICA/IHBhcmVudFNlbGVjdG9yICsgJyAnICsgc2VsZWN0b3JcbiAgICAgIDogc2VsZWN0b3I7XG4gICAgZ2V0T3JTZXREZWZhdWx0VmFsdWUoY29udGV4dC5jb2xsZWN0ZWRTdHlsZXMsIGNvbnRleHQuY3VycmVudFF1ZXJ5U2VsZWN0b3IsIG5ldyBNYXAoKSk7XG5cbiAgICBjb25zdCBhbmltYXRpb24gPSB2aXNpdERzbE5vZGUodGhpcywgbm9ybWFsaXplQW5pbWF0aW9uRW50cnkobWV0YWRhdGEuYW5pbWF0aW9uKSwgY29udGV4dCk7XG4gICAgY29udGV4dC5jdXJyZW50UXVlcnkgPSBudWxsO1xuICAgIGNvbnRleHQuY3VycmVudFF1ZXJ5U2VsZWN0b3IgPSBwYXJlbnRTZWxlY3RvcjtcblxuICAgIHJldHVybiB7XG4gICAgICB0eXBlOiBBbmltYXRpb25NZXRhZGF0YVR5cGUuUXVlcnksXG4gICAgICBzZWxlY3RvcixcbiAgICAgIGxpbWl0OiBvcHRpb25zLmxpbWl0IHx8IDAsXG4gICAgICBvcHRpb25hbDogISFvcHRpb25zLm9wdGlvbmFsLFxuICAgICAgaW5jbHVkZVNlbGYsXG4gICAgICBhbmltYXRpb24sXG4gICAgICBvcmlnaW5hbFNlbGVjdG9yOiBtZXRhZGF0YS5zZWxlY3RvcixcbiAgICAgIG9wdGlvbnM6IG5vcm1hbGl6ZUFuaW1hdGlvbk9wdGlvbnMobWV0YWRhdGEub3B0aW9ucyksXG4gICAgfTtcbiAgfVxuXG4gIHZpc2l0U3RhZ2dlcihcbiAgICBtZXRhZGF0YTogQW5pbWF0aW9uU3RhZ2dlck1ldGFkYXRhLFxuICAgIGNvbnRleHQ6IEFuaW1hdGlvbkFzdEJ1aWxkZXJDb250ZXh0LFxuICApOiBTdGFnZ2VyQXN0IHtcbiAgICBpZiAoIWNvbnRleHQuY3VycmVudFF1ZXJ5KSB7XG4gICAgICBjb250ZXh0LmVycm9ycy5wdXNoKGludmFsaWRTdGFnZ2VyKCkpO1xuICAgIH1cbiAgICBjb25zdCB0aW1pbmdzID1cbiAgICAgIG1ldGFkYXRhLnRpbWluZ3MgPT09ICdmdWxsJ1xuICAgICAgICA/IHtkdXJhdGlvbjogMCwgZGVsYXk6IDAsIGVhc2luZzogJ2Z1bGwnfVxuICAgICAgICA6IHJlc29sdmVUaW1pbmcobWV0YWRhdGEudGltaW5ncywgY29udGV4dC5lcnJvcnMsIHRydWUpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6IEFuaW1hdGlvbk1ldGFkYXRhVHlwZS5TdGFnZ2VyLFxuICAgICAgYW5pbWF0aW9uOiB2aXNpdERzbE5vZGUodGhpcywgbm9ybWFsaXplQW5pbWF0aW9uRW50cnkobWV0YWRhdGEuYW5pbWF0aW9uKSwgY29udGV4dCksXG4gICAgICB0aW1pbmdzLFxuICAgICAgb3B0aW9uczogbnVsbCxcbiAgICB9O1xuICB9XG59XG5cbmZ1bmN0aW9uIG5vcm1hbGl6ZVNlbGVjdG9yKHNlbGVjdG9yOiBzdHJpbmcpOiBbc3RyaW5nLCBib29sZWFuXSB7XG4gIGNvbnN0IGhhc0FtcGVyc2FuZCA9IHNlbGVjdG9yLnNwbGl0KC9cXHMqLFxccyovKS5maW5kKCh0b2tlbikgPT4gdG9rZW4gPT0gU0VMRl9UT0tFTilcbiAgICA/IHRydWVcbiAgICA6IGZhbHNlO1xuICBpZiAoaGFzQW1wZXJzYW5kKSB7XG4gICAgc2VsZWN0b3IgPSBzZWxlY3Rvci5yZXBsYWNlKFNFTEZfVE9LRU5fUkVHRVgsICcnKTtcbiAgfVxuXG4gIC8vIE5vdGU6IHRoZSA6ZW50ZXIgYW5kIDpsZWF2ZSBhcmVuJ3Qgbm9ybWFsaXplZCBoZXJlIHNpbmNlIHRob3NlXG4gIC8vIHNlbGVjdG9ycyBhcmUgZmlsbGVkIGluIGF0IHJ1bnRpbWUgZHVyaW5nIHRpbWVsaW5lIGJ1aWxkaW5nXG4gIHNlbGVjdG9yID0gc2VsZWN0b3JcbiAgICAucmVwbGFjZSgvQFxcKi9nLCBOR19UUklHR0VSX1NFTEVDVE9SKVxuICAgIC5yZXBsYWNlKC9AXFx3Ky9nLCAobWF0Y2gpID0+IE5HX1RSSUdHRVJfU0VMRUNUT1IgKyAnLScgKyBtYXRjaC5zbGljZSgxKSlcbiAgICAucmVwbGFjZSgvOmFuaW1hdGluZy9nLCBOR19BTklNQVRJTkdfU0VMRUNUT1IpO1xuXG4gIHJldHVybiBbc2VsZWN0b3IsIGhhc0FtcGVyc2FuZF07XG59XG5cbmZ1bmN0aW9uIG5vcm1hbGl6ZVBhcmFtcyhvYmo6IHtba2V5OiBzdHJpbmddOiBhbnl9IHwgYW55KToge1trZXk6IHN0cmluZ106IGFueX0gfCBudWxsIHtcbiAgcmV0dXJuIG9iaiA/IHsuLi5vYmp9IDogbnVsbDtcbn1cblxuZXhwb3J0IHR5cGUgU3R5bGVUaW1lVHVwbGUgPSB7XG4gIHN0YXJ0VGltZTogbnVtYmVyO1xuICBlbmRUaW1lOiBudW1iZXI7XG59O1xuXG5leHBvcnQgY2xhc3MgQW5pbWF0aW9uQXN0QnVpbGRlckNvbnRleHQge1xuICBwdWJsaWMgcXVlcnlDb3VudDogbnVtYmVyID0gMDtcbiAgcHVibGljIGRlcENvdW50OiBudW1iZXIgPSAwO1xuICBwdWJsaWMgY3VycmVudFRyYW5zaXRpb246IEFuaW1hdGlvblRyYW5zaXRpb25NZXRhZGF0YSB8IG51bGwgPSBudWxsO1xuICBwdWJsaWMgY3VycmVudFF1ZXJ5OiBBbmltYXRpb25RdWVyeU1ldGFkYXRhIHwgbnVsbCA9IG51bGw7XG4gIHB1YmxpYyBjdXJyZW50UXVlcnlTZWxlY3Rvcjogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG4gIHB1YmxpYyBjdXJyZW50QW5pbWF0ZVRpbWluZ3M6IFRpbWluZ0FzdCB8IG51bGwgPSBudWxsO1xuICBwdWJsaWMgY3VycmVudFRpbWU6IG51bWJlciA9IDA7XG4gIHB1YmxpYyBjb2xsZWN0ZWRTdHlsZXMgPSBuZXcgTWFwPHN0cmluZywgTWFwPHN0cmluZywgU3R5bGVUaW1lVHVwbGU+PigpO1xuICBwdWJsaWMgb3B0aW9uczogQW5pbWF0aW9uT3B0aW9ucyB8IG51bGwgPSBudWxsO1xuICBwdWJsaWMgdW5zdXBwb3J0ZWRDU1NQcm9wZXJ0aWVzRm91bmQ6IFNldDxzdHJpbmc+ID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gIGNvbnN0cnVjdG9yKHB1YmxpYyBlcnJvcnM6IEVycm9yW10pIHt9XG59XG5cbnR5cGUgT2Zmc2V0U3R5bGVzID0gc3RyaW5nIHwgybVTdHlsZURhdGFNYXA7XG5cbmZ1bmN0aW9uIGNvbnN1bWVPZmZzZXQoc3R5bGVzOiBPZmZzZXRTdHlsZXMgfCBBcnJheTxPZmZzZXRTdHlsZXM+KTogbnVtYmVyIHwgbnVsbCB7XG4gIGlmICh0eXBlb2Ygc3R5bGVzID09ICdzdHJpbmcnKSByZXR1cm4gbnVsbDtcblxuICBsZXQgb2Zmc2V0OiBudW1iZXIgfCBudWxsID0gbnVsbDtcblxuICBpZiAoQXJyYXkuaXNBcnJheShzdHlsZXMpKSB7XG4gICAgc3R5bGVzLmZvckVhY2goKHN0eWxlVHVwbGUpID0+IHtcbiAgICAgIGlmIChzdHlsZVR1cGxlIGluc3RhbmNlb2YgTWFwICYmIHN0eWxlVHVwbGUuaGFzKCdvZmZzZXQnKSkge1xuICAgICAgICBjb25zdCBvYmogPSBzdHlsZVR1cGxlIGFzIMm1U3R5bGVEYXRhTWFwO1xuICAgICAgICBvZmZzZXQgPSBwYXJzZUZsb2F0KG9iai5nZXQoJ29mZnNldCcpIGFzIHN0cmluZyk7XG4gICAgICAgIG9iai5kZWxldGUoJ29mZnNldCcpO1xuICAgICAgfVxuICAgIH0pO1xuICB9IGVsc2UgaWYgKHN0eWxlcyBpbnN0YW5jZW9mIE1hcCAmJiBzdHlsZXMuaGFzKCdvZmZzZXQnKSkge1xuICAgIGNvbnN0IG9iaiA9IHN0eWxlcztcbiAgICBvZmZzZXQgPSBwYXJzZUZsb2F0KG9iai5nZXQoJ29mZnNldCcpIGFzIHN0cmluZyk7XG4gICAgb2JqLmRlbGV0ZSgnb2Zmc2V0Jyk7XG4gIH1cbiAgcmV0dXJuIG9mZnNldDtcbn1cblxuZnVuY3Rpb24gY29uc3RydWN0VGltaW5nQXN0KHZhbHVlOiBzdHJpbmcgfCBudW1iZXIgfCBBbmltYXRlVGltaW5ncywgZXJyb3JzOiBFcnJvcltdKSB7XG4gIGlmICh2YWx1ZS5oYXNPd25Qcm9wZXJ0eSgnZHVyYXRpb24nKSkge1xuICAgIHJldHVybiB2YWx1ZSBhcyBBbmltYXRlVGltaW5ncztcbiAgfVxuXG4gIGlmICh0eXBlb2YgdmFsdWUgPT0gJ251bWJlcicpIHtcbiAgICBjb25zdCBkdXJhdGlvbiA9IHJlc29sdmVUaW1pbmcodmFsdWUsIGVycm9ycykuZHVyYXRpb247XG4gICAgcmV0dXJuIG1ha2VUaW1pbmdBc3QoZHVyYXRpb24sIDAsICcnKTtcbiAgfVxuXG4gIGNvbnN0IHN0clZhbHVlID0gdmFsdWUgYXMgc3RyaW5nO1xuICBjb25zdCBpc0R5bmFtaWMgPSBzdHJWYWx1ZS5zcGxpdCgvXFxzKy8pLnNvbWUoKHYpID0+IHYuY2hhckF0KDApID09ICd7JyAmJiB2LmNoYXJBdCgxKSA9PSAneycpO1xuICBpZiAoaXNEeW5hbWljKSB7XG4gICAgY29uc3QgYXN0ID0gbWFrZVRpbWluZ0FzdCgwLCAwLCAnJykgYXMgYW55O1xuICAgIGFzdC5keW5hbWljID0gdHJ1ZTtcbiAgICBhc3Quc3RyVmFsdWUgPSBzdHJWYWx1ZTtcbiAgICByZXR1cm4gYXN0IGFzIER5bmFtaWNUaW1pbmdBc3Q7XG4gIH1cblxuICBjb25zdCB0aW1pbmdzID0gcmVzb2x2ZVRpbWluZyhzdHJWYWx1ZSwgZXJyb3JzKTtcbiAgcmV0dXJuIG1ha2VUaW1pbmdBc3QodGltaW5ncy5kdXJhdGlvbiwgdGltaW5ncy5kZWxheSwgdGltaW5ncy5lYXNpbmcpO1xufVxuXG5mdW5jdGlvbiBub3JtYWxpemVBbmltYXRpb25PcHRpb25zKG9wdGlvbnM6IEFuaW1hdGlvbk9wdGlvbnMgfCBudWxsKTogQW5pbWF0aW9uT3B0aW9ucyB7XG4gIGlmIChvcHRpb25zKSB7XG4gICAgb3B0aW9ucyA9IHsuLi5vcHRpb25zfTtcbiAgICBpZiAob3B0aW9uc1sncGFyYW1zJ10pIHtcbiAgICAgIG9wdGlvbnNbJ3BhcmFtcyddID0gbm9ybWFsaXplUGFyYW1zKG9wdGlvbnNbJ3BhcmFtcyddKSE7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIG9wdGlvbnMgPSB7fTtcbiAgfVxuICByZXR1cm4gb3B0aW9ucztcbn1cblxuZnVuY3Rpb24gbWFrZVRpbWluZ0FzdChkdXJhdGlvbjogbnVtYmVyLCBkZWxheTogbnVtYmVyLCBlYXNpbmc6IHN0cmluZyB8IG51bGwpOiBUaW1pbmdBc3Qge1xuICByZXR1cm4ge2R1cmF0aW9uLCBkZWxheSwgZWFzaW5nfTtcbn1cbiJdfQ==